aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2012-05-23 16:26:54 -0400
committerDave Airlie <airlied@redhat.com>2012-05-29 11:16:38 -0400
commitbc42aabc6a01b92b0f961d65671564e0e1cd7592 (patch)
tree33ed0b015ed36051ef50a842af29771694c0eb95 /drivers/gpu
parent1c780f2cfec8b533b9cfda77209b4e3e7adaddbf (diff)
drm/edid/quirks: ViewSonic VA2026w
Entirely new class of fail for this one. The detailed timings are for normal CVT but the monitor really wanted CVT-R. Bugzilla: http://bugzilla.redhat/com/516471 Signed-off-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/drm_edid.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 608bddfc7e35..c3b5139eba7f 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -66,6 +66,8 @@
66#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5) 66#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5)
67/* use +hsync +vsync for detailed mode */ 67/* use +hsync +vsync for detailed mode */
68#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) 68#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
69/* Force reduced-blanking timings for detailed modes */
70#define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7)
69 71
70struct detailed_mode_closure { 72struct detailed_mode_closure {
71 struct drm_connector *connector; 73 struct drm_connector *connector;
@@ -120,6 +122,9 @@ static struct edid_quirk {
120 /* Samsung SyncMaster 22[5-6]BW */ 122 /* Samsung SyncMaster 22[5-6]BW */
121 { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 }, 123 { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
122 { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, 124 { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
125
126 /* ViewSonic VA2026w */
127 { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
123}; 128};
124 129
125/*** DDC fetch and block validation ***/ 130/*** DDC fetch and block validation ***/
@@ -885,12 +890,19 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
885 "Wrong Hsync/Vsync pulse width\n"); 890 "Wrong Hsync/Vsync pulse width\n");
886 return NULL; 891 return NULL;
887 } 892 }
893
894 if (quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) {
895 mode = drm_cvt_mode(dev, hactive, vactive, 60, true, false, false);
896 if (!mode)
897 return NULL;
898
899 goto set_size;
900 }
901
888 mode = drm_mode_create(dev); 902 mode = drm_mode_create(dev);
889 if (!mode) 903 if (!mode)
890 return NULL; 904 return NULL;
891 905
892 mode->type = DRM_MODE_TYPE_DRIVER;
893
894 if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH) 906 if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
895 timing->pixel_clock = cpu_to_le16(1088); 907 timing->pixel_clock = cpu_to_le16(1088);
896 908
@@ -914,8 +926,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
914 926
915 drm_mode_do_interlace_quirk(mode, pt); 927 drm_mode_do_interlace_quirk(mode, pt);
916 928
917 drm_mode_set_name(mode);
918
919 if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { 929 if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
920 pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; 930 pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
921 } 931 }
@@ -925,6 +935,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
925 mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? 935 mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
926 DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; 936 DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
927 937
938set_size:
928 mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; 939 mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4;
929 mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; 940 mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8;
930 941
@@ -938,6 +949,9 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
938 mode->height_mm = edid->height_cm * 10; 949 mode->height_mm = edid->height_cm * 10;
939 } 950 }
940 951
952 mode->type = DRM_MODE_TYPE_DRIVER;
953 drm_mode_set_name(mode);
954
941 return mode; 955 return mode;
942} 956}
943 957