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