add preliminary Marvell Orion support
[librecmc/librecmc.git] / target / linux / orion / patches / 019-add_technologic_systems_ts-78xx_support.patch
1 Hi,
2
3 The following patch series adds support for the Technologic Systems 
4 TS-7800[1].  This is an updated driver to the one I posted before[2] which 
5 takes on all the advice and fixes suggested here.
6
7 Cheers
8
9 Alex
10
11 Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
12
13 [1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
14 [2] http://lists.arm.linux.org.uk/lurker/message/20080522.190133.54887e96.en.html
15
16 ---
17  arch/arm/mach-orion5x/Kconfig        |    7 +
18  arch/arm/mach-orion5x/Makefile       |    1 +
19  arch/arm/mach-orion5x/ts78xx-setup.c |  257 ++++++++++++++++++++++++++++++++++
20  3 files changed, 265 insertions(+), 0 deletions(-)
21  create mode 100644 arch/arm/mach-orion5x/ts78xx-setup.c
22
23 --- a/arch/arm/mach-orion5x/Kconfig
24 +++ b/arch/arm/mach-orion5x/Kconfig
25 @@ -62,6 +62,13 @@
26           Say 'Y' here if you want your kernel to support the
27           HP Media Vault mv2120 or mv5100.
28  
29 +config MACH_TS78XX
30 +       bool "Technologic Systems TS-78xx"
31 +       select CPU_FEROCEON_OLD_ID
32 +       help
33 +         Say 'Y' here if you want your kernel to support the
34 +         Technologic Systems TS-78xx platform.
35 +
36  endmenu
37  
38  endif
39 --- a/arch/arm/mach-orion5x/Makefile
40 +++ b/arch/arm/mach-orion5x/Makefile
41 @@ -8,3 +8,4 @@
42  obj-$(CONFIG_MACH_TS409)       += ts409-setup.o
43  obj-$(CONFIG_MACH_WRT350N_V2)  += wrt350n-v2-setup.o
44  obj-$(CONFIG_MACH_MV2120)      += mv2120-setup.o
45 +obj-$(CONFIG_MACH_TS78XX)      += ts78xx-setup.o
46 --- /dev/null
47 +++ b/arch/arm/mach-orion5x/ts78xx-setup.c
48 @@ -0,0 +1,257 @@
49 +/*
50 + * arch/arm/mach-orion5x/ts78xx-setup.c
51 + *
52 + * Maintainer: Alexander Clouter <alex@digriz.org.uk>
53 + *
54 + * This file is licensed under the terms of the GNU General Public
55 + * License version 2.  This program is licensed "as is" without any
56 + * warranty of any kind, whether express or implied.
57 + */
58 +
59 +#include <linux/kernel.h>
60 +#include <linux/init.h>
61 +#include <linux/platform_device.h>
62 +#include <linux/mtd/physmap.h>
63 +#include <linux/mv643xx_eth.h>
64 +#include <linux/ata_platform.h>
65 +#include <linux/m48t86.h>
66 +#include <asm/mach-types.h>
67 +#include <asm/mach/arch.h>
68 +#include <asm/mach/map.h>
69 +#include <asm/arch/orion5x.h>
70 +#include "common.h"
71 +#include "mpp.h"
72 +
73 +/*****************************************************************************
74 + * TS-78xx Info
75 + ****************************************************************************/
76 +
77 +/*
78 + * FPGA - lives where the PCI bus would be at ORION5X_PCI_MEM_PHYS_BASE
79 + */
80 +#define        TS78XX_FPGA_REGS_PHYS_BASE      0xe8000000
81 +#define        TS78XX_FPGA_REGS_VIRT_BASE      0xff900000
82 +#define        TS78XX_FPGA_REGS_SIZE           SZ_1M
83 +
84 +#define        TS78XX_FPGA_REGS_RTC_CTRL       TS78XX_FPGA_REGS_VIRT_BASE | 0x808
85 +#define        TS78XX_FPGA_REGS_RTC_DATA       TS78XX_FPGA_REGS_VIRT_BASE | 0x80c
86 +
87 +/*
88 + * 512kB NOR flash Device
89 + */
90 +#define        TS78XX_NOR_BOOT_BASE            0xff800000
91 +#define        TS78XX_NOR_BOOT_SIZE            SZ_512K
92 +
93 +/*****************************************************************************
94 + * I/O Address Mapping
95 + ****************************************************************************/
96 +static struct map_desc ts78xx_io_desc[] __initdata = {
97 +       {
98 +               .virtual        = TS78XX_FPGA_REGS_VIRT_BASE,
99 +               .pfn            = __phys_to_pfn(TS78XX_FPGA_REGS_PHYS_BASE),
100 +               .length         = TS78XX_FPGA_REGS_SIZE,
101 +               .type           = MT_DEVICE,
102 +       },
103 +};
104 +
105 +void __init ts78xx_map_io(void)
106 +{
107 +       orion5x_map_io();
108 +       iotable_init(ts78xx_io_desc, ARRAY_SIZE(ts78xx_io_desc));
109 +}
110 +
111 +/*****************************************************************************
112 + * 512kB NOR Boot Flash - the chip is a M25P40
113 + ****************************************************************************/
114 +static struct mtd_partition ts78xx_nor_boot_flash_resources[] = {
115 +       {
116 +               .name           = "ts-bootrom",
117 +               .offset         = 0,
118 +               /* only the first 256kB is used */
119 +               .size           = SZ_256K,
120 +               .mask_flags     = MTD_WRITEABLE,
121 +       },
122 +};
123 +
124 +static struct physmap_flash_data ts78xx_nor_boot_flash_data = {
125 +       .width          = 1,
126 +       .parts          = ts78xx_nor_boot_flash_resources,
127 +       .nr_parts       = ARRAY_SIZE(ts78xx_nor_boot_flash_resources),
128 +};
129 +
130 +static struct resource ts78xx_nor_boot_flash_resource = {
131 +       .flags          = IORESOURCE_MEM,
132 +       .start          = TS78XX_NOR_BOOT_BASE,
133 +       .end            = TS78XX_NOR_BOOT_BASE + TS78XX_NOR_BOOT_SIZE - 1,
134 +};
135 +
136 +static struct platform_device ts78xx_nor_boot_flash = {
137 +       .name           = "physmap-flash",
138 +       .id             = -1,
139 +       .dev            = {
140 +               .platform_data  = &ts78xx_nor_boot_flash_data,
141 +       },
142 +       .num_resources  = 1,
143 +       .resource       = &ts78xx_nor_boot_flash_resource,
144 +};
145 +
146 +/*****************************************************************************
147 + * PCI
148 + ****************************************************************************/
149 +
150 +/*
151 + * WARNING: TS shunt the PCI IO via the FPGA so that you could build soft-PCI
152 + *             devices for it and what-not.  There is nothing on the PCI or
153 + *             PCIe buses so probably nothing really to do yet here, if ever
154 + */
155 +
156 +/*****************************************************************************
157 + * Ethernet
158 + ****************************************************************************/
159 +static struct mv643xx_eth_platform_data ts78xx_eth_data = {
160 +       .phy_addr       = 0,
161 +       .force_phy_addr = 1,
162 +};
163 +
164 +/*****************************************************************************
165 + * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c
166 + ****************************************************************************/
167 +static unsigned char ts78xx_rtc_readbyte(unsigned long addr)
168 +{
169 +       writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
170 +       return readb(TS78XX_FPGA_REGS_RTC_DATA);
171 +}
172 +
173 +static void ts78xx_rtc_writebyte(unsigned char value, unsigned long addr)
174 +{
175 +       writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
176 +       writeb(value, TS78XX_FPGA_REGS_RTC_DATA);
177 +}
178 +
179 +static struct m48t86_ops ts78xx_rtc_ops = {
180 +       .readbyte       = ts78xx_rtc_readbyte,
181 +       .writebyte      = ts78xx_rtc_writebyte,
182 +};
183 +
184 +static struct platform_device ts78xx_rtc_device = {
185 +       .name           = "rtc-m48t86",
186 +       .id             = -1,
187 +       .dev            = {
188 +               .platform_data  = &ts78xx_rtc_ops,
189 +       },
190 +       .num_resources  = 0,
191 +};
192 +
193 +/*****************************************************************************
194 + * SATA
195 + ****************************************************************************/
196 +static struct mv_sata_platform_data ts78xx_sata_data = {
197 +       .n_ports        = 2,
198 +};
199 +
200 +/*****************************************************************************
201 + * General Setup
202 + ****************************************************************************/
203 +static void __init ts78xx_init(void)
204 +{
205 +#ifdef CONFIG_RTC_DRV_M48T86
206 +       unsigned char tmp_rtc0, tmp_rtc1;
207 +#endif
208 +
209 +       /*
210 +        * Setup basic Orion functions. Need to be called early.
211 +        */
212 +       orion5x_init();
213 +
214 +       orion5x_mpp_conf(0, MPP_UNUSED);
215 +
216 +       /*
217 +        * MPP[1] JTAG Clock
218 +        * MPP[2] JTAG Data In
219 +        * MPP[3] Lattice ECP2 256 FPGA - PB2B
220 +        * MPP[4] JTAG Data Out
221 +        * MPP[5] JTAG TMS
222 +        * MPP[6] Lattice ECP2 256 FPGA - PB31A_CLK4+
223 +        * MPP[7] Lattice ECP2 256 FPGA - PB22B
224 +        */
225 +
226 +       orion5x_mpp_conf(8, MPP_UNUSED);
227 +       orion5x_mpp_conf(9, MPP_UNUSED);
228 +       orion5x_mpp_conf(10, MPP_UNUSED);
229 +       orion5x_mpp_conf(11, MPP_UNUSED);
230 +       orion5x_mpp_conf(12, MPP_UNUSED);
231 +       orion5x_mpp_conf(13, MPP_UNUSED);
232 +       orion5x_mpp_conf(14, MPP_UNUSED);
233 +       orion5x_mpp_conf(15, MPP_UNUSED);
234 +       orion5x_mpp_conf(16, MPP_UART);
235 +       orion5x_mpp_conf(17, MPP_UART);
236 +       orion5x_mpp_conf(18, MPP_UART);
237 +       orion5x_mpp_conf(19, MPP_UART);
238 +
239 +       /*
240 +        * MPP[20] PCI Clock Out 1
241 +        * MPP[21] PCI Clock Out 0
242 +        * MPP[22] Unused
243 +        * MPP[23] Unused
244 +        * MPP[24] Unused
245 +        * MPP[25] Unused
246 +        */
247 +
248 +       /*
249 +        * Configure peripherals.
250 +        */
251 +       orion5x_ehci0_init();
252 +       orion5x_ehci1_init();
253 +       orion5x_eth_init(&ts78xx_eth_data);
254 +       orion5x_sata_init(&ts78xx_sata_data);
255 +       orion5x_uart0_init();
256 +       orion5x_uart1_init();
257 +
258 +       orion5x_setup_dev_boot_win(TS78XX_NOR_BOOT_BASE,
259 +                                  TS78XX_NOR_BOOT_SIZE);
260 +       platform_device_register(&ts78xx_nor_boot_flash);
261 +
262 +#ifdef CONFIG_RTC_DRV_M48T86
263 +       /*
264 +        * TS uses some of the user storage space on the RTC chip so see if it
265 +        * is present; as it's an optional feature at purchase time and not all
266 +        * boards will have it present
267 +        *
268 +        * I've used the method TS use in their rtc7800.c example for the
269 +        * detection logic; a little 'funky' but thats what floats my boat
270 +        *
271 +        * TODO: track down a guinea pig without an RTC to see if we can work
272 +        *              out a better RTC detection routine
273 +        */
274 +       tmp_rtc0 = ts78xx_rtc_readbyte(126);
275 +       tmp_rtc1 = ts78xx_rtc_readbyte(127);
276 +
277 +       ts78xx_rtc_writebyte(0x00, 126);
278 +       ts78xx_rtc_writebyte(0x55, 127);
279 +       if (ts78xx_rtc_readbyte(127) == 0x55) {
280 +               ts78xx_rtc_writebyte(0xaa, 127);
281 +               if (ts78xx_rtc_readbyte(127) == 0xaa
282 +                               && ts78xx_rtc_readbyte(126) == 0x00) {
283 +                       ts78xx_rtc_writebyte(tmp_rtc0, 126);
284 +                       ts78xx_rtc_writebyte(tmp_rtc1, 127);
285 +                       platform_device_register(&ts78xx_rtc_device);
286 +                       goto rtcok;
287 +               }
288 +       }
289 +       printk(KERN_INFO "TS-78xx RTC not detected\n");
290 +
291 + rtcok:
292 +       ;
293 +#endif
294 +}
295 +
296 +MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
297 +       /* Maintainer: Alexander Clouter <alex@digriz.org.uk> */
298 +       .phys_io        = ORION5X_REGS_PHYS_BASE,
299 +       .io_pg_offst    = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
300 +       .boot_params    = 0x00000100,
301 +       .init_machine   = ts78xx_init,
302 +       .map_io         = ts78xx_map_io,
303 +       .init_irq       = orion5x_init_irq,
304 +       .timer          = &orion5x_timer,
305 +MACHINE_END