From dafe647cc1096106a821929e87b0649d03a5dd95 Mon Sep 17 00:00:00 2001 From: hjc Date: Thu, 25 Jul 2013 10:52:25 +0800 Subject: [PATCH] rk3188 lcdc:add support rk3026/rk3028a lcdc and iep --- arch/arm/configs/rk3026_tb_defconfig | 3 ++ arch/arm/configs/rk3028a_tb_defconfig | 3 ++ arch/arm/mach-rk3026/board-rk3026-tb.c | 37 ++++++++++---- arch/arm/mach-rk3026/board-rk3028a-tb.c | 37 ++++++++++---- drivers/video/rockchip/lcdc/Kconfig | 2 +- drivers/video/rockchip/lcdc/rk3188_lcdc.c | 62 ++++++++++++++++++++--- drivers/video/rockchip/lcdc/rk3188_lcdc.h | 32 +++++++++++- drivers/video/rockchip/rk_fb.c | 31 ++++++++++++ include/linux/rk_fb.h | 7 +++ 9 files changed, 182 insertions(+), 32 deletions(-) mode change 100644 => 100755 drivers/video/rockchip/lcdc/Kconfig mode change 100644 => 100755 drivers/video/rockchip/lcdc/rk3188_lcdc.c mode change 100644 => 100755 drivers/video/rockchip/lcdc/rk3188_lcdc.h mode change 100644 => 100755 include/linux/rk_fb.h diff --git a/arch/arm/configs/rk3026_tb_defconfig b/arch/arm/configs/rk3026_tb_defconfig index c3390abda034..4ba1bb8b44d5 100644 --- a/arch/arm/configs/rk3026_tb_defconfig +++ b/arch/arm/configs/rk3026_tb_defconfig @@ -303,6 +303,9 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_DISPLAY_SUPPORT=y CONFIG_FB_ROCKCHIP=y CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL=y +CONFIG_LCDC_RK3188=y +CONFIG_LCDC0_RK3188=y +CONFIG_LCDC1_RK3188=y CONFIG_LCD_B101EW05=y CONFIG_RK_TRSM=y CONFIG_RK_HDMI=y diff --git a/arch/arm/configs/rk3028a_tb_defconfig b/arch/arm/configs/rk3028a_tb_defconfig index bc1c86659ed7..27ecaa0aedbd 100644 --- a/arch/arm/configs/rk3028a_tb_defconfig +++ b/arch/arm/configs/rk3028a_tb_defconfig @@ -303,6 +303,9 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_DISPLAY_SUPPORT=y CONFIG_FB_ROCKCHIP=y CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL=y +CONFIG_LCDC_RK3188=y +CONFIG_LCDC0_RK3188=y +CONFIG_LCDC1_RK3188=y CONFIG_LCD_B101EW05=y CONFIG_RK_TRSM=y CONFIG_RK_HDMI=y diff --git a/arch/arm/mach-rk3026/board-rk3026-tb.c b/arch/arm/mach-rk3026/board-rk3026-tb.c index cb948985caf4..d29eaddf1a6b 100755 --- a/arch/arm/mach-rk3026/board-rk3026-tb.c +++ b/arch/arm/mach-rk3026/board-rk3026-tb.c @@ -265,22 +265,37 @@ static int rk_fb_io_enable(void) #if defined(CONFIG_LCDC0_RK3066B) || defined(CONFIG_LCDC0_RK3188) struct rk29fb_info lcdc0_screen_info = { - #if defined(CONFIG_RK_HDMI) - .prop = EXTEND, //extend display device - .lcd_info = NULL, +#if defined(CONFIG_RK_HDMI) && defined(CONFIG_HDMI_SOURCE_LCDC0) && defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL) + .prop = EXTEND, //extend display device + .io_init = NULL, + .io_disable = NULL, + .io_enable = NULL, .set_screen_info = hdmi_init_lcdc, - #endif +#else + .prop = PRMRY, //primary display device + .io_init = rk_fb_io_init, + .io_disable = rk_fb_io_disable, + .io_enable = rk_fb_io_enable, + .set_screen_info = set_lcd_info, +#endif }; #endif #if defined(CONFIG_LCDC1_RK3066B) || defined(CONFIG_LCDC1_RK3188) struct rk29fb_info lcdc1_screen_info = { +#if defined(CONFIG_RK_HDMI) && defined(CONFIG_HDMI_SOURCE_LCDC1) && defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL) + .prop = EXTEND, //extend display device + .io_init = NULL, + .io_disable = NULL, + .io_enable = NULL, + .set_screen_info = hdmi_init_lcdc, +#else .prop = PRMRY, //primary display device .io_init = rk_fb_io_init, .io_disable = rk_fb_io_disable, .io_enable = rk_fb_io_enable, .set_screen_info = set_lcd_info, - +#endif }; #endif @@ -317,15 +332,15 @@ static struct platform_device device_fb = { static struct resource resource_lcdc0[] = { [0] = { .name = "lcdc0 reg", - .start = RK30_LCDC0_PHYS, - .end = RK30_LCDC0_PHYS + RK30_LCDC0_SIZE - 1, + .start = RK3026_LCDC0_PHYS, + .end = RK3026_LCDC0_PHYS + RK3026_LCDC0_PHYS - 1, .flags = IORESOURCE_MEM, }, [1] = { .name = "lcdc0 irq", - .start = IRQ_LCDC0, - .end = IRQ_LCDC0, + .start = IRQ_LCDC, + .end = IRQ_LCDC, .flags = IORESOURCE_IRQ, }, }; @@ -345,8 +360,8 @@ static struct platform_device device_lcdc0 = { static struct resource resource_lcdc1[] = { [0] = { .name = "lcdc1 reg", - .start = RK30_LCDC1_PHYS, - .end = RK30_LCDC1_PHYS + RK30_LCDC1_SIZE - 1, + .start = RK3026_LCDC1_PHYS, + .end = RK3026_LCDC1_PHYS + RK3026_LCDC1_PHYS - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-rk3026/board-rk3028a-tb.c b/arch/arm/mach-rk3026/board-rk3028a-tb.c index 8f9351f0aaa7..ee23d5f8d945 100755 --- a/arch/arm/mach-rk3026/board-rk3028a-tb.c +++ b/arch/arm/mach-rk3026/board-rk3028a-tb.c @@ -265,22 +265,37 @@ static int rk_fb_io_enable(void) #if defined(CONFIG_LCDC0_RK3066B) || defined(CONFIG_LCDC0_RK3188) struct rk29fb_info lcdc0_screen_info = { - #if defined(CONFIG_RK_HDMI) - .prop = EXTEND, //extend display device - .lcd_info = NULL, +#if defined(CONFIG_RK_HDMI) && defined(CONFIG_HDMI_SOURCE_LCDC0) && defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL) + .prop = EXTEND, //extend display device + .io_init = NULL, + .io_disable = NULL, + .io_enable = NULL, .set_screen_info = hdmi_init_lcdc, - #endif +#else + .prop = PRMRY, //primary display device + .io_init = rk_fb_io_init, + .io_disable = rk_fb_io_disable, + .io_enable = rk_fb_io_enable, + .set_screen_info = set_lcd_info, +#endif }; #endif #if defined(CONFIG_LCDC1_RK3066B) || defined(CONFIG_LCDC1_RK3188) struct rk29fb_info lcdc1_screen_info = { +#if defined(CONFIG_RK_HDMI) && defined(CONFIG_HDMI_SOURCE_LCDC1) && defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL) + .prop = EXTEND, //extend display device + .io_init = NULL, + .io_disable = NULL, + .io_enable = NULL, + .set_screen_info = hdmi_init_lcdc, +#else .prop = PRMRY, //primary display device .io_init = rk_fb_io_init, .io_disable = rk_fb_io_disable, .io_enable = rk_fb_io_enable, .set_screen_info = set_lcd_info, - +#endif }; #endif @@ -317,15 +332,15 @@ static struct platform_device device_fb = { static struct resource resource_lcdc0[] = { [0] = { .name = "lcdc0 reg", - .start = RK30_LCDC0_PHYS, - .end = RK30_LCDC0_PHYS + RK30_LCDC0_SIZE - 1, + .start = RK3026_LCDC0_PHYS, + .end = RK3026_LCDC0_PHYS + RK3026_LCDC0_PHYS - 1, .flags = IORESOURCE_MEM, }, [1] = { .name = "lcdc0 irq", - .start = IRQ_LCDC0, - .end = IRQ_LCDC0, + .start = IRQ_LCDC, + .end = IRQ_LCDC, .flags = IORESOURCE_IRQ, }, }; @@ -345,8 +360,8 @@ static struct platform_device device_lcdc0 = { static struct resource resource_lcdc1[] = { [0] = { .name = "lcdc1 reg", - .start = RK30_LCDC1_PHYS, - .end = RK30_LCDC1_PHYS + RK30_LCDC1_SIZE - 1, + .start = RK3026_LCDC1_PHYS, + .end = RK3026_LCDC1_PHYS + RK3026_LCDC1_PHYS - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/drivers/video/rockchip/lcdc/Kconfig b/drivers/video/rockchip/lcdc/Kconfig old mode 100644 new mode 100755 index ee1a0d2eb155..db3dadb480d1 --- a/drivers/video/rockchip/lcdc/Kconfig +++ b/drivers/video/rockchip/lcdc/Kconfig @@ -61,7 +61,7 @@ config RK3066B_LCDC1_IO_18V config LCDC_RK3188 bool "rk3188 lcdc support" - depends on FB_ROCKCHIP && ARCH_RK3188 + depends on FB_ROCKCHIP && (ARCH_RK3188 || ARCH_RK3026) help Driver for rk3188 lcdc.There are two lcd controllers on rk3188 config LCDC0_RK3188 diff --git a/drivers/video/rockchip/lcdc/rk3188_lcdc.c b/drivers/video/rockchip/lcdc/rk3188_lcdc.c old mode 100644 new mode 100755 index a8d52defdfdd..6b16fcf8eab6 --- a/drivers/video/rockchip/lcdc/rk3188_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3188_lcdc.c @@ -448,17 +448,17 @@ static int rk3188_lcdc_init(struct rk_lcdc_device_driver *dev_drv) } rk3188_lcdc_read_reg_defalut_cfg(lcdc_dev); + #ifdef CONFIG_ARCH_RK3188 if(lcdc_dev->id == 0) { #if defined(CONFIG_LCDC0_IO_18V) - v = 0x40004000; //bit14: 1,1.8v;0,3.3v - writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4); + 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); + v = 0x40000000; + writel_relaxed(v,RK30_GRF_BASE + GRF_IO_CON4); #endif } - if(lcdc_dev->id == 1) //iomux for lcdc1 { #if defined(CONFIG_LCDC1_IO_18V) @@ -496,8 +496,8 @@ static int rk3188_lcdc_init(struct rk_lcdc_device_driver *dev_drv) iomux_set(LCDC1_D21); iomux_set(LCDC1_D22); iomux_set(LCDC1_D23); - } + #endif lcdc_set_bit(lcdc_dev,SYS_CTRL,m_AUTO_GATING_EN);//eanble axi-clk auto gating for low power //lcdc_set_bit(lcdc_dev,DSP_CTRL0,m_WIN0_TOP); if(dev_drv->cur_screen->dsp_lut) @@ -632,7 +632,27 @@ static int rk3188_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initsc v_VASP(screen->vsync_len + screen->upper_margin)); } spin_unlock(&lcdc_dev->reg_lock); - + if(dev_drv->screen0->type == SCREEN_RGB) //iomux for RGB screen + { + iomux_set(LCDC0_DCLK); + iomux_set(LCDC0_HSYNC); + iomux_set(LCDC0_VSYNC); + iomux_set(LCDC0_DEN); + iomux_set(LCDC0_D10); + iomux_set(LCDC0_D11); + iomux_set(LCDC0_D12); + iomux_set(LCDC0_D13); + iomux_set(LCDC0_D14); + iomux_set(LCDC0_D15); + iomux_set(LCDC0_D16); + iomux_set(LCDC0_D17); + iomux_set(LCDC0_D18); + iomux_set(LCDC0_D19); + iomux_set(LCDC0_D20); + iomux_set(LCDC0_D21); + iomux_set(LCDC0_D22); + iomux_set(LCDC0_D23); + } ret = clk_set_rate(lcdc_dev->dclk, screen->pixclock); if(ret) { @@ -1374,6 +1394,31 @@ static int rk3188_set_dsp_lut(struct rk_lcdc_device_driver *dev_drv,int *lut) return ret; } +static int rk3188_lcdc_dpi_open(struct rk_lcdc_device_driver *dev_drv,bool open) +{ + struct rk3188_lcdc_device *lcdc_dev = + container_of(dev_drv,struct rk3188_lcdc_device,driver); + lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DIRECT_PATCH_EN,v_DIRECT_PATCH_EN(open)); + lcdc_cfg_done(lcdc_dev); + return 0; +} + +static int rk3188_lcdc_dpi_layer_sel(struct rk_lcdc_device_driver *dev_drv,int layer_id) +{ + struct rk3188_lcdc_device *lcdc_dev = + container_of(dev_drv,struct rk3188_lcdc_device,driver); + lcdc_msk_reg(lcdc_dev,SYS_CTRL,m_DIRECT_PATH_LAY_SEL,v_DIRECT_PATH_LAY_SEL(layer_id)); + lcdc_cfg_done(lcdc_dev); + return 0; + +} +static int rk3188_lcdc_dpi_status(struct rk_lcdc_device_driver *dev_drv) +{ + struct rk3188_lcdc_device *lcdc_dev = + container_of(dev_drv,struct rk3188_lcdc_device,driver); + int ovl = lcdc_read_bit(lcdc_dev,SYS_CTRL,m_DIRECT_PATCH_EN); + return ovl; +} static struct layer_par lcdc_layer[] = { [0] = { @@ -1409,6 +1454,9 @@ static struct rk_lcdc_device_driver lcdc_driver = { .fb_get_layer = rk3188_fb_get_layer, .fb_layer_remap = rk3188_fb_layer_remap, .set_dsp_lut = rk3188_set_dsp_lut, + .dpi_open = rk3188_lcdc_dpi_open, + .dpi_layer_sel = rk3188_lcdc_dpi_layer_sel, + .dpi_status = rk3188_lcdc_dpi_status, }; static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id) diff --git a/drivers/video/rockchip/lcdc/rk3188_lcdc.h b/drivers/video/rockchip/lcdc/rk3188_lcdc.h old mode 100644 new mode 100755 index a8b9202e1c9b..be728a6a12ca --- a/drivers/video/rockchip/lcdc/rk3188_lcdc.h +++ b/drivers/video/rockchip/lcdc/rk3188_lcdc.h @@ -16,7 +16,7 @@ #define m_WIN1_FORMAT (7<<6) #define m_HWC_COLOR_MODE (1<<9) #define m_HWC_SIZE (1<<10) -#define m_WIN0_3D_EN (1<11) +#define m_WIN0_3D_EN (1<<11) #define m_WIN0_3D_MODE (7<<12) #define m_WIN0_RB_SWAP (1<<15) #define m_WIN0_ALPHA_SWAP (1<<16) @@ -41,7 +41,7 @@ #define v_WIN1_FORMAT(x) (((x)&7)<<6) #define v_HWC_COLOR_MODE(x) (((x)&1)<<9) #define v_HWC_SIZE(x) (((x)&1)<<10) -#define v_WIN0_3D_EN(x) (((x)&1)<11) +#define v_WIN0_3D_EN(x) (((x)&1)<<11) #define v_WIN0_3D_MODE(x) (((x)&7)<<12) #define v_WIN0_RB_SWAP(x) (((x)&1)<<15) #define v_WIN0_ALPHA_SWAP(x) (((x)&1)<<16) @@ -288,6 +288,34 @@ #define WIN1_LUT_ADDR (0x400) #define DSP_LUT_ADDR (0x800) +/* + RK3026/RK3028A max output resolution 1920x1080 + support IEP instead of 3d +*/ +#ifdef CONFIG_ARCH_RK3026 +//SYS_CTRL 0x00 +#define m_DIRECT_PATCH_EN (1<<11) +#define m_DIRECT_PATH_LAY_SEL (1<<12) + +#define v_DIRECT_PATCH_EN(x) (((x)&1)<<11) +#define v_DIRECT_PATH_LAY_SEL(x) (((x)&1)<<12) + +//INT_STATUS 0x10 +#define m_WIN0_EMPTY_INTR_EN (1<<24) +#define m_WIN1_EMPTY_INTR_EN (1<<25) +#define m_WIN0_EMPTY_INTR_CLR (1<<26) +#define m_WIN1_EMPTY_INTR_CLR (1<<27) +#define m_WIN0_EMPTY_INTR_STA (1<<28) +#define m_WIN1_EMPTY_INTR_STA (1<<29) + +#define v_WIN0_EMPTY_INTR_EN(x) (((x)&1)<<24) +#define v_WIN1_EMPTY_INTR_EN(x) (((x)&1)<<25) +#define v_WIN0_EMPTY_INTR_CLR(x) (((x)&1)<<26) +#define v_WIN1_EMPTY_INTR_CLR(x) (((x)&1)<<27) +#define v_WIN0_EMPTY_INTR_STA(x) (((x)&1)<<28) +#define v_WIN1_EMPTY_INTR_STA(x) (((x)&1)<<29) +#endif + #define CalScale(x, y) ((((u32)(x-1))*0x1000)/(y-1)) diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index cda82efb1ab5..e709ee2491d0 100755 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -983,6 +983,31 @@ static int set_xact_yact_for_hdmi(struct fb_var_screeninfo *pmy_var, return 0; } +int rk_fb_dpi_open(bool open) +{ + struct rk_lcdc_device_driver * dev_drv = NULL; + dev_drv = rk_get_prmry_lcdc_drv(); + dev_drv->dpi_open(dev_drv,open); + + return 0; +} +int rk_fb_dpi_layer_sel(int layer_id) +{ + struct rk_lcdc_device_driver * dev_drv = NULL; + dev_drv = rk_get_prmry_lcdc_drv(); + dev_drv->dpi_layer_sel(dev_drv,layer_id); + + return 0; +} +int rk_fb_dpi_status(void) +{ + int ret; + struct rk_lcdc_device_driver * dev_drv = NULL; + dev_drv = rk_get_prmry_lcdc_drv(); + ret = dev_drv->dpi_status(dev_drv); + + return ret; +} /****************************************** function:this function will be called by hdmi,when @@ -1384,6 +1409,12 @@ static int init_lcdc_device_driver(struct rk_lcdc_device_driver *dev_drv, dev_drv->lcdc_hdmi_process = def_drv->lcdc_hdmi_process; if(def_drv->lcdc_reg_update) dev_drv->lcdc_reg_update = def_drv->lcdc_reg_update; + if(def_drv->dpi_open) + dev_drv->dpi_open = def_drv->dpi_open; + if(def_drv->dpi_layer_sel) + dev_drv->dpi_layer_sel = def_drv->dpi_layer_sel; + if(def_drv->dpi_status) + dev_drv->dpi_status = def_drv->dpi_status; init_layer_par(dev_drv); init_completion(&dev_drv->frame_done); spin_lock_init(&dev_drv->cpl_lock); diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h old mode 100644 new mode 100755 index 53e47bfa8331..f5599fec1349 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -281,6 +281,9 @@ struct rk_lcdc_device_driver{ int (*read_dsp_lut)(struct rk_lcdc_device_driver *dev_drv,int *lut); int (*lcdc_hdmi_process)(struct rk_lcdc_device_driver *dev_drv,int mode); //some lcdc need to some process in hdmi mode int (*lcdc_rst)(struct rk_lcdc_device_driver *dev_drv); + int (*dpi_open)(struct rk_lcdc_device_driver *dev_drv,bool open); + int (*dpi_layer_sel)(struct rk_lcdc_device_driver *dev_drv,int layer_id); + int (*dpi_status)(struct rk_lcdc_device_driver *dev_drv); }; @@ -304,6 +307,10 @@ extern struct rk_lcdc_device_driver * rk_get_lcdc_drv(char *name); extern rk_screen * rk_fb_get_prmry_screen(void); u32 rk_fb_get_prmry_screen_pixclock(void); +extern int rk_fb_dpi_open(bool open); +extern int rk_fb_dpi_layer_sel(int layer_id); +extern int rk_fb_dpi_status(void); + extern int rk_fb_switch_screen(rk_screen *screen ,int enable ,int lcdc_id); extern int rk_fb_disp_scale(u8 scale_x, u8 scale_y,u8 lcdc_id); extern int rkfb_create_sysfs(struct fb_info *fbi); -- 2.34.1