Loading drivers/gpu/drm/drm_edid.c +48 −0 Original line number Diff line number Diff line Loading @@ -897,6 +897,51 @@ static int drm_gtf_modes_for_range(struct drm_connector *connector, return modes; } static int drm_cvt_modes(struct drm_connector *connector, struct detailed_timing *timing) { int i, j, modes = 0; struct drm_display_mode *newmode; struct drm_device *dev = connector->dev; struct cvt_timing *cvt; const int rates[] = { 60, 85, 75, 60, 50 }; for (i = 0; i < 4; i++) { int width, height; cvt = &(timing->data.other_data.data.cvt[i]); height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; switch (cvt->code[1] & 0xc0) { case 0x00: width = height * 4 / 3; break; case 0x40: width = height * 16 / 9; break; case 0x80: width = height * 16 / 10; break; case 0xc0: width = height * 15 / 9; break; } for (j = 1; j < 5; j++) { if (cvt->code[2] & (1 << j)) { newmode = drm_cvt_mode(dev, width, height, rates[j], j == 0, false, false); if (newmode) { drm_mode_probed_add(connector, newmode); modes++; } } } } return modes; } static int add_detailed_modes(struct drm_connector *connector, struct detailed_timing *timing, struct edid *edid, u32 quirks, int preferred) Loading Loading @@ -941,6 +986,9 @@ static int add_detailed_modes(struct drm_connector *connector, } } break; case EDID_DETAIL_CVT_3BYTE: modes += drm_cvt_modes(connector, timing); break; default: break; } Loading include/drm/drm_edid.h +5 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,10 @@ struct detailed_data_color_point { u8 wpindex2[3]; } __attribute__((packed)); struct cvt_timing { u8 code[3]; } __attribute__((packed)); struct detailed_non_pixel { u8 pad1; u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name Loading @@ -117,6 +121,7 @@ struct detailed_non_pixel { struct detailed_data_monitor_range range; struct detailed_data_wpindex color; struct std_timing timings[5]; struct cvt_timing cvt[4]; } data; } __attribute__((packed)); Loading Loading
drivers/gpu/drm/drm_edid.c +48 −0 Original line number Diff line number Diff line Loading @@ -897,6 +897,51 @@ static int drm_gtf_modes_for_range(struct drm_connector *connector, return modes; } static int drm_cvt_modes(struct drm_connector *connector, struct detailed_timing *timing) { int i, j, modes = 0; struct drm_display_mode *newmode; struct drm_device *dev = connector->dev; struct cvt_timing *cvt; const int rates[] = { 60, 85, 75, 60, 50 }; for (i = 0; i < 4; i++) { int width, height; cvt = &(timing->data.other_data.data.cvt[i]); height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; switch (cvt->code[1] & 0xc0) { case 0x00: width = height * 4 / 3; break; case 0x40: width = height * 16 / 9; break; case 0x80: width = height * 16 / 10; break; case 0xc0: width = height * 15 / 9; break; } for (j = 1; j < 5; j++) { if (cvt->code[2] & (1 << j)) { newmode = drm_cvt_mode(dev, width, height, rates[j], j == 0, false, false); if (newmode) { drm_mode_probed_add(connector, newmode); modes++; } } } } return modes; } static int add_detailed_modes(struct drm_connector *connector, struct detailed_timing *timing, struct edid *edid, u32 quirks, int preferred) Loading Loading @@ -941,6 +986,9 @@ static int add_detailed_modes(struct drm_connector *connector, } } break; case EDID_DETAIL_CVT_3BYTE: modes += drm_cvt_modes(connector, timing); break; default: break; } Loading
include/drm/drm_edid.h +5 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,10 @@ struct detailed_data_color_point { u8 wpindex2[3]; } __attribute__((packed)); struct cvt_timing { u8 code[3]; } __attribute__((packed)); struct detailed_non_pixel { u8 pad1; u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name Loading @@ -117,6 +121,7 @@ struct detailed_non_pixel { struct detailed_data_monitor_range range; struct detailed_data_wpindex color; struct std_timing timings[5]; struct cvt_timing cvt[4]; } data; } __attribute__((packed)); Loading