Loading Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ Optional properties: - qcom,iommu-pmu-event-classes: List of event classes supported. - Bus scaling properties: See msm_bus.txt - qcom,no-atos-support: boolean indicating that IOMMU doesn't have ATS support - qcom,cb-base-offset: context bank 0's base address from global base address - List of sub nodes, one for each of the translation context banks supported. Each sub node has the following required properties: Loading arch/arm/mach-msm/include/mach/iommu.h +1 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ struct msm_iommu_bfb_settings { struct msm_iommu_drvdata { void __iomem *base; void __iomem *glb_base; void __iomem *cb_base; int ncb; int ttbr_split; struct clk *clk; Loading arch/arm/mach-msm/include/mach/iommu_hw-v1.h +8 −9 Original line number Diff line number Diff line Loading @@ -14,14 +14,13 @@ #define __ARCH_ARM_MACH_MSM_IOMMU_HW_V2_H #define CTX_SHIFT 12 #define CTX_OFFSET 0x8000 #define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg))) #define GET_GLOBAL_REG_Q(reg, base) (readq_relaxed((base) + (reg))) #define GET_CTX_REG(reg, base, ctx) \ (readl_relaxed((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT))) (readl_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT))) #define GET_CTX_REG_Q(reg, base, ctx) \ (readq_relaxed((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT))) (readq_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT))) #define SET_GLOBAL_REG(reg, base, val) writel_relaxed((val), ((base) + (reg))) #define SET_GLOBAL_REG_Q(reg, base, val) \ Loading @@ -29,10 +28,10 @@ #define SET_CTX_REG(reg, base, ctx, val) \ writel_relaxed((val), \ ((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT))) ((base) + (reg) + ((ctx) << CTX_SHIFT))) #define SET_CTX_REG_Q(reg, base, ctx, val) \ writeq_relaxed((val), \ ((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT))) ((base) + (reg) + ((ctx) << CTX_SHIFT))) /* Wrappers for numbered registers */ #define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG((b), ((r) + (n << 2)), (v)) Loading @@ -42,19 +41,19 @@ #define GET_GLOBAL_FIELD(b, r, F) \ GET_FIELD(((b) + (r)), r##_##F##_MASK, r##_##F##_SHIFT) #define GET_CONTEXT_FIELD(b, c, r, F) \ GET_FIELD(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \ GET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), \ r##_##F##_MASK, r##_##F##_SHIFT) #define GET_CONTEXT_FIELD_Q(b, c, r, F) \ GET_FIELD_Q(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \ GET_FIELD_Q(((b) + (r) + ((c) << CTX_SHIFT)), \ r##_##F##_MASK, r##_##F##_SHIFT) #define SET_GLOBAL_FIELD(b, r, F, v) \ SET_FIELD(((b) + (r)), r##_##F##_MASK, r##_##F##_SHIFT, (v)) #define SET_CONTEXT_FIELD(b, c, r, F, v) \ SET_FIELD(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \ SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), \ r##_##F##_MASK, r##_##F##_SHIFT, (v)) #define SET_CONTEXT_FIELD_Q(b, c, r, F, v) \ SET_FIELD_Q(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \ SET_FIELD_Q(((b) + (r) + ((c) << CTX_SHIFT)), \ r##_##F##_MASK, r##_##F##_SHIFT, (v)) /* Wrappers for numbered field registers */ Loading drivers/iommu/msm_iommu-v1.c +27 −24 Original line number Diff line number Diff line Loading @@ -239,10 +239,10 @@ static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va) if (ret) goto fail; SET_TLBIVA(iommu_drvdata->base, ctx_drvdata->num, SET_TLBIVA(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid | (va & CB_TLBIVA_VA)); mb(); __sync_tlb(iommu_drvdata->base, ctx_drvdata->num); __sync_tlb(iommu_drvdata->cb_base, ctx_drvdata->num); __disable_clocks(iommu_drvdata); } fail: Loading @@ -266,10 +266,10 @@ static int __flush_iotlb(struct iommu_domain *domain) if (ret) goto fail; SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, SET_TLBIASID(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid); mb(); __sync_tlb(iommu_drvdata->base, ctx_drvdata->num); __sync_tlb(iommu_drvdata->cb_base, ctx_drvdata->num); __disable_clocks(iommu_drvdata); } Loading Loading @@ -410,7 +410,7 @@ static void msm_iommu_assign_ASID(const struct msm_iommu_drvdata *iommu_drvdata, struct msm_iommu_priv *priv) { unsigned int found = 0; void __iomem *base = iommu_drvdata->base; void __iomem *cb_base = iommu_drvdata->cb_base; unsigned int i; unsigned int ncb = iommu_drvdata->ncb; struct msm_iommu_ctx_drvdata *tmp_drvdata; Loading Loading @@ -438,7 +438,7 @@ static void msm_iommu_assign_ASID(const struct msm_iommu_drvdata *iommu_drvdata, BUG_ON(!found); } msm_iommu_set_ASID(base, curr_ctx->num, curr_ctx->asid); msm_iommu_set_ASID(cb_base, curr_ctx->num, curr_ctx->asid); } #ifdef CONFIG_IOMMU_LPAE Loading Loading @@ -542,30 +542,31 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata, { phys_addr_t pn; void __iomem *base = iommu_drvdata->base; void __iomem *cb_base = iommu_drvdata->cb_base; unsigned int ctx = ctx_drvdata->num; phys_addr_t pgtable = __pa(priv->pt.fl_table); __reset_context(base, ctx); msm_iommu_setup_ctx(base, ctx); __reset_context(cb_base, ctx); msm_iommu_setup_ctx(cb_base, ctx); if (priv->pt.redirect) msm_iommu_setup_pg_l2_redirect(base, ctx); msm_iommu_setup_pg_l2_redirect(cb_base, ctx); msm_iommu_setup_memory_remap(base, ctx); msm_iommu_setup_memory_remap(cb_base, ctx); pn = pgtable >> CB_TTBR0_ADDR_SHIFT; SET_CB_TTBR0_ADDR(base, ctx, pn); SET_CB_TTBR0_ADDR(cb_base, ctx, pn); /* Enable context fault interrupt */ SET_CB_SCTLR_CFIE(base, ctx, 1); SET_CB_SCTLR_CFIE(cb_base, ctx, 1); /* Redirect all cacheable requests to L2 slave port. */ SET_CB_ACTLR_BPRCISH(base, ctx, 1); SET_CB_ACTLR_BPRCOSH(base, ctx, 1); SET_CB_ACTLR_BPRCNSH(base, ctx, 1); SET_CB_ACTLR_BPRCISH(cb_base, ctx, 1); SET_CB_ACTLR_BPRCOSH(cb_base, ctx, 1); SET_CB_ACTLR_BPRCNSH(cb_base, ctx, 1); /* Enable private ASID namespace */ SET_CB_SCTLR_ASIDPNE(base, ctx, 1); SET_CB_SCTLR_ASIDPNE(cb_base, ctx, 1); if (!is_secure) { if (program_m2v) Loading Loading @@ -593,7 +594,7 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata, msm_iommu_assign_ASID(iommu_drvdata, ctx_drvdata, priv); /* Enable the MMU */ SET_CB_SCTLR_M(base, ctx, 1); SET_CB_SCTLR_M(cb_base, ctx, 1); mb(); } Loading Loading @@ -768,7 +769,8 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain, is_secure = iommu_drvdata->sec_id != -1; SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, ctx_drvdata->asid); SET_TLBIASID(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid); BUG_ON(iommu_drvdata->asid[ctx_drvdata->asid - 1] == 0); iommu_drvdata->asid[ctx_drvdata->asid - 1]--; Loading @@ -776,7 +778,7 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain, iommu_halt(iommu_drvdata); __reset_context(iommu_drvdata->base, ctx_drvdata->num); __reset_context(iommu_drvdata->cb_base, ctx_drvdata->num); /* * Only reset the M2V tables on the very last detach */ Loading Loading @@ -940,7 +942,7 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain, return ret; } base = iommu_drvdata->base; base = iommu_drvdata->cb_base; ctx = ctx_drvdata->num; ret = __enable_clocks(iommu_drvdata); Loading Loading @@ -1180,7 +1182,7 @@ irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id) goto fail; } fsr = GET_FSR(drvdata->base, ctx_drvdata->num); fsr = GET_FSR(drvdata->cb_base, ctx_drvdata->num); if (fsr) { if (!ctx_drvdata->attached_domain) { pr_err("Bad domain in interrupt handler\n"); Loading @@ -1188,7 +1190,7 @@ irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id) } else ret = report_iommu_fault(ctx_drvdata->attached_domain, &ctx_drvdata->pdev->dev, GET_FAR(drvdata->base, ctx_drvdata->num), 0); GET_FAR(drvdata->cb_base, ctx_drvdata->num), 0); if (ret == -ENOSYS) { pr_err("Unexpected IOMMU page fault!\n"); Loading @@ -1196,11 +1198,12 @@ irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id) pr_err("context = %s (%d)\n", ctx_drvdata->name, ctx_drvdata->num); pr_err("Interesting registers:\n"); __print_ctx_regs(drvdata->base, ctx_drvdata->num, fsr); __print_ctx_regs(drvdata->cb_base, ctx_drvdata->num, fsr); } if (ret != -EBUSY) SET_FSR(drvdata->base, ctx_drvdata->num, fsr); SET_FSR(drvdata->cb_base, ctx_drvdata->num, fsr); ret = IRQ_HANDLED; } else ret = IRQ_NONE; Loading drivers/iommu/msm_iommu_dev-v1.c +18 −5 Original line number Diff line number Diff line Loading @@ -287,6 +287,7 @@ static int msm_iommu_probe(struct platform_device *pdev) struct resource *r; int ret, needs_alt_core_clk, needs_alt_iface_clk; int global_cfg_irq, global_client_irq; u32 temp; drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) Loading Loading @@ -343,6 +344,13 @@ static int msm_iommu_probe(struct platform_device *pdev) drvdata->no_atos_support = of_property_read_bool(pdev->dev.of_node, "qcom,no-atos-support"); if (!of_property_read_u32(pdev->dev.of_node, "qcom,cb-base-offset", &temp)) drvdata->cb_base = drvdata->base + temp; else drvdata->cb_base = drvdata->base + 0x8000; if (clk_get_rate(drvdata->clk) == 0) { ret = clk_round_rate(drvdata->clk, 1000); clk_set_rate(drvdata->clk, ret); Loading Loading @@ -442,7 +450,9 @@ static int msm_iommu_ctx_parse_dt(struct platform_device *pdev, { struct resource *r, rp; int irq = 0, ret = 0; struct msm_iommu_drvdata *drvdata; u32 nsid; unsigned long cb_offset; get_secure_ctx(pdev->dev.of_node, ctx_drvdata); Loading Loading @@ -484,12 +494,15 @@ static int msm_iommu_ctx_parse_dt(struct platform_device *pdev, if (ret) goto out; /* Calculate the context bank number using the base addresses. The * first 8 pages belong to the global address space which is followed * by the context banks, hence subtract by 8 to get the context bank * number. /* Calculate the context bank number using the base addresses. * Typically CB0 base address is 0x8000 pages away if the number * of CBs are <=8. So, assume the offset 0x8000 until mentioned * explicitely. */ ctx_drvdata->num = ((r->start - rp.start) >> CTX_SHIFT) - 8; drvdata = dev_get_drvdata(pdev->dev.parent); cb_offset = drvdata->cb_base - drvdata->base; ctx_drvdata->num = ((r->start - rp.start - cb_offset) >> CTX_SHIFT); if (of_property_read_string(pdev->dev.of_node, "label", &ctx_drvdata->name)) Loading Loading
Documentation/devicetree/bindings/iommu/msm_iommu_v1.txt +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ Optional properties: - qcom,iommu-pmu-event-classes: List of event classes supported. - Bus scaling properties: See msm_bus.txt - qcom,no-atos-support: boolean indicating that IOMMU doesn't have ATS support - qcom,cb-base-offset: context bank 0's base address from global base address - List of sub nodes, one for each of the translation context banks supported. Each sub node has the following required properties: Loading
arch/arm/mach-msm/include/mach/iommu.h +1 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ struct msm_iommu_bfb_settings { struct msm_iommu_drvdata { void __iomem *base; void __iomem *glb_base; void __iomem *cb_base; int ncb; int ttbr_split; struct clk *clk; Loading
arch/arm/mach-msm/include/mach/iommu_hw-v1.h +8 −9 Original line number Diff line number Diff line Loading @@ -14,14 +14,13 @@ #define __ARCH_ARM_MACH_MSM_IOMMU_HW_V2_H #define CTX_SHIFT 12 #define CTX_OFFSET 0x8000 #define GET_GLOBAL_REG(reg, base) (readl_relaxed((base) + (reg))) #define GET_GLOBAL_REG_Q(reg, base) (readq_relaxed((base) + (reg))) #define GET_CTX_REG(reg, base, ctx) \ (readl_relaxed((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT))) (readl_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT))) #define GET_CTX_REG_Q(reg, base, ctx) \ (readq_relaxed((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT))) (readq_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT))) #define SET_GLOBAL_REG(reg, base, val) writel_relaxed((val), ((base) + (reg))) #define SET_GLOBAL_REG_Q(reg, base, val) \ Loading @@ -29,10 +28,10 @@ #define SET_CTX_REG(reg, base, ctx, val) \ writel_relaxed((val), \ ((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT))) ((base) + (reg) + ((ctx) << CTX_SHIFT))) #define SET_CTX_REG_Q(reg, base, ctx, val) \ writeq_relaxed((val), \ ((base) + CTX_OFFSET + (reg) + ((ctx) << CTX_SHIFT))) ((base) + (reg) + ((ctx) << CTX_SHIFT))) /* Wrappers for numbered registers */ #define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG((b), ((r) + (n << 2)), (v)) Loading @@ -42,19 +41,19 @@ #define GET_GLOBAL_FIELD(b, r, F) \ GET_FIELD(((b) + (r)), r##_##F##_MASK, r##_##F##_SHIFT) #define GET_CONTEXT_FIELD(b, c, r, F) \ GET_FIELD(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \ GET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), \ r##_##F##_MASK, r##_##F##_SHIFT) #define GET_CONTEXT_FIELD_Q(b, c, r, F) \ GET_FIELD_Q(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \ GET_FIELD_Q(((b) + (r) + ((c) << CTX_SHIFT)), \ r##_##F##_MASK, r##_##F##_SHIFT) #define SET_GLOBAL_FIELD(b, r, F, v) \ SET_FIELD(((b) + (r)), r##_##F##_MASK, r##_##F##_SHIFT, (v)) #define SET_CONTEXT_FIELD(b, c, r, F, v) \ SET_FIELD(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \ SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), \ r##_##F##_MASK, r##_##F##_SHIFT, (v)) #define SET_CONTEXT_FIELD_Q(b, c, r, F, v) \ SET_FIELD_Q(((b) + CTX_OFFSET + (r) + ((c) << CTX_SHIFT)), \ SET_FIELD_Q(((b) + (r) + ((c) << CTX_SHIFT)), \ r##_##F##_MASK, r##_##F##_SHIFT, (v)) /* Wrappers for numbered field registers */ Loading
drivers/iommu/msm_iommu-v1.c +27 −24 Original line number Diff line number Diff line Loading @@ -239,10 +239,10 @@ static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va) if (ret) goto fail; SET_TLBIVA(iommu_drvdata->base, ctx_drvdata->num, SET_TLBIVA(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid | (va & CB_TLBIVA_VA)); mb(); __sync_tlb(iommu_drvdata->base, ctx_drvdata->num); __sync_tlb(iommu_drvdata->cb_base, ctx_drvdata->num); __disable_clocks(iommu_drvdata); } fail: Loading @@ -266,10 +266,10 @@ static int __flush_iotlb(struct iommu_domain *domain) if (ret) goto fail; SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, SET_TLBIASID(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid); mb(); __sync_tlb(iommu_drvdata->base, ctx_drvdata->num); __sync_tlb(iommu_drvdata->cb_base, ctx_drvdata->num); __disable_clocks(iommu_drvdata); } Loading Loading @@ -410,7 +410,7 @@ static void msm_iommu_assign_ASID(const struct msm_iommu_drvdata *iommu_drvdata, struct msm_iommu_priv *priv) { unsigned int found = 0; void __iomem *base = iommu_drvdata->base; void __iomem *cb_base = iommu_drvdata->cb_base; unsigned int i; unsigned int ncb = iommu_drvdata->ncb; struct msm_iommu_ctx_drvdata *tmp_drvdata; Loading Loading @@ -438,7 +438,7 @@ static void msm_iommu_assign_ASID(const struct msm_iommu_drvdata *iommu_drvdata, BUG_ON(!found); } msm_iommu_set_ASID(base, curr_ctx->num, curr_ctx->asid); msm_iommu_set_ASID(cb_base, curr_ctx->num, curr_ctx->asid); } #ifdef CONFIG_IOMMU_LPAE Loading Loading @@ -542,30 +542,31 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata, { phys_addr_t pn; void __iomem *base = iommu_drvdata->base; void __iomem *cb_base = iommu_drvdata->cb_base; unsigned int ctx = ctx_drvdata->num; phys_addr_t pgtable = __pa(priv->pt.fl_table); __reset_context(base, ctx); msm_iommu_setup_ctx(base, ctx); __reset_context(cb_base, ctx); msm_iommu_setup_ctx(cb_base, ctx); if (priv->pt.redirect) msm_iommu_setup_pg_l2_redirect(base, ctx); msm_iommu_setup_pg_l2_redirect(cb_base, ctx); msm_iommu_setup_memory_remap(base, ctx); msm_iommu_setup_memory_remap(cb_base, ctx); pn = pgtable >> CB_TTBR0_ADDR_SHIFT; SET_CB_TTBR0_ADDR(base, ctx, pn); SET_CB_TTBR0_ADDR(cb_base, ctx, pn); /* Enable context fault interrupt */ SET_CB_SCTLR_CFIE(base, ctx, 1); SET_CB_SCTLR_CFIE(cb_base, ctx, 1); /* Redirect all cacheable requests to L2 slave port. */ SET_CB_ACTLR_BPRCISH(base, ctx, 1); SET_CB_ACTLR_BPRCOSH(base, ctx, 1); SET_CB_ACTLR_BPRCNSH(base, ctx, 1); SET_CB_ACTLR_BPRCISH(cb_base, ctx, 1); SET_CB_ACTLR_BPRCOSH(cb_base, ctx, 1); SET_CB_ACTLR_BPRCNSH(cb_base, ctx, 1); /* Enable private ASID namespace */ SET_CB_SCTLR_ASIDPNE(base, ctx, 1); SET_CB_SCTLR_ASIDPNE(cb_base, ctx, 1); if (!is_secure) { if (program_m2v) Loading Loading @@ -593,7 +594,7 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata, msm_iommu_assign_ASID(iommu_drvdata, ctx_drvdata, priv); /* Enable the MMU */ SET_CB_SCTLR_M(base, ctx, 1); SET_CB_SCTLR_M(cb_base, ctx, 1); mb(); } Loading Loading @@ -768,7 +769,8 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain, is_secure = iommu_drvdata->sec_id != -1; SET_TLBIASID(iommu_drvdata->base, ctx_drvdata->num, ctx_drvdata->asid); SET_TLBIASID(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid); BUG_ON(iommu_drvdata->asid[ctx_drvdata->asid - 1] == 0); iommu_drvdata->asid[ctx_drvdata->asid - 1]--; Loading @@ -776,7 +778,7 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain, iommu_halt(iommu_drvdata); __reset_context(iommu_drvdata->base, ctx_drvdata->num); __reset_context(iommu_drvdata->cb_base, ctx_drvdata->num); /* * Only reset the M2V tables on the very last detach */ Loading Loading @@ -940,7 +942,7 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain, return ret; } base = iommu_drvdata->base; base = iommu_drvdata->cb_base; ctx = ctx_drvdata->num; ret = __enable_clocks(iommu_drvdata); Loading Loading @@ -1180,7 +1182,7 @@ irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id) goto fail; } fsr = GET_FSR(drvdata->base, ctx_drvdata->num); fsr = GET_FSR(drvdata->cb_base, ctx_drvdata->num); if (fsr) { if (!ctx_drvdata->attached_domain) { pr_err("Bad domain in interrupt handler\n"); Loading @@ -1188,7 +1190,7 @@ irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id) } else ret = report_iommu_fault(ctx_drvdata->attached_domain, &ctx_drvdata->pdev->dev, GET_FAR(drvdata->base, ctx_drvdata->num), 0); GET_FAR(drvdata->cb_base, ctx_drvdata->num), 0); if (ret == -ENOSYS) { pr_err("Unexpected IOMMU page fault!\n"); Loading @@ -1196,11 +1198,12 @@ irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id) pr_err("context = %s (%d)\n", ctx_drvdata->name, ctx_drvdata->num); pr_err("Interesting registers:\n"); __print_ctx_regs(drvdata->base, ctx_drvdata->num, fsr); __print_ctx_regs(drvdata->cb_base, ctx_drvdata->num, fsr); } if (ret != -EBUSY) SET_FSR(drvdata->base, ctx_drvdata->num, fsr); SET_FSR(drvdata->cb_base, ctx_drvdata->num, fsr); ret = IRQ_HANDLED; } else ret = IRQ_NONE; Loading
drivers/iommu/msm_iommu_dev-v1.c +18 −5 Original line number Diff line number Diff line Loading @@ -287,6 +287,7 @@ static int msm_iommu_probe(struct platform_device *pdev) struct resource *r; int ret, needs_alt_core_clk, needs_alt_iface_clk; int global_cfg_irq, global_client_irq; u32 temp; drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) Loading Loading @@ -343,6 +344,13 @@ static int msm_iommu_probe(struct platform_device *pdev) drvdata->no_atos_support = of_property_read_bool(pdev->dev.of_node, "qcom,no-atos-support"); if (!of_property_read_u32(pdev->dev.of_node, "qcom,cb-base-offset", &temp)) drvdata->cb_base = drvdata->base + temp; else drvdata->cb_base = drvdata->base + 0x8000; if (clk_get_rate(drvdata->clk) == 0) { ret = clk_round_rate(drvdata->clk, 1000); clk_set_rate(drvdata->clk, ret); Loading Loading @@ -442,7 +450,9 @@ static int msm_iommu_ctx_parse_dt(struct platform_device *pdev, { struct resource *r, rp; int irq = 0, ret = 0; struct msm_iommu_drvdata *drvdata; u32 nsid; unsigned long cb_offset; get_secure_ctx(pdev->dev.of_node, ctx_drvdata); Loading Loading @@ -484,12 +494,15 @@ static int msm_iommu_ctx_parse_dt(struct platform_device *pdev, if (ret) goto out; /* Calculate the context bank number using the base addresses. The * first 8 pages belong to the global address space which is followed * by the context banks, hence subtract by 8 to get the context bank * number. /* Calculate the context bank number using the base addresses. * Typically CB0 base address is 0x8000 pages away if the number * of CBs are <=8. So, assume the offset 0x8000 until mentioned * explicitely. */ ctx_drvdata->num = ((r->start - rp.start) >> CTX_SHIFT) - 8; drvdata = dev_get_drvdata(pdev->dev.parent); cb_offset = drvdata->cb_base - drvdata->base; ctx_drvdata->num = ((r->start - rp.start - cb_offset) >> CTX_SHIFT); if (of_property_read_string(pdev->dev.of_node, "label", &ctx_drvdata->name)) Loading