From b1b0cf98bf04890d9eb591e2bb5b70bc1072ad2b Mon Sep 17 00:00:00 2001 From: Alpha Lin Date: Fri, 10 Jul 2015 14:35:26 +0800 Subject: [PATCH] VPU: add cru reset support. This depend on RESET_CONTROLLER enable on kernel. Signed-off-by: Alpha Lin --- arch/arm/mach-rockchip/vcodec_service.c | 76 ++++++++++++++----------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/arch/arm/mach-rockchip/vcodec_service.c b/arch/arm/mach-rockchip/vcodec_service.c index ea9827e82e3c..09e591e74b53 100755 --- a/arch/arm/mach-rockchip/vcodec_service.c +++ b/arch/arm/mach-rockchip/vcodec_service.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -495,6 +496,11 @@ typedef struct vpu_service_info { struct clk *clk_cabac; struct clk *pd_video; +#ifdef CONFIG_RESET_CONTROLLER + struct reset_control *rst_a; + struct reset_control *rst_h; + struct reset_control *rst_v; +#endif struct device *dev; u32 irq_status; @@ -770,26 +776,6 @@ static void vpu_put_clk(struct vpu_service_info *pservice) #endif } -static const u8 pmu_idle_map[] = { - [IDLE_REQ_VIDEO] = 7, -}; - -extern void __iomem *rk_cru_base; -static void cru_writel(u32 val, u32 offset) -{ - writel_relaxed(val, rk_cru_base + (offset)); - dsb(sy); -} - -extern int rk3368_pmu_set_idle_request(enum pmu_idle_req req, bool idle); -static inline void rk3368_cru_set_soft_reset(u32 idx, bool on) -{ - u32 val = on ? 0x10001U << (idx & 0xf) : 0x10000U << (idx & 0xf); - cru_writel(val, 0x31c); -} -#define SOFT_RST_VCODEC_AXI (7*16) -#define SOFT_RST_VCODEC_AHB (7*16+1) - static void vpu_reset(struct vpu_subdev_data *data) { struct vpu_service_info *pservice = data->pservice; @@ -829,17 +815,19 @@ static void vpu_reset(struct vpu_subdev_data *data) pservice->reg_resev = NULL; pr_info("for 3288/3368..."); - /**rk3368_pmu_set_idle_request(IDLE_REQ_VIDEO, true);*/ - /*rockchip_pmu_ops.set_idle_request(IDLE_REQ_VIDEO, true);*/ - /**rockchip_pmu_ops.set_power_domain(PD_VIDEO, false);*/ - /*rk3368_cru_set_soft_reset(SOFT_RST_VCODEC_AHB, true); - rk3368_cru_set_soft_reset(SOFT_RST_VCODEC_AXI, true); - mdelay(1); - rk3368_cru_set_soft_reset(SOFT_RST_VCODEC_AXI, false); - rk3368_cru_set_soft_reset(SOFT_RST_VCODEC_AHB, false);*/ - /**rockchip_pmu_ops.set_power_domain(PD_VIDEO, true);*/ - /*rockchip_pmu_ops.set_idle_request(IDLE_REQ_VIDEO, false);*/ - /**rk3368_pmu_set_idle_request(IDLE_REQ_VIDEO, false);*/ +#ifdef CONFIG_RESET_CONTROLLER + if (pservice->rst_a && pservice->rst_h) { + if (pservice->rst_v) + reset_control_assert(pservice->rst_v); + reset_control_assert(pservice->rst_a); + reset_control_assert(pservice->rst_h); + usleep_range(10, 20); + reset_control_deassert(pservice->rst_h); + reset_control_deassert(pservice->rst_a); + if (pservice->rst_v) + reset_control_deassert(pservice->rst_v); + } +#endif #if defined(CONFIG_VCODEC_MMU) if (data->mmu_dev && test_bit(MMU_ACTIVATED, &data->state)) { @@ -2352,6 +2340,28 @@ static void vcodec_read_property(struct device_node *np, return; #endif } + +#ifdef CONFIG_RESET_CONTROLLER + pservice->rst_a = devm_reset_control_get(pservice->dev, "video_a"); + pservice->rst_h = devm_reset_control_get(pservice->dev, "video_h"); + pservice->rst_v = devm_reset_control_get(pservice->dev, "video"); + + if (IS_ERR_OR_NULL(pservice->rst_a)) { + pr_warn("No reset resource define\n"); + pservice->rst_a = NULL; + } + + if (IS_ERR_OR_NULL(pservice->rst_h)) { + pr_warn("No reset resource define\n"); + pservice->rst_h = NULL; + } + + if (IS_ERR_OR_NULL(pservice->rst_v)) { + pr_warn("No reset resource define\n"); + pservice->rst_v = NULL; + } +#endif + of_property_read_string(np, "name", (const char**)&pservice->name); } @@ -2399,6 +2409,8 @@ static int vcodec_probe(struct platform_device *pdev) pr_info("probe device %s\n", dev_name(dev)); + pservice->dev = dev; + vcodec_read_property(np, pservice); vcodec_init_drvdata(pservice); @@ -2409,8 +2421,6 @@ static int vcodec_probe(struct platform_device *pdev) else pservice->dev_id = VCODEC_DEVICE_ID_COMBO; - pservice->dev = dev; - if (0 > vpu_get_clk(pservice)) goto err; -- 2.34.1