2 * linux/arch/alpha/kernel/core_irongate.c
4 * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
6 * Copyright (C) 1999 Alpha Processor, Inc.,
7 * (David Daniel, Stig Telfer, Soohoon Lee)
9 * Code common to all IRONGATE core logic chips.
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>
18 #include <asm/ptrace.h>
19 #include <asm/system.h>
21 #include <asm/hwrpb.h>
23 #define __EXTERN_INLINE inline
25 #include <asm/core_irongate.h>
26 #undef __EXTERN_INLINE
28 #include <linux/bootmem.h>
34 * BIOS32-style PCI interface:
37 #define DEBUG_CONFIG 0
40 # define DBG_CFG(args) printk args
42 # define DBG_CFG(args)
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.
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
60 * if (bus = addr[23:16]) == 0
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
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
74 * The function number selects which function of a multi-function device
75 * (e.g., SCSI and Ethernet).
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
83 mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
87 u8 bus = dev->bus->number;
88 u8 device_fn = dev->devfn;
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));
96 addr = (bus << 16) | (device_fn << 8) | where;
97 addr |= IRONGATE_CONF;
100 DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
105 irongate_read_config_byte(struct pci_dev *dev, int where, u8 *value)
110 if (mk_conf_addr(dev, where, &addr, &type1))
111 return PCIBIOS_DEVICE_NOT_FOUND;
113 *value = __kernel_ldbu(*(vucp)addr);
114 return PCIBIOS_SUCCESSFUL;
118 irongate_read_config_word(struct pci_dev *dev, int where, u16 *value)
123 if (mk_conf_addr(dev, where, &addr, &type1))
124 return PCIBIOS_DEVICE_NOT_FOUND;
126 *value = __kernel_ldwu(*(vusp)addr);
127 return PCIBIOS_SUCCESSFUL;
131 irongate_read_config_dword(struct pci_dev *dev, int where, u32 *value)
136 if (mk_conf_addr(dev, where, &addr, &type1))
137 return PCIBIOS_DEVICE_NOT_FOUND;
139 *value = *(vuip)addr;
140 return PCIBIOS_SUCCESSFUL;
144 irongate_write_config_byte(struct pci_dev *dev, int where, u8 value)
149 if (mk_conf_addr(dev, where, &addr, &type1))
150 return PCIBIOS_DEVICE_NOT_FOUND;
152 __kernel_stb(value, *(vucp)addr);
154 __kernel_ldbu(*(vucp)addr);
155 return PCIBIOS_SUCCESSFUL;
159 irongate_write_config_word(struct pci_dev *dev, int where, u16 value)
164 if (mk_conf_addr(dev, where, &addr, &type1))
165 return PCIBIOS_DEVICE_NOT_FOUND;
167 __kernel_stw(value, *(vusp)addr);
169 __kernel_ldwu(*(vusp)addr);
170 return PCIBIOS_SUCCESSFUL;
174 irongate_write_config_dword(struct pci_dev *dev, int where, u32 value)
179 if (mk_conf_addr(dev, where, &addr, &type1))
180 return PCIBIOS_DEVICE_NOT_FOUND;
185 return PCIBIOS_SUCCESSFUL;
189 struct pci_ops irongate_pci_ops =
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
200 irongate_pci_clr_err(void)
202 unsigned int nmi_ctl=0;
203 unsigned int IRONGATE_jd;
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 */
210 IRONGATE_jd = IRONGATE0->stat_cmd; /* re-read to force write */
212 IRONGATE_jd = *IronECC;
213 printk("Iron ECC %x\n", IRONGATE_jd);
214 *IronECC = IRONGATE_jd; /* write again clears error bits */
216 IRONGATE_jd = *IronECC; /* re-read to force write */
225 IRONGATE_jd = *IronECC;
226 if (IRONGATE_jd & 0x300) goto again;
231 #define IRONGATE_3GB 0xc0000000UL
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. */
237 albacore_init_arch(void)
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;
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;
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 "
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);
266 /* Move the initrd out of the way. */
267 if (initrd_end && __pa(initrd_end) > pci_mem) {
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",
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);
285 irongate_setup_agp(void)
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;
294 irongate_init_arch(void)
296 struct pci_controller *hose;
297 int amd761 = (IRONGATE0->dev_vendor >> 16) > 0x7006; /* Albacore? */
299 IronECC = amd761 ? &IRONGATE0->bacsr54_eccms761 : &IRONGATE0->dramms;
301 irongate_pci_clr_err();
304 albacore_init_arch();
306 irongate_setup_agp();
309 * Create our single hose.
312 pci_isa_hose = hose = alloc_pci_controller();
313 hose->io_space = &ioport_resource;
314 hose->mem_space = &iomem_resource;
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
321 hose->sparse_mem_base = 0;
322 hose->sparse_io_base = 0;
324 = (IRONGATE_MEM & 0xffffffffff) | 0x80000000000;
326 = (IRONGATE_IO & 0xffffffffff) | 0x80000000000;
328 hose->sg_isa = hose->sg_pci = NULL;
329 __direct_map_base = 0;
330 __direct_map_size = 0xffffffff;
334 * IO map and AGP support
336 #include <linux/vmalloc.h>
337 #include <linux/agp_backend.h>
338 #include <linux/agpgart.h>
339 #include <asm/pgalloc.h>
341 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
342 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr))
344 #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
345 #define GET_GATT(addr) (gatt_pages[GET_PAGE_DIR_IDX(addr)])
348 irongate_ioremap(unsigned long addr, unsigned long size)
350 struct vm_struct *area;
352 unsigned long baddr, last;
353 u32 *mmio_regs, *gatt_pages, *cur_gatt, pte;
354 unsigned long gart_bus_addr;
356 if (!alpha_agpgart_size)
357 return addr + IRONGATE_MEM;
359 gart_bus_addr = (unsigned long)IRONGATE0->bar0 &
360 PCI_BASE_ADDRESS_MEM_MASK;
363 * Check for within the AGP aperture...
369 if (addr >= gart_bus_addr && addr + size - 1 <
370 gart_bus_addr + alpha_agpgart_size)
374 * Not found - assume legacy ioremap
376 return addr + IRONGATE_MEM;
379 mmio_regs = (u32 *)(((unsigned long)IRONGATE0->bar1 &
380 PCI_BASE_ADDRESS_MEM_MASK) + IRONGATE_MEM);
382 gatt_pages = (u32 *)(phys_to_virt(mmio_regs[1])); /* FIXME */
385 * Adjust the limits (mappings must be page aligned)
387 if (addr & ~PAGE_MASK) {
388 printk("AGP ioremap failed... addr not page aligned (0x%lx)\n",
390 return addr + IRONGATE_MEM;
392 last = addr + size - 1;
393 size = PAGE_ALIGN(last) - addr;
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);
402 for(baddr = addr; baddr <= last; baddr += PAGE_SIZE)
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",
414 area = get_vm_area(size, VM_IOREMAP);
415 if (!area) return (unsigned long)NULL;
417 for(baddr = addr, vaddr = (unsigned long)area->addr;
419 baddr += PAGE_SIZE, vaddr += PAGE_SIZE)
421 cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
422 pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
424 if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
425 pte, PAGE_SIZE, 0)) {
426 printk("AGP ioremap: FAILED to map...\n");
428 return (unsigned long)NULL;
434 vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);
436 printk("irongate_ioremap(0x%lx, 0x%lx) returning 0x%lx\n",
443 irongate_iounmap(unsigned long addr)
445 if (((long)addr >> 41) == -2)
446 return; /* kseg map, nothing to do */
447 if (addr) return vfree((void *)(PAGE_MASK & addr));