aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2010-03-29 17:43:26 -0400
committerDave Airlie <airlied@redhat.com>2010-04-05 20:40:22 -0400
commitd1ff6409b1cd2cd2a65df415648fa38b9fdf4cd8 (patch)
treea5bd240d397e0f0a657433a815eee2d4df482325
parenta327f6b806103ee177aba20bb1e42ba7ec7d0f4b (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.c47
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
677typedef void detailed_cb(struct detailed_timing *timing, void *closure);
678
679static void
680drm_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
694static void
695is_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. */
704static bool
705drm_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