Linux Audio

Check our new training course

Loading...
v4.6
  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 */
v4.10.11
  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
 38struct pll_rate_table {
 39	unsigned long	rate;
 40	u16		m;
 41	u16		n;
 42	u16		od;
 43	u16		od2;
 44	u16		frac;
 45};
 46
 47#define PLL_RATE(_r, _m, _n, _od)					\
 48	{								\
 49		.rate		= (_r),					\
 50		.m		= (_m),					\
 51		.n		= (_n),					\
 52		.od		= (_od),				\
 53	}								\
 54
 55#define PLL_FRAC_RATE(_r, _m, _n, _od, _od2, _frac)			\
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 56	{								\
 57		.rate		= (_r),					\
 58		.m		= (_m),					\
 59		.n		= (_n),					\
 60		.od		= (_od),				\
 61		.od2		= (_od2),				\
 62		.frac		= (_frac),				\
 
 
 63	}								\
 64
 65struct meson_clk_pll {
 66	struct clk_hw hw;
 67	void __iomem *base;
 68	struct parm m;
 69	struct parm n;
 70	struct parm frac;
 71	struct parm od;
 72	struct parm od2;
 73	const struct pll_rate_table *rate_table;
 74	unsigned int rate_count;
 75	spinlock_t *lock;
 76};
 77
 78#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
 79
 80struct meson_clk_cpu {
 81	struct clk_hw hw;
 82	void __iomem *base;
 83	u16 reg_off;
 84	struct notifier_block clk_nb;
 85	const struct clk_div_table *div_table;
 86};
 87
 88int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
 89		void *data);
 90
 91struct meson_clk_mpll {
 92	struct clk_hw hw;
 93	void __iomem *base;
 94	struct parm sdm;
 95	struct parm n2;
 96	/* FIXME ssen gate control? */
 97	spinlock_t *lock;
 98};
 99
100#define MESON_GATE(_name, _reg, _bit)					\
101struct clk_gate _name = { 						\
102	.reg = (void __iomem *) _reg, 					\
103	.bit_idx = (_bit), 						\
104	.lock = &clk_lock,						\
105	.hw.init = &(struct clk_init_data) { 				\
106		.name = #_name,					\
107		.ops = &clk_gate_ops,					\
108		.parent_names = (const char *[]){ "clk81" },		\
109		.num_parents = 1,					\
110		.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), 	\
111	},								\
112};
113
114/* clk_ops */
115extern const struct clk_ops meson_clk_pll_ro_ops;
116extern const struct clk_ops meson_clk_pll_ops;
117extern const struct clk_ops meson_clk_cpu_ops;
118extern const struct clk_ops meson_clk_mpll_ro_ops;
119
120#endif /* __CLKC_H */