From: Theodore Oviguian <[email protected]>

Add a TI eHRPWM TBCLK clock driver.
TBCLK provides the input clock required by all eHRPWM instances, so this
clock must be enabled before eHRPWM can operate.

Signed-off-by: Theodore Oviguian <[email protected]>
Cc: Tom Rini <[email protected]>
Cc: Lukasz Majewski <[email protected]>
---
 drivers/clk/ti/Kconfig        |  7 ++++
 drivers/clk/ti/Makefile       |  1 +
 drivers/clk/ti/ehrpwm-tbclk.c | 69 +++++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+)
 create mode 100644 drivers/clk/ti/ehrpwm-tbclk.c

diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig
index 3b995ab8f47..937f586706d 100644
--- a/drivers/clk/ti/Kconfig
+++ b/drivers/clk/ti/Kconfig
@@ -83,3 +83,10 @@ config SPL_CLK_K3
        depends on CLK && SPL
        help
          Enables the clock translation layer from DT to device clocks.
+
+config EHRPWM_TBCLK
+       bool "Clock support for TI AM6X EHRPWM"
+       depends on ARCH_K3 && CLK
+       default y if PWM_TI_EHRPWM
+       help
+         Enables clock support for TI AM6X pwms.
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index 74e4329a343..2c685224e7d 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_CLK_TI_OMAP4_CM) += omap4-cm.o
 obj-$(CONFIG_CLK_TI_SCI) += clk-sci.o
 obj-$(CONFIG_$(PHASE_)CLK_K3_PLL) += clk-k3-pll.o
 obj-$(CONFIG_$(PHASE_)CLK_K3) += clk-k3.o
+obj-$(CONFIG_EHRPWM_TBCLK) += ehrpwm-tbclk.o
diff --git a/drivers/clk/ti/ehrpwm-tbclk.c b/drivers/clk/ti/ehrpwm-tbclk.c
new file mode 100644
index 00000000000..bc91ef65b2e
--- /dev/null
+++ b/drivers/clk/ti/ehrpwm-tbclk.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *
+ * Copyright (C) 2026 Schneider Electric - https://se.com
+ *     Théodore Oviguian <[email protected]>
+ */
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <stdint.h>
+
+#define TBCLK_SET_REG_OFFSET 4
+#define TBCLK_CLR_REG_OFFSET 8
+
+static int ehrpwm_tbclk_enable(struct clk *clk)
+{
+       fdt_addr_t reg = dev_read_addr(clk->dev);
+       uint32_t reg_val = readl(reg);
+
+       reg_val |= BIT(clk->id);
+
+       writel(reg_val, reg);
+
+       return 0;
+}
+
+static int ehrpwm_tbclk_disable(struct clk *clk)
+{
+       fdt_addr_t reg = dev_read_addr(clk->dev);
+       uint32_t reg_val = readl(reg);
+
+       reg_val &= ~BIT(clk->id);
+
+       writel(reg_val, reg);
+
+       return 0;
+}
+
+static ulong ehrpwm_tbclk_get_rate(struct clk *clk)
+{
+       return 0;
+}
+
+static struct clk_ops ehrpwm_tbclk_ops = {
+       .enable = ehrpwm_tbclk_enable,
+    .disable = ehrpwm_tbclk_disable,
+       .get_rate = ehrpwm_tbclk_get_rate,
+};
+
+static const struct udevice_id ehrpwm_tbclk_ids[] = {
+       { .compatible = "ti,am654-ehrpwm-tbclk" },
+       { .compatible = "ti,am64-epwm-tbclk" },
+       { .compatible = "ti,am62-epwm-tbclk" },
+       { /* sentinel */ }
+};
+
+static int ehrpwm_tbclk_probe(struct udevice *dev)
+{
+       return 0;
+}
+
+U_BOOT_DRIVER(ehrpwm_tbclk) = {
+       .name = "ehrpwm_tbclk",
+       .id = UCLASS_CLK,
+       .of_match = ehrpwm_tbclk_ids,
+       .ops = &ehrpwm_tbclk_ops,
+       .probe = ehrpwm_tbclk_probe,
+       .priv_auto      = 0,
+};
-- 
2.43.0

Reply via email to