patch-2.4.21 linux-2.4.21/arch/alpha/kernel/core_irongate.c
Next file: linux-2.4.21/arch/alpha/kernel/core_marvel.c
Previous file: linux-2.4.21/arch/alpha/kernel/core_cia.c
Back to the patch index
Back to the overall index
- Lines: 413
- Date:
2003-06-13 07:51:29.000000000 -0700
- Orig file:
linux-2.4.20/arch/alpha/kernel/core_irongate.c
- Orig date:
2001-09-13 15:21:32.000000000 -0700
diff -urN linux-2.4.20/arch/alpha/kernel/core_irongate.c linux-2.4.21/arch/alpha/kernel/core_irongate.c
@@ -25,13 +25,11 @@
#include <asm/core_irongate.h>
#undef __EXTERN_INLINE
+#include <linux/bootmem.h>
+
#include "proto.h"
#include "pci_impl.h"
-#undef DEBUG_IRONGATE /* define to enable verbose Irongate debug */
-
-#define IRONGATE_DEFAULT_AGP_APER_SIZE (256*1024*1024) /* 256MB */
-
/*
* BIOS32-style PCI interface:
*/
@@ -44,6 +42,7 @@
# define DBG_CFG(args)
#endif
+igcsr32 *IronECC;
/*
* Given a bus, device, and function number, compute resulting
@@ -197,143 +196,6 @@
write_dword: irongate_write_config_dword
};
-#ifdef DEBUG_IRONGATE
-static void
-irongate_register_dump(const char *function_name)
-{
- printk("%s: Irongate registers:\n"
- "\tFunction 0:\n"
- "\tdev_vendor\t0x%08x\n"
- "\tstat_cmd\t0x%08x\n"
- "\tclass\t\t0x%08x\n"
- "\tlatency\t\t0x%08x\n"
- "\tbar0\t\t0x%08x\n"
- "\tbar1\t\t0x%08x\n"
- "\tbar2\t\t0x%08x\n"
- "\trsrvd0[0]\t0x%08x\n"
- "\trsrvd0[1]\t0x%08x\n"
- "\trsrvd0[2]\t0x%08x\n"
- "\trsrvd0[3]\t0x%08x\n"
- "\trsrvd0[4]\t0x%08x\n"
- "\trsrvd0[5]\t0x%08x\n"
- "\tcapptr\t\t0x%08x\n"
- "\trsrvd1[0]\t0x%08x\n"
- "\trsrvd1[1]\t0x%08x\n"
- "\tbacsr10\t\t0x%08x\n"
- "\tbacsr32\t\t0x%08x\n"
- "\tbacsr54\t\t0x%08x\n"
- "\trsrvd2[0]\t0x%08x\n"
- "\tdrammap\t\t0x%08x\n"
- "\tdramtm\t\t0x%08x\n"
- "\tdramms\t\t0x%08x\n"
- "\trsrvd3[0]\t0x%08x\n"
- "\tbiu0\t\t0x%08x\n"
- "\tbiusip\t\t0x%08x\n"
- "\trsrvd4[0]\t0x%08x\n"
- "\trsrvd4[1]\t0x%08x\n"
- "\tmro\t\t0x%08x\n"
- "\trsrvd5[0]\t0x%08x\n"
- "\trsrvd5[1]\t0x%08x\n"
- "\trsrvd5[2]\t0x%08x\n"
- "\twhami\t\t0x%08x\n"
- "\tpciarb\t\t0x%08x\n"
- "\tpcicfg\t\t0x%08x\n"
- "\trsrvd6[0]\t0x%08x\n"
- "\trsrvd6[1]\t0x%08x\n"
- "\trsrvd6[2]\t0x%08x\n"
- "\trsrvd6[3]\t0x%08x\n"
- "\trsrvd6[4]\t0x%08x\n"
- "\tagpcap\t\t0x%08x\n"
- "\tagpstat\t\t0x%08x\n"
- "\tagpcmd\t\t0x%08x\n"
- "\tagpva\t\t0x%08x\n"
- "\tagpmode\t\t0x%08x\n"
-
- "\n\tFunction 1:\n"
- "\tdev_vendor:\t0x%08x\n"
- "\tcmd_status:\t0x%08x\n"
- "\trevid_etc :\t0x%08x\n"
- "\thtype_etc :\t0x%08x\n"
- "\trsrvd0[0] :\t0x%08x\n"
- "\trsrvd0[1] :\t0x%08x\n"
- "\tbus_nmbers:\t0x%08x\n"
- "\tio_baselim:\t0x%08x\n"
- "\tmem_bselim:\t0x%08x\n"
- "\tpf_baselib:\t0x%08x\n"
- "\trsrvd1[0] :\t0x%08x\n"
- "\trsrvd1[1] :\t0x%08x\n"
- "\tio_baselim:\t0x%08x\n"
- "\trsrvd2[0] :\t0x%08x\n"
- "\trsrvd2[1] :\t0x%08x\n"
- "\tinterrupt :\t0x%08x\n",
-
- function_name,
- IRONGATE0->dev_vendor,
- IRONGATE0->stat_cmd,
- IRONGATE0->class,
- IRONGATE0->latency,
- IRONGATE0->bar0,
- IRONGATE0->bar1,
- IRONGATE0->bar2,
- IRONGATE0->rsrvd0[0],
- IRONGATE0->rsrvd0[1],
- IRONGATE0->rsrvd0[2],
- IRONGATE0->rsrvd0[3],
- IRONGATE0->rsrvd0[4],
- IRONGATE0->rsrvd0[5],
- IRONGATE0->capptr,
- IRONGATE0->rsrvd1[0],
- IRONGATE0->rsrvd1[1],
- IRONGATE0->bacsr10,
- IRONGATE0->bacsr32,
- IRONGATE0->bacsr54,
- IRONGATE0->rsrvd2[0],
- IRONGATE0->drammap,
- IRONGATE0->dramtm,
- IRONGATE0->dramms,
- IRONGATE0->rsrvd3[0],
- IRONGATE0->biu0,
- IRONGATE0->biusip,
- IRONGATE0->rsrvd4[0],
- IRONGATE0->rsrvd4[1],
- IRONGATE0->mro,
- IRONGATE0->rsrvd5[0],
- IRONGATE0->rsrvd5[1],
- IRONGATE0->rsrvd5[2],
- IRONGATE0->whami,
- IRONGATE0->pciarb,
- IRONGATE0->pcicfg,
- IRONGATE0->rsrvd6[0],
- IRONGATE0->rsrvd6[1],
- IRONGATE0->rsrvd6[2],
- IRONGATE0->rsrvd6[3],
- IRONGATE0->rsrvd6[4],
- IRONGATE0->agpcap,
- IRONGATE0->agpstat,
- IRONGATE0->agpcmd,
- IRONGATE0->agpva,
- IRONGATE0->agpmode,
- IRONGATE1->dev_vendor,
- IRONGATE1->stat_cmd,
- IRONGATE1->class,
- IRONGATE1->htype,
- IRONGATE1->rsrvd0[0],
- IRONGATE1->rsrvd0[1],
- IRONGATE1->busnos,
- IRONGATE1->io_baselim_regs,
- IRONGATE1->mem_baselim,
- IRONGATE1->pfmem_baselim,
- IRONGATE1->rsrvd1[0],
- IRONGATE1->rsrvd1[1],
- IRONGATE1->io_baselim,
- IRONGATE1->rsrvd2[0],
- IRONGATE1->rsrvd2[1],
- IRONGATE1->interrupt );
-}
-#else
-#define irongate_register_dump(x)
-#endif
-
int
irongate_pci_clr_err(void)
{
@@ -347,11 +209,11 @@
mb();
IRONGATE_jd = IRONGATE0->stat_cmd; /* re-read to force write */
- IRONGATE_jd = IRONGATE0->dramms;
- printk("Iron dramms %x\n", IRONGATE_jd);
- IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */
+ IRONGATE_jd = *IronECC;
+ printk("Iron ECC %x\n", IRONGATE_jd);
+ *IronECC = IRONGATE_jd; /* write again clears error bits */
mb();
- IRONGATE_jd = IRONGATE0->dramms; /* re-read to force write */
+ IRONGATE_jd = *IronECC; /* re-read to force write */
/* Clear ALI NMI */
nmi_ctl = inb(0x61);
@@ -360,28 +222,88 @@
nmi_ctl &= ~0x0c;
outb(nmi_ctl, 0x61);
- IRONGATE_jd = IRONGATE0->dramms;
+ IRONGATE_jd = *IronECC;
if (IRONGATE_jd & 0x300) goto again;
return 0;
}
+#define IRONGATE_3GB 0xc0000000UL
+
+/* On Albacore (aka UP1500) with 4Gb of RAM we have to reserve some
+ memory for PCI. At this point we just reserve memory above 3Gb. Most
+ of this memory will be freed after PCI setup is done. */
+static void __init
+albacore_init_arch(void)
+{
+ unsigned long memtop = max_low_pfn << PAGE_SHIFT;
+ unsigned long pci_mem = (memtop + 0x1000000UL) & ~0xffffffUL;
+ struct percpu_struct *cpu;
+ int pal_rev, pal_var;
+
+ cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
+ pal_rev = cpu->pal_revision & 0xffff;
+ pal_var = (cpu->pal_revision >> 16) & 0xff;
+
+ /* Consoles earlier than A5.6-18 (OSF PALcode v1.62-2) set up
+ the CPU incorrectly (leave speculative stores enabled),
+ which causes memory corruption under certain conditions.
+ Issue a warning for such consoles. */
+ if (alpha_using_srm &&
+ (pal_rev < 0x13e || (pal_rev == 0x13e && pal_var < 2)))
+ printk(KERN_WARNING "WARNING! Upgrade to SRM A5.6-19 "
+ "or later\n");
+
+ if (pci_mem > IRONGATE_3GB)
+ pci_mem = IRONGATE_3GB;
+ IRONGATE0->pci_mem = pci_mem;
+ alpha_mv.min_mem_address = pci_mem;
+ if (memtop > pci_mem) {
+#ifdef CONFIG_BLK_DEV_INITRD
+ extern unsigned long initrd_start, initrd_end;
+ extern void *move_initrd(unsigned long);
+
+ /* Move the initrd out of the way. */
+ if (initrd_end && __pa(initrd_end) > pci_mem) {
+ unsigned long size;
+
+ size = initrd_end - initrd_start;
+ free_bootmem(__pa(initrd_start), PAGE_ALIGN(size));
+ if (!move_initrd(pci_mem))
+ printk("irongate_init_arch: initrd too big "
+ "(%ldK)\ndisabling initrd\n",
+ size / 1024);
+ }
+#endif
+ reserve_bootmem(pci_mem, memtop - pci_mem);
+ printk("irongate_init_arch: temporarily reserving "
+ "region %08lx-%08lx for PCI\n", pci_mem, memtop - 1);
+ }
+}
+
+static void __init
+irongate_setup_agp(void)
+{
+ /* Disable the GART window. AGPGART doesn't work due to yet
+ unresolved memory coherency issues... */
+ IRONGATE0->agpva = IRONGATE0->agpva & ~0xf;
+ alpha_agpgart_size = 0;
+}
+
void __init
irongate_init_arch(void)
{
struct pci_controller *hose;
+ int amd761 = (IRONGATE0->dev_vendor >> 16) > 0x7006; /* Albacore? */
+
+ IronECC = amd761 ? &IRONGATE0->bacsr54_eccms761 : &IRONGATE0->dramms;
- IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100;
irongate_pci_clr_err();
- irongate_register_dump(__FUNCTION__);
- /*
- * HACK: set AGP aperture size to 256MB.
- * This should really be changed during PCI probe, when the
- * size of the aperture the AGP card wants is known.
- */
- printk("irongate_init_arch: AGPVA was 0x%x\n", IRONGATE0->agpva);
- IRONGATE0->agpva = (IRONGATE0->agpva & ~0x0000000f) | 0x00000007;
+ if (amd761)
+ albacore_init_arch();
+
+ irongate_setup_agp();
/*
* Create our single hose.
@@ -412,88 +334,9 @@
* IO map and AGP support
*/
#include <linux/vmalloc.h>
-#include <asm/pgalloc.h>
-
-static inline void
-irongate_remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- if (address >= end)
- BUG();
- do {
- if (!pte_none(*pte)) {
- printk("irongate_remap_area_pte: page already exists\n");
- BUG();
- }
- set_pte(pte,
- mk_pte_phys(phys_addr,
- __pgprot(_PAGE_VALID | _PAGE_ASM |
- _PAGE_KRE | _PAGE_KWE | flags)));
- address += PAGE_SIZE;
- phys_addr += PAGE_SIZE;
- pte++;
- } while (address && (address < end));
-}
-
-static inline int
-irongate_remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- phys_addr -= address;
- if (address >= end)
- BUG();
- do {
- pte_t * pte = pte_alloc(&init_mm, pmd, address);
- if (!pte)
- return -ENOMEM;
- irongate_remap_area_pte(pte, address, end - address,
- address + phys_addr, flags);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
-}
-
-static int
-irongate_remap_area_pages(unsigned long address, unsigned long phys_addr,
- unsigned long size, unsigned long flags)
-{
- pgd_t * dir;
- unsigned long end = address + size;
-
- phys_addr -= address;
- dir = pgd_offset(&init_mm, address);
- flush_cache_all();
- if (address >= end)
- BUG();
- do {
- pmd_t *pmd;
- pmd = pmd_alloc(&init_mm, dir, address);
- if (!pmd)
- return -ENOMEM;
- if (irongate_remap_area_pmd(pmd, address, end - address,
- phys_addr + address, flags))
- return -ENOMEM;
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
- return 0;
-}
-
#include <linux/agp_backend.h>
#include <linux/agpgart.h>
+#include <asm/pgalloc.h>
#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr))
@@ -508,15 +351,13 @@
unsigned long vaddr;
unsigned long baddr, last;
u32 *mmio_regs, *gatt_pages, *cur_gatt, pte;
- unsigned long gart_bus_addr, gart_aper_size;
+ unsigned long gart_bus_addr;
- gart_bus_addr = (unsigned long)IRONGATE0->bar0 &
- PCI_BASE_ADDRESS_MEM_MASK;
-
- if (!gart_bus_addr) /* FIXME - there must be a better way!!! */
+ if (!alpha_agpgart_size)
return addr + IRONGATE_MEM;
- gart_aper_size = IRONGATE_DEFAULT_AGP_APER_SIZE; /* FIXME */
+ gart_bus_addr = (unsigned long)IRONGATE0->bar0 &
+ PCI_BASE_ADDRESS_MEM_MASK;
/*
* Check for within the AGP aperture...
@@ -526,7 +367,7 @@
* Check the AGP area
*/
if (addr >= gart_bus_addr && addr + size - 1 <
- gart_bus_addr + gart_aper_size)
+ gart_bus_addr + alpha_agpgart_size)
break;
/*
@@ -580,8 +421,8 @@
cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
- if (irongate_remap_area_pages(VMALLOC_VMADDR(vaddr),
- pte, PAGE_SIZE, 0)) {
+ if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
+ pte, PAGE_SIZE, 0)) {
printk("AGP ioremap: FAILED to map...\n");
vfree(area->addr);
return (unsigned long)NULL;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)