diff options
-rw-r--r-- | arch/arm/mach-msm/devices-iommu.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-msm/include/mach/iommu.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-msm/iommu.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-msm/iommu_dev.c | 29 |
4 files changed, 42 insertions, 22 deletions
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c index af97afe0bfab..24030d0da6e3 100644 --- a/arch/arm/mach-msm/devices-iommu.c +++ b/arch/arm/mach-msm/devices-iommu.c | |||
@@ -280,50 +280,62 @@ static struct platform_device msm_root_iommu_dev = { | |||
280 | 280 | ||
281 | static struct msm_iommu_dev jpegd_iommu = { | 281 | static struct msm_iommu_dev jpegd_iommu = { |
282 | .name = "jpegd", | 282 | .name = "jpegd", |
283 | .ncb = 2, | ||
283 | }; | 284 | }; |
284 | 285 | ||
285 | static struct msm_iommu_dev vpe_iommu = { | 286 | static struct msm_iommu_dev vpe_iommu = { |
286 | .name = "vpe" | 287 | .name = "vpe", |
288 | .ncb = 2, | ||
287 | }; | 289 | }; |
288 | 290 | ||
289 | static struct msm_iommu_dev mdp0_iommu = { | 291 | static struct msm_iommu_dev mdp0_iommu = { |
290 | .name = "mdp0" | 292 | .name = "mdp0", |
293 | .ncb = 2, | ||
291 | }; | 294 | }; |
292 | 295 | ||
293 | static struct msm_iommu_dev mdp1_iommu = { | 296 | static struct msm_iommu_dev mdp1_iommu = { |
294 | .name = "mdp1" | 297 | .name = "mdp1", |
298 | .ncb = 2, | ||
295 | }; | 299 | }; |
296 | 300 | ||
297 | static struct msm_iommu_dev rot_iommu = { | 301 | static struct msm_iommu_dev rot_iommu = { |
298 | .name = "rot" | 302 | .name = "rot", |
303 | .ncb = 2, | ||
299 | }; | 304 | }; |
300 | 305 | ||
301 | static struct msm_iommu_dev ijpeg_iommu = { | 306 | static struct msm_iommu_dev ijpeg_iommu = { |
302 | .name = "ijpeg" | 307 | .name = "ijpeg", |
308 | .ncb = 2, | ||
303 | }; | 309 | }; |
304 | 310 | ||
305 | static struct msm_iommu_dev vfe_iommu = { | 311 | static struct msm_iommu_dev vfe_iommu = { |
306 | .name = "vfe", | 312 | .name = "vfe", |
313 | .ncb = 2, | ||
307 | }; | 314 | }; |
308 | 315 | ||
309 | static struct msm_iommu_dev vcodec_a_iommu = { | 316 | static struct msm_iommu_dev vcodec_a_iommu = { |
310 | .name = "vcodec_a" | 317 | .name = "vcodec_a", |
318 | .ncb = 2, | ||
311 | }; | 319 | }; |
312 | 320 | ||
313 | static struct msm_iommu_dev vcodec_b_iommu = { | 321 | static struct msm_iommu_dev vcodec_b_iommu = { |
314 | .name = "vcodec_b" | 322 | .name = "vcodec_b", |
323 | .ncb = 2, | ||
315 | }; | 324 | }; |
316 | 325 | ||
317 | static struct msm_iommu_dev gfx3d_iommu = { | 326 | static struct msm_iommu_dev gfx3d_iommu = { |
318 | .name = "gfx3d", | 327 | .name = "gfx3d", |
328 | .ncb = 3, | ||
319 | }; | 329 | }; |
320 | 330 | ||
321 | static struct msm_iommu_dev gfx2d0_iommu = { | 331 | static struct msm_iommu_dev gfx2d0_iommu = { |
322 | .name = "gfx2d0", | 332 | .name = "gfx2d0", |
333 | .ncb = 2, | ||
323 | }; | 334 | }; |
324 | 335 | ||
325 | static struct msm_iommu_dev gfx2d1_iommu = { | 336 | static struct msm_iommu_dev gfx2d1_iommu = { |
326 | .name = "gfx2d1", | 337 | .name = "gfx2d1", |
338 | .ncb = 2, | ||
327 | }; | 339 | }; |
328 | 340 | ||
329 | static struct platform_device msm_device_iommu_jpegd = { | 341 | static struct platform_device msm_device_iommu_jpegd = { |
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h index 4dfe7efcf4ea..5c7c955e6d25 100644 --- a/arch/arm/mach-msm/include/mach/iommu.h +++ b/arch/arm/mach-msm/include/mach/iommu.h | |||
@@ -45,9 +45,11 @@ | |||
45 | /** | 45 | /** |
46 | * struct msm_iommu_dev - a single IOMMU hardware instance | 46 | * struct msm_iommu_dev - a single IOMMU hardware instance |
47 | * name Human-readable name given to this IOMMU HW instance | 47 | * name Human-readable name given to this IOMMU HW instance |
48 | * ncb Number of context banks present on this IOMMU HW instance | ||
48 | */ | 49 | */ |
49 | struct msm_iommu_dev { | 50 | struct msm_iommu_dev { |
50 | const char *name; | 51 | const char *name; |
52 | int ncb; | ||
51 | }; | 53 | }; |
52 | 54 | ||
53 | /** | 55 | /** |
@@ -69,6 +71,7 @@ struct msm_iommu_ctx_dev { | |||
69 | /** | 71 | /** |
70 | * struct msm_iommu_drvdata - A single IOMMU hardware instance | 72 | * struct msm_iommu_drvdata - A single IOMMU hardware instance |
71 | * @base: IOMMU config port base address (VA) | 73 | * @base: IOMMU config port base address (VA) |
74 | * @ncb The number of contexts on this IOMMU | ||
72 | * @irq: Interrupt number | 75 | * @irq: Interrupt number |
73 | * @clk: The bus clock for this IOMMU hardware instance | 76 | * @clk: The bus clock for this IOMMU hardware instance |
74 | * @pclk: The clock for the IOMMU bus interconnect | 77 | * @pclk: The clock for the IOMMU bus interconnect |
@@ -79,6 +82,7 @@ struct msm_iommu_ctx_dev { | |||
79 | struct msm_iommu_drvdata { | 82 | struct msm_iommu_drvdata { |
80 | void __iomem *base; | 83 | void __iomem *base; |
81 | int irq; | 84 | int irq; |
85 | int ncb; | ||
82 | struct clk *clk; | 86 | struct clk *clk; |
83 | struct clk *pclk; | 87 | struct clk *pclk; |
84 | }; | 88 | }; |
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c index 9c087405c635..0146f519e85c 100644 --- a/arch/arm/mach-msm/iommu.c +++ b/arch/arm/mach-msm/iommu.c | |||
@@ -636,7 +636,7 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id) | |||
636 | struct msm_iommu_drvdata *drvdata = dev_id; | 636 | struct msm_iommu_drvdata *drvdata = dev_id; |
637 | void __iomem *base; | 637 | void __iomem *base; |
638 | unsigned int fsr; | 638 | unsigned int fsr; |
639 | int ncb, i, ret; | 639 | int i, ret; |
640 | 640 | ||
641 | spin_lock(&msm_iommu_lock); | 641 | spin_lock(&msm_iommu_lock); |
642 | 642 | ||
@@ -654,8 +654,7 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id) | |||
654 | if (ret) | 654 | if (ret) |
655 | goto fail; | 655 | goto fail; |
656 | 656 | ||
657 | ncb = GET_NCB(base)+1; | 657 | for (i = 0; i < drvdata->ncb; i++) { |
658 | for (i = 0; i < ncb; i++) { | ||
659 | fsr = GET_FSR(base, i); | 658 | fsr = GET_FSR(base, i); |
660 | if (fsr) { | 659 | if (fsr) { |
661 | pr_err("Fault occurred in context %d.\n", i); | 660 | pr_err("Fault occurred in context %d.\n", i); |
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c index 0e240c9d6e71..8e8fb079852d 100644 --- a/arch/arm/mach-msm/iommu_dev.c +++ b/arch/arm/mach-msm/iommu_dev.c | |||
@@ -85,9 +85,9 @@ fail: | |||
85 | } | 85 | } |
86 | EXPORT_SYMBOL(msm_iommu_get_ctx); | 86 | EXPORT_SYMBOL(msm_iommu_get_ctx); |
87 | 87 | ||
88 | static void msm_iommu_reset(void __iomem *base) | 88 | static void msm_iommu_reset(void __iomem *base, int ncb) |
89 | { | 89 | { |
90 | int ctx, ncb; | 90 | int ctx; |
91 | 91 | ||
92 | SET_RPUE(base, 0); | 92 | SET_RPUE(base, 0); |
93 | SET_RPUEIE(base, 0); | 93 | SET_RPUEIE(base, 0); |
@@ -100,7 +100,6 @@ static void msm_iommu_reset(void __iomem *base) | |||
100 | SET_GLOBAL_TLBIALL(base, 0); | 100 | SET_GLOBAL_TLBIALL(base, 0); |
101 | SET_RPU_ACR(base, 0); | 101 | SET_RPU_ACR(base, 0); |
102 | SET_TLBLKCRWE(base, 1); | 102 | SET_TLBLKCRWE(base, 1); |
103 | ncb = GET_NCB(base)+1; | ||
104 | 103 | ||
105 | for (ctx = 0; ctx < ncb; ctx++) { | 104 | for (ctx = 0; ctx < ncb; ctx++) { |
106 | SET_BPRCOSH(base, ctx, 0); | 105 | SET_BPRCOSH(base, ctx, 0); |
@@ -136,7 +135,7 @@ static int msm_iommu_probe(struct platform_device *pdev) | |||
136 | struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data; | 135 | struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data; |
137 | void __iomem *regs_base; | 136 | void __iomem *regs_base; |
138 | resource_size_t len; | 137 | resource_size_t len; |
139 | int ret, ncb, nm2v, irq; | 138 | int ret, irq, par; |
140 | 139 | ||
141 | if (pdev->id == -1) { | 140 | if (pdev->id == -1) { |
142 | msm_iommu_root_dev = pdev; | 141 | msm_iommu_root_dev = pdev; |
@@ -211,10 +210,18 @@ static int msm_iommu_probe(struct platform_device *pdev) | |||
211 | goto fail_io; | 210 | goto fail_io; |
212 | } | 211 | } |
213 | 212 | ||
214 | mb(); | 213 | msm_iommu_reset(regs_base, iommu_dev->ncb); |
215 | 214 | ||
216 | if (GET_IDR(regs_base) == 0) { | 215 | SET_M(regs_base, 0, 1); |
217 | pr_err("Invalid IDR value detected\n"); | 216 | SET_PAR(regs_base, 0, 0); |
217 | SET_V2PCFG(regs_base, 0, 1); | ||
218 | SET_V2PPR(regs_base, 0, 0); | ||
219 | par = GET_PAR(regs_base, 0); | ||
220 | SET_V2PCFG(regs_base, 0, 0); | ||
221 | SET_M(regs_base, 0, 0); | ||
222 | |||
223 | if (!par) { | ||
224 | pr_err("%s: Invalid PAR value detected\n", iommu_dev->name); | ||
218 | ret = -ENODEV; | 225 | ret = -ENODEV; |
219 | goto fail_io; | 226 | goto fail_io; |
220 | } | 227 | } |
@@ -226,17 +233,15 @@ static int msm_iommu_probe(struct platform_device *pdev) | |||
226 | goto fail_io; | 233 | goto fail_io; |
227 | } | 234 | } |
228 | 235 | ||
229 | msm_iommu_reset(regs_base); | 236 | |
230 | drvdata->pclk = iommu_pclk; | 237 | drvdata->pclk = iommu_pclk; |
231 | drvdata->clk = iommu_clk; | 238 | drvdata->clk = iommu_clk; |
232 | drvdata->base = regs_base; | 239 | drvdata->base = regs_base; |
233 | drvdata->irq = irq; | 240 | drvdata->irq = irq; |
234 | 241 | drvdata->ncb = iommu_dev->ncb; | |
235 | nm2v = GET_NM2VCBMT((unsigned long) regs_base); | ||
236 | ncb = GET_NCB((unsigned long) regs_base); | ||
237 | 242 | ||
238 | pr_info("device %s mapped at %p, irq %d with %d ctx banks\n", | 243 | pr_info("device %s mapped at %p, irq %d with %d ctx banks\n", |
239 | iommu_dev->name, regs_base, irq, ncb+1); | 244 | iommu_dev->name, regs_base, irq, iommu_dev->ncb); |
240 | 245 | ||
241 | platform_set_drvdata(pdev, drvdata); | 246 | platform_set_drvdata(pdev, drvdata); |
242 | 247 | ||