From a1364527e9326c1ab46f8fee3df79ceeecd34bab Mon Sep 17 00:00:00 2001 From: yxj Date: Thu, 11 Dec 2014 15:45:57 +0800 Subject: [PATCH] video: rockchip: rk32_dp: add support for rk3368 Signed-off-by: yxj --- drivers/video/rockchip/transmitter/rk32_dp.c | 108 +++++++++++++------ drivers/video/rockchip/transmitter/rk32_dp.h | 8 ++ 2 files changed, 82 insertions(+), 34 deletions(-) diff --git a/drivers/video/rockchip/transmitter/rk32_dp.c b/drivers/video/rockchip/transmitter/rk32_dp.c index 216118c361ac..70f692ba2f2d 100644 --- a/drivers/video/rockchip/transmitter/rk32_dp.c +++ b/drivers/video/rockchip/transmitter/rk32_dp.c @@ -12,20 +12,20 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ -#include -#include -#include -#include -#include -#include +#include #include +#include +#include #include -#include +#include +#include #include -#include +#include #include #include -#include "rk32_dp.h" +#include +#include +#include #if defined(CONFIG_OF) #include @@ -37,16 +37,27 @@ #include #endif +#include "rk32_dp.h" + /*#define EDP_BIST_MODE*/ /*#define SW_LT*/ + +#define RK3368_GRF_SOC_CON4 0x410 + static struct rk32_edp *rk32_edp; static int rk32_edp_clk_enable(struct rk32_edp *edp) { + int ret; + if (!edp->clk_on) { - clk_prepare_enable(edp->pd); + if (edp->pd) + clk_prepare_enable(edp->pd); clk_prepare_enable(edp->pclk); clk_prepare_enable(edp->clk_edp); + ret = clk_set_rate(edp->clk_24m, 24000000); + if (ret < 0) + dev_err(edp->dev, "cannot set edp clk_24m %d\n", ret); clk_prepare_enable(edp->clk_24m); edp->clk_on = true; } @@ -60,30 +71,39 @@ static int rk32_edp_clk_disable(struct rk32_edp *edp) clk_disable_unprepare(edp->pclk); clk_disable_unprepare(edp->clk_edp); clk_disable_unprepare(edp->clk_24m); - clk_disable_unprepare(edp->pd); + if (edp->pd) + clk_disable_unprepare(edp->pd); edp->clk_on = false; } return 0; } -static int rk32_edp_pre_init(void) +static int rk32_edp_pre_init(struct rk32_edp *edp) { u32 val; - val = GRF_EDP_REF_CLK_SEL_INTER | (GRF_EDP_REF_CLK_SEL_INTER << 16); - writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_SOC_CON12); - - val = 0x80008000; - writel_relaxed(val, RK_CRU_VIRT + 0x0d0); /*select 24m*/ - dsb(sy); - val = 0x80008000; - writel_relaxed(val, RK_CRU_VIRT + 0x01d0); /*reset edp*/ - dsb(sy); - udelay(1); - val = 0x80000000; - writel_relaxed(val, RK_CRU_VIRT + 0x01d0); - dsb(sy); - udelay(1); + + if (cpu_is_rk3288()) { + val = GRF_EDP_REF_CLK_SEL_INTER | + (GRF_EDP_REF_CLK_SEL_INTER << 16); + writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_SOC_CON12); + + val = 0x80008000; + writel_relaxed(val, RK_CRU_VIRT + 0x01d0); /*reset edp*/ + dsb(sy); + udelay(1); + val = 0x80000000; + writel_relaxed(val, RK_CRU_VIRT + 0x01d0); + dsb(sy); + udelay(1); + } else { + val = 0x01 | (0x01 << 16); + regmap_write(edp->grf, RK3368_GRF_SOC_CON4, val); + + reset_control_assert(edp->rst_24m); + usleep_range(10, 20); + reset_control_deassert(edp->rst_24m); + } return 0; } @@ -93,11 +113,14 @@ static int rk32_edp_init_edp(struct rk32_edp *edp) u32 val = 0; rk_fb_get_prmry_screen(screen); - if (screen->lcdc_id == 1) /*select lcdc*/ - val = EDP_SEL_VOP_LIT | (EDP_SEL_VOP_LIT << 16); - else - val = EDP_SEL_VOP_LIT << 16; - writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_SOC_CON6); + + if (cpu_is_rk3288()) { + if (screen->lcdc_id == 1) /*select lcdc*/ + val = EDP_SEL_VOP_LIT | (EDP_SEL_VOP_LIT << 16); + else + val = EDP_SEL_VOP_LIT << 16; + writel_relaxed(val, RK_GRF_VIRT + RK3288_GRF_SOC_CON6); + } rk32_edp_reset(edp); rk32_edp_init_refclk(edp); @@ -1153,7 +1176,7 @@ static int rk32_edp_enable(void) rk32_edp_clk_enable(edp); - rk32_edp_pre_init(); + rk32_edp_pre_init(edp); rk32_edp_init_edp(edp); enable_irq(edp->irq); /*ret = rk32_edp_handle_edid(edp); @@ -1352,9 +1375,18 @@ static int rk32_edp_probe(struct platform_device *pdev) return PTR_ERR(edp->regs); } + edp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); + if (IS_ERR(edp->grf)) { + dev_err(&pdev->dev, "can't find rockchip,grf property\n"); + return PTR_ERR(edp->grf); + } + edp->pd = devm_clk_get(&pdev->dev, "pd_edp"); - if (IS_ERR(edp->pd)) + if (IS_ERR(edp->pd)) { dev_err(&pdev->dev, "cannot get pd\n"); + edp->pd = NULL; + } + edp->clk_edp = devm_clk_get(&pdev->dev, "clk_edp"); if (IS_ERR(edp->clk_edp)) { dev_err(&pdev->dev, "cannot get clk_edp\n"); @@ -1372,9 +1404,17 @@ static int rk32_edp_probe(struct platform_device *pdev) dev_err(&pdev->dev, "cannot get pclk\n"); return PTR_ERR(edp->pclk); } + + /*edp 24m need sorft reset*/ + edp->rst_24m = devm_reset_control_get(&pdev->dev, "edp_24m"); + if (IS_ERR(edp->rst_24m)) { + dev_err(&pdev->dev, "failed to get reset\n"); + return PTR_ERR(edp->rst_24m); + } + rk32_edp_clk_enable(edp); if (!support_uboot_display()) - rk32_edp_pre_init(); + rk32_edp_pre_init(edp); edp->irq = platform_get_irq(pdev, 0); if (edp->irq < 0) { dev_err(&pdev->dev, "cannot find IRQ\n"); diff --git a/drivers/video/rockchip/transmitter/rk32_dp.h b/drivers/video/rockchip/transmitter/rk32_dp.h index de90cf29dc45..a1c6909b1528 100644 --- a/drivers/video/rockchip/transmitter/rk32_dp.h +++ b/drivers/video/rockchip/transmitter/rk32_dp.h @@ -1,6 +1,11 @@ #ifndef __RK32_DP_H #define __RK32_DP_H + +#include +#include +#include #include + #include "dpcd_edid.h" #define DP_VERSION 0x10 @@ -513,11 +518,14 @@ struct link_train { struct rk32_edp { struct device *dev; void __iomem *regs; + struct regmap *grf; unsigned int irq; struct clk *pd; struct clk *clk_edp; /*clk for edp controller*/ struct clk *clk_24m; /*clk for edp phy*/ struct clk *pclk; /*clk for phb bus*/ + struct reset_control *rst_24m; + struct reset_control *rst_apb; struct link_train link_train; struct video_info video_info; struct rk_screen screen; -- 2.34.1