diff options
author | Paul Cercueil <paul@crapouillou.net> | 2020-07-28 17:16:41 +0200 |
---|---|---|
committer | Paul Cercueil <paul@crapouillou.net> | 2020-07-29 02:29:46 +0200 |
commit | 639abb72f189a9df1033cbe5eaf1c0508021f699 (patch) | |
tree | fea83011bbfebbafe624c1225a249bfca72c1620 /drivers/gpu/drm/ingenic | |
parent | c114e72313045108d6ddc1847b4ffff4e50ab444 (diff) |
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 <paul@crapouillou.net>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200728151641.26124-3-paul@crapouillou.net
Diffstat (limited to 'drivers/gpu/drm/ingenic')
-rw-r--r-- | drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 64eabab3ef69..5dab9c3d0a52 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 = { |