History

drm/edid: Handle EDID 1.4 range descriptor h/vfreq offsets

EDID 1.4 introduced some extra flags in the range descriptor to support min/max h/vfreq >= 255. Consult them to correctly parse the vfreq limits. Note that some combinations of the flags are documented as "reserved" (as are some other values in the descriptor) but explicitly checking for those doesn't seem particularly worthwile since we end up with bogus results whether we decode them or not. v2: Increase the storage to u16 to make it work (Jani) Note the "reserved" values situation (Jani) v3: Document the EDID version number in the defines Drop some bogus (u8) casts

Ville Syrjälä committed 4 years ago

Commit c7943bb1 parent a3f7c104 files · +27 −10Browse files

Unified · Split

4 files
  1. drivers/gpu/drm/drm_debugfs.c +2 −2
  2. drivers/gpu/drm/drm_edid.c +18 −6
  3. include/drm/drm_connector.h +2 −2
  4. include/drm/drm_edid.h +5 −0
drivers/gpu/drm/drm_debugfs.c+2−2
@@ -377,8 +377,8 @@ static int vrr_range_show(struct seq_file *m, void *data) · 376 unmodified lines
377377 if (connector->status != connector_status_connected)
378378 return -ENODEV;
379379
380− seq_printf(m, "Min: %u\n", (u8)connector->display_info.monitor_range.min_vfreq);
381− seq_printf(m, "Max: %u\n", (u8)connector->display_info.monitor_range.max_vfreq);
380+ seq_printf(m, "Min: %u\n", connector->display_info.monitor_range.min_vfreq);
381+ seq_printf(m, "Max: %u\n", connector->display_info.monitor_range.max_vfreq);
382382
383383 return 0;
384384 }
drivers/gpu/drm/drm_edid.c+18−6
@@ -5971,12 +5971,14 @@ static void drm_parse_cea_ext(struct drm_connector *connector, · 5970 unmodified lines
59715971 }
59725972
59735973 static
5974−void get_monitor_range(const struct detailed_timing *timing,
5975− void *info_monitor_range)
5974+void get_monitor_range(const struct detailed_timing *timing, void *c)
59765975 {
5977− struct drm_monitor_range_info *monitor_range = info_monitor_range;
5976+ struct detailed_mode_closure *closure = c;
5977+ struct drm_display_info *info = &closure->connector->display_info;
5978+ struct drm_monitor_range_info *monitor_range = &info->monitor_range;
59785979 const struct detailed_non_pixel *data = &timing->data.other_data;
59795980 const struct detailed_data_monitor_range *range = &data->data.range;
5981+ const struct edid *edid = closure->drm_edid->edid;
59805982
59815983 if (!is_display_descriptor(timing, EDID_DETAIL_MONITOR_RANGE))
59825984 return;
@@ -5992,18 +5994,28 @@ void get_monitor_range(const struct detailed_timing *timing, · 9 unmodified lines
59925994
59935995 monitor_range->min_vfreq = range->min_vfreq;
59945996 monitor_range->max_vfreq = range->max_vfreq;
5997+
5998+ if (edid->revision >= 4) {
5999+ if (data->pad2 & DRM_EDID_RANGE_OFFSET_MIN_VFREQ)
6000+ monitor_range->min_vfreq += 255;
6001+ if (data->pad2 & DRM_EDID_RANGE_OFFSET_MAX_VFREQ)
6002+ monitor_range->max_vfreq += 255;
6003+ }
59956004 }
59966005
59976006 static void drm_get_monitor_range(struct drm_connector *connector,
59986007 const struct drm_edid *drm_edid)
59996008 {
6000− struct drm_display_info *info = &connector->display_info;
6009+ const struct drm_display_info *info = &connector->display_info;
6010+ struct detailed_mode_closure closure = {
6011+ .connector = connector,
6012+ .drm_edid = drm_edid,
6013+ };
60016014
60026015 if (!version_greater(drm_edid, 1, 1))
60036016 return;
60046017
6005− drm_for_each_detailed_block(drm_edid, get_monitor_range,
6006− &info->monitor_range);
6018+ drm_for_each_detailed_block(drm_edid, get_monitor_range, &closure);
60076019
60086020 DRM_DEBUG_KMS("Supported Monitor Refresh rate range is %d Hz - %d Hz\n",
60096021 info->monitor_range.min_vfreq,
include/drm/drm_connector.h+2−2
@@ -319,8 +319,8 @@ enum drm_panel_orientation { · 318 unmodified lines
319319 * EDID's detailed monitor range
320320 */
321321 struct drm_monitor_range_info {
322− u8 min_vfreq;
323− u8 max_vfreq;
322+ u16 min_vfreq;
323+ u16 max_vfreq;
324324 };
325325
326326 /**
include/drm/drm_edid.h+5−0
@@ -92,6 +92,11 @@ struct detailed_data_string { · 91 unmodified lines
9292 u8 str[13];
9393 } __attribute__((packed));
9494
95+#define DRM_EDID_RANGE_OFFSET_MIN_VFREQ (1 << 0) /* 1.4 */
96+#define DRM_EDID_RANGE_OFFSET_MAX_VFREQ (1 << 1) /* 1.4 */
97+#define DRM_EDID_RANGE_OFFSET_MIN_HFREQ (1 << 2) /* 1.4 */
98+#define DRM_EDID_RANGE_OFFSET_MAX_HFREQ (1 << 3) /* 1.4 */
99+
95100 #define DRM_EDID_DEFAULT_GTF_SUPPORT_FLAG 0x00
96101 #define DRM_EDID_RANGE_LIMITS_ONLY_FLAG 0x01
97102 #define DRM_EDID_SECONDARY_GTF_SUPPORT_FLAG 0x02