From 4c9e1d535cc0074da7f39ea5e0f9d27d3d449c9d Mon Sep 17 00:00:00 2001 From: yzq <yzq@rockchips.com> Date: Mon, 23 Jul 2012 17:47:06 +0800 Subject: [PATCH] rk2928 lvds support --- drivers/video/rockchip/Kconfig | 1 + drivers/video/rockchip/Makefile | 1 + drivers/video/rockchip/chips/rk2928_lcdc.c | 12 ++- drivers/video/rockchip/lvds/Kconfig | 2 + drivers/video/rockchip/lvds/Makefile | 6 ++ drivers/video/rockchip/lvds/rk_lvds.c | 58 ++++++++++++++ drivers/video/rockchip/lvds/rk_lvds.h | 93 ++++++++++++++++++++++ 7 files changed, 172 insertions(+), 1 deletion(-) create mode 100755 drivers/video/rockchip/lvds/Kconfig create mode 100755 drivers/video/rockchip/lvds/Makefile create mode 100644 drivers/video/rockchip/lvds/rk_lvds.c create mode 100644 drivers/video/rockchip/lvds/rk_lvds.h diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig index 04ba7263c5ac..267b5b5a222e 100755 --- a/drivers/video/rockchip/Kconfig +++ b/drivers/video/rockchip/Kconfig @@ -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" diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile index 68967a49fc80..0f1a3880879e 100755 --- a/drivers/video/rockchip/Makefile +++ b/drivers/video/rockchip/Makefile @@ -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/ diff --git a/drivers/video/rockchip/chips/rk2928_lcdc.c b/drivers/video/rockchip/chips/rk2928_lcdc.c index 5298a8e98291..71146072f545 100755 --- a/drivers/video/rockchip/chips/rk2928_lcdc.c +++ b/drivers/video/rockchip/chips/rk2928_lcdc.c @@ -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 index 000000000000..1577242cb924 --- /dev/null +++ b/drivers/video/rockchip/lvds/Kconfig @@ -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 index 000000000000..f410fda78ee1 --- /dev/null +++ b/drivers/video/rockchip/lvds/Makefile @@ -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 index 000000000000..0fd1656120cb --- /dev/null +++ b/drivers/video/rockchip/lvds/rk_lvds.c @@ -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 index 000000000000..3916fad54a90 --- /dev/null +++ b/drivers/video/rockchip/lvds/rk_lvds.h @@ -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 -- 2.34.1