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