From: ljf Date: Fri, 8 Aug 2014 01:46:48 +0000 (+0800) Subject: rk3036, rk312x: add iommu switch in dts for vcodec and iep X-Git-Tag: firefly_0821_release~4916^2~32 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b2076f04e899a1fcabb800a4e5bcdf2ce2167919;p=firefly-linux-kernel-4.4.55.git rk3036, rk312x: add iommu switch in dts for vcodec and iep --- diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index 4f065c51a034..82c2229248fa 100755 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -643,8 +643,9 @@ }; }; - vpu: vpu_service@10108000 { + vpu: vpu_service@10108000 { compatible = "vpu_service"; + iommu_enabled = <1>; reg = <0x10108000 0x800>; interrupts = ; interrupt-names = "irq_dec"; @@ -656,6 +657,7 @@ hevc: hevc_service@1010c000 { compatible = "rockchip,hevc_service"; + iommu_enabled = <1>; reg = <0x1010c000 0x400>; interrupts = ; interrupt-names = "irq_dec"; @@ -663,7 +665,7 @@ clock-names = "aclk_vcodec", "hclk_vcodec", "clk_core"; name = "hevc_service"; status = "okay"; - }; + }; vop_mmu { dbgname = "vop"; diff --git a/arch/arm/boot/dts/rk312x.dtsi b/arch/arm/boot/dts/rk312x.dtsi index b587bc91f4af..637a6d6c83aa 100755 --- a/arch/arm/boot/dts/rk312x.dtsi +++ b/arch/arm/boot/dts/rk312x.dtsi @@ -657,6 +657,7 @@ vpu: vpu_service@10106000 { compatible = "vpu_service"; + iommu_enabled = <1>; reg = <0x10106000 0x800>; interrupts = , ; interrupt-names = "irq_enc", "irq_dec"; @@ -668,6 +669,7 @@ hevc: hevc_service@10104000 { compatible = "rockchip,hevc_service"; + iommu_enabled = <1>; reg = <0x10104000 0x400>; interrupts = ; interrupt-names = "irq_dec"; @@ -679,6 +681,7 @@ iep: iep@10108000 { compatible = "rockchip,iep"; + iommu_enabled = <1>; reg = <0x10108000 0x800>; interrupts = ; clocks = <&clk_gates9 8>, <&clk_gates9 7>; diff --git a/arch/arm/mach-rockchip/vcodec_service.c b/arch/arm/mach-rockchip/vcodec_service.c index 5ea3129b82f2..873e83fbb318 100755 --- a/arch/arm/mach-rockchip/vcodec_service.c +++ b/arch/arm/mach-rockchip/vcodec_service.c @@ -405,9 +405,9 @@ static const struct file_operations debug_vcodec_fops = { #define BIT_VCODEC_SEL_RK312X (1<<15) static void vcodec_enter_mode_nolock(enum vcodec_device_id id, u32 *reserved_mode) { - if (soc_is_rk3036() || soc_is_rk3126() || soc_is_rk3128()) { - int bits = soc_is_rk3036() ? BIT_VCODEC_SEL_RK3036 : BIT_VCODEC_SEL_RK312X; - void __iomem *addr = soc_is_rk3036() ? (RK_GRF_VIRT + RK3036_GRF_SOC_CON1) : (RK_GRF_VIRT + RK312X_GRF_SOC_CON1); + if (cpu_is_rk3036() || cpu_is_rk312x()) { + int bits = cpu_is_rk3036() ? BIT_VCODEC_SEL_RK3036 : BIT_VCODEC_SEL_RK312X; + void __iomem *addr = cpu_is_rk3036() ? (RK_GRF_VIRT + RK3036_GRF_SOC_CON1) : (RK_GRF_VIRT + RK312X_GRF_SOC_CON1); if (reserved_mode) *reserved_mode = readl_relaxed(addr); if (id == VCODEC_DEVICE_ID_HEVC) @@ -419,23 +419,23 @@ static void vcodec_enter_mode_nolock(enum vcodec_device_id id, u32 *reserved_mod static void vcodec_exit_mode_nolock(enum vcodec_device_id id, u32 reserved_mode) { - if (soc_is_rk3036() || soc_is_rk3126() || soc_is_rk3128()) { - int bits = soc_is_rk3036() ? BIT_VCODEC_SEL_RK3036 : BIT_VCODEC_SEL_RK312X; - void __iomem *addr = soc_is_rk3036() ? (RK_GRF_VIRT + RK3036_GRF_SOC_CON1) : (RK_GRF_VIRT + RK312X_GRF_SOC_CON1); + if (cpu_is_rk3036() || cpu_is_rk312x()) { + int bits = cpu_is_rk3036() ? BIT_VCODEC_SEL_RK3036 : BIT_VCODEC_SEL_RK312X; + void __iomem *addr = cpu_is_rk3036() ? (RK_GRF_VIRT + RK3036_GRF_SOC_CON1) : (RK_GRF_VIRT + RK312X_GRF_SOC_CON1); writel_relaxed(reserved_mode | (bits << 16), addr); } } static void vcodec_enter_mode(enum vcodec_device_id id) { - if (soc_is_rk3036() || soc_is_rk3126() || soc_is_rk3128()) + if (cpu_is_rk3036() || cpu_is_rk312x()) mutex_lock(&g_mode_mutex); vcodec_enter_mode_nolock(id, NULL); } static void vcodec_exit_mode(void) { - if (soc_is_rk3036() || soc_is_rk3126() || soc_is_rk3128()) + if (cpu_is_rk3036() || cpu_is_rk312x()) mutex_unlock(&g_mode_mutex); } @@ -462,7 +462,7 @@ static int vpu_get_clk(struct vpu_service_info *pservice) break; } - if (!soc_is_rk3036() && !soc_is_rk3126() && !soc_is_rk3128()) { + if (!cpu_is_rk3036() && !cpu_is_rk312x()) { 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"); @@ -472,7 +472,7 @@ static int vpu_get_clk(struct vpu_service_info *pservice) pservice->clk_cabac = NULL; } - if (!soc_is_rk3036() && !soc_is_rk3126() && !soc_is_rk3128()) { + if (!cpu_is_rk3036() && !cpu_is_rk312x()) { 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"); @@ -482,7 +482,7 @@ static int vpu_get_clk(struct vpu_service_info *pservice) pservice->pd_video = NULL; } } else { - if (!soc_is_rk3036() && !soc_is_rk3126() && !soc_is_rk3128()) { + if (!cpu_is_rk3036() && !cpu_is_rk312x()) { pservice->pd_video = devm_clk_get(pservice->dev, "pd_video"); if (IS_ERR(pservice->pd_video)) { dev_err(pservice->dev, "failed on clk_get pd_video\n"); @@ -493,7 +493,7 @@ static int vpu_get_clk(struct vpu_service_info *pservice) } } - if (soc_is_rk3126() || soc_is_rk3128()) { + if (cpu_is_rk312x()) { pservice->pd_video = devm_clk_get(pservice->dev, "pd_video"); if (IS_ERR(pservice->pd_video)) { dev_err(pservice->dev, "failed on clk_get pd_video\n"); @@ -1415,7 +1415,7 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, unsigned long return 0; } -#if 1 + static int vpu_service_check_hw(vpu_service_info *p, unsigned long hw_addr) { int ret = -EINVAL, i = 0; @@ -1442,7 +1442,6 @@ static int vpu_service_check_hw(vpu_service_info *p, unsigned long hw_addr) iounmap((void *)tmp); return ret; } -#endif static int vpu_service_open(struct inode *inode, struct file *filp) { @@ -1554,7 +1553,9 @@ static int vcodec_probe(struct platform_device *pdev) struct vpu_service_info *pservice = devm_kzalloc(dev, sizeof(struct vpu_service_info), GFP_KERNEL); char *prop = (char*)dev_name(dev); #if defined(CONFIG_VCODEC_MMU) + u32 iommu_en = 0; char mmu_dev_dts_name[40]; + of_property_read_u32(np, "iommu_enabled", &iommu_en); #endif pr_info("probe device %s\n", dev_name(dev)); @@ -1584,7 +1585,7 @@ static int vcodec_probe(struct platform_device *pdev) pservice->reg_pproc = NULL; atomic_set(&pservice->total_running, 0); pservice->enabled = false; -#if defined(CONFIG_VCODEC_MMU) +#if defined(CONFIG_VCODEC_MMU) pservice->mmu_dev = NULL; #endif pservice->dev = dev; @@ -1610,7 +1611,7 @@ static int vcodec_probe(struct platform_device *pdev) { u32 offset = res->start; - if (soc_is_rk3036()) { + if (cpu_is_rk3036()) { if (pservice->dev_id == VCODEC_DEVICE_ID_VPU) offset += 0x400; } @@ -1629,7 +1630,7 @@ static int vcodec_probe(struct platform_device *pdev) pservice->reg_size = pservice->dec_dev.iosize; - if (pservice->hw_info->hw_id != HEVC_ID && !soc_is_rk3036()) { + if (pservice->hw_info->hw_id != HEVC_ID && !cpu_is_rk3036()) { pservice->enc_dev.iobaseaddr = res->start + pservice->hw_info->enc_offset; pservice->enc_dev.iosize = pservice->hw_info->enc_io_size; @@ -1716,23 +1717,26 @@ static int vcodec_probe(struct platform_device *pdev) #endif #if defined(CONFIG_VCODEC_MMU) - pservice->ion_client = rockchip_ion_client_create("vpu"); - if (IS_ERR(pservice->ion_client)) { - dev_err(&pdev->dev, "failed to create ion client for vcodec"); - return PTR_ERR(pservice->ion_client); - } else { - dev_info(&pdev->dev, "vcodec ion client create success!\n"); - } + if (iommu_en) { + pservice->ion_client = rockchip_ion_client_create("vpu"); + if (IS_ERR(pservice->ion_client)) { + dev_err(&pdev->dev, "failed to create ion client for vcodec"); + return PTR_ERR(pservice->ion_client); + } else { + dev_info(&pdev->dev, "vcodec ion client create success!\n"); + } - if (pservice->hw_info->hw_id == HEVC_ID) - sprintf(mmu_dev_dts_name, "iommu,hevc_mmu"); - else - sprintf(mmu_dev_dts_name, "iommu,vpu_mmu"); - pservice->mmu_dev = rockchip_get_sysmmu_device_by_compatible(mmu_dev_dts_name); + if (pservice->hw_info->hw_id == HEVC_ID) + sprintf(mmu_dev_dts_name, "iommu,hevc_mmu"); + else + sprintf(mmu_dev_dts_name, "iommu,vpu_mmu"); - if (pservice->mmu_dev) { - platform_set_sysmmu(pservice->mmu_dev, pservice->dev); - iovmm_activate(pservice->dev); + pservice->mmu_dev = rockchip_get_sysmmu_device_by_compatible(mmu_dev_dts_name); + + if (pservice->mmu_dev) { + platform_set_sysmmu(pservice->mmu_dev, pservice->dev); + iovmm_activate(pservice->dev); + } } #endif @@ -1844,7 +1848,7 @@ static void get_hw_info(struct vpu_service_info *pservice) if (soc_is_rk3190() || soc_is_rk3288()) dec->maxDecPicWidth = 4096; - else if (soc_is_rk3036() || soc_is_rk3126() || soc_is_rk3128()) + else if (cpu_is_rk3036() || cpu_is_rk312x()) dec->maxDecPicWidth = 1920; else dec->maxDecPicWidth = configReg & 0x07FFU; @@ -1878,7 +1882,7 @@ static void get_hw_info(struct vpu_service_info *pservice) dec->refBufSupport |= 8; /* enable HW support for offset */ /// invalidate fuse register value in rk319x vpu and following. - if (!soc_is_rk3190() && !soc_is_rk3288() && !soc_is_rk3036() && !soc_is_rk3126() && !soc_is_rk3128()) { + if (!soc_is_rk3190() && !soc_is_rk3288() && !cpu_is_rk3036() && !cpu_is_rk312x()) { VPUHwFuseStatus_t hwFuseSts; /* Decoder fuse configuration */ u32 fuseReg = pservice->dec_dev.hwregs[VPU_DEC_HW_FUSE_CFG]; @@ -1995,7 +1999,7 @@ static void get_hw_info(struct vpu_service_info *pservice) } } - if (!soc_is_rk3036()) { + if (!cpu_is_rk3036()) { configReg = pservice->enc_dev.hwregs[63]; enc->maxEncodedWidth = configReg & ((1 << 11) - 1); enc->h264Enabled = (configReg >> 27) & 1; @@ -2018,7 +2022,7 @@ static void get_hw_info(struct vpu_service_info *pservice) pservice->bug_dec_addr = cpu_is_rk30xx(); } else { - if (soc_is_rk3036() || soc_is_rk3126() || soc_is_rk3128()) + if (cpu_is_rk3036() || cpu_is_rk312x()) dec->maxDecPicWidth = 1920; else dec->maxDecPicWidth = 4096; diff --git a/drivers/video/rockchip/iep/hw_iep_reg.c b/drivers/video/rockchip/iep/hw_iep_reg.c index 0552a3984fe7..810206eebf1d 100755 --- a/drivers/video/rockchip/iep/hw_iep_reg.c +++ b/drivers/video/rockchip/iep/hw_iep_reg.c @@ -1195,7 +1195,7 @@ void iep_config(iep_session *session, IEP_MSG *iep_msg) #if defined(CONFIG_IEP_IOMMU) INIT_LIST_HEAD(®->mem_region_list); -#endif +#endif //write config iep_config_src_size(iep_msg); @@ -1249,10 +1249,12 @@ void iep_config(iep_session *session, IEP_MSG *iep_msg) #endif #if defined(CONFIG_IEP_IOMMU) - if (0 > iep_reg_address_translate(&iep_service, reg)) { - IEP_ERR("error: translate reg address failed\n"); - kfree(reg); - return; + if (iep_service.iommu_dev) { + if (0 > iep_reg_address_translate(&iep_service, reg)) { + IEP_ERR("error: translate reg address failed\n"); + kfree(reg); + return; + } } #endif diff --git a/drivers/video/rockchip/iep/iep_drv.c b/drivers/video/rockchip/iep/iep_drv.c index d5c8d96b1025..f1d0114a201d 100755 --- a/drivers/video/rockchip/iep/iep_drv.c +++ b/drivers/video/rockchip/iep/iep_drv.c @@ -79,11 +79,13 @@ static void iep_reg_deinit(struct iep_reg *reg) #if defined(CONFIG_IEP_IOMMU) struct iep_mem_region *mem_region = NULL, *n; // release memory region attach to this registers table. - list_for_each_entry_safe(mem_region, n, ®->mem_region_list, reg_lnk) { - ion_unmap_iommu(iep_service.iommu_dev, iep_service.ion_client, mem_region->hdl); - ion_free(iep_service.ion_client, mem_region->hdl); - list_del_init(&mem_region->reg_lnk); - kfree(mem_region); + if (iep_service.iommu_dev) { + list_for_each_entry_safe(mem_region, n, ®->mem_region_list, reg_lnk) { + ion_unmap_iommu(iep_service.iommu_dev, iep_service.ion_client, mem_region->hdl); + ion_free(iep_service.ion_client, mem_region->hdl); + list_del_init(&mem_region->reg_lnk); + kfree(mem_region); + } } #endif list_del_init(®->session_link); @@ -797,7 +799,10 @@ static int iep_drv_probe(struct platform_device *pdev) int ret = 0; struct resource *res = NULL; #if defined(CONFIG_IEP_IOMMU) + u32 iommu_en = 0; struct device *mmu_dev = NULL; + struct device_node *np = pdev->dev.of_node; + of_property_read_u32(np, "iommu_enabled", &iommu_en); #endif data = (struct iep_drvdata*)devm_kzalloc(&pdev->dev, sizeof(struct iep_drvdata), GFP_KERNEL); @@ -884,24 +889,26 @@ static int iep_drv_probe(struct platform_device *pdev) #if defined(CONFIG_IEP_IOMMU) iep_service.iommu_dev = NULL; - iep_power_on(); - iep_service.ion_client = rockchip_ion_client_create("iep"); - if (IS_ERR(iep_service.ion_client)) { - IEP_ERR("failed to create ion client for vcodec"); - return PTR_ERR(iep_service.ion_client); - } else { - IEP_INFO("iep ion client create success!\n"); - } - - mmu_dev = rockchip_get_sysmmu_device_by_compatible("iommu,iep_mmu"); - - if (mmu_dev) { - platform_set_sysmmu(mmu_dev, &pdev->dev); - iovmm_activate(&pdev->dev); + if (iommu_en) { + iep_power_on(); + iep_service.ion_client = rockchip_ion_client_create("iep"); + if (IS_ERR(iep_service.ion_client)) { + IEP_ERR("failed to create ion client for vcodec"); + return PTR_ERR(iep_service.ion_client); + } else { + IEP_INFO("iep ion client create success!\n"); + } + + mmu_dev = rockchip_get_sysmmu_device_by_compatible("iommu,iep_mmu"); + + if (mmu_dev) { + platform_set_sysmmu(mmu_dev, &pdev->dev); + iovmm_activate(&pdev->dev); + } + + iep_service.iommu_dev = &pdev->dev; + iep_power_off(); } - - iep_service.iommu_dev = &pdev->dev; - iep_power_off(); #endif IEP_INFO("IEP Driver loaded succesfully\n");