diff options
author | Imre Kaloz <kaloz@openwrt.org> | 2008-06-05 17:14:02 +0000 |
---|---|---|
committer | Imre Kaloz <kaloz@openwrt.org> | 2008-06-05 17:14:02 +0000 |
commit | 12d5244f2b95681f494b90e26e21d90e4bd88929 (patch) | |
tree | 24c34e6edb6d50c28a61df63b394818a7171bef0 /target/linux/storm/patches/001-arch.patch | |
parent | 6ca4659c4e3f5851d0c1ec7779ce34f339c925db (diff) | |
download | upstream-12d5244f2b95681f494b90e26e21d90e4bd88929.tar.gz upstream-12d5244f2b95681f494b90e26e21d90e4bd88929.tar.bz2 upstream-12d5244f2b95681f494b90e26e21d90e4bd88929.zip |
rename and renumber storm patches
SVN-Revision: 11368
Diffstat (limited to 'target/linux/storm/patches/001-arch.patch')
-rw-r--r-- | target/linux/storm/patches/001-arch.patch | 8864 |
1 files changed, 8864 insertions, 0 deletions
diff --git a/target/linux/storm/patches/001-arch.patch b/target/linux/storm/patches/001-arch.patch new file mode 100644 index 0000000000..b0461d44e3 --- /dev/null +++ b/target/linux/storm/patches/001-arch.patch @@ -0,0 +1,8864 @@ +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -220,6 +220,9 @@ + help + This enables support for the Cirrus EP93xx series of CPUs. + ++config ARCH_SL2312 ++ bool "SL2312" ++ + config ARCH_FOOTBRIDGE + bool "FootBridge" + select FOOTBRIDGE +@@ -414,6 +417,8 @@ + + source "arch/arm/mach-footbridge/Kconfig" + ++source "arch/arm/mach-sl2312/Kconfig" ++ + source "arch/arm/mach-integrator/Kconfig" + + source "arch/arm/mach-iop32x/Kconfig" +@@ -549,6 +554,16 @@ + config PCI_SYSCALL + def_bool PCI + ++config SL2312_LPC ++ bool "LPC Host Support" ++ depends on ARCH_SL2312 ++ help ++ ++config SL2312_LPC_IT8712 ++ bool "IT8712 Support" ++ depends on ARCH_SL2312 && SL2312_LPC ++ help ++ + # Select the host bridge type + config PCI_HOST_VIA82C505 + bool +@@ -988,6 +1003,10 @@ + source "drivers/mtd/Kconfig" + endif + ++if ARCH_SL2312 ++source "drivers/telephony/Kconfig" ++endif ++ + source "drivers/parport/Kconfig" + + source "drivers/pnp/Kconfig" +@@ -997,7 +1016,7 @@ + if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \ + || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ + || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ +- || ARCH_IXP23XX ++ || ARCH_IXP23XX || ARCH_SL2312 + source "drivers/ide/Kconfig" + endif + +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -72,6 +72,7 @@ + tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi + tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi + tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi ++tune-$(CONFIG_CPU_FA52X) :=-mtune=arm9tdmi + tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 + tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 + tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale +@@ -111,6 +112,7 @@ + machine-$(CONFIG_ARCH_PXA) := pxa + machine-$(CONFIG_ARCH_L7200) := l7200 + machine-$(CONFIG_ARCH_INTEGRATOR) := integrator ++ machine-$(CONFIG_ARCH_SL2312) := sl2312 + textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 + machine-$(CONFIG_ARCH_CLPS711X) := clps711x + machine-$(CONFIG_ARCH_IOP32X) := iop32x +--- a/arch/arm/boot/compressed/Makefile ++++ b/arch/arm/boot/compressed/Makefile +@@ -19,6 +19,10 @@ + OBJS += head-shark.o ofw-shark.o + endif + ++ifeq ($(CONFIG_ARCH_SL2312),y) ++OBJS += head-sl2312.o ++endif ++ + ifeq ($(CONFIG_ARCH_L7200),y) + OBJS += head-l7200.o + endif +--- /dev/null ++++ b/arch/arm/boot/compressed/head-sl2312.S +@@ -0,0 +1,6 @@ ++#include <asm/mach-types.h> ++#include <asm/arch/sl2312.h> ++ ++ .section ".start", "ax" ++ mov r7, #MACH_TYPE_SL2312 ++ +--- a/arch/arm/boot/compressed/head.S ++++ b/arch/arm/boot/compressed/head.S +@@ -57,6 +57,17 @@ + mov \rb, #0x50000000 + add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT + .endm ++/***************************************************** ++ * for Storlink SoC ++ *****************************************************/ ++#elif defined(CONFIG_ARCH_SL2312) ++ .macro loadsp, rb ++ mov \rb, #0x16000000 ++ .endm ++ .macro writeb, rb ++ strb \rb, [r3, #0] ++ .endm ++/****************************************************/ + #else + .macro loadsp, rb + addruart \rb +@@ -116,7 +127,28 @@ + .rept 8 + mov r0, r0 + .endr +- ++/***************************************************************************** ++ * for Storlink Soc -- on chip UART ++ *****************************************************************************/ ++#ifndef CONFIG_SERIAL_IT8712 // Jason test ++@ mov r3, #0x22000000 ++ mov r3, #0x42000000 ++ mov r11, #0x80 ++ strb r11, [r3, #0xc] ++ mov r11, #0x0 ++ strb r11, [r3, #0x4] ++#ifndef CONFIG_SL3516_ASIC ++ mov r11, #0x9C /*0x9c->19200 0x4E->38400 0x34->57600 */ ++#else ++ mov r11, #0x9C /* 0x61 for 30MHz on GeminiA chip*/ ++#endif ++ strb r11, [r3, #0x0] ++ mov r11, #0x03 ++ strb r11, [r3, #0xc] ++ mov r11, #0xFB ++ strb r11, [r3, #0x18] ++#endif ++/*****************************************************************************/ + b 1f + .word 0x016f2818 @ Magic numbers to help the loader + .word start @ absolute load/run zImage address +@@ -458,6 +490,39 @@ + mcr p15, 0, r0, c7, c5, 4 @ ISB + mov pc, r12 + ++/***************************************************************************** ++ * for Storlink Soc -- CPU cache ++ *****************************************************************************/ ++__fa526_cache_on: ++ mov r12, lr ++ bl __setup_mmu ++ mov r0, #0 ++ mcr p15, 0, r0, c7, c6, 0 @ Invalidate D cache ++ mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache ++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer ++ mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs ++ mcr p15, 0, r3, c2, c0, 0 @ load page table pointer ++ mov r0, #-1 ++ mcr p15, 0, r0, c3, c0, 0 @ load domain access register ++ mrc p15, 0, r0, c1, c0, 0 ++ mov r0, r0 ++ mov r0, r0 ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++ orr r0, r0, #0x0004 @ .... .... .... .1.. ++#endif ++#ifndef CONFIG_CPU_ICACHE_DISABLE ++ orr r0, r0, #0x1000 @ ...1 .... .... .... ++#endif ++ ++#ifndef DEBUG ++ orr r0, r0, #0x0039 @ Write buffer, mmu ++#endif ++ mcr p15, 0, r0, c1, c0 ++ mov r0, r0 ++ mov r0, r0 ++ mov pc, r12 ++/********************************************************************************/ ++ + __arm6_mmu_cache_on: + mov r12, lr + bl __setup_mmu +@@ -625,6 +690,16 @@ + + @ These match on the architecture ID + ++/***************************************************************************** ++ * for Storlink Soc -- CPU architecture ID ++ *****************************************************************************/ ++ .word 0x66015261 @ FA526 ++ .word 0xff01fff1 ++ b __fa526_cache_on ++ b __fa526_cache_off ++ b __fa526_cache_flush ++/*****************************************************************************/ ++ + .word 0x00020000 @ ARMv4T + .word 0x000f0000 + b __armv4_mmu_cache_on +@@ -712,6 +787,23 @@ + mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB + mov pc, r12 + ++/***************************************************************************** ++ * for Storlink Soc -- CPU cache ++ *****************************************************************************/ ++__fa526_cache_off: ++ mrc p15, 0, r0, c1, c0 ++ bic r0, r0, #0x000d ++ mov r1, #0 ++ mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache ++ mcr p15, 0, r1, c7, c10, 4 @ drain WB ++ mcr p15, 0, r0, c1, c0 @ turn MMU and cache off ++ mov r0, #0 ++ mcr p15, 0, r0, c7, c5, 0 @ invalidate whole cache v4 ++ mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB v4 ++ mov pc, lr ++/*****************************************************************************/ ++ ++ + __arm6_mmu_cache_off: + mov r0, #0x00000030 @ ARM6 control reg. + b __armv3_mmu_cache_off +@@ -759,6 +851,17 @@ + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + ++/***************************************************************************** ++ * for Storlink Soc -- CPU cache ++ *****************************************************************************/ ++__fa526_cache_flush: ++ mov r1, #0 ++ mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache ++ mcr p15, 0, r1, c7, c5, 0 @ flush I cache ++ mcr p15, 0, r1, c7, c10, 4 @ drain WB ++ mov pc, lr ++/*****************************************************************************/ ++ + + __armv6_mmu_cache_flush: + mov r1, #0 +--- /dev/null ++++ b/arch/arm/boot/compressed/it8712.h +@@ -0,0 +1,25 @@ ++ ++#ifndef __IT8712_H__ ++#define __IT8712_H__ ++ ++#include "asm/arch/sl2312.h" ++ ++#define IT8712_IO_BASE SL2312_LPC_IO_BASE ++//#define IT8712_IO_BASE 0x27000000 ++// Device LDN ++#define LDN_SERIAL1 0x01 ++#define LDN_SERIAL2 0x02 ++#define LDN_PARALLEL 0x03 ++#define LDN_KEYBOARD 0x05 ++#define LDN_MOUSE 0x06 ++#define LDN_GPIO 0x07 ++ ++#define IT8712_UART1_PORT 0x3F8 ++#define IT8712_UART2_PORT 0x2F8 ++ ++#define IT8712_GPIO_BASE 0x800 // 0x800-0x804 for GPIO set1-set5 ++ ++void LPCSetConfig(char LdnNumber, char Index, char data); ++char LPCGetConfig(char LdnNumber, char Index); ++ ++#endif +--- a/arch/arm/boot/compressed/misc.c ++++ b/arch/arm/boot/compressed/misc.c +@@ -30,7 +30,7 @@ + #include <asm/arch/uncompress.h> + + #ifdef CONFIG_DEBUG_ICEDCC +- ++#include "it8712.h" + #ifdef CONFIG_CPU_V6 + + static void icedcc_putc(int ch) +@@ -69,6 +69,7 @@ + #define flush() do { } while (0) + #endif + ++#if 0 + static void putstr(const char *ptr) + { + char c; +@@ -81,11 +82,36 @@ + + flush(); + } ++#endif + + #endif + + #define __ptr_t void * + ++#ifdef CONFIG_SERIAL_IT8712 ++unsigned int it8712_uart_base; ++#define UART_RX 0 ++#define UART_TX 0 ++#define UART_DLL 0 ++#define UART_TRG 0 ++#define UART_DLM 1 ++#define UART_IER 1 ++#define UART_FCTR 1 ++#define UART_IIR 2 ++#define UART_FCR 2 ++#define UART_EFR 2 ++#define UART_LCR 3 ++#define UART_MCR 4 ++#define UART_LSR 5 ++#define UART_MSR 6 ++#define UART_SCR 7 ++#define UART_EMSR 7 ++void LPCEnterMBPnP(void); ++void LPCExitMBPnP(void); ++int SearchIT8712(void); ++int InitLPCInterface(void); ++#endif ++ + /* + * Optimised C version of memzero for the ARM. + */ +@@ -346,6 +372,9 @@ + decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, + int arch_id) + { ++#ifdef CONFIG_SERIAL_IT8712 ++ unsigned char *addr; ++#endif + output_data = (uch *)output_start; /* Points to kernel start */ + free_mem_ptr = free_mem_ptr_p; + free_mem_ptr_end = free_mem_ptr_end_p; +@@ -353,6 +382,33 @@ + + arch_decomp_setup(); + ++#ifdef CONFIG_SERIAL_IT8712 ++ ++ InitLPCInterface(); ++ LPCSetConfig(0, 0x02, 0x01); ++ LPCSetConfig(LDN_SERIAL1, 0x30, 0x1); ++ LPCSetConfig(LDN_SERIAL1, 0x23, 0x0); ++ it8712_uart_base = IT8712_IO_BASE; ++ it8712_uart_base += ((LPCGetConfig(LDN_SERIAL1, 0x60) << 8) + LPCGetConfig(LDN_SERIAL1, 0x61)); ++ ++ do { ++ addr = (unsigned char *)(it8712_uart_base + UART_LCR) ; ++ *addr = 0x80; ++ // Set Baud Rate ++ addr = (unsigned char *)(it8712_uart_base+UART_DLL); ++ *addr = 0x06 ; ++ addr = (unsigned char *)(it8712_uart_base+UART_DLM); ++ *addr = 0x00 ; ++ ++ addr = (unsigned char *)(it8712_uart_base+UART_LCR); // LCR ++ *addr = 0x07 ; ++ addr = (unsigned char *)(it8712_uart_base+UART_MCR); // MCR ++ *addr = 0x08 ; ++ addr = (unsigned char *)(it8712_uart_base+UART_FCR); // FCR ++ *addr = 0x01 ; ++ } while(0); ++#endif ++ + makecrc(); + putstr("Uncompressing Linux..."); + gunzip(); +@@ -374,4 +430,119 @@ + return 0; + } + #endif ++ ++#ifdef CONFIG_SERIAL_IT8712 ++ ++#define LPC_KEY_ADDR (unsigned char *)(SL2312_LPC_IO_BASE + 0x2e) ++#define LPC_DATA_ADDR (unsigned char *)(SL2312_LPC_IO_BASE + 0x2f) ++#define LPC_BUS_CTRL *( unsigned char*) (SL2312_LPC_HOST_BASE + 0) ++#define LPC_BUS_STATUS *( unsigned char*) (SL2312_LPC_HOST_BASE + 2) ++#define LPC_SERIAL_IRQ_CTRL *( unsigned char*) (SL2312_LPC_HOST_BASE + 4) ++ ++char LPCGetConfig(char LdnNumber, char Index) ++{ ++ char rtn; ++ unsigned char *addr ; ++ ++ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode ++ ++ addr = LPC_KEY_ADDR; ++ *addr = 0x07 ; ++ ++ addr = LPC_DATA_ADDR; ++ *addr = LdnNumber ; ++ ++ addr = LPC_KEY_ADDR; ++ *addr = Index ; ++ ++ addr = LPC_DATA_ADDR ; ++ rtn = *addr ; ++ ++ LPCExitMBPnP(); ++ return rtn; ++ ++} ++ ++void LPCSetConfig(char LdnNumber, char Index, char data) ++{ ++ unsigned char *addr; ++ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode ++ addr = LPC_KEY_ADDR; ++ *addr = 0x07; ++ addr = LPC_DATA_ADDR; ++ *addr = LdnNumber; ++ addr = LPC_KEY_ADDR; ++ *addr = Index; ++ addr = LPC_DATA_ADDR; ++ *addr = data; ++ ++ LPCExitMBPnP(); ++} ++ ++//unsigned char key[4] ; ++void LPCEnterMBPnP(void) ++{ ++ unsigned char *addr; ++ addr = LPC_KEY_ADDR; ++ unsigned char key[4] = {0x87, 0x01, 0x55, 0x55}; ++ ++ do { ++ *addr = key[0]; ++ *addr = key[1]; ++ *addr = key[2]; ++ *addr = key[3]; ++ }while(0); ++} ++ ++void LPCExitMBPnP(void) ++{ ++ unsigned char *addr; ++ addr = LPC_KEY_ADDR; ++ *addr = 0x02 ; ++ ++ addr = LPC_DATA_ADDR; ++ *addr = 0x02 ; ++} ++ ++int InitLPCInterface(void) ++{ ++ int i; ++ LPC_BUS_CTRL = 0xc0; ++ LPC_SERIAL_IRQ_CTRL = 0xc0; ++ ++ for(i=0;i<0x2000;i++) ; ++ ++ LPC_SERIAL_IRQ_CTRL = 0x80; ++ if (!SearchIT8712()) ; ++// while(1); ++ return 0; ++} ++ ++int SearchIT8712(void) ++{ ++ unsigned char Id1, Id2; ++ unsigned short Id; ++ unsigned char *addr; ++ ++ LPCEnterMBPnP(); ++ addr = LPC_KEY_ADDR; ++ *addr = 0x20 ; ++ addr = LPC_DATA_ADDR; ++ Id1 = *addr ; ++ ++ addr = LPC_KEY_ADDR; ++ *addr = 0x21 ; ++ addr = LPC_DATA_ADDR; ++ Id2 = *addr ; ++ ++ Id = (Id1 << 8) | Id2; ++ LPCExitMBPnP(); ++ ++ if (Id == 0x8712) ++ return 1; ++ else ++ return 0; ++} ++ ++#endif + +--- a/arch/arm/kernel/entry-armv.S ++++ b/arch/arm/kernel/entry-armv.S +@@ -18,6 +18,8 @@ + #include <asm/memory.h> + #include <asm/glue.h> + #include <asm/vfpmacros.h> ++#include <asm/arch/irqs.h> ++#include <asm/hardware.h> + #include <asm/arch/entry-macro.S> + #include <asm/thread_notify.h> + +--- a/arch/arm/kernel/irq.c ++++ b/arch/arm/kernel/irq.c +@@ -40,6 +40,8 @@ + #include <asm/system.h> + #include <asm/mach/time.h> + ++extern int fixup_irq(unsigned int irq); ++ + /* + * No architecture-specific irq_finish function defined in arm/arch/irqs.h. + */ +@@ -111,8 +113,11 @@ + asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) + { + struct pt_regs *old_regs = set_irq_regs(regs); +- struct irq_desc *desc = irq_desc + irq; ++// struct irq_desc *desc = irq_desc + irq; ++ struct irq_desc *desc; + ++ irq = fixup_irq(irq); ++ desc = irq_desc + irq; + /* + * Some hardware gives randomly wrong interrupts. Rather + * than crashing, do something sensible. +--- a/arch/arm/kernel/process.c ++++ b/arch/arm/kernel/process.c +@@ -117,7 +117,7 @@ + void (*pm_idle)(void); + EXPORT_SYMBOL(pm_idle); + +-void (*pm_power_off)(void); ++//void (*pm_power_off)(void); + EXPORT_SYMBOL(pm_power_off); + + void (*arm_pm_restart)(char str) = arm_machine_restart; +@@ -188,13 +188,37 @@ + + void machine_halt(void) + { ++ unsigned int reg_v; ++ ++ printk("arch_power_off\n"); ++ ++ reg_v = readl(IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04); ++ reg_v &= ~0x00000002; ++ reg_v |= 0x1; ++ mdelay(5); ++ // Power off ++ __raw_writel( reg_v, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04); ++ + } + + + void machine_power_off(void) + { +- if (pm_power_off) ++ unsigned int reg_v; ++ ++// if (pm_power_off) ++ if (&pm_power_off!=NULL) + pm_power_off(); ++ ++ printk("arch_power_off\n"); ++ ++ reg_v = readl(IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04); ++ reg_v &= ~0x00000002; ++ reg_v |= 0x1; ++ mdelay(5); ++ // Power off ++ __raw_writel( reg_v, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04); ++ + } + + void machine_restart(char * __unused) +--- a/arch/arm/kernel/time.c ++++ b/arch/arm/kernel/time.c +@@ -502,8 +502,13 @@ + + device_initcall(timer_init_sysfs); + ++extern unsigned int rtc_get_time_second(void); ++ + void __init time_init(void) + { ++#ifdef CONFIG_SL2312_RTC ++ xtime.tv_sec = rtc_get_time_second() ; ++#endif + #ifndef CONFIG_GENERIC_TIME + if (system_timer->offset == NULL) + system_timer->offset = dummy_gettimeoffset; +--- /dev/null ++++ b/arch/arm/mach-sl2312/Kconfig +@@ -0,0 +1,33 @@ ++ ++menu "SL2312" ++ ++config SL3516_ASIC ++ bool "SL3516 ASIC version" ++ depends on ARCH_SL2312 ++ help ++ This option to select AISC or FPGA ++config PCI ++ bool "SL2312 PCI" ++ depends on ARCH_SL2312 ++ help ++ This option to enable Storlink PCI controller ++ ++config SL2312_LPC ++ bool "SL2312 LPC" ++ depends on ARCH_SL2312 ++ help ++ This option to enable Low Pin Count controller ++ ++config SL2312_USB ++ bool "SL2312 USB" ++ depends on ARCH_SL2312 ++ help ++ This option to enable USB OTG host controller ++ ++config GEMINI_IPI ++ bool "Gemini IPI test" ++ depends on ARCH_SL2312 ++ help ++ Enable this option to test dual cpu Inter-Processor-Interrupt ++endmenu ++ +--- /dev/null ++++ b/arch/arm/mach-sl2312/Makefile +@@ -0,0 +1,16 @@ ++# ++# Makefile for the linux kernel. ++# ++ ++# Object file lists. ++ ++obj-y := arch.o irq.o mm.o time.o sl3516_device.o ++obj-m := ++obj-n := ++ ++ ++obj-$(CONFIG_PCI) += pci.o ++obj-$(CONFIG_SL2312_LPC) += lpc.o ++obj-$(CONFIG_SL2312_USB) += sl2312-otg.o # sl2312-otg-1.o ++obj-$(CONFIG_GEMINI_XOR_ACCE) += xor.o ++obj-$(CONFIG_GEMINI_IPI) += gemini_ipi.o +--- /dev/null ++++ b/arch/arm/mach-sl2312/Makefile.boot +@@ -0,0 +1,5 @@ ++ zreladdr-y := 0x00008000 ++params_phys-y := 0x00508100 ++#params_phys-y := 0x00008100 ++initrd_phys-y := 0x00800000 ++ +--- /dev/null ++++ b/arch/arm/mach-sl2312/arch.c +@@ -0,0 +1,72 @@ ++/* ++ * linux/arch/arm/mach-epxa10db/arch.c ++ * ++ * Copyright (C) 2000 Deep Blue Solutions Ltd ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include <linux/types.h> ++#include <linux/init.h> ++ ++#include <asm/hardware.h> ++#include <asm/setup.h> ++#include <asm/mach-types.h> ++#include <asm/mach/time.h> ++#include <asm/mach/arch.h> ++ ++extern void sl2312_map_io(void); ++extern void sl2312_init_irq(void); ++extern unsigned long sl2312_gettimeoffset (void); ++extern void __init sl2312_time_init(void); ++ ++static struct sys_timer sl2312_timer = { ++ .init = sl2312_time_init, ++ .offset = sl2312_gettimeoffset, ++}; ++ ++static void __init ++sl2312_fixup(struct machine_desc *desc, struct tag *tags, ++ char **cmdline, struct meminfo *mi) ++{ ++ mi->nr_banks = 1; ++ mi->bank[0].start = 0; ++#ifdef CONFIG_GEMINI_IPI ++ mi->bank[0].size = (64*1024*1024); // 128M ++#else ++ mi->bank[0].size = (128*1024*1024); // 128M ++#endif ++ mi->bank[0].node = 0; ++} ++ ++/* MACHINE_START(SL2312, "GeminiA") ++ MAINTAINER("Storlink Semi") ++ BOOT_MEM(0x00000000, 0x90000000, 0xf0000000) ++ FIXUP(sl2312_fixup) ++ MAPIO(sl2312_map_io) ++ INITIRQ(sl2312_init_irq) ++ .timer = &sl2312_timer, ++MACHINE_END */ ++ ++MACHINE_START(SL2312, "GeminiA") ++ /* .phys_ram = 0x00000000, */ ++ .phys_io = 0x7fffc000, ++ .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc, ++ .boot_params = 0x100, ++ .fixup = sl2312_fixup, ++ .map_io = sl2312_map_io, ++ .init_irq = sl2312_init_irq, ++ .timer = &sl2312_timer, ++MACHINE_END +--- /dev/null ++++ b/arch/arm/mach-sl2312/gemini_ipi.c +@@ -0,0 +1,593 @@ ++/* ++ * FILE NAME sl_cir.c ++ * ++ * BRIEF MODULE DESCRIPTION ++ * IPI Driver for CPU1. ++ * ++ * Author: StorLink, Corp. ++ * Jason Lee ++ * ++ * Copyright 2002~2006 StorLink, Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMit8712D TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMit8712D TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, writ8712 to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include <linux/module.h> ++#include <linux/types.h> ++#include <linux/kernel.h> ++#include <linux/miscdevice.h> ++#include <linux/init.h> ++#include <linux/pagemap.h> ++#include <asm/uaccess.h> ++#include <linux/ioport.h> ++#include <linux/sched.h> ++#include <linux/delay.h> ++#include <linux/fs.h> ++#include <linux/interrupt.h> ++#include <asm/io.h> ++#include <asm/delay.h> ++#include <linux/signal.h> ++#include <asm/arch/sl2312.h> ++#include <asm/arch/int_ctrl.h> ++#include <asm/arch/ipi.h> ++#include <linux/dma-mapping.h> ++ ++ ++#include <linux/mm.h> ++ ++#include <linux/bootmem.h> ++ ++#include <asm/hardware.h> ++#include <asm/page.h> ++#include <asm/setup.h> ++#include <asm/pgtable.h> ++#include <asm/pgalloc.h> ++ ++#include <asm/mach/map.h> ++ ++ ++static int sl_ipi_debug = 1 ; ++#define DEB(x) if(sl_ipi_debug>=1) x ++ ++#define SRAM_PTR IO_ADDRESS(SL2312_SRAM_BASE) ++volatile JSCALE_REQ_T *req=(JSCALE_REQ_T*)SRAM_PTR; ++volatile JSCALE_RSP_T *rsp=(JSCALE_RSP_T*)(SRAM_PTR+0x20); ++ ++unsigned int jscale_status=0; ++ ++#define JSCALE_WAIT 0 ++#define XXXXXX_WAIT 1 ++#define MAX_WAIT_Q 8 ++wait_queue_head_t gemini_ipi_wait[MAX_WAIT_Q]; ++ ++#define DRAMCTL_DMA_CTL 0X20 ++#define DRAMCTL_DMA_SA 0X24 ++#define DRAMCTL_DMA_DA 0X28 ++#define DRAMCTL_DMA_CNT 0X2C ++#define MEMCPY_UNIT 0x40000 ++int hw_memcpy(const void *to, const void *from, unsigned int bytes) ++{ ++ unsigned int reg_a,reg_d; ++ int count = bytes,i=0; ++ ++ consistent_sync((unsigned int *)to, bytes, DMA_BIDIRECTIONAL); ++ consistent_sync((unsigned int *)from,bytes, DMA_TO_DEVICE); ++ ++ DEB(printk("hwmemcpy:count %d\n",count)); ++ while(count>0){ ++ // SA ++ reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_SA; ++ reg_d = (unsigned int )__virt_to_phys(from) + i*MEMCPY_UNIT; ++ DEB(printk("hwmemcpy:from 0x%08x\n",reg_d)); ++ writel(reg_d,reg_a); ++ // DA ++ reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_DA; ++ reg_d = (unsigned int )__virt_to_phys(to) + i*MEMCPY_UNIT; ++ writel(reg_d,reg_a); ++ DEB(printk("hwmemcpy:to 0x%08x\n",reg_d)); ++ // byte count ++ reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CNT; ++ reg_d = (count>=MEMCPY_UNIT)?MEMCPY_UNIT:count; ++ writel(reg_d,reg_a); ++ // start DMA ++ reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CTL; ++ writel(0x80000001,reg_a); ++ ++ do{ ++ cond_resched(); ++// msleep(4); ++ reg_d = readl(IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CTL); ++ }while(reg_d&0x1); ++ ++ count -= MEMCPY_UNIT; ++ i++; ++ } ++ ++ return bytes; ++} ++ ++static irqreturn_t ipi_interrupt() ++{ ++ unsigned int id=getcpuid(),tmp; ++ ++ //dmac_inv_range(__phys_to_virt(SL2312_SRAM_BASE),__phys_to_virt(SHAREADDR)+0x2000); ++ ++ ++ // Clear Interrupt ++ if(id==CPU0) { ++ tmp = readl(CPU1_STATUS); ++ tmp &= ~CPU_IPI_BIT_MASK; ++ writel(tmp,CPU1_STATUS); ++ } ++ else{ ++ tmp = readl(CPU0_STATUS); ++ tmp &= ~CPU_IPI_BIT_MASK; ++ writel(tmp,CPU0_STATUS); ++ } ++ ++ // ++ DEB(printk("ipi interrupt:0x%x\n",rsp->status)); ++ switch(rsp->status){ ++ case JSCALE_STATUS_OK: ++ ++ break; ++ case JSCALE_UNKNOWN_MSG_TYPE: ++ ++ break; ++ case JSCALE_FAILED_FILE_SIZE: ++ ++ break; ++ case JSCALE_FAILED_MALLOC: ++ ++ break; ++ case JSCALE_FAILED_FORMAT: ++ ++ break; ++ case JSCALE_DECODE_ERROR: ++ ++ break; ++ ++ } ++ jscale_status = rsp->status; ++// wake_up(&gemini_ipi_wait[JSCALE_WAIT]); ++ ++ return IRQ_HANDLED; ++} ++ ++static int gemini_ipi_open(struct inode *inode, struct file *file) ++{ ++ DEB(printk("ipi open\n")); ++ return 0; ++} ++ ++ ++static int gemini_ipi_release(struct inode *inode, struct file *file) ++{ ++ DEB(printk("ipi release\n")); ++ return 0; ++} ++ ++ ++static int gemini_ipi_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ JSCALE_RSP_T tmp; ++ ++ switch(cmd) { ++ case GEMINI_IPI_JSCALE_REQ: ++ DEB(printk("ipi:ioctl jscale request %dX%d Q:%d\n",req->ScaledImageWidth,req->ScaledImageHeight,req->ScaledImageQuality)); ++ if (copy_from_user(req, (JSCALE_REQ_T *)arg, sizeof(JSCALE_REQ_T))) ++ return -EFAULT; ++ req->hdr.type = IPC_JSCALE_REQ_MSG; ++ req->hdr.length = sizeof(JSCALE_REQ_T); ++ req->input_location = CPU_1_DATA_OFFSET; ++ req->output_location = CPU_1_DATA_OFFSET; ++ break; ++ case GEMINI_IPI_JSCALE_STAT: ++ DEB(printk("ipi:ioctl jscale stat \n")); ++ if(jscale_status==JSCALE_BUSY){ // not yet ++ tmp.status = JSCALE_BUSY; ++ if (copy_to_user((JSCALE_RSP_T *)arg,&tmp, sizeof(JSCALE_RSP_T))) ++ return -EFAULT; ++ } ++ else{ // finish or error ++ if (copy_to_user((JSCALE_RSP_T *)arg,rsp, sizeof(JSCALE_RSP_T))) ++ return -EFAULT; ++ } ++ break; ++ default: ++ printk("IPI: Error IOCTL number\n"); ++ return -ENOIOCTLCMD; ++ } ++ ++ return 0; ++} ++ ++#define SRAM_SIZE 0x2000 ++static ssize_t gemini_ipi_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos) ++{ ++ int i=0,tmp=0,j; ++ const char *ptr=(unsigned int)__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET); ++ DEB(printk("ipi:write 0x%x to 0x%x length:%d\n",&buf,ptr,count)); ++ memcpy(ptr,buf,count); ++ consistent_sync(ptr,count, DMA_TO_DEVICE); ++ //hw_memcpy(ptr,&buf,count); ++ ++/* if(count>SRAM_SIZE){ ++ for(i=0;i<(count/SRAM_SIZE);i++) ++ raid_memcpy(ptr+i*SRAM_SIZE,buf+i*SRAM_SIZE,SRAM_SIZE); ++ if(count%SRAM_SIZE) ++ raid_memcpy(ptr+i*SRAM_SIZE,buf+i*SRAM_SIZE,count%SRAM_SIZE); ++ } ++ else ++ raid_memcpy(ptr,buf,count); ++*/ ++ ++/* for(i=0;i<count;i++){ ++ if(buf[i]!=ptr[i]) ++ printk("ipi error:offset %d valud %x[should %x]\n",i,ptr[i],buf[i]); ++ } ++ ++ printk("===========input buf===============\n"); ++ for(i=0;i<64;i+=16){ ++ for(j=0;j<16;j++) ++ printk("%02x ",buf[i+j]); ++ printk("\n"); ++ cond_resched(); ++ } ++ printk("===========output buf==============\n"); ++ for(i=0;i<64;i+=16){ ++ for(j=0;j<16;j++) ++ printk("%02x ",ptr[i+j]); ++ printk("\n"); ++ cond_resched(); ++ } ++*/ ++ // send irq for CPU1 ++ tmp |= CPU_IPI_BIT_MASK; ++ writel(tmp,CPU0_STATUS); ++ jscale_status = JSCALE_BUSY; ++ ++ return count; ++} ++ ++static ssize_t gemini_ipi_read(struct file * file_p, char *buf, size_t length, loff_t * ppos) ++{ ++ int i=0; ++ const char *ptr=(unsigned int )__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET); ++ ++ consistent_sync(ptr,length, DMA_FROM_DEVICE); ++ memcpy(buf,ptr,length); ++ DEB(printk("ipi:read 0x%x to 0x%x length:%d\n",ptr,buf,length)); ++ ++ //consistent_sync((unsigned int *)ptr,0x2000, DMA_FROM_DEVICE); // invalid ++ //hw_memcpy(buf,ptr,length); ++ ++ // need encoded file size ******** ++/* if(count>SRAM_SIZE){ ++ for(i=0;i<(count/SRAM_SIZE);i++) ++ raid_memcpy(buf+i*SRAM_SIZE,p_mbox->message+i*SRAM_SIZE,SRAM_SIZE); ++ if(count%0xFFFF) ++ raid_memcpy(buf+i*SRAM_SIZE,p_mbox->message+i*SRAM_SIZE,length%SRAM_SIZE); ++ } ++ else ++ raid_memcpy(buf,p_mbox->message,length); ++*/ ++ return length; ++} ++ ++void do_mapping_read(struct address_space *mapping, ++ struct file_ra_state *_ra, ++ struct file *filp, ++ loff_t *ppos, ++ read_descriptor_t *desc, ++ read_actor_t actor) ++{ ++ struct inode *inode = mapping->host; ++ unsigned long index; ++ unsigned long end_index; ++ unsigned long offset; ++ unsigned long last_index; ++ unsigned long next_index; ++ unsigned long prev_index; ++ loff_t isize; ++ struct page *cached_page; ++ int error; ++ struct file_ra_state ra = *_ra; ++ ++ cached_page = NULL; ++ index = *ppos >> PAGE_CACHE_SHIFT; ++ next_index = index; ++ prev_index = ra.prev_page; ++ last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT; ++ offset = *ppos & ~PAGE_CACHE_MASK; ++ ++ isize = i_size_read(inode); ++ if (!isize) ++ goto out; ++ ++ end_index = (isize - 1) >> PAGE_CACHE_SHIFT; ++ for (;;) { ++ struct page *page; ++ unsigned long nr, ret; ++ ++ /* nr is the maximum number of bytes to copy from this page */ ++ nr = PAGE_CACHE_SIZE; ++ if (index >= end_index) { ++ if (index > end_index) ++ goto out; ++ nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1; ++ if (nr <= offset) { ++ goto out; ++ } ++ } ++ nr = nr - offset; ++ ++ cond_resched(); ++ if (index == next_index) ++ next_index = page_cache_readahead(mapping, &ra, filp, ++ index, last_index - index); ++ ++find_page: ++ page = find_get_page(mapping, index); ++ if (unlikely(page == NULL)) { ++ handle_ra_miss(mapping, &ra, index); ++ goto no_cached_page; ++ } ++ if (!PageUptodate(page)) ++ goto page_not_up_to_date; ++page_ok: ++ ++ /* If users can be writing to this page using arbitrary ++ * virtual addresses, take care about potential aliasing ++ * before reading the page on the kernel side. ++ */ ++ if (mapping_writably_mapped(mapping)) ++ flush_dcache_page(page); ++ ++ /* ++ * When (part of) the same page is read multiple times ++ * in succession, only mark it as accessed the first time. ++ */ ++ if (prev_index != index) ++ mark_page_accessed(page); ++ prev_index = index; ++ ++ /* ++ * Ok, we have the page, and it's up-to-date, so ++ * now we can copy it to user space... ++ * ++ * The actor routine returns how many bytes were actually used.. ++ * NOTE! This may not be the same as how much of a user buffer ++ * we filled up (we may be padding etc), so we can only update ++ * "pos" here (the actor routine has to update the user buffer ++ * pointers and the remaining count). ++ */ ++ ret = actor(desc, page, offset, nr); ++ offset += ret; ++ index += offset >> PAGE_CACHE_SHIFT; ++ offset &= ~PAGE_CACHE_MASK; ++ ++ page_cache_release(page); ++ if (ret == nr && desc->count) ++ continue; ++ goto out; ++ ++page_not_up_to_date: ++ /* Get exclusive access to the page ... */ ++ lock_page(page); ++ ++ /* Did it get unhashed before we got the lock? */ ++ if (!page->mapping) { ++ unlock_page(page); ++ page_cache_release(page); ++ continue; ++ } ++ ++ /* Did somebody else fill it already? */ ++ if (PageUptodate(page)) { ++ unlock_page(page); ++ goto page_ok; ++ } ++ ++readpage: ++ /* Start the actual read. The read will unlock the page. */ ++ error = mapping->a_ops->readpage(filp, page); ++ ++ if (unlikely(error)) ++ goto readpage_error; ++ ++ if (!PageUptodate(page)) { ++ lock_page(page); ++ if (!PageUptodate(page)) { ++ if (page->mapping == NULL) { ++ /* ++ * invalidate_inode_pages got it ++ */ ++ unlock_page(page); ++ page_cache_release(page); ++ goto find_page; ++ } ++ unlock_page(page); ++ error = -EIO; ++ goto readpage_error; ++ } ++ unlock_page(page); ++ } ++ ++ /* ++ * i_size must be checked after we have done ->readpage. ++ * ++ * Checking i_size after the readpage allows us to calculate ++ * the correct value for "nr", which means the zero-filled ++ * part of the page is not copied back to userspace (unless ++ * another truncate extends the file - this is desired though). ++ */ ++ isize = i_size_read(inode); ++ end_index = (isize - 1) >> PAGE_CACHE_SHIFT; ++ if (unlikely(!isize || index > end_index)) { ++ page_cache_release(page); ++ goto out; ++ } ++ ++ /* nr is the maximum number of bytes to copy from this page */ ++ nr = PAGE_CACHE_SIZE; ++ if (index == end_index) { ++ nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1; ++ if (nr <= offset) { ++ page_cache_release(page); ++ goto out; ++ } ++ } ++ nr = nr - offset; ++ goto page_ok; ++ ++readpage_error: ++ /* UHHUH! A synchronous read error occurred. Report it */ ++ desc->error = error; ++ page_cache_release(page); ++ goto out; ++ ++no_cached_page: ++ /* ++ * Ok, it wasn't cached, so we need to create a new ++ * page.. ++ */ ++ if (!cached_page) { ++ cached_page = page_cache_alloc_cold(mapping); ++ if (!cached_page) { ++ desc->error = -ENOMEM; ++ goto out; ++ } ++ } ++ error = add_to_page_cache_lru(cached_page, mapping, ++ index, GFP_KERNEL); ++ if (error) { ++ if (error == -EEXIST) ++ goto find_page; ++ desc->error = error; ++ goto out; ++ } ++ page = cached_page; ++ cached_page = NULL; ++ goto readpage; ++ } ++ ++out: ++ *_ra = ra; ++ ++ *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset; ++ if (cached_page) ++ page_cache_release(cached_page); ++ if (filp) ++ file_accessed(filp); ++} ++ ++int ipi_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) ++{ ++ ssize_t written; ++ unsigned long count = desc->count; ++ struct file *file = desc->arg.data; ++ unsigned int *ptr_to=(unsigned int)__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET) + desc->written; ++ void *ptr_from; ++ ++ if (size > count) ++ size = count; ++ ++ ptr_from = page_address(page)+offset; ++ written = memcpy(ptr_to,ptr_from,size); ++ ++ if (written < 0) { ++ desc->error = written; ++ written = 0; ++ } ++ desc->count = count - written; ++ desc->written += written; ++ return written; ++} ++ ++ssize_t gemini_ipi_sendfile(struct file *in_file, loff_t *ppos, ++ size_t count, read_actor_t actor, void *TARGET) ++{ ++ read_descriptor_t desc; ++ ++ if (!count) ++ return 0; ++ ++ desc.written = 0; ++ desc.count = count; ++ desc.arg.data = TARGET; ++ desc.error = 0; ++ ++ do_mapping_read(in_file->f_mapping,&in_file->f_ra,in_file, ppos, &desc, ipi_send_actor); ++ ++ if (desc.written) ++ return desc.written; ++ return desc.error; ++} ++static struct file_operations gemini_ipi_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = gemini_ipi_ioctl, ++ .open = gemini_ipi_open, ++ .release= gemini_ipi_release, ++ .write = gemini_ipi_write, ++ .read = gemini_ipi_read, ++ .sendfile = gemini_ipi_sendfile, ++}; ++ ++#ifndef STORLINK_IPI ++#define STORLINK_IPI 242 // Documents/devices.txt suggest to use 240~255 for local driver!! ++#endif ++ ++static struct miscdevice gemini_ipi_miscdev = ++{ ++ STORLINK_IPI, ++ "slave_ipc", ++ &gemini_ipi_fops ++}; ++ ++int __init sl_ipi_init(void) ++{ ++ ++ printk("Gemini IPI Driver Initialization...\n"); ++ printk("REQ Head :0x%x(phy:0x%x)\n",(unsigned int)req,(unsigned int)SL2312_SRAM_BASE); ++ printk("RSP Head :0x%x(phy:0x%x)\n",(unsigned int)rsp,(unsigned int)SL2312_SRAM_BASE+0x20); ++ 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); ++ ++ misc_register(&gemini_ipi_miscdev); ++ ++ if (request_irq(IRQ_CPU0_IP_IRQ_OFFSET, ipi_interrupt, SA_INTERRUPT, "ipi", NULL)) ++ printk("Error: Register IRQ for Storlink IPI failed\n"); ++ ++ return 0; ++} ++ ++void __exit sl_ipi_exit(void) ++{ ++ ++} ++ ++module_init(sl_ipi_init); ++module_exit(sl_ipi_exit); ++ ++MODULE_AUTHOR("Jason Lee <jason@storlink.com.tw>"); ++MODULE_DESCRIPTION("Storlink IPI driver"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/arch/arm/mach-sl2312/hw_xor.h +@@ -0,0 +1,573 @@ ++/* ++* linux/include/asm-arm/xor.h ++* ++* Copyright (C) 2001 Storlink Semi. ++* Jason Lee <jason@storlink.com.tw> ++* ++*/ ++#include <asm/arch/sl2312.h> ++#include <asm/io.h> ++//#include <linux/compatmac.h> ++ ++#undef BIG_ENDIAN ++#define CPU 0 ++#define DMA 1 ++ ++#define DESC_NO 8 ++#define TX_DESC_NUM DESC_NO ++#define RX_DESC_NUM DESC_NO ++ ++#define RAID_BASE_ADDR IO_ADDRESS(SL2312_RAID_BASE) ++ ++#define SRAM_PAR_0k 0 ++#define SRAM_PAR_4k 1 ++#define SRAM_PAR_8k 2 ++#define SRAM_PAR_16k 3 ++#define SRAM_PAR_SIZE SRAM_PAR_8k ++ ++#define RUNNING 0x1 ++#define COMPLETE 0x2 ++#define ERROR 0x4 ++ ++#define CMD_XOR 0x0 ++#define CMD_FILL 0x1 ++#define CMD_CPY 0x3 ++#define CMD_CHK 0x4 ++ ++enum RAID_DMA_REGISTER { ++ RAID_DMA_DEVICE_ID = 0xff00, ++ RAID_DMA_STATUS = 0xff04, ++ RAID_FCHDMA_CTRL = 0xff08, ++ RAID_FCHDMA_FIRST_DESC = 0xff0C, ++ RAID_FCHDMA_CURR_DESC = 0xff10, ++ RAID_STRDMA_CTRL = 0xff14, ++ RAID_STRDMA_FIRST_DESC = 0xff18, ++ RAID_STRDMA_CURR_DESC = 0xff1C, ++ RAID_TX_FLG_REG = 0xff24, ++ RAID_RX_FLG_REG = 0xff34, ++ RAID_PCR = 0xff50, ++ SMC_CMD_REG = 0xff60, ++ SMC_STATUS_REG = 0xff64 ++ }; ++ ++enum RAID_FUNC_MODE { ++ RAID_XOR = 0, ++ RAID_MIX = 2, ++ RAID_SRAM = 3, ++ RAID_ENDIAN = 4, ++ RAID_MEM_BLK = 5, ++ RAID_MEM2MEM = 7, ++ RAID_BUF_SIZE = 8, ++ RAID_ERR_TEST = 9, ++ RAID_BURST = 10, ++ RAID_BUS = 11 ++ }; ++ ++typedef struct reg_info { ++ int mask; ++ char err[32]; ++ int offset; ++} REG_INFO; ++ ++/********************************************************/ ++/* the definition of RAID DMA Module Register */ ++/********************************************************/ ++typedef union ++{ ++ unsigned int bit32; ++ struct bits_ff00 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int : 8; ++ unsigned int teytPerr : 4; /* define protocol error under tsPErrI*/ ++ unsigned int reytPerr : 14; /* define protocol error under rsPErrI */ ++ unsigned int device_id : 12; ++ unsigned int revision_id : 4; ++ #else ++ unsigned int revision_id : 4; ++ unsigned int device_id : 12; ++ unsigned int reytPerr : 14; /* define protocol error under rsPErrI */ ++ unsigned int teytPerr : 4; /* define protocol error under tsPErrI*/ ++ unsigned int : 8; ++ #endif ++ } bits; ++} RAID_DMA_DEVICE_ID_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bits_ff04 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int tsFinishI : 1; /* owner bit error interrupt */ ++ unsigned int tsDErrI : 1; /* AHB bus error interrupt */ ++ unsigned int tsPErrI : 1; /* RAID XOR fetch descriptor protocol error interrupt */ ++ unsigned int tsEODI : 1; /* RAID XOR fetch DMA end of descriptor interrupt */ ++ unsigned int tsEOFI : 1; /* RAID XOR fetch DMA end of frame interrupt */ ++ unsigned int rsFinishI : 1; /* owner bit error interrupt */ ++ unsigned int rsDErrI : 1; /* AHB bus error while RAID XOR store interrupt */ ++ unsigned int rsPErrI : 1; /* RAID XOR store descriptor protocol error interrupt */ ++ unsigned int rsEODI : 1; /* RAID XOR store DMA end of descriptor interrupt */ ++ unsigned int rsEOFI : 1; /* RAID XOR store DMA end of frame interrupt */ ++ unsigned int inter : 8; /* pattern check error interrupt */ ++ unsigned int : 5; ++ unsigned int Loopback : 1; /* loopback */ ++ unsigned int intEnable : 8; /*pattern check error interrupt enable */ ++ #else ++ unsigned int intEnable : 8; /*pattern check error interrupt enable */ ++ unsigned int Loopback : 1; /* loopback */ ++ unsigned int : 5; ++ unsigned int inter : 8; /* pattern check error interrupt */ ++ unsigned int rsEOFI : 1; /* RAID XOR store DMA end of frame interrupt */ ++ unsigned int rsEODI : 1; /* RAID XOR store DMA end of descriptor interrupt */ ++ unsigned int rsPErrI : 1; /* RAID XOR store descriptor protocol error interrupt */ ++ unsigned int rsDErrI : 1; /* AHB bus error while RAID XOR store interrupt */ ++ unsigned int rsFinishI : 1; /* owner bit error interrupt */ ++ unsigned int tsEOFI : 1; /* RAID XOR fetch DMA end of frame interrupt */ ++ unsigned int tsEODI : 1; /* RAID XOR fetch DMA end of descriptor interrupt */ ++ unsigned int tsPErrI : 1; /* RAID XOR fetch descriptor protocol error interrupt */ ++ unsigned int tsDErrI : 1; /* AHB bus error interrupt */ ++ unsigned int tsFinishI : 1; /* owner bit error interrupt */ ++ #endif ++ } bits; ++} RAID_DMA_STATUS_T; ++ ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bits_ff08 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int td_start : 1; /* Start DMA transfer */ ++ unsigned int td_continue : 1; /* Continue DMA operation */ ++ unsigned int td_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/ ++ unsigned int : 1; ++ unsigned int td_prot : 4; /* DMA protection control */ ++ unsigned int td_burst_size : 2; /* DMA max burst size for every AHB request */ ++ unsigned int td_bus : 2; /* peripheral bus width */ ++ unsigned int td_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */ ++ unsigned int td_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */ ++ unsigned int td_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */ ++ unsigned int : 14; ++ #else ++ unsigned int : 14; ++ unsigned int td_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */ ++ unsigned int td_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */ ++ unsigned int td_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */ ++ unsigned int td_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */ ++ unsigned int td_burst_size : 2; /* TxDMA max burst size for every AHB request */ ++ unsigned int td_prot : 4; /* TxDMA protection control */ ++ unsigned int : 1; ++ unsigned int td_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/ ++ unsigned int td_continue : 1; /* Continue DMA operation */ ++ unsigned int td_start : 1; /* Start DMA transfer */ ++ #endif ++ } bits; ++} RAID_TXDMA_CTRL_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bits_ff0c ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int td_first_des_ptr : 28;/* first descriptor address */ ++ unsigned int td_busy : 1;/* 1-TxDMA busy; 0-TxDMA idle */ ++ unsigned int : 3; ++ #else ++ unsigned int : 3; ++ unsigned int td_busy : 1;/* 1-TxDMA busy; 0-TxDMA idle */ ++ unsigned int td_first_des_ptr : 28;/* first descriptor address */ ++ #endif ++ } bits; ++} RAID_TXDMA_FIRST_DESC_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bits_ff10 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int ndar : 28; /* next descriptor address */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int : 1; ++ unsigned int sof_eof : 2; ++ #else ++ unsigned int sof_eof : 2; ++ unsigned int : 1; ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int ndar : 28; /* next descriptor address */ ++ #endif ++ } bits; ++} RAID_TXDMA_CURR_DESC_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bits_ff14 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int rd_start : 1; /* Start DMA transfer */ ++ unsigned int rd_continue : 1; /* Continue DMA operation */ ++ unsigned int rd_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/ ++ unsigned int : 1; ++ unsigned int rd_prot : 4; /* DMA protection control */ ++ unsigned int rd_burst_size : 2; /* DMA max burst size for every AHB request */ ++ unsigned int rd_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */ ++ unsigned int rd_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */ ++ unsigned int rd_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */ ++ unsigned int : 14; ++ #else ++ unsigned int : 14; ++ unsigned int rd_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */ ++ unsigned int rd_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */ ++ unsigned int rd_burst_size : 2; /* DMA max burst size for every AHB request */ ++ unsigned int rd_prot : 4; /* DMA protection control */ ++ unsigned int : 1; ++ unsigned int rd_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/ ++ unsigned int rd_continue : 1; /* Continue DMA operation */ ++ unsigned int rd_start : 1; /* Start DMA transfer */ ++ #endif ++ } bits; ++} RAID_RXDMA_CTRL_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bits_ff18 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int rd_first_des_ptr : 28;/* first descriptor address */ ++ unsigned int rd_busy : 1;/* 1-RxDMA busy; 0-RxDMA idle */ ++ unsigned int : 3; ++ #else ++ unsigned int : 3; ++ unsigned int rd_busy : 1;/* 1-RxDMA busy; 0-RxDMA idle */ ++ unsigned int rd_first_des_ptr : 28;/* first descriptor address */ ++ #endif ++ } bits; ++} RAID_RXDMA_FIRST_DESC_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bits_ff1c ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int ndar : 28; /* next descriptor address */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */ ++ unsigned int sof_eof : 2; ++ #else ++ unsigned int sof_eof : 2; ++ unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int ndar : 28; /* next descriptor address */ ++ #endif ++ } bits; ++} RAID_RXDMA_CURR_DESC_T; ++ ++typedef union ++{ ++ unsigned int bit32; ++ struct bits_ff50 ++ { ++ unsigned int pat : 32; /* data for pattern check */ ++ } bits; ++} RAID_PACR_T; ++ ++/******************************************************/ ++/* the definition of DMA Descriptor Register */ ++/******************************************************/ ++typedef struct raid_descriptor_t ++{ ++ union func_ctrl_t ++ { ++ unsigned int bit32; ++ struct bits_0000 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int own : 1; /* owner bit */ ++ unsigned int derr : 1; /* data error during processing this descriptor */ ++ unsigned int perr : 1; /* protocol error during processing this descriptor */ ++ unsigned int raid_ctrl_status : 7; /* pass RAID XOR fetch/store control status to CPU */ ++ unsigned int desc_cnt : 6; ++ unsigned int buffer_size : 16; /* transfer buffer size associated with current description*/ ++ #else ++ unsigned int buffer_size : 16; /* transfer buffer size associated with current description*/ ++ unsigned int desc_cnt : 6; ++ unsigned int raid_ctrl_status : 7; /* pass RAID XOR fetch/store control status to CPU */ ++ unsigned int perr : 1; /* protocol error during processing this descriptor */ ++ unsigned int derr : 1; /* data error during processing this descriptor */ ++ unsigned int own : 1; /* owner bit */ ++ #endif ++ } bits; ++ } func_ctrl; ++ ++ union flg_status_t ++ { ++ unsigned int bits32; ++ struct bit_004 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int bcc : 16; ++ unsigned int : 13 ++ unsigned int mode : 3; ++ #else ++ unsigned int mode : 3; ++ unsigned int : 13; ++ unsigned int bcc : 16; ++ #endif ++ } bits_cmd_status; ++ } flg_status; //Sanders ++ ++ unsigned int buf_addr; ++ ++ union next_desc_addr_t ++ { ++ unsigned int bits32; ++ struct bits_000c ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int ndar : 28; /* next descriptor address */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int : 1; ++ unsigned int sof_eof : 2; /* the position of the descriptor in chain */ ++ #else ++ unsigned int sof_eof : 2; /* the position of the descriptor in chain */ ++ unsigned int : 1; ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int ndar : 28; /* next descriptor address */ ++ #endif ++ } bits; ++ } next_desc_addr; ++} RAID_DESCRIPTOR_T; ++ ++/******************************************************/ ++/* the offset of RAID SMC register */ ++/******************************************************/ ++enum RAID_SMC_REGISTER { ++ RAID_SMC_CMD_REG = 0xff60, ++ RAID_SMC_STATUS_REG = 0xff64 ++ }; ++ ++/******************************************************/ ++/* the definition of RAID SMC module register */ ++/******************************************************/ ++typedef union ++{ ++ unsigned int bits32; ++ struct bits_ff60 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int pat_mode : 2; /* partition mode selection */ ++ unsigned int : 14; ++ unsigned int device_id : 12; ++ unsigned int revision_id : 4; ++ #else ++ unsigned int revision_id : 4; ++ unsigned int device_id : 12; ++ unsigned int : 14; ++ unsigned int pat_mode : 2; /* partition mode selection */ ++ #endif ++ } bits; ++} RAID_SMC_CMD; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bits_ff64 ++ { ++ #ifdef BIG_ENDIAN ++ unsigned int addr_err1 : 1; /* address is out of range for controller 1 */ ++ unsigned int ahb_err1 : 1; /* AHB bus error for controller 1 */ ++ unsigned int : 14; ++ unsigned int addr_err2 : 1; /* address is out of range for controller 2 */ ++ unsigned int ahb_err2 : 1; /* AHB bus error for controller 2 */ ++ unsigned int : 14; ++ #else ++ unsigned int : 14; ++ unsigned int ahb_err2 : 1; /* AHB bus error for controller 2 */ ++ unsigned int addr_err2 : 1; /* address is out of range for controller 2 */ ++ unsigned int : 14; ++ unsigned int ahb_err1 : 1; /* AHB bus error for controller 1 */ ++ unsigned int addr_err1 : 1; /* address is out of range for controller 1 */ ++ #endif ++ } bits; ++} RAID_SMC_STATUS; ++ ++typedef struct RAID_S ++{ ++ const char *device_name; ++ wait_queue_head_t wait; ++ unsigned int busy; ++ int irq; ++ unsigned int status; ++ RAID_DESCRIPTOR_T *tx_desc; /* point to virtual TX descriptor address */ ++ RAID_DESCRIPTOR_T *rx_desc; /* point ot virtual RX descriptor address */ ++ RAID_DESCRIPTOR_T *tx_cur_desc; /* current TX descriptor */ ++ RAID_DESCRIPTOR_T *rx_cur_desc; /* current RX descriptor */ ++ RAID_DESCRIPTOR_T *tx_finished_desc; ++ RAID_DESCRIPTOR_T *rx_finished_desc; ++ RAID_DESCRIPTOR_T *tx_first_desc; ++ RAID_DESCRIPTOR_T *rx_first_desc; ++ ++// unsigned int *tx_buf[TX_DESC_NUM]; ++ unsigned int *rx_desc_dma; // physical address of rx_descript ++ unsigned int *tx_desc_dma; // physical address of tx_descript ++ unsigned int *rx_bufs_dma; ++ unsigned int *tx_bufs_dma; ++ ++} RAID_T; ++ ++struct reg_ioctl ++{ ++ unsigned int reg_addr; ++ unsigned int val_in; ++ unsigned int val_out; ++}; ++ ++typedef struct dma_ctrl { ++ int sram; ++ int prot; ++ int burst; ++ int bus; ++ int endian; ++ int mode; ++} DMA_CTRL; ++ ++ ++#ifdef XOR_SW_FILL_IN ++ ++#define __XOR(a1, a2) a1 ^= a2 ++ ++#define GET_BLOCK_2(dst) \ ++ __asm__("ldmia %0, {%1, %2}" \ ++ : "=r" (dst), "=r" (a1), "=r" (a2) \ ++ : "0" (dst)) ++ ++#define GET_BLOCK_4(dst) \ ++ __asm__("ldmia %0, {%1, %2, %3, %4}" \ ++ : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \ ++ : "0" (dst)) ++ ++#define XOR_BLOCK_2(src) \ ++ __asm__("ldmia %0!, {%1, %2}" \ ++ : "=r" (src), "=r" (b1), "=r" (b2) \ ++ : "0" (src)); \ ++ __XOR(a1, b1); __XOR(a2, b2); ++ ++#define XOR_BLOCK_4(src) \ ++ __asm__("ldmia %0!, {%1, %2, %3, %4}" \ ++ : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \ ++ : "0" (src)); \ ++ __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4) ++ ++#define PUT_BLOCK_2(dst) \ ++ __asm__ __volatile__("stmia %0!, {%2, %3}" \ ++ : "=r" (dst) \ ++ : "0" (dst), "r" (a1), "r" (a2)) ++ ++#define PUT_BLOCK_4(dst) \ ++ __asm__ __volatile__("stmia %0!, {%2, %3, %4, %5}" \ ++ : "=r" (dst) \ ++ : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4)) ++ ++static void ++xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) ++{ ++ unsigned int lines = bytes / sizeof(unsigned long) / 4; ++ register unsigned int a1 __asm__("r4"); ++ register unsigned int a2 __asm__("r5"); ++ register unsigned int a3 __asm__("r6"); ++ register unsigned int a4 __asm__("r7"); ++ register unsigned int b1 __asm__("r8"); ++ register unsigned int b2 __asm__("r9"); ++ register unsigned int b3 __asm__("ip"); ++ register unsigned int b4 __asm__("lr"); ++ ++ do { ++ GET_BLOCK_4(p1); ++ XOR_BLOCK_4(p2); ++ PUT_BLOCK_4(p1); ++ } while (--lines); ++} ++ ++static void ++xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3) ++{ ++ unsigned int lines = bytes / sizeof(unsigned long) / 4; ++ register unsigned int a1 __asm__("r4"); ++ register unsigned int a2 __asm__("r5"); ++ register unsigned int a3 __asm__("r6"); ++ register unsigned int a4 __asm__("r7"); ++ register unsigned int b1 __asm__("r8"); ++ register unsigned int b2 __asm__("r9"); ++ register unsigned int b3 __asm__("ip"); ++ register unsigned int b4 __asm__("lr"); ++ ++ do { ++ GET_BLOCK_4(p1); ++ XOR_BLOCK_4(p2); ++ XOR_BLOCK_4(p3); ++ PUT_BLOCK_4(p1); ++ } while (--lines); ++} ++ ++static void ++xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3, unsigned long *p4) ++{ ++ unsigned int lines = bytes / sizeof(unsigned long) / 2; ++ register unsigned int a1 __asm__("r8"); ++ register unsigned int a2 __asm__("r9"); ++ register unsigned int b1 __asm__("ip"); ++ register unsigned int b2 __asm__("lr"); ++ ++ do { ++ GET_BLOCK_2(p1); ++ XOR_BLOCK_2(p2); ++ XOR_BLOCK_2(p3); ++ XOR_BLOCK_2(p4); ++ PUT_BLOCK_2(p1); ++ } while (--lines); ++} ++ ++static void ++xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3, unsigned long *p4, unsigned long *p5) ++{ ++ unsigned int lines = bytes / sizeof(unsigned long) / 2; ++ register unsigned int a1 __asm__("r8"); ++ register unsigned int a2 __asm__("r9"); ++ register unsigned int b1 __asm__("ip"); ++ register unsigned int b2 __asm__("lr"); ++ ++ do { ++ GET_BLOCK_2(p1); ++ XOR_BLOCK_2(p2); ++ XOR_BLOCK_2(p3); ++ XOR_BLOCK_2(p4); ++ XOR_BLOCK_2(p5); ++ PUT_BLOCK_2(p1); ++ } while (--lines); ++} ++#endif //XOR_SW_FILL_IN ++ +--- /dev/null ++++ b/arch/arm/mach-sl2312/irq.c +@@ -0,0 +1,202 @@ ++/* ++ * linux/arch/arm/mach-epxa10db/irq.c ++ * ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include <linux/init.h> ++#include <linux/ioport.h> ++#include <linux/stddef.h> ++#include <linux/list.h> ++#include <linux/sched.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++#include <asm/io.h> ++#include <asm/mach/irq.h> ++#include <asm/arch/platform.h> ++#include <asm/arch/int_ctrl.h> ++ ++#ifdef CONFIG_PCI ++#include <asm/arch/pci.h> ++#endif ++ ++int fixup_irq(unsigned int irq) ++{ ++#ifdef CONFIG_PCI ++ if (irq == IRQ_PCI) { ++ return sl2312_pci_get_int_src(); ++ } ++#endif ++ return irq; ++} ++ ++static void sl2312_ack_irq(unsigned int irq) ++{ ++ __raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++} ++ ++static void sl2312_mask_irq(unsigned int irq) ++{ ++ unsigned int mask; ++ ++#ifdef CONFIG_PCI ++ if (irq >= PCI_IRQ_OFFSET) ++ { ++ mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ mask &= ~IRQ_PCI_MASK ; ++ __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ sl2312_pci_mask_irq(irq - PCI_IRQ_OFFSET); ++ } ++ else ++#endif ++ if(irq >= FIQ_OFFSET) ++ { ++ mask = __raw_readl(FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ mask &= ~(1 << (irq - FIQ_OFFSET)); ++ __raw_writel(mask, FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ } ++ else ++ { ++ mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ mask &= ~(1 << irq); ++ __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ } ++ ++} ++ ++static void sl2312_unmask_irq(unsigned int irq) ++{ ++ unsigned int mask; ++ ++#ifdef CONFIG_PCI ++ if (irq >= PCI_IRQ_OFFSET) ++ { ++ mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ mask |= IRQ_PCI_MASK ; ++ __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ sl2312_pci_unmask_irq(irq - PCI_IRQ_OFFSET); ++ } ++ else ++#endif ++ if(irq >= FIQ_OFFSET) ++ { ++ mask = __raw_readl(FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ mask |= (1 << (irq - FIQ_OFFSET)); ++ __raw_writel(mask, FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ } ++ else ++ { ++ mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ mask |= (1 << irq); ++ __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ } ++} ++ ++static struct irq_chip sl2312_level_irq = { ++ .ack = sl2312_mask_irq, ++ .mask = sl2312_mask_irq, ++ .unmask = sl2312_unmask_irq, ++// .set_type = ixp4xx_set_irq_type, ++}; ++ ++static struct irq_chip sl2312_edge_irq = { ++ .ack = sl2312_ack_irq, ++ .mask = sl2312_mask_irq, ++ .unmask = sl2312_unmask_irq, ++// .set_type = ixp4xx_set_irq_type, ++}; ++ ++static struct resource irq_resource = { ++ .name = "irq_handler", ++ .start = IO_ADDRESS(SL2312_INTERRUPT_BASE), ++ .end = IO_ADDRESS(FIQ_STATUS(SL2312_INTERRUPT_BASE))+4, ++}; ++ ++void __init sl2312_init_irq(void) ++{ ++ unsigned int i, mode, level; ++ ++ request_resource(&iomem_resource, &irq_resource); ++ ++ for (i = 0; i < NR_IRQS; i++) ++ { ++ if((i>=IRQ_TIMER1 && i<=IRQ_TIMER3)||(i>=IRQ_SERIRQ0 && i<=IRQ_SERIRQ_MAX)) ++ { ++ set_irq_chip(i, &sl2312_edge_irq); ++ set_irq_handler(i, handle_edge_irq); ++ } ++ else ++ { ++ set_irq_chip(i, &sl2312_level_irq); ++ set_irq_handler(i,handle_level_irq); ++ } ++ set_irq_flags(i, IRQF_VALID | IRQF_PROBE); ++ } ++ ++ /* Disable all interrupt */ ++ __raw_writel(0,IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ __raw_writel(0,FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ ++ /* Set interrupt mode */ ++ /* emac & ipsec type is level trigger and high active */ ++ mode = __raw_readl(IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ level = __raw_readl(IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ ++ mode &= ~IRQ_GMAC0_MASK; ++ level &= ~IRQ_GMAC0_MASK; ++ ++ mode &= ~IRQ_GMAC1_MASK; ++ level &= ~IRQ_GMAC1_MASK; ++ ++ mode &= ~IRQ_IPSEC_MASK; ++ level &= ~IRQ_IPSEC_MASK; ++ ++ // for IDE0,1, high active and level trigger ++ mode &= ~IRQ_IDE0_MASK; ++ level &= ~IRQ_IDE0_MASK; ++ mode &= ~IRQ_IDE1_MASK; ++ level &= ~IRQ_IDE1_MASK; ++ ++ ++ // for PCI, high active and level trigger ++ mode &= ~IRQ_PCI_MASK; ++ level &= ~IRQ_PCI_MASK; ++ ++ // for USB, high active and level trigger ++ mode &= ~IRQ_USB0_MASK; ++ level &= ~IRQ_USB0_MASK; ++ ++ mode &= ~IRQ_USB1_MASK; ++ level &= ~IRQ_USB1_MASK; ++ ++ // for LPC, high active and edge trigger ++ mode |= 0xffff0000; ++ level &= 0x0000ffff; ++ ++ // for GPIO, high active and level trigger ++ mode &= ~(IRQ_GPIO_MASK); ++ level &= ~(IRQ_GPIO_MASK); ++ ++ mode &= ~(IRQ_GPIO1_MASK); ++ level &= ~(IRQ_GPIO1_MASK); ++ ++ mode &= ~(IRQ_GPIO2_MASK); ++ level &= ~(IRQ_GPIO2_MASK); ++ ++ __raw_writel(mode,IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ __raw_writel(level,IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))); ++ ++} +--- /dev/null ++++ b/arch/arm/mach-sl2312/lpc.c +@@ -0,0 +1,125 @@ ++/* ++ * ++ * BRIEF MODULE DESCRIPTION ++ * ITE Semi IT8712 Super I/O functions. ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * Author: MontaVista Software, Inc. ++ * ppopov@mvista.com or source@mvista.com ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include <linux/kernel.h> ++#include <linux/delay.h> ++#include <asm/io.h> ++#include <asm/types.h> ++#include <asm/arch/it8712.h> ++#include <linux/init.h> ++#include <asm/arch/hardware.h> ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++ ++// MB PnP configuration register ++#define LPC_KEY_ADDR (IO_ADDRESS(SL2312_LPC_IO_BASE) + 0x2e) ++#define LPC_DATA_ADDR (IO_ADDRESS(SL2312_LPC_IO_BASE) + 0x2f) ++ ++#define LPC_BUS_CTRL *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 0) ++#define LPC_BUS_STATUS *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 2) ++#define LPC_SERIAL_IRQ_CTRL *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 4) ++ ++int it8712_exist; ++ ++static void LPCEnterMBPnP(void) ++{ ++ int i; ++ unsigned char key[4] = {0x87, 0x01, 0x55, 0x55}; ++ ++ for (i = 0; i<4; i++) ++ outb(key[i], LPC_KEY_ADDR); ++ ++} ++ ++static void LPCExitMBPnP(void) ++{ ++ outb(0x02, LPC_KEY_ADDR); ++ outb(0x02, LPC_DATA_ADDR); ++} ++ ++void LPCSetConfig(char LdnNumber, char Index, char data) ++{ ++ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode ++ outb(0x07, LPC_KEY_ADDR); ++ outb(LdnNumber, LPC_DATA_ADDR); ++ outb(Index, LPC_KEY_ADDR); ++ outb(data, LPC_DATA_ADDR); ++ LPCExitMBPnP(); ++} ++ ++char LPCGetConfig(char LdnNumber, char Index) ++{ ++ char rtn; ++ ++ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode ++ outb(0x07, LPC_KEY_ADDR); ++ outb(LdnNumber, LPC_DATA_ADDR); ++ outb(Index, LPC_KEY_ADDR); ++ rtn = inb(LPC_DATA_ADDR); ++ LPCExitMBPnP(); ++ return rtn; ++} ++ ++static int SearchIT8712(void) ++{ ++ unsigned char Id1, Id2; ++ unsigned short Id; ++ ++ LPCEnterMBPnP(); ++ outb(0x20, LPC_KEY_ADDR); /* chip id byte 1 */ ++ Id1 = inb(LPC_DATA_ADDR); ++ outb(0x21, LPC_KEY_ADDR); /* chip id byte 2 */ ++ Id2 = inb(LPC_DATA_ADDR); ++ Id = (Id1 << 8) | Id2; ++ LPCExitMBPnP(); ++ if (Id == 0x8712) ++ return TRUE; ++ else ++ return FALSE; ++} ++ ++int InitLPCInterface(void) ++{ ++ LPC_BUS_CTRL = 0xc0; ++ LPC_SERIAL_IRQ_CTRL = 0xc0; ++ mdelay(1); // wait for 1 serial IRQ cycle ++ LPC_SERIAL_IRQ_CTRL = 0x80; ++ it8712_exist = SearchIT8712(); ++ printk("IT8712 %s exist\n", it8712_exist?"":"doesn't"); ++ return 0; ++} ++ ++//__initcall(InitLPCInterface); +--- /dev/null ++++ b/arch/arm/mach-sl2312/mm.c +@@ -0,0 +1,80 @@ ++/* ++ * linux/arch/arm/mach-epxa10db/mm.c ++ * ++ * MM routines for Altera'a Epxa10db board ++ * ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include <linux/sched.h> ++#include <linux/mm.h> ++#include <linux/init.h> ++ ++#include <asm/hardware.h> ++#include <asm/io.h> ++#include <asm/pgtable.h> ++#include <asm/page.h> ++#include <asm/sizes.h> ++ ++#include <asm/mach/map.h> ++ ++/* Page table mapping for I/O region */ ++static struct map_desc sl2312_io_desc[] __initdata = { ++#ifdef CONFIG_GEMINI_IPI ++{__phys_to_virt(CPU_1_MEM_BASE), __phys_to_pfn(CPU_1_MEM_BASE), SZ_64M, MT_MEMORY}, ++#endif ++{IO_ADDRESS(SL2312_SRAM_BASE), __phys_to_pfn(SL2312_SRAM_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_DRAM_CTRL_BASE), __phys_to_pfn(SL2312_DRAM_CTRL_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_GLOBAL_BASE), __phys_to_pfn(SL2312_GLOBAL_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_WAQTCHDOG_BASE), __phys_to_pfn(SL2312_WAQTCHDOG_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_UART_BASE), __phys_to_pfn(SL2312_UART_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_TIMER_BASE), __phys_to_pfn(SL2312_TIMER_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_LCD_BASE), __phys_to_pfn(SL2312_LCD_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_RTC_BASE), __phys_to_pfn(SL2312_RTC_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_SATA_BASE), __phys_to_pfn(SL2312_SATA_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_LPC_HOST_BASE), __phys_to_pfn(SL2312_LPC_HOST_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_LPC_IO_BASE), __phys_to_pfn(SL2312_LPC_IO_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_INTERRUPT_BASE), __phys_to_pfn(SL2312_INTERRUPT_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_INTERRUPT1_BASE), __phys_to_pfn(SL2312_INTERRUPT1_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_SSP_CTRL_BASE), __phys_to_pfn(SL2312_SSP_CTRL_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_POWER_CTRL_BASE), __phys_to_pfn(SL2312_POWER_CTRL_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_CIR_BASE), __phys_to_pfn(SL2312_CIR_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_GPIO_BASE), __phys_to_pfn(SL2312_GPIO_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_GPIO_BASE1), __phys_to_pfn(SL2312_GPIO_BASE1), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_GPIO_BASE2), __phys_to_pfn(SL2312_GPIO_BASE2), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_PCI_IO_BASE), __phys_to_pfn(SL2312_PCI_IO_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_PCI_MEM_BASE), __phys_to_pfn(SL2312_PCI_MEM_BASE), SZ_512K, MT_DEVICE}, ++#ifdef CONFIG_NET_SL351X ++{IO_ADDRESS(SL2312_TOE_BASE), __phys_to_pfn(SL2312_TOE_BASE) , SZ_512K, MT_DEVICE}, ++#endif ++{IO_ADDRESS(SL2312_GMAC0_BASE), __phys_to_pfn(SL2312_GMAC0_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_GMAC1_BASE), __phys_to_pfn(SL2312_GMAC1_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_SECURITY_BASE), __phys_to_pfn(SL2312_SECURITY_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_IDE0_BASE), __phys_to_pfn(SL2312_IDE0_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_IDE1_BASE), __phys_to_pfn(SL2312_IDE1_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_RAID_BASE), __phys_to_pfn(SL2312_RAID_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_FLASH_CTRL_BASE), __phys_to_pfn(SL2312_FLASH_CTRL_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_DRAM_CTRL_BASE), __phys_to_pfn(SL2312_DRAM_CTRL_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_GENERAL_DMA_BASE), __phys_to_pfn(SL2312_GENERAL_DMA_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_USB0_BASE), __phys_to_pfn(SL2312_USB_BASE), SZ_512K, MT_DEVICE}, ++{IO_ADDRESS(SL2312_USB1_BASE), __phys_to_pfn(SL2312_USB1_BASE), SZ_512K, MT_DEVICE}, ++{FLASH_VADDR(SL2312_FLASH_BASE), __phys_to_pfn(SL2312_FLASH_BASE), SZ_16M, MT_DEVICE}, ++}; ++ ++void __init sl2312_map_io(void) ++{ ++ iotable_init(sl2312_io_desc, ARRAY_SIZE(sl2312_io_desc)); ++} +--- /dev/null ++++ b/arch/arm/mach-sl2312/pci.c +@@ -0,0 +1,359 @@ ++/* ++ * linux/arch/arm/mach-sl2312/pci_sl2312.c ++ * ++ * PCI functions for sl2312 host PCI bridge ++ * ++ * Copyright (C) 2003 StorLink Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include <linux/sched.h> ++#include <linux/kernel.h> ++#include <linux/pci.h> ++#include <linux/ptrace.h> ++#include <linux/slab.h> ++#include <linux/ioport.h> ++#include <linux/interrupt.h> ++#include <linux/spinlock.h> ++#include <linux/init.h> ++ ++#include <asm/sizes.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++#include <asm/system.h> ++#include <asm/mach/pci.h> ++#include <asm/mach/irq.h> ++#include <asm/mach-types.h> ++ ++#include <asm/arch/pci.h> ++ ++//#define DEBUG ++ ++// sl2312 PCI bridge access routines ++ ++#define PCI_IOSIZE_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE))) ++#define PCI_PROT_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x04)) ++#define PCI_CTRL_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x08)) ++#define PCI_SOFTRST_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x10)) ++#define PCI_CONFIG_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x28)) ++#define PCI_DATA_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x2C)) ++ ++static spinlock_t sl2312_pci_lock = SPIN_LOCK_UNLOCKED; ++// for initialize PCI devices ++struct resource pci_ioport_resource = { ++ .name = "PCI I/O Space", ++ .start = IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x100, ++ .end = IO_ADDRESS(SL2312_PCI_IO_BASE) + SZ_512K - 1, ++ .flags = IORESOURCE_IO, ++}; ++struct resource pci_iomem_resource = { ++ .name = "PCI Mem Space", ++ .start = SL2312_PCI_MEM_BASE, ++ .end = SL2312_PCI_MEM_BASE + SZ_128M - 1, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static int sl2312_read_config(struct pci_bus *bus, unsigned int devfn, int where,int size, u32 *val) ++{ ++ unsigned long addr,data; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sl2312_pci_lock, flags); ++ addr = 0x80000000 | (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | (where & ~3); ++ PCI_CONFIG_REG = addr; ++ data = PCI_DATA_REG; ++ ++ switch (size) { ++ case 1: ++ *val = (u8) (data >> ((where & 0x03) * 8)); ++ break; ++ case 2: ++ *val = (u16) (data >> ((where & 0x02) * 8)); ++ break; ++ case 4: ++ *val = data; ++ if ((where >= 0x10) && (where <= 0x24)) { ++ if ((*val & 0xfff00000) == SL2312_PCI_IO_BASE) { ++ *val &= 0x000fffff; ++ *val |= IO_ADDRESS(SL2312_PCI_IO_BASE); ++ } ++ } ++ break; ++ } ++ spin_unlock_irqrestore(&sl2312_pci_lock, flags); ++// printk("READ==>slot=%d fn=%d where=%d value=%x\n",PCI_SLOT(devfn),PCI_FUNC(devfn),where,*val); ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int sl2312_write_config(struct pci_bus *bus, unsigned int devfn, int where,int size, u32 val) ++{ ++ unsigned long addr,data; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sl2312_pci_lock, flags); ++ addr = 0x80000000 | (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | (where & ~3); ++ PCI_CONFIG_REG = addr; ++ data = PCI_DATA_REG; ++ ++ switch (size) { ++ case 1: ++ data &= ~(0xff << ((where & 0x03) * 8)); ++ data |= (val << ((where & 0x03) * 8)); ++ PCI_DATA_REG = data; ++ break; ++ case 2: ++ data &= ~(0xffff << ((where & 0x02) * 8)); ++ data |= (val << ((where & 0x02) * 8)); ++ PCI_DATA_REG = data; ++ break; ++ case 4: ++ if ((where >= 0x10) && (where <= 0x24)) { ++ if ((val & 0xfff00000) == IO_ADDRESS(SL2312_PCI_IO_BASE)) { ++ val &= 0x000fffff; ++ val |= SL2312_PCI_IO_BASE; ++ } ++ } ++ PCI_DATA_REG = val; ++ break; ++ } ++ spin_unlock_irqrestore(&sl2312_pci_lock, flags); ++ ++// printk("WRITE==> slot=%d fn=%d where=%d value=%x \n",PCI_SLOT(devfn),PCI_FUNC(devfn),where,val); ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static struct pci_ops sl2312_pci_ops = { ++ .read = sl2312_read_config, ++ .write = sl2312_write_config, ++}; ++ ++ ++int __init sl2312_pci_setup_resources(struct resource **resource) ++{ ++ PCI_IOSIZE_REG = 0; // 1M IO size ++ PCI_CTRL_REG = 0x06; ++ ++ resource[0] = &pci_ioport_resource; ++ resource[1] = &pci_iomem_resource; ++ resource[2] = NULL; ++ ++ return 1; ++} ++ ++//static int sl2312_pci_fault(unsigned long addr, struct pt_regs *regs) ++//{ ++// return 1; ++//} ++ ++ ++/********************************************************************** ++ * MASK(disable) PCI interrupt ++ * 0: PCI INTA, 1: PCI INTB, ... // for Linux interrupt routing ++ * 16: PERR // for PCI module internal use ++ * 17: SERR,.. respect to PCI CTRL2 REG ++ **********************************************************************/ ++void sl2312_pci_mask_irq(unsigned int irq) ++{ ++ struct pci_bus bus; ++ unsigned int tmp; ++ ++ bus.number = 0; ++ sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp); ++ if (irq < 16) { // for linux int routing ++ tmp &= ~(1 << (irq + 16 + 6)); ++ } ++ else { ++ tmp &= ~(1 << irq); ++ } ++ sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp); ++} ++ ++/* UNMASK(enable) PCI interrupt */ ++void sl2312_pci_unmask_irq(unsigned int irq) ++{ ++ struct pci_bus bus; ++ unsigned int tmp; ++ ++ bus.number = 0; ++ sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp); ++ if (irq < 16) { // for linux int routing ++ tmp |= (1 << (irq + 16 + 6)); ++ } ++ else { ++ tmp |= (1 << irq); ++ } ++ sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp); ++} ++ ++/* Get PCI interrupt source */ ++int sl2312_pci_get_int_src(void) ++{ ++ struct pci_bus bus; ++ unsigned int tmp=0; ++ ++ bus.number = 0; ++ sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp); ++ if (tmp & (1 << 28)) { // PCI INTA ++ sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp); ++ return IRQ_PCI_INTA; ++ } ++ if (tmp & (1 << 29)) { // PCI INTB ++ sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp); ++ return IRQ_PCI_INTB; ++ } ++ if (tmp & (1 << 30)) { // PCI INTC ++ sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp); ++ return IRQ_PCI_INTC; ++ } ++ if (tmp & (1 << 31)) { // PCI INTD ++ sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp); ++ return IRQ_PCI_INTD; ++ } ++ // otherwise, it should be a PCI error ++ return IRQ_PCI; ++} ++ ++static irqreturn_t sl2312_pci_irq(int irq, void *devid) ++{ ++ struct irq_desc *desc; ++ struct irqaction *action; ++ int retval = 0; ++ ++ return 1; ++ ++ irq = sl2312_pci_get_int_src(); ++ desc = &irq_desc[irq]; ++ action = desc->action; ++ do { ++ retval |= action->handler(irq, devid); ++ action = action->next; ++ } while (action); ++ ++ return 1; ++} ++ ++//extern int (*external_fault)(unsigned long addr, struct pt_regs *regs); ++ ++void __init sl2312_pci_preinit(void) ++{ ++ struct pci_bus bus; ++ unsigned long flags; ++ unsigned int temp; ++ int ret; ++ ++ /* ++ * Hook in our fault handler for PCI errors ++ */ ++// external_fault = sl2312_pci_fault; ++ ++ spin_lock_irqsave(&sl2312_pci_lock, flags); ++ ++ /* ++ * Grab the PCI interrupt. ++ */ ++ ret = request_irq(IRQ_PCI, sl2312_pci_irq, 0, "sl2312 pci int", NULL); ++ if (ret) ++ printk(KERN_ERR "PCI: unable to grab PCI error " ++ "interrupt: %d\n", ret); ++ ++ spin_unlock_irqrestore(&sl2312_pci_lock, flags); ++ ++ // setup pci bridge ++ bus.number = 0; /* device 0, function 0 */ ++ temp = (SL2312_PCI_DMA_MEM1_BASE & 0xfff00000) | (SL2312_PCI_DMA_MEM1_SIZE << 16); ++ sl2312_write_config(&bus, 0, SL2312_PCI_MEM1_BASE_SIZE, 4, temp); ++} ++ ++/* ++ * No swizzle on SL2312 ++ */ ++static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp) ++{ ++ return PCI_SLOT(dev->devfn); ++} ++ ++/* ++ * map the specified device/slot/pin to an IRQ. This works out such ++ * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1. ++ */ ++static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ int intnr = ((slot + (pin - 1)) & 3) + 4; /* the IRQ number of PCI bridge */ ++ ++ // printk("%s : slot = %d pin = %d \n",__func__,slot,pin); ++ switch (slot) ++ { ++ case 12: ++ if (pin==1) ++ { ++ intnr = 3; ++ } ++ else ++ { ++ intnr = 0; ++ } ++ break; ++ case 11: ++ intnr = (2 + (pin - 1)) & 3; ++ break; ++ case 10: ++ intnr = (1 + (pin - 1)) & 3; ++ break; ++ case 9: ++ intnr = (pin - 1) & 3; ++ break; ++ } ++// if (slot == 10) ++// intnr = (1 + (pin - 1)) & 3; ++// else if (slot == 9) ++// intnr = (pin - 1) & 3; ++ return (IRQ_PCI_INTA + intnr); ++} ++ ++struct pci_bus * __init sl2312_pci_scan_bus(int nr, struct pci_sys_data *sysdata) ++{ ++ return (pci_scan_bus(0, &sl2312_pci_ops, sysdata)); ++ ++} ++ ++int __init sl2312_pci_setup(int nr, struct pci_sys_data *sys) ++{ ++ int ret = 0; ++ ++ if (nr == 0) { ++ ret = sl2312_pci_setup_resources(sys->resource); ++ } ++ ++ return ret; ++} ++ ++ ++struct hw_pci sl2312_pci __initdata = { ++ .setup = sl2312_pci_setup, ++ .preinit = sl2312_pci_preinit, ++ .nr_controllers = 1, ++ .swizzle = sl2312_pci_swizzle, ++ .map_irq = sl2312_pci_map_irq, ++ .scan = sl2312_pci_scan_bus, ++}; ++ ++static int __init sl2312_pci_init(void) ++{ ++ if (machine_is_sl2312()) ++ pci_common_init(&sl2312_pci); ++ return 0; ++} ++ ++subsys_initcall(sl2312_pci_init); +--- /dev/null ++++ b/arch/arm/mach-sl2312/sl2312-otg-1.c +@@ -0,0 +1,64 @@ ++/* ++ * linux/arch/arm/mach-pxa/sl2312.c ++ * ++ * Author: Nicolas Pitre ++ * Created: Nov 05, 2002 ++ * Copyright: MontaVista Software Inc. ++ * ++ * Code specific to sl2312 aka Bulverde. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/pm.h> ++#include <linux/device.h> ++#include "asm/arch/sl2312.h" ++#include "asm/arch/irqs.h" ++#include <asm/hardware.h> ++#include <asm/irq.h> ++#include <linux/platform_device.h> ++ ++/* ++ * device registration specific to sl2312. ++ */ ++ ++static u64 sl2312_dmamask_1 = 0xffffffffUL; ++ ++static struct resource sl2312_otg_resources_1[] = { ++ [0] = { ++ .start = 0x69000000, ++ .end = 0x69000fff, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_USB1, ++ .end = IRQ_USB1, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device ehci_1_device = { ++ .name = "ehci-hcd-FOTG2XX", ++ .id = -1, ++ .dev = { ++ .dma_mask = &sl2312_dmamask_1, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .num_resources = ARRAY_SIZE(sl2312_otg_resources_1), ++ .resource = sl2312_otg_resources_1, ++}; ++ ++static struct platform_device *devices[] __initdata = { ++ &ehci_1_device, ++}; ++ ++static int __init sl2312_1_init(void) ++{ ++ return platform_add_devices(devices, ARRAY_SIZE(devices)); ++} ++ ++subsys_initcall(sl2312_1_init); +--- /dev/null ++++ b/arch/arm/mach-sl2312/sl2312-otg.c +@@ -0,0 +1,87 @@ ++/* ++ * linux/arch/arm/mach-pxa/sl2312.c ++ * ++ * Author: Nicolas Pitre ++ * Created: Nov 05, 2002 ++ * Copyright: MontaVista Software Inc. ++ * ++ * Code specific to sl2312 aka Bulverde. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/pm.h> ++#include <linux/device.h> ++#include "asm/arch/sl2312.h" ++#include "asm/arch/irqs.h" ++#include <asm/hardware.h> ++#include <asm/irq.h> ++#include <linux/platform_device.h> ++ ++/* ++ * device registration specific to sl2312. ++ */ ++ ++static u64 sl2312_dmamask = 0xffffffffUL; ++ ++static struct resource sl2312_otg_resources_1[] = { ++ [0] = { ++ .start = 0x68000000, ++ .end = 0x68000fff, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_USB0, ++ .end = IRQ_USB0, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++static struct resource sl2312_otg_resources_2[] = { ++ [2] = { ++ .start = 0x69000000, ++ .end = 0x69000fff, ++ .flags = IORESOURCE_MEM, ++ }, ++ [3] = { ++ .start = IRQ_USB1, ++ .end = IRQ_USB1, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device ehci_device_1 = { ++ .name = "ehci-hcd-FOTG2XX", ++ .id = 1, ++ .dev = { ++ .dma_mask = &sl2312_dmamask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .num_resources = ARRAY_SIZE(sl2312_otg_resources_1), ++ .resource = sl2312_otg_resources_1, ++}; ++ ++static struct platform_device ehci_device_2 = { ++ .name = "ehci-hcd-FOTG2XX", ++ .id = 2, ++ .dev = { ++ .dma_mask = &sl2312_dmamask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .num_resources = ARRAY_SIZE(sl2312_otg_resources_2), ++ .resource = sl2312_otg_resources_2, ++}; ++ ++static struct platform_device *devices[] __initdata = { ++ &ehci_device_1, /* &ehci_device_2, */ ++}; ++ ++static int __init sl2312_init(void) ++{ ++ return platform_add_devices(devices, ARRAY_SIZE(devices)); ++} ++ ++subsys_initcall(sl2312_init); +--- /dev/null ++++ b/arch/arm/mach-sl2312/sl3516_device.c +@@ -0,0 +1,89 @@ ++/* ++ * linux/arch/arm/mach-2312/sl3516_device.c ++ * ++ * Author: Nicolas Pitre ++ * Created: Nov 05, 2002 ++ * Copyright: MontaVista Software Inc. ++ * ++ * Code specific to sl2312 aka Bulverde. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/pm.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include "asm/arch/sl2312.h" ++#include "asm/arch/irqs.h" ++#include <asm/hardware.h> ++#include <asm/irq.h> ++ ++/* ++ * device registration specific to sl2312. ++ */ ++ ++static u64 sl3516_dmamask = 0xffffffffUL; ++ ++static struct resource sl3516_sata_resources[] = { ++ [0] = { ++ .start = 0x63400000, ++ .end = 0x63400040, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_IDE1, ++ .end = IRQ_IDE1, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device sata_device = { ++ .name = "lepus-sata", ++ .id = -1, ++ .dev = { ++ .dma_mask = &sl3516_dmamask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .num_resources = ARRAY_SIZE(sl3516_sata_resources), ++ .resource = sl3516_sata_resources, ++}; ++ ++static struct resource sl3516_sata0_resources[] = { ++ [0] = { ++ .start = 0x63000000, ++ .end = 0x63000040, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_IDE0, ++ .end = IRQ_IDE0, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device sata0_device = { ++ .name = "lepus-sata0", ++ .id = -1, ++ .dev = { ++ .dma_mask = &sl3516_dmamask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .num_resources = ARRAY_SIZE(sl3516_sata0_resources), ++ .resource = sl3516_sata0_resources, ++}; ++ ++static struct platform_device *sata_devices[] __initdata = { ++ &sata_device, ++ &sata0_device, ++}; ++ ++static int __init sl3516_init(void) ++{ ++ return platform_add_devices(sata_devices, ARRAY_SIZE(sata_devices)); ++} ++ ++subsys_initcall(sl3516_init); +--- /dev/null ++++ b/arch/arm/mach-sl2312/time.c +@@ -0,0 +1,134 @@ ++/* ++ * linux/include/asm-arm/arch-epxa10db/time.h ++ * ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++#include <asm/io.h> ++#include <asm/system.h> ++#include <asm/leds.h> ++#include <asm/arch/hardware.h> ++#include <asm/mach/time.h> ++#define TIMER_TYPE (volatile unsigned int*) ++#include <asm/arch/timer.h> ++// #define FIQ_PLUS 1 ++ ++ ++/* ++ * IRQ handler for the timer ++ */ ++static irqreturn_t sl2312_timer_interrupt(int irq, void *dev_id) ++{ ++// unsigned int led; ++ // ...clear the interrupt ++#ifdef FIQ_PLUS ++ *((volatile unsigned int *)FIQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK); ++#else ++ *((volatile unsigned int *)IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK); ++#endif ++ ++#if 0 ++ if(!(jiffies % HZ)) ++ { ++ led = jiffies / HZ; ++// printk("ticks %x \n", led); ++ } ++ do_leds(); ++ do_timer(regs); ++ do_profile(regs); ++#endif ++ timer_tick(); ++ return IRQ_HANDLED; ++} ++ ++static struct irqaction sl2312_timer_irq = { ++ .name = "SL2312 Timer Tick", ++ .flags = IRQF_DISABLED | IRQF_TIMER, ++ .handler = sl2312_timer_interrupt, ++}; ++ ++unsigned long sl2312_gettimeoffset (void) ++{ ++ return 0L; ++} ++ ++/* ++ * Set up timer interrupt, and return the current time in seconds. ++ */ ++void __init sl2312_time_init(void) ++{ ++ // For clock rate adjusting ++ unsigned int tick_rate=0; ++ ++#ifdef CONFIG_SL3516_ASIC ++ unsigned int clock_rate_base = 130000000; ++ unsigned int reg_v=0; ++ ++ //--> Add by jason for clock adjust ++ reg_v = readl(IO_ADDRESS((SL2312_GLOBAL_BASE+GLOBAL_STATUS))); ++ reg_v >>= 15; ++ tick_rate = (clock_rate_base + (reg_v & 0x07)*10000000); ++ ++ // FPGA use AHB bus tick rate ++ printk("Bus: %dMHz",tick_rate/1000000); ++ ++ tick_rate /= 6; // APB bus run AHB*(1/6) ++ ++ switch((reg_v>>3)&3){ ++ case 0: printk("(1/1)\n") ; ++ break; ++ case 1: printk("(3/2)\n") ; ++ break; ++ case 2: printk("(24/13)\n") ; ++ break; ++ case 3: printk("(2/1)\n") ; ++ break; ++ } ++ //<-- ++#else ++ printk("Bus: %dMHz(1/1)\n",CLOCK_TICK_RATE/1000000); // FPGA use 20MHz ++ tick_rate = CLOCK_TICK_RATE; ++#endif ++ ++ ++ /* ++ * Make irqs happen for the system timer ++ */ ++ // initialize timer interrupt ++ // low active and edge trigger ++#ifdef FIQ_PLUS ++ *((volatile unsigned int *)FIQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK); ++ *((volatile unsigned int *)FIQ_LEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK); ++ setup_irq(IRQ_TIMER1, &sl2312_timer_irq); ++ /* Start the timer */ ++ *TIMER_COUNT(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(tick_rate/HZ); ++ *TIMER_LOAD(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(tick_rate/HZ); ++ *TIMER_CR(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(TIMER_1_CR_ENABLE_MSK|TIMER_1_CR_INT_MSK); ++#else ++ *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK); ++ *((volatile unsigned int *)IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK); ++ setup_irq(IRQ_TIMER2, &sl2312_timer_irq); ++ /* Start the timer */ ++ *TIMER_COUNT(IO_ADDRESS(SL2312_TIMER2_BASE))=(unsigned int)(tick_rate/HZ); ++ *TIMER_LOAD(IO_ADDRESS(SL2312_TIMER2_BASE))=(unsigned int)(tick_rate/HZ); ++ *TIMER_CR(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(TIMER_2_CR_ENABLE_MSK|TIMER_2_CR_INT_MSK); ++#endif ++ ++} ++ ++ +--- /dev/null ++++ b/arch/arm/mach-sl2312/xor.c +@@ -0,0 +1,1200 @@ ++/* ++ * arch/arm/mach-sl2312/xor.c ++ * ++ * Support functions for the Gemini Soc. This is ++ * a HW XOR unit that is specifically designed for use with RAID5 ++ * applications. This driver provides an interface that is used by ++ * the Linux RAID stack. ++ * ++ * Original Author: Jason Lee<jason@storlink.com.tw> ++ * ++ * Contributors:Sanders<sanders@storlink.com.tw> ++ Jason Lee<jason@storlink.com.tw> ++ * ++ * ++ * Maintainer: Jason Lee<jason@storlink.com.tw> ++ * ++ * Copyright (C) 2005 Storlink Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ++ * History: (06/25/2005, DJ) Initial Creation ++ * ++ * Versing 1.0.0 Initial version ++ */ ++ ++#include <linux/types.h> ++#include <linux/init.h> ++#include <linux/sched.h> ++#include <linux/spinlock.h> ++#include <linux/slab.h> ++#include <linux/errno.h> ++#include <linux/interrupt.h> ++#include <linux/sched.h> ++#include <linux/wait.h> ++#include <linux/list.h> ++#include <linux/pci.h> ++#include <linux/delay.h> ++#include <linux/dma-mapping.h> ++#include <linux/mm.h> ++#include <asm/irq.h> ++#include <asm/delay.h> ++#include <asm/uaccess.h> ++#include <asm/cacheflush.h> ++#include <asm/hardware.h> ++#include <asm/arch/xor.h> ++#include <asm/pci.h> ++#include <linux/version.h> ++ ++/* ++ * pick up local definitions ++ */ ++#define XOR_SW_FILL_IN ++#include "hw_xor.h" ++ ++ ++//#define XOR_DEBUG ++//#define XOR_TEST 1 ++#ifdef XOR_TEST ++#define TEST_ITERATION 1000 ++#define SPIN_WAIT 1 ++#endif ++#ifdef XOR_DEBUG ++#define DPRINTK(s, args...) printk("Gemini XOR: " s "\n", ## args) ++#define DENTER() DPRINTK("Entered...\n"); ++#define DEXIT() DPRINTK("Exited...\n"); ++#else ++#define DPRINTK(s, args...) ++#define DENTER() ++#define DEXIT() ++#endif ++ ++//#define SPIN_WAIT ++ ++/* globals */ ++static RAID_T tp; ++static RAID_TXDMA_CTRL_T txdma_ctrl; ++RAID_RXDMA_CTRL_T rxdma_ctrl; ++ ++//#ifndef SPIN_WAIT ++static spinlock_t raid_lock; ++//#endif ++ ++static unsigned int tx_desc_virtual_base; ++static unsigned int rx_desc_virtual_base; ++RAID_DESCRIPTOR_T *tx_desc_ptr; ++RAID_DESCRIPTOR_T *rx_desc_ptr; ++ ++/* static prototypes */ ++#define DMA_MALLOC(size,handle) pci_alloc_consistent(NULL,size,handle) ++#define DMA_MFREE(mem,size,handle) pci_free_consistent(NULL,size,mem,handle) ++ ++static int gemini_xor_init_desc(void); ++ ++static unsigned int raid_read_reg(unsigned int offset) ++{ ++ unsigned int reg_val; ++ ++ reg_val = readl(RAID_BASE_ADDR + offset); ++ return (reg_val); ++} ++ ++static void raid_write_reg(unsigned int offset,unsigned int data,unsigned int bit_mask) ++{ ++ unsigned int reg_val; ++ unsigned int *addr; ++ ++ reg_val = ( raid_read_reg(offset) & (~bit_mask) ) | (data & bit_mask); ++ addr = (unsigned int *)(RAID_BASE_ADDR + offset); ++ writel(reg_val,addr); ++ return; ++} ++ ++#ifndef SPIN_WAIT ++__inline__ void xor_queue_descriptor(void) ++{ ++ unsigned int flags,status=1; ++ ++ DPRINTK("Going to sleep"); ++ ++ while(status){ ++ yield(); ++ //schedule(); ++ spin_lock_irqsave(&raid_lock,flags); ++ status = tp.busy; ++ spin_unlock_irqrestore(&raid_lock, flags); ++ } ++// tp.status = COMPLETE; ++ DPRINTK("woken up!"); ++ ++} ++#endif ++ ++#ifdef SPIN_WAIT ++static void gemini_xor_isr(int d_n) ++#else ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28) ++static void gemini_xor_isr(int irq, void *dev_id, struct pt_regs *regs) ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++static irqreturn_t gemini_xor_isr(int irq, void *dev_instance, struct pt_regs *regs) ++#endif ++#endif ++{ ++ ++ unsigned int err; ++ RAID_DMA_STATUS_T dma_status; ++// RAID_DESCRIPTOR_T *rdesc,*tdesc; ++// unsigned int *paddr; ++ ++ dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS); ++#ifdef SPIN_WAIT ++ while( (dma_status.bits32& (1<<31) ) ==0 ){ ++ udelay(1); ++ dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS); ++ } ++ ++/* tdesc = tp.tx_first_desc; ++ rdesc = tp.rx_first_desc; ++ for(d_n;d_n>0;d_n--){ ++ if( tdesc->func_ctrl.bits.own == DMA ){ ++ paddr = tdesc; ++ printk("error tx desc:0x%x\n",*paddr++); ++ printk("error tx desc:0x%x\n",*paddr++); ++ printk("error tx desc:0s%x\n",*paddr++); ++ printk("error tx desc:0x%x\n",*paddr); ++ while(1); ++ } ++ tdesc = (RAID_DESCRIPTOR_T *)((tdesc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ } ++ ++ if( rdesc->func_ctrl.bits.own == DMA ){ ++ paddr = rdesc; ++ printk("error rx desc:0x%x\n",*paddr++); ++ printk("error rx desc:0x%x\n",*paddr++); ++ printk("error rx desc:0s%x\n",*paddr++); ++ printk("error rx desc:0x%x\n",*paddr); ++ while(1); ++ } ++*/ ++#endif ++ ++ if(dma_status.bits32 & ((1<<31)|(1<<26))){ ++ // if no bug , we can turn off rx finish interrupt ++ dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS); ++ err = raid_read_reg(RAID_DMA_DEVICE_ID); ++ tp.busy = 0; ++ ++ if(err&0x00FF0000){ ++ tp.status = ERROR; ++ printk("XOR:<HW>%s error code %x\n",(err&0x00F00000)?"tx":"rx",err); ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28) ++ return ; ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++#ifndef SPIN_WAIT ++ return IRQ_RETVAL(IRQ_HANDLED); ++#endif ++#endif ++ } ++ // 16~19 rx error code ++ // 20~23 tx error codd ++ ++ dma_status.bits.tsFinishI = 1; ++ dma_status.bits.rsFinishI = 1; ++ raid_write_reg(RAID_DMA_STATUS, dma_status.bits32,0x84000000); // clear INT ++ ++// printk("xor %d\n",d_n); ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28) ++ return ; ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++#ifndef SPIN_WAIT ++ return IRQ_RETVAL(IRQ_HANDLED); ++#endif ++#endif ++ } ++ ++ #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28) ++ return ; ++ #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++ #ifndef SPIN_WAIT ++ printk("XOR: DMA status register(0x%8x)\n",dma_status.bits32); ++ return IRQ_RETVAL(IRQ_HANDLED); ++ #endif ++ #endif ++} ++ ++void ++xor_gemini_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) ++{ ++ int status=0; ++ unsigned int flags; ++ ++ if(bytes > (1<<(SRAM_PAR_SIZE+11))){ ++ printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes); ++ } ++ ++ spin_lock_irqsave(&raid_lock,flags); ++ while(tp.status != COMPLETE){ ++ spin_unlock_irqrestore(&raid_lock, flags); ++ //printk("XOR yield2\n"); ++#ifdef XOR_SW_FILL_IN ++ xor_arm4regs_2(bytes,p1,p2); ++ return ; ++#else ++ yield(); ++#endif ++ } ++ spin_unlock_irqrestore(&raid_lock, flags); ++ tp.status = RUNNING; ++ ++ // flush the cache to memory before H/W XOR touches them ++ consistent_sync(p1, bytes, DMA_BIDIRECTIONAL); ++ consistent_sync(p2, bytes, DMA_TO_DEVICE); ++ ++ ++ tp.tx_desc = tp.tx_first_desc; ++ tp.rx_desc = tp.rx_first_desc; ++ if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){ ++ // prepare tx descript ++ raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff); ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00020000; ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ wmb(); ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p2); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00010000; ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); // keep last descript ++ ++ wmb(); ++ // prepare rx descript ++ raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFf); ++ tp.rx_desc->buf_addr = (unsigned int)__pa(p1); ++ tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++ tp.rx_desc->flg_status.bits32 = 0; // link data from XOR ++// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ ++ } ++ else{ ++ /* no free tx descriptor */ ++ printk("XOR:no free tx descript"); ++ return ; ++ } ++ ++ // change status ++// tp.status = RUNNING; ++ status = tp.busy = 1; ++ ++ // start tx DMA ++ rxdma_ctrl.bits.rd_start = 1; ++ // start rx DMA ++ txdma_ctrl.bits.td_start = 1; ++ ++ raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000); ++ raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000); ++ ++#ifdef SPIN_WAIT ++ gemini_xor_isr(2); ++#else ++ xor_queue_descriptor(); ++#endif ++ ++ tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*2) ; ++ tp.status = COMPLETE; ++// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ; ++// tp.rx_desc = tp.rx_first_desc ; ++// tp.rx_desc->func_ctrl.bits.own = DMA; ++ ++} ++ ++void ++xor_gemini_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3) ++{ ++ int status=0; ++ unsigned int flags; ++ ++ if(bytes > (1<<(SRAM_PAR_SIZE+11))){ ++ printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes); ++ } ++ ++ spin_lock_irqsave(&raid_lock,flags); ++ if(tp.status != COMPLETE){ ++ spin_unlock_irqrestore(&raid_lock, flags); ++ //printk("XOR yield3\n"); ++#ifdef XOR_SW_FILL_IN ++ xor_arm4regs_3(bytes,p1,p2,p3); ++ return; ++#else ++ yield(); ++#endif ++ } ++ spin_unlock_irqrestore(&raid_lock, flags); ++ tp.status = RUNNING; ++ ++ // flush the cache to memory before H/W XOR touches them ++ consistent_sync(p1, bytes, DMA_BIDIRECTIONAL); ++ consistent_sync(p2, bytes, DMA_TO_DEVICE); ++ consistent_sync(p3, bytes, DMA_TO_DEVICE); ++ ++ tp.tx_desc = tp.tx_first_desc; ++ tp.rx_desc = tp.rx_first_desc; ++ if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){ ++ // prepare tx descript ++ raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff); ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00020000; ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p2); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x0000000; ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p3); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00010000; ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); // keep last descript ++ ++ // prepare rx descript ++ raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFf); ++ tp.rx_desc->buf_addr = (unsigned int)__pa(p1); ++ tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++ tp.rx_desc->flg_status.bits32 = 0; // link data from XOR ++// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ ++ } ++ else{ ++ /* no free tx descriptor */ ++ printk("XOR:no free tx descript \n"); ++ return ; ++ } ++ ++ // change status ++// tp.status = RUNNING; ++ status = tp.busy = 1; ++ ++ // start tx DMA ++ rxdma_ctrl.bits.rd_start = 1; ++ // start rx DMA ++ txdma_ctrl.bits.td_start = 1; ++ wmb(); ++ raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000); ++ raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000); ++ ++#ifdef SPIN_WAIT ++ gemini_xor_isr(3); ++#else ++ xor_queue_descriptor(); ++#endif ++ tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*3) | 0x0B; ++ tp.status = COMPLETE; ++// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B; ++ //tp.rx_desc = tp.rx_first_desc ; ++// tp.rx_desc->func_ctrl.bits.own = DMA; ++ ++} ++ ++void ++xor_gemini_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3, unsigned long *p4) ++{ ++ int status=0; ++ unsigned int flags; ++ ++ if(bytes > (1<<(SRAM_PAR_SIZE+11))){ ++ printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes); ++ } ++ ++ spin_lock_irqsave(&raid_lock,flags); ++ if(tp.status != COMPLETE){ ++ spin_unlock_irqrestore(&raid_lock, flags); ++ //printk("S\n"); ++#ifdef XOR_SW_FILL_IN ++ xor_arm4regs_4(bytes,p1,p2,p3,p4); ++ return; ++#else ++ msleep(1); ++ yield(); ++#endif ++ } ++ spin_unlock_irqrestore(&raid_lock, flags); ++ ++ tp.status = RUNNING; ++ ++ // flush the cache to memory before H/W XOR touches them ++ consistent_sync(p1, bytes, DMA_BIDIRECTIONAL); ++ consistent_sync(p2, bytes, DMA_TO_DEVICE); ++ consistent_sync(p3, bytes, DMA_TO_DEVICE); ++ consistent_sync(p4, bytes, DMA_TO_DEVICE); ++ ++ tp.tx_desc = tp.tx_first_desc; ++ tp.rx_desc = tp.rx_first_desc; ++ if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){ ++ // prepare tx descript ++ raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff); ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00020000; ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_cur_desc->buf_addr = (unsigned int)__pa(p2); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00000000; ++ tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p3); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00000000; ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ ++ ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p4); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00010000; ++// tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); // keep last descript ++ ++ // prepare rx descript ++ raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF); ++ tp.rx_desc->buf_addr = (unsigned int)__pa(p1); ++ tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++ tp.rx_desc->flg_status.bits32 = 0; // link data from XOR ++// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ ++ } ++ else{ ++ /* no free tx descriptor */ ++ printk("XOR:no free tx descript"); ++ return ; ++ } ++ ++ // change status ++// tp.status = RUNNING; ++ status = tp.busy = 1; ++ ++ // start tx DMA ++ rxdma_ctrl.bits.rd_start = 1; ++ // start rx DMA ++ txdma_ctrl.bits.td_start = 1; ++ wmb(); ++ raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000); ++ raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000); ++ ++#ifdef SPIN_WAIT ++ gemini_xor_isr(4); ++#else ++ xor_queue_descriptor(); ++#endif ++ ++ tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*4) | 0x0B; ++ tp.status = COMPLETE; ++// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B; ++ //tp.rx_desc = tp.rx_first_desc ; ++// tp.rx_desc->func_ctrl.bits.own = DMA; ++ ++} ++ ++void ++xor_gemini_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3, unsigned long *p4, unsigned long *p5) ++{ ++ ++ int status=0; ++ unsigned int flags; ++ ++ ++ if(bytes > (1<<(SRAM_PAR_SIZE+11))){ ++ printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes); ++ } ++ ++ spin_lock_irqsave(&raid_lock,flags); ++ while(tp.status != COMPLETE){ ++ spin_unlock_irqrestore(&raid_lock, flags); ++ //printk("XOR yield5\n"); ++#ifdef XOR_SW_FILL_IN ++ xor_arm4regs_5(bytes,p1,p2,p3,p4,p5); ++ return; ++#else ++ msleep(1); ++ yield(); ++#endif ++ } ++ spin_unlock_irqrestore(&raid_lock, flags); ++ tp.status = RUNNING; ++ ++ // flush the cache to memory before H/W XOR touches them ++ consistent_sync(p1, bytes, DMA_BIDIRECTIONAL); ++ consistent_sync(p2, bytes, DMA_TO_DEVICE); ++ consistent_sync(p3, bytes, DMA_TO_DEVICE); ++ consistent_sync(p4, bytes, DMA_TO_DEVICE); ++ consistent_sync(p5, bytes, DMA_TO_DEVICE); ++ ++ tp.tx_desc = tp.tx_first_desc; ++ tp.rx_desc = tp.rx_first_desc; ++ if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){ ++ // prepare tx descript ++ raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff); ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00020000; ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ wmb(); ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p2); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00000000; ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ wmb(); ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p3); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00000000; ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ wmb(); ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p4); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++ tp.tx_desc->flg_status.bits32 = 0x00000000; ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ wmb(); ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ ++ ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p5); // pysical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript ++// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command ++// tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->flg_status.bits32 = 0x00010000; ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); ++ tp.tx_finished_desc = tp.tx_desc; // keep last descript ++ ++ // prepare rx descript ++ raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF); ++ tp.rx_desc->buf_addr = (unsigned int)__pa(p1); ++ tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++ tp.rx_desc->flg_status.bits32 = 0; // link data from XOR ++// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ ++ } ++ else{ ++ /* no free tx descriptor */ ++ printk("XOR:no free tx descript"); ++ return ; ++ } ++ ++ // change status ++// tp.status = RUNNING; ++ status = tp.busy = 1; ++ ++ // start tx DMA ++ rxdma_ctrl.bits.rd_start = 1; ++ // start rx DMA ++ txdma_ctrl.bits.td_start = 1; ++ wmb(); ++ raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000); ++ raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000); ++ ++#ifdef SPIN_WAIT ++ gemini_xor_isr(5); ++#else ++ xor_queue_descriptor(); ++#endif ++ ++ tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*5) | 0x0B; ++ tp.status = COMPLETE; ++// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B; ++ //tp.rx_desc = tp.rx_first_desc ; ++// tp.rx_desc->func_ctrl.bits.own = DMA; ++ ++} ++ ++#ifdef XOR_TEST ++void ++raid_memset(unsigned int *p1, unsigned int pattern, unsigned int bytes) ++{ ++ int status=0,i; ++ ++ if(bytes > (1<<(SRAM_PAR_SIZE+11))){ ++ printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes); ++ } ++ ++ *p1 = pattern; ++ ++ // flush the cache to memory before H/W XOR touches them ++ consistent_sync(p1, bytes, DMA_BIDIRECTIONAL); ++ ++ while(tp.status != COMPLETE){ ++ DPRINTK("XOR yield\n"); ++ //schedule(); ++ yield(); ++ } ++ tp.status = RUNNING; ++ ++ tp.tx_desc = tp.tx_first_desc; ++ tp.rx_desc = tp.rx_first_desc; ++ if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){ ++ // prepare tx descript ++ raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xFFFFFFFF); ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = 4; /* total frame byte count */ ++ tp.tx_desc->flg_status.bits_cmd_status.bcc = bytes; // bytes to fill ++ tp.tx_desc->flg_status.bits_cmd_status.mode = CMD_FILL; // only support memory FILL command ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_desc->next_desc_addr.bits32 = 0x0000000b; ++// tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xFFFFFFF0)+tx_desc_virtual_base); ++ ++ // prepare rx descript ++ raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF); ++ tp.rx_desc->buf_addr = (unsigned int)__pa(p1); ++ tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++ tp.rx_desc->flg_status.bits32 = 0; // link data from XOR ++ tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++// tp.rx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.rx_cur_desc->next_desc_addr.bits32 & 0xfffffff0)+rx_desc_virtual_base); ++ tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ tp.rx_finished_desc = tp.rx_desc; ++ ++ } ++ else{ ++ /* no free tx descriptor */ ++ printk("XOR:no free tx descript"); ++ return ; ++ } ++ ++ // change status ++ //tp.status = RUNNING; ++ status = tp.busy = 1; ++ ++ // start tx DMA ++ rxdma_ctrl.bits.rd_start = 1; ++ // start rx DMA ++ txdma_ctrl.bits.td_start = 1; ++ ++ raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000); ++ raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000); ++ ++#ifdef SPIN_WAIT ++ gemini_xor_isr(2); ++#else ++ xor_queue_descriptor(); ++#endif ++ ++ for(i=1; i<(bytes/sizeof(int)); i++) { ++ if(p1[0]!=p1[i]){ ++ printk("pattern set error!\n"); ++ while(1); ++ } ++ } ++ ++ tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ; ++ tp.status = COMPLETE; ++// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ; ++ //tp.rx_desc = tp.rx_first_desc ; ++// tp.rx_desc->func_ctrl.bits.own = DMA; ++ ++} ++#endif ++ ++void ++raid_memcpy(unsigned int *to, unsigned int *from, unsigned int bytes) ++{ ++ int status=0,i; ++ ++ if(bytes > (1<<(SRAM_PAR_SIZE+11))){ ++ printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes); ++ } ++ ++ // flush the cache to memory before H/W XOR touches them ++ consistent_sync(to, bytes, DMA_BIDIRECTIONAL); ++ consistent_sync(from,bytes, DMA_TO_DEVICE); ++ ++ while(tp.status != COMPLETE){ ++ DPRINTK("XOR yield\n"); ++ //schedule(); ++ yield(); ++ } ++ tp.status = RUNNING; ++ ++ tp.tx_desc = tp.tx_first_desc; ++ tp.rx_desc = tp.rx_first_desc; ++ if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){ ++ // prepare tx descript ++ raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xFFFFFFFF); ++ tp.tx_desc->buf_addr = (unsigned int)__pa(from); // physical address ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++ tp.tx_desc->flg_status.bits32 = CMD_CPY; // only support memory FILL command ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_desc->next_desc_addr.bits32 = 0x0000000b; ++// tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xFFFFFFF0)+tx_desc_virtual_base); ++ ++ // prepare rx descript ++ raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF); ++ tp.rx_desc->buf_addr = (unsigned int)__pa(to); ++ tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */ ++ tp.rx_desc->flg_status.bits32 = 0; // link data from XOR ++ tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++// tp.rx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.rx_cur_desc->next_desc_addr.bits32 & 0xfffffff0)+rx_desc_virtual_base); ++ tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript ++ ++ } ++ else{ ++ /* no free tx descriptor */ ++ printk("XOR:no free tx descript"); ++ return ; ++ } ++ ++ // change status ++ //tp.status = RUNNING; ++ status = tp.busy = 1; ++ ++ // start tx DMA ++ rxdma_ctrl.bits.rd_start = 1; ++ // start rx DMA ++ txdma_ctrl.bits.td_start = 1; ++ ++ raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000); ++ raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000); ++ ++#ifdef SPIN_WAIT ++ gemini_xor_isr(2); ++#else ++ xor_queue_descriptor(); ++#endif ++ ++#ifdef XOR_TEST ++ for(i=1; i<(bytes/sizeof(int)); i++) { ++ if(to[i]!=from[i]){ ++ printk("pattern check error!\n"); ++ printk("offset=0x%x p1=%x p2=%x\n",i*4,to[i],from[i]); ++ while(1); ++ } ++ } ++#endif ++ ++ tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ; ++ tp.status = COMPLETE; ++// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ; ++ //tp.rx_desc = tp.rx_first_desc ; ++// tp.rx_desc->func_ctrl.bits.own = DMA; ++ ++} ++EXPORT_SYMBOL(raid_memcpy); ++ ++#ifdef XOR_TEST ++int ++raid_memchk(unsigned int *p1, unsigned int pattern, unsigned int bytes) ++{ ++ int status=0; ++ RAID_DMA_STATUS_T dma_status; ++ ++ if(bytes > (1<<(SRAM_PAR_SIZE+11))){ ++ printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes); ++ } ++ ++ status = ((pattern&0xFFFF)%bytes )/4; ++ p1[status] = pattern; ++ ++ while(tp.status != COMPLETE){ ++ DPRINTK("XOR yield\n"); ++ //schedule(); ++ yield(); ++ } ++ tp.status = RUNNING; ++ ++ // flush the cache to memory before H/W XOR touches them ++ consistent_sync(p1, bytes, DMA_BIDIRECTIONAL); ++ ++ tp.tx_desc = tp.tx_first_desc; ++ if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){ ++ // prepare tx descript ++ raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xFFFFFFFF); ++ tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address ++ tp.tx_desc->func_ctrl.bits.raid_ctrl_status = 0; ++ tp.tx_desc->func_ctrl.bits.buffer_size = bytes ; /* total frame byte count */ ++ tp.tx_desc->flg_status.bits32 = CMD_CHK; // only support memory FILL command ++ tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/ ++ tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */ ++ tp.tx_desc->next_desc_addr.bits32 = 0x0000000b; ++// tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xFFFFFFF0)+tx_desc_virtual_base); ++ ++ } ++ else{ ++ /* no free tx descriptor */ ++ printk("XOR:no free tx descript"); ++ return -1; ++ } ++ ++ // change status ++ //tp.status = RUNNING; ++ status = tp.busy = 1; ++ ++ // start tx DMA ++ txdma_ctrl.bits.td_start = 1; ++ ++ raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000); ++// raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000); ++ ++#ifdef SPIN_WAIT ++ gemini_xor_isr(2); ++#else ++ xor_queue_descriptor(); ++#endif ++ ++// dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS); ++// if (dma_status.bits32 & (1<<15)) { ++ ++ if((tp.tx_first_desc->func_ctrl.bits.raid_ctrl_status & 0x2)) { ++ status = 1; ++// raid_write_reg(RAID_DMA_STATUS,0x00008000,0x00080000); ++ } ++ else{ ++ status = 0; ++ } ++ ++ tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ; ++ tp.status = COMPLETE; ++// tp.rx_desc->func_ctrl.bits.own = DMA; ++ return status ; ++} ++#endif ++ ++int __init gemini_xor_init(void) ++{ ++ unsigned int res; ++ unsigned int *paddr1,*paddr2,*paddr3,i; ++ unsigned volatile char *charact; ++ unsigned volatile short *two_char; ++ unsigned volatile int *four_char; ++ ++ // init descript ++ res = gemini_xor_init_desc(); ++ if(res) { ++ printk("Init RAID Descript Fail!!\n"); ++ return -res; ++ } ++ ++ tp.device_name = "Gemini XOR Acceleration"; ++ ++ // request irq ++#ifndef SPIN_WAIT ++ res = request_irq(IRQ_RAID, gemini_xor_isr, SA_INTERRUPT, tp.device_name, NULL); ++#endif ++ if(res){ ++ printk(KERN_ERR "%s: unable to request IRQ %d for " ++ "HW XOR %d\n", tp.device_name, IRQ_RAID, res); ++ return -EBUSY; ++ } ++ ++#ifdef XOR_TEST ++ ++RETEST: ++ paddr1 = kmalloc(0x1000,GFP_KERNEL); ++ paddr2 = kmalloc(0x1000,GFP_KERNEL); ++ paddr3 = kmalloc(0x1000,GFP_KERNEL); ++ for(i=0;i<TEST_ITERATION;i++) { ++ printk("XOR test round %d\n",i); ++ for(res=0;res<(0x1000)/sizeof(int);res++){ // prepare data pattern ++ paddr1[res]= readl(0xf62000ac); ++ paddr2[res]= readl(0xf62000ac); ++ } ++ for(res=0;res<0x1000/sizeof(int);res++){ // calculate xor by software ++ paddr3[res] = paddr1[res]^paddr2[res]; ++ } ++ xor_gemini_2(0x1000,paddr1,paddr2); // calculate xor by hw ++ for(res=0;res<0x1000/sizeof(int);res++){ // check error ++ if(paddr1[res]!=paddr3[res]){ ++ printk("XOR ERROR\n"); ++ printk("[%d][0x%x]=0x%x should be %x\n",res,&paddr1[res],paddr1[res],paddr3[res]); ++ while(1); ++ } ++ } ++ } ++ kfree(paddr1); ++ kfree(paddr2); ++ kfree(paddr3); ++ ++ ++ // memcpy test ++ paddr1 = kmalloc(0x4000,GFP_KERNEL); ++ for(i=0;i<TEST_ITERATION;i++) { ++ for(res=0;res<(0x4000)/sizeof(int);res++) ++ paddr1[res]= readl(0xf62000ac); ++ ++ printk("MEMCOPY round %d\n",i); ++ paddr2 = kmalloc(0x4000,GFP_KERNEL); ++ raid_memcpy(paddr2,paddr1,0x4000); ++ kfree(paddr2); ++ } ++ kfree(paddr1); ++ ++ // memset test ++ for(i=0;i<TEST_ITERATION;i++) { ++ raid_memset(paddr1,0xFFFFFFFF,0x4000); ++ res = readl(0xf62000ac); ++ printk("MEMFILL fill 0x%x round %d\n",res,i); ++ paddr1 = kmalloc(0x4000,GFP_KERNEL); ++ raid_memset(paddr1,res,0x4000); ++ raid_memset(paddr1,0x0,0x4000); ++ kfree(paddr1); ++ } ++ ++ paddr1 = kmalloc(0x4000,GFP_KERNEL); ++ for(i=0;i<TEST_ITERATION;i++){ ++ raid_memset(paddr1, i,0x4000); ++ printk("Pattern check same ? "); ++ res = raid_memchk(paddr1, i,0x4000); ++ printk("%s\n",res?"Fail":"OK"); ++ if(res) while(1); ++ ++ printk("Pattern check diff ? "); ++ res = raid_memchk(paddr1,readl(0xf62000ac),0x4000); ++ printk("%s\n",res?"OK":"Fail"); ++ if(!res) while(1); ++ } ++ kfree(paddr1); ++ ++ // SRAM test ++ raid_write_reg(RAID_PCR, 0,0x00000003); ++ for(i=0;i<TEST_ITERATION;i++) { ++ printk("SRAM test %d\n",i); ++ charact = 0xF7000000; ++ two_char = 0xF7000000; ++ four_char = 0xF7000000; ++ for(res=0;res<(16*1024)/sizeof(char);res++) { // 8-bit access ++ *charact++ = (unsigned char)res; ++ } ++ charact = 0xF7000000; ++ for(res=0;res<(16*1024)/sizeof(char);res++) { ++ if(*charact++ != (unsigned char)res){ ++ printk("SRAM data error(8)\n"); ++ while(1); ++ } ++ } ++ ++ for(res=0;res<(16*1024)/sizeof(short);res++) { // 16-bit access ++ *two_char++ = (unsigned short)res; ++ } ++ two_char = 0xF7000000; ++ for(res=0;res<(16*1024)/sizeof(short);res++) { ++ if(*two_char++ != (unsigned short)res){ ++ printk("SRAM data error(16)\n"); ++ while(1); ++ } ++ } ++ ++ for(res=0;res<(16*1024)/sizeof(int);res++) { // 32-bit access ++ *four_char++ = (unsigned int)res; ++ } ++ four_char = 0xF7000000; ++ for(res=0;res<(16*1024)/sizeof(int);res++) { ++ if(*four_char++ != (unsigned int)res){ ++ printk("SRAM data error(32)\n"); ++ while(1); ++ } ++ } ++ } ++ raid_write_reg(RAID_PCR, SRAM_PAR_SIZE,0x00000003); ++ ++#endif ++ return 0; ++} ++ ++void __exit gemini_xor_exit(void) ++{ ++ DMA_MFREE(tp.tx_desc, TX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(unsigned int)tp.tx_desc_dma); ++ DMA_MFREE(tp.rx_desc, RX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(unsigned int)tp.rx_desc_dma); ++ free_irq(IRQ_RAID, NULL); ++} ++ ++ ++static int gemini_xor_init_desc(void) ++{ ++ unsigned int i; ++ dma_addr_t tx_first_desc_dma; ++ dma_addr_t rx_first_desc_dma; ++ RAID_DMA_STATUS_T dma_status; ++ ++ printk("Initial RAID Descripter...\n"); ++ ++ tp.tx_desc = (RAID_DESCRIPTOR_T*)DMA_MALLOC(TX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(dma_addr_t *)&tp.tx_desc_dma); ++ tx_desc_virtual_base = (unsigned int)tp.tx_desc - (unsigned int)tp.tx_desc_dma; ++ memset(tp.tx_desc,0x00,TX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T)); ++ ++ tp.rx_desc = (RAID_DESCRIPTOR_T*)DMA_MALLOC(RX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(dma_addr_t *)&tp.rx_desc_dma); ++ rx_desc_virtual_base = (unsigned int)tp.rx_desc - (unsigned int)tp.rx_desc_dma; ++ memset(tp.rx_desc,0x00,RX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T)); ++ printk("XOR:tx_desc = %08x\n",(unsigned int)tp.tx_desc); ++ printk("XOR:rx_desc = %08x\n",(unsigned int)tp.rx_desc); ++ printk("XOR:tx_desc_dma = %08x\n",(unsigned int)tp.tx_desc_dma); ++ printk("XOR:rx_desc_dma = %08x\n",(unsigned int)tp.rx_desc_dma); ++ ++ if ((tp.tx_desc == NULL) || (tp.rx_desc == NULL)) { ++ if (tp.tx_desc) ++ DMA_MFREE(tp.tx_desc, TX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(dma_addr_t)tp.tx_desc_dma); ++ if (tp.rx_desc) ++ DMA_MFREE(tp.rx_desc, RX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(dma_addr_t)tp.rx_desc_dma); ++ return -ENOMEM; ++ } ++ ++ tp.tx_cur_desc = tp.tx_desc; /* virtual address */ ++ tp.tx_finished_desc = tp.tx_desc; /* virtual address */ ++ tx_first_desc_dma = (dma_addr_t)tp.tx_desc_dma; /* physical address */ ++ for (i = 1; i < TX_DESC_NUM; i++) { ++ tp.tx_desc->func_ctrl.bits.own = CPU; ++ tp.tx_desc->func_ctrl.bits.buffer_size = 0; ++ tp.tx_desc_dma = tp.tx_desc_dma + sizeof(RAID_DESCRIPTOR_T); ++// tp.tx_desc->next_desc_addr.bits32 = (unsigned int)tp.tx_desc_dma | 0x0B; ++ tp.tx_desc->next_desc_addr.bits32 = ((unsigned int)tx_first_desc_dma | 0x0B) + i*0x10; ++ tp.tx_desc = &tp.tx_desc[1]; ++ } ++ tp.tx_desc->func_ctrl.bits.own = DMA; ++ tp.tx_desc->next_desc_addr.bits32 = (unsigned int)tx_first_desc_dma|0x0b; ++ tp.tx_desc = tp.tx_cur_desc; ++ tp.tx_desc_dma = (unsigned int*)tx_first_desc_dma; ++ tp.tx_first_desc = tp.tx_desc ; ++ ++ tp.rx_cur_desc = tp.rx_desc; /* virtual address */ ++ tp.rx_finished_desc = tp.rx_desc; /* virtual address */ ++ rx_first_desc_dma = (dma_addr_t)tp.rx_desc_dma; /* physical address */ ++ for (i = 1; i < RX_DESC_NUM; i++) { ++ tp.rx_desc->func_ctrl.bits.own = DMA; ++ tp.rx_desc->func_ctrl.bits.buffer_size = 0; ++ tp.rx_desc_dma = tp.rx_desc_dma + sizeof(RAID_DESCRIPTOR_T); ++// tp.rx_desc->next_desc_addr.bits32 = (unsigned int)tp.rx_desc_dma | 0x0B; ++ tp.rx_desc->next_desc_addr.bits32 = ((unsigned int)rx_first_desc_dma | 0x0B) + i*0x10; ++ tp.rx_desc = &tp.rx_desc[1]; ++ } ++ tp.rx_desc->func_ctrl.bits.own = DMA; ++ tp.rx_desc->next_desc_addr.bits32 = rx_first_desc_dma|0x0b; ++ tp.rx_desc = tp.rx_cur_desc; ++ tp.rx_desc_dma = (unsigned int*)rx_first_desc_dma; ++ tp.rx_first_desc = tp.rx_desc ; ++ tp.busy = 0; ++ tp.status = COMPLETE; ++ ++ // Partition SRAM size ++ raid_write_reg(RAID_PCR, SRAM_PAR_SIZE,0x00000003); ++ ++ // config tx DMA controler ++ txdma_ctrl.bits32 = 0; ++ txdma_ctrl.bits.td_start = 0; ++ txdma_ctrl.bits.td_continue = 1; ++ txdma_ctrl.bits.td_chain_mode = 1; ++ txdma_ctrl.bits.td_prot = 0; ++ txdma_ctrl.bits.td_burst_size = 1; ++ txdma_ctrl.bits.td_bus = 3; ++ txdma_ctrl.bits.td_endian = 0; ++ txdma_ctrl.bits.td_finish_en = 1; ++ txdma_ctrl.bits.td_fail_en = 1; ++ txdma_ctrl.bits.td_perr_en = 1; ++ txdma_ctrl.bits.td_eod_en = 0; // enable tx descript ++ txdma_ctrl.bits.td_eof_en = 0; ++ raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0xFFFFFFFF); ++ ++ // config rx DMA controler ++ rxdma_ctrl.bits32 = 0; ++ rxdma_ctrl.bits.rd_start = 0; ++ rxdma_ctrl.bits.rd_continue = 1; ++ rxdma_ctrl.bits.rd_chain_mode = 1; ++ rxdma_ctrl.bits.rd_prot = 0; ++ rxdma_ctrl.bits.rd_burst_size = 1; ++ rxdma_ctrl.bits.rd_bus = 3; ++ rxdma_ctrl.bits.rd_endian = 0; ++ rxdma_ctrl.bits.rd_finish_en = 0; ++ rxdma_ctrl.bits.rd_fail_en = 1; ++ rxdma_ctrl.bits.rd_perr_en = 1; ++ rxdma_ctrl.bits.rd_eod_en = 0; ++ rxdma_ctrl.bits.rd_eof_en = 0; ++ raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0xFFFFFFFF); ++ ++ // enable interrupt ++ dma_status.bits32 = 3; // enable RpInt ++ raid_write_reg(RAID_DMA_STATUS, dma_status.bits32,0xFFFFFFFF); ++ ++ return 0; ++} ++ ++module_init(gemini_xor_init); ++module_exit(gemini_xor_exit); ++ +--- a/arch/arm/mm/Kconfig ++++ b/arch/arm/mm/Kconfig +@@ -187,6 +187,26 @@ + Say Y if you want support for the ARM926T processor. + Otherwise, say N. + ++###### for Storlink SoC ###### ++config CPU_FA526 ++ bool "FA526 processor" ++ depends on ARCH_SL2312 ++ default y ++ select CPU_32v4 ++ select CPU_ABRT_EV4 ++ select CPU_CACHE_FA ++ select CPU_CACHE_VIVT ++ select CPU_CP15_MMU ++ select CPU_COPY_FA ++ select CPU_TLB_FA ++ select CPU_FA_BTB ++ help ++ The FA526 is a version of the ARM9 compatible processor, but with smaller ++ instruction and data caches. It is used in Storlink Sword device family. ++ ++ Say Y if you want support for the FA526 processor. ++ Otherwise, say N. ++ + # ARM940T + config CPU_ARM940T + bool "Support ARM940T processor" if ARCH_INTEGRATOR +@@ -461,6 +481,9 @@ + config CPU_CACHE_VIPT + bool + ++config CPU_CACHE_FA ++ bool ++ + if MMU + # The copy-page model + config CPU_COPY_V3 +@@ -475,6 +498,12 @@ + config CPU_COPY_V6 + bool + ++config CPU_COPY_FA ++ bool ++ ++config CPU_FA_BTB ++ bool ++ + # This selects the TLB model + config CPU_TLB_V3 + bool +@@ -534,6 +563,14 @@ + config IO_36 + bool + ++config CPU_TLB_FA ++ bool ++ help ++ //TODO ++ Faraday ARM FA526 architecture, unified TLB with writeback cache ++ and invalidate instruction cache entry. Branch target buffer is also ++ supported. ++ + comment "Processor Features" + + config ARM_THUMB +@@ -600,7 +637,7 @@ + + config CPU_DCACHE_WRITETHROUGH + bool "Force write through D-cache" +- depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE ++ depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FA526) && !CPU_DCACHE_DISABLE + default y if CPU_ARM925T + help + Say Y here to use the data cache in writethrough mode. Unless you +--- a/arch/arm/mm/Makefile ++++ b/arch/arm/mm/Makefile +@@ -32,6 +32,7 @@ + obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o + obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o + obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o ++obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o + + obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o + obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o +@@ -40,6 +41,7 @@ + obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o + obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o + obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o ++obj-$(CONFIG_CPU_COPY_FA) += copypage-fa.o + + obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o + obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o +@@ -47,6 +49,7 @@ + obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o + obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o + obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o ++obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o + + obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o + obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o +@@ -60,6 +63,7 @@ + obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o + obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o + obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o ++obj-$(CONFIG_CPU_FA526) += proc-fa526.o + obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o + obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o + obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o +--- /dev/null ++++ b/arch/arm/mm/cache-fa.S +@@ -0,0 +1,400 @@ ++/* ++ * linux/arch/arm/mm/cache-fa.S ++ * ++ * Copyright (C) 2005 Faraday Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Processors: FA520 FA526 FA626 ++ * 03/31/2005 : Luke Lee created, modified from cache-v4wb.S ++ * 04/06/2005 : 1. Read CR0-1 and determine the cache size dynamically, ++ * to suit all Faraday CPU series ++ * 2. Fixed all functions ++ * 04/08/2005 : insert CONFIG_CPU_ICACHE_DISABLE and CONFIG_CPU_DCACHE_DISABLE ++ * 04/12/2005 : TODO: make this processor dependent or a self-modifying code to ++ * inline cache len/size info into the instructions, as reading cache ++ * size and len info in memory could cause another cache miss. ++ * 05/05/2005 : Modify fa_flush_user_cache_range to comply APCS. ++ * 05/19/2005 : Adjust for boundary conditions. ++ */ ++#include <linux/linkage.h> ++#include <linux/init.h> ++#include <asm/hardware.h> ++#include <asm/page.h> ++#include "proc-macros.S" ++ ++#define CACHE_DLINESIZE 16 ++#ifdef CONFIG_SL3516_ASIC ++#define CACHE_DSIZE 8192 ++#else ++#define CACHE_DSIZE 16384 ++#endif ++#define CACHE_ILINESIZE 16 ++#define CACHE_ISIZE 16384 ++ ++/* Luke Lee 04/06/2005 ins begin */ ++/* ++ * initialize_cache_info() ++ * ++ * Automatic detection of DSIZE, DLEN, ISIZE, ILEN variables according to ++ * system register CR0-1 ++ * Destroyed register: r0, r1, r2, r3, ip ++ */ ++ .align ++ENTRY(fa_initialize_cache_info) ++ mov r3, #1 @ r3 always = 1 ++ adr ip, __fa_cache_ilen ++ ++ mrc p15, 0, r0, c0, c0, 1 ++ /* ILEN */ ++ and r1, r0, #3 @ bits [1:0] ++ add r1, r1, #3 @ cache line size is at least 8 bytes (2^3) ++ mov r2, r3, lsl r1 @ r2 = 1<<r1 ++ str r2, [ip], #4 ++ /* ISIZE */ ++ mov r1, r0, lsr #6 @ bits [8:6] ++ and r1, r1, #7 ++ add r1, r1, #9 @ cache size is at least 512 bytes (2^9) ++ mov r2, r3, lsl r1 ++ str r2, [ip], #4 ++ /* DLEN */ ++ mov r1, r0, lsr #12 ++ and r1, r1, #3 @ bits [13:12] ++ add r1, r1, #3 @ cache line size is at least 8 bytes (2^3) ++ mov r2, r3, lsl r1 @ r2 = 1<<r1 ++ str r2, [ip], #4 ++ /* DSIZE */ ++ mov r1, r0, lsr #18 @ bits [20:18] ++ and r1, r1, #7 ++ add r1, r1, #9 @ cache size is at least 512 bytes (2^9) ++ mov r2, r3, lsl r1 ++ str r2, [ip] ++ mov pc, lr ++ ++ /* Warning : Do not change the order ! Successive codes depends on this */ ++ .align ++ .globl __fa_cache_ilen, __fa_cache_isize, __fa_cache_dlen, __fa_cache_dsize ++__fa_cache_ilen: ++ .word 0 @ instruction cache line length ++__fa_cache_isize: ++ .word 0 @ instruction cache size ++__fa_cache_dlen: ++ .word 0 @ data cahce line length ++__fa_cache_dsize: ++ .word 0 @ data cache size ++ ++/* Luke Lee 04/06/2005 ins end */ ++ ++/* ++ * flush_user_cache_all() ++ * ++ * Clean and invalidate all cache entries in a particular address ++ * space. ++ */ ++ENTRY(fa_flush_user_cache_all) ++ /* FALLTHROUGH */ ++/* ++ * flush_kern_cache_all() ++ * ++ * Clean and invalidate the entire cache. ++ */ ++ENTRY(fa_flush_kern_cache_all) ++/* Luke Lee 04/06/2005 mod ok */ ++ mov ip, #0 ++ ++#ifndef CONFIG_CPU_ICACHE_DISABLE ++ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache ++#endif ++ ++__flush_whole_cache: ++ ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++ mov ip, #0 ++# ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache ++# else ++ mcr p15, 0, ip, c7,c14, 0 @ clean/invalidate D cache ++# endif ++#endif /*CONFIG_CPU_DCACHE_DISABLE*/ ++ ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ mcr p15, 0, ip, c7, c10, 4 @ drain write buffer ++#endif ++ ++#ifdef CONFIG_CPU_FA_BTB ++ mcr p15, 0, ip, c7, c5, 6 @ invalidate BTB ++ nop ++ nop ++#endif ++ ++/* Luke Lee 04/06/2005 que todo tofix : should iscratchpad and dscratchpad be invalidated ? */ ++ mov pc, lr ++ ++/* ++ * flush_user_cache_range(start, end, flags) ++ * ++ * Invalidate a range of cache entries in the specified ++ * address space. ++ * ++ * - start - start address (inclusive, page aligned) ++ * - end - end address (exclusive, page aligned) ++ * - flags - vma_area_struct flags describing address space ++ */ ++ENTRY(fa_flush_user_cache_range) ++ ++/* Luke Lee 04/06/2005 mod ok */ ++ /* Luke Lee 04/07/2005 ins 1 */ ++ mov ip, #0 ++ sub r3, r1, r0 @ calculate total size ++#ifndef CONFIG_CPU_ICACHE_DISABLE ++ tst r2, #VM_EXEC @ executable region? ++ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache ++#endif ++ ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++ /* Luke Lee 04/06/2005 ins 2 mod 1 */ ++ cmp r3, #CACHE_DSIZE @ total size >= limit? ++ bhs __flush_whole_cache @ flush whole D cache ++ ++ //debug_Aaron ++ bic r0, r0, #CACHE_DLINESIZE-1 ++ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate boundary D entry ++ bic r1, r1, #CACHE_DLINESIZE-1 ++ mcr p15, 0, r1, c7, c14, 1 @ clean and invalidate boundary D entry ++ ++ ++1: /* Luke Lee 04/06/2005 del 2 ins 5 */ ++ ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry ++#else ++ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry ++#endif ++ /* Luke Lee 04/06/2005 mod 1 */ ++ add r0, r0, #CACHE_DLINESIZE ++ cmp r0, r1 ++ bls 1b @ Luke Lee 05/19/2005 ++#endif /* CONFIG_CPU_DCACHE_DISABLE */ ++ ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ tst r2, #VM_EXEC ++ /* Luke Lee 04/06/2005 mod 1 tofix todo : ne->eq */ ++ mcreq p15, 0, r4, c7, c10, 4 @ drain write buffer ++#endif ++ ++ /* Luke Lee 04/06/2005 ins block */ ++#ifdef CONFIG_CPU_FA_BTB ++ tst r2, #VM_EXEC ++ mov ip, #0 ++ mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB ++ nop ++ nop ++#endif ++ mov pc, lr ++ ++/* ++ * flush_kern_dcache_page(void *page) ++ * ++ * Ensure no D cache aliasing occurs, either with itself or ++ * the I cache ++ * ++ * - addr - page aligned address ++ */ ++ENTRY(fa_flush_kern_dcache_page) ++ add r1, r0, #PAGE_SZ ++ /* fall through */ ++ ++/* ++ * coherent_kern_range(start, end) ++ * ++ * Ensure coherency between the Icache and the Dcache in the ++ * region described by start. If you have non-snooping ++ * Harvard caches, you need to implement this function. ++ * ++ * - start - virtual start address ++ * - end - virtual end address ++ */ ++ENTRY(fa_coherent_kern_range) ++ /* fall through */ ++ ++/* ++ * coherent_user_range(start, end) ++ * ++ * Ensure coherency between the Icache and the Dcache in the ++ * region described by start. If you have non-snooping ++ * Harvard caches, you need to implement this function. ++ * ++ * - start - virtual start address ++ * - end - virtual end address ++ */ ++ENTRY(fa_coherent_user_range) ++ ++/* Luke Lee 04/06/2005 mod ok */ ++ /* Luke Lee 04/06/2005 ins 3 mod 1 */ ++ bic r0, r0, #CACHE_DLINESIZE-1 ++ ++ //debug_Aaron ++ bic r0, r0, #CACHE_DLINESIZE-1 ++ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate boundary D entry ++ bic r1, r1, #CACHE_DLINESIZE-1 ++ mcr p15, 0, r1, c7, c14, 1 @ clean and invalidate boundary D entry ++ ++#if !(defined(CONFIG_CPU_DCACHE_DISABLE) && defined(CONFIG_CPU_ICACHE_DISABLE)) ++1: /* Luke Lee 04/06/2005 del 2 ins 5 mod 1 */ ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry ++#else ++ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry ++#endif ++#endif /* CONFIG_CPU_DCACHE_DISABLE */ ++ ++#ifndef CONFIG_CPU_ICACHE_DISABLE ++ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry ++#endif ++ add r0, r0, #CACHE_DLINESIZE ++ cmp r0, r1 ++ bls 1b @ Luke Lee 05/19/2005 blo->bls ++#endif /* !(defined(CONFIG_CPU_DCACHE_DISABLE) && defined(CONFIG_CPU_ICACHE_DISABLE)) */ ++ ++ mov ip, #0 ++#ifdef CONFIG_CPU_FA_BTB ++ mcr p15, 0, ip, c7, c5, 6 @ invalidate BTB ++ nop ++ nop ++#endif ++ ++/* Luke Lee 04/08/2005 ins 1 skp 1 ins 1 */ ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ mcr p15, 0, ip, c7, c10, 4 @ drain WB ++#endif ++ ++ mov pc, lr ++ ++/* ++ * dma_inv_range(start, end) ++ * ++ * Invalidate (discard) the specified virtual address range. ++ * May not write back any entries. If 'start' or 'end' ++ * are not cache line aligned, those lines must be written ++ * back. ++ * ++ * - start - virtual start address ++ * - end - virtual end address ++ */ ++ENTRY(fa_dma_inv_range) ++ ++/* Luke Lee 04/06/2005 mod ok */ ++ ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++ ++ //debug_Aaron ++ bic r0, r0, #CACHE_DLINESIZE-1 ++ mcr p15, 0, r0, c7, c6, 1 @ invalidate boundary D entry ++ bic r1, r1, #CACHE_DLINESIZE-1 ++ mcr p15, 0, r1, c7, c6, 1 @ invalidate boundary D entry ++ ++ /* Luke Lee 04/06/2005 ins 4 mod 2 */ ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ tst r0, #CACHE_DLINESIZE -1 ++ bic r0, r0, #CACHE_DLINESIZE -1 ++ ++//debug_Aaron ++ //mcrne p15, 0, r0, c7, c10, 1 @ clean boundary D entry ++ ++ /* Luke Lee 04/06/2005 mod 1 */ ++ /* Luke Lee 05/19/2005 always clean the end-point boundary mcrne->mcr */ ++ ////tst r1, #CACHE_DLINESIZE -1 ++ //mcr p15, 0, r1, c7, c10, 1 @ clean boundary D entry ++ /* Luke Lee 04/06/2005 ins 1 */ ++#else ++ bic r0, r0, #CACHE_DLINESIZE -1 ++#endif ++ ++//debug_Aaron ++1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry ++//1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry ++ ++ /* Luke Lee 04/06/2005 mod 1 */ ++ add r0, r0, #CACHE_DLINESIZE ++ cmp r0, r1 ++ bls 1b @ Luke Lee 05/19/2005 blo->bls ++#endif /* CONFIG_CPU_DCACHE_DISABLE */ ++ ++ /* Luke Lee 04/06/2005 ins 1 */ ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ mov r0, #0 ++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer ++#endif ++ ++ mov pc, lr ++ ++/* ++ * dma_clean_range(start, end) ++ * ++ * Clean (write back) the specified virtual address range. ++ * ++ * - start - virtual start address ++ * - end - virtual end address ++ */ ++ENTRY(fa_dma_clean_range) ++ ++/* Luke Lee 04/06/2005 mod ok */ ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++ ++ //debug_Aaron ++ bic r0, r0, #CACHE_DLINESIZE-1 ++ mcr p15, 0, r0, c7, c10, 1 @ clean boundary D entry ++ bic r1, r1, #CACHE_DLINESIZE-1 ++ mcr p15, 0, r1, c7, c10, 1 @ clean boundary D entry ++ ++ /* Luke Lee 04/06/2005 ins 4 mod 2 */ ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ bic r0, r0, #CACHE_DLINESIZE - 1 ++ ++//debug_Aaron ++1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry ++//1: mcr p15, 0, r0, c7, c14, 1 @ clean D entry ++ add r0, r0, #CACHE_DLINESIZE ++ cmp r0, r1 ++ bls 1b @ Luke Lee 05/19/2005 blo->bls ++ /* Luke Lee 04/06/2005 ins 2 */ ++#endif ++#endif /* CONFIG_CPU_DCACHE_DISABLE */ ++ ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ mov r0, #0 ++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer ++#endif ++ ++ mov pc, lr ++ ++/* ++ * dma_flush_range(start, end) ++ * ++ * Clean and invalidate the specified virtual address range. ++ * ++ * - start - virtual start address ++ * - end - virtual end address ++ * ++ * This is actually the same as fa_coherent_kern_range() ++ */ ++ .globl fa_dma_flush_range ++ .set fa_dma_flush_range, fa_coherent_kern_range ++ ++ __INITDATA ++ ++ .type fa_cache_fns, #object ++ENTRY(fa_cache_fns) ++ .long fa_flush_kern_cache_all ++ .long fa_flush_user_cache_all ++ .long fa_flush_user_cache_range ++ .long fa_coherent_kern_range ++ .long fa_coherent_user_range ++ .long fa_flush_kern_dcache_page ++ .long fa_dma_inv_range ++ .long fa_dma_clean_range ++ .long fa_dma_flush_range ++ .size fa_cache_fns, . - fa_cache_fns +--- /dev/null ++++ b/arch/arm/mm/copypage-fa.S +@@ -0,0 +1,106 @@ ++/* ++ * linux/arch/arm/lib/copypage-fa.S ++ * ++ * Copyright (C) 2005 Faraday Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ASM optimised string functions ++ * 05/18/2005 : Luke Lee created, modified from copypage-v4wb.S ++ */ ++#include <linux/linkage.h> ++#include <linux/init.h> ++#include <asm/asm-offsets.h> ++ ++ .text ++/* ++ * ARMv4 optimised copy_user_page for Faraday processors ++ * ++ * We flush the destination cache lines just before we write the data into the ++ * corresponding address. Since the Dcache is read-allocate, this removes the ++ * Dcache aliasing issue. The writes will be forwarded to the write buffer, ++ * and merged as appropriate. ++ * ++ * Note: We rely on all ARMv4 processors implementing the "invalidate D line" ++ * instruction. If your processor does not supply this, you have to write your ++ * own copy_user_page that does the right thing. ++ * ++ * copy_user_page(to,from,vaddr) ++ */ ++ .align 4 ++ENTRY(fa_copy_user_page) ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ /* Write through */ ++ stmfd sp!, {r4, lr} @ 2 ++ mov r2, #PAGE_SZ/32 @ 1 ++ ++ ldmia r1!, {r3, r4, ip, lr} @ 4 ++1: stmia r0!, {r3, r4, ip, lr} @ 4 ++ ldmia r1!, {r3, r4, ip, lr} @ 4+1 ++ subs r2, r2, #1 @ 1 ++ stmia r0!, {r3, r4, ip, lr} @ 4 ++ ldmneia r1!, {r3, r4, ip, lr} @ 4 ++ bne 1b @ 1 ++ ++ mcr p15, 0, r2, c7, c7, 0 @ flush ID cache ++ ldmfd sp!, {r4, pc} @ 3 ++#else ++ /* Write back */ ++ stmfd sp!, {r4, lr} @ 2 ++ mov r2, #PAGE_SZ/32 @ 1 ++ ++1: ldmia r1!, {r3, r4, ip, lr} @ 4 ++ mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line ++ stmia r0!, {r3, r4, ip, lr} @ 4 ++ ldmia r1!, {r3, r4, ip, lr} @ 4 ++ mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line ++ stmia r0!, {r3, r4, ip, lr} @ 4 ++ subs r2, r2, #1 @ 1 ++ bne 1b ++ mcr p15, 0, r2, c7, c10, 4 @ 1 drain WB ++ ldmfd sp!, {r4, pc} @ 3 ++#endif ++ ++/* ++ * ARMv4 optimised clear_user_page ++ * ++ * Same story as above. ++ */ ++ .align 4 ++ENTRY(fa_clear_user_page) ++ str lr, [sp, #-4]! ++ mov r1, #PAGE_SZ/32 @ 1 ++ mov r2, #0 @ 1 ++ mov r3, #0 @ 1 ++ mov ip, #0 @ 1 ++ mov lr, #0 @ 1 ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ /* Write through */ ++1: stmia r0!, {r2, r3, ip, lr} @ 4 ++ stmia r0!, {r2, r3, ip, lr} @ 4 ++ subs r1, r1, #1 @ 1 ++ bne 1b @ 1 ++ ++ mcr p15, 0, r1, c7, c7, 0 @ flush ID cache ++ ldr pc, [sp], #4 ++#else ++ /* Write back */ ++1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line ++ stmia r0!, {r2, r3, ip, lr} @ 4 ++ mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line ++ stmia r0!, {r2, r3, ip, lr} @ 4 ++ subs r1, r1, #1 @ 1 ++ bne 1b @ 1 ++ mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB ++ ldr pc, [sp], #4 ++#endif ++ ++ __INITDATA ++ ++ .type fa_user_fns, #object ++ENTRY(fa_user_fns) ++ .long fa_clear_user_page ++ .long fa_copy_user_page ++ .size fa_user_fns, . - fa_user_fns +--- a/arch/arm/mm/init.c ++++ b/arch/arm/mm/init.c +@@ -23,6 +23,7 @@ + + #include <asm/mach/arch.h> + #include <asm/mach/map.h> ++#include <asm/arch/ipi.h> + + #include "mm.h" + +@@ -252,6 +253,11 @@ + initrd_end = initrd_start + phys_initrd_size; + } + #endif ++#ifdef CONFIG_GEMINI_IPI ++ printk("CPU ID:%d\n",getcpuid()); ++// reserve_bootmem_node(NODE_DATA(0), 0x400000, 0x400000); //CPU0 space ++// reserve_bootmem_node(NODE_DATA(0), SHAREADDR, SHARE_MEM_SIZE); //share memory ++#endif + + /* + * Finally, reserve any node zero regions. +--- /dev/null ++++ b/arch/arm/mm/proc-fa526.S +@@ -0,0 +1,407 @@ ++/* ++ * linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526 ++ * ++ * Copyright (C) 2005 Faraday Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ++ * These are the low level assembler for performing cache and TLB ++ * functions on the fa526. ++ * ++ * Written by : Luke Lee ++ */ ++#include <linux/linkage.h> ++#include <linux/init.h> ++#include <asm/assembler.h> ++#include <asm/pgtable.h> ++#include <asm/pgtable-hwdef.h> ++#include <asm/elf.h> ++#include <asm/hardware.h> ++#include <asm/page.h> ++#include <asm/ptrace.h> ++#include <asm/system.h> ++#include "proc-macros.S" ++ ++#define CACHE_DLINESIZE 16 ++ ++ .text ++/* ++ * cpu_fa526_proc_init() ++ */ ++ENTRY(cpu_fa526_proc_init) ++ /* MMU is already ON here, ICACHE, DCACHE conditionally disabled */ ++ ++ mov r0, #1 ++ nop ++ nop ++ mcr p15, 0, r0, c1, c1, 0 @ turn-on ECR ++ nop ++ nop ++ ++ mrc p15, 0, r0, c1, c0, 0 @ read ctrl register ++ ++#ifdef CONFIG_CPU_FA_BTB ++ orr r0, r0, #CR_Z ++#else ++ bic r0, r0, #CR_Z ++#endif ++#ifdef CONFIG_CPU_FA_WB_DISABLE ++ mov r1, #0 ++ mcr p15, 0, r1, c7, c10, 4 @ drain write buffer ++ nop ++ nop ++ bic r0, r0, #CR_W ++#else ++ orr r0, r0, #CR_W ++#endif ++#ifdef CONFIG_CPU_DCACHE_DISABLE ++ bic r0, r0, #CR_C ++#else ++ orr r0, r0, #CR_C ++#endif ++#ifdef CONFIG_CPU_ICACHE_DISABLE ++ bic r0, r0, #CR_I ++#else ++ orr r0, r0, #CR_I ++#endif ++ ++ nop ++ nop ++ mcr p15, 0, r0, c1, c0, 0 ++ nop ++ nop ++ ++ mov r5, lr ++ bl fa_initialize_cache_info @ destroy r0~r4 ++ mov pc, r5 @ return ++ ++ ++/* ++ * cpu_fa526_proc_fin() ++ */ ++ENTRY(cpu_fa526_proc_fin) ++ stmfd sp!, {lr} ++ mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE ++ msr cpsr_c, ip ++ ++ bl fa_flush_kern_cache_all ++ mrc p15, 0, r0, c1, c0, 0 @ ctrl register ++ bic r0, r0, #0x1000 @ ...i............ ++ bic r0, r0, #0x000e @ ............wca. ++ mcr p15, 0, r0, c1, c0, 0 @ disable caches ++ ++ nop ++ nop ++ ldmfd sp!, {pc} ++ ++/* ++ * cpu_fa526_reset(loc) ++ * ++ * Perform a soft reset of the system. Put the CPU into the ++ * same state as it would be if it had been reset, and branch ++ * to what would be the reset vector. ++ * ++ * loc: location to jump to for soft reset ++ */ ++ .align 4 ++ENTRY(cpu_fa526_reset) ++ mov ip, #0 ++ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ mcr p15, 0, ip, c7, c10, 4 @ drain WB ++#endif ++ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs ++ mrc p15, 0, ip, c1, c0, 0 @ ctrl register ++ bic ip, ip, #0x000f @ ............wcam ++ bic ip, ip, #0x1100 @ ...i...s........ ++ ++ bic ip, ip, #0x0800 @ BTB off ++ mcr p15, 0, ip, c1, c0, 0 @ ctrl register ++ nop ++ nop ++ mov pc, r0 ++ ++/* ++ * cpu_fa526_do_idle() ++ */ ++ .align 4 ++ENTRY(cpu_fa526_do_idle) ++ ++#ifdef CONFIG_CPU_FA_IDLE ++ nop ++ nop ++ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt (IDLE mode) ++#endif ++ mov pc, lr ++ ++ ++ENTRY(cpu_fa526_dcache_clean_area) ++ ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry ++ add r0, r0, #CACHE_DLINESIZE ++ subs r1, r1, #CACHE_DLINESIZE ++ bhi 1b ++#endif ++#endif ++ mov pc, lr ++ ++ ++/* =============================== PageTable ============================== */ ++ ++/* ++ * cpu_fa526_switch_mm(pgd) ++ * ++ * Set the translation base pointer to be as described by pgd. ++ * ++ * pgd: new page tables ++ */ ++ .align 4 ++ ++ .globl fault_address ++fault_address: ++ .long 0 ++ ++ENTRY(cpu_fa526_switch_mm) ++ ++ mov ip, #0 ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache ++#else ++ mcr p15, 0, ip, c7, c14, 0 @ Clean and invalidate whole DCache ++#endif ++#endif /*CONFIG_CPU_DCACHE_DISABLE*/ ++ ++#ifndef CONFIG_CPU_ICACHE_DISABLE ++ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache ++#endif ++ ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ mcr p15, 0, ip, c7, c10, 4 @ drain WB ++#endif ++ ++#ifdef CONFIG_CPU_FA_BTB ++ mcr p15, 0, ip, c7, c5, 6 @ invalidate BTB since mm changed ++ nop ++ nop ++#endif ++ bic r0, r0, #0xff @ clear bits [7:0] ++ bic r0, r0, #0x3f00 @ clear bits [13:8] ++ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer ++ mcr p15, 0, ip, c8, c7, 0 @ invalidate UTLB ++ nop ++ nop ++ mov pc, lr ++ ++/* ++ * cpu_fa526_set_pte_ext(ptep, pte, ext) ++ * ++ * Set a PTE and flush it out ++ */ ++ .align 4 ++ENTRY(cpu_fa526_set_pte_ext) ++ str r1, [r0], #-2048 @ linux version ++ ++ eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY ++ ++ bic r2, r1, #PTE_SMALL_AP_MASK ++ bic r2, r2, #PTE_TYPE_MASK ++ orr r2, r2, #PTE_TYPE_SMALL ++ ++ tst r1, #L_PTE_USER @ User? ++ orrne r2, r2, #PTE_SMALL_AP_URO_SRW ++ ++ tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? ++ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW ++ ++ tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? ++ movne r2, #0 ++ ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ eor r3, r2, #0x0a @ C & small page? 1010 ++ tst r3, #0x0b @ 1011 ++ biceq r2, r2, #4 ++#endif ++ str r2, [r0] @ hardware version ++ ++ mov r2, #0 ++ mcr p15, 0, r2, c7, c10, 0 @ clean D cache all ++ ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ mcr p15, 0, r2, c7, c10, 4 @ drain WB ++#endif ++#ifdef CONFIG_CPU_FA_BTB ++ mcr p15, 0, r2, c7, c5, 6 @ invalidate BTB ++ nop ++ nop ++#endif ++ mov pc, lr ++ ++ __INIT ++ ++ .type __fa526_setup, #function ++__fa526_setup: ++ /* On return of this routine, r0 must carry correct flags for CFG register */ ++ mov r0, #0 ++ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 ++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 ++ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 ++ ++ mcr p15, 0, r0, c7, c5, 5 @ invalidate IScratchpad RAM ++ ++ mov r0, #1 ++ mcr p15, 0, r0, c1, c1, 0 @ turn-on ECR ++ ++ mrc p15, 0, r0, c9, c1, 0 @ DScratchpad ++ bic r0, r0, #1 ++ mcr p15, 0, r0, c9, c1, 0 ++ mrc p15, 0, r0, c9, c1, 1 @ IScratchpad ++ bic r0, r0, #1 ++ mcr p15, 0, r0, c9, c1, 1 ++ ++ mov r0, #0 ++ mcr p15, 0, r0, c1, c1, 0 @ turn-off ECR ++ ++#ifdef CONFIG_CPU_FA_BTB ++ mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB All ++ nop ++ nop ++#endif ++ ++ mov r0, #0x1f @ Domains 0, 1 = manager, 2 = client ++ mcr p15, 0, r0, c3, c0 @ load domain access register ++ ++ mrc p15, 0, r0, c1, c0 @ get control register v4 ++ ldr r5, fa526_cr1_clear ++ bic r0, r0, r5 ++ ldr r5, fa526_cr1_set ++ orr r0, r0, r5 ++ ++#ifdef CONFIG_CPU_FA_BTB ++ orr r0, r0, #CR_Z ++#else ++ bic r0, r0, #CR_Z ++#endif ++#ifdef CONFIG_CPU_FA_WB_DISABLE ++ mov r12, #0 ++ mcr p15, 0, r12, c7, c10, 4 @ drain write buffer ++ nop ++ nop ++ bic r0, r0, #CR_W @ .... .... .... 1... ++#else ++ orr r0, r0, #CR_W ++#endif ++ ++ mov pc, lr ++ .size __fa526_setup, . - __fa526_setup ++ ++ /* ++ * .RVI ZFRS BLDP WCAM ++ * ..11 0001 .111 1101 ++ * ++ */ ++ .type fa526_cr1_clear, #object ++ .type fa526_cr1_set, #object ++fa526_cr1_clear: ++ .word 0x3f3f ++fa526_cr1_set: ++ .word 0x317D ++ ++ __INITDATA ++ ++/* ++ * Purpose : Function pointers used to access above functions - all calls ++ * come through these ++ */ ++ .type fa526_processor_functions, #object ++fa526_processor_functions: ++ .word v4_early_abort ++ .word cpu_fa526_proc_init ++ .word cpu_fa526_proc_fin ++ .word cpu_fa526_reset ++ .word cpu_fa526_do_idle ++ .word cpu_fa526_dcache_clean_area ++ .word cpu_fa526_switch_mm ++ .word cpu_fa526_set_pte_ext ++ .size fa526_processor_functions, . - fa526_processor_functions ++ ++ .section ".rodata" ++ ++ .type cpu_arch_name, #object ++cpu_arch_name: ++ .asciz "armv4" ++ .size cpu_arch_name, . - cpu_arch_name ++ ++ .type cpu_elf_name, #object ++cpu_elf_name: ++ .asciz "v4" ++ .size cpu_elf_name, . - cpu_elf_name ++ ++ .type cpu_fa526_name, #object ++cpu_fa526_name: ++ .ascii "FA526" ++#ifndef CONFIG_CPU_ICACHE_DISABLE ++ .ascii "i" ++#endif ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++ .ascii "d" ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ .ascii "(wt)" ++#else ++ .ascii "(wb)" ++#endif ++#endif ++ .ascii "\0" ++ .size cpu_fa526_name, . - cpu_fa526_name ++ ++ .align ++ ++ .section ".proc.info.init", #alloc, #execinstr ++ ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++#define __PMD_SECT_BUFFERABLE 0 ++#else ++#define __PMD_SECT_BUFFERABLE PMD_SECT_BUFFERABLE ++#endif ++ ++ .type __fa526_proc_info,#object ++__fa526_proc_info: ++ .long 0x66015261 ++ .long 0xff01fff1 ++ .long PMD_TYPE_SECT | \ ++ __PMD_SECT_BUFFERABLE | \ ++ PMD_SECT_CACHEABLE | \ ++ PMD_BIT4 | \ ++ PMD_SECT_AP_WRITE | \ ++ PMD_SECT_AP_READ ++ .long PMD_TYPE_SECT | \ ++ PMD_BIT4 | \ ++ PMD_SECT_AP_WRITE | \ ++ PMD_SECT_AP_READ ++ b __fa526_setup ++ .long cpu_arch_name ++ .long cpu_elf_name ++ .long HWCAP_SWP | HWCAP_HALF ++ .long cpu_fa526_name ++ .long fa526_processor_functions ++ .long fa_tlb_fns ++ .long fa_user_fns ++ .long fa_cache_fns ++ .size __fa526_proc_info, . - __fa526_proc_info ++ ++ +--- /dev/null ++++ b/arch/arm/mm/tlb-fa.S +@@ -0,0 +1,96 @@ ++/* ++ * linux/arch/arm/mm/tlb-fa.S ++ * ++ * Copyright (C) 2005 Faraday Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ARM architecture version 4, Faraday variation. ++ * This assume an unified TLBs, with a write buffer, and branch target buffer (BTB) ++ * ++ * Processors: FA520 FA526 FA626 ++ * 03/31/2005 : Created by Luke Lee, modified from tlb-v4wbi.S ++ * 05/06/2005 : Fixed buggy CPU versions that did not invalidate the associated ++ * data cache entries when invalidating TLB entries. ++ */ ++#include <linux/linkage.h> ++#include <linux/init.h> ++#include <asm/asm-offsets.h> ++#include <asm/tlbflush.h> ++#include "proc-macros.S" ++ ++ ++/* ++ * flush_user_tlb_range(start, end, mm) ++ * ++ * Invalidate a range of TLB entries in the specified address space. ++ * ++ * - start - range start address ++ * - end - range end address ++ * - mm - mm_struct describing address space ++ */ ++ .align 4 ++ENTRY(fa_flush_user_tlb_range) ++ ++ vma_vm_mm ip, r2 ++ act_mm r3 @ get current->active_mm ++ eors r3, ip, r3 @ == mm ? ++ movne pc, lr @ no, we dont do anything ++ mov r3, #0 ++ ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ mcr p15, 0, r3, c7, c10, 4 @ drain WB ++#endif ++ ++ vma_vm_flags r2, r2 ++ bic r0, r0, #0x0ff ++ bic r0, r0, #0xf00 ++ ++1: mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry ++ add r0, r0, #PAGE_SZ ++ cmp r0, r1 ++ bls 1b @ Luke Lee 05/19/2005 blo -> bls ++ ++#ifdef CONFIG_CPU_FA_BTB ++ mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB ++ nop ++ nop ++#endif ++ mov pc, lr ++ ++ ++ENTRY(fa_flush_kern_tlb_range) ++ mov r3, #0 ++ ++ mcr p15, 0, r3, c7, c10, 0 @ clean Dcache all 06/03/2005 ++ ++#ifndef CONFIG_CPU_FA_WB_DISABLE ++ mcr p15, 0, r3, c7, c10, 4 @ drain WB ++#endif ++ ++ bic r0, r0, #0x0ff ++ bic r0, r0, #0xf00 ++1: ++ mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry ++ add r0, r0, #PAGE_SZ ++ cmp r0, r1 ++ bls 1b @ Luke Lee 05/19/2005 blo -> bls ++ ++#ifdef CONFIG_CPU_FA_BTB ++ mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB ++ nop ++ nop ++#endif ++ mov pc, lr ++ ++ ++ __INITDATA ++ ++ .type fa_tlb_fns, #object ++ENTRY(fa_tlb_fns) ++ .long fa_flush_user_tlb_range ++ .long fa_flush_kern_tlb_range ++ .long fa_tlb_flags ++ .size fa_tlb_fns, . - fa_tlb_fns +--- a/arch/arm/tools/mach-types ++++ b/arch/arm/tools/mach-types +@@ -208,7 +208,8 @@ + fester SA1100_FESTER FESTER 191 + gpi ARCH_GPI GPI 192 + smdk2410 ARCH_SMDK2410 SMDK2410 193 +-i519 ARCH_I519 I519 194 ++#i519 ARCH_I519 I519 194 ++sl2312 ARCH_SL2312 SL2312 194 + nexio SA1100_NEXIO NEXIO 195 + bitbox SA1100_BITBOX BITBOX 196 + g200 SA1100_G200 G200 197 +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/SL_gpio.h +@@ -0,0 +1,59 @@ ++#define GPIO_MINOR_LAST 31 ++#define GPIO_MAJOR 120 // Experiemental ++ ++#define GPIO_IRQ_NBR 12 ++ ++#define GPIOBASEADDR (IO_ADDRESS(0x021000000)) ++ ++#define GPIODATAOUTOFF 0x00 ++#define GPIODATAINOFF 0x04 ++#define GPIOPINDIROFF 0x08 ++#define GPIOPINBYPASSOFF 0x0C ++#define GPIODATASETOFF 0x10 ++#define GPIODATACLEAROFF 0x14 ++#define GPIOPINPULLENBOFF 0x18 ++#define GPIOPINPULLTPOFF 0x1C ++#define GPIOINTRENBOFF 0x20 ++#define GPIOINTRRAWSOFF 0x24 ++#define GPIOINTRMASKEDSTATEOFF 0x28 ++#define GPIOINTRMASKOFF 0x2C ++#define GPIOINTRCLEAROFF 0x30 ++#define GPIOINTRTRIGGEROFF 0x34 ++#define GPIOINTRBOTHOFF 0x38 ++#define GPIOINTRRISENEGOFF 0x3C ++#define GPIOBNCEENBOFF 0x40 ++#define GPIOBNCEPRESOFF 0x44 ++ ++#define GPIO_IOCTRL_SETDIR 0x20 ++#define GPIO_IOCTRL_SET 0x40 ++#define GPIO_IOCTRL_CLEAR 0x50 ++#define GPIO_IOCTRL_ENBINT 0x60 ++#define GPIO_IOCTRL_MASKINT 0x70 ++#define GPIO_IOCTRL_LVLTRIG 0x75 ++#define GPIO_IOCTRL_EDGINT 0x77 ++#define GPIO_IOCTRL_EDGPOLINT 0x78 ++#define GPIO_IOCTRL_BYPASS 0x30 ++#define GPIO_IOCTRL_PRESCLK 0x80 ++#define GPIO_IOCTRL_CLKVAL 0x90 ++#define GPIO_IOCTRL_PULLENB 0xA0 ++#define GPIO_IOCTRL_PULLTYPE 0xA8 ++ ++ ++#define GPIO_MAJOR 120 /* experimental MAJOR number */ ++ // Minor - 0 : 31 gpio pins ++ ++#define GPIO_SET 0x01 ++#define GPIO_CLEAR 0x01 ++ ++#define GPIO_INPUT 0 ++#define GPIO_OUTPUT 1 ++#define GPIO_EDGEINTR 0 ++#define GPIO_EDGESINGL 0 ++#define GPIO_EDGEBOTH 1 ++#define GPIO_POSITIVE 0 ++#define GPIO_ENBINT 1 ++#define GPIO_DISABLEMASK 1 ++#define GPIO_PULLDOWN 0 ++#define GPIO_PULLUP 1 ++#define GPIO_ENABLEPULL 1 ++#define GPIO_DISABLEPULL 0 +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/debug-macro.S +@@ -0,0 +1,20 @@ ++/* linux/include/asm-arm/arch-ebsa110/debug-macro.S ++ * ++ * Debugging macro include header ++ * ++ * Copyright (C) 1994-1999 Russell King ++ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++**/ ++ ++ .macro addruart,rx ++ mov \rx, #0x42000000 ++ .endm ++ ++#define UART_SHIFT 2 ++#define FLOW_CONTROL ++#include <asm/hardware/debug-8250.S> +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/dma.h +@@ -0,0 +1,28 @@ ++/* ++ * linux/include/asm-arm/arch-camelot/dma.h ++ * ++ * Copyright (C) 1997,1998 Russell King ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARCH_DMA_H ++#define __ASM_ARCH_DMA_H ++ ++#define MAX_DMA_ADDRESS 0xffffffff ++ ++#define MAX_DMA_CHANNELS 0 ++ ++#endif /* _ASM_ARCH_DMA_H */ ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/entry-macro.S +@@ -0,0 +1,42 @@ ++/* ++ * include/asm-arm/arch-arm/entry-macro.S ++ * ++ * Low-level IRQ helper macros for ebsa110 platform. ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++#include <asm/arch/platform.h> ++#include <asm/arch/int_ctrl.h> ++ ++ ++ .macro disable_fiq ++ .endm ++ ++ .macro get_irqnr_preamble, base, tmp ++ .endm ++ ++ .macro arch_ret_to_user, tmp1, tmp2 ++ .endm ++ ++ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ++ ldr \irqstat, =IRQ_STATUS(IO_ADDRESS(SL2312_INTERRUPT_BASE)) ++ ldr \irqnr,[\irqstat] ++ cmp \irqnr,#0 ++ beq 2313f ++ mov \tmp,\irqnr ++ mov \irqnr,#0 ++2312: ++ tst \tmp, #1 ++ bne 2313f ++ add \irqnr, \irqnr, #1 ++ mov \tmp, \tmp, lsr #1 ++ cmp \irqnr, #31 ++ bcc 2312b ++2313: ++ .endm ++ ++ .macro irq_prio_table ++ .endm ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/flash.h +@@ -0,0 +1,83 @@ ++#ifndef __ASM_ARM_ARCH_FLASH_H ++#define __ASM_ARM_ARCH_FLASH_H ++ ++#define FLASH_START SL2312_FLASH_BASE ++#define SFLASH_SIZE 0x00400000 ++#define SPAGE_SIZE 0x200 ++#define BLOCK_ERASE 0x50 ++#define BUFFER1_READ 0x54 ++#define BUFFER2_READ 0x56 ++#define PAGE_ERASE 0x81 ++#define MAIN_MEMORY_PAGE_READ 0x52 ++#define MAIN_MEMORY_PROGRAM_BUFFER1 0x82 ++#define MAIN_MEMORY_PROGRAM_BUFFER2 0x85 ++#define BUFFER1_TO_MAIN_MEMORY 0x83 ++#define BUFFER2_TO_MAIN_MEMORY 0x86 ++#define MAIN_MEMORY_TO_BUFFER1 0x53 ++#define MAIN_MEMORY_TO_BUFFER2 0x55 ++#define BUFFER1_WRITE 0x84 ++#define BUFFER2_WRITE 0x87 ++#define AUTO_PAGE_REWRITE_BUFFER1 0x58 ++#define AUTO_PAGE_REWRITE_BUFFER2 0x59 ++#define READ_STATUS 0x57 ++ ++#define MAIN_MEMORY_PAGE_READ_SPI 0xD2 ++#define BUFFER1_READ_SPI 0xD4 ++#define BUFFER2_READ_SPI 0xD6 ++#define READ_STATUS_SPI 0xD7 ++ ++#define FLASH_ACCESS_OFFSET 0x00000010 ++#define FLASH_ADDRESS_OFFSET 0x00000014 ++#define FLASH_WRITE_DATA_OFFSET 0x00000018 ++#define FLASH_READ_DATA_OFFSET 0x00000018 ++#define SERIAL_FLASH_CHIP1_EN 0x00010000 // 16th bit = 1 ++#define SERIAL_FLASH_CHIP0_EN 0x00000000 // 16th bit = 0 ++#define AT45DB321_PAGE_SHIFT 0xa ++#define AT45DB642_PAGE_SHIFT 0xb ++#define CONTINUOUS_MODE 0x00008000 ++ ++#define FLASH_ACCESS_ACTION_OPCODE 0x0000 ++#define FLASH_ACCESS_ACTION_OPCODE_DATA 0x0100 ++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS 0x0200 ++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_DATA 0x0300 ++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_X_DATA 0x0400 ++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_2X_DATA 0x0500 ++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_3X_DATA 0x0600 ++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_4X_DATA 0x0700 ++//#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_X_DATA 0x0600 ++//#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_4X_DATA 0x0700 ++ ++#define M25P80_PAGE_SIZE 0x100 ++#define M25P80_SECTOR_SIZE 0x10000 ++ ++ ++//#define M25P80_BULK_ERASE 1 ++//#define M25P80_SECTOR_ERASE 2 ++//#define M25P80_SECTOR_SIZE 0x10000 ++ ++#define M25P80_WRITE_ENABLE 0x06 ++#define M25P80_WRITE_DISABLE 0x04 ++#define M25P80_READ_STATUS 0x05 ++#define M25P80_WRITE_STATUS 0x01 ++#define M25P80_READ 0x03 ++#define M25P80_FAST_READ 0x0B ++#define M25P80_PAGE_PROGRAM 0x02 ++#define M25P80_SECTOR_ERASE 0xD8 ++#define M25P80_BULK_ERASE 0xC7 ++#define FLASH_ERR_OK 0x0 ++ ++extern void address_to_page(__u32, __u16 *, __u16 *); ++extern void main_memory_page_read(__u8, __u16, __u16, __u8 *); ++extern void buffer_to_main_memory(__u8, __u16); ++extern void main_memory_to_buffer(__u8, __u16); ++extern void main_memory_page_program(__u8, __u16, __u16, __u8); ++extern void atmel_flash_read_page(__u32, __u8 *, __u32); ++extern void atmel_erase_page(__u8, __u16); ++extern void atmel_read_status(__u8, __u8 *); ++extern void atmel_flash_program_page(__u32, __u8 *, __u32); ++extern void atmel_buffer_write(__u8, __u16, __u8); ++extern void flash_delay(void); ++ ++extern int m25p80_sector_erase(__u32 address, __u32 schip_en); ++ ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/gemini_cir.h +@@ -0,0 +1,102 @@ ++#ifndef _ASM_ARCH_CIR_H ++#define _ASM_ARCH_CIR_H ++#include <linux/ioctl.h> ++ ++#define VCR_KEY_POWER 0x613E609F ++#define TV1_KEY_POWER 0x40040100 ++#define TV1_KEY_POWER_EXT 0xBCBD ++#define RC5_KER_POWER 0x0CF3 ++ ++#define VCC_H_ACT_PER (16-1) ++#define VCC_L_ACT_PER (8-1) ++#define VCC_DATA_LEN (32-1) ++#define TV1_H_ACT_PER (8-1) ++#define TV1_L_ACT_PER (4-1) ++#define TV1_DATA_LEN (48-1) ++ ++#define VCC_BAUD 540 ++#define TV1_BAUD 430 ++#ifdef CONFIG_SL3516_ASIC ++#define EXT_CLK 60 ++#else ++#define EXT_CLK 20 ++#endif ++ ++#define NEC_PROTOCOL 0x0 ++#define RC5_PROTOCOL 0x1 ++#define VCC_PROTOCOL 0x0 ++#define TV1_PROTOCOL 0x01 ++ ++#ifndef SL2312_CIR_BASE ++#define SL2312_CIR_BASE 0x4C000000 ++#endif ++#define CIR_BASE_ADDR IO_ADDRESS(SL2312_CIR_BASE) ++#define STORLINK_CIR_ID 0x00010400 ++ ++#define CIR_IP_ID *(volatile unsigned int *)(CIR_BASE_ADDR + 0x00) ++#define CIR_CTR_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x04) ++#define CIR_STATUS_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x08) ++#define CIR_RX_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x0C) ++#define CIR_RX_EXT_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x10) ++#define CIR_PWR_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x14) ++#define CIR_PWR_EXT_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x18) ++#define CIR_TX_CTR_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x1C) ++#define CIR_TX_FEQ_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x20) ++#define CIR_TX_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x24) ++#define CIR_TX_EXT_REG *(volatile unsigned int *)(CIR_BASE_ADDR + 0x28) ++ ++ ++#ifndef SL2312_POWER_CTRL_BASE ++#define SL2312_POWER_CTRL_BASE 0x4B000000 ++#endif ++ ++#ifndef PWR_BASE_ADDR ++#define PWR_BASE_ADDR IO_ADDRESS(SL2312_POWER_CTRL_BASE) ++#endif ++#define PWR_CTRL_ID *(unsigned int*)(PWR_BASE_ADDR+0x00) ++#define PWR_CTRL_REG *(unsigned int*)(PWR_BASE_ADDR+0x04) ++#define PWR_STATUS_REG *(unsigned int*)(PWR_BASE_ADDR+0x08) ++ ++ ++#define BIT(x) (1<<x) ++#define TX_STATUS BIT(3) ++ ++#define PWR_STAT_CIR 0x10 ++#define PWR_STAT_RTC 0x20 ++#define PWR_STAT_PUSH 0x40 ++#define PWR_SHUTDOWN 0x01 ++ ++#define CARR_FREQ 38000 ++ ++struct cir_ioctl_data { ++ __u32 data; ++}; ++struct cir_ioctl_data48 { ++ __u32 timeout; ++ __u32 length; ++ __u8 ret; ++ __u32 data; ++ __u32 data_ext; ++}; ++#define OLD_DATA 0 ++#define NEW_RECEIVE 1 ++ ++#define CIR_IOCTL_BASE ('I'|'R') ++#define CIR_SET_BAUDRATE _IOW (CIR_IOCTL_BASE, 0, struct cir_ioctl_data) ++#define CIR_SET_HIGH_PERIOD _IOW (CIR_IOCTL_BASE, 1, struct cir_ioctl_data) ++#define CIR_SET_LOW_PERIOD _IOW (CIR_IOCTL_BASE, 2, struct cir_ioctl_data) ++#define CIR_SET_PROTOCOL _IOW (CIR_IOCTL_BASE, 3, struct cir_ioctl_data) ++#define CIR_SET_ENABLE_COMPARE _IOW (CIR_IOCTL_BASE, 4, struct cir_ioctl_data) ++#define CIR_SET_ENABLE_DEMOD _IOW (CIR_IOCTL_BASE, 5, struct cir_ioctl_data) ++#define CIR_SET_POWER_KEY _IOW (CIR_IOCTL_BASE, 6, struct cir_ioctl_data) ++#define CIR_GET_BAUDRATE _IOR (CIR_IOCTL_BASE, 7, struct cir_ioctl_data) ++#define CIR_GET_HIGH_PERIOD _IOR (CIR_IOCTL_BASE, 8 ,struct cir_ioctl_data) ++#define CIR_GET_LOW_PERIOD _IOR (CIR_IOCTL_BASE, 9 ,struct cir_ioctl_data) ++#define CIR_GET_PROTOCOL _IOR (CIR_IOCTL_BASE, 10, struct cir_ioctl_data) ++#define CIR_GET_ENABLE_COMPARE _IOR (CIR_IOCTL_BASE, 11, struct cir_ioctl_data) ++#define CIR_GET_ENABLE_DEMOD _IOR (CIR_IOCTL_BASE, 12, struct cir_ioctl_data) ++#define CIR_GET_POWER_KEY _IOR (CIR_IOCTL_BASE, 13, struct cir_ioctl_data) ++#define CIR_GET_DATA _IOWR (CIR_IOCTL_BASE, 14, struct cir_ioctl_data48) ++#define CIR_WAIT_INT_DATA _IOWR (CIR_IOCTL_BASE, 15, struct cir_ioctl_data48) ++ ++#endif //_ASM_ARCH_CIR_H +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/gemini_gpio.h +@@ -0,0 +1,77 @@ ++/* ++ * FILE NAME gemini_gpio.h ++ * ++ * BRIEF MODULE DESCRIPTION ++ * Generic Gemini GPIO ++ * ++ * Author: Storlink Software [Device driver] ++ * Jason Lee <jason@storlink.com.tw> ++ * ++ * Copyright 2005 Storlink Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef __GEMINI_GPIO_H ++#define __GEMINI_GPIO_H ++ ++#include <linux/ioctl.h> ++ ++#define STATUS_HIGH 1 ++#define STATUS_LOW 0 ++#define DIRECT_OUT 1 ++#define DIRECT_IN 0 ++ ++#define EDGE_TRIG 0 ++#define RISING_EDGE 0 ++#define FALL_EDGE 1 ++#define SINGLE_EDGE 0 ++#define BOTH_EDGE 1 ++ ++#define LEVEL_TRIG 1 ++#define HIGH_ACTIVE 0 ++#define LOW_ACTIVE 1 ++ ++struct gemini_gpio_ioctl_data { ++ __u32 pin; ++ __u8 status; // status or pin direction ++ // 0: status low or Input ++ // 1: status high or Output ++ ++ /* these member are used to config GPIO interrupt parameter */ ++ __u8 use_default; // if not sure ,set this argument 1 ++ __u8 trig_type; // 0/1:edge/level triger ? ++ __u8 trig_polar; // 0/1:rising/falling high/low active ? ++ __u8 trig_both; // 0/1:single/both detect both ? ++}; ++ ++#define GEMINI_GPIO_IOCTL_BASE 'Z' ++ ++#define GEMINI_SET_GPIO_PIN_DIR _IOW (GEMINI_GPIO_IOCTL_BASE,16, struct gemini_gpio_ioctl_data) ++#define GEMINI_SET_GPIO_PIN_STATUS _IOW (GEMINI_GPIO_IOCTL_BASE,17, struct gemini_gpio_ioctl_data) ++#define GEMINI_GET_GPIO_PIN_STATUS _IOWR(GEMINI_GPIO_IOCTL_BASE,18, struct gemini_gpio_ioctl_data) ++#define GEMINI_WAIT_GPIO_PIN_INT _IOWR(GEMINI_GPIO_IOCTL_BASE,19, struct gemini_gpio_ioctl_data) ++ ++ ++extern void init_gpio_int(__u32 pin,__u8 trig_type,__u8 trig_polar,__u8 trig_both); ++extern int request_gpio_irq(int bit,void (*handler)(int),char level,char high,char both); ++extern int free_gpio_irq(int bit); ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/gemini_i2s.h +@@ -0,0 +1,169 @@ ++#ifndef __GEMINI_I2S_H__ ++#define __GEMINI_I2S_H__ ++#include <linux/ioctl.h> ++#include <linux/types.h> ++#include <asm/arch-sl2312/irqs.h> ++ ++typedef __u16 UINT16; ++typedef __u32 UINT32; ++typedef __u8 UINT8; ++typedef __u8 BOOL; ++ ++/***************************************/ ++/* define GPIO module base address */ ++/***************************************/ ++#define DMA_CONTROL_PHY_BASE (IO_ADDRESS(SL2312_GENERAL_DMA_BASE)) ++#define DMA_CONTROL_SSP_BASE (IO_ADDRESS(SL2312_SSP_CTRL_BASE)) ++#define SSP_INT IRQ_SSP ++#define GPIO_BASE_ADDR (IO_ADDRESS(SL2312_GPIO_BASE)) ++#define GPIO_BASE_ADDR1 (IO_ADDRESS(SL2312_GPIO_BASE1)) ++#define GLOBAL_BASE (IO_ADDRESS(SL2312_GLOBAL_BASE)) ++ ++/* define read/write register utility */ ++#define READ_SSP_REG(offset) (__raw_readl(offset+DMA_CONTROL_SSP_BASE)) ++#define WRITE_SSP_REG(offset,val) (__raw_writel(val,offset+DMA_CONTROL_SSP_BASE)) ++ ++#define READ_GPIO_REG(offset) (__raw_readl(offset+GPIO_BASE_ADDR)) ++#define WRITE_GPIO_REG(offset,val) (__raw_writel(val,offset+GPIO_BASE_ADDR)) ++ ++#define READ_GPIO1_REG(offset) (__raw_readl(offset+GPIO_BASE_ADDR1)) ++#define WRITE_GPIO1_REG(offset,val) (__raw_writel(val,offset+GPIO_BASE_ADDR1)) ++ ++#define READ_DMA_REG(offset) (__raw_readl(offset+DMA_CONTROL_PHY_BASE)) ++#define WRITE_DMA_REG(offset,val) (__raw_writel(val,offset+DMA_CONTROL_PHY_BASE)) ++ ++#define READ_GLOBAL_REG(offset) (__raw_readl(offset+GLOBAL_BASE)) ++#define WRITE_GLOBAL_REG(offset,val) (__raw_writel(val,offset+GLOBAL_BASE)) ++ ++#define SSP_GPIO_INT IRQ_GPIO ++ ++#ifndef CONFIG_SL3516_ASIC ++#define SSP_GPIO_INT_BIT 0x00000400 //GPIO[10] : SLIC interrupt pin ++ ++#define GPIO_EECK 0x00000040 /* SCK: GPIO[06] */ ++#define GPIO_EECS 0x00000080 /* SCS: GPIO[07] */ ++#define GPIO_MISO 0x00000200 /* SDO: GPIO[09] receive from 6996*/ ++#define GPIO_MOSI 0x00000100 /* SDI: GPIO[08] send to 6996*/ ++#define GPIO_MISO_BIT 9 ++#else ++#define SSP_GPIO_INT_BIT 0x00000001 //GPIO[0] : SLIC interrupt pin ++ ++//#if 0 ++//#define GPIO_EECK 0x80000000 /* SCK: GPIO1[31] */ ++//#define GPIO_EECS 0x40000000 /* SCS: GPIO1[30] */ ++//#define GPIO_MISO 0x20000000 /* SDO: GPIO1[29] receive from 6996*/ ++//#define GPIO_MOSI 0x10000000 /* SDI: GPIO1[28] send to 6996*/ ++//#define GPIO_MISO_BIT 29 ++//#else ++//#define GPIO_EECK 0x00000100 /* SCK: GPIO1[08] */ ++//#define GPIO_EECS 0x08000000 /* SCS: GPIO1[27] */ ++//#define GPIO_MISO 0x00000080 /* SDO: GPIO1[07] receive from 6996*/ ++//#define GPIO_MOSI 0x00000200 /* SDI: GPIO1[09] send to 6996*/ ++//#define GPIO_MISO_BIT 7 ++//#endif ++#endif ++ ++ ++enum GPIO_REG ++{ ++ GPIO_DATA_OUT = 0x00, ++ GPIO_DATA_IN = 0x04, ++ GPIO_PIN_DIR = 0x08, ++ GPIO_BY_PASS = 0x0c, ++ GPIO_DATA_SET = 0x10, ++ GPIO_DATA_CLEAR = 0x14, ++ GPIO_INT_ENABLE = 0x20, ++ GPIO_INT_RAWSTATE = 0x24, ++ GPIO_INT_MASKSTATE = 0x28, ++ GPIO_INT_MASK = 0x2C, ++ GPIO_INT_CLEAR = 0x30, ++ GPIO_INT_TRIGGER = 0x34, ++ GPIO_INT_BOTH = 0x38, ++ GPIO_INT_POLARITY = 0x3C ++}; ++ ++typedef struct ++{ ++ UINT32 src_addr; ++ UINT32 dst_addr; ++ UINT32 llp; ++ UINT32 ctrl_size; ++ UINT32 owner; ++}DMA_LLP_t; ++ ++typedef struct ++{ ++ UINT32 owner; ++ UINT32 src_addr; ++ UINT32 ctrl_size; ++}IOCTL_LLP_t; ++ ++typedef unsigned char byte; ++typedef unsigned short word; ++typedef unsigned long dword; ++ ++/* DMA Registers */ ++#define DMA_INT 0x00000000 ++#define DMA_INT_TC 0x00000004 ++#define DMA_CFG 0x00000024 ++#define DMA_INT_TC_CLR 0x00000008 ++#define DMA_TC 0x00000014 ++#define DMA_CSR 0x00000024 ++#define DMA_SYNC 0x00000028 ++ ++#define DMA_CH2_CSR 0x00000140 ++#define DMA_CH2_CFG 0x00000144 ++#define DMA_CH2_SRC_ADDR 0x00000148 ++#define DMA_CH2_DST_ADDR 0x0000014c ++#define DMA_CH2_LLP 0x00000150 ++#define DMA_CH2_SIZE 0x00000154 ++ ++#define DMA_CH3_CSR 0x00000160 ++#define DMA_CH3_CFG 0x00000164 ++#define DMA_CH3_SRC_ADDR 0x00000168 ++#define DMA_CH3_DST_ADDR 0x0000016c ++#define DMA_CH3_LLP 0x00000170 ++#define DMA_CH3_SIZE 0x00000174 ++ ++#define SSP_DEVICE_ID 0x00 ++#define SSP_CTRL_STATUS 0x04 ++#define SSP_FRAME_CTRL 0x08 ++#define SSP_BAUD_RATE 0x0c ++#define SSP_FRAME_CTRL2 0x10 ++#define SSP_FIFO_CTRL 0x14 ++#define SSP_TX_SLOT_VALID0 0x18 ++#define SSP_TX_SLOT_VALID1 0x1c ++#define SSP_TX_SLOT_VALID2 0x20 ++#define SSP_TX_SLOT_VALID3 0x24 ++#define SSP_RX_SLOT_VALID0 0x28 ++#define SSP_RX_SLOT_VALID1 0x2c ++#define SSP_RX_SLOT_VALID2 0x30 ++#define SSP_RX_SLOT_VALID3 0x34 ++#define SSP_SLOT_SIZE0 0x38 ++#define SSP_SLOT_SIZE1 0x3c ++#define SSP_SLOT_SIZE2 0x40 ++#define SSP_SLOT_SIZE3 0x44 ++#define SSP_READ_PORT 0x48 ++#define SSP_WRITE_PORT 0x4c ++ ++ ++ ++#define SSP_I2S_INIT_BUF _IO ('q', 0x00) ++#define SSP_I2S_STOP_DMA _IO ('q', 0x01) ++#define SSP_I2S_FILE_LEN _IOW ('q', 0x2, int) ++/* ++#define SSP_GET_HOOK_STATUS _IOR ('q', 0xC0, int) ++#define SSP_GET_LINEFEED _IOR ('q', 0xC1, int) ++#define SSP_SET_LINEFEED _IOW ('q', 0xC2, int) ++#define SSP_GET_REG _IOWR ('q', 0xC3, struct Ssp_reg *) ++#define SSP_SET_REG _IOWR ('q', 0xC4, struct Ssp_reg *) ++#define SSP_GEN_OFFHOOK_TONE _IO ('q', 0xC5) ++#define SSP_GEN_BUSY_TONE _IO ('q', 0xC6) ++#define SSP_GEN_RINGBACK_TONE _IO ('q', 0xC7) ++#define SSP_GEN_CONGESTION_TONE _IO ('q', 0xC8) ++#define SSP_DISABLE_DIALTONE _IO ('q', 0xC9) ++#define SSP_PHONE_RING_START _IO ('q', 0xCA) ++*/ ++ ++ ++#endif //__GEMINI_I2S_H__ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/gemini_ssp.h +@@ -0,0 +1,263 @@ ++/****************************************************************************** ++ * gemini_ssp.h ++ * ++ * ++ *****************************************************************************/ ++ ++#include <linux/types.h> ++#include <asm/arch-sl2312/irqs.h> ++#include <linux/phonedev.h> ++#include <linux/telephony.h> ++//#include "proslic.h" ++ ++typedef __u16 UINT16; ++typedef __u32 UINT32; ++typedef __u8 UINT8; ++typedef __u8 BOOL; ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++/***************************************/ ++/* define GPIO module base address */ ++/***************************************/ ++#define DMA_CONTROL_PHY_BASE (IO_ADDRESS(SL2312_GENERAL_DMA_BASE)) ++#define DMA_CONTROL_SSP_BASE (IO_ADDRESS(SL2312_SSP_CTRL_BASE)) ++#define SSP_INT IRQ_SSP ++#define GPIO_BASE_ADDR (IO_ADDRESS(SL2312_GPIO_BASE)) ++#define GPIO_BASE_ADDR1 (IO_ADDRESS(SL2312_GPIO_BASE1)) ++#define GLOBAL_BASE (IO_ADDRESS(SL2312_GLOBAL_BASE)) ++ ++/* define read/write register utility */ ++#define READ_SSP_REG(offset) (__raw_readl(offset+DMA_CONTROL_SSP_BASE)) ++#define WRITE_SSP_REG(offset,val) (__raw_writel(val,offset+DMA_CONTROL_SSP_BASE)) ++ ++#define READ_GPIO_REG(offset) (__raw_readl(offset+GPIO_BASE_ADDR)) ++#define WRITE_GPIO_REG(offset,val) (__raw_writel(val,offset+GPIO_BASE_ADDR)) ++ ++#define READ_GPIO1_REG(offset) (__raw_readl(offset+GPIO_BASE_ADDR1)) ++#define WRITE_GPIO1_REG(offset,val) (__raw_writel(val,offset+GPIO_BASE_ADDR1)) ++ ++#define READ_DMA_REG(offset) (__raw_readl(offset+DMA_CONTROL_PHY_BASE)) ++#define WRITE_DMA_REG(offset,val) (__raw_writel(val,offset+DMA_CONTROL_PHY_BASE)) ++ ++#define READ_GLOBAL_REG(offset) (__raw_readl(offset+GLOBAL_BASE)) ++#define WRITE_GLOBAL_REG(offset,val) (__raw_writel(val,offset+GLOBAL_BASE)) ++ ++ ++#define SSP_GPIO_INT IRQ_GPIO ++ ++#ifndef CONFIG_SL3516_ASIC ++#define SSP_GPIO_INT_BIT 0x00000400 //GPIO[10] : SLIC interrupt pin ++ ++#define GPIO_EECK 0x00000040 /* SCK: GPIO[06] */ ++#define GPIO_EECS 0x00000080 /* SCS: GPIO[07] */ ++#define GPIO_MISO 0x00000200 /* SDO: GPIO[09] receive from 6996*/ ++#define GPIO_MOSI 0x00000100 /* SDI: GPIO[08] send to 6996*/ ++#define GPIO_MISO_BIT 9 ++#else ++#define SSP_GPIO_INT_BIT 0x00000001 //GPIO[0] : SLIC interrupt pin ++ ++//#if 0 ++//#define GPIO_EECK 0x80000000 /* SCK: GPIO1[31] */ ++//#define GPIO_EECS 0x40000000 /* SCS: GPIO1[30] */ ++//#define GPIO_MISO 0x20000000 /* SDO: GPIO1[29] receive from 6996*/ ++//#define GPIO_MOSI 0x10000000 /* SDI: GPIO1[28] send to 6996*/ ++//#define GPIO_MISO_BIT 29 ++//#else ++//#define GPIO_EECK 0x00000100 /* SCK: GPIO1[08] */ ++//#define GPIO_EECS 0x08000000 /* SCS: GPIO1[27] */ ++//#define GPIO_MISO 0x00000080 /* SDO: GPIO1[07] receive from 6996*/ ++//#define GPIO_MOSI 0x00000200 /* SDI: GPIO1[09] send to 6996*/ ++//#define GPIO_MISO_BIT 7 ++//#endif ++#endif ++ ++ ++enum GPIO_REG ++{ ++ GPIO_DATA_OUT = 0x00, ++ GPIO_DATA_IN = 0x04, ++ GPIO_PIN_DIR = 0x08, ++ GPIO_BY_PASS = 0x0c, ++ GPIO_DATA_SET = 0x10, ++ GPIO_DATA_CLEAR = 0x14, ++ GPIO_INT_ENABLE = 0x20, ++ GPIO_INT_RAWSTATE = 0x24, ++ GPIO_INT_MASKSTATE = 0x28, ++ GPIO_INT_MASK = 0x2C, ++ GPIO_INT_CLEAR = 0x30, ++ GPIO_INT_TRIGGER = 0x34, ++ GPIO_INT_BOTH = 0x38, ++ GPIO_INT_POLARITY = 0x3C ++}; ++ ++ ++#define SPI_ADD_LEN 7 // bits of Address ++#define SPI_DAT_LEN 8 // bits of Data ++ ++ ++ ++//#ifdef MIDWAY_DIAG ++#define DAISY_MODE 1 ++#if (DAISY_MODE==1) ++#define NUMBER_OF_CHAN 2 ++#else ++#define NUMBER_OF_CHAN 1 ++#endif ++#define LLP_SIZE 8 ++#define SBUF_SIZE 512 //0xff0 //2560 ++#define DBUF_SIZE SBUF_SIZE*NUMBER_OF_CHAN //0xff0 //2560 ++#define TBUF_SIZE (LLP_SIZE)*DBUF_SIZE ++#define DESC_NUM 1 ++#define DTMF_NUM 20 ++ ++/* define owner bit of SSP */ ++//data into SSP and transfer to AP==> SSP_Rx ++//data out of SSP and transfer to SLIC==> SSP_Tx ++#define CPU 0 ++#define DMA 1 ++ ++#define DMA_DEMO 0 ++#define DMA_NDEMO 1 ++//#define DMA_NONE 2 ++ ++enum exceptions { ++ PROSLICiNSANE, ++ TIMEoUTpOWERuP, ++ TIMEoUTpOWERdOWN, ++ POWERlEAK, ++ TIPoRrINGgROUNDsHORT, ++ POWERaLARMQ1, ++ POWERaLARMQ2, ++ POWERaLARMQ3, ++ POWERaLARMQ4, ++ POWERaLARMQ5, ++ OWERaLARMQ6, ++ CM_CAL_ERR ++}; ++ ++typedef struct ++{ ++ UINT32 src_addr; ++ UINT32 dst_addr; ++ UINT32 llp; ++ UINT32 ctrl_size; ++}DMA_LLP_t; ++ ++typedef struct { ++ unsigned int own ; ++ char *tbuf; ++ //UINT32 *LinkAddrT; ++ DMA_LLP_t LLPT[LLP_SIZE]; ++}DMA_Tx_t; ++ ++typedef struct { ++ unsigned int own ; ++ char *rbuf; ++ //UINT32 *LinkAddrR; ++ DMA_LLP_t LLPR[LLP_SIZE]; ++}DMA_Rx_t; ++ ++//typedef struct { ++// //UINT32 init_stat; ++// struct chipStruct chipData ; /* Represents a proslics state, cached information, and timers */ ++// struct phone_device p; ++// ++// ++//}SSP_SLIC; ++ ++ ++ ++/* DMA Registers */ ++#define DMA_INT 0x00000000 ++#define DMA_INT_TC 0x00000004 ++#define DMA_CFG 0x00000024 ++#define DMA_INT_TC_CLR 0x00000008 ++#define DMA_TC 0x00000014 ++#define DMA_CSR 0x00000024 ++#define DMA_SYNC 0x00000028 ++ ++#define DMA_CH2_CSR 0x00000140 ++#define DMA_CH2_CFG 0x00000144 ++#define DMA_CH2_SRC_ADDR 0x00000148 ++#define DMA_CH2_DST_ADDR 0x0000014c ++#define DMA_CH2_LLP 0x00000150 ++#define DMA_CH2_SIZE 0x00000154 ++ ++#define DMA_CH3_CSR 0x00000160 ++#define DMA_CH3_CFG 0x00000164 ++#define DMA_CH3_SRC_ADDR 0x00000168 ++#define DMA_CH3_DST_ADDR 0x0000016c ++#define DMA_CH3_LLP 0x00000170 ++#define DMA_CH3_SIZE 0x00000174 ++ ++#define SSP_DEVICE_ID 0x00 ++#define SSP_CTRL_STATUS 0x04 ++#define SSP_FRAME_CTRL 0x08 ++#define SSP_BAUD_RATE 0x0c ++#define SSP_FRAME_CTRL2 0x10 ++#define SSP_FIFO_CTRL 0x14 ++#define SSP_TX_SLOT_VALID0 0x18 ++#define SSP_TX_SLOT_VALID1 0x1c ++#define SSP_TX_SLOT_VALID2 0x20 ++#define SSP_TX_SLOT_VALID3 0x24 ++#define SSP_RX_SLOT_VALID0 0x28 ++#define SSP_RX_SLOT_VALID1 0x2c ++#define SSP_RX_SLOT_VALID2 0x30 ++#define SSP_RX_SLOT_VALID3 0x34 ++#define SSP_SLOT_SIZE0 0x38 ++#define SSP_SLOT_SIZE1 0x3c ++#define SSP_SLOT_SIZE2 0x40 ++#define SSP_SLOT_SIZE3 0x44 ++#define SSP_READ_PORT 0x48 ++#define SSP_WRITE_PORT 0x4c ++ ++ ++void printFreq_Revision(int num); ++void SLIC_SPI_write(int num, UINT8 ,UINT8); ++UINT8 SLIC_SPI_read(int num, UINT8); ++void SLIC_SPI_write_bit(char); ++void SLIC_SPI_ind_write(int num, UINT8, UINT16); ++UINT16 SLIC_SPI_ind_read(int num, UINT8); ++void SLIC_SPI_CS_enable(UINT8); ++unsigned int SLIC_SPI_read_bit(void); ++void SLIC_SPI_pre_st(void); ++UINT32 ssp_init(void); ++UINT16 SLIC_SPI_get_identifier(int num); ++int selfTest(int num); ++void exception (int num, enum exceptions e); ++int SLIC_init(int num); ++UINT8 version(int num); ++UINT8 chipType (int num); ++void SLIC_init_ind_reg_set(int num); ++UINT8 powerUp(int num); ++UINT8 powerLeakTest(int num); ++void SLIC_init_reg_set(int num); ++int calibrate(int num); ++void goActive(int num); ++void clearInterrupts(int num); ++void setState(int num, int); ++UINT8 loopStatus(int num); ++int verifyIndirectRegisters(int num); ++int verifyIndirectReg(int num, UINT8 , UINT16); ++void sendProSLICID(int num); ++void disableOscillators(int num); ++UINT8 checkSum(int num, char * string ); ++void fskInitialization (int num); ++void fskByte(int num, UINT8 c); ++void waitForInterrupt (int num); ++//void findNumber(void); ++UINT8 dtmfAction(int num); ++UINT8 digit(int num); ++void interrupt_init(void); ++//void gemini_slic_isr (int ); ++int groundShort(int num); ++void clearAlarmBits(int num); ++void stopRinging(int num); ++void activateRinging(int num); ++void initializeLoopDebounceReg(int num); ++void busyJapan(int num) ; ++void ringBackJapan(int num) ; ++void stateMachine(int num); ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/hardware.h +@@ -0,0 +1,47 @@ ++/* ++ * linux/include/asm-arm/arch-epxa10/hardware.h ++ * ++ * This file contains the hardware definitions of the Integrator. ++ * ++ * Copyright (C) 1999 ARM Limited. ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARCH_HARDWARE_H ++#define __ASM_ARCH_HARDWARE_H ++ ++#include <asm/arch/platform.h> ++ ++#define pcibios_assign_all_busses() 1 ++ ++/* ++ * Where in virtual memory the IO devices (timers, system controllers ++ * and so on) ++ * ++ * macro to get at IO space when running virtually ++*/ ++ ++#define IO_ADDRESS(x) (((x&0xfff00000)>>4)|(x & 0x000fffff)|0xF0000000) ++#define FLASH_VBASE 0xFE000000 ++#define FLASH_SIZE 0x1000000// 8M ++#define FLASH_START SL2312_FLASH_BASE ++#define FLASH_VADDR(x) ((x & 0x00ffffff)|0xFE000000) // flash virtual address ++ ++#define PCIBIOS_MIN_IO 0x100 // 0x000-0x100 AHB reg and PCI config, data ++#define PCIBIOS_MIN_MEM 0 ++ ++#endif ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/int_ctrl.h +@@ -0,0 +1,171 @@ ++/* ++ * ++ * This file contains the register definitions for the Excalibur ++ * Timer TIMER00. ++ * ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef __INT_CTRL_H ++#define __INT_CTRL_H ++ ++#define PCI_IRQ_OFFSET 64 /* PCI start IRQ number */ ++#define FIQ_OFFSET 32 ++ ++#define IRQ_SOURCE(base_addr) (INT_CTRL_TYPE(base_addr + 0x00)) ++#define IRQ_MASK(base_addr) (INT_CTRL_TYPE (base_addr + 0x04 )) ++#define IRQ_CLEAR(base_addr) (INT_CTRL_TYPE (base_addr + 0x08 )) ++#define IRQ_TMODE(base_addr) (INT_CTRL_TYPE (base_addr + 0x0C )) ++#define IRQ_TLEVEL(base_addr) (INT_CTRL_TYPE (base_addr + 0x10 )) ++#define IRQ_STATUS(base_addr) (INT_CTRL_TYPE (base_addr + 0x14 )) ++#define FIQ_SOURCE(base_addr) (INT_CTRL_TYPE (base_addr + 0x20 )) ++#define FIQ_MASK(base_addr) (INT_CTRL_TYPE (base_addr + 0x24 )) ++#define FIQ_CLEAR(base_addr) (INT_CTRL_TYPE (base_addr + 0x28 )) ++#define FIQ_TMODE(base_addr) (INT_CTRL_TYPE (base_addr + 0x2C )) ++#define FIQ_LEVEL(base_addr) (INT_CTRL_TYPE (base_addr + 0x30 )) ++#define FIQ_STATUS(base_addr) (INT_CTRL_TYPE (base_addr + 0x34 )) ++ ++#ifdef CONFIG_SL3516_ASIC ++#define IRQ_SERIRQ0_OFFSET 30 ++#define IRQ_PCID_OFFSET 29 ++#define IRQ_PCIC_OFFSET 28 ++#define IRQ_PCIB_OFFSET 27 ++#define IRQ_PWR_OFFSET 26 ++#define IRQ_CIR_OFFSET 25 ++#define IRQ_GPIO2_OFFSET 24 ++#define IRQ_GPIO1_OFFSET 23 ++#define IRQ_GPIO_OFFSET 22 ++#define IRQ_SSP_OFFSET 21 ++#define IRQ_LPC_OFFSET 20 ++#define IRQ_LCD_OFFSET 19 ++#define IRQ_UART_OFFSET 18 ++#define IRQ_RTC_OFFSET 17 ++#define IRQ_TIMER3_OFFSET 16 ++#define IRQ_TIMER2_OFFSET 15 ++#define IRQ_TIMER1_OFFSET 14 ++#define IRQ_FLASH_OFFSET 12 ++#define IRQ_USB1_OFFSET 11 ++#define IRQ_USB0_OFFSET 10 ++#define IRQ_DMA_OFFSET 9 ++#define IRQ_PCI_OFFSET 8 ++#define IRQ_IPSEC_OFFSET 7 ++#define IRQ_RAID_OFFSET 6 ++#define IRQ_IDE1_OFFSET 5 ++#define IRQ_IDE0_OFFSET 4 ++#define IRQ_WATCHDOG_OFFSET 3 ++#define IRQ_GMAC1_OFFSET 2 ++#define IRQ_GMAC0_OFFSET 1 ++#define IRQ_CPU0_IP_IRQ_OFFSET 0 ++ ++#define IRQ_SERIRQ0_MASK (1<<30) ++#define IRQ_PCID_MASK (1<<29) ++#define IRQ_PCIC_MASK (1<<28) ++#define IRQ_PCIB_MASK (1<<27) ++#define IRQ_PWR_MASK (1<<26) ++#define IRQ_CIR_MASK (1<<25) ++#define IRQ_GPIO2_MASK (1<<24) ++#define IRQ_GPIO1_MASK (1<<23) ++#define IRQ_GPIO_MASK (1<<22) ++#define IRQ_SSP_MASK (1<<21) ++#define IRQ_LPC_MASK (1<<20) ++#define IRQ_LCD_MASK (1<<19) ++#define IRQ_UART_MASK (1<<18) ++#define IRQ_RTC_MASK (1<<17) ++#define IRQ_TIMER3_MASK (1<<16) ++#define IRQ_TIMER2_MASK (1<<15) ++#define IRQ_TIMER1_MASK (1<<14) ++#define IRQ_FLASH_MASK (1<<12) ++#define IRQ_USB1_MASK (1<<11) ++#define IRQ_USB0_MASK (1<<10) ++#define IRQ_DMA_MASK (1<< 9) ++#define IRQ_PCI_MASK (1<< 8) ++#define IRQ_IPSEC_MASK (1<< 7) ++#define IRQ_RAID_MASK (1<< 6) ++#define IRQ_IDE1_MASK (1<< 5) ++#define IRQ_IDE0_MASK (1<< 4) ++#define IRQ_WATCHDOG_MASK (1<< 3) ++#define IRQ_GMAC1_MASK (1<< 2) ++#define IRQ_GMAC0_MASK (1<< 1) ++#define IRQ_CPU0_IP_IRQ_MASK (1<< 0) ++#else ++#define IRQ_SERIRQ0_OFFSET 30 ++#define IRQ_PCID_OFFSET 29 ++#define IRQ_PCIC_OFFSET 28 ++#define IRQ_PCIB_OFFSET 27 ++#define IRQ_PWR_OFFSET 26 ++#define IRQ_CIR_OFFSET 25 ++#define IRQ_GPIO2_OFFSET 24 ++#define IRQ_GPIO1_OFFSET 23 ++#define IRQ_GPIO_OFFSET 22 ++#define IRQ_SSP_OFFSET 21 ++#define IRQ_LPC_OFFSET 20 ++#define IRQ_LCD_OFFSET 19 ++#define IRQ_UART_OFFSET 18 ++#define IRQ_RTC_OFFSET 17 ++#define IRQ_TIMER3_OFFSET 16 ++#define IRQ_TIMER2_OFFSET 15 ++#define IRQ_TIMER1_OFFSET 14 ++#define IRQ_FLASH_OFFSET 12 ++#define IRQ_USB1_OFFSET 11 ++#define IRQ_USB0_OFFSET 10 ++#define IRQ_DMA_OFFSET 9 ++#define IRQ_PCI_OFFSET 8 ++#define IRQ_IPSEC_OFFSET 7 ++#define IRQ_RAID_OFFSET 6 ++#define IRQ_IDE1_OFFSET 5 ++#define IRQ_IDE0_OFFSET 4 ++#define IRQ_WATCHDOG_OFFSET 3 ++#define IRQ_GMAC1_OFFSET 2 ++#define IRQ_GMAC0_OFFSET 1 ++#define IRQ_CPU0_IP_IRQ_OFFSET 0 ++ ++#define IRQ_SERIRQ0_MASK (1<<30) ++#define IRQ_PCID_MASK (1<<29) ++#define IRQ_PCIC_MASK (1<<28) ++#define IRQ_PCIB_MASK (1<<27) ++#define IRQ_PWR_MASK (1<<26) ++#define IRQ_CIR_MASK (1<<25) ++#define IRQ_GPIO2_MASK (1<<24) ++#define IRQ_GPIO1_MASK (1<<23) ++#define IRQ_GPIO_MASK (1<<22) ++#define IRQ_SSP_MASK (1<<21) ++#define IRQ_LPC_MASK (1<<20) ++#define IRQ_LCD_MASK (1<<19) ++#define IRQ_UART_MASK (1<<18) ++#define IRQ_RTC_MASK (1<<17) ++#define IRQ_TIMER3_MASK (1<<16) ++#define IRQ_TIMER2_MASK (1<<15) ++#define IRQ_TIMER1_MASK (1<<14) ++#define IRQ_FLASH_MASK (1<<12) ++#define IRQ_USB1_MASK (1<<11) ++#define IRQ_USB0_MASK (1<<10) ++#define IRQ_DMA_MASK (1<< 9) ++#define IRQ_PCI_MASK (1<< 8) ++#define IRQ_IPSEC_MASK (1<< 7) ++#define IRQ_RAID_MASK (1<< 6) ++#define IRQ_IDE1_MASK (1<< 5) ++#define IRQ_IDE0_MASK (1<< 4) ++#define IRQ_WATCHDOG_MASK (1<< 3) ++#define IRQ_GMAC1_MASK (1<< 2) ++#define IRQ_GMAC0_MASK (1<< 1) ++#define IRQ_CPU0_IP_IRQ_MASK (1<< 0) ++#endif ++ ++ ++#endif /* __INT_CTRL_H */ ++ ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/io.h +@@ -0,0 +1,50 @@ ++/* ++ * linux/include/asm-arm/arch-epxa10db/io.h ++ * ++ * Copyright (C) 1999 ARM Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARM_ARCH_IO_H ++#define __ASM_ARM_ARCH_IO_H ++ ++#define IO_SPACE_LIMIT 0xffffffff ++ ++ ++/* ++ * Generic virtual read/write ++ */ ++/* ++#define __arch_getw(a) (*(volatile unsigned short *)(a)) ++#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) ++*/ ++/*#define outsw __arch_writesw ++#define outsl __arch_writesl ++#define outsb __arch_writesb ++#define insb __arch_readsb ++#define insw __arch_readsw ++#define insl __arch_readsl*/ ++ ++#define __io(a) (a) ++#define __mem_pci(a) (a) ++/* ++#define __arch_getw(a) (*(volatile unsigned short *)(a)) ++#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) ++*/ ++#define iomem_valid_addr(off,size) (1) ++#define iomem_to_phys(off) (off) ++ ++ ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/ipi.h +@@ -0,0 +1,189 @@ ++/* ++ * linux/include/asm-arm/arch-sl2312/system.h ++ * ++ * Copyright (C) 1999 ARM Limited ++ * Copyright (C) 2000 Deep Blue Solutions Ltd ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARCH_IPI_H ++#define __ASM_ARCH_IPI_H ++#include <asm/io.h> ++ ++//#define spin_lock(x) spin_lock_dt(x) ++//#define spin_unlock(x) spin_unlock_dt(x) ++ ++#define SWAP_OFFSET 0x400000 ++#define SWAP_SIZE 0x400000 ++ ++#define SHARE_MEM_ADDR 0x2000000 ++#define SHARE_MEM_SIZE 1024*1024 ++ ++ ++//--> Add by jason for IPI testing ++// memory layout for maste & slave bin ++#define MASTERTEXT 0x8000 ++#define SLAVETEXT 0x108000 ++#define SHARESIZE 0x4000 ++#define SHAREADDR SHARE_MEM_ADDR // starting 8M ++ ++// CPU1 reset release ++#define GLOBAL_BASE IO_ADDRESS(0x40000000) ++#define GLOBAL_SOFTRESET (GLOBAL_BASE + 0x0C) ++#define CPU1_RESET_BIT_MASK 0x40000000 ++ ++// IPI , need to redefine the folliwing, bug ++#define CPU0_STATUS (GLOBAL_BASE + 0x0038) ++#define CPU1_STATUS (GLOBAL_BASE + 0x003C) ++#define CPU_IPI_BIT_MASK 0x80000000 ++ ++/* Your basic SMP spinlocks, allowing only a single CPU anywhere ++*/ ++typedef struct { ++ volatile unsigned int lock; ++} spinlock_dt; ++ ++ ++#define MASTER_BIT 0x01 ++#define SLAVE_BIT 0x02 ++#define HEART_BIT 0x04 ++#define IPI0_IRQ_BIT 0x08 ++#define IPI0_FIQ_BIT 0x10 ++#define IPI1_IRQ_BIT 0x20 ++#define IPI1_FIQ_BIT 0x40 ++ ++#define IRQ 0 ++#define FIQ 1 ++#define DONE 0xff ++ ++#define CPU0 0x0 ++#define CPU1 0x1 ++ ++#define MAXCHAR 128*1024 ++typedef struct { ++ int flag; ++ int uart_flag; ++ int cnt; ++ spinlock_dt lk; ++ char message[MAXCHAR]; ++}s_mailbox; ++ ++// JScale proj definition ++typedef struct { ++ u16 type; // message Type ++ u16 length; // message length, including message header ++} IPC_MSG_HDR_T; ++ ++typedef struct{ ++ IPC_MSG_HDR_T hdr; ++ u32 input_location; ++ u32 input_size; ++ u32 output_location; ++ u16 ScaledImageWidth; ++ u16 ScaledImageHeight; ++ u8 ScaledImageQuality; ++ u8 MaintainResultionRatio; ++ u8 TwoStepScaling; ++ u8 InputFormat; ++ u8 verbose; ++ u8 reserved[3]; ++} JSCALE_REQ_T; ++ ++typedef struct{ ++ IPC_MSG_HDR_T hdr; ++ u32 status; ++ u32 code; ++ u32 output_size; ++} JSCALE_RSP_T; ++ ++#define IPC_JSCALE_REQ_MSG 0 // JScale request from CPU-0 to CPU-1 ++#define IPC_JSCALE_RSP_MSG 1 // JScale response from CPU-1 to CPU-0 ++ ++enum { ++ JSCALE_STATUS_OK = 0, ++ JSCALE_UNKNOWN_MSG_TYPE, ++ JSCALE_FAILED_FILE_SIZE, ++ JSCALE_FAILED_MALLOC, ++ JSCALE_FAILED_FORMAT, ++ JSCALE_DECODE_ERROR, ++ JSCALE_BUSY, ++}; ++// <-- JScale ++ ++#define GEMINI_IPI_IOCTL_BASE 'Z' ++#define GEMINI_IPI_JSCALE_REQ _IOW (GEMINI_IPI_IOCTL_BASE,0,JSCALE_REQ_T) ++#define GEMINI_IPI_JSCALE_STAT _IOR (GEMINI_IPI_IOCTL_BASE,1,JSCALE_RSP_T) ++ ++ ++/* ++* Simple spin lock operations. ++* ++*/ ++ ++#define spin_is_locked_dt(x)((x)->lock != 0) ++ ++static inline int test_and_set_dt(spinlock_dt *lock) ++{ ++unsigned long tmp; ++__asm__ __volatile__( ++"swp %0, %2, [%1]\n" ++: "=&r" (tmp) ++: "r" (&lock->lock), "r" (1) ++: "cc", "memory"); ++ ++return tmp; ++} ++ ++static inline void spin_lock_dt(spinlock_dt *lock) ++{ ++ ++unsigned long tmp; ++__asm__ __volatile__( ++"1: ldr %0, [%1]\n" ++"teq %0, #0\n" ++"swpeq %0, %2, [%1]\n" ++" teqeq %0, #0\n" ++" bne 1b" ++ : "=&r" (tmp) ++ : "r" (&lock->lock), "r" (1) ++ : "cc", "memory"); ++} ++ ++static inline void spin_unlock_dt(spinlock_dt *lock) ++{ ++ __asm__ __volatile__( ++" str %1, [%0]" ++ : ++ : "r" (&lock->lock), "r" (0) ++ : "cc", "memory"); ++} ++ ++static inline int getcpuid(void) ++{ ++ int cpuid; ++ ++ __asm__( ++"mrc p8, 0, r0, c0, c0, 0\n" ++"mov %0, r0" ++ :"=r"(cpuid) ++ : ++ :"r0"); ++ return (cpuid & 0x07); ++} ++ ++ ++ ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/irq.h +@@ -0,0 +1,23 @@ ++/* ++ * linux/include/asm-arm/arch-sl2312/irq.h ++ * ++ * Copyright (C) 1999 ARM Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++ // Since we have PCI interrupt which the interrupt line is pseudo ++ // we need do some fixup ++int fixup_irq(int irq); +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/irqs.h +@@ -0,0 +1,102 @@ ++/* ++ * linux/include/asm-arm/arch-camelot/irqs.h ++ * ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/* Use the Excalibur chip definitions */ ++#define INT_CTRL_TYPE ++#include "asm/arch/int_ctrl.h" ++ ++#ifdef CONFIG_SL3516_ASIC ++#define IRQ_SERIRQ_MAX 31 ++#define IRQ_SERIRQ1 31 ++#define IRQ_SERIRQ0 30 ++#define IRQ_PCID 29 ++#define IRQ_PCIC 28 ++#define IRQ_PCIB 27 ++#define IRQ_PWR 26 ++#define IRQ_CIR 25 ++#define IRQ_GPIO2 24 ++#define IRQ_GPIO1 23 ++#define IRQ_GPIO 22 ++#define IRQ_SSP 21 ++#define IRQ_LPC 20 ++#define IRQ_LCD 19 ++#define IRQ_UART 18 ++#define IRQ_RTC 17 ++#define IRQ_TIMER3 16 ++#define IRQ_TIMER2 15 ++#define IRQ_TIMER1 14 ++#define IRQ_FLASH 12 ++#define IRQ_USB1 11 ++#define IRQ_USB0 10 ++#define IRQ_DMA 9 ++#define IRQ_PCI 8 ++#define IRQ_IPSEC 7 ++#define IRQ_RAID 6 ++#define IRQ_IDE1 5 ++#define IRQ_IDE0 4 ++#define IRQ_WATCHDOG 3 ++#define IRQ_GMAC1 2 ++#define IRQ_GMAC0 1 ++#define IRQ_CPU0_IP_IRQ 0 ++#else ++#define IRQ_SERIRQ_MAX 31 ++#define IRQ_SERIRQ1 31 ++#define IRQ_SERIRQ0 30 ++#define IRQ_PCID 29 ++#define IRQ_PCIC 28 ++#define IRQ_PCIB 27 ++#define IRQ_PWR 26 ++#define IRQ_CIR 25 ++#define IRQ_GPIO2 24 ++#define IRQ_GPIO1 23 ++#define IRQ_GPIO 22 ++#define IRQ_SSP 21 ++#define IRQ_LPC 20 ++#define IRQ_LCD 19 ++#define IRQ_UART 18 ++#define IRQ_RTC 17 ++#define IRQ_TIMER3 16 ++#define IRQ_TIMER2 15 ++#define IRQ_TIMER1 14 ++#define IRQ_FLASH 12 ++#define IRQ_USB1 11 ++#define IRQ_USB0 10 ++#define IRQ_DMA 9 ++#define IRQ_PCI 8 ++#define IRQ_IPSEC 7 ++#define IRQ_RAID 6 ++#define IRQ_IDE1 5 ++#define IRQ_IDE0 4 ++#define IRQ_WATCHDOG 3 ++#define IRQ_GMAC1 2 ++#define IRQ_GMAC0 1 ++#endif ++ ++#define ARCH_TIMER_IRQ IRQ_TIMER2 /* for MV 4.0 */ ++ ++#define IRQ_PCI_INTA PCI_IRQ_OFFSET + 0 ++#define IRQ_PCI_INTB PCI_IRQ_OFFSET + 1 ++#define IRQ_PCI_INTC PCI_IRQ_OFFSET + 2 ++#define IRQ_PCI_INTD PCI_IRQ_OFFSET + 3 ++ ++#define NR_IRQS (IRQ_PCI_INTD + 4) ++ ++ ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/it8712.h +@@ -0,0 +1,24 @@ ++ ++#ifndef __IT8712_H__ ++#define __IT8712_H__ ++ ++#include "asm/arch/sl2312.h" ++ ++#define IT8712_IO_BASE SL2312_LPC_IO_BASE ++// Device LDN ++#define LDN_SERIAL1 0x01 ++#define LDN_SERIAL2 0x02 ++#define LDN_PARALLEL 0x03 ++#define LDN_KEYBOARD 0x05 ++#define LDN_MOUSE 0x06 ++#define LDN_GPIO 0x07 ++ ++#define IT8712_UART1_PORT 0x3F8 ++#define IT8712_UART2_PORT 0x2F8 ++ ++#define IT8712_GPIO_BASE 0x800 // 0x800-0x804 for GPIO set1-set5 ++ ++void LPCSetConfig(char LdnNumber, char Index, char data); ++char LPCGetConfig(char LdnNumber, char Index); ++ ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/memory.h +@@ -0,0 +1,38 @@ ++/* ++ * linux/include/asm-arm/arch-sl2312/memory.h ++ * ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARCH_MMU_H ++#define __ASM_ARCH_MMU_H ++ ++/* ++ * Physical DRAM offset. ++ */ ++#define PHYS_OFFSET UL(0x00000000) ++ ++/* ++ * Virtual view <-> DMA view memory address translations ++ * virt_to_bus: Used to translate the virtual address to an ++ * address suitable to be passed to set_dma_addr ++ * bus_to_virt: Used to convert an address for DMA operations ++ * to an address that the kernel can use. ++ */ ++#define __virt_to_bus(x) (x - PAGE_OFFSET + /*SDRAM_BASE*/0) ++#define __bus_to_virt(x) (x - /*SDRAM_BASE*/0 + PAGE_OFFSET) ++ ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/param.h +@@ -0,0 +1,20 @@ ++/* ++ * linux/include/asm-arm/arch-epxa10db/param.h ++ * ++ * Copyright (C) 1999 ARM Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/pci.h +@@ -0,0 +1,18 @@ ++ ++#ifndef __SL2312_PCI_H__ ++#define __SL2312_PCI_H__ ++ ++#define SL2312_PCI_PMC 0x40 ++#define SL2312_PCI_PMCSR 0x44 ++#define SL2312_PCI_CTRL1 0x48 ++#define SL2312_PCI_CTRL2 0x4c ++#define SL2312_PCI_MEM1_BASE_SIZE 0x50 ++#define SL2312_PCI_MEM2_BASE_SIZE 0x54 ++#define SL2312_PCI_MEM3_BASE_SIZE 0x58 ++ ++ ++void sl2312_pci_mask_irq(unsigned int irq); ++void sl2312_pci_unmask_irq(unsigned int irq); ++int sl2312_pci_get_int_src(void); ++ ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/platform.h +@@ -0,0 +1,7 @@ ++#ifndef PLATFORM_H ++#define PLATFORM_H ++#include "sl2312.h" ++ ++#define MAXIRQNUM 68 ++#endif ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/preempt.h +@@ -0,0 +1,63 @@ ++/* ++ * include/asm-arm/arch-sl2312/preempt.h ++ * ++ * Timing support for preempt-stats, kfi, ilatency patches ++ * ++ * Author: dsingleton <dsingleton@mvista.com> ++ * ++ * 2001-2004 (c) MontaVista Software, Inc. This file is licensed under ++ * the terms of the GNU General Public License version 2. This program ++ * is licensed "as is" without any warranty of any kind, whether express ++ * or implied. ++ */ ++ ++#ifndef _ASM_ARCH_PREEMT_H ++#define _ASM_ARCH_PREEMT_H ++ ++#include <asm/arch/hardware.h> ++#include <asm/arch/sl2312.h> ++ ++static inline unsigned long clock_diff(unsigned long start, unsigned long stop) ++{ ++ return (start - stop); ++} ++ ++static inline unsigned int readclock(void) ++{ ++ unsigned int x; ++ ++ x = readl(IO_ADDRESS(SL2312_TIMER2_BASE)); ++ return x; ++} ++ ++static inline unsigned __ticks_per_usec(void) ++{ ++#ifdef CONFIG_SL3516_ASIC ++ unsigned int ahb_clock_rate_base=130; /* unit = MHz*/ ++ unsigned int reg_v=0; ++ unsigned int ticks_usec; ++ ++ reg_v = readl(IO_ADDRESS((SL2312_GLOBAL_BASE+4))); ++ reg_v >>=15; ++ ticks_usec = (ahb_clock_rate_base + (reg_v & 0x07)*10)>>2; ++ ++#else ++ unsigned int ticks_usec=20; ++#endif ++ ++ return ticks_usec; ++} ++ ++/* ++ * timer 1 runs @ 6Mhz 6 ticks = 1 microsecond ++ * and is configed as a count down timer. ++ */ ++#define TICKS_PER_USEC __ticks_per_usec() ++#define ARCH_PREDEFINES_TICKS_PER_USEC ++ ++#define clock_to_usecs(x) ((x) / TICKS_PER_USEC) ++ ++#define INTERRUPTS_ENABLED(x) (!(x & PSR_I_BIT)) ++ ++#endif ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/sl2312.h +@@ -0,0 +1,254 @@ ++#ifndef __sl2312_h ++#define __sl2312_h ++ ++/**************************************************************************** ++ * Copyright Storlink Corp 2002-2003. All rights reserved. * ++ *--------------------------------------------------------------------------* ++ * Name:board.s * ++ * Description: SL231x specfic define * ++ * Author: Plus Chen * ++ * Version: 0.9 Create ++ ****************************************************************************/ ++ ++/* ++ CPE address map; ++ ++ +==================================================== ++ 0x00000000 | FLASH ++ 0x0FFFFFFF | ++ |==================================================== ++ 0x10000000 | SDRAM ++ 0x1FFFFFFF | ++ |==================================================== ++ 0x20000000 | Global Registers 0x20000000-0x20FFFFFF ++ | EMAC and DMA 0x21000000-0x21FFFFFF ++ | UART Module 0x22000000-0x22FFFFFF ++ | Timer Module 0x23000000-0x23FFFFFF ++ | Interrupt Module 0x24000000-0x24FFFFFF ++ | RTC Module 0x25000000-0x25FFFFFF ++ | LPC Host Controller 0x26000000-0x26FFFFFF ++ | LPC Peripherial IO 0x27000000-0x27FFFFFF ++ | WatchDog Timer 0x28000000-0x28FFFFFF ++ 0x2FFFFFFF | Reserved 0x29000000-0x29FFFFFF ++ |===================================================== ++ 0x30000000 | PCI IO, Configuration Registers ++ 0x3FFFFFFF | ++ |===================================================== ++ 0x40000000 | PCI Memory ++ 0x4FFFFFFF | ++ |===================================================== ++ 0x50000000 | Ethernet MAC and DMA 0x50000000-0x50FFFFFF ++ | Security and DMA 0x51000000-0x51FFFFFF ++ | IDE Channel 0 Register 0x52000000-0x527FFFFF ++ | IDE Channel 1 Register 0x52800000-0x52FFFFFF ++ | USB Register 0x53000000-0x53FFFFFF ++ | Flash Controller 0x54000000-0x54FFFFFF ++ | DRAM Controller 0x55000000-0x55FFFFFF ++ 0x5FFFFFFF | Reserved 0x56000000-0x5FFFFFFF ++ |===================================================== ++ 0x60000000 | Reserved ++ 0x6FFFFFFF | ++ |===================================================== ++ 0x70000000 | FLASH shadow Memory ++ 0x7FFFFFFF | ++ |===================================================== ++ 0x80000000 | Big Endian of memory 0x00000000-0x7FFFFFFF ++ 0xFFFFFFFF | ++ +===================================================== ++*/ ++ ++ ++ ++/*------------------------------------------------------------------------------- ++ Memory Map definitions ++-------------------------------------------------------------------------------- */ ++#define TEST 1 ++#if 0 ++ ++static inline int GETCPUID() ++{ ++ int cpuid; ++ __asm__( ++"mrc p8, 0, r0, c0, c0, 0\n" ++"mov %0, r0" ++ :"=r"(cpuid) ++ : ++ :"r0"); ++ return (cpuid & 0x07); ++} ++#endif ++#define SL2312_SRAM_BASE 0x70000000 // SRAM base after remap ++#define SL2312_DRAM_BASE 0x00000000 // DRAM base after remap ++#define SL2312_RAM_BASE 0x10000000 // RAM code base before remap ++#define SL2312_FLASH_BASE 0x30000000 ++#define SL2312_ROM_BASE 0x30000000 ++#define SL2312_GLOBAL_BASE 0x40000000 ++#define SL2312_WAQTCHDOG_BASE 0x41000000 ++#define SL2312_UART_BASE 0x42000000 ++#define SL2312_TIMER_BASE 0x43000000 ++#define SL2312_LCD_BASE 0x44000000 ++#define SL2312_RTC_BASE 0x45000000 ++#define SL2312_SATA_BASE 0x46000000 ++#define SL2312_LPC_HOST_BASE 0x47000000 ++#define SL2312_LPC_IO_BASE 0x47800000 ++// #define SL2312_INTERRUPT_BASE 0x48000000 ++#define SL2312_INTERRUPT0_BASE 0x48000000 ++#define SL2312_INTERRUPT1_BASE 0x49000000 ++//#define SL2312_INTERRUPT_BASE ((getcpuid()==0)?SL2312_INTERRUPT0_BASE:SL2312_INTERRUPT1_BASE) ++#define SL2312_INTERRUPT_BASE 0x48000000 ++#define SL2312_SSP_CTRL_BASE 0x4A000000 ++#define SL2312_POWER_CTRL_BASE 0x4B000000 ++#define SL2312_CIR_BASE 0x4C000000 ++#define SL2312_GPIO_BASE 0x4D000000 ++#define SL2312_GPIO_BASE1 0x4E000000 ++#define SL2312_GPIO_BASE2 0x4F000000 ++#define SL2312_PCI_IO_BASE 0x50000000 ++#define SL2312_PCI_MEM_BASE 0x58000000 ++#ifdef CONFIG_NET_SL351X ++#define SL2312_TOE_BASE 0x60000000 ++#define SL2312_GMAC0_BASE 0x6000A000 ++#define SL2312_GMAC1_BASE 0x6000E000 ++#else ++#define SL2312_GMAC0_BASE 0x60000000 ++#define SL2312_GMAC1_BASE 0x61000000 ++#endif ++#define SL2312_SECURITY_BASE 0x62000000 ++#define SL2312_IDE0_BASE 0x63000000 ++#define SL2312_IDE1_BASE 0x63400000 ++#define SL2312_RAID_BASE 0x64000000 ++#define SL2312_FLASH_CTRL_BASE 0x65000000 ++#define SL2312_DRAM_CTRL_BASE 0x66000000 ++#define SL2312_GENERAL_DMA_BASE 0x67000000 ++#define SL2312_USB_BASE 0x68000000 ++#define SL2312_USB0_BASE 0x68000000 ++#define SL2312_USB1_BASE 0x69000000 ++#define SL2312_FLASH_SHADOW 0x30000000 ++#define SL2312_BIG_ENDIAN_BASE 0x80000000 ++ ++#ifdef CONFIG_GEMINI_IPI ++#define CPU_1_MEM_BASE 0x4000000 // 64 MB ++#define CPU_1_DATA_OFFSET 0x4000000-0x300000 // Offset 61 MB ++#endif ++ ++#define SL2312_TIMER1_BASE SL2312_TIMER_BASE ++#define SL2312_TIMER2_BASE (SL2312_TIMER_BASE + 0x10) ++#define SL2312_TIMER3_BASE (SL2312_TIMER_BASE + 0x20) ++ ++#define SL2312_PCI_DMA_MEM1_BASE 0x00000000 ++#define SL2312_PCI_DMA_MEM2_BASE 0x00000000 ++#define SL2312_PCI_DMA_MEM3_BASE 0x00000000 ++#define SL2312_PCI_DMA_MEM1_SIZE 7 ++#define SL2312_PCI_DMA_MEM2_SIZE 6 ++#define SL2312_PCI_DMA_MEM3_SIZE 6 ++ ++/*------------------------------------------------------------------------------- ++ Global Module ++---------------------------------------------------------------------------------*/ ++#define GLOBAL_ID 0x00 ++#define GLOBAL_CHIP_ID 0x002311 ++#define GLOBAL_CHIP_REV 0xA0 ++#define GLOBAL_STATUS 0x04 ++#define GLOBAL_CONTROL 0x1C ++#define GLOBAL_REMAP_BIT 0x01 ++#define GLOBAL_RESET_REG 0x0C ++#define GLOBAL_MISC_REG 0x30 ++#define PFLASH_SHARE_BIT 0x02 ++ ++#define GLOBAL_RESET (1<<31) ++#define RESET_CPU1 (1<<30) ++#define RESET_SATA1 (1<<27) ++#define RESET_SATA0 (1<<26) ++#define RESET_CIR (1<<25) ++#define RESET_EXT_DEV (1<<24) ++#define RESET_WD (1<<23) ++#define RESET_GPIO2 (1<<22) ++#define RESET_GPIO1 (1<<21) ++#define RESET_GPIO0 (1<<20) ++#define RESET_SSP (1<<19) ++#define RESET_UART (1<<18) ++#define RESET_TIMER (1<<17) ++#define RESET_RTC (1<<16) ++#define RESET_INT0 (1<<15) ++#define RESET_INT1 (1<<14) ++#define RESET_LCD (1<<13) ++#define RESET_LPC (1<<12) ++#define RESET_APB (1<<11) ++#define RESET_DMA (1<<10) ++#define RESET_USB1 (1<<9 ) ++#define RESET_USB0 (1<<8 ) ++#define RESET_PCI (1<<7 ) ++#define RESET_GMAC1 (1<<6 ) ++#define RESET_GMAC0 (1<<5 ) ++#define RESET_IPSEC (1<<4 ) ++#define RESET_RAID (1<<3 ) ++#define RESET_IDE (1<<2 ) ++#define RESET_FLASH (1<<1 ) ++#define RESET_DRAM (1<<0 ) ++ ++ ++ ++ ++ ++ ++ ++ ++/*------------------------------------------------------------------------------- ++ DRAM Module ++---------------------------------------------------------------------------------*/ ++#define DRAM_SIZE_32M 0x2000000 ++#define DRAM_SIZE_64M 0x4000000 ++#define DRAM_SIZE_128M 0x8000000 ++ ++#define DRAM_SIZE DRAM_SIZE_128M ++ ++#define DRAM_SDRMR 0x00 ++#define SDRMR_DISABLE_DLL 0x80010000 ++ ++/*------------------------------------------------------------------------------ ++ Share Pin Flag ++--------------------------------------------------------------------------------*/ ++#ifdef CONFIG_SL2312_SHARE_PIN ++#define FLASH_SHARE_BIT 0 ++#define UART_SHARE_BIT 1 ++#define EMAC_SHARE_BIT 2 ++#define IDE_RW_SHARE_BIT 3 ++#define IDE_CMD_SHARE_BIT 4 ++#endif ++/*------------------------------------------------------------------------------- ++ System Clock ++---------------------------------------------------------------------------------*/ ++ ++#ifndef SYS_CLK ++#ifdef CONFIG_SL3516_ASIC ++#define SYS_CLK 150000000 ++#else ++#define SYS_CLK 20000000 ++#endif ++#endif ++ ++#define AHB_CLK SYS_CLK ++#define MAX_TIMER 3 ++#ifndef APB_CLK ++#ifdef CONFIG_SL3516_ASIC ++#define APB_CLK (SYS_CLK / 6) ++#else ++#define APB_CLK SYS_CLK ++#endif ++#endif ++ ++#ifdef CONFIG_SL3516_ASIC ++#define UART_CLK 48000000 // 30000000 for GeminiA chip, else 48000000 ++#else ++#define UART_CLK 48000000 ++#endif ++ ++#define SL2312_BAUD_115200 (UART_CLK / 1843200) ++#define SL2312_BAUD_57600 (UART_CLK / 921600) ++#define SL2312_BAUD_38400 (UART_CLK / 614400) ++#define SL2312_BAUD_19200 (UART_CLK / 307200) ++#define SL2312_BAUD_14400 (UART_CLK / 230400) ++#define SL2312_BAUD_9600 (UART_CLK / 153600) ++ ++#endif ++ ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/sl2312_ipsec.h +@@ -0,0 +1,684 @@ ++#ifndef _IPSEC_DIAG_H ++#define _IPSEC_DIAG_H ++ ++#include <linux/scatterlist.h> ++ ++#define BIG_ENDIAN 0 ++ ++#define IPSEC_TEST 0 ++#define ZERO_COPY 1 ++ ++#define UINT unsigned int ++#define BYTE unsigned char ++ ++/* define cipher algorithm */ ++enum CIPHER { ++ DES_ECB_E =20, ++ TDES_ECB_E =21, ++ AES_ECB_E =22, ++ DES_CBC_E =24, ++ TDES_CBC_E =25, ++ AES_CBC_E =26, ++ ++ DES_ECB_D =27, ++ TDES_ECB_D =28, ++ AES_ECB_D =29, ++ DES_CBC_D =31, ++ TDES_CBC_D =32, ++ AES_CBC_D =33, ++ A_SHA1 =12, ++ A_HMAC_SHA1 =13, ++ A_MD5 =14, ++ A_HMAC_MD5 =15, ++}; ++ ++// opMode ++#define CIPHER_ENC 0x1 ++#define CIPHER_DEC 0x3 ++#define AUTH 0x4 ++#define ENC_AUTH 0x5 ++#define AUTH_DEC 0x7 ++ ++// cipherAlgorithm ++#define CBC_DES 0x4 ++#define CBC_3DES 0x5 ++#define CBC_AES 0x6 ++#define ECB_DES 0x0 ++#define ECB_3DES 0x1 ++#define ECB_AES 0x2 ++ ++// authAlgorithm ++#define SHA1 0 ++#define MD5 1 ++#define HMAC_SHA1 2 ++#define HMAC_MD5 3 ++#define FCS 4 ++ ++//cipher mode ++#define ECB 0 ++#define CBC 1 ++ ++// authMode ++#define AUTH_APPEND 0 ++#define AUTH_CHKVAL 1 ++ ++/******************************************************/ ++/* the offset of IPSEC DMA register */ ++/******************************************************/ ++enum IPSEC_DMA_REGISTER { ++ IPSEC_DMA_DEVICE_ID = 0xff00, ++ IPSEC_DMA_STATUS = 0xff04, ++ IPSEC_TXDMA_CTRL = 0xff08, ++ IPSEC_TXDMA_FIRST_DESC = 0xff0c, ++ IPSEC_TXDMA_CURR_DESC = 0xff10, ++ IPSEC_RXDMA_CTRL = 0xff14, ++ IPSEC_RXDMA_FIRST_DESC = 0xff18, ++ IPSEC_RXDMA_CURR_DESC = 0xff1c, ++ IPSEC_TXDMA_BUF_ADDR = 0xff28, ++ IPSEC_RXDMA_BUF_ADDR = 0xff38, ++ IPSEC_RXDMA_BUF_SIZE = 0xff30, ++}; ++ ++#define IPSEC_STATUS_REG 0x00a8 ++#define IPSEC_RAND_NUM_REG 0x00ac ++ ++/******************************************************/ ++/* the field definition of IPSEC DMA Module Register */ ++/******************************************************/ ++typedef union ++{ ++ unsigned int bits32; ++ struct bit2_ff00 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int p_wclk : 4; /* DMA_APB write clock period */ ++ unsigned int p_rclk : 4; /* DMA_APB read clock period */ ++ unsigned int : 8; ++ unsigned int device_id : 12; ++ unsigned int revision_id : 4; ++#else ++ unsigned int revision_id : 4; ++ unsigned int device_id : 12; ++ unsigned int : 8; ++ unsigned int p_rclk : 4; /* DMA_APB read clock period */ ++ unsigned int p_wclk : 4; /* DMA_APB write clock period */ ++#endif ++ } bits; ++} IPSEC_DMA_DEVICE_ID_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bit2_ff04 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int ts_finish : 1; /* finished tx interrupt */ ++ unsigned int ts_derr : 1; /* AHB Bus Error while tx */ ++ unsigned int ts_perr : 1; /* Tx Descriptor protocol error */ ++ unsigned int ts_eodi : 1; /* TxDMA end of descriptor interrupt */ ++ unsigned int ts_eofi : 1; /* TxDMA end of frame interrupt */ ++ unsigned int rs_finish : 1; /* finished rx interrupt */ ++ unsigned int rs_derr : 1; /* AHB Bus Error while rx */ ++ unsigned int rs_perr : 1; /* Rx Descriptor protocol error */ ++ unsigned int rs_eodi : 1; /* RxDMA end of descriptor interrupt */ ++ unsigned int rs_eofi : 1; /* RxDMA end of frame interrupt */ ++ unsigned int intr : 8; /* Peripheral interrupt */ ++ unsigned int dma_reset : 1; /* write 1 to this bit will cause DMA HClk domain soft reset */ ++ unsigned int peri_reset : 1; /* write 1 to this bit will cause DMA PClk domain soft reset */ ++ unsigned int : 3; ++ unsigned int loop_back : 1; /* loopback TxDMA to RxDMA */ ++ unsigned int intr_enable : 8; /* Peripheral Interrupt Enable */ ++#else ++ unsigned int intr_enable : 8; /* Peripheral Interrupt Enable */ ++ unsigned int loop_back : 1; /* loopback TxDMA to RxDMA */ ++ unsigned int : 3; ++ unsigned int peri_reset : 1; /* write 1 to this bit will cause DMA PClk domain soft reset */ ++ unsigned int dma_reset : 1; /* write 1 to this bit will cause DMA HClk domain soft reset */ ++ unsigned int intr : 8; /* Peripheral interrupt */ ++ unsigned int rs_eofi : 1; /* RxDMA end of frame interrupt */ ++ unsigned int rs_eodi : 1; /* RxDMA end of descriptor interrupt */ ++ unsigned int rs_perr : 1; /* Rx Descriptor protocol error */ ++ unsigned int rs_derr : 1; /* AHB Bus Error while rx */ ++ unsigned int rs_finish : 1; /* finished rx interrupt */ ++ unsigned int ts_eofi : 1; /* TxDMA end of frame interrupt */ ++ unsigned int ts_eodi : 1; /* TxDMA end of descriptor interrupt */ ++ unsigned int ts_perr : 1; /* Tx Descriptor protocol error */ ++ unsigned int ts_derr : 1; /* AHB Bus Error while tx */ ++ unsigned int ts_finish : 1; /* finished tx interrupt */ ++#endif ++ } bits; ++} IPSEC_DMA_STATUS_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bit2_ff08 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int td_start : 1; /* Start DMA transfer */ ++ unsigned int td_continue : 1; /* Continue DMA operation */ ++ unsigned int td_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/ ++ unsigned int : 1; ++ unsigned int td_prot : 4; /* TxDMA protection control */ ++ unsigned int td_burst_size : 2; /* TxDMA max burst size for every AHB request */ ++ unsigned int td_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */ ++ unsigned int td_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */ ++ unsigned int td_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */ ++ unsigned int td_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */ ++ unsigned int : 14; ++#else ++ unsigned int : 14; ++ unsigned int td_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */ ++ unsigned int td_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */ ++ unsigned int td_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */ ++ unsigned int td_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */ ++ unsigned int td_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */ ++ unsigned int td_burst_size : 2; /* TxDMA max burst size for every AHB request */ ++ unsigned int td_prot : 4; /* TxDMA protection control */ ++ unsigned int : 1; ++ unsigned int td_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/ ++ unsigned int td_continue : 1; /* Continue DMA operation */ ++ unsigned int td_start : 1; /* Start DMA transfer */ ++#endif ++ } bits; ++} IPSEC_TXDMA_CTRL_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bit2_ff0c ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int td_first_des_ptr : 28;/* first descriptor address */ ++ unsigned int td_busy : 1;/* 1-TxDMA busy; 0-TxDMA idle */ ++ unsigned int : 3; ++#else ++ unsigned int : 3; ++ unsigned int td_busy : 1;/* 1-TxDMA busy; 0-TxDMA idle */ ++ unsigned int td_first_des_ptr : 28;/* first descriptor address */ ++#endif ++ } bits; ++} IPSEC_TXDMA_FIRST_DESC_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bit2_ff10 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int ndar : 28; /* next descriptor address */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */ ++ unsigned int sof_eof : 2; ++#else ++ unsigned int sof_eof : 2; ++ unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int ndar : 28; /* next descriptor address */ ++#endif ++ } bits; ++} IPSEC_TXDMA_CURR_DESC_T; ++ ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bit2_ff14 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int rd_start : 1; /* Start DMA transfer */ ++ unsigned int rd_continue : 1; /* Continue DMA operation */ ++ unsigned int rd_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/ ++ unsigned int : 1; ++ unsigned int rd_prot : 4; /* DMA protection control */ ++ unsigned int rd_burst_size : 2; /* DMA max burst size for every AHB request */ ++ unsigned int rd_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */ ++ unsigned int rd_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */ ++ unsigned int rd_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */ ++ unsigned int : 14; ++#else ++ unsigned int : 14; ++ unsigned int rd_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */ ++ unsigned int rd_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */ ++ unsigned int rd_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */ ++ unsigned int rd_burst_size : 2; /* DMA max burst size for every AHB request */ ++ unsigned int rd_prot : 4; /* DMA protection control */ ++ unsigned int : 1; ++ unsigned int rd_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/ ++ unsigned int rd_continue : 1; /* Continue DMA operation */ ++ unsigned int rd_start : 1; /* Start DMA transfer */ ++#endif ++ } bits; ++} IPSEC_RXDMA_CTRL_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bit2_ff18 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int rd_first_des_ptr : 28;/* first descriptor address */ ++ unsigned int rd_busy : 1;/* 1-RxDMA busy; 0-RxDMA idle */ ++ unsigned int : 3; ++#else ++ unsigned int : 3; ++ unsigned int rd_busy : 1;/* 1-RxDMA busy; 0-RxDMA idle */ ++ unsigned int rd_first_des_ptr : 28;/* first descriptor address */ ++#endif ++ } bits; ++} IPSEC_RXDMA_FIRST_DESC_T; ++ ++typedef union ++{ ++ unsigned int bits32; ++ struct bit2_ff1c ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int ndar : 28; /* next descriptor address */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */ ++ unsigned int sof_eof : 2; ++#else ++ unsigned int sof_eof : 2; ++ unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int ndar : 28; /* next descriptor address */ ++#endif ++ } bits; ++} IPSEC_RXDMA_CURR_DESC_T; ++ ++ ++ ++/******************************************************/ ++/* the field definition of IPSEC module Register */ ++/******************************************************/ ++typedef union ++{ ++ unsigned int id; ++ struct bit_0000 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int device_id : 28; ++ unsigned int revision_id : 4; ++#else ++ unsigned int revision_id : 4; ++ unsigned int device_id : 28; ++#endif ++ } bits; ++} IPSEC_ID_T; ++ ++typedef union ++{ ++ unsigned int control; ++ struct bit_0004 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int op_mode : 4; /* Operation Mode for the IPSec Module */ ++ unsigned int : 1; ++ unsigned int cipher_algorithm : 3; ++ unsigned int aesnk : 4; /* AES Key Size */ ++ unsigned int mix_key_sel : 1; /* 0:use rCipherKey0-3 1:use Key Mixer */ ++ unsigned int : 2; ++ unsigned int fcs_stream_copy : 1; /* enable authentication stream copy */ ++ unsigned int auth_mode : 1; /* 0-Append or 1-Check Authentication Result */ ++ unsigned int auth_algorithm : 3; ++ unsigned int : 1; ++ unsigned int auth_check_len : 3; /* Number of 32-bit words to be check or appended */ ++ /* by the authentication module */ ++ unsigned int process_id : 8; /* Used to identify process.This number will be */ ++ /* copied to the descriptor status of received packet*/ ++#else ++ unsigned int process_id : 8; /* Used to identify process.This number will be */ ++ /* copied to the descriptor status of received packet*/ ++ unsigned int auth_check_len : 3; /* Number of 32-bit words to be check or appended */ ++ /* by the authentication module */ ++ unsigned int : 1; ++ unsigned int auth_algorithm : 3; ++ unsigned int auth_mode : 1; /* 0-Append or 1-Check Authentication Result */ ++ unsigned int fcs_stream_copy : 1; /* enable authentication stream copy */ ++ unsigned int : 2; ++ unsigned int mix_key_sel : 1; /* 0:use rCipherKey0-3 1:use Key Mixer */ ++ unsigned int aesnk : 4; /* AES Key Size */ ++ unsigned int cipher_algorithm : 3; ++ unsigned int : 1; ++ unsigned int op_mode : 4; /* Operation Mode for the IPSec Module */ ++#endif ++ } bits; ++} IPSEC_CONTROL_T; ++ ++ ++typedef union ++{ ++ unsigned int cipher_packet; ++ struct bit_0008 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int cipher_header_len : 16; /* The header length to be skipped by the cipher */ ++ unsigned int cipher_algorithm_len : 16; /* The length of message body to be encrypted/decrypted */ ++#else ++ unsigned int cipher_algorithm_len : 16; /* The length of message body to be encrypted/decrypted */ ++ unsigned int cipher_header_len : 16; /* The header length to be skipped by the cipher */ ++#endif ++ } bits; ++} IPSEC_CIPHER_PACKET_T; ++ ++typedef union ++{ ++ unsigned int auth_packet; ++ struct bit_000c ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int auth_header_len : 16; /* The header length that is to be skipped by the authenticator */ ++ unsigned int auth_algorithm_len : 16; /* The length of message body that is to be authenticated */ ++#else ++ unsigned int auth_algorithm_len : 16; /* The length of message body that is to be authenticated */ ++ unsigned int auth_header_len : 16; /* The header length that is to be skipped by the authenticator */ ++#endif ++ } bits; ++} IPSEC_AUTH_PACKET_T; ++ ++typedef union ++{ ++ unsigned int status; ++ struct bit_00a8 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int auth_cmp_rslt : 1; /* Authentication Compare result */ ++ unsigned int wep_crc_ok : 1; /* WEP ICV compare result */ ++ unsigned int tkip_mic_ok : 1; /* TKIP Mic compare result */ ++ unsigned int ccm_mic_ok : 1; /* CCM Mic compare result */ ++ unsigned int : 16; ++ unsigned int parser_err_code: 4; /* Authentication Compare result */ ++ unsigned int auth_err_code : 4; /* Authentication module error code */ ++ unsigned int cipher_err_code: 4; /* Cipher module erroe code */ ++#else ++ unsigned int cipher_err_code: 4; /* Cipher module erroe code */ ++ unsigned int auth_err_code : 4; /* Authentication module error code */ ++ unsigned int parser_err_code: 4; /* Authentication Compare result */ ++ unsigned int : 16; ++ unsigned int ccm_mic_ok : 1; /* CCM Mic compare result */ ++ unsigned int tkip_mic_ok : 1; /* TKIP Mic compare result */ ++ unsigned int wep_crc_ok : 1; /* WEP ICV compare result */ ++ unsigned int auth_cmp_rslt : 1; /* Authentication Compare result */ ++#endif ++ } bits; ++} IPSEC_STATUS_T; ++ ++ ++ ++/************************************************************************/ ++/* IPSec Descriptor Format */ ++/************************************************************************/ ++typedef struct descriptor_t ++{ ++ union frame_control_t ++ { ++ unsigned int bits32; ++ struct bits_0000 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int own : 1; /* owner bit. 0-CPU, 1-DMA */ ++ unsigned int derr : 1; /* data error during processing this descriptor */ ++ unsigned int perr : 1; /* protocol error during processing this descriptor */ ++ unsigned int : 1; /* authentication compare result */ ++ unsigned int : 6; /* checksum[15:8] */ ++ unsigned int desc_count : 6; /* number of descriptors used for the current frame */ ++ unsigned int buffer_size:16; /* transfer buffer size associated with current description*/ ++#else ++ unsigned int buffer_size:16; /* transfer buffer size associated with current description*/ ++ unsigned int desc_count : 6; /* number of descriptors used for the current frame */ ++ unsigned int : 6; /* checksum[15:8] */ ++ unsigned int : 1; /* authentication compare result */ ++ unsigned int perr : 1; /* protocol error during processing this descriptor */ ++ unsigned int derr : 1; /* data error during processing this descriptor */ ++ unsigned int own : 1; /* owner bit. 0-CPU, 1-DMA */ ++#endif ++ } bits; ++ } frame_ctrl; ++ ++ union flag_status_t ++ { ++ unsigned int bits32; ++ struct bits_0004 ++ { ++#if (BIG_ENDIAN==1) ++// unsigned int checksum : 8; /* checksum[7:0] */ ++ unsigned int : 4; ++ unsigned int auth_result: 1; ++ unsigned int wep_crc_ok : 1; ++ unsigned int tkip_mic_ok: 1; ++ unsigned int ccmp_mic_ok: 1; ++ unsigned int process_id : 8; ++ unsigned int frame_count:16; ++#else ++ unsigned int frame_count:16; ++ unsigned int process_id : 8; ++ unsigned int ccmp_mic_ok: 1; ++ unsigned int tkip_mic_ok: 1; ++ unsigned int wep_crc_ok : 1; ++ unsigned int auth_result: 1; ++ unsigned int : 4; ++// unsigned int checksum : 8; /* checksum[7:0] */ ++#endif ++ } bits_rx_status; ++ ++ struct bits_0005 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int : 8; ++ unsigned int process_id : 8; ++ unsigned int frame_count:16; ++#else ++ unsigned int frame_count:16; ++ unsigned int process_id : 8; ++ unsigned int : 8; ++#endif ++ } bits_tx_status; ++ ++ struct bits_0006 ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int :22; ++ unsigned int tqflag :10; ++#else ++ unsigned int tqflag :10; ++ unsigned int :22; ++#endif ++ } bits_tx_flag; ++ } flag_status; ++ ++ unsigned int buf_adr; /* data buffer address */ ++ ++ union next_desc_t ++ { ++ unsigned int next_descriptor; ++ struct bits_000c ++ { ++#if (BIG_ENDIAN==1) ++ unsigned int ndar :28; /* next descriptor address */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int dec : 1; /* AHB bus address. 0-increment; 1-decrement */ ++ unsigned int sof_eof : 2; /* 00-the linking descriptor 01-the last descriptor of a frame*/ ++ /* 10-the first descriptor of a frame 11-only one descriptor for a frame*/ ++#else ++ unsigned int sof_eof : 2; /* 00-the linking descriptor 01-the last descriptor of a frame*/ ++ /* 10-the first descriptor of a frame 11-only one descriptor for a frame*/ ++ unsigned int dec : 1; /* AHB bus address. 0-increment; 1-decrement */ ++ unsigned int eofie : 1; /* end of frame interrupt enable */ ++ unsigned int ndar :28; /* next descriptor address */ ++#endif ++ } bits; ++ } next_desc; ++} IPSEC_DESCRIPTOR_T; ++ ++ ++typedef struct IPSEC_S ++{ ++ unsigned char *tx_bufs; ++ unsigned char *rx_bufs; ++ IPSEC_DESCRIPTOR_T *tx_desc; /* point to virtual TX descriptor address*/ ++ IPSEC_DESCRIPTOR_T *rx_desc; /* point to virtual RX descriptor address*/ ++ IPSEC_DESCRIPTOR_T *tx_cur_desc; /* point to current TX descriptor */ ++ IPSEC_DESCRIPTOR_T *rx_cur_desc; /* point to current RX descriptor */ ++ IPSEC_DESCRIPTOR_T *tx_finished_desc; ++ IPSEC_DESCRIPTOR_T *rx_finished_desc; ++ dma_addr_t rx_desc_dma; /* physical RX descriptor address */ ++ dma_addr_t tx_desc_dma; /* physical TX descriptor address */ ++ dma_addr_t rx_bufs_dma; /* physical RX descriptor address */ ++ dma_addr_t tx_bufs_dma; /* physical TX descriptor address */ ++} IPSEC_T; ++ ++ ++/*=====================================================================================================*/ ++/* Data Structure of IPSEC Control Packet */ ++/*=====================================================================================================*/ ++typedef struct IPSEC_ECB_AUTH_S ++{ ++ IPSEC_CONTROL_T control; /* control parameter */ ++ IPSEC_CIPHER_PACKET_T cipher; /* cipher packet parameter */ ++ IPSEC_AUTH_PACKET_T auth; /* authentication packet parameter */ ++ unsigned char cipher_key[8*4]; ++ unsigned char auth_check_val[5*4]; ++} IPSEC_ECB_AUTH_T; ++ ++typedef struct IPSEC_CBC_AUTH_S ++{ ++ IPSEC_CONTROL_T control; /* control parameter */ ++ IPSEC_CIPHER_PACKET_T cipher; /* cipher packet parameter */ ++ IPSEC_AUTH_PACKET_T auth; /* authentication packet parameter */ ++ unsigned char cipher_iv[4*4]; ++ unsigned char cipher_key[8*4]; ++ unsigned char auth_check_val[5*4]; ++} IPSEC_CBC_AUTH_T; ++ ++typedef struct IPSEC_ECB_HMAC_AUTH_S ++{ ++ IPSEC_CONTROL_T control; /* control parameter */ ++ IPSEC_CIPHER_PACKET_T cipher; /* cipher packet parameter */ ++ IPSEC_AUTH_PACKET_T auth; /* authentication packet parameter */ ++ unsigned char cipher_key[8*4]; ++ unsigned char auth_key[16*4]; ++ unsigned char auth_check_val[5*4]; ++} IPSEC_ECB_AUTH_HMAC_T; ++ ++typedef struct IPSEC_CBC_HMAC_AUTH_S ++{ ++ IPSEC_CONTROL_T control; /* control parameter */ ++ IPSEC_CIPHER_PACKET_T cipher; /* cipher packet parameter */ ++ IPSEC_AUTH_PACKET_T auth; /* authentication packet parameter */ ++ unsigned char cipher_iv[4*4]; ++ unsigned char cipher_key[8*4]; ++ unsigned char auth_key[16*4]; ++ unsigned char auth_check_val[5*4]; ++} IPSEC_CBC_AUTH_HMAC_T; ++ ++typedef struct IPSEC_HMAC_AUTH_S ++{ ++ IPSEC_CONTROL_T control; /* control parameter */ ++ IPSEC_AUTH_PACKET_T auth; /* authentication packet parameter */ ++ unsigned char auth_key[16*4]; ++ unsigned char auth_check_val[5*4]; ++} IPSEC_HMAC_AUTH_T; ++ ++typedef union ++{ ++ unsigned char auth_pkt[28]; ++ ++ struct IPSEC_AUTH_S ++ { ++ IPSEC_CONTROL_T control; /* control parameter(4-byte) */ ++ IPSEC_AUTH_PACKET_T auth; /* authentication packet parameter(4-byte) */ ++ unsigned char auth_check_val[5*4]; ++ } var; ++} IPSEC_AUTH_T; ++ ++typedef struct IPSEC_CIPHER_CBC_S ++{ ++ IPSEC_CONTROL_T control; /* control parameter */ ++ IPSEC_CIPHER_PACKET_T cipher; /* cipher packet parameter */ ++ unsigned char cipher_iv[4*4]; ++ unsigned char cipher_key[8*4]; ++} IPSEC_CIPHER_CBC_T; ++ ++typedef struct IPSEC_CIPHER_ECB_S ++{ ++ IPSEC_CONTROL_T control; /* control parameter */ ++ IPSEC_CIPHER_PACKET_T cipher; /* cipher packet parameter */ ++ unsigned char cipher_key[8*4]; ++} IPSEC_CIPHER_ECB_T; ++ ++ ++/**************************************************************************** ++ * Structure Definition * ++ ****************************************************************************/ ++struct IPSEC_PACKET_S ++{ ++ unsigned int op_mode; /* CIPHER_ENC(1),CIPHER_DEC(3),AUTH(4),ENC_AUTH(5),AUTH_DEC(7) */ ++ unsigned int cipher_algorithm; /* ECB_DES(0),ECB_3DES(1),ECB_AES(2),CBC_DES(4),CBC_3DES(5),CBC_AES(6) */ ++ unsigned int auth_algorithm; /* SHA1(0),MD5(1),HMAC_SHA1(2),HMAC_MD5(3),FCS(4) */ ++ unsigned int auth_result_mode; /* AUTH_APPEND(0),AUTH_CHKVAL(1) */ ++ unsigned int process_id; /* Used to identify the process */ ++ unsigned int auth_header_len; /* Header length to be skipped by the authenticator */ ++ unsigned int auth_algorithm_len; /* Length of message body that is to be authenticated */ ++ unsigned int cipher_header_len; /* Header length to be skipped by the cipher */ ++ unsigned int cipher_algorithm_len; /* Length of message body to be encrypted or decrypted */ ++ unsigned char iv[16]; /* Initial vector used for DES,3DES,AES */ ++ unsigned int iv_size; /* Initial vector size */ ++ unsigned char auth_key[64]; /* authentication key */ ++ unsigned int auth_key_size; /* authentication key size */ ++ unsigned char cipher_key[32]; /* cipher key */ ++ unsigned int cipher_key_size; /* cipher key size */ ++ struct scatterlist *in_packet; /* input_packet buffer pointer */ ++ //unsigned char *in_packet; /* input_packet buffer pointer */ ++ unsigned int pkt_len; /* input total packet length */ ++ unsigned char auth_checkval[20]; /* Authentication check value/FCS check value */ ++ struct IPSEC_PACKET_S *next,*prev; /* pointer to next/previous operation to perform on buffer */ ++ void (*callback)(struct IPSEC_PACKET_S *); /* function to call when done authentication/cipher */ ++ unsigned char *out_packet; /* output_packet buffer pointer */ ++ //struct scatterlist *out_packet; /* output_packet buffer pointer */ ++ unsigned int out_pkt_len; /* output total packet length */ ++ unsigned int auth_cmp_result; /* authentication compare result */ ++ unsigned int checksum; /* checksum value */ ++ unsigned int status; /* ipsec return status. 0:success, others:fail */ ++#if (IPSEC_TEST == 1) ++ unsigned char *sw_packet; /* for test only */ ++ unsigned int sw_pkt_len; /* for test only */ ++#endif ++} ; ++ ++/***************************************************************************** ++ * Function : ipsec_crypto_hw_process ++ * Description : This function processes H/W authentication and cipher. ++ * Input : op_info - the authentication and cipher information for IPSec module. ++ * Output : none. ++ * Return : 0 - success, others - failure. ++ *****************************************************************************/ ++int ipsec_crypto_hw_process(struct IPSEC_PACKET_S *op_info); ++ ++int ipsec_get_cipher_algorithm(unsigned char *alg_name,unsigned int alg_mode); ++int ipsec_get_auth_algorithm(unsigned char *alg_name,unsigned int alg_mode); ++#if 0 ++void ipsec_sw_authentication(char *data,unsigned int data_len,char *authkey,char authAlgorithm,char *auth_result); ++void ipsec_sw_cipher(unsigned char *pt,unsigned int pt_len, unsigned char *cipher_key, unsigned int key_size, ++ unsigned char *iv,unsigned int cipherAlgorithm,unsigned char *ct); ++void ipsec_sw_auth_cipher(unsigned int op_mode,char *data,unsigned int data_len, ++ BYTE *auth_key,char authAlgorithm,char *auth_result, ++ char *pt, unsigned int pt_len,char *cipher_key, int key_size, ++ char *iv, char cipherAlgorithm,char *ct); ++#endif ++ ++ ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/sl_random.h +@@ -0,0 +1,2 @@ ++#define RANDOM_ADD (IO_ADDRESS (0x051000000) + 0x0AC) ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/system.h +@@ -0,0 +1,54 @@ ++/* ++ * linux/include/asm-arm/arch-sl2312/system.h ++ * ++ * Copyright (C) 1999 ARM Limited ++ * Copyright (C) 2000 Deep Blue Solutions Ltd ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARCH_SYSTEM_H ++#define __ASM_ARCH_SYSTEM_H ++ ++#include <asm/arch/platform.h> ++#include <asm/arch/hardware.h> ++#include <asm/arch/it8712.h> ++#include <asm/io.h> ++ ++static void arch_idle(void) ++{ ++ /* ++ * This should do all the clock switching ++ * and wait for interrupt tricks ++ */ ++ cpu_do_idle(); ++} ++ ++extern __inline__ void arch_reset(char mode) ++{ ++ __raw_writel( (int) GLOBAL_RESET|RESET_CPU1, IO_ADDRESS(SL2312_GLOBAL_BASE) + GLOBAL_RESET_REG); ++} ++ ++ ++void (*pm_power_off)(void); ++//{ ++// printk("arch_power_off\n"); ++ ++ // Power off ++// __raw_writel( (int) 0x00000001, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04); ++ ++//} ++ ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/timer.h +@@ -0,0 +1,53 @@ ++/* ++ * ++ * This file contains the register definitions for the Excalibur ++ * Timer TIMER00. ++ * ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __TIMER_H ++#define __TIMER_H ++ ++/* ++ * Register definitions for the timers ++ */ ++ ++#define TIMER_COUNT(BASE_ADDR) (TIMER_TYPE (BASE_ADDR + 0x00 )) ++#define TIMER_LOAD(BASE_ADDR) (TIMER_TYPE (BASE_ADDR + 0x04 )) ++#define TIMER_MATCH1(BASE_ADDR) (TIMER_TYPE (BASE_ADDR + 0x08 )) ++#define TIMER_MATCH2(BASE_ADDR) (TIMER_TYPE (BASE_ADDR + 0x0C )) ++#define TIMER_CR(BASE_ADDR) (TIMER_TYPE (BASE_ADDR + 0x30 )) ++#define TIMER_1_CR_ENABLE_MSK (0x00000001) ++#define TIMER_1_CR_ENABLE_OFST (0) ++#define TIMER_1_CR_CLOCK_MSK (0x00000002) ++#define TIMER_1_CR_CLOCK_OFST (1) ++#define TIMER_1_CR_INT_MSK (0x00000004) ++#define TIMER_1_CR_INT_OFST (2) ++#define TIMER_2_CR_ENABLE_MSK (0x00000008) ++#define TIMER_2_CR_ENABLE_OFST (3) ++#define TIMER_2_CR_CLOCK_MSK (0x00000010) ++#define TIMER_2_CR_CLOCK_OFST (4) ++#define TIMER_2_CR_INT_MSK (0x00000020) ++#define TIMER_2_CR_INT_OFST (5) ++#define TIMER_3_CR_ENABLE_MSK (0x00000040) ++#define TIMER_3_CR_ENABLE_OFST (6) ++#define TIMER_3_CR_CLOCK_MSK (0x00000080) ++#define TIMER_3_CR_CLOCK_OFST (7) ++#define TIMER_3_CR_INT_MSK (0x00000100) ++#define TIMER_3_CR_INT_OFST (8) ++ ++#endif /* __TIMER00_H */ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/timex.h +@@ -0,0 +1,29 @@ ++/* ++ * linux/include/asm-arm/arch-epxa10db/timex.h ++ * ++ * Excalibur timex specifications ++ * ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/* ++ * ?? ++ */ ++#include <asm/arch/sl2312.h> ++ ++#define CLOCK_TICK_RATE APB_CLK ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/uart.h +@@ -0,0 +1,100 @@ ++/* * ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __UART_H ++#define __UART_H ++ ++/* ++ * Register definitions for the UART ++ */ ++ ++#define UART_TX_FIFO_SIZE (15) ++ ++#define UART_RBR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x00)) // read ++#define UART_THR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x00)) // write ++#define UART_IER(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x04)) ++#define UART_IER_MS (0x08) ++#define UART_IER_RLS (0x04) ++#define UART_IER_TE (0x02) ++#define UART_IER_DR (0x01) ++#define UART_IIR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x08)) // read ++#define UART_IIR_NONE (0x01) /* No interrupt pending */ ++#define UART_IIR_RLS (0x06) /* Receive Line Status */ ++#define UART_IIR_DR (0x04) /* Receive Data Ready */ ++#define UART_IIR_TIMEOUT (0x0c) /* Receive Time Out */ ++#define UART_IIR_TE (0x02) /* THR Empty */ ++#define UART_IIR_MODEM (0x00) /* Modem Status */ ++#define UART_FCR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x08)) // write ++#define UART_FCR_FE (0x01) /* FIFO Enable */ ++#define UART_FCR_RXFR (0x02) /* Rx FIFO Reset */ ++#define UART_FCR_TXFR (0x04) /* Tx FIFO Reset */ ++#define UART_FCR_FIFO_1C (0x00) ++#define UART_FCR_FIFO_4C (0x40) ++#define UART_FCR_FIFO_8C (0x80) ++#define UART_FCR_FIFO_14C (0xC0) ++#define UART_LCR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x0C)) ++#define UART_LCR_MSK (0x03) ++#define UART_LCR_LEN5 (0x00) ++#define UART_LCR_LEN6 (0x01) ++#define UART_LCR_LEN7 (0x02) ++#define UART_LCR_LEN8 (0x03) ++#define UART_LCR_STOP (0x04) ++#define UART_LCR_EVEN (0x18) /* Even Parity */ ++#define UART_LCR_ODD (0x08) /* Odd Parity */ ++#define UART_LCR_PE (0x08) /* Parity Enable */ ++#define UART_LCR_SETBREAK (0x40) /* Set Break condition */ ++#define UART_LCR_STICKPARITY (0x20) /* Stick Parity Enable */ ++#define UART_LCR_DLAB (0x80) /* Divisor Latch Access Bit */ ++#define UART_MCR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x10)) ++#define UART_MCR_DTR (0x1) /* Data Terminal Ready */ ++#define UART_MCR_RTS (0x2) /* Request to Send */ ++#define UART_MCR_OUT1 (0x4) /* output 1 */ ++#define UART_MCR_OUT2 (0x8) /* output2 or global interrupt enable */ ++#define UART_MCR_LPBK (0x10) /* loopback mode */ ++#define UART_MCR_MASK (0xE3) ++#define UART_LSR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x14)) ++#define UART_LSR_DR (0x01) /* Data Ready */ ++#define UART_LSR_OE (0x02) /* Overrun Error */ ++#define UART_LSR_PE (0x04) /* Parity Error */ ++#define UART_LSR_FE (0x08) /* Framing Error */ ++#define UART_LSR_BI (0x10) /* Break Interrupt */ ++#define UART_LSR_THRE (0x20) /* THR Empty */ ++#define UART_LSR_TE (0x40) /* Transmitte Empty */ ++#define UART_LSR_DE (0x80) /* FIFO Data Error */ ++#define UART_MSR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x18)) ++#define UART_MSR_DELTACTS (0x01) /* Delta CTS */ ++#define UART_MSR_DELTADSR (0x02) /* Delta DSR */ ++#define UART_MSR_TERI (0x04) /* Trailing Edge RI */ ++#define UART_MSR_DELTACD (0x08) /* Delta CD */ ++#define UART_MSR_CTS (0x10) /* Clear To Send */ ++#define UART_MSR_DSR (0x20) /* Data Set Ready */ ++#define UART_MSR_RI (0x40) /* Ring Indicator */ ++#define UART_MSR_DCD (0x80) /* Data Carrier Detect */ ++#define UART_SPR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x1C)) ++#define UART_DIV_LO(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x0)) ++#define UART_DIV_HI(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x4)) ++#define UART_PSR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x8)) ++#define UART_MDR(BASE_ADDR) (UART_TYPE (BASE_ADDR + 0x20)) ++#define UART_MDR_SERIAL (0x0) ++ ++#define UART_MSR_DDCD 0x08 /* Delta DCD */ ++#define UART_MSR_DDSR 0x02 /* Delta DSR */ ++#define UART_MSR_DCTS 0x01 /* Delta CTS */ ++#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */ ++ ++ ++#endif /* __UART_H */ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/uncompress.h +@@ -0,0 +1,94 @@ ++/* ++ * linux/include/asm-arm/arch-epxa10db/uncompress.h ++ * ++ * Copyright (C) 1999 ARM Limited ++ * Copyright (C) 2001 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include "asm/arch/platform.h" ++#include "asm/arch/hardware.h" ++#define UART_TYPE (volatile unsigned int*) ++#ifndef CONFIG_SERIAL_IT8712 ++#include "asm/arch/uart.h" ++#endif ++extern unsigned int it8712_uart_base; ++ ++/* ++ * This does not append a newline ++ */ ++static void putstr(const char *s) ++{ ++ ++#ifdef CONFIG_SERIAL_IT8712 ++ ++ unsigned char *base,*status,stat; ++ int i ; ++ ++ status = (unsigned char*)it8712_uart_base + 5; ++ base = (unsigned char*)it8712_uart_base ; ++ ++ while (*s) { ++ ++ stat = *status; ++ while (!(stat&0x20)) { // check status ++ for(i=0;i<0x10;i++) ; ++ status = (unsigned char*)it8712_uart_base + 5; ++ stat = *status ; ++ } ++ ++ *base = *s; ++ barrier(); ++ ++ if (*s == '\n') { ++ stat = *status; ++ while (!(stat&0x20)) { // check status ++ for(i=0;i<0x10;i++) ; ++ status = (unsigned char*)it8712_uart_base + 5; ++ stat = *status ; ++ } ++ ++ barrier(); ++ *base = '\r'; ++ } ++ s++; ++ } ++ ++#else ++ while (*s) { ++ while (!(*UART_LSR(SL2312_UART_BASE) & ++ UART_LSR_THRE)); ++ barrier(); ++ ++ *UART_THR(SL2312_UART_BASE) = *s; ++ ++ if (*s == '\n') { ++ while (!(*UART_LSR(SL2312_UART_BASE) & ++ UART_LSR_THRE)); ++ barrier(); ++ ++ *UART_THR(SL2312_UART_BASE) = '\r'; ++ } ++ s++; ++ } ++#endif ++} ++ ++/* ++ * nothing to do ++ */ ++#define arch_decomp_setup() ++ ++#define arch_decomp_wdog() +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/vmalloc.h +@@ -0,0 +1,36 @@ ++/* ++ * linux/include/asm-arm/arch-epxa10db/vmalloc.h ++ * ++ * Copyright (C) 2000 Russell King. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/* ++ * Just any arbitrary offset to the start of the vmalloc VM area: the ++ * current 8MB value just means that there will be a 8MB "hole" after the ++ * physical memory until the kernel virtual memory starts. That means that ++ * any out-of-bounds memory accesses will hopefully be caught. ++ * The vmalloc() routines leaves a hole of 4kB between each vmalloced ++ * area for the same reason. ;) ++ */ ++#define VMALLOC_OFFSET (8*1024*1024) ++#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) ++#define VMALLOC_VMADDR(x) ((unsigned long)(x)) ++#define VMALLOC_END (PAGE_OFFSET + 0x10000000) ++ ++//#define MODULE_START (PAGE_OFFSET - 16*1048576) ++//#define MODULE_END (PAGE_OFFSET) ++ +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/watchdog.h +@@ -0,0 +1,58 @@ ++#ifndef __WATCHDOG_H ++#define __WATCHDOG_H ++ ++#define WATCHDOG_BASE (IO_ADDRESS (SL2312_WAQTCHDOG_BASE)) ++#define WATCHDOG_COUNTER (WATCHDOG_BASE + 0x00) ++#define WATCHDOG_LOAD (WATCHDOG_BASE + 0x04) ++#define WATCHDOG_RESTART (WATCHDOG_BASE + 0x08) ++#define WATCHDOG_CR (WATCHDOG_BASE + 0x0C) ++#define WATCHDOG_STATUS (WATCHDOG_BASE + 0x10) ++#define WATCHDOG_CLEAR (WATCHDOG_BASE + 0x14) ++#define WATCHDOG_INTRLEN (WATCHDOG_BASE + 0x18) ++ ++#define WATCHDOG_WDENABLE_MSK (0x00000001) ++#define WATCHDOG_WDENABLE_OFST (0) ++#define WATCHDOG_WDRST_MSK (0x00000002) ++#define WATCHDOG_WDRST_OFST (1) ++#define WATCHDOG_WDINTR_MSK (0x00000004) ++#define WATCHDOG_WDINTR_OFST (2) ++#define WATCHDOG_WDEXT_MSK (0x00000008) ++#define WATCHDOG_WDEXT_OFST (3) ++#define WATCHDOG_WDCLOCK_MSK (0x00000010) ++#define WATCHDOG_WDCLOCK_OFST (4) ++#define WATCHDOG_CR_MASK (0x0000001F) ++ ++#define WATCHDOG_CLEAR_STATUS 0x1 ++#define WATCHDOG_ENABLE 1 ++#define WATCHDOG_DISABLE 0 ++#define WATCHDOG_RESTART_VALUE 0x5AB9 ++ ++#define WATCHDOG_MINOR 130 ++ ++#define WATCHDOG_IOCTRL_DISABLE 0x01 ++#define WATCHDOG_IOCTRL_SETTIME 0x02 ++#define WATCHDOG_IOCTRL_ENABLE 0x03 ++#define WATCHDOG_IOCTRL_RESTART 0x04 ++ ++#define WATCHDOG_TIMEOUT_SCALE APB_CLK ++#define WATCHDOG_TIMEOUT_MARGIN 30 ++#define WATCHDOG_DRIVER_OPEN 1 ++#define WATCHDOG_DRIVER_CLOSE 0 ++ ++ ++static void watchdog_disable(void); ++static void watchdog_enable(void); ++static int watchdog_open(struct inode *, struct file *); ++static int watchdog_release(struct inode *, struct file *); ++static ssize_t watchdog_read(struct file *, char *, size_t, loff_t *); ++static ssize_t watchdog_write(struct file *, const char *, size_t, loff_t *); ++static int watchdog_ioctl(struct inode *, struct file *, unsigned int, unsigned long); ++#ifdef WATCHDOG_TEST ++static void watchdog_fire(int, void *, struct pt_regs *); ++#endif ++ ++ ++ ++ ++ ++#endif +--- /dev/null ++++ b/include/asm-arm/arch-sl2312/xor.h +@@ -0,0 +1,29 @@ ++/* ++ * include/asm-arm/arch-sl2312/xor.h ++ * ++ * Copyright (C) 2005 Storlink Corp. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef _ASM_ARCH_XOR_H ++#define _ASM_ARCH_XOR_H ++ ++/* ++ * Function prototypes ++ */ ++void xor_gemini_2(unsigned long bytes, unsigned long *p1, unsigned long *p2); ++ ++void xor_gemini_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3); ++ ++void xor_gemini_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3, unsigned long *p4); ++ ++void xor_gemini_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3, unsigned long *p4, unsigned long *p5); ++ ++#endif /* _ASM_ARCH_XOR_H */ ++ +--- a/include/asm-arm/cacheflush.h ++++ b/include/asm-arm/cacheflush.h +@@ -46,6 +46,18 @@ + # define MULTI_CACHE 1 + #endif + ++/*********************************************************************** ++ * Storlink SoC -- Cache ++ ***********************************************************************/ ++#if defined(CONFIG_CPU_FA526) ++# ifdef _CACHE ++# define MULTI_CACHE 1 ++# else ++# define _CACHE fa ++# endif ++#endif ++/***********************************************************************/ ++ + #if defined(CONFIG_CPU_ARM926T) + # ifdef _CACHE + # define MULTI_CACHE 1 +--- a/include/asm-arm/page.h ++++ b/include/asm-arm/page.h +@@ -74,6 +74,18 @@ + # endif + #endif + ++/*********************************************************************** ++ * Storlink SoC -- flash ++ ***********************************************************************/ ++#ifdef CONFIG_CPU_COPY_FA ++# ifdef _USER ++# define MULTI_USER 1 ++# else ++# define _USER fa ++# endif ++#endif ++/***********************************************************************/ ++ + #ifdef CONFIG_CPU_SA1100 + # ifdef _USER + # define MULTI_USER 1 +--- a/include/asm-arm/proc-fns.h ++++ b/include/asm-arm/proc-fns.h +@@ -89,6 +89,14 @@ + # define CPU_NAME cpu_arm922 + # endif + # endif ++# ifdef CONFIG_CPU_FA526 ++# ifdef CPU_NAME ++# undef MULTI_CPU ++# define MULTI_CPU ++# else ++# define CPU_NAME cpu_fa526 ++# endif ++# endif + # ifdef CONFIG_CPU_ARM925T + # ifdef CPU_NAME + # undef MULTI_CPU +--- a/include/asm-arm/tlbflush.h ++++ b/include/asm-arm/tlbflush.h +@@ -39,6 +39,8 @@ + #define TLB_V6_D_ASID (1 << 17) + #define TLB_V6_I_ASID (1 << 18) + ++#define TLB_DINVAL (1 << 28) ++#define TLB_BTB (1 << 29) + #define TLB_DCLEAN (1 << 30) + #define TLB_WB (1 << 31) + +@@ -52,6 +54,7 @@ + * v4wb - ARMv4 with write buffer without I TLB flush entry instruction + * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction + * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction ++ * fa - ARMv4 with write buffer with UTLB and branch target buffer (BTB) + */ + #undef _TLB + #undef MULTI_TLB +@@ -86,6 +89,44 @@ + # define v4_always_flags (-1UL) + #endif + ++#ifdef CONFIG_CPU_FA_BTB ++#define __TLB_BTB TLB_BTB ++#else ++#define __TLB_BTB 0 ++#endif ++ ++#ifdef CONFIG_CPU_FA_WB_DISABLE ++#define __TLB_WB 0 ++#else ++#define __TLB_WB TLB_WB ++#endif ++ ++/* Fix buggy CPU which doesn't invalidate Dcache properly */ ++#ifdef CONFIG_CPU_FA520 ++#define __TLB_DINVAL TLB_DINVAL ++#elif defined(CONFIG_CPU_FA526) ++//#define __TLB_DINVAL TLB_DINVAL ++#define __TLB_DINVAL 0 ++#else ++#define __TLB_DINVAL 0 ++#endif ++ ++#define fa_tlb_flags (__TLB_WB | __TLB_BTB | __TLB_DINVAL | TLB_DCLEAN | \ ++ TLB_V4_U_FULL | TLB_V4_U_PAGE) ++ ++#ifdef CONFIG_CPU_TLB_FA ++# define fa_possible_flags fa_tlb_flags ++# define fa_always_flags fa_tlb_flags ++# ifdef _TLB ++# define MULTI_TLB 1 ++# else ++# define _TLB fa ++# endif ++#else ++# define fa_possible_flags 0 ++# define fa_always_flags (-1UL) ++#endif ++ + #define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_I_PAGE | TLB_V4_D_PAGE) +@@ -246,12 +287,14 @@ + v4_possible_flags | \ + v4wbi_possible_flags | \ + v4wb_possible_flags | \ ++ fa_possible_flags | \ + v6wbi_possible_flags) + + #define always_tlb_flags (v3_always_flags & \ + v4_always_flags & \ + v4wbi_always_flags & \ + v4wb_always_flags & \ ++ fa_always_flags & \ + v6wbi_always_flags) + + #define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) +@@ -261,6 +304,9 @@ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + ++ if (tlb_flag(TLB_DINVAL)) ++ asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero)); ++ + if (tlb_flag(TLB_WB)) + dsb(); + +@@ -281,6 +327,13 @@ + dsb(); + isb(); + } ++ ++ if (tlb_flag(TLB_BTB)) ++ { ++ asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero)); ++ asm("mov r0, r0" : : ); ++ asm("mov r0, r0" : : ); ++ } + } + + static inline void local_flush_tlb_mm(struct mm_struct *mm) +@@ -289,6 +342,9 @@ + const int asid = ASID(mm); + const unsigned int __tlb_flag = __cpu_tlb_flags; + ++ if (tlb_flag(TLB_DINVAL)) ++ asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero)); ++ + if (tlb_flag(TLB_WB)) + dsb(); + +@@ -317,6 +373,14 @@ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + } ++ ++ if (tlb_flag(TLB_BTB)) ++ { ++ asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero)); ++ asm("mov r0, r0" : : ); ++ asm("mov r0, r0" : : ); ++ } ++ + } + + static inline void +@@ -327,6 +391,9 @@ + + uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); + ++ if (tlb_flag(TLB_DINVAL)) ++ asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero)); // clean & invalidate data cache all ++ + if (tlb_flag(TLB_WB)) + dsb(); + +@@ -357,6 +424,13 @@ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + } ++ ++ if (tlb_flag(TLB_BTB)) ++ { ++ asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero)); ++ asm("mov r0, r0" : : ); ++ asm("mov r0, r0" : : ); ++ } + } + + static inline void local_flush_tlb_kernel_page(unsigned long kaddr) +@@ -366,6 +440,9 @@ + + kaddr &= PAGE_MASK; + ++ if (tlb_flag(TLB_DINVAL)) ++ asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero)); ++ + if (tlb_flag(TLB_WB)) + dsb(); + +@@ -386,6 +463,12 @@ + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V6_I_PAGE)) + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); ++ if (tlb_flag(TLB_BTB)) ++ { ++ asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero)); ++ asm("mov r0, r0" : : ); ++ asm("mov r0, r0" : : ); ++ } + + if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | + TLB_V6_I_PAGE | TLB_V6_D_PAGE | +@@ -412,6 +495,7 @@ + */ + static inline void flush_pmd_entry(pmd_t *pmd) + { ++ const unsigned int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_DCLEAN)) +@@ -419,15 +503,30 @@ + : : "r" (pmd) : "cc"); + if (tlb_flag(TLB_WB)) + dsb(); ++ ++ if (tlb_flag(TLB_BTB)) // Luke Lee 05/16/2005 ++ { ++ asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero)); ++ asm("mov r0, r0" : : ); ++ asm("mov r0, r0" : : ); ++ } + } + + static inline void clean_pmd_entry(pmd_t *pmd) + { ++ const unsigned int zero = 0; // Luke Lee 05/16/2005 ins 1 + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_DCLEAN)) + asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" + : : "r" (pmd) : "cc"); ++ ++ if (tlb_flag(TLB_BTB)) // Luke Lee 05/16/2005 ++ { ++ asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero)); ++ asm("mov r0, r0" : : ); ++ asm("mov r0, r0" : : ); ++ } + } + + #undef tlb_flag +--- a/include/asm-arm/xor.h ++++ b/include/asm-arm/xor.h +@@ -139,3 +139,18 @@ + xor_speed(&xor_block_8regs); \ + xor_speed(&xor_block_32regs); \ + } while (0) ++ ++#ifdef CONFIG_GEMINI_XOR_ACCE ++#include <asm/arch/xor.h> ++static struct xor_block_template xor_block_gemini = { ++ .name = "gemini xor acceleration", ++ .do_2 = xor_gemini_2, ++ .do_3 = xor_gemini_3, ++ .do_4 = xor_gemini_4, ++ .do_5 = xor_gemini_5,}; ++#undef XOR_TRY_TEMPLATES ++#define XOR_TRY_TEMPLATES \ ++ do { \ ++ xor_speed(&xor_block_gemini); \ ++ } while (0) ++#endif +--- a/include/linux/apm_bios.h ++++ b/include/linux/apm_bios.h +@@ -217,4 +217,24 @@ + #define APM_IOC_STANDBY _IO('A', 1) + #define APM_IOC_SUSPEND _IO('A', 2) + ++// add by jason for power control ++struct pwc_ioctl_data { ++ unsigned int action; // sword struct ++ unsigned int data; // stand shutdown time for PWC_SET_SHUT_TIME ++ // stand shutdown source for PWC_WAIT_BTN ++}; ++ ++#define POWEROFF 0x01 ++#define RESTORE_DEFAULT 0x02 ++#define SYSTEM_REBOOT 0x04 ++ ++#define PWR_SRC_CIR 0x10 ++#define PWR_SRC_RTC 0x20 ++#define PWR_SRC_BTN 0x40 ++ ++#define PWC_IOCTL_BASE 'A' // use linux APM ioctl ++#define PWC_SET_SHUT_TIME _IOW('A', 16, struct pwc_ioctl_data) ++#define PWC_WAIT_BTN _IOR('A', 17, struct pwc_ioctl_data) ++#define PWC_SHUTDOWN _IO ('A', 18) ++ + #endif /* LINUX_APM_H */ +--- a/kernel/time.c ++++ b/kernel/time.c +@@ -76,6 +76,7 @@ + * why not move it into the appropriate arch directory (for those + * architectures that need it). + */ ++extern void rtc_set_time_second(unsigned int second); + + asmlinkage long sys_stime(time_t __user *tptr) + { +@@ -87,6 +88,10 @@ + + tv.tv_nsec = 0; + ++#ifdef CONFIG_SL2312_RTC ++ rtc_set_time_second(tv.tv_sec); ++#endif ++ + err = security_settime(&tv, NULL); + if (err) + return err; |