1/*
2 *  Copyright (C) 2004, 2005 by Thomas Koeller (thomas.koeller@baslerweb.com)
3 *  Based on the PMC-Sierra Yosemite board support by Ralf Baechle and
4 *  Manish Lachwani.
5 *
6 *  This program is free software; you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation; either version 2 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21#include <linux/init.h>
22#include <linux/sched.h>
23#include <linux/mm.h>
24#include <linux/delay.h>
25#include <linux/smp.h>
26#include <linux/module.h>
27#include <asm/io.h>
28#include <asm/pgtable.h>
29#include <asm/processor.h>
30#include <asm/reboot.h>
31#include <asm/system.h>
32#include <asm/bootinfo.h>
33#include <asm/string.h>
34
35#include <excite.h>
36
37/* This struct is used by Redboot to pass arguments to the kernel */
38typedef struct
39{
40	char *name;
41	char *val;
42} t_env_var;
43
44struct parmblock {
45	t_env_var memsize;
46	t_env_var modetty0;
47	t_env_var ethaddr;
48	t_env_var env_end;
49	char *argv[2];
50	char text[0];
51};
52
53static unsigned int prom_argc;
54static const char ** prom_argv;
55static const t_env_var * prom_env;
56
57static void prom_halt(void) __attribute__((noreturn));
58static void prom_exit(void) __attribute__((noreturn));
59
60
61
62const char *get_system_type(void)
63{
64	return "Basler eXcite";
65}
66
67/*
68 * Halt the system
69 */
70static void prom_halt(void)
71{
72	printk(KERN_NOTICE "\n** System halted.\n");
73	while (1)
74		asm volatile (
75			"\t.set\tmips3\n"
76			"\twait\n"
77			"\t.set\tmips0\n"
78		);
79}
80
81/*
82 * Reset the CPU and re-enter Redboot
83 */
84static void prom_exit(void)
85{
86	unsigned int i;
87	volatile unsigned char * const flg =
88		(volatile unsigned char *) (EXCITE_ADDR_FPGA + EXCITE_FPGA_DPR);
89
90	/* Clear the watchdog reset flag, set the reboot flag */
91	*flg &= ~0x01;
92	*flg |= 0x80;
93
94	for (i = 0; i < 10; i++) {
95		*(volatile unsigned char *)  (EXCITE_ADDR_FPGA + EXCITE_FPGA_SYSCTL) = 0x02;
96		iob();
97		mdelay(1000);
98	}
99
100	printk(KERN_NOTICE "Reset failed\n");
101	prom_halt();
102}
103
104static const char __init *prom_getenv(char *name)
105{
106	const t_env_var * p;
107	for (p = prom_env; p->name != NULL; p++)
108		if(strcmp(name, p->name) == 0)
109			break;
110	return p->val;
111}
112
113/*
114 * Init routine which accepts the variables from Redboot
115 */
116void __init prom_init(void)
117{
118	const struct parmblock * const pb = (struct parmblock *) fw_arg2;
119
120	prom_argc = fw_arg0;
121	prom_argv = (const char **) fw_arg1;
122	prom_env = &pb->memsize;
123
124	/* Callbacks for halt, restart */
125	_machine_restart = (void (*)(char *)) prom_exit;
126	_machine_halt = prom_halt;
127
128#ifdef CONFIG_32BIT
129	/* copy command line */
130	strcpy(arcs_cmdline, prom_argv[1]);
131	memsize = simple_strtol(prom_getenv("memsize"), NULL, 16);
132	strcpy(modetty, prom_getenv("modetty0"));
133#endif /* CONFIG_32BIT */
134
135#ifdef CONFIG_64BIT
136#	error 64 bit support not implemented
137#endif /* CONFIG_64BIT */
138
139	mips_machgroup = MACH_GROUP_TITAN;
140	mips_machtype = MACH_TITAN_EXCITE;
141}
142
143/* This is called from free_initmem(), so we need to provide it */
144void __init prom_free_prom_memory(void)
145{
146	/* Nothing to do */
147}
148