Skip to content

Commit

Permalink
ppc/pnv: Remove PnvLpcController::psi link
Browse files Browse the repository at this point in the history
Create an anonymous output GPIO line to connect the LPC device with
the PSIHB device and raise the appropriate PSI IRQ line depending on
the processor model.

A temporary __pnv_psi_irq_set() routine is introduced to handle the
transition. It will be removed when all devices raising PSI interrupts
are converted to use GPIOs.

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20220323072846.1780212-3-clg@kaod.org>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
  • Loading branch information
legoater authored and danielhb committed Apr 20, 2022
1 parent 5885875 commit c05aa14
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 27 deletions.
18 changes: 12 additions & 6 deletions hw/ppc/pnv.c
Expand Up @@ -614,24 +614,36 @@ static void pnv_reset(MachineState *machine)
static ISABus *pnv_chip_power8_isa_create(PnvChip *chip, Error **errp)
{
Pnv8Chip *chip8 = PNV8_CHIP(chip);
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_EXTERNAL);

qdev_connect_gpio_out(DEVICE(&chip8->lpc), 0, irq);
return pnv_lpc_isa_create(&chip8->lpc, true, errp);
}

static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp)
{
Pnv8Chip *chip8 = PNV8_CHIP(chip);
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_LPC_I2C);

qdev_connect_gpio_out(DEVICE(&chip8->lpc), 0, irq);
return pnv_lpc_isa_create(&chip8->lpc, false, errp);
}

static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
{
Pnv9Chip *chip9 = PNV9_CHIP(chip);
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip9->psi), PSIHB9_IRQ_LPCHC);

qdev_connect_gpio_out(DEVICE(&chip9->lpc), 0, irq);
return pnv_lpc_isa_create(&chip9->lpc, false, errp);
}

static ISABus *pnv_chip_power10_isa_create(PnvChip *chip, Error **errp)
{
Pnv10Chip *chip10 = PNV10_CHIP(chip);
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip10->psi), PSIHB9_IRQ_LPCHC);

qdev_connect_gpio_out(DEVICE(&chip10->lpc), 0, irq);
return pnv_lpc_isa_create(&chip10->lpc, false, errp);
}

Expand Down Expand Up @@ -1222,8 +1234,6 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
&PNV_PSI(psi8)->xscom_regs);

/* Create LPC controller */
object_property_set_link(OBJECT(&chip8->lpc), "psi", OBJECT(&chip8->psi),
&error_abort);
qdev_realize(DEVICE(&chip8->lpc), NULL, &error_fatal);
pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);

Expand Down Expand Up @@ -1507,8 +1517,6 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
&PNV_PSI(psi9)->xscom_regs);

/* LPC */
object_property_set_link(OBJECT(&chip9->lpc), "psi", OBJECT(&chip9->psi),
&error_abort);
if (!qdev_realize(DEVICE(&chip9->lpc), NULL, errp)) {
return;
}
Expand Down Expand Up @@ -1712,8 +1720,6 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
&PNV_PSI(&chip10->psi)->xscom_regs);

/* LPC */
object_property_set_link(OBJECT(&chip10->lpc), "psi",
OBJECT(&chip10->psi), &error_abort);
if (!qdev_realize(DEVICE(&chip10->lpc), NULL, errp)) {
return;
}
Expand Down
19 changes: 4 additions & 15 deletions hw/ppc/pnv_lpc.c
Expand Up @@ -422,7 +422,6 @@ static const MemoryRegionOps pnv_lpc_mmio_ops = {
static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
{
bool lpc_to_opb_irq = false;
PnvLpcClass *plc = PNV_LPC_GET_CLASS(lpc);

/* Update LPC controller to OPB line */
if (lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN) {
Expand All @@ -445,7 +444,7 @@ static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask;

/* Reflect the interrupt */
pnv_psi_irq_set(lpc->psi, plc->psi_irq, lpc->opb_irq_stat != 0);
qemu_set_irq(lpc->psi_irq, lpc->opb_irq_stat != 0);
}

static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size)
Expand Down Expand Up @@ -637,8 +636,6 @@ static void pnv_lpc_power8_class_init(ObjectClass *klass, void *data)

xdc->dt_xscom = pnv_lpc_dt_xscom;

plc->psi_irq = PSIHB_IRQ_LPC_I2C;

device_class_set_parent_realize(dc, pnv_lpc_power8_realize,
&plc->parent_realize);
}
Expand Down Expand Up @@ -677,8 +674,6 @@ static void pnv_lpc_power9_class_init(ObjectClass *klass, void *data)

