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 <algea.cao@rock-chips.com>
This commit is contained in:
Algea Cao 2020-06-09 10:24:59 +08:00 committed by Jianhong Chen
parent d34efd258b
commit 00997ff116
4 changed files with 323 additions and 321 deletions

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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_ */