From 172d27a35b31fa416b43287fdbcf2f7b2ef11999 Mon Sep 17 00:00:00 2001 From: xubilv Date: Mon, 28 Mar 2016 21:08:28 +0800 Subject: [PATCH] video: rockchip: mipi: 3399: add support rk3399 Change-Id: I52fbecb5c6739b8ed1e35c3c3be7778a189874a6 Signed-off-by: xubilv --- .../rockchip/transmitter/rk32_mipi_dsi.c | 105 +++++++++++++----- .../rockchip/transmitter/rk32_mipi_dsi.h | 7 ++ 2 files changed, 84 insertions(+), 28 deletions(-) diff --git a/drivers/video/rockchip/transmitter/rk32_mipi_dsi.c b/drivers/video/rockchip/transmitter/rk32_mipi_dsi.c index 018cb0810a3d..9f01f96054d9 100755 --- a/drivers/video/rockchip/transmitter/rk32_mipi_dsi.c +++ b/drivers/video/rockchip/transmitter/rk32_mipi_dsi.c @@ -27,6 +27,7 @@ #define DSI_RK312x 0x3128 #define DSI_RK3368 0x3368 #define DSI_RK3366 0x3366 +#define DSI_RK3399 0x3399 #define DSI_ERR -1 #include @@ -50,6 +51,8 @@ #include "rk32_mipi_dsi.h" #include #include +#include +#include #define MIPI_DBG(x...) /* printk(KERN_INFO x) */ @@ -108,7 +111,8 @@ int rockchip_get_screen_type(void) static int rk32_dsi_read_reg(struct dsi *dsi, u16 reg, u32 *pval) { - if (dsi->ops.id == DSI_RK3288) + if (dsi->ops.id == DSI_RK3288 || + dsi->ops.id == DSI_RK3399) *pval = __raw_readl(dsi->host.membase + (reg - MIPI_DSI_HOST_OFFSET)); else if (dsi->ops.id == DSI_RK312x || dsi->ops.id == DSI_RK3368 || @@ -123,7 +127,8 @@ static int rk32_dsi_read_reg(struct dsi *dsi, u16 reg, u32 *pval) static int rk32_dsi_write_reg(struct dsi *dsi, u16 reg, u32 *pval) { - if (dsi->ops.id == DSI_RK3288) + if (dsi->ops.id == DSI_RK3288 || + dsi->ops.id == DSI_RK3399) __raw_writel(*pval, dsi->host.membase + (reg - MIPI_DSI_HOST_OFFSET)); else if (dsi->ops.id == DSI_RK312x || dsi->ops.id == DSI_RK3368 || @@ -220,6 +225,8 @@ static int rk32_phy_power_up(struct dsi *dsi) /* enable ref clock */ clk_prepare_enable(dsi->phy.refclk); clk_prepare_enable(dsi->dsi_pclk); + if (dsi->ops.id == DSI_RK3399) + clk_prepare_enable(dsi->dsi_host_pclk); udelay(10); switch (dsi->host.lane) { @@ -495,7 +502,8 @@ static int rk312x_phy_power_up(struct dsi *dsi) static int rk_phy_power_up(struct dsi *dsi) { - if (dsi->ops.id == DSI_RK3288) + if (dsi->ops.id == DSI_RK3288 || + dsi->ops.id == DSI_RK3399) rk32_phy_power_up(dsi); else if (dsi->ops.id == DSI_RK312x || dsi->ops.id == DSI_RK3368 || @@ -509,6 +517,8 @@ static int rk32_phy_power_down(struct dsi *dsi) rk32_dsi_set_bits(dsi, 0, phy_shutdownz); clk_disable_unprepare(dsi->phy.refclk); clk_disable_unprepare(dsi->dsi_pclk); + if (dsi->ops.id == DSI_RK3399) + clk_disable_unprepare(dsi->dsi_host_pclk); return 0; } @@ -529,7 +539,8 @@ static int rk312x_phy_power_down(struct dsi *dsi) static int rk_phy_power_down(struct dsi *dsi) { - if (dsi->ops.id == DSI_RK3288) + if (dsi->ops.id == DSI_RK3288 || + dsi->ops.id == DSI_RK3399) rk32_phy_power_down(dsi); else if (dsi->ops.id == DSI_RK312x || dsi->ops.id == DSI_RK3368 || @@ -775,7 +786,8 @@ static int rk312x_phy_init(struct dsi *dsi, int n) static int rk_phy_init(struct dsi *dsi) { - if (dsi->ops.id == DSI_RK3288) + if (dsi->ops.id == DSI_RK3288 || + dsi->ops.id == DSI_RK3399) rk32_phy_init(dsi); else if (dsi->ops.id == DSI_RK312x || dsi->ops.id == DSI_RK3368 || @@ -851,7 +863,8 @@ static int rk32_mipi_dsi_host_init(struct dsi *dsi) } if (dsi->ops.id == DSI_RK3288 || dsi->ops.id == DSI_RK3368 || - dsi->ops.id == DSI_RK3366) { + dsi->ops.id == DSI_RK3366 || + dsi->ops.id == DSI_RK3399) { rk32_dsi_set_bits(dsi, 1, hsync_active_low); rk32_dsi_set_bits(dsi, 1, vsync_active_low); @@ -932,7 +945,10 @@ static int rk32_mipi_dsi_host_init(struct dsi *dsi) rk32_dsi_set_bits(dsi, 10, TO_CLK_DIVISION); rk32_dsi_set_bits(dsi, 1000, hstx_to_cnt); /* no sure */ rk32_dsi_set_bits(dsi, 1000, lprx_to_cnt); - rk32_dsi_set_bits(dsi, 100, phy_stop_wait_time); + if (dsi->ops.id == DSI_RK3399) + rk32_dsi_set_bits(dsi, 32, phy_stop_wait_time); + else + rk32_dsi_set_bits(dsi, 100, phy_stop_wait_time); /* enable send command in low power mode */ rk32_dsi_set_bits(dsi, 4, outvact_lpcmd_time); @@ -1001,7 +1017,8 @@ static int rk_mipi_dsi_init(void *arg, u32 n) dsi->phy.sys_clk = dsi->phy.ref_clk; printk("dsi->phy.sys_clk =%d\n", dsi->phy.sys_clk); - if (dsi->ops.id == DSI_RK3288) { + if (dsi->ops.id == DSI_RK3288 || + dsi->ops.id == DSI_RK3399) { if ((screen->hs_tx_clk <= 90 * MHz) || (screen->hs_tx_clk >= 1500 * MHz)) dsi->phy.ddr_clk = 1500 * MHz; /* default is 1.5HGz */ else @@ -1639,27 +1656,34 @@ static void rk32_init_phy_mode(int lcdc_id) MIPI_DBG("rk32_init_phy_mode----------lcdc_id=%d\n", lcdc_id); /* Only the rk3288 VOP need setting the VOP output. */ - if (dsi0->ops.id != DSI_RK3288) - return; - - /* D-PHY mode select */ - if (rk_mipi_get_dsi_num() == 1) { - if (lcdc_id == 1) - /* 1'b1: VOP LIT output to DSI host0;1'b0: VOP BIG output to DSI host0 */ - val0 = 0x1 << 22 | 0x1 << 6; - else - val0 = 0x1 << 22 | 0x0 << 6; - writel_relaxed(val0, RK_GRF_VIRT + RK3288_GRF_SOC_CON6); - } else { - if (lcdc_id == 1) { - val0 = 0x1 << 25 | 0x1 << 9 | 0x1 << 22 | 0x1 << 6; - val1 = 0x1 << 31 | 0x1 << 30 | 0x0 << 15 | 0x1 << 14; + if (dsi0->ops.id == DSI_RK3288) { + /* D-PHY mode select */ + if (rk_mipi_get_dsi_num() == 1) { + if (lcdc_id == 1) + /* 1'b1: VOP LIT output to DSI host0;1'b0: VOP BIG output to DSI host0 */ + val0 = 0x1 << 22 | 0x1 << 6; + else + val0 = 0x1 << 22 | 0x0 << 6; + writel_relaxed(val0, RK_GRF_VIRT + RK3288_GRF_SOC_CON6); } else { - val0 = 0x1 << 25 | 0x0 << 9 | 0x1 << 22 | 0x0 << 14; - val1 = 0x1 << 31 | 0x1 << 30 | 0x0 << 15 | 0x1 << 14; + if (lcdc_id == 1) { + val0 = 0x1 << 25 | 0x1 << 9 | 0x1 << 22 | 0x1 << 6; + val1 = 0x1 << 31 | 0x1 << 30 | 0x0 << 15 | 0x1 << 14; + } else { + val0 = 0x1 << 25 | 0x0 << 9 | 0x1 << 22 | 0x0 << 14; + val1 = 0x1 << 31 | 0x1 << 30 | 0x0 << 15 | 0x1 << 14; + } + writel_relaxed(val0, RK_GRF_VIRT + RK3288_GRF_SOC_CON6); + writel_relaxed(val1, RK_GRF_VIRT + RK3288_GRF_SOC_CON14); } - writel_relaxed(val0, RK_GRF_VIRT + RK3288_GRF_SOC_CON6); - writel_relaxed(val1, RK_GRF_VIRT + RK3288_GRF_SOC_CON14); + } else if (dsi0->ops.id == DSI_RK3399) { + val0 = 0x1 << 16 | 0x0; + regmap_write(dsi0->grf_base, RK3399_GRF_CON20, val0); + + val0 = 0x1 << 28 | 0x0 << 12; + val0 |= 0xf << 20 | 0x0 << 4; + val0 |= 0xf << 16 | 0x0; + regmap_write(dsi0->grf_base, RK3399_GRF_CON22, val0); } } @@ -1710,11 +1734,17 @@ static struct dsi_type dsi_rk3366 = { .dsi_id = DSI_RK3366, }; +static struct dsi_type dsi_rk3399 = { + .label = "rk3399-dsi", + .dsi_id = DSI_RK3399, +}; + static const struct of_device_id of_rk_mipi_dsi_match[] = { { .compatible = "rockchip,rk32-dsi", .data = &dsi_rk32}, { .compatible = "rockchip,rk312x-dsi", .data = &dsi_rk312x}, { .compatible = "rockchip,rk3368-dsi", .data = &dsi_rk3368}, { .compatible = "rockchip,rk3366-dsi", .data = &dsi_rk3366}, + { .compatible = "rockchip,rk3399-dsi", .data = &dsi_rk3399}, { /* Sentinel */ } }; @@ -1727,6 +1757,7 @@ static int rk32_mipi_dsi_probe(struct platform_device *pdev) struct rk_screen *screen; struct mipi_dsi_screen *dsi_screen; struct resource *res_host, *res_phy; + struct device_node *np = pdev->dev.of_node; const struct dsi_type *data; const struct of_device_id *of_id = of_match_device(of_rk_mipi_dsi_match, &pdev->dev); @@ -1743,7 +1774,8 @@ static int rk32_mipi_dsi_probe(struct platform_device *pdev) } dsi->ops.id = data->dsi_id; printk(KERN_INFO "%s\n", data->label); - if (dsi->ops.id == DSI_RK3288) { + if (dsi->ops.id == DSI_RK3288 || + dsi->ops.id == DSI_RK3399) { res_host = platform_get_resource(pdev, IORESOURCE_MEM, 0); dsi->host.membase = devm_ioremap_resource(&pdev->dev, res_host); if (IS_ERR(dsi->host.membase)) { @@ -1805,6 +1837,21 @@ static int rk32_mipi_dsi_probe(struct platform_device *pdev) } } + if (dsi->ops.id == DSI_RK3399) { + /* Get mipi phy cfg clk */ + dsi->dsi_host_pclk = devm_clk_get(&pdev->dev, "mipi_dphy_cfg"); + if (unlikely(IS_ERR(dsi->dsi_host_pclk))) { + dev_err(&pdev->dev, "get mipi_dphy_cfg clock fail\n"); + return PTR_ERR(dsi->dsi_host_pclk); + } + + dsi->grf_base = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); + if (IS_ERR(dsi->grf_base)) { + dev_err(&pdev->dev, "can't find mipi grf property\n"); + dsi->grf_base = NULL; + } + } + dsi->host.irq = platform_get_irq(pdev, 0); if (dsi->host.irq < 0) { dev_err(&pdev->dev, "no irq resource?\n"); @@ -1904,6 +1951,8 @@ static int rk32_mipi_dsi_probe(struct platform_device *pdev) } else if (dsi->ops.id == DSI_RK3368 || dsi->ops.id == DSI_RK3366) clk_prepare_enable(dsi->dsi_host_pclk); + else if (dsi->ops.id == DSI_RK3399) + clk_prepare_enable(dsi->dsi_host_pclk); dsi->clk_on = 1; udelay(10); diff --git a/drivers/video/rockchip/transmitter/rk32_mipi_dsi.h b/drivers/video/rockchip/transmitter/rk32_mipi_dsi.h index da47cfd3349c..ea18185b6a1f 100755 --- a/drivers/video/rockchip/transmitter/rk32_mipi_dsi.h +++ b/drivers/video/rockchip/transmitter/rk32_mipi_dsi.h @@ -15,6 +15,12 @@ drivers/video/rockchip/transmitter/rk32_mipi_dsi.h #else #include #endif + +#define RK3399_GRF_CON20 0x6250 +#define RK3399_GRF_CON22 0x6258 +#define RK3399_GRF_CON23 0x625c +#define RK3399_GRF_CON24 0x6260 + #define MIPI_DSI_PHY_OFFSET 0x0C00 #define MIPI_DSI_PHY_SIZE 0x34c @@ -301,6 +307,7 @@ struct dsi { u8 lcdc_id; u8 vid; u8 clk_on; + struct regmap *grf_base; struct dsi_phy phy; struct dsi_host host; struct mipi_dsi_ops ops; -- 2.34.1