18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 #include <linux/kernel.h>
20 #include <linux/module.h>
22 #include <linux/errno.h>
25 #include <linux/list.h>
27 #include <linux/slab.h>
31 #include <asm/cacheflush.h>
32 #include <asm/sizes.h>
37 #define MRC(reg, processor, op1, crn, crm, op2) \
38 __asm__ __volatile__ ( \
39 " mrc " #processor "," #op1 ", %0," #crn "," #crm "," #op2 "\n" \
42 #define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0)
43 #define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1)
46 #define MSM_IOMMU_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M)
48 static int msm_iommu_tex_class[4];
87 #ifndef CONFIG_IOMMU_PGTABLES_L2
88 unsigned long *fl_table = priv->
pgtable;
96 void *sl_table =
__va(fl_table[i] &
104 if (!ctx_drvdata->
pdev || !ctx_drvdata->
pdev->dev.parent)
110 ret = __enable_clocks(iommu_drvdata);
115 __disable_clocks(iommu_drvdata);
121 static void __reset_context(
void __iomem *base,
int ctx)
147 unsigned int prrr, nmrr;
148 __reset_context(base, ctx);
189 #ifdef CONFIG_IOMMU_PGTABLES_L2
213 static int msm_iommu_domain_init(
struct iommu_domain *domain)
230 domain->
geometry.aperture_start = 0;
231 domain->
geometry.aperture_end = (1ULL << 32) - 1;
232 domain->
geometry.force_aperture =
true;
241 static void msm_iommu_domain_destroy(
struct iommu_domain *domain)
245 unsigned long *fl_table;
265 spin_unlock_irqrestore(&msm_iommu_lock, flags);
291 if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) {
302 if (tmp_drvdata == ctx_drvdata) {
307 ret = __enable_clocks(iommu_drvdata);
311 __program_context(iommu_drvdata->
base, ctx_dev->
num,
314 __disable_clocks(iommu_drvdata);
316 ret = __flush_iotlb(domain);
319 spin_unlock_irqrestore(&msm_iommu_lock, flags);
323 static void msm_iommu_detach_dev(
struct iommu_domain *domain,
343 if (!iommu_drvdata || !ctx_drvdata || !ctx_dev)
346 ret = __flush_iotlb(domain);
350 ret = __enable_clocks(iommu_drvdata);
354 __reset_context(iommu_drvdata->
base, ctx_dev->
num);
355 __disable_clocks(iommu_drvdata);
359 spin_unlock_irqrestore(&msm_iommu_lock, flags);
362 static int msm_iommu_map(
struct iommu_domain *domain,
unsigned long va,
367 unsigned long *fl_table;
368 unsigned long *fl_pte;
369 unsigned long fl_offset;
370 unsigned long *sl_table;
371 unsigned long *sl_pte;
372 unsigned long sl_offset;
374 int ret = 0, tex, sh;
411 pgprot |= tex & 0x04 ?
FL_TEX0 : 0;
416 pgprot |= tex & 0x04 ?
SL_TEX0 : 0;
420 fl_pte = fl_table + fl_offset;
424 for (i = 0; i < 16; i++)
435 if ((len ==
SZ_4K || len ==
SZ_64K) && (*fl_pte) == 0) {
441 pr_debug(
"Could not allocate second level table\n");
452 sl_pte = sl_table + sl_offset;
462 for (i = 0; i < 16; i++)
467 ret = __flush_iotlb(domain);
469 spin_unlock_irqrestore(&msm_iommu_lock, flags);
473 static size_t msm_iommu_unmap(
struct iommu_domain *domain,
unsigned long va,
478 unsigned long *fl_table;
479 unsigned long *fl_pte;
480 unsigned long fl_offset;
481 unsigned long *sl_table;
482 unsigned long *sl_pte;
483 unsigned long sl_offset;
507 fl_pte = fl_table + fl_offset;
516 for (i = 0; i < 16; i++)
524 sl_pte = sl_table + sl_offset;
527 for (i = 0; i < 16; i++)
546 ret = __flush_iotlb(domain);
549 spin_unlock_irqrestore(&msm_iommu_lock, flags);
578 base = iommu_drvdata->
base;
579 ctx = ctx_drvdata->
num;
581 ret = __enable_clocks(iommu_drvdata);
593 ret = (par & 0xFF000000) | (va & 0x00FFFFFF);
595 ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
600 __disable_clocks(iommu_drvdata);
602 spin_unlock_irqrestore(&msm_iommu_lock, flags);
606 static int msm_iommu_domain_has_cap(
struct iommu_domain *domain,
612 static void print_ctx_regs(
void __iomem *base,
int ctx)
614 unsigned int fsr =
GET_FSR(base, ctx);
615 pr_err(
"FAR = %08x PAR = %08x\n",
617 pr_err(
"FSR = %08x [%s%s%s%s%s%s%s%s%s%s]\n", fsr,
618 (fsr & 0x02) ?
"TF " :
"",
619 (fsr & 0x04) ?
"AFF " :
"",
620 (fsr & 0x08) ?
"APF " :
"",
621 (fsr & 0x10) ?
"TLBMF " :
"",
622 (fsr & 0x20) ?
"HTWDEEF " :
"",
623 (fsr & 0x40) ?
"HTWSEEF " :
"",
624 (fsr & 0x80) ?
"MHF " :
"",
625 (fsr & 0x10000) ?
"SL " :
"",
626 (fsr & 0x40000000) ?
"SS " :
"",
627 (fsr & 0x80000000) ?
"MULTI " :
"");
629 pr_err(
"FSYNR0 = %08x FSYNR1 = %08x\n",
631 pr_err(
"TTBR0 = %08x TTBR1 = %08x\n",
633 pr_err(
"SCTLR = %08x ACTLR = %08x\n",
635 pr_err(
"PRRR = %08x NMRR = %08x\n",
646 spin_lock(&msm_iommu_lock);
649 pr_err(
"Invalid device ID in context interrupt handler\n");
653 base = drvdata->
base;
655 pr_err(
"Unexpected IOMMU page fault!\n");
656 pr_err(
"base = %08x\n", (
unsigned int) base);
658 ret = __enable_clocks(drvdata);
662 for (i = 0; i < drvdata->
ncb; i++) {
665 pr_err(
"Fault occurred in context %d.\n", i);
666 pr_err(
"Interesting registers:\n");
667 print_ctx_regs(base, i);
671 __disable_clocks(drvdata);
673 spin_unlock(&msm_iommu_lock);
677 static struct iommu_ops msm_iommu_ops = {
678 .domain_init = msm_iommu_domain_init,
679 .domain_destroy = msm_iommu_domain_destroy,
680 .attach_dev = msm_iommu_attach_dev,
681 .detach_dev = msm_iommu_detach_dev,
682 .map = msm_iommu_map,
683 .unmap = msm_iommu_unmap,
684 .iova_to_phys = msm_iommu_iova_to_phys,
685 .domain_has_cap = msm_iommu_domain_has_cap,
689 static int __init get_tex_class(
int icp,
int ocp,
int mt,
int nos)
692 unsigned int prrr = 0;
693 unsigned int nmrr = 0;
694 int c_icp, c_ocp, c_mt, c_nos;
705 if (icp == c_icp && ocp == c_ocp && c_mt == mt && c_nos == nos)
712 static void __init setup_iommu_tex_classes(
void)
727 static int __init msm_iommu_init(
void)
729 setup_iommu_tex_classes();