1 // SPDX-License-Identifier: GPL-2.0+
3 * Texas Instruments' K3 Error Signalling Module driver
5 * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
6 * Tero Kristo <t-kristo@ti.com>
13 #include <dm/device_compat.h>
14 #include <linux/bitops.h>
16 #define ESM_SFT_RST 0x0c
17 #define ESM_SFT_RST_KEY 0x0f
19 #define ESM_EN_KEY 0x0f
21 #define ESM_STS(i) (0x404 + (i) / 32 * 0x20)
22 #define ESM_STS_MASK(i) (1 << ((i) % 32))
23 #define ESM_PIN_EN_SET_OFFSET(i) (0x414 + (i) / 32 * 0x20)
24 #define ESM_PIN_MASK(i) (1 << ((i) % 32))
25 #define ESM_INTR_EN_SET_OFFSET(i) (0x408 + (i) / 32 * 0x20)
26 #define ESM_INTR_MASK(i) (1 << ((i) % 32))
27 #define ESM_INTR_PRIO_SET_OFFSET(i) (0x410 + (i) / 32 * 0x20)
28 #define ESM_INTR_PRIO_MASK(i) (1 << ((i) % 32))
30 static void esm_pin_enable(void __iomem *base, int pin)
34 value = readl(base + ESM_PIN_EN_SET_OFFSET(pin));
35 value |= ESM_PIN_MASK(pin);
37 writel(value, base + ESM_PIN_EN_SET_OFFSET(pin));
40 static void esm_intr_enable(void __iomem *base, int pin)
44 value = readl(base + ESM_INTR_EN_SET_OFFSET(pin));
45 value |= ESM_INTR_MASK(pin);
46 /* Enable Interrupt event */
47 writel(value, base + ESM_INTR_EN_SET_OFFSET(pin));
50 static void esm_intr_prio_set(void __iomem *base, int pin)
54 value = readl(base + ESM_INTR_PRIO_SET_OFFSET(pin));
55 value |= ESM_INTR_PRIO_MASK(pin);
57 writel(value, base + ESM_INTR_PRIO_SET_OFFSET(pin));
60 static void esm_clear_raw_status(void __iomem *base, int pin)
64 value = readl(base + ESM_STS(pin));
65 value |= ESM_STS_MASK(pin);
66 /* Clear Event status */
67 writel(value, base + ESM_STS(pin));
70 * k3_esm_probe: configures ESM based on DT data
72 * Parses ESM info from device tree, and configures the module accordingly.
74 static int k3_esm_probe(struct udevice *dev)
82 base = dev_remap_addr_index(dev, 0);
86 num_pins = dev_read_size(dev, "ti,esm-pins");
88 dev_err(dev, "ti,esm-pins property missing or invalid: %d\n",
93 num_pins /= sizeof(u32);
95 pins = kmalloc(num_pins * sizeof(u32), __GFP_ZERO);
99 ret = dev_read_u32_array(dev, "ti,esm-pins", pins, num_pins);
101 dev_err(dev, "failed to read ti,esm-pins property: %d\n",
106 /* Clear any pending events */
107 writel(ESM_SFT_RST_KEY, base + ESM_SFT_RST);
109 for (i = 0; i < num_pins; i++) {
110 esm_intr_prio_set(base, pins[i]);
111 esm_clear_raw_status(base, pins[i]);
112 esm_pin_enable(base, pins[i]);
113 esm_intr_enable(base, pins[i]);
117 writel(ESM_EN_KEY, base + ESM_EN);
124 static const struct udevice_id k3_esm_ids[] = {
125 { .compatible = "ti,j721e-esm" },
129 U_BOOT_DRIVER(k3_esm) = {
131 .of_match = k3_esm_ids,
133 .probe = k3_esm_probe,