From 6302d18dfddbec973dc03337a1dc504842accda1 Mon Sep 17 00:00:00 2001 From: Alpha Lin Date: Wed, 21 Jan 2015 08:47:18 +0800 Subject: [PATCH] RK32: vpu disable iommu when vpu catch a failure. Disable iommu when vpu in failure state, so iommu could restore its state in the next task in. Signed-off-by: Alpha Lin --- arch/arm/boot/dts/rk3288.dtsi | 2 ++ arch/arm/mach-rockchip/vcodec_service.c | 40 +++++++++++++++---------- 2 files changed, 27 insertions(+), 15 deletions(-) mode change 100755 => 100644 arch/arm/boot/dts/rk3288.dtsi diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi old mode 100755 new mode 100644 index 22e8d2cb82da..621110a49a67 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -1003,6 +1003,7 @@ clocks = <&clk_vdpu>, <&hclk_vdpu>; clock-names = "aclk_vcodec", "hclk_vcodec"; name = "vpu_service"; + dev_mode = <0>; //status = "disabled"; }; @@ -1014,6 +1015,7 @@ interrupt-names = "irq_dec"; clocks = <&aclk_hevc>, <&hclk_hevc>, <&clk_hevc_core>, <&clk_hevc_cabac>; clock-names = "aclk_vcodec", "hclk_vcodec", "clk_core", "clk_cabac"; + dev_mode = <1>; name = "hevc_service"; //status = "disabled"; }; diff --git a/arch/arm/mach-rockchip/vcodec_service.c b/arch/arm/mach-rockchip/vcodec_service.c index b472d3ad47df..9f6ccff39bb9 100644 --- a/arch/arm/mach-rockchip/vcodec_service.c +++ b/arch/arm/mach-rockchip/vcodec_service.c @@ -334,7 +334,7 @@ typedef struct vpu_reg { #if defined(CONFIG_VCODEC_MMU) struct list_head mem_region_list; #endif - unsigned long *reg; + u32 *reg; } vpu_reg; typedef struct vpu_device { @@ -515,10 +515,21 @@ static void vcodec_enter_mode(struct vpu_subdev_data *data) u32 raw = 0; struct vpu_service_info *pservice = data->pservice; struct vpu_subdev_data *subdata, *n; - if (pservice->subcnt < 2 || pservice->curr_mode == data->mode) { - pservice->prev_mode = pservice->curr_mode; + if (pservice->subcnt < 2) { +#if defined(CONFIG_VCODEC_MMU) + if (data->mmu_dev && !test_bit(MMU_ACTIVATED, &data->state)) { + set_bit(MMU_ACTIVATED, &data->state); + BUG_ON(!pservice->enabled); + if (pservice->enabled) + rockchip_iovmm_activate(data->dev); + } +#endif return; } + + if (pservice->curr_mode == data->mode) + return; + vpu_debug(3, "vcodec enter mode %d\n", data->mode); #if defined(CONFIG_VCODEC_MMU) list_for_each_entry_safe(subdata, n, &pservice->subdev_list, lnk_service) { @@ -570,18 +581,17 @@ static int vpu_get_clk(struct vpu_service_info *pservice) #if VCODEC_CLOCK_ENABLE switch (pservice->dev_id) { case VCODEC_DEVICE_ID_HEVC: - pservice->clk_cabac = devm_clk_get(pservice->dev, "clk_cabac"); - if (IS_ERR(pservice->clk_cabac)) { - dev_err(pservice->dev, "failed on clk_get clk_cabac\n"); - return -1; - } - pservice->pd_video = devm_clk_get(pservice->dev, "pd_hevc"); if (IS_ERR(pservice->pd_video)) { dev_err(pservice->dev, "failed on clk_get pd_hevc\n"); return -1; } case VCODEC_DEVICE_ID_COMBO: + pservice->clk_cabac = devm_clk_get(pservice->dev, "clk_cabac"); + if (IS_ERR(pservice->clk_cabac)) { + dev_err(pservice->dev, "failed on clk_get clk_cabac\n"); + pservice->clk_cabac = NULL; + } pservice->clk_core = devm_clk_get(pservice->dev, "clk_core"); if (IS_ERR(pservice->clk_core)) { dev_err(pservice->dev, "failed on clk_get clk_core\n"); @@ -664,11 +674,11 @@ static void vpu_reset(struct vpu_subdev_data *data) pservice->reg_resev = NULL; #if defined(CONFIG_VCODEC_MMU) - if (data->mmu_dev && !test_bit(MMU_ACTIVATED, &data->state)) { - set_bit(MMU_ACTIVATED, &data->state); + if (data->mmu_dev && test_bit(MMU_ACTIVATED, &data->state)) { + clear_bit(MMU_ACTIVATED, &data->state); BUG_ON(!pservice->enabled); if (pservice->enabled) - rockchip_iovmm_activate(data->dev); + rockchip_iovmm_deactivate(data->dev); } #endif } @@ -796,13 +806,13 @@ static void vpu_service_power_on(struct vpu_service_info *pservice) static inline bool reg_check_rmvb_wmv(vpu_reg *reg) { - unsigned long type = (reg->reg[3] & 0xF0000000) >> 28; + u32 type = (reg->reg[3] & 0xF0000000) >> 28; return ((type == 8) || (type == 4)); } static inline bool reg_check_interlace(vpu_reg *reg) { - unsigned long type = (reg->reg[3] & (1 << 23)); + u32 type = (reg->reg[3] & (1 << 23)); return (type > 0); } @@ -1055,7 +1065,7 @@ static vpu_reg *reg_init(struct vpu_subdev_data *data, reg->type = session->type; reg->size = size; reg->freq = VPU_FREQ_DEFAULT; - reg->reg = (unsigned long *)®[1]; + reg->reg = (u32 *)®[1]; INIT_LIST_HEAD(®->session_link); INIT_LIST_HEAD(®->status_link); -- 2.34.1