aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRahul Sharma <rahul.sharma@samsung.com>2013-01-15 08:11:05 -0500
committerInki Dae <inki.dae@samsung.com>2013-02-21 01:00:27 -0500
commit438c0f85cbbe6e7025e2375f97f5223b6eac5cd7 (patch)
treeea3bec17569b0a299a289ce4798ac10bd0e4cbc2
parent979c0c7eb0fb969f0621c7017a6a87e6a0e36a4c (diff)
drm/exynos: add display-mode-check operation to exynos_mixer_ops struct
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@samsung.com> Reviewed-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.h5
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c13
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 28644539b305..7c27df03c9ff 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -124,9 +124,21 @@ static struct edid *drm_hdmi_get_edid(struct device *dev,
124static int drm_hdmi_check_timing(struct device *dev, void *timing) 124static int drm_hdmi_check_timing(struct device *dev, void *timing)
125{ 125{
126 struct drm_hdmi_context *ctx = to_context(dev); 126 struct drm_hdmi_context *ctx = to_context(dev);
127 int ret = 0;
127 128
128 DRM_DEBUG_KMS("%s\n", __FILE__); 129 DRM_DEBUG_KMS("%s\n", __FILE__);
129 130
131 /*
132 * Both, mixer and hdmi should be able to handle the requested mode.
133 * If any of the two fails, return mode as BAD.
134 */
135
136 if (mixer_ops && mixer_ops->check_timing)
137 ret = mixer_ops->check_timing(ctx->mixer_ctx->ctx, timing);
138
139 if (ret)
140 return ret;
141
130 if (hdmi_ops && hdmi_ops->check_timing) 142 if (hdmi_ops && hdmi_ops->check_timing)
131 return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing); 143 return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);
132 144
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index d80516fc9ed7..b7faa3662307 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 {
32 bool (*is_connected)(void *ctx); 32 bool (*is_connected)(void *ctx);
33 struct edid *(*get_edid)(void *ctx, 33 struct edid *(*get_edid)(void *ctx,
34 struct drm_connector *connector); 34 struct drm_connector *connector);
35 int (*check_timing)(void *ctx, void *timing); 35 int (*check_timing)(void *ctx, struct fb_videomode *timing);
36 int (*power_on)(void *ctx, int mode); 36 int (*power_on)(void *ctx, int mode);
37 37
38 /* manager */ 38 /* manager */
@@ -58,6 +58,9 @@ struct exynos_mixer_ops {
58 void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); 58 void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
59 void (*win_commit)(void *ctx, int zpos); 59 void (*win_commit)(void *ctx, int zpos);
60 void (*win_disable)(void *ctx, int zpos); 60 void (*win_disable)(void *ctx, int zpos);
61
62 /* display */
63 int (*check_timing)(void *ctx, struct fb_videomode *timing);
61}; 64};
62 65
63void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx); 66void 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 fbab3c468603..ba3301575525 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1457,21 +1457,20 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1457 return -EINVAL; 1457 return -EINVAL;
1458} 1458}
1459 1459
1460static int hdmi_check_timing(void *ctx, void *timing) 1460static int hdmi_check_timing(void *ctx, struct fb_videomode *timing)
1461{ 1461{
1462 struct hdmi_context *hdata = ctx; 1462 struct hdmi_context *hdata = ctx;
1463 struct fb_videomode *check_timing = timing;
1464 1463
1465 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1464 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1466 1465
1467 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres, 1466 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", timing->xres,
1468 check_timing->yres, check_timing->refresh, 1467 timing->yres, timing->refresh,
1469 check_timing->vmode); 1468 timing->vmode);
1470 1469
1471 if (hdata->type == HDMI_TYPE13) 1470 if (hdata->type == HDMI_TYPE13)
1472 return hdmi_v13_check_timing(check_timing); 1471 return hdmi_v13_check_timing(timing);
1473 else 1472 else
1474 return hdmi_v14_check_timing(check_timing); 1473 return hdmi_v14_check_timing(timing);
1475} 1474}
1476 1475
1477static void hdmi_set_acr(u32 freq, u8 *acr) 1476static void hdmi_set_acr(u32 freq, u8 *acr)