Commit 4e8a4830 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'irqchip-fixes-4.0-2' of git://git.infradead.org/users/jcooper/linux

Pull irqchip fixes from Jason Cooper:
 "This is the second round of fixes for irqchip.  It contains some fixes
  found while the arm64 guys were writing the kvm gicv3 its emulation.

  GICv3 ITS:
    - Small batch of fixes discovered while writing the kvm ITS emulation"

* tag 'irqchip-fixes-4.0-2' of git://git.infradead.org/users/jcooper/linux:
  irqchip: gicv3-its: Use non-cacheable accesses when no shareability
  irqchip: gicv3-its: Fix PROP/PEND and BASE/CBASE confusion
  irqchip: gicv3-its: Fix device ID encoding
  irqchip: gicv3-its: Fix encoding of collection's target redistributor
parents b0838b15 dbcf9886
...@@ -169,7 +169,7 @@ static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr) ...@@ -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) 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; cmd->raw_cmd[0] |= ((u64)devid) << 32;
} }
...@@ -802,6 +802,7 @@ static int its_alloc_tables(struct its_node *its) ...@@ -802,6 +802,7 @@ static int its_alloc_tables(struct its_node *its)
int i; int i;
int psz = SZ_64K; int psz = SZ_64K;
u64 shr = GITS_BASER_InnerShareable; u64 shr = GITS_BASER_InnerShareable;
u64 cache = GITS_BASER_WaWb;
for (i = 0; i < GITS_BASER_NR_REGS; i++) { for (i = 0; i < GITS_BASER_NR_REGS; i++) {
u64 val = readq_relaxed(its->base + GITS_BASER + i * 8); u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
...@@ -848,7 +849,7 @@ static int its_alloc_tables(struct its_node *its) ...@@ -848,7 +849,7 @@ static int its_alloc_tables(struct its_node *its)
val = (virt_to_phys(base) | val = (virt_to_phys(base) |
(type << GITS_BASER_TYPE_SHIFT) | (type << GITS_BASER_TYPE_SHIFT) |
((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | ((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
GITS_BASER_WaWb | cache |
shr | shr |
GITS_BASER_VALID); GITS_BASER_VALID);
...@@ -874,9 +875,12 @@ static int its_alloc_tables(struct its_node *its) ...@@ -874,9 +875,12 @@ static int its_alloc_tables(struct its_node *its)
* Shareability didn't stick. Just use * Shareability didn't stick. Just use
* whatever the read reported, which is likely * whatever the read reported, which is likely
* to be the only thing this redistributor * 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; shr = tmp & GITS_BASER_SHAREABILITY_MASK;
if (!shr)
cache = GITS_BASER_nC;
goto retry_baser; goto retry_baser;
} }
...@@ -980,16 +984,39 @@ static void its_cpu_init_lpis(void) ...@@ -980,16 +984,39 @@ static void its_cpu_init_lpis(void)
tmp = readq_relaxed(rbase + GICR_PROPBASER); tmp = readq_relaxed(rbase + GICR_PROPBASER);
if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) { 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"); pr_info_once("GIC: using cache flushing for LPI property table\n");
gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING; gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
} }
/* set PENDBASE */ /* set PENDBASE */
val = (page_to_phys(pend_page) | val = (page_to_phys(pend_page) |
GICR_PROPBASER_InnerShareable | GICR_PENDBASER_InnerShareable |
GICR_PROPBASER_WaWb); GICR_PENDBASER_WaWb);
writeq_relaxed(val, rbase + GICR_PENDBASER); 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 */ /* Enable LPIs */
val = readl_relaxed(rbase + GICR_CTLR); val = readl_relaxed(rbase + GICR_CTLR);
...@@ -1026,7 +1053,7 @@ static void its_cpu_init_collection(void) ...@@ -1026,7 +1053,7 @@ static void its_cpu_init_collection(void)
* This ITS wants a linear CPU number. * This ITS wants a linear CPU number.
*/ */
target = readq_relaxed(gic_data_rdist_rd_base() + GICR_TYPER); 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 */ /* Perform collection mapping */
...@@ -1422,14 +1449,26 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) ...@@ -1422,14 +1449,26 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
writeq_relaxed(baser, its->base + GITS_CBASER); writeq_relaxed(baser, its->base + GITS_CBASER);
tmp = readq_relaxed(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"); pr_info("ITS: using cache flushing for cmd queue\n");
its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING; 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")) { if (of_property_read_bool(its->msi_chip.of_node, "msi-controller")) {
its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its); its->domain = irq_domain_add_tree(NULL, &its_domain_ops, its);
if (!its->domain) { if (!its->domain) {
......
...@@ -126,8 +126,23 @@ ...@@ -126,8 +126,23 @@
#define GICR_PROPBASER_WaWb (5U << 7) #define GICR_PROPBASER_WaWb (5U << 7)
#define GICR_PROPBASER_RaWaWt (6U << 7) #define GICR_PROPBASER_RaWaWt (6U << 7)
#define GICR_PROPBASER_RaWaWb (7U << 7) #define GICR_PROPBASER_RaWaWb (7U << 7)
#define GICR_PROPBASER_CACHEABILITY_MASK (7U << 7)
#define GICR_PROPBASER_IDBITS_MASK (0x1f) #define GICR_PROPBASER_IDBITS_MASK (0x1f)
#define GICR_PENDBASER_NonShareable (0U << 10)
#define GICR_PENDBASER_InnerShareable (1U << 10)
#define GICR_PENDBASER_OuterShareable (2U << 10)
#define GICR_PENDBASER_SHAREABILITY_MASK (3UL << 10)
#define GICR_PENDBASER_nCnB (0U << 7)
#define GICR_PENDBASER_nC (1U << 7)
#define GICR_PENDBASER_RaWt (2U << 7)
#define GICR_PENDBASER_RaWb (3U << 7)
#define GICR_PENDBASER_WaWt (4U << 7)
#define GICR_PENDBASER_WaWb (5U << 7)
#define GICR_PENDBASER_RaWaWt (6U << 7)
#define GICR_PENDBASER_RaWaWb (7U << 7)
#define GICR_PENDBASER_CACHEABILITY_MASK (7U << 7)
/* /*
* Re-Distributor registers, offsets from SGI_base * Re-Distributor registers, offsets from SGI_base
*/ */
...@@ -182,6 +197,7 @@ ...@@ -182,6 +197,7 @@
#define GITS_CBASER_WaWb (5UL << 59) #define GITS_CBASER_WaWb (5UL << 59)
#define GITS_CBASER_RaWaWt (6UL << 59) #define GITS_CBASER_RaWaWt (6UL << 59)
#define GITS_CBASER_RaWaWb (7UL << 59) #define GITS_CBASER_RaWaWb (7UL << 59)
#define GITS_CBASER_CACHEABILITY_MASK (7UL << 59)
#define GITS_CBASER_NonShareable (0UL << 10) #define GITS_CBASER_NonShareable (0UL << 10)
#define GITS_CBASER_InnerShareable (1UL << 10) #define GITS_CBASER_InnerShareable (1UL << 10)
#define GITS_CBASER_OuterShareable (2UL << 10) #define GITS_CBASER_OuterShareable (2UL << 10)
...@@ -198,6 +214,7 @@ ...@@ -198,6 +214,7 @@
#define GITS_BASER_WaWb (5UL << 59) #define GITS_BASER_WaWb (5UL << 59)
#define GITS_BASER_RaWaWt (6UL << 59) #define GITS_BASER_RaWaWt (6UL << 59)
#define GITS_BASER_RaWaWb (7UL << 59) #define GITS_BASER_RaWaWb (7UL << 59)
#define GITS_BASER_CACHEABILITY_MASK (7UL << 59)
#define GITS_BASER_TYPE_SHIFT (56) #define GITS_BASER_TYPE_SHIFT (56)
#define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7) #define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7)
#define GITS_BASER_ENTRY_SIZE_SHIFT (48) #define GITS_BASER_ENTRY_SIZE_SHIFT (48)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment