Message ID | 006c5ae9b1b39b684fa0035b53dcbe9408244721.1495796138.git.jsarha@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, May 26, 2017 at 12:56 PM, Jyri Sarha <jsarha@ti.com> wrote: > The best possible crtc reset callback implementation would be reading > the video mode information from the registers and generating the new > crtc state based on that. But I have no idea what I should do with > framebuffer that was used and how to show that in the state variable. > Anyway, right now I do not have more time to spend with this. You need to wrap it up into a real drm_framebuffer and store a reference to that in the plane_state->fb pointer. Which means you also need to read out the plane_state (or at least parts of it). A more minimal approach would be to just read out the crtc state, and force-disable all the planes on reset. That still gives you the benefit of avoiding the modeset (since hopefully the compositor/bootsplash/whatever just change the plane setup, not the mode). But that only works with some hw, and not if your primary plane is tied to the crtc. Also, currently only i915 does such fastboot tricks, but I assume once there's more drivers there's some big room for extracting helpers. -Daniel
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index d524ed0..9ca134d 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -716,11 +716,39 @@ static void tilcdc_crtc_disable_vblank(struct drm_crtc *crtc) { } +static void tilcdc_crtc_reset(struct drm_crtc *crtc) +{ + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); + struct drm_device *dev = crtc->dev; + int ret; + + drm_atomic_helper_crtc_reset(crtc); + + /* Turn the raster off if it for some reason is on. */ + pm_runtime_get_sync(dev->dev); + if (tilcdc_read(dev, LCDC_RASTER_CTRL_REG) & LCDC_RASTER_ENABLE) { + /* Enable DMA Frame Done Interrupt */ + tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_FRAME_DONE); + tilcdc_clear_irqstatus(dev, 0xffffffff); + + tilcdc_crtc->frame_done = false; + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); + + ret = wait_event_timeout(tilcdc_crtc->frame_done_wq, + tilcdc_crtc->frame_done, + msecs_to_jiffies(500)); + if (ret == 0) + dev_err(dev->dev, "%s: timeout waiting for framedone\n", + __func__); + } + pm_runtime_put_sync(dev->dev); +} + static const struct drm_crtc_funcs tilcdc_crtc_funcs = { .destroy = tilcdc_crtc_destroy, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, - .reset = drm_atomic_helper_crtc_reset, + .reset = tilcdc_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, .enable_vblank = tilcdc_crtc_enable_vblank,
This forces the HW to be in sync with the empty state. This should help with the problem when LCDC is already enabled (e.g. by the bootloader) at the initialization phase and the enable fails when a new mode is applied. Signed-off-by: Jyri Sarha <jsarha@ti.com> --- There is two earlier patches that try to tackle the same problem: 1. https://lists.freedesktop.org/archives/dri-devel/2017-March/137091.html - This supposedly works, but I did not like second guessing if the display was already on every we enable the display 2. https://patchwork.kernel.org/patch/9672341/ - My first attempt to try to fix the problem The best possible crtc reset callback implementation would be reading the video mode information from the registers and generating the new crtc state based on that. But I have no idea what I should do with framebuffer that was used and how to show that in the state variable. Anyway, right now I do not have more time to spend with this. drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-)