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