1e19aa786SEmil Renner Berthing /* SPDX-License-Identifier: GPL-2.0 */ 2*147455edSEmil Renner Berthing #ifndef __CLK_STARFIVE_JH71X0_H 3*147455edSEmil Renner Berthing #define __CLK_STARFIVE_JH71X0_H 4e19aa786SEmil Renner Berthing 5e19aa786SEmil Renner Berthing #include <linux/bits.h> 6e19aa786SEmil Renner Berthing #include <linux/clk-provider.h> 7e19aa786SEmil Renner Berthing #include <linux/device.h> 8e19aa786SEmil Renner Berthing #include <linux/spinlock.h> 9e19aa786SEmil Renner Berthing 10e19aa786SEmil Renner Berthing /* register fields */ 11*147455edSEmil Renner Berthing #define JH71X0_CLK_ENABLE BIT(31) 12*147455edSEmil Renner Berthing #define JH71X0_CLK_INVERT BIT(30) 13*147455edSEmil Renner Berthing #define JH71X0_CLK_MUX_MASK GENMASK(27, 24) 14*147455edSEmil Renner Berthing #define JH71X0_CLK_MUX_SHIFT 24 15*147455edSEmil Renner Berthing #define JH71X0_CLK_DIV_MASK GENMASK(23, 0) 16*147455edSEmil Renner Berthing #define JH71X0_CLK_FRAC_MASK GENMASK(15, 8) 17*147455edSEmil Renner Berthing #define JH71X0_CLK_FRAC_SHIFT 8 18*147455edSEmil Renner Berthing #define JH71X0_CLK_INT_MASK GENMASK(7, 0) 19e19aa786SEmil Renner Berthing 20e19aa786SEmil Renner Berthing /* fractional divider min/max */ 21*147455edSEmil Renner Berthing #define JH71X0_CLK_FRAC_MIN 100UL 22*147455edSEmil Renner Berthing #define JH71X0_CLK_FRAC_MAX 25599UL 23e19aa786SEmil Renner Berthing 24e19aa786SEmil Renner Berthing /* clock data */ 25*147455edSEmil Renner Berthing struct jh71x0_clk_data { 26e19aa786SEmil Renner Berthing const char *name; 27e19aa786SEmil Renner Berthing unsigned long flags; 28e19aa786SEmil Renner Berthing u32 max; 29e19aa786SEmil Renner Berthing u8 parents[4]; 30e19aa786SEmil Renner Berthing }; 31e19aa786SEmil Renner Berthing 32*147455edSEmil Renner Berthing #define JH71X0_GATE(_idx, _name, _flags, _parent) \ 33*147455edSEmil Renner Berthing [_idx] = { \ 34e19aa786SEmil Renner Berthing .name = _name, \ 35e19aa786SEmil Renner Berthing .flags = CLK_SET_RATE_PARENT | (_flags), \ 36*147455edSEmil Renner Berthing .max = JH71X0_CLK_ENABLE, \ 37e19aa786SEmil Renner Berthing .parents = { [0] = _parent }, \ 38e19aa786SEmil Renner Berthing } 39e19aa786SEmil Renner Berthing 40*147455edSEmil Renner Berthing #define JH71X0__DIV(_idx, _name, _max, _parent) \ 41*147455edSEmil Renner Berthing [_idx] = { \ 42e19aa786SEmil Renner Berthing .name = _name, \ 43e19aa786SEmil Renner Berthing .flags = 0, \ 44e19aa786SEmil Renner Berthing .max = _max, \ 45e19aa786SEmil Renner Berthing .parents = { [0] = _parent }, \ 46e19aa786SEmil Renner Berthing } 47e19aa786SEmil Renner Berthing 48*147455edSEmil Renner Berthing #define JH71X0_GDIV(_idx, _name, _flags, _max, _parent) \ 49*147455edSEmil Renner Berthing [_idx] = { \ 50e19aa786SEmil Renner Berthing .name = _name, \ 51e19aa786SEmil Renner Berthing .flags = _flags, \ 52*147455edSEmil Renner Berthing .max = JH71X0_CLK_ENABLE | (_max), \ 53e19aa786SEmil Renner Berthing .parents = { [0] = _parent }, \ 54e19aa786SEmil Renner Berthing } 55e19aa786SEmil Renner Berthing 56*147455edSEmil Renner Berthing #define JH71X0_FDIV(_idx, _name, _parent) \ 57*147455edSEmil Renner Berthing [_idx] = { \ 58e19aa786SEmil Renner Berthing .name = _name, \ 59e19aa786SEmil Renner Berthing .flags = 0, \ 60*147455edSEmil Renner Berthing .max = JH71X0_CLK_FRAC_MAX, \ 61e19aa786SEmil Renner Berthing .parents = { [0] = _parent }, \ 62e19aa786SEmil Renner Berthing } 63e19aa786SEmil Renner Berthing 64*147455edSEmil Renner Berthing #define JH71X0__MUX(_idx, _name, _nparents, ...) \ 65*147455edSEmil Renner Berthing [_idx] = { \ 66e19aa786SEmil Renner Berthing .name = _name, \ 67e19aa786SEmil Renner Berthing .flags = 0, \ 68*147455edSEmil Renner Berthing .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \ 69e19aa786SEmil Renner Berthing .parents = { __VA_ARGS__ }, \ 70e19aa786SEmil Renner Berthing } 71e19aa786SEmil Renner Berthing 72*147455edSEmil Renner Berthing #define JH71X0_GMUX(_idx, _name, _flags, _nparents, ...) \ 73*147455edSEmil Renner Berthing [_idx] = { \ 74e19aa786SEmil Renner Berthing .name = _name, \ 75e19aa786SEmil Renner Berthing .flags = _flags, \ 76*147455edSEmil Renner Berthing .max = JH71X0_CLK_ENABLE | \ 77*147455edSEmil Renner Berthing (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT), \ 78e19aa786SEmil Renner Berthing .parents = { __VA_ARGS__ }, \ 79e19aa786SEmil Renner Berthing } 80e19aa786SEmil Renner Berthing 81*147455edSEmil Renner Berthing #define JH71X0_MDIV(_idx, _name, _max, _nparents, ...) \ 82*147455edSEmil Renner Berthing [_idx] = { \ 83e19aa786SEmil Renner Berthing .name = _name, \ 84e19aa786SEmil Renner Berthing .flags = 0, \ 85*147455edSEmil Renner Berthing .max = (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \ 86e19aa786SEmil Renner Berthing .parents = { __VA_ARGS__ }, \ 87e19aa786SEmil Renner Berthing } 88e19aa786SEmil Renner Berthing 89*147455edSEmil Renner Berthing #define JH71X0__GMD(_idx, _name, _flags, _max, _nparents, ...) \ 90*147455edSEmil Renner Berthing [_idx] = { \ 91e19aa786SEmil Renner Berthing .name = _name, \ 92e19aa786SEmil Renner Berthing .flags = _flags, \ 93*147455edSEmil Renner Berthing .max = JH71X0_CLK_ENABLE | \ 94*147455edSEmil Renner Berthing (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \ 95e19aa786SEmil Renner Berthing .parents = { __VA_ARGS__ }, \ 96e19aa786SEmil Renner Berthing } 97e19aa786SEmil Renner Berthing 98*147455edSEmil Renner Berthing #define JH71X0__INV(_idx, _name, _parent) \ 99*147455edSEmil Renner Berthing [_idx] = { \ 100e19aa786SEmil Renner Berthing .name = _name, \ 101e19aa786SEmil Renner Berthing .flags = CLK_SET_RATE_PARENT, \ 102*147455edSEmil Renner Berthing .max = JH71X0_CLK_INVERT, \ 103e19aa786SEmil Renner Berthing .parents = { [0] = _parent }, \ 104e19aa786SEmil Renner Berthing } 105e19aa786SEmil Renner Berthing 106*147455edSEmil Renner Berthing struct jh71x0_clk { 107e19aa786SEmil Renner Berthing struct clk_hw hw; 108e19aa786SEmil Renner Berthing unsigned int idx; 109e19aa786SEmil Renner Berthing unsigned int max_div; 110e19aa786SEmil Renner Berthing }; 111e19aa786SEmil Renner Berthing 112*147455edSEmil Renner Berthing struct jh71x0_clk_priv { 113e19aa786SEmil Renner Berthing /* protect clk enable and set rate/parent from happening at the same time */ 114e19aa786SEmil Renner Berthing spinlock_t rmw_lock; 115e19aa786SEmil Renner Berthing struct device *dev; 116e19aa786SEmil Renner Berthing void __iomem *base; 117e19aa786SEmil Renner Berthing struct clk_hw *pll[3]; 118*147455edSEmil Renner Berthing struct jh71x0_clk reg[]; 119e19aa786SEmil Renner Berthing }; 120e19aa786SEmil Renner Berthing 121*147455edSEmil Renner Berthing const struct clk_ops *starfive_jh71x0_clk_ops(u32 max); 122e19aa786SEmil Renner Berthing 123e19aa786SEmil Renner Berthing #endif 124