]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/arm/mv/common.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / arm / mv / common.c
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
68 static int win_eth_can_remap(int i);
69
70 static int decode_win_cpu_valid(void);
71 static int decode_win_usb_valid(void);
72 static int decode_win_eth_valid(void);
73 static int decode_win_pcie_valid(void);
74 static int decode_win_sata_valid(void);
75 static int decode_win_cesa_valid(void);
76 static int decode_win_idma_valid(void);
77 static int decode_win_xor_valid(void);
78
79 static void decode_win_cpu_setup(void);
80 static void decode_win_usb_setup(u_long);
81 static void decode_win_eth_setup(u_long);
82 static void decode_win_pcie_setup(u_long);
83 static void decode_win_sata_setup(u_long);
84 static void decode_win_cesa_setup(u_long);
85 static void decode_win_idma_setup(u_long);
86 static void decode_win_xor_setup(u_long);
87
88 static void decode_win_cesa_dump(u_long);
89 static void decode_win_usb_dump(u_long);
90 static void decode_win_eth_dump(u_long base);
91 static void decode_win_idma_dump(u_long base);
92 static void decode_win_xor_dump(u_long base);
93
94 static int fdt_get_ranges(const char *, void *, int, int *, int *);
95
96 static int win_cpu_from_dt(void);
97 static int fdt_win_setup(void);
98
99 static uint32_t used_cpu_wins;
100 static uint32_t dev_mask = 0;
101 static int cpu_wins_no = 0;
102 static int eth_port = 0;
103 static int usb_port = 0;
104
105 static struct decode_win cpu_win_tbl[MAX_CPU_WIN];
106
107 static const struct decode_win *cpu_wins = cpu_win_tbl;
108
109 typedef void (*decode_win_setup_t)(u_long);
110 typedef void (*dump_win_t)(u_long);
111
112 struct soc_node_spec {
113         const char              *compat;
114         decode_win_setup_t      decode_handler;
115         dump_win_t              dump_handler;
116 };
117
118 static 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
129 struct 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
142 static __inline int
143 pm_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  */
182 static __inline void
183 pm_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
200 int
201 fdt_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
227 uint32_t
228 read_cpu_ctrl(uint32_t reg)
229 {
230
231         return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg));
232 }
233
234 void
235 write_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
241 void
242 cpu_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
250 uint32_t
251 cpu_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  */
272 uint32_t
273 soc_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  */
290 void
291 soc_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
300 void
301 soc_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
314 static void
315 soc_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
376 static void
377 platform_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 }
387 SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify,
388     NULL);
389
390 int
391 soc_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  **************************************************************************/
430 WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
431 WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
432 WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
433 WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
434 WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
435 WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
436 WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
437 WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
438
439 WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
440 WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
441
442 WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
443 WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
444 WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
445 WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE)
446
447 WIN_REG_BASE_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL)
448 WIN_REG_BASE_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE)
449 WIN_REG_BASE_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL)
450 WIN_REG_BASE_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE)
451
452 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
453 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
454 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
455 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
456 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
457 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
458
459 WIN_REG_BASE_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE)
460 WIN_REG_BASE_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE)
461 WIN_REG_BASE_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP)
462 WIN_REG_BASE_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL)
463 WIN_REG_BASE_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE)
464 WIN_REG_BASE_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE)
465 WIN_REG_BASE_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP)
466 WIN_REG_BASE_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL)
467
468 WIN_REG_BASE_RD(win_eth, bare, 0x290)
469 WIN_REG_BASE_RD(win_eth, epap, 0x294)
470 WIN_REG_BASE_WR(win_eth, bare, 0x290)
471 WIN_REG_BASE_WR(win_eth, epap, 0x294)
472
473 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
474 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
475 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
476 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
477 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
478 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
479 WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
480
481 WIN_REG_BASE_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE)
482 WIN_REG_BASE_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE)
483 WIN_REG_BASE_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP)
484 WIN_REG_BASE_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP)
485 WIN_REG_BASE_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE)
486 WIN_REG_BASE_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE)
487 WIN_REG_BASE_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP)
488 WIN_REG_BASE_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP)
489 WIN_REG_BASE_RD(win_idma, bare, 0xa80)
490 WIN_REG_BASE_WR(win_idma, bare, 0xa80)
491
492 WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL);
493 WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE);
494 WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL);
495 WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE);
496
497 /**************************************************************************
498  * Decode windows helper routines
499  **************************************************************************/
500 void
501 soc_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  **************************************************************************/
531 int
532 win_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.. */
550 int
551 decode_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
576 static int
577 decode_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
629 int
630 decode_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
665 static void
666 decode_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  */
693 static int
694 decode_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  **************************************************************************/
715 int
716 ddr_is_active(int i)
717 {
718
719         if (ddr_sz_read(i) & 0x1)
720                 return (1);
721
722         return (0);
723 }
724
725 uint32_t
726 ddr_base(int i)
727 {
728
729         return (ddr_br_read(i) & 0xff000000);
730 }
731
732 uint32_t
733 ddr_size(int i)
734 {
735
736         return ((ddr_sz_read(i) | 0x00ffffff) + 1);
737 }
738
739 uint32_t
740 ddr_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
749 uint32_t
750 ddr_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  **************************************************************************/
760 static int
761 decode_win_usb_valid(void)
762 {
763
764         return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
765 }
766
767 static void
768 decode_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  */
783 static void
784 decode_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
829 static int
830 win_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
840 static int
841 eth_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
851 static void
852 eth_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
862 static void
863 eth_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
873 static void
874 decode_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
897 static void
898 decode_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
946 static int
947 decode_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
957 static void
958 decode_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
1002 static int
1003 decode_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)
1013 static int
1014 idma_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
1024 static void
1025 idma_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  */
1038 static void
1039 idma_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  */
1052 static void
1053 idma_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
1061 static int
1062 win_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
1072 void
1073 decode_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
1152 int
1153 decode_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
1214 void
1215 decode_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 */
1239 int
1240 decode_win_idma_valid(void)
1241 {
1242
1243         return (1);
1244 }
1245
1246 void
1247 decode_win_idma_setup(u_long base)
1248 {
1249 }
1250
1251 void
1252 decode_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)
1261 static int
1262 xor_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
1271 static void
1272 xor_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
1286 static void
1287 xor_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  */
1300 static void
1301 xor_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
1309 static int
1310 win_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
1320 static int
1321 xor_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
1334 static void
1335 xor_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
1370 void
1371 decode_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
1438 int
1439 decode_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
1502 void
1503 decode_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 */
1529 static int
1530 decode_win_xor_valid(void)
1531 {
1532
1533         return (1);
1534 }
1535
1536 static void
1537 decode_win_xor_setup(u_long base)
1538 {
1539 }
1540
1541 static void
1542 decode_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  */
1554 static void
1555 decode_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  */
1571 static void
1572 decode_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  */
1608 static int
1609 decode_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
1621 static int
1622 decode_win_cesa_valid(void)
1623 {
1624
1625         return (1);
1626 }
1627
1628 static void
1629 decode_win_cesa_setup(u_long base)
1630 {
1631 }
1632
1633 static void
1634 decode_win_cesa_dump(u_long base)
1635 {
1636 }
1637 #endif
1638
1639 /**************************************************************************
1640  * SATA windows routines
1641  **************************************************************************/
1642 static void
1643 decode_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
1674 static int
1675 decode_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
1690 static int
1691 fdt_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
1732 static int
1733 win_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);
1778 moveon:
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
1793 static int
1794 fdt_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
1838 static void
1839 fdt_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
1855 struct fdt_fixup_entry fdt_fixup_table[] = {
1856         { "mrvl,DB-88F6281", &fdt_fixup_busfreq },
1857         { NULL, NULL }
1858 };
1859
1860 static int
1861 fdt_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
1875 fdt_pic_decode_t fdt_pic_table[] = {
1876         &fdt_pic_decode_ic,
1877         NULL
1878 };