|
@@ -169,7 +169,7 @@ static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr)
|
|
|
|
|
|
static void its_encode_devid(struct its_cmd_block *cmd, u32 devid)
|
|
|
{
|
|
|
- cmd->raw_cmd[0] &= ~(0xffffUL << 32);
|
|
|
+ cmd->raw_cmd[0] &= BIT_ULL(32) - 1;
|
|
|
cmd->raw_cmd[0] |= ((u64)devid) << 32;
|
|
|
}
|
|
|
|
|
@@ -802,6 +802,7 @@ static int its_alloc_tables(struct its_node *its)
|
|
|
int i;
|
|
|
int psz = SZ_64K;
|
|
|
u64 shr = GITS_BASER_InnerShareable;
|
|
|
+ u64 cache = GITS_BASER_WaWb;
|
|
|
|
|
|
for (i = 0; i < GITS_BASER_NR_REGS; i++) {
|
|
|
u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
|
|
@@ -848,7 +849,7 @@ retry_baser:
|
|
|
val = (virt_to_phys(base) |
|
|
|
(type << GITS_BASER_TYPE_SHIFT) |
|
|
|
((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
|
|
|
- GITS_BASER_WaWb |
|
|
|
+ cache |
|
|
|
shr |
|
|
|
GITS_BASER_VALID);
|
|
|
|
|
@@ -874,9 +875,12 @@ retry_baser:
|
|
|
* Shareability didn't stick. Just use
|
|
|
* whatever the read reported, which is likely
|
|
|
* to be the only thing this redistributor
|
|
|
- * supports.
|
|
|
+ * supports. If that's zero, make it
|
|
|
+ * non-cacheable as well.
|
|
|
*/
|
|
|
shr = tmp & GITS_BASER_SHAREABILITY_MASK;
|
|
|
+ if (!shr)
|
|
|
+ cache = GITS_BASER_nC;
|
|
|
goto retry_baser;
|
|
|
}
|
|
|
|
|
@@ -980,16 +984,39 @@ static void its_cpu_init_lpis(void)
|
|
|
tmp = readq_relaxed(rbase + GICR_PROPBASER);
|
|
|
|
|
|
if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
|
|
|
+ if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
|
|
|
+ /*
|
|
|
+ * The HW reports non-shareable, we must
|
|
|
+ * remove the cacheability attributes as
|
|
|
+ * well.
|
|
|
+ */
|
|
|
+ val &= ~(GICR_PROPBASER_SHAREABILITY_MASK |
|
|
|
+ GICR_PROPBASER_CACHEABILITY_MASK);
|
|
|
+ val |= GICR_PROPBASER_nC;
|
|
|
+ writeq_relaxed(val, rbase + GICR_PROPBASER);
|
|
|
+ }
|
|
|
pr_info_once("GIC: using cache flushing for LPI property table\n");
|
|
|
gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
|
|
|
}
|
|
|
|
|
|
/* set PENDBASE */
|
|
|
val = (page_to_phys(pend_page) |
|
|
|
- GICR_PROPBASER_InnerShareable |
|
|
|
- GICR_PROPBASER_WaWb);
|
|
|
+ GICR_PENDBASER_InnerShareable |
|
|
|
+ GICR_PENDBASER_WaWb);
|
|
|
|
|
|
writeq_relaxed(val, rbase + GICR_PENDBASER);
|
|
|
+ tmp = readq_relaxed(rbase + GICR_PENDBASER);
|
|
|
+
|
|
|
+ if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
|
|
|
+ /*
|
|
|
+ * The HW reports non-shareable, we must remove the
|
|
|
+ * cacheability attributes as well.
|
|
|
+ */
|
|
|
+ val &= ~(GICR_PENDBASER_SHAREABILITY_MASK |
|
|
|
+ GICR_PENDBASER_CACHEABILITY_MASK);
|
|
|
+ val |= GICR_PENDBASER_nC;
|
|
|
+ writeq_relaxed(val, rbase + GICR_PENDBASER);
|
|
|
+ }
|
|
|
|
|
|
/* Enable LPIs */
|
|
|
val = readl_relaxed(rbase + GICR_CTLR);
|
|
@@ -1026,7 +1053,7 @@ static void its_cpu_init_collection(void)
|
|
|
* This ITS wants a linear CPU number.
|
|
|
*/
|
|
|
target = readq_relaxed(gic_data_rdist_rd_base() + GICR_TYPER);
|
|
|
- target = GICR_TYPER_CPU_NUMBER(target);
|
|
|
+ target = GICR_TYPER_CPU_NUMBER(target) << 16;
|
|
|
}
|
|
|
|
|
|
/* Perform collection mapping */
|
|
@@ -1422,14 +1449,26 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
|
|
|
|
|
|
writeq_relaxed(baser, its->base + GITS_CBASER);
|
|
|
tmp = readq_relaxed(its->base + GITS_CBASER);
|
|
|
- writeq_relaxed(0, its->base + GITS_CWRITER);
|
|
|
- writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
|
|
|
|
|
|
- if ((tmp ^ baser) & GITS_BASER_SHAREABILITY_MASK) {
|
|
|
+ if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
|
|
|
+ if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
|
|
|
+ /*
|
|
|
+ * The HW reports non-shareable, we must
|
|
|
+ * remove the cacheability attributes as
|
|
|
+ * well.
|
|
|
+ */
|
|
|
+ baser &= ~(GITS_CBASER_SHAREABILITY_MASK |
|
|
|
+ GITS_CBASER_CACHEABILITY_MASK);
|
|
|
+ baser |= GITS_CBASER_nC;
|
|
|
+ writeq_relaxed(baser, its->base + GITS_CBASER);
|
|
|
+ }
|
|
|
pr_info("ITS: using cache flushing for cmd queue\n");
|
|
|
its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING;
|
|
|
}
|
|
|
|
|
|
+ writeq_relaxed(0, its->base + GITS_CWRITER);
|
|
|
+ writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
|
|
|
+
|
|
|
if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) {
|
|
|
its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its);
|
|
|
if (!its->domain) {
|