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