From: Paul Cercueil Date: Tue, 28 Jul 2020 15:16:41 +0000 (+0200) Subject: drm/ingenic: Validate mode in a .mode_valid callback X-Git-Tag: v5.10.7~1332^2~33^2~208 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=639abb72f189a9df1033cbe5eaf1c0508021f699;p=platform%2Fkernel%2Flinux-rpi.git drm/ingenic: Validate mode in a .mode_valid callback Validate modes in the drm_crtc_helper_funcs.mode_valid() callback, which is designed for this purpose, instead of doing it in drm_crtc_helper_funcs.atomic_check(). Signed-off-by: Paul Cercueil Reviewed-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200728151641.26124-3-paul@crapouillou.net --- diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 64eabab..5dab9c3 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -199,21 +199,8 @@ static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc, { struct ingenic_drm *priv = drm_crtc_get_priv(crtc); struct drm_plane_state *f1_state, *f0_state, *ipu_state = NULL; - long rate; - - if (!drm_atomic_crtc_needs_modeset(state)) - return 0; - - if (state->mode.hdisplay > priv->soc_info->max_width || - state->mode.vdisplay > priv->soc_info->max_height) - return -EINVAL; - rate = clk_round_rate(priv->pix_clk, - state->adjusted_mode.clock * 1000); - if (rate < 0) - return rate; - - if (priv->soc_info->has_osd) { + if (drm_atomic_crtc_needs_modeset(state) && priv->soc_info->has_osd) { f1_state = drm_atomic_get_plane_state(state->state, &priv->f1); if (IS_ERR(f1_state)) return PTR_ERR(f1_state); @@ -242,6 +229,24 @@ static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc, return 0; } +static enum drm_mode_status +ingenic_drm_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) +{ + struct ingenic_drm *priv = drm_crtc_get_priv(crtc); + long rate; + + if (mode->hdisplay > priv->soc_info->max_width) + return MODE_BAD_HVALUE; + if (mode->vdisplay > priv->soc_info->max_height) + return MODE_BAD_VVALUE; + + rate = clk_round_rate(priv->pix_clk, mode->clock * 1000); + if (rate < 0) + return MODE_CLOCK_RANGE; + + return MODE_OK; +} + static void ingenic_drm_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *oldstate) { @@ -655,6 +660,7 @@ static const struct drm_crtc_helper_funcs ingenic_drm_crtc_helper_funcs = { .atomic_begin = ingenic_drm_crtc_atomic_begin, .atomic_flush = ingenic_drm_crtc_atomic_flush, .atomic_check = ingenic_drm_crtc_atomic_check, + .mode_valid = ingenic_drm_crtc_mode_valid, }; static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs = {