[RFC PATCH v1 03/14] clk: thead: Enable clock gates with regmaps
Michal Wilczynski
m.wilczynski at samsung.com
Tue Dec 3 05:41:26 PST 2024
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 at samsung.com>
---
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
More information about the linux-riscv
mailing list