rk30 lcdc: win2 support
authoryxj <yxj@V470.(none)>
Fri, 20 Jul 2012 06:13:27 +0000 (14:13 +0800)
committeryxj <yxj@rock-chips.com>
Wed, 29 Aug 2012 07:45:24 +0000 (15:45 +0800)
drivers/video/rockchip/chips/rk30_lcdc.c
drivers/video/rockchip/chips/rk30_lcdc.h
include/linux/rk_fb.h

index 819444db1d3fcbc812bd0615fce8d20bc155d5e0..b66560db53422fb80c4f1cc837de6bc99df9ea80 100644 (file)
@@ -310,6 +310,19 @@ static int win1_open(struct rk30_lcdc_device *lcdc_dev,bool open)
        return 0;
 }
 
+static int win2_open(struct rk30_lcdc_device *lcdc_dev,bool open)
+{
+       spin_lock(&lcdc_dev->reg_lock);
+       if(likely(lcdc_dev->clk_on))
+       {
+               LcdMskReg(lcdc_dev, SYS_CTRL1, m_W2_EN, v_W2_EN(open));
+               LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01);
+               lcdc_dev->driver.layer_par[1]->state = open;
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       printk(KERN_INFO "lcdc%d win2 %s\n",lcdc_dev->id,open?"open":"closed");
+       return 0;
+}
 
 static int rk30_lcdc_blank(struct rk_lcdc_device_driver*lcdc_drv,int layer_id,int blank_mode)
 {
@@ -380,6 +393,25 @@ static  int win1_display(struct rk30_lcdc_device *lcdc_dev,struct layer_par *par
        return 0;
 }
 
+static  int win2_display(struct rk30_lcdc_device *lcdc_dev,struct layer_par *par )
+{
+       u32 y_addr;
+       u32 uv_addr;
+       y_addr = par->smem_start + par->y_offset;
+       uv_addr = par->cbr_start + par->c_offset;
+       DBG(2,KERN_INFO "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",lcdc_dev->id,__func__,y_addr,uv_addr);
+       
+       spin_lock(&lcdc_dev->reg_lock);
+       if(likely(lcdc_dev->clk_on))
+       {
+               LcdWrReg(lcdc_dev, WIN2_MST, y_addr);
+               LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01); 
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       
+       return 0;
+}
+
 static  int win0_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen,
        struct layer_par *par )
 {
@@ -540,6 +572,65 @@ static int win1_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen,
     return 0;
 }
 
+static int win2_set_par(struct rk30_lcdc_device *lcdc_dev,rk_screen *screen,
+       struct layer_par *par )
+{
+       u32 xact, yact, xvir, yvir, xpos, ypos;
+       u32 ScaleYrgbX = 0x1000;
+       u32 ScaleYrgbY = 0x1000;
+       u32 ScaleCbrX = 0x1000;
+       u32 ScaleCbrY = 0x1000;
+       
+       xact = par->xact;                       
+       yact = par->yact;
+       xvir = par->xvir;               
+       yvir = par->yvir;
+       xpos = par->xpos+screen->left_margin + screen->hsync_len;
+       ypos = par->ypos+screen->upper_margin + screen->vsync_len;
+       
+       ScaleYrgbX = CalScale(xact, par->xsize);
+       ScaleYrgbY = CalScale(yact, par->ysize);
+       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))
+       {
+
+               LcdMskReg(lcdc_dev,SYS_CTRL1, m_W2_FORMAT, v_W2_FORMAT(par->format));
+               LcdWrReg(lcdc_dev, WIN2_DSP_ST,v_DSP_STX(xpos) | v_DSP_STY(ypos));
+               LcdWrReg(lcdc_dev, WIN2_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, WIN2_COLOR_KEY_CTRL, m_COLORKEY_EN | m_KEYCOLOR,v_COLORKEY_EN(1) | v_KEYCOLOR(0));
+               switch(par->format)
+               {
+                       case ARGB888:
+                               LcdWrReg(lcdc_dev, WIN2_VIR,v_ARGB888_VIRWIDTH(xvir));
+                               //LcdMskReg(lcdc_dev,SYS_CTRL1,m_W1_RGB_RB_SWAP,v_W1_RGB_RB_SWAP(1));
+                               break;
+                       case RGB888:  //rgb888
+                               LcdWrReg(lcdc_dev, WIN2_VIR,v_RGB888_VIRWIDTH(xvir));
+                               // LcdMskReg(lcdc_dev,SYS_CTRL1,m_W1_RGB_RB_SWAP,v_W1_RGB_RB_SWAP(1));
+                               break;
+                       case RGB565:  //rgb565
+                               LcdWrReg(lcdc_dev, WIN2_VIR,v_RGB565_VIRWIDTH(xvir));
+                               break;
+                       case YUV422:
+                       case YUV420:   
+                               LcdWrReg(lcdc_dev, WIN2_VIR,v_YUV_VIRWIDTH(xvir));
+                               break;
+                       default:
+                               LcdWrReg(lcdc_dev, WIN2_VIR,v_RGB888_VIRWIDTH(xvir));
+                               break;
+               }
+               
+               LcdWrReg(lcdc_dev, REG_CFG_DONE, 0x01); 
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+    return 0;
+}
+
 static int rk30_lcdc_open(struct rk_lcdc_device_driver *dev_drv,int layer_id,bool open)
 {
        struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
@@ -551,6 +642,10 @@ static int rk30_lcdc_open(struct rk_lcdc_device_driver *dev_drv,int layer_id,boo
        {
                win1_open(lcdc_dev,open);
        }
+       else if(layer_id == 2)
+       {
+               win2_open(lcdc_dev,open);
+       }
 
        return 0;
 }
@@ -575,6 +670,11 @@ static int rk30_lcdc_set_par(struct rk_lcdc_device_driver *dev_drv,int layer_id)
                par = dev_drv->layer_par[1];
                win1_set_par(lcdc_dev,screen,par);
        }
