2022-01-26 18:39:51 +01:00
/* SPDX-License-Identifier: GPL-2.0 */
2023-04-01 19:19:18 +08:00
# ifndef __CLK_STARFIVE_JH71X0_H
# define __CLK_STARFIVE_JH71X0_H
2022-01-26 18:39:51 +01:00
# include <linux/bits.h>
# include <linux/clk-provider.h>
2023-04-01 19:19:16 +08:00
# include <linux/device.h>
# include <linux/spinlock.h>
2022-01-26 18:39:51 +01:00
/* register fields */
2023-04-01 19:19:18 +08:00
# define JH71X0_CLK_ENABLE BIT(31)
# define JH71X0_CLK_INVERT BIT(30)
# define JH71X0_CLK_MUX_MASK GENMASK(27, 24)
# define JH71X0_CLK_MUX_SHIFT 24
# define JH71X0_CLK_DIV_MASK GENMASK(23, 0)
# define JH71X0_CLK_FRAC_MASK GENMASK(15, 8)
# define JH71X0_CLK_FRAC_SHIFT 8
# define JH71X0_CLK_INT_MASK GENMASK(7, 0)
2022-01-26 18:39:51 +01:00
/* fractional divider min/max */
2023-04-01 19:19:18 +08:00
# define JH71X0_CLK_FRAC_MIN 100UL
# define JH71X0_CLK_FRAC_MAX 25599UL
2022-01-26 18:39:51 +01:00
/* clock data */
2023-04-01 19:19:18 +08:00
struct jh71x0_clk_data {
2022-01-26 18:39:51 +01:00
const char * name ;
unsigned long flags ;
u32 max ;
u8 parents [ 4 ] ;
} ;
2023-04-01 19:19:18 +08:00
# define JH71X0_GATE(_idx, _name, _flags, _parent) \
[ _idx ] = { \
2022-01-26 18:39:51 +01:00
. name = _name , \
. flags = CLK_SET_RATE_PARENT | ( _flags ) , \
2023-04-01 19:19:18 +08:00
. max = JH71X0_CLK_ENABLE , \
2022-01-26 18:39:51 +01:00
. parents = { [ 0 ] = _parent } , \
}
2023-04-01 19:19:18 +08:00
# define JH71X0__DIV(_idx, _name, _max, _parent) \
[ _idx ] = { \
2022-01-26 18:39:51 +01:00
. name = _name , \
. flags = 0 , \
. max = _max , \
. parents = { [ 0 ] = _parent } , \
}
2023-04-01 19:19:18 +08:00
# define JH71X0_GDIV(_idx, _name, _flags, _max, _parent) \
[ _idx ] = { \
2022-01-26 18:39:51 +01:00
. name = _name , \
. flags = _flags , \
2023-04-01 19:19:18 +08:00
. max = JH71X0_CLK_ENABLE | ( _max ) , \
2022-01-26 18:39:51 +01:00
. parents = { [ 0 ] = _parent } , \
}
2023-04-01 19:19:18 +08:00
# define JH71X0_FDIV(_idx, _name, _parent) \
[ _idx ] = { \
2022-01-26 18:39:51 +01:00
. name = _name , \
. flags = 0 , \
2023-04-01 19:19:18 +08:00
. max = JH71X0_CLK_FRAC_MAX , \
2022-01-26 18:39:51 +01:00
. parents = { [ 0 ] = _parent } , \
}
2023-04-01 19:19:18 +08:00
# define JH71X0__MUX(_idx, _name, _nparents, ...) \
[ _idx ] = { \
2022-01-26 18:39:51 +01:00
. name = _name , \
. flags = 0 , \
2023-04-01 19:19:18 +08:00
. max = ( ( _nparents ) - 1 ) < < JH71X0_CLK_MUX_SHIFT , \
2022-01-26 18:39:51 +01:00
. parents = { __VA_ARGS__ } , \
}
2023-04-01 19:19:18 +08:00
# define JH71X0_GMUX(_idx, _name, _flags, _nparents, ...) \
[ _idx ] = { \
2022-01-26 18:39:51 +01:00
. name = _name , \
. flags = _flags , \
2023-04-01 19:19:18 +08:00
. max = JH71X0_CLK_ENABLE | \
( ( ( _nparents ) - 1 ) < < JH71X0_CLK_MUX_SHIFT ) , \
2022-01-26 18:39:51 +01:00
. parents = { __VA_ARGS__ } , \
}
2023-04-01 19:19:18 +08:00
# define JH71X0_MDIV(_idx, _name, _max, _nparents, ...) \
[ _idx ] = { \
2022-01-26 18:39:52 +01:00
. name = _name , \
. flags = 0 , \
2023-04-01 19:19:18 +08:00
. max = ( ( ( _nparents ) - 1 ) < < JH71X0_CLK_MUX_SHIFT ) | ( _max ) , \
2022-01-26 18:39:52 +01:00
. parents = { __VA_ARGS__ } , \
}
2023-04-01 19:19:18 +08:00
# define JH71X0__GMD(_idx, _name, _flags, _max, _nparents, ...) \
[ _idx ] = { \
2022-01-26 18:39:52 +01:00
. name = _name , \
. flags = _flags , \
2023-04-01 19:19:18 +08:00
. max = JH71X0_CLK_ENABLE | \
( ( ( _nparents ) - 1 ) < < JH71X0_CLK_MUX_SHIFT ) | ( _max ) , \
2022-01-26 18:39:52 +01:00
. parents = { __VA_ARGS__ } , \
}
2023-04-01 19:19:18 +08:00
# define JH71X0__INV(_idx, _name, _parent) \
[ _idx ] = { \
2022-01-26 18:39:51 +01:00
. name = _name , \
. flags = CLK_SET_RATE_PARENT , \
2023-04-01 19:19:18 +08:00
. max = JH71X0_CLK_INVERT , \
2022-01-26 18:39:51 +01:00
. parents = { [ 0 ] = _parent } , \
}
2023-04-01 19:19:18 +08:00
struct jh71x0_clk {
2022-01-26 18:39:51 +01:00
struct clk_hw hw ;
unsigned int idx ;
unsigned int max_div ;
} ;
2023-04-01 19:19:18 +08:00
struct jh71x0_clk_priv {
2022-01-26 18:39:51 +01:00
/* protect clk enable and set rate/parent from happening at the same time */
spinlock_t rmw_lock ;
struct device * dev ;
void __iomem * base ;
struct clk_hw * pll [ 3 ] ;
2023-04-01 19:19:18 +08:00
struct jh71x0_clk reg [ ] ;
2022-01-26 18:39:51 +01:00
} ;
2023-04-01 19:19:18 +08:00
const struct clk_ops * starfive_jh71x0_clk_ops ( u32 max ) ;
2022-01-26 18:39:51 +01:00
# endif