|
34 | 34 | #define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80) |
35 | 35 |
|
36 | 36 | #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0) |
| 37 | +#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1) |
37 | 38 |
|
38 | 39 | struct redist_region { |
39 | 40 | void __iomem *redist_base; |
@@ -1464,6 +1465,15 @@ static bool gic_enable_quirk_msm8996(void *data) |
1464 | 1465 | return true; |
1465 | 1466 | } |
1466 | 1467 |
|
| 1468 | +static bool gic_enable_quirk_cavium_38539(void *data) |
| 1469 | +{ |
| 1470 | + struct gic_chip_data *d = data; |
| 1471 | + |
| 1472 | + d->flags |= FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539; |
| 1473 | + |
| 1474 | + return true; |
| 1475 | +} |
| 1476 | + |
1467 | 1477 | static bool gic_enable_quirk_hip06_07(void *data) |
1468 | 1478 | { |
1469 | 1479 | struct gic_chip_data *d = data; |
@@ -1502,6 +1512,19 @@ static const struct gic_quirk gic_quirks[] = { |
1502 | 1512 | .mask = 0xffffffff, |
1503 | 1513 | .init = gic_enable_quirk_hip06_07, |
1504 | 1514 | }, |
| 1515 | + { |
| 1516 | + /* |
| 1517 | + * Reserved register accesses generate a Synchronous |
| 1518 | + * External Abort. This erratum applies to: |
| 1519 | + * - ThunderX: CN88xx |
| 1520 | + * - OCTEON TX: CN83xx, CN81xx |
| 1521 | + * - OCTEON TX2: CN93xx, CN96xx, CN98xx, CNF95xx* |
| 1522 | + */ |
| 1523 | + .desc = "GICv3: Cavium erratum 38539", |
| 1524 | + .iidr = 0xa000034c, |
| 1525 | + .mask = 0xe8f00fff, |
| 1526 | + .init = gic_enable_quirk_cavium_38539, |
| 1527 | + }, |
1505 | 1528 | { |
1506 | 1529 | } |
1507 | 1530 | }; |
@@ -1577,7 +1600,12 @@ static int __init gic_init_bases(void __iomem *dist_base, |
1577 | 1600 | pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32); |
1578 | 1601 | pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR); |
1579 | 1602 |
|
1580 | | - gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2); |
| 1603 | + /* |
| 1604 | + * ThunderX1 explodes on reading GICD_TYPER2, in violation of the |
| 1605 | + * architecture spec (which says that reserved registers are RES0). |
| 1606 | + */ |
| 1607 | + if (!(gic_data.flags & FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539)) |
| 1608 | + gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2); |
1581 | 1609 |
|
1582 | 1610 | gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, |
1583 | 1611 | &gic_data); |
|
0 commit comments