diff mbox series

[v1,1/4] misc: k3_esm: Add functionality to set and route error events within K3SoC

Message ID 20220202182223.16521-2-hnagalla@ti.com
State Changes Requested
Delegated to: Tom Rini
Headers show
Series Add ESM driver support for AM64x R5 | expand

Commit Message

Hari Nagalla Feb. 2, 2022, 6:22 p.m. UTC
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'.

Signed-off-by: Hari Nagalla <hnagalla@ti.com>
---
 drivers/misc/k3_esm.c | 53 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 3 deletions(-)

Comments

Nishanth Menon Feb. 3, 2022, 9:44 p.m. UTC | #1
On 12:22-20220202, Hari Nagalla wrote:
> 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'.
> 

Since this driver is common, it will be good to also highlight that
existing devices (such as J7* SoCs) which use the same driver is not
impacted by this change.

> 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);
> -- 
> 2.17.1
>
diff mbox series

Patch

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);