summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>2022-08-24 15:47:25 +0300
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2022-09-07 23:48:42 +0300
commit957fe62d7d15f43d49e8cbacafaff8ede7d6cb30 (patch)
tree9edc14e56ef057cbf474a384d264a5c126091672 /drivers/gpu/drm/rcar-du/rcar_du_crtc.c
parent222abba69c620875c60b20cf77356f260d360ac8 (diff)
downloadlinux-957fe62d7d15f43d49e8cbacafaff8ede7d6cb30.tar.xz
drm: rcar-du: Fix DSI enable & disable sequence
The rcar crtc depends on the clock provided from the rcar DSI bridge. When the DSI bridge is disabled, the clock is stopped, which causes the crtc disable to timeout. Also, while I have no issue with the enable, the documentation suggests to enable the DSI before the crtc so that the crtc has its clock enabled at enable time. This is also not done by the current driver. To fix this, we need to keep the DSI bridge enabled until the crtc has disabled itself, and enable the DSI bridge before crtc enables itself. Add functions rcar_mipi_dsi_pclk_enable and rcar_mipi_dsi_pclk_disable to the rcar DSI bridge driver which the rcar driver can use to enable/disable the DSI clock when needed. This is similar to what is already done with the rcar LVDS bridge. Signed-off-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Diffstat (limited to 'drivers/gpu/drm/rcar-du/rcar_du_crtc.c')
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index d38092d85df7..3619e1ddeb62 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -29,6 +29,7 @@
#include "rcar_du_regs.h"
#include "rcar_du_vsp.h"
#include "rcar_lvds.h"
+#include "rcar_mipi_dsi.h"
static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
{
@@ -747,6 +748,18 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
rcar_lvds_pclk_enable(bridge, mode->clock * 1000);
}
+ /*
+ * Similarly to LVDS, on V3U the dot clock is provided by the DSI
+ * encoder, and we need to enable the DSI clocks before enabling the CRTC.
+ */
+ if ((rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) &&
+ (rstate->outputs &
+ (BIT(RCAR_DU_OUTPUT_DSI0) | BIT(RCAR_DU_OUTPUT_DSI1)))) {
+ struct drm_bridge *bridge = rcdu->dsi[rcrtc->index];
+
+ rcar_mipi_dsi_pclk_enable(bridge, state);
+ }
+
rcar_du_crtc_start(rcrtc);
/*
@@ -780,6 +793,19 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
rcar_lvds_pclk_disable(bridge);
}
+ if ((rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) &&
+ (rstate->outputs &
+ (BIT(RCAR_DU_OUTPUT_DSI0) | BIT(RCAR_DU_OUTPUT_DSI1)))) {
+ struct drm_bridge *bridge = rcdu->dsi[rcrtc->index];
+
+ /*
+ * Disable the DSI clock output, see
+ * rcar_du_crtc_atomic_enable().
+ */
+
+ rcar_mipi_dsi_pclk_disable(bridge);
+ }
+
spin_lock_irq(&crtc->dev->event_lock);
if (crtc->state->event) {
drm_crtc_send_vblank_event(crtc, crtc->state->event);