ops-tx4927.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Copyright 2001 MontaVista Software Inc.
  3. * Author: MontaVista Software, Inc.
  4. * ahennessy@mvista.com
  5. *
  6. * Copyright (C) 2000-2001 Toshiba Corporation
  7. * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
  8. *
  9. * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
  10. *
  11. * Define the pci_ops for the Toshiba rbtx4927
  12. *
  13. * Much of the code is derived from the original DDB5074 port by
  14. * Geert Uytterhoeven <geert@sonycom.com>
  15. *
  16. * Copyright 2004 MontaVista Software Inc.
  17. * Author: Manish Lachwani (mlachwani@mvista.com)
  18. *
  19. * This program is free software; you can redistribute it and/or modify it
  20. * under the terms of the GNU General Public License as published by the
  21. * Free Software Foundation; either version 2 of the License, or (at your
  22. * option) any later version.
  23. *
  24. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  25. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  26. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  27. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  28. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  29. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  30. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  33. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. * You should have received a copy of the GNU General Public License along
  36. * with this program; if not, write to the Free Software Foundation, Inc.,
  37. * 675 Mass Ave, Cambridge, MA 02139, USA.
  38. */
  39. #include <linux/types.h>
  40. #include <linux/pci.h>
  41. #include <linux/kernel.h>
  42. #include <linux/init.h>
  43. #include <asm/addrspace.h>
  44. #include <asm/byteorder.h>
  45. #include <asm/tx4927/tx4927_pci.h>
  46. /* initialize in setup */
  47. struct resource pci_io_resource = {
  48. .name = "TX4927 PCI IO SPACE",
  49. .start = 0x1000,
  50. .end = (0x1000 + (TX4927_PCIIO_SIZE)) - 1,
  51. .flags = IORESOURCE_IO
  52. };
  53. /* initialize in setup */
  54. struct resource pci_mem_resource = {
  55. .name = "TX4927 PCI MEM SPACE",
  56. .start = TX4927_PCIMEM,
  57. .end = TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1,
  58. .flags = IORESOURCE_MEM
  59. };
  60. static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
  61. {
  62. if (bus > 0) {
  63. /* Type 1 configuration */
  64. tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
  65. ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
  66. } else {
  67. if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0))
  68. return -1;
  69. /* Type 0 configuration */
  70. tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
  71. ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
  72. }
  73. /* clear M_ABORT and Disable M_ABORT Int. */
  74. tx4927_pcicptr->pcistatus =
  75. (tx4927_pcicptr->pcistatus & 0x0000ffff) |
  76. (PCI_STATUS_REC_MASTER_ABORT << 16);
  77. tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
  78. return 0;
  79. }
  80. static int check_abort(int flags)
  81. {
  82. int code = PCIBIOS_SUCCESSFUL;
  83. if (tx4927_pcicptr->
  84. pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
  85. tx4927_pcicptr->pcistatus =
  86. (tx4927_pcicptr->
  87. pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
  88. << 16);
  89. tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
  90. code = PCIBIOS_DEVICE_NOT_FOUND;
  91. }
  92. return code;
  93. }
  94. static int tx4927_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, int where,
  95. int size, u32 * val)
  96. {
  97. int flags, retval, dev, busno, func;
  98. busno = bus->number;
  99. dev = PCI_SLOT(devfn);
  100. func = PCI_FUNC(devfn);
  101. /* check if the bus is top-level */
  102. if (bus->parent != NULL) {
  103. busno = bus->number;
  104. } else {
  105. busno = 0;
  106. }
  107. if (mkaddr(busno, devfn, where, &flags))
  108. return -1;
  109. switch (size) {
  110. case 1:
  111. *val = *(volatile u8 *) ((ulong) & tx4927_pcicptr->
  112. g2pcfgdata |
  113. #ifdef __LITTLE_ENDIAN
  114. (where & 3));
  115. #else
  116. ((where & 0x3) ^ 0x3));
  117. #endif
  118. break;
  119. case 2:
  120. *val = *(volatile u16 *) ((ulong) & tx4927_pcicptr->
  121. g2pcfgdata |
  122. #ifdef __LITTLE_ENDIAN
  123. (where & 3));
  124. #else
  125. ((where & 0x3) ^ 0x2));
  126. #endif
  127. break;
  128. case 4:
  129. *val = tx4927_pcicptr->g2pcfgdata;
  130. break;
  131. }
  132. retval = check_abort(flags);
  133. if (retval == PCIBIOS_DEVICE_NOT_FOUND)
  134. *val = 0xffffffff;
  135. return retval;
  136. }
  137. static int tx4927_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
  138. int size, u32 val)
  139. {
  140. int flags, dev, busno, func;
  141. busno = bus->number;
  142. dev = PCI_SLOT(devfn);
  143. func = PCI_FUNC(devfn);
  144. /* check if the bus is top-level */
  145. if (bus->parent != NULL) {
  146. busno = bus->number;
  147. } else {
  148. busno = 0;
  149. }
  150. if (mkaddr(busno, devfn, where, &flags))
  151. return -1;
  152. switch (size) {
  153. case 1:
  154. *(volatile u8 *) ((ulong) & tx4927_pcicptr->
  155. g2pcfgdata |
  156. #ifdef __LITTLE_ENDIAN
  157. (where & 3)) = val;
  158. #else
  159. ((where & 0x3) ^ 0x3)) = val;
  160. #endif
  161. break;
  162. case 2:
  163. *(volatile u16 *) ((ulong) & tx4927_pcicptr->
  164. g2pcfgdata |
  165. #ifdef __LITTLE_ENDIAN
  166. (where & 3)) = val;
  167. #else
  168. ((where & 0x3) ^ 0x2)) = val;
  169. #endif
  170. break;
  171. case 4:
  172. tx4927_pcicptr->g2pcfgdata = val;
  173. break;
  174. }
  175. return check_abort(flags);
  176. }
  177. struct pci_ops tx4927_pci_ops = {
  178. tx4927_pcibios_read_config,
  179. tx4927_pcibios_write_config
  180. };
  181. /*
  182. * h/w only supports devices 0x00 to 0x14
  183. */
  184. struct pci_controller tx4927_controller = {
  185. .pci_ops = &tx4927_pci_ops,
  186. .io_resource = &pci_io_resource,
  187. .mem_resource = &pci_mem_resource,
  188. };