Linux Audio

Check our new training course

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