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