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