Loading Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt +7 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,13 @@ Optional properties: - qcom,vdd-supply: Regulator needed to access IOMMU - qcom,alt-vdd-supply : Alternative regulator needed to access IOMMU configuration registers. - interrupts : should contain the performance monitor overflow interrupt number. - interrupts : Interrupt numbers for permormance and global fault interrupts - interrupt-names: Refers to the interrupts number mentioned above. "pmon" : the performance monitor overflow interrupt number "global_cfg_NS_irq" : the global config non-secure interrupt number "global_client_NS_irq" : the global client non-secure interrupt number "global_cfg_S_irq" : the global config secure interrupt number "global_client_S_irq" : the global client secure interrupt number - qcom,iommu-enable-halt : Enable halt of the IOMMU before programming certain 19 registers - qcom,iommu-pmu-ngroups: Number of Performance Monitor Unit (PMU) groups. Loading arch/arm/boot/dts/msm-iommu-v1.dtsi +66 −11 Original line number Diff line number Diff line Loading @@ -18,7 +18,12 @@ ranges; reg = <0xfda64000 0x10000>; reg-names = "iommu_base"; interrupts = <0 67 0>; interrupts = <0 67 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,needs-alt-core-clk; label = "jpeg_iommu"; status = "disabled"; Loading Loading @@ -113,7 +118,12 @@ ranges; reg = <0xfd928000 0x10000>; reg-names = "iommu_base"; interrupts = <0 73 0>; interrupts = <0 73 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <1>; label = "mdp_iommu"; qcom,msm-bus,name = "mdp_ebi"; Loading Loading @@ -217,7 +227,12 @@ reg = <0xfdc84000 0x10000 0xfdce0004 0x4>; reg-names = "iommu_base", "clk_base"; interrupts = <0 45 0>; interrupts = <0 45 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <0>; qcom,needs-alt-core-clk; label = "venus_iommu"; Loading Loading @@ -333,7 +348,12 @@ ranges; reg = <0xfdb10000 0x10000>; reg-names = "iommu_base"; interrupts = <0 38 0>; interrupts = <0 38 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; label = "kgsl_iommu"; qcom,msm-bus,name = "kgsl_ebi"; qcom,msm-bus,num-cases = <2>; Loading Loading @@ -422,7 +442,12 @@ ranges; reg = <0xfda44000 0x10000>; reg-names = "iommu_base"; interrupts = <0 62 0>; interrupts = <0 62 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,needs-alt-core-clk; label = "vfe_iommu"; qcom,msm-bus,name = "vfe_ebi"; Loading Loading @@ -523,7 +548,12 @@ ranges; reg = <0xf9bc4000 0x10000>; reg-names = "iommu_base"; interrupts = <0 153 0>; interrupts = <0 153 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <8>; label = "copss_iommu"; qcom,msm-bus,name = "copss_ebi"; Loading Loading @@ -682,7 +712,12 @@ ranges; reg = <0xfdee4000 0x10000>; reg-names = "iommu_base"; interrupts = <0 147 0>; interrupts = <0 147 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <7>; label = "vpu_iommu"; qcom,msm-bus,name = "vpu_ebi"; Loading Loading @@ -815,7 +850,12 @@ ranges; reg = <0xfe054000 0x10000>; reg-names = "iommu_base"; interrupts = <0 202 0>; interrupts = <0 202 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <2>; label = "lpass_qdsp_iommu"; qcom,msm-bus,name = "lpass_qdsp_ebi"; Loading Loading @@ -943,7 +983,12 @@ ranges; reg = <0xfe064000 0x10000>; reg-names = "iommu_base"; interrupts = <0 166 0>; interrupts = <0 166 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <6>; label = "lpass_core_iommu"; qcom,msm-bus,name = "lpass_core_ebi"; Loading Loading @@ -1063,7 +1108,12 @@ ranges; reg = <0xfdfb6000 0x10000>; reg-names = "iommu_base"; interrupts = <0 315 0>; interrupts = <0 315 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,needs-alt-core-clk; label = "vcap_iommu"; status = "disabled"; Loading Loading @@ -1156,7 +1206,12 @@ ranges; reg = <0xfc734000 0x10000>; reg-names = "iommu_base"; interrupts = <0 279 0>; interrupts = <0 279 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,needs-alt-core-clk; label = "bcast_iommu"; status = "disabled"; Loading arch/arm/mach-msm/include/mach/iommu.h +1 −0 Original line number Diff line number Diff line Loading @@ -236,6 +236,7 @@ void print_ctx_regs(struct msm_iommu_context_reg regs[]); * interrupt is not supported in the API yet, but this will print an error * message and dump useful IOMMU registers. */ irqreturn_t msm_iommu_global_fault_handler(int irq, void *dev_id); irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id); irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id); irqreturn_t msm_iommu_secure_fault_handler_v2(int irq, void *dev_id); Loading drivers/iommu/msm_iommu-v1.c +69 −0 Original line number Diff line number Diff line Loading @@ -1026,6 +1026,75 @@ static void __print_ctx_regs(void __iomem *base, int ctx, unsigned int fsr) print_ctx_regs(regs); } static void print_global_regs(void __iomem *base, unsigned int gfsr) { pr_err("GFAR = %016llx\n", GET_GFAR(base)); pr_err("GFSR = %08x [%s%s%s%s%s%s%s%s%s%s]\n", gfsr, (gfsr & 0x01) ? "ICF " : "", (gfsr & 0x02) ? "USF " : "", (gfsr & 0x04) ? "SMCF " : "", (gfsr & 0x08) ? "UCBF " : "", (gfsr & 0x10) ? "UCIF " : "", (gfsr & 0x20) ? "CAF " : "", (gfsr & 0x40) ? "EF " : "", (gfsr & 0x80) ? "PF " : "", (gfsr & 0x40000000) ? "SS " : "", (gfsr & 0x80000000) ? "MULTI " : ""); pr_err("GFSYNR0 = %08x\n", GET_GFSYNR0(base)); pr_err("GFSYNR1 = %08x\n", GET_GFSYNR1(base)); pr_err("GFSYNR2 = %08x\n", GET_GFSYNR2(base)); } irqreturn_t msm_iommu_global_fault_handler(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct msm_iommu_drvdata *drvdata; unsigned int gfsr; int ret; mutex_lock(&msm_iommu_lock); BUG_ON(!pdev); drvdata = dev_get_drvdata(&pdev->dev); BUG_ON(!drvdata); if (!drvdata->ctx_attach_count) { pr_err("Unexpected IOMMU global fault !!\n"); pr_err("name = %s\n", drvdata->name); pr_err("Power is OFF. Can't read global fault information\n"); ret = IRQ_HANDLED; goto fail; } if (drvdata->sec_id != -1) { pr_err("NON-secure interrupt from secure %s\n", drvdata->name); ret = IRQ_HANDLED; goto fail; } ret = __enable_clocks(drvdata); if (ret) { ret = IRQ_NONE; goto fail; } gfsr = GET_GFSR(drvdata->base); if (gfsr) { pr_err("Unexpected %s global fault !!\n", drvdata->name); print_global_regs(drvdata->base, gfsr); SET_GFSR(drvdata->base, gfsr); ret = IRQ_HANDLED; } else ret = IRQ_NONE; __disable_clocks(drvdata); fail: mutex_unlock(&msm_iommu_lock); return ret; } irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id) { struct platform_device *pdev = dev_id; Loading drivers/iommu/msm_iommu_dev-v1.c +30 −0 Original line number Diff line number Diff line Loading @@ -282,6 +282,7 @@ static int msm_iommu_probe(struct platform_device *pdev) struct msm_iommu_drvdata *drvdata; struct resource *r; int ret, needs_alt_core_clk; int global_cfg_irq, global_client_irq; drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) Loading Loading @@ -368,6 +369,35 @@ static int msm_iommu_probe(struct platform_device *pdev) } } } global_cfg_irq = platform_get_irq_byname(pdev, "global_cfg_NS_irq"); if (global_cfg_irq > 0) { ret = devm_request_threaded_irq(&pdev->dev, global_cfg_irq, NULL, msm_iommu_global_fault_handler, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING, "msm_iommu_global_cfg_irq", pdev); if (ret < 0) pr_err("Request Global CFG IRQ %d failed with ret=%d\n", global_cfg_irq, ret); } global_client_irq = platform_get_irq_byname(pdev, "global_client_NS_irq"); if (global_client_irq > 0) { ret = devm_request_threaded_irq(&pdev->dev, global_client_irq, NULL, msm_iommu_global_fault_handler, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING, "msm_iommu_global_client_irq", pdev); if (ret < 0) pr_err("Request Global Client IRQ %d failed with ret=%d\n", global_client_irq, ret); } return 0; } Loading Loading
Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt +7 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,13 @@ Optional properties: - qcom,vdd-supply: Regulator needed to access IOMMU - qcom,alt-vdd-supply : Alternative regulator needed to access IOMMU configuration registers. - interrupts : should contain the performance monitor overflow interrupt number. - interrupts : Interrupt numbers for permormance and global fault interrupts - interrupt-names: Refers to the interrupts number mentioned above. "pmon" : the performance monitor overflow interrupt number "global_cfg_NS_irq" : the global config non-secure interrupt number "global_client_NS_irq" : the global client non-secure interrupt number "global_cfg_S_irq" : the global config secure interrupt number "global_client_S_irq" : the global client secure interrupt number - qcom,iommu-enable-halt : Enable halt of the IOMMU before programming certain 19 registers - qcom,iommu-pmu-ngroups: Number of Performance Monitor Unit (PMU) groups. Loading
arch/arm/boot/dts/msm-iommu-v1.dtsi +66 −11 Original line number Diff line number Diff line Loading @@ -18,7 +18,12 @@ ranges; reg = <0xfda64000 0x10000>; reg-names = "iommu_base"; interrupts = <0 67 0>; interrupts = <0 67 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,needs-alt-core-clk; label = "jpeg_iommu"; status = "disabled"; Loading Loading @@ -113,7 +118,12 @@ ranges; reg = <0xfd928000 0x10000>; reg-names = "iommu_base"; interrupts = <0 73 0>; interrupts = <0 73 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <1>; label = "mdp_iommu"; qcom,msm-bus,name = "mdp_ebi"; Loading Loading @@ -217,7 +227,12 @@ reg = <0xfdc84000 0x10000 0xfdce0004 0x4>; reg-names = "iommu_base", "clk_base"; interrupts = <0 45 0>; interrupts = <0 45 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <0>; qcom,needs-alt-core-clk; label = "venus_iommu"; Loading Loading @@ -333,7 +348,12 @@ ranges; reg = <0xfdb10000 0x10000>; reg-names = "iommu_base"; interrupts = <0 38 0>; interrupts = <0 38 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; label = "kgsl_iommu"; qcom,msm-bus,name = "kgsl_ebi"; qcom,msm-bus,num-cases = <2>; Loading Loading @@ -422,7 +442,12 @@ ranges; reg = <0xfda44000 0x10000>; reg-names = "iommu_base"; interrupts = <0 62 0>; interrupts = <0 62 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,needs-alt-core-clk; label = "vfe_iommu"; qcom,msm-bus,name = "vfe_ebi"; Loading Loading @@ -523,7 +548,12 @@ ranges; reg = <0xf9bc4000 0x10000>; reg-names = "iommu_base"; interrupts = <0 153 0>; interrupts = <0 153 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <8>; label = "copss_iommu"; qcom,msm-bus,name = "copss_ebi"; Loading Loading @@ -682,7 +712,12 @@ ranges; reg = <0xfdee4000 0x10000>; reg-names = "iommu_base"; interrupts = <0 147 0>; interrupts = <0 147 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <7>; label = "vpu_iommu"; qcom,msm-bus,name = "vpu_ebi"; Loading Loading @@ -815,7 +850,12 @@ ranges; reg = <0xfe054000 0x10000>; reg-names = "iommu_base"; interrupts = <0 202 0>; interrupts = <0 202 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <2>; label = "lpass_qdsp_iommu"; qcom,msm-bus,name = "lpass_qdsp_ebi"; Loading Loading @@ -943,7 +983,12 @@ ranges; reg = <0xfe064000 0x10000>; reg-names = "iommu_base"; interrupts = <0 166 0>; interrupts = <0 166 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,iommu-secure-id = <6>; label = "lpass_core_iommu"; qcom,msm-bus,name = "lpass_core_ebi"; Loading Loading @@ -1063,7 +1108,12 @@ ranges; reg = <0xfdfb6000 0x10000>; reg-names = "iommu_base"; interrupts = <0 315 0>; interrupts = <0 315 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,needs-alt-core-clk; label = "vcap_iommu"; status = "disabled"; Loading Loading @@ -1156,7 +1206,12 @@ ranges; reg = <0xfc734000 0x10000>; reg-names = "iommu_base"; interrupts = <0 279 0>; interrupts = <0 279 0>, <0 229 0>, <0 231 0>, <0 230 0>, <0 232 0>; interrupt-names = "pmon", "global_cfg_NS_irq", "global_client_NS_irq", "global_cfg_S_irq", "global_client_S_irq"; qcom,needs-alt-core-clk; label = "bcast_iommu"; status = "disabled"; Loading
arch/arm/mach-msm/include/mach/iommu.h +1 −0 Original line number Diff line number Diff line Loading @@ -236,6 +236,7 @@ void print_ctx_regs(struct msm_iommu_context_reg regs[]); * interrupt is not supported in the API yet, but this will print an error * message and dump useful IOMMU registers. */ irqreturn_t msm_iommu_global_fault_handler(int irq, void *dev_id); irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id); irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id); irqreturn_t msm_iommu_secure_fault_handler_v2(int irq, void *dev_id); Loading
drivers/iommu/msm_iommu-v1.c +69 −0 Original line number Diff line number Diff line Loading @@ -1026,6 +1026,75 @@ static void __print_ctx_regs(void __iomem *base, int ctx, unsigned int fsr) print_ctx_regs(regs); } static void print_global_regs(void __iomem *base, unsigned int gfsr) { pr_err("GFAR = %016llx\n", GET_GFAR(base)); pr_err("GFSR = %08x [%s%s%s%s%s%s%s%s%s%s]\n", gfsr, (gfsr & 0x01) ? "ICF " : "", (gfsr & 0x02) ? "USF " : "", (gfsr & 0x04) ? "SMCF " : "", (gfsr & 0x08) ? "UCBF " : "", (gfsr & 0x10) ? "UCIF " : "", (gfsr & 0x20) ? "CAF " : "", (gfsr & 0x40) ? "EF " : "", (gfsr & 0x80) ? "PF " : "", (gfsr & 0x40000000) ? "SS " : "", (gfsr & 0x80000000) ? "MULTI " : ""); pr_err("GFSYNR0 = %08x\n", GET_GFSYNR0(base)); pr_err("GFSYNR1 = %08x\n", GET_GFSYNR1(base)); pr_err("GFSYNR2 = %08x\n", GET_GFSYNR2(base)); } irqreturn_t msm_iommu_global_fault_handler(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct msm_iommu_drvdata *drvdata; unsigned int gfsr; int ret; mutex_lock(&msm_iommu_lock); BUG_ON(!pdev); drvdata = dev_get_drvdata(&pdev->dev); BUG_ON(!drvdata); if (!drvdata->ctx_attach_count) { pr_err("Unexpected IOMMU global fault !!\n"); pr_err("name = %s\n", drvdata->name); pr_err("Power is OFF. Can't read global fault information\n"); ret = IRQ_HANDLED; goto fail; } if (drvdata->sec_id != -1) { pr_err("NON-secure interrupt from secure %s\n", drvdata->name); ret = IRQ_HANDLED; goto fail; } ret = __enable_clocks(drvdata); if (ret) { ret = IRQ_NONE; goto fail; } gfsr = GET_GFSR(drvdata->base); if (gfsr) { pr_err("Unexpected %s global fault !!\n", drvdata->name); print_global_regs(drvdata->base, gfsr); SET_GFSR(drvdata->base, gfsr); ret = IRQ_HANDLED; } else ret = IRQ_NONE; __disable_clocks(drvdata); fail: mutex_unlock(&msm_iommu_lock); return ret; } irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id) { struct platform_device *pdev = dev_id; Loading
drivers/iommu/msm_iommu_dev-v1.c +30 −0 Original line number Diff line number Diff line Loading @@ -282,6 +282,7 @@ static int msm_iommu_probe(struct platform_device *pdev) struct msm_iommu_drvdata *drvdata; struct resource *r; int ret, needs_alt_core_clk; int global_cfg_irq, global_client_irq; drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) Loading Loading @@ -368,6 +369,35 @@ static int msm_iommu_probe(struct platform_device *pdev) } } } global_cfg_irq = platform_get_irq_byname(pdev, "global_cfg_NS_irq"); if (global_cfg_irq > 0) { ret = devm_request_threaded_irq(&pdev->dev, global_cfg_irq, NULL, msm_iommu_global_fault_handler, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING, "msm_iommu_global_cfg_irq", pdev); if (ret < 0) pr_err("Request Global CFG IRQ %d failed with ret=%d\n", global_cfg_irq, ret); } global_client_irq = platform_get_irq_byname(pdev, "global_client_NS_irq"); if (global_client_irq > 0) { ret = devm_request_threaded_irq(&pdev->dev, global_client_irq, NULL, msm_iommu_global_fault_handler, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING, "msm_iommu_global_client_irq", pdev); if (ret < 0) pr_err("Request Global Client IRQ %d failed with ret=%d\n", global_client_irq, ret); } return 0; } Loading