Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1/*
  2 * Copyright (c) 2015 Endless Mobile, Inc.
  3 * Author: Carlo Caione <carlo@endlessm.com>
  4 *
  5 * This program is free software; you can redistribute it and/or modify it
  6 * under the terms and conditions of the GNU General Public License,
  7 * version 2, as published by the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope it will be useful, but WITHOUT
 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 12 * more details.
 13 *
 14 * You should have received a copy of the GNU General Public License along with
 15 * this program.  If not, see <http://www.gnu.org/licenses/>.
 16 */
 17
 18#ifndef __CLKC_H
 19#define __CLKC_H
 20
 21#define PMASK(width)			GENMASK(width - 1, 0)
 22#define SETPMASK(width, shift)		GENMASK(shift + width - 1, shift)
 23#define CLRPMASK(width, shift)		(~SETPMASK(width, shift))
 24
 25#define PARM_GET(width, shift, reg)					\
 26	(((reg) & SETPMASK(width, shift)) >> (shift))
 27#define PARM_SET(width, shift, reg, val)				\
 28	(((reg) & CLRPMASK(width, shift)) | (val << (shift)))
 29
 30#define MESON_PARM_APPLICABLE(p)		(!!((p)->width))
 31
 32struct parm {
 33	u16	reg_off;
 34	u8	shift;
 35	u8	width;
 36};
 37#define PARM(_r, _s, _w)						\
 38	{								\
 39		.reg_off	= (_r),					\
 40		.shift		= (_s),					\
 41		.width		= (_w),					\
 42	}								\
 43
 44struct pll_rate_table {
 45	unsigned long	rate;
 46	u16		m;
 47	u16		n;
 48	u16		od;
 49};
 50#define PLL_RATE(_r, _m, _n, _od)					\
 51	{								\
 52		.rate		= (_r),					\
 53		.m		= (_m),					\
 54		.n		= (_n),					\
 55		.od		= (_od),				\
 56	}								\
 57
 58struct pll_conf {
 59	const struct pll_rate_table	*rate_table;
 60	struct parm			m;
 61	struct parm			n;
 62	struct parm			od;
 63};
 64
 65struct fixed_fact_conf {
 66	unsigned int	div;
 67	unsigned int	mult;
 68	struct parm	div_parm;
 69	struct parm	mult_parm;
 70};
 71
 72struct fixed_rate_conf {
 73	unsigned long	rate;
 74	struct parm	rate_parm;
 75};
 76
 77struct composite_conf {
 78	struct parm		mux_parm;
 79	struct parm		div_parm;
 80	struct parm		gate_parm;
 81	struct clk_div_table	*div_table;
 82	u32			*mux_table;
 83	u8			mux_flags;
 84	u8			div_flags;
 85	u8			gate_flags;
 86};
 87
 88#define PNAME(x) static const char *x[]
 89
 90enum clk_type {
 91	CLK_FIXED_FACTOR,
 92	CLK_FIXED_RATE,
 93	CLK_COMPOSITE,
 94	CLK_CPU,
 95	CLK_PLL,
 96};
 97
 98struct clk_conf {
 99	u16				reg_off;
100	enum clk_type			clk_type;
101	unsigned int			clk_id;
102	const char			*clk_name;
103	const char			**clks_parent;
104	int				num_parents;
105	unsigned long			flags;
106	union {
107		struct fixed_fact_conf		fixed_fact;
108		struct fixed_rate_conf		fixed_rate;
109		const struct composite_conf		*composite;
110		struct pll_conf			*pll;
111		const struct clk_div_table	*div_table;
112	} conf;
113};
114
115#define FIXED_RATE_P(_ro, _ci, _cn, _f, _c)				\
116	{								\
117		.reg_off			= (_ro),		\
118		.clk_type			= CLK_FIXED_RATE,	\
119		.clk_id				= (_ci),		\
120		.clk_name			= (_cn),		\
121		.flags				= (_f),			\
122		.conf.fixed_rate.rate_parm	= _c,			\
123	}								\
124
125#define FIXED_RATE(_ci, _cn, _f, _r)					\
126	{								\
127		.clk_type			= CLK_FIXED_RATE,	\
128		.clk_id				= (_ci),		\
129		.clk_name			= (_cn),		\
130		.flags				= (_f),			\
131		.conf.fixed_rate.rate		= (_r),			\
132	}								\
133
134#define PLL(_ro, _ci, _cn, _cp, _f, _c)					\
135	{								\
136		.reg_off			= (_ro),		\
137		.clk_type			= CLK_PLL,		\
138		.clk_id				= (_ci),		\
139		.clk_name			= (_cn),		\
140		.clks_parent			= (_cp),		\
141		.num_parents			= ARRAY_SIZE(_cp),	\
142		.flags				= (_f),			\
143		.conf.pll			= (_c),			\
144	}								\
145
146#define FIXED_FACTOR_DIV(_ci, _cn, _cp, _f, _d)				\
147	{								\
148		.clk_type			= CLK_FIXED_FACTOR,	\
149		.clk_id				= (_ci),		\
150		.clk_name			= (_cn),		\
151		.clks_parent			= (_cp),		\
152		.num_parents			= ARRAY_SIZE(_cp),	\
153		.conf.fixed_fact.div		= (_d),			\
154	}								\
155
156#define CPU(_ro, _ci, _cn, _cp, _dt)					\
157	{								\
158		.reg_off			= (_ro),		\
159		.clk_type			= CLK_CPU,		\
160		.clk_id				= (_ci),		\
161		.clk_name			= (_cn),		\
162		.clks_parent			= (_cp),		\
163		.num_parents			= ARRAY_SIZE(_cp),	\
164		.conf.div_table			= (_dt),		\
165	}								\
166
167#define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c)				\
168	{								\
169		.reg_off			= (_ro),		\
170		.clk_type			= CLK_COMPOSITE,	\
171		.clk_id				= (_ci),		\
172		.clk_name			= (_cn),		\
173		.clks_parent			= (_cp),		\
174		.num_parents			= ARRAY_SIZE(_cp),	\
175		.flags				= (_f),			\
176		.conf.composite			= (_c),			\
177	}								\
178
179struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
180void meson_clk_register_clks(const struct clk_conf *clk_confs,
181			     unsigned int nr_confs, void __iomem *clk_base);
182struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
183				   void __iomem *reg_base, spinlock_t *lock);
184struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
185				   void __iomem *reg_base, spinlock_t *lock);
186
187#endif /* __CLKC_H */