Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.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#include <linux/clk-provider.h>
 22#include "clk-regmap.h"
 23
 24#define PMASK(width)			GENMASK(width - 1, 0)
 25#define SETPMASK(width, shift)		GENMASK(shift + width - 1, shift)
 26#define CLRPMASK(width, shift)		(~SETPMASK(width, shift))
 27
 28#define PARM_GET(width, shift, reg)					\
 29	(((reg) & SETPMASK(width, shift)) >> (shift))
 30#define PARM_SET(width, shift, reg, val)				\
 31	(((reg) & CLRPMASK(width, shift)) | ((val) << (shift)))
 32
 33#define MESON_PARM_APPLICABLE(p)		(!!((p)->width))
 34
 35struct parm {
 36	u16	reg_off;
 37	u8	shift;
 38	u8	width;
 39};
 40
 41static inline unsigned int meson_parm_read(struct regmap *map, struct parm *p)
 42{
 43	unsigned int val;
 44
 45	regmap_read(map, p->reg_off, &val);
 46	return PARM_GET(p->width, p->shift, val);
 47}
 48
 49static inline void meson_parm_write(struct regmap *map, struct parm *p,
 50				    unsigned int val)
 51{
 52	regmap_update_bits(map, p->reg_off, SETPMASK(p->width, p->shift),
 53			   val << p->shift);
 54}
 55
 56
 57struct pll_rate_table {
 58	unsigned long	rate;
 59	u16		m;
 60	u16		n;
 61	u16		od;
 62	u16		od2;
 63	u16		od3;
 64};
 65
 66#define PLL_RATE(_r, _m, _n, _od)					\
 67	{								\
 68		.rate		= (_r),					\
 69		.m		= (_m),					\
 70		.n		= (_n),					\
 71		.od		= (_od),				\
 72	}
 73
 74#define CLK_MESON_PLL_ROUND_CLOSEST	BIT(0)
 75
 76struct meson_clk_pll_data {
 77	struct parm m;
 78	struct parm n;
 79	struct parm frac;
 80	struct parm od;
 81	struct parm od2;
 82	struct parm od3;
 83	struct parm l;
 84	struct parm rst;
 85	const struct reg_sequence *init_regs;
 86	unsigned int init_count;
 87	const struct pll_rate_table *table;
 88	u8 flags;
 89};
 90
 91#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
 92
 93struct meson_clk_mpll_data {
 94	struct parm sdm;
 95	struct parm sdm_en;
 96	struct parm n2;
 97	struct parm ssen;
 98	struct parm misc;
 99	spinlock_t *lock;
100};
101
102struct meson_clk_audio_div_data {
103	struct parm div;
104	u8 flags;
105};
106
107#define MESON_GATE(_name, _reg, _bit)					\
108struct clk_regmap _name = {						\
109	.data = &(struct clk_regmap_gate_data){				\
110		.offset = (_reg),					\
111		.bit_idx = (_bit),					\
112	},								\
113	.hw.init = &(struct clk_init_data) {				\
114		.name = #_name,						\
115		.ops = &clk_regmap_gate_ops,				\
116		.parent_names = (const char *[]){ "clk81" },		\
117		.num_parents = 1,					\
118		.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),	\
119	},								\
120};
121
122/* clk_ops */
123extern const struct clk_ops meson_clk_pll_ro_ops;
124extern const struct clk_ops meson_clk_pll_ops;
125extern const struct clk_ops meson_clk_cpu_ops;
126extern const struct clk_ops meson_clk_mpll_ro_ops;
127extern const struct clk_ops meson_clk_mpll_ops;
128extern const struct clk_ops meson_clk_audio_divider_ro_ops;
129extern const struct clk_ops meson_clk_audio_divider_ops;
130
131#endif /* __CLKC_H */