Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mv64x60.c
Go to the documentation of this file.
1 /*
2  * Marvell hostbridge routines
3  *
4  * Author: Mark A. Greer <[email protected]>
5  *
6  * 2004, 2005, 2007 (c) MontaVista Software, Inc. This file is licensed under
7  * the terms of the GNU General Public License version 2. This program
8  * is licensed "as is" without any warranty of any kind, whether express
9  * or implied.
10  */
11 
12 #include <stdarg.h>
13 #include <stddef.h>
14 #include "types.h"
15 #include "elf.h"
16 #include "page.h"
17 #include "string.h"
18 #include "stdio.h"
19 #include "io.h"
20 #include "ops.h"
21 #include "mv64x60.h"
22 
23 #define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
24 
25 #define MV64x60_CPU2MEM_WINDOWS 4
26 #define MV64x60_CPU2MEM_0_BASE 0x0008
27 #define MV64x60_CPU2MEM_0_SIZE 0x0010
28 #define MV64x60_CPU2MEM_1_BASE 0x0208
29 #define MV64x60_CPU2MEM_1_SIZE 0x0210
30 #define MV64x60_CPU2MEM_2_BASE 0x0018
31 #define MV64x60_CPU2MEM_2_SIZE 0x0020
32 #define MV64x60_CPU2MEM_3_BASE 0x0218
33 #define MV64x60_CPU2MEM_3_SIZE 0x0220
34 
35 #define MV64x60_ENET2MEM_BAR_ENABLE 0x2290
36 #define MV64x60_ENET2MEM_0_BASE 0x2200
37 #define MV64x60_ENET2MEM_0_SIZE 0x2204
38 #define MV64x60_ENET2MEM_1_BASE 0x2208
39 #define MV64x60_ENET2MEM_1_SIZE 0x220c
40 #define MV64x60_ENET2MEM_2_BASE 0x2210
41 #define MV64x60_ENET2MEM_2_SIZE 0x2214
42 #define MV64x60_ENET2MEM_3_BASE 0x2218
43 #define MV64x60_ENET2MEM_3_SIZE 0x221c
44 #define MV64x60_ENET2MEM_4_BASE 0x2220
45 #define MV64x60_ENET2MEM_4_SIZE 0x2224
46 #define MV64x60_ENET2MEM_5_BASE 0x2228
47 #define MV64x60_ENET2MEM_5_SIZE 0x222c
48 #define MV64x60_ENET2MEM_ACC_PROT_0 0x2294
49 #define MV64x60_ENET2MEM_ACC_PROT_1 0x2298
50 #define MV64x60_ENET2MEM_ACC_PROT_2 0x229c
51 
52 #define MV64x60_MPSC2MEM_BAR_ENABLE 0xf250
53 #define MV64x60_MPSC2MEM_0_BASE 0xf200
54 #define MV64x60_MPSC2MEM_0_SIZE 0xf204
55 #define MV64x60_MPSC2MEM_1_BASE 0xf208
56 #define MV64x60_MPSC2MEM_1_SIZE 0xf20c
57 #define MV64x60_MPSC2MEM_2_BASE 0xf210
58 #define MV64x60_MPSC2MEM_2_SIZE 0xf214
59 #define MV64x60_MPSC2MEM_3_BASE 0xf218
60 #define MV64x60_MPSC2MEM_3_SIZE 0xf21c
61 #define MV64x60_MPSC_0_REMAP 0xf240
62 #define MV64x60_MPSC_1_REMAP 0xf244
63 #define MV64x60_MPSC2MEM_ACC_PROT_0 0xf254
64 #define MV64x60_MPSC2MEM_ACC_PROT_1 0xf258
65 #define MV64x60_MPSC2REGS_BASE 0xf25c
66 
67 #define MV64x60_IDMA2MEM_BAR_ENABLE 0x0a80
68 #define MV64x60_IDMA2MEM_0_BASE 0x0a00
69 #define MV64x60_IDMA2MEM_0_SIZE 0x0a04
70 #define MV64x60_IDMA2MEM_1_BASE 0x0a08
71 #define MV64x60_IDMA2MEM_1_SIZE 0x0a0c
72 #define MV64x60_IDMA2MEM_2_BASE 0x0a10
73 #define MV64x60_IDMA2MEM_2_SIZE 0x0a14
74 #define MV64x60_IDMA2MEM_3_BASE 0x0a18
75 #define MV64x60_IDMA2MEM_3_SIZE 0x0a1c
76 #define MV64x60_IDMA2MEM_4_BASE 0x0a20
77 #define MV64x60_IDMA2MEM_4_SIZE 0x0a24
78 #define MV64x60_IDMA2MEM_5_BASE 0x0a28
79 #define MV64x60_IDMA2MEM_5_SIZE 0x0a2c
80 #define MV64x60_IDMA2MEM_6_BASE 0x0a30
81 #define MV64x60_IDMA2MEM_6_SIZE 0x0a34
82 #define MV64x60_IDMA2MEM_7_BASE 0x0a38
83 #define MV64x60_IDMA2MEM_7_SIZE 0x0a3c
84 #define MV64x60_IDMA2MEM_ACC_PROT_0 0x0a70
85 #define MV64x60_IDMA2MEM_ACC_PROT_1 0x0a74
86 #define MV64x60_IDMA2MEM_ACC_PROT_2 0x0a78
87 #define MV64x60_IDMA2MEM_ACC_PROT_3 0x0a7c
88 
89 #define MV64x60_PCI_ACC_CNTL_WINDOWS 6
90 #define MV64x60_PCI0_PCI_DECODE_CNTL 0x0d3c
91 #define MV64x60_PCI1_PCI_DECODE_CNTL 0x0dbc
92 
93 #define MV64x60_PCI0_BAR_ENABLE 0x0c3c
94 #define MV64x60_PCI02MEM_0_SIZE 0x0c08
95 #define MV64x60_PCI0_ACC_CNTL_0_BASE_LO 0x1e00
96 #define MV64x60_PCI0_ACC_CNTL_0_BASE_HI 0x1e04
97 #define MV64x60_PCI0_ACC_CNTL_0_SIZE 0x1e08
98 #define MV64x60_PCI0_ACC_CNTL_1_BASE_LO 0x1e10
99 #define MV64x60_PCI0_ACC_CNTL_1_BASE_HI 0x1e14
100 #define MV64x60_PCI0_ACC_CNTL_1_SIZE 0x1e18
101 #define MV64x60_PCI0_ACC_CNTL_2_BASE_LO 0x1e20
102 #define MV64x60_PCI0_ACC_CNTL_2_BASE_HI 0x1e24
103 #define MV64x60_PCI0_ACC_CNTL_2_SIZE 0x1e28
104 #define MV64x60_PCI0_ACC_CNTL_3_BASE_LO 0x1e30
105 #define MV64x60_PCI0_ACC_CNTL_3_BASE_HI 0x1e34
106 #define MV64x60_PCI0_ACC_CNTL_3_SIZE 0x1e38
107 #define MV64x60_PCI0_ACC_CNTL_4_BASE_LO 0x1e40
108 #define MV64x60_PCI0_ACC_CNTL_4_BASE_HI 0x1e44
109 #define MV64x60_PCI0_ACC_CNTL_4_SIZE 0x1e48
110 #define MV64x60_PCI0_ACC_CNTL_5_BASE_LO 0x1e50
111 #define MV64x60_PCI0_ACC_CNTL_5_BASE_HI 0x1e54
112 #define MV64x60_PCI0_ACC_CNTL_5_SIZE 0x1e58
113 
114 #define MV64x60_PCI1_BAR_ENABLE 0x0cbc
115 #define MV64x60_PCI12MEM_0_SIZE 0x0c88
116 #define MV64x60_PCI1_ACC_CNTL_0_BASE_LO 0x1e80
117 #define MV64x60_PCI1_ACC_CNTL_0_BASE_HI 0x1e84
118 #define MV64x60_PCI1_ACC_CNTL_0_SIZE 0x1e88
119 #define MV64x60_PCI1_ACC_CNTL_1_BASE_LO 0x1e90
120 #define MV64x60_PCI1_ACC_CNTL_1_BASE_HI 0x1e94
121 #define MV64x60_PCI1_ACC_CNTL_1_SIZE 0x1e98
122 #define MV64x60_PCI1_ACC_CNTL_2_BASE_LO 0x1ea0
123 #define MV64x60_PCI1_ACC_CNTL_2_BASE_HI 0x1ea4
124 #define MV64x60_PCI1_ACC_CNTL_2_SIZE 0x1ea8
125 #define MV64x60_PCI1_ACC_CNTL_3_BASE_LO 0x1eb0
126 #define MV64x60_PCI1_ACC_CNTL_3_BASE_HI 0x1eb4
127 #define MV64x60_PCI1_ACC_CNTL_3_SIZE 0x1eb8
128 #define MV64x60_PCI1_ACC_CNTL_4_BASE_LO 0x1ec0
129 #define MV64x60_PCI1_ACC_CNTL_4_BASE_HI 0x1ec4
130 #define MV64x60_PCI1_ACC_CNTL_4_SIZE 0x1ec8
131 #define MV64x60_PCI1_ACC_CNTL_5_BASE_LO 0x1ed0
132 #define MV64x60_PCI1_ACC_CNTL_5_BASE_HI 0x1ed4
133 #define MV64x60_PCI1_ACC_CNTL_5_SIZE 0x1ed8
134 
135 #define MV64x60_CPU2PCI_SWAP_NONE 0x01000000
136 
137 #define MV64x60_CPU2PCI0_IO_BASE 0x0048
138 #define MV64x60_CPU2PCI0_IO_SIZE 0x0050
139 #define MV64x60_CPU2PCI0_IO_REMAP 0x00f0
140 #define MV64x60_CPU2PCI0_MEM_0_BASE 0x0058
141 #define MV64x60_CPU2PCI0_MEM_0_SIZE 0x0060
142 #define MV64x60_CPU2PCI0_MEM_0_REMAP_LO 0x00f8
143 #define MV64x60_CPU2PCI0_MEM_0_REMAP_HI 0x0320
144 
145 #define MV64x60_CPU2PCI1_IO_BASE 0x0090
146 #define MV64x60_CPU2PCI1_IO_SIZE 0x0098
147 #define MV64x60_CPU2PCI1_IO_REMAP 0x0108
148 #define MV64x60_CPU2PCI1_MEM_0_BASE 0x00a0
149 #define MV64x60_CPU2PCI1_MEM_0_SIZE 0x00a8
150 #define MV64x60_CPU2PCI1_MEM_0_REMAP_LO 0x0110
151 #define MV64x60_CPU2PCI1_MEM_0_REMAP_HI 0x0340
152 
157 };
158 
164 };
165 
166 /* PCI config access routines */
167 struct {
170 } static mv64x60_pci_cfgio[2] = {
171  { /* hose 0 */
172  .addr = 0xcf8,
173  .data = 0xcfc,
174  },
175  { /* hose 1 */
176  .addr = 0xc78,
177  .data = 0xc7c,
178  }
179 };
180 
181 u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset)
182 {
183  out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
184  (1 << 31) | (bus << 16) | (devfn << 8) | offset);
185  return in_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data));
186 }
187 
188 void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset,
189  u32 val)
190 {
191  out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
192  (1 << 31) | (bus << 16) | (devfn << 8) | offset);
193  out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data), val);
194 }
195 
196 /* I/O ctlr -> system memory setup */
197 static struct mv64x60_mem_win mv64x60_cpu2mem[MV64x60_CPU2MEM_WINDOWS] = {
198  {
200  .size = MV64x60_CPU2MEM_0_SIZE,
201  },
202  {
204  .size = MV64x60_CPU2MEM_1_SIZE,
205  },
206  {
208  .size = MV64x60_CPU2MEM_2_SIZE,
209  },
210  {
212  .size = MV64x60_CPU2MEM_3_SIZE,
213  },
214 };
215 
216 static struct mv64x60_mem_win mv64x60_enet2mem[MV64x60_CPU2MEM_WINDOWS] = {
217  {
219  .size = MV64x60_ENET2MEM_0_SIZE,
220  },
221  {
223  .size = MV64x60_ENET2MEM_1_SIZE,
224  },
225  {
227  .size = MV64x60_ENET2MEM_2_SIZE,
228  },
229  {
231  .size = MV64x60_ENET2MEM_3_SIZE,
232  },
233 };
234 
235 static struct mv64x60_mem_win mv64x60_mpsc2mem[MV64x60_CPU2MEM_WINDOWS] = {
236  {
238  .size = MV64x60_MPSC2MEM_0_SIZE,
239  },
240  {
242  .size = MV64x60_MPSC2MEM_1_SIZE,
243  },
244  {
246  .size = MV64x60_MPSC2MEM_2_SIZE,
247  },
248  {
250  .size = MV64x60_MPSC2MEM_3_SIZE,
251  },
252 };
253 
254 static struct mv64x60_mem_win mv64x60_idma2mem[MV64x60_CPU2MEM_WINDOWS] = {
255  {
257  .size = MV64x60_IDMA2MEM_0_SIZE,
258  },
259  {
261  .size = MV64x60_IDMA2MEM_1_SIZE,
262  },
263  {
265  .size = MV64x60_IDMA2MEM_2_SIZE,
266  },
267  {
269  .size = MV64x60_IDMA2MEM_3_SIZE,
270  },
271 };
272 
273 static u32 mv64x60_dram_selects[MV64x60_CPU2MEM_WINDOWS] = {0xe,0xd,0xb,0x7};
274 
275 /*
276  * ENET, MPSC, and IDMA ctlrs on the MV64x60 have separate windows that
277  * must be set up so that the respective ctlr can access system memory.
278  * Configure them to be same as cpu->memory windows.
279  */
280 void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
281  u8 is_coherent)
282 {
283  u32 i, base, size, enables, prot = 0, snoop_bits = 0;
284 
285  /* Disable ctlr->mem windows */
286  out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0x3f);
287  out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), 0xf);
288  out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0xff);
289 
290  if (is_coherent)
291  snoop_bits = 0x2 << 12; /* Writeback */
292 
293  enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
294 
295  for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
296  if (enables & (1 << i)) /* Set means disabled */
297  continue;
298 
299  base = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].lo))
300  << 16;
301  base |= snoop_bits | (mv64x60_dram_selects[i] << 8);
302  size = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].size))
303  << 16;
304  prot |= (0x3 << (i << 1)); /* RW access */
305 
306  out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].lo), base);
307  out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].size), size);
308  out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].lo), base);
309  out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].size), size);
310  out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].lo), base);
311  out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].size), size);
312  }
313 
314  out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_0), prot);
315  out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_1), prot);
316  out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_2), prot);
317  out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_0), prot);
318  out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_1), prot);
319  out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_0), prot);
320  out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_1), prot);
321  out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_2), prot);
322  out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_3), prot);
323 
324  /* Set mpsc->bridge's reg window to the bridge's internal registers. */
325  out_le32((u32 *)(bridge_base + MV64x60_MPSC2REGS_BASE),
326  (u32)bridge_pbase);
327 
328  out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), enables);
329  out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), enables);
330  out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_BAR_ENABLE), enables);
331 }
332 
333 /* PCI MEM -> system memory, et. al. setup */
334 static struct mv64x60_pci_win mv64x60_pci2mem[2] = {
335  { /* hose 0 */
336  .fcn = 0,
337  .hi = 0x14,
338  .lo = 0x10,
339  .size = MV64x60_PCI02MEM_0_SIZE,
340  },
341  { /* hose 1 */
342  .fcn = 0,
343  .hi = 0x94,
344  .lo = 0x90,
345  .size = MV64x60_PCI12MEM_0_SIZE,
346  },
347 };
348 
349 static struct
350 mv64x60_mem_win mv64x60_pci_acc[2][MV64x60_PCI_ACC_CNTL_WINDOWS] = {
351  { /* hose 0 */
352  {
356  },
357  {
361  },
362  {
366  },
367  {
371  },
372  },
373  { /* hose 1 */
374  {
378  },
379  {
383  },
384  {
388  },
389  {
393  },
394  },
395 };
396 
397 static struct mv64x60_mem_win mv64x60_pci2reg[2] = {
398  {
399  .hi = 0x24,
400  .lo = 0x20,
401  .size = 0,
402  },
403  {
404  .hi = 0xa4,
405  .lo = 0xa0,
406  .size = 0,
407  },
408 };
409 
410 /* Only need to use 1 window (per hose) to get access to all of system memory */
411 void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
412  u8 bus, u32 mem_size, u32 acc_bits)
413 {
414  u32 i, offset, bar_enable, enables;
415 
416  /* Disable all windows but PCI MEM -> Bridge's regs window */
417  enables = ~(1 << 9);
418  bar_enable = hose ? MV64x60_PCI1_BAR_ENABLE : MV64x60_PCI0_BAR_ENABLE;
419  out_le32((u32 *)(bridge_base + bar_enable), enables);
420 
421  for (i=0; i<MV64x60_PCI_ACC_CNTL_WINDOWS; i++)
422  out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][i].lo), 0);
423 
424  /* If mem_size is 0, leave windows disabled */
425  if (mem_size == 0)
426  return;
427 
428  /* Cause automatic updates of PCI remap regs */
429  offset = hose ?
431  i = in_le32((u32 *)(bridge_base + offset));
432  out_le32((u32 *)(bridge_base + offset), i & ~0x1);
433 
434  mem_size = (mem_size - 1) & 0xfffff000;
435 
436  /* Map PCI MEM addr 0 -> System Mem addr 0 */
437  mv64x60_cfg_write(bridge_base, hose, bus,
438  PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
439  mv64x60_pci2mem[hose].hi, 0);
440  mv64x60_cfg_write(bridge_base, hose, bus,
441  PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
442  mv64x60_pci2mem[hose].lo, 0);
443  out_le32((u32 *)(bridge_base + mv64x60_pci2mem[hose].size),mem_size);
444 
445  acc_bits |= MV64x60_PCI_ACC_CNTL_ENABLE;
446  out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].hi), 0);
447  out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].lo), acc_bits);
448  out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].size),mem_size);
449 
450  /* Set PCI MEM->bridge's reg window to where they are in CPU mem map */
451  i = (u32)bridge_base;
452  i &= 0xffff0000;
453  i |= (0x2 << 1);
454  mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
455  mv64x60_pci2reg[hose].hi, 0);
456  mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
457  mv64x60_pci2reg[hose].lo, i);
458 
459  enables &= ~0x1; /* Enable PCI MEM -> System Mem window 0 */
460  out_le32((u32 *)(bridge_base + bar_enable), enables);
461 }
462 
463 /* CPU -> PCI I/O & MEM setup */
465  { /* hose 0 */
467  .size = MV64x60_CPU2PCI0_IO_SIZE,
468  .remap_hi = 0,
469  .remap_lo = MV64x60_CPU2PCI0_IO_REMAP,
470  },
471  { /* hose 1 */
473  .size = MV64x60_CPU2PCI1_IO_SIZE,
474  .remap_hi = 0,
475  .remap_lo = MV64x60_CPU2PCI1_IO_REMAP,
476  },
477 };
478 
480  { /* hose 0 */
485  },
486  { /* hose 1 */
491  },
492 };
493 
494 /* Only need to set up 1 window to pci mem space */
495 void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
496  u32 pci_base_lo, u32 cpu_base, u32 size,
497  struct mv64x60_cpu2pci_win *offset_tbl)
498 {
499  cpu_base >>= 16;
500  cpu_base |= MV64x60_CPU2PCI_SWAP_NONE;
501  out_le32((u32 *)(bridge_base + offset_tbl[hose].lo), cpu_base);
502 
503  if (offset_tbl[hose].remap_hi != 0)
504  out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_hi),
505  pci_base_hi);
506  out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_lo),
507  pci_base_lo >> 16);
508 
509  size = (size - 1) >> 16;
510  out_le32((u32 *)(bridge_base + offset_tbl[hose].size), size);
511 }
512 
513 /* Read mem ctlr to get the amount of mem in system */
515 {
516  u32 enables, i, v;
517  u32 mem = 0;
518 
519  enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
520 
521  for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
522  if (!(enables & (1<<i))) {
523  v = in_le32((u32*)(bridge_base
524  + mv64x60_cpu2mem[i].size));
525  v = ((v & 0xffff) + 1) << 16;
526  mem += v;
527  }
528 
529  return mem;
530 }
531 
532 /* Get physical address of bridge's registers */
534 {
535  u32 v[2];
536  void *devp;
537 
538  devp = find_node_by_compatible(NULL, "marvell,mv64360");
539  if (devp == NULL)
540  goto err_out;
541  if (getprop(devp, "reg", v, sizeof(v)) != sizeof(v))
542  goto err_out;
543 
544  return (u8 *)v[0];
545 
546 err_out:
547  return 0;
548 }
549 
550 /* Get virtual address of bridge's registers */
552 {
553  u32 v;
554  void *devp;
555 
556  devp = find_node_by_compatible(NULL, "marvell,mv64360");
557  if (devp == NULL)
558  goto err_out;
559  if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
560  goto err_out;
561 
562  return (u8 *)v;
563 
564 err_out:
565  return 0;
566 }
567 
569 {
570  u32 v;
571  void *devp;
572 
573  devp = finddevice("/");
574  if (devp == NULL)
575  return 1; /* Assume coherency on */
576 
577  if (getprop(devp, "coherency-off", &v, sizeof(v)) < 0)
578  return 1; /* Coherency on */
579  else
580  return 0;
581 }