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