--- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -220,6 +220,9 @@ config ARCH_EP93XX 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-ep93xx/Kconfig" 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 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 @@ if ALIGNMENT_TRAP || !CPU_CP15_MMU 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 @@ source "drivers/block/Kconfig" 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_ARM920T) :=-mtune=arm9 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 @@ endif 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 @@ ifeq ($(CONFIG_ARCH_SHARK),y) 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 +#include + + .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 @@ start: .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 @@ __armv7_mmu_cache_on: 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 @@ proc_types: @ 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 @@ __armv7_mmu_cache_off: 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 @@ __armv4_mpu_cache_flush: 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 @@ static void putstr(const char *ptr); #include #ifdef CONFIG_DEBUG_ICEDCC - +#include "it8712.h" #ifdef CONFIG_CPU_V6 static void icedcc_putc(int ch) @@ -69,6 +69,7 @@ static void icedcc_putc(int ch) #define flush() do { } while (0) #endif +#if 0 static void putstr(const char *ptr) { char c; @@ -81,11 +82,36 @@ static void putstr(const char *ptr) 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 @@ ulg 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 @@ decompress_kernel(ulg output_start, ulg 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 @@ int main() 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 #include #include +#include +#include #include #include --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -40,6 +40,8 @@ #include #include +extern int fixup_irq(unsigned int irq); + /* * No architecture-specific irq_finish function defined in arm/arch/irqs.h. */ @@ -111,8 +113,11 @@ static struct irq_desc bad_irq_desc = { 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 arm_machine_restart(char mode) 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 @@ __setup("reboot=", reboot_setup); 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 @@ static int __init timer_init_sysfs(void) 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 +#include + +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + + +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;iSRAM_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 "); +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 +* +*/ +#include +#include +//#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PCI +#include +#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 +#include +#include +#include +#include +#include +#include + +#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 +#include +#include + +#include +#include +#include +#include +#include + +#include + +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +//#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 +#include +#include +#include +#include +#include "asm/arch/sl2312.h" +#include "asm/arch/irqs.h" +#include +#include +#include + +/* + * 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 +#include +#include +#include +#include +#include "asm/arch/sl2312.h" +#include "asm/arch/irqs.h" +#include +#include +#include + +/* + * 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 +#include +#include +#include +#include +#include +#include "asm/arch/sl2312.h" +#include "asm/arch/irqs.h" +#include +#include + +/* + * 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 +#include +#include +#include +#include +#include +#include +#define TIMER_TYPE (volatile unsigned int*) +#include +// #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 + * + * Contributors:Sanders + Jason Lee + * + * + * Maintainer: Jason Lee + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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:%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;ifunc_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 @@ config CPU_ARM926T 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_VIVT 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_V4WB 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 CPU_CP15_MPU 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_SIZE 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_V4WT) += cache-v4 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_COPY_V6) += copypage-v6 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_V4WB) += tlb-v4wb.o 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_ARM925T) += proc-arm925 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 +#include +#include +#include +#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<= 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 +#include +#include + + .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 #include +#include #include "mm.h" @@ -252,6 +253,11 @@ bootmem_init_node(int node, int initrd_n 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#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 @@ karo ARCH_KARO KARO 190 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 --- /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 +#include + + + .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 + +#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< + * + * 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 + +#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 +#include +#include + +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 +#include +#include +#include +//#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 + +#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 + +//#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 + * + * 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 +#include + +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 + +#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 +#include +#include +#include + +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 + +#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 @@ extern struct cpu_tlb_fns cpu_tlb; 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 @@ static inline void local_flush_tlb_all(v 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 @@ static inline void local_flush_tlb_all(v 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 @@ static inline void local_flush_tlb_mm(st 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 @@ static inline void local_flush_tlb_mm(st 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 @@ local_flush_tlb_page(struct vm_area_stru 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 @@ local_flush_tlb_page(struct vm_area_stru 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 @@ static inline void local_flush_tlb_kerne 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 @@ static inline void local_flush_tlb_kerne 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 local_flush_tlb_kerne */ 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 @@ static inline void flush_pmd_entry(pmd_t : : "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 @@ static struct xor_block_template xor_blo xor_speed(&xor_block_8regs); \ xor_speed(&xor_block_32regs); \ } while (0) + +#ifdef CONFIG_GEMINI_XOR_ACCE +#include +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 @@ extern struct apm_info apm_info; #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 @@ asmlinkage long sys_time(time_t __user * * 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 @@ asmlinkage long sys_stime(time_t __user 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;