aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-msm/devices-iommu.c26
-rw-r--r--arch/arm/mach-msm/include/mach/iommu.h4
-rw-r--r--arch/arm/mach-msm/iommu.c5
-rw-r--r--arch/arm/mach-msm/iommu_dev.c29
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
281static struct msm_iommu_dev jpegd_iommu = { 281static struct msm_iommu_dev jpegd_iommu = {
282 .name = "jpegd", 282 .name = "jpegd",
283 .ncb = 2,
283}; 284};
284 285
285static struct msm_iommu_dev vpe_iommu = { 286static struct msm_iommu_dev vpe_iommu = {
286 .name = "vpe" 287 .name = "vpe",
288 .ncb = 2,
287}; 289};
288 290
289static struct msm_iommu_dev mdp0_iommu = { 291static struct msm_iommu_dev mdp0_iommu = {
290 .name = "mdp0" 292 .name = "mdp0",
293 .ncb = 2,
291}; 294};
292 295
293static struct msm_iommu_dev mdp1_iommu = { 296static struct msm_iommu_dev mdp1_iommu = {
294 .name = "mdp1" 297 .name = "mdp1",
298 .ncb = 2,
295}; 299};
296 300
297static struct msm_iommu_dev rot_iommu = { 301static struct msm_iommu_dev rot_iommu = {
298 .name = "rot" 302 .name = "rot",
303 .ncb = 2,
299}; 304};
300 305
301static struct msm_iommu_dev ijpeg_iommu = { 306static struct msm_iommu_dev ijpeg_iommu = {
302 .name = "ijpeg" 307 .name = "ijpeg",
308 .ncb = 2,
303}; 309};
304 310
305static struct msm_iommu_dev vfe_iommu = { 311static struct msm_iommu_dev vfe_iommu = {
306 .name = "vfe", 312 .name = "vfe",
313 .ncb = 2,
307}; 314};
308 315
309static struct msm_iommu_dev vcodec_a_iommu = { 316static struct msm_iommu_dev vcodec_a_iommu = {
310 .name = "vcodec_a" 317 .name = "vcodec_a",
318 .ncb = 2,
311}; 319};
312 320
313static struct msm_iommu_dev vcodec_b_iommu = { 321static struct msm_iommu_dev vcodec_b_iommu = {
314 .name = "vcodec_b" 322 .name = "vcodec_b",
323 .ncb = 2,
315}; 324};
316 325
317static struct msm_iommu_dev gfx3d_iommu = { 326static struct msm_iommu_dev gfx3d_iommu = {
318 .name = "gfx3d", 327 .name = "gfx3d",
328 .ncb = 3,
319}; 329};
320 330
321static struct msm_iommu_dev gfx2d0_iommu = { 331static struct msm_iommu_dev gfx2d0_iommu = {
322 .name = "gfx2d0", 332 .name = "gfx2d0",
333 .ncb = 2,
323}; 334};
324 335
325static struct msm_iommu_dev gfx2d1_iommu = { 336static struct msm_iommu_dev gfx2d1_iommu = {
326 .name = "gfx2d1", 337 .name = "gfx2d1",
338 .ncb = 2,
327}; 339};
328 340
329static struct platform_device msm_device_iommu_jpegd = { 341static 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 */
49struct msm_iommu_dev { 50struct 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 {
79struct msm_iommu_drvdata { 82struct 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}
86EXPORT_SYMBOL(msm_iommu_get_ctx); 86EXPORT_SYMBOL(msm_iommu_get_ctx);
87 87
88static void msm_iommu_reset(void __iomem *base) 88static 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