video: rockchip: hdmi: support hdr function
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rockchip-hdmi-lcdc.c
1 #include "rockchip-hdmi.h"
2
3 static const struct hdmi_video_timing hdmi_mode[] = {
4         {
5                 .mode = {
6                         .name = "720x480i@60Hz",
7                         .refresh = 60,
8                         .xres = 720,
9                         .yres = 480,
10                         .pixclock = 27000000,
11                         .left_margin = 57,
12                         .right_margin = 19,
13                         .upper_margin = 15,
14                         .lower_margin = 4,
15                         .hsync_len = 62,
16                         .vsync_len = 3,
17                         .sync = 0,
18                         .vmode = FB_VMODE_INTERLACED,
19                         .flag = 0,
20                 },
21                 .vic = HDMI_720X480I_60HZ_4_3,
22                 .vic_2nd = HDMI_720X480I_60HZ_16_9,
23                 .pixelrepeat = 2,
24                 .interface = OUT_P888,
25         },
26         {
27                 .mode = {
28                         .name = "720x576i@50Hz",
29                         .refresh = 50,
30                         .xres = 720,
31                         .yres = 576,
32                         .pixclock = 27000000,
33                         .left_margin = 69,
34                         .right_margin = 12,
35                         .upper_margin = 19,
36                         .lower_margin = 2,
37                         .hsync_len = 63,
38                         .vsync_len = 3,
39                         .sync = 0,
40                         .vmode = FB_VMODE_INTERLACED,
41                         .flag = 0,
42                 },
43                 .vic = HDMI_720X576I_50HZ_4_3,
44                 .vic_2nd = HDMI_720X576I_50HZ_16_9,
45                 .pixelrepeat = 2,
46                 .interface = OUT_P888,
47         },
48         {
49                 .mode = {
50                         .name = "720x480p@60Hz",
51                         .refresh = 60,
52                         .xres = 720,
53                         .yres = 480,
54                         .pixclock = 27000000,
55                         .left_margin = 60,
56                         .right_margin = 16,
57                         .upper_margin = 30,
58                         .lower_margin = 9,
59                         .hsync_len = 62,
60                         .vsync_len = 6,
61                         .sync = 0,
62                         .vmode = 0,
63                         .flag = 0,
64                 },
65                 .vic = HDMI_720X480P_60HZ_4_3,
66                 .vic_2nd = HDMI_720X480P_60HZ_16_9,
67                 .pixelrepeat = 1,
68                 .interface = OUT_P888,
69         },
70         {
71                 .mode = {
72                         .name = "720x576p@50Hz",
73                         .refresh = 50,
74                         .xres = 720,
75                         .yres = 576,
76                         .pixclock = 27000000,
77                         .left_margin = 68,
78                         .right_margin = 12,
79                         .upper_margin = 39,
80                         .lower_margin = 5,
81                         .hsync_len = 64,
82                         .vsync_len = 5,
83                         .sync = 0,
84                         .vmode = 0,
85                         .flag = 0,
86                 },
87                 .vic = HDMI_720X576P_50HZ_4_3,
88                 .vic_2nd = HDMI_720X576P_50HZ_16_9,
89                 .pixelrepeat = 1,
90                 .interface = OUT_P888,
91         },
92         {
93                 .mode = {
94                         .name = "1280x720p@24Hz",
95                         .refresh = 24,
96                         .xres = 1280,
97                         .yres = 720,
98                         .pixclock = 59400000,
99                         .left_margin = 220,
100                         .right_margin = 1760,
101                         .upper_margin = 20,
102                         .lower_margin = 5,
103                         .hsync_len = 40,
104                         .vsync_len = 5,
105                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
106                         .vmode = 0,
107                         .flag = 0,
108                 },
109                 .vic = HDMI_1280X720P_24HZ,
110                 .vic_2nd = HDMI_1280X720P_24HZ_21_9,
111                 .pixelrepeat = 1,
112                 .interface = OUT_P888,
113         },
114         {
115                 .mode = {
116                         .name = "1280x720p@25Hz",
117                         .refresh = 25,
118                         .xres = 1280,
119                         .yres = 720,
120                         .pixclock = 74250000,
121                         .left_margin = 220,
122                         .right_margin = 2420,
123                         .upper_margin = 20,
124                         .lower_margin = 5,
125                         .hsync_len = 40,
126                         .vsync_len = 5,
127                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
128                         .vmode = 0,
129                         .flag = 0,
130                 },
131                 .vic = HDMI_1280X720P_25HZ,
132                 .vic_2nd = HDMI_1280X720P_25HZ_21_9,
133                 .pixelrepeat = 1,
134                 .interface = OUT_P888,
135         },
136         {
137                 .mode = {
138                         .name = "1280x720p@30Hz",
139                         .refresh = 30,
140                         .xres = 1280,
141                         .yres = 720,
142                         .pixclock = 74250000,
143                         .left_margin = 220,
144                         .right_margin = 1760,
145                         .upper_margin = 20,
146                         .lower_margin = 5,
147                         .hsync_len = 40,
148                         .vsync_len = 5,
149                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
150                         .vmode = 0,
151                         .flag = 0,
152                 },
153                 .vic = HDMI_1280X720P_30HZ,
154                 .vic_2nd = HDMI_1280X720P_30HZ_21_9,
155                 .pixelrepeat = 1,
156                 .interface = OUT_P888,
157         },
158         {
159                 .mode = {
160                         .name = "1280x720p@50Hz",
161                         .refresh = 50,
162                         .xres = 1280,
163                         .yres = 720,
164                         .pixclock = 74250000,
165                         .left_margin = 220,
166                         .right_margin = 440,
167                         .upper_margin = 20,
168                         .lower_margin = 5,
169                         .hsync_len = 40,
170                         .vsync_len = 5,
171                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
172                         .vmode = 0,
173                         .flag = 0,
174                 },
175                 .vic = HDMI_1280X720P_50HZ,
176                 .vic_2nd = HDMI_1280X720P_50HZ_21_9,
177                 .pixelrepeat = 1,
178                 .interface = OUT_P888,
179         },
180         {
181                 .mode = {
182                         .name = "1280x720p@60Hz",
183                         .refresh = 60,
184                         .xres = 1280,
185                         .yres = 720,
186                         .pixclock = 74250000,
187                         .left_margin = 220,
188                         .right_margin = 110,
189                         .upper_margin = 20,
190                         .lower_margin = 5,
191                         .hsync_len = 40,
192                         .vsync_len = 5,
193                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
194                         .vmode = 0,
195                         .flag = 0,
196                 },
197                 .vic = HDMI_1280X720P_60HZ,
198                 .vic_2nd = HDMI_1280X720P_60HZ_21_9,
199                 .pixelrepeat = 1,
200                 .interface = OUT_P888,
201         },
202         {
203                 .mode = {
204                         .name = "1920x1080i@50Hz",
205                         .refresh = 50,
206                         .xres = 1920,
207                         .yres = 1080,
208                         .pixclock = 74250000,
209                         .left_margin = 148,
210                         .right_margin = 528,
211                         .upper_margin = 15,
212                         .lower_margin = 2,
213                         .hsync_len = 44,
214                         .vsync_len = 5,
215                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
216                         .vmode = FB_VMODE_INTERLACED,
217                         .flag = 0,
218                 },
219                 .vic = HDMI_1920X1080I_50HZ,
220                 .vic_2nd = 0,
221                 .pixelrepeat = 1,
222                 .interface = OUT_P888,
223         },
224         {
225                 .mode = {
226                         .name = "1920x1080i@60Hz",
227                         .refresh = 60,
228                         .xres = 1920,
229                         .yres = 1080,
230                         .pixclock = 74250000,
231                         .left_margin = 148,
232                         .right_margin = 88,
233                         .upper_margin = 15,
234                         .lower_margin = 2,
235                         .hsync_len = 44,
236                         .vsync_len = 5,
237                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
238                         .vmode = FB_VMODE_INTERLACED,
239                         .flag = 0,
240                 },
241                 .vic = HDMI_1920X1080I_60HZ,
242                 .vic_2nd = 0,
243                 .pixelrepeat = 1,
244                 .interface = OUT_P888,
245         },
246         {
247                 .mode = {
248                         .name = "1920x1080p@24Hz",
249                         .refresh = 24,
250                         .xres = 1920,
251                         .yres = 1080,
252                         .pixclock = 74250000,
253                         .left_margin = 148,
254                         .right_margin = 638,
255                         .upper_margin = 36,
256                         .lower_margin = 4,
257                         .hsync_len = 44,
258                         .vsync_len = 5,
259                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
260                         .vmode = 0,
261                         .flag = 0,
262                 },
263                 .vic = HDMI_1920X1080P_24HZ,
264                 .vic_2nd = HDMI_1920X1080P_24HZ_21_9,
265                 .pixelrepeat = 1,
266                 .interface = OUT_P888,
267         },
268         {
269                 .mode = {
270                         .name = "1920x1080p@25Hz",
271                         .refresh = 25,
272                         .xres = 1920,
273                         .yres = 1080,
274                         .pixclock = 74250000,
275                         .left_margin = 148,
276                         .right_margin = 528,
277                         .upper_margin = 36,
278                         .lower_margin = 4,
279                         .hsync_len = 44,
280                         .vsync_len = 5,
281                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
282                         .vmode = 0,
283                         .flag = 0,
284                 },
285                 .vic = HDMI_1920X1080P_25HZ,
286                 .vic_2nd = HDMI_1920X1080P_25HZ_21_9,
287                 .pixelrepeat = 1,
288                 .interface = OUT_P888,
289         },
290         {
291                 .mode = {
292                         .name = "1920x1080p@30Hz",
293                         .refresh = 30,
294                         .xres = 1920,
295                         .yres = 1080,
296                         .pixclock = 74250000,
297                         .left_margin = 148,
298                         .right_margin = 88,
299                         .upper_margin = 36,
300                         .lower_margin = 4,
301                         .hsync_len = 44,
302                         .vsync_len = 5,
303                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
304                         .vmode = 0,
305                         .flag = 0,
306                 },
307                 .vic = HDMI_1920X1080P_30HZ,
308                 .vic_2nd = HDMI_1920X1080P_30HZ_21_9,
309                 .pixelrepeat = 1,
310                 .interface = OUT_P888,
311         },
312         {
313                 .mode = {
314                         .name = "1920x1080p@50Hz",
315                         .refresh = 50,
316                         .xres = 1920,
317                         .yres = 1080,
318                         .pixclock = 148500000,
319                         .left_margin = 148,
320                         .right_margin = 528,
321                         .upper_margin = 36,
322                         .lower_margin = 4,
323                         .hsync_len = 44,
324                         .vsync_len = 5,
325                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
326                         .vmode = 0,
327                         .flag = 0,
328                 },
329                 .vic = HDMI_1920X1080P_50HZ,
330                 .vic_2nd = HDMI_1920X1080P_50HZ_21_9,
331                 .pixelrepeat = 1,
332                 .interface = OUT_P888,
333         },
334         {
335                 .mode = {
336                         .name = "1920x1080p@60Hz",
337                         .refresh = 60,
338                         .xres = 1920,
339                         .yres = 1080,
340                         .pixclock = 148500000,
341                         .left_margin = 148,
342                         .right_margin = 88,
343                         .upper_margin = 36,
344                         .lower_margin = 4,
345                         .hsync_len = 44,
346                         .vsync_len = 5,
347                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
348                         .vmode = 0,
349                         .flag = 0,
350                 },
351                 .vic = HDMI_1920X1080P_60HZ,
352                 .vic_2nd = HDMI_1920X1080P_60HZ_21_9,
353                 .pixelrepeat = 1,
354                 .interface = OUT_P888,
355         },
356         {
357                 .mode = {
358                         .name = "3840x2160p@24Hz",
359                         .refresh = 24,
360                         .xres = 3840,
361                         .yres = 2160,
362                         .pixclock = 297000000,
363                         .left_margin = 296,
364                         .right_margin = 1276,
365                         .upper_margin = 72,
366                         .lower_margin = 8,
367                         .hsync_len = 88,
368                         .vsync_len = 10,
369                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
370                         .vmode = 0,
371                         .flag = 0,
372                 },
373                 .vic = HDMI_3840X2160P_24HZ,
374                 .vic_2nd = HDMI_3840X2160P_24HZ_21_9,
375                 .pixelrepeat = 1,
376                 .interface = OUT_P888,
377         },
378         {
379                 .mode = {
380                         .name = "3840x2160p@25Hz",
381                         .refresh = 25,
382                         .xres = 3840,
383                         .yres = 2160,
384                         .pixclock = 297000000,
385                         .left_margin = 296,
386                         .right_margin = 1056,
387                         .upper_margin = 72,
388                         .lower_margin = 8,
389                         .hsync_len = 88,
390                         .vsync_len = 10,
391                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
392                         .vmode = 0,
393                         .flag = 0,
394                 },
395                 .vic = HDMI_3840X2160P_25HZ,
396                 .vic_2nd = HDMI_3840X2160P_25HZ_21_9,
397                 .pixelrepeat = 1,
398                 .interface = OUT_P888,
399         },
400         {
401                 .mode = {
402                         .name = "3840x2160p@30Hz",
403                         .refresh = 30,
404                         .xres = 3840,
405                         .yres = 2160,
406                         .pixclock = 297000000,
407                         .left_margin = 296,
408                         .right_margin = 176,
409                         .upper_margin = 72,
410                         .lower_margin = 8,
411                         .hsync_len = 88,
412                         .vsync_len = 10,
413                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
414                         .vmode = 0,
415                         .flag = 0,
416                 },
417                 .vic = HDMI_3840X2160P_30HZ,
418                 .vic_2nd = HDMI_3840X2160P_30HZ_21_9,
419                 .pixelrepeat = 1,
420                 .interface = OUT_P888,
421         },
422         {
423                 .mode = {
424                         .name = "4096x2160p@24Hz",
425                         .refresh = 24,
426                         .xres = 4096,
427                         .yres = 2160,
428                         .pixclock = 297000000,
429                         .left_margin = 296,
430                         .right_margin = 1020,
431                         .upper_margin = 72,
432                         .lower_margin = 8,
433                         .hsync_len = 88,
434                         .vsync_len = 10,
435                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
436                         .vmode = 0,
437                         .flag = 0,
438                 },
439                 .vic = HDMI_4096X2160P_24HZ,
440                 .vic_2nd = 0,
441                 .pixelrepeat = 1,
442                 .interface = OUT_P888,
443         },
444         {
445                 .mode = {
446                         .name = "4096x2160p@25Hz",
447                         .refresh = 25,
448                         .xres = 4096,
449                         .yres = 2160,
450                         .pixclock = 297000000,
451                         .left_margin = 128,
452                         .right_margin = 968,
453                         .upper_margin = 72,
454                         .lower_margin = 8,
455                         .hsync_len = 88,
456                         .vsync_len = 10,
457                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
458                         .vmode = 0,
459                         .flag = 0,
460                 },
461                 .vic = HDMI_4096X2160P_25HZ,
462                 .vic_2nd = 0,
463                 .pixelrepeat = 1,
464                 .interface = OUT_P888,
465         },
466         {
467                 .mode = {
468                         .name = "4096x2160p@30Hz",
469                         .refresh = 30,
470                         .xres = 4096,
471                         .yres = 2160,
472                         .pixclock = 297000000,
473                         .left_margin = 128,
474                         .right_margin = 88,
475                         .upper_margin = 72,
476                         .lower_margin = 8,
477                         .hsync_len = 88,
478                         .vsync_len = 10,
479                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
480                         .vmode = 0,
481                         .flag = 0,
482                 },
483                 .vic = HDMI_4096X2160P_30HZ,
484                 .vic_2nd = 0,
485                 .pixelrepeat = 1,
486                 .interface = OUT_P888,
487         },
488         {
489                 .mode = {
490                         .name = "3840x2160p@50Hz",
491                         .refresh = 50,
492                         .xres = 3840,
493                         .yres = 2160,
494                         .pixclock = 594000000,
495                         .left_margin = 296,
496                         .right_margin = 1056,
497                         .upper_margin = 72,
498                         .lower_margin = 8,
499                         .hsync_len = 88,
500                         .vsync_len = 10,
501                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
502                         .vmode = 0,
503                         .flag = 0,
504                 },
505                 .vic = HDMI_3840X2160P_50HZ,
506                 .vic_2nd = HDMI_3840X2160P_50HZ_21_9,
507                 .pixelrepeat = 1,
508                 .interface = OUT_P888,
509         },
510         {
511                 .mode = {
512                         .name = "3840x2160p@60Hz",
513                         .refresh = 60,
514                         .xres = 3840,
515                         .yres = 2160,
516                         .pixclock = 594000000,
517                         .left_margin = 296,
518                         .right_margin = 176,
519                         .upper_margin = 72,
520                         .lower_margin = 8,
521                         .hsync_len = 88,
522                         .vsync_len = 10,
523                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
524                         .vmode = 0,
525                         .flag = 0,
526                 },
527                 .vic = HDMI_3840X2160P_60HZ,
528                 .vic_2nd = HDMI_3840X2160P_60HZ_21_9,
529                 .pixelrepeat = 1,
530                 .interface = OUT_P888,
531         },
532         {
533                 .mode = {
534                         .name = "4096x2160p@50Hz",
535                         .refresh = 50,
536                         .xres = 4096,
537                         .yres = 2160,
538                         .pixclock = 594000000,
539                         .left_margin = 128,
540                         .right_margin = 968,
541                         .upper_margin = 72,
542                         .lower_margin = 8,
543                         .hsync_len = 88,
544                         .vsync_len = 10,
545                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
546                         .vmode = 0,
547                         .flag = 0,
548                 },
549                 .vic = HDMI_4096X2160P_50HZ,
550                 .vic_2nd = 0,
551                 .pixelrepeat = 1,
552                 .interface = OUT_P888,
553         },
554         {
555                 .mode = {
556                         .name = "4096x2160p@60Hz",
557                         .refresh = 60,
558                         .xres = 4096,
559                         .yres = 2160,
560                         .pixclock = 594000000,
561                         .left_margin = 128,
562                         .right_margin = 88,
563                         .upper_margin = 72,
564                         .lower_margin = 8,
565                         .hsync_len = 88,
566                         .vsync_len = 10,
567                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
568                         .vmode = 0,
569                         .flag = 0,
570                 },
571                 .vic = HDMI_4096X2160P_60HZ,
572                 .vic_2nd = 0,
573                 .pixelrepeat = 1,
574                 .interface = OUT_P888,
575         },
576         {
577                 .mode = {
578                         .name = "800x600p@60Hz",
579                         .refresh = 60,
580                         .xres = 800,
581                         .yres = 600,
582                         .pixclock = 40000000,
583                         .left_margin = 88,
584                         .right_margin = 40,
585                         .upper_margin = 23,
586                         .lower_margin = 1,
587                         .hsync_len = 128,
588                         .vsync_len = 4,
589                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
590                         .vmode = 0,
591                         .flag = 0,
592                 },
593                 .vic = HDMI_VIDEO_DMT | 1,
594                 .vic_2nd = 0,
595                 .pixelrepeat = 1,
596                 .interface = OUT_P888,
597         },
598         {
599                 .mode = {
600                         .name = "1024x768p@60Hz",
601                         .refresh = 60,
602                         .xres = 1024,
603                         .yres = 768,
604                         .pixclock = 65000000,
605                         .left_margin = 160,
606                         .right_margin = 24,
607                         .upper_margin = 29,
608                         .lower_margin = 3,
609                         .hsync_len = 136,
610                         .vsync_len = 6,
611                         .sync = 0,
612                         .vmode = 0,
613                         .flag = 0,
614                 },
615                 .vic = HDMI_VIDEO_DMT | 2,
616                 .vic_2nd = 0,
617                 .pixelrepeat = 1,
618                 .interface = OUT_P888,
619         },
620         {
621                 .mode = {
622                         .name = "1280x960p@60Hz",
623                         .refresh = 60,
624                         .xres = 1280,
625                         .yres = 960,
626                         .pixclock = 108000000,
627                         .left_margin = 312,
628                         .right_margin = 96,
629                         .upper_margin = 36,
630                         .lower_margin = 1,
631                         .hsync_len = 112,
632                         .vsync_len = 3,
633                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
634                         .vmode = 0,
635                         .flag = 0,
636                 },
637                 .vic = HDMI_VIDEO_DMT | 3,
638                 .vic_2nd = 0,
639                 .pixelrepeat = 1,
640                 .interface = OUT_P888,
641         },
642         {
643                 .mode = {
644                         .name = "1280x1024p@60Hz",
645                         .refresh = 60,
646                         .xres = 1280,
647                         .yres = 1024,
648                         .pixclock = 108000000,
649                         .left_margin = 248,
650                         .right_margin = 48,
651                         .upper_margin = 38,
652                         .lower_margin = 1,
653                         .hsync_len = 112,
654                         .vsync_len = 3,
655                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
656                         .vmode = 0,
657                         .flag = 0,
658                 },
659                 .vic = HDMI_VIDEO_DMT | 4,
660                 .vic_2nd = 0,
661                 .pixelrepeat = 1,
662                 .interface = OUT_P888,
663         },
664         {
665                 .mode = {
666                         .name = "1360x768p@60Hz",
667                         .refresh = 60,
668                         .xres = 1360,
669                         .yres = 768,
670                         .pixclock = 85500000,
671                         .left_margin = 256,
672                         .right_margin = 64,
673                         .upper_margin = 18,
674                         .lower_margin = 3,
675                         .hsync_len = 112,
676                         .vsync_len = 6,
677                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
678                         .vmode = 0,
679                         .flag = 0,
680                 },
681                 .vic = HDMI_VIDEO_DMT | 5,
682                 .vic_2nd = 0,
683                 .pixelrepeat = 1,
684                 .interface = OUT_P888,
685         },
686         {
687                 .mode = {
688                         .name = "1366x768p@60Hz",
689                         .refresh = 60,
690                         .xres = 1366,
691                         .yres = 768,
692                         .pixclock = 85500000,
693                         .left_margin = 213,
694                         .right_margin = 70,
695                         .upper_margin = 24,
696                         .lower_margin = 3,
697                         .hsync_len = 143,
698                         .vsync_len = 3,
699                         .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
700                         .vmode = 0,
701                         .flag = 0,
702                 },
703                 .vic = HDMI_VIDEO_DMT | 6,
704                 .vic_2nd = 0,
705                 .pixelrepeat = 1,
706                 .interface = OUT_P888,
707         },
708         {
709                 .mode = {
710                         .name = "1440x900p@60Hz",
711                         .refresh = 60,
712                         .xres = 1440,
713                         .yres = 900,
714                         .pixclock = 106500000,
715                         .left_margin = 232,
716                         .right_margin = 80,
717                         .upper_margin = 25,
718                         .lower_margin = 3,
719                         .hsync_len = 152,
720                         .vsync_len = 6,
721                         .sync = FB_SYNC_VERT_HIGH_ACT,
722                         .vmode = 0,
723                         .flag = 0,
724                 },
725                 .vic = HDMI_VIDEO_DMT | 7,
726                 .vic_2nd = 0,
727                 .pixelrepeat = 1,
728                 .interface = OUT_P888,
729         },
730         {
731                 .mode = {
732                         .name = "1600x900p@60Hz",
733                         .refresh = 60,
734                         .xres = 1600,
735                         .yres = 900,
736                         .pixclock = 108000000,
737                         .left_margin = 96,
738                         .right_margin = 24,
739                         .upper_margin = 96,
740                         .lower_margin = 1,
741                         .hsync_len = 80,
742                         .vsync_len = 3,
743                         .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
744                         .vmode = 0,
745                         .flag = 0,
746                 },
747                 .vic = HDMI_VIDEO_DMT | 8,
748                 .vic_2nd = 0,
749                 .pixelrepeat = 1,
750                 .interface = OUT_P888,
751         },
752         {
753                 .mode = {
754                         .name = "1680x1050@60Hz",
755                         .refresh = 60,
756                         .xres = 1680,
757                         .yres = 1050,
758                         .pixclock = 146250000,
759                         .left_margin = 280,
760                         .right_margin = 104,
761                         .upper_margin = 30,
762                         .lower_margin = 3,
763                         .hsync_len = 176,
764                         .vsync_len = 6,
765                         .sync = FB_SYNC_VERT_HIGH_ACT,
766                         .vmode = 0,
767                         .flag = 0,
768                 },
769                 .vic = HDMI_VIDEO_DMT | 9,
770                 .vic_2nd = 0,
771                 .pixelrepeat = 1,
772                 .interface = OUT_P888,
773         },
774         {
775                 .mode = {
776                         .name = "1440x1280@60Hz",
777                         .refresh = 60,
778                         .xres = 1440,
779                         .yres = 1280,
780                         .pixclock = 148500000,
781                         .left_margin = 84,
782                         .right_margin = 360,
783                         .upper_margin = 8,
784                         .lower_margin = 10,
785                         .hsync_len = 20,
786                         .vsync_len = 2,
787                         .sync = 0,
788                         .vmode = 0,
789                         .flag = 0,
790                 },
791                 .vic = HDMI_VIDEO_DISCRETE_VR | 1,
792                 .vic_2nd = 0,
793                 .pixelrepeat = 1,
794                 .interface = OUT_P888,
795         },
796         {
797                 /* AUO 3.81 */
798                 .mode = {
799                         .name = "2160x1200@75Hz",
800                         .refresh = 75,
801                         .xres = 2160,
802                         .yres = 1200,
803                         .pixclock = 245000000,
804                         .left_margin = 100,
805                         .right_margin = 420,
806                         .upper_margin = 3,
807                         .lower_margin = 6,
808                         .hsync_len = 32,
809                         .vsync_len = 3,
810                         .sync = 0,
811                         .vmode = 0,
812                         .flag = 0,
813                 },
814                 .vic = HDMI_VIDEO_DISCRETE_VR | 3,
815                 .vic_2nd = 0,
816                 .pixelrepeat = 1,
817                 .interface = OUT_P888,
818         },
819         {
820                 /* sharp 2.89 */
821                 .mode = {
822                         .name = "2880x1440@75Hz",
823                         .refresh = 75,
824                         .xres = 2880,
825                         .yres = 1440,
826                         .pixclock = 340000000,
827                         .left_margin = 100,
828                         .right_margin = 50,
829                         .upper_margin = 8,
830                         .lower_margin = 6,
831                         .hsync_len = 50,
832                         .vsync_len = 1,
833                         .sync = 0,
834                         .vmode = 0,
835                         .flag = 0,
836                 },
837                 .vic = HDMI_VIDEO_DISCRETE_VR | 4,
838                 .vic_2nd = 0,
839                 .pixelrepeat = 1,
840                 .interface = OUT_P888,
841         },
842         {
843                 /* RAYKEN 5.46 */
844                 .mode = {
845                         .name = "1440x2560@60Hz",
846                         .refresh = 60,
847                         .xres = 1440,
848                         .yres = 2560,
849                         .pixclock = 268500000,
850                         .left_margin = 50,
851                         .right_margin = 200,
852                         .upper_margin = 20,
853                         .lower_margin = 20,
854                         .hsync_len = 20,
855                         .vsync_len = 10,
856                         .sync = 0,
857                         .vmode = 0,
858                         .flag = 0,
859                 },
860                 .vic = HDMI_VIDEO_DISCRETE_VR | 5,
861                 .vic_2nd = 0,
862                 .pixelrepeat = 1,
863                 .interface = OUT_P888,
864         },
865         {
866                 /* samsung */
867                 .mode = {
868                         .name = "1440x2560@70Hz",
869                         .refresh = 70,
870                         .xres = 1440,
871                         .yres = 2560,
872                         .pixclock = 285000000,
873                         .left_margin = 40,
874                         .right_margin = 80,
875                         .upper_margin = 2,
876                         .lower_margin = 6,
877                         .hsync_len = 20,
878                         .vsync_len = 8,
879                         .sync = 0,
880                         .vmode = 0,
881                         .flag = 0,
882                 },
883                 .vic = HDMI_VIDEO_DISCRETE_VR | 6,
884                 .vic_2nd = 0,
885                 .pixelrepeat = 1,
886                 .interface = OUT_P888,
887         },
888 };
889
890 static int hdmi_set_info(struct rk_screen *screen, struct hdmi *hdmi)
891 {
892         int i, vic, colorimetry;
893         struct fb_videomode *mode;
894
895         if (!screen || !hdmi)
896                 return HDMI_ERROR_FALSE;
897
898         if (hdmi->vic == 0)
899                 hdmi->vic = hdmi->property->defaultmode;
900
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;
906                         else
907                                 vic = hdmi->vic;
908                 } else {
909                         vic = hdmi->vic & HDMI_VIC_MASK;
910                 }
911         } else {
912                 if ((hdmi->vic & HDMI_VIDEO_DMT) ||
913                     (hdmi->vic & HDMI_VIDEO_DISCRETE_VR))
914                         vic = hdmi->vic;
915                 else
916                         vic = hdmi->vic & HDMI_VIC_MASK;
917         }
918
919         for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
920                 if (hdmi_mode[i].vic == vic ||
921                     hdmi_mode[i].vic_2nd == vic)
922                         break;
923         }
924         if (i == ARRAY_SIZE(hdmi_mode))
925                 return HDMI_ERROR_FALSE;
926
927         memset(screen, 0, sizeof(struct rk_screen));
928
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;
944                 else
945                         screen->color_mode = COLOR_YCBCR;
946         } else if (colorimetry == HDMI_COLORIMETRY_SMTPE_170M) {
947                 screen->color_mode = COLOR_YCBCR;
948         } else {
949                 screen->color_mode = COLOR_YCBCR_BT709;
950         }
951
952         if (hdmi->vic & HDMI_VIDEO_YUV420) {
953                 if (hdmi->video.color_output_depth == 10)
954                         screen->face = OUT_YUV_420_10BIT;
955                 else
956                         screen->face = OUT_YUV_420;
957         } else {
958                 if (hdmi->video.color_output_depth == 10)
959                         screen->face = OUT_P101010;
960                 else
961                         screen->face = hdmi_mode[i].interface;
962         }
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 +
969                                         mode->upper_margin +
970                                         mode->lower_margin +
971                                         mode->vsync_len;
972                 } else {
973                         screen->mode.yres = 2 * mode->yres +
974                                             3 * (mode->upper_margin +
975                                                  mode->lower_margin +
976                                                  mode->vsync_len) + 2;
977                         screen->mode.vmode = 0;
978                 }
979         }
980         /* Pin polarity */
981         if (FB_SYNC_HOR_HIGH_ACT & mode->sync)
982                 screen->pin_hsync = 1;
983         else
984                 screen->pin_hsync = 0;
985         if (FB_SYNC_VERT_HIGH_ACT & mode->sync)
986                 screen->pin_vsync = 1;
987         else
988                 screen->pin_vsync = 0;
989
990         screen->pin_den = 0;
991         screen->pin_dclk = 1;
992
993         /* Swap rule */
994         if (hdmi->soctype > HDMI_SOC_RK312X &&
995             screen->color_mode > COLOR_RGB &&
996             (screen->face == OUT_P888 ||
997              screen->face == OUT_P101010))
998                 screen->swap_rb = 1;
999         else
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;
1005
1006         /* Operation function*/
1007         screen->init = NULL;
1008         screen->standby = NULL;
1009
1010         screen->overscan.left = hdmi->xscale;
1011         screen->overscan.top = hdmi->yscale;
1012         screen->overscan.right = hdmi->xscale;
1013         screen->overscan.bottom = hdmi->yscale;
1014
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);
1022
1023         return 0;
1024 }
1025
1026 /**
1027  * hdmi_find_best_mode: find the video mode nearest to input vic
1028  * @hdmi:
1029  * @vic: input vic
1030  *
1031  * NOTES:
1032  * If vic is zero, return the high resolution video mode vic.
1033  */
1034 int hdmi_find_best_mode(struct hdmi *hdmi, int vic)
1035 {
1036         struct list_head *pos, *head = &hdmi->edid.modelist;
1037         struct display_modelist *modelist = NULL;
1038         int found = 0;
1039
1040         if (vic) {
1041                 list_for_each(pos, head) {
1042                         modelist =
1043                                 list_entry(pos,
1044                                            struct display_modelist, list);
1045                         if (modelist->vic == vic) {
1046                                 found = 1;
1047                                 break;
1048                         }
1049                 }
1050         }
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);
1057                 else
1058                         return hdmi->property->defaultmode;
1059         }
1060
1061         if (modelist)
1062                 return modelist->vic;
1063         else
1064                 return 0;
1065 }
1066
1067 /**
1068  * hdmi_set_lcdc: switch lcdc mode to required video mode
1069  * @hdmi:
1070  *
1071  * NOTES:
1072  *
1073  */
1074 int hdmi_set_lcdc(struct hdmi *hdmi)
1075 {
1076         int rc = 0;
1077         struct rk_screen screen;
1078
1079         rc = hdmi_set_info(&screen, hdmi);
1080         if (!rc)
1081                 rk_fb_switch_screen(&screen, 1, hdmi->lcdc->id);
1082         return rc;
1083 }
1084
1085 /**
1086  * hdmi_videomode_compare - compare 2 videomodes
1087  * @mode1: first videomode
1088  * @mode2: second videomode
1089  *
1090  * RETURNS:
1091  * 1 if mode1 > mode2, 0 if mode1 = mode2, -1 mode1 < mode2
1092  */
1093 static int hdmi_videomode_compare(const struct fb_videomode *mode1,
1094                                   const struct fb_videomode *mode2)
1095 {
1096         if (mode1->xres > mode2->xres)
1097                 return 1;
1098
1099         if (mode1->xres == mode2->xres) {
1100                 if (mode1->yres > mode2->yres)
1101                         return 1;
1102                 if (mode1->yres == mode2->yres) {
1103                         if (mode1->vmode < mode2->vmode)
1104                                 return 1;
1105                         if (mode1->pixclock > mode2->pixclock)
1106                                 return 1;
1107                         if (mode1->pixclock == mode2->pixclock) {
1108                                 if (mode1->refresh > mode2->refresh)
1109                                         return 1;
1110                                 if (mode1->refresh == mode2->refresh) {
1111                                         if (mode2->flag > mode1->flag)
1112                                                 return 1;
1113                                         if (mode2->flag < mode1->flag)
1114                                                 return -1;
1115                                         if (mode2->vmode > mode1->vmode)
1116                                                 return 1;
1117                                         if (mode2->vmode == mode1->vmode)
1118                                                 return 0;
1119                                 }
1120                         }
1121                 }
1122         }
1123         return -1;
1124 }
1125
1126 /**
1127  * hdmi_add_vic - add entry to modelist according vic
1128  * @vic: vic to be added
1129  * @head: struct list_head of modelist
1130  *
1131  * NOTES:
1132  * Will only add unmatched mode entries
1133  */
1134 int hdmi_add_vic(int vic, struct list_head *head)
1135 {
1136         struct list_head *pos;
1137         struct display_modelist *modelist;
1138         int found = 0, v;
1139
1140         /*pr_info("%s vic %d\n", __FUNCTION__, vic);*/
1141         if (vic == 0)
1142                 return -1;
1143
1144         if (vic & HDMI_VIDEO_YUV420) {
1145                 v = vic & 0xff;
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) {
1152                         return -1;
1153                 }
1154         }
1155
1156         list_for_each(pos, head) {
1157                 modelist = list_entry(pos, struct display_modelist, list);
1158                 v = modelist->vic;
1159                 if (v == vic) {
1160                         found = 1;
1161                         break;
1162                 }
1163         }
1164         if (!found) {
1165                 modelist = kmalloc(sizeof(*modelist),
1166                                    GFP_KERNEL);
1167
1168                 if (!modelist)
1169                         return -ENOMEM;
1170                 memset(modelist, 0, sizeof(struct display_modelist));
1171                 modelist->vic = vic;
1172                 list_add_tail(&modelist->list, head);
1173         }
1174         return 0;
1175 }
1176
1177 /**
1178  * hdmi_add_videomode: adds videomode entry to modelist
1179  * @mode: videomode to be added
1180  * @head: struct list_head of modelist
1181  *
1182  * NOTES:
1183  * Will only add unmatched mode entries
1184  */
1185 static int hdmi_add_videomode(const struct fb_videomode *mode,
1186                               struct list_head *head)
1187 {
1188         struct list_head *pos;
1189         struct display_modelist *modelist, *modelist_new;
1190         struct fb_videomode *m;
1191         int i, found = 0;
1192
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)) {
1196                         found = 1;
1197                         break;
1198                 }
1199         }
1200
1201         if (found) {
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))
1207                                 return 0;
1208                         else if (hdmi_videomode_compare(m, mode) == -1)
1209                                 break;
1210                 }
1211
1212                 modelist_new = kmalloc(sizeof(*modelist_new), GFP_KERNEL);
1213                 if (!modelist_new)
1214                         return -ENOMEM;
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);
1219         }
1220
1221         return 0;
1222 }
1223
1224 /**
1225  * hdmi_sort_modelist: sort modelist of edid
1226  * @edid: edid to be sort
1227  */
1228 static void hdmi_sort_modelist(struct hdmi_edid *edid, int feature)
1229 {
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;
1235
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;
1244                                 else
1245                                         continue;
1246                         } else {
1247                                 vic = modelist->vic & HDMI_VIC_MASK;
1248                         }
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)
1253                                         continue;
1254                                 if ((feature & SUPPORT_4K_4096) == 0 &&
1255                                     hdmi_mode[i].mode.xres == 4096)
1256                                         continue;
1257                                 if ((feature & SUPPORT_TMDS_600M) == 0 &&
1258                                     !(modelist->vic & HDMI_VIDEO_YUV420) &&
1259                                     hdmi_mode[i].mode.pixclock > 340000000)
1260                                         continue;
1261                                 if ((modelist->vic & HDMI_VIDEO_YUV420) &&
1262                                     (feature & SUPPORT_YUV420) == 0)
1263                                         continue;
1264                                 if ((feature & SUPPORT_1080I) == 0 &&
1265                                     hdmi_mode[i].mode.xres == 1920 &&
1266                                     (hdmi_mode[i].mode.vmode &
1267                                      FB_VMODE_INTERLACED))
1268                                         continue;
1269                                 if ((feature & SUPPORT_480I_576I) == 0 &&
1270                                     hdmi_mode[i].mode.xres == 720 &&
1271                                     hdmi_mode[i].mode.vmode &
1272                                      FB_VMODE_INTERLACED)
1273                                         continue;
1274                                 modelist->mode = hdmi_mode[i].mode;
1275                                 if (modelist->vic & HDMI_VIDEO_YUV420)
1276                                         modelist->mode.flag = 1;
1277
1278                                 compare = 1;
1279                                 m = (struct fb_videomode *)&modelist->mode;
1280                                 list_for_each(pos_new, &head_new) {
1281                                         modelist_new =
1282                                         list_entry(pos_new,
1283                                                    struct display_modelist,
1284                                                    list);
1285                                         m_new = &modelist_new->mode;
1286                                         compare =
1287                                         hdmi_videomode_compare(m, m_new);
1288                                         if (compare != -1)
1289                                                 break;
1290                                 }
1291                                 if (compare != 0) {
1292                                         modelist_n =
1293                                                 kmalloc(sizeof(*modelist_n),
1294                                                         GFP_KERNEL);
1295                                         if (!modelist_n)
1296                                                 return;
1297                                         *modelist_n = *modelist;
1298                                         list_add_tail(&modelist_n->list,
1299                                                       pos_new);
1300                                 }
1301                                 break;
1302                         }
1303                 }
1304         }
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);
1309         } else {
1310                 edid->modelist = head_new;
1311                 edid->modelist.prev->next = &edid->modelist;
1312                 edid->modelist.next->prev = &edid->modelist;
1313         }
1314 }
1315
1316 static int edid_select_prop_value(struct hdmi *hdmi)
1317 {
1318         struct edid_prop_value *prop_value = NULL;
1319         int nstates = 0;
1320         int i, vid, pid, sn, xres, yres, reboot = 0;
1321
1322         prop_value = hdmi->pvalue;
1323         nstates = hdmi->nstates;
1324
1325         if (!prop_value) {
1326                 pr_info("%s:pvalue is NULL\n", __func__);
1327                 return -1;
1328         }
1329
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;
1335
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))) {
1350                                 reboot = 1;
1351                         } else {
1352                                 reboot = 0;
1353                         }
1354
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);
1363
1364                         break;
1365                 }
1366         }
1367
1368         if (reboot) {
1369                 dev_info(hdmi->dev, "%s:kernel_restart\n", __func__);
1370                 kernel_restart(NULL);
1371         }
1372
1373         return 0;
1374 }
1375
1376 /**
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.
1380  */
1381 int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
1382 {
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;
1387
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;
1395         }
1396
1397         if (hdmi->edid_auto_support)
1398                 edid_select_prop_value(hdmi);
1399
1400         if (head->next == head) {
1401                 dev_info(hdmi->dev,
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.
1406                  */
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 ==
1414                                          modedb->xres &&
1415                                          specs->modedb[i].yres > modedb->yres)
1416                                         modedb = &specs->modedb[i];
1417                         }
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.
1421                          */
1422                         pixclock = PICOS2KHZ(modedb->pixclock);
1423                         pixclock /= 250;
1424                         pixclock *= 250;
1425                         pixclock *= 1000;
1426                         if (pixclock == 148250000)
1427                                 pixclock = 148500000;
1428                         if (pixclock > specs->dclkmax)
1429                                 specs->dclkmax = pixclock;
1430                 }
1431
1432                 for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
1433                         mode = (struct fb_videomode *)&hdmi_mode[i].mode;
1434                         if (modedb) {
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))
1441                                         continue;
1442                         } else {
1443                                 /* If there is no valid information in EDID,
1444                                  * just list common hdmi foramt.
1445                                  */
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)
1451                                         continue;
1452                         }
1453                         if ((feature & SUPPORT_TMDS_600M) == 0 &&
1454                             mode->pixclock > 340000000)
1455                                 continue;
1456                         if ((feature & SUPPORT_4K) == 0 &&
1457                             mode->xres >= 3840)
1458                                 continue;
1459                         if ((feature & SUPPORT_4K_4096) == 0 &&
1460                             mode->xres == 4096)
1461                                 continue;
1462                         if ((feature & SUPPORT_1080I) == 0 &&
1463                             mode->xres == 1920 &&
1464                             (mode->vmode & FB_VMODE_INTERLACED))
1465                                 continue;
1466                         if ((feature & SUPPORT_480I_576I) == 0 &&
1467                             mode->xres == 720 &&
1468                             (mode->vmode & FB_VMODE_INTERLACED))
1469                                 continue;
1470                         hdmi_add_videomode(mode, head);
1471                 }
1472         } else {
1473                 /* There are some video mode is not defined in EDID extend
1474                  * block, so we need to check first block data.
1475                  */
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);
1480                                 if (pixclock)
1481                                         hdmi_add_vic(pixclock, head);
1482                         }
1483                 }
1484                 hdmi_sort_modelist(&hdmi->edid, hdmi->property->feature);
1485         }
1486
1487         return HDMI_ERROR_SUCCESS;
1488 }
1489
1490 /**
1491  * hdmi_videomode_to_vic: transverse video mode to vic
1492  * @vmode: videomode to transverse
1493  *
1494  */
1495 int hdmi_videomode_to_vic(struct fb_videomode *vmode)
1496 {
1497         struct fb_videomode *mode;
1498         unsigned int vic = 0;
1499         int i = 0;
1500
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;
1514                         break;
1515                 }
1516         }
1517         return vic;
1518 }
1519
1520 /**
1521  * hdmi_vic2timing: transverse vic mode to video timing
1522  * @vmode: vic to transverse
1523  *
1524  */
1525 const struct hdmi_video_timing *hdmi_vic2timing(int vic)
1526 {
1527         int i;
1528
1529         if (vic == 0)
1530                 return NULL;
1531
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];
1535         }
1536         return NULL;
1537 }
1538
1539 /**
1540  * hdmi_vic_to_videomode: transverse vic mode to video mode
1541  * @vmode: vic to transverse
1542  *
1543  */
1544 const struct fb_videomode *hdmi_vic_to_videomode(int vic)
1545 {
1546         int i, vid;
1547
1548         if (vic == 0)
1549                 return NULL;
1550         else if ((vic & HDMI_VIDEO_DMT) || (vic & HDMI_VIDEO_DISCRETE_VR))
1551                 vid = vic;
1552         else
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;
1558         }
1559         return NULL;
1560 }
1561
1562 /**
1563  * hdmi_init_modelist: initial hdmi mode list
1564  * @hdmi:
1565  *
1566  * NOTES:
1567  *
1568  */
1569 void hdmi_init_modelist(struct hdmi *hdmi)
1570 {
1571         int i, feature;
1572         struct list_head *head = &hdmi->edid.modelist;
1573
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))
1578                         continue;
1579                 if ((feature & SUPPORT_TMDS_600M) == 0 &&
1580                     hdmi_mode[i].mode.pixclock > 340000000)
1581                         continue;
1582                 if ((feature & SUPPORT_4K) == 0 &&
1583                     hdmi_mode[i].mode.xres >= 3840)
1584                         continue;
1585                 if ((feature & SUPPORT_4K_4096) == 0 &&
1586                     hdmi_mode[i].mode.xres == 4096)
1587                         continue;
1588                 if ((feature & SUPPORT_1080I) == 0 &&
1589                     hdmi_mode[i].mode.xres == 1920 &&
1590                     (hdmi_mode[i].mode.vmode & FB_VMODE_INTERLACED))
1591                         continue;
1592                 if ((feature & SUPPORT_480I_576I) == 0 &&
1593                     hdmi_mode[i].mode.xres == 720 &&
1594                     (hdmi_mode[i].mode.vmode & FB_VMODE_INTERLACED))
1595                         continue;
1596                 hdmi_add_videomode(&hdmi_mode[i].mode, head);
1597         }
1598 }