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