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