aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Miles <milesg@linux.vnet.ibm.com>2023-10-17 17:14:34 -0500
committerDaniel Henrique Barboza <danielhb413@gmail.com>2023-11-07 15:49:41 -0300
commit1ceda19c28a11cf51ca5f670c50934c66b7785bd (patch)
tree45540e4875d926dc4ee512c0debb87fe326fceb8
parent5f0661215454959e98f69e7d3933e793d884282d (diff)
ppc/pnv: Connect PNV I2C controller to powernv10
Wires up four I2C controller instances to the powernv10 chip XSCOM address space. Each controller instance is wired up to two I2C buses of its own. No other I2C devices are connected to the buses at this time. Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com> Reviewed-by: Cédric Le Goater <clg@kaod.org> Message-ID: <20231017221434.810363-1-milesg@linux.vnet.ibm.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
-rw-r--r--hw/ppc/pnv.c29
-rw-r--r--include/hw/ppc/pnv_chip.h4
-rw-r--r--include/hw/ppc/pnv_xscom.h3
3 files changed, 36 insertions, 0 deletions
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index bb4d00e266..ae8e0b45cd 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1684,6 +1684,10 @@ static void pnv_chip_power10_instance_init(Object *obj)
object_initialize_child(obj, "pec[*]", &chip10->pecs[i],
TYPE_PNV_PHB5_PEC);
}
+
+ for (i = 0; i < pcc->i2c_num_engines; i++) {
+ object_initialize_child(obj, "i2c[*]", &chip10->i2c[i], TYPE_PNV_I2C);
+ }
}
static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp)
@@ -1742,6 +1746,7 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
PnvChip *chip = PNV_CHIP(dev);
Pnv10Chip *chip10 = PNV10_CHIP(dev);
Error *local_err = NULL;
+ int i;
/* XSCOM bridge is first */
pnv_xscom_init(chip, PNV10_XSCOM_SIZE, PNV10_XSCOM_BASE(chip));
@@ -1847,6 +1852,28 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
error_propagate(errp, local_err);
return;
}
+
+
+ /*
+ * I2C
+ */
+ for (i = 0; i < pcc->i2c_num_engines; i++) {
+ Object *obj = OBJECT(&chip10->i2c[i]);
+
+ object_property_set_int(obj, "engine", i + 1, &error_fatal);
+ object_property_set_int(obj, "num-busses", pcc->i2c_num_ports,
+ &error_fatal);
+ object_property_set_link(obj, "chip", OBJECT(chip), &error_abort);
+ if (!qdev_realize(DEVICE(obj), NULL, errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV10_XSCOM_I2CM_BASE +
+ chip10->i2c[i].engine * PNV10_XSCOM_I2CM_SIZE,
+ &chip10->i2c[i].xscom_regs);
+ qdev_connect_gpio_out(DEVICE(&chip10->i2c[i]), 0,
+ qdev_get_gpio_in(DEVICE(&chip10->psi),
+ PSIHB9_IRQ_SBE_I2C));
+ }
}
static uint32_t pnv_chip_power10_xscom_pcba(PnvChip *chip, uint64_t addr)
@@ -1874,6 +1901,8 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
k->xscom_pcba = pnv_chip_power10_xscom_pcba;
dc->desc = "PowerNV Chip POWER10";
k->num_pecs = PNV10_CHIP_MAX_PEC;
+ k->i2c_num_engines = PNV10_CHIP_MAX_I2C;
+ k->i2c_num_ports = PNV10_CHIP_MAX_I2C_PORTS;
device_class_set_parent_realize(dc, pnv_chip_power10_realize,
&k->parent_realize);
diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index 90cfbad1a5..5815d96ecf 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -120,6 +120,10 @@ struct Pnv10Chip {
#define PNV10_CHIP_MAX_PEC 2
PnvPhb4PecState pecs[PNV10_CHIP_MAX_PEC];
+
+#define PNV10_CHIP_MAX_I2C 4
+#define PNV10_CHIP_MAX_I2C_PORTS 2
+ PnvI2C i2c[PNV10_CHIP_MAX_I2C];
};
#define PNV10_PIR2FUSEDCORE(pir) (((pir) >> 3) & 0xf)
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 056392ab60..f5becbab41 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -152,6 +152,9 @@ struct PnvXScomInterfaceClass {
#define PNV10_XSCOM_PSIHB_BASE 0x3011D00
#define PNV10_XSCOM_PSIHB_SIZE 0x100
+#define PNV10_XSCOM_I2CM_BASE PNV9_XSCOM_I2CM_BASE
+#define PNV10_XSCOM_I2CM_SIZE PNV9_XSCOM_I2CM_SIZE
+
#define PNV10_XSCOM_OCC_BASE PNV9_XSCOM_OCC_BASE
#define PNV10_XSCOM_OCC_SIZE PNV9_XSCOM_OCC_SIZE