ops-tx3927.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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 JMR3927.
  12. *
  13. * Much of the code is derived from the original DDB5074 port by
  14. * Geert Uytterhoeven <geert@sonycom.com>
  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/types.h>
  37. #include <linux/pci.h>
  38. #include <linux/kernel.h>
  39. #include <linux/init.h>
  40. #include <asm/addrspace.h>
  41. #include <asm/jmr3927/jmr3927.h>
  42. #include <asm/debug.h>
  43. static inline int mkaddr(unsigned char bus, unsigned char dev_fn,
  44. unsigned char where)
  45. {
  46. if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
  47. return PCIBIOS_DEVICE_NOT_FOUND;
  48. tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) |
  49. ((dev_fn & 0xff) << 0x08) |
  50. (where & 0xfc);
  51. /* clear M_ABORT and Disable M_ABORT Int. */
  52. tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
  53. tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;
  54. return PCIBIOS_SUCCESSFUL;
  55. }
  56. static inline int check_abort(void)
  57. {
  58. if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
  59. tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
  60. tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
  61. return PCIBIOS_DEVICE_NOT_FOUND;
  62. return PCIBIOS_SUCCESSFUL;
  63. }
  64. static int jmr3927_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  65. int where, int size, u32 * val)
  66. {
  67. int ret, busno;
  68. /* check if the bus is top-level */
  69. if (bus->parent != NULL)
  70. busno = bus->number;
  71. ret = mkaddr(busno, devfn, where);
  72. if (ret)
  73. return ret;
  74. switch (size) {
  75. case 1:
  76. *val = *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3));
  77. break;
  78. case 2:
  79. *val = le16_to_cpu(*(volatile u16 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)));
  80. break;
  81. case 4:
  82. *val = le32_to_cpu(tx3927_pcicptr->icd);
  83. break;
  84. }
  85. return check_abort();
  86. }
  87. static int jmr3927_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  88. int where, int size, u32 val)
  89. {
  90. int ret, busno;
  91. /* check if the bus is top-level */
  92. if (bus->parent != NULL)
  93. bus = bus->number;
  94. else
  95. bus = 0;
  96. ret = mkaddr(busno, devfn, where);
  97. if (ret)
  98. return ret;
  99. switch (size) {
  100. case 1:
  101. *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)) = val;
  102. break;
  103. case 2:
  104. *(volatile u16 *) (unsigned longulong) & tx3927_pcicptr->icd | (where & 2)) =
  105. cpu_to_le16(val);
  106. break;
  107. case 4:
  108. tx3927_pcicptr->icd = cpu_to_le32(val);
  109. }
  110. if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
  111. tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
  112. tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
  113. return PCIBIOS_DEVICE_NOT_FOUND;
  114. return check_abort();
  115. }
  116. struct pci_ops jmr3927_pci_ops = {
  117. jmr3927_pcibios_read_config,
  118. jmr3927_pcibios_write_config,
  119. };
  120. #ifndef JMR3927_INIT_INDIRECT_PCI
  121. inline unsigned long tc_readl(volatile __u32 * addr)
  122. {
  123. return readl(addr);
  124. }
  125. inline void tc_writel(unsigned long data, volatile __u32 * addr)
  126. {
  127. writel(data, addr);
  128. }
  129. #else
  130. unsigned long tc_readl(volatile __u32 * addr)
  131. {
  132. unsigned long val;
  133. addr = PHYSADDR(addr);
  134. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
  135. (unsigned long) addr;
  136. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
  137. (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) |
  138. PCI_IPCIBE_IBE_LONG;
  139. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
  140. val =
  141. le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
  142. ipcidata);
  143. /* clear by setting */
  144. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  145. return val;
  146. }
  147. void tc_writel(unsigned long data, volatile __u32 * addr)
  148. {
  149. addr = PHYSADDR(addr);
  150. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata =
  151. cpu_to_le32(data);
  152. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
  153. (unsigned long) addr;
  154. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
  155. (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT) |
  156. PCI_IPCIBE_IBE_LONG;
  157. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
  158. /* clear by setting */
  159. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  160. }
  161. unsigned char tx_ioinb(unsigned char *addr)
  162. {
  163. unsigned long val;
  164. __u32 ioaddr;
  165. int offset;
  166. int byte;
  167. ioaddr = (unsigned long) addr;
  168. offset = ioaddr & 0x3;
  169. if (offset == 0)
  170. byte = 0x7;
  171. else if (offset == 1)
  172. byte = 0xb;
  173. else if (offset == 2)
  174. byte = 0xd;
  175. else if (offset == 3)
  176. byte = 0xe;
  177. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
  178. (unsigned long) ioaddr;
  179. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
  180. (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
  181. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
  182. val =
  183. le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
  184. ipcidata);
  185. val = val & 0xff;
  186. /* clear by setting */
  187. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  188. return val;
  189. }
  190. void tx_iooutb(unsigned long data, unsigned char *addr)
  191. {
  192. __u32 ioaddr;
  193. int offset;
  194. int byte;
  195. data = data | (data << 8) | (data << 16) | (data << 24);
  196. ioaddr = (unsigned long) addr;
  197. offset = ioaddr & 0x3;
  198. if (offset == 0)
  199. byte = 0x7;
  200. else if (offset == 1)
  201. byte = 0xb;
  202. else if (offset == 2)
  203. byte = 0xd;
  204. else if (offset == 3)
  205. byte = 0xe;
  206. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data;
  207. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
  208. (unsigned long) ioaddr;
  209. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
  210. (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte;
  211. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
  212. /* clear by setting */
  213. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  214. }
  215. unsigned short tx_ioinw(unsigned short *addr)
  216. {
  217. unsigned long val;
  218. __u32 ioaddr;
  219. int offset;
  220. int byte;
  221. ioaddr = (unsigned long) addr;
  222. offset = ioaddr & 0x3;
  223. if (offset == 0)
  224. byte = 0x3;
  225. else if (offset == 2)
  226. byte = 0xc;
  227. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
  228. (unsigned long) ioaddr;
  229. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
  230. (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
  231. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
  232. val =
  233. le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
  234. ipcidata);
  235. val = val & 0xffff;
  236. /* clear by setting */
  237. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  238. return val;
  239. }
  240. void tx_iooutw(unsigned long data, unsigned short *addr)
  241. {
  242. __u32 ioaddr;
  243. int offset;
  244. int byte;
  245. data = data | (data << 16);
  246. ioaddr = (unsigned long) addr;
  247. offset = ioaddr & 0x3;
  248. if (offset == 0)
  249. byte = 0x3;
  250. else if (offset == 2)
  251. byte = 0xc;
  252. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data;
  253. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
  254. (unsigned long) ioaddr;
  255. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
  256. (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte;
  257. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
  258. /* clear by setting */
  259. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  260. }
  261. unsigned long tx_ioinl(unsigned int *addr)
  262. {
  263. unsigned long val;
  264. __u32 ioaddr;
  265. ioaddr = (unsigned long) addr;
  266. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
  267. (unsigned long) ioaddr;
  268. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
  269. (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) |
  270. PCI_IPCIBE_IBE_LONG;
  271. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
  272. val =
  273. le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
  274. ipcidata);
  275. /* clear by setting */
  276. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  277. return val;
  278. }
  279. void tx_iooutl(unsigned long data, unsigned int *addr)
  280. {
  281. __u32 ioaddr;
  282. ioaddr = (unsigned long) addr;
  283. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata =
  284. cpu_to_le32(data);
  285. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
  286. (unsigned long) ioaddr;
  287. *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
  288. (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) |
  289. PCI_IPCIBE_IBE_LONG;
  290. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
  291. /* clear by setting */
  292. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  293. }
  294. void tx_insbyte(unsigned char *addr, void *buffer, unsigned int count)
  295. {
  296. unsigned char *ptr = (unsigned char *) buffer;
  297. while (count--) {
  298. *ptr++ = tx_ioinb(addr);
  299. }
  300. }
  301. void tx_insword(unsigned short *addr, void *buffer, unsigned int count)
  302. {
  303. unsigned short *ptr = (unsigned short *) buffer;
  304. while (count--) {
  305. *ptr++ = tx_ioinw(addr);
  306. }
  307. }
  308. void tx_inslong(unsigned int *addr, void *buffer, unsigned int count)
  309. {
  310. unsigned long *ptr = (unsigned long *) buffer;
  311. while (count--) {
  312. *ptr++ = tx_ioinl(addr);
  313. }
  314. }
  315. void tx_outsbyte(unsigned char *addr, void *buffer, unsigned int count)
  316. {
  317. unsigned char *ptr = (unsigned char *) buffer;
  318. while (count--) {
  319. tx_iooutb(*ptr++, addr);
  320. }
  321. }
  322. void tx_outsword(unsigned short *addr, void *buffer, unsigned int count)
  323. {
  324. unsigned short *ptr = (unsigned short *) buffer;
  325. while (count--) {
  326. tx_iooutw(*ptr++, addr);
  327. }
  328. }
  329. void tx_outslong(unsigned int *addr, void *buffer, unsigned int count)
  330. {
  331. unsigned long *ptr = (unsigned long *) buffer;
  332. while (count--) {
  333. tx_iooutl(*ptr++, addr);
  334. }
  335. }
  336. #endif