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