Messages in this thread Patch in this message | | | From | Chunyan Zhang <> | Subject | [PATCH 1/5] clk: sprd: add gate for pll clocks | Date | Fri, 25 Oct 2019 19:13:34 +0800 |
| |
From: Xiaolong Zhang <xiaolong.zhang@unisoc.com>
Some sprd's gate clocks are used to the switch of pll, which need to wait a certain time for stable after being enabled.
Signed-off-by: Xiaolong Zhang <xiaolong.zhang@unisoc.com> Signed-off-by: Chunyan Zhang <chunyan.zhang@unisoc.com> --- drivers/clk/sprd/gate.c | 19 +++++++++++++++++++ drivers/clk/sprd/gate.h | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/sprd/gate.c b/drivers/clk/sprd/gate.c index f59d1936b412..d8b480f852f3 100644 --- a/drivers/clk/sprd/gate.c +++ b/drivers/clk/sprd/gate.c @@ -79,6 +79,17 @@ static int sprd_sc_gate_enable(struct clk_hw *hw) return 0; } + +static int sprd_pll_sc_gate_prepare(struct clk_hw *hw) +{ + struct sprd_gate *sg = hw_to_sprd_gate(hw); + + clk_sc_gate_toggle(sg, true); + udelay(sg->udelay); + + return 0; +} + static int sprd_gate_is_enabled(struct clk_hw *hw) { struct sprd_gate *sg = hw_to_sprd_gate(hw); @@ -109,3 +120,11 @@ const struct clk_ops sprd_sc_gate_ops = { }; EXPORT_SYMBOL_GPL(sprd_sc_gate_ops); +#define sprd_pll_sc_gate_unprepare sprd_sc_gate_disable + +const struct clk_ops sprd_pll_sc_gate_ops = { + .unprepare = sprd_pll_sc_gate_unprepare, + .prepare = sprd_pll_sc_gate_prepare, + .is_enabled = sprd_gate_is_enabled, +}; +EXPORT_SYMBOL_GPL(sprd_pll_sc_gate_ops); diff --git a/drivers/clk/sprd/gate.h b/drivers/clk/sprd/gate.h index dc352ea55e1f..598ce607ca0a 100644 --- a/drivers/clk/sprd/gate.h +++ b/drivers/clk/sprd/gate.h @@ -14,16 +14,19 @@ struct sprd_gate { u32 enable_mask; u16 flags; u16 sc_offset; + u32 udelay; struct sprd_clk_common common; }; -#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ - _enable_mask, _flags, _gate_flags, _ops) \ +#define SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops) \ struct sprd_gate _struct = { \ .enable_mask = _enable_mask, \ .sc_offset = _sc_offset, \ .flags = _gate_flags, \ + .udelay = _udelay, \ .common = { \ .regmap = NULL, \ .reg = _reg, \ @@ -34,6 +37,12 @@ struct sprd_gate { } \ } +#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ + _enable_mask, _flags, _gate_flags, _ops) \ + SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, 0, _ops) + #define SPRD_GATE_CLK(_struct, _name, _parent, _reg, \ _enable_mask, _flags, _gate_flags) \ SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, 0, \ @@ -46,6 +55,13 @@ struct sprd_gate { _enable_mask, _flags, _gate_flags, \ &sprd_sc_gate_ops) +#define SPRD_PLL_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset, \ + _enable_mask, _flags, _gate_flags, _udelay) \ + SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, \ + &sprd_pll_sc_gate_ops) + static inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw) { struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); @@ -55,5 +71,6 @@ static inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw) extern const struct clk_ops sprd_gate_ops; extern const struct clk_ops sprd_sc_gate_ops; +extern const struct clk_ops sprd_pll_sc_gate_ops; #endif /* _SPRD_GATE_H_ */ -- 2.20.1
| |