1 /*
2  * Copyright (C) 2016 Socionext Inc.
3  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <dm/device.h>
9 
10 #include "clk-uniphier.h"
11 
12 #define UNIPHIER_MIO_CLK_GATE_SD(ch, idx)	\
13 	{					\
14 		.index = (idx),			\
15 		.reg = 0x20 + 0x200 * (ch),	\
16 		.mask = 0x00000100,		\
17 		.data = 0x00000100,		\
18 	},					\
19 	{					\
20 		.index = (idx),			\
21 		.reg = 0x110 + 0x200 * (ch),	\
22 		.mask = 0x00000001,		\
23 		.data = 0x00000001,		\
24 	}
25 
26 #define UNIPHIER_MIO_CLK_RATE_SD(ch, idx)	\
27 	{					\
28 		.index = (idx),			\
29 		.reg = 0x30 + 0x200 * (ch),	\
30 		.mask = 0x00031300,		\
31 		.data = 0x00000000,		\
32 		.rate = 44444444,		\
33 	},					\
34 	{					\
35 		.index = (idx),			\
36 		.reg = 0x30 + 0x200 * (ch),	\
37 		.mask = 0x00031300,		\
38 		.data = 0x00010000,		\
39 		.rate = 33333333,		\
40 	},					\
41 	{					\
42 		.index = (idx),			\
43 		.reg = 0x30 + 0x200 * (ch),	\
44 		.mask = 0x00031300,		\
45 		.data = 0x00020000,		\
46 		.rate = 50000000,		\
47 	},					\
48 	{					\
49 		.index = (idx),			\
50 		.reg = 0x30 + 0x200 * (ch),	\
51 		.mask = 0x00031300,		\
52 		.data = 0x00020000,		\
53 		.rate = 66666666,		\
54 	},					\
55 	{					\
56 		.index = (idx),			\
57 		.reg = 0x30 + 0x200 * (ch),	\
58 		.mask = 0x00031300,		\
59 		.data = 0x00001000,		\
60 		.rate = 100000000,		\
61 	},					\
62 	{					\
63 		.index = (idx),			\
64 		.reg = 0x30 + 0x200 * (ch),	\
65 		.mask = 0x00031300,		\
66 		.data = 0x00001100,		\
67 		.rate = 40000000,		\
68 	},					\
69 	{					\
70 		.index = (idx),			\
71 		.reg = 0x30 + 0x200 * (ch),	\
72 		.mask = 0x00031300,		\
73 		.data = 0x00001200,		\
74 		.rate = 25000000,		\
75 	},					\
76 	{					\
77 		.index = (idx),			\
78 		.reg = 0x30 + 0x200 * (ch),	\
79 		.mask = 0x00031300,		\
80 		.data = 0x00001300,		\
81 		.rate = 22222222,		\
82 	}
83 
84 #define UNIPHIER_MIO_CLK_GATE_USB(ch, idx)	\
85 	{					\
86 		.index = (idx),			\
87 		.reg = 0x20 + 0x200 * (ch),	\
88 		.mask = 0x30000000,		\
89 		.data = 0x30000000,		\
90 	},					\
91 	{					\
92 		.index = (idx),			\
93 		.reg = 0x110 + 0x200 * (ch),	\
94 		.mask = 0x01000000,		\
95 		.data = 0x01000000,		\
96 	},					\
97 	{					\
98 		.index = (idx),			\
99 		.reg = 0x114 + 0x200 * (ch),	\
100 		.mask = 0x00000001,		\
101 		.data = 0x00000001,		\
102 	}
103 
104 #define UNIPHIER_MIO_CLK_GATE_DMAC(idx)		\
105 	{					\
106 		.index = (idx),			\
107 		.reg = 0x20,			\
108 		.mask = 0x02000000,		\
109 		.data = 0x02000000,		\
110 	},					\
111 	{					\
112 		.index = (idx),			\
113 		.reg = 0x110,			\
114 		.mask = 0x00020000,		\
115 		.data = 0x00020000,		\
116 	}
117 
118 static struct uniphier_clk_gate_data uniphier_mio_clk_gate[] = {
119 	UNIPHIER_MIO_CLK_GATE_SD(0, 0),
120 	UNIPHIER_MIO_CLK_GATE_SD(1, 1),
121 	UNIPHIER_MIO_CLK_GATE_SD(2, 2),		/* for PH1-Pro4 only */
122 	UNIPHIER_MIO_CLK_GATE_USB(0, 3),
123 	UNIPHIER_MIO_CLK_GATE_USB(1, 4),
124 	UNIPHIER_MIO_CLK_GATE_USB(2, 5),
125 	UNIPHIER_MIO_CLK_GATE_DMAC(6),
126 	UNIPHIER_MIO_CLK_GATE_USB(3, 7),	/* for PH1-sLD3 only */
127 };
128 
129 static struct uniphier_clk_rate_data uniphier_mio_clk_rate[] = {
130 	UNIPHIER_MIO_CLK_RATE_SD(0, 0),
131 	UNIPHIER_MIO_CLK_RATE_SD(1, 1),
132 	UNIPHIER_MIO_CLK_RATE_SD(2, 2),		/* for PH1-Pro4 only */
133 };
134 
135 static struct uniphier_clk_soc_data uniphier_mio_clk_data = {
136 	.gate = uniphier_mio_clk_gate,
137 	.nr_gate = ARRAY_SIZE(uniphier_mio_clk_gate),
138 	.rate = uniphier_mio_clk_rate,
139 	.nr_rate = ARRAY_SIZE(uniphier_mio_clk_rate),
140 };
141 
142 static const struct udevice_id uniphier_mio_clk_match[] = {
143 	{
144 		.compatible = "socionext,ph1-sld3-mioctrl",
145 		.data = (ulong)&uniphier_mio_clk_data,
146 	},
147 	{
148 		.compatible = "socionext,ph1-ld4-mioctrl",
149 		.data = (ulong)&uniphier_mio_clk_data,
150 	},
151 	{
152 		.compatible = "socionext,ph1-pro4-mioctrl",
153 		.data = (ulong)&uniphier_mio_clk_data,
154 	},
155 	{
156 		.compatible = "socionext,ph1-sld8-mioctrl",
157 		.data = (ulong)&uniphier_mio_clk_data,
158 	},
159 	{
160 		.compatible = "socionext,ph1-pro5-mioctrl",
161 		.data = (ulong)&uniphier_mio_clk_data,
162 	},
163 	{
164 		.compatible = "socionext,proxstream2-mioctrl",
165 		.data = (ulong)&uniphier_mio_clk_data,
166 	},
167 	{
168 		.compatible = "socionext,ph1-ld11-mioctrl",
169 		.data = (ulong)&uniphier_mio_clk_data,
170 	},
171 	{
172 		.compatible = "socionext,ph1-ld20-mioctrl",
173 		.data = (ulong)&uniphier_mio_clk_data,
174 	},
175 	{ /* sentinel */ }
176 };
177 
178 U_BOOT_DRIVER(uniphier_mio_clk) = {
179 	.name = "uniphier-mio-clk",
180 	.id = UCLASS_CLK,
181 	.of_match = uniphier_mio_clk_match,
182 	.probe = uniphier_clk_probe,
183 	.priv_auto_alloc_size = sizeof(struct uniphier_clk_priv),
184 	.ops = &uniphier_clk_ops,
185 };
186