1 /*
2  * arch/xtensa/platforms/xt2000/setup.c
3  *
4  * Platform specific functions for the XT2000 board.
5  *
6  * Authors:	Chris Zankel <chris@zankel.net>
7  *		Joe Taylor <joe@tensilica.com>
8  *
9  * Copyright 2001 - 2004 Tensilica Inc.
10  *
11  * This program is free software; you can redistribute  it and/or modify it
12  * under  the terms of  the GNU General  Public License as published by the
13  * Free Software Foundation;  either version 2 of the  License, or (at your
14  * option) any later version.
15  *
16  */
17 #include <linux/stddef.h>
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/errno.h>
21 #include <linux/reboot.h>
22 #include <linux/kdev_t.h>
23 #include <linux/types.h>
24 #include <linux/major.h>
25 #include <linux/console.h>
26 #include <linux/delay.h>
27 #include <linux/stringify.h>
28 #include <linux/platform_device.h>
29 #include <linux/serial.h>
30 #include <linux/serial_8250.h>
31 
32 #include <asm/processor.h>
33 #include <asm/platform.h>
34 #include <asm/bootparam.h>
35 #include <platform/hardware.h>
36 #include <platform/serial.h>
37 
38 /* Assumes s points to an 8-chr string.  No checking for NULL. */
39 
40 static void led_print (int f, char *s)
41 {
42 	unsigned long* led_addr = (unsigned long*) (XT2000_LED_ADDR + 0xE0) + f;
43 	int i;
44 	for (i = f; i < 8; i++)
45 		if ((*led_addr++ = *s++) == 0)
46 		    break;
47 }
48 
49 void platform_halt(void)
50 {
51 	led_print (0, "  HALT  ");
52 	local_irq_disable();
53 	while (1);
54 }
55 
56 void platform_power_off(void)
57 {
58 	led_print (0, "POWEROFF");
59 	local_irq_disable();
60 	while (1);
61 }
62 
63 void platform_restart(void)
64 {
65 	/* Flush and reset the mmu, simulate a processor reset, and
66 	 * jump to the reset vector. */
67 
68 	__asm__ __volatile__ ("movi	a2, 15\n\t"
69 			      "wsr	a2, icountlevel\n\t"
70 			      "movi	a2, 0\n\t"
71 			      "wsr	a2, icount\n\t"
72 			      "wsr	a2, ibreakenable\n\t"
73 			      "wsr	a2, lcount\n\t"
74 			      "movi	a2, 0x1f\n\t"
75 			      "wsr	a2, ps\n\t"
76 			      "isync\n\t"
77 			      "jx	%0\n\t"
78 			      :
79 			      : "a" (XCHAL_RESET_VECTOR_VADDR)
80 			      : "a2"
81 			      );
82 
83 	/* control never gets here */
84 }
85 
86 void __init platform_setup(char** cmdline)
87 {
88 	led_print (0, "LINUX   ");
89 }
90 
91 /* early initialization */
92 
93 extern sysmem_info_t __initdata sysmem;
94 
95 void platform_init(bp_tag_t* first)
96 {
97 	/* Set default memory block if not provided by the bootloader. */
98 
99 	if (sysmem.nr_banks == 0) {
100 		sysmem.nr_banks = 1;
101 		sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START;
102 		sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START
103 				     + PLATFORM_DEFAULT_MEM_SIZE;
104 	}
105 }
106 
107 /* Heartbeat. Let the LED blink. */
108 
109 void platform_heartbeat(void)
110 {
111 	static int i=0, t = 0;
112 
113 	if (--t < 0)
114 	{
115 		t = 59;
116 		led_print(7, i ? ".": " ");
117 		i ^= 1;
118 	}
119 }
120 
121 //#define RS_TABLE_SIZE 2
122 //#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
123 
124 #define _SERIAL_PORT(_base,_irq)					\
125 {									\
126 	.mapbase	= (_base),					\
127 	.membase	= (void*)(_base),				\
128 	.irq		= (_irq),					\
129 	.uartclk	= DUART16552_XTAL_FREQ,				\
130 	.iotype		= UPIO_MEM,					\
131 	.flags		= UPF_BOOT_AUTOCONF,				\
132 	.regshift	= 2,						\
133 }
134 
135 static struct plat_serial8250_port xt2000_serial_data[] = {
136 #if XCHAL_HAVE_BE
137 	_SERIAL_PORT(DUART16552_1_ADDR + 3, DUART16552_1_INTNUM),
138 	_SERIAL_PORT(DUART16552_2_ADDR + 3, DUART16552_2_INTNUM),
139 #else
140 	_SERIAL_PORT(DUART16552_1_ADDR, DUART16552_1_INTNUM),
141 	_SERIAL_PORT(DUART16552_2_ADDR, DUART16552_2_INTNUM),
142 #endif
143 	{ }
144 };
145 
146 static struct platform_device xt2000_serial8250_device = {
147 	.name		= "serial8250",
148 	.id		= PLAT8250_DEV_PLATFORM,
149 	.dev		= {
150 	    .platform_data = xt2000_serial_data,
151 	},
152 };
153 
154 static struct resource xt2000_sonic_res[] = {
155 	{
156 		.start = SONIC83934_ADDR,
157 		.end   = SONIC83934_ADDR + 0xff,
158 		.flags = IORESOURCE_MEM,
159 	},
160 	{
161 		.start = SONIC83934_INTNUM,
162 		.end = SONIC83934_INTNUM,
163 		.flags = IORESOURCE_IRQ,
164 	},
165 };
166 
167 static struct platform_device xt2000_sonic_device = {
168 	.name		= "xtsonic",
169 	.num_resources	= ARRAY_SIZE(xt2000_sonic_res),
170 	.resource		= xt2000_sonic_res,
171 };
172 
173 static int __init xt2000_setup_devinit(void)
174 {
175 	platform_device_register(&xt2000_serial8250_device);
176 	platform_device_register(&xt2000_sonic_device);
177 
178 	return 0;
179 }
180 
181 device_initcall(xt2000_setup_devinit);
182