]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/Marvell/db64360/pci.c
gic: fixed compilation error in GICv2 wait for interrupt macro
[karo-tx-uboot.git] / board / Marvell / db64360 / pci.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7 /* PCI.c - PCI functions */
8
9
10 #include <common.h>
11 #include <pci.h>
12
13 #include "../include/pci.h"
14
15 #undef DEBUG
16 #undef IDE_SET_NATIVE_MODE
17 static unsigned int local_buses[] = { 0, 0 };
18
19 static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
20         {0, 0, 0, 0, 0, 0, 0, 27, 27, [9 ... PCI_MAX_DEVICES - 1] = 0 },
21         {0, 0, 0, 0, 0, 0, 0, 29, 29, [9 ... PCI_MAX_DEVICES - 1] = 0 },
22 };
23
24
25 #ifdef DEBUG
26 static const unsigned int pci_bus_list[] = { PCI_0_MODE, PCI_1_MODE };
27 static void gt_pci_bus_mode_display (PCI_HOST host)
28 {
29         unsigned int mode;
30
31
32         mode = (GTREGREAD (pci_bus_list[host]) & (BIT4 | BIT5)) >> 4;
33         switch (mode) {
34         case 0:
35                 printf ("PCI %d bus mode: Conventional PCI\n", host);
36                 break;
37         case 1:
38                 printf ("PCI %d bus mode: 66 MHz PCIX\n", host);
39                 break;
40         case 2:
41                 printf ("PCI %d bus mode: 100 MHz PCIX\n", host);
42                 break;
43         case 3:
44                 printf ("PCI %d bus mode: 133 MHz PCIX\n", host);
45                 break;
46         default:
47                 printf ("Unknown BUS %d\n", mode);
48         }
49 }
50 #endif
51
52 static const unsigned int pci_p2p_configuration_reg[] = {
53         PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
54 };
55
56 static const unsigned int pci_configuration_address[] = {
57         PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS
58 };
59
60 static const unsigned int pci_configuration_data[] = {
61         PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
62         PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER
63 };
64
65 static const unsigned int pci_error_cause_reg[] = {
66         PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE
67 };
68
69 static const unsigned int pci_arbiter_control[] = {
70         PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL
71 };
72
73 static const unsigned int pci_address_space_en[] = {
74         PCI_0_BASE_ADDR_REG_ENABLE, PCI_1_BASE_ADDR_REG_ENABLE
75 };
76
77 static const unsigned int pci_snoop_control_base_0_low[] = {
78         PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW
79 };
80 static const unsigned int pci_snoop_control_top_0[] = {
81         PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0
82 };
83
84 static const unsigned int pci_access_control_base_0_low[] = {
85         PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW
86 };
87 static const unsigned int pci_access_control_top_0[] = {
88         PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0
89 };
90
91 static const unsigned int pci_scs_bank_size[2][4] = {
92         {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
93          PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
94         {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
95          PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}
96 };
97
98 static const unsigned int pci_p2p_configuration[] = {
99         PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
100 };
101
102
103 /********************************************************************
104 * pciWriteConfigReg - Write to a PCI configuration register
105 *                    - Make sure the GT is configured as a master before writing
106 *                      to another device on the PCI.
107 *                    - The function takes care of Big/Little endian conversion.
108 *
109 *
110 * Inputs:   unsigned int regOffset: The register offset as it apears in the GT spec
111 *                   (or any other PCI device spec)
112 *           pciDevNum: The device number needs to be addressed.
113 *
114 *  Configuration Address 0xCF8:
115 *
116 *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
117 *  |congif|Reserved|  Bus |Device|Function|Register|00|
118 *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
119 *
120 *********************************************************************/
121 void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset,
122                         unsigned int pciDevNum, unsigned int data)
123 {
124         volatile unsigned int DataForAddrReg;
125         unsigned int functionNum;
126         unsigned int busNum = 0;
127         unsigned int addr;
128
129         if (pciDevNum > 32)     /* illegal device Number */
130                 return;
131         if (pciDevNum == SELF) {        /* configure our configuration space. */
132                 pciDevNum =
133                         (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
134                         0x1f;
135                 busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
136                         0xff0000;
137         }
138         functionNum = regOffset & 0x00000700;
139         pciDevNum = pciDevNum << 11;
140         regOffset = regOffset & 0xfc;
141         DataForAddrReg =
142                 (regOffset | pciDevNum | functionNum | busNum) | BIT31;
143         GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
144         GT_REG_READ (pci_configuration_address[host], &addr);
145         if (addr != DataForAddrReg)
146                 return;
147         GT_REG_WRITE (pci_configuration_data[host], data);
148 }
149
150 /********************************************************************
151 * pciReadConfigReg  - Read from a PCI0 configuration register
152 *                    - Make sure the GT is configured as a master before reading
153 *                     from another device on the PCI.
154 *                   - The function takes care of Big/Little endian conversion.
155 * INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
156 *                        spec)
157 *           pciDevNum: The device number needs to be addressed.
158 * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
159 *                 cause register to make sure the data is valid
160 *
161 *  Configuration Address 0xCF8:
162 *
163 *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
164 *  |congif|Reserved|  Bus |Device|Function|Register|00|
165 *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
166 *
167 *********************************************************************/
168 unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,
169                                unsigned int pciDevNum)
170 {
171         volatile unsigned int DataForAddrReg;
172         unsigned int data;
173         unsigned int functionNum;
174         unsigned int busNum = 0;
175
176         if (pciDevNum > 32)     /* illegal device Number */
177                 return 0xffffffff;
178         if (pciDevNum == SELF) {        /* configure our configuration space. */
179                 pciDevNum =
180                         (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
181                         0x1f;
182                 busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
183                         0xff0000;
184         }
185         functionNum = regOffset & 0x00000700;
186         pciDevNum = pciDevNum << 11;
187         regOffset = regOffset & 0xfc;
188         DataForAddrReg =
189                 (regOffset | pciDevNum | functionNum | busNum) | BIT31;
190         GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
191         GT_REG_READ (pci_configuration_address[host], &data);
192         if (data != DataForAddrReg)
193                 return 0xffffffff;
194         GT_REG_READ (pci_configuration_data[host], &data);
195         return data;
196 }
197
198 /********************************************************************
199 * pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
200 *                               the agent is placed on another Bus. For more
201 *                               information read P2P in the PCI spec.
202 *
203 * Inputs:   unsigned int regOffset - The register offset as it apears in the
204 *           GT spec (or any other PCI device spec).
205 *           unsigned int pciDevNum - The device number needs to be addressed.
206 *           unsigned int busNum - On which bus does the Target agent connect
207 *                                 to.
208 *           unsigned int data - data to be written.
209 *
210 *  Configuration Address 0xCF8:
211 *
212 *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
213 *  |congif|Reserved|  Bus |Device|Function|Register|01|
214 *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
215 *
216 *  The configuration Address is configure as type-I (bits[1:0] = '01') due to
217 *   PCI spec referring to P2P.
218 *
219 *********************************************************************/
220 void pciOverBridgeWriteConfigReg (PCI_HOST host,
221                                   unsigned int regOffset,
222                                   unsigned int pciDevNum,
223                                   unsigned int busNum, unsigned int data)
224 {
225         unsigned int DataForReg;
226         unsigned int functionNum;
227
228         functionNum = regOffset & 0x00000700;
229         pciDevNum = pciDevNum << 11;
230         regOffset = regOffset & 0xff;
231         busNum = busNum << 16;
232         if (pciDevNum == SELF) {        /* This board */
233                 DataForReg = (regOffset | pciDevNum | functionNum) | BIT0;
234         } else {
235                 DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
236                         BIT31 | BIT0;
237         }
238         GT_REG_WRITE (pci_configuration_address[host], DataForReg);
239         GT_REG_WRITE (pci_configuration_data[host], data);
240 }
241
242
243 /********************************************************************
244 * pciOverBridgeReadConfigReg  - Read from a PCIn configuration register where
245 *                               the agent target locate on another PCI bus.
246 *                             - Make sure the GT is configured as a master
247 *                               before reading from another device on the PCI.
248 *                             - The function takes care of Big/Little endian
249 *                               conversion.
250 * INPUTS:   regOffset: The register offset as it apears in the GT spec (or PCI
251 *                        spec). (configuration register offset.)
252 *           pciDevNum: The device number needs to be addressed.
253 *           busNum: the Bus number where the agent is place.
254 * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
255 *                 cause register to make sure the data is valid
256 *
257 *  Configuration Address 0xCF8:
258 *
259 *       31 30    24 23  16 15  11 10     8 7      2  0     <=bit Number
260 *  |congif|Reserved|  Bus |Device|Function|Register|01|
261 *  |Enable|        |Number|Number| Number | Number |  |    <=field Name
262 *
263 *********************************************************************/
264 unsigned int pciOverBridgeReadConfigReg (PCI_HOST host,
265                                          unsigned int regOffset,
266                                          unsigned int pciDevNum,
267                                          unsigned int busNum)
268 {
269         unsigned int DataForReg;
270         unsigned int data;
271         unsigned int functionNum;
272
273         functionNum = regOffset & 0x00000700;
274         pciDevNum = pciDevNum << 11;
275         regOffset = regOffset & 0xff;
276         busNum = busNum << 16;
277         if (pciDevNum == SELF) {        /* This board */
278                 DataForReg = (regOffset | pciDevNum | functionNum) | BIT31;
279         } else {                /* agent on another bus */
280
281                 DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
282                         BIT0 | BIT31;
283         }
284         GT_REG_WRITE (pci_configuration_address[host], DataForReg);
285         GT_REG_READ (pci_configuration_data[host], &data);
286         return data;
287 }
288
289
290 /********************************************************************
291 * pciGetRegOffset - Gets the register offset for this region config.
292 *
293 * INPUT:   Bus, Region - The bus and region we ask for its base address.
294 * OUTPUT:   N/A
295 * RETURNS: PCI register base address
296 *********************************************************************/
297 static unsigned int pciGetRegOffset (PCI_HOST host, PCI_REGION region)
298 {
299         switch (host) {
300         case PCI_HOST0:
301                 switch (region) {
302                 case PCI_IO:
303                         return PCI_0I_O_LOW_DECODE_ADDRESS;
304                 case PCI_REGION0:
305                         return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
306                 case PCI_REGION1:
307                         return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
308                 case PCI_REGION2:
309                         return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
310                 case PCI_REGION3:
311                         return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
312                 }
313         case PCI_HOST1:
314                 switch (region) {
315                 case PCI_IO:
316                         return PCI_1I_O_LOW_DECODE_ADDRESS;
317                 case PCI_REGION0:
318                         return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
319                 case PCI_REGION1:
320                         return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
321                 case PCI_REGION2:
322                         return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
323                 case PCI_REGION3:
324                         return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
325                 }
326         }
327         return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
328 }
329
330 static unsigned int pciGetRemapOffset (PCI_HOST host, PCI_REGION region)
331 {
332         switch (host) {
333         case PCI_HOST0:
334                 switch (region) {
335                 case PCI_IO:
336                         return PCI_0I_O_ADDRESS_REMAP;
337                 case PCI_REGION0:
338                         return PCI_0MEMORY0_ADDRESS_REMAP;
339                 case PCI_REGION1:
340                         return PCI_0MEMORY1_ADDRESS_REMAP;
341                 case PCI_REGION2:
342                         return PCI_0MEMORY2_ADDRESS_REMAP;
343                 case PCI_REGION3:
344                         return PCI_0MEMORY3_ADDRESS_REMAP;
345                 }
346         case PCI_HOST1:
347                 switch (region) {
348                 case PCI_IO:
349                         return PCI_1I_O_ADDRESS_REMAP;
350                 case PCI_REGION0:
351                         return PCI_1MEMORY0_ADDRESS_REMAP;
352                 case PCI_REGION1:
353                         return PCI_1MEMORY1_ADDRESS_REMAP;
354                 case PCI_REGION2:
355                         return PCI_1MEMORY2_ADDRESS_REMAP;
356                 case PCI_REGION3:
357                         return PCI_1MEMORY3_ADDRESS_REMAP;
358                 }
359         }
360         return PCI_0MEMORY0_ADDRESS_REMAP;
361 }
362
363 /********************************************************************
364 * pciGetBaseAddress - Gets the base address of a PCI.
365 *           - If the PCI size is 0 then this base address has no meaning!!!
366 *
367 *
368 * INPUT:   Bus, Region - The bus and region we ask for its base address.
369 * OUTPUT:   N/A
370 * RETURNS: PCI base address.
371 *********************************************************************/
372 unsigned int pciGetBaseAddress (PCI_HOST host, PCI_REGION region)
373 {
374         unsigned int regBase;
375         unsigned int regEnd;
376         unsigned int regOffset = pciGetRegOffset (host, region);
377
378         GT_REG_READ (regOffset, &regBase);
379         GT_REG_READ (regOffset + 8, &regEnd);
380
381         if (regEnd <= regBase)
382                 return 0xffffffff;      /* ERROR !!! */
383
384         regBase = regBase << 16;
385         return regBase;
386 }
387
388 bool pciMapSpace (PCI_HOST host, PCI_REGION region, unsigned int remapBase,
389                   unsigned int bankBase, unsigned int bankLength)
390 {
391         unsigned int low = 0xfff;
392         unsigned int high = 0x0;
393         unsigned int regOffset = pciGetRegOffset (host, region);
394         unsigned int remapOffset = pciGetRemapOffset (host, region);
395
396         if (bankLength != 0) {
397                 low = (bankBase >> 16) & 0xffff;
398                 high = ((bankBase + bankLength) >> 16) - 1;
399         }
400
401         GT_REG_WRITE (regOffset, low | (1 << 24));      /* no swapping */
402         GT_REG_WRITE (regOffset + 8, high);
403
404         if (bankLength != 0) {  /* must do AFTER writing maps */
405                 GT_REG_WRITE (remapOffset, remapBase >> 16);    /* sorry, 32 bits only.
406                                                                    dont support upper 32
407                                                                    in this driver */
408         }
409         return true;
410 }
411
412 unsigned int pciGetSpaceBase (PCI_HOST host, PCI_REGION region)
413 {
414         unsigned int low;
415         unsigned int regOffset = pciGetRegOffset (host, region);
416
417         GT_REG_READ (regOffset, &low);
418         return (low & 0xffff) << 16;
419 }
420
421 unsigned int pciGetSpaceSize (PCI_HOST host, PCI_REGION region)
422 {
423         unsigned int low, high;
424         unsigned int regOffset = pciGetRegOffset (host, region);
425
426         GT_REG_READ (regOffset, &low);
427         GT_REG_READ (regOffset + 8, &high);
428         return ((high & 0xffff) + 1) << 16;
429 }
430
431
432 /* ronen - 7/Dec/03*/
433 /********************************************************************
434 * gtPciDisable/EnableInternalBAR - This function enable/disable PCI BARS.
435 * Inputs: one of the PCI BAR
436 *********************************************************************/
437 void gtPciEnableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
438 {
439         RESET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
440 }
441
442 void gtPciDisableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
443 {
444         SET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
445 }
446
447 /********************************************************************
448 * pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
449 *
450 * Inputs: base and size of PCI SCS
451 *********************************************************************/
452 void pciMapMemoryBank (PCI_HOST host, MEMORY_BANK bank,
453                        unsigned int pciDramBase, unsigned int pciDramSize)
454 {
455         /*ronen different function for 3rd bank. */
456         unsigned int offset = (bank < 2) ? bank * 8 : 0x100 + (bank - 2) * 8;
457
458         pciDramBase = pciDramBase & 0xfffff000;
459         pciDramBase = pciDramBase | (pciReadConfigReg (host,
460                                                        PCI_SCS_0_BASE_ADDRESS
461                                                        + offset,
462                                                        SELF) & 0x00000fff);
463         pciWriteConfigReg (host, PCI_SCS_0_BASE_ADDRESS + offset, SELF,
464                            pciDramBase);
465         if (pciDramSize == 0)
466                 pciDramSize++;
467         GT_REG_WRITE (pci_scs_bank_size[host][bank], pciDramSize - 1);
468         gtPciEnableInternalBAR (host, bank);
469 }
470
471 /********************************************************************
472 * pciSetRegionFeatures - This function modifys one of the 8 regions with
473 *                         feature bits given as an input.
474 *                       - Be advised to check the spec before modifying them.
475 * Inputs: PCI_PROTECT_REGION region - one of the eight regions.
476 *         unsigned int features - See file: pci.h there are defintion for those
477 *                                 region features.
478 *         unsigned int baseAddress - The region base Address.
479 *         unsigned int topAddress - The region top Address.
480 * Returns: false if one of the parameters is erroneous true otherwise.
481 *********************************************************************/
482 bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region,
483                            unsigned int features, unsigned int baseAddress,
484                            unsigned int regionLength)
485 {
486         unsigned int accessLow;
487         unsigned int accessHigh;
488         unsigned int accessTop = baseAddress + regionLength;
489
490         if (regionLength == 0) {        /* close the region. */
491                 pciDisableAccessRegion (host, region);
492                 return true;
493         }
494         /* base Address is store is bits [11:0] */
495         accessLow = (baseAddress & 0xfff00000) >> 20;
496         /* All the features are update according to the defines in pci.h (to be on
497            the safe side we disable bits: [11:0] */
498         accessLow = accessLow | (features & 0xfffff000);
499         /* write to the Low Access Region register */
500         GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
501                       accessLow);
502
503         accessHigh = (accessTop & 0xfff00000) >> 20;
504
505         /* write to the High Access Region register */
506         GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region,
507                       accessHigh - 1);
508         return true;
509 }
510
511 /********************************************************************
512 * pciDisableAccessRegion - Disable The given Region by writing MAX size
513 *                           to its low Address and MIN size to its high Address.
514 *
515 * Inputs:   PCI_ACCESS_REGIONS region - The region we to be Disabled.
516 * Returns:  N/A.
517 *********************************************************************/
518 void pciDisableAccessRegion (PCI_HOST host, PCI_ACCESS_REGIONS region)
519 {
520         /* writing back the registers default values. */
521         GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
522                       0x01001fff);
523         GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, 0);
524 }
525
526 /********************************************************************
527 * pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
528 *
529 * Inputs:   N/A
530 * Returns:  true.
531 *********************************************************************/
532 bool pciArbiterEnable (PCI_HOST host)
533 {
534         unsigned int regData;
535
536         GT_REG_READ (pci_arbiter_control[host], &regData);
537         GT_REG_WRITE (pci_arbiter_control[host], regData | BIT31);
538         return true;
539 }
540
541 /********************************************************************
542 * pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
543 *
544 * Inputs:   N/A
545 * Returns:  true
546 *********************************************************************/
547 bool pciArbiterDisable (PCI_HOST host)
548 {
549         unsigned int regData;
550
551         GT_REG_READ (pci_arbiter_control[host], &regData);
552         GT_REG_WRITE (pci_arbiter_control[host], regData & 0x7fffffff);
553         return true;
554 }
555
556 /********************************************************************
557 * pciSetArbiterAgentsPriority - Priority setup for the PCI agents (Hi or Low)
558 *
559 * Inputs:   PCI_AGENT_PRIO internalAgent - priotity for internal agent.
560 *           PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent.
561 *           PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent.
562 *           PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent.
563 *           PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent.
564 *           PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent.
565 *           PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent.
566 * Returns:  true
567 *********************************************************************/
568 bool pciSetArbiterAgentsPriority (PCI_HOST host, PCI_AGENT_PRIO internalAgent,
569                                   PCI_AGENT_PRIO externalAgent0,
570                                   PCI_AGENT_PRIO externalAgent1,
571                                   PCI_AGENT_PRIO externalAgent2,
572                                   PCI_AGENT_PRIO externalAgent3,
573                                   PCI_AGENT_PRIO externalAgent4,
574                                   PCI_AGENT_PRIO externalAgent5)
575 {
576         unsigned int regData;
577         unsigned int writeData;
578
579         GT_REG_READ (pci_arbiter_control[host], &regData);
580         writeData = (internalAgent << 7) + (externalAgent0 << 8) +
581                 (externalAgent1 << 9) + (externalAgent2 << 10) +
582                 (externalAgent3 << 11) + (externalAgent4 << 12) +
583                 (externalAgent5 << 13);
584         regData = (regData & 0xffffc07f) | writeData;
585         GT_REG_WRITE (pci_arbiter_control[host], regData & regData);
586         return true;
587 }
588
589 /********************************************************************
590 * pciParkingDisable - Park on last option disable, with this function you can
591 *                      disable the park on last mechanism for each agent.
592 *                      disabling this option for all agents results parking
593 *                      on the internal master.
594 *
595 * Inputs: PCI_AGENT_PARK internalAgent -  parking Disable for internal agent.
596 *         PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
597 *         PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
598 *         PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
599 *         PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
600 *         PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
601 *         PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
602 * Returns:  true
603 *********************************************************************/
604 bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent,
605                         PCI_AGENT_PARK externalAgent0,
606                         PCI_AGENT_PARK externalAgent1,
607                         PCI_AGENT_PARK externalAgent2,
608                         PCI_AGENT_PARK externalAgent3,
609                         PCI_AGENT_PARK externalAgent4,
610                         PCI_AGENT_PARK externalAgent5)
611 {
612         unsigned int regData;
613         unsigned int writeData;
614
615         GT_REG_READ (pci_arbiter_control[host], &regData);
616         writeData = (internalAgent << 14) + (externalAgent0 << 15) +
617                 (externalAgent1 << 16) + (externalAgent2 << 17) +
618                 (externalAgent3 << 18) + (externalAgent4 << 19) +
619                 (externalAgent5 << 20);
620         regData = (regData & ~(0x7f << 14)) | writeData;
621         GT_REG_WRITE (pci_arbiter_control[host], regData);
622         return true;
623 }
624
625 /********************************************************************
626 * pciEnableBrokenAgentDetection - A master is said to be broken if it fails to
627 *                       respond to grant assertion within a window specified in
628 *                       the input value: 'brokenValue'.
629 *
630 * Inputs: unsigned char brokenValue -  A value which limits the Master to hold the
631 *                       grant without asserting frame.
632 * Returns:  Error for illegal broken value otherwise true.
633 *********************************************************************/
634 bool pciEnableBrokenAgentDetection (PCI_HOST host, unsigned char brokenValue)
635 {
636         unsigned int data;
637         unsigned int regData;
638
639         if (brokenValue > 0xf)
640                 return false;   /* brokenValue must be 4 bit */
641         data = brokenValue << 3;
642         GT_REG_READ (pci_arbiter_control[host], &regData);
643         regData = (regData & 0xffffff87) | data;
644         GT_REG_WRITE (pci_arbiter_control[host], regData | BIT1);
645         return true;
646 }
647
648 /********************************************************************
649 * pciDisableBrokenAgentDetection - This function disable the Broken agent
650 *                           Detection mechanism.
651 *                           NOTE: This operation may cause a dead lock on the
652 *                           pci0 arbitration.
653 *
654 * Inputs:   N/A
655 * Returns:  true.
656 *********************************************************************/
657 bool pciDisableBrokenAgentDetection (PCI_HOST host)
658 {
659         unsigned int regData;
660
661         GT_REG_READ (pci_arbiter_control[host], &regData);
662         regData = regData & 0xfffffffd;
663         GT_REG_WRITE (pci_arbiter_control[host], regData);
664         return true;
665 }
666
667 /********************************************************************
668 * pciP2PConfig - This function set the PCI_n P2P configurate.
669 *                 For more information on the P2P read PCI spec.
670 *
671 * Inputs:  unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
672 *                                      Boundry.
673 *          unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
674 *                                      Boundry.
675 *          unsigned int busNum - The CPI bus number to which the PCI interface
676 *                                      is connected.
677 *          unsigned int devNum - The PCI interface's device number.
678 *
679 * Returns:  true.
680 *********************************************************************/
681 bool pciP2PConfig (PCI_HOST host, unsigned int SecondBusLow,
682                    unsigned int SecondBusHigh,
683                    unsigned int busNum, unsigned int devNum)
684 {
685         unsigned int regData;
686
687         regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
688                 ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
689         GT_REG_WRITE (pci_p2p_configuration[host], regData);
690         return true;
691 }
692
693 /********************************************************************
694 * pciSetRegionSnoopMode - This function modifys one of the 4 regions which
695 *                          supports Cache Coherency in the PCI_n interface.
696 * Inputs: region - One of the four regions.
697 *         snoopType - There is four optional Types:
698 *                        1. No Snoop.
699 *                        2. Snoop to WT region.
700 *                        3. Snoop to WB region.
701 *                        4. Snoop & Invalidate to WB region.
702 *         baseAddress - Base Address of this region.
703 *         regionLength - Region length.
704 * Returns: false if one of the parameters is wrong otherwise return true.
705 *********************************************************************/
706 bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region,
707                             PCI_SNOOP_TYPE snoopType,
708                             unsigned int baseAddress,
709                             unsigned int regionLength)
710 {
711         unsigned int snoopXbaseAddress;
712         unsigned int snoopXtopAddress;
713         unsigned int data;
714         unsigned int snoopHigh = baseAddress + regionLength;
715
716         if ((region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB))
717                 return false;
718         snoopXbaseAddress =
719                 pci_snoop_control_base_0_low[host] + 0x10 * region;
720         snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
721         if (regionLength == 0) {        /* closing the region */
722                 GT_REG_WRITE (snoopXbaseAddress, 0x0000ffff);
723                 GT_REG_WRITE (snoopXtopAddress, 0);
724                 return true;
725         }
726         baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
727         data = (baseAddress >> 20) | snoopType << 12;
728         GT_REG_WRITE (snoopXbaseAddress, data);
729         snoopHigh = (snoopHigh & 0xfff00000) >> 20;
730         GT_REG_WRITE (snoopXtopAddress, snoopHigh - 1);
731         return true;
732 }
733
734 static int gt_read_config_dword (struct pci_controller *hose,
735                                  pci_dev_t dev, int offset, u32 * value)
736 {
737         int bus = PCI_BUS (dev);
738
739         if ((bus == local_buses[0]) || (bus == local_buses[1])) {
740                 *value = pciReadConfigReg ((PCI_HOST) hose->cfg_addr, offset,
741                                            PCI_DEV (dev));
742         } else {
743                 *value = pciOverBridgeReadConfigReg ((PCI_HOST) hose->
744                                                      cfg_addr, offset,
745                                                      PCI_DEV (dev), bus);
746         }
747
748         return 0;
749 }
750
751 static int gt_write_config_dword (struct pci_controller *hose,
752                                   pci_dev_t dev, int offset, u32 value)
753 {
754         int bus = PCI_BUS (dev);
755
756         if ((bus == local_buses[0]) || (bus == local_buses[1])) {
757                 pciWriteConfigReg ((PCI_HOST) hose->cfg_addr, offset,
758                                    PCI_DEV (dev), value);
759         } else {
760                 pciOverBridgeWriteConfigReg ((PCI_HOST) hose->cfg_addr,
761                                              offset, PCI_DEV (dev), bus,
762                                              value);
763         }
764         return 0;
765 }
766
767
768 static void gt_setup_ide (struct pci_controller *hose,
769                           pci_dev_t dev, struct pci_config_table *entry)
770 {
771         static const int ide_bar[] = { 8, 4, 8, 4, 0, 0 };
772         u32 bar_response, bar_value;
773         int bar;
774
775         for (bar = 0; bar < 6; bar++) {
776                 /*ronen different function for 3rd bank. */
777                 unsigned int offset =
778                         (bar < 2) ? bar * 8 : 0x100 + (bar - 2) * 8;
779
780                 pci_write_config_dword (dev, PCI_BASE_ADDRESS_0 + offset,
781                                         0x0);
782                 pci_read_config_dword (dev, PCI_BASE_ADDRESS_0 + offset,
783                                        &bar_response);
784
785                 pciauto_region_allocate (bar_response &
786                                          PCI_BASE_ADDRESS_SPACE_IO ? hose->
787                                          pci_io : hose->pci_mem, ide_bar[bar],
788                                          &bar_value);
789
790                 pci_write_config_dword (dev, PCI_BASE_ADDRESS_0 + bar * 4,
791                                         bar_value);
792         }
793 }
794
795
796 /* TODO BJW: Change this for DB64360. This was pulled from the EV64260  */
797 /* and is curently not called *. */
798 #if 0
799 static void gt_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
800 {
801         unsigned char pin, irq;
802
803         pci_read_config_byte (dev, PCI_INTERRUPT_PIN, &pin);
804
805         if (pin == 1) {         /* only allow INT A */
806                 irq = pci_irq_swizzle[(PCI_HOST) hose->
807                                       cfg_addr][PCI_DEV (dev)];
808                 if (irq)
809                         pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
810         }
811 }
812 #endif
813
814 struct pci_config_table gt_config_table[] = {
815         {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
816          PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
817
818         {}
819 };
820
821 struct pci_controller pci0_hose = {
822 /*    fixup_irq: gt_fixup_irq, */
823         config_table:gt_config_table,
824 };
825
826 struct pci_controller pci1_hose = {
827 /*    fixup_irq: gt_fixup_irq, */
828         config_table:gt_config_table,
829 };
830
831 void pci_init_board (void)
832 {
833         unsigned int command;
834
835 #ifdef DEBUG
836         gt_pci_bus_mode_display (PCI_HOST0);
837 #endif
838
839         pci0_hose.first_busno = 0;
840         pci0_hose.last_busno = 0xff;
841         local_buses[0] = pci0_hose.first_busno;
842
843         /* PCI memory space */
844         pci_set_region (pci0_hose.regions + 0,
845                         CONFIG_SYS_PCI0_0_MEM_SPACE,
846                         CONFIG_SYS_PCI0_0_MEM_SPACE,
847                         CONFIG_SYS_PCI0_MEM_SIZE, PCI_REGION_MEM);
848
849         /* PCI I/O space */
850         pci_set_region (pci0_hose.regions + 1,
851                         CONFIG_SYS_PCI0_IO_SPACE_PCI,
852                         CONFIG_SYS_PCI0_IO_SPACE, CONFIG_SYS_PCI0_IO_SIZE, PCI_REGION_IO);
853
854         pci_set_ops (&pci0_hose,
855                      pci_hose_read_config_byte_via_dword,
856                      pci_hose_read_config_word_via_dword,
857                      gt_read_config_dword,
858                      pci_hose_write_config_byte_via_dword,
859                      pci_hose_write_config_word_via_dword,
860                      gt_write_config_dword);
861         pci0_hose.region_count = 2;
862
863         pci0_hose.cfg_addr = (unsigned int *) PCI_HOST0;
864
865         pci_register_hose (&pci0_hose);
866         pciArbiterEnable (PCI_HOST0);
867         pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1);
868         command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
869         command |= PCI_COMMAND_MASTER;
870         pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
871         command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
872         command |= PCI_COMMAND_MEMORY;
873         pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
874
875         pci0_hose.last_busno = pci_hose_scan (&pci0_hose);
876
877 #ifdef DEBUG
878         gt_pci_bus_mode_display (PCI_HOST1);
879 #endif
880         pci1_hose.first_busno = pci0_hose.last_busno + 1;
881         pci1_hose.last_busno = 0xff;
882         pci1_hose.current_busno = pci1_hose.first_busno;
883         local_buses[1] = pci1_hose.first_busno;
884
885         /* PCI memory space */
886         pci_set_region (pci1_hose.regions + 0,
887                         CONFIG_SYS_PCI1_0_MEM_SPACE,
888                         CONFIG_SYS_PCI1_0_MEM_SPACE,
889                         CONFIG_SYS_PCI1_MEM_SIZE, PCI_REGION_MEM);
890
891         /* PCI I/O space */
892         pci_set_region (pci1_hose.regions + 1,
893                         CONFIG_SYS_PCI1_IO_SPACE_PCI,
894                         CONFIG_SYS_PCI1_IO_SPACE, CONFIG_SYS_PCI1_IO_SIZE, PCI_REGION_IO);
895
896         pci_set_ops (&pci1_hose,
897                      pci_hose_read_config_byte_via_dword,
898                      pci_hose_read_config_word_via_dword,
899                      gt_read_config_dword,
900                      pci_hose_write_config_byte_via_dword,
901                      pci_hose_write_config_word_via_dword,
902                      gt_write_config_dword);
903
904         pci1_hose.region_count = 2;
905
906         pci1_hose.cfg_addr = (unsigned int *) PCI_HOST1;
907
908         pci_register_hose (&pci1_hose);
909
910         pciArbiterEnable (PCI_HOST1);
911         pciParkingDisable (PCI_HOST1, 1, 1, 1, 1, 1, 1, 1);
912
913         command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
914         command |= PCI_COMMAND_MASTER;
915         pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
916
917         pci1_hose.last_busno = pci_hose_scan (&pci1_hose);
918
919         command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
920         command |= PCI_COMMAND_MEMORY;
921         pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
922
923 }