History

irqchip: gicv3-its: Use non-cacheable accesses when no shareability

If the ITS or the redistributors report their shareability as zero, then it is important to make sure they will no generate any cacheable traffic, as this is unlikely to produce the expected result.

Marc Zyngier committed 11 years ago

Commit 241a3861 parent 4ad3e362 files · +47 −4Browse files

Unified · Split

2 files
  1. drivers/irqchip/irq-gic-v3-its.c +43 −4
  2. include/linux/irqchip/arm-gic-v3.h +4 −0
drivers/irqchip/irq-gic-v3-its.c+43−4
@@ -802,6 +802,7 @@ static int its_alloc_tables(struct its_node *its) · 801 unmodified lines
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: · 40 unmodified lines
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: · 19 unmodified lines
874 * Shareability didn't stick. Just use875 * Shareability didn't stick. Just use
875 * whatever the read reported, which is likely876 * whatever the read reported, which is likely
876 * to be the only thing this redistributor877 * 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) · 97 unmodified lines
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) · 4 unmodified lines
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) · 426 unmodified lines
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) {
include/linux/irqchip/arm-gic-v3.h+4−0
@@ -126,6 +126,7 @@ · 125 unmodified lines
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 @@ · 8 unmodified lines
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_base147 * Re-Distributor registers, offsets from SGI_base
@@ -195,6 +197,7 @@ · 49 unmodified lines
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 @@ · 10 unmodified lines
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)