[PATCH v2 0/4] Add ESM driver support for AM64x R5 SPL/U-boot

AM64x devices have a main ESM and a MCU ESM. The ESM driver enables routing of the error events from various sources to different processors or to reset hardware logic. Only the MCU ESM's high output can trigger reset logic. The main RTI0 WWDT output can be routed to the MCU highoutput to trigger reset through the main ESM. For this reset to occur CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RESET_EN_Z is set to '0'.
AM64x Technical Reference Manual - https://www.ti.com/lit/pdf/spruim2
Hari Nagalla (4): misc: k3_esm: Add functionality to set and route error events within K3SoC arm: dts: k3-am64: Add support for ESM device nodes arch: arm: mach-k3: am642_init: Probe ESM nodes configs: am64x_evm_r5_defconfig: Add support for ESM
arch/arm/dts/k3-am64.dtsi | 1 + arch/arm/dts/k3-am642-r5-evm.dts | 19 ++++++++++++ arch/arm/dts/k3-am642-r5-sk.dts | 19 ++++++++++++ arch/arm/mach-k3/am642_init.c | 29 ++++++++++++++--- configs/am64x_evm_r5_defconfig | 1 + drivers/misc/k3_esm.c | 53 ++++++++++++++++++++++++++++++-- 6 files changed, 115 insertions(+), 7 deletions(-)

Add functionality to enable, set priority to the input events and to route to MCU ESM. On AM64x/AM62x devices, it is possible to route Main ESM0 error events to MCU ESM. When these error events are routed to MCU ESM high output, it can trigger the reset logic to reset the device, when CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RESET_EN_Z is set to '0'.
K3 based J7 devices (ex: J721e) also have ESM modules, and the changes to the driver does not impact those devices.
Signed-off-by: Hari Nagalla hnagalla@ti.com --- drivers/misc/k3_esm.c | 53 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/k3_esm.c b/drivers/misc/k3_esm.c index cc2a23dd66..41faeb3d85 100644 --- a/drivers/misc/k3_esm.c +++ b/drivers/misc/k3_esm.c @@ -16,17 +16,57 @@
#define ESM_SFT_RST 0x0c #define ESM_SFT_RST_KEY 0x0f +#define ESM_EN 0x08 +#define ESM_EN_KEY 0x0f
#define ESM_STS(i) (0x404 + (i) / 32 * 0x20) +#define ESM_STS_MASK(i) (1 << ((i) % 32)) #define ESM_PIN_EN_SET_OFFSET(i) (0x414 + (i) / 32 * 0x20) -#define ESM_PIN_MASK(i) BIT((i) & 0x1f) +#define ESM_PIN_MASK(i) (1 << ((i) % 32)) +#define ESM_INTR_EN_SET_OFFSET(i) (0x408 + (i) / 32 * 0x20) +#define ESM_INTR_MASK(i) (1 << ((i) % 32)) +#define ESM_INTR_PRIO_SET_OFFSET(i) (0x410 + (i) / 32 * 0x20) +#define ESM_INTR_PRIO_MASK(i) (1 << ((i) % 32))
static void esm_pin_enable(void __iomem *base, int pin) { + u32 value; + + value = readl(base + ESM_PIN_EN_SET_OFFSET(pin)); + value |= ESM_PIN_MASK(pin); /* Enable event */ - writel(ESM_PIN_MASK(pin), base + ESM_PIN_EN_SET_OFFSET(pin)); + writel(value, base + ESM_PIN_EN_SET_OFFSET(pin)); +} + +static void esm_intr_enable(void __iomem *base, int pin) +{ + u32 value; + + value = readl(base + ESM_INTR_EN_SET_OFFSET(pin)); + value |= ESM_INTR_MASK(pin); + /* Enable Interrupt event */ + writel(value, base + ESM_INTR_EN_SET_OFFSET(pin)); +} + +static void esm_intr_prio_set(void __iomem *base, int pin) +{ + u32 value; + + value = readl(base + ESM_INTR_PRIO_SET_OFFSET(pin)); + value |= ESM_INTR_PRIO_MASK(pin); + /* Set to priority */ + writel(value, base + ESM_INTR_PRIO_SET_OFFSET(pin)); }
+static void esm_clear_raw_status(void __iomem *base, int pin) +{ + u32 value; + + value = readl(base + ESM_STS(pin)); + value |= ESM_STS_MASK(pin); + /* Clear Event status */ + writel(value, base + ESM_STS(pin)); +} /** * k3_esm_probe: configures ESM based on DT data * @@ -67,8 +107,15 @@ static int k3_esm_probe(struct udevice *dev) /* Clear any pending events */ writel(ESM_SFT_RST_KEY, base + ESM_SFT_RST);
- for (i = 0; i < num_pins; i++) + for (i = 0; i < num_pins; i++) { + esm_intr_prio_set(base, pins[i]); + esm_clear_raw_status(base, pins[i]); esm_pin_enable(base, pins[i]); + esm_intr_enable(base, pins[i]); + } + + /* Enable ESM */ + writel(ESM_EN_KEY, base + ESM_EN);
free_pins: kfree(pins);

