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