mfd:rk616:vif:fix rk616 set vif
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / rk616-vif.c
1 #include <linux/kernel.h>
2 #include <linux/init.h>
3 #include <linux/platform_device.h>
4 #include <linux/slab.h>
5 #include <linux/mfd/rk616.h>
6
7
8 extern int rk616_pll_set_rate(struct mfd_rk616 *rk616,int id,u32 cfg_val,u32 frac);
9
10 /*rk616 video interface config*/
11 int rk616_vif_cfg(struct mfd_rk616 *rk616,rk_screen *screen,int id)
12 {
13         int ret = 0;
14         u32 val = 0;
15         int offset = 0;
16         int pll_id;
17         bool pll_use_mclk12m = false;
18         
19         if(id == 0) //video interface 0
20         {
21                 if(!rk616->route.vif0_en)
22                 {
23                         val = (VIF0_EN << 16); //disable vif0
24                         ret = rk616->write_dev(rk616,VIF0_REG0,&val);
25                         clk_set_rate(rk616->mclk, 11289600);
26                         return 0;
27                 }
28                 offset = 0;
29                 pll_id = rk616->route.vif0_clk_sel;
30                 if(rk616->route.pll0_clk_sel == PLL0_CLK_SEL(MCLK_12M))
31                         pll_use_mclk12m = true;
32                 else
33                         pll_use_mclk12m = false;
34         }
35         else       //vide0 interface 1
36         {
37                 if(!rk616->route.vif1_en)
38                 {
39                         val = (VIF0_EN << 16); //disabl VIF1
40                         ret = rk616->write_dev(rk616,VIF1_REG0,&val);
41                         clk_set_rate(rk616->mclk, 11289600);
42                         return 0;
43                 }
44                 offset = 0x18;
45                 pll_id = (rk616->route.vif1_clk_sel >> 6);
46                 if(rk616->route.pll1_clk_sel == PLL1_CLK_SEL(MCLK_12M))
47                         pll_use_mclk12m = true;
48                 else
49                         pll_use_mclk12m = false;
50         }
51
52         if(pll_use_mclk12m)
53         {
54                 clk_set_rate(rk616->mclk, 12000000);
55         }
56
57         
58         if(!screen)
59         {
60                 dev_err(rk616->dev,"%s:screen is null.........\n",__func__);
61                 return -EINVAL;
62         }
63
64         
65         
66         val |= (VIF0_DDR_CLK_EN <<16) | (VIF0_DDR_PHASEN_EN << 16) | (VIF0_DDR_MODE_EN << 16)|
67                 (VIF0_EN <<16) | VIF0_EN; //disable ddr mode,enable VIF
68         
69         ret = rk616->write_dev(rk616,VIF0_REG0 + offset,&val);  
70
71         if( (screen->x_res == 1920) && (screen->y_res == 1080))
72         {
73                 if(pll_use_mclk12m)
74                         rk616_pll_set_rate(rk616,pll_id,0xc11025,0x200000);
75                 else
76                         rk616_pll_set_rate(rk616,pll_id,0x02bf5276,0);
77         }
78         else if((screen->x_res == 1280) && (screen->y_res == 720))
79         {
80                 if(pll_use_mclk12m)
81                         rk616_pll_set_rate(rk616,pll_id,0x01811025,0x200000);
82                 else
83                         rk616_pll_set_rate(rk616,pll_id,0x1422014,0);
84         }
85         else if((screen->x_res == 720))
86         {
87                 if(pll_use_mclk12m)
88                         rk616_pll_set_rate(rk616,pll_id,0x01413021,0xc00000);
89                 else
90                         rk616_pll_set_rate(rk616,pll_id,0x1c13015,0);
91         }
92
93         //val = fscreen->vif_hst | (fscreen->vif_vst<<16);
94         val = (0xc1) | (0x01 <<16);
95         ret = rk616->write_dev(rk616,VIF0_REG1 + offset,&val);
96
97         val = (screen->hsync_len << 16) | (screen->hsync_len + screen->left_margin + 
98                 screen->right_margin + screen->x_res);
99         ret = rk616->write_dev(rk616,VIF0_REG2 + offset,&val);
100
101         
102         val = ((screen->hsync_len + screen->left_margin + screen->x_res)<<16) |
103                 (screen->hsync_len + screen->left_margin);
104         ret = rk616->write_dev(rk616,VIF0_REG3 + offset,&val);
105
106         val = (screen->vsync_len << 16) | (screen->vsync_len + screen->upper_margin + 
107                 screen->lower_margin + screen->y_res);
108         ret = rk616->write_dev(rk616,VIF0_REG4 + offset,&val);
109
110
111         val = ((screen->vsync_len + screen->upper_margin + screen->y_res)<<16) |
112                 (screen->vsync_len + screen->upper_margin);
113         ret = rk616->write_dev(rk616,VIF0_REG5 + offset,&val);
114
115         dev_info(rk616->dev,"rk616 vif%d enable\n",id);
116         
117         return ret;
118         
119 }
120
121
122 static int rk616_vif_disable(struct mfd_rk616 *rk616,int id)
123 {
124         u32 val = 0;
125         int ret = 0;
126
127         printk(KERN_INFO "rk616 vif%d disable\n",id);
128         
129         if(id == 0) //video interface 0
130         {
131                 
132                         val = (VIF0_EN << 16); //disable vif0
133                         ret = rk616->write_dev(rk616,VIF0_REG0,&val);
134                         clk_set_rate(rk616->mclk, 11289600);
135                         return 0;
136                 
137         }
138         else       //vide0 interface 1
139         {
140                 
141                         val = (VIF0_EN << 16); //disabl VIF1
142                         ret = rk616->write_dev(rk616,VIF1_REG0,&val);
143                         clk_set_rate(rk616->mclk, 11289600);
144                         return 0;
145         }
146         
147         
148         return 0;
149 }
150 static int rk616_scaler_disable(struct mfd_rk616 *rk616)
151 {
152         u32 val = 0;
153         int ret;
154         val &= (~SCL_EN);       //disable scaler
155         val |= (SCL_EN<<16);
156         ret = rk616->write_dev(rk616,SCL_REG0,&val);
157         return 0;
158 }
159 int rk616_scaler_cfg(struct mfd_rk616 *rk616,rk_screen *screen)
160 {
161         u32 val = 0;
162         int ret = 0;
163         u32 scl_hor_mode,scl_ver_mode;
164         u32 scl_v_factor,scl_h_factor;
165         u32 scl_reg0_value,scl_reg1_value,scl_reg2_value;                //scl_con,scl_h_factor,scl_v_factor,
166         u32 scl_reg3_value,scl_reg4_value,scl_reg5_value,scl_reg6_value; //dsp_frame_hst,dsp_frame_vst,dsp_timing,dsp_act_timing
167         u32 scl_reg7_value,scl_reg8_value;                               //dsp_hbor ,dsp_vbor
168         u32 dst_frame_hst,dst_frame_vst;                    //ʱÐò»º´æ
169         u32 dst_htotal,dst_hs_end,dst_hact_st,dst_hact_end; //ÆÁÄ»typical h²ÎÊý
170         u32 dst_vtotal,dst_vs_end,dst_vact_st,dst_vact_end; //ÆÁÄ»typical v²ÎÊý
171
172         u32 dsp_htotal,dsp_hs_end,dsp_hact_st,dsp_hact_end; //scalerÊä³öµÄtiming²ÎÊý
173         u32 dsp_vtotal,dsp_vs_end,dsp_vact_st,dsp_vact_end; 
174         u32 dsp_hbor_end,dsp_hbor_st,dsp_vbor_end,dsp_vbor_st;
175         u32 src_w,src_h,src_htotal,src_vtotal,dst_w,dst_h,src_hact_st,src_vact_st;
176         u16 bor_right = 0;
177         u16 bor_left = 0;
178         u16 bor_up = 0;
179         u16 bor_down = 0;
180         u8 hor_down_mode = 0;  //1:average,0:bilinear
181         u8 ver_down_mode = 0;
182         u8 bic_coe_sel = 2;
183         rk_screen *src;
184         rk_screen *dst;
185         int pll_id;
186
187         struct rk616_route *route = &rk616->route;
188
189
190         if(!route->scl_en)
191         {
192                 rk616_scaler_disable(rk616);
193                 return 0;
194         }
195         
196         
197         dst = screen;
198         if(!dst)
199         {
200                 dev_err(rk616->dev,"%s:screen is null!\n",__func__);
201                 return -EINVAL;
202         }
203
204         if(route->scl_bypass)
205         {
206                 src = dst;
207                 dst->pll_cfg_val = 0x01422014;
208                 dst->frac = 0;
209         }
210         else
211                 src = screen->ext_screen;
212         
213         if(route->sclk_sel == SCLK_SEL(SCLK_SEL_PLL0))
214                 pll_id = 0;
215         else
216                 pll_id = 1;
217         rk616_pll_set_rate(rk616,pll_id,dst->pll_cfg_val,dst->frac);
218         dst_frame_vst = dst->scl_vst;
219         dst_frame_hst = dst->scl_hst;
220
221
222 #if 1
223
224         src_htotal = src->hsync_len + src->left_margin + src->x_res + src->right_margin;
225         src_vact_st = src->vsync_len + src->upper_margin  ;
226         dst_vact_st = dst->vsync_len + dst->upper_margin;
227
228         dsp_htotal    = dst->hsync_len + dst->left_margin + dst->x_res + dst->right_margin; //dst_htotal ;
229         dsp_hs_end    = dst->hsync_len;
230
231         dsp_vtotal    = dst->vsync_len + dst->upper_margin + dst->y_res + dst->lower_margin;
232         dsp_vs_end    = dst->vsync_len;
233
234         dsp_hbor_end  = dst->hsync_len + dst->left_margin + dst->x_res;
235         dsp_hbor_st   = dst->hsync_len + dst->left_margin  ;
236         dsp_vbor_end  = dst->vsync_len + dst->upper_margin + dst->y_res; //dst_vact_end ;
237         dsp_vbor_st   = dst_vact_st  ;
238
239         dsp_hact_st   = dsp_hbor_st  + bor_left;
240         dsp_hact_end  = dsp_hbor_end - bor_right; 
241         dsp_vact_st   = dsp_vbor_st  + bor_up;
242         dsp_vact_end  = dsp_vbor_end - bor_down; 
243
244         src_w = src->x_res;
245         src_h = src->y_res;
246         dst_w = dsp_hact_end - dsp_hact_st ;
247         dst_h = dsp_vact_end - dsp_vact_st ;
248
249         if(src_w > dst_w)         //ÅжÏhorµÄËõ·Åģʽ 0£ºno_scl 1£ºscl_up 2£ºscl_down
250         {
251                 scl_hor_mode = 0x2;   //scl_down
252                 if(hor_down_mode == 0)//bilinear
253                 {
254                         if((src_w-1)/(dst_w-1) > 2)
255                         {
256                                 scl_h_factor = ((src_w-1)<<14)/(dst_w-1);
257                         }
258                         else
259                                 scl_h_factor = ((src_w-2)<<14)/(dst_w-1);
260                 }
261                 else  //average
262                 {
263                         scl_h_factor = ((dst_w)<<16)/(src_w-1);
264                 }
265         }
266         else if(src_w == dst_w)
267         {
268                 scl_hor_mode = 0x0;   //no_Scl
269                 scl_h_factor = 0x0;
270         } 
271         else 
272         {
273                 scl_hor_mode = 0x1;   //scl_up
274                 scl_h_factor = ((src_w-1)<<16)/(dst_w-1);
275         } 
276     
277         if(src_h > dst_h)         //ÅжÏverµÄËõ·Åģʽ 0£ºno_scl 1£ºscl_up 2£ºscl_down
278         {
279                 scl_ver_mode = 0x2;   //scl_down
280                 if(ver_down_mode == 0)//bilinearhor_down_mode,u8 ver_down_mode
281                 {
282                         if((src_h-1)/(dst_h-1) > 2)
283                         {
284                                 scl_v_factor = ((src_h-1)<<14)/(dst_h-1);
285                         }
286                         else
287                                 scl_v_factor = ((src_h-2)<<14)/(dst_h-1);
288                 }
289                 else
290                 {
291                         scl_v_factor = ((dst_h)<<16)/(src_h-1);
292                 }
293         }
294         else if(src_h == dst_h)
295         {
296                 scl_ver_mode = 0x0;   //no_Scl
297                 scl_v_factor = 0x0;
298         }
299         else 
300         {
301                 scl_ver_mode = 0x1;   //scl_up
302                 scl_v_factor = ((src_h-1)<<16)/(dst_h-1);
303         }
304
305         //control   register0 
306         scl_reg0_value = (0x1ff<<16) | SCL_EN | (scl_hor_mode<<1) |
307                         (scl_ver_mode<<3) | (bic_coe_sel<<5) | 
308                         (hor_down_mode<<7) | (ver_down_mode<<8) ;
309         //factor    register1 
310         scl_reg1_value = (scl_v_factor << 16) | scl_h_factor ;
311         //dsp_frame register2 
312         scl_reg2_value = dst_frame_vst<<16 | dst_frame_hst ;
313         //dsp_h     register3
314         scl_reg3_value = dsp_hs_end<<16 | dsp_htotal ;
315         //dsp_hact  register4
316         scl_reg4_value = dsp_hact_end <<16 | dsp_hact_st ;
317         //dsp_v     register5
318         scl_reg5_value = dsp_vs_end<<16 | dsp_vtotal ;
319         //dsp_vact  register6
320         scl_reg6_value = dsp_vact_end<<16 | dsp_vact_st ;
321         //hbor      register7
322         scl_reg7_value = dsp_hbor_end<<16 | dsp_hbor_st ;
323         //vbor      register8
324         scl_reg8_value = dsp_vbor_end<<16 | dsp_vbor_st ;
325
326     
327         rk616->write_dev(rk616,SCL_REG0,&scl_reg0_value);  
328         rk616->write_dev(rk616,SCL_REG1,&scl_reg1_value);  
329         rk616->write_dev(rk616,SCL_REG2,&scl_reg2_value);  
330         rk616->write_dev(rk616,SCL_REG3,&scl_reg3_value);  
331         rk616->write_dev(rk616,SCL_REG4,&scl_reg4_value);  
332         rk616->write_dev(rk616,SCL_REG5,&scl_reg5_value);  
333         rk616->write_dev(rk616,SCL_REG6,&scl_reg6_value);  
334         rk616->write_dev(rk616,SCL_REG7,&scl_reg7_value);  
335         rk616->write_dev(rk616,SCL_REG8,&scl_reg8_value);  
336 #endif
337         return 0;
338         
339 }
340
341
342 static int rk616_dual_input_cfg(struct mfd_rk616 *rk616,rk_screen *screen,
343                                         bool enable)
344 {
345         struct rk616_platform_data *pdata = rk616->pdata;
346         struct rk616_route *route = &rk616->route;
347         
348         route->vif0_bypass = VIF0_CLK_BYPASS;
349         route->vif0_en     = 0;
350         route->vif0_clk_sel = VIF0_CLKIN_SEL(VIF_CLKIN_SEL_PLL0);
351         route->pll0_clk_sel = PLL0_CLK_SEL(LCD0_DCLK);
352         route->pll1_clk_sel = PLL1_CLK_SEL(MCLK_12M);
353         route->vif1_clk_sel = VIF1_CLKIN_SEL(VIF_CLKIN_SEL_PLL1);
354         route->hdmi_sel     = HDMI_IN_SEL(HDMI_CLK_SEL_VIF1);
355         if(enable)  //hdmi plug in
356         {
357                 route->vif1_bypass  = 0;
358                 route->vif1_en      = 1;
359                 
360         }
361         else  //hdmi plug out
362         {
363                 route->vif1_bypass = VIF1_CLK_BYPASS;
364                 route->vif1_en     = 0;
365         }
366
367         route->sclin_sel   = SCL_IN_SEL(SCL_SEL_VIF0); //from vif0
368         route->scl_en      = 0;            //dual lcdc, scaler not needed
369         route->dither_sel  = DITHER_IN_SEL(DITHER_SEL_VIF0); //dither from vif0
370         route->lcd1_input  = 1; 
371         
372
373         if(screen->type == SCREEN_RGB)
374         {
375                 route->lvds_en     = 1;
376                 route->lvds_mode   = RGB; //rgb output 
377         }
378         else if(screen->type == SCREEN_LVDS)
379         {
380                 route->lvds_en     = 1;
381                 route->lvds_mode = LVDS;
382                 route->lvds_ch_nr = pdata->lvds_ch_nr;
383         }
384         else if(screen->type == SCREEN_MIPI)
385         {
386                 route->lvds_en = 0;
387         }
388         else
389         {
390                 dev_err(rk616->dev,"un supported interface:%d\n",screen->type);
391                 return -EINVAL;
392         }
393
394         return 0;
395         
396 }
397
398 static int rk616_lcd0_input_lcd1_unused_cfg(struct mfd_rk616 *rk616,rk_screen *screen,
399                                                         bool enable)
400 {
401         struct rk616_platform_data *pdata = rk616->pdata;
402         struct rk616_route *route = &rk616->route;
403         
404         if(enable)  //hdmi plug in
405         {
406                 route->vif0_bypass  = 0;
407                 route->vif0_en      = 1;
408                 route->vif0_clk_sel = VIF0_CLKIN_SEL(VIF_CLKIN_SEL_PLL0);
409                 route->sclin_sel    = SCL_IN_SEL(SCL_SEL_VIF0); //from vif0
410                 route->scl_en       = 1;
411                 route->sclk_sel     = SCLK_SEL(SCLK_SEL_PLL1);
412                 route->dither_sel   = DITHER_IN_SEL(DITHER_SEL_SCL); //dither from sclaer
413                 route->hdmi_sel     = HDMI_IN_SEL(HDMI_CLK_SEL_VIF0);//from vif0
414                 
415         }
416         else
417         {
418                 route->vif0_bypass = VIF0_CLK_BYPASS;
419                 route->vif0_en     = 0;
420                 route->sclin_sel   = SCL_IN_SEL(SCL_SEL_VIF0); //from vif0
421                 route->scl_en      = 0;
422                 route->dither_sel  = DITHER_IN_SEL(DITHER_SEL_VIF0); //dither from sclaer
423                 route->hdmi_sel    = HDMI_IN_SEL(HDMI_CLK_SEL_VIF0);//from vif0
424         }
425         route->pll1_clk_sel = PLL1_CLK_SEL(LCD0_DCLK);
426         route->pll0_clk_sel = PLL0_CLK_SEL(LCD0_DCLK);
427         route->vif1_bypass = VIF1_CLK_BYPASS;
428         route->vif1_en     = 0;
429         route->lcd1_input  = 0;  
430         
431         if(screen->type == SCREEN_RGB)
432         {
433                 route->lvds_en     = 1;
434                 route->lvds_mode   = RGB; //rgb output 
435         }
436         else if(screen->type == SCREEN_LVDS)
437         {
438                 route->lvds_en     = 1;
439                 route->lvds_mode = LVDS;
440                 route->lvds_ch_nr = pdata->lvds_ch_nr;
441         }
442         else if(screen->type == SCREEN_MIPI)
443         {
444                 route->lvds_en = 0;
445         }
446         
447
448         return 0;
449 }
450
451
452 static int rk616_lcd0_input_lcd1_output_cfg(struct mfd_rk616 *rk616,rk_screen *screen,
453                                                         bool enable)
454 {
455         struct rk616_route *route = &rk616->route;
456
457         if(enable)
458         {
459                 route->vif0_bypass  = 0;
460                 route->vif0_en      = 1;
461                 route->vif0_clk_sel = VIF0_CLKIN_SEL(VIF_CLKIN_SEL_PLL0);
462                 route->sclin_sel    = SCL_IN_SEL(SCL_SEL_VIF0); //from vif0
463                 route->scl_en       = 1;
464                 route->sclk_sel     = SCLK_SEL(SCLK_SEL_PLL1);
465                 route->dither_sel   = DITHER_IN_SEL(DITHER_SEL_SCL); //dither from sclaer
466                 route->hdmi_sel     = HDMI_IN_SEL(HDMI_CLK_SEL_VIF0);//from vif0
467         }
468         else
469         {
470                 route->vif0_bypass = VIF0_CLK_BYPASS;
471                 route->vif0_en     = 0;
472                 route->sclin_sel   = SCL_IN_SEL(SCL_SEL_VIF0); //from vif0
473                 route->scl_en      = 0;
474                 route->dither_sel  = DITHER_IN_SEL(DITHER_SEL_VIF0); //dither from sclaer
475                 route->hdmi_sel    = HDMI_IN_SEL(HDMI_CLK_SEL_VIF0);//from vif0 
476         }
477         route->pll0_clk_sel = PLL0_CLK_SEL(LCD0_DCLK);
478         route->pll1_clk_sel = PLL1_CLK_SEL(LCD0_DCLK);
479         route->vif1_bypass = VIF1_CLK_BYPASS;
480         route->vif1_en = 0;
481         route->lcd1_input = 0; //lcd1 as out put
482         route->lvds_en  = 0;
483
484         return 0;
485         
486 }
487
488
489 static int rk616_lcd0_unused_lcd1_input_cfg(struct mfd_rk616 *rk616,rk_screen *screen,
490                                                         bool enable)
491 {
492         struct rk616_platform_data *pdata = rk616->pdata;
493         struct rk616_route *route = &rk616->route;
494
495         route->pll0_clk_sel = PLL0_CLK_SEL(LCD1_DCLK);
496         route->pll1_clk_sel = PLL1_CLK_SEL(LCD1_DCLK);
497         route->vif0_bypass = VIF0_CLK_BYPASS;
498         route->vif0_en     = 0;
499         if(enable)
500         {
501                 route->vif1_bypass = 0;
502                 route->vif1_en     = 1;
503                 route->scl_bypass  = 0;
504         }
505         else
506         {
507                 route->vif1_bypass = VIF1_CLK_BYPASS;
508                 route->vif1_en     = 0;
509                 route->scl_bypass = 1; //1:1 scaler
510         }
511         route->vif1_clk_sel = VIF1_CLKIN_SEL(VIF_CLKIN_SEL_PLL1);
512         route->sclin_sel   = SCL_IN_SEL(SCL_SEL_VIF1); //from vif1
513         route->scl_en      = 1;
514         route->sclk_sel    = SCLK_SEL(SCLK_SEL_PLL0);
515         
516         route->dither_sel  = DITHER_IN_SEL(DITHER_SEL_SCL); //dither from sclaer
517         route->hdmi_sel    = HDMI_IN_SEL(HDMI_CLK_SEL_VIF1); //from vif1
518         route->lcd1_input  = 1;  
519         if(screen->type == SCREEN_RGB)
520         {
521                 route->lvds_en     = 1;
522                 route->lvds_mode   = RGB; //rgb output 
523         }
524         else if(screen->type == SCREEN_LVDS)
525         {
526                 route->lvds_en = 1;
527                 route->lvds_mode = LVDS;
528                 route->lvds_ch_nr = pdata->lvds_ch_nr;
529         }
530         else if(screen->type == SCREEN_MIPI)
531         {
532                 route->lvds_en = 0;
533         }
534         else
535         {
536                 dev_err(rk616->dev,"un supported interface:%d\n",screen->type);
537                 return -EINVAL;
538         }
539
540         return 0;
541 }
542
543 int  rk616_set_router(struct mfd_rk616 *rk616,rk_screen *screen,bool enable)
544 {
545         struct rk616_platform_data *pdata = rk616->pdata;
546         int ret;
547
548         if((pdata->lcd0_func == INPUT) && (pdata->lcd1_func == INPUT))
549         {
550                 
551                 ret = rk616_dual_input_cfg(rk616,screen,enable);
552                 dev_info(rk616->dev,"rk616 use dual input for dual display!\n");
553         }
554         else if((pdata->lcd0_func == INPUT) && (pdata->lcd1_func == UNUSED))
555         {
556                 ret = rk616_lcd0_input_lcd1_unused_cfg(rk616,screen,enable);
557
558                 dev_info(rk616->dev,
559                         "rk616 use lcd0 as input and lvds/rgb "
560                         "port as output for dual display\n");
561         }
562         else if((pdata->lcd0_func == INPUT) && (pdata->lcd1_func == OUTPUT))
563         {
564                 ret = rk616_lcd0_input_lcd1_output_cfg(rk616,screen,enable);
565                 
566                 dev_info(rk616->dev,
567                         "rk616 use lcd0 as input and lcd1 as "
568                         "output for dual display\n");
569         }
570         else if((pdata->lcd0_func == UNUSED) && (pdata->lcd1_func == INPUT))
571         {
572                 ret = rk616_lcd0_unused_lcd1_input_cfg(rk616,screen,enable);
573                 dev_info(rk616->dev,
574                         "rk616 use lcd1 as input and lvds/rgb as "
575                         "output for dual display\n");
576         }
577         else
578         {
579                 dev_err(rk616->dev,
580                         "invalid configration,please check your"
581                         "rk616_platform_data setting in your board file!\n");
582                 return -EINVAL;
583         }
584
585         return ret ;
586         
587 }
588
589
590
591
592 static int rk616_router_cfg(struct mfd_rk616 *rk616)
593 {
594         u32 val;
595         int ret;
596         struct rk616_route *route = &rk616->route;
597         val = (route->pll0_clk_sel) | (route->pll1_clk_sel) |
598                 PLL1_CLK_SEL_MASK | PLL0_CLK_SEL_MASK; //pll1 clk from lcdc1_dclk,pll0 clk from lcdc0_dclk,mux_lcdx = lcdx_clk
599         ret = rk616->write_dev(rk616,CRU_CLKSEL0_CON,&val);
600         
601         val = (route->sclk_sel) | SCLK_SEL_MASK;
602         ret = rk616->write_dev(rk616,CRU_CLKSEL1_CON,&val);
603         
604         val = (SCL_IN_SEL_MASK) | (DITHER_IN_SEL_MASK) | (HDMI_IN_SEL_MASK) | 
605                 (VIF1_CLKIN_SEL_MASK) | (VIF0_CLKIN_SEL_MASK) | (VIF1_CLK_BYPASS << 16) | 
606                 (VIF0_CLK_BYPASS << 16) |(route->sclin_sel) | (route->dither_sel) | 
607                 (route->hdmi_sel) | (route->vif1_bypass) | (route->vif0_bypass) |
608                 (route->vif1_clk_sel)| (route->vif0_clk_sel); 
609         ret = rk616->write_dev(rk616,CRU_CLKSE2_CON,&val);
610
611         return ret;
612 }
613
614
615 int rk616_display_router_cfg(struct mfd_rk616 *rk616,rk_screen *screen,bool enable)
616 {
617         int ret;
618         rk_screen *hdmi_screen = screen->ext_screen;
619         ret = rk616_set_router(rk616,screen,enable);
620         if(ret < 0)
621                 return ret;
622         ret = rk616_router_cfg(rk616);
623         ret = rk616_vif_cfg(rk616,hdmi_screen,0);
624         ret = rk616_vif_cfg(rk616,hdmi_screen,1);
625         ret = rk616_scaler_cfg(rk616,screen);
626
627         return 0;
628         
629 }
630
631
632 int rk616_set_vif(struct mfd_rk616 *rk616,rk_screen *screen,bool connect)
633 {
634         struct rk616_platform_data *pdata;
635         if(!rk616)
636         {
637                 printk(KERN_ERR "%s:mfd rk616 is null!\n",__func__);
638                 return -1;
639         }
640         else
641         {
642                 pdata = rk616->pdata;
643         }
644
645         if(!connect)
646         {
647                 rk616_vif_disable(rk616,0);
648                 rk616_vif_disable(rk616,1);
649                 return 0;
650         }
651 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
652         return 0;
653 #else
654         if((pdata->lcd0_func == INPUT) && (pdata->lcd1_func == INPUT))
655         {
656                 
657                 rk616_dual_input_cfg(rk616,screen,connect);
658                 dev_info(rk616->dev,"rk616 use dual input for dual display!\n");
659         }
660         else if((pdata->lcd0_func == INPUT) && (pdata->lcd1_func == UNUSED))
661         {
662                 rk616_lcd0_input_lcd1_unused_cfg(rk616,screen,connect);
663                 dev_info(rk616->dev,"rk616 use lcd0 input for hdmi display!\n");
664         }
665         rk616_router_cfg(rk616);
666         rk616_vif_cfg(rk616,screen,0);
667         rk616_vif_cfg(rk616,screen,1);
668         rk616_scaler_disable(rk616);
669 #endif
670         
671         return 0;
672         
673         
674 }
675
676
677
678