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