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