Message ID | 20231025152714.956664-1-milesg@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
Series | [v3] ppc/pnv: Fix number of I2C engines and ports for power9/10 | expand |
Queued in gitlab.com/danielhb/qemu/tree/ppc-next. Thanks, Daniel On 10/25/23 12:27, Glenn Miles wrote: > Power9 is supposed to have 4 PIB-connected I2C engines with the > following number of ports on each engine: > > 0: 2 > 1: 13 > 2: 2 > 3: 2 > > Power10 also has 4 engines but has the following number of ports > on each engine: > > 0: 14 > 1: 14 > 2: 2 > 3: 16 > > Current code assumes that they all have the same (maximum) number. > This can be a problem if software expects to see a certain number > of ports present (Power Hypervisor seems to care). > > Fixed this by adding separate tables for power9 and power10 that > map the I2C controller number to the number of I2C buses that should > be attached for that engine. > > Reviewed-by: Cédric Le Goater <clg@kaod.org> > Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com> > --- > Based-on: <20231017221434.810363-1-milesg@linux.vnet.ibm.com> > ([PATCH] ppc/pnv: Connect PNV I2C controller to powernv10) > > Changes from v2: > - Moved I2C port definitions close to the class definitions > - Changed I2C port array type to const > > hw/ppc/pnv.c | 12 ++++++++---- > include/hw/ppc/pnv_chip.h | 6 ++---- > 2 files changed, 10 insertions(+), 8 deletions(-) > > diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c > index 2655b6e506..1a728b92a0 100644 > --- a/hw/ppc/pnv.c > +++ b/hw/ppc/pnv.c > @@ -1626,7 +1626,8 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp) > Object *obj = OBJECT(&chip9->i2c[i]); > > object_property_set_int(obj, "engine", i + 1, &error_fatal); > - object_property_set_int(obj, "num-busses", pcc->i2c_num_ports, > + object_property_set_int(obj, "num-busses", > + pcc->i2c_ports_per_engine[i], > &error_fatal); > object_property_set_link(obj, "chip", OBJECT(chip), &error_abort); > if (!qdev_realize(DEVICE(obj), NULL, errp)) { > @@ -1651,6 +1652,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) > { > DeviceClass *dc = DEVICE_CLASS(klass); > PnvChipClass *k = PNV_CHIP_CLASS(klass); > + static const int i2c_ports_per_engine[PNV9_CHIP_MAX_I2C] = {2, 13, 2, 2}; > > k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */ > k->cores_mask = POWER9_CORE_MASK; > @@ -1667,7 +1669,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) > dc->desc = "PowerNV Chip POWER9"; > k->num_pecs = PNV9_CHIP_MAX_PEC; > k->i2c_num_engines = PNV9_CHIP_MAX_I2C; > - k->i2c_num_ports = PNV9_CHIP_MAX_I2C_PORTS; > + k->i2c_ports_per_engine = i2c_ports_per_engine; > > device_class_set_parent_realize(dc, pnv_chip_power9_realize, > &k->parent_realize); > @@ -1877,7 +1879,8 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp) > 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, > + object_property_set_int(obj, "num-busses", > + pcc->i2c_ports_per_engine[i], > &error_fatal); > object_property_set_link(obj, "chip", OBJECT(chip), &error_abort); > if (!qdev_realize(DEVICE(obj), NULL, errp)) { > @@ -1902,6 +1905,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data) > { > DeviceClass *dc = DEVICE_CLASS(klass); > PnvChipClass *k = PNV_CHIP_CLASS(klass); > + static const int i2c_ports_per_engine[PNV10_CHIP_MAX_I2C] = {14, 14, 2, 16}; > > k->chip_cfam_id = 0x120da04900008000ull; /* P10 DD1.0 (with NX) */ > k->cores_mask = POWER10_CORE_MASK; > @@ -1918,7 +1922,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data) > 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; > + k->i2c_ports_per_engine = i2c_ports_per_engine; > > 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 5815d96ecf..0ab5c42308 100644 > --- a/include/hw/ppc/pnv_chip.h > +++ b/include/hw/ppc/pnv_chip.h > @@ -88,8 +88,7 @@ struct Pnv9Chip { > #define PNV9_CHIP_MAX_PEC 3 > PnvPhb4PecState pecs[PNV9_CHIP_MAX_PEC]; > > -#define PNV9_CHIP_MAX_I2C 3 > -#define PNV9_CHIP_MAX_I2C_PORTS 1 > +#define PNV9_CHIP_MAX_I2C 4 > PnvI2C i2c[PNV9_CHIP_MAX_I2C]; > }; > > @@ -122,7 +121,6 @@ struct Pnv10Chip { > 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]; > }; > > @@ -140,7 +138,7 @@ struct PnvChipClass { > uint32_t num_phbs; > > uint32_t i2c_num_engines; > - uint32_t i2c_num_ports; > + const int *i2c_ports_per_engine; > > DeviceRealize parent_realize; >
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 2655b6e506..1a728b92a0 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1626,7 +1626,8 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp) Object *obj = OBJECT(&chip9->i2c[i]); object_property_set_int(obj, "engine", i + 1, &error_fatal); - object_property_set_int(obj, "num-busses", pcc->i2c_num_ports, + object_property_set_int(obj, "num-busses", + pcc->i2c_ports_per_engine[i], &error_fatal); object_property_set_link(obj, "chip", OBJECT(chip), &error_abort); if (!qdev_realize(DEVICE(obj), NULL, errp)) { @@ -1651,6 +1652,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvChipClass *k = PNV_CHIP_CLASS(klass); + static const int i2c_ports_per_engine[PNV9_CHIP_MAX_I2C] = {2, 13, 2, 2}; k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */ k->cores_mask = POWER9_CORE_MASK; @@ -1667,7 +1669,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) dc->desc = "PowerNV Chip POWER9"; k->num_pecs = PNV9_CHIP_MAX_PEC; k->i2c_num_engines = PNV9_CHIP_MAX_I2C; - k->i2c_num_ports = PNV9_CHIP_MAX_I2C_PORTS; + k->i2c_ports_per_engine = i2c_ports_per_engine; device_class_set_parent_realize(dc, pnv_chip_power9_realize, &k->parent_realize); @@ -1877,7 +1879,8 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp) 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, + object_property_set_int(obj, "num-busses", + pcc->i2c_ports_per_engine[i], &error_fatal); object_property_set_link(obj, "chip", OBJECT(chip), &error_abort); if (!qdev_realize(DEVICE(obj), NULL, errp)) { @@ -1902,6 +1905,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvChipClass *k = PNV_CHIP_CLASS(klass); + static const int i2c_ports_per_engine[PNV10_CHIP_MAX_I2C] = {14, 14, 2, 16}; k->chip_cfam_id = 0x120da04900008000ull; /* P10 DD1.0 (with NX) */ k->cores_mask = POWER10_CORE_MASK; @@ -1918,7 +1922,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data) 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; + k->i2c_ports_per_engine = i2c_ports_per_engine; 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 5815d96ecf..0ab5c42308 100644 --- a/include/hw/ppc/pnv_chip.h +++ b/include/hw/ppc/pnv_chip.h @@ -88,8 +88,7 @@ struct Pnv9Chip { #define PNV9_CHIP_MAX_PEC 3 PnvPhb4PecState pecs[PNV9_CHIP_MAX_PEC]; -#define PNV9_CHIP_MAX_I2C 3 -#define PNV9_CHIP_MAX_I2C_PORTS 1 +#define PNV9_CHIP_MAX_I2C 4 PnvI2C i2c[PNV9_CHIP_MAX_I2C]; }; @@ -122,7 +121,6 @@ struct Pnv10Chip { 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]; }; @@ -140,7 +138,7 @@ struct PnvChipClass { uint32_t num_phbs; uint32_t i2c_num_engines; - uint32_t i2c_num_ports; + const int *i2c_ports_per_engine; DeviceRealize parent_realize;