diff options
author | Adam Jackson <ajax@redhat.com> | 2009-12-03 17:44:40 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-12-03 17:53:47 -0500 |
commit | 9340d8cfeacd16cef1cbe94527f7baaed7640669 (patch) | |
tree | 08739867be1f39978793dcdc34b606db81775975 /drivers | |
parent | 2dbdc52c8162291aa7541b8ba6e1c1587f50c1dd (diff) |
drm/edid: Decode 3-byte CVT codes from EDID 1.4
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 | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index cc8e69682714..30af8f3e6427 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -897,6 +897,51 @@ static int drm_gtf_modes_for_range(struct drm_connector *connector, | |||
897 | return modes; | 897 | return modes; |
898 | } | 898 | } |
899 | 899 | ||
900 | static int drm_cvt_modes(struct drm_connector *connector, | ||
901 | struct detailed_timing *timing) | ||
902 | { | ||
903 | int i, j, modes = 0; | ||
904 | struct drm_display_mode *newmode; | ||
905 | struct drm_device *dev = connector->dev; | ||
906 | struct cvt_timing *cvt; | ||
907 | const int rates[] = { 60, 85, 75, 60, 50 }; | ||
908 | |||
909 | for (i = 0; i < 4; i++) { | ||
910 | int width, height; | ||
911 | cvt = &(timing->data.other_data.data.cvt[i]); | ||
912 | |||
913 | height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; | ||
914 | switch (cvt->code[1] & 0xc0) { | ||
915 | case 0x00: | ||
916 | width = height * 4 / 3; | ||
917 | break; | ||
918 | case 0x40: | ||
919 | width = height * 16 / 9; | ||
920 | break; | ||
921 | case 0x80: | ||
922 | width = height * 16 / 10; | ||
923 | break; | ||
924 | case 0xc0: | ||
925 | width = height * 15 / 9; | ||
926 | break; | ||
927 | } | ||
928 | |||
929 | for (j = 1; j < 5; j++) { | ||
930 | if (cvt->code[2] & (1 << j)) { | ||
931 | newmode = drm_cvt_mode(dev, width, height, | ||
932 | rates[j], j == 0, | ||
933 | false, false); | ||
934 | if (newmode) { | ||
935 | drm_mode_probed_add(connector, newmode); | ||
936 | modes++; | ||
937 | } | ||
938 | } | ||
939 | } | ||
940 | } | ||
941 | |||
942 | return modes; | ||
943 | } | ||
944 | |||
900 | static int add_detailed_modes(struct drm_connector *connector, | 945 | static int add_detailed_modes(struct drm_connector *connector, |
901 | struct detailed_timing *timing, | 946 | struct detailed_timing *timing, |
902 | struct edid *edid, u32 quirks, int preferred) | 947 | struct edid *edid, u32 quirks, int preferred) |
@@ -941,6 +986,9 @@ static int add_detailed_modes(struct drm_connector *connector, | |||
941 | } | 986 | } |
942 | } | 987 | } |
943 | break; | 988 | break; |
989 | case EDID_DETAIL_CVT_3BYTE: | ||
990 | modes += drm_cvt_modes(connector, timing); | ||
991 | break; | ||
944 | default: | 992 | default: |
945 | break; | 993 | break; |
946 | } | 994 | } |