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