|
@@ -1006,6 +1006,221 @@ static const struct drm_display_mode edid_cea_modes[] = {
|
|
|
2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
.vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
|
|
|
+ /* 65 - 1280x720@24Hz */
|
|
|
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
|
|
|
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 66 - 1280x720@25Hz */
|
|
|
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
|
|
|
+ 3740, 3960, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 67 - 1280x720@30Hz */
|
|
|
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
|
|
|
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 68 - 1280x720@50Hz */
|
|
|
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
|
|
|
+ 1760, 1980, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 69 - 1280x720@60Hz */
|
|
|
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
|
|
|
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 70 - 1280x720@100Hz */
|
|
|
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
|
|
|
+ 1760, 1980, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 71 - 1280x720@120Hz */
|
|
|
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
|
|
|
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 72 - 1920x1080@24Hz */
|
|
|
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
|
|
|
+ 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 73 - 1920x1080@25Hz */
|
|
|
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
|
|
|
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 74 - 1920x1080@30Hz */
|
|
|
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
|
|
|
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 75 - 1920x1080@50Hz */
|
|
|
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
|
|
|
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 76 - 1920x1080@60Hz */
|
|
|
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
|
|
|
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 77 - 1920x1080@100Hz */
|
|
|
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
|
|
|
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 78 - 1920x1080@120Hz */
|
|
|
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
|
|
|
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 79 - 1680x720@24Hz */
|
|
|
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 3040,
|
|
|
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 80 - 1680x720@25Hz */
|
|
|
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2908,
|
|
|
+ 2948, 3168, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 81 - 1680x720@30Hz */
|
|
|
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2380,
|
|
|
+ 2420, 2640, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 82 - 1680x720@50Hz */
|
|
|
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 82500, 1680, 1940,
|
|
|
+ 1980, 2200, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 83 - 1680x720@60Hz */
|
|
|
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 1940,
|
|
|
+ 1980, 2200, 0, 720, 725, 730, 750, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 84 - 1680x720@100Hz */
|
|
|
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 165000, 1680, 1740,
|
|
|
+ 1780, 2000, 0, 720, 725, 730, 825, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 85 - 1680x720@120Hz */
|
|
|
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 198000, 1680, 1740,
|
|
|
+ 1780, 2000, 0, 720, 725, 730, 825, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 86 - 2560x1080@24Hz */
|
|
|
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 99000, 2560, 3558,
|
|
|
+ 3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 87 - 2560x1080@25Hz */
|
|
|
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 90000, 2560, 3008,
|
|
|
+ 3052, 3200, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 88 - 2560x1080@30Hz */
|
|
|
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 118800, 2560, 3328,
|
|
|
+ 3372, 3520, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 89 - 2560x1080@50Hz */
|
|
|
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 185625, 2560, 3108,
|
|
|
+ 3152, 3300, 0, 1080, 1084, 1089, 1125, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 90 - 2560x1080@60Hz */
|
|
|
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 2808,
|
|
|
+ 2852, 3000, 0, 1080, 1084, 1089, 1100, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 91 - 2560x1080@100Hz */
|
|
|
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 371250, 2560, 2778,
|
|
|
+ 2822, 2970, 0, 1080, 1084, 1089, 1250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 92 - 2560x1080@120Hz */
|
|
|
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 495000, 2560, 3108,
|
|
|
+ 3152, 3300, 0, 1080, 1084, 1089, 1250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 93 - 3840x2160p@24Hz 16:9 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
|
|
|
+ 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
|
|
|
+ /* 94 - 3840x2160p@25Hz 16:9 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
|
|
|
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
|
|
|
+ /* 95 - 3840x2160p@30Hz 16:9 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
|
|
|
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
|
|
|
+ /* 96 - 3840x2160p@50Hz 16:9 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
|
|
|
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
|
|
|
+ /* 97 - 3840x2160p@60Hz 16:9 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
|
|
|
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
|
|
|
+ /* 98 - 4096x2160p@24Hz 256:135 */
|
|
|
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5116,
|
|
|
+ 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
|
|
|
+ /* 99 - 4096x2160p@25Hz 256:135 */
|
|
|
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5064,
|
|
|
+ 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
|
|
|
+ /* 100 - 4096x2160p@30Hz 256:135 */
|
|
|
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 4184,
|
|
|
+ 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
|
|
|
+ /* 101 - 4096x2160p@50Hz 256:135 */
|
|
|
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5064,
|
|
|
+ 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
|
|
|
+ /* 102 - 4096x2160p@60Hz 256:135 */
|
|
|
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 4184,
|
|
|
+ 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
|
|
|
+ /* 103 - 3840x2160p@24Hz 64:27 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
|
|
|
+ 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 104 - 3840x2160p@25Hz 64:27 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
|
|
|
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 105 - 3840x2160p@30Hz 64:27 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
|
|
|
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 106 - 3840x2160p@50Hz 64:27 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
|
|
|
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
+ /* 107 - 3840x2160p@60Hz 64:27 */
|
|
|
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
|
|
|
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
|
|
|
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
|
|
|
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -2566,7 +2781,10 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
|
|
|
#define VIDEO_BLOCK 0x02
|
|
|
#define VENDOR_BLOCK 0x03
|
|
|
#define SPEAKER_BLOCK 0x04
|
|
|
-#define VIDEO_CAPABILITY_BLOCK 0x07
|
|
|
+#define USE_EXTENDED_TAG 0x07
|
|
|
+#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
|
|
|
+#define EXT_VIDEO_DATA_BLOCK_420 0x0E
|
|
|
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
|
|
|
#define EDID_BASIC_AUDIO (1 << 6)
|
|
|
#define EDID_CEA_YCRCB444 (1 << 5)
|
|
|
#define EDID_CEA_YCRCB422 (1 << 4)
|
|
@@ -2902,6 +3120,15 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
|
|
|
return modes;
|
|
|
}
|
|
|
|
|
|
+static u8 svd_to_vic(u8 svd)
|
|
|
+{
|
|
|
+ /* 0-6 bit vic, 7th bit native mode indicator */
|
|
|
+ if ((svd >= 1 && svd <= 64) || (svd >= 129 && svd <= 192))
|
|
|
+ return svd & 127;
|
|
|
+
|
|
|
+ return svd;
|
|
|
+}
|
|
|
+
|
|
|
static struct drm_display_mode *
|
|
|
drm_display_mode_from_vic_index(struct drm_connector *connector,
|
|
|
const u8 *video_db, u8 video_len,
|
|
@@ -2915,7 +3142,7 @@ drm_display_mode_from_vic_index(struct drm_connector *connector,
|
|
|
return NULL;
|
|
|
|
|
|
/* CEA modes are numbered 1..127 */
|
|
|
- vic = (video_db[video_index] & 127);
|
|
|
+ vic = svd_to_vic(video_db[video_index]);
|
|
|
if (!drm_valid_cea_vic(vic))
|
|
|
return NULL;
|
|
|
|
|
@@ -2928,15 +3155,85 @@ drm_display_mode_from_vic_index(struct drm_connector *connector,
|
|
|
return newmode;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * do_y420vdb_modes - Parse YCBCR 420 only modes
|
|
|
+ * @connector: connector corresponding to the HDMI sink
|
|
|
+ * @svds: start of the data block of CEA YCBCR 420 VDB
|
|
|
+ * @len: length of the CEA YCBCR 420 VDB
|
|
|
+ *
|
|
|
+ * Parse the CEA-861-F YCBCR 420 Video Data Block (Y420VDB)
|
|
|
+ * which contains modes which can be supported in YCBCR 420
|
|
|
+ * output format only.
|
|
|
+ */
|
|
|
+static int do_y420vdb_modes(struct drm_connector *connector,
|
|
|
+ const u8 *svds, u8 svds_len)
|
|
|
+{
|
|
|
+ int modes = 0, i;
|
|
|
+ struct drm_device *dev = connector->dev;
|
|
|
+ struct drm_display_info *info = &connector->display_info;
|
|
|
+ struct drm_hdmi_info *hdmi = &info->hdmi;
|
|
|
+
|
|
|
+ for (i = 0; i < svds_len; i++) {
|
|
|
+ u8 vic = svd_to_vic(svds[i]);
|
|
|
+ struct drm_display_mode *newmode;
|
|
|
+
|
|
|
+ if (!drm_valid_cea_vic(vic))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ newmode = drm_mode_duplicate(dev, &edid_cea_modes[vic]);
|
|
|
+ if (!newmode)
|
|
|
+ break;
|
|
|
+ bitmap_set(hdmi->y420_vdb_modes, vic, 1);
|
|
|
+ drm_mode_probed_add(connector, newmode);
|
|
|
+ modes++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (modes > 0)
|
|
|
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
|
|
|
+ return modes;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * drm_add_cmdb_modes - Add a YCBCR 420 mode into bitmap
|
|
|
+ * @connector: connector corresponding to the HDMI sink
|
|
|
+ * @vic: CEA vic for the video mode to be added in the map
|
|
|
+ *
|
|
|
+ * Makes an entry for a videomode in the YCBCR 420 bitmap
|
|
|
+ */
|
|
|
+static void
|
|
|
+drm_add_cmdb_modes(struct drm_connector *connector, u8 svd)
|
|
|
+{
|
|
|
+ u8 vic = svd_to_vic(svd);
|
|
|
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
|
|
|
+
|
|
|
+ if (!drm_valid_cea_vic(vic))
|
|
|
+ return;
|
|
|
+
|
|
|
+ bitmap_set(hdmi->y420_cmdb_modes, vic, 1);
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
|
|
|
{
|
|
|
int i, modes = 0;
|
|
|
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
|
|
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
struct drm_display_mode *mode;
|
|
|
mode = drm_display_mode_from_vic_index(connector, db, len, i);
|
|
|
if (mode) {
|
|
|
+ /*
|
|
|
+ * YCBCR420 capability block contains a bitmap which
|
|
|
+ * gives the index of CEA modes from CEA VDB, which
|
|
|
+ * can support YCBCR 420 sampling output also (apart
|
|
|
+ * from RGB/YCBCR444 etc).
|
|
|
+ * For example, if the bit 0 in bitmap is set,
|
|
|
+ * first mode in VDB can support YCBCR420 output too.
|
|
|
+ * Add YCBCR420 modes only if sink is HDMI 2.0 capable.
|
|
|
+ */
|
|
|
+ if (i < 64 && hdmi->y420_cmdb_map & (1ULL << i))
|
|
|
+ drm_add_cmdb_modes(connector, db[i]);
|
|
|
+
|
|
|
drm_mode_probed_add(connector, mode);
|
|
|
modes++;
|
|
|
}
|
|
@@ -3217,6 +3514,12 @@ cea_db_payload_len(const u8 *db)
|
|
|
return db[0] & 0x1f;
|
|
|
}
|
|
|
|
|
|
+static int
|
|
|
+cea_db_extended_tag(const u8 *db)
|
|
|
+{
|
|
|
+ return db[1];
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
cea_db_tag(const u8 *db)
|
|
|
{
|
|
@@ -3272,9 +3575,77 @@ static bool cea_db_is_hdmi_forum_vsdb(const u8 *db)
|
|
|
return oui == HDMI_FORUM_IEEE_OUI;
|
|
|
}
|
|
|
|
|
|
+static bool cea_db_is_y420cmdb(const u8 *db)
|
|
|
+{
|
|
|
+ if (cea_db_tag(db) != USE_EXTENDED_TAG)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (!cea_db_payload_len(db))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (cea_db_extended_tag(db) != EXT_VIDEO_CAP_BLOCK_Y420CMDB)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+static bool cea_db_is_y420vdb(const u8 *db)
|
|
|
+{
|
|
|
+ if (cea_db_tag(db) != USE_EXTENDED_TAG)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (!cea_db_payload_len(db))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (cea_db_extended_tag(db) != EXT_VIDEO_DATA_BLOCK_420)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
#define for_each_cea_db(cea, i, start, end) \
|
|
|
for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
|
|
|
|
|
|
+static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
|
|
|
+ const u8 *db)
|
|
|
+{
|
|
|
+ struct drm_display_info *info = &connector->display_info;
|
|
|
+ struct drm_hdmi_info *hdmi = &info->hdmi;
|
|
|
+ u8 map_len = cea_db_payload_len(db) - 1;
|
|
|
+ u8 count;
|
|
|
+ u64 map = 0;
|
|
|
+
|
|
|
+ if (map_len == 0) {
|
|
|
+ /* All CEA modes support ycbcr420 sampling also.*/
|
|
|
+ hdmi->y420_cmdb_map = U64_MAX;
|
|
|
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * This map indicates which of the existing CEA block modes
|
|
|
+ * from VDB can support YCBCR420 output too. So if bit=0 is
|
|
|
+ * set, first mode from VDB can support YCBCR420 output too.
|
|
|
+ * We will parse and keep this map, before parsing VDB itself
|
|
|
+ * to avoid going through the same block again and again.
|
|
|
+ *
|
|
|
+ * Spec is not clear about max possible size of this block.
|
|
|
+ * Clamping max bitmap block size at 8 bytes. Every byte can
|
|
|
+ * address 8 CEA modes, in this way this map can address
|
|
|
+ * 8*8 = first 64 SVDs.
|
|
|
+ */
|
|
|
+ if (WARN_ON_ONCE(map_len > 8))
|
|
|
+ map_len = 8;
|
|
|
+
|
|
|
+ for (count = 0; count < map_len; count++)
|
|
|
+ map |= (u64)db[2 + count] << (8 * count);
|
|
|
+
|
|
|
+ if (map)
|
|
|
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
|
|
|
+
|
|
|
+ hdmi->y420_cmdb_map = map;
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
add_cea_modes(struct drm_connector *connector, struct edid *edid)
|
|
|
{
|
|
@@ -3297,10 +3668,16 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
|
|
|
video = db + 1;
|
|
|
video_len = dbl;
|
|
|
modes += do_cea_modes(connector, video, dbl);
|
|
|
- }
|
|
|
- else if (cea_db_is_hdmi_vsdb(db)) {
|
|
|
+ } else if (cea_db_is_hdmi_vsdb(db)) {
|
|
|
hdmi = db;
|
|
|
hdmi_len = dbl;
|
|
|
+ } else if (cea_db_is_y420vdb(db)) {
|
|
|
+ const u8 *vdb420 = &db[2];
|
|
|
+
|
|
|
+ /* Add 4:2:0(only) modes present in EDID */
|
|
|
+ modes += do_y420vdb_modes(connector,
|
|
|
+ vdb420,
|
|
|
+ dbl - 1);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -3793,8 +4170,10 @@ bool drm_rgb_quant_range_selectable(struct edid *edid)
|
|
|
return false;
|
|
|
|
|
|
for_each_cea_db(edid_ext, i, start, end) {
|
|
|
- if (cea_db_tag(&edid_ext[i]) == VIDEO_CAPABILITY_BLOCK &&
|
|
|
- cea_db_payload_len(&edid_ext[i]) == 2) {
|
|
|
+ if (cea_db_tag(&edid_ext[i]) == USE_EXTENDED_TAG &&
|
|
|
+ cea_db_payload_len(&edid_ext[i]) == 2 &&
|
|
|
+ cea_db_extended_tag(&edid_ext[i]) ==
|
|
|
+ EXT_VIDEO_CAPABILITY_BLOCK) {
|
|
|
DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", edid_ext[i + 2]);
|
|
|
return edid_ext[i + 2] & EDID_CEA_VCDB_QS;
|
|
|
}
|
|
@@ -3823,6 +4202,16 @@ drm_default_rgb_quant_range(const struct drm_display_mode *mode)
|
|
|
}
|
|
|
EXPORT_SYMBOL(drm_default_rgb_quant_range);
|
|
|
|
|
|
+static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
|
|
|
+ const u8 *db)
|
|
|
+{
|
|
|
+ u8 dc_mask;
|
|
|
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
|
|
|
+
|
|
|
+ dc_mask = db[7] & DRM_EDID_YCBCR420_DC_MASK;
|
|
|
+ hdmi->y420_dc_modes |= dc_mask;
|
|
|
+}
|
|
|
+
|
|
|
static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector,
|
|
|
const u8 *hf_vsdb)
|
|
|
{
|
|
@@ -3863,6 +4252,8 @@ static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector,
|
|
|
scdc->scrambling.low_rates = true;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ drm_parse_ycbcr420_deep_color_info(connector, hf_vsdb);
|
|
|
}
|
|
|
|
|
|
static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
|
|
@@ -3981,6 +4372,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
|
|
|
drm_parse_hdmi_vsdb_video(connector, db);
|
|
|
if (cea_db_is_hdmi_forum_vsdb(db))
|
|
|
drm_parse_hdmi_forum_vsdb(connector, db);
|
|
|
+ if (cea_db_is_y420cmdb(db))
|
|
|
+ drm_parse_y420cmdb_bitmap(connector, db);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -4214,6 +4607,13 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
|
|
|
|
|
|
quirks = edid_get_quirks(edid);
|
|
|
|
|
|
+ /*
|
|
|
+ * CEA-861-F adds ycbcr capability map block, for HDMI 2.0 sinks.
|
|
|
+ * To avoid multiple parsing of same block, lets parse that map
|
|
|
+ * from sink info, before parsing CEA modes.
|
|
|
+ */
|
|
|
+ drm_add_display_info(connector, edid);
|
|
|
+
|
|
|
/*
|
|
|
* EDID spec says modes should be preferred in this order:
|
|
|
* - preferred detailed mode
|
|
@@ -4241,8 +4641,6 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
|
|
|
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
|
|
|
edid_fixup_preferred(connector, quirks);
|
|
|
|
|
|
- drm_add_display_info(connector, edid);
|
|
|
-
|
|
|
if (quirks & EDID_QUIRK_FORCE_6BPC)
|
|
|
connector->display_info.bpc = 6;
|
|
|
|
|
@@ -4334,12 +4732,14 @@ EXPORT_SYMBOL(drm_set_preferred_mode);
|
|
|
* data from a DRM display mode
|
|
|
* @frame: HDMI AVI infoframe
|
|
|
* @mode: DRM display mode
|
|
|
+ * @is_hdmi2_sink: Sink is HDMI 2.0 compliant
|
|
|
*
|
|
|
* Return: 0 on success or a negative error code on failure.
|
|
|
*/
|
|
|
int
|
|
|
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
|
|
|
- const struct drm_display_mode *mode)
|
|
|
+ const struct drm_display_mode *mode,
|
|
|
+ bool is_hdmi2_sink)
|
|
|
{
|
|
|
int err;
|
|
|
|
|
@@ -4355,6 +4755,28 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
|
|
|
|
|
|
frame->video_code = drm_match_cea_mode(mode);
|
|
|
|
|
|
+ /*
|
|
|
+ * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but
|
|
|
+ * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we
|
|
|
+ * have to make sure we dont break HDMI 1.4 sinks.
|
|
|
+ */
|
|
|
+ if (!is_hdmi2_sink && frame->video_code > 64)
|
|
|
+ frame->video_code = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * HDMI spec says if a mode is found in HDMI 1.4b 4K modes
|
|
|
+ * we should send its VIC in vendor infoframes, else send the
|
|
|
+ * VIC in AVI infoframes. Lets check if this mode is present in
|
|
|
+ * HDMI 1.4b 4K modes
|
|
|
+ */
|
|
|
+ if (frame->video_code) {
|
|
|
+ u8 vendor_if_vic = drm_match_hdmi_mode(mode);
|
|
|
+ bool is_s3d = mode->flags & DRM_MODE_FLAG_3D_MASK;
|
|
|
+
|
|
|
+ if (drm_valid_hdmi_vic(vendor_if_vic) && !is_s3d)
|
|
|
+ frame->video_code = 0;
|
|
|
+ }
|
|
|
+
|
|
|
frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
|
|
|
|
|
|
/*
|