|
@@ -66,6 +66,8 @@
|
|
|
#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5)
|
|
|
/* use +hsync +vsync for detailed mode */
|
|
|
#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
|
|
|
+/* Force reduced-blanking timings for detailed modes */
|
|
|
+#define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7)
|
|
|
|
|
|
struct detailed_mode_closure {
|
|
|
struct drm_connector *connector;
|
|
@@ -120,6 +122,9 @@ static struct edid_quirk {
|
|
|
/* Samsung SyncMaster 22[5-6]BW */
|
|
|
{ "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 },
|
|
|
{ "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 },
|
|
|
+
|
|
|
+ /* ViewSonic VA2026w */
|
|
|
+ { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
|
|
|
};
|
|
|
|
|
|
/*** DDC fetch and block validation ***/
|
|
@@ -885,12 +890,19 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
|
|
|
"Wrong Hsync/Vsync pulse width\n");
|
|
|
return NULL;
|
|
|
}
|
|
|
+
|
|
|
+ if (quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) {
|
|
|
+ mode = drm_cvt_mode(dev, hactive, vactive, 60, true, false, false);
|
|
|
+ if (!mode)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ goto set_size;
|
|
|
+ }
|
|
|
+
|
|
|
mode = drm_mode_create(dev);
|
|
|
if (!mode)
|
|
|
return NULL;
|
|
|
|
|
|
- mode->type = DRM_MODE_TYPE_DRIVER;
|
|
|
-
|
|
|
if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH)
|
|
|
timing->pixel_clock = cpu_to_le16(1088);
|
|
|
|
|
@@ -914,8 +926,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
|
|
|
|
|
|
drm_mode_do_interlace_quirk(mode, pt);
|
|
|
|
|
|
- drm_mode_set_name(mode);
|
|
|
-
|
|
|
if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
|
|
|
pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
|
|
|
}
|
|
@@ -925,6 +935,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
|
|
|
mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
|
|
|
DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
|
|
|
|
|
|
+set_size:
|
|
|
mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4;
|
|
|
mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8;
|
|
|
|
|
@@ -938,6 +949,9 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
|
|
|
mode->height_mm = edid->height_cm * 10;
|
|
|
}
|
|
|
|
|
|
+ mode->type = DRM_MODE_TYPE_DRIVER;
|
|
|
+ drm_mode_set_name(mode);
|
|
|
+
|
|
|
return mode;
|
|
|
}
|
|
|
|