diff options
Diffstat (limited to 'drivers/iommu/arm-smmu-v3.c')
-rw-r--r-- | drivers/iommu/arm-smmu-v3.c | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 8e9ec81ce4bb..da902baaa794 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c | |||
@@ -199,9 +199,10 @@ | |||
199 | * Stream table. | 199 | * Stream table. |
200 | * | 200 | * |
201 | * Linear: Enough to cover 1 << IDR1.SIDSIZE entries | 201 | * Linear: Enough to cover 1 << IDR1.SIDSIZE entries |
202 | * 2lvl: 8k L1 entries, 256 lazy entries per table (each table covers a PCI bus) | 202 | * 2lvl: 128k L1 entries, |
203 | * 256 lazy entries per table (each table covers a PCI bus) | ||
203 | */ | 204 | */ |
204 | #define STRTAB_L1_SZ_SHIFT 16 | 205 | #define STRTAB_L1_SZ_SHIFT 20 |
205 | #define STRTAB_SPLIT 8 | 206 | #define STRTAB_SPLIT 8 |
206 | 207 | ||
207 | #define STRTAB_L1_DESC_DWORDS 1 | 208 | #define STRTAB_L1_DESC_DWORDS 1 |
@@ -269,10 +270,10 @@ | |||
269 | #define ARM64_TCR_TG0_SHIFT 14 | 270 | #define ARM64_TCR_TG0_SHIFT 14 |
270 | #define ARM64_TCR_TG0_MASK 0x3UL | 271 | #define ARM64_TCR_TG0_MASK 0x3UL |
271 | #define CTXDESC_CD_0_TCR_IRGN0_SHIFT 8 | 272 | #define CTXDESC_CD_0_TCR_IRGN0_SHIFT 8 |
272 | #define ARM64_TCR_IRGN0_SHIFT 24 | 273 | #define ARM64_TCR_IRGN0_SHIFT 8 |
273 | #define ARM64_TCR_IRGN0_MASK 0x3UL | 274 | #define ARM64_TCR_IRGN0_MASK 0x3UL |
274 | #define CTXDESC_CD_0_TCR_ORGN0_SHIFT 10 | 275 | #define CTXDESC_CD_0_TCR_ORGN0_SHIFT 10 |
275 | #define ARM64_TCR_ORGN0_SHIFT 26 | 276 | #define ARM64_TCR_ORGN0_SHIFT 10 |
276 | #define ARM64_TCR_ORGN0_MASK 0x3UL | 277 | #define ARM64_TCR_ORGN0_MASK 0x3UL |
277 | #define CTXDESC_CD_0_TCR_SH0_SHIFT 12 | 278 | #define CTXDESC_CD_0_TCR_SH0_SHIFT 12 |
278 | #define ARM64_TCR_SH0_SHIFT 12 | 279 | #define ARM64_TCR_SH0_SHIFT 12 |
@@ -542,6 +543,9 @@ struct arm_smmu_device { | |||
542 | #define ARM_SMMU_FEAT_HYP (1 << 12) | 543 | #define ARM_SMMU_FEAT_HYP (1 << 12) |
543 | u32 features; | 544 | u32 features; |
544 | 545 | ||
546 | #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) | ||
547 | u32 options; | ||
548 | |||
545 | struct arm_smmu_cmdq cmdq; | 549 | struct arm_smmu_cmdq cmdq; |
546 | struct arm_smmu_evtq evtq; | 550 | struct arm_smmu_evtq evtq; |
547 | struct arm_smmu_priq priq; | 551 | struct arm_smmu_priq priq; |
@@ -602,11 +606,35 @@ struct arm_smmu_domain { | |||
602 | static DEFINE_SPINLOCK(arm_smmu_devices_lock); | 606 | static DEFINE_SPINLOCK(arm_smmu_devices_lock); |
603 | static LIST_HEAD(arm_smmu_devices); | 607 | static LIST_HEAD(arm_smmu_devices); |
604 | 608 | ||
609 | struct arm_smmu_option_prop { | ||
610 | u32 opt; | ||
611 | const char *prop; | ||
612 | }; | ||
613 | |||
614 | static struct arm_smmu_option_prop arm_smmu_options[] = { | ||
615 | { ARM_SMMU_OPT_SKIP_PREFETCH, "hisilicon,broken-prefetch-cmd" }, | ||
616 | { 0, NULL}, | ||
617 | }; | ||
618 | |||
605 | static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) | 619 | static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom) |
606 | { | 620 | { |
607 | return container_of(dom, struct arm_smmu_domain, domain); | 621 | return container_of(dom, struct arm_smmu_domain, domain); |
608 | } | 622 | } |
609 | 623 | ||
624 | static void parse_driver_options(struct arm_smmu_device *smmu) | ||
625 | { | ||
626 | int i = 0; | ||
627 | |||
628 | do { | ||
629 | if (of_property_read_bool(smmu->dev->of_node, | ||
630 | arm_smmu_options[i].prop)) { | ||
631 | smmu->options |= arm_smmu_options[i].opt; | ||
632 | dev_notice(smmu->dev, "option %s\n", | ||
633 | arm_smmu_options[i].prop); | ||
634 | } | ||
635 | } while (arm_smmu_options[++i].opt); | ||
636 | } | ||
637 | |||
610 | /* Low-level queue manipulation functions */ | 638 | /* Low-level queue manipulation functions */ |
611 | static bool queue_full(struct arm_smmu_queue *q) | 639 | static bool queue_full(struct arm_smmu_queue *q) |
612 | { | 640 | { |
@@ -1036,7 +1064,8 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid, | |||
1036 | arm_smmu_sync_ste_for_sid(smmu, sid); | 1064 | arm_smmu_sync_ste_for_sid(smmu, sid); |
1037 | 1065 | ||
1038 | /* It's likely that we'll want to use the new STE soon */ | 1066 | /* It's likely that we'll want to use the new STE soon */ |
1039 | arm_smmu_cmdq_issue_cmd(smmu, &prefetch_cmd); | 1067 | if (!(smmu->options & ARM_SMMU_OPT_SKIP_PREFETCH)) |
1068 | arm_smmu_cmdq_issue_cmd(smmu, &prefetch_cmd); | ||
1040 | } | 1069 | } |
1041 | 1070 | ||
1042 | static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent) | 1071 | static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent) |
@@ -1064,7 +1093,7 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid) | |||
1064 | return 0; | 1093 | return 0; |
1065 | 1094 | ||
1066 | size = 1 << (STRTAB_SPLIT + ilog2(STRTAB_STE_DWORDS) + 3); | 1095 | size = 1 << (STRTAB_SPLIT + ilog2(STRTAB_STE_DWORDS) + 3); |
1067 | strtab = &cfg->strtab[sid >> STRTAB_SPLIT << STRTAB_L1_DESC_DWORDS]; | 1096 | strtab = &cfg->strtab[(sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS]; |
1068 | 1097 | ||
1069 | desc->span = STRTAB_SPLIT + 1; | 1098 | desc->span = STRTAB_SPLIT + 1; |
1070 | desc->l2ptr = dma_zalloc_coherent(smmu->dev, size, &desc->l2ptr_dma, | 1099 | desc->l2ptr = dma_zalloc_coherent(smmu->dev, size, &desc->l2ptr_dma, |
@@ -2020,21 +2049,23 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) | |||
2020 | { | 2049 | { |
2021 | void *strtab; | 2050 | void *strtab; |
2022 | u64 reg; | 2051 | u64 reg; |
2023 | u32 size; | 2052 | u32 size, l1size; |
2024 | int ret; | 2053 | int ret; |
2025 | struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; | 2054 | struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; |
2026 | 2055 | ||
2027 | /* Calculate the L1 size, capped to the SIDSIZE */ | 2056 | /* Calculate the L1 size, capped to the SIDSIZE */ |
2028 | size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3); | 2057 | size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3); |
2029 | size = min(size, smmu->sid_bits - STRTAB_SPLIT); | 2058 | size = min(size, smmu->sid_bits - STRTAB_SPLIT); |
2030 | if (size + STRTAB_SPLIT < smmu->sid_bits) | 2059 | cfg->num_l1_ents = 1 << size; |
2060 | |||
2061 | size += STRTAB_SPLIT; | ||
2062 | if (size < smmu->sid_bits) | ||
2031 | dev_warn(smmu->dev, | 2063 | dev_warn(smmu->dev, |
2032 | "2-level strtab only covers %u/%u bits of SID\n", | 2064 | "2-level strtab only covers %u/%u bits of SID\n", |
2033 | size + STRTAB_SPLIT, smmu->sid_bits); | 2065 | size, smmu->sid_bits); |
2034 | 2066 | ||
2035 | cfg->num_l1_ents = 1 << size; | 2067 | l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3); |
2036 | size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3); | 2068 | strtab = dma_zalloc_coherent(smmu->dev, l1size, &cfg->strtab_dma, |
2037 | strtab = dma_zalloc_coherent(smmu->dev, size, &cfg->strtab_dma, | ||
2038 | GFP_KERNEL); | 2069 | GFP_KERNEL); |
2039 | if (!strtab) { | 2070 | if (!strtab) { |
2040 | dev_err(smmu->dev, | 2071 | dev_err(smmu->dev, |
@@ -2055,8 +2086,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) | |||
2055 | ret = arm_smmu_init_l1_strtab(smmu); | 2086 | ret = arm_smmu_init_l1_strtab(smmu); |
2056 | if (ret) | 2087 | if (ret) |
2057 | dma_free_coherent(smmu->dev, | 2088 | dma_free_coherent(smmu->dev, |
2058 | cfg->num_l1_ents * | 2089 | l1size, |
2059 | (STRTAB_L1_DESC_DWORDS << 3), | ||
2060 | strtab, | 2090 | strtab, |
2061 | cfg->strtab_dma); | 2091 | cfg->strtab_dma); |
2062 | return ret; | 2092 | return ret; |
@@ -2573,6 +2603,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
2573 | if (irq > 0) | 2603 | if (irq > 0) |
2574 | smmu->gerr_irq = irq; | 2604 | smmu->gerr_irq = irq; |
2575 | 2605 | ||
2606 | parse_driver_options(smmu); | ||
2607 | |||
2576 | /* Probe the h/w */ | 2608 | /* Probe the h/w */ |
2577 | ret = arm_smmu_device_probe(smmu); | 2609 | ret = arm_smmu_device_probe(smmu); |
2578 | if (ret) | 2610 | if (ret) |