MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / nios2nommu / drivers / pci / altpci.c
blob85959ea747cd1c6d39ea0ee781e766a7502cef0f
1 /* arch/sh/kernel/pci.c
2 * $Id: altpci.c,v 1.1 2006/07/05 06:23:17 gerg Exp $
4 * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org>
5 *
6 *
7 * These functions are collected here to reduce duplication of common
8 * code amongst the many platform-specific PCI support code files.
9 *
10 * These routines require the following board-specific routines:
11 * void pcibios_fixup_irqs();
13 * See include/asm-sh/pci.h for more information.
16 #include <linux/kernel.h>
17 #include <linux/pci.h>
18 #include <linux/init.h>
21 * Direct access to PCI hardware...
23 #define pcicfg_space (na_pci_compiler_0_PCI_Bus_Access) // avalon space
24 #define pciio (pcicfg_space+0x100000) // pci io device base in avalon space
25 #define pcimm (pcicfg_space+0x200000) // pci mem device base in avalon space
26 // idsel of ad11=dev0,ad12=dev1 , using type 0 config request
27 #define pcicfg(dev,fun,reg) (pcicfg_space | ((dev)<<11) | ((fun)<<8) | (reg)) // cfg space
29 // FIX ME for your board, dram device for external pci masters access
30 static int __init alt_pci_init(void)
32 unsigned dev,fun;
33 // setup dram bar
34 dev=0; fun=0;
35 outl(nasys_program_mem,pcicfg(dev,fun,0x10)); // mem space
36 outw(0x0006,pcicfg(dev,fun,0x04)); // enable master, mem space
37 return 0;
40 subsys_initcall(alt_pci_init);
42 #define PCICFG(bus, devfn, where) (pcicfg_space | (bus->number << 16) | (devfn << 8) | (where & ~3))
43 #define ALT_PCI_IO_BASE (pciio)
44 #define ALT_PCI_IO_SIZE 0x100000
45 #define ALT_PCI_MEMORY_BASE (pcimm)
46 #define ALT_PCI_MEM_SIZE 0x100000
49 * Functions for accessing PCI configuration space with type 1 accesses
52 // FIX ME for your board, number of pci bus, and number of devices
53 static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn)
55 if (bus->number > 0 || PCI_SLOT(devfn) == 0 || PCI_SLOT(devfn) > 2)
56 return -1;
58 return 0;
61 static int alt_pci_read(struct pci_bus *bus, unsigned int devfn,
62 int where, int size, u32 *val)
64 u32 data;
66 if (pci_range_ck(bus, devfn))
67 return PCIBIOS_DEVICE_NOT_FOUND;
69 // local_irq_save(flags);
70 data = inl(PCICFG(bus, devfn, where));
71 // local_irq_restore(flags);
73 switch (size) {
74 case 1:
75 *val = (data >> ((where & 3) << 3)) & 0xff;
76 break;
77 case 2:
78 *val = (data >> ((where & 2) << 3)) & 0xffff;
79 break;
80 case 4:
81 *val = data;
82 break;
83 default:
84 return PCIBIOS_FUNC_NOT_SUPPORTED;
87 return PCIBIOS_SUCCESSFUL;
90 /*
91 * we'll do a read,
92 * mask,write operation.
93 * We'll allow an odd byte offset, though it should be illegal.
94 */
95 static int alt_pci_write(struct pci_bus *bus, unsigned int devfn,
96 int where, int size, u32 val)
98 int shift;
99 u32 data;
101 if (pci_range_ck(bus, devfn))
102 return PCIBIOS_DEVICE_NOT_FOUND;
104 // local_irq_save(flags);
105 data = inl(PCICFG(bus, devfn, where));
106 // local_irq_restore(flags);
108 switch (size) {
109 case 1:
110 shift = (where & 3) << 3;
111 data &= ~(0xff << shift);
112 data |= ((val & 0xff) << shift);
113 break;
114 case 2:
115 shift = (where & 2) << 3;
116 data &= ~(0xffff << shift);
117 data |= ((val & 0xffff) << shift);
118 break;
119 case 4:
120 data = val;
121 break;
122 default:
123 return PCIBIOS_FUNC_NOT_SUPPORTED;
126 outl(data, PCICFG(bus, devfn, where));
128 return PCIBIOS_SUCCESSFUL;
131 struct pci_ops alt_pci_ops = {
132 .read = alt_pci_read,
133 .write = alt_pci_write,
136 static struct resource alt_io_resource = {
137 .name = "ALTPCI IO",
138 .start = ALT_PCI_IO_BASE,
139 .end = ALT_PCI_IO_BASE + ALT_PCI_IO_SIZE - 1,
140 .flags = IORESOURCE_IO
143 static struct resource alt_mem_resource = {
144 .name = "ALTPCI mem",
145 .start = ALT_PCI_MEMORY_BASE,
146 .end = ALT_PCI_MEMORY_BASE + ALT_PCI_MEM_SIZE - 1,
147 .flags = IORESOURCE_MEM
150 extern struct pci_ops alt_pci_ops;
152 struct pci_channel board_pci_channels[] = {
153 { &alt_pci_ops, &alt_io_resource, &alt_mem_resource, 0, 0xff },
154 { NULL, NULL, NULL, 0, 0 },
157 char *pcibios_setup(char *option)
159 /* Nothing for us to handle. */
160 return(option);
163 void pcibios_fixup_bus(struct pci_bus *b)
168 * IRQ functions
170 static u8 __init altpci_no_swizzle(struct pci_dev *dev, u8 *pin)
172 /* no swizzling */
173 return PCI_SLOT(dev->devfn);
176 // FIX ME for your board, nios2 irqn mapping
177 int __init pcibios_map_platform_irq(u8 slot, u8 pin)
179 int irq = na_irqn_0_irq + ((slot-1)*4) + (pin-1);
180 // printk("map slot %d pin %d irq %d\n",slot,pin,irq);
181 return irq;
184 static int altpci_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
186 int irq = -1;
188 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
189 irq = pcibios_map_platform_irq(slot,pin);
190 if( irq < 0 ) {
191 // printk("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
192 return irq;
195 // printk("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
197 return irq;
200 void __init pcibios_fixup_irqs(void)
202 pci_fixup_irqs(altpci_no_swizzle, altpci_pci_lookup_irq);