diff options
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 67 |
1 files changed, 39 insertions, 28 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 8835dcddfac3..2e678f1540ae 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -2562,25 +2562,40 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) | |||
2562 | return modes; | 2562 | return modes; |
2563 | } | 2563 | } |
2564 | 2564 | ||
2565 | static int | 2565 | static struct drm_display_mode * |
2566 | do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len) | 2566 | drm_display_mode_from_vic_index(struct drm_connector *connector, |
2567 | const u8 *video_db, u8 video_len, | ||
2568 | u8 video_index) | ||
2567 | { | 2569 | { |
2568 | struct drm_device *dev = connector->dev; | 2570 | struct drm_device *dev = connector->dev; |
2569 | const u8 *mode; | 2571 | struct drm_display_mode *newmode; |
2570 | u8 cea_mode; | 2572 | u8 cea_mode; |
2571 | int modes = 0; | ||
2572 | 2573 | ||
2573 | for (mode = db; mode < db + len; mode++) { | 2574 | if (video_db == NULL || video_index >= video_len) |
2574 | cea_mode = (*mode & 127) - 1; /* CEA modes are numbered 1..127 */ | 2575 | return NULL; |
2575 | if (cea_mode < ARRAY_SIZE(edid_cea_modes)) { | 2576 | |
2576 | struct drm_display_mode *newmode; | 2577 | /* CEA modes are numbered 1..127 */ |
2577 | newmode = drm_mode_duplicate(dev, | 2578 | cea_mode = (video_db[video_index] & 127) - 1; |
2578 | &edid_cea_modes[cea_mode]); | 2579 | if (cea_mode >= ARRAY_SIZE(edid_cea_modes)) |
2579 | if (newmode) { | 2580 | return NULL; |
2580 | newmode->vrefresh = 0; | 2581 | |
2581 | drm_mode_probed_add(connector, newmode); | 2582 | newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]); |
2582 | modes++; | 2583 | newmode->vrefresh = 0; |
2583 | } | 2584 | |
2585 | return newmode; | ||
2586 | } | ||
2587 | |||
2588 | static int | ||
2589 | do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len) | ||
2590 | { | ||
2591 | int i, modes = 0; | ||
2592 | |||
2593 | for (i = 0; i < len; i++) { | ||
2594 | struct drm_display_mode *mode; | ||
2595 | mode = drm_display_mode_from_vic_index(connector, db, len, i); | ||
2596 | if (mode) { | ||
2597 | drm_mode_probed_add(connector, mode); | ||
2598 | modes++; | ||
2584 | } | 2599 | } |
2585 | } | 2600 | } |
2586 | 2601 | ||
@@ -2674,21 +2689,13 @@ static int add_hdmi_mode(struct drm_connector *connector, u8 vic) | |||
2674 | static int add_3d_struct_modes(struct drm_connector *connector, u16 structure, | 2689 | static int add_3d_struct_modes(struct drm_connector *connector, u16 structure, |
2675 | const u8 *video_db, u8 video_len, u8 video_index) | 2690 | const u8 *video_db, u8 video_len, u8 video_index) |
2676 | { | 2691 | { |
2677 | struct drm_device *dev = connector->dev; | ||
2678 | struct drm_display_mode *newmode; | 2692 | struct drm_display_mode *newmode; |
2679 | int modes = 0; | 2693 | int modes = 0; |
2680 | u8 cea_mode; | ||
2681 | |||
2682 | if (video_db == NULL || video_index >= video_len) | ||
2683 | return 0; | ||
2684 | |||
2685 | /* CEA modes are numbered 1..127 */ | ||
2686 | cea_mode = (video_db[video_index] & 127) - 1; | ||
2687 | if (cea_mode >= ARRAY_SIZE(edid_cea_modes)) | ||
2688 | return 0; | ||
2689 | 2694 | ||
2690 | if (structure & (1 << 0)) { | 2695 | if (structure & (1 << 0)) { |
2691 | newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]); | 2696 | newmode = drm_display_mode_from_vic_index(connector, video_db, |
2697 | video_len, | ||
2698 | video_index); | ||
2692 | if (newmode) { | 2699 | if (newmode) { |
2693 | newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING; | 2700 | newmode->flags |= DRM_MODE_FLAG_3D_FRAME_PACKING; |
2694 | drm_mode_probed_add(connector, newmode); | 2701 | drm_mode_probed_add(connector, newmode); |
@@ -2696,7 +2703,9 @@ static int add_3d_struct_modes(struct drm_connector *connector, u16 structure, | |||
2696 | } | 2703 | } |
2697 | } | 2704 | } |
2698 | if (structure & (1 << 6)) { | 2705 | if (structure & (1 << 6)) { |
2699 | newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]); | 2706 | newmode = drm_display_mode_from_vic_index(connector, video_db, |
2707 | video_len, | ||
2708 | video_index); | ||
2700 | if (newmode) { | 2709 | if (newmode) { |
2701 | newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM; | 2710 | newmode->flags |= DRM_MODE_FLAG_3D_TOP_AND_BOTTOM; |
2702 | drm_mode_probed_add(connector, newmode); | 2711 | drm_mode_probed_add(connector, newmode); |
@@ -2704,7 +2713,9 @@ static int add_3d_struct_modes(struct drm_connector *connector, u16 structure, | |||
2704 | } | 2713 | } |
2705 | } | 2714 | } |
2706 | if (structure & (1 << 8)) { | 2715 | if (structure & (1 << 8)) { |
2707 | newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]); | 2716 | newmode = drm_display_mode_from_vic_index(connector, video_db, |
2717 | video_len, | ||
2718 | video_index); | ||
2708 | if (newmode) { | 2719 | if (newmode) { |
2709 | newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF; | 2720 | newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF; |
2710 | drm_mode_probed_add(connector, newmode); | 2721 | drm_mode_probed_add(connector, newmode); |