From 4cd85a1ffbd0d13a55edf3eb2a000431bcd5e65f Mon Sep 17 00:00:00 2001 From: hjc Date: Tue, 9 Dec 2014 12:17:28 +0800 Subject: [PATCH] rk31xx lvds: add support rk3368 lvds transmitter Signed-off-by: hjc --- drivers/video/rockchip/Makefile | 4 +- drivers/video/rockchip/transmitter/Kconfig | 6 +- .../video/rockchip/transmitter/rk31xx_lvds.c | 88 ++++++++++++++----- .../video/rockchip/transmitter/rk31xx_lvds.h | 17 ++++ 4 files changed, 91 insertions(+), 24 deletions(-) diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile index f3adbabbaeb8..00247d0c13e9 100755 --- a/drivers/video/rockchip/Makefile +++ b/drivers/video/rockchip/Makefile @@ -2,10 +2,10 @@ obj-$(CONFIG_FB_ROCKCHIP) += rk_fb.o rkfb_sysfs.o bmp_helper.o screen/ obj-$(CONFIG_DRM_ROCKCHIP) += rk_drm_fb.o screen/ obj-$(CONFIG_RK_TRSM) += transmitter/ obj-$(CONFIG_DRM_ROCKCHIP) += lcdc/ -obj-$(CONFIG_FB_ROCKCHIP) += lcdc/ +obj-$(CONFIG_FB_ROCKCHIP) += display-sys.o lcdc/ obj-$(CONFIG_ROCKCHIP_RGA) += rga/ obj-$(CONFIG_ROCKCHIP_RGA2) += rga2/ -obj-$(CONFIG_RK_HDMI) += display-sys.o hdmi/ +obj-$(CONFIG_RK_HDMI) += hdmi/ obj-$(CONFIG_IEP) += iep/ obj-$(CONFIG_RK_TVENCODER) += tve/ diff --git a/drivers/video/rockchip/transmitter/Kconfig b/drivers/video/rockchip/transmitter/Kconfig index b773db1c2c8a..f9320f51cde7 100755 --- a/drivers/video/rockchip/transmitter/Kconfig +++ b/drivers/video/rockchip/transmitter/Kconfig @@ -17,8 +17,10 @@ config RK32_LVDS depends on RK_TRSM config RK31XX_LVDS - bool "RK312x/RK3190 lvds transmitter support" - depends on RK_TRSM + bool "RK312x/RK3190/3368 lvds transmitter support" + depends on RK_TRSM + help + If use LVDS or RGB output interface,selete this module. config RK610_LVDS bool "RK610(Jetta) lvds transmitter support" diff --git a/drivers/video/rockchip/transmitter/rk31xx_lvds.c b/drivers/video/rockchip/transmitter/rk31xx_lvds.c index de3100b44dbd..12ca9fc9cc7c 100755 --- a/drivers/video/rockchip/transmitter/rk31xx_lvds.c +++ b/drivers/video/rockchip/transmitter/rk31xx_lvds.c @@ -52,10 +52,12 @@ static int rk31xx_lvds_clk_init(struct rk_lvds_device *lvds) return PTR_ERR(lvds->ctrl_pclk); } - lvds->ctrl_hclk = devm_clk_get(lvds->dev, "hclk_vio_h2p"); - if (IS_ERR(lvds->ctrl_hclk)) { - dev_err(lvds->dev, "get ctrl hclk failed\n"); - return PTR_ERR(lvds->ctrl_hclk); + if (lvds->data->soc_type == LVDS_SOC_RK312X) { + lvds->ctrl_hclk = devm_clk_get(lvds->dev, "hclk_vio_h2p"); + if (IS_ERR(lvds->ctrl_hclk)) { + dev_err(lvds->dev, "get ctrl hclk failed\n"); + return PTR_ERR(lvds->ctrl_hclk); + } } return 0; @@ -66,7 +68,8 @@ static int rk31xx_lvds_clk_enable(struct rk_lvds_device *lvds) if (!lvds->clk_on) { clk_prepare_enable(lvds->pclk); clk_prepare_enable(lvds->ctrl_pclk); - clk_prepare_enable(lvds->ctrl_hclk); + if (lvds->data->soc_type == LVDS_SOC_RK312X) + clk_prepare_enable(lvds->ctrl_hclk); lvds->clk_on = true; } @@ -77,7 +80,8 @@ static int rk31xx_lvds_clk_disable(struct rk_lvds_device *lvds) { if (lvds->clk_on) { clk_disable_unprepare(lvds->pclk); - clk_disable_unprepare(lvds->ctrl_hclk); + if (lvds->data->soc_type == LVDS_SOC_RK312X) + clk_disable_unprepare(lvds->ctrl_hclk); clk_disable_unprepare(lvds->ctrl_pclk); lvds->clk_on = false; } @@ -145,6 +149,7 @@ static int rk31xx_lvds_disable(void) rk31xx_lvds_clk_disable(lvds); #if !defined(CONFIG_RK_FPGA) +#ifdef CONFIG_PINCTRL if (lvds->screen.type == SCREEN_RGB) { if (lvds->dev->pins) { pinctrl_select_state(lvds->dev->pins->p, @@ -154,6 +159,7 @@ static int rk31xx_lvds_disable(void) lvds->pins->sleep_state); } } +#endif #endif lvds->sys_state = false; return 0; @@ -168,14 +174,32 @@ static void rk31xx_output_lvds(struct rk_lvds_device *lvds, /* if LVDS transmitter source from VOP, vop_dclk need get invert * set iomux in dts pinctrl */ - val = 0; - val |= v_LVDSMODE_EN(1) | v_MIPIPHY_TTL_EN(0); /* enable lvds mode */ - val |= v_LVDS_DATA_SEL(LVDS_DATA_FROM_LCDC); /* config data source */ - val |= v_LVDS_OUTPUT_FORMAT(screen->lvds_format); /* config lvds_format */ - val |= v_LVDS_MSBSEL(LVDS_MSB_D7); /* LSB receive mode */ - val |= v_MIPIPHY_LANE0_EN(1) | v_MIPIDPI_FORCEX_EN(1); - grf_writel(val, RK312X_GRF_LVDS_CON0); - + if (lvds->data->soc_type == LVDS_SOC_RK3368) { + /* enable lvds mode */ + val |= v_RK3368_LVDSMODE_EN(1) | v_RK3368_MIPIPHY_TTL_EN(0); + /* config data source */ + /*val |= v_LVDS_DATA_SEL(LVDS_DATA_FROM_LCDC); */ + /* config lvds_format */ + val |= v_RK3368_LVDS_OUTPUT_FORMAT(screen->lvds_format); + /* LSB receive mode */ + val |= v_RK3368_LVDS_MSBSEL(LVDS_MSB_D7); + val |= v_RK3368_MIPIPHY_LANE0_EN(1) | + v_RK3368_MIPIDPI_FORCEX_EN(1); + /*rk3368 RK3368_GRF_SOC_CON7 = 0X0041C*/ + grf_writel(val, 0x0041C); + } else { + /* enable lvds mode */ + val |= v_LVDSMODE_EN(1) | v_MIPIPHY_TTL_EN(0); + /* config data source */ + val |= v_LVDS_DATA_SEL(LVDS_DATA_FROM_LCDC); + /* config lvds_format */ + val |= v_LVDS_OUTPUT_FORMAT(screen->lvds_format); + /* LSB receive mode */ + val |= v_LVDS_MSBSEL(LVDS_MSB_D7); + val |= v_MIPIPHY_LANE0_EN(1) | v_MIPIDPI_FORCEX_EN(1); + /*rk312x RK312X_GRF_LVDS_CON0 = 0X00150*/ + grf_writel(val, 0X00150); + } /* digital internal disable */ lvds_msk_reg(lvds, MIPIPHY_REGE1, m_DIG_INTER_EN, v_DIG_INTER_EN(0)); @@ -223,8 +247,10 @@ static void rk31xx_output_lvttl(struct rk_lvds_device *lvds, grf_writel(0x77771111, 0x00e8); /* RK312X_GRF_GPIO2C_IOMUX2 */ grf_writel(0x700c1004, RK312X_GRF_GPIO2D_IOMUX); #else +#ifdef CONFIG_PINCTRL if (lvds->pins && !IS_ERR(lvds->pins->default_state)) pinctrl_select_state(lvds->pins->p, lvds->pins->default_state); +#endif #endif val |= v_LVDSMODE_EN(0) | v_MIPIPHY_TTL_EN(1); /* enable lvds mode */ @@ -287,12 +313,34 @@ static struct rk_fb_trsm_ops trsm_lvds_ops = { .dsp_pwr_on = rk31xx_lvds_pwr_on, .dsp_pwr_off = rk31xx_lvds_pwr_off, }; +#if defined(CONFIG_OF) +static struct rk_lvds_drvdata rk31xx_lvds_drvdata = { + .soc_type = LVDS_SOC_RK312X, +}; + +static struct rk_lvds_drvdata rk3368_lvds_drvdata = { + .soc_type = LVDS_SOC_RK3368, +}; + + +static const struct of_device_id rk31xx_lvds_dt_ids[] = { + {.compatible = "rockchip,rk31xx-lvds", + .data = (void *)&rk31xx_lvds_drvdata,}, + {.compatible = "rockchip,rk3368-lvds", + .data = (void *)&rk3368_lvds_drvdata,}, + {} +}; + +/*MODULE_DEVICE_TABLE(of, rk31xx_lvds_dt_ids);*/ + +#endif static int rk31xx_lvds_probe(struct platform_device *pdev) { struct rk_lvds_device *lvds; struct resource *res; struct device_node *np = pdev->dev.of_node; + const struct of_device_id *match; int ret = 0; if (!np) { @@ -306,6 +354,10 @@ static int rk31xx_lvds_probe(struct platform_device *pdev) return -ENOMEM; } lvds->dev = &pdev->dev; + match = of_match_node(rk31xx_lvds_dt_ids, np); + lvds->data = (struct rk_lvds_drvdata *)match->data; + dev_info(lvds->dev, "%s,type=%d\n", + __func__, lvds->data->soc_type); rk_fb_get_prmry_screen(&lvds->screen); if ((lvds->screen.type != SCREEN_RGB) && @@ -318,6 +370,7 @@ static int rk31xx_lvds_probe(struct platform_device *pdev) platform_set_drvdata(pdev, lvds); dev_set_name(lvds->dev, "rk31xx-lvds"); +#ifdef CONFIG_PINCTRL if (lvds->dev->pins == NULL && lvds->screen.type == SCREEN_RGB) { lvds->pins = devm_kzalloc(lvds->dev, sizeof(*(lvds->pins)), GFP_KERNEL); @@ -344,6 +397,7 @@ static int rk31xx_lvds_probe(struct platform_device *pdev) } } +#endif /* lvds regs on MIPIPHY_REG */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mipi_lvds_phy"); lvds->regbase = devm_ioremap_resource(&pdev->dev, res); @@ -390,12 +444,6 @@ static void rk31xx_lvds_shutdown(struct platform_device *pdev) return; } -#if defined(CONFIG_OF) -static const struct of_device_id rk31xx_lvds_dt_ids[] = { - {.compatible = "rockchip,rk31xx-lvds",}, - {} -}; -#endif static struct platform_driver rk31xx_lvds_driver = { .driver = { diff --git a/drivers/video/rockchip/transmitter/rk31xx_lvds.h b/drivers/video/rockchip/transmitter/rk31xx_lvds.h index 0c271e476d81..326749f9448f 100755 --- a/drivers/video/rockchip/transmitter/rk31xx_lvds.h +++ b/drivers/video/rockchip/transmitter/rk31xx_lvds.h @@ -17,6 +17,13 @@ #define v_MIPIPHY_LANE0_EN(x) (BITS_MASK(x, 1, 8) | BITS_EN(1, 8)) #define v_MIPIDPI_FORCEX_EN(x) (BITS_MASK(x, 1, 9) | BITS_EN(1, 9)) +/* RK3368_GRF_SOC_CON7 */ +#define v_RK3368_LVDS_OUTPUT_FORMAT(x) (BITS_MASK(x, 3, 13) | BITS_EN(3, 13)) +#define v_RK3368_LVDS_MSBSEL(x) (BITS_MASK(x, 1, 11) | BITS_EN(1, 11)) +#define v_RK3368_LVDSMODE_EN(x) (BITS_MASK(x, 1, 12) | BITS_EN(1, 12)) +#define v_RK3368_MIPIPHY_TTL_EN(x) (BITS_MASK(x, 1, 15) | BITS_EN(1, 15)) +#define v_RK3368_MIPIPHY_LANE0_EN(x) (BITS_MASK(x, 1, 5) | BITS_EN(1, 5)) +#define v_RK3368_MIPIDPI_FORCEX_EN(x) (BITS_MASK(x, 1, 6) | BITS_EN(1, 6)) enum { LVDS_DATA_FROM_LCDC = 0, LVDS_DATA_FORM_EBC, @@ -98,8 +105,18 @@ enum { #define v_LANE1_EN(x) BITS_MASK(x, 1, 6) #define v_LANE0_EN(x) BITS_MASK(x, 1, 7) +enum { + LVDS_SOC_RK312X, + LVDS_SOC_RK3368 +}; + +struct rk_lvds_drvdata { + u8 soc_type; + u32 reversed; +}; struct rk_lvds_device { + struct rk_lvds_drvdata *data; struct device *dev; void __iomem *regbase; void __iomem *ctrl_reg; -- 2.34.1