Merge tag 'v3.10.92'
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / lcdc / rk3066b_lcdc.c
1 /*
2  * drivers/video/rockchip/chips/rk3066b_lcdc.c
3  *
4  * Copyright (C) 2012 ROCKCHIP, Inc.
5  *Author:yzq<yzq@rock-chips.com>
6  *      yxj<yxj@rock-chips.com>
7  *This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/string.h>
22 #include <linux/mm.h>
23 #include <linux/slab.h>
24 #include <linux/device.h>
25 #include <linux/delay.h>
26 #include <linux/init.h>
27 #include <linux/interrupt.h>
28 #include <linux/platform_device.h>
29 #include <linux/clk.h>
30 #include <linux/earlysuspend.h>
31 #include <asm/div64.h>
32 #include <asm/uaccess.h>
33 #include <mach/iomux.h>
34
35 #include "rk3066b_lcdc.h"
36 #include "../hdmi/rk_hdmi.h"
37
38
39
40
41 static int dbg_thresd = 0;
42 module_param(dbg_thresd, int, S_IRUGO|S_IWUSR);
43 #define DBG(level,x...) do { if(unlikely(dbg_thresd >= level)) printk(KERN_INFO x); } while (0)
44
45
46 static int  rk3066b_lcdc_clk_enable(struct rk3066b_lcdc_device *lcdc_dev)
47 {
48         if(!lcdc_dev->clk_on)
49         {
50                 clk_enable(lcdc_dev->hclk);
51                 clk_enable(lcdc_dev->dclk);
52                 clk_enable(lcdc_dev->aclk);
53                 clk_enable(lcdc_dev->pd);
54
55                 spin_lock(&lcdc_dev->reg_lock);
56                 lcdc_dev->clk_on = 1;
57                 spin_unlock(&lcdc_dev->reg_lock);
58         }
59         printk("rk3066b lcdc%d clk enable...\n",lcdc_dev->id);
60         
61         return 0;
62 }
63
64 static int rk3066b_lcdc_clk_disable(struct rk3066b_lcdc_device *lcdc_dev)
65 {
66         if(lcdc_dev->clk_on)
67         {
68                 spin_lock(&lcdc_dev->reg_lock);
69                 lcdc_dev->clk_on = 0;
70                 spin_unlock(&lcdc_dev->reg_lock);
71                 mdelay(25);
72                 clk_disable(lcdc_dev->dclk);
73                 clk_disable(lcdc_dev->hclk);
74                 clk_disable(lcdc_dev->aclk);
75                 clk_disable(lcdc_dev->pd);
76         }
77         printk("rk3066b lcdc%d clk disable...\n",lcdc_dev->id);
78         
79         return 0;
80 }
81
82 static int rk3066b_lcdc_reg_resume(struct rk3066b_lcdc_device *lcdc_dev)
83 {
84         memcpy((u8*)lcdc_dev->preg, (u8*)&lcdc_dev->regbak, 0x9C);
85         return 0;       
86 }
87
88 static int init_rk3066b_lcdc(struct rk_lcdc_device_driver *dev_drv)
89 {
90         int i=0;
91         int __iomem *c;
92         int v;
93
94         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
95         
96         if(lcdc_dev->id == 0) //lcdc0
97         {
98                 lcdc_dev->pd = clk_get(NULL,"pd_lcdc0");
99                 lcdc_dev->hclk = clk_get(NULL,"hclk_lcdc0"); 
100                 lcdc_dev->aclk = clk_get(NULL,"aclk_lcdc0");
101                 lcdc_dev->dclk = clk_get(NULL,"dclk_lcdc0");
102         }
103         else if(lcdc_dev->id == 1)
104         {
105                 lcdc_dev->pd = clk_get(NULL,"pd_lcdc1");
106                 lcdc_dev->hclk = clk_get(NULL,"hclk_lcdc1");  
107                 lcdc_dev->aclk = clk_get(NULL,"aclk_lcdc1");
108                 lcdc_dev->dclk = clk_get(NULL,"dclk_lcdc1");
109         }
110         else
111         {
112                 printk(KERN_ERR "invalid lcdc device!\n");
113                 return -EINVAL;
114         }
115         if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||(IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk)))
116         {
117                 printk(KERN_ERR "failed to get lcdc%d clk source\n",lcdc_dev->id);
118         }
119
120         rk3066b_lcdc_clk_enable(lcdc_dev);
121         
122         if(lcdc_dev->id == 0)
123         {
124                 #if defined(CONFIG_RK3066B_LCDC0_IO_18V)
125                 v = 0x40004000;               //bit14: 1,1.8v;0,3.3v
126                 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
127                 #else
128                 v = 0x40000000;              
129                 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
130                 #endif
131         }
132
133         if(lcdc_dev->id == 1) //iomux for lcdc1
134         {
135                 #if defined(CONFIG_RK3066B_LCDC1_IO_18V)
136                 v = 0x80008000;               //bit14: 1,1.8v;0,3.3v
137                 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
138                 #else
139                 v = 0x80000000;
140                 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
141                 #endif
142                 
143                 iomux_set(LCDC1_DCLK);
144                 iomux_set(LCDC1_DEN);
145                 iomux_set(LCDC1_HSYNC);
146                 iomux_set(LCDC1_VSYNC);
147                 iomux_set(LCDC1_D0);
148                 iomux_set(LCDC1_D1);
149                 iomux_set(LCDC1_D2);
150                 iomux_set(LCDC1_D3);
151                 iomux_set(LCDC1_D4);
152                 iomux_set(LCDC1_D5);
153                 iomux_set(LCDC1_D6);
154                 iomux_set(LCDC1_D7);
155                 iomux_set(LCDC1_D8);
156                 iomux_set(LCDC1_D9);
157                 iomux_set(LCDC1_D10);
158                 iomux_set(LCDC1_D11);
159                 iomux_set(LCDC1_D12);
160                 iomux_set(LCDC1_D13);
161                 iomux_set(LCDC1_D14);
162                 iomux_set(LCDC1_D15);
163                 iomux_set(LCDC1_D16);
164                 iomux_set(LCDC1_D17);
165                 iomux_set(LCDC1_D18);
166                 iomux_set(LCDC1_D19);
167                 iomux_set(LCDC1_D20);
168                 iomux_set(LCDC1_D21);
169                 iomux_set(LCDC1_D22);
170                 iomux_set(LCDC1_D23);
171                 
172         }
173         LcdMskReg(lcdc_dev,SYS_CFG, m_LCDC_AXICLK_AUTO_ENABLE | m_W0_AXI_OUTSTANDING2 |
174                 m_W1_AXI_OUTSTANDING2,v_LCDC_AXICLK_AUTO_ENABLE(1) | v_W0_AXI_OUTSTANDING2(1) |
175                 v_W1_AXI_OUTSTANDING2(1));//eanble axi-clk auto gating for low power
176          LcdWrReg(lcdc_dev,AXI_MS_ID,v_HWC_CHANNEL_ID(5) | v_WIN2_CHANNEL_ID(4) |
177                 v_WIN1_YRGB_CHANNEL_ID(3) | v_WIN0_CBR_CHANNEL_ID(2) | 
178                 v_WIN0_YRGB_CHANNEL_ID(1));
179         LcdMskReg(lcdc_dev, INT_STATUS,m_HOR_STARTMASK| m_FRM_STARTMASK | 
180               m_SCANNING_MASK, v_HOR_STARTMASK(1) | v_FRM_STARTMASK(1) | 
181               v_SCANNING_MASK(1));  //mask all interrupt in init
182         LcdMskReg(lcdc_dev,FIFO_WATER_MARK,m_WIN1_FIFO_FULL_LEVEL,v_WIN1_FIFO_FULL_LEVEL(0x1e0));
183         //LCDC_REG_CFG_DONE();  // write any value to  REG_CFG_DONE let config become effective
184         if(dev_drv->cur_screen->dsp_lut)                        //resume dsp lut
185         {
186                 LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
187                 LCDC_REG_CFG_DONE();
188
189                 mdelay(25); //wait for dsp lut disabled
190                 for(i=0;i<256;i++)
191                 {
192                         v = dev_drv->cur_screen->dsp_lut[i];
193                         c = lcdc_dev->dsp_lut_addr_base+i;
194                         writel_relaxed(v,c);
195                 }
196                 LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));//enable dsp lut
197         }
198
199         rk3066b_lcdc_clk_disable(lcdc_dev);
200         return 0;
201 }
202
203 static int rk3066b_lcdc_deinit(struct rk3066b_lcdc_device *lcdc_dev)
204 {
205         spin_lock(&lcdc_dev->reg_lock);
206         if(likely(lcdc_dev->clk_on))
207         {
208                 lcdc_dev->clk_on = 0;
209                 LcdMskReg(lcdc_dev, INT_STATUS, m_FRM_STARTCLEAR, v_FRM_STARTCLEAR(1));
210                 LcdMskReg(lcdc_dev, INT_STATUS,m_HOR_STARTMASK| m_FRM_STARTMASK | 
211                           m_SCANNING_MASK, v_HOR_STARTMASK(1) | v_FRM_STARTMASK(1) | 
212                           v_SCANNING_MASK(1));  //mask all interrupt in init
213                 LcdSetBit(lcdc_dev,SYS_CFG,m_LCDC_STANDBY);
214                 LCDC_REG_CFG_DONE();
215                 spin_unlock(&lcdc_dev->reg_lock);
216         }
217         else   //clk already disabled 
218         {
219                 spin_unlock(&lcdc_dev->reg_lock);
220                 return 0;
221         }
222         mdelay(1);
223         
224         return 0;
225 }
226
227 static int rk3066b_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initscreen)
228 {
229         int ret = -EINVAL;
230         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
231         rk_screen *screen = dev_drv->cur_screen;
232         u64 ft;
233         int fps;
234         u16 face;
235         u16 mcu_total, mcu_rwstart, mcu_csstart, mcu_rwend, mcu_csend;
236         u16 right_margin = screen->right_margin;
237         u16 lower_margin = screen->lower_margin;
238         u16 x_res = screen->x_res, y_res = screen->y_res;
239
240         // set the rgb or mcu
241         spin_lock(&lcdc_dev->reg_lock);
242         if(likely(lcdc_dev->clk_on))
243         {
244                 if(screen->type==SCREEN_MCU)
245                 {
246                         LcdMskReg(lcdc_dev, MCU_CTRL, m_MCU_OUTPUT_SELECT,v_MCU_OUTPUT_SELECT(1));
247                         // set out format and mcu timing
248                         mcu_total  = (screen->mcu_wrperiod*150*1000)/1000000;
249                         if(mcu_total>31)    
250                                 mcu_total = 31;
251                         if(mcu_total<3)    
252                                 mcu_total = 3;
253                         mcu_rwstart = (mcu_total+1)/4 - 1;
254                         mcu_rwend = ((mcu_total+1)*3)/4 - 1;
255                         mcu_csstart = (mcu_rwstart>2) ? (mcu_rwstart-3) : (0);
256                         mcu_csend = (mcu_rwend>15) ? (mcu_rwend-1) : (mcu_rwend);
257
258                         //DBG(1,">> mcu_total=%d, mcu_rwstart=%d, mcu_csstart=%d, mcu_rwend=%d, mcu_csend=%d \n",
259                         //      mcu_total, mcu_rwstart, mcu_csstart, mcu_rwend, mcu_csend);
260
261                         // set horizontal & vertical out timing
262                 
263                         right_margin = x_res/6; 
264                         screen->pixclock = 150000000; //mcu fix to 150 MHz
265                         LcdMskReg(lcdc_dev, MCU_CTRL,m_MCU_CS_ST | m_MCU_CS_END| m_MCU_RW_ST | m_MCU_RW_END |
266                                 m_MCU_WRITE_PERIOD | m_MCU_HOLDMODE_SELECT | m_MCU_HOLDMODE_FRAME_ST,
267                                 v_MCU_CS_ST(mcu_csstart) | v_MCU_CS_END(mcu_csend) | v_MCU_RW_ST(mcu_rwstart) |
268                                 v_MCU_RW_END(mcu_rwend) |  v_MCU_WRITE_PERIOD(mcu_total) |
269                                 v_MCU_HOLDMODE_SELECT((SCREEN_MCU==screen->type)?(1):(0)) | v_MCU_HOLDMODE_FRAME_ST(0));
270         
271                 }
272
273                 switch (screen->face)
274                 {
275                         case OUT_P565:
276                                 face = OUT_P565;
277                                 LcdMskReg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0));
278                                 break;
279                         case OUT_P666:
280                                 face = OUT_P666;
281                                 LcdMskReg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1));
282                                 break;
283                         case OUT_D888_P565:
284                                 face = OUT_P888;
285                                 LcdMskReg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0));
286                                 break;
287                         case OUT_D888_P666:
288                                 face = OUT_P888;
289                                 LcdMskReg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1));
290                                 break;
291                         case OUT_P888:
292                                 face = OUT_P888;
293                                 LcdMskReg(lcdc_dev, DSP_CTRL0, m_DITHER_UP_EN, v_DITHER_UP_EN(1));
294                                 LcdMskReg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(0) | v_DITHER_DOWN_MODE(0));
295                                 break;
296                         default:
297                                 LcdMskReg(lcdc_dev, DSP_CTRL0, m_DITHER_UP_EN, v_DITHER_UP_EN(0));
298                                 LcdMskReg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(0) | v_DITHER_DOWN_MODE(0));
299                                 face = screen->face;
300                                 break;
301                 }
302
303                 //use default overlay,set vsyn hsync den dclk polarity
304                 LcdMskReg(lcdc_dev, DSP_CTRL0,m_DISPLAY_FORMAT | m_HSYNC_POLARITY | m_VSYNC_POLARITY |
305                         m_DEN_POLARITY |m_DCLK_POLARITY,v_DISPLAY_FORMAT(face) | 
306                         v_HSYNC_POLARITY(screen->pin_hsync) | v_VSYNC_POLARITY(screen->pin_vsync) |
307                         v_DEN_POLARITY(screen->pin_den) | v_DCLK_POLARITY(screen->pin_dclk));
308
309                 //set background color to black,set swap according to the screen panel,disable blank mode
310                 LcdMskReg(lcdc_dev,DSP_CTRL1,m_BLANK_MODE | m_BLACK_MODE | m_BG_COLOR, v_BLANK_MODE(0) | 
311                                         v_BLACK_MODE(0) | v_BG_COLOR(0x000000));
312                 LcdMskReg(lcdc_dev,SWAP_CTRL,m_OUTPUT_RB_SWAP | m_OUTPUT_RG_SWAP | m_DELTA_SWAP | m_DUMMY_SWAP, 
313                                         v_OUTPUT_RB_SWAP(screen->swap_rb) | v_OUTPUT_RG_SWAP(screen->swap_rg) | 
314                                         v_DELTA_SWAP(screen->swap_delta) | v_DUMMY_SWAP(screen->swap_dumy));
315                 LcdWrReg(lcdc_dev, DSP_HTOTAL_HS_END,v_HSYNC(screen->hsync_len) |
316                      v_HORPRD(screen->hsync_len + screen->left_margin + x_res + right_margin));
317                 LcdWrReg(lcdc_dev, DSP_HACT_ST_END, v_HAEP(screen->hsync_len + screen->left_margin + x_res) |
318                      v_HASP(screen->hsync_len + screen->left_margin));
319
320                 LcdWrReg(lcdc_dev, DSP_VTOTAL_VS_END, v_VSYNC(screen->vsync_len) |
321                       v_VERPRD(screen->vsync_len + screen->upper_margin + y_res + lower_margin));
322                 LcdWrReg(lcdc_dev, DSP_VACT_ST_END,  v_VAEP(screen->vsync_len + screen->upper_margin+y_res)|
323                       v_VASP(screen->vsync_len + screen->upper_margin));
324                 // let above to take effect
325                 //LCDC_REG_CFG_DONE();
326         }
327         spin_unlock(&lcdc_dev->reg_lock);
328
329         ret = clk_set_rate(lcdc_dev->dclk, screen->pixclock);
330         if(ret)
331         {
332                 printk(KERN_ERR ">>>>>> set lcdc%d dclk failed\n",lcdc_dev->id);
333         }
334         lcdc_dev->driver.pixclock = lcdc_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
335         
336         
337         ft = (u64)(screen->upper_margin + screen->lower_margin + screen->y_res +screen->vsync_len)*
338                 (screen->left_margin + screen->right_margin + screen->x_res + screen->hsync_len)*
339                 (dev_drv->pixclock);       // one frame time ,(pico seconds)
340         fps = div64_u64(1000000000000llu,ft);
341         screen->ft = 1000/fps;
342         printk("%s: dclk:%lu>>fps:%d ",lcdc_dev->driver.name,clk_get_rate(lcdc_dev->dclk),fps);
343
344         if(screen->init)
345         {
346                 screen->init();
347         }
348         printk("%s for lcdc%d ok!\n",__func__,lcdc_dev->id);
349         return 0;
350 }
351
352 static int mcu_refresh(struct rk3066b_lcdc_device *lcdc_dev)
353 {
354    
355     return 0;
356 }
357
358
359
360 //enable layer,open:1,enable;0 disable
361 static int win0_open(struct rk3066b_lcdc_device *lcdc_dev,bool open)
362 {
363         
364         spin_lock(&lcdc_dev->reg_lock);
365         if(likely(lcdc_dev->clk_on))
366         {
367                 if(open)
368                 {
369                         if(!lcdc_dev->atv_layer_cnt)
370                         {
371                                 LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
372                         }
373                         lcdc_dev->atv_layer_cnt++;
374                 }
375                 else
376                 {
377                         lcdc_dev->atv_layer_cnt--;
378                 }
379                 lcdc_dev->driver.layer_par[0]->state = open;
380                 
381                 LcdMskReg(lcdc_dev, SYS_CFG, m_W0_EN, v_W0_EN(open));
382                 if(!lcdc_dev->atv_layer_cnt)  //if no layer used,disable lcdc
383                 {
384                         LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
385                 }
386                 //LCDC_REG_CFG_DONE();  
387         }
388         spin_unlock(&lcdc_dev->reg_lock);
389         printk(KERN_INFO "lcdc%d win0 %s\n",lcdc_dev->id,open?"open":"closed");
390         return 0;
391 }
392 static int win1_open(struct rk3066b_lcdc_device *lcdc_dev,bool open)
393 {
394         spin_lock(&lcdc_dev->reg_lock);
395         if(likely(lcdc_dev->clk_on))
396         {
397                 if(open)
398                 {
399                         if(!lcdc_dev->atv_layer_cnt)
400                         {
401                                 printk("lcdc%d wakeup from stanby\n",lcdc_dev->id);
402                                 LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
403                         }
404                         lcdc_dev->atv_layer_cnt++;
405                 }
406                 else
407                 {
408                         lcdc_dev->atv_layer_cnt--;
409                 }
410                 lcdc_dev->driver.layer_par[1]->state = open;
411                 
412                 LcdMskReg(lcdc_dev, SYS_CFG, m_W1_EN, v_W1_EN(open));
413                 if(!lcdc_dev->atv_layer_cnt)  //if no layer used,disable lcdc
414                 {
415                         printk(KERN_INFO "no layer of lcdc%d is used,go to standby!",lcdc_dev->id);
416                         LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
417                 }
418                 LCDC_REG_CFG_DONE();
419         }
420         spin_unlock(&lcdc_dev->reg_lock);
421         printk(KERN_INFO "lcdc%d win1 %s\n",lcdc_dev->id,open?"open":"closed");
422         return 0;
423 }
424
425
426 static int rk3066b_lcdc_blank(struct rk_lcdc_device_driver*lcdc_drv,int layer_id,int blank_mode)
427 {
428         struct rk3066b_lcdc_device * lcdc_dev = container_of(lcdc_drv,struct rk3066b_lcdc_device ,driver);
429
430         spin_lock(&lcdc_dev->reg_lock);
431         if(likely(lcdc_dev->clk_on))
432         {
433                 switch(blank_mode)
434                 {
435                         case FB_BLANK_UNBLANK:
436                                 LcdMskReg(lcdc_dev,DSP_CTRL1,m_BLANK_MODE ,v_BLANK_MODE(0));
437                                 break;
438                         case FB_BLANK_NORMAL:
439                                 LcdMskReg(lcdc_dev,DSP_CTRL1,m_BLANK_MODE ,v_BLANK_MODE(1));
440                                 break;
441                         default:
442                                 LcdMskReg(lcdc_dev,DSP_CTRL1,m_BLANK_MODE ,v_BLANK_MODE(1));
443                                 break;
444                 }
445                 LCDC_REG_CFG_DONE();
446         }
447         spin_unlock(&lcdc_dev->reg_lock);
448
449         dev_info(lcdc_drv->dev,"blank mode:%d\n",blank_mode);
450         
451         return 0;
452 }
453
454 static  int win0_display(struct rk3066b_lcdc_device *lcdc_dev,struct layer_par *par )
455 {
456         u32 y_addr;
457         u32 uv_addr;
458         y_addr = par->smem_start + par->y_offset;
459         uv_addr = par->cbr_start + par->c_offset;
460         DBG(2,KERN_INFO "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);
461
462         spin_lock(&lcdc_dev->reg_lock);
463         if(likely(lcdc_dev->clk_on))
464         {
465                 LcdWrReg(lcdc_dev, WIN0_YRGB_MST,y_addr);
466                 LcdWrReg(lcdc_dev, WIN0_CBR_MST,uv_addr);
467                 LCDC_REG_CFG_DONE();
468         }
469         spin_unlock(&lcdc_dev->reg_lock);
470
471         return 0;
472         
473 }
474
475 static  int win1_display(struct rk3066b_lcdc_device *lcdc_dev,struct layer_par *par )
476 {
477         u32 y_addr;
478         u32 uv_addr;
479         y_addr = par->smem_start + par->y_offset;
480         uv_addr = par->cbr_start + par->c_offset;
481         DBG(2,KERN_INFO "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);
482         
483         spin_lock(&lcdc_dev->reg_lock);
484         if(likely(lcdc_dev->clk_on))
485         {
486                 LcdWrReg(lcdc_dev, WIN1_YRGB_MST, y_addr);
487                 LCDC_REG_CFG_DONE();
488         }
489         spin_unlock(&lcdc_dev->reg_lock);
490         
491         return 0;
492 }
493
494 static  int win0_set_par(struct rk3066b_lcdc_device *lcdc_dev,rk_screen *screen,
495         struct layer_par *par )
496 {
497         u32 xact, yact, xvir, yvir, xpos, ypos;
498         u32 ScaleYrgbX = 0x1000;
499         u32 ScaleYrgbY = 0x1000;
500         u32 ScaleCbrX = 0x1000;
501         u32 ScaleCbrY = 0x1000;
502         u8 fmt_cfg =0 ; //data format register config value
503         char fmt[9] = "NULL";
504         xact = par->xact;                           //active (origin) picture window width/height               
505         yact = par->yact;
506         xvir = par->xvir;                          // virtual resolution                
507         yvir = par->yvir;
508         xpos = par->xpos+screen->left_margin + screen->hsync_len;
509         ypos = par->ypos+screen->upper_margin + screen->vsync_len;
510    
511         DBG(1,"%s for lcdc%d>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
512                 __func__,lcdc_dev->id,get_format_string(par->format,fmt),xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
513         
514         ScaleYrgbX = CalScale(xact, par->xsize); //both RGB and yuv need this two factor
515         ScaleYrgbY = CalScale(yact, par->ysize);
516         switch (par->format)
517         {
518                 case XBGR888:
519                 case ABGR888:
520                 case ARGB888:
521                         fmt_cfg = 0;
522                         break;
523                 case RGB565:
524                         fmt_cfg = 1;
525                         break;
526                 case YUV422:// yuv422
527                         fmt_cfg = 2;
528                         ScaleCbrX = CalScale((xact/2), par->xsize);
529                         ScaleCbrY = CalScale(yact, par->ysize);
530                         break;
531                 case YUV420: // yuv420
532                         fmt_cfg = 3;
533                         ScaleCbrX = CalScale(xact/2, par->xsize);
534                         ScaleCbrY = CalScale(yact/2, par->ysize);
535                         break;
536                 case YUV444:// yuv444
537                         fmt_cfg = 4;
538                         ScaleCbrX = CalScale(xact, par->xsize);
539                         ScaleCbrY = CalScale(yact, par->ysize);
540                         break;
541                 default:
542                         printk("%s:un supported format\n",__func__);
543                    break;
544         }
545
546         
547         spin_lock(&lcdc_dev->reg_lock);
548         if(likely(lcdc_dev->clk_on))
549         {
550                 LcdWrReg(lcdc_dev, WIN0_SCL_FACTOR_YRGB, v_X_SCL_FACTOR(ScaleYrgbX) | v_Y_SCL_FACTOR(ScaleYrgbY));
551                 LcdWrReg(lcdc_dev, WIN0_SCL_FACTOR_CBR,v_X_SCL_FACTOR(ScaleCbrX)| v_Y_SCL_FACTOR(ScaleCbrY));
552                 LcdMskReg(lcdc_dev,SYS_CFG, m_W0_FORMAT, v_W0_FORMAT(fmt_cfg));         //(inf->video_mode==0)
553                 LcdWrReg(lcdc_dev, WIN0_ACT_INFO,v_ACT_WIDTH(xact) | v_ACT_HEIGHT(yact));
554                 LcdWrReg(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(xpos) | v_DSP_STY(ypos));
555                 LcdWrReg(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(par->xsize)| v_DSP_HEIGHT(par->ysize));
556                 LcdMskReg(lcdc_dev, WIN0_COLOR_KEY_CTRL, m_COLORKEY_EN | m_KEYCOLOR,
557                         v_COLORKEY_EN(0) | v_KEYCOLOR(0));
558                 LcdWrReg(lcdc_dev,WIN0_VIR,v_VIRWIDTH(xvir));
559                 //LCDC_REG_CFG_DONE();
560         }
561         spin_unlock(&lcdc_dev->reg_lock);
562
563     return 0;
564
565 }
566
567 static int win1_set_par(struct rk3066b_lcdc_device *lcdc_dev,rk_screen *screen,
568         struct layer_par *par )
569 {
570         u32 xact, yact, xvir, yvir, xpos, ypos;
571         u8 fmt_cfg;
572         char fmt[9]="NULL";
573         xact = par->xact;                       
574         yact = par->yact;
575         xvir = par->xvir;               
576         yvir = par->yvir;
577         xpos = par->xpos+screen->left_margin + screen->hsync_len;
578         ypos = par->ypos+screen->upper_margin + screen->vsync_len;
579         
580         
581         DBG(1,"%s for lcdc%d>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
582                 __func__,lcdc_dev->id,get_format_string(par->format,fmt),xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
583
584         
585         spin_lock(&lcdc_dev->reg_lock);
586         if(likely(lcdc_dev->clk_on))
587         {
588                 switch (par->format)
589                 {
590                         case XBGR888:
591                         case ABGR888:
592                         case ARGB888:
593                                 fmt_cfg = 0;
594                                 break;
595                         case RGB565:
596                                 fmt_cfg = 1;
597                                 break;
598                         default:
599                                 printk("%s:un supported format\n",__func__);
600                                 break;
601                 }
602
603                 LcdMskReg(lcdc_dev,SYS_CFG, m_W1_FORMAT, v_W1_FORMAT(fmt_cfg));
604                 LcdWrReg(lcdc_dev, WIN1_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
605                 LcdWrReg(lcdc_dev, WIN1_DSP_INFO,v_DSP_WIDTH(par->xsize) | v_DSP_HEIGHT(par->ysize));
606                 // enable win1 color key and set the color to black(rgb=0)
607                 LcdMskReg(lcdc_dev,WIN1_COLOR_KEY_CTRL, m_COLORKEY_EN | m_KEYCOLOR,v_COLORKEY_EN(1) | v_KEYCOLOR(0));
608                 LcdWrReg(lcdc_dev,WIN1_VIR,v_VIRWIDTH(xvir));
609                 
610                 //LCDC_REG_CFG_DONE(); 
611         }
612         spin_unlock(&lcdc_dev->reg_lock);
613     return 0;
614 }
615
616 static int rk3066b_lcdc_open(struct rk_lcdc_device_driver *dev_drv,int layer_id,bool open)
617 {
618         int i=0;
619         int __iomem *c;
620         int v;
621         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
622
623         if((open) && (!lcdc_dev->atv_layer_cnt)) //enable clk,when first layer open
624         {
625                 rk3066b_lcdc_clk_enable(lcdc_dev);
626                 rk3066b_lcdc_reg_resume(lcdc_dev); //resume reg
627                 LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
628                 rk3066b_load_screen(dev_drv,1);
629                 spin_lock(&lcdc_dev->reg_lock);
630                 if(dev_drv->cur_screen->dsp_lut)                        //resume dsp lut
631                 {
632                         LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
633                         LCDC_REG_CFG_DONE();
634
635                         mdelay(25); //wait for dsp lut disabled
636                         for(i=0;i<256;i++)
637                         {
638                                 v = dev_drv->cur_screen->dsp_lut[i];
639                                 c = lcdc_dev->dsp_lut_addr_base+i;
640                                 writel_relaxed(v,c);
641                         }
642                         LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));//enable dsp lut
643                 }
644                 spin_unlock(&lcdc_dev->reg_lock);
645         }
646         if(layer_id == 0)
647         {
648                 win0_open(lcdc_dev,open);       
649         }
650         else if(layer_id == 1)
651         {
652                 win1_open(lcdc_dev,open);
653         }
654         
655         if((!open) && (!lcdc_dev->atv_layer_cnt))  //when all layer closed,disable clk
656         {
657                 LcdMskReg(lcdc_dev, INT_STATUS, m_FRM_STARTCLEAR, v_FRM_STARTCLEAR(1));
658                 LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
659                 LCDC_REG_CFG_DONE();
660                 rk3066b_lcdc_clk_disable(lcdc_dev);
661         }
662         return 0;
663 }
664
665 static int rk3066b_lcdc_set_par(struct rk_lcdc_device_driver *dev_drv,int layer_id)
666 {
667         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
668         struct layer_par *par = NULL;
669         rk_screen *screen = dev_drv->cur_screen;
670         if(!screen)
671         {
672                 printk(KERN_ERR "screen is null!\n");
673                 return -ENOENT;
674         }
675         if(layer_id==0)
676         {
677                 par = dev_drv->layer_par[0];
678                 win0_set_par(lcdc_dev,screen,par);
679         }
680         else if(layer_id==1)
681         {
682                 par = dev_drv->layer_par[1];
683                 win1_set_par(lcdc_dev,screen,par);
684         }
685         
686         return 0;
687 }
688
689 int rk3066b_lcdc_pan_display(struct rk_lcdc_device_driver * dev_drv,int layer_id)
690 {
691         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
692         struct layer_par *par = NULL;
693         rk_screen *screen = dev_drv->cur_screen;
694         unsigned long flags;
695         int timeout;
696         if(!screen)
697         {
698                 printk(KERN_ERR "screen is null!\n");
699                 return -ENOENT; 
700         }
701         if(layer_id==0)
702         {
703                 par = dev_drv->layer_par[0];
704                 win0_display(lcdc_dev,par);
705         }
706         else if(layer_id==1)
707         {
708                 par = dev_drv->layer_par[1];
709                 win1_display(lcdc_dev,par);
710         }
711         if((dev_drv->first_frame))  //this is the first frame of the system ,enable frame start interrupt
712         {
713                 dev_drv->first_frame = 0;
714                 LcdMskReg(lcdc_dev,INT_STATUS,m_HOR_STARTMASK | m_FRM_STARTMASK | m_SCANNING_MASK | 
715                         m_HOR_STARTCLEAR | m_FRM_STARTCLEAR |m_SCANNING_CLEAR | m_SCAN_LINE_NUM,
716                           v_HOR_STARTMASK(1) | v_FRM_STARTMASK(0) | v_SCANNING_MASK(0) |
717                           v_HOR_STARTCLEAR(1) | v_FRM_STARTCLEAR(1) | v_SCANNING_CLEAR(1) |
718                           //v_SCANNING_CLEAR(screen->vsync_len + screen->upper_margin+screen->y_res -1));
719                           v_SCAN_LINE_NUM(screen->vsync_len + screen->upper_margin+screen->y_res -1));
720                 LCDC_REG_CFG_DONE();  // write any value to  REG_CFG_DONE let config become effective
721                  
722         }
723
724 #if 0
725         if(dev_drv->num_buf < 3) //3buffer ,no need to  wait for sysn
726         {
727                 spin_lock_irqsave(&dev_drv->cpl_lock,flags);
728                 init_completion(&dev_drv->frame_done);
729                 spin_unlock_irqrestore(&dev_drv->cpl_lock,flags);
730                 timeout = wait_for_completion_timeout(&dev_drv->frame_done,msecs_to_jiffies(dev_drv->cur_screen->ft+5));
731                 if(!timeout&&(!dev_drv->frame_done.done))
732                 {
733                         printk(KERN_ERR "wait for new frame start time out!\n");
734                         return -ETIMEDOUT;
735                 }
736         }
737 #endif
738         
739         return 0;
740 }
741
742 int rk3066b_lcdc_ioctl(struct rk_lcdc_device_driver * dev_drv,unsigned int cmd, unsigned long arg,int layer_id)
743 {
744         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
745         u32 panel_size[2];
746         void __user *argp = (void __user *)arg;
747         int ret = 0;
748         switch(cmd)
749         {
750                 case RK_FBIOGET_PANEL_SIZE:    //get panel size
751                         panel_size[0] = lcdc_dev->screen->x_res;
752                         panel_size[1] = lcdc_dev->screen->y_res;
753                         if(copy_to_user(argp, panel_size, 8)) 
754                                 return -EFAULT;
755                         break;
756                 default:
757                         break;
758         }
759
760         return ret;
761 }
762 static int rk3066b_lcdc_get_layer_state(struct rk_lcdc_device_driver *dev_drv,int layer_id)
763 {
764         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
765         struct layer_par *par = dev_drv->layer_par[layer_id];
766
767         spin_lock(&lcdc_dev->reg_lock);
768         if(lcdc_dev->clk_on)
769         {
770                 if(layer_id == 0)
771                 {
772                         par->state = LcdReadBit(lcdc_dev,SYS_CFG,m_W0_EN);
773                 }
774                 else if( layer_id == 1)
775                 {
776                         par->state = LcdReadBit(lcdc_dev,SYS_CFG,m_W1_EN);
777                 }
778         }
779         spin_unlock(&lcdc_dev->reg_lock);
780         
781         return par->state;
782         
783 }
784
785 /***********************************
786 overlay manager
787 swap:1 win0 on the top of win1
788         0 win1 on the top of win0
789 set  : 1 set overlay 
790         0 get overlay state
791 ************************************/
792 static int rk3066b_lcdc_ovl_mgr(struct rk_lcdc_device_driver *dev_drv,int swap,bool set)
793 {
794         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
795         int ovl;
796         spin_lock(&lcdc_dev->reg_lock);
797         if(lcdc_dev->clk_on)
798         {
799                 if(set)  //set overlay
800                 {
801                         LcdMskReg(lcdc_dev,DSP_CTRL0,m_W0W1_POSITION_SWAP,v_W0W1_POSITION_SWAP(swap));
802                         LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
803                         LCDC_REG_CFG_DONE();
804                         ovl = swap;
805                 }
806                 else  //get overlay
807                 {
808                         ovl = LcdReadBit(lcdc_dev,DSP_CTRL0,m_W0W1_POSITION_SWAP);
809                 }
810         }
811         else
812         {
813                 ovl = -EPERM;
814         }
815         spin_unlock(&lcdc_dev->reg_lock);
816
817         return ovl;
818 }
819
820 static ssize_t rk3066b_lcdc_get_disp_info(struct rk_lcdc_device_driver *dev_drv,char *buf,int layer_id)
821
822 {
823         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
824         char format_w0[9]= "NULL";
825         char format_w1[9]= "NULL";
826         char status_w0[9]= "NULL";
827         char status_w1[9]= "NULL";
828         u32 fmt_id = LcdRdReg(lcdc_dev,SYS_CFG);
829         u32 act_info,dsp_info,dsp_st,factor;
830         u16 xvir_w0,x_act_w0,y_act_w0,x_dsp_w0,y_dsp_w0,x_st_w0,y_st_w0;
831         u16 xvir_w1,x_dsp_w1,y_dsp_w1,x_st_w1,y_st_w1;
832         u16 x_scale,y_scale;
833         int ovl = LcdReadBit(lcdc_dev,DSP_CTRL0,m_W0W1_POSITION_SWAP);
834
835         switch((fmt_id&m_W0_FORMAT)>>3)
836         {
837                 case 0:
838                         strcpy(format_w0,"ARGB888");
839                         break;
840                 case 1:
841                         strcpy(format_w0,"RGB565");
842                         break;
843                 case 2:
844                         strcpy(format_w0,"YCbCr422");
845                         break;
846                 case 3:
847                         strcpy(format_w0,"YCbCr420");
848                         break;
849                 case 5:
850                         strcpy(format_w0,"YCbCr444");
851                         break;
852                 default:
853                         strcpy(format_w0,"invalid\n");
854                         break;
855         }
856
857          switch((fmt_id&m_W1_FORMAT)>>2)
858         {
859                 case 0:
860                         strcpy(format_w1,"ARGB888");
861                         break;
862                 case 1:
863                         strcpy(format_w1,"RGB565");
864                         break;
865                 default:
866                         strcpy(format_w1,"invalid\n");
867                         break;
868         }
869
870         if((fmt_id&m_W0_EN)>>11)
871         {
872                 strcpy(status_w0,"enabled");
873         }
874         else
875         {
876                 strcpy(status_w0,"disabled");
877         }
878
879         if((fmt_id&m_W1_EN)>>10)
880         {
881                 strcpy(status_w1,"enabled");
882         }
883         else
884         {
885                 strcpy(status_w1,"disabled");
886         }
887
888         xvir_w0 = LcdRdReg(lcdc_dev,WIN0_VIR)&0xffff;
889         act_info = LcdRdReg(lcdc_dev,WIN0_ACT_INFO);
890         dsp_info = LcdRdReg(lcdc_dev,WIN0_DSP_INFO);
891         dsp_st = LcdRdReg(lcdc_dev,WIN0_DSP_ST);
892         factor = LcdRdReg(lcdc_dev,WIN0_SCL_FACTOR_YRGB);
893         x_act_w0 =  (act_info&0xffff);
894         y_act_w0 = (act_info>>16);
895         x_dsp_w0 = (dsp_info&0x7ff);
896         y_dsp_w0 = (dsp_info>>16);
897         x_scale = 4096*100/(factor&0xffff);
898         y_scale = 4096*100/(factor>>16);
899         x_st_w0 = dsp_st&0xffff;
900         y_st_w0 = dsp_st>>16;
901
902         
903         xvir_w1 = LcdRdReg(lcdc_dev,WIN1_VIR)&0xffff;
904         dsp_info = LcdRdReg(lcdc_dev,WIN1_DSP_INFO);
905         dsp_st = LcdRdReg(lcdc_dev,WIN1_DSP_ST);
906         x_dsp_w1 = dsp_info&0x7ff;
907         y_dsp_w1 = dsp_info>>16;
908         x_st_w1 = dsp_st&0xffff;
909         y_st_w1 = dsp_st>>16;
910
911         return snprintf(buf,PAGE_SIZE,
912                 "win0:%s\n"
913                 "xvir:%d\n"
914                 "xact:%d\n"
915                 "yact:%d\n"
916                 "xdsp:%d\n"
917                 "ydsp:%d\n"
918                 "x_st:%d\n"
919                 "y_st:%d\n"
920                 "x_scale:%d.%d\n"
921                 "y_scale:%d.%d\n"
922                 "format:%s\n"
923                 "YRGB buffer addr:0x%08x\n"
924                 "CBR buffer addr:0x%08x\n\n"
925                 "win1:%s\n"
926                 "xvir:%d\n"
927                 "xdsp:%d\n"
928                 "ydsp:%d\n"
929                 "x_st:%d\n"
930                 "y_st:%d\n"
931                 "format:%s\n"
932                 "YRGB buffer addr:0x%08x\n"
933                 "overlay:%s\n",
934                 status_w0,
935                 xvir_w0,
936                 x_act_w0,
937                 y_act_w0,
938                 x_dsp_w0,
939                 y_dsp_w0,
940                 x_st_w0,
941                 y_st_w0,
942                 x_scale/100,
943                 x_scale%100,
944                 y_scale/100,
945                 y_scale%100,
946                 format_w0,
947                 LcdRdReg(lcdc_dev,WIN0_YRGB_MST),
948                 LcdRdReg(lcdc_dev,WIN0_CBR_MST),
949                 status_w1,
950                 xvir_w1,
951                 x_dsp_w1,
952                 y_dsp_w1,
953                 x_st_w1,
954                 y_st_w1,
955                 format_w1,
956                 LcdRdReg(lcdc_dev,WIN1_YRGB_MST),
957                 ovl ? "win0 on the top of win1\n":"win1 on the top of win0\n");
958         return 0;
959 }
960
961
962 /*******************************************
963 lcdc fps manager,set or get lcdc fps
964 set:0 get
965      1 set
966 ********************************************/
967 static int rk3066b_lcdc_fps_mgr(struct rk_lcdc_device_driver *dev_drv,int fps,bool set)
968 {
969         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
970         rk_screen * screen = dev_drv->cur_screen;
971         u64 ft = 0;
972         u32 dotclk;
973         int ret;
974
975         if(set)
976         {
977                 ft = div_u64(1000000000000llu,fps);
978                 dev_drv->pixclock = div_u64(ft,(screen->upper_margin + screen->lower_margin + screen->y_res +screen->vsync_len)*
979                                 (screen->left_margin + screen->right_margin + screen->x_res + screen->hsync_len));
980                 dotclk = div_u64(1000000000000llu,dev_drv->pixclock);
981                 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
982                 if(ret)
983                 {
984                         printk(KERN_ERR ">>>>>> set lcdc%d dclk failed\n",lcdc_dev->id);
985                 }
986                 dev_drv->pixclock = lcdc_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
987                         
988         }
989         
990         ft = (u64)(screen->upper_margin + screen->lower_margin + screen->y_res +screen->vsync_len)*
991         (screen->left_margin + screen->right_margin + screen->x_res + screen->hsync_len)*
992         (dev_drv->pixclock);       // one frame time ,(pico seconds)
993         fps = div64_u64(1000000000000llu,ft);
994         screen->ft = 1000/fps ;  //one frame time in ms
995         return fps;
996 }
997
998 static int rk3066b_fb_layer_remap(struct rk_lcdc_device_driver *dev_drv,
999         enum fb_win_map_order order)
1000 {
1001         mutex_lock(&dev_drv->fb_win_id_mutex);
1002         if(order == FB_DEFAULT_ORDER)
1003         {
1004                 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
1005         }
1006         dev_drv->fb2_win_id  = order/100;
1007         dev_drv->fb1_win_id = (order/10)%10;
1008         dev_drv->fb0_win_id = order%10;
1009         mutex_unlock(&dev_drv->fb_win_id_mutex);
1010
1011         printk("fb0:win%d\nfb1:win%d\nfb2:win%d\n",dev_drv->fb0_win_id,dev_drv->fb1_win_id,
1012                 dev_drv->fb2_win_id);
1013
1014         return 0;
1015 }
1016
1017 static int rk3066b_fb_get_layer(struct rk_lcdc_device_driver *dev_drv,const char *id)
1018 {
1019         int layer_id = 0;
1020         mutex_lock(&dev_drv->fb_win_id_mutex);
1021         if(!strcmp(id,"fb0") || !strcmp(id,"fb2"))
1022         {
1023                 layer_id = dev_drv->fb0_win_id;
1024         }
1025         else if(!strcmp(id,"fb1") || !strcmp(id,"fb3"))
1026         {
1027                 layer_id = dev_drv->fb1_win_id;
1028         }
1029         else
1030         {
1031                 printk(KERN_ERR "%s>>un supported %s\n",__func__,id);
1032                 layer_id = -1;
1033         }
1034         mutex_unlock(&dev_drv->fb_win_id_mutex);
1035         
1036         return  layer_id;
1037 }
1038
1039
1040 static void rk3066b_lcdc_reg_dump(struct rk3066b_lcdc_device *lcdc_dev)
1041 {
1042         int *cbase =  (int *)lcdc_dev->reg_vir_base;
1043         int i,j;
1044         
1045         for(i=0; i<=(0xa0>>4);i++)
1046         {
1047                 for(j=0;j<4;j++)
1048                         printk("%08x  ",readl(cbase+i*4 +j));
1049                 printk("\n");
1050         }
1051         
1052 }
1053
1054 int rk3066b_lcdc_early_suspend(struct rk_lcdc_device_driver *dev_drv)
1055 {
1056         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
1057
1058         if(dev_drv->screen0->standby)
1059                 dev_drv->screen0->standby(1);
1060         if(dev_drv->screen_ctr_info->io_disable)
1061                 dev_drv->screen_ctr_info->io_disable();
1062         
1063         spin_lock(&lcdc_dev->reg_lock);
1064         if(likely(lcdc_dev->clk_on))
1065         {
1066                 lcdc_dev->clk_on = 0;
1067                 LcdMskReg(lcdc_dev, INT_STATUS, m_FRM_STARTCLEAR, v_FRM_STARTCLEAR(1));
1068                 LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
1069                 LCDC_REG_CFG_DONE();
1070                 spin_unlock(&lcdc_dev->reg_lock);
1071         }
1072         else  //clk already disabled
1073         {
1074                 spin_unlock(&lcdc_dev->reg_lock);
1075                 return 0;
1076         }
1077         
1078         rk3066b_lcdc_clk_disable(lcdc_dev);
1079
1080         return 0;
1081 }
1082
1083
1084 int rk3066b_lcdc_early_resume(struct rk_lcdc_device_driver *dev_drv)
1085 {  
1086         struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
1087         int i=0;
1088         int __iomem *c;
1089         int v;
1090
1091         if(dev_drv->screen_ctr_info->io_enable)                 //power on
1092                 dev_drv->screen_ctr_info->io_enable();
1093         
1094         if(lcdc_dev->atv_layer_cnt) //only resume the lcdc that need to use
1095         {
1096         
1097                 rk3066b_lcdc_clk_enable(lcdc_dev);
1098                 mdelay(5);
1099                 memcpy((u8*)lcdc_dev->preg, (u8*)&lcdc_dev->regbak, 0x24);  //resume reg ,skip INT_STATUS reg
1100                 memcpy(((u8*)lcdc_dev->preg) + 0x28,((u8*)&lcdc_dev->regbak) + 0x28, 0x74);
1101
1102                 spin_lock(&lcdc_dev->reg_lock);
1103
1104                 if(dev_drv->cur_screen->dsp_lut)                        //resume dsp lut
1105                 {
1106                         LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
1107                         LCDC_REG_CFG_DONE();
1108
1109                         mdelay(25); //wait for dsp lut disabled
1110                         for(i=0;i<256;i++)
1111                         {
1112                                 v = dev_drv->cur_screen->dsp_lut[i];
1113                                 c = lcdc_dev->dsp_lut_addr_base+i;
1114                                 writel_relaxed(v,c);
1115                         }
1116                         LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));//enable dsp lut
1117                 }
1118                 LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
1119                 LcdMskReg(lcdc_dev, INT_STATUS, m_SCANNING_CLEAR | m_FRM_STARTCLEAR | m_HOR_STARTCLEAR |
1120                                         m_SCANNING_MASK | m_HOR_STARTMASK | m_FRM_STARTMASK , 
1121                                         v_SCANNING_CLEAR(1) | v_FRM_STARTCLEAR(1) | v_HOR_STARTCLEAR(1) | 
1122                                         v_SCANNING_MASK(0) | v_FRM_STARTMASK(0) | v_HOR_STARTMASK(1));
1123                 LCDC_REG_CFG_DONE();
1124                 
1125                 spin_unlock(&lcdc_dev->reg_lock);
1126
1127         }
1128         
1129         if(dev_drv->screen0->standby)
1130                 dev_drv->screen0->standby(0);         //screen wake up
1131         
1132         return 0;
1133 }
1134
1135 static int no_report(struct rk3066b_lcdc_device *lcdc_dev)
1136 {
1137         struct rk_lcdc_device_driver *dev = &(lcdc_dev->driver);
1138         static u32 lcdc0_old_addr = 0,cur_addr = 0;
1139         static u32 mode = 0,num = 0;
1140         static u32 cur_state = 0,old_state = 0;
1141         
1142         if(dev->screen_ctr_info->prop == PRMRY){
1143                 cur_addr = LcdRdReg(lcdc_dev,WIN0_YRGB_MST);
1144                 if(lcdc0_old_addr != cur_addr){
1145                         if(cur_state++ > 10000)
1146                                 cur_state = 0;
1147
1148                         lcdc0_old_addr = cur_addr;
1149                 }
1150         }
1151
1152         if(old_state == cur_state){
1153                 if(num++>10 && mode != 0)
1154                         mode = 0;
1155         }
1156         else{
1157                 mode = 1;
1158                 num = 0;
1159         }
1160
1161         if(mode == 1 && old_state == cur_state){
1162                 return -1;
1163         }
1164
1165         old_state = cur_state;
1166
1167         return 0;
1168 }
1169
1170 static irqreturn_t rk3066b_lcdc_isr(int irq, void *dev_id)
1171 {
1172         struct rk3066b_lcdc_device *lcdc_dev = (struct rk3066b_lcdc_device *)dev_id;
1173
1174         u32 int_reg = LcdRdReg(lcdc_dev,INT_STATUS);
1175         if(int_reg & m_FRM_START){
1176         ktime_t timestamp = ktime_get();
1177         
1178         LcdMskReg(lcdc_dev, INT_STATUS, m_FRM_STARTCLEAR, v_FRM_STARTCLEAR(1));
1179         
1180 #if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER)
1181         if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED){
1182                 if(no_report(lcdc_dev)){
1183                         return IRQ_HANDLED;
1184                 }
1185         }
1186 #endif
1187         //LcdMskReg(lcdc_dev, INT_STATUS, m_LINE_FLAG_INT_CLEAR, v_LINE_FLAG_INT_CLEAR(1));
1188
1189 #if 0
1190         if(lcdc_dev->driver.num_buf < 3)  //three buffer ,no need to wait for sync
1191         {
1192                 spin_lock(&(lcdc_dev->driver.cpl_lock));
1193                 complete(&(lcdc_dev->driver.frame_done));
1194                 spin_unlock(&(lcdc_dev->driver.cpl_lock));
1195         }
1196 #endif
1197
1198         lcdc_dev->driver.vsync_info.timestamp = timestamp;
1199         wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
1200         }
1201         else if(int_reg & m_SCANNING_FLAG){
1202                 LcdMskReg(lcdc_dev, INT_STATUS, m_SCANNING_CLEAR, v_SCANNING_CLEAR(1));
1203         }
1204         return IRQ_HANDLED;
1205 }
1206
1207
1208 static int rk3066b_set_dsp_lut(struct rk_lcdc_device_driver *dev_drv,int *lut)
1209 {
1210         int i=0;
1211         int __iomem *c;
1212         int v;
1213         int ret = 0;
1214
1215         struct rk3066b_lcdc_device *lcdc_dev =
1216                                 container_of(dev_drv,struct rk3066b_lcdc_device,driver);
1217         LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
1218         LCDC_REG_CFG_DONE();
1219         msleep(25);
1220         if(dev_drv->cur_screen->dsp_lut)
1221         {
1222                 for(i=0;i<256;i++)
1223                 {
1224                         v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
1225                         c = lcdc_dev->dsp_lut_addr_base+i;
1226                         writel_relaxed(v,c);
1227                 }
1228         }
1229         else
1230         {
1231                 dev_err(dev_drv->dev,"no buffer to backup lut data!\n");
1232                 ret =  -1;
1233         }
1234         LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));
1235         LCDC_REG_CFG_DONE();
1236
1237         return ret;
1238 }
1239
1240 int rk3066b_lcdc_poll_vblank(struct rk_lcdc_device_driver * dev_drv)
1241 {
1242         struct rk3066b_lcdc_device *lcdc_dev = 
1243                                 container_of(dev_drv,struct rk3066b_lcdc_device,driver);    
1244         u32 int_reg ;
1245         int ret;
1246         //spin_lock(&lcdc_dev->reg_lock);
1247         if(lcdc_dev->clk_on)
1248         {
1249                 int_reg = LcdRdReg(lcdc_dev,INT_STATUS);
1250                 if(int_reg & m_SCANNING_FLAG)
1251                 {
1252                       LcdMskReg(lcdc_dev, INT_STATUS, m_SCANNING_CLEAR,v_SCANNING_CLEAR(1));              
1253                       ret =  RK_LF_STATUS_FC;
1254                 }
1255                 else
1256                      ret = RK_LF_STATUS_FR;
1257         }
1258         else
1259         {
1260                 ret = RK_LF_STATUS_NC;
1261         }       
1262         //spin_unlock(&lcdc_dev->reg_lock);
1263
1264
1265         return ret;
1266 }
1267
1268 static struct layer_par lcdc_layer[] = {
1269         [0] = {
1270                 .name           = "win0",
1271                 .id             = 0,
1272                 .support_3d     = true,
1273         },
1274         [1] = {
1275                 .name           = "win1",
1276                 .id             = 1,
1277                 .support_3d     = false,
1278         },
1279 };
1280
1281 static struct rk_lcdc_device_driver lcdc_driver = {
1282         .name                   = "lcdc",
1283         .def_layer_par          = lcdc_layer,
1284         .num_layer              = ARRAY_SIZE(lcdc_layer),
1285         .open                   = rk3066b_lcdc_open,
1286         .init_lcdc              = init_rk3066b_lcdc,
1287         .ioctl                  = rk3066b_lcdc_ioctl,
1288         .suspend                = rk3066b_lcdc_early_suspend,
1289         .resume                 = rk3066b_lcdc_early_resume,
1290         .set_par                = rk3066b_lcdc_set_par,
1291         .blank                  = rk3066b_lcdc_blank,
1292         .pan_display            = rk3066b_lcdc_pan_display,
1293         .load_screen            = rk3066b_load_screen,
1294         .get_layer_state        = rk3066b_lcdc_get_layer_state,
1295         .ovl_mgr                = rk3066b_lcdc_ovl_mgr,
1296         .get_disp_info          = rk3066b_lcdc_get_disp_info,
1297         .fps_mgr                = rk3066b_lcdc_fps_mgr,
1298         .fb_get_layer           = rk3066b_fb_get_layer,
1299         .fb_layer_remap         = rk3066b_fb_layer_remap,
1300         .set_dsp_lut            = rk3066b_set_dsp_lut,
1301         .poll_vblank            = rk3066b_lcdc_poll_vblank,
1302 };
1303 #ifdef CONFIG_PM
1304 static int rk3066b_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
1305 {
1306         return 0;
1307 }
1308
1309 static int rk3066b_lcdc_resume(struct platform_device *pdev)
1310 {
1311         return 0;
1312 }
1313
1314 #else
1315 #define rk3066b_lcdc_suspend NULL
1316 #define rk3066b_lcdc_resume NULL
1317 #endif
1318
1319 static int __devinit rk3066b_lcdc_probe (struct platform_device *pdev)
1320 {
1321         struct rk3066b_lcdc_device *lcdc_dev=NULL;
1322         rk_screen *screen;
1323         rk_screen *screen1;
1324         struct rk29fb_info *screen_ctr_info;
1325         struct resource *res = NULL;
1326         struct resource *mem;
1327         int ret = 0;
1328         
1329         /*************Malloc rk3066blcdc_inf and set it to pdev for drvdata**********/
1330         lcdc_dev = kzalloc(sizeof(struct rk3066b_lcdc_device), GFP_KERNEL);
1331         if(!lcdc_dev)
1332         {
1333                 dev_err(&pdev->dev, ">>rk3066b lcdc device kmalloc fail!");
1334                 return -ENOMEM;
1335         }
1336         platform_set_drvdata(pdev, lcdc_dev);
1337         lcdc_dev->id = pdev->id;
1338         screen_ctr_info = (struct rk29fb_info * )pdev->dev.platform_data;
1339         screen =  kzalloc(sizeof(rk_screen), GFP_KERNEL);
1340         if(!screen)
1341         {
1342                 dev_err(&pdev->dev, ">>rk3066b lcdc screen kmalloc fail!");
1343                 ret =  -ENOMEM;
1344                 goto err0;
1345         }
1346         else
1347         {
1348                 lcdc_dev->screen = screen;
1349         }
1350         screen->lcdc_id = lcdc_dev->id;
1351         screen->screen_id = 0;
1352
1353 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& (defined(CONFIG_RK610_LVDS) || defined(CONFIG_RK616_LVDS))
1354         screen1 =  kzalloc(sizeof(rk_screen), GFP_KERNEL);
1355         if(!screen1)
1356         {
1357                 dev_err(&pdev->dev, ">>rk3066b lcdc screen1 kmalloc fail!");
1358                 ret =  -ENOMEM;
1359                 goto err0;
1360         }
1361         screen1->lcdc_id = 1;
1362         screen1->screen_id = 1;
1363         printk("use lcdc%d and rk610 implemention dual display!\n",lcdc_dev->id);
1364         
1365 #endif
1366         /****************get lcdc0 reg  *************************/
1367         res = platform_get_resource(pdev, IORESOURCE_MEM,0);
1368         if (res == NULL)
1369         {
1370                 dev_err(&pdev->dev, "failed to get io resource for lcdc%d \n",lcdc_dev->id);
1371                 ret = -ENOENT;
1372                 goto err1;
1373         }
1374         lcdc_dev->reg_phy_base = res->start;
1375         lcdc_dev->len = resource_size(res);
1376         mem = request_mem_region(lcdc_dev->reg_phy_base, resource_size(res), pdev->name);
1377         if (mem == NULL)
1378         {
1379                 dev_err(&pdev->dev, "failed to request mem region for lcdc%d\n",lcdc_dev->id);
1380                 ret = -ENOENT;
1381                 goto err1;
1382         }
1383         lcdc_dev->reg_vir_base = ioremap(lcdc_dev->reg_phy_base,  resource_size(res));
1384         if (lcdc_dev->reg_vir_base == NULL)
1385         {
1386                 dev_err(&pdev->dev, "cannot map IO\n");
1387                 ret = -ENXIO;
1388                 goto err2;
1389         }
1390         
1391         lcdc_dev->preg = (LCDC_REG*)lcdc_dev->reg_vir_base;
1392         printk("lcdc%d:reg_phy_base = 0x%08x,reg_vir_base:0x%p\n",pdev->id,lcdc_dev->reg_phy_base, lcdc_dev->preg);
1393         lcdc_dev->dsp_lut_addr_base = (lcdc_dev->reg_vir_base+DSP_LUT_ADDR);
1394
1395         lcdc_dev->driver.dev=&pdev->dev;
1396         lcdc_dev->driver.screen0 = screen;
1397 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& (defined(CONFIG_RK610_LVDS) || defined(CONFIG_RK616_LVDS))
1398         lcdc_dev->driver.screen1 = screen1;
1399 #endif
1400         lcdc_dev->driver.cur_screen = screen;
1401         lcdc_dev->driver.screen_ctr_info = screen_ctr_info;
1402         spin_lock_init(&lcdc_dev->reg_lock);
1403         lcdc_dev->irq = platform_get_irq(pdev, 0);
1404         if(lcdc_dev->irq < 0)
1405         {
1406                 dev_err(&pdev->dev, "cannot find IRQ\n");
1407                 goto err3;
1408         }
1409         ret = request_irq(lcdc_dev->irq, rk3066b_lcdc_isr, IRQF_DISABLED,dev_name(&pdev->dev),lcdc_dev);
1410         if (ret)
1411         {
1412                dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n", lcdc_dev->irq, ret);
1413                ret = -EBUSY;
1414                goto err3;
1415         }
1416
1417         if(screen_ctr_info->set_screen_info)
1418         {
1419                 screen_ctr_info->set_screen_info(screen,screen_ctr_info->lcd_info);
1420                 if(SCREEN_NULL==screen->type)
1421                 {
1422                         printk(KERN_WARNING "no display device on lcdc%d!?\n",lcdc_dev->id);
1423                         ret = -ENODEV;
1424                 }
1425                 if(screen_ctr_info->io_init)
1426                         screen_ctr_info->io_init(NULL);
1427         }
1428         else
1429         {
1430                 printk(KERN_WARNING "no display device on lcdc%d!?\n",lcdc_dev->id);
1431                 ret =  -ENODEV;
1432                 goto err4;
1433         }
1434                 
1435         ret = rk_fb_register(&(lcdc_dev->driver),&lcdc_driver,lcdc_dev->id);
1436         if(ret < 0)
1437         {
1438                 printk(KERN_ERR "register fb for lcdc%d failed!\n",lcdc_dev->id);
1439                 goto err4;
1440         }
1441         printk("rk3066b lcdc%d probe ok!\n",lcdc_dev->id);
1442
1443         return 0;
1444
1445 err4:
1446         free_irq(lcdc_dev->irq,lcdc_dev);
1447 err3:   
1448         iounmap(lcdc_dev->reg_vir_base);
1449 err2:
1450         release_mem_region(lcdc_dev->reg_phy_base,resource_size(res));
1451 err1:
1452         kfree(screen);
1453 err0:
1454         platform_set_drvdata(pdev, NULL);
1455         kfree(lcdc_dev);
1456         return ret;
1457     
1458 }
1459 static int __devexit rk3066b_lcdc_remove(struct platform_device *pdev)
1460 {
1461         struct rk3066b_lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
1462         rk_fb_unregister(&(lcdc_dev->driver));
1463         rk3066b_lcdc_deinit(lcdc_dev);
1464         iounmap(lcdc_dev->reg_vir_base);
1465         release_mem_region(lcdc_dev->reg_phy_base,lcdc_dev->len);
1466         kfree(lcdc_dev->screen);
1467         kfree(lcdc_dev);
1468         return 0;
1469 }
1470
1471 static void rk3066b_lcdc_shutdown(struct platform_device *pdev)
1472 {
1473         struct rk3066b_lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
1474         if(lcdc_dev->driver.cur_screen->standby) //standby the screen if necessary
1475                 lcdc_dev->driver.cur_screen->standby(1);
1476         if(lcdc_dev->driver.screen_ctr_info->io_disable) //power off the screen if necessary
1477                 lcdc_dev->driver.screen_ctr_info->io_disable();
1478         if(lcdc_dev->driver.cur_screen->sscreen_set) //turn off  lvds if necessary
1479                 lcdc_dev->driver.cur_screen->sscreen_set(lcdc_dev->driver.cur_screen , 0);
1480
1481         rk3066b_lcdc_deinit(lcdc_dev);
1482         //rk_fb_unregister(&(lcdc_dev->driver));
1483         
1484         /*iounmap(lcdc_dev->reg_vir_base);
1485         release_mem_region(lcdc_dev->reg_phy_base,lcdc_dev->len);
1486         kfree(lcdc_dev->screen);
1487         kfree(lcdc_dev);*/
1488 }
1489
1490
1491 static struct platform_driver rk3066b_lcdc_driver = {
1492         .probe          = rk3066b_lcdc_probe,
1493         .remove         = __devexit_p(rk3066b_lcdc_remove),
1494         .driver         = {
1495                 .name   = "rk30-lcdc",
1496                 .owner  = THIS_MODULE,
1497         },
1498         .suspend        = rk3066b_lcdc_suspend,
1499         .resume         = rk3066b_lcdc_resume,
1500         .shutdown       = rk3066b_lcdc_shutdown,
1501 };
1502
1503 static int __init rk3066b_lcdc_init(void)
1504 {
1505         return platform_driver_register(&rk3066b_lcdc_driver);
1506 }
1507
1508 static void __exit rk3066b_lcdc_exit(void)
1509 {
1510         platform_driver_unregister(&rk3066b_lcdc_driver);
1511 }
1512
1513
1514
1515 fs_initcall(rk3066b_lcdc_init);
1516 module_exit(rk3066b_lcdc_exit);
1517
1518
1519