Commit 48a8748f authored by Zhifeng Tang's avatar Zhifeng Tang Committed by Stephen Boyd
Browse files

clk: sprd: Composite driver support offset config



The composite interface support the offset configuration,
which is used to support mux and div in different registers.
Because some sprd projects, the divider has different
addresses from mux for one composite clk.

Signed-off-by: default avatarZhifeng Tang <zhifeng.tang@unisoc.com>
Reviewed-by: default avatarChunyan Zhang <zhang.lyra@gmail.com>
Link: https://lore.kernel.org/r/20230913115211.11512-1-zhifeng.tang@unisoc.com


Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 0bb80ecc
Loading
Loading
Loading
Loading
+27 −9
Original line number Diff line number Diff line
@@ -19,11 +19,11 @@ struct sprd_comp {
};

#define SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table,	\
				 _mshift, _mwidth, _dshift, _dwidth,	\
				 _flags, _fn)				\
				 _mshift, _mwidth, _doffset, _dshift,	\
				 _dwidth, _flags, _fn)			\
	struct sprd_comp _struct = {					\
		.mux	= _SPRD_MUX_CLK(_mshift, _mwidth, _table),	\
		.div	= _SPRD_DIV_CLK(_dshift, _dwidth),		\
		.div	= _SPRD_DIV_CLK(_doffset, _dshift, _dwidth),	\
		.common = {						\
			.regmap		= NULL,				\
			.reg		= _reg,				\
@@ -35,8 +35,8 @@ struct sprd_comp {
#define SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, _table,	\
			    _mshift, _mwidth, _dshift, _dwidth, _flags)	\
	SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table,	\
				 _mshift, _mwidth, _dshift, _dwidth,	\
				 _flags, CLK_HW_INIT_PARENTS)
				 _mshift, _mwidth, 0x0, _dshift,	\
				 _dwidth, _flags, CLK_HW_INIT_PARENTS)

#define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _mshift,		\
		      _mwidth, _dshift, _dwidth, _flags)		\
@@ -47,8 +47,9 @@ struct sprd_comp {
				 _mshift, _mwidth, _dshift,		\
				 _dwidth, _flags)			\
	SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table,	\
				 _mshift, _mwidth, _dshift, _dwidth,	\
				 _flags, CLK_HW_INIT_PARENTS_DATA)
				 _mshift, _mwidth, 0x0, _dshift,	\
				 _dwidth, _flags,			\
				 CLK_HW_INIT_PARENTS_DATA)

#define SPRD_COMP_CLK_DATA(_struct, _name, _parent, _reg, _mshift,	\
			   _mwidth, _dshift, _dwidth, _flags)		\
@@ -56,6 +57,23 @@ struct sprd_comp {
				 _mshift, _mwidth, _dshift, _dwidth,	\
				 _flags)

#define SPRD_COMP_CLK_DATA_TABLE_OFFSET(_struct, _name, _parent, _reg,	\
					_table, _mshift, _mwidth,	\
					_doffset, _dshift, _dwidth,	\
					_flags)				\
	SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table,	\
				 _mshift, _mwidth, _doffset, _dshift,	\
				 _dwidth, _flags,			\
				 CLK_HW_INIT_PARENTS_DATA)

#define SPRD_COMP_CLK_DATA_OFFSET(_struct, _name, _parent, _reg,	\
				  _mshift, _mwidth, _doffset, _dshift,	\
				  _dwidth, _flags)			\
	SPRD_COMP_CLK_DATA_TABLE_OFFSET(_struct, _name, _parent, _reg,	\
					NULL, _mshift, _mwidth,		\
					_doffset, _dshift, _dwidth,	\
					_flags)

static inline struct sprd_comp *hw_to_sprd_comp(const struct clk_hw *hw)
{
	struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
+3 −3
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
	unsigned long val;
	unsigned int reg;

	regmap_read(common->regmap, common->reg, &reg);
	regmap_read(common->regmap, common->reg + div->offset, &reg);
	val = reg >> div->shift;
	val &= (1 << div->width) - 1;

@@ -53,10 +53,10 @@ int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
	val = divider_get_val(rate, parent_rate, NULL,
			      div->width, 0);

	regmap_read(common->regmap, common->reg, &reg);
	regmap_read(common->regmap, common->reg + div->offset, &reg);
	reg &= ~GENMASK(div->width + div->shift - 1, div->shift);

	regmap_write(common->regmap, common->reg,
	regmap_write(common->regmap, common->reg + div->offset,
			  reg | (val << div->shift));

	return 0;
+12 −5
Original line number Diff line number Diff line
@@ -20,12 +20,14 @@
 * classes.
 */
struct sprd_div_internal {
	s32	offset;
	u8	shift;
	u8	width;
};

#define _SPRD_DIV_CLK(_shift, _width)	\
#define _SPRD_DIV_CLK(_offset, _shift, _width)	\
	{				\
		.offset = _offset,	\
		.shift	= _shift,	\
		.width	= _width,	\
	}
@@ -35,10 +37,10 @@ struct sprd_div {
	struct sprd_clk_common	common;
};

#define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,		\
#define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _offset,	\
				_shift, _width, _flags, _fn)		\
	struct sprd_div _struct = {					\
		.div	= _SPRD_DIV_CLK(_shift, _width),		\
		.div	= _SPRD_DIV_CLK(_offset, _shift, _width),	\
		.common	= {						\
			.regmap		= NULL,				\
			.reg		= _reg,				\
@@ -49,12 +51,17 @@ struct sprd_div {

#define SPRD_DIV_CLK(_struct, _name, _parent, _reg,			\
		     _shift, _width, _flags)				\
	SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,		\
	SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0,	\
				_shift, _width, _flags, CLK_HW_INIT)

#define SPRD_DIV_CLK_FW_NAME(_struct, _name, _parent, _reg,		\
			_shift, _width, _flags)				\
	SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0,	\
				_shift, _width, _flags, CLK_HW_INIT_FW_NAME)

#define SPRD_DIV_CLK_HW(_struct, _name, _parent, _reg,			\
			_shift, _width, _flags)				\
	SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg,		\
	SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0,	\
				_shift, _width, _flags, CLK_HW_INIT_HW)

static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw)