rk2928 lvds support
authoryzq <yzq@rockchips.com>
Mon, 23 Jul 2012 09:47:06 +0000 (17:47 +0800)
committeryzq <yzq@rockchips.com>
Mon, 23 Jul 2012 10:18:49 +0000 (18:18 +0800)
drivers/video/rockchip/Kconfig
drivers/video/rockchip/Makefile
drivers/video/rockchip/chips/rk2928_lcdc.c
drivers/video/rockchip/lvds/Kconfig [new file with mode: 0755]
drivers/video/rockchip/lvds/Makefile [new file with mode: 0755]
drivers/video/rockchip/lvds/rk_lvds.c [new file with mode: 0644]
drivers/video/rockchip/lvds/rk_lvds.h [new file with mode: 0644]

index 04ba7263c5acc56696d24c892fb23db294f01a41..267b5b5a222ec359bd7e1af91e9eed22e443e667 100755 (executable)
@@ -75,3 +75,4 @@ config THREE_FB_BUFFER
           select y if android support three buffer,like Jelly Bean
 source "drivers/video/rockchip/hdmi/Kconfig"
 source "drivers/video/rockchip/rga/Kconfig"
+source "drivers/video/rockchip/lvds/Kconfig"
index 68967a49fc80e9afc2dd727e9eaf09e11ace69ce..0f1a3880879efbdefd6f8e70a651bbb2717c6ae9 100755 (executable)
@@ -5,3 +5,4 @@ obj-$(CONFIG_LCDC_RK2928) += chips/rk2928_lcdc.o
 obj-$(CONFIG_LCDC_RK31) += chips/rk31_lcdc.o 
 obj-$(CONFIG_RGA_RK30) += rga/
 obj-$(CONFIG_RK_HDMI) += hdmi/
+obj-$(CONFIG_RK_LVDS) += lvds/
index 5298a8e98291dfa415c513dcc5dd1fd6755ef154..71146072f545c2533a747758edfc1670abe1622c 100755 (executable)
@@ -31,7 +31,7 @@
 #include <asm/div64.h>
 #include <asm/uaccess.h>
 #include "rk2928_lcdc.h"
-
+#include "../lvds/rk_lvds.h"
 
 
 
@@ -68,6 +68,10 @@ static int init_rk2928_lcdc(struct rk_lcdc_device_driver *dev_drv)
        {
                        printk(KERN_ERR "failed to get lcdc%d clk source\n",lcdc_dev->id);
        }
+#ifdef CONFIG_RK_LVDS
+       rk_lvds_register(lcdc_dev->screen);
+#endif
+
        clk_enable(lcdc_dev->pd);
        clk_enable(lcdc_dev->hclk);  //enable aclk and hclk for register config
        clk_enable(lcdc_dev->aclk);  
@@ -685,6 +689,9 @@ int rk2928_lcdc_early_suspend(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->screen->sscreen_set != NULL)
+               lcdc_dev->screen->sscreen_set(lcdc_dev->screen , 0);
+
        spin_lock(&lcdc_dev->reg_lock);
        if(likely(lcdc_dev->clk_on))
        {
@@ -733,6 +740,9 @@ int rk2928_lcdc_early_resume(struct rk_lcdc_device_driver *dev_drv)
        lcdc_dev->clk_on = 1;
        spin_unlock(&lcdc_dev->reg_lock);
        
+       if(lcdc_dev->screen->sscreen_set != NULL)
+               lcdc_dev->screen->sscreen_set(lcdc_dev->screen , 1);
+
        return 0;
 }
 static irqreturn_t rk2928_lcdc_isr(int irq, void *dev_id)
