blob: 8e9178db4f60bb21bc836b3e9cd4074d2faec153 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/* PCI.c - PCI functions */
2
3/* Copyright - Galileo technology. */
4
5#include <common.h>
6#include <pci.h>
7
8#include <galileo/pci.h>
9
10static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
11#ifdef CONFIG_ZUMA_V2
12 {0,0,0,0,0,0,0,29, [8 ... PCI_MAX_DEVICES-1]=0},
13 {0,0,0,0,0,0,0,28, [8 ... PCI_MAX_DEVICES-1]=0}
14#else /* EVB??? This is a guess */
15 {0,0,0,0,0,0,0,27,27, [9 ... PCI_MAX_DEVICES-1]=0},
16 {0,0,0,0,0,0,0,29,29, [9 ... PCI_MAX_DEVICES-1]=0}
17#endif
18};
19
20static const unsigned int pci_p2p_configuration_reg[]={
21 PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
22
23static const unsigned int pci_configuration_address[]={
24 PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS};
25
26static const unsigned int pci_configuration_data[]={
27 PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
28 PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER};
29
30static const unsigned int pci_error_cause_reg[]={
31 PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE};
32
33static const unsigned int pci_arbiter_control[]={
34 PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL};
35
36static const unsigned int pci_snoop_control_base_0_low[]={
37 PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW};
38static const unsigned int pci_snoop_control_top_0[]={
39 PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0};
40
41static const unsigned int pci_access_control_base_0_low[]={
42 PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW};
43static const unsigned int pci_access_control_top_0[]={
44 PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0};
45
46static const unsigned int pci_scs_bank_size[2][4] = {
47 {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
48 PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
49 {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
50 PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}};
51
52static const unsigned int pci_p2p_configuration[] = {
53 PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
54
55/********************************************************************
56* pciWriteConfigReg - Write to a PCI configuration register
57* - Make sure the GT is configured as a master before writing
58* to another device on the PCI.
59* - The function takes care of Big/Little endian conversion.
60*
61*
62* Inputs: unsigned int regOffset: The register offset as it apears in the GT spec
63* (or any other PCI device spec)
64* pciDevNum: The device number needs to be addressed.
65*
66* Configuration Address 0xCF8:
67*
68* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
69* |congif|Reserved| Bus |Device|Function|Register|00|
70* |Enable| |Number|Number| Number | Number | | <=field Name
71*
72*********************************************************************/
73void pciWriteConfigReg(PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum,unsigned int data)
74{
75 volatile unsigned int DataForAddrReg;
76 unsigned int functionNum;
77 unsigned int busNum = 0;
78 unsigned int addr;
79
80 if(pciDevNum > 32) /* illegal device Number */
81 return;
82 if(pciDevNum == SELF) /* configure our configuration space. */
83 {
84 pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
85 busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
86 }
87 functionNum = regOffset & 0x00000700;
88 pciDevNum = pciDevNum << 11;
89 regOffset = regOffset & 0xfc;
90 DataForAddrReg = ( regOffset | pciDevNum | functionNum | busNum) | BIT31;
91 GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
92 GT_REG_READ(pci_configuration_address[host], &addr);
93 if (addr != DataForAddrReg) return;
94 GT_REG_WRITE(pci_configuration_data[host],data);
95}
96
97/********************************************************************
98* pciReadConfigReg - Read from a PCI0 configuration register
99* - Make sure the GT is configured as a master before reading
100* from another device on the PCI.
101* - The function takes care of Big/Little endian conversion.
102* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
103* spec)
104* pciDevNum: The device number needs to be addressed.
105* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
106* cause register to make sure the data is valid
107*
108* Configuration Address 0xCF8:
109*
110* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
111* |congif|Reserved| Bus |Device|Function|Register|00|
112* |Enable| |Number|Number| Number | Number | | <=field Name
113*
114*********************************************************************/
115unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum)
116{
117 volatile unsigned int DataForAddrReg;
118 unsigned int data;
119 unsigned int functionNum;
120 unsigned int busNum = 0;
121
122 if(pciDevNum > 32) /* illegal device Number */
123 return 0xffffffff;
124 if(pciDevNum == SELF) /* configure our configuration space. */
125 {
126 pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
127 busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
128 }
129 functionNum = regOffset & 0x00000700;
130 pciDevNum = pciDevNum << 11;
131 regOffset = regOffset & 0xfc;
132 DataForAddrReg = (regOffset | pciDevNum | functionNum | busNum) | BIT31 ;
133 GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
134 GT_REG_READ(pci_configuration_address[host], &data);
135 if (data != DataForAddrReg)
136 return 0xffffffff;
137 GT_REG_READ(pci_configuration_data[host], &data);
138 return data;
139}
140
141/********************************************************************
142* pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
143* the agent is placed on another Bus. For more
144* information read P2P in the PCI spec.
145*
146* Inputs: unsigned int regOffset - The register offset as it apears in the
147* GT spec (or any other PCI device spec).
148* unsigned int pciDevNum - The device number needs to be addressed.
149* unsigned int busNum - On which bus does the Target agent connect
150* to.
151* unsigned int data - data to be written.
152*
153* Configuration Address 0xCF8:
154*
155* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
156* |congif|Reserved| Bus |Device|Function|Register|01|
157* |Enable| |Number|Number| Number | Number | | <=field Name
158*
159* The configuration Address is configure as type-I (bits[1:0] = '01') due to
160* PCI spec referring to P2P.
161*
162*********************************************************************/
163void pciOverBridgeWriteConfigReg(PCI_HOST host,
164 unsigned int regOffset,
165 unsigned int pciDevNum,
166 unsigned int busNum,unsigned int data)
167{
168 unsigned int DataForReg;
169 unsigned int functionNum;
170
171 functionNum = regOffset & 0x00000700;
172 pciDevNum = pciDevNum << 11;
173 regOffset = regOffset & 0xff;
174 busNum = busNum << 16;
175 if(pciDevNum == SELF) /* This board */
176 {
177 DataForReg = ( regOffset | pciDevNum | functionNum) | BIT0;
178 }
179 else
180 {
181 DataForReg = ( regOffset | pciDevNum | functionNum | busNum) |
182 BIT31 | BIT0;
183 }
184 GT_REG_WRITE(pci_configuration_address[host],DataForReg);
185 if(pciDevNum == SELF) /* This board */
186 {
187 GT_REG_WRITE(pci_configuration_data[host],data);
188 }
189 else /* configuration Transaction over the pci. */
190 {
191 /* The PCI is working in LE Mode So it swap the Data. */
192 GT_REG_WRITE(pci_configuration_data[host],WORD_SWAP(data));
193 }
194}
195
196
197/********************************************************************
198* pciOverBridgeReadConfigReg - Read from a PCIn configuration register where
199* the agent target locate on another PCI bus.
200* - Make sure the GT is configured as a master
201* before reading from another device on the PCI.
202* - The function takes care of Big/Little endian
203* conversion.
204* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
205* spec). (configuration register offset.)
206* pciDevNum: The device number needs to be addressed.
207* busNum: the Bus number where the agent is place.
208* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
209* cause register to make sure the data is valid
210*
211* Configuration Address 0xCF8:
212*
213* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
214* |congif|Reserved| Bus |Device|Function|Register|01|
215* |Enable| |Number|Number| Number | Number | | <=field Name
216*
217*********************************************************************/
218unsigned int pciOverBridgeReadConfigReg(PCI_HOST host,
219 unsigned int regOffset,
220 unsigned int pciDevNum,
221 unsigned int busNum)
222{
223 unsigned int DataForReg;
224 unsigned int data;
225 unsigned int functionNum;
226
227 functionNum = regOffset & 0x00000700;
228 pciDevNum = pciDevNum << 11;
229 regOffset = regOffset & 0xff;
230 busNum = busNum << 16;
231 if (pciDevNum == SELF) /* This board */
232 {
233 DataForReg = (regOffset | pciDevNum | functionNum) | BIT31 ;
234 }
235 else /* agent on another bus */
236 {
237 DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
238 BIT0 | BIT31 ;
239 }
240 GT_REG_WRITE(pci_configuration_address[host],DataForReg);
241 if (pciDevNum == SELF) /* This board */
242 {
243 GT_REG_READ(pci_configuration_data[host], &data);
244 return data;
245 }
246 else /* The PCI is working in LE Mode So it swap the Data. */
247 {
248 GT_REG_READ(pci_configuration_data[host], &data);
249 return WORD_SWAP(data);
250 }
251}
252
253/********************************************************************
254* pciGetRegOffset - Gets the register offset for this region config.
255*
256* INPUT: Bus, Region - The bus and region we ask for its base address.
257* OUTPUT: N/A
258* RETURNS: PCI register base address
259*********************************************************************/
260static unsigned int pciGetRegOffset(PCI_HOST host, PCI_REGION region)
261{
262 switch (host)
263 {
264 case PCI_HOST0:
265 switch(region) {
266 case PCI_IO: return PCI_0I_O_LOW_DECODE_ADDRESS;
267 case PCI_REGION0: return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
268 case PCI_REGION1: return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
269 case PCI_REGION2: return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
270 case PCI_REGION3: return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
271 }
272 case PCI_HOST1:
273 switch(region) {
274 case PCI_IO: return PCI_1I_O_LOW_DECODE_ADDRESS;
275 case PCI_REGION0: return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
276 case PCI_REGION1: return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
277 case PCI_REGION2: return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
278 case PCI_REGION3: return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
279 }
280 }
281 return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
282}
283
284static unsigned int pciGetRemapOffset(PCI_HOST host, PCI_REGION region)
285{
286 switch (host)
287 {
288 case PCI_HOST0:
289 switch(region) {
290 case PCI_IO: return PCI_0I_O_ADDRESS_REMAP;
291 case PCI_REGION0: return PCI_0MEMORY0_ADDRESS_REMAP;
292 case PCI_REGION1: return PCI_0MEMORY1_ADDRESS_REMAP;
293 case PCI_REGION2: return PCI_0MEMORY2_ADDRESS_REMAP;
294 case PCI_REGION3: return PCI_0MEMORY3_ADDRESS_REMAP;
295 }
296 case PCI_HOST1:
297 switch(region) {
298 case PCI_IO: return PCI_1I_O_ADDRESS_REMAP;
299 case PCI_REGION0: return PCI_1MEMORY0_ADDRESS_REMAP;
300 case PCI_REGION1: return PCI_1MEMORY1_ADDRESS_REMAP;
301 case PCI_REGION2: return PCI_1MEMORY2_ADDRESS_REMAP;
302 case PCI_REGION3: return PCI_1MEMORY3_ADDRESS_REMAP;
303 }
304 }
305 return PCI_0MEMORY0_ADDRESS_REMAP;
306}
307
308bool pciMapSpace(PCI_HOST host, PCI_REGION region, unsigned int remapBase, unsigned int bankBase,unsigned int bankLength)
309{
310 unsigned int low=0xfff;
311 unsigned int high=0x0;
312 unsigned int regOffset=pciGetRegOffset(host, region);
313 unsigned int remapOffset=pciGetRemapOffset(host, region);
314
315 if(bankLength!=0) {
316 low = (bankBase >> 20) & 0xfff;
317 high=((bankBase+bankLength)>>20)-1;
318 }
319
320 GT_REG_WRITE(regOffset, low | (1<<24)); /* no swapping */
321 GT_REG_WRITE(regOffset+8, high);
322
323 if(bankLength!=0) { /* must do AFTER writing maps */
324 GT_REG_WRITE(remapOffset, remapBase>>20); /* sorry, 32 bits only.
325 dont support upper 32
326 in this driver */
327 }
328 return true;
329}
330
331unsigned int pciGetSpaceBase(PCI_HOST host, PCI_REGION region)
332{
333 unsigned int low;
334 unsigned int regOffset=pciGetRegOffset(host, region);
335 GT_REG_READ(regOffset,&low);
336 return (low&0xfff)<<20;
337}
338
339unsigned int pciGetSpaceSize(PCI_HOST host, PCI_REGION region)
340{
341 unsigned int low,high;
342 unsigned int regOffset=pciGetRegOffset(host, region);
343 GT_REG_READ(regOffset,&low);
344 GT_REG_READ(regOffset+8,&high);
345 high&=0xfff;
346 low&=0xfff;
347 if(high<=low) return 0;
348 return (high+1-low)<<20;
349}
350
351/********************************************************************
352* pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
353*
354* Inputs: base and size of PCI SCS
355*********************************************************************/
356void pciMapMemoryBank(PCI_HOST host, MEMORY_BANK bank, unsigned int pciDramBase,unsigned int pciDramSize)
357{
358 pciDramBase = pciDramBase & 0xfffff000;
359 pciDramBase = pciDramBase | (pciReadConfigReg(host,
360 PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF) & 0x00000fff);
361 pciWriteConfigReg(host,PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF,pciDramBase);
362 if(pciDramSize == 0)
363 pciDramSize ++;
364 GT_REG_WRITE(pci_scs_bank_size[host][bank], pciDramSize-1);
365}
366
367
368/********************************************************************
369* pciSetRegionFeatures - This function modifys one of the 8 regions with
370* feature bits given as an input.
371* - Be advised to check the spec before modifying them.
372* Inputs: PCI_PROTECT_REGION region - one of the eight regions.
373* unsigned int features - See file: pci.h there are defintion for those
374* region features.
375* unsigned int baseAddress - The region base Address.
376* unsigned int topAddress - The region top Address.
377* Returns: false if one of the parameters is erroneous true otherwise.
378*********************************************************************/
379bool pciSetRegionFeatures(PCI_HOST host, PCI_ACCESS_REGIONS region,unsigned int features,
380 unsigned int baseAddress,unsigned int regionLength)
381{
382 unsigned int accessLow;
383 unsigned int accessHigh;
384 unsigned int accessTop = baseAddress + regionLength;
385
386 if(regionLength == 0) /* close the region. */
387 {
388 pciDisableAccessRegion(host, region);
389 return true;
390 }
391 /* base Address is store is bits [11:0] */
392 accessLow = (baseAddress & 0xfff00000) >> 20;
393 /* All the features are update according to the defines in pci.h (to be on
394 the safe side we disable bits: [11:0] */
395 accessLow = accessLow | (features & 0xfffff000);
396 /* write to the Low Access Region register */
397 GT_REG_WRITE( pci_access_control_base_0_low[host] + 0x10*region,accessLow);
398
399 accessHigh = (accessTop & 0xfff00000) >> 20;
400
401 /* write to the High Access Region register */
402 GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,accessHigh - 1);
403 return true;
404}
405
406/********************************************************************
407* pciDisableAccessRegion - Disable The given Region by writing MAX size
408* to its low Address and MIN size to its high Address.
409*
410* Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled.
411* Returns: N/A.
412*********************************************************************/
413void pciDisableAccessRegion(PCI_HOST host, PCI_ACCESS_REGIONS region)
414{
415 /* writing back the registers default values. */
416 GT_REG_WRITE(pci_access_control_base_0_low[host] + 0x10*region,0x01001fff);
417 GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,0);
418}
419
420/********************************************************************
421* pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
422*
423* Inputs: N/A
424* Returns: true.
425*********************************************************************/
426bool pciArbiterEnable(PCI_HOST host)
427{
428 unsigned int regData;
429
430 GT_REG_READ(pci_arbiter_control[host],&regData);
431 GT_REG_WRITE(pci_arbiter_control[host],regData | BIT31);
432 return true;
433}
434
435/********************************************************************
436* pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
437*
438* Inputs: N/A
439* Returns: true
440*********************************************************************/
441bool pciArbiterDisable(PCI_HOST host)
442{
443 unsigned int regData;
444
445 GT_REG_READ(pci_arbiter_control[host],&regData);
446 GT_REG_WRITE(pci_arbiter_control[host],regData & 0x7fffffff);
447 return true;
448}
449
450/********************************************************************
451* pciParkingDisable - Park on last option disable, with this function you can
452* disable the park on last mechanism for each agent.
453* disabling this option for all agents results parking
454* on the internal master.
455*
456* Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent.
457* PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
458* PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
459* PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
460* PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
461* PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
462* PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
463* Returns: true
464*********************************************************************/
465bool pciParkingDisable(PCI_HOST host, PCI_AGENT_PARK internalAgent,
466 PCI_AGENT_PARK externalAgent0,
467 PCI_AGENT_PARK externalAgent1,
468 PCI_AGENT_PARK externalAgent2,
469 PCI_AGENT_PARK externalAgent3,
470 PCI_AGENT_PARK externalAgent4,
471 PCI_AGENT_PARK externalAgent5)
472{
473 unsigned int regData;
474 unsigned int writeData;
475
476 GT_REG_READ(pci_arbiter_control[host],&regData);
477 writeData = (internalAgent << 14) + (externalAgent0 << 15) + \
478 (externalAgent1 << 16) + (externalAgent2 << 17) + \
479 (externalAgent3 << 18) + (externalAgent4 << 19) + \
480 (externalAgent5 << 20);
481 regData = (regData & ~(0x7f<<14)) | writeData;
482 GT_REG_WRITE(pci_arbiter_control[host],regData);
483 return true;
484}
485
486/********************************************************************
487* pciSetRegionSnoopMode - This function modifys one of the 4 regions which
488* supports Cache Coherency in the PCI_n interface.
489* Inputs: region - One of the four regions.
490* snoopType - There is four optional Types:
491* 1. No Snoop.
492* 2. Snoop to WT region.
493* 3. Snoop to WB region.
494* 4. Snoop & Invalidate to WB region.
495* baseAddress - Base Address of this region.
496* regionLength - Region length.
497* Returns: false if one of the parameters is wrong otherwise return true.
498*********************************************************************/
499bool pciSetRegionSnoopMode(PCI_HOST host, PCI_SNOOP_REGION region,PCI_SNOOP_TYPE snoopType,
500 unsigned int baseAddress,
501 unsigned int regionLength)
502{
503 unsigned int snoopXbaseAddress;
504 unsigned int snoopXtopAddress;
505 unsigned int data;
506 unsigned int snoopHigh = baseAddress + regionLength;
507
508 if( (region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB) )
509 return false;
510 snoopXbaseAddress = pci_snoop_control_base_0_low[host] + 0x10 * region;
511 snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
512 if(regionLength == 0) /* closing the region */
513 {
514 GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
515 GT_REG_WRITE(snoopXtopAddress,0);
516 return true;
517 }
518 baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
519 data = (baseAddress >> 20) | snoopType << 12;
520 GT_REG_WRITE(snoopXbaseAddress,data);
521 snoopHigh = (snoopHigh & 0xfff00000) >> 20;
522 GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1);
523 return true;
524}
525
526/*
527 *
528 */
529
530static int gt_read_config_dword(struct pci_controller *hose,
531 pci_dev_t dev,
532 int offset, u32* value)
533{
534 *value = pciReadConfigReg((PCI_HOST) hose->cfg_addr, offset, PCI_DEV(dev));
535 return 0;
536}
537
538static int gt_write_config_dword(struct pci_controller *hose,
539 pci_dev_t dev,
540 int offset, u32 value)
541{
542 pciWriteConfigReg((PCI_HOST)hose->cfg_addr, offset, PCI_DEV(dev), value);
543 return 0;
544}
545
546/*
547 *
548 */
549
550static void gt_setup_ide(struct pci_controller *hose,
551 pci_dev_t dev, struct pci_config_table *entry)
552{
553 static const int ide_bar[]={8,4,8,4,0,0};
554 u32 bar_response, bar_value;
555 int bar;
556
557 for (bar=0; bar<6; bar++)
558 {
559 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, 0x0);
560 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, &bar_response);
561
562 pciauto_region_allocate(bar_response & PCI_BASE_ADDRESS_SPACE_IO ?
563 hose->pci_io : hose->pci_mem, ide_bar[bar], &bar_value);
564
565 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, bar_value);
566 }
567}
568
569static void gt_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
570{
571 unsigned char pin, irq;
572
573 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
574
575 if(pin == 1) { /* only allow INT A */
576 irq = pci_irq_swizzle[(PCI_HOST)hose->cfg_addr][PCI_DEV(dev)];
577 if(irq)
578 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
579 }
580}
581
582struct pci_config_table gt_config_table[] = {
583 { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
584 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
585
586 { }
587};
588
589struct pci_controller pci0_hose = {
590 fixup_irq: gt_fixup_irq,
591 config_table: gt_config_table,
592};
593
594struct pci_controller pci1_hose = {
595 fixup_irq: gt_fixup_irq,
596 config_table: gt_config_table,
597};
598
599void
600pci_init(void)
601{
602 unsigned int command;
603
604 pci0_hose.first_busno = 0;
605 pci0_hose.last_busno = 0xff;
606
607 /* PCI memory space */
608 pci_set_region(pci0_hose.regions + 0,
609 CFG_PCI0_0_MEM_SPACE,
610 CFG_PCI0_0_MEM_SPACE,
611 CFG_PCI0_MEM_SIZE,
612 PCI_REGION_MEM);
613
614 /* PCI I/O space */
615 pci_set_region(pci0_hose.regions + 1,
616 CFG_PCI0_IO_SPACE_PCI,
617 CFG_PCI0_IO_SPACE,
618 CFG_PCI0_IO_SIZE,
619 PCI_REGION_IO);
620
621 pci_set_ops(&pci0_hose,
622 pci_hose_read_config_byte_via_dword,
623 pci_hose_read_config_word_via_dword,
624 gt_read_config_dword,
625 pci_hose_write_config_byte_via_dword,
626 pci_hose_write_config_word_via_dword,
627 gt_write_config_dword);
628
629 pci0_hose.region_count = 2;
630
631 pci0_hose.cfg_addr = (unsigned int*) PCI_HOST0;
632
633 pci_register_hose(&pci0_hose);
634
635 pciArbiterEnable(PCI_HOST0);
636 pciParkingDisable(PCI_HOST0,1,1,1,1,1,1,1);
637
638 command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
639 command |= PCI_COMMAND_MASTER;
640 pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
641
642 pci0_hose.last_busno = pci_hose_scan(&pci0_hose);
643
644 command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
645 command |= PCI_COMMAND_MEMORY;
646 pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
647
648 pci1_hose.first_busno = pci0_hose.last_busno + 1;
649 pci1_hose.last_busno = 0xff;
650
651 /* PCI memory space */
652 pci_set_region(pci1_hose.regions + 0,
653 CFG_PCI1_0_MEM_SPACE,
654 CFG_PCI1_0_MEM_SPACE,
655 CFG_PCI1_MEM_SIZE,
656 PCI_REGION_MEM);
657
658 /* PCI I/O space */
659 pci_set_region(pci1_hose.regions + 1,
660 CFG_PCI1_IO_SPACE_PCI,
661 CFG_PCI1_IO_SPACE,
662 CFG_PCI1_IO_SIZE,
663 PCI_REGION_IO);
664
665 pci_set_ops(&pci1_hose,
666 pci_hose_read_config_byte_via_dword,
667 pci_hose_read_config_word_via_dword,
668 gt_read_config_dword,
669 pci_hose_write_config_byte_via_dword,
670 pci_hose_write_config_word_via_dword,
671 gt_write_config_dword);
672
673 pci1_hose.region_count = 2;
674
675 pci1_hose.cfg_addr = (unsigned int*) PCI_HOST1;
676
677 pci_register_hose(&pci1_hose);
678
679 pciArbiterEnable(PCI_HOST1);
680 pciParkingDisable(PCI_HOST1,1,1,1,1,1,1,1);
681
682 command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
683 command |= PCI_COMMAND_MASTER;
684 pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
685
686 pci1_hose.last_busno = pci_hose_scan(&pci1_hose);
687
688 command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
689 command |= PCI_COMMAND_MEMORY;
690 pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
691}