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
802802 int i;
803803 int psz = SZ_64K;
804804 u64 shr = GITS_BASER_InnerShareable;
805+ u64 cache = GITS_BASER_WaWb;
805806
806807 for (i = 0; i < GITS_BASER_NR_REGS; i++) {
807808 u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -848,7 +849,7 @@ retry_baser: · 40 unmodified lines
848849 val = (virt_to_phys(base) |
849850 (type << GITS_BASER_TYPE_SHIFT) |
850851 ((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
851− GITS_BASER_WaWb |
852+ cache |
852853 shr |
853854 GITS_BASER_VALID);
854855
@@ -874,9 +875,12 @@ retry_baser: · 19 unmodified lines
874875 * Shareability didn't stick. Just use
875876 * whatever the read reported, which is likely
876877 * to be the only thing this redistributor
877− * supports.
878+ * supports. If that's zero, make it
879+ * non-cacheable as well.
878880 */
879881 shr = tmp & GITS_BASER_SHAREABILITY_MASK;
882+ if (!shr)
883+ cache = GITS_BASER_nC;
880884 goto retry_baser;
881885 }
882886
@@ -980,6 +984,17 @@ static void its_cpu_init_lpis(void) · 97 unmodified lines
980984 tmp = readq_relaxed(rbase + GICR_PROPBASER);
981985
982986 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+ }
983998 pr_info_once("GIC: using cache flushing for LPI property table\n");
984999 gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
9851000 }
@@ -990,6 +1005,18 @@ static void its_cpu_init_lpis(void) · 4 unmodified lines
9901005 GICR_PENDBASER_WaWb);
9911006
9921007 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+ }
9931020
9941021 /* Enable LPIs */
9951022 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
14221449
14231450 writeq_relaxed(baser, its->base + GITS_CBASER);
14241451 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);
14271452
14281453 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+ }
14291465 pr_info("ITS: using cache flushing for cmd queue\n");
14301466 its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING;
14311467 }
14321468
1469+ writeq_relaxed(0, its->base + GITS_CWRITER);
1470+ writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
1471+
14331472 if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) {
14341473 its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its);
14351474 if (!its->domain) {
include/linux/irqchip/arm-gic-v3.h+4−0
@@ -126,6 +126,7 @@ · 125 unmodified lines
126126 #define GICR_PROPBASER_WaWb (5U << 7)
127127 #define GICR_PROPBASER_RaWaWt (6U << 7)
128128 #define GICR_PROPBASER_RaWaWb (7U << 7)
129+#define GICR_PROPBASER_CACHEABILITY_MASK (7U << 7)
129130 #define GICR_PROPBASER_IDBITS_MASK (0x1f)
130131
131132 #define GICR_PENDBASER_NonShareable (0U << 10)
@@ -140,6 +141,7 @@ · 8 unmodified lines
140141 #define GICR_PENDBASER_WaWb (5U << 7)
141142 #define GICR_PENDBASER_RaWaWt (6U << 7)
142143 #define GICR_PENDBASER_RaWaWb (7U << 7)
144+#define GICR_PENDBASER_CACHEABILITY_MASK (7U << 7)
143145
144146 /*
145147 * Re-Distributor registers, offsets from SGI_base
@@ -195,6 +197,7 @@ · 49 unmodified lines
195197 #define GITS_CBASER_WaWb (5UL << 59)
196198 #define GITS_CBASER_RaWaWt (6UL << 59)
197199 #define GITS_CBASER_RaWaWb (7UL << 59)
200+#define GITS_CBASER_CACHEABILITY_MASK (7UL << 59)
198201 #define GITS_CBASER_NonShareable (0UL << 10)
199202 #define GITS_CBASER_InnerShareable (1UL << 10)
200203 #define GITS_CBASER_OuterShareable (2UL << 10)
@@ -211,6 +214,7 @@ · 10 unmodified lines
211214 #define GITS_BASER_WaWb (5UL << 59)
212215 #define GITS_BASER_RaWaWt (6UL << 59)
213216 #define GITS_BASER_RaWaWb (7UL << 59)
217+#define GITS_BASER_CACHEABILITY_MASK (7UL << 59)
214218 #define GITS_BASER_TYPE_SHIFT (56)
215219 #define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7)
216220 #define GITS_BASER_ENTRY_SIZE_SHIFT (48)