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