aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLespiau, Damien <damien.lespiau@intel.com>2013-08-19 11:58:55 -0400
committerDave Airlie <airlied@gmail.com>2013-08-29 18:40:14 -0400
commit3f2f653378112c1453c0d83c81746a9225e4bc75 (patch)
tree27d2a06b1ee7a62078197ec17a8e464a03ec8050
parent7ebe1963a063daf30f95752c35244c5d49550aa9 (diff)
drm: Add support for alternate clocks of 4k modes
v2: Fix hmdi typo (Simon Farnsworth, Ville Syrjälä) Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Simon Farnsworth <simon.farnsworth@onelan.co.uk> Reviewed-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Dave Airlie <airlied@gmail.com>
-rw-r--r--drivers/gpu/drm/drm_edid.c68
1 files changed, 62 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9de573cd3683..2381abd452f1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2409,6 +2409,54 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
2409} 2409}
2410EXPORT_SYMBOL(drm_match_cea_mode); 2410EXPORT_SYMBOL(drm_match_cea_mode);
2411 2411
2412/*
2413 * Calculate the alternate clock for HDMI modes (those from the HDMI vendor
2414 * specific block).
2415 *
2416 * It's almost like cea_mode_alternate_clock(), we just need to add an
2417 * exception for the VIC 4 mode (4096x2160@24Hz): no alternate clock for this
2418 * one.
2419 */
2420static unsigned int
2421hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode)
2422{
2423 if (hdmi_mode->vdisplay == 4096 && hdmi_mode->hdisplay == 2160)
2424 return hdmi_mode->clock;
2425
2426 return cea_mode_alternate_clock(hdmi_mode);
2427}
2428
2429/*
2430 * drm_match_hdmi_mode - look for a HDMI mode matching given mode
2431 * @to_match: display mode
2432 *
2433 * An HDMI mode is one defined in the HDMI vendor specific block.
2434 *
2435 * Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one.
2436 */
2437static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
2438{
2439 u8 mode;
2440
2441 if (!to_match->clock)
2442 return 0;
2443
2444 for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) {
2445 const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode];
2446 unsigned int clock1, clock2;
2447
2448 /* Make sure to also match alternate clocks */
2449 clock1 = hdmi_mode->clock;
2450 clock2 = hdmi_mode_alternate_clock(hdmi_mode);
2451
2452 if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
2453 KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
2454 drm_mode_equal_no_clocks(to_match, hdmi_mode))
2455 return mode + 1;
2456 }
2457 return 0;
2458}
2459
2412static int 2460static int
2413add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) 2461add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
2414{ 2462{
@@ -2426,18 +2474,26 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
2426 * with the alternate clock for certain CEA modes. 2474 * with the alternate clock for certain CEA modes.
2427 */ 2475 */
2428 list_for_each_entry(mode, &connector->probed_modes, head) { 2476 list_for_each_entry(mode, &connector->probed_modes, head) {
2429 const struct drm_display_mode *cea_mode; 2477 const struct drm_display_mode *cea_mode = NULL;
2430 struct drm_display_mode *newmode; 2478 struct drm_display_mode *newmode;
2431 u8 cea_mode_idx = drm_match_cea_mode(mode) - 1; 2479 u8 mode_idx = drm_match_cea_mode(mode) - 1;
2432 unsigned int clock1, clock2; 2480 unsigned int clock1, clock2;
2433 2481
2434 if (cea_mode_idx >= ARRAY_SIZE(edid_cea_modes)) 2482 if (mode_idx < ARRAY_SIZE(edid_cea_modes)) {
2435 continue; 2483 cea_mode = &edid_cea_modes[mode_idx];
2484 clock2 = cea_mode_alternate_clock(cea_mode);
2485 } else {
2486 mode_idx = drm_match_hdmi_mode(mode) - 1;
2487 if (mode_idx < ARRAY_SIZE(edid_4k_modes)) {
2488 cea_mode = &edid_4k_modes[mode_idx];
2489 clock2 = hdmi_mode_alternate_clock(cea_mode);
2490 }
2491 }
2436 2492
2437 cea_mode = &edid_cea_modes[cea_mode_idx]; 2493 if (!cea_mode)
2494 continue;
2438 2495
2439 clock1 = cea_mode->clock; 2496 clock1 = cea_mode->clock;
2440 clock2 = cea_mode_alternate_clock(cea_mode);
2441 2497
2442 if (clock1 == clock2) 2498 if (clock1 == clock2)
2443 continue; 2499 continue;