blob: 24ab13f685536e461442316f505fc3beff44c5a0 [file] [log] [blame]
stroese771e05b2004-12-16 18:21:17 +00001/*
2 * (C) Copyright 2000
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Wolfgang Denkbfc81252006-03-06 13:03:37 +010015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
stroese771e05b2004-12-16 18:21:17 +000016 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 *
23 */
24/* PCI.c - PCI functions */
25
26
27#include <common.h>
28#ifdef CONFIG_PCI
29#include <pci.h>
30
31#ifdef CONFIG_PCI_PNP
stroese771e05b2004-12-16 18:21:17 +000032int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
33#endif
34
35#include "../../Marvell/include/pci.h"
36
37#undef DEBUG
38#undef IDE_SET_NATIVE_MODE
39static unsigned int local_buses[] = { 0, 0 };
40
41static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
42 {0, 0, 0, 0, 0, 0, 0, 27, 27, [9 ... PCI_MAX_DEVICES - 1] = 0 },
43 {0, 0, 0, 0, 0, 0, 0, 29, 29, [9 ... PCI_MAX_DEVICES - 1] = 0 },
44};
45
Stefan Roesea7b9fb92006-01-18 20:05:34 +010046#ifdef CONFIG_USE_CPCIDVI
47typedef struct {
Wolfgang Denkbfc81252006-03-06 13:03:37 +010048 unsigned int base;
49 unsigned int init;
Stefan Roesea7b9fb92006-01-18 20:05:34 +010050} GT_CPCIDVI_ROM_T;
51
52static GT_CPCIDVI_ROM_T gt_cpcidvi_rom = {0, 0};
53#endif
stroese771e05b2004-12-16 18:21:17 +000054
55#ifdef DEBUG
56static const unsigned int pci_bus_list[] = { PCI_0_MODE, PCI_1_MODE };
57static void gt_pci_bus_mode_display (PCI_HOST host)
58{
59 unsigned int mode;
60
61
62 mode = (GTREGREAD (pci_bus_list[host]) & (BIT4 | BIT5)) >> 4;
63 switch (mode) {
64 case 0:
65 printf ("PCI %d bus mode: Conventional PCI\n", host);
66 break;
67 case 1:
Wolfgang Denk8ed44d92008-10-19 02:35:50 +020068 printf ("PCI %d bus mode: 66 MHz PCIX\n", host);
stroese771e05b2004-12-16 18:21:17 +000069 break;
70 case 2:
Wolfgang Denk8ed44d92008-10-19 02:35:50 +020071 printf ("PCI %d bus mode: 100 MHz PCIX\n", host);
stroese771e05b2004-12-16 18:21:17 +000072 break;
73 case 3:
Wolfgang Denk8ed44d92008-10-19 02:35:50 +020074 printf ("PCI %d bus mode: 133 MHz PCIX\n", host);
stroese771e05b2004-12-16 18:21:17 +000075 break;
76 default:
77 printf ("Unknown BUS %d\n", mode);
78 }
79}
80#endif
81
82static const unsigned int pci_p2p_configuration_reg[] = {
83 PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
84};
85
86static const unsigned int pci_configuration_address[] = {
87 PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS
88};
89
90static const unsigned int pci_configuration_data[] = {
91 PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
92 PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER
93};
94
95static const unsigned int pci_error_cause_reg[] = {
96 PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE
97};
98
99static const unsigned int pci_arbiter_control[] = {
100 PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL
101};
102
103static const unsigned int pci_address_space_en[] = {
104 PCI_0_BASE_ADDR_REG_ENABLE, PCI_1_BASE_ADDR_REG_ENABLE
105};
106
107static const unsigned int pci_snoop_control_base_0_low[] = {
108 PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW
109};
110static const unsigned int pci_snoop_control_top_0[] = {
111 PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0
112};
113
114static const unsigned int pci_access_control_base_0_low[] = {
115 PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW
116};
117static const unsigned int pci_access_control_top_0[] = {
118 PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0
119};
120
121static const unsigned int pci_scs_bank_size[2][4] = {
122 {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
123 PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
124 {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
125 PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}
126};
127
128static const unsigned int pci_p2p_configuration[] = {
129 PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
130};
131
132
133/********************************************************************
134* pciWriteConfigReg - Write to a PCI configuration register
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100135* - Make sure the GT is configured as a master before writing
136* to another device on the PCI.
137* - The function takes care of Big/Little endian conversion.
stroese771e05b2004-12-16 18:21:17 +0000138*
139*
140* Inputs: unsigned int regOffset: The register offset as it apears in the GT spec
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100141* (or any other PCI device spec)
142* pciDevNum: The device number needs to be addressed.
stroese771e05b2004-12-16 18:21:17 +0000143*
144* Configuration Address 0xCF8:
145*
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100146* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
stroese771e05b2004-12-16 18:21:17 +0000147* |congif|Reserved| Bus |Device|Function|Register|00|
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100148* |Enable| |Number|Number| Number | Number | | <=field Name
stroese771e05b2004-12-16 18:21:17 +0000149*
150*********************************************************************/
151void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset,
152 unsigned int pciDevNum, unsigned int data)
153{
154 volatile unsigned int DataForAddrReg;
155 unsigned int functionNum;
156 unsigned int busNum = 0;
157 unsigned int addr;
158
159 if (pciDevNum > 32) /* illegal device Number */
160 return;
161 if (pciDevNum == SELF) { /* configure our configuration space. */
162 pciDevNum =
163 (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
164 0x1f;
165 busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
166 0xff0000;
167 }
168 functionNum = regOffset & 0x00000700;
169 pciDevNum = pciDevNum << 11;
170 regOffset = regOffset & 0xfc;
171 DataForAddrReg =
172 (regOffset | pciDevNum | functionNum | busNum) | BIT31;
173 GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
174 GT_REG_READ (pci_configuration_address[host], &addr);
175 if (addr != DataForAddrReg)
176 return;
177 GT_REG_WRITE (pci_configuration_data[host], data);
178}
179
180/********************************************************************
181* pciReadConfigReg - Read from a PCI0 configuration register
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100182* - Make sure the GT is configured as a master before reading
183* from another device on the PCI.
184* - The function takes care of Big/Little endian conversion.
stroese771e05b2004-12-16 18:21:17 +0000185* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100186* spec)
187* pciDevNum: The device number needs to be addressed.
stroese771e05b2004-12-16 18:21:17 +0000188* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100189* cause register to make sure the data is valid
stroese771e05b2004-12-16 18:21:17 +0000190*
191* Configuration Address 0xCF8:
192*
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100193* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
stroese771e05b2004-12-16 18:21:17 +0000194* |congif|Reserved| Bus |Device|Function|Register|00|
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100195* |Enable| |Number|Number| Number | Number | | <=field Name
stroese771e05b2004-12-16 18:21:17 +0000196*
197*********************************************************************/
198unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,
199 unsigned int pciDevNum)
200{
201 volatile unsigned int DataForAddrReg;
202 unsigned int data;
203 unsigned int functionNum;
204 unsigned int busNum = 0;
205
206 if (pciDevNum > 32) /* illegal device Number */
207 return 0xffffffff;
208 if (pciDevNum == SELF) { /* configure our configuration space. */
209 pciDevNum =
210 (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
211 0x1f;
212 busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
213 0xff0000;
214 }
215 functionNum = regOffset & 0x00000700;
216 pciDevNum = pciDevNum << 11;
217 regOffset = regOffset & 0xfc;
218 DataForAddrReg =
219 (regOffset | pciDevNum | functionNum | busNum) | BIT31;
220 GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
221 GT_REG_READ (pci_configuration_address[host], &data);
222 if (data != DataForAddrReg)
223 return 0xffffffff;
224 GT_REG_READ (pci_configuration_data[host], &data);
225 return data;
226}
227
228/********************************************************************
229* pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100230* the agent is placed on another Bus. For more
231* information read P2P in the PCI spec.
stroese771e05b2004-12-16 18:21:17 +0000232*
233* Inputs: unsigned int regOffset - The register offset as it apears in the
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100234* GT spec (or any other PCI device spec).
235* unsigned int pciDevNum - The device number needs to be addressed.
236* unsigned int busNum - On which bus does the Target agent connect
237* to.
238* unsigned int data - data to be written.
stroese771e05b2004-12-16 18:21:17 +0000239*
240* Configuration Address 0xCF8:
241*
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100242* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
stroese771e05b2004-12-16 18:21:17 +0000243* |congif|Reserved| Bus |Device|Function|Register|01|
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100244* |Enable| |Number|Number| Number | Number | | <=field Name
stroese771e05b2004-12-16 18:21:17 +0000245*
246* The configuration Address is configure as type-I (bits[1:0] = '01') due to
247* PCI spec referring to P2P.
248*
249*********************************************************************/
250void pciOverBridgeWriteConfigReg (PCI_HOST host,
251 unsigned int regOffset,
252 unsigned int pciDevNum,
253 unsigned int busNum, unsigned int data)
254{
255 unsigned int DataForReg;
256 unsigned int functionNum;
257
258 functionNum = regOffset & 0x00000700;
259 pciDevNum = pciDevNum << 11;
260 regOffset = regOffset & 0xff;
261 busNum = busNum << 16;
262 if (pciDevNum == SELF) { /* This board */
263 DataForReg = (regOffset | pciDevNum | functionNum) | BIT0;
264 } else {
265 DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
266 BIT31 | BIT0;
267 }
268 GT_REG_WRITE (pci_configuration_address[host], DataForReg);
269 GT_REG_WRITE (pci_configuration_data[host], data);
270}
271
272
273/********************************************************************
274* pciOverBridgeReadConfigReg - Read from a PCIn configuration register where
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100275* the agent target locate on another PCI bus.
276* - Make sure the GT is configured as a master
277* before reading from another device on the PCI.
278* - The function takes care of Big/Little endian
279* conversion.
stroese771e05b2004-12-16 18:21:17 +0000280* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100281* spec). (configuration register offset.)
282* pciDevNum: The device number needs to be addressed.
283* busNum: the Bus number where the agent is place.
stroese771e05b2004-12-16 18:21:17 +0000284* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100285* cause register to make sure the data is valid
stroese771e05b2004-12-16 18:21:17 +0000286*
287* Configuration Address 0xCF8:
288*
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100289* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
stroese771e05b2004-12-16 18:21:17 +0000290* |congif|Reserved| Bus |Device|Function|Register|01|
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100291* |Enable| |Number|Number| Number | Number | | <=field Name
stroese771e05b2004-12-16 18:21:17 +0000292*
293*********************************************************************/
294unsigned int pciOverBridgeReadConfigReg (PCI_HOST host,
295 unsigned int regOffset,
296 unsigned int pciDevNum,
297 unsigned int busNum)
298{
299 unsigned int DataForReg;
300 unsigned int data;
301 unsigned int functionNum;
302
303 functionNum = regOffset & 0x00000700;
304 pciDevNum = pciDevNum << 11;
305 regOffset = regOffset & 0xff;
306 busNum = busNum << 16;
307 if (pciDevNum == SELF) { /* This board */
308 DataForReg = (regOffset | pciDevNum | functionNum) | BIT31;
309 } else { /* agent on another bus */
310
311 DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
312 BIT0 | BIT31;
313 }
314 GT_REG_WRITE (pci_configuration_address[host], DataForReg);
315 GT_REG_READ (pci_configuration_data[host], &data);
316 return data;
317}
318
319
320/********************************************************************
321* pciGetRegOffset - Gets the register offset for this region config.
322*
323* INPUT: Bus, Region - The bus and region we ask for its base address.
324* OUTPUT: N/A
325* RETURNS: PCI register base address
326*********************************************************************/
327static unsigned int pciGetRegOffset (PCI_HOST host, PCI_REGION region)
328{
329 switch (host) {
330 case PCI_HOST0:
331 switch (region) {
332 case PCI_IO:
333 return PCI_0I_O_LOW_DECODE_ADDRESS;
334 case PCI_REGION0:
335 return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
336 case PCI_REGION1:
337 return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
338 case PCI_REGION2:
339 return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
340 case PCI_REGION3:
341 return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
342 }
343 case PCI_HOST1:
344 switch (region) {
345 case PCI_IO:
346 return PCI_1I_O_LOW_DECODE_ADDRESS;
347 case PCI_REGION0:
348 return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
349 case PCI_REGION1:
350 return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
351 case PCI_REGION2:
352 return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
353 case PCI_REGION3:
354 return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
355 }
356 }
357 return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
358}
359
360static unsigned int pciGetRemapOffset (PCI_HOST host, PCI_REGION region)
361{
362 switch (host) {
363 case PCI_HOST0:
364 switch (region) {
365 case PCI_IO:
366 return PCI_0I_O_ADDRESS_REMAP;
367 case PCI_REGION0:
368 return PCI_0MEMORY0_ADDRESS_REMAP;
369 case PCI_REGION1:
370 return PCI_0MEMORY1_ADDRESS_REMAP;
371 case PCI_REGION2:
372 return PCI_0MEMORY2_ADDRESS_REMAP;
373 case PCI_REGION3:
374 return PCI_0MEMORY3_ADDRESS_REMAP;
375 }
376 case PCI_HOST1:
377 switch (region) {
378 case PCI_IO:
379 return PCI_1I_O_ADDRESS_REMAP;
380 case PCI_REGION0:
381 return PCI_1MEMORY0_ADDRESS_REMAP;
382 case PCI_REGION1:
383 return PCI_1MEMORY1_ADDRESS_REMAP;
384 case PCI_REGION2:
385 return PCI_1MEMORY2_ADDRESS_REMAP;
386 case PCI_REGION3:
387 return PCI_1MEMORY3_ADDRESS_REMAP;
388 }
389 }
390 return PCI_0MEMORY0_ADDRESS_REMAP;
391}
392
393/********************************************************************
394* pciGetBaseAddress - Gets the base address of a PCI.
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100395* - If the PCI size is 0 then this base address has no meaning!!!
stroese771e05b2004-12-16 18:21:17 +0000396*
397*
398* INPUT: Bus, Region - The bus and region we ask for its base address.
399* OUTPUT: N/A
400* RETURNS: PCI base address.
401*********************************************************************/
402unsigned int pciGetBaseAddress (PCI_HOST host, PCI_REGION region)
403{
404 unsigned int regBase;
405 unsigned int regEnd;
406 unsigned int regOffset = pciGetRegOffset (host, region);
407
408 GT_REG_READ (regOffset, &regBase);
409 GT_REG_READ (regOffset + 8, &regEnd);
410
411 if (regEnd <= regBase)
412 return 0xffffffff; /* ERROR !!! */
413
414 regBase = regBase << 16;
415 return regBase;
416}
417
418bool pciMapSpace (PCI_HOST host, PCI_REGION region, unsigned int remapBase,
419 unsigned int bankBase, unsigned int bankLength)
420{
421 unsigned int low = 0xfff;
422 unsigned int high = 0x0;
423 unsigned int regOffset = pciGetRegOffset (host, region);
424 unsigned int remapOffset = pciGetRemapOffset (host, region);
425
426 if (bankLength != 0) {
427 low = (bankBase >> 16) & 0xffff;
428 high = ((bankBase + bankLength) >> 16) - 1;
429 }
430
431 GT_REG_WRITE (regOffset, low | (1 << 24)); /* no swapping */
432 GT_REG_WRITE (regOffset + 8, high);
433
434 if (bankLength != 0) { /* must do AFTER writing maps */
435 GT_REG_WRITE (remapOffset, remapBase >> 16); /* sorry, 32 bits only.
436 dont support upper 32
437 in this driver */
438 }
439 return true;
440}
441
442unsigned int pciGetSpaceBase (PCI_HOST host, PCI_REGION region)
443{
444 unsigned int low;
445 unsigned int regOffset = pciGetRegOffset (host, region);
446
447 GT_REG_READ (regOffset, &low);
448 return (low & 0xffff) << 16;
449}
450
451unsigned int pciGetSpaceSize (PCI_HOST host, PCI_REGION region)
452{
453 unsigned int low, high;
454 unsigned int regOffset = pciGetRegOffset (host, region);
455
456 GT_REG_READ (regOffset, &low);
457 GT_REG_READ (regOffset + 8, &high);
458 return ((high & 0xffff) + 1) << 16;
459}
460
461
462/* ronen - 7/Dec/03*/
463/********************************************************************
464* gtPciDisable/EnableInternalBAR - This function enable/disable PCI BARS.
465* Inputs: one of the PCI BAR
466*********************************************************************/
467void gtPciEnableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
468{
469 RESET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
470}
471
472void gtPciDisableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
473{
474 SET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
475}
476
477/********************************************************************
478* pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
479*
480* Inputs: base and size of PCI SCS
481*********************************************************************/
482void pciMapMemoryBank (PCI_HOST host, MEMORY_BANK bank,
483 unsigned int pciDramBase, unsigned int pciDramSize)
484{
485 /*ronen different function for 3rd bank. */
486 unsigned int offset = (bank < 2) ? bank * 8 : 0x100 + (bank - 2) * 8;
487
488 pciDramBase = pciDramBase & 0xfffff000;
489 pciDramBase = pciDramBase | (pciReadConfigReg (host,
490 PCI_SCS_0_BASE_ADDRESS
491 + offset,
492 SELF) & 0x00000fff);
493 pciWriteConfigReg (host, PCI_SCS_0_BASE_ADDRESS + offset, SELF,
494 pciDramBase);
495 if (pciDramSize == 0)
496 pciDramSize++;
497 GT_REG_WRITE (pci_scs_bank_size[host][bank], pciDramSize - 1);
498 gtPciEnableInternalBAR (host, bank);
499}
500
501/********************************************************************
502* pciSetRegionFeatures - This function modifys one of the 8 regions with
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100503* feature bits given as an input.
504* - Be advised to check the spec before modifying them.
stroese771e05b2004-12-16 18:21:17 +0000505* Inputs: PCI_PROTECT_REGION region - one of the eight regions.
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100506* unsigned int features - See file: pci.h there are defintion for those
507* region features.
508* unsigned int baseAddress - The region base Address.
509* unsigned int topAddress - The region top Address.
stroese771e05b2004-12-16 18:21:17 +0000510* Returns: false if one of the parameters is erroneous true otherwise.
511*********************************************************************/
512bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region,
513 unsigned int features, unsigned int baseAddress,
514 unsigned int regionLength)
515{
516 unsigned int accessLow;
517 unsigned int accessHigh;
518 unsigned int accessTop = baseAddress + regionLength;
519
520 if (regionLength == 0) { /* close the region. */
521 pciDisableAccessRegion (host, region);
522 return true;
523 }
524 /* base Address is store is bits [11:0] */
525 accessLow = (baseAddress & 0xfff00000) >> 20;
526 /* All the features are update according to the defines in pci.h (to be on
527 the safe side we disable bits: [11:0] */
528 accessLow = accessLow | (features & 0xfffff000);
529 /* write to the Low Access Region register */
530 GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
531 accessLow);
532
533 accessHigh = (accessTop & 0xfff00000) >> 20;
534
535 /* write to the High Access Region register */
536 GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region,
537 accessHigh - 1);
538 return true;
539}
540
541/********************************************************************
542* pciDisableAccessRegion - Disable The given Region by writing MAX size
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100543* to its low Address and MIN size to its high Address.
stroese771e05b2004-12-16 18:21:17 +0000544*
545* Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled.
546* Returns: N/A.
547*********************************************************************/
548void pciDisableAccessRegion (PCI_HOST host, PCI_ACCESS_REGIONS region)
549{
550 /* writing back the registers default values. */
551 GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
552 0x01001fff);
553 GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, 0);
554}
555
556/********************************************************************
557* pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
558*
559* Inputs: N/A
560* Returns: true.
561*********************************************************************/
562bool pciArbiterEnable (PCI_HOST host)
563{
564 unsigned int regData;
565
566 GT_REG_READ (pci_arbiter_control[host], &regData);
567 GT_REG_WRITE (pci_arbiter_control[host], regData | BIT31);
568 return true;
569}
570
571/********************************************************************
572* pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
573*
574* Inputs: N/A
575* Returns: true
576*********************************************************************/
577bool pciArbiterDisable (PCI_HOST host)
578{
579 unsigned int regData;
580
581 GT_REG_READ (pci_arbiter_control[host], &regData);
582 GT_REG_WRITE (pci_arbiter_control[host], regData & 0x7fffffff);
583 return true;
584}
585
586/********************************************************************
587* pciSetArbiterAgentsPriority - Priority setup for the PCI agents (Hi or Low)
588*
589* Inputs: PCI_AGENT_PRIO internalAgent - priotity for internal agent.
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100590* PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent.
591* PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent.
592* PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent.
593* PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent.
594* PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent.
595* PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent.
stroese771e05b2004-12-16 18:21:17 +0000596* Returns: true
597*********************************************************************/
598bool pciSetArbiterAgentsPriority (PCI_HOST host, PCI_AGENT_PRIO internalAgent,
599 PCI_AGENT_PRIO externalAgent0,
600 PCI_AGENT_PRIO externalAgent1,
601 PCI_AGENT_PRIO externalAgent2,
602 PCI_AGENT_PRIO externalAgent3,
603 PCI_AGENT_PRIO externalAgent4,
604 PCI_AGENT_PRIO externalAgent5)
605{
606 unsigned int regData;
607 unsigned int writeData;
608
609 GT_REG_READ (pci_arbiter_control[host], &regData);
610 writeData = (internalAgent << 7) + (externalAgent0 << 8) +
611 (externalAgent1 << 9) + (externalAgent2 << 10) +
612 (externalAgent3 << 11) + (externalAgent4 << 12) +
613 (externalAgent5 << 13);
614 regData = (regData & 0xffffc07f) | writeData;
615 GT_REG_WRITE (pci_arbiter_control[host], regData & regData);
616 return true;
617}
618
619/********************************************************************
620* pciParkingDisable - Park on last option disable, with this function you can
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100621* disable the park on last mechanism for each agent.
622* disabling this option for all agents results parking
623* on the internal master.
stroese771e05b2004-12-16 18:21:17 +0000624*
625* Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent.
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100626* PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
627* PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
628* PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
629* PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
630* PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
631* PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
stroese771e05b2004-12-16 18:21:17 +0000632* Returns: true
633*********************************************************************/
634bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent,
635 PCI_AGENT_PARK externalAgent0,
636 PCI_AGENT_PARK externalAgent1,
637 PCI_AGENT_PARK externalAgent2,
638 PCI_AGENT_PARK externalAgent3,
639 PCI_AGENT_PARK externalAgent4,
640 PCI_AGENT_PARK externalAgent5)
641{
642 unsigned int regData;
643 unsigned int writeData;
644
645 GT_REG_READ (pci_arbiter_control[host], &regData);
646 writeData = (internalAgent << 14) + (externalAgent0 << 15) +
647 (externalAgent1 << 16) + (externalAgent2 << 17) +
648 (externalAgent3 << 18) + (externalAgent4 << 19) +
649 (externalAgent5 << 20);
650 regData = (regData & ~(0x7f << 14)) | writeData;
651 GT_REG_WRITE (pci_arbiter_control[host], regData);
652 return true;
653}
654
655/********************************************************************
656* pciEnableBrokenAgentDetection - A master is said to be broken if it fails to
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100657* respond to grant assertion within a window specified in
658* the input value: 'brokenValue'.
stroese771e05b2004-12-16 18:21:17 +0000659*
660* Inputs: unsigned char brokenValue - A value which limits the Master to hold the
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100661* grant without asserting frame.
stroese771e05b2004-12-16 18:21:17 +0000662* Returns: Error for illegal broken value otherwise true.
663*********************************************************************/
664bool pciEnableBrokenAgentDetection (PCI_HOST host, unsigned char brokenValue)
665{
666 unsigned int data;
667 unsigned int regData;
668
669 if (brokenValue > 0xf)
670 return false; /* brokenValue must be 4 bit */
671 data = brokenValue << 3;
672 GT_REG_READ (pci_arbiter_control[host], &regData);
673 regData = (regData & 0xffffff87) | data;
674 GT_REG_WRITE (pci_arbiter_control[host], regData | BIT1);
675 return true;
676}
677
678/********************************************************************
679* pciDisableBrokenAgentDetection - This function disable the Broken agent
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100680* Detection mechanism.
681* NOTE: This operation may cause a dead lock on the
682* pci0 arbitration.
stroese771e05b2004-12-16 18:21:17 +0000683*
684* Inputs: N/A
685* Returns: true.
686*********************************************************************/
687bool pciDisableBrokenAgentDetection (PCI_HOST host)
688{
689 unsigned int regData;
690
691 GT_REG_READ (pci_arbiter_control[host], &regData);
692 regData = regData & 0xfffffffd;
693 GT_REG_WRITE (pci_arbiter_control[host], regData);
694 return true;
695}
696
697/********************************************************************
698* pciP2PConfig - This function set the PCI_n P2P configurate.
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100699* For more information on the P2P read PCI spec.
stroese771e05b2004-12-16 18:21:17 +0000700*
701* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100702* Boundry.
703* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
704* Boundry.
705* unsigned int busNum - The CPI bus number to which the PCI interface
706* is connected.
707* unsigned int devNum - The PCI interface's device number.
stroese771e05b2004-12-16 18:21:17 +0000708*
709* Returns: true.
710*********************************************************************/
711bool pciP2PConfig (PCI_HOST host, unsigned int SecondBusLow,
712 unsigned int SecondBusHigh,
713 unsigned int busNum, unsigned int devNum)
714{
715 unsigned int regData;
716
717 regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
718 ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
719 GT_REG_WRITE (pci_p2p_configuration[host], regData);
720 return true;
721}
722
723/********************************************************************
724* pciSetRegionSnoopMode - This function modifys one of the 4 regions which
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100725* supports Cache Coherency in the PCI_n interface.
stroese771e05b2004-12-16 18:21:17 +0000726* Inputs: region - One of the four regions.
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100727* snoopType - There is four optional Types:
728* 1. No Snoop.
729* 2. Snoop to WT region.
730* 3. Snoop to WB region.
731* 4. Snoop & Invalidate to WB region.
732* baseAddress - Base Address of this region.
733* regionLength - Region length.
stroese771e05b2004-12-16 18:21:17 +0000734* Returns: false if one of the parameters is wrong otherwise return true.
735*********************************************************************/
736bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region,
737 PCI_SNOOP_TYPE snoopType,
738 unsigned int baseAddress,
739 unsigned int regionLength)
740{
741 unsigned int snoopXbaseAddress;
742 unsigned int snoopXtopAddress;
743 unsigned int data;
744 unsigned int snoopHigh = baseAddress + regionLength;
745
746 if ((region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB))
747 return false;
748 snoopXbaseAddress =
749 pci_snoop_control_base_0_low[host] + 0x10 * region;
750 snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
751 if (regionLength == 0) { /* closing the region */
752 GT_REG_WRITE (snoopXbaseAddress, 0x0000ffff);
753 GT_REG_WRITE (snoopXtopAddress, 0);
754 return true;
755 }
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100756 baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
stroese771e05b2004-12-16 18:21:17 +0000757 data = (baseAddress >> 20) | snoopType << 12;
758 GT_REG_WRITE (snoopXbaseAddress, data);
759 snoopHigh = (snoopHigh & 0xfff00000) >> 20;
760 GT_REG_WRITE (snoopXtopAddress, snoopHigh - 1);
761 return true;
762}
763
764static int gt_read_config_dword (struct pci_controller *hose,
765 pci_dev_t dev, int offset, u32 * value)
766{
767 int bus = PCI_BUS (dev);
768
769 if ((bus == local_buses[0]) || (bus == local_buses[1])) {
Stefan Roeseae7a2732009-06-05 05:45:41 +0200770 *value = pciReadConfigReg ((PCI_HOST) hose->cfg_addr,
771 offset | (PCI_FUNC(dev) << 8),
stroese771e05b2004-12-16 18:21:17 +0000772 PCI_DEV (dev));
773 } else {
Stefan Roeseae7a2732009-06-05 05:45:41 +0200774 *value = pciOverBridgeReadConfigReg ((PCI_HOST) hose->cfg_addr,
775 offset | (PCI_FUNC(dev) << 8),
stroese771e05b2004-12-16 18:21:17 +0000776 PCI_DEV (dev), bus);
777 }
778
779 return 0;
780}
781
782static int gt_write_config_dword (struct pci_controller *hose,
783 pci_dev_t dev, int offset, u32 value)
784{
785 int bus = PCI_BUS (dev);
786
787 if ((bus == local_buses[0]) || (bus == local_buses[1])) {
Stefan Roeseae7a2732009-06-05 05:45:41 +0200788 pciWriteConfigReg ((PCI_HOST) hose->cfg_addr,
789 offset | (PCI_FUNC(dev) << 8),
stroese771e05b2004-12-16 18:21:17 +0000790 PCI_DEV (dev), value);
791 } else {
792 pciOverBridgeWriteConfigReg ((PCI_HOST) hose->cfg_addr,
Stefan Roeseae7a2732009-06-05 05:45:41 +0200793 offset | (PCI_FUNC(dev) << 8),
794 PCI_DEV (dev), bus,
stroese771e05b2004-12-16 18:21:17 +0000795 value);
796 }
797 return 0;
798}
799
800
801static void gt_setup_ide (struct pci_controller *hose,
802 pci_dev_t dev, struct pci_config_table *entry)
803{
804 static const int ide_bar[] = { 8, 4, 8, 4, 0, 0 };
805 u32 bar_response, bar_value;
806 int bar;
807
Stefan Roese58f10462009-06-04 13:35:39 +0200808 if (CPCI750_SLAVE_TEST != 0)
809 return;
810
stroese771e05b2004-12-16 18:21:17 +0000811 for (bar = 0; bar < 6; bar++) {
812 /*ronen different function for 3rd bank. */
813 unsigned int offset =
814 (bar < 2) ? bar * 8 : 0x100 + (bar - 2) * 8;
815
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100816 pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset,
817 0x0);
818 pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset,
819 &bar_response);
stroese771e05b2004-12-16 18:21:17 +0000820
821 pciauto_region_allocate (bar_response &
822 PCI_BASE_ADDRESS_SPACE_IO ? hose->
823 pci_io : hose->pci_mem, ide_bar[bar],
824 &bar_value);
825
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100826 pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + bar * 4,
827 bar_value);
stroese771e05b2004-12-16 18:21:17 +0000828 }
829}
830
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100831#ifdef CONFIG_USE_CPCIDVI
832static void gt_setup_cpcidvi (struct pci_controller *hose,
833 pci_dev_t dev, struct pci_config_table *entry)
834{
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100835 u32 bar_value, pci_response;
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100836
Stefan Roese58f10462009-06-04 13:35:39 +0200837 if (CPCI750_SLAVE_TEST != 0)
838 return;
839
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100840 pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &pci_response);
841 pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, 0xffffffff);
842 pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0, &pci_response);
843 pciauto_region_allocate (hose->pci_mem, 0x01000000, &bar_value);
844 pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, (bar_value & 0xffffff00));
845 pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, 0x0);
846 pciauto_region_allocate (hose->pci_mem, 0x40000, &bar_value);
847 pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, (bar_value & 0xffffff00) | 0x01);
848 gt_cpcidvi_rom.base = bar_value & 0xffffff00;
849 gt_cpcidvi_rom.init = 1;
850}
851
852unsigned char gt_cpcidvi_in8(unsigned int offset)
853{
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100854 unsigned char data;
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100855
856 if (gt_cpcidvi_rom.init == 0) {
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100857 return(0);
858 }
859 data = in8((offset & 0x04) + 0x3f000 + gt_cpcidvi_rom.base);
860 return(data);
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100861}
862
863void gt_cpcidvi_out8(unsigned int offset, unsigned char data)
864{
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100865 unsigned int off;
866
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100867 if (gt_cpcidvi_rom.init == 0) {
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100868 return;
869 }
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100870 off = data;
871 off = ((off << 3) & 0x7f8) + (offset & 0x4) + 0x3e000 + gt_cpcidvi_rom.base;
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100872 in8(off);
873 return;
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100874}
875#endif
stroese771e05b2004-12-16 18:21:17 +0000876
Wolfgang Denkbfc81252006-03-06 13:03:37 +0100877/* TODO BJW: Change this for DB64360. This was pulled from the EV64260 */
stroese771e05b2004-12-16 18:21:17 +0000878/* and is curently not called *. */
879#if 0
880static void gt_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
881{
882 unsigned char pin, irq;
883
884 pci_read_config_byte (dev, PCI_INTERRUPT_PIN, &pin);
885
886 if (pin == 1) { /* only allow INT A */
887 irq = pci_irq_swizzle[(PCI_HOST) hose->
888 cfg_addr][PCI_DEV (dev)];
889 if (irq)
890 pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
891 }
892}
893#endif
894
895struct pci_config_table gt_config_table[] = {
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100896#ifdef CONFIG_USE_CPCIDVI
897 {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030, PCI_CLASS_DISPLAY_VGA,
898 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_cpcidvi},
899#endif
stroese771e05b2004-12-16 18:21:17 +0000900 {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
901 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
stroese771e05b2004-12-16 18:21:17 +0000902 {}
903};
904
905struct pci_controller pci0_hose = {
906/* fixup_irq: gt_fixup_irq, */
907 config_table:gt_config_table,
908};
909
910struct pci_controller pci1_hose = {
911/* fixup_irq: gt_fixup_irq, */
912 config_table:gt_config_table,
913};
914
915void pci_init_board (void)
916{
917 unsigned int command;
Stefan Roese58f10462009-06-04 13:35:39 +0200918 unsigned int slave;
stroese771e05b2004-12-16 18:21:17 +0000919#ifdef CONFIG_PCI_PNP
920 unsigned int bar;
921#endif
stroese771e05b2004-12-16 18:21:17 +0000922#ifdef DEBUG
923 gt_pci_bus_mode_display (PCI_HOST0);
924#endif
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100925#ifdef CONFIG_USE_CPCIDVI
926 gt_cpcidvi_rom.init = 0;
927 gt_cpcidvi_rom.base = 0;
928#endif
929
Stefan Roese58f10462009-06-04 13:35:39 +0200930 slave = CPCI750_SLAVE_TEST;
931
Stefan Roesea7b9fb92006-01-18 20:05:34 +0100932 pci0_hose.config_table = gt_config_table;
933 pci1_hose.config_table = gt_config_table;
934
935#ifdef CONFIG_USE_CPCIDVI
936 gt_config_table[0].config_device = gt_setup_cpcidvi;
937#endif
938 gt_config_table[1].config_device = gt_setup_ide;
stroese771e05b2004-12-16 18:21:17 +0000939
940 pci0_hose.first_busno = 0;
941 pci0_hose.last_busno = 0xff;
942 local_buses[0] = pci0_hose.first_busno;
943
944 /* PCI memory space */
945 pci_set_region (pci0_hose.regions + 0,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200946 CONFIG_SYS_PCI0_0_MEM_SPACE,
947 CONFIG_SYS_PCI0_0_MEM_SPACE,
948 CONFIG_SYS_PCI0_MEM_SIZE, PCI_REGION_MEM);
stroese771e05b2004-12-16 18:21:17 +0000949
950 /* PCI I/O space */
951 pci_set_region (pci0_hose.regions + 1,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200952 CONFIG_SYS_PCI0_IO_SPACE_PCI,
953 CONFIG_SYS_PCI0_IO_SPACE, CONFIG_SYS_PCI0_IO_SIZE, PCI_REGION_IO);
stroese771e05b2004-12-16 18:21:17 +0000954
955 pci_set_ops (&pci0_hose,
956 pci_hose_read_config_byte_via_dword,
957 pci_hose_read_config_word_via_dword,
958 gt_read_config_dword,
959 pci_hose_write_config_byte_via_dword,
960 pci_hose_write_config_word_via_dword,
961 gt_write_config_dword);
962 pci0_hose.region_count = 2;
963
964 pci0_hose.cfg_addr = (unsigned int *) PCI_HOST0;
965
966 pci_register_hose (&pci0_hose);
Stefan Roese58f10462009-06-04 13:35:39 +0200967 if (slave == 0) {
968 pciArbiterEnable (PCI_HOST0);
969 pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1);
970 command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
971 command |= PCI_COMMAND_MASTER;
972 pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
973 command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
974 command |= PCI_COMMAND_MEMORY;
975 pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
stroese771e05b2004-12-16 18:21:17 +0000976
977#ifdef CONFIG_PCI_PNP
Stefan Roese58f10462009-06-04 13:35:39 +0200978 pciauto_config_init(&pci0_hose);
979 pciauto_region_allocate(pci0_hose.pci_io, 0x400, &bar);
stroese771e05b2004-12-16 18:21:17 +0000980#endif
981#ifdef CONFIG_PCI_SCAN_SHOW
Stefan Roese58f10462009-06-04 13:35:39 +0200982 printf("PCI: Bus Dev VenId DevId Class Int\n");
stroese771e05b2004-12-16 18:21:17 +0000983#endif
Stefan Roese58f10462009-06-04 13:35:39 +0200984 pci0_hose.last_busno = pci_hose_scan_bus (&pci0_hose,
985 pci0_hose.first_busno);
stroese771e05b2004-12-16 18:21:17 +0000986
987#ifdef DEBUG
Stefan Roese58f10462009-06-04 13:35:39 +0200988 gt_pci_bus_mode_display (PCI_HOST1);
stroese771e05b2004-12-16 18:21:17 +0000989#endif
Stefan Roese58f10462009-06-04 13:35:39 +0200990 } else {
991 pciArbiterDisable (PCI_HOST0);
992 pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1);
993 command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
994 command |= PCI_COMMAND_MASTER;
995 pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
996 command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
997 command |= PCI_COMMAND_MEMORY;
998 pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
999 pci0_hose.last_busno = pci0_hose.first_busno;
1000 }
stroese771e05b2004-12-16 18:21:17 +00001001 pci1_hose.first_busno = pci0_hose.last_busno + 1;
1002 pci1_hose.last_busno = 0xff;
1003 pci1_hose.current_busno = pci1_hose.first_busno;
1004 local_buses[1] = pci1_hose.first_busno;
1005
1006 /* PCI memory space */
1007 pci_set_region (pci1_hose.regions + 0,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +02001008 CONFIG_SYS_PCI1_0_MEM_SPACE,
1009 CONFIG_SYS_PCI1_0_MEM_SPACE,
1010 CONFIG_SYS_PCI1_MEM_SIZE, PCI_REGION_MEM);
stroese771e05b2004-12-16 18:21:17 +00001011
1012 /* PCI I/O space */
1013 pci_set_region (pci1_hose.regions + 1,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +02001014 CONFIG_SYS_PCI1_IO_SPACE_PCI,
1015 CONFIG_SYS_PCI1_IO_SPACE, CONFIG_SYS_PCI1_IO_SIZE, PCI_REGION_IO);
stroese771e05b2004-12-16 18:21:17 +00001016
1017 pci_set_ops (&pci1_hose,
1018 pci_hose_read_config_byte_via_dword,
1019 pci_hose_read_config_word_via_dword,
1020 gt_read_config_dword,
1021 pci_hose_write_config_byte_via_dword,
1022 pci_hose_write_config_word_via_dword,
1023 gt_write_config_dword);
1024
1025 pci1_hose.region_count = 2;
1026
1027 pci1_hose.cfg_addr = (unsigned int *) PCI_HOST1;
1028
1029 pci_register_hose (&pci1_hose);
1030
1031 pciArbiterEnable (PCI_HOST1);
1032 pciParkingDisable (PCI_HOST1, 1, 1, 1, 1, 1, 1, 1);
1033
1034 command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
1035 command |= PCI_COMMAND_MASTER;
1036 pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
1037
1038#ifdef CONFIG_PCI_PNP
1039 pciauto_config_init(&pci1_hose);
1040 pciauto_region_allocate(pci1_hose.pci_io, 0x400, &bar);
1041#endif
1042 pci1_hose.last_busno = pci_hose_scan_bus (&pci1_hose, pci1_hose.first_busno);
1043
1044 command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
1045 command |= PCI_COMMAND_MEMORY;
1046 pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
1047
1048}
1049#endif /* of CONFIG_PCI */