[PATCH] ppc/pnv: Connect PNV I2C controller to powernv10

Glenn Miles posted 1 patch 1 year, 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20231017221434.810363-1-milesg@linux.vnet.ibm.com
Maintainers: "Cédric Le Goater" <clg@kaod.org>, Nicholas Piggin <npiggin@gmail.com>, "Frédéric Barrat" <fbarrat@linux.ibm.com>
hw/ppc/pnv.c               | 29 +++++++++++++++++++++++++++++
include/hw/ppc/pnv_chip.h  |  4 ++++
include/hw/ppc/pnv_xscom.h |  3 +++
3 files changed, 36 insertions(+)
[PATCH] ppc/pnv: Connect PNV I2C controller to powernv10
Posted by Glenn Miles 1 year, 1 month ago
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>
---
Based-on: <20231016222013.3739530-1-milesg@linux.vnet.ibm.com>
([PATCH v3 0/2] Add PowerNV I2C Controller Model)

 hw/ppc/pnv.c               | 29 +++++++++++++++++++++++++++++
 include/hw/ppc/pnv_chip.h  |  4 ++++
 include/hw/ppc/pnv_xscom.h |  3 +++
 3 files changed, 36 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index e0b3478325..2655b6e506 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1695,6 +1695,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)
@@ -1753,6 +1757,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_realize(chip, PNV10_XSCOM_SIZE, &local_err);
@@ -1863,6 +1868,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)
@@ -1890,6 +1917,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 0c8b873c4c..2b607b22c9 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
 
-- 
2.31.1
Re: [PATCH] ppc/pnv: Connect PNV I2C controller to powernv10
Posted by Daniel Henrique Barboza 1 year ago
Queued in gitlab.com/danielhb/qemu/tree/ppc-next. Thanks,


Daniel

On 10/17/23 19:14, Glenn Miles wrote:
> 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>
> ---
> Based-on: <20231016222013.3739530-1-milesg@linux.vnet.ibm.com>
> ([PATCH v3 0/2] Add PowerNV I2C Controller Model)
> 
>   hw/ppc/pnv.c               | 29 +++++++++++++++++++++++++++++
>   include/hw/ppc/pnv_chip.h  |  4 ++++
>   include/hw/ppc/pnv_xscom.h |  3 +++
>   3 files changed, 36 insertions(+)
> 
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index e0b3478325..2655b6e506 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -1695,6 +1695,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)
> @@ -1753,6 +1757,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_realize(chip, PNV10_XSCOM_SIZE, &local_err);
> @@ -1863,6 +1868,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)
> @@ -1890,6 +1917,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 0c8b873c4c..2b607b22c9 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
>
Re: [PATCH] ppc/pnv: Connect PNV I2C controller to powernv10
Posted by Cédric Le Goater 1 year, 1 month ago
On 10/18/23 00:14, Glenn Miles wrote:
> 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>
> ---
> Based-on: <20231016222013.3739530-1-milesg@linux.vnet.ibm.com>
> ([PATCH v3 0/2] Add PowerNV I2C Controller Model)


Reviewed-by: Cédric Le Goater <clg@kaod.org>

Thanks,

C.


> 
>   hw/ppc/pnv.c               | 29 +++++++++++++++++++++++++++++
>   include/hw/ppc/pnv_chip.h  |  4 ++++
>   include/hw/ppc/pnv_xscom.h |  3 +++
>   3 files changed, 36 insertions(+)
> 
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index e0b3478325..2655b6e506 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -1695,6 +1695,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)
> @@ -1753,6 +1757,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_realize(chip, PNV10_XSCOM_SIZE, &local_err);
> @@ -1863,6 +1868,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)
> @@ -1890,6 +1917,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 0c8b873c4c..2b607b22c9 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
>