rk2928:add scaler register config
authoryxj <yxj@rock-chips.com>
Thu, 9 Aug 2012 10:38:21 +0000 (18:38 +0800)
committeryxj <yxj@rock-chips.com>
Wed, 29 Aug 2012 07:45:26 +0000 (15:45 +0800)
drivers/video/rockchip/chips/rk2928_lcdc.c
drivers/video/rockchip/chips/rk2928_lcdc.h

index e7dfdd262f6d538ef2becbe043ab13238680ff97..f5977adece4f33b3c840a862be57dbc70442d829 100755 (executable)
@@ -48,24 +48,17 @@ static int init_rk2928_lcdc(struct rk_lcdc_device_driver *dev_drv)
        struct rk2928_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk2928_lcdc_device,driver);
        if(lcdc_dev->id == 0) //lcdc0
        {
-               lcdc_dev->pd = clk_get(NULL,"pd_lcdc0");
                lcdc_dev->hclk = clk_get(NULL,"hclk_lcdc0"); 
                lcdc_dev->aclk = clk_get(NULL,"aclk_lcdc0");
                lcdc_dev->dclk = clk_get(NULL,"dclk_lcdc0");
-       }
-       else if(lcdc_dev->id == 1)
-       {
-               lcdc_dev->pd = clk_get(NULL,"pd_lcdc1");
-               lcdc_dev->hclk = clk_get(NULL,"hclk_lcdc1");  
-               lcdc_dev->aclk = clk_get(NULL,"aclk_lcdc1");
-               lcdc_dev->dclk = clk_get(NULL,"dclk_lcdc1");
+               lcdc_dev->sclk = clk_get(NULL,"sclk_lcdc0");
        }
        else
        {
                printk(KERN_ERR "invalid lcdc device!\n");
                return -EINVAL;
        }
-       if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||(IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk)))
+       if (IS_ERR(lcdc_dev->sclk) || (IS_ERR(lcdc_dev->aclk)) ||(IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk)))
        {
                        printk(KERN_ERR "failed to get lcdc%d clk source\n",lcdc_dev->id);
        }
@@ -206,6 +199,27 @@ static int rk2928_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initsc
                      v_VERPRD(screen->vsync_len + screen->upper_margin + y_res + lower_margin));
                LcdWrReg(lcdc_dev, DSP_VACT_ST_END,  v_VAEP(screen->vsync_len + screen->upper_margin+y_res)|
                      v_VASP(screen->vsync_len + screen->upper_margin));
+
+
+               //set register for scaller
+               LcdMskReg(lcdc_dev,SCL_REG0,m_SCL_DSP_ZERO | m_SCL_DEN_INVERT |
+                       m_SCL_SYNC_INVERT | m_SCL_DCLK_INVERT | m_SCL_EN,v_SCL_DSP_ZERO(0) |
+                       v_SCL_DEN_INVERT(screen->pin_den) | v_SCL_SYNC_INVERT(screen->pin_hsync) |
+                       v_SCL_DCLK_INVERT(screen->pin_dclk) | v_SCL_EN(1));
+               LcdWrReg(lcdc_dev,SCL_REG2,v_HASP(0) | v_HAEP(0));
+               LcdWrReg(lcdc_dev,SCL_REG3,v_HASP(screen->hsync_len + screen->left_margin + x_res) |
+                        v_HAEP(screen->hsync_len + screen->left_margin + x_res + right_margin));
+               LcdWrReg(lcdc_dev,SCL_REG4,v_HASP(screen->hsync_len + screen->left_margin) |
+                        v_HAEP(screen->hsync_len + screen->left_margin + x_res + right_margin));
+               LcdWrReg(lcdc_dev,SCL_REG5,v_VASP(screen->vsync_len + screen->upper_margin+y_res) |
+                        v_VAEP(screen->vsync_len + screen->upper_margin + y_res + lower_margin));
+               LcdWrReg(lcdc_dev,SCL_REG6,v_VASP(screen->vsync_len + screen->upper_margin+y_res) |
+                        v_VAEP(screen->vsync_len + screen->upper_margin + y_res + lower_margin));
+               LcdWrReg(lcdc_dev,SCL_REG8,v_VASP(screen->vsync_len + screen->upper_margin+y_res) |
+                        v_VAEP(screen->vsync_len + screen->upper_margin + y_res));
+               LcdWrReg(lcdc_dev,SCL_REG7,v_HASP(screen->hsync_len + screen->left_margin) |
+                        v_HAEP(screen->hsync_len + screen->left_margin + x_res ));
+               LcdWrReg(lcdc_dev,SCL_REG1,v_SCL_V_FACTOR(0x1000)|v_SCL_H_FACTOR(0x1000));
                // let above to take effect
                LCDC_REG_CFG_DONE();
        }
@@ -216,8 +230,14 @@ static int rk2928_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initsc
        {
                printk(KERN_ERR ">>>>>> set lcdc%d dclk failed\n",lcdc_dev->id);
        }
