The current implementation of the CCU_GATE macro assumes direct access to memory-mapped registers, which isn't suitable when using regmaps for register access. In the TH1520 SoC, the address space for the VO (Video Output) subsystem clocks is shared with other control registers, such as those used for resetting the GPU. To prevent conflicts and ensure synchronized access, it's important to access these registers via a regmap. This patch updates the CCU_GATE macro to support regmap-based access by reusing the clk_ops from the divider clocks (ccu_div_ops). This change allows the clock gates to be controlled through regmap, enabling proper synchronization when multiple components interact with the shared address space. Signed-off-by: Michal Wilczynski <m.wilczynski@xxxxxxxxxxx> --- drivers/clk/thead/clk-th1520.c | 10 ++++++++-- drivers/clk/thead/clk-th1520.h | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/clk/thead/clk-th1520.c b/drivers/clk/thead/clk-th1520.c index e2bfe56de9af..3ada8b98bd8e 100644 --- a/drivers/clk/thead/clk-th1520.c +++ b/drivers/clk/thead/clk-th1520.c @@ -120,8 +120,14 @@ const struct clk_ops ccu_div_ops = { .determine_rate = clk_hw_determine_rate_no_reparent, }; -static unsigned long th1520_pll_vco_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) +const struct clk_ops ccu_gate_ops = { + .disable = ccu_div_disable, + .enable = ccu_div_enable, + .is_enabled = ccu_div_is_enabled, +}; + +unsigned long th1520_pll_vco_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) { struct ccu_pll *pll = hw_to_ccu_pll(hw); unsigned long div, mul, frac; diff --git a/drivers/clk/thead/clk-th1520.h b/drivers/clk/thead/clk-th1520.h index 5d30f55e88a1..532afbbfea01 100644 --- a/drivers/clk/thead/clk-th1520.h +++ b/drivers/clk/thead/clk-th1520.h @@ -94,6 +94,20 @@ struct ccu_pll { } \ } +#define CCU_GATE_REGMAP(_clkid, _struct, _name, _parent, _reg, _gate, _flags) \ + struct ccu_gate _struct = { \ + .enable = _gate, \ + .common = { \ + .clkid = _clkid, \ + .cfg0 = _reg, \ + .hw.init = CLK_HW_INIT_PARENTS_DATA( \ + _name, \ + _parent, \ + &ccu_gate_ops, \ + _flags), \ + } \ + } + static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) { return container_of(hw, struct ccu_common, hw); @@ -130,5 +144,6 @@ static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw) extern const struct clk_ops ccu_div_ops; extern const struct clk_ops clk_pll_ops; extern const struct regmap_config th1520_clk_regmap_config; +extern const struct clk_ops ccu_gate_ops; #endif /* CLK_TH1520_H */ -- 2.34.1