diff mbox series

[2/7] misc: k3_esm: Add support for Texas Instruments K3 ESM driver

Message ID 20200213093403.25037-3-t-kristo@ti.com
State Superseded
Headers show
Series ESM support for TI K3 SoCs | expand

Commit Message

Tero Kristo Feb. 13, 2020, 9:33 a.m. UTC
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.

Signed-off-by: Tero Kristo <t-kristo at ti.com>
---
 doc/device-tree-bindings/misc/esm-k3.txt | 25 +++++++
 drivers/misc/Kconfig                     |  5 ++
 drivers/misc/Makefile                    |  1 +
 drivers/misc/k3_esm.c                    | 87 ++++++++++++++++++++++++
 4 files changed, 118 insertions(+)
 create mode 100644 doc/device-tree-bindings/misc/esm-k3.txt
 create mode 100644 drivers/misc/k3_esm.c
diff mbox series

Patch

diff --git a/doc/device-tree-bindings/misc/esm-k3.txt b/doc/device-tree-bindings/misc/esm-k3.txt
new file mode 100644
index 0000000000..01c8b6b294
--- /dev/null
+++ b/doc/device-tree-bindings/misc/esm-k3.txt
@@ -0,0 +1,25 @@ 
+Texas Instruments K3 ESM Binding
+======================
+
+ESM (Error Signaling Module) is an IP block on TI K3 devices that allows
+handling of safety events somewhat similar to what interrupt controller
+would do. The safety signals have their separate paths within the SoC,
+and they are handled by the ESM, which routes them to the proper
+destination, which can be system reset, interrupt controller, etc. In
+the simplest configuration the signals are just routed to reset the
+SoC.
+
+Required properties :
+- compatible	: "ti,j721e-esm"
+- ti,esm-pins	: integer array of esm events IDs to route to external event
+		  pin which can be used to reset the SoC. The array can
+		  have arbitrary amount of event IDs listed on it.
+
+Example
+=======
+
+	main_esm: esm at 700000 {
+		compatible = "ti,j721e-esm";
+		reg = <0x0 0x700000 0x0 0x1000>;
+		ti,esm-pins = <344>, <345>;
+	};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index f18aa8f7ba..38588b2cbd 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -462,6 +462,11 @@  config IHS_FPGA
 	  gdsys devices, which supply the majority of the functionality offered
 	  by the devices. This driver supports both CON and CPU variants of the
 	  devices, depending on the device tree entry.
+config ESM_K3
+	bool "Enable K3 ESM driver"
+	depends on ARCH_K3
+	help
+	  Support ESM (Error Signaling Module) on TI K3 SoCs.
 
 config MICROCHIP_FLEXCOM
 	bool "Enable Microchip Flexcom driver"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2b843de93c..60406c3e0a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -72,3 +72,4 @@  obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
 obj-$(CONFIG_JZ4780_EFUSE) += jz4780_efuse.o
 obj-$(CONFIG_MICROCHIP_FLEXCOM) += microchip_flexcom.o
 obj-$(CONFIG_K3_AVS0) += k3_avs.o
+obj-$(CONFIG_ESM_K3) += k3_esm.o
diff --git a/drivers/misc/k3_esm.c b/drivers/misc/k3_esm.c
new file mode 100644
index 0000000000..8f270f3b5c
--- /dev/null
+++ b/drivers/misc/k3_esm.c
@@ -0,0 +1,87 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments' K3 Error Signalling Module driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *      Tero Kristo <t-kristo at ti.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/device_compat.h>
+
+#define ESM_SFT_RST			0x0c
+#define ESM_SFT_RST_KEY			0x0f
+
+#define ESM_STS(i)			(0x404 + (i) / 32 * 0x20)
+#define ESM_PIN_EN_SET_OFFSET(i)	(0x414 + (i) / 32 * 0x20)
+#define ESM_PIN_MASK(i)			BIT((i) & 0x1f)
+
+static void esm_pin_enable(void __iomem *base, int pin)
+{
+	/* Enable event */
+	writel(ESM_PIN_MASK(pin), base + ESM_PIN_EN_SET_OFFSET(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 udevice *dev)
+{
+	int ret;
+	void __iomem *base;
+	int num_pins;
+	u32 *pins;
+	int i;
+
+	base = dev_remap_addr_index(dev, 0);
+	if (!base)
+		return -ENODEV;
+
+	num_pins = dev_read_size(dev, "ti,esm-pins");
+	if (num_pins < 0) {
+		dev_err(dev, "ti,esm-pins property missing or invalid: %d\n",
+			num_pins);
+		return num_pins;
+	}
+
+	num_pins /= sizeof(u32);
+
+	pins = kmalloc(num_pins * sizeof(u32), __GFP_ZERO);
+	if (!pins)
+		return -ENOMEM;
+
+	ret = dev_read_u32_array(dev, "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_pin_enable(base, pins[i]);
+
+free_pins:
+	kfree(pins);
+	return ret;
+}
+
+static const struct udevice_id k3_esm_ids[] = {
+	{ .compatible = "ti,j721e-esm" },
+	{}
+};
+
+U_BOOT_DRIVER(k3_esm) = {
+	.name = "k3_esm",
+	.of_match = k3_esm_ids,
+	.id = UCLASS_MISC,
+	.probe = k3_esm_probe,
+};