diff --git a/drivers/video/rockchip/lvds/Kconfig b/drivers/video/rockchip/lvds/Kconfig
new file mode 100755 (executable)
index 0000000..1577242
--- /dev/null
@@ -0,0 +1,2 @@
+config RK_LVDS
+       bool "RK_LVDS support"
diff --git a/drivers/video/rockchip/lvds/Makefile b/drivers/video/rockchip/lvds/Makefile
new file mode 100755 (executable)
index 0000000..f410fda
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for LVDS linux kernel module.
+#
+
+
+obj-$(CONFIG_RK_LVDS) += rk_lvds.o 
diff --git a/drivers/video/rockchip/lvds/rk_lvds.c b/drivers/video/rockchip/lvds/rk_lvds.c
new file mode 100644 (file)
index 0000000..0fd1656
--- /dev/null
@@ -0,0 +1,58 @@
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/io.h>
+#include <mach/io.h>
+#include <linux/rk_screen.h>
+#include "rk_lvds.h"
+
+static void rk_output_lvds(rk_screen *screen)
+{
+       LVDSWrReg(m_PD_PLL(1)|m_PD_PLL(0)|m_PDN(1)|m_OEN(0)     \
+                                       |m_DS(DS_10PF)|m_MSBSEL(DATA_D0_MSB)    \
+                                       |m_OUT_FORMAT(screen->hw_format)                \
+                                       |m_LCDC_SEL(FROM_LCDC0));
+}
+
+static void rk_output_lvttl(rk_screen *screen)
+{
+       LVDSWrReg(m_PD_PLL(0)|m_PD_PLL(1)|m_PDN(0)|m_OEN(1)     \
+                                       |m_DS(DS_10PF)|m_MSBSEL(DATA_D0_MSB)    \
+                                       |m_OUT_FORMAT(screen->hw_format)                \
+                                       |m_LCDC_SEL(FROM_LCDC0));
+}
+
+static void rk_output_disable(void)
+{
+       LVDSWrReg(m_PD_PLL(0)|m_PD_PLL(0)|m_PDN(0)|m_OEN(0));
+}
+
+static int rk_lvds_set_param(rk_screen *screen,bool enable )
+{
+       if(OUT_ENABLE == enable){
+               switch(screen->type){
+                       case SCREEN_LVDS:
+                                       rk_output_lvds(screen);
+                                       break;
+                       case SCREEN_RGB:
+                                       rk_output_lvttl(screen);
+                                       break;
+                       default:
+                               printk("%s>>>>LVDS not support this screen type %d,power down LVDS\n",__func__,screen->type);
+                                       rk_output_disable();
+                                       break;
+               }
+       }else{
+               rk_output_disable();
+       }
+       return 0;
+}
+
+int rk_lvds_register(rk_screen *screen)
+{
+       if(screen->sscreen_set == NULL)
+               screen->sscreen_set = rk_lvds_set_param;
+
+       rk_lvds_set_param(screen , OUT_ENABLE);
+
+       return 0;
+}
diff --git a/drivers/video/rockchip/lvds/rk_lvds.h b/drivers/video/rockchip/lvds/rk_lvds.h
new file mode 100644 (file)
index 0000000..3916fad
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef RK_LVDS_H_
+#define RK_LVDS_H
+
+#define LVDS_CON0_OFFSET       0x150
+#define LVDS_CON0_REG          (RK2928_GRF_PHYS + LVDS_CON0_OFFSET) 
+
+#define LVDSRdReg()                                    __raw_readl(LVDS_CON0_REG)
+#define LVDSWrReg(val)         __raw_writel( val ,LVDS_CON0_REG)
+
+#define m_value(x,offset,mask)      \
+                       ((mask<<(offset+8)) | (x&mask)<<offset)
+
+#define OEN                            (1<<9)
+#define m_OEN(x)                       m_value(x,9,1)
+#define PD_PLL                                 (1<<8)
+#define m_PD_PLL(x)            m_value(x,8,1)
+#define PDN_CBG                        (1<<7)
+#define m_PDN_CBG(x)           m_value(x,7,1)
+#define PDN                            (1<<6)
+#define m_PDN(x)                       m_value(x,6,1)
+#define DS                                     (3<<4)
+#define m_DS(x)                        m_value(x,4,3)
+#define MSBSEL                         (1<<3)
+#define m_MSBSEL(x)                    m_value(x,3,1)
+#define OUT_FORMAT                     (3<<1)
+#define m_OUT_FORMAT(x)        m_value(x,1,3)
+#define LCDC_SEL                       (1<<0)
+#define m_LCDC_SEL(x)          m_value(x,0,1)
+
+enum{
+       OUT_DISABLE=0,
+       OUT_ENABLE,
+};
+
+//DS
+#define DS_3PF                         0
+#define DS_7PF                         0
+#define DS_5PF                         0
+#define DS_10PF                        0
+
+//LVDS lane input format
+#define DATA_D0_MSB            0
+#define DATA_D7_MSB            1
+//LVDS input source
+#define FROM_LCDC0             0
+#define FROM_LCDC1             1
+
+
+#define LVDS_8BIT_1     0x00
+#define LVDS_8BIT_2     0x01
+#define LVDS_8BIT_3     0x10
+#define LVDS_6BIT       0x11
+/*                                     LVDS config         
+ *                  LVDS 外部连线接法                       
+ *          LVDS_8BIT_1    LVDS_8BIT_2     LVDS_8BIT_3     LVDS_6BIT
+----------------------------------------------------------------------
+    TX0     R0              R2              R2              R0
+    TX1     R1              R3              R3              R1
+    TX2     R2              R4              R4              R2
+Y   TX3     R3              R5              R5              R3
+0   TX4     R4              R6              R6              R4
+    TX6     R5              R7              R7              R5
+    TX7     G0              G2              G2              G0
+----------------------------------------------------------------------
+    TX8     G1              G3              G3              G1
+    TX9     G2              G4              G4              G2
+Y   TX12    G3              G5              G5              G3
+1   TX13    G4              G6              G6              G4
+    TX14    G5              G7              G7              G5
+    TX15    B0              B2              B2              B0
+    TX18    B1              B3              B3              B1
+----------------------------------------------------------------------
+    TX19    B2              B4              B4              B2
+    TX20    B3              B5              B5              B3
+    TX21    B4              B6              B6              B4
+Y   TX22    B5              B7              B7              B5
+2   TX24    HSYNC           HSYNC           HSYNC           HSYNC
+    TX25    VSYNC           VSYNC           VSYNC           VSYNC
+    TX26    ENABLE          ENABLE          ENABLE          ENABLE
+----------------------------------------------------------------------    
+    TX27    R6              R0              GND             GND
+    TX5     R7              R1              GND             GND
+    TX10    G6              G0              GND             GND
+Y   TX11    G7              G1              GND             GND
+3   TX16    B6              B0              GND             GND
+    TX17    B7              B1              GND             GND
+    TX23    RSVD            RSVD            RSVD            RSVD
+----------------------------------------------------------------------
+*/
+
+
+extern int rk_lvds_register(rk_screen *screen);
+#endif