The dispc_vp_mode_valid() function checks whether a mode can be handled by the display controller.
There's a whole bunch of criteria, and it's not clear when a rejection happens why it did. Add logs on each rejection criterion to make it clearer. Signed-off-by: Maxime Ripard <[email protected]> --- drivers/gpu/drm/tidss/tidss_dispc.c | 45 +++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index 58d5eb033bdb..4cda3824864b 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -1302,10 +1302,12 @@ unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate) } static int check_pixel_clock(struct dispc_device *dispc, u32 hw_videoport, unsigned long clock) { + struct tidss_device *tidss = dispc->tidss; + struct drm_device *dev = &tidss->ddev; unsigned long round_clock; /* * For VP's with external clocking, clock operations must be * delegated to respective driver, so we skip the check here. @@ -1316,51 +1318,65 @@ static int check_pixel_clock(struct dispc_device *dispc, u32 hw_videoport, round_clock = clk_round_rate(dispc->vp_clk[hw_videoport], clock); /* * To keep the check consistent with dispc_vp_set_clk_rate(), we * use the same 5% check here. */ - if (dispc_pclk_diff(clock, round_clock) > 5) + if (dispc_pclk_diff(clock, round_clock) > 5) { + drm_dbg(dev, "Mode pixel clock below hardware minimum pixel clock."); return -EINVAL; + } return 0; } enum drm_mode_status dispc_vp_mode_valid(struct dispc_device *dispc, u32 hw_videoport, const struct drm_display_mode *mode) { + struct tidss_device *tidss = dispc->tidss; + struct drm_device *dev = &tidss->ddev; u32 hsw, hfp, hbp, vsw, vfp, vbp; enum dispc_vp_bus_type bus_type; bus_type = dispc->feat->vp_bus_type[hw_videoport]; - if (WARN_ON(bus_type == DISPC_VP_TIED_OFF)) + if (WARN_ON(bus_type == DISPC_VP_TIED_OFF)) { + drm_dbg(dev, "Invalid bus type."); return MODE_BAD; + } - if (mode->hdisplay > 4096) + if (mode->hdisplay > 4096) { + drm_dbg(dev, "Number of active horizontal pixels above hardware limits."); return MODE_BAD; + } - if (mode->vdisplay > 4096) + if (mode->vdisplay > 4096) { + drm_dbg(dev, "Number of active vertical lines above hardware limits."); return MODE_BAD; + } if (check_pixel_clock(dispc, hw_videoport, mode->clock * 1000)) return MODE_CLOCK_RANGE; /* TODO: add interlace support */ - if (mode->flags & DRM_MODE_FLAG_INTERLACE) + if (mode->flags & DRM_MODE_FLAG_INTERLACE) { + drm_dbg(dev, "Interlace modes not supported."); return MODE_NO_INTERLACE; + } /* * Enforce the output width is divisible by 2. Actually this * is only needed in following cases: * - YUV output selected (BT656, BT1120) * - Dithering enabled * - TDM with TDMCycleFormat == 3 * But for simplicity we enforce that always. */ - if ((mode->hdisplay % 2) != 0) + if ((mode->hdisplay % 2) != 0) { + drm_dbg(dev, "Number of active horizontal pixels must be even."); return MODE_BAD_HVALUE; + } hfp = mode->hsync_start - mode->hdisplay; hsw = mode->hsync_end - mode->hsync_start; hbp = mode->htotal - mode->hsync_end; @@ -1368,29 +1384,40 @@ enum drm_mode_status dispc_vp_mode_valid(struct dispc_device *dispc, vsw = mode->vsync_end - mode->vsync_start; vbp = mode->vtotal - mode->vsync_end; if (hsw < 1 || hsw > 256 || hfp < 1 || hfp > 4096 || - hbp < 1 || hbp > 4096) + hbp < 1 || hbp > 4096) { + drm_dbg(dev, + "Horizontal blanking or sync outside of hardware limits (fp: %u, sw: %u, bp: %u).", + hfp, hsw, hbp); return MODE_BAD_HVALUE; + } if (vsw < 1 || vsw > 256 || - vfp > 4095 || vbp > 4095) + vfp > 4095 || vbp > 4095) { + drm_dbg(dev, + "Vertical blanking or sync outside of hardware limits (fp: %u, sw: %u, bp: %u).", + vfp, vsw, vbp); return MODE_BAD_VVALUE; + } if (dispc->memory_bandwidth_limit) { const unsigned int bpp = 4; u64 bandwidth; bandwidth = 1000 * mode->clock; bandwidth = bandwidth * mode->hdisplay * mode->vdisplay * bpp; bandwidth = div_u64(bandwidth, mode->htotal * mode->vtotal); - if (dispc->memory_bandwidth_limit < bandwidth) + if (dispc->memory_bandwidth_limit < bandwidth) { + drm_dbg(dev, "Required memory bandwidth outside of hardware limits."); return MODE_BAD; + } } + drm_dbg(dev, "Mode is valid."); return MODE_OK; } int dispc_vp_enable_clk(struct dispc_device *dispc, u32 hw_videoport) { -- 2.54.0
