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
16struct 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
33struct pll_data {
34	u32 reg;
35	const char *name;
36	const char *parent;
37	u32 flags;
38};
39
40struct 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
50struct 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
60struct hfosc_data {
61	const char *name;
62	u32 flags;
63};
64
65struct fixed_rate_data {
66	const char *name;
67	u64 rate;
68	u32 flags;
69};
70
71struct postdiv_data {
72	const char *name;
73	const char *parent;
74	int width;
75	u32 flags;
76};
77
78struct mux_pllctrl_data {
79	u32 reg;
80	const char *name;
81	const char * const *parents;
82	int num_parents;
83	u32 flags;
84};
85
86struct 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
167struct 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
174extern const struct ti_k3_clk_platdata j721e_clk_platdata;
175extern const struct ti_k3_clk_platdata j7200_clk_platdata;
176extern const struct ti_k3_clk_platdata j721s2_clk_platdata;
177extern const struct ti_k3_clk_platdata am62x_clk_platdata;
178extern const struct ti_k3_clk_platdata am62ax_clk_platdata;
179extern const struct ti_k3_clk_platdata j784s4_clk_platdata;
180extern const struct ti_k3_clk_platdata am62px_clk_platdata;
181
182struct clk *clk_register_ti_pll(const char *name, const char *parent_name,
183				void __iomem *reg);
184
185#endif /* __K3_CLK_H__ */
186