Commit 187e5cd2 authored by Xiaolong Zhang's avatar Xiaolong Zhang Committed by Stephen Boyd
Browse files

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: default avatarXiaolong Zhang <xiaolong.zhang@unisoc.com>
Signed-off-by: default avatarChunyan Zhang <chunyan.zhang@unisoc.com>
Link: https://lkml.kernel.org/r/20200304072730.9193-2-zhang.lyra@gmail.com


Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent bb6d3fb3
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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,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);
+19 −2
Original line number Diff line number Diff line
@@ -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,				\
@@ -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_ */