diff options
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 2f325bcd0708..8835dcddfac3 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -68,6 +68,8 @@ #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) /* Force reduced-blanking timings for detailed modes */ #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) +/* Force 8bpc */ +#define EDID_QUIRK_FORCE_8BPC (1 << 8) struct detailed_mode_closure { struct drm_connector *connector; @@ -128,6 +130,9 @@ static struct edid_quirk { /* Medion MD 30217 PG */ { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, + + /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */ + { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC }, }; /* @@ -1329,7 +1334,7 @@ static u32 edid_get_quirks(struct edid *edid) } #define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay) -#define MODE_REFRESH_DIFF(m,r) (abs((m)->vrefresh - target_refresh)) +#define MODE_REFRESH_DIFF(c,t) (abs((c) - (t))) /** * edid_fixup_preferred - set preferred modes based on quirk list @@ -1344,6 +1349,7 @@ static void edid_fixup_preferred(struct drm_connector *connector, { struct drm_display_mode *t, *cur_mode, *preferred_mode; int target_refresh = 0; + int cur_vrefresh, preferred_vrefresh; if (list_empty(&connector->probed_modes)) return; @@ -1366,10 +1372,14 @@ static void edid_fixup_preferred(struct drm_connector *connector, if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode)) preferred_mode = cur_mode; + cur_vrefresh = cur_mode->vrefresh ? + cur_mode->vrefresh : drm_mode_vrefresh(cur_mode); + preferred_vrefresh = preferred_mode->vrefresh ? + preferred_mode->vrefresh : drm_mode_vrefresh(preferred_mode); /* At a given size, try to get closest to target refresh */ if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) && - MODE_REFRESH_DIFF(cur_mode, target_refresh) < - MODE_REFRESH_DIFF(preferred_mode, target_refresh)) { + MODE_REFRESH_DIFF(cur_vrefresh, target_refresh) < + MODE_REFRESH_DIFF(preferred_vrefresh, target_refresh)) { preferred_mode = cur_mode; } } @@ -2669,7 +2679,7 @@ static int add_3d_struct_modes(struct drm_connector *connector, u16 structure, int modes = 0; u8 cea_mode; - if (video_db == NULL || video_index > video_len) + if (video_db == NULL || video_index >= video_len) return 0; /* CEA modes are numbered 1..127 */ @@ -2696,7 +2706,7 @@ static int add_3d_struct_modes(struct drm_connector *connector, u16 structure, if (structure & (1 << 8)) { newmode = drm_mode_duplicate(dev, &edid_cea_modes[cea_mode]); if (newmode) { - newmode->flags = DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF; + newmode->flags |= DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF; drm_mode_probed_add(connector, newmode); modes++; } @@ -3430,6 +3440,9 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) drm_add_display_info(edid, &connector->display_info); + if (quirks & EDID_QUIRK_FORCE_8BPC) + connector->display_info.bpc = 8; + return num_modes; } EXPORT_SYMBOL(drm_add_edid_modes); |