[PATCH] soc: k3: Add support for Texas Instruments K3 ESM driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The ESM (Error Signaling Module) is used to route error signals within
the K3 SoCs somewhat similar to interrupts. The handling for these is
different though, and can be routed for hardware error handling, to
be handled by safety processor or just as error interrupts handled
by the main processor. The u-boot level ESM driver is just used to
configure the ESM signals so that they get routed to proper destination.

The code and the commit message is based on the corresponding U-Boot
driver as of U-Boot-2025.01.

Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
---
 arch/arm/mach-k3/common.c |  13 ++++
 drivers/soc/Kconfig       |   1 +
 drivers/soc/ti/Kconfig    |   4 ++
 drivers/soc/ti/Makefile   |   1 +
 drivers/soc/ti/k3-esm.c   | 136 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 155 insertions(+)
 create mode 100644 drivers/soc/ti/Kconfig
 create mode 100644 drivers/soc/ti/k3-esm.c

diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 9e3dab5b8e..c2a774ea67 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -242,6 +242,17 @@ static int am625_of_fixup(struct device_node *root, void *unused)
 	return 0;
 }
 
+#define CTRLMMR_MCU_RST_CTRL	IOMEM(0x04518170)
+#define RST_CTRL_ESM_ERROR_RST_EN_Z_MASK BIT(17)
+
+static void am625_enable_mcu_esm_reset(void)
+{
+	/* activate reset of main by ESMO */
+	u32 stat = readl(CTRLMMR_MCU_RST_CTRL);
+	stat &= ~RST_CTRL_ESM_ERROR_RST_EN_Z_MASK;
+	writel(stat, CTRLMMR_MCU_RST_CTRL);
+}
+
 static int am625_init(void)
 {
 	enum bootsource src = BOOTSOURCE_UNKNOWN;
@@ -264,6 +275,8 @@ static int am625_init(void)
 
 	of_register_fixup(am625_of_fixup, NULL);
 
+	am625_enable_mcu_esm_reset();
+
 	return 0;
 }
 postcore_initcall(am625_init);
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index c0fe214429..cbde3c35a4 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -3,5 +3,6 @@ menu "SoC drivers"
 source "drivers/soc/imx/Kconfig"
 source "drivers/soc/kvx/Kconfig"
 source "drivers/soc/rockchip/Kconfig"
+source "drivers/soc/ti/Kconfig"
 
 endmenu
diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
new file mode 100644
index 0000000000..8d2dd86f3f
--- /dev/null
+++ b/drivers/soc/ti/Kconfig
@@ -0,0 +1,4 @@
+config K3_ESM
+	bool
+	depends on ARCH_K3 && MACH_K3_CORTEX_R5
+	default y
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
index 56f6653882..3109a4e967 100644
--- a/drivers/soc/ti/Makefile
+++ b/drivers/soc/ti/Makefile
@@ -1 +1,2 @@
 obj-y += k3-navss-ringacc.o
+obj-$(CONFIG_K3_ESM) += k3-esm.o
diff --git a/drivers/soc/ti/k3-esm.c b/drivers/soc/ti/k3-esm.c
new file mode 100644
index 0000000000..3f51b757c9
--- /dev/null
+++ b/drivers/soc/ti/k3-esm.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments' K3 Error Signalling Module driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
+ *      Tero Kristo <t-kristo@xxxxxx>
+ *
+ */
+
+#include <driver.h>
+#include <malloc.h>
+#include <xfuncs.h>
+#include <io.h>
+
+#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)			(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(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
+ *
+ * Parses ESM info from device tree, and configures the module accordingly.
+ */
+static int k3_esm_probe(struct device *dev)
+{
+	int ret;
+	void __iomem *base;
+	int num_pins;
+	u32 *pins;
+	int i;
+	struct device_node *np = dev->of_node;
+
+	base = dev_request_mem_region(dev, 0);
+	if (IS_ERR(base))
+		return -ENODEV;
+
+	num_pins = of_property_count_elems_of_size(np, "ti,esm-pins", sizeof(u32));
+	if (num_pins < 0) {
+		dev_err(dev, "ti,esm-pins property missing or invalid: %d\n",
+			num_pins);
+		return num_pins;
+	}
+
+	pins = xzalloc(num_pins * sizeof(u32));
+	if (!pins)
+		return -ENOMEM;
+
+	ret = of_property_read_u32_array(np, "ti,esm-pins", pins, num_pins);
+	if (ret < 0) {
+		dev_err(dev, "failed to read ti,esm-pins property: %d\n",
+			ret);
+		goto free_pins;
+	}
+
+	/* Clear any pending events */
+	writel(ESM_SFT_RST_KEY, base + ESM_SFT_RST);
+
+	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:
+	free(pins);
+	return ret;
+}
+
+static const struct of_device_id k3_esm_ids[] = {
+	{
+		.compatible = "ti,j721e-esm",
+	}, {
+		/* sentinel */
+	},
+};
+
+static struct driver k3_esm = {
+	.probe  = k3_esm_probe,
+	.name   = "k3-esm",
+	.of_compatible = k3_esm_ids,
+};
+
+core_platform_driver(k3_esm);
-- 
2.39.5





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux