From cd8ce5dfa7a35fcea619bba791a6743e91deb4ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Wed, 4 Aug 2021 12:50:47 +0530 Subject: psi/p10: Activate P10 interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Behave as P9 for now until we know more on P10. Interface should be the same, apart from the size of the ESB pages. Signed-off-by: Cédric Le Goater [Fixed suprious interrupt issue - Vasant] Signed-off-by: Vasant Hegde --- hw/psi.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- include/psi.h | 7 +++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/hw/psi.c b/hw/psi.c index 545a816..f95a066 100644 --- a/hw/psi.c +++ b/hw/psi.c @@ -266,7 +266,10 @@ static void psi_spurious_fsp_irq(struct psi *psi) prlog(PR_NOTICE, "PSI: Spurious interrupt, attempting clear\n"); - if (proc_gen == proc_gen_p9) { + if (proc_gen == proc_gen_p10) { + reg = PSIHB_XSCOM_P10_HBCSR_CLR; + bit = PSIHB_XSCOM_P10_HBSCR_FSP_IRQ; + } else if (proc_gen == proc_gen_p9) { reg = PSIHB_XSCOM_P9_HBCSR_CLR; bit = PSIHB_XSCOM_P9_HBSCR_FSP_IRQ; } else if (proc_gen == proc_gen_p8) { @@ -737,6 +740,61 @@ static void psi_init_p9_interrupts(struct psi *psi) out_be64(psi->regs + PSIHB_INTERRUPT_CONTROL, 0); } +/* + * P9 and P10 have the same PSIHB interface + */ +static const struct irq_source_ops psi_p10_irq_ops = { + .interrupt = psihb_p9_interrupt, + .attributes = psi_p9_irq_attributes, + .name = psi_p9_irq_name, +}; + +static void psi_init_p10_interrupts(struct psi *psi) +{ + struct proc_chip *chip; + u64 val; + /* TODO (clg) : fix ESB page size to 64k when ready */ + uint32_t esb_shift = 12; + + /* Grab chip */ + chip = get_chip(psi->chip_id); + if (!chip) + return; + + /* Configure the CI BAR */ + phys_map_get(chip->id, PSIHB_ESB, 0, &val, NULL); + val |= PSIHB_ESB_CI_VALID; + out_be64(psi->regs + PSIHB_ESB_CI_BASE, val); + + val = in_be64(psi->regs + PSIHB_ESB_CI_BASE); + psi->esb_mmio = (void *)(val & ~PSIHB_ESB_CI_VALID); + prlog(PR_DEBUG, "PSI[0x%03x]: ESB MMIO at @%p\n", + psi->chip_id, psi->esb_mmio); + + /* Grab and configure the notification port */ + val = xive_get_notify_port(psi->chip_id, XIVE_HW_SRC_PSI); + val |= PSIHB_ESB_NOTIF_VALID; + out_be64(psi->regs + PSIHB_ESB_NOTIF_ADDR, val); + + /* Setup interrupt offset */ + val = xive_get_notify_base(psi->interrupt); + val <<= 32; + out_be64(psi->regs + PSIHB_IVT_OFFSET, val); + + /* Register sources */ + prlog(PR_DEBUG, + "PSI[0x%03x]: Interrupts sources registered for P10 DD%i.%i\n", + psi->chip_id, 0xf & (chip->ec_level >> 4), chip->ec_level & 0xf); + + xive_register_hw_source(psi->interrupt, P9_PSI_NUM_IRQS, + esb_shift, psi->esb_mmio, XIVE_SRC_LSI, + psi, &psi_p10_irq_ops); + + /* Reset irq handling and switch to ESB mode */ + out_be64(psi->regs + PSIHB_INTERRUPT_CONTROL, PSIHB_IRQ_RESET); + out_be64(psi->regs + PSIHB_INTERRUPT_CONTROL, 0); +} + static void psi_init_interrupts(struct psi *psi) { /* Configure the interrupt BUID and mask it */ @@ -747,6 +805,9 @@ static void psi_init_interrupts(struct psi *psi) case proc_gen_p9: psi_init_p9_interrupts(psi); break; + case proc_gen_p10: + psi_init_p10_interrupts(psi); + break; default: /* Unknown: just no interrupts */ prerror("PSI: Unknown interrupt type\n"); @@ -826,6 +887,7 @@ static void psi_create_mm_dtnode(struct psi *psi) "ibm,power8-psi"); break; case proc_gen_p9: + case proc_gen_p10: dt_add_property_strings(np, "compatible", "ibm,psi", "ibm,power9-psi"); psi_create_p9_int_map(psi, np); diff --git a/include/psi.h b/include/psi.h index f7b5927..a7104ef 100644 --- a/include/psi.h +++ b/include/psi.h @@ -116,6 +116,13 @@ #define PSIHB_XSCOM_P9_HBCSR_CLR 0x13 #define PSIHB_XSCOM_P9_HBSCR_FSP_IRQ PPC_BIT(17) +#define PSIHB_XSCOM_P10_BASE 0xa +#define PSIHB_XSCOM_P10_HBBAR_EN PPC_BIT(63) +#define PSIHB_XSCOM_P10_HBCSR 0xe +#define PSIHB_XSCOM_P10_HBCSR_SET 0x12 +#define PSIHB_XSCOM_P10_HBCSR_CLR 0x13 +#define PSIHB_XSCOM_P10_HBSCR_FSP_IRQ PPC_BIT(17) + /* P9 PSI Interrupts */ #define P9_PSI_IRQ_PSI 0 #define P9_PSI_IRQ_OCC 1 -- cgit v1.1