[PATCH v2 10/18] hw/arm/fsl-imx8mp: Add I2C controllers

2025-02-23 Thread Bernhard Beschow
Reviewed-by: Peter Maydell 
Signed-off-by: Bernhard Beschow 
---
 docs/system/arm/imx8mp-evk.rst |  1 +
 include/hw/arm/fsl-imx8mp.h| 11 +++
 hw/arm/fsl-imx8mp.c| 29 +
 hw/arm/Kconfig |  2 ++
 4 files changed, 43 insertions(+)

diff --git a/docs/system/arm/imx8mp-evk.rst b/docs/system/arm/imx8mp-evk.rst
index 37d3630d09..ef0d997250 100644
--- a/docs/system/arm/imx8mp-evk.rst
+++ b/docs/system/arm/imx8mp-evk.rst
@@ -15,6 +15,7 @@ The ``imx8mp-evk`` machine implements the following devices:
  * 3 USDHC Storage Controllers
  * 1 Designware PCI Express Controller
  * 5 GPIO Controllers
+ * 6 I2C Controllers
  * Secure Non-Volatile Storage (SNVS) including an RTC
  * Clock Tree
 
diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h
index 18ea52d083..2590056627 100644
--- a/include/hw/arm/fsl-imx8mp.h
+++ b/include/hw/arm/fsl-imx8mp.h
@@ -12,6 +12,7 @@
 #include "cpu.h"
 #include "hw/char/imx_serial.h"
 #include "hw/gpio/imx_gpio.h"
+#include "hw/i2c/imx_i2c.h"
 #include "hw/intc/arm_gicv3_common.h"
 #include "hw/misc/imx7_snvs.h"
 #include "hw/misc/imx8mp_analog.h"
@@ -31,6 +32,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP)
 enum FslImx8mpConfiguration {
 FSL_IMX8MP_NUM_CPUS = 4,
 FSL_IMX8MP_NUM_GPIOS= 5,
+FSL_IMX8MP_NUM_I2CS = 6,
 FSL_IMX8MP_NUM_IRQS = 160,
 FSL_IMX8MP_NUM_UARTS= 4,
 FSL_IMX8MP_NUM_USDHCS   = 3,
@@ -45,6 +47,7 @@ struct FslImx8mpState {
 IMX8MPCCMState ccm;
 IMX8MPAnalogState  analog;
 IMX7SNVSState  snvs;
+IMXI2CStatei2c[FSL_IMX8MP_NUM_I2CS];
 IMXSerialState uart[FSL_IMX8MP_NUM_UARTS];
 SDHCIState usdhc[FSL_IMX8MP_NUM_USDHCS];
 DesignwarePCIEHost pcie;
@@ -205,6 +208,11 @@ enum FslImx8mpIrqs {
 FSL_IMX8MP_UART5_IRQ= 30,
 FSL_IMX8MP_UART6_IRQ= 16,
 
+FSL_IMX8MP_I2C1_IRQ = 35,
+FSL_IMX8MP_I2C2_IRQ = 36,
+FSL_IMX8MP_I2C3_IRQ = 37,
+FSL_IMX8MP_I2C4_IRQ = 38,
+
 FSL_IMX8MP_GPIO1_LOW_IRQ  = 64,
 FSL_IMX8MP_GPIO1_HIGH_IRQ = 65,
 FSL_IMX8MP_GPIO2_LOW_IRQ  = 66,
@@ -216,6 +224,9 @@ enum FslImx8mpIrqs {
 FSL_IMX8MP_GPIO5_LOW_IRQ  = 72,
 FSL_IMX8MP_GPIO5_HIGH_IRQ = 73,
 
+FSL_IMX8MP_I2C5_IRQ = 76,
+FSL_IMX8MP_I2C6_IRQ = 77,
+
 FSL_IMX8MP_PCI_INTA_IRQ = 126,
 FSL_IMX8MP_PCI_INTB_IRQ = 125,
 FSL_IMX8MP_PCI_INTC_IRQ = 124,
diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c
index 456fa47dc7..3da81e28ca 100644
--- a/hw/arm/fsl-imx8mp.c
+++ b/hw/arm/fsl-imx8mp.c
@@ -208,6 +208,11 @@ static void fsl_imx8mp_init(Object *obj)
 object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
 }
 
+for (i = 0; i < FSL_IMX8MP_NUM_I2CS; i++) {
+g_autofree char *name = g_strdup_printf("i2c%d", i + 1);
+object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
+}
+
 for (i = 0; i < FSL_IMX8MP_NUM_GPIOS; i++) {
 g_autofree char *name = g_strdup_printf("gpio%d", i + 1);
 object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
@@ -360,6 +365,29 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error 
**errp)
qdev_get_gpio_in(gicdev, serial_table[i].irq));
 }
 
+/* I2Cs */
+for (i = 0; i < FSL_IMX8MP_NUM_I2CS; i++) {
+static const struct {
+hwaddr addr;
+unsigned int irq;
+} i2c_table[FSL_IMX8MP_NUM_I2CS] = {
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C1].addr, FSL_IMX8MP_I2C1_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C2].addr, FSL_IMX8MP_I2C2_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C3].addr, FSL_IMX8MP_I2C3_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C4].addr, FSL_IMX8MP_I2C4_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C5].addr, FSL_IMX8MP_I2C5_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C6].addr, FSL_IMX8MP_I2C6_IRQ },
+};
+
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), errp)) {
+return;
+}
+
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
+   qdev_get_gpio_in(gicdev, i2c_table[i].irq));
+}
+
 /* GPIOs */
 for (i = 0; i < FSL_IMX8MP_NUM_GPIOS; i++) {
 static const struct {
@@ -470,6 +498,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error 
**errp)
 case FSL_IMX8MP_GIC_DIST:
 case FSL_IMX8MP_GIC_REDIST:
 case FSL_IMX8MP_GPIO1 ... FSL_IMX8MP_GPIO5:
+case FSL_IMX8MP_I2C1 ... FSL_IMX8MP_I2C6:
 case FSL_IMX8MP_PCIE1:
 case FSL_IMX8MP_PCIE_PHY1:
 case FSL_IMX8MP_RAM:
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index be5a2c02b7..28ae409c85 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -595,11 +595,13 @@ config FSL_IMX7
 
 config FSL_IMX8MP
 bool
+imply I2C_DEVICES

Re: [PATCH v2 10/18] hw/arm/fsl-imx8mp: Add I2C controllers

2025-02-06 Thread Peter Maydell
On Tue, 4 Feb 2025 at 09:21, Bernhard Beschow  wrote:
>
> Signed-off-by: Bernhard Beschow 
> ---
>  docs/system/arm/imx8mp-evk.rst |  1 +
>  include/hw/arm/fsl-imx8mp.h| 11 +++
>  hw/arm/fsl-imx8mp.c| 29 +
>  hw/arm/Kconfig |  2 ++
>  4 files changed, 43 insertions(+)

Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH v2 10/18] hw/arm/fsl-imx8mp: Add I2C controllers