+       ret = clk_set_rate(lcdc_dev->sclk, screen->pixclock);
+       if(ret)
+       {
+               printk(KERN_ERR ">>>>>> set lcdc%d sclk 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);
+       clk_enable(lcdc_dev->sclk);
        
        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)*
@@ -442,7 +462,7 @@ static  int win0_set_par(struct rk2928_lcdc_device *lcdc_dev,rk_screen *screen,
                                LcdMskReg(lcdc_dev, WIN_VIR,m_WIN0_VIR,v_WIN0_RGB888_VIRWIDTH(xvir));
                                break;
                }
-
+               
                LCDC_REG_CFG_DONE();
        }
        spin_unlock(&lcdc_dev->reg_lock);
index 826828f25091f4335ff43193b3146cc96fc67ff2..6c9d46cf6befba5666481a1aac1d0dcc5d7fc738 100755 (executable)
@@ -385,6 +385,72 @@ typedef volatile struct tagLCDC_REG
 #define v_W0_CBR_VSP_OFFSET(x)   (((x)&0xff)<<24)
 
 
+//LCDC_SCL_REG0
+#define m_SCL_DSP_ZERO                  (1<<4)
+#define m_SCL_DEN_INVERT        (1<<3)
+#define m_SCL_SYNC_INVERT       (1<<2)
+#define m_SCL_DCLK_INVERT       (1<<1)
+#define m_SCL_EN                (1<<0)
+#define v_SCL_DSP_ZERO(x)       (((x)&1)<<4)
+#define v_SCL_DEN_INVERT(x)     (((x)&1)<<3)
+#define v_SCL_SYNC_INVERT(x)    (((x)&1)<<2)
+#define v_SCL_DCLK_INVERT(x)    (((x)&1)<<1)
+#define v_SCL_EN(x)             (((x)&1)<<0)
+
+//LCDC_SCL_REG1
+#define m_SCL_V_FACTOR                  (0x3fff<<16)
+#define m_SCL_H_FACTOR          (0x3fff<<0)
+#define v_SCL_V_FACTOR(x)               (((x)&0x3fff)<<16)
+#define v_SCL_H_FACTOR(x)               (((x)&0x3fff)<<0)
+
+
+//LCDC_SCL_REG2
+#define m_SCL_DSP_FRAME_VST    (0xfff<<16)
+#define m_SCL_DSP_FRAME_HST    (0xfff<<0)
+#define v_SCL_DSP_FRAME_VST(x) (((x)&0xfff)<<16)
+#define v_SCL_DSP_FRAME_HST(x) (((x)&0xfff)<<0)
+
+//LCDC_SCL_REG3
+#define m_SCL_DSP_HS_END       (0xff<<16)
+#define m_SCL_DSP_HTOTAL       (0xfff<<0)
+#define v_SCL_DSP_HS_END(x)    (((x)&0xff)<<16)
+#define v_SCL_DSP_HTOTAL(x)    (((x)&0xfff)<<0)
+
+//LCDC_SCL_REG4
+#define m_SCL_DSP_HACT_ST      (0x3ff<<16)
+#define m_SCL_DSP_HACT_END     (0xfff<<0)
+#define v_SCL_DSP_HACT_ST(x)   (((x)&0x3ff)<<16)
+#define v_SCL_DSP_HACT_END(x)  (((x)&0xfff)<<0)
+
+//LCDC_SCL_REG5
+#define m_SCL_DSP_VS_END       (0xff<<16)
+#define m_SCL_DSP_VTOTAL       (0xfff<<0)
+#define v_SCL_DSP_VS_END(x)    (((x)&0xff)<<16)
+#define v_SCL_DSP_VTOTAL(x)    (((x)&0xfff)<<0)
+
+//LCDC_SCL_REG6
+#define m_SCL_DSP_VACT_ST      (0xff<<16)
+#define m_SCL_DSP_VACT_END     (0xfff<<0)
+#define v_SCL_DSP_VACT_ST(x)   (((x)&0xff)<<16)
+#define v_SCL_DSP_VACT_END(x)  (((x)&0xfff)<<0)
+
+
+//LCDC_SCL_REG7
+#define m_SCL_DSP_HBOR_ST      (0x3ff<<16)
+#define m_SCL_DSP_HBOR_END     (0xfff<<0)
+#define v_SCL_DSP_HBOR_ST(x)   (((x)&0x3ff)<<16)
+#define v_SCL_DSP_HBOR_END(x)  (((x)&0xfff)<<0)
+
+//LCDC_SCL_REG8
+
+#define m_SCL_DSP_VBOR_ST      (0xff<<16)
+#define m_SCL_DSP_VBOR_END     (0xfff<<0)
+#define v_SCL_DSP_VBOR_ST(x)   (((x)&0xff)<<16)
+#define v_SCL_DSP_VBOR_END(x)  (((x)&0xfff)<<0)
+
+
+
+
 
 #define CalScale(x, y)              (((u32)x*0x1000)/y)
 struct rk2928_lcdc_device{
@@ -407,6 +473,7 @@ struct rk2928_lcdc_device{
        struct clk              *hclk;                          //lcdc AHP clk
        struct clk              *dclk;                          //lcdc dclk
        struct clk              *aclk;                          //lcdc share memory frequency
+       struct clk              *sclk;                          //scale clk
        struct clk              *aclk_parent;           //lcdc aclk divider frequency source
        struct clk              *aclk_ddr_lcdc;         //DDR LCDC AXI clock disable.
        struct clk              *aclk_disp_matrix;      //DISPLAY matrix AXI clock disable.