From d68164fe29642270ffba64ed64b0178ef7d916bf Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 21 Sep 2018 16:13:00 +0300 Subject: [PATCH] drm/omap: Factor out common mode validation code The encoder .atomic_check() and connector .mode_valid() operations both walk through the dss devices in the pipeline to validate the mode. Factor out the common code in a new omap_drm_connector_mode_fixup() function. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel Tested-by: Sebastian Reichel Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_connector.c | 54 +++++++++++++----------- drivers/gpu/drm/omapdrm/omap_connector.h | 5 +++ drivers/gpu/drm/omapdrm/omap_encoder.c | 28 ++++-------- 3 files changed, 43 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 99ca5b3eaebb..6fceb020e86c 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -241,45 +241,51 @@ static int omap_connector_get_modes(struct drm_connector *connector) return 0; } -static int omap_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +enum drm_mode_status omap_connector_mode_fixup(struct omap_dss_device *dssdev, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { - struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *dssdev; - struct videomode vm = {0}; - struct drm_device *dev = connector->dev; - struct drm_display_mode *new_mode; - int r, ret = MODE_BAD; + struct videomode vm = { 0 }; + int ret; drm_display_mode_to_videomode(mode, &vm); - mode->vrefresh = drm_mode_vrefresh(mode); - for (dssdev = omap_connector->output; dssdev; dssdev = dssdev->next) { + for (; dssdev; dssdev = dssdev->next) { if (!dssdev->ops->check_timings) continue; - r = dssdev->ops->check_timings(dssdev, &vm); - if (r) - goto done; + ret = dssdev->ops->check_timings(dssdev, &vm); + if (ret) + return MODE_BAD; } - /* check if vrefresh is still valid */ - new_mode = drm_mode_duplicate(dev, mode); - if (!new_mode) - return MODE_BAD; + drm_display_mode_from_videomode(&vm, adjusted_mode); - new_mode->clock = vm.pixelclock / 1000; - new_mode->vrefresh = 0; - if (mode->vrefresh == drm_mode_vrefresh(new_mode)) - ret = MODE_OK; - drm_mode_destroy(dev, new_mode); + return MODE_OK; +} + +static enum drm_mode_status omap_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct omap_connector *omap_connector = to_omap_connector(connector); + struct drm_display_mode new_mode = { { 0 } }; + enum drm_mode_status status; + + status = omap_connector_mode_fixup(omap_connector->output, mode, + &new_mode); + if (status != MODE_OK) + goto done; + + /* Check if vrefresh is still valid. */ + if (drm_mode_vrefresh(mode) != drm_mode_vrefresh(&new_mode)) + status = MODE_NOCLOCK; done: DBG("connector: mode %s: " DRM_MODE_FMT, - (ret == MODE_OK) ? "valid" : "invalid", + (status == MODE_OK) ? "valid" : "invalid", DRM_MODE_ARG(mode)); - return ret; + return status; } static const struct drm_connector_funcs omap_connector_funcs = { diff --git a/drivers/gpu/drm/omapdrm/omap_connector.h b/drivers/gpu/drm/omapdrm/omap_connector.h index 4a1dcd0f031b..6b7d4d95e32b 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.h +++ b/drivers/gpu/drm/omapdrm/omap_connector.h @@ -22,6 +22,8 @@ #include +enum drm_mode_status; + struct drm_connector; struct drm_device; struct drm_encoder; @@ -34,5 +36,8 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, bool omap_connector_get_hdmi_mode(struct drm_connector *connector); void omap_connector_enable_hpd(struct drm_connector *connector); void omap_connector_disable_hpd(struct drm_connector *connector); +enum drm_mode_status omap_connector_mode_fixup(struct omap_dss_device *dssdev, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); #endif /* __OMAPDRM_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 623154bc44bb..3a7cca01888e 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -206,29 +206,17 @@ static int omap_encoder_atomic_check(struct drm_encoder *encoder, struct drm_connector_state *conn_state) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct omap_dss_device *dssdev; - struct videomode vm = { 0 }; - int ret; + enum drm_mode_status status; - drm_display_mode_to_videomode(&crtc_state->mode, &vm); - - for (dssdev = omap_encoder->output; dssdev; dssdev = dssdev->next) { - if (!dssdev->ops->check_timings) - continue; - - ret = dssdev->ops->check_timings(dssdev, &vm); - if (ret) - goto done; + status = omap_connector_mode_fixup(omap_encoder->output, + &crtc_state->mode, + &crtc_state->adjusted_mode); + if (status != MODE_OK) { + dev_err(encoder->dev->dev, "invalid timings: %d\n", status); + return -EINVAL; } - drm_display_mode_from_videomode(&vm, &crtc_state->adjusted_mode); - -done: - if (ret) - dev_err(dev->dev, "invalid timings: %d\n", ret); - - return ret; + return 0; } static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {