drm/ingenic: Validate mode in a .mode_valid callback
authorPaul Cercueil <paul@crapouillou.net>
Tue, 28 Jul 2020 15:16:41 +0000 (17:16 +0200)
committerPaul Cercueil <paul@crapouillou.net>
Wed, 29 Jul 2020 00:29:46 +0000 (02:29 +0200)
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 <paul@crapouillou.net>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200728151641.26124-3-paul@crapouillou.net
drivers/gpu/drm/ingenic/ingenic-drm-drv.c

index 64eabab3ef691b9422a4f191eb3082ab4436cbba..5dab9c3d0a520283c42266c24c0f9a256b2406a1 100644 (file)
@@ -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 = {