blob: e00bc2d7f3018562b52a78e360cd559800af114f [file] [log] [blame]
Ralf Baechle35189fa2006-06-18 16:39:46 +01001/*
2 * Copyright (C) 2004 by Basler Vision Technologies AG
3 * Author: Thomas Koeller <thomas.koeller@baslerweb.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
Ralf Baechle35189fa2006-06-18 16:39:46 +010020#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/ioport.h>
24#include <linux/err.h>
25#include <linux/jiffies.h>
26#include <linux/sched.h>
27#include <asm/types.h>
28#include <asm/rm9k-ocd.h>
29
30#include <excite.h>
31#include <rm9k_eth.h>
32#include <rm9k_wdt.h>
33#include <rm9k_xicap.h>
34#include <excite_nandflash.h>
35
36#include "excite_iodev.h"
37
38#define RM9K_GE_UNIT 0
39#define XICAP_UNIT 0
40#define NAND_UNIT 0
41
42#define DLL_TIMEOUT 3 /* seconds */
43
44
45#define RINIT(__start__, __end__, __name__, __parent__) { \
46 .name = __name__ "_0", \
47 .start = (__start__), \
48 .end = (__end__), \
49 .flags = 0, \
50 .parent = (__parent__) \
51}
52
53#define RINIT_IRQ(__irq__, __name__) { \
54 .name = __name__ "_0", \
55 .start = (__irq__), \
56 .end = (__irq__), \
57 .flags = IORESOURCE_IRQ, \
58 .parent = NULL \
59}
60
61
62
63enum {
64 slice_xicap,
65 slice_eth
66};
67
68
69
70static struct resource
David Rientjesf6d376a2007-05-10 22:51:04 -070071 excite_ctr_resource __maybe_unused = {
Ralf Baechle35189fa2006-06-18 16:39:46 +010072 .name = "GPI counters",
73 .start = 0,
74 .end = 5,
75 .flags = 0,
76 .parent = NULL,
77 .sibling = NULL,
78 .child = NULL
79 },
David Rientjesf6d376a2007-05-10 22:51:04 -070080 excite_gpislice_resource __maybe_unused = {
Ralf Baechle35189fa2006-06-18 16:39:46 +010081 .name = "GPI slices",
82 .start = 0,
83 .end = 1,
84 .flags = 0,
85 .parent = NULL,
86 .sibling = NULL,
87 .child = NULL
88 },
David Rientjesf6d376a2007-05-10 22:51:04 -070089 excite_mdio_channel_resource __maybe_unused = {
Ralf Baechle35189fa2006-06-18 16:39:46 +010090 .name = "MDIO channels",
91 .start = 0,
92 .end = 1,
93 .flags = 0,
94 .parent = NULL,
95 .sibling = NULL,
96 .child = NULL
97 },
David Rientjesf6d376a2007-05-10 22:51:04 -070098 excite_fifomem_resource __maybe_unused = {
Ralf Baechle35189fa2006-06-18 16:39:46 +010099 .name = "FIFO memory",
100 .start = 0,
101 .end = 767,
102 .flags = 0,
103 .parent = NULL,
104 .sibling = NULL,
105 .child = NULL
106 },
David Rientjesf6d376a2007-05-10 22:51:04 -0700107 excite_scram_resource __maybe_unused = {
Ralf Baechle35189fa2006-06-18 16:39:46 +0100108 .name = "Scratch RAM",
109 .start = EXCITE_PHYS_SCRAM,
110 .end = EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1,
111 .flags = IORESOURCE_MEM,
112 .parent = NULL,
113 .sibling = NULL,
114 .child = NULL
115 },
David Rientjesf6d376a2007-05-10 22:51:04 -0700116 excite_fpga_resource __maybe_unused = {
Ralf Baechle35189fa2006-06-18 16:39:46 +0100117 .name = "System FPGA",
118 .start = EXCITE_PHYS_FPGA,
119 .end = EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1,
120 .flags = IORESOURCE_MEM,
121 .parent = NULL,
122 .sibling = NULL,
123 .child = NULL
124 },
David Rientjesf6d376a2007-05-10 22:51:04 -0700125 excite_nand_resource __maybe_unused = {
Ralf Baechle35189fa2006-06-18 16:39:46 +0100126 .name = "NAND flash control",
127 .start = EXCITE_PHYS_NAND,
128 .end = EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1,
129 .flags = IORESOURCE_MEM,
130 .parent = NULL,
131 .sibling = NULL,
132 .child = NULL
133 },
David Rientjesf6d376a2007-05-10 22:51:04 -0700134 excite_titan_resource __maybe_unused = {
Ralf Baechle35189fa2006-06-18 16:39:46 +0100135 .name = "TITAN registers",
136 .start = EXCITE_PHYS_TITAN,
137 .end = EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1,
138 .flags = IORESOURCE_MEM,
139 .parent = NULL,
140 .sibling = NULL,
141 .child = NULL
142 };
143
144
145
146static void adjust_resources(struct resource *res, unsigned int n)
147{
148 struct resource *p;
149 const unsigned long mask = IORESOURCE_IO | IORESOURCE_MEM
150 | IORESOURCE_IRQ | IORESOURCE_DMA;
151
152 for (p = res; p < res + n; p++) {
153 const struct resource * const parent = p->parent;
154 if (parent) {
155 p->start += parent->start;
156 p->end += parent->start;
157 p->flags = parent->flags & mask;
158 }
159 }
160}
161
162
163
164#if defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE)
165static struct resource xicap_rsrc[] = {
166 RINIT(0x4840, 0x486f, XICAP_RESOURCE_FIFO_RX, &excite_titan_resource),
167 RINIT(0x4940, 0x494b, XICAP_RESOURCE_FIFO_TX, &excite_titan_resource),
168 RINIT(0x5040, 0x5127, XICAP_RESOURCE_XDMA, &excite_titan_resource),
169 RINIT(0x1000, 0x112f, XICAP_RESOURCE_PKTPROC, &excite_titan_resource),
170 RINIT(0x1100, 0x110f, XICAP_RESOURCE_PKT_STREAM, &excite_fpga_resource),
171 RINIT(0x0800, 0x0bff, XICAP_RESOURCE_DMADESC, &excite_scram_resource),
172 RINIT(slice_xicap, slice_xicap, XICAP_RESOURCE_GPI_SLICE, &excite_gpislice_resource),
173 RINIT(0x0100, 0x02ff, XICAP_RESOURCE_FIFO_BLK, &excite_fifomem_resource),
174 RINIT_IRQ(TITAN_IRQ, XICAP_RESOURCE_IRQ)
175};
176
177static struct platform_device xicap_pdev = {
178 .name = XICAP_NAME,
179 .id = XICAP_UNIT,
180 .num_resources = ARRAY_SIZE(xicap_rsrc),
181 .resource = xicap_rsrc
182};
183
184/*
185 * Create a platform device for the GPI port that receives the
186 * image data from the embedded camera.
187 */
188static int __init xicap_devinit(void)
189{
190 unsigned long tend;
191 u32 reg;
192 int retval;
193
194 adjust_resources(xicap_rsrc, ARRAY_SIZE(xicap_rsrc));
195
196 /* Power up the slice and configure it. */
197 reg = titan_readl(CPTC1R);
198 reg &= ~(0x11100 << slice_xicap);
199 titan_writel(reg, CPTC1R);
200
201 /* Enable slice & DLL. */
202 reg= titan_readl(CPRR);
203 reg &= ~(0x00030003 << (slice_xicap * 2));
204 titan_writel(reg, CPRR);
205
206 /* Wait for DLLs to lock */
207 tend = jiffies + DLL_TIMEOUT * HZ;
208 while (time_before(jiffies, tend)) {
209 if (!(~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4))))
210 break;
211 yield();
212 }
213
214 if (~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4))) {
215 printk(KERN_ERR "%s: DLL not locked after %u seconds\n",
216 xicap_pdev.name, DLL_TIMEOUT);
217 retval = -ETIME;
218 } else {
219 /* Register platform device */
220 retval = platform_device_register(&xicap_pdev);
221 }
222
223 return retval;
224}
225
226device_initcall(xicap_devinit);
227#endif /* defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE) */
228
229
230
231#if defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE)
232static struct resource wdt_rsrc[] = {
233 RINIT(0, 0, WDT_RESOURCE_COUNTER, &excite_ctr_resource),
234 RINIT(0x0084, 0x008f, WDT_RESOURCE_REGS, &excite_titan_resource),
235 RINIT_IRQ(TITAN_IRQ, WDT_RESOURCE_IRQ)
236};
237
238static struct platform_device wdt_pdev = {
239 .name = WDT_NAME,
240 .id = -1,
241 .num_resources = ARRAY_SIZE(wdt_rsrc),
242 .resource = wdt_rsrc
243};
244
245/*
246 * Create a platform device for the GPI port that receives the
247 * image data from the embedded camera.
248 */
249static int __init wdt_devinit(void)
250{
251 adjust_resources(wdt_rsrc, ARRAY_SIZE(wdt_rsrc));
252 return platform_device_register(&wdt_pdev);
253}
254
255device_initcall(wdt_devinit);
256#endif /* defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE) */
257
258
259
260static struct resource excite_nandflash_rsrc[] = {
261 RINIT(0x2000, 0x201f, EXCITE_NANDFLASH_RESOURCE_REGS, &excite_nand_resource)
262};
263
264static struct platform_device excite_nandflash_pdev = {
265 .name = "excite_nand",
266 .id = NAND_UNIT,
267 .num_resources = ARRAY_SIZE(excite_nandflash_rsrc),
268 .resource = excite_nandflash_rsrc
269};
270
271/*
272 * Create a platform device for the access to the nand-flash
273 * port
274 */
275static int __init excite_nandflash_devinit(void)
276{
277 adjust_resources(excite_nandflash_rsrc, ARRAY_SIZE(excite_nandflash_rsrc));
278
279 /* nothing to be done here */
280
281 /* Register platform device */
282 return platform_device_register(&excite_nandflash_pdev);
283}
284
285device_initcall(excite_nandflash_devinit);
286
287
288
289static struct resource iodev_rsrc[] = {
290 RINIT_IRQ(FPGA1_IRQ, IODEV_RESOURCE_IRQ)
291};
292
293static struct platform_device io_pdev = {
294 .name = IODEV_NAME,
295 .id = -1,
296 .num_resources = ARRAY_SIZE(iodev_rsrc),
297 .resource = iodev_rsrc
298};
299
300/*
301 * Create a platform device for the external I/O ports.
302 */
303static int __init io_devinit(void)
304{
305 adjust_resources(iodev_rsrc, ARRAY_SIZE(iodev_rsrc));
306 return platform_device_register(&io_pdev);
307}
308
309device_initcall(io_devinit);
310
311
312
313
314#if defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE)
315static struct resource rm9k_ge_rsrc[] = {
316 RINIT(0x2200, 0x27ff, RM9K_GE_RESOURCE_MAC, &excite_titan_resource),
317 RINIT(0x1800, 0x1fff, RM9K_GE_RESOURCE_MSTAT, &excite_titan_resource),
318 RINIT(0x2000, 0x212f, RM9K_GE_RESOURCE_PKTPROC, &excite_titan_resource),
319 RINIT(0x5140, 0x5227, RM9K_GE_RESOURCE_XDMA, &excite_titan_resource),
320 RINIT(0x4870, 0x489f, RM9K_GE_RESOURCE_FIFO_RX, &excite_titan_resource),
321 RINIT(0x494c, 0x4957, RM9K_GE_RESOURCE_FIFO_TX, &excite_titan_resource),
322 RINIT(0x0000, 0x007f, RM9K_GE_RESOURCE_FIFOMEM_RX, &excite_fifomem_resource),
323 RINIT(0x0080, 0x00ff, RM9K_GE_RESOURCE_FIFOMEM_TX, &excite_fifomem_resource),
324 RINIT(0x0180, 0x019f, RM9K_GE_RESOURCE_PHY, &excite_titan_resource),
325 RINIT(0x0000, 0x03ff, RM9K_GE_RESOURCE_DMADESC_RX, &excite_scram_resource),
326 RINIT(0x0400, 0x07ff, RM9K_GE_RESOURCE_DMADESC_TX, &excite_scram_resource),
327 RINIT(slice_eth, slice_eth, RM9K_GE_RESOURCE_GPI_SLICE, &excite_gpislice_resource),
328 RINIT(0, 0, RM9K_GE_RESOURCE_MDIO_CHANNEL, &excite_mdio_channel_resource),
329 RINIT_IRQ(TITAN_IRQ, RM9K_GE_RESOURCE_IRQ_MAIN),
330 RINIT_IRQ(PHY_IRQ, RM9K_GE_RESOURCE_IRQ_PHY)
331};
332
333static struct platform_device rm9k_ge_pdev = {
334 .name = RM9K_GE_NAME,
335 .id = RM9K_GE_UNIT,
336 .num_resources = ARRAY_SIZE(rm9k_ge_rsrc),
337 .resource = rm9k_ge_rsrc
338};
339
340
341
342/*
343 * Create a platform device for the Ethernet port.
344 */
345static int __init rm9k_ge_devinit(void)
346{
347 u32 reg;
348
349 adjust_resources(rm9k_ge_rsrc, ARRAY_SIZE(rm9k_ge_rsrc));
350
351 /* Power up the slice and configure it. */
352 reg = titan_readl(CPTC1R);
353 reg &= ~(0x11000 << slice_eth);
354 reg |= 0x100 << slice_eth;
355 titan_writel(reg, CPTC1R);
356
357 /* Take the MAC out of reset, reset the DLLs. */
358 reg = titan_readl(CPRR);
359 reg &= ~(0x00030000 << (slice_eth * 2));
360 reg |= 0x3 << (slice_eth * 2);
361 titan_writel(reg, CPRR);
362
363 return platform_device_register(&rm9k_ge_pdev);
364}
365
366device_initcall(rm9k_ge_devinit);
367#endif /* defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE) */
368
369
370
371static int __init excite_setup_devs(void)
372{
373 int res;
374 u32 reg;
375
376 /* Enable xdma and fifo interrupts */
377 reg = titan_readl(0x0050);
378 titan_writel(reg | 0x18000000, 0x0050);
379
380 res = request_resource(&iomem_resource, &excite_titan_resource);
381 if (res)
382 return res;
383 res = request_resource(&iomem_resource, &excite_scram_resource);
384 if (res)
385 return res;
386 res = request_resource(&iomem_resource, &excite_fpga_resource);
387 if (res)
388 return res;
389 res = request_resource(&iomem_resource, &excite_nand_resource);
390 if (res)
391 return res;
392 excite_fpga_resource.flags = excite_fpga_resource.parent->flags &
393 ( IORESOURCE_IO | IORESOURCE_MEM
394 | IORESOURCE_IRQ | IORESOURCE_DMA);
395 excite_nand_resource.flags = excite_nand_resource.parent->flags &
396 ( IORESOURCE_IO | IORESOURCE_MEM
397 | IORESOURCE_IRQ | IORESOURCE_DMA);
398
399 return 0;
400}
401
402arch_initcall(excite_setup_devs);
403