rk3288 lcdc: add dsp_lut adjust support
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3288_lcdc.c
1 /*
2  * drivers/video/rockchip/lcdc/rk3288_lcdc.c
3  *
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  *Author:hjc<hjc@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/rockchip-iovmm.h>
30 #include <asm/div64.h>
31 #include <asm/uaccess.h>
32 #include <linux/rockchip/cpu.h>
33 #include <linux/rockchip/iomap.h>
34 #include <linux/rockchip/grf.h>
35 #include <linux/rockchip/common.h>
36 #include <dt-bindings/clock/rk_system_status.h>
37
38 #include "rk3288_lcdc.h"
39
40 #if defined(CONFIG_HAS_EARLYSUSPEND)
41 #include <linux/earlysuspend.h>
42 #endif
43
44 static int dbg_thresd;
45 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
46
47 #define DBG(level, x...) do {                   \
48         if (unlikely(dbg_thresd >= level))      \
49                 printk(KERN_INFO x); } while (0)
50
51 static int rk3288_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv,
52                                      bool enable);
53
54 /*#define WAIT_FOR_SYNC 1*/
55
56 static int rk3288_lcdc_get_id(u32 phy_base)
57 {
58         if (cpu_is_rk3288()) {
59                 if (phy_base == 0xff930000)/*vop big*/
60                         return 0;
61                 else if (phy_base == 0xff940000)/*vop lit*/     
62                         return 1;
63                 else
64                         return -EINVAL;
65         } else {
66                 pr_err("un supported platform \n");
67                 return -EINVAL;
68         }
69 }
70
71 static int rk3288_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
72 {
73         int i,j;
74         int __iomem *c;
75         u32 v,r,g,b;
76         struct lcdc_device *lcdc_dev = container_of(dev_drv,
77                                         struct lcdc_device,driver);
78         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
79         lcdc_cfg_done(lcdc_dev);
80         mdelay(25);
81         for (i = 0; i < 256; i++) {
82                 v = dev_drv->cur_screen->dsp_lut[i];
83                 c = lcdc_dev->dsp_lut_addr_base + (i << 2);
84                 b = (v & 0xff) << 2;
85                 g = (v & 0xff00) << 4;
86                 r = (v & 0xff0000) << 6;
87                 v = r + g + b;
88                 for (j = 0; j < 4; j++) {
89                         writel_relaxed(v, c);
90                         v += (1 + (1 << 10) + (1 << 20)) ;
91                         c++;
92                 }
93         }
94         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
95
96         return 0;
97
98 }
99
100 static int rk3288_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
101 {
102 #ifdef CONFIG_RK_FPGA
103         lcdc_dev->clk_on = 1;
104         return 0;
105 #endif  
106         if (!lcdc_dev->clk_on) {
107                 clk_prepare_enable(lcdc_dev->hclk);
108                 clk_prepare_enable(lcdc_dev->dclk);
109                 clk_prepare_enable(lcdc_dev->aclk);
110                 clk_prepare_enable(lcdc_dev->pd);
111                 spin_lock(&lcdc_dev->reg_lock);
112                 lcdc_dev->clk_on = 1;
113                 spin_unlock(&lcdc_dev->reg_lock);
114         }
115
116         return 0;
117 }
118
119 static int rk3288_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
120 {
121 #ifdef CONFIG_RK_FPGA
122         lcdc_dev->clk_on = 0;
123         return 0;
124 #endif  
125         if (lcdc_dev->clk_on) {
126                 spin_lock(&lcdc_dev->reg_lock);
127                 lcdc_dev->clk_on = 0;
128                 spin_unlock(&lcdc_dev->reg_lock);
129                 mdelay(25);
130                 clk_disable_unprepare(lcdc_dev->dclk);
131                 clk_disable_unprepare(lcdc_dev->hclk);
132                 clk_disable_unprepare(lcdc_dev->aclk);
133                 clk_disable_unprepare(lcdc_dev->pd);
134         }
135
136         return 0;
137 }
138
139 static int rk3288_lcdc_disable_irq(struct lcdc_device *lcdc_dev)
140 {       
141         u32 mask, val;
142         spin_lock(&lcdc_dev->reg_lock);
143         if (likely(lcdc_dev->clk_on)) {
144                 mask = m_DSP_HOLD_VALID_INTR_EN | m_FS_INTR_EN |
145                         m_LINE_FLAG_INTR_EN | m_BUS_ERROR_INTR_EN;
146                 val = v_DSP_HOLD_VALID_INTR_EN(0) | v_FS_INTR_EN(0) |
147                         v_LINE_FLAG_INTR_EN(0) | v_BUS_ERROR_INTR_EN(0);
148                 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
149
150                 mask = m_DSP_HOLD_VALID_INTR_CLR | m_FS_INTR_CLR |
151                         m_LINE_FLAG_INTR_CLR | m_LINE_FLAG_INTR_CLR;
152                 val = v_DSP_HOLD_VALID_INTR_CLR(0) | v_FS_INTR_CLR(0) |
153                         v_LINE_FLAG_INTR_CLR(0) | v_BUS_ERROR_INTR_CLR(0);
154                 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);
155
156                 mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN |
157                         m_WIN2_EMPTY_INTR_EN | m_WIN3_EMPTY_INTR_EN |
158                         m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
159                         m_POST_BUF_EMPTY_INTR_EN;
160                 val = v_WIN0_EMPTY_INTR_EN(0) | v_WIN1_EMPTY_INTR_EN(0) |
161                         v_WIN2_EMPTY_INTR_EN(0) | v_WIN3_EMPTY_INTR_EN(0) |
162                         v_HWC_EMPTY_INTR_EN(0) | v_POST_BUF_EMPTY_INTR_EN(0) |
163                         v_PWM_GEN_INTR_EN(0);
164                 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
165
166                 mask = m_WIN0_EMPTY_INTR_CLR | m_WIN1_EMPTY_INTR_CLR |
167                         m_WIN2_EMPTY_INTR_CLR | m_WIN3_EMPTY_INTR_CLR |
168                         m_HWC_EMPTY_INTR_CLR | m_POST_BUF_EMPTY_INTR_CLR |
169                         m_POST_BUF_EMPTY_INTR_CLR;
170                 val = v_WIN0_EMPTY_INTR_CLR(0) | v_WIN1_EMPTY_INTR_CLR(0) |
171                         v_WIN2_EMPTY_INTR_CLR(0) | v_WIN3_EMPTY_INTR_CLR(0) |
172                         v_HWC_EMPTY_INTR_CLR(0) | v_POST_BUF_EMPTY_INTR_CLR(0) |
173                         v_PWM_GEN_INTR_CLR(0);
174                 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);          
175                 lcdc_cfg_done(lcdc_dev);
176                 spin_unlock(&lcdc_dev->reg_lock);
177         } else {
178                 spin_unlock(&lcdc_dev->reg_lock);
179         }
180         mdelay(1);
181         return 0;
182 }
183 static int rk3288_lcdc_reg_dump(struct rk_lcdc_driver *dev_drv)
184 {
185         struct lcdc_device *lcdc_dev = container_of(dev_drv,
186                                                 struct lcdc_device,
187                                                 driver);
188         int *cbase = (int *)lcdc_dev->regs;
189         int *regsbak = (int *)lcdc_dev->regsbak;
190         int i, j;
191
192         printk("back up reg:\n");
193         for (i = 0; i <= (0x200 >> 4); i++) {
194                 printk("0x%04x: ",i*16);
195                 for (j = 0; j < 4; j++)
196                         printk("%08x  ", *(regsbak + i * 4 + j));
197                 printk("\n");
198         }
199
200         printk("lcdc reg:\n");
201         for (i = 0; i <= (0x200 >> 4); i++) {
202                 printk("0x%04x: ",i*16);
203                 for (j = 0; j < 4; j++)
204                         printk("%08x  ", readl_relaxed(cbase + i * 4 + j));
205                 printk("\n");
206         }
207         return 0;
208
209 }
210
211 #define WIN_EN(id)              \
212 static int win##id##_enable(struct lcdc_device *lcdc_dev, int en)       \
213 { \
214         u32 msk, val;                                                   \
215         spin_lock(&lcdc_dev->reg_lock);                                 \
216         msk =  m_WIN##id##_EN;                                          \
217         val  =  v_WIN##id##_EN(en);                                     \
218         lcdc_msk_reg(lcdc_dev, WIN##id##_CTRL0, msk, val);              \
219         lcdc_cfg_done(lcdc_dev);                                        \
220         val = lcdc_read_bit(lcdc_dev, WIN##id##_CTRL0, msk);            \
221         while (val !=  (!!en))  {                                       \
222                 val = lcdc_read_bit(lcdc_dev, WIN##id##_CTRL0, msk);    \
223         }                                                               \
224         spin_unlock(&lcdc_dev->reg_lock);                               \
225         return 0;                                                       \
226 }
227
228 WIN_EN(0);
229 WIN_EN(1);
230 WIN_EN(2);
231 WIN_EN(3);
232 /*enable/disable win directly*/
233 static int rk3288_lcdc_win_direct_en
234                 (struct rk_lcdc_driver *drv, int win_id , int en)
235 {
236         struct lcdc_device *lcdc_dev = container_of(drv,
237                                         struct lcdc_device, driver);
238         if (win_id == 0)
239                 win0_enable(lcdc_dev, en);
240         else if (win_id == 1)
241                 win1_enable(lcdc_dev, en);
242         else if (win_id == 2)
243                 win2_enable(lcdc_dev, en);
244         else if (win_id == 3)
245                 win3_enable(lcdc_dev, en);
246         else
247                 dev_err(lcdc_dev->dev, "invalid win number:%d\n", win_id);
248         return 0;
249                 
250 }
251
252 #define SET_WIN_ADDR(id) \
253 static int set_win##id##_addr(struct lcdc_device *lcdc_dev, u32 addr) \
254 {                                                       \
255         u32 msk, val;                                   \
256         spin_lock(&lcdc_dev->reg_lock);                 \
257         lcdc_writel(lcdc_dev,WIN##id##_YRGB_MST,addr);  \
258         msk =  m_WIN##id##_EN;                          \
259         val  =  v_WIN0_EN(1);                           \
260         lcdc_msk_reg(lcdc_dev, WIN##id##_CTRL0, msk,val);       \
261         lcdc_cfg_done(lcdc_dev);                        \
262         spin_unlock(&lcdc_dev->reg_lock);               \
263         return 0;                                       \
264 }
265
266 SET_WIN_ADDR(0);
267 SET_WIN_ADDR(1);
268 int rk3288_lcdc_direct_set_win_addr
269                 (struct rk_lcdc_driver *dev_drv, int win_id, u32 addr)
270 {
271         struct lcdc_device *lcdc_dev = container_of(dev_drv,
272                                 struct lcdc_device, driver);
273         if (win_id == 0)
274                 set_win0_addr(lcdc_dev, addr);
275         else
276                 set_win1_addr(lcdc_dev, addr);
277         
278         return 0;
279 }
280
281 static void lcdc_read_reg_defalut_cfg(struct lcdc_device *lcdc_dev)
282 {
283         int reg = 0;
284         u32 val = 0;
285         struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
286
287         spin_lock(&lcdc_dev->reg_lock);
288         for (reg = 0; reg < 0x1a0; reg+= 4) {
289                 val = lcdc_readl(lcdc_dev, reg);
290                 switch (reg) {
291                         case WIN0_ACT_INFO:
292                                 win0->area[0].xact = (val & m_WIN0_ACT_WIDTH)+1;
293                                 win0->area[0].yact = ((val & m_WIN0_ACT_HEIGHT)>>16)+1;
294                         default:
295                                 break;
296                 }
297         }
298         spin_unlock(&lcdc_dev->reg_lock);
299         
300 }
301
302 /********do basic init*********/
303 static int rk3288_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
304 {
305         int v;
306         u32 mask,val;
307         struct lcdc_device *lcdc_dev = container_of(dev_drv,
308                                                            struct
309                                                            lcdc_device,
310                                                    driver);
311         if (lcdc_dev->pre_init)
312                 return 0;
313
314         lcdc_dev->hclk = devm_clk_get(lcdc_dev->dev, "hclk_lcdc");
315         lcdc_dev->aclk = devm_clk_get(lcdc_dev->dev, "aclk_lcdc");
316         lcdc_dev->dclk = devm_clk_get(lcdc_dev->dev, "dclk_lcdc");
317         lcdc_dev->pd   = devm_clk_get(lcdc_dev->dev, "pd_lcdc");
318         
319         if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
320             (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
321                 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
322                         lcdc_dev->id);
323         }
324
325         rk_disp_pwr_enable(dev_drv);
326         rk3288_lcdc_clk_enable(lcdc_dev);
327
328         /*backup reg config at uboot*/
329         lcdc_read_reg_defalut_cfg(lcdc_dev);
330 #ifndef CONFIG_RK_FPGA
331         if (lcdc_dev->pwr18 == true) {
332                 v = 0x00010001; /*bit14: 1,1.8v;0,3.3v*/
333                 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_IO_VSEL);
334         } else {
335                 v = 0x00010000;
336                 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_IO_VSEL);
337         }
338 #endif  
339         lcdc_writel(lcdc_dev,CABC_GAUSS_LINE0_0,0x15110903);
340         lcdc_writel(lcdc_dev,CABC_GAUSS_LINE0_1,0x00030911);
341         lcdc_writel(lcdc_dev,CABC_GAUSS_LINE1_0,0x1a150b04);
342         lcdc_writel(lcdc_dev,CABC_GAUSS_LINE1_1,0x00040b15);
343         lcdc_writel(lcdc_dev,CABC_GAUSS_LINE2_0,0x15110903);
344         lcdc_writel(lcdc_dev,CABC_GAUSS_LINE2_1,0x00030911);
345
346         lcdc_writel(lcdc_dev,FRC_LOWER01_0,0x12844821);
347         lcdc_writel(lcdc_dev,FRC_LOWER01_1,0x21488412);
348         lcdc_writel(lcdc_dev,FRC_LOWER10_0,0xa55a9696);
349         lcdc_writel(lcdc_dev,FRC_LOWER10_1,0x5aa56969);
350         lcdc_writel(lcdc_dev,FRC_LOWER11_0,0xdeb77deb);
351         lcdc_writel(lcdc_dev,FRC_LOWER11_1,0xed7bb7de);
352
353         mask =  m_AUTO_GATING_EN;
354         val  =  v_AUTO_GATING_EN(0);
355         lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask,val);
356         lcdc_cfg_done(lcdc_dev);
357         if (dev_drv->iommu_enabled) /*disable win0 to workaround iommu pagefault*/
358                 win0_enable(lcdc_dev, 0);
359         lcdc_dev->pre_init = true;
360
361
362         return 0;
363 }
364
365 static void rk3288_lcdc_deint(struct lcdc_device *lcdc_dev)
366 {
367
368         
369         rk3288_lcdc_disable_irq(lcdc_dev);
370         spin_lock(&lcdc_dev->reg_lock);
371         if (likely(lcdc_dev->clk_on)) {
372                 lcdc_dev->clk_on = 0;
373                 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_STANDBY_EN);
374                 lcdc_cfg_done(lcdc_dev);
375                 spin_unlock(&lcdc_dev->reg_lock);
376         } else {
377                 spin_unlock(&lcdc_dev->reg_lock);
378         }
379         mdelay(1);
380 }
381 static int rk3288_lcdc_post_cfg(struct rk_lcdc_driver *dev_drv)
382 {
383         struct lcdc_device *lcdc_dev =
384             container_of(dev_drv, struct lcdc_device, driver);
385         struct rk_screen *screen = dev_drv->cur_screen;
386         u16 x_res = screen->mode.xres;
387         u16 y_res = screen->mode.yres;
388         u32 mask, val;
389         u16 h_total,v_total;
390         u16 post_hsd_en,post_vsd_en;
391         u16 post_dsp_hact_st,post_dsp_hact_end; 
392         u16 post_dsp_vact_st,post_dsp_vact_end;
393         u16 post_dsp_vact_st_f1,post_dsp_vact_end_f1;
394         u16 post_h_fac,post_v_fac;
395
396         h_total = screen->mode.hsync_len+screen->mode.left_margin +
397                   x_res + screen->mode.right_margin;
398         v_total = screen->mode.vsync_len+screen->mode.upper_margin +
399                   y_res + screen->mode.lower_margin;
400
401         if(screen->post_dsp_stx + screen->post_xsize > x_res){          
402                 dev_warn(lcdc_dev->dev, "post:stx[%d] + xsize[%d] > x_res[%d]\n",
403                         screen->post_dsp_stx,screen->post_xsize,x_res);
404                 screen->post_dsp_stx = x_res - screen->post_xsize;
405         }
406         if(screen->x_mirror == 0){
407                 post_dsp_hact_st=screen->post_dsp_stx + 
408                         screen->mode.hsync_len+screen->mode.left_margin;
409                 post_dsp_hact_end = post_dsp_hact_st + screen->post_xsize;
410         }else{
411                 post_dsp_hact_end = h_total - screen->mode.right_margin -
412                                         screen->post_dsp_stx;
413                 post_dsp_hact_st = post_dsp_hact_end - screen->post_xsize;
414         }       
415         if((screen->post_xsize < x_res)&&(screen->post_xsize != 0)){
416                 post_hsd_en = 1;
417                 post_h_fac = 
418                         GET_SCALE_FACTOR_BILI_DN(x_res , screen->post_xsize); 
419         }else{
420                 post_hsd_en = 0;
421                 post_h_fac = 0x1000;
422         }
423
424
425         if(screen->post_dsp_sty + screen->post_ysize > y_res){
426                 dev_warn(lcdc_dev->dev, "post:sty[%d] + ysize[%d] > y_res[%d]\n",
427                         screen->post_dsp_sty,screen->post_ysize,y_res);
428                 screen->post_dsp_sty = y_res - screen->post_ysize;      
429         }
430         
431         if(screen->y_mirror == 0){
432                 post_dsp_vact_st = screen->post_dsp_sty + 
433                         screen->mode.vsync_len+screen->mode.upper_margin;
434                 post_dsp_vact_end = post_dsp_vact_st + screen->post_ysize;
435         }else{
436                 post_dsp_vact_end = v_total - screen->mode.lower_margin -
437                                         - screen->post_dsp_sty;
438                 post_dsp_vact_st = post_dsp_vact_end - screen->post_ysize;
439         }
440         if((screen->post_ysize < y_res)&&(screen->post_ysize != 0)){
441                 post_vsd_en = 1;
442                 post_v_fac = GET_SCALE_FACTOR_BILI_DN(y_res, screen->post_ysize);               
443         }else{
444                 post_vsd_en = 0;
445                 post_v_fac = 0x1000;
446         }
447
448         if(screen->interlace == 1){
449                 post_dsp_vact_st_f1  = v_total + post_dsp_vact_st;
450                 post_dsp_vact_end_f1 = post_dsp_vact_st_f1 + screen->post_ysize;
451         }else{
452                 post_dsp_vact_st_f1  = 0;
453                 post_dsp_vact_end_f1 = 0;
454         }
455         DBG(1,"post:xsize=%d,ysize=%d,xpos=%d,ypos=%d,"
456               "hsd_en=%d,h_fac=%d,vsd_en=%d,v_fac=%d\n",
457                 screen->post_xsize,screen->post_ysize,screen->xpos,screen->ypos,
458                 post_hsd_en,post_h_fac,post_vsd_en,post_v_fac);
459         mask = m_DSP_HACT_END_POST | m_DSP_HACT_ST_POST;
460         val = v_DSP_HACT_END_POST(post_dsp_hact_end) | 
461               v_DSP_HACT_ST_POST(post_dsp_hact_st);
462         lcdc_msk_reg(lcdc_dev, POST_DSP_HACT_INFO, mask, val);
463
464         mask = m_DSP_VACT_END_POST | m_DSP_VACT_ST_POST;
465         val = v_DSP_VACT_END_POST(post_dsp_vact_end) | 
466               v_DSP_VACT_ST_POST(post_dsp_vact_st);
467         lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO, mask, val);
468
469         mask = m_POST_HS_FACTOR_YRGB | m_POST_VS_FACTOR_YRGB;
470         val = v_POST_HS_FACTOR_YRGB(post_h_fac) |
471                 v_POST_VS_FACTOR_YRGB(post_v_fac);
472         lcdc_msk_reg(lcdc_dev, POST_SCL_FACTOR_YRGB, mask, val);
473
474         mask = m_DSP_VACT_END_POST_F1 | m_DSP_VACT_ST_POST_F1;
475         val = v_DSP_VACT_END_POST_F1(post_dsp_vact_end_f1) |
476                 v_DSP_VACT_ST_POST_F1(post_dsp_vact_st_f1);
477         lcdc_msk_reg(lcdc_dev, POST_DSP_VACT_INFO_F1, mask, val);
478
479         mask = m_POST_HOR_SD_EN | m_POST_VER_SD_EN;
480         val = v_POST_HOR_SD_EN(post_hsd_en) | v_POST_VER_SD_EN(post_vsd_en);
481         lcdc_msk_reg(lcdc_dev, POST_SCL_CTRL, mask, val);
482         return 0;
483 }
484
485 static int rk3288_lcdc_clr_key_cfg(struct rk_lcdc_driver *dev_drv)
486 {
487         struct lcdc_device *lcdc_dev = container_of(dev_drv,
488                                                            struct
489                                                            lcdc_device,
490                                                            driver);
491         struct rk_lcdc_win *win;
492         u32  colorkey_r,colorkey_g,colorkey_b;
493         int i,key_val;
494         for(i=0;i<4;i++){
495                 win = dev_drv->win[i];
496                 key_val = win->color_key_val;
497                 colorkey_r = (key_val & 0xff)<<2;
498                 colorkey_g = ((key_val>>8)&0xff)<<12;
499                 colorkey_b = ((key_val>>16)&0xff)<<22;
500                 /*color key dither 565/888->aaa*/
501                 key_val = colorkey_r | colorkey_g | colorkey_b;
502                 switch(i){
503                 case 0:
504                         lcdc_writel(lcdc_dev, WIN0_COLOR_KEY, key_val);
505                         break;
506                 case 1:
507                         lcdc_writel(lcdc_dev, WIN1_COLOR_KEY, key_val);
508                         break;
509                 case 2:
510                         lcdc_writel(lcdc_dev, WIN2_COLOR_KEY, key_val);
511                         break;
512                 case 3:
513                         lcdc_writel(lcdc_dev, WIN3_COLOR_KEY, key_val);
514                         break;
515                 default:
516                         printk(KERN_WARNING "%s:un support win num:%d\n",
517                                 __func__,i);            
518                         break;
519                 }
520         }
521         return 0;
522 }
523
524 static int rk3288_lcdc_alpha_cfg(struct rk_lcdc_driver *dev_drv,int win_id)
525 {
526         struct lcdc_device *lcdc_dev =
527                 container_of(dev_drv, struct lcdc_device, driver);
528         struct rk_lcdc_win *win = dev_drv->win[win_id];
529         struct alpha_config alpha_config;
530
531         u32 mask, val;
532         int ppixel_alpha,global_alpha;
533         u32 src_alpha_ctl,dst_alpha_ctl;
534         ppixel_alpha = ((win->format == ARGB888)||(win->format == ABGR888)) ? 1 : 0;
535         global_alpha = (win->g_alpha_val == 0) ? 0 : 1; 
536         alpha_config.src_global_alpha_val = win->g_alpha_val;
537         win->alpha_mode = AB_SRC_OVER;
538         /*printk("%s,alpha_mode=%d,alpha_en=%d,ppixel_a=%d,gla_a=%d\n",
539                 __func__,win->alpha_mode,win->alpha_en,ppixel_alpha,global_alpha);*/
540         switch(win->alpha_mode){
541         case AB_USER_DEFINE:
542                 break;
543         case AB_CLEAR:
544                 alpha_config.src_factor_mode=AA_ZERO;
545                 alpha_config.dst_factor_mode=AA_ZERO;           
546                 break;
547         case AB_SRC:
548                 alpha_config.src_factor_mode=AA_ONE;
549                 alpha_config.dst_factor_mode=AA_ZERO;
550                 break;
551         case AB_DST:
552                 alpha_config.src_factor_mode=AA_ZERO;
553                 alpha_config.dst_factor_mode=AA_ONE;
554                 break;
555         case AB_SRC_OVER:
556                 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
557                 if(global_alpha)
558                         alpha_config.src_factor_mode=AA_SRC_GLOBAL;
559                 else
560                         alpha_config.src_factor_mode=AA_ONE;
561                 alpha_config.dst_factor_mode=AA_SRC_INVERSE;            
562                 break;
563         case AB_DST_OVER:
564                 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
565                 alpha_config.src_factor_mode=AA_SRC_INVERSE;
566                 alpha_config.dst_factor_mode=AA_ONE;
567                 break;
568         case AB_SRC_IN:
569                 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
570                 alpha_config.src_factor_mode=AA_SRC;
571                 alpha_config.dst_factor_mode=AA_ZERO;
572                 break;
573         case AB_DST_IN:
574                 alpha_config.src_factor_mode=AA_ZERO;
575                 alpha_config.dst_factor_mode=AA_SRC;
576                 break;
577         case AB_SRC_OUT:
578                 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
579                 alpha_config.src_factor_mode=AA_SRC_INVERSE;
580                 alpha_config.dst_factor_mode=AA_ZERO;           
581                 break;
582         case AB_DST_OUT:
583                 alpha_config.src_factor_mode=AA_ZERO;
584                 alpha_config.dst_factor_mode=AA_SRC_INVERSE;    
585                 break;
586         case AB_SRC_ATOP:
587                 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
588                 alpha_config.src_factor_mode=AA_SRC;
589                 alpha_config.dst_factor_mode=AA_SRC_INVERSE;            
590                 break;
591         case AB_DST_ATOP:
592                 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
593                 alpha_config.src_factor_mode=AA_SRC_INVERSE;
594                 alpha_config.dst_factor_mode=AA_SRC;            
595                 break;
596         case XOR:
597                 alpha_config.src_color_mode=AA_SRC_PRE_MUL;
598                 alpha_config.src_factor_mode=AA_SRC_INVERSE;
599                 alpha_config.dst_factor_mode=AA_SRC_INVERSE;                    
600                 break;  
601         case AB_SRC_OVER_GLOBAL:        
602                 alpha_config.src_global_alpha_mode=AA_PER_PIX_GLOBAL;
603                 alpha_config.src_color_mode=AA_SRC_NO_PRE_MUL;
604                 alpha_config.src_factor_mode=AA_SRC_GLOBAL;
605                 alpha_config.dst_factor_mode=AA_SRC_INVERSE;
606                 break;
607         default:
608                 pr_err("alpha mode error\n");
609                 break;          
610         }
611         if((ppixel_alpha == 1)&&(global_alpha == 1)){
612                 alpha_config.src_global_alpha_mode = AA_PER_PIX_GLOBAL;
613         }else if(ppixel_alpha == 1){
614                 alpha_config.src_global_alpha_mode = AA_PER_PIX;
615         }else if(global_alpha == 1){
616                 alpha_config.src_global_alpha_mode = AA_GLOBAL;
617         }else{
618                 dev_warn(lcdc_dev->dev,"alpha_en should be 0\n");
619         }
620         alpha_config.src_alpha_mode = AA_STRAIGHT;
621         alpha_config.src_alpha_cal_m0 = AA_NO_SAT;
622
623         switch(win_id){
624         case 0:
625                 src_alpha_ctl = 0x60;
626                 dst_alpha_ctl = 0x64;
627                 break;
628         case 1:
629                 src_alpha_ctl = 0xa0;
630                 dst_alpha_ctl = 0xa4;
631                 break;
632         case 2:
633                 src_alpha_ctl = 0xdc;
634                 dst_alpha_ctl = 0xec;
635                 break;
636         case 3:
637                 src_alpha_ctl = 0x12c;
638                 dst_alpha_ctl = 0x13c;
639                 break;
640         }
641         mask = m_WIN0_DST_FACTOR_M0;
642         val  = v_WIN0_DST_FACTOR_M0(alpha_config.dst_factor_mode);
643         lcdc_msk_reg(lcdc_dev, dst_alpha_ctl, mask, val);
644         mask = m_WIN0_SRC_ALPHA_EN | m_WIN0_SRC_COLOR_M0 |
645                 m_WIN0_SRC_ALPHA_M0 | m_WIN0_SRC_BLEND_M0 |
646                 m_WIN0_SRC_ALPHA_CAL_M0 | m_WIN0_SRC_FACTOR_M0|
647                 m_WIN0_SRC_GLOBAL_ALPHA;
648         val = v_WIN0_SRC_ALPHA_EN(1) | 
649                 v_WIN0_SRC_COLOR_M0(alpha_config.src_color_mode) |
650                 v_WIN0_SRC_ALPHA_M0(alpha_config.src_alpha_mode) |
651                 v_WIN0_SRC_BLEND_M0(alpha_config.src_global_alpha_mode) |
652                 v_WIN0_SRC_ALPHA_CAL_M0(alpha_config.src_alpha_cal_m0) |
653                 v_WIN0_SRC_FACTOR_M0(alpha_config.src_factor_mode) |
654                 v_WIN0_SRC_GLOBAL_ALPHA(alpha_config.src_global_alpha_val);
655         lcdc_msk_reg(lcdc_dev, src_alpha_ctl, mask, val);
656
657         return 0;
658 }
659 static int rk3288_lcdc_area_swap(struct rk_lcdc_win *win,int area_num)
660 {
661         struct rk_lcdc_win_area area_temp;
662         switch(area_num){
663         case 2:
664                 area_temp = win->area[0];
665                 win->area[0] = win->area[1];
666                 win->area[1] = area_temp;
667                 break;
668         case 3:
669                 area_temp = win->area[0];
670                 win->area[0] = win->area[2];
671                 win->area[2] = area_temp;
672                 break;
673         case 4:
674                 area_temp = win->area[0];
675                 win->area[0] = win->area[3];
676                 win->area[3] = area_temp;
677                 
678                 area_temp = win->area[1];
679                 win->area[1] = win->area[2];
680                 win->area[2] = area_temp;       
681                 break;
682         default:
683                 printk(KERN_WARNING "un supported area num!\n");
684                 break;
685         }
686         return 0;
687 }
688
689 static int rk3288_win_area_check_var(int win_id,int area_num,struct rk_lcdc_win_area *area_pre,
690                         struct rk_lcdc_win_area *area_now)
691 {
692         if((area_pre->ypos >= area_now->ypos) ||
693                 (area_pre->ypos+area_pre->ysize > area_now->ypos)){
694                 area_now->state = 0;
695                 pr_err("win[%d]:\n"
696                         "area_pre[%d]:ypos[%d],ysize[%d]\n"
697                         "area_now[%d]:ypos[%d],ysize[%d]\n",
698                         win_id,
699                         area_num-1,area_pre->ypos,area_pre->ysize,
700                         area_num,  area_now->ypos,area_now->ysize);
701                 return -EINVAL;
702         }
703         return 0;
704 }
705
706 static int rk3288_win_0_1_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
707 {
708         struct lcdc_device *lcdc_dev =
709             container_of(dev_drv, struct lcdc_device, driver);
710         struct rk_lcdc_win *win = dev_drv->win[win_id];
711         unsigned int mask, val, off;
712         off = win_id * 0x40;
713         if(win->win_lb_mode == 5)
714                 win->win_lb_mode = 4;
715
716         if(win->state == 1){
717                 mask =  m_WIN0_EN | m_WIN0_DATA_FMT | m_WIN0_FMT_10 |
718                         m_WIN0_LB_MODE | m_WIN0_RB_SWAP;
719                 val  =  v_WIN0_EN(win->state) | v_WIN0_DATA_FMT(win->fmt_cfg) |
720                         v_WIN0_FMT_10(win->fmt_10) | 
721                         v_WIN0_LB_MODE(win->win_lb_mode) | 
722                         v_WIN0_RB_SWAP(win->swap_rb);
723                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0+off, mask,val);       
724         
725                 mask =  m_WIN0_BIC_COE_SEL |
726                         m_WIN0_VSD_YRGB_GT4 | m_WIN0_VSD_YRGB_GT2 |
727                         m_WIN0_VSD_CBR_GT4 | m_WIN0_VSD_CBR_GT2 |
728                         m_WIN0_YRGB_HOR_SCL_MODE | m_WIN0_YRGB_VER_SCL_MODE |
729                         m_WIN0_YRGB_HSD_MODE | m_WIN0_YRGB_VSU_MODE |
730                         m_WIN0_YRGB_VSD_MODE | m_WIN0_CBR_HOR_SCL_MODE |
731                         m_WIN0_CBR_VER_SCL_MODE | m_WIN0_CBR_HSD_MODE |
732                         m_WIN0_CBR_VSU_MODE | m_WIN0_CBR_VSD_MODE;
733                 val =   v_WIN0_BIC_COE_SEL(win->bic_coe_el) |
734                         v_WIN0_VSD_YRGB_GT4(win->vsd_yrgb_gt4) |
735                         v_WIN0_VSD_YRGB_GT2(win->vsd_yrgb_gt2) |
736                         v_WIN0_VSD_CBR_GT4(win->vsd_cbr_gt4) |
737                         v_WIN0_VSD_CBR_GT2(win->vsd_cbr_gt2) |
738                         v_WIN0_YRGB_HOR_SCL_MODE(win->yrgb_hor_scl_mode) |
739                         v_WIN0_YRGB_VER_SCL_MODE(win->yrgb_ver_scl_mode) |
740                         v_WIN0_YRGB_HSD_MODE(win->yrgb_hsd_mode) |
741                         v_WIN0_YRGB_VSU_MODE(win->yrgb_vsu_mode) |
742                         v_WIN0_YRGB_VSD_MODE(win->yrgb_vsd_mode) |
743                         v_WIN0_CBR_HOR_SCL_MODE(win->cbr_hor_scl_mode) |
744                         v_WIN0_CBR_VER_SCL_MODE(win->cbr_ver_scl_mode) |
745                         v_WIN0_CBR_HSD_MODE(win->cbr_hsd_mode) |
746                         v_WIN0_CBR_VSU_MODE(win->cbr_vsu_mode) |
747                         v_WIN0_CBR_VSD_MODE(win->cbr_vsd_mode);
748                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL1+off, mask,val);
749         
750                 val =   v_WIN0_VIR_STRIDE(win->area[0].y_vir_stride) |
751                         v_WIN0_VIR_STRIDE_UV(win->area[0].uv_vir_stride);       
752                 lcdc_writel(lcdc_dev, WIN0_VIR+off, val);       
753                 /*lcdc_writel(lcdc_dev, WIN0_YRGB_MST+off, win->area[0].y_addr); 
754                 lcdc_writel(lcdc_dev, WIN0_CBR_MST+off, win->area[0].uv_addr);*/
755                 val =   v_WIN0_ACT_WIDTH(win->area[0].xact) |
756                         v_WIN0_ACT_HEIGHT(win->area[0].yact);
757                 lcdc_writel(lcdc_dev, WIN0_ACT_INFO+off, val); 
758         
759                 val =   v_WIN0_DSP_WIDTH(win->area[0].xsize) |
760                         v_WIN0_DSP_HEIGHT(win->area[0].ysize);
761                 lcdc_writel(lcdc_dev, WIN0_DSP_INFO+off, val); 
762         
763                 val =   v_WIN0_DSP_XST(win->area[0].dsp_stx) |
764                         v_WIN0_DSP_YST(win->area[0].dsp_sty);
765                 lcdc_writel(lcdc_dev, WIN0_DSP_ST+off, val); 
766         
767                 val =   v_WIN0_HS_FACTOR_YRGB(win->scale_yrgb_x) |
768                         v_WIN0_VS_FACTOR_YRGB(win->scale_yrgb_y);
769                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB+off, val); 
770         
771                 val =   v_WIN0_HS_FACTOR_CBR(win->scale_cbcr_x) |
772                         v_WIN0_VS_FACTOR_CBR(win->scale_cbcr_y);
773                 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR+off, val); 
774                 if(win->alpha_en == 1)
775                         rk3288_lcdc_alpha_cfg(dev_drv,win_id);
776                 else{
777                         mask = m_WIN0_SRC_ALPHA_EN;
778                         val = v_WIN0_SRC_ALPHA_EN(0);
779                         lcdc_msk_reg(lcdc_dev,WIN0_SRC_ALPHA_CTRL+off,mask,val);                                
780                 }
781                 /*offset*/      
782         }else{
783                 mask = m_WIN0_EN;
784                 val = v_WIN0_EN(win->state);
785                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0+off, mask,val); 
786         }
787         return 0;
788 }
789
790 static int rk3288_win_2_3_reg_update(struct rk_lcdc_driver *dev_drv,int win_id)
791 {
792         struct lcdc_device *lcdc_dev =
793             container_of(dev_drv, struct lcdc_device, driver);
794         struct rk_lcdc_win *win = dev_drv->win[win_id];
795         struct rk_screen *screen = dev_drv->cur_screen;
796         unsigned int mask, val, off;
797         off = (win_id-2) * 0x50;
798         if((screen->y_mirror == 1)&&(win->area_num > 1)){
799                 rk3288_lcdc_area_swap(win,win->area_num);
800         }
801         
802         if(win->state == 1){
803                 mask =  m_WIN2_EN | m_WIN2_DATA_FMT | m_WIN2_RB_SWAP;
804                 val  =  v_WIN2_EN(1) | v_WIN2_DATA_FMT(win->fmt_cfg) |
805                         v_WIN2_RB_SWAP(win->swap_rb);   
806                 lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
807                 /*area 0*/
808                 if(win->area[0].state == 1){
809                         mask = m_WIN2_MST0_EN;
810                         val  = v_WIN2_MST0_EN(win->area[0].state);
811                         lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
812
813                         mask = m_WIN2_VIR_STRIDE0;
814                         val  = v_WIN2_VIR_STRIDE0(win->area[0].y_vir_stride);
815                         lcdc_msk_reg(lcdc_dev,WIN2_VIR0_1+off,mask,val);
816
817                         /*lcdc_writel(lcdc_dev,WIN2_MST0+off,win->area[0].y_addr);*/
818                         val  =  v_WIN2_DSP_WIDTH0(win->area[0].xsize) | 
819                                 v_WIN2_DSP_HEIGHT0(win->area[0].ysize);
820                         lcdc_writel(lcdc_dev,WIN2_DSP_INFO0+off,val);
821                         val  =  v_WIN2_DSP_XST0(win->area[0].dsp_stx) |
822                                 v_WIN2_DSP_YST0(win->area[0].dsp_sty);
823                         lcdc_writel(lcdc_dev,WIN2_DSP_ST0+off,val);     
824                 }else{
825                         mask = m_WIN2_MST0_EN;
826                         val  = v_WIN2_MST0_EN(0);
827                         lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
828                 }
829                 /*area 1*/
830                 if(win->area[1].state == 1){
831                         rk3288_win_area_check_var(win_id,1,&win->area[0],&win->area[1]);
832                         
833                         mask = m_WIN2_MST1_EN;
834                         val  = v_WIN2_MST1_EN(win->area[1].state);
835                         lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
836
837                         mask = m_WIN2_VIR_STRIDE1;
838                         val  = v_WIN2_VIR_STRIDE1(win->area[1].y_vir_stride);
839                         lcdc_msk_reg(lcdc_dev,WIN2_VIR0_1+off,mask,val);
840
841                         /*lcdc_writel(lcdc_dev,WIN2_MST1+off,win->area[1].y_addr);*/
842                         val  =  v_WIN2_DSP_WIDTH1(win->area[1].xsize) | 
843                                 v_WIN2_DSP_HEIGHT1(win->area[1].ysize);
844                         lcdc_writel(lcdc_dev,WIN2_DSP_INFO1+off,val);
845                         val  =  v_WIN2_DSP_XST1(win->area[1].dsp_stx) |
846                                 v_WIN2_DSP_YST1(win->area[1].dsp_sty);
847                         lcdc_writel(lcdc_dev,WIN2_DSP_ST1+off,val);     
848                 }else{
849                         mask = m_WIN2_MST1_EN;
850                         val  = v_WIN2_MST1_EN(0);
851                         lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
852                 }
853                 /*area 2*/
854                 if(win->area[2].state == 1){
855                         rk3288_win_area_check_var(win_id,2,&win->area[1],&win->area[2]);
856                         
857                         mask = m_WIN2_MST2_EN;
858                         val  = v_WIN2_MST2_EN(win->area[2].state);
859                         lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
860
861                         mask = m_WIN2_VIR_STRIDE2;
862                         val  = v_WIN2_VIR_STRIDE2(win->area[2].y_vir_stride);
863                         lcdc_msk_reg(lcdc_dev,WIN2_VIR2_3+off,mask,val);
864
865                         /*lcdc_writel(lcdc_dev,WIN2_MST2+off,win->area[2].y_addr);*/
866                         val  =  v_WIN2_DSP_WIDTH2(win->area[2].xsize) | 
867                                 v_WIN2_DSP_HEIGHT2(win->area[2].ysize);
868                         lcdc_writel(lcdc_dev,WIN2_DSP_INFO2+off,val);
869                         val  =  v_WIN2_DSP_XST2(win->area[2].dsp_stx) |
870                                 v_WIN2_DSP_YST2(win->area[2].dsp_sty);
871                         lcdc_writel(lcdc_dev,WIN2_DSP_ST2+off,val);     
872                 }else{
873                         mask = m_WIN2_MST2_EN;
874                         val  = v_WIN2_MST2_EN(0);
875                         lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
876                 }
877                 /*area 3*/
878                 if(win->area[3].state == 1){
879                         rk3288_win_area_check_var(win_id,3,&win->area[2],&win->area[3]);
880                         
881                         mask = m_WIN2_MST3_EN;
882                         val  = v_WIN2_MST3_EN(win->area[3].state);
883                         lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
884
885                         mask = m_WIN2_VIR_STRIDE3;
886                         val  = v_WIN2_VIR_STRIDE3(win->area[3].y_vir_stride);
887                         lcdc_msk_reg(lcdc_dev,WIN2_VIR2_3+off,mask,val);
888
889                         /*lcdc_writel(lcdc_dev,WIN2_MST3+off,win->area[3].y_addr);*/
890                         val  =  v_WIN2_DSP_WIDTH3(win->area[3].xsize) | 
891                                 v_WIN2_DSP_HEIGHT3(win->area[3].ysize);
892                         lcdc_writel(lcdc_dev,WIN2_DSP_INFO3+off,val);
893                         val  =  v_WIN2_DSP_XST3(win->area[3].dsp_stx) |
894                                 v_WIN2_DSP_YST3(win->area[3].dsp_sty);
895                         lcdc_writel(lcdc_dev,WIN2_DSP_ST3+off,val);     
896                 }else{
897                         mask = m_WIN2_MST3_EN;
898                         val  = v_WIN2_MST3_EN(0);
899                         lcdc_msk_reg(lcdc_dev,WIN2_CTRL0+off,mask,val);
900                 }       
901
902                 if(win->alpha_en == 1)
903                         rk3288_lcdc_alpha_cfg(dev_drv,win_id);
904                 else{
905                         mask = m_WIN2_SRC_ALPHA_EN;
906                         val = v_WIN2_SRC_ALPHA_EN(0);
907                         lcdc_msk_reg(lcdc_dev,WIN2_SRC_ALPHA_CTRL+off,mask,val);                                
908                 }
909         }else{
910                 mask =  m_WIN2_EN | m_WIN2_MST0_EN |
911                         m_WIN2_MST0_EN | m_WIN2_MST2_EN |
912                         m_WIN2_MST3_EN;
913                 val  =  v_WIN2_EN(win->state) | v_WIN2_MST0_EN(0) |
914                         v_WIN2_MST1_EN(0) | v_WIN2_MST2_EN(0) |
915                         v_WIN2_MST3_EN(0);
916                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0+off, mask,val); 
917         }
918         return 0;
919 }
920
921 static int rk3288_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
922 {
923         struct lcdc_device *lcdc_dev =
924             container_of(dev_drv, struct lcdc_device, driver);
925         int timeout;
926         unsigned long flags;
927
928         spin_lock(&lcdc_dev->reg_lock);
929         if(likely(lcdc_dev->clk_on))
930         {
931                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
932                              v_STANDBY_EN(lcdc_dev->standby));
933                 rk3288_win_0_1_reg_update(dev_drv,0);
934                 rk3288_win_0_1_reg_update(dev_drv,1);
935                 rk3288_win_2_3_reg_update(dev_drv,2);
936                 rk3288_win_2_3_reg_update(dev_drv,3);
937                 /*rk3288_lcdc_post_cfg(dev_drv);*/
938                 lcdc_cfg_done(lcdc_dev);
939         }
940         spin_unlock(&lcdc_dev->reg_lock);
941         
942         /*if (dev_drv->wait_fs) {*/
943         if (0){
944                 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
945                 init_completion(&dev_drv->frame_done);
946                 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
947                 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
948                                                       msecs_to_jiffies
949                                                       (dev_drv->cur_screen->ft +
950                                                        5));
951                 if (!timeout && (!dev_drv->frame_done.done)) {
952                         dev_warn(lcdc_dev->dev, "wait for new frame start time out!\n");
953                         return -ETIMEDOUT;
954                 }
955         }
956         DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
957         return 0;
958
959 }
960
961 static int rk3288_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
962 {
963         if (lcdc_dev->driver.iommu_enabled)
964                 memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0x330);
965         else
966                 memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0x1fc);
967         return 0;
968 }
969 static int rk3288_lcdc_mmu_en(struct rk_lcdc_driver *dev_drv)
970 {
971         u32 mask,val;
972         struct lcdc_device *lcdc_dev =
973             container_of(dev_drv, struct lcdc_device, driver);
974         spin_lock(&lcdc_dev->reg_lock);
975         if (likely(lcdc_dev->clk_on)) {
976                 mask = m_MMU_EN;
977                 val = v_MMU_EN(1);
978                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
979                 mask = m_AXI_MAX_OUTSTANDING_EN | m_AXI_OUTSTANDING_MAX_NUM;
980                 val = v_AXI_OUTSTANDING_MAX_NUM(31) | v_AXI_MAX_OUTSTANDING_EN(1);
981                 lcdc_msk_reg(lcdc_dev, SYS_CTRL1, mask, val);
982         }
983         spin_unlock(&lcdc_dev->reg_lock);
984         return 0;
985 }
986
987 static int rk3288_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
988 {
989 #ifdef CONFIG_RK_FPGA
990         return 0;
991 #endif
992         int ret,fps;
993         struct lcdc_device *lcdc_dev =
994             container_of(dev_drv, struct lcdc_device, driver);
995         struct rk_screen *screen = dev_drv->cur_screen;
996
997         ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
998         if (ret)
999                 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
1000         lcdc_dev->pixclock =
1001                  div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1002         lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
1003         
1004         fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
1005         screen->ft = 1000 / fps;
1006         dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
1007                  lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
1008         return 0;
1009
1010 }
1011
1012 static int rk3288_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
1013 {
1014         u16 face = 0;
1015         u32 v=0;
1016         struct lcdc_device *lcdc_dev =
1017             container_of(dev_drv, struct lcdc_device, driver);
1018         struct rk_screen *screen = dev_drv->cur_screen;
1019         u16 hsync_len = screen->mode.hsync_len;
1020         u16 left_margin = screen->mode.left_margin;
1021         u16 right_margin = screen->mode.right_margin;
1022         u16 vsync_len = screen->mode.vsync_len;
1023         u16 upper_margin = screen->mode.upper_margin;
1024         u16 lower_margin = screen->mode.lower_margin;
1025         u16 x_res = screen->mode.xres;
1026         u16 y_res = screen->mode.yres;
1027         u32 mask, val;
1028         u16 h_total,v_total;
1029         
1030         h_total = hsync_len + left_margin  + x_res + right_margin;
1031         v_total = vsync_len + upper_margin + y_res + lower_margin;
1032
1033         screen->post_dsp_stx = x_res * (100 - screen->overscan.left) / 200;
1034         screen->post_dsp_sty = y_res * (100 - screen->overscan.top) / 200;
1035         screen->post_xsize = x_res * (screen->overscan.left + screen->overscan.right) / 200;
1036         screen->post_ysize = y_res * (screen->overscan.top + screen->overscan.bottom) / 200;
1037         
1038         spin_lock(&lcdc_dev->reg_lock);
1039         if (likely(lcdc_dev->clk_on)) {
1040                 switch (screen->face) {
1041                 case OUT_P565:
1042                         face = OUT_P565;
1043                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1044                             m_DITHER_DOWN_SEL;
1045                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
1046                             v_DITHER_DOWN_SEL(1);
1047                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1048                         break;
1049                 case OUT_P666:
1050                         face = OUT_P666;
1051                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1052                             m_DITHER_DOWN_SEL;
1053                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
1054                             v_DITHER_DOWN_SEL(1);
1055                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1056                         break;
1057                 case OUT_D888_P565:
1058                         face = OUT_P888;
1059                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1060                             m_DITHER_DOWN_SEL;
1061                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
1062                             v_DITHER_DOWN_SEL(1);
1063                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1064                         break;
1065                 case OUT_D888_P666:
1066                         face = OUT_P888;
1067                         mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
1068                             m_DITHER_DOWN_SEL;
1069                         val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
1070                             v_DITHER_DOWN_SEL(1);
1071                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1072                         break;
1073                 case OUT_P888:
1074                         face = OUT_P888;
1075                         mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1076                         val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1077                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1078                         break;
1079                 default:
1080                         dev_err(lcdc_dev->dev,"un supported interface!\n");
1081                         break;
1082                 }
1083                 switch(screen->type){
1084                 case SCREEN_RGB:
1085                 case SCREEN_LVDS:
1086                 case SCREEN_DUAL_LVDS:                  
1087                         mask = m_RGB_OUT_EN;
1088                         val = v_RGB_OUT_EN(1);
1089                         v = 1 << (3+16);
1090                         v |= (lcdc_dev->id << 3);
1091                         break;
1092                 case SCREEN_HDMI:
1093                         face = OUT_RGB_AAA;
1094                         mask = m_HDMI_OUT_EN;
1095                         val = v_HDMI_OUT_EN(1);         
1096                         break;
1097                 case SCREEN_MIPI:
1098                         mask = m_MIPI_OUT_EN;
1099                         val = v_MIPI_OUT_EN(1);                 
1100                         break;
1101                 case SCREEN_DUAL_MIPI:
1102                         mask = m_MIPI_OUT_EN | m_DOUB_CHANNEL_EN;
1103                         val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1);  
1104                         break;
1105                 case SCREEN_EDP:
1106                         face = OUT_RGB_AAA;  /*RGB AAA output*/
1107                         mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
1108                         val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
1109                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
1110                         mask = m_EDP_OUT_EN;
1111                         val = v_EDP_OUT_EN(1);          
1112                         break;
1113                 }
1114                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, mask, val);
1115 #ifndef CONFIG_RK_FPGA
1116                 writel_relaxed(v, RK_GRF_VIRT + RK3288_GRF_SOC_CON6);
1117 #endif          
1118                 mask = m_DSP_OUT_MODE | m_DSP_HSYNC_POL | m_DSP_VSYNC_POL |
1119                        m_DSP_DEN_POL | m_DSP_DCLK_POL | m_DSP_BG_SWAP | 
1120                        m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
1121                        m_DSP_DUMMY_SWAP | m_DSP_OUT_ZERO | m_DSP_BLANK_EN | 
1122                        m_DSP_BLACK_EN | m_DSP_X_MIR_EN | m_DSP_Y_MIR_EN;
1123                 val = v_DSP_OUT_MODE(face) | v_DSP_HSYNC_POL(screen->pin_hsync) |
1124                       v_DSP_VSYNC_POL(screen->pin_vsync) | 
1125                       v_DSP_DEN_POL(screen->pin_den) | v_DSP_DCLK_POL(screen->pin_dclk) |
1126                       v_DSP_BG_SWAP(screen->swap_gb) | v_DSP_RB_SWAP(screen->swap_rb) | 
1127                       v_DSP_RG_SWAP(screen->swap_rg) | 
1128                       v_DSP_DELTA_SWAP(screen->swap_delta) |
1129                       v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_DSP_OUT_ZERO(0) | 
1130                       v_DSP_BLANK_EN(0) | v_DSP_BLACK_EN(0) |
1131                       v_DSP_X_MIR_EN(screen->x_mirror) | v_DSP_Y_MIR_EN(screen->y_mirror);
1132                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
1133
1134                 mask = m_DSP_BG_BLUE | m_DSP_BG_GREEN | m_DSP_BG_RED;
1135                 val  = v_DSP_BG_BLUE(0) | v_DSP_BG_GREEN(0) | v_DSP_BG_RED(0);
1136                 lcdc_msk_reg(lcdc_dev, DSP_BG, mask, val);
1137
1138                 mask = m_DSP_HS_PW | m_DSP_HTOTAL;
1139                 val = v_DSP_HS_PW(hsync_len) | v_DSP_HTOTAL(h_total);
1140                 lcdc_msk_reg(lcdc_dev, DSP_HTOTAL_HS_END, mask, val);
1141
1142                 mask = m_DSP_HACT_END | m_DSP_HACT_ST;
1143                 val = v_DSP_HACT_END(hsync_len + left_margin + x_res) |
1144                     v_DSP_HACT_ST(hsync_len + left_margin);
1145                 lcdc_msk_reg(lcdc_dev, DSP_HACT_ST_END, mask, val);
1146
1147                 mask = m_DSP_VS_PW | m_DSP_VTOTAL;
1148                 val = v_DSP_VS_PW(vsync_len) | v_DSP_VTOTAL(v_total);
1149                 lcdc_msk_reg(lcdc_dev, DSP_VTOTAL_VS_END, mask, val);
1150
1151                 mask = m_DSP_VACT_END | m_DSP_VACT_ST;
1152                 val = v_DSP_VACT_END(vsync_len + upper_margin + y_res) |
1153                     v_DSP_VACT_ST(vsync_len + upper_margin);
1154                 lcdc_msk_reg(lcdc_dev, DSP_VACT_ST_END, mask, val);
1155
1156                 rk3288_lcdc_post_cfg(dev_drv);
1157         }
1158         spin_unlock(&lcdc_dev->reg_lock);
1159         rk3288_lcdc_set_dclk(dev_drv);
1160         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
1161                 dev_drv->trsm_ops->enable();
1162         if (screen->init)
1163                 screen->init();
1164         
1165         return 0;
1166 }
1167
1168 /*enable layer,open:1,enable;0 disable*/
1169 static int win0_open(struct lcdc_device *lcdc_dev, bool open)
1170 {
1171         spin_lock(&lcdc_dev->reg_lock);
1172         if (likely(lcdc_dev->clk_on)) {
1173                 if (open) {
1174                         if (!lcdc_dev->atv_layer_cnt) {
1175                                 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1176                                 lcdc_dev->standby = 0;
1177                         }
1178                         lcdc_dev->atv_layer_cnt++;
1179                 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1180                         lcdc_dev->atv_layer_cnt--;
1181                 }
1182                 lcdc_dev->driver.win[0]->state = open;
1183                 if (!lcdc_dev->atv_layer_cnt) {
1184                         dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1185                         lcdc_dev->standby = 1;
1186                 }
1187         }
1188         spin_unlock(&lcdc_dev->reg_lock);
1189
1190         return 0;
1191 }
1192
1193 static int win1_open(struct lcdc_device *lcdc_dev, bool open)
1194 {
1195         spin_lock(&lcdc_dev->reg_lock);
1196         if (likely(lcdc_dev->clk_on)) {
1197                 if (open) {
1198                         if (!lcdc_dev->atv_layer_cnt) {
1199                                 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1200                                 lcdc_dev->standby = 0;
1201                         }
1202                         lcdc_dev->atv_layer_cnt++;
1203                 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1204                         lcdc_dev->atv_layer_cnt--;
1205                 }
1206                 lcdc_dev->driver.win[1]->state = open;
1207
1208                 /*if no layer used,disable lcdc*/
1209                 if (!lcdc_dev->atv_layer_cnt) {
1210                         dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1211                         lcdc_dev->standby = 1;
1212                 }
1213         }
1214         spin_unlock(&lcdc_dev->reg_lock);
1215
1216         return 0;
1217 }
1218
1219 static int win2_open(struct lcdc_device *lcdc_dev, bool open)
1220 {
1221         spin_lock(&lcdc_dev->reg_lock);
1222         if (likely(lcdc_dev->clk_on)) {
1223                 if (open) {
1224                         if (!lcdc_dev->atv_layer_cnt) {
1225                                 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1226                                 lcdc_dev->standby = 0;
1227                         }
1228                         lcdc_dev->atv_layer_cnt++;
1229                 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1230                         lcdc_dev->atv_layer_cnt--;
1231                 }
1232                 lcdc_dev->driver.win[2]->state = open;
1233
1234                 /*if no layer used,disable lcdc*/
1235                 if (!lcdc_dev->atv_layer_cnt) {
1236                         dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1237                         lcdc_dev->standby = 1;
1238                 }
1239         }
1240         spin_unlock(&lcdc_dev->reg_lock);
1241
1242         return 0;
1243 }
1244
1245 static int win3_open(struct lcdc_device *lcdc_dev, bool open)
1246 {
1247         spin_lock(&lcdc_dev->reg_lock);
1248         if (likely(lcdc_dev->clk_on)) {
1249                 if (open) {
1250                         if (!lcdc_dev->atv_layer_cnt) {
1251                                 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
1252                                 lcdc_dev->standby = 0;
1253                         }
1254                         lcdc_dev->atv_layer_cnt++;
1255                 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
1256                         lcdc_dev->atv_layer_cnt--;
1257                 }
1258                 lcdc_dev->driver.win[3]->state = open;
1259
1260                 /*if no layer used,disable lcdc*/
1261                 if (!lcdc_dev->atv_layer_cnt) {
1262                         dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
1263                         lcdc_dev->standby = 1;
1264                 }
1265         }
1266         spin_unlock(&lcdc_dev->reg_lock);
1267
1268         return 0;
1269 }
1270 static int rk3288_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv)
1271 {
1272         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1273                                         struct lcdc_device, driver);
1274         u32 mask,val;
1275         struct rk_screen *screen = dev_drv->cur_screen;
1276         
1277         mask = m_FS_INTR_CLR | m_FS_INTR_EN | m_LINE_FLAG_INTR_CLR |
1278                             m_LINE_FLAG_INTR_EN | m_BUS_ERROR_INTR_CLR | 
1279                             m_BUS_ERROR_INTR_EN | m_DSP_LINE_FLAG_NUM;
1280         val = v_FS_INTR_CLR(1) | v_FS_INTR_EN(1) | v_LINE_FLAG_INTR_CLR(1) |
1281             v_LINE_FLAG_INTR_EN(1) | v_BUS_ERROR_INTR_CLR(1) | v_BUS_ERROR_INTR_EN(0) |
1282             v_DSP_LINE_FLAG_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
1283             screen->mode.yres);
1284         lcdc_msk_reg(lcdc_dev, INTR_CTRL0, mask, val);  
1285 #ifdef LCDC_IRQ_EMPTY_DEBUG
1286                  mask = m_WIN0_EMPTY_INTR_EN | m_WIN1_EMPTY_INTR_EN | m_WIN2_EMPTY_INTR_EN |
1287                          m_WIN3_EMPTY_INTR_EN |m_HWC_EMPTY_INTR_EN | m_POST_BUF_EMPTY_INTR_EN |
1288                          m_PWM_GEN_INTR_EN;
1289                  val = v_WIN0_EMPTY_INTR_EN(1) | v_WIN1_EMPTY_INTR_EN(1) | v_WIN2_EMPTY_INTR_EN(1) |
1290                          v_WIN3_EMPTY_INTR_EN(1)| v_HWC_EMPTY_INTR_EN(1) | v_POST_BUF_EMPTY_INTR_EN(1) |
1291                          v_PWM_GEN_INTR_EN(1);
1292                  lcdc_msk_reg(lcdc_dev, INTR_CTRL1, mask, val);
1293 #endif  
1294         return 0;
1295 }
1296
1297 static int rk3288_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
1298                             bool open)
1299 {
1300         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1301                                         struct lcdc_device, driver);
1302         int sys_status = (dev_drv->id == 0) ?
1303                         SYS_STATUS_LCDC0 : SYS_STATUS_LCDC1;
1304
1305         /*enable clk,when first layer open */
1306         if ((open) && (!lcdc_dev->atv_layer_cnt)) {
1307                 rockchip_set_system_status(sys_status);
1308                 rk3288_lcdc_pre_init(dev_drv);
1309 #if defined(CONFIG_ROCKCHIP_IOMMU)
1310                 if (dev_drv->iommu_enabled) {
1311                         if (!dev_drv->mmu_dev) {
1312                                 dev_drv->mmu_dev =
1313                                         rk_fb_get_sysmmu_device_by_compatible(dev_drv->mmu_dts_name);
1314                                 if (dev_drv->mmu_dev) {
1315                                         rk_fb_platform_set_sysmmu(dev_drv->mmu_dev,
1316                                                                   dev_drv->dev);
1317                                         rockchip_iovmm_activate(dev_drv->dev);
1318                                 } else {
1319                                         dev_err(dev_drv->dev,
1320                                                 "failed to get rockchip iommu device\n");
1321                                         return -1;
1322                                 }
1323                         }
1324                 }
1325 #endif
1326                 rk3288_lcdc_clk_enable(lcdc_dev);
1327                 rk3288_lcdc_reg_restore(lcdc_dev);
1328                 if (dev_drv->iommu_enabled)
1329                         rk3288_lcdc_mmu_en(dev_drv);
1330                 if ((support_uboot_display()&&(lcdc_dev->prop == PRMRY))) {
1331                         rk3288_lcdc_set_dclk(dev_drv);
1332                         rk3288_lcdc_enable_irq(dev_drv);
1333                 } else {
1334                         rk3288_load_screen(dev_drv, 1);
1335                 }
1336                 if (dev_drv->bcsh.enable)
1337                         rk3288_lcdc_set_bcsh(dev_drv, 1);
1338                 spin_lock(&lcdc_dev->reg_lock);
1339                 if (dev_drv->cur_screen->dsp_lut)
1340                         rk3288_lcdc_set_lut(dev_drv);
1341                 spin_unlock(&lcdc_dev->reg_lock);
1342         }
1343
1344         if (win_id == 0)
1345                 win0_open(lcdc_dev, open);
1346         else if (win_id == 1)
1347                 win1_open(lcdc_dev, open);
1348         else if (win_id == 2)
1349                 win2_open(lcdc_dev, open);
1350         else if (win_id == 3)
1351                 win3_open(lcdc_dev, open);
1352         else
1353                 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
1354
1355         /* when all layer closed,disable clk */
1356         if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
1357                 rk3288_lcdc_disable_irq(lcdc_dev);
1358                 rk3288_lcdc_reg_update(dev_drv);
1359 #if defined(CONFIG_ROCKCHIP_IOMMU)
1360                 if (dev_drv->iommu_enabled) {
1361                         if (dev_drv->mmu_dev)
1362                                 rockchip_iovmm_deactivate(dev_drv->dev);
1363                 }
1364 #endif
1365                 rk3288_lcdc_clk_disable(lcdc_dev);
1366                 rockchip_clear_system_status(sys_status);
1367         }
1368
1369         return 0;
1370 }
1371
1372 static int win0_display(struct lcdc_device *lcdc_dev,
1373                         struct rk_lcdc_win *win)
1374 {
1375         u32 y_addr;
1376         u32 uv_addr;
1377         y_addr = win->area[0].smem_start+win->area[0].y_offset;/*win->smem_start + win->y_offset;*/
1378         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
1379         DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x>>offset:%d\n",
1380             lcdc_dev->id, __func__, y_addr, uv_addr,win->area[0].y_offset);
1381         spin_lock(&lcdc_dev->reg_lock);
1382         if (likely(lcdc_dev->clk_on)) {
1383                 win->area[0].y_addr = y_addr;
1384                 win->area[0].uv_addr = uv_addr; 
1385                 lcdc_writel(lcdc_dev, WIN0_YRGB_MST, win->area[0].y_addr); 
1386                 lcdc_writel(lcdc_dev, WIN0_CBR_MST, win->area[0].uv_addr);
1387                 /*lcdc_cfg_done(lcdc_dev);*/
1388         }
1389         spin_unlock(&lcdc_dev->reg_lock);
1390
1391         return 0;
1392
1393 }
1394
1395 static int win1_display(struct lcdc_device *lcdc_dev,
1396                         struct rk_lcdc_win *win)
1397 {
1398         u32 y_addr;
1399         u32 uv_addr;
1400         y_addr = win->area[0].smem_start + win->area[0].y_offset;
1401         uv_addr = win->area[0].cbr_start + win->area[0].c_offset;
1402         DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
1403             lcdc_dev->id, __func__, y_addr, uv_addr);
1404
1405         spin_lock(&lcdc_dev->reg_lock);
1406         if (likely(lcdc_dev->clk_on)) {
1407                 win->area[0].y_addr = y_addr;
1408                 win->area[0].uv_addr = uv_addr; 
1409                 lcdc_writel(lcdc_dev, WIN1_YRGB_MST, win->area[0].y_addr); 
1410                 lcdc_writel(lcdc_dev, WIN1_CBR_MST, win->area[0].uv_addr);
1411         }
1412         spin_unlock(&lcdc_dev->reg_lock);
1413
1414
1415         return 0;
1416 }
1417
1418 static int win2_display(struct lcdc_device *lcdc_dev,
1419                         struct rk_lcdc_win *win)
1420 {
1421         u32 i,y_addr;
1422         y_addr = win->area[0].smem_start + win->area[0].y_offset;
1423         DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>\n",
1424             lcdc_dev->id, __func__, y_addr);
1425
1426         spin_lock(&lcdc_dev->reg_lock);
1427         if (likely(lcdc_dev->clk_on)){
1428                 for(i=0;i<win->area_num;i++)
1429                         win->area[i].y_addr = 
1430                                 win->area[i].smem_start + win->area[i].y_offset;
1431                         lcdc_writel(lcdc_dev,WIN2_MST0,win->area[0].y_addr);
1432                         lcdc_writel(lcdc_dev,WIN2_MST1,win->area[1].y_addr);
1433                         lcdc_writel(lcdc_dev,WIN2_MST2,win->area[2].y_addr);
1434                         lcdc_writel(lcdc_dev,WIN2_MST3,win->area[3].y_addr);
1435         }
1436         spin_unlock(&lcdc_dev->reg_lock);
1437         return 0;
1438 }
1439
1440 static int win3_display(struct lcdc_device *lcdc_dev,
1441                         struct rk_lcdc_win *win)
1442 {
1443         u32 i,y_addr;
1444         y_addr = win->area[0].smem_start + win->area[0].y_offset;
1445         DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>\n",
1446             lcdc_dev->id, __func__, y_addr);
1447
1448         spin_lock(&lcdc_dev->reg_lock);
1449         if (likely(lcdc_dev->clk_on)){
1450                 for(i=0;i<win->area_num;i++)
1451                         win->area[i].y_addr = 
1452                                 win->area[i].smem_start + win->area[i].y_offset;
1453                         lcdc_writel(lcdc_dev,WIN3_MST0,win->area[0].y_addr);
1454                         lcdc_writel(lcdc_dev,WIN3_MST1,win->area[1].y_addr);
1455                         lcdc_writel(lcdc_dev,WIN3_MST2,win->area[2].y_addr);
1456                         lcdc_writel(lcdc_dev,WIN3_MST3,win->area[3].y_addr);            
1457                 }
1458         spin_unlock(&lcdc_dev->reg_lock);
1459         return 0;
1460 }
1461
1462 static int rk3288_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
1463 {
1464         struct lcdc_device *lcdc_dev = container_of(dev_drv,
1465                                 struct lcdc_device, driver);
1466         struct rk_lcdc_win *win = NULL;
1467         struct rk_screen *screen = dev_drv->cur_screen;
1468         
1469 #if defined(WAIT_FOR_SYNC)
1470         int timeout;
1471         unsigned long flags;
1472 #endif
1473         win = dev_drv->win[win_id];
1474         if (!screen) {
1475                 dev_err(dev_drv->dev, "screen is null!\n");
1476                 return -ENOENT;
1477         }
1478         if(win_id == 0){
1479                 win0_display(lcdc_dev, win);
1480         }else if(win_id == 1){
1481                 win1_display(lcdc_dev, win);
1482         }else if(win_id == 2){
1483                 win2_display(lcdc_dev, win);
1484         }else if(win_id == 3){
1485                 win3_display(lcdc_dev, win);
1486         }else{
1487                 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
1488                 return -EINVAL;
1489         }
1490  
1491         /*this is the first frame of the system ,enable frame start interrupt */
1492         if ((dev_drv->first_frame)) {
1493                 dev_drv->first_frame = 0;
1494                 rk3288_lcdc_enable_irq(dev_drv);
1495         }
1496 #if defined(WAIT_FOR_SYNC)
1497         spin_lock_irqsave(&dev_drv->cpl_lock, flags);
1498         init_completion(&dev_drv->frame_done);
1499         spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
1500         timeout = wait_for_completion_timeout(&dev_drv->frame_done,
1501                                               msecs_to_jiffies(dev_drv->
1502                                                                cur_screen->ft +
1503                                                                5));
1504         if (!timeout && (!dev_drv->frame_done.done)) {
1505                 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
1506                 return -ETIMEDOUT;
1507         }
1508 #endif 
1509         return 0;
1510 }
1511
1512 static int rk3288_lcdc_cal_scl_fac(struct rk_lcdc_win *win)
1513 {
1514         u16 srcW;
1515         u16 srcH;
1516         u16 dstW;
1517         u16 dstH;
1518         u16 yrgb_srcW;
1519         u16 yrgb_srcH;
1520         u16 yrgb_dstW;
1521         u16 yrgb_dstH;
1522         u32 yrgb_vScaleDnMult;
1523         u32 yrgb_xscl_factor;
1524         u32 yrgb_yscl_factor;
1525         u8  yrgb_vsd_bil_gt2=0;
1526         u8  yrgb_vsd_bil_gt4=0;
1527         
1528         u16 cbcr_srcW;
1529         u16 cbcr_srcH;
1530         u16 cbcr_dstW;
1531         u16 cbcr_dstH;    
1532         u32 cbcr_vScaleDnMult;
1533         u32 cbcr_xscl_factor;
1534         u32 cbcr_yscl_factor;
1535         u8  cbcr_vsd_bil_gt2=0;
1536         u8  cbcr_vsd_bil_gt4=0;
1537         u8  yuv_fmt=0;
1538
1539
1540         srcW = win->area[0].xact;
1541         srcH = win->area[0].yact;
1542         dstW = win->area[0].xsize;
1543         dstH = win->area[0].ysize;
1544
1545         /*yrgb scl mode*/
1546         yrgb_srcW = srcW;
1547         yrgb_srcH = srcH;
1548         yrgb_dstW = dstW;
1549         yrgb_dstH = dstH;
1550         if ((yrgb_dstW >= yrgb_srcW*8) || (yrgb_dstH >= yrgb_srcH*8) ||
1551                 (yrgb_dstW*8 <= yrgb_srcW) || (yrgb_dstH*8 <= yrgb_srcH)) {
1552                 pr_err("ERROR: yrgb scale exceed 8,"
1553                        "srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
1554                        yrgb_srcW,yrgb_srcH,yrgb_dstW,yrgb_dstH);
1555         }
1556         if(yrgb_srcW < yrgb_dstW){
1557                 win->yrgb_hor_scl_mode = SCALE_UP;
1558         }else if(yrgb_srcW > yrgb_dstW){
1559                 win->yrgb_hor_scl_mode = SCALE_DOWN;
1560         }else{
1561                 win->yrgb_hor_scl_mode = SCALE_NONE;
1562         }
1563
1564         if(yrgb_srcH < yrgb_dstH){
1565                 win->yrgb_ver_scl_mode = SCALE_UP;
1566         }else if (yrgb_srcH  > yrgb_dstH){
1567                 win->yrgb_ver_scl_mode = SCALE_DOWN;
1568         }else{
1569                 win->yrgb_ver_scl_mode = SCALE_NONE;
1570         }
1571
1572         /*cbcr scl mode*/
1573         switch (win->format) {
1574         case YUV422:
1575         case YUV422_A:  
1576                 cbcr_srcW = srcW/2;
1577                 cbcr_dstW = dstW;
1578                 cbcr_srcH = srcH;
1579                 cbcr_dstH = dstH;
1580                 yuv_fmt = 1;
1581                 break;
1582         case YUV420:
1583         case YUV420_A:  
1584                 cbcr_srcW = srcW/2;
1585                 cbcr_dstW = dstW;
1586                 cbcr_srcH = srcH/2;
1587                 cbcr_dstH = dstH;
1588                 yuv_fmt = 1;
1589                 break;
1590         case YUV444:
1591         case YUV444_A:  
1592                 cbcr_srcW = srcW;
1593                 cbcr_dstW = dstW;
1594                 cbcr_srcH = srcH;
1595                 cbcr_dstH = dstH;
1596                 yuv_fmt = 1;
1597                 break;
1598         default:
1599                 cbcr_srcW = 0;
1600                 cbcr_dstW = 0;
1601                 cbcr_srcH = 0;
1602                 cbcr_dstH = 0;
1603                 yuv_fmt = 0;
1604                 break;
1605         }               
1606         if (yuv_fmt) {
1607                 if ((cbcr_dstW >= cbcr_srcW*8) || (cbcr_dstH >= cbcr_srcH*8) ||
1608                         (cbcr_dstW*8 <= cbcr_srcW)||(cbcr_dstH*8 <= cbcr_srcH)) {
1609                         pr_err("ERROR: cbcr scale exceed 8,"
1610                        "srcW=%d,srcH=%d,dstW=%d,dstH=%d\n",
1611                        cbcr_srcW,cbcr_srcH,cbcr_dstW,cbcr_dstH);
1612                 }
1613         }
1614         
1615         if(cbcr_srcW < cbcr_dstW){
1616                 win->cbr_hor_scl_mode = SCALE_UP;
1617         }else if(cbcr_srcW > cbcr_dstW){
1618                 win->cbr_hor_scl_mode = SCALE_DOWN;
1619         }else{
1620                 win->cbr_hor_scl_mode = SCALE_NONE;
1621         }
1622         
1623         if(cbcr_srcH < cbcr_dstH){
1624                 win->cbr_ver_scl_mode = SCALE_UP;
1625         }else if(cbcr_srcH > cbcr_dstH){
1626                 win->cbr_ver_scl_mode = SCALE_DOWN;
1627         }else{
1628                 win->cbr_ver_scl_mode = SCALE_NONE;
1629         }
1630         DBG(1, "srcW:%d>>srcH:%d>>dstW:%d>>dstH:%d>>\n"
1631                "yrgb:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
1632                "cbcr:src:W=%d>>H=%d,dst:W=%d>>H=%d,H_mode=%d,V_mode=%d\n"
1633                 ,srcW,srcH,dstW,dstH,yrgb_srcW,yrgb_srcH,yrgb_dstW,
1634                 yrgb_dstH,win->yrgb_hor_scl_mode,win->yrgb_ver_scl_mode,
1635                 cbcr_srcW,cbcr_srcH,cbcr_dstW,cbcr_dstH,
1636                 win->cbr_hor_scl_mode,win->cbr_ver_scl_mode);
1637
1638     /*line buffer mode*/
1639         if((win->format == YUV422) || (win->format == YUV420) || (win->format == YUV422_A) || (win->format == YUV420_A)){
1640                 if(win->cbr_hor_scl_mode == SCALE_DOWN){
1641                         if ((cbcr_dstW > 3840) || (cbcr_dstW == 0)) {
1642                                 pr_err("ERROR cbcr_dstW = %d\n",cbcr_dstW);                
1643                         }else if(cbcr_dstW > 2560){
1644                                 win->win_lb_mode = LB_RGB_3840X2;
1645                         }else if(cbcr_dstW > 1920){
1646                                 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1647                                         if(yrgb_dstW > 3840){
1648                                                 pr_err("ERROR yrgb_dst_width exceeds 3840\n");
1649                                         }else if(yrgb_dstW > 2560){
1650                                                 win->win_lb_mode = LB_RGB_3840X2;
1651                                         }else if(yrgb_dstW > 1920){
1652                                                 win->win_lb_mode = LB_RGB_2560X4;
1653                                         }else{
1654                                                 pr_err("ERROR never run here!yrgb_dstW<1920 ==> cbcr_dstW>1920\n");
1655                                         }
1656                                 }
1657                         }else if(cbcr_dstW > 1280){
1658                                 win->win_lb_mode = LB_YUV_3840X5;
1659                         }else{
1660                                 win->win_lb_mode = LB_YUV_2560X8;
1661                         }            
1662                 } else { /*SCALE_UP or SCALE_NONE*/
1663                         if ((cbcr_srcW > 3840) || (cbcr_srcW == 0)) {
1664                                 pr_err("ERROR cbcr_srcW = %d\n",cbcr_srcW);
1665                         }else if(cbcr_srcW > 2560){                
1666                                 win->win_lb_mode = LB_RGB_3840X2;
1667                         }else if(cbcr_srcW > 1920){
1668                                 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1669                                         if(yrgb_dstW > 3840){
1670                                                 pr_err("ERROR yrgb_dst_width exceeds 3840\n");
1671                                         }else if(yrgb_dstW > 2560){
1672                                                 win->win_lb_mode = LB_RGB_3840X2;
1673                                         }else if(yrgb_dstW > 1920){
1674                                                 win->win_lb_mode = LB_RGB_2560X4;
1675                                         }else{
1676                                                 pr_err("ERROR never run here!yrgb_dstW<1920 ==> cbcr_dstW>1920\n");
1677                                         }
1678                                 }  
1679                         }else if(cbcr_srcW > 1280){
1680                                  win->win_lb_mode = LB_YUV_3840X5;
1681                         }else{
1682                                 win->win_lb_mode = LB_YUV_2560X8;
1683                         }            
1684                 }
1685         }else {
1686                 if(win->yrgb_hor_scl_mode == SCALE_DOWN){
1687                         if ((yrgb_dstW > 3840) || (yrgb_dstW == 0)) {
1688                                 pr_err("ERROR yrgb_dstW = %d\n",yrgb_dstW);
1689                         }else if(yrgb_dstW > 2560){
1690                                 win->win_lb_mode = LB_RGB_3840X2;
1691                         }else if(yrgb_dstW > 1920){
1692                                 win->win_lb_mode = LB_RGB_2560X4;
1693                         }else if(yrgb_dstW > 1280){
1694                                 win->win_lb_mode = LB_RGB_1920X5;
1695                         }else{
1696                                 win->win_lb_mode = LB_RGB_1280X8;
1697                         }            
1698                 }else{ /*SCALE_UP or SCALE_NONE*/
1699                         if ((yrgb_srcW > 3840) || (yrgb_srcW == 0)) {
1700                                 pr_err("ERROR yrgb_srcW = %d\n",yrgb_srcW);
1701                         }else if(yrgb_srcW > 2560){
1702                                 win->win_lb_mode = LB_RGB_3840X2;
1703                         }else if(yrgb_srcW > 1920){
1704                                 win->win_lb_mode = LB_RGB_2560X4;
1705                         }else if(yrgb_srcW > 1280){
1706                                 win->win_lb_mode = LB_RGB_1920X5;
1707                         }else{
1708                                 win->win_lb_mode = LB_RGB_1280X8;
1709                         }            
1710                 }
1711         }
1712         DBG(1,"win->win_lb_mode = %d;\n",win->win_lb_mode);
1713
1714         /*vsd/vsu scale ALGORITHM*/
1715         win->yrgb_hsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1716         win->cbr_hsd_mode  = SCALE_DOWN_BIL;/*not to specify*/
1717         win->yrgb_vsd_mode = SCALE_DOWN_BIL;/*not to specify*/
1718         win->cbr_vsd_mode  = SCALE_DOWN_BIL;/*not to specify*/
1719         switch(win->win_lb_mode){
1720             case LB_YUV_3840X5:
1721             case LB_YUV_2560X8:
1722             case LB_RGB_1920X5:
1723             case LB_RGB_1280X8:         
1724                 win->yrgb_vsu_mode = SCALE_UP_BIC; 
1725                 win->cbr_vsu_mode  = SCALE_UP_BIC; 
1726                 break;
1727             case LB_RGB_3840X2:
1728                 if(win->yrgb_ver_scl_mode != SCALE_NONE) {
1729                     pr_err("ERROR : not allow yrgb ver scale\n");
1730                 }
1731                 if(win->cbr_ver_scl_mode != SCALE_NONE) {
1732                     pr_err("ERROR : not allow cbcr ver scale\n");
1733                 }                 
1734                 break;
1735             case LB_RGB_2560X4:
1736                 win->yrgb_vsu_mode = SCALE_UP_BIL; 
1737                 win->cbr_vsu_mode  = SCALE_UP_BIL;          
1738                 break;
1739             default:
1740                 printk(KERN_WARNING "%s:un supported win_lb_mode:%d\n",
1741                         __func__,win->win_lb_mode);     
1742                 break;
1743         }
1744         DBG(1,"yrgb:hsd=%d,vsd=%d,vsu=%d;cbcr:hsd=%d,vsd=%d,vsu=%d\n",
1745                win->yrgb_hsd_mode,win->yrgb_vsd_mode,win->yrgb_vsu_mode,
1746                win->cbr_hsd_mode,win->cbr_vsd_mode,win->cbr_vsu_mode);
1747
1748         /*SCALE FACTOR*/
1749     
1750         /*(1.1)YRGB HOR SCALE FACTOR*/
1751         switch(win->yrgb_hor_scl_mode){
1752         case SCALE_NONE:
1753                 yrgb_xscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1754                 break;
1755         case SCALE_UP  :
1756                 yrgb_xscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcW, yrgb_dstW);
1757                 break;
1758         case SCALE_DOWN:
1759                 switch(win->yrgb_hsd_mode)
1760                 {
1761                 case SCALE_DOWN_BIL:
1762                         yrgb_xscl_factor = GET_SCALE_FACTOR_BILI_DN(yrgb_srcW, yrgb_dstW);
1763                         break;
1764                 case SCALE_DOWN_AVG:
1765                         yrgb_xscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcW, yrgb_dstW);
1766                         break;
1767                 default :
1768                         printk(KERN_WARNING "%s:un supported yrgb_hsd_mode:%d\n",
1769                                 __func__,win->yrgb_hsd_mode);           
1770                         break;
1771                 } 
1772                 break;
1773         default :
1774                 printk(KERN_WARNING "%s:un supported yrgb_hor_scl_mode:%d\n",
1775                                 __func__,win->yrgb_hor_scl_mode);       
1776             break;
1777         } /*win->yrgb_hor_scl_mode*/
1778
1779         /*(1.2)YRGB VER SCALE FACTOR*/
1780         switch(win->yrgb_ver_scl_mode)
1781         {
1782         case SCALE_NONE:
1783                 yrgb_yscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1784                  break;
1785         case SCALE_UP  :
1786                 switch(win->yrgb_vsu_mode)
1787                 {
1788                 case SCALE_UP_BIL:
1789                         yrgb_yscl_factor = GET_SCALE_FACTOR_BILI_UP(yrgb_srcH, yrgb_dstH);
1790                         break;
1791                 case SCALE_UP_BIC:
1792                         if(yrgb_srcH < 3){
1793                                 pr_err("yrgb_srcH should be greater than 3 !!!\n");
1794                         }                    
1795                         yrgb_yscl_factor = GET_SCALE_FACTOR_BIC(yrgb_srcH, yrgb_dstH);
1796                         break;
1797                 default :
1798                         printk(KERN_WARNING "%s:un supported yrgb_vsu_mode:%d\n",
1799                                 __func__,win->yrgb_vsu_mode);                   
1800                         break;
1801             }
1802             break;
1803         case SCALE_DOWN:
1804                 switch(win->yrgb_vsd_mode)
1805                 {
1806                 case SCALE_DOWN_BIL:
1807                         yrgb_vScaleDnMult = getHardWareVSkipLines(yrgb_srcH, yrgb_dstH);
1808                         yrgb_yscl_factor  = GET_SCALE_FACTOR_BILI_DN_VSKIP(yrgb_srcH, yrgb_dstH, yrgb_vScaleDnMult);                                 
1809                         if(yrgb_vScaleDnMult == 4){
1810                                 yrgb_vsd_bil_gt4 = 1;
1811                                 yrgb_vsd_bil_gt2 = 0;
1812                         }else if(yrgb_vScaleDnMult == 2){
1813                                 yrgb_vsd_bil_gt4 = 0;
1814                                 yrgb_vsd_bil_gt2 = 1;
1815                         }else{
1816                                 yrgb_vsd_bil_gt4 = 0;
1817                                 yrgb_vsd_bil_gt2 = 0;
1818                         }
1819                         break;
1820                 case SCALE_DOWN_AVG:
1821                         yrgb_yscl_factor = GET_SCALE_FACTOR_AVRG(yrgb_srcH, yrgb_dstH);
1822                         break;
1823                 default:
1824                         printk(KERN_WARNING "%s:un supported yrgb_vsd_mode:%d\n",
1825                                 __func__,win->yrgb_vsd_mode);           
1826                         break;
1827                 } /*win->yrgb_vsd_mode*/
1828                 break;
1829         default :
1830                 printk(KERN_WARNING "%s:un supported yrgb_ver_scl_mode:%d\n",
1831                         __func__,win->yrgb_ver_scl_mode);               
1832                 break;
1833         }
1834         win->scale_yrgb_x = yrgb_xscl_factor;
1835         win->scale_yrgb_y = yrgb_yscl_factor;
1836         win->vsd_yrgb_gt4 = yrgb_vsd_bil_gt4;
1837         win->vsd_yrgb_gt2 = yrgb_vsd_bil_gt2;
1838         DBG(1,"yrgb:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n",yrgb_xscl_factor,
1839                 yrgb_yscl_factor,yrgb_vsd_bil_gt4,yrgb_vsd_bil_gt2);
1840
1841         /*(2.1)CBCR HOR SCALE FACTOR*/
1842         switch(win->cbr_hor_scl_mode)
1843         {
1844         case SCALE_NONE:
1845                 cbcr_xscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1846                 break;
1847         case SCALE_UP  :
1848                 cbcr_xscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcW, cbcr_dstW);
1849                 break;
1850         case SCALE_DOWN:
1851                 switch(win->cbr_hsd_mode)
1852                 {
1853                 case SCALE_DOWN_BIL:
1854                         cbcr_xscl_factor = GET_SCALE_FACTOR_BILI_DN(cbcr_srcW, cbcr_dstW);
1855                         break;
1856                 case SCALE_DOWN_AVG:
1857                         cbcr_xscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcW, cbcr_dstW);
1858                         break;
1859                 default :
1860                         printk(KERN_WARNING "%s:un supported cbr_hsd_mode:%d\n",
1861                                 __func__,win->cbr_hsd_mode);    
1862                         break;
1863                 }
1864                 break;
1865         default :
1866                 printk(KERN_WARNING "%s:un supported cbr_hor_scl_mode:%d\n",
1867                         __func__,win->cbr_hor_scl_mode);        
1868                 break;
1869         } /*win->cbr_hor_scl_mode*/
1870
1871         /*(2.2)CBCR VER SCALE FACTOR*/
1872         switch(win->cbr_ver_scl_mode)
1873         {
1874         case SCALE_NONE:
1875                 cbcr_yscl_factor = (1<<SCALE_FACTOR_DEFAULT_FIXPOINT_SHIFT);
1876                 break;
1877         case SCALE_UP  :
1878                 switch(win->cbr_vsu_mode)
1879                 {
1880                 case SCALE_UP_BIL:
1881                         cbcr_yscl_factor = GET_SCALE_FACTOR_BILI_UP(cbcr_srcH, cbcr_dstH);
1882                         break;
1883                 case SCALE_UP_BIC:
1884                         if(cbcr_srcH < 3) {
1885                                 pr_err("cbcr_srcH should be greater than 3 !!!\n");
1886                         }                    
1887                         cbcr_yscl_factor = GET_SCALE_FACTOR_BIC(cbcr_srcH, cbcr_dstH);
1888                         break;
1889                 default :
1890                         printk(KERN_WARNING "%s:un supported cbr_vsu_mode:%d\n",
1891                                 __func__,win->cbr_vsu_mode);            
1892                         break;
1893                 }
1894                 break;
1895         case SCALE_DOWN:
1896                 switch(win->cbr_vsd_mode)
1897                 {
1898                 case SCALE_DOWN_BIL:
1899                         cbcr_vScaleDnMult = getHardWareVSkipLines(cbcr_srcH, cbcr_dstH);
1900                         cbcr_yscl_factor  = GET_SCALE_FACTOR_BILI_DN_VSKIP(cbcr_srcH, cbcr_dstH, cbcr_vScaleDnMult);                    
1901                         if(cbcr_vScaleDnMult == 4){
1902                                 cbcr_vsd_bil_gt4 = 1;
1903                                 cbcr_vsd_bil_gt2 = 0;
1904                         }else if(cbcr_vScaleDnMult == 2){
1905                                 cbcr_vsd_bil_gt4 = 0;
1906                                 cbcr_vsd_bil_gt2 = 1;
1907                         }else{
1908                                 cbcr_vsd_bil_gt4 = 0;
1909                                 cbcr_vsd_bil_gt2 = 0;
1910                         }
1911                         break;
1912                 case SCALE_DOWN_AVG:
1913                         cbcr_yscl_factor = GET_SCALE_FACTOR_AVRG(cbcr_srcH, cbcr_dstH);
1914                         break;
1915                 default :
1916                         printk(KERN_WARNING "%s:un supported cbr_vsd_mode:%d\n",
1917                                 __func__,win->cbr_vsd_mode);            
1918                     break;
1919                 }
1920                 break;
1921         default :
1922                 printk(KERN_WARNING "%s:un supported cbr_ver_scl_mode:%d\n",
1923                         __func__,win->cbr_ver_scl_mode);                        
1924                 break;
1925         }
1926         win->scale_cbcr_x = cbcr_xscl_factor;
1927         win->scale_cbcr_y = cbcr_yscl_factor;
1928         win->vsd_cbr_gt4  = cbcr_vsd_bil_gt4;
1929         win->vsd_cbr_gt2  = cbcr_vsd_bil_gt2;   
1930
1931         DBG(1,"cbcr:h_fac=%d,v_fac=%d,gt4=%d,gt2=%d\n",cbcr_xscl_factor,
1932                 cbcr_yscl_factor,cbcr_vsd_bil_gt4,cbcr_vsd_bil_gt2);
1933         return 0;
1934 }
1935
1936
1937
1938 static int win0_set_par(struct lcdc_device *lcdc_dev,
1939                         struct rk_screen *screen, struct rk_lcdc_win *win)
1940 {
1941         u32 xact,yact,xvir, yvir,xpos, ypos;
1942         u8 fmt_cfg = 0;
1943         char fmt[9] = "NULL";
1944
1945         xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
1946         ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
1947
1948         spin_lock(&lcdc_dev->reg_lock);
1949         if(likely(lcdc_dev->clk_on)){
1950                 rk3288_lcdc_cal_scl_fac(win);/*fac,lb,gt2,gt4*/
1951                 switch (win->format){
1952                 case ARGB888:
1953                         fmt_cfg = 0;
1954                         win->swap_rb = 0;
1955                         win->fmt_10 = 0;
1956                         break;
1957                 case XBGR888:
1958                 case ABGR888:
1959                         fmt_cfg = 0;
1960                         win->swap_rb = 1;
1961                         win->fmt_10 = 0;
1962                         break;
1963                 case RGB888:
1964                         fmt_cfg = 1;
1965                         win->swap_rb = 0;
1966                         win->fmt_10 = 0;
1967                         break;
1968                 case RGB565:
1969                         fmt_cfg = 2;
1970                         win->swap_rb = 0;
1971                         win->fmt_10 = 0;
1972                         break;
1973                 case YUV422:
1974                         fmt_cfg = 5;
1975                         win->swap_rb = 0;
1976                         win->fmt_10 = 0;
1977                         break;
1978                 case YUV420:    
1979                         fmt_cfg = 4;
1980                         win->swap_rb = 0;
1981                         win->fmt_10 = 0;
1982                         break;
1983                 case YUV444:    
1984                         fmt_cfg = 6;
1985                         win->swap_rb = 0;
1986                         win->fmt_10 = 0;
1987                 case YUV422_A:
1988                         fmt_cfg = 5;
1989                         win->swap_rb = 0;
1990                         win->fmt_10 = 1;
1991                         break;
1992                 case YUV420_A:  
1993                         fmt_cfg = 4;
1994                         win->swap_rb = 0;
1995                         win->fmt_10 = 1;
1996                         break;
1997                 case YUV444_A:  
1998                         fmt_cfg = 6;
1999                         win->swap_rb = 0;
2000                         win->fmt_10 = 1;
2001                         break;
2002                 default:
2003                         dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
2004                                 __func__);
2005                         break;
2006                 }
2007                 win->fmt_cfg = fmt_cfg;
2008                 win->area[0].dsp_stx = xpos;
2009                 win->area[0].dsp_sty = ypos;
2010                 xact = win->area[0].xact;
2011                 yact = win->area[0].yact;
2012                 xvir = win->area[0].xvir;
2013                 yvir = win->area[0].yvir;
2014         }
2015         rk3288_win_0_1_reg_update(&lcdc_dev->driver,0);
2016         spin_unlock(&lcdc_dev->reg_lock);
2017
2018         DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
2019                 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
2020                 __func__, get_format_string(win->format, fmt), xact,
2021                 yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
2022         return 0;
2023
2024 }
2025
2026 static int win1_set_par(struct lcdc_device *lcdc_dev,
2027                         struct rk_screen *screen, struct rk_lcdc_win *win)
2028 {
2029         u32 xact,yact,xvir, yvir,xpos, ypos;
2030         u8 fmt_cfg = 0;
2031         char fmt[9] = "NULL";
2032
2033         xpos = win->area[0].xpos + screen->mode.left_margin + screen->mode.hsync_len;
2034         ypos = win->area[0].ypos + screen->mode.upper_margin + screen->mode.vsync_len;
2035
2036         spin_lock(&lcdc_dev->reg_lock);
2037         if(likely(lcdc_dev->clk_on)){
2038                 rk3288_lcdc_cal_scl_fac(win);/*fac,lb,gt2,gt4*/
2039                 switch (win->format){
2040                 case ARGB888:
2041                         fmt_cfg = 0;
2042                         win->swap_rb = 0;
2043                         win->fmt_10 = 0;
2044                         break;
2045                 case XBGR888:
2046                 case ABGR888:
2047                         fmt_cfg = 0;
2048                         win->swap_rb = 1;
2049                         win->fmt_10 = 0;
2050                         break;
2051                 case RGB888:
2052                         fmt_cfg = 1;
2053                         win->swap_rb = 0;
2054                         win->fmt_10 = 0;
2055                         break;
2056                 case RGB565:
2057                         fmt_cfg = 2;
2058                         win->swap_rb = 0;
2059                         win->fmt_10 = 0;
2060                         break;
2061                 case YUV422:
2062                         fmt_cfg = 5;
2063                         win->swap_rb = 0;
2064                         win->fmt_10 = 0;
2065                         break;
2066                 case YUV420:
2067                         fmt_cfg = 4;
2068                         win->swap_rb = 0;
2069                         win->fmt_10 = 0;
2070                         break;
2071                 case YUV444:
2072                         fmt_cfg = 6;
2073                         win->swap_rb = 0;
2074                         win->fmt_10 = 0;
2075                         break;
2076                 case YUV422_A:
2077                         fmt_cfg = 5;
2078                         win->swap_rb = 0;
2079                         win->fmt_10 = 1;
2080                         break;
2081                 case YUV420_A:  
2082                         fmt_cfg = 4;
2083                         win->swap_rb = 0;
2084                         win->fmt_10 = 1;
2085                         break;
2086                 case YUV444_A:  
2087                         fmt_cfg = 6;
2088                         win->swap_rb = 0;
2089                         win->fmt_10 = 1;
2090                         break;                  
2091                 default:
2092                         dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
2093                                 __func__);
2094                         break;
2095                 }
2096                 win->fmt_cfg = fmt_cfg;
2097                 win->area[0].dsp_stx = xpos;
2098                 win->area[0].dsp_sty = ypos;
2099                 xact = win->area[0].xact;
2100                 yact = win->area[0].yact;
2101                 xvir = win->area[0].xvir;
2102                 yvir = win->area[0].yvir;
2103         }
2104         rk3288_win_0_1_reg_update(&lcdc_dev->driver,1);
2105         spin_unlock(&lcdc_dev->reg_lock);
2106
2107         DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
2108                 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
2109                 __func__, get_format_string(win->format, fmt), xact,
2110                 yact, win->area[0].xsize, win->area[0].ysize, xvir, yvir, xpos, ypos);
2111         return 0;
2112
2113 }
2114
2115 static int win2_set_par(struct lcdc_device *lcdc_dev,
2116                         struct rk_screen *screen, struct rk_lcdc_win *win)
2117 {
2118         int i;
2119         u8 fmt_cfg;
2120
2121         spin_lock(&lcdc_dev->reg_lock);
2122         if(likely(lcdc_dev->clk_on)){
2123                 for(i=0;i<win->area_num;i++){
2124                         switch (win->format){
2125                         case ARGB888:
2126                                 fmt_cfg = 0;
2127                                 win->swap_rb = 0;
2128                                 break;
2129                         case XBGR888:
2130                         case ABGR888:
2131                                 fmt_cfg = 0;
2132                                 win->swap_rb = 1;
2133                                 break;
2134                         case RGB888:
2135                                 fmt_cfg = 1;
2136                                 win->swap_rb = 0;
2137                                 break;
2138                         case RGB565:
2139                                 fmt_cfg = 2;
2140                                 win->swap_rb = 0;               
2141                                 break;
2142                         default:
2143                                 dev_err(lcdc_dev->driver.dev, 
2144                                         "%s:un supported format!\n",
2145                                         __func__);
2146                                 break;
2147                         }                       
2148                         win->fmt_cfg = fmt_cfg;
2149                         win->area[i].dsp_stx = win->area[i].xpos + 
2150                                 screen->mode.left_margin +
2151                                 screen->mode.hsync_len;
2152                         if (screen->y_mirror == 1) {
2153                                 win->area[i].dsp_sty = screen->mode.yres -
2154                                         win->area[i].ypos -
2155                                         win->area[i].ysize + 
2156                                         screen->mode.upper_margin +
2157                                         screen->mode.vsync_len;
2158                         } else {
2159                                 win->area[i].dsp_sty = win->area[i].ypos + 
2160                                         screen->mode.upper_margin +
2161                                         screen->mode.vsync_len;
2162                         }
2163                 }
2164         }
2165         rk3288_win_2_3_reg_update(&lcdc_dev->driver,2);
2166         spin_unlock(&lcdc_dev->reg_lock);       
2167         return 0;
2168 }
2169
2170 static int win3_set_par(struct lcdc_device *lcdc_dev,
2171                         struct rk_screen *screen, struct rk_lcdc_win *win)
2172
2173 {
2174         int i;
2175         u8 fmt_cfg;
2176
2177         spin_lock(&lcdc_dev->reg_lock);
2178         if(likely(lcdc_dev->clk_on)){
2179                 for(i=0;i<win->area_num;i++){
2180                         switch (win->format){
2181                         case ARGB888:
2182                                 fmt_cfg = 0;
2183                                 win->swap_rb = 0;
2184                                 break;
2185                         case XBGR888:
2186                         case ABGR888:
2187                                 fmt_cfg = 0;
2188                                 win->swap_rb = 1;
2189                                 break;
2190                         case RGB888:
2191                                 fmt_cfg = 1;
2192                                 win->swap_rb = 0;
2193                                 break;
2194                         case RGB565:
2195                                 fmt_cfg = 2;
2196                                 win->swap_rb = 0;               
2197                                 break;
2198                         default:
2199                                 dev_err(lcdc_dev->driver.dev, 
2200                                         "%s:un supported format!\n",
2201                                         __func__);
2202                                 break;
2203                         }                       
2204                         win->fmt_cfg = fmt_cfg;
2205                         win->area[i].dsp_stx = win->area[i].xpos + 
2206                                 screen->mode.left_margin +
2207                                 screen->mode.hsync_len;
2208                         if (screen->y_mirror == 1) {
2209                                 win->area[i].dsp_sty = screen->mode.yres -
2210                                         win->area[i].ypos -
2211                                         win->area[i].ysize + 
2212                                         screen->mode.upper_margin +
2213                                         screen->mode.vsync_len;
2214                         } else {
2215                                 win->area[i].dsp_sty = win->area[i].ypos + 
2216                                         screen->mode.upper_margin +
2217                                         screen->mode.vsync_len;
2218                         }
2219                 }
2220         }
2221         rk3288_win_2_3_reg_update(&lcdc_dev->driver,3);
2222         spin_unlock(&lcdc_dev->reg_lock);       
2223         return 0;
2224 }
2225
2226 static int rk3288_lcdc_set_par(struct rk_lcdc_driver *dev_drv,int win_id)
2227 {
2228         struct lcdc_device *lcdc_dev =
2229             container_of(dev_drv, struct lcdc_device, driver);
2230         struct rk_lcdc_win *win = NULL;
2231         struct rk_screen *screen = dev_drv->cur_screen;
2232         win = dev_drv->win[win_id];
2233
2234         switch(win_id)
2235         {
2236         case 0:
2237                 win0_set_par(lcdc_dev, screen, win);
2238                 break;
2239         case 1:
2240                 win1_set_par(lcdc_dev, screen, win);
2241                 break;  
2242         case 2:
2243                 win2_set_par(lcdc_dev, screen, win);
2244                 break;
2245         case 3:
2246                 win3_set_par(lcdc_dev, screen, win);
2247                 break;          
2248         default:
2249                 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
2250                 break;  
2251         }
2252         return 0;
2253 }
2254
2255 static int rk3288_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
2256                              unsigned long arg, int win_id)
2257 {
2258         struct lcdc_device *lcdc_dev = container_of(dev_drv,
2259                                                            struct
2260                                                            lcdc_device,
2261                                                            driver);
2262         u32 panel_size[2];
2263         void __user *argp = (void __user *)arg;
2264         struct color_key_cfg clr_key_cfg;
2265
2266         switch (cmd) {
2267         case RK_FBIOGET_PANEL_SIZE:
2268                 panel_size[0] = lcdc_dev->screen->mode.xres;
2269                 panel_size[1] = lcdc_dev->screen->mode.yres;
2270                 if (copy_to_user(argp, panel_size, 8))
2271                         return -EFAULT;
2272                 break;
2273         case RK_FBIOPUT_COLOR_KEY_CFG:
2274                 if (copy_from_user(&clr_key_cfg, argp,
2275                                    sizeof(struct color_key_cfg)))
2276                         return -EFAULT;
2277                 rk3288_lcdc_clr_key_cfg(dev_drv);
2278                 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
2279                             clr_key_cfg.win0_color_key_cfg);
2280                 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
2281                             clr_key_cfg.win1_color_key_cfg);
2282                 break;
2283
2284         default:
2285                 break;
2286         }
2287         return 0;
2288 }
2289
2290 static int rk3288_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
2291 {
2292         u32 reg;
2293         struct lcdc_device *lcdc_dev =
2294             container_of(dev_drv, struct lcdc_device, driver);
2295         if (dev_drv->suspend_flag)
2296                 return 0;
2297         
2298         dev_drv->suspend_flag = 1;
2299         flush_kthread_worker(&dev_drv->update_regs_worker);
2300         
2301         for (reg = MMU_DTE_ADDR; reg <= MMU_AUTO_GATING; reg +=4)
2302                         lcdc_readl(lcdc_dev, reg);
2303         if (dev_drv->trsm_ops && dev_drv->trsm_ops->disable)
2304                 dev_drv->trsm_ops->disable();
2305         
2306         spin_lock(&lcdc_dev->reg_lock);
2307         if (likely(lcdc_dev->clk_on)) {
2308                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2309                                         v_DSP_BLANK_EN(1));
2310                 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_FS_INTR_CLR | m_LINE_FLAG_INTR_CLR,
2311                                         v_FS_INTR_CLR(1) | v_LINE_FLAG_INTR_CLR(1));    
2312                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
2313                                         v_DSP_OUT_ZERO(1));
2314                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
2315                                         v_STANDBY_EN(1));
2316                 lcdc_cfg_done(lcdc_dev);
2317
2318                 if (dev_drv->iommu_enabled) {
2319                         if (dev_drv->mmu_dev)
2320                                 rockchip_iovmm_deactivate(dev_drv->dev);
2321                 }
2322
2323                 spin_unlock(&lcdc_dev->reg_lock);
2324         } else {
2325                 spin_unlock(&lcdc_dev->reg_lock);
2326                 return 0;
2327         }
2328         rk3288_lcdc_clk_disable(lcdc_dev);
2329         rk_disp_pwr_disable(dev_drv);
2330         return 0;
2331 }
2332
2333 static int rk3288_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
2334 {
2335         struct lcdc_device *lcdc_dev =
2336             container_of(dev_drv, struct lcdc_device, driver);
2337         int i, j;
2338         int __iomem *c;
2339         int v, r, g, b;
2340
2341         if (!dev_drv->suspend_flag)
2342                 return 0;
2343         rk_disp_pwr_enable(dev_drv);
2344         dev_drv->suspend_flag = 0;
2345
2346         if (lcdc_dev->atv_layer_cnt) {
2347                 rk3288_lcdc_clk_enable(lcdc_dev);
2348                 rk3288_lcdc_reg_restore(lcdc_dev);
2349
2350                 spin_lock(&lcdc_dev->reg_lock);
2351                 if (dev_drv->cur_screen->dsp_lut) {
2352                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2353                                      v_DSP_LUT_EN(0));
2354                         lcdc_cfg_done(lcdc_dev);
2355                         mdelay(25);
2356                         for (i = 0; i < 256; i++) {
2357                                 v = dev_drv->cur_screen->dsp_lut[i];
2358                                 c = lcdc_dev->dsp_lut_addr_base + (i << 2);
2359                                 b = (v & 0xff) << 2;
2360                                 g = (v & 0xff00) << 4;
2361                                 r = (v & 0xff0000) << 6;
2362                                 v = r + g + b;
2363                                 for (j = 0; j < 4; j++) {
2364                                         writel_relaxed(v, c);
2365                                         v += (1 + (1 << 10) + (1 << 20)) ;
2366                                         c++;
2367                                 }
2368                         }
2369                         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN,
2370                                      v_DSP_LUT_EN(1));
2371                 }
2372
2373                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_OUT_ZERO,
2374                              v_DSP_OUT_ZERO(0));
2375                 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
2376                              v_STANDBY_EN(0));
2377                 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DSP_BLANK_EN,
2378                                         v_DSP_BLANK_EN(0));     
2379                 lcdc_cfg_done(lcdc_dev);
2380
2381                 if (dev_drv->iommu_enabled) {
2382                         if (dev_drv->mmu_dev)
2383                                 rockchip_iovmm_activate(dev_drv->dev);
2384                 }
2385
2386                 spin_unlock(&lcdc_dev->reg_lock);
2387         }
2388
2389         if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
2390                 dev_drv->trsm_ops->enable();
2391
2392         return 0;
2393 }
2394
2395 static int rk3288_lcdc_blank(struct rk_lcdc_driver *dev_drv,
2396                              int win_id, int blank_mode)
2397 {
2398         switch (blank_mode) {
2399         case FB_BLANK_UNBLANK:
2400                 rk3288_lcdc_early_resume(dev_drv);
2401                 break;
2402         case FB_BLANK_NORMAL:   
2403                 rk3288_lcdc_early_suspend(dev_drv);
2404                 break;
2405         default:
2406                 rk3288_lcdc_early_suspend(dev_drv);
2407                 break;
2408         }
2409
2410         dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
2411
2412         return 0;
2413 }
2414
2415 static int rk3288_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
2416 {
2417         return 0;
2418 }
2419
2420 /*overlay will be do at regupdate*/
2421 static int rk3288_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
2422                                bool set)
2423 {
2424         struct lcdc_device *lcdc_dev =
2425             container_of(dev_drv, struct lcdc_device, driver);
2426         struct rk_lcdc_win *win = NULL;
2427         int i,ovl;
2428         unsigned int mask, val;
2429         int z_order_num=0;
2430         int layer0_sel,layer1_sel,layer2_sel,layer3_sel;
2431         if(swap == 0){
2432                 for(i=0;i<4;i++){
2433                         win = dev_drv->win[i];
2434                         if(win->state == 1){
2435                                 z_order_num++;
2436                         }       
2437                 }
2438                 for(i=0;i<4;i++){
2439                         win = dev_drv->win[i];
2440                         if(win->state == 0)
2441                                 win->z_order = z_order_num++;
2442                         switch(win->z_order){
2443                         case 0:
2444                                 layer0_sel = win->id;
2445                                 break;
2446                         case 1:
2447                                 layer1_sel = win->id;
2448                                 break;
2449                         case 2:
2450                                 layer2_sel = win->id;
2451                                 break;
2452                         case 3:
2453                                 layer3_sel = win->id;
2454                                 break;
2455                         default:
2456                                 break;
2457                         }
2458                 }
2459         }else{
2460                 layer0_sel = swap %10;;
2461                 layer1_sel = swap /10 % 10;
2462                 layer2_sel = swap / 100 %10;
2463                 layer3_sel = swap / 1000;
2464         }
2465
2466         spin_lock(&lcdc_dev->reg_lock);
2467         if(lcdc_dev->clk_on){
2468                 if(set){
2469                         mask = m_DSP_LAYER0_SEL | m_DSP_LAYER1_SEL |
2470                                 m_DSP_LAYER2_SEL | m_DSP_LAYER3_SEL;
2471                         val  = v_DSP_LAYER0_SEL(layer0_sel) |
2472                                 v_DSP_LAYER1_SEL(layer1_sel) |
2473                                 v_DSP_LAYER2_SEL(layer2_sel) |
2474                                 v_DSP_LAYER3_SEL(layer3_sel);
2475                         lcdc_msk_reg(lcdc_dev,DSP_CTRL1,mask,val);
2476                 }else{
2477                         layer0_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER0_SEL);
2478                         layer1_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER1_SEL);
2479                         layer2_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER2_SEL);
2480                         layer3_sel = lcdc_read_bit(lcdc_dev, DSP_CTRL1, m_DSP_LAYER3_SEL);
2481                         ovl = layer3_sel*1000 + layer2_sel*100 + layer1_sel *10 + layer0_sel;
2482                 }
2483         }else{
2484                 ovl = -EPERM;
2485         }
2486         spin_unlock(&lcdc_dev->reg_lock);
2487
2488         return ovl;
2489 }
2490
2491 static ssize_t rk3288_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
2492                                          char *buf, int win_id)
2493 {
2494         struct lcdc_device *lcdc_dev = container_of(dev_drv,
2495                                                            struct
2496                                                            lcdc_device,
2497                                                            driver);
2498         struct rk_screen *screen = dev_drv->cur_screen;
2499         u16 hsync_len = screen->mode.hsync_len;
2500         u16 left_margin = screen->mode.left_margin;
2501         u16 vsync_len = screen->mode.vsync_len;
2502         u16 upper_margin = screen->mode.upper_margin;
2503         u32 h_pw_bp = hsync_len + left_margin;
2504         u32 v_pw_bp = vsync_len + upper_margin;
2505         u32 fmt_id;
2506         char format_w0[9] = "NULL";
2507         char format_w1[9] = "NULL";
2508         char format_w2[9] = "NULL";
2509         char format_w3[9] = "NULL";     
2510         u32 win_ctrl,zorder,vir_info,act_info,dsp_info,dsp_st,y_factor,uv_factor;
2511         u8 layer0_sel,layer1_sel,layer2_sel,layer3_sel;
2512         u8 w0_state,w1_state,w2_state,w3_state;
2513         u8 w2_0_state,w2_1_state,w2_2_state,w2_3_state;
2514         u8 w3_0_state,w3_1_state,w3_2_state,w3_3_state;
2515
2516         u32 w0_vir_y,w0_vir_uv,w0_act_x,w0_act_y,w0_dsp_x,w0_dsp_y,w0_st_x=h_pw_bp,w0_st_y=v_pw_bp;
2517         u32 w1_vir_y,w1_vir_uv,w1_act_x,w1_act_y,w1_dsp_x,w1_dsp_y,w1_st_x=h_pw_bp,w1_st_y=v_pw_bp;
2518         u32 w0_y_h_fac,w0_y_v_fac,w0_uv_h_fac,w0_uv_v_fac;
2519         u32 w1_y_h_fac,w1_y_v_fac,w1_uv_h_fac,w1_uv_v_fac;
2520
2521         u32 w2_0_vir_y,w2_1_vir_y,w2_2_vir_y,w2_3_vir_y;
2522         u32 w2_0_dsp_x,w2_1_dsp_x,w2_2_dsp_x,w2_3_dsp_x;
2523         u32 w2_0_dsp_y,w2_1_dsp_y,w2_2_dsp_y,w2_3_dsp_y;
2524         u32 w2_0_st_x=h_pw_bp,w2_1_st_x=h_pw_bp,w2_2_st_x=h_pw_bp,w2_3_st_x=h_pw_bp;
2525         u32 w2_0_st_y=v_pw_bp,w2_1_st_y=v_pw_bp,w2_2_st_y=v_pw_bp,w2_3_st_y=v_pw_bp;
2526
2527         u32 w3_0_vir_y,w3_1_vir_y,w3_2_vir_y,w3_3_vir_y;
2528         u32 w3_0_dsp_x,w3_1_dsp_x,w3_2_dsp_x,w3_3_dsp_x;
2529         u32 w3_0_dsp_y,w3_1_dsp_y,w3_2_dsp_y,w3_3_dsp_y;
2530         u32 w3_0_st_x=h_pw_bp,w3_1_st_x=h_pw_bp,w3_2_st_x=h_pw_bp,w3_3_st_x=h_pw_bp;
2531         u32 w3_0_st_y=v_pw_bp,w3_1_st_y=v_pw_bp,w3_2_st_y=v_pw_bp,w3_3_st_y=v_pw_bp;
2532         u32 dclk_freq;
2533
2534         dclk_freq = screen->mode.pixclock;
2535         /*rk3288_lcdc_reg_dump(dev_drv);*/
2536
2537         spin_lock(&lcdc_dev->reg_lock);         
2538         if (lcdc_dev->clk_on) {
2539                 zorder = lcdc_readl(lcdc_dev, DSP_CTRL1);
2540                 layer0_sel = (zorder & m_DSP_LAYER0_SEL)>>8;
2541                 layer1_sel = (zorder & m_DSP_LAYER1_SEL)>>10;
2542                 layer2_sel = (zorder & m_DSP_LAYER2_SEL)>>12;
2543                 layer3_sel = (zorder & m_DSP_LAYER3_SEL)>>14;
2544                 /*WIN0*/
2545                 win_ctrl = lcdc_readl(lcdc_dev, WIN0_CTRL0);
2546                 w0_state = win_ctrl & m_WIN0_EN;
2547                 fmt_id = (win_ctrl & m_WIN0_DATA_FMT)>>1;
2548                 switch (fmt_id) {
2549                 case 0:
2550                         strcpy(format_w0, "ARGB888");
2551                         break;
2552                 case 1:
2553                         strcpy(format_w0, "RGB888");
2554                         break;
2555                 case 2:
2556                         strcpy(format_w0, "RGB565");
2557                         break;
2558                 case 4:
2559                         strcpy(format_w0, "YCbCr420");
2560                         break;
2561                 case 5:
2562                         strcpy(format_w0, "YCbCr422");
2563                         break;
2564                 case 6:
2565                         strcpy(format_w0, "YCbCr444");
2566                         break;
2567                 default:
2568                         strcpy(format_w0, "invalid\n");
2569                         break;
2570                 }
2571                 vir_info = lcdc_readl(lcdc_dev,WIN0_VIR);
2572                 act_info = lcdc_readl(lcdc_dev,WIN0_ACT_INFO);
2573                 dsp_info = lcdc_readl(lcdc_dev,WIN0_DSP_INFO);
2574                 dsp_st = lcdc_readl(lcdc_dev,WIN0_DSP_ST);
2575                 y_factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_YRGB);
2576                 uv_factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_CBR);
2577                 w0_vir_y = vir_info & m_WIN0_VIR_STRIDE;
2578                 w0_vir_uv = (vir_info & m_WIN0_VIR_STRIDE_UV)>>16;
2579                 w0_act_x = (act_info & m_WIN0_ACT_WIDTH)+1;
2580                 w0_act_y = ((act_info & m_WIN0_ACT_HEIGHT)>>16)+1;
2581                 w0_dsp_x = (dsp_info & m_WIN0_DSP_WIDTH)+1;
2582                 w0_dsp_y = ((dsp_info & m_WIN0_DSP_HEIGHT)>>16)+1;
2583                 if (w0_state) {
2584                         w0_st_x = dsp_st & m_WIN0_DSP_XST;
2585                         w0_st_y = (dsp_st & m_WIN0_DSP_YST)>>16;
2586                 }
2587                 w0_y_h_fac = y_factor & m_WIN0_HS_FACTOR_YRGB;
2588                 w0_y_v_fac = (y_factor & m_WIN0_VS_FACTOR_YRGB)>>16;
2589                 w0_uv_h_fac = uv_factor & m_WIN0_HS_FACTOR_CBR;
2590                 w0_uv_v_fac = (uv_factor & m_WIN0_VS_FACTOR_CBR)>>16;
2591
2592                 /*WIN1*/
2593                 win_ctrl = lcdc_readl(lcdc_dev, WIN1_CTRL0);
2594                 w1_state = win_ctrl & m_WIN1_EN;
2595                 fmt_id = (win_ctrl & m_WIN1_DATA_FMT)>>1;
2596                 switch (fmt_id) {
2597                 case 0:
2598                         strcpy(format_w1, "ARGB888");
2599                         break;
2600                 case 1:
2601                         strcpy(format_w1, "RGB888");
2602                         break;
2603                 case 2:
2604                         strcpy(format_w1, "RGB565");
2605                         break;
2606                 case 4:
2607                         strcpy(format_w1, "YCbCr420");
2608                         break;
2609                 case 5:
2610                         strcpy(format_w1, "YCbCr422");
2611                         break;
2612                 case 6:
2613                         strcpy(format_w1, "YCbCr444");
2614                         break;
2615                 default:
2616                         strcpy(format_w1, "invalid\n");
2617                         break;
2618                 }
2619                 vir_info = lcdc_readl(lcdc_dev,WIN1_VIR);
2620                 act_info = lcdc_readl(lcdc_dev,WIN1_ACT_INFO);
2621                 dsp_info = lcdc_readl(lcdc_dev,WIN1_DSP_INFO);
2622                 dsp_st = lcdc_readl(lcdc_dev,WIN1_DSP_ST);
2623                 y_factor = lcdc_readl(lcdc_dev,WIN1_SCL_FACTOR_YRGB);
2624                 uv_factor = lcdc_readl(lcdc_dev,WIN1_SCL_FACTOR_CBR);
2625                 w1_vir_y = vir_info & m_WIN1_VIR_STRIDE;
2626                 w1_vir_uv = (vir_info & m_WIN1_VIR_STRIDE_UV)>>16;
2627                 w1_act_x = (act_info & m_WIN1_ACT_WIDTH)+1;
2628                 w1_act_y = ((act_info & m_WIN1_ACT_HEIGHT)>>16)+1;
2629                 w1_dsp_x = (dsp_info & m_WIN1_DSP_WIDTH)+1;
2630                 w1_dsp_y =((dsp_info & m_WIN1_DSP_HEIGHT)>>16)+1;
2631                 if (w1_state) {
2632                         w1_st_x = dsp_st & m_WIN1_DSP_XST;
2633                         w1_st_y = (dsp_st & m_WIN1_DSP_YST)>>16;
2634                 }
2635                 w1_y_h_fac = y_factor & m_WIN1_HS_FACTOR_YRGB;
2636                 w1_y_v_fac = (y_factor & m_WIN1_VS_FACTOR_YRGB)>>16;
2637                 w1_uv_h_fac = uv_factor & m_WIN1_HS_FACTOR_CBR;
2638                 w1_uv_v_fac = (uv_factor & m_WIN1_VS_FACTOR_CBR)>>16;
2639                 /*WIN2*/
2640                 win_ctrl = lcdc_readl(lcdc_dev, WIN2_CTRL0);
2641                 w2_state = win_ctrl & m_WIN2_EN;
2642                 w2_0_state = (win_ctrl & m_WIN2_MST0_EN)>>4;
2643                 w2_1_state = (win_ctrl & m_WIN2_MST1_EN)>>5;
2644                 w2_2_state = (win_ctrl & m_WIN2_MST2_EN)>>6;
2645                 w2_3_state = (win_ctrl & m_WIN2_MST3_EN)>>7;    
2646                 vir_info = lcdc_readl(lcdc_dev,WIN2_VIR0_1);
2647                 w2_0_vir_y = vir_info & m_WIN2_VIR_STRIDE0;
2648                 w2_1_vir_y = (vir_info & m_WIN2_VIR_STRIDE1)>>16;
2649                 vir_info = lcdc_readl(lcdc_dev,WIN2_VIR2_3);
2650                 w2_2_vir_y = vir_info & m_WIN2_VIR_STRIDE2;
2651                 w2_3_vir_y = (vir_info & m_WIN2_VIR_STRIDE3)>>16;                       
2652                 fmt_id = (win_ctrl & m_WIN2_DATA_FMT)>>1;
2653                 switch (fmt_id) {
2654                 case 0:
2655                         strcpy(format_w2, "ARGB888");
2656                         break;
2657                 case 1:
2658                         strcpy(format_w2, "RGB888");
2659                         break;
2660                 case 2:
2661                         strcpy(format_w2, "RGB565");
2662                         break;
2663                 case 4:
2664                         strcpy(format_w2,"8bpp");
2665                         break;
2666                 case 5:
2667                         strcpy(format_w2,"4bpp");
2668                         break;
2669                 case 6:
2670                         strcpy(format_w2,"2bpp");
2671                         break;
2672                 case 7:
2673                         strcpy(format_w2,"1bpp");
2674                         break;
2675                 default:
2676                         strcpy(format_w2, "invalid\n");
2677                         break;
2678                 } 
2679                 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO0);
2680                 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST0);
2681                 w2_0_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH0)+1;
2682                 w2_0_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT0)>>16)+1;
2683                 if (w2_0_state) {
2684                         w2_0_st_x = dsp_st & m_WIN2_DSP_XST0;
2685                         w2_0_st_y = (dsp_st & m_WIN2_DSP_YST0)>>16;
2686                 }
2687                 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO1);
2688                 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST1);
2689                 w2_1_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH1)+1;
2690                 w2_1_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT1)>>16)+1;
2691                 if (w2_1_state) {
2692                         w2_1_st_x = dsp_st & m_WIN2_DSP_XST1;
2693                         w2_1_st_y = (dsp_st & m_WIN2_DSP_YST1)>>16;
2694                 }
2695                 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO2);
2696                 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST2);
2697                 w2_2_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH2)+1;
2698                 w2_2_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT2)>>16)+1;
2699                 if (w2_2_state) {
2700                         w2_2_st_x = dsp_st & m_WIN2_DSP_XST2;
2701                         w2_2_st_y = (dsp_st & m_WIN2_DSP_YST2)>>16;
2702                 }
2703                 dsp_info = lcdc_readl(lcdc_dev,WIN2_DSP_INFO3);
2704                 dsp_st = lcdc_readl(lcdc_dev,WIN2_DSP_ST3);
2705                 w2_3_dsp_x = (dsp_info & m_WIN2_DSP_WIDTH3)+1;
2706                 w2_3_dsp_y = ((dsp_info & m_WIN2_DSP_HEIGHT3)>>16)+1;
2707                 if (w2_3_state) {
2708                         w2_3_st_x = dsp_st & m_WIN2_DSP_XST3;
2709                         w2_3_st_y = (dsp_st & m_WIN2_DSP_YST3)>>16;
2710                 }
2711
2712                 /*WIN3*/
2713                 win_ctrl = lcdc_readl(lcdc_dev, WIN3_CTRL0);
2714                 w3_state = win_ctrl & m_WIN3_EN;
2715                 w3_0_state = (win_ctrl & m_WIN3_MST0_EN)>>4;
2716                 w3_1_state = (win_ctrl & m_WIN3_MST1_EN)>>5;
2717                 w3_2_state = (win_ctrl & m_WIN3_MST2_EN)>>6;
2718                 w3_3_state = (win_ctrl & m_WIN3_MST3_EN)>>7; 
2719                 vir_info = lcdc_readl(lcdc_dev,WIN3_VIR0_1);
2720                 w3_0_vir_y = vir_info & m_WIN3_VIR_STRIDE0;
2721                 w3_1_vir_y = (vir_info & m_WIN3_VIR_STRIDE1)>>16;
2722                 vir_info = lcdc_readl(lcdc_dev,WIN3_VIR2_3);
2723                 w3_2_vir_y = vir_info & m_WIN3_VIR_STRIDE2;
2724                 w3_3_vir_y = (vir_info & m_WIN3_VIR_STRIDE3)>>16;                       
2725                 fmt_id = (win_ctrl & m_WIN3_DATA_FMT)>>1;
2726                 switch (fmt_id) {
2727                 case 0:
2728                         strcpy(format_w3, "ARGB888");
2729                         break;
2730                 case 1:
2731                         strcpy(format_w3, "RGB888");
2732                         break;
2733                 case 2:
2734                         strcpy(format_w3, "RGB565");
2735                         break;
2736                 case 4:
2737                         strcpy(format_w3,"8bpp");
2738                         break;
2739                 case 5:
2740                         strcpy(format_w3,"4bpp");
2741                         break;
2742                 case 6:
2743                         strcpy(format_w3,"2bpp");
2744                         break;
2745                 case 7:
2746                         strcpy(format_w3,"1bpp");
2747                         break;
2748                 default:
2749                         strcpy(format_w3, "invalid");
2750                         break;
2751                 } 
2752                 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO0);
2753                 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST0);
2754                 w3_0_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH0)+1;
2755                 w3_0_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT0)>>16)+1;
2756                 if (w3_0_state) {
2757                         w3_0_st_x = dsp_st & m_WIN3_DSP_XST0;
2758                         w3_0_st_y = (dsp_st & m_WIN3_DSP_YST0)>>16;
2759                 }
2760                 
2761                 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO1);
2762                 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST1);
2763                 w3_1_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH1)+1;
2764                 w3_1_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT1)>>16)+1;
2765                 if (w3_1_state) {
2766                         w3_1_st_x = dsp_st & m_WIN3_DSP_XST1;
2767                         w3_1_st_y = (dsp_st & m_WIN3_DSP_YST1)>>16;
2768                 }
2769                 
2770                 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO2);
2771                 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST2);
2772                 w3_2_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH2)+1;
2773                 w3_2_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT2)>>16)+1;
2774                 if (w3_2_state) {
2775                         w3_2_st_x = dsp_st & m_WIN3_DSP_XST2;
2776                         w3_2_st_y = (dsp_st & m_WIN3_DSP_YST2)>>16;
2777                 }
2778                 
2779                 dsp_info = lcdc_readl(lcdc_dev,WIN3_DSP_INFO3);
2780                 dsp_st = lcdc_readl(lcdc_dev,WIN3_DSP_ST3);
2781                 w3_3_dsp_x = (dsp_info & m_WIN3_DSP_WIDTH3)+1;
2782                 w3_3_dsp_y = ((dsp_info & m_WIN3_DSP_HEIGHT3)>>16)+1;
2783                 if (w3_3_state) {
2784                         w3_3_st_x = dsp_st & m_WIN3_DSP_XST3;
2785                         w3_3_st_y = (dsp_st & m_WIN3_DSP_YST3)>>16;
2786                 }
2787
2788         } else {
2789                 spin_unlock(&lcdc_dev->reg_lock);
2790                 return -EPERM;
2791         }
2792         spin_unlock(&lcdc_dev->reg_lock);
2793         return snprintf(buf, PAGE_SIZE,
2794                         "z-order:\n"
2795                         "  layer3_sel_win[%d]\n"
2796                         "  layer2_sel_win[%d]\n"
2797                         "  layer1_sel_win[%d]\n"
2798                         "  layer0_sel_win[%d]\n"
2799                         "win0:\n"
2800                         "  state:%d, "
2801                         "  fmt:%s, "
2802                         "  y_vir:%d, "
2803                         "  uv_vir:%d\n"
2804                         "  xact:%4d, "
2805                         "  yact:%4d, "
2806                         "  dsp_x:%4d, "
2807                         "  dsp_y:%4d, "
2808                         "  x_st:%4d, "
2809                         "  y_st:%4d\n"
2810                         "  y_h_fac:%8d, "
2811                         "  y_v_fac:%8d, "
2812                         "  uv_h_fac:%8d, "
2813                         "  uv_v_fac:%8d\n"
2814                         "  y_addr: 0x%08x, "
2815                         "  uv_addr:0x%08x\n"
2816                         "win1:\n"
2817                         "  state:%d, "
2818                         "  fmt:%s, "
2819                         "  y_vir:%d, "
2820                         "  uv_vir:%d\n"
2821                         "  xact:%4d, "
2822                         "  yact:%4d, "
2823                         "  dsp_x:%4d, "
2824                         "  dsp_y:%4d, "
2825                         "  x_st:%4d, "
2826                         "  y_st:%4d\n"
2827                         "  y_h_fac:%8d, "
2828                         "  y_v_fac:%8d, "
2829                         "  uv_h_fac:%8d, "
2830                         "  uv_v_fac:%8d\n"
2831                         "  y_addr: 0x%08x, "
2832                         "  uv_addr:0x%08x\n"    
2833                         "win2:\n"
2834                         "  state:%d\n"
2835                         "  fmt:%s\n"
2836                         "  area0:"
2837                         "  state:%d,"
2838                         "  y_vir:%4d,"
2839                         "  dsp_x:%4d,"
2840                         "  dsp_y:%4d,"
2841                         "  x_st:%4d,"
2842                         "  y_st:%4d,"
2843                         "  addr:0x%08x\n"
2844                         "  area1:"
2845                         "  state:%d,"
2846                         "  y_vir:%4d,"
2847                         "  dsp_x:%4d,"
2848                         "  dsp_y:%4d,"
2849                         "  x_st:%4d,"
2850                         "  y_st:%4d,"
2851                         "  addr:0x%08x\n"
2852                         "  area2:"
2853                         "  state:%d,"
2854                         "  y_vir:%4d,"
2855                         "  dsp_x:%4d,"
2856                         "  dsp_y:%4d,"
2857                         "  x_st:%4d,"
2858                         "  y_st:%4d,"
2859                         "  addr:0x%08x\n"
2860                         "  area3:"
2861                         "  state:%d,"
2862                         "  y_vir:%4d,"
2863                         "  dsp_x:%4d,"
2864                         "  dsp_y:%4d,"
2865                         "  x_st:%4d,"
2866                         "  y_st:%4d,"
2867                         "  addr:0x%08x\n"
2868                         "win3:\n"
2869                         "  state:%d\n"
2870                         "  fmt:%s\n"
2871                         "  area0:"
2872                         "  state:%d,"
2873                         "  y_vir:%4d,"
2874                         "  dsp_x:%4d,"
2875                         "  dsp_y:%4d,"
2876                         "  x_st:%4d,"
2877                         "  y_st:%4d,"
2878                         "  addr:0x%08x\n"
2879                         "  area1:"
2880                         "  state:%d,"
2881                         "  y_vir:%4d,"
2882                         "  dsp_x:%4d,"
2883                         "  dsp_y:%4d,"
2884                         "  x_st:%4d,"
2885                         "  y_st:%4d "
2886                         "  addr:0x%08x\n"
2887                         "  area2:"
2888                         "  state:%d,"
2889                         "  y_vir:%4d,"
2890                         "  dsp_x:%4d,"
2891                         "  dsp_y:%4d,"
2892                         "  x_st:%4d,"
2893                         "  y_st:%4d,"
2894                         "  addr:0x%08x\n"
2895                         "  area3:"
2896                         "  state:%d,"
2897                         "  y_vir:%4d,"
2898                         "  dsp_x:%4d,"
2899                         "  dsp_y:%4d,"
2900                         "  x_st:%4d,"
2901                         "  y_st:%4d,"
2902                         "  addr:0x%08x\n",
2903                         layer3_sel,layer2_sel,layer1_sel,layer0_sel,
2904                         w0_state,format_w0,w0_vir_y,w0_vir_uv,w0_act_x,w0_act_y,
2905                         w0_dsp_x,w0_dsp_y,w0_st_x-h_pw_bp,w0_st_y-v_pw_bp,w0_y_h_fac,w0_y_v_fac,w0_uv_h_fac,
2906                         w0_uv_v_fac,lcdc_readl(lcdc_dev, WIN0_YRGB_MST),
2907                         lcdc_readl(lcdc_dev, WIN0_CBR_MST),
2908
2909                         w1_state,format_w1,w1_vir_y,w1_vir_uv,w1_act_x,w1_act_y,
2910                         w1_dsp_x,w1_dsp_y,w1_st_x-h_pw_bp,w1_st_y-v_pw_bp,w1_y_h_fac,w1_y_v_fac,w1_uv_h_fac,
2911                         w1_uv_v_fac,lcdc_readl(lcdc_dev, WIN1_YRGB_MST),
2912                         lcdc_readl(lcdc_dev, WIN1_CBR_MST),                     
2913
2914                         w2_state,format_w2,
2915                         w2_0_state,w2_0_vir_y,w2_0_dsp_x,w2_0_dsp_y,
2916                         w2_0_st_x-h_pw_bp,w2_0_st_y-v_pw_bp,lcdc_readl(lcdc_dev, WIN2_MST0),
2917
2918                         w2_1_state,w2_1_vir_y,w2_1_dsp_x,w2_1_dsp_y,
2919                         w2_1_st_x-h_pw_bp,w2_1_st_y-v_pw_bp,lcdc_readl(lcdc_dev, WIN2_MST1),
2920
2921                         w2_2_state,w2_2_vir_y,w2_2_dsp_x,w2_2_dsp_y,
2922                         w2_2_st_x-h_pw_bp,w2_2_st_y-v_pw_bp,lcdc_readl(lcdc_dev, WIN2_MST2),
2923
2924                         w2_3_state,w2_3_vir_y,w2_3_dsp_x,w2_3_dsp_y,
2925                         w2_3_st_x-h_pw_bp,w2_3_st_y-v_pw_bp,lcdc_readl(lcdc_dev, WIN2_MST3),
2926                         
2927                         w3_state,format_w3,
2928                         w3_0_state,w3_0_vir_y,w3_0_dsp_x,w3_0_dsp_y,
2929                         w3_0_st_x-h_pw_bp,w3_0_st_y-v_pw_bp,lcdc_readl(lcdc_dev, WIN3_MST0),
2930
2931                         w3_1_state,w3_1_vir_y,w3_1_dsp_x,w3_1_dsp_y,
2932                         w3_1_st_x-h_pw_bp,w3_1_st_y-v_pw_bp,lcdc_readl(lcdc_dev, WIN3_MST1),
2933
2934                         w3_2_state,w3_2_vir_y,w3_2_dsp_x,w3_2_dsp_y,
2935                         w3_2_st_x-h_pw_bp,w3_2_st_y-v_pw_bp,lcdc_readl(lcdc_dev, WIN3_MST2),
2936
2937                         w3_3_state,w3_3_vir_y,w3_3_dsp_x,w3_3_dsp_y,
2938                         w3_3_st_x-h_pw_bp,w3_3_st_y-v_pw_bp,lcdc_readl(lcdc_dev, WIN3_MST3)
2939         );
2940                         
2941 }
2942
2943 static int rk3288_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
2944                                bool set)
2945 {
2946         struct lcdc_device *lcdc_dev =
2947             container_of(dev_drv, struct lcdc_device, driver);
2948         struct rk_screen *screen = dev_drv->cur_screen;
2949         u64 ft = 0;
2950         u32 dotclk;
2951         int ret;
2952         u32 pixclock;
2953         u32 x_total, y_total;
2954         if (set) {
2955                 ft = div_u64(1000000000000llu, fps);
2956                 x_total =
2957                     screen->mode.upper_margin + screen->mode.lower_margin +
2958                     screen->mode.yres + screen->mode.vsync_len;
2959                 y_total =
2960                     screen->mode.left_margin + screen->mode.right_margin +
2961                     screen->mode.xres + screen->mode.hsync_len;
2962                 dev_drv->pixclock = div_u64(ft, x_total * y_total);
2963                 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
2964                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
2965         }
2966
2967         pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
2968         dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
2969         fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
2970         screen->ft = 1000 / fps;        /*one frame time in ms */
2971
2972         if (set)
2973                 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
2974                          clk_get_rate(lcdc_dev->dclk), fps);
2975
2976         return fps;
2977 }
2978
2979 static int rk3288_fb_win_remap(struct rk_lcdc_driver *dev_drv, u16 order)
2980 {
2981         mutex_lock(&dev_drv->fb_win_id_mutex);
2982         if (order == FB_DEFAULT_ORDER)
2983                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2_FB3_WIN3;
2984         dev_drv->fb3_win_id = order / 1000;
2985         dev_drv->fb2_win_id = (order / 100) % 10;
2986         dev_drv->fb1_win_id = (order / 10) % 10;
2987         dev_drv->fb0_win_id = order % 10;
2988         mutex_unlock(&dev_drv->fb_win_id_mutex);
2989
2990         return 0;
2991 }
2992
2993 static int rk3288_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
2994                                   const char *id)
2995 {
2996         int win_id = 0;
2997         mutex_lock(&dev_drv->fb_win_id_mutex);
2998         if (!strcmp(id, "fb0") || !strcmp(id, "fb4"))
2999                 win_id = dev_drv->fb0_win_id;
3000         else if (!strcmp(id, "fb1") || !strcmp(id, "fb5"))
3001                 win_id = dev_drv->fb1_win_id;
3002         else if (!strcmp(id, "fb2") || !strcmp(id, "fb6"))
3003                 win_id = dev_drv->fb2_win_id;
3004         else if (!strcmp(id, "fb3") || !strcmp(id, "fb7"))
3005                 win_id = dev_drv->fb3_win_id;
3006         mutex_unlock(&dev_drv->fb_win_id_mutex);
3007
3008         return win_id;
3009 }
3010
3011 static int rk3288_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
3012 {
3013         int i,j;
3014         int __iomem *c;
3015         int v, r, g, b;
3016         int ret = 0;
3017
3018         struct lcdc_device *lcdc_dev =
3019             container_of(dev_drv, struct lcdc_device, driver);
3020         lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
3021         lcdc_cfg_done(lcdc_dev);
3022         mdelay(25);
3023         if (dev_drv->cur_screen->dsp_lut) {
3024                 for (i = 0; i < 256; i++) {
3025                         v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
3026                         c = lcdc_dev->dsp_lut_addr_base + (i << 2);
3027                         b = (v & 0xff) << 2;
3028                         g = (v & 0xff00) << 4;
3029                         r = (v & 0xff0000) << 6;
3030                         v = r + g + b;
3031                         for (j = 0; j < 4; j++) {
3032                                 writel_relaxed(v, c);
3033                                 v += (1 + (1 << 10) + (1 << 20)) ;
3034                                 c++;
3035                         }
3036                 }
3037         } else {
3038                 dev_err(dev_drv->dev, "no buffer to backup lut data!\n");
3039                 ret = -1;
3040         }
3041         
3042         do{
3043                 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
3044                 lcdc_cfg_done(lcdc_dev);
3045         }while(!lcdc_read_bit(lcdc_dev,DSP_CTRL1,m_DSP_LUT_EN));
3046         return ret;
3047 }
3048
3049 static int rk3288_lcdc_config_done(struct rk_lcdc_driver *dev_drv)
3050 {
3051         struct lcdc_device *lcdc_dev =
3052             container_of(dev_drv, struct lcdc_device, driver);
3053         int i;
3054         unsigned int mask, val;
3055         struct rk_lcdc_win *win = NULL;
3056         spin_lock(&lcdc_dev->reg_lock);
3057         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_STANDBY_EN,
3058                              v_STANDBY_EN(lcdc_dev->standby));
3059         for (i=0;i<4;i++) {
3060                 win = dev_drv->win[i];
3061                 if ((win->state == 0)&&(win->last_state == 1)) {
3062                         switch (win->id) {
3063                         case 0:
3064                                 lcdc_writel(lcdc_dev,WIN0_CTRL1,0x0);
3065                                 mask =  m_WIN0_EN;
3066                                 val  =  v_WIN0_EN(0);
3067                                 lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask,val);   
3068                                 break;
3069                         case 1:
3070                                 lcdc_writel(lcdc_dev,WIN1_CTRL1,0x0);
3071                                 mask =  m_WIN1_EN;
3072                                 val  =  v_WIN1_EN(0);
3073                                 lcdc_msk_reg(lcdc_dev, WIN1_CTRL0, mask,val);           
3074                                 break;
3075                         case 2:
3076                                 mask =  m_WIN2_EN | m_WIN2_MST0_EN | m_WIN2_MST1_EN |
3077                                         m_WIN2_MST2_EN | m_WIN2_MST3_EN;
3078                                 val  =  v_WIN2_EN(0) | v_WIN2_MST0_EN(0) | v_WIN2_MST1_EN(0) |
3079                                         v_WIN2_MST2_EN(0) | v_WIN2_MST3_EN(0);
3080                                 lcdc_msk_reg(lcdc_dev, WIN2_CTRL0, mask,val);                   
3081                                 break;
3082                         case 3:
3083                                 mask =  m_WIN3_EN | m_WIN3_MST0_EN | m_WIN3_MST1_EN |
3084                                         m_WIN3_MST2_EN | m_WIN3_MST3_EN;
3085                                 val  =  v_WIN3_EN(0) | v_WIN3_MST0_EN(0) |  v_WIN3_MST1_EN(0) |
3086                                         v_WIN3_MST2_EN(0) | v_WIN3_MST3_EN(0);
3087                                 lcdc_msk_reg(lcdc_dev, WIN3_CTRL0, mask,val);
3088                                 break;
3089                         default:
3090                                 break;
3091                         }
3092                 }       
3093                 win->last_state = win->state;
3094         }
3095         lcdc_cfg_done(lcdc_dev);
3096         spin_unlock(&lcdc_dev->reg_lock);
3097         return 0;
3098 }
3099
3100
3101 static int rk3288_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
3102 {
3103         struct lcdc_device *lcdc_dev =
3104             container_of(dev_drv, struct lcdc_device, driver);
3105         spin_lock(&lcdc_dev->reg_lock);
3106         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN,
3107                      v_DIRECT_PATH_EN(open));
3108         lcdc_cfg_done(lcdc_dev);
3109         spin_unlock(&lcdc_dev->reg_lock);
3110         return 0;
3111 }
3112
3113 static int rk3288_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
3114 {
3115         struct lcdc_device *lcdc_dev = container_of(dev_drv,
3116                                         struct lcdc_device, driver);
3117         spin_lock(&lcdc_dev->reg_lock);
3118         lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_SEL,
3119                      v_DIRECT_PATCH_SEL(win_id));
3120         lcdc_cfg_done(lcdc_dev);
3121         spin_unlock(&lcdc_dev->reg_lock);
3122         return 0;
3123
3124 }
3125
3126 static int rk3288_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
3127 {
3128         struct lcdc_device *lcdc_dev =
3129             container_of(dev_drv, struct lcdc_device, driver);
3130         int ovl;
3131         spin_lock(&lcdc_dev->reg_lock);
3132         ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_EN);
3133         spin_unlock(&lcdc_dev->reg_lock);
3134         return ovl;
3135 }
3136 static int rk3288_lcdc_set_irq_to_cpu(struct rk_lcdc_driver * dev_drv,int enable)
3137 {
3138        struct lcdc_device *lcdc_dev =
3139                                 container_of(dev_drv,struct lcdc_device,driver);
3140        if (enable)
3141                enable_irq(lcdc_dev->irq);
3142        else
3143                disable_irq(lcdc_dev->irq);
3144        return 0;
3145 }
3146
3147 int rk3288_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
3148 {
3149         struct lcdc_device *lcdc_dev =
3150             container_of(dev_drv, struct lcdc_device, driver);
3151         u32 int_reg;
3152         int ret;
3153
3154         if (lcdc_dev->clk_on &&(!dev_drv->suspend_flag)){
3155                 int_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
3156                 if (int_reg & m_LINE_FLAG_INTR_STS) {
3157                         lcdc_dev->driver.frame_time.last_framedone_t =
3158                                         lcdc_dev->driver.frame_time.framedone_t;
3159                         lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
3160                         lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
3161                                      v_LINE_FLAG_INTR_CLR(1));
3162                         ret = RK_LF_STATUS_FC;
3163                 } else
3164                         ret = RK_LF_STATUS_FR;
3165         } else {
3166                 ret = RK_LF_STATUS_NC;
3167         }
3168
3169         return ret;
3170 }
3171 static int rk3288_lcdc_get_dsp_addr(struct rk_lcdc_driver *dev_drv,unsigned int *dsp_addr)
3172 {
3173         struct lcdc_device *lcdc_dev =
3174             container_of(dev_drv, struct lcdc_device, driver);
3175         spin_lock(&lcdc_dev->reg_lock);
3176         if(lcdc_dev->clk_on){
3177                 dsp_addr[0] = lcdc_readl(lcdc_dev, WIN0_YRGB_MST);
3178                 dsp_addr[1] = lcdc_readl(lcdc_dev, WIN1_YRGB_MST);
3179                 dsp_addr[2] = lcdc_readl(lcdc_dev, WIN2_MST0);
3180                 dsp_addr[3] = lcdc_readl(lcdc_dev, WIN3_MST0);
3181         }
3182         spin_unlock(&lcdc_dev->reg_lock);
3183         return 0;
3184 }
3185
3186 static struct lcdc_cabc_mode cabc_mode[4] = {
3187 /* pixel_num, stage_up, stage_down */
3188         {5,     128,    0},     /*mode 1*/
3189         {10,    128,    0},     /*mode 2*/
3190         {15,    128,    0},     /*mode 3*/
3191         {20,    128,    0},     /*mode 4*/
3192 };
3193
3194 static int rk3288_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv, int mode)
3195 {
3196         struct lcdc_device *lcdc_dev =
3197             container_of(dev_drv, struct lcdc_device, driver);
3198         struct rk_screen *screen = dev_drv->cur_screen;
3199         u32 total_pixel, calc_pixel, stage_up, stage_down, pixel_num;
3200         u32 mask = 0, val = 0, cabc_en = 0;
3201         u32 max_mode_num = sizeof(cabc_mode) / sizeof(struct lcdc_cabc_mode);
3202
3203         dev_drv->cabc_mode = mode;
3204
3205         /* iomux connect to vop or pwm */
3206         if (mode == 0) {
3207                 DBG(3, "close cabc and select rk pwm\n");
3208                 val = 0x30001;
3209                 writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_GPIO7A_IOMUX);
3210                 cabc_en = 0;
3211         } else if (mode > 0 && mode <= max_mode_num) {
3212                 DBG(3, "open cabc and select vop pwm\n");
3213                 val = (dev_drv->id == 0) ? 0x30002 : 0x30003;
3214                 writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_GPIO7A_IOMUX);
3215                 cabc_en = 1;
3216         } else if (mode > 0x10 && mode <= (max_mode_num + 0x10)) {
3217                 DBG(3, "open cabc and select rk pwm\n");
3218                 val = 0x30001;
3219                 writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_GPIO7A_IOMUX);
3220                 cabc_en = 1;
3221                 mode -= 0x10;
3222         } else if (mode == 0xff) {
3223                 DBG(3, "close cabc and select vop pwm\n");
3224                 val = (dev_drv->id == 0) ? 0x30002 : 0x30003;
3225                 writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_GPIO7A_IOMUX);
3226                 cabc_en = 0;
3227         } else {
3228                 dev_err(lcdc_dev->dev, "invalid cabc mode value:%d", mode);
3229                 return 0;
3230         }
3231
3232         if (cabc_en == 0) {
3233                 spin_lock(&lcdc_dev->reg_lock);
3234                 if(lcdc_dev->clk_on) {
3235                         lcdc_msk_reg(lcdc_dev, CABC_CTRL0, m_CABC_EN, v_CABC_EN(0));
3236                         lcdc_cfg_done(lcdc_dev);
3237                 }
3238                 spin_unlock(&lcdc_dev->reg_lock);
3239                 return 0;
3240         }
3241
3242         total_pixel = screen->mode.xres * screen->mode.yres;
3243         pixel_num = 1000 - (cabc_mode[mode - 1].pixel_num);
3244         calc_pixel = (total_pixel * pixel_num) / 1000;
3245         stage_up = cabc_mode[mode - 1].stage_up;
3246         stage_down = cabc_mode[mode - 1].stage_down;
3247         
3248         spin_lock(&lcdc_dev->reg_lock);
3249         if(lcdc_dev->clk_on) {
3250                 mask = m_CABC_TOTAL_NUM | m_CABC_STAGE_DOWN;
3251                 val = v_CABC_TOTAL_NUM(total_pixel) | v_CABC_STAGE_DOWN(stage_down);
3252                 lcdc_msk_reg(lcdc_dev, CABC_CTRL1, mask, val);
3253
3254                 mask = m_CABC_EN | m_CABC_CALC_PIXEL_NUM |
3255                         m_CABC_STAGE_UP;
3256                 val = v_CABC_EN(1) | v_CABC_CALC_PIXEL_NUM(calc_pixel) |
3257                         v_CABC_STAGE_UP(stage_up);
3258                 lcdc_msk_reg(lcdc_dev, CABC_CTRL0, mask, val);
3259                 lcdc_cfg_done(lcdc_dev);
3260         }
3261         spin_unlock(&lcdc_dev->reg_lock);
3262
3263         return 0;
3264 }
3265 /*
3266         a:[-30~0]:
3267             sin_hue = sin(a)*256 +0x100;
3268             cos_hue = cos(a)*256;
3269         a:[0~30]
3270             sin_hue = sin(a)*256;
3271             cos_hue = cos(a)*256;
3272 */
3273 static int rk3288_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,bcsh_hue_mode mode)
3274 {
3275
3276         struct lcdc_device *lcdc_dev =
3277             container_of(dev_drv, struct lcdc_device, driver);
3278         u32 val;
3279                         
3280         spin_lock(&lcdc_dev->reg_lock);
3281         if (lcdc_dev->clk_on) {
3282                 val = lcdc_readl(lcdc_dev, BCSH_H);
3283                 switch(mode){
3284                 case H_SIN:
3285                         val &= m_BCSH_SIN_HUE;
3286                         break;
3287                 case H_COS:
3288                         val &= m_BCSH_COS_HUE;
3289                         val >>= 16;
3290                         break;
3291                 default:
3292                         break;
3293                 }
3294         }
3295         spin_unlock(&lcdc_dev->reg_lock);
3296
3297         return val;
3298 }
3299
3300
3301 static int rk3288_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,int sin_hue, int cos_hue)
3302 {
3303
3304         struct lcdc_device *lcdc_dev =
3305             container_of(dev_drv, struct lcdc_device, driver);
3306         u32 mask, val;
3307
3308         spin_lock(&lcdc_dev->reg_lock);
3309         if (lcdc_dev->clk_on) {
3310                 mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
3311                 val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
3312                 lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
3313                 lcdc_cfg_done(lcdc_dev);
3314         }       
3315         spin_unlock(&lcdc_dev->reg_lock);
3316         
3317         return 0;
3318 }
3319
3320 static int rk3288_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,bcsh_bcs_mode mode,int value)
3321 {
3322         struct lcdc_device *lcdc_dev =
3323             container_of(dev_drv, struct lcdc_device, driver);
3324         u32 mask, val;
3325         
3326         spin_lock(&lcdc_dev->reg_lock);
3327         if(lcdc_dev->clk_on) {
3328                 switch (mode) {
3329                 case BRIGHTNESS:
3330                 /*from 0 to 255,typical is 128*/
3331                         if (value < 0x80)
3332                                 value += 0x80;
3333                         else if (value >= 0x80)
3334                                 value = value - 0x80;
3335                         mask =  m_BCSH_BRIGHTNESS;
3336                         val = v_BCSH_BRIGHTNESS(value);
3337                         break;
3338                 case CONTRAST:
3339                 /*from 0 to 510,typical is 256*/
3340                         mask =  m_BCSH_CONTRAST;
3341                         val =  v_BCSH_CONTRAST(value);
3342                         break;
3343                 case SAT_CON:
3344                 /*from 0 to 1015,typical is 256*/
3345                         mask = m_BCSH_SAT_CON;
3346                         val = v_BCSH_SAT_CON(value);
3347                         break;
3348                 default:
3349                         break;
3350                 }
3351                 lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
3352                 lcdc_cfg_done(lcdc_dev);
3353         }
3354         spin_unlock(&lcdc_dev->reg_lock);
3355         return val;
3356 }
3357
3358 static int rk3288_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,bcsh_bcs_mode mode)
3359 {
3360         struct lcdc_device *lcdc_dev =
3361             container_of(dev_drv, struct lcdc_device, driver);
3362         u32 val;
3363
3364         spin_lock(&lcdc_dev->reg_lock);
3365         if(lcdc_dev->clk_on) {
3366                 val = lcdc_readl(lcdc_dev, BCSH_BCS);
3367                 switch (mode) {
3368                 case BRIGHTNESS:
3369                         val &= m_BCSH_BRIGHTNESS;
3370                         if(val > 0x80)
3371                                 val -= 0x80;
3372                         else
3373                                 val += 0x80;
3374                         break;
3375                 case CONTRAST:
3376                         val &= m_BCSH_CONTRAST;
3377                         val >>= 8;
3378                         break;
3379                 case SAT_CON:
3380                         val &= m_BCSH_SAT_CON;
3381                         val >>= 20;
3382                         break;
3383                 default:
3384                         break;
3385                 }
3386         }
3387         spin_unlock(&lcdc_dev->reg_lock);
3388         return val;
3389 }
3390
3391
3392 static int rk3288_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
3393 {
3394         struct lcdc_device *lcdc_dev =
3395             container_of(dev_drv, struct lcdc_device, driver);
3396         u32 mask, val;
3397
3398         spin_lock(&lcdc_dev->reg_lock);
3399         if (lcdc_dev->clk_on) {
3400                 if (open) {
3401                         lcdc_writel(lcdc_dev,BCSH_COLOR_BAR,0x1);
3402                         lcdc_writel(lcdc_dev,BCSH_BCS,0xd0010000);
3403                         lcdc_writel(lcdc_dev,BCSH_H,0x01000000);
3404                 } else {
3405                         mask = m_BCSH_EN;
3406                         val = v_BCSH_EN(0);
3407                         lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
3408                 }
3409                 lcdc_cfg_done(lcdc_dev);
3410         }
3411         spin_unlock(&lcdc_dev->reg_lock);
3412         return 0;
3413 }
3414
3415 static int rk3288_lcdc_set_bcsh(struct rk_lcdc_driver *dev_drv,
3416                                      bool enable)
3417 {
3418         if (!enable || !dev_drv->bcsh.enable) {
3419                 rk3288_lcdc_open_bcsh(dev_drv, false);
3420                 return 0;
3421         }
3422
3423         if (dev_drv->bcsh.brightness <= 255 ||
3424             dev_drv->bcsh.contrast <= 510 ||
3425             dev_drv->bcsh.sat_con <= 1015 ||
3426             (dev_drv->bcsh.sin_hue <= 511 && dev_drv->bcsh.cos_hue <= 511)) {
3427                 rk3288_lcdc_open_bcsh(dev_drv, true);
3428                 if (dev_drv->bcsh.brightness <= 255)
3429                         rk3288_lcdc_set_bcsh_bcs(dev_drv, BRIGHTNESS,
3430                                                  dev_drv->bcsh.brightness);
3431                 if (dev_drv->bcsh.contrast <= 510)
3432                         rk3288_lcdc_set_bcsh_bcs(dev_drv, CONTRAST,
3433                                                  dev_drv->bcsh.contrast);
3434                 if (dev_drv->bcsh.sat_con <= 1015)
3435                         rk3288_lcdc_set_bcsh_bcs(dev_drv, SAT_CON,
3436                                                  dev_drv->bcsh.sat_con);
3437                 if (dev_drv->bcsh.sin_hue <= 511 &&
3438                     dev_drv->bcsh.cos_hue <= 511)
3439                         rk3288_lcdc_set_bcsh_hue(dev_drv,
3440                                                  dev_drv->bcsh.sin_hue,
3441                                                  dev_drv->bcsh.cos_hue);
3442         }
3443         return 0;
3444 }
3445
3446 static struct rk_lcdc_win lcdc_win[] = {
3447         [0] = {
3448                .name = "win0",
3449                .id = 0,
3450                .support_3d = false,
3451                },
3452         [1] = {
3453                .name = "win1",
3454                .id = 1,
3455                .support_3d = false,
3456                },
3457         [2] = {
3458                .name = "win2",
3459                .id = 2,
3460                .support_3d = false,
3461                },
3462         [3] = {
3463                .name = "win3",
3464                .id = 3,
3465                .support_3d = false,
3466                },              
3467 };
3468
3469 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
3470         .open                   = rk3288_lcdc_open,
3471         .win_direct_en          = rk3288_lcdc_win_direct_en,
3472         .load_screen            = rk3288_load_screen,
3473         .set_par                = rk3288_lcdc_set_par,
3474         .pan_display            = rk3288_lcdc_pan_display,
3475         .direct_set_addr        = rk3288_lcdc_direct_set_win_addr,
3476         .lcdc_reg_update        = rk3288_lcdc_reg_update,
3477         .blank                  = rk3288_lcdc_blank,
3478         .ioctl                  = rk3288_lcdc_ioctl,
3479         .suspend                = rk3288_lcdc_early_suspend,
3480         .resume                 = rk3288_lcdc_early_resume,
3481         .get_win_state          = rk3288_lcdc_get_win_state,
3482         .ovl_mgr                = rk3288_lcdc_ovl_mgr,
3483         .get_disp_info          = rk3288_lcdc_get_disp_info,
3484         .fps_mgr                = rk3288_lcdc_fps_mgr,
3485         .fb_get_win_id          = rk3288_lcdc_get_win_id,
3486         .fb_win_remap           = rk3288_fb_win_remap,
3487         .set_dsp_lut            = rk3288_set_dsp_lut,
3488         .poll_vblank            = rk3288_lcdc_poll_vblank,
3489         .dpi_open               = rk3288_lcdc_dpi_open,
3490         .dpi_win_sel            = rk3288_lcdc_dpi_win_sel,
3491         .dpi_status             = rk3288_lcdc_dpi_status,
3492         .get_dsp_addr           = rk3288_lcdc_get_dsp_addr,
3493         .set_dsp_cabc           = rk3288_lcdc_set_dsp_cabc,
3494         .set_dsp_bcsh_hue       = rk3288_lcdc_set_bcsh_hue,
3495         .set_dsp_bcsh_bcs       = rk3288_lcdc_set_bcsh_bcs,
3496         .get_dsp_bcsh_hue       = rk3288_lcdc_get_bcsh_hue,
3497         .get_dsp_bcsh_bcs       = rk3288_lcdc_get_bcsh_bcs,
3498         .open_bcsh              = rk3288_lcdc_open_bcsh,
3499         .dump_reg               = rk3288_lcdc_reg_dump,
3500         .cfg_done               = rk3288_lcdc_config_done,
3501         .set_irq_to_cpu         = rk3288_lcdc_set_irq_to_cpu,
3502 };
3503
3504 #ifdef LCDC_IRQ_DEBUG
3505 static int rk3288_lcdc_parse_irq(struct lcdc_device *lcdc_dev,unsigned int reg_val)
3506 {
3507         if (reg_val & m_WIN0_EMPTY_INTR_STS) {
3508                 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN0_EMPTY_INTR_CLR,
3509                              v_WIN0_EMPTY_INTR_CLR(1));
3510                 dev_warn(lcdc_dev->dev,"win0 empty irq!");
3511         }else if (reg_val & m_WIN1_EMPTY_INTR_STS) {
3512                 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN1_EMPTY_INTR_CLR,
3513                              v_WIN1_EMPTY_INTR_CLR(1));
3514                 dev_warn(lcdc_dev->dev,"win1 empty irq!");
3515         }else if (reg_val & m_WIN2_EMPTY_INTR_STS) {
3516                 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN2_EMPTY_INTR_CLR,
3517                              v_WIN2_EMPTY_INTR_CLR(1));
3518                 dev_warn(lcdc_dev->dev,"win2 empty irq!");
3519         }else if (reg_val & m_WIN3_EMPTY_INTR_STS) {
3520                 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_WIN3_EMPTY_INTR_CLR,
3521                              v_WIN3_EMPTY_INTR_CLR(1));
3522                 dev_warn(lcdc_dev->dev,"win3 empty irq!");
3523         }else if (reg_val & m_HWC_EMPTY_INTR_STS) {
3524                 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_HWC_EMPTY_INTR_CLR,
3525                              v_HWC_EMPTY_INTR_CLR(1));
3526                 dev_warn(lcdc_dev->dev,"HWC empty irq!");
3527         }else if (reg_val & m_POST_BUF_EMPTY_INTR_STS) {
3528                 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_POST_BUF_EMPTY_INTR_CLR,
3529                              v_POST_BUF_EMPTY_INTR_CLR(1));
3530                 dev_warn(lcdc_dev->dev,"post buf empty irq!");
3531         }else if (reg_val & m_PWM_GEN_INTR_STS) {
3532                 lcdc_msk_reg(lcdc_dev, INTR_CTRL1, m_PWM_GEN_INTR_CLR,
3533                              v_PWM_GEN_INTR_CLR(1));
3534                 dev_warn(lcdc_dev->dev,"PWM gen irq!");
3535         }
3536
3537         return 0;
3538 }
3539 #endif
3540
3541 static irqreturn_t rk3288_lcdc_isr(int irq, void *dev_id)
3542 {
3543         struct lcdc_device *lcdc_dev =
3544             (struct lcdc_device *)dev_id;
3545         ktime_t timestamp = ktime_get();
3546         u32 intr0_reg;
3547
3548         intr0_reg = lcdc_readl(lcdc_dev, INTR_CTRL0);
3549
3550         if(intr0_reg & m_FS_INTR_STS){
3551                 timestamp = ktime_get();
3552                 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_FS_INTR_CLR,
3553                              v_FS_INTR_CLR(1));
3554                 /*if(lcdc_dev->driver.wait_fs){ */
3555                 if (0) {
3556                         spin_lock(&(lcdc_dev->driver.cpl_lock));
3557                         complete(&(lcdc_dev->driver.frame_done));
3558                         spin_unlock(&(lcdc_dev->driver.cpl_lock));
3559                 }
3560 #ifdef CONFIG_DRM_ROCKCHIP
3561                 lcdc_dev->driver.irq_call_back(&lcdc_dev->driver);
3562 #endif 
3563                 lcdc_dev->driver.vsync_info.timestamp = timestamp;
3564                 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
3565
3566         }else if(intr0_reg & m_LINE_FLAG_INTR_STS){
3567                 lcdc_dev->driver.frame_time.last_framedone_t =
3568                                 lcdc_dev->driver.frame_time.framedone_t;
3569                 lcdc_dev->driver.frame_time.framedone_t = cpu_clock(0);
3570                 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_LINE_FLAG_INTR_CLR,
3571                              v_LINE_FLAG_INTR_CLR(1));
3572         }else if(intr0_reg & m_BUS_ERROR_INTR_STS){
3573                 lcdc_msk_reg(lcdc_dev, INTR_CTRL0, m_BUS_ERROR_INTR_CLR,
3574                              v_BUS_ERROR_INTR_CLR(1));
3575                 dev_warn(lcdc_dev->dev,"buf_error_int!");
3576         }
3577
3578         /* for win empty debug */
3579 #ifdef LCDC_IRQ_EMPTY_DEBUG
3580         intr1_reg = lcdc_readl(lcdc_dev, INTR_CTRL1);
3581         if (intr1_reg != 0) {
3582                 rk3288_lcdc_parse_irq(lcdc_dev,intr1_reg);
3583         }
3584 #endif
3585         return IRQ_HANDLED;
3586 }
3587
3588 #if defined(CONFIG_PM)
3589 static int rk3288_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
3590 {
3591         return 0;
3592 }
3593
3594 static int rk3288_lcdc_resume(struct platform_device *pdev)
3595 {
3596         return 0;
3597 }
3598 #else
3599 #define rk3288_lcdc_suspend NULL
3600 #define rk3288_lcdc_resume  NULL
3601 #endif
3602
3603 static int rk3288_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
3604 {
3605         struct device_node *np = lcdc_dev->dev->of_node;
3606         struct rk_lcdc_driver *dev_drv = &lcdc_dev->driver;
3607         int val;
3608
3609         if (of_property_read_u32(np, "rockchip,prop", &val))
3610                 lcdc_dev->prop = PRMRY; /*default set it as primary */
3611         else
3612                 lcdc_dev->prop = val;
3613
3614         if (of_property_read_u32(np, "rockchip,mirror", &val))
3615                 dev_drv->rotate_mode = NO_MIRROR;
3616         else
3617                 dev_drv->rotate_mode = val;
3618
3619         if (of_property_read_u32(np, "rockchip,cabc_mode", &val))
3620                 dev_drv->cabc_mode = 0; /* default set close cabc */
3621         else
3622                 dev_drv->cabc_mode = val;
3623
3624         if (of_property_read_u32(np, "rockchip,pwr18", &val))
3625                 lcdc_dev->pwr18 = false;        /*default set it as 3.xv power supply */
3626         else
3627                 lcdc_dev->pwr18 = (val ? true : false);
3628
3629         if (of_property_read_u32(np, "rockchip,fb-win-map", &val))
3630                 dev_drv->fb_win_map = FB_DEFAULT_ORDER;
3631         else
3632                 dev_drv->fb_win_map = val;
3633
3634         if (of_property_read_u32(np, "rockchip,bcsh-en", &val))
3635                 dev_drv->bcsh.enable = false;
3636         else
3637                 dev_drv->bcsh.enable = (val ? true : false);
3638
3639         if (of_property_read_u32(np, "rockchip,brightness", &val))
3640                 dev_drv->bcsh.brightness = 0xffff;
3641         else
3642                 dev_drv->bcsh.brightness = val;
3643
3644         if (of_property_read_u32(np, "rockchip,contrast", &val))
3645                 dev_drv->bcsh.contrast = 0xffff;
3646         else
3647                 dev_drv->bcsh.contrast = val;
3648
3649         if (of_property_read_u32(np, "rockchip,sat-con", &val))
3650                 dev_drv->bcsh.sat_con = 0xffff;
3651         else
3652                 dev_drv->bcsh.sat_con = val;
3653
3654         if (of_property_read_u32(np, "rockchip,hue", &val)) {
3655                 dev_drv->bcsh.sin_hue = 0xffff;
3656                 dev_drv->bcsh.cos_hue = 0xffff;
3657         } else {
3658                 dev_drv->bcsh.sin_hue = val & 0xff;
3659                 dev_drv->bcsh.cos_hue = (val >> 8) & 0xff;
3660         }
3661
3662 #if defined(CONFIG_ROCKCHIP_IOMMU)
3663         if (of_property_read_u32(np, "rockchip,iommu-enabled", &val))
3664                 dev_drv->iommu_enabled = 0;
3665         else
3666                 dev_drv->iommu_enabled = val;
3667 #else
3668         dev_drv->iommu_enabled = 0;
3669 #endif
3670         return 0;
3671 }
3672
3673 static int rk3288_lcdc_probe(struct platform_device *pdev)
3674 {
3675         struct lcdc_device *lcdc_dev = NULL;
3676         struct rk_lcdc_driver *dev_drv;
3677         struct device *dev = &pdev->dev;
3678         struct resource *res;
3679         struct device_node *np = pdev->dev.of_node;
3680         int prop;
3681         int ret = 0;
3682
3683         /*if the primary lcdc has not registered ,the extend
3684            lcdc register later */
3685         of_property_read_u32(np, "rockchip,prop", &prop);
3686         if (prop == EXTEND) {
3687                 if (!is_prmry_rk_lcdc_registered())
3688                         return -EPROBE_DEFER;
3689         }
3690         lcdc_dev = devm_kzalloc(dev,
3691                                 sizeof(struct lcdc_device), GFP_KERNEL);
3692         if (!lcdc_dev) {
3693                 dev_err(&pdev->dev, "rk3288 lcdc device kmalloc fail!");
3694                 return -ENOMEM;
3695         }
3696         platform_set_drvdata(pdev, lcdc_dev);
3697         lcdc_dev->dev = dev;
3698         rk3288_lcdc_parse_dt(lcdc_dev);
3699         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3700         lcdc_dev->reg_phy_base = res->start;
3701         lcdc_dev->len = resource_size(res);
3702         lcdc_dev->regs = devm_ioremap_resource(dev, res);
3703         if (IS_ERR(lcdc_dev->regs))
3704                 return PTR_ERR(lcdc_dev->regs);
3705
3706         lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
3707         if (IS_ERR(lcdc_dev->regsbak))
3708                 return PTR_ERR(lcdc_dev->regsbak);
3709         lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + GAMMA_LUT_ADDR);
3710         lcdc_dev->id = rk3288_lcdc_get_id(lcdc_dev->reg_phy_base);
3711         if (lcdc_dev->id < 0) {
3712                 dev_err(&pdev->dev, "no such lcdc device!\n");
3713                 return -ENXIO;
3714         }
3715         dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
3716         dev_drv = &lcdc_dev->driver;
3717         dev_drv->dev = dev;
3718         dev_drv->prop = prop;
3719         dev_drv->id = lcdc_dev->id;
3720         dev_drv->ops = &lcdc_drv_ops;
3721         dev_drv->lcdc_win_num = ARRAY_SIZE(lcdc_win);
3722         spin_lock_init(&lcdc_dev->reg_lock);
3723
3724         lcdc_dev->irq = platform_get_irq(pdev, 0);
3725         if (lcdc_dev->irq < 0) {
3726                 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
3727                         lcdc_dev->id);
3728                 return -ENXIO;
3729         }
3730
3731         ret = devm_request_irq(dev, lcdc_dev->irq, rk3288_lcdc_isr,
3732                                IRQF_DISABLED | IRQF_SHARED, dev_name(dev), lcdc_dev);
3733         if (ret) {
3734                 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
3735                         lcdc_dev->irq, ret);
3736                 return ret;
3737         }
3738
3739         if (dev_drv->iommu_enabled) {
3740                 if(lcdc_dev->id == 0){
3741                         strcpy(dev_drv->mmu_dts_name, VOPB_IOMMU_COMPATIBLE_NAME);
3742                 }else{
3743                         strcpy(dev_drv->mmu_dts_name, VOPL_IOMMU_COMPATIBLE_NAME);
3744                 }
3745         }
3746
3747         ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
3748         if (ret < 0) {
3749                 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
3750                 return ret;
3751         }
3752         lcdc_dev->screen = dev_drv->screen0;
3753         dev_info(dev, "lcdc%d probe ok, iommu %s\n",
3754                 lcdc_dev->id, dev_drv->iommu_enabled ? "enabled" : "disabled");
3755
3756         return 0;
3757 }
3758
3759 static int rk3288_lcdc_remove(struct platform_device *pdev)
3760 {
3761
3762         return 0;
3763 }
3764
3765 static void rk3288_lcdc_shutdown(struct platform_device *pdev)
3766 {
3767         struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
3768
3769         rk3288_lcdc_deint(lcdc_dev);
3770         rk_disp_pwr_disable(&lcdc_dev->driver);
3771 }
3772
3773 #if defined(CONFIG_OF)
3774 static const struct of_device_id rk3288_lcdc_dt_ids[] = {
3775         {.compatible = "rockchip,rk3288-lcdc",},
3776         {}
3777 };
3778 #endif
3779
3780 static struct platform_driver rk3288_lcdc_driver = {
3781         .probe = rk3288_lcdc_probe,
3782         .remove = rk3288_lcdc_remove,
3783         .driver = {
3784                    .name = "rk3288-lcdc",
3785                    .owner = THIS_MODULE,
3786                    .of_match_table = of_match_ptr(rk3288_lcdc_dt_ids),
3787                    },
3788         .suspend = rk3288_lcdc_suspend,
3789         .resume = rk3288_lcdc_resume,
3790         .shutdown = rk3288_lcdc_shutdown,
3791 };
3792
3793 static int __init rk3288_lcdc_module_init(void)
3794 {
3795         return platform_driver_register(&rk3288_lcdc_driver);
3796 }
3797
3798 static void __exit rk3288_lcdc_module_exit(void)
3799 {
3800         platform_driver_unregister(&rk3288_lcdc_driver);
3801 }
3802
3803 fs_initcall(rk3288_lcdc_module_init);
3804 module_exit(rk3288_lcdc_module_exit);
3805
3806