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