1 /*
2  * Copyright (C) 2014 Google, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  */
8 
9 #ifndef __PISTACHIO_CLK_H
10 #define __PISTACHIO_CLK_H
11 
12 #include <linux/clk-provider.h>
13 
14 struct pistachio_gate {
15 	unsigned int id;
16 	unsigned long reg;
17 	unsigned int shift;
18 	const char *name;
19 	const char *parent;
20 };
21 
22 #define GATE(_id, _name, _pname, _reg, _shift)	\
23 	{					\
24 		.id	= _id,			\
25 		.reg	= _reg,			\
26 		.shift	= _shift,		\
27 		.name	= _name,		\
28 		.parent = _pname,		\
29 	}
30 
31 struct pistachio_mux {
32 	unsigned int id;
33 	unsigned long reg;
34 	unsigned int shift;
35 	unsigned int num_parents;
36 	const char *name;
37 	const char **parents;
38 };
39 
40 #define PNAME(x) static const char *x[] __initconst
41 
42 #define MUX(_id, _name, _pnames, _reg, _shift)			\
43 	{							\
44 		.id		= _id,				\
45 		.reg		= _reg,				\
46 		.shift		= _shift,			\
47 		.name		= _name,			\
48 		.parents	= _pnames,			\
49 		.num_parents	= ARRAY_SIZE(_pnames)		\
50 	}
51 
52 
53 struct pistachio_div {
54 	unsigned int id;
55 	unsigned long reg;
56 	unsigned int width;
57 	unsigned int div_flags;
58 	const char *name;
59 	const char *parent;
60 };
61 
62 #define DIV(_id, _name, _pname, _reg, _width)			\
63 	{							\
64 		.id		= _id,				\
65 		.reg		= _reg,				\
66 		.width		= _width,			\
67 		.div_flags	= 0,				\
68 		.name		= _name,			\
69 		.parent		= _pname,			\
70 	}
71 
72 #define DIV_F(_id, _name, _pname, _reg, _width, _div_flags)	\
73 	{							\
74 		.id		= _id,				\
75 		.reg		= _reg,				\
76 		.width		= _width,			\
77 		.div_flags	= _div_flags,			\
78 		.name		= _name,			\
79 		.parent		= _pname,			\
80 	}
81 
82 struct pistachio_fixed_factor {
83 	unsigned int id;
84 	unsigned int div;
85 	const char *name;
86 	const char *parent;
87 };
88 
89 #define FIXED_FACTOR(_id, _name, _pname, _div)			\
90 	{							\
91 		.id		= _id,				\
92 		.div		= _div,				\
93 		.name		= _name,			\
94 		.parent		= _pname,			\
95 	}
96 
97 struct pistachio_pll_rate_table {
98 	unsigned long long fref;
99 	unsigned long long fout;
100 	unsigned long long refdiv;
101 	unsigned long long fbdiv;
102 	unsigned long long postdiv1;
103 	unsigned long long postdiv2;
104 	unsigned long long frac;
105 };
106 
107 enum pistachio_pll_type {
108 	PLL_GF40LP_LAINT,
109 	PLL_GF40LP_FRAC,
110 };
111 
112 struct pistachio_pll {
113 	unsigned int id;
114 	unsigned long reg_base;
115 	enum pistachio_pll_type type;
116 	struct pistachio_pll_rate_table *rates;
117 	unsigned int nr_rates;
118 	const char *name;
119 	const char *parent;
120 };
121 
122 #define PLL(_id, _name, _pname, _type, _reg, _rates)		\
123 	{							\
124 		.id		= _id,				\
125 		.reg_base	= _reg,				\
126 		.type		= _type,			\
127 		.rates		= _rates,			\
128 		.nr_rates	= ARRAY_SIZE(_rates),		\
129 		.name		= _name,			\
130 		.parent		= _pname,			\
131 	}
132 
133 #define PLL_FIXED(_id, _name, _pname, _type, _reg)		\
134 	{							\
135 		.id		= _id,				\
136 		.reg_base	= _reg,				\
137 		.type		= _type,			\
138 		.rates		= NULL,				\
139 		.nr_rates	= 0,				\
140 		.name		= _name,			\
141 		.parent		= _pname,			\
142 	}
143 
144 struct pistachio_clk_provider {
145 	struct device_node *node;
146 	void __iomem *base;
147 	struct clk_onecell_data clk_data;
148 };
149 
150 extern struct pistachio_clk_provider *
151 pistachio_clk_alloc_provider(struct device_node *node, unsigned int num_clks);
152 extern void pistachio_clk_register_provider(struct pistachio_clk_provider *p);
153 
154 extern void pistachio_clk_register_gate(struct pistachio_clk_provider *p,
155 					struct pistachio_gate *gate,
156 					unsigned int num);
157 extern void pistachio_clk_register_mux(struct pistachio_clk_provider *p,
158 				       struct pistachio_mux *mux,
159 				       unsigned int num);
160 extern void pistachio_clk_register_div(struct pistachio_clk_provider *p,
161 				       struct pistachio_div *div,
162 				       unsigned int num);
163 extern void
164 pistachio_clk_register_fixed_factor(struct pistachio_clk_provider *p,
165 				    struct pistachio_fixed_factor *ff,
166 				    unsigned int num);
167 extern void pistachio_clk_register_pll(struct pistachio_clk_provider *p,
168 				       struct pistachio_pll *pll,
169 				       unsigned int num);
170 
171 extern void pistachio_clk_force_enable(struct pistachio_clk_provider *p,
172 				       unsigned int *clk_ids, unsigned int num);
173 
174 #endif
175