Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: sprd: add gate for pll clocks

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>
Link: https://lkml.kernel.org/r/20200304072730.9193-2-zhang.lyra@gmail.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Xiaolong Zhang and committed by
Stephen Boyd
187e5cd2 bb6d3fb3

+36 -2
+17
drivers/clk/sprd/gate.c
··· 79 79 80 80 return 0; 81 81 } 82 + 83 + static int sprd_pll_sc_gate_prepare(struct clk_hw *hw) 84 + { 85 + struct sprd_gate *sg = hw_to_sprd_gate(hw); 86 + 87 + clk_sc_gate_toggle(sg, true); 88 + udelay(sg->udelay); 89 + 90 + return 0; 91 + } 92 + 82 93 static int sprd_gate_is_enabled(struct clk_hw *hw) 83 94 { 84 95 struct sprd_gate *sg = hw_to_sprd_gate(hw); ··· 120 109 }; 121 110 EXPORT_SYMBOL_GPL(sprd_sc_gate_ops); 122 111 112 + const struct clk_ops sprd_pll_sc_gate_ops = { 113 + .unprepare = sprd_sc_gate_disable, 114 + .prepare = sprd_pll_sc_gate_prepare, 115 + .is_enabled = sprd_gate_is_enabled, 116 + }; 117 + EXPORT_SYMBOL_GPL(sprd_pll_sc_gate_ops);
+19 -2
drivers/clk/sprd/gate.h
··· 14 14 u32 enable_mask; 15 15 u16 flags; 16 16 u16 sc_offset; 17 + u16 udelay; 17 18 18 19 struct sprd_clk_common common; 19 20 }; 20 21 21 - #define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ 22 - _enable_mask, _flags, _gate_flags, _ops) \ 22 + #define SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ 23 + _sc_offset, _enable_mask, _flags, \ 24 + _gate_flags, _udelay, _ops) \ 23 25 struct sprd_gate _struct = { \ 24 26 .enable_mask = _enable_mask, \ 25 27 .sc_offset = _sc_offset, \ 26 28 .flags = _gate_flags, \ 29 + .udelay = _udelay, \ 27 30 .common = { \ 28 31 .regmap = NULL, \ 29 32 .reg = _reg, \ ··· 36 33 _flags), \ 37 34 } \ 38 35 } 36 + 37 + #define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ 38 + _enable_mask, _flags, _gate_flags, _ops) \ 39 + SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ 40 + _sc_offset, _enable_mask, _flags, \ 41 + _gate_flags, 0, _ops) 39 42 40 43 #define SPRD_GATE_CLK(_struct, _name, _parent, _reg, \ 41 44 _enable_mask, _flags, _gate_flags) \ ··· 55 46 _enable_mask, _flags, _gate_flags, \ 56 47 &sprd_sc_gate_ops) 57 48 49 + #define SPRD_PLL_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset, \ 50 + _enable_mask, _flags, _gate_flags, _udelay) \ 51 + SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ 52 + _sc_offset, _enable_mask, _flags, \ 53 + _gate_flags, _udelay, \ 54 + &sprd_pll_sc_gate_ops) 55 + 58 56 static inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw) 59 57 { 60 58 struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); ··· 71 55 72 56 extern const struct clk_ops sprd_gate_ops; 73 57 extern const struct clk_ops sprd_sc_gate_ops; 58 + extern const struct clk_ops sprd_pll_sc_gate_ops; 74 59 75 60 #endif /* _SPRD_GATE_H_ */