diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2012-11-04 22:37:14 -0500 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2012-12-19 00:10:24 -0500 |
commit | 0d456bad36d42d16022be045c8a53ddbb59ee478 (patch) | |
tree | 3c135bfcf37d6ccf45fd9ac4f739df95e181d416 | |
parent | da844a81779e2bb263eca4ecb1046541fdb11cf8 (diff) |
xtensa: add support for the XTFPGA boards
The Avnet LX60/LX110/LX200 board is an FPGA board that can be configured with
an Xtensa processor and an OpenCores Ethernet device.
Signed-off-by: Chris Zankel <chris@zankel.net>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Chris Zankel <chris@zankel.net>
-rw-r--r-- | arch/xtensa/Kconfig | 9 | ||||
-rw-r--r-- | arch/xtensa/Makefile | 1 | ||||
-rw-r--r-- | arch/xtensa/boot/Makefile | 1 | ||||
-rw-r--r-- | arch/xtensa/platforms/xtfpga/Makefile | 9 | ||||
-rw-r--r-- | arch/xtensa/platforms/xtfpga/include/platform/hardware.h | 69 | ||||
-rw-r--r-- | arch/xtensa/platforms/xtfpga/include/platform/lcd.h | 20 | ||||
-rw-r--r-- | arch/xtensa/platforms/xtfpga/include/platform/serial.h | 18 | ||||
-rw-r--r-- | arch/xtensa/platforms/xtfpga/lcd.c | 76 | ||||
-rw-r--r-- | arch/xtensa/platforms/xtfpga/setup.c | 269 |
9 files changed, 472 insertions, 0 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 8ceb5b2ffbb1..73d34e77c39c 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -151,6 +151,15 @@ config XTENSA_PLATFORM_S6105 | |||
151 | select SERIAL_CONSOLE | 151 | select SERIAL_CONSOLE |
152 | select NO_IOPORT | 152 | select NO_IOPORT |
153 | 153 | ||
154 | config XTENSA_PLATFORM_XTFPGA | ||
155 | bool "XTFPGA" | ||
156 | select SERIAL_CONSOLE | ||
157 | select ETHOC | ||
158 | select XTENSA_CALIBRATE_CCOUNT | ||
159 | help | ||
160 | XTFPGA is the name of Tensilica board family (LX60, LX110, LX200, ML605). | ||
161 | This hardware is capable of running a full Linux distribution. | ||
162 | |||
154 | endchoice | 163 | endchoice |
155 | 164 | ||
156 | 165 | ||
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 227f658fc2b9..7e0ae8fd4da8 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile | |||
@@ -38,6 +38,7 @@ endif | |||
38 | platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 | 38 | platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 |
39 | platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss | 39 | platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss |
40 | platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 | 40 | platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 |
41 | platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA) := xtfpga | ||
41 | 42 | ||
42 | PLATFORM = $(platform-y) | 43 | PLATFORM = $(platform-y) |
43 | export PLATFORM | 44 | export PLATFORM |
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index cb5ff4dbdf88..196bc3c967af 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile | |||
@@ -23,6 +23,7 @@ subdir-y := lib | |||
23 | 23 | ||
24 | bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf | 24 | bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf |
25 | bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot | 25 | bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot |
26 | bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot | ||
26 | 27 | ||
27 | 28 | ||
28 | BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o | 29 | BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o |
diff --git a/arch/xtensa/platforms/xtfpga/Makefile b/arch/xtensa/platforms/xtfpga/Makefile new file mode 100644 index 000000000000..b9ae206340cd --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | # Makefile for the Tensilica xtavnet Emulation Board | ||
2 | # | ||
3 | # Note! Dependencies are done automagically by 'make dep', which also | ||
4 | # removes any old dependencies. DON'T put your own dependencies here | ||
5 | # unless it's something special (ie not a .c file). | ||
6 | # | ||
7 | # Note 2! The CFLAGS definitions are in the main makefile... | ||
8 | |||
9 | obj-y = setup.o lcd.o | ||
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h new file mode 100644 index 000000000000..4416773cbde5 --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * arch/xtensa/platform/xtavnet/include/platform/hardware.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2006 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This file contains the hardware configuration of the XTAVNET boards. | ||
13 | */ | ||
14 | |||
15 | #ifndef __XTENSA_XTAVNET_HARDWARE_H | ||
16 | #define __XTENSA_XTAVNET_HARDWARE_H | ||
17 | |||
18 | /* By default NO_IRQ is defined to 0 in Linux, but we use the | ||
19 | interrupt 0 for UART... */ | ||
20 | #define NO_IRQ -1 | ||
21 | |||
22 | /* Memory configuration. */ | ||
23 | |||
24 | #define PLATFORM_DEFAULT_MEM_START 0x00000000 | ||
25 | #define PLATFORM_DEFAULT_MEM_SIZE 0x04000000 | ||
26 | |||
27 | /* Interrupt configuration. */ | ||
28 | |||
29 | #define PLATFORM_NR_IRQS 10 | ||
30 | |||
31 | /* Default assignment of LX60 devices to external interrupts. */ | ||
32 | |||
33 | #ifdef CONFIG_ARCH_HAS_SMP | ||
34 | #define DUART16552_INTNUM XCHAL_EXTINT3_NUM | ||
35 | #define OETH_IRQ XCHAL_EXTINT4_NUM | ||
36 | #else | ||
37 | #define DUART16552_INTNUM XCHAL_EXTINT0_NUM | ||
38 | #define OETH_IRQ XCHAL_EXTINT1_NUM | ||
39 | #endif | ||
40 | |||
41 | /* | ||
42 | * Device addresses and parameters. | ||
43 | */ | ||
44 | |||
45 | /* UART */ | ||
46 | #define DUART16552_PADDR (XCHAL_KIO_PADDR + 0x0D050020) | ||
47 | /* LCD instruction and data addresses. */ | ||
48 | #define LCD_INSTR_ADDR ((char *)IOADDR(0x0D040000)) | ||
49 | #define LCD_DATA_ADDR ((char *)IOADDR(0x0D040004)) | ||
50 | |||
51 | /* Misc. */ | ||
52 | #define XTFPGA_FPGAREGS_VADDR IOADDR(0x0D020000) | ||
53 | /* Clock frequency in Hz (read-only): */ | ||
54 | #define XTFPGA_CLKFRQ_VADDR (XTFPGA_FPGAREGS_VADDR + 0x04) | ||
55 | /* Setting of 8 DIP switches: */ | ||
56 | #define DIP_SWITCHES_VADDR (XTFPGA_FPGAREGS_VADDR + 0x0C) | ||
57 | /* Software reset (write 0xdead): */ | ||
58 | #define XTFPGA_SWRST_VADDR (XTFPGA_FPGAREGS_VADDR + 0x10) | ||
59 | |||
60 | /* OpenCores Ethernet controller: */ | ||
61 | /* regs + RX/TX descriptors */ | ||
62 | #define OETH_REGS_PADDR (XCHAL_KIO_PADDR + 0x0D030000) | ||
63 | #define OETH_REGS_SIZE 0x1000 | ||
64 | #define OETH_SRAMBUFF_PADDR (XCHAL_KIO_PADDR + 0x0D800000) | ||
65 | |||
66 | /* 5*rx buffs + 5*tx buffs */ | ||
67 | #define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600) | ||
68 | |||
69 | #endif /* __XTENSA_XTAVNET_HARDWARE_H */ | ||
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/lcd.h b/arch/xtensa/platforms/xtfpga/include/platform/lcd.h new file mode 100644 index 000000000000..0e435645af5a --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/lcd.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * arch/xtensa/platform/xtavnet/include/platform/lcd.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2001, 2006 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef __XTENSA_XTAVNET_LCD_H | ||
12 | #define __XTENSA_XTAVNET_LCD_H | ||
13 | |||
14 | /* Display string STR at position POS on the LCD. */ | ||
15 | void lcd_disp_at_pos(char *str, unsigned char pos); | ||
16 | |||
17 | /* Shift the contents of the LCD display left or right. */ | ||
18 | void lcd_shiftleft(void); | ||
19 | void lcd_shiftright(void); | ||
20 | #endif | ||
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/serial.h b/arch/xtensa/platforms/xtfpga/include/platform/serial.h new file mode 100644 index 000000000000..14d8f7beebfd --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/serial.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * arch/xtensa/platform/xtavnet/include/platform/serial.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2001, 2006 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_XTENSA_XTAVNET_SERIAL_H | ||
12 | #define __ASM_XTENSA_XTAVNET_SERIAL_H | ||
13 | |||
14 | #include <platform/hardware.h> | ||
15 | |||
16 | #define BASE_BAUD (*(long *)XTFPGA_CLKFRQ_VADDR / 16) | ||
17 | |||
18 | #endif /* __ASM_XTENSA_XTAVNET_SERIAL_H */ | ||
diff --git a/arch/xtensa/platforms/xtfpga/lcd.c b/arch/xtensa/platforms/xtfpga/lcd.c new file mode 100644 index 000000000000..2872301598df --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/lcd.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Driver for the LCD display on the Tensilica LX60 Board. | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2001, 2006 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * | ||
13 | * FIXME: this code is from the examples from the LX60 user guide. | ||
14 | * | ||
15 | * The lcd_pause function does busy waiting, which is probably not | ||
16 | * great. Maybe the code could be changed to use kernel timers, or | ||
17 | * change the hardware to not need to wait. | ||
18 | */ | ||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/io.h> | ||
22 | |||
23 | #include <platform/hardware.h> | ||
24 | #include <platform/lcd.h> | ||
25 | #include <linux/delay.h> | ||
26 | |||
27 | #define LCD_PAUSE_ITERATIONS 4000 | ||
28 | #define LCD_CLEAR 0x1 | ||
29 | #define LCD_DISPLAY_ON 0xc | ||
30 | |||
31 | /* 8bit and 2 lines display */ | ||
32 | #define LCD_DISPLAY_MODE8BIT 0x38 | ||
33 | #define LCD_DISPLAY_POS 0x80 | ||
34 | #define LCD_SHIFT_LEFT 0x18 | ||
35 | #define LCD_SHIFT_RIGHT 0x1c | ||
36 | |||
37 | static int __init lcd_init(void) | ||
38 | { | ||
39 | *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; | ||
40 | mdelay(5); | ||
41 | *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; | ||
42 | udelay(200); | ||
43 | *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; | ||
44 | udelay(50); | ||
45 | *LCD_INSTR_ADDR = LCD_DISPLAY_ON; | ||
46 | udelay(50); | ||
47 | *LCD_INSTR_ADDR = LCD_CLEAR; | ||
48 | mdelay(10); | ||
49 | lcd_disp_at_pos("XTENSA LINUX", 0); | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | void lcd_disp_at_pos(char *str, unsigned char pos) | ||
54 | { | ||
55 | *LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos; | ||
56 | udelay(100); | ||
57 | while (*str != 0) { | ||
58 | *LCD_DATA_ADDR = *str; | ||
59 | udelay(200); | ||
60 | str++; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | void lcd_shiftleft(void) | ||
65 | { | ||
66 | *LCD_INSTR_ADDR = LCD_SHIFT_LEFT; | ||
67 | udelay(50); | ||
68 | } | ||
69 | |||
70 | void lcd_shiftright(void) | ||
71 | { | ||
72 | *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT; | ||
73 | udelay(50); | ||
74 | } | ||
75 | |||
76 | arch_initcall(lcd_init); | ||
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c new file mode 100644 index 000000000000..71d61ca6a4af --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/setup.c | |||
@@ -0,0 +1,269 @@ | |||
1 | /* | ||
2 | * | ||
3 | * arch/xtensa/platform/xtavnet/setup.c | ||
4 | * | ||
5 | * ... | ||
6 | * | ||
7 | * Authors: Chris Zankel <chris@zankel.net> | ||
8 | * Joe Taylor <joe@tensilica.com> | ||
9 | * | ||
10 | * Copyright 2001 - 2006 Tensilica Inc. | ||
11 | * | ||
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. | ||
16 | * | ||
17 | */ | ||
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> | ||
28 | #include <linux/of.h> | ||
29 | |||
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 | |||
36 | void platform_halt(void) | ||
37 | { | ||
38 | lcd_disp_at_pos(" HALT ", 0); | ||
39 | local_irq_disable(); | ||
40 | while (1) | ||
41 | cpu_relax(); | ||
42 | } | ||
43 | |||
44 | void platform_power_off(void) | ||
45 | { | ||
46 | lcd_disp_at_pos("POWEROFF", 0); | ||
47 | local_irq_disable(); | ||
48 | while (1) | ||
49 | cpu_relax(); | ||
50 | } | ||
51 | |||
52 | void platform_restart(void) | ||
53 | { | ||
54 | /* Flush and reset the mmu, simulate a processor reset, and | ||
55 | * jump to the reset vector. */ | ||
56 | |||
57 | |||
58 | __asm__ __volatile__ ("movi a2, 15\n\t" | ||
59 | "wsr a2, icountlevel\n\t" | ||
60 | "movi a2, 0\n\t" | ||
61 | "wsr a2, icount\n\t" | ||
62 | "wsr a2, ibreakenable\n\t" | ||
63 | "wsr a2, lcount\n\t" | ||
64 | "movi a2, 0x1f\n\t" | ||
65 | "wsr a2, ps\n\t" | ||
66 | "isync\n\t" | ||
67 | "jx %0\n\t" | ||
68 | : | ||
69 | : "a" (XCHAL_RESET_VECTOR_VADDR) | ||
70 | : "a2" | ||
71 | ); | ||
72 | |||
73 | /* control never gets here */ | ||
74 | } | ||
75 | |||
76 | void __init platform_setup(char **cmdline) | ||
77 | { | ||
78 | } | ||
79 | |||
80 | #ifdef CONFIG_OF | ||
81 | |||
82 | static void __init update_clock_frequency(struct device_node *node) | ||
83 | { | ||
84 | struct property *newfreq; | ||
85 | u32 freq; | ||
86 | |||
87 | if (!of_property_read_u32(node, "clock-frequency", &freq) && | ||
88 | freq != 0) | ||
89 | return; | ||
90 | |||
91 | newfreq = kzalloc(sizeof(*newfreq) + sizeof(u32), GFP_KERNEL); | ||
92 | if (!newfreq) | ||
93 | return; | ||
94 | newfreq->value = newfreq + 1; | ||
95 | newfreq->length = sizeof(freq); | ||
96 | newfreq->name = kstrdup("clock-frequency", GFP_KERNEL); | ||
97 | if (!newfreq->name) { | ||
98 | kfree(newfreq); | ||
99 | return; | ||
100 | } | ||
101 | |||
102 | *(u32 *)newfreq->value = cpu_to_be32(*(u32 *)XTFPGA_CLKFRQ_VADDR); | ||
103 | prom_update_property(node, newfreq); | ||
104 | } | ||
105 | |||
106 | static int __init machine_setup(void) | ||
107 | { | ||
108 | struct device_node *serial = NULL; | ||
109 | |||
110 | while ((serial = of_find_compatible_node(serial, NULL, "ns16550a"))) | ||
111 | update_clock_frequency(serial); | ||
112 | return 0; | ||
113 | } | ||
114 | arch_initcall(machine_setup); | ||
115 | |||
116 | #endif | ||
117 | |||
118 | /* early initialization */ | ||
119 | |||
120 | void __init platform_init(bp_tag_t *first) | ||
121 | { | ||
122 | } | ||
123 | |||
124 | /* Heartbeat. */ | ||
125 | |||
126 | void platform_heartbeat(void) | ||
127 | { | ||
128 | } | ||
129 | |||
130 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT | ||
131 | |||
132 | void platform_calibrate_ccount(void) | ||
133 | { | ||
134 | long clk_freq = 0; | ||
135 | #ifdef CONFIG_OF | ||
136 | struct device_node *cpu = | ||
137 | of_find_compatible_node(NULL, NULL, "xtensa,cpu"); | ||
138 | if (cpu) { | ||
139 | u32 freq; | ||
140 | update_clock_frequency(cpu); | ||
141 | if (!of_property_read_u32(cpu, "clock-frequency", &freq)) | ||
142 | clk_freq = freq; | ||
143 | } | ||
144 | #endif | ||
145 | if (!clk_freq) | ||
146 | clk_freq = *(long *)XTFPGA_CLKFRQ_VADDR; | ||
147 | |||
148 | ccount_per_jiffy = clk_freq / HZ; | ||
149 | nsec_per_ccount = 1000000000UL / clk_freq; | ||
150 | } | ||
151 | |||
152 | #endif | ||
153 | |||
154 | #ifndef CONFIG_OF | ||
155 | |||
156 | #include <linux/serial_8250.h> | ||
157 | #include <linux/if.h> | ||
158 | #include <net/ethoc.h> | ||
159 | |||
160 | /*---------------------------------------------------------------------------- | ||
161 | * Ethernet -- OpenCores Ethernet MAC (ethoc driver) | ||
162 | */ | ||
163 | |||
164 | static struct resource ethoc_res[] __initdata = { | ||
165 | [0] = { /* register space */ | ||
166 | .start = OETH_REGS_PADDR, | ||
167 | .end = OETH_REGS_PADDR + OETH_REGS_SIZE - 1, | ||
168 | .flags = IORESOURCE_MEM, | ||
169 | }, | ||
170 | [1] = { /* buffer space */ | ||
171 | .start = OETH_SRAMBUFF_PADDR, | ||
172 | .end = OETH_SRAMBUFF_PADDR + OETH_SRAMBUFF_SIZE - 1, | ||
173 | .flags = IORESOURCE_MEM, | ||
174 | }, | ||
175 | [2] = { /* IRQ number */ | ||
176 | .start = OETH_IRQ, | ||
177 | .end = OETH_IRQ, | ||
178 | .flags = IORESOURCE_IRQ, | ||
179 | }, | ||
180 | }; | ||
181 | |||
182 | static struct ethoc_platform_data ethoc_pdata __initdata = { | ||
183 | /* | ||
184 | * The MAC address for these boards is 00:50:c2:13:6f:xx. | ||
185 | * The last byte (here as zero) is read from the DIP switches on the | ||
186 | * board. | ||
187 | */ | ||
188 | .hwaddr = { 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 }, | ||
189 | .phy_id = -1, | ||
190 | }; | ||
191 | |||
192 | static struct platform_device ethoc_device __initdata = { | ||
193 | .name = "ethoc", | ||
194 | .id = -1, | ||
195 | .num_resources = ARRAY_SIZE(ethoc_res), | ||
196 | .resource = ethoc_res, | ||
197 | .dev = { | ||
198 | .platform_data = ðoc_pdata, | ||
199 | }, | ||
200 | }; | ||
201 | |||
202 | /*---------------------------------------------------------------------------- | ||
203 | * UART | ||
204 | */ | ||
205 | |||
206 | static struct resource serial_resource __initdata = { | ||
207 | .start = DUART16552_PADDR, | ||
208 | .end = DUART16552_PADDR + 0x1f, | ||
209 | .flags = IORESOURCE_MEM, | ||
210 | }; | ||
211 | |||
212 | static struct plat_serial8250_port serial_platform_data[] __initdata = { | ||
213 | [0] = { | ||
214 | .mapbase = DUART16552_PADDR, | ||
215 | .irq = DUART16552_INTNUM, | ||
216 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
217 | UPF_IOREMAP, | ||
218 | .iotype = UPIO_MEM32, | ||
219 | .regshift = 2, | ||
220 | .uartclk = 0, /* set in xtavnet_init() */ | ||
221 | }, | ||
222 | { }, | ||
223 | }; | ||
224 | |||
225 | static struct platform_device xtavnet_uart __initdata = { | ||
226 | .name = "serial8250", | ||
227 | .id = PLAT8250_DEV_PLATFORM, | ||
228 | .dev = { | ||
229 | .platform_data = serial_platform_data, | ||
230 | }, | ||
231 | .num_resources = 1, | ||
232 | .resource = &serial_resource, | ||
233 | }; | ||
234 | |||
235 | /* platform devices */ | ||
236 | static struct platform_device *platform_devices[] __initdata = { | ||
237 | ðoc_device, | ||
238 | &xtavnet_uart, | ||
239 | }; | ||
240 | |||
241 | |||
242 | static int __init xtavnet_init(void) | ||
243 | { | ||
244 | /* Ethernet MAC address. */ | ||
245 | ethoc_pdata.hwaddr[5] = *(u32 *)DIP_SWITCHES_VADDR; | ||
246 | |||
247 | /* Clock rate varies among FPGA bitstreams; board specific FPGA register | ||
248 | * reports the actual clock rate. | ||
249 | */ | ||
250 | serial_platform_data[0].uartclk = *(long *)XTFPGA_CLKFRQ_VADDR; | ||
251 | |||
252 | |||
253 | /* register platform devices */ | ||
254 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
255 | |||
256 | /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user | ||
257 | * knows whether they set it correctly on the DIP switches. | ||
258 | */ | ||
259 | pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata.hwaddr); | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * Register to be done during do_initcalls(). | ||
266 | */ | ||
267 | arch_initcall(xtavnet_init); | ||
268 | |||
269 | #endif /* CONFIG_OF */ | ||