#define DBG(level,x...) do { if(unlikely(dbg_thresd >= level)) printk(KERN_INFO x); } while (0)
+static int rk3066b_lcdc_clk_enable(struct rk3066b_lcdc_device *lcdc_dev)
+{
+
+ clk_enable(lcdc_dev->hclk);
+ clk_enable(lcdc_dev->dclk);
+ clk_enable(lcdc_dev->aclk);
+ clk_enable(lcdc_dev->pd);
+
+ spin_lock(&lcdc_dev->reg_lock);
+ lcdc_dev->clk_on = 1;
+ spin_unlock(&lcdc_dev->reg_lock);
+ printk("rk3066b lcdc%d clk enable...\n",lcdc_dev->id);
+
+ return 0;
+}
+
+static int rk3066b_lcdc_clk_disable(struct rk3066b_lcdc_device *lcdc_dev)
+{
+ spin_lock(&lcdc_dev->reg_lock);
+ lcdc_dev->clk_on = 0;
+ spin_unlock(&lcdc_dev->reg_lock);
+ mdelay(25);
+ clk_disable(lcdc_dev->dclk);
+ clk_disable(lcdc_dev->hclk);
+ clk_disable(lcdc_dev->aclk);
+ clk_disable(lcdc_dev->pd);
+ printk("rk3066b lcdc%d clk disable...\n",lcdc_dev->id);
+
+ return 0;
+}
+
+static int rk3066b_lcdc_reg_resume(struct rk3066b_lcdc_device *lcdc_dev)
+{
+ memcpy((u8*)lcdc_dev->preg, (u8*)&lcdc_dev->regbak, 0x9C);
+ return 0;
+}
+
static int init_rk3066b_lcdc(struct rk_lcdc_device_driver *dev_drv)
{
+ int i=0;
+ int __iomem *c;
+ int v;
+
struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
+
if(lcdc_dev->id == 0) //lcdc0
{
lcdc_dev->pd = clk_get(NULL,"pd_lcdc0");
{
printk(KERN_ERR "failed to get lcdc%d clk source\n",lcdc_dev->id);
}
- clk_enable(lcdc_dev->pd);
- clk_enable(lcdc_dev->hclk); //enable aclk and hclk for register config
- clk_enable(lcdc_dev->aclk);
- lcdc_dev->clk_on = 1;
+
+ rk3066b_lcdc_clk_enable(lcdc_dev);
+
+ if(lcdc_dev->id == 0)
+ {
+ #if defined(CONFIG_RK3066B_LCDC0_IO_18V)
+ v = 0x40004000; //bit14: 1,1.8v;0,3.3v
+ writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
+ #else
+ v = 0x40000000;
+ writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
+ #endif
+ }
if(lcdc_dev->id == 1) //iomux for lcdc1
{
- rk30_mux_api_set(GPIO2D0_LCDC1DCLK_SMCCSN0_NAME,GPIO2D_LCDC1DCLK);
- rk30_mux_api_set(GPIO2D1_LCDC1DEN_SMCWEN_NAME,GPIO2D_LCDC1DEN);
- rk30_mux_api_set(GPIO2D2_LCDC1HSYNC_SMCOEN_NAME,GPIO2D_LCDC1HSYNC);
- rk30_mux_api_set(GPIO2D3_LCDC1VSYNC_SMCADVN_NAME,GPIO2D_LCDC1VSYNC);
- rk30_mux_api_set(GPIO2A0_LCDC1DATA0_SMCDATA0_TRACEDATA0_NAME,GPIO2A_LCDC1DATA0);
- rk30_mux_api_set(GPIO2A1_LCDC1DATA1_SMCDATA1_TRACEDATA1_NAME,GPIO2A_LCDC1DATA1);
- rk30_mux_api_set(GPIO2A2_LCDC1DATA2_SMCDATA2_TRACEDATA2_NAME,GPIO2A_LCDC1DATA2);
- rk30_mux_api_set(GPIO2A3_LCDC1DATA3_SMCDATA3_TRACEDATA3_NAME,GPIO2A_LCDC1DATA3);
- rk30_mux_api_set(GPIO2A4_LCDC1DATA4_SMCDATA4_TRACEDATA4_NAME,GPIO2A_LCDC1DATA4);
- rk30_mux_api_set(GPIO2A5_LCDC1DATA5_SMCDATA5_TRACEDATA5_NAME,GPIO2A_LCDC1DATA5);
- rk30_mux_api_set(GPIO2A6_LCDC1DATA6_SMCDATA6_TRACEDATA6_NAME,GPIO2A_LCDC1DATA6);
- rk30_mux_api_set(GPIO2A7_LCDC1DATA7_SMCDATA7_TRACEDATA7_NAME,GPIO2A_LCDC1DATA7);
- rk30_mux_api_set(GPIO2B0_LCDC1DATA8_SMCDATA8_TRACEDATA8_NAME,GPIO2B_LCDC1DATA8);
- rk30_mux_api_set(GPIO2B1_LCDC1DATA9_SMCDATA9_TRACEDATA9_NAME,GPIO2B_LCDC1DATA9);
- rk30_mux_api_set(GPIO2B2_LCDC1DATA10_SMCDATA10_TRACEDATA10_NAME,GPIO2B_LCDC1DATA10);
- rk30_mux_api_set(GPIO2B3_LCDC1DATA11_SMCDATA11_TRACEDATA11_NAME,GPIO2B_LCDC1DATA11);
- rk30_mux_api_set(GPIO2B4_LCDC1DATA12_SMCDATA12_TRACEDATA12_NAME,GPIO2B_LCDC1DATA12);
- rk30_mux_api_set(GPIO2B5_LCDC1DATA13_SMCDATA13_TRACEDATA13_NAME,GPIO2B_LCDC1DATA13);
- rk30_mux_api_set(GPIO2B6_LCDC1DATA14_SMCDATA14_TRACEDATA14_NAME,GPIO2B_LCDC1DATA14);
- rk30_mux_api_set(GPIO2B7_LCDC1DATA15_SMCDATA15_TRACEDATA15_NAME,GPIO2B_LCDC1DATA15);
- rk30_mux_api_set(GPIO2C0_LCDC1DATA16_SMCADDR0_TRACECLK_NAME,GPIO2C_LCDC1DATA16);
- rk30_mux_api_set(GPIO2C1_LCDC1DATA17_SMCADDR1_TRACECTL_NAME,GPIO2C_LCDC1DATA17);
- rk30_mux_api_set(GPIO2C2_LCDC1DATA18_SMCADDR2_NAME,GPIO2C_LCDC1DATA18);
- rk30_mux_api_set(GPIO2C3_LCDC1DATA19_SMCADDR3_NAME,GPIO2C_LCDC1DATA19);
- rk30_mux_api_set(GPIO2C4_LCDC1DATA20_SMCADDR4_NAME,GPIO2C_LCDC1DATA20);
- rk30_mux_api_set(GPIO2C5_LCDC1DATA21_SMCADDR5_NAME,GPIO2C_LCDC1DATA21);
- rk30_mux_api_set(GPIO2C6_LCDC1DATA22_SMCADDR6_NAME,GPIO2C_LCDC1DATA22);
- rk30_mux_api_set(GPIO2C7_LCDC1DATA23_SMCADDR7_NAME,GPIO2C_LCDC1DATA23);
+ #if defined(CONFIG_RK3066B_LCDC1_IO_18V)
+ v = 0x80008000; //bit14: 1,1.8v;0,3.3v
+ writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
+ #else
+ v = 0x80000000;
+ writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4);
+ #endif
+
+ iomux_set(LCDC1_DCLK);
+ iomux_set(LCDC1_DEN);
+ iomux_set(LCDC1_HSYNC);
+ iomux_set(LCDC1_VSYNC);
+ iomux_set(LCDC1_D0);
+ iomux_set(LCDC1_D1);
+ iomux_set(LCDC1_D2);
+ iomux_set(LCDC1_D3);
+ iomux_set(LCDC1_D4);
+ iomux_set(LCDC1_D5);
+ iomux_set(LCDC1_D6);
+ iomux_set(LCDC1_D7);
+ iomux_set(LCDC1_D8);
+ iomux_set(LCDC1_D9);
+ iomux_set(LCDC1_D10);
+ iomux_set(LCDC1_D11);
+ iomux_set(LCDC1_D12);
+ iomux_set(LCDC1_D13);
+ iomux_set(LCDC1_D14);
+ iomux_set(LCDC1_D15);
+ iomux_set(LCDC1_D16);
+ iomux_set(LCDC1_D17);
+ iomux_set(LCDC1_D18);
+ iomux_set(LCDC1_D19);
+ iomux_set(LCDC1_D20);
+ iomux_set(LCDC1_D21);
+ iomux_set(LCDC1_D22);
+ iomux_set(LCDC1_D23);
}
LcdMskReg(lcdc_dev,SYS_CFG, m_LCDC_AXICLK_AUTO_ENABLE | m_W0_AXI_OUTSTANDING2 |
v_SCANNING_MASK(1)); //mask all interrupt in init
LcdMskReg(lcdc_dev,FIFO_WATER_MARK,m_WIN1_FIFO_FULL_LEVEL,v_WIN1_FIFO_FULL_LEVEL(0x1e0));
//LCDC_REG_CFG_DONE(); // write any value to REG_CFG_DONE let config become effective
+ if(dev_drv->cur_screen->dsp_lut) //resume dsp lut
+ {
+ LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
+ LCDC_REG_CFG_DONE();
+
+ mdelay(25); //wait for dsp lut disabled
+ for(i=0;i<256;i++)
+ {
+ v = dev_drv->cur_screen->dsp_lut[i];
+ c = lcdc_dev->dsp_lut_addr_base+i;
+ writel_relaxed(v,c);
+ }
+ LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));//enable dsp lut
+ }
+
+ rk3066b_lcdc_clk_disable(lcdc_dev);
return 0;
}
v_DEN_POLARITY(screen->pin_den) | v_DCLK_POLARITY(screen->pin_dclk));
//set background color to black,set swap according to the screen panel,disable blank mode
- LcdMskReg(lcdc_dev, DSP_CTRL1, m_BG_COLOR | m_OUTPUT_RB_SWAP | m_OUTPUT_RG_SWAP | m_DELTA_SWAP |
- m_DUMMY_SWAP | m_BLANK_MODE,v_BG_COLOR(0x000000) | v_OUTPUT_RB_SWAP(screen->swap_rb) |
- v_OUTPUT_RG_SWAP(screen->swap_rg) | v_DELTA_SWAP(screen->swap_delta) | v_DUMMY_SWAP(screen->swap_dumy) |
- v_BLACK_MODE(0));
-
-
+ LcdMskReg(lcdc_dev,DSP_CTRL1,m_BLANK_MODE | m_BLACK_MODE | m_BG_COLOR, v_BLANK_MODE(0) |
+ v_BLACK_MODE(0) | v_BG_COLOR(0x000000));
+ LcdMskReg(lcdc_dev,SWAP_CTRL,m_OUTPUT_RB_SWAP | m_OUTPUT_RG_SWAP | m_DELTA_SWAP | m_DUMMY_SWAP,
+ v_OUTPUT_RB_SWAP(screen->swap_rb) | v_OUTPUT_RG_SWAP(screen->swap_rg) |
+ v_DELTA_SWAP(screen->swap_delta) | v_DUMMY_SWAP(screen->swap_dumy));
LcdWrReg(lcdc_dev, DSP_HTOTAL_HS_END,v_HSYNC(screen->hsync_len) |
v_HORPRD(screen->hsync_len + screen->left_margin + x_res + right_margin));
LcdWrReg(lcdc_dev, DSP_HACT_ST_END, v_HAEP(screen->hsync_len + screen->left_margin + x_res) |
printk(KERN_ERR ">>>>>> set lcdc%d dclk failed\n",lcdc_dev->id);
}
lcdc_dev->driver.pixclock = lcdc_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
- clk_enable(lcdc_dev->dclk);
+
ft = (u64)(screen->upper_margin + screen->lower_margin + screen->y_res +screen->vsync_len)*
(screen->left_margin + screen->right_margin + screen->x_res + screen->hsync_len)*
{
screen->init();
}
- if(screen->sscreen_set)
- {
- screen->sscreen_set(screen,!initscreen);
- }
printk("%s for lcdc%d ok!\n",__func__,lcdc_dev->id);
return 0;
}
u32 ScaleCbrX = 0x1000;
u32 ScaleCbrY = 0x1000;
u8 fmt_cfg =0 ; //data format register config value
-
+ char fmt[9] = "NULL";
xact = par->xact; //active (origin) picture window width/height
yact = par->yact;
xvir = par->xvir; // virtual resolution
xpos = par->xpos+screen->left_margin + screen->hsync_len;
ypos = par->ypos+screen->upper_margin + screen->vsync_len;
+ 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",
+ __func__,lcdc_dev->id,get_format_string(par->format,fmt),xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
ScaleYrgbX = CalScale(xact, par->xsize); //both RGB and yuv need this two factor
ScaleYrgbY = CalScale(yact, par->ysize);
switch (par->format)
{
+ case XBGR888:
+ case ABGR888:
case ARGB888:
fmt_cfg = 0;
break;
ScaleCbrY = CalScale(yact, par->ysize);
break;
default:
+ printk("%s:un supported format\n",__func__);
break;
}
- 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",
- __func__,lcdc_dev->id,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
spin_lock(&lcdc_dev->reg_lock);
if(likely(lcdc_dev->clk_on))
{
u32 xact, yact, xvir, yvir, xpos, ypos;
u8 fmt_cfg;
-
+ char fmt[9]="NULL";
xact = par->xact;
yact = par->yact;
xvir = par->xvir;
ypos = par->ypos+screen->upper_margin + screen->vsync_len;
- 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",
- __func__,lcdc_dev->id,par->format,xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
+ 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",
+ __func__,lcdc_dev->id,get_format_string(par->format,fmt),xact,yact,par->xsize,par->ysize,xvir,yvir,xpos,ypos);
spin_lock(&lcdc_dev->reg_lock);
{
switch (par->format)
{
+ case XBGR888:
+ case ABGR888:
case ARGB888:
fmt_cfg = 0;
break;
fmt_cfg = 1;
break;
default:
+ printk("%s:un supported format\n",__func__);
break;
}
LcdWrReg(lcdc_dev, WIN1_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
LcdWrReg(lcdc_dev, WIN1_DSP_INFO,v_DSP_WIDTH(par->xsize) | v_DSP_HEIGHT(par->ysize));
// enable win1 color key and set the color to black(rgb=0)
- LcdMskReg(lcdc_dev,WIN1_COLOR_KEY_CTRL, m_COLORKEY_EN | m_KEYCOLOR,v_COLORKEY_EN(0) | v_KEYCOLOR(0));
+ LcdMskReg(lcdc_dev,WIN1_COLOR_KEY_CTRL, m_COLORKEY_EN | m_KEYCOLOR,v_COLORKEY_EN(1) | v_KEYCOLOR(0));
LcdWrReg(lcdc_dev,WIN1_VIR,v_VIRWIDTH(xvir));
//LCDC_REG_CFG_DONE();
static int rk3066b_lcdc_open(struct rk_lcdc_device_driver *dev_drv,int layer_id,bool open)
{
+ int i=0;
+ int __iomem *c;
+ int v;
struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
+
+ if((open) && (!lcdc_dev->atv_layer_cnt)) //enable clk,when first layer open
+ {
+ rk3066b_lcdc_clk_enable(lcdc_dev);
+ rk3066b_lcdc_reg_resume(lcdc_dev); //resume reg
+ LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
+ rk3066b_load_screen(dev_drv,1);
+ spin_lock(&lcdc_dev->reg_lock);
+ if(dev_drv->cur_screen->dsp_lut) //resume dsp lut
+ {
+ LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
+ LCDC_REG_CFG_DONE();
+
+ mdelay(25); //wait for dsp lut disabled
+ for(i=0;i<256;i++)
+ {
+ v = dev_drv->cur_screen->dsp_lut[i];
+ c = lcdc_dev->dsp_lut_addr_base+i;
+ writel_relaxed(v,c);
+ }
+ LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));//enable dsp lut
+ }
+ spin_unlock(&lcdc_dev->reg_lock);
+ }
if(layer_id == 0)
{
win0_open(lcdc_dev,open);
{
win1_open(lcdc_dev,open);
}
-
+
+ if((!open) && (!lcdc_dev->atv_layer_cnt)) //when all layer closed,disable clk
+ {
+ LcdMskReg(lcdc_dev, INT_STATUS, m_FRM_STARTCLEAR, v_FRM_STARTCLEAR(1));
+ LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(1));
+ LCDC_REG_CFG_DONE();
+ rk3066b_lcdc_clk_disable(lcdc_dev);
+ }
return 0;
}
if((dev_drv->first_frame)) //this is the first frame of the system ,enable frame start interrupt
{
dev_drv->first_frame = 0;
- LcdMskReg(lcdc_dev,INT_STATUS,m_FRM_STARTCLEAR | m_FRM_STARTMASK ,
- v_FRM_STARTCLEAR(1) | v_FRM_STARTMASK(0));
+ LcdMskReg(lcdc_dev,INT_STATUS,m_HOR_STARTMASK | m_FRM_STARTMASK | m_SCANNING_MASK |
+ m_HOR_STARTCLEAR | m_FRM_STARTCLEAR |m_SCANNING_CLEAR | m_SCAN_LINE_NUM,
+ v_HOR_STARTMASK(1) | v_FRM_STARTMASK(0) | v_SCANNING_MASK(0) |
+ v_HOR_STARTCLEAR(1) | v_FRM_STARTCLEAR(1) | v_SCANNING_CLEAR(1) |
+ //v_SCANNING_CLEAR(screen->vsync_len + screen->upper_margin+screen->y_res -1));
+ v_SCAN_LINE_NUM(screen->vsync_len + screen->upper_margin+screen->y_res -1));
LCDC_REG_CFG_DONE(); // write any value to REG_CFG_DONE let config become effective
}
+#if 0
if(dev_drv->num_buf < 3) //3buffer ,no need to wait for sysn
{
spin_lock_irqsave(&dev_drv->cpl_lock,flags);
return -ETIMEDOUT;
}
}
+#endif
return 0;
}
int ret = 0;
switch(cmd)
{
- case FBIOGET_PANEL_SIZE: //get panel size
+ case RK_FBIOGET_PANEL_SIZE: //get panel size
panel_size[0] = lcdc_dev->screen->x_res;
panel_size[1] = lcdc_dev->screen->y_res;
if(copy_to_user(argp, panel_size, 8))
{
struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
- return 0;
+ char format_w0[9]= "NULL";
+ char format_w1[9]= "NULL";
+ char status_w0[9]= "NULL";
+ char status_w1[9]= "NULL";
+ u32 fmt_id = LcdRdReg(lcdc_dev,SYS_CFG);
+ u32 act_info,dsp_info,dsp_st,factor;
+ u16 xvir_w0,x_act_w0,y_act_w0,x_dsp_w0,y_dsp_w0,x_st_w0,y_st_w0;
+ u16 xvir_w1,x_dsp_w1,y_dsp_w1,x_st_w1,y_st_w1;
+ u16 x_scale,y_scale;
+ int ovl = LcdReadBit(lcdc_dev,DSP_CTRL0,m_W0W1_POSITION_SWAP);
+
+ switch((fmt_id&m_W0_FORMAT)>>3)
+ {
+ case 0:
+ strcpy(format_w0,"ARGB888");
+ break;
+ case 1:
+ strcpy(format_w0,"RGB565");
+ break;
+ case 2:
+ strcpy(format_w0,"YCbCr422");
+ break;
+ case 3:
+ strcpy(format_w0,"YCbCr420");
+ break;
+ case 5:
+ strcpy(format_w0,"YCbCr444");
+ break;
+ default:
+ strcpy(format_w0,"invalid\n");
+ break;
+ }
+
+ switch((fmt_id&m_W1_FORMAT)>>2)
+ {
+ case 0:
+ strcpy(format_w1,"ARGB888");
+ break;
+ case 1:
+ strcpy(format_w1,"RGB565");
+ break;
+ default:
+ strcpy(format_w1,"invalid\n");
+ break;
+ }
+
+ if((fmt_id&m_W0_EN)>>11)
+ {
+ strcpy(status_w0,"enabled");
+ }
+ else
+ {
+ strcpy(status_w0,"disabled");
+ }
+
+ if((fmt_id&m_W1_EN)>>10)
+ {
+ strcpy(status_w1,"enabled");
+ }
+ else
+ {
+ strcpy(status_w1,"disabled");
+ }
+
+ xvir_w0 = LcdRdReg(lcdc_dev,WIN0_VIR)&0xffff;
+ act_info = LcdRdReg(lcdc_dev,WIN0_ACT_INFO);
+ dsp_info = LcdRdReg(lcdc_dev,WIN0_DSP_INFO);
+ dsp_st = LcdRdReg(lcdc_dev,WIN0_DSP_ST);
+ factor = LcdRdReg(lcdc_dev,WIN0_SCL_FACTOR_YRGB);
+ x_act_w0 = (act_info&0xffff);
+ y_act_w0 = (act_info>>16);
+ x_dsp_w0 = (dsp_info&0x7ff);
+ y_dsp_w0 = (dsp_info>>16);
+ x_scale = 4096*100/(factor&0xffff);
+ y_scale = 4096*100/(factor>>16);
+ x_st_w0 = dsp_st&0xffff;
+ y_st_w0 = dsp_st>>16;
+
+
+ xvir_w1 = LcdRdReg(lcdc_dev,WIN1_VIR)&0xffff;
+ dsp_info = LcdRdReg(lcdc_dev,WIN1_DSP_INFO);
+ dsp_st = LcdRdReg(lcdc_dev,WIN1_DSP_ST);
+ x_dsp_w1 = dsp_info&0x7ff;
+ y_dsp_w1 = dsp_info>>16;
+ x_st_w1 = dsp_st&0xffff;
+ y_st_w1 = dsp_st>>16;
+
+ return snprintf(buf,PAGE_SIZE,
+ "win0:%s\n"
+ "xvir:%d\n"
+ "xact:%d\n"
+ "yact:%d\n"
+ "xdsp:%d\n"
+ "ydsp:%d\n"
+ "x_st:%d\n"
+ "y_st:%d\n"
+ "x_scale:%d.%d\n"
+ "y_scale:%d.%d\n"
+ "format:%s\n"
+ "YRGB buffer addr:0x%08x\n"
+ "CBR buffer addr:0x%08x\n\n"
+ "win1:%s\n"
+ "xvir:%d\n"
+ "xdsp:%d\n"
+ "ydsp:%d\n"
+ "x_st:%d\n"
+ "y_st:%d\n"
+ "format:%s\n"
+ "YRGB buffer addr:0x%08x\n"
+ "overlay:%s\n",
+ status_w0,
+ xvir_w0,
+ x_act_w0,
+ y_act_w0,
+ x_dsp_w0,
+ y_dsp_w0,
+ x_st_w0,
+ y_st_w0,
+ x_scale/100,
+ x_scale%100,
+ y_scale/100,
+ y_scale%100,
+ format_w0,
+ LcdRdReg(lcdc_dev,WIN0_YRGB_MST),
+ LcdRdReg(lcdc_dev,WIN0_CBR_MST),
+ status_w1,
+ xvir_w1,
+ x_dsp_w1,
+ y_dsp_w1,
+ x_st_w1,
+ y_st_w1,
+ format_w1,
+ LcdRdReg(lcdc_dev,WIN1_YRGB_MST),
+ ovl ? "win0 on the top of win1\n":"win1 on the top of win0\n");
+ return 0;
}
int rk3066b_lcdc_early_suspend(struct rk_lcdc_device_driver *dev_drv)
{
struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
+
+ if(dev_drv->screen0->standby)
+ dev_drv->screen0->standby(1);
+ if(dev_drv->screen_ctr_info->io_disable)
+ dev_drv->screen_ctr_info->io_disable();
spin_lock(&lcdc_dev->reg_lock);
if(likely(lcdc_dev->clk_on))
int rk3066b_lcdc_early_resume(struct rk_lcdc_device_driver *dev_drv)
{
struct rk3066b_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3066b_lcdc_device,driver);
+ int i=0;
+ int __iomem *c;
+ int v;
+
+ if(dev_drv->screen_ctr_info->io_enable) //power on
+ dev_drv->screen_ctr_info->io_enable();
if(!lcdc_dev->clk_on)
{
memcpy(((u8*)lcdc_dev->preg) + 0x28,((u8*)&lcdc_dev->regbak) + 0x28, 0x74);
spin_lock(&lcdc_dev->reg_lock);
+
+ if(dev_drv->cur_screen->dsp_lut) //resume dsp lut
+ {
+ LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
+ LCDC_REG_CFG_DONE();
+
+ mdelay(25); //wait for dsp lut disabled
+ for(i=0;i<256;i++)
+ {
+ v = dev_drv->cur_screen->dsp_lut[i];
+ c = lcdc_dev->dsp_lut_addr_base+i;
+ writel_relaxed(v,c);
+ }
+ LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));//enable dsp lut
+ }
if(lcdc_dev->atv_layer_cnt)
{
LcdMskReg(lcdc_dev, SYS_CFG,m_LCDC_STANDBY,v_LCDC_STANDBY(0));
LcdMskReg(lcdc_dev, INT_STATUS, m_SCANNING_CLEAR | m_FRM_STARTCLEAR | m_HOR_STARTCLEAR |
m_SCANNING_MASK | m_HOR_STARTMASK | m_FRM_STARTMASK ,
v_SCANNING_CLEAR(1) | v_FRM_STARTCLEAR(1) | v_HOR_STARTCLEAR(1) |
- v_SCANNING_MASK(1) | v_FRM_STARTMASK(0) | v_HOR_STARTMASK(1));
+ v_SCANNING_MASK(0) | v_FRM_STARTMASK(0) | v_HOR_STARTMASK(1));
LCDC_REG_CFG_DONE();
}
lcdc_dev->clk_on = 1;
spin_unlock(&lcdc_dev->reg_lock);
+
+ if(!lcdc_dev->atv_layer_cnt)
+ rk3066b_lcdc_clk_disable(lcdc_dev);
+
+ if(dev_drv->screen0->standby)
+ dev_drv->screen0->standby(0); //screen wake up
return 0;
}
static irqreturn_t rk3066b_lcdc_isr(int irq, void *dev_id)
{
struct rk3066b_lcdc_device *lcdc_dev = (struct rk3066b_lcdc_device *)dev_id;
+
+ u32 int_reg = LcdRdReg(lcdc_dev,INT_STATUS);
+ if(int_reg & m_FRM_START){
+ ktime_t timestamp = ktime_get();
LcdMskReg(lcdc_dev, INT_STATUS, m_FRM_STARTCLEAR, v_FRM_STARTCLEAR(1));
- LCDC_REG_CFG_DONE();
+
//LcdMskReg(lcdc_dev, INT_STATUS, m_LINE_FLAG_INT_CLEAR, v_LINE_FLAG_INT_CLEAR(1));
-
+
+#if 0
if(lcdc_dev->driver.num_buf < 3) //three buffer ,no need to wait for sync
{
spin_lock(&(lcdc_dev->driver.cpl_lock));
complete(&(lcdc_dev->driver.frame_done));
spin_unlock(&(lcdc_dev->driver.cpl_lock));
}
+#endif
+
+ lcdc_dev->driver.vsync_info.timestamp = timestamp;
+ wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
+ }
+ else if(int_reg & m_SCANNING_FLAG){
+ LcdMskReg(lcdc_dev, INT_STATUS, m_FRM_STARTCLEAR, v_SCANNING_CLEAR(1));
+ }
return IRQ_HANDLED;
}
+
+static int rk3066b_set_dsp_lut(struct rk_lcdc_device_driver *dev_drv,int *lut)
+{
+ int i=0;
+ int __iomem *c;
+ int v;
+ int ret = 0;
+
+ struct rk3066b_lcdc_device *lcdc_dev =
+ container_of(dev_drv,struct rk3066b_lcdc_device,driver);
+ LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(0));
+ LCDC_REG_CFG_DONE();
+ msleep(25);
+ if(dev_drv->cur_screen->dsp_lut)
+ {
+ for(i=0;i<256;i++)
+ {
+ v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
+ c = lcdc_dev->dsp_lut_addr_base+i;
+ writel_relaxed(v,c);
+ }
+ }
+ else
+ {
+ dev_err(dev_drv->dev,"no buffer to backup lut data!\n");
+ ret = -1;
+ }
+ LcdMskReg(lcdc_dev,SYS_CFG,m_DSIP_LUT_CTL,v_DSIP_LUT_CTL(1));
+ LCDC_REG_CFG_DONE();
+
+ return ret;
+}
+
+int rk3066b_lcdc_poll_vblank(struct rk_lcdc_device_driver * dev_drv)
+{
+ struct rk3066b_lcdc_device *lcdc_dev =
+ container_of(dev_drv,struct rk3066b_lcdc_device,driver);
+ u32 int_reg ;
+ int ret;
+ //spin_lock(&lcdc_dev->reg_lock);
+ if(lcdc_dev->clk_on)
+ {
+ int_reg = LcdRdReg(lcdc_dev,INT_STATUS);
+ if(int_reg & m_SCANNING_FLAG)
+ {
+ LcdMskReg(lcdc_dev, INT_STATUS, m_SCANNING_CLEAR,v_SCANNING_CLEAR(1));
+ ret = RK_LF_STATUS_FC;
+ }
+ else
+ ret = RK_LF_STATUS_FR;
+ }
+ else
+ {
+ ret = RK_LF_STATUS_NC;
+ }
+ //spin_unlock(&lcdc_dev->reg_lock);
+
+
+ return ret;
+}
+
static struct layer_par lcdc_layer[] = {
[0] = {
.name = "win0",
.fps_mgr = rk3066b_lcdc_fps_mgr,
.fb_get_layer = rk3066b_fb_get_layer,
.fb_layer_remap = rk3066b_fb_layer_remap,
+ .set_dsp_lut = rk3066b_set_dsp_lut,
+ .poll_vblank = rk3066b_lcdc_poll_vblank,
};
#ifdef CONFIG_PM
static int rk3066b_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
screen->lcdc_id = lcdc_dev->id;
screen->screen_id = 0;
-#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& defined(CONFIG_RK610_LVDS)
+#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& (defined(CONFIG_RK610_LVDS) || defined(CONFIG_RK616_LVDS))
screen1 = kzalloc(sizeof(rk_screen), GFP_KERNEL);
if(!screen1)
{
lcdc_dev->preg = (LCDC_REG*)lcdc_dev->reg_vir_base;
printk("lcdc%d:reg_phy_base = 0x%08x,reg_vir_base:0x%p\n",pdev->id,lcdc_dev->reg_phy_base, lcdc_dev->preg);
+ lcdc_dev->dsp_lut_addr_base = (lcdc_dev->reg_vir_base+DSP_LUT_ADDR);
+
lcdc_dev->driver.dev=&pdev->dev;
lcdc_dev->driver.screen0 = screen;
-#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& defined(CONFIG_RK610_LVDS)
+#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& (defined(CONFIG_RK610_LVDS) || defined(CONFIG_RK616_LVDS))
lcdc_dev->driver.screen1 = screen1;
#endif
lcdc_dev->driver.cur_screen = screen;
ret = -EBUSY;
goto err3;
}
+
+ if(screen_ctr_info->set_screen_info)
+ {
+ screen_ctr_info->set_screen_info(screen,screen_ctr_info->lcd_info);
+ if(SCREEN_NULL==screen->type)
+ {
+ printk(KERN_WARNING "no display device on lcdc%d!?\n",lcdc_dev->id);
+ ret = -ENODEV;
+ }
+ if(screen_ctr_info->io_init)
+ screen_ctr_info->io_init(NULL);
+ }
+ else
+ {
+ printk(KERN_WARNING "no display device on lcdc%d!?\n",lcdc_dev->id);
+ ret = -ENODEV;
+ goto err4;
+ }
+
ret = rk_fb_register(&(lcdc_dev->driver),&lcdc_driver,lcdc_dev->id);
if(ret < 0)
{
lcdc_dev->driver.screen_ctr_info->io_disable();
if(lcdc_dev->driver.cur_screen->sscreen_set) //turn off lvds if necessary
lcdc_dev->driver.cur_screen->sscreen_set(lcdc_dev->driver.cur_screen , 0);
- rk_fb_unregister(&(lcdc_dev->driver));
+
rk3066b_lcdc_deinit(lcdc_dev);
+ rk_fb_unregister(&(lcdc_dev->driver));
+
/*iounmap(lcdc_dev->reg_vir_base);
release_mem_region(lcdc_dev->reg_phy_base,lcdc_dev->len);
kfree(lcdc_dev->screen);