public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC uL PATCH 0/2] Add TI's event mux router driver and build
@ 2026-03-13  6:04 Rahul Sharma
  2026-03-13  6:04 ` [RFC uL PATCH 1/2] dt-bindings: mux-controller: ti: add binding for event mux router Rahul Sharma
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Rahul Sharma @ 2026-03-13  6:04 UTC (permalink / raw)
  To: peda, robh, krzk+dt, conor+dt
  Cc: devicetree, vigneshr, r-sharma3, linux-kernel

This series contains the event mux router support present in TI's K3
platforms. The event mux router are of 2 types
1) gpio-mux router
2) timesync router

In normal scenarios, GPIO signals are received by CPU via GIC, but the
gpio mux router routes the incoming GPIO signal to BCDMA(Block copy
DMA) which the DMA upon receiving uses as HW triger to perform a single
block transfer or as configured.

Time sync router does the same but for the time synchronization based
events.

This driver supports both the routers but this patch series adds support
only for GPIO-mux router.

Rahul Sharma (2):
  dt-bindings: mux-controller: ti: add binding for event mux router
  mux-controller: ti: add driver for event mux router

 .../mux/ti,am62l-event-mux-router.yaml        |  79 ++++++
 drivers/mux/Kconfig                           |  15 ++
 drivers/mux/Makefile                          |   2 +
 drivers/mux/ti-k3-event-mux.c                 | 235 ++++++++++++++++++
 4 files changed, 331 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mux/ti,am62l-event-mux-router.yaml
 create mode 100644 drivers/mux/ti-k3-event-mux.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC uL PATCH 1/2] dt-bindings: mux-controller: ti: add binding for event mux router
  2026-03-13  6:04 [RFC uL PATCH 0/2] Add TI's event mux router driver and build Rahul Sharma
@ 2026-03-13  6:04 ` Rahul Sharma
  2026-03-13  6:04 ` [RFC uL PATCH 2/2] mux-controller: ti: add driver " Rahul Sharma
  2026-03-13  6:35 ` [RFC uL PATCH 0/2] Add TI's event mux router driver and build Sharma, Rahul
  2 siblings, 0 replies; 4+ messages in thread
From: Rahul Sharma @ 2026-03-13  6:04 UTC (permalink / raw)
  To: peda, robh, krzk+dt, conor+dt
  Cc: devicetree, vigneshr, r-sharma3, linux-kernel

Add binding for the event mux router of TI's K3 based SoC AM62L.

The TI K3 mux routers which route the GPIO input events or Time-Sync
events b/w peripherals instead of routing to a CPU.

Refer Section 10.2 and 10.2.1 of https://www.ti.com/lit/pdf/sprujb4

Signed-off-by: Rahul Sharma <r-sharma3@ti.com>
---
 .../mux/ti,am62l-event-mux-router.yaml        | 79 +++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mux/ti,am62l-event-mux-router.yaml

