[storm] refresh patches
[openwrt/svn-archive/archive.git] / target / linux / storm / patches / 001-arch.patch
1 --- a/arch/arm/Kconfig
2 +++ b/arch/arm/Kconfig
3 @@ -220,6 +220,9 @@ config ARCH_EP93XX
4 help
5 This enables support for the Cirrus EP93xx series of CPUs.
6
7 +config ARCH_SL2312
8 + bool "SL2312"
9 +
10 config ARCH_FOOTBRIDGE
11 bool "FootBridge"
12 select FOOTBRIDGE
13 @@ -414,6 +417,8 @@ source "arch/arm/mach-ep93xx/Kconfig"
14
15 source "arch/arm/mach-footbridge/Kconfig"
16
17 +source "arch/arm/mach-sl2312/Kconfig"
18 +
19 source "arch/arm/mach-integrator/Kconfig"
20
21 source "arch/arm/mach-iop32x/Kconfig"
22 @@ -549,6 +554,16 @@ config PCI
23 config PCI_SYSCALL
24 def_bool PCI
25
26 +config SL2312_LPC
27 + bool "LPC Host Support"
28 + depends on ARCH_SL2312
29 + help
30 +
31 +config SL2312_LPC_IT8712
32 + bool "IT8712 Support"
33 + depends on ARCH_SL2312 && SL2312_LPC
34 + help
35 +
36 # Select the host bridge type
37 config PCI_HOST_VIA82C505
38 bool
39 @@ -988,6 +1003,10 @@ if ALIGNMENT_TRAP || !CPU_CP15_MMU
40 source "drivers/mtd/Kconfig"
41 endif
42
43 +if ARCH_SL2312
44 +source "drivers/telephony/Kconfig"
45 +endif
46 +
47 source "drivers/parport/Kconfig"
48
49 source "drivers/pnp/Kconfig"
50 @@ -997,7 +1016,7 @@ source "drivers/block/Kconfig"
51 if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
52 || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
53 || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
54 - || ARCH_IXP23XX
55 + || ARCH_IXP23XX || ARCH_SL2312
56 source "drivers/ide/Kconfig"
57 endif
58
59 --- a/arch/arm/Makefile
60 +++ b/arch/arm/Makefile
61 @@ -72,6 +72,7 @@ tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9
62 tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi
63 tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi
64 tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
65 +tune-$(CONFIG_CPU_FA52X) :=-mtune=arm9tdmi
66 tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
67 tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
68 tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
69 @@ -111,6 +112,7 @@ endif
70 machine-$(CONFIG_ARCH_PXA) := pxa
71 machine-$(CONFIG_ARCH_L7200) := l7200
72 machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
73 + machine-$(CONFIG_ARCH_SL2312) := sl2312
74 textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
75 machine-$(CONFIG_ARCH_CLPS711X) := clps711x
76 machine-$(CONFIG_ARCH_IOP32X) := iop32x
77 --- a/arch/arm/boot/compressed/Makefile
78 +++ b/arch/arm/boot/compressed/Makefile
79 @@ -19,6 +19,10 @@ ifeq ($(CONFIG_ARCH_SHARK),y)
80 OBJS += head-shark.o ofw-shark.o
81 endif
82
83 +ifeq ($(CONFIG_ARCH_SL2312),y)
84 +OBJS += head-sl2312.o
85 +endif
86 +
87 ifeq ($(CONFIG_ARCH_L7200),y)
88 OBJS += head-l7200.o
89 endif
90 --- /dev/null
91 +++ b/arch/arm/boot/compressed/head-sl2312.S
92 @@ -0,0 +1,6 @@
93 +#include <asm/mach-types.h>
94 +#include <asm/arch/sl2312.h>
95 +
96 + .section ".start", "ax"
97 + mov r7, #MACH_TYPE_SL2312
98 +
99 --- a/arch/arm/boot/compressed/head.S
100 +++ b/arch/arm/boot/compressed/head.S
101 @@ -57,6 +57,17 @@
102 mov \rb, #0x50000000
103 add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
104 .endm
105 +/*****************************************************
106 + * for Storlink SoC
107 + *****************************************************/
108 +#elif defined(CONFIG_ARCH_SL2312)
109 + .macro loadsp, rb
110 + mov \rb, #0x16000000
111 + .endm
112 + .macro writeb, rb
113 + strb \rb, [r3, #0]
114 + .endm
115 +/****************************************************/
116 #else
117 .macro loadsp, rb
118 addruart \rb
119 @@ -116,7 +127,28 @@ start:
120 .rept 8
121 mov r0, r0
122 .endr
123 -
124 +/*****************************************************************************
125 + * for Storlink Soc -- on chip UART
126 + *****************************************************************************/
127 +#ifndef CONFIG_SERIAL_IT8712 // Jason test
128 +@ mov r3, #0x22000000
129 + mov r3, #0x42000000
130 + mov r11, #0x80
131 + strb r11, [r3, #0xc]
132 + mov r11, #0x0
133 + strb r11, [r3, #0x4]
134 +#ifndef CONFIG_SL3516_ASIC
135 + mov r11, #0x9C /*0x9c->19200 0x4E->38400 0x34->57600 */
136 +#else
137 + mov r11, #0x9C /* 0x61 for 30MHz on GeminiA chip*/
138 +#endif
139 + strb r11, [r3, #0x0]
140 + mov r11, #0x03
141 + strb r11, [r3, #0xc]
142 + mov r11, #0xFB
143 + strb r11, [r3, #0x18]
144 +#endif
145 +/*****************************************************************************/
146 b 1f
147 .word 0x016f2818 @ Magic numbers to help the loader
148 .word start @ absolute load/run zImage address
149 @@ -458,6 +490,39 @@ __armv7_mmu_cache_on:
150 mcr p15, 0, r0, c7, c5, 4 @ ISB
151 mov pc, r12
152
153 +/*****************************************************************************
154 + * for Storlink Soc -- CPU cache
155 + *****************************************************************************/
156 +__fa526_cache_on:
157 + mov r12, lr
158 + bl __setup_mmu
159 + mov r0, #0
160 + mcr p15, 0, r0, c7, c6, 0 @ Invalidate D cache
161 + mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache
162 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
163 + mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
164 + mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
165 + mov r0, #-1
166 + mcr p15, 0, r0, c3, c0, 0 @ load domain access register
167 + mrc p15, 0, r0, c1, c0, 0
168 + mov r0, r0
169 + mov r0, r0
170 +#ifndef CONFIG_CPU_DCACHE_DISABLE
171 + orr r0, r0, #0x0004 @ .... .... .... .1..
172 +#endif
173 +#ifndef CONFIG_CPU_ICACHE_DISABLE
174 + orr r0, r0, #0x1000 @ ...1 .... .... ....
175 +#endif
176 +
177 +#ifndef DEBUG
178 + orr r0, r0, #0x0039 @ Write buffer, mmu
179 +#endif
180 + mcr p15, 0, r0, c1, c0
181 + mov r0, r0
182 + mov r0, r0
183 + mov pc, r12
184 +/********************************************************************************/
185 +
186 __arm6_mmu_cache_on:
187 mov r12, lr
188 bl __setup_mmu
189 @@ -625,6 +690,16 @@ proc_types:
190
191 @ These match on the architecture ID
192
193 +/*****************************************************************************
194 + * for Storlink Soc -- CPU architecture ID
195 + *****************************************************************************/
196 + .word 0x66015261 @ FA526
197 + .word 0xff01fff1
198 + b __fa526_cache_on
199 + b __fa526_cache_off
200 + b __fa526_cache_flush
201 +/*****************************************************************************/
202 +
203 .word 0x00020000 @ ARMv4T
204 .word 0x000f0000
205 b __armv4_mmu_cache_on
206 @@ -712,6 +787,23 @@ __armv7_mmu_cache_off:
207 mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB
208 mov pc, r12
209
210 +/*****************************************************************************
211 + * for Storlink Soc -- CPU cache
212 + *****************************************************************************/
213 +__fa526_cache_off:
214 + mrc p15, 0, r0, c1, c0
215 + bic r0, r0, #0x000d
216 + mov r1, #0
217 + mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
218 + mcr p15, 0, r1, c7, c10, 4 @ drain WB
219 + mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
220 + mov r0, #0
221 + mcr p15, 0, r0, c7, c5, 0 @ invalidate whole cache v4
222 + mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB v4
223 + mov pc, lr
224 +/*****************************************************************************/
225 +
226 +
227 __arm6_mmu_cache_off:
228 mov r0, #0x00000030 @ ARM6 control reg.
229 b __armv3_mmu_cache_off
230 @@ -759,6 +851,17 @@ __armv4_mpu_cache_flush:
231 mcr p15, 0, ip, c7, c10, 4 @ drain WB
232 mov pc, lr
233
234 +/*****************************************************************************
235 + * for Storlink Soc -- CPU cache
236 + *****************************************************************************/
237 +__fa526_cache_flush:
238 + mov r1, #0
239 + mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
240 + mcr p15, 0, r1, c7, c5, 0 @ flush I cache
241 + mcr p15, 0, r1, c7, c10, 4 @ drain WB
242 + mov pc, lr
243 +/*****************************************************************************/
244 +
245
246 __armv6_mmu_cache_flush:
247 mov r1, #0
248 --- /dev/null
249 +++ b/arch/arm/boot/compressed/it8712.h
250 @@ -0,0 +1,25 @@
251 +
252 +#ifndef __IT8712_H__
253 +#define __IT8712_H__
254 +
255 +#include "asm/arch/sl2312.h"
256 +
257 +#define IT8712_IO_BASE SL2312_LPC_IO_BASE
258 +//#define IT8712_IO_BASE 0x27000000
259 +// Device LDN
260 +#define LDN_SERIAL1 0x01
261 +#define LDN_SERIAL2 0x02
262 +#define LDN_PARALLEL 0x03
263 +#define LDN_KEYBOARD 0x05
264 +#define LDN_MOUSE 0x06
265 +#define LDN_GPIO 0x07
266 +
267 +#define IT8712_UART1_PORT 0x3F8
268 +#define IT8712_UART2_PORT 0x2F8
269 +
270 +#define IT8712_GPIO_BASE 0x800 // 0x800-0x804 for GPIO set1-set5
271 +
272 +void LPCSetConfig(char LdnNumber, char Index, char data);
273 +char LPCGetConfig(char LdnNumber, char Index);
274 +
275 +#endif
276 --- a/arch/arm/boot/compressed/misc.c
277 +++ b/arch/arm/boot/compressed/misc.c
278 @@ -30,7 +30,7 @@ static void putstr(const char *ptr);
279 #include <asm/arch/uncompress.h>
280
281 #ifdef CONFIG_DEBUG_ICEDCC
282 -
283 +#include "it8712.h"
284 #ifdef CONFIG_CPU_V6
285
286 static void icedcc_putc(int ch)
287 @@ -69,6 +69,7 @@ static void icedcc_putc(int ch)
288 #define flush() do { } while (0)
289 #endif
290
291 +#if 0
292 static void putstr(const char *ptr)
293 {
294 char c;
295 @@ -81,11 +82,36 @@ static void putstr(const char *ptr)
296
297 flush();
298 }
299 +#endif
300
301 #endif
302
303 #define __ptr_t void *
304
305 +#ifdef CONFIG_SERIAL_IT8712
306 +unsigned int it8712_uart_base;
307 +#define UART_RX 0
308 +#define UART_TX 0
309 +#define UART_DLL 0
310 +#define UART_TRG 0
311 +#define UART_DLM 1
312 +#define UART_IER 1
313 +#define UART_FCTR 1
314 +#define UART_IIR 2
315 +#define UART_FCR 2
316 +#define UART_EFR 2
317 +#define UART_LCR 3
318 +#define UART_MCR 4
319 +#define UART_LSR 5
320 +#define UART_MSR 6
321 +#define UART_SCR 7
322 +#define UART_EMSR 7
323 +void LPCEnterMBPnP(void);
324 +void LPCExitMBPnP(void);
325 +int SearchIT8712(void);
326 +int InitLPCInterface(void);
327 +#endif
328 +
329 /*
330 * Optimised C version of memzero for the ARM.
331 */
332 @@ -346,6 +372,9 @@ ulg
333 decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
334 int arch_id)
335 {
336 +#ifdef CONFIG_SERIAL_IT8712
337 + unsigned char *addr;
338 +#endif
339 output_data = (uch *)output_start; /* Points to kernel start */
340 free_mem_ptr = free_mem_ptr_p;
341 free_mem_ptr_end = free_mem_ptr_end_p;
342 @@ -353,6 +382,33 @@ decompress_kernel(ulg output_start, ulg
343
344 arch_decomp_setup();
345
346 +#ifdef CONFIG_SERIAL_IT8712
347 +
348 + InitLPCInterface();
349 + LPCSetConfig(0, 0x02, 0x01);
350 + LPCSetConfig(LDN_SERIAL1, 0x30, 0x1);
351 + LPCSetConfig(LDN_SERIAL1, 0x23, 0x0);
352 + it8712_uart_base = IT8712_IO_BASE;
353 + it8712_uart_base += ((LPCGetConfig(LDN_SERIAL1, 0x60) << 8) + LPCGetConfig(LDN_SERIAL1, 0x61));
354 +
355 + do {
356 + addr = (unsigned char *)(it8712_uart_base + UART_LCR) ;
357 + *addr = 0x80;
358 + // Set Baud Rate
359 + addr = (unsigned char *)(it8712_uart_base+UART_DLL);
360 + *addr = 0x06 ;
361 + addr = (unsigned char *)(it8712_uart_base+UART_DLM);
362 + *addr = 0x00 ;
363 +
364 + addr = (unsigned char *)(it8712_uart_base+UART_LCR); // LCR
365 + *addr = 0x07 ;
366 + addr = (unsigned char *)(it8712_uart_base+UART_MCR); // MCR
367 + *addr = 0x08 ;
368 + addr = (unsigned char *)(it8712_uart_base+UART_FCR); // FCR
369 + *addr = 0x01 ;
370 + } while(0);
371 +#endif
372 +
373 makecrc();
374 putstr("Uncompressing Linux...");
375 gunzip();
376 @@ -374,4 +430,119 @@ int main()
377 return 0;
378 }
379 #endif
380 +
381 +#ifdef CONFIG_SERIAL_IT8712
382 +
383 +#define LPC_KEY_ADDR (unsigned char *)(SL2312_LPC_IO_BASE + 0x2e)
384 +#define LPC_DATA_ADDR (unsigned char *)(SL2312_LPC_IO_BASE + 0x2f)
385 +#define LPC_BUS_CTRL *( unsigned char*) (SL2312_LPC_HOST_BASE + 0)
386 +#define LPC_BUS_STATUS *( unsigned char*) (SL2312_LPC_HOST_BASE + 2)
387 +#define LPC_SERIAL_IRQ_CTRL *( unsigned char*) (SL2312_LPC_HOST_BASE + 4)
388 +
389 +char LPCGetConfig(char LdnNumber, char Index)
390 +{
391 + char rtn;
392 + unsigned char *addr ;
393 +
394 + LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
395 +
396 + addr = LPC_KEY_ADDR;
397 + *addr = 0x07 ;
398 +
399 + addr = LPC_DATA_ADDR;
400 + *addr = LdnNumber ;
401 +
402 + addr = LPC_KEY_ADDR;
403 + *addr = Index ;
404 +
405 + addr = LPC_DATA_ADDR ;
406 + rtn = *addr ;
407 +
408 + LPCExitMBPnP();
409 + return rtn;
410 +
411 +}
412 +
413 +void LPCSetConfig(char LdnNumber, char Index, char data)
414 +{
415 + unsigned char *addr;
416 + LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
417 + addr = LPC_KEY_ADDR;
418 + *addr = 0x07;
419 + addr = LPC_DATA_ADDR;
420 + *addr = LdnNumber;
421 + addr = LPC_KEY_ADDR;
422 + *addr = Index;
423 + addr = LPC_DATA_ADDR;
424 + *addr = data;
425 +
426 + LPCExitMBPnP();
427 +}
428 +
429 +//unsigned char key[4] ;
430 +void LPCEnterMBPnP(void)
431 +{
432 + unsigned char *addr;
433 + addr = LPC_KEY_ADDR;
434 + unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
435 +
436 + do {
437 + *addr = key[0];
438 + *addr = key[1];
439 + *addr = key[2];
440 + *addr = key[3];
441 + }while(0);
442 +}
443 +
444 +void LPCExitMBPnP(void)
445 +{
446 + unsigned char *addr;
447 + addr = LPC_KEY_ADDR;
448 + *addr = 0x02 ;
449 +
450 + addr = LPC_DATA_ADDR;
451 + *addr = 0x02 ;
452 +}
453 +
454 +int InitLPCInterface(void)
455 +{
456 + int i;
457 + LPC_BUS_CTRL = 0xc0;
458 + LPC_SERIAL_IRQ_CTRL = 0xc0;
459 +
460 + for(i=0;i<0x2000;i++) ;
461 +
462 + LPC_SERIAL_IRQ_CTRL = 0x80;
463 + if (!SearchIT8712()) ;
464 +// while(1);
465 + return 0;
466 +}
467 +
468 +int SearchIT8712(void)
469 +{
470 + unsigned char Id1, Id2;
471 + unsigned short Id;
472 + unsigned char *addr;
473 +
474 + LPCEnterMBPnP();
475 + addr = LPC_KEY_ADDR;
476 + *addr = 0x20 ;
477 + addr = LPC_DATA_ADDR;
478 + Id1 = *addr ;
479 +
480 + addr = LPC_KEY_ADDR;
481 + *addr = 0x21 ;
482 + addr = LPC_DATA_ADDR;
483 + Id2 = *addr ;
484 +
485 + Id = (Id1 << 8) | Id2;
486 + LPCExitMBPnP();
487 +
488 + if (Id == 0x8712)
489 + return 1;
490 + else
491 + return 0;
492 +}
493 +
494 +#endif
495
496 --- a/arch/arm/kernel/entry-armv.S
497 +++ b/arch/arm/kernel/entry-armv.S
498 @@ -18,6 +18,8 @@
499 #include <asm/memory.h>
500 #include <asm/glue.h>
501 #include <asm/vfpmacros.h>
502 +#include <asm/arch/irqs.h>
503 +#include <asm/hardware.h>
504 #include <asm/arch/entry-macro.S>
505 #include <asm/thread_notify.h>
506
507 --- a/arch/arm/kernel/irq.c
508 +++ b/arch/arm/kernel/irq.c
509 @@ -40,6 +40,8 @@
510 #include <asm/system.h>
511 #include <asm/mach/time.h>
512
513 +extern int fixup_irq(unsigned int irq);
514 +
515 /*
516 * No architecture-specific irq_finish function defined in arm/arch/irqs.h.
517 */
518 @@ -111,8 +113,11 @@ static struct irq_desc bad_irq_desc = {
519 asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
520 {
521 struct pt_regs *old_regs = set_irq_regs(regs);
522 - struct irq_desc *desc = irq_desc + irq;
523 +// struct irq_desc *desc = irq_desc + irq;
524 + struct irq_desc *desc;
525
526 + irq = fixup_irq(irq);
527 + desc = irq_desc + irq;
528 /*
529 * Some hardware gives randomly wrong interrupts. Rather
530 * than crashing, do something sensible.
531 --- a/arch/arm/kernel/process.c
532 +++ b/arch/arm/kernel/process.c
533 @@ -117,7 +117,7 @@ void arm_machine_restart(char mode)
534 void (*pm_idle)(void);
535 EXPORT_SYMBOL(pm_idle);
536
537 -void (*pm_power_off)(void);
538 +//void (*pm_power_off)(void);
539 EXPORT_SYMBOL(pm_power_off);
540
541 void (*arm_pm_restart)(char str) = arm_machine_restart;
542 @@ -188,13 +188,37 @@ __setup("reboot=", reboot_setup);
543
544 void machine_halt(void)
545 {
546 + unsigned int reg_v;
547 +
548 + printk("arch_power_off\n");
549 +
550 + reg_v = readl(IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
551 + reg_v &= ~0x00000002;
552 + reg_v |= 0x1;
553 + mdelay(5);
554 + // Power off
555 + __raw_writel( reg_v, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
556 +
557 }
558
559
560 void machine_power_off(void)
561 {
562 - if (pm_power_off)
563 + unsigned int reg_v;
564 +
565 +// if (pm_power_off)
566 + if (&pm_power_off!=NULL)
567 pm_power_off();
568 +
569 + printk("arch_power_off\n");
570 +
571 + reg_v = readl(IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
572 + reg_v &= ~0x00000002;
573 + reg_v |= 0x1;
574 + mdelay(5);
575 + // Power off
576 + __raw_writel( reg_v, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
577 +
578 }
579
580 void machine_restart(char * __unused)
581 --- a/arch/arm/kernel/time.c
582 +++ b/arch/arm/kernel/time.c
583 @@ -502,8 +502,13 @@ static int __init timer_init_sysfs(void)
584
585 device_initcall(timer_init_sysfs);
586
587 +extern unsigned int rtc_get_time_second(void);
588 +
589 void __init time_init(void)
590 {
591 +#ifdef CONFIG_SL2312_RTC
592 + xtime.tv_sec = rtc_get_time_second() ;
593 +#endif
594 #ifndef CONFIG_GENERIC_TIME
595 if (system_timer->offset == NULL)
596 system_timer->offset = dummy_gettimeoffset;
597 --- /dev/null
598 +++ b/arch/arm/mach-sl2312/Kconfig
599 @@ -0,0 +1,33 @@
600 +
601 +menu "SL2312"
602 +
603 +config SL3516_ASIC
604 + bool "SL3516 ASIC version"
605 + depends on ARCH_SL2312
606 + help
607 + This option to select AISC or FPGA
608 +config PCI
609 + bool "SL2312 PCI"
610 + depends on ARCH_SL2312
611 + help
612 + This option to enable Storlink PCI controller
613 +
614 +config SL2312_LPC
615 + bool "SL2312 LPC"
616 + depends on ARCH_SL2312
617 + help
618 + This option to enable Low Pin Count controller
619 +
620 +config SL2312_USB
621 + bool "SL2312 USB"
622 + depends on ARCH_SL2312
623 + help
624 + This option to enable USB OTG host controller
625 +
626 +config GEMINI_IPI
627 + bool "Gemini IPI test"
628 + depends on ARCH_SL2312
629 + help
630 + Enable this option to test dual cpu Inter-Processor-Interrupt
631 +endmenu
632 +
633 --- /dev/null
634 +++ b/arch/arm/mach-sl2312/Makefile
635 @@ -0,0 +1,16 @@
636 +#
637 +# Makefile for the linux kernel.
638 +#
639 +
640 +# Object file lists.
641 +
642 +obj-y := arch.o irq.o mm.o time.o sl3516_device.o
643 +obj-m :=
644 +obj-n :=
645 +
646 +
647 +obj-$(CONFIG_PCI) += pci.o
648 +obj-$(CONFIG_SL2312_LPC) += lpc.o
649 +obj-$(CONFIG_SL2312_USB) += sl2312-otg.o # sl2312-otg-1.o
650 +obj-$(CONFIG_GEMINI_XOR_ACCE) += xor.o
651 +obj-$(CONFIG_GEMINI_IPI) += gemini_ipi.o
652 --- /dev/null
653 +++ b/arch/arm/mach-sl2312/Makefile.boot
654 @@ -0,0 +1,5 @@
655 + zreladdr-y := 0x00008000
656 +params_phys-y := 0x00508100
657 +#params_phys-y := 0x00008100
658 +initrd_phys-y := 0x00800000
659 +
660 --- /dev/null
661 +++ b/arch/arm/mach-sl2312/arch.c
662 @@ -0,0 +1,72 @@
663 +/*
664 + * linux/arch/arm/mach-epxa10db/arch.c
665 + *
666 + * Copyright (C) 2000 Deep Blue Solutions Ltd
667 + * Copyright (C) 2001 Altera Corporation
668 + *
669 + * This program is free software; you can redistribute it and/or modify
670 + * it under the terms of the GNU General Public License as published by
671 + * the Free Software Foundation; either version 2 of the License, or
672 + * (at your option) any later version.
673 + *
674 + * This program is distributed in the hope that it will be useful,
675 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
676 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
677 + * GNU General Public License for more details.
678 + *
679 + * You should have received a copy of the GNU General Public License
680 + * along with this program; if not, write to the Free Software
681 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
682 + */
683 +#include <linux/types.h>
684 +#include <linux/init.h>
685 +
686 +#include <asm/hardware.h>
687 +#include <asm/setup.h>
688 +#include <asm/mach-types.h>
689 +#include <asm/mach/time.h>
690 +#include <asm/mach/arch.h>
691 +
692 +extern void sl2312_map_io(void);
693 +extern void sl2312_init_irq(void);
694 +extern unsigned long sl2312_gettimeoffset (void);
695 +extern void __init sl2312_time_init(void);
696 +
697 +static struct sys_timer sl2312_timer = {
698 + .init = sl2312_time_init,
699 + .offset = sl2312_gettimeoffset,
700 +};
701 +
702 +static void __init
703 +sl2312_fixup(struct machine_desc *desc, struct tag *tags,
704 + char **cmdline, struct meminfo *mi)
705 +{
706 + mi->nr_banks = 1;
707 + mi->bank[0].start = 0;
708 +#ifdef CONFIG_GEMINI_IPI
709 + mi->bank[0].size = (64*1024*1024); // 128M
710 +#else
711 + mi->bank[0].size = (128*1024*1024); // 128M
712 +#endif
713 + mi->bank[0].node = 0;
714 +}
715 +
716 +/* MACHINE_START(SL2312, "GeminiA")
717 + MAINTAINER("Storlink Semi")
718 + BOOT_MEM(0x00000000, 0x90000000, 0xf0000000)
719 + FIXUP(sl2312_fixup)
720 + MAPIO(sl2312_map_io)
721 + INITIRQ(sl2312_init_irq)
722 + .timer = &sl2312_timer,
723 +MACHINE_END */
724 +
725 +MACHINE_START(SL2312, "GeminiA")
726 + /* .phys_ram = 0x00000000, */
727 + .phys_io = 0x7fffc000,
728 + .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc,
729 + .boot_params = 0x100,
730 + .fixup = sl2312_fixup,
731 + .map_io = sl2312_map_io,
732 + .init_irq = sl2312_init_irq,
733 + .timer = &sl2312_timer,
734 +MACHINE_END
735 --- /dev/null
736 +++ b/arch/arm/mach-sl2312/gemini_ipi.c
737 @@ -0,0 +1,593 @@
738 +/*
739 + * FILE NAME sl_cir.c
740 + *
741 + * BRIEF MODULE DESCRIPTION
742 + * IPI Driver for CPU1.
743 + *
744 + * Author: StorLink, Corp.
745 + * Jason Lee
746 + *
747 + * Copyright 2002~2006 StorLink, Corp.
748 + *
749 + * This program is free software; you can redistribute it and/or modify it
750 + * under the terms of the GNU General Public License as published by the
751 + * Free Software Foundation; either version 2 of the License, or (at your
752 + * option) any later version.
753 + *
754 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
755 + * WARRANTIES, INCLUDING, BUT NOT LIMit8712D TO, THE IMPLIED WARRANTIES OF
756 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
757 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
758 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
759 + * NOT LIMit8712D TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
760 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
761 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
762 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
763 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
764 + *
765 + * You should have received a copy of the GNU General Public License along
766 + * with this program; if not, writ8712 to the Free Software Foundation, Inc.,
767 + * 675 Mass Ave, Cambridge, MA 02139, USA.
768 + */
769 +
770 +#include <linux/module.h>
771 +#include <linux/types.h>
772 +#include <linux/kernel.h>
773 +#include <linux/miscdevice.h>
774 +#include <linux/init.h>
775 +#include <linux/pagemap.h>
776 +#include <asm/uaccess.h>
777 +#include <linux/ioport.h>
778 +#include <linux/sched.h>
779 +#include <linux/delay.h>
780 +#include <linux/fs.h>
781 +#include <linux/interrupt.h>
782 +#include <asm/io.h>
783 +#include <asm/delay.h>
784 +#include <linux/signal.h>
785 +#include <asm/arch/sl2312.h>
786 +#include <asm/arch/int_ctrl.h>
787 +#include <asm/arch/ipi.h>
788 +#include <linux/dma-mapping.h>
789 +
790 +
791 +#include <linux/mm.h>
792 +
793 +#include <linux/bootmem.h>
794 +
795 +#include <asm/hardware.h>
796 +#include <asm/page.h>
797 +#include <asm/setup.h>
798 +#include <asm/pgtable.h>
799 +#include <asm/pgalloc.h>
800 +
801 +#include <asm/mach/map.h>
802 +
803 +
804 +static int sl_ipi_debug = 1 ;
805 +#define DEB(x) if(sl_ipi_debug>=1) x
806 +
807 +#define SRAM_PTR IO_ADDRESS(SL2312_SRAM_BASE)
808 +volatile JSCALE_REQ_T *req=(JSCALE_REQ_T*)SRAM_PTR;
809 +volatile JSCALE_RSP_T *rsp=(JSCALE_RSP_T*)(SRAM_PTR+0x20);
810 +
811 +unsigned int jscale_status=0;
812 +
813 +#define JSCALE_WAIT 0
814 +#define XXXXXX_WAIT 1
815 +#define MAX_WAIT_Q 8
816 +wait_queue_head_t gemini_ipi_wait[MAX_WAIT_Q];
817 +
818 +#define DRAMCTL_DMA_CTL 0X20
819 +#define DRAMCTL_DMA_SA 0X24
820 +#define DRAMCTL_DMA_DA 0X28
821 +#define DRAMCTL_DMA_CNT 0X2C
822 +#define MEMCPY_UNIT 0x40000
823 +int hw_memcpy(const void *to, const void *from, unsigned int bytes)
824 +{
825 + unsigned int reg_a,reg_d;
826 + int count = bytes,i=0;
827 +
828 + consistent_sync((unsigned int *)to, bytes, DMA_BIDIRECTIONAL);
829 + consistent_sync((unsigned int *)from,bytes, DMA_TO_DEVICE);
830 +
831 + DEB(printk("hwmemcpy:count %d\n",count));
832 + while(count>0){
833 + // SA
834 + reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_SA;
835 + reg_d = (unsigned int )__virt_to_phys(from) + i*MEMCPY_UNIT;
836 + DEB(printk("hwmemcpy:from 0x%08x\n",reg_d));
837 + writel(reg_d,reg_a);
838 + // DA
839 + reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_DA;
840 + reg_d = (unsigned int )__virt_to_phys(to) + i*MEMCPY_UNIT;
841 + writel(reg_d,reg_a);
842 + DEB(printk("hwmemcpy:to 0x%08x\n",reg_d));
843 + // byte count
844 + reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CNT;
845 + reg_d = (count>=MEMCPY_UNIT)?MEMCPY_UNIT:count;
846 + writel(reg_d,reg_a);
847 + // start DMA
848 + reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CTL;
849 + writel(0x80000001,reg_a);
850 +
851 + do{
852 + cond_resched();
853 +// msleep(4);
854 + reg_d = readl(IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CTL);
855 + }while(reg_d&0x1);
856 +
857 + count -= MEMCPY_UNIT;
858 + i++;
859 + }
860 +
861 + return bytes;
862 +}
863 +
864 +static irqreturn_t ipi_interrupt()
865 +{
866 + unsigned int id=getcpuid(),tmp;
867 +
868 + //dmac_inv_range(__phys_to_virt(SL2312_SRAM_BASE),__phys_to_virt(SHAREADDR)+0x2000);
869 +
870 +
871 + // Clear Interrupt
872 + if(id==CPU0) {
873 + tmp = readl(CPU1_STATUS);
874 + tmp &= ~CPU_IPI_BIT_MASK;
875 + writel(tmp,CPU1_STATUS);
876 + }
877 + else{
878 + tmp = readl(CPU0_STATUS);
879 + tmp &= ~CPU_IPI_BIT_MASK;
880 + writel(tmp,CPU0_STATUS);
881 + }
882 +
883 + //
884 + DEB(printk("ipi interrupt:0x%x\n",rsp->status));
885 + switch(rsp->status){
886 + case JSCALE_STATUS_OK:
887 +
888 + break;
889 + case JSCALE_UNKNOWN_MSG_TYPE:
890 +
891 + break;
892 + case JSCALE_FAILED_FILE_SIZE:
893 +
894 + break;
895 + case JSCALE_FAILED_MALLOC:
896 +
897 + break;
898 + case JSCALE_FAILED_FORMAT:
899 +
900 + break;
901 + case JSCALE_DECODE_ERROR:
902 +
903 + break;
904 +
905 + }
906 + jscale_status = rsp->status;
907 +// wake_up(&gemini_ipi_wait[JSCALE_WAIT]);
908 +
909 + return IRQ_HANDLED;
910 +}
911 +
912 +static int gemini_ipi_open(struct inode *inode, struct file *file)
913 +{
914 + DEB(printk("ipi open\n"));
915 + return 0;
916 +}
917 +
918 +
919 +static int gemini_ipi_release(struct inode *inode, struct file *file)
920 +{
921 + DEB(printk("ipi release\n"));
922 + return 0;
923 +}
924 +
925 +
926 +static int gemini_ipi_ioctl(struct inode *inode, struct file *file,
927 + unsigned int cmd, unsigned long arg)
928 +{
929 + JSCALE_RSP_T tmp;
930 +
931 + switch(cmd) {
932 + case GEMINI_IPI_JSCALE_REQ:
933 + DEB(printk("ipi:ioctl jscale request %dX%d Q:%d\n",req->ScaledImageWidth,req->ScaledImageHeight,req->ScaledImageQuality));
934 + if (copy_from_user(req, (JSCALE_REQ_T *)arg, sizeof(JSCALE_REQ_T)))
935 + return -EFAULT;
936 + req->hdr.type = IPC_JSCALE_REQ_MSG;
937 + req->hdr.length = sizeof(JSCALE_REQ_T);
938 + req->input_location = CPU_1_DATA_OFFSET;
939 + req->output_location = CPU_1_DATA_OFFSET;
940 + break;
941 + case GEMINI_IPI_JSCALE_STAT:
942 + DEB(printk("ipi:ioctl jscale stat \n"));
943 + if(jscale_status==JSCALE_BUSY){ // not yet
944 + tmp.status = JSCALE_BUSY;
945 + if (copy_to_user((JSCALE_RSP_T *)arg,&tmp, sizeof(JSCALE_RSP_T)))
946 + return -EFAULT;
947 + }
948 + else{ // finish or error
949 + if (copy_to_user((JSCALE_RSP_T *)arg,rsp, sizeof(JSCALE_RSP_T)))
950 + return -EFAULT;
951 + }
952 + break;
953 + default:
954 + printk("IPI: Error IOCTL number\n");
955 + return -ENOIOCTLCMD;
956 + }
957 +
958 + return 0;
959 +}
960 +
961 +#define SRAM_SIZE 0x2000
962 +static ssize_t gemini_ipi_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
963 +{
964 + int i=0,tmp=0,j;
965 + const char *ptr=(unsigned int)__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET);
966 + DEB(printk("ipi:write 0x%x to 0x%x length:%d\n",&buf,ptr,count));
967 + memcpy(ptr,buf,count);
968 + consistent_sync(ptr,count, DMA_TO_DEVICE);
969 + //hw_memcpy(ptr,&buf,count);
970 +
971 +/* if(count>SRAM_SIZE){
972 + for(i=0;i<(count/SRAM_SIZE);i++)
973 + raid_memcpy(ptr+i*SRAM_SIZE,buf+i*SRAM_SIZE,SRAM_SIZE);
974 + if(count%SRAM_SIZE)
975 + raid_memcpy(ptr+i*SRAM_SIZE,buf+i*SRAM_SIZE,count%SRAM_SIZE);
976 + }
977 + else
978 + raid_memcpy(ptr,buf,count);
979 +*/
980 +
981 +/* for(i=0;i<count;i++){
982 + if(buf[i]!=ptr[i])
983 + printk("ipi error:offset %d valud %x[should %x]\n",i,ptr[i],buf[i]);
984 + }
985 +
986 + printk("===========input buf===============\n");
987 + for(i=0;i<64;i+=16){
988 + for(j=0;j<16;j++)
989 + printk("%02x ",buf[i+j]);
990 + printk("\n");
991 + cond_resched();
992 + }
993 + printk("===========output buf==============\n");
994 + for(i=0;i<64;i+=16){
995 + for(j=0;j<16;j++)
996 + printk("%02x ",ptr[i+j]);
997 + printk("\n");
998 + cond_resched();
999 + }
1000 +*/
1001 + // send irq for CPU1
1002 + tmp |= CPU_IPI_BIT_MASK;
1003 + writel(tmp,CPU0_STATUS);
1004 + jscale_status = JSCALE_BUSY;
1005 +
1006 + return count;
1007 +}
1008 +
1009 +static ssize_t gemini_ipi_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
1010 +{
1011 + int i=0;
1012 + const char *ptr=(unsigned int )__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET);
1013 +
1014 + consistent_sync(ptr,length, DMA_FROM_DEVICE);
1015 + memcpy(buf,ptr,length);
1016 + DEB(printk("ipi:read 0x%x to 0x%x length:%d\n",ptr,buf,length));
1017 +
1018 + //consistent_sync((unsigned int *)ptr,0x2000, DMA_FROM_DEVICE); // invalid
1019 + //hw_memcpy(buf,ptr,length);
1020 +
1021 + // need encoded file size ********
1022 +/* if(count>SRAM_SIZE){
1023 + for(i=0;i<(count/SRAM_SIZE);i++)
1024 + raid_memcpy(buf+i*SRAM_SIZE,p_mbox->message+i*SRAM_SIZE,SRAM_SIZE);
1025 + if(count%0xFFFF)
1026 + raid_memcpy(buf+i*SRAM_SIZE,p_mbox->message+i*SRAM_SIZE,length%SRAM_SIZE);
1027 + }
1028 + else
1029 + raid_memcpy(buf,p_mbox->message,length);
1030 +*/
1031 + return length;
1032 +}
1033 +
1034 +void do_mapping_read(struct address_space *mapping,
1035 + struct file_ra_state *_ra,
1036 + struct file *filp,
1037 + loff_t *ppos,
1038 + read_descriptor_t *desc,
1039 + read_actor_t actor)
1040 +{
1041 + struct inode *inode = mapping->host;
1042 + unsigned long index;
1043 + unsigned long end_index;
1044 + unsigned long offset;
1045 + unsigned long last_index;
1046 + unsigned long next_index;
1047 + unsigned long prev_index;
1048 + loff_t isize;
1049 + struct page *cached_page;
1050 + int error;
1051 + struct file_ra_state ra = *_ra;
1052 +
1053 + cached_page = NULL;
1054 + index = *ppos >> PAGE_CACHE_SHIFT;
1055 + next_index = index;
1056 + prev_index = ra.prev_page;
1057 + last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
1058 + offset = *ppos & ~PAGE_CACHE_MASK;
1059 +
1060 + isize = i_size_read(inode);
1061 + if (!isize)
1062 + goto out;
1063 +
1064 + end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
1065 + for (;;) {
1066 + struct page *page;
1067 + unsigned long nr, ret;
1068 +
1069 + /* nr is the maximum number of bytes to copy from this page */
1070 + nr = PAGE_CACHE_SIZE;
1071 + if (index >= end_index) {
1072 + if (index > end_index)
1073 + goto out;
1074 + nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
1075 + if (nr <= offset) {
1076 + goto out;
1077 + }
1078 + }
1079 + nr = nr - offset;
1080 +
1081 + cond_resched();
1082 + if (index == next_index)
1083 + next_index = page_cache_readahead(mapping, &ra, filp,
1084 + index, last_index - index);
1085 +
1086 +find_page:
1087 + page = find_get_page(mapping, index);
1088 + if (unlikely(page == NULL)) {
1089 + handle_ra_miss(mapping, &ra, index);
1090 + goto no_cached_page;
1091 + }
1092 + if (!PageUptodate(page))
1093 + goto page_not_up_to_date;
1094 +page_ok:
1095 +
1096 + /* If users can be writing to this page using arbitrary
1097 + * virtual addresses, take care about potential aliasing
1098 + * before reading the page on the kernel side.
1099 + */
1100 + if (mapping_writably_mapped(mapping))
1101 + flush_dcache_page(page);
1102 +
1103 + /*
1104 + * When (part of) the same page is read multiple times
1105 + * in succession, only mark it as accessed the first time.
1106 + */
1107 + if (prev_index != index)
1108 + mark_page_accessed(page);
1109 + prev_index = index;
1110 +
1111 + /*
1112 + * Ok, we have the page, and it's up-to-date, so
1113 + * now we can copy it to user space...
1114 + *
1115 + * The actor routine returns how many bytes were actually used..
1116 + * NOTE! This may not be the same as how much of a user buffer
1117 + * we filled up (we may be padding etc), so we can only update
1118 + * "pos" here (the actor routine has to update the user buffer
1119 + * pointers and the remaining count).
1120 + */
1121 + ret = actor(desc, page, offset, nr);
1122 + offset += ret;
1123 + index += offset >> PAGE_CACHE_SHIFT;
1124 + offset &= ~PAGE_CACHE_MASK;
1125 +
1126 + page_cache_release(page);
1127 + if (ret == nr && desc->count)
1128 + continue;
1129 + goto out;
1130 +
1131 +page_not_up_to_date:
1132 + /* Get exclusive access to the page ... */
1133 + lock_page(page);
1134 +
1135 + /* Did it get unhashed before we got the lock? */
1136 + if (!page->mapping) {
1137 + unlock_page(page);
1138 + page_cache_release(page);
1139 + continue;
1140 + }
1141 +
1142 + /* Did somebody else fill it already? */
1143 + if (PageUptodate(page)) {
1144 + unlock_page(page);
1145 + goto page_ok;
1146 + }
1147 +
1148 +readpage:
1149 + /* Start the actual read. The read will unlock the page. */
1150 + error = mapping->a_ops->readpage(filp, page);
1151 +
1152 + if (unlikely(error))
1153 + goto readpage_error;
1154 +
1155 + if (!PageUptodate(page)) {
1156 + lock_page(page);
1157 + if (!PageUptodate(page)) {
1158 + if (page->mapping == NULL) {
1159 + /*
1160 + * invalidate_inode_pages got it
1161 + */
1162 + unlock_page(page);
1163 + page_cache_release(page);
1164 + goto find_page;
1165 + }
1166 + unlock_page(page);
1167 + error = -EIO;
1168 + goto readpage_error;
1169 + }
1170 + unlock_page(page);
1171 + }
1172 +
1173 + /*
1174 + * i_size must be checked after we have done ->readpage.
1175 + *
1176 + * Checking i_size after the readpage allows us to calculate
1177 + * the correct value for "nr", which means the zero-filled
1178 + * part of the page is not copied back to userspace (unless
1179 + * another truncate extends the file - this is desired though).
1180 + */
1181 + isize = i_size_read(inode);
1182 + end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
1183 + if (unlikely(!isize || index > end_index)) {
1184 + page_cache_release(page);
1185 + goto out;
1186 + }
1187 +
1188 + /* nr is the maximum number of bytes to copy from this page */
1189 + nr = PAGE_CACHE_SIZE;
1190 + if (index == end_index) {
1191 + nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
1192 + if (nr <= offset) {
1193 + page_cache_release(page);
1194 + goto out;
1195 + }
1196 + }
1197 + nr = nr - offset;
1198 + goto page_ok;
1199 +
1200 +readpage_error:
1201 + /* UHHUH! A synchronous read error occurred. Report it */
1202 + desc->error = error;
1203 + page_cache_release(page);
1204 + goto out;
1205 +
1206 +no_cached_page:
1207 + /*
1208 + * Ok, it wasn't cached, so we need to create a new
1209 + * page..
1210 + */
1211 + if (!cached_page) {
1212 + cached_page = page_cache_alloc_cold(mapping);
1213 + if (!cached_page) {
1214 + desc->error = -ENOMEM;
1215 + goto out;
1216 + }
1217 + }
1218 + error = add_to_page_cache_lru(cached_page, mapping,
1219 + index, GFP_KERNEL);
1220 + if (error) {
1221 + if (error == -EEXIST)
1222 + goto find_page;
1223 + desc->error = error;
1224 + goto out;
1225 + }
1226 + page = cached_page;
1227 + cached_page = NULL;
1228 + goto readpage;
1229 + }
1230 +
1231 +out:
1232 + *_ra = ra;
1233 +
1234 + *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
1235 + if (cached_page)
1236 + page_cache_release(cached_page);
1237 + if (filp)
1238 + file_accessed(filp);
1239 +}
1240 +
1241 +int ipi_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
1242 +{
1243 + ssize_t written;
1244 + unsigned long count = desc->count;
1245 + struct file *file = desc->arg.data;
1246 + unsigned int *ptr_to=(unsigned int)__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET) + desc->written;
1247 + void *ptr_from;
1248 +
1249 + if (size > count)
1250 + size = count;
1251 +
1252 + ptr_from = page_address(page)+offset;
1253 + written = memcpy(ptr_to,ptr_from,size);
1254 +
1255 + if (written < 0) {
1256 + desc->error = written;
1257 + written = 0;
1258 + }
1259 + desc->count = count - written;
1260 + desc->written += written;
1261 + return written;
1262 +}
1263 +
1264 +ssize_t gemini_ipi_sendfile(struct file *in_file, loff_t *ppos,
1265 + size_t count, read_actor_t actor, void *TARGET)
1266 +{
1267 + read_descriptor_t desc;
1268 +
1269 + if (!count)
1270 + return 0;
1271 +
1272 + desc.written = 0;
1273 + desc.count = count;
1274 + desc.arg.data = TARGET;
1275 + desc.error = 0;
1276 +
1277 + do_mapping_read(in_file->f_mapping,&in_file->f_ra,in_file, ppos, &desc, ipi_send_actor);
1278 +
1279 + if (desc.written)
1280 + return desc.written;
1281 + return desc.error;
1282 +}
1283 +static struct file_operations gemini_ipi_fops = {
1284 + .owner = THIS_MODULE,
1285 + .ioctl = gemini_ipi_ioctl,
1286 + .open = gemini_ipi_open,
1287 + .release= gemini_ipi_release,
1288 + .write = gemini_ipi_write,
1289 + .read = gemini_ipi_read,
1290 + .sendfile = gemini_ipi_sendfile,
1291 +};
1292 +
1293 +#ifndef STORLINK_IPI
1294 +#define STORLINK_IPI 242 // Documents/devices.txt suggest to use 240~255 for local driver!!
1295 +#endif
1296 +
1297 +static struct miscdevice gemini_ipi_miscdev =
1298 +{
1299 + STORLINK_IPI,
1300 + "slave_ipc",
1301 + &gemini_ipi_fops
1302 +};
1303 +
1304 +int __init sl_ipi_init(void)
1305 +{
1306 +
1307 + printk("Gemini IPI Driver Initialization...\n");
1308 + printk("REQ Head :0x%x(phy:0x%x)\n",(unsigned int)req,(unsigned int)SL2312_SRAM_BASE);
1309 + printk("RSP Head :0x%x(phy:0x%x)\n",(unsigned int)rsp,(unsigned int)SL2312_SRAM_BASE+0x20);
1310 + printk("Data buff:0x%x(phy:0x%x)\n",__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET),CPU_1_MEM_BASE+CPU_1_DATA_OFFSET);
1311 +
1312 + misc_register(&gemini_ipi_miscdev);
1313 +
1314 + if (request_irq(IRQ_CPU0_IP_IRQ_OFFSET, ipi_interrupt, SA_INTERRUPT, "ipi", NULL))
1315 + printk("Error: Register IRQ for Storlink IPI failed\n");
1316 +
1317 + return 0;
1318 +}
1319 +
1320 +void __exit sl_ipi_exit(void)
1321 +{
1322 +
1323 +}
1324 +
1325 +module_init(sl_ipi_init);
1326 +module_exit(sl_ipi_exit);
1327 +
1328 +MODULE_AUTHOR("Jason Lee <jason@storlink.com.tw>");
1329 +MODULE_DESCRIPTION("Storlink IPI driver");
1330 +MODULE_LICENSE("GPL");
1331 --- /dev/null
1332 +++ b/arch/arm/mach-sl2312/hw_xor.h
1333 @@ -0,0 +1,573 @@
1334 +/*
1335 +* linux/include/asm-arm/xor.h
1336 +*
1337 +* Copyright (C) 2001 Storlink Semi.
1338 +* Jason Lee <jason@storlink.com.tw>
1339 +*
1340 +*/
1341 +#include <asm/arch/sl2312.h>
1342 +#include <asm/io.h>
1343 +//#include <linux/compatmac.h>
1344 +
1345 +#undef BIG_ENDIAN
1346 +#define CPU 0
1347 +#define DMA 1
1348 +
1349 +#define DESC_NO 8
1350 +#define TX_DESC_NUM DESC_NO
1351 +#define RX_DESC_NUM DESC_NO
1352 +
1353 +#define RAID_BASE_ADDR IO_ADDRESS(SL2312_RAID_BASE)
1354 +
1355 +#define SRAM_PAR_0k 0
1356 +#define SRAM_PAR_4k 1
1357 +#define SRAM_PAR_8k 2
1358 +#define SRAM_PAR_16k 3
1359 +#define SRAM_PAR_SIZE SRAM_PAR_8k
1360 +
1361 +#define RUNNING 0x1
1362 +#define COMPLETE 0x2
1363 +#define ERROR 0x4
1364 +
1365 +#define CMD_XOR 0x0
1366 +#define CMD_FILL 0x1
1367 +#define CMD_CPY 0x3
1368 +#define CMD_CHK 0x4
1369 +
1370 +enum RAID_DMA_REGISTER {
1371 + RAID_DMA_DEVICE_ID = 0xff00,
1372 + RAID_DMA_STATUS = 0xff04,
1373 + RAID_FCHDMA_CTRL = 0xff08,
1374 + RAID_FCHDMA_FIRST_DESC = 0xff0C,
1375 + RAID_FCHDMA_CURR_DESC = 0xff10,
1376 + RAID_STRDMA_CTRL = 0xff14,
1377 + RAID_STRDMA_FIRST_DESC = 0xff18,
1378 + RAID_STRDMA_CURR_DESC = 0xff1C,
1379 + RAID_TX_FLG_REG = 0xff24,
1380 + RAID_RX_FLG_REG = 0xff34,
1381 + RAID_PCR = 0xff50,
1382 + SMC_CMD_REG = 0xff60,
1383 + SMC_STATUS_REG = 0xff64
1384 + };
1385 +
1386 +enum RAID_FUNC_MODE {
1387 + RAID_XOR = 0,
1388 + RAID_MIX = 2,
1389 + RAID_SRAM = 3,
1390 + RAID_ENDIAN = 4,
1391 + RAID_MEM_BLK = 5,
1392 + RAID_MEM2MEM = 7,
1393 + RAID_BUF_SIZE = 8,
1394 + RAID_ERR_TEST = 9,
1395 + RAID_BURST = 10,
1396 + RAID_BUS = 11
1397 + };
1398 +
1399 +typedef struct reg_info {
1400 + int mask;
1401 + char err[32];
1402 + int offset;
1403 +} REG_INFO;
1404 +
1405 +/********************************************************/
1406 +/* the definition of RAID DMA Module Register */
1407 +/********************************************************/
1408 +typedef union
1409 +{
1410 + unsigned int bit32;
1411 + struct bits_ff00
1412 + {
1413 + #ifdef BIG_ENDIAN
1414 + unsigned int : 8;
1415 + unsigned int teytPerr : 4; /* define protocol error under tsPErrI*/
1416 + unsigned int reytPerr : 14; /* define protocol error under rsPErrI */
1417 + unsigned int device_id : 12;
1418 + unsigned int revision_id : 4;
1419 + #else
1420 + unsigned int revision_id : 4;
1421 + unsigned int device_id : 12;
1422 + unsigned int reytPerr : 14; /* define protocol error under rsPErrI */
1423 + unsigned int teytPerr : 4; /* define protocol error under tsPErrI*/
1424 + unsigned int : 8;
1425 + #endif
1426 + } bits;
1427 +} RAID_DMA_DEVICE_ID_T;
1428 +
1429 +typedef union
1430 +{
1431 + unsigned int bits32;
1432 + struct bits_ff04
1433 + {
1434 + #ifdef BIG_ENDIAN
1435 + unsigned int tsFinishI : 1; /* owner bit error interrupt */
1436 + unsigned int tsDErrI : 1; /* AHB bus error interrupt */
1437 + unsigned int tsPErrI : 1; /* RAID XOR fetch descriptor protocol error interrupt */
1438 + unsigned int tsEODI : 1; /* RAID XOR fetch DMA end of descriptor interrupt */
1439 + unsigned int tsEOFI : 1; /* RAID XOR fetch DMA end of frame interrupt */
1440 + unsigned int rsFinishI : 1; /* owner bit error interrupt */
1441 + unsigned int rsDErrI : 1; /* AHB bus error while RAID XOR store interrupt */
1442 + unsigned int rsPErrI : 1; /* RAID XOR store descriptor protocol error interrupt */
1443 + unsigned int rsEODI : 1; /* RAID XOR store DMA end of descriptor interrupt */
1444 + unsigned int rsEOFI : 1; /* RAID XOR store DMA end of frame interrupt */
1445 + unsigned int inter : 8; /* pattern check error interrupt */
1446 + unsigned int : 5;
1447 + unsigned int Loopback : 1; /* loopback */
1448 + unsigned int intEnable : 8; /*pattern check error interrupt enable */
1449 + #else
1450 + unsigned int intEnable : 8; /*pattern check error interrupt enable */
1451 + unsigned int Loopback : 1; /* loopback */
1452 + unsigned int : 5;
1453 + unsigned int inter : 8; /* pattern check error interrupt */
1454 + unsigned int rsEOFI : 1; /* RAID XOR store DMA end of frame interrupt */
1455 + unsigned int rsEODI : 1; /* RAID XOR store DMA end of descriptor interrupt */
1456 + unsigned int rsPErrI : 1; /* RAID XOR store descriptor protocol error interrupt */
1457 + unsigned int rsDErrI : 1; /* AHB bus error while RAID XOR store interrupt */
1458 + unsigned int rsFinishI : 1; /* owner bit error interrupt */
1459 + unsigned int tsEOFI : 1; /* RAID XOR fetch DMA end of frame interrupt */
1460 + unsigned int tsEODI : 1; /* RAID XOR fetch DMA end of descriptor interrupt */
1461 + unsigned int tsPErrI : 1; /* RAID XOR fetch descriptor protocol error interrupt */
1462 + unsigned int tsDErrI : 1; /* AHB bus error interrupt */
1463 + unsigned int tsFinishI : 1; /* owner bit error interrupt */
1464 + #endif
1465 + } bits;
1466 +} RAID_DMA_STATUS_T;
1467 +
1468 +
1469 +typedef union
1470 +{
1471 + unsigned int bits32;
1472 + struct bits_ff08
1473 + {
1474 + #ifdef BIG_ENDIAN
1475 + unsigned int td_start : 1; /* Start DMA transfer */
1476 + unsigned int td_continue : 1; /* Continue DMA operation */
1477 + unsigned int td_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
1478 + unsigned int : 1;
1479 + unsigned int td_prot : 4; /* DMA protection control */
1480 + unsigned int td_burst_size : 2; /* DMA max burst size for every AHB request */
1481 + unsigned int td_bus : 2; /* peripheral bus width */
1482 + unsigned int td_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */
1483 + unsigned int td_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
1484 + unsigned int td_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */
1485 + unsigned int td_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */
1486 + unsigned int td_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */
1487 + unsigned int td_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */
1488 + unsigned int : 14;
1489 + #else
1490 + unsigned int : 14;
1491 + unsigned int td_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */
1492 + unsigned int td_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */
1493 + unsigned int td_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */
1494 + unsigned int td_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */
1495 + unsigned int td_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
1496 + unsigned int td_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */
1497 + unsigned int td_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */
1498 + unsigned int td_burst_size : 2; /* TxDMA max burst size for every AHB request */
1499 + unsigned int td_prot : 4; /* TxDMA protection control */
1500 + unsigned int : 1;
1501 + unsigned int td_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
1502 + unsigned int td_continue : 1; /* Continue DMA operation */
1503 + unsigned int td_start : 1; /* Start DMA transfer */
1504 + #endif
1505 + } bits;
1506 +} RAID_TXDMA_CTRL_T;
1507 +
1508 +typedef union
1509 +{
1510 + unsigned int bits32;
1511 + struct bits_ff0c
1512 + {
1513 + #ifdef BIG_ENDIAN
1514 + unsigned int td_first_des_ptr : 28;/* first descriptor address */
1515 + unsigned int td_busy : 1;/* 1-TxDMA busy; 0-TxDMA idle */
1516 + unsigned int : 3;
1517 + #else
1518 + unsigned int : 3;
1519 + unsigned int td_busy : 1;/* 1-TxDMA busy; 0-TxDMA idle */
1520 + unsigned int td_first_des_ptr : 28;/* first descriptor address */
1521 + #endif
1522 + } bits;
1523 +} RAID_TXDMA_FIRST_DESC_T;
1524 +
1525 +typedef union
1526 +{
1527 + unsigned int bits32;
1528 + struct bits_ff10
1529 + {
1530 + #ifdef BIG_ENDIAN
1531 + unsigned int ndar : 28; /* next descriptor address */
1532 + unsigned int eofie : 1; /* end of frame interrupt enable */
1533 + unsigned int : 1;
1534 + unsigned int sof_eof : 2;
1535 + #else
1536 + unsigned int sof_eof : 2;
1537 + unsigned int : 1;
1538 + unsigned int eofie : 1; /* end of frame interrupt enable */
1539 + unsigned int ndar : 28; /* next descriptor address */
1540 + #endif
1541 + } bits;
1542 +} RAID_TXDMA_CURR_DESC_T;
1543 +
1544 +typedef union
1545 +{
1546 + unsigned int bits32;
1547 + struct bits_ff14
1548 + {
1549 + #ifdef BIG_ENDIAN
1550 + unsigned int rd_start : 1; /* Start DMA transfer */
1551 + unsigned int rd_continue : 1; /* Continue DMA operation */
1552 + unsigned int rd_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
1553 + unsigned int : 1;
1554 + unsigned int rd_prot : 4; /* DMA protection control */
1555 + unsigned int rd_burst_size : 2; /* DMA max burst size for every AHB request */
1556 + unsigned int rd_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */
1557 + unsigned int rd_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */
1558 + unsigned int rd_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
1559 + unsigned int rd_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */
1560 + unsigned int rd_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */
1561 + unsigned int rd_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */
1562 + unsigned int rd_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */
1563 + unsigned int : 14;
1564 + #else
1565 + unsigned int : 14;
1566 + unsigned int rd_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */
1567 + unsigned int rd_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */
1568 + unsigned int rd_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */
1569 + unsigned int rd_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */
1570 + unsigned int rd_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
1571 + unsigned int rd_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */
1572 + unsigned int rd_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */
1573 + unsigned int rd_burst_size : 2; /* DMA max burst size for every AHB request */
1574 + unsigned int rd_prot : 4; /* DMA protection control */
1575 + unsigned int : 1;
1576 + unsigned int rd_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
1577 + unsigned int rd_continue : 1; /* Continue DMA operation */
1578 + unsigned int rd_start : 1; /* Start DMA transfer */
1579 + #endif
1580 + } bits;
1581 +} RAID_RXDMA_CTRL_T;
1582 +
1583 +typedef union
1584 +{
1585 + unsigned int bits32;
1586 + struct bits_ff18
1587 + {
1588 + #ifdef BIG_ENDIAN
1589 + unsigned int rd_first_des_ptr : 28;/* first descriptor address */
1590 + unsigned int rd_busy : 1;/* 1-RxDMA busy; 0-RxDMA idle */
1591 + unsigned int : 3;
1592 + #else
1593 + unsigned int : 3;
1594 + unsigned int rd_busy : 1;/* 1-RxDMA busy; 0-RxDMA idle */
1595 + unsigned int rd_first_des_ptr : 28;/* first descriptor address */
1596 + #endif
1597 + } bits;
1598 +} RAID_RXDMA_FIRST_DESC_T;
1599 +
1600 +typedef union
1601 +{
1602 + unsigned int bits32;
1603 + struct bits_ff1c
1604 + {
1605 + #ifdef BIG_ENDIAN
1606 + unsigned int ndar : 28; /* next descriptor address */
1607 + unsigned int eofie : 1; /* end of frame interrupt enable */
1608 + unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */
1609 + unsigned int sof_eof : 2;
1610 + #else
1611 + unsigned int sof_eof : 2;
1612 + unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */
1613 + unsigned int eofie : 1; /* end of frame interrupt enable */
1614 + unsigned int ndar : 28; /* next descriptor address */
1615 + #endif
1616 + } bits;
1617 +} RAID_RXDMA_CURR_DESC_T;
1618 +
1619 +typedef union
1620 +{
1621 + unsigned int bit32;
1622 + struct bits_ff50
1623 + {
1624 + unsigned int pat : 32; /* data for pattern check */
1625 + } bits;
1626 +} RAID_PACR_T;
1627 +
1628 +/******************************************************/
1629 +/* the definition of DMA Descriptor Register */
1630 +/******************************************************/
1631 +typedef struct raid_descriptor_t
1632 +{
1633 + union func_ctrl_t
1634 + {
1635 + unsigned int bit32;
1636 + struct bits_0000
1637 + {
1638 + #ifdef BIG_ENDIAN
1639 + unsigned int own : 1; /* owner bit */
1640 + unsigned int derr : 1; /* data error during processing this descriptor */
1641 + unsigned int perr : 1; /* protocol error during processing this descriptor */
1642 + unsigned int raid_ctrl_status : 7; /* pass RAID XOR fetch/store control status to CPU */
1643 + unsigned int desc_cnt : 6;
1644 + unsigned int buffer_size : 16; /* transfer buffer size associated with current description*/
1645 + #else
1646 + unsigned int buffer_size : 16; /* transfer buffer size associated with current description*/
1647 + unsigned int desc_cnt : 6;
1648 + unsigned int raid_ctrl_status : 7; /* pass RAID XOR fetch/store control status to CPU */
1649 + unsigned int perr : 1; /* protocol error during processing this descriptor */
1650 + unsigned int derr : 1; /* data error during processing this descriptor */
1651 + unsigned int own : 1; /* owner bit */
1652 + #endif
1653 + } bits;
1654 + } func_ctrl;
1655 +
1656 + union flg_status_t
1657 + {
1658 + unsigned int bits32;
1659 + struct bit_004
1660 + {
1661 + #ifdef BIG_ENDIAN
1662 + unsigned int bcc : 16;
1663 + unsigned int : 13
1664 + unsigned int mode : 3;
1665 + #else
1666 + unsigned int mode : 3;
1667 + unsigned int : 13;
1668 + unsigned int bcc : 16;
1669 + #endif
1670 + } bits_cmd_status;
1671 + } flg_status; //Sanders
1672 +
1673 + unsigned int buf_addr;
1674 +
1675 + union next_desc_addr_t
1676 + {
1677 + unsigned int bits32;
1678 + struct bits_000c
1679 + {
1680 + #ifdef BIG_ENDIAN
1681 + unsigned int ndar : 28; /* next descriptor address */
1682 + unsigned int eofie : 1; /* end of frame interrupt enable */
1683 + unsigned int : 1;
1684 + unsigned int sof_eof : 2; /* the position of the descriptor in chain */
1685 + #else
1686 + unsigned int sof_eof : 2; /* the position of the descriptor in chain */
1687 + unsigned int : 1;
1688 + unsigned int eofie : 1; /* end of frame interrupt enable */
1689 + unsigned int ndar : 28; /* next descriptor address */
1690 + #endif
1691 + } bits;
1692 + } next_desc_addr;
1693 +} RAID_DESCRIPTOR_T;
1694 +
1695 +/******************************************************/
1696 +/* the offset of RAID SMC register */
1697 +/******************************************************/
1698 +enum RAID_SMC_REGISTER {
1699 + RAID_SMC_CMD_REG = 0xff60,
1700 + RAID_SMC_STATUS_REG = 0xff64
1701 + };
1702 +
1703 +/******************************************************/
1704 +/* the definition of RAID SMC module register */
1705 +/******************************************************/
1706 +typedef union
1707 +{
1708 + unsigned int bits32;
1709 + struct bits_ff60
1710 + {
1711 + #ifdef BIG_ENDIAN
1712 + unsigned int pat_mode : 2; /* partition mode selection */
1713 + unsigned int : 14;
1714 + unsigned int device_id : 12;
1715 + unsigned int revision_id : 4;
1716 + #else
1717 + unsigned int revision_id : 4;
1718 + unsigned int device_id : 12;
1719 + unsigned int : 14;
1720 + unsigned int pat_mode : 2; /* partition mode selection */
1721 + #endif
1722 + } bits;
1723 +} RAID_SMC_CMD;
1724 +
1725 +typedef union
1726 +{
1727 + unsigned int bits32;
1728 + struct bits_ff64
1729 + {
1730 + #ifdef BIG_ENDIAN
1731 + unsigned int addr_err1 : 1; /* address is out of range for controller 1 */
1732 + unsigned int ahb_err1 : 1; /* AHB bus error for controller 1 */
1733 + unsigned int : 14;
1734 + unsigned int addr_err2 : 1; /* address is out of range for controller 2 */
1735 + unsigned int ahb_err2 : 1; /* AHB bus error for controller 2 */
1736 + unsigned int : 14;
1737 + #else
1738 + unsigned int : 14;
1739 + unsigned int ahb_err2 : 1; /* AHB bus error for controller 2 */
1740 + unsigned int addr_err2 : 1; /* address is out of range for controller 2 */
1741 + unsigned int : 14;
1742 + unsigned int ahb_err1 : 1; /* AHB bus error for controller 1 */
1743 + unsigned int addr_err1 : 1; /* address is out of range for controller 1 */
1744 + #endif
1745 + } bits;
1746 +} RAID_SMC_STATUS;
1747 +
1748 +typedef struct RAID_S
1749 +{
1750 + const char *device_name;
1751 + wait_queue_head_t wait;
1752 + unsigned int busy;
1753 + int irq;
1754 + unsigned int status;
1755 + RAID_DESCRIPTOR_T *tx_desc; /* point to virtual TX descriptor address */
1756 + RAID_DESCRIPTOR_T *rx_desc; /* point ot virtual RX descriptor address */
1757 + RAID_DESCRIPTOR_T *tx_cur_desc; /* current TX descriptor */
1758 + RAID_DESCRIPTOR_T *rx_cur_desc; /* current RX descriptor */
1759 + RAID_DESCRIPTOR_T *tx_finished_desc;
1760 + RAID_DESCRIPTOR_T *rx_finished_desc;
1761 + RAID_DESCRIPTOR_T *tx_first_desc;
1762 + RAID_DESCRIPTOR_T *rx_first_desc;
1763 +
1764 +// unsigned int *tx_buf[TX_DESC_NUM];
1765 + unsigned int *rx_desc_dma; // physical address of rx_descript
1766 + unsigned int *tx_desc_dma; // physical address of tx_descript
1767 + unsigned int *rx_bufs_dma;
1768 + unsigned int *tx_bufs_dma;
1769 +
1770 +} RAID_T;
1771 +
1772 +struct reg_ioctl
1773 +{
1774 + unsigned int reg_addr;
1775 + unsigned int val_in;
1776 + unsigned int val_out;
1777 +};
1778 +
1779 +typedef struct dma_ctrl {
1780 + int sram;
1781 + int prot;
1782 + int burst;
1783 + int bus;
1784 + int endian;
1785 + int mode;
1786 +} DMA_CTRL;
1787 +
1788 +
1789 +#ifdef XOR_SW_FILL_IN
1790 +
1791 +#define __XOR(a1, a2) a1 ^= a2
1792 +
1793 +#define GET_BLOCK_2(dst) \
1794 + __asm__("ldmia %0, {%1, %2}" \
1795 + : "=r" (dst), "=r" (a1), "=r" (a2) \
1796 + : "0" (dst))
1797 +
1798 +#define GET_BLOCK_4(dst) \
1799 + __asm__("ldmia %0, {%1, %2, %3, %4}" \
1800 + : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
1801 + : "0" (dst))
1802 +
1803 +#define XOR_BLOCK_2(src) \
1804 + __asm__("ldmia %0!, {%1, %2}" \
1805 + : "=r" (src), "=r" (b1), "=r" (b2) \
1806 + : "0" (src)); \
1807 + __XOR(a1, b1); __XOR(a2, b2);
1808 +
1809 +#define XOR_BLOCK_4(src) \
1810 + __asm__("ldmia %0!, {%1, %2, %3, %4}" \
1811 + : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
1812 + : "0" (src)); \
1813 + __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
1814 +
1815 +#define PUT_BLOCK_2(dst) \
1816 + __asm__ __volatile__("stmia %0!, {%2, %3}" \
1817 + : "=r" (dst) \
1818 + : "0" (dst), "r" (a1), "r" (a2))
1819 +
1820 +#define PUT_BLOCK_4(dst) \
1821 + __asm__ __volatile__("stmia %0!, {%2, %3, %4, %5}" \
1822 + : "=r" (dst) \
1823 + : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
1824 +
1825 +static void
1826 +xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
1827 +{
1828 + unsigned int lines = bytes / sizeof(unsigned long) / 4;
1829 + register unsigned int a1 __asm__("r4");
1830 + register unsigned int a2 __asm__("r5");
1831 + register unsigned int a3 __asm__("r6");
1832 + register unsigned int a4 __asm__("r7");
1833 + register unsigned int b1 __asm__("r8");
1834 + register unsigned int b2 __asm__("r9");
1835 + register unsigned int b3 __asm__("ip");
1836 + register unsigned int b4 __asm__("lr");
1837 +
1838 + do {
1839 + GET_BLOCK_4(p1);
1840 + XOR_BLOCK_4(p2);
1841 + PUT_BLOCK_4(p1);
1842 + } while (--lines);
1843 +}
1844 +
1845 +static void
1846 +xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
1847 + unsigned long *p3)
1848 +{
1849 + unsigned int lines = bytes / sizeof(unsigned long) / 4;
1850 + register unsigned int a1 __asm__("r4");
1851 + register unsigned int a2 __asm__("r5");
1852 + register unsigned int a3 __asm__("r6");
1853 + register unsigned int a4 __asm__("r7");
1854 + register unsigned int b1 __asm__("r8");
1855 + register unsigned int b2 __asm__("r9");
1856 + register unsigned int b3 __asm__("ip");
1857 + register unsigned int b4 __asm__("lr");
1858 +
1859 + do {
1860 + GET_BLOCK_4(p1);
1861 + XOR_BLOCK_4(p2);
1862 + XOR_BLOCK_4(p3);
1863 + PUT_BLOCK_4(p1);
1864 + } while (--lines);
1865 +}
1866 +
1867 +static void
1868 +xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
1869 + unsigned long *p3, unsigned long *p4)
1870 +{
1871 + unsigned int lines = bytes / sizeof(unsigned long) / 2;
1872 + register unsigned int a1 __asm__("r8");
1873 + register unsigned int a2 __asm__("r9");
1874 + register unsigned int b1 __asm__("ip");
1875 + register unsigned int b2 __asm__("lr");
1876 +
1877 + do {
1878 + GET_BLOCK_2(p1);
1879 + XOR_BLOCK_2(p2);
1880 + XOR_BLOCK_2(p3);
1881 + XOR_BLOCK_2(p4);
1882 + PUT_BLOCK_2(p1);
1883 + } while (--lines);
1884 +}
1885 +
1886 +static void
1887 +xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
1888 + unsigned long *p3, unsigned long *p4, unsigned long *p5)
1889 +{
1890 + unsigned int lines = bytes / sizeof(unsigned long) / 2;
1891 + register unsigned int a1 __asm__("r8");
1892 + register unsigned int a2 __asm__("r9");
1893 + register unsigned int b1 __asm__("ip");
1894 + register unsigned int b2 __asm__("lr");
1895 +
1896 + do {
1897 + GET_BLOCK_2(p1);
1898 + XOR_BLOCK_2(p2);
1899 + XOR_BLOCK_2(p3);
1900 + XOR_BLOCK_2(p4);
1901 + XOR_BLOCK_2(p5);
1902 + PUT_BLOCK_2(p1);
1903 + } while (--lines);
1904 +}
1905 +#endif //XOR_SW_FILL_IN
1906 +
1907 --- /dev/null
1908 +++ b/arch/arm/mach-sl2312/irq.c
1909 @@ -0,0 +1,202 @@
1910 +/*
1911 + * linux/arch/arm/mach-epxa10db/irq.c
1912 + *
1913 + * Copyright (C) 2001 Altera Corporation
1914 + *
1915 + * This program is free software; you can redistribute it and/or modify
1916 + * it under the terms of the GNU General Public License as published by
1917 + * the Free Software Foundation; either version 2 of the License, or
1918 + * (at your option) any later version.
1919 + *
1920 + * This program is distributed in the hope that it will be useful,
1921 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1922 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1923 + * GNU General Public License for more details.
1924 + *
1925 + * You should have received a copy of the GNU General Public License
1926 + * along with this program; if not, write to the Free Software
1927 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1928 + */
1929 +#include <linux/init.h>
1930 +#include <linux/ioport.h>
1931 +#include <linux/stddef.h>
1932 +#include <linux/list.h>
1933 +#include <linux/sched.h>
1934 +#include <asm/hardware.h>
1935 +#include <asm/irq.h>
1936 +#include <asm/io.h>
1937 +#include <asm/mach/irq.h>
1938 +#include <asm/arch/platform.h>
1939 +#include <asm/arch/int_ctrl.h>
1940 +
1941 +#ifdef CONFIG_PCI
1942 +#include <asm/arch/pci.h>
1943 +#endif
1944 +
1945 +int fixup_irq(unsigned int irq)
1946 +{
1947 +#ifdef CONFIG_PCI
1948 + if (irq == IRQ_PCI) {
1949 + return sl2312_pci_get_int_src();
1950 + }
1951 +#endif
1952 + return irq;
1953 +}
1954 +
1955 +static void sl2312_ack_irq(unsigned int irq)
1956 +{
1957 + __raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1958 +}
1959 +
1960 +static void sl2312_mask_irq(unsigned int irq)
1961 +{
1962 + unsigned int mask;
1963 +
1964 +#ifdef CONFIG_PCI
1965 + if (irq >= PCI_IRQ_OFFSET)
1966 + {
1967 + mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1968 + mask &= ~IRQ_PCI_MASK ;
1969 + __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1970 + sl2312_pci_mask_irq(irq - PCI_IRQ_OFFSET);
1971 + }
1972 + else
1973 +#endif
1974 + if(irq >= FIQ_OFFSET)
1975 + {
1976 + mask = __raw_readl(FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1977 + mask &= ~(1 << (irq - FIQ_OFFSET));
1978 + __raw_writel(mask, FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1979 + }
1980 + else
1981 + {
1982 + mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1983 + mask &= ~(1 << irq);
1984 + __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1985 + }
1986 +
1987 +}
1988 +
1989 +static void sl2312_unmask_irq(unsigned int irq)
1990 +{
1991 + unsigned int mask;
1992 +
1993 +#ifdef CONFIG_PCI
1994 + if (irq >= PCI_IRQ_OFFSET)
1995 + {
1996 + mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1997 + mask |= IRQ_PCI_MASK ;
1998 + __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1999 + sl2312_pci_unmask_irq(irq - PCI_IRQ_OFFSET);
2000 + }
2001 + else
2002 +#endif
2003 + if(irq >= FIQ_OFFSET)
2004 + {
2005 + mask = __raw_readl(FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2006 + mask |= (1 << (irq - FIQ_OFFSET));
2007 + __raw_writel(mask, FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2008 + }
2009 + else
2010 + {
2011 + mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2012 + mask |= (1 << irq);
2013 + __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2014 + }
2015 +}
2016 +
2017 +static struct irq_chip sl2312_level_irq = {
2018 + .ack = sl2312_mask_irq,
2019 + .mask = sl2312_mask_irq,
2020 + .unmask = sl2312_unmask_irq,
2021 +// .set_type = ixp4xx_set_irq_type,
2022 +};
2023 +
2024 +static struct irq_chip sl2312_edge_irq = {
2025 + .ack = sl2312_ack_irq,
2026 + .mask = sl2312_mask_irq,
2027 + .unmask = sl2312_unmask_irq,
2028 +// .set_type = ixp4xx_set_irq_type,
2029 +};
2030 +
2031 +static struct resource irq_resource = {
2032 + .name = "irq_handler",
2033 + .start = IO_ADDRESS(SL2312_INTERRUPT_BASE),
2034 + .end = IO_ADDRESS(FIQ_STATUS(SL2312_INTERRUPT_BASE))+4,
2035 +};
2036 +
2037 +void __init sl2312_init_irq(void)
2038 +{
2039 + unsigned int i, mode, level;
2040 +
2041 + request_resource(&iomem_resource, &irq_resource);
2042 +
2043 + for (i = 0; i < NR_IRQS; i++)
2044 + {
2045 + if((i>=IRQ_TIMER1 && i<=IRQ_TIMER3)||(i>=IRQ_SERIRQ0 && i<=IRQ_SERIRQ_MAX))
2046 + {
2047 + set_irq_chip(i, &sl2312_edge_irq);
2048 + set_irq_handler(i, handle_edge_irq);
2049 + }
2050 + else
2051 + {
2052 + set_irq_chip(i, &sl2312_level_irq);
2053 + set_irq_handler(i,handle_level_irq);
2054 + }
2055 + set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
2056 + }
2057 +
2058 + /* Disable all interrupt */
2059 + __raw_writel(0,IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2060 + __raw_writel(0,FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2061 +
2062 + /* Set interrupt mode */
2063 + /* emac & ipsec type is level trigger and high active */
2064 + mode = __raw_readl(IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2065 + level = __raw_readl(IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2066 +
2067 + mode &= ~IRQ_GMAC0_MASK;
2068 + level &= ~IRQ_GMAC0_MASK;
2069 +
2070 + mode &= ~IRQ_GMAC1_MASK;
2071 + level &= ~IRQ_GMAC1_MASK;
2072 +
2073 + mode &= ~IRQ_IPSEC_MASK;
2074 + level &= ~IRQ_IPSEC_MASK;
2075 +
2076 + // for IDE0,1, high active and level trigger
2077 + mode &= ~IRQ_IDE0_MASK;
2078 + level &= ~IRQ_IDE0_MASK;
2079 + mode &= ~IRQ_IDE1_MASK;
2080 + level &= ~IRQ_IDE1_MASK;
2081 +
2082 +
2083 + // for PCI, high active and level trigger
2084 + mode &= ~IRQ_PCI_MASK;
2085 + level &= ~IRQ_PCI_MASK;
2086 +
2087 + // for USB, high active and level trigger
2088 + mode &= ~IRQ_USB0_MASK;
2089 + level &= ~IRQ_USB0_MASK;
2090 +
2091 + mode &= ~IRQ_USB1_MASK;
2092 + level &= ~IRQ_USB1_MASK;
2093 +
2094 + // for LPC, high active and edge trigger
2095 + mode |= 0xffff0000;
2096 + level &= 0x0000ffff;
2097 +
2098 + // for GPIO, high active and level trigger
2099 + mode &= ~(IRQ_GPIO_MASK);
2100 + level &= ~(IRQ_GPIO_MASK);
2101 +
2102 + mode &= ~(IRQ_GPIO1_MASK);
2103 + level &= ~(IRQ_GPIO1_MASK);
2104 +
2105 + mode &= ~(IRQ_GPIO2_MASK);
2106 + level &= ~(IRQ_GPIO2_MASK);
2107 +
2108 + __raw_writel(mode,IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2109 + __raw_writel(level,IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2110 +
2111 +}
2112 --- /dev/null
2113 +++ b/arch/arm/mach-sl2312/lpc.c
2114 @@ -0,0 +1,125 @@
2115 +/*
2116 + *
2117 + * BRIEF MODULE DESCRIPTION
2118 + * ITE Semi IT8712 Super I/O functions.
2119 + *
2120 + * Copyright 2001 MontaVista Software Inc.
2121 + * Author: MontaVista Software, Inc.
2122 + * ppopov@mvista.com or source@mvista.com
2123 + *
2124 + * This program is free software; you can redistribute it and/or modify it
2125 + * under the terms of the GNU General Public License as published by the
2126 + * Free Software Foundation; either version 2 of the License, or (at your
2127 + * option) any later version.
2128 + *
2129 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2130 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2131 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2132 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2133 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2134 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2135 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2136 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2137 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2138 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2139 + *
2140 + * You should have received a copy of the GNU General Public License along
2141 + * with this program; if not, write to the Free Software Foundation, Inc.,
2142 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2143 + */
2144 +#include <linux/kernel.h>
2145 +#include <linux/delay.h>
2146 +#include <asm/io.h>
2147 +#include <asm/types.h>
2148 +#include <asm/arch/it8712.h>
2149 +#include <linux/init.h>
2150 +#include <asm/arch/hardware.h>
2151 +
2152 +#ifndef TRUE
2153 +#define TRUE 1
2154 +#endif
2155 +
2156 +#ifndef FALSE
2157 +#define FALSE 0
2158 +#endif
2159 +
2160 +
2161 +// MB PnP configuration register
2162 +#define LPC_KEY_ADDR (IO_ADDRESS(SL2312_LPC_IO_BASE) + 0x2e)
2163 +#define LPC_DATA_ADDR (IO_ADDRESS(SL2312_LPC_IO_BASE) + 0x2f)
2164 +
2165 +#define LPC_BUS_CTRL *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 0)
2166 +#define LPC_BUS_STATUS *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 2)
2167 +#define LPC_SERIAL_IRQ_CTRL *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 4)
2168 +
2169 +int it8712_exist;
2170 +
2171 +static void LPCEnterMBPnP(void)
2172 +{
2173 + int i;
2174 + unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
2175 +
2176 + for (i = 0; i<4; i++)
2177 + outb(key[i], LPC_KEY_ADDR);
2178 +
2179 +}
2180 +
2181 +static void LPCExitMBPnP(void)
2182 +{
2183 + outb(0x02, LPC_KEY_ADDR);
2184 + outb(0x02, LPC_DATA_ADDR);
2185 +}
2186 +
2187 +void LPCSetConfig(char LdnNumber, char Index, char data)
2188 +{
2189 + LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
2190 + outb(0x07, LPC_KEY_ADDR);
2191 + outb(LdnNumber, LPC_DATA_ADDR);
2192 + outb(Index, LPC_KEY_ADDR);
2193 + outb(data, LPC_DATA_ADDR);
2194 + LPCExitMBPnP();
2195 +}
2196 +
2197 +char LPCGetConfig(char LdnNumber, char Index)
2198 +{
2199 + char rtn;
2200 +
2201 + LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
2202 + outb(0x07, LPC_KEY_ADDR);
2203 + outb(LdnNumber, LPC_DATA_ADDR);
2204 + outb(Index, LPC_KEY_ADDR);
2205 + rtn = inb(LPC_DATA_ADDR);
2206 + LPCExitMBPnP();
2207 + return rtn;
2208 +}
2209 +
2210 +static int SearchIT8712(void)
2211 +{
2212 + unsigned char Id1, Id2;
2213 + unsigned short Id;
2214 +
2215 + LPCEnterMBPnP();
2216 + outb(0x20, LPC_KEY_ADDR); /* chip id byte 1 */
2217 + Id1 = inb(LPC_DATA_ADDR);
2218 + outb(0x21, LPC_KEY_ADDR); /* chip id byte 2 */
2219 + Id2 = inb(LPC_DATA_ADDR);
2220 + Id = (Id1 << 8) | Id2;
2221 + LPCExitMBPnP();
2222 + if (Id == 0x8712)
2223 + return TRUE;
2224 + else
2225 + return FALSE;
2226 +}
2227 +
2228 +int InitLPCInterface(void)
2229 +{
2230 + LPC_BUS_CTRL = 0xc0;
2231 + LPC_SERIAL_IRQ_CTRL = 0xc0;
2232 + mdelay(1); // wait for 1 serial IRQ cycle
2233 + LPC_SERIAL_IRQ_CTRL = 0x80;
2234 + it8712_exist = SearchIT8712();
2235 + printk("IT8712 %s exist\n", it8712_exist?"":"doesn't");
2236 + return 0;
2237 +}
2238 +
2239 +//__initcall(InitLPCInterface);
2240 --- /dev/null
2241 +++ b/arch/arm/mach-sl2312/mm.c
2242 @@ -0,0 +1,80 @@
2243 +/*
2244 + * linux/arch/arm/mach-epxa10db/mm.c
2245 + *
2246 + * MM routines for Altera'a Epxa10db board
2247 + *
2248 + * Copyright (C) 2001 Altera Corporation
2249 + *
2250 + * This program is free software; you can redistribute it and/or modify
2251 + * it under the terms of the GNU General Public License as published by
2252 + * the Free Software Foundation; either version 2 of the License, or
2253 + * (at your option) any later version.
2254 + *
2255 + * This program is distributed in the hope that it will be useful,
2256 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2257 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2258 + * GNU General Public License for more details.
2259 + *
2260 + * You should have received a copy of the GNU General Public License
2261 + * along with this program; if not, write to the Free Software
2262 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2263 + */
2264 +#include <linux/sched.h>
2265 +#include <linux/mm.h>
2266 +#include <linux/init.h>
2267 +
2268 +#include <asm/hardware.h>
2269 +#include <asm/io.h>
2270 +#include <asm/pgtable.h>
2271 +#include <asm/page.h>
2272 +#include <asm/sizes.h>
2273 +
2274 +#include <asm/mach/map.h>
2275 +
2276 +/* Page table mapping for I/O region */
2277 +static struct map_desc sl2312_io_desc[] __initdata = {
2278 +#ifdef CONFIG_GEMINI_IPI
2279 +{__phys_to_virt(CPU_1_MEM_BASE), __phys_to_pfn(CPU_1_MEM_BASE), SZ_64M, MT_MEMORY},
2280 +#endif
2281 +{IO_ADDRESS(SL2312_SRAM_BASE), __phys_to_pfn(SL2312_SRAM_BASE), SZ_512K, MT_DEVICE},
2282 +{IO_ADDRESS(SL2312_DRAM_CTRL_BASE), __phys_to_pfn(SL2312_DRAM_CTRL_BASE), SZ_512K, MT_DEVICE},
2283 +{IO_ADDRESS(SL2312_GLOBAL_BASE), __phys_to_pfn(SL2312_GLOBAL_BASE), SZ_512K, MT_DEVICE},
2284 +{IO_ADDRESS(SL2312_WAQTCHDOG_BASE), __phys_to_pfn(SL2312_WAQTCHDOG_BASE), SZ_512K, MT_DEVICE},
2285 +{IO_ADDRESS(SL2312_UART_BASE), __phys_to_pfn(SL2312_UART_BASE), SZ_512K, MT_DEVICE},
2286 +{IO_ADDRESS(SL2312_TIMER_BASE), __phys_to_pfn(SL2312_TIMER_BASE), SZ_512K, MT_DEVICE},
2287 +{IO_ADDRESS(SL2312_LCD_BASE), __phys_to_pfn(SL2312_LCD_BASE), SZ_512K, MT_DEVICE},
2288 +{IO_ADDRESS(SL2312_RTC_BASE), __phys_to_pfn(SL2312_RTC_BASE), SZ_512K, MT_DEVICE},
2289 +{IO_ADDRESS(SL2312_SATA_BASE), __phys_to_pfn(SL2312_SATA_BASE), SZ_512K, MT_DEVICE},
2290 +{IO_ADDRESS(SL2312_LPC_HOST_BASE), __phys_to_pfn(SL2312_LPC_HOST_BASE), SZ_512K, MT_DEVICE},
2291 +{IO_ADDRESS(SL2312_LPC_IO_BASE), __phys_to_pfn(SL2312_LPC_IO_BASE), SZ_512K, MT_DEVICE},
2292 +{IO_ADDRESS(SL2312_INTERRUPT_BASE), __phys_to_pfn(SL2312_INTERRUPT_BASE), SZ_512K, MT_DEVICE},
2293 +{IO_ADDRESS(SL2312_INTERRUPT1_BASE), __phys_to_pfn(SL2312_INTERRUPT1_BASE), SZ_512K, MT_DEVICE},
2294 +{IO_ADDRESS(SL2312_SSP_CTRL_BASE), __phys_to_pfn(SL2312_SSP_CTRL_BASE), SZ_512K, MT_DEVICE},
2295 +{IO_ADDRESS(SL2312_POWER_CTRL_BASE), __phys_to_pfn(SL2312_POWER_CTRL_BASE), SZ_512K, MT_DEVICE},
2296 +{IO_ADDRESS(SL2312_CIR_BASE), __phys_to_pfn(SL2312_CIR_BASE), SZ_512K, MT_DEVICE},
2297 +{IO_ADDRESS(SL2312_GPIO_BASE), __phys_to_pfn(SL2312_GPIO_BASE), SZ_512K, MT_DEVICE},
2298 +{IO_ADDRESS(SL2312_GPIO_BASE1), __phys_to_pfn(SL2312_GPIO_BASE1), SZ_512K, MT_DEVICE},
2299 +{IO_ADDRESS(SL2312_GPIO_BASE2), __phys_to_pfn(SL2312_GPIO_BASE2), SZ_512K, MT_DEVICE},
2300 +{IO_ADDRESS(SL2312_PCI_IO_BASE), __phys_to_pfn(SL2312_PCI_IO_BASE), SZ_512K, MT_DEVICE},
2301 +{IO_ADDRESS(SL2312_PCI_MEM_BASE), __phys_to_pfn(SL2312_PCI_MEM_BASE), SZ_512K, MT_DEVICE},
2302 +#ifdef CONFIG_NET_SL351X
2303 +{IO_ADDRESS(SL2312_TOE_BASE), __phys_to_pfn(SL2312_TOE_BASE) , SZ_512K, MT_DEVICE},
2304 +#endif
2305 +{IO_ADDRESS(SL2312_GMAC0_BASE), __phys_to_pfn(SL2312_GMAC0_BASE), SZ_512K, MT_DEVICE},
2306 +{IO_ADDRESS(SL2312_GMAC1_BASE), __phys_to_pfn(SL2312_GMAC1_BASE), SZ_512K, MT_DEVICE},
2307 +{IO_ADDRESS(SL2312_SECURITY_BASE), __phys_to_pfn(SL2312_SECURITY_BASE), SZ_512K, MT_DEVICE},
2308 +{IO_ADDRESS(SL2312_IDE0_BASE), __phys_to_pfn(SL2312_IDE0_BASE), SZ_512K, MT_DEVICE},
2309 +{IO_ADDRESS(SL2312_IDE1_BASE), __phys_to_pfn(SL2312_IDE1_BASE), SZ_512K, MT_DEVICE},
2310 +{IO_ADDRESS(SL2312_RAID_BASE), __phys_to_pfn(SL2312_RAID_BASE), SZ_512K, MT_DEVICE},
2311 +{IO_ADDRESS(SL2312_FLASH_CTRL_BASE), __phys_to_pfn(SL2312_FLASH_CTRL_BASE), SZ_512K, MT_DEVICE},
2312 +{IO_ADDRESS(SL2312_DRAM_CTRL_BASE), __phys_to_pfn(SL2312_DRAM_CTRL_BASE), SZ_512K, MT_DEVICE},
2313 +{IO_ADDRESS(SL2312_GENERAL_DMA_BASE), __phys_to_pfn(SL2312_GENERAL_DMA_BASE), SZ_512K, MT_DEVICE},
2314 +{IO_ADDRESS(SL2312_USB0_BASE), __phys_to_pfn(SL2312_USB_BASE), SZ_512K, MT_DEVICE},
2315 +{IO_ADDRESS(SL2312_USB1_BASE), __phys_to_pfn(SL2312_USB1_BASE), SZ_512K, MT_DEVICE},
2316 +{FLASH_VADDR(SL2312_FLASH_BASE), __phys_to_pfn(SL2312_FLASH_BASE), SZ_16M, MT_DEVICE},
2317 +};
2318 +
2319 +void __init sl2312_map_io(void)
2320 +{
2321 + iotable_init(sl2312_io_desc, ARRAY_SIZE(sl2312_io_desc));
2322 +}
2323 --- /dev/null
2324 +++ b/arch/arm/mach-sl2312/pci.c
2325 @@ -0,0 +1,359 @@
2326 +/*
2327 + * linux/arch/arm/mach-sl2312/pci_sl2312.c
2328 + *
2329 + * PCI functions for sl2312 host PCI bridge
2330 + *
2331 + * Copyright (C) 2003 StorLink Corp.
2332 + *
2333 + * This program is free software; you can redistribute it and/or modify
2334 + * it under the terms of the GNU General Public License as published by
2335 + * the Free Software Foundation; either version 2 of the License, or
2336 + * (at your option) any later version.
2337 + *
2338 + * This program is distributed in the hope that it will be useful,
2339 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2340 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2341 + * GNU General Public License for more details.
2342 + *
2343 + * You should have received a copy of the GNU General Public License
2344 + * along with this program; if not, write to the Free Software
2345 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2346 + */
2347 +#include <linux/sched.h>
2348 +#include <linux/kernel.h>
2349 +#include <linux/pci.h>
2350 +#include <linux/ptrace.h>
2351 +#include <linux/slab.h>
2352 +#include <linux/ioport.h>
2353 +#include <linux/interrupt.h>
2354 +#include <linux/spinlock.h>
2355 +#include <linux/init.h>
2356 +
2357 +#include <asm/sizes.h>
2358 +#include <asm/hardware.h>
2359 +#include <asm/irq.h>
2360 +#include <asm/system.h>
2361 +#include <asm/mach/pci.h>
2362 +#include <asm/mach/irq.h>
2363 +#include <asm/mach-types.h>
2364 +
2365 +#include <asm/arch/pci.h>
2366 +
2367 +//#define DEBUG
2368 +
2369 +// sl2312 PCI bridge access routines
2370 +
2371 +#define PCI_IOSIZE_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE)))
2372 +#define PCI_PROT_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x04))
2373 +#define PCI_CTRL_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x08))
2374 +#define PCI_SOFTRST_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x10))
2375 +#define PCI_CONFIG_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x28))
2376 +#define PCI_DATA_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x2C))
2377 +
2378 +static spinlock_t sl2312_pci_lock = SPIN_LOCK_UNLOCKED;
2379 +// for initialize PCI devices
2380 +struct resource pci_ioport_resource = {
2381 + .name = "PCI I/O Space",
2382 + .start = IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x100,
2383 + .end = IO_ADDRESS(SL2312_PCI_IO_BASE) + SZ_512K - 1,
2384 + .flags = IORESOURCE_IO,
2385 +};
2386 +struct resource pci_iomem_resource = {
2387 + .name = "PCI Mem Space",
2388 + .start = SL2312_PCI_MEM_BASE,
2389 + .end = SL2312_PCI_MEM_BASE + SZ_128M - 1,
2390 + .flags = IORESOURCE_MEM,
2391 +};
2392 +
2393 +static int sl2312_read_config(struct pci_bus *bus, unsigned int devfn, int where,int size, u32 *val)
2394 +{
2395 + unsigned long addr,data;
2396 + unsigned long flags;
2397 +
2398 + spin_lock_irqsave(&sl2312_pci_lock, flags);
2399 + addr = 0x80000000 | (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | (where & ~3);
2400 + PCI_CONFIG_REG = addr;
2401 + data = PCI_DATA_REG;
2402 +
2403 + switch (size) {
2404 + case 1:
2405 + *val = (u8) (data >> ((where & 0x03) * 8));
2406 + break;
2407 + case 2:
2408 + *val = (u16) (data >> ((where & 0x02) * 8));
2409 + break;
2410 + case 4:
2411 + *val = data;
2412 + if ((where >= 0x10) && (where <= 0x24)) {
2413 + if ((*val & 0xfff00000) == SL2312_PCI_IO_BASE) {
2414 + *val &= 0x000fffff;
2415 + *val |= IO_ADDRESS(SL2312_PCI_IO_BASE);
2416 + }
2417 + }
2418 + break;
2419 + }
2420 + spin_unlock_irqrestore(&sl2312_pci_lock, flags);
2421 +// printk("READ==>slot=%d fn=%d where=%d value=%x\n",PCI_SLOT(devfn),PCI_FUNC(devfn),where,*val);
2422 + return PCIBIOS_SUCCESSFUL;
2423 +}
2424 +
2425 +static int sl2312_write_config(struct pci_bus *bus, unsigned int devfn, int where,int size, u32 val)
2426 +{
2427 + unsigned long addr,data;
2428 + unsigned long flags;
2429 +
2430 + spin_lock_irqsave(&sl2312_pci_lock, flags);
2431 + addr = 0x80000000 | (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | (where & ~3);
2432 + PCI_CONFIG_REG = addr;
2433 + data = PCI_DATA_REG;
2434 +
2435 + switch (size) {
2436 + case 1:
2437 + data &= ~(0xff << ((where & 0x03) * 8));
2438 + data |= (val << ((where & 0x03) * 8));
2439 + PCI_DATA_REG = data;
2440 + break;
2441 + case 2:
2442 + data &= ~(0xffff << ((where & 0x02) * 8));
2443 + data |= (val << ((where & 0x02) * 8));
2444 + PCI_DATA_REG = data;
2445 + break;
2446 + case 4:
2447 + if ((where >= 0x10) && (where <= 0x24)) {
2448 + if ((val & 0xfff00000) == IO_ADDRESS(SL2312_PCI_IO_BASE)) {
2449 + val &= 0x000fffff;
2450 + val |= SL2312_PCI_IO_BASE;
2451 + }
2452 + }
2453 + PCI_DATA_REG = val;
2454 + break;
2455 + }
2456 + spin_unlock_irqrestore(&sl2312_pci_lock, flags);
2457 +
2458 +// printk("WRITE==> slot=%d fn=%d where=%d value=%x \n",PCI_SLOT(devfn),PCI_FUNC(devfn),where,val);
2459 + return PCIBIOS_SUCCESSFUL;
2460 +}
2461 +
2462 +static struct pci_ops sl2312_pci_ops = {
2463 + .read = sl2312_read_config,
2464 + .write = sl2312_write_config,
2465 +};
2466 +
2467 +
2468 +int __init sl2312_pci_setup_resources(struct resource **resource)
2469 +{
2470 + PCI_IOSIZE_REG = 0; // 1M IO size
2471 + PCI_CTRL_REG = 0x06;
2472 +
2473 + resource[0] = &pci_ioport_resource;
2474 + resource[1] = &pci_iomem_resource;
2475 + resource[2] = NULL;
2476 +
2477 + return 1;
2478 +}
2479 +
2480 +//static int sl2312_pci_fault(unsigned long addr, struct pt_regs *regs)
2481 +//{
2482 +// return 1;
2483 +//}
2484 +
2485 +
2486 +/**********************************************************************
2487 + * MASK(disable) PCI interrupt
2488 + * 0: PCI INTA, 1: PCI INTB, ... // for Linux interrupt routing
2489 + * 16: PERR // for PCI module internal use
2490 + * 17: SERR,.. respect to PCI CTRL2 REG
2491 + **********************************************************************/
2492 +void sl2312_pci_mask_irq(unsigned int irq)
2493 +{
2494 + struct pci_bus bus;
2495 + unsigned int tmp;
2496 +
2497 + bus.number = 0;
2498 + sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp);
2499 + if (irq < 16) { // for linux int routing
2500 + tmp &= ~(1 << (irq + 16 + 6));
2501 + }
2502 + else {
2503 + tmp &= ~(1 << irq);
2504 + }
2505 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2506 +}
2507 +
2508 +/* UNMASK(enable) PCI interrupt */
2509 +void sl2312_pci_unmask_irq(unsigned int irq)
2510 +{
2511 + struct pci_bus bus;
2512 + unsigned int tmp;
2513 +
2514 + bus.number = 0;
2515 + sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp);
2516 + if (irq < 16) { // for linux int routing
2517 + tmp |= (1 << (irq + 16 + 6));
2518 + }
2519 + else {
2520 + tmp |= (1 << irq);
2521 + }
2522 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2523 +}
2524 +
2525 +/* Get PCI interrupt source */
2526 +int sl2312_pci_get_int_src(void)
2527 +{
2528 + struct pci_bus bus;
2529 + unsigned int tmp=0;
2530 +
2531 + bus.number = 0;
2532 + sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp);
2533 + if (tmp & (1 << 28)) { // PCI INTA
2534 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2535 + return IRQ_PCI_INTA;
2536 + }
2537 + if (tmp & (1 << 29)) { // PCI INTB
2538 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2539 + return IRQ_PCI_INTB;
2540 + }
2541 + if (tmp & (1 << 30)) { // PCI INTC
2542 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2543 + return IRQ_PCI_INTC;
2544 + }
2545 + if (tmp & (1 << 31)) { // PCI INTD
2546 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2547 + return IRQ_PCI_INTD;
2548 + }
2549 + // otherwise, it should be a PCI error
2550 + return IRQ_PCI;
2551 +}
2552 +
2553 +static irqreturn_t sl2312_pci_irq(int irq, void *devid)
2554 +{
2555 + struct irq_desc *desc;
2556 + struct irqaction *action;
2557 + int retval = 0;
2558 +
2559 + return 1;
2560 +
2561 + irq = sl2312_pci_get_int_src();
2562 + desc = &irq_desc[irq];
2563 + action = desc->action;
2564 + do {
2565 + retval |= action->handler(irq, devid);
2566 + action = action->next;
2567 + } while (action);
2568 +
2569 + return 1;
2570 +}
2571 +
2572 +//extern int (*external_fault)(unsigned long addr, struct pt_regs *regs);
2573 +
2574 +void __init sl2312_pci_preinit(void)
2575 +{
2576 + struct pci_bus bus;
2577 + unsigned long flags;
2578 + unsigned int temp;
2579 + int ret;
2580 +
2581 + /*
2582 + * Hook in our fault handler for PCI errors
2583 + */
2584 +// external_fault = sl2312_pci_fault;
2585 +
2586 + spin_lock_irqsave(&sl2312_pci_lock, flags);
2587 +
2588 + /*
2589 + * Grab the PCI interrupt.
2590 + */
2591 + ret = request_irq(IRQ_PCI, sl2312_pci_irq, 0, "sl2312 pci int", NULL);
2592 + if (ret)
2593 + printk(KERN_ERR "PCI: unable to grab PCI error "
2594 + "interrupt: %d\n", ret);
2595 +
2596 + spin_unlock_irqrestore(&sl2312_pci_lock, flags);
2597 +
2598 + // setup pci bridge
2599 + bus.number = 0; /* device 0, function 0 */
2600 + temp = (SL2312_PCI_DMA_MEM1_BASE & 0xfff00000) | (SL2312_PCI_DMA_MEM1_SIZE << 16);
2601 + sl2312_write_config(&bus, 0, SL2312_PCI_MEM1_BASE_SIZE, 4, temp);
2602 +}
2603 +
2604 +/*
2605 + * No swizzle on SL2312
2606 + */
2607 +static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp)
2608 +{
2609 + return PCI_SLOT(dev->devfn);
2610 +}
2611 +
2612 +/*
2613 + * map the specified device/slot/pin to an IRQ. This works out such
2614 + * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
2615 + */
2616 +static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
2617 +{
2618 + int intnr = ((slot + (pin - 1)) & 3) + 4; /* the IRQ number of PCI bridge */
2619 +
2620 + // printk("%s : slot = %d pin = %d \n",__func__,slot,pin);
2621 + switch (slot)
2622 + {
2623 + case 12:
2624 + if (pin==1)
2625 + {
2626 + intnr = 3;
2627 + }
2628 + else
2629 + {
2630 + intnr = 0;
2631 + }
2632 + break;
2633 + case 11:
2634 + intnr = (2 + (pin - 1)) & 3;
2635 + break;
2636 + case 10:
2637 + intnr = (1 + (pin - 1)) & 3;
2638 + break;
2639 + case 9:
2640 + intnr = (pin - 1) & 3;
2641 + break;
2642 + }
2643 +// if (slot == 10)
2644 +// intnr = (1 + (pin - 1)) & 3;
2645 +// else if (slot == 9)
2646 +// intnr = (pin - 1) & 3;
2647 + return (IRQ_PCI_INTA + intnr);
2648 +}
2649 +
2650 +struct pci_bus * __init sl2312_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
2651 +{
2652 + return (pci_scan_bus(0, &sl2312_pci_ops, sysdata));
2653 +
2654 +}
2655 +
2656 +int __init sl2312_pci_setup(int nr, struct pci_sys_data *sys)
2657 +{
2658 + int ret = 0;
2659 +
2660 + if (nr == 0) {
2661 + ret = sl2312_pci_setup_resources(sys->resource);
2662 + }
2663 +
2664 + return ret;
2665 +}
2666 +
2667 +
2668 +struct hw_pci sl2312_pci __initdata = {
2669 + .setup = sl2312_pci_setup,
2670 + .preinit = sl2312_pci_preinit,
2671 + .nr_controllers = 1,
2672 + .swizzle = sl2312_pci_swizzle,
2673 + .map_irq = sl2312_pci_map_irq,
2674 + .scan = sl2312_pci_scan_bus,
2675 +};
2676 +
2677 +static int __init sl2312_pci_init(void)
2678 +{
2679 + if (machine_is_sl2312())
2680 + pci_common_init(&sl2312_pci);
2681 + return 0;
2682 +}
2683 +
2684 +subsys_initcall(sl2312_pci_init);
2685 --- /dev/null
2686 +++ b/arch/arm/mach-sl2312/sl2312-otg-1.c
2687 @@ -0,0 +1,64 @@
2688 +/*
2689 + * linux/arch/arm/mach-pxa/sl2312.c
2690 + *
2691 + * Author: Nicolas Pitre
2692 + * Created: Nov 05, 2002
2693 + * Copyright: MontaVista Software Inc.
2694 + *
2695 + * Code specific to sl2312 aka Bulverde.
2696 + *
2697 + * This program is free software; you can redistribute it and/or modify
2698 + * it under the terms of the GNU General Public License version 2 as
2699 + * published by the Free Software Foundation.
2700 + */
2701 +#include <linux/module.h>
2702 +#include <linux/kernel.h>
2703 +#include <linux/init.h>
2704 +#include <linux/pm.h>
2705 +#include <linux/device.h>
2706 +#include "asm/arch/sl2312.h"
2707 +#include "asm/arch/irqs.h"
2708 +#include <asm/hardware.h>
2709 +#include <asm/irq.h>
2710 +#include <linux/platform_device.h>
2711 +
2712 +/*
2713 + * device registration specific to sl2312.
2714 + */
2715 +
2716 +static u64 sl2312_dmamask_1 = 0xffffffffUL;
2717 +
2718 +static struct resource sl2312_otg_resources_1[] = {
2719 + [0] = {
2720 + .start = 0x69000000,
2721 + .end = 0x69000fff,
2722 + .flags = IORESOURCE_MEM,
2723 + },
2724 + [1] = {
2725 + .start = IRQ_USB1,
2726 + .end = IRQ_USB1,
2727 + .flags = IORESOURCE_IRQ,
2728 + },
2729 +};
2730 +
2731 +static struct platform_device ehci_1_device = {
2732 + .name = "ehci-hcd-FOTG2XX",
2733 + .id = -1,
2734 + .dev = {
2735 + .dma_mask = &sl2312_dmamask_1,
2736 + .coherent_dma_mask = 0xffffffff,
2737 + },
2738 + .num_resources = ARRAY_SIZE(sl2312_otg_resources_1),
2739 + .resource = sl2312_otg_resources_1,
2740 +};
2741 +
2742 +static struct platform_device *devices[] __initdata = {
2743 + &ehci_1_device,
2744 +};
2745 +
2746 +static int __init sl2312_1_init(void)
2747 +{
2748 + return platform_add_devices(devices, ARRAY_SIZE(devices));
2749 +}
2750 +
2751 +subsys_initcall(sl2312_1_init);
2752 --- /dev/null
2753 +++ b/arch/arm/mach-sl2312/sl2312-otg.c
2754 @@ -0,0 +1,87 @@
2755 +/*
2756 + * linux/arch/arm/mach-pxa/sl2312.c
2757 + *
2758 + * Author: Nicolas Pitre
2759 + * Created: Nov 05, 2002
2760 + * Copyright: MontaVista Software Inc.
2761 + *
2762 + * Code specific to sl2312 aka Bulverde.
2763 + *
2764 + * This program is free software; you can redistribute it and/or modify
2765 + * it under the terms of the GNU General Public License version 2 as
2766 + * published by the Free Software Foundation.
2767 + */
2768 +#include <linux/module.h>
2769 +#include <linux/kernel.h>
2770 +#include <linux/init.h>
2771 +#include <linux/pm.h>
2772 +#include <linux/device.h>
2773 +#include "asm/arch/sl2312.h"
2774 +#include "asm/arch/irqs.h"
2775 +#include <asm/hardware.h>
2776 +#include <asm/irq.h>
2777 +#include <linux/platform_device.h>
2778 +
2779 +/*
2780 + * device registration specific to sl2312.
2781 + */
2782 +
2783 +static u64 sl2312_dmamask = 0xffffffffUL;
2784 +
2785 +static struct resource sl2312_otg_resources_1[] = {
2786 + [0] = {
2787 + .start = 0x68000000,
2788 + .end = 0x68000fff,
2789 + .flags = IORESOURCE_MEM,
2790 + },
2791 + [1] = {
2792 + .start = IRQ_USB0,
2793 + .end = IRQ_USB0,
2794 + .flags = IORESOURCE_IRQ,
2795 + },
2796 +};
2797 +static struct resource sl2312_otg_resources_2[] = {
2798 + [2] = {
2799 + .start = 0x69000000,
2800 + .end = 0x69000fff,
2801 + .flags = IORESOURCE_MEM,
2802 + },
2803 + [3] = {
2804 + .start = IRQ_USB1,
2805 + .end = IRQ_USB1,
2806 + .flags = IORESOURCE_IRQ,
2807 + },
2808 +};
2809 +
2810 +static struct platform_device ehci_device_1 = {
2811 + .name = "ehci-hcd-FOTG2XX",
2812 + .id = 1,
2813 + .dev = {
2814 + .dma_mask = &sl2312_dmamask,
2815 + .coherent_dma_mask = 0xffffffff,
2816 + },
2817 + .num_resources = ARRAY_SIZE(sl2312_otg_resources_1),
2818 + .resource = sl2312_otg_resources_1,
2819 +};
2820 +
2821 +static struct platform_device ehci_device_2 = {
2822 + .name = "ehci-hcd-FOTG2XX",
2823 + .id = 2,
2824 + .dev = {
2825 + .dma_mask = &sl2312_dmamask,
2826 + .coherent_dma_mask = 0xffffffff,
2827 + },
2828 + .num_resources = ARRAY_SIZE(sl2312_otg_resources_2),
2829 + .resource = sl2312_otg_resources_2,
2830 +};
2831 +
2832 +static struct platform_device *devices[] __initdata = {
2833 + &ehci_device_1, /* &ehci_device_2, */
2834 +};
2835 +
2836 +static int __init sl2312_init(void)
2837 +{
2838 + return platform_add_devices(devices, ARRAY_SIZE(devices));
2839 +}
2840 +
2841 +subsys_initcall(sl2312_init);
2842 --- /dev/null
2843 +++ b/arch/arm/mach-sl2312/sl3516_device.c
2844 @@ -0,0 +1,89 @@
2845 +/*
2846 + * linux/arch/arm/mach-2312/sl3516_device.c
2847 + *
2848 + * Author: Nicolas Pitre
2849 + * Created: Nov 05, 2002
2850 + * Copyright: MontaVista Software Inc.
2851 + *
2852 + * Code specific to sl2312 aka Bulverde.
2853 + *
2854 + * This program is free software; you can redistribute it and/or modify
2855 + * it under the terms of the GNU General Public License version 2 as
2856 + * published by the Free Software Foundation.
2857 + */
2858 +#include <linux/module.h>
2859 +#include <linux/kernel.h>
2860 +#include <linux/init.h>
2861 +#include <linux/pm.h>
2862 +#include <linux/device.h>
2863 +#include <linux/platform_device.h>
2864 +#include "asm/arch/sl2312.h"
2865 +#include "asm/arch/irqs.h"
2866 +#include <asm/hardware.h>
2867 +#include <asm/irq.h>
2868 +
2869 +/*
2870 + * device registration specific to sl2312.
2871 + */
2872 +
2873 +static u64 sl3516_dmamask = 0xffffffffUL;
2874 +
2875 +static struct resource sl3516_sata_resources[] = {
2876 + [0] = {
2877 + .start = 0x63400000,
2878 + .end = 0x63400040,
2879 + .flags = IORESOURCE_MEM,
2880 + },
2881 + [1] = {
2882 + .start = IRQ_IDE1,
2883 + .end = IRQ_IDE1,
2884 + .flags = IORESOURCE_IRQ,
2885 + },
2886 +};
2887 +
2888 +static struct platform_device sata_device = {
2889 + .name = "lepus-sata",
2890 + .id = -1,
2891 + .dev = {
2892 + .dma_mask = &sl3516_dmamask,
2893 + .coherent_dma_mask = 0xffffffff,
2894 + },
2895 + .num_resources = ARRAY_SIZE(sl3516_sata_resources),
2896 + .resource = sl3516_sata_resources,
2897 +};
2898 +
2899 +static struct resource sl3516_sata0_resources[] = {
2900 + [0] = {
2901 + .start = 0x63000000,
2902 + .end = 0x63000040,
2903 + .flags = IORESOURCE_MEM,
2904 + },
2905 + [1] = {
2906 + .start = IRQ_IDE0,
2907 + .end = IRQ_IDE0,
2908 + .flags = IORESOURCE_IRQ,
2909 + },
2910 +};
2911 +
2912 +static struct platform_device sata0_device = {
2913 + .name = "lepus-sata0",
2914 + .id = -1,
2915 + .dev = {
2916 + .dma_mask = &sl3516_dmamask,
2917 + .coherent_dma_mask = 0xffffffff,
2918 + },
2919 + .num_resources = ARRAY_SIZE(sl3516_sata0_resources),
2920 + .resource = sl3516_sata0_resources,
2921 +};
2922 +
2923 +static struct platform_device *sata_devices[] __initdata = {
2924 + &sata_device,
2925 + &sata0_device,
2926 +};
2927 +
2928 +static int __init sl3516_init(void)
2929 +{
2930 + return platform_add_devices(sata_devices, ARRAY_SIZE(sata_devices));
2931 +}
2932 +
2933 +subsys_initcall(sl3516_init);
2934 --- /dev/null
2935 +++ b/arch/arm/mach-sl2312/time.c
2936 @@ -0,0 +1,134 @@
2937 +/*
2938 + * linux/include/asm-arm/arch-epxa10db/time.h
2939 + *
2940 + * Copyright (C) 2001 Altera Corporation
2941 + *
2942 + * This program is free software; you can redistribute it and/or modify
2943 + * it under the terms of the GNU General Public License as published by
2944 + * the Free Software Foundation; either version 2 of the License, or
2945 + * (at your option) any later version.
2946 + *
2947 + * This program is distributed in the hope that it will be useful,
2948 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2949 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2950 + * GNU General Public License for more details.
2951 + *
2952 + * You should have received a copy of the GNU General Public License
2953 + * along with this program; if not, write to the Free Software
2954 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2955 + */
2956 +#include <linux/interrupt.h>
2957 +#include <linux/irq.h>
2958 +#include <asm/io.h>
2959 +#include <asm/system.h>
2960 +#include <asm/leds.h>
2961 +#include <asm/arch/hardware.h>
2962 +#include <asm/mach/time.h>
2963 +#define TIMER_TYPE (volatile unsigned int*)
2964 +#include <asm/arch/timer.h>
2965 +// #define FIQ_PLUS 1
2966 +
2967 +
2968 +/*
2969 + * IRQ handler for the timer
2970 + */
2971 +static irqreturn_t sl2312_timer_interrupt(int irq, void *dev_id)
2972 +{
2973 +// unsigned int led;
2974 + // ...clear the interrupt
2975 +#ifdef FIQ_PLUS
2976 + *((volatile unsigned int *)FIQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK);
2977 +#else
2978 + *((volatile unsigned int *)IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK);
2979 +#endif
2980 +
2981 +#if 0
2982 + if(!(jiffies % HZ))
2983 + {
2984 + led = jiffies / HZ;
2985 +// printk("ticks %x \n", led);
2986 + }
2987 + do_leds();
2988 + do_timer(regs);
2989 + do_profile(regs);
2990 +#endif
2991 + timer_tick();
2992 + return IRQ_HANDLED;
2993 +}
2994 +
2995 +static struct irqaction sl2312_timer_irq = {
2996 + .name = "SL2312 Timer Tick",
2997 + .flags = IRQF_DISABLED | IRQF_TIMER,
2998 + .handler = sl2312_timer_interrupt,
2999 +};
3000 +
3001 +unsigned long sl2312_gettimeoffset (void)
3002 +{
3003 + return 0L;
3004 +}
3005 +
3006 +/*
3007 + * Set up timer interrupt, and return the current time in seconds.
3008 + */
3009 +void __init sl2312_time_init(void)
3010 +{
3011 + // For clock rate adjusting
3012 + unsigned int tick_rate=0;
3013 +
3014 +#ifdef CONFIG_SL3516_ASIC
3015 + unsigned int clock_rate_base = 130000000;
3016 + unsigned int reg_v=0;
3017 +
3018 + //--> Add by jason for clock adjust
3019 + reg_v = readl(IO_ADDRESS((SL2312_GLOBAL_BASE+GLOBAL_STATUS)));
3020 + reg_v >>= 15;
3021 + tick_rate = (clock_rate_base + (reg_v & 0x07)*10000000);
3022 +
3023 + // FPGA use AHB bus tick rate
3024 + printk("Bus: %dMHz",tick_rate/1000000);
3025 +
3026 + tick_rate /= 6; // APB bus run AHB*(1/6)
3027 +
3028 + switch((reg_v>>3)&3){
3029 + case 0: printk("(1/1)\n") ;
3030 + break;
3031 + case 1: printk("(3/2)\n") ;
3032 + break;
3033 + case 2: printk("(24/13)\n") ;
3034 + break;
3035 + case 3: printk("(2/1)\n") ;
3036 + break;
3037 + }
3038 + //<--
3039 +#else
3040 + printk("Bus: %dMHz(1/1)\n",CLOCK_TICK_RATE/1000000); // FPGA use 20MHz
3041 + tick_rate = CLOCK_TICK_RATE;
3042 +#endif
3043 +
3044 +
3045 + /*
3046 + * Make irqs happen for the system timer
3047 + */
3048 + // initialize timer interrupt
3049 + // low active and edge trigger
3050 +#ifdef FIQ_PLUS
3051 + *((volatile unsigned int *)FIQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK);
3052 + *((volatile unsigned int *)FIQ_LEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK);
3053 + setup_irq(IRQ_TIMER1, &sl2312_timer_irq);
3054 + /* Start the timer */
3055 + *TIMER_COUNT(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(tick_rate/HZ);
3056 + *TIMER_LOAD(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(tick_rate/HZ);
3057 + *TIMER_CR(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(TIMER_1_CR_ENABLE_MSK|TIMER_1_CR_INT_MSK);
3058 +#else
3059 + *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK);
3060 + *((volatile unsigned int *)IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK);
3061 + setup_irq(IRQ_TIMER2, &sl2312_timer_irq);
3062 + /* Start the timer */
3063 + *TIMER_COUNT(IO_ADDRESS(SL2312_TIMER2_BASE))=(unsigned int)(tick_rate/HZ);
3064 + *TIMER_LOAD(IO_ADDRESS(SL2312_TIMER2_BASE))=(unsigned int)(tick_rate/HZ);
3065 + *TIMER_CR(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(TIMER_2_CR_ENABLE_MSK|TIMER_2_CR_INT_MSK);
3066 +#endif
3067 +
3068 +}
3069 +
3070 +
3071 --- /dev/null
3072 +++ b/arch/arm/mach-sl2312/xor.c
3073 @@ -0,0 +1,1200 @@
3074 +/*
3075 + * arch/arm/mach-sl2312/xor.c
3076 + *
3077 + * Support functions for the Gemini Soc. This is
3078 + * a HW XOR unit that is specifically designed for use with RAID5
3079 + * applications. This driver provides an interface that is used by
3080 + * the Linux RAID stack.
3081 + *
3082 + * Original Author: Jason Lee<jason@storlink.com.tw>
3083 + *
3084 + * Contributors:Sanders<sanders@storlink.com.tw>
3085 + Jason Lee<jason@storlink.com.tw>
3086 + *
3087 + *
3088 + * Maintainer: Jason Lee<jason@storlink.com.tw>
3089 + *
3090 + * Copyright (C) 2005 Storlink Corporation
3091 + *
3092 + * This program is free software; you can redistribute it and/or modify
3093 + * it under the terms of the GNU General Public License version 2 as
3094 + * published by the Free Software Foundation.
3095 + *
3096 + *
3097 + * History: (06/25/2005, DJ) Initial Creation
3098 + *
3099 + * Versing 1.0.0 Initial version
3100 + */
3101 +
3102 +#include <linux/types.h>
3103 +#include <linux/init.h>
3104 +#include <linux/sched.h>
3105 +#include <linux/spinlock.h>
3106 +#include <linux/slab.h>
3107 +#include <linux/errno.h>
3108 +#include <linux/interrupt.h>
3109 +#include <linux/sched.h>
3110 +#include <linux/wait.h>
3111 +#include <linux/list.h>
3112 +#include <linux/pci.h>
3113 +#include <linux/delay.h>
3114 +#include <linux/dma-mapping.h>
3115 +#include <linux/mm.h>
3116 +#include <asm/irq.h>
3117 +#include <asm/delay.h>
3118 +#include <asm/uaccess.h>
3119 +#include <asm/cacheflush.h>
3120 +#include <asm/hardware.h>
3121 +#include <asm/arch/xor.h>
3122 +#include <asm/pci.h>
3123 +#include <linux/version.h>
3124 +
3125 +/*
3126 + * pick up local definitions
3127 + */
3128 +#define XOR_SW_FILL_IN
3129 +#include "hw_xor.h"
3130 +
3131 +
3132 +//#define XOR_DEBUG
3133 +//#define XOR_TEST 1
3134 +#ifdef XOR_TEST
3135 +#define TEST_ITERATION 1000
3136 +#define SPIN_WAIT 1
3137 +#endif
3138 +#ifdef XOR_DEBUG
3139 +#define DPRINTK(s, args...) printk("Gemini XOR: " s "\n", ## args)
3140 +#define DENTER() DPRINTK("Entered...\n");
3141 +#define DEXIT() DPRINTK("Exited...\n");
3142 +#else
3143 +#define DPRINTK(s, args...)
3144 +#define DENTER()
3145 +#define DEXIT()
3146 +#endif
3147 +
3148 +//#define SPIN_WAIT
3149 +
3150 +/* globals */
3151 +static RAID_T tp;
3152 +static RAID_TXDMA_CTRL_T txdma_ctrl;
3153 +RAID_RXDMA_CTRL_T rxdma_ctrl;
3154 +
3155 +//#ifndef SPIN_WAIT
3156 +static spinlock_t raid_lock;
3157 +//#endif
3158 +
3159 +static unsigned int tx_desc_virtual_base;
3160 +static unsigned int rx_desc_virtual_base;
3161 +RAID_DESCRIPTOR_T *tx_desc_ptr;
3162 +RAID_DESCRIPTOR_T *rx_desc_ptr;
3163 +
3164 +/* static prototypes */
3165 +#define DMA_MALLOC(size,handle) pci_alloc_consistent(NULL,size,handle)
3166 +#define DMA_MFREE(mem,size,handle) pci_free_consistent(NULL,size,mem,handle)
3167 +
3168 +static int gemini_xor_init_desc(void);
3169 +
3170 +static unsigned int raid_read_reg(unsigned int offset)
3171 +{
3172 + unsigned int reg_val;
3173 +
3174 + reg_val = readl(RAID_BASE_ADDR + offset);
3175 + return (reg_val);
3176 +}
3177 +
3178 +static void raid_write_reg(unsigned int offset,unsigned int data,unsigned int bit_mask)
3179 +{
3180 + unsigned int reg_val;
3181 + unsigned int *addr;
3182 +
3183 + reg_val = ( raid_read_reg(offset) & (~bit_mask) ) | (data & bit_mask);
3184 + addr = (unsigned int *)(RAID_BASE_ADDR + offset);
3185 + writel(reg_val,addr);
3186 + return;
3187 +}
3188 +
3189 +#ifndef SPIN_WAIT
3190 +__inline__ void xor_queue_descriptor(void)
3191 +{
3192 + unsigned int flags,status=1;
3193 +
3194 + DPRINTK("Going to sleep");
3195 +
3196 + while(status){
3197 + yield();
3198 + //schedule();
3199 + spin_lock_irqsave(&raid_lock,flags);
3200 + status = tp.busy;
3201 + spin_unlock_irqrestore(&raid_lock, flags);
3202 + }
3203 +// tp.status = COMPLETE;
3204 + DPRINTK("woken up!");
3205 +
3206 +}
3207 +#endif
3208 +
3209 +#ifdef SPIN_WAIT
3210 +static void gemini_xor_isr(int d_n)
3211 +#else
3212 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
3213 +static void gemini_xor_isr(int irq, void *dev_id, struct pt_regs *regs)
3214 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3215 +static irqreturn_t gemini_xor_isr(int irq, void *dev_instance, struct pt_regs *regs)
3216 +#endif
3217 +#endif
3218 +{
3219 +
3220 + unsigned int err;
3221 + RAID_DMA_STATUS_T dma_status;
3222 +// RAID_DESCRIPTOR_T *rdesc,*tdesc;
3223 +// unsigned int *paddr;
3224 +
3225 + dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
3226 +#ifdef SPIN_WAIT
3227 + while( (dma_status.bits32& (1<<31) ) ==0 ){
3228 + udelay(1);
3229 + dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
3230 + }
3231 +
3232 +/* tdesc = tp.tx_first_desc;
3233 + rdesc = tp.rx_first_desc;
3234 + for(d_n;d_n>0;d_n--){
3235 + if( tdesc->func_ctrl.bits.own == DMA ){
3236 + paddr = tdesc;
3237 + printk("error tx desc:0x%x\n",*paddr++);
3238 + printk("error tx desc:0x%x\n",*paddr++);
3239 + printk("error tx desc:0s%x\n",*paddr++);
3240 + printk("error tx desc:0x%x\n",*paddr);
3241 + while(1);
3242 + }
3243 + tdesc = (RAID_DESCRIPTOR_T *)((tdesc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3244 + }
3245 +
3246 + if( rdesc->func_ctrl.bits.own == DMA ){
3247 + paddr = rdesc;
3248 + printk("error rx desc:0x%x\n",*paddr++);
3249 + printk("error rx desc:0x%x\n",*paddr++);
3250 + printk("error rx desc:0s%x\n",*paddr++);
3251 + printk("error rx desc:0x%x\n",*paddr);
3252 + while(1);
3253 + }
3254 +*/
3255 +#endif
3256 +
3257 + if(dma_status.bits32 & ((1<<31)|(1<<26))){
3258 + // if no bug , we can turn off rx finish interrupt
3259 + dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
3260 + err = raid_read_reg(RAID_DMA_DEVICE_ID);
3261 + tp.busy = 0;
3262 +
3263 + if(err&0x00FF0000){
3264 + tp.status = ERROR;
3265 + printk("XOR:<HW>%s error code %x\n",(err&0x00F00000)?"tx":"rx",err);
3266 +
3267 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
3268 + return ;
3269 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3270 +#ifndef SPIN_WAIT
3271 + return IRQ_RETVAL(IRQ_HANDLED);
3272 +#endif
3273 +#endif
3274 + }
3275 + // 16~19 rx error code
3276 + // 20~23 tx error codd
3277 +
3278 + dma_status.bits.tsFinishI = 1;
3279 + dma_status.bits.rsFinishI = 1;
3280 + raid_write_reg(RAID_DMA_STATUS, dma_status.bits32,0x84000000); // clear INT
3281 +
3282 +// printk("xor %d\n",d_n);
3283 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
3284 + return ;
3285 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3286 +#ifndef SPIN_WAIT
3287 + return IRQ_RETVAL(IRQ_HANDLED);
3288 +#endif
3289 +#endif
3290 + }
3291 +
3292 + #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
3293 + return ;
3294 + #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3295 + #ifndef SPIN_WAIT
3296 + printk("XOR: DMA status register(0x%8x)\n",dma_status.bits32);
3297 + return IRQ_RETVAL(IRQ_HANDLED);
3298 + #endif
3299 + #endif
3300 +}
3301 +
3302 +void
3303 +xor_gemini_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
3304 +{
3305 + int status=0;
3306 + unsigned int flags;
3307 +
3308 + if(bytes > (1<<(SRAM_PAR_SIZE+11))){
3309 + printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
3310 + }
3311 +
3312 + spin_lock_irqsave(&raid_lock,flags);
3313 + while(tp.status != COMPLETE){
3314 + spin_unlock_irqrestore(&raid_lock, flags);
3315 + //printk("XOR yield2\n");
3316 +#ifdef XOR_SW_FILL_IN
3317 + xor_arm4regs_2(bytes,p1,p2);
3318 + return ;
3319 +#else
3320 + yield();
3321 +#endif
3322 + }
3323 + spin_unlock_irqrestore(&raid_lock, flags);
3324 + tp.status = RUNNING;
3325 +
3326 + // flush the cache to memory before H/W XOR touches them
3327 + consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
3328 + consistent_sync(p2, bytes, DMA_TO_DEVICE);
3329 +
3330 +
3331 + tp.tx_desc = tp.tx_first_desc;
3332 + tp.rx_desc = tp.rx_first_desc;
3333 + if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
3334 + // prepare tx descript
3335 + raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
3336 + tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address
3337 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3338 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript
3339 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3340 + tp.tx_desc->flg_status.bits32 = 0x00020000;
3341 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3342 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3343 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3344 + wmb();
3345 + tp.tx_desc = tp.tx_cur_desc;
3346 + tp.tx_desc->buf_addr = (unsigned int)__pa(p2); // pysical address
3347 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3348 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript
3349 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3350 + tp.tx_desc->flg_status.bits32 = 0x00010000;
3351 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3352 + tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3353 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); // keep last descript
3354 +
3355 + wmb();
3356 + // prepare rx descript
3357 + raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFf);
3358 + tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
3359 + tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3360 + tp.rx_desc->flg_status.bits32 = 0; // link data from XOR
3361 +// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3362 + tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3363 + tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3364 +
3365 + }
3366 + else{
3367 + /* no free tx descriptor */
3368 + printk("XOR:no free tx descript");
3369 + return ;
3370 + }
3371 +
3372 + // change status
3373 +// tp.status = RUNNING;
3374 + status = tp.busy = 1;
3375 +
3376 + // start tx DMA
3377 + rxdma_ctrl.bits.rd_start = 1;
3378 + // start rx DMA
3379 + txdma_ctrl.bits.td_start = 1;
3380 +
3381 + raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
3382 + raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
3383 +
3384 +#ifdef SPIN_WAIT
3385 + gemini_xor_isr(2);
3386 +#else
3387 + xor_queue_descriptor();
3388 +#endif
3389 +
3390 + tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*2) ;
3391 + tp.status = COMPLETE;
3392 +// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ;
3393 +// tp.rx_desc = tp.rx_first_desc ;
3394 +// tp.rx_desc->func_ctrl.bits.own = DMA;
3395 +
3396 +}
3397 +
3398 +void
3399 +xor_gemini_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
3400 + unsigned long *p3)
3401 +{
3402 + int status=0;
3403 + unsigned int flags;
3404 +
3405 + if(bytes > (1<<(SRAM_PAR_SIZE+11))){
3406 + printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
3407 + }
3408 +
3409 + spin_lock_irqsave(&raid_lock,flags);
3410 + if(tp.status != COMPLETE){
3411 + spin_unlock_irqrestore(&raid_lock, flags);
3412 + //printk("XOR yield3\n");
3413 +#ifdef XOR_SW_FILL_IN
3414 + xor_arm4regs_3(bytes,p1,p2,p3);
3415 + return;
3416 +#else
3417 + yield();
3418 +#endif
3419 + }
3420 + spin_unlock_irqrestore(&raid_lock, flags);
3421 + tp.status = RUNNING;
3422 +
3423 + // flush the cache to memory before H/W XOR touches them
3424 + consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
3425 + consistent_sync(p2, bytes, DMA_TO_DEVICE);
3426 + consistent_sync(p3, bytes, DMA_TO_DEVICE);
3427 +
3428 + tp.tx_desc = tp.tx_first_desc;
3429 + tp.rx_desc = tp.rx_first_desc;
3430 + if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
3431 + // prepare tx descript
3432 + raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
3433 + tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address
3434 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3435 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript
3436 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3437 + tp.tx_desc->flg_status.bits32 = 0x00020000;
3438 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3439 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3440 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3441 +
3442 + tp.tx_desc = tp.tx_cur_desc;
3443 + tp.tx_desc->buf_addr = (unsigned int)__pa(p2); // pysical address
3444 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3445 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript
3446 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3447 + tp.tx_desc->flg_status.bits32 = 0x0000000;
3448 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3449 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3450 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3451 +
3452 + tp.tx_desc = tp.tx_cur_desc;
3453 + tp.tx_desc->buf_addr = (unsigned int)__pa(p3); // pysical address
3454 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3455 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript
3456 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3457 + tp.tx_desc->flg_status.bits32 = 0x00010000;
3458 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3459 + tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3460 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); // keep last descript
3461 +
3462 + // prepare rx descript
3463 + raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFf);
3464 + tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
3465 + tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3466 + tp.rx_desc->flg_status.bits32 = 0; // link data from XOR
3467 +// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3468 + tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3469 + tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3470 +
3471 + }
3472 + else{
3473 + /* no free tx descriptor */
3474 + printk("XOR:no free tx descript \n");
3475 + return ;
3476 + }
3477 +
3478 + // change status
3479 +// tp.status = RUNNING;
3480 + status = tp.busy = 1;
3481 +
3482 + // start tx DMA
3483 + rxdma_ctrl.bits.rd_start = 1;
3484 + // start rx DMA
3485 + txdma_ctrl.bits.td_start = 1;
3486 + wmb();
3487 + raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
3488 + raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
3489 +
3490 +#ifdef SPIN_WAIT
3491 + gemini_xor_isr(3);
3492 +#else
3493 + xor_queue_descriptor();
3494 +#endif
3495 + tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*3) | 0x0B;
3496 + tp.status = COMPLETE;
3497 +// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B;
3498 + //tp.rx_desc = tp.rx_first_desc ;
3499 +// tp.rx_desc->func_ctrl.bits.own = DMA;
3500 +
3501 +}
3502 +
3503 +void
3504 +xor_gemini_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
3505 + unsigned long *p3, unsigned long *p4)
3506 +{
3507 + int status=0;
3508 + unsigned int flags;
3509 +
3510 + if(bytes > (1<<(SRAM_PAR_SIZE+11))){
3511 + printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
3512 + }
3513 +
3514 + spin_lock_irqsave(&raid_lock,flags);
3515 + if(tp.status != COMPLETE){
3516 + spin_unlock_irqrestore(&raid_lock, flags);
3517 + //printk("S\n");
3518 +#ifdef XOR_SW_FILL_IN
3519 + xor_arm4regs_4(bytes,p1,p2,p3,p4);
3520 + return;
3521 +#else
3522 + msleep(1);
3523 + yield();
3524 +#endif
3525 + }
3526 + spin_unlock_irqrestore(&raid_lock, flags);
3527 +
3528 + tp.status = RUNNING;
3529 +
3530 + // flush the cache to memory before H/W XOR touches them
3531 + consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
3532 + consistent_sync(p2, bytes, DMA_TO_DEVICE);
3533 + consistent_sync(p3, bytes, DMA_TO_DEVICE);
3534 + consistent_sync(p4, bytes, DMA_TO_DEVICE);
3535 +
3536 + tp.tx_desc = tp.tx_first_desc;
3537 + tp.rx_desc = tp.rx_first_desc;
3538 + if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
3539 + // prepare tx descript
3540 + raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
3541 + tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address
3542 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3543 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript
3544 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3545 + tp.tx_desc->flg_status.bits32 = 0x00020000;
3546 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3547 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3548 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3549 +
3550 + tp.tx_desc = tp.tx_cur_desc;
3551 + tp.tx_cur_desc->buf_addr = (unsigned int)__pa(p2); // pysical address
3552 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3553 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript
3554 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3555 + tp.tx_desc->flg_status.bits32 = 0x00000000;
3556 + tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3557 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3558 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3559 +
3560 + tp.tx_desc = tp.tx_cur_desc;
3561 + tp.tx_desc->buf_addr = (unsigned int)__pa(p3); // pysical address
3562 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3563 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript
3564 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3565 + tp.tx_desc->flg_status.bits32 = 0x00000000;
3566 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3567 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3568 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3569 +
3570 +
3571 + tp.tx_desc = tp.tx_cur_desc;
3572 + tp.tx_desc->buf_addr = (unsigned int)__pa(p4); // pysical address
3573 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3574 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript
3575 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3576 + tp.tx_desc->flg_status.bits32 = 0x00010000;
3577 +// tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3578 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3579 + tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3580 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); // keep last descript
3581 +
3582 + // prepare rx descript
3583 + raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF);
3584 + tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
3585 + tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3586 + tp.rx_desc->flg_status.bits32 = 0; // link data from XOR
3587 +// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3588 + tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3589 + tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3590 +
3591 + }
3592 + else{
3593 + /* no free tx descriptor */
3594 + printk("XOR:no free tx descript");
3595 + return ;
3596 + }
3597 +
3598 + // change status
3599 +// tp.status = RUNNING;
3600 + status = tp.busy = 1;
3601 +
3602 + // start tx DMA
3603 + rxdma_ctrl.bits.rd_start = 1;
3604 + // start rx DMA
3605 + txdma_ctrl.bits.td_start = 1;
3606 + wmb();
3607 + raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
3608 + raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
3609 +
3610 +#ifdef SPIN_WAIT
3611 + gemini_xor_isr(4);
3612 +#else
3613 + xor_queue_descriptor();
3614 +#endif
3615 +
3616 + tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*4) | 0x0B;
3617 + tp.status = COMPLETE;
3618 +// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B;
3619 + //tp.rx_desc = tp.rx_first_desc ;
3620 +// tp.rx_desc->func_ctrl.bits.own = DMA;
3621 +
3622 +}
3623 +
3624 +void
3625 +xor_gemini_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
3626 + unsigned long *p3, unsigned long *p4, unsigned long *p5)
3627 +{
3628 +
3629 + int status=0;
3630 + unsigned int flags;
3631 +
3632 +
3633 + if(bytes > (1<<(SRAM_PAR_SIZE+11))){
3634 + printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
3635 + }
3636 +
3637 + spin_lock_irqsave(&raid_lock,flags);
3638 + while(tp.status != COMPLETE){
3639 + spin_unlock_irqrestore(&raid_lock, flags);
3640 + //printk("XOR yield5\n");
3641 +#ifdef XOR_SW_FILL_IN
3642 + xor_arm4regs_5(bytes,p1,p2,p3,p4,p5);
3643 + return;
3644 +#else
3645 + msleep(1);
3646 + yield();
3647 +#endif
3648 + }
3649 + spin_unlock_irqrestore(&raid_lock, flags);
3650 + tp.status = RUNNING;
3651 +
3652 + // flush the cache to memory before H/W XOR touches them
3653 + consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
3654 + consistent_sync(p2, bytes, DMA_TO_DEVICE);
3655 + consistent_sync(p3, bytes, DMA_TO_DEVICE);
3656 + consistent_sync(p4, bytes, DMA_TO_DEVICE);
3657 + consistent_sync(p5, bytes, DMA_TO_DEVICE);
3658 +
3659 + tp.tx_desc = tp.tx_first_desc;
3660 + tp.rx_desc = tp.rx_first_desc;
3661 + if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
3662 + // prepare tx descript
3663 + raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
3664 + tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address
3665 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3666 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript
3667 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3668 + tp.tx_desc->flg_status.bits32 = 0x00020000;
3669 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3670 + wmb();
3671 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3672 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3673 +