1/*
2 * setup.c
3 *
4 * Carsten Langgaard, carstenl@mips.com
5 * Copyright (C) 1999 MIPS Technologies, Inc.  All rights reserved.
6 *
7 * Thomas Horsten <thh@lasat.com>
8 * Copyright (C) 2000 LASAT Networks A/S.
9 *
10 * ########################################################################
11 *
12 *  This program is free software; you can distribute it and/or modify it
13 *  under the terms of the GNU General Public License (Version 2) as
14 *  published by the Free Software Foundation.
15 *
16 *  This program is distributed in the hope it will be useful, but WITHOUT
17 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19 *  for more details.
20 *
21 *  You should have received a copy of the GNU General Public License along
22 *  with this program; if not, write to the Free Software Foundation, Inc.,
23 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
24 *
25 * ########################################################################
26 *
27 * Lasat specific setup.
28 */
29#include <linux/config.h>
30#include <linux/init.h>
31#include <linux/sched.h>
32#include <linux/pci.h>
33#include <linux/ide.h>
34
35#include <linux/interrupt.h>
36#include <asm/time.h>
37
38#include <asm/cpu.h>
39#include <asm/bootinfo.h>
40#include <asm/irq.h>
41#include <asm/lasat/lasat.h>
42
43#include <asm/lasat/lasat_mtd.h>
44#include <linux/serial.h>
45#include <asm/serial.h>
46#include <asm/lasat/serial.h>
47
48#if CONFIG_PICVUE
49#include <linux/notifier.h>
50#endif
51
52#include "ds1603.h"
53#include "at93c.h"
54#include <asm/lasat/ds1603.h>
55#include <asm/lasat/picvue.h>
56#include <asm/lasat/eeprom.h>
57
58int lasat_command_line = 0;
59void lasatint_init(void);
60
61#ifdef CONFIG_BLK_DEV_IDE
62extern struct ide_ops std_ide_ops;
63extern struct ide_ops *ide_ops;
64#endif
65
66extern char arcs_cmdline[CL_SIZE];
67
68extern void lasat_reboot_setup(void);
69extern void pcisetup(void);
70extern void edhac_init(void *, void *, void *);
71extern void addrflt_init(void);
72
73void __init bus_error_init(void) { /* nothing */ }
74
75struct lasat_misc lasat_misc_info[N_MACHTYPES] = {
76	{(void *)KSEG1ADDR(0x1c840000), (void *)KSEG1ADDR(0x1c800000), 2},
77	{(void *)KSEG1ADDR(0x11080000), (void *)KSEG1ADDR(0x11000000), 6}
78};
79
80struct lasat_misc *lasat_misc = NULL;
81
82#ifdef CONFIG_DS1603
83static struct ds_defs ds_defs[N_MACHTYPES] = {
84	{ (void *)DS1603_REG_100, (void *)DS1603_REG_100,
85		DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100,
86		DS1603_DATA_SHIFT_100, 0, 0 },
87	{ (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200,
88		DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200,
89		DS1603_DATA_READ_SHIFT_200, 1, 2000 }
90};
91#endif
92
93#ifdef CONFIG_PICVUE
94#include "picvue.h"
95static struct pvc_defs pvc_defs[N_MACHTYPES] = {
96	{ (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100,
97		PVC_E_100, PVC_RW_100, PVC_RS_100 },
98	{ (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200,
99		PVC_E_200, PVC_RW_200, PVC_RS_200 }
100};
101
102
103static int lasat_panic_event(struct notifier_block *this,
104			     unsigned long event, void *ptr)
105{
106	unsigned char *string = ptr;
107	if (string == NULL)
108		string = "Kernel Panic";
109	pvc_write_string(string, 0, 0);
110	if (strlen(string) > PVC_VISIBLE_CHARS)
111		pvc_write_string(&string[PVC_VISIBLE_CHARS], 0, 1);
112	return NOTIFY_DONE;
113}
114
115static struct notifier_block lasat_panic_block = {
116	lasat_panic_event,
117	NULL,
118	INT_MAX /* try to do it first */
119};
120#endif
121
122static int lasat_ide_default_irq(ide_ioreg_t base) {
123	return 0;
124}
125
126static ide_ioreg_t lasat_ide_default_io_base(int index) {
127	return 0;
128}
129
130static void lasat_time_init(void)
131{
132	mips_counter_frequency = lasat_board_info.li_cpu_hz / 2;
133}
134
135static void lasat_timer_setup(struct irqaction *irq)
136{
137
138	write_c0_compare(
139		read_c0_count() +
140		mips_counter_frequency / HZ);
141	change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5);
142}
143
144#define MIPS_CPU_TIMER_IRQ 7
145asmlinkage void lasat_timer_interrupt(struct pt_regs *regs)
146{
147	ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs);
148}
149
150void __init serial_init(void)
151{
152#ifdef CONFIG_SERIAL
153	struct serial_struct s;
154
155	memset(&s, 0, sizeof(s));
156
157	s.flags = STD_COM_FLAGS;
158	s.io_type = SERIAL_IO_MEM;
159
160	if (mips_machtype == MACH_LASAT_100) {
161		s.baud_base = LASAT_BASE_BAUD_100;
162		s.irq = LASATINT_UART_100;
163		s.iomem_reg_shift = LASAT_UART_REGS_SHIFT_100;
164		s.iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE_100);
165	} else {
166		s.baud_base = LASAT_BASE_BAUD_200;
167		s.irq = LASATINT_UART_200;
168		s.iomem_reg_shift = LASAT_UART_REGS_SHIFT_200;
169		s.iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE_200);
170	}
171
172	if (early_serial_setup(&s) != 0)
173		printk(KERN_ERR "Serial setup failed!\n");
174#endif
175}
176
177void __init lasat_setup(void)
178{
179	lasat_misc  = &lasat_misc_info[mips_machtype];
180#ifdef CONFIG_PICVUE
181	picvue = &pvc_defs[mips_machtype];
182	/* Set up panic notifier */
183
184	notifier_chain_register(&panic_notifier_list, &lasat_panic_block);
185#endif
186
187#ifdef CONFIG_BLK_DEV_IDE
188	ide_ops = &std_ide_ops;
189	ide_ops->ide_default_irq = &lasat_ide_default_irq;
190	ide_ops->ide_default_io_base = &lasat_ide_default_io_base;
191#endif
192
193	lasat_reboot_setup();
194
195	board_time_init = lasat_time_init;
196	board_timer_setup = lasat_timer_setup;
197
198#ifdef CONFIG_DS1603
199	ds1603 = &ds_defs[mips_machtype];
200	rtc_get_time = ds1603_read;
201	rtc_set_time = ds1603_set;
202#endif
203
204	serial_init();
205
206	/* Switch from prom exception handler to normal mode */
207	change_c0_status(ST0_BEV,0);
208}
209
210#ifdef CONFIG_LASAT_SERVICE
211/*
212 * Called by init() (just before starting user space init program)
213 */
214static int __init lasat_init(void)
215{
216	/* This is where we call service mode */
217	lasat_service();
218	for (;;) {}	/* We should never get here */
219
220	return 0;
221}
222
223__initcall(lasat_init);
224#endif
225
226unsigned long lasat_flash_partition_start(int partno)
227{
228	unsigned long dst;
229
230	switch (partno) {
231	case LASAT_MTD_BOOTLOADER:
232		dst = lasat_board_info.li_flash_service_base;
233		break;
234	case LASAT_MTD_SERVICE:
235		dst = lasat_board_info.li_flash_service_base + BOOTLOADER_SIZE;
236		break;
237	case LASAT_MTD_NORMAL:
238		dst = lasat_board_info.li_flash_normal_base;
239		break;
240	case LASAT_MTD_FS:
241		dst = lasat_board_info.li_flash_fs_base;
242		break;
243	case LASAT_MTD_CONFIG:
244		dst = lasat_board_info.li_flash_cfg_base;
245		break;
246	default:
247		dst = 0;
248		break;
249	}
250
251	return dst;
252}
253
254unsigned long lasat_flash_partition_size(int partno)
255{
256	unsigned long size;
257
258	switch (partno) {
259	case LASAT_MTD_BOOTLOADER:
260		size = BOOTLOADER_SIZE;
261		break;
262	case LASAT_MTD_SERVICE:
263		size = lasat_board_info.li_flash_service_size - BOOTLOADER_SIZE;
264		break;
265	case LASAT_MTD_NORMAL:
266		size = lasat_board_info.li_flash_normal_size;
267		break;
268	case LASAT_MTD_FS:
269		size = lasat_board_info.li_flash_fs_size;
270		break;
271	case LASAT_MTD_CONFIG:
272		size = lasat_board_info.li_flash_cfg_size;
273		break;
274	default:
275		size = 0;
276		break;
277	}
278
279	return size;
280}
281