blob: 252151f3e5d9acbc9075894cc37bb34cddd9e3f5 [file] [log] [blame]
Pali Rohár87e2e462022-07-25 13:56:09 +02001// SPDX-License-Identifier: GPL-2.0-or-later
2// (C) 2022 Pali Rohár <pali@kernel.org>
3
4#include <common.h>
5#include <config.h>
6#include <dm.h>
7#include <dm/devres.h>
8#include <dm/lists.h>
9#include <dm/pinctrl.h>
10#include <dm/root.h>
11#include <errno.h>
12#include <asm/io.h>
13
14struct mvebu_mpp_ctrl_setting {
15 const char *name;
16 const char *subname;
17 u8 val;
18 u8 variant;
19};
20
21struct mvebu_mpp_mode {
22 const char *name;
23 size_t nsettings;
24 struct mvebu_mpp_ctrl_setting *settings;
25};
26
27#define MPP_MODE(_name, ...) \
28 { \
29 .name = _name, \
30 .nsettings = ARRAY_SIZE(( \
31 (struct mvebu_mpp_ctrl_setting[]) \
32 { __VA_ARGS__ })), \
33 .settings = (struct mvebu_mpp_ctrl_setting[]){ \
34 __VA_ARGS__ }, \
35 }
36
37#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \
38 { \
39 .val = _val, \
40 .name = _name, \
41 .subname = _subname, \
42 .variant = _mask, \
43 }
44
45#define MVEBU_MPPS_PER_REG 8
46#define MVEBU_MPP_BITS 4
47#define MVEBU_MPP_MASK 0xf
48
49enum {
50 V_88F6810 = BIT(0),
51 V_88F6820 = BIT(1),
52 V_88F6828 = BIT(2),
53 V_88F6810_PLUS = (V_88F6810 | V_88F6820 | V_88F6828),
54 V_88F6820_PLUS = (V_88F6820 | V_88F6828),
55};
56
57static struct mvebu_mpp_mode armada_38x_mpp_modes[] = {
58 MPP_MODE("mpp0",
59 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
60 MPP_VAR_FUNCTION(1, "ua0", "rxd", V_88F6810_PLUS)),
61 MPP_MODE("mpp1",
62 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
63 MPP_VAR_FUNCTION(1, "ua0", "txd", V_88F6810_PLUS)),
64 MPP_MODE("mpp2",
65 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
66 MPP_VAR_FUNCTION(1, "i2c0", "sck", V_88F6810_PLUS)),
67 MPP_MODE("mpp3",
68 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
69 MPP_VAR_FUNCTION(1, "i2c0", "sda", V_88F6810_PLUS)),
70 MPP_MODE("mpp4",
71 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
72 MPP_VAR_FUNCTION(1, "ge", "mdc", V_88F6810_PLUS),
73 MPP_VAR_FUNCTION(2, "ua1", "txd", V_88F6810_PLUS),
74 MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6810_PLUS)),
75 MPP_MODE("mpp5",
76 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
77 MPP_VAR_FUNCTION(1, "ge", "mdio", V_88F6810_PLUS),
78 MPP_VAR_FUNCTION(2, "ua1", "rxd", V_88F6810_PLUS),
79 MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6810_PLUS)),
80 MPP_MODE("mpp6",
81 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
82 MPP_VAR_FUNCTION(1, "ge0", "txclkout", V_88F6810_PLUS),
83 MPP_VAR_FUNCTION(2, "ge0", "crs", V_88F6810_PLUS),
84 MPP_VAR_FUNCTION(5, "dev", "cs3", V_88F6810_PLUS)),
85 MPP_MODE("mpp7",
86 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
87 MPP_VAR_FUNCTION(1, "ge0", "txd0", V_88F6810_PLUS),
88 MPP_VAR_FUNCTION(5, "dev", "ad9", V_88F6810_PLUS)),
89 MPP_MODE("mpp8",
90 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
91 MPP_VAR_FUNCTION(1, "ge0", "txd1", V_88F6810_PLUS),
92 MPP_VAR_FUNCTION(5, "dev", "ad10", V_88F6810_PLUS)),
93 MPP_MODE("mpp9",
94 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
95 MPP_VAR_FUNCTION(1, "ge0", "txd2", V_88F6810_PLUS),
96 MPP_VAR_FUNCTION(5, "dev", "ad11", V_88F6810_PLUS)),
97 MPP_MODE("mpp10",
98 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
99 MPP_VAR_FUNCTION(1, "ge0", "txd3", V_88F6810_PLUS),
100 MPP_VAR_FUNCTION(5, "dev", "ad12", V_88F6810_PLUS)),
101 MPP_MODE("mpp11",
102 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
103 MPP_VAR_FUNCTION(1, "ge0", "txctl", V_88F6810_PLUS),
104 MPP_VAR_FUNCTION(5, "dev", "ad13", V_88F6810_PLUS)),
105 MPP_MODE("mpp12",
106 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
107 MPP_VAR_FUNCTION(1, "ge0", "rxd0", V_88F6810_PLUS),
108 MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6810_PLUS),
109 MPP_VAR_FUNCTION(4, "spi0", "cs1", V_88F6810_PLUS),
110 MPP_VAR_FUNCTION(5, "dev", "ad14", V_88F6810_PLUS),
111 MPP_VAR_FUNCTION(6, "pcie3", "clkreq", V_88F6810_PLUS)),
112 MPP_MODE("mpp13",
113 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
114 MPP_VAR_FUNCTION(1, "ge0", "rxd1", V_88F6810_PLUS),
115 MPP_VAR_FUNCTION(2, "pcie0", "clkreq", V_88F6810_PLUS),
116 MPP_VAR_FUNCTION(3, "pcie1", "clkreq", V_88F6820_PLUS),
117 MPP_VAR_FUNCTION(4, "spi0", "cs2", V_88F6810_PLUS),
118 MPP_VAR_FUNCTION(5, "dev", "ad15", V_88F6810_PLUS),
119 MPP_VAR_FUNCTION(6, "pcie2", "clkreq", V_88F6810_PLUS)),
120 MPP_MODE("mpp14",
121 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
122 MPP_VAR_FUNCTION(1, "ge0", "rxd2", V_88F6810_PLUS),
123 MPP_VAR_FUNCTION(2, "ptp", "clk", V_88F6810_PLUS),
124 MPP_VAR_FUNCTION(3, "dram", "vttctrl", V_88F6810_PLUS),
125 MPP_VAR_FUNCTION(4, "spi0", "cs3", V_88F6810_PLUS),
126 MPP_VAR_FUNCTION(5, "dev", "we1", V_88F6810_PLUS),
127 MPP_VAR_FUNCTION(6, "pcie3", "clkreq", V_88F6810_PLUS)),
128 MPP_MODE("mpp15",
129 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
130 MPP_VAR_FUNCTION(1, "ge0", "rxd3", V_88F6810_PLUS),
131 MPP_VAR_FUNCTION(2, "ge", "mdc slave", V_88F6810_PLUS),
132 MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6810_PLUS),
133 MPP_VAR_FUNCTION(4, "spi0", "mosi", V_88F6810_PLUS)),
134 MPP_MODE("mpp16",
135 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
136 MPP_VAR_FUNCTION(1, "ge0", "rxctl", V_88F6810_PLUS),
137 MPP_VAR_FUNCTION(2, "ge", "mdio slave", V_88F6810_PLUS),
138 MPP_VAR_FUNCTION(3, "dram", "deccerr", V_88F6810_PLUS),
139 MPP_VAR_FUNCTION(4, "spi0", "miso", V_88F6810_PLUS),
140 MPP_VAR_FUNCTION(5, "pcie0", "clkreq", V_88F6810_PLUS),
141 MPP_VAR_FUNCTION(6, "pcie1", "clkreq", V_88F6820_PLUS)),
142 MPP_MODE("mpp17",
143 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
144 MPP_VAR_FUNCTION(1, "ge0", "rxclk", V_88F6810_PLUS),
145 MPP_VAR_FUNCTION(2, "ptp", "clk", V_88F6810_PLUS),
146 MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6810_PLUS),
147 MPP_VAR_FUNCTION(4, "spi0", "sck", V_88F6810_PLUS),
148 MPP_VAR_FUNCTION(5, "sata1", "prsnt", V_88F6810_PLUS),
149 MPP_VAR_FUNCTION(6, "sata0", "prsnt", V_88F6810_PLUS)),
150 MPP_MODE("mpp18",
151 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
152 MPP_VAR_FUNCTION(1, "ge0", "rxerr", V_88F6810_PLUS),
153 MPP_VAR_FUNCTION(2, "ptp", "trig", V_88F6810_PLUS),
154 MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6810_PLUS),
155 MPP_VAR_FUNCTION(4, "spi0", "cs0", V_88F6810_PLUS)),
156 MPP_MODE("mpp19",
157 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
158 MPP_VAR_FUNCTION(1, "ge0", "col", V_88F6810_PLUS),
159 MPP_VAR_FUNCTION(2, "ptp", "evreq", V_88F6810_PLUS),
160 MPP_VAR_FUNCTION(3, "ge0", "txerr", V_88F6810_PLUS),
161 MPP_VAR_FUNCTION(4, "sata1", "prsnt", V_88F6810_PLUS),
162 MPP_VAR_FUNCTION(5, "ua0", "cts", V_88F6810_PLUS),
163 MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6810_PLUS)),
164 MPP_MODE("mpp20",
165 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
166 MPP_VAR_FUNCTION(1, "ge0", "txclk", V_88F6810_PLUS),
167 MPP_VAR_FUNCTION(2, "ptp", "clk", V_88F6810_PLUS),
168 MPP_VAR_FUNCTION(4, "sata0", "prsnt", V_88F6810_PLUS),
169 MPP_VAR_FUNCTION(5, "ua0", "rts", V_88F6810_PLUS),
170 MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6810_PLUS)),
171 MPP_MODE("mpp21",
172 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
173 MPP_VAR_FUNCTION(1, "spi0", "cs1", V_88F6810_PLUS),
174 MPP_VAR_FUNCTION(2, "ge1", "rxd0", V_88F6810_PLUS),
175 MPP_VAR_FUNCTION(3, "sata0", "prsnt", V_88F6810_PLUS),
176 MPP_VAR_FUNCTION(4, "sd0", "cmd", V_88F6810_PLUS),
177 MPP_VAR_FUNCTION(5, "dev", "bootcs", V_88F6810_PLUS),
178 MPP_VAR_FUNCTION(6, "sata1", "prsnt", V_88F6810_PLUS)),
179 MPP_MODE("mpp22",
180 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
181 MPP_VAR_FUNCTION(1, "spi0", "mosi", V_88F6810_PLUS),
182 MPP_VAR_FUNCTION(5, "dev", "ad0", V_88F6810_PLUS)),
183 MPP_MODE("mpp23",
184 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
185 MPP_VAR_FUNCTION(1, "spi0", "sck", V_88F6810_PLUS),
186 MPP_VAR_FUNCTION(5, "dev", "ad2", V_88F6810_PLUS)),
187 MPP_MODE("mpp24",
188 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
189 MPP_VAR_FUNCTION(1, "spi0", "miso", V_88F6810_PLUS),
190 MPP_VAR_FUNCTION(2, "ua0", "cts", V_88F6810_PLUS),
191 MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6810_PLUS),
192 MPP_VAR_FUNCTION(4, "sd0", "d4", V_88F6810_PLUS),
193 MPP_VAR_FUNCTION(5, "dev", "ready", V_88F6810_PLUS)),
194 MPP_MODE("mpp25",
195 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
196 MPP_VAR_FUNCTION(1, "spi0", "cs0", V_88F6810_PLUS),
197 MPP_VAR_FUNCTION(2, "ua0", "rts", V_88F6810_PLUS),
198 MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6810_PLUS),
199 MPP_VAR_FUNCTION(4, "sd0", "d5", V_88F6810_PLUS),
200 MPP_VAR_FUNCTION(5, "dev", "cs0", V_88F6810_PLUS)),
201 MPP_MODE("mpp26",
202 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
203 MPP_VAR_FUNCTION(1, "spi0", "cs2", V_88F6810_PLUS),
204 MPP_VAR_FUNCTION(3, "i2c1", "sck", V_88F6810_PLUS),
205 MPP_VAR_FUNCTION(4, "sd0", "d6", V_88F6810_PLUS),
206 MPP_VAR_FUNCTION(5, "dev", "cs1", V_88F6810_PLUS)),
207 MPP_MODE("mpp27",
208 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
209 MPP_VAR_FUNCTION(1, "spi0", "cs3", V_88F6810_PLUS),
210 MPP_VAR_FUNCTION(2, "ge1", "txclkout", V_88F6810_PLUS),
211 MPP_VAR_FUNCTION(3, "i2c1", "sda", V_88F6810_PLUS),
212 MPP_VAR_FUNCTION(4, "sd0", "d7", V_88F6810_PLUS),
213 MPP_VAR_FUNCTION(5, "dev", "cs2", V_88F6810_PLUS)),
214 MPP_MODE("mpp28",
215 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
216 MPP_VAR_FUNCTION(2, "ge1", "txd0", V_88F6810_PLUS),
217 MPP_VAR_FUNCTION(4, "sd0", "clk", V_88F6810_PLUS),
218 MPP_VAR_FUNCTION(5, "dev", "ad5", V_88F6810_PLUS)),
219 MPP_MODE("mpp29",
220 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
221 MPP_VAR_FUNCTION(2, "ge1", "txd1", V_88F6810_PLUS),
222 MPP_VAR_FUNCTION(5, "dev", "ale0", V_88F6810_PLUS)),
223 MPP_MODE("mpp30",
224 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
225 MPP_VAR_FUNCTION(2, "ge1", "txd2", V_88F6810_PLUS),
226 MPP_VAR_FUNCTION(5, "dev", "oe", V_88F6810_PLUS)),
227 MPP_MODE("mpp31",
228 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
229 MPP_VAR_FUNCTION(2, "ge1", "txd3", V_88F6810_PLUS),
230 MPP_VAR_FUNCTION(5, "dev", "ale1", V_88F6810_PLUS)),
231 MPP_MODE("mpp32",
232 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
233 MPP_VAR_FUNCTION(2, "ge1", "txctl", V_88F6810_PLUS),
234 MPP_VAR_FUNCTION(5, "dev", "we0", V_88F6810_PLUS)),
235 MPP_MODE("mpp33",
236 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
237 MPP_VAR_FUNCTION(1, "dram", "deccerr", V_88F6810_PLUS),
238 MPP_VAR_FUNCTION(5, "dev", "ad3", V_88F6810_PLUS)),
239 MPP_MODE("mpp34",
240 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
241 MPP_VAR_FUNCTION(5, "dev", "ad1", V_88F6810_PLUS)),
242 MPP_MODE("mpp35",
243 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
244 MPP_VAR_FUNCTION(1, "ref", "clk_out1", V_88F6810_PLUS),
245 MPP_VAR_FUNCTION(5, "dev", "a1", V_88F6810_PLUS)),
246 MPP_MODE("mpp36",
247 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
248 MPP_VAR_FUNCTION(1, "ptp", "trig", V_88F6810_PLUS),
249 MPP_VAR_FUNCTION(5, "dev", "a0", V_88F6810_PLUS)),
250 MPP_MODE("mpp37",
251 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
252 MPP_VAR_FUNCTION(1, "ptp", "clk", V_88F6810_PLUS),
253 MPP_VAR_FUNCTION(2, "ge1", "rxclk", V_88F6810_PLUS),
254 MPP_VAR_FUNCTION(4, "sd0", "d3", V_88F6810_PLUS),
255 MPP_VAR_FUNCTION(5, "dev", "ad8", V_88F6810_PLUS)),
256 MPP_MODE("mpp38",
257 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
258 MPP_VAR_FUNCTION(1, "ptp", "evreq", V_88F6810_PLUS),
259 MPP_VAR_FUNCTION(2, "ge1", "rxd1", V_88F6810_PLUS),
260 MPP_VAR_FUNCTION(3, "ref", "clk_out0", V_88F6810_PLUS),
261 MPP_VAR_FUNCTION(4, "sd0", "d0", V_88F6810_PLUS),
262 MPP_VAR_FUNCTION(5, "dev", "ad4", V_88F6810_PLUS)),
263 MPP_MODE("mpp39",
264 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
265 MPP_VAR_FUNCTION(1, "i2c1", "sck", V_88F6810_PLUS),
266 MPP_VAR_FUNCTION(2, "ge1", "rxd2", V_88F6810_PLUS),
267 MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6810_PLUS),
268 MPP_VAR_FUNCTION(4, "sd0", "d1", V_88F6810_PLUS),
269 MPP_VAR_FUNCTION(5, "dev", "a2", V_88F6810_PLUS)),
270 MPP_MODE("mpp40",
271 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
272 MPP_VAR_FUNCTION(1, "i2c1", "sda", V_88F6810_PLUS),
273 MPP_VAR_FUNCTION(2, "ge1", "rxd3", V_88F6810_PLUS),
274 MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6810_PLUS),
275 MPP_VAR_FUNCTION(4, "sd0", "d2", V_88F6810_PLUS),
276 MPP_VAR_FUNCTION(5, "dev", "ad6", V_88F6810_PLUS)),
277 MPP_MODE("mpp41",
278 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
279 MPP_VAR_FUNCTION(1, "ua1", "rxd", V_88F6810_PLUS),
280 MPP_VAR_FUNCTION(2, "ge1", "rxctl", V_88F6810_PLUS),
281 MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6810_PLUS),
282 MPP_VAR_FUNCTION(4, "spi1", "cs3", V_88F6810_PLUS),
283 MPP_VAR_FUNCTION(5, "dev", "burst/last", V_88F6810_PLUS),
284 MPP_VAR_FUNCTION(6, "nand", "rb0", V_88F6810_PLUS)),
285 MPP_MODE("mpp42",
286 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
287 MPP_VAR_FUNCTION(1, "ua1", "txd", V_88F6810_PLUS),
288 MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6810_PLUS),
289 MPP_VAR_FUNCTION(5, "dev", "ad7", V_88F6810_PLUS)),
290 MPP_MODE("mpp43",
291 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
292 MPP_VAR_FUNCTION(1, "pcie0", "clkreq", V_88F6810_PLUS),
293 MPP_VAR_FUNCTION(2, "dram", "vttctrl", V_88F6810_PLUS),
294 MPP_VAR_FUNCTION(3, "dram", "deccerr", V_88F6810_PLUS),
295 MPP_VAR_FUNCTION(4, "spi1", "cs2", V_88F6810_PLUS),
296 MPP_VAR_FUNCTION(5, "dev", "clkout", V_88F6810_PLUS),
297 MPP_VAR_FUNCTION(6, "nand", "rb1", V_88F6810_PLUS)),
298 MPP_MODE("mpp44",
299 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
300 MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
301 MPP_VAR_FUNCTION(2, "sata1", "prsnt", V_88F6810_PLUS),
302 MPP_VAR_FUNCTION(3, "sata2", "prsnt", V_88F6828),
303 MPP_VAR_FUNCTION(4, "sata3", "prsnt", V_88F6828)),
304 MPP_MODE("mpp45",
305 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
306 MPP_VAR_FUNCTION(1, "ref", "clk_out0", V_88F6810_PLUS),
307 MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6810_PLUS),
308 MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6810_PLUS)),
309 MPP_MODE("mpp46",
310 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
311 MPP_VAR_FUNCTION(1, "ref", "clk_out1", V_88F6810_PLUS),
312 MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6810_PLUS),
313 MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6810_PLUS)),
314 MPP_MODE("mpp47",
315 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
316 MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
317 MPP_VAR_FUNCTION(2, "sata1", "prsnt", V_88F6810_PLUS),
318 MPP_VAR_FUNCTION(3, "sata2", "prsnt", V_88F6828),
319 MPP_VAR_FUNCTION(5, "sata3", "prsnt", V_88F6828)),
320 MPP_MODE("mpp48",
321 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
322 MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
323 MPP_VAR_FUNCTION(2, "dram", "vttctrl", V_88F6810_PLUS),
324 MPP_VAR_FUNCTION(3, "tdm", "pclk", V_88F6810_PLUS),
325 MPP_VAR_FUNCTION(4, "audio", "mclk", V_88F6810_PLUS),
326 MPP_VAR_FUNCTION(5, "sd0", "d4", V_88F6810_PLUS),
327 MPP_VAR_FUNCTION(6, "pcie0", "clkreq", V_88F6810_PLUS)),
328 MPP_MODE("mpp49",
329 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
330 MPP_VAR_FUNCTION(1, "sata2", "prsnt", V_88F6828),
331 MPP_VAR_FUNCTION(2, "sata3", "prsnt", V_88F6828),
332 MPP_VAR_FUNCTION(3, "tdm", "fsync", V_88F6810_PLUS),
333 MPP_VAR_FUNCTION(4, "audio", "lrclk", V_88F6810_PLUS),
334 MPP_VAR_FUNCTION(5, "sd0", "d5", V_88F6810_PLUS),
335 MPP_VAR_FUNCTION(6, "pcie1", "clkreq", V_88F6820_PLUS)),
336 MPP_MODE("mpp50",
337 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
338 MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6810_PLUS),
339 MPP_VAR_FUNCTION(3, "tdm", "drx", V_88F6810_PLUS),
340 MPP_VAR_FUNCTION(4, "audio", "extclk", V_88F6810_PLUS),
341 MPP_VAR_FUNCTION(5, "sd0", "cmd", V_88F6810_PLUS)),
342 MPP_MODE("mpp51",
343 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
344 MPP_VAR_FUNCTION(3, "tdm", "dtx", V_88F6810_PLUS),
345 MPP_VAR_FUNCTION(4, "audio", "sdo", V_88F6810_PLUS),
346 MPP_VAR_FUNCTION(5, "dram", "deccerr", V_88F6810_PLUS),
347 MPP_VAR_FUNCTION(6, "ptp", "trig", V_88F6810_PLUS)),
348 MPP_MODE("mpp52",
349 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
350 MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6810_PLUS),
351 MPP_VAR_FUNCTION(3, "tdm", "int", V_88F6810_PLUS),
352 MPP_VAR_FUNCTION(4, "audio", "sdi", V_88F6810_PLUS),
353 MPP_VAR_FUNCTION(5, "sd0", "d6", V_88F6810_PLUS),
354 MPP_VAR_FUNCTION(6, "ptp", "clk", V_88F6810_PLUS)),
355 MPP_MODE("mpp53",
356 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
357 MPP_VAR_FUNCTION(1, "sata1", "prsnt", V_88F6810_PLUS),
358 MPP_VAR_FUNCTION(2, "sata0", "prsnt", V_88F6810_PLUS),
359 MPP_VAR_FUNCTION(3, "tdm", "rst", V_88F6810_PLUS),
360 MPP_VAR_FUNCTION(4, "audio", "bclk", V_88F6810_PLUS),
361 MPP_VAR_FUNCTION(5, "sd0", "d7", V_88F6810_PLUS),
362 MPP_VAR_FUNCTION(6, "ptp", "evreq", V_88F6810_PLUS)),
363 MPP_MODE("mpp54",
364 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
365 MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
366 MPP_VAR_FUNCTION(2, "sata1", "prsnt", V_88F6810_PLUS),
367 MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6810_PLUS),
368 MPP_VAR_FUNCTION(4, "ge0", "txerr", V_88F6810_PLUS),
369 MPP_VAR_FUNCTION(5, "sd0", "d3", V_88F6810_PLUS)),
370 MPP_MODE("mpp55",
371 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
372 MPP_VAR_FUNCTION(1, "ua1", "cts", V_88F6810_PLUS),
373 MPP_VAR_FUNCTION(2, "ge", "mdio", V_88F6810_PLUS),
374 MPP_VAR_FUNCTION(3, "pcie1", "clkreq", V_88F6820_PLUS),
375 MPP_VAR_FUNCTION(4, "spi1", "cs1", V_88F6810_PLUS),
376 MPP_VAR_FUNCTION(5, "sd0", "d0", V_88F6810_PLUS),
377 MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6810_PLUS)),
378 MPP_MODE("mpp56",
379 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
380 MPP_VAR_FUNCTION(1, "ua1", "rts", V_88F6810_PLUS),
381 MPP_VAR_FUNCTION(2, "ge", "mdc", V_88F6810_PLUS),
382 MPP_VAR_FUNCTION(3, "dram", "deccerr", V_88F6810_PLUS),
383 MPP_VAR_FUNCTION(4, "spi1", "mosi", V_88F6810_PLUS),
384 MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6810_PLUS)),
385 MPP_MODE("mpp57",
386 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
387 MPP_VAR_FUNCTION(4, "spi1", "sck", V_88F6810_PLUS),
388 MPP_VAR_FUNCTION(5, "sd0", "clk", V_88F6810_PLUS),
389 MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6810_PLUS)),
390 MPP_MODE("mpp58",
391 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
392 MPP_VAR_FUNCTION(1, "pcie1", "clkreq", V_88F6820_PLUS),
393 MPP_VAR_FUNCTION(2, "i2c1", "sck", V_88F6810_PLUS),
394 MPP_VAR_FUNCTION(3, "pcie2", "clkreq", V_88F6810_PLUS),
395 MPP_VAR_FUNCTION(4, "spi1", "miso", V_88F6810_PLUS),
396 MPP_VAR_FUNCTION(5, "sd0", "d1", V_88F6810_PLUS),
397 MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6810_PLUS)),
398 MPP_MODE("mpp59",
399 MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
400 MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6810_PLUS),
401 MPP_VAR_FUNCTION(2, "i2c1", "sda", V_88F6810_PLUS),
402 MPP_VAR_FUNCTION(4, "spi1", "cs0", V_88F6810_PLUS),
403 MPP_VAR_FUNCTION(5, "sd0", "d2", V_88F6810_PLUS)),
404};
405
406static const char * const armada_38x_mpp_function_names[] = {
407 "gpio", /* make gpio always as function 0 */
408
409 "audio",
410 "dev",
411 "dram",
412 "ge",
413 "ge0",
414 "ge1",
415 "i2c0",
416 "i2c1",
417 "nand",
418 "pcie0",
419 "pcie1",
420 "pcie2",
421 "pcie3",
422 "ptp",
423 "ref",
424 "sata0",
425 "sata1",
426 "sata2",
427 "sata3",
428 "sd0",
429 "spi0",
430 "spi1",
431 "tdm",
432 "ua0",
433 "ua1",
434};
435
436struct armada_38x_pinctrl {
437 void __iomem *base;
438 u8 variant;
439};
440
441static int armada_38x_pinctrl_get_pins_count(struct udevice *dev)
442{
443 return ARRAY_SIZE(armada_38x_mpp_modes);
444}
445
446static const char *armada_38x_pinctrl_get_pin_name(struct udevice *dev, unsigned int selector)
447{
448 return armada_38x_mpp_modes[selector].name;
449}
450
451static int armada_38x_pinctrl_get_functions_count(struct udevice *dev)
452{
453 return ARRAY_SIZE(armada_38x_mpp_function_names);
454}
455
456static const char *armada_38x_pinctrl_get_function_name(struct udevice *dev, unsigned int selector)
457{
458 return armada_38x_mpp_function_names[selector];
459}
460
461static int armada_38x_pinctrl_get_pin_muxing(struct udevice *dev, unsigned int selector,
462 char *buf, int size)
463{
464 struct armada_38x_pinctrl *info = dev_get_priv(dev);
465 unsigned int off = (selector / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
466 unsigned int shift = (selector % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
467 const char *func_name = NULL;
468 const char *sub_name = NULL;
469 unsigned long config;
470 int i;
471
472 config = (readl(info->base + off) >> shift) & MVEBU_MPP_MASK;
473
474 for (i = 0; i < armada_38x_mpp_modes[selector].nsettings; i++) {
475 if (armada_38x_mpp_modes[selector].settings[i].val == config)
476 break;
477 }
478
479 if (i < armada_38x_mpp_modes[selector].nsettings) {
480 func_name = armada_38x_mpp_modes[selector].settings[i].name;
481 sub_name = armada_38x_mpp_modes[selector].settings[i].subname;
482 }
483
484 snprintf(buf, size, "%s%s%s",
485 func_name ? func_name : "unknown",
486 sub_name ? "_" : "",
487 sub_name ? sub_name : "");
488 return 0;
489}
490
491static int armada_38x_pinctrl_pinmux_set(struct udevice *dev, unsigned int pin_selector,
492 unsigned int func_selector)
493{
494 struct armada_38x_pinctrl *info = dev_get_priv(dev);
495 unsigned int off = (pin_selector / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
496 unsigned int shift = (pin_selector % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
497 const char *func_name = armada_38x_mpp_function_names[func_selector];
498 unsigned long config, reg;
499 int i;
500
501 for (i = 0; i < armada_38x_mpp_modes[pin_selector].nsettings; i++) {
502 if (strcmp(armada_38x_mpp_modes[pin_selector].settings[i].name, func_name) == 0)
503 break;
504 }
505
506 if (i >= armada_38x_mpp_modes[pin_selector].nsettings)
507 return -EINVAL;
508
509 if (!(info->variant & armada_38x_mpp_modes[pin_selector].settings[i].variant))
510 return -EINVAL;
511
512 reg = readl(info->base + off) & ~(MVEBU_MPP_MASK << shift);
513 config = armada_38x_mpp_modes[pin_selector].settings[i].val;
514 writel(reg | (config << shift), info->base + off);
515
516 return 0;
517}
518
519static int armada_38x_pinctrl_gpio_request_enable(struct udevice *dev, unsigned int selector)
520{
521 char buf[20];
522
523 armada_38x_pinctrl_get_pin_muxing(dev, selector, buf, sizeof(buf));
524 if (strcmp(buf, "gpio") != 0)
525 printf("Warning: Changing mpp%u function from %s to gpio...\n", selector, buf);
526
527 return armada_38x_pinctrl_pinmux_set(dev, selector, 0); /* gpio is always function 0 */
528}
529
530static int armada_38x_pinctrl_gpio_disable_free(struct udevice *dev, unsigned int selector)
531{
532 /* nothing to do */
533 return 0;
534}
535
536static int armada_38x_pinctrl_set_state(struct udevice *dev, struct udevice *config)
537{
538 return pinctrl_generic_set_state_prefix(dev, config, "marvell,");
539}
540
541static int armada_38x_pinctrl_probe(struct udevice *dev)
542{
543 struct armada_38x_pinctrl *info = dev_get_priv(dev);
544
545 info->variant = (u8)dev_get_driver_data(dev);
546 info->base = dev_read_addr_ptr(dev);
547
548 if (!info->base)
549 return -EINVAL;
550
551 return 0;
552}
553
554struct pinctrl_ops armada_37xx_pinctrl_ops = {
555 .get_pins_count = armada_38x_pinctrl_get_pins_count,
556 .get_pin_name = armada_38x_pinctrl_get_pin_name,
557 .get_functions_count = armada_38x_pinctrl_get_functions_count,
558 .get_function_name = armada_38x_pinctrl_get_function_name,
559 .get_pin_muxing = armada_38x_pinctrl_get_pin_muxing,
560 .pinmux_set = armada_38x_pinctrl_pinmux_set,
561 .gpio_request_enable = armada_38x_pinctrl_gpio_request_enable,
562 .gpio_disable_free = armada_38x_pinctrl_gpio_disable_free,
563 .set_state = armada_38x_pinctrl_set_state,
564};
565
566static const struct udevice_id armada_38x_pinctrl_of_match[] = {
567 {
568 .compatible = "marvell,mv88f6810-pinctrl",
569 .data = V_88F6810,
570 },
571 {
572 .compatible = "marvell,mv88f6820-pinctrl",
573 .data = V_88F6820,
574 },
575 {
576 .compatible = "marvell,mv88f6828-pinctrl",
577 .data = V_88F6828,
578 },
579 { },
580};
581
582U_BOOT_DRIVER(armada_38x_pinctrl) = {
583 .name = "armada-38x-pinctrl",
584 .id = UCLASS_PINCTRL,
585 .of_match = of_match_ptr(armada_38x_pinctrl_of_match),
586 .probe = armada_38x_pinctrl_probe,
587 .priv_auto = sizeof(struct armada_38x_pinctrl),
588 .ops = &armada_37xx_pinctrl_ops,
589};