1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * (C) Copyright 2020-2021 Texas Instruments Incorporated - https://www.ti.com
4  *      Tero Kristo <t-kristo@ti.com>
5  */
6 
7 #ifndef __K3_CLK_H__
8 #define __K3_CLK_H__
9 
10 #include <asm/io.h>
11 #include <linux/bitops.h>
12 #include <linux/clk-provider.h>
13 #include <linux/types.h>
14 #include <stdint.h>
15 
16 struct dev_clk {
17 	int dev_id;
18 	int clk_id;
19 	const char *clk_name;
20 };
21 
22 #define DEV_CLK(_dev_id, _clk_id, _clk_name) { .dev_id = _dev_id,		\
23 					.clk_id = _clk_id, .clk_name = _clk_name, }
24 
25 #define CLK_TYPE_MUX		0x01
26 #define CLK_TYPE_DIV		0x02
27 #define CLK_TYPE_PLL		0x03
28 #define CLK_TYPE_HFOSC		0x04
29 #define CLK_TYPE_POSTDIV	0x05
30 #define CLK_TYPE_MUX_PLLCTRL	0x06
31 #define CLK_TYPE_FIXED_RATE	0x07
32 
33 struct pll_data {
34 	u32 reg;
35 	const char *name;
36 	const char *parent;
37 	u32 flags;
38 };
39 
40 struct mux_data {
41 	u32 reg;
42 	const char *name;
43 	const char * const *parents;
44 	int num_parents;
45 	u32 flags;
46 	int shift;
47 	int width;
48 };
49 
50 struct div_data {
51 	u32 reg;
52 	const char *name;
53 	const char *parent;
54 	u32 flags;
55 	int shift;
56 	int width;
57 	u32 div_flags;
58 };
59 
60 struct hfosc_data {
61 	const char *name;
62 	u32 flags;
63 };
64 
65 struct fixed_rate_data {
66 	const char *name;
67 	u64 rate;
68 	u32 flags;
69 };
70 
71 struct postdiv_data {
72 	const char *name;
73 	const char *parent;
74 	int width;
75 	u32 flags;
76 };
77 
78 struct mux_pllctrl_data {
79 	u32 reg;
80 	const char *name;
81 	const char * const *parents;
82 	int num_parents;
83 	u32 flags;
84 };
85 
86 struct clk_data {
87 	int type;
88 	u32 default_freq;
89 	union {
90 		struct pll_data pll;
91 		struct mux_data mux;
92 		struct div_data div;
93 		struct hfosc_data hfosc;
94 		struct postdiv_data postdiv;
95 		struct mux_pllctrl_data mux_pllctrl;
96 		struct fixed_rate_data fixed_rate;
97 	} clk;
98 };
99 
100 #define CLK_MUX(_name, _parents, _num_parents, _reg, _shift, _width, _flags) \
101 	{								\
102 		.type = CLK_TYPE_MUX,					\
103 		.clk.mux = { .name = _name, .parents = _parents,	\
104 		.reg = _reg,						\
105 		.num_parents = _num_parents, .shift = _shift,		\
106 		.width = _width, .flags = _flags }			\
107 	}
108 
109 #define CLK_DIV(_name, _parent, _reg, _shift, _width, _flags, _div_flags)	\
110 	{								\
111 		.type = CLK_TYPE_DIV,					\
112 		.clk.div = {						\
113 			.name = _name, .parent = _parent, .reg = _reg,	\
114 			.shift = _shift, .width = _width,		\
115 			.flags = _flags, .div_flags = _div_flags }	\
116 	}
117 
118 #define CLK_DIV_DEFFREQ(_name, _parent, _reg, _shift, _width, _flags, _div_flags, _freq) \
119 	{								\
120 		.type = CLK_TYPE_DIV,					\
121 		.default_freq = _freq,					\
122 		.clk.div = {						\
123 			.name = _name, .parent = _parent, .reg = _reg,	\
124 			.shift = _shift, .width = _width,		\
125 			.flags = _flags, .div_flags = _div_flags }	\
126 	}
127 
128 #define CLK_PLL(_name, _parent, _reg,  _flags)	\
129 	{					\
130 		.type = CLK_TYPE_PLL,		\
131 		.clk.pll = {.name = _name, .parent = _parent, .reg = _reg, .flags = _flags } \
132 	}
133 
134 #define CLK_PLL_DEFFREQ(_name, _parent, _reg, _flags, _freq)	\
135 	{							\
136 		.type = CLK_TYPE_PLL,				\
137 		.default_freq = _freq,				\
138 		.clk.pll = { .name = _name, .parent = _parent,	\
139 				.reg = _reg, .flags = _flags }	\
140 	}
141 
142 #define CLK_HFOSC(_name, _flags)		\
143 	{					\
144 		.type = CLK_TYPE_HFOSC,		\
145 		.clk.hfosc = { .name = _name, .flags = _flags } \
146 	}
147 
148 #define CLK_FIXED_RATE(_name, _rate, _flags)		\
149 	{						\
150 		.type = CLK_TYPE_FIXED_RATE,		\
151 		.clk.fixed_rate = { .name = _name, .rate = _rate, .flags = _flags } \
152 	}
153 
154 #define CLK_POSTDIV(_name, _parent, _width, _flags)	\
155 	{						\
156 		.type = CLK_TYPE_POSTDIV,		\
157 		.clk.postdiv = {.name = _name, .parent = _parent, .width = _width, .flags = _flags } \
158 	}
159 
160 #define CLK_MUX_PLLCTRL(_name, _parents, _num_parents, _reg, _flags)	\
161 	{								\
162 		.type = CLK_TYPE_MUX,					\
163 		.clk.mux_pllctrl = { .name = _name, .parents = _parents,\
164 		.num_parents = _num_parents, .flags = _flags }		\
165 	}
166 
167 struct ti_k3_clk_platdata {
168 	const struct clk_data *clk_list;
169 	int clk_list_cnt;
170 	const struct dev_clk *soc_dev_clk_data;
171 	int soc_dev_clk_data_cnt;
172 };
173 
174 extern const struct ti_k3_clk_platdata j721e_clk_platdata;
175 extern const struct ti_k3_clk_platdata j7200_clk_platdata;
176 extern const struct ti_k3_clk_platdata j721s2_clk_platdata;
177 extern const struct ti_k3_clk_platdata am62x_clk_platdata;
178 extern const struct ti_k3_clk_platdata am62ax_clk_platdata;
179 extern const struct ti_k3_clk_platdata j784s4_clk_platdata;
180 extern const struct ti_k3_clk_platdata am62px_clk_platdata;
181 extern const struct ti_k3_clk_platdata j722s_clk_platdata;
182 
183 struct clk *clk_register_ti_pll(const char *name, const char *parent_name,
184 				void __iomem *reg);
185 
186 #endif /* __K3_CLK_H__ */
187