aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2012-11-04 22:37:14 -0500
committerChris Zankel <chris@zankel.net>2012-12-19 00:10:24 -0500
commit0d456bad36d42d16022be045c8a53ddbb59ee478 (patch)
tree3c135bfcf37d6ccf45fd9ac4f739df95e181d416
parentda844a81779e2bb263eca4ecb1046541fdb11cf8 (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/Kconfig9
-rw-r--r--arch/xtensa/Makefile1
-rw-r--r--arch/xtensa/boot/Makefile1
-rw-r--r--arch/xtensa/platforms/xtfpga/Makefile9
-rw-r--r--arch/xtensa/platforms/xtfpga/include/platform/hardware.h69
-rw-r--r--arch/xtensa/platforms/xtfpga/include/platform/lcd.h20
-rw-r--r--arch/xtensa/platforms/xtfpga/include/platform/serial.h18
-rw-r--r--arch/xtensa/platforms/xtfpga/lcd.c76
-rw-r--r--arch/xtensa/platforms/xtfpga/setup.c269
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
154config 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
154endchoice 163endchoice
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
38platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 38platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000
39platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss 39platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss
40platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 40platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105
41platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA) := xtfpga
41 42
42PLATFORM = $(platform-y) 43PLATFORM = $(platform-y)
43export PLATFORM 44export 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
24bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf 24bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf
25bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot 25bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot
26bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot
26 27
27 28
28BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o 29BUILTIN_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
9obj-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. */
15void lcd_disp_at_pos(char *str, unsigned char pos);
16
17/* Shift the contents of the LCD display left or right. */
18void lcd_shiftleft(void);
19void 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
37static 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
53void 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
64void lcd_shiftleft(void)
65{
66 *LCD_INSTR_ADDR = LCD_SHIFT_LEFT;
67 udelay(50);
68}
69
70void lcd_shiftright(void)
71{
72 *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT;
73 udelay(50);
74}
75
76arch_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
36void platform_halt(void)
37{
38 lcd_disp_at_pos(" HALT ", 0);
39 local_irq_disable();
40 while (1)
41 cpu_relax();
42}
43
44void platform_power_off(void)
45{
46 lcd_disp_at_pos("POWEROFF", 0);
47 local_irq_disable();
48 while (1)
49 cpu_relax();
50}
51
52void 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
76void __init platform_setup(char **cmdline)
77{
78}
79
80#ifdef CONFIG_OF
81
82static 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
106static 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}
114arch_initcall(machine_setup);
115
116#endif
117
118/* early initialization */
119
120void __init platform_init(bp_tag_t *first)
121{
122}
123
124/* Heartbeat. */
125
126void platform_heartbeat(void)
127{
128}
129
130#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
131
132void 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
164static 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
182static 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
192static 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 = &ethoc_pdata,
199 },
200};
201
202/*----------------------------------------------------------------------------
203 * UART
204 */
205
206static struct resource serial_resource __initdata = {
207 .start = DUART16552_PADDR,
208 .end = DUART16552_PADDR + 0x1f,
209 .flags = IORESOURCE_MEM,
210};
211
212static 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
225static 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 */
236static struct platform_device *platform_devices[] __initdata = {
237 &ethoc_device,
238 &xtavnet_uart,
239};
240
241
242static 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 */
267arch_initcall(xtavnet_init);
268
269#endif /* CONFIG_OF */