irqchip fixes for v4.0 (round 2)
- GICv3 ITS - Small batch of fixes discovered while writing the kvm ITS emulation -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJVHcHDAAoJEP45WPkGe8ZnrXUP/Rp67onmizG6AtVNTCB5HT0V 6HNrLS4cnlpkFpWLf75ojZKfjJ/Gi3Bo4aqie9iWbOgGuI4/vxo35FdoBP8992k2 Stm++FR1jWdxbsTZJxdIqkl2uw7enA/0wpJL2JttdHFb+7Inirh0rphEyNAw24y4 Qe1hQT+c4CzCLA6ED5bqN7z28X9RoesW6dt8zDk/08IrolVsVSt+ZEdepBBBIZYf u3d+mOP0UohAew+g+hVLvwTplcQVQK+ZGdnzoyMf9s/3r2bAobGFZvCQxoJLm7fw tAV1Uf/iYFkqBzWYj8VC9crxY7QK2sr68OA+QMAkJoBYW0ypBowvggx+noAd4FO4 jPKGbmEJrYxbk3woxwZKvihU1fXbsQq8OykEk/urZeZyCPIXz9TIDneiI+RGGh9a 1o6Iu605bbKttwzlHjzU8C0y34qDLyJpA+zjIQJbXWOExyHynP4jIDEkvV7PGIQn Z88QKvkDn0TUdnPkaBUHOI1Y6SJm/ernR0FomIKWyd4innwfjyQCTRXaCryfRVWW lLRSakFyaRWjmNX50eDRp8x8yUPJhyg4Dd25Dd4KWZv5QhD7DJctywwjDCf+l9jC 8U8BbvhbPO2pwXratGNcbjapotAHX9Y46BHr0TrI4nbcaUz5+JvPLMQE6UA/92SQ aT8pb4m7zfS5zhZPL06D =Q4Dt -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
4e8a4830dc
|
@ -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) {
|
||||
|
|
|
@ -126,8 +126,23 @@
|
|||
#define GICR_PROPBASER_WaWb (5U << 7)
|
||||
#define GICR_PROPBASER_RaWaWt (6U << 7)
|
||||
#define GICR_PROPBASER_RaWaWb (7U << 7)
|
||||
#define GICR_PROPBASER_CACHEABILITY_MASK (7U << 7)
|
||||
#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
|
||||
*/
|
||||
|
@ -182,6 +197,7 @@
|
|||
#define GITS_CBASER_WaWb (5UL << 59)
|
||||
#define GITS_CBASER_RaWaWt (6UL << 59)
|
||||
#define GITS_CBASER_RaWaWb (7UL << 59)
|
||||
#define GITS_CBASER_CACHEABILITY_MASK (7UL << 59)
|
||||
#define GITS_CBASER_NonShareable (0UL << 10)
|
||||
#define GITS_CBASER_InnerShareable (1UL << 10)
|
||||
#define GITS_CBASER_OuterShareable (2UL << 10)
|
||||
|
@ -198,6 +214,7 @@
|
|||
#define GITS_BASER_WaWb (5UL << 59)
|
||||
#define GITS_BASER_RaWaWt (6UL << 59)
|
||||
#define GITS_BASER_RaWaWb (7UL << 59)
|
||||
#define GITS_BASER_CACHEABILITY_MASK (7UL << 59)
|
||||
#define GITS_BASER_TYPE_SHIFT (56)
|
||||
#define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7)
|
||||
#define GITS_BASER_ENTRY_SIZE_SHIFT (48)
|
||||
|
|
Loading…
Reference in a new issue