diff options
author | Stefan Eichenberger <stefan.eichenberger@toradex.com> | 2023-09-11 10:16:50 +0200 |
---|---|---|
committer | Stefan Eichenberger <eichest@gmail.com> | 2023-09-27 09:10:51 +0200 |
commit | 946d7e24107a26c6f27ce9c5a687246844d449d6 (patch) | |
tree | 4ae99e5a0918b9ab829b9b8a1595bbeef48632e3 | |
parent | 49e4130e2197bd79e232faa746a449d167335778 (diff) |
gpu: drm: imx: lcdif-mux: enable the clk_pixel when the driver binds
Make sure to enable the clk_pixel clock during bind so that all other
driver in the display pipeline can rely on it. Without this change we
might see ghosting effects in around 10% of the reboots because
something in the display pipeline runs out of sync. With this change we
don't disable the clk_pixel when the display is turned off so this might
increase the power consumption in standby mode a bit. However, it would
require some bigger changes in the display pipeline to allow this.
Upstream-Status: Inappropriate [other]
The dpu is currently only supported in the downstream kernel. A fix will
most likely be applied by NXP to the downstream kernel. A similar patch
was provided by them but it breaks the DPMS off/standby mode. See this
ticket for more information:
https://support.nxp.com/s/case/5002p00002vUMOL/ghosting-effect-on-parallel-rgb-interface
Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
-rw-r--r-- | drivers/gpu/drm/imx/lcdif-mux-display.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/drivers/gpu/drm/imx/lcdif-mux-display.c b/drivers/gpu/drm/imx/lcdif-mux-display.c index 58e4226c0bbe..2cf60429fee0 100644 --- a/drivers/gpu/drm/imx/lcdif-mux-display.c +++ b/drivers/gpu/drm/imx/lcdif-mux-display.c @@ -48,20 +48,6 @@ static inline struct imx_lcdif_mux_display *enc_to_lmuxd(struct drm_encoder *e) return container_of(e, struct imx_lcdif_mux_display, encoder); } -static void imx_lmuxd_encoder_enable(struct drm_encoder *encoder) -{ - struct imx_lcdif_mux_display *lmuxd = enc_to_lmuxd(encoder); - - clk_prepare_enable(lmuxd->clk_pixel); -} - -static void imx_lmuxd_encoder_disable(struct drm_encoder *encoder) -{ - struct imx_lcdif_mux_display *lmuxd = enc_to_lmuxd(encoder); - - clk_disable_unprepare(lmuxd->clk_pixel); -} - static void imx_lmuxd_encoder_atomic_mode_set(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, @@ -120,8 +106,6 @@ static const struct drm_encoder_funcs imx_lmuxd_encoder_funcs = { }; static const struct drm_encoder_helper_funcs imx_lmuxd_encoder_helper_funcs = { - .enable = imx_lmuxd_encoder_enable, - .disable = imx_lmuxd_encoder_disable, .atomic_mode_set = imx_lmuxd_encoder_atomic_mode_set, .atomic_check = imx_lmuxd_encoder_atomic_check, }; @@ -200,14 +184,33 @@ static int imx_lmuxd_bind(struct device *dev, struct device *master, void *data) } } + /** + * We need to make sure the clock is enabled the whole time we use this + * driver. Else it might happen that something in the display pipeline + * runs out of sync and we see some ghosting effects. It is not clear + * what exactly triggers this issue and could maybe also be solved in + * the driver that causes the issue by adding a dependency to the pixel + * clock. + */ + ret = clk_prepare_enable(lmuxd->clk_pixel); + if (ret) + return ret; + lmuxd->dev = dev; - return imx_lmuxd_register(drm, lmuxd); + ret = imx_lmuxd_register(drm, lmuxd); + if (ret) + clk_disable_unprepare(lmuxd->clk_pixel); + + return ret; } static void imx_lmuxd_unbind(struct device *dev, struct device *master, void *data) { + struct imx_lcdif_mux_display *lmuxd = dev_get_drvdata(dev); + + clk_disable_unprepare(lmuxd->clk_pixel); } static const struct component_ops imx_lmuxd_ops = { |