2 * drivers/video/rockchip/lcdc/rk3188_lcdc.c
4 * Copyright (C) 2013 ROCKCHIP, Inc.
5 *Author:yxj<yxj@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.
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.
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
22 #include <linux/slab.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/platform_device.h>
28 #include <linux/clk.h>
29 #include <linux/earlysuspend.h>
30 #include <asm/div64.h>
31 #include <asm/uaccess.h>
32 #include <mach/iomux.h>
33 #include "../hdmi/rk_hdmi.h"
34 #include "rk3188_lcdc.h"
38 static int dbg_thresd = 0;
39 module_param(dbg_thresd, int, S_IRUGO|S_IWUSR);
40 #define DBG(level,x...) do { \
41 if(unlikely(dbg_thresd >= level)) \
42 printk(KERN_INFO x);} while (0)
44 //#define WAIT_FOR_SYNC 1
46 static int rk3188_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initscreen);
47 static int rk3188_lcdc_clk_enable(struct rk3188_lcdc_device *lcdc_dev)
50 clk_enable(lcdc_dev->hclk);
51 clk_enable(lcdc_dev->dclk);
52 clk_enable(lcdc_dev->aclk);
53 clk_enable(lcdc_dev->pd);
55 spin_lock(&lcdc_dev->reg_lock);
57 spin_unlock(&lcdc_dev->reg_lock);
58 printk("rk3188 lcdc%d clk enable...\n",lcdc_dev->id);
63 static int rk3188_lcdc_clk_disable(struct rk3188_lcdc_device *lcdc_dev)
65 spin_lock(&lcdc_dev->reg_lock);
67 spin_unlock(&lcdc_dev->reg_lock);
69 clk_disable(lcdc_dev->dclk);
70 clk_disable(lcdc_dev->hclk);
71 clk_disable(lcdc_dev->aclk);
72 clk_disable(lcdc_dev->pd);
73 printk("rk3188 lcdc%d clk disable...\n",lcdc_dev->id);
80 static void rk3188_lcdc_reg_dump(struct rk3188_lcdc_device *lcdc_dev)
82 int *cbase = (int *)lcdc_dev->regs;
83 int *regsbak = (int*)lcdc_dev->regsbak;
86 printk("back up reg:\n");
87 for(i=0; i<=(0x90>>4);i++)
90 printk("%08x ",*(regsbak+i*4 +j));
94 printk("lcdc reg:\n");
95 for(i=0; i<=(0x90>>4);i++)
98 printk("%08x ",readl_relaxed(cbase+i*4 +j));
104 static int rk3188_lcdc_alpha_cfg(struct rk3188_lcdc_device *lcdc_dev)
107 enum data_format win0_format = lcdc_dev->driver.layer_par[0]->format;
108 enum data_format win1_format = lcdc_dev->driver.layer_par[1]->format;
110 int win0_alpha_en = ((win0_format == ARGB888) || (win0_format == ABGR888))?1:0;
111 int win1_alpha_en = ((win1_format == ARGB888) || (win1_format == ABGR888))?1:0;
112 u32 *_pv = (u32*)lcdc_dev->regsbak;
113 _pv += (DSP_CTRL0 >> 2);
114 win0_top = ((*_pv)&(m_WIN0_TOP))>> 8;
116 if(win0_top && (lcdc_dev->atv_layer_cnt >= 2) && (win0_alpha_en))
118 lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN,
119 v_WIN0_ALPHA_EN(1) | v_WIN1_ALPHA_EN(0));
121 else if((!win0_top) && (lcdc_dev->atv_layer_cnt >= 2) && (win1_alpha_en))
123 lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN,
124 v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1));
128 lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN,
129 v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0));
131 lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 |
132 m_ALPHA_MODE_SEL1,v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) |
133 v_ALPHA_MODE_SEL1(0));//default set to per-pixel alpha
138 static int rk3188_lcdc_reg_resume(struct rk3188_lcdc_device *lcdc_dev)
140 memcpy((u8*)lcdc_dev->regs, (u8*)lcdc_dev->regsbak, 0x84);
145 //enable layer,open:1,enable;0 disable
146 static int win0_open(struct rk3188_lcdc_device *lcdc_dev,bool open)
148 spin_lock(&lcdc_dev->reg_lock);
149 if(likely(lcdc_dev->clk_on))
153 if(!lcdc_dev->atv_layer_cnt)
155 printk(KERN_INFO "lcdc%d wakeup from standby!\n",lcdc_dev->id);
156 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
158 lcdc_dev->atv_layer_cnt++;
160 else if((lcdc_dev->atv_layer_cnt > 0) && (!open))
162 lcdc_dev->atv_layer_cnt--;
164 lcdc_dev->driver.layer_par[0]->state = open;
166 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN, v_WIN0_EN(open));
167 if(!lcdc_dev->atv_layer_cnt) //if no layer used,disable lcdc
169 printk(KERN_INFO "no layer of lcdc%d is used,go to standby!\n",lcdc_dev->id);
170 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
172 //lcdc_cfg_done(lcdc_dev);
174 spin_unlock(&lcdc_dev->reg_lock);
180 static int win1_open(struct rk3188_lcdc_device *lcdc_dev,bool open)
182 spin_lock(&lcdc_dev->reg_lock);
183 if(likely(lcdc_dev->clk_on))
187 if(!lcdc_dev->atv_layer_cnt)
189 printk(KERN_INFO "lcdc%d wakeup from standby!\n",lcdc_dev->id);
190 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
192 lcdc_dev->atv_layer_cnt++;
194 else if((lcdc_dev->atv_layer_cnt > 0) && (!open))
196 lcdc_dev->atv_layer_cnt--;
198 lcdc_dev->driver.layer_par[1]->state = open;
200 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN, v_WIN1_EN(open));
201 if(!lcdc_dev->atv_layer_cnt) //if no layer used,disable lcdc
203 printk(KERN_INFO "no layer of lcdc%d is used,go to standby!\n",lcdc_dev->id);
204 lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
205 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
207 //lcdc_cfg_done(lcdc_dev);
209 spin_unlock(&lcdc_dev->reg_lock);
214 static int rk3188_lcdc_open(struct rk_lcdc_device_driver *dev_drv,int layer_id,bool open)
219 struct rk3188_lcdc_device *lcdc_dev =
220 container_of(dev_drv,struct rk3188_lcdc_device,driver);
222 if((open) && (!lcdc_dev->atv_layer_cnt)) //enable clk,when first layer open
224 rk3188_lcdc_clk_enable(lcdc_dev);
225 rk3188_lcdc_reg_resume(lcdc_dev); //resume reg
226 rk3188_load_screen(dev_drv,1);
227 spin_lock(&lcdc_dev->reg_lock);
228 if(dev_drv->cur_screen->dsp_lut) //resume dsp lut
230 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(0));
231 lcdc_cfg_done(lcdc_dev);
232 mdelay(25); //wait for dsp lut disabled
235 v = dev_drv->cur_screen->dsp_lut[i];
236 c = lcdc_dev->dsp_lut_addr_base+i;
240 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(1)); //enable dsp lut
242 spin_unlock(&lcdc_dev->reg_lock);
247 win0_open(lcdc_dev,open);
249 else if(layer_id == 1)
251 win1_open(lcdc_dev,open);
255 printk("invalid win number:%d\n",layer_id);
258 if((!open) && (!lcdc_dev->atv_layer_cnt)) //when all layer closed,disable clk
260 rk3188_lcdc_clk_disable(lcdc_dev);
263 printk(KERN_INFO "lcdc%d win%d %s,atv layer:%d\n",
264 lcdc_dev->id,layer_id,open?"open":"closed",
265 lcdc_dev->atv_layer_cnt);
269 static int rk3188_lcdc_init(struct rk_lcdc_device_driver *dev_drv)
274 struct rk3188_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3188_lcdc_device,driver);
275 if(lcdc_dev->id == 0) //lcdc0
277 lcdc_dev->pd = clk_get(NULL,"pd_lcdc0");
278 lcdc_dev->hclk = clk_get(NULL,"hclk_lcdc0");
279 lcdc_dev->aclk = clk_get(NULL,"aclk_lcdc0");
280 lcdc_dev->dclk = clk_get(NULL,"dclk_lcdc0");
282 else if(lcdc_dev->id == 1)
284 lcdc_dev->pd = clk_get(NULL,"pd_lcdc1");
285 lcdc_dev->hclk = clk_get(NULL,"hclk_lcdc1");
286 lcdc_dev->aclk = clk_get(NULL,"aclk_lcdc1");
287 lcdc_dev->dclk = clk_get(NULL,"dclk_lcdc1");
291 printk(KERN_ERR "invalid lcdc device!\n");
294 if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||(IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk)))
296 printk(KERN_ERR "failed to get lcdc%d clk source\n",lcdc_dev->id);
299 rk3188_lcdc_clk_enable(lcdc_dev);
301 if(lcdc_dev->id == 0)
303 #if defined(CONFIG_LCDC0_IO_18V)
304 v = 0x40004000; //bit14: 1,1.8v;0,3.3v
305 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
308 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
312 if(lcdc_dev->id == 1) //iomux for lcdc1
314 #if defined(CONFIG_LCDC1_IO_18V)
315 v = 0x80008000; //bit14: 1,1.8v;0,3.3v
316 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
319 writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
321 iomux_set(LCDC1_DCLK);
322 iomux_set(LCDC1_DEN);
323 iomux_set(LCDC1_HSYNC);
324 iomux_set(LCDC1_VSYNC);
335 iomux_set(LCDC1_D10);
336 iomux_set(LCDC1_D11);
337 iomux_set(LCDC1_D12);
338 iomux_set(LCDC1_D13);
339 iomux_set(LCDC1_D14);
340 iomux_set(LCDC1_D15);
341 iomux_set(LCDC1_D16);
342 iomux_set(LCDC1_D17);
343 iomux_set(LCDC1_D18);
344 iomux_set(LCDC1_D19);
345 iomux_set(LCDC1_D20);
346 iomux_set(LCDC1_D21);
347 iomux_set(LCDC1_D22);
348 iomux_set(LCDC1_D23);
351 lcdc_set_bit(lcdc_dev,SYS_CTRL,m_AUTO_GATING_EN);//eanble axi-clk auto gating for low power
352 //lcdc_set_bit(lcdc_dev,DSP_CTRL0,m_WIN0_TOP);
353 if(dev_drv->cur_screen->dsp_lut)
355 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(0));
356 lcdc_cfg_done(lcdc_dev);
360 v = dev_drv->cur_screen->dsp_lut[i];
361 c = lcdc_dev->dsp_lut_addr_base+i;
365 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(1));
368 lcdc_cfg_done(lcdc_dev); // write any value to REG_CFG_DONE let config become effective
370 rk3188_lcdc_clk_disable(lcdc_dev);
376 static void rk3188_lcdc_deint(struct rk3188_lcdc_device * lcdc_dev)
378 spin_lock(&lcdc_dev->reg_lock);
379 if(likely(lcdc_dev->clk_on))
381 lcdc_dev->clk_on = 0;
382 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
383 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_HS_INT_EN | m_FS_INT_EN |
384 m_LF_INT_EN | m_BUS_ERR_INT_EN,v_HS_INT_EN(0) | v_FS_INT_EN(0) |
385 v_LF_INT_EN(0) | v_BUS_ERR_INT_EN(0)); //disable all lcdc interrupt
386 lcdc_set_bit(lcdc_dev,SYS_CTRL,m_LCDC_STANDBY);
387 lcdc_cfg_done(lcdc_dev);
388 spin_unlock(&lcdc_dev->reg_lock);
390 else //clk already disabled
392 spin_unlock(&lcdc_dev->reg_lock);
399 //set lcdc according the screen info
400 static int rk3188_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initscreen)
405 struct rk3188_lcdc_device *lcdc_dev =
406 container_of(dev_drv,struct rk3188_lcdc_device,driver);
407 rk_screen *screen = dev_drv->cur_screen;
408 u16 right_margin = screen->right_margin;
409 u16 left_margin = screen->left_margin;
410 u16 lower_margin = screen->lower_margin;
411 u16 upper_margin = screen->upper_margin;
412 u16 x_res = screen->x_res;
413 u16 y_res = screen->y_res;
415 spin_lock(&lcdc_dev->reg_lock);
416 if(likely(lcdc_dev->clk_on))
418 if(screen->type==SCREEN_MCU)
420 printk("MUC¡¡screen not supported now!\n");
424 switch (screen->face)
427 face = OUT_P565; //dither down to rgb565
428 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
429 m_DITHER_DOWN_SEL,v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
430 v_DITHER_DOWN_SEL(1));
433 face = OUT_P666; //dither down to rgb666
434 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
435 m_DITHER_DOWN_SEL, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
436 v_DITHER_DOWN_SEL(1));
440 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
441 m_DITHER_DOWN_SEL, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
442 v_DITHER_DOWN_SEL(1));
446 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
447 m_DITHER_DOWN_SEL, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
448 v_DITHER_DOWN_SEL(1));
454 printk("unsupported display output interface!\n");
458 //use default overlay,set vsyn hsync den dclk polarity
459 lcdc_msk_reg(lcdc_dev, DSP_CTRL0,m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
460 m_DEN_POL |m_DCLK_POL,v_DSP_OUT_FORMAT(face) | v_HSYNC_POL(screen->pin_hsync) |
461 v_VSYNC_POL(screen->pin_vsync) | v_DEN_POL(screen->pin_den) | v_DCLK_POL(screen->pin_dclk));
464 //set background color to black,set swap according to the screen panel,disable blank mode
465 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BG_COLOR| m_DSP_BG_SWAP | m_DSP_RB_SWAP |
466 m_DSP_RG_SWAP | m_DSP_DELTA_SWAP | m_DSP_DUMMY_SWAP | m_BLANK_EN,
467 v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
468 v_DSP_RB_SWAP(screen->swap_rb) | v_DSP_RG_SWAP(screen->swap_rg) |
469 v_DSP_DELTA_SWAP(screen->swap_delta) | v_DSP_DUMMY_SWAP(screen->swap_dumy) |
470 v_BLANK_EN(0) | v_BLACK_EN(0));
471 lcdc_writel(lcdc_dev,DSP_HTOTAL_HS_END,v_HSYNC(screen->hsync_len) |
472 v_HORPRD(screen->hsync_len + left_margin + x_res + right_margin));
473 lcdc_writel(lcdc_dev,DSP_HACT_ST_END,v_HAEP(screen->hsync_len + left_margin + x_res) |
474 v_HASP(screen->hsync_len + left_margin));
476 lcdc_writel(lcdc_dev,DSP_VTOTAL_VS_END, v_VSYNC(screen->vsync_len) |
477 v_VERPRD(screen->vsync_len + upper_margin + y_res + lower_margin));
478 lcdc_writel(lcdc_dev,DSP_VACT_ST_END,v_VAEP(screen->vsync_len + upper_margin+y_res)|
479 v_VASP(screen->vsync_len + screen->upper_margin));
481 spin_unlock(&lcdc_dev->reg_lock);
483 ret = clk_set_rate(lcdc_dev->dclk, screen->pixclock);
486 dev_err(dev_drv->dev,"set lcdc%d dclk failed\n",lcdc_dev->id);
488 lcdc_dev->driver.pixclock = lcdc_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
490 fps = rk_fb_calc_fps(screen,lcdc_dev->pixclock);
491 screen->ft = 1000/fps;
492 printk("%s: dclk:%lu>>fps:%d ",lcdc_dev->driver.name,clk_get_rate(lcdc_dev->dclk),fps);
499 if(screen->sscreen_set)
501 screen->sscreen_set(screen,!initscreen);
504 dev_info(dev_drv->dev,"%s for lcdc%d ok!\n",__func__,lcdc_dev->id);
509 static int win0_set_par(struct rk3188_lcdc_device *lcdc_dev,rk_screen *screen,
510 struct layer_par *par )
512 u32 xact, yact, xvir, yvir, xpos, ypos;
513 u32 ScaleYrgbX = 0x1000;
514 u32 ScaleYrgbY = 0x1000;
515 u32 ScaleCbrX = 0x1000;
516 u32 ScaleCbrY = 0x1000;
517 u8 fmt_cfg =0 ; //data format register config value
519 xact = par->xact; //active (origin) picture window width/height
521 xvir = par->xvir; // virtual resolution
523 xpos = par->xpos+screen->left_margin + screen->hsync_len;
524 ypos = par->ypos+screen->upper_margin + screen->vsync_len;
527 ScaleYrgbX = CalScale(xact, par->xsize); //both RGB and yuv need this two factor
528 ScaleYrgbY = CalScale(yact, par->ysize);
542 case YUV422:// yuv422
544 ScaleCbrX = CalScale((xact/2), par->xsize);
545 ScaleCbrY = CalScale(yact, par->ysize);
547 case YUV420: // yuv420
549 ScaleCbrX = CalScale(xact/2, par->xsize);
550 ScaleCbrY = CalScale(yact/2, par->ysize);
552 case YUV444:// yuv444
554 ScaleCbrX = CalScale(xact, par->xsize);
555 ScaleCbrY = CalScale(yact, par->ysize);
558 dev_err(lcdc_dev->driver.dev,"%s:un supported format!\n",__func__);
562 DBG(1,"%s for lcdc%d>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
563 __func__,lcdc_dev->id,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
565 spin_lock(&lcdc_dev->reg_lock);
566 if(likely(lcdc_dev->clk_on))
568 lcdc_writel(lcdc_dev,WIN0_SCL_FACTOR_YRGB,v_X_SCL_FACTOR(ScaleYrgbX) | v_Y_SCL_FACTOR(ScaleYrgbY));
569 lcdc_writel(lcdc_dev,WIN0_SCL_FACTOR_CBR,v_X_SCL_FACTOR(ScaleCbrX) | v_Y_SCL_FACTOR(ScaleCbrY));
570 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_FORMAT,v_WIN0_FORMAT(fmt_cfg)); //(inf->video_mode==0)
571 lcdc_writel(lcdc_dev,WIN0_ACT_INFO,v_ACT_WIDTH(xact) | v_ACT_HEIGHT(yact));
572 lcdc_writel(lcdc_dev,WIN0_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
573 lcdc_writel(lcdc_dev,WIN0_DSP_INFO,v_DSP_WIDTH(par->xsize) | v_DSP_HEIGHT(par->ysize));
574 lcdc_msk_reg(lcdc_dev,WIN0_COLOR_KEY,m_COLOR_KEY_EN,v_COLOR_KEY_EN(0));
579 lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_ARGB888_VIRWIDTH(xvir));
580 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
581 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(1));
584 lcdc_msk_reg(lcdc_dev,WIN_VIR,m_WIN0_VIR,v_ARGB888_VIRWIDTH(xvir));
585 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(1));
586 //lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 |
587 // m_ALPHA_MODE_SEL1,v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) |
588 // v_ALPHA_MODE_SEL1(0));//default set to per-pixel alpha
589 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(1));
592 lcdc_msk_reg(lcdc_dev,WIN_VIR,m_WIN0_VIR,v_ARGB888_VIRWIDTH(xvir));
593 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(1));
594 //lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0,
595 // v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1));//default set to per-pixel alpha
596 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
598 case RGB888: //rgb888
599 lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_RGB888_VIRWIDTH(xvir));
600 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
601 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
603 case RGB565: //rgb565
604 lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_RGB565_VIRWIDTH(xvir));
605 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
606 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
611 lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_YUV_VIRWIDTH(xvir));
612 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN0_ALPHA_EN,v_WIN0_ALPHA_EN(0));
613 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN0_RB_SWAP,v_WIN0_RB_SWAP(0));
616 dev_err(lcdc_dev->driver.dev,"%s:un supported format!\n",__func__);
621 spin_unlock(&lcdc_dev->reg_lock);
627 static int win1_set_par(struct rk3188_lcdc_device *lcdc_dev,rk_screen *screen,
628 struct layer_par *par )
630 u32 xact, yact, xvir, yvir, xpos, ypos;
637 xpos = par->xpos+screen->left_margin + screen->hsync_len;
638 ypos = par->ypos+screen->upper_margin + screen->vsync_len;
641 DBG(1,"%s for lcdc%d>>format:%d>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d>>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n",
642 __func__,lcdc_dev->id,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
645 spin_lock(&lcdc_dev->reg_lock);
646 if(likely(lcdc_dev->clk_on))
649 lcdc_writel(lcdc_dev, WIN1_DSP_INFO,v_DSP_WIDTH(par->xsize) | v_DSP_HEIGHT(par->ysize));
650 lcdc_writel(lcdc_dev, WIN1_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
651 // disable win1 color key and set the color to black(rgb=0)
652 lcdc_msk_reg(lcdc_dev, WIN1_COLOR_KEY,m_COLOR_KEY_EN,v_COLOR_KEY_EN(0));
657 lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_ARGB888_VIRWIDTH(xvir));
658 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(0));
659 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(1));
663 lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_ARGB888_VIRWIDTH(xvir));
664 lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(1));
665 lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0,
666 v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1));//default set to per-pixel alpha
667 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(1));
671 lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_ARGB888_VIRWIDTH(xvir));
672 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(1));
673 //lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0,
674 // v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1));//default set to per-pixel alpha
675 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(0));
677 case RGB888: //rgb888
679 lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_RGB888_VIRWIDTH(xvir));
680 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(0));
681 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(0));
682 //lcdc_msk_reg(lcdc_dev,SYS_CTRL1,m_W1_RGB_RB_SWAP,v_W1_RGB_RB_SWAP(1));
684 case RGB565: //rgb565
686 lcdc_msk_reg(lcdc_dev, WIN_VIR,m_WIN1_VIR,v_WIN1_RGB565_VIRWIDTH(xvir));
687 //lcdc_msk_reg(lcdc_dev,ALPHA_CTRL,m_WIN1_ALPHA_EN,v_WIN1_ALPHA_EN(0));
688 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_RB_SWAP,v_WIN1_RB_SWAP(0));
691 dev_err(lcdc_dev->driver.dev,"%s:un supported format!\n",__func__);
694 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_WIN1_FORMAT, v_WIN1_FORMAT(fmt_cfg));
697 spin_unlock(&lcdc_dev->reg_lock);
703 static int rk3188_lcdc_set_par(struct rk_lcdc_device_driver *dev_drv,int layer_id)
705 struct rk3188_lcdc_device *lcdc_dev =
706 container_of(dev_drv,struct rk3188_lcdc_device,driver);
707 struct layer_par *par = NULL;
708 rk_screen *screen = dev_drv->cur_screen;
712 dev_err(dev_drv->dev,"screen is null!\n");
717 par = dev_drv->layer_par[0];
718 win0_set_par(lcdc_dev,screen,par);
722 par = dev_drv->layer_par[1];
723 win1_set_par(lcdc_dev,screen,par);
727 dev_err(dev_drv->dev,"unsupported win number:%d\n",layer_id);
734 static int win0_display(struct rk3188_lcdc_device *lcdc_dev,struct layer_par *par )
738 y_addr = par->smem_start + par->y_offset;
739 uv_addr = par->cbr_start + par->c_offset;
740 DBG(2,KERN_INFO "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);
742 spin_lock(&lcdc_dev->reg_lock);
743 if(likely(lcdc_dev->clk_on))
745 lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, y_addr);
746 lcdc_writel(lcdc_dev, WIN0_CBR_MST0, uv_addr);
747 #if defined(CONFIG_RK_HDMI)
748 #if defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL)
749 if(lcdc_dev->driver.screen_ctr_info->prop == EXTEND)
751 if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
753 lcdc_cfg_done(lcdc_dev);
759 spin_unlock(&lcdc_dev->reg_lock);
765 static int win1_display(struct rk3188_lcdc_device *lcdc_dev,struct layer_par *par )
769 y_addr = par->smem_start + par->y_offset;
770 uv_addr = par->cbr_start + par->c_offset;
771 DBG(2,KERN_INFO "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);
773 spin_lock(&lcdc_dev->reg_lock);
774 if(likely(lcdc_dev->clk_on))
776 lcdc_writel(lcdc_dev,WIN1_MST,y_addr);
777 #if defined(CONFIG_RK_HDMI)
778 #if defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL)
779 if(lcdc_dev->driver.screen_ctr_info->prop == EXTEND)
781 if(hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
783 lcdc_cfg_done(lcdc_dev);
789 spin_unlock(&lcdc_dev->reg_lock);
794 static int rk3188_lcdc_pan_display(struct rk_lcdc_device_driver * dev_drv,int layer_id)
796 struct rk3188_lcdc_device *lcdc_dev =
797 container_of(dev_drv,struct rk3188_lcdc_device,driver);
798 struct layer_par *par = NULL;
799 rk_screen *screen = dev_drv->cur_screen;
805 dev_err(dev_drv->dev,"screen is null!\n");
810 par = dev_drv->layer_par[0];
811 win0_display(lcdc_dev,par);
815 par = dev_drv->layer_par[1];
816 win1_display(lcdc_dev,par);
820 dev_err(dev_drv->dev,"invalid win number:%d!\n",layer_id);
823 if((dev_drv->first_frame)) //this is the first frame of the system ,enable frame start interrupt
825 dev_drv->first_frame = 0;
826 lcdc_msk_reg(lcdc_dev,INT_STATUS,m_FS_INT_CLEAR |m_FS_INT_EN ,
827 v_FS_INT_CLEAR(1) | v_FS_INT_EN(1));
828 lcdc_cfg_done(lcdc_dev); // write any value to REG_CFG_DONE let config become effective
832 #if defined(WAIT_FOR_SYNC)
833 spin_lock_irqsave(&dev_drv->cpl_lock,flags);
834 init_completion(&dev_drv->frame_done);
835 spin_unlock_irqrestore(&dev_drv->cpl_lock,flags);
836 timeout = wait_for_completion_timeout(&dev_drv->frame_done,msecs_to_jiffies(dev_drv->cur_screen->ft+5));
837 if(!timeout&&(!dev_drv->frame_done.done))
839 printk(KERN_ERR "wait for new frame start time out!\n");
846 static int rk3188_lcdc_blank(struct rk_lcdc_device_driver *dev_drv,
847 int layer_id,int blank_mode)
849 struct rk3188_lcdc_device * lcdc_dev =
850 container_of(dev_drv,struct rk3188_lcdc_device,driver);
852 spin_lock(&lcdc_dev->reg_lock);
853 if(likely(lcdc_dev->clk_on))
857 case FB_BLANK_UNBLANK:
858 lcdc_msk_reg(lcdc_dev,DSP_CTRL1,m_BLANK_EN ,v_BLANK_EN(0));
860 case FB_BLANK_NORMAL:
861 lcdc_msk_reg(lcdc_dev,DSP_CTRL1,m_BLANK_EN ,v_BLANK_EN(1));
864 lcdc_msk_reg(lcdc_dev,DSP_CTRL1,m_BLANK_EN ,v_BLANK_EN(1));
867 lcdc_cfg_done(lcdc_dev);
868 dev_info(dev_drv->dev,"blank mode:%d\n",blank_mode);
870 spin_unlock(&lcdc_dev->reg_lock);
876 static int rk3188_lcdc_ioctl(struct rk_lcdc_device_driver *dev_drv, unsigned int cmd,unsigned long arg,int layer_id)
878 struct rk3188_lcdc_device *lcdc_dev =
879 container_of(dev_drv,struct rk3188_lcdc_device,driver);
881 void __user *argp = (void __user *)arg;
887 case RK_FBIOGET_PANEL_SIZE: //get panel size
888 panel_size[0] = lcdc_dev->screen->x_res;
889 panel_size[1] = lcdc_dev->screen->y_res;
890 if(copy_to_user(argp, panel_size, 8))
893 case RK_FBIOSET_CONFIG_DONE:
894 if (copy_from_user(&(dev_drv->wait_fs),argp,sizeof(dev_drv->wait_fs)))
896 rk3188_lcdc_alpha_cfg(lcdc_dev);
897 lcdc_cfg_done(lcdc_dev);
900 spin_lock_irqsave(&dev_drv->cpl_lock,flags);
901 init_completion(&dev_drv->frame_done);
902 spin_unlock_irqrestore(&dev_drv->cpl_lock,flags);
903 timeout = wait_for_completion_timeout(&dev_drv->frame_done,msecs_to_jiffies(dev_drv->cur_screen->ft+5));
904 if(!timeout&&(!dev_drv->frame_done.done))
906 printk(KERN_ERR "wait for new frame start time out!\n");
917 static int rk3188_lcdc_early_suspend(struct rk_lcdc_device_driver *dev_drv)
920 struct rk3188_lcdc_device *lcdc_dev =
921 container_of(dev_drv,struct rk3188_lcdc_device,driver);
923 if(dev_drv->screen0->standby)
924 dev_drv->screen0->standby(1);
925 if(dev_drv->screen_ctr_info->io_disable)
926 dev_drv->screen_ctr_info->io_disable();
928 spin_lock(&lcdc_dev->reg_lock);
929 if(likely(lcdc_dev->clk_on))
931 lcdc_msk_reg(lcdc_dev,INT_STATUS,m_FS_INT_CLEAR,v_FS_INT_CLEAR(1));
932 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
933 lcdc_cfg_done(lcdc_dev);
934 spin_unlock(&lcdc_dev->reg_lock);
936 else //clk already disabled
938 spin_unlock(&lcdc_dev->reg_lock);
943 rk3188_lcdc_clk_disable(lcdc_dev);
947 static int rk3188_lcdc_early_resume(struct rk_lcdc_device_driver *dev_drv)
949 struct rk3188_lcdc_device *lcdc_dev =
950 container_of(dev_drv,struct rk3188_lcdc_device,driver);
955 if(dev_drv->screen_ctr_info->io_enable) //power on
956 dev_drv->screen_ctr_info->io_enable();
958 if(!lcdc_dev->clk_on)
960 rk3188_lcdc_clk_enable(lcdc_dev);
962 rk3188_lcdc_reg_resume(lcdc_dev); //resume reg
964 spin_lock(&lcdc_dev->reg_lock);
965 if(dev_drv->cur_screen->dsp_lut) //resume dsp lut
967 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(0));
968 lcdc_cfg_done(lcdc_dev);
972 v = dev_drv->cur_screen->dsp_lut[i];
973 c = lcdc_dev->dsp_lut_addr_base+i;
976 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(1));
979 if(lcdc_dev->atv_layer_cnt)
981 lcdc_msk_reg(lcdc_dev, SYS_CTRL,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
982 lcdc_cfg_done(lcdc_dev);
984 spin_unlock(&lcdc_dev->reg_lock);
986 if(!lcdc_dev->atv_layer_cnt)
987 rk3188_lcdc_clk_disable(lcdc_dev);
989 if(dev_drv->screen0->standby)
990 dev_drv->screen0->standby(0); //screen wake up
995 static int rk3188_lcdc_get_layer_state(struct rk_lcdc_device_driver *dev_drv,int layer_id)
1000 static int rk3188_lcdc_ovl_mgr(struct rk_lcdc_device_driver *dev_drv,int swap,bool set)
1002 struct rk3188_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3188_lcdc_device,driver);
1004 spin_lock(&lcdc_dev->reg_lock);
1005 if(lcdc_dev->clk_on)
1007 if(set) //set overlay
1009 lcdc_msk_reg(lcdc_dev,DSP_CTRL0,m_WIN0_TOP,v_WIN0_TOP(swap));
1010 //lcdc_cfg_done(lcdc_dev);
1015 ovl = lcdc_read_bit(lcdc_dev,DSP_CTRL0,m_WIN0_TOP);
1022 spin_unlock(&lcdc_dev->reg_lock);
1028 static ssize_t rk3188_lcdc_get_disp_info(struct rk_lcdc_device_driver *dev_drv,char *buf,int layer_id)
1031 struct rk3188_lcdc_device *lcdc_dev =
1032 container_of(dev_drv,struct rk3188_lcdc_device,driver);
1034 char format_w0[9]= "NULL";
1035 char format_w1[9]= "NULL";
1036 char status_w0[9]= "NULL";
1037 char status_w1[9]= "NULL";
1038 u32 fmt_id = lcdc_readl(lcdc_dev,SYS_CTRL);
1039 u32 act_info,dsp_info,dsp_st,factor;
1040 u16 xvir_w0,x_act_w0,y_act_w0,x_dsp_w0,y_dsp_w0,x_st_w0,y_st_w0,x_factor,y_factor;
1041 u16 xvir_w1,x_dsp_w1,y_dsp_w1,x_st_w1,y_st_w1;
1042 u16 x_scale,y_scale;
1043 switch((fmt_id&m_WIN0_FORMAT)>>3)
1046 strcpy(format_w0,"ARGB888");
1049 strcpy(format_w0,"RGB888");
1052 strcpy(format_w0,"RGB565");
1055 strcpy(format_w0,"YCbCr420");
1058 strcpy(format_w0,"YCbCr422");
1061 strcpy(format_w0,"YCbCr444");
1064 strcpy(format_w0,"invalid\n");
1068 switch((fmt_id&m_WIN1_FORMAT)>>6)
1071 strcpy(format_w1,"ARGB888");
1074 strcpy(format_w1,"RGB888");
1077 strcpy(format_w1,"RGB565");
1080 strcpy(format_w1,"8bpp");
1083 strcpy(format_w1,"4bpp");
1086 strcpy(format_w1,"2bpp");
1089 strcpy(format_w1,"1bpp");
1092 strcpy(format_w1,"invalid\n");
1096 if(fmt_id&m_WIN0_EN)
1098 strcpy(status_w0,"enabled");
1102 strcpy(status_w0,"disabled");
1105 if((fmt_id&m_WIN1_EN)>>1)
1107 strcpy(status_w1,"enabled");
1111 strcpy(status_w1,"disabled");
1114 xvir_w0 = lcdc_readl(lcdc_dev,WIN_VIR)&0x1fff;
1115 act_info = lcdc_readl(lcdc_dev,WIN0_ACT_INFO);
1116 dsp_info = lcdc_readl(lcdc_dev,WIN0_DSP_INFO);
1117 dsp_st = lcdc_readl(lcdc_dev,WIN0_DSP_ST);
1118 factor = lcdc_readl(lcdc_dev,WIN0_SCL_FACTOR_YRGB);
1119 x_act_w0= (act_info&0x1fff) + 1;
1120 y_act_w0= ((act_info>>16)&0x1fff) + 1;
1121 x_dsp_w0= (dsp_info&0x7ff) + 1;
1122 y_dsp_w0= ((dsp_info>>16)&0x7ff) + 1;
1123 x_st_w0 = dsp_st&0xffff;
1124 y_st_w0 = dsp_st>>16;
1125 x_factor = factor&0xffff;
1126 y_factor = factor>>16;
1127 x_scale = 4096*100/x_factor;
1128 y_scale = 4096*100/y_factor;
1130 xvir_w1= (lcdc_readl(lcdc_dev,WIN_VIR)>> 16)&0x1fff;
1131 dsp_info = lcdc_readl(lcdc_dev,WIN1_DSP_INFO);
1132 dsp_st = lcdc_readl(lcdc_dev,WIN1_DSP_ST);
1133 x_dsp_w1= (dsp_info&0x7ff) + 1;
1134 y_dsp_w1= ((dsp_info>>16)&0x7ff) + 1;
1135 x_st_w1 = dsp_st&0xffff;
1136 y_st_w1 = dsp_st>>16;
1137 return snprintf(buf,PAGE_SIZE,
1180 static int rk3188_lcdc_fps_mgr(struct rk_lcdc_device_driver *dev_drv,int fps,bool set)
1182 struct rk3188_lcdc_device *lcdc_dev =
1183 container_of(dev_drv,struct rk3188_lcdc_device,driver);
1184 rk_screen * screen = dev_drv->cur_screen;
1191 ft = div_u64(1000000000000llu,fps);
1192 dev_drv->pixclock = div_u64(ft,(screen->upper_margin + screen->lower_margin + screen->y_res +screen->vsync_len)*
1193 (screen->left_margin + screen->right_margin + screen->x_res + screen->hsync_len));
1194 dotclk = div_u64(1000000000000llu,dev_drv->pixclock);
1195 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
1198 printk(KERN_ERR ">>>>>> set lcdc%d dclk failed\n",lcdc_dev->id);
1204 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1205 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
1206 fps = rk_fb_calc_fps(lcdc_dev->screen,pixclock);
1207 screen->ft = 1000/fps ; //one frame time in ms
1210 dev_info(dev_drv->dev,"%s:dclk:%lu,fps:%d\n",__func__,clk_get_rate(lcdc_dev->dclk),fps);
1216 static int rk3188_fb_layer_remap(struct rk_lcdc_device_driver *dev_drv,
1217 enum fb_win_map_order order)
1219 mutex_lock(&dev_drv->fb_win_id_mutex);
1220 if(order == FB_DEFAULT_ORDER )
1222 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
1224 dev_drv->fb2_win_id = order/100;
1225 dev_drv->fb1_win_id = (order/10)%10;
1226 dev_drv->fb0_win_id = order%10;
1227 mutex_unlock(&dev_drv->fb_win_id_mutex);
1229 printk("fb0:win%d\nfb1:win%d\nfb2:win%d\n",dev_drv->fb0_win_id,dev_drv->fb1_win_id,
1230 dev_drv->fb2_win_id);
1235 static int rk3188_fb_get_layer(struct rk_lcdc_device_driver *dev_drv,const char *id)
1238 mutex_lock(&dev_drv->fb_win_id_mutex);
1239 if(!strcmp(id,"fb0")||!strcmp(id,"fb2"))
1241 layer_id = dev_drv->fb0_win_id;
1243 else if(!strcmp(id,"fb1")||!strcmp(id,"fb3"))
1245 layer_id = dev_drv->fb1_win_id;
1247 mutex_unlock(&dev_drv->fb_win_id_mutex);
1252 static int rk3188_set_dsp_lut(struct rk_lcdc_device_driver *dev_drv,int *lut)
1259 struct rk3188_lcdc_device *lcdc_dev =
1260 container_of(dev_drv,struct rk3188_lcdc_device,driver);
1261 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(0));
1262 lcdc_cfg_done(lcdc_dev);
1264 if(dev_drv->cur_screen->dsp_lut)
1268 v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
1269 c = lcdc_dev->dsp_lut_addr_base+i;
1270 writel_relaxed(v,c);
1276 dev_err(dev_drv->dev,"no buffer to backup lut data!\n");
1279 lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DSP_LUT_EN,v_DSP_LUT_EN(1));
1280 lcdc_cfg_done(lcdc_dev);
1286 static struct layer_par lcdc_layer[] = {
1295 .support_3d = false,
1299 static struct rk_lcdc_device_driver lcdc_driver = {
1301 .def_layer_par = lcdc_layer,
1302 .num_layer = ARRAY_SIZE(lcdc_layer),
1303 .open = rk3188_lcdc_open,
1304 .init_lcdc = rk3188_lcdc_init,
1305 .load_screen = rk3188_load_screen,
1306 .set_par = rk3188_lcdc_set_par,
1307 .pan_display = rk3188_lcdc_pan_display,
1308 .blank = rk3188_lcdc_blank,
1309 .ioctl = rk3188_lcdc_ioctl,
1310 .suspend = rk3188_lcdc_early_suspend,
1311 .resume = rk3188_lcdc_early_resume,
1312 .get_layer_state = rk3188_lcdc_get_layer_state,
1313 .ovl_mgr = rk3188_lcdc_ovl_mgr,
1314 .get_disp_info = rk3188_lcdc_get_disp_info,
1315 .fps_mgr = rk3188_lcdc_fps_mgr,
1316 .fb_get_layer = rk3188_fb_get_layer,
1317 .fb_layer_remap = rk3188_fb_layer_remap,
1318 .set_dsp_lut = rk3188_set_dsp_lut,
1321 static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id)
1323 struct rk3188_lcdc_device *lcdc_dev =
1324 (struct rk3188_lcdc_device *)dev_id;
1325 ktime_t timestamp = ktime_get();
1327 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
1329 if(lcdc_dev->driver.wait_fs) //three buffer ,no need to wait for sync
1331 spin_lock(&(lcdc_dev->driver.cpl_lock));
1332 complete(&(lcdc_dev->driver.frame_done));
1333 spin_unlock(&(lcdc_dev->driver.cpl_lock));
1335 lcdc_dev->driver.vsync_info.timestamp = timestamp;
1336 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
1342 #if defined(CONFIG_PM)
1343 static int rk3188_lcdc_suspend(struct platform_device *pdev,
1349 static int rk3188_lcdc_resume(struct platform_device *pdev)
1354 #define rk3188_lcdc_suspend NULL
1355 #define rk3188_lcdc_resume NULL
1357 static int __devinit rk3188_lcdc_probe(struct platform_device *pdev)
1359 struct rk3188_lcdc_device *lcdc_dev = NULL;
1360 struct device *dev = &pdev->dev;
1363 struct rk29fb_info *screen_ctr_info;
1364 struct resource *res = NULL;
1365 struct resource *mem = NULL;
1368 lcdc_dev = devm_kzalloc(dev,sizeof(struct rk3188_lcdc_device), GFP_KERNEL);
1371 dev_err(&pdev->dev, ">>rk3188 lcdc device kmalloc fail!");
1374 platform_set_drvdata(pdev, lcdc_dev);
1375 lcdc_dev->id = pdev->id;
1376 screen_ctr_info = (struct rk29fb_info * )pdev->dev.platform_data;
1377 screen = kzalloc(sizeof(rk_screen), GFP_KERNEL);
1378 if(!screen_ctr_info)
1380 dev_err(dev, "no platform data specified for screen control info!\n");
1386 dev_err(&pdev->dev, "rk screen kmalloc fail!");
1392 lcdc_dev->screen = screen;
1394 screen->lcdc_id = lcdc_dev->id;
1395 screen->screen_id = 0;
1396 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& defined(CONFIG_RK610_LVDS)
1397 screen1 = kzalloc(sizeof(rk_screen), GFP_KERNEL);
1400 dev_err(&pdev->dev, ">>rk3066b lcdc screen1 kmalloc fail!");
1404 screen1->lcdc_id = 1;
1405 screen1->screen_id = 1;
1406 printk("use lcdc%d and rk610 implemention dual display!\n",lcdc_dev->id);
1410 res = platform_get_resource(pdev, IORESOURCE_MEM,0);
1413 dev_err(&pdev->dev, "failed to get register resource for lcdc%d \n",lcdc_dev->id);
1418 lcdc_dev->reg_phy_base = res->start;
1419 lcdc_dev->len = resource_size(res);
1420 mem = request_mem_region(lcdc_dev->reg_phy_base,lcdc_dev->len, pdev->name);
1423 dev_err(&pdev->dev, "failed to request mem region for lcdc%d\n",lcdc_dev->id);
1427 lcdc_dev->regs = ioremap(lcdc_dev->reg_phy_base,lcdc_dev->len);
1428 if (!lcdc_dev->regs)
1430 dev_err(&pdev->dev, "cannot map register for lcdc%d\n",lcdc_dev->id);
1435 lcdc_dev->regsbak = kzalloc(lcdc_dev->len,GFP_KERNEL);
1436 if(!lcdc_dev->regsbak)
1438 dev_err(&pdev->dev, "failed to map memory for reg backup!\n");
1442 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
1443 printk("lcdc%d:reg_phy_base = 0x%08x,reg_vir_base:0x%p\n",pdev->id,lcdc_dev->reg_phy_base, lcdc_dev->regs);
1444 lcdc_dev->driver.dev = dev;
1445 lcdc_dev->driver.screen0 = screen;
1446 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& defined(CONFIG_RK610_LVDS)
1447 lcdc_dev->driver.screen1 = screen1;
1449 lcdc_dev->driver.cur_screen = screen;
1450 lcdc_dev->driver.screen_ctr_info = screen_ctr_info;
1452 spin_lock_init(&lcdc_dev->reg_lock);
1454 lcdc_dev->irq = platform_get_irq(pdev, 0);
1455 if(lcdc_dev->irq < 0)
1457 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",lcdc_dev->id);
1460 ret = devm_request_irq(dev,lcdc_dev->irq, rk3188_lcdc_isr, IRQF_DISABLED,dev_name(dev),lcdc_dev);
1463 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n", lcdc_dev->irq, ret);
1468 if(screen_ctr_info->set_screen_info)
1470 screen_ctr_info->set_screen_info(screen,screen_ctr_info->lcd_info);
1471 if(SCREEN_NULL==screen->type)
1473 printk(KERN_WARNING "no display device on lcdc%d!?\n",lcdc_dev->id);
1476 if(screen_ctr_info->io_init)
1477 screen_ctr_info->io_init(NULL);
1481 printk(KERN_WARNING "no display device on lcdc%d!?\n",lcdc_dev->id);
1486 ret = rk_fb_register(&(lcdc_dev->driver),&lcdc_driver,lcdc_dev->id);
1489 dev_err(dev,"register fb for lcdc%d failed!\n",lcdc_dev->id);
1493 printk("rk3188 lcdc%d probe ok!\n",lcdc_dev->id);
1499 iounmap(lcdc_dev->regs);
1501 release_mem_region(lcdc_dev->reg_phy_base,lcdc_dev->len);
1505 platform_set_drvdata(pdev, NULL);
1510 static int __devexit rk3188_lcdc_remove(struct platform_device *pdev)
1515 static void rk3188_lcdc_shutdown(struct platform_device *pdev)
1517 struct rk3188_lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
1518 if(lcdc_dev->driver.cur_screen->standby) //standby the screen if necessary
1519 lcdc_dev->driver.cur_screen->standby(1);
1520 if(lcdc_dev->driver.screen_ctr_info->io_disable) //power off the screen if necessary
1521 lcdc_dev->driver.screen_ctr_info->io_disable();
1522 if(lcdc_dev->driver.cur_screen->sscreen_set) //turn off lvds if necessary
1523 lcdc_dev->driver.cur_screen->sscreen_set(lcdc_dev->driver.cur_screen , 0);
1524 rk3188_lcdc_deint(lcdc_dev);
1525 rk_fb_unregister(&(lcdc_dev->driver));
1527 static struct platform_driver rk3188_lcdc_driver = {
1528 .probe = rk3188_lcdc_probe,
1529 .remove = __devexit_p(rk3188_lcdc_remove),
1531 .name = "rk30-lcdc",
1532 .owner = THIS_MODULE,
1534 .suspend = rk3188_lcdc_suspend,
1535 .resume = rk3188_lcdc_resume,
1536 .shutdown = rk3188_lcdc_shutdown,
1538 static int __init rk3188_lcdc_module_init(void)
1540 return platform_driver_register(&rk3188_lcdc_driver);
1543 static void __exit rk3188_lcdc_module_exit(void)
1545 platform_driver_unregister(&rk3188_lcdc_driver);
1547 fs_initcall(rk3188_lcdc_module_init);
1548 module_exit(rk3188_lcdc_module_exit);