blob: 7ac8ce0d765ba3a9e7d11b25ed8b8c396c6cd10a [file] [log] [blame]
Rafal Jaworowski692519b2006-08-10 12:43:17 +02001/*
Grzegorz Bernackic9240982007-07-31 18:51:48 +02002 * (C) Copyright 2006 - 2007
Rafal Jaworowski692519b2006-08-10 12:43:17 +02003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * Copyright (c) 2005 Cisco Systems. All rights reserved.
6 * Roland Dreier <rolandd@cisco.com>
7 *
8 * See file CREDITS for list of people who contributed to this
9 * project.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 */
22
Stefan Roese4dbee8a2007-10-05 07:57:20 +020023/* define DEBUG for debugging output (obviously ;-)) */
24#if 1
25#define DEBUG
26#endif
27
Rafal Jaworowski692519b2006-08-10 12:43:17 +020028#include <asm/processor.h>
29#include <asm-ppc/io.h>
30#include <ppc4xx.h>
31#include <common.h>
32#include <pci.h>
33
Stefan Roese5fb692c2007-01-18 10:25:34 +010034#if defined(CONFIG_440SPE) && defined(CONFIG_PCI)
Rafal Jaworowski692519b2006-08-10 12:43:17 +020035
Stefan Roesec7c6da22007-10-03 07:34:10 +020036#include <asm/4xx_pcie.h>
Rafal Jaworowski692519b2006-08-10 12:43:17 +020037
38enum {
39 PTYPE_ENDPOINT = 0x0,
40 PTYPE_LEGACY_ENDPOINT = 0x1,
41 PTYPE_ROOT_PORT = 0x4,
42
43 LNKW_X1 = 0x1,
44 LNKW_X4 = 0x4,
45 LNKW_X8 = 0x8
46};
47
Grzegorz Bernacki7f191392007-09-07 18:20:23 +020048static u8* pcie_get_base(struct pci_controller *hose, unsigned int devfn)
49{
50 u8 *base = (u8*)hose->cfg_data;
51
52 /* use local configuration space for the first bus */
53 if (PCI_BUS(devfn) == 0) {
54 if (hose->cfg_data == (u8*)CFG_PCIE0_CFGBASE)
55 base = (u8*)CFG_PCIE0_XCFGBASE;
56 if (hose->cfg_data == (u8*)CFG_PCIE1_CFGBASE)
57 base = (u8*)CFG_PCIE1_XCFGBASE;
58 if (hose->cfg_data == (u8*)CFG_PCIE2_CFGBASE)
59 base = (u8*)CFG_PCIE2_XCFGBASE;
60 }
61
62 return base;
63}
64
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +020065static void pcie_dmer_disable(void)
Grzegorz Bernackic9240982007-07-31 18:51:48 +020066{
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +020067 mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE),
68 mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) | GPL_DMER_MASK_DISA);
69 mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE),
70 mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) | GPL_DMER_MASK_DISA);
71 mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE),
72 mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) | GPL_DMER_MASK_DISA);
Grzegorz Bernackic9240982007-07-31 18:51:48 +020073}
74
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +020075static void pcie_dmer_enable(void)
Grzegorz Bernackic9240982007-07-31 18:51:48 +020076{
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +020077 mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE0_BASE),
78 mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) & ~GPL_DMER_MASK_DISA);
79 mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE1_BASE),
80 mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) & ~GPL_DMER_MASK_DISA);
81 mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE2_BASE),
82 mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) & ~GPL_DMER_MASK_DISA);
Grzegorz Bernackic9240982007-07-31 18:51:48 +020083}
84
Rafal Jaworowski692519b2006-08-10 12:43:17 +020085static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
86 int offset, int len, u32 *val) {
87
Grzegorz Bernacki7f191392007-09-07 18:20:23 +020088 u8 *address;
Rafal Jaworowski692519b2006-08-10 12:43:17 +020089 *val = 0;
Grzegorz Bernacki7f191392007-09-07 18:20:23 +020090
Rafal Jaworowski692519b2006-08-10 12:43:17 +020091 /*
Grzegorz Bernacki7f191392007-09-07 18:20:23 +020092 * Bus numbers are relative to hose->first_busno
Rafal Jaworowski692519b2006-08-10 12:43:17 +020093 */
Grzegorz Bernacki7f191392007-09-07 18:20:23 +020094 devfn -= PCI_BDF(hose->first_busno, 0, 0);
95
96 /*
97 * NOTICE: configuration space ranges are currenlty mapped only for
98 * the first 16 buses, so such limit must be imposed. In case more
99 * buses are required the TLB settings in board/amcc/<board>/init.S
100 * need to be altered accordingly (one bus takes 1 MB of memory space).
101 */
102 if (PCI_BUS(devfn) >= 16)
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200103 return 0;
104
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200105 /*
106 * Only single device/single function is supported for the primary and
107 * secondary buses of the 440SPe host bridge.
108 */
109 if ((!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 0))) &&
110 ((PCI_BUS(devfn) == 0) || (PCI_BUS(devfn) == 1)))
111 return 0;
Stefan Roese738815c2007-10-02 11:44:46 +0200112
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200113 address = pcie_get_base(hose, devfn);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200114 offset += devfn << 4;
115
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +0200116 /*
117 * Reading from configuration space of non-existing device can
118 * generate transaction errors. For the read duration we suppress
119 * assertion of machine check exceptions to avoid those.
120 */
121 pcie_dmer_disable ();
122
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200123 switch (len) {
124 case 1:
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +0200125 *val = in_8(hose->cfg_data + offset);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200126 break;
127 case 2:
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +0200128 *val = in_le16((u16 *)(hose->cfg_data + offset));
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200129 break;
130 default:
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +0200131 *val = in_le32((u32*)(hose->cfg_data + offset));
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200132 break;
133 }
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +0200134
135 pcie_dmer_enable ();
136
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200137 return 0;
138}
139
140static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
141 int offset, int len, u32 val) {
142
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200143 u8 *address;
Stefan Roese738815c2007-10-02 11:44:46 +0200144
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200145 /*
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200146 * Bus numbers are relative to hose->first_busno
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200147 */
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200148 devfn -= PCI_BDF(hose->first_busno, 0, 0);
Stefan Roese738815c2007-10-02 11:44:46 +0200149
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200150 /*
151 * Same constraints as in pcie_read_config().
152 */
153 if (PCI_BUS(devfn) >= 16)
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200154 return 0;
155
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200156 if ((!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 0))) &&
157 ((PCI_BUS(devfn) == 0) || (PCI_BUS(devfn) == 1)))
158 return 0;
Stefan Roese738815c2007-10-02 11:44:46 +0200159
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200160 address = pcie_get_base(hose, devfn);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200161 offset += devfn << 4;
162
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +0200163 /*
164 * Suppress MCK exceptions, similar to pcie_read_config()
165 */
166 pcie_dmer_disable ();
167
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200168 switch (len) {
169 case 1:
170 out_8(hose->cfg_data + offset, val);
171 break;
172 case 2:
173 out_le16((u16 *)(hose->cfg_data + offset), val);
174 break;
175 default:
176 out_le32((u32 *)(hose->cfg_data + offset), val);
177 break;
178 }
Grzegorz Bernacki15ee4732007-09-07 17:46:18 +0200179
180 pcie_dmer_enable ();
181
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200182 return 0;
183}
184
185int pcie_read_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 *val)
186{
187 u32 v;
188 int rv;
189
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200190 rv = pcie_read_config(hose, dev, offset, 1, &v);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200191 *val = (u8)v;
192 return rv;
193}
194
195int pcie_read_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 *val)
196{
197 u32 v;
198 int rv;
199
200 rv = pcie_read_config(hose, dev, offset, 2, &v);
201 *val = (u16)v;
202 return rv;
203}
204
205int pcie_read_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 *val)
206{
207 u32 v;
208 int rv;
209
210 rv = pcie_read_config(hose, dev, offset, 3, &v);
211 *val = (u32)v;
212 return rv;
213}
214
215int pcie_write_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 val)
216{
217 return pcie_write_config(hose,(u32)dev,offset,1,val);
218}
219
220int pcie_write_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 val)
221{
222 return pcie_write_config(hose,(u32)dev,offset,2,(u32 )val);
223}
224
225int pcie_write_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 val)
226{
227 return pcie_write_config(hose,(u32)dev,offset,3,(u32 )val);
228}
229
Stefan Roese026f7112007-10-03 07:48:09 +0200230static void ppc4xx_setup_utl(u32 port) {
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200231
232 volatile void *utl_base = NULL;
233
234 /*
235 * Map UTL registers
236 */
237 switch (port) {
238 case 0:
Rafal Jaworowski36b904a2006-08-11 12:35:52 +0200239 mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
240 mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x20000000);
241 mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200242 mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200243 break;
244
245 case 1:
Rafal Jaworowski36b904a2006-08-11 12:35:52 +0200246 mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
247 mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x20001000);
248 mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200249 mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200250 break;
251
252 case 2:
Rafal Jaworowski36b904a2006-08-11 12:35:52 +0200253 mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
254 mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x20002000);
255 mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200256 mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200257 break;
258 }
Rafal Jaworowski36b904a2006-08-11 12:35:52 +0200259 utl_base = (unsigned int *)(CFG_PCIE_BASE + 0x1000 * port);
Wolfgang Denk16850912006-08-27 18:10:01 +0200260
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200261 /*
262 * Set buffer allocations and then assert VRB and TXE.
263 */
264 out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
265 out_be32(utl_base + PEUTL_INTR, 0x02000000);
266 out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000);
267 out_be32(utl_base + PEUTL_PBBSZ, 0x53000000);
268 out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000);
269 out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000);
270 out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
Rafal Jaworowski36b904a2006-08-11 12:35:52 +0200271 out_be32(utl_base + PEUTL_PCTL, 0x80800066);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200272}
273
274static int check_error(void)
275{
276 u32 valPE0, valPE1, valPE2;
277 int err = 0;
278
279 /* SDR0_PEGPLLLCT1 reset */
280 if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
281 printf("PCIE: SDR0_PEGPLLLCT1 reset error 0x%x\n", valPE0);
282 }
283
284 valPE0 = SDR_READ(PESDR0_RCSSET);
285 valPE1 = SDR_READ(PESDR1_RCSSET);
286 valPE2 = SDR_READ(PESDR2_RCSSET);
287
288 /* SDR0_PExRCSSET rstgu */
289 if (!(valPE0 & 0x01000000) ||
290 !(valPE1 & 0x01000000) ||
291 !(valPE2 & 0x01000000)) {
292 printf("PCIE: SDR0_PExRCSSET rstgu error\n");
293 err = -1;
294 }
295
296 /* SDR0_PExRCSSET rstdl */
297 if (!(valPE0 & 0x00010000) ||
298 !(valPE1 & 0x00010000) ||
299 !(valPE2 & 0x00010000)) {
300 printf("PCIE: SDR0_PExRCSSET rstdl error\n");
301 err = -1;
302 }
303
304 /* SDR0_PExRCSSET rstpyn */
305 if ((valPE0 & 0x00001000) ||
306 (valPE1 & 0x00001000) ||
307 (valPE2 & 0x00001000)) {
308 printf("PCIE: SDR0_PExRCSSET rstpyn error\n");
309 err = -1;
310 }
311
312 /* SDR0_PExRCSSET hldplb */
313 if ((valPE0 & 0x10000000) ||
314 (valPE1 & 0x10000000) ||
315 (valPE2 & 0x10000000)) {
316 printf("PCIE: SDR0_PExRCSSET hldplb error\n");
317 err = -1;
318 }
319
320 /* SDR0_PExRCSSET rdy */
321 if ((valPE0 & 0x00100000) ||
322 (valPE1 & 0x00100000) ||
323 (valPE2 & 0x00100000)) {
324 printf("PCIE: SDR0_PExRCSSET rdy error\n");
325 err = -1;
326 }
327
328 /* SDR0_PExRCSSET shutdown */
329 if ((valPE0 & 0x00000100) ||
330 (valPE1 & 0x00000100) ||
331 (valPE2 & 0x00000100)) {
332 printf("PCIE: SDR0_PExRCSSET shutdown error\n");
333 err = -1;
334 }
335 return err;
336}
337
338/*
339 * Initialize PCI Express core
340 */
Stefan Roese026f7112007-10-03 07:48:09 +0200341int ppc4xx_init_pcie(void)
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200342{
343 int time_out = 20;
344
345 /* Set PLL clock receiver to LVPECL */
346 SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
347
348 if (check_error())
349 return -1;
350
351 if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
352 {
353 printf("PCIE: PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
354 SDR_READ(PESDR0_PLLLCT2));
355 return -1;
356 }
357 /* De-assert reset of PCIe PLL, wait for lock */
358 SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
359 udelay(3);
360
Stefan Roese2b393b02006-08-29 08:05:15 +0200361 while (time_out) {
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200362 if (!(SDR_READ(PESDR0_PLLLCT3) & 0x10000000)) {
363 time_out--;
364 udelay(1);
365 } else
366 break;
367 }
368 if (!time_out) {
369 printf("PCIE: VCO output not locked\n");
370 return -1;
371 }
372 return 0;
373}
374
Stefan Roese2b393b02006-08-29 08:05:15 +0200375/*
Stefan Roese03d344b2007-10-03 10:38:09 +0200376 * Board-specific pcie initialization
377 * Platform code can reimplement ppc4xx_init_pcie_port_hw() if needed
378 */
379
380/*
381 * Initialize various parts of the PCI Express core for our port:
382 *
383 * - Set as a root port and enable max width
384 * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
385 * - Set up UTL configuration.
386 * - Increase SERDES drive strength to levels suggested by AMCC.
387 * - De-assert RSTPYN, RSTDL and RSTGU.
388 *
389 * NOTICE for 440SPE revB chip: PESDRn_UTLSET2 is not set - we leave it
390 * with default setting 0x11310000. The register has new fields,
391 * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
392 * hang.
393 */
394#if defined(CONFIG_440SPE)
395int __ppc4xx_init_pcie_port_hw(int port, int rootport)
396{
397 u32 val = 1 << 24;
398 u32 utlset1;
399
400 if (rootport) {
401 val = PTYPE_ROOT_PORT << 20;
402 utlset1 = 0x21222222;
403 } else {
404 val = PTYPE_LEGACY_ENDPOINT << 20;
405 utlset1 = 0x20222222;
406 }
407
408 if (port == 0)
409 val |= LNKW_X8 << 12;
410 else
411 val |= LNKW_X4 << 12;
412
413 SDR_WRITE(SDRN_PESDR_DLPSET(port), val);
414 SDR_WRITE(SDRN_PESDR_UTLSET1(port), utlset1);
415 if (!ppc440spe_revB())
416 SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x11000000);
417 SDR_WRITE(SDRN_PESDR_HSSL0SET1(port), 0x35000000);
418 SDR_WRITE(SDRN_PESDR_HSSL1SET1(port), 0x35000000);
419 SDR_WRITE(SDRN_PESDR_HSSL2SET1(port), 0x35000000);
420 SDR_WRITE(SDRN_PESDR_HSSL3SET1(port), 0x35000000);
421 if (port == 0) {
422 SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
423 SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
424 SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
425 SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
426 }
427 SDR_WRITE(SDRN_PESDR_RCSSET(port), (SDR_READ(SDRN_PESDR_RCSSET(port)) &
428 ~(1 << 24 | 1 << 16)) | 1 << 12);
429
430 return 0;
431}
432#endif /* CONFIG_440SPE */
433
434#if defined(CONFIG_405EX)
435int __ppc4xx_init_pcie_port_hw(int port, int rootport)
436{
437 u32 val;
438
Stefan Roese94276eb2007-10-03 14:14:58 +0200439 /*
440 * test-only:
441 * This needs some testing and perhaps changes for
442 * endpoint configuration. Probably no PHY reset at all, etc.
443 * sr, 2007-10-03
444 */
Stefan Roese03d344b2007-10-03 10:38:09 +0200445 if (rootport)
446 val = 0x00401000;
447 else
448 val = 0x00101000;
449
450 SDR_WRITE(SDRN_PESDR_DLPSET(port), val);
451 SDR_WRITE(SDRN_PESDR_UTLSET1(port), 0x20222222);
452 SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x01110000);
453 SDR_WRITE(SDRN_PESDR_PHYSET1(port), 0x720F0000);
454 SDR_WRITE(SDRN_PESDR_PHYSET2(port), 0x70600003);
455
456 /* Assert the PE0_PHY reset */
457 SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01010000);
458 udelay(1000);
459
460 /* deassert the PE0_hotreset */
461 SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01101000);
462
463 /* poll for phy !reset */
464 while (!(SDR_READ(SDRN_PESDR_PHYSTA(port)) & 0x00001000))
465 ;
466
467 /* deassert the PE0_gpl_utl_reset */
468 SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x00101000);
469
470 if (port == 0)
471 mtdcr(DCRN_PEGPL_CFG(PCIE0), 0x10000000); /* guarded on */
472 else
473 mtdcr(DCRN_PEGPL_CFG(PCIE1), 0x10000000); /* guarded on */
474
475 return 0;
476}
477#endif /* CONFIG_405EX */
478
479int ppc4xx_init_pcie_port_hw(int port, int rootport)
480 __attribute__((weak, alias("__ppc4xx_init_pcie_port_hw")));
481
482/*
483 * We map PCI Express configuration access into the 512MB regions
484 *
485 * NOTICE: revB is very strict about PLB real addressess and ranges to
486 * be mapped for config space; it seems to only work with d_nnnn_nnnn
487 * range (hangs the core upon config transaction attempts when set
488 * otherwise) while revA uses c_nnnn_nnnn.
489 *
490 * For revA:
491 * PCIE0: 0xc_4000_0000
492 * PCIE1: 0xc_8000_0000
493 * PCIE2: 0xc_c000_0000
494 *
495 * For revB:
496 * PCIE0: 0xd_0000_0000
497 * PCIE1: 0xd_2000_0000
498 * PCIE2: 0xd_4000_0000
499 *
500 * For 405EX:
501 * PCIE0: 0xa000_0000
502 * PCIE1: 0xc000_0000
503 */
504static inline u64 ppc4xx_get_cfgaddr(int port)
505{
506#if defined(CONFIG_405EX)
507 if (port == 0)
508 return (u64)CFG_PCIE0_CFGBASE;
509 else
510 return (u64)CFG_PCIE1_CFGBASE;
511#endif
512#if defined(CONFIG_440SPE)
513 if (ppc440spe_revB()) {
514 switch (port) {
515 default: /* to satisfy compiler */
516 case 0:
517 return 0x0000000d00000000ULL;
518 case 1:
519 return 0x0000000d20000000ULL;
520 case 2:
521 return 0x0000000d40000000ULL;
522 }
523 } else {
524 switch (port) {
525 default: /* to satisfy compiler */
526 case 0:
527 return 0x0000000c40000000ULL;
528 case 1:
529 return 0x0000000c80000000ULL;
530 case 2:
531 return 0x0000000cc0000000ULL;
532 }
533 }
534#endif
535}
536
537/*
538 * 4xx boards as end point and root point setup
Stefan Roese2b393b02006-08-29 08:05:15 +0200539 * and
540 * testing inbound and out bound windows
541 *
Stefan Roese03d344b2007-10-03 10:38:09 +0200542 * 4xx boards can be plugged into another 4xx boards or you can get PCI-E
Stefan Roese2b393b02006-08-29 08:05:15 +0200543 * cable which can be used to setup loop back from one port to another port.
544 * Please rememeber that unless there is a endpoint plugged in to root port it
545 * will not initialize. It is the same in case of endpoint , unless there is
546 * root port attached it will not initialize.
547 *
548 * In this release of software all the PCI-E ports are configured as either
549 * endpoint or rootpoint.In future we will have support for selective ports
550 * setup as endpoint and root point in single board.
551 *
552 * Once your board came up as root point , you can verify by reading
553 * /proc/bus/pci/devices. Where you can see the configuration registers
554 * of end point device attached to the port.
555 *
Stefan Roese03d344b2007-10-03 10:38:09 +0200556 * Enpoint cofiguration can be verified by connecting 4xx board to any
557 * host or another 4xx board. Then try to scan the device. In case of
Stefan Roese2b393b02006-08-29 08:05:15 +0200558 * linux use "lspci" or appripriate os command.
559 *
Stefan Roese03d344b2007-10-03 10:38:09 +0200560 * How do I verify the inbound and out bound windows ? (4xx to 4xx)
Stefan Roese2b393b02006-08-29 08:05:15 +0200561 * in this configuration inbound and outbound windows are setup to access
562 * sram memroy area. SRAM is at 0x4 0000 0000 , on PLB bus. This address
563 * is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000,
564 * This is waere your POM(PLB out bound memory window) mapped. then
Stefan Roese03d344b2007-10-03 10:38:09 +0200565 * read the data from other 4xx board's u-boot prompt at address
Stefan Roese2b393b02006-08-29 08:05:15 +0200566 * 0x9000 0000(SRAM). Data should match.
567 * In case of inbound , write data to u-boot command prompt at 0xb000 0000
568 * which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check
569 * data at 0x9000 0000(SRAM).Data should match.
570 */
Stefan Roese03d344b2007-10-03 10:38:09 +0200571int ppc4xx_init_pcie_port(int port, int rootport)
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200572{
573 static int core_init;
574 volatile u32 val = 0;
575 int attempts;
Stefan Roese03d344b2007-10-03 10:38:09 +0200576 u64 addr;
577 u32 low, high;
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200578
579 if (!core_init) {
580 ++core_init;
Stefan Roese026f7112007-10-03 07:48:09 +0200581 if (ppc4xx_init_pcie())
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200582 return -1;
583 }
584
585 /*
Stefan Roese03d344b2007-10-03 10:38:09 +0200586 * Initialize various parts of the PCI Express core for our port
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200587 */
Stefan Roese03d344b2007-10-03 10:38:09 +0200588 ppc4xx_init_pcie_port_hw(port, rootport);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200589
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200590 /*
591 * Notice: the following delay has critical impact on device
592 * initialization - if too short (<50ms) the link doesn't get up.
593 */
594 mdelay(100);
595
Stefan Roese6d952892007-10-03 21:16:32 +0200596 val = SDR_READ(SDRN_PESDR_RCSSTS(port));
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200597 if (val & (1 << 20)) {
598 printf("PCIE%d: PGRST failed %08x\n", port, val);
599 return -1;
600 }
601
602 /*
603 * Verify link is up
604 */
Stefan Roese6d952892007-10-03 21:16:32 +0200605 val = SDR_READ(SDRN_PESDR_LOOP(port));
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200606 if (!(val & 0x00001000)) {
607 printf("PCIE%d: link is not up.\n", port);
608 return -1;
609 }
610
611 /*
612 * Setup UTL registers - but only on revA!
613 * We use default settings for revB chip.
614 */
615 if (!ppc440spe_revB())
Stefan Roese026f7112007-10-03 07:48:09 +0200616 ppc4xx_setup_utl(port);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200617
618 /*
619 * We map PCI Express configuration access into the 512MB regions
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200620 */
Stefan Roese03d344b2007-10-03 10:38:09 +0200621 addr = ppc4xx_get_cfgaddr(port);
622 low = (u32)(addr & 0x00000000ffffffff);
623 high = (u32)(addr >> 32);
Rafal Jaworowski36b904a2006-08-11 12:35:52 +0200624
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200625 switch (port) {
626 case 0:
Stefan Roese03d344b2007-10-03 10:38:09 +0200627 mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), high);
628 mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), low);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200629 mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
630 break;
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200631 case 1:
Stefan Roese03d344b2007-10-03 10:38:09 +0200632 mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), high);
633 mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), low);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200634 mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
635 break;
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200636 case 2:
Stefan Roese03d344b2007-10-03 10:38:09 +0200637 mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), high);
638 mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), low);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200639 mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
640 break;
641 }
642
643 /*
644 * Check for VC0 active and assert RDY.
645 */
646 attempts = 10;
Stefan Roese6d952892007-10-03 21:16:32 +0200647 while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 16))) {
Stefan Roese03d344b2007-10-03 10:38:09 +0200648 if (!(attempts--)) {
649 printf("PCIE%d: VC0 not active\n", port);
650 return -1;
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200651 }
Stefan Roese03d344b2007-10-03 10:38:09 +0200652 mdelay(1000);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200653 }
Stefan Roese6d952892007-10-03 21:16:32 +0200654 SDR_WRITE(SDRN_PESDR_RCSSET(port),
655 SDR_READ(SDRN_PESDR_RCSSET(port)) | 1 << 20);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200656 mdelay(100);
657
658 return 0;
659}
660
Stefan Roese03d344b2007-10-03 10:38:09 +0200661int ppc4xx_init_pcie_rootport(int port)
662{
663 return ppc4xx_init_pcie_port(port, 1);
664}
665
Stefan Roese026f7112007-10-03 07:48:09 +0200666int ppc4xx_init_pcie_endport(int port)
Stefan Roese2b393b02006-08-29 08:05:15 +0200667{
Stefan Roese03d344b2007-10-03 10:38:09 +0200668 return ppc4xx_init_pcie_port(port, 0);
Stefan Roese2b393b02006-08-29 08:05:15 +0200669}
670
Stefan Roese026f7112007-10-03 07:48:09 +0200671void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200672{
673 volatile void *mbase = NULL;
Stefan Roese2b393b02006-08-29 08:05:15 +0200674 volatile void *rmbase = NULL;
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200675
676 pci_set_ops(hose,
Stefan Roese03d344b2007-10-03 10:38:09 +0200677 pcie_read_config_byte,
678 pcie_read_config_word,
679 pcie_read_config_dword,
680 pcie_write_config_byte,
681 pcie_write_config_word,
682 pcie_write_config_dword);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200683
Stefan Roese2b393b02006-08-29 08:05:15 +0200684 switch (port) {
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200685 case 0:
686 mbase = (u32 *)CFG_PCIE0_XCFGBASE;
Stefan Roese2b393b02006-08-29 08:05:15 +0200687 rmbase = (u32 *)CFG_PCIE0_CFGBASE;
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200688 hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
689 break;
690 case 1:
691 mbase = (u32 *)CFG_PCIE1_XCFGBASE;
Stefan Roese2b393b02006-08-29 08:05:15 +0200692 rmbase = (u32 *)CFG_PCIE1_CFGBASE;
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200693 hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
694 break;
695 case 2:
696 mbase = (u32 *)CFG_PCIE2_XCFGBASE;
Stefan Roese2b393b02006-08-29 08:05:15 +0200697 rmbase = (u32 *)CFG_PCIE2_CFGBASE;
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200698 hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
699 break;
700 }
701
702 /*
703 * Set bus numbers on our root port
704 */
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200705 out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
706 out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
707 out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200708
709 /*
710 * Set up outbound translation to hose->mem_space from PLB
711 * addresses at an offset of 0xd_0000_0000. We set the low
712 * bits of the mask to 11 to turn off splitting into 8
713 * subregions and to enable the outbound translation.
714 */
715 out_le32(mbase + PECFG_POM0LAH, 0x00000000);
Stefan Roese4dbee8a2007-10-05 07:57:20 +0200716 out_le32(mbase + PECFG_POM0LAL, CFG_PCIE_MEMBASE +
717 port * CFG_PCIE_MEMSIZE);
718 debug("PECFG_POM0LA=%08x.%08x\n", in_le32(mbase + PECFG_POM0LAH),
719 in_le32(mbase + PECFG_POM0LAL));
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200720
721 switch (port) {
722 case 0:
723 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
724 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
Stefan Roese03d344b2007-10-03 10:38:09 +0200725 port * CFG_PCIE_MEMSIZE);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200726 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
727 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
Stefan Roese03d344b2007-10-03 10:38:09 +0200728 ~(CFG_PCIE_MEMSIZE - 1) | 3);
Stefan Roese4dbee8a2007-10-05 07:57:20 +0200729 debug("0:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n",
730 mfdcr(DCRN_PEGPL_OMR1BAH(PCIE0)),
731 mfdcr(DCRN_PEGPL_OMR1BAL(PCIE0)),
732 mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE0)),
733 mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE0)));
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200734 break;
735 case 1:
736 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
Stefan Roese03d344b2007-10-03 10:38:09 +0200737 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), CFG_PCIE_MEMBASE +
738 port * CFG_PCIE_MEMSIZE);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200739 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
740 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
Stefan Roese03d344b2007-10-03 10:38:09 +0200741 ~(CFG_PCIE_MEMSIZE - 1) | 3);
Stefan Roese4dbee8a2007-10-05 07:57:20 +0200742 debug("1:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n",
743 mfdcr(DCRN_PEGPL_OMR1BAH(PCIE1)),
744 mfdcr(DCRN_PEGPL_OMR1BAL(PCIE1)),
745 mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE1)),
746 mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE1)));
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200747 break;
748 case 2:
749 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
Stefan Roese03d344b2007-10-03 10:38:09 +0200750 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), CFG_PCIE_MEMBASE +
751 port * CFG_PCIE_MEMSIZE);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200752 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
753 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
Stefan Roese03d344b2007-10-03 10:38:09 +0200754 ~(CFG_PCIE_MEMSIZE - 1) | 3);
Stefan Roese4dbee8a2007-10-05 07:57:20 +0200755 debug("2:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n",
756 mfdcr(DCRN_PEGPL_OMR1BAH(PCIE2)),
757 mfdcr(DCRN_PEGPL_OMR1BAL(PCIE2)),
758 mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE2)),
759 mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE2)));
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200760 break;
761 }
762
763 /* Set up 16GB inbound memory window at 0 */
764 out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
765 out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
766 out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
767 out_le32(mbase + PECFG_BAR0LMPA, 0);
Stefan Roese2b393b02006-08-29 08:05:15 +0200768
769 out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
770 out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200771 out_le32(mbase + PECFG_PIM0LAL, 0);
772 out_le32(mbase + PECFG_PIM0LAH, 0);
Stefan Roese2b393b02006-08-29 08:05:15 +0200773 out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
774 out_le32(mbase + PECFG_PIM1LAH, 0x00000004);
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200775 out_le32(mbase + PECFG_PIMEN, 0x1);
776
777 /* Enable I/O, Mem, and Busmaster cycles */
778 out_le16((u16 *)(mbase + PCI_COMMAND),
779 in_le16((u16 *)(mbase + PCI_COMMAND)) |
780 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
Stefan Roese738815c2007-10-02 11:44:46 +0200781
Grzegorz Bernacki7f191392007-09-07 18:20:23 +0200782 /* Set Device and Vendor Id */
783 switch (port) {
784 case 0:
785 out_le16(mbase + 0x200, 0xaaa0);
786 out_le16(mbase + 0x202, 0xbed0);
787 break;
788 case 1:
789 out_le16(mbase + 0x200, 0xaaa1);
790 out_le16(mbase + 0x202, 0xbed1);
791 break;
792 case 2:
793 out_le16(mbase + 0x200, 0xaaa2);
794 out_le16(mbase + 0x202, 0xbed2);
795 break;
796 default:
797 out_le16(mbase + 0x200, 0xaaa3);
798 out_le16(mbase + 0x202, 0xbed3);
799 }
800
801 /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
802 out_le32(mbase + 0x208, 0x06040001);
803
Stefan Roese03d344b2007-10-03 10:38:09 +0200804 printf("PCIE:%d successfully set as rootpoint\n", port);
Stefan Roese2b393b02006-08-29 08:05:15 +0200805}
806
Stefan Roese026f7112007-10-03 07:48:09 +0200807int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
Stefan Roese2b393b02006-08-29 08:05:15 +0200808{
809 volatile void *mbase = NULL;
810 int attempts = 0;
811
812 pci_set_ops(hose,
813 pcie_read_config_byte,
814 pcie_read_config_word,
815 pcie_read_config_dword,
816 pcie_write_config_byte,
817 pcie_write_config_word,
818 pcie_write_config_dword);
819
820 switch (port) {
821 case 0:
822 mbase = (u32 *)CFG_PCIE0_XCFGBASE;
823 hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
824 break;
825 case 1:
826 mbase = (u32 *)CFG_PCIE1_XCFGBASE;
827 hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
828 break;
829 case 2:
830 mbase = (u32 *)CFG_PCIE2_XCFGBASE;
831 hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
832 break;
833 }
834
835 /*
836 * Set up outbound translation to hose->mem_space from PLB
837 * addresses at an offset of 0xd_0000_0000. We set the low
838 * bits of the mask to 11 to turn off splitting into 8
839 * subregions and to enable the outbound translation.
840 */
841 out_le32(mbase + PECFG_POM0LAH, 0x00001ff8);
842 out_le32(mbase + PECFG_POM0LAL, 0x00001000);
843
844 switch (port) {
845 case 0:
846 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
847 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
Stefan Roese03d344b2007-10-03 10:38:09 +0200848 port * CFG_PCIE_MEMSIZE);
Stefan Roese2b393b02006-08-29 08:05:15 +0200849 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
850 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
Stefan Roese03d344b2007-10-03 10:38:09 +0200851 ~(CFG_PCIE_MEMSIZE - 1) | 3);
Stefan Roese2b393b02006-08-29 08:05:15 +0200852 break;
853 case 1:
854 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
Stefan Roese03d344b2007-10-03 10:38:09 +0200855 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), CFG_PCIE_MEMBASE +
856 port * CFG_PCIE_MEMSIZE);
Stefan Roese2b393b02006-08-29 08:05:15 +0200857 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
858 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
Stefan Roese03d344b2007-10-03 10:38:09 +0200859 ~(CFG_PCIE_MEMSIZE - 1) | 3);
Stefan Roese2b393b02006-08-29 08:05:15 +0200860 break;
861 case 2:
862 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
Stefan Roese03d344b2007-10-03 10:38:09 +0200863 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), CFG_PCIE_MEMBASE +
864 port * CFG_PCIE_MEMSIZE);
Stefan Roese2b393b02006-08-29 08:05:15 +0200865 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
866 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
Stefan Roese03d344b2007-10-03 10:38:09 +0200867 ~(CFG_PCIE_MEMSIZE - 1) | 3);
Stefan Roese2b393b02006-08-29 08:05:15 +0200868 break;
869 }
870
871 /* Set up 16GB inbound memory window at 0 */
872 out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
873 out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
874 out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
875 out_le32(mbase + PECFG_BAR0LMPA, 0);
876 out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
877 out_le32(mbase + PECFG_PIM0LAH, 0x00000004); /* pointing to SRAM */
878 out_le32(mbase + PECFG_PIMEN, 0x1);
879
880 /* Enable I/O, Mem, and Busmaster cycles */
881 out_le16((u16 *)(mbase + PCI_COMMAND),
Stefan Roese03d344b2007-10-03 10:38:09 +0200882 in_le16((u16 *)(mbase + PCI_COMMAND)) |
883 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
Stefan Roese2b393b02006-08-29 08:05:15 +0200884 out_le16(mbase + 0x200,0xcaad); /* Setting vendor ID */
885 out_le16(mbase + 0x202,0xfeed); /* Setting device ID */
Stefan Roese03d344b2007-10-03 10:38:09 +0200886
Stefan Roese2b393b02006-08-29 08:05:15 +0200887 attempts = 10;
Stefan Roese6d952892007-10-03 21:16:32 +0200888 while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 8))) {
Stefan Roese03d344b2007-10-03 10:38:09 +0200889 if (!(attempts--)) {
890 printf("PCIE%d: BME not active\n", port);
891 return -1;
Stefan Roese2b393b02006-08-29 08:05:15 +0200892 }
Stefan Roese03d344b2007-10-03 10:38:09 +0200893 mdelay(1000);
Stefan Roese2b393b02006-08-29 08:05:15 +0200894 }
Stefan Roese03d344b2007-10-03 10:38:09 +0200895
Stefan Roese2b393b02006-08-29 08:05:15 +0200896 printf("PCIE:%d successfully set as endpoint\n",port);
897
898 return 0;
Rafal Jaworowski692519b2006-08-10 12:43:17 +0200899}
Stefan Roese5fb692c2007-01-18 10:25:34 +0100900#endif /* CONFIG_440SPE && CONFIG_PCI */