it8172_pci.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BRIEF MODULE DESCRIPTION
  3.  * IT8172 system controller specific pci support.
  4.  *
  5.  * Copyright 2000 MontaVista Software Inc.
  6.  * Author: MontaVista Software, Inc.
  7.  *          ppopov@mvista.com or source@mvista.com
  8.  *
  9.  *  This program is free software; you can redistribute  it and/or modify it
  10.  *  under  the terms of  the GNU General  Public License as published by the
  11.  *  Free Software Foundation;  either version 2 of the  License, or (at your
  12.  *  option) any later version.
  13.  *
  14.  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
  15.  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
  16.  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  17.  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
  18.  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19.  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
  20.  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  21.  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
  22.  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23.  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24.  *
  25.  *  You should have received a copy of the  GNU General Public License along
  26.  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  27.  *  675 Mass Ave, Cambridge, MA 02139, USA.
  28.  */
  29. #include <linux/config.h>
  30. #ifdef CONFIG_PCI
  31. #include <linux/types.h>
  32. #include <linux/pci.h>
  33. #include <linux/kernel.h>
  34. #include <linux/init.h>
  35. #include <asm/it8172/it8172.h>
  36. #include <asm/it8172/it8172_pci.h>
  37. #define PCI_ACCESS_READ  0
  38. #define PCI_ACCESS_WRITE 1
  39. #undef DEBUG
  40. #undef DEBUG_CONFIG_CYCLES
  41. static int
  42. it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
  43.                            unsigned char where, u32 *data)
  44. {
  45. /* 
  46.  * config cycles are on 4 byte boundary only
  47.  */
  48. unsigned char bus = dev->bus->number;
  49. unsigned char dev_fn = dev->devfn;
  50. #ifdef DEBUG_CONFIG_CYCLES
  51. printk("it config: type %d dev %x bus %d dev_fn %x data %xn",
  52. access_type, dev, bus, dev_fn, *data);
  53. #endif
  54. /* Setup address */
  55. IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | 
  56. (dev_fn << IT_FUNCNUM_SHF) | (where & ~0x3));
  57. if (access_type == PCI_ACCESS_WRITE) {
  58. IT_WRITE(IT_CONFDATA, *data);
  59. else {
  60. IT_READ(IT_CONFDATA, *data);
  61. }
  62. /*
  63.  * Revisit: check for master or target abort.
  64.  */
  65. return 0;
  66. }
  67. /*
  68.  * We can't address 8 and 16 bit words directly.  Instead we have to
  69.  * read/write a 32bit word and mask/modify the data we actually want.
  70.  */
  71. static int
  72. it8172_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val)
  73. {
  74. u32 data = 0;
  75. if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
  76. return -1;
  77. *val = (data >> ((where & 3) << 3)) & 0xff;
  78. #ifdef DEBUG
  79.         printk("cfg read byte: bus %d dev_fn %x where %x: val %xn", 
  80.                 dev->bus->number, dev->devfn, where, *val);
  81. #endif
  82. return PCIBIOS_SUCCESSFUL;
  83. }
  84. static int
  85. it8172_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val)
  86. {
  87. u32 data = 0;
  88. if (where & 1)
  89. return PCIBIOS_BAD_REGISTER_NUMBER;
  90. if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
  91.        return -1;
  92. *val = (data >> ((where & 3) << 3)) & 0xffff;
  93. #ifdef DEBUG
  94.         printk("cfg read word: bus %d dev_fn %x where %x: val %xn", 
  95.                 dev->bus->number, dev->devfn, where, *val);
  96. #endif
  97. return PCIBIOS_SUCCESSFUL;
  98. }
  99. static int
  100. it8172_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val)
  101. {
  102. u32 data = 0;
  103. if (where & 3)
  104. return PCIBIOS_BAD_REGISTER_NUMBER;
  105. if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
  106. return -1;
  107. *val = data;
  108. #ifdef DEBUG
  109.         printk("cfg read dword: bus %d dev_fn %x where %x: val %xn", 
  110.                 dev->bus->number, dev->devfn, where, *val);
  111. #endif
  112. return PCIBIOS_SUCCESSFUL;
  113. }
  114. static int
  115. it8172_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val)
  116. {
  117. u32 data = 0;
  118.        
  119. if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
  120. return -1;
  121. data = (data & ~(0xff << ((where & 3) << 3))) |
  122.        (val << ((where & 3) << 3));
  123. if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
  124. return -1;
  125. return PCIBIOS_SUCCESSFUL;
  126. }
  127. static int
  128. it8172_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val)
  129. {
  130.         u32 data = 0;
  131. if (where & 1)
  132. return PCIBIOS_BAD_REGISTER_NUMBER;
  133.        
  134.         if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
  135.        return -1;
  136. data = (data & ~(0xffff << ((where & 3) << 3))) | 
  137.        (val << ((where & 3) << 3));
  138. if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
  139.        return -1;
  140. return PCIBIOS_SUCCESSFUL;
  141. }
  142. static int
  143. it8172_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val)
  144. {
  145. if (where & 3)
  146. return PCIBIOS_BAD_REGISTER_NUMBER;
  147. if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val))
  148.        return -1;
  149. return PCIBIOS_SUCCESSFUL;
  150. }
  151. struct pci_ops it8172_pci_ops = {
  152. it8172_pcibios_read_config_byte,
  153.         it8172_pcibios_read_config_word,
  154. it8172_pcibios_read_config_dword,
  155. it8172_pcibios_write_config_byte,
  156. it8172_pcibios_write_config_word,
  157. it8172_pcibios_write_config_dword
  158. };
  159. void __init pcibios_init(void)
  160. {
  161. printk("PCI: Probing PCI hardware on host bus 0.n");
  162. pci_scan_bus(0, &it8172_pci_ops, NULL);
  163. }
  164. int __init
  165. pcibios_enable_device(struct pci_dev *dev)
  166. {
  167. u16 cmd, old_cmd;
  168. int idx;
  169. struct resource *r;
  170. pci_read_config_word(dev, PCI_COMMAND, &cmd);
  171. old_cmd = cmd;
  172. for(idx=0; idx<6; idx++) {
  173. r = &dev->resource[idx];
  174. if (!r->start && r->end) {
  175. printk(KERN_ERR "PCI: Device %s not available because of resource collisionsn", dev->slot_name);
  176. return -EINVAL;
  177. }
  178. if (r->flags & IORESOURCE_IO)
  179. cmd |= PCI_COMMAND_IO;
  180. if (r->flags & IORESOURCE_MEM)
  181. cmd |= PCI_COMMAND_MEMORY;
  182. }
  183. if (dev->resource[PCI_ROM_RESOURCE].start)
  184. cmd |= PCI_COMMAND_MEMORY;
  185. if (cmd != old_cmd) {
  186. printk("PCI: Enabling device %s (%04x -> %04x)n", dev->slot_name, old_cmd, cmd);
  187. pci_write_config_word(dev, PCI_COMMAND, cmd);
  188. }
  189. return 0;
  190. }
  191. void __init
  192. pcibios_align_resource(void *data, struct resource *res, unsigned long size)
  193. {
  194.     printk("pcibios_align_resourcen");
  195. }
  196. char * __init
  197. pcibios_setup(char *str)
  198. {
  199. /* Nothing to do for now.  */
  200. return str;
  201. }
  202. void __init
  203. pcibios_update_resource(struct pci_dev *dev, struct resource *root,
  204.                         struct resource *res, int resource)
  205. {
  206. unsigned long where, size;
  207. u32 reg;
  208. where = PCI_BASE_ADDRESS_0 + (resource * 4);
  209. size = res->end - res->start;
  210. pci_read_config_dword(dev, where, &reg);
  211. reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
  212. pci_write_config_dword(dev, where, reg);
  213. }
  214. void __init pcibios_fixup_bus(struct pci_bus *b)
  215. {
  216. //printk("pcibios_fixup_busn");
  217. }
  218. unsigned __init int pcibios_assign_all_busses(void)
  219. {
  220. return 1;
  221. }
  222. #endif /* CONFIG_PCI */