+       else if(layer_id == 2)
+       {
+               par = dev_drv->layer_par[2];
+               win2_set_par(lcdc_dev,screen,par);
+       }
        
        return 0;
 }
@@ -601,6 +701,11 @@ int rk30_lcdc_pan_display(struct rk_lcdc_device_driver * dev_drv,int layer_id)
                par = dev_drv->layer_par[1];
                win1_display(lcdc_dev,par);
        }
+       else if(layer_id == 2)
+       {
+               par = dev_drv->layer_par[2];
+               win2_display(lcdc_dev,par);
+       }
        if((dev_drv->first_frame))  //this is the first frame of the system ,enable frame start interrupt
        {
                dev_drv->first_frame = 0;
@@ -857,6 +962,11 @@ static struct layer_par lcdc_layer[] = {
                .id             = 1,
                .support_3d     = false,
        },
+       [2] = {
+               .name           = "win2",
+               .id             = 2,
+               .support_3d     = false,
+       },
 };
 
 static struct rk_lcdc_device_driver lcdc_driver = {
index b986c3fc330f22cf03c8ed6995bcaf8a14b0f37f..3634b2ea62ae5d0ce2b6dda656f50a09973cf5c3 100644 (file)
@@ -51,7 +51,7 @@ typedef volatile struct tagLCDC_REG
        unsigned int WIN1_SCL_FACTOR_CBR;     //0x70 Win1 YRGB scaling factor setting
        unsigned int WIN1_SCL_OFFSET;         //0x74 Win1 Cbr scaling start point offset
        unsigned int WIN2_MST;                            //0x78 win2 memort start address
-       unsigned int WIM2_VIR;                            //0x7c win2 virtual stride
+       unsigned int WIN2_VIR;                            //0x7c win2 virtual stride
        unsigned int WIN2_DSP_INFO;           //0x80 Win2 display width/height on panel
        unsigned int WIN2_DSP_ST;             //0x84 Win2 display start point on panel
        unsigned int HWC_MST;                 //0x88 HWC memory start address
index 9c1aa1518bbda8af55e9a6e12ff8bdd0cfdbc02b..e4e2db3e4429cdbce0259eb4a2d2adf4619d70f7 100644 (file)
@@ -25,7 +25,7 @@
 
 #define RK30_MAX_LCDC_SUPPORT  4
 #define RK30_MAX_LAYER_SUPPORT 4
-#define RK_MAX_FB_SUPPORT     4
+#define RK_MAX_FB_SUPPORT       8