diff --git a/Documentation/devicetree/bindings/mux/ti,am62l-event-mux-router.yaml b/Documentation/devicetree/bindings/mux/ti,am62l-event-mux-router.yaml
new file mode 100644
index 000000000000..5401b0542eff
--- /dev/null
+++ b/Documentation/devicetree/bindings/mux/ti,am62l-event-mux-router.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mux/ti,am62l-event-mux-router.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI Event Multiplexer on K3 SoCs
+
+maintainers:
+  - Rahul Sharma <r-sharma3@ti.com>
+
+description:
+  The TI K3 mux routers routes the GPIO input events or Time
+  Sync events between peripherals instead of routing to a CPU.
+
+allOf:
+  - $ref: mux-controller.yaml#
+
+properties:
+  compatible:
+    const: ti,am62l-event-mux-router
+
+  reg:
+    description: Register base address and size.
+    maxItems: 1
+
+  '#mux-control-cells':
+    const: 1
+    description:
+      Number of cells in a mux control specifier. This should be 1.
+      The cell specifies which mux control to use (0-based index).
+
+  ti,reg-mask-val:
+    $ref: /schemas/types.yaml#/definitions/uint32-matrix
+    items:
+      items:
+        - description: Register offset (relative to reg base)
+        - description: Bit mask for the mux control bits
+        - description: Value to write when mux is active (state 1)
+    minItems: 1
+    description: |
+      Array of triplets specifying register offset, mask, and value for each
+      mux control. Each triplet contains:
+      - register offset (relative to reg base or syscon)
+      - bit mask for the mux control bits
+      - value to write when mux is active (state 1)
+
+  idle-states:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: |
+      Idle state for each mux control. Each entry corresponds to a mux control:
+      - 0: clear masked bits when idle, also refers to inactive state
+      - 1: set configured value when idle, also refers to active state
+      - MUX_IDLE_AS_IS (-1): keep current state when idle
+
+required:
+  - compatible
+  - reg
+  - '#mux-control-cells'
+  - ti,reg-mask-val
+  - idle-states
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/mux/mux.h>
+
+    // Example 1: TI AM62L GPIO Mux Router
+    mux-controller@a00000 {
+        compatible = "ti,am62l-event-mux-router";
+        reg = <0xa00000 0x400>;
+        #mux-control-cells = <1>;
+
+        /* Mux Register addresses: 0xa00004 + (J × 4) */
+        /* GPIO0_40 -> BCDMA trigger 15 */
+        ti,reg-mask-val = <0x40 0x000ff 0x00028>;
+        idle-states = <0>;
+    };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC uL PATCH 2/2] mux-controller: ti: add driver for event mux router
  2026-03-13  6:04 [RFC uL PATCH 0/2] Add TI's event mux router driver and build Rahul Sharma
  2026-03-13  6:04 ` [RFC uL PATCH 1/2] dt-bindings: mux-controller: ti: add binding for event mux router Rahul Sharma
@ 2026-03-13  6:04 ` Rahul Sharma
  2026-03-13  6:35 ` [RFC uL PATCH 0/2] Add TI's event mux router driver and build Sharma, Rahul
  2 siblings, 0 replies; 4+ messages in thread
From: Rahul Sharma @ 2026-03-13  6:04 UTC (permalink / raw)
  To: peda, robh, krzk+dt, conor+dt
  Cc: devicetree, vigneshr, r-sharma3, linux-kernel

The driver supports event muxing routers like gpio mux router and timesync
router. This driver is adaptation of original reg-mux driver, along with
changes specific to support TI's mux router.

The idle states this driver supports are only 2 which active(represented
by 1 in dt-node) and in-active(represented by 0 in dt-node).

Signed-off-by: Rahul Sharma <r-sharma3@ti.com>
---
 drivers/mux/Kconfig           |  15 +++
 drivers/mux/Makefile          |   2 +
 drivers/mux/ti-k3-event-mux.c | 235 ++++++++++++++++++++++++++++++++++
 3 files changed, 252 insertions(+)
 create mode 100644 drivers/mux/ti-k3-event-mux.c

diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index c68132e38138..ad3af2724d28 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -59,4 +59,19 @@ config MUX_MMIO
 	  To compile the driver as a module, choose M here: the module will
 	  be called mux-mmio.
 
+config MUX_TI_K3_EVENT_ROUTER
+	tristate "TI Event Mux Router using MMIO registers"
+	depends on OF && (REGMAP_MMIO || COMPILE_TEST)
+	help
+	  This is extension of MMIO mux for  timesync router and gpiomux
+	  routers on TI K3 SoCs. This driver supports the 3-field format for
+	  mux control: <register-offset mask value>.
+
+	  The driver allows configuration of hardware mux routers using
+	  memory-mapped registers. It's based on the mmio-mux driver but
+	  supports the extended 3-field format for more precise control.
+
+	  To compile the driver as a module, choose M here: the module will
+	  be called mux-ti-k3-event.
+
 endmenu
diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile
index 6e9fa47daf56..f3f367de84da 100644
--- a/drivers/mux/Makefile
+++ b/drivers/mux/Makefile
@@ -8,9 +8,11 @@ mux-adg792a-objs		:= adg792a.o
 mux-adgs1408-objs		:= adgs1408.o
 mux-gpio-objs			:= gpio.o
 mux-mmio-objs			:= mmio.o
+mux-ti-k3-event-objs		:= ti-k3-event-mux.o
 
 obj-$(CONFIG_MULTIPLEXER)	+= mux-core.o
 obj-$(CONFIG_MUX_ADG792A)	+= mux-adg792a.o
 obj-$(CONFIG_MUX_ADGS1408)	+= mux-adgs1408.o
 obj-$(CONFIG_MUX_GPIO)		+= mux-gpio.o
 obj-$(CONFIG_MUX_MMIO)		+= mux-mmio.o
+obj-$(CONFIG_MUX_TI_K3_EVENT_ROUTER)	+= mux-ti-k3-event.o
diff --git a/drivers/mux/ti-k3-event-mux.c b/drivers/mux/ti-k3-event-mux.c
new file mode 100644
index 000000000000..2469500d1b48
--- /dev/null
+++ b/drivers/mux/ti-k3-event-mux.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MMIO register bit-field controlled multiplexer driver
+ *
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com
+ *
+ * Based on drivers/mux/mmio.c by Philipp Zabel <kernel@pengutronix.de>
+ * Modified to support 3-field format: reg-offset, mask & value
+ *
+ * Author: Rahul Sharma <r-sharma3@ti.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/mux/driver.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#define MUX_ENABLE_INTR BIT(16)
+
+struct mux_ti_k3_event {
+	struct regmap *regmap;
+	u32 reg;
+	u32 mask;
+	u32 value;
+};
+
+struct mux_ti_k3_event_chip {
+	struct mux_chip *mux_chip;
+	struct mux_ti_k3_event *fields;
+	int num_fields;
+	u32 *saved_states;
+};
+
+static int mux_ti_k3_event_suspend(struct device *dev)
+{
+	struct mux_ti_k3_event_chip *chip = dev_get_drvdata(dev);
+	int i, ret;
+
+	if (!chip->saved_states) {
+		chip->saved_states = devm_kcalloc(dev, chip->num_fields,
+						  sizeof(u32), GFP_KERNEL);
+		if (!chip->saved_states)
+			return -ENOMEM;
+	}
+
+	for (i = 0; i < chip->num_fields; i++) {
+		struct mux_ti_k3_event *field = &chip->fields[i];
+
+		ret = regmap_read(field->regmap, field->reg,
+				  &chip->saved_states[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int mux_ti_k3_event_resume(struct device *dev)
+{
+	struct mux_ti_k3_event_chip *chip = dev_get_drvdata(dev);
+	int i, ret;
+
+	if (!chip->saved_states)
+		return 0;
+
+	for (i = 0; i < chip->num_fields; i++) {
+		struct mux_ti_k3_event *field = &chip->fields[i];
+
+		ret = regmap_write(field->regmap, field->reg,
+				   chip->saved_states[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(mux_ti_k3_event_pm_ops,
+				mux_ti_k3_event_suspend,
+				mux_ti_k3_event_resume);
+
+/*
+ * State behavior:
+ * - state 0: Clears the mask bits in the target register (inactive state)
+ * - state 1: Sets both the value bits and enable bit (bit 16) in the register
+ */
+static int mux_ti_k3_event_set(struct mux_control *mux, int state)
+{
+	struct mux_ti_k3_event *fields = mux_chip_priv(mux->chip);
+	struct mux_ti_k3_event *field = &fields[mux_control_get_index(mux)];
+
+	if (!state)
+		return regmap_update_bits(field->regmap, field->reg, field->mask, 0);
+
+	return regmap_update_bits(field->regmap, field->reg, field->mask | MUX_ENABLE_INTR,
+		field->value | MUX_ENABLE_INTR);
+}
+
+static const struct mux_control_ops mux_ti_k3_event_ops = {
+	.set = mux_ti_k3_event_set,
+};
+
+static const struct regmap_config mux_ti_k3_event_regmap_cfg = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+};
+
+static int mux_ti_k3_event_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct mux_ti_k3_event_chip *chip;
+	struct mux_ti_k3_event *fields;
+	struct mux_chip *mux_chip;
+	struct regmap *regmap;
+	void __iomem *base;
+	int num_fields;
+	int ret;
+	int i;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base)) {
+		return dev_err_probe(dev, -ENODEV,
+				     "failed to get base address\n");
+	} else {
+		regmap = devm_regmap_init_mmio(dev, base, &mux_ti_k3_event_regmap_cfg);
+	}
+	if (IS_ERR(regmap)) {
+		iounmap(base);
+		return dev_err_probe(dev, PTR_ERR(regmap),
+				     "failed to get regmap\n");
+	}
+
+	ret = of_property_count_u32_elems(np, "ti,reg-mask-val");
+	if (!ret || ret % 3) {
+		ret = -EINVAL;
+		dev_err(dev, "ti,reg-mask-val property missing or invalid: %d\n",
+			ret);
+		return ret;
+	}
+
+	num_fields = ret / 3;
+	mux_chip = devm_mux_chip_alloc(dev, num_fields, num_fields *
+				       sizeof(*fields));
+	if (IS_ERR(mux_chip))
+		return PTR_ERR(mux_chip);
+
+	fields = mux_chip_priv(mux_chip);
+	chip->mux_chip = mux_chip;
+	chip->fields = fields;
+	chip->num_fields = num_fields;
+
+	platform_set_drvdata(pdev, chip);
+
+	for (i = 0; i < num_fields; i++) {
+		struct mux_control *mux = &mux_chip->mux[i];
+		s32 idle_state = MUX_IDLE_AS_IS;
+		u32 reg, mask, value;
+
+		ret = of_property_read_u32_index(np, "ti,reg-mask-val",
+						 3 * i, &reg);
+		if (!ret)
+			ret = of_property_read_u32_index(np, "ti,reg-mask-val",
+							 3 * i + 1, &mask);
+		if (!ret)
+			ret = of_property_read_u32_index(np, "ti,reg-mask-val",
+							 3 * i + 2, &value);
+		if (ret < 0) {
+			dev_err(dev, "field %d: failed to read ti,reg-mask-val property: %d\n",
+				i, ret);
+			return ret;
+		}
+
+		/* Validate that value bits are within mask */
+		if (value & ~mask) {
+			dev_err(dev, "field %d: value 0x%x has bits outside mask 0x%x\n",
+				i, value, mask);
+			return -EINVAL;
+		}
+
+		fields[i].regmap = regmap;
+		fields[i].reg = reg;
+		fields[i].mask = mask;
+		fields[i].value = value;
+
+		/* This driver supports binary mux (2 states: 0 and active) */
+		mux->states = 2;
+
+		of_property_read_u32_index(np, "idle-states", i,
+					   (u32 *)&idle_state);
+		if (idle_state != MUX_IDLE_AS_IS) {
+			if (idle_state < 0 || idle_state >= mux->states) {
+				dev_err(dev, "field: %d: out of range idle state %d\n",
+					i, idle_state);
+				return -EINVAL;
+			}
+
+			mux->idle_state = idle_state;
+		}
+	}
+
+	mux_chip->ops = &mux_ti_k3_event_ops;
+
+	return devm_mux_chip_register(dev, mux_chip);
+}
+
+static const struct of_device_id mux_ti_k3_event_dt_ids[] = {
+	{ .compatible = "ti,am62l-event-mux-router", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mux_ti_k3_event_dt_ids);
+
+static struct platform_driver mux_ti_k3_event_driver = {
+	.driver = {
+		.name = "ti-k3-event-mux",
+		.of_match_table	= mux_ti_k3_event_dt_ids,
+		.pm = &mux_ti_k3_event_pm_ops,
+	},
+	.probe = mux_ti_k3_event_probe,
+};
+module_platform_driver(mux_ti_k3_event_driver);
+
+MODULE_DESCRIPTION("TI K3 Bit-field Controlled Event Multiplexer driver");
+MODULE_AUTHOR("Rahul Sharma <r-sharma3@ti.com>");
+MODULE_LICENSE("GPL");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC uL PATCH 0/2] Add TI's event mux router driver and build
  2026-03-13  6:04 [RFC uL PATCH 0/2] Add TI's event mux router driver and build Rahul Sharma
  2026-03-13  6:04 ` [RFC uL PATCH 1/2] dt-bindings: mux-controller: ti: add binding for event mux router Rahul Sharma
  2026-03-13  6:04 ` [RFC uL PATCH 2/2] mux-controller: ti: add driver " Rahul Sharma
@ 2026-03-13  6:35 ` Sharma, Rahul
  2 siblings, 0 replies; 4+ messages in thread
