xref: /freebsd/sys/arm/mv/mv_common.c (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
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/cdefs.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/bus.h>
38 #include <sys/kernel.h>
39 #include <sys/malloc.h>
40 #include <sys/kdb.h>
41 #include <sys/reboot.h>
42 
43 #include <dev/fdt/fdt_common.h>
44 #include <dev/ofw/openfirm.h>
45 #include <dev/ofw/ofw_bus_subr.h>
46 
47 #include <machine/bus.h>
48 #include <machine/fdt.h>
49 #include <machine/vmparam.h>
50 #include <machine/intr.h>
51 
52 #include <arm/mv/mvreg.h>
53 #include <arm/mv/mvvar.h>
54 #include <arm/mv/mvwin.h>
55 
56 MALLOC_DEFINE(M_IDMA, "idma", "idma dma test memory");
57 
58 #define IDMA_DEBUG
59 #undef IDMA_DEBUG
60 
61 #define MAX_CPU_WIN	5
62 
63 #ifdef DEBUG
64 #define debugf(fmt, args...) do { printf("%s(): ", __func__);	\
65     printf(fmt,##args); } while (0)
66 #else
67 #define debugf(fmt, args...)
68 #endif
69 
70 #ifdef DEBUG
71 #define MV_DUMP_WIN	1
72 #else
73 #define MV_DUMP_WIN	0
74 #endif
75 
76 struct soc_node_spec;
77 
78 static enum soc_family soc_family;
79 
80 static int mv_win_cesa_attr_armv5(int eng_sel);
81 static int mv_win_cesa_attr_armada38x(int eng_sel);
82 static int mv_win_cesa_attr_armadaxp(int eng_sel);
83 
84 uint32_t read_cpu_ctrl_armv5(uint32_t reg);
85 uint32_t read_cpu_ctrl_armv7(uint32_t reg);
86 
87 void write_cpu_ctrl_armv5(uint32_t reg, uint32_t val);
88 void write_cpu_ctrl_armv7(uint32_t reg, uint32_t val);
89 
90 static int win_eth_can_remap(int i);
91 
92 static int decode_win_cesa_valid(void);
93 static int decode_win_usb_valid(void);
94 static int decode_win_usb3_valid(void);
95 static int decode_win_eth_valid(void);
96 static int decode_win_pcie_valid(void);
97 static int decode_win_sata_valid(void);
98 static int decode_win_sdhci_valid(void);
99 
100 static int decode_win_idma_valid(void);
101 static int decode_win_xor_valid(void);
102 
103 static void decode_win_cpu_setup(void);
104 static int decode_win_sdram_fixup(void);
105 static void decode_win_cesa_setup(u_long);
106 static void decode_win_a38x_cesa_setup(u_long);
107 static void decode_win_usb_setup(u_long);
108 static void decode_win_usb3_setup(u_long);
109 static void decode_win_eth_setup(u_long);
110 static void decode_win_neta_setup(u_long);
111 static void decode_win_sata_setup(u_long);
112 static void decode_win_ahci_setup(u_long);
113 static void decode_win_sdhci_setup(u_long);
114 
115 static void decode_win_idma_setup(u_long);
116 static void decode_win_xor_setup(u_long);
117 
118 static void decode_win_cesa_dump(u_long);
119 static void decode_win_a38x_cesa_dump(u_long);
120 static void decode_win_usb_dump(u_long);
121 static void decode_win_usb3_dump(u_long);
122 static void decode_win_eth_dump(u_long base);
123 static void decode_win_neta_dump(u_long base);
124 static void decode_win_idma_dump(u_long base);
125 static void decode_win_xor_dump(u_long base);
126 static void decode_win_ahci_dump(u_long base);
127 static void decode_win_sdhci_dump(u_long);
128 static void decode_win_pcie_dump(u_long);
129 
130 static uint32_t win_cpu_cr_read(int);
131 static uint32_t win_cpu_armv5_cr_read(int);
132 static uint32_t win_cpu_armv7_cr_read(int);
133 static uint32_t win_cpu_br_read(int);
134 static uint32_t win_cpu_armv5_br_read(int);
135 static uint32_t win_cpu_armv7_br_read(int);
136 static uint32_t win_cpu_remap_l_read(int);
137 static uint32_t win_cpu_armv5_remap_l_read(int);
138 static uint32_t win_cpu_armv7_remap_l_read(int);
139 static uint32_t win_cpu_remap_h_read(int);
140 static uint32_t win_cpu_armv5_remap_h_read(int);
141 static uint32_t win_cpu_armv7_remap_h_read(int);
142 
143 static void win_cpu_cr_write(int, uint32_t);
144 static void win_cpu_armv5_cr_write(int, uint32_t);
145 static void win_cpu_armv7_cr_write(int, uint32_t);
146 static void win_cpu_br_write(int, uint32_t);
147 static void win_cpu_armv5_br_write(int, uint32_t);
148 static void win_cpu_armv7_br_write(int, uint32_t);
149 static void win_cpu_remap_l_write(int, uint32_t);
150 static void win_cpu_armv5_remap_l_write(int, uint32_t);
151 static void win_cpu_armv7_remap_l_write(int, uint32_t);
152 static void win_cpu_remap_h_write(int, uint32_t);
153 static void win_cpu_armv5_remap_h_write(int, uint32_t);
154 static void win_cpu_armv7_remap_h_write(int, uint32_t);
155 
156 static uint32_t ddr_br_read(int);
157 static uint32_t ddr_sz_read(int);
158 static uint32_t ddr_armv5_br_read(int);
159 static uint32_t ddr_armv5_sz_read(int);
160 static uint32_t ddr_armv7_br_read(int);
161 static uint32_t ddr_armv7_sz_read(int);
162 static void ddr_br_write(int, uint32_t);
163 static void ddr_sz_write(int, uint32_t);
164 static void ddr_armv5_br_write(int, uint32_t);
165 static void ddr_armv5_sz_write(int, uint32_t);
166 static void ddr_armv7_br_write(int, uint32_t);
167 static void ddr_armv7_sz_write(int, uint32_t);
168 
169 static int fdt_get_ranges(const char *, void *, int, int *, int *);
170 int gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt,
171     int *trig, int *pol);
172 
173 static int win_cpu_from_dt(void);
174 static int fdt_win_setup(void);
175 
176 static int fdt_win_process_child(phandle_t, struct soc_node_spec *, const char*);
177 
178 static void soc_identify(uint32_t, uint32_t);
179 
180 static uint32_t dev_mask = 0;
181 static int cpu_wins_no = 0;
182 static int eth_port = 0;
183 static int usb_port = 0;
184 static boolean_t platform_io_coherent = false;
185 
186 static struct decode_win cpu_win_tbl[MAX_CPU_WIN];
187 
188 const struct decode_win *cpu_wins = cpu_win_tbl;
189 
190 typedef void (*decode_win_setup_t)(u_long);
191 typedef void (*dump_win_t)(u_long);
192 typedef int (*valid_t)(void);
193 
194 /*
195  * The power status of device feature is only supported on
196  * Kirkwood and Discovery SoCs.
197  */
198 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
199 #define	SOC_MV_POWER_STAT_SUPPORTED		1
200 #else
201 #define	SOC_MV_POWER_STAT_SUPPORTED		0
202 #endif
203 
204 struct soc_node_spec {
205 	const char		*compat;
206 	decode_win_setup_t	decode_handler;
207 	dump_win_t		dump_handler;
208 	valid_t			valid_handler;
209 };
210 
211 static struct soc_node_spec soc_nodes[] = {
212 	{ "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump, &decode_win_eth_valid},
213 	{ "marvell,armada-370-neta", &decode_win_neta_setup,
214 	    &decode_win_neta_dump, NULL },
215 	{ "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump, &decode_win_usb_valid},
216 	{ "marvell,orion-ehci", &decode_win_usb_setup, &decode_win_usb_dump, &decode_win_usb_valid },
217 	{ "marvell,armada-380-xhci", &decode_win_usb3_setup,
218 	    &decode_win_usb3_dump, &decode_win_usb3_valid },
219 	{ "marvell,armada-380-ahci", &decode_win_ahci_setup,
220 	    &decode_win_ahci_dump, NULL },
221 	{ "marvell,armada-380-sdhci", &decode_win_sdhci_setup,
222 	    &decode_win_sdhci_dump, &decode_win_sdhci_valid},
223 	{ "mrvl,sata", &decode_win_sata_setup, NULL, &decode_win_sata_valid},
224 	{ "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump, &decode_win_xor_valid},
225 	{ "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump, &decode_win_idma_valid},
226 	{ "mrvl,cesa", &decode_win_cesa_setup, &decode_win_cesa_dump, &decode_win_cesa_valid},
227 	{ "mrvl,pcie", &decode_win_pcie_setup, &decode_win_pcie_dump, &decode_win_pcie_valid},
228 	{ "marvell,armada-38x-crypto", &decode_win_a38x_cesa_setup,
229 	    &decode_win_a38x_cesa_dump, &decode_win_cesa_valid},
230 	{ NULL, NULL, NULL, NULL },
231 };
232 
233 #define	SOC_NODE_PCIE_ENTRY_IDX		11
234 
235 typedef uint32_t(*read_cpu_ctrl_t)(uint32_t);
236 typedef void(*write_cpu_ctrl_t)(uint32_t, uint32_t);
237 typedef uint32_t (*win_read_t)(int);
238 typedef void (*win_write_t)(int, uint32_t);
239 typedef int (*win_cesa_attr_t)(int);
240 typedef uint32_t (*get_t)(void);
241 
242 struct decode_win_spec {
243 	read_cpu_ctrl_t  read_cpu_ctrl;
244 	write_cpu_ctrl_t write_cpu_ctrl;
245 	win_read_t	cr_read;
246 	win_read_t	br_read;
247 	win_read_t	remap_l_read;
248 	win_read_t	remap_h_read;
249 	win_write_t	cr_write;
250 	win_write_t	br_write;
251 	win_write_t	remap_l_write;
252 	win_write_t	remap_h_write;
253 	uint32_t	mv_win_cpu_max;
254 	win_cesa_attr_t win_cesa_attr;
255 	int 		win_cesa_target;
256 	win_read_t	ddr_br_read;
257 	win_read_t	ddr_sz_read;
258 	win_write_t	ddr_br_write;
259 	win_write_t	ddr_sz_write;
260 	get_t		get_tclk;
261 	get_t		get_cpu_freq;
262 };
263 
264 struct decode_win_spec *soc_decode_win_spec;
265 
266 static struct decode_win_spec decode_win_specs[] =
267 {
268 	{
269 		&read_cpu_ctrl_armv7,
270 		&write_cpu_ctrl_armv7,
271 		&win_cpu_armv7_cr_read,
272 		&win_cpu_armv7_br_read,
273 		&win_cpu_armv7_remap_l_read,
274 		&win_cpu_armv7_remap_h_read,
275 		&win_cpu_armv7_cr_write,
276 		&win_cpu_armv7_br_write,
277 		&win_cpu_armv7_remap_l_write,
278 		&win_cpu_armv7_remap_h_write,
279 		MV_WIN_CPU_MAX_ARMV7,
280 		&mv_win_cesa_attr_armada38x,
281 		MV_WIN_CESA_TARGET_ARMADA38X,
282 		&ddr_armv7_br_read,
283 		&ddr_armv7_sz_read,
284 		&ddr_armv7_br_write,
285 		&ddr_armv7_sz_write,
286 		&get_tclk_armada38x,
287 		&get_cpu_freq_armada38x,
288 	},
289 	{
290 		&read_cpu_ctrl_armv7,
291 		&write_cpu_ctrl_armv7,
292 		&win_cpu_armv7_cr_read,
293 		&win_cpu_armv7_br_read,
294 		&win_cpu_armv7_remap_l_read,
295 		&win_cpu_armv7_remap_h_read,
296 		&win_cpu_armv7_cr_write,
297 		&win_cpu_armv7_br_write,
298 		&win_cpu_armv7_remap_l_write,
299 		&win_cpu_armv7_remap_h_write,
300 		MV_WIN_CPU_MAX_ARMV7,
301 		&mv_win_cesa_attr_armadaxp,
302 		MV_WIN_CESA_TARGET_ARMADAXP,
303 		&ddr_armv7_br_read,
304 		&ddr_armv7_sz_read,
305 		&ddr_armv7_br_write,
306 		&ddr_armv7_sz_write,
307 		&get_tclk_armadaxp,
308 		&get_cpu_freq_armadaxp,
309 	},
310 	{
311 		&read_cpu_ctrl_armv5,
312 		&write_cpu_ctrl_armv5,
313 		&win_cpu_armv5_cr_read,
314 		&win_cpu_armv5_br_read,
315 		&win_cpu_armv5_remap_l_read,
316 		&win_cpu_armv5_remap_h_read,
317 		&win_cpu_armv5_cr_write,
318 		&win_cpu_armv5_br_write,
319 		&win_cpu_armv5_remap_l_write,
320 		&win_cpu_armv5_remap_h_write,
321 		MV_WIN_CPU_MAX,
322 		&mv_win_cesa_attr_armv5,
323 		MV_WIN_CESA_TARGET,
324 		&ddr_armv5_br_read,
325 		&ddr_armv5_sz_read,
326 		&ddr_armv5_br_write,
327 		&ddr_armv5_sz_write,
328 		NULL,
329 		NULL,
330 	},
331 };
332 
333 struct fdt_pm_mask_entry {
334 	char		*compat;
335 	uint32_t	mask;
336 };
337 
338 static struct fdt_pm_mask_entry fdt_pm_mask_table[] = {
339 	{ "mrvl,ge",		CPU_PM_CTRL_GE(0) },
340 	{ "mrvl,ge",		CPU_PM_CTRL_GE(1) },
341 	{ "mrvl,usb-ehci",	CPU_PM_CTRL_USB(0) },
342 	{ "mrvl,usb-ehci",	CPU_PM_CTRL_USB(1) },
343 	{ "mrvl,usb-ehci",	CPU_PM_CTRL_USB(2) },
344 	{ "mrvl,xor",		CPU_PM_CTRL_XOR },
345 	{ "mrvl,sata",		CPU_PM_CTRL_SATA },
346 	{ NULL, 0 }
347 };
348 
349 static __inline int
350 pm_is_disabled(uint32_t mask)
351 {
352 #if SOC_MV_POWER_STAT_SUPPORTED
353 	return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
354 #else
355 	return (0);
356 #endif
357 }
358 
359 /*
360  * Disable device using power management register.
361  * 1 - Device Power On
362  * 0 - Device Power Off
363  * Mask can be set in loader.
364  * EXAMPLE:
365  * loader> set hw.pm-disable-mask=0x2
366  *
367  * Common mask:
368  * |-------------------------------|
369  * | Device | Kirkwood | Discovery |
370  * |-------------------------------|
371  * | USB0   | 0x00008  | 0x020000  |
372  * |-------------------------------|
373  * | USB1   |     -    | 0x040000  |
374  * |-------------------------------|
375  * | USB2   |     -    | 0x080000  |
376  * |-------------------------------|
377  * | GE0    | 0x00001  | 0x000002  |
378  * |-------------------------------|
379  * | GE1    |     -    | 0x000004  |
380  * |-------------------------------|
381  * | IDMA   |     -    | 0x100000  |
382  * |-------------------------------|
383  * | XOR    | 0x10000  | 0x200000  |
384  * |-------------------------------|
385  * | CESA   | 0x20000  | 0x400000  |
386  * |-------------------------------|
387  * | SATA   | 0x04000  | 0x004000  |
388  * --------------------------------|
389  * This feature can be used only on Kirkwood and Discovery
390  * machines.
391  */
392 
393 static int mv_win_cesa_attr_armv5(int eng_sel)
394 {
395 
396 	return MV_WIN_CESA_ATTR(eng_sel);
397 }
398 
399 static int mv_win_cesa_attr_armada38x(int eng_sel)
400 {
401 
402 	return MV_WIN_CESA_ATTR_ARMADA38X(eng_sel);
403 }
404 
405 static int mv_win_cesa_attr_armadaxp(int eng_sel)
406 {
407 
408 	return MV_WIN_CESA_ATTR_ARMADAXP(eng_sel);
409 }
410 
411 enum soc_family
412 mv_check_soc_family(void)
413 {
414 	uint32_t dev, rev;
415 
416 	soc_id(&dev, &rev);
417 	switch (dev) {
418 	case MV_DEV_MV78230:
419 	case MV_DEV_MV78260:
420 	case MV_DEV_MV78460:
421 		soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMADA_XP];
422 		soc_family = MV_SOC_ARMADA_XP;
423 		break;
424 	case MV_DEV_88F6828:
425 	case MV_DEV_88F6820:
426 	case MV_DEV_88F6810:
427 		soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMADA_38X];
428 		soc_family = MV_SOC_ARMADA_38X;
429 		break;
430 	case MV_DEV_88F5181:
431 	case MV_DEV_88F5182:
432 	case MV_DEV_88F5281:
433 	case MV_DEV_88F6281:
434 	case MV_DEV_88RC8180:
435 	case MV_DEV_88RC9480:
436 	case MV_DEV_88RC9580:
437 	case MV_DEV_88F6781:
438 	case MV_DEV_88F6282:
439 	case MV_DEV_MV78100_Z0:
440 	case MV_DEV_MV78100:
441 	case MV_DEV_MV78160:
442 		soc_decode_win_spec = &decode_win_specs[MV_SOC_ARMV5];
443 		soc_family = MV_SOC_ARMV5;
444 		break;
445 	default:
446 		soc_family = MV_SOC_UNSUPPORTED;
447 		return (MV_SOC_UNSUPPORTED);
448 	}
449 
450 	soc_identify(dev, rev);
451 
452 	return (soc_family);
453 }
454 
455 static __inline void
456 pm_disable_device(int mask)
457 {
458 #ifdef DIAGNOSTIC
459 	uint32_t reg;
460 
461 	reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
462 	printf("Power Management Register: 0%x\n", reg);
463 
464 	reg &= ~mask;
465 	soc_power_ctrl_set(reg);
466 	printf("Device %x is disabled\n", mask);
467 
468 	reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
469 	printf("Power Management Register: 0%x\n", reg);
470 #endif
471 }
472 
473 int
474 mv_fdt_is_type(phandle_t node, const char *typestr)
475 {
476 #define FDT_TYPE_LEN	64
477 	char type[FDT_TYPE_LEN];
478 
479 	if (OF_getproplen(node, "device_type") <= 0)
480 		return (0);
481 
482 	if (OF_getprop(node, "device_type", type, FDT_TYPE_LEN) < 0)
483 		return (0);
484 
485 	if (strncasecmp(type, typestr, FDT_TYPE_LEN) == 0)
486 		/* This fits. */
487 		return (1);
488 
489 	return (0);
490 #undef FDT_TYPE_LEN
491 }
492 
493 int
494 mv_fdt_pm(phandle_t node)
495 {
496 	uint32_t cpu_pm_ctrl;
497 	int i, ena, compat;
498 
499 	ena = 1;
500 	cpu_pm_ctrl = read_cpu_ctrl(CPU_PM_CTRL);
501 	for (i = 0; fdt_pm_mask_table[i].compat != NULL; i++) {
502 		if (dev_mask & (1 << i))
503 			continue;
504 
505 		compat = ofw_bus_node_is_compatible(node,
506 		    fdt_pm_mask_table[i].compat);
507 #if defined(SOC_MV_KIRKWOOD)
508 		if (compat && (cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
509 			dev_mask |= (1 << i);
510 			ena = 0;
511 			break;
512 		} else if (compat) {
513 			dev_mask |= (1 << i);
514 			break;
515 		}
516 #else
517 		if (compat && (~cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
518 			dev_mask |= (1 << i);
519 			ena = 0;
520 			break;
521 		} else if (compat) {
522 			dev_mask |= (1 << i);
523 			break;
524 		}
525 #endif
526 	}
527 
528 	return (ena);
529 }
530 
531 uint32_t
532 read_cpu_ctrl(uint32_t reg)
533 {
534 
535 	if (soc_decode_win_spec->read_cpu_ctrl != NULL)
536 		return (soc_decode_win_spec->read_cpu_ctrl(reg));
537 	return (-1);
538 }
539 
540 uint32_t
541 read_cpu_ctrl_armv5(uint32_t reg)
542 {
543 
544 	return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg));
545 }
546 
547 uint32_t
548 read_cpu_ctrl_armv7(uint32_t reg)
549 {
550 
551 	return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE_ARMV7, reg));
552 }
553 
554 void
555 write_cpu_ctrl(uint32_t reg, uint32_t val)
556 {
557 
558 	if (soc_decode_win_spec->write_cpu_ctrl != NULL)
559 		soc_decode_win_spec->write_cpu_ctrl(reg, val);
560 }
561 
562 void
563 write_cpu_ctrl_armv5(uint32_t reg, uint32_t val)
564 {
565 
566 	bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg, val);
567 }
568 
569 void
570 write_cpu_ctrl_armv7(uint32_t reg, uint32_t val)
571 {
572 
573 	bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE_ARMV7, reg, val);
574 }
575 
576 uint32_t
577 read_cpu_mp_clocks(uint32_t reg)
578 {
579 
580 	return (bus_space_read_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg));
581 }
582 
583 void
584 write_cpu_mp_clocks(uint32_t reg, uint32_t val)
585 {
586 
587 	bus_space_write_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg, val);
588 }
589 
590 uint32_t
591 read_cpu_misc(uint32_t reg)
592 {
593 
594 	return (bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE, reg));
595 }
596 
597 void
598 write_cpu_misc(uint32_t reg, uint32_t val)
599 {
600 
601 	bus_space_write_4(fdtbus_bs_tag, MV_MISC_BASE, reg, val);
602 }
603 
604 uint32_t
605 cpu_extra_feat(void)
606 {
607 	uint32_t dev, rev;
608 	uint32_t ef = 0;
609 
610 	soc_id(&dev, &rev);
611 
612 	switch (dev) {
613 	case MV_DEV_88F6281:
614 	case MV_DEV_88F6282:
615 	case MV_DEV_88RC8180:
616 	case MV_DEV_MV78100_Z0:
617 	case MV_DEV_MV78100:
618 		__asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
619 		break;
620 	case MV_DEV_88F5182:
621 	case MV_DEV_88F5281:
622 		__asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
623 		break;
624 	default:
625 		if (bootverbose)
626 			printf("This ARM Core does not support any extra features\n");
627 	}
628 
629 	return (ef);
630 }
631 
632 /*
633  * Get the power status of device. This feature is only supported on
634  * Kirkwood and Discovery SoCs.
635  */
636 uint32_t
637 soc_power_ctrl_get(uint32_t mask)
638 {
639 
640 #if SOC_MV_POWER_STAT_SUPPORTED
641 	if (mask != CPU_PM_CTRL_NONE)
642 		mask &= read_cpu_ctrl(CPU_PM_CTRL);
643 
644 	return (mask);
645 #else
646 	return (mask);
647 #endif
648 }
649 
650 /*
651  * Set the power status of device. This feature is only supported on
652  * Kirkwood and Discovery SoCs.
653  */
654 void
655 soc_power_ctrl_set(uint32_t mask)
656 {
657 
658 #if !defined(SOC_MV_ORION)
659 	if (mask != CPU_PM_CTRL_NONE)
660 		write_cpu_ctrl(CPU_PM_CTRL, mask);
661 #endif
662 }
663 
664 void
665 soc_id(uint32_t *dev, uint32_t *rev)
666 {
667 	uint64_t mv_pcie_base = MV_PCIE_BASE;
668 	phandle_t node;
669 
670 	/*
671 	 * Notice: system identifiers are available in the registers range of
672 	 * PCIE controller, so using this function is only allowed (and
673 	 * possible) after the internal registers range has been mapped in via
674 	 * devmap_bootstrap().
675 	 */
676 	*dev = 0;
677 	*rev = 0;
678 	if ((node = OF_finddevice("/")) == -1)
679 		return;
680 	if (ofw_bus_node_is_compatible(node, "marvell,armada380"))
681 		mv_pcie_base = MV_PCIE_BASE_ARMADA38X;
682 
683 	*dev = bus_space_read_4(fdtbus_bs_tag, mv_pcie_base, 0) >> 16;
684 	*rev = bus_space_read_4(fdtbus_bs_tag, mv_pcie_base, 8) & 0xff;
685 }
686 
687 static void
688 soc_identify(uint32_t d, uint32_t r)
689 {
690 	uint32_t size, mode, freq;
691 	const char *dev;
692 	const char *rev;
693 
694 	printf("SOC: ");
695 	if (bootverbose)
696 		printf("(0x%4x:0x%02x) ", d, r);
697 
698 	rev = "";
699 	switch (d) {
700 	case MV_DEV_88F5181:
701 		dev = "Marvell 88F5181";
702 		if (r == 3)
703 			rev = "B1";
704 		break;
705 	case MV_DEV_88F5182:
706 		dev = "Marvell 88F5182";
707 		if (r == 2)
708 			rev = "A2";
709 		break;
710 	case MV_DEV_88F5281:
711 		dev = "Marvell 88F5281";
712 		if (r == 4)
713 			rev = "D0";
714 		else if (r == 5)
715 			rev = "D1";
716 		else if (r == 6)
717 			rev = "D2";
718 		break;
719 	case MV_DEV_88F6281:
720 		dev = "Marvell 88F6281";
721 		if (r == 0)
722 			rev = "Z0";
723 		else if (r == 2)
724 			rev = "A0";
725 		else if (r == 3)
726 			rev = "A1";
727 		break;
728 	case MV_DEV_88RC8180:
729 		dev = "Marvell 88RC8180";
730 		break;
731 	case MV_DEV_88RC9480:
732 		dev = "Marvell 88RC9480";
733 		break;
734 	case MV_DEV_88RC9580:
735 		dev = "Marvell 88RC9580";
736 		break;
737 	case MV_DEV_88F6781:
738 		dev = "Marvell 88F6781";
739 		if (r == 2)
740 			rev = "Y0";
741 		break;
742 	case MV_DEV_88F6282:
743 		dev = "Marvell 88F6282";
744 		if (r == 0)
745 			rev = "A0";
746 		else if (r == 1)
747 			rev = "A1";
748 		break;
749 	case MV_DEV_88F6828:
750 		dev = "Marvell 88F6828";
751 		break;
752 	case MV_DEV_88F6820:
753 		dev = "Marvell 88F6820";
754 		break;
755 	case MV_DEV_88F6810:
756 		dev = "Marvell 88F6810";
757 		break;
758 	case MV_DEV_MV78100_Z0:
759 		dev = "Marvell MV78100 Z0";
760 		break;
761 	case MV_DEV_MV78100:
762 		dev = "Marvell MV78100";
763 		break;
764 	case MV_DEV_MV78160:
765 		dev = "Marvell MV78160";
766 		break;
767 	case MV_DEV_MV78260:
768 		dev = "Marvell MV78260";
769 		break;
770 	case MV_DEV_MV78460:
771 		dev = "Marvell MV78460";
772 		break;
773 	default:
774 		dev = "UNKNOWN";
775 		break;
776 	}
777 
778 	printf("%s", dev);
779 	if (*rev != '\0')
780 		printf(" rev %s", rev);
781 	printf(", TClock %dMHz", get_tclk() / 1000 / 1000);
782 	freq = get_cpu_freq();
783 	if (freq != 0)
784 		printf(", Frequency %dMHz", freq / 1000 / 1000);
785 	printf("\n");
786 
787 	mode = read_cpu_ctrl(CPU_CONFIG);
788 	printf("  Instruction cache prefetch %s, data cache prefetch %s\n",
789 	    (mode & CPU_CONFIG_IC_PREF) ? "enabled" : "disabled",
790 	    (mode & CPU_CONFIG_DC_PREF) ? "enabled" : "disabled");
791 
792 	switch (d) {
793 	case MV_DEV_88F6281:
794 	case MV_DEV_88F6282:
795 		mode = read_cpu_ctrl(CPU_L2_CONFIG) & CPU_L2_CONFIG_MODE;
796 		printf("  256KB 4-way set-associative %s unified L2 cache\n",
797 		    mode ? "write-through" : "write-back");
798 		break;
799 	case MV_DEV_MV78100:
800 		mode = read_cpu_ctrl(CPU_CONTROL);
801 		size = mode & CPU_CONTROL_L2_SIZE;
802 		mode = mode & CPU_CONTROL_L2_MODE;
803 		printf("  %s set-associative %s unified L2 cache\n",
804 		    size ? "256KB 4-way" : "512KB 8-way",
805 		    mode ? "write-through" : "write-back");
806 		break;
807 	default:
808 		break;
809 	}
810 }
811 
812 #ifdef KDB
813 static void
814 mv_enter_debugger(void *dummy)
815 {
816 
817 	if (boothowto & RB_KDB)
818 		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
819 }
820 SYSINIT(mv_enter_debugger, SI_SUB_CPU, SI_ORDER_ANY, mv_enter_debugger, NULL);
821 #endif
822 
823 int
824 soc_decode_win(void)
825 {
826 	uint32_t dev, rev;
827 	int mask, err;
828 
829 	mask = 0;
830 	TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
831 
832 	if (mask != 0)
833 		pm_disable_device(mask);
834 
835 	/* Retrieve data about physical addresses from device tree. */
836 	if ((err = win_cpu_from_dt()) != 0)
837 		return (err);
838 
839 	/* Retrieve our ID: some windows facilities vary between SoC models */
840 	soc_id(&dev, &rev);
841 
842 	if (soc_family == MV_SOC_ARMADA_XP)
843 		if ((err = decode_win_sdram_fixup()) != 0)
844 			return(err);
845 
846 	decode_win_cpu_setup();
847 	if (MV_DUMP_WIN)
848 		soc_dump_decode_win();
849 
850 	eth_port = 0;
851 	usb_port = 0;
852 	if ((err = fdt_win_setup()) != 0)
853 		return (err);
854 
855 	return (0);
856 }
857 
858 /**************************************************************************
859  * Decode windows registers accessors
860  **************************************************************************/
861 WIN_REG_IDX_RD(win_cpu_armv5, cr, MV_WIN_CPU_CTRL_ARMV5, MV_MBUS_BRIDGE_BASE)
862 WIN_REG_IDX_RD(win_cpu_armv5, br, MV_WIN_CPU_BASE_ARMV5, MV_MBUS_BRIDGE_BASE)
863 WIN_REG_IDX_RD(win_cpu_armv5, remap_l, MV_WIN_CPU_REMAP_LO_ARMV5, MV_MBUS_BRIDGE_BASE)
864 WIN_REG_IDX_RD(win_cpu_armv5, remap_h, MV_WIN_CPU_REMAP_HI_ARMV5, MV_MBUS_BRIDGE_BASE)
865 WIN_REG_IDX_WR(win_cpu_armv5, cr, MV_WIN_CPU_CTRL_ARMV5, MV_MBUS_BRIDGE_BASE)
866 WIN_REG_IDX_WR(win_cpu_armv5, br, MV_WIN_CPU_BASE_ARMV5, MV_MBUS_BRIDGE_BASE)
867 WIN_REG_IDX_WR(win_cpu_armv5, remap_l, MV_WIN_CPU_REMAP_LO_ARMV5, MV_MBUS_BRIDGE_BASE)
868 WIN_REG_IDX_WR(win_cpu_armv5, remap_h, MV_WIN_CPU_REMAP_HI_ARMV5, MV_MBUS_BRIDGE_BASE)
869 
870 WIN_REG_IDX_RD(win_cpu_armv7, cr, MV_WIN_CPU_CTRL_ARMV7, MV_MBUS_BRIDGE_BASE)
871 WIN_REG_IDX_RD(win_cpu_armv7, br, MV_WIN_CPU_BASE_ARMV7, MV_MBUS_BRIDGE_BASE)
872 WIN_REG_IDX_RD(win_cpu_armv7, remap_l, MV_WIN_CPU_REMAP_LO_ARMV7, MV_MBUS_BRIDGE_BASE)
873 WIN_REG_IDX_RD(win_cpu_armv7, remap_h, MV_WIN_CPU_REMAP_HI_ARMV7, MV_MBUS_BRIDGE_BASE)
874 WIN_REG_IDX_WR(win_cpu_armv7, cr, MV_WIN_CPU_CTRL_ARMV7, MV_MBUS_BRIDGE_BASE)
875 WIN_REG_IDX_WR(win_cpu_armv7, br, MV_WIN_CPU_BASE_ARMV7, MV_MBUS_BRIDGE_BASE)
876 WIN_REG_IDX_WR(win_cpu_armv7, remap_l, MV_WIN_CPU_REMAP_LO_ARMV7, MV_MBUS_BRIDGE_BASE)
877 WIN_REG_IDX_WR(win_cpu_armv7, remap_h, MV_WIN_CPU_REMAP_HI_ARMV7, MV_MBUS_BRIDGE_BASE)
878 
879 static uint32_t
880 win_cpu_cr_read(int i)
881 {
882 
883 	if (soc_decode_win_spec->cr_read != NULL)
884 		return (soc_decode_win_spec->cr_read(i));
885 	return (-1);
886 }
887 
888 static uint32_t
889 win_cpu_br_read(int i)
890 {
891 
892 	if (soc_decode_win_spec->br_read != NULL)
893 		return (soc_decode_win_spec->br_read(i));
894 	return (-1);
895 }
896 
897 static uint32_t
898 win_cpu_remap_l_read(int i)
899 {
900 
901 	if (soc_decode_win_spec->remap_l_read != NULL)
902 		return (soc_decode_win_spec->remap_l_read(i));
903 	return (-1);
904 }
905 
906 static uint32_t
907 win_cpu_remap_h_read(int i)
908 {
909 
910 	if (soc_decode_win_spec->remap_h_read != NULL)
911 		return soc_decode_win_spec->remap_h_read(i);
912 	return (-1);
913 }
914 
915 static void
916 win_cpu_cr_write(int i, uint32_t val)
917 {
918 
919 	if (soc_decode_win_spec->cr_write != NULL)
920 		soc_decode_win_spec->cr_write(i, val);
921 }
922 
923 static void
924 win_cpu_br_write(int i, uint32_t val)
925 {
926 
927 	if (soc_decode_win_spec->br_write != NULL)
928 		soc_decode_win_spec->br_write(i, val);
929 }
930 
931 static void
932 win_cpu_remap_l_write(int i, uint32_t val)
933 {
934 
935 	if (soc_decode_win_spec->remap_l_write != NULL)
936 		soc_decode_win_spec->remap_l_write(i, val);
937 }
938 
939 static void
940 win_cpu_remap_h_write(int i, uint32_t val)
941 {
942 
943 	if (soc_decode_win_spec->remap_h_write != NULL)
944 		soc_decode_win_spec->remap_h_write(i, val);
945 }
946 
947 WIN_REG_BASE_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL)
948 WIN_REG_BASE_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE)
949 WIN_REG_BASE_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL)
950 WIN_REG_BASE_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE)
951 
952 WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
953 WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
954 WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
955 WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE)
956 
957 WIN_REG_BASE_IDX_RD(win_usb3, cr, MV_WIN_USB3_CTRL)
958 WIN_REG_BASE_IDX_RD(win_usb3, br, MV_WIN_USB3_BASE)
959 WIN_REG_BASE_IDX_WR(win_usb3, cr, MV_WIN_USB3_CTRL)
960 WIN_REG_BASE_IDX_WR(win_usb3, br, MV_WIN_USB3_BASE)
961 
962 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
963 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
964 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
965 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
966 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
967 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
968 
969 WIN_REG_BASE_RD(win_eth, bare, 0x290)
970 WIN_REG_BASE_RD(win_eth, epap, 0x294)
971 WIN_REG_BASE_WR(win_eth, bare, 0x290)
972 WIN_REG_BASE_WR(win_eth, epap, 0x294)
973 
974 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
975 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
976 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
977 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
978 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
979 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
980 WIN_REG_BASE_IDX_RD(pcie_bar, br, MV_PCIE_BAR_BASE);
981 WIN_REG_BASE_IDX_RD(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
982 WIN_REG_BASE_IDX_RD(pcie_bar, cr, MV_PCIE_BAR_CTRL);
983 WIN_REG_BASE_IDX_WR(pcie_bar, br, MV_PCIE_BAR_BASE);
984 WIN_REG_BASE_IDX_WR(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
985 WIN_REG_BASE_IDX_WR(pcie_bar, cr, MV_PCIE_BAR_CTRL);
986 
987 WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL);
988 WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE);
989 WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL);
990 WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE);
991 
992 WIN_REG_BASE_IDX_RD(win_sata_armada38x, sz, MV_WIN_SATA_SIZE_ARMADA38X);
993 WIN_REG_BASE_IDX_WR(win_sata_armada38x, sz, MV_WIN_SATA_SIZE_ARMADA38X);
994 WIN_REG_BASE_IDX_RD(win_sata_armada38x, cr, MV_WIN_SATA_CTRL_ARMADA38X);
995 WIN_REG_BASE_IDX_WR(win_sata_armada38x, cr, MV_WIN_SATA_CTRL_ARMADA38X);
996 WIN_REG_BASE_IDX_WR(win_sata_armada38x, br, MV_WIN_SATA_BASE_ARMADA38X);
997 
998 WIN_REG_BASE_IDX_RD(win_sdhci, cr, MV_WIN_SDHCI_CTRL);
999 WIN_REG_BASE_IDX_RD(win_sdhci, br, MV_WIN_SDHCI_BASE);
1000 WIN_REG_BASE_IDX_WR(win_sdhci, cr, MV_WIN_SDHCI_CTRL);
1001 WIN_REG_BASE_IDX_WR(win_sdhci, br, MV_WIN_SDHCI_BASE);
1002 
1003 #ifndef SOC_MV_DOVE
1004 WIN_REG_IDX_RD(ddr_armv5, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
1005 WIN_REG_IDX_RD(ddr_armv5, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
1006 WIN_REG_IDX_WR(ddr_armv5, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
1007 WIN_REG_IDX_WR(ddr_armv5, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
1008 
1009 WIN_REG_IDX_RD(ddr_armv7, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE_ARMV7)
1010 WIN_REG_IDX_RD(ddr_armv7, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE_ARMV7)
1011 WIN_REG_IDX_WR(ddr_armv7, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE_ARMV7)
1012 WIN_REG_IDX_WR(ddr_armv7, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE_ARMV7)
1013 
1014 static inline uint32_t
1015 ddr_br_read(int i)
1016 {
1017 
1018 	if (soc_decode_win_spec->ddr_br_read != NULL)
1019 		return (soc_decode_win_spec->ddr_br_read(i));
1020 	return (-1);
1021 }
1022 
1023 static inline uint32_t
1024 ddr_sz_read(int i)
1025 {
1026 
1027 	if (soc_decode_win_spec->ddr_sz_read != NULL)
1028 		return (soc_decode_win_spec->ddr_sz_read(i));
1029 	return (-1);
1030 }
1031 
1032 static inline void
1033 ddr_br_write(int i, uint32_t val)
1034 {
1035 
1036 	if (soc_decode_win_spec->ddr_br_write != NULL)
1037 		soc_decode_win_spec->ddr_br_write(i, val);
1038 }
1039 
1040 static inline void
1041 ddr_sz_write(int i, uint32_t val)
1042 {
1043 
1044 	if (soc_decode_win_spec->ddr_sz_write != NULL)
1045 		soc_decode_win_spec->ddr_sz_write(i, val);
1046 }
1047 #else
1048 /*
1049  * On 88F6781 (Dove) SoC DDR Controller is accessed through
1050  * single MBUS <-> AXI bridge. In this case we provide emulated
1051  * ddr_br_read() and ddr_sz_read() functions to keep compatibility
1052  * with common decoding windows setup code.
1053  */
1054 
1055 static inline uint32_t ddr_br_read(int i)
1056 {
1057 	uint32_t mmap;
1058 
1059 	/* Read Memory Address Map Register for CS i */
1060 	mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
1061 
1062 	/* Return CS i base address */
1063 	return (mmap & 0xFF000000);
1064 }
1065 
1066 static inline uint32_t ddr_sz_read(int i)
1067 {
1068 	uint32_t mmap, size;
1069 
1070 	/* Read Memory Address Map Register for CS i */
1071 	mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
1072 
1073 	/* Extract size of CS space in 64kB units */
1074 	size = (1 << ((mmap >> 16) & 0x0F));
1075 
1076 	/* Return CS size and enable/disable status */
1077 	return (((size - 1) << 16) | (mmap & 0x01));
1078 }
1079 #endif
1080 
1081 /**************************************************************************
1082  * Decode windows helper routines
1083  **************************************************************************/
1084 void
1085 soc_dump_decode_win(void)
1086 {
1087 	int i;
1088 
1089 	for (i = 0; i < soc_decode_win_spec->mv_win_cpu_max; i++) {
1090 		printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
1091 		    win_cpu_cr_read(i),
1092 		    win_cpu_br_read(i));
1093 
1094 		if (win_cpu_can_remap(i))
1095 			printf(", rl 0x%08x, rh 0x%08x",
1096 			    win_cpu_remap_l_read(i),
1097 			    win_cpu_remap_h_read(i));
1098 
1099 		printf("\n");
1100 	}
1101 	printf("Internal regs base: 0x%08x\n",
1102 	    bus_space_read_4(fdtbus_bs_tag, MV_INTREGS_BASE, 0));
1103 
1104 	for (i = 0; i < MV_WIN_DDR_MAX; i++)
1105 		printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
1106 		    ddr_br_read(i), ddr_sz_read(i));
1107 }
1108 
1109 /**************************************************************************
1110  * CPU windows routines
1111  **************************************************************************/
1112 int
1113 win_cpu_can_remap(int i)
1114 {
1115 	uint32_t dev, rev;
1116 
1117 	soc_id(&dev, &rev);
1118 
1119 	/* Depending on the SoC certain windows have remap capability */
1120 	if ((dev == MV_DEV_88F5182 && i < 2) ||
1121 	    (dev == MV_DEV_88F5281 && i < 4) ||
1122 	    (dev == MV_DEV_88F6281 && i < 4) ||
1123 	    (dev == MV_DEV_88F6282 && i < 4) ||
1124 	    (dev == MV_DEV_88F6828 && i < 20) ||
1125 	    (dev == MV_DEV_88F6820 && i < 20) ||
1126 	    (dev == MV_DEV_88F6810 && i < 20) ||
1127 	    (dev == MV_DEV_88RC8180 && i < 2) ||
1128 	    (dev == MV_DEV_88F6781 && i < 4) ||
1129 	    (dev == MV_DEV_MV78100_Z0 && i < 8) ||
1130 	    ((dev & MV_DEV_FAMILY_MASK) == MV_DEV_DISCOVERY && i < 8))
1131 		return (1);
1132 
1133 	return (0);
1134 }
1135 
1136 /* XXX This should check for overlapping remap fields too.. */
1137 int
1138 decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
1139 {
1140 	const struct decode_win *tab;
1141 	int i;
1142 
1143 	tab = wintab;
1144 
1145 	for (i = 0; i < win_no; i++, tab++) {
1146 		if (i == win)
1147 			/* Skip self */
1148 			continue;
1149 
1150 		if ((tab->base + tab->size - 1) < (wintab + win)->base)
1151 			continue;
1152 
1153 		else if (((wintab + win)->base + (wintab + win)->size - 1) <
1154 		    tab->base)
1155 			continue;
1156 		else
1157 			return (i);
1158 	}
1159 
1160 	return (-1);
1161 }
1162 
1163 int
1164 decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
1165     vm_paddr_t remap)
1166 {
1167 	uint32_t br, cr;
1168 	int win, i;
1169 
1170 	if (remap == ~0) {
1171 		win = soc_decode_win_spec->mv_win_cpu_max - 1;
1172 		i = -1;
1173 	} else {
1174 		win = 0;
1175 		i = 1;
1176 	}
1177 
1178 	while ((win >= 0) && (win < soc_decode_win_spec->mv_win_cpu_max)) {
1179 		cr = win_cpu_cr_read(win);
1180 		if ((cr & MV_WIN_CPU_ENABLE_BIT) == 0)
1181 			break;
1182 		if ((cr & ((0xff << MV_WIN_CPU_ATTR_SHIFT) |
1183 		    (0x1f << MV_WIN_CPU_TARGET_SHIFT))) ==
1184 		    ((attr << MV_WIN_CPU_ATTR_SHIFT) |
1185 		    (target << MV_WIN_CPU_TARGET_SHIFT)))
1186 			break;
1187 		win += i;
1188 	}
1189 	if ((win < 0) || (win >= soc_decode_win_spec->mv_win_cpu_max) ||
1190 	    ((remap != ~0) && (win_cpu_can_remap(win) == 0)))
1191 		return (-1);
1192 
1193 	br = base & 0xffff0000;
1194 	win_cpu_br_write(win, br);
1195 
1196 	if (win_cpu_can_remap(win)) {
1197 		if (remap != ~0) {
1198 			win_cpu_remap_l_write(win, remap & 0xffff0000);
1199 			win_cpu_remap_h_write(win, 0);
1200 		} else {
1201 			/*
1202 			 * Remap function is not used for a given window
1203 			 * (capable of remapping) - set remap field with the
1204 			 * same value as base.
1205 			 */
1206 			win_cpu_remap_l_write(win, base & 0xffff0000);
1207 			win_cpu_remap_h_write(win, 0);
1208 		}
1209 	}
1210 
1211 	cr = ((size - 1) & 0xffff0000) | (attr << MV_WIN_CPU_ATTR_SHIFT) |
1212 	    (target << MV_WIN_CPU_TARGET_SHIFT) | MV_WIN_CPU_ENABLE_BIT;
1213 	win_cpu_cr_write(win, cr);
1214 
1215 	return (0);
1216 }
1217 
1218 static void
1219 decode_win_cpu_setup(void)
1220 {
1221 	int i;
1222 
1223 	/* Disable all CPU windows */
1224 	for (i = 0; i < soc_decode_win_spec->mv_win_cpu_max; i++) {
1225 		win_cpu_cr_write(i, 0);
1226 		win_cpu_br_write(i, 0);
1227 		if (win_cpu_can_remap(i)) {
1228 			win_cpu_remap_l_write(i, 0);
1229 			win_cpu_remap_h_write(i, 0);
1230 		}
1231 	}
1232 
1233 	for (i = 0; i < cpu_wins_no; i++)
1234 		if (cpu_wins[i].target > 0)
1235 			decode_win_cpu_set(cpu_wins[i].target,
1236 			    cpu_wins[i].attr, cpu_wins[i].base,
1237 			    cpu_wins[i].size, cpu_wins[i].remap);
1238 
1239 }
1240 
1241 static int
1242 decode_win_sdram_fixup(void)
1243 {
1244 	struct mem_region mr[FDT_MEM_REGIONS];
1245 	uint8_t window_valid[MV_WIN_DDR_MAX];
1246 	int mr_cnt, err, i, j;
1247 	uint32_t valid_win_num = 0;
1248 
1249 	/* Grab physical memory regions information from device tree. */
1250 	err = fdt_get_mem_regions(mr, &mr_cnt, NULL);
1251 	if (err != 0)
1252 		return (err);
1253 
1254 	for (i = 0; i < MV_WIN_DDR_MAX; i++)
1255 		window_valid[i] = 0;
1256 
1257 	/* Try to match entries from device tree with settings from u-boot */
1258 	for (i = 0; i < mr_cnt; i++) {
1259 		for (j = 0; j < MV_WIN_DDR_MAX; j++) {
1260 			if (ddr_is_active(j) &&
1261 			    (ddr_base(j) == mr[i].mr_start) &&
1262 			    (ddr_size(j) == mr[i].mr_size)) {
1263 				window_valid[j] = 1;
1264 				valid_win_num++;
1265 			}
1266 		}
1267 	}
1268 
1269 	if (mr_cnt != valid_win_num)
1270 		return (EINVAL);
1271 
1272 	/* Destroy windows without corresponding device tree entry */
1273 	for (j = 0; j < MV_WIN_DDR_MAX; j++) {
1274 		if (ddr_is_active(j) && (window_valid[j] != 1)) {
1275 			printf("Disabling SDRAM decoding window: %d\n", j);
1276 			ddr_disable(j);
1277 		}
1278 	}
1279 
1280 	return (0);
1281 }
1282 /*
1283  * Check if we're able to cover all active DDR banks.
1284  */
1285 static int
1286 decode_win_can_cover_ddr(int max)
1287 {
1288 	int i, c;
1289 
1290 	c = 0;
1291 	for (i = 0; i < MV_WIN_DDR_MAX; i++)
1292 		if (ddr_is_active(i))
1293 			c++;
1294 
1295 	if (c > max) {
1296 		printf("Unable to cover all active DDR banks: "
1297 		    "%d, available windows: %d\n", c, max);
1298 		return (0);
1299 	}
1300 
1301 	return (1);
1302 }
1303 
1304 /**************************************************************************
1305  * DDR windows routines
1306  **************************************************************************/
1307 int
1308 ddr_is_active(int i)
1309 {
1310 
1311 	if (ddr_sz_read(i) & 0x1)
1312 		return (1);
1313 
1314 	return (0);
1315 }
1316 
1317 void
1318 ddr_disable(int i)
1319 {
1320 
1321 	ddr_sz_write(i, 0);
1322 	ddr_br_write(i, 0);
1323 }
1324 
1325 uint32_t
1326 ddr_base(int i)
1327 {
1328 
1329 	return (ddr_br_read(i) & 0xff000000);
1330 }
1331 
1332 uint32_t
1333 ddr_size(int i)
1334 {
1335 
1336 	return ((ddr_sz_read(i) | 0x00ffffff) + 1);
1337 }
1338 
1339 uint32_t
1340 ddr_attr(int i)
1341 {
1342 	uint32_t dev, rev, attr;
1343 
1344 	soc_id(&dev, &rev);
1345 	if (dev == MV_DEV_88RC8180)
1346 		return ((ddr_sz_read(i) & 0xf0) >> 4);
1347 	if (dev == MV_DEV_88F6781)
1348 		return (0);
1349 
1350 	attr = (i == 0 ? 0xe :
1351 	    (i == 1 ? 0xd :
1352 	    (i == 2 ? 0xb :
1353 	    (i == 3 ? 0x7 : 0xff))));
1354 	if (platform_io_coherent)
1355 		attr |= 0x10;
1356 
1357 	return (attr);
1358 }
1359 
1360 uint32_t
1361 ddr_target(int i)
1362 {
1363 	uint32_t dev, rev;
1364 
1365 	soc_id(&dev, &rev);
1366 	if (dev == MV_DEV_88RC8180) {
1367 		i = (ddr_sz_read(i) & 0xf0) >> 4;
1368 		return (i == 0xe ? 0xc :
1369 		    (i == 0xd ? 0xd :
1370 		    (i == 0xb ? 0xe :
1371 		    (i == 0x7 ? 0xf : 0xc))));
1372 	}
1373 
1374 	/*
1375 	 * On SOCs other than 88RC8180 Mbus unit ID for
1376 	 * DDR SDRAM controller is always 0x0.
1377 	 */
1378 	return (0);
1379 }
1380 
1381 /**************************************************************************
1382  * CESA windows routines
1383  **************************************************************************/
1384 static int
1385 decode_win_cesa_valid(void)
1386 {
1387 
1388 	return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
1389 }
1390 
1391 static void
1392 decode_win_cesa_dump(u_long base)
1393 {
1394 	int i;
1395 
1396 	for (i = 0; i < MV_WIN_CESA_MAX; i++)
1397 		printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
1398 		    win_cesa_cr_read(base, i), win_cesa_br_read(base, i));
1399 }
1400 
1401 /*
1402  * Set CESA decode windows.
1403  */
1404 static void
1405 decode_win_cesa_setup(u_long base)
1406 {
1407 	uint32_t br, cr;
1408 	uint64_t size;
1409 	int i, j;
1410 
1411 	for (i = 0; i < MV_WIN_CESA_MAX; i++) {
1412 		win_cesa_cr_write(base, i, 0);
1413 		win_cesa_br_write(base, i, 0);
1414 	}
1415 
1416 	/* Only access to active DRAM banks is required */
1417 	for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1418 		if (ddr_is_active(i)) {
1419 			br = ddr_base(i);
1420 
1421 			size = ddr_size(i);
1422 			/*
1423 			 * Armada 38x SoC's equipped with 4GB DRAM
1424 			 * suffer freeze during CESA operation, if
1425 			 * MBUS window opened at given DRAM CS reaches
1426 			 * end of the address space. Apply a workaround
1427 			 * by setting the window size to the closest possible
1428 			 * value, i.e. divide it by 2.
1429 			 */
1430 			if ((soc_family == MV_SOC_ARMADA_38X) &&
1431 			    (size + ddr_base(i) == 0x100000000ULL))
1432 				size /= 2;
1433 
1434 			cr = (((size - 1) & 0xffff0000) |
1435 			    (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1436 			    (ddr_target(i) << IO_WIN_TGT_SHIFT) |
1437 			    IO_WIN_ENA_MASK);
1438 
1439 			/* Set the first free CESA window */
1440 			for (j = 0; j < MV_WIN_CESA_MAX; j++) {
1441 				if (win_cesa_cr_read(base, j) & 0x1)
1442 					continue;
1443 
1444 				win_cesa_br_write(base, j, br);
1445 				win_cesa_cr_write(base, j, cr);
1446 				break;
1447 			}
1448 		}
1449 	}
1450 }
1451 
1452 static void
1453 decode_win_a38x_cesa_setup(u_long base)
1454 {
1455 	decode_win_cesa_setup(base);
1456 	decode_win_cesa_setup(base + MV_WIN_CESA_OFFSET);
1457 }
1458 
1459 static void
1460 decode_win_a38x_cesa_dump(u_long base)
1461 {
1462 	decode_win_cesa_dump(base);
1463 	decode_win_cesa_dump(base + MV_WIN_CESA_OFFSET);
1464 }
1465 
1466 /**************************************************************************
1467  * USB windows routines
1468  **************************************************************************/
1469 static int
1470 decode_win_usb_valid(void)
1471 {
1472 
1473 	return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
1474 }
1475 
1476 static void
1477 decode_win_usb_dump(u_long base)
1478 {
1479 	int i;
1480 
1481 	if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port - 1)))
1482 		return;
1483 
1484 	for (i = 0; i < MV_WIN_USB_MAX; i++)
1485 		printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
1486 		    win_usb_cr_read(base, i), win_usb_br_read(base, i));
1487 }
1488 
1489 /*
1490  * Set USB decode windows.
1491  */
1492 static void
1493 decode_win_usb_setup(u_long base)
1494 {
1495 	uint32_t br, cr;
1496 	int i, j;
1497 
1498 	if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port)))
1499 		return;
1500 
1501 	usb_port++;
1502 
1503 	for (i = 0; i < MV_WIN_USB_MAX; i++) {
1504 		win_usb_cr_write(base, i, 0);
1505 		win_usb_br_write(base, i, 0);
1506 	}
1507 
1508 	/* Only access to active DRAM banks is required */
1509 	for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1510 		if (ddr_is_active(i)) {
1511 			br = ddr_base(i);
1512 			/*
1513 			 * XXX for 6281 we should handle Mbus write
1514 			 * burst limit field in the ctrl reg
1515 			 */
1516 			cr = (((ddr_size(i) - 1) & 0xffff0000) |
1517 			    (ddr_attr(i) << 8) |
1518 			    (ddr_target(i) << 4) | 1);
1519 
1520 			/* Set the first free USB window */
1521 			for (j = 0; j < MV_WIN_USB_MAX; j++) {
1522 				if (win_usb_cr_read(base, j) & 0x1)
1523 					continue;
1524 
1525 				win_usb_br_write(base, j, br);
1526 				win_usb_cr_write(base, j, cr);
1527 				break;
1528 			}
1529 		}
1530 	}
1531 }
1532 
1533 /**************************************************************************
1534  * USB3 windows routines
1535  **************************************************************************/
1536 static int
1537 decode_win_usb3_valid(void)
1538 {
1539 
1540 	return (decode_win_can_cover_ddr(MV_WIN_USB3_MAX));
1541 }
1542 
1543 static void
1544 decode_win_usb3_dump(u_long base)
1545 {
1546 	int i;
1547 
1548 	for (i = 0; i < MV_WIN_USB3_MAX; i++)
1549 		printf("USB3.0 window#%d: c 0x%08x, b 0x%08x\n", i,
1550 		    win_usb3_cr_read(base, i), win_usb3_br_read(base, i));
1551 }
1552 
1553 /*
1554  * Set USB3 decode windows
1555  */
1556 static void
1557 decode_win_usb3_setup(u_long base)
1558 {
1559 	uint32_t br, cr;
1560 	int i, j;
1561 
1562 	for (i = 0; i < MV_WIN_USB3_MAX; i++) {
1563 		win_usb3_cr_write(base, i, 0);
1564 		win_usb3_br_write(base, i, 0);
1565 	}
1566 
1567 	/* Only access to active DRAM banks is required */
1568 	for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1569 		if (ddr_is_active(i)) {
1570 			br = ddr_base(i);
1571 			cr = (((ddr_size(i) - 1) &
1572 			    (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT)) |
1573 			    (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
1574 			    (ddr_target(i) << IO_WIN_TGT_SHIFT) |
1575 			    IO_WIN_ENA_MASK);
1576 
1577 			/* Set the first free USB3.0 window */
1578 			for (j = 0; j < MV_WIN_USB3_MAX; j++) {
1579 				if (win_usb3_cr_read(base, j) & IO_WIN_ENA_MASK)
1580 					continue;
1581 
1582 				win_usb3_br_write(base, j, br);
1583 				win_usb3_cr_write(base, j, cr);
1584 				break;
1585 			}
1586 		}
1587 	}
1588 }
1589 
1590 /**************************************************************************
1591  * ETH windows routines
1592  **************************************************************************/
1593 
1594 static int
1595 win_eth_can_remap(int i)
1596 {
1597 
1598 	/* ETH encode windows 0-3 have remap capability */
1599 	if (i < 4)
1600 		return (1);
1601 
1602 	return (0);
1603 }
1604 
1605 static int
1606 eth_bare_read(uint32_t base, int i)
1607 {
1608 	uint32_t v;
1609 
1610 	v = win_eth_bare_read(base);
1611 	v &= (1 << i);
1612 
1613 	return (v >> i);
1614 }
1615 
1616 static void
1617 eth_bare_write(uint32_t base, int i, int val)
1618 {
1619 	uint32_t v;
1620 
1621 	v = win_eth_bare_read(base);
1622 	v &= ~(1 << i);
1623 	v |= (val << i);
1624 	win_eth_bare_write(base, v);
1625 }
1626 
1627 static void
1628 eth_epap_write(uint32_t base, int i, int val)
1629 {
1630 	uint32_t v;
1631 
1632 	v = win_eth_epap_read(base);
1633 	v &= ~(0x3 << (i * 2));
1634 	v |= (val << (i * 2));
1635 	win_eth_epap_write(base, v);
1636 }
1637 
1638 static void
1639 decode_win_eth_dump(u_long base)
1640 {
1641 	int i;
1642 
1643 	if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port - 1)))
1644 		return;
1645 
1646 	for (i = 0; i < MV_WIN_ETH_MAX; i++) {
1647 		printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
1648 		    win_eth_br_read(base, i),
1649 		    win_eth_sz_read(base, i));
1650 
1651 		if (win_eth_can_remap(i))
1652 			printf(", ha 0x%08x",
1653 			    win_eth_har_read(base, i));
1654 
1655 		printf("\n");
1656 	}
1657 	printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
1658 	    win_eth_bare_read(base),
1659 	    win_eth_epap_read(base));
1660 }
1661 
1662 #define MV_WIN_ETH_DDR_TRGT(n)	ddr_target(n)
1663 
1664 static void
1665 decode_win_eth_setup(u_long base)
1666 {
1667 	uint32_t br, sz;
1668 	int i, j;
1669 
1670 	if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port)))
1671 		return;
1672 
1673 	eth_port++;
1674 
1675 	/* Disable, clear and revoke protection for all ETH windows */
1676 	for (i = 0; i < MV_WIN_ETH_MAX; i++) {
1677 		eth_bare_write(base, i, 1);
1678 		eth_epap_write(base, i, 0);
1679 		win_eth_br_write(base, i, 0);
1680 		win_eth_sz_write(base, i, 0);
1681 		if (win_eth_can_remap(i))
1682 			win_eth_har_write(base, i, 0);
1683 	}
1684 
1685 	/* Only access to active DRAM banks is required */
1686 	for (i = 0; i < MV_WIN_DDR_MAX; i++)
1687 		if (ddr_is_active(i)) {
1688 			br = ddr_base(i) | (ddr_attr(i) << 8) | MV_WIN_ETH_DDR_TRGT(i);
1689 			sz = ((ddr_size(i) - 1) & 0xffff0000);
1690 
1691 			/* Set the first free ETH window */
1692 			for (j = 0; j < MV_WIN_ETH_MAX; j++) {
1693 				if (eth_bare_read(base, j) == 0)
1694 					continue;
1695 
1696 				win_eth_br_write(base, j, br);
1697 				win_eth_sz_write(base, j, sz);
1698 
1699 				/* XXX remapping ETH windows not supported */
1700 
1701 				/* Set protection RW */
1702 				eth_epap_write(base, j, 0x3);
1703 
1704 				/* Enable window */
1705 				eth_bare_write(base, j, 0);
1706 				break;
1707 			}
1708 		}
1709 }
1710 
1711 static void
1712 decode_win_neta_dump(u_long base)
1713 {
1714 
1715 	decode_win_eth_dump(base + MV_WIN_NETA_OFFSET);
1716 }
1717 
1718 static void
1719 decode_win_neta_setup(u_long base)
1720 {
1721 
1722 	decode_win_eth_setup(base + MV_WIN_NETA_OFFSET);
1723 }
1724 
1725 static int
1726 decode_win_eth_valid(void)
1727 {
1728 
1729 	return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
1730 }
1731 
1732 /**************************************************************************
1733  * PCIE windows routines
1734  **************************************************************************/
1735 static void
1736 decode_win_pcie_dump(u_long base)
1737 {
1738 	int i;
1739 
1740 	printf("PCIE windows base 0x%08lx\n", base);
1741 	for (i = 0; i < MV_WIN_PCIE_MAX; i++)
1742 		printf("PCIE window#%d: cr 0x%08x br 0x%08x remap 0x%08x\n",
1743 		    i, win_pcie_cr_read(base, i),
1744 		    win_pcie_br_read(base, i), win_pcie_remap_read(base, i));
1745 
1746 	for (i = 0; i < MV_PCIE_BAR_MAX; i++)
1747 		printf("PCIE bar#%d: cr 0x%08x br 0x%08x brh 0x%08x\n",
1748 		    i, pcie_bar_cr_read(base, i),
1749 		    pcie_bar_br_read(base, i), pcie_bar_brh_read(base, i));
1750 }
1751 
1752 void
1753 decode_win_pcie_setup(u_long base)
1754 {
1755 	uint32_t size = 0, ddrbase = ~0;
1756 	uint32_t cr, br;
1757 	int i, j;
1758 
1759 	for (i = 0; i < MV_PCIE_BAR_MAX; i++) {
1760 		pcie_bar_br_write(base, i,
1761 		    MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1762 		if (i < 3)
1763 			pcie_bar_brh_write(base, i, 0);
1764 		if (i > 0)
1765 			pcie_bar_cr_write(base, i, 0);
1766 	}
1767 
1768 	for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
1769 		win_pcie_cr_write(base, i, 0);
1770 		win_pcie_br_write(base, i, 0);
1771 		win_pcie_remap_write(base, i, 0);
1772 	}
1773 
1774 	/* On End-Point only set BAR size to 1MB regardless of DDR size */
1775 	if ((bus_space_read_4(fdtbus_bs_tag, base, MV_PCIE_CONTROL)
1776 	    & MV_PCIE_ROOT_CMPLX) == 0) {
1777 		pcie_bar_cr_write(base, 1, 0xf0000 | 1);
1778 		return;
1779 	}
1780 
1781 	for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1782 		if (ddr_is_active(i)) {
1783 			/* Map DDR to BAR 1 */
1784 			cr = (ddr_size(i) - 1) & 0xffff0000;
1785 			size += ddr_size(i) & 0xffff0000;
1786 			cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
1787 			br = ddr_base(i);
1788 			if (br < ddrbase)
1789 				ddrbase = br;
1790 
1791 			/* Use the first available PCIE window */
1792 			for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
1793 				if (win_pcie_cr_read(base, j) != 0)
1794 					continue;
1795 
1796 				win_pcie_br_write(base, j, br);
1797 				win_pcie_cr_write(base, j, cr);
1798 				break;
1799 			}
1800 		}
1801 	}
1802 
1803 	/*
1804 	 * Upper 16 bits in BAR register is interpreted as BAR size
1805 	 * (in 64 kB units) plus 64kB, so subtract 0x10000
1806 	 * form value passed to register to get correct value.
1807 	 */
1808 	size -= 0x10000;
1809 	pcie_bar_cr_write(base, 1, size | 1);
1810 	pcie_bar_br_write(base, 1, ddrbase |
1811 	    MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1812 	pcie_bar_br_write(base, 0, fdt_immr_pa |
1813 	    MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1814 }
1815 
1816 static int
1817 decode_win_pcie_valid(void)
1818 {
1819 
1820 	return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
1821 }
1822 
1823 /**************************************************************************
1824  * IDMA windows routines
1825  **************************************************************************/
1826 #if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
1827 static int
1828 idma_bare_read(u_long base, int i)
1829 {
1830 	uint32_t v;
1831 
1832 	v = win_idma_bare_read(base);
1833 	v &= (1 << i);
1834 
1835 	return (v >> i);
1836 }
1837 
1838 static void
1839 idma_bare_write(u_long base, int i, int val)
1840 {
1841 	uint32_t v;
1842 
1843 	v = win_idma_bare_read(base);
1844 	v &= ~(1 << i);
1845 	v |= (val << i);
1846 	win_idma_bare_write(base, v);
1847 }
1848 
1849 /*
1850  * Sets channel protection 'val' for window 'w' on channel 'c'
1851  */
1852 static void
1853 idma_cap_write(u_long base, int c, int w, int val)
1854 {
1855 	uint32_t v;
1856 
1857 	v = win_idma_cap_read(base, c);
1858 	v &= ~(0x3 << (w * 2));
1859 	v |= (val << (w * 2));
1860 	win_idma_cap_write(base, c, v);
1861 }
1862 
1863 /*
1864  * Set protection 'val' on all channels for window 'w'
1865  */
1866 static void
1867 idma_set_prot(u_long base, int w, int val)
1868 {
1869 	int c;
1870 
1871 	for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
1872 		idma_cap_write(base, c, w, val);
1873 }
1874 
1875 static int
1876 win_idma_can_remap(int i)
1877 {
1878 
1879 	/* IDMA decode windows 0-3 have remap capability */
1880 	if (i < 4)
1881 		return (1);
1882 
1883 	return (0);
1884 }
1885 
1886 void
1887 decode_win_idma_setup(u_long base)
1888 {
1889 	uint32_t br, sz;
1890 	int i, j;
1891 
1892 	if (pm_is_disabled(CPU_PM_CTRL_IDMA))
1893 		return;
1894 	/*
1895 	 * Disable and clear all IDMA windows, revoke protection for all channels
1896 	 */
1897 	for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
1898 		idma_bare_write(base, i, 1);
1899 		win_idma_br_write(base, i, 0);
1900 		win_idma_sz_write(base, i, 0);
1901 		if (win_idma_can_remap(i) == 1)
1902 			win_idma_har_write(base, i, 0);
1903 	}
1904 	for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1905 		win_idma_cap_write(base, i, 0);
1906 
1907 	/*
1908 	 * Set up access to all active DRAM banks
1909 	 */
1910 	for (i = 0; i < MV_WIN_DDR_MAX; i++)
1911 		if (ddr_is_active(i)) {
1912 			br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
1913 			sz = ((ddr_size(i) - 1) & 0xffff0000);
1914 
1915 			/* Place DDR entries in non-remapped windows */
1916 			for (j = 0; j < MV_WIN_IDMA_MAX; j++)
1917 				if (win_idma_can_remap(j) != 1 &&
1918 				    idma_bare_read(base, j) == 1) {
1919 					/* Configure window */
1920 					win_idma_br_write(base, j, br);
1921 					win_idma_sz_write(base, j, sz);
1922 
1923 					/* Set protection RW on all channels */
1924 					idma_set_prot(base, j, 0x3);
1925 
1926 					/* Enable window */
1927 					idma_bare_write(base, j, 0);
1928 					break;
1929 				}
1930 		}
1931 
1932 	/*
1933 	 * Remaining targets -- from statically defined table
1934 	 */
1935 	for (i = 0; i < idma_wins_no; i++)
1936 		if (idma_wins[i].target > 0) {
1937 			br = (idma_wins[i].base & 0xffff0000) |
1938 			    (idma_wins[i].attr << 8) | idma_wins[i].target;
1939 			sz = ((idma_wins[i].size - 1) & 0xffff0000);
1940 
1941 			/* Set the first free IDMA window */
1942 			for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
1943 				if (idma_bare_read(base, j) == 0)
1944 					continue;
1945 
1946 				/* Configure window */
1947 				win_idma_br_write(base, j, br);
1948 				win_idma_sz_write(base, j, sz);
1949 				if (win_idma_can_remap(j) &&
1950 				    idma_wins[j].remap >= 0)
1951 					win_idma_har_write(base, j,
1952 					    idma_wins[j].remap);
1953 
1954 				/* Set protection RW on all channels */
1955 				idma_set_prot(base, j, 0x3);
1956 
1957 				/* Enable window */
1958 				idma_bare_write(base, j, 0);
1959 				break;
1960 			}
1961 		}
1962 }
1963 
1964 int
1965 decode_win_idma_valid(void)
1966 {
1967 	const struct decode_win *wintab;
1968 	int c, i, j, rv;
1969 	uint32_t b, e, s;
1970 
1971 	if (idma_wins_no > MV_WIN_IDMA_MAX) {
1972 		printf("IDMA windows: too many entries: %d\n", idma_wins_no);
1973 		return (0);
1974 	}
1975 	for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1976 		if (ddr_is_active(i))
1977 			c++;
1978 
1979 	if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
1980 		printf("IDMA windows: too many entries: %d, available: %d\n",
1981 		    idma_wins_no, MV_WIN_IDMA_MAX - c);
1982 		return (0);
1983 	}
1984 
1985 	wintab = idma_wins;
1986 	rv = 1;
1987 	for (i = 0; i < idma_wins_no; i++, wintab++) {
1988 		if (wintab->target == 0) {
1989 			printf("IDMA window#%d: DDR target window is not "
1990 			    "supposed to be reprogrammed!\n", i);
1991 			rv = 0;
1992 		}
1993 
1994 		if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1995 			printf("IDMA window#%d: not capable of remapping, but "
1996 			    "val 0x%08x defined\n", i, wintab->remap);
1997 			rv = 0;
1998 		}
1999 
2000 		s = wintab->size;
2001 		b = wintab->base;
2002 		e = b + s - 1;
2003 		if (s > (0xFFFFFFFF - b + 1)) {
2004 			/* XXX this boundary check should account for 64bit and
2005 			 * remapping.. */
2006 			printf("IDMA window#%d: no space for size 0x%08x at "
2007 			    "0x%08x\n", i, s, b);
2008 			rv = 0;
2009 			continue;
2010 		}
2011 
2012 		j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
2013 		if (j >= 0) {
2014 			printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
2015 			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
2016 			    idma_wins[j].base,
2017 			    idma_wins[j].base + idma_wins[j].size - 1);
2018 			rv = 0;
2019 		}
2020 	}
2021 
2022 	return (rv);
2023 }
2024 
2025 void
2026 decode_win_idma_dump(u_long base)
2027 {
2028 	int i;
2029 
2030 	if (pm_is_disabled(CPU_PM_CTRL_IDMA))
2031 		return;
2032 
2033 	for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
2034 		printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
2035 		    win_idma_br_read(base, i), win_idma_sz_read(base, i));
2036 
2037 		if (win_idma_can_remap(i))
2038 			printf(", ha 0x%08x", win_idma_har_read(base, i));
2039 
2040 		printf("\n");
2041 	}
2042 	for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
2043 		printf("IDMA channel#%d: ap 0x%08x\n", i,
2044 		    win_idma_cap_read(base, i));
2045 	printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read(base));
2046 }
2047 #else
2048 
2049 /* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
2050 int
2051 decode_win_idma_valid(void)
2052 {
2053 
2054 	return (1);
2055 }
2056 
2057 void
2058 decode_win_idma_setup(u_long base)
2059 {
2060 }
2061 
2062 void
2063 decode_win_idma_dump(u_long base)
2064 {
2065 }
2066 #endif
2067 
2068 /**************************************************************************
2069  * XOR windows routines
2070  **************************************************************************/
2071 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
2072 static int
2073 xor_ctrl_read(u_long base, int i, int c, int e)
2074 {
2075 	uint32_t v;
2076 	v = win_xor_ctrl_read(base, c, e);
2077 	v &= (1 << i);
2078 
2079 	return (v >> i);
2080 }
2081 
2082 static void
2083 xor_ctrl_write(u_long base, int i, int c, int e, int val)
2084 {
2085 	uint32_t v;
2086 
2087 	v = win_xor_ctrl_read(base, c, e);
2088 	v &= ~(1 << i);
2089 	v |= (val << i);
2090 	win_xor_ctrl_write(base, c, e, v);
2091 }
2092 
2093 /*
2094  * Set channel protection 'val' for window 'w' on channel 'c'
2095  */
2096 static void
2097 xor_chan_write(u_long base, int c, int e, int w, int val)
2098 {
2099 	uint32_t v;
2100 
2101 	v = win_xor_ctrl_read(base, c, e);
2102 	v &= ~(0x3 << (w * 2 + 16));
2103 	v |= (val << (w * 2 + 16));
2104 	win_xor_ctrl_write(base, c, e, v);
2105 }
2106 
2107 /*
2108  * Set protection 'val' on all channels for window 'w' on engine 'e'
2109  */
2110 static void
2111 xor_set_prot(u_long base, int w, int e, int val)
2112 {
2113 	int c;
2114 
2115 	for (c = 0; c < MV_XOR_CHAN_MAX; c++)
2116 		xor_chan_write(base, c, e, w, val);
2117 }
2118 
2119 static int
2120 win_xor_can_remap(int i)
2121 {
2122 
2123 	/* XOR decode windows 0-3 have remap capability */
2124 	if (i < 4)
2125 		return (1);
2126 
2127 	return (0);
2128 }
2129 
2130 static int
2131 xor_max_eng(void)
2132 {
2133 	uint32_t dev, rev;
2134 
2135 	soc_id(&dev, &rev);
2136 	switch (dev) {
2137 	case MV_DEV_88F6281:
2138 	case MV_DEV_88F6282:
2139 	case MV_DEV_MV78130:
2140 	case MV_DEV_MV78160:
2141 	case MV_DEV_MV78230:
2142 	case MV_DEV_MV78260:
2143 	case MV_DEV_MV78460:
2144 		return (2);
2145 	case MV_DEV_MV78100:
2146 	case MV_DEV_MV78100_Z0:
2147 		return (1);
2148 	default:
2149 		return (0);
2150 	}
2151 }
2152 
2153 static void
2154 xor_active_dram(u_long base, int c, int e, int *window)
2155 {
2156 	uint32_t br, sz;
2157 	int i, m, w;
2158 
2159 	/*
2160 	 * Set up access to all active DRAM banks
2161 	 */
2162 	m = xor_max_eng();
2163 	for (i = 0; i < m; i++)
2164 		if (ddr_is_active(i)) {
2165 			br = ddr_base(i) | (ddr_attr(i) << 8) |
2166 			    ddr_target(i);
2167 			sz = ((ddr_size(i) - 1) & 0xffff0000);
2168 
2169 			/* Place DDR entries in non-remapped windows */
2170 			for (w = 0; w < MV_WIN_XOR_MAX; w++)
2171 				if (win_xor_can_remap(w) != 1 &&
2172 				    (xor_ctrl_read(base, w, c, e) == 0) &&
2173 				    w > *window) {
2174 					/* Configure window */
2175 					win_xor_br_write(base, w, e, br);
2176 					win_xor_sz_write(base, w, e, sz);
2177 
2178 					/* Set protection RW on all channels */
2179 					xor_set_prot(base, w, e, 0x3);
2180 
2181 					/* Enable window */
2182 					xor_ctrl_write(base, w, c, e, 1);
2183 					(*window)++;
2184 					break;
2185 				}
2186 		}
2187 }
2188 
2189 void
2190 decode_win_xor_setup(u_long base)
2191 {
2192 	uint32_t br, sz;
2193 	int i, j, z, e = 1, m, window;
2194 
2195 	if (pm_is_disabled(CPU_PM_CTRL_XOR))
2196 		return;
2197 
2198 	/*
2199 	 * Disable and clear all XOR windows, revoke protection for all
2200 	 * channels
2201 	 */
2202 	m = xor_max_eng();
2203 	for (j = 0; j < m; j++, e--) {
2204 		/* Number of non-remaped windows */
2205 		window = MV_XOR_NON_REMAP - 1;
2206 
2207 		for (i = 0; i < MV_WIN_XOR_MAX; i++) {
2208 			win_xor_br_write(base, i, e, 0);
2209 			win_xor_sz_write(base, i, e, 0);
2210 		}
2211 
2212 		if (win_xor_can_remap(i) == 1)
2213 			win_xor_har_write(base, i, e, 0);
2214 
2215 		for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
2216 			win_xor_ctrl_write(base, i, e, 0);
2217 			xor_active_dram(base, i, e, &window);
2218 		}
2219 
2220 		/*
2221 		 * Remaining targets -- from a statically defined table
2222 		 */
2223 		for (i = 0; i < xor_wins_no; i++)
2224 			if (xor_wins[i].target > 0) {
2225 				br = (xor_wins[i].base & 0xffff0000) |
2226 				    (xor_wins[i].attr << 8) |
2227 				    xor_wins[i].target;
2228 				sz = ((xor_wins[i].size - 1) & 0xffff0000);
2229 
2230 				/* Set the first free XOR window */
2231 				for (z = 0; z < MV_WIN_XOR_MAX; z++) {
2232 					if (xor_ctrl_read(base, z, 0, e) &&
2233 					    xor_ctrl_read(base, z, 1, e))
2234 						continue;
2235 
2236 					/* Configure window */
2237 					win_xor_br_write(base, z, e, br);
2238 					win_xor_sz_write(base, z, e, sz);
2239 					if (win_xor_can_remap(z) &&
2240 					    xor_wins[z].remap >= 0)
2241 						win_xor_har_write(base, z, e,
2242 						    xor_wins[z].remap);
2243 
2244 					/* Set protection RW on all channels */
2245 					xor_set_prot(base, z, e, 0x3);
2246 
2247 					/* Enable window */
2248 					xor_ctrl_write(base, z, 0, e, 1);
2249 					xor_ctrl_write(base, z, 1, e, 1);
2250 					break;
2251 				}
2252 			}
2253 	}
2254 }
2255 
2256 int
2257 decode_win_xor_valid(void)
2258 {
2259 	const struct decode_win *wintab;
2260 	int c, i, j, rv;
2261 	uint32_t b, e, s;
2262 
2263 	if (xor_wins_no > MV_WIN_XOR_MAX) {
2264 		printf("XOR windows: too many entries: %d\n", xor_wins_no);
2265 		return (0);
2266 	}
2267 	for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
2268 		if (ddr_is_active(i))
2269 			c++;
2270 
2271 	if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
2272 		printf("XOR windows: too many entries: %d, available: %d\n",
2273 		    xor_wins_no, MV_WIN_IDMA_MAX - c);
2274 		return (0);
2275 	}
2276 
2277 	wintab = xor_wins;
2278 	rv = 1;
2279 	for (i = 0; i < xor_wins_no; i++, wintab++) {
2280 		if (wintab->target == 0) {
2281 			printf("XOR window#%d: DDR target window is not "
2282 			    "supposed to be reprogrammed!\n", i);
2283 			rv = 0;
2284 		}
2285 
2286 		if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
2287 			printf("XOR window#%d: not capable of remapping, but "
2288 			    "val 0x%08x defined\n", i, wintab->remap);
2289 			rv = 0;
2290 		}
2291 
2292 		s = wintab->size;
2293 		b = wintab->base;
2294 		e = b + s - 1;
2295 		if (s > (0xFFFFFFFF - b + 1)) {
2296 			/*
2297 			 * XXX this boundary check should account for 64bit
2298 			 * and remapping..
2299 			 */
2300 			printf("XOR window#%d: no space for size 0x%08x at "
2301 			    "0x%08x\n", i, s, b);
2302 			rv = 0;
2303 			continue;
2304 		}
2305 
2306 		j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
2307 		if (j >= 0) {
2308 			printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
2309 			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
2310 			    xor_wins[j].base,
2311 			    xor_wins[j].base + xor_wins[j].size - 1);
2312 			rv = 0;
2313 		}
2314 	}
2315 
2316 	return (rv);
2317 }
2318 
2319 void
2320 decode_win_xor_dump(u_long base)
2321 {
2322 	int i, j;
2323 	int e = 1;
2324 
2325 	if (pm_is_disabled(CPU_PM_CTRL_XOR))
2326 		return;
2327 
2328 	for (j = 0; j < xor_max_eng(); j++, e--) {
2329 		for (i = 0; i < MV_WIN_XOR_MAX; i++) {
2330 			printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
2331 			    win_xor_br_read(base, i, e), win_xor_sz_read(base, i, e));
2332 
2333 			if (win_xor_can_remap(i))
2334 				printf(", ha 0x%08x", win_xor_har_read(base, i, e));
2335 
2336 			printf("\n");
2337 		}
2338 		for (i = 0; i < MV_XOR_CHAN_MAX; i++)
2339 			printf("XOR control#%d: 0x%08x\n", i,
2340 			    win_xor_ctrl_read(base, i, e));
2341 	}
2342 }
2343 
2344 #else
2345 /* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
2346 static int
2347 decode_win_xor_valid(void)
2348 {
2349 
2350 	return (1);
2351 }
2352 
2353 static void
2354 decode_win_xor_setup(u_long base)
2355 {
2356 }
2357 
2358 static void
2359 decode_win_xor_dump(u_long base)
2360 {
2361 }
2362 #endif
2363 
2364 /**************************************************************************
2365  * SATA windows routines
2366  **************************************************************************/
2367 static void
2368 decode_win_sata_setup(u_long base)
2369 {
2370 	uint32_t cr, br;
2371 	int i, j;
2372 
2373 	if (pm_is_disabled(CPU_PM_CTRL_SATA))
2374 		return;
2375 
2376 	for (i = 0; i < MV_WIN_SATA_MAX; i++) {
2377 		win_sata_cr_write(base, i, 0);
2378 		win_sata_br_write(base, i, 0);
2379 	}
2380 
2381 	for (i = 0; i < MV_WIN_DDR_MAX; i++)
2382 		if (ddr_is_active(i)) {
2383 			cr = ((ddr_size(i) - 1) & 0xffff0000) |
2384 			    (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
2385 			br = ddr_base(i);
2386 
2387 			/* Use the first available SATA window */
2388 			for (j = 0; j < MV_WIN_SATA_MAX; j++) {
2389 				if ((win_sata_cr_read(base, j) & 1) != 0)
2390 					continue;
2391 
2392 				win_sata_br_write(base, j, br);
2393 				win_sata_cr_write(base, j, cr);
2394 				break;
2395 			}
2396 		}
2397 }
2398 
2399 /*
2400  * Configure AHCI decoding windows
2401  */
2402 static void
2403 decode_win_ahci_setup(u_long base)
2404 {
2405 	uint32_t br, cr, sz;
2406 	int i, j;
2407 
2408 	for (i = 0; i < MV_WIN_SATA_MAX_ARMADA38X; i++) {
2409 		win_sata_armada38x_cr_write(base, i, 0);
2410 		win_sata_armada38x_br_write(base, i, 0);
2411 		win_sata_armada38x_sz_write(base, i, 0);
2412 	}
2413 
2414 	for (i = 0; i < MV_WIN_DDR_MAX; i++) {
2415 		if (ddr_is_active(i)) {
2416 			cr = (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
2417 			    (ddr_target(i) << IO_WIN_TGT_SHIFT) |
2418 			    IO_WIN_ENA_MASK;
2419 			br = ddr_base(i);
2420 			sz = (ddr_size(i) - 1) &
2421 			    (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT);
2422 
2423 			/* Use first available SATA window */
2424 			for (j = 0; j < MV_WIN_SATA_MAX_ARMADA38X; j++) {
2425 				if (win_sata_armada38x_cr_read(base, j) & IO_WIN_ENA_MASK)
2426 					continue;
2427 
2428 				/* BASE is set to DRAM base (0x00000000) */
2429 				win_sata_armada38x_br_write(base, j, br);
2430 				/* CTRL targets DRAM ctrl with 0x0E or 0x0D */
2431 				win_sata_armada38x_cr_write(base, j, cr);
2432 				/* SIZE is set to 16MB - max value */
2433 				win_sata_armada38x_sz_write(base, j, sz);
2434 				break;
2435 			}
2436 		}
2437 	}
2438 }
2439 
2440 static void
2441 decode_win_ahci_dump(u_long base)
2442 {
2443 	int i;
2444 
2445 	for (i = 0; i < MV_WIN_SATA_MAX_ARMADA38X; i++)
2446 		printf("SATA window#%d: cr 0x%08x, br 0x%08x, sz 0x%08x\n", i,
2447 		    win_sata_armada38x_cr_read(base, i), win_sata_br_read(base, i),
2448 		    win_sata_armada38x_sz_read(base,i));
2449 }
2450 
2451 static int
2452 decode_win_sata_valid(void)
2453 {
2454 	uint32_t dev, rev;
2455 
2456 	soc_id(&dev, &rev);
2457 	if (dev == MV_DEV_88F5281)
2458 		return (1);
2459 
2460 	return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
2461 }
2462 
2463 static void
2464 decode_win_sdhci_setup(u_long base)
2465 {
2466 	uint32_t cr, br;
2467 	int i, j;
2468 
2469 	for (i = 0; i < MV_WIN_SDHCI_MAX; i++) {
2470 		win_sdhci_cr_write(base, i, 0);
2471 		win_sdhci_br_write(base, i, 0);
2472 	}
2473 
2474 	for (i = 0; i < MV_WIN_DDR_MAX; i++)
2475 		if (ddr_is_active(i)) {
2476 			br = ddr_base(i);
2477 			cr = (((ddr_size(i) - 1) &
2478 			    (IO_WIN_SIZE_MASK << IO_WIN_SIZE_SHIFT)) |
2479 			    (ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
2480 			    (ddr_target(i) << IO_WIN_TGT_SHIFT) |
2481 			    IO_WIN_ENA_MASK);
2482 
2483 			/* Use the first available SDHCI window */
2484 			for (j = 0; j < MV_WIN_SDHCI_MAX; j++) {
2485 				if (win_sdhci_cr_read(base, j) & IO_WIN_ENA_MASK)
2486 					continue;
2487 
2488 				win_sdhci_cr_write(base, j, cr);
2489 				win_sdhci_br_write(base, j, br);
2490 				break;
2491 			}
2492 		}
2493 }
2494 
2495 static void
2496 decode_win_sdhci_dump(u_long base)
2497 {
2498 	int i;
2499 
2500 	for (i = 0; i < MV_WIN_SDHCI_MAX; i++)
2501 		printf("SDHCI window#%d: c 0x%08x, b 0x%08x\n", i,
2502 		    win_sdhci_cr_read(base, i), win_sdhci_br_read(base, i));
2503 }
2504 
2505 static int
2506 decode_win_sdhci_valid(void)
2507 {
2508 
2509 	return (decode_win_can_cover_ddr(MV_WIN_SDHCI_MAX));
2510 }
2511 
2512 /**************************************************************************
2513  * FDT parsing routines.
2514  **************************************************************************/
2515 
2516 static int
2517 fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples,
2518     int *tuplesize)
2519 {
2520 	phandle_t node;
2521 	pcell_t addr_cells, par_addr_cells, size_cells;
2522 	int len, tuple_size, tuples_count;
2523 
2524 	node = OF_finddevice(nodename);
2525 	if (node == -1)
2526 		return (EINVAL);
2527 
2528 	if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
2529 		return (ENXIO);
2530 
2531 	par_addr_cells = fdt_parent_addr_cells(node);
2532 	if (par_addr_cells > 2)
2533 		return (ERANGE);
2534 
2535 	tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
2536 	    size_cells);
2537 
2538 	/* Note the OF_getprop_alloc() cannot be used at this early stage. */
2539 	len = OF_getprop(node, "ranges", buf, size);
2540 
2541 	/*
2542 	 * XXX this does not handle the empty 'ranges;' case, which is
2543 	 * legitimate and should be allowed.
2544 	 */
2545 	tuples_count = len / tuple_size;
2546 	if (tuples_count <= 0)
2547 		return (ERANGE);
2548 
2549 	if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2)
2550 		return (ERANGE);
2551 
2552 	*tuples = tuples_count;
2553 	*tuplesize = tuple_size;
2554 	return (0);
2555 }
2556 
2557 static int
2558 win_cpu_from_dt(void)
2559 {
2560 	pcell_t ranges[48];
2561 	phandle_t node;
2562 	int i, entry_size, err, t, tuple_size, tuples;
2563 	u_long sram_base, sram_size;
2564 
2565 	t = 0;
2566 	/* Retrieve 'ranges' property of '/localbus' node. */
2567 	if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges),
2568 	    &tuples, &tuple_size)) == 0) {
2569 		/*
2570 		 * Fill CPU decode windows table.
2571 		 */
2572 		bzero((void *)&cpu_win_tbl, sizeof(cpu_win_tbl));
2573 
2574 		entry_size = tuple_size / sizeof(pcell_t);
2575 		cpu_wins_no = tuples;
2576 
2577 		/* Check range */
2578 		if (tuples > nitems(cpu_win_tbl)) {
2579 			debugf("too many tuples to fit into cpu_win_tbl\n");
2580 			return (ENOMEM);
2581 		}
2582 
2583 		for (i = 0, t = 0; t < tuples; i += entry_size, t++) {
2584 			cpu_win_tbl[t].target = 1;
2585 			cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]);
2586 			cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]);
2587 			cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]);
2588 			cpu_win_tbl[t].remap = ~0;
2589 			debugf("target = 0x%0x attr = 0x%0x base = 0x%0x "
2590 			    "size = 0x%0x remap = 0x%0x\n",
2591 			    cpu_win_tbl[t].target,
2592 			    cpu_win_tbl[t].attr, cpu_win_tbl[t].base,
2593 			    cpu_win_tbl[t].size, cpu_win_tbl[t].remap);
2594 		}
2595 	}
2596 
2597 	/*
2598 	 * Retrieve CESA SRAM data.
2599 	 */
2600 	if ((node = OF_finddevice("sram")) != -1)
2601 		if (ofw_bus_node_is_compatible(node, "mrvl,cesa-sram"))
2602 			goto moveon;
2603 
2604 	if ((node = OF_finddevice("/")) == -1)
2605 		return (ENXIO);
2606 
2607 	if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
2608 		/* SRAM block is not always present. */
2609 		return (0);
2610 moveon:
2611 	sram_base = sram_size = 0;
2612 	if (fdt_regsize(node, &sram_base, &sram_size) != 0)
2613 		return (EINVAL);
2614 
2615 	/* Check range */
2616 	if (t >= nitems(cpu_win_tbl)) {
2617 		debugf("cannot fit CESA tuple into cpu_win_tbl\n");
2618 		return (ENOMEM);
2619 	}
2620 
2621 	cpu_win_tbl[t].target = soc_decode_win_spec->win_cesa_target;
2622 	if (soc_family == MV_SOC_ARMADA_38X)
2623 		cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(0);
2624 	else
2625 		cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(1);
2626 	cpu_win_tbl[t].base = sram_base;
2627 	cpu_win_tbl[t].size = sram_size;
2628 	cpu_win_tbl[t].remap = ~0;
2629 	cpu_wins_no++;
2630 	debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
2631 
2632 	/* Check if there is a second CESA node */
2633 	while ((node = OF_peer(node)) != 0) {
2634 		if (ofw_bus_node_is_compatible(node, "mrvl,cesa-sram")) {
2635 			if (fdt_regsize(node, &sram_base, &sram_size) != 0)
2636 				return (EINVAL);
2637 			break;
2638 		}
2639 	}
2640 
2641 	if (node == 0)
2642 		return (0);
2643 
2644 	t++;
2645 	if (t >= nitems(cpu_win_tbl)) {
2646 		debugf("cannot fit CESA tuple into cpu_win_tbl\n");
2647 		return (ENOMEM);
2648 	}
2649 
2650 	/* Configure window for CESA1 */
2651 	cpu_win_tbl[t].target = soc_decode_win_spec->win_cesa_target;
2652 	cpu_win_tbl[t].attr = soc_decode_win_spec->win_cesa_attr(1);
2653 	cpu_win_tbl[t].base = sram_base;
2654 	cpu_win_tbl[t].size = sram_size;
2655 	cpu_win_tbl[t].remap = ~0;
2656 	cpu_wins_no++;
2657 	debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
2658 
2659 	return (0);
2660 }
2661 
2662 static int
2663 fdt_win_process(phandle_t child)
2664 {
2665 	int i, ret;
2666 
2667 	for (i = 0; soc_nodes[i].compat != NULL; i++) {
2668 		/* Setup only for enabled devices */
2669 		if (ofw_bus_node_status_okay(child) == 0)
2670 			continue;
2671 
2672 		if (!ofw_bus_node_is_compatible(child, soc_nodes[i].compat))
2673 			continue;
2674 
2675 		ret = fdt_win_process_child(child, &soc_nodes[i], "reg");
2676 		if (ret != 0)
2677 			return (ret);
2678 	}
2679 
2680 	return (0);
2681 }
2682 
2683 static int
2684 fdt_win_process_child(phandle_t child, struct soc_node_spec *soc_node,
2685     const char* mimo_reg_source)
2686 {
2687 	int addr_cells, size_cells;
2688 	pcell_t reg[8];
2689 	u_long base;
2690 
2691 	if (fdt_addrsize_cells(OF_parent(child), &addr_cells,
2692 	    &size_cells))
2693 		return (ENXIO);
2694 
2695 	if ((sizeof(pcell_t) * (addr_cells + size_cells)) > sizeof(reg))
2696 		return (ENOMEM);
2697 	if (OF_getprop(child, mimo_reg_source, &reg, sizeof(reg)) <= 0)
2698 		return (EINVAL);
2699 
2700 	if (addr_cells <= 2)
2701 		base = fdt_data_get(&reg[0], addr_cells);
2702 	else
2703 		base = fdt_data_get(&reg[addr_cells - 2], 2);
2704 	fdt_data_get(&reg[addr_cells], size_cells);
2705 
2706 	if (soc_node->valid_handler != NULL)
2707 		if (!soc_node->valid_handler())
2708 			return (EINVAL);
2709 
2710 	base = (base & 0x000fffff) | fdt_immr_va;
2711 	if (soc_node->decode_handler != NULL)
2712 		soc_node->decode_handler(base);
2713 	else
2714 		return (ENXIO);
2715 
2716 	if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
2717 		soc_node->dump_handler(base);
2718 
2719 	return (0);
2720 }
2721 
2722 static int
2723 fdt_win_setup(void)
2724 {
2725 	phandle_t node, child, sb;
2726 	phandle_t child_pci;
2727 	int err;
2728 
2729 	sb = 0;
2730 	node = OF_finddevice("/");
2731 	if (node == -1)
2732 		panic("fdt_win_setup: no root node");
2733 
2734 	/* Allow for coherent transactions on the A38x MBUS */
2735 	if (ofw_bus_node_is_compatible(node, "marvell,armada380"))
2736 		platform_io_coherent = true;
2737 
2738 	/*
2739 	 * Traverse through all children of root and simple-bus nodes.
2740 	 * For each found device retrieve decode windows data (if applicable).
2741 	 */
2742 	child = OF_child(node);
2743 	while (child != 0) {
2744 		/* Lookup for callback and run */
2745 		err = fdt_win_process(child);
2746 		if (err != 0)
2747 			return (err);
2748 
2749 		/* Process Marvell Armada-XP/38x PCIe controllers */
2750 		if (ofw_bus_node_is_compatible(child, "marvell,armada-370-pcie")) {
2751 			child_pci = OF_child(child);
2752 			while (child_pci != 0) {
2753 				err = fdt_win_process_child(child_pci,
2754 				    &soc_nodes[SOC_NODE_PCIE_ENTRY_IDX],
2755 				    "assigned-addresses");
2756 				if (err != 0)
2757 					return (err);
2758 
2759 				child_pci = OF_peer(child_pci);
2760 			}
2761 		}
2762 
2763 		/*
2764 		 * Once done with root-level children let's move down to
2765 		 * simple-bus and its children.
2766 		 */
2767 		child = OF_peer(child);
2768 		if ((child == 0) && (node == OF_finddevice("/"))) {
2769 			sb = node = fdt_find_compatible(node, "simple-bus", 0);
2770 			if (node == 0)
2771 				return (ENXIO);
2772 			child = OF_child(node);
2773 		}
2774 		/*
2775 		 * Next, move one more level down to internal-regs node (if
2776 		 * it is present) and its children. This node also have
2777 		 * "simple-bus" compatible.
2778 		 */
2779 		if ((child == 0) && (node == sb)) {
2780 			node = fdt_find_compatible(node, "simple-bus", 0);
2781 			if (node == 0)
2782 				return (0);
2783 			child = OF_child(node);
2784 		}
2785 	}
2786 
2787 	return (0);
2788 }
2789 
2790 static void
2791 fdt_fixup_busfreq(phandle_t root)
2792 {
2793 	phandle_t sb;
2794 	pcell_t freq;
2795 
2796 	freq = cpu_to_fdt32(get_tclk());
2797 
2798 	/*
2799 	 * Fix bus speed in cpu node
2800 	 */
2801 	if ((sb = OF_finddevice("cpu")) != -1)
2802 		if (fdt_is_compatible_strict(sb, "ARM,88VS584"))
2803 			OF_setprop(sb, "bus-frequency", (void *)&freq,
2804 			    sizeof(freq));
2805 
2806 	/*
2807 	 * This fixup sets the simple-bus bus-frequency property.
2808 	 */
2809 	if ((sb = fdt_find_compatible(root, "simple-bus", 1)) != 0)
2810 		OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
2811 }
2812 
2813 static void
2814 fdt_fixup_ranges(phandle_t root)
2815 {
2816 	phandle_t node;
2817 	pcell_t par_addr_cells, addr_cells, size_cells;
2818 	pcell_t ranges[3], reg[2], *rangesptr;
2819 	int len, tuple_size, tuples_count;
2820 	uint32_t base;
2821 
2822 	/* Fix-up SoC ranges according to real fdt_immr_pa */
2823 	if ((node = fdt_find_compatible(root, "simple-bus", 1)) != 0) {
2824 		if (fdt_addrsize_cells(node, &addr_cells, &size_cells) == 0 &&
2825 		    ((par_addr_cells = fdt_parent_addr_cells(node)) <= 2)) {
2826 			tuple_size = sizeof(pcell_t) * (par_addr_cells +
2827 			   addr_cells + size_cells);
2828 			len = OF_getprop(node, "ranges", ranges,
2829 			    sizeof(ranges));
2830 			tuples_count = len / tuple_size;
2831 			/* Unexpected settings are not supported */
2832 			if (tuples_count != 1)
2833 				goto fixup_failed;
2834 
2835 			rangesptr = &ranges[0];
2836 			rangesptr += par_addr_cells;
2837 			base = fdt_data_get((void *)rangesptr, addr_cells);
2838 			*rangesptr = cpu_to_fdt32(fdt_immr_pa);
2839 			if (OF_setprop(node, "ranges", (void *)&ranges[0],
2840 			    sizeof(ranges)) < 0)
2841 				goto fixup_failed;
2842 		}
2843 	}
2844 
2845 	/* Fix-up PCIe reg according to real PCIe registers' PA */
2846 	if ((node = fdt_find_compatible(root, "mrvl,pcie", 1)) != 0) {
2847 		if (fdt_addrsize_cells(OF_parent(node), &par_addr_cells,
2848 		    &size_cells) == 0) {
2849 			tuple_size = sizeof(pcell_t) * (par_addr_cells +
2850 			    size_cells);
2851 			len = OF_getprop(node, "reg", reg, sizeof(reg));
2852 			tuples_count = len / tuple_size;
2853 			/* Unexpected settings are not supported */
2854 			if (tuples_count != 1)
2855 				goto fixup_failed;
2856 
2857 			base = fdt_data_get((void *)&reg[0], par_addr_cells);
2858 			base &= ~0xFF000000;
2859 			base |= fdt_immr_pa;
2860 			reg[0] = cpu_to_fdt32(base);
2861 			if (OF_setprop(node, "reg", (void *)&reg[0],
2862 			    sizeof(reg)) < 0)
2863 				goto fixup_failed;
2864 		}
2865 	}
2866 	/* Fix-up succeeded. May return and continue */
2867 	return;
2868 
2869 fixup_failed:
2870 	while (1) {
2871 		/*
2872 		 * In case of any error while fixing ranges just hang.
2873 		 *	1. No message can be displayed yet since console
2874 		 *	   is not initialized.
2875 		 *	2. Going further will cause failure on bus_space_map()
2876 		 *	   relying on the wrong ranges or data abort when
2877 		 *	   accessing PCIe registers.
2878 		 */
2879 	}
2880 }
2881 
2882 struct fdt_fixup_entry fdt_fixup_table[] = {
2883 	{ "mrvl,DB-88F6281", &fdt_fixup_busfreq },
2884 	{ "mrvl,DB-78460", &fdt_fixup_busfreq },
2885 	{ "mrvl,DB-78460", &fdt_fixup_ranges },
2886 	{ NULL, NULL }
2887 };
2888 
2889 uint32_t
2890 get_tclk(void)
2891 {
2892 
2893 	if (soc_decode_win_spec->get_tclk != NULL)
2894 		return soc_decode_win_spec->get_tclk();
2895 	else
2896 		return -1;
2897 }
2898 
2899 uint32_t
2900 get_cpu_freq(void)
2901 {
2902 
2903 	if (soc_decode_win_spec->get_cpu_freq != NULL)
2904 		return soc_decode_win_spec->get_cpu_freq();
2905 	else
2906 		return -1;
2907 }
2908