diff options
author | Adam Jackson <ajax@redhat.com> | 2010-08-03 14:38:17 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-08-09 20:46:57 -0400 |
commit | 4d76a22134d5a5ad259fd667f3d2b215b7e71d10 (patch) | |
tree | 683d8df7efc2a652cc78146022a31bbab1877950 /drivers | |
parent | fb439640145df0d3af7eacb83a19d8eb0a24002a (diff) |
drm/edid: Add detailed block walk for CEA extensions
Signed-off-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 3d6abde8e785..30b286ba16c4 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -685,6 +685,33 @@ EXPORT_SYMBOL(drm_mode_find_dmt); | |||
685 | typedef void detailed_cb(struct detailed_timing *timing, void *closure); | 685 | typedef void detailed_cb(struct detailed_timing *timing, void *closure); |
686 | 686 | ||
687 | static void | 687 | static void |
688 | cea_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure) | ||
689 | { | ||
690 | int i, n = 0; | ||
691 | u8 rev = ext[0x01], d = ext[0x02]; | ||
692 | u8 *det_base = ext + d; | ||
693 | |||
694 | switch (rev) { | ||
695 | case 0: | ||
696 | /* can't happen */ | ||
697 | return; | ||
698 | case 1: | ||
699 | /* have to infer how many blocks we have, check pixel clock */ | ||
700 | for (i = 0; i < 6; i++) | ||
701 | if (det_base[18*i] || det_base[18*i+1]) | ||
702 | n++; | ||
703 | break; | ||
704 | default: | ||
705 | /* explicit count */ | ||
706 | n = min(ext[0x03] & 0x0f, 6); | ||
707 | break; | ||
708 | } | ||
709 | |||
710 | for (i = 0; i < n; i++) | ||
711 | cb((struct detailed_timing *)(det_base + 18 * i), closure); | ||
712 | } | ||
713 | |||
714 | static void | ||
688 | drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure) | 715 | drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure) |
689 | { | 716 | { |
690 | int i; | 717 | int i; |
@@ -696,7 +723,16 @@ drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure) | |||
696 | for (i = 0; i < EDID_DETAILED_TIMINGS; i++) | 723 | for (i = 0; i < EDID_DETAILED_TIMINGS; i++) |
697 | cb(&(edid->detailed_timings[i]), closure); | 724 | cb(&(edid->detailed_timings[i]), closure); |
698 | 725 | ||
699 | /* XXX extension block walk */ | 726 | for (i = 1; i <= raw_edid[0x7e]; i++) { |
727 | u8 *ext = raw_edid + (i * EDID_LENGTH); | ||
728 | switch (*ext) { | ||
729 | case CEA_EXT: | ||
730 | cea_for_each_detailed_block(ext, cb, closure); | ||
731 | break; | ||
732 | default: | ||
733 | break; | ||
734 | } | ||
735 | } | ||
700 | } | 736 | } |
701 | 737 | ||
702 | static void | 738 | static void |