summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/mcde/mcde_display.c32
-rw-r--r--drivers/gpu/drm/mcde/mcde_drm.h1
-rw-r--r--drivers/gpu/drm/mcde/mcde_drv.c2
-rw-r--r--drivers/gpu/drm/mcde/mcde_dsi.c13
4 files changed, 30 insertions, 18 deletions
diff --git a/drivers/gpu/drm/mcde/mcde_display.c b/drivers/gpu/drm/mcde/mcde_display.c
index 65522481b367..a3375a974caf 100644
--- a/drivers/gpu/drm/mcde/mcde_display.c
+++ b/drivers/gpu/drm/mcde/mcde_display.c
@@ -498,24 +498,20 @@ static void mcde_configure_channel(struct mcde *mcde, enum mcde_channel ch,
}
/* Set up channel 0 sync (based on chnl_update_registers()) */
- if (mcde->te_sync) {
- /*
- * Turn on hardware TE0 synchronization
- */
+ if (mcde->video_mode || mcde->te_sync)
val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE
<< MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;
- val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0
- << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;
- } else {
- /*
- * Set up sync source to software, out sync formatter
- * Code mostly from mcde_hw.c chnl_update_registers()
- */
+ else
val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SOFTWARE
<< MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;
+
+ if (mcde->te_sync)
+ val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0
+ << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;
+ else
val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER
<< MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;
- }
+
writel(val, mcde->regs + sync);
/* Set up pixels per line and lines per frame */
@@ -938,6 +934,13 @@ static void mcde_display_enable(struct drm_simple_display_pipe *pipe,
drm_crtc_vblank_on(crtc);
+ if (mcde->video_mode)
+ /*
+ * Keep FIFO permanently enabled in video mode,
+ * otherwise MCDE will stop feeding data to the panel.
+ */
+ mcde_enable_fifo(mcde, MCDE_FIFO_A);
+
dev_info(drm->dev, "MCDE display is enabled\n");
}
@@ -1047,8 +1050,9 @@ static void mcde_display_update(struct drm_simple_display_pipe *pipe,
*/
if (fb) {
mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0));
- /* Send a single frame using software sync */
- mcde_display_send_one_frame(mcde);
+ if (!mcde->video_mode)
+ /* Send a single frame using software sync */
+ mcde_display_send_one_frame(mcde);
dev_info_once(mcde->dev, "sent first display update\n");
} else {
/*
diff --git a/drivers/gpu/drm/mcde/mcde_drm.h b/drivers/gpu/drm/mcde/mcde_drm.h
index dab4db021231..80edd6628979 100644
--- a/drivers/gpu/drm/mcde/mcde_drm.h
+++ b/drivers/gpu/drm/mcde/mcde_drm.h
@@ -19,6 +19,7 @@ struct mcde {
struct mipi_dsi_device *mdsi;
s16 stride;
bool te_sync;
+ bool video_mode;
bool oneshot_mode;
unsigned int flow_active;
spinlock_t flow_lock; /* Locks the channel flow control */
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index 0ccd3b0308c2..9008ddcfc528 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -331,8 +331,6 @@ static int mcde_probe(struct platform_device *pdev)
drm->dev_private = mcde;
platform_set_drvdata(pdev, drm);
- /* Enable use of the TE signal and interrupt */
- mcde->te_sync = true;
/* Enable continuous updates: this is what Linux' framebuffer expects */
mcde->oneshot_mode = false;
drm->dev_private = mcde;
diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c
index d6214d3c8b33..ffd2e0b64628 100644
--- a/drivers/gpu/drm/mcde/mcde_dsi.c
+++ b/drivers/gpu/drm/mcde/mcde_dsi.c
@@ -130,6 +130,15 @@ bool mcde_dsi_irq(struct mipi_dsi_device *mdsi)
return te_received;
}
+static void mcde_dsi_attach_to_mcde(struct mcde_dsi *d)
+{
+ d->mcde->mdsi = d->mdsi;
+
+ d->mcde->video_mode = !!(d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO);
+ /* Enable use of the TE signal for all command mode panels */
+ d->mcde->te_sync = !d->mcde->video_mode;
+}
+
static int mcde_dsi_host_attach(struct mipi_dsi_host *host,
struct mipi_dsi_device *mdsi)
{
@@ -148,7 +157,7 @@ static int mcde_dsi_host_attach(struct mipi_dsi_host *host,
d->mdsi = mdsi;
if (d->mcde)
- d->mcde->mdsi = mdsi;
+ mcde_dsi_attach_to_mcde(d);
return 0;
}
@@ -901,7 +910,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
d->mcde = mcde;
/* If the display attached before binding, set this up */
if (d->mdsi)
- d->mcde->mdsi = d->mdsi;
+ mcde_dsi_attach_to_mcde(d);
/* Obtain the clocks */
d->hs_clk = devm_clk_get(dev, "hs");