3 * arch/xtensa/platform/xtavnet/setup.c
7 * Authors: Chris Zankel <chris@zankel.net>
8 * Joe Taylor <joe@tensilica.com>
10 * Copyright 2001 - 2006 Tensilica Inc.
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
18 #include <linux/stddef.h>
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/errno.h>
22 #include <linux/reboot.h>
23 #include <linux/kdev_t.h>
24 #include <linux/types.h>
25 #include <linux/major.h>
26 #include <linux/console.h>
27 #include <linux/delay.h>
30 #include <asm/timex.h>
31 #include <asm/processor.h>
32 #include <asm/platform.h>
33 #include <asm/bootparam.h>
34 #include <platform/lcd.h>
35 #include <platform/hardware.h>
37 void platform_halt(void)
39 lcd_disp_at_pos(" HALT ", 0);
45 void platform_power_off(void)
47 lcd_disp_at_pos("POWEROFF", 0);
53 void platform_restart(void)
55 /* Flush and reset the mmu, simulate a processor reset, and
56 * jump to the reset vector. */
59 __asm__
__volatile__ ("movi a2, 15\n\t"
60 "wsr a2, icountlevel\n\t"
63 "wsr a2, ibreakenable\n\t"
70 : "a" (XCHAL_RESET_VECTOR_VADDR
)
74 /* control never gets here */
77 void __init
platform_setup(char **cmdline
)
83 static void __init
update_clock_frequency(struct device_node
*node
)
85 struct property
*newfreq
;
88 if (!of_property_read_u32(node
, "clock-frequency", &freq
) && freq
!= 0)
91 newfreq
= kzalloc(sizeof(*newfreq
) + sizeof(u32
), GFP_KERNEL
);
94 newfreq
->value
= newfreq
+ 1;
95 newfreq
->length
= sizeof(freq
);
96 newfreq
->name
= kstrdup("clock-frequency", GFP_KERNEL
);
102 *(u32
*)newfreq
->value
= cpu_to_be32(*(u32
*)XTFPGA_CLKFRQ_VADDR
);
103 prom_update_property(node
, newfreq
);
107 static void __init
update_local_mac(struct device_node
*node
)
109 struct property
*newmac
;
113 macaddr
= of_get_property(node
, "local-mac-address", &prop_len
);
114 if (macaddr
== NULL
|| prop_len
!= MAC_LEN
)
117 newmac
= kzalloc(sizeof(*newmac
) + MAC_LEN
, GFP_KERNEL
);
121 newmac
->value
= newmac
+ 1;
122 newmac
->length
= MAC_LEN
;
123 newmac
->name
= kstrdup("local-mac-address", GFP_KERNEL
);
124 if (newmac
->name
== NULL
) {
129 memcpy(newmac
->value
, macaddr
, MAC_LEN
);
130 ((u8
*)newmac
->value
)[5] = (*(u32
*)DIP_SWITCHES_VADDR
) & 0x3f;
131 prom_update_property(node
, newmac
);
134 static int __init
machine_setup(void)
136 struct device_node
*serial
;
137 struct device_node
*eth
= NULL
;
139 for_each_compatible_node(serial
, NULL
, "ns16550a")
140 update_clock_frequency(serial
);
142 if ((eth
= of_find_compatible_node(eth
, NULL
, "opencores,ethoc")))
143 update_local_mac(eth
);
146 arch_initcall(machine_setup
);
150 /* early initialization */
152 void __init
platform_init(bp_tag_t
*first
)
158 void platform_heartbeat(void)
162 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
164 void platform_calibrate_ccount(void)
168 struct device_node
*cpu
=
169 of_find_compatible_node(NULL
, NULL
, "xtensa,cpu");
172 update_clock_frequency(cpu
);
173 if (!of_property_read_u32(cpu
, "clock-frequency", &freq
))
178 clk_freq
= *(long *)XTFPGA_CLKFRQ_VADDR
;
180 ccount_per_jiffy
= clk_freq
/ HZ
;
181 nsec_per_ccount
= 1000000000UL / clk_freq
;
188 #include <linux/serial_8250.h>
189 #include <linux/if.h>
190 #include <net/ethoc.h>
192 /*----------------------------------------------------------------------------
193 * Ethernet -- OpenCores Ethernet MAC (ethoc driver)
196 static struct resource ethoc_res
[] __initdata
= {
197 [0] = { /* register space */
198 .start
= OETH_REGS_PADDR
,
199 .end
= OETH_REGS_PADDR
+ OETH_REGS_SIZE
- 1,
200 .flags
= IORESOURCE_MEM
,
202 [1] = { /* buffer space */
203 .start
= OETH_SRAMBUFF_PADDR
,
204 .end
= OETH_SRAMBUFF_PADDR
+ OETH_SRAMBUFF_SIZE
- 1,
205 .flags
= IORESOURCE_MEM
,
207 [2] = { /* IRQ number */
210 .flags
= IORESOURCE_IRQ
,
214 static struct ethoc_platform_data ethoc_pdata __initdata
= {
216 * The MAC address for these boards is 00:50:c2:13:6f:xx.
217 * The last byte (here as zero) is read from the DIP switches on the
220 .hwaddr
= { 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 },
224 static struct platform_device ethoc_device __initdata
= {
227 .num_resources
= ARRAY_SIZE(ethoc_res
),
228 .resource
= ethoc_res
,
230 .platform_data
= ðoc_pdata
,
234 /*----------------------------------------------------------------------------
238 static struct resource serial_resource __initdata
= {
239 .start
= DUART16552_PADDR
,
240 .end
= DUART16552_PADDR
+ 0x1f,
241 .flags
= IORESOURCE_MEM
,
244 static struct plat_serial8250_port serial_platform_data
[] __initdata
= {
246 .mapbase
= DUART16552_PADDR
,
247 .irq
= DUART16552_INTNUM
,
248 .flags
= UPF_BOOT_AUTOCONF
| UPF_SKIP_TEST
|
250 .iotype
= UPIO_MEM32
,
252 .uartclk
= 0, /* set in xtavnet_init() */
257 static struct platform_device xtavnet_uart __initdata
= {
258 .name
= "serial8250",
259 .id
= PLAT8250_DEV_PLATFORM
,
261 .platform_data
= serial_platform_data
,
264 .resource
= &serial_resource
,
267 /* platform devices */
268 static struct platform_device
*platform_devices
[] __initdata
= {
274 static int __init
xtavnet_init(void)
276 /* Ethernet MAC address. */
277 ethoc_pdata
.hwaddr
[5] = *(u32
*)DIP_SWITCHES_VADDR
;
279 /* Clock rate varies among FPGA bitstreams; board specific FPGA register
280 * reports the actual clock rate.
282 serial_platform_data
[0].uartclk
= *(long *)XTFPGA_CLKFRQ_VADDR
;
285 /* register platform devices */
286 platform_add_devices(platform_devices
, ARRAY_SIZE(platform_devices
));
288 /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user
289 * knows whether they set it correctly on the DIP switches.
291 pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata
.hwaddr
);
297 * Register to be done during do_initcalls().
299 arch_initcall(xtavnet_init
);
301 #endif /* CONFIG_OF */