This patch adds the display mode check operation to exynos_mixer_ops in drm-common-hdmi. In Exynos SoCs, mixer IP can put certain restrictions on the proposed display modes. These restriction needs to be considered during mode negotiation, which happens immediately after edid parsing. Both, mixer check-mode and hdmi check-timing callbacks are called one after another and ANDed result is returned back. Signed-off-by: Rahul Sharma <rahul.sharma@xxxxxxxxxxx> --- drivers/gpu/drm/exynos/exynos_drm_hdmi.c | 12 ++++++++++++ drivers/gpu/drm/exynos/exynos_drm_hdmi.h | 5 ++++- drivers/gpu/drm/exynos/exynos_hdmi.c | 13 ++++++------- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 55793c4..1c06a11 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -125,9 +125,21 @@ static int drm_hdmi_get_edid(struct device *dev, static int drm_hdmi_check_timing(struct device *dev, void *timing) { struct drm_hdmi_context *ctx = to_context(dev); + int ret = 0; DRM_DEBUG_KMS("%s\n", __FILE__); + /* + * Both, mixer and hdmi should be able to handle the requested mode. + * If any of the two fails, return mode as BAD. + */ + + if (mixer_ops && mixer_ops->check_timing) + ret = mixer_ops->check_timing(ctx->mixer_ctx->ctx, timing); + + if (ret) + return ret; + if (hdmi_ops && hdmi_ops->check_timing) return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing); diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index 784a7e9..f5202af 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h @@ -32,7 +32,7 @@ struct exynos_hdmi_ops { bool (*is_connected)(void *ctx); int (*get_edid)(void *ctx, struct drm_connector *connector, u8 *edid, int len); - int (*check_timing)(void *ctx, void *timing); + int (*check_timing)(void *ctx, struct fb_videomode *timing); int (*power_on)(void *ctx, int mode); /* manager */ @@ -58,6 +58,9 @@ struct exynos_mixer_ops { void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); void (*win_commit)(void *ctx, int zpos); void (*win_disable)(void *ctx, int zpos); + + /* display */ + int (*check_timing)(void *ctx, struct fb_videomode *timing); }; void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx); diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 2c46b6c..d9d742a 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1464,21 +1464,20 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing) return -EINVAL; } -static int hdmi_check_timing(void *ctx, void *timing) +static int hdmi_check_timing(void *ctx, struct fb_videomode *timing) { struct hdmi_context *hdata = ctx; - struct fb_videomode *check_timing = timing; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres, - check_timing->yres, check_timing->refresh, - check_timing->vmode); + DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", timing->xres, + timing->yres, timing->refresh, + timing->vmode); if (hdata->type == HDMI_TYPE13) - return hdmi_v13_check_timing(check_timing); + return hdmi_v13_check_timing(timing); else - return hdmi_v14_check_timing(check_timing); + return hdmi_v14_check_timing(timing); } static void hdmi_set_acr(u32 freq, u8 *acr) -- 1.8.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel