FreeBSD/Linux Kernel Cross Reference
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: releng/8.0/sys/arm/mv/common.c 197251 2009-09-16 12:07:58Z raj $");
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 }
Cache object: 82aad0780dc4b2664cc82b464467e548
|