From: ZHW Date: Thu, 18 Jul 2013 09:58:08 +0000 (+0800) Subject: lvds:support rk3028a_lvds,config:"RK3028a_LVDS" X-Git-Tag: firefly_0821_release~6877 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=56bd854a9aaf223e0e95c6d374cdd469bde5ff19;p=firefly-linux-kernel-4.4.55.git lvds:support rk3028a_lvds,config:"RK3028a_LVDS" --- diff --git a/drivers/video/rockchip/transmitter/Kconfig b/drivers/video/rockchip/transmitter/Kconfig index 502ffcbe4c48..fffe1a9368fd 100644 --- a/drivers/video/rockchip/transmitter/Kconfig +++ b/drivers/video/rockchip/transmitter/Kconfig @@ -7,6 +7,11 @@ config RK2928_LVDS bool "RK2928/RK2926 lvds transmitter support" depends on ARCH_RK2928 && RK_TRSM +config RK3028a_LVDS + bool "KK3028a lvds transmitter support" + depends on RK_TRSM + + config RK610_LVDS bool "RK610(Jetta) lvds transmitter support" depends on MFD_RK610 && RK_TRSM diff --git a/drivers/video/rockchip/transmitter/Makefile b/drivers/video/rockchip/transmitter/Makefile index 010fc6a0d0af..3ef07caa9707 100644 --- a/drivers/video/rockchip/transmitter/Makefile +++ b/drivers/video/rockchip/transmitter/Makefile @@ -2,6 +2,7 @@ # Makefile for display transmitter like lvds edp mipi # obj-$(CONFIG_RK2928_LVDS) += rk2928_lvds.o +obj-$(CONFIG_RK3028a_LVDS) += rk3028a_lvds.o obj-$(CONFIG_RK610_LVDS) += rk610_lcd.o obj-$(CONFIG_RK616_LVDS) += rk616_lvds.o obj-$(CONFIG_DP_ANX6345) += dp_anx6345.o @@ -9,4 +10,5 @@ obj-$(CONFIG_DP501) += dp501.o obj-$(CONFIG_MIPI_DSI) += mipi_dsi.o obj-$(CONFIG_RK616_MIPI_DSI) += rk616_mipi_dsi.o obj-$(CONFIG_TC358768_RGB2MIPI) += tc358768.o -obj-$(CONFIG_SSD2828_RGB2MIPI) += ssd2828.o \ No newline at end of file +obj-$(CONFIG_SSD2828_RGB2MIPI) += ssd2828.o + diff --git a/drivers/video/rockchip/transmitter/rk3028a_lvds.c b/drivers/video/rockchip/transmitter/rk3028a_lvds.c new file mode 100644 index 000000000000..cc8769cc3579 --- /dev/null +++ b/drivers/video/rockchip/transmitter/rk3028a_lvds.c @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "rk3028a_lvds.h" + +#define lvds_readl(offset) readl_relaxed(RK30_GRF_BASE + offset) +#define lvds_writel(v,offset) do{ writel_relaxed(v, RK30_GRF_BASE + offset);dsb();} while (0) + +static void rk3028a_output_lvds(rk_screen *screen) +{ + u32 val =0; + + /* + Choise LVDS transmitter source from LCDC or EBC + */ +#if defined(CONFIG_LCDC0_RK3188) + val |= LVDS_DATA_SEL; +#else + val &= ~(LVDS_DATA_SEL); +#endif + /* + When LVDS output format is 8bit mode format-1/8bit mode format-2, configure + grf_lvds_con0 in 24-bit color mode. + When LVDS output format is 8bit mode format-3/6bit mode, configure + grf_lvds_con0 in 18-bit color mode. + */ + if(screen->lvds_format == 0 || screen->lvds_format == 1) + val |= LVDS_CBS_COL_SEL(2); + else + val |= LVDS_CBS_COL_SEL(1); + + + val &= ~(LVDS_CBG_PWR_EN | LVDS_OUTPUT_EN | LVDS_SWING_SEL); + val |= (LVDS_OUTPUT_FORMAT(screen->lvds_format) | LVDS_PLL_PWR_EN | LVDS_SWING_SEL); + + val |= (LVDS_DATA_SEL | LVDS_OUTPUT_FORMAT(3) | LVDS_CBG_PWR_EN | LVDS_PLL_PWR_EN | + LVDS_OUTPUT_EN | LVDS_CBS_COL_SEL(3) | LVDS_SWING_SEL) << 16; + + lvds_writel(val,CRU_LVDS_CON0); + + return; +} + +static void rk3028a_output_lvttl(rk_screen *screen) +{ + u32 val =0; + + /* + Choise LVDS transmitter source from LCDC or EBC + */ +#if defined(CONFIG_LCDC0_RK3188) + val |= LVDS_DATA_SEL; +#else + val &= ~(LVDS_DATA_SEL); +#endif + /* + When LVDS output format is 8bit mode format-1/8bit mode format-2, configure + grf_lvds_con0 in 24-bit color mode. + When LVDS output format is 8bit mode format-3/6bit mode, configure + grf_lvds_con0 in 18-bit color mode. + */ + if(screen->lvds_format == 0 || screen->lvds_format == 1) + val |= LVDS_CBS_COL_SEL(2); + else + val |= LVDS_CBS_COL_SEL(1); + + val &= ~(LVDS_DATA_SEL | LVDS_CBG_PWR_EN | LVDS_SWING_SEL); + val |= (LVDS_OUTPUT_FORMAT(screen->lvds_format) | LVDS_PLL_PWR_EN | LVDS_OUTPUT_EN | LVDS_CBS_COL_SEL(3)); + + val |= ((LVDS_DATA_SEL | LVDS_CBG_PWR_EN | LVDS_SWING_SEL | LVDS_OUTPUT_FORMAT(screen->lvds_format) | + LVDS_PLL_PWR_EN | LVDS_OUTPUT_EN | LVDS_CBS_COL_SEL(3)) << 16); + + lvds_writel(val,CRU_LVDS_CON0); + + return; +} + +static void rk3028a_output_disable(void) +{ + u32 val =0; + + val |= ((LVDS_CBG_PWR_EN | LVDS_PLL_PWR_EN | LVDS_CBS_COL_SEL(3)) << 16); + val &= ~(LVDS_CBG_PWR_EN); + val |= (LVDS_PLL_PWR_EN | LVDS_CBS_COL_SEL(3)); + + lvds_writel(val,CRU_LVDS_CON0); +} + + +static int rk3028a_lvds_set_param(rk_screen *screen,bool enable) +{ + if(OUT_ENABLE == enable){ + switch(screen->type){ + case SCREEN_LVDS: + rk3028a_output_lvds(screen); + break; + case SCREEN_RGB: + rk3028a_output_lvttl(screen); + break; + default: + printk("%s>>>>LVDS not support this screen type %d,power down LVDS\n",__func__,screen->type); + rk3028a_output_disable(); + break; + } + }else{ + rk3028a_output_disable(); + } + return 0; +} + + +static int rk3028a_lvds_probe(struct platform_device *pdev) +{ + rk_screen *screen = NULL; + + screen = rk_fb_get_prmry_screen(); + if(!screen) + { + dev_err(&pdev->dev,"the fb prmry screen is null!\n"); + return -ENODEV; + } + + rk3028a_lvds_set_param(screen,OUT_ENABLE); + + return 0; + +} + +static int rk3028a_lvds_remove(struct platform_device *pdev) +{ + return 0; +} + +static void rk3028a_lvds_shutdown(struct platform_device *pdev) +{ + return; +} + +static struct platform_driver rk3028a_lvds_driver = { + .driver = { + .name = "rk3028a-lvds", + .owner = THIS_MODULE, + }, + .probe = rk3028a_lvds_probe, + .remove = rk3028a_lvds_remove, + .shutdown = rk3028a_lvds_shutdown, +}; + +static int __init rk3028a_lvds_init(void) +{ + return platform_driver_register(&rk3028a_lvds_driver); +} +fs_initcall(rk3028a_lvds_init); +static void __exit rk3028a_lvds_exit(void) +{ + platform_driver_unregister(&rk3028a_lvds_driver); +} +module_exit(rk3028a_lvds_exit); + + + diff --git a/drivers/video/rockchip/transmitter/rk3028a_lvds.h b/drivers/video/rockchip/transmitter/rk3028a_lvds.h new file mode 100644 index 000000000000..0de11a0911e7 --- /dev/null +++ b/drivers/video/rockchip/transmitter/rk3028a_lvds.h @@ -0,0 +1,19 @@ +#include + + +#define CRU_LVDS_CON0 0x0150 +#define LVDS_SWING_SEL (1<<12) +#define LVDS_CBS_COL_SEL(x) ((x&3)<<10) +#define LVDS_OUTPUT_EN (1<<9) +#define LVDS_PLL_PWR_EN (1<<8) +#define LVDS_CBG_PWR_EN (1<<7) +#define LVDS_CH_LOAD (1<<4) +#define LVDS_INPUT_FORMAT (1<<3) +#define LVDS_OUTPUT_FORMAT(x) (((x)&3)<<1) +#define LVDS_DATA_SEL (1<<0) + +enum{ + OUT_DISABLE=0, + OUT_ENABLE, +}; +