1/*-
2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
3 * All rights reserved.
4 *
5 * Developed by Semihalf.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of MARVELL nor the names of contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD$");
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/bus.h>
38#include <sys/kernel.h>
39
40#include <dev/fdt/fdt_common.h>
41#include <dev/ofw/openfirm.h>
42
43#include <machine/bus.h>
44#include <machine/fdt.h>
45
46#include <arm/mv/mvreg.h>
47#include <arm/mv/mvvar.h>
48#include <arm/mv/mvwin.h>
49
50#define MAX_CPU_WIN	5
51
52#define DEBUG
53#undef DEBUG
54
55#ifdef DEBUG
56#define debugf(fmt, args...) do { printf("%s(): ", __func__);	\
57    printf(fmt,##args); } while (0)
58#else
59#define debugf(fmt, args...)
60#endif
61
62#ifdef DEBUG
63#define MV_DUMP_WIN	1
64#else
65#define MV_DUMP_WIN	0
66#endif
67
68static int win_eth_can_remap(int i);
69
70static int decode_win_cpu_valid(void);
71static int decode_win_usb_valid(void);
72static int decode_win_eth_valid(void);
73static int decode_win_pcie_valid(void);
74static int decode_win_sata_valid(void);
75static int decode_win_cesa_valid(void);
76static int decode_win_idma_valid(void);
77static int decode_win_xor_valid(void);
78
79static void decode_win_cpu_setup(void);
80static void decode_win_usb_setup(u_long);
81static void decode_win_eth_setup(u_long);
82static void decode_win_pcie_setup(u_long);
83static void decode_win_sata_setup(u_long);
84static void decode_win_cesa_setup(u_long);
85static void decode_win_idma_setup(u_long);
86static void decode_win_xor_setup(u_long);
87
88static void decode_win_cesa_dump(u_long);
89static void decode_win_usb_dump(u_long);
90static void decode_win_eth_dump(u_long base);
91static void decode_win_idma_dump(u_long base);
92static void decode_win_xor_dump(u_long base);
93
94static int fdt_get_ranges(const char *, void *, int, int *, int *);
95
96static int win_cpu_from_dt(void);
97static int fdt_win_setup(void);
98
99static uint32_t used_cpu_wins;
100static uint32_t dev_mask = 0;
101static int cpu_wins_no = 0;
102static int eth_port = 0;
103static int usb_port = 0;
104
105static struct decode_win cpu_win_tbl[MAX_CPU_WIN];
106
107static const struct decode_win *cpu_wins = cpu_win_tbl;
108
109typedef void (*decode_win_setup_t)(u_long);
110typedef void (*dump_win_t)(u_long);
111
112struct soc_node_spec {
113	const char		*compat;
114	decode_win_setup_t	decode_handler;
115	dump_win_t		dump_handler;
116};
117
118static struct soc_node_spec soc_nodes[] = {
119	{ "mrvl,cesa", &decode_win_cesa_setup, &decode_win_cesa_dump },
120	{ "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump },
121	{ "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump },
122	{ "mrvl,sata", &decode_win_sata_setup, NULL },
123	{ "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump },
124	{ "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump },
125	{ "mrvl,pcie", &decode_win_pcie_setup, NULL },
126	{ NULL, NULL, NULL },
127};
128
129struct fdt_pm_mask_entry fdt_pm_mask_table[] = {
130	{ "mrvl,ge",		CPU_PM_CTRL_GE(0) },
131	{ "mrvl,ge",		CPU_PM_CTRL_GE(1) },
132	{ "mrvl,usb-ehci",	CPU_PM_CTRL_USB(0) },
133	{ "mrvl,usb-ehci",	CPU_PM_CTRL_USB(1) },
134	{ "mrvl,usb-ehci",	CPU_PM_CTRL_USB(2) },
135	{ "mrvl,cesa",		CPU_PM_CTRL_CRYPTO },
136	{ "mrvl,xor",		CPU_PM_CTRL_XOR },
137	{ "mrvl,sata",		CPU_PM_CTRL_SATA },
138
139	{ NULL, 0 }
140};
141
142static __inline int
143pm_is_disabled(uint32_t mask)
144{
145
146	return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
147}
148
149/*
150 * Disable device using power management register.
151 * 1 - Device Power On
152 * 0 - Device Power Off
153 * Mask can be set in loader.
154 * EXAMPLE:
155 * loader> set hw.pm-disable-mask=0x2
156 *
157 * Common mask:
158 * |-------------------------------|
159 * | Device | Kirkwood | Discovery |
160 * |-------------------------------|
161 * | USB0   | 0x00008  | 0x020000  |
162 * |-------------------------------|
163 * | USB1   |     -    | 0x040000  |
164 * |-------------------------------|
165 * | USB2   |     -    | 0x080000  |
166 * |-------------------------------|
167 * | GE0    | 0x00001  | 0x000002  |
168 * |-------------------------------|
169 * | GE1    |     -    | 0x000004  |
170 * |-------------------------------|
171 * | IDMA   |     -    | 0x100000  |
172 * |-------------------------------|
173 * | XOR    | 0x10000  | 0x200000  |
174 * |-------------------------------|
175 * | CESA   | 0x20000  | 0x400000  |
176 * |-------------------------------|
177 * | SATA   | 0x04000  | 0x004000  |
178 * --------------------------------|
179 * This feature can be used only on Kirkwood and Discovery
180 * machines.
181 */
182static __inline void
183pm_disable_device(int mask)
184{
185#ifdef DIAGNOSTIC
186	uint32_t reg;
187
188	reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
189	printf("Power Management Register: 0%x\n", reg);
190
191	reg &= ~mask;
192	soc_power_ctrl_set(reg);
193	printf("Device %x is disabled\n", mask);
194
195	reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
196	printf("Power Management Register: 0%x\n", reg);
197#endif
198}
199
200int
201fdt_pm(phandle_t node)
202{
203	uint32_t cpu_pm_ctrl;
204	int i, ena, compat;
205
206	ena = 1;
207	cpu_pm_ctrl = read_cpu_ctrl(CPU_PM_CTRL);
208	for (i = 0; fdt_pm_mask_table[i].compat != NULL; i++) {
209		if (dev_mask & (1 << i))
210			continue;
211
212		compat = fdt_is_compatible(node, fdt_pm_mask_table[i].compat);
213
214		if (compat && (~cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
215			dev_mask |= (1 << i);
216			ena = 0;
217			break;
218		} else if (compat) {
219			dev_mask |= (1 << i);
220			break;
221		}
222	}
223
224	return (ena);
225}
226
227uint32_t
228read_cpu_ctrl(uint32_t reg)
229{
230
231	return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg));
232}
233
234void
235write_cpu_ctrl(uint32_t reg, uint32_t val)
236{
237
238	bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg, val);
239}
240
241void
242cpu_reset(void)
243{
244
245	write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
246	write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
247	while (1);
248}
249
250uint32_t
251cpu_extra_feat(void)
252{
253	uint32_t dev, rev;
254	uint32_t ef = 0;
255
256	soc_id(&dev, &rev);
257	if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100_Z0 ||
258	    dev == MV_DEV_MV78100)
259		__asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
260	else if (dev == MV_DEV_88F5182 || dev == MV_DEV_88F5281)
261		__asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
262	else if (bootverbose)
263		printf("This ARM Core does not support any extra features\n");
264
265	return (ef);
266}
267
268/*
269 * Get the power status of device. This feature is only supported on
270 * Kirkwood and Discovery SoCs.
271 */
272uint32_t
273soc_power_ctrl_get(uint32_t mask)
274{
275
276#ifndef SOC_MV_ORION
277	if (mask != CPU_PM_CTRL_NONE)
278		mask &= read_cpu_ctrl(CPU_PM_CTRL);
279
280	return (mask);
281#else
282	return (mask);
283#endif
284}
285
286/*
287 * Set the power status of device. This feature is only supported on
288 * Kirkwood and Discovery SoCs.
289 */
290void
291soc_power_ctrl_set(uint32_t mask)
292{
293
294#ifndef SOC_MV_ORION
295	if (mask != CPU_PM_CTRL_NONE)
296		write_cpu_ctrl(CPU_PM_CTRL, mask);
297#endif
298}
299
300void
301soc_id(uint32_t *dev, uint32_t *rev)
302{
303
304	/*
305	 * Notice: system identifiers are available in the registers range of
306	 * PCIE controller, so using this function is only allowed (and
307	 * possible) after the internal registers range has been mapped in via
308	 * pmap_devmap_bootstrap().
309	 */
310	*dev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 0) >> 16;
311	*rev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 8) & 0xff;
312}
313
314static void
315soc_identify(void)
316{
317	uint32_t d, r;
318	const char *dev;
319	const char *rev;
320
321	soc_id(&d, &r);
322
323	printf("SOC: ");
324	if (bootverbose)
325		printf("(0x%4x:0x%02x) ", d, r);
326
327	rev = "";
328	switch (d) {
329	case MV_DEV_88F5181:
330		dev = "Marvell 88F5181";
331		if (r == 3)
332			rev = "B1";
333		break;
334	case MV_DEV_88F5182:
335		dev = "Marvell 88F5182";
336		if (r == 2)
337			rev = "A2";
338		break;
339	case MV_DEV_88F5281:
340		dev = "Marvell 88F5281";
341		if (r == 4)
342			rev = "D0";
343		else if (r == 5)
344			rev = "D1";
345		else if (r == 6)
346			rev = "D2";
347		break;
348	case MV_DEV_88F6281:
349		dev = "Marvell 88F6281";
350		if (r == 0)
351			rev = "Z0";
352		else if (r == 2)
353			rev = "A0";
354		else if (r == 3)
355			rev = "A1";
356		break;
357	case MV_DEV_MV78100_Z0:
358		dev = "Marvell MV78100 Z0";
359		break;
360	case MV_DEV_MV78100:
361		dev = "Marvell MV78100";
362		break;
363	default:
364		dev = "UNKNOWN";
365		break;
366	}
367
368	printf("%s", dev);
369	if (*rev != '\0')
370		printf(" rev %s", rev);
371	printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
372
373	/* TODO add info on currently set endianess */
374}
375
376static void
377platform_identify(void *dummy)
378{
379
380	soc_identify();
381
382	/*
383	 * XXX Board identification e.g. read out from FPGA or similar should
384	 * go here
385	 */
386}
387SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify,
388    NULL);
389
390int
391soc_decode_win(void)
392{
393	uint32_t dev, rev;
394	int mask, err;
395
396	mask = 0;
397	TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
398
399	if (mask != 0)
400		pm_disable_device(mask);
401
402	/* Retrieve data about physical addresses from device tree. */
403	if ((err = win_cpu_from_dt()) != 0)
404		return (err);
405
406	/* Retrieve our ID: some windows facilities vary between SoC models */
407	soc_id(&dev, &rev);
408
409	if (!decode_win_cpu_valid() || !decode_win_usb_valid() ||
410	    !decode_win_eth_valid() || !decode_win_idma_valid() ||
411	    !decode_win_pcie_valid() || !decode_win_sata_valid() ||
412	    !decode_win_cesa_valid() || !decode_win_xor_valid())
413		return (EINVAL);
414
415	decode_win_cpu_setup();
416	if (MV_DUMP_WIN)
417		soc_dump_decode_win();
418
419	eth_port = 0;
420	usb_port = 0;
421	if ((err = fdt_win_setup()) != 0)
422		return (err);
423
424	return (0);
425}
426
427/**************************************************************************
428 * Decode windows registers accessors
429 **************************************************************************/
430WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
431WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
432WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
433WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
434WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
435WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
436WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
437WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
438
439WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
440WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
441
442WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
443WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
444WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
445WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE)
446
447WIN_REG_BASE_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL)
448WIN_REG_BASE_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE)
449WIN_REG_BASE_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL)
450WIN_REG_BASE_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE)
451
452WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
453WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
454WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
455WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
456WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
457WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
458
459WIN_REG_BASE_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE)
460WIN_REG_BASE_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE)
461WIN_REG_BASE_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP)
462WIN_REG_BASE_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL)
463WIN_REG_BASE_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE)
464WIN_REG_BASE_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE)
465WIN_REG_BASE_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP)
466WIN_REG_BASE_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL)
467
468WIN_REG_BASE_RD(win_eth, bare, 0x290)
469WIN_REG_BASE_RD(win_eth, epap, 0x294)
470WIN_REG_BASE_WR(win_eth, bare, 0x290)
471WIN_REG_BASE_WR(win_eth, epap, 0x294)
472
473WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
474WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
475WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
476WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
477WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
478WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
479WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
480
481WIN_REG_BASE_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE)
482WIN_REG_BASE_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE)
483WIN_REG_BASE_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP)
484WIN_REG_BASE_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP)
485WIN_REG_BASE_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE)
486WIN_REG_BASE_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE)
487WIN_REG_BASE_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP)
488WIN_REG_BASE_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP)
489WIN_REG_BASE_RD(win_idma, bare, 0xa80)
490WIN_REG_BASE_WR(win_idma, bare, 0xa80)
491
492WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL);
493WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE);
494WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL);
495WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE);
496
497/**************************************************************************
498 * Decode windows helper routines
499 **************************************************************************/
500void
501soc_dump_decode_win(void)
502{
503	uint32_t dev, rev;
504	int i;
505
506	soc_id(&dev, &rev);
507
508	for (i = 0; i < MV_WIN_CPU_MAX; i++) {
509		printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
510		    win_cpu_cr_read(i),
511		    win_cpu_br_read(i));
512
513		if (win_cpu_can_remap(i))
514			printf(", rl 0x%08x, rh 0x%08x",
515			    win_cpu_remap_l_read(i),
516			    win_cpu_remap_h_read(i));
517
518		printf("\n");
519	}
520	printf("Internal regs base: 0x%08x\n",
521	    bus_space_read_4(fdtbus_bs_tag, MV_INTREGS_BASE, 0));
522
523	for (i = 0; i < MV_WIN_DDR_MAX; i++)
524		printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
525		    ddr_br_read(i), ddr_sz_read(i));
526}
527
528/**************************************************************************
529 * CPU windows routines
530 **************************************************************************/
531int
532win_cpu_can_remap(int i)
533{
534	uint32_t dev, rev;
535
536	soc_id(&dev, &rev);
537
538	/* Depending on the SoC certain windows have remap capability */
539	if ((dev == MV_DEV_88F5182 && i < 2) ||
540	    (dev == MV_DEV_88F5281 && i < 4) ||
541	    (dev == MV_DEV_88F6281 && i < 4) ||
542	    (dev == MV_DEV_MV78100 && i < 8) ||
543	    (dev == MV_DEV_MV78100_Z0 && i < 8))
544		return (1);
545
546	return (0);
547}
548
549/* XXX This should check for overlapping remap fields too.. */
550int
551decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
552{
553	const struct decode_win *tab;
554	int i;
555
556	tab = wintab;
557
558	for (i = 0; i < win_no; i++, tab++) {
559		if (i == win)
560			/* Skip self */
561			continue;
562
563		if ((tab->base + tab->size - 1) < (wintab + win)->base)
564			continue;
565
566		else if (((wintab + win)->base + (wintab + win)->size - 1) <
567		    tab->base)
568			continue;
569		else
570			return (i);
571	}
572
573	return (-1);
574}
575
576static int
577decode_win_cpu_valid(void)
578{
579	int i, j, rv;
580	uint32_t b, e, s;
581
582	if (cpu_wins_no > MV_WIN_CPU_MAX) {
583		printf("CPU windows: too many entries: %d\n", cpu_wins_no);
584		return (0);
585	}
586
587	rv = 1;
588	for (i = 0; i < cpu_wins_no; i++) {
589
590		if (cpu_wins[i].target == 0) {
591			printf("CPU window#%d: DDR target window is not "
592			    "supposed to be reprogrammed!\n", i);
593			rv = 0;
594		}
595
596		if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) {
597			printf("CPU window#%d: not capable of remapping, but "
598			    "val 0x%08x defined\n", i, cpu_wins[i].remap);
599			rv = 0;
600		}
601
602		s = cpu_wins[i].size;
603		b = cpu_wins[i].base;
604		e = b + s - 1;
605		if (s > (0xFFFFFFFF - b + 1)) {
606			/*
607			 * XXX this boundary check should account for 64bit
608			 * and remapping..
609			 */
610			printf("CPU window#%d: no space for size 0x%08x at "
611			    "0x%08x\n", i, s, b);
612			rv = 0;
613			continue;
614		}
615
616		j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
617		if (j >= 0) {
618			printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
619			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
620			    cpu_wins[j].base,
621			    cpu_wins[j].base + cpu_wins[j].size - 1);
622			rv = 0;
623		}
624	}
625
626	return (rv);
627}
628
629int
630decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
631    int remap)
632{
633	uint32_t br, cr;
634	int win;
635
636	if (used_cpu_wins >= MV_WIN_CPU_MAX)
637		return (0);
638
639	win = used_cpu_wins++;
640
641	br = base & 0xffff0000;
642	win_cpu_br_write(win, br);
643
644	if (win_cpu_can_remap(win)) {
645		if (remap >= 0) {
646			win_cpu_remap_l_write(win, remap & 0xffff0000);
647			win_cpu_remap_h_write(win, 0);
648		} else {
649			/*
650			 * Remap function is not used for a given window
651			 * (capable of remapping) - set remap field with the
652			 * same value as base.
653			 */
654			win_cpu_remap_l_write(win, base & 0xffff0000);
655			win_cpu_remap_h_write(win, 0);
656		}
657	}
658
659	cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
660	win_cpu_cr_write(win, cr);
661
662	return (0);
663}
664
665static void
666decode_win_cpu_setup(void)
667{
668	int i;
669
670	used_cpu_wins = 0;
671
672	/* Disable all CPU windows */
673	for (i = 0; i < MV_WIN_CPU_MAX; i++) {
674		win_cpu_cr_write(i, 0);
675		win_cpu_br_write(i, 0);
676		if (win_cpu_can_remap(i)) {
677			win_cpu_remap_l_write(i, 0);
678			win_cpu_remap_h_write(i, 0);
679		}
680	}
681
682	for (i = 0; i < cpu_wins_no; i++)
683		if (cpu_wins[i].target > 0)
684			decode_win_cpu_set(cpu_wins[i].target,
685			    cpu_wins[i].attr, cpu_wins[i].base,
686			    cpu_wins[i].size, cpu_wins[i].remap);
687
688}
689
690/*
691 * Check if we're able to cover all active DDR banks.
692 */
693static int
694decode_win_can_cover_ddr(int max)
695{
696	int i, c;
697
698	c = 0;
699	for (i = 0; i < MV_WIN_DDR_MAX; i++)
700		if (ddr_is_active(i))
701			c++;
702
703	if (c > max) {
704		printf("Unable to cover all active DDR banks: "
705		    "%d, available windows: %d\n", c, max);
706		return (0);
707	}
708
709	return (1);
710}
711
712/**************************************************************************
713 * DDR windows routines
714 **************************************************************************/
715int
716ddr_is_active(int i)
717{
718
719	if (ddr_sz_read(i) & 0x1)
720		return (1);
721
722	return (0);
723}
724
725uint32_t
726ddr_base(int i)
727{
728
729	return (ddr_br_read(i) & 0xff000000);
730}
731
732uint32_t
733ddr_size(int i)
734{
735
736	return ((ddr_sz_read(i) | 0x00ffffff) + 1);
737}
738
739uint32_t
740ddr_attr(int i)
741{
742
743	return (i == 0 ? 0xe :
744	    (i == 1 ? 0xd :
745	    (i == 2 ? 0xb :
746	    (i == 3 ? 0x7 : 0xff))));
747}
748
749uint32_t
750ddr_target(int i)
751{
752
753	/* Mbus unit ID is 0x0 for DDR SDRAM controller */
754	return (0);
755}
756
757/**************************************************************************
758 * USB windows routines
759 **************************************************************************/
760static int
761decode_win_usb_valid(void)
762{
763
764	return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
765}
766
767static void
768decode_win_usb_dump(u_long base)
769{
770	int i;
771
772	if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port - 1)))
773		return;
774
775	for (i = 0; i < MV_WIN_USB_MAX; i++)
776		printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
777		    win_usb_cr_read(base, i), win_usb_br_read(base, i));
778}
779
780/*
781 * Set USB decode windows.
782 */
783static void
784decode_win_usb_setup(u_long base)
785{
786	uint32_t br, cr;
787	int i, j;
788
789
790	if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port)))
791		return;
792
793	usb_port++;
794
795	for (i = 0; i < MV_WIN_USB_MAX; i++) {
796		win_usb_cr_write(base, i, 0);
797		win_usb_br_write(base, i, 0);
798	}
799
800	/* Only access to active DRAM banks is required */
801	for (i = 0; i < MV_WIN_DDR_MAX; i++) {
802		if (ddr_is_active(i)) {
803			br = ddr_base(i);
804			/*
805			 * XXX for 6281 we should handle Mbus write
806			 * burst limit field in the ctrl reg
807			 */
808			cr = (((ddr_size(i) - 1) & 0xffff0000) |
809			    (ddr_attr(i) << 8) |
810			    (ddr_target(i) << 4) | 1);
811
812			/* Set the first free USB window */
813			for (j = 0; j < MV_WIN_USB_MAX; j++) {
814				if (win_usb_cr_read(base, j) & 0x1)
815					continue;
816
817				win_usb_br_write(base, j, br);
818				win_usb_cr_write(base, j, cr);
819				break;
820			}
821		}
822	}
823}
824
825/**************************************************************************
826 * ETH windows routines
827 **************************************************************************/
828
829static int
830win_eth_can_remap(int i)
831{
832
833	/* ETH encode windows 0-3 have remap capability */
834	if (i < 4)
835		return (1);
836
837	return (0);
838}
839
840static int
841eth_bare_read(uint32_t base, int i)
842{
843	uint32_t v;
844
845	v = win_eth_bare_read(base);
846	v &= (1 << i);
847
848	return (v >> i);
849}
850
851static void
852eth_bare_write(uint32_t base, int i, int val)
853{
854	uint32_t v;
855
856	v = win_eth_bare_read(base);
857	v &= ~(1 << i);
858	v |= (val << i);
859	win_eth_bare_write(base, v);
860}
861
862static void
863eth_epap_write(uint32_t base, int i, int val)
864{
865	uint32_t v;
866
867	v = win_eth_epap_read(base);
868	v &= ~(0x3 << (i * 2));
869	v |= (val << (i * 2));
870	win_eth_epap_write(base, v);
871}
872
873static void
874decode_win_eth_dump(u_long base)
875{
876	int i;
877
878	if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port - 1)))
879		return;
880
881	for (i = 0; i < MV_WIN_ETH_MAX; i++) {
882		printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
883		    win_eth_br_read(base, i),
884		    win_eth_sz_read(base, i));
885
886		if (win_eth_can_remap(i))
887			printf(", ha 0x%08x",
888			    win_eth_har_read(base, i));
889
890		printf("\n");
891	}
892	printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
893	    win_eth_bare_read(base),
894	    win_eth_epap_read(base));
895}
896
897static void
898decode_win_eth_setup(u_long base)
899{
900	uint32_t br, sz;
901	int i, j;
902
903	if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port)))
904		return;
905
906	eth_port++;
907
908	/* Disable, clear and revoke protection for all ETH windows */
909	for (i = 0; i < MV_WIN_ETH_MAX; i++) {
910
911		eth_bare_write(base, i, 1);
912		eth_epap_write(base, i, 0);
913		win_eth_br_write(base, i, 0);
914		win_eth_sz_write(base, i, 0);
915		if (win_eth_can_remap(i))
916			win_eth_har_write(base, i, 0);
917	}
918
919	/* Only access to active DRAM banks is required */
920	for (i = 0; i < MV_WIN_DDR_MAX; i++)
921		if (ddr_is_active(i)) {
922
923			br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
924			sz = ((ddr_size(i) - 1) & 0xffff0000);
925
926			/* Set the first free ETH window */
927			for (j = 0; j < MV_WIN_ETH_MAX; j++) {
928				if (eth_bare_read(base, j) == 0)
929					continue;
930
931				win_eth_br_write(base, j, br);
932				win_eth_sz_write(base, j, sz);
933
934				/* XXX remapping ETH windows not supported */
935
936				/* Set protection RW */
937				eth_epap_write(base, j, 0x3);
938
939				/* Enable window */
940				eth_bare_write(base, j, 0);
941				break;
942			}
943		}
944}
945
946static int
947decode_win_eth_valid(void)
948{
949
950	return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
951}
952
953/**************************************************************************
954 * PCIE windows routines
955 **************************************************************************/
956
957static void
958decode_win_pcie_setup(u_long base)
959{
960	uint32_t size = 0;
961	uint32_t cr, br;
962	int i, j;
963
964	for (i = 0; i < MV_PCIE_BAR_MAX; i++)
965		pcie_bar_write(base, i, 0);
966
967	for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
968		win_pcie_cr_write(base, i, 0);
969		win_pcie_br_write(base, i, 0);
970		win_pcie_remap_write(base, i, 0);
971	}
972
973	for (i = 0; i < MV_WIN_DDR_MAX; i++) {
974		if (ddr_is_active(i)) {
975			/* Map DDR to BAR 1 */
976			cr = (ddr_size(i) - 1) & 0xffff0000;
977			size += ddr_size(i) & 0xffff0000;
978			cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
979			br = ddr_base(i);
980
981			/* Use the first available PCIE window */
982			for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
983				if (win_pcie_cr_read(base, j) != 0)
984					continue;
985
986				win_pcie_br_write(base, j, br);
987				win_pcie_cr_write(base, j, cr);
988				break;
989			}
990		}
991	}
992
993	/*
994	 * Upper 16 bits in BAR register is interpreted as BAR size
995	 * (in 64 kB units) plus 64kB, so substract 0x10000
996	 * form value passed to register to get correct value.
997	 */
998	size -= 0x10000;
999	pcie_bar_write(base, 0, size | 1);
1000}
1001
1002static int
1003decode_win_pcie_valid(void)
1004{
1005
1006	return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
1007}
1008
1009/**************************************************************************
1010 * IDMA windows routines
1011 **************************************************************************/
1012#if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
1013static int
1014idma_bare_read(u_long base, int i)
1015{
1016	uint32_t v;
1017
1018	v = win_idma_bare_read(base);
1019	v &= (1 << i);
1020
1021	return (v >> i);
1022}
1023
1024static void
1025idma_bare_write(u_long base, int i, int val)
1026{
1027	uint32_t v;
1028
1029	v = win_idma_bare_read(base);
1030	v &= ~(1 << i);
1031	v |= (val << i);
1032	win_idma_bare_write(base, v);
1033}
1034
1035/*
1036 * Sets channel protection 'val' for window 'w' on channel 'c'
1037 */
1038static void
1039idma_cap_write(u_long base, int c, int w, int val)
1040{
1041	uint32_t v;
1042
1043	v = win_idma_cap_read(base, c);
1044	v &= ~(0x3 << (w * 2));
1045	v |= (val << (w * 2));
1046	win_idma_cap_write(base, c, v);
1047}
1048
1049/*
1050 * Set protection 'val' on all channels for window 'w'
1051 */
1052static void
1053idma_set_prot(u_long base, int w, int val)
1054{
1055	int c;
1056
1057	for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
1058		idma_cap_write(base, c, w, val);
1059}
1060
1061static int
1062win_idma_can_remap(int i)
1063{
1064
1065	/* IDMA decode windows 0-3 have remap capability */
1066	if (i < 4)
1067		return (1);
1068
1069	return (0);
1070}
1071
1072void
1073decode_win_idma_setup(u_long base)
1074{
1075	uint32_t br, sz;
1076	int i, j;
1077
1078	if (pm_is_disabled(CPU_PM_CTRL_IDMA))
1079		return;
1080	/*
1081	 * Disable and clear all IDMA windows, revoke protection for all channels
1082	 */
1083	for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
1084
1085		idma_bare_write(base, i, 1);
1086		win_idma_br_write(base, i, 0);
1087		win_idma_sz_write(base, i, 0);
1088		if (win_idma_can_remap(i) == 1)
1089			win_idma_har_write(base, i, 0);
1090	}
1091	for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1092		win_idma_cap_write(base, i, 0);
1093
1094	/*
1095	 * Set up access to all active DRAM banks
1096	 */
1097	for (i = 0; i < MV_WIN_DDR_MAX; i++)
1098		if (ddr_is_active(i)) {
1099			br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
1100			sz = ((ddr_size(i) - 1) & 0xffff0000);
1101
1102			/* Place DDR entries in non-remapped windows */
1103			for (j = 0; j < MV_WIN_IDMA_MAX; j++)
1104				if (win_idma_can_remap(j) != 1 &&
1105				    idma_bare_read(base, j) == 1) {
1106
1107					/* Configure window */
1108					win_idma_br_write(base, j, br);
1109					win_idma_sz_write(base, j, sz);
1110
1111					/* Set protection RW on all channels */
1112					idma_set_prot(base, j, 0x3);
1113
1114					/* Enable window */
1115					idma_bare_write(base, j, 0);
1116					break;
1117				}
1118		}
1119
1120	/*
1121	 * Remaining targets -- from statically defined table
1122	 */
1123	for (i = 0; i < idma_wins_no; i++)
1124		if (idma_wins[i].target > 0) {
1125			br = (idma_wins[i].base & 0xffff0000) |
1126			    (idma_wins[i].attr << 8) | idma_wins[i].target;
1127			sz = ((idma_wins[i].size - 1) & 0xffff0000);
1128
1129			/* Set the first free IDMA window */
1130			for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
1131				if (idma_bare_read(base, j) == 0)
1132					continue;
1133
1134				/* Configure window */
1135				win_idma_br_write(base, j, br);
1136				win_idma_sz_write(base, j, sz);
1137				if (win_idma_can_remap(j) &&
1138				    idma_wins[j].remap >= 0)
1139					win_idma_har_write(base, j,
1140					    idma_wins[j].remap);
1141
1142				/* Set protection RW on all channels */
1143				idma_set_prot(base, j, 0x3);
1144
1145				/* Enable window */
1146				idma_bare_write(base, j, 0);
1147				break;
1148			}
1149		}
1150}
1151
1152int
1153decode_win_idma_valid(void)
1154{
1155	const struct decode_win *wintab;
1156	int c, i, j, rv;
1157	uint32_t b, e, s;
1158
1159	if (idma_wins_no > MV_WIN_IDMA_MAX) {
1160		printf("IDMA windows: too many entries: %d\n", idma_wins_no);
1161		return (0);
1162	}
1163	for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1164		if (ddr_is_active(i))
1165			c++;
1166
1167	if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
1168		printf("IDMA windows: too many entries: %d, available: %d\n",
1169		    idma_wins_no, MV_WIN_IDMA_MAX - c);
1170		return (0);
1171	}
1172
1173	wintab = idma_wins;
1174	rv = 1;
1175	for (i = 0; i < idma_wins_no; i++, wintab++) {
1176
1177		if (wintab->target == 0) {
1178			printf("IDMA window#%d: DDR target window is not "
1179			    "supposed to be reprogrammed!\n", i);
1180			rv = 0;
1181		}
1182
1183		if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1184			printf("IDMA window#%d: not capable of remapping, but "
1185			    "val 0x%08x defined\n", i, wintab->remap);
1186			rv = 0;
1187		}
1188
1189		s = wintab->size;
1190		b = wintab->base;
1191		e = b + s - 1;
1192		if (s > (0xFFFFFFFF - b + 1)) {
1193			/* XXX this boundary check should account for 64bit and
1194			 * remapping.. */
1195			printf("IDMA window#%d: no space for size 0x%08x at "
1196			    "0x%08x\n", i, s, b);
1197			rv = 0;
1198			continue;
1199		}
1200
1201		j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
1202		if (j >= 0) {
1203			printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
1204			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
1205			    idma_wins[j].base,
1206			    idma_wins[j].base + idma_wins[j].size - 1);
1207			rv = 0;
1208		}
1209	}
1210
1211	return (rv);
1212}
1213
1214void
1215decode_win_idma_dump(u_long base)
1216{
1217	int i;
1218
1219	if (pm_is_disabled(CPU_PM_CTRL_IDMA))
1220		return;
1221
1222	for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
1223		printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
1224		    win_idma_br_read(base, i), win_idma_sz_read(base, i));
1225
1226		if (win_idma_can_remap(i))
1227			printf(", ha 0x%08x", win_idma_har_read(base, i));
1228
1229		printf("\n");
1230	}
1231	for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1232		printf("IDMA channel#%d: ap 0x%08x\n", i,
1233		    win_idma_cap_read(base, i));
1234	printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read(base));
1235}
1236#else
1237
1238/* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
1239int
1240decode_win_idma_valid(void)
1241{
1242
1243	return (1);
1244}
1245
1246void
1247decode_win_idma_setup(u_long base)
1248{
1249}
1250
1251void
1252decode_win_idma_dump(u_long base)
1253{
1254}
1255#endif
1256
1257/**************************************************************************
1258 * XOR windows routines
1259 **************************************************************************/
1260#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
1261static int
1262xor_ctrl_read(u_long base, int i, int c, int e)
1263{
1264	uint32_t v;
1265	v = win_xor_ctrl_read(base, c, e);
1266	v &= (1 << i);
1267
1268	return (v >> i);
1269}
1270
1271static void
1272xor_ctrl_write(u_long base, int i, int c, int e, int val)
1273{
1274	uint32_t v;
1275
1276	v = win_xor_ctrl_read(base, c, e);
1277	v &= ~(1 << i);
1278	v |= (val << i);
1279	win_xor_ctrl_write(base, c, e, v);
1280}
1281
1282/*
1283 * Set channel protection 'val' for window 'w' on channel 'c'
1284 */
1285
1286static void
1287xor_chan_write(u_long base, int c, int e, int w, int val)
1288{
1289	uint32_t v;
1290
1291	v = win_xor_ctrl_read(base, c, e);
1292	v &= ~(0x3 << (w * 2 + 16));
1293	v |= (val << (w * 2 + 16));
1294	win_xor_ctrl_write(base, c, e, v);
1295}
1296
1297/*
1298 * Set protection 'val' on all channels for window 'w' on engine 'e'
1299 */
1300static void
1301xor_set_prot(u_long base, int w, int e, int val)
1302{
1303	int c;
1304
1305	for (c = 0; c < MV_XOR_CHAN_MAX; c++)
1306		xor_chan_write(base, c, e, w, val);
1307}
1308
1309static int
1310win_xor_can_remap(int i)
1311{
1312
1313	/* XOR decode windows 0-3 have remap capability */
1314	if (i < 4)
1315		return (1);
1316
1317	return (0);
1318}
1319
1320static int
1321xor_max_eng(void)
1322{
1323	uint32_t dev, rev;
1324
1325	soc_id(&dev, &rev);
1326	if (dev == MV_DEV_88F6281)
1327		return (2);
1328	else if ((dev == MV_DEV_MV78100) || (dev == MV_DEV_MV78100_Z0))
1329		return (1);
1330	else
1331		return (0);
1332}
1333
1334static void
1335xor_active_dram(u_long base, int c, int e, int *window)
1336{
1337	uint32_t br, sz;
1338	int i, m, w;
1339
1340	/*
1341	 * Set up access to all active DRAM banks
1342	 */
1343	m = xor_max_eng();
1344	for (i = 0; i < m; i++)
1345		if (ddr_is_active(i)) {
1346			br = ddr_base(i) | (ddr_attr(i) << 8) |
1347			    ddr_target(i);
1348			sz = ((ddr_size(i) - 1) & 0xffff0000);
1349
1350			/* Place DDR entries in non-remapped windows */
1351			for (w = 0; w < MV_WIN_XOR_MAX; w++)
1352				if (win_xor_can_remap(w) != 1 &&
1353				    (xor_ctrl_read(base, w, c, e) == 0) &&
1354				    w > *window) {
1355					/* Configure window */
1356					win_xor_br_write(base, w, e, br);
1357					win_xor_sz_write(base, w, e, sz);
1358
1359					/* Set protection RW on all channels */
1360					xor_set_prot(base, w, e, 0x3);
1361
1362					/* Enable window */
1363					xor_ctrl_write(base, w, c, e, 1);
1364					(*window)++;
1365					break;
1366				}
1367		}
1368}
1369
1370void
1371decode_win_xor_setup(u_long base)
1372{
1373	uint32_t br, sz;
1374	int i, j, z, e = 1, m, window;
1375
1376	if (pm_is_disabled(CPU_PM_CTRL_XOR))
1377		return;
1378
1379	/*
1380	 * Disable and clear all XOR windows, revoke protection for all
1381	 * channels
1382	 */
1383	m = xor_max_eng();
1384	for (j = 0; j < m; j++, e--) {
1385
1386		/* Number of non-remaped windows */
1387		window = MV_XOR_NON_REMAP - 1;
1388
1389		for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1390			win_xor_br_write(base, i, e, 0);
1391			win_xor_sz_write(base, i, e, 0);
1392		}
1393
1394		if (win_xor_can_remap(i) == 1)
1395			win_xor_har_write(base, i, e, 0);
1396
1397		for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
1398			win_xor_ctrl_write(base, i, e, 0);
1399			xor_active_dram(base, i, e, &window);
1400		}
1401
1402		/*
1403		 * Remaining targets -- from a statically defined table
1404		 */
1405		for (i = 0; i < xor_wins_no; i++)
1406			if (xor_wins[i].target > 0) {
1407				br = (xor_wins[i].base & 0xffff0000) |
1408				    (xor_wins[i].attr << 8) |
1409				    xor_wins[i].target;
1410				sz = ((xor_wins[i].size - 1) & 0xffff0000);
1411
1412				/* Set the first free XOR window */
1413				for (z = 0; z < MV_WIN_XOR_MAX; z++) {
1414					if (xor_ctrl_read(base, z, 0, e) &&
1415					    xor_ctrl_read(base, z, 1, e))
1416						continue;
1417
1418					/* Configure window */
1419					win_xor_br_write(base, z, e, br);
1420					win_xor_sz_write(base, z, e, sz);
1421					if (win_xor_can_remap(z) &&
1422					    xor_wins[z].remap >= 0)
1423						win_xor_har_write(base, z, e,
1424						    xor_wins[z].remap);
1425
1426					/* Set protection RW on all channels */
1427					xor_set_prot(base, z, e, 0x3);
1428
1429					/* Enable window */
1430					xor_ctrl_write(base, z, 0, e, 1);
1431					xor_ctrl_write(base, z, 1, e, 1);
1432					break;
1433				}
1434			}
1435	}
1436}
1437
1438int
1439decode_win_xor_valid(void)
1440{
1441	const struct decode_win *wintab;
1442	int c, i, j, rv;
1443	uint32_t b, e, s;
1444
1445	if (xor_wins_no > MV_WIN_XOR_MAX) {
1446		printf("XOR windows: too many entries: %d\n", xor_wins_no);
1447		return (0);
1448	}
1449	for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1450		if (ddr_is_active(i))
1451			c++;
1452
1453	if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
1454		printf("XOR windows: too many entries: %d, available: %d\n",
1455		    xor_wins_no, MV_WIN_IDMA_MAX - c);
1456		return (0);
1457	}
1458
1459	wintab = xor_wins;
1460	rv = 1;
1461	for (i = 0; i < xor_wins_no; i++, wintab++) {
1462
1463		if (wintab->target == 0) {
1464			printf("XOR window#%d: DDR target window is not "
1465			    "supposed to be reprogrammed!\n", i);
1466			rv = 0;
1467		}
1468
1469		if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1470			printf("XOR window#%d: not capable of remapping, but "
1471			    "val 0x%08x defined\n", i, wintab->remap);
1472			rv = 0;
1473		}
1474
1475		s = wintab->size;
1476		b = wintab->base;
1477		e = b + s - 1;
1478		if (s > (0xFFFFFFFF - b + 1)) {
1479			/*
1480			 * XXX this boundary check should account for 64bit
1481			 * and remapping..
1482			 */
1483			printf("XOR window#%d: no space for size 0x%08x at "
1484			    "0x%08x\n", i, s, b);
1485			rv = 0;
1486			continue;
1487		}
1488
1489		j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
1490		if (j >= 0) {
1491			printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
1492			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
1493			    xor_wins[j].base,
1494			    xor_wins[j].base + xor_wins[j].size - 1);
1495			rv = 0;
1496		}
1497	}
1498
1499	return (rv);
1500}
1501
1502void
1503decode_win_xor_dump(u_long base)
1504{
1505	int i, j;
1506	int e = 1;
1507
1508	if (pm_is_disabled(CPU_PM_CTRL_XOR))
1509		return;
1510
1511	for (j = 0; j < xor_max_eng(); j++, e--) {
1512		for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1513			printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
1514			    win_xor_br_read(base, i, e), win_xor_sz_read(base, i, e));
1515
1516			if (win_xor_can_remap(i))
1517				printf(", ha 0x%08x", win_xor_har_read(base, i, e));
1518
1519			printf("\n");
1520		}
1521		for (i = 0; i < MV_XOR_CHAN_MAX; i++)
1522			printf("XOR control#%d: 0x%08x\n", i,
1523			    win_xor_ctrl_read(base, i, e));
1524	}
1525}
1526
1527#else
1528/* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
1529static int
1530decode_win_xor_valid(void)
1531{
1532
1533	return (1);
1534}
1535
1536static void
1537decode_win_xor_setup(u_long base)
1538{
1539}
1540
1541static void
1542decode_win_xor_dump(u_long base)
1543{
1544}
1545#endif
1546
1547/**************************************************************************
1548 * CESA TDMA windows routines
1549 **************************************************************************/
1550#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
1551/*
1552 * Dump CESA TDMA decode windows.
1553 */
1554static void
1555decode_win_cesa_dump(u_long base)
1556{
1557	int i;
1558
1559	if (pm_is_disabled(CPU_PM_CTRL_CRYPTO))
1560		return;
1561
1562	for (i = 0; i < MV_WIN_CESA_MAX; i++)
1563		printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
1564		    win_cesa_cr_read(base, i), win_cesa_br_read(base, i));
1565}
1566
1567
1568/*
1569 * Set CESA TDMA decode windows.
1570 */
1571static void
1572decode_win_cesa_setup(u_long base)
1573{
1574	uint32_t br, cr;
1575	int i, j;
1576
1577	if (pm_is_disabled(CPU_PM_CTRL_CRYPTO))
1578		return;
1579
1580	/* Disable and clear all CESA windows */
1581	for (i = 0; i < MV_WIN_CESA_MAX; i++) {
1582		win_cesa_cr_write(base, i, 0);
1583		win_cesa_br_write(base, i, 0);
1584	}
1585
1586	/* Only access to active DRAM banks is required. */
1587	for (i = 0; i < MV_WIN_DDR_MAX; i++)
1588		if (ddr_is_active(i)) {
1589			br = ddr_base(i);
1590			cr = (((ddr_size(i) - 1) & 0xffff0000) |
1591			   (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
1592
1593			/* Set the first available CESA window */
1594			for (j = 0; j < MV_WIN_CESA_MAX; j++) {
1595				if (win_cesa_cr_read(base, j) & 0x1)
1596					continue;
1597
1598				win_cesa_br_write(base, j, br);
1599				win_cesa_cr_write(base, j, cr);
1600				break;
1601			}
1602		}
1603}
1604
1605/*
1606 * Check CESA TDMA decode windows.
1607 */
1608static int
1609decode_win_cesa_valid(void)
1610{
1611
1612	return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
1613}
1614#else
1615
1616/*
1617 * Provide dummy functions to satisfy the build for SoCs not equipped with
1618 * CESA
1619 */
1620
1621static int
1622decode_win_cesa_valid(void)
1623{
1624
1625	return (1);
1626}
1627
1628static void
1629decode_win_cesa_setup(u_long base)
1630{
1631}
1632
1633static void
1634decode_win_cesa_dump(u_long base)
1635{
1636}
1637#endif
1638
1639/**************************************************************************
1640 * SATA windows routines
1641 **************************************************************************/
1642static void
1643decode_win_sata_setup(u_long base)
1644{
1645	uint32_t cr, br;
1646	int i, j;
1647
1648	if (pm_is_disabled(CPU_PM_CTRL_SATA))
1649		return;
1650
1651	for (i = 0; i < MV_WIN_SATA_MAX; i++) {
1652		win_sata_cr_write(base, i, 0);
1653		win_sata_br_write(base, i, 0);
1654	}
1655
1656	for (i = 0; i < MV_WIN_DDR_MAX; i++)
1657		if (ddr_is_active(i)) {
1658			cr = ((ddr_size(i) - 1) & 0xffff0000) |
1659			    (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
1660			br = ddr_base(i);
1661
1662			/* Use the first available SATA window */
1663			for (j = 0; j < MV_WIN_SATA_MAX; j++) {
1664				if ((win_sata_cr_read(base, j) & 1) != 0)
1665					continue;
1666
1667				win_sata_br_write(base, j, br);
1668				win_sata_cr_write(base, j, cr);
1669				break;
1670			}
1671		}
1672}
1673
1674static int
1675decode_win_sata_valid(void)
1676{
1677	uint32_t dev, rev;
1678
1679	soc_id(&dev, &rev);
1680	if (dev == MV_DEV_88F5281)
1681		return (1);
1682
1683	return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
1684}
1685
1686/**************************************************************************
1687 * FDT parsing routines.
1688 **************************************************************************/
1689
1690static int
1691fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples,
1692    int *tuplesize)
1693{
1694	phandle_t node;
1695	pcell_t addr_cells, par_addr_cells, size_cells;
1696	int len, tuple_size, tuples_count;
1697
1698	node = OF_finddevice(nodename);
1699	if (node <= 0)
1700		return (EINVAL);
1701
1702	if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
1703		return (ENXIO);
1704
1705	par_addr_cells = fdt_parent_addr_cells(node);
1706	if (par_addr_cells > 2)
1707		return (ERANGE);
1708
1709	tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
1710	    size_cells);
1711
1712	/* Note the OF_getprop_alloc() cannot be used at this early stage. */
1713	len = OF_getprop(node, "ranges", buf, size);
1714
1715	/*
1716	 * XXX this does not handle the empty 'ranges;' case, which is
1717	 * legitimate and should be allowed.
1718	 */
1719	tuples_count = len / tuple_size;
1720	if (tuples_count <= 0)
1721		return (ERANGE);
1722
1723	if (fdt_ranges_verify(buf, tuples_count, par_addr_cells,
1724	    addr_cells, size_cells) != 0)
1725		return (ERANGE);
1726
1727	*tuples = tuples_count;
1728	*tuplesize = tuple_size;
1729	return (0);
1730}
1731
1732static int
1733win_cpu_from_dt(void)
1734{
1735	pcell_t ranges[48];
1736	u_long sram_base, sram_size;
1737	phandle_t node;
1738	int i, entry_size, err, t, tuple_size, tuples;
1739
1740	/* Retrieve 'ranges' property of '/localbus' node. */
1741	if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges),
1742	    &tuples, &tuple_size)) != 0)
1743		return (err);
1744
1745	/*
1746	 * Fill CPU decode windows table.
1747	 */
1748	bzero((void *)&cpu_win_tbl, sizeof(cpu_win_tbl));
1749
1750	entry_size = tuple_size / sizeof(pcell_t);
1751	cpu_wins_no = tuples;
1752
1753	for (i = 0, t = 0; t < tuples; i += entry_size, t++) {
1754		cpu_win_tbl[t].target = 1;
1755		cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]);
1756		cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]);
1757		cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]);
1758		cpu_win_tbl[t].remap = -1;
1759		debugf("target = 0x%0x attr = 0x%0x base = 0x%0x "
1760		    "size = 0x%0x remap = %d\n", cpu_win_tbl[t].target,
1761		    cpu_win_tbl[t].attr, cpu_win_tbl[t].base,
1762		    cpu_win_tbl[t].size, cpu_win_tbl[t].remap);
1763	}
1764
1765	/*
1766	 * Retrieve CESA SRAM data.
1767	 */
1768	if ((node = OF_finddevice("sram")) != 0)
1769		if (fdt_is_compatible(node, "mrvl,cesa-sram"))
1770			goto moveon;
1771
1772	if ((node = OF_finddevice("/")) == 0)
1773		return (ENXIO);
1774
1775	if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
1776		/* SRAM block is not always present. */
1777		return (0);
1778moveon:
1779	sram_base = sram_size = 0;
1780	if (fdt_regsize(node, &sram_base, &sram_size) != 0)
1781		return (EINVAL);
1782
1783	cpu_win_tbl[++t].target = MV_WIN_CESA_TARGET;
1784	cpu_win_tbl[t].attr = MV_WIN_CESA_ATTR;
1785	cpu_win_tbl[t].base = sram_base;
1786	cpu_win_tbl[t].size = sram_size;
1787	cpu_win_tbl[t].remap = -1;
1788	debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
1789
1790	return (0);
1791}
1792
1793static int
1794fdt_win_setup(void)
1795{
1796	phandle_t node, child;
1797	struct soc_node_spec *soc_node;
1798	u_long size, base;
1799	int err, i;
1800
1801	node = OF_finddevice("/");
1802	if (node == 0)
1803		panic("fdt_win_setup: no root node");
1804
1805	node = fdt_find_compatible(node, "simple-bus", 1);
1806	if (node == 0)
1807		return (ENXIO);
1808
1809	/*
1810	 * Traverse through all children of simple-bus node, and retrieve
1811	 * decode windows data for devices (if applicable).
1812	 */
1813	for (child = OF_child(node); child != 0; child = OF_peer(child))
1814		for (i = 0; soc_nodes[i].compat != NULL; i++) {
1815
1816			soc_node = &soc_nodes[i];
1817
1818			if (!fdt_is_compatible(child, soc_node->compat))
1819				continue;
1820
1821			err = fdt_regsize(child, &base, &size);
1822			if (err != 0)
1823				return (err);
1824
1825			base += fdt_immr_va;
1826			if (soc_node->decode_handler != NULL)
1827				soc_node->decode_handler(base);
1828			else
1829				return (ENXIO);
1830
1831			if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
1832				soc_node->dump_handler(base);
1833		}
1834
1835	return (0);
1836}
1837
1838static void
1839fdt_fixup_busfreq(phandle_t root)
1840{
1841	phandle_t sb;
1842	pcell_t freq;
1843
1844	/*
1845	 * This fixup sets the simple-bus bus-frequency property.
1846	 */
1847
1848	if ((sb = fdt_find_compatible(root, "simple-bus", 1)) == 0)
1849		return;
1850
1851	freq = cpu_to_fdt32(get_tclk());
1852	OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
1853}
1854
1855struct fdt_fixup_entry fdt_fixup_table[] = {
1856	{ "mrvl,DB-88F6281", &fdt_fixup_busfreq },
1857	{ NULL, NULL }
1858};
1859
1860static int
1861fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
1862    int *pol)
1863{
1864
1865	if (!fdt_is_compatible(node, "mrvl,pic"))
1866		return (ENXIO);
1867
1868	*interrupt = fdt32_to_cpu(intr[0]);
1869	*trig = INTR_TRIGGER_CONFORM;
1870	*pol = INTR_POLARITY_CONFORM;
1871
1872	return (0);
1873}
1874
1875fdt_pic_decode_t fdt_pic_table[] = {
1876	&fdt_pic_decode_ic,
1877	NULL
1878};
1879