]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/mv/mv_common.c
Update Makefiles and other build glue for llvm/clang 3.7.0, as of trunk
[FreeBSD/FreeBSD.git] / sys / arm / mv / mv_common.c
1 /*-
2  * Copyright (C) 2008-2011 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 #include <sys/malloc.h>
40 #include <sys/kdb.h>
41 #include <sys/reboot.h>
42
43 #include <dev/fdt/fdt_common.h>
44 #include <dev/ofw/openfirm.h>
45
46 #include <machine/bus.h>
47 #include <machine/fdt.h>
48 #include <machine/vmparam.h>
49
50 #include <arm/mv/mvreg.h>
51 #include <arm/mv/mvvar.h>
52 #include <arm/mv/mvwin.h>
53
54
55 MALLOC_DEFINE(M_IDMA, "idma", "idma dma test memory");
56
57 #define IDMA_DEBUG
58 #undef IDMA_DEBUG
59
60 #define MAX_CPU_WIN     5
61
62 #ifdef DEBUG
63 #define debugf(fmt, args...) do { printf("%s(): ", __func__);   \
64     printf(fmt,##args); } while (0)
65 #else
66 #define debugf(fmt, args...)
67 #endif
68
69 #ifdef DEBUG
70 #define MV_DUMP_WIN     1
71 #else
72 #define MV_DUMP_WIN     0
73 #endif
74
75 static int win_eth_can_remap(int i);
76
77 #ifndef SOC_MV_FREY
78 static int decode_win_cpu_valid(void);
79 #endif
80 static int decode_win_usb_valid(void);
81 static int decode_win_eth_valid(void);
82 static int decode_win_pcie_valid(void);
83 static int decode_win_sata_valid(void);
84
85 static int decode_win_idma_valid(void);
86 static int decode_win_xor_valid(void);
87
88 #ifndef SOC_MV_FREY
89 static void decode_win_cpu_setup(void);
90 #endif
91 #ifdef SOC_MV_ARMADAXP
92 static int decode_win_sdram_fixup(void);
93 #endif
94 static void decode_win_usb_setup(u_long);
95 static void decode_win_eth_setup(u_long);
96 static void decode_win_sata_setup(u_long);
97
98 static void decode_win_idma_setup(u_long);
99 static void decode_win_xor_setup(u_long);
100
101 static void decode_win_usb_dump(u_long);
102 static void decode_win_eth_dump(u_long base);
103 static void decode_win_idma_dump(u_long base);
104 static void decode_win_xor_dump(u_long base);
105
106 static int fdt_get_ranges(const char *, void *, int, int *, int *);
107
108 static int win_cpu_from_dt(void);
109 static int fdt_win_setup(void);
110
111 static uint32_t dev_mask = 0;
112 static int cpu_wins_no = 0;
113 static int eth_port = 0;
114 static int usb_port = 0;
115
116 static struct decode_win cpu_win_tbl[MAX_CPU_WIN];
117
118 const struct decode_win *cpu_wins = cpu_win_tbl;
119
120 typedef void (*decode_win_setup_t)(u_long);
121 typedef void (*dump_win_t)(u_long);
122
123 struct soc_node_spec {
124         const char              *compat;
125         decode_win_setup_t      decode_handler;
126         dump_win_t              dump_handler;
127 };
128
129 static struct soc_node_spec soc_nodes[] = {
130         { "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump },
131         { "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump },
132         { "mrvl,sata", &decode_win_sata_setup, NULL },
133         { "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump },
134         { "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump },
135         { "mrvl,pcie", &decode_win_pcie_setup, NULL },
136         { NULL, NULL, NULL },
137 };
138
139 struct fdt_pm_mask_entry fdt_pm_mask_table[] = {
140         { "mrvl,ge",            CPU_PM_CTRL_GE(0) },
141         { "mrvl,ge",            CPU_PM_CTRL_GE(1) },
142         { "mrvl,usb-ehci",      CPU_PM_CTRL_USB(0) },
143         { "mrvl,usb-ehci",      CPU_PM_CTRL_USB(1) },
144         { "mrvl,usb-ehci",      CPU_PM_CTRL_USB(2) },
145         { "mrvl,xor",           CPU_PM_CTRL_XOR },
146         { "mrvl,sata",          CPU_PM_CTRL_SATA },
147
148         { NULL, 0 }
149 };
150
151 static __inline int
152 pm_is_disabled(uint32_t mask)
153 {
154 #if defined(SOC_MV_KIRKWOOD)
155         return (soc_power_ctrl_get(mask) == mask);
156 #else
157         return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
158 #endif
159 }
160
161 /*
162  * Disable device using power management register.
163  * 1 - Device Power On
164  * 0 - Device Power Off
165  * Mask can be set in loader.
166  * EXAMPLE:
167  * loader> set hw.pm-disable-mask=0x2
168  *
169  * Common mask:
170  * |-------------------------------|
171  * | Device | Kirkwood | Discovery |
172  * |-------------------------------|
173  * | USB0   | 0x00008  | 0x020000  |
174  * |-------------------------------|
175  * | USB1   |     -    | 0x040000  |
176  * |-------------------------------|
177  * | USB2   |     -    | 0x080000  |
178  * |-------------------------------|
179  * | GE0    | 0x00001  | 0x000002  |
180  * |-------------------------------|
181  * | GE1    |     -    | 0x000004  |
182  * |-------------------------------|
183  * | IDMA   |     -    | 0x100000  |
184  * |-------------------------------|
185  * | XOR    | 0x10000  | 0x200000  |
186  * |-------------------------------|
187  * | CESA   | 0x20000  | 0x400000  |
188  * |-------------------------------|
189  * | SATA   | 0x04000  | 0x004000  |
190  * --------------------------------|
191  * This feature can be used only on Kirkwood and Discovery
192  * machines.
193  */
194 static __inline void
195 pm_disable_device(int mask)
196 {
197 #ifdef DIAGNOSTIC
198         uint32_t reg;
199
200         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
201         printf("Power Management Register: 0%x\n", reg);
202
203         reg &= ~mask;
204         soc_power_ctrl_set(reg);
205         printf("Device %x is disabled\n", mask);
206
207         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
208         printf("Power Management Register: 0%x\n", reg);
209 #endif
210 }
211
212 int
213 fdt_pm(phandle_t node)
214 {
215         uint32_t cpu_pm_ctrl;
216         int i, ena, compat;
217
218         ena = 1;
219         cpu_pm_ctrl = read_cpu_ctrl(CPU_PM_CTRL);
220         for (i = 0; fdt_pm_mask_table[i].compat != NULL; i++) {
221                 if (dev_mask & (1 << i))
222                         continue;
223
224                 compat = fdt_is_compatible(node, fdt_pm_mask_table[i].compat);
225 #if defined(SOC_MV_KIRKWOOD)
226                 if (compat && (cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
227                         dev_mask |= (1 << i);
228                         ena = 0;
229                         break;
230                 } else if (compat) {
231                         dev_mask |= (1 << i);
232                         break;
233                 }
234 #else
235                 if (compat && (~cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
236                         dev_mask |= (1 << i);
237                         ena = 0;
238                         break;
239                 } else if (compat) {
240                         dev_mask |= (1 << i);
241                         break;
242                 }
243 #endif
244         }
245
246         return (ena);
247 }
248
249 uint32_t
250 read_cpu_ctrl(uint32_t reg)
251 {
252
253         return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg));
254 }
255
256 void
257 write_cpu_ctrl(uint32_t reg, uint32_t val)
258 {
259
260         bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg, val);
261 }
262
263 #if defined(SOC_MV_ARMADAXP)
264 uint32_t
265 read_cpu_mp_clocks(uint32_t reg)
266 {
267
268         return (bus_space_read_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg));
269 }
270
271 void
272 write_cpu_mp_clocks(uint32_t reg, uint32_t val)
273 {
274
275         bus_space_write_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg, val);
276 }
277
278 uint32_t
279 read_cpu_misc(uint32_t reg)
280 {
281
282         return (bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE, reg));
283 }
284
285 void
286 write_cpu_misc(uint32_t reg, uint32_t val)
287 {
288
289         bus_space_write_4(fdtbus_bs_tag, MV_MISC_BASE, reg, val);
290 }
291 #endif
292
293 void
294 cpu_reset(void)
295 {
296
297 #if defined(SOC_MV_ARMADAXP)
298         write_cpu_misc(RSTOUTn_MASK, SOFT_RST_OUT_EN);
299         write_cpu_misc(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
300 #else
301         write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
302         write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
303 #endif
304         while (1);
305 }
306
307 uint32_t
308 cpu_extra_feat(void)
309 {
310         uint32_t dev, rev;
311         uint32_t ef = 0;
312
313         soc_id(&dev, &rev);
314
315         switch (dev) {
316         case MV_DEV_88F6281:
317         case MV_DEV_88F6282:
318         case MV_DEV_88RC8180:
319         case MV_DEV_MV78100_Z0:
320         case MV_DEV_MV78100:
321                 __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
322                 break;
323         case MV_DEV_88F5182:
324         case MV_DEV_88F5281:
325                 __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
326                 break;
327         default:
328                 if (bootverbose)
329                         printf("This ARM Core does not support any extra features\n");
330         }
331
332         return (ef);
333 }
334
335 /*
336  * Get the power status of device. This feature is only supported on
337  * Kirkwood and Discovery SoCs.
338  */
339 uint32_t
340 soc_power_ctrl_get(uint32_t mask)
341 {
342
343 #if !defined(SOC_MV_ORION) && !defined(SOC_MV_LOKIPLUS) && !defined(SOC_MV_FREY)
344         if (mask != CPU_PM_CTRL_NONE)
345                 mask &= read_cpu_ctrl(CPU_PM_CTRL);
346
347         return (mask);
348 #else
349         return (mask);
350 #endif
351 }
352
353 /*
354  * Set the power status of device. This feature is only supported on
355  * Kirkwood and Discovery SoCs.
356  */
357 void
358 soc_power_ctrl_set(uint32_t mask)
359 {
360
361 #if !defined(SOC_MV_ORION) && !defined(SOC_MV_LOKIPLUS)
362         if (mask != CPU_PM_CTRL_NONE)
363                 write_cpu_ctrl(CPU_PM_CTRL, mask);
364 #endif
365 }
366
367 void
368 soc_id(uint32_t *dev, uint32_t *rev)
369 {
370
371         /*
372          * Notice: system identifiers are available in the registers range of
373          * PCIE controller, so using this function is only allowed (and
374          * possible) after the internal registers range has been mapped in via
375          * pmap_devmap_bootstrap().
376          */
377         *dev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 0) >> 16;
378         *rev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 8) & 0xff;
379 }
380
381 static void
382 soc_identify(void)
383 {
384         uint32_t d, r, size, mode;
385         const char *dev;
386         const char *rev;
387
388         soc_id(&d, &r);
389
390         printf("SOC: ");
391         if (bootverbose)
392                 printf("(0x%4x:0x%02x) ", d, r);
393
394         rev = "";
395         switch (d) {
396         case MV_DEV_88F5181:
397                 dev = "Marvell 88F5181";
398                 if (r == 3)
399                         rev = "B1";
400                 break;
401         case MV_DEV_88F5182:
402                 dev = "Marvell 88F5182";
403                 if (r == 2)
404                         rev = "A2";
405                 break;
406         case MV_DEV_88F5281:
407                 dev = "Marvell 88F5281";
408                 if (r == 4)
409                         rev = "D0";
410                 else if (r == 5)
411                         rev = "D1";
412                 else if (r == 6)
413                         rev = "D2";
414                 break;
415         case MV_DEV_88F6281:
416                 dev = "Marvell 88F6281";
417                 if (r == 0)
418                         rev = "Z0";
419                 else if (r == 2)
420                         rev = "A0";
421                 else if (r == 3)
422                         rev = "A1";
423                 break;
424         case MV_DEV_88RC8180:
425                 dev = "Marvell 88RC8180";
426                 break;
427         case MV_DEV_88RC9480:
428                 dev = "Marvell 88RC9480";
429                 break;
430         case MV_DEV_88RC9580:
431                 dev = "Marvell 88RC9580";
432                 break;
433         case MV_DEV_88F6781:
434                 dev = "Marvell 88F6781";
435                 if (r == 2)
436                         rev = "Y0";
437                 break;
438         case MV_DEV_88F6282:
439                 dev = "Marvell 88F6282";
440                 if (r == 0)
441                         rev = "A0";
442                 else if (r == 1)
443                         rev = "A1";
444                 break;
445         case MV_DEV_MV78100_Z0:
446                 dev = "Marvell MV78100 Z0";
447                 break;
448         case MV_DEV_MV78100:
449                 dev = "Marvell MV78100";
450                 break;
451         case MV_DEV_MV78160:
452                 dev = "Marvell MV78160";
453                 break;
454         case MV_DEV_MV78260:
455                 dev = "Marvell MV78260";
456                 break;
457         case MV_DEV_MV78460:
458                 dev = "Marvell MV78460";
459                 break;
460         default:
461                 dev = "UNKNOWN";
462                 break;
463         }
464
465         printf("%s", dev);
466         if (*rev != '\0')
467                 printf(" rev %s", rev);
468         printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
469
470         mode = read_cpu_ctrl(CPU_CONFIG);
471         printf("  Instruction cache prefetch %s, data cache prefetch %s\n",
472             (mode & CPU_CONFIG_IC_PREF) ? "enabled" : "disabled",
473             (mode & CPU_CONFIG_DC_PREF) ? "enabled" : "disabled");
474
475         switch (d) {
476         case MV_DEV_88F6281:
477         case MV_DEV_88F6282:
478                 mode = read_cpu_ctrl(CPU_L2_CONFIG) & CPU_L2_CONFIG_MODE;
479                 printf("  256KB 4-way set-associative %s unified L2 cache\n",
480                     mode ? "write-through" : "write-back");
481                 break;
482         case MV_DEV_MV78100:
483                 mode = read_cpu_ctrl(CPU_CONTROL);
484                 size = mode & CPU_CONTROL_L2_SIZE;
485                 mode = mode & CPU_CONTROL_L2_MODE;
486                 printf("  %s set-associative %s unified L2 cache\n",
487                     size ? "256KB 4-way" : "512KB 8-way",
488                     mode ? "write-through" : "write-back");
489                 break;
490         default:
491                 break;
492         }
493 }
494
495 static void
496 platform_identify(void *dummy)
497 {
498
499         soc_identify();
500
501         /*
502          * XXX Board identification e.g. read out from FPGA or similar should
503          * go here
504          */
505 }
506 SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify,
507     NULL);
508
509 #ifdef KDB
510 static void
511 mv_enter_debugger(void *dummy)
512 {
513
514         if (boothowto & RB_KDB)
515                 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
516 }
517 SYSINIT(mv_enter_debugger, SI_SUB_CPU, SI_ORDER_ANY, mv_enter_debugger, NULL);
518 #endif
519
520 int
521 soc_decode_win(void)
522 {
523         uint32_t dev, rev;
524         int mask, err;
525
526         mask = 0;
527         TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
528
529         if (mask != 0)
530                 pm_disable_device(mask);
531
532         /* Retrieve data about physical addresses from device tree. */
533         if ((err = win_cpu_from_dt()) != 0)
534                 return (err);
535
536         /* Retrieve our ID: some windows facilities vary between SoC models */
537         soc_id(&dev, &rev);
538
539 #ifdef SOC_MV_ARMADAXP
540         if ((err = decode_win_sdram_fixup()) != 0)
541                 return(err);
542 #endif
543
544 #ifndef SOC_MV_FREY
545         if (!decode_win_cpu_valid() || !decode_win_usb_valid() ||
546             !decode_win_eth_valid() || !decode_win_idma_valid() ||
547             !decode_win_pcie_valid() || !decode_win_sata_valid() ||
548             !decode_win_xor_valid())
549                 return (EINVAL);
550
551         decode_win_cpu_setup();
552 #else
553         if (!decode_win_usb_valid() ||
554             !decode_win_eth_valid() || !decode_win_idma_valid() ||
555             !decode_win_pcie_valid() || !decode_win_sata_valid() ||
556             !decode_win_xor_valid())
557                 return (EINVAL);
558 #endif
559         if (MV_DUMP_WIN)
560                 soc_dump_decode_win();
561
562         eth_port = 0;
563         usb_port = 0;
564         if ((err = fdt_win_setup()) != 0)
565                 return (err);
566
567         return (0);
568 }
569
570 /**************************************************************************
571  * Decode windows registers accessors
572  **************************************************************************/
573 #if !defined(SOC_MV_FREY)
574 WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
575 WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
576 WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
577 WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
578 WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
579 WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
580 WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
581 WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
582 #endif
583
584 WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
585 WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
586 WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
587 WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE)
588
589 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
590 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
591 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
592 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
593 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
594 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
595
596 WIN_REG_BASE_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE)
597 WIN_REG_BASE_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE)
598 WIN_REG_BASE_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP)
599 WIN_REG_BASE_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL)
600 WIN_REG_BASE_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE)
601 WIN_REG_BASE_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE)
602 WIN_REG_BASE_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP)
603 WIN_REG_BASE_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL)
604
605 WIN_REG_BASE_RD(win_eth, bare, 0x290)
606 WIN_REG_BASE_RD(win_eth, epap, 0x294)
607 WIN_REG_BASE_WR(win_eth, bare, 0x290)
608 WIN_REG_BASE_WR(win_eth, epap, 0x294)
609
610 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
611 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
612 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
613 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
614 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
615 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
616 WIN_REG_BASE_IDX_RD(pcie_bar, br, MV_PCIE_BAR_BASE);
617 WIN_REG_BASE_IDX_WR(pcie_bar, br, MV_PCIE_BAR_BASE);
618 WIN_REG_BASE_IDX_WR(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
619 WIN_REG_BASE_IDX_WR(pcie_bar, cr, MV_PCIE_BAR_CTRL);
620
621 WIN_REG_BASE_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE)
622 WIN_REG_BASE_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE)
623 WIN_REG_BASE_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP)
624 WIN_REG_BASE_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP)
625 WIN_REG_BASE_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE)
626 WIN_REG_BASE_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE)
627 WIN_REG_BASE_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP)
628 WIN_REG_BASE_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP)
629 WIN_REG_BASE_RD(win_idma, bare, 0xa80)
630 WIN_REG_BASE_WR(win_idma, bare, 0xa80)
631
632 WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL);
633 WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE);
634 WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL);
635 WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE);
636 #ifndef SOC_MV_DOVE
637 WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
638 WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
639 WIN_REG_IDX_WR(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
640 WIN_REG_IDX_WR(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
641 #else
642 /*
643  * On 88F6781 (Dove) SoC DDR Controller is accessed through
644  * single MBUS <-> AXI bridge. In this case we provide emulated
645  * ddr_br_read() and ddr_sz_read() functions to keep compatibility
646  * with common decoding windows setup code.
647  */
648
649 static inline uint32_t ddr_br_read(int i)
650 {
651         uint32_t mmap;
652
653         /* Read Memory Address Map Register for CS i */
654         mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
655
656         /* Return CS i base address */
657         return (mmap & 0xFF000000);
658 }
659
660 static inline uint32_t ddr_sz_read(int i)
661 {
662         uint32_t mmap, size;
663
664         /* Read Memory Address Map Register for CS i */
665         mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
666
667         /* Extract size of CS space in 64kB units */
668         size = (1 << ((mmap >> 16) & 0x0F));
669
670         /* Return CS size and enable/disable status */
671         return (((size - 1) << 16) | (mmap & 0x01));
672 }
673 #endif
674
675 #if !defined(SOC_MV_FREY)
676 /**************************************************************************
677  * Decode windows helper routines
678  **************************************************************************/
679 void
680 soc_dump_decode_win(void)
681 {
682         uint32_t dev, rev;
683         int i;
684
685         soc_id(&dev, &rev);
686
687         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
688                 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
689                     win_cpu_cr_read(i),
690                     win_cpu_br_read(i));
691
692                 if (win_cpu_can_remap(i))
693                         printf(", rl 0x%08x, rh 0x%08x",
694                             win_cpu_remap_l_read(i),
695                             win_cpu_remap_h_read(i));
696
697                 printf("\n");
698         }
699         printf("Internal regs base: 0x%08x\n",
700             bus_space_read_4(fdtbus_bs_tag, MV_INTREGS_BASE, 0));
701
702         for (i = 0; i < MV_WIN_DDR_MAX; i++)
703                 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
704                     ddr_br_read(i), ddr_sz_read(i));
705 }
706
707 /**************************************************************************
708  * CPU windows routines
709  **************************************************************************/
710 int
711 win_cpu_can_remap(int i)
712 {
713         uint32_t dev, rev;
714
715         soc_id(&dev, &rev);
716
717         /* Depending on the SoC certain windows have remap capability */
718         if ((dev == MV_DEV_88F5182 && i < 2) ||
719             (dev == MV_DEV_88F5281 && i < 4) ||
720             (dev == MV_DEV_88F6281 && i < 4) ||
721             (dev == MV_DEV_88F6282 && i < 4) ||
722             (dev == MV_DEV_88RC8180 && i < 2) ||
723             (dev == MV_DEV_88F6781 && i < 4) ||
724             (dev == MV_DEV_MV78100_Z0 && i < 8) ||
725             ((dev & MV_DEV_FAMILY_MASK) == MV_DEV_DISCOVERY && i < 8))
726                 return (1);
727
728         return (0);
729 }
730
731 /* XXX This should check for overlapping remap fields too.. */
732 int
733 decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
734 {
735         const struct decode_win *tab;
736         int i;
737
738         tab = wintab;
739
740         for (i = 0; i < win_no; i++, tab++) {
741                 if (i == win)
742                         /* Skip self */
743                         continue;
744
745                 if ((tab->base + tab->size - 1) < (wintab + win)->base)
746                         continue;
747
748                 else if (((wintab + win)->base + (wintab + win)->size - 1) <
749                     tab->base)
750                         continue;
751                 else
752                         return (i);
753         }
754
755         return (-1);
756 }
757
758 static int
759 decode_win_cpu_valid(void)
760 {
761         int i, j, rv;
762         uint32_t b, e, s;
763
764         if (cpu_wins_no > MV_WIN_CPU_MAX) {
765                 printf("CPU windows: too many entries: %d\n", cpu_wins_no);
766                 return (0);
767         }
768
769         rv = 1;
770         for (i = 0; i < cpu_wins_no; i++) {
771
772                 if (cpu_wins[i].target == 0) {
773                         printf("CPU window#%d: DDR target window is not "
774                             "supposed to be reprogrammed!\n", i);
775                         rv = 0;
776                 }
777
778                 if (cpu_wins[i].remap != ~0 && win_cpu_can_remap(i) != 1) {
779                         printf("CPU window#%d: not capable of remapping, but "
780                             "val 0x%08x defined\n", i, cpu_wins[i].remap);
781                         rv = 0;
782                 }
783
784                 s = cpu_wins[i].size;
785                 b = cpu_wins[i].base;
786                 e = b + s - 1;
787                 if (s > (0xFFFFFFFF - b + 1)) {
788                         /*
789                          * XXX this boundary check should account for 64bit
790                          * and remapping..
791                          */
792                         printf("CPU window#%d: no space for size 0x%08x at "
793                             "0x%08x\n", i, s, b);
794                         rv = 0;
795                         continue;
796                 }
797
798                 if (b != (b & ~(s - 1))) {
799                         printf("CPU window#%d: address 0x%08x is not aligned "
800                             "to 0x%08x\n", i, b, s);
801                         rv = 0;
802                         continue;
803                 }
804
805                 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
806                 if (j >= 0) {
807                         printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
808                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
809                             cpu_wins[j].base,
810                             cpu_wins[j].base + cpu_wins[j].size - 1);
811                         rv = 0;
812                 }
813         }
814
815         return (rv);
816 }
817
818 int
819 decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
820     vm_paddr_t remap)
821 {
822         uint32_t br, cr;
823         int win, i;
824
825         if (remap == ~0) {
826                 win = MV_WIN_CPU_MAX - 1;
827                 i = -1;
828         } else {
829                 win = 0;
830                 i = 1;
831         }
832
833         while ((win >= 0) && (win < MV_WIN_CPU_MAX)) {
834                 cr = win_cpu_cr_read(win);
835                 if ((cr & MV_WIN_CPU_ENABLE_BIT) == 0)
836                         break;
837                 if ((cr & ((0xff << MV_WIN_CPU_ATTR_SHIFT) |
838                     (0x1f << MV_WIN_CPU_TARGET_SHIFT))) ==
839                     ((attr << MV_WIN_CPU_ATTR_SHIFT) |
840                     (target << MV_WIN_CPU_TARGET_SHIFT)))
841                         break;
842                 win += i;
843         }
844         if ((win < 0) || (win >= MV_WIN_CPU_MAX) ||
845             ((remap != ~0) && (win_cpu_can_remap(win) == 0)))
846                 return (-1);
847
848         br = base & 0xffff0000;
849         win_cpu_br_write(win, br);
850
851         if (win_cpu_can_remap(win)) {
852                 if (remap != ~0) {
853                         win_cpu_remap_l_write(win, remap & 0xffff0000);
854                         win_cpu_remap_h_write(win, 0);
855                 } else {
856                         /*
857                          * Remap function is not used for a given window
858                          * (capable of remapping) - set remap field with the
859                          * same value as base.
860                          */
861                         win_cpu_remap_l_write(win, base & 0xffff0000);
862                         win_cpu_remap_h_write(win, 0);
863                 }
864         }
865
866         cr = ((size - 1) & 0xffff0000) | (attr << MV_WIN_CPU_ATTR_SHIFT) |
867             (target << MV_WIN_CPU_TARGET_SHIFT) | MV_WIN_CPU_ENABLE_BIT;
868         win_cpu_cr_write(win, cr);
869
870         return (0);
871 }
872
873 static void
874 decode_win_cpu_setup(void)
875 {
876         int i;
877
878         /* Disable all CPU windows */
879         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
880                 win_cpu_cr_write(i, 0);
881                 win_cpu_br_write(i, 0);
882                 if (win_cpu_can_remap(i)) {
883                         win_cpu_remap_l_write(i, 0);
884                         win_cpu_remap_h_write(i, 0);
885                 }
886         }
887
888         for (i = 0; i < cpu_wins_no; i++)
889                 if (cpu_wins[i].target > 0)
890                         decode_win_cpu_set(cpu_wins[i].target,
891                             cpu_wins[i].attr, cpu_wins[i].base,
892                             cpu_wins[i].size, cpu_wins[i].remap);
893
894 }
895 #endif
896
897 #ifdef SOC_MV_ARMADAXP
898 static int
899 decode_win_sdram_fixup(void)
900 {
901         struct mem_region mr[FDT_MEM_REGIONS];
902         uint8_t window_valid[MV_WIN_DDR_MAX];
903         int mr_cnt, memsize, err, i, j;
904         uint32_t valid_win_num = 0;
905
906         /* Grab physical memory regions information from device tree. */
907         err = fdt_get_mem_regions(mr, &mr_cnt, &memsize);
908         if (err != 0)
909                 return (err);
910
911         for (i = 0; i < MV_WIN_DDR_MAX; i++)
912                 window_valid[i] = 0;
913
914         /* Try to match entries from device tree with settings from u-boot */
915         for (i = 0; i < mr_cnt; i++) {
916                 for (j = 0; j < MV_WIN_DDR_MAX; j++) {
917                         if (ddr_is_active(j) &&
918                             (ddr_base(j) == mr[i].mr_start) &&
919                             (ddr_size(j) == mr[i].mr_size)) {
920                                 window_valid[j] = 1;
921                                 valid_win_num++;
922                         }
923                 }
924         }
925
926         if (mr_cnt != valid_win_num)
927                 return (EINVAL);
928
929         /* Destroy windows without corresponding device tree entry */
930         for (j = 0; j < MV_WIN_DDR_MAX; j++) {
931                 if (ddr_is_active(j) && (window_valid[j] != 1)) {
932                         printf("Disabling SDRAM decoding window: %d\n", j);
933                         ddr_disable(j);
934                 }
935         }
936
937         return (0);
938 }
939 #endif
940 /*
941  * Check if we're able to cover all active DDR banks.
942  */
943 static int
944 decode_win_can_cover_ddr(int max)
945 {
946         int i, c;
947
948         c = 0;
949         for (i = 0; i < MV_WIN_DDR_MAX; i++)
950                 if (ddr_is_active(i))
951                         c++;
952
953         if (c > max) {
954                 printf("Unable to cover all active DDR banks: "
955                     "%d, available windows: %d\n", c, max);
956                 return (0);
957         }
958
959         return (1);
960 }
961
962 /**************************************************************************
963  * DDR windows routines
964  **************************************************************************/
965 int
966 ddr_is_active(int i)
967 {
968
969         if (ddr_sz_read(i) & 0x1)
970                 return (1);
971
972         return (0);
973 }
974
975 void
976 ddr_disable(int i)
977 {
978
979         ddr_sz_write(i, 0);
980         ddr_br_write(i, 0);
981 }
982
983 uint32_t
984 ddr_base(int i)
985 {
986
987         return (ddr_br_read(i) & 0xff000000);
988 }
989
990 uint32_t
991 ddr_size(int i)
992 {
993
994         return ((ddr_sz_read(i) | 0x00ffffff) + 1);
995 }
996
997 uint32_t
998 ddr_attr(int i)
999 {
1000         uint32_t dev, rev;
1001
1002         soc_id(&dev, &rev);
1003         if (dev == MV_DEV_88RC8180)
1004                 return ((ddr_sz_read(i) & 0xf0) >> 4);
1005         if (dev == MV_DEV_88F6781)
1006                 return (0);
1007
1008         return (i == 0 ? 0xe :
1009             (i == 1 ? 0xd :
1010             (i == 2 ? 0xb :
1011             (i == 3 ? 0x7 : 0xff))));
1012 }
1013
1014 uint32_t
1015 ddr_target(int i)
1016 {
1017         uint32_t dev, rev;
1018
1019         soc_id(&dev, &rev);
1020         if (dev == MV_DEV_88RC8180) {
1021                 i = (ddr_sz_read(i) & 0xf0) >> 4;
1022                 return (i == 0xe ? 0xc :
1023                     (i == 0xd ? 0xd :
1024                     (i == 0xb ? 0xe :
1025                     (i == 0x7 ? 0xf : 0xc))));
1026         }
1027
1028         /*
1029          * On SOCs other than 88RC8180 Mbus unit ID for
1030          * DDR SDRAM controller is always 0x0.
1031          */
1032         return (0);
1033 }
1034
1035 /**************************************************************************
1036  * USB windows routines
1037  **************************************************************************/
1038 static int
1039 decode_win_usb_valid(void)
1040 {
1041
1042         return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
1043 }
1044
1045 static void
1046 decode_win_usb_dump(u_long base)
1047 {
1048         int i;
1049
1050         if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port - 1)))
1051                 return;
1052
1053         for (i = 0; i < MV_WIN_USB_MAX; i++)
1054                 printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
1055                     win_usb_cr_read(base, i), win_usb_br_read(base, i));
1056 }
1057
1058 /*
1059  * Set USB decode windows.
1060  */
1061 static void
1062 decode_win_usb_setup(u_long base)
1063 {
1064         uint32_t br, cr;
1065         int i, j;
1066
1067
1068         if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port)))
1069                 return;
1070
1071         usb_port++;
1072
1073         for (i = 0; i < MV_WIN_USB_MAX; i++) {
1074                 win_usb_cr_write(base, i, 0);
1075                 win_usb_br_write(base, i, 0);
1076         }
1077
1078         /* Only access to active DRAM banks is required */
1079         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1080                 if (ddr_is_active(i)) {
1081                         br = ddr_base(i);
1082                         /*
1083                          * XXX for 6281 we should handle Mbus write
1084                          * burst limit field in the ctrl reg
1085                          */
1086                         cr = (((ddr_size(i) - 1) & 0xffff0000) |
1087                             (ddr_attr(i) << 8) |
1088                             (ddr_target(i) << 4) | 1);
1089
1090                         /* Set the first free USB window */
1091                         for (j = 0; j < MV_WIN_USB_MAX; j++) {
1092                                 if (win_usb_cr_read(base, j) & 0x1)
1093                                         continue;
1094
1095                                 win_usb_br_write(base, j, br);
1096                                 win_usb_cr_write(base, j, cr);
1097                                 break;
1098                         }
1099                 }
1100         }
1101 }
1102
1103 /**************************************************************************
1104  * ETH windows routines
1105  **************************************************************************/
1106
1107 static int
1108 win_eth_can_remap(int i)
1109 {
1110
1111         /* ETH encode windows 0-3 have remap capability */
1112         if (i < 4)
1113                 return (1);
1114
1115         return (0);
1116 }
1117
1118 static int
1119 eth_bare_read(uint32_t base, int i)
1120 {
1121         uint32_t v;
1122
1123         v = win_eth_bare_read(base);
1124         v &= (1 << i);
1125
1126         return (v >> i);
1127 }
1128
1129 static void
1130 eth_bare_write(uint32_t base, int i, int val)
1131 {
1132         uint32_t v;
1133
1134         v = win_eth_bare_read(base);
1135         v &= ~(1 << i);
1136         v |= (val << i);
1137         win_eth_bare_write(base, v);
1138 }
1139
1140 static void
1141 eth_epap_write(uint32_t base, int i, int val)
1142 {
1143         uint32_t v;
1144
1145         v = win_eth_epap_read(base);
1146         v &= ~(0x3 << (i * 2));
1147         v |= (val << (i * 2));
1148         win_eth_epap_write(base, v);
1149 }
1150
1151 static void
1152 decode_win_eth_dump(u_long base)
1153 {
1154         int i;
1155
1156         if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port - 1)))
1157                 return;
1158
1159         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
1160                 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
1161                     win_eth_br_read(base, i),
1162                     win_eth_sz_read(base, i));
1163
1164                 if (win_eth_can_remap(i))
1165                         printf(", ha 0x%08x",
1166                             win_eth_har_read(base, i));
1167
1168                 printf("\n");
1169         }
1170         printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
1171             win_eth_bare_read(base),
1172             win_eth_epap_read(base));
1173 }
1174
1175 #if defined(SOC_MV_LOKIPLUS)
1176 #define MV_WIN_ETH_DDR_TRGT(n)  0
1177 #else
1178 #define MV_WIN_ETH_DDR_TRGT(n)  ddr_target(n)
1179 #endif
1180
1181 static void
1182 decode_win_eth_setup(u_long base)
1183 {
1184         uint32_t br, sz;
1185         int i, j;
1186
1187         if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port)))
1188                 return;
1189
1190         eth_port++;
1191
1192         /* Disable, clear and revoke protection for all ETH windows */
1193         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
1194
1195                 eth_bare_write(base, i, 1);
1196                 eth_epap_write(base, i, 0);
1197                 win_eth_br_write(base, i, 0);
1198                 win_eth_sz_write(base, i, 0);
1199                 if (win_eth_can_remap(i))
1200                         win_eth_har_write(base, i, 0);
1201         }
1202
1203         /* Only access to active DRAM banks is required */
1204         for (i = 0; i < MV_WIN_DDR_MAX; i++)
1205                 if (ddr_is_active(i)) {
1206
1207                         br = ddr_base(i) | (ddr_attr(i) << 8) | MV_WIN_ETH_DDR_TRGT(i);
1208                         sz = ((ddr_size(i) - 1) & 0xffff0000);
1209
1210                         /* Set the first free ETH window */
1211                         for (j = 0; j < MV_WIN_ETH_MAX; j++) {
1212                                 if (eth_bare_read(base, j) == 0)
1213                                         continue;
1214
1215                                 win_eth_br_write(base, j, br);
1216                                 win_eth_sz_write(base, j, sz);
1217
1218                                 /* XXX remapping ETH windows not supported */
1219
1220                                 /* Set protection RW */
1221                                 eth_epap_write(base, j, 0x3);
1222
1223                                 /* Enable window */
1224                                 eth_bare_write(base, j, 0);
1225                                 break;
1226                         }
1227                 }
1228 }
1229
1230 static int
1231 decode_win_eth_valid(void)
1232 {
1233
1234         return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
1235 }
1236
1237 /**************************************************************************
1238  * PCIE windows routines
1239  **************************************************************************/
1240
1241 void
1242 decode_win_pcie_setup(u_long base)
1243 {
1244         uint32_t size = 0, ddrbase = ~0;
1245         uint32_t cr, br;
1246         int i, j;
1247
1248         for (i = 0; i < MV_PCIE_BAR_MAX; i++) {
1249                 pcie_bar_br_write(base, i,
1250                     MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1251                 if (i < 3)
1252                         pcie_bar_brh_write(base, i, 0);
1253                 if (i > 0)
1254                         pcie_bar_cr_write(base, i, 0);
1255         }
1256
1257         for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
1258                 win_pcie_cr_write(base, i, 0);
1259                 win_pcie_br_write(base, i, 0);
1260                 win_pcie_remap_write(base, i, 0);
1261         }
1262
1263         /* On End-Point only set BAR size to 1MB regardless of DDR size */
1264         if ((bus_space_read_4(fdtbus_bs_tag, base, MV_PCIE_CONTROL)
1265             & MV_PCIE_ROOT_CMPLX) == 0) {
1266                 pcie_bar_cr_write(base, 1, 0xf0000 | 1);
1267                 return;
1268         }
1269
1270         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
1271                 if (ddr_is_active(i)) {
1272                         /* Map DDR to BAR 1 */
1273                         cr = (ddr_size(i) - 1) & 0xffff0000;
1274                         size += ddr_size(i) & 0xffff0000;
1275                         cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
1276                         br = ddr_base(i);
1277                         if (br < ddrbase)
1278                                 ddrbase = br;
1279
1280                         /* Use the first available PCIE window */
1281                         for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
1282                                 if (win_pcie_cr_read(base, j) != 0)
1283                                         continue;
1284
1285                                 win_pcie_br_write(base, j, br);
1286                                 win_pcie_cr_write(base, j, cr);
1287                                 break;
1288                         }
1289                 }
1290         }
1291
1292         /*
1293          * Upper 16 bits in BAR register is interpreted as BAR size
1294          * (in 64 kB units) plus 64kB, so substract 0x10000
1295          * form value passed to register to get correct value.
1296          */
1297         size -= 0x10000;
1298         pcie_bar_cr_write(base, 1, size | 1);
1299         pcie_bar_br_write(base, 1, ddrbase |
1300             MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1301         pcie_bar_br_write(base, 0, fdt_immr_pa |
1302             MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
1303 }
1304
1305 static int
1306 decode_win_pcie_valid(void)
1307 {
1308
1309         return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
1310 }
1311
1312 /**************************************************************************
1313  * IDMA windows routines
1314  **************************************************************************/
1315 #if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
1316 static int
1317 idma_bare_read(u_long base, int i)
1318 {
1319         uint32_t v;
1320
1321         v = win_idma_bare_read(base);
1322         v &= (1 << i);
1323
1324         return (v >> i);
1325 }
1326
1327 static void
1328 idma_bare_write(u_long base, int i, int val)
1329 {
1330         uint32_t v;
1331
1332         v = win_idma_bare_read(base);
1333         v &= ~(1 << i);
1334         v |= (val << i);
1335         win_idma_bare_write(base, v);
1336 }
1337
1338 /*
1339  * Sets channel protection 'val' for window 'w' on channel 'c'
1340  */
1341 static void
1342 idma_cap_write(u_long base, int c, int w, int val)
1343 {
1344         uint32_t v;
1345
1346         v = win_idma_cap_read(base, c);
1347         v &= ~(0x3 << (w * 2));
1348         v |= (val << (w * 2));
1349         win_idma_cap_write(base, c, v);
1350 }
1351
1352 /*
1353  * Set protection 'val' on all channels for window 'w'
1354  */
1355 static void
1356 idma_set_prot(u_long base, int w, int val)
1357 {
1358         int c;
1359
1360         for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
1361                 idma_cap_write(base, c, w, val);
1362 }
1363
1364 static int
1365 win_idma_can_remap(int i)
1366 {
1367
1368         /* IDMA decode windows 0-3 have remap capability */
1369         if (i < 4)
1370                 return (1);
1371
1372         return (0);
1373 }
1374
1375 void
1376 decode_win_idma_setup(u_long base)
1377 {
1378         uint32_t br, sz;
1379         int i, j;
1380
1381         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
1382                 return;
1383         /*
1384          * Disable and clear all IDMA windows, revoke protection for all channels
1385          */
1386         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
1387
1388                 idma_bare_write(base, i, 1);
1389                 win_idma_br_write(base, i, 0);
1390                 win_idma_sz_write(base, i, 0);
1391                 if (win_idma_can_remap(i) == 1)
1392                         win_idma_har_write(base, i, 0);
1393         }
1394         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1395                 win_idma_cap_write(base, i, 0);
1396
1397         /*
1398          * Set up access to all active DRAM banks
1399          */
1400         for (i = 0; i < MV_WIN_DDR_MAX; i++)
1401                 if (ddr_is_active(i)) {
1402                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
1403                         sz = ((ddr_size(i) - 1) & 0xffff0000);
1404
1405                         /* Place DDR entries in non-remapped windows */
1406                         for (j = 0; j < MV_WIN_IDMA_MAX; j++)
1407                                 if (win_idma_can_remap(j) != 1 &&
1408                                     idma_bare_read(base, j) == 1) {
1409
1410                                         /* Configure window */
1411                                         win_idma_br_write(base, j, br);
1412                                         win_idma_sz_write(base, j, sz);
1413
1414                                         /* Set protection RW on all channels */
1415                                         idma_set_prot(base, j, 0x3);
1416
1417                                         /* Enable window */
1418                                         idma_bare_write(base, j, 0);
1419                                         break;
1420                                 }
1421                 }
1422
1423         /*
1424          * Remaining targets -- from statically defined table
1425          */
1426         for (i = 0; i < idma_wins_no; i++)
1427                 if (idma_wins[i].target > 0) {
1428                         br = (idma_wins[i].base & 0xffff0000) |
1429                             (idma_wins[i].attr << 8) | idma_wins[i].target;
1430                         sz = ((idma_wins[i].size - 1) & 0xffff0000);
1431
1432                         /* Set the first free IDMA window */
1433                         for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
1434                                 if (idma_bare_read(base, j) == 0)
1435                                         continue;
1436
1437                                 /* Configure window */
1438                                 win_idma_br_write(base, j, br);
1439                                 win_idma_sz_write(base, j, sz);
1440                                 if (win_idma_can_remap(j) &&
1441                                     idma_wins[j].remap >= 0)
1442                                         win_idma_har_write(base, j,
1443                                             idma_wins[j].remap);
1444
1445                                 /* Set protection RW on all channels */
1446                                 idma_set_prot(base, j, 0x3);
1447
1448                                 /* Enable window */
1449                                 idma_bare_write(base, j, 0);
1450                                 break;
1451                         }
1452                 }
1453 }
1454
1455 int
1456 decode_win_idma_valid(void)
1457 {
1458         const struct decode_win *wintab;
1459         int c, i, j, rv;
1460         uint32_t b, e, s;
1461
1462         if (idma_wins_no > MV_WIN_IDMA_MAX) {
1463                 printf("IDMA windows: too many entries: %d\n", idma_wins_no);
1464                 return (0);
1465         }
1466         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1467                 if (ddr_is_active(i))
1468                         c++;
1469
1470         if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
1471                 printf("IDMA windows: too many entries: %d, available: %d\n",
1472                     idma_wins_no, MV_WIN_IDMA_MAX - c);
1473                 return (0);
1474         }
1475
1476         wintab = idma_wins;
1477         rv = 1;
1478         for (i = 0; i < idma_wins_no; i++, wintab++) {
1479
1480                 if (wintab->target == 0) {
1481                         printf("IDMA window#%d: DDR target window is not "
1482                             "supposed to be reprogrammed!\n", i);
1483                         rv = 0;
1484                 }
1485
1486                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1487                         printf("IDMA window#%d: not capable of remapping, but "
1488                             "val 0x%08x defined\n", i, wintab->remap);
1489                         rv = 0;
1490                 }
1491
1492                 s = wintab->size;
1493                 b = wintab->base;
1494                 e = b + s - 1;
1495                 if (s > (0xFFFFFFFF - b + 1)) {
1496                         /* XXX this boundary check should account for 64bit and
1497                          * remapping.. */
1498                         printf("IDMA window#%d: no space for size 0x%08x at "
1499                             "0x%08x\n", i, s, b);
1500                         rv = 0;
1501                         continue;
1502                 }
1503
1504                 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
1505                 if (j >= 0) {
1506                         printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
1507                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
1508                             idma_wins[j].base,
1509                             idma_wins[j].base + idma_wins[j].size - 1);
1510                         rv = 0;
1511                 }
1512         }
1513
1514         return (rv);
1515 }
1516
1517 void
1518 decode_win_idma_dump(u_long base)
1519 {
1520         int i;
1521
1522         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
1523                 return;
1524
1525         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
1526                 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
1527                     win_idma_br_read(base, i), win_idma_sz_read(base, i));
1528                 
1529                 if (win_idma_can_remap(i))
1530                         printf(", ha 0x%08x", win_idma_har_read(base, i));
1531
1532                 printf("\n");
1533         }
1534         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1535                 printf("IDMA channel#%d: ap 0x%08x\n", i,
1536                     win_idma_cap_read(base, i));
1537         printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read(base));
1538 }
1539 #else
1540
1541 /* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
1542 int
1543 decode_win_idma_valid(void)
1544 {
1545
1546         return (1);
1547 }
1548
1549 void
1550 decode_win_idma_setup(u_long base)
1551 {
1552 }
1553
1554 void
1555 decode_win_idma_dump(u_long base)
1556 {
1557 }
1558 #endif
1559
1560 /**************************************************************************
1561  * XOR windows routines
1562  **************************************************************************/
1563 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
1564 static int
1565 xor_ctrl_read(u_long base, int i, int c, int e)
1566 {
1567         uint32_t v;
1568         v = win_xor_ctrl_read(base, c, e);
1569         v &= (1 << i);
1570
1571         return (v >> i);
1572 }
1573
1574 static void
1575 xor_ctrl_write(u_long base, int i, int c, int e, int val)
1576 {
1577         uint32_t v;
1578
1579         v = win_xor_ctrl_read(base, c, e);
1580         v &= ~(1 << i);
1581         v |= (val << i);
1582         win_xor_ctrl_write(base, c, e, v);
1583 }
1584
1585 /*
1586  * Set channel protection 'val' for window 'w' on channel 'c'
1587  */
1588 static void
1589 xor_chan_write(u_long base, int c, int e, int w, int val)
1590 {
1591         uint32_t v;
1592
1593         v = win_xor_ctrl_read(base, c, e);
1594         v &= ~(0x3 << (w * 2 + 16));
1595         v |= (val << (w * 2 + 16));
1596         win_xor_ctrl_write(base, c, e, v);
1597 }
1598
1599 /*
1600  * Set protection 'val' on all channels for window 'w' on engine 'e'
1601  */
1602 static void
1603 xor_set_prot(u_long base, int w, int e, int val)
1604 {
1605         int c;
1606
1607         for (c = 0; c < MV_XOR_CHAN_MAX; c++)
1608                 xor_chan_write(base, c, e, w, val);
1609 }
1610
1611 static int
1612 win_xor_can_remap(int i)
1613 {
1614
1615         /* XOR decode windows 0-3 have remap capability */
1616         if (i < 4)
1617                 return (1);
1618
1619         return (0);
1620 }
1621
1622 static int
1623 xor_max_eng(void)
1624 {
1625         uint32_t dev, rev;
1626
1627         soc_id(&dev, &rev);
1628         switch (dev) {
1629         case MV_DEV_88F6281:
1630         case MV_DEV_88F6282:
1631         case MV_DEV_MV78130:
1632         case MV_DEV_MV78160:
1633         case MV_DEV_MV78230:
1634         case MV_DEV_MV78260:
1635         case MV_DEV_MV78460:
1636                 return (2);
1637         case MV_DEV_MV78100:
1638         case MV_DEV_MV78100_Z0:
1639                 return (1);
1640         default:
1641                 return (0);
1642         }
1643 }
1644
1645 static void
1646 xor_active_dram(u_long base, int c, int e, int *window)
1647 {
1648         uint32_t br, sz;
1649         int i, m, w;
1650
1651         /*
1652          * Set up access to all active DRAM banks
1653          */
1654         m = xor_max_eng();
1655         for (i = 0; i < m; i++)
1656                 if (ddr_is_active(i)) {
1657                         br = ddr_base(i) | (ddr_attr(i) << 8) |
1658                             ddr_target(i);
1659                         sz = ((ddr_size(i) - 1) & 0xffff0000);
1660
1661                         /* Place DDR entries in non-remapped windows */
1662                         for (w = 0; w < MV_WIN_XOR_MAX; w++)
1663                                 if (win_xor_can_remap(w) != 1 &&
1664                                     (xor_ctrl_read(base, w, c, e) == 0) &&
1665                                     w > *window) {
1666                                         /* Configure window */
1667                                         win_xor_br_write(base, w, e, br);
1668                                         win_xor_sz_write(base, w, e, sz);
1669
1670                                         /* Set protection RW on all channels */
1671                                         xor_set_prot(base, w, e, 0x3);
1672
1673                                         /* Enable window */
1674                                         xor_ctrl_write(base, w, c, e, 1);
1675                                         (*window)++;
1676                                         break;
1677                                 }
1678                 }
1679 }
1680
1681 void
1682 decode_win_xor_setup(u_long base)
1683 {
1684         uint32_t br, sz;
1685         int i, j, z, e = 1, m, window;
1686
1687         if (pm_is_disabled(CPU_PM_CTRL_XOR))
1688                 return;
1689
1690         /*
1691          * Disable and clear all XOR windows, revoke protection for all
1692          * channels
1693          */
1694         m = xor_max_eng();
1695         for (j = 0; j < m; j++, e--) {
1696
1697                 /* Number of non-remaped windows */
1698                 window = MV_XOR_NON_REMAP - 1;
1699
1700                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1701                         win_xor_br_write(base, i, e, 0);
1702                         win_xor_sz_write(base, i, e, 0);
1703                 }
1704
1705                 if (win_xor_can_remap(i) == 1)
1706                         win_xor_har_write(base, i, e, 0);
1707
1708                 for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
1709                         win_xor_ctrl_write(base, i, e, 0);
1710                         xor_active_dram(base, i, e, &window);
1711                 }
1712
1713                 /*
1714                  * Remaining targets -- from a statically defined table
1715                  */
1716                 for (i = 0; i < xor_wins_no; i++)
1717                         if (xor_wins[i].target > 0) {
1718                                 br = (xor_wins[i].base & 0xffff0000) |
1719                                     (xor_wins[i].attr << 8) |
1720                                     xor_wins[i].target;
1721                                 sz = ((xor_wins[i].size - 1) & 0xffff0000);
1722
1723                                 /* Set the first free XOR window */
1724                                 for (z = 0; z < MV_WIN_XOR_MAX; z++) {
1725                                         if (xor_ctrl_read(base, z, 0, e) &&
1726                                             xor_ctrl_read(base, z, 1, e))
1727                                                 continue;
1728
1729                                         /* Configure window */
1730                                         win_xor_br_write(base, z, e, br);
1731                                         win_xor_sz_write(base, z, e, sz);
1732                                         if (win_xor_can_remap(z) &&
1733                                             xor_wins[z].remap >= 0)
1734                                                 win_xor_har_write(base, z, e,
1735                                                     xor_wins[z].remap);
1736
1737                                         /* Set protection RW on all channels */
1738                                         xor_set_prot(base, z, e, 0x3);
1739
1740                                         /* Enable window */
1741                                         xor_ctrl_write(base, z, 0, e, 1);
1742                                         xor_ctrl_write(base, z, 1, e, 1);
1743                                         break;
1744                                 }
1745                         }
1746         }
1747 }
1748
1749 int
1750 decode_win_xor_valid(void)
1751 {
1752         const struct decode_win *wintab;
1753         int c, i, j, rv;
1754         uint32_t b, e, s;
1755
1756         if (xor_wins_no > MV_WIN_XOR_MAX) {
1757                 printf("XOR windows: too many entries: %d\n", xor_wins_no);
1758                 return (0);
1759         }
1760         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1761                 if (ddr_is_active(i))
1762                         c++;
1763
1764         if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
1765                 printf("XOR windows: too many entries: %d, available: %d\n",
1766                     xor_wins_no, MV_WIN_IDMA_MAX - c);
1767                 return (0);
1768         }
1769
1770         wintab = xor_wins;
1771         rv = 1;
1772         for (i = 0; i < xor_wins_no; i++, wintab++) {
1773
1774                 if (wintab->target == 0) {
1775                         printf("XOR window#%d: DDR target window is not "
1776                             "supposed to be reprogrammed!\n", i);
1777                         rv = 0;
1778                 }
1779
1780                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1781                         printf("XOR window#%d: not capable of remapping, but "
1782                             "val 0x%08x defined\n", i, wintab->remap);
1783                         rv = 0;
1784                 }
1785
1786                 s = wintab->size;
1787                 b = wintab->base;
1788                 e = b + s - 1;
1789                 if (s > (0xFFFFFFFF - b + 1)) {
1790                         /*
1791                          * XXX this boundary check should account for 64bit
1792                          * and remapping..
1793                          */
1794                         printf("XOR window#%d: no space for size 0x%08x at "
1795                             "0x%08x\n", i, s, b);
1796                         rv = 0;
1797                         continue;
1798                 }
1799
1800                 j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
1801                 if (j >= 0) {
1802                         printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
1803                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
1804                             xor_wins[j].base,
1805                             xor_wins[j].base + xor_wins[j].size - 1);
1806                         rv = 0;
1807                 }
1808         }
1809
1810         return (rv);
1811 }
1812
1813 void
1814 decode_win_xor_dump(u_long base)
1815 {
1816         int i, j;
1817         int e = 1;
1818
1819         if (pm_is_disabled(CPU_PM_CTRL_XOR))
1820                 return;
1821
1822         for (j = 0; j < xor_max_eng(); j++, e--) {
1823                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1824                         printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
1825                             win_xor_br_read(base, i, e), win_xor_sz_read(base, i, e));
1826
1827                         if (win_xor_can_remap(i))
1828                                 printf(", ha 0x%08x", win_xor_har_read(base, i, e));
1829
1830                         printf("\n");
1831                 }
1832                 for (i = 0; i < MV_XOR_CHAN_MAX; i++)
1833                         printf("XOR control#%d: 0x%08x\n", i,
1834                             win_xor_ctrl_read(base, i, e));
1835         }
1836 }
1837
1838 #else
1839 /* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
1840 static int
1841 decode_win_xor_valid(void)
1842 {
1843
1844         return (1);
1845 }
1846
1847 static void
1848 decode_win_xor_setup(u_long base)
1849 {
1850 }
1851
1852 static void
1853 decode_win_xor_dump(u_long base)
1854 {
1855 }
1856 #endif
1857
1858 /**************************************************************************
1859  * SATA windows routines
1860  **************************************************************************/
1861 static void
1862 decode_win_sata_setup(u_long base)
1863 {
1864         uint32_t cr, br;
1865         int i, j;
1866
1867         if (pm_is_disabled(CPU_PM_CTRL_SATA))
1868                 return;
1869
1870         for (i = 0; i < MV_WIN_SATA_MAX; i++) {
1871                 win_sata_cr_write(base, i, 0);
1872                 win_sata_br_write(base, i, 0);
1873         }
1874
1875         for (i = 0; i < MV_WIN_DDR_MAX; i++)
1876                 if (ddr_is_active(i)) {
1877                         cr = ((ddr_size(i) - 1) & 0xffff0000) |
1878                             (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
1879                         br = ddr_base(i);
1880
1881                         /* Use the first available SATA window */
1882                         for (j = 0; j < MV_WIN_SATA_MAX; j++) {
1883                                 if ((win_sata_cr_read(base, j) & 1) != 0)
1884                                         continue;
1885
1886                                 win_sata_br_write(base, j, br);
1887                                 win_sata_cr_write(base, j, cr);
1888                                 break;
1889                         }
1890                 }
1891 }
1892
1893 static int
1894 decode_win_sata_valid(void)
1895 {
1896         uint32_t dev, rev;
1897
1898         soc_id(&dev, &rev);
1899         if (dev == MV_DEV_88F5281)
1900                 return (1);
1901
1902         return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
1903 }
1904
1905 /**************************************************************************
1906  * FDT parsing routines.
1907  **************************************************************************/
1908
1909 static int
1910 fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples,
1911     int *tuplesize)
1912 {
1913         phandle_t node;
1914         pcell_t addr_cells, par_addr_cells, size_cells;
1915         int len, tuple_size, tuples_count;
1916
1917         node = OF_finddevice(nodename);
1918         if (node == -1)
1919                 return (EINVAL);
1920
1921         if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
1922                 return (ENXIO);
1923
1924         par_addr_cells = fdt_parent_addr_cells(node);
1925         if (par_addr_cells > 2)
1926                 return (ERANGE);
1927
1928         tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
1929             size_cells);
1930
1931         /* Note the OF_getprop_alloc() cannot be used at this early stage. */
1932         len = OF_getprop(node, "ranges", buf, size);
1933
1934         /*
1935          * XXX this does not handle the empty 'ranges;' case, which is
1936          * legitimate and should be allowed.
1937          */
1938         tuples_count = len / tuple_size;
1939         if (tuples_count <= 0)
1940                 return (ERANGE);
1941
1942         if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2)
1943                 return (ERANGE);
1944
1945         *tuples = tuples_count;
1946         *tuplesize = tuple_size;
1947         return (0);
1948 }
1949
1950 static int
1951 win_cpu_from_dt(void)
1952 {
1953         pcell_t ranges[48];
1954         phandle_t node;
1955         int i, entry_size, err, t, tuple_size, tuples;
1956         u_long sram_base, sram_size;
1957
1958         t = 0;
1959         /* Retrieve 'ranges' property of '/localbus' node. */
1960         if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges),
1961             &tuples, &tuple_size)) == 0) {
1962                 /*
1963                  * Fill CPU decode windows table.
1964                  */
1965                 bzero((void *)&cpu_win_tbl, sizeof(cpu_win_tbl));
1966
1967                 entry_size = tuple_size / sizeof(pcell_t);
1968                 cpu_wins_no = tuples;
1969
1970                 for (i = 0, t = 0; t < tuples; i += entry_size, t++) {
1971                         cpu_win_tbl[t].target = 1;
1972                         cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]);
1973                         cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]);
1974                         cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]);
1975                         cpu_win_tbl[t].remap = ~0;
1976                         debugf("target = 0x%0x attr = 0x%0x base = 0x%0x "
1977                             "size = 0x%0x remap = 0x%0x\n",
1978                             cpu_win_tbl[t].target,
1979                             cpu_win_tbl[t].attr, cpu_win_tbl[t].base,
1980                             cpu_win_tbl[t].size, cpu_win_tbl[t].remap);
1981                 }
1982         }
1983
1984         /*
1985          * Retrieve CESA SRAM data.
1986          */
1987         if ((node = OF_finddevice("sram")) != -1)
1988                 if (fdt_is_compatible(node, "mrvl,cesa-sram"))
1989                         goto moveon;
1990
1991         if ((node = OF_finddevice("/")) == 0)
1992                 return (ENXIO);
1993
1994         if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
1995                 /* SRAM block is not always present. */
1996                 return (0);
1997 moveon:
1998         sram_base = sram_size = 0;
1999         if (fdt_regsize(node, &sram_base, &sram_size) != 0)
2000                 return (EINVAL);
2001
2002         cpu_win_tbl[t].target = MV_WIN_CESA_TARGET;
2003         cpu_win_tbl[t].attr = MV_WIN_CESA_ATTR(1);
2004         cpu_win_tbl[t].base = sram_base;
2005         cpu_win_tbl[t].size = sram_size;
2006         cpu_win_tbl[t].remap = ~0;
2007         cpu_wins_no++;
2008         debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
2009
2010         return (0);
2011 }
2012
2013 static int
2014 fdt_win_setup(void)
2015 {
2016         phandle_t node, child;
2017         struct soc_node_spec *soc_node;
2018         u_long size, base;
2019         int err, i;
2020
2021         node = OF_finddevice("/");
2022         if (node == -1)
2023                 panic("fdt_win_setup: no root node");
2024
2025         /*
2026          * Traverse through all children of root and simple-bus nodes.
2027          * For each found device retrieve decode windows data (if applicable).
2028          */
2029         child = OF_child(node);
2030         while (child != 0) {
2031                 for (i = 0; soc_nodes[i].compat != NULL; i++) {
2032
2033                         soc_node = &soc_nodes[i];
2034
2035                         if (!fdt_is_compatible(child, soc_node->compat))
2036                                 continue;
2037
2038                         err = fdt_regsize(child, &base, &size);
2039                         if (err != 0)
2040                                 return (err);
2041
2042                         base = (base & 0x000fffff) | fdt_immr_va;
2043                         if (soc_node->decode_handler != NULL)
2044                                 soc_node->decode_handler(base);
2045                         else
2046                                 return (ENXIO);
2047
2048                         if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
2049                                 soc_node->dump_handler(base);
2050                 }
2051
2052                 /*
2053                  * Once done with root-level children let's move down to
2054                  * simple-bus and its children.
2055                  */
2056                 child = OF_peer(child);
2057                 if ((child == 0) && (node == OF_finddevice("/"))) {
2058                         node = fdt_find_compatible(node, "simple-bus", 1);
2059                         if (node == 0)
2060                                 return (ENXIO);
2061                         child = OF_child(node);
2062                 }
2063         }
2064
2065         return (0);
2066 }
2067
2068 static void
2069 fdt_fixup_busfreq(phandle_t root)
2070 {
2071         phandle_t sb;
2072         pcell_t freq;
2073
2074         freq = cpu_to_fdt32(get_tclk());
2075
2076         /*
2077          * Fix bus speed in cpu node
2078          */
2079         if ((sb = OF_finddevice("cpu")) != 0)
2080                 if (fdt_is_compatible_strict(sb, "ARM,88VS584"))
2081                         OF_setprop(sb, "bus-frequency", (void *)&freq,
2082                             sizeof(freq));
2083
2084         /*
2085          * This fixup sets the simple-bus bus-frequency property.
2086          */
2087         if ((sb = fdt_find_compatible(root, "simple-bus", 1)) != 0)
2088                 OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
2089 }
2090
2091 static void
2092 fdt_fixup_ranges(phandle_t root)
2093 {
2094         phandle_t node;
2095         pcell_t par_addr_cells, addr_cells, size_cells;
2096         pcell_t ranges[3], reg[2], *rangesptr;
2097         int len, tuple_size, tuples_count;
2098         uint32_t base;
2099
2100         /* Fix-up SoC ranges according to real fdt_immr_pa */
2101         if ((node = fdt_find_compatible(root, "simple-bus", 1)) != 0) {
2102                 if (fdt_addrsize_cells(node, &addr_cells, &size_cells) == 0 &&
2103                     (par_addr_cells = fdt_parent_addr_cells(node) <= 2)) {
2104                         tuple_size = sizeof(pcell_t) * (par_addr_cells +
2105                            addr_cells + size_cells);
2106                         len = OF_getprop(node, "ranges", ranges,
2107                             sizeof(ranges));
2108                         tuples_count = len / tuple_size;
2109                         /* Unexpected settings are not supported */
2110                         if (tuples_count != 1)
2111                                 goto fixup_failed;
2112
2113                         rangesptr = &ranges[0];
2114                         rangesptr += par_addr_cells;
2115                         base = fdt_data_get((void *)rangesptr, addr_cells);
2116                         *rangesptr = cpu_to_fdt32(fdt_immr_pa);
2117                         if (OF_setprop(node, "ranges", (void *)&ranges[0],
2118                             sizeof(ranges)) < 0)
2119                                 goto fixup_failed;
2120                 }
2121         }
2122
2123         /* Fix-up PCIe reg according to real PCIe registers' PA */
2124         if ((node = fdt_find_compatible(root, "mrvl,pcie", 1)) != 0) {
2125                 if (fdt_addrsize_cells(OF_parent(node), &par_addr_cells,
2126                     &size_cells) == 0) {
2127                         tuple_size = sizeof(pcell_t) * (par_addr_cells +
2128                             size_cells);
2129                         len = OF_getprop(node, "reg", reg, sizeof(reg));
2130                         tuples_count = len / tuple_size;
2131                         /* Unexpected settings are not supported */
2132                         if (tuples_count != 1)
2133                                 goto fixup_failed;
2134
2135                         base = fdt_data_get((void *)&reg[0], par_addr_cells);
2136                         base &= ~0xFF000000;
2137                         base |= fdt_immr_pa;
2138                         reg[0] = cpu_to_fdt32(base);
2139                         if (OF_setprop(node, "reg", (void *)&reg[0],
2140                             sizeof(reg)) < 0)
2141                                 goto fixup_failed;
2142                 }
2143         }
2144         /* Fix-up succeeded. May return and continue */
2145         return;
2146
2147 fixup_failed:
2148         while (1) {
2149                 /*
2150                  * In case of any error while fixing ranges just hang.
2151                  *      1. No message can be displayed yet since console
2152                  *         is not initialized.
2153                  *      2. Going further will cause failure on bus_space_map()
2154                  *         relying on the wrong ranges or data abort when
2155                  *         accessing PCIe registers.
2156                  */
2157         }
2158 }
2159
2160 struct fdt_fixup_entry fdt_fixup_table[] = {
2161         { "mrvl,DB-88F6281", &fdt_fixup_busfreq },
2162         { "mrvl,DB-78460", &fdt_fixup_busfreq },
2163         { "mrvl,DB-78460", &fdt_fixup_ranges },
2164         { NULL, NULL }
2165 };
2166
2167 static int
2168 fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
2169     int *pol)
2170 {
2171
2172         if (!fdt_is_compatible(node, "mrvl,pic") &&
2173             !fdt_is_compatible(node, "mrvl,mpic"))
2174                 return (ENXIO);
2175
2176         *interrupt = fdt32_to_cpu(intr[0]);
2177         *trig = INTR_TRIGGER_CONFORM;
2178         *pol = INTR_POLARITY_CONFORM;
2179
2180         return (0);
2181 }
2182
2183 fdt_pic_decode_t fdt_pic_table[] = {
2184         &fdt_pic_decode_ic,
2185         NULL
2186 };
2187
2188 uint64_t
2189 get_sar_value(void)
2190 {
2191         uint32_t sar_low, sar_high;
2192
2193 #if defined(SOC_MV_ARMADAXP)
2194         sar_high = bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE,
2195             SAMPLE_AT_RESET_HI);
2196         sar_low = bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE,
2197             SAMPLE_AT_RESET_LO);
2198 #else
2199         /*
2200          * TODO: Add getting proper values for other SoC configurations
2201          */
2202         sar_high = 0;
2203         sar_low = 0;
2204 #endif
2205
2206         return (((uint64_t)sar_high << 32) | sar_low);
2207 }