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