dc->desc = "PowerNV LPC Controller POWER9";

plc->psi_irq = PSIHB9_IRQ_LPCHC;

device_class_set_parent_realize(dc, pnv_lpc_power9_realize,
&plc->parent_realize);
}
Expand Down Expand Up @@ -706,8 +701,6 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
{
PnvLpcController *lpc = PNV_LPC(dev);

assert(lpc->psi);

/* Reg inits */
lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;

Expand Down Expand Up @@ -746,20 +739,16 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
"lpc-hc", LPC_HC_REGS_OPB_SIZE);
memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
&lpc->lpc_hc_regs);
}

static Property pnv_lpc_properties[] = {
DEFINE_PROP_LINK("psi", PnvLpcController, psi, TYPE_PNV_PSI, PnvPsi *),
DEFINE_PROP_END_OF_LIST(),
};
qdev_init_gpio_out(DEVICE(dev), &lpc->psi_irq, 1);
}

static void pnv_lpc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);

dc->realize = pnv_lpc_realize;
dc->desc = "PowerNV LPC Controller";
device_class_set_props(dc, pnv_lpc_properties);
dc->user_creatable = false;
}

Expand Down Expand Up @@ -803,7 +792,7 @@ static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level)
}

if (pnv->cpld_irqstate != old_state) {
pnv_psi_irq_set(lpc->psi, PSIHB_IRQ_EXTERNAL, pnv->cpld_irqstate != 0);
qemu_set_irq(lpc->psi_irq, pnv->cpld_irqstate != 0);
}
}

Expand Down
10 changes: 10 additions & 0 deletions hw/ppc/pnv_psi.c
Expand Up @@ -216,6 +216,12 @@ void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state)
PNV_PSI_GET_CLASS(psi)->irq_set(psi, irq, state);
}

static void __pnv_psi_irq_set(void *opaque, int irq, int state)
{
PnvPsi *psi = (PnvPsi *) opaque;
PNV_PSI_GET_CLASS(psi)->irq_set(psi, irq, state);
}

static void pnv_psi_power8_irq_set(PnvPsi *psi, int irq, bool state)
{
uint32_t xivr_reg;
Expand Down Expand Up @@ -512,6 +518,8 @@ static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
ics_set_irq_type(ics, i, true);
}

qdev_init_gpio_in(dev, __pnv_psi_irq_set, ics->nr_irqs);

psi->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);

/* XSCOM region for PSI registers */
Expand Down Expand Up @@ -873,6 +881,8 @@ static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)

psi->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);

qdev_init_gpio_in(dev, __pnv_psi_irq_set, xsrc->nr_irqs);

/* XSCOM region for PSI registers */
pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_p9_xscom_ops,
psi, "xscom-psi", PNV9_XSCOM_PSIHB_SIZE);
Expand Down
8 changes: 2 additions & 6 deletions include/hw/ppc/pnv_lpc.h
@@ -1,7 +1,7 @@
/*
* QEMU PowerPC PowerNV LPC controller
*
* Copyright (c) 2016, IBM Corporation.
* Copyright (c) 2016-2022, IBM Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand All @@ -20,7 +20,6 @@
#ifndef PPC_PNV_LPC_H
#define PPC_PNV_LPC_H

#include "hw/ppc/pnv_psi.h"
#include "qom/object.h"

#define TYPE_PNV_LPC "pnv-lpc"
Expand Down Expand Up @@ -84,15 +83,12 @@ struct PnvLpcController {
MemoryRegion xscom_regs;

/* PSI to generate interrupts */
PnvPsi *psi;
qemu_irq psi_irq;
};


struct PnvLpcClass {
DeviceClass parent_class;

int psi_irq;

DeviceRealize parent_realize;
};

Expand Down

0 comments on commit c05aa14

Please sign in to comment.