1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __CLK_STARFIVE_JH7100_H 3 #define __CLK_STARFIVE_JH7100_H 4 5 #include <linux/bits.h> 6 #include <linux/clk-provider.h> 7 8 /* register fields */ 9 #define JH7100_CLK_ENABLE BIT(31) 10 #define JH7100_CLK_INVERT BIT(30) 11 #define JH7100_CLK_MUX_MASK GENMASK(27, 24) 12 #define JH7100_CLK_MUX_SHIFT 24 13 #define JH7100_CLK_DIV_MASK GENMASK(23, 0) 14 #define JH7100_CLK_FRAC_MASK GENMASK(15, 8) 15 #define JH7100_CLK_FRAC_SHIFT 8 16 #define JH7100_CLK_INT_MASK GENMASK(7, 0) 17 18 /* fractional divider min/max */ 19 #define JH7100_CLK_FRAC_MIN 100UL 20 #define JH7100_CLK_FRAC_MAX 25599UL 21 22 /* clock data */ 23 struct jh7100_clk_data { 24 const char *name; 25 unsigned long flags; 26 u32 max; 27 u8 parents[4]; 28 }; 29 30 #define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \ 31 .name = _name, \ 32 .flags = CLK_SET_RATE_PARENT | (_flags), \ 33 .max = JH7100_CLK_ENABLE, \ 34 .parents = { [0] = _parent }, \ 35 } 36 37 #define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \ 38 .name = _name, \ 39 .flags = 0, \ 40 .max = _max, \ 41 .parents = { [0] = _parent }, \ 42 } 43 44 #define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \ 45 .name = _name, \ 46 .flags = _flags, \ 47 .max = JH7100_CLK_ENABLE | (_max), \ 48 .parents = { [0] = _parent }, \ 49 } 50 51 #define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \ 52 .name = _name, \ 53 .flags = 0, \ 54 .max = JH7100_CLK_FRAC_MAX, \ 55 .parents = { [0] = _parent }, \ 56 } 57 58 #define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \ 59 .name = _name, \ 60 .flags = 0, \ 61 .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \ 62 .parents = { __VA_ARGS__ }, \ 63 } 64 65 #define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \ 66 .name = _name, \ 67 .flags = _flags, \ 68 .max = JH7100_CLK_ENABLE | \ 69 (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \ 70 .parents = { __VA_ARGS__ }, \ 71 } 72 73 #define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \ 74 .name = _name, \ 75 .flags = 0, \ 76 .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \ 77 .parents = { __VA_ARGS__ }, \ 78 } 79 80 #define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \ 81 .name = _name, \ 82 .flags = _flags, \ 83 .max = JH7100_CLK_ENABLE | \ 84 (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \ 85 .parents = { __VA_ARGS__ }, \ 86 } 87 88 #define JH7100__INV(_idx, _name, _parent) [_idx] = { \ 89 .name = _name, \ 90 .flags = CLK_SET_RATE_PARENT, \ 91 .max = JH7100_CLK_INVERT, \ 92 .parents = { [0] = _parent }, \ 93 } 94 95 struct jh7100_clk { 96 struct clk_hw hw; 97 unsigned int idx; 98 unsigned int max_div; 99 }; 100 101 struct jh7100_clk_priv { 102 /* protect clk enable and set rate/parent from happening at the same time */ 103 spinlock_t rmw_lock; 104 struct device *dev; 105 void __iomem *base; 106 struct clk_hw *pll[3]; 107 struct jh7100_clk reg[]; 108 }; 109 110 const struct clk_ops *starfive_jh7100_clk_ops(u32 max); 111 112 #endif 113