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