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