Hello,
This series adds support for the DPAD0 output for the D3 and E3 SoCs. On the Draak and Ebisu boards, DPAD0 is used for the VGA output.
Patches 1/6 and 2/6 prepare the grounds by successfully probing LVDS encoders that have no connected output. This is required in order to provide a dot clock to the DPAD output, as on the D3 and E3 SoCs the dot clock is provided by the LVDS encoders.
Patch 3/6 then adds an API to the LVDS encoder driver to control the LVDS output clock independently of the LVDS encoder itself, and patch 4/6 makes use of that API to control the clock from the DU driver.
Patches 5/6 and 6/6 finally enable the LVDS1 encoders in the Ebisu and Draak boards DTs, required to operate the HDMI (out of LVDS0) and VGA (using the LVDS1 dot clock) together.
Changes compared to v1 are minor and include compilation fixes (in patch 3/6), typo fixes and additional comments in the DT files.
The patches have been tested on Draak only as I don't have access to an Ebisu board, but they should work equally well on both boards.
For your convenience the patches are available from
git://linuxtv.org/pinchartl/media.git drm/du/d3e3
Laurent Pinchart (6): drm: rcar-du: Simplify encoder registration drm: rcar-du: lvds: Don't fail probe if output is not connected on D3/E3 drm: rcar-du: lvds: Add API to enable/disable clock output drm: rcar-du: Turn LVDS clock output on/off for DPAD0 output on D3/E3 arm64: dts: renesas: r8a77990: ebisu: Enable LVDS1 encoder arm64: dts: renesas: r8a77995: draak: Enable LVDS1 encoder
.../arm64/boot/dts/renesas/r8a77990-ebisu.dts | 2 + .../arm64/boot/dts/renesas/r8a77995-draak.dts | 7 ++ drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/rcar-du/Kconfig | 1 + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 34 +++++++ drivers/gpu/drm/rcar-du/rcar_du_drv.h | 3 + drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 4 +- drivers/gpu/drm/rcar-du/rcar_du_encoder.h | 3 +- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 52 +--------- drivers/gpu/drm/rcar-du/rcar_lvds.c | 94 ++++++++++++++++--- drivers/gpu/drm/rcar-du/rcar_lvds.h | 27 ++++++ 11 files changed, 164 insertions(+), 65 deletions(-) create mode 100644 drivers/gpu/drm/rcar-du/rcar_lvds.h
Before the driver fully moved to drm_bridge and drm_panel, it was necessary to parse DT and locate encoder and connector nodes. The connector node is now unused and can be removed as a parameter to rcar_du_encoder_init(). As a consequence rcar_du_encoders_init_one() can be greatly simplified, removing most of the DT parsing.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 3 +- drivers/gpu/drm/rcar-du/rcar_du_encoder.h | 3 +- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 52 ++--------------------- 3 files changed, 6 insertions(+), 52 deletions(-)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c index f16209499117..ba2b38f76b54 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c @@ -30,8 +30,7 @@ static const struct drm_encoder_funcs encoder_funcs = {
int rcar_du_encoder_init(struct rcar_du_device *rcdu, enum rcar_du_output output, - struct device_node *enc_node, - struct device_node *con_node) + struct device_node *enc_node) { struct rcar_du_encoder *renc; struct drm_encoder *encoder; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h index 552f2a02e5b5..df9be4524301 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h @@ -26,7 +26,6 @@ struct rcar_du_encoder {
int rcar_du_encoder_init(struct rcar_du_device *rcdu, enum rcar_du_output output, - struct device_node *enc_node, - struct device_node *con_node); + struct device_node *enc_node);
#endif /* __RCAR_DU_ENCODER_H__ */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 015c421451dc..1bd75187d039 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -330,17 +330,10 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu, enum rcar_du_output output, struct of_endpoint *ep) { - struct device_node *connector = NULL; - struct device_node *encoder = NULL; - struct device_node *ep_node = NULL; - struct device_node *entity_ep_node; struct device_node *entity; int ret;
- /* - * Locate the connected entity and infer its type from the number of - * endpoints. - */ + /* Locate the connected entity and initialize the encoder. */ entity = of_graph_get_remote_port_parent(ep->local_node); if (!entity) { dev_dbg(rcdu->dev, "unconnected endpoint %pOF, skipping\n", @@ -356,50 +349,13 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu, return -ENODEV; }
- entity_ep_node = of_graph_get_remote_endpoint(ep->local_node); - - for_each_endpoint_of_node(entity, ep_node) { - if (ep_node == entity_ep_node) - continue; - - /* - * We've found one endpoint other than the input, this must - * be an encoder. Locate the connector. - */ - encoder = entity; - connector = of_graph_get_remote_port_parent(ep_node); - of_node_put(ep_node); - - if (!connector) { - dev_warn(rcdu->dev, - "no connector for encoder %pOF, skipping\n", - encoder); - of_node_put(entity_ep_node); - of_node_put(encoder); - return -ENODEV; - } - - break; - } - - of_node_put(entity_ep_node); - - if (!encoder) { - dev_warn(rcdu->dev, - "no encoder found for endpoint %pOF, skipping\n", - ep->local_node); - of_node_put(entity); - return -ENODEV; - } - - ret = rcar_du_encoder_init(rcdu, output, encoder, connector); + ret = rcar_du_encoder_init(rcdu, output, entity); if (ret && ret != -EPROBE_DEFER) dev_warn(rcdu->dev, "failed to initialize encoder %pOF on output %u (%d), skipping\n", - encoder, output, ret); + entity, output, ret);
- of_node_put(encoder); - of_node_put(connector); + of_node_put(entity);
return ret; }
On the D3 and E3 SoCs the LVDS encoder has an extended internal PLL and supplies a clock to the DU. That clock is used not only for the LVDS outputs but also for the DPAD output. The LVDS encoder thus needs to be available to the DU even when its output is disabled. Don't fail probe in that case on D3 and E3.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com --- Changes since v1:
- Typo fix in the commit message --- drivers/gpu/drm/rcar-du/rcar_lvds.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index caea2c590b7a..b21906b81f10 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -544,7 +544,10 @@ static int rcar_lvds_attach(struct drm_bridge *bridge) return drm_bridge_attach(bridge->encoder, lvds->next_bridge, bridge);
- /* Otherwise we have a panel, create a connector. */ + /* Otherwise if we have a panel, create a connector. */ + if (!lvds->panel) + return 0; + ret = drm_connector_init(bridge->dev, connector, &rcar_lvds_conn_funcs, DRM_MODE_CONNECTOR_LVDS); if (ret < 0) @@ -592,7 +595,8 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds) local_output = of_graph_get_endpoint_by_regs(lvds->dev->of_node, 1, 0); if (!local_output) { dev_dbg(lvds->dev, "unconnected port@1\n"); - return -ENODEV; + ret = -ENODEV; + goto done; }
/* @@ -642,6 +646,15 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds) of_node_put(remote_input); of_node_put(remote);
+ /* + * On D3/E3 the LVDS encoder provides a clock to the DU, which can be + * used for the DPAD output even when the LVDS output is not connected. + * Don't fail probe in that case as the DU will need the bridge to + * control the clock. + */ + if (lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL) + return ret == -ENODEV ? 0 : ret; + return ret; }
On the D3 and E3 platforms, the LVDS internal PLL supplies the pixel clock to the DU. This works automatically for LVDS outputs as the LVDS encoder is enabled through the bridge API, enabling the internal PLL and clock output. However, when using the DU DPAD output with the LVDS outputs turned off, the LVDS PLL needs to be controlled manually. Add an API to do so, to be called by the DU driver.
The drivers/gpu/drm/rcar-du/ directory has to be treated as obj-y unconditionally, as the LVDS driver could be built-in while the DU driver is compiled as a module.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com --- Changes since v1:
- Provide stubs when the LVDS driver is not available - Export the LVDS driver API symbols - Fix dependency with the DU and LVDS drivers to prevent DU=y && LVDS=m - Always treat drivers/gpu/drm/rcar-du/ as obj-y --- drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/rcar-du/Kconfig | 1 + drivers/gpu/drm/rcar-du/rcar_lvds.c | 77 +++++++++++++++++++++++++---- drivers/gpu/drm/rcar-du/rcar_lvds.h | 27 ++++++++++ 4 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 drivers/gpu/drm/rcar-du/rcar_lvds.h
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index ce8d1d384319..59e426704755 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -81,7 +81,7 @@ obj-$(CONFIG_DRM_UDL) += udl/ obj-$(CONFIG_DRM_AST) += ast/ obj-$(CONFIG_DRM_ARMADA) += armada/ obj-$(CONFIG_DRM_ATMEL_HLCDC) += atmel-hlcdc/ -obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/ +obj-y += rcar-du/ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ obj-y += omapdrm/ obj-$(CONFIG_DRM_SUN4I) += sun4i/ diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig index 225141656e19..7c36e2777a15 100644 --- a/drivers/gpu/drm/rcar-du/Kconfig +++ b/drivers/gpu/drm/rcar-du/Kconfig @@ -4,6 +4,7 @@ config DRM_RCAR_DU depends on DRM && OF depends on ARM || ARM64 depends on ARCH_RENESAS || COMPILE_TEST + imply DRM_RCAR_LVDS select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index b21906b81f10..7b9d8cccead4 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -22,6 +22,7 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_panel.h>
+#include "rcar_lvds.h" #include "rcar_lvds_regs.h"
struct rcar_lvds; @@ -182,8 +183,9 @@ struct pll_info {
static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk, unsigned long target, struct pll_info *pll, - u32 clksel) + u32 clksel, bool dot_clock_only) { + unsigned int div7 = dot_clock_only ? 1 : 7; unsigned long output; unsigned long fin; unsigned int m_min; @@ -217,9 +219,9 @@ static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk, * `------------> | | * |/ * - * The /7 divider is optional when the LVDS PLL is used to generate a - * dot clock for the DU RGB output, without using the LVDS encoder. We - * don't support this configuration yet. + * The /7 divider is optional, it is enabled when the LVDS PLL is used + * to drive the LVDS encoder, and disabled when used to generate a dot + * clock for the DU RGB output, without using the LVDS encoder. * * The PLL allowed input frequency range is 12 MHz to 192 MHz. */ @@ -279,7 +281,7 @@ static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk, * the PLL, followed by a an optional fixed /7 * divider. */ - fout = fvco / (1 << e) / 7; + fout = fvco / (1 << e) / div7; div = DIV_ROUND_CLOSEST(fout, target); diff = abs(fout / div - target);
@@ -300,7 +302,7 @@ static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk,
done: output = fin * pll->pll_n / pll->pll_m / (1 << pll->pll_e) - / 7 / pll->div; + / div7 / pll->div; error = (long)(output - target) * 10000 / (long)target;
dev_dbg(lvds->dev, @@ -310,17 +312,18 @@ static void rcar_lvds_d3_e3_pll_calc(struct rcar_lvds *lvds, struct clk *clk, pll->pll_m, pll->pll_n, pll->pll_e, pll->div); }
-static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq) +static void __rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, + unsigned int freq, bool dot_clock_only) { struct pll_info pll = { .diff = (unsigned long)-1 }; u32 lvdpllcr;
rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[0], freq, &pll, - LVDPLLCR_CKSEL_DU_DOTCLKIN(0)); + LVDPLLCR_CKSEL_DU_DOTCLKIN(0), dot_clock_only); rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.dotclkin[1], freq, &pll, - LVDPLLCR_CKSEL_DU_DOTCLKIN(1)); + LVDPLLCR_CKSEL_DU_DOTCLKIN(1), dot_clock_only); rcar_lvds_d3_e3_pll_calc(lvds, lvds->clocks.extal, freq, &pll, - LVDPLLCR_CKSEL_EXTAL); + LVDPLLCR_CKSEL_EXTAL, dot_clock_only);
lvdpllcr = LVDPLLCR_PLLON | pll.clksel | LVDPLLCR_CLKOUT | LVDPLLCR_PLLN(pll.pll_n - 1) | LVDPLLCR_PLLM(pll.pll_m - 1); @@ -329,6 +332,9 @@ static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq) lvdpllcr |= LVDPLLCR_STP_CLKOUTE | LVDPLLCR_OUTCLKSEL | LVDPLLCR_PLLE(pll.pll_e - 1);
+ if (dot_clock_only) + lvdpllcr |= LVDPLLCR_OCKSEL; + rcar_lvds_write(lvds, LVDPLLCR, lvdpllcr);
if (pll.div > 1) @@ -342,6 +348,57 @@ static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq) rcar_lvds_write(lvds, LVDDIV, 0); }
+static void rcar_lvds_pll_setup_d3_e3(struct rcar_lvds *lvds, unsigned int freq) +{ + __rcar_lvds_pll_setup_d3_e3(lvds, freq, false); +} + +/* ----------------------------------------------------------------------------- + * Clock - D3/E3 only + */ + +int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq) +{ + struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); + int ret; + + if (WARN_ON(!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))) + return -ENODEV; + + dev_dbg(lvds->dev, "enabling LVDS PLL, freq=%luHz\n", freq); + + WARN_ON(lvds->enabled); + + ret = clk_prepare_enable(lvds->clocks.mod); + if (ret < 0) + return ret; + + __rcar_lvds_pll_setup_d3_e3(lvds, freq, true); + + lvds->enabled = true; + return 0; +} +EXPORT_SYMBOL_GPL(rcar_lvds_clk_enable); + +void rcar_lvds_clk_disable(struct drm_bridge *bridge) +{ + struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); + + if (WARN_ON(!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL))) + return; + + dev_dbg(lvds->dev, "disabling LVDS PLL\n"); + + WARN_ON(!lvds->enabled); + + rcar_lvds_write(lvds, LVDPLLCR, 0); + + clk_disable_unprepare(lvds->clocks.mod); + + lvds->enabled = false; +} +EXPORT_SYMBOL_GPL(rcar_lvds_clk_disable); + /* ----------------------------------------------------------------------------- * Bridge */ diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.h b/drivers/gpu/drm/rcar-du/rcar_lvds.h new file mode 100644 index 000000000000..a709cae1bc32 --- /dev/null +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * rcar_lvds.h -- R-Car LVDS Encoder + * + * Copyright (C) 2013-2018 Renesas Electronics Corporation + * + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) + */ + +#ifndef __RCAR_LVDS_H__ +#define __RCAR_LVDS_H__ + +struct drm_bridge; + +#if IS_ENABLED(CONFIG_DRM_RCAR_LVDS) +int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq); +void rcar_lvds_clk_disable(struct drm_bridge *bridge); +#else +static inline int rcar_lvds_clk_enable(struct drm_bridge *bridge, + unsigned long freq) +{ + return -ENOSYS; +} +static inline void rcar_lvds_clk_disable(struct drm_bridge *bridge) { } +#endif /* CONFIG_DRM_RCAR_LVDS */ + +#endif /* __RCAR_LVDS_H__ */
On the D3 and E3 SoCs the LVDS PLL clock output provides the dot clock to the DU channels, even when the LVDS outputs are not in use. Enable and disable the LVDS clock output when enabling or disabling a CRTC connected to the DPAD0 output.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 34 +++++++++++++++++++++++ drivers/gpu/drm/rcar-du/rcar_du_drv.h | 3 ++ drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 1 + 3 files changed, 38 insertions(+)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 771b460c7216..3018e4500aa1 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -26,6 +26,7 @@ #include "rcar_du_plane.h" #include "rcar_du_regs.h" #include "rcar_du_vsp.h" +#include "rcar_lvds.h"
static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg) { @@ -657,8 +658,27 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); + struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc->state); + struct rcar_du_device *rcdu = rcrtc->group->dev;
rcar_du_crtc_get(rcrtc); + + /* + * On D3/E3 the dot clock is provided by the LVDS encoder attached to + * the DU channel. We need to enable its clock output explicitly if + * the LVDS output is disabled. + */ + if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) && + rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) { + struct rcar_du_encoder *encoder = + rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index]; + const struct drm_display_mode *mode = + &crtc->state->adjusted_mode; + + rcar_lvds_clk_enable(encoder->base.bridge, + mode->clock * 1000); + } + rcar_du_crtc_start(rcrtc); }
@@ -666,10 +686,24 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); + struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(old_state); + struct rcar_du_device *rcdu = rcrtc->group->dev;
rcar_du_crtc_stop(rcrtc); rcar_du_crtc_put(rcrtc);
+ if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) && + rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) { + struct rcar_du_encoder *encoder = + rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index]; + + /* + * Disable the LVDS clock output, see + * rcar_du_crtc_atomic_enable(). + */ + rcar_lvds_clk_disable(encoder->base.bridge); + } + spin_lock_irq(&crtc->dev->event_lock); if (crtc->state->event) { drm_crtc_send_vblank_event(crtc, crtc->state->event); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 6c187d0bf7c2..1327cd0df90a 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h @@ -22,6 +22,7 @@ struct device; struct drm_device; struct drm_property; struct rcar_du_device; +struct rcar_du_encoder;
#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK BIT(0) /* Per-CRTC IRQ and clock */ #define RCAR_DU_FEATURE_VSP1_SOURCE BIT(1) /* Has inputs from VSP1 */ @@ -81,6 +82,8 @@ struct rcar_du_device { struct rcar_du_crtc crtcs[RCAR_DU_MAX_CRTCS]; unsigned int num_crtcs;
+ struct rcar_du_encoder *encoders[RCAR_DU_OUTPUT_MAX]; + struct rcar_du_group groups[RCAR_DU_MAX_GROUPS]; struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c index ba2b38f76b54..13c3c7382514 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c @@ -41,6 +41,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, if (renc == NULL) return -ENOMEM;
+ rcdu->encoders[output] = renc; renc->output = output; encoder = rcar_encoder_to_drm_encoder(renc);
The LVDS1 encoder must supply a pixel clock to the DU for the DPAD output when the LVDS0 encoder is used. Enable it despite its output not being connected.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com --- Changes since v1:
- Add a comment in the DT to explain why the LVDS1 encoder needs to be enabled. --- arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts index 62bdddcbbae7..800a537bbbe0 100644 --- a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts +++ b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts @@ -443,6 +443,13 @@ };
&lvds1 { + /* + * Even though the LVDS1 output is not connected, the encoder must be + * enabled to supply a pixel clock to the DU for the DPAD output when + * LVDS0 is in use. + */ + status = "okay"; + clocks = <&cpg CPG_MOD 727>, <&x13_clk>, <&extal_clk>;
On Wed, Jan 23, 2019 at 12:54:04AM +0200, Laurent Pinchart wrote:
The LVDS1 encoder must supply a pixel clock to the DU for the DPAD output when the LVDS0 encoder is used. Enable it despite its output not being connected.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com
Changes since v1:
- Add a comment in the DT to explain why the LVDS1 encoder needs to be enabled.
Thanks,
This looks fine to me but I will wait to see if there are other reviews before applying.
Reviewed-by: Simon Horman horms+renesas@verge.net.au
Hi Simon,
On Wed, Jan 23, 2019 at 09:56:57AM +0100, Simon Horman wrote:
On Wed, Jan 23, 2019 at 12:54:04AM +0200, Laurent Pinchart wrote:
The LVDS1 encoder must supply a pixel clock to the DU for the DPAD output when the LVDS0 encoder is used. Enable it despite its output not being connected.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com
Changes since v1:
- Add a comment in the DT to explain why the LVDS1 encoder needs to be enabled.
Thanks,
This looks fine to me but I will wait to see if there are other reviews before applying.
Reviewed-by: Simon Horman horms+renesas@verge.net.au
Please note that this will likely cause probe failures if applied without the driver patches from this series. Would it be OK to merge the DT changes through the DRM tree ?
Hi Laurent,
On Wed, Jan 23, 2019 at 11:55:52AM +0200, Laurent Pinchart wrote:
Hi Simon,
On Wed, Jan 23, 2019 at 09:56:57AM +0100, Simon Horman wrote:
On Wed, Jan 23, 2019 at 12:54:04AM +0200, Laurent Pinchart wrote:
The LVDS1 encoder must supply a pixel clock to the DU for the DPAD output when the LVDS0 encoder is used. Enable it despite its output not being connected.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com
Changes since v1:
- Add a comment in the DT to explain why the LVDS1 encoder needs to be enabled.
Thanks,
This looks fine to me but I will wait to see if there are other reviews before applying.
Reviewed-by: Simon Horman horms+renesas@verge.net.au
Please note that this will likely cause probe failures if applied without the driver patches from this series. Would it be OK to merge the DT changes through the DRM tree ?
I'm not sure that the probe failures are a problem unless they move something that was in a working state to a non-working state. Nonetheless they are at the very least not very nice.
I generally shy away from having DT patches merged in other trees to avoid the chance of merge conflicts (that need to be resolved by Linus). What is your feeling on the risk of such a conflict?
Hi Simon,
On Wed, Jan 23, 2019 at 11:03:04AM +0100, Simon Horman wrote:
On Wed, Jan 23, 2019 at 11:55:52AM +0200, Laurent Pinchart wrote:
On Wed, Jan 23, 2019 at 09:56:57AM +0100, Simon Horman wrote:
On Wed, Jan 23, 2019 at 12:54:04AM +0200, Laurent Pinchart wrote:
The LVDS1 encoder must supply a pixel clock to the DU for the DPAD output when the LVDS0 encoder is used. Enable it despite its output not being connected.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com
Changes since v1:
- Add a comment in the DT to explain why the LVDS1 encoder needs to be enabled.
Thanks,
This looks fine to me but I will wait to see if there are other reviews before applying.
Reviewed-by: Simon Horman horms+renesas@verge.net.au
Please note that this will likely cause probe failures if applied without the driver patches from this series. Would it be OK to merge the DT changes through the DRM tree ?
I'm not sure that the probe failures are a problem unless they move something that was in a working state to a non-working state. Nonetheless they are at the very least not very nice.
I generally shy away from having DT patches merged in other trees to avoid the chance of merge conflicts (that need to be resolved by Linus). What is your feeling on the risk of such a conflict?
I would have said low, but given that it's too late to get the DT changes in v5.1 anyway, it's no big deal. The driver patches have been merged for v5.1, so could you queue the DT changes for v5.2 ?
On Fri, Feb 15, 2019 at 01:44:43PM +0200, Laurent Pinchart wrote:
Hi Simon,
On Wed, Jan 23, 2019 at 11:03:04AM +0100, Simon Horman wrote:
On Wed, Jan 23, 2019 at 11:55:52AM +0200, Laurent Pinchart wrote:
On Wed, Jan 23, 2019 at 09:56:57AM +0100, Simon Horman wrote:
On Wed, Jan 23, 2019 at 12:54:04AM +0200, Laurent Pinchart wrote:
The LVDS1 encoder must supply a pixel clock to the DU for the DPAD output when the LVDS0 encoder is used. Enable it despite its output not being connected.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com
Changes since v1:
- Add a comment in the DT to explain why the LVDS1 encoder needs to be enabled.
Thanks,
This looks fine to me but I will wait to see if there are other reviews before applying.
Reviewed-by: Simon Horman horms+renesas@verge.net.au
Please note that this will likely cause probe failures if applied without the driver patches from this series. Would it be OK to merge the DT changes through the DRM tree ?
I'm not sure that the probe failures are a problem unless they move something that was in a working state to a non-working state. Nonetheless they are at the very least not very nice.
I generally shy away from having DT patches merged in other trees to avoid the chance of merge conflicts (that need to be resolved by Linus). What is your feeling on the risk of such a conflict?
I would have said low, but given that it's too late to get the DT changes in v5.1 anyway, it's no big deal. The driver patches have been merged for v5.1, so could you queue the DT changes for v5.2 ?
Thanks, I've applied patches 5 and 6 of this series to my renesas tree for inclusion in v5.2.
The LVDS1 encoder must supply a pixel clock to the DU for the DPAD output when the LVDS0 encoder is used. Enable it despite its output not being connected.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com --- Changes since v1:
- Add a comment in the DT to explain why the LVDS1 encoder needs to be enabled. --- arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts index 89df9bc844c0..3c9ec67e342b 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts @@ -356,6 +356,13 @@ };
&lvds1 { + /* + * Even though the LVDS1 output is not connected, the encoder must be + * enabled to supply a pixel clock to the DU for the DPAD output when + * LVDS0 is in use. + */ + status = "okay"; + clocks = <&cpg CPG_MOD 727>, <&x12_clk>, <&extal_clk>;
On Wed, Jan 23, 2019 at 12:54:05AM +0200, Laurent Pinchart wrote:
The LVDS1 encoder must supply a pixel clock to the DU for the DPAD output when the LVDS0 encoder is used. Enable it despite its output not being connected.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com
Changes since v1:
- Add a comment in the DT to explain why the LVDS1 encoder needs to be enabled.
Thanks,
This looks fine to me but I will wait to see if there are other reviews before applying.
Reviewed-by: Simon Horman horms+renesas@verge.net.au
Hi Laurent
For your convenience the patches are available from
git://linuxtv.org/pinchartl/media.git drm/du/d3e3
It seems we can't find this branch/tag on your branch Is it removed ? or not yet pushed ?
https://git.linuxtv.org/pinchartl/media.git/refs/heads
Best regards --- Kuninori Morimoto
Hi Morimoto-san,
On Mon, Feb 25, 2019 at 04:44:55PM +0900, Kuninori Morimoto wrote:
Hi Laurent
For your convenience the patches are available from
git://linuxtv.org/pinchartl/media.git drm/du/d3e3
It seems we can't find this branch/tag on your branch Is it removed ? or not yet pushed ?
The branch has been merged to drm-next (for the DU driver part) and to Simon's next branch (for the DT part), so I've removed it from my tree. You can find a merge of those two branches in my repository in the drm/du/base branch.
Hi Laurent
For your convenience the patches are available from
git://linuxtv.org/pinchartl/media.git drm/du/d3e3
It seems we can't find this branch/tag on your branch Is it removed ? or not yet pushed ?
The branch has been merged to drm-next (for the DU driver part) and to Simon's next branch (for the DT part), so I've removed it from my tree. You can find a merge of those two branches in my repository in the drm/du/base branch.
OK, Thanks. Nice to know
Best regards --- Kuninori Morimoto
dri-devel@lists.freedesktop.org