2025-02-04 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 docs/system/arm/imx8mp-evk.rst |  1 +
 include/hw/arm/fsl-imx8mp.h| 11 +++
 hw/arm/fsl-imx8mp.c| 29 +
 hw/arm/Kconfig |  2 ++
 4 files changed, 43 insertions(+)

diff --git a/docs/system/arm/imx8mp-evk.rst b/docs/system/arm/imx8mp-evk.rst
index a89aad6f92..e63c5b7118 100644
--- a/docs/system/arm/imx8mp-evk.rst
+++ b/docs/system/arm/imx8mp-evk.rst
@@ -16,6 +16,7 @@ The ``imx8mp-evk`` machine implements the following devices:
  * 3 USDHC Storage Controllers
  * 1 Designware PCI Express Controller
  * 5 GPIO Controllers
+ * 6 I2C Controllers
  * Secure Non-Volatile Storage (SNVS) including an RTC
  * Clock Tree
 
diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h
index 18ea52d083..2590056627 100644
--- a/include/hw/arm/fsl-imx8mp.h
+++ b/include/hw/arm/fsl-imx8mp.h
@@ -12,6 +12,7 @@
 #include "cpu.h"
 #include "hw/char/imx_serial.h"
 #include "hw/gpio/imx_gpio.h"
+#include "hw/i2c/imx_i2c.h"
 #include "hw/intc/arm_gicv3_common.h"
 #include "hw/misc/imx7_snvs.h"
 #include "hw/misc/imx8mp_analog.h"