From: Sharma, Rahul @ 2026-03-13  6:35 UTC (permalink / raw)
  To: peda, robh, krzk+dt, conor+dt; +Cc: devicetree, vigneshr, linux-kernel

Hi,

A note point for this patch series,

1) Subject prefix has "uL" which means upstream Linux. This got added by
mistake.

2) In both the patches of this series the commit header should use "mux"
instead of "mux-controller".

I will correct above but would wait for 1st round of comments before
re-spin.

BR,
Rahul

On 3/13/2026 11:34 AM, Rahul Sharma wrote:
> This series contains the event mux router support present in TI's K3
> platforms. The event mux router are of 2 types
> 1) gpio-mux router
> 2) timesync router
> 
> In normal scenarios, GPIO signals are received by CPU via GIC, but the
> gpio mux router routes the incoming GPIO signal to BCDMA(Block copy
> DMA) which the DMA upon receiving uses as HW triger to perform a single
> block transfer or as configured.
> 
> Time sync router does the same but for the time synchronization based
> events.
> 
> This driver supports both the routers but this patch series adds support
> only for GPIO-mux router.
> 
> Rahul Sharma (2):
>   dt-bindings: mux-controller: ti: add binding for event mux router
>   mux-controller: ti: add driver for event mux router
> 
>  .../mux/ti,am62l-event-mux-router.yaml        |  79 ++++++
>  drivers/mux/Kconfig                           |  15 ++
>  drivers/mux/Makefile                          |   2 +
>  drivers/mux/ti-k3-event-mux.c                 | 235 ++++++++++++++++++
>  4 files changed, 331 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mux/ti,am62l-event-mux-router.yaml
>  create mode 100644 drivers/mux/ti-k3-event-mux.c
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-03-13  6:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-13  6:04 [RFC uL PATCH 0/2] Add TI's event mux router driver and build Rahul Sharma
2026-03-13  6:04 ` [RFC uL PATCH 1/2] dt-bindings: mux-controller: ti: add binding for event mux router Rahul Sharma
2026-03-13  6:04 ` [RFC uL PATCH 2/2] mux-controller: ti: add driver " Rahul Sharma
2026-03-13  6:35 ` [RFC uL PATCH 0/2] Add TI's event mux router driver and build Sharma, Rahul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox