]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - sys/arm/mv/common.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.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                 break;
265         case MV_DEV_MV78100_Z0:
266                 dev = "Marvell MV78100 Z0";
267                 break;
268         case MV_DEV_MV78100:
269                 dev = "Marvell MV78100";
270                 break;
271         default:
272                 dev = "UNKNOWN";
273                 break;
274         }
275
276         printf("%s", dev);
277         if (*rev != '\0')
278                 printf(" rev %s", rev);
279         printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
280
281         /* TODO add info on currently set endianess */
282 }
283
284 int
285 soc_decode_win(void)
286 {
287         uint32_t dev, rev;
288         int mask;
289
290         mask = 0;
291         TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
292
293         if (mask != 0)
294                 pm_disable_device(mask);
295
296         /* Retrieve our ID: some windows facilities vary between SoC models */
297         soc_id(&dev, &rev);
298
299         if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
300             decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
301             decode_win_pcie_valid() != 1 || decode_win_sata_valid() != 1 ||
302             decode_win_cesa_valid() != 1)
303                 return(-1);
304
305         decode_win_cpu_setup();
306         decode_win_usb_setup();
307         decode_win_eth_setup(MV_ETH0_BASE);
308         if (dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0)
309                 decode_win_eth_setup(MV_ETH1_BASE);
310         if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100 ||
311             dev == MV_DEV_MV78100_Z0)
312                 decode_win_cesa_setup();
313
314         decode_win_idma_setup();
315         decode_win_xor_setup();
316
317         if (dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0) {
318                 decode_win_pcie_setup(MV_PCIE00_BASE);
319                 decode_win_pcie_setup(MV_PCIE01_BASE);
320                 decode_win_pcie_setup(MV_PCIE02_BASE);
321                 decode_win_pcie_setup(MV_PCIE03_BASE);
322                 decode_win_pcie_setup(MV_PCIE10_BASE);
323                 decode_win_pcie_setup(MV_PCIE11_BASE);
324                 decode_win_pcie_setup(MV_PCIE12_BASE);
325                 decode_win_pcie_setup(MV_PCIE13_BASE);
326         } else
327                 decode_win_pcie_setup(MV_PCIE_BASE);
328
329         if (dev != MV_DEV_88F5281)
330                 decode_win_sata_setup();
331
332         return (0);
333 }
334
335 /**************************************************************************
336  * Decode windows registers accessors
337  **************************************************************************/
338 WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
339 WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
340 WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
341 WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
342 WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
343 WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
344 WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
345 WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
346
347 WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
348 WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
349
350 WIN_REG_IDX_RD2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
351 WIN_REG_IDX_RD2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
352 WIN_REG_IDX_WR2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
353 WIN_REG_IDX_WR2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
354
355 WIN_REG_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
356 WIN_REG_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
357 WIN_REG_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
358 WIN_REG_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
359
360 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
361 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
362 WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
363 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
364 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
365 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
366
367 WIN_REG_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
368 WIN_REG_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
369 WIN_REG_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
370 WIN_REG_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
371 WIN_REG_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
372 WIN_REG_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
373 WIN_REG_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
374 WIN_REG_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
375
376 WIN_REG_BASE_RD(win_eth, bare, 0x290)
377 WIN_REG_BASE_RD(win_eth, epap, 0x294)
378 WIN_REG_BASE_WR(win_eth, bare, 0x290)
379 WIN_REG_BASE_WR(win_eth, epap, 0x294)
380
381 WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
382 WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
383 WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
384 WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
385 WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
386 WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
387 WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
388
389 WIN_REG_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
390 WIN_REG_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
391 WIN_REG_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
392 WIN_REG_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
393 WIN_REG_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
394 WIN_REG_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
395 WIN_REG_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
396 WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
397 WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
398 WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
399
400 WIN_REG_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
401 WIN_REG_IDX_RD(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
402 WIN_REG_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
403 WIN_REG_IDX_WR(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
404
405 /**************************************************************************
406  * Decode windows helper routines
407  **************************************************************************/
408 void
409 soc_dump_decode_win(void)
410 {
411         uint32_t dev, rev;
412         int i;
413
414         soc_id(&dev, &rev);
415
416         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
417                 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
418                     win_cpu_cr_read(i),
419                     win_cpu_br_read(i));
420
421                 if (win_cpu_can_remap(i))
422                         printf(", rl 0x%08x, rh 0x%08x",
423                             win_cpu_remap_l_read(i),
424                             win_cpu_remap_h_read(i));
425
426                 printf("\n");
427         }
428         printf("Internal regs base: 0x%08x\n",
429             bus_space_read_4(obio_tag, MV_INTREGS_BASE, 0));
430
431         for (i = 0; i < MV_WIN_DDR_MAX; i++)
432                 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
433                     ddr_br_read(i), ddr_sz_read(i));
434
435         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
436                 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
437                     win_eth_br_read(MV_ETH0_BASE, i),
438                     win_eth_sz_read(MV_ETH0_BASE, i));
439
440                 if (win_eth_can_remap(i))
441                         printf(", ha 0x%08x",
442                             win_eth_har_read(MV_ETH0_BASE, i));
443
444                 printf("\n");
445         }
446         printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
447             win_eth_bare_read(MV_ETH0_BASE),
448             win_eth_epap_read(MV_ETH0_BASE));
449
450         decode_win_idma_dump();
451         decode_win_cesa_dump();
452         decode_win_usb_dump();
453         printf("\n");
454 }
455
456 /**************************************************************************
457  * CPU windows routines
458  **************************************************************************/
459 int
460 win_cpu_can_remap(int i)
461 {
462         uint32_t dev, rev;
463
464         soc_id(&dev, &rev);
465
466         /* Depending on the SoC certain windows have remap capability */
467         if ((dev == MV_DEV_88F5182 && i < 2) ||
468             (dev == MV_DEV_88F5281 && i < 4) ||
469             (dev == MV_DEV_88F6281 && i < 4) ||
470             (dev == MV_DEV_MV78100 && i < 8) ||
471             (dev == MV_DEV_MV78100_Z0 && i < 8))
472                 return (1);
473
474         return (0);
475 }
476
477 /* XXX This should check for overlapping remap fields too.. */
478 int
479 decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
480 {
481         const struct decode_win *tab;
482         int i;
483
484         tab = wintab;
485
486         for (i = 0; i < win_no; i++, tab++) {
487                 if (i == win)
488                         /* Skip self */
489                         continue;
490
491                 if ((tab->base + tab->size - 1) < (wintab + win)->base)
492                         continue;
493
494                 else if (((wintab + win)->base + (wintab + win)->size - 1) <
495                     tab->base)
496                         continue;
497                 else
498                         return (i);
499         }
500
501         return (-1);
502 }
503
504 static int
505 decode_win_cpu_valid(void)
506 {
507         int i, j, rv;
508         uint32_t b, e, s;
509
510         if (cpu_wins_no > MV_WIN_CPU_MAX) {
511                 printf("CPU windows: too many entries: %d\n", cpu_wins_no);
512                 return (-1);
513         }
514
515         rv = 1;
516         for (i = 0; i < cpu_wins_no; i++) {
517
518                 if (cpu_wins[i].target == 0) {
519                         printf("CPU window#%d: DDR target window is not "
520                             "supposed to be reprogrammed!\n", i);
521                         rv = 0;
522                 }
523
524                 if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) {
525                         printf("CPU window#%d: not capable of remapping, but "
526                             "val 0x%08x defined\n", i, cpu_wins[i].remap);
527                         rv = 0;
528                 }
529
530                 s = cpu_wins[i].size;
531                 b = cpu_wins[i].base;
532                 e = b + s - 1;
533                 if (s > (0xFFFFFFFF - b + 1)) {
534                         /*
535                          * XXX this boundary check should account for 64bit
536                          * and remapping..
537                          */
538                         printf("CPU window#%d: no space for size 0x%08x at "
539                             "0x%08x\n", i, s, b);
540                         rv = 0;
541                         continue;
542                 }
543
544                 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
545                 if (j >= 0) {
546                         printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
547                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
548                             cpu_wins[j].base,
549                             cpu_wins[j].base + cpu_wins[j].size - 1);
550                         rv = 0;
551                 }
552         }
553
554         return (rv);
555 }
556
557 int
558 decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
559     int remap)
560 {
561         uint32_t br, cr;
562         int win;
563
564         if (used_cpu_wins >= MV_WIN_CPU_MAX)
565                 return (-1);
566
567         win = used_cpu_wins++;
568
569         br = base & 0xffff0000;
570         win_cpu_br_write(win, br);
571
572         if (win_cpu_can_remap(win)) {
573                 if (remap >= 0) {
574                         win_cpu_remap_l_write(win, remap & 0xffff0000);
575                         win_cpu_remap_h_write(win, 0);
576                 } else {
577                         /*
578                          * Remap function is not used for a given window
579                          * (capable of remapping) - set remap field with the
580                          * same value as base.
581                          */
582                         win_cpu_remap_l_write(win, base & 0xffff0000);
583                         win_cpu_remap_h_write(win, 0);
584                 }
585         }
586
587         cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
588         win_cpu_cr_write(win, cr);
589
590         return (0);
591 }
592
593 static void
594 decode_win_cpu_setup(void)
595 {
596         int i;
597
598         used_cpu_wins = 0;
599
600         /* Disable all CPU windows */
601         for (i = 0; i < MV_WIN_CPU_MAX; i++) {
602                 win_cpu_cr_write(i, 0);
603                 win_cpu_br_write(i, 0);
604                 if (win_cpu_can_remap(i)) {
605                         win_cpu_remap_l_write(i, 0);
606                         win_cpu_remap_h_write(i, 0);
607                 }
608         }
609
610         for (i = 0; i < cpu_wins_no; i++)
611                 if (cpu_wins[i].target > 0)
612                         decode_win_cpu_set(cpu_wins[i].target,
613                             cpu_wins[i].attr, cpu_wins[i].base,
614                             cpu_wins[i].size, cpu_wins[i].remap);
615
616 }
617
618 /*
619  * Check if we're able to cover all active DDR banks.
620  */
621 static int
622 decode_win_can_cover_ddr(int max)
623 {
624         int i, c;
625
626         c = 0;
627         for (i = 0; i < MV_WIN_DDR_MAX; i++)
628                 if (ddr_is_active(i))
629                         c++;
630
631         if (c > max) {
632                 printf("Unable to cover all active DDR banks: "
633                     "%d, available windows: %d\n", c, max);
634                 return (0);
635         }
636
637         return (1);
638 }
639
640 /**************************************************************************
641  * DDR windows routines
642  **************************************************************************/
643 int
644 ddr_is_active(int i)
645 {
646
647         if (ddr_sz_read(i) & 0x1)
648                 return (1);
649
650         return (0);
651 }
652
653 uint32_t
654 ddr_base(int i)
655 {
656
657         return (ddr_br_read(i) & 0xff000000);
658 }
659
660 uint32_t
661 ddr_size(int i)
662 {
663
664         return ((ddr_sz_read(i) | 0x00ffffff) + 1);
665 }
666
667 uint32_t
668 ddr_attr(int i)
669 {
670
671         return (i == 0 ? 0xe :
672             (i == 1 ? 0xd :
673             (i == 2 ? 0xb :
674             (i == 3 ? 0x7 : 0xff))));
675 }
676
677 uint32_t
678 ddr_target(int i)
679 {
680
681         /* Mbus unit ID is 0x0 for DDR SDRAM controller */
682         return (0);
683 }
684
685 /**************************************************************************
686  * USB windows routines
687  **************************************************************************/
688 static int
689 decode_win_usb_valid(void)
690 {
691
692         return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
693 }
694
695 static __inline int
696 usb_max_ports(void)
697 {
698         uint32_t dev, rev;
699
700         soc_id(&dev, &rev);
701         return ((dev == MV_DEV_MV78100 || dev == MV_DEV_MV78100_Z0) ? 3 : 1);
702 }
703
704 static void
705 decode_win_usb_dump(void)
706 {
707         int i, p, m;
708
709         m = usb_max_ports();
710         for (p = 0; p < m; p++)
711                 for (i = 0; i < MV_WIN_USB_MAX; i++)
712                         printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
713                             win_usb_cr_read(i, p), win_usb_br_read(i, p));
714 }
715
716 /*
717  * Set USB decode windows.
718  */
719 static void
720 decode_win_usb_setup(void)
721 {
722         uint32_t br, cr;
723         int i, j, p, m;
724
725         /* Disable and clear all USB windows for all ports */
726         m = usb_max_ports();
727
728         for (p = 0; p < m; p++) {
729
730                 if (pm_is_disabled(CPU_PM_CTRL_USB(p)))
731                         continue;
732
733                 for (i = 0; i < MV_WIN_USB_MAX; i++) {
734                         win_usb_cr_write(i, p, 0);
735                         win_usb_br_write(i, p, 0);
736                 }
737
738                 /* Only access to active DRAM banks is required */
739                 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
740                         if (ddr_is_active(i)) {
741                                 br = ddr_base(i);
742                                 /*
743                                  * XXX for 6281 we should handle Mbus write
744                                  * burst limit field in the ctrl reg
745                                  */
746                                 cr = (((ddr_size(i) - 1) & 0xffff0000) |
747                                     (ddr_attr(i) << 8) |
748                                     (ddr_target(i) << 4) | 1);
749
750                                 /* Set the first free USB window */
751                                 for (j = 0; j < MV_WIN_USB_MAX; j++) {
752                                         if (win_usb_cr_read(j, p) & 0x1)
753                                                 continue;
754
755                                         win_usb_br_write(j, p, br);
756                                         win_usb_cr_write(j, p, cr);
757                                         break;
758                                 }
759                         }
760                 }
761         }
762 }
763
764 /**************************************************************************
765  * ETH windows routines
766  **************************************************************************/
767
768 static int
769 win_eth_can_remap(int i)
770 {
771
772         /* ETH encode windows 0-3 have remap capability */
773         if (i < 4)
774                 return (1);
775         
776         return (0);
777 }
778
779 static int
780 eth_bare_read(uint32_t base, int i)
781 {
782         uint32_t v;
783
784         v = win_eth_bare_read(base);
785         v &= (1 << i);
786
787         return (v >> i);
788 }
789
790 static void
791 eth_bare_write(uint32_t base, int i, int val)
792 {
793         uint32_t v;
794
795         v = win_eth_bare_read(base);
796         v &= ~(1 << i);
797         v |= (val << i);
798         win_eth_bare_write(base, v);
799 }
800
801 static void
802 eth_epap_write(uint32_t base, int i, int val)
803 {
804         uint32_t v;
805
806         v = win_eth_epap_read(base);
807         v &= ~(0x3 << (i * 2));
808         v |= (val << (i * 2));
809         win_eth_epap_write(base, v);
810 }
811
812 static void
813 decode_win_eth_setup(uint32_t base)
814 {
815         uint32_t br, sz;
816         int i, j;
817
818         if (pm_is_disabled(obio_get_pm_mask(base)))
819                 return;
820
821         /* Disable, clear and revoke protection for all ETH windows */
822         for (i = 0; i < MV_WIN_ETH_MAX; i++) {
823
824                 eth_bare_write(base, i, 1);
825                 eth_epap_write(base, i, 0);
826                 win_eth_br_write(base, i, 0);
827                 win_eth_sz_write(base, i, 0);
828                 if (win_eth_can_remap(i))
829                         win_eth_har_write(base, i, 0);
830         }
831
832         /* Only access to active DRAM banks is required */
833         for (i = 0; i < MV_WIN_DDR_MAX; i++)
834                 if (ddr_is_active(i)) {
835
836                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
837                         sz = ((ddr_size(i) - 1) & 0xffff0000);
838
839                         /* Set the first free ETH window */
840                         for (j = 0; j < MV_WIN_ETH_MAX; j++) {
841                                 if (eth_bare_read(base, j) == 0)
842                                         continue;
843
844                                 win_eth_br_write(base, j, br);
845                                 win_eth_sz_write(base, j, sz);
846
847                                 /* XXX remapping ETH windows not supported */
848
849                                 /* Set protection RW */
850                                 eth_epap_write(base, j, 0x3);
851
852                                 /* Enable window */
853                                 eth_bare_write(base, j, 0);
854                                 break;
855                         }
856                 }
857 }
858
859 static int
860 decode_win_eth_valid(void)
861 {
862
863         return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
864 }
865
866 /**************************************************************************
867  * PCIE windows routines
868  **************************************************************************/
869
870 static void
871 decode_win_pcie_setup(uint32_t base)
872 {
873         uint32_t size = 0;
874         uint32_t cr, br;
875         int i, j;
876
877         for (i = 0; i < MV_PCIE_BAR_MAX; i++)
878                 pcie_bar_write(base, i, 0);
879
880         for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
881                 win_pcie_cr_write(base, i, 0);
882                 win_pcie_br_write(base, i, 0);
883                 win_pcie_remap_write(base, i, 0);
884         }
885
886         for (i = 0; i < MV_WIN_DDR_MAX; i++) {
887                 if (ddr_is_active(i)) {
888                         /* Map DDR to BAR 1 */
889                         cr = (ddr_size(i) - 1) & 0xffff0000;
890                         size += ddr_size(i) & 0xffff0000;
891                         cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
892                         br = ddr_base(i);
893
894                         /* Use the first available PCIE window */
895                         for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
896                                 if (win_pcie_cr_read(base, j) != 0)
897                                         continue;
898
899                                 win_pcie_br_write(base, j, br);
900                                 win_pcie_cr_write(base, j, cr);
901                                 break;
902                         }
903                 }
904         }
905
906         /*
907          * Upper 16 bits in BAR register is interpreted as BAR size
908          * (in 64 kB units) plus 64kB, so substract 0x10000
909          * form value passed to register to get correct value.
910          */
911         size -= 0x10000;
912         pcie_bar_write(base, 0, size | 1);
913 }
914
915 static int
916 decode_win_pcie_valid(void)
917 {
918
919         return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
920 }
921
922 /**************************************************************************
923  * IDMA windows routines
924  **************************************************************************/
925 #if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
926 static int
927 idma_bare_read(int i)
928 {
929         uint32_t v;
930
931         v = win_idma_bare_read();
932         v &= (1 << i);
933
934         return (v >> i);
935 }
936
937 static void
938 idma_bare_write(int i, int val)
939 {
940         uint32_t v;
941
942         v = win_idma_bare_read();
943         v &= ~(1 << i);
944         v |= (val << i);
945         win_idma_bare_write(v);
946 }
947
948 /*
949  * Sets channel protection 'val' for window 'w' on channel 'c'
950  */
951 static void
952 idma_cap_write(int c, int w, int val)
953 {
954         uint32_t v;
955
956         v = win_idma_cap_read(c);
957         v &= ~(0x3 << (w * 2));
958         v |= (val << (w * 2));
959         win_idma_cap_write(c, v);
960 }
961
962 /*
963  * Set protection 'val' on all channels for window 'w'
964  */
965 static void
966 idma_set_prot(int w, int val)
967 {
968         int c;
969
970         for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
971                 idma_cap_write(c, w, val);
972 }
973
974 static int
975 win_idma_can_remap(int i)
976 {
977
978         /* IDMA decode windows 0-3 have remap capability */
979         if (i < 4)
980                 return (1);
981
982         return (0);
983 }
984
985 void
986 decode_win_idma_setup(void)
987 {
988         uint32_t br, sz;
989         int i, j;
990
991         if (pm_is_disabled(CPU_PM_CTRL_IDMA))
992                 return;
993         /*
994          * Disable and clear all IDMA windows, revoke protection for all channels
995          */
996         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
997
998                 idma_bare_write(i, 1);
999                 win_idma_br_write(i, 0);
1000                 win_idma_sz_write(i, 0);
1001                 if (win_idma_can_remap(i) == 1)
1002                         win_idma_har_write(i, 0);
1003         }
1004         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1005                 win_idma_cap_write(i, 0);
1006
1007         /*
1008          * Set up access to all active DRAM banks
1009          */
1010         for (i = 0; i < MV_WIN_DDR_MAX; i++)
1011                 if (ddr_is_active(i)) {
1012                         br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
1013                         sz = ((ddr_size(i) - 1) & 0xffff0000);
1014
1015                         /* Place DDR entries in non-remapped windows */
1016                         for (j = 0; j < MV_WIN_IDMA_MAX; j++)
1017                                 if (win_idma_can_remap(j) != 1 &&
1018                                     idma_bare_read(j) == 1) {
1019
1020                                         /* Configure window */
1021                                         win_idma_br_write(j, br);
1022                                         win_idma_sz_write(j, sz);
1023
1024                                         /* Set protection RW on all channels */
1025                                         idma_set_prot(j, 0x3);
1026
1027                                         /* Enable window */
1028                                         idma_bare_write(j, 0);
1029                                         break;
1030                                 }
1031                 }
1032
1033         /*
1034          * Remaining targets -- from statically defined table
1035          */
1036         for (i = 0; i < idma_wins_no; i++)
1037                 if (idma_wins[i].target > 0) {
1038                         br = (idma_wins[i].base & 0xffff0000) |
1039                             (idma_wins[i].attr << 8) | idma_wins[i].target;
1040                         sz = ((idma_wins[i].size - 1) & 0xffff0000);
1041
1042                         /* Set the first free IDMA window */
1043                         for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
1044                                 if (idma_bare_read(j) == 0)
1045                                         continue;
1046
1047                                 /* Configure window */
1048                                 win_idma_br_write(j, br);
1049                                 win_idma_sz_write(j, sz);
1050                                 if (win_idma_can_remap(j) &&
1051                                     idma_wins[j].remap >= 0)
1052                                         win_idma_har_write(j, idma_wins[j].remap);
1053
1054                                 /* Set protection RW on all channels */
1055                                 idma_set_prot(j, 0x3);
1056
1057                                 /* Enable window */
1058                                 idma_bare_write(j, 0);
1059                                 break;
1060                         }
1061                 }
1062 }
1063
1064 int
1065 decode_win_idma_valid(void)
1066 {
1067         const struct decode_win *wintab;
1068         int c, i, j, rv;
1069         uint32_t b, e, s;
1070
1071         if (idma_wins_no > MV_WIN_IDMA_MAX) {
1072                 printf("IDMA windows: too many entries: %d\n", idma_wins_no);
1073                 return (-1);
1074         }
1075         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1076                 if (ddr_is_active(i))
1077                         c++;
1078
1079         if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
1080                 printf("IDMA windows: too many entries: %d, available: %d\n",
1081                     idma_wins_no, MV_WIN_IDMA_MAX - c);
1082                 return (-1);
1083         }
1084
1085         wintab = idma_wins;
1086         rv = 1;
1087         for (i = 0; i < idma_wins_no; i++, wintab++) {
1088
1089                 if (wintab->target == 0) {
1090                         printf("IDMA window#%d: DDR target window is not "
1091                             "supposed to be reprogrammed!\n", i);
1092                         rv = 0;
1093                 }
1094
1095                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1096                         printf("IDMA window#%d: not capable of remapping, but "
1097                             "val 0x%08x defined\n", i, wintab->remap);
1098                         rv = 0;
1099                 }
1100
1101                 s = wintab->size;
1102                 b = wintab->base;
1103                 e = b + s - 1;
1104                 if (s > (0xFFFFFFFF - b + 1)) {
1105                         /* XXX this boundary check should account for 64bit and
1106                          * remapping.. */
1107                         printf("IDMA window#%d: no space for size 0x%08x at "
1108                             "0x%08x\n", i, s, b);
1109                         rv = 0;
1110                         continue;
1111                 }
1112
1113                 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
1114                 if (j >= 0) {
1115                         printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
1116                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
1117                             idma_wins[j].base,
1118                             idma_wins[j].base + idma_wins[j].size - 1);
1119                         rv = 0;
1120                 }
1121         }
1122
1123         return (rv);
1124 }
1125
1126 void
1127 decode_win_idma_dump(void)
1128 {
1129         int i;
1130
1131         for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
1132                 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
1133                     win_idma_br_read(i), win_idma_sz_read(i));
1134                 
1135                 if (win_idma_can_remap(i))
1136                         printf(", ha 0x%08x", win_idma_har_read(i));
1137
1138                 printf("\n");
1139         }
1140         for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1141                 printf("IDMA channel#%d: ap 0x%08x\n", i,
1142                     win_idma_cap_read(i));
1143         printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read());
1144 }
1145 #else
1146
1147 /* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
1148 int
1149 decode_win_idma_valid(void)
1150 {
1151
1152         return (1);
1153 }
1154
1155 void
1156 decode_win_idma_setup(void)
1157 {
1158 }
1159
1160 void
1161 decode_win_idma_dump(void)
1162 {
1163 }
1164 #endif
1165
1166 /**************************************************************************
1167  * XOR windows routines
1168  **************************************************************************/
1169 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
1170 static int
1171 xor_ctrl_read(int i, int c, int e)
1172 {
1173         uint32_t v;
1174         v = win_xor_ctrl_read(c, e);
1175         v &= (1 << i);
1176
1177         return (v >> i);
1178 }
1179
1180 static void
1181 xor_ctrl_write(int i, int c, int e, int val)
1182 {
1183         uint32_t v;
1184
1185         v = win_xor_ctrl_read(c, e);
1186         v &= ~(1 << i);
1187         v |= (val << i);
1188         win_xor_ctrl_write(c, e, v);
1189 }
1190
1191 /*
1192  * Set channel protection 'val' for window 'w' on channel 'c'
1193  */
1194
1195 static void
1196 xor_chan_write(int c, int e, int w, int val)
1197 {
1198         uint32_t v;
1199
1200         v = win_xor_ctrl_read(c, e);
1201         v &= ~(0x3 << (w * 2 + 16));
1202         v |= (val << (w * 2 + 16));
1203         win_xor_ctrl_write(c, e, v);
1204 }
1205
1206 /*
1207  * Set protection 'val' on all channels for window 'w' on engine 'e'
1208  */
1209 static void
1210 xor_set_prot(int w, int e, int val)
1211 {
1212         int c;
1213
1214         for (c = 0; c < MV_XOR_CHAN_MAX; c++)
1215                 xor_chan_write(c, e, w, val);
1216 }
1217
1218 static int
1219 win_xor_can_remap(int i)
1220 {
1221
1222         /* XOR decode windows 0-3 have remap capability */
1223         if (i < 4)
1224                 return (1);
1225
1226         return (0);
1227 }
1228
1229 static int
1230 xor_max_eng(void)
1231 {
1232         uint32_t dev, rev;
1233
1234         soc_id(&dev, &rev);
1235         if (dev == MV_DEV_88F6281)
1236                 return (2);
1237         else if ((dev == MV_DEV_MV78100) || (dev == MV_DEV_MV78100_Z0))
1238                 return (1);
1239         else
1240                 return (0);
1241 }
1242
1243 static void
1244 xor_active_dram(int c, int e, int *window)
1245 {
1246         uint32_t br, sz;
1247         int i, m, w;
1248
1249         /*
1250          * Set up access to all active DRAM banks
1251          */
1252         m = xor_max_eng();
1253         for (i = 0; i < m; i++)
1254                 if (ddr_is_active(i)) {
1255                         br = ddr_base(i) | (ddr_attr(i) << 8) |
1256                             ddr_target(i);
1257                         sz = ((ddr_size(i) - 1) & 0xffff0000);
1258
1259                         /* Place DDR entries in non-remapped windows */
1260                         for (w = 0; w < MV_WIN_XOR_MAX; w++)
1261                                 if (win_xor_can_remap(w) != 1 &&
1262                                     (xor_ctrl_read(w, c, e) == 0) &&
1263                                     w > *window) {
1264                                         /* Configure window */
1265                                         win_xor_br_write(w, e, br);
1266                                         win_xor_sz_write(w, e, sz);
1267
1268                                         /* Set protection RW on all channels */
1269                                         xor_set_prot(w, e, 0x3);
1270
1271                                         /* Enable window */
1272                                         xor_ctrl_write(w, c, e, 1);
1273                                         (*window)++;
1274                                         break;
1275                                 }
1276                 }
1277 }
1278
1279 void
1280 decode_win_xor_setup(void)
1281 {
1282         uint32_t br, sz;
1283         int i, j, z, e = 1, m, window;
1284
1285         if (pm_is_disabled(CPU_PM_CTRL_XOR))
1286                 return;
1287
1288         /*
1289          * Disable and clear all XOR windows, revoke protection for all
1290          * channels
1291          */
1292         m = xor_max_eng();
1293         for (j = 0; j < m; j++, e--) {
1294
1295                 /* Number of non-remaped windows */
1296                 window = MV_XOR_NON_REMAP - 1;
1297
1298                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1299                         win_xor_br_write(i, e, 0);
1300                         win_xor_sz_write(i, e, 0);
1301                 }
1302
1303                 if (win_xor_can_remap(i) == 1)
1304                         win_xor_har_write(i, e, 0);
1305
1306                 for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
1307                         win_xor_ctrl_write(i, e, 0);
1308                         xor_active_dram(i, e, &window);
1309                 }
1310
1311                 /*
1312                  * Remaining targets -- from a statically defined table
1313                  */
1314                 for (i = 0; i < xor_wins_no; i++)
1315                         if (xor_wins[i].target > 0) {
1316                                 br = (xor_wins[i].base & 0xffff0000) |
1317                                     (xor_wins[i].attr << 8) |
1318                                     xor_wins[i].target;
1319                                 sz = ((xor_wins[i].size - 1) & 0xffff0000);
1320
1321                                 /* Set the first free XOR window */
1322                                 for (z = 0; z < MV_WIN_XOR_MAX; z++) {
1323                                         if (xor_ctrl_read(z, 0, e) &&
1324                                             xor_ctrl_read(z, 1, e))
1325                                                 continue;
1326
1327                                         /* Configure window */
1328                                         win_xor_br_write(z, e, br);
1329                                         win_xor_sz_write(z, e, sz);
1330                                         if (win_xor_can_remap(z) &&
1331                                             xor_wins[z].remap >= 0)
1332                                                 win_xor_har_write(z, e,
1333                                                     xor_wins[z].remap);
1334
1335                                         /* Set protection RW on all channels */
1336                                         xor_set_prot(z, e, 0x3);
1337
1338                                         /* Enable window */
1339                                         xor_ctrl_write(z, 0, e, 1);
1340                                         xor_ctrl_write(z, 1, e, 1);
1341                                         break;
1342                                 }
1343                         }
1344         }
1345 }
1346
1347 int
1348 decode_win_xor_valid(void)
1349 {
1350         const struct decode_win *wintab;
1351         int c, i, j, rv;
1352         uint32_t b, e, s;
1353
1354         if (xor_wins_no > MV_WIN_XOR_MAX) {
1355                 printf("XOR windows: too many entries: %d\n", xor_wins_no);
1356                 return (-1);
1357         }
1358         for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1359                 if (ddr_is_active(i))
1360                         c++;
1361
1362         if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
1363                 printf("XOR windows: too many entries: %d, available: %d\n",
1364                     xor_wins_no, MV_WIN_IDMA_MAX - c);
1365                 return (-1);
1366         }
1367
1368         wintab = xor_wins;
1369         rv = 1;
1370         for (i = 0; i < xor_wins_no; i++, wintab++) {
1371
1372                 if (wintab->target == 0) {
1373                         printf("XOR window#%d: DDR target window is not "
1374                             "supposed to be reprogrammed!\n", i);
1375                         rv = 0;
1376                 }
1377
1378                 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1379                         printf("XOR window#%d: not capable of remapping, but "
1380                             "val 0x%08x defined\n", i, wintab->remap);
1381                         rv = 0;
1382                 }
1383
1384                 s = wintab->size;
1385                 b = wintab->base;
1386                 e = b + s - 1;
1387                 if (s > (0xFFFFFFFF - b + 1)) {
1388                         /*
1389                          * XXX this boundary check should account for 64bit
1390                          * and remapping..
1391                          */
1392                         printf("XOR window#%d: no space for size 0x%08x at "
1393                             "0x%08x\n", i, s, b);
1394                         rv = 0;
1395                         continue;
1396                 }
1397
1398                 j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
1399                 if (j >= 0) {
1400                         printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
1401                             "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
1402                             xor_wins[j].base,
1403                             xor_wins[j].base + xor_wins[j].size - 1);
1404                         rv = 0;
1405                 }
1406         }
1407
1408         return (rv);
1409 }
1410
1411 void
1412 decode_win_xor_dump(void)
1413 {
1414         int i, j;
1415         int e = 1;
1416
1417         for (j = 0; j < xor_max_eng(); j++, e--) {
1418                 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1419                         printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
1420                             win_xor_br_read(i, e), win_xor_sz_read(i, e));
1421
1422                         if (win_xor_can_remap(i))
1423                                 printf(", ha 0x%08x", win_xor_har_read(i, e));
1424
1425                         printf("\n");
1426                 }
1427                 for (i = 0; i < MV_XOR_CHAN_MAX; i++)
1428                         printf("XOR control#%d: 0x%08x\n", i,
1429                             win_xor_ctrl_read(i, e));
1430         }
1431 }
1432
1433 #else
1434 /* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
1435 int
1436 decode_win_xor_valid(void)
1437 {
1438
1439         return (1);
1440 }
1441
1442 void
1443 decode_win_xor_setup(void)
1444 {
1445 }
1446
1447 void
1448 decode_win_xor_dump(void)
1449 {
1450 }
1451 #endif
1452
1453 /**************************************************************************
1454  * CESA TDMA windows routines
1455  **************************************************************************/
1456 #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
1457 /*
1458  * Dump CESA TDMA decode windows.
1459  */
1460 static void
1461 decode_win_cesa_dump(void)
1462 {
1463         int i;
1464
1465         for (i = 0; i < MV_WIN_CESA_MAX; i++)
1466                 printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
1467                     win_cesa_cr_read(i), win_cesa_br_read(i));
1468 }
1469
1470
1471 /*
1472  * Set CESA TDMA decode windows.
1473  */
1474 static void
1475 decode_win_cesa_setup(void)
1476 {
1477         uint32_t br, cr;
1478         int i, j;
1479
1480         if (pm_is_disabled(CPU_PM_CTRL_CRYPTO))
1481                 return;
1482
1483         /* Disable and clear all CESA windows */
1484         for (i = 0; i < MV_WIN_CESA_MAX; i++) {
1485                 win_cesa_cr_write(i, 0);
1486                 win_cesa_br_write(i, 0);
1487         }
1488
1489         /* Only access to active DRAM banks is required. */
1490         for (i = 0; i < MV_WIN_DDR_MAX; i++)
1491                 if (ddr_is_active(i)) {
1492                         br = ddr_base(i);
1493                         cr = (((ddr_size(i) - 1) & 0xffff0000) |
1494                            (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
1495
1496                         /* Set the first available CESA window */
1497                         for (j = 0; j < MV_WIN_CESA_MAX; j++) {
1498                                 if (win_cesa_cr_read(j) & 0x1)
1499                                         continue;
1500
1501                                 win_cesa_br_write(j, br);
1502                                 win_cesa_cr_write(j, cr);
1503                                 break;
1504                         }
1505                 }
1506 }
1507
1508 /*
1509  * Check CESA TDMA decode windows.
1510  */
1511 static int
1512 decode_win_cesa_valid(void)
1513 {
1514
1515         return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
1516 }
1517 #else
1518
1519 /*
1520  * Provide dummy functions to satisfy the build for SoCs not equipped with
1521  * CESA
1522  */
1523
1524 int
1525 decode_win_cesa_valid(void)
1526 {
1527
1528         return (1);
1529 }
1530
1531 void
1532 decode_win_cesa_setup(void)
1533 {
1534 }
1535
1536 void
1537 decode_win_cesa_dump(void)
1538 {
1539 }
1540 #endif
1541
1542 /**************************************************************************
1543  * SATA windows routines
1544  **************************************************************************/
1545 static void
1546 decode_win_sata_setup(void)
1547 {
1548         uint32_t cr, br;
1549         int i, j;
1550
1551         if (pm_is_disabled(CPU_PM_CTRL_SATA))
1552                 return;
1553
1554         for (i = 0; i < MV_WIN_SATA_MAX; i++) {
1555                 win_sata_cr_write(i, 0);
1556                 win_sata_br_write(i, 0);
1557         }
1558
1559         for (i = 0; i < MV_WIN_DDR_MAX; i++)
1560                 if (ddr_is_active(i)) {
1561                         cr = ((ddr_size(i) - 1) & 0xffff0000) |
1562                             (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
1563                         br = ddr_base(i);
1564
1565                         /* Use the first available SATA window */
1566                         for (j = 0; j < MV_WIN_SATA_MAX; j++) {
1567                                 if ((win_sata_cr_read(j) & 1) != 0)
1568                                         continue;
1569
1570                                 win_sata_br_write(j, br);
1571                                 win_sata_cr_write(j, cr);
1572                                 break;
1573                         }
1574                 }
1575 }
1576
1577 static int
1578 decode_win_sata_valid(void)
1579 {
1580         uint32_t dev, rev;
1581
1582         soc_id(&dev, &rev);
1583         if (dev == MV_DEV_88F5281)
1584                 return (1);
1585
1586         return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
1587 }