ixp425Pci.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:27k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ixp425Pci.c - PCI driver for the IXP425 */
  2. /* Copyright 2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01a,05jun02,jb  initial version...
  7. */
  8. /*
  9. DESCRIPTION
  10.   
  11. This is device driver code for the Intel IXP425 PCI unit. This code provides 
  12. a set of initialization routines which automatically discover and initialize 
  13. any PCI devices on the PCI bus at startup time. Configuration routines are 
  14. provided to be used by PCI device drivers in order to configure PCI devices.
  15. In order for the functionality defined herein to be available, INCLUDE_PCI 
  16. must be defined in config.h
  17. .SH INITIALIZATION
  18. The function sysPciInit() should be called from
  19. sysHwInit() to initialize the PCI unit on the IXP425.
  20. The function sysPciAssignAddrs() should be called from 
  21. sysHwInit() after the call to sysPciInit to initialise 
  22. devices on the PCI bus.
  23. INCLUDE FILES:
  24. ixp425Pci.h ixp425Pci_p.h
  25. SEE ALSO:
  26. .I "PCI Local Bus Specification, Revision 2.2, December 18, 1998"
  27. */
  28. #include "vxWorks.h"
  29. #include "config.h" 
  30. #include "dllLib.h"   
  31. #include "sysLib.h"  
  32. #include "stdio.h"   
  33. #include "stdlib.h" 
  34. #include "intLib.h" 
  35. #include "ixp425Pci.h"
  36. #include "ixp425Pci_p.h"
  37. #ifndef IX_PCI_UNIT_TEST
  38. #include "ixp425Gpio.h"
  39. #include "ixp425IntrCtl.h"
  40. #endif
  41. /* local defines  */
  42. /*The following defines are used by busy-loop waits. Busy loops are necessary because 
  43.   in the early stages of PCI initialisation we do not have proper OS services. 
  44.   The delay values here are chosen to be pessimistic, ensuring that we always
  45.   wait for at least the required period.
  46. */
  47. #define PCI_DELAY       500  
  48. #define USEC_LOOP_COUNT 533
  49. #define PCI_SETTLE_USEC 200
  50. #define PCI_MIN_RESET_ASSERT_USEC 2000
  51. /*Specify the initial command we send to PCI devices*/
  52. #define INITIAL_PCI_CMD (PCI_CMD_IO_ENABLE         
  53.  | PCI_CMD_MEM_ENABLE      
  54.  | PCI_CMD_MASTER_ENABLE   
  55.  | PCI_CMD_WI_ENABLE)
  56. #define MAX_PCC_MAP  (3)
  57. /*Each mapping permits access to exactly 16MB of AHB space*/
  58. #define MAPPING_SIZE (0x1000000)
  59. /*
  60.  * Variable declarations global to this file only. Externs are followed by
  61.  * static variables.
  62.  */
  63. #ifdef IXP425_PCI_SIMPLE_MAPPING
  64. LOCAL UINT32 nextPccMap = MAX_PCC_MAP+1;
  65. #else
  66. LOCAL UINT32 nextPccMap = 0;
  67. #endif
  68. extern DL_LIST pciIntList[PCI_IRQ_LINES];  /* linked list of interrupt handlers */
  69. extern DL_LIST pciCallbackList;            /* linked list of callback error handlers */
  70. LOCAL STATUS    pciLibInitStatus = NONE;
  71. LOCAL PciStatus lastError        = PCI_OK;
  72. LOCAL UINT32    nMBars;
  73. LOCAL UINT32    nIOBars;
  74. LOCAL PciBar   *memBars[IXP425_PCI_MAX_BAR];
  75. LOCAL PciBar   *ioBars[IXP425_PCI_MAX_BAR];
  76.     
  77. /* 
  78.  * The devices  array contains an entry for each individually configurable
  79.  * entity on the PCI bus. In PCI nomenclature, such entities are 
  80.  * referred to as "functions", and it is possible for a PCI card to contain
  81.  * more than one function (e.g. combined NIC + Modem), however the convention in PCI 
  82.  * controller drivers is to refer to such individually configurable entities
  83.  * as devices. This is primarily due to the fact that multi function
  84.  * cards are rare, so function and device are for the most part synonymous.
  85.  *
  86.  * This is potentially confusing since the drivers also typically
  87.  * implicity refer to slots/cards on the PCI bus as devices, 
  88.  * since the constant PCI_MAX_DEV (in our case IXP425_PCI_MAX_DEV)
  89.  * is set to be the maximum number of slots/cards.
  90.  * We have chosen to follow the normal PCI driver convention here,
  91.  * so the devices array contains an entry for each function,
  92.  * and the constant IXP425_PCI_MAX_DEV is set to the maximum
  93.  * number of PCI cards that can be present on the bus.
  94.  * We include the PCI controller itself in this array, hence the +1 
  95.  */
  96. LOCAL PciDevice devices[IXP425_PCI_MAX_FUNC_ON_BUS]; 
  97. LOCAL UINT32    nDevices;
  98. LOCAL UINT32 ixp425PciIntTranslate[IXP425_PCI_MAX_DEV][PCI_IRQ_LINES] = {
  99.     {IXP425_PCI_INTA_INTERRUPT_NUM, IXP425_PCI_INTB_INTERRUPT_NUM, 
  100.      IXP425_PCI_INTC_INTERRUPT_NUM, IXP425_PCI_INTD_INTERRUPT_NUM},
  101.     {IXP425_PCI_INTB_INTERRUPT_NUM, IXP425_PCI_INTC_INTERRUPT_NUM, 
  102.      IXP425_PCI_INTD_INTERRUPT_NUM, IXP425_PCI_INTA_INTERRUPT_NUM},
  103.     {IXP425_PCI_INTC_INTERRUPT_NUM, IXP425_PCI_INTD_INTERRUPT_NUM, 
  104.      IXP425_PCI_INTA_INTERRUPT_NUM, IXP425_PCI_INTB_INTERRUPT_NUM},
  105.     {IXP425_PCI_INTD_INTERRUPT_NUM, IXP425_PCI_INTA_INTERRUPT_NUM, 
  106.      IXP425_PCI_INTB_INTERRUPT_NUM, IXP425_PCI_INTC_INTERRUPT_NUM}
  107. };
  108. /* extern prototypes*/
  109. extern void   pciInternalIsr (UINT32 param);
  110. extern void   pciInt (UINT32 param); 
  111. extern BOOL pciDeviceExists (UINT32 busNo, UINT32 deviceNo, UINT32 funcNo);
  112. #ifdef INCLUDE_PCI_DMA
  113. extern STATUS pciDmaInit (void);
  114. #endif
  115. /* static function prototypes */
  116. LOCAL void crpRead (UINT32 offset, UINT32 *data);
  117. LOCAL void crpWrite (UINT32 offset, UINT32 data);
  118. /* driver functions */
  119. /******************************************************************************
  120. *
  121. * sysPciIsHost - returns a boolean indicating whether we are the Bus host
  122. *
  123. * This function returns a boolean indicating whether we are the PCI Bus host or not
  124. *
  125. * RETURNS: TRUE if we are PCI bus host, otherwise FALSE
  126. */
  127. LOCAL BOOL
  128. sysPciIsHost (void)
  129. {
  130.     UINT32 regval;
  131.     
  132.     REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
  133.     if(regval & PCI_CSR_HOST)
  134.     {
  135. return TRUE;
  136.     }
  137.     else
  138.     {
  139. return FALSE;
  140.     }
  141. }
  142. /******************************************************************************
  143. *
  144. * sysPciGpioConfig - Configure the PCI gpio lines as outputs
  145. *
  146. * Configures the Clock and Reset GPIO lines as outputs,
  147. * and configures the PCI INTA#..INTD# as interrupts, active low.
  148. * Clears the interrupt status indicators for PCI interrupts.
  149. * If IXP425_PCI_GPIO_CLOCK_ON is not defined, then the clock GPIO
  150. * is not driven as an output by this code.
  151. *
  152. * RETURNS: void
  153. */
  154. LOCAL void 
  155. sysPciGpioConfig (void)
  156. {   
  157. #ifdef IXP425_PCI_GPIO_CLOCK_ON
  158.     ixp425GPIOLineConfig (IXP425_PCI_CLK_PIN, IXP425_GPIO_OUT);
  159. #endif
  160.     ixp425GPIOLineConfig (IXP425_PCI_RESET_GPIO, IXP425_GPIO_OUT);    
  161.     
  162.     ixp425GPIOLineConfig (IXP425_PCI_INTA_PIN, 
  163.   IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
  164. /*    ixp425GPIOLineConfig (IXP425_PCI_INTB_PIN, 
  165.   IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
  166.     ixp425GPIOLineConfig (IXP425_PCI_INTC_PIN, 
  167.   IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);
  168.     ixp425GPIOLineConfig (IXP425_PCI_INTD_PIN, 
  169.   IXP425_GPIO_IN | IXP425_GPIO_ACTIVE_LOW);*/
  170.     /*Set the interrupt status in the GPIO block to a known starting state*/
  171.     ixp425GPIOIntStatusClear(IXP425_PCI_INTA_PIN);
  172. /*    ixp425GPIOIntStatusClear(IXP425_PCI_INTB_PIN);
  173.     ixp425GPIOIntStatusClear(IXP425_PCI_INTC_PIN);
  174.     ixp425GPIOIntStatusClear(IXP425_PCI_INTD_PIN);*/
  175. }
  176. /******************************************************************************
  177. *
  178. * sysPciResetAssert - Asserts PCI reset to the PCI bus via IXP425_PCI_RESET_GPIO
  179. *
  180. * RETURNS: void
  181. */
  182. LOCAL void 
  183. sysPciResetAssert (void)
  184. {
  185.     ixp425GPIOLineSet (IXP425_PCI_RESET_GPIO, IXP425_GPIO_LOW);
  186. }
  187. /******************************************************************************
  188. *
  189. * sysPciResetDeassert - Deasserts PCI reset to the PCI bus via IXP425_PCI_RESET_GPIO
  190. *
  191. * RETURNS: void
  192. */
  193. LOCAL void 
  194. sysPciResetDeassert (void)
  195. {
  196.     ixp425GPIOLineSet (IXP425_PCI_RESET_GPIO, IXP425_GPIO_HIGH);
  197. }
  198. /******************************************************************************
  199. *
  200. * sysAhbDoorbellReset - reset the AHB doorbell register
  201. *
  202. * RETURNS: void
  203. */
  204. LOCAL void 
  205. sysAhbDoorbellReset (void)
  206. {
  207.     UINT32 regval;
  208.     REG_READ (PCI_CSR_BASE, PCI_AHBDOORBELL_OFFSET, regval);
  209.     /*The bits in this register are write 1 to clear*/
  210.     REG_WRITE (PCI_CSR_BASE, PCI_AHBDOORBELL_OFFSET, regval);
  211. }
  212. /******************************************************************************
  213. *
  214. * sysPciGpioClockConfig - Configures the PCI clock output on IXP425_PCI_CLK_PIN
  215. *
  216. * This function configures the GPIO clock pin specified by IXP425_PCI_CLK_PIN.
  217. * RETURNS: void
  218. */
  219. LOCAL STATUS
  220. sysPciGpioClockConfig (PciClockRate rate)
  221. {
  222.     if (rate==PciClock33)
  223.     {
  224. ixp425GPIOClockSet (IXP425_PCI_CLK_PIN,IXP425_GPIO_33_MHZ);
  225. return OK;
  226.     }
  227.     else
  228.     {       
  229. return ERROR;
  230.     }
  231. }
  232. /******************************************************************************
  233. *
  234. * sysPciGpioClockEnable - Enables the clock output
  235. *
  236. * RETURNS: void
  237. */
  238. LOCAL void 
  239. sysPciGpioClockEnable ()
  240. {
  241.     ixp425GPIOClockEnable (IXP425_PCI_CLK_PIN, TRUE);
  242. }
  243. /******************************************************************************
  244. *
  245. * sysPciGpioClockDisable - Disables the clock output
  246. *
  247. * RETURNS: void
  248. */
  249. LOCAL void 
  250. sysPciGpioClockDisable ()
  251. {
  252.     ixp425GPIOClockEnable (IXP425_PCI_CLK_PIN, FALSE);
  253. }
  254. /******************************************************************************
  255. *
  256. * sysPciIntConnect - Bind PCI interrupts
  257. *
  258. * This function binds the four PCI bus interrupts (INTA..INTD) to the
  259. * appropriate vectors, and also binds the internal PCI controller interrupt
  260. * to a vector.
  261. *
  262. * RETURNS: N/A
  263. */
  264. LOCAL void
  265. sysPciIntConnect()
  266. {
  267.     /*bind INTA# through INTD# to the PCI interrupt handler*/
  268.     intConnect (INUM_TO_IVEC (IXP425_PCI_INTA_INTERRUPT_NUM), pciInt, 
  269. IXP425_PCI_INTA_INDEX);
  270. /*
  271.     intConnect (INUM_TO_IVEC (IXP425_PCI_INTB_INTERRUPT_NUM), pciInt, 
  272.        IXP425_PCI_INTB_INDEX);
  273.     intConnect (INUM_TO_IVEC (IXP425_PCI_INTC_INTERRUPT_NUM), pciInt, 
  274. IXP425_PCI_INTC_INDEX);
  275.     intConnect (INUM_TO_IVEC (IXP425_PCI_INTD_INTERRUPT_NUM), pciInt, 
  276. IXP425_PCI_INTD_INDEX);*/
  277.     /*Bind the internal interrupt handler to the PCI interrupt*/
  278.     intConnect (INUM_TO_IVEC (IXP425_PCI_INTERNAL_INT_VEC), pciInternalIsr, 0);
  279. }
  280. /******************************************************************************
  281. *
  282. * sysPciIntEnable - enable PCI interrupts
  283. *
  284. * This function enables the internal PCI controller interrupt
  285. * Interrupts INTA..INTD are enabled by the drivers associated with
  286. * the devices using them, and so are not enabled here.
  287. *
  288. * RETURNS: N/A
  289. */
  290. LOCAL void
  291. sysPciIntEnable()
  292. {    
  293.     intEnable(IXP425_PCI_INTERNAL_INT_VEC);
  294. }
  295. /******************************************************************************
  296. *
  297. * sortBars - Sort Bars largest to smallest
  298. *
  299. * This function takes in an array of pointers to BARs,
  300. * it will sort the BARS from largest to smallest.
  301. *
  302. * RETURNS: N/A
  303. */
  304. LOCAL void
  305. sortBars (PciBar *Bars[],     /* Array of pointers to BARs */
  306.   UINT32 nBars)       /* Number of BARs in array */      
  307. {
  308.     UINT32 i, j;
  309.     PciBar *tmp;
  310.     
  311.     if(nBars == 0)
  312.     {
  313. return;
  314.     }
  315.     /* Sort biggest to smallest */
  316.     for (i = 0; i < nBars-1; i++) 
  317.     {
  318.         for (j = i+1; j < nBars; j++) 
  319. {
  320.             if (Bars[j]->size > Bars[i]->size) 
  321.     {
  322.                 /* swap them */
  323.                 tmp = Bars[i];
  324.                 Bars[i] = Bars[j];
  325.                 Bars[j] = tmp;
  326.             }
  327.         } 
  328.     }     
  329. }
  330. /******************************************************************************
  331. *
  332. * calcBars - calculate BAR values
  333. *
  334. * This function takes in an array of pointers to BARs and a starting
  335. * PCI address, then it will then align the address appropriately for the first 
  336. * (largest) BAR, and then assign increasing addresses with no gaps.
  337. *
  338. * RETURNS: N/A
  339. */
  340. LOCAL void
  341. calcBars (PciBar *Bars[],     /* Array of pointers to BARs */
  342.   UINT32 nBars,       /* Number of BARs in array */
  343.   UINT32 startAddr)   /* PCI address at which to start */    
  344. {
  345.     UINT32 i;
  346.     
  347.     if (nBars == 0)
  348.     {
  349. return;
  350.     }
  351.     /* Assign Addresses; first align startAddr */
  352.     
  353.     startAddr = (startAddr + Bars[0]->size - 1) & ~(Bars[0]->size - 1);
  354.     
  355.     for (i=0; i < nBars; i++) 
  356.     {
  357.         Bars[i]->address |= startAddr;
  358.         startAddr += Bars[i]->size;
  359.     } 
  360. }
  361. /******************************************************************************
  362. *
  363. * sysPciBarInfoGet - retrieve BAR info from a device
  364. *
  365. * This function ascertains the size requirement of each BAR in the 
  366. * specified device, and determines whether the BAR is for IO or
  367. * Memory space. Retreived data is stored in the global devices array
  368. */
  369.  
  370. LOCAL void
  371. sysPciBarInfoGet (UINT32 devnum, 
  372.   UINT32 bus, 
  373.   UINT32 dev, 
  374.   UINT32 func)
  375. {    
  376.     UINT32 data32;
  377.     UINT32 tmp;
  378.     UINT32 size;   
  379.     UINT32 i;
  380.     for (i=0; i < IXP425_PCI_MAX_BAR_PER_FUNC; i++) 
  381.     {
  382. pciConfigOutLong (bus, dev, func,
  383.   PCI_CFG_BASE_ADDRESS_0 + (4*i),
  384.   IXP425_PCI_BAR_QUERY);
  385. pciConfigInLong (bus, dev, func,
  386.  PCI_CFG_BASE_ADDRESS_0 + (4*i),
  387.  &data32);
  388. if (data32 == 0)
  389. {
  390.     /*If the BAR reads back as zero, we know that we have
  391.       already configured all BARs that are supported in the device*/
  392.     break;
  393. }
  394. /*set the bottom bit of the BAR address, according
  395.   to whether this is memory (bit 0 = 0) or IO (bit 0 = 1) space
  396.   the actual address is calculated in the function calcBars*/
  397. devices[devnum].bar[i].address = (data32 & 1);
  398. if (data32 & 1) 
  399. {
  400.     /* IO space */
  401.     tmp = data32 & ~0x3;
  402.     size = ~(tmp-1);
  403.     devices[devnum].bar[i].size = size;
  404.     
  405.     if (nIOBars < IXP425_PCI_MAX_BAR)
  406.     {
  407. ioBars[nIOBars++] = &devices[devnum].bar[i];
  408.     }     
  409. else 
  410. {
  411.     /* Mem space */
  412.     tmp = data32 & ~IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
  413.     size = ~(tmp-1);
  414.     devices[devnum].bar[i].size = size;
  415.     if (nMBars < IXP425_PCI_MAX_BAR)
  416.     {
  417. memBars[nMBars++] = &devices[devnum].bar[i];
  418.     }     
  419.     else
  420.     {
  421. devices[devnum].error = TRUE;
  422.     }
  423. }
  424.     }
  425.     devices[devnum].bar[i].size = 0;
  426. }
  427. /******************************************************************************
  428. *
  429. * sysPciDeviceBarsWrite - write BARs in PCI devices
  430. *
  431. * Write the bars calculated in the devices array to the actual
  432. * devices' BAR registers
  433. *
  434. * RETURNS - N/A
  435. */
  436.  
  437. LOCAL void
  438. sysPciDeviceBarsWrite ()
  439. {
  440.     UINT32 i,j;
  441.     for (i=1; i<nDevices; i++)  
  442.     {
  443.         if (devices[i].error)
  444. {
  445.             continue;
  446. }
  447. /*Write the BARs in PCI device i*/
  448.         for (j=0; devices[i].bar[j].size; j++) 
  449. {     
  450.             pciConfigOutLong (devices[i].bus,
  451.       devices[i].device,
  452.       devices[i].func,
  453.       PCI_CFG_BASE_ADDRESS_0 + (4*j),
  454.       devices[i].bar[j].address);
  455.         } 
  456.         pciConfigOutLong (devices[i].bus,
  457.   devices[i].device,
  458.   devices[i].func,
  459.   PCI_CFG_DEV_INT_LINE,
  460.   devices[i].irq);
  461.         pciConfigOutWord (devices[i].bus,
  462.   devices[i].device,
  463.   devices[i].func,
  464.   PCI_CFG_COMMAND, 
  465.   INITIAL_PCI_CMD);
  466.     }
  467. }
  468. /* 
  469.  * PCI controller config registers are accessed through these functions
  470.  * i.e. these allow us to set up our own BARs etc.
  471.  */
  472. LOCAL void 
  473. crpRead (UINT32 offset, 
  474.  UINT32* data)
  475. {
  476.     UINT32 key;
  477.     key = intLock ();
  478.     REG_WRITE (PCI_CSR_BASE, PCI_CRP_OFFSET, offset);
  479.     REG_READ (PCI_CSR_BASE, PCI_CRP_RDATA_OFFSET, *data);
  480.     intUnlock (key);
  481. }
  482. LOCAL void 
  483. crpWrite (UINT32 offset, 
  484.   UINT32 data)
  485. {
  486.     UINT32 key;
  487.     key = intLock ();
  488.     /*The CRP address register bit 16 indicates that we want to do a write */
  489.     REG_WRITE (PCI_CSR_BASE, PCI_CRP_OFFSET, PCI_CRP_WRITE | offset);
  490.     REG_WRITE (PCI_CSR_BASE, PCI_CRP_WDATA_OFFSET, data);
  491.     intUnlock (key);
  492. }
  493. /******************************************************************************
  494. *
  495. * sysPciInit - initialise PCI bridge controller
  496. *
  497. * This function initialises the PCI controller block.
  498. *
  499. * RETURNS: N/A
  500. */
  501. void 
  502. sysPciInit (void)
  503. {
  504.     volatile UINT32 i, j; 
  505.     UINT32 regval; 
  506.     /* Check to see if we are host, if we are PCI host we
  507.        assert reset signals and provide the clock
  508.     */
  509.     if (sysPciIsHost ())
  510.     {
  511. sysPciGpioClockDisable();
  512. /*Configure reset and clock gpio signals*/
  513. sysPciGpioConfig (); 
  514. /* assert PCI reset */    
  515. sysPciResetAssert ();
  516. /* PCI spec says that we must assert reset for a minimum of 1 ms
  517.  * we don't have any usable timers at this stage in the
  518.  * system boot, so we busy loop for 
  519.  * approximately twice the required minimum delay time.
  520.  */
  521. for (i = 0; i < PCI_MIN_RESET_ASSERT_USEC*USEC_LOOP_COUNT; i++)
  522. {
  523.     j = i + 1;
  524. }
  525. #ifdef IXP425_PCI_GPIO_CLOCK_ON     
  526. /*configure PCI clock output from GPIO pin*/
  527. sysPciGpioClockConfig (PciClock33);
  528. /*enable the PCI clock output from GPIO pin*/
  529. sysPciGpioClockEnable ();
  530. #endif     
  531. /* Disable all PCI Controller interrupts*/
  532. REG_WRITE (PCI_CSR_BASE, PCI_INTEN_OFFSET, 0);          
  533. /*Wait at least 100us to satisfy "minimum reset assertion time from clock stable"*/
  534. for (i = 0; i < PCI_SETTLE_USEC*USEC_LOOP_COUNT; i++)
  535. {
  536.     j = i + 1;
  537. }
  538. /* Negate PCI reset, i.e. take the bus out of reset*/
  539. sysPciResetDeassert ();
  540. /* wait a few usecs to settle the device and PCI bus */
  541. for (i = 0; i < PCI_SETTLE_USEC*USEC_LOOP_COUNT ; i++)
  542. {
  543.     j = i + 1;
  544. }         
  545. /*Initialise interrupt callback list*/
  546. for (i = 0; i < PCI_IRQ_LINES; i++)
  547. {
  548.     dllInit (&pciIntList[i]);
  549. }
  550. /*Initialise callback list*/
  551. dllInit (&pciCallbackList);
  552. /*setup BARs in controller */
  553. crpWrite (PCI_CFG_BASE_ADDRESS_0, IXP425_PCI_BAR_0_DEFAULT);
  554. crpWrite (PCI_CFG_BASE_ADDRESS_1, IXP425_PCI_BAR_1_DEFAULT);
  555. crpWrite (PCI_CFG_BASE_ADDRESS_2, IXP425_PCI_BAR_2_DEFAULT);
  556. crpWrite (PCI_CFG_BASE_ADDRESS_3, IXP425_PCI_BAR_3_DEFAULT);
  557. crpWrite (PCI_CFG_BASE_ADDRESS_4, IXP425_PCI_BAR_4_DEFAULT);
  558. crpWrite (PCI_CFG_BASE_ADDRESS_5, IXP425_PCI_BAR_5_DEFAULT);
  559. /*Setup PCI-AHB and AHB-PCI address mappings*/
  560. REG_WRITE (PCI_CSR_BASE, PCI_AHBMEMBASE_OFFSET, 
  561.    IXP425_PCI_AHBMEMBASE_DEFAULT);
  562. REG_WRITE (PCI_CSR_BASE,PCI_AHBIOBASE_OFFSET, 
  563.    IXP425_PCI_AHBIOBASE_DEFAULT);
  564. REG_WRITE (PCI_CSR_BASE,PCI_PCIMEMBASE_OFFSET, 
  565.    IXP425_PCI_PCIMEMBASE_DEFAULT);
  566.     } 
  567.     else 
  568.     {
  569. /*if we are not the PCI bus host, we must not assert reset
  570.   or drive the clock, and the GPIO's used for INTA#..INTD#
  571.   when in host mode must not be claimed/configured as they
  572.   may be used by another driver.*/
  573.    
  574. /* We must allow ourselves to be configured by a bus
  575.  * master out on the PCI bus, to do this we must set
  576.  * BAR4 to permit access to the CSRs and set the
  577.  * Subsystem ID register      
  578.  * Set CSR BAR4: i.e. set base address of CSRs from PCI,
  579.  * CSR Base Address Mask Register will setup 128 byte window.
  580.  */
  581. crpWrite (PCI_CFG_BASE_ADDRESS_4, IXP425_PCI_BAR_4_DEFAULT);
  582.     }
  583.     /*Clear error bits in ISR, write 1 to clear*/
  584.     REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET , PCI_ISR_PSE | PCI_ISR_PFE 
  585. | PCI_ISR_PPE |  PCI_ISR_AHBE );
  586.     
  587.     /*reset the AHB doorbell*/
  588.     sysAhbDoorbellReset ();
  589.     
  590.     /*Enable interrupts in the controller*/
  591.     REG_WRITE (PCI_CSR_BASE, PCI_INTEN_OFFSET,  
  592.        PCI_INTEN_PSE | PCI_INTEN_PFE 
  593.        | PCI_INTEN_PPE | PCI_INTEN_AHBE
  594.        | PCI_INTEN_ADB | PCI_INTEN_PDB);
  595.     /*set the subsystem vendor and device ids*/
  596.     crpWrite (PCI_CFG_SUB_VENDOR_ID, IXP425_PCI_SUB_VENDOR_SYSTEM);
  597.     /*
  598.      * Set Initialise Complete in PCI Control Register: allow IXP425 to
  599.      * respond to PCI configuration cycles.
  600.      */    
  601.     REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
  602.     /*This line sets up byte lane swapping between little-endian PCI
  603.       and the big-endian AHB bus, specifies that initialisation is
  604.       complete and therefore enables the controller to respond to
  605.       transactions and also specifies that the AHB bus is operating in
  606.       big endian mode.*/
  607. #ifdef IXP425_PCI_ENABLE_BYTE_ROUTING
  608.     regval |= PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
  609. #else
  610.     regval |= PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS;
  611. #endif
  612.     REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
  613.     /*Set up PCI Bus interface in our PCI configuration registers
  614.      * i.e. not the PCI controller configuration registers*/
  615.     /*enable memory access and bus mastering*/
  616.     crpWrite (PCI_CFG_COMMAND, PCI_CFG_CMD_MAE | PCI_CFG_CMD_BME);
  617.     pciLibInitStatus=OK;
  618. #ifdef INCLUDE_PCI_DMA
  619.     pciDmaInit();
  620. #endif
  621.     return;
  622. }
  623. /******************************************************************************
  624. *
  625. * sysPciAssignAddrs - Scan PCI bus and automatically assign PCI addresses
  626. *
  627. * This function scans the PCI bus to see what other devices are there. It then
  628. * sorts the BARs that it finds and assigns them addresses. It enables PCI transactions
  629. * as defined by INITIAL_PCI_CMD.
  630. *
  631. * This function only has an effect if this processor is the PCI central function.
  632. *
  633. * RETURNS: N/A
  634. */
  635. void
  636. sysPciAssignAddrs (void)
  637. {
  638.     UINT32 bus, dev, func;
  639.     UINT16 data16;
  640.     UINT32 data32;   
  641.     UINT8  intPin;
  642.     if (!sysPciIsHost ())
  643.     {
  644.         return;
  645.     }
  646.     /* Assign first device to ourselves */
  647.     devices[0].bus    = 0;
  648.     devices[0].device = 0;
  649.     devices[0].func   = 0;
  650.     crpRead (PCI_CFG_VENDOR_ID, &data32);
  651.     devices[0].vendor_id = data32 & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK;
  652.     devices[0].device_id = data32 >> 16;
  653.     devices[0].error     = FALSE;
  654.     devices[0].bar[NO_BAR].size = 0;           /*dummy - required*/
  655.     nDevices = 1;
  656.     nMBars  = 0;
  657.     nIOBars = 0;
  658.     for (bus = 0; bus < IXP425_PCI_MAX_BUS; bus++ ) 
  659.     {
  660.         for (dev = 0; dev < IXP425_PCI_MAX_DEV; dev++ ) 
  661. {
  662.     for(func = 0; func < IXP425_PCI_MAX_FUNC; func++)
  663.     {
  664. /*Check whether a device is present*/
  665. if (pciDeviceExists (bus, dev, func)!=TRUE)
  666. {
  667.     /*Clear error bits in ISR, write 1 to clear*/
  668.     REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET , PCI_ISR_PSE 
  669.        | PCI_ISR_PFE | PCI_ISR_PPE |  PCI_ISR_AHBE );
  670.     continue;
  671. }
  672. /*A device is present, add an entry to the array*/
  673. devices[nDevices].bus    = bus;
  674. devices[nDevices].device = dev;
  675. devices[nDevices].func   = func;
  676. pciConfigInWord (bus, dev, func, PCI_CFG_VENDOR_ID, &data16);
  677. devices[nDevices].vendor_id = data16;
  678. pciConfigInWord (bus, dev, func, PCI_CFG_DEVICE_ID, &data16);
  679. devices[nDevices].device_id = data16;
  680. /*The device is functioning correctly, set error to FALSE*/
  681. devices[nDevices].error = FALSE;
  682. /*Figure out what BARs are on this device*/
  683. sysPciBarInfoGet (nDevices, bus, dev, func);
  684. /*Figure out what INTX# line the card uses*/
  685. pciConfigInByte(bus, dev, func, PCI_CFG_DEV_INT_PIN, &intPin);
  686. /*assign the appropriate irq line*/
  687. if (intPin > PCI_IRQ_LINES)
  688. {
  689.     devices[nDevices].error = TRUE;
  690. else if (intPin != 0)
  691. {
  692.     /*This device uses an interrupt line*/
  693.     devices[nDevices].irq = ixp425PciIntTranslate[dev][intPin-1];
  694. }
  695. nDevices++;
  696.     } /* end for func*/
  697. } /* end for dev */
  698.     } /* end for bus */
  699.     
  700.     /* Sort BARs and set
  701.        devices[].bar[].address variables to appropriate values.*/
  702.     sortBars (memBars, nMBars);
  703.     calcBars (memBars, nMBars, IXP425_PCI_BAR_MEM_BASE);
  704.     sortBars (ioBars, nIOBars);
  705.     calcBars (ioBars, nIOBars, IXP425_PCI_BAR_IO_BASE); 
  706.     /*write the BARs to the PCI devices*/
  707.     sysPciDeviceBarsWrite();
  708.     /*Clear error bits in ISR, write 1 to clear*/
  709.     REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET , PCI_ISR_PSE 
  710.        | PCI_ISR_PFE | PCI_ISR_PPE |  PCI_ISR_AHBE );
  711. }
  712. #ifndef IXP425_PCI_SIMPLE_MAPPING
  713. /******************************************************************************
  714. *
  715. * sysPciMappingAdd - configure the AHB membase register 
  716. *
  717. * This function configures the next available slot in the PCI controller's AHBMEMBASE
  718. * to permit  a device on the PCI bus to access the specified SDRAM address. 
  719. * This function is only available when IXP425_PCI_SIMPLE_MAPPING
  720. * is not defined, as it is the mechanism for creating dynamic (non-simple) mappings.
  721. *
  722. * RETURNS: OK or ERROR if all mappings have already been used
  723. */
  724. STATUS
  725. sysPciMappingAdd(UINT32 sdramAddress, 
  726.  UINT32 size)
  727. {
  728.     UINT32 ahbMemBaseReg;
  729.     UINT32 topEight;
  730.     UINT32 i;
  731.     if(size > MAPPING_SIZE)
  732.     {
  733. return ERROR;
  734.     }
  735.     REG_READ (PCI_CSR_BASE, PCI_AHBMEMBASE_OFFSET, ahbMemBaseReg);
  736.     /* check whether a mapping already exists that covers the address
  737.      * and size:
  738.      * foreach mapping
  739.      * if  (base <= address) and (base+Mapping size >= address+size) then this is the mapping 
  740.      *  that covers the address
  741.      */
  742.     for(i=0;i<nextPccMap;i++)
  743.     {
  744. topEight = (ahbMemBaseReg << (i*8)) &  IXP425_PCI_TOP_BYTE_OF_LONG_MASK;
  745. if ((topEight <= sdramAddress) && 
  746.     ((topEight + MAPPING_SIZE) >= (sdramAddress + size)))
  747. {
  748.     break;
  749. }
  750.     }
  751.     if(i<nextPccMap)
  752.     {
  753. /*mapping exists, no need to do anything*/
  754. return OK;
  755.     }
  756.     
  757.     /*create new mapping*/
  758.     if(nextPccMap > MAX_PCC_MAP)
  759.     {
  760. return ERROR;
  761.     }
  762.     
  763.     /*get the top 8 bits of the sdram address*/
  764.     sdramAddress = sdramAddress &  IXP425_PCI_TOP_BYTE_OF_LONG_MASK;
  765.     /*blank the byte we are about to write*/
  766.     ahbMemBaseReg = ahbMemBaseReg & (~ ( IXP425_PCI_TOP_BYTE_OF_LONG_MASK >> (nextPccMap*8)));
  767.     
  768.     ahbMemBaseReg = ahbMemBaseReg | (sdramAddress >> (nextPccMap*8));
  769.     REG_WRITE (PCI_CSR_BASE, PCI_AHBMEMBASE_OFFSET, ahbMemBaseReg);
  770.     nextPccMap++;
  771.     return OK;
  772. }
  773. #endif
  774. /******************************************************************************
  775. *
  776. * sysPhysToPci - translate a physical address to a PCI address
  777. *
  778. * This function converts a physical address to a PCI address.
  779. * It tells a PCI device what PCI address it needs to read/write
  780. * in order to access the physical address specified
  781. *
  782. *
  783. * RETURNS: the PCI adddress
  784. */
  785. void * 
  786. sysPhysToPci (void *physAddr)
  787. {
  788.     UINT32 topEight;
  789.     UINT32 ahbBase=0;
  790.     UINT32 ahbMemBaseReg;
  791.     void *pciAddr;
  792.     UINT32 pciBarValue=0;
  793.     UINT32 i;
  794.     /*figure out which of the regions defined by AHBMEMBASE covers physAddr*/
  795.     REG_READ (PCI_CSR_BASE, PCI_AHBMEMBASE_OFFSET, ahbMemBaseReg);
  796.  
  797.     /*
  798.      * foreach mapping
  799.      * if  base <= address and base+Mapping size => address+size then this mapping 
  800.      * covers the address
  801.      */
  802.     for(i=0;i<nextPccMap;i++)
  803.     {
  804. topEight = (ahbMemBaseReg << (i*8)) &  IXP425_PCI_TOP_BYTE_OF_LONG_MASK;
  805. if ((topEight <= (UINT32)physAddr) && 
  806.     ((topEight + MAPPING_SIZE) >= (UINT32)physAddr))
  807. {
  808.     ahbBase = topEight;
  809.     break;
  810. }
  811.     }
  812.     
  813.     if (i == nextPccMap)
  814.     {
  815. /*no AHB base covering the specified physical address was found*/
  816. return NULL;
  817.     }
  818.     /*the PCC bar corresponding to this AHB membase is specified by minindex*/
  819.     crpRead (PCI_CFG_BASE_ADDRESS_0 + 4*i, &pciBarValue);
  820.     /*we're only interested in the top eight bits of the BAR - these
  821.       specify the address, the rest is status info*/
  822.     pciBarValue = pciBarValue &  IXP425_PCI_TOP_BYTE_OF_LONG_MASK;
  823.     
  824.     /*therefore the PCI address needed to access this AHB address is
  825.       the PCI BAR plus (the physical addres minus the AHB base)*/
  826.     pciAddr = (void*) (pciBarValue + ((UINT32)physAddr - ahbBase));
  827.     return pciAddr;
  828. }
  829. /******************************************************************************
  830. *
  831. * sysPciToPhys - translate a PCI address to a physical address
  832. *
  833. * This function tells the caller what Physical address they need to generate
  834. * on the AHB bus in order to access the specified PCI address on the PCI bus
  835. * There is the facility for more complex mappings of PCI space using the
  836. * pci_pcimembasereg, but we do not use them as we can access 128MB of the PCI
  837. * address space which is sufficient, so this function assumes that the
  838. * pcimembasereg is set to zero. 
  839. *
  840. * RETURNS: the physical adddress
  841. */
  842. void * 
  843. sysPciToPhys (void *pciAddr)
  844. {
  845.     UINT32 pciMemBaseReg;
  846.     REG_READ (PCI_CSR_BASE, PCI_PCIMEMBASE_OFFSET, pciMemBaseReg);
  847.     if( pciMemBaseReg != 0)
  848.     {
  849. return NULL;
  850.     }
  851.     return (void*)((UINT32)pciAddr + CPU_PCI_MEM_ADRS);    
  852. }
  853.