diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 5554b72cf56a78d4b469ffe651df697b7034ddf0..d956e6266368afd6c4378e049d6c778f3d31f884 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -2506,6 +2506,25 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk, return -EINVAL; } + if (*decim_x > 4 && color_mode != OMAP_DSS_COLOR_NV12) { + /* + * Let's disable all scaling that requires horizontal + * decimation with higher factor than 4, until we have + * better estimates of what we can and can not + * do. However, NV12 color format appears to work Ok + * with all decimation factors. + * + * When decimating horizontally by more that 4 the dss + * is not able to fetch the data in burst mode. When + * this happens it is hard to tell if there enough + * bandwidth. Despite what theory says this appears to + * be true also for 16-bit color formats. + */ + DSSERR("Not enough bandwidth, too much downscaling (x-decimation factor %d > 4)", *decim_x); + + return -EINVAL; + } + *core_clk = dispc.feat->calc_core_clk(pclk, in_width, in_height, out_width, out_height, mem_to_mem); return 0; diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index dd47dc191e6b1ce10f41818156cb532e857c2ba2..b68c70eb395f2dccf55e6f775738ea4be3c62690 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -410,13 +410,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc, dispc_mgr_set_gamma(omap_crtc->channel, lut, length); } - /* - * Only flush the CRTC if it is currently enabled. CRTCs that require a - * mode set are disabled prior plane updates and enabled afterwards. - * They are thus not active (regardless of what their CRTC core state - * reports) and the DRM core could thus call this function even though - * the CRTC is currently disabled. Do nothing in that case. - */ + /* Only flush the CRTC if it is currently enabled. */ if (!omap_crtc->enabled) return; diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index afe8f05b927b2c43170a58f5564be44c01c0fc60..3f2554235225b5b5a37960d4e8511be1ff057e09 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -96,9 +96,22 @@ static void omap_atomic_complete(struct omap_atomic_state_commit *commit) dispc_runtime_get(); drm_atomic_helper_commit_modeset_disables(dev, old_state); - drm_atomic_helper_commit_planes(dev, old_state, - DRM_PLANE_COMMIT_ACTIVE_ONLY); + + /* With the current dss dispc implementation we have to enable + * the new modeset before we can commit planes. The dispc ovl + * configuration relies on the video mode configuration been + * written into the HW when the ovl configuration is + * calculated. + * + * This approach is not ideal because after a mode change the + * plane update is executed only after the first vblank + * interrupt. The dispc implementation should be fixed so that + * it is able use uncommitted drm state information. + */ drm_atomic_helper_commit_modeset_enables(dev, old_state); + omap_atomic_wait_for_completion(dev, old_state); + + drm_atomic_helper_commit_planes(dev, old_state, 0); omap_atomic_wait_for_completion(dev, old_state);