2 * Copyright (C) 2004 by Basler Vision Technologies AG
3 * Author: Thomas Koeller <thomas.koeller@baslerweb.com>
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.
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.
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
20 #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>
33 #include <rm9k_xicap.h>
34 #include <excite_nandflash.h>
36 #include "excite_iodev.h"
38 #define RM9K_GE_UNIT 0
42 #define DLL_TIMEOUT 3 /* seconds */
45 #define RINIT(__start__, __end__, __name__, __parent__) { \
46 .name = __name__ "_0", \
47 .start = (__start__), \
50 .parent = (__parent__) \
53 #define RINIT_IRQ(__irq__, __name__) { \
54 .name = __name__ "_0", \
57 .flags = IORESOURCE_IRQ, \
70 static struct resource
71 excite_ctr_resource __maybe_unused
= {
72 .name
= "GPI counters",
80 excite_gpislice_resource __maybe_unused
= {
89 excite_mdio_channel_resource __maybe_unused
= {
90 .name
= "MDIO channels",
98 excite_fifomem_resource __maybe_unused
= {
99 .name
= "FIFO memory",
107 excite_scram_resource __maybe_unused
= {
108 .name
= "Scratch RAM",
109 .start
= EXCITE_PHYS_SCRAM
,
110 .end
= EXCITE_PHYS_SCRAM
+ EXCITE_SIZE_SCRAM
- 1,
111 .flags
= IORESOURCE_MEM
,
116 excite_fpga_resource __maybe_unused
= {
117 .name
= "System FPGA",
118 .start
= EXCITE_PHYS_FPGA
,
119 .end
= EXCITE_PHYS_FPGA
+ EXCITE_SIZE_FPGA
- 1,
120 .flags
= IORESOURCE_MEM
,
125 excite_nand_resource __maybe_unused
= {
126 .name
= "NAND flash control",
127 .start
= EXCITE_PHYS_NAND
,
128 .end
= EXCITE_PHYS_NAND
+ EXCITE_SIZE_NAND
- 1,
129 .flags
= IORESOURCE_MEM
,
134 excite_titan_resource __maybe_unused
= {
135 .name
= "TITAN registers",
136 .start
= EXCITE_PHYS_TITAN
,
137 .end
= EXCITE_PHYS_TITAN
+ EXCITE_SIZE_TITAN
- 1,
138 .flags
= IORESOURCE_MEM
,
146 static void adjust_resources(struct resource
*res
, unsigned int n
)
149 const unsigned long mask
= IORESOURCE_IO
| IORESOURCE_MEM
150 | IORESOURCE_IRQ
| IORESOURCE_DMA
;
152 for (p
= res
; p
< res
+ n
; p
++) {
153 const struct resource
* const parent
= p
->parent
;
155 p
->start
+= parent
->start
;
156 p
->end
+= parent
->start
;
157 p
->flags
= parent
->flags
& mask
;
164 #if defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE)
165 static 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
)
177 static struct platform_device xicap_pdev
= {
180 .num_resources
= ARRAY_SIZE(xicap_rsrc
),
181 .resource
= xicap_rsrc
185 * Create a platform device for the GPI port that receives the
186 * image data from the embedded camera.
188 static int __init
xicap_devinit(void)
194 adjust_resources(xicap_rsrc
, ARRAY_SIZE(xicap_rsrc
));
196 /* Power up the slice and configure it. */
197 reg
= titan_readl(CPTC1R
);
198 reg
&= ~(0x11100 << slice_xicap
);
199 titan_writel(reg
, CPTC1R
);
201 /* Enable slice & DLL. */
202 reg
= titan_readl(CPRR
);
203 reg
&= ~(0x00030003 << (slice_xicap
* 2));
204 titan_writel(reg
, CPRR
);
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))))
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
);
219 /* Register platform device */
220 retval
= platform_device_register(&xicap_pdev
);
226 device_initcall(xicap_devinit
);
227 #endif /* defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE) */
231 #if defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE)
232 static 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
)
238 static struct platform_device wdt_pdev
= {
241 .num_resources
= ARRAY_SIZE(wdt_rsrc
),
246 * Create a platform device for the GPI port that receives the
247 * image data from the embedded camera.
249 static int __init
wdt_devinit(void)
251 adjust_resources(wdt_rsrc
, ARRAY_SIZE(wdt_rsrc
));
252 return platform_device_register(&wdt_pdev
);
255 device_initcall(wdt_devinit
);
256 #endif /* defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE) */
260 static struct resource excite_nandflash_rsrc
[] = {
261 RINIT(0x2000, 0x201f, EXCITE_NANDFLASH_RESOURCE_REGS
, &excite_nand_resource
)
264 static struct platform_device excite_nandflash_pdev
= {
265 .name
= "excite_nand",
267 .num_resources
= ARRAY_SIZE(excite_nandflash_rsrc
),
268 .resource
= excite_nandflash_rsrc
272 * Create a platform device for the access to the nand-flash
275 static int __init
excite_nandflash_devinit(void)
277 adjust_resources(excite_nandflash_rsrc
, ARRAY_SIZE(excite_nandflash_rsrc
));
279 /* nothing to be done here */
281 /* Register platform device */
282 return platform_device_register(&excite_nandflash_pdev
);
285 device_initcall(excite_nandflash_devinit
);
289 static struct resource iodev_rsrc
[] = {
290 RINIT_IRQ(FPGA1_IRQ
, IODEV_RESOURCE_IRQ
)
293 static struct platform_device io_pdev
= {
296 .num_resources
= ARRAY_SIZE(iodev_rsrc
),
297 .resource
= iodev_rsrc
301 * Create a platform device for the external I/O ports.
303 static int __init
io_devinit(void)
305 adjust_resources(iodev_rsrc
, ARRAY_SIZE(iodev_rsrc
));
306 return platform_device_register(&io_pdev
);
309 device_initcall(io_devinit
);
314 #if defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE)
315 static 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
)
333 static struct platform_device rm9k_ge_pdev
= {
334 .name
= RM9K_GE_NAME
,
336 .num_resources
= ARRAY_SIZE(rm9k_ge_rsrc
),
337 .resource
= rm9k_ge_rsrc
343 * Create a platform device for the Ethernet port.
345 static int __init
rm9k_ge_devinit(void)
349 adjust_resources(rm9k_ge_rsrc
, ARRAY_SIZE(rm9k_ge_rsrc
));
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
);
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
);
363 return platform_device_register(&rm9k_ge_pdev
);
366 device_initcall(rm9k_ge_devinit
);
367 #endif /* defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE) */
371 static int __init
excite_setup_devs(void)
376 /* Enable xdma and fifo interrupts */
377 reg
= titan_readl(0x0050);
378 titan_writel(reg
| 0x18000000, 0x0050);
380 res
= request_resource(&iomem_resource
, &excite_titan_resource
);
383 res
= request_resource(&iomem_resource
, &excite_scram_resource
);
386 res
= request_resource(&iomem_resource
, &excite_fpga_resource
);
389 res
= request_resource(&iomem_resource
, &excite_nand_resource
);
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
);
402 arch_initcall(excite_setup_devs
);