1 // SPDX-License-Identifier: GPL-2.0 1 2 /* 3 * ip22-mc.c: Routines for manipulating SGI Me 4 * 5 * Copyright (C) 1996 David S. Miller (davem@d 6 * Copyright (C) 1999 Andrew R. Baker (andrewb 7 * Copyright (C) 2003 Ladislav Michl (ladis@l 8 * Copyright (C) 2004 Peter Fuerst (pf@net. 9 */ 10 11 #include <linux/init.h> 12 #include <linux/export.h> 13 #include <linux/kernel.h> 14 #include <linux/memblock.h> 15 #include <linux/spinlock.h> 16 17 #include <asm/io.h> 18 #include <asm/bootinfo.h> 19 #include <asm/sgialib.h> 20 #include <asm/sgi/mc.h> 21 #include <asm/sgi/hpc3.h> 22 #include <asm/sgi/ip22.h> 23 24 struct sgimc_regs *sgimc; 25 26 EXPORT_SYMBOL(sgimc); 27 28 static inline unsigned long get_bank_addr(unsi 29 { 30 return (memconfig & SGIMC_MCONFIG_BASE 31 } 32 33 static inline unsigned long get_bank_size(unsi 34 { 35 return ((memconfig & SGIMC_MCONFIG_RMA 36 } 37 38 static inline unsigned int get_bank_config(int 39 { 40 unsigned int res = bank > 1 ? sgimc->m 41 return bank % 2 ? res & 0xffff : res > 42 } 43 44 #if defined(CONFIG_SGI_IP28) || defined(CONFIG 45 static void __init probe_memory(void) 46 { 47 /* prom detects all usable memory */ 48 } 49 #else 50 /* 51 * Detect installed memory, which PROM misses 52 */ 53 static void __init probe_memory(void) 54 { 55 unsigned long addr, size; 56 int i; 57 58 printk(KERN_INFO "MC: Probing memory c 59 for (i = 0; i < 4; i++) { 60 unsigned int tmp = get_bank_co 61 if (!(tmp & SGIMC_MCONFIG_BVAL 62 continue; 63 64 size = get_bank_size(tmp); 65 addr = get_bank_addr(tmp); 66 printk(KERN_INFO " bank%d: %3l 67 i, size / 1024 / 1024, 68 69 if (addr >= SGIMC_SEG1_BADDR) 70 memblock_add(addr, siz 71 } 72 } 73 #endif 74 75 void __init sgimc_init(void) 76 { 77 u32 tmp; 78 79 /* ioremap can't fail */ 80 sgimc = (struct sgimc_regs *) 81 ioremap(SGIMC_BASE, sizeof(str 82 83 printk(KERN_INFO "MC: SGI memory contr 84 (int) sgimc->systemid & SGIMC_S 85 86 /* Place the MC into a known state. T 87 * interrupts are first enabled etc. 88 */ 89 90 /* Step 0: Make sure we turn off the w 91 * still running (which might 92 * soft reboot). 93 */ 94 tmp = sgimc->cpuctrl0; 95 tmp &= ~SGIMC_CCTRL0_WDOG; 96 sgimc->cpuctrl0 = tmp; 97 98 /* Step 1: The CPU/GIO error status re 99 * up a new error status until 100 * cleared by the cpu. These 101 * cleared by writing any valu 102 */ 103 sgimc->cstat = sgimc->gstat = 0; 104 105 /* Step 2: Enable all parity checking 106 * zero. 107 */ 108 /* don't touch parity settings for IP2 109 tmp = sgimc->cpuctrl0; 110 #ifndef CONFIG_SGI_IP28 111 tmp |= SGIMC_CCTRL0_EPERRGIO | SGIMC_C 112 #endif 113 tmp |= SGIMC_CCTRL0_R4KNOCHKPARR; 114 sgimc->cpuctrl0 = tmp; 115 116 /* Step 3: Setup the MC write buffer d 117 * in cpu control register 1 i 118 */ 119 tmp = sgimc->cpuctrl1; 120 tmp &= ~0xf; 121 tmp |= 0xd; 122 sgimc->cpuctrl1 = tmp; 123 124 /* Step 4: Initialize the RPSS divider 125 * as it can correctly operate 126 * out as follows: 127 * 128 * --------------------------- 129 * | RESERVED | INCREMENT 130 * --------------------------- 131 * 31 16 15 132 * 133 * DIVIDER determines how ofte 134 * INCREMENT determines by how 135 * registers value increases a 136 * for IP22 we get INCREMENT=1 137 */ 138 sgimc->divider = 0x101; 139 140 /* Step 5: Initialize GIO64 arbitrator 141 * 142 * NOTE: HPC init code in sgihpc_init( 143 * we need to know Guiness vs. F 144 * revision on this machine. You 145 */ 146 147 /* First the basic invariants across a 148 tmp = sgimc->giopar & SGIMC_GIOPAR_GFX 149 tmp |= SGIMC_GIOPAR_HPC64; /* All 150 tmp |= SGIMC_GIOPAR_ONEBUS; /* Onl 151 152 if (ip22_is_fullhouse()) { 153 /* Fullhouse specific settings 154 if (SGIOC_SYSID_BOARDREV(sgioc 155 tmp |= SGIMC_GIOPAR_HP 156 tmp |= SGIMC_GIOPAR_PL 157 tmp |= SGIMC_GIOPAR_MA 158 tmp |= SGIMC_GIOPAR_RT 159 } else { 160 tmp |= SGIMC_GIOPAR_HP 161 tmp |= SGIMC_GIOPAR_PL 162 tmp |= SGIMC_GIOPAR_PL 163 tmp |= SGIMC_GIOPAR_MA 164 } 165 } else { 166 /* Guiness specific settings. 167 tmp |= SGIMC_GIOPAR_EISA64; 168 tmp |= SGIMC_GIOPAR_MASTEREISA 169 } 170 sgimc->giopar = tmp; /* poof */ 171 172 probe_memory(); 173 } 174 175 #ifdef CONFIG_SGI_IP28 176 void __init prom_cleanup(void) 177 { 178 u32 mconfig1; 179 unsigned long flags; 180 spinlock_t lock; 181 182 /* 183 * because ARCS accesses memory uncach 184 * isn't needed any longer, before we 185 * normal mode 186 */ 187 spin_lock_irqsave(&lock, flags); 188 mconfig1 = sgimc->mconfig1; 189 /* map ECC register */ 190 sgimc->mconfig1 = (mconfig1 & 0xffff00 191 iob(); 192 /* switch to normal mode */ 193 *(unsigned long *)PHYS_TO_XKSEG_UNCACH 194 iob(); 195 /* reduce WR_COL */ 196 sgimc->cmacc = (sgimc->cmacc & ~0xf) | 197 iob(); 198 /* restore old config */ 199 sgimc->mconfig1 = mconfig1; 200 iob(); 201 spin_unlock_irqrestore(&lock, flags); 202 } 203 #endif 204
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.