clk: exynos: add support for fixed rate and fixed factor clocks
authorKaustabh Chakraborty <kauschluss@disroot.org>
Fri, 17 Oct 2025 15:21:30 +0000 (20:51 +0530)
committerMinkyu Kang <mk7.kang@samsung.com>
Wed, 12 Nov 2025 04:56:12 +0000 (13:56 +0900)
Add register functions for fixed rate and fixed factor clock drivers.
The vendor-specific structs defined are borrowed from the CCF driver
found in the Linux kernel.

Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
drivers/clk/exynos/clk.c
drivers/clk/exynos/clk.h

index 2f5a3de..a383298 100644 (file)
 #include <dm.h>
 #include "clk.h"
 
+static void
+samsung_clk_register_fixed_rate(struct udevice *dev, void __iomem *base,
+                               unsigned int cmu_id,
+                               const struct samsung_fixed_rate_clock *clk_list,
+                               unsigned int nr_clk)
+{
+       unsigned int cnt;
+
+       for (cnt = 0; cnt < nr_clk; cnt++) {
+               struct clk *clk;
+               const struct samsung_fixed_rate_clock *m;
+               unsigned long clk_id;
+
+               m = &clk_list[cnt];
+               clk = clk_register_fixed_rate(NULL, m->name, m->fixed_rate);
+               clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id);
+               clk_dm(clk_id, clk);
+       }
+}
+
+static void
+samsung_clk_register_fixed_factor(struct udevice *dev, void __iomem *base,
+                                 unsigned int cmu_id,
+                                 const struct samsung_fixed_factor_clock *clk_list,
+                                 unsigned int nr_clk)
+{
+       unsigned int cnt;
+
+       for (cnt = 0; cnt < nr_clk; cnt++) {
+               struct clk *clk;
+               const struct samsung_fixed_factor_clock *m;
+               unsigned long clk_id;
+
+               m = &clk_list[cnt];
+               clk = clk_register_fixed_factor(dev, m->name, m->parent_name,
+                                               m->flags, m->mult, m->div);
+               clk_id = SAMSUNG_TO_CLK_ID(cmu_id, m->id);
+               clk_dm(clk_id, clk);
+       }
+}
+
 static void samsung_clk_register_mux(struct udevice *dev, void __iomem *base,
                                     unsigned int cmu_id,
                                     const struct samsung_mux_clock *clk_list,
@@ -79,6 +120,8 @@ typedef void (*samsung_clk_register_fn)(struct udevice *dev, void __iomem *base,
                                        unsigned int nr_clk);
 
 static const samsung_clk_register_fn samsung_clk_register_fns[] = {
+       [S_CLK_FRATE]   = (samsung_clk_register_fn)samsung_clk_register_fixed_rate,
+       [S_CLK_FFACTOR] = (samsung_clk_register_fn)samsung_clk_register_fixed_factor,
        [S_CLK_MUX]     = (samsung_clk_register_fn)samsung_clk_register_mux,
        [S_CLK_DIV]     = (samsung_clk_register_fn)samsung_clk_register_div,
        [S_CLK_GATE]    = (samsung_clk_register_fn)samsung_clk_register_gate,
index ed0a395..e53dcc6 100644 (file)
@@ -58,6 +58,53 @@ static const struct clk_ops _name##_clk_ops = {                              \
  */
 #define SAMSUNG_TO_CLK_ID(_cmu, _id)   (((_cmu) << 8) | ((_id) & 0xff))
 
+/**
+ * struct samsung_fixed_rate_clock - information about fixed-rate clock
+ * @id: platform specific id of the clock
+ * @name: name of this fixed-rate clock
+ * @fixed_rate: fixed clock rate of this clock
+ */
+struct samsung_fixed_rate_clock {
+       unsigned int            id;
+       const char              *name;
+       unsigned long           fixed_rate;
+};
+
+#define FRATE(_id, cname, frate)                       \
+       {                                               \
+               .id             = _id,                  \
+               .name           = cname,                \
+               .fixed_rate     = frate,                \
+       }
+
+/**
+ * struct samsung_fixed_factor_clock - information about fixed-factor clock
+ * @id: platform specific id of the clock
+ * @name: name of this fixed-factor clock
+ * @parent_name: parent clock name
+ * @mult: fixed multiplication factor
+ * @div: fixed division factor
+ * @flags: optional fixed-factor clock flags
+ */
+struct samsung_fixed_factor_clock {
+       unsigned int            id;
+       const char              *name;
+       const char              *parent_name;
+       unsigned long           mult;
+       unsigned long           div;
+       unsigned long           flags;
+};
+
+#define FFACTOR(_id, cname, pname, m, d, f)            \
+       {                                               \
+               .id             = _id,                  \
+               .name           = cname,                \
+               .parent_name    = pname,                \
+               .mult           = m,                    \
+               .div            = d,                    \
+               .flags          = f,                    \
+       }
+
 /**
  * struct samsung_mux_clock - information about mux clock
  * @id: platform specific id of the clock
@@ -206,6 +253,8 @@ struct samsung_pll_clock {
        }
 
 enum samsung_clock_type {
+       S_CLK_FRATE,
+       S_CLK_FFACTOR,
        S_CLK_MUX,
        S_CLK_DIV,
        S_CLK_GATE,