b35c551c7598e88bdd48e846f3277fec8b4f3933
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3188_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk3188_lcdc.c
3  *
4  * Copyright (C) 2013 ROCKCHIP, Inc.
5  *Author:yxj<yxj@rock-chips.com>
6  *This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
21 #include <linux/mm.h>
22 #include <linux/slab.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/platform_device.h>
28 #include <linux/clk.h>
29 #include <linux/earlysuspend.h>
30 #include <asm/div64.h>
31 #include <asm/uaccess.h>
32 #include <mach/iomux.h>
33 #include "../hdmi/rk_hdmi.h"
34 #include "rk3188_lcdc.h"
35
36
37
38 static int dbg_thresd = 0;
39 module_param(dbg_thresd, int, S_IRUGO|S_IWUSR);
40 #define DBG(level,x...) do {                    \
41         if(unlikely(dbg_thresd >= level))       \
42                 printk(KERN_INFO x);} while (0)
43
44 //#define WAIT_FOR_SYNC 1
45
46 static int rk3188_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initscreen);
47 static int  rk3188_lcdc_clk_enable(struct rk3188_lcdc_device *lcdc_dev)
48 {
49
50         clk_enable(lcdc_dev->hclk);
51         clk_enable(lcdc_dev->dclk);
52         clk_enable(lcdc_dev->aclk);
53         clk_enable(lcdc_dev->pd);
54
55         spin_lock(&lcdc_dev->reg_lock);
56         lcdc_dev->clk_on = 1;
57         spin_unlock(&lcdc_dev->reg_lock);
58         printk("rk3188 lcdc%d clk enable...\n",lcdc_dev->id);
59         
60         return 0;
61 }
62
63 static int rk3188_lcdc_clk_disable(struct rk3188_lcdc_device *lcdc_dev)
64 {
65         spin_lock(&lcdc_dev->reg_lock);
66         lcdc_dev->clk_on = 0;
67         spin_unlock(&lcdc_dev->reg_lock);
68
69         clk_disable(lcdc_dev->dclk);
70         clk_disable(lcdc_dev->hclk);
71         clk_disable(lcdc_dev->aclk);
72         clk_disable(lcdc_dev->pd);
73         printk("rk3188 lcdc%d clk disable...\n",lcdc_dev->id);
74         
75         return 0;
76 }
77
78
79
80 static void rk3188_lcdc_reg_dump(struct rk3188_lcdc_device *lcdc_dev)
81 {
82        int *cbase =  (int *)lcdc_dev->regs;
83        int *regsbak = (int*)lcdc_dev->regsbak;
84        int i,j;
85
86        printk("back up reg:\n");
87        for(i=0; i<=(0x90>>4);i++)
88        {
89                for(j=0;j<4;j++)
90                        printk("%08x  ",*(regsbak+i*4 +j));
91                printk("\n");
92        }
93
94        printk("lcdc reg:\n");
95        for(i=0; i<=(0x90>>4);i++)
96        {
97                for(j=0;j<4;j++)
98                        printk("%08x  ",readl_relaxed(cbase+i*4 +j));
99                printk("\n");
100        }
101        
102 }
103
104
105 static int rk3188_lcdc_reg_resume(struct rk3188_lcdc_device *lcdc_dev)
106 {
107         memcpy((u8*)lcdc_dev->regs, (u8*)lcdc_dev->regsbak, 0x84);
108         return 0;       
109 }
110
111
112 //enable layer,open:1,enable;0 disable
113 static int win0_open(struct rk3188_lcdc_device *lcdc_dev,bool open)
114 {
115         spin_lock(&lcdc_dev->reg_lock);
116         if(likely(lcdc_dev->clk_on))
117         {
118                 if(open)
119                 {
120                         if(!lcdc_dev->atv_layer_cnt)
121                         {
122                                 printk(KERN_INFO "lcdc%d wakeup from standby!\n",lcdc_dev->id);
123                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
124                         }
125                         lcdc_dev->atv_layer_cnt++;
126                 }
127                 else if((lcdc_dev->atv_layer_cnt > 0) && (!open))
128                 {
129                         lcdc_dev->atv_layer_cnt--;
130                 }
131                 lcdc_dev->driver.layer_par[0]->state = open;
132
133                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN, v_WIN0_EN(open));
134                 if(!lcdc_dev->atv_layer_cnt)  //if no layer used,disable lcdc
135                 {
136                         printk(KERN_INFO "no layer of lcdc%d is used,go to standby!\n",lcdc_dev->id);
137                         lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
138                 }
139                 //lcdc_cfg_done(lcdc_dev);      
140         }
141         spin_unlock(&lcdc_dev->reg_lock);
142
143
144         return 0;
145 }
146
147 static int win1_open(struct rk3188_lcdc_device *lcdc_dev,bool open)
148 {
149         spin_lock(&lcdc_dev->reg_lock);
150         if(likely(lcdc_dev->clk_on))
151         {
152                 if(open)
153                 {
154                         if(!lcdc_dev->atv_layer_cnt)
155                         {
156                                 printk(KERN_INFO "lcdc%d wakeup from standby!\n",lcdc_dev->id);
157                                 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
158                         }
159                         lcdc_dev->atv_layer_cnt++;
160                 }
161                 else if((lcdc_dev->atv_layer_cnt > 0) && (!open))
162                 {
163                         lcdc_dev->atv_layer_cnt--;
164                 }
165                 lcdc_dev->driver.layer_par[1]->state = open;
166                 
167                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN, v_WIN1_EN(open));
168                 if(!lcdc_dev->atv_layer_cnt)  //if no layer used,disable lcdc
169                 {
170                         printk(KERN_INFO "no layer of lcdc%d is used,go to standby!\n",lcdc_dev->id);
171                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
172                         lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
173                 }
174                 //lcdc_cfg_done(lcdc_dev);
175         }
176         spin_unlock(&lcdc_dev->reg_lock);
177         
178         return 0;
179 }
180
181 static int rk3188_lcdc_open(struct rk_lcdc_device_driver *dev_drv,int layer_id,bool open)
182 {
183         int i=0;
184         int __iomem *c;
185         int v;
186         struct rk3188_lcdc_device *lcdc_dev = 
187                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
188
189         if((open) && (!lcdc_dev->atv_layer_cnt)) //enable clk,when first layer open
190         {
191                 rk3188_lcdc_clk_enable(lcdc_dev);
192                 rk3188_lcdc_reg_resume(lcdc_dev); //resume reg
193                 rk3188_load_screen(dev_drv,1);
194                 spin_lock(&lcdc_dev->reg_lock);
195                 if(dev_drv->cur_screen->dsp_lut)                        //resume dsp lut
196                 {
197                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(0));
198                         lcdc_cfg_done(lcdc_dev);
199                         mdelay(25); //wait for dsp lut disabled
200                         for(i=0;i<256;i++)
201                         {
202                                 v = dev_drv->cur_screen->dsp_lut[i];
203                                 c = lcdc_dev->dsp_lut_addr_base+i;
204                                 writel_relaxed(v,c);
205
206                         }
207                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(1)); //enable dsp lut
208                 }
209                 spin_unlock(&lcdc_dev->reg_lock);
210         }
211
212         if(layer_id == 0)
213         {
214                 win0_open(lcdc_dev,open);       
215         }
216         else if(layer_id == 1)
217         {
218                 win1_open(lcdc_dev,open);
219         }
220         else 
221         {
222                 printk("invalid win number:%d\n",layer_id);
223         }
224
225         if((!open) && (!lcdc_dev->atv_layer_cnt))  //when all layer closed,disable clk
226         {
227                 rk3188_lcdc_clk_disable(lcdc_dev);
228         }
229
230         printk(KERN_INFO "lcdc%d win%d %s,atv layer:%d\n",
231                 lcdc_dev->id,layer_id,open?"open":"closed",
232                 lcdc_dev->atv_layer_cnt);
233         return 0;
234 }
235
236 static int rk3188_lcdc_init(struct rk_lcdc_device_driver *dev_drv)
237 {
238         int i = 0;
239         int __iomem *c;
240         int v;
241         struct rk3188_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3188_lcdc_device,driver);
242         if(lcdc_dev->id == 0) //lcdc0
243         {
244                 lcdc_dev->pd    = clk_get(NULL,"pd_lcdc0");
245                 lcdc_dev->hclk  = clk_get(NULL,"hclk_lcdc0"); 
246                 lcdc_dev->aclk  = clk_get(NULL,"aclk_lcdc0");
247                 lcdc_dev->dclk  = clk_get(NULL,"dclk_lcdc0");
248         }
249         else if(lcdc_dev->id == 1)
250         {
251                 lcdc_dev->pd    = clk_get(NULL,"pd_lcdc1");
252                 lcdc_dev->hclk  = clk_get(NULL,"hclk_lcdc1");  
253                 lcdc_dev->aclk  = clk_get(NULL,"aclk_lcdc1");
254                 lcdc_dev->dclk  = clk_get(NULL,"dclk_lcdc1");
255         }
256         else
257         {
258                 printk(KERN_ERR "invalid lcdc device!\n");
259                 return -EINVAL;
260         }
261         if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||(IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk)))
262         {
263                 printk(KERN_ERR "failed to get lcdc%d clk source\n",lcdc_dev->id);
264         }
265         
266         rk3188_lcdc_clk_enable(lcdc_dev);
267
268         if(lcdc_dev->id == 0)
269         {
270                 #if defined(CONFIG_LCDC0_IO_18V)
271                 v = 0x40004000;               //bit14: 1,1.8v;0,3.3v
272                 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
273                 #else
274                 v = 0x40000000;              
275                 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
276                 #endif
277         }
278
279         if(lcdc_dev->id == 1) //iomux for lcdc1
280         {
281                 #if defined(CONFIG_LCDC1_IO_18V)
282                 v = 0x80008000;               //bit14: 1,1.8v;0,3.3v
283                 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
284                 #else
285                 v = 0x80000000;
286                 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
287                 #endif
288                 iomux_set(LCDC1_DCLK);
289                 iomux_set(LCDC1_DEN);
290                 iomux_set(LCDC1_HSYNC);
291                 iomux_set(LCDC1_VSYNC);
292                 iomux_set(LCDC1_D0);
293                 iomux_set(LCDC1_D1);
294                 iomux_set(LCDC1_D2);
295                 iomux_set(LCDC1_D3);
296                 iomux_set(LCDC1_D4);
297                 iomux_set(LCDC1_D5);
298                 iomux_set(LCDC1_D6);
299                 iomux_set(LCDC1_D7);
300                 iomux_set(LCDC1_D8);
301                 iomux_set(LCDC1_D9);
302                 iomux_set(LCDC1_D10);
303                 iomux_set(LCDC1_D11);
304                 iomux_set(LCDC1_D12);
305                 iomux_set(LCDC1_D13);
306                 iomux_set(LCDC1_D14);
307                 iomux_set(LCDC1_D15);
308                 iomux_set(LCDC1_D16);
309                 iomux_set(LCDC1_D17);
310                 iomux_set(LCDC1_D18);
311                 iomux_set(LCDC1_D19);
312                 iomux_set(LCDC1_D20);
313                 iomux_set(LCDC1_D21);
314                 iomux_set(LCDC1_D22);
315                 iomux_set(LCDC1_D23);
316                 
317         }
318         lcdc_set_bit(lcdc_dev,SYS_CTRL,m_AUTO_GATING_EN);//eanble axi-clk auto gating for low power
319         //lcdc_set_bit(lcdc_dev,DSP_CTRL0,m_WIN0_TOP);
320         if(dev_drv->cur_screen->dsp_lut)
321         {
322                 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(0));
323                 lcdc_cfg_done(lcdc_dev);
324                 msleep(25);
325                 for(i=0;i<256;i++)
326                 {
327                         v = dev_drv->cur_screen->dsp_lut[i];
328                         c = lcdc_dev->dsp_lut_addr_base+i;
329                         writel_relaxed(v,c);
330                         
331                 }
332                 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(1));
333         }
334         
335         lcdc_cfg_done(lcdc_dev);  // write any value to  REG_CFG_DONE let config become effective
336
337         rk3188_lcdc_clk_disable(lcdc_dev);
338         
339         return 0;
340 }
341
342
343 static void rk3188_lcdc_deint(struct rk3188_lcdc_device * lcdc_dev)
344 {
345         spin_lock(&lcdc_dev->reg_lock);
346         if(likely(lcdc_dev->clk_on))
347         {
348                 lcdc_dev->clk_on = 0;
349                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
350                 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_HS_INT_EN | m_FS_INT_EN | 
351                         m_LF_INT_EN | m_BUS_ERR_INT_EN,v_HS_INT_EN(0) | v_FS_INT_EN(0) | 
352                         v_LF_INT_EN(0) | v_BUS_ERR_INT_EN(0));  //disable all lcdc interrupt
353                 lcdc_set_bit(lcdc_dev,SYS_CTRL,m_LCDC_STANDBY);
354                 lcdc_cfg_done(lcdc_dev);
355                 spin_unlock(&lcdc_dev->reg_lock);
356         }
357         else   //clk already disabled 
358         {
359                 spin_unlock(&lcdc_dev->reg_lock);
360                 return 0;
361         }
362         mdelay(1);
363         
364 }
365
366 //set lcdc according the screen info
367 static int rk3188_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initscreen)
368 {
369         int ret = -EINVAL;
370         int fps;
371         u16 face = 0;
372         struct rk3188_lcdc_device *lcdc_dev = 
373                                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
374         rk_screen *screen = dev_drv->cur_screen;
375         u16 right_margin = screen->right_margin;
376         u16 left_margin = screen->left_margin;
377         u16 lower_margin = screen->lower_margin;
378         u16 upper_margin = screen->upper_margin;
379         u16 x_res = screen->x_res;
380         u16 y_res = screen->y_res;
381
382         spin_lock(&lcdc_dev->reg_lock);
383         if(likely(lcdc_dev->clk_on))
384         {
385                 if(screen->type==SCREEN_MCU)
386                 {
387                         printk("MUC¡¡screen not supported now!\n");
388                         return -EINVAL;
389                 }
390
391                 switch (screen->face)
392                 {
393                 case OUT_P565:
394                         face = OUT_P565;  //dither down to rgb565
395                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
396                                  m_DITHER_DOWN_SEL,v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
397                                  v_DITHER_DOWN_SEL(1));
398                         break;
399                 case OUT_P666:
400                         face = OUT_P666; //dither down to rgb666
401                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
402                                 m_DITHER_DOWN_SEL, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
403                                 v_DITHER_DOWN_SEL(1));
404                         break;
405                 case OUT_D888_P565:
406                         face = OUT_P888;
407                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
408                                 m_DITHER_DOWN_SEL, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
409                                 v_DITHER_DOWN_SEL(1));
410                         break;
411                 case OUT_D888_P666:
412                         face = OUT_P888;
413                         lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
414                                 m_DITHER_DOWN_SEL, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
415                                 v_DITHER_DOWN_SEL(1));
416                         break;
417                 case OUT_P888:
418                         face = OUT_P888;
419                         break;
420                 default:
421                         printk("unsupported display output interface!\n");
422                         break;
423                 }
424
425                 //use default overlay,set vsyn hsync den dclk polarity
426                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
427                              m_DEN_POL |m_DCLK_POL,v_DSP_OUT_FORMAT(face) | v_HSYNC_POL(screen->pin_hsync) | 
428                              v_VSYNC_POL(screen->pin_vsync) | v_DEN_POL(screen->pin_den) | v_DCLK_POL(screen->pin_dclk));
429
430                 
431                 //set background color to black,set swap according to the screen panel,disable blank mode
432                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BG_COLOR| m_DSP_BG_SWAP | m_DSP_RB_SWAP | 
433                              m_DSP_RG_SWAP | m_DSP_DELTA_SWAP | m_DSP_DUMMY_SWAP | m_BLANK_EN,
434                              v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) | 
435                              v_DSP_RB_SWAP(screen->swap_rb) | v_DSP_RG_SWAP(screen->swap_rg) | 
436                              v_DSP_DELTA_SWAP(screen->swap_delta) | v_DSP_DUMMY_SWAP(screen->swap_dumy) |
437                              v_BLANK_EN(0) | v_BLACK_EN(0));
438                 lcdc_writel(lcdc_dev,DSP_HTOTAL_HS_END,v_HSYNC(screen->hsync_len) |
439                             v_HORPRD(screen->hsync_len + left_margin + x_res + right_margin));
440                 lcdc_writel(lcdc_dev,DSP_HACT_ST_END,v_HAEP(screen->hsync_len + left_margin + x_res) |
441                             v_HASP(screen->hsync_len + left_margin));
442
443                 lcdc_writel(lcdc_dev,DSP_VTOTAL_VS_END, v_VSYNC(screen->vsync_len) |
444                             v_VERPRD(screen->vsync_len + upper_margin + y_res + lower_margin));
445                 lcdc_writel(lcdc_dev,DSP_VACT_ST_END,v_VAEP(screen->vsync_len + upper_margin+y_res)|
446                             v_VASP(screen->vsync_len + screen->upper_margin));
447         }
448         spin_unlock(&lcdc_dev->reg_lock);
449
450         ret = clk_set_rate(lcdc_dev->dclk, screen->pixclock);
451         if(ret)
452         {
453                 dev_err(dev_drv->dev,"set lcdc%d dclk failed\n",lcdc_dev->id);
454         }
455         lcdc_dev->driver.pixclock = lcdc_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
456         
457         fps = rk_fb_calc_fps(screen,lcdc_dev->pixclock);
458         screen->ft = 1000/fps;
459         printk("%s: dclk:%lu>>fps:%d ",lcdc_dev->driver.name,clk_get_rate(lcdc_dev->dclk),fps);
460
461         if(screen->init)
462         {
463                 screen->init();
464         }
465
466         if(screen->sscreen_set)
467         {
468                 screen->sscreen_set(screen,!initscreen);
469         }
470         
471         dev_info(dev_drv->dev,"%s for lcdc%d ok!\n",__func__,lcdc_dev->id);
472         return 0;
473 }
474
475
476 static  int win0_set_par(struct rk3188_lcdc_device *lcdc_dev,rk_screen *screen,
477                             struct layer_par *par )
478 {
479         u32 xact, yact, xvir, yvir, xpos, ypos;
480         u32 ScaleYrgbX = 0x1000;
481         u32 ScaleYrgbY = 0x1000;
482         u32 ScaleCbrX = 0x1000;
483         u32 ScaleCbrY = 0x1000;
484         u8 fmt_cfg =0 ; //data format register config value
485         
486         xact = par->xact;                           //active (origin) picture window width/height               
487         yact = par->yact;
488         xvir = par->xvir;                          // virtual resolution                
489         yvir = par->yvir;
490         xpos = par->xpos+screen->left_margin + screen->hsync_len;
491         ypos = par->ypos+screen->upper_margin + screen->vsync_len;
492
493         
494         ScaleYrgbX = CalScale(xact, par->xsize); //both RGB and yuv need this two factor
495         ScaleYrgbY = CalScale(yact, par->ysize);
496         switch (par->format)
497         {
498         case ARGB888:
499         case XBGR888:
500         case ABGR888:
501                 fmt_cfg = 0;
502                 break;
503         case RGB888:
504                 fmt_cfg = 1;
505                 break;
506         case RGB565:
507                 fmt_cfg = 2;
508                 break;
509         case YUV422:// yuv422
510                 fmt_cfg = 5;
511                 ScaleCbrX = CalScale((xact/2), par->xsize);
512                 ScaleCbrY = CalScale(yact, par->ysize);
513                 break;
514         case YUV420: // yuv420
515                 fmt_cfg = 4;
516                 ScaleCbrX = CalScale(xact/2, par->xsize);
517                 ScaleCbrY = CalScale(yact/2, par->ysize);
518                 break;
519         case YUV444:// yuv444
520                 fmt_cfg = 6;
521                 ScaleCbrX = CalScale(xact, par->xsize);
522                 ScaleCbrY = CalScale(yact, par->ysize);
523                 break;
524         default:
525                 dev_err(lcdc_dev->driver.dev,"%s:un supported format!\n",__func__);
526                 break;
527         }
528
529         DBG(1,"%s for lcdc%d>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
530                 __func__,lcdc_dev->id,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
531         
532         spin_lock(&lcdc_dev->reg_lock);
533         if(likely(lcdc_dev->clk_on))
534         {
535                 lcdc_writel(lcdc_dev,WIN0_SCL_FACTOR_YRGB,v_X_SCL_FACTOR(ScaleYrgbX) | v_Y_SCL_FACTOR(ScaleYrgbY));
536                 lcdc_writel(lcdc_dev,WIN0_SCL_FACTOR_CBR,v_X_SCL_FACTOR(ScaleCbrX) | v_Y_SCL_FACTOR(ScaleCbrY));
537                 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_FORMAT,v_WIN0_FORMAT(fmt_cfg));           //(inf->video_mode==0)
538                 lcdc_writel(lcdc_dev,WIN0_ACT_INFO,v_ACT_WIDTH(xact) | v_ACT_HEIGHT(yact));
539                 lcdc_writel(lcdc_dev,WIN0_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
540                 lcdc_writel(lcdc_dev,WIN0_DSP_INFO,v_DSP_WIDTH(par->xsize) | v_DSP_HEIGHT(par->ysize));
541                 lcdc_msk_reg(lcdc_dev,WIN0_COLOR_KEY,m_COLOR_KEY_EN,v_COLOR_KEY_EN(0));
542                 
543                 switch(par->format) 
544                 {
545                 case XBGR888:
546                         lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_ARGB888_VIRWIDTH(xvir));
547                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
548                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(1));
549                         break;
550                 case ABGR888:
551                         lcdc_msk_reg(lcdc_dev,WIN_VIR,m_WIN0_VIR,v_ARGB888_VIRWIDTH(xvir));
552                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(1));
553                         lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 |
554                                 m_ALPHA_MODE_SEL1,v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) |
555                                 v_ALPHA_MODE_SEL1(0));//default set to per-pixel alpha
556                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(1));
557                         break;
558                 case ARGB888:
559                         lcdc_msk_reg(lcdc_dev,WIN_VIR,m_WIN0_VIR,v_ARGB888_VIRWIDTH(xvir));
560                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(1));
561                         lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0,
562                                 v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1));//default set to per-pixel alpha
563                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
564                         break;
565                 case RGB888:  //rgb888
566                         lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_RGB888_VIRWIDTH(xvir));
567                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
568                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
569                         break;
570                 case RGB565:  //rgb565
571                         lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_RGB565_VIRWIDTH(xvir));
572                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
573                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
574                         break;
575                 case YUV422:
576                 case YUV420:
577                 case YUV444:
578                         lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_YUV_VIRWIDTH(xvir));
579                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
580                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
581                         break;
582                 default:
583                         dev_err(lcdc_dev->driver.dev,"%s:un supported format!\n",__func__);
584                         break;
585                 }
586
587         }
588         spin_unlock(&lcdc_dev->reg_lock);
589
590     return 0;
591
592 }
593
594 static int win1_set_par(struct rk3188_lcdc_device *lcdc_dev,rk_screen *screen,
595                            struct layer_par *par )
596 {
597         u32 xact, yact, xvir, yvir, xpos, ypos;
598         u8 fmt_cfg;
599
600         xact = par->xact;                       
601         yact = par->yact;
602         xvir = par->xvir;               
603         yvir = par->yvir;
604         xpos = par->xpos+screen->left_margin + screen->hsync_len;
605         ypos = par->ypos+screen->upper_margin + screen->vsync_len;
606
607         
608         DBG(1,"%s for lcdc%d>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
609                 __func__,lcdc_dev->id,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
610
611         
612         spin_lock(&lcdc_dev->reg_lock);
613         if(likely(lcdc_dev->clk_on))
614         {
615                 
616                 lcdc_writel(lcdc_dev, WIN1_DSP_INFO,v_DSP_WIDTH(par->xsize) | v_DSP_HEIGHT(par->ysize));
617                 lcdc_writel(lcdc_dev, WIN1_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
618                 // disable win1 color key and set the color to black(rgb=0)
619                 lcdc_msk_reg(lcdc_dev, WIN1_COLOR_KEY,m_COLOR_KEY_EN,v_COLOR_KEY_EN(0));
620                 switch(par->format)
621                 {
622                 case XBGR888:
623                         fmt_cfg = 0;
624                         lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_ARGB888_VIRWIDTH(xvir));
625                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(0));
626                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(1));
627                         break;
628                 case ABGR888:
629                         fmt_cfg = 0;
630                         lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_ARGB888_VIRWIDTH(xvir));
631                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(1));
632                         lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0,
633                                 v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1));//default set to per-pixel alpha
634                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(1));
635                         break;
636                 case ARGB888:
637                         fmt_cfg = 0;
638                         lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_ARGB888_VIRWIDTH(xvir));
639                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(1));
640                         lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0,
641                                 v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1));//default set to per-pixel alpha
642                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(0));
643                         break;
644                 case RGB888:  //rgb888
645                         fmt_cfg = 1;
646                         lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_RGB888_VIRWIDTH(xvir));
647                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(0));
648                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(0));
649                         //lcdc_msk_reg(lcdc_dev,SYS_CTRL1,m_W1_RGB_RB_SWAP,v_W1_RGB_RB_SWAP(1));
650                         break;
651                 case RGB565:  //rgb565
652                         fmt_cfg = 2;
653                         lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_RGB565_VIRWIDTH(xvir));
654                         lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(0));
655                         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(0));
656                         break;
657                 default:
658                         dev_err(lcdc_dev->driver.dev,"%s:un supported format!\n",__func__);
659                         break;
660                 }
661                 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_FORMAT, v_WIN1_FORMAT(fmt_cfg));
662
663         }
664         spin_unlock(&lcdc_dev->reg_lock);
665
666         return 0;
667 }
668
669
670 static int rk3188_lcdc_set_par(struct rk_lcdc_device_driver *dev_drv,int layer_id)
671 {
672         struct rk3188_lcdc_device *lcdc_dev = 
673                         container_of(dev_drv,struct rk3188_lcdc_device,driver);
674         struct layer_par *par = NULL;
675         rk_screen *screen = dev_drv->cur_screen;
676
677         if(!screen)
678         {
679                 dev_err(dev_drv->dev,"screen is null!\n");
680                 return -ENOENT;
681         }
682         if(layer_id==0)
683         {
684                 par = dev_drv->layer_par[0];
685                 win0_set_par(lcdc_dev,screen,par);
686         }
687         else if(layer_id==1)
688         {
689                 par = dev_drv->layer_par[1];
690                 win1_set_par(lcdc_dev,screen,par);
691         }
692         else
693         {
694                 dev_err(dev_drv->dev,"unsupported win number:%d\n",layer_id);
695                 return -EINVAL;
696         }
697         
698         return 0;
699 }
700
701 static  int win0_display(struct rk3188_lcdc_device *lcdc_dev,struct layer_par *par )
702 {
703         u32 y_addr;
704         u32 uv_addr;
705         y_addr = par->smem_start + par->y_offset;
706         uv_addr = par->cbr_start + par->c_offset;
707         DBG(2,KERN_INFO "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);
708
709         spin_lock(&lcdc_dev->reg_lock);
710         if(likely(lcdc_dev->clk_on))
711         {
712                 lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, y_addr);
713                 lcdc_writel(lcdc_dev, WIN0_CBR_MST0, uv_addr);  
714  #if defined(CONFIG_RK_HDMI)
715  #if defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL)
716         if(lcdc_dev->driver.screen_ctr_info->prop == EXTEND)
717         {
718             if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
719             {
720                 lcdc_cfg_done(lcdc_dev);
721             }
722         }
723  #endif 
724  #endif
725         }
726         spin_unlock(&lcdc_dev->reg_lock);
727
728         return 0;
729         
730 }
731
732 static  int win1_display(struct rk3188_lcdc_device *lcdc_dev,struct layer_par *par )
733 {
734         u32 y_addr;
735         u32 uv_addr;
736         y_addr = par->smem_start + par->y_offset;
737         uv_addr = par->cbr_start + par->c_offset;
738         DBG(2,KERN_INFO "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);
739
740         spin_lock(&lcdc_dev->reg_lock);
741         if(likely(lcdc_dev->clk_on))
742         {
743                 lcdc_writel(lcdc_dev,WIN1_MST,y_addr);
744  #if defined(CONFIG_RK_HDMI)
745  #if defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL)
746         if(lcdc_dev->driver.screen_ctr_info->prop == EXTEND)
747         {
748             if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
749             {
750                 lcdc_cfg_done(lcdc_dev);
751             }
752         }
753  #endif 
754  #endif
755         }
756         spin_unlock(&lcdc_dev->reg_lock);
757
758         return 0;
759 }
760
761 static int rk3188_lcdc_pan_display(struct rk_lcdc_device_driver * dev_drv,int layer_id)
762 {
763         struct rk3188_lcdc_device *lcdc_dev = 
764                                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
765         struct layer_par *par = NULL;
766         rk_screen *screen = dev_drv->cur_screen;
767         unsigned long flags;
768         int timeout;
769         
770         if(!screen)
771         {
772                 dev_err(dev_drv->dev,"screen is null!\n");
773                 return -ENOENT; 
774         }
775         if(layer_id==0)
776         {
777                 par = dev_drv->layer_par[0];
778                 win0_display(lcdc_dev,par);
779         }
780         else if(layer_id==1)
781         {
782                 par = dev_drv->layer_par[1];
783                 win1_display(lcdc_dev,par);
784         }
785         else 
786         {
787                 dev_err(dev_drv->dev,"invalid win number:%d!\n",layer_id);
788                 return -EINVAL;
789         }
790         if((dev_drv->first_frame))  //this is the first frame of the system ,enable frame start interrupt
791         {
792                 dev_drv->first_frame = 0;
793                 lcdc_msk_reg(lcdc_dev,INT_STATUS,m_FS_INT_CLEAR |m_FS_INT_EN ,
794                           v_FS_INT_CLEAR(1) | v_FS_INT_EN(1));
795                 lcdc_cfg_done(lcdc_dev);  // write any value to  REG_CFG_DONE let config become effective
796                  
797         }
798
799 #if defined(WAIT_FOR_SYNC)
800         spin_lock_irqsave(&dev_drv->cpl_lock,flags);
801         init_completion(&dev_drv->frame_done);
802         spin_unlock_irqrestore(&dev_drv->cpl_lock,flags);
803         timeout = wait_for_completion_timeout(&dev_drv->frame_done,msecs_to_jiffies(dev_drv->cur_screen->ft+5));
804         if(!timeout&&(!dev_drv->frame_done.done))
805         {
806                 printk(KERN_ERR "wait for new frame start time out!\n");
807                 return -ETIMEDOUT;
808         }
809 #endif
810         return 0;
811 }
812
813 static int rk3188_lcdc_blank(struct rk_lcdc_device_driver *dev_drv,
814                                 int layer_id,int blank_mode)
815 {
816         struct rk3188_lcdc_device * lcdc_dev = 
817                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
818         
819         spin_lock(&lcdc_dev->reg_lock);
820         if(likely(lcdc_dev->clk_on))
821         {
822                 switch(blank_mode)
823                 {
824                 case FB_BLANK_UNBLANK:
825                         lcdc_msk_reg(lcdc_dev,DSP_CTRL1,m_BLANK_EN ,v_BLANK_EN(0));
826                         break;
827                 case FB_BLANK_NORMAL:
828                         lcdc_msk_reg(lcdc_dev,DSP_CTRL1,m_BLANK_EN ,v_BLANK_EN(1));
829                         break;
830                 default:
831                         lcdc_msk_reg(lcdc_dev,DSP_CTRL1,m_BLANK_EN ,v_BLANK_EN(1));
832                         break;
833                 }
834                 lcdc_cfg_done(lcdc_dev);
835                 dev_info(dev_drv->dev,"blank mode:%d\n",blank_mode);
836         }
837         spin_unlock(&lcdc_dev->reg_lock);
838
839         return 0;
840 }
841
842
843 static int rk3188_lcdc_ioctl(struct rk_lcdc_device_driver *dev_drv, unsigned int cmd,unsigned long arg,int layer_id)
844 {
845         struct rk3188_lcdc_device *lcdc_dev = 
846                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
847         u32 panel_size[2];
848         void __user *argp = (void __user *)arg;
849         int enable;
850         unsigned long flags;
851         int timeout;
852         switch(cmd)
853         {
854                 case RK_FBIOGET_PANEL_SIZE:    //get panel size
855                         panel_size[0] = lcdc_dev->screen->x_res;
856                         panel_size[1] = lcdc_dev->screen->y_res;
857                         if(copy_to_user(argp, panel_size, 8)) 
858                                 return -EFAULT;
859                         break;
860                 case RK_FBIOSET_CONFIG_DONE:
861                         if (copy_from_user(&(dev_drv->wait_fs),argp,sizeof(dev_drv->wait_fs)))
862                                 return -EFAULT;
863                         lcdc_cfg_done(lcdc_dev);
864                         if(dev_drv->wait_fs)
865                         {
866                                 spin_lock_irqsave(&dev_drv->cpl_lock,flags);
867                                 init_completion(&dev_drv->frame_done);
868                                 spin_unlock_irqrestore(&dev_drv->cpl_lock,flags);
869                                 timeout = wait_for_completion_timeout(&dev_drv->frame_done,msecs_to_jiffies(dev_drv->cur_screen->ft+5));
870                                 if(!timeout&&(!dev_drv->frame_done.done))
871                                 {
872                                         printk(KERN_ERR "wait for new frame start time out!\n");
873                                         return -ETIMEDOUT;
874                                 }
875                         }
876                         break;
877                 default:
878                         break;
879         }
880         return 0;
881 }
882
883 static int rk3188_lcdc_early_suspend(struct rk_lcdc_device_driver *dev_drv)
884 {
885         
886         struct rk3188_lcdc_device *lcdc_dev = 
887                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
888
889         if(dev_drv->screen0->standby)
890                 dev_drv->screen0->standby(1);
891         if(dev_drv->screen_ctr_info->io_disable)
892                 dev_drv->screen_ctr_info->io_disable();
893
894         spin_lock(&lcdc_dev->reg_lock);
895         if(likely(lcdc_dev->clk_on))
896         {
897                 lcdc_msk_reg(lcdc_dev,INT_STATUS,m_FS_INT_CLEAR,v_FS_INT_CLEAR(1));
898                 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
899                 lcdc_cfg_done(lcdc_dev);
900                 spin_unlock(&lcdc_dev->reg_lock);
901         }
902         else  //clk already disabled
903         {
904                 spin_unlock(&lcdc_dev->reg_lock);
905                 return 0;
906         }
907
908         mdelay(25);
909         rk3188_lcdc_clk_disable(lcdc_dev);
910         return 0;
911 }
912
913 static int rk3188_lcdc_early_resume(struct rk_lcdc_device_driver *dev_drv)
914 {
915         struct rk3188_lcdc_device *lcdc_dev = 
916                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
917         int i=0;
918         int __iomem *c;
919         int v;
920
921         if(dev_drv->screen_ctr_info->io_enable)                 //power on
922                 dev_drv->screen_ctr_info->io_enable();
923         
924         if(!lcdc_dev->clk_on)
925         {
926                 rk3188_lcdc_clk_enable(lcdc_dev);
927         }
928         rk3188_lcdc_reg_resume(lcdc_dev);  //resume reg
929
930         spin_lock(&lcdc_dev->reg_lock);
931         if(dev_drv->cur_screen->dsp_lut)                        //resume dsp lut
932         {
933                 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(0));
934                 lcdc_cfg_done(lcdc_dev);
935                 mdelay(25);
936                 for(i=0;i<256;i++)
937                 {
938                         v = dev_drv->cur_screen->dsp_lut[i];
939                         c = lcdc_dev->dsp_lut_addr_base+i;
940                         writel_relaxed(v,c);
941                 }
942                 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(1));
943         }
944         
945         if(lcdc_dev->atv_layer_cnt)
946         {
947                 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
948                 lcdc_cfg_done(lcdc_dev);
949         }
950         spin_unlock(&lcdc_dev->reg_lock);
951
952         if(!lcdc_dev->atv_layer_cnt)
953                 rk3188_lcdc_clk_disable(lcdc_dev);
954
955         if(dev_drv->screen0->standby)
956                 dev_drv->screen0->standby(0);         //screen wake up
957         
958         return 0;
959 }
960
961 static int rk3188_lcdc_get_layer_state(struct rk_lcdc_device_driver *dev_drv,int layer_id)
962 {
963         return 0;
964 }
965
966 static int rk3188_lcdc_ovl_mgr(struct rk_lcdc_device_driver *dev_drv,int swap,bool set)
967 {
968         struct rk3188_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3188_lcdc_device,driver);
969         int ovl;
970         spin_lock(&lcdc_dev->reg_lock);
971         if(lcdc_dev->clk_on)
972         {
973                 if(set)  //set overlay
974                 {
975                         lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN0_TOP,v_WIN0_TOP(swap));
976                         //lcdc_cfg_done(lcdc_dev);
977                         ovl = swap;
978                 }
979                 else  //get overlay
980                 {
981                         ovl = lcdc_read_bit(lcdc_dev,DSP_CTRL0,m_WIN0_TOP);
982                 }
983         }
984         else
985         {
986                 ovl = -EPERM;
987         }
988         spin_unlock(&lcdc_dev->reg_lock);
989
990         return ovl;
991 }
992
993
994 static ssize_t rk3188_lcdc_get_disp_info(struct rk_lcdc_device_driver *dev_drv,char *buf,int layer_id)
995 {
996         
997         struct rk3188_lcdc_device *lcdc_dev = 
998                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
999
1000         char format_w0[9]= "NULL";
1001         char format_w1[9]= "NULL";
1002         char status_w0[9]= "NULL";
1003         char status_w1[9]= "NULL";
1004         u32 fmt_id = lcdc_readl(lcdc_dev,SYS_CTRL);
1005         u32 act_info,dsp_info,dsp_st,factor;
1006         u16 xvir_w0,x_act_w0,y_act_w0,x_dsp_w0,y_dsp_w0,x_st_w0,y_st_w0,x_factor,y_factor;
1007         u16 xvir_w1,x_dsp_w1,y_dsp_w1,x_st_w1,y_st_w1;
1008         u16 x_scale,y_scale;
1009         switch((fmt_id&m_WIN0_FORMAT)>>3)
1010         {
1011                 case 0:
1012                         strcpy(format_w0,"ARGB888");
1013                         break;
1014                 case 1:
1015                         strcpy(format_w0,"RGB888");
1016                         break;
1017                 case 2:
1018                         strcpy(format_w0,"RGB565");
1019                         break;
1020                 case 4:
1021                         strcpy(format_w0,"YCbCr420");
1022                         break;
1023                 case 5:
1024                         strcpy(format_w0,"YCbCr422");
1025                         break;
1026                 case 6:
1027                         strcpy(format_w0,"YCbCr444");
1028                         break;
1029                 default:
1030                         strcpy(format_w0,"invalid\n");
1031                         break;
1032         }
1033
1034          switch((fmt_id&m_WIN1_FORMAT)>>6)
1035         {
1036                 case 0:
1037                         strcpy(format_w1,"ARGB888");
1038                         break;
1039                 case 1:
1040                         strcpy(format_w1,"RGB888");
1041                         break;
1042                 case 2:
1043                         strcpy(format_w1,"RGB565");
1044                         break;
1045                 case 4:
1046                         strcpy(format_w1,"8bpp");
1047                         break;
1048                 case 5:
1049                         strcpy(format_w1,"4bpp");
1050                         break;
1051                 case 6:
1052                         strcpy(format_w1,"2bpp");
1053                         break;
1054                 case 7:
1055                         strcpy(format_w1,"1bpp");
1056                         break;
1057                 default:
1058                         strcpy(format_w1,"invalid\n");
1059                         break;
1060         }
1061
1062         if(fmt_id&m_WIN0_EN)
1063         {
1064                 strcpy(status_w0,"enabled");
1065         }
1066         else
1067         {
1068                 strcpy(status_w0,"disabled");
1069         }
1070
1071         if((fmt_id&m_WIN1_EN)>>1)
1072         {
1073                 strcpy(status_w1,"enabled");
1074         }
1075         else
1076         {
1077                 strcpy(status_w1,"disabled");
1078         }
1079
1080         xvir_w0 = lcdc_readl(lcdc_dev,WIN_VIR)&0x1fff;
1081         act_info = lcdc_readl(lcdc_dev,WIN0_ACT_INFO);
1082         dsp_info = lcdc_readl(lcdc_dev,WIN0_DSP_INFO);
1083         dsp_st = lcdc_readl(lcdc_dev,WIN0_DSP_ST);
1084         factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_YRGB);
1085         x_act_w0= (act_info&0x1fff) + 1;
1086         y_act_w0= ((act_info>>16)&0x1fff) + 1;
1087         x_dsp_w0= (dsp_info&0x7ff) + 1;
1088         y_dsp_w0= ((dsp_info>>16)&0x7ff) + 1;
1089         x_st_w0 = dsp_st&0xffff;
1090         y_st_w0 = dsp_st>>16;
1091         x_factor = factor&0xffff;
1092         y_factor = factor>>16;
1093         x_scale = 4096*100/x_factor;
1094         y_scale = 4096*100/y_factor;
1095
1096         xvir_w1= (lcdc_readl(lcdc_dev,WIN_VIR)>> 16)&0x1fff;
1097         dsp_info = lcdc_readl(lcdc_dev,WIN1_DSP_INFO);
1098         dsp_st = lcdc_readl(lcdc_dev,WIN1_DSP_ST);
1099         x_dsp_w1= (dsp_info&0x7ff) + 1;
1100         y_dsp_w1= ((dsp_info>>16)&0x7ff) + 1;
1101         x_st_w1 = dsp_st&0xffff;
1102         y_st_w1 = dsp_st>>16;
1103         return snprintf(buf,PAGE_SIZE,
1104                 "win0:%s\n"
1105                 "xvir:%d\n"
1106                 "xact:%d\n"
1107                 "yact:%d\n"
1108                 "xdsp:%d\n"
1109                 "ydsp:%d\n"
1110                 "x_st:%d\n"
1111                 "y_st:%d\n"
1112                 "x_scale:%d.%d\n"
1113                 "y_scale:%d.%d\n"
1114                 "format:%s\n\n"
1115                 "win1:%s\n"
1116                 "xvir:%d\n"
1117                 "xdsp:%d\n"
1118                 "ydsp:%d\n"
1119                 "x_st:%d\n"
1120                 "y_st:%d\n"
1121                 "format:%s\n",
1122                 status_w0,
1123                 xvir_w0,
1124                 x_act_w0,
1125                 y_act_w0,
1126                 x_dsp_w0,
1127                 y_dsp_w0,
1128                 x_st_w0,
1129                 y_st_w0,
1130                 x_scale/100,
1131                 x_scale%100,
1132                 y_scale/100,
1133                 y_scale%100,
1134                 format_w0,
1135                 status_w1,
1136                 xvir_w1,
1137                 x_dsp_w1,
1138                 y_dsp_w1,
1139                 x_st_w1,
1140                 y_st_w1,
1141                 format_w1);
1142
1143 }
1144
1145
1146 static int rk3188_lcdc_fps_mgr(struct rk_lcdc_device_driver *dev_drv,int fps,bool set)
1147 {
1148         struct rk3188_lcdc_device *lcdc_dev = 
1149                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
1150         rk_screen * screen = dev_drv->cur_screen;
1151         u64 ft = 0;
1152         u32 dotclk;
1153         int ret;
1154         u32 pixclock;
1155         if(set)
1156         {
1157                 ft = div_u64(1000000000000llu,fps);
1158                 dev_drv->pixclock = div_u64(ft,(screen->upper_margin + screen->lower_margin + screen->y_res +screen->vsync_len)*
1159                                 (screen->left_margin + screen->right_margin + screen->x_res + screen->hsync_len));
1160                 dotclk = div_u64(1000000000000llu,dev_drv->pixclock);
1161                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
1162                 if(ret)
1163                 {
1164                         printk(KERN_ERR ">>>>>> set lcdc%d dclk failed\n",lcdc_dev->id);
1165                         return 0;
1166                 }                       
1167         }
1168         
1169         
1170         pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1171         dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
1172         fps = rk_fb_calc_fps(lcdc_dev->screen,pixclock);
1173         screen->ft = 1000/fps ;  //one frame time in ms
1174
1175         if(set)
1176                 dev_info(dev_drv->dev,"%s:dclk:%lu,fps:%d\n",__func__,clk_get_rate(lcdc_dev->dclk),fps);
1177         
1178         return fps;
1179 }
1180
1181
1182 static int rk3188_fb_layer_remap(struct rk_lcdc_device_driver *dev_drv,
1183         enum fb_win_map_order order)
1184 {
1185         mutex_lock(&dev_drv->fb_win_id_mutex);
1186         if(order == FB_DEFAULT_ORDER )
1187         {
1188                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
1189         }
1190         dev_drv->fb2_win_id  = order/100;
1191         dev_drv->fb1_win_id = (order/10)%10;
1192         dev_drv->fb0_win_id = order%10;
1193         mutex_unlock(&dev_drv->fb_win_id_mutex);
1194
1195         printk("fb0:win%d\nfb1:win%d\nfb2:win%d\n",dev_drv->fb0_win_id,dev_drv->fb1_win_id,
1196                dev_drv->fb2_win_id);
1197
1198        return 0;
1199 }
1200
1201 static int rk3188_fb_get_layer(struct rk_lcdc_device_driver *dev_drv,const char *id)
1202 {
1203        int layer_id = 0;
1204        mutex_lock(&dev_drv->fb_win_id_mutex);
1205        if(!strcmp(id,"fb0")||!strcmp(id,"fb2"))
1206        {
1207                layer_id = dev_drv->fb0_win_id;
1208        }
1209        else if(!strcmp(id,"fb1")||!strcmp(id,"fb3"))
1210        {
1211                layer_id = dev_drv->fb1_win_id;
1212        }
1213        mutex_unlock(&dev_drv->fb_win_id_mutex);
1214
1215        return  layer_id;
1216 }
1217
1218 static int rk3188_set_dsp_lut(struct rk_lcdc_device_driver *dev_drv,int *lut)
1219 {
1220         int i=0;
1221         int __iomem *c;
1222         int v;
1223         int ret = 0;
1224
1225         struct rk3188_lcdc_device *lcdc_dev = 
1226                                 container_of(dev_drv,struct rk3188_lcdc_device,driver);
1227         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(0));
1228         lcdc_cfg_done(lcdc_dev);
1229         msleep(25);
1230         if(dev_drv->cur_screen->dsp_lut)
1231         {
1232                 for(i=0;i<256;i++)
1233                 {
1234                         v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
1235                         c = lcdc_dev->dsp_lut_addr_base+i;
1236                         writel_relaxed(v,c);
1237                         
1238                 }
1239         }
1240         else
1241         {
1242                 dev_err(dev_drv->dev,"no buffer to backup lut data!\n");
1243                 ret =  -1;
1244         }
1245         lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(1));
1246         lcdc_cfg_done(lcdc_dev);
1247
1248         return ret;
1249 }
1250
1251
1252 static struct layer_par lcdc_layer[] = {
1253         [0] = {
1254                 .name           = "win0",
1255                 .id             = 0,
1256                 .support_3d     = true,
1257         },
1258         [1] = {
1259                 .name           = "win1",
1260                 .id             = 1,
1261                 .support_3d     = false,
1262         },
1263 };
1264
1265 static struct rk_lcdc_device_driver lcdc_driver = {
1266         .name                   = "lcdc",
1267         .def_layer_par          = lcdc_layer,
1268         .num_layer              = ARRAY_SIZE(lcdc_layer),
1269         .open                   = rk3188_lcdc_open,
1270         .init_lcdc              = rk3188_lcdc_init,
1271         .load_screen            = rk3188_load_screen,
1272         .set_par                = rk3188_lcdc_set_par,
1273         .pan_display            = rk3188_lcdc_pan_display,
1274         .blank                  = rk3188_lcdc_blank,
1275         .ioctl                  = rk3188_lcdc_ioctl,
1276         .suspend                = rk3188_lcdc_early_suspend,
1277         .resume                 = rk3188_lcdc_early_resume,
1278         .get_layer_state        = rk3188_lcdc_get_layer_state,
1279         .ovl_mgr                = rk3188_lcdc_ovl_mgr,
1280         .get_disp_info          = rk3188_lcdc_get_disp_info,
1281         .fps_mgr                = rk3188_lcdc_fps_mgr,
1282         .fb_get_layer           = rk3188_fb_get_layer,
1283         .fb_layer_remap         = rk3188_fb_layer_remap,
1284         .set_dsp_lut            = rk3188_set_dsp_lut,
1285 };
1286
1287 static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id)
1288 {
1289         struct rk3188_lcdc_device *lcdc_dev = 
1290                                 (struct rk3188_lcdc_device *)dev_id;
1291         ktime_t timestamp = ktime_get();
1292         
1293         lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
1294
1295         if(lcdc_dev->driver.wait_fs)  //three buffer ,no need to wait for sync
1296         {
1297                 spin_lock(&(lcdc_dev->driver.cpl_lock));
1298                 complete(&(lcdc_dev->driver.frame_done));
1299                 spin_unlock(&(lcdc_dev->driver.cpl_lock));
1300         }
1301         lcdc_dev->driver.vsync_info.timestamp = timestamp;
1302         wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
1303         
1304         return IRQ_HANDLED;
1305 }
1306
1307
1308 #if defined(CONFIG_PM)
1309 static int rk3188_lcdc_suspend(struct platform_device *pdev,
1310                                         pm_message_t state)
1311 {
1312         return 0;
1313 }
1314
1315 static int rk3188_lcdc_resume(struct platform_device *pdev)
1316 {
1317         return 0;
1318 }
1319 #else
1320 #define rk3188_lcdc_suspend NULL
1321 #define rk3188_lcdc_resume  NULL
1322 #endif
1323 static int __devinit rk3188_lcdc_probe(struct platform_device *pdev)
1324 {
1325         struct rk3188_lcdc_device *lcdc_dev = NULL;
1326         struct device *dev = &pdev->dev;
1327         rk_screen *screen;
1328         rk_screen *screen1;
1329         struct rk29fb_info *screen_ctr_info;
1330         struct resource *res = NULL;
1331         struct resource *mem = NULL;
1332         int ret = 0;
1333         
1334         lcdc_dev = devm_kzalloc(dev,sizeof(struct rk3188_lcdc_device), GFP_KERNEL);
1335         if(!lcdc_dev)
1336         {
1337                 dev_err(&pdev->dev, ">>rk3188 lcdc device kmalloc fail!");
1338                 return -ENOMEM;
1339         }
1340         platform_set_drvdata(pdev, lcdc_dev);
1341         lcdc_dev->id = pdev->id;
1342         screen_ctr_info = (struct rk29fb_info * )pdev->dev.platform_data;
1343         screen =  kzalloc(sizeof(rk_screen), GFP_KERNEL);
1344         if(!screen_ctr_info)
1345         {
1346                 dev_err(dev, "no platform data specified for screen control info!\n");
1347                 ret = -EINVAL;
1348                 goto err0;
1349         }
1350         if(!screen)
1351         {
1352                 dev_err(&pdev->dev, "rk screen kmalloc fail!");
1353                 ret = -ENOMEM;
1354                 goto err0;
1355         }
1356         else
1357         {
1358                 lcdc_dev->screen = screen;
1359         }
1360         screen->lcdc_id = lcdc_dev->id;
1361         screen->screen_id = 0;
1362 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& defined(CONFIG_RK610_LVDS)
1363         screen1 =  kzalloc(sizeof(rk_screen), GFP_KERNEL);
1364         if(!screen1)
1365         {
1366                 dev_err(&pdev->dev, ">>rk3066b lcdc screen1 kmalloc fail!");
1367                 ret =  -ENOMEM;
1368                 goto err0;
1369         }
1370         screen1->lcdc_id = 1;
1371         screen1->screen_id = 1;
1372         printk("use lcdc%d and rk610 implemention dual display!\n",lcdc_dev->id);
1373         
1374 #endif
1375         
1376         res = platform_get_resource(pdev, IORESOURCE_MEM,0);
1377         if (res == NULL)
1378         {
1379                 dev_err(&pdev->dev, "failed to get register resource for lcdc%d \n",lcdc_dev->id);
1380                 ret = -ENOENT;
1381                 goto err1;
1382         }
1383         
1384         lcdc_dev->reg_phy_base = res->start;
1385         lcdc_dev->len = resource_size(res);
1386         mem = request_mem_region(lcdc_dev->reg_phy_base,lcdc_dev->len, pdev->name);
1387         if (!mem)
1388         {
1389                 dev_err(&pdev->dev, "failed to request mem region for lcdc%d\n",lcdc_dev->id);
1390                 ret = -ENOENT;
1391                 goto err1;
1392         }
1393         lcdc_dev->regs = ioremap(lcdc_dev->reg_phy_base,lcdc_dev->len);
1394         if (!lcdc_dev->regs)
1395         {
1396                 dev_err(&pdev->dev, "cannot map register for lcdc%d\n",lcdc_dev->id);
1397                 ret = -ENXIO;
1398                 goto err2;
1399         }
1400         
1401         lcdc_dev->regsbak = kzalloc(lcdc_dev->len,GFP_KERNEL);
1402         if(!lcdc_dev->regsbak)
1403         {
1404                 dev_err(&pdev->dev, "failed to map memory for reg backup!\n");
1405                 ret = -ENOMEM;
1406                 goto err3;
1407         }
1408         lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
1409         printk("lcdc%d:reg_phy_base = 0x%08x,reg_vir_base:0x%p\n",pdev->id,lcdc_dev->reg_phy_base, lcdc_dev->regs);
1410         lcdc_dev->driver.dev = dev;
1411         lcdc_dev->driver.screen0 = screen;
1412 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& defined(CONFIG_RK610_LVDS)
1413         lcdc_dev->driver.screen1 = screen1;
1414 #endif
1415         lcdc_dev->driver.cur_screen = screen;
1416         lcdc_dev->driver.screen_ctr_info = screen_ctr_info;
1417         
1418         spin_lock_init(&lcdc_dev->reg_lock);
1419         
1420         lcdc_dev->irq = platform_get_irq(pdev, 0);
1421         if(lcdc_dev->irq < 0)
1422         {
1423                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",lcdc_dev->id);
1424                 goto err3;
1425         }
1426         ret = devm_request_irq(dev,lcdc_dev->irq, rk3188_lcdc_isr, IRQF_DISABLED,dev_name(dev),lcdc_dev);
1427         if (ret)
1428         {
1429                dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n", lcdc_dev->irq, ret);
1430                ret = -EBUSY;
1431                goto err3;
1432         }
1433
1434         if(screen_ctr_info->set_screen_info)
1435         {
1436                 screen_ctr_info->set_screen_info(screen,screen_ctr_info->lcd_info);
1437                 if(SCREEN_NULL==screen->type)
1438                 {
1439                         printk(KERN_WARNING "no display device on lcdc%d!?\n",lcdc_dev->id);
1440                         ret = -ENODEV;
1441                 }
1442                 if(screen_ctr_info->io_init)
1443                         screen_ctr_info->io_init(NULL);
1444         }
1445         else
1446         {
1447                 printk(KERN_WARNING "no display device on lcdc%d!?\n",lcdc_dev->id);
1448                 ret = -ENODEV;
1449                 goto err3;
1450         }
1451         
1452         ret = rk_fb_register(&(lcdc_dev->driver),&lcdc_driver,lcdc_dev->id);
1453         if(ret < 0)
1454         {
1455                 dev_err(dev,"register fb for lcdc%d failed!\n",lcdc_dev->id);
1456                 goto err4;
1457         }
1458         
1459         printk("rk3188 lcdc%d probe ok!\n",lcdc_dev->id);
1460         
1461         return 0;
1462
1463 err4:
1464 err3:
1465         iounmap(lcdc_dev->regs);
1466 err2:
1467         release_mem_region(lcdc_dev->reg_phy_base,lcdc_dev->len);
1468 err1:
1469         kfree(screen);
1470 err0:
1471         platform_set_drvdata(pdev, NULL);
1472
1473         return ret;
1474 }
1475
1476 static int __devexit rk3188_lcdc_remove(struct platform_device *pdev)
1477 {
1478         return 0;
1479 }
1480
1481 static void rk3188_lcdc_shutdown(struct platform_device *pdev)
1482 {
1483         struct rk3188_lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
1484         if(lcdc_dev->driver.cur_screen->standby) //standby the screen if necessary
1485                 lcdc_dev->driver.cur_screen->standby(1);
1486         if(lcdc_dev->driver.screen_ctr_info->io_disable) //power off the screen if necessary
1487                 lcdc_dev->driver.screen_ctr_info->io_disable();
1488         if(lcdc_dev->driver.cur_screen->sscreen_set) //turn off  lvds if necessary
1489                 lcdc_dev->driver.cur_screen->sscreen_set(lcdc_dev->driver.cur_screen , 0);
1490         rk3188_lcdc_deint(lcdc_dev);
1491         rk_fb_unregister(&(lcdc_dev->driver));  
1492 }
1493 static struct platform_driver rk3188_lcdc_driver = {
1494         .probe          = rk3188_lcdc_probe,
1495         .remove         = __devexit_p(rk3188_lcdc_remove),
1496         .driver         = {
1497                 .name   = "rk30-lcdc",
1498                 .owner  = THIS_MODULE,
1499         },
1500         .suspend        = rk3188_lcdc_suspend,
1501         .resume         = rk3188_lcdc_resume,
1502         .shutdown       = rk3188_lcdc_shutdown,
1503 };
1504 static int __init rk3188_lcdc_module_init(void)
1505 {
1506         return platform_driver_register(&rk3188_lcdc_driver);
1507 }
1508
1509 static void __exit rk3188_lcdc_module_exit(void)
1510 {
1511         platform_driver_unregister(&rk3188_lcdc_driver);
1512 }
1513 fs_initcall(rk3188_lcdc_module_init);
1514 module_exit(rk3188_lcdc_module_exit);