]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/arm/mv/common.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / arm / mv / common.c
1 /*-
2  * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
3  * All rights reserved.
4  *
5  * Developed by Semihalf.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of MARVELL nor the names of contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/bus.h>
38 #include <sys/kernel.h>
39
40 #include <machine/bus.h>
41
42 #include <arm/mv/mvreg.h>
43 #include <arm/mv/mvvar.h>
44 #include <arm/mv/mvwin.h>
45
46 static int win_eth_can_remap(int i);
47
48 static int decode_win_cpu_valid(void);
49 static int decode_win_usb_valid(void);
50 static int decode_win_eth_valid(void);
51 static int decode_win_pcie_valid(void);
52 static int decode_win_sata_valid(void);
53 static int decode_win_cesa_valid(void);
54
55 static void decode_win_cpu_setup(void);
56 static void decode_win_usb_setup(void);
57 static void decode_win_eth_setup(uint32_t base);
58 static void decode_win_pcie_setup(uint32_t base);
59 static void decode_win_sata_setup(void);
60 static void decode_win_cesa_setup(void);
61
62 static void decode_win_cesa_dump(void);
63 static void decode_win_usb_dump(void);
64
65 static uint32_t used_cpu_wins;
66
67 static __inline int
68 pm_is_disabled(uint32_t mask)
69 {
70
71         return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
72 }
73
74 static __inline uint32_t
75 obio_get_pm_mask(uint32_t base)
76 {
77         struct obio_device *od;
78
79         for (od = obio_devices; od->od_name != NULL; od++)
80                 if (od->od_base == base)
81                         return (od->od_pwr_mask);
82
83         return (CPU_PM_CTRL_NONE);
84 }
85
86 /*
87  * Disable device using power management register.
88  * 1 - Device Power On
89  * 0 - Device Power Off
90  * Mask can be set in loader.
91  * EXAMPLE:
92  * loader> set hw.pm-disable-mask=0x2
93  *
94  * Common mask:
95  * |-------------------------------|
96  * | Device | Kirkwood | Discovery |
97  * |-------------------------------|
98  * | USB0   | 0x00008  | 0x020000  |
99  * |-------------------------------|
100  * | USB1   |     -    | 0x040000  |
101  * |-------------------------------|
102  * | USB2   |     -    | 0x080000  |
103  * |-------------------------------|
104  * | GE0    | 0x00001  | 0x000002  |
105  * |-------------------------------|
106  * | GE1    |     -    | 0x000004  |
107  * |-------------------------------|
108  * | IDMA   |     -    | 0x100000  |
109  * |-------------------------------|
110  * | XOR    | 0x10000  | 0x200000  |
111  * |-------------------------------|
112  * | CESA   | 0x20000  | 0x400000  |
113  * |-------------------------------|
114  * | SATA   | 0x04000  | 0x004000  |
115  * --------------------------------|
116  * This feature can be used only on Kirkwood and Discovery
117  * machines.
118  */
119 static __inline void
120 pm_disable_device(int mask)
121 {
122 #ifdef DIAGNOSTIC
123         uint32_t reg;
124
125         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
126         printf("Power Management Register: 0%x\n", reg);
127
128         reg &= ~mask;
129         soc_power_ctrl_set(reg);
130         printf("Device %x is disabled\n", mask);
131
132         reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
133         printf("Power Management Register: 0%x\n", reg);
134 #endif
135 }
136
137 uint32_t
138 read_cpu_ctrl(uint32_t reg)
139 {
140
141         return (bus_space_read_4(obio_tag, MV_CPU_CONTROL_BASE, reg));
142 }
143
144 void
145 write_cpu_ctrl(uint32_t reg, uint32_t val)
146 {
147
148         bus_space_write_4(obio_tag, MV_CPU_CONTROL_BASE, reg, val);
149 }
150
151 void
152 cpu_reset(void)
153 {
154
155         write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
156         write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
157         while (1);
158 }
159
160 uint32_t
161 cpu_extra_feat(void)
162 {
163         uint32_t dev, rev;
164         uint32_t ef = 0;
165
166         soc_id(&dev, &rev);
167         if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100_Z0 ||
168             dev == MV_DEV_MV78100)
169                 __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
170         else if (dev == MV_DEV_88F5182 || dev == MV_DEV_88F5281)
171                 __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
172         else if (bootverbose)
173                 printf("This ARM Core does not support any extra features\n");
174
175         return (ef);
176 }
177
178 /*
179  * Get the power status of device. This feature is only supported on
180  * Kirkwood and Discovery SoCs.
181  */
182 uint32_t
183 soc_power_ctrl_get(uint32_t mask)
184 {
185
186 #ifndef SOC_MV_ORION
187         if (mask != CPU_PM_CTRL_NONE)
188                 mask &= read_cpu_ctrl(CPU_PM_CTRL);
189
190         return (mask);
191 #else
192         return (mask);
193 #endif
194 }
195
196 /*
197  * Set the power status of device. This feature is only supported on
198  * Kirkwood and Discovery SoCs.
199  */
200 void
201 soc_power_ctrl_set(uint32_t mask)
202 {
203
204 #ifndef SOC_MV_ORION
205         if (mask != CPU_PM_CTRL_NONE)
206                 write_cpu_ctrl(CPU_PM_CTRL, mask);
207 #endif
208 }
209
210 void
211 soc_id(uint32_t *dev, uint32_t *rev)
212 {
213
214         /*
215          * Notice: system identifiers are available in the registers range of
216          * PCIE controller, so using this function is only allowed (and
217          * possible) after the internal registers range has been mapped in via
218          * pmap_devmap_bootstrap().
219          */
220         *dev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 0) >> 16;
221         *rev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 8) & 0xff;
222 }
223
224 void
225 soc_identify(void)
226 {
227         uint32_t d, r;
228         const char *dev;
229         const char *rev;
230
231         soc_id(&d, &r);
232
233         printf("SOC: ");
234         if (bootverbose)
235                 printf("(0x%4x:0x%02x) ", d, r);
236
237         rev = "";
238         switch (d) {
239         case MV_DEV_88F5181:
240                 dev = "Marvell 88F5181";
241                 if (r == 3)
242                         rev = "B1";
243                 break;
244         case MV_DEV_88F5182:
245                 dev = "Marvell 88F5182";
246                 if (r == 2)
247                         rev = "A2";
248                 break;
249         case MV_DEV_88F5281:
250                 dev = "Marvell 88F5281";
251                 if (r == 4)
252                         rev = "D0";
253                 else if (r == 5)
254                         rev = "D1";
255                 else if (r == 6)
256                         rev = "D2";
257                 break;
258         case MV_DEV_88F6281:
259                 dev = "Marvell 88F6281";
260                 if (r == 0)
261                         rev = "Z0";
262                 else if (r == 2)
263                         rev = "A0";
264                 else if (r == 3)
265                         rev = "A1";
266                 break;
267         case MV_DEV_MV78100_Z0:
268                 dev = "Marvell MV78100 Z0";
269                 break;
270         case MV_DEV_MV78100:
271                 dev = "Marvell MV78100";
272                 break;
273         default:
274                 dev = "UNKNOWN";
275                 break;
276         }
277
278         printf("%s", dev);
279         if (*rev != '\0')
280                 printf(" rev %s", rev);
281         printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
282
283         /* TODO add info on currently set endianess */
284 }
285
286 int
287 soc_decode_win(void)
288 {
289         uint32_t dev, rev;
290         int mask;
291
292         mask = 0;
293         TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
294
295         if (mask != 0)
296                 pm_disable_device(mask);
297
298         /* Retrieve our ID: some windows facilities vary between SoC models */
299         soc_id(&dev, &rev);
300
301         if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
302             decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
303             decode_win_pcie_valid() != 1 || decode_win_sata_valid() != 1 ||
304             decode_win_cesa_valid() != 1)
305                 return(-1);
306
307         decode_win_cpu_setup();
308         decode_win_usb_setup();
309         decode_win_eth_setup(MV_ETH0_BASE);
310         if (dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0)
311                 decode_win_eth_setup(MV_ETH1_BASE);
312         if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100 ||
313             dev == MV_DEV_MV78100_Z0)
314                 decode_win_cesa_setup();
315
316         decode_win_idma_setup();
317         decode_win_xor_setup();
318
319         if (dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0) {
320                 decode_win_pcie_setup(MV_PCIE00_BASE);
321                 decode_win_pcie_setup(MV_PCIE01_BASE);
322                 decode_win_pcie_setup(MV_PCIE02_BASE);
323                 decode_win_pcie_setup(MV_PCIE03_BASE);
324                 decode_win_pcie_setup(MV_PCIE10_BASE);
325                 decode_win_pcie_setup(MV_PCIE11_BASE);
326                 decode_win_pcie_setup(MV_PCIE12_BASE);
327                 decode_win_pcie_setup(MV_PCIE13_BASE);
328         } else
329                 decode_win_pcie_setup(MV_PCIE_BASE);
330
331         if (dev != MV_DEV_88F5281)
332                 decode_win_sata_setup();
333
334         return (0);
335 }
336
337 /**************************************************************************
338  * Decode windows registers accessors
339  **************************************************************************/
340 WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
341 WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
342 WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
343 WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
344 WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
345 WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
346 WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
347 WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
348
349 WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
350 WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
351
352 WIN_REG_IDX_RD2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
353 WIN_REG_IDX_RD2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
354 WIN_REG_IDX_WR2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
355 WIN_REG_IDX_WR2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
356
357 WIN_REG_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
358 WIN_REG_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
359 WIN_REG_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
360 WIN_REG_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
361
362 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
363 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
364 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
365 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
366 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
367 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
368
369 WIN_REG_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
370 WIN_REG_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
371 WIN_REG_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
372 WIN_REG_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
373 WIN_REG_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
374 WIN_REG_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
375 WIN_REG_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
376 WIN_REG_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
377
378 WIN_REG_BASE_RD(win_eth, bare, 0x290)
379 WIN_REG_BASE_RD(win_eth, epap, 0x294)
380 WIN_REG_BASE_WR(win_eth, bare, 0x290)
381 WIN_REG_BASE_WR(win_eth, epap, 0x294)
382
383 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
384 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
385 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
386 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
387 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
388 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
389 WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
390
391 WIN_REG_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
392 WIN_REG_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
393 WIN_REG_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
394 WIN_REG_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
395 WIN_REG_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
396 WIN_REG_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
397 WIN_REG_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
398 WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
399 WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
400 WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
401
402 WIN_REG_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
403 WIN_REG_IDX_RD(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
404 WIN_REG_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
405 WIN_REG_IDX_WR(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
406
407 /**************************************************************************
408  * Decode windows helper routines
409  **************************************************************************/
410 void
411 soc_dump_decode_win(void)
412 {
413         uint32_t dev, rev;
414         int i;
415
416         soc_id(&dev, &rev);
417
418         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
419                 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
420                     win_cpu_cr_read(i),
421                     win_cpu_br_read(i));
422
423                 if (win_cpu_can_remap(i))
424                         printf(", rl 0x%08x, rh 0x%08x",
425                             win_cpu_remap_l_read(i),
426                             win_cpu_remap_h_read(i));
427
428                 printf("\n");
429         }
430         printf("Internal regs base: 0x%08x\n",
431             bus_space_read_4(obio_tag, MV_INTREGS_BASE, 0));
432
433         for (i = 0; i < MV_WIN_DDR_MAX; i++)
434                 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
435                     ddr_br_read(i), ddr_sz_read(i));
436
437         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
438                 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
439                     win_eth_br_read(MV_ETH0_BASE, i),
440                     win_eth_sz_read(MV_ETH0_BASE, i));
441
442                 if (win_eth_can_remap(i))
443                         printf(", ha 0x%08x",
444                             win_eth_har_read(MV_ETH0_BASE, i));
445
446                 printf("\n");
447         }
448         printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
449             win_eth_bare_read(MV_ETH0_BASE),
450             win_eth_epap_read(MV_ETH0_BASE));
451
452         decode_win_idma_dump();
453         decode_win_cesa_dump();
454         decode_win_usb_dump();
455         printf("\n");
456 }
457
458 /**************************************************************************
459  * CPU windows routines
460  **************************************************************************/
461 int
462 win_cpu_can_remap(int i)
463 {
464         uint32_t dev, rev;
465
466         soc_id(&dev, &rev);
467
468         /* Depending on the SoC certain windows have remap capability */
469         if ((dev == MV_DEV_88F5182 && i < 2) ||
470             (dev == MV_DEV_88F5281 && i < 4) ||
471             (dev == MV_DEV_88F6281 && i < 4) ||
472             (dev == MV_DEV_MV78100 && i < 8) ||
473             (dev == MV_DEV_MV78100_Z0 && i < 8))
474                 return (1);
475
476         return (0);
477 }
478
479 /* XXX This should check for overlapping remap fields too.. */
480 int
481 decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
482 {
483         const struct decode_win *tab;
484         int i;
485
486         tab = wintab;
487
488         for (i = 0; i < win_no; i++, tab++) {
489                 if (i == win)
490                         /* Skip self */
491                         continue;
492
493                 if ((tab->base + tab->size - 1) < (wintab + win)->base)
494                         continue;
495
496                 else if (((wintab + win)->base + (wintab + win)->size - 1) <
497                     tab->base)
498                         continue;
499                 else
500                         return (i);
501         }
502
503         return (-1);
504 }
505
506 static int
507 decode_win_cpu_valid(void)
508 {
509         int i, j, rv;
510         uint32_t b, e, s;
511
512         if (cpu_wins_no > MV_WIN_CPU_MAX) {
513                 printf("CPU windows: too many entries: %d\n", cpu_wins_no);
514                 return (-1);
515         }
516
517         rv = 1;
518         for (i = 0; i < cpu_wins_no; i++) {
519
520                 if (cpu_wins[i].target == 0) {
521                         printf("CPU window#%d: DDR target window is not "
522                             "supposed to be reprogrammed!\n", i);
523                         rv = 0;
524                 }
525
526                 if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) {
527                         printf("CPU window#%d: not capable of remapping, but "
528                             "val 0x%08x defined\n", i, cpu_wins[i].remap);
529                         rv = 0;
530                 }
531
532                 s = cpu_wins[i].size;
533                 b = cpu_wins[i].base;
534                 e = b + s - 1;
535                 if (s > (0xFFFFFFFF - b + 1)) {
536                         /*
537                          * XXX this boundary check should account for 64bit
538                          * and remapping..
539                          */
540                         printf("CPU window#%d: no space for size 0x%08x at "
541                             "0x%08x\n", i, s, b);
542                         rv = 0;
543                         continue;
544                 }
545
546                 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
547                 if (j >= 0) {
548                         printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
549                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
550                             cpu_wins[j].base,
551                             cpu_wins[j].base + cpu_wins[j].size - 1);
552                         rv = 0;
553                 }
554         }
555
556         return (rv);
557 }
558
559 int
560 decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
561     int remap)
562 {
563         uint32_t br, cr;
564         int win;
565
566         if (used_cpu_wins >= MV_WIN_CPU_MAX)
567                 return (-1);
568
569         win = used_cpu_wins++;
570
571         br = base & 0xffff0000;
572         win_cpu_br_write(win, br);
573
574         if (win_cpu_can_remap(win)) {
575                 if (remap >= 0) {
576                         win_cpu_remap_l_write(win, remap & 0xffff0000);
577                         win_cpu_remap_h_write(win, 0);
578                 } else {
579                         /*
580                          * Remap function is not used for a given window
581                          * (capable of remapping) - set remap field with the
582                          * same value as base.
583                          */
584                         win_cpu_remap_l_write(win, base & 0xffff0000);
585                         win_cpu_remap_h_write(win, 0);
586                 }
587         }
588
589         cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
590         win_cpu_cr_write(win, cr);
591
592         return (0);
593 }
594
595 static void
596 decode_win_cpu_setup(void)
597 {
598         int i;
599
600         used_cpu_wins = 0;
601
602         /* Disable all CPU windows */
603         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
604                 win_cpu_cr_write(i, 0);
605                 win_cpu_br_write(i, 0);
606                 if (win_cpu_can_remap(i)) {
607                         win_cpu_remap_l_write(i, 0);
608                         win_cpu_remap_h_write(i, 0);
609                 }
610         }
611
612         for (i = 0; i < cpu_wins_no; i++)
613                 if (cpu_wins[i].target > 0)
614                         decode_win_cpu_set(cpu_wins[i].target,
615                             cpu_wins[i].attr, cpu_wins[i].base,
616                             cpu_wins[i].size, cpu_wins[i].remap);
617
618 }
619
620 /*
621  * Check if we're able to cover all active DDR banks.
622  */
623 static int
624 decode_win_can_cover_ddr(int max)
625 {
626         int i, c;
627
628         c = 0;
629         for (i = 0; i < MV_WIN_DDR_MAX; i++)
630                 if (ddr_is_active(i))
631                         c++;
632
633         if (c > max) {
634                 printf("Unable to cover all active DDR banks: "
635                     "%d, available windows: %d\n", c, max);
636                 return (0);
637         }
638
639         return (1);
640 }
641
642 /**************************************************************************
643  * DDR windows routines
644  **************************************************************************/
645 int
646 ddr_is_active(int i)
647 {
648
649         if (ddr_sz_read(i) & 0x1)
650                 return (1);
651
652         return (0);
653 }
654
655 uint32_t
656 ddr_base(int i)
657 {
658
659         return (ddr_br_read(i) & 0xff000000);
660 }
661
662 uint32_t
663 ddr_size(int i)
664 {
665
666         return ((ddr_sz_read(i) | 0x00ffffff) + 1);
667 }
668
669 uint32_t
670 ddr_attr(int i)
671 {
672
673         return (i == 0 ? 0xe :
674             (i == 1 ? 0xd :
675             (i == 2 ? 0xb :
676             (i == 3 ? 0x7 : 0xff))));
677 }
678
679 uint32_t
680 ddr_target(int i)
681 {
682
683         /* Mbus unit ID is 0x0 for DDR SDRAM controller */
684         return (0);
685 }
686
687 /**************************************************************************
688  * USB windows routines
689  **************************************************************************/
690 static int
691 decode_win_usb_valid(void)
692 {
693
694         return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
695 }
696
697 static __inline int
698 usb_max_ports(void)
699 {
700         uint32_t dev, rev;
701
702         soc_id(&dev, &rev);
703         return ((dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0) ? 3 : 1);
704 }
705
706 static void
707 decode_win_usb_dump(void)
708 {
709         int i, p, m;
710
711         m = usb_max_ports();
712         for (p = 0; p < m; p++)
713                 for (i = 0; i < MV_WIN_USB_MAX; i++)
714                         printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
715                             win_usb_cr_read(i, p), win_usb_br_read(i, p));
716 }
717
718 /*
719  * Set USB decode windows.
720  */
721 static void
722 decode_win_usb_setup(void)
723 {
724         uint32_t br, cr;
725         int i, j, p, m;
726
727         /* Disable and clear all USB windows for all ports */
728         m = usb_max_ports();
729
730         for (p = 0; p < m; p++) {
731
732                 if (pm_is_disabled(CPU_PM_CTRL_USB(p)))
733                         continue;
734
735                 for (i = 0; i < MV_WIN_USB_MAX; i++) {
736                         win_usb_cr_write(i, p, 0);
737                         win_usb_br_write(i, p, 0);
738                 }
739
740                 /* Only access to active DRAM banks is required */
741                 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
742                         if (ddr_is_active(i)) {
743                                 br = ddr_base(i);
744                                 /*
745                                  * XXX for 6281 we should handle Mbus write
746                                  * burst limit field in the ctrl reg
747                                  */
748                                 cr = (((ddr_size(i) - 1) & 0xffff0000) |
749                                     (ddr_attr(i) << 8) |
750                                     (ddr_target(i) << 4) | 1);
751
752                                 /* Set the first free USB window */
753                                 for (j = 0; j < MV_WIN_USB_MAX; j++) {
754                                         if (win_usb_cr_read(j, p) & 0x1)
755                                                 continue;
756
757                                         win_usb_br_write(j, p, br);
758                                         win_usb_cr_write(j, p, cr);
759                                         break;
760                                 }
761                         }
762                 }
763         }
764 }
765
766 /**************************************************************************
767  * ETH windows routines
768  **************************************************************************/
769
770 static int
771 win_eth_can_remap(int i)
772 {
773
774         /* ETH encode windows 0-3 have remap capability */
775         if (i < 4)
776                 return (1);
777         
778         return (0);
779 }
780
781 static int
782 eth_bare_read(uint32_t base, int i)
783 {
784         uint32_t v;
785
786         v = win_eth_bare_read(base);
787         v &= (1 << i);
788
789         return (v >> i);
790 }
791
792 static void
793 eth_bare_write(uint32_t base, int i, int val)
794 {
795         uint32_t v;
796
797         v = win_eth_bare_read(base);
798         v &= ~(1 << i);
799         v |= (val << i);
800         win_eth_bare_write(base, v);
801 }
802
803 static void
804 eth_epap_write(uint32_t base, int i, int val)
805 {
806         uint32_t v;
807
808         v = win_eth_epap_read(base);
809         v &= ~(0x3 << (i * 2));
810         v |= (val << (i * 2));
811         win_eth_epap_write(base, v);
812 }
813
814 static void
815 decode_win_eth_setup(uint32_t base)
816 {
817         uint32_t br, sz;
818         int i, j;
819
820         if (pm_is_disabled(obio_get_pm_mask(base)))
821                 return;
822
823         /* Disable, clear and revoke protection for all ETH windows */
824         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
825
826                 eth_bare_write(base, i, 1);
827                 eth_epap_write(base, i, 0);
828                 win_eth_br_write(base, i, 0);
829                 win_eth_sz_write(base, i, 0);
830                 if (win_eth_can_remap(i))
831                         win_eth_har_write(base, i, 0);
832         }
833
834         /* Only access to active DRAM banks is required */
835         for (i = 0; i < MV_WIN_DDR_MAX; i++)
836                 if (ddr_is_active(i)) {
837
838                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
839                         sz = ((ddr_size(i) - 1) & 0xffff0000);
840
841                         /* Set the first free ETH window */
842                         for (j = 0; j < MV_WIN_ETH_MAX; j++) {
843                                 if (eth_bare_read(base, j) == 0)
844                                         continue;
845
846                                 win_eth_br_write(base, j, br);
847                                 win_eth_sz_write(base, j, sz);
848
849                                 /* XXX remapping ETH windows not supported */
850
851                                 /* Set protection RW */
852                                 eth_epap_write(base, j, 0x3);
853
854                                 /* Enable window */
855                                 eth_bare_write(base, j, 0);
856                                 break;
857                         }
858                 }
859 }
860
861 static int
862 decode_win_eth_valid(void)
863 {
864
865         return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
866 }
867
868 /**************************************************************************
869  * PCIE windows routines
870  **************************************************************************/
871
872 static void
873 decode_win_pcie_setup(uint32_t base)
874 {
875         uint32_t size = 0;
876         uint32_t cr, br;
877         int i, j;
878
879         for (i = 0; i < MV_PCIE_BAR_MAX; i++)
880                 pcie_bar_write(base, i, 0);
881
882         for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
883                 win_pcie_cr_write(base, i, 0);
884                 win_pcie_br_write(base, i, 0);
885                 win_pcie_remap_write(base, i, 0);
886         }
887
888         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
889                 if (ddr_is_active(i)) {
890                         /* Map DDR to BAR 1 */
891                         cr = (ddr_size(i) - 1) & 0xffff0000;
892                         size += ddr_size(i) & 0xffff0000;
893                         cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
894                         br = ddr_base(i);
895
896                         /* Use the first available PCIE window */
897                         for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
898                                 if (win_pcie_cr_read(base, j) != 0)
899                                         continue;
900
901                                 win_pcie_br_write(base, j, br);
902                                 win_pcie_cr_write(base, j, cr);
903                                 break;
904                         }
905                 }
906         }
907
908         /*
909          * Upper 16 bits in BAR register is interpreted as BAR size
910          * (in 64 kB units) plus 64kB, so substract 0x10000
911          * form value passed to register to get correct value.
912          */
913         size -= 0x10000;
914         pcie_bar_write(base, 0, size | 1);
915 }
916
917 static int
918 decode_win_pcie_valid(void)
919 {
920
921         return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
922 }
923
924 /**************************************************************************
925  * IDMA windows routines
926  **************************************************************************/
927 #if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
928 static int
929 idma_bare_read(int i)
930 {
931         uint32_t v;
932
933         v = win_idma_bare_read();
934         v &= (1 << i);
935
936         return (v >> i);
937 }
938
939 static void
940 idma_bare_write(int i, int val)
941 {
942         uint32_t v;
943
944         v = win_idma_bare_read();
945         v &= ~(1 << i);
946         v |= (val << i);
947         win_idma_bare_write(v);
948 }
949
950 /*
951  * Sets channel protection 'val' for window 'w' on channel 'c'
952  */
953 static void
954 idma_cap_write(int c, int w, int val)
955 {
956         uint32_t v;
957
958         v = win_idma_cap_read(c);
959         v &= ~(0x3 << (w * 2));
960         v |= (val << (w * 2));
961         win_idma_cap_write(c, v);
962 }
963
964 /*
965  * Set protection 'val' on all channels for window 'w'
966  */
967 static void
968 idma_set_prot(int w, int val)
969 {
970         int c;
971
972         for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
973                 idma_cap_write(c, w, val);
974 }
975
976 static int
977 win_idma_can_remap(int i)
978 {
979
980         /* IDMA decode windows 0-3 have remap capability */
981         if (i < 4)
982                 return (1);
983
984         return (0);
985 }
986
987 void
988 decode_win_idma_setup(void)
989 {
990         uint32_t br, sz;
991         int i, j;
992
993         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
994                 return;
995         /*
996          * Disable and clear all IDMA windows, revoke protection for all channels
997          */
998         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
999
1000                 idma_bare_write(i, 1);
1001                 win_idma_br_write(i, 0);
1002                 win_idma_sz_write(i, 0);
1003                 if (win_idma_can_remap(i) == 1)
1004                         win_idma_har_write(i, 0);
1005         }
1006         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1007                 win_idma_cap_write(i, 0);
1008
1009         /*
1010          * Set up access to all active DRAM banks
1011          */
1012         for (i = 0; i < MV_WIN_DDR_MAX; i++)
1013                 if (ddr_is_active(i)) {
1014                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
1015                         sz = ((ddr_size(i) - 1) & 0xffff0000);
1016
1017                         /* Place DDR entries in non-remapped windows */
1018                         for (j = 0; j < MV_WIN_IDMA_MAX; j++)
1019                                 if (win_idma_can_remap(j) != 1 &&
1020                                     idma_bare_read(j) == 1) {
1021
1022                                         /* Configure window */
1023                                         win_idma_br_write(j, br);
1024                                         win_idma_sz_write(j, sz);
1025
1026                                         /* Set protection RW on all channels */
1027                                         idma_set_prot(j, 0x3);
1028
1029                                         /* Enable window */
1030                                         idma_bare_write(j, 0);
1031                                         break;
1032                                 }
1033                 }
1034
1035         /*
1036          * Remaining targets -- from statically defined table
1037          */
1038         for (i = 0; i < idma_wins_no; i++)
1039                 if (idma_wins[i].target > 0) {
1040                         br = (idma_wins[i].base & 0xffff0000) |
1041                             (idma_wins[i].attr << 8) | idma_wins[i].target;
1042                         sz = ((idma_wins[i].size - 1) & 0xffff0000);
1043
1044                         /* Set the first free IDMA window */
1045                         for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
1046                                 if (idma_bare_read(j) == 0)
1047                                         continue;
1048
1049                                 /* Configure window */
1050                                 win_idma_br_write(j, br);
1051                                 win_idma_sz_write(j, sz);
1052                                 if (win_idma_can_remap(j) &&
1053                                     idma_wins[j].remap >= 0)
1054                                         win_idma_har_write(j, idma_wins[j].remap);
1055
1056                                 /* Set protection RW on all channels */
1057                                 idma_set_prot(j, 0x3);
1058
1059                                 /* Enable window */
1060                                 idma_bare_write(j, 0);
1061                                 break;
1062                         }
1063                 }
1064 }
1065
1066 int
1067 decode_win_idma_valid(void)
1068 {
1069         const struct decode_win *wintab;
1070         int c, i, j, rv;
1071         uint32_t b, e, s;
1072
1073         if (idma_wins_no > MV_WIN_IDMA_MAX) {
1074                 printf("IDMA windows: too many entries: %d\n", idma_wins_no);
1075                 return (-1);
1076         }
1077         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1078                 if (ddr_is_active(i))
1079                         c++;
1080
1081         if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
1082                 printf("IDMA windows: too many entries: %d, available: %d\n",
1083                     idma_wins_no, MV_WIN_IDMA_MAX - c);
1084                 return (-1);
1085         }
1086
1087         wintab = idma_wins;
1088         rv = 1;
1089         for (i = 0; i < idma_wins_no; i++, wintab++) {
1090
1091                 if (wintab->target == 0) {
1092                         printf("IDMA window#%d: DDR target window is not "
1093                             "supposed to be reprogrammed!\n", i);
1094                         rv = 0;
1095                 }
1096
1097                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1098                         printf("IDMA window#%d: not capable of remapping, but "
1099                             "val 0x%08x defined\n", i, wintab->remap);
1100                         rv = 0;
1101                 }
1102
1103                 s = wintab->size;
1104                 b = wintab->base;
1105                 e = b + s - 1;
1106                 if (s > (0xFFFFFFFF - b + 1)) {
1107                         /* XXX this boundary check should account for 64bit and
1108                          * remapping.. */
1109                         printf("IDMA window#%d: no space for size 0x%08x at "
1110                             "0x%08x\n", i, s, b);
1111                         rv = 0;
1112                         continue;
1113                 }
1114
1115                 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
1116                 if (j >= 0) {
1117                         printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
1118                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
1119                             idma_wins[j].base,
1120                             idma_wins[j].base + idma_wins[j].size - 1);
1121                         rv = 0;
1122                 }
1123         }
1124
1125         return (rv);
1126 }
1127
1128 void
1129 decode_win_idma_dump(void)
1130 {
1131         int i;
1132
1133         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
1134                 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
1135                     win_idma_br_read(i), win_idma_sz_read(i));
1136                 
1137                 if (win_idma_can_remap(i))
1138                         printf(", ha 0x%08x", win_idma_har_read(i));
1139
1140                 printf("\n");
1141         }
1142         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1143                 printf("IDMA channel#%d: ap 0x%08x\n", i,
1144                     win_idma_cap_read(i));
1145         printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read());
1146 }
1147 #else
1148
1149 /* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
1150 int
1151 decode_win_idma_valid(void)
1152 {
1153
1154         return (1);
1155 }
1156
1157 void
1158 decode_win_idma_setup(void)
1159 {
1160 }
1161
1162 void
1163 decode_win_idma_dump(void)
1164 {
1165 }
1166 #endif
1167
1168 /**************************************************************************
1169  * XOR windows routines
1170  **************************************************************************/
1171 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
1172 static int
1173 xor_ctrl_read(int i, int c, int e)
1174 {
1175         uint32_t v;
1176         v = win_xor_ctrl_read(c, e);
1177         v &= (1 << i);
1178
1179         return (v >> i);
1180 }
1181
1182 static void
1183 xor_ctrl_write(int i, int c, int e, int val)
1184 {
1185         uint32_t v;
1186
1187         v = win_xor_ctrl_read(c, e);
1188         v &= ~(1 << i);
1189         v |= (val << i);
1190         win_xor_ctrl_write(c, e, v);
1191 }
1192
1193 /*
1194  * Set channel protection 'val' for window 'w' on channel 'c'
1195  */
1196
1197 static void
1198 xor_chan_write(int c, int e, int w, int val)
1199 {
1200         uint32_t v;
1201
1202         v = win_xor_ctrl_read(c, e);
1203         v &= ~(0x3 << (w * 2 + 16));
1204         v |= (val << (w * 2 + 16));
1205         win_xor_ctrl_write(c, e, v);
1206 }
1207
1208 /*
1209  * Set protection 'val' on all channels for window 'w' on engine 'e'
1210  */
1211 static void
1212 xor_set_prot(int w, int e, int val)
1213 {
1214         int c;
1215
1216         for (c = 0; c < MV_XOR_CHAN_MAX; c++)
1217                 xor_chan_write(c, e, w, val);
1218 }
1219
1220 static int
1221 win_xor_can_remap(int i)
1222 {
1223
1224         /* XOR decode windows 0-3 have remap capability */
1225         if (i < 4)
1226                 return (1);
1227
1228         return (0);
1229 }
1230
1231 static int
1232 xor_max_eng(void)
1233 {
1234         uint32_t dev, rev;
1235
1236         soc_id(&dev, &rev);
1237         if (dev == MV_DEV_88F6281)
1238                 return (2);
1239         else if ((dev == MV_DEV_MV78100) || (dev == MV_DEV_MV78100_Z0))
1240                 return (1);
1241         else
1242                 return (0);
1243 }
1244
1245 static void
1246 xor_active_dram(int c, int e, int *window)
1247 {
1248         uint32_t br, sz;
1249         int i, m, w;
1250
1251         /*
1252          * Set up access to all active DRAM banks
1253          */
1254         m = xor_max_eng();
1255         for (i = 0; i < m; i++)
1256                 if (ddr_is_active(i)) {
1257                         br = ddr_base(i) | (ddr_attr(i) << 8) |
1258                             ddr_target(i);
1259                         sz = ((ddr_size(i) - 1) & 0xffff0000);
1260
1261                         /* Place DDR entries in non-remapped windows */
1262                         for (w = 0; w < MV_WIN_XOR_MAX; w++)
1263                                 if (win_xor_can_remap(w) != 1 &&
1264                                     (xor_ctrl_read(w, c, e) == 0) &&
1265                                     w > *window) {
1266                                         /* Configure window */
1267                                         win_xor_br_write(w, e, br);
1268                                         win_xor_sz_write(w, e, sz);
1269
1270                                         /* Set protection RW on all channels */
1271                                         xor_set_prot(w, e, 0x3);
1272
1273                                         /* Enable window */
1274                                         xor_ctrl_write(w, c, e, 1);
1275                                         (*window)++;
1276                                         break;
1277                                 }
1278                 }
1279 }
1280
1281 void
1282 decode_win_xor_setup(void)
1283 {
1284         uint32_t br, sz;
1285         int i, j, z, e = 1, m, window;
1286
1287         if (pm_is_disabled(CPU_PM_CTRL_XOR))
1288                 return;
1289
1290         /*
1291          * Disable and clear all XOR windows, revoke protection for all
1292          * channels
1293          */
1294         m = xor_max_eng();
1295         for (j = 0; j < m; j++, e--) {
1296
1297                 /* Number of non-remaped windows */
1298                 window = MV_XOR_NON_REMAP - 1;
1299
1300                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1301                         win_xor_br_write(i, e, 0);
1302                         win_xor_sz_write(i, e, 0);
1303                 }
1304
1305                 if (win_xor_can_remap(i) == 1)
1306                         win_xor_har_write(i, e, 0);
1307
1308                 for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
1309                         win_xor_ctrl_write(i, e, 0);
1310                         xor_active_dram(i, e, &window);
1311                 }
1312
1313                 /*
1314                  * Remaining targets -- from a statically defined table
1315                  */
1316                 for (i = 0; i < xor_wins_no; i++)
1317                         if (xor_wins[i].target > 0) {
1318                                 br = (xor_wins[i].base & 0xffff0000) |
1319                                     (xor_wins[i].attr << 8) |
1320                                     xor_wins[i].target;
1321                                 sz = ((xor_wins[i].size - 1) & 0xffff0000);
1322
1323                                 /* Set the first free XOR window */
1324                                 for (z = 0; z < MV_WIN_XOR_MAX; z++) {
1325                                         if (xor_ctrl_read(z, 0, e) &&
1326                                             xor_ctrl_read(z, 1, e))
1327                                                 continue;
1328
1329                                         /* Configure window */
1330                                         win_xor_br_write(z, e, br);
1331                                         win_xor_sz_write(z, e, sz);
1332                                         if (win_xor_can_remap(z) &&
1333                                             xor_wins[z].remap >= 0)
1334                                                 win_xor_har_write(z, e,
1335                                                     xor_wins[z].remap);
1336
1337                                         /* Set protection RW on all channels */
1338                                         xor_set_prot(z, e, 0x3);
1339
1340                                         /* Enable window */
1341                                         xor_ctrl_write(z, 0, e, 1);
1342                                         xor_ctrl_write(z, 1, e, 1);
1343                                         break;
1344                                 }
1345                         }
1346         }
1347 }
1348
1349 int
1350 decode_win_xor_valid(void)
1351 {
1352         const struct decode_win *wintab;
1353         int c, i, j, rv;
1354         uint32_t b, e, s;
1355
1356         if (xor_wins_no > MV_WIN_XOR_MAX) {
1357                 printf("XOR windows: too many entries: %d\n", xor_wins_no);
1358                 return (-1);
1359         }
1360         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1361                 if (ddr_is_active(i))
1362                         c++;
1363
1364         if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
1365                 printf("XOR windows: too many entries: %d, available: %d\n",
1366                     xor_wins_no, MV_WIN_IDMA_MAX - c);
1367                 return (-1);
1368         }
1369
1370         wintab = xor_wins;
1371         rv = 1;
1372         for (i = 0; i < xor_wins_no; i++, wintab++) {
1373
1374                 if (wintab->target == 0) {
1375                         printf("XOR window#%d: DDR target window is not "
1376                             "supposed to be reprogrammed!\n", i);
1377                         rv = 0;
1378                 }
1379
1380                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1381                         printf("XOR window#%d: not capable of remapping, but "
1382                             "val 0x%08x defined\n", i, wintab->remap);
1383                         rv = 0;
1384                 }
1385
1386                 s = wintab->size;
1387                 b = wintab->base;
1388                 e = b + s - 1;
1389                 if (s > (0xFFFFFFFF - b + 1)) {
1390                         /*
1391                          * XXX this boundary check should account for 64bit
1392                          * and remapping..
1393                          */
1394                         printf("XOR window#%d: no space for size 0x%08x at "
1395                             "0x%08x\n", i, s, b);
1396                         rv = 0;
1397                         continue;
1398                 }
1399
1400                 j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
1401                 if (j >= 0) {
1402                         printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
1403                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
1404                             xor_wins[j].base,
1405                             xor_wins[j].base + xor_wins[j].size - 1);
1406                         rv = 0;
1407                 }
1408         }
1409
1410         return (rv);
1411 }
1412
1413 void
1414 decode_win_xor_dump(void)
1415 {
1416         int i, j;
1417         int e = 1;
1418
1419         for (j = 0; j < xor_max_eng(); j++, e--) {
1420                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1421                         printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
1422                             win_xor_br_read(i, e), win_xor_sz_read(i, e));
1423
1424                         if (win_xor_can_remap(i))
1425                                 printf(", ha 0x%08x", win_xor_har_read(i, e));
1426
1427                         printf("\n");
1428                 }
1429                 for (i = 0; i < MV_XOR_CHAN_MAX; i++)
1430                         printf("XOR control#%d: 0x%08x\n", i,
1431                             win_xor_ctrl_read(i, e));
1432         }
1433 }
1434
1435 #else
1436 /* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
1437 int
1438 decode_win_xor_valid(void)
1439 {
1440
1441         return (1);
1442 }
1443
1444 void
1445 decode_win_xor_setup(void)
1446 {
1447 }
1448
1449 void
1450 decode_win_xor_dump(void)
1451 {
1452 }
1453 #endif
1454
1455 /**************************************************************************
1456  * CESA TDMA windows routines
1457  **************************************************************************/
1458 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
1459 /*
1460  * Dump CESA TDMA decode windows.
1461  */
1462 static void
1463 decode_win_cesa_dump(void)
1464 {
1465         int i;
1466
1467         for (i = 0; i < MV_WIN_CESA_MAX; i++)
1468                 printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
1469                     win_cesa_cr_read(i), win_cesa_br_read(i));
1470 }
1471
1472
1473 /*
1474  * Set CESA TDMA decode windows.
1475  */
1476 static void
1477 decode_win_cesa_setup(void)
1478 {
1479         uint32_t br, cr;
1480         int i, j;
1481
1482         if (pm_is_disabled(CPU_PM_CTRL_CRYPTO))
1483                 return;
1484
1485         /* Disable and clear all CESA windows */
1486         for (i = 0; i < MV_WIN_CESA_MAX; i++) {
1487                 win_cesa_cr_write(i, 0);
1488                 win_cesa_br_write(i, 0);
1489         }
1490
1491         /* Only access to active DRAM banks is required. */
1492         for (i = 0; i < MV_WIN_DDR_MAX; i++)
1493                 if (ddr_is_active(i)) {
1494                         br = ddr_base(i);
1495                         cr = (((ddr_size(i) - 1) & 0xffff0000) |
1496                            (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
1497
1498                         /* Set the first available CESA window */
1499                         for (j = 0; j < MV_WIN_CESA_MAX; j++) {
1500                                 if (win_cesa_cr_read(j) & 0x1)
1501                                         continue;
1502
1503                                 win_cesa_br_write(j, br);
1504                                 win_cesa_cr_write(j, cr);
1505                                 break;
1506                         }
1507                 }
1508 }
1509
1510 /*
1511  * Check CESA TDMA decode windows.
1512  */
1513 static int
1514 decode_win_cesa_valid(void)
1515 {
1516
1517         return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
1518 }
1519 #else
1520
1521 /*
1522  * Provide dummy functions to satisfy the build for SoCs not equipped with
1523  * CESA
1524  */
1525
1526 int
1527 decode_win_cesa_valid(void)
1528 {
1529
1530         return (1);
1531 }
1532
1533 void
1534 decode_win_cesa_setup(void)
1535 {
1536 }
1537
1538 void
1539 decode_win_cesa_dump(void)
1540 {
1541 }
1542 #endif
1543
1544 /**************************************************************************
1545  * SATA windows routines
1546  **************************************************************************/
1547 static void
1548 decode_win_sata_setup(void)
1549 {
1550         uint32_t cr, br;
1551         int i, j;
1552
1553         if (pm_is_disabled(CPU_PM_CTRL_SATA))
1554                 return;
1555
1556         for (i = 0; i < MV_WIN_SATA_MAX; i++) {
1557                 win_sata_cr_write(i, 0);
1558                 win_sata_br_write(i, 0);
1559         }
1560
1561         for (i = 0; i < MV_WIN_DDR_MAX; i++)
1562                 if (ddr_is_active(i)) {
1563                         cr = ((ddr_size(i) - 1) & 0xffff0000) |
1564                             (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
1565                         br = ddr_base(i);
1566
1567                         /* Use the first available SATA window */
1568                         for (j = 0; j < MV_WIN_SATA_MAX; j++) {
1569                                 if ((win_sata_cr_read(j) & 1) != 0)
1570                                         continue;
1571
1572                                 win_sata_br_write(j, br);
1573                                 win_sata_cr_write(j, cr);
1574                                 break;
1575                         }
1576                 }
1577 }
1578
1579 static int
1580 decode_win_sata_valid(void)
1581 {
1582         uint32_t dev, rev;
1583
1584         soc_id(&dev, &rev);
1585         if (dev == MV_DEV_88F5281)
1586                 return (1);
1587
1588         return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
1589 }