1 #include "rockchip-hdmi.h"
3 static const struct hdmi_video_timing hdmi_mode[] = {
4 /* name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag vic 2ndvic pixelrepeat interface */
6 { { "720x480i@60Hz", 60, 720, 480, 27000000, 57, 19, 15, 4, 62, 3, 0, 1, 0 }, 6, HDMI_720X480I_60HZ_16_9, 2, OUT_P888},
7 { { "720x576i@50Hz", 50, 720, 576, 27000000, 69, 12, 19, 2, 63, 3, 0, 1, 0 }, 21, HDMI_720X576I_50HZ_16_9, 2, OUT_P888},
8 { { "720x480p@60Hz", 60, 720, 480, 27000000, 60, 16, 30, 9, 62, 6, 0, 0, 0 }, 2, HDMI_720X480P_60HZ_16_9, 1, OUT_P888},
9 { { "720x576p@50Hz", 50, 720, 576, 27000000, 68, 12, 39, 5, 64, 5, 0, 0, 0 }, 17, HDMI_720X576P_50HZ_16_9, 1, OUT_P888},
10 { { "1280x720p@24Hz", 24, 1280, 720, 59400000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 60, HDMI_1280X720P_24HZ_4_3, 1, OUT_P888},
11 { { "1280x720p@25Hz", 25, 1280, 720, 74250000, 220, 2420, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 61, HDMI_1280X720P_25HZ_4_3, 1, OUT_P888},
12 { { "1280x720p@30Hz", 30, 1280, 720, 74250000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 62, HDMI_1280X720P_30HZ_4_3, 1, OUT_P888},
13 { { "1280x720p@50Hz", 50, 1280, 720, 74250000, 220, 440, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 19, HDMI_1280X720P_50HZ_4_3, 1, OUT_P888},
14 { { "1280x720p@60Hz", 60, 1280, 720, 74250000, 220, 110, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 4, HDMI_1280X720P_60HZ_4_3, 1, OUT_P888},
15 { { "1920x1080i@50Hz", 50, 1920, 1080, 74250000, 148, 528, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 0 }, 20, 0, 1, OUT_P888},
16 { { "1920x1080i@60Hz", 60, 1920, 1080, 74250000, 148, 88, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 0 }, 5, 0, 1, OUT_P888},
17 { { "1920x1080p@24Hz", 24, 1920, 1080, 74250000, 148, 638, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 32, HDMI_1920X1080P_24HZ_4_3, 1, OUT_P888},
18 { { "1920x1080p@25Hz", 25, 1920, 1080, 74250000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 33, HDMI_1920X1080P_25HZ_4_3, 1, OUT_P888},
19 { { "1920x1080p@30Hz", 30, 1920, 1080, 74250000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 34, HDMI_1920X1080P_30HZ_4_3, 1, OUT_P888},
20 { { "1920x1080p@50Hz", 50, 1920, 1080, 148500000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 31, HDMI_1920X1080P_50HZ_4_3, 1, OUT_P888},
21 { { "1920x1080p@60Hz", 60, 1920, 1080, 148500000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 16, HDMI_1920X1080P_60HZ_4_3, 1, OUT_P888},
22 { { "3840x2160p@24Hz", 24, 3840, 2160, 297000000, 296, 1276, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 93, HDMI_3840X2160P_24HZ_4_3, 1, OUT_P888},
23 { { "3840x2160p@25Hz", 25, 3840, 2160, 297000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 94, HDMI_3840X2160P_25HZ_4_3, 1, OUT_P888},
24 { { "3840x2160p@30Hz", 30, 3840, 2160, 297000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 95, HDMI_3840X2160P_30HZ_4_3, 1, OUT_P888},
25 { { "4096x2160p@24Hz", 24, 4096, 2160, 297000000, 296, 1020, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 98, 0, 1, OUT_P888},
26 { { "4096x2160p@25Hz", 25, 4096, 2160, 297000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 99, 0, 1, OUT_P888},
27 { { "4096x2160p@30Hz", 30, 4096, 2160, 297000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 100, 0, 1, OUT_P888},
28 { { "3840x2160p@50Hz", 50, 3840, 2160, 594000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 96, HDMI_3840X2160P_50HZ_4_3, 1, OUT_P888},
29 { { "3840x2160p@60Hz", 60, 3840, 2160, 594000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 97, HDMI_3840X2160P_60HZ_4_3, 1, OUT_P888},
30 { { "4096x2160p@50Hz", 50, 4096, 2160, 594000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 101, 0, 1, OUT_P888},
31 { { "4096x2160p@60Hz", 60, 4096, 2160, 594000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 102, 0, 1, OUT_P888},
32 { { "800x600p@60Hz", 60, 800, 600, 40000000, 88, 40, 23, 1, 128, 4, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 1 | HDMI_VIDEO_DMT, 0, 1, OUT_P888},
33 { { "1024x768p@60Hz", 60, 1024, 768, 65000000, 160, 24, 29, 3, 136, 6, 0, 0, 0 }, 2 | HDMI_VIDEO_DMT, 0, 1, OUT_P888},
34 { { "1280x960p@60Hz", 60, 1280, 960, 108000000, 312, 96, 36, 1, 112, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 3 | HDMI_VIDEO_DMT, 0, 1, OUT_P888},
35 { { "1280x1024p@60Hz", 60, 1280, 1024, 108000000, 248, 48, 38, 1, 112, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 4 | HDMI_VIDEO_DMT, 0, 1, OUT_P888},
36 { { "1360x768p@60Hz", 60, 1360, 768, 85500000, 256, 64, 18, 3, 112, 6, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 5 | HDMI_VIDEO_DMT, 0, 1, OUT_P888},
37 { { "1366x768p@60Hz", 60, 1366, 768, 85500000, 213, 70, 24, 3, 143, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 6 | HDMI_VIDEO_DMT, 0, 1, OUT_P888},
38 { { "1440x900p@60Hz", 60, 1440, 900, 106500000, 232, 80, 25, 3, 152, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 7 | HDMI_VIDEO_DMT, 0, 1, OUT_P888},
39 { { "1600x900p@60Hz", 60, 1600, 900, 108000000, 96, 24, 96, 1, 80, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 8 | HDMI_VIDEO_DMT, 0, 1, OUT_P888},
40 { { "1680x1050@60Hz", 60, 1680, 1050, 146250000, 280, 104, 30, 3, 176, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0 }, 9 | HDMI_VIDEO_DMT, 0, 1, OUT_P888},
43 static int hdmi_set_info(struct rk_screen *screen, struct hdmi *hdmi)
46 struct fb_videomode *mode;
48 if (screen == NULL || hdmi == NULL)
49 return HDMI_ERROR_FALSE;
52 hdmi->vic = hdmi->property->defaultmode;
54 if (hdmi->vic & HDMI_VIDEO_DMT)
57 vic = hdmi->vic & HDMI_VIC_MASK;
58 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
59 if (hdmi_mode[i].vic == vic ||
60 hdmi_mode[i].vic_2nd == vic)
63 if (i == ARRAY_SIZE(hdmi_mode))
64 return HDMI_ERROR_FALSE;
66 memset(screen, 0, sizeof(struct rk_screen));
68 /* screen type & face */
69 screen->type = SCREEN_HDMI;
70 if (hdmi->video.color_input == HDMI_COLOR_RGB_0_255)
71 screen->color_mode = COLOR_RGB;
73 screen->color_mode = COLOR_YCBCR;
74 if (hdmi->vic & HDMI_VIDEO_YUV420) {
75 if (hdmi->video.color_output_depth == 10)
76 screen->face = OUT_YUV_420_10BIT;
78 screen->face = OUT_YUV_420;
80 if (hdmi->video.color_output_depth == 10)
81 screen->face = OUT_P101010;
83 screen->face = hdmi_mode[i].interface;
85 screen->pixelrepeat = hdmi_mode[i].pixelrepeat - 1;
86 mode = (struct fb_videomode *)&(hdmi_mode[i].mode);
89 if (hdmi->video.format_3d == HDMI_3D_FRAME_PACKING) {
90 screen->mode.pixclock = 2 * mode->pixclock;
91 if (mode->vmode == 0) {
92 screen->mode.yres = 2 * mode->yres +
97 screen->mode.yres = 2 * mode->yres +
98 3 * (mode->upper_margin +
100 mode->vsync_len) + 2;
101 screen->mode.vmode = 0;
105 if (FB_SYNC_HOR_HIGH_ACT & mode->sync)
106 screen->pin_hsync = 1;
108 screen->pin_hsync = 0;
109 if (FB_SYNC_VERT_HIGH_ACT & mode->sync)
110 screen->pin_vsync = 1;
112 screen->pin_vsync = 0;
115 screen->pin_dclk = 1;
118 if (hdmi->soctype > HDMI_SOC_RK3288 &&
119 screen->color_mode > COLOR_RGB &&
120 (screen->face == OUT_P888 ||
121 screen->face == OUT_P101010))
127 screen->swap_delta = 0;
128 screen->swap_dumy = 0;
130 /* Operation function*/
132 screen->standby = NULL;
134 screen->overscan.left = hdmi->xscale;
135 screen->overscan.top = hdmi->yscale;
136 screen->overscan.right = hdmi->xscale;
137 screen->overscan.bottom = hdmi->yscale;
142 * hdmi_find_best_mode: find the video mode nearest to input vic
147 * If vic is zero, return the high resolution video mode vic.
149 int hdmi_find_best_mode(struct hdmi *hdmi, int vic)
151 struct list_head *pos, *head = &hdmi->edid.modelist;
152 struct display_modelist *modelist;
154 /* pr_info("%s vic %d\n", __FUNCTION__, vic); */
156 list_for_each(pos, head) {
159 struct display_modelist, list);
160 if (modelist->vic == vic) {
166 if ((vic == 0 || found == 0) && head->next != head) {
167 /* If parse edid error, we select default mode; */
168 if (hdmi->edid.specs == NULL ||
169 hdmi->edid.specs->modedb_len == 0)
170 return hdmi->property->defaultmode;
171 /*modelist = list_entry(head->prev,
172 struct display_modelist, list);*/
174 modelist = list_entry(head->next,
175 struct display_modelist, list);
178 if (modelist != NULL)
179 return modelist->vic;
184 * hdmi_set_lcdc: switch lcdc mode to required video mode
190 int hdmi_set_lcdc(struct hdmi *hdmi)
193 struct rk_screen screen;
195 rc = hdmi_set_info(&screen, hdmi);
198 rk_fb_switch_screen(&screen, 1, hdmi->lcdc->id);
199 /* if (rk_fb_get_display_policy() != DISPLAY_POLICY_BOX)
200 rk_fb_disp_scale(hdmi->xscale,
208 * hdmi_videomode_compare - compare 2 videomodes
209 * @mode1: first videomode
210 * @mode2: second videomode
213 * 1 if mode1 > mode2, 0 if mode1 = mode2, -1 mode1 < mode2
215 static int hdmi_videomode_compare(const struct fb_videomode *mode1,
216 const struct fb_videomode *mode2)
218 if (mode1->xres > mode2->xres)
221 if (mode1->xres == mode2->xres) {
222 if (mode1->yres > mode2->yres)
224 if (mode1->yres == mode2->yres) {
225 if (mode1->vmode < mode2->vmode)
227 if (mode1->pixclock > mode2->pixclock)
229 if (mode1->pixclock == mode2->pixclock) {
230 if (mode1->refresh > mode2->refresh)
232 if (mode1->refresh == mode2->refresh) {
233 if (mode2->flag > mode1->flag)
235 if (mode2->flag < mode1->flag)
237 if (mode2->vmode > mode1->vmode)
239 if (mode2->vmode == mode1->vmode)
249 * hdmi_add_vic - add entry to modelist according vic
250 * @vic: vic to be added
251 * @head: struct list_head of modelist
254 * Will only add unmatched mode entries
256 int hdmi_add_vic(int vic, struct list_head *head)
258 struct list_head *pos;
259 struct display_modelist *modelist;
262 /*pr_info("%s vic %d\n", __FUNCTION__, vic);*/
266 list_for_each(pos, head) {
267 modelist = list_entry(pos, struct display_modelist, list);
275 modelist = kmalloc(sizeof(*modelist),
280 memset(modelist, 0, sizeof(struct display_modelist));
282 list_add_tail(&modelist->list, head);
288 * hdmi_add_videomode: adds videomode entry to modelist
289 * @mode: videomode to be added
290 * @head: struct list_head of modelist
293 * Will only add unmatched mode entries
295 static int hdmi_add_videomode(const struct fb_videomode *mode,
296 struct list_head *head)
298 struct list_head *pos;
299 struct display_modelist *modelist, *modelist_new;
300 struct fb_videomode *m;
303 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
304 m = (struct fb_videomode *)&(hdmi_mode[i].mode);
305 if (fb_mode_is_equal(m, mode)) {
312 list_for_each(pos, head) {
313 modelist = list_entry(pos,
314 struct display_modelist, list);
316 if (fb_mode_is_equal(m, mode))
318 else if (hdmi_videomode_compare(m, mode) == -1)
322 modelist_new = kmalloc(sizeof(*modelist_new), GFP_KERNEL);
325 memset(modelist_new, 0, sizeof(struct display_modelist));
326 modelist_new->mode = hdmi_mode[i].mode;
327 modelist_new->vic = hdmi_mode[i].vic;
328 list_add_tail(&modelist_new->list, pos);
335 * hdmi_sort_modelist: sort modelist of edid
336 * @edid: edid to be sort
338 static void hdmi_sort_modelist(struct hdmi_edid *edid, int feature)
340 struct list_head *pos, *pos_new;
341 struct list_head head_new, *head = &edid->modelist;
342 struct display_modelist *modelist, *modelist_new, *modelist_n;
343 struct fb_videomode *m, *m_new;
346 INIT_LIST_HEAD(&head_new);
347 list_for_each(pos, head) {
348 modelist = list_entry(pos, struct display_modelist, list);
349 /*pr_info("%s vic %d\n", __function__, modelist->vic);*/
350 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
351 if (modelist->vic & HDMI_VIDEO_DMT) {
352 if (feature & SUPPORT_VESA_DMT)
357 vic = modelist->vic & HDMI_VIC_MASK;
359 if (vic == hdmi_mode[i].vic ||
360 vic == hdmi_mode[i].vic_2nd) {
361 if ((feature & SUPPORT_4K) == 0 &&
362 hdmi_mode[i].mode.xres >= 3840)
364 if ((feature & SUPPORT_4K_4096) == 0 &&
365 hdmi_mode[i].mode.xres == 4096)
367 if ((feature & SUPPORT_TMDS_600M) == 0 &&
368 !(modelist->vic & HDMI_VIDEO_YUV420) &&
369 hdmi_mode[i].mode.pixclock > 340000000)
371 if ((modelist->vic & HDMI_VIDEO_YUV420) &&
372 (feature & SUPPORT_YUV420) == 0)
374 if ((feature & SUPPORT_1080I) == 0 &&
375 hdmi_mode[i].mode.xres == 1920 &&
376 (hdmi_mode[i].mode.vmode &
377 FB_VMODE_INTERLACED))
379 if ((feature & SUPPORT_480I_576I) == 0 &&
380 hdmi_mode[i].mode.xres == 720 &&
381 hdmi_mode[i].mode.vmode &
385 modelist->vic = hdmi_mode[i].vic;
386 modelist->mode = hdmi_mode[i].mode;
387 if (vic & HDMI_VIDEO_YUV420) {
388 modelist->vic |= HDMI_VIDEO_YUV420;
389 modelist->mode.flag = 1;
392 m = (struct fb_videomode *)&(modelist->mode);
393 list_for_each(pos_new, &head_new) {
396 struct display_modelist,
398 m_new = &modelist_new->mode;
400 hdmi_videomode_compare(m, m_new);
406 kmalloc(sizeof(*modelist_n),
410 *modelist_n = *modelist;
411 list_add_tail(&modelist_n->list,
418 fb_destroy_modelist(head);
419 if (head_new.next == &head_new) {
420 pr_info("There is no available video mode in EDID.\n");
421 INIT_LIST_HEAD(&edid->modelist);
423 edid->modelist = head_new;
424 edid->modelist.prev->next = &edid->modelist;
425 edid->modelist.next->prev = &edid->modelist;
430 * hdmi_ouputmode_select - select hdmi transmitter output mode: hdmi or dvi?
431 * @hdmi: handle of hdmi
432 * @edid_ok: get EDID data success or not, HDMI_ERROR_SUCESS means success.
434 int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
436 struct list_head *head = &hdmi->edid.modelist;
437 struct fb_monspecs *specs = hdmi->edid.specs;
438 struct fb_videomode *modedb = NULL, *mode = NULL;
439 int i, pixclock, feature = hdmi->property->feature;
441 if (edid_ok != HDMI_ERROR_SUCESS) {
442 dev_err(hdmi->dev, "warning: EDID error, assume sink as HDMI !!!!");
443 hdmi->edid.status = -1;
444 hdmi->edid.sink_hdmi = 1;
445 hdmi->edid.baseaudio_support = 1;
446 hdmi->edid.ycbcr444 = 0;
447 hdmi->edid.ycbcr422 = 0;
450 if (head->next == head) {
452 "warning: no CEA video mode parsed from EDID !!!!\n");
453 /* If EDID get error, list all system supported mode.
454 If output mode is set to DVI and EDID is ok, check
457 if (hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) {
458 /* Get max resolution timing */
459 modedb = &specs->modedb[0];
460 for (i = 0; i < specs->modedb_len; i++) {
461 if (specs->modedb[i].xres > modedb->xres)
462 modedb = &specs->modedb[i];
463 else if (specs->modedb[i].xres ==
465 specs->modedb[i].yres > modedb->yres)
466 modedb = &specs->modedb[i];
468 /* For some monitor, the max pixclock read from EDID
469 is smaller than the clock of max resolution mode
470 supported. We fix it. */
471 pixclock = PICOS2KHZ(modedb->pixclock);
475 if (pixclock == 148250000)
476 pixclock = 148500000;
477 if (pixclock > specs->dclkmax)
478 specs->dclkmax = pixclock;
481 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
482 mode = (struct fb_videomode *)&(hdmi_mode[i].mode);
484 if ((mode->pixclock < specs->dclkmin) ||
485 (mode->pixclock > specs->dclkmax) ||
486 (mode->refresh < specs->vfmin) ||
487 (mode->refresh > specs->vfmax) ||
488 (mode->xres > modedb->xres) ||
489 (mode->yres > modedb->yres))
492 /* If there is no valid information in EDID,
493 just list common hdmi foramt. */
494 if (mode->xres > 3840 ||
495 mode->refresh < 50 ||
496 (mode->vmode & FB_VMODE_INTERLACED) ||
497 hdmi_mode[i].vic & HDMI_VIDEO_DMT)
500 if ((feature & SUPPORT_TMDS_600M) == 0 &&
501 mode->pixclock > 340000000)
503 if ((feature & SUPPORT_4K) == 0 &&
506 if ((feature & SUPPORT_4K_4096) == 0 &&
509 if ((feature & SUPPORT_1080I) == 0 &&
510 mode->xres == 1920 &&
511 (mode->vmode & FB_VMODE_INTERLACED))
513 if ((feature & SUPPORT_480I_576I) == 0 &&
515 (mode->vmode & FB_VMODE_INTERLACED))
517 hdmi_add_videomode(mode, head);
520 /* There are some video mode is not defined in EDID extend
521 block, so we need to check first block data.*/
522 if (specs && specs->modedb_len) {
523 for (i = 0; i < specs->modedb_len; i++) {
524 modedb = &specs->modedb[i];
525 pixclock = hdmi_videomode_to_vic(modedb);
527 hdmi_add_vic(pixclock, head);
530 hdmi_sort_modelist(&hdmi->edid, hdmi->property->feature);
533 return HDMI_ERROR_SUCESS;
537 * hdmi_videomode_to_vic: transverse video mode to vic
538 * @vmode: videomode to transverse
541 int hdmi_videomode_to_vic(struct fb_videomode *vmode)
543 struct fb_videomode *mode;
544 unsigned int vic = 0;
547 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
548 mode = (struct fb_videomode *)&(hdmi_mode[i].mode);
549 if (vmode->vmode == mode->vmode &&
550 vmode->refresh == mode->refresh &&
551 vmode->xres == mode->xres &&
552 vmode->yres == mode->yres &&
553 vmode->left_margin == mode->left_margin &&
554 vmode->right_margin == mode->right_margin &&
555 vmode->upper_margin == mode->upper_margin &&
556 vmode->lower_margin == mode->lower_margin &&
557 vmode->hsync_len == mode->hsync_len &&
558 vmode->vsync_len == mode->vsync_len) {
559 vic = hdmi_mode[i].vic;
567 * hdmi_vic2timing: transverse vic mode to video timing
568 * @vmode: vic to transverse
571 const struct hdmi_video_timing *hdmi_vic2timing(int vic)
578 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
579 if (hdmi_mode[i].vic == vic || hdmi_mode[i].vic_2nd == vic)
580 return &(hdmi_mode[i]);
586 * hdmi_vic_to_videomode: transverse vic mode to video mode
587 * @vmode: vic to transverse
590 const struct fb_videomode *hdmi_vic_to_videomode(int vic)
596 else if (vic & HDMI_VIDEO_DMT)
599 vid = vic & HDMI_VIC_MASK;
600 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
601 if (hdmi_mode[i].vic == vid ||
602 hdmi_mode[i].vic_2nd == vid)
603 return &hdmi_mode[i].mode;
609 * hdmi_init_modelist: initial hdmi mode list
615 void hdmi_init_modelist(struct hdmi *hdmi)
618 struct list_head *head = &hdmi->edid.modelist;
620 feature = hdmi->property->feature;
621 INIT_LIST_HEAD(&hdmi->edid.modelist);
622 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
623 if (hdmi_mode[i].vic & HDMI_VIDEO_DMT)
625 if ((feature & SUPPORT_TMDS_600M) == 0 &&
626 hdmi_mode[i].mode.pixclock > 340000000)
628 if ((feature & SUPPORT_4K) == 0 &&
629 hdmi_mode[i].mode.xres >= 3840)
631 if ((feature & SUPPORT_4K_4096) == 0 &&
632 hdmi_mode[i].mode.xres == 4096)
634 if ((feature & SUPPORT_1080I) == 0 &&
635 hdmi_mode[i].mode.xres == 1920 &&
636 (hdmi_mode[i].mode.vmode & FB_VMODE_INTERLACED))
638 if ((feature & SUPPORT_480I_576I) == 0 &&
639 hdmi_mode[i].mode.xres == 720 &&
640 (hdmi_mode[i].mode.vmode & FB_VMODE_INTERLACED))
642 hdmi_add_videomode(&(hdmi_mode[i].mode), head);