Skip to content

Commit

Permalink
xive: DD2.0 updates
Browse files Browse the repository at this point in the history
Add support for StoreEOI, fix StoreEOI MMIO offset in ESB page,
and other cleanups

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
  • Loading branch information
ozbenh authored and stewartsmith committed Jun 26, 2017
1 parent 8019007 commit c890a1f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 8 deletions.
56 changes: 48 additions & 8 deletions hw/xive.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ struct xive {
uint32_t chip_id;
uint32_t block_id;
struct dt_node *x_node;
int rev;
#define XIVE_REV_UNKNOWN 0 /* Unknown version */
#define XIVE_REV_1 1 /* P9 (Nimbus) DD1.x */
#define XIVE_REV_2 2 /* P9 (Nimbus) DD2.x or Cumulus */

uint64_t xscom_base;

Expand Down Expand Up @@ -488,6 +492,7 @@ static struct dt_node *xive_dt_node;
static uint32_t xive_block_to_chip[XIVE_MAX_CHIPS];
static uint32_t xive_block_count;

#ifdef USE_BLOCK_GROUP_MODE
static uint32_t xive_chip_to_block(uint32_t chip_id)
{
struct proc_chip *c = get_chip(chip_id);
Expand All @@ -496,6 +501,7 @@ static uint32_t xive_chip_to_block(uint32_t chip_id)
assert(c->xive);
return c->xive->block_id;
}
#endif

/* Conversion between GIRQ and block/index.
*
Expand Down Expand Up @@ -1678,20 +1684,37 @@ static bool xive_config_init(struct xive *x)
val = xive_regr(x, VC_GLOBAL_CONFIG);
val |= VC_GCONF_INDIRECT;
xive_regw(x, VC_GLOBAL_CONFIG, val);
#endif

/* Enable indirect mode in PC config */
val = xive_regr(x, PC_GLOBAL_CONFIG);
#ifdef USE_INDIRECT
val |= PC_GCONF_INDIRECT;
xive_regw(x, PC_GLOBAL_CONFIG, val);
#endif
val |= PC_GCONF_CHIPID_OVR;
val = SETFIELD(PC_GCONF_CHIPID, val, x->block_id);
xive_regw(x, PC_GLOBAL_CONFIG, val);
xive_dbg(x, "PC_GLOBAL_CONFIG=%016llx\n", val);

val = xive_regr(x, PC_TCTXT_CFG);
#ifdef USE_BLOCK_GROUP_MODE
val |= PC_TCTXT_CFG_BLKGRP_EN | PC_TCTXT_CFG_HARD_CHIPID_BLK;
#endif
val |= PC_TCTXT_CHIPID_OVERRIDE;
val |= PC_TCTXT_CFG_TARGET_EN;
val = SETFIELD(PC_TCTXT_CHIPID, val, x->block_id);
xive_regw(x, PC_TCTXT_CFG, val);
xive_dbg(x, "PC_TCTXT_CFG=%016llx\n", val);

/* Subsequent inits are DD2 only */
if (x->rev < XIVE_REV_2)
return true;

/* Enable StoreEOI */
val = xive_regr(x, VC_SBC_CONFIG);
val |= VC_SBC_CONF_CPLX_CIST | VC_SBC_CONF_CIST_BOTH;
val |= VC_SBC_CONF_NO_UPD_PRF;
xive_regw(x, VC_SBC_CONFIG, val);

return true;
}
Expand Down Expand Up @@ -2562,7 +2585,7 @@ void __xive_source_eoi(struct irq_source *is, uint32_t isn)

/* If the XIVE supports the new "store EOI facility, use it */
if (s->flags & XIVE_SRC_STORE_EOI)
out_be64(mmio_base, 0);
out_be64(mmio_base + 0x400, 0);
else {
uint64_t offset;

Expand Down Expand Up @@ -2682,26 +2705,31 @@ void xive_register_ipi_source(uint32_t base, uint32_t count, void *data,
struct xive *x = xive_from_isn(base);
uint32_t base_idx = GIRQ_TO_IDX(base);
void *mmio_base;
uint32_t flags = XIVE_SRC_EOI_PAGE1 | XIVE_SRC_TRIGGER_PAGE;

assert(x);
assert(base >= x->int_base && (base + count) <= x->int_ipi_top);

s = malloc(sizeof(struct xive_src));
assert(s);

/* Store EOI supported on DD2.0 */
if (x->rev >= XIVE_REV_2)
flags |= XIVE_SRC_STORE_EOI;

/* Callbacks assume the MMIO base corresponds to the first
* interrupt of that source structure so adjust it
*/
mmio_base = x->esb_mmio + (1ul << IPI_ESB_SHIFT) * base_idx;
__xive_register_source(x, s, base, count, IPI_ESB_SHIFT, mmio_base,
XIVE_SRC_EOI_PAGE1 | XIVE_SRC_TRIGGER_PAGE,
false, data, ops);
flags, false, data, ops);
}

