diff options
author | Adam Jackson <ajax@redhat.com> | 2010-03-29 17:43:26 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-04-05 20:40:22 -0400 |
commit | d1ff6409b1cd2cd2a65df415648fa38b9fdf4cd8 (patch) | |
tree | a5bd240d397e0f0a657433a815eee2d4df482325 | |
parent | a327f6b806103ee177aba20bb1e42ba7ec7d0f4b (diff) |
drm/edid: Add test for monitor reduced blanking support.
The generic block walk callback looks like overkill, but we'll need it
for other detailed block walks in the future.
Signed-off-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 2e1298cf576f..a1b6b433e5bc 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -33,6 +33,10 @@ | |||
33 | #include "drmP.h" | 33 | #include "drmP.h" |
34 | #include "drm_edid.h" | 34 | #include "drm_edid.h" |
35 | 35 | ||
36 | #define EDID_EST_TIMINGS 16 | ||
37 | #define EDID_STD_TIMINGS 8 | ||
38 | #define EDID_DETAILED_TIMINGS 4 | ||
39 | |||
36 | /* | 40 | /* |
37 | * EDID blocks out in the wild have a variety of bugs, try to collect | 41 | * EDID blocks out in the wild have a variety of bugs, try to collect |
38 | * them here (note that userspace may work around broken monitors first, | 42 | * them here (note that userspace may work around broken monitors first, |
@@ -670,6 +674,45 @@ static struct drm_display_mode *drm_find_dmt(struct drm_device *dev, | |||
670 | return mode; | 674 | return mode; |
671 | } | 675 | } |
672 | 676 | ||
677 | typedef void detailed_cb(struct detailed_timing *timing, void *closure); | ||
678 | |||
679 | static void | ||
680 | drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure) | ||
681 | { | ||
682 | int i; | ||
683 | struct edid *edid = (struct edid *)raw_edid; | ||
684 | |||
685 | if (edid == NULL) | ||
686 | return; | ||
687 | |||
688 | for (i = 0; i < EDID_DETAILED_TIMINGS; i++) | ||
689 | cb(&(edid->detailed_timings[i]), closure); | ||
690 | |||
691 | /* XXX extension block walk */ | ||
692 | } | ||
693 | |||
694 | static void | ||
695 | is_rb(struct detailed_timing *t, void *data) | ||
696 | { | ||
697 | u8 *r = (u8 *)t; | ||
698 | if (r[3] == EDID_DETAIL_MONITOR_RANGE) | ||
699 | if (r[15] & 0x10) | ||
700 | *(bool *)data = true; | ||
701 | } | ||
702 | |||
703 | /* EDID 1.4 defines this explicitly. For EDID 1.3, we guess, badly. */ | ||
704 | static bool | ||
705 | drm_monitor_supports_rb(struct edid *edid) | ||
706 | { | ||
707 | if (edid->revision >= 4) { | ||
708 | bool ret; | ||
709 | drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); | ||
710 | return ret; | ||
711 | } | ||
712 | |||
713 | return ((edid->input & DRM_EDID_INPUT_DIGITAL) != 0); | ||
714 | } | ||
715 | |||
673 | /* | 716 | /* |
674 | * 0 is reserved. The spec says 0x01 fill for unused timings. Some old | 717 | * 0 is reserved. The spec says 0x01 fill for unused timings. Some old |
675 | * monitors fill with ascii space (0x20) instead. | 718 | * monitors fill with ascii space (0x20) instead. |
@@ -952,10 +995,6 @@ static struct drm_display_mode edid_est_modes[] = { | |||
952 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */ | 995 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */ |
953 | }; | 996 | }; |
954 | 997 | ||
955 | #define EDID_EST_TIMINGS 16 | ||
956 | #define EDID_STD_TIMINGS 8 | ||
957 | #define EDID_DETAILED_TIMINGS 4 | ||
958 | |||
959 | /** | 998 | /** |
960 | * add_established_modes - get est. modes from EDID and add them | 999 | * add_established_modes - get est. modes from EDID and add them |
961 | * @edid: EDID block to scan | 1000 | * @edid: EDID block to scan |