Import 2.3.18pre1
[davej-history.git] / arch / ppc / kernel / gemini_pci.c
blob89ed435014944c44ae4ca732b54aa0b7c9857db9
1 #include <linux/kernel.h>
2 #include <linux/init.h>
3 #include <linux/pci.h>
4 #include <linux/malloc.h>
6 #include <asm/machdep.h>
7 #include <asm/gemini.h>
8 #include <asm/byteorder.h>
9 #include <asm/io.h>
10 #include <asm/uaccess.h>
12 #include "pci.h"
14 #define pci_config_addr(bus,dev,offset) \
15 (0x80000000 | (bus<<16) | (dev<<8) | offset)
18 int
19 gemini_pcibios_read_config_byte(unsigned char bus, unsigned char dev,
20 unsigned char offset, unsigned char *val)
22 unsigned long reg;
23 reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3))));
24 *val = ((reg >> ((offset & 0x3) << 3)) & 0xff);
25 return PCIBIOS_SUCCESSFUL;
28 int
29 gemini_pcibios_read_config_word(unsigned char bus, unsigned char dev,
30 unsigned char offset, unsigned short *val)
32 unsigned long reg;
33 reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3))));
34 *val = ((reg >> ((offset & 0x3) << 3)) & 0xffff);
35 return PCIBIOS_SUCCESSFUL;
38 int
39 gemini_pcibios_read_config_dword(unsigned char bus, unsigned char dev,
40 unsigned char offset, unsigned int *val)
42 *val = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3))));
43 return PCIBIOS_SUCCESSFUL;
46 int
47 gemini_pcibios_write_config_byte(unsigned char bus, unsigned char dev,
48 unsigned char offset, unsigned char val)
50 unsigned long reg;
51 int shifts = offset & 0x3;
53 reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3))));
54 reg = (reg & ~(0xff << (shifts << 3))) | (val << (shifts << 3));
55 grackle_write( pci_config_addr( bus, dev, (offset & ~(0x3))), reg );
56 return PCIBIOS_SUCCESSFUL;
59 int
60 gemini_pcibios_write_config_word(unsigned char bus, unsigned char dev,
61 unsigned char offset, unsigned short val)
63 unsigned long reg;
64 int shifts = offset & 0x3;
66 reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3))));
67 reg = (reg & ~(0xffff << (shifts << 3))) | (val << (shifts << 3));
68 grackle_write( pci_config_addr( bus, dev, (offset & ~(0x3))), reg );
69 return PCIBIOS_SUCCESSFUL;
72 int
73 gemini_pcibios_write_config_dword(unsigned char bus, unsigned char dev,
74 unsigned char offset, unsigned int val)
76 grackle_write( pci_config_addr( bus, dev, (offset & ~(0x3))), val );
77 return PCIBIOS_SUCCESSFUL;
80 struct gemini_device {
81 unsigned short vendor, device;
82 unsigned char irq;
83 unsigned short cmd;
84 unsigned char cache_line, latency;
85 void (*init)(struct pci_dev *dev);
88 static struct gemini_device gemini_map[] = {
89 { PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C885, 11, 0x15, 32, 248, NULL },
90 { PCI_VENDOR_ID_NCR, 0x701, 10, 0, 0, 0, NULL },
91 { PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C042, 3, 0, 0, 0, NULL },
92 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_MPIC, 0xff, 0, 0, 0, NULL },
93 { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_670, 0xff, 0, 0, 0, NULL },
94 { PCI_VENDOR_ID_MOTOROLA, PCI_DEVICE_ID_MOTOROLA_MPC106, 0xff, 0, 0, 0, NULL },
97 static int gemini_map_count = (sizeof( gemini_map ) /
98 sizeof( gemini_map[0] ));
102 /* This just sets up the known devices on the board. */
103 static void __init mapin_device( struct pci_dev *dev )
105 struct gemini_device *p;
106 unsigned short cmd;
107 int i;
110 for( i=0; i < gemini_map_count; i++ ) {
111 p = &(gemini_map[i]);
113 if ( p->vendor == dev->vendor &&
114 p->device == dev->device ) {
116 if (p->irq != 0xff) {
117 pci_write_config_byte( dev, PCI_INTERRUPT_LINE, p->irq );
118 dev->irq = p->irq;
121 if (p->cmd) {
122 pci_read_config_word( dev, PCI_COMMAND, &cmd );
123 pci_write_config_word( dev, PCI_COMMAND, (p->cmd|cmd));
126 if (p->cache_line)
127 pci_write_config_byte( dev, PCI_CACHE_LINE_SIZE, p->cache_line );
129 if (p->latency)
130 pci_write_config_byte( dev, PCI_LATENCY_TIMER, p->latency );
135 #define KB 1024
136 #define MB (KB*KB)
138 #define ALIGN(val,align) (((val) + ((align) -1))&(~((align) -1)))
139 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
141 #define FIRST_IO_ADDR 0x10000
142 #define FIRST_MEM_ADDR 0x02000000
144 #define GEMINI_PCI_MEM_BASE (0xf0000000)
145 #define GEMINI_PCI_IO_BASE (0xfe800000)
147 static unsigned long pci_mem_base = GEMINI_PCI_MEM_BASE;
148 static unsigned long pci_io_base = GEMINI_PCI_IO_BASE;
150 static unsigned int io_base = FIRST_IO_ADDR;
151 static unsigned int mem_base = FIRST_MEM_ADDR;
155 __init void layout_dev( struct pci_dev *dev )
157 int i;
158 struct pci_bus *bus;
159 unsigned short cmd;
160 unsigned int reg, base, mask, size, alignto, type;
162 bus = dev->bus;
164 /* make any known settings happen */
165 mapin_device( dev );
167 gemini_pcibios_read_config_word( bus->number, dev->devfn, PCI_COMMAND, &cmd );
169 for( reg = PCI_BASE_ADDRESS_0, i=0; reg <= PCI_BASE_ADDRESS_5; reg += 4, i++ ) {
171 /* MPIC already done */
172 if (dev->vendor == PCI_VENDOR_ID_IBM &&
173 dev->device == PCI_DEVICE_ID_IBM_MPIC)
174 return;
176 gemini_pcibios_write_config_dword( bus->number, dev->devfn, reg, 0xffffffff );
177 gemini_pcibios_read_config_dword( bus->number, dev->devfn, reg, &base );
178 if (!base) {
179 dev->resource[i].start = 0;
180 continue;
183 if (base & PCI_BASE_ADDRESS_SPACE_IO) {
184 cmd |= PCI_COMMAND_IO;
185 base &= PCI_BASE_ADDRESS_IO_MASK;
186 mask = (~base << 1) | 0x1;
187 size = (mask & base) & 0xffffffff;
188 alignto = MAX(0x400, size);
189 base = ALIGN(io_base, alignto);
190 io_base = base + size;
191 gemini_pcibios_write_config_dword( bus->number, dev->devfn, reg,
192 ((pci_io_base + base) & 0x00ffffff) | 0x1);
193 dev->resource[i].start = (pci_io_base + base) | 0x1;
196 else {
197 cmd |= PCI_COMMAND_MEMORY;
198 type = base & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
199 mask = (~base << 1) | 0x1;
200 size = (mask & base) & 0xffffffff;
201 switch( type ) {
203 case PCI_BASE_ADDRESS_MEM_TYPE_32:
204 break;
205 case PCI_BASE_ADDRESS_MEM_TYPE_64:
206 printk("Warning: Ignoring 64-bit device; slot %d, function %d.\n",
207 PCI_SLOT( dev->devfn ), PCI_FUNC( dev->devfn ));
208 reg += 4;
209 continue;
212 alignto = MAX(0x1000, size);
213 base = ALIGN(mem_base, alignto);
214 mem_base = base + size;
215 gemini_pcibios_write_config_dword( bus->number, dev->devfn,
216 reg, (pci_mem_base + base));
217 dev->resource[i].start = pci_mem_base + base;
221 if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
222 cmd |= PCI_COMMAND_IO;
224 gemini_pcibios_write_config_word( bus->number, dev->devfn, PCI_COMMAND,
225 (cmd|PCI_COMMAND_MASTER));
228 __init void layout_bus( struct pci_bus *bus )
230 struct pci_dev *dev;
232 if (!bus->devices && !bus->children)
233 return;
235 io_base = ALIGN(io_base, 4*KB);
236 mem_base = ALIGN(mem_base, 4*KB);
238 for( dev = bus->devices; dev; dev = dev->sibling ) {
239 if (((dev->class >> 16) != PCI_BASE_CLASS_BRIDGE) ||
240 ((dev->class >> 8) == PCI_CLASS_BRIDGE_OTHER))
241 layout_dev( dev );
245 void __init gemini_pcibios_fixup(void)
247 struct pci_bus *bus;
248 unsigned long orig_mem_base, orig_io_base;
250 orig_mem_base = pci_mem_base;
251 orig_io_base = pci_io_base;
253 pci_mem_base = orig_mem_base;
254 pci_io_base = orig_io_base;
257 decl_config_access_method(gemini);
259 /* The "bootloader" for Synergy boards does none of this for us, so we need to
260 lay it all out ourselves... --Dan */
261 void __init gemini_setup_pci_ptrs(void)
263 set_config_access_method(gemini);
264 ppc_md.pcibios_fixup = gemini_pcibios_fixup;