1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * arch/xtensa/platform/xtavnet/setup.c
8 * Authors: Chris Zankel <chris@zankel.net>
9 * Joe Taylor <joe@tensilica.com>
11 * Copyright 2001 - 2006 Tensilica Inc.
13 #include <linux/stddef.h>
14 #include <linux/kernel.h>
15 #include <linux/init.h>
17 #include <linux/errno.h>
18 #include <linux/reboot.h>
19 #include <linux/kdev_t.h>
20 #include <linux/types.h>
21 #include <linux/major.h>
22 #include <linux/console.h>
23 #include <linux/delay.h>
25 #include <linux/clk-provider.h>
26 #include <linux/of_address.h>
28 #include <asm/timex.h>
29 #include <asm/processor.h>
30 #include <asm/platform.h>
31 #include <asm/bootparam.h>
32 #include <platform/lcd.h>
33 #include <platform/hardware.h>
35 void platform_halt(void)
37 lcd_disp_at_pos(" HALT ", 0);
43 void platform_power_off(void)
45 lcd_disp_at_pos("POWEROFF", 0);
51 void platform_restart(void)
53 /* Flush and reset the mmu, simulate a processor reset, and
54 * jump to the reset vector. */
56 /* control never gets here */
59 void __init
platform_setup(char **cmdline
)
63 /* early initialization */
65 void __init
platform_init(bp_tag_t
*first
)
71 void platform_heartbeat(void)
75 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
77 void __init
platform_calibrate_ccount(void)
79 ccount_freq
= *(long *)XTFPGA_CLKFRQ_VADDR
;
86 static void __init
xtfpga_clk_setup(struct device_node
*np
)
88 void __iomem
*base
= of_iomap(np
, 0);
93 pr_err("%pOFn: invalid address\n", np
);
97 freq
= __raw_readl(base
);
99 clk
= clk_register_fixed_rate(NULL
, np
->name
, NULL
, 0, freq
);
102 pr_err("%pOFn: clk registration failed\n", np
);
106 if (of_clk_add_provider(np
, of_clk_src_simple_get
, clk
)) {
107 pr_err("%pOFn: clk provider registration failed\n", np
);
111 CLK_OF_DECLARE(xtfpga_clk
, "cdns,xtfpga-clock", xtfpga_clk_setup
);
114 static void __init
update_local_mac(struct device_node
*node
)
116 struct property
*newmac
;
120 macaddr
= of_get_property(node
, "local-mac-address", &prop_len
);
121 if (macaddr
== NULL
|| prop_len
!= MAC_LEN
)
124 newmac
= kzalloc(sizeof(*newmac
) + MAC_LEN
, GFP_KERNEL
);
128 newmac
->value
= newmac
+ 1;
129 newmac
->length
= MAC_LEN
;
130 newmac
->name
= kstrdup("local-mac-address", GFP_KERNEL
);
131 if (newmac
->name
== NULL
) {
136 memcpy(newmac
->value
, macaddr
, MAC_LEN
);
137 ((u8
*)newmac
->value
)[5] = (*(u32
*)DIP_SWITCHES_VADDR
) & 0x3f;
138 of_update_property(node
, newmac
);
141 static int __init
machine_setup(void)
143 struct device_node
*eth
= NULL
;
145 if ((eth
= of_find_compatible_node(eth
, NULL
, "opencores,ethoc")))
146 update_local_mac(eth
);
149 arch_initcall(machine_setup
);
153 #include <linux/serial_8250.h>
154 #include <linux/if.h>
155 #include <net/ethoc.h>
156 #include <linux/usb/c67x00.h>
158 /*----------------------------------------------------------------------------
159 * Ethernet -- OpenCores Ethernet MAC (ethoc driver)
162 static struct resource ethoc_res
[] = {
163 [0] = { /* register space */
164 .start
= OETH_REGS_PADDR
,
165 .end
= OETH_REGS_PADDR
+ OETH_REGS_SIZE
- 1,
166 .flags
= IORESOURCE_MEM
,
168 [1] = { /* buffer space */
169 .start
= OETH_SRAMBUFF_PADDR
,
170 .end
= OETH_SRAMBUFF_PADDR
+ OETH_SRAMBUFF_SIZE
- 1,
171 .flags
= IORESOURCE_MEM
,
173 [2] = { /* IRQ number */
174 .start
= XTENSA_PIC_LINUX_IRQ(OETH_IRQ
),
175 .end
= XTENSA_PIC_LINUX_IRQ(OETH_IRQ
),
176 .flags
= IORESOURCE_IRQ
,
180 static struct ethoc_platform_data ethoc_pdata
= {
182 * The MAC address for these boards is 00:50:c2:13:6f:xx.
183 * The last byte (here as zero) is read from the DIP switches on the
186 .hwaddr
= { 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 },
188 .big_endian
= XCHAL_HAVE_BE
,
191 static struct platform_device ethoc_device
= {
194 .num_resources
= ARRAY_SIZE(ethoc_res
),
195 .resource
= ethoc_res
,
197 .platform_data
= ðoc_pdata
,
201 /*----------------------------------------------------------------------------
202 * USB Host/Device -- Cypress CY7C67300
205 static struct resource c67x00_res
[] = {
206 [0] = { /* register space */
207 .start
= C67X00_PADDR
,
208 .end
= C67X00_PADDR
+ C67X00_SIZE
- 1,
209 .flags
= IORESOURCE_MEM
,
211 [1] = { /* IRQ number */
212 .start
= XTENSA_PIC_LINUX_IRQ(C67X00_IRQ
),
213 .end
= XTENSA_PIC_LINUX_IRQ(C67X00_IRQ
),
214 .flags
= IORESOURCE_IRQ
,
218 static struct c67x00_platform_data c67x00_pdata
= {
219 .sie_config
= C67X00_SIE1_HOST
| C67X00_SIE2_UNUSED
,
223 static struct platform_device c67x00_device
= {
226 .num_resources
= ARRAY_SIZE(c67x00_res
),
227 .resource
= c67x00_res
,
229 .platform_data
= &c67x00_pdata
,
233 /*----------------------------------------------------------------------------
237 static struct resource serial_resource
= {
238 .start
= DUART16552_PADDR
,
239 .end
= DUART16552_PADDR
+ 0x1f,
240 .flags
= IORESOURCE_MEM
,
243 static struct plat_serial8250_port serial_platform_data
[] = {
245 .mapbase
= DUART16552_PADDR
,
246 .irq
= XTENSA_PIC_LINUX_IRQ(DUART16552_INTNUM
),
247 .flags
= UPF_BOOT_AUTOCONF
| UPF_SKIP_TEST
|
249 .iotype
= XCHAL_HAVE_BE
? UPIO_MEM32BE
: UPIO_MEM32
,
251 .uartclk
= 0, /* set in xtavnet_init() */
256 static struct platform_device xtavnet_uart
= {
257 .name
= "serial8250",
258 .id
= PLAT8250_DEV_PLATFORM
,
260 .platform_data
= serial_platform_data
,
263 .resource
= &serial_resource
,
266 /* platform devices */
267 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
);
292 ethoc_pdata
.eth_clkfreq
= *(long *)XTFPGA_CLKFRQ_VADDR
;
298 * Register to be done during do_initcalls().
300 arch_initcall(xtavnet_init
);
302 #endif /* CONFIG_OF */