static struct xive *init_one_xive(struct dt_node *np)
{
struct xive *x;
struct proc_chip *chip;
uint32_t flags;

x = zalloc(sizeof(struct xive));
assert(x);
Expand All @@ -2717,7 +2745,18 @@ static struct xive *init_one_xive(struct dt_node *np)

chip = get_chip(x->chip_id);
assert(chip);
xive_dbg(x, "Initializing, block ID %d...\n", x->block_id);

x->rev = XIVE_REV_UNKNOWN;
if (chip->type == PROC_CHIP_P9_NIMBUS) {
if ((chip->ec_level & 0xf0) == 0x10)
x->rev = XIVE_REV_1;
else if ((chip->ec_level & 0xf0) == 0x20)
x->rev = XIVE_REV_2;
} else if (chip->type == PROC_CHIP_P9_CUMULUS)
x->rev = XIVE_REV_2;

xive_dbg(x, "Initializing rev %d block ID %d...\n",
x->rev, x->block_id);
chip->xive = x;

#ifdef USE_INDIRECT
Expand Down Expand Up @@ -2781,11 +2820,12 @@ static struct xive *init_one_xive(struct dt_node *np)
goto fail;

/* Register built-in source controllers (aka IPIs) */
flags = XIVE_SRC_EOI_PAGE1 | XIVE_SRC_TRIGGER_PAGE;
if (x->rev >= XIVE_REV_2)
flags |= XIVE_SRC_STORE_EOI;
__xive_register_source(x, &x->ipis, x->int_base,
x->int_hw_bot - x->int_base, IPI_ESB_SHIFT,
x->esb_mmio,
XIVE_SRC_EOI_PAGE1 | XIVE_SRC_TRIGGER_PAGE,
true, NULL, NULL);
x->esb_mmio, flags, true, NULL, NULL);

/* Register escalation sources */
__xive_register_source(x, &x->esc_irqs,
Expand Down
7 changes: 7 additions & 0 deletions include/xive.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#define X_PC_TCTXT_CFG 0x100
#define PC_TCTXT_CFG 0x400
#define PC_TCTXT_CFG_BLKGRP_EN PPC_BIT(0)
#define PC_TCTXT_CFG_TARGET_EN PPC_BIT(1)
#define PC_TCTXT_CFG_HARD_CHIPID_BLK PPC_BIT(8)
#define PC_TCTXT_CHIPID_OVERRIDE PPC_BIT(9)
#define PC_TCTXT_CHIPID PPC_BITMASK(12,15)
Expand Down Expand Up @@ -102,6 +103,8 @@
#define X_PC_GLOBAL_CONFIG 0x110
#define PC_GLOBAL_CONFIG 0x480
#define PC_GCONF_INDIRECT PPC_BIT(32)
#define PC_GCONF_CHIPID_OVR PPC_BIT(40)
#define PC_GCONF_CHIPID PPC_BITMASK(44,47)
#define X_PC_VSD_TABLE_ADDR 0x111
#define PC_VSD_TABLE_ADDR 0x488
#define X_PC_VSD_TABLE_DATA 0x112
Expand Down Expand Up @@ -225,6 +228,10 @@
#define VC_SBC_CACHE_SCRUB_TRIG 0xa10
#define VC_SBC_CACHE_SCRUB_MASK 0xa18
#define VC_SBC_CONFIG 0xa20
#define X_VC_SBC_CONFIG 0x234
#define VC_SBC_CONF_CPLX_CIST PPC_BIT(44)
#define VC_SBC_CONF_CIST_BOTH PPC_BIT(45)
#define VC_SBC_CONF_NO_UPD_PRF PPC_BIT(59)

/* VC1 register offsets */

Expand Down

0 comments on commit c890a1f

Please sign in to comment.