1 /*
2 * linux/arch/alpha/kernel/core_irongate.c
3 *
4 * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
5 *
6 * Copyright (C) 1999 Alpha Processor, Inc.,
7 * (David Daniel, Stig Telfer, Soohoon Lee)
8 *
9 * Code common to all IRONGATE core logic chips.
10 */
11
12 #include <linux/kernel.h>
13 #include <linux/types.h>
14 #include <linux/pci.h>
15 #include <linux/sched.h>
16 #include <linux/init.h>
17
18 #include <asm/ptrace.h>
19 #include <asm/system.h>
20 #include <asm/pci.h>
21 #include <asm/hwrpb.h>
22
23 #define __EXTERN_INLINE inline
24 #include <asm/io.h>
25 #include <asm/core_irongate.h>
26 #undef __EXTERN_INLINE
27
28 #include <linux/bootmem.h>
29
30 #include "proto.h"
31 #include "pci_impl.h"
32
33 /*
34 * BIOS32-style PCI interface:
35 */
36
37 #define DEBUG_CONFIG 0
38
39 #if DEBUG_CONFIG
40 # define DBG_CFG(args) printk args
41 #else
42 # define DBG_CFG(args)
43 #endif
44
45 igcsr32 *IronECC;
46
47 /*
48 * Given a bus, device, and function number, compute resulting
49 * configuration space address accordingly. It is therefore not safe
50 * to have concurrent invocations to configuration space access
51 * routines, but there really shouldn't be any need for this.
52 *
53 * addr[31:24] reserved
54 * addr[23:16] bus number (8 bits = 128 possible buses)
55 * addr[15:11] Device number (5 bits)
56 * addr[10: 8] function number
57 * addr[ 7: 2] register number
58 *
59 * For IRONGATE:
60 * if (bus = addr[23:16]) == 0
61 * then
62 * type 0 config cycle:
63 * addr_on_pci[31:11] = id selection for device = addr[15:11]
64 * addr_on_pci[10: 2] = addr[10: 2] ???
65 * addr_on_pci[ 1: 0] = 00
66 * else
67 * type 1 config cycle (pass on with no decoding):
68 * addr_on_pci[31:24] = 0
69 * addr_on_pci[23: 2] = addr[23: 2]
70 * addr_on_pci[ 1: 0] = 01
71 * fi
72 *
73 * Notes:
74 * The function number selects which function of a multi-function device
75 * (e.g., SCSI and Ethernet).
76 *
77 * The register selects a DWORD (32 bit) register offset. Hence it
78 * doesn't get shifted by 2 bits as we want to "drop" the bottom two
79 * bits.
80 */
81
82 static int
mk_conf_addr(struct pci_dev * dev,int where,unsigned long * pci_addr,unsigned char * type1)83 mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
84 unsigned char *type1)
85 {
86 unsigned long addr;
87 u8 bus = dev->bus->number;
88 u8 device_fn = dev->devfn;
89
90 DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
91 "pci_addr=0x%p, type1=0x%p)\n",
92 bus, device_fn, where, pci_addr, type1));
93
94 *type1 = (bus != 0);
95
96 addr = (bus << 16) | (device_fn << 8) | where;
97 addr |= IRONGATE_CONF;
98
99 *pci_addr = addr;
100 DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
101 return 0;
102 }
103
104 static int
irongate_read_config_byte(struct pci_dev * dev,int where,u8 * value)105 irongate_read_config_byte(struct pci_dev *dev, int where, u8 *value)
106 {
107 unsigned long addr;
108 unsigned char type1;
109
110 if (mk_conf_addr(dev, where, &addr, &type1))
111 return PCIBIOS_DEVICE_NOT_FOUND;
112
113 *value = __kernel_ldbu(*(vucp)addr);
114 return PCIBIOS_SUCCESSFUL;
115 }
116
117 static int
irongate_read_config_word(struct pci_dev * dev,int where,u16 * value)118 irongate_read_config_word(struct pci_dev *dev, int where, u16 *value)
119 {
120 unsigned long addr;
121 unsigned char type1;
122
123 if (mk_conf_addr(dev, where, &addr, &type1))
124 return PCIBIOS_DEVICE_NOT_FOUND;
125
126 *value = __kernel_ldwu(*(vusp)addr);
127 return PCIBIOS_SUCCESSFUL;
128 }
129
130 static int
irongate_read_config_dword(struct pci_dev * dev,int where,u32 * value)131 irongate_read_config_dword(struct pci_dev *dev, int where, u32 *value)
132 {
133 unsigned long addr;
134 unsigned char type1;
135
136 if (mk_conf_addr(dev, where, &addr, &type1))
137 return PCIBIOS_DEVICE_NOT_FOUND;
138
139 *value = *(vuip)addr;
140 return PCIBIOS_SUCCESSFUL;
141 }
142
143 static int
irongate_write_config_byte(struct pci_dev * dev,int where,u8 value)144 irongate_write_config_byte(struct pci_dev *dev, int where, u8 value)
145 {
146 unsigned long addr;
147 unsigned char type1;
148
149 if (mk_conf_addr(dev, where, &addr, &type1))
150 return PCIBIOS_DEVICE_NOT_FOUND;
151
152 __kernel_stb(value, *(vucp)addr);
153 mb();
154 __kernel_ldbu(*(vucp)addr);
155 return PCIBIOS_SUCCESSFUL;
156 }
157
158 static int
irongate_write_config_word(struct pci_dev * dev,int where,u16 value)159 irongate_write_config_word(struct pci_dev *dev, int where, u16 value)
160 {
161 unsigned long addr;
162 unsigned char type1;
163
164 if (mk_conf_addr(dev, where, &addr, &type1))
165 return PCIBIOS_DEVICE_NOT_FOUND;
166
167 __kernel_stw(value, *(vusp)addr);
168 mb();
169 __kernel_ldwu(*(vusp)addr);
170 return PCIBIOS_SUCCESSFUL;
171 }
172
173 static int
irongate_write_config_dword(struct pci_dev * dev,int where,u32 value)174 irongate_write_config_dword(struct pci_dev *dev, int where, u32 value)
175 {
176 unsigned long addr;
177 unsigned char type1;
178
179 if (mk_conf_addr(dev, where, &addr, &type1))
180 return PCIBIOS_DEVICE_NOT_FOUND;
181
182 *(vuip)addr = value;
183 mb();
184 *(vuip)addr;
185 return PCIBIOS_SUCCESSFUL;
186 }
187
188
189 struct pci_ops irongate_pci_ops =
190 {
191 read_byte: irongate_read_config_byte,
192 read_word: irongate_read_config_word,
193 read_dword: irongate_read_config_dword,
194 write_byte: irongate_write_config_byte,
195 write_word: irongate_write_config_word,
196 write_dword: irongate_write_config_dword
197 };
198
199 int
irongate_pci_clr_err(void)200 irongate_pci_clr_err(void)
201 {
202 unsigned int nmi_ctl=0;
203 unsigned int IRONGATE_jd;
204
205 again:
206 IRONGATE_jd = IRONGATE0->stat_cmd;
207 printk("Iron stat_cmd %x\n", IRONGATE_jd);
208 IRONGATE0->stat_cmd = IRONGATE_jd; /* write again clears error bits */
209 mb();
210 IRONGATE_jd = IRONGATE0->stat_cmd; /* re-read to force write */
211
212 IRONGATE_jd = *IronECC;
213 printk("Iron ECC %x\n", IRONGATE_jd);
214 *IronECC = IRONGATE_jd; /* write again clears error bits */
215 mb();
216 IRONGATE_jd = *IronECC; /* re-read to force write */
217
218 /* Clear ALI NMI */
219 nmi_ctl = inb(0x61);
220 nmi_ctl |= 0x0c;
221 outb(nmi_ctl, 0x61);
222 nmi_ctl &= ~0x0c;
223 outb(nmi_ctl, 0x61);
224
225 IRONGATE_jd = *IronECC;
226 if (IRONGATE_jd & 0x300) goto again;
227
228 return 0;
229 }
230
231 #define IRONGATE_3GB 0xc0000000UL
232
233 /* On Albacore (aka UP1500) with 4Gb of RAM we have to reserve some
234 memory for PCI. At this point we just reserve memory above 3Gb. Most
235 of this memory will be freed after PCI setup is done. */
236 static void __init
albacore_init_arch(void)237 albacore_init_arch(void)
238 {
239 unsigned long memtop = max_low_pfn << PAGE_SHIFT;
240 unsigned long pci_mem = (memtop + 0x1000000UL) & ~0xffffffUL;
241 struct percpu_struct *cpu;
242 int pal_rev, pal_var;
243
244 cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
245 pal_rev = cpu->pal_revision & 0xffff;
246 pal_var = (cpu->pal_revision >> 16) & 0xff;
247
248 /* Consoles earlier than A5.6-18 (OSF PALcode v1.62-2) set up
249 the CPU incorrectly (leave speculative stores enabled),
250 which causes memory corruption under certain conditions.
251 Issue a warning for such consoles. */
252 if (alpha_using_srm &&
253 (pal_rev < 0x13e || (pal_rev == 0x13e && pal_var < 2)))
254 printk(KERN_WARNING "WARNING! Upgrade to SRM A5.6-19 "
255 "or later\n");
256
257 if (pci_mem > IRONGATE_3GB)
258 pci_mem = IRONGATE_3GB;
259 IRONGATE0->pci_mem = pci_mem;
260 alpha_mv.min_mem_address = pci_mem;
261 if (memtop > pci_mem) {
262 #ifdef CONFIG_BLK_DEV_INITRD
263 extern unsigned long initrd_start, initrd_end;
264 extern void *move_initrd(unsigned long);
265
266 /* Move the initrd out of the way. */
267 if (initrd_end && __pa(initrd_end) > pci_mem) {
268 unsigned long size;
269
270 size = initrd_end - initrd_start;
271 free_bootmem(__pa(initrd_start), PAGE_ALIGN(size));
272 if (!move_initrd(pci_mem))
273 printk("irongate_init_arch: initrd too big "
274 "(%ldK)\ndisabling initrd\n",
275 size / 1024);
276 }
277 #endif
278 reserve_bootmem(pci_mem, memtop - pci_mem);
279 printk("irongate_init_arch: temporarily reserving "
280 "region %08lx-%08lx for PCI\n", pci_mem, memtop - 1);
281 }
282 }
283
284 static void __init
irongate_setup_agp(void)285 irongate_setup_agp(void)
286 {
287 /* Disable the GART window. AGPGART doesn't work due to yet
288 unresolved memory coherency issues... */
289 IRONGATE0->agpva = IRONGATE0->agpva & ~0xf;
290 alpha_agpgart_size = 0;
291 }
292
293 void __init
irongate_init_arch(void)294 irongate_init_arch(void)
295 {
296 struct pci_controller *hose;
297 int amd761 = (IRONGATE0->dev_vendor >> 16) > 0x7006; /* Albacore? */
298
299 IronECC = amd761 ? &IRONGATE0->bacsr54_eccms761 : &IRONGATE0->dramms;
300
301 irongate_pci_clr_err();
302
303 if (amd761)
304 albacore_init_arch();
305
306 irongate_setup_agp();
307
308 /*
309 * Create our single hose.
310 */
311
312 pci_isa_hose = hose = alloc_pci_controller();
313 hose->io_space = &ioport_resource;
314 hose->mem_space = &iomem_resource;
315 hose->index = 0;
316
317 /* This is for userland consumption. For some reason, the 40-bit
318 PIO bias that we use in the kernel through KSEG didn't work for
319 the page table based user mappings. So make sure we get the
320 43-bit PIO bias. */
321 hose->sparse_mem_base = 0;
322 hose->sparse_io_base = 0;
323 hose->dense_mem_base
324 = (IRONGATE_MEM & 0xffffffffff) | 0x80000000000;
325 hose->dense_io_base
326 = (IRONGATE_IO & 0xffffffffff) | 0x80000000000;
327
328 hose->sg_isa = hose->sg_pci = NULL;
329 __direct_map_base = 0;
330 __direct_map_size = 0xffffffff;
331 }
332
333 /*
334 * IO map and AGP support
335 */
336 #include <linux/vmalloc.h>
337 #include <linux/agp_backend.h>
338 #include <linux/agpgart.h>
339 #include <asm/pgalloc.h>
340
341 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
342 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr))
343
344 #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
345 #define GET_GATT(addr) (gatt_pages[GET_PAGE_DIR_IDX(addr)])
346
347 unsigned long
irongate_ioremap(unsigned long addr,unsigned long size)348 irongate_ioremap(unsigned long addr, unsigned long size)
349 {
350 struct vm_struct *area;
351 unsigned long vaddr;
352 unsigned long baddr, last;
353 u32 *mmio_regs, *gatt_pages, *cur_gatt, pte;
354 unsigned long gart_bus_addr;
355
356 if (!alpha_agpgart_size)
357 return addr + IRONGATE_MEM;
358
359 gart_bus_addr = (unsigned long)IRONGATE0->bar0 &
360 PCI_BASE_ADDRESS_MEM_MASK;
361
362 /*
363 * Check for within the AGP aperture...
364 */
365 do {
366 /*
367 * Check the AGP area
368 */
369 if (addr >= gart_bus_addr && addr + size - 1 <
370 gart_bus_addr + alpha_agpgart_size)
371 break;
372
373 /*
374 * Not found - assume legacy ioremap
375 */
376 return addr + IRONGATE_MEM;
377 } while(0);
378
379 mmio_regs = (u32 *)(((unsigned long)IRONGATE0->bar1 &
380 PCI_BASE_ADDRESS_MEM_MASK) + IRONGATE_MEM);
381
382 gatt_pages = (u32 *)(phys_to_virt(mmio_regs[1])); /* FIXME */
383
384 /*
385 * Adjust the limits (mappings must be page aligned)
386 */
387 if (addr & ~PAGE_MASK) {
388 printk("AGP ioremap failed... addr not page aligned (0x%lx)\n",
389 addr);
390 return addr + IRONGATE_MEM;
391 }
392 last = addr + size - 1;
393 size = PAGE_ALIGN(last) - addr;
394
395 #if 0
396 printk("irongate_ioremap(0x%lx, 0x%lx)\n", addr, size);
397 printk("irongate_ioremap: gart_bus_addr 0x%lx\n", gart_bus_addr);
398 printk("irongate_ioremap: gart_aper_size 0x%lx\n", gart_aper_size);
399 printk("irongate_ioremap: mmio_regs %p\n", mmio_regs);
400 printk("irongate_ioremap: gatt_pages %p\n", gatt_pages);
401
402 for(baddr = addr; baddr <= last; baddr += PAGE_SIZE)
403 {
404 cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
405 pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
406 printk("irongate_ioremap: cur_gatt %p pte 0x%x\n",
407 cur_gatt, pte);
408 }
409 #endif
410
411 /*
412 * Map it
413 */
414 area = get_vm_area(size, VM_IOREMAP);
415 if (!area) return (unsigned long)NULL;
416
417 for(baddr = addr, vaddr = (unsigned long)area->addr;
418 baddr <= last;
419 baddr += PAGE_SIZE, vaddr += PAGE_SIZE)
420 {
421 cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
422 pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
423
424 if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
425 pte, PAGE_SIZE, 0)) {
426 printk("AGP ioremap: FAILED to map...\n");
427 vfree(area->addr);
428 return (unsigned long)NULL;
429 }
430 }
431
432 flush_tlb_all();
433
434 vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);
435 #if 0
436 printk("irongate_ioremap(0x%lx, 0x%lx) returning 0x%lx\n",
437 addr, size, vaddr);
438 #endif
439 return vaddr;
440 }
441
442 void
irongate_iounmap(unsigned long addr)443 irongate_iounmap(unsigned long addr)
444 {
445 if (((long)addr >> 41) == -2)
446 return; /* kseg map, nothing to do */
447 if (addr) return vfree((void *)(PAGE_MASK & addr));
448 }
449