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