~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/boot/mv64x60.c

Version: ~ [ linux-5.1-rc1 ] ~ [ linux-5.0.3 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.30 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.107 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.164 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.176 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.136 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.63 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Marvell hostbridge routines
  3  *
  4  * Author: Mark A. Greer <source@mvista.com>
  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 
153 struct mv64x60_mem_win {
154         u32 hi;
155         u32 lo;
156         u32 size;
157 };
158 
159 struct mv64x60_pci_win {
160         u32 fcn;
161         u32 hi;
162         u32 lo;
163         u32 size;
164 };
165 
166 /* PCI config access routines */
167 struct {
168         u32 addr;
169         u32 data;
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         {
199                 .lo     = MV64x60_CPU2MEM_0_BASE,
200                 .size   = MV64x60_CPU2MEM_0_SIZE,
201         },
202         {
203                 .lo     = MV64x60_CPU2MEM_1_BASE,
204                 .size   = MV64x60_CPU2MEM_1_SIZE,
205         },
206         {
207                 .lo     = MV64x60_CPU2MEM_2_BASE,
208                 .size   = MV64x60_CPU2MEM_2_SIZE,
209         },
210         {
211                 .lo     = MV64x60_CPU2MEM_3_BASE,
212                 .size   = MV64x60_CPU2MEM_3_SIZE,
213         },
214 };
215 
216 static struct mv64x60_mem_win mv64x60_enet2mem[MV64x60_CPU2MEM_WINDOWS] = {
217         {
218                 .lo     = MV64x60_ENET2MEM_0_BASE,
219                 .size   = MV64x60_ENET2MEM_0_SIZE,
220         },
221         {
222                 .lo     = MV64x60_ENET2MEM_1_BASE,
223                 .size   = MV64x60_ENET2MEM_1_SIZE,
224         },
225         {
226                 .lo     = MV64x60_ENET2MEM_2_BASE,
227                 .size   = MV64x60_ENET2MEM_2_SIZE,
228         },
229         {
230                 .lo     = MV64x60_ENET2MEM_3_BASE,
231                 .size   = MV64x60_ENET2MEM_3_SIZE,
232         },
233 };
234 
235 static struct mv64x60_mem_win mv64x60_mpsc2mem[MV64x60_CPU2MEM_WINDOWS] = {
236         {
237                 .lo     = MV64x60_MPSC2MEM_0_BASE,
238                 .size   = MV64x60_MPSC2MEM_0_SIZE,
239         },
240         {
241                 .lo     = MV64x60_MPSC2MEM_1_BASE,
242                 .size   = MV64x60_MPSC2MEM_1_SIZE,
243         },
244         {
245                 .lo     = MV64x60_MPSC2MEM_2_BASE,
246                 .size   = MV64x60_MPSC2MEM_2_SIZE,
247         },
248         {
249                 .lo     = MV64x60_MPSC2MEM_3_BASE,
250                 .size   = MV64x60_MPSC2MEM_3_SIZE,
251         },
252 };
253 
254 static struct mv64x60_mem_win mv64x60_idma2mem[MV64x60_CPU2MEM_WINDOWS] = {
255         {
256                 .lo     = MV64x60_IDMA2MEM_0_BASE,
257                 .size   = MV64x60_IDMA2MEM_0_SIZE,
258         },
259         {
260                 .lo     = MV64x60_IDMA2MEM_1_BASE,
261                 .size   = MV64x60_IDMA2MEM_1_SIZE,
262         },
263         {
264                 .lo     = MV64x60_IDMA2MEM_2_BASE,
265                 .size   = MV64x60_IDMA2MEM_2_SIZE,
266         },
267         {
268                 .lo     = MV64x60_IDMA2MEM_3_BASE,
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                 {
353                         .hi     = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
354                         .lo     = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
355                         .size   = MV64x60_PCI0_ACC_CNTL_0_SIZE,
356                 },
357                 {
358                         .hi     = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
359                         .lo     = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
360                         .size   = MV64x60_PCI0_ACC_CNTL_1_SIZE,
361                 },
362                 {
363                         .hi     = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
364                         .lo     = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
365                         .size   = MV64x60_PCI0_ACC_CNTL_2_SIZE,
366                 },
367                 {
368                         .hi     = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
369                         .lo     = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
370                         .size   = MV64x60_PCI0_ACC_CNTL_3_SIZE,
371                 },
372         },
373         { /* hose 1 */
374                 {
375                         .hi     = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
376                         .lo     = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
377                         .size   = MV64x60_PCI1_ACC_CNTL_0_SIZE,
378                 },
379                 {
380                         .hi     = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
381                         .lo     = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
382                         .size   = MV64x60_PCI1_ACC_CNTL_1_SIZE,
383                 },
384                 {
385                         .hi     = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
386                         .lo     = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
387                         .size   = MV64x60_PCI1_ACC_CNTL_2_SIZE,
388                 },
389                 {
390                         .hi     = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
391                         .lo     = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
392                         .size   = MV64x60_PCI1_ACC_CNTL_3_SIZE,
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 ?
430                 MV64x60_PCI1_PCI_DECODE_CNTL : MV64x60_PCI0_PCI_DECODE_CNTL;
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 */
464 struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2] = {
465         { /* hose 0 */
466                 .lo             = MV64x60_CPU2PCI0_IO_BASE,
467                 .size           = MV64x60_CPU2PCI0_IO_SIZE,
468                 .remap_hi       = 0,
469                 .remap_lo       = MV64x60_CPU2PCI0_IO_REMAP,
470         },
471         { /* hose 1 */
472                 .lo             = MV64x60_CPU2PCI1_IO_BASE,
473                 .size           = MV64x60_CPU2PCI1_IO_SIZE,
474                 .remap_hi       = 0,
475                 .remap_lo       = MV64x60_CPU2PCI1_IO_REMAP,
476         },
477 };
478 
479 struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2] = {
480         { /* hose 0 */
481                 .lo             = MV64x60_CPU2PCI0_MEM_0_BASE,
482                 .size           = MV64x60_CPU2PCI0_MEM_0_SIZE,
483                 .remap_hi       = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
484                 .remap_lo       = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
485         },
486         { /* hose 1 */
487                 .lo             = MV64x60_CPU2PCI1_MEM_0_BASE,
488                 .size           = MV64x60_CPU2PCI1_MEM_0_SIZE,
489                 .remap_hi       = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
490                 .remap_lo       = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
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 */
514 u32 mv64x60_get_mem_size(u8 *bridge_base)
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 */
533 u8 *mv64x60_get_bridge_pbase(void)
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 */
551 u8 *mv64x60_get_bridge_base(void)
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 
568 u8 mv64x60_is_coherent(void)
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 }
582 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp