diff options
author | Rahul Sharma <rahul.sharma@samsung.com> | 2013-03-06 03:28:16 -0500 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2013-04-16 11:06:42 -0400 |
commit | 7ddcc7364a93d18b80967b3a9b3f6aea107323f6 (patch) | |
tree | 0b4e7f21efd604b335a33799439c261d98d694e2 | |
parent | 6b986edfbce195b4111f96a43221fc6d387277ba (diff) |
drm/exynos: hdmi: move mode_fixup to drm common hdmi
Currently, mode_fixup code doesn't consider the limitations of mixer as it
is implemented inside the hdmi driver. Following fix, moves the mode_fixup
to common drm hdmi driver. To check the mode support, it calls both, mixer
and hdmi check_timing callbacks for a given resolution mode.
This patch is dependent on https://patchwork.kernel.org/patch/2176021/.
Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_hdmi.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_hdmi.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_hdmi.c | 47 |
3 files changed, 36 insertions, 54 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 7c27df03c9ff..5285509e4b34 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c | |||
@@ -205,13 +205,45 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev, | |||
205 | const struct drm_display_mode *mode, | 205 | const struct drm_display_mode *mode, |
206 | struct drm_display_mode *adjusted_mode) | 206 | struct drm_display_mode *adjusted_mode) |
207 | { | 207 | { |
208 | struct drm_hdmi_context *ctx = to_context(subdrv_dev); | 208 | struct drm_display_mode *m; |
209 | int mode_ok; | ||
209 | 210 | ||
210 | DRM_DEBUG_KMS("%s\n", __FILE__); | 211 | DRM_DEBUG_KMS("%s\n", __FILE__); |
211 | 212 | ||
212 | if (hdmi_ops && hdmi_ops->mode_fixup) | 213 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
213 | hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode, | 214 | |
214 | adjusted_mode); | 215 | mode_ok = drm_hdmi_check_timing(subdrv_dev, adjusted_mode); |
216 | |||
217 | /* just return if user desired mode exists. */ | ||
218 | if (mode_ok == 0) | ||
219 | return; | ||
220 | |||
221 | /* | ||
222 | * otherwise, find the most suitable mode among modes and change it | ||
223 | * to adjusted_mode. | ||
224 | */ | ||
225 | list_for_each_entry(m, &connector->modes, head) { | ||
226 | mode_ok = drm_hdmi_check_timing(subdrv_dev, m); | ||
227 | |||
228 | if (mode_ok == 0) { | ||
229 | struct drm_mode_object base; | ||
230 | struct list_head head; | ||
231 | |||
232 | DRM_INFO("desired mode doesn't exist so\n"); | ||
233 | DRM_INFO("use the most suitable mode among modes.\n"); | ||
234 | |||
235 | DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n", | ||
236 | m->hdisplay, m->vdisplay, m->vrefresh); | ||
237 | |||
238 | /* preserve display mode header while copying. */ | ||
239 | head = adjusted_mode->head; | ||
240 | base = adjusted_mode->base; | ||
241 | memcpy(adjusted_mode, m, sizeof(*m)); | ||
242 | adjusted_mode->head = head; | ||
243 | adjusted_mode->base = base; | ||
244 | break; | ||
245 | } | ||
246 | } | ||
215 | } | 247 | } |
216 | 248 | ||
217 | static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) | 249 | static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index b7faa3662307..6b709440df4c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h | |||
@@ -36,9 +36,6 @@ struct exynos_hdmi_ops { | |||
36 | int (*power_on)(void *ctx, int mode); | 36 | int (*power_on)(void *ctx, int mode); |
37 | 37 | ||
38 | /* manager */ | 38 | /* manager */ |
39 | void (*mode_fixup)(void *ctx, struct drm_connector *connector, | ||
40 | const struct drm_display_mode *mode, | ||
41 | struct drm_display_mode *adjusted_mode); | ||
42 | void (*mode_set)(void *ctx, void *mode); | 39 | void (*mode_set)(void *ctx, void *mode); |
43 | void (*get_max_resol)(void *ctx, unsigned int *width, | 40 | void (*get_max_resol)(void *ctx, unsigned int *width, |
44 | unsigned int *height); | 41 | unsigned int *height); |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index a8c0d5b5ff6e..1469ae2ceacd 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -1430,52 +1430,6 @@ static void hdmi_conf_apply(struct hdmi_context *hdata) | |||
1430 | hdmi_regs_dump(hdata, "start"); | 1430 | hdmi_regs_dump(hdata, "start"); |
1431 | } | 1431 | } |
1432 | 1432 | ||
1433 | static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, | ||
1434 | const struct drm_display_mode *mode, | ||
1435 | struct drm_display_mode *adjusted_mode) | ||
1436 | { | ||
1437 | struct drm_display_mode *m; | ||
1438 | struct hdmi_context *hdata = ctx; | ||
1439 | int index; | ||
1440 | |||
1441 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | ||
1442 | |||
1443 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
1444 | |||
1445 | index = hdmi_find_phy_conf(hdata, adjusted_mode->clock * 1000); | ||
1446 | |||
1447 | /* just return if user desired mode exists. */ | ||
1448 | if (index >= 0) | ||
1449 | return; | ||
1450 | |||
1451 | /* | ||
1452 | * otherwise, find the most suitable mode among modes and change it | ||
1453 | * to adjusted_mode. | ||
1454 | */ | ||
1455 | list_for_each_entry(m, &connector->modes, head) { | ||
1456 | index = hdmi_find_phy_conf(hdata, m->clock * 1000); | ||
1457 | |||
1458 | if (index >= 0) { | ||
1459 | struct drm_mode_object base; | ||
1460 | struct list_head head; | ||
1461 | |||
1462 | DRM_INFO("desired mode doesn't exist so\n"); | ||
1463 | DRM_INFO("use the most suitable mode among modes.\n"); | ||
1464 | |||
1465 | DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n", | ||
1466 | m->hdisplay, m->vdisplay, m->vrefresh); | ||
1467 | |||
1468 | /* preserve display mode header while copying. */ | ||
1469 | head = adjusted_mode->head; | ||
1470 | base = adjusted_mode->base; | ||
1471 | memcpy(adjusted_mode, m, sizeof(*m)); | ||
1472 | adjusted_mode->head = head; | ||
1473 | adjusted_mode->base = base; | ||
1474 | break; | ||
1475 | } | ||
1476 | } | ||
1477 | } | ||
1478 | |||
1479 | static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value) | 1433 | static void hdmi_set_reg(u8 *reg_pair, int num_bytes, u32 value) |
1480 | { | 1434 | { |
1481 | int i; | 1435 | int i; |
@@ -1816,7 +1770,6 @@ static struct exynos_hdmi_ops hdmi_ops = { | |||
1816 | .check_timing = hdmi_check_timing, | 1770 | .check_timing = hdmi_check_timing, |
1817 | 1771 | ||
1818 | /* manager */ | 1772 | /* manager */ |
1819 | .mode_fixup = hdmi_mode_fixup, | ||
1820 | .mode_set = hdmi_mode_set, | 1773 | .mode_set = hdmi_mode_set, |
1821 | .get_max_resol = hdmi_get_max_resol, | 1774 | .get_max_resol = hdmi_get_max_resol, |
1822 | .commit = hdmi_commit, | 1775 | .commit = hdmi_commit, |