diff options
author | Adam Jackson <ajax@redhat.com> | 2012-04-13 16:33:31 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-04-20 07:57:03 -0400 |
commit | f6e252bac45cab5edc30c2ede971def51e272c9b (patch) | |
tree | 802132a84330670d3e394b033a371510cdac596b | |
parent | f8b46a05e6ced02e75cd782c015a57e67d5c644d (diff) |
drm/edid: Allow drm_mode_find_dmt to hunt for reduced-blanking modes
It won't find any, yet. Fix up callers to match: standard mode codes
will look prefer r-b modes for a given size if present, EST3 mode codes
will look for exactly the r-b-ness mentioned in the mode code. This
might mean fewer modes matched for EST3 mode codes between now and when
the DMT mode list regrows the r-b modes, but practically speaking EST3
codes don't exist in the wild.
Signed-off-by: Adam Jackson <ajax@redhat.com>
Tested-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 2 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 3 |
3 files changed, 27 insertions, 15 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 9c8fa8860f6b..ec0464c91847 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -486,18 +486,29 @@ static void edid_fixup_preferred(struct drm_connector *connector, | |||
486 | preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; | 486 | preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; |
487 | } | 487 | } |
488 | 488 | ||
489 | static bool | ||
490 | mode_is_rb(const struct drm_display_mode *mode) | ||
491 | { | ||
492 | return (mode->htotal - mode->hdisplay == 160) && | ||
493 | (mode->hsync_end - mode->hdisplay == 80) && | ||
494 | (mode->hsync_end - mode->hsync_start == 32) && | ||
495 | (mode->vsync_start - mode->vdisplay == 3); | ||
496 | } | ||
497 | |||
489 | /* | 498 | /* |
490 | * drm_mode_find_dmt - Create a copy of a mode if present in DMT | 499 | * drm_mode_find_dmt - Create a copy of a mode if present in DMT |
491 | * @dev: Device to duplicate against | 500 | * @dev: Device to duplicate against |
492 | * @hsize: Mode width | 501 | * @hsize: Mode width |
493 | * @vsize: Mode height | 502 | * @vsize: Mode height |
494 | * @fresh: Mode refresh rate | 503 | * @fresh: Mode refresh rate |
504 | * @rb: Mode reduced-blanking-ness | ||
495 | * | 505 | * |
496 | * Walk the DMT mode list looking for a match for the given parameters. | 506 | * Walk the DMT mode list looking for a match for the given parameters. |
497 | * Return a newly allocated copy of the mode, or NULL if not found. | 507 | * Return a newly allocated copy of the mode, or NULL if not found. |
498 | */ | 508 | */ |
499 | struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, | 509 | struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, |
500 | int hsize, int vsize, int fresh) | 510 | int hsize, int vsize, int fresh, |
511 | bool rb) | ||
501 | { | 512 | { |
502 | int i; | 513 | int i; |
503 | 514 | ||
@@ -509,6 +520,8 @@ struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, | |||
509 | continue; | 520 | continue; |
510 | if (fresh != drm_mode_vrefresh(ptr)) | 521 | if (fresh != drm_mode_vrefresh(ptr)) |
511 | continue; | 522 | continue; |
523 | if (rb != mode_is_rb(ptr)) | ||
524 | continue; | ||
512 | 525 | ||
513 | return drm_mode_duplicate(dev, ptr); | 526 | return drm_mode_duplicate(dev, ptr); |
514 | } | 527 | } |
@@ -742,10 +755,17 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, | |||
742 | } | 755 | } |
743 | 756 | ||
744 | /* check whether it can be found in default mode table */ | 757 | /* check whether it can be found in default mode table */ |
745 | mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate); | 758 | if (drm_monitor_supports_rb(edid)) { |
759 | mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, | ||
760 | true); | ||
761 | if (mode) | ||
762 | return mode; | ||
763 | } | ||
764 | mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, false); | ||
746 | if (mode) | 765 | if (mode) |
747 | return mode; | 766 | return mode; |
748 | 767 | ||
768 | /* okay, generate it */ | ||
749 | switch (timing_level) { | 769 | switch (timing_level) { |
750 | case LEVEL_DMT: | 770 | case LEVEL_DMT: |
751 | break; | 771 | break; |
@@ -920,15 +940,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
920 | } | 940 | } |
921 | 941 | ||
922 | static bool | 942 | static bool |
923 | mode_is_rb(const struct drm_display_mode *mode) | ||
924 | { | ||
925 | return (mode->htotal - mode->hdisplay == 160) && | ||
926 | (mode->hsync_end - mode->hdisplay == 80) && | ||
927 | (mode->hsync_end - mode->hsync_start == 32) && | ||
928 | (mode->vsync_start - mode->vdisplay == 3); | ||
929 | } | ||
930 | |||
931 | static bool | ||
932 | mode_in_hsync_range(const struct drm_display_mode *mode, | 943 | mode_in_hsync_range(const struct drm_display_mode *mode, |
933 | struct edid *edid, u8 *t) | 944 | struct edid *edid, u8 *t) |
934 | { | 945 | { |
@@ -1073,8 +1084,8 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing) | |||
1073 | mode = drm_mode_find_dmt(connector->dev, | 1084 | mode = drm_mode_find_dmt(connector->dev, |
1074 | est3_modes[m].w, | 1085 | est3_modes[m].w, |
1075 | est3_modes[m].h, | 1086 | est3_modes[m].h, |
1076 | est3_modes[m].r | 1087 | est3_modes[m].r, |
1077 | /*, est3_modes[m].rb */); | 1088 | est3_modes[m].rb); |
1078 | if (mode) { | 1089 | if (mode) { |
1079 | drm_mode_probed_add(connector, mode); | 1090 | drm_mode_probed_add(connector, mode); |
1080 | modes++; | 1091 | modes++; |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index a0d6e894d97c..6e19dd156be0 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -1083,7 +1083,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, | |||
1083 | 1083 | ||
1084 | /* try and find a 1024x768 mode on each connector */ | 1084 | /* try and find a 1024x768 mode on each connector */ |
1085 | can_clone = true; | 1085 | can_clone = true; |
1086 | dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60); | 1086 | dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false); |
1087 | 1087 | ||
1088 | for (i = 0; i < fb_helper->connector_count; i++) { | 1088 | for (i = 0; i < fb_helper->connector_count; i++) { |
1089 | 1089 | ||
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 2d63a02571ff..6f5faf669959 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -1015,7 +1015,8 @@ extern int drm_edid_header_is_valid(const u8 *raw_edid); | |||
1015 | extern bool drm_edid_block_valid(u8 *raw_edid); | 1015 | extern bool drm_edid_block_valid(u8 *raw_edid); |
1016 | extern bool drm_edid_is_valid(struct edid *edid); | 1016 | extern bool drm_edid_is_valid(struct edid *edid); |
1017 | struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, | 1017 | struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, |
1018 | int hsize, int vsize, int fresh); | 1018 | int hsize, int vsize, int fresh, |
1019 | bool rb); | ||
1019 | 1020 | ||
1020 | extern int drm_mode_create_dumb_ioctl(struct drm_device *dev, | 1021 | extern int drm_mode_create_dumb_ioctl(struct drm_device *dev, |
1021 | void *data, struct drm_file *file_priv); | 1022 | void *data, struct drm_file *file_priv); |