From 00997ff116c359d2a523271069632c7911c629a0 Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Tue, 9 Jun 2020 10:24:59 +0800 Subject: [PATCH] edid: Move functions of sorting modes to edid.c Not only does dw-hdmi use these functions, but others need to use them, such as inno-hdmi. Change-Id: I1ced6e30b7634511fecbbfb39c24ede78894dd1d Signed-off-by: Algea Cao --- common/edid.c | 318 +++++++++++++++++++++++++++ drivers/video/drm/dw_hdmi.h | 3 - drivers/video/drm/rockchip_dw_hdmi.c | 318 --------------------------- include/edid.h | 5 + 4 files changed, 323 insertions(+), 321 deletions(-) diff --git a/common/edid.c b/common/edid.c index f8301fb3ce..8ae25df940 100644 --- a/common/edid.c +++ b/common/edid.c @@ -1191,6 +1191,166 @@ static const struct drm_display_mode edid_est_modes[] = { DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, }; +#define DRM_BASE_MODE(c, hd, hss, hse, ht, vd, vss, vse, vt, vs, f) \ + .clock = (c), \ + .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \ + .htotal = (ht), .vdisplay = (vd), \ + .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \ + .vscan = (vs), .flags = (f) + +static const struct base_drm_display_mode resolution_white[] = { + /* 0. vic:2 - 720x480@60Hz */ + { DRM_BASE_MODE(27000, 720, 736, + 798, 858, 480, 489, 495, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), + .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, + /* 1. vic:3 - 720x480@60Hz */ + { DRM_BASE_MODE(27000, 720, 736, + 798, 858, 480, 489, 495, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), + .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 2. vic:4 - 1280x720@60Hz */ + { DRM_BASE_MODE(74250, 1280, 1390, + 1430, 1650, 720, 725, 730, 750, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 3. vic:5 - 1920x1080i@60Hz */ + { DRM_BASE_MODE(74250, 1920, 2008, + 2052, 2200, 1080, 1084, 1094, 1125, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | + DRM_MODE_FLAG_INTERLACE), + .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 4. vic:6 - 720(1440)x480i@60Hz */ + { DRM_BASE_MODE(13500, 720, 739, + 801, 858, 480, 488, 494, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), + .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, + /* 5. vic:16 - 1920x1080@60Hz */ + { DRM_BASE_MODE(148500, 1920, 2008, + 2052, 2200, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 6. vic:17 - 720x576@50Hz */ + { DRM_BASE_MODE(27000, 720, 732, + 796, 864, 576, 581, 586, 625, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), + .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, + /* 7. vic:18 - 720x576@50Hz */ + { DRM_BASE_MODE(27000, 720, 732, + 796, 864, 576, 581, 586, 625, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), + .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 8. vic:19 - 1280x720@50Hz */ + { DRM_BASE_MODE(74250, 1280, 1720, + 1760, 1980, 720, 725, 730, 750, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 9. vic:20 - 1920x1080i@50Hz */ + { DRM_BASE_MODE(74250, 1920, 2448, + 2492, 2640, 1080, 1084, 1094, 1125, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | + DRM_MODE_FLAG_INTERLACE), + .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 10. vic:21 - 720(1440)x576i@50Hz */ + { DRM_BASE_MODE(13500, 720, 732, + 795, 864, 576, 580, 586, 625, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), + .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, + /* 11. vic:31 - 1920x1080@50Hz */ + { DRM_BASE_MODE(148500, 1920, 2448, + 2492, 2640, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 12. vic:32 - 1920x1080@24Hz */ + { DRM_BASE_MODE(74250, 1920, 2558, + 2602, 2750, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 13. vic:33 - 1920x1080@25Hz */ + { DRM_BASE_MODE(74250, 1920, 2448, + 2492, 2640, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 14. vic:34 - 1920x1080@30Hz */ + { DRM_BASE_MODE(74250, 1920, 2008, + 2052, 2200, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 15. vic:39 - 1920x1080i@50Hz */ + { DRM_BASE_MODE(72000, 1920, 1952, + 2120, 2304, 1080, 1126, 1136, 1250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC | + DRM_MODE_FLAG_INTERLACE), + .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 16. vic:60 - 1280x720@24Hz */ + { DRM_BASE_MODE(59400, 1280, 3040, + 3080, 3300, 720, 725, 730, 750, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 17. vic:61 - 1280x720@25Hz */ + { DRM_BASE_MODE(74250, 1280, 3700, + 3740, 3960, 720, 725, 730, 750, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 18. vic:62 - 1280x720@30Hz */ + { DRM_BASE_MODE(74250, 1280, 3040, + 3080, 3300, 720, 725, 730, 750, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 19. vic:93 - 3840x2160p@24Hz 16:9 */ + { DRM_BASE_MODE(297000, 3840, 5116, + 5204, 5500, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 20. vic:94 - 3840x2160p@25Hz 16:9 */ + { DRM_BASE_MODE(297000, 3840, 4896, + 4984, 5280, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 21. vic:95 - 3840x2160p@30Hz 16:9 */ + { DRM_BASE_MODE(297000, 3840, 4016, + 4104, 4400, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 22. vic:96 - 3840x2160p@50Hz 16:9 */ + { DRM_BASE_MODE(594000, 3840, 4896, + 4984, 5280, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 23. vic:97 - 3840x2160p@60Hz 16:9 */ + { DRM_BASE_MODE(594000, 3840, 4016, + 4104, 4400, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, + /* 24. vic:98 - 4096x2160p@24Hz 256:135 */ + { DRM_BASE_MODE(297000, 4096, 5116, + 5204, 5500, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, + /* 25. vic:99 - 4096x2160p@25Hz 256:135 */ + { DRM_BASE_MODE(297000, 4096, 5064, + 5152, 5280, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, + /* 26. vic:100 - 4096x2160p@30Hz 256:135 */ + { DRM_BASE_MODE(297000, 4096, 4184, + 4272, 4400, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, + /* 27. vic:101 - 4096x2160p@50Hz 256:135 */ + { DRM_BASE_MODE(594000, 4096, 5064, + 5152, 5280, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, + /* 28. vic:102 - 4096x2160p@60Hz 256:135 */ + { DRM_BASE_MODE(594000, 4096, 4184, + 4272, 4400, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, +}; + struct minimode { short w; short h; @@ -6008,6 +6168,164 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer) return ret; } +bool drm_mode_equal(const struct base_drm_display_mode *mode1, + const struct drm_display_mode *mode2) +{ + unsigned int flags_mask = + DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_PHSYNC | + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC | + DRM_MODE_FLAG_NVSYNC; + + if (mode1->clock == mode2->clock && + mode1->hdisplay == mode2->hdisplay && + mode1->hsync_start == mode2->hsync_start && + mode1->hsync_end == mode2->hsync_end && + mode1->htotal == mode2->htotal && + mode1->vdisplay == mode2->vdisplay && + mode1->vsync_start == mode2->vsync_start && + mode1->vsync_end == mode2->vsync_end && + mode1->vtotal == mode2->vtotal && + (mode1->flags & flags_mask) == (mode2->flags & flags_mask)) { + return true; + } + + return false; +} + +/** + * drm_mode_sort - sort mode list + * @edid_data: modes structures to sort + * + * Sort @edid_data by favorability, moving good modes to the head of the list. + */ +void drm_mode_sort(struct hdmi_edid_data *edid_data) +{ + struct drm_display_mode *a, *b; + struct drm_display_mode c; + int diff, i, j; + + for (i = 0; i < (edid_data->modes - 1); i++) { + a = &edid_data->mode_buf[i]; + for (j = i + 1; j < edid_data->modes; j++) { + b = &edid_data->mode_buf[j]; + diff = ((b->type & DRM_MODE_TYPE_PREFERRED) != 0) - + ((a->type & DRM_MODE_TYPE_PREFERRED) != 0); + if (diff) { + if (diff > 0) { + c = *a; + *a = *b; + *b = c; + } + continue; + } + + diff = b->hdisplay * b->vdisplay + - a->hdisplay * a->vdisplay; + if (diff) { + if (diff > 0) { + c = *a; + *a = *b; + *b = c; + } + continue; + } + + diff = b->vrefresh - a->vrefresh; + if (diff) { + if (diff > 0) { + c = *a; + *a = *b; + *b = c; + } + continue; + } + + diff = b->clock - a->clock; + if (diff > 0) { + c = *a; + *a = *b; + *b = c; + } + } + } + edid_data->preferred_mode = &edid_data->mode_buf[0]; +} + +/** + * drm_mode_prune_invalid - remove invalid modes from mode list + * @edid_data: structure store mode list + * Returns: + * Number of valid modes. + */ +int drm_mode_prune_invalid(struct hdmi_edid_data *edid_data) +{ + int i, j; + int num = edid_data->modes; + int len = sizeof(struct drm_display_mode); + struct drm_display_mode *mode_buf = edid_data->mode_buf; + + for (i = 0; i < num; i++) { + if (mode_buf[i].invalid) { + /* If mode is invalid, delete it. */ + for (j = i; j < num - 1; j++) + memcpy(&mode_buf[j], &mode_buf[j + 1], len); + + num--; + i--; + } + } + /* Clear redundant modes of mode_buf. */ + memset(&mode_buf[num], 0, len * (edid_data->modes - num)); + + edid_data->modes = num; + return num; +} + +/** + * drm_rk_filter_whitelist - mark modes out of white list from mode list + * @edid_data: structure store mode list + */ +void drm_rk_filter_whitelist(struct hdmi_edid_data *edid_data) +{ + int i, j, white_len; + + if (sizeof(resolution_white)) { + white_len = sizeof(resolution_white) / + sizeof(resolution_white[0]); + for (i = 0; i < edid_data->modes; i++) { + for (j = 0; j < white_len; j++) { + if (drm_mode_equal(&resolution_white[j], + &edid_data->mode_buf[i])) + break; + } + + if (j == white_len) + edid_data->mode_buf[i].invalid = true; + } + } +} + +void drm_rk_select_mode(struct hdmi_edid_data *edid_data, + struct base_screen_info *screen_info) +{ + int i; + const struct base_drm_display_mode *base_mode; + + if (!screen_info) { + /* define init resolution here */ + } else { + base_mode = &screen_info->mode; + for (i = 0; i < edid_data->modes; i++) { + if (drm_mode_equal(base_mode, + &edid_data->mode_buf[i])) { + edid_data->preferred_mode = + &edid_data->mode_buf[i]; + break; + } + } + } +} + /** * drm_do_probe_ddc_edid() - get EDID information via I2C * @adap: ddc adapter diff --git a/drivers/video/drm/dw_hdmi.h b/drivers/video/drm/dw_hdmi.h index f3df9f6054..a3e1fa7c2c 100644 --- a/drivers/video/drm/dw_hdmi.h +++ b/drivers/video/drm/dw_hdmi.h @@ -1404,9 +1404,6 @@ enum { FAST_MODE }; -void drm_mode_sort(struct hdmi_edid_data *edid_data); -int drm_mode_prune_invalid(struct hdmi_edid_data *edid_data); -void drm_rk_filter_whitelist(struct hdmi_edid_data *edid_data); void drm_rk_selete_output(struct hdmi_edid_data *edid_data, unsigned int *bus_format, struct overscan *overscan, diff --git a/drivers/video/drm/rockchip_dw_hdmi.c b/drivers/video/drm/rockchip_dw_hdmi.c index 30acb21b29..c856b61773 100644 --- a/drivers/video/drm/rockchip_dw_hdmi.c +++ b/drivers/video/drm/rockchip_dw_hdmi.c @@ -35,13 +35,6 @@ #define RK3328_GRF_SOC_CON3 0x040c #define RK3328_GRF_SOC_CON4 0x0410 -#define DRM_BASE_MODE(c, hd, hss, hse, ht, vd, vss, vse, vt, vs, f) \ - .clock = (c), \ - .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \ - .htotal = (ht), .vdisplay = (vd), \ - .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \ - .vscan = (vs), .flags = (f) - static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { { 30666000, { @@ -188,317 +181,6 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = { { ~0UL, 0x0000, 0x0000, 0x0000} }; -static const struct base_drm_display_mode resolution_white[] = { - /* 0. vic:2 - 720x480@60Hz */ - { DRM_BASE_MODE(27000, 720, 736, - 798, 858, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), - .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 1. vic:3 - 720x480@60Hz */ - { DRM_BASE_MODE(27000, 720, 736, - 798, 858, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), - .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 2. vic:4 - 1280x720@60Hz */ - { DRM_BASE_MODE(74250, 1280, 1390, - 1430, 1650, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 3. vic:5 - 1920x1080i@60Hz */ - { DRM_BASE_MODE(74250, 1920, 2008, - 2052, 2200, 1080, 1084, 1094, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | - DRM_MODE_FLAG_INTERLACE), - .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 4. vic:6 - 720(1440)x480i@60Hz */ - { DRM_BASE_MODE(13500, 720, 739, - 801, 858, 480, 488, 494, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), - .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 5. vic:16 - 1920x1080@60Hz */ - { DRM_BASE_MODE(148500, 1920, 2008, - 2052, 2200, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 6. vic:17 - 720x576@50Hz */ - { DRM_BASE_MODE(27000, 720, 732, - 796, 864, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), - .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 7. vic:18 - 720x576@50Hz */ - { DRM_BASE_MODE(27000, 720, 732, - 796, 864, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), - .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 8. vic:19 - 1280x720@50Hz */ - { DRM_BASE_MODE(74250, 1280, 1720, - 1760, 1980, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 9. vic:20 - 1920x1080i@50Hz */ - { DRM_BASE_MODE(74250, 1920, 2448, - 2492, 2640, 1080, 1084, 1094, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | - DRM_MODE_FLAG_INTERLACE), - .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 10. vic:21 - 720(1440)x576i@50Hz */ - { DRM_BASE_MODE(13500, 720, 732, - 795, 864, 576, 580, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), - .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, - /* 11. vic:31 - 1920x1080@50Hz */ - { DRM_BASE_MODE(148500, 1920, 2448, - 2492, 2640, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 12. vic:32 - 1920x1080@24Hz */ - { DRM_BASE_MODE(74250, 1920, 2558, - 2602, 2750, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 13. vic:33 - 1920x1080@25Hz */ - { DRM_BASE_MODE(74250, 1920, 2448, - 2492, 2640, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 14. vic:34 - 1920x1080@30Hz */ - { DRM_BASE_MODE(74250, 1920, 2008, - 2052, 2200, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 15. vic:39 - 1920x1080i@50Hz */ - { DRM_BASE_MODE(72000, 1920, 1952, - 2120, 2304, 1080, 1126, 1136, 1250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE), - .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 16. vic:60 - 1280x720@24Hz */ - { DRM_BASE_MODE(59400, 1280, 3040, - 3080, 3300, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 17. vic:61 - 1280x720@25Hz */ - { DRM_BASE_MODE(74250, 1280, 3700, - 3740, 3960, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 18. vic:62 - 1280x720@30Hz */ - { DRM_BASE_MODE(74250, 1280, 3040, - 3080, 3300, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 19. vic:93 - 3840x2160p@24Hz 16:9 */ - { DRM_BASE_MODE(297000, 3840, 5116, - 5204, 5500, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 20. vic:94 - 3840x2160p@25Hz 16:9 */ - { DRM_BASE_MODE(297000, 3840, 4896, - 4984, 5280, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 21. vic:95 - 3840x2160p@30Hz 16:9 */ - { DRM_BASE_MODE(297000, 3840, 4016, - 4104, 4400, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 22. vic:96 - 3840x2160p@50Hz 16:9 */ - { DRM_BASE_MODE(594000, 3840, 4896, - 4984, 5280, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 23. vic:97 - 3840x2160p@60Hz 16:9 */ - { DRM_BASE_MODE(594000, 3840, 4016, - 4104, 4400, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, - /* 24. vic:98 - 4096x2160p@24Hz 256:135 */ - { DRM_BASE_MODE(297000, 4096, 5116, - 5204, 5500, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, - /* 25. vic:99 - 4096x2160p@25Hz 256:135 */ - { DRM_BASE_MODE(297000, 4096, 5064, - 5152, 5280, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, - /* 26. vic:100 - 4096x2160p@30Hz 256:135 */ - { DRM_BASE_MODE(297000, 4096, 4184, - 4272, 4400, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, - /* 27. vic:101 - 4096x2160p@50Hz 256:135 */ - { DRM_BASE_MODE(594000, 4096, 5064, - 5152, 5280, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, - /* 28. vic:102 - 4096x2160p@60Hz 256:135 */ - { DRM_BASE_MODE(594000, 4096, 4184, - 4272, 4400, 2160, 2168, 2178, 2250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), - .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, }, -}; - -static bool drm_mode_equal(const struct base_drm_display_mode *mode1, - const struct drm_display_mode *mode2) -{ - unsigned int flags_mask = - DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_PHSYNC | - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC | - DRM_MODE_FLAG_NVSYNC; - - if (mode1->clock == mode2->clock && - mode1->hdisplay == mode2->hdisplay && - mode1->hsync_start == mode2->hsync_start && - mode1->hsync_end == mode2->hsync_end && - mode1->htotal == mode2->htotal && - mode1->vdisplay == mode2->vdisplay && - mode1->vsync_start == mode2->vsync_start && - mode1->vsync_end == mode2->vsync_end && - mode1->vtotal == mode2->vtotal && - (mode1->flags & flags_mask) == (mode2->flags & flags_mask)) { - return true; - } - - return false; -} - -/** - * drm_mode_sort - sort mode list - * @edid_data: modes structures to sort - * - * Sort @edid_data by favorability, moving good modes to the head of the list. - */ -void drm_mode_sort(struct hdmi_edid_data *edid_data) -{ - struct drm_display_mode *a, *b; - struct drm_display_mode c; - int diff, i, j; - - for (i = 0; i < (edid_data->modes - 1); i++) { - a = &edid_data->mode_buf[i]; - for (j = i + 1; j < edid_data->modes; j++) { - b = &edid_data->mode_buf[j]; - diff = ((b->type & DRM_MODE_TYPE_PREFERRED) != 0) - - ((a->type & DRM_MODE_TYPE_PREFERRED) != 0); - if (diff) { - if (diff > 0) { - c = *a; - *a = *b; - *b = c; - } - continue; - } - - diff = b->hdisplay * b->vdisplay - - a->hdisplay * a->vdisplay; - if (diff) { - if (diff > 0) { - c = *a; - *a = *b; - *b = c; - } - continue; - } - - diff = b->vrefresh - a->vrefresh; - if (diff) { - if (diff > 0) { - c = *a; - *a = *b; - *b = c; - } - continue; - } - - diff = b->clock - a->clock; - if (diff > 0) { - c = *a; - *a = *b; - *b = c; - } - } - } - edid_data->preferred_mode = &edid_data->mode_buf[0]; -} - -/** - * drm_mode_prune_invalid - remove invalid modes from mode list - * @edid_data: structure store mode list - * Returns: - * Number of valid modes. - */ -int drm_mode_prune_invalid(struct hdmi_edid_data *edid_data) -{ - int i, j; - int num = edid_data->modes; - int len = sizeof(struct drm_display_mode); - struct drm_display_mode *mode_buf = edid_data->mode_buf; - - for (i = 0; i < num; i++) { - if (mode_buf[i].invalid) { - /* If mode is invalid, delete it. */ - for (j = i; j < num - 1; j++) - memcpy(&mode_buf[j], &mode_buf[j + 1], len); - - num--; - i--; - } - } - /* Clear redundant modes of mode_buf. */ - memset(&mode_buf[num], 0, len * (edid_data->modes - num)); - - edid_data->modes = num; - return num; -} - -/** - * drm_rk_filter_whitelist - mark modes out of white list from mode list - * @edid_data: structure store mode list - */ -void drm_rk_filter_whitelist(struct hdmi_edid_data *edid_data) -{ - int i, j, white_len; - - if (sizeof(resolution_white)) { - white_len = sizeof(resolution_white) / - sizeof(resolution_white[0]); - for (i = 0; i < edid_data->modes; i++) { - for (j = 0; j < white_len; j++) { - if (drm_mode_equal(&resolution_white[j], - &edid_data->mode_buf[i])) - break; - } - - if (j == white_len) - edid_data->mode_buf[i].invalid = true; - } - } -} - -void drm_rk_select_mode(struct hdmi_edid_data *edid_data, - struct base_screen_info *screen_info) -{ - int i; - const struct base_drm_display_mode *base_mode; - - if (!screen_info) { - /* define init resolution here */ - } else { - base_mode = &screen_info->mode; - for (i = 0; i < edid_data->modes; i++) { - if (drm_mode_equal(base_mode, - &edid_data->mode_buf[i])) { - edid_data->preferred_mode = - &edid_data->mode_buf[i]; - break; - } - } - } -} - static unsigned int drm_rk_select_color(struct hdmi_edid_data *edid_data, struct base_screen_info *screen_info, enum dw_hdmi_devtype dev_type) diff --git a/include/edid.h b/include/edid.h index 7e52b325fd..aa2d0aaa7e 100644 --- a/include/edid.h +++ b/include/edid.h @@ -853,5 +853,10 @@ u8 drm_scdc_readb(struct ddc_adapter *adap, u8 offset, u8 *value); u8 drm_scdc_writeb(struct ddc_adapter *adap, u8 offset, u8 value); +void drm_mode_sort(struct hdmi_edid_data *edid_data); +int drm_mode_prune_invalid(struct hdmi_edid_data *edid_data); +void drm_rk_filter_whitelist(struct hdmi_edid_data *edid_data); +void drm_rk_select_mode(struct hdmi_edid_data *edid_data, + struct base_screen_info *screen_info); #endif /* __EDID_H_ */