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