11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IP32 basic setup
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * License.  See the file "COPYING" in the main directory of this archive
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for more details.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000 Harald Koerfgen
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002, 2003, 2005 Ilya A. Volynets
1054d0a216f40e060ba4265bb851cc36b3ca55d1a8Ralf Baechle * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/console.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mc146818rtc.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/param.h>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/bootinfo.h>
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mc146818-time.h>
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mipsregs.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mmu_context.h>
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/sgialib.h>
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/time.h>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/traps.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/ip32/crime.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/ip32/mace.h>
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/ip32/ip32_ints.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void ip32_be_init(void);
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void crime_init(void);
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SGI_O2MACE_ETH
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is taken care of in here 'cause they say using Arc later on is
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * problematic
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern char o2meth_eaddr[8];
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned char str2hexnum(unsigned char c)
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (c >= '0' && c <= '9')
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return c - '0';
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (c >= 'a' && c <= 'f')
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return c - 'a' + 10;
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0; /* foo */
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void str2eaddr(unsigned char *ea, unsigned char *str)
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < 6; i++) {
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned char num;
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(*str == ':')
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			str++;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		num = str2hexnum(*str++) << 4;
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		num |= (str2hexnum(*str++));
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ea[i] = num;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* An arbitrary time; this can be decreased if reliability looks good */
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WAIT_MS 10
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
684b550488f894c899aa54dc935c8fee47bca2b7dfRalf Baechlevoid __init plat_time_init(void)
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk(KERN_INFO "Calibrating system timer... ");
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	write_c0_count(0);
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	crime->timer = 0;
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (crime->timer < CRIME_MASTER_FREQ * WAIT_MS / 1000) ;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mips_hpt_frequency = read_c0_count() * 1000 / WAIT_MS;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("%d MHz CPU detected\n", mips_hpt_frequency * 2 / 1000000);
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
782925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechlevoid __init plat_mem_setup(void)
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	board_be_init = ip32_be_init;
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SGI_O2MACE_ETH
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		char *mac = ArcGetEnvironmentVariable("eaddr");
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		str2eaddr(o2meth_eaddr, mac);
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(CONFIG_SERIAL_CORE_CONSOLE)
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		char* con = ArcGetEnvironmentVariable("console");
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (con && *con == 'd') {
93599a89459f316499446fdb5c817a0a4835681baeDmitri Vorobiev			static char options[8] __initdata;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			char *baud = ArcGetEnvironmentVariable("dbaud");
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (baud)
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				strcpy(options, baud);
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			add_preferred_console("ttyS", *(con + 1) == '2' ? 1 : 0,
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					      baud ? options : NULL);
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
103