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