source: SVN/rincon/u-boot/board/esd/cpci750/pci.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

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