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