]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
clk: spacemit: ccu_mix: add inverted enable gate clock
authorYixun Lan <dlan@gentoo.org>
Fri, 31 Oct 2025 12:40:46 +0000 (20:40 +0800)
committerYixun Lan <dlan@gentoo.org>
Fri, 9 Jan 2026 02:27:53 +0000 (10:27 +0800)
K3 SoC has the clock IP which support to write value 0 for enabling the
clock, while write 1 for disabling it, thus the enable BIT is inverted.
So, introduce a flag to support the inverted gate clock.

Link: https://lore.kernel.org/r/20260108-k3-clk-v5-2-42a11b74ad58@gentoo.org
Signed-off-by: Yixun Lan <dlan@gentoo.org>
drivers/clk/spacemit/ccu_mix.c
drivers/clk/spacemit/ccu_mix.h

index 67f8b12b4f5b7d2cfcd7fedb53aaf988414fc613..9578366e97466e3383b0d917448b82d7e831092c 100644 (file)
 static void ccu_gate_disable(struct clk_hw *hw)
 {
        struct ccu_mix *mix = hw_to_ccu_mix(hw);
+       struct ccu_gate_config *gate = &mix->gate;
+       u32 val = gate->inverted ? gate->mask : 0;
 
-       ccu_update(&mix->common, ctrl, mix->gate.mask, 0);
+       ccu_update(&mix->common, ctrl, gate->mask, val);
 }
 
 static int ccu_gate_enable(struct clk_hw *hw)
 {
        struct ccu_mix *mix = hw_to_ccu_mix(hw);
        struct ccu_gate_config *gate = &mix->gate;
+       u32 val = gate->inverted ? 0 : gate->mask;
 
-       ccu_update(&mix->common, ctrl, gate->mask, gate->mask);
-
+       ccu_update(&mix->common, ctrl, gate->mask, val);
        return 0;
 }
 
@@ -34,8 +36,10 @@ static int ccu_gate_is_enabled(struct clk_hw *hw)
 {
        struct ccu_mix *mix = hw_to_ccu_mix(hw);
        struct ccu_gate_config *gate = &mix->gate;
+       u32 tmp = ccu_read(&mix->common, ctrl) & gate->mask;
+       u32 val = gate->inverted ? 0 : gate->mask;
 
-       return (ccu_read(&mix->common, ctrl) & gate->mask) == gate->mask;
+       return !!(tmp == val);
 }
 
 static unsigned long ccu_factor_recalc_rate(struct clk_hw *hw,
index c406508e3504efe2cc8681b9d68200c44cb5bb35..dbba9bf49b3bd01952f8e3ba143b827779c7e0fa 100644 (file)
  *
  * @mask:      Mask to enable the gate. Some clocks may have more than one bit
  *             set in this field.
+ * @inverted:  Enable bit is inverted, 1 - disable clock, 0 - enable clock
  */
 struct ccu_gate_config {
        u32 mask;
+       bool inverted;
 };
 
 struct ccu_factor_config {
@@ -48,6 +50,7 @@ struct ccu_mix {
 #define CCU_FACTOR_INIT(_div, _mul)    { .div = _div, .mul = _mul }
 #define CCU_MUX_INIT(_shift, _width)   { .shift = _shift, .width = _width }
 #define CCU_DIV_INIT(_shift, _width)   { .shift = _shift, .width = _width }
+#define CCU_GATE_FLAGS_INIT(_mask, _inverted)  { .mask = _mask, .inverted = _inverted }
 
 #define CCU_PARENT_HW(_parent)         { .hw = &_parent.common.hw }
 #define CCU_PARENT_NAME(_name)         { .fw_name = #_name }
@@ -101,6 +104,15 @@ static struct ccu_mix _name = {                                                    \
        }                                                                       \
 }
 
+#define CCU_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _inverted, _flags)                \
+static struct ccu_mix _name = {                                                        \
+       .gate   = CCU_GATE_FLAGS_INIT(_mask_gate, _inverted),                   \
+       .common = {                                                             \
+               .reg_ctrl       = _reg_ctrl,                                    \
+               CCU_MIX_INITHW(_name, _parent, spacemit_ccu_gate_ops, _flags),  \
+       }                                                                       \
+}
+
 #define CCU_FACTOR_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div,      \
                               _mul, _flags)                                    \
 static struct ccu_mix _name = {                                                        \