pci.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * BRIEF MODULE DESCRIPTION
  3. * Galileo Evaluation Boards PCI support.
  4. *
  5. * The general-purpose functions to read/write and configure the GT64120A's
  6. * PCI registers (function names start with pci0 or pci1) are either direct
  7. * copies of functions written by Galileo Technology, or are modifications
  8. * of their functions to work with Linux 2.4 vs Linux 2.2. These functions
  9. * are Copyright - Galileo Technology.
  10. *
  11. * Other functions are derived from other MIPS PCI implementations, or were
  12. * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc.
  13. * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
  14. *
  15. * This program is free software; you can redistribute it and/or modify it
  16. * under the terms of the GNU General Public License as published by the
  17. * Free Software Foundation; either version 2 of the License, or (at your
  18. * option) any later version.
  19. *
  20. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  21. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  22. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  23. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  26. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  29. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. * You should have received a copy of the GNU General Public License along
  32. * with this program; if not, write to the Free Software Foundation, Inc.,
  33. * 675 Mass Ave, Cambridge, MA 02139, USA.
  34. */
  35. #include <linux/init.h>
  36. #include <linux/types.h>
  37. #include <linux/pci.h>
  38. #include <linux/kernel.h>
  39. #include <asm/gt64120.h>
  40. #define SELF 0
  41. /*
  42. * pciXReadConfigReg - Read from a PCI configuration register
  43. * - Make sure the GT is configured as a master before
  44. * reading from another device on the PCI.
  45. * - The function takes care of Big/Little endian conversion.
  46. * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
  47. * spec)
  48. * pciDevNum: The device number needs to be addressed.
  49. * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
  50. * cause register to make sure the data is valid
  51. *
  52. * Configuration Address 0xCF8:
  53. *
  54. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  55. * |congif|Reserved| Bus |Device|Function|Register|00|
  56. * |Enable| |Number|Number| Number | Number | | <=field Name
  57. *
  58. */
  59. static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device)
  60. {
  61. unsigned int DataForRegCf8;
  62. unsigned int data;
  63. DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
  64. (PCI_FUNC(device->devfn) << 8) |
  65. (offset & ~0x3)) | 0x80000000;
  66. GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
  67. /*
  68. * The casual observer might wonder why the READ is duplicated here,
  69. * rather than immediately following the WRITE, and just have the swap
  70. * in the "if". That's because there is a latency problem with trying
  71. * to read immediately after setting up the address register. The "if"
  72. * check gives enough time for the address to stabilize, so the READ
  73. * can work.
  74. */
  75. if (PCI_SLOT(device->devfn) == SELF) /* This board */
  76. return GT_READ(GT_PCI0_CFGDATA_OFS);
  77. else /* PCI is little endian so swap the Data. */
  78. return __GT_READ(GT_PCI0_CFGDATA_OFS);
  79. }
  80. /*
  81. * pciXWriteConfigReg - Write to a PCI configuration register
  82. * - Make sure the GT is configured as a master before
  83. * writingto another device on the PCI.
  84. * - The function takes care of Big/Little endian conversion.
  85. * Inputs: unsigned int regOffset: The register offset as it apears in the
  86. * GT spec
  87. * (or any other PCI device spec)
  88. * pciDevNum: The device number needs to be addressed.
  89. *
  90. * Configuration Address 0xCF8:
  91. *
  92. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  93. * |congif|Reserved| Bus |Device|Function|Register|00|
  94. * |Enable| |Number|Number| Number | Number | | <=field Name
  95. *
  96. */
  97. static void pci0WriteConfigReg(unsigned int offset,
  98. struct pci_dev *device, unsigned int data)
  99. {
  100. unsigned int DataForRegCf8;
  101. DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
  102. (PCI_FUNC(device->devfn) << 8) |
  103. (offset & ~0x3)) | 0x80000000;
  104. GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
  105. if (PCI_SLOT(device->devfn) == SELF) /* This board */
  106. GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
  107. else /* configuration Transaction over the pci. */
  108. __GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
  109. }
  110. extern struct pci_ops gt64120_pci_ops;
  111. void __init pcibios_init(void)
  112. {
  113. u32 tmp;
  114. struct pci_dev controller;
  115. controller.devfn = SELF;
  116. tmp = GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */
  117. tmp = GT_READ(GT_PCI0_BARE_OFS);
  118. /*
  119. * You have to enable bus mastering to configure any other
  120. * card on the bus.
  121. */
  122. tmp = pci0ReadConfigReg(PCI_COMMAND, &controller);
  123. tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
  124. pci0WriteConfigReg(PCI_COMMAND, &controller, tmp);
  125. /*
  126. * Reset PCI I/O and PCI MEM values to ones supported by EVM.
  127. */
  128. ioport_resource.start = GT_PCI_IO_BASE;
  129. ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
  130. iomem_resource.start = GT_PCI_MEM_BASE;
  131. iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1;
  132. pci_scan_bus(0, &gt64120_pci_ops, NULL);
  133. }