Skip to content

Commit

Permalink
clk: sprd: add gate for pll clocks
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Xiaolong Zhang authored and Stephen Boyd committed Mar 25, 2020
1 parent bb6d3fb commit 187e5cd
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
17 changes: 17 additions & 0 deletions drivers/clk/sprd/gate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -109,3 +120,9 @@ const struct clk_ops sprd_sc_gate_ops = {
};
EXPORT_SYMBOL_GPL(sprd_sc_gate_ops);

const struct clk_ops sprd_pll_sc_gate_ops = {
.unprepare = sprd_sc_gate_disable,
.prepare = sprd_pll_sc_gate_prepare,
.is_enabled = sprd_gate_is_enabled,
};
EXPORT_SYMBOL_GPL(sprd_pll_sc_gate_ops);
21 changes: 19 additions & 2 deletions drivers/clk/sprd/gate.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ struct sprd_gate {
u32 enable_mask;
u16 flags;
u16 sc_offset;
u16 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, \
Expand All @@ -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, \
Expand All @@ -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);
Expand All @@ -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_ */

0 comments on commit 187e5cd

Please sign in to comment.