pci_ops.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:7k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  * BRIEF MODULE DESCRIPTION
  4.  * Galileo EV96100 board specific pci support.
  5.  *
  6.  * Copyright 2000 MontaVista Software Inc.
  7.  * Author: MontaVista Software, Inc.
  8.  *          ppopov@mvista.com or source@mvista.com
  9.  *
  10.  * This file was derived from Carsten Langgaard's
  11.  * arch/mips/mips-boards/generic/pci.c
  12.  *
  13.  * Carsten Langgaard, carstenl@mips.com
  14.  * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
  15.  *
  16.  *  This program is free software; you can redistribute  it and/or modify it
  17.  *  under  the terms of  the GNU General  Public License as published by the
  18.  *  Free Software Foundation;  either version 2 of the  License, or (at your
  19.  *  option) any later version.
  20.  *
  21.  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
  22.  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
  23.  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  24.  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
  25.  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  26.  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
  27.  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28.  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  29.  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  30.  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31.  *
  32.  *  You should have received a copy of the  GNU General Public License along
  33.  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  34.  *  675 Mass Ave, Cambridge, MA 02139, USA.
  35.  */
  36. #include <linux/config.h>
  37. #ifdef CONFIG_PCI
  38. #include <linux/types.h>
  39. #include <linux/pci.h>
  40. #include <linux/kernel.h>
  41. #include <linux/init.h>
  42. #include <asm/delay.h>
  43. #include <asm//gt64120.h>
  44. #include <asm/galileo-boards/ev96100.h>
  45. #include <asm/pci_channel.h>
  46. #define PCI_ACCESS_READ  0
  47. #define PCI_ACCESS_WRITE 1
  48. #undef DEBUG
  49. #ifdef DEBUG
  50. #define DBG(x...) printk(x)
  51. #else
  52. #define DBG(x...)
  53. #endif
  54. #define GT_PCI_MEM_BASE    0x12000000
  55. #define GT_PCI_MEM_SIZE    0x02000000
  56. #define GT_PCI_IO_BASE     0x10000000
  57. #define GT_PCI_IO_SIZE     0x02000000
  58. static struct resource pci_io_resource = {
  59. "io pci IO space",
  60. 0x10000000,
  61. 0x10000000 + 0x02000000,
  62. IORESOURCE_IO};
  63. static struct resource pci_mem_resource = {
  64. "ext pci memory space",
  65. 0x12000000,
  66. 0x12000000 + 0x02000000,
  67. IORESOURCE_MEM};
  68. extern struct pci_ops gt96100_pci_ops;
  69. struct pci_channel mips_pci_channels[] = {
  70. { &gt96100_pci_ops, &pci_io_resource, &pci_mem_resource, 1, 0xff },
  71. { NULL, NULL, NULL, NULL, NULL}
  72. };
  73. int
  74. static gt96100_config_access(unsigned char access_type, struct pci_dev *dev,
  75.                            unsigned char where, u32 *data)
  76. {
  77. unsigned char bus = dev->bus->number;
  78. unsigned char dev_fn = dev->devfn;
  79.         u32 intr;
  80. if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) {
  81.             return -1; /* Because of a bug in the galileo (for slot 31). */
  82.         }
  83. /* Clear cause register bits */
  84. GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
  85.                              GT_INTRCAUSE_TARABORT0_BIT));
  86. /* Setup address */
  87. GT_WRITE(GT_PCI0_CFGADDR_OFS,
  88.  (bus         << GT_PCI0_CFGADDR_BUSNUM_SHF)   |
  89.  (dev_fn      << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
  90.  ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF)   |
  91.  GT_PCI0_CFGADDR_CONFIGEN_BIT);
  92. udelay(2);
  93. if (access_type == PCI_ACCESS_WRITE) {
  94. if (dev_fn != 0) {
  95. *data = le32_to_cpu(*data);
  96. }
  97. GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
  98. }
  99.         else {
  100. GT_READ(GT_PCI0_CFGDATA_OFS, *data);
  101. if (dev_fn != 0) {
  102. *data = le32_to_cpu(*data);
  103. }
  104. }
  105. udelay(2);
  106. /* Check for master or target abort */
  107. GT_READ(GT_INTRCAUSE_OFS, intr);
  108. if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT))
  109. {
  110. //printk("config access error:  %x:%xn", dev_fn,where);
  111.         /* Error occured */
  112.         /* Clear bits */
  113.         GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
  114.       GT_INTRCAUSE_TARABORT0_BIT) );
  115. if (access_type == PCI_ACCESS_READ) {
  116. *data = 0xffffffff;
  117. }
  118. return -1;
  119. }
  120. return 0;
  121. }
  122. /*
  123.  * We can't address 8 and 16 bit words directly.  Instead we have to
  124.  * read/write a 32bit word and mask/modify the data we actually want.
  125.  */
  126. static int
  127. read_config_byte (struct pci_dev *dev, int where, u8 *val)
  128. {
  129. u32 data = 0;
  130. if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) {
  131. *val = 0xff;
  132. return -1;
  133. }
  134. *val = (data >> ((where & 3) << 3)) & 0xff;
  135.         DBG("cfg read byte: bus %d dev_fn %x where %x: val %xn",
  136.                 dev->bus->number, dev->devfn, where, *val);
  137. return PCIBIOS_SUCCESSFUL;
  138. }
  139. static int
  140. read_config_word (struct pci_dev *dev, int where, u16 *val)
  141. {
  142. u32 data = 0;
  143. if (where & 1)
  144. return PCIBIOS_BAD_REGISTER_NUMBER;
  145. if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) {
  146. *val = 0xffff;
  147. return -1;
  148. }
  149. *val = (data >> ((where & 3) << 3)) & 0xffff;
  150.         DBG("cfg read word: bus %d dev_fn %x where %x: val %xn",
  151.                 dev->bus->number, dev->devfn, where, *val);
  152. return PCIBIOS_SUCCESSFUL;
  153. }
  154. static int
  155. read_config_dword (struct pci_dev *dev, int where, u32 *val)
  156. {
  157. u32 data = 0;
  158. if (where & 3)
  159. return PCIBIOS_BAD_REGISTER_NUMBER;
  160. if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) {
  161. *val = 0xffffffff;
  162. return -1;
  163. }
  164. *val = data;
  165.         DBG("cfg read dword: bus %d dev_fn %x where %x: val %xn",
  166.                 dev->bus->number, dev->devfn, where, *val);
  167. return PCIBIOS_SUCCESSFUL;
  168. }
  169. static int
  170. write_config_byte (struct pci_dev *dev, int where, u8 val)
  171. {
  172. u32 data = 0;
  173. if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data))
  174. return -1;
  175. data = (data & ~(0xff << ((where & 3) << 3))) |
  176.        (val << ((where & 3) << 3));
  177.         DBG("cfg write byte: bus %d dev_fn %x where %x: val %xn",
  178.                 dev->bus->number, dev->devfn, where, val);
  179. if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data))
  180. return -1;
  181. return PCIBIOS_SUCCESSFUL;
  182. }
  183. static int
  184. write_config_word (struct pci_dev *dev, int where, u16 val)
  185. {
  186.         u32 data = 0;
  187. if (where & 1)
  188. return PCIBIOS_BAD_REGISTER_NUMBER;
  189.         if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data))
  190.        return -1;
  191. data = (data & ~(0xffff << ((where & 3) << 3))) |
  192.        (val << ((where & 3) << 3));
  193.         DBG("cfg write word: bus %d dev_fn %x where %x: val %xn",
  194.                 dev->bus->number, dev->devfn, where, val);
  195. if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data))
  196.        return -1;
  197. return PCIBIOS_SUCCESSFUL;
  198. }
  199. static int
  200. write_config_dword(struct pci_dev *dev, int where, u32 val)
  201. {
  202. if (where & 3)
  203. return PCIBIOS_BAD_REGISTER_NUMBER;
  204. if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val))
  205.        return -1;
  206.         DBG("cfg write dword: bus %d dev_fn %x where %x: val %xn",
  207.                 dev->bus->number, dev->devfn, where, val);
  208. return PCIBIOS_SUCCESSFUL;
  209. }
  210. struct pci_ops gt96100_pci_ops = {
  211. read_config_byte,
  212.         read_config_word,
  213. read_config_dword,
  214. write_config_byte,
  215. write_config_word,
  216. write_config_dword
  217. };
  218. #endif /* CONFIG_PCI */