diff options
| -rw-r--r-- | drivers/irqchip/irq-gic-v3-its.c | 47 | ||||
| -rw-r--r-- | include/linux/irqchip/arm-gic-v3.h | 4 |
2 files changed, 47 insertions, 4 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 56353f6b5952..9687f8afebff 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
| @@ -802,6 +802,7 @@ static int its_alloc_tables(struct its_node *its) | |||
| 802 | int i; | 802 | int i; |
| 803 | int psz = SZ_64K; | 803 | int psz = SZ_64K; |
| 804 | u64 shr = GITS_BASER_InnerShareable; | 804 | u64 shr = GITS_BASER_InnerShareable; |
| 805 | u64 cache = GITS_BASER_WaWb; | ||
| 805 | 806 | ||
| 806 | for (i = 0; i < GITS_BASER_NR_REGS; i++) { | 807 | for (i = 0; i < GITS_BASER_NR_REGS; i++) { |
| 807 | u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); | 808 | u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); |
| @@ -848,7 +849,7 @@ retry_baser: | |||
| 848 | val = (virt_to_phys(base) | | 849 | val = (virt_to_phys(base) | |
| 849 | (type << GITS_BASER_TYPE_SHIFT) | | 850 | (type << GITS_BASER_TYPE_SHIFT) | |
| 850 | ((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | | 851 | ((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | |
| 851 | GITS_BASER_WaWb | | 852 | cache | |
| 852 | shr | | 853 | shr | |
| 853 | GITS_BASER_VALID); | 854 | GITS_BASER_VALID); |
| 854 | 855 | ||
| @@ -874,9 +875,12 @@ retry_baser: | |||
| 874 | * Shareability didn't stick. Just use | 875 | * Shareability didn't stick. Just use |
| 875 | * whatever the read reported, which is likely | 876 | * whatever the read reported, which is likely |
| 876 | * to be the only thing this redistributor | 877 | * to be the only thing this redistributor |
| 877 | * supports. | 878 | * supports. If that's zero, make it |
| 879 | * non-cacheable as well. | ||
| 878 | */ | 880 | */ |
| 879 | shr = tmp & GITS_BASER_SHAREABILITY_MASK; | 881 | shr = tmp & GITS_BASER_SHAREABILITY_MASK; |
| 882 | if (!shr) | ||
| 883 | cache = GITS_BASER_nC; | ||
| 880 | goto retry_baser; | 884 | goto retry_baser; |
| 881 | } | 885 | } |
| 882 | 886 | ||
| @@ -980,6 +984,17 @@ static void its_cpu_init_lpis(void) | |||
| 980 | tmp = readq_relaxed(rbase + GICR_PROPBASER); | 984 | tmp = readq_relaxed(rbase + GICR_PROPBASER); |
| 981 | 985 | ||
| 982 | if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) { | 986 | if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) { |
| 987 | if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) { | ||
| 988 | /* | ||
| 989 | * The HW reports non-shareable, we must | ||
| 990 | * remove the cacheability attributes as | ||
| 991 | * well. | ||
| 992 | */ | ||
| 993 | val &= ~(GICR_PROPBASER_SHAREABILITY_MASK | | ||
| 994 | GICR_PROPBASER_CACHEABILITY_MASK); | ||
| 995 | val |= GICR_PROPBASER_nC; | ||
| 996 | writeq_relaxed(val, rbase + GICR_PROPBASER); | ||
| 997 | } | ||
| 983 | pr_info_once("GIC: using cache flushing for LPI property table\n"); | 998 | pr_info_once("GIC: using cache flushing for LPI property table\n"); |
| 984 | gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING; | 999 | gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING; |
| 985 | } | 1000 | } |
| @@ -990,6 +1005,18 @@ static void its_cpu_init_lpis(void) | |||
| 990 | GICR_PENDBASER_WaWb); | 1005 | GICR_PENDBASER_WaWb); |
| 991 | 1006 | ||
| 992 | writeq_relaxed(val, rbase + GICR_PENDBASER); | 1007 | writeq_relaxed(val, rbase + GICR_PENDBASER); |
| 1008 | tmp = readq_relaxed(rbase + GICR_PENDBASER); | ||
| 1009 | |||
| 1010 | if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) { | ||
| 1011 | /* | ||
| 1012 | * The HW reports non-shareable, we must remove the | ||
| 1013 | * cacheability attributes as well. | ||
| 1014 | */ | ||
| 1015 | val &= ~(GICR_PENDBASER_SHAREABILITY_MASK | | ||
| 1016 | GICR_PENDBASER_CACHEABILITY_MASK); | ||
| 1017 | val |= GICR_PENDBASER_nC; | ||
| 1018 | writeq_relaxed(val, rbase + GICR_PENDBASER); | ||
| 1019 | } | ||
| 993 | 1020 | ||
| 994 | /* Enable LPIs */ | 1021 | /* Enable LPIs */ |
| 995 | val = readl_relaxed(rbase + GICR_CTLR); | 1022 | val = readl_relaxed(rbase + GICR_CTLR); |
| @@ -1422,14 +1449,26 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) | |||
| 1422 | 1449 | ||
| 1423 | writeq_relaxed(baser, its->base + GITS_CBASER); | 1450 | writeq_relaxed(baser, its->base + GITS_CBASER); |
| 1424 | tmp = readq_relaxed(its->base + GITS_CBASER); | 1451 | tmp = readq_relaxed(its->base + GITS_CBASER); |
| 1425 | writeq_relaxed(0, its->base + GITS_CWRITER); | ||
| 1426 | writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); | ||
| 1427 | 1452 | ||
| 1428 | if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) { | 1453 | if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) { |
| 1454 | if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) { | ||
| 1455 | /* | ||
| 1456 | * The HW reports non-shareable, we must | ||
| 1457 | * remove the cacheability attributes as | ||
| 1458 | * well. | ||
| 1459 | */ | ||
| 1460 | baser &= ~(GITS_CBASER_SHAREABILITY_MASK | | ||
| 1461 | GITS_CBASER_CACHEABILITY_MASK); | ||
| 1462 | baser |= GITS_CBASER_nC; | ||
| 1463 | writeq_relaxed(baser, its->base + GITS_CBASER); | ||
| 1464 | } | ||
| 1429 | pr_info("ITS: using cache flushing for cmd queue\n"); | 1465 | pr_info("ITS: using cache flushing for cmd queue\n"); |
| 1430 | its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING; | 1466 | its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING; |
| 1431 | } | 1467 | } |
| 1432 | 1468 | ||
| 1469 | writeq_relaxed(0, its->base + GITS_CWRITER); | ||
| 1470 | writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); | ||
| 1471 | |||
| 1433 | if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) { | 1472 | if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) { |
| 1434 | its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its); | 1473 | its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its); |
| 1435 | if (!its->domain) { | 1474 | if (!its->domain) { |
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 826a4bd63d4a..ffbc034c8810 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h | |||
| @@ -126,6 +126,7 @@ | |||
| 126 | #define GICR_PROPBASER_WaWb (5U << 7) | 126 | #define GICR_PROPBASER_WaWb (5U << 7) |
| 127 | #define GICR_PROPBASER_RaWaWt (6U << 7) | 127 | #define GICR_PROPBASER_RaWaWt (6U << 7) |
| 128 | #define GICR_PROPBASER_RaWaWb (7U << 7) | 128 | #define GICR_PROPBASER_RaWaWb (7U << 7) |
| 129 | #define GICR_PROPBASER_CACHEABILITY_MASK (7U << 7) | ||
| 129 | #define GICR_PROPBASER_IDBITS_MASK (0x1f) | 130 | #define GICR_PROPBASER_IDBITS_MASK (0x1f) |
| 130 | 131 | ||
| 131 | #define GICR_PENDBASER_NonShareable (0U << 10) | 132 | #define GICR_PENDBASER_NonShareable (0U << 10) |
| @@ -140,6 +141,7 @@ | |||
| 140 | #define GICR_PENDBASER_WaWb (5U << 7) | 141 | #define GICR_PENDBASER_WaWb (5U << 7) |
| 141 | #define GICR_PENDBASER_RaWaWt (6U << 7) | 142 | #define GICR_PENDBASER_RaWaWt (6U << 7) |
| 142 | #define GICR_PENDBASER_RaWaWb (7U << 7) | 143 | #define GICR_PENDBASER_RaWaWb (7U << 7) |
| 144 | #define GICR_PENDBASER_CACHEABILITY_MASK (7U << 7) | ||
| 143 | 145 | ||
| 144 | /* | 146 | /* |
| 145 | * Re-Distributor registers, offsets from SGI_base | 147 | * Re-Distributor registers, offsets from SGI_base |
| @@ -195,6 +197,7 @@ | |||
| 195 | #define GITS_CBASER_WaWb (5UL << 59) | 197 | #define GITS_CBASER_WaWb (5UL << 59) |
| 196 | #define GITS_CBASER_RaWaWt (6UL << 59) | 198 | #define GITS_CBASER_RaWaWt (6UL << 59) |
| 197 | #define GITS_CBASER_RaWaWb (7UL << 59) | 199 | #define GITS_CBASER_RaWaWb (7UL << 59) |
| 200 | #define GITS_CBASER_CACHEABILITY_MASK (7UL << 59) | ||
| 198 | #define GITS_CBASER_NonShareable (0UL << 10) | 201 | #define GITS_CBASER_NonShareable (0UL << 10) |
| 199 | #define GITS_CBASER_InnerShareable (1UL << 10) | 202 | #define GITS_CBASER_InnerShareable (1UL << 10) |
| 200 | #define GITS_CBASER_OuterShareable (2UL << 10) | 203 | #define GITS_CBASER_OuterShareable (2UL << 10) |
| @@ -211,6 +214,7 @@ | |||
| 211 | #define GITS_BASER_WaWb (5UL << 59) | 214 | #define GITS_BASER_WaWb (5UL << 59) |
| 212 | #define GITS_BASER_RaWaWt (6UL << 59) | 215 | #define GITS_BASER_RaWaWt (6UL << 59) |
| 213 | #define GITS_BASER_RaWaWb (7UL << 59) | 216 | #define GITS_BASER_RaWaWb (7UL << 59) |
| 217 | #define GITS_BASER_CACHEABILITY_MASK (7UL << 59) | ||
| 214 | #define GITS_BASER_TYPE_SHIFT (56) | 218 | #define GITS_BASER_TYPE_SHIFT (56) |
| 215 | #define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7) | 219 | #define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7) |
| 216 | #define GITS_BASER_ENTRY_SIZE_SHIFT (48) | 220 | #define GITS_BASER_ENTRY_SIZE_SHIFT (48) |
