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

Linux/Unix编程

开发平台:

Unix_Linux

  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.  *
  8.  * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
  9.  *
  10.  *     Define the pci_ops for JMR3927.
  11.  *
  12.  * Much of the code is derived from the original DDB5074 port by 
  13.  * Geert Uytterhoeven <geert@sonycom.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.  */
  36. #include <linux/types.h>
  37. #include <linux/pci.h>
  38. #include <linux/kernel.h>
  39. #include <linux/init.h>
  40. #include <linux/config.h>
  41. #include <asm/addrspace.h>
  42. #include <asm/pci_channel.h>
  43. #include <asm/jmr3927/jmr3927.h>
  44. #include <asm/debug.h>
  45. struct resource pci_io_resource = {
  46. "pci IO space", 
  47. 0x1000,  /* reserve regacy I/O space */
  48. 0x1000 + JMR3927_PCIIO_SIZE -1,
  49. IORESOURCE_IO};
  50. struct resource pci_mem_resource = {
  51. "pci memory space", 
  52. JMR3927_PCIMEM,
  53. JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE -1,
  54. IORESOURCE_MEM};
  55. extern struct pci_ops jmr3927_pci_ops;
  56. struct pci_channel mips_pci_channels[] = {
  57. { &jmr3927_pci_ops, &pci_io_resource, &pci_mem_resource, 0, 0xff },
  58. { NULL, NULL, NULL, NULL, NULL}
  59. };
  60. unsigned int pcibios_assign_all_busses(void)
  61. {
  62. return 1;
  63. }                           
  64. static int
  65. mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, int *flagsp)
  66. {
  67. if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
  68. return -1;
  69. tx3927_pcicptr->ica = ((bus    & 0xff) << 0x10) |
  70.                       ((dev_fn & 0xff) << 0x08) |
  71.                       (where  & 0xfc);
  72. /* clear M_ABORT and Disable M_ABORT Int. */
  73. tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
  74. tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;
  75. return 0;
  76. }
  77. static int
  78. check_abort(int flags)
  79. {
  80. int code = PCIBIOS_SUCCESSFUL;
  81. if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) {
  82. tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
  83. tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
  84. code =PCIBIOS_DEVICE_NOT_FOUND;
  85. }
  86. return code;
  87. }
  88. /*
  89.  * We can't address 8 and 16 bit words directly.  Instead we have to
  90.  * read/write a 32bit word and mask/modify the data we actually want.
  91.  */
  92. static int jmr3927_pcibios_read_config_byte (struct pci_dev *dev,
  93.      int where,
  94.      unsigned char *val)
  95. {
  96. int flags;
  97. unsigned char bus, func_num;
  98. db_assert((where & 3) == 0);
  99. db_assert(where < (1 << 8));  
  100. /* check if the bus is top-level */
  101. if (dev->bus->parent != NULL) {
  102. bus = dev->bus->number;
  103. db_assert(bus != 0);
  104. } else {
  105. bus = 0;
  106. }                               
  107. func_num = PCI_FUNC(dev->devfn);
  108. if (mkaddr(bus, dev->devfn, where, &flags))
  109. return -1;
  110. *val = *(volatile u8 *)((ulong)&tx3927_pcicptr->icd | (where&3));
  111. return check_abort(flags);
  112. }
  113. static int jmr3927_pcibios_read_config_word (struct pci_dev *dev,
  114.      int where,
  115.      unsigned short *val)
  116. {
  117. int flags;
  118. unsigned char bus, func_num;
  119. if (where & 1)
  120. return PCIBIOS_BAD_REGISTER_NUMBER;
  121. db_assert((where & 3) == 0);
  122. db_assert(where < (1 << 8));  
  123. /* check if the bus is top-level */
  124. if (dev->bus->parent != NULL) {
  125. bus = dev->bus->number;
  126. db_assert(bus != 0);
  127. } else {
  128. bus = 0;
  129. }                               
  130. func_num = PCI_FUNC(dev->devfn);
  131. if (mkaddr(bus, dev->devfn, where, &flags))
  132. return -1;
  133. *val = le16_to_cpu(*(volatile u16 *)((ulong)&tx3927_pcicptr->icd | (where&3)));
  134. return check_abort(flags);
  135. }
  136. static int jmr3927_pcibios_read_config_dword (struct pci_dev *dev,
  137.       int where,
  138.       unsigned int *val)
  139. {
  140. int flags;
  141. unsigned char bus, func_num;
  142. if (where & 3)
  143. return PCIBIOS_BAD_REGISTER_NUMBER;
  144. db_assert((where & 3) == 0);
  145. db_assert(where < (1 << 8));  
  146. /* check if the bus is top-level */
  147. if (dev->bus->parent != NULL) {
  148. bus = dev->bus->number;
  149. db_assert(bus != 0);
  150. } else {
  151. bus = 0;
  152. }                               
  153. func_num = PCI_FUNC(dev->devfn);
  154. if (mkaddr(bus, dev->devfn, where, &flags))
  155. return -1;
  156. *val = le32_to_cpu(tx3927_pcicptr->icd);
  157. return check_abort(flags);
  158. }
  159. static int jmr3927_pcibios_write_config_byte (struct pci_dev *dev,
  160.       int where,
  161.       unsigned char val)
  162. {
  163. int flags;
  164. unsigned char bus, func_num;
  165. /* check if the bus is top-level */
  166. if (dev->bus->parent != NULL) {
  167. bus = dev->bus->number;
  168. db_assert(bus != 0);
  169. } else {
  170. bus = 0;
  171. }                               
  172. func_num = PCI_FUNC(dev->devfn);
  173. if (mkaddr(bus, dev->devfn, where, &flags))
  174. return -1;
  175. *(volatile u8 *)((ulong)&tx3927_pcicptr->icd | (where&3)) = val;
  176. return check_abort(flags);
  177. }
  178. static int jmr3927_pcibios_write_config_word (struct pci_dev *dev,
  179.       int where,
  180.       unsigned short val)
  181. {
  182. int flags;
  183. unsigned char bus, func_num;
  184. if (where & 1)
  185. return PCIBIOS_BAD_REGISTER_NUMBER;
  186. /* check if the bus is top-level */
  187. if (dev->bus->parent != NULL) {
  188. bus = dev->bus->number;
  189. db_assert(bus != 0);
  190. } else {
  191. bus = 0;
  192. }                               
  193. func_num = PCI_FUNC(dev->devfn);
  194. if (mkaddr(bus, dev->devfn, where, &flags))
  195. return -1;
  196. *(volatile u16 *)((ulong)&tx3927_pcicptr->icd | (where&3)) = cpu_to_le16(val);
  197. return check_abort(flags);
  198. }
  199. static int jmr3927_pcibios_write_config_dword (struct pci_dev *dev,
  200.        int where,
  201.        unsigned int val)
  202. {
  203. int flags;
  204. unsigned char bus, func_num;
  205. if (where & 3)
  206. return PCIBIOS_BAD_REGISTER_NUMBER;
  207. /* check if the bus is top-level */
  208. if (dev->bus->parent != NULL) {
  209. bus = dev->bus->number;
  210. db_assert(bus != 0);
  211. } else {
  212. bus = 0;
  213. }                               
  214. func_num = PCI_FUNC(dev->devfn);
  215. if (mkaddr(bus, dev->devfn, where, &flags))
  216. return -1;
  217. tx3927_pcicptr->icd = cpu_to_le32(val);
  218. return check_abort(flags);
  219. }
  220. struct pci_ops jmr3927_pci_ops = {
  221. jmr3927_pcibios_read_config_byte,
  222. jmr3927_pcibios_read_config_word,
  223. jmr3927_pcibios_read_config_dword,
  224. jmr3927_pcibios_write_config_byte,
  225. jmr3927_pcibios_write_config_word,
  226. jmr3927_pcibios_write_config_dword
  227. };
  228. #ifndef JMR3927_INIT_INDIRECT_PCI
  229. inline unsigned long tc_readl(volatile __u32 *addr)
  230. {
  231. return readl(addr);
  232. }
  233. inline void tc_writel(unsigned long data, volatile __u32 *addr)
  234. {
  235. writel(data, addr);
  236. }
  237. #else
  238. unsigned long tc_readl(volatile __u32 *addr)
  239. {
  240. unsigned long val;
  241. addr = PHYSADDR(addr);
  242. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)addr;
  243. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
  244.     (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG;
  245. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
  246. val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
  247. /* clear by setting */
  248. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  249. return val;
  250. }
  251. void tc_writel(unsigned long data, volatile __u32 *addr)
  252. {
  253. addr = PHYSADDR(addr);
  254. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data);
  255. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)addr;
  256. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
  257.     (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT)  | PCI_IPCIBE_IBE_LONG;
  258. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
  259. /* clear by setting */
  260. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  261. }
  262. unsigned char tx_ioinb(unsigned char *addr)
  263. {
  264. unsigned long val;
  265. __u32 ioaddr;
  266. int offset;
  267. int byte;
  268. ioaddr = (unsigned long)addr;
  269.         offset = ioaddr & 0x3;
  270. if (offset == 0)
  271. byte = 0x7;
  272. else if (offset == 1)
  273. byte = 0xb;
  274. else if (offset == 2)
  275. byte = 0xd;
  276. else if (offset == 3)
  277. byte = 0xe;
  278. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
  279. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
  280.     (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
  281. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
  282. val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
  283. val = val & 0xff;
  284. /* clear by setting */
  285. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  286. return val;
  287. }
  288. void tx_iooutb(unsigned long data, unsigned char *addr)
  289. {
  290. __u32 ioaddr;
  291. int offset;
  292. int byte;
  293. data = data | (data << 8) | (data << 16) | (data << 24);
  294. ioaddr = (unsigned long)addr;
  295.         offset = ioaddr & 0x3;
  296. if (offset == 0)
  297. byte = 0x7;
  298. else if (offset == 1)
  299. byte = 0xb;
  300. else if (offset == 2)
  301. byte = 0xd;
  302. else if (offset == 3)
  303. byte = 0xe;
  304. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data;
  305. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
  306. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
  307.     (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT)  | byte;
  308. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
  309. /* clear by setting */
  310. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  311. }
  312. unsigned short tx_ioinw(unsigned short *addr)
  313. {
  314. unsigned long val;
  315. __u32 ioaddr;
  316. int offset;
  317. int byte;
  318. ioaddr = (unsigned long)addr;
  319.         offset = ioaddr & 0x3;
  320. if (offset == 0)
  321. byte = 0x3;
  322. else if (offset == 2)
  323. byte = 0xc;
  324. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
  325. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
  326.     (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
  327. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
  328. val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
  329. val = val & 0xffff;
  330. /* clear by setting */
  331. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  332. return val;
  333. }
  334. void tx_iooutw(unsigned long data, unsigned short *addr)
  335. {
  336. __u32 ioaddr;
  337. int offset;
  338. int byte;
  339. data = data | (data << 16);
  340. ioaddr = (unsigned long)addr;
  341.         offset = ioaddr & 0x3;
  342. if (offset == 0)
  343. byte = 0x3;
  344. else if (offset == 2)
  345. byte = 0xc;
  346. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data;
  347. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
  348. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
  349.     (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT)  | byte;
  350. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
  351. /* clear by setting */
  352. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  353. }
  354. unsigned long tx_ioinl(unsigned int *addr)
  355. {
  356. unsigned long val;
  357. __u32 ioaddr;
  358. ioaddr = (unsigned long)addr;
  359. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
  360. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
  361.     (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG;
  362. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
  363. val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata);
  364. /* clear by setting */
  365. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  366. return val;
  367. }
  368. void tx_iooutl(unsigned long data, unsigned int *addr)
  369. {
  370. __u32 ioaddr;
  371. ioaddr = (unsigned long)addr;
  372. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data);
  373. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr =  (unsigned long)ioaddr;
  374. *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe =  
  375.     (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT)  | PCI_IPCIBE_IBE_LONG;
  376. while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ;
  377. /* clear by setting */
  378. tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
  379. }
  380. void tx_insbyte(unsigned char *addr,void *buffer,unsigned int count)
  381. {
  382. unsigned char *ptr = (unsigned char *) buffer;
  383. while (count--) {
  384. *ptr++ = tx_ioinb(addr);
  385. }
  386. }
  387. void tx_insword(unsigned short *addr,void *buffer,unsigned int count)
  388. {
  389. unsigned short *ptr = (unsigned short *) buffer;
  390. while (count--) {
  391. *ptr++ = tx_ioinw(addr);
  392. }
  393. }
  394. void tx_inslong(unsigned int *addr,void *buffer,unsigned int count)
  395. {
  396. unsigned long *ptr = (unsigned long *) buffer;
  397. while (count--) {
  398. *ptr++ = tx_ioinl(addr);
  399. }
  400. }
  401. void tx_outsbyte(unsigned char *addr,void *buffer,unsigned int count)
  402. {
  403. unsigned char *ptr = (unsigned char *) buffer;
  404. while (count--) {
  405. tx_iooutb(*ptr++,addr);
  406. }
  407. }
  408. void tx_outsword(unsigned short *addr,void *buffer,unsigned int count)
  409. {
  410. unsigned short *ptr = (unsigned short *) buffer;
  411. while (count--) {
  412. tx_iooutw(*ptr++,addr);
  413. }
  414. }
  415. void tx_outslong(unsigned int *addr,void *buffer,unsigned int count)
  416. {
  417. unsigned long *ptr = (unsigned long *) buffer;
  418. while (count--) {
  419. tx_iooutl(*ptr++,addr);
  420. }
  421. }
  422. #endif