1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
5 * All rights reserved.
6 *
7 * Developed by Semihalf.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of MARVELL nor the names of contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/kdb.h>
40 #include <sys/reboot.h>
41
42 #include <dev/fdt/fdt_common.h>
43 #include <dev/ofw/openfirm.h>
44 #include <dev/ofw/ofw_bus_subr.h>
45
46 #include <machine/bus.h>
47 #include <machine/fdt.h>
48 #include <machine/vmparam.h>
49 #include <machine/intr.h>
50
51 #include <arm/mv/mvreg.h>
52 #include <arm/mv/mvvar.h>
53 #include <arm/mv/mvwin.h>
54
55 MALLOC_DEFINE(M_IDMA, "idma", "idma dma test memory");
56
57 #define IDMA_DEBUG
58 #undef IDMA_DEBUG
59
60 #define MAX_CPU_WIN 5
61
62 #ifdef DEBUG
63 #define debugf(fmt, args...) do { printf("%s(): ", __func__); \
64 printf(fmt,##args); } while (0)
65 #else
66 #define debugf(fmt, args...)
67 #endif
68
69 #ifdef DEBUG
70 #define MV_DUMP_WIN 1
71 #else
72 #define MV_DUMP_WIN 0
73 #endif
74
75 struct soc_node_spec;
76
77 static enum soc_family soc_family;
78
79 static int mv_win_cesa_attr_armada38x(int eng_sel);
80 static int mv_win_cesa_attr_armadaxp(int eng_sel);
81
82 uint32_t read_cpu_ctrl_armv7(uint32_t reg);
83
84 void write_cpu_ctrl_armv7(uint32_t reg, uint32_t val);
85
86 static int win_eth_can_remap(int i);
87
88 static int decode_win_cesa_valid(void);
89 static int decode_win_usb_valid(void);
90 static int decode_win_usb3_valid(void);
91 static int decode_win_eth_valid(void);
92 static int decode_win_pcie_valid(void);
93 static int decode_win_sata_valid(void);
94 static int decode_win_sdhci_valid(void);
95
96 static int decode_win_idma_valid(void);
97 static int decode_win_xor_valid(void);
98
99 static void decode_win_cpu_setup(void);
100 static int decode_win_sdram_fixup(void);
101 static void decode_win_cesa_setup(u_long);
102 static void decode_win_a38x_cesa_setup(u_long);
103 static void decode_win_usb_setup(u_long);
104 static void decode_win_usb3_setup(u_long);
105 static void decode_win_eth_setup(u_long);
106 static void decode_win_neta_setup(u_long);
107 static void decode_win_sata_setup(u_long);
108 static void decode_win_ahci_setup(u_long);
109 static void decode_win_sdhci_setup(u_long);
110
111 static void decode_win_idma_setup(u_long);
112 static void decode_win_xor_setup(u_long);
113
114 static void decode_win_cesa_dump(u_long);
115 static void decode_win_a38x_cesa_dump(u_long);
116 static void decode_win_usb_dump(u_long);
117 static void decode_win_usb3_dump(u_long);
118 static void decode_win_eth_dump(u_long base);
119 static void decode_win_neta_dump(u_long base);
120 static void decode_win_idma_dump(u_long base);
121 static void decode_win_xor_dump(u_long base);
122 static void decode_win_ahci_dump(u_long base);
123 static void decode_win_sdhci_dump(u_long);
124 static void decode_win_pcie_dump(u_long);
125
126 static uint32_t win_cpu_cr_read(int);
127 static uint32_t win_cpu_armv7_cr_read(int);
128 static uint32_t win_cpu_br_read(int);
129 static uint32_t win_cpu_armv7_br_read(int);
130 static uint32_t win_cpu_remap_l_read(int);
131 static uint32_t win_cpu_armv7_remap_l_read(int);
132 static uint32_t win_cpu_remap_h_read(int);
133 static uint32_t win_cpu_armv7_remap_h_read(int);
134
135 static void win_cpu_cr_write(int, uint32_t);
136 static void win_cpu_armv7_cr_write(int, uint32_t);
137 static void win_cpu_br_write(int, uint32_t);
138 static void win_cpu_armv7_br_write(int, uint32_t);
139 static void win_cpu_remap_l_write(int, uint32_t);
140 static void win_cpu_armv7_remap_l_write(int, uint32_t);
141 static void win_cpu_remap_h_write(int, uint32_t);
142 static void win_cpu_armv7_remap_h_write(int, uint32_t);
143
144 static uint32_t ddr_br_read(int);
145 static uint32_t ddr_sz_read(int);
146 static uint32_t ddr_armv7_br_read(int);
147 static uint32_t ddr_armv7_sz_read(int);
148 static void ddr_br_write(int, uint32_t);
149 static void ddr_sz_write(int, uint32_t);
150 static void ddr_armv7_br_write(int, uint32_t);
151 static void ddr_armv7_sz_write(int, uint32_t);
152
153 static int fdt_get_ranges(const char *, void *, int, int *, int *);
154 int gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt,
155 int *trig, int *pol);
156
157 static int win_cpu_from_dt(void);
158 static int fdt_win_setup(void);
159
160 static int fdt_win_process_child(phandle_t, struct soc_node_spec *, const char*);
161
162 static void soc_identify(uint32_t, uint32_t);
163
164 static uint32_t dev_mask = 0;
165 static int cpu_wins_no = 0;
166 static int eth_port = 0;
167 static int usb_port = 0;
168 static boolean_t platform_io_coherent = false;
169
170 static struct decode_win cpu_win_tbl[MAX_CPU_WIN];
171
172 const struct decode_win *cpu_wins = cpu_win_tbl;
173
174 typedef void (*decode_win_setup_t)(u_long);
175 typedef void (*dump_win_t)(u_long);
176 typedef int (*valid_t)(void);
177
178 struct soc_node_spec {
179 const char *compat;
180 decode_win_setup_t decode_handler;
181 dump_win_t dump_handler;
182 valid_t valid_handler;
183 };
184
185 static struct soc_node_spec soc_nodes[] = {
186 { "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump, &decode_win_eth_valid},
187 { "marvell,armada-370-neta", &decode_win_neta_setup,
188 &decode_win_neta_dump, NULL },
189 { "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump, &decode_win_usb_valid},
190 { "marvell,orion-ehci", &decode_win_usb_setup, &decode_win_usb_dump, &decode_win_usb_valid },
191 { "marvell,armada-380-xhci", &decode_win_usb3_setup,
192 &decode_win_usb3_dump, &decode_win_usb3_valid },
193 { "marvell,armada-380-ahci", &decode_win_ahci_setup,
194 &decode_win_ahci_dump, NULL },
195 { "marvell,armada-380-sdhci", &decode_win_sdhci_setup,
196 &decode_win_sdhci_dump, &decode_win_sdhci_valid},
197 { "mrvl,sata", &decode_win_sata_setup, NULL, &decode_win_sata_valid},
198 { "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump, &decode_win_xor_valid},
199 { "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump, &decode_win_idma_valid},
200 { "mrvl,cesa", &decode_win_cesa_setup, &decode_win_cesa_dump, &decode_win_cesa_valid},
201 { "mrvl,pcie", &decode_win_pcie_setup, &decode_win_pcie_dump, &decode_win_pcie_valid},
202 { "marvell,armada-38x-crypto", &decode_win_a38x_cesa_setup,
203 &decode_win_a38x_cesa_dump, &decode_win_cesa_valid},
204 { NULL, NULL, NULL, NULL },
205 };
206
207 #define SOC_NODE_PCIE_ENTRY_IDX 11
208
209 typedef uint32_t(*read_cpu_ctrl_t)(uint32_t);
210 typedef void(*write_cpu_ctrl_t)(uint32_t, uint32_t);
211 typedef uint32_t (*win_read_t)(int);
212 typedef void (*win_write_t)(int, uint32_t);
213 typedef int (*win_cesa_attr_t)(int);
214 typedef uint32_t (*get_t)(void);
215
216 struct decode_win_spec {
217 read_cpu_ctrl_t read_cpu_ctrl;
218 write_cpu_ctrl_t write_cpu_ctrl;
219 win_read_t cr_read;
220 win_read_t br_read;
221 win_read_t remap_l_read;
222 win_read_t remap_h_read;
223 win_write_t cr_write;
224 win_write_t br_write;
225 win_write_t remap_l_write;
226 win_write_t remap_h_write;
227 uint32_t mv_win_cpu_max;
228 win_cesa_attr_t win_cesa_attr;
229 int win_cesa_target;
230 win_read_t ddr_br_read;
231 win_read_t ddr_sz_read;
232 win_write_t ddr_br_write;
233 win_write_t ddr_sz_write;
234 get_t get_tclk;
235 get_t get_cpu_freq;
236 };
237
238 struct decode_win_spec *soc_decode_win_spec;
239
240 static struct decode_win_spec decode_win_specs[] =
241 {
242 {
243 &read_cpu_ctrl_armv7,
244 &write_cpu_ctrl_armv7,
245 &win_cpu_armv7_cr_read,
246 &win_cpu_armv7_br_read,
247 &win_cpu_armv7_remap_l_read,
248 &win_cpu_armv7_remap_h_read,
249 &win_cpu_armv7_cr_write,
250 &win_cpu_armv7_br_write,
251 &win_cpu_armv7_remap_l_write,
252 &win_cpu_armv7_remap_h_write,
253 MV_WIN_CPU_MAX_ARMV7,
254 &mv_win_cesa_attr_armada38x,
255 MV_WIN_CESA_TARGET_ARMADA38X,
256 &ddr_armv7_br_read,
257 &ddr_armv7_sz_read,
258 &ddr_armv7_br_write,
259 &ddr_armv7_sz_write,
260 &get_tclk_armada38x,
261 &get_cpu_freq_armada38x,
262 },
263 {
264 &read_cpu_ctrl_armv7,
265 &write_cpu_ctrl_armv7,
266 &win_cpu_armv7_cr_read,
267 &win_cpu_armv7_br_read,
268 &win_cpu_armv7_remap_l_read,
269 &win_cpu_armv7_remap_h_read,
270 &win_cpu_armv7_cr_write,
271 &win_cpu_armv7_br_write,
272 &win_cpu_armv7_remap_l_write,
273 &win_cpu_armv7_remap_h_write,
274 MV_WIN_CPU_MAX_ARMV7,
275 &mv_win_cesa_attr_armadaxp,
276 MV_WIN_CESA_TARGET_ARMADAXP,
277 &ddr_armv7_br_read,
278 &ddr_armv7_sz_read,
279 &ddr_armv7_br_write,
280 &ddr_armv7_sz_write,
281 &get_tclk_armadaxp,
282 &get_cpu_freq_armadaxp,
283 },
284 };
285
286 struct fdt_pm_mask_entry {
287 char *compat;
288 uint32_t mask;
289 };
290
291 static struct fdt_pm_mask_entry fdt_pm_mask_table[] = {
292 { "mrvl,ge", CPU_PM_CTRL_GE(0) },
293 { "mrvl,ge", CPU_PM_CTRL_GE(1) },
294 { "mrvl,usb-ehci", CPU_PM_CTRL_USB(0) },
295 { "mrvl,usb-ehci", CPU_PM_CTRL_USB(1) },
296 { "mrvl,usb-ehci", CPU_PM_CTRL_USB(2) },
297 { "mrvl,xor", CPU_PM_CTRL_XOR },
298 { "mrvl,sata", CPU_PM_CTRL_SATA },
299 { NULL, 0 }
300 };
301
302 /*
303 * Disable device using power management register.
304 * 1 - Device Power On
305 * 0 - Device Power Off
306 * Mask can be set in loader.
307 * EXAMPLE:
308 * loader> set hw.pm-disable-mask=0x2
309 *
310 * Common mask:
311 * |-------------------------------|
312 * | Device | Kirkwood | Discovery |
313 * |-------------------------------|
314 * | USB0 | 0x00008 | 0x020000 |
315 * |-------------------------------|
316 * | USB1 | - | 0x040000 |
317 * |-------------------------------|
318 * | USB2 | - | 0x080000 |
319 * |-------------------------------|
320 * | GE0 | 0x00001 | 0x000002 |
321 * |-------------------------------|
322 * | GE1 | - | 0x000004 |
323 * |-------------------------------|
324 * | IDMA | - | 0x100000 |
325 * |-------------------------------|
326 * | XOR | 0x10000 | 0x200000 |
327 * |-------------------------------|
328 * | CESA | 0x20000 | 0x400000 |
329 * |-------------------------------|
330 * | SATA | 0x04000 | 0x004000 |
331 * --------------------------------|
332 * This feature can be used only on Kirkwood and Discovery
333 * machines.
334 */
335
mv_win_cesa_attr_armada38x(int eng_sel)336 static int mv_win_cesa_attr_armada38x(int eng_sel)
337 {
338
339 return MV_WIN_CESA_ATTR_ARMADA38X(eng_sel);
340 }
341
mv_win_cesa_attr_armadaxp(int eng_sel)342 static int mv_win_cesa_attr_armadaxp(int eng_sel)
343 {
344
345 return MV_WIN_CESA_ATTR_ARMADAXP(eng_sel);
346 }
347
348 enum soc_family
mv_check_soc_family(void)349 mv_check_soc_family(void)
350 {
351 uint32_t dev, rev;
352
353 soc_id(&dev, &rev);
354 switch (dev) {
355 case MV_DEV_MV78230:
356 case MV_DEV_MV78260:
357 case MV_DEV_MV78460:
358 soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMADA_XP];
359 soc_family = MV_SOC_ARMADA_XP;
360 break;
361 case MV_DEV_88F6828:
362 case MV_DEV_88F6820:
363 case MV_DEV_88F6810:
364 soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMADA_38X];
365 soc_family = MV_SOC_ARMADA_38X;
366 break;
367 default:
368 soc_family = MV_SOC_UNSUPPORTED;
369 return (MV_SOC_UNSUPPORTED);
370 }
371
372 soc_identify(dev, rev);
373
374 return (soc_family);
375 }
376
377 static __inline void
pm_disable_device(int mask)378 pm_disable_device(int mask)
379 {
380 #ifdef DIAGNOSTIC
381 uint32_t reg;
382
383 reg = CPU_PM_CTRL_ALL;
384 reg &= ~mask;
385 soc_power_ctrl_set(reg);
386 printf("Device %x is disabled\n", mask);
387 #endif
388 }
389
390 int
mv_fdt_is_type(phandle_t node,const char * typestr)391 mv_fdt_is_type(phandle_t node, const char *typestr)
392 {
393 #define FDT_TYPE_LEN 64
394 char type[FDT_TYPE_LEN];
395
396 if (OF_getproplen(node, "device_type") <= 0)
397 return (0);
398
399 if (OF_getprop(node, "device_type", type, FDT_TYPE_LEN) < 0)
400 return (0);
401
402 if (strncasecmp(type, typestr, FDT_TYPE_LEN) == 0)
403 /* This fits. */
404 return (1);
405
406 return (0);
407 #undef FDT_TYPE_LEN
408 }
409
410 int
mv_fdt_pm(phandle_t node)411 mv_fdt_pm(phandle_t node)
412 {
413 uint32_t cpu_pm_ctrl;
414 int i, ena, compat;
415
416 ena = 1;
417 cpu_pm_ctrl = read_cpu_ctrl(CPU_PM_CTRL);
418 for (i = 0; fdt_pm_mask_table[i].compat != NULL; i++) {
419 if (dev_mask & (1 << i))
420 continue;
421
422 compat = ofw_bus_node_is_compatible(node,
423 fdt_pm_mask_table[i].compat);
424 if (compat && (~cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
425 dev_mask |= (1 << i);
426 ena = 0;
427 break;
428 } else if (compat) {
429 dev_mask |= (1 << i);
430 break;
431 }
432 }
433
434 return (ena);
435 }
436
437 uint32_t
read_cpu_ctrl(uint32_t reg)438 read_cpu_ctrl(uint32_t reg)
439 {
440
441 if (soc_decode_win_spec->read_cpu_ctrl != NULL)
442 return (soc_decode_win_spec->read_cpu_ctrl(reg));
443 return (-1);
444 }
445
446 uint32_t
read_cpu_ctrl_armv7(uint32_t reg)447 read_cpu_ctrl_armv7(uint32_t reg)
448 {
449
450 return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE_ARMV7, reg));
451 }
452
453 void
write_cpu_ctrl(uint32_t reg,uint32_t val)454 write_cpu_ctrl(uint32_t reg, uint32_t val)
455 {
456
457 if (soc_decode_win_spec->write_cpu_ctrl != NULL)
458 soc_decode_win_spec->write_cpu_ctrl(reg, val);
459 }
460
461 void
write_cpu_ctrl_armv7(uint32_t reg,uint32_t val)462 write_cpu_ctrl_armv7(uint32_t reg, uint32_t val)
463 {
464
465 bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE_ARMV7, reg, val);
466 }
467
468 uint32_t
read_cpu_mp_clocks(uint32_t reg)469 read_cpu_mp_clocks(uint32_t reg)
470 {
471
472 return (bus_space_read_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg));
473 }
474
475 void
write_cpu_mp_clocks(uint32_t reg,uint32_t val)476 write_cpu_mp_clocks(uint32_t reg, uint32_t val)
477 {
478
479 bus_space_write_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg, val);
480 }
481
482 uint32_t
read_cpu_misc(uint32_t reg)483 read_cpu_misc(uint32_t reg)
484 {
485
486 return (bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE, reg));
487 }
488
489 void
write_cpu_misc(uint32_t reg,uint32_t val)490 write_cpu_misc(uint32_t reg, uint32_t val)
491 {
492
493 bus_space_write_4(fdtbus_bs_tag, MV_MISC_BASE, reg, val);
494 }
495
496 /*
497 * Set the power status of device. This feature was only supported on
498 * Kirkwood and Discovery SoCs.
499 */
500 void
soc_power_ctrl_set(uint32_t mask)501 soc_power_ctrl_set(uint32_t mask)
502 {
503
504 if (mask != CPU_PM_CTRL_NONE)
505 write_cpu_ctrl(CPU_PM_CTRL, mask);
506 }
507
508 void
soc_id(uint32_t * dev,uint32_t * rev)509 soc_id(uint32_t *dev, uint32_t *rev)
510 {
511 uint64_t mv_pcie_base = MV_PCIE_BASE;
512 phandle_t node;
513
514 /*
515 * Notice: system identifiers are available in the registers range of
516 * PCIE controller, so using this function is only allowed (and
517 * possible) after the internal registers range has been mapped in via
518 * devmap_bootstrap().
519 */
520 *dev = 0;
521 *rev = 0;
522 if ((node = OF_finddevice("/")) == -1)
523 return;
524 if (ofw_bus_node_is_compatible(node, "marvell,armada380"))
525 mv_pcie_base = MV_PCIE_BASE_ARMADA38X;
526
527 *dev = bus_space_read_4(fdtbus_bs_tag, mv_pcie_base, 0) >> 16;
528 *rev = bus_space_read_4(fdtbus_bs_tag, mv_pcie_base, 8) & 0xff;
529 }
530
531 static void
soc_identify(uint32_t d,uint32_t r)532 soc_identify(uint32_t d, uint32_t r)
533 {
534 uint32_t mode, freq;
535 const char *dev;
536 const char *rev;
537
538 printf("SOC: ");
539 if (bootverbose)
540 printf("(0x%4x:0x%02x) ", d, r);
541
542 rev = "";
543 switch (d) {
544 case MV_DEV_88F6828:
545 dev = "Marvell 88F6828";
546 break;
547 case MV_DEV_88F6820:
548 dev = "Marvell 88F6820";
549 break;
550 case MV_DEV_88F6810:
551 dev = "Marvell 88F6810";
552 break;
553 case MV_DEV_MV78260:
554 dev = "Marvell MV78260";
555 break;
556 case MV_DEV_MV78460:
557 dev = "Marvell MV78460";
558 break;
559 default:
560 dev = "UNKNOWN";
561 break;
562 }
563
564 printf("%s", dev);
565 if (*rev != '\0')
566 printf(" rev %s", rev);
567 printf(", TClock %dMHz", get_tclk() / 1000 / 1000);
568 freq = get_cpu_freq();
569 if (freq != 0)
570 printf(", Frequency %dMHz", freq / 1000 / 1000);
571 printf("\n");
572
573 mode = read_cpu_ctrl(CPU_CONFIG);
574 printf(" Instruction cache prefetch %s, data cache prefetch %s\n",
575 (mode & CPU_CONFIG_IC_PREF) ? "enabled" : "disabled",
576 (mode & CPU_CONFIG_DC_PREF) ? "enabled" : "disabled");
577 }
578
579 #ifdef KDB
580 static void
mv_enter_debugger(void * dummy)581 mv_enter_debugger(void *dummy)
582 {
583
584 if (boothowto & RB_KDB)
585 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
586 }
587 SYSINIT(mv_enter_debugger, SI_SUB_CPU, SI_ORDER_ANY, mv_enter_debugger, NULL);
588 #endif
589
590 int
soc_decode_win(void)591 soc_decode_win(void)
592 {
593 uint32_t dev, rev;
594 int mask, err;
595
596 mask = 0;
597 TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
598
599 if (mask != 0)
600 pm_disable_device(mask);
601
602 /* Retrieve data about physical addresses from device tree. */
603 if ((err = win_cpu_from_dt()) != 0)
604 return (err);
605
606 /* Retrieve our ID: some windows facilities vary between SoC models */
607 soc_id(&dev, &rev);
608
609 if (soc_family == MV_SOC_ARMADA_XP)
610 if ((err = decode_win_sdram_fixup()) != 0)
611 return(err);
612
613 decode_win_cpu_setup();
614 if (MV_DUMP_WIN)
615 soc_dump_decode_win();
616
617 eth_port = 0;
618 usb_port = 0;
619 if ((err = fdt_win_setup()) != 0)
620 return (err);
621
622 return (0);
623 }
624
625 /**************************************************************************
626 * Decode windows registers accessors
627 **************************************************************************/
628
WIN_REG_IDX_RD(win_cpu_armv7,cr,MV_WIN_CPU_CTRL_ARMV7,MV_MBUS_BRIDGE_BASE)629 WIN_REG_IDX_RD(win_cpu_armv7, cr, MV_WIN_CPU_CTRL_ARMV7, MV_MBUS_BRIDGE_BASE)
630 WIN_REG_IDX_RD(win_cpu_armv7, br, MV_WIN_CPU_BASE_ARMV7, MV_MBUS_BRIDGE_BASE)
631 WIN_REG_IDX_RD(win_cpu_armv7, remap_l, MV_WIN_CPU_REMAP_LO_ARMV7, MV_MBUS_BRIDGE_BASE)
632 WIN_REG_IDX_RD(win_cpu_armv7, remap_h, MV_WIN_CPU_REMAP_HI_ARMV7, MV_MBUS_BRIDGE_BASE)
633 WIN_REG_IDX_WR(win_cpu_armv7, cr, MV_WIN_CPU_CTRL_ARMV7, MV_MBUS_BRIDGE_BASE)
634 WIN_REG_IDX_WR(win_cpu_armv7, br, MV_WIN_CPU_BASE_ARMV7, MV_MBUS_BRIDGE_BASE)
635 WIN_REG_IDX_WR(win_cpu_armv7, remap_l, MV_WIN_CPU_REMAP_LO_ARMV7, MV_MBUS_BRIDGE_BASE)
636 WIN_REG_IDX_WR(win_cpu_armv7, remap_h, MV_WIN_CPU_REMAP_HI_ARMV7, MV_MBUS_BRIDGE_BASE)
637
638 static uint32_t
639 win_cpu_cr_read(int i)
640 {
641
642 if (soc_decode_win_spec->cr_read != NULL)
643 return (soc_decode_win_spec->cr_read(i));
644 return (-1);
645 }
646
647 static uint32_t
win_cpu_br_read(int i)648 win_cpu_br_read(int i)
649 {
650
651 if (soc_decode_win_spec->br_read != NULL)
652 return (soc_decode_win_spec->br_read(i));
653 return (-1);
654 }
655
656 static uint32_t
win_cpu_remap_l_read(int i)657 win_cpu_remap_l_read(int i)
658 {
659
660 if (soc_decode_win_spec->remap_l_read != NULL)
661 return (soc_decode_win_spec->remap_l_read(i));
662 return (-1);
663 }
664
665 static uint32_t
win_cpu_remap_h_read(int i)666 win_cpu_remap_h_read(int i)
667 {
668
669 if (soc_decode_win_spec->remap_h_read != NULL)
670 return soc_decode_win_spec->remap_h_read(i);
671 return (-1);
672 }
673
674 static void
win_cpu_cr_write(int i,uint32_t val)675 win_cpu_cr_write(int i, uint32_t val)
676 {
677
678 if (soc_decode_win_spec->cr_write != NULL)
679 soc_decode_win_spec->cr_write(i, val);
680 }
681
682 static void
win_cpu_br_write(int i,uint32_t val)683 win_cpu_br_write(int i, uint32_t val)
684 {
685
686 if (soc_decode_win_spec->br_write != NULL)
687 soc_decode_win_spec->br_write(i, val);
688 }
689
690 static void
win_cpu_remap_l_write(int i,uint32_t val)691 win_cpu_remap_l_write(int i, uint32_t val)
692 {
693
694 if (soc_decode_win_spec->remap_l_write != NULL)
695 soc_decode_win_spec->remap_l_write(i, val);
696 }
697
698 static void
win_cpu_remap_h_write(int i,uint32_t val)699 win_cpu_remap_h_write(int i, uint32_t val)
700 {
701
702 if (soc_decode_win_spec->remap_h_write != NULL)
703 soc_decode_win_spec->remap_h_write(i, val);
704 }
705
706 WIN_REG_BASE_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL)
707 WIN_REG_BASE_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE)
708 WIN_REG_BASE_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL)
709 WIN_REG_BASE_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE)
710
711 WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
712 WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
713 WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
714 WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE)
715
716 WIN_REG_BASE_IDX_RD(win_usb3, cr, MV_WIN_USB3_CTRL)
717 WIN_REG_BASE_IDX_RD(win_usb3, br, MV_WIN_USB3_BASE)
718 WIN_REG_BASE_IDX_WR(win_usb3, cr, MV_WIN_USB3_CTRL)
719 WIN_REG_BASE_IDX_WR(win_usb3, br, MV_WIN_USB3_BASE)
720
721 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
722 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
723 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
724 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
725 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
726 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
727
728 WIN_REG_BASE_RD(win_eth, bare, 0x290)
729 WIN_REG_BASE_RD(win_eth, epap, 0x294)
730 WIN_REG_BASE_WR(win_eth, bare, 0x290)
731 WIN_REG_BASE_WR(win_eth, epap, 0x294)
732
733 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
734 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
735 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
736 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
737 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
738 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
739 WIN_REG_BASE_IDX_RD(pcie_bar, br, MV_PCIE_BAR_BASE);
740 WIN_REG_BASE_IDX_RD(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
741 WIN_REG_BASE_IDX_RD(pcie_bar, cr, MV_PCIE_BAR_CTRL);
742 WIN_REG_BASE_IDX_WR(pcie_bar, br, MV_PCIE_BAR_BASE);
743 WIN_REG_BASE_IDX_WR(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
744 WIN_REG_BASE_IDX_WR(pcie_bar, cr, MV_PCIE_BAR_CTRL);
745
746 WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL);
747 WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE);
748 WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL);
749 WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE);
750
751 WIN_REG_BASE_IDX_RD(win_sata_armada38x, sz, MV_WIN_SATA_SIZE_ARMADA38X);
752 WIN_REG_BASE_IDX_WR(win_sata_armada38x, sz, MV_WIN_SATA_SIZE_ARMADA38X);
753 WIN_REG_BASE_IDX_RD(win_sata_armada38x, cr, MV_WIN_SATA_CTRL_ARMADA38X);
754 WIN_REG_BASE_IDX_WR(win_sata_armada38x, cr, MV_WIN_SATA_CTRL_ARMADA38X);
755 WIN_REG_BASE_IDX_WR(win_sata_armada38x, br, MV_WIN_SATA_BASE_ARMADA38X);
756
757 WIN_REG_BASE_IDX_RD(win_sdhci, cr, MV_WIN_SDHCI_CTRL);
758 WIN_REG_BASE_IDX_RD(win_sdhci, br, MV_WIN_SDHCI_BASE);
759 WIN_REG_BASE_IDX_WR(win_sdhci, cr, MV_WIN_SDHCI_CTRL);
760 WIN_REG_BASE_IDX_WR(win_sdhci, br, MV_WIN_SDHCI_BASE);
761
762 #ifndef SOC_MV_DOVE
WIN_REG_IDX_RD(ddr_armv7,br,MV_WIN_DDR_BASE,MV_DDR_CADR_BASE_ARMV7)763 WIN_REG_IDX_RD(ddr_armv7, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE_ARMV7)
764 WIN_REG_IDX_RD(ddr_armv7, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE_ARMV7)
765 WIN_REG_IDX_WR(ddr_armv7, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE_ARMV7)
766 WIN_REG_IDX_WR(ddr_armv7, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE_ARMV7)
767
768 static inline uint32_t
769 ddr_br_read(int i)
770 {
771
772 if (soc_decode_win_spec->ddr_br_read != NULL)
773 return (soc_decode_win_spec->ddr_br_read(i));
774 return (-1);
775 }
776
777 static inline uint32_t
ddr_sz_read(int i)778 ddr_sz_read(int i)
779 {
780
781 if (soc_decode_win_spec->ddr_sz_read != NULL)
782 return (soc_decode_win_spec->ddr_sz_read(i));
783 return (-1);
784 }
785
786 static inline void
ddr_br_write(int i,uint32_t val)787 ddr_br_write(int i, uint32_t val)
788 {
789
790 if (soc_decode_win_spec->ddr_br_write != NULL)
791 soc_decode_win_spec->ddr_br_write(i, val);
792 }
793
794 static inline void
ddr_sz_write(int i,uint32_t val)795 ddr_sz_write(int i, uint32_t val)
796 {
797
798 if (soc_decode_win_spec->ddr_sz_write != NULL)
799 soc_decode_win_spec->ddr_sz_write(i, val);
800 }
801 #else
802 /*
803 * On 88F6781 (Dove) SoC DDR Controller is accessed through
804 * single MBUS <-> AXI bridge. In this case we provide emulated
805 * ddr_br_read() and ddr_sz_read() functions to keep compatibility
806 * with common decoding windows setup code.
807 */
808
ddr_br_read(int i)809 static inline uint32_t ddr_br_read(int i)
810 {
811 uint32_t mmap;
812
813 /* Read Memory Address Map Register for CS i */
814 mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
815
816 /* Return CS i base address */
817 return (mmap & 0xFF000000);
818 }
819
ddr_sz_read(int i)820 static inline uint32_t ddr_sz_read(int i)
821 {
822 uint32_t mmap, size;
823
824 /* Read Memory Address Map Register for CS i */
825 mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
826
827 /* Extract size of CS space in 64kB units */
828 size = (1 << ((mmap >> 16) & 0x0F));
829
830 /* Return CS size and enable/disable status */
831 return (((size - 1) << 16) | (mmap & 0x01));
832 }
833 #endif
834
835 /**************************************************************************
836 * Decode windows helper routines
837 **************************************************************************/
838 void
soc_dump_decode_win(void)839 soc_dump_decode_win(void)
840 {
841 int i;
842
843 for (i = 0; i < soc_decode_win_spec->mv_win_cpu_max; i++) {
844 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
845 win_cpu_cr_read(i),
846 win_cpu_br_read(i));
847
848 if (win_cpu_can_remap(i))
849 printf(", rl 0x%08x, rh 0x%08x",
850 win_cpu_remap_l_read(i),
851 win_cpu_remap_h_read(i));
852
853 printf("\n");
854 }
855 printf("Internal regs base: 0x%08x\n",
856 bus_space_read_4(fdtbus_bs_tag, MV_INTREGS_BASE, 0));
857
858 for (i = 0; i < MV_WIN_DDR_MAX; i++)
859 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
860 ddr_br_read(i), ddr_sz_read(i));
861 }
862
863 /**************************************************************************
864 * CPU windows routines
865 **************************************************************************/
866 int
win_cpu_can_remap(int i)867 win_cpu_can_remap(int i)
868 {
869 uint32_t dev, rev;
870
871 soc_id(&dev, &rev);
872
873 /* Depending on the SoC certain windows have remap capability */
874 if ((dev == MV_DEV_88F6828 && i < 20) ||
875 (dev == MV_DEV_88F6820 && i < 20) ||
876 (dev == MV_DEV_88F6810 && i < 20))
877 return (1);
878
879 return (0);
880 }
881
882 /* XXX This should check for overlapping remap fields too.. */
883 int
decode_win_overlap(int win,int win_no,const struct decode_win * wintab)884 decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
885 {
886 const struct decode_win *tab;
887 int i;
888
889 tab = wintab;
890
891 for (i = 0; i < win_no; i++, tab++) {
892 if (i == win)
893 /* Skip self */
894 continue;
895
896 if ((tab->base + tab->size - 1) < (wintab + win)->base)
897 continue;
898
899 else if (((wintab + win)->base + (wintab + win)->size - 1) <
900 tab->base)
901 continue;
902 else
903 return (i);
904 }
905
906 return (-1);
907 }
908
909 int
decode_win_cpu_set(int target,int attr,vm_paddr_t base,uint32_t size,vm_paddr_t remap)910 decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
911 vm_paddr_t remap)
912 {
913 uint32_t br, cr;
914 int win, i;
915
916 if (remap == ~0) {
917 win = soc_decode_win_spec->mv_win_cpu_max - 1;
918 i = -1;
919 } else {
920 win = 0;
921 i = 1;
922 }
923
924 while ((win >= 0) && (win < soc_decode_win_spec->mv_win_cpu_max)) {
925 cr = win_cpu_cr_read(win);
926 if ((cr & MV_WIN_CPU_ENABLE_BIT) == 0)
927 break;
928 if ((cr & ((0xff << MV_WIN_CPU_ATTR_SHIFT) |
929 (0x1f << MV_WIN_CPU_TARGET_SHIFT))) ==
930 ((attr << MV_WIN_CPU_ATTR_SHIFT) |
931 (target << MV_WIN_CPU_TARGET_SHIFT)))
932 break;
933 win += i;
934 }
935 if ((win < 0) || (win >= soc_decode_win_spec->mv_win_cpu_max) ||
936 ((remap != ~0) && (win_cpu_can_remap(win) == 0)))
937 return (-1);
938
939 br = base & 0xffff0000;
940 win_cpu_br_write(win, br);
941
942 if (win_cpu_can_remap(win)) {
943 if (remap != ~0) {
944 win_cpu_remap_l_write(win, remap & 0xffff0000);
945 win_cpu_remap_h_write(win, 0);
946 } else {
947 /*
948 * Remap function is not used for a given window
949 * (capable of remapping) - set remap field with the
950 * same value as base.
951 */
952 win_cpu_remap_l_write(win, base & 0xffff0000);
953 win_cpu_remap_h_write(win, 0);
954 }
955 }
956
957 cr = ((size - 1) & 0xffff0000) | (attr << MV_WIN_CPU_ATTR_SHIFT) |
958 (target << MV_WIN_CPU_TARGET_SHIFT) | MV_WIN_CPU_ENABLE_BIT;
959 win_cpu_cr_write(win, cr);
960
961 return (0);
962 }
963
964 static void
decode_win_cpu_setup(void)965 decode_win_cpu_setup(void)
966 {
967 int i;
968
969 /* Disable all CPU windows */
970 for (i = 0; i < soc_decode_win_spec->mv_win_cpu_max; i++) {
971 win_cpu_cr_write(i, 0);
972 win_cpu_br_write(i, 0);
973 if (win_cpu_can_remap(i)) {
974 win_cpu_remap_l_write(i, 0);
975 win_cpu_remap_h_write(i, 0);
976 }
977 }
978
979 for (i = 0; i < cpu_wins_no; i++)
980 if (cpu_wins[i].target > 0)
981 decode_win_cpu_set(cpu_wins[i].target,
982 cpu_wins[i].attr, cpu_wins[i].base,
983 cpu_wins[i].size, cpu_wins[i].remap);
984
985 }
986
987 static int
decode_win_sdram_fixup(void)988 decode_win_sdram_fixup(void)
989 {
990 struct mem_region mr[FDT_MEM_REGIONS];
991 uint8_t window_valid[MV_WIN_DDR_MAX];
992 int mr_cnt, err, i, j;
993 uint32_t valid_win_num = 0;
994
995 /* Grab physical memory regions information from device tree. */
996 err = fdt_get_mem_regions(mr, &mr_cnt, NULL);
997 if (err != 0)
998 return (err);
999
1000 for (i = 0; i < MV_WIN_DDR_MAX; i++)
1001 window_valid[i] = 0;
1002
1003 /* Try to match entries from device tree with settings from u-boot */
1004 for (i = 0; i < mr_cnt; i++) {
1005 for (j = 0; j < MV_WIN_DDR_MAX; j++) {
1006 if (ddr_is_active(j) &&
1007 (ddr_base(j) == mr[i].mr_start) &&
1008 (ddr_size(j) == mr[i].mr_size)) {
1009 window_valid[j] = 1;
1010 valid_win_num++;
1011 }
1012 }
1013 }
1014
1015 if (mr_cnt != valid_win_num)
1016 return (EINVAL);
1017
1018 /* Destroy windows without corresponding device tree entry */
1019 for (j = 0; j < MV_WIN_DDR_MAX; j++) {
1020 if (ddr_is_active(j) && (window_valid[j] != 1)) {
1021 printf("Disabling SDRAM decoding window: %d\n", j);
1022 ddr_disable(j);
1023 }
1024 }
1025
1026 return (0);
1027 }
1028 /*
1029 * Check if we're able to cover all active DDR banks.
1030 */
1031 static int
decode_win_can_cover_ddr(int max)1032 decode_win_can_cover_ddr(int max)
1033 {
1034 int i, c;
1035
1036 c = 0;
1037 for (i = 0; i < MV_WIN_DDR_MAX; i++)
1038 if (ddr_is_active(i))
1039 c++;
1040
1041 if (c > max) {
1042 printf("Unable to cover all active DDR banks: "
1043 "%d, available windows: %d\n", c, max);
1044 return (0);
1045 }
1046
1047 return (1);
1048 }
1049
1050 /**************************************************************************
1051 * DDR windows routines
1052 **************************************************************************/
1053 int
ddr_is_active(int i)1054 ddr_is_active(int i)
1055 {
1056
1057 if (ddr_sz_read(i) & 0x1)
1058 return (1);
1059
1060 return (0);
1061 }
1062
1063 void
ddr_disable(int i)1064 ddr_disable(int i)
1065 {
1066
1067 ddr_sz_write(i, 0);
1068 ddr_br_write(i, 0);
1069 }
1070
1071 uint32_t
ddr_base(int i)1072 ddr_base(int i)
1073 {
1074
1075 return (ddr_br_read(i) & 0xff000000);
1076 }
1077
1078 uint32_t
ddr_size(int i)1079 ddr_size(int i)
1080 {
1081
1082 return ((ddr_sz_read(i) | 0x00ffffff) + 1);
1083 }
1084
1085 uint32_t
ddr_attr(int i)1086 ddr_attr(int i)
1087 {
1088 uint32_t attr;
1089
1090 attr = (i == 0 ? 0xe :
1091 (i == 1 ? 0xd :
1092 (i == 2 ? 0xb :
1093 (i == 3 ? 0x7 : 0xff))));
1094 if (platform_io_coherent)
1095 attr |= 0x10;
1096
1097 return (attr);
1098 }
1099
1100 /**************************************************************************
1101 * CESA windows routines
1102 **************************************************************************/
1103 static int
decode_win_cesa_valid(void)1104 decode_win_cesa_valid(void)
1105 {
1106
1107 return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
1108 }
1109
1110 static void
decode_win_cesa_dump(u_long base)1111 decode_win_cesa_dump(u_long base)
1112 {
1113 int i;
1114
1115 for (i = 0; i < MV_WIN_CESA_MAX; i++)
1116 printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
1117 win_cesa_cr_read(base, i), win_cesa_br_read(base, i));
1118 }
1119
1120 /*
1121 * Set CESA decode windows.
1122 */
1123 static void
decode_win_cesa_setup(u_long base)1124 decode_win_cesa_setup(u_long base)
1125 {
1126 uint32_t br, cr;
1127 uint64_t size;
1128 int i, j;
1129
1130 for (i = 0; i < MV_WIN_CESA_MAX; i++) {
1131 win_cesa_cr_write(base, i, 0);
1132 win_cesa_br_write(base, i, 0);
1133 }
1134
1135 /* Only access to active DRAM banks is required */
1136 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1137 if (ddr_is_active(i)) {
1138 br = ddr_base(i);
1139
1140 size = ddr_size(i);
1141 /*
1142 * Armada 38x SoC's equipped with 4GB DRAM
1143 * suffer freeze during CESA operation, if
1144 * MBUS window opened at given DRAM CS reaches
1145 * end of the address space. Apply a workaround
1146 * by setting the window size to the closest possible
1147 * value, i.e. divide it by 2.
1148 */
1149 if ((soc_family == MV_SOC_ARMADA_38X) &&
1150 (size + ddr_base(i) == 0x100000000ULL))
1151 size /= 2;
1152
1153 cr = (((size - 1) & 0xffff0000) |
1154 (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1155 IO_WIN_ENA_MASK);
1156
1157 /* Set the first free CESA window */
1158 for (j = 0; j < MV_WIN_CESA_MAX; j++) {
1159 if (win_cesa_cr_read(base, j) & 0x1)
1160 continue;
1161
1162 win_cesa_br_write(base, j, br);
1163 win_cesa_cr_write(base, j, cr);
1164 break;
1165 }
1166 }
1167 }
1168 }
1169
1170 static void
decode_win_a38x_cesa_setup(u_long base)1171 decode_win_a38x_cesa_setup(u_long base)
1172 {
1173 decode_win_cesa_setup(base);
1174 decode_win_cesa_setup(base + MV_WIN_CESA_OFFSET);
1175 }
1176
1177 static void
decode_win_a38x_cesa_dump(u_long base)1178 decode_win_a38x_cesa_dump(u_long base)
1179 {
1180 decode_win_cesa_dump(base);
1181 decode_win_cesa_dump(base + MV_WIN_CESA_OFFSET);
1182 }
1183
1184 /**************************************************************************
1185 * USB windows routines
1186 **************************************************************************/
1187 static int
decode_win_usb_valid(void)1188 decode_win_usb_valid(void)
1189 {
1190
1191 return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
1192 }
1193
1194 static void
decode_win_usb_dump(u_long base)1195 decode_win_usb_dump(u_long base)
1196 {
1197 int i;
1198
1199 for (i = 0; i < MV_WIN_USB_MAX; i++)
1200 printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
1201 win_usb_cr_read(base, i), win_usb_br_read(base, i));
1202 }
1203
1204 /*
1205 * Set USB decode windows.
1206 */
1207 static void
decode_win_usb_setup(u_long base)1208 decode_win_usb_setup(u_long base)
1209 {
1210 uint32_t br, cr;
1211 int i, j;
1212
1213 usb_port++;
1214
1215 for (i = 0; i < MV_WIN_USB_MAX; i++) {
1216 win_usb_cr_write(base, i, 0);
1217 win_usb_br_write(base, i, 0);
1218 }
1219
1220 /* Only access to active DRAM banks is required */
1221 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1222 if (ddr_is_active(i)) {
1223 br = ddr_base(i);
1224 /*
1225 * XXX for 6281 we should handle Mbus write
1226 * burst limit field in the ctrl reg
1227 */
1228 cr = (((ddr_size(i) - 1) & 0xffff0000) |
1229 (ddr_attr(i) << 8) | 1);
1230
1231 /* Set the first free USB window */
1232 for (j = 0; j < MV_WIN_USB_MAX; j++) {
1233 if (win_usb_cr_read(base, j) & 0x1)
1234 continue;
1235
1236 win_usb_br_write(base, j, br);
1237 win_usb_cr_write(base, j, cr);
1238 break;
1239 }
1240 }
1241 }
1242 }
1243
1244 /**************************************************************************
1245 * USB3 windows routines
1246 **************************************************************************/
1247 static int
decode_win_usb3_valid(void)1248 decode_win_usb3_valid(void)
1249 {
1250
1251 return (decode_win_can_cover_ddr(MV_WIN_USB3_MAX));
1252 }
1253
1254 static void
decode_win_usb3_dump(u_long base)1255 decode_win_usb3_dump(u_long base)
1256 {
1257 int i;
1258
1259 for (i = 0; i < MV_WIN_USB3_MAX; i++)
1260 printf("USB3.0 window#%d: c 0x%08x, b 0x%08x\n", i,
1261 win_usb3_cr_read(base, i), win_usb3_br_read(base, i));
1262 }
1263
1264 /*
1265 * Set USB3 decode windows
1266 */
1267 static void
decode_win_usb3_setup(u_long base)1268 decode_win_usb3_setup(u_long base)
1269 {
1270 uint32_t br, cr;
1271 int i, j;
1272
1273 for (i = 0; i < MV_WIN_USB3_MAX; i++) {
1274 win_usb3_cr_write(base, i, 0);
1275 win_usb3_br_write(base, i, 0);
1276 }
1277
1278 /* Only access to active DRAM banks is required */
1279 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1280 if (ddr_is_active(i)) {
1281 br = ddr_base(i);
1282 cr = (((ddr_size(i) - 1) &
1283 (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT)) |
1284 (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1285 IO_WIN_ENA_MASK);
1286
1287 /* Set the first free USB3.0 window */
1288 for (j = 0; j < MV_WIN_USB3_MAX; j++) {
1289 if (win_usb3_cr_read(base, j) & IO_WIN_ENA_MASK)
1290 continue;
1291
1292 win_usb3_br_write(base, j, br);
1293 win_usb3_cr_write(base, j, cr);
1294 break;
1295 }
1296 }
1297 }
1298 }
1299
1300 /**************************************************************************
1301 * ETH windows routines
1302 **************************************************************************/
1303
1304 static int
win_eth_can_remap(int i)1305 win_eth_can_remap(int i)
1306 {
1307
1308 /* ETH encode windows 0-3 have remap capability */
1309 if (i < 4)
1310 return (1);
1311
1312 return (0);
1313 }
1314
1315 static int
eth_bare_read(uint32_t base,int i)1316 eth_bare_read(uint32_t base, int i)
1317 {
1318 uint32_t v;
1319
1320 v = win_eth_bare_read(base);
1321 v &= (1 << i);
1322
1323 return (v >> i);
1324 }
1325
1326 static void
eth_bare_write(uint32_t base,int i,int val)1327 eth_bare_write(uint32_t base, int i, int val)
1328 {
1329 uint32_t v;
1330
1331 v = win_eth_bare_read(base);
1332 v &= ~(1 << i);
1333 v |= (val << i);
1334 win_eth_bare_write(base, v);
1335 }
1336
1337 static void
eth_epap_write(uint32_t base,int i,int val)1338 eth_epap_write(uint32_t base, int i, int val)
1339 {
1340 uint32_t v;
1341
1342 v = win_eth_epap_read(base);
1343 v &= ~(0x3 << (i * 2));
1344 v |= (val << (i * 2));
1345 win_eth_epap_write(base, v);
1346 }
1347
1348 static void
decode_win_eth_dump(u_long base)1349 decode_win_eth_dump(u_long base)
1350 {
1351 int i;
1352
1353 for (i = 0; i < MV_WIN_ETH_MAX; i++) {
1354 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
1355 win_eth_br_read(base, i),
1356 win_eth_sz_read(base, i));
1357
1358 if (win_eth_can_remap(i))
1359 printf(", ha 0x%08x",
1360 win_eth_har_read(base, i));
1361
1362 printf("\n");
1363 }
1364 printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
1365 win_eth_bare_read(base),
1366 win_eth_epap_read(base));
1367 }
1368
1369 static void
decode_win_eth_setup(u_long base)1370 decode_win_eth_setup(u_long base)
1371 {
1372 uint32_t br, sz;
1373 int i, j;
1374
1375 eth_port++;
1376
1377 /* Disable, clear and revoke protection for all ETH windows */
1378 for (i = 0; i < MV_WIN_ETH_MAX; i++) {
1379 eth_bare_write(base, i, 1);
1380 eth_epap_write(base, i, 0);
1381 win_eth_br_write(base, i, 0);
1382 win_eth_sz_write(base, i, 0);
1383 if (win_eth_can_remap(i))
1384 win_eth_har_write(base, i, 0);
1385 }
1386
1387 /* Only access to active DRAM banks is required */
1388 for (i = 0; i < MV_WIN_DDR_MAX; i++)
1389 if (ddr_is_active(i)) {
1390 br = ddr_base(i) | (ddr_attr(i) << 8);
1391 sz = ((ddr_size(i) - 1) & 0xffff0000);
1392
1393 /* Set the first free ETH window */
1394 for (j = 0; j < MV_WIN_ETH_MAX; j++) {
1395 if (eth_bare_read(base, j) == 0)
1396 continue;
1397
1398 win_eth_br_write(base, j, br);
1399 win_eth_sz_write(base, j, sz);
1400
1401 /* XXX remapping ETH windows not supported */
1402
1403 /* Set protection RW */
1404 eth_epap_write(base, j, 0x3);
1405
1406 /* Enable window */
1407 eth_bare_write(base, j, 0);
1408 break;
1409 }
1410 }
1411 }
1412
1413 static void
decode_win_neta_dump(u_long base)1414 decode_win_neta_dump(u_long base)
1415 {
1416
1417 decode_win_eth_dump(base + MV_WIN_NETA_OFFSET);
1418 }
1419
1420 static void
decode_win_neta_setup(u_long base)1421 decode_win_neta_setup(u_long base)
1422 {
1423
1424 decode_win_eth_setup(base + MV_WIN_NETA_OFFSET);
1425 }
1426
1427 static int
decode_win_eth_valid(void)1428 decode_win_eth_valid(void)
1429 {
1430
1431 return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
1432 }
1433
1434 /**************************************************************************
1435 * PCIE windows routines
1436 **************************************************************************/
1437 static void
decode_win_pcie_dump(u_long base)1438 decode_win_pcie_dump(u_long base)
1439 {
1440 int i;
1441
1442 printf("PCIE windows base 0x%08lx\n", base);
1443 for (i = 0; i < MV_WIN_PCIE_MAX; i++)
1444 printf("PCIE window#%d: cr 0x%08x br 0x%08x remap 0x%08x\n",
1445 i, win_pcie_cr_read(base, i),
1446 win_pcie_br_read(base, i), win_pcie_remap_read(base, i));
1447
1448 for (i = 0; i < MV_PCIE_BAR_MAX; i++)
1449 printf("PCIE bar#%d: cr 0x%08x br 0x%08x brh 0x%08x\n",
1450 i, pcie_bar_cr_read(base, i),
1451 pcie_bar_br_read(base, i), pcie_bar_brh_read(base, i));
1452 }
1453
1454 void
decode_win_pcie_setup(u_long base)1455 decode_win_pcie_setup(u_long base)
1456 {
1457 uint32_t size = 0, ddrbase = ~0;
1458 uint32_t cr, br;
1459 int i, j;
1460
1461 for (i = 0; i < MV_PCIE_BAR_MAX; i++) {
1462 pcie_bar_br_write(base, i,
1463 MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1464 if (i < 3)
1465 pcie_bar_brh_write(base, i, 0);
1466 if (i > 0)
1467 pcie_bar_cr_write(base, i, 0);
1468 }
1469
1470 for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
1471 win_pcie_cr_write(base, i, 0);
1472 win_pcie_br_write(base, i, 0);
1473 win_pcie_remap_write(base, i, 0);
1474 }
1475
1476 /* On End-Point only set BAR size to 1MB regardless of DDR size */
1477 if ((bus_space_read_4(fdtbus_bs_tag, base, MV_PCIE_CONTROL)
1478 & MV_PCIE_ROOT_CMPLX) == 0) {
1479 pcie_bar_cr_write(base, 1, 0xf0000 | 1);
1480 return;
1481 }
1482
1483 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1484 if (ddr_is_active(i)) {
1485 /* Map DDR to BAR 1 */
1486 cr = (ddr_size(i) - 1) & 0xffff0000;
1487 size += ddr_size(i) & 0xffff0000;
1488 cr |= (ddr_attr(i) << 8) | 1;
1489 br = ddr_base(i);
1490 if (br < ddrbase)
1491 ddrbase = br;
1492
1493 /* Use the first available PCIE window */
1494 for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
1495 if (win_pcie_cr_read(base, j) != 0)
1496 continue;
1497
1498 win_pcie_br_write(base, j, br);
1499 win_pcie_cr_write(base, j, cr);
1500 break;
1501 }
1502 }
1503 }
1504
1505 /*
1506 * Upper 16 bits in BAR register is interpreted as BAR size
1507 * (in 64 kB units) plus 64kB, so subtract 0x10000
1508 * form value passed to register to get correct value.
1509 */
1510 size -= 0x10000;
1511 pcie_bar_cr_write(base, 1, size | 1);
1512 pcie_bar_br_write(base, 1, ddrbase |
1513 MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1514 pcie_bar_br_write(base, 0, fdt_immr_pa |
1515 MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1516 }
1517
1518 static int
decode_win_pcie_valid(void)1519 decode_win_pcie_valid(void)
1520 {
1521
1522 return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
1523 }
1524
1525 /**************************************************************************
1526 * IDMA windows routines
1527 **************************************************************************/
1528
1529 /* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
1530 int
decode_win_idma_valid(void)1531 decode_win_idma_valid(void)
1532 {
1533
1534 return (1);
1535 }
1536
1537 void
decode_win_idma_setup(u_long base)1538 decode_win_idma_setup(u_long base)
1539 {
1540 }
1541
1542 void
decode_win_idma_dump(u_long base)1543 decode_win_idma_dump(u_long base)
1544 {
1545 }
1546
1547 /**************************************************************************
1548 * XOR windows routines
1549 **************************************************************************/
1550 /* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
1551 static int
decode_win_xor_valid(void)1552 decode_win_xor_valid(void)
1553 {
1554
1555 return (1);
1556 }
1557
1558 static void
decode_win_xor_setup(u_long base)1559 decode_win_xor_setup(u_long base)
1560 {
1561 }
1562
1563 static void
decode_win_xor_dump(u_long base)1564 decode_win_xor_dump(u_long base)
1565 {
1566 }
1567
1568 /**************************************************************************
1569 * SATA windows routines
1570 **************************************************************************/
1571 static void
decode_win_sata_setup(u_long base)1572 decode_win_sata_setup(u_long base)
1573 {
1574 uint32_t cr, br;
1575 int i, j;
1576
1577 for (i = 0; i < MV_WIN_SATA_MAX; i++) {
1578 win_sata_cr_write(base, i, 0);
1579 win_sata_br_write(base, i, 0);
1580 }
1581
1582 for (i = 0; i < MV_WIN_DDR_MAX; i++)
1583 if (ddr_is_active(i)) {
1584 cr = ((ddr_size(i) - 1) & 0xffff0000) |
1585 (ddr_attr(i) << 8) | 1;
1586 br = ddr_base(i);
1587
1588 /* Use the first available SATA window */
1589 for (j = 0; j < MV_WIN_SATA_MAX; j++) {
1590 if ((win_sata_cr_read(base, j) & 1) != 0)
1591 continue;
1592
1593 win_sata_br_write(base, j, br);
1594 win_sata_cr_write(base, j, cr);
1595 break;
1596 }
1597 }
1598 }
1599
1600 /*
1601 * Configure AHCI decoding windows
1602 */
1603 static void
decode_win_ahci_setup(u_long base)1604 decode_win_ahci_setup(u_long base)
1605 {
1606 uint32_t br, cr, sz;
1607 int i, j;
1608
1609 for (i = 0; i < MV_WIN_SATA_MAX_ARMADA38X; i++) {
1610 win_sata_armada38x_cr_write(base, i, 0);
1611 win_sata_armada38x_br_write(base, i, 0);
1612 win_sata_armada38x_sz_write(base, i, 0);
1613 }
1614
1615 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1616 if (ddr_is_active(i)) {
1617 cr = (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1618 IO_WIN_ENA_MASK;
1619 br = ddr_base(i);
1620 sz = (ddr_size(i) - 1) &
1621 (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT);
1622
1623 /* Use first available SATA window */
1624 for (j = 0; j < MV_WIN_SATA_MAX_ARMADA38X; j++) {
1625 if (win_sata_armada38x_cr_read(base, j) & IO_WIN_ENA_MASK)
1626 continue;
1627
1628 /* BASE is set to DRAM base (0x00000000) */
1629 win_sata_armada38x_br_write(base, j, br);
1630 /* CTRL targets DRAM ctrl with 0x0E or 0x0D */
1631 win_sata_armada38x_cr_write(base, j, cr);
1632 /* SIZE is set to 16MB - max value */
1633 win_sata_armada38x_sz_write(base, j, sz);
1634 break;
1635 }
1636 }
1637 }
1638 }
1639
1640 static void
decode_win_ahci_dump(u_long base)1641 decode_win_ahci_dump(u_long base)
1642 {
1643 int i;
1644
1645 for (i = 0; i < MV_WIN_SATA_MAX_ARMADA38X; i++)
1646 printf("SATA window#%d: cr 0x%08x, br 0x%08x, sz 0x%08x\n", i,
1647 win_sata_armada38x_cr_read(base, i), win_sata_br_read(base, i),
1648 win_sata_armada38x_sz_read(base,i));
1649 }
1650
1651 static int
decode_win_sata_valid(void)1652 decode_win_sata_valid(void)
1653 {
1654 uint32_t dev, rev;
1655
1656 soc_id(&dev, &rev);
1657
1658 return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
1659 }
1660
1661 static void
decode_win_sdhci_setup(u_long base)1662 decode_win_sdhci_setup(u_long base)
1663 {
1664 uint32_t cr, br;
1665 int i, j;
1666
1667 for (i = 0; i < MV_WIN_SDHCI_MAX; i++) {
1668 win_sdhci_cr_write(base, i, 0);
1669 win_sdhci_br_write(base, i, 0);
1670 }
1671
1672 for (i = 0; i < MV_WIN_DDR_MAX; i++)
1673 if (ddr_is_active(i)) {
1674 br = ddr_base(i);
1675 cr = (((ddr_size(i) - 1) &
1676 (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT)) |
1677 (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1678 IO_WIN_ENA_MASK);
1679
1680 /* Use the first available SDHCI window */
1681 for (j = 0; j < MV_WIN_SDHCI_MAX; j++) {
1682 if (win_sdhci_cr_read(base, j) & IO_WIN_ENA_MASK)
1683 continue;
1684
1685 win_sdhci_cr_write(base, j, cr);
1686 win_sdhci_br_write(base, j, br);
1687 break;
1688 }
1689 }
1690 }
1691
1692 static void
decode_win_sdhci_dump(u_long base)1693 decode_win_sdhci_dump(u_long base)
1694 {
1695 int i;
1696
1697 for (i = 0; i < MV_WIN_SDHCI_MAX; i++)
1698 printf("SDHCI window#%d: c 0x%08x, b 0x%08x\n", i,
1699 win_sdhci_cr_read(base, i), win_sdhci_br_read(base, i));
1700 }
1701
1702 static int
decode_win_sdhci_valid(void)1703 decode_win_sdhci_valid(void)
1704 {
1705
1706 return (decode_win_can_cover_ddr(MV_WIN_SDHCI_MAX));
1707 }
1708
1709 /**************************************************************************
1710 * FDT parsing routines.
1711 **************************************************************************/
1712
1713 static int
fdt_get_ranges(const char * nodename,void * buf,int size,int * tuples,int * tuplesize)1714 fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples,
1715 int *tuplesize)
1716 {
1717 phandle_t node;
1718 pcell_t addr_cells, par_addr_cells, size_cells;
1719 int len, tuple_size, tuples_count;
1720
1721 node = OF_finddevice(nodename);
1722 if (node == -1)
1723 return (EINVAL);
1724
1725 if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
1726 return (ENXIO);
1727
1728 par_addr_cells = fdt_parent_addr_cells(node);
1729 if (par_addr_cells > 2)
1730 return (ERANGE);
1731
1732 tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
1733 size_cells);
1734
1735 /* Note the OF_getprop_alloc() cannot be used at this early stage. */
1736 len = OF_getprop(node, "ranges", buf, size);
1737
1738 /*
1739 * XXX this does not handle the empty 'ranges;' case, which is
1740 * legitimate and should be allowed.
1741 */
1742 tuples_count = len / tuple_size;
1743 if (tuples_count <= 0)
1744 return (ERANGE);
1745
1746 if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2)
1747 return (ERANGE);
1748
1749 *tuples = tuples_count;
1750 *tuplesize = tuple_size;
1751 return (0);
1752 }
1753
1754 static int
win_cpu_from_dt(void)1755 win_cpu_from_dt(void)
1756 {
1757 pcell_t ranges[48];
1758 phandle_t node;
1759 int i, entry_size, err, t, tuple_size, tuples;
1760 u_long sram_base, sram_size;
1761
1762 t = 0;
1763 /* Retrieve 'ranges' property of '/localbus' node. */
1764 if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges),
1765 &tuples, &tuple_size)) == 0) {
1766 /*
1767 * Fill CPU decode windows table.
1768 */
1769 bzero((void *)&cpu_win_tbl, sizeof(cpu_win_tbl));
1770
1771 entry_size = tuple_size / sizeof(pcell_t);
1772 cpu_wins_no = tuples;
1773
1774 /* Check range */
1775 if (tuples > nitems(cpu_win_tbl)) {
1776 debugf("too many tuples to fit into cpu_win_tbl\n");
1777 return (ENOMEM);
1778 }
1779
1780 for (i = 0, t = 0; t < tuples; i += entry_size, t++) {
1781 cpu_win_tbl[t].target = 1;
1782 cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]);
1783 cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]);
1784 cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]);
1785 cpu_win_tbl[t].remap = ~0;
1786 debugf("target = 0x%0x attr = 0x%0x base = 0x%0x "
1787 "size = 0x%0x remap = 0x%0x\n",
1788 cpu_win_tbl[t].target,
1789 cpu_win_tbl[t].attr, cpu_win_tbl[t].base,
1790 cpu_win_tbl[t].size, cpu_win_tbl[t].remap);
1791 }
1792 }
1793
1794 /*
1795 * Retrieve CESA SRAM data.
1796 */
1797 if ((node = OF_finddevice("sram")) != -1)
1798 if (ofw_bus_node_is_compatible(node, "mrvl,cesa-sram"))
1799 goto moveon;
1800
1801 if ((node = OF_finddevice("/")) == -1)
1802 return (ENXIO);
1803
1804 if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
1805 /* SRAM block is not always present. */
1806 return (0);
1807 moveon:
1808 sram_base = sram_size = 0;
1809 if (fdt_regsize(node, &sram_base, &sram_size) != 0)
1810 return (EINVAL);
1811
1812 /* Check range */
1813 if (t >= nitems(cpu_win_tbl)) {
1814 debugf("cannot fit CESA tuple into cpu_win_tbl\n");
1815 return (ENOMEM);
1816 }
1817
1818 cpu_win_tbl[t].target = soc_decode_win_spec->win_cesa_target;
1819 if (soc_family == MV_SOC_ARMADA_38X)
1820 cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(0);
1821 else
1822 cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(1);
1823 cpu_win_tbl[t].base = sram_base;
1824 cpu_win_tbl[t].size = sram_size;
1825 cpu_win_tbl[t].remap = ~0;
1826 cpu_wins_no++;
1827 debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
1828
1829 /* Check if there is a second CESA node */
1830 while ((node = OF_peer(node)) != 0) {
1831 if (ofw_bus_node_is_compatible(node, "mrvl,cesa-sram")) {
1832 if (fdt_regsize(node, &sram_base, &sram_size) != 0)
1833 return (EINVAL);
1834 break;
1835 }
1836 }
1837
1838 if (node == 0)
1839 return (0);
1840
1841 t++;
1842 if (t >= nitems(cpu_win_tbl)) {
1843 debugf("cannot fit CESA tuple into cpu_win_tbl\n");
1844 return (ENOMEM);
1845 }
1846
1847 /* Configure window for CESA1 */
1848 cpu_win_tbl[t].target = soc_decode_win_spec->win_cesa_target;
1849 cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(1);
1850 cpu_win_tbl[t].base = sram_base;
1851 cpu_win_tbl[t].size = sram_size;
1852 cpu_win_tbl[t].remap = ~0;
1853 cpu_wins_no++;
1854 debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
1855
1856 return (0);
1857 }
1858
1859 static int
fdt_win_process(phandle_t child)1860 fdt_win_process(phandle_t child)
1861 {
1862 int i, ret;
1863
1864 for (i = 0; soc_nodes[i].compat != NULL; i++) {
1865 /* Setup only for enabled devices */
1866 if (ofw_bus_node_status_okay(child) == 0)
1867 continue;
1868
1869 if (!ofw_bus_node_is_compatible(child, soc_nodes[i].compat))
1870 continue;
1871
1872 ret = fdt_win_process_child(child, &soc_nodes[i], "reg");
1873 if (ret != 0)
1874 return (ret);
1875 }
1876
1877 return (0);
1878 }
1879
1880 static int
fdt_win_process_child(phandle_t child,struct soc_node_spec * soc_node,const char * mimo_reg_source)1881 fdt_win_process_child(phandle_t child, struct soc_node_spec *soc_node,
1882 const char* mimo_reg_source)
1883 {
1884 int addr_cells, size_cells;
1885 pcell_t reg[8];
1886 u_long base;
1887
1888 if (fdt_addrsize_cells(OF_parent(child), &addr_cells,
1889 &size_cells))
1890 return (ENXIO);
1891
1892 if ((sizeof(pcell_t) * (addr_cells + size_cells)) > sizeof(reg))
1893 return (ENOMEM);
1894 if (OF_getprop(child, mimo_reg_source, ®, sizeof(reg)) <= 0)
1895 return (EINVAL);
1896
1897 if (addr_cells <= 2)
1898 base = fdt_data_get(®[0], addr_cells);
1899 else
1900 base = fdt_data_get(®[addr_cells - 2], 2);
1901 fdt_data_get(®[addr_cells], size_cells);
1902
1903 if (soc_node->valid_handler != NULL)
1904 if (!soc_node->valid_handler())
1905 return (EINVAL);
1906
1907 base = (base & 0x000fffff) | fdt_immr_va;
1908 if (soc_node->decode_handler != NULL)
1909 soc_node->decode_handler(base);
1910 else
1911 return (ENXIO);
1912
1913 if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
1914 soc_node->dump_handler(base);
1915
1916 return (0);
1917 }
1918
1919 static int
fdt_win_setup(void)1920 fdt_win_setup(void)
1921 {
1922 phandle_t node, child, sb;
1923 phandle_t child_pci;
1924 int err;
1925
1926 sb = 0;
1927 node = OF_finddevice("/");
1928 if (node == -1)
1929 panic("fdt_win_setup: no root node");
1930
1931 /* Allow for coherent transactions on the A38x MBUS */
1932 if (ofw_bus_node_is_compatible(node, "marvell,armada380"))
1933 platform_io_coherent = true;
1934
1935 /*
1936 * Traverse through all children of root and simple-bus nodes.
1937 * For each found device retrieve decode windows data (if applicable).
1938 */
1939 child = OF_child(node);
1940 while (child != 0) {
1941 /* Lookup for callback and run */
1942 err = fdt_win_process(child);
1943 if (err != 0)
1944 return (err);
1945
1946 /* Process Marvell Armada-XP/38x PCIe controllers */
1947 if (ofw_bus_node_is_compatible(child, "marvell,armada-370-pcie")) {
1948 child_pci = OF_child(child);
1949 while (child_pci != 0) {
1950 err = fdt_win_process_child(child_pci,
1951 &soc_nodes[SOC_NODE_PCIE_ENTRY_IDX],
1952 "assigned-addresses");
1953 if (err != 0)
1954 return (err);
1955
1956 child_pci = OF_peer(child_pci);
1957 }
1958 }
1959
1960 /*
1961 * Once done with root-level children let's move down to
1962 * simple-bus and its children.
1963 */
1964 child = OF_peer(child);
1965 if ((child == 0) && (node == OF_finddevice("/"))) {
1966 sb = node = fdt_find_compatible(node, "simple-bus", 0);
1967 if (node == 0)
1968 return (ENXIO);
1969 child = OF_child(node);
1970 }
1971 /*
1972 * Next, move one more level down to internal-regs node (if
1973 * it is present) and its children. This node also have
1974 * "simple-bus" compatible.
1975 */
1976 if ((child == 0) && (node == sb)) {
1977 node = fdt_find_compatible(node, "simple-bus", 0);
1978 if (node == 0)
1979 return (0);
1980 child = OF_child(node);
1981 }
1982 }
1983
1984 return (0);
1985 }
1986
1987 static void
fdt_fixup_busfreq(phandle_t root)1988 fdt_fixup_busfreq(phandle_t root)
1989 {
1990 phandle_t sb;
1991 pcell_t freq;
1992
1993 freq = cpu_to_fdt32(get_tclk());
1994
1995 /*
1996 * Fix bus speed in cpu node
1997 */
1998 if ((sb = OF_finddevice("cpu")) != -1)
1999 if (fdt_is_compatible_strict(sb, "ARM,88VS584"))
2000 OF_setprop(sb, "bus-frequency", (void *)&freq,
2001 sizeof(freq));
2002
2003 /*
2004 * This fixup sets the simple-bus bus-frequency property.
2005 */
2006 if ((sb = fdt_find_compatible(root, "simple-bus", 1)) != 0)
2007 OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
2008 }
2009
2010 static void
fdt_fixup_ranges(phandle_t root)2011 fdt_fixup_ranges(phandle_t root)
2012 {
2013 phandle_t node;
2014 pcell_t par_addr_cells, addr_cells, size_cells;
2015 pcell_t ranges[3], reg[2], *rangesptr;
2016 int len, tuple_size, tuples_count;
2017 uint32_t base;
2018
2019 /* Fix-up SoC ranges according to real fdt_immr_pa */
2020 if ((node = fdt_find_compatible(root, "simple-bus", 1)) != 0) {
2021 if (fdt_addrsize_cells(node, &addr_cells, &size_cells) == 0 &&
2022 ((par_addr_cells = fdt_parent_addr_cells(node)) <= 2)) {
2023 tuple_size = sizeof(pcell_t) * (par_addr_cells +
2024 addr_cells + size_cells);
2025 len = OF_getprop(node, "ranges", ranges,
2026 sizeof(ranges));
2027 tuples_count = len / tuple_size;
2028 /* Unexpected settings are not supported */
2029 if (tuples_count != 1)
2030 goto fixup_failed;
2031
2032 rangesptr = &ranges[0];
2033 rangesptr += par_addr_cells;
2034 base = fdt_data_get((void *)rangesptr, addr_cells);
2035 *rangesptr = cpu_to_fdt32(fdt_immr_pa);
2036 if (OF_setprop(node, "ranges", (void *)&ranges[0],
2037 sizeof(ranges)) < 0)
2038 goto fixup_failed;
2039 }
2040 }
2041
2042 /* Fix-up PCIe reg according to real PCIe registers' PA */
2043 if ((node = fdt_find_compatible(root, "mrvl,pcie", 1)) != 0) {
2044 if (fdt_addrsize_cells(OF_parent(node), &par_addr_cells,
2045 &size_cells) == 0) {
2046 tuple_size = sizeof(pcell_t) * (par_addr_cells +
2047 size_cells);
2048 len = OF_getprop(node, "reg", reg, sizeof(reg));
2049 tuples_count = len / tuple_size;
2050 /* Unexpected settings are not supported */
2051 if (tuples_count != 1)
2052 goto fixup_failed;
2053
2054 base = fdt_data_get((void *)®[0], par_addr_cells);
2055 base &= ~0xFF000000;
2056 base |= fdt_immr_pa;
2057 reg[0] = cpu_to_fdt32(base);
2058 if (OF_setprop(node, "reg", (void *)®[0],
2059 sizeof(reg)) < 0)
2060 goto fixup_failed;
2061 }
2062 }
2063 /* Fix-up succeeded. May return and continue */
2064 return;
2065
2066 fixup_failed:
2067 while (1) {
2068 /*
2069 * In case of any error while fixing ranges just hang.
2070 * 1. No message can be displayed yet since console
2071 * is not initialized.
2072 * 2. Going further will cause failure on bus_space_map()
2073 * relying on the wrong ranges or data abort when
2074 * accessing PCIe registers.
2075 */
2076 }
2077 }
2078
2079 struct fdt_fixup_entry fdt_fixup_table[] = {
2080 { "mrvl,DB-88F6281", &fdt_fixup_busfreq },
2081 { "mrvl,DB-78460", &fdt_fixup_busfreq },
2082 { "mrvl,DB-78460", &fdt_fixup_ranges },
2083 { NULL, NULL }
2084 };
2085
2086 uint32_t
get_tclk(void)2087 get_tclk(void)
2088 {
2089
2090 if (soc_decode_win_spec->get_tclk != NULL)
2091 return soc_decode_win_spec->get_tclk();
2092 else
2093 return -1;
2094 }
2095
2096 uint32_t
get_cpu_freq(void)2097 get_cpu_freq(void)
2098 {
2099
2100 if (soc_decode_win_spec->get_cpu_freq != NULL)
2101 return soc_decode_win_spec->get_cpu_freq();
2102 else
2103 return -1;
2104 }
2105