Loading arch/arm/mach-msm/include/mach/iommu_hw-v1.h +15 −11 Original line number Diff line number Diff line Loading @@ -15,23 +15,24 @@ #define CTX_SHIFT 12 #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) + (reg) + ((ctx) << CTX_SHIFT))) #define GET_CTX_REG_Q(reg, base, ctx) \ (readq_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT))) #define CTX_REG(reg, base, ctx) \ ((base) + (reg) + ((ctx) << CTX_SHIFT)) #define GLB_REG(reg, base) \ ((base) + (reg)) #define GET_GLOBAL_REG(reg, base) (readl_relaxed(GLB_REG(reg, base))) #define GET_GLOBAL_REG_Q(reg, base) (readq_relaxed(GLB_REG(reg, base))) #define GET_CTX_REG(reg, base, ctx) (readl_relaxed(CTX_REG(reg, base, ctx))) #define GET_CTX_REG_Q(reg, base, ctx) (readq_relaxed(CTX_REG(reg, base, ctx))) #define SET_GLOBAL_REG(reg, base, val) writel_relaxed((val), ((base) + (reg))) #define SET_GLOBAL_REG_Q(reg, base, val) \ (writeq_relaxed((val), ((base) + (reg)))) (writeq_relaxed((val), GLB_REG(reg, base))) #define SET_CTX_REG(reg, base, ctx, val) \ writel_relaxed((val), \ ((base) + (reg) + ((ctx) << CTX_SHIFT))) writel_relaxed((val), (CTX_REG(reg, base, ctx))) #define SET_CTX_REG_Q(reg, base, ctx, val) \ writeq_relaxed((val), \ ((base) + (reg) + ((ctx) << CTX_SHIFT))) writeq_relaxed((val), CTX_REG(reg, base, ctx)) /* Wrappers for numbered registers */ #define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG((b), ((r) + (n << 2)), (v)) Loading Loading @@ -172,6 +173,9 @@ do { \ GET_GLOBAL_FIELD(b, MICRO_MMU_CTRL, IDLE) #define SET_MICRO_MMU_CTRL_RESERVED(b, v) \ SET_GLOBAL_FIELD(b, MICRO_MMU_CTRL, RESERVED, v) #define MMU_CTRL_IDLE (MICRO_MMU_CTRL_IDLE_MASK << MICRO_MMU_CTRL_IDLE_SHIFT) #define SET_PREDICTIONDIS0(b, v) SET_GLOBAL_REG(PREDICTIONDIS0, (b), (v)) #define SET_PREDICTIONDIS1(b, v) SET_GLOBAL_REG(PREDICTIONDIS1, (b), (v)) #define SET_S1L1BFBLP0(b, v) SET_GLOBAL_REG(S1L1BFBLP0, (b), (v)) Loading drivers/iommu/msm_iommu-v1.c +22 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/platform_device.h> #include <linux/errno.h> #include <linux/io.h> #include <linux/iopoll.h> #include <linux/interrupt.h> #include <linux/list.h> #include <linux/mutex.h> Loading Loading @@ -174,13 +175,20 @@ struct iommu_access_ops iommu_access_ops_v1 = { .iommu_lock_release = _iommu_lock_release, }; void iommu_halt(const struct msm_iommu_drvdata *iommu_drvdata) void iommu_halt(struct msm_iommu_drvdata const *iommu_drvdata) { if (iommu_drvdata->halt_enabled) { SET_MICRO_MMU_CTRL_HALT_REQ(iommu_drvdata->base, 1); unsigned int val; void __iomem *base = iommu_drvdata->base; int res; SET_MICRO_MMU_CTRL_HALT_REQ(base, 1); res = readl_tight_poll_timeout( GLB_REG(MICRO_MMU_CTRL, base), val, (val & MMU_CTRL_IDLE) == MMU_CTRL_IDLE, 5000000); while (GET_MICRO_MMU_CTRL_IDLE(iommu_drvdata->base) == 0) cpu_relax(); if (res) BUG(); /* Ensure device is idle before continuing */ mb(); } Loading @@ -204,21 +212,19 @@ void iommu_resume(const struct msm_iommu_drvdata *iommu_drvdata) } } static void __sync_tlb(void __iomem *base, int ctx) static void __sync_tlb(struct msm_iommu_drvdata *iommu_drvdata, int ctx) { int i; unsigned int val; unsigned int res; void __iomem *base = iommu_drvdata->cb_base; SET_TLBSYNC(base, ctx, 0); /* No barrier needed due to register proximity */ for (i = 0; i < IOMMU_MSEC_TIMEOUT; i += IOMMU_MSEC_STEP) if (GET_CB_TLBSTATUS_SACTIVE(base, ctx) == 0) break; else msleep(IOMMU_MSEC_STEP); BUG_ON(i >= IOMMU_MSEC_TIMEOUT); /* No barrier needed due to read dependency */ res = readl_tight_poll_timeout(CTX_REG(CB_TLBSTATUS, base, ctx), val, (val & CB_TLBSTATUS_SACTIVE) == 0, 5000000); if (res) BUG(); } static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va) Loading @@ -242,7 +248,7 @@ static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va) SET_TLBIVA(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid | (va & CB_TLBIVA_VA)); mb(); __sync_tlb(iommu_drvdata->cb_base, ctx_drvdata->num); __sync_tlb(iommu_drvdata, ctx_drvdata->num); __disable_clocks(iommu_drvdata); } fail: Loading @@ -269,7 +275,7 @@ static int __flush_iotlb(struct iommu_domain *domain) SET_TLBIASID(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid); mb(); __sync_tlb(iommu_drvdata->cb_base, ctx_drvdata->num); __sync_tlb(iommu_drvdata, ctx_drvdata->num); __disable_clocks(iommu_drvdata); } Loading Loading
arch/arm/mach-msm/include/mach/iommu_hw-v1.h +15 −11 Original line number Diff line number Diff line Loading @@ -15,23 +15,24 @@ #define CTX_SHIFT 12 #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) + (reg) + ((ctx) << CTX_SHIFT))) #define GET_CTX_REG_Q(reg, base, ctx) \ (readq_relaxed((base) + (reg) + ((ctx) << CTX_SHIFT))) #define CTX_REG(reg, base, ctx) \ ((base) + (reg) + ((ctx) << CTX_SHIFT)) #define GLB_REG(reg, base) \ ((base) + (reg)) #define GET_GLOBAL_REG(reg, base) (readl_relaxed(GLB_REG(reg, base))) #define GET_GLOBAL_REG_Q(reg, base) (readq_relaxed(GLB_REG(reg, base))) #define GET_CTX_REG(reg, base, ctx) (readl_relaxed(CTX_REG(reg, base, ctx))) #define GET_CTX_REG_Q(reg, base, ctx) (readq_relaxed(CTX_REG(reg, base, ctx))) #define SET_GLOBAL_REG(reg, base, val) writel_relaxed((val), ((base) + (reg))) #define SET_GLOBAL_REG_Q(reg, base, val) \ (writeq_relaxed((val), ((base) + (reg)))) (writeq_relaxed((val), GLB_REG(reg, base))) #define SET_CTX_REG(reg, base, ctx, val) \ writel_relaxed((val), \ ((base) + (reg) + ((ctx) << CTX_SHIFT))) writel_relaxed((val), (CTX_REG(reg, base, ctx))) #define SET_CTX_REG_Q(reg, base, ctx, val) \ writeq_relaxed((val), \ ((base) + (reg) + ((ctx) << CTX_SHIFT))) writeq_relaxed((val), CTX_REG(reg, base, ctx)) /* Wrappers for numbered registers */ #define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG((b), ((r) + (n << 2)), (v)) Loading Loading @@ -172,6 +173,9 @@ do { \ GET_GLOBAL_FIELD(b, MICRO_MMU_CTRL, IDLE) #define SET_MICRO_MMU_CTRL_RESERVED(b, v) \ SET_GLOBAL_FIELD(b, MICRO_MMU_CTRL, RESERVED, v) #define MMU_CTRL_IDLE (MICRO_MMU_CTRL_IDLE_MASK << MICRO_MMU_CTRL_IDLE_SHIFT) #define SET_PREDICTIONDIS0(b, v) SET_GLOBAL_REG(PREDICTIONDIS0, (b), (v)) #define SET_PREDICTIONDIS1(b, v) SET_GLOBAL_REG(PREDICTIONDIS1, (b), (v)) #define SET_S1L1BFBLP0(b, v) SET_GLOBAL_REG(S1L1BFBLP0, (b), (v)) Loading
drivers/iommu/msm_iommu-v1.c +22 −16 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/platform_device.h> #include <linux/errno.h> #include <linux/io.h> #include <linux/iopoll.h> #include <linux/interrupt.h> #include <linux/list.h> #include <linux/mutex.h> Loading Loading @@ -174,13 +175,20 @@ struct iommu_access_ops iommu_access_ops_v1 = { .iommu_lock_release = _iommu_lock_release, }; void iommu_halt(const struct msm_iommu_drvdata *iommu_drvdata) void iommu_halt(struct msm_iommu_drvdata const *iommu_drvdata) { if (iommu_drvdata->halt_enabled) { SET_MICRO_MMU_CTRL_HALT_REQ(iommu_drvdata->base, 1); unsigned int val; void __iomem *base = iommu_drvdata->base; int res; SET_MICRO_MMU_CTRL_HALT_REQ(base, 1); res = readl_tight_poll_timeout( GLB_REG(MICRO_MMU_CTRL, base), val, (val & MMU_CTRL_IDLE) == MMU_CTRL_IDLE, 5000000); while (GET_MICRO_MMU_CTRL_IDLE(iommu_drvdata->base) == 0) cpu_relax(); if (res) BUG(); /* Ensure device is idle before continuing */ mb(); } Loading @@ -204,21 +212,19 @@ void iommu_resume(const struct msm_iommu_drvdata *iommu_drvdata) } } static void __sync_tlb(void __iomem *base, int ctx) static void __sync_tlb(struct msm_iommu_drvdata *iommu_drvdata, int ctx) { int i; unsigned int val; unsigned int res; void __iomem *base = iommu_drvdata->cb_base; SET_TLBSYNC(base, ctx, 0); /* No barrier needed due to register proximity */ for (i = 0; i < IOMMU_MSEC_TIMEOUT; i += IOMMU_MSEC_STEP) if (GET_CB_TLBSTATUS_SACTIVE(base, ctx) == 0) break; else msleep(IOMMU_MSEC_STEP); BUG_ON(i >= IOMMU_MSEC_TIMEOUT); /* No barrier needed due to read dependency */ res = readl_tight_poll_timeout(CTX_REG(CB_TLBSTATUS, base, ctx), val, (val & CB_TLBSTATUS_SACTIVE) == 0, 5000000); if (res) BUG(); } static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va) Loading @@ -242,7 +248,7 @@ static int __flush_iotlb_va(struct iommu_domain *domain, unsigned int va) SET_TLBIVA(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid | (va & CB_TLBIVA_VA)); mb(); __sync_tlb(iommu_drvdata->cb_base, ctx_drvdata->num); __sync_tlb(iommu_drvdata, ctx_drvdata->num); __disable_clocks(iommu_drvdata); } fail: Loading @@ -269,7 +275,7 @@ static int __flush_iotlb(struct iommu_domain *domain) SET_TLBIASID(iommu_drvdata->cb_base, ctx_drvdata->num, ctx_drvdata->asid); mb(); __sync_tlb(iommu_drvdata->cb_base, ctx_drvdata->num); __sync_tlb(iommu_drvdata, ctx_drvdata->num); __disable_clocks(iommu_drvdata); } Loading