6ca348f50de3439b908b491225b4fb4a61c04ddb
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rk30_hdmi_lcdc.c
1 #include <linux/console.h>
2 #include "rk30_hdmi.h"
3 #include "rk30_hdmi_hw.h"
4 #include<linux/rk_fb.h>
5
6 #define OUT_TYPE                SCREEN_HDMI
7 #define OUT_FACE                OUT_P888
8 #define DCLK_POL                1
9 #define SWAP_RB                 0
10 #define LCD_ACLK                800000000
11
12 const struct fb_videomode hdmi_mode [] = {
13         //name                          refresh         xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag(used for vic)
14 //{     "640x480p@60Hz",        60,                     640,    480,    25175000,       48,             16,             33,             10,             96,             2,              0,                      0,              1       },
15 //{     "720x480i@60Hz",        60,                     720,    480,    27000000,       114,    38,             15,             4,              124,    3,              0,                      1,              6       },
16 //{     "720x576i@50Hz",        50,                     720,    576,    27000000,       138,    24,             19,             2,              126,    3,              0,                      1,              21      },
17 {       "720x480p@60Hz",        60,                     720,    480,    27000000,       60,             16,             30,             9,              62,             6,              0,                      0,              2       },
18 {       "720x576p@50Hz",        50,                     720,    576,    27000000,       68,             12,             39,             5,              64,             5,              0,                      0,              17      },
19 //{     "1280x720p@24Hz",       24,                     1280,   720,    59400000,       220,    1760,   20,             5,              40,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              60      },
20 //{     "1280x720p@25Hz",       25,                     1280,   720,    74250000,       220,    2420,   20,             5,              40,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              61      },
21 //{     "1280x720p@30Hz",       30,                     1280,   720,    74250000,       220,    1760,   20,             5,              40,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              62      },
22 {       "1280x720p@50Hz",       50,                     1280,   720,    74250000,       220,    440,    20,             5,              40,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              19      },
23 {       "1280x720p@60Hz",       60,                     1280,   720,    74250000,       220,    110,    20,             5,              40,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              4       },
24 //{     "1920x1080p@24Hz",      24,                     1920,   1080,   74250000,       148,    638,    36,             4,              44,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              32      },
25 //{     "1920x1080p@25Hz",      25,                     1920,   1080,   74250000,       148,    528,    36,             4,              44,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              33      },
26 //{     "1920x1080p@30Hz",      30,                     1920,   1080,   74250000,       148,    88,             36,             4,              44,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              34      },      
27 //{     "1920x1080i@50Hz_2",50,                 1920,   1080,   72000000,       184,    32,             57,             23,             168,    5,              FB_SYNC_HOR_HIGH_ACT,                   1,              39      },
28 //{     "1920x1080i@50Hz",      50,                     1920,   1080,   74250000,       148,    528,    15,             2,              44,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   1,              20      },
29 //{     "1920x1080i@60Hz",      60,                     1920,   1080,   74250000,       148,    88,             15,             2,              44,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   1,              5       },
30 {       "1920x1080p@50Hz",      50,                     1920,   1080,   148500000,      148,    528,    36,             4,              44,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              31      },
31 {       "1920x1080p@60Hz",      60,                     1920,   1080,   148500000,      148,    88,             36,             4,              44,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              16      },
32 /*
33 {       "1440x288p@50Hz",       50,                     720,    480,    27000000,       138,    24,             19,             2,              126,    3,              0,                      0,              23      },
34 {       "2880x576i@50Hz",       50,                     1440,   240,    54000000,       276,    48,             19,             2,              252,    3,              0,                      1,              25      },
35 {       "2880x288p@50Hz",       50,                     2880,   480,    54000000,       276,    48,             19,             3,              252,    3,              0,                      0,              27      },
36 {       "1440x576p@50Hz",       50,                     2880,   480,    54000000,       136,    24,             39,             5,              128,    5,              0,                      0,              29      },
37 {       "2880x576p@50Hz",       50,                     1920,   1080,   108000000,      272,    48,             39,             5,              256,    5,              0,                      0,              37      },
38 {       "1440x240p@60Hz",       60,                     1440,   240,    27000000,       114,    38,             15,             4,              124,    3,              0,                      0,              8       },
39 {       "2880x480i@60Hz",       60,                     2880,   480,    54000000,       228,    76,             15,             4,              248,    3,              0,                      1,              10      },
40 {       "2880x480p@60Hz",       60,                     2880,   480,    54000000,       228,    76,             15,             4,              248,    3,              0,                      0,              12      },
41 {       "1440x480p@60Hz",       60,                     1440,   480,    54000000,       120,    32,             30,             9,              124,    6,              0,                      0,              14      },
42 {       "2880x480p@60Hz",       60,                     2880,   480,    54000000,       240,    64,             30,             9,              248,    6,              0,                      0,              35      },
43
44 {       "1920x1080i@100Hz",     100,            1920,   1080,   148500000,      148,    528,    15,             2,              44,             5,              1,                      1,              40      },
45 {       "1280x720p@100Hz",      100,            1280,   720,    148500000,      220,    440,    20,             5,              40,             5,              1,                      0,              41      },
46 {       "720x576p@100Hz",       100,            720,    576,    54000000,       68,             12,             39,             5,              64,             5,              0,                      0,              42      },
47 {       "1440x576i@100Hz",      100,            1440,   576,    54000000,       138,    24,             19,             2,              12,             3,              0,                      1,              44      },
48 {       "1920x1080p@100Hz",     100,            1920,   1080,   297000000,      148,    528,    36,             4,              44,             5,              1,                      0,              64      },
49
50 {       "1920x1080i@120Hz",     120,            1920,   1080,   148500000,      148,    88,             15,             2,              44,             5,              1,                      1,              46      },
51 {       "1280x720p@120Hz",      120,            1280,   720,    148500000,      220,    110,    20,             5,              40,             5,              1,                      0,              47      },
52 {       "720x480p@120Hz",       120,            720,    480,    54000000,       60,             16,             30,             9,              62,             6,              0,                      0,              48      },
53 {       "1440x480i@120Hz",      120,            1440,   480,    54000000,       114,    38,             15,             4,              12,             3,              0,                      1,              50      },
54 {       "1920x1080p@120Hz",     120,            1920,   1080,   297000000,      148,    88,             36,             4,              44,             5,              1,                      0,              63      },
55
56 {       "720x576p@200Hz",       200,            720,    576,    108000000,      68,             12,             39,             5,              64,             5,              0,                      0,              52      },
57 {       "1440x576i@200Hz",      200,            1920,   1080,   108000000,      138,    24,             19,             2,              12,             3,              0,                      1,              54      },
58
59 {       "720x480p@240Hz",       240,            720,    480,    108000000,      60,             16,             30,             9,              62,             6,              0,                      0,              56      },
60 {       "1440x480i@240Hz",      240,            1440,   480,    108000000,      114,    38,             15,             4,              12,             3,              0,                      1,              58      },
61 */
62
63 };
64
65 int hdmi_set_info(struct rk29fb_screen *screen, unsigned int vic)
66 {
67     int i;
68     
69     if(screen == NULL || vic == 0)
70         return -1;
71     
72     for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
73     {
74         if(hdmi_mode[i].flag == vic)
75                 break;
76     }
77     if(i == ARRAY_SIZE(hdmi_mode))
78         return -1;
79     
80     memset(screen, 0, sizeof(struct rk29fb_screen));
81     
82     /* screen type & face */
83     screen->type = OUT_TYPE;
84     screen->face = OUT_FACE;
85
86     /* Screen size */
87     screen->x_res = hdmi_mode[i].xres;
88     screen->y_res = hdmi_mode[i].yres;
89     
90     /* Timing */
91     screen->pixclock = hdmi_mode[i].pixclock;
92         screen->lcdc_aclk = LCD_ACLK;
93         screen->left_margin = hdmi_mode[i].left_margin;
94         screen->right_margin = hdmi_mode[i].right_margin;
95         screen->hsync_len = hdmi_mode[i].hsync_len;
96         screen->upper_margin = hdmi_mode[i].upper_margin;
97         screen->lower_margin = hdmi_mode[i].lower_margin;
98         screen->vsync_len = hdmi_mode[i].vsync_len;
99
100         /* Pin polarity */
101         if(FB_SYNC_HOR_HIGH_ACT & hdmi_mode[i].sync)
102                 screen->pin_hsync = 1;
103         else
104                 screen->pin_hsync = 0;
105         if(FB_SYNC_VERT_HIGH_ACT & hdmi_mode[i].sync)
106                 screen->pin_vsync = 1;
107         else
108                 screen->pin_vsync = 0;
109         screen->pin_den = 0;
110         screen->pin_dclk = DCLK_POL;
111
112         /* Swap rule */
113     screen->swap_rb = SWAP_RB;
114     screen->swap_rg = 0;
115     screen->swap_gb = 0;
116     screen->swap_delta = 0;
117     screen->swap_dumy = 0;
118
119     /* Operation function*/
120     screen->init = NULL;
121     screen->standby = NULL;
122     
123     return 0;
124 }
125
126 static void hdmi_show_sink_info(struct hdmi *hdmi)
127 {
128         struct list_head *pos, *head = &hdmi->edid.modelist;
129         struct fb_modelist *modelist;
130         struct fb_videomode *m;
131         int i;
132         struct hdmi_audio *audio;
133
134         hdmi_dbg(hdmi->dev, "******** Show Sink Info ********\n");
135         hdmi_dbg(hdmi->dev, "Support video mode: \n");
136         list_for_each(pos, head) {
137                 modelist = list_entry(pos, struct fb_modelist, list);
138                 m = &modelist->mode;
139                 hdmi_dbg(hdmi->dev, "   %s.\n", m->name);
140         }
141         
142         for(i = 0; i < hdmi->edid.audio_num; i++)
143         {
144                 audio = &(hdmi->edid.audio[i]);
145                 switch(audio->type)
146                 {
147                         case HDMI_AUDIO_LPCM:
148                                 hdmi_dbg(hdmi->dev, "Support audio type: LPCM\n");
149                                 break;
150                         case HDMI_AUDIO_AC3:
151                                 hdmi_dbg(hdmi->dev, "Support audio type: AC3\n");
152                                 break;
153                         case HDMI_AUDIO_MPEG1:
154                                 hdmi_dbg(hdmi->dev, "Support audio type: MPEG1\n");
155                                 break;
156                         case HDMI_AUDIO_MP3:
157                                 hdmi_dbg(hdmi->dev, "Support audio type: MP3\n");
158                                 break;
159                         case HDMI_AUDIO_MPEG2:
160                                 hdmi_dbg(hdmi->dev, "Support audio type: MPEG2\n");
161                                 break;
162                         case HDMI_AUDIO_AAC_LC:
163                                 hdmi_dbg(hdmi->dev, "Support audio type: AAC\n");
164                                 break;
165                         case HDMI_AUDIO_DTS:
166                                 hdmi_dbg(hdmi->dev, "Support audio type: DTS\n");
167                                 break;
168                         case HDMI_AUDIO_ATARC:
169                                 hdmi_dbg(hdmi->dev, "Support audio type: ATARC\n");
170                                 break;
171                         case HDMI_AUDIO_DSD:
172                                 hdmi_dbg(hdmi->dev, "Support audio type: DSD\n");
173                                 break;
174                         case HDMI_AUDIO_E_AC3:
175                                 hdmi_dbg(hdmi->dev, "Support audio type: E-AC3\n");
176                                 break;
177                         case HDMI_AUDIO_DTS_HD:
178                                 hdmi_dbg(hdmi->dev, "Support audio type: DTS-HD\n");
179                                 break;
180                         case HDMI_AUDIO_MLP:
181                                 hdmi_dbg(hdmi->dev, "Support audio type: MLP\n");
182                                 break;
183                         case HDMI_AUDIO_DST:
184                                 hdmi_dbg(hdmi->dev, "Support audio type: DST\n");
185                                 break;
186                         case HDMI_AUDIO_WMA_PRO:
187                                 hdmi_dbg(hdmi->dev, "Support audio type: WMP-PRO\n");
188                                 break;
189                         default:
190                                 hdmi_dbg(hdmi->dev, "Support audio type: Unkown\n");
191                                 break;
192                 }
193                 
194                 hdmi_dbg(hdmi->dev, "Support audio sample rate: \n");
195                 if(audio->rate & HDMI_AUDIO_FS_32000)
196                         hdmi_dbg(hdmi->dev, "   32000\n");
197                 if(audio->rate & HDMI_AUDIO_FS_44100)
198                         hdmi_dbg(hdmi->dev, "   44100\n");
199                 if(audio->rate & HDMI_AUDIO_FS_48000)
200                         hdmi_dbg(hdmi->dev, "   48000\n");
201                 if(audio->rate & HDMI_AUDIO_FS_88200)
202                         hdmi_dbg(hdmi->dev, "   88200\n");
203                 if(audio->rate & HDMI_AUDIO_FS_96000)
204                         hdmi_dbg(hdmi->dev, "   96000\n");
205                 if(audio->rate & HDMI_AUDIO_FS_176400)
206                         hdmi_dbg(hdmi->dev, "   176400\n");
207                 if(audio->rate & HDMI_AUDIO_FS_192000)
208                         hdmi_dbg(hdmi->dev, "   192000\n");
209                 
210                 hdmi_dbg(hdmi->dev, "Support audio word lenght: \n");
211                 if(audio->rate & HDMI_AUDIO_WORD_LENGTH_16bit)
212                         hdmi_dbg(hdmi->dev, "   16bit\n");
213                 if(audio->rate & HDMI_AUDIO_WORD_LENGTH_20bit)
214                         hdmi_dbg(hdmi->dev, "   20bit\n");
215                 if(audio->rate & HDMI_AUDIO_WORD_LENGTH_24bit)
216                         hdmi_dbg(hdmi->dev, "   24bit\n");
217         }
218         hdmi_dbg(hdmi->dev, "******** Show Sink Info ********\n");
219 }
220
221 /**
222  * hdmi_ouputmode_select - select hdmi transmitter output mode: hdmi or dvi?
223  * @hdmi: handle of hdmi
224  * @edid_ok: get EDID data success or not, HDMI_ERROR_SUCESS means success.
225  */
226 int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
227 {
228         struct list_head *head = &hdmi->edid.modelist;
229         struct fb_monspecs      *specs = hdmi->edid.specs;
230         struct fb_videomode *modedb = NULL;
231         int i, pixclock;
232         
233         if(edid_ok != HDMI_ERROR_SUCESS) {
234                 dev_err(hdmi->dev, "warning: EDID error, assume sink as HDMI !!!!");
235                 hdmi->edid.sink_hdmi = 1;
236         }
237
238         if(edid_ok != HDMI_ERROR_SUCESS) {
239                 hdmi->edid.ycbcr444 = 0;
240                 hdmi->edid.ycbcr422 = 0;
241                 hdmi->autoconfig = HDMI_DISABLE;
242         }
243         if(head->next == head) {
244                 dev_info(hdmi->dev, "warning: no CEA video mode parsed from EDID !!!!");
245                 // If EDID get error, list all system supported mode.
246                 // If output mode is set to DVI and EDID is ok, check
247                 // the output timing.
248                 
249                 if(hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) {
250                         /* Get max resolution timing */
251                         modedb = &specs->modedb[0];
252                         for (i = 0; i < specs->modedb_len; i++) {
253                                 if(specs->modedb[i].xres > modedb->xres)
254                                         modedb = &specs->modedb[i];
255                                 else if(specs->modedb[i].yres > modedb->yres)
256                                         modedb = &specs->modedb[i];
257                         }
258                         // For some monitor, the max pixclock read from EDID is smaller
259                         // than the clock of max resolution mode supported. We fix it.
260                         pixclock = PICOS2KHZ(modedb->pixclock);
261                         pixclock /= 250;
262                         pixclock *= 250;
263                         pixclock *= 1000;
264                         if(pixclock == 148250000)
265                                 pixclock = 148500000;
266                         if(pixclock > specs->dclkmax)
267                                 specs->dclkmax = pixclock;
268                 }
269                 
270                 for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
271                         if(modedb) {
272                                 if( (hdmi_mode[i].pixclock < specs->dclkmin) || 
273                                         (hdmi_mode[i].pixclock > specs->dclkmax) || 
274                                         (hdmi_mode[i].refresh < specs->vfmin) ||
275                                         (hdmi_mode[i].refresh > specs->vfmax) ||
276                                         (hdmi_mode[i].xres > modedb->xres) ||
277                                         (hdmi_mode[i].yres > modedb->yres) )
278                                 continue;
279                         }
280                         hdmi_add_videomode(&hdmi_mode[i], head);
281                 }
282         }
283         
284         #ifdef HDMI_DEBUG
285         hdmi_show_sink_info(hdmi);
286         #endif
287         return HDMI_ERROR_SUCESS;
288 }
289 /**
290  * hdmi_videomode_compare - compare 2 videomodes
291  * @mode1: first videomode
292  * @mode2: second videomode
293  *
294  * RETURNS:
295  * 1 if mode1 > mode2, 0 if mode1 = mode2, -1 mode1 < mode2
296  */
297 static int hdmi_videomode_compare(const struct fb_videomode *mode1,
298                      const struct fb_videomode *mode2)
299 {
300         if(mode1->xres > mode2->xres)
301                 return 1;
302         else if(mode1->xres == mode2->xres)
303         { 
304                 if(mode1->yres > mode2->yres)
305                         return 1;
306                 else if(mode1->yres == mode2->yres)
307                 {
308                         if(mode1->pixclock > mode2->pixclock)   
309                                 return 1;
310                         else if(mode1->pixclock == mode2->pixclock)
311                         {       
312                                 if(mode1->refresh > mode2->refresh)
313                                         return 1;
314                                 else if(mode1->refresh == mode2->refresh) 
315                                         return 0;
316                         }
317                 }
318         }
319         return -1;              
320 }
321 /**
322  * hdmi_add_videomode: adds videomode entry to modelist
323  * @mode: videomode to add
324  * @head: struct list_head of modelist
325  *
326  * NOTES:
327  * Will only add unmatched mode entries
328  */
329 int hdmi_add_videomode(const struct fb_videomode *mode, struct list_head *head)
330 {
331         struct list_head *pos;
332         struct fb_modelist *modelist, *modelist_new;
333         struct fb_videomode *m;
334         int i, found = 0;
335
336         for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
337     {
338         m =(struct fb_videomode*) &hdmi_mode[i];
339         if (fb_mode_is_equal(m, mode)) {
340                         found = 1;
341                         break;
342                 }
343     }
344
345         if (found) {
346                 list_for_each(pos, head) {
347                         modelist = list_entry(pos, struct fb_modelist, list);
348                         m = &modelist->mode;
349                         if (fb_mode_is_equal(m, mode)) {
350                         // m == mode    
351                                 return 0;
352                         }
353                         else
354                         { 
355                                 if(hdmi_videomode_compare(m, mode) == -1) {
356                                         break;
357                                 }
358                         }
359                 }
360
361                 modelist_new = kmalloc(sizeof(struct fb_modelist),
362                                   GFP_KERNEL);                                  
363                 if (!modelist_new)
364                         return -ENOMEM; 
365                 modelist_new->mode = hdmi_mode[i];
366                 list_add_tail(&modelist_new->list, pos);
367         }
368         
369         return 0;
370 }
371
372 /**
373  * hdmi_videomode_to_vic: transverse video mode to vic
374  * @vmode: videomode to transverse
375  * 
376  */
377 int hdmi_videomode_to_vic(struct fb_videomode *vmode)
378 {
379         unsigned char vic = 0;
380         int i = 0;
381         
382         for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
383         {
384                 if(     vmode->vmode == hdmi_mode[i].vmode &&
385                         vmode->refresh == hdmi_mode[i].refresh &&
386                         vmode->xres == hdmi_mode[i].xres && 
387                         vmode->left_margin == hdmi_mode[i].left_margin &&
388                         vmode->right_margin == hdmi_mode[i].right_margin &&
389                         vmode->upper_margin == hdmi_mode[i].upper_margin &&
390                         vmode->lower_margin == hdmi_mode[i].lower_margin && 
391                         vmode->hsync_len == hdmi_mode[i].hsync_len && 
392                         vmode->vsync_len == hdmi_mode[i].vsync_len)
393                 {
394                         if( (vmode->vmode == FB_VMODE_NONINTERLACED && vmode->yres == hdmi_mode[i].yres) || 
395                                 (vmode->vmode == FB_VMODE_INTERLACED && vmode->yres == hdmi_mode[i].yres/2))
396                         {                                                               
397                                 vic = hdmi_mode[i].flag;
398                                 break;
399                         }
400                 }
401         }
402         return vic;
403 }
404
405 /**
406  * hdmi_vic_to_videomode: transverse vic mode to video mode
407  * @vmode: vic to transverse
408  * 
409  */
410 const struct fb_videomode* hdmi_vic_to_videomode(int vic)
411 {
412         int i;
413         
414         if(vic == 0)
415                 return NULL;
416         
417         for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
418         {
419                 if(hdmi_mode[i].flag == vic)
420                         return &hdmi_mode[i];
421         }
422         return NULL;
423 }
424
425 /**
426  * hdmi_find_best_mode: find the video mode nearest to input vic
427  * @hdmi: 
428  * @vic: input vic
429  * 
430  * NOTES:
431  * If vic is zero, return the high resolution video mode vic.
432  */
433 int hdmi_find_best_mode(struct hdmi* hdmi, int vic)
434 {
435         struct list_head *pos, *head = &hdmi->edid.modelist;
436         struct fb_modelist *modelist;
437         struct fb_videomode *m = NULL;
438         int found = 0;
439         
440         if(vic)
441         {
442                 list_for_each(pos, head) {
443                         modelist = list_entry(pos, struct fb_modelist, list);
444                         m = &modelist->mode;
445                         if(m->flag == vic)
446                         {
447                                 found = 1;      
448                                 break;
449                         }
450                 }
451         }
452         if( (vic == 0 || found == 0) && head->next != head)
453         {
454                 modelist = list_entry(head->next, struct fb_modelist, list);
455                 m = &modelist->mode;
456         }
457         if(m != NULL)
458                 return m->flag;
459         else
460                 return 0;
461 }
462
463 const char *hdmi_get_video_mode_name(unsigned char vic)
464 {
465         int i;
466         
467         for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
468         {
469                 if(vic == hdmi_mode[i].flag)
470                         break;
471         }
472         if(i == ARRAY_SIZE(hdmi_mode))
473                 return NULL;
474         else
475                 return hdmi_mode[i].name;
476 }
477
478 /**
479  * hdmi_switch_fb: switch lcdc mode to required video mode
480  * @hdmi: 
481  * @type:
482  * 
483  * NOTES:
484  * 
485  */
486 int hdmi_switch_fb(struct hdmi *hdmi, int vic)
487 {
488         int rc = 0;
489         struct layer_par *par = NULL;
490         struct rk_lcdc_device_driver * dev_drv;
491         struct rk29fb_screen *screen; 
492
493         if(hdmi->vic == 0)
494                 hdmi->vic = HDMI_VIDEO_DEFAULT_MODE;
495                 
496         if(hdmi->lcdc == NULL || hdmi->lcdc->screen == NULL) {
497                 dev_err(hdmi->dev, "lcdc %d not exist\n", HDMI_SOURCE_DEFAULT);
498                 return -1;
499         }
500
501         dev_drv = hdmi->lcdc;
502         screen = dev_drv->screen;
503         rc = hdmi_set_info(hdmi->lcdc->screen, vic);
504
505         if(rc == 0 &&  hdmi->lcdc->load_screen) {
506                 
507                 hdmi->lcdc->load_screen(hdmi->lcdc, 0);
508                 par = &dev_drv->layer_par[1];
509                 par->xsize = screen->x_res;
510         par->ysize = screen->y_res;
511                 hdmi->lcdc->set_par(hdmi->lcdc, 1);
512                 hdmi->lcdc->pan_display(hdmi->lcdc, 1);
513         }
514         return rc;
515 }