Am Mo., 28. Feb. 2022 um 05:56 Uhr schrieb Hari Nagalla hnagalla@ti.com:
Add functionality to enable, set priority to the input events and to route to MCU ESM. On AM64x/AM62x devices, it is possible to route Main ESM0 error events to MCU ESM. When these error events are routed to MCU ESM high output, it can trigger the reset logic to reset the device, when CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RESET_EN_Z is set to '0'.
K3 based J7 devices (ex: J721e) also have ESM modules, and the changes to the driver does not impact those devices.
Signed-off-by: Hari Nagalla hnagalla@ti.com
Reviewed-by: Christian Gmeiner christian.gmeiner@gmail.com

Enable access to ESM0 configuration space and add Main ESM0 and MCU ESM nodes to the AM64 device tree.
Signed-off-by: Hari Nagalla hnagalla@ti.com --- arch/arm/dts/k3-am64.dtsi | 1 + arch/arm/dts/k3-am642-r5-evm.dts | 19 +++++++++++++++++++ arch/arm/dts/k3-am642-r5-sk.dts | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+)
diff --git a/arch/arm/dts/k3-am64.dtsi b/arch/arm/dts/k3-am64.dtsi index de6805b0c7..7aa94d5a6e 100644 --- a/arch/arm/dts/k3-am64.dtsi +++ b/arch/arm/dts/k3-am64.dtsi @@ -64,6 +64,7 @@ #address-cells = <2>; #size-cells = <2>; ranges = <0x00 0x000f4000 0x00 0x000f4000 0x00 0x000002d0>, /* PINCTRL */ + <0x00 0x00420000 0x00 0x00420000 0x00 0x00001000>, /* ESM0 */ <0x00 0x00600000 0x00 0x00600000 0x00 0x00001100>, /* GPIO */ <0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* Timesync router */ <0x00 0x01000000 0x00 0x01000000 0x00 0x02330400>, /* First peripheral window */ diff --git a/arch/arm/dts/k3-am642-r5-evm.dts b/arch/arm/dts/k3-am642-r5-evm.dts index cc48fd4cb6..3ea6471e94 100644 --- a/arch/arm/dts/k3-am642-r5-evm.dts +++ b/arch/arm/dts/k3-am642-r5-evm.dts @@ -82,6 +82,25 @@ }; };
+&cbass_main { + main_esm: esm@420000 { + compatible = "ti,j721e-esm"; + reg = <0x0 0x420000 0x0 0x1000>; + ti,esm-pins = <160>, <161>; + u-boot,dm-spl; + }; +}; + +&cbass_mcu { + u-boot,dm-spl; + mcu_esm: esm@4100000 { + compatible = "ti,j721e-esm"; + reg = <0x0 0x4100000 0x0 0x1000>; + ti,esm-pins = <0>, <1>; + u-boot,dm-spl; + }; +}; + &main_pmx0 { u-boot,dm-spl; main_uart0_pins_default: main-uart0-pins-default { diff --git a/arch/arm/dts/k3-am642-r5-sk.dts b/arch/arm/dts/k3-am642-r5-sk.dts index 7d1cb85615..1f96e3fcac 100644 --- a/arch/arm/dts/k3-am642-r5-sk.dts +++ b/arch/arm/dts/k3-am642-r5-sk.dts @@ -75,6 +75,25 @@ }; };
+&cbass_main { + main_esm: esm@420000 { + compatible = "ti,j721e-esm"; + reg = <0x0 0x420000 0x0 0x1000>; + ti,esm-pins = <160>, <161>; + u-boot,dm-spl; + }; +}; + +&cbass_mcu { + u-boot,dm-spl; + mcu_esm: esm@4100000 { + compatible = "ti,j721e-esm"; + reg = <0x0 0x4100000 0x0 0x1000>; + ti,esm-pins = <0>, <1>; + u-boot,dm-spl; + }; +}; + &main_pmx0 { u-boot,dm-spl; main_uart0_pins_default: main-uart0-pins-default {

Am Mo., 28. Feb. 2022 um 05:56 Uhr schrieb Hari Nagalla hnagalla@ti.com:
Enable access to ESM0 configuration space and add Main ESM0 and MCU ESM nodes to the AM64 device tree.
Signed-off-by: Hari Nagalla hnagalla@ti.com
Reviewed-by: Christian Gmeiner christian.gmeiner@gmail.com

On AM64x devices, it is possible to route Main ESM0 error events to MCU ESM. MCU ESM high error output can trigger the reset logic to reset the device. So, for these devices we expect two ESM device nodes in the device tree, one for Main ESM and the another MCU ESM in the device tree. When these ESM device nodes are properly configired it is possible to route the Main RTI0 WWDT output to the MCU ESM high ouput through Main ESM and trigger a device reset when CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RESET_EN_Z is set to '0'.
On K3 AM64x devices, the R5 SPL u-boot handles the ESM device node configurations.
Signed-off-by: Hari Nagalla hnagalla@ti.com --- arch/arm/mach-k3/am642_init.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-k3/am642_init.c b/arch/arm/mach-k3/am642_init.c index 543dea02bc..f171c1e254 100644 --- a/arch/arm/mach-k3/am642_init.c +++ b/arch/arm/mach-k3/am642_init.c @@ -24,12 +24,22 @@ #include <dm/root.h>
#if defined(CONFIG_SPL_BUILD) +#define MCU_CTRL_MMR0_BASE 0x04500000 +#define CTRLMMR_MCU_RST_CTRL 0x04518170
static void ctrl_mmr_unlock(void) { /* Unlock all PADCFG_MMR1 module registers */ mmr_unlock(PADCFG_MMR1_BASE, 1);
+ /* Unlock all MCU_CTRL_MMR0 module registers */ + mmr_unlock(MCU_CTRL_MMR0_BASE, 0); + mmr_unlock(MCU_CTRL_MMR0_BASE, 1); + mmr_unlock(MCU_CTRL_MMR0_BASE, 2); + mmr_unlock(MCU_CTRL_MMR0_BASE, 3); + mmr_unlock(MCU_CTRL_MMR0_BASE, 4); + mmr_unlock(MCU_CTRL_MMR0_BASE, 6); + /* Unlock all CTRL_MMR0 module registers */ mmr_unlock(CTRL_MMR0_BASE, 0); mmr_unlock(CTRL_MMR0_BASE, 1); @@ -37,9 +47,6 @@ static void ctrl_mmr_unlock(void) mmr_unlock(CTRL_MMR0_BASE, 3); mmr_unlock(CTRL_MMR0_BASE, 5); mmr_unlock(CTRL_MMR0_BASE, 6); - - /* Unlock all MCU_PADCFG_MMR1 module registers */ - mmr_unlock(MCU_PADCFG_MMR1_BASE, 1); }
/* @@ -144,7 +151,7 @@ int fdtdec_board_setup(const void *fdt_blob)
void board_init_f(ulong dummy) { -#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM64_DDRSS) +#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM64_DDRSS) || defined(CONFIG_ESM_K3) struct udevice *dev; int ret; #endif @@ -194,6 +201,20 @@ void board_init_f(ulong dummy) /* Output System Firmware version info */ k3_sysfw_print_ver();
+#if defined(CONFIG_ESM_K3) + /* Probe/configure ESM0 */ + ret = uclass_get_device_by_name(UCLASS_MISC, "esm@420000", &dev); + if (ret) + printf("esm main init failed: %d\n", ret); + + /* Probe/configure MCUESM */ + ret = uclass_get_device_by_name(UCLASS_MISC, "esm@4100000", &dev); + if (ret) + printf("esm mcu init failed: %d\n", ret); + + enable_mcu_esm_reset(); +#endif + #if defined(CONFIG_K3_AM64_DDRSS) ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret)

Am Mo., 28. Feb. 2022 um 05:56 Uhr schrieb Hari Nagalla hnagalla@ti.com:
On AM64x devices, it is possible to route Main ESM0 error events to MCU ESM. MCU ESM high error output can trigger the reset logic to reset the device. So, for these devices we expect two ESM device nodes in the device tree, one for Main ESM and the another MCU ESM in the device tree. When these ESM device nodes are properly configired it is possible to route the Main RTI0 WWDT output to the MCU ESM high ouput through Main ESM and trigger a device reset when CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RESET_EN_Z is set to '0'.
On K3 AM64x devices, the R5 SPL u-boot handles the ESM device node configurations.
Signed-off-by: Hari Nagalla hnagalla@ti.com
Reviewed-by: Christian Gmeiner christian.gmeiner@gmail.com

Am Mo., 28. Feb. 2022 um 05:56 Uhr schrieb Hari Nagalla hnagalla@ti.com:
On AM64x devices, it is possible to route Main ESM0 error events to MCU ESM. MCU ESM high error output can trigger the reset logic to reset the device. So, for these devices we expect two ESM device nodes in the device tree, one for Main ESM and the another MCU ESM in the device tree. When these ESM device nodes are properly configired it is possible to route the Main RTI0 WWDT output to the MCU ESM high ouput through Main ESM and trigger a device reset when CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RESET_EN_Z is set to '0'.
On K3 AM64x devices, the R5 SPL u-boot handles the ESM device node configurations.
Signed-off-by: Hari Nagalla hnagalla@ti.com
arch/arm/mach-k3/am642_init.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-k3/am642_init.c b/arch/arm/mach-k3/am642_init.c index 543dea02bc..f171c1e254 100644 --- a/arch/arm/mach-k3/am642_init.c +++ b/arch/arm/mach-k3/am642_init.c @@ -24,12 +24,22 @@ #include <dm/root.h>
#if defined(CONFIG_SPL_BUILD) +#define MCU_CTRL_MMR0_BASE 0x04500000 +#define CTRLMMR_MCU_RST_CTRL 0x04518170
static void ctrl_mmr_unlock(void) { /* Unlock all PADCFG_MMR1 module registers */ mmr_unlock(PADCFG_MMR1_BASE, 1);
/* Unlock all MCU_CTRL_MMR0 module registers */
mmr_unlock(MCU_CTRL_MMR0_BASE, 0);
mmr_unlock(MCU_CTRL_MMR0_BASE, 1);
mmr_unlock(MCU_CTRL_MMR0_BASE, 2);
mmr_unlock(MCU_CTRL_MMR0_BASE, 3);
mmr_unlock(MCU_CTRL_MMR0_BASE, 4);
mmr_unlock(MCU_CTRL_MMR0_BASE, 6);
/* Unlock all CTRL_MMR0 module registers */ mmr_unlock(CTRL_MMR0_BASE, 0); mmr_unlock(CTRL_MMR0_BASE, 1);
@@ -37,9 +47,6 @@ static void ctrl_mmr_unlock(void) mmr_unlock(CTRL_MMR0_BASE, 3); mmr_unlock(CTRL_MMR0_BASE, 5); mmr_unlock(CTRL_MMR0_BASE, 6);
/* Unlock all MCU_PADCFG_MMR1 module registers */
mmr_unlock(MCU_PADCFG_MMR1_BASE, 1);
}
/* @@ -144,7 +151,7 @@ int fdtdec_board_setup(const void *fdt_blob)
void board_init_f(ulong dummy) { -#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM64_DDRSS) +#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM64_DDRSS) || defined(CONFIG_ESM_K3) struct udevice *dev; int ret; #endif @@ -194,6 +201,20 @@ void board_init_f(ulong dummy) /* Output System Firmware version info */ k3_sysfw_print_ver();
+#if defined(CONFIG_ESM_K3)
/* Probe/configure ESM0 */
ret = uclass_get_device_by_name(UCLASS_MISC, "esm@420000", &dev);
if (ret)
printf("esm main init failed: %d\n", ret);
/* Probe/configure MCUESM */
ret = uclass_get_device_by_name(UCLASS_MISC, "esm@4100000", &dev);
if (ret)
printf("esm mcu init failed: %d\n", ret);
enable_mcu_esm_reset();
enable_mcu_esm_reset() is undefined! I think you forgot something in this patch series :(

Am Mo., 7. März 2022 um 12:18 Uhr schrieb Christian Gmeiner christian.gmeiner@gmail.com:
Am Mo., 28. Feb. 2022 um 05:56 Uhr schrieb Hari Nagalla hnagalla@ti.com:
On AM64x devices, it is possible to route Main ESM0 error events to MCU ESM. MCU ESM high error output can trigger the reset logic to reset the device. So, for these devices we expect two ESM device nodes in the device tree, one for Main ESM and the another MCU ESM in the device tree. When these ESM device nodes are properly configired it is possible to route the Main RTI0 WWDT output to the MCU ESM high ouput through Main ESM and trigger a device reset when CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RESET_EN_Z is set to '0'.
On K3 AM64x devices, the R5 SPL u-boot handles the ESM device node configurations.
Signed-off-by: Hari Nagalla hnagalla@ti.com
arch/arm/mach-k3/am642_init.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-k3/am642_init.c b/arch/arm/mach-k3/am642_init.c index 543dea02bc..f171c1e254 100644 --- a/arch/arm/mach-k3/am642_init.c +++ b/arch/arm/mach-k3/am642_init.c @@ -24,12 +24,22 @@ #include <dm/root.h>
#if defined(CONFIG_SPL_BUILD) +#define MCU_CTRL_MMR0_BASE 0x04500000 +#define CTRLMMR_MCU_RST_CTRL 0x04518170
static void ctrl_mmr_unlock(void) { /* Unlock all PADCFG_MMR1 module registers */ mmr_unlock(PADCFG_MMR1_BASE, 1);
/* Unlock all MCU_CTRL_MMR0 module registers */
mmr_unlock(MCU_CTRL_MMR0_BASE, 0);
mmr_unlock(MCU_CTRL_MMR0_BASE, 1);
mmr_unlock(MCU_CTRL_MMR0_BASE, 2);
mmr_unlock(MCU_CTRL_MMR0_BASE, 3);
mmr_unlock(MCU_CTRL_MMR0_BASE, 4);
mmr_unlock(MCU_CTRL_MMR0_BASE, 6);
/* Unlock all CTRL_MMR0 module registers */ mmr_unlock(CTRL_MMR0_BASE, 0); mmr_unlock(CTRL_MMR0_BASE, 1);
@@ -37,9 +47,6 @@ static void ctrl_mmr_unlock(void) mmr_unlock(CTRL_MMR0_BASE, 3); mmr_unlock(CTRL_MMR0_BASE, 5); mmr_unlock(CTRL_MMR0_BASE, 6);
/* Unlock all MCU_PADCFG_MMR1 module registers */
mmr_unlock(MCU_PADCFG_MMR1_BASE, 1);
}
Something like this:
#if defined(CONFIG_ESM_K3) static void enable_mcu_esm_reset(void) { /* Set CTRLMMR_MCU_RST_CTRL:MCU_ESM_ERROR_RST_EN_Z to '0' (low active) */ u32 stat = readl(CTRLMMR_MCU_RST_CTRL);
stat = stat & 0xFFFDFFFF; writel(stat, CTRLMMR_MCU_RST_CTRL); } #endif
/* @@ -144,7 +151,7 @@ int fdtdec_board_setup(const void *fdt_blob)
void board_init_f(ulong dummy) { -#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM64_DDRSS) +#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM64_DDRSS) || defined(CONFIG_ESM_K3) struct udevice *dev; int ret; #endif @@ -194,6 +201,20 @@ void board_init_f(ulong dummy) /* Output System Firmware version info */ k3_sysfw_print_ver();
+#if defined(CONFIG_ESM_K3)
/* Probe/configure ESM0 */
ret = uclass_get_device_by_name(UCLASS_MISC, "esm@420000", &dev);
if (ret)
printf("esm main init failed: %d\n", ret);
/* Probe/configure MCUESM */
ret = uclass_get_device_by_name(UCLASS_MISC, "esm@4100000", &dev);
if (ret)
printf("esm mcu init failed: %d\n", ret);
enable_mcu_esm_reset();
enable_mcu_esm_reset() is undefined! I think you forgot something in this patch series :(
Can you send a fixed V3?

Enable ESM driver for AM64x R5 SPL/u-boot builds.
Signed-off-by: Hari Nagalla hnagalla@ti.com --- configs/am64x_evm_r5_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/am64x_evm_r5_defconfig b/configs/am64x_evm_r5_defconfig index 61138dd1a9..e29e99c2d1 100644 --- a/configs/am64x_evm_r5_defconfig +++ b/configs/am64x_evm_r5_defconfig @@ -103,6 +103,7 @@ CONFIG_DM_I2C=y CONFIG_SYS_I2C_OMAP24XX=y CONFIG_DM_MAILBOX=y CONFIG_K3_SEC_PROXY=y +CONFIG_ESM_K3=y CONFIG_SPL_MISC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ADMA=y

Am Mo., 28. Feb. 2022 um 05:56 Uhr schrieb Hari Nagalla hnagalla@ti.com:
Enable ESM driver for AM64x R5 SPL/u-boot builds.
Signed-off-by: Hari Nagalla hnagalla@ti.com
Reviewed-by: Christian Gmeiner christian.gmeiner@gmail.com
participants (2)
-
Christian Gmeiner
-
Hari Nagalla