@@ -31,6 +32,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP)
 enum FslImx8mpConfiguration {
 FSL_IMX8MP_NUM_CPUS = 4,
 FSL_IMX8MP_NUM_GPIOS= 5,
+FSL_IMX8MP_NUM_I2CS = 6,
 FSL_IMX8MP_NUM_IRQS = 160,
 FSL_IMX8MP_NUM_UARTS= 4,
 FSL_IMX8MP_NUM_USDHCS   = 3,
@@ -45,6 +47,7 @@ struct FslImx8mpState {
 IMX8MPCCMState ccm;
 IMX8MPAnalogState  analog;
 IMX7SNVSState  snvs;
+IMXI2CStatei2c[FSL_IMX8MP_NUM_I2CS];
 IMXSerialState uart[FSL_IMX8MP_NUM_UARTS];
 SDHCIState usdhc[FSL_IMX8MP_NUM_USDHCS];
 DesignwarePCIEHost pcie;
@@ -205,6 +208,11 @@ enum FslImx8mpIrqs {
 FSL_IMX8MP_UART5_IRQ= 30,
 FSL_IMX8MP_UART6_IRQ= 16,
 
+FSL_IMX8MP_I2C1_IRQ = 35,
+FSL_IMX8MP_I2C2_IRQ = 36,
+FSL_IMX8MP_I2C3_IRQ = 37,
+FSL_IMX8MP_I2C4_IRQ = 38,
+
 FSL_IMX8MP_GPIO1_LOW_IRQ  = 64,
 FSL_IMX8MP_GPIO1_HIGH_IRQ = 65,
 FSL_IMX8MP_GPIO2_LOW_IRQ  = 66,
@@ -216,6 +224,9 @@ enum FslImx8mpIrqs {
 FSL_IMX8MP_GPIO5_LOW_IRQ  = 72,
 FSL_IMX8MP_GPIO5_HIGH_IRQ = 73,
 
+FSL_IMX8MP_I2C5_IRQ = 76,
+FSL_IMX8MP_I2C6_IRQ = 77,
+
 FSL_IMX8MP_PCI_INTA_IRQ = 126,
 FSL_IMX8MP_PCI_INTB_IRQ = 125,
 FSL_IMX8MP_PCI_INTC_IRQ = 124,
diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c
index 13910dc44a..1971c76aaa 100644
--- a/hw/arm/fsl-imx8mp.c
+++ b/hw/arm/fsl-imx8mp.c
@@ -211,6 +211,11 @@ static void fsl_imx8mp_init(Object *obj)
 object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
 }
 
+for (i = 0; i < FSL_IMX8MP_NUM_I2CS; i++) {
+snprintf(name, NAME_SIZE, "i2c%d", i + 1);
+object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
+}
+
 for (i = 0; i < FSL_IMX8MP_NUM_GPIOS; i++) {
 snprintf(name, NAME_SIZE, "gpio%d", i + 1);
 object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
@@ -364,6 +369,29 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error 
**errp)
qdev_get_gpio_in(gicdev, serial_table[i].irq));
 }
 
+/* I2Cs */
+for (i = 0; i < FSL_IMX8MP_NUM_I2CS; i++) {
+static const struct {
+hwaddr addr;
+unsigned int irq;
+} i2c_table[FSL_IMX8MP_NUM_I2CS] = {
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C1].addr, FSL_IMX8MP_I2C1_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C2].addr, FSL_IMX8MP_I2C2_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C3].addr, FSL_IMX8MP_I2C3_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C4].addr, FSL_IMX8MP_I2C4_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C5].addr, FSL_IMX8MP_I2C5_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_I2C6].addr, FSL_IMX8MP_I2C6_IRQ },
+};
+
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), errp)) {
+return;
+}
+
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
+   qdev_get_gpio_in(gicdev, i2c_table[i].irq));
+}
+
 /* GPIOs */
 for (i = 0; i < FSL_IMX8MP_NUM_GPIOS; i++) {
 static const struct {
@@ -474,6 +502,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error 
**errp)
 case FSL_IMX8MP_GIC_DIST:
 case FSL_IMX8MP_GIC_REDIST:
 case FSL_IMX8MP_GPIO1 ... FSL_IMX8MP_GPIO5:
+case FSL_IMX8MP_I2C1 ... FSL_IMX8MP_I2C6:
 case FSL_IMX8MP_PCIE1:
 case FSL_IMX8MP_PCIE_PHY1:
 case FSL_IMX8MP_RAM:
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index f1e140a29d..4a8695f22a 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -579,11 +579,13 @@ config FSL_IMX7
 
 config FSL_IMX8MP
 bool
+imply I2C_DEVICES
 imply PCI_DEVICES
 select ARM_GIC
 select F