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

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: Zhifeng Tang <zhifeng.tang@unisoc.com>
Reviewed-by: Chunyan Zhang <zhang.lyra@gmail.com>
Link: https://lore.kernel.org/r/20230913115211.11512-1-zhifeng.tang@unisoc.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Zhifeng Tang and committed by
Stephen Boyd
48a8748f 0bb80ecc

+42 -17
+27 -9
drivers/clk/sprd/composite.h
··· 19 19 }; 20 20 21 21 #define SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ 22 - _mshift, _mwidth, _dshift, _dwidth, \ 23 - _flags, _fn) \ 22 + _mshift, _mwidth, _doffset, _dshift, \ 23 + _dwidth, _flags, _fn) \ 24 24 struct sprd_comp _struct = { \ 25 25 .mux = _SPRD_MUX_CLK(_mshift, _mwidth, _table), \ 26 - .div = _SPRD_DIV_CLK(_dshift, _dwidth), \ 26 + .div = _SPRD_DIV_CLK(_doffset, _dshift, _dwidth), \ 27 27 .common = { \ 28 28 .regmap = NULL, \ 29 29 .reg = _reg, \ 30 30 .hw.init = _fn(_name, _parent, \ 31 31 &sprd_comp_ops, _flags), \ 32 - } \ 32 + } \ 33 33 } 34 34 35 35 #define SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, _table, \ 36 36 _mshift, _mwidth, _dshift, _dwidth, _flags) \ 37 37 SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ 38 - _mshift, _mwidth, _dshift, _dwidth, \ 39 - _flags, CLK_HW_INIT_PARENTS) 38 + _mshift, _mwidth, 0x0, _dshift, \ 39 + _dwidth, _flags, CLK_HW_INIT_PARENTS) 40 40 41 41 #define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _mshift, \ 42 42 _mwidth, _dshift, _dwidth, _flags) \ ··· 47 47 _mshift, _mwidth, _dshift, \ 48 48 _dwidth, _flags) \ 49 49 SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ 50 - _mshift, _mwidth, _dshift, _dwidth, \ 51 - _flags, CLK_HW_INIT_PARENTS_DATA) 50 + _mshift, _mwidth, 0x0, _dshift, \ 51 + _dwidth, _flags, \ 52 + CLK_HW_INIT_PARENTS_DATA) 52 53 53 54 #define SPRD_COMP_CLK_DATA(_struct, _name, _parent, _reg, _mshift, \ 54 55 _mwidth, _dshift, _dwidth, _flags) \ 55 - SPRD_COMP_CLK_DATA_TABLE(_struct, _name, _parent, _reg, NULL, \ 56 + SPRD_COMP_CLK_DATA_TABLE(_struct, _name, _parent, _reg, NULL, \ 56 57 _mshift, _mwidth, _dshift, _dwidth, \ 57 58 _flags) 59 + 60 + #define SPRD_COMP_CLK_DATA_TABLE_OFFSET(_struct, _name, _parent, _reg, \ 61 + _table, _mshift, _mwidth, \ 62 + _doffset, _dshift, _dwidth, \ 63 + _flags) \ 64 + SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ 65 + _mshift, _mwidth, _doffset, _dshift, \ 66 + _dwidth, _flags, \ 67 + CLK_HW_INIT_PARENTS_DATA) 68 + 69 + #define SPRD_COMP_CLK_DATA_OFFSET(_struct, _name, _parent, _reg, \ 70 + _mshift, _mwidth, _doffset, _dshift, \ 71 + _dwidth, _flags) \ 72 + SPRD_COMP_CLK_DATA_TABLE_OFFSET(_struct, _name, _parent, _reg, \ 73 + NULL, _mshift, _mwidth, \ 74 + _doffset, _dshift, _dwidth, \ 75 + _flags) 58 76 59 77 static inline struct sprd_comp *hw_to_sprd_comp(const struct clk_hw *hw) 60 78 {
+3 -3
drivers/clk/sprd/div.c
··· 25 25 unsigned long val; 26 26 unsigned int reg; 27 27 28 - regmap_read(common->regmap, common->reg, &reg); 28 + regmap_read(common->regmap, common->reg + div->offset, &reg); 29 29 val = reg >> div->shift; 30 30 val &= (1 << div->width) - 1; 31 31 ··· 53 53 val = divider_get_val(rate, parent_rate, NULL, 54 54 div->width, 0); 55 55 56 - regmap_read(common->regmap, common->reg, &reg); 56 + regmap_read(common->regmap, common->reg + div->offset, &reg); 57 57 reg &= ~GENMASK(div->width + div->shift - 1, div->shift); 58 58 59 - regmap_write(common->regmap, common->reg, 59 + regmap_write(common->regmap, common->reg + div->offset, 60 60 reg | (val << div->shift)); 61 61 62 62 return 0;
+12 -5
drivers/clk/sprd/div.h
··· 20 20 * classes. 21 21 */ 22 22 struct sprd_div_internal { 23 + s32 offset; 23 24 u8 shift; 24 25 u8 width; 25 26 }; 26 27 27 - #define _SPRD_DIV_CLK(_shift, _width) \ 28 + #define _SPRD_DIV_CLK(_offset, _shift, _width) \ 28 29 { \ 30 + .offset = _offset, \ 29 31 .shift = _shift, \ 30 32 .width = _width, \ 31 33 } ··· 37 35 struct sprd_clk_common common; 38 36 }; 39 37 40 - #define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ 38 + #define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _offset, \ 41 39 _shift, _width, _flags, _fn) \ 42 40 struct sprd_div _struct = { \ 43 - .div = _SPRD_DIV_CLK(_shift, _width), \ 41 + .div = _SPRD_DIV_CLK(_offset, _shift, _width), \ 44 42 .common = { \ 45 43 .regmap = NULL, \ 46 44 .reg = _reg, \ ··· 51 49 52 50 #define SPRD_DIV_CLK(_struct, _name, _parent, _reg, \ 53 51 _shift, _width, _flags) \ 54 - SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ 52 + SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0, \ 55 53 _shift, _width, _flags, CLK_HW_INIT) 54 + 55 + #define SPRD_DIV_CLK_FW_NAME(_struct, _name, _parent, _reg, \ 56 + _shift, _width, _flags) \ 57 + SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0, \ 58 + _shift, _width, _flags, CLK_HW_INIT_FW_NAME) 56 59 57 60 #define SPRD_DIV_CLK_HW(_struct, _name, _parent, _reg, \ 58 61 _shift, _width, _flags) \ 59 - SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ 62 + SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0, \ 60 63 _shift, _width, _flags, CLK_HW_INIT_HW) 61 64 62 65 static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw)