diff options
-rw-r--r-- | drivers/gpu/drm/mcde/mcde_display.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/mcde/mcde_drm.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/mcde/mcde_drv.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/mcde/mcde_dsi.c | 13 |
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"); |