1 #include "rockchip-hdmi.h"
3 static const struct hdmi_video_timing hdmi_mode[] = {
6 .name = "720x480i@60Hz",
18 .vmode = FB_VMODE_INTERLACED,
21 .vic = HDMI_720X480I_60HZ_4_3,
22 .vic_2nd = HDMI_720X480I_60HZ_16_9,
24 .interface = OUT_P888,
28 .name = "720x576i@50Hz",
40 .vmode = FB_VMODE_INTERLACED,
43 .vic = HDMI_720X576I_50HZ_4_3,
44 .vic_2nd = HDMI_720X576I_50HZ_16_9,
46 .interface = OUT_P888,
50 .name = "720x480p@60Hz",
65 .vic = HDMI_720X480P_60HZ_4_3,
66 .vic_2nd = HDMI_720X480P_60HZ_16_9,
68 .interface = OUT_P888,
72 .name = "720x576p@50Hz",
87 .vic = HDMI_720X576P_50HZ_4_3,
88 .vic_2nd = HDMI_720X576P_50HZ_16_9,
90 .interface = OUT_P888,
94 .name = "1280x720p@24Hz",
100 .right_margin = 1760,
105 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
109 .vic = HDMI_1280X720P_24HZ,
110 .vic_2nd = HDMI_1280X720P_24HZ_21_9,
112 .interface = OUT_P888,
116 .name = "1280x720p@25Hz",
120 .pixclock = 74250000,
122 .right_margin = 2420,
127 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
131 .vic = HDMI_1280X720P_25HZ,
132 .vic_2nd = HDMI_1280X720P_25HZ_21_9,
134 .interface = OUT_P888,
138 .name = "1280x720p@30Hz",
142 .pixclock = 74250000,
144 .right_margin = 1760,
149 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
153 .vic = HDMI_1280X720P_30HZ,
154 .vic_2nd = HDMI_1280X720P_30HZ_21_9,
156 .interface = OUT_P888,
160 .name = "1280x720p@50Hz",
164 .pixclock = 74250000,
171 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
175 .vic = HDMI_1280X720P_50HZ,
176 .vic_2nd = HDMI_1280X720P_50HZ_21_9,
178 .interface = OUT_P888,
182 .name = "1280x720p@60Hz",
186 .pixclock = 74250000,
193 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
197 .vic = HDMI_1280X720P_60HZ,
198 .vic_2nd = HDMI_1280X720P_60HZ_21_9,
200 .interface = OUT_P888,
204 .name = "1920x1080i@50Hz",
208 .pixclock = 74250000,
215 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
216 .vmode = FB_VMODE_INTERLACED,
219 .vic = HDMI_1920X1080I_50HZ,
222 .interface = OUT_P888,
226 .name = "1920x1080i@60Hz",
230 .pixclock = 74250000,
237 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
238 .vmode = FB_VMODE_INTERLACED,
241 .vic = HDMI_1920X1080I_60HZ,
244 .interface = OUT_P888,
248 .name = "1920x1080p@24Hz",
252 .pixclock = 74250000,
259 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
263 .vic = HDMI_1920X1080P_24HZ,
264 .vic_2nd = HDMI_1920X1080P_24HZ_21_9,
266 .interface = OUT_P888,
270 .name = "1920x1080p@25Hz",
274 .pixclock = 74250000,
281 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
285 .vic = HDMI_1920X1080P_25HZ,
286 .vic_2nd = HDMI_1920X1080P_25HZ_21_9,
288 .interface = OUT_P888,
292 .name = "1920x1080p@30Hz",
296 .pixclock = 74250000,
303 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
307 .vic = HDMI_1920X1080P_30HZ,
308 .vic_2nd = HDMI_1920X1080P_30HZ_21_9,
310 .interface = OUT_P888,
314 .name = "1920x1080p@50Hz",
318 .pixclock = 148500000,
325 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
329 .vic = HDMI_1920X1080P_50HZ,
330 .vic_2nd = HDMI_1920X1080P_50HZ_21_9,
332 .interface = OUT_P888,
336 .name = "1920x1080p@60Hz",
340 .pixclock = 148500000,
347 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
351 .vic = HDMI_1920X1080P_60HZ,
352 .vic_2nd = HDMI_1920X1080P_60HZ_21_9,
354 .interface = OUT_P888,
358 .name = "3840x2160p@24Hz",
362 .pixclock = 297000000,
364 .right_margin = 1276,
369 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
373 .vic = HDMI_3840X2160P_24HZ,
374 .vic_2nd = HDMI_3840X2160P_24HZ_21_9,
376 .interface = OUT_P888,
380 .name = "3840x2160p@25Hz",
384 .pixclock = 297000000,
386 .right_margin = 1056,
391 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
395 .vic = HDMI_3840X2160P_25HZ,
396 .vic_2nd = HDMI_3840X2160P_25HZ_21_9,
398 .interface = OUT_P888,
402 .name = "3840x2160p@30Hz",
406 .pixclock = 297000000,
413 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
417 .vic = HDMI_3840X2160P_30HZ,
418 .vic_2nd = HDMI_3840X2160P_30HZ_21_9,
420 .interface = OUT_P888,
424 .name = "4096x2160p@24Hz",
428 .pixclock = 297000000,
430 .right_margin = 1020,
435 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
439 .vic = HDMI_4096X2160P_24HZ,
442 .interface = OUT_P888,
446 .name = "4096x2160p@25Hz",
450 .pixclock = 297000000,
457 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
461 .vic = HDMI_4096X2160P_25HZ,
464 .interface = OUT_P888,
468 .name = "4096x2160p@30Hz",
472 .pixclock = 297000000,
479 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
483 .vic = HDMI_4096X2160P_30HZ,
486 .interface = OUT_P888,
490 .name = "3840x2160p@50Hz",
494 .pixclock = 594000000,
496 .right_margin = 1056,
501 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
505 .vic = HDMI_3840X2160P_50HZ,
506 .vic_2nd = HDMI_3840X2160P_50HZ_21_9,
508 .interface = OUT_P888,
512 .name = "3840x2160p@60Hz",
516 .pixclock = 594000000,
523 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
527 .vic = HDMI_3840X2160P_60HZ,
528 .vic_2nd = HDMI_3840X2160P_60HZ_21_9,
530 .interface = OUT_P888,
534 .name = "4096x2160p@50Hz",
538 .pixclock = 594000000,
545 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
549 .vic = HDMI_4096X2160P_50HZ,
552 .interface = OUT_P888,
556 .name = "4096x2160p@60Hz",
560 .pixclock = 594000000,
567 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
571 .vic = HDMI_4096X2160P_60HZ,
574 .interface = OUT_P888,
578 .name = "800x600p@60Hz",
582 .pixclock = 40000000,
589 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
593 .vic = HDMI_VIDEO_DMT | 1,
596 .interface = OUT_P888,
600 .name = "1024x768p@60Hz",
604 .pixclock = 65000000,
615 .vic = HDMI_VIDEO_DMT | 2,
618 .interface = OUT_P888,
622 .name = "1280x960p@60Hz",
626 .pixclock = 108000000,
633 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
637 .vic = HDMI_VIDEO_DMT | 3,
640 .interface = OUT_P888,
644 .name = "1280x1024p@60Hz",
648 .pixclock = 108000000,
655 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
659 .vic = HDMI_VIDEO_DMT | 4,
662 .interface = OUT_P888,
666 .name = "1360x768p@60Hz",
670 .pixclock = 85500000,
677 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
681 .vic = HDMI_VIDEO_DMT | 5,
684 .interface = OUT_P888,
688 .name = "1366x768p@60Hz",
692 .pixclock = 85500000,
699 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
703 .vic = HDMI_VIDEO_DMT | 6,
706 .interface = OUT_P888,
710 .name = "1440x900p@60Hz",
714 .pixclock = 106500000,
721 .sync = FB_SYNC_VERT_HIGH_ACT,
725 .vic = HDMI_VIDEO_DMT | 7,
728 .interface = OUT_P888,
732 .name = "1600x900p@60Hz",
736 .pixclock = 108000000,
743 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
747 .vic = HDMI_VIDEO_DMT | 8,
750 .interface = OUT_P888,
754 .name = "1680x1050@60Hz",
758 .pixclock = 146250000,
765 .sync = FB_SYNC_VERT_HIGH_ACT,
769 .vic = HDMI_VIDEO_DMT | 9,
772 .interface = OUT_P888,
776 .name = "1440x1280@60Hz",
780 .pixclock = 148500000,
791 .vic = HDMI_VIDEO_DISCRETE_VR | 1,
794 .interface = OUT_P888,
799 .name = "2160x1200@75Hz",
803 .pixclock = 245000000,
814 .vic = HDMI_VIDEO_DISCRETE_VR | 3,
817 .interface = OUT_P888,
822 .name = "2880x1440@75Hz",
826 .pixclock = 340000000,
837 .vic = HDMI_VIDEO_DISCRETE_VR | 4,
840 .interface = OUT_P888,
845 .name = "1440x2560@60Hz",
849 .pixclock = 268500000,
860 .vic = HDMI_VIDEO_DISCRETE_VR | 5,
863 .interface = OUT_P888,
868 .name = "1440x2560@70Hz",
872 .pixclock = 285000000,
883 .vic = HDMI_VIDEO_DISCRETE_VR | 6,
886 .interface = OUT_P888,
890 static int hdmi_set_info(struct rk_screen *screen, struct hdmi *hdmi)
892 int i, vic, colorimetry;
893 struct fb_videomode *mode;
895 if (!screen || !hdmi)
896 return HDMI_ERROR_FALSE;
899 hdmi->vic = hdmi->property->defaultmode;
901 if (hdmi->edid_auto_support) {
902 if ((hdmi->vic & HDMI_VIDEO_DMT) ||
903 (hdmi->vic & HDMI_VIDEO_DISCRETE_VR)) {
904 if (hdmi->prop.value.vic)
905 vic = hdmi->prop.value.vic;
909 vic = hdmi->vic & HDMI_VIC_MASK;
912 if ((hdmi->vic & HDMI_VIDEO_DMT) ||
913 (hdmi->vic & HDMI_VIDEO_DISCRETE_VR))
916 vic = hdmi->vic & HDMI_VIC_MASK;
919 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
920 if (hdmi_mode[i].vic == vic ||
921 hdmi_mode[i].vic_2nd == vic)
924 if (i == ARRAY_SIZE(hdmi_mode))
925 return HDMI_ERROR_FALSE;
927 memset(screen, 0, sizeof(struct rk_screen));
929 /* screen type & face */
930 screen->type = SCREEN_HDMI;
931 colorimetry = hdmi->video.colorimetry;
932 mode = (struct fb_videomode *)&hdmi_mode[i].mode;
933 if (hdmi->video.color_input == HDMI_COLOR_RGB_0_255) {
934 screen->color_mode = COLOR_RGB;
935 } else if (mode->xres >= 3840 &&
936 mode->yres >= 2160 &&
937 colorimetry > HDMI_COLORIMETRY_EXTEND_ADOBE_RGB) {
938 screen->color_mode = COLOR_YCBCR_BT2020;
939 if (hdmi->video.eotf == EOTF_ST_2084)
940 screen->data_space = 1;
941 } else if (colorimetry == HDMI_COLORIMETRY_NO_DATA) {
942 if (mode->xres > 720 && mode->yres > 576)
943 screen->color_mode = COLOR_YCBCR_BT709;
945 screen->color_mode = COLOR_YCBCR;
946 } else if (colorimetry == HDMI_COLORIMETRY_SMTPE_170M) {
947 screen->color_mode = COLOR_YCBCR;
949 screen->color_mode = COLOR_YCBCR_BT709;
952 if (hdmi->vic & HDMI_VIDEO_YUV420) {
953 if (hdmi->video.color_output_depth == 10)
954 screen->face = OUT_YUV_420_10BIT;
956 screen->face = OUT_YUV_420;
958 if (hdmi->video.color_output_depth == 10)
959 screen->face = OUT_P101010;
961 screen->face = hdmi_mode[i].interface;
963 screen->pixelrepeat = hdmi_mode[i].pixelrepeat - 1;
964 screen->mode = *mode;
965 if (hdmi->video.format_3d == HDMI_3D_FRAME_PACKING) {
966 screen->mode.pixclock = 2 * mode->pixclock;
967 if (mode->vmode == 0) {
968 screen->mode.yres = 2 * mode->yres +
973 screen->mode.yres = 2 * mode->yres +
974 3 * (mode->upper_margin +
976 mode->vsync_len) + 2;
977 screen->mode.vmode = 0;
981 if (FB_SYNC_HOR_HIGH_ACT & mode->sync)
982 screen->pin_hsync = 1;
984 screen->pin_hsync = 0;
985 if (FB_SYNC_VERT_HIGH_ACT & mode->sync)
986 screen->pin_vsync = 1;
988 screen->pin_vsync = 0;
991 screen->pin_dclk = 1;
994 if (hdmi->soctype > HDMI_SOC_RK312X &&
995 screen->color_mode > COLOR_RGB &&
996 (screen->face == OUT_P888 ||
997 screen->face == OUT_P101010))
1000 screen->swap_rb = 0;
1001 screen->swap_rg = 0;
1002 screen->swap_gb = 0;
1003 screen->swap_delta = 0;
1004 screen->swap_dumy = 0;
1006 /* Operation function*/
1007 screen->init = NULL;
1008 screen->standby = NULL;
1010 screen->overscan.left = hdmi->xscale;
1011 screen->overscan.top = hdmi->yscale;
1012 screen->overscan.right = hdmi->xscale;
1013 screen->overscan.bottom = hdmi->yscale;
1015 screen->width = hdmi->prop.value.width;
1016 screen->height = hdmi->prop.value.height;
1017 pr_info("%s:line=%d %d %d %d %d %d %d %d %d\n",
1018 __func__, __LINE__, screen->mode.xres, screen->mode.yres,
1019 screen->mode.left_margin, screen->mode.right_margin,
1020 screen->mode.upper_margin, screen->mode.lower_margin,
1021 screen->mode.hsync_len, screen->mode.vsync_len);
1027 * hdmi_find_best_mode: find the video mode nearest to input vic
1032 * If vic is zero, return the high resolution video mode vic.
1034 int hdmi_find_best_mode(struct hdmi *hdmi, int vic)
1036 struct list_head *pos, *head = &hdmi->edid.modelist;
1037 struct display_modelist *modelist = NULL;
1041 list_for_each(pos, head) {
1044 struct display_modelist, list);
1045 if (modelist->vic == vic) {
1051 if ((!vic || !found) && head->next != head) {
1052 /* If parse edid error, we select default mode; */
1053 if (hdmi->edid.specs &&
1054 hdmi->edid.specs->modedb_len)
1055 modelist = list_entry(head->next,
1056 struct display_modelist, list);
1058 return hdmi->property->defaultmode;
1062 return modelist->vic;
1068 * hdmi_set_lcdc: switch lcdc mode to required video mode
1074 int hdmi_set_lcdc(struct hdmi *hdmi)
1077 struct rk_screen screen;
1079 rc = hdmi_set_info(&screen, hdmi);
1081 rk_fb_switch_screen(&screen, 1, hdmi->lcdc->id);
1086 * hdmi_videomode_compare - compare 2 videomodes
1087 * @mode1: first videomode
1088 * @mode2: second videomode
1091 * 1 if mode1 > mode2, 0 if mode1 = mode2, -1 mode1 < mode2
1093 static int hdmi_videomode_compare(const struct fb_videomode *mode1,
1094 const struct fb_videomode *mode2)
1096 if (mode1->xres > mode2->xres)
1099 if (mode1->xres == mode2->xres) {
1100 if (mode1->yres > mode2->yres)
1102 if (mode1->yres == mode2->yres) {
1103 if (mode1->vmode < mode2->vmode)
1105 if (mode1->pixclock > mode2->pixclock)
1107 if (mode1->pixclock == mode2->pixclock) {
1108 if (mode1->refresh > mode2->refresh)
1110 if (mode1->refresh == mode2->refresh) {
1111 if (mode2->flag > mode1->flag)
1113 if (mode2->flag < mode1->flag)
1115 if (mode2->vmode > mode1->vmode)
1117 if (mode2->vmode == mode1->vmode)
1127 * hdmi_add_vic - add entry to modelist according vic
1128 * @vic: vic to be added
1129 * @head: struct list_head of modelist
1132 * Will only add unmatched mode entries
1134 int hdmi_add_vic(int vic, struct list_head *head)
1136 struct list_head *pos;
1137 struct display_modelist *modelist;
1140 /*pr_info("%s vic %d\n", __FUNCTION__, vic);*/
1144 if (vic & HDMI_VIDEO_YUV420) {
1146 if (v != HDMI_3840X2160P_50HZ &&
1147 v != HDMI_3840X2160P_60HZ &&
1148 v != HDMI_4096X2160P_50HZ &&
1149 v != HDMI_4096X2160P_60HZ &&
1150 v != HDMI_3840X2160P_50HZ_21_9 &&
1151 v != HDMI_3840X2160P_60HZ_21_9) {
1156 list_for_each(pos, head) {
1157 modelist = list_entry(pos, struct display_modelist, list);
1165 modelist = kmalloc(sizeof(*modelist),
1170 memset(modelist, 0, sizeof(struct display_modelist));
1171 modelist->vic = vic;
1172 list_add_tail(&modelist->list, head);
1178 * hdmi_add_videomode: adds videomode entry to modelist
1179 * @mode: videomode to be added
1180 * @head: struct list_head of modelist
1183 * Will only add unmatched mode entries
1185 static int hdmi_add_videomode(const struct fb_videomode *mode,
1186 struct list_head *head)
1188 struct list_head *pos;
1189 struct display_modelist *modelist, *modelist_new;
1190 struct fb_videomode *m;
1193 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
1194 m = (struct fb_videomode *)&hdmi_mode[i].mode;
1195 if (fb_mode_is_equal(m, mode)) {
1202 list_for_each(pos, head) {
1203 modelist = list_entry(pos,
1204 struct display_modelist, list);
1205 m = &modelist->mode;
1206 if (fb_mode_is_equal(m, mode))
1208 else if (hdmi_videomode_compare(m, mode) == -1)
1212 modelist_new = kmalloc(sizeof(*modelist_new), GFP_KERNEL);
1215 memset(modelist_new, 0, sizeof(struct display_modelist));
1216 modelist_new->mode = hdmi_mode[i].mode;
1217 modelist_new->vic = hdmi_mode[i].vic;
1218 list_add_tail(&modelist_new->list, pos);
1225 * hdmi_sort_modelist: sort modelist of edid
1226 * @edid: edid to be sort
1228 static void hdmi_sort_modelist(struct hdmi_edid *edid, int feature)
1230 struct list_head *pos, *pos_new;
1231 struct list_head head_new, *head = &edid->modelist;
1232 struct display_modelist *modelist, *modelist_new, *modelist_n;
1233 struct fb_videomode *m, *m_new;
1234 int i, compare, vic;
1236 INIT_LIST_HEAD(&head_new);
1237 list_for_each(pos, head) {
1238 modelist = list_entry(pos, struct display_modelist, list);
1239 /*pr_info("%s vic %d\n", __function__, modelist->vic);*/
1240 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
1241 if ((modelist->vic & HDMI_VIDEO_DMT) || (modelist->vic & HDMI_VIDEO_DISCRETE_VR)) {
1242 if (feature & (SUPPORT_VESA_DMT | SUPPORT_RK_DISCRETE_VR))
1243 vic = modelist->vic;
1247 vic = modelist->vic & HDMI_VIC_MASK;
1249 if (vic == hdmi_mode[i].vic ||
1250 vic == hdmi_mode[i].vic_2nd) {
1251 if ((feature & SUPPORT_4K) == 0 &&
1252 hdmi_mode[i].mode.xres >= 3840)
1254 if ((feature & SUPPORT_4K_4096) == 0 &&
1255 hdmi_mode[i].mode.xres == 4096)
1257 if ((feature & SUPPORT_TMDS_600M) == 0 &&
1258 !(modelist->vic & HDMI_VIDEO_YUV420) &&
1259 hdmi_mode[i].mode.pixclock > 340000000)
1261 if ((modelist->vic & HDMI_VIDEO_YUV420) &&
1262 (feature & SUPPORT_YUV420) == 0)
1264 if ((feature & SUPPORT_1080I) == 0 &&
1265 hdmi_mode[i].mode.xres == 1920 &&
1266 (hdmi_mode[i].mode.vmode &
1267 FB_VMODE_INTERLACED))
1269 if ((feature & SUPPORT_480I_576I) == 0 &&
1270 hdmi_mode[i].mode.xres == 720 &&
1271 hdmi_mode[i].mode.vmode &
1272 FB_VMODE_INTERLACED)
1274 modelist->mode = hdmi_mode[i].mode;
1275 if (modelist->vic & HDMI_VIDEO_YUV420)
1276 modelist->mode.flag = 1;
1279 m = (struct fb_videomode *)&modelist->mode;
1280 list_for_each(pos_new, &head_new) {
1283 struct display_modelist,
1285 m_new = &modelist_new->mode;
1287 hdmi_videomode_compare(m, m_new);
1293 kmalloc(sizeof(*modelist_n),
1297 *modelist_n = *modelist;
1298 list_add_tail(&modelist_n->list,
1305 fb_destroy_modelist(head);
1306 if (head_new.next == &head_new) {
1307 pr_info("There is no available video mode in EDID.\n");
1308 INIT_LIST_HEAD(&edid->modelist);
1310 edid->modelist = head_new;
1311 edid->modelist.prev->next = &edid->modelist;
1312 edid->modelist.next->prev = &edid->modelist;
1316 static int edid_select_prop_value(struct hdmi *hdmi)
1318 struct edid_prop_value *prop_value = NULL;
1320 int i, vid, pid, sn, xres, yres, reboot = 0;
1322 prop_value = hdmi->pvalue;
1323 nstates = hdmi->nstates;
1326 pr_info("%s:pvalue is NULL\n", __func__);
1330 vid = hdmi->edid.value.vid;
1331 pid = hdmi->edid.value.pid;
1332 sn = hdmi->edid.value.sn;
1333 xres = hdmi->edid.value.xres;
1334 yres = hdmi->edid.value.yres;
1336 for (i = 0; i < nstates; i++) {
1337 if ((prop_value[i].vid == vid) &&
1338 (prop_value[i].pid == pid) &&
1339 (prop_value[i].sn == sn) &&
1340 (prop_value[i].xres == xres) &&
1341 (prop_value[i].yres == yres)) {
1342 hdmi->edid.value = prop_value[i];
1343 hdmi->prop.value = prop_value[i];
1344 if ((hdmi->prop.valid) &&
1345 ((hdmi->prop.last_vid != vid) ||
1346 (hdmi->prop.last_pid != pid) ||
1347 (hdmi->prop.last_sn != sn) ||
1348 (hdmi->prop.last_xres != xres) ||
1349 (hdmi->prop.last_yres != yres))) {
1355 hdmi->prop.last_vid = vid;
1356 hdmi->prop.last_pid = pid;
1357 hdmi->prop.last_sn = sn;
1358 hdmi->prop.last_xres = xres;
1359 hdmi->prop.last_yres = yres;
1360 hdmi->prop.valid = 1;
1361 pr_info("%s:i=%d reboot=%d,valid=%d\n",
1362 __func__, i, reboot, hdmi->prop.valid);
1369 dev_info(hdmi->dev, "%s:kernel_restart\n", __func__);
1370 kernel_restart(NULL);
1377 * hdmi_ouputmode_select - select hdmi transmitter output mode: hdmi or dvi?
1378 * @hdmi: handle of hdmi
1379 * @edid_ok: get EDID data success or not, HDMI_ERROR_SUCCESS means success.
1381 int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
1383 struct list_head *head = &hdmi->edid.modelist;
1384 struct fb_monspecs *specs = hdmi->edid.specs;
1385 struct fb_videomode *modedb = NULL, *mode = NULL;
1386 int i, pixclock, feature = hdmi->property->feature;
1388 if (edid_ok != HDMI_ERROR_SUCCESS) {
1389 dev_err(hdmi->dev, "warning: EDID error, assume sink as HDMI !!!!");
1390 hdmi->edid.status = -1;
1391 hdmi->edid.sink_hdmi = 1;
1392 hdmi->edid.baseaudio_support = 1;
1393 hdmi->edid.ycbcr444 = 0;
1394 hdmi->edid.ycbcr422 = 0;
1397 if (hdmi->edid_auto_support)
1398 edid_select_prop_value(hdmi);
1400 if (head->next == head) {
1402 "warning: no CEA video mode parsed from EDID !!!!\n");
1403 /* If EDID get error, list all system supported mode.
1404 * If output mode is set to DVI and EDID is ok, check
1405 * the output timing.
1407 if (hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) {
1408 /* Get max resolution timing */
1409 modedb = &specs->modedb[0];
1410 for (i = 0; i < specs->modedb_len; i++) {
1411 if (specs->modedb[i].xres > modedb->xres)
1412 modedb = &specs->modedb[i];
1413 else if (specs->modedb[i].xres ==
1415 specs->modedb[i].yres > modedb->yres)
1416 modedb = &specs->modedb[i];
1418 /* For some monitor, the max pixclock read from EDID
1419 * is smaller than the clock of max resolution mode
1420 * supported. We fix it.
1422 pixclock = PICOS2KHZ(modedb->pixclock);
1426 if (pixclock == 148250000)
1427 pixclock = 148500000;
1428 if (pixclock > specs->dclkmax)
1429 specs->dclkmax = pixclock;
1432 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
1433 mode = (struct fb_videomode *)&hdmi_mode[i].mode;
1435 if ((mode->pixclock < specs->dclkmin) ||
1436 (mode->pixclock > specs->dclkmax) ||
1437 (mode->refresh < specs->vfmin) ||
1438 (mode->refresh > specs->vfmax) ||
1439 (mode->xres > modedb->xres) ||
1440 (mode->yres > modedb->yres))
1443 /* If there is no valid information in EDID,
1444 * just list common hdmi foramt.
1446 if (mode->xres > 3840 ||
1447 mode->refresh < 50 ||
1448 (mode->vmode & FB_VMODE_INTERLACED) ||
1449 hdmi_mode[i].vic & HDMI_VIDEO_DMT ||
1450 hdmi_mode[i].vic & HDMI_VIDEO_DISCRETE_VR)
1453 if ((feature & SUPPORT_TMDS_600M) == 0 &&
1454 mode->pixclock > 340000000)
1456 if ((feature & SUPPORT_4K) == 0 &&
1459 if ((feature & SUPPORT_4K_4096) == 0 &&
1462 if ((feature & SUPPORT_1080I) == 0 &&
1463 mode->xres == 1920 &&
1464 (mode->vmode & FB_VMODE_INTERLACED))
1466 if ((feature & SUPPORT_480I_576I) == 0 &&
1467 mode->xres == 720 &&
1468 (mode->vmode & FB_VMODE_INTERLACED))
1470 hdmi_add_videomode(mode, head);
1473 /* There are some video mode is not defined in EDID extend
1474 * block, so we need to check first block data.
1476 if (specs && specs->modedb_len) {
1477 for (i = 0; i < specs->modedb_len; i++) {
1478 modedb = &specs->modedb[i];
1479 pixclock = hdmi_videomode_to_vic(modedb);
1481 hdmi_add_vic(pixclock, head);
1484 hdmi_sort_modelist(&hdmi->edid, hdmi->property->feature);
1487 return HDMI_ERROR_SUCCESS;
1491 * hdmi_videomode_to_vic: transverse video mode to vic
1492 * @vmode: videomode to transverse
1495 int hdmi_videomode_to_vic(struct fb_videomode *vmode)
1497 struct fb_videomode *mode;
1498 unsigned int vic = 0;
1501 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
1502 mode = (struct fb_videomode *)&hdmi_mode[i].mode;
1503 if (vmode->vmode == mode->vmode &&
1504 vmode->refresh == mode->refresh &&
1505 vmode->xres == mode->xres &&
1506 vmode->yres == mode->yres &&
1507 vmode->left_margin == mode->left_margin &&
1508 vmode->right_margin == mode->right_margin &&
1509 vmode->upper_margin == mode->upper_margin &&
1510 vmode->lower_margin == mode->lower_margin &&
1511 vmode->hsync_len == mode->hsync_len &&
1512 vmode->vsync_len == mode->vsync_len) {
1513 vic = hdmi_mode[i].vic;
1521 * hdmi_vic2timing: transverse vic mode to video timing
1522 * @vmode: vic to transverse
1525 const struct hdmi_video_timing *hdmi_vic2timing(int vic)
1532 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
1533 if (hdmi_mode[i].vic == vic || hdmi_mode[i].vic_2nd == vic)
1534 return &hdmi_mode[i];
1540 * hdmi_vic_to_videomode: transverse vic mode to video mode
1541 * @vmode: vic to transverse
1544 const struct fb_videomode *hdmi_vic_to_videomode(int vic)
1550 else if ((vic & HDMI_VIDEO_DMT) || (vic & HDMI_VIDEO_DISCRETE_VR))
1553 vid = vic & HDMI_VIC_MASK;
1554 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
1555 if (hdmi_mode[i].vic == vid ||
1556 hdmi_mode[i].vic_2nd == vid)
1557 return &hdmi_mode[i].mode;
1563 * hdmi_init_modelist: initial hdmi mode list
1569 void hdmi_init_modelist(struct hdmi *hdmi)
1572 struct list_head *head = &hdmi->edid.modelist;
1574 feature = hdmi->property->feature;
1575 INIT_LIST_HEAD(&hdmi->edid.modelist);
1576 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
1577 if ((hdmi_mode[i].vic & HDMI_VIDEO_DMT) || (hdmi_mode[i].vic & HDMI_VIDEO_DISCRETE_VR))
1579 if ((feature & SUPPORT_TMDS_600M) == 0 &&
1580 hdmi_mode[i].mode.pixclock > 340000000)
1582 if ((feature & SUPPORT_4K) == 0 &&
1583 hdmi_mode[i].mode.xres >= 3840)
1585 if ((feature & SUPPORT_4K_4096) == 0 &&
1586 hdmi_mode[i].mode.xres == 4096)
1588 if ((feature & SUPPORT_1080I) == 0 &&
1589 hdmi_mode[i].mode.xres == 1920 &&
1590 (hdmi_mode[i].mode.vmode & FB_VMODE_INTERLACED))
1592 if ((feature & SUPPORT_480I_576I) == 0 &&
1593 hdmi_mode[i].mode.xres == 720 &&
1594 (hdmi_mode[i].mode.vmode & FB_VMODE_INTERLACED))
1596 hdmi_add_videomode(&hdmi_mode[i].mode, head);