Blame view
arch/mips/mti-malta/malta-init.c
9.57 KB
1da177e4c
|
1 |
/* |
aa0980b80
|
2 3 4 5 |
* Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc. * All rights reserved. * Authors: Carsten Langgaard <carstenl@mips.com> * Maciej W. Rozycki <macro@mips.com> |
1da177e4c
|
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
* * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * PROM library initialisation code. */ |
1da177e4c
|
22 23 24 |
#include <linux/init.h> #include <linux/string.h> #include <linux/kernel.h> |
1da177e4c
|
25 |
#include <asm/bootinfo.h> |
aa0980b80
|
26 27 |
#include <asm/gt64120.h> #include <asm/io.h> |
e01402b11
|
28 |
#include <asm/cacheflush.h> |
852fe3105
|
29 |
#include <asm/smp-ops.h> |
e01402b11
|
30 |
#include <asm/traps.h> |
aa0980b80
|
31 |
|
47b178bb6
|
32 |
#include <asm/gcmpregs.h> |
1da177e4c
|
33 34 |
#include <asm/mips-boards/prom.h> #include <asm/mips-boards/generic.h> |
1da177e4c
|
35 |
#include <asm/mips-boards/bonito64.h> |
aa0980b80
|
36 |
#include <asm/mips-boards/msc01_pci.h> |
1da177e4c
|
37 |
#include <asm/mips-boards/malta.h> |
1da177e4c
|
38 |
|
1da177e4c
|
39 40 41 42 43 44 45 46 |
int prom_argc; int *_prom_argv, *_prom_envp; /* * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. * This macro take care of sign extension, if running in 64-bit mode. */ #define prom_envp(index) ((char *)(long)_prom_envp[(index)]) |
982f6ffee
|
47 |
int init_debug; |
1da177e4c
|
48 |
|
d0cdfe242
|
49 |
static int mips_revision_corid; |
b72c05262
|
50 |
int mips_revision_sconid; |
1da177e4c
|
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
/* Bonito64 system controller register base. */ unsigned long _pcictrl_bonito; unsigned long _pcictrl_bonito_pcicfg; /* GT64120 system controller register base */ unsigned long _pcictrl_gt64120; /* MIPS System controller register base */ unsigned long _pcictrl_msc; char *prom_getenv(char *envname) { /* * Return a pointer to the given environment variable. * In 64-bit mode: we're using 64-bit pointers, but all pointers * in the PROM structures are only 32-bit, so we need some * workarounds, if we are running in 64-bit mode. */ int i, index=0; i = strlen(envname); while (prom_envp(index)) { if(strncmp(envname, prom_envp(index), i) == 0) { return(prom_envp(index+1)); } index += 2; } return NULL; } static inline unsigned char str2hexnum(unsigned char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; return 0; /* foo */ } static inline void str2eaddr(unsigned char *ea, unsigned char *str) { int i; for (i = 0; i < 6; i++) { unsigned char num; if((*str == '.') || (*str == ':')) str++; num = str2hexnum(*str++) << 4; num |= (str2hexnum(*str++)); ea[i] = num; } } int get_ethernet_addr(char *ethernet_addr) { char *ethaddr_str; ethaddr_str = prom_getenv("ethaddr"); if (!ethaddr_str) { printk("ethaddr not set in boot prom "); return -1; } str2eaddr(ethernet_addr, ethaddr_str); if (init_debug > 1) { int i; printk("get_ethernet_addr: "); for (i=0; i<5; i++) printk("%02x:", (unsigned char)*(ethernet_addr+i)); printk("%02x ", *(ethernet_addr+i)); } return 0; } #ifdef CONFIG_SERIAL_8250_CONSOLE static void __init console_config(void) { char console_string[40]; int baud = 0; char parity = '\0', bits = '\0', flow = '\0'; char *s; |
43e3c885d
|
139 |
if ((strstr(prom_getcmdline(), "console=")) == NULL) { |
1da177e4c
|
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
s = prom_getenv("modetty0"); if (s) { while (*s >= '0' && *s <= '9') baud = baud*10 + *s++ - '0'; if (*s == ',') s++; if (*s) parity = *s++; if (*s == ',') s++; if (*s) bits = *s++; if (*s == ',') s++; if (*s == 'h') flow = 'r'; } if (baud == 0) baud = 38400; if (parity != 'n' && parity != 'o' && parity != 'e') parity = 'n'; if (bits != '7' && bits != '8') bits = '8'; if (flow == '\0') flow = 'r'; |
49a89efbb
|
159 160 |
sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow); strcat(prom_getcmdline(), console_string); |
36a885306
|
161 162 |
pr_info("Config serial console:%s ", console_string); |
1da177e4c
|
163 164 165 |
} } #endif |
cd2675fba
|
166 |
static void __init mips_nmi_setup(void) |
e01402b11
|
167 168 169 170 171 172 173 174 175 176 |
{ void *base; extern char except_vec_nmi; base = cpu_has_veic ? (void *)(CAC_BASE + 0xa80) : (void *)(CAC_BASE + 0x380); memcpy(base, &except_vec_nmi, 0x80); flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); } |
33d69d2a7
|
177 |
static void __init mips_ejtag_setup(void) |
e01402b11
|
178 179 180 181 182 183 184 185 186 187 |
{ void *base; extern char except_vec_ejtag_debug; base = cpu_has_veic ? (void *)(CAC_BASE + 0xa00) : (void *)(CAC_BASE + 0x300); memcpy(base, &except_vec_ejtag_debug, 0x80); flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); } |
87353d8ac
|
188 |
extern struct plat_smp_ops msmtc_smp_ops; |
1da177e4c
|
189 190 191 192 193 194 195 |
void __init prom_init(void) { prom_argc = fw_arg0; _prom_argv = (int *) fw_arg1; _prom_envp = (int *) fw_arg2; mips_display_message("LINUX"); |
1da177e4c
|
196 197 198 199 200 201 202 203 204 |
/* * early setup of _pcictrl_bonito so that we can determine * the system controller on a CORE_EMUL board */ _pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE); mips_revision_corid = MIPS_REVISION_CORID; if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) { |
42a3b4f25
|
205 |
if (BONITO_PCIDID == 0x0001df53 || |
1da177e4c
|
206 207 208 209 210 |
BONITO_PCIDID == 0x0003df53) mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON; else mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC; } |
b72c05262
|
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
mips_revision_sconid = MIPS_REVISION_SCONID; if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) { switch (mips_revision_corid) { case MIPS_REVISION_CORID_QED_RM5261: case MIPS_REVISION_CORID_CORE_LV: case MIPS_REVISION_CORID_CORE_FPGA: case MIPS_REVISION_CORID_CORE_FPGAR2: mips_revision_sconid = MIPS_REVISION_SCON_GT64120; break; case MIPS_REVISION_CORID_CORE_EMUL_BON: case MIPS_REVISION_CORID_BONITO64: case MIPS_REVISION_CORID_CORE_20K: mips_revision_sconid = MIPS_REVISION_SCON_BONITO; break; case MIPS_REVISION_CORID_CORE_MSC: case MIPS_REVISION_CORID_CORE_FPGA2: |
b72c05262
|
228 |
case MIPS_REVISION_CORID_CORE_24K: |
308402445
|
229 230 231 232 |
/* * SOCit/ROCit support is essentially identical * but make an attempt to distinguish them */ |
b72c05262
|
233 234 |
mips_revision_sconid = MIPS_REVISION_SCON_SOCIT; break; |
308402445
|
235 236 237 238 |
case MIPS_REVISION_CORID_CORE_FPGA3: case MIPS_REVISION_CORID_CORE_FPGA4: case MIPS_REVISION_CORID_CORE_FPGA5: case MIPS_REVISION_CORID_CORE_EMUL_MSC: |
b72c05262
|
239 |
default: |
308402445
|
240 241 242 |
/* See above */ mips_revision_sconid = MIPS_REVISION_SCON_ROCIT; break; |
b72c05262
|
243 244 245 246 |
} } switch (mips_revision_sconid) { |
f76b7ea48
|
247 |
u32 start, map, mask, data; |
b72c05262
|
248 |
case MIPS_REVISION_SCON_GT64120: |
1da177e4c
|
249 250 251 252 253 254 255 256 257 258 259 260 |
/* * Setup the North bridge to do Master byte-lane swapping * when running in bigendian. */ _pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000); #ifdef CONFIG_CPU_LITTLE_ENDIAN GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | GT_PCI0_CMD_SBYTESWAP_BIT); #else GT_WRITE(GT_PCI0_CMD_OFS, 0); #endif |
aa0980b80
|
261 262 263 264 265 266 267 |
/* Fix up PCI I/O mapping if necessary (for Atlas). */ start = GT_READ(GT_PCI0IOLD_OFS); map = GT_READ(GT_PCI0IOREMAP_OFS); if ((start & map) != 0) { map &= ~start; GT_WRITE(GT_PCI0IOREMAP_OFS, map); } |
1da177e4c
|
268 |
|
1da177e4c
|
269 |
set_io_port_base(MALTA_GT_PORT_BASE); |
1da177e4c
|
270 |
break; |
b72c05262
|
271 |
case MIPS_REVISION_SCON_BONITO: |
1da177e4c
|
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
_pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE); /* * Disable Bonito IOBC. */ BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); /* * Setup the North bridge to do Master byte-lane swapping * when running in bigendian. */ #ifdef CONFIG_CPU_LITTLE_ENDIAN BONITO_BONGENCFG = BONITO_BONGENCFG & ~(BONITO_BONGENCFG_MSTRBYTESWAP | BONITO_BONGENCFG_BYTESWAP); #else BONITO_BONGENCFG = BONITO_BONGENCFG | BONITO_BONGENCFG_MSTRBYTESWAP | BONITO_BONGENCFG_BYTESWAP; #endif |
1da177e4c
|
294 |
set_io_port_base(MALTA_BONITO_PORT_BASE); |
1da177e4c
|
295 |
break; |
b72c05262
|
296 297 |
case MIPS_REVISION_SCON_SOCIT: case MIPS_REVISION_SCON_ROCIT: |
42a3b4f25
|
298 |
_pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); |
b72c05262
|
299 |
mips_pci_controller: |
aa0980b80
|
300 301 302 303 304 305 |
mb(); MSC_READ(MSC01_PCI_CFG, data); MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT); wmb(); /* Fix up lane swapping. */ |
1da177e4c
|
306 307 308 309 310 311 312 313 |
#ifdef CONFIG_CPU_LITTLE_ENDIAN MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP); #else MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF); #endif |
aa0980b80
|
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
/* Fix up target memory mapping. */ MSC_READ(MSC01_PCI_BAR0, mask); MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK); /* Don't handle target retries indefinitely. */ if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) == MSC01_PCI_CFG_MAXRTRY_MSK) data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK << MSC01_PCI_CFG_MAXRTRY_SHF)) | ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) << MSC01_PCI_CFG_MAXRTRY_SHF); wmb(); MSC_WRITE(MSC01_PCI_CFG, data); mb(); |
1da177e4c
|
329 |
|
1da177e4c
|
330 |
set_io_port_base(MALTA_MSC_PORT_BASE); |
1da177e4c
|
331 |
break; |
b72c05262
|
332 333 334 335 |
case MIPS_REVISION_SCON_SOCITSC: case MIPS_REVISION_SCON_SOCITSCP: _pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000); goto mips_pci_controller; |
1da177e4c
|
336 |
default: |
b72c05262
|
337 338 339 |
/* Unknown system controller */ mips_display_message("SC Error"); while (1); /* We die here... */ |
1da177e4c
|
340 |
} |
e01402b11
|
341 342 |
board_nmi_handler_setup = mips_nmi_setup; board_ejtag_handler_setup = mips_ejtag_setup; |
1da177e4c
|
343 344 345 346 347 |
prom_init_cmdline(); prom_meminit(); #ifdef CONFIG_SERIAL_8250_CONSOLE console_config(); #endif |
af3a1f6f4
|
348 349 |
/* Early detection of CMP support */ if (gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ)) |
852fe3105
|
350 351 352 353 354 |
if (!register_cmp_smp_ops()) return; if (!register_vsmp_smp_ops()) return; |
87353d8ac
|
355 356 357 |
#ifdef CONFIG_MIPS_MT_SMTC register_smp_ops(&msmtc_smp_ops); #endif |
1da177e4c
|
358 |
} |