From e50d64097b6e63278789ee3a4394d127bd6e4254 Mon Sep 17 00:00:00 2001 From: Assaf Hoffman Date: Tue, 23 Oct 2007 15:14:41 -0400 Subject: [ARM] Marvell Feroceon CPU core support The Feroceon is a family of independent ARMv5TE compliant CPU core implementations, supporting a variable depth pipeline and out-of-order execution. The Feroceon is configurable with VFP support, and the later models in the series are superscalar with up to two instructions per clock cycle. This patch adds the initial low-level cache/TLB handling for this core. Signed-off-by: Assaf Hoffman Reviewed-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/Kconfig | 2 +- arch/arm/mm/Kconfig | 16 +- arch/arm/mm/Makefile | 1 + arch/arm/mm/proc-feroceon.S | 479 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 495 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mm/proc-feroceon.S (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a04f507e7f2c..fae3f164218f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -951,7 +951,7 @@ config FPE_FASTFPE config VFP bool "VFP-format floating point maths" - depends on CPU_V6 || CPU_ARM926T + depends on CPU_V6 || CPU_ARM926T || CPU_FEROCEON help Say Y to include VFP support code in the kernel. This is needed if your hardware includes a VFP unit. diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 7868f4dc1d00..378fb744abe2 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -342,6 +342,18 @@ config CPU_XSC3 select CPU_TLB_V4WBI if MMU select IO_36 +# Feroceon +config CPU_FEROCEON + bool + depends on ARCH_ORION + default y + select CPU_32v5 + select CPU_ABRT_EV5T + select CPU_CACHE_VIVT + select CPU_CP15_MMU + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU + # ARMv6 config CPU_V6 bool "Support ARM V6 processor" @@ -538,7 +550,7 @@ comment "Processor Features" config ARM_THUMB bool "Support Thumb user binaries" - depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7 + depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7 || CPU_FEROCEON default y help Say Y if you want to include kernel support for running user space @@ -600,7 +612,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_FEROCEON) && !CPU_DCACHE_DISABLE default y if CPU_ARM925T help Say Y here to use the data cache in writethrough mode. Unless you diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 762702765fc3..44536a0b995a 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_CPU_SA110) += proc-sa110.o obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o +obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o obj-$(CONFIG_CPU_V6) += proc-v6.o obj-$(CONFIG_CPU_V7) += proc-v7.o diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S new file mode 100644 index 000000000000..8ad341af7906 --- /dev/null +++ b/arch/arm/mm/proc-feroceon.S @@ -0,0 +1,479 @@ +/* + * linux/arch/arm/mm/proc-feroceon.S: MMU functions for Feroceon + * + * Heavily based on proc-arm926.S + * Maintainer: Assaf Hoffman + * + * 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 "proc-macros.S" + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define CACHE_DLIMIT 16384 + +/* + * the cache line size of the I and D cache + */ +#define CACHE_DLINESIZE 32 + + .text +/* + * cpu_feroceon_proc_init() + */ +ENTRY(cpu_feroceon_proc_init) + mov pc, lr + +/* + * cpu_feroceon_proc_fin() + */ +ENTRY(cpu_feroceon_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl feroceon_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 + ldmfd sp!, {pc} + +/* + * cpu_feroceon_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 5 +ENTRY(cpu_feroceon_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_feroceon_do_idle() + * + * Called with IRQs disabled + */ + .align 10 +ENTRY(cpu_feroceon_do_idle) + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* + * flush_user_cache_all() + * + * Clean and invalidate all cache entries in a particular + * address space. + */ +ENTRY(feroceon_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(feroceon_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate + bne 1b +#endif + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the + * specified address range. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags describing address space + */ +ENTRY(feroceon_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bgt __flush_whole_cache +1: tst r2, #VM_EXEC +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#else + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#endif + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(feroceon_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(feroceon_coherent_user_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + 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(feroceon_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + 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 + * + * (same as v4wb) + */ +ENTRY(feroceon_dma_inv_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + tst r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +#endif + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(feroceon_dma_clean_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(feroceon_dma_flush_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry +#else + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(feroceon_cache_fns) + .long feroceon_flush_kern_cache_all + .long feroceon_flush_user_cache_all + .long feroceon_flush_user_cache_range + .long feroceon_coherent_kern_range + .long feroceon_coherent_user_range + .long feroceon_flush_kern_dcache_page + .long feroceon_dma_inv_range + .long feroceon_dma_clean_range + .long feroceon_dma_flush_range + +ENTRY(cpu_feroceon_dcache_clean_area) +#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 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_feroceon_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_feroceon_switch_mm) +#ifdef CONFIG_MMU + mov ip, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +@ && 'Clean & Invalidate whole DCache' +1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate + bne 1b +#endif + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif + mov pc, lr + +/* + * cpu_feroceon_set_pte_ext(ptep, pte, ext) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_feroceon_set_pte_ext) +#ifdef CONFIG_MMU + 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? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif + mov pc, lr + + __INIT + + .type __feroceon_setup, #function +__feroceon_setup: + 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 +#ifdef CONFIG_MMU + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif + + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #4 @ disable write-back on caches explicitly + mcr p15, 7, r0, c15, c0, 0 +#endif + + adr r5, feroceon_crval + ldmia r5, {r5, r6} + mrc p15, 0, r0, c1, c0 @ get control register v4 + bic r0, r0, r5 + orr r0, r0, r6 +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x4000 @ .1.. .... .... .... +#endif + mov pc, lr + .size __feroceon_setup, . - __feroceon_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * .011 0001 ..11 0101 + * + */ + .type feroceon_crval, #object +feroceon_crval: + crval clear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134 + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type feroceon_processor_functions, #object +feroceon_processor_functions: + .word v5t_early_abort + .word cpu_feroceon_proc_init + .word cpu_feroceon_proc_fin + .word cpu_feroceon_reset + .word cpu_feroceon_do_idle + .word cpu_feroceon_dcache_clean_area + .word cpu_feroceon_switch_mm + .word cpu_feroceon_set_pte_ext + .size feroceon_processor_functions, . - feroceon_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5te" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_feroceon_name, #object +cpu_feroceon_name: + .asciz "Feroceon" + .size cpu_feroceon_name, . - cpu_feroceon_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + + .type __feroceon_proc_info,#object +__feroceon_proc_info: + .long 0x56055310 + .long 0xfffffff0 + .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 __feroceon_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_feroceon_name + .long feroceon_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns + .long feroceon_cache_fns + .size __feroceon_proc_info, . - __feroceon_proc_info -- cgit v1.2.3 From 15754bf98ff564e8bb5296c7f5e67bc59b5700aa Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 31 Oct 2007 15:15:29 -0400 Subject: [ARM] add ARMv5TEJ aware cache flush method to compressed/head.S The default ARMv4 method consisting of reading through some memory area isn't compatible with the cache replacement policy of some ARMv5TEJ compatible cache implementations. It is also a bit wasteful when a dedicated instruction can do the needed work optimally. It is hard to tell if all ARMv5TEJ cores will support the used CP15 instruction, but at least all those implementations Linux currently knows about (ARM926 and ARM1026) do support it. Tested on an OMAP1610 H2 target. Signed-off-by: Nicolas Pitre Tested-by: George G. Davis Acked-by: Russell King --- arch/arm/boot/compressed/head.S | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 5cac46a19bb7..2073bf080523 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -641,7 +641,7 @@ proc_types: .word 0x000f0000 b __armv4_mmu_cache_on b __armv4_mmu_cache_off - b __armv4_mmu_cache_flush + b __armv5tej_mmu_cache_flush .word 0x0007b000 @ ARMv6 .word 0x000ff000 @@ -821,6 +821,13 @@ iflush: mcr p15, 0, r10, c7, c10, 4 @ drain WB mov pc, lr +__armv5tej_mmu_cache_flush: +1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache + bne 1b + mcr p15, 0, r0, c7, c5, 0 @ flush I cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + __armv4_mmu_cache_flush: mov r2, #64*1024 @ default: 32K dcache size (*2) mov r11, #32 @ default: 32 byte line size -- cgit v1.2.3 From 3ebb5a2b44b02bddd5fbf0f29d71f1df6146c2c3 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 31 Oct 2007 15:31:48 -0400 Subject: [ARM] add Feroceon support to compressed/head.S The cache replacement policy on the Feroceon core doesn't guarantee that reading through a linear chunk of memory flushes the entire cache. This is however what the default method for ARMv5TE cores does. Although the Feroceon is an ARMv5TE core, it implements the same cache handling instructions as the ARMv5TEJ cores, and must use it for proper cache flush. Signed-off-by: Nicolas Pitre Acked-by: Russell King --- arch/arm/boot/compressed/head.S | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 2073bf080523..3c2c8f2a1dc4 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -623,6 +623,12 @@ proc_types: b __armv4_mmu_cache_off b __armv4_mmu_cache_flush + .word 0x56055310 @ Feroceon + .word 0xfffffff0 + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off + b __armv5tej_mmu_cache_flush + @ These match on the architecture ID .word 0x00020000 @ ARMv4T -- cgit v1.2.3 From d910a0aa21c9c6e824744d0139bbe6a9ae676e2d Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 6 Nov 2007 10:35:40 +0200 Subject: [ARM] Feroceon: support old cores with ARM926 ID This enables the usage of some old Feroceon cores for which the CPU ID is equal to the ARM926 ID. Relevant for Feroceon-1850 and old Feroceon-2850. Signed-off-by: Tzachi Perelstein Signed-off-by: Nicolas Pitre Acked-by: Russell King --- arch/arm/mm/Kconfig | 9 +++++++++ arch/arm/mm/proc-feroceon.S | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 378fb744abe2..9cdc74f94b11 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -354,6 +354,15 @@ config CPU_FEROCEON select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU +config CPU_FEROCEON_OLD_ID + bool "Accept early Feroceon cores with an ARM926 ID" + depends on CPU_FEROCEON && !CPU_ARM926T + default y + help + This enables the usage of some old Feroceon cores + for which the CPU ID is equal to the ARM926 ID. + Relevant for Feroceon-1850 and early Feroceon-2850. + # ARMv6 config CPU_V6 bool "Support ARM V6 processor" diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index 8ad341af7906..fa0dc7e6f0ea 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -453,6 +453,33 @@ cpu_feroceon_name: .section ".proc.info.init", #alloc, #execinstr +#ifdef CONFIG_CPU_FEROCEON_OLD_ID + .type __feroceon_old_id_proc_info,#object +__feroceon_old_id_proc_info: + .long 0x41069260 + .long 0xfffffff0 + .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 __feroceon_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_feroceon_name + .long feroceon_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns + .long feroceon_cache_fns + .size __feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info +#endif + .type __feroceon_proc_info,#object __feroceon_proc_info: .long 0x56055310 -- cgit v1.2.3 From 585cf17561d3174a745bec49c422c1a621c95fc4 Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 23 Oct 2007 15:14:41 -0400 Subject: [ARM] basic support for the Marvell Orion SoC family The Marvell Orion is a family of ARM SoCs with a DDR/DDR2 memory controller, 10/100/1000 ethernet MAC, and USB 2.0 interfaces, and, depending on the specific model, PCI-E interface, PCI-X interface, SATA controllers, crypto unit, SPI interface, SDIO interface, device bus, NAND controller, DMA engine and/or XOR engine. This contains the basic structure and architecture register definitions. Signed-off-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/Kconfig | 8 ++++++ arch/arm/Makefile | 1 + arch/arm/mach-orion/Kconfig | 7 ++++++ arch/arm/mach-orion/Makefile | 1 + arch/arm/mach-orion/Makefile.boot | 3 +++ arch/arm/mach-orion/common.c | 53 +++++++++++++++++++++++++++++++++++++++ arch/arm/mach-orion/common.h | 9 +++++++ 7 files changed, 82 insertions(+) create mode 100644 arch/arm/mach-orion/Kconfig create mode 100644 arch/arm/mach-orion/Makefile create mode 100644 arch/arm/mach-orion/Makefile.boot create mode 100644 arch/arm/mach-orion/common.c create mode 100644 arch/arm/mach-orion/common.h (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fae3f164218f..036239150ff8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -333,6 +333,12 @@ config ARCH_MXC help Support for Freescale MXC/iMX-based family of processors +config ARCH_ORION + bool "Marvell Orion" + depends on MMU + help + Support for Marvell Orion System on Chip family. + config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" help @@ -441,6 +447,8 @@ source "arch/arm/mach-omap1/Kconfig" source "arch/arm/mach-omap2/Kconfig" +source "arch/arm/mach-orion/Kconfig" + source "arch/arm/plat-s3c24xx/Kconfig" source "arch/arm/plat-s3c/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 35e56c99ad1d..2daa278149e0 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -139,6 +139,7 @@ endif machine-$(CONFIG_ARCH_KS8695) := ks8695 incdir-$(CONFIG_ARCH_MXC) := mxc machine-$(CONFIG_ARCH_MX3) := mx3 + machine-$(CONFIG_ARCH_ORION) := orion ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. diff --git a/arch/arm/mach-orion/Kconfig b/arch/arm/mach-orion/Kconfig new file mode 100644 index 000000000000..c2af02125ce9 --- /dev/null +++ b/arch/arm/mach-orion/Kconfig @@ -0,0 +1,7 @@ +if ARCH_ORION + +menu "Orion Implementations" + +endmenu + +endif diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile new file mode 100644 index 000000000000..69eb30187738 --- /dev/null +++ b/arch/arm/mach-orion/Makefile @@ -0,0 +1 @@ +obj-y += common.o diff --git a/arch/arm/mach-orion/Makefile.boot b/arch/arm/mach-orion/Makefile.boot new file mode 100644 index 000000000000..67039c3e0c48 --- /dev/null +++ b/arch/arm/mach-orion/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c new file mode 100644 index 000000000000..e04f3f07cac0 --- /dev/null +++ b/arch/arm/mach-orion/common.c @@ -0,0 +1,53 @@ +/* + * arch/arm/mach-orion/common.c + * + * Core functions for Marvell Orion System On Chip + * + * Maintainer: Tzachi Perelstein + * + * 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 +#include +#include +#include +#include "common.h" + +/***************************************************************************** + * I/O Address Mapping + ****************************************************************************/ +static struct map_desc orion_io_desc[] __initdata = { + { + .virtual = ORION_REGS_BASE, + .pfn = __phys_to_pfn(ORION_REGS_BASE), + .length = ORION_REGS_SIZE, + .type = MT_DEVICE + }, + { + .virtual = ORION_PCIE_IO_BASE, + .pfn = __phys_to_pfn(ORION_PCIE_IO_BASE), + .length = ORION_PCIE_IO_SIZE, + .type = MT_DEVICE + }, + { + .virtual = ORION_PCI_IO_BASE, + .pfn = __phys_to_pfn(ORION_PCI_IO_BASE), + .length = ORION_PCI_IO_SIZE, + .type = MT_DEVICE + }, + { + .virtual = ORION_PCIE_WA_BASE, + .pfn = __phys_to_pfn(ORION_PCIE_WA_BASE), + .length = ORION_PCIE_WA_SIZE, + .type = MT_DEVICE + }, +}; + +void __init orion_map_io(void) +{ + iotable_init(orion_io_desc, ARRAY_SIZE(orion_io_desc)); +} diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h new file mode 100644 index 000000000000..224b44618a72 --- /dev/null +++ b/arch/arm/mach-orion/common.h @@ -0,0 +1,9 @@ +#ifndef __ARCH_ORION_COMMON_H__ +#define __ARCH_ORION_COMMON_H__ + +/* + * Basic Orion init functions used early by machine-setup. + */ +void __init orion_map_io(void); + +#endif /* __ARCH_ORION_COMMON_H__ */ -- cgit v1.2.3 From 038ee0832ee1b1e2bd2be4599cd535ea9aaaf658 Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 23 Oct 2007 15:14:42 -0400 Subject: [ARM] Orion: PCI support This patch adds support for PCI and PCI-E controllers in the Orion, Orion-NAS and Orion2. Signed-off-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-orion/Makefile | 2 +- arch/arm/mach-orion/common.h | 17 ++ arch/arm/mach-orion/pci.c | 557 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 576 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-orion/pci.c (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 036239150ff8..37aa3c606c0c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -336,6 +336,7 @@ config ARCH_MXC config ARCH_ORION bool "Marvell Orion" depends on MMU + select PCI help Support for Marvell Orion System on Chip family. diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index 69eb30187738..2937f05b868e 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -1 +1 @@ -obj-y += common.o +obj-y += common.o pci.o diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h index 224b44618a72..02d0fec44a40 100644 --- a/arch/arm/mach-orion/common.h +++ b/arch/arm/mach-orion/common.h @@ -6,4 +6,21 @@ */ void __init orion_map_io(void); +/* + * Shared code used internally by other Orion core functions. + * (/mach-orion/pci.c) + */ + +struct pci_sys_data; +struct pci_bus; + +void orion_pcie_id(u32 *dev, u32 *rev); +u32 orion_pcie_local_bus_nr(void); +u32 orion_pci_local_bus_nr(void); +u32 orion_pci_local_dev_nr(void); +int orion_pci_sys_setup(int nr, struct pci_sys_data *sys); +struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); +int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 *val); +int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 val); + #endif /* __ARCH_ORION_COMMON_H__ */ diff --git a/arch/arm/mach-orion/pci.c b/arch/arm/mach-orion/pci.c new file mode 100644 index 000000000000..cf569c647112 --- /dev/null +++ b/arch/arm/mach-orion/pci.c @@ -0,0 +1,557 @@ +/* + * arch/arm/mach-orion/pci.c + * + * PCI and PCIE functions for Marvell Orion System On Chip + * + * Maintainer: Tzachi Perelstein + * + * 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 +#include +#include "common.h" + +/***************************************************************************** + * Orion has one PCIE controller and one PCI controller. + * + * Note1: The local PCIE bus number is '0'. The local PCI bus number + * follows the scanned PCIE bridged busses, if any. + * + * Note2: It is possible for PCI/PCIE agents to access many subsystem's + * space, by configuring BARs and Address Decode Windows, e.g. flashes on + * device bus, Orion registers, etc. However this code only enable the + * access to DDR banks. + ****************************************************************************/ + + +/***************************************************************************** + * PCIE controller + ****************************************************************************/ +#define PCIE_CTRL ORION_PCIE_REG(0x1a00) +#define PCIE_STAT ORION_PCIE_REG(0x1a04) +#define PCIE_DEV_ID ORION_PCIE_REG(0x0000) +#define PCIE_CMD_STAT ORION_PCIE_REG(0x0004) +#define PCIE_DEV_REV ORION_PCIE_REG(0x0008) +#define PCIE_MASK ORION_PCIE_REG(0x1910) +#define PCIE_CONF_ADDR ORION_PCIE_REG(0x18f8) +#define PCIE_CONF_DATA ORION_PCIE_REG(0x18fc) + +/* + * PCIE_STAT bits + */ +#define PCIE_STAT_LINK_DOWN 1 +#define PCIE_STAT_BUS_OFFS 8 +#define PCIE_STAT_BUS_MASK (0xff << PCIE_STAT_BUS_OFFS) +#define PCIE_STAT_DEV_OFFS 20 +#define PCIE_STAT_DEV_MASK (0x1f << PCIE_STAT_DEV_OFFS) + +/* + * PCIE_CONF_ADDR bits + */ +#define PCIE_CONF_REG(r) ((((r) & 0xf00) << 24) | ((r) & 0xfc)) +#define PCIE_CONF_FUNC(f) (((f) & 0x3) << 8) +#define PCIE_CONF_DEV(d) (((d) & 0x1f) << 11) +#define PCIE_CONF_BUS(b) (((b) & 0xff) << 16) +#define PCIE_CONF_ADDR_EN (1 << 31) + +/* + * PCIE config cycles are done by programming the PCIE_CONF_ADDR register + * and then reading the PCIE_CONF_DATA register. Need to make sure these + * transactions are atomic. + */ +static DEFINE_SPINLOCK(orion_pcie_lock); + +void orion_pcie_id(u32 *dev, u32 *rev) +{ + *dev = orion_read(PCIE_DEV_ID) >> 16; + *rev = orion_read(PCIE_DEV_REV) & 0xff; +} + +u32 orion_pcie_local_bus_nr(void) +{ + u32 stat = orion_read(PCIE_STAT); + return((stat & PCIE_STAT_BUS_MASK) >> PCIE_STAT_BUS_OFFS); +} + +static u32 orion_pcie_local_dev_nr(void) +{ + u32 stat = orion_read(PCIE_STAT); + return((stat & PCIE_STAT_DEV_MASK) >> PCIE_STAT_DEV_OFFS); +} + +static u32 orion_pcie_no_link(void) +{ + u32 stat = orion_read(PCIE_STAT); + return(stat & PCIE_STAT_LINK_DOWN); +} + +static void orion_pcie_set_bus_nr(int nr) +{ + orion_clrbits(PCIE_STAT, PCIE_STAT_BUS_MASK); + orion_setbits(PCIE_STAT, nr << PCIE_STAT_BUS_OFFS); +} + +static void orion_pcie_master_slave_enable(void) +{ + orion_setbits(PCIE_CMD_STAT, PCI_COMMAND_MASTER | + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY); +} + +static void orion_pcie_enable_interrupts(void) +{ + /* + * Enable interrupts lines + * INTA[24] INTB[25] INTC[26] INTD[27] + */ + orion_setbits(PCIE_MASK, 0xf<<24); +} + +static int orion_pcie_valid_config(u32 bus, u32 dev) +{ + /* + * Don't go out when trying to access -- + * 1. our own device + * 2. where there's no device connected (no link) + * 3. nonexisting devices on local bus + */ + + if ((orion_pcie_local_bus_nr() == bus) && + (orion_pcie_local_dev_nr() == dev)) + return 0; + + if (orion_pcie_no_link()) + return 0; + + if (bus == orion_pcie_local_bus_nr()) + if (((orion_pcie_local_dev_nr() == 0) && (dev != 1)) || + ((orion_pcie_local_dev_nr() != 0) && (dev != 0))) + return 0; + + return 1; +} + +static int orion_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, + int size, u32 *val) +{ + unsigned long flags; + unsigned int dev, rev, pcie_addr; + + if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) { + *val = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + spin_lock_irqsave(&orion_pcie_lock, flags); + + orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) | + PCIE_CONF_DEV(PCI_SLOT(devfn)) | + PCIE_CONF_FUNC(PCI_FUNC(devfn)) | + PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN); + + orion_pcie_id(&dev, &rev); + if (dev == MV88F5182_DEV_ID) { + /* extended register space */ + pcie_addr = ORION_PCIE_WA_BASE; + pcie_addr |= PCIE_CONF_BUS(bus->number) | + PCIE_CONF_DEV(PCI_SLOT(devfn)) | + PCIE_CONF_FUNC(PCI_FUNC(devfn)) | + PCIE_CONF_REG(where); + *val = orion_read(pcie_addr); + } else + *val = orion_read(PCIE_CONF_DATA); + + if (size == 1) + *val = (*val >> (8*(where & 0x3))) & 0xff; + else if (size == 2) + *val = (*val >> (8*(where & 0x3))) & 0xffff; + + spin_unlock_irqrestore(&orion_pcie_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + + +static int orion_pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, + int size, u32 val) +{ + unsigned long flags; + int ret; + + if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + spin_lock_irqsave(&orion_pcie_lock, flags); + + ret = PCIBIOS_SUCCESSFUL; + + orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) | + PCIE_CONF_DEV(PCI_SLOT(devfn)) | + PCIE_CONF_FUNC(PCI_FUNC(devfn)) | + PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN); + + if (size == 4) { + __raw_writel(val, PCIE_CONF_DATA); + } else if (size == 2) { + __raw_writew(val, PCIE_CONF_DATA + (where & 0x3)); + } else if (size == 1) { + __raw_writeb(val, PCIE_CONF_DATA + (where & 0x3)); + } else { + ret = PCIBIOS_BAD_REGISTER_NUMBER; + } + + spin_unlock_irqrestore(&orion_pcie_lock, flags); + + return ret; +} + +struct pci_ops orion_pcie_ops = { + .read = orion_pcie_rd_conf, + .write = orion_pcie_wr_conf, +}; + + +static int orion_pcie_setup(struct pci_sys_data *sys) +{ + struct resource *res; + + /* + * Master + Slave enable + */ + orion_pcie_master_slave_enable(); + + /* + * Enable interrupts lines A-D + */ + orion_pcie_enable_interrupts(); + + /* + * Request resource + */ + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("orion_pci_setup unable to alloc resources"); + + /* + * IORESOURCE_IO + */ + res[0].name = "PCI-EX I/O Space"; + res[0].flags = IORESOURCE_IO; + res[0].start = ORION_PCIE_IO_REMAP; + res[0].end = res[0].start + ORION_PCIE_IO_SIZE - 1; + if (request_resource(&ioport_resource, &res[0])) + panic("Request PCIE IO resource failed\n"); + sys->resource[0] = &res[0]; + + /* + * IORESOURCE_MEM + */ + res[1].name = "PCI-EX Memory Space"; + res[1].flags = IORESOURCE_MEM; + res[1].start = ORION_PCIE_MEM_BASE; + res[1].end = res[1].start + ORION_PCIE_MEM_SIZE - 1; + if (request_resource(&iomem_resource, &res[1])) + panic("Request PCIE Memory resource failed\n"); + sys->resource[1] = &res[1]; + + sys->resource[2] = NULL; + sys->io_offset = 0; + + return 1; +} + +/***************************************************************************** + * PCI controller + ****************************************************************************/ +#define PCI_MODE ORION_PCI_REG(0xd00) +#define PCI_CMD ORION_PCI_REG(0xc00) +#define PCI_P2P_CONF ORION_PCI_REG(0x1d14) +#define PCI_CONF_ADDR ORION_PCI_REG(0xc78) +#define PCI_CONF_DATA ORION_PCI_REG(0xc7c) + +/* + * PCI_MODE bits + */ +#define PCI_MODE_64BIT (1 << 2) +#define PCI_MODE_PCIX ((1 << 4) | (1 << 5)) + +/* + * PCI_CMD bits + */ +#define PCI_CMD_HOST_REORDER (1 << 29) + +/* + * PCI_P2P_CONF bits + */ +#define PCI_P2P_BUS_OFFS 16 +#define PCI_P2P_BUS_MASK (0xff << PCI_P2P_BUS_OFFS) +#define PCI_P2P_DEV_OFFS 24 +#define PCI_P2P_DEV_MASK (0x1f << PCI_P2P_DEV_OFFS) + +/* + * PCI_CONF_ADDR bits + */ +#define PCI_CONF_REG(reg) ((reg) & 0xfc) +#define PCI_CONF_FUNC(func) (((func) & 0x3) << 8) +#define PCI_CONF_DEV(dev) (((dev) & 0x1f) << 11) +#define PCI_CONF_BUS(bus) (((bus) & 0xff) << 16) +#define PCI_CONF_ADDR_EN (1 << 31) + +/* + * Internal configuration space + */ +#define PCI_CONF_FUNC_STAT_CMD 0 +#define PCI_CONF_REG_STAT_CMD 4 +#define PCIX_STAT 0x64 +#define PCIX_STAT_BUS_OFFS 8 +#define PCIX_STAT_BUS_MASK (0xff << PCIX_STAT_BUS_OFFS) + +/* + * PCI config cycles are done by programming the PCI_CONF_ADDR register + * and then reading the PCI_CONF_DATA register. Need to make sure these + * transactions are atomic. + */ +static DEFINE_SPINLOCK(orion_pci_lock); + +u32 orion_pci_local_bus_nr(void) +{ + u32 conf = orion_read(PCI_P2P_CONF); + return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS); +} + +u32 orion_pci_local_dev_nr(void) +{ + u32 conf = orion_read(PCI_P2P_CONF); + return((conf & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS); +} + +int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, + u32 where, u32 size, u32 *val) +{ + unsigned long flags; + spin_lock_irqsave(&orion_pci_lock, flags); + + orion_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) | + PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | + PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN); + + *val = orion_read(PCI_CONF_DATA); + + if (size == 1) + *val = (*val >> (8*(where & 0x3))) & 0xff; + else if (size == 2) + *val = (*val >> (8*(where & 0x3))) & 0xffff; + + spin_unlock_irqrestore(&orion_pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, + u32 where, u32 size, u32 val) +{ + unsigned long flags; + int ret = PCIBIOS_SUCCESSFUL; + + spin_lock_irqsave(&orion_pci_lock, flags); + + orion_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) | + PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | + PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN); + + if (size == 4) { + __raw_writel(val, PCI_CONF_DATA); + } else if (size == 2) { + __raw_writew(val, PCI_CONF_DATA + (where & 0x3)); + } else if (size == 1) { + __raw_writeb(val, PCI_CONF_DATA + (where & 0x3)); + } else { + ret = PCIBIOS_BAD_REGISTER_NUMBER; + } + + spin_unlock_irqrestore(&orion_pci_lock, flags); + + return ret; +} + +static int orion_pci_rd_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 *val) +{ + /* + * Don't go out for local device + */ + if ((orion_pci_local_bus_nr() == bus->number) && + (orion_pci_local_dev_nr() == PCI_SLOT(devfn))) { + *val = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + return orion_pci_hw_rd_conf(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where, size, val); +} + +static int orion_pci_wr_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 val) +{ + /* + * Don't go out for local device + */ + if ((orion_pci_local_bus_nr() == bus->number) && + (orion_pci_local_dev_nr() == PCI_SLOT(devfn))) + return PCIBIOS_DEVICE_NOT_FOUND; + + return orion_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where, size, val); +} + +struct pci_ops orion_pci_ops = { + .read = orion_pci_rd_conf, + .write = orion_pci_wr_conf, +}; + +static void orion_pci_set_bus_nr(int nr) +{ + u32 p2p = orion_read(PCI_P2P_CONF); + + if (orion_read(PCI_MODE) & PCI_MODE_PCIX) { + /* + * PCI-X mode + */ + u32 pcix_status, bus, dev; + bus = (p2p & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS; + dev = (p2p & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS; + orion_pci_hw_rd_conf(bus, dev, 0, PCIX_STAT, 4, &pcix_status); + pcix_status &= ~PCIX_STAT_BUS_MASK; + pcix_status |= (nr << PCIX_STAT_BUS_OFFS); + orion_pci_hw_wr_conf(bus, dev, 0, PCIX_STAT, 4, pcix_status); + } else { + /* + * PCI Conventional mode + */ + p2p &= ~PCI_P2P_BUS_MASK; + p2p |= (nr << PCI_P2P_BUS_OFFS); + orion_write(PCI_P2P_CONF, p2p); + } +} + +static void orion_pci_master_slave_enable(void) +{ + u32 bus_nr, dev_nr, func, reg, val; + + bus_nr = orion_pci_local_bus_nr(); + dev_nr = orion_pci_local_dev_nr(); + func = PCI_CONF_FUNC_STAT_CMD; + reg = PCI_CONF_REG_STAT_CMD; + orion_pci_hw_rd_conf(bus_nr, dev_nr, func, reg, 4, &val); + val |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + orion_pci_hw_wr_conf(bus_nr, dev_nr, func, reg, 4, val | 0x7); +} + +static int orion_pci_setup(struct pci_sys_data *sys) +{ + struct resource *res; + + /* + * Master + Slave enable + */ + orion_pci_master_slave_enable(); + + /* + * Force ordering + */ + orion_setbits(PCI_CMD, PCI_CMD_HOST_REORDER); + + /* + * Request resources + */ + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("orion_pci_setup unable to alloc resources"); + + /* + * IORESOURCE_IO + */ + res[0].name = "PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + res[0].start = ORION_PCI_IO_REMAP; + res[0].end = res[0].start + ORION_PCI_IO_SIZE - 1; + if (request_resource(&ioport_resource, &res[0])) + panic("Request PCI IO resource failed\n"); + sys->resource[0] = &res[0]; + + /* + * IORESOURCE_MEM + */ + res[1].name = "PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + res[1].start = ORION_PCI_MEM_BASE; + res[1].end = res[1].start + ORION_PCI_MEM_SIZE - 1; + if (request_resource(&iomem_resource, &res[1])) + panic("Request PCI Memory resource failed\n"); + sys->resource[1] = &res[1]; + + sys->resource[2] = NULL; + sys->io_offset = 0; + + return 1; +} + + +/***************************************************************************** + * General PCIE + PCI + ****************************************************************************/ +int orion_pci_sys_setup(int nr, struct pci_sys_data *sys) +{ + int ret = 0; + + if (nr == 0) { + /* + * PCIE setup + */ + orion_pcie_set_bus_nr(0); + ret = orion_pcie_setup(sys); + } else if (nr == 1) { + /* + * PCI setup + */ + ret = orion_pci_setup(sys); + } + + return ret; +} + +struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys) +{ + struct pci_ops *ops; + struct pci_bus *bus; + + + if (nr == 0) { + u32 pci_bus; + /* + * PCIE scan + */ + ops = &orion_pcie_ops; + bus = pci_scan_bus(sys->busnr, ops, sys); + /* + * Set local PCI bus number to follow PCIE bridges (if any) + */ + pci_bus = bus->number + bus->subordinate - bus->secondary + 1; + orion_pci_set_bus_nr(pci_bus); + } else if (nr == 1) { + /* + * PCI scan + */ + ops = &orion_pci_ops; + bus = pci_scan_bus(sys->busnr, ops, sys); + } else { + BUG(); + bus = NULL; + } + + return bus; +} -- cgit v1.2.3 From c67de5b3c0bb48ac56f14928e11f1f7d76add26f Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 23 Oct 2007 15:14:42 -0400 Subject: [ARM] Orion: programable address map support The Orion has fully programable address map. There's a separate address map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIE, USB, Gigabit Ethernet, DMA/XOR engines, etc. Signed-off-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek --- arch/arm/mach-orion/Makefile | 2 +- arch/arm/mach-orion/addr-map.c | 482 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-orion/common.c | 51 +++++ arch/arm/mach-orion/common.h | 30 +++ 4 files changed, 564 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-orion/addr-map.c (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index 2937f05b868e..1d4b5570067e 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -1 +1 @@ -obj-y += common.o pci.o +obj-y += common.o addr-map.o pci.o diff --git a/arch/arm/mach-orion/addr-map.c b/arch/arm/mach-orion/addr-map.c new file mode 100644 index 000000000000..ff6e010bccb2 --- /dev/null +++ b/arch/arm/mach-orion/addr-map.c @@ -0,0 +1,482 @@ +/* + * arch/arm/mach-orion/addr-map.c + * + * Address map functions for Marvell Orion System On Chip + * + * Maintainer: Tzachi Perelstein + * + * 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 +#include +#include "common.h" + +/* + * The Orion has fully programable address map. There's a separate address + * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIE, USB, + * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own + * address decode windows that allow it to access any of the Orion resources. + * + * CPU address decoding -- + * Linux assumes that it is the boot loader that already setup the access to + * DDR and internal registers. + * Setup access to PCI and PCI-E IO/MEM space is issued by core.c. + * Setup access to various devices located on the device bus interface (e.g. + * flashes, RTC, etc) should be issued by machine-setup.c according to + * specific board population (by using orion_setup_cpu_win()). + * + * Non-CPU Masters address decoding -- + * Unlike the CPU, we setup the access from Orion's master interfaces to DDR + * banks only (the typical use case). + * Setup access for each master to DDR is issued by common.c. + * + * Note: although orion_setbits() and orion_clrbits() are not atomic + * no locking is necessary here since code in this file is only called + * at boot time when there is no concurrency issues. + */ + +/* + * Generic Address Decode Windows bit settings + */ +#define TARGET_DDR 0 +#define TARGET_PCI 3 +#define TARGET_PCIE 4 +#define TARGET_DEV_BUS 1 +#define ATTR_DDR_CS(n) (((n) ==0) ? 0xe : \ + ((n) == 1) ? 0xd : \ + ((n) == 2) ? 0xb : \ + ((n) == 3) ? 0x7 : 0xf) +#define ATTR_PCIE_MEM 0x59 +#define ATTR_PCIE_IO 0x51 +#define ATTR_PCI_MEM 0x59 +#define ATTR_PCI_IO 0x51 +#define ATTR_DEV_CS0 0x1e +#define ATTR_DEV_CS1 0x1d +#define ATTR_DEV_CS2 0x1b +#define ATTR_DEV_BOOT 0xf +#define WIN_EN 1 + +/* + * Helpers to get DDR banks info + */ +#define DDR_BASE_CS(n) ORION_DDR_REG(0x1500 + ((n) * 8)) +#define DDR_SIZE_CS(n) ORION_DDR_REG(0x1504 + ((n) * 8)) +#define DDR_MAX_CS 4 +#define DDR_REG_TO_SIZE(reg) (((reg) | 0xffffff) + 1) +#define DDR_REG_TO_BASE(reg) ((reg) & 0xff000000) +#define DDR_BANK_EN 1 + +/* + * CPU Address Decode Windows registers + */ +#define CPU_WIN_CTRL(n) ORION_BRIDGE_REG(0x000 | ((n) << 4)) +#define CPU_WIN_BASE(n) ORION_BRIDGE_REG(0x004 | ((n) << 4)) +#define CPU_WIN_REMAP_LO(n) ORION_BRIDGE_REG(0x008 | ((n) << 4)) +#define CPU_WIN_REMAP_HI(n) ORION_BRIDGE_REG(0x00c | ((n) << 4)) +#define CPU_MAX_WIN 8 + +/* + * Use this CPU address decode windows allocation + */ +#define CPU_WIN_PCIE_IO 0 +#define CPU_WIN_PCI_IO 1 +#define CPU_WIN_PCIE_MEM 2 +#define CPU_WIN_PCI_MEM 3 +#define CPU_WIN_DEV_BOOT 4 +#define CPU_WIN_DEV_CS0 5 +#define CPU_WIN_DEV_CS1 6 +#define CPU_WIN_DEV_CS2 7 + +/* + * PCIE Address Decode Windows registers + */ +#define PCIE_BAR_CTRL(n) ORION_PCIE_REG(0x1804 + ((n - 1) * 4)) +#define PCIE_BAR_LO(n) ORION_PCIE_REG(0x0010 + ((n) * 8)) +#define PCIE_BAR_HI(n) ORION_PCIE_REG(0x0014 + ((n) * 8)) +#define PCIE_WIN_CTRL(n) ORION_PCIE_REG(0x1820 + ((n) << 4)) +#define PCIE_WIN_BASE(n) ORION_PCIE_REG(0x1824 + ((n) << 4)) +#define PCIE_WIN_REMAP(n) ORION_PCIE_REG(0x182c + ((n) << 4)) +#define PCIE_DEFWIN_CTRL ORION_PCIE_REG(0x18b0) +#define PCIE_EXPROM_WIN_CTRL ORION_PCIE_REG(0x18c0) +#define PCIE_EXPROM_WIN_REMP ORION_PCIE_REG(0x18c4) +#define PCIE_MAX_BARS 3 +#define PCIE_MAX_WINS 5 + +/* + * Use PCIE BAR '1' for all DDR banks + */ +#define PCIE_DRAM_BAR 1 + +/* + * PCI Address Decode Windows registers + */ +#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION_PCI_REG(0xc08) : \ + ((n) == 1) ? ORION_PCI_REG(0xd08) : \ + ((n) == 2) ? ORION_PCI_REG(0xc0c) : \ + ((n) == 3) ? ORION_PCI_REG(0xd0c) : 0) +#define PCI_BAR_REMAP_DDR_CS(n) (((n) ==0) ? ORION_PCI_REG(0xc48) : \ + ((n) == 1) ? ORION_PCI_REG(0xd48) : \ + ((n) == 2) ? ORION_PCI_REG(0xc4c) : \ + ((n) == 3) ? ORION_PCI_REG(0xd4c) : 0) +#define PCI_BAR_ENABLE ORION_PCI_REG(0xc3c) +#define PCI_CTRL_BASE_LO(n) ORION_PCI_REG(0x1e00 | ((n) << 4)) +#define PCI_CTRL_BASE_HI(n) ORION_PCI_REG(0x1e04 | ((n) << 4)) +#define PCI_CTRL_SIZE(n) ORION_PCI_REG(0x1e08 | ((n) << 4)) +#define PCI_ADDR_DECODE_CTRL ORION_PCI_REG(0xd3c) + +/* + * PCI configuration heleprs for BAR settings + */ +#define PCI_CONF_FUNC_BAR_CS(n) ((n) >> 1) +#define PCI_CONF_REG_BAR_LO_CS(n) (((n) & 1) ? 0x18 : 0x10) +#define PCI_CONF_REG_BAR_HI_CS(n) (((n) & 1) ? 0x1c : 0x14) + +/* + * Gigabit Ethernet Address Decode Windows registers + */ +#define ETH_WIN_BASE(win) ORION_ETH_REG(0x200 + ((win) * 8)) +#define ETH_WIN_SIZE(win) ORION_ETH_REG(0x204 + ((win) * 8)) +#define ETH_WIN_REMAP(win) ORION_ETH_REG(0x280 + ((win) * 4)) +#define ETH_WIN_EN ORION_ETH_REG(0x290) +#define ETH_WIN_PROT ORION_ETH_REG(0x294) +#define ETH_MAX_WIN 6 +#define ETH_MAX_REMAP_WIN 4 + +/* + * USB Address Decode Windows registers + */ +#define USB_WIN_CTRL(i, w) ((i == 0) ? ORION_USB0_REG(0x320 + ((w) << 4)) \ + : ORION_USB1_REG(0x320 + ((w) << 4))) +#define USB_WIN_BASE(i, w) ((i == 0) ? ORION_USB0_REG(0x324 + ((w) << 4)) \ + : ORION_USB1_REG(0x324 + ((w) << 4))) +#define USB_MAX_WIN 4 + +/* + * SATA Address Decode Windows registers + */ +#define SATA_WIN_CTRL(win) ORION_SATA_REG(0x30 + ((win) * 0x10)) +#define SATA_WIN_BASE(win) ORION_SATA_REG(0x34 + ((win) * 0x10)) +#define SATA_MAX_WIN 4 + +static int __init orion_cpu_win_can_remap(u32 win) +{ + u32 dev, rev; + + orion_pcie_id(&dev, &rev); + if ((dev == MV88F5281_DEV_ID && win < 4) || (dev == MV88F5182_DEV_ID && win < 2)) + return 1; + + return 0; +} + +void __init orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap) +{ + u32 win, attr, ctrl; + + switch (target) { + case ORION_PCIE_IO: + target = TARGET_PCIE; + attr = ATTR_PCIE_IO; + win = CPU_WIN_PCIE_IO; + break; + case ORION_PCI_IO: + target = TARGET_PCI; + attr = ATTR_PCI_IO; + win = CPU_WIN_PCI_IO; + break; + case ORION_PCIE_MEM: + target = TARGET_PCIE; + attr = ATTR_PCIE_MEM; + win = CPU_WIN_PCIE_MEM; + break; + case ORION_PCI_MEM: + target = TARGET_PCI; + attr = ATTR_PCI_MEM; + win = CPU_WIN_PCI_MEM; + break; + case ORION_DEV_BOOT: + target = TARGET_DEV_BUS; + attr = ATTR_DEV_BOOT; + win = CPU_WIN_DEV_BOOT; + break; + case ORION_DEV0: + target = TARGET_DEV_BUS; + attr = ATTR_DEV_CS0; + win = CPU_WIN_DEV_CS0; + break; + case ORION_DEV1: + target = TARGET_DEV_BUS; + attr = ATTR_DEV_CS1; + win = CPU_WIN_DEV_CS1; + break; + case ORION_DEV2: + target = TARGET_DEV_BUS; + attr = ATTR_DEV_CS2; + win = CPU_WIN_DEV_CS2; + break; + case ORION_DDR: + case ORION_REGS: + /* + * Must be mapped by bootloader. + */ + default: + target = attr = win = -1; + BUG(); + } + + base &= 0xffff0000; + ctrl = (((size - 1) & 0xffff0000) | (attr << 8) | + (target << 4) | WIN_EN); + + orion_write(CPU_WIN_BASE(win), base); + orion_write(CPU_WIN_CTRL(win), ctrl); + + if (orion_cpu_win_can_remap(win)) { + if (remap >= 0) { + orion_write(CPU_WIN_REMAP_LO(win), remap & 0xffff0000); + orion_write(CPU_WIN_REMAP_HI(win), 0); + } else { + orion_write(CPU_WIN_REMAP_LO(win), base); + orion_write(CPU_WIN_REMAP_HI(win), 0); + } + } +} + +void __init orion_setup_cpu_wins(void) +{ + int i; + + /* + * First, disable and clear windows + */ + for (i = 0; i < CPU_MAX_WIN; i++) { + orion_write(CPU_WIN_BASE(i), 0); + orion_write(CPU_WIN_CTRL(i), 0); + if (orion_cpu_win_can_remap(i)) { + orion_write(CPU_WIN_REMAP_LO(i), 0); + orion_write(CPU_WIN_REMAP_HI(i), 0); + } + } + + /* + * Setup windows for PCI+PCIE IO+MAM space + */ + orion_setup_cpu_win(ORION_PCIE_IO, ORION_PCIE_IO_BASE, + ORION_PCIE_IO_SIZE, ORION_PCIE_IO_REMAP); + orion_setup_cpu_win(ORION_PCI_IO, ORION_PCI_IO_BASE, + ORION_PCI_IO_SIZE, ORION_PCI_IO_REMAP); + orion_setup_cpu_win(ORION_PCIE_MEM, ORION_PCIE_MEM_BASE, + ORION_PCIE_MEM_SIZE, -1); + orion_setup_cpu_win(ORION_PCI_MEM, ORION_PCI_MEM_BASE, + ORION_PCI_MEM_SIZE, -1); +} + +/* + * Setup PCIE BARs and Address Decode Wins: + * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks + * WIN[0-3] -> DRAM bank[0-3] + */ +void __init orion_setup_pcie_wins(void) +{ + u32 base, size, i; + + /* + * First, disable and clear BARs and windows + */ + for (i = 1; i < PCIE_MAX_BARS; i++) { + orion_write(PCIE_BAR_CTRL(i), 0); + orion_write(PCIE_BAR_LO(i), 0); + orion_write(PCIE_BAR_HI(i), 0); + } + + for (i = 0; i < PCIE_MAX_WINS; i++) { + orion_write(PCIE_WIN_CTRL(i), 0); + orion_write(PCIE_WIN_BASE(i), 0); + orion_write(PCIE_WIN_REMAP(i), 0); + } + + /* + * Setup windows for DDR banks. Count total DDR size on the fly. + */ + base = DDR_REG_TO_BASE(orion_read(DDR_BASE_CS(0))); + size = 0; + for (i = 0; i < DDR_MAX_CS; i++) { + u32 bank_base, bank_size; + bank_size = orion_read(DDR_SIZE_CS(i)); + bank_base = orion_read(DDR_BASE_CS(i)); + if (bank_size & DDR_BANK_EN) { + bank_size = DDR_REG_TO_SIZE(bank_size); + bank_base = DDR_REG_TO_BASE(bank_base); + orion_write(PCIE_WIN_BASE(i), bank_base & 0xffff0000); + orion_write(PCIE_WIN_REMAP(i), 0); + orion_write(PCIE_WIN_CTRL(i), + ((bank_size-1) & 0xffff0000) | + (ATTR_DDR_CS(i) << 8) | + (TARGET_DDR << 4) | + (PCIE_DRAM_BAR << 1) | WIN_EN); + size += bank_size; + } + } + + /* + * Setup BAR[1] to all DRAM banks + */ + orion_write(PCIE_BAR_LO(PCIE_DRAM_BAR), base & 0xffff0000); + orion_write(PCIE_BAR_HI(PCIE_DRAM_BAR), 0); + orion_write(PCIE_BAR_CTRL(PCIE_DRAM_BAR), + ((size - 1) & 0xffff0000) | WIN_EN); +} + +void __init orion_setup_pci_wins(void) +{ + u32 base, size, i; + + /* + * First, disable windows + */ + orion_write(PCI_BAR_ENABLE, 0xffffffff); + + /* + * Setup windows for DDR banks. + */ + for (i = 0; i < DDR_MAX_CS; i++) { + base = orion_read(DDR_BASE_CS(i)); + size = orion_read(DDR_SIZE_CS(i)); + if (size & DDR_BANK_EN) { + u32 bus, dev, func, reg, val; + size = DDR_REG_TO_SIZE(size); + base = DDR_REG_TO_BASE(base); + bus = orion_pci_local_bus_nr(); + dev = orion_pci_local_dev_nr(); + func = PCI_CONF_FUNC_BAR_CS(i); + reg = PCI_CONF_REG_BAR_LO_CS(i); + orion_pci_hw_rd_conf(bus, dev, func, reg, 4, &val); + orion_pci_hw_wr_conf(bus, dev, func, reg, 4, + (base & 0xfffff000) | (val & 0xfff)); + reg = PCI_CONF_REG_BAR_HI_CS(i); + orion_pci_hw_wr_conf(bus, dev, func, reg, 4, 0); + orion_write(PCI_BAR_SIZE_DDR_CS(i), + (size - 1) & 0xfffff000); + orion_write(PCI_BAR_REMAP_DDR_CS(i), + base & 0xfffff000); + orion_clrbits(PCI_BAR_ENABLE, (1 << i)); + } + } + + /* + * Disable automatic update of address remaping when writing to BARs + */ + orion_setbits(PCI_ADDR_DECODE_CTRL, 1); +} + +void __init orion_setup_usb_wins(void) +{ + int i; + u32 usb_if, dev, rev; + u32 max_usb_if = 1; + + orion_pcie_id(&dev, &rev); + if (dev == MV88F5182_DEV_ID) + max_usb_if = 2; + + for (usb_if = 0; usb_if < max_usb_if; usb_if++) { + /* + * First, disable and clear windows + */ + for (i = 0; i < USB_MAX_WIN; i++) { + orion_write(USB_WIN_BASE(usb_if, i), 0); + orion_write(USB_WIN_CTRL(usb_if, i), 0); + } + + /* + * Setup windows for DDR banks. + */ + for (i = 0; i < DDR_MAX_CS; i++) { + u32 base, size; + size = orion_read(DDR_SIZE_CS(i)); + base = orion_read(DDR_BASE_CS(i)); + if (size & DDR_BANK_EN) { + base = DDR_REG_TO_BASE(base); + size = DDR_REG_TO_SIZE(size); + orion_write(USB_WIN_CTRL(usb_if, i), + ((size-1) & 0xffff0000) | + (ATTR_DDR_CS(i) << 8) | + (TARGET_DDR << 4) | WIN_EN); + orion_write(USB_WIN_BASE(usb_if, i), + base & 0xffff0000); + } + } + } +} + +void __init orion_setup_eth_wins(void) +{ + int i; + + /* + * First, disable and clear windows + */ + for (i = 0; i < ETH_MAX_WIN; i++) { + orion_write(ETH_WIN_BASE(i), 0); + orion_write(ETH_WIN_SIZE(i), 0); + orion_setbits(ETH_WIN_EN, 1 << i); + orion_clrbits(ETH_WIN_PROT, 0x3 << (i * 2)); + if (i < ETH_MAX_REMAP_WIN) + orion_write(ETH_WIN_REMAP(i), 0); + } + + /* + * Setup windows for DDR banks. + */ + for (i = 0; i < DDR_MAX_CS; i++) { + u32 base, size; + size = orion_read(DDR_SIZE_CS(i)); + base = orion_read(DDR_BASE_CS(i)); + if (size & DDR_BANK_EN) { + base = DDR_REG_TO_BASE(base); + size = DDR_REG_TO_SIZE(size); + orion_write(ETH_WIN_SIZE(i), (size-1) & 0xffff0000); + orion_write(ETH_WIN_BASE(i), (base & 0xffff0000) | + (ATTR_DDR_CS(i) << 8) | + TARGET_DDR); + orion_clrbits(ETH_WIN_EN, 1 << i); + orion_setbits(ETH_WIN_PROT, 0x3 << (i * 2)); + } + } +} + +void __init orion_setup_sata_wins(void) +{ + int i; + + /* + * First, disable and clear windows + */ + for (i = 0; i < SATA_MAX_WIN; i++) { + orion_write(SATA_WIN_BASE(i), 0); + orion_write(SATA_WIN_CTRL(i), 0); + } + + /* + * Setup windows for DDR banks. + */ + for (i = 0; i < DDR_MAX_CS; i++) { + u32 base, size; + size = orion_read(DDR_SIZE_CS(i)); + base = orion_read(DDR_BASE_CS(i)); + if (size & DDR_BANK_EN) { + base = DDR_REG_TO_BASE(base); + size = DDR_REG_TO_SIZE(size); + orion_write(SATA_WIN_CTRL(i), + ((size-1) & 0xffff0000) | + (ATTR_DDR_CS(i) << 8) | + (TARGET_DDR << 4) | WIN_EN); + orion_write(SATA_WIN_BASE(i), + base & 0xffff0000); + } + } +} diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c index e04f3f07cac0..69363cbcb63b 100644 --- a/arch/arm/mach-orion/common.c +++ b/arch/arm/mach-orion/common.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "common.h" @@ -51,3 +52,53 @@ void __init orion_map_io(void) { iotable_init(orion_io_desc, ARRAY_SIZE(orion_io_desc)); } + +/***************************************************************************** + * General + ****************************************************************************/ + +/* + * Identify device ID and rev from PCIE configuration header space '0'. + */ +static void orion_id(u32 *dev, u32 *rev, char **dev_name) +{ + orion_pcie_id(dev, rev); + + if (*dev == MV88F5281_DEV_ID) { + if (*rev == MV88F5281_REV_D2) { + *dev_name = "MV88F5281-D2"; + } else if (*rev == MV88F5281_REV_D1) { + *dev_name = "MV88F5281-D1"; + } else { + *dev_name = "MV88F5281-Rev-Unsupported"; + } + } else if (*dev == MV88F5182_DEV_ID) { + if (*rev == MV88F5182_REV_A2) { + *dev_name = "MV88F5182-A2"; + } else { + *dev_name = "MV88F5182-Rev-Unsupported"; + } + } else { + *dev_name = "Device-Unknown"; + } +} + +void __init orion_init(void) +{ + char *dev_name; + u32 dev, rev; + + orion_id(&dev, &rev, &dev_name); + printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, ORION_TCLK); + + /* + * Setup Orion address map + */ + orion_setup_cpu_wins(); + orion_setup_usb_wins(); + orion_setup_eth_wins(); + orion_setup_pci_wins(); + orion_setup_pcie_wins(); + if (dev == MV88F5182_DEV_ID) + orion_setup_sata_wins(); +} diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h index 02d0fec44a40..056043464ca1 100644 --- a/arch/arm/mach-orion/common.h +++ b/arch/arm/mach-orion/common.h @@ -4,7 +4,37 @@ /* * Basic Orion init functions used early by machine-setup. */ + void __init orion_map_io(void); +void __init orion_init(void); + +/* + * Enumerations and functions for Orion windows mapping. Used by Orion core + * functions to map its interfaces and by the machine-setup to map its on- + * board devices. Details in /mach-orion/addr-map.c + */ + +enum orion_target { + ORION_DEV_BOOT = 0, + ORION_DEV0, + ORION_DEV1, + ORION_DEV2, + ORION_PCIE_MEM, + ORION_PCIE_IO, + ORION_PCI_MEM, + ORION_PCI_IO, + ORION_DDR, + ORION_REGS, + ORION_MAX_TARGETS +}; + +void orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap); +void orion_setup_cpu_wins(void); +void orion_setup_eth_wins(void); +void orion_setup_usb_wins(void); +void orion_setup_pci_wins(void); +void orion_setup_pcie_wins(void); +void orion_setup_sata_wins(void); /* * Shared code used internally by other Orion core functions. -- cgit v1.2.3 From 01af72e4e36fba66cd7cfc2a628efee866c346d1 Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 23 Oct 2007 15:14:42 -0400 Subject: [ARM] Orion: GPIO support Signed-off-by: Tzachi Perelstein Signed-off-by: Nicolas Pitre Acked-by: David Brownell --- arch/arm/Kconfig | 1 + arch/arm/mach-orion/Makefile | 2 +- arch/arm/mach-orion/common.h | 8 ++ arch/arm/mach-orion/gpio.c | 206 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-orion/gpio.c (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 37aa3c606c0c..71e905ebcc05 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -337,6 +337,7 @@ config ARCH_ORION bool "Marvell Orion" depends on MMU select PCI + select GENERIC_GPIO help Support for Marvell Orion System on Chip family. diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index 1d4b5570067e..d6a6c86faafc 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -1 +1 @@ -obj-y += common.o addr-map.o pci.o +obj-y += common.o addr-map.o pci.o gpio.o diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h index 056043464ca1..a6a7af189b0e 100644 --- a/arch/arm/mach-orion/common.h +++ b/arch/arm/mach-orion/common.h @@ -53,4 +53,12 @@ struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 *val); int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 val); +/* + * Valid GPIO pins according to MPP setup, used by machine-setup. + * (/mach-orion/gpio.c). + */ + +void __init orion_gpio_set_valid_pins(u32 pins); +void gpio_display(void); /* debug */ + #endif /* __ARCH_ORION_COMMON_H__ */ diff --git a/arch/arm/mach-orion/gpio.c b/arch/arm/mach-orion/gpio.c new file mode 100644 index 000000000000..af8553ccd230 --- /dev/null +++ b/arch/arm/mach-orion/gpio.c @@ -0,0 +1,206 @@ +/* + * arch/arm/mach-orion/gpio.c + * + * GPIO functions for Marvell Orion System On Chip + * + * Maintainer: Tzachi Perelstein + * + * 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 +#include +#include +#include +#include +#include +#include "common.h" + +static DEFINE_SPINLOCK(gpio_lock); +static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)]; +static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */ + +void __init orion_gpio_set_valid_pins(u32 pins) +{ + gpio_valid[0] = pins; +} + +/* + * GENERIC_GPIO primitives + */ +int gpio_direction_input(unsigned pin) +{ + unsigned long flags; + + if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { + pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin); + return -EINVAL; + } + + spin_lock_irqsave(&gpio_lock, flags); + + /* + * Some callers might have not used the gpio_request(), + * so flag this pin as requested now. + */ + if (!gpio_label[pin]) + gpio_label[pin] = "?"; + + orion_setbits(GPIO_IO_CONF, 1 << pin); + + spin_unlock_irqrestore(&gpio_lock, flags); + return 0; +} +EXPORT_SYMBOL(gpio_direction_input); + +int gpio_direction_output(unsigned pin, int value) +{ + unsigned long flags; + int mask; + + if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { + pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin); + return -EINVAL; + } + + spin_lock_irqsave(&gpio_lock, flags); + + /* + * Some callers might have not used the gpio_request(), + * so flag this pin as requested now. + */ + if (!gpio_label[pin]) + gpio_label[pin] = "?"; + + mask = 1 << pin; + if (value) + orion_setbits(GPIO_OUT, mask); + else + orion_clrbits(GPIO_OUT, mask); + orion_clrbits(GPIO_IO_CONF, mask); + + spin_unlock_irqrestore(&gpio_lock, flags); + return 0; +} +EXPORT_SYMBOL(gpio_direction_output); + +int gpio_get_value(unsigned pin) +{ + int val, mask = 1 << pin; + + if (orion_read(GPIO_IO_CONF) & mask) + val = orion_read(GPIO_DATA_IN); + else + val = orion_read(GPIO_OUT); + + return val & mask; +} +EXPORT_SYMBOL(gpio_get_value); + +void gpio_set_value(unsigned pin, int value) +{ + unsigned long flags; + int mask = 1 << pin; + + spin_lock_irqsave(&gpio_lock, flags); + + if (value) + orion_setbits(GPIO_OUT, mask); + else + orion_clrbits(GPIO_OUT, mask); + + spin_unlock_irqrestore(&gpio_lock, flags); +} +EXPORT_SYMBOL(gpio_set_value); + +int gpio_request(unsigned pin, const char *label) +{ + int ret = 0; + unsigned long flags; + + if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { + pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin); + return -EINVAL; + } + + spin_lock_irqsave(&gpio_lock, flags); + + if (gpio_label[pin]) { + pr_debug("%s: GPIO %d already used as %s\n", + __FUNCTION__, pin, gpio_label[pin]); + ret = -EBUSY; + } else + gpio_label[pin] = label ? label : "?"; + + spin_unlock_irqrestore(&gpio_lock, flags); + return ret; +} +EXPORT_SYMBOL(gpio_request); + +void gpio_free(unsigned pin) +{ + if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { + pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin); + return; + } + + if (!gpio_label[pin]) + pr_warning("%s: GPIO %d already freed\n", __FUNCTION__, pin); + else + gpio_label[pin] = NULL; +} +EXPORT_SYMBOL(gpio_free); + +/* Debug helper */ +void gpio_display(void) +{ + int i; + + for (i = 0; i < GPIO_MAX; i++) { + printk(KERN_DEBUG "Pin-%d: ", i); + + if (!test_bit(i, gpio_valid)) { + printk("non-GPIO\n"); + } else if (!gpio_label[i]) { + printk("GPIO, free\n"); + } else { + printk("GPIO, used by %s, ", gpio_label[i]); + if (orion_read(GPIO_IO_CONF) & (1 << i)) { + printk("input, active %s, level %s, edge %s\n", + ((orion_read(GPIO_IN_POL) >> i) & 1) ? "low" : "high", + ((orion_read(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked", + ((orion_read(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked"); + } else { + printk("output, val=%d\n", (orion_read(GPIO_OUT) >> i) & 1); + } + } + } + + printk(KERN_DEBUG "MPP_0_7_CTRL (0x%08x) = 0x%08x\n", + MPP_0_7_CTRL, orion_read(MPP_0_7_CTRL)); + printk(KERN_DEBUG "MPP_8_15_CTRL (0x%08x) = 0x%08x\n", + MPP_8_15_CTRL, orion_read(MPP_8_15_CTRL)); + printk(KERN_DEBUG "MPP_16_19_CTRL (0x%08x) = 0x%08x\n", + MPP_16_19_CTRL, orion_read(MPP_16_19_CTRL)); + printk(KERN_DEBUG "MPP_DEV_CTRL (0x%08x) = 0x%08x\n", + MPP_DEV_CTRL, orion_read(MPP_DEV_CTRL)); + printk(KERN_DEBUG "GPIO_OUT (0x%08x) = 0x%08x\n", + GPIO_OUT, orion_read(GPIO_OUT)); + printk(KERN_DEBUG "GPIO_IO_CONF (0x%08x) = 0x%08x\n", + GPIO_IO_CONF, orion_read(GPIO_IO_CONF)); + printk(KERN_DEBUG "GPIO_BLINK_EN (0x%08x) = 0x%08x\n", + GPIO_BLINK_EN, orion_read(GPIO_BLINK_EN)); + printk(KERN_DEBUG "GPIO_IN_POL (0x%08x) = 0x%08x\n", + GPIO_IN_POL, orion_read(GPIO_IN_POL)); + printk(KERN_DEBUG "GPIO_DATA_IN (0x%08x) = 0x%08x\n", + GPIO_DATA_IN, orion_read(GPIO_DATA_IN)); + printk(KERN_DEBUG "GPIO_LEVEL_MASK (0x%08x) = 0x%08x\n", + GPIO_LEVEL_MASK, orion_read(GPIO_LEVEL_MASK)); + printk(KERN_DEBUG "GPIO_EDGE_CAUSE (0x%08x) = 0x%08x\n", + GPIO_EDGE_CAUSE, orion_read(GPIO_EDGE_CAUSE)); + printk(KERN_DEBUG "GPIO_EDGE_MASK (0x%08x) = 0x%08x\n", + GPIO_EDGE_MASK, orion_read(GPIO_EDGE_MASK)); +} -- cgit v1.2.3 From b11e9e020c8c6cdd7e7cc6d5178cce2ad0ac0784 Mon Sep 17 00:00:00 2001 From: Herbert Valerio Riedel Date: Thu, 29 Nov 2007 15:19:56 +0100 Subject: [ARM] Orion: provide GPIO method for enabling hardware assisted blinking This is a pre-requisite for implementing proper hardware accelerated GPIO LED flashing, and since we want proper locking, it's sensible to provide the orion specific orion_gpio_set_blink() implementation within mach-orion/gpio.c. The functions orion_gpio_set_blink() and gpio_set_value() implicitly turn off each others state. Signed-off-by: Herbert Valerio Riedel Acked-by: Tzachi Perelstein Acked-by: Nicolas Pitre Acked-by: Russell King --- arch/arm/mach-orion/gpio.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/gpio.c b/arch/arm/mach-orion/gpio.c index af8553ccd230..0418f5b1ebe7 100644 --- a/arch/arm/mach-orion/gpio.c +++ b/arch/arm/mach-orion/gpio.c @@ -76,6 +76,7 @@ int gpio_direction_output(unsigned pin, int value) gpio_label[pin] = "?"; mask = 1 << pin; + orion_clrbits(GPIO_BLINK_EN, mask); if (value) orion_setbits(GPIO_OUT, mask); else @@ -107,6 +108,7 @@ void gpio_set_value(unsigned pin, int value) spin_lock_irqsave(&gpio_lock, flags); + orion_clrbits(GPIO_BLINK_EN, mask); if (value) orion_setbits(GPIO_OUT, mask); else @@ -116,6 +118,23 @@ void gpio_set_value(unsigned pin, int value) } EXPORT_SYMBOL(gpio_set_value); +void orion_gpio_set_blink(unsigned pin, int blink) +{ + unsigned long flags; + int mask = 1 << pin; + + spin_lock_irqsave(&gpio_lock, flags); + + orion_clrbits(GPIO_OUT, mask); + if (blink) + orion_setbits(GPIO_BLINK_EN, mask); + else + orion_clrbits(GPIO_BLINK_EN, mask); + + spin_unlock_irqrestore(&gpio_lock, flags); +} +EXPORT_SYMBOL(orion_gpio_set_blink); + int gpio_request(unsigned pin, const char *label) { int ret = 0; -- cgit v1.2.3 From 3085de6a82821e3d227e8fae7403dc7a5dc27932 Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 23 Oct 2007 15:14:42 -0400 Subject: [ARM] Orion: IRQ support Signed-off-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/mach-orion/Makefile | 2 +- arch/arm/mach-orion/common.h | 1 + arch/arm/mach-orion/irq.c | 160 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-orion/irq.c (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index d6a6c86faafc..57d459a2090e 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -1 +1 @@ -obj-y += common.o addr-map.o pci.o gpio.o +obj-y += common.o addr-map.o pci.o gpio.o irq.o diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h index a6a7af189b0e..155371e1d672 100644 --- a/arch/arm/mach-orion/common.h +++ b/arch/arm/mach-orion/common.h @@ -6,6 +6,7 @@ */ void __init orion_map_io(void); +void __init orion_init_irq(void); void __init orion_init(void); /* diff --git a/arch/arm/mach-orion/irq.c b/arch/arm/mach-orion/irq.c new file mode 100644 index 000000000000..585a0fb06262 --- /dev/null +++ b/arch/arm/mach-orion/irq.c @@ -0,0 +1,160 @@ +/* + * arch/arm/mach-orion/irq.c + * + * Core IRQ functions for Marvell Orion System On Chip + * + * Maintainer: Tzachi Perelstein + * + * 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 +#include +#include +#include +#include "common.h" + +/***************************************************************************** + * Orion GPIO IRQ + ****************************************************************************/ +static void orion_gpio_irq_mask(u32 irq) +{ + int pin = irq_to_gpio(irq); + orion_clrbits(GPIO_LEVEL_MASK, 1 << pin); +} + +static void orion_gpio_irq_unmask(u32 irq) +{ + int pin = irq_to_gpio(irq); + orion_setbits(GPIO_LEVEL_MASK, 1 << pin); +} + +static int orion_gpio_set_irq_type(u32 irq, u32 type) +{ + int pin = irq_to_gpio(irq); + + if ((orion_read(GPIO_IO_CONF) & (1 << pin)) == 0) { + printk(KERN_ERR "orion_gpio_set_irq_type failed " + "(irq %d, pin %d).\n", irq, pin); + return -EINVAL; + } + + switch (type) { + case IRQT_HIGH: + orion_clrbits(GPIO_IN_POL, (1 << pin)); + break; + case IRQT_LOW: + orion_setbits(GPIO_IN_POL, (1 << pin)); + break; + default: + printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type); + return -EINVAL; + } + + return 0; +} + +static struct irq_chip orion_gpio_irq_chip = { + .name = "Orion-IRQ-GPIO", + .ack = orion_gpio_irq_mask, + .mask = orion_gpio_irq_mask, + .unmask = orion_gpio_irq_unmask, + .set_type = orion_gpio_set_irq_type, +}; + +static void orion_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + int i; + u32 cause, shift; + + BUG_ON(irq < IRQ_ORION_GPIO_0_7 || irq > IRQ_ORION_GPIO_24_31); + shift = (irq - IRQ_ORION_GPIO_0_7) * 8; + cause = orion_read(GPIO_EDGE_CAUSE) & orion_read(GPIO_LEVEL_MASK); + cause &= (0xff << shift); + + for (i = shift; i < shift + 8; i++) { + if (cause & (1 << i)) { + int gpio_irq = i + IRQ_ORION_GPIO_START; + if (gpio_irq > 0) { + desc = irq_desc + gpio_irq; + desc_handle_irq(gpio_irq, desc); + } else { + printk(KERN_ERR "orion_gpio_irq_handler error, " + "invalid irq %d\n", gpio_irq); + } + } + } +} + +static void __init orion_init_gpio_irq(void) +{ + int i; + + /* + * Mask and clear GPIO IRQ interrupts + */ + orion_write(GPIO_LEVEL_MASK, 0x0); + orion_write(GPIO_EDGE_CAUSE, 0x0); + + /* + * Register chained level handlers for GPIO IRQs + */ + for (i = IRQ_ORION_GPIO_START; i < NR_IRQS; i++) { + set_irq_chip(i, &orion_gpio_irq_chip); + set_irq_handler(i, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + } + set_irq_chained_handler(IRQ_ORION_GPIO_0_7, orion_gpio_irq_handler); + set_irq_chained_handler(IRQ_ORION_GPIO_8_15, orion_gpio_irq_handler); + set_irq_chained_handler(IRQ_ORION_GPIO_16_23, orion_gpio_irq_handler); + set_irq_chained_handler(IRQ_ORION_GPIO_24_31, orion_gpio_irq_handler); +} + +/***************************************************************************** + * Orion Main IRQ + ****************************************************************************/ +static void orion_main_irq_mask(u32 irq) +{ + orion_clrbits(MAIN_IRQ_MASK, 1 << irq); +} + +static void orion_main_irq_unmask(u32 irq) +{ + orion_setbits(MAIN_IRQ_MASK, 1 << irq); +} + +static struct irq_chip orion_main_irq_chip = { + .name = "Orion-IRQ-Main", + .ack = orion_main_irq_mask, + .mask = orion_main_irq_mask, + .unmask = orion_main_irq_unmask, +}; + +static void __init orion_init_main_irq(void) +{ + int i; + + /* + * Mask and clear Main IRQ interrupts + */ + orion_write(MAIN_IRQ_MASK, 0x0); + orion_write(MAIN_IRQ_CAUSE, 0x0); + + /* + * Register level handler for Main IRQs + */ + for (i = 0; i < IRQ_ORION_GPIO_START; i++) { + set_irq_chip(i, &orion_main_irq_chip); + set_irq_handler(i, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + } +} + +void __init orion_init_irq(void) +{ + orion_init_main_irq(); + orion_init_gpio_irq(); +} -- cgit v1.2.3 From f00666140cb84cd80276c9a874198874890d5733 Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Thu, 15 Nov 2007 10:57:48 +0200 Subject: [ARM] Orion edge GPIO IRQ support This patch adds support for Orion edge sensitive GPIO IRQs. Signed-off-by: Tzachi Perelstein Signed-off-by: Nicolas Pitre CC: Thomas Gleixner --- arch/arm/mach-orion/gpio.c | 2 +- arch/arm/mach-orion/irq.c | 119 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 101 insertions(+), 20 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/gpio.c b/arch/arm/mach-orion/gpio.c index 0418f5b1ebe7..d5f00c86d616 100644 --- a/arch/arm/mach-orion/gpio.c +++ b/arch/arm/mach-orion/gpio.c @@ -93,7 +93,7 @@ int gpio_get_value(unsigned pin) int val, mask = 1 << pin; if (orion_read(GPIO_IO_CONF) & mask) - val = orion_read(GPIO_DATA_IN); + val = orion_read(GPIO_DATA_IN) ^ orion_read(GPIO_IN_POL); else val = orion_read(GPIO_OUT); diff --git a/arch/arm/mach-orion/irq.c b/arch/arm/mach-orion/irq.c index 585a0fb06262..df7e12ad378b 100644 --- a/arch/arm/mach-orion/irq.c +++ b/arch/arm/mach-orion/irq.c @@ -19,22 +19,66 @@ /***************************************************************************** * Orion GPIO IRQ + * + * GPIO_IN_POL register controlls whether GPIO_DATA_IN will hold the same + * value of the line or the opposite value. + * + * Level IRQ handlers: DATA_IN is used directly as cause register. + * Interrupt are masked by LEVEL_MASK registers. + * Edge IRQ handlers: Change in DATA_IN are latched in EDGE_CAUSE. + * Interrupt are masked by EDGE_MASK registers. + * Both-edge handlers: Similar to regular Edge handlers, but also swaps + * the polarity to catch the next line transaction. + * This is a race condition that might not perfectly + * work on some use cases. + * + * Every eight GPIO lines are grouped (OR'ed) before going up to main + * cause register. + * + * EDGE cause mask + * data-in /--------| |-----| |----\ + * -----| |----- ---- to main cause reg + * X \----------------| |----/ + * polarity LEVEL mask + * ****************************************************************************/ +static void orion_gpio_irq_ack(u32 irq) +{ + int pin = irq_to_gpio(irq); + if (irq_desc[irq].status & IRQ_LEVEL) + /* + * Mask bit for level interrupt + */ + orion_clrbits(GPIO_LEVEL_MASK, 1 << pin); + else + /* + * Clear casue bit for egde interrupt + */ + orion_clrbits(GPIO_EDGE_CAUSE, 1 << pin); +} + static void orion_gpio_irq_mask(u32 irq) { int pin = irq_to_gpio(irq); - orion_clrbits(GPIO_LEVEL_MASK, 1 << pin); + if (irq_desc[irq].status & IRQ_LEVEL) + orion_clrbits(GPIO_LEVEL_MASK, 1 << pin); + else + orion_clrbits(GPIO_EDGE_MASK, 1 << pin); } static void orion_gpio_irq_unmask(u32 irq) { int pin = irq_to_gpio(irq); - orion_setbits(GPIO_LEVEL_MASK, 1 << pin); + if (irq_desc[irq].status & IRQ_LEVEL) + orion_setbits(GPIO_LEVEL_MASK, 1 << pin); + else + orion_setbits(GPIO_EDGE_MASK, 1 << pin); } static int orion_gpio_set_irq_type(u32 irq, u32 type) { int pin = irq_to_gpio(irq); + struct irq_desc *desc; if ((orion_read(GPIO_IO_CONF) & (1 << pin)) == 0) { printk(KERN_ERR "orion_gpio_set_irq_type failed " @@ -42,24 +86,56 @@ static int orion_gpio_set_irq_type(u32 irq, u32 type) return -EINVAL; } + desc = irq_desc + irq; + switch (type) { case IRQT_HIGH: + desc->handle_irq = handle_level_irq; + desc->status |= IRQ_LEVEL; orion_clrbits(GPIO_IN_POL, (1 << pin)); break; case IRQT_LOW: + desc->handle_irq = handle_level_irq; + desc->status |= IRQ_LEVEL; + orion_setbits(GPIO_IN_POL, (1 << pin)); + break; + case IRQT_RISING: + desc->handle_irq = handle_edge_irq; + desc->status &= ~IRQ_LEVEL; + orion_clrbits(GPIO_IN_POL, (1 << pin)); + break; + case IRQT_FALLING: + desc->handle_irq = handle_edge_irq; + desc->status &= ~IRQ_LEVEL; orion_setbits(GPIO_IN_POL, (1 << pin)); + break; + case IRQT_BOTHEDGE: + desc->handle_irq = handle_edge_irq; + desc->status &= ~IRQ_LEVEL; + /* + * set initial polarity based on current input level + */ + if ((orion_read(GPIO_IN_POL) ^ orion_read(GPIO_DATA_IN)) + & (1 << pin)) + orion_setbits(GPIO_IN_POL, (1 << pin)); /* falling */ + else + orion_clrbits(GPIO_IN_POL, (1 << pin)); /* rising */ + break; default: printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type); return -EINVAL; } + desc->status &= ~IRQ_TYPE_SENSE_MASK; + desc->status |= type & IRQ_TYPE_SENSE_MASK; + return 0; } static struct irq_chip orion_gpio_irq_chip = { .name = "Orion-IRQ-GPIO", - .ack = orion_gpio_irq_mask, + .ack = orion_gpio_irq_ack, .mask = orion_gpio_irq_mask, .unmask = orion_gpio_irq_unmask, .set_type = orion_gpio_set_irq_type, @@ -67,24 +143,24 @@ static struct irq_chip orion_gpio_irq_chip = { static void orion_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { - int i; - u32 cause, shift; + u32 cause, offs, pin; BUG_ON(irq < IRQ_ORION_GPIO_0_7 || irq > IRQ_ORION_GPIO_24_31); - shift = (irq - IRQ_ORION_GPIO_0_7) * 8; - cause = orion_read(GPIO_EDGE_CAUSE) & orion_read(GPIO_LEVEL_MASK); - cause &= (0xff << shift); - - for (i = shift; i < shift + 8; i++) { - if (cause & (1 << i)) { - int gpio_irq = i + IRQ_ORION_GPIO_START; - if (gpio_irq > 0) { - desc = irq_desc + gpio_irq; - desc_handle_irq(gpio_irq, desc); - } else { - printk(KERN_ERR "orion_gpio_irq_handler error, " - "invalid irq %d\n", gpio_irq); + offs = (irq - IRQ_ORION_GPIO_0_7) * 8; + cause = (orion_read(GPIO_DATA_IN) & orion_read(GPIO_LEVEL_MASK)) | + (orion_read(GPIO_EDGE_CAUSE) & orion_read(GPIO_EDGE_MASK)); + + for (pin = offs; pin < offs + 8; pin++) { + if (cause & (1 << pin)) { + irq = gpio_to_irq(pin); + desc = irq_desc + irq; + if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) { + /* Swap polarity (race with GPIO line) */ + u32 polarity = orion_read(GPIO_IN_POL); + polarity ^= 1 << pin; + orion_write(GPIO_IN_POL, polarity); } + desc_handle_irq(irq, desc); } } } @@ -92,19 +168,24 @@ static void orion_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) static void __init orion_init_gpio_irq(void) { int i; + struct irq_desc *desc; /* * Mask and clear GPIO IRQ interrupts */ orion_write(GPIO_LEVEL_MASK, 0x0); + orion_write(GPIO_EDGE_MASK, 0x0); orion_write(GPIO_EDGE_CAUSE, 0x0); /* - * Register chained level handlers for GPIO IRQs + * Register chained level handlers for GPIO IRQs by default. + * User can use set_type() if he wants to use edge types handlers. */ for (i = IRQ_ORION_GPIO_START; i < NR_IRQS; i++) { set_irq_chip(i, &orion_gpio_irq_chip); set_irq_handler(i, handle_level_irq); + desc = irq_desc + i; + desc->status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); } set_irq_chained_handler(IRQ_ORION_GPIO_0_7, orion_gpio_irq_handler); -- cgit v1.2.3 From 51cbff1d6f1946f97b847f9a144737eca20ede84 Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 23 Oct 2007 15:14:42 -0400 Subject: [ARM] Orion: system timer support Signed-off-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/Kconfig | 2 + arch/arm/mach-orion/Makefile | 2 +- arch/arm/mach-orion/common.h | 5 ++ arch/arm/mach-orion/time.c | 181 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-orion/time.c (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 71e905ebcc05..20084f273d8e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -338,6 +338,8 @@ config ARCH_ORION depends on MMU select PCI select GENERIC_GPIO + select GENERIC_TIME + select GENERIC_CLOCKEVENTS help Support for Marvell Orion System on Chip family. diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index 57d459a2090e..3b2a3eef39dd 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -1 +1 @@ -obj-y += common.o addr-map.o pci.o gpio.o irq.o +obj-y += common.o addr-map.o pci.o gpio.o irq.o time.o diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h index 155371e1d672..2b452facadd1 100644 --- a/arch/arm/mach-orion/common.h +++ b/arch/arm/mach-orion/common.h @@ -62,4 +62,9 @@ int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, u32 where, u32 size, u32 va void __init orion_gpio_set_valid_pins(u32 pins); void gpio_display(void); /* debug */ +/* + * Orion system timer (clocksource + clockevnt, /mach-orion/time.c) + */ +extern struct sys_timer orion_timer; + #endif /* __ARCH_ORION_COMMON_H__ */ diff --git a/arch/arm/mach-orion/time.c b/arch/arm/mach-orion/time.c new file mode 100644 index 000000000000..bd4262da4f40 --- /dev/null +++ b/arch/arm/mach-orion/time.c @@ -0,0 +1,181 @@ +/* + * arch/arm/mach-orion/time.c + * + * Core time functions for Marvell Orion System On Chip + * + * Maintainer: Tzachi Perelstein + * + * 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 +#include +#include +#include +#include +#include "common.h" + +/* + * Timer0: clock_event_device, Tick. + * Timer1: clocksource, Free running. + * WatchDog: Not used. + * + * Timers are counting down. + */ +#define CLOCKEVENT 0 +#define CLOCKSOURCE 1 + +/* + * Timers bits + */ +#define BRIDGE_INT_TIMER(x) (1 << ((x) + 1)) +#define TIMER_EN(x) (1 << ((x) * 2)) +#define TIMER_RELOAD_EN(x) (1 << (((x) * 2) + 1)) +#define BRIDGE_INT_TIMER_WD (1 << 3) +#define TIMER_WD_EN (1 << 4) +#define TIMER_WD_RELOAD_EN (1 << 5) + +static cycle_t orion_clksrc_read(void) +{ + return (0xffffffff - orion_read(TIMER_VAL(CLOCKSOURCE))); +} + +static struct clocksource orion_clksrc = { + .name = "orion_clocksource", + .shift = 20, + .rating = 300, + .read = orion_clksrc_read, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int +orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev) +{ + unsigned long flags; + + if (delta == 0) + return -ETIME; + + local_irq_save(flags); + + /* + * Clear and enable timer interrupt bit + */ + orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT)); + orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT)); + + /* + * Setup new timer value + */ + orion_write(TIMER_VAL(CLOCKEVENT), delta); + + /* + * Disable auto reload and kickoff the timer + */ + orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT)); + orion_setbits(TIMER_CTRL, TIMER_EN(CLOCKEVENT)); + + local_irq_restore(flags); + + return 0; +} + +static void +orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) +{ + unsigned long flags; + + local_irq_save(flags); + + if (mode == CLOCK_EVT_MODE_PERIODIC) { + /* + * Setup latch cycles in timer and enable reload interrupt. + */ + orion_write(TIMER_VAL_RELOAD(CLOCKEVENT), LATCH); + orion_write(TIMER_VAL(CLOCKEVENT), LATCH); + orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT)); + orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) | + TIMER_EN(CLOCKEVENT)); + } else { + /* + * Disable timer and interrupt + */ + orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT)); + orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT)); + orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) | + TIMER_EN(CLOCKEVENT)); + } + + local_irq_restore(flags); +} + +static struct clock_event_device orion_clkevt = { + .name = "orion_tick", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .rating = 300, + .cpumask = CPU_MASK_CPU0, + .set_next_event = orion_clkevt_next_event, + .set_mode = orion_clkevt_mode, +}; + +static irqreturn_t orion_timer_interrupt(int irq, void *dev_id) +{ + /* + * Clear cause bit and do event + */ + orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT)); + orion_clkevt.event_handler(&orion_clkevt); + return IRQ_HANDLED; +} + +static struct irqaction orion_timer_irq = { + .name = "orion_tick", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = orion_timer_interrupt +}; + +static void orion_timer_init(void) +{ + /* + * Setup clocksource free running timer (no interrupt on reload) + */ + orion_write(TIMER_VAL(CLOCKSOURCE), 0xffffffff); + orion_write(TIMER_VAL_RELOAD(CLOCKSOURCE), 0xffffffff); + orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKSOURCE)); + orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKSOURCE) | + TIMER_EN(CLOCKSOURCE)); + + /* + * Register clocksource + */ + orion_clksrc.mult = + clocksource_hz2mult(CLOCK_TICK_RATE, orion_clksrc.shift); + + clocksource_register(&orion_clksrc); + + /* + * Connect and enable tick handler + */ + setup_irq(IRQ_ORION_BRIDGE, &orion_timer_irq); + + /* + * Register clockevent + */ + orion_clkevt.mult = + div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, orion_clkevt.shift); + orion_clkevt.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &orion_clkevt); + orion_clkevt.min_delta_ns = + clockevent_delta2ns(1, &orion_clkevt); + + clockevents_register_device(&orion_clkevt); +} + +struct sys_timer orion_timer = { + .init = orion_timer_init, +}; -- cgit v1.2.3 From ca26f7d3ed3c841e561613a9ea2f44ca899e27de Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 23 Oct 2007 15:14:42 -0400 Subject: [ARM] Orion: platform device registration for UART, USB and NAND Signed-off-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/mach-orion/common.c | 123 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c index 69363cbcb63b..ab1000eeaefe 100644 --- a/arch/arm/mach-orion/common.c +++ b/arch/arm/mach-orion/common.c @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include #include @@ -53,6 +55,119 @@ void __init orion_map_io(void) iotable_init(orion_io_desc, ARRAY_SIZE(orion_io_desc)); } +/***************************************************************************** + * UART + ****************************************************************************/ + +static struct resource orion_uart_resources[] = { + { + .start = UART0_BASE, + .end = UART0_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_ORION_UART0, + .end = IRQ_ORION_UART0, + .flags = IORESOURCE_IRQ, + }, + { + .start = UART1_BASE, + .end = UART1_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_ORION_UART1, + .end = IRQ_ORION_UART1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct plat_serial8250_port orion_uart_data[] = { + { + .mapbase = UART0_BASE, + .membase = (char *)UART0_BASE, + .irq = IRQ_ORION_UART0, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = ORION_TCLK, + }, + { + .mapbase = UART1_BASE, + .membase = (char *)UART1_BASE, + .irq = IRQ_ORION_UART1, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = ORION_TCLK, + }, + { }, +}; + +static struct platform_device orion_uart = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = orion_uart_data, + }, + .resource = orion_uart_resources, + .num_resources = ARRAY_SIZE(orion_uart_resources), +}; + +/******************************************************************************* + * USB Controller - 2 interfaces + ******************************************************************************/ + +static struct resource orion_ehci0_resources[] = { + { + .start = ORION_USB0_REG_BASE, + .end = ORION_USB0_REG_BASE + SZ_4K, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_ORION_USB0_CTRL, + .end = IRQ_ORION_USB0_CTRL, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource orion_ehci1_resources[] = { + { + .start = ORION_USB1_REG_BASE, + .end = ORION_USB1_REG_BASE + SZ_4K, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_ORION_USB1_CTRL, + .end = IRQ_ORION_USB1_CTRL, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 ehci_dmamask = 0xffffffffUL; + +static struct platform_device orion_ehci0 = { + .name = "orion-ehci", + .id = 0, + .dev = { + .dma_mask = &ehci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = orion_ehci0_resources, + .num_resources = ARRAY_SIZE(orion_ehci0_resources), +}; + +static struct platform_device orion_ehci1 = { + .name = "orion-ehci", + .id = 1, + .dev = { + .dma_mask = &ehci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = orion_ehci1_resources, + .num_resources = ARRAY_SIZE(orion_ehci1_resources), +}; + /***************************************************************************** * General ****************************************************************************/ @@ -101,4 +216,12 @@ void __init orion_init(void) orion_setup_pcie_wins(); if (dev == MV88F5182_DEV_ID) orion_setup_sata_wins(); + + /* + * REgister devices + */ + platform_device_register(&orion_uart); + platform_device_register(&orion_ehci0); + if (dev == MV88F5182_DEV_ID) + platform_device_register(&orion_ehci1); } -- cgit v1.2.3 From e07c9d85726e57914608a4e66a5dbb35863cd8fb Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Wed, 31 Oct 2007 12:42:41 +0200 Subject: [ARM] Orion: common platform setup for Gigabit Ethernet port The Orion Ethernet port is the same port used in the Discovery family (MV643XX). This patch include the common platform_device stuff according to the existing mv643xx_eth conventions. Signed-off-by: Tzachi Perelstein Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/mach-orion/common.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-orion/common.h | 8 ++++++++ 2 files changed, 52 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c index ab1000eeaefe..12736fd60004 100644 --- a/arch/arm/mach-orion/common.c +++ b/arch/arm/mach-orion/common.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -168,6 +169,49 @@ static struct platform_device orion_ehci1 = { .num_resources = ARRAY_SIZE(orion_ehci1_resources), }; +/***************************************************************************** + * Gigabit Ethernet port + * (The Orion and Discovery (MV643xx) families use the same Ethernet driver) + ****************************************************************************/ + +static struct resource orion_eth_shared_resources[] = { + { + .start = ORION_ETH_REG_BASE, + .end = ORION_ETH_REG_BASE + 0xffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device orion_eth_shared = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .num_resources = 1, + .resource = orion_eth_shared_resources, +}; + +static struct resource orion_eth_resources[] = { + { + .name = "eth irq", + .start = IRQ_ORION_ETH_SUM, + .end = IRQ_ORION_ETH_SUM, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device orion_eth = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = 1, + .resource = orion_eth_resources, +}; + +void __init orion_eth_init(struct mv643xx_eth_platform_data *eth_data) +{ + orion_eth.dev.platform_data = eth_data; + platform_device_register(&orion_eth_shared); + platform_device_register(&orion_eth); +} + /***************************************************************************** * General ****************************************************************************/ diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h index 2b452facadd1..06c10c06f03e 100644 --- a/arch/arm/mach-orion/common.h +++ b/arch/arm/mach-orion/common.h @@ -67,4 +67,12 @@ void gpio_display(void); /* debug */ */ extern struct sys_timer orion_timer; +/* + * Pull in Orion Ethernet platform_data, used by machine-setup + */ + +struct mv643xx_eth_platform_data; + +void __init orion_eth_init(struct mv643xx_eth_platform_data *eth_data); + #endif /* __ARCH_ORION_COMMON_H__ */ -- cgit v1.2.3 From e448b12cdacd4b26747480250df843b734896ae5 Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 23 Oct 2007 15:14:42 -0400 Subject: [ARM] Orion: support for Marvell Orion-2 (88F5281) Development Board Signed-off-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/mach-orion/Kconfig | 7 + arch/arm/mach-orion/Makefile | 3 +- arch/arm/mach-orion/db88f5281-setup.c | 364 ++++++++++++++++++++++++++++++++++ 3 files changed, 373 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-orion/db88f5281-setup.c (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/Kconfig b/arch/arm/mach-orion/Kconfig index c2af02125ce9..5c1dee8724c1 100644 --- a/arch/arm/mach-orion/Kconfig +++ b/arch/arm/mach-orion/Kconfig @@ -2,6 +2,13 @@ if ARCH_ORION menu "Orion Implementations" +config MACH_DB88F5281 + bool "Marvell Orion-2 Development Board" + select I2C_BOARDINFO + help + Say 'Y' here if you want your kernel to support the + Marvell Orion-2 (88F5281) Development Board + endmenu endif diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index 3b2a3eef39dd..55c59bb7f1d9 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -1 +1,2 @@ -obj-y += common.o addr-map.o pci.o gpio.o irq.o time.o +obj-y += common.o addr-map.o pci.o gpio.o irq.o time.o +obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o diff --git a/arch/arm/mach-orion/db88f5281-setup.c b/arch/arm/mach-orion/db88f5281-setup.c new file mode 100644 index 000000000000..cb2a95ce5b57 --- /dev/null +++ b/arch/arm/mach-orion/db88f5281-setup.c @@ -0,0 +1,364 @@ +/* + * arch/arm/mach-orion/db88f5281-setup.c + * + * Marvell Orion-2 Development Board Setup + * + * Maintainer: Tzachi Perelstein + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +/***************************************************************************** + * DB-88F5281 on board devices + ****************************************************************************/ + +/* + * 512K NOR flash Device bus boot chip select + */ + +#define DB88F5281_NOR_BOOT_BASE 0xf4000000 +#define DB88F5281_NOR_BOOT_SIZE SZ_512K + +/* + * 7-Segment on Device bus chip select 0 + */ + +#define DB88F5281_7SEG_BASE 0xfa000000 +#define DB88F5281_7SEG_SIZE SZ_1K + +/* + * 32M NOR flash on Device bus chip select 1 + */ + +#define DB88F5281_NOR_BASE 0xfc000000 +#define DB88F5281_NOR_SIZE SZ_32M + +/* + * 32M NAND flash on Device bus chip select 2 + */ + +#define DB88F5281_NAND_BASE 0xfa800000 +#define DB88F5281_NAND_SIZE SZ_1K + +/* + * PCI + */ + +#define DB88F5281_PCI_SLOT0_OFFS 7 +#define DB88F5281_PCI_SLOT0_IRQ_PIN 12 +#define DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN 13 + +/***************************************************************************** + * 512M NOR Flash on Device bus Boot CS + ****************************************************************************/ + +static struct physmap_flash_data db88f5281_boot_flash_data = { + .width = 1, /* 8 bit bus width */ +}; + +static struct resource db88f5281_boot_flash_resource = { + .flags = IORESOURCE_MEM, + .start = DB88F5281_NOR_BOOT_BASE, + .end = DB88F5281_NOR_BOOT_BASE + DB88F5281_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device db88f5281_boot_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &db88f5281_boot_flash_data, + }, + .num_resources = 1, + .resource = &db88f5281_boot_flash_resource, +}; + +/***************************************************************************** + * 32M NOR Flash on Device bus CS1 + ****************************************************************************/ + +static struct physmap_flash_data db88f5281_nor_flash_data = { + .width = 4, /* 32 bit bus width */ +}; + +static struct resource db88f5281_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = DB88F5281_NOR_BASE, + .end = DB88F5281_NOR_BASE + DB88F5281_NOR_SIZE - 1, +}; + +static struct platform_device db88f5281_nor_flash = { + .name = "physmap-flash", + .id = 1, + .dev = { + .platform_data = &db88f5281_nor_flash_data, + }, + .num_resources = 1, + .resource = &db88f5281_nor_flash_resource, +}; + +/***************************************************************************** + * 32M NAND Flash on Device bus CS2 + ****************************************************************************/ + +static struct mtd_partition db88f5281_nand_parts[] = { + { + .name = "kernel", + .offset = 0, + .size = SZ_2M, + }, + { + .name = "root", + .offset = SZ_2M, + .size = (SZ_16M - SZ_2M), + }, + { + .name = "user", + .offset = SZ_16M, + .size = SZ_8M, + }, + { + .name = "recovery", + .offset = (SZ_16M + SZ_8M), + .size = SZ_8M, + }, +}; + +static struct resource db88f5281_nand_resource = { + .flags = IORESOURCE_MEM, + .start = DB88F5281_NAND_BASE, + .end = DB88F5281_NAND_BASE + DB88F5281_NAND_SIZE - 1, +}; + +static struct orion_nand_data db88f5281_nand_data = { + .parts = db88f5281_nand_parts, + .nr_parts = ARRAY_SIZE(db88f5281_nand_parts), + .cle = 0, + .ale = 1, + .width = 8, +}; + +static struct platform_device db88f5281_nand_flash = { + .name = "orion_nand", + .id = -1, + .dev = { + .platform_data = &db88f5281_nand_data, + }, + .resource = &db88f5281_nand_resource, + .num_resources = 1, +}; + +/***************************************************************************** + * 7-Segment on Device bus CS0 + * Dummy counter every 2 sec + ****************************************************************************/ + +static void __iomem *db88f5281_7seg; +static struct timer_list db88f5281_timer; + +static void db88f5281_7seg_event(unsigned long data) +{ + static int count = 0; + writel(0, db88f5281_7seg + (count << 4)); + count = (count + 1) & 7; + mod_timer(&db88f5281_timer, jiffies + 2 * HZ); +} + +static int __init db88f5281_7seg_init(void) +{ + if (machine_is_db88f5281()) { + db88f5281_7seg = ioremap(DB88F5281_7SEG_BASE, + DB88F5281_7SEG_SIZE); + if (!db88f5281_7seg) { + printk(KERN_ERR "Failed to ioremap db88f5281_7seg\n"); + return -EIO; + } + setup_timer(&db88f5281_timer, db88f5281_7seg_event, 0); + mod_timer(&db88f5281_timer, jiffies + 2 * HZ); + } + + return 0; +} + +__initcall(db88f5281_7seg_init); + +/***************************************************************************** + * PCI + ****************************************************************************/ + +void __init db88f5281_pci_preinit(void) +{ + int pin; + + /* + * Configure PCI GPIO IRQ pins + */ + pin = DB88F5281_PCI_SLOT0_IRQ_PIN; + if (gpio_request(pin, "PCI Int1") == 0) { + if (gpio_direction_input(pin) == 0) { + set_irq_type(gpio_to_irq(pin), IRQT_LOW); + } else { + printk(KERN_ERR "db88f5281_pci_preinit faield to " + "set_irq_type pin %d\n", pin); + gpio_free(pin); + } + } else { + printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin); + } + + pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN; + if (gpio_request(pin, "PCI Int2") == 0) { + if (gpio_direction_input(pin) == 0) { + set_irq_type(gpio_to_irq(pin), IRQT_LOW); + } else { + printk(KERN_ERR "db88f5281_pci_preinit faield " + "to set_irq_type pin %d\n", pin); + gpio_free(pin); + } + } else { + printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin); + } +} + +static int __init db88f5281_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + /* + * PCIE IRQ is connected internally (not GPIO) + */ + if (dev->bus->number == orion_pcie_local_bus_nr()) + return IRQ_ORION_PCIE0_INT; + + /* + * PCI IRQs are connected via GPIOs + */ + switch (slot - DB88F5281_PCI_SLOT0_OFFS) { + case 0: + return gpio_to_irq(DB88F5281_PCI_SLOT0_IRQ_PIN); + case 1: + case 2: + return gpio_to_irq(DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN); + default: + return -1; + } +} + +static struct hw_pci db88f5281_pci __initdata = { + .nr_controllers = 2, + .preinit = db88f5281_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = orion_pci_sys_setup, + .scan = orion_pci_sys_scan_bus, + .map_irq = db88f5281_pci_map_irq, +}; + +static int __init db88f5281_pci_init(void) +{ + if (machine_is_db88f5281()) + pci_common_init(&db88f5281_pci); + + return 0; +} + +subsys_initcall(db88f5281_pci_init); + +/***************************************************************************** + * Ethernet + ****************************************************************************/ +static struct mv643xx_eth_platform_data db88f5281_eth_data = { + .phy_addr = 8, + .force_phy_addr = 1, +}; + +/***************************************************************************** + * RTC DS1339 on I2C bus + ****************************************************************************/ +static struct i2c_board_info __initdata db88f5281_i2c_rtc = { + .driver_name = "rtc-ds1307", + .type = "ds1339", + .addr = 0x68, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static struct platform_device *db88f5281_devs[] __initdata = { + &db88f5281_boot_flash, + &db88f5281_nor_flash, + &db88f5281_nand_flash, +}; + +static void __init db88f5281_init(void) +{ + /* + * Basic Orion setup. Need to be called early. + */ + orion_init(); + + /* + * Setup the CPU address decode windows for our on-board devices + */ + orion_setup_cpu_win(ORION_DEV_BOOT, DB88F5281_NOR_BOOT_BASE, + DB88F5281_NOR_BOOT_SIZE, -1); + orion_setup_cpu_win(ORION_DEV0, DB88F5281_7SEG_BASE, + DB88F5281_7SEG_SIZE, -1); + orion_setup_cpu_win(ORION_DEV1, DB88F5281_NOR_BASE, + DB88F5281_NOR_SIZE, -1); + orion_setup_cpu_win(ORION_DEV2, DB88F5281_NAND_BASE, + DB88F5281_NAND_SIZE, -1); + + /* + * Setup Multiplexing Pins: + * MPP0: GPIO (USB Over Current) MPP1: GPIO (USB Vbat input) + * MPP2: PCI_REQn[2] MPP3: PCI_GNTn[2] + * MPP4: PCI_REQn[3] MPP5: PCI_GNTn[3] + * MPP6: GPIO (JP0, CON17.2) MPP7: GPIO (JP1, CON17.1) + * MPP8: GPIO (JP2, CON11.2) MPP9: GPIO (JP3, CON11.3) + * MPP10: GPIO (RTC int) MPP11: GPIO (Baud Rate Generator) + * MPP12: GPIO (PCI int 1) MPP13: GPIO (PCI int 2) + * MPP14: NAND_REn[2] MPP15: NAND_WEn[2] + * MPP16: UART1_RX MPP17: UART1_TX + * MPP18: UART1_CTS MPP19: UART1_RTS + * MPP-DEV: DEV_D[16:31] + */ + orion_write(MPP_0_7_CTRL, 0x00222203); + orion_write(MPP_8_15_CTRL, 0x44000000); + orion_write(MPP_16_19_CTRL, 0); + orion_write(MPP_DEV_CTRL, 0); + + orion_gpio_set_valid_pins(0x00003fc3); + + platform_add_devices(db88f5281_devs, ARRAY_SIZE(db88f5281_devs)); + i2c_register_board_info(0, &db88f5281_i2c_rtc, 1); + orion_eth_init(&db88f5281_eth_data); +} + +MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board") + /* Maintainer: Tzachi Perelstein */ + .phys_io = ORION_REGS_BASE, + .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = db88f5281_init, + .map_io = orion_map_io, + .init_irq = orion_init_irq, + .timer = &orion_timer, +MACHINE_END -- cgit v1.2.3 From 817eb2109d28fcac8f4fd84a9ef3a761de4f8b50 Mon Sep 17 00:00:00 2001 From: Ronen Shitrit Date: Wed, 17 Oct 2007 14:51:34 -0400 Subject: [ARM] OrionNAS RD board support serial, NOR, PCI and Ethernet is activated at the moment. Signed-off-by: Ronen Shitrit Reviewed-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/Kconfig | 2 +- arch/arm/mach-orion/Kconfig | 7 + arch/arm/mach-orion/Makefile | 1 + arch/arm/mach-orion/rd88f5182-setup.c | 306 ++++++++++++++++++++++++++++++++++ 4 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-orion/rd88f5182-setup.c (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 20084f273d8e..a32b3b52c5c0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -728,7 +728,7 @@ config LEDS ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \ ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \ - ARCH_KS8695 + ARCH_KS8695 || MACH_RD88F5182 help If you say Y here, the LEDs on your machine will be used to provide useful information about your current system status. diff --git a/arch/arm/mach-orion/Kconfig b/arch/arm/mach-orion/Kconfig index 5c1dee8724c1..73d9f9aa283f 100644 --- a/arch/arm/mach-orion/Kconfig +++ b/arch/arm/mach-orion/Kconfig @@ -9,6 +9,13 @@ config MACH_DB88F5281 Say 'Y' here if you want your kernel to support the Marvell Orion-2 (88F5281) Development Board +config MACH_RD88F5182 + bool "Marvell Orion-NAS Reference Design" + select I2C_BOARDINFO + help + Say 'Y' here if you want your kernel to support the + Marvell Orion-NAS (88F5182) RD2 + endmenu endif diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index 55c59bb7f1d9..1cbdd7513120 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -1,2 +1,3 @@ obj-y += common.o addr-map.o pci.o gpio.o irq.o time.o obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o +obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o diff --git a/arch/arm/mach-orion/rd88f5182-setup.c b/arch/arm/mach-orion/rd88f5182-setup.c new file mode 100644 index 000000000000..026d74325d01 --- /dev/null +++ b/arch/arm/mach-orion/rd88f5182-setup.c @@ -0,0 +1,306 @@ +/* + * arch/arm/mach-orion/rd88f5182-setup.c + * + * Marvell Orion-NAS Reference Design Setup + * + * Maintainer: Ronen Shitrit + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +/***************************************************************************** + * RD-88F5182 Info + ****************************************************************************/ + +/* + * 512K NOR flash Device bus boot chip select + */ + +#define RD88F5182_NOR_BOOT_BASE 0xf4000000 +#define RD88F5182_NOR_BOOT_SIZE SZ_512K + +/* + * 16M NOR flash on Device bus chip select 1 + */ + +#define RD88F5182_NOR_BASE 0xfc000000 +#define RD88F5182_NOR_SIZE SZ_16M + +/* + * PCI + */ + +#define RD88F5182_PCI_SLOT0_OFFS 7 +#define RD88F5182_PCI_SLOT0_IRQ_A_PIN 7 +#define RD88F5182_PCI_SLOT0_IRQ_B_PIN 6 + +/* + * GPIO Debug LED + */ + +#define RD88F5182_GPIO_DBG_LED 0 + +/***************************************************************************** + * 16M NOR Flash on Device bus CS1 + ****************************************************************************/ + +static struct physmap_flash_data rd88f5182_nor_flash_data = { + .width = 1, +}; + +static struct resource rd88f5182_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = RD88F5182_NOR_BASE, + .end = RD88F5182_NOR_BASE + RD88F5182_NOR_SIZE - 1, +}; + +static struct platform_device rd88f5182_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &rd88f5182_nor_flash_data, + }, + .num_resources = 1, + .resource = &rd88f5182_nor_flash_resource, +}; + +#ifdef CONFIG_LEDS + +/***************************************************************************** + * Use GPIO debug led as CPU active indication + ****************************************************************************/ + +static void rd88f5182_dbgled_event(led_event_t evt) +{ + int val; + + if (evt == led_idle_end) + val = 1; + else if (evt == led_idle_start) + val = 0; + else + return; + + gpio_set_value(RD88F5182_GPIO_DBG_LED, val); +} + +static int __init rd88f5182_dbgled_init(void) +{ + int pin; + + if (machine_is_rd88f5182()) { + pin = RD88F5182_GPIO_DBG_LED; + + if (gpio_request(pin, "DBGLED") == 0) { + if (gpio_direction_output(pin, 0) != 0) { + printk(KERN_ERR "rd88f5182_dbgled_init failed " + "to set output pin %d\n", pin); + gpio_free(pin); + return 0; + } + } else { + printk(KERN_ERR "rd88f5182_dbgled_init failed " + "to request gpio %d\n", pin); + return 0; + } + + leds_event = rd88f5182_dbgled_event; + } + return 0; +} + +__initcall(rd88f5182_dbgled_init); + +#endif + +/***************************************************************************** + * PCI + ****************************************************************************/ + +void __init rd88f5182_pci_preinit(void) +{ + int pin; + + /* + * Configure PCI GPIO IRQ pins + */ + pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN; + if (gpio_request(pin, "PCI IntA") == 0) { + if (gpio_direction_input(pin) == 0) { + set_irq_type(gpio_to_irq(pin), IRQT_LOW); + } else { + printk(KERN_ERR "rd88f5182_pci_preinit faield to " + "set_irq_type pin %d\n", pin); + gpio_free(pin); + } + } else { + printk(KERN_ERR "rd88f5182_pci_preinit failed to request gpio %d\n", pin); + } + + pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN; + if (gpio_request(pin, "PCI IntB") == 0) { + if (gpio_direction_input(pin) == 0) { + set_irq_type(gpio_to_irq(pin), IRQT_LOW); + } else { + printk(KERN_ERR "rd88f5182_pci_preinit faield to " + "set_irq_type pin %d\n", pin); + gpio_free(pin); + } + } else { + printk(KERN_ERR "rd88f5182_pci_preinit failed to gpio_request %d\n", pin); + } +} + +static int __init rd88f5182_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + /* + * PCI-E isn't used on the RD2 + */ + if (dev->bus->number == orion_pcie_local_bus_nr()) + return IRQ_ORION_PCIE0_INT; + + /* + * PCI IRQs are connected via GPIOs + */ + switch (slot - RD88F5182_PCI_SLOT0_OFFS) { + case 0: + if (pin == 1) + return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_A_PIN); + else + return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_B_PIN); + default: + return -1; + } +} + +static struct hw_pci rd88f5182_pci __initdata = { + .nr_controllers = 2, + .preinit = rd88f5182_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = orion_pci_sys_setup, + .scan = orion_pci_sys_scan_bus, + .map_irq = rd88f5182_pci_map_irq, +}; + +static int __init rd88f5182_pci_init(void) +{ + if (machine_is_rd88f5182()) + pci_common_init(&rd88f5182_pci); + + return 0; +} + +subsys_initcall(rd88f5182_pci_init); + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data rd88f5182_eth_data = { + .phy_addr = 8, + .force_phy_addr = 1, +}; + +/***************************************************************************** + * RTC DS1338 on I2C bus + ****************************************************************************/ +static struct i2c_board_info __initdata rd88f5182_i2c_rtc = { + .driver_name = "rtc-ds1307", + .type = "ds1338", + .addr = 0x68, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static struct platform_device *rd88f5182_devices[] __initdata = { + &rd88f5182_nor_flash, +}; + +static void __init rd88f5182_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion_init(); + + /* + * Setup the CPU address decode windows for our devices + */ + orion_setup_cpu_win(ORION_DEV_BOOT, RD88F5182_NOR_BOOT_BASE, + RD88F5182_NOR_BOOT_SIZE, -1); + orion_setup_cpu_win(ORION_DEV1, RD88F5182_NOR_BASE, + RD88F5182_NOR_SIZE, -1); + + /* + * Open a special address decode windows for the PCIE WA. + */ + orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE); + orion_write(ORION_REGS_BASE | 0x20070, (0x7941 | + (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16)); + + /* + * Setup Multiplexing Pins -- + * MPP[0] Debug Led (GPIO - Out) + * MPP[1] Debug Led (GPIO - Out) + * MPP[2] N/A + * MPP[3] RTC_Int (GPIO - In) + * MPP[4] GPIO + * MPP[5] GPIO + * MPP[6] PCI_intA (GPIO - In) + * MPP[7] PCI_intB (GPIO - In) + * MPP[8-11] N/A + * MPP[12] SATA 0 presence Indication + * MPP[13] SATA 1 presence Indication + * MPP[14] SATA 0 active Indication + * MPP[15] SATA 1 active indication + * MPP[16-19] Not used + * MPP[20] PCI Clock to MV88F5182 + * MPP[21] PCI Clock to mini PCI CON11 + * MPP[22] USB 0 over current indication + * MPP[23] USB 1 over current indication + * MPP[24] USB 1 over current enable + * MPP[25] USB 0 over current enable + */ + + orion_write(MPP_0_7_CTRL, 0x00000003); + orion_write(MPP_8_15_CTRL, 0x55550000); + orion_write(MPP_16_19_CTRL, 0x5555); + + orion_gpio_set_valid_pins(0x000000fb); + + platform_add_devices(rd88f5182_devices, ARRAY_SIZE(rd88f5182_devices)); + i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1); + orion_eth_init(&rd88f5182_eth_data); +} + +MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design") + /* Maintainer: Ronen Shitrit */ + .phys_io = ORION_REGS_BASE, + .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = rd88f5182_init, + .map_io = orion_map_io, + .init_irq = orion_init_irq, + .timer = &orion_timer, +MACHINE_END -- cgit v1.2.3 From 1e78045306e9a402b096eef95864ddf313d402d8 Mon Sep 17 00:00:00 2001 From: Ronen Shitrit Date: Tue, 23 Oct 2007 15:14:42 -0400 Subject: [ARM] Orion: Buffalo/Revogear Kurobox Pro support Only serial, NOR, NAND, PCI and Ethernet is activated at the moment. Signed-off-by: Ronen Shitrit Reviewed-by: Tzachi Perelstein Reviewed-by: Nicolas Pitre Reviewed-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/mach-orion/Kconfig | 7 + arch/arm/mach-orion/Makefile | 1 + arch/arm/mach-orion/kurobox_pro-setup.c | 234 ++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+) create mode 100644 arch/arm/mach-orion/kurobox_pro-setup.c (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/Kconfig b/arch/arm/mach-orion/Kconfig index 73d9f9aa283f..dc929511837f 100644 --- a/arch/arm/mach-orion/Kconfig +++ b/arch/arm/mach-orion/Kconfig @@ -16,6 +16,13 @@ config MACH_RD88F5182 Say 'Y' here if you want your kernel to support the Marvell Orion-NAS (88F5182) RD2 +config MACH_KUROBOX_PRO + bool "KuroBox Pro" + select I2C_BOARDINFO + help + Say 'Y' here if you want your kernel to support the + KuroBox Pro platform. + endmenu endif diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index 1cbdd7513120..caf20ff921d8 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -1,3 +1,4 @@ obj-y += common.o addr-map.o pci.o gpio.o irq.o time.o obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o +obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o diff --git a/arch/arm/mach-orion/kurobox_pro-setup.c b/arch/arm/mach-orion/kurobox_pro-setup.c new file mode 100644 index 000000000000..2d812ed6b5c7 --- /dev/null +++ b/arch/arm/mach-orion/kurobox_pro-setup.c @@ -0,0 +1,234 @@ +/* + * arch/arm/mach-orion/kurobox_pro-setup.c + * + * Maintainer: Ronen Shitrit + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +/***************************************************************************** + * KUROBOX-PRO Info + ****************************************************************************/ + +/* + * 256K NOR flash Device bus boot chip select + */ + +#define KUROBOX_PRO_NOR_BOOT_BASE 0xf4000000 +#define KUROBOX_PRO_NOR_BOOT_SIZE SZ_256K + +/* + * 256M NAND flash on Device bus chip select 1 + */ + +#define KUROBOX_PRO_NAND_BASE 0xfc000000 +#define KUROBOX_PRO_NAND_SIZE SZ_2M + +/***************************************************************************** + * 256MB NAND Flash on Device bus CS0 + ****************************************************************************/ + +static struct mtd_partition kurobox_pro_nand_parts[] = { + { + .name = "uImage", + .offset = 0, + .size = SZ_4M, + }, + { + .name = "rootfs", + .offset = SZ_4M, + .size = SZ_64M, + }, + { + .name = "extra", + .offset = SZ_4M + SZ_64M, + .size = SZ_256M - (SZ_4M + SZ_64M), + }, +}; + +static struct resource kurobox_pro_nand_resource = { + .flags = IORESOURCE_MEM, + .start = KUROBOX_PRO_NAND_BASE, + .end = KUROBOX_PRO_NAND_BASE + KUROBOX_PRO_NAND_SIZE - 1, +}; + +static struct orion_nand_data kurobox_pro_nand_data = { + .parts = kurobox_pro_nand_parts, + .nr_parts = ARRAY_SIZE(kurobox_pro_nand_parts), + .cle = 0, + .ale = 1, + .width = 8, +}; + +static struct platform_device kurobox_pro_nand_flash = { + .name = "orion_nand", + .id = -1, + .dev = { + .platform_data = &kurobox_pro_nand_data, + }, + .resource = &kurobox_pro_nand_resource, + .num_resources = 1, +}; + +/***************************************************************************** + * 256KB NOR Flash on BOOT Device + ****************************************************************************/ + +static struct physmap_flash_data kurobox_pro_nor_flash_data = { + .width = 1, +}; + +static struct resource kurobox_pro_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = KUROBOX_PRO_NOR_BOOT_BASE, + .end = KUROBOX_PRO_NOR_BOOT_BASE + KUROBOX_PRO_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device kurobox_pro_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &kurobox_pro_nor_flash_data, + }, + .num_resources = 1, + .resource = &kurobox_pro_nor_flash_resource, +}; + +/***************************************************************************** + * PCI + ****************************************************************************/ + +static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + /* + * PCI isn't used on the Kuro + */ + if (dev->bus->number == orion_pcie_local_bus_nr()) + return IRQ_ORION_PCIE0_INT; + else + printk(KERN_ERR "kurobox_pro_pci_map_irq failed, unknown bus\n"); + + return -1; +} + +static struct hw_pci kurobox_pro_pci __initdata = { + .nr_controllers = 1, + .swizzle = pci_std_swizzle, + .setup = orion_pci_sys_setup, + .scan = orion_pci_sys_scan_bus, + .map_irq = kurobox_pro_pci_map_irq, +}; + +static int __init kurobox_pro_pci_init(void) +{ + if (machine_is_kurobox_pro()) + pci_common_init(&kurobox_pro_pci); + + return 0; +} + +subsys_initcall(kurobox_pro_pci_init); + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data kurobox_pro_eth_data = { + .phy_addr = 8, + .force_phy_addr = 1, +}; + +/***************************************************************************** + * RTC 5C372a on I2C bus + ****************************************************************************/ +static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = { + .driver_name = "rtc-rs5c372", + .type = "rs5c372a", + .addr = 0x32, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static struct platform_device *kurobox_pro_devices[] __initdata = { + &kurobox_pro_nor_flash, + &kurobox_pro_nand_flash, +}; + +static void __init kurobox_pro_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion_init(); + + /* + * Setup the CPU address decode windows for our devices + */ + orion_setup_cpu_win(ORION_DEV_BOOT, KUROBOX_PRO_NOR_BOOT_BASE, + KUROBOX_PRO_NOR_BOOT_SIZE, -1); + orion_setup_cpu_win(ORION_DEV0, KUROBOX_PRO_NAND_BASE, + KUROBOX_PRO_NAND_SIZE, -1); + /* + * Open a special address decode windows for the PCIE WA. + */ + orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE); + orion_write(ORION_REGS_BASE | 0x20070, (0x7941 | + (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16)); + + /* + * Setup Multiplexing Pins -- + * MPP[0-1] Not used + * MPP[2] GPIO Micon + * MPP[3] GPIO RTC + * MPP[4-5] Not used + * MPP[6] Nand Flash REn + * MPP[7] Nand Flash WEn + * MPP[8-11] Not used + * MPP[12] SATA 0 presence Indication + * MPP[13] SATA 1 presence Indication + * MPP[14] SATA 0 active Indication + * MPP[15] SATA 1 active indication + * MPP[16-19] Not used + */ + orion_write(MPP_0_7_CTRL, 0x44220003); + orion_write(MPP_8_15_CTRL, 0x55550000); + orion_write(MPP_16_19_CTRL, 0x0); + + orion_gpio_set_valid_pins(0x0000000c); + + platform_add_devices(kurobox_pro_devices, ARRAY_SIZE(kurobox_pro_devices)); + i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1); + orion_eth_init(&kurobox_pro_eth_data); +} + +MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro") + /* Maintainer: Ronen Shitrit */ + .phys_io = ORION_REGS_BASE, + .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = kurobox_pro_init, + .map_io = orion_map_io, + .init_irq = orion_init_irq, + .timer = &orion_timer, +MACHINE_END -- cgit v1.2.3 From c9e3de941a1694aeab60a10bd39eb710c975010d Mon Sep 17 00:00:00 2001 From: Herbert Valerio Riedel Date: Sun, 11 Nov 2007 12:05:11 +0100 Subject: [ARM] Orion: MV88F5181 support bits add MV88F5181 support bits required by D-link DNS-323 patch Signed-off-by: Herbert Valerio Riedel Acked-by: Tzachi Perelstein Acked-by: Russell King --- arch/arm/mach-orion/addr-map.c | 4 +++- arch/arm/mach-orion/common.c | 6 ++++++ arch/arm/mach-orion/pci.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/addr-map.c b/arch/arm/mach-orion/addr-map.c index ff6e010bccb2..488da3811a68 100644 --- a/arch/arm/mach-orion/addr-map.c +++ b/arch/arm/mach-orion/addr-map.c @@ -167,7 +167,9 @@ static int __init orion_cpu_win_can_remap(u32 win) u32 dev, rev; orion_pcie_id(&dev, &rev); - if ((dev == MV88F5281_DEV_ID && win < 4) || (dev == MV88F5182_DEV_ID && win < 2)) + if ((dev == MV88F5281_DEV_ID && win < 4) + || (dev == MV88F5182_DEV_ID && win < 2) + || (dev == MV88F5181_DEV_ID && win < 2)) return 1; return 0; diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c index 12736fd60004..ff34827f82a5 100644 --- a/arch/arm/mach-orion/common.c +++ b/arch/arm/mach-orion/common.c @@ -237,6 +237,12 @@ static void orion_id(u32 *dev, u32 *rev, char **dev_name) } else { *dev_name = "MV88F5182-Rev-Unsupported"; } + } else if (*dev == MV88F5181_DEV_ID) { + if (*rev == MV88F5181_REV_B1) { + *dev_name = "MV88F5181-Rev-B1"; + } else { + *dev_name = "MV88F5181-Rev-Unsupported"; + } } else { *dev_name = "Device-Unknown"; } diff --git a/arch/arm/mach-orion/pci.c b/arch/arm/mach-orion/pci.c index cf569c647112..0498d7c69b30 100644 --- a/arch/arm/mach-orion/pci.c +++ b/arch/arm/mach-orion/pci.c @@ -154,7 +154,7 @@ static int orion_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN); orion_pcie_id(&dev, &rev); - if (dev == MV88F5182_DEV_ID) { + if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) { /* extended register space */ pcie_addr = ORION_PCIE_WA_BASE; pcie_addr |= PCIE_CONF_BUS(bus->number) | -- cgit v1.2.3 From 555a36561be191eb01658a5229aa11b4e4a8a7f0 Mon Sep 17 00:00:00 2001 From: Herbert Valerio Riedel Date: Mon, 12 Nov 2007 09:05:55 +0100 Subject: [ARM] Orion: add support for Orion/MV88F5181 based D-Link DNS-323 With this patch USB, SATA (via sata_mv), Ethernet, RTC, LEDs and NOR Flash work. Signed-off-by: Herbert Valerio Riedel Acked-by: Tzachi Perelstein Acked-by: Russell King --- arch/arm/mach-orion/Kconfig | 7 + arch/arm/mach-orion/Makefile | 1 + arch/arm/mach-orion/dns323-setup.c | 322 +++++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+) create mode 100644 arch/arm/mach-orion/dns323-setup.c (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/Kconfig b/arch/arm/mach-orion/Kconfig index dc929511837f..bdaed867e450 100644 --- a/arch/arm/mach-orion/Kconfig +++ b/arch/arm/mach-orion/Kconfig @@ -23,6 +23,13 @@ config MACH_KUROBOX_PRO Say 'Y' here if you want your kernel to support the KuroBox Pro platform. +config MACH_DNS323 + bool "D-Link DNS-323" + select I2C_BOARDINFO + help + Say 'Y' here if you want your kernel to support the + D-Link DNS-323 platform. + endmenu endif diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index caf20ff921d8..237ce98ad0ef 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -2,3 +2,4 @@ obj-y += common.o addr-map.o pci.o gpio.o irq.o time.o obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o +obj-$(CONFIG_MACH_DNS323) += dns323-setup.o diff --git a/arch/arm/mach-orion/dns323-setup.c b/arch/arm/mach-orion/dns323-setup.c new file mode 100644 index 000000000000..c8a806f249c6 --- /dev/null +++ b/arch/arm/mach-orion/dns323-setup.c @@ -0,0 +1,322 @@ +/* + * arch/arm/mach-orion/dns323-setup.c + * + * Copyright (C) 2007 Herbert Valerio Riedel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +#define DNS323_GPIO_LED_RIGHT_AMBER 1 +#define DNS323_GPIO_LED_LEFT_AMBER 2 +#define DNS323_GPIO_LED_POWER 5 +#define DNS323_GPIO_OVERTEMP 6 +#define DNS323_GPIO_RTC 7 +#define DNS323_GPIO_POWER_OFF 8 +#define DNS323_GPIO_KEY_POWER 9 +#define DNS323_GPIO_KEY_RESET 10 + +/**************************************************************************** + * PCI setup + */ + +static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + /* PCI-E */ + if (dev->bus->number == orion_pcie_local_bus_nr()) + return IRQ_ORION_PCIE0_INT; + + pr_err("%s: requested mapping for unknown bus\n", __func__); + + return -1; +} + +static struct hw_pci dns323_pci __initdata = { + .nr_controllers = 1, + .swizzle = pci_std_swizzle, + .setup = orion_pci_sys_setup, + .scan = orion_pci_sys_scan_bus, + .map_irq = dns323_pci_map_irq, +}; + +static int __init dns323_pci_init(void) +{ + if (machine_is_dns323()) + pci_common_init(&dns323_pci); + + return 0; +} + +subsys_initcall(dns323_pci_init); + +/**************************************************************************** + * Ethernet + */ + +static struct mv643xx_eth_platform_data dns323_eth_data = { + .phy_addr = 8, + .force_phy_addr = 1, +}; + +/**************************************************************************** + * 8MiB NOR flash (Spansion S29GL064M90TFIR4) + * + * Layout as used by D-Link: + * 0x00000000-0x00010000 : "MTD1" + * 0x00010000-0x00020000 : "MTD2" + * 0x00020000-0x001a0000 : "Linux Kernel" + * 0x001a0000-0x007d0000 : "File System" + * 0x007d0000-0x00800000 : "u-boot" + */ + +#define DNS323_NOR_BOOT_BASE 0xf4000000 +#define DNS323_NOR_BOOT_SIZE SZ_8M + +static struct mtd_partition dns323_partitions[] = { + { + .name = "MTD1", + .size = 0x00010000, + .offset = 0, + }, { + .name = "MTD2", + .size = 0x00010000, + .offset = 0x00010000, + }, { + .name = "Linux Kernel", + .size = 0x00180000, + .offset = 0x00020000, + }, { + .name = "File System", + .size = 0x00630000, + .offset = 0x001A0000, + }, { + .name = "u-boot", + .size = 0x00030000, + .offset = 0x007d0000, + } +}; + +static struct physmap_flash_data dns323_nor_flash_data = { + .width = 1, + .parts = dns323_partitions, + .nr_parts = ARRAY_SIZE(dns323_partitions) +}; + +static struct resource dns323_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = DNS323_NOR_BOOT_BASE, + .end = DNS323_NOR_BOOT_BASE + DNS323_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device dns323_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { .platform_data = &dns323_nor_flash_data, }, + .resource = &dns323_nor_flash_resource, + .num_resources = 1, +}; + +/**************************************************************************** + * GPIO LEDs (simple - doesn't use hardware blinking support) + */ + +static struct gpio_led dns323_leds[] = { + { + .name = "power:blue", + .gpio = DNS323_GPIO_LED_POWER, + .active_low = 1, + }, { + .name = "right:amber", + .gpio = DNS323_GPIO_LED_RIGHT_AMBER, + .active_low = 1, + }, { + .name = "left:amber", + .gpio = DNS323_GPIO_LED_LEFT_AMBER, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data dns323_led_data = { + .num_leds = ARRAY_SIZE(dns323_leds), + .leds = dns323_leds, +}; + +static struct platform_device dns323_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { .platform_data = &dns323_led_data, }, +}; + +/**************************************************************************** + * GPIO Attached Keys + */ + +static struct gpio_keys_button dns323_buttons[] = { + { + .code = KEY_RESTART, + .gpio = DNS323_GPIO_KEY_RESET, + .desc = "Reset Button", + .active_low = 1, + }, + { + .code = KEY_POWER, + .gpio = DNS323_GPIO_KEY_POWER, + .desc = "Power Button", + .active_low = 1, + } +}; + +static struct gpio_keys_platform_data dns323_button_data = { + .buttons = dns323_buttons, + .nbuttons = ARRAY_SIZE(dns323_buttons), +}; + +static struct platform_device dns323_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { .platform_data = &dns323_button_data, }, +}; + +/**************************************************************************** + * General Setup + */ + +static struct platform_device *dns323_plat_devices[] __initdata = { + &dns323_nor_flash, + &dns323_gpio_leds, + &dns323_button_device, +}; + +/* + * On the DNS-323 the following devices are attached via I2C: + * + * i2c addr | chip | description + * 0x3e | GMT G760Af | fan speed PWM controller + * 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible) + * 0x68 | ST M41T80 | RTC w/ alarm + */ +static struct i2c_board_info __initdata dns323_i2c_devices[] = { + { + I2C_BOARD_INFO("g760a", 0x3e), + .type = "g760a", + }, +#if 0 + /* this entry requires the new-style driver model lm75 driver, + * for the meantime "insmod lm75.ko force_lm75=0,0x48" is needed */ + { + I2C_BOARD_INFO("lm75", 0x48), + .type = "g751", + }, +#endif + { + I2C_BOARD_INFO("rtc-m41t80", 0x68), + .type = "m41t80", + } +}; + +/* DNS-323 specific power off method */ +static void dns323_power_off(void) +{ + pr_info("%s: triggering power-off...\n", __func__); + gpio_set_value(DNS323_GPIO_POWER_OFF, 1); +} + +static void __init dns323_init(void) +{ + /* Setup basic Orion functions. Need to be called early. */ + orion_init(); + + /* setup flash mapping + * CS3 holds a 8 MB Spansion S29GL064M90TFIR4 + */ + orion_setup_cpu_win(ORION_DEV_BOOT, DNS323_NOR_BOOT_BASE, + DNS323_NOR_BOOT_SIZE, -1); + + /* DNS-323 has a Marvell 88X7042 SATA controller attached via PCIE + * + * Open a special address decode windows for the PCIE WA. + */ + orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE); + orion_write(ORION_REGS_BASE | 0x20070, + (0x7941 | (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16)); + + /* set MPP to 0 as D-Link's 2.6.12.6 kernel did */ + orion_write(MPP_0_7_CTRL, 0); + orion_write(MPP_8_15_CTRL, 0); + orion_write(MPP_16_19_CTRL, 0); + orion_write(MPP_DEV_CTRL, 0); + + /* Define used GPIO pins + + GPIO Map: + + | 0 | | PEX_RST_OUT (not controlled by GPIO) + | 1 | Out | right amber LED (= sata ch0 LED) (low-active) + | 2 | Out | left amber LED (= sata ch1 LED) (low-active) + | 3 | Out | //unknown// + | 4 | Out | power button LED (low-active, together with pin #5) + | 5 | Out | power button LED (low-active, together with pin #4) + | 6 | In | GMT G751-2f overtemp. shutdown signal (low-active) + | 7 | In | M41T80 nIRQ/OUT/SQW signal + | 8 | Out | triggers power off (high-active) + | 9 | In | power button switch (low-active) + | 10 | In | reset button switch (low-active) + | 11 | Out | //unknown// + | 12 | Out | //unknown// + | 13 | Out | //unknown// + | 14 | Out | //unknown// + | 15 | Out | //unknown// + */ + orion_gpio_set_valid_pins(0x07f6); + + /* register dns323 specific power-off method */ + if ((gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0) + || (gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)) + pr_err("DNS323: failed to setup power-off GPIO\n"); + + pm_power_off = dns323_power_off; + + /* register flash and other platform devices */ + platform_add_devices(dns323_plat_devices, + ARRAY_SIZE(dns323_plat_devices)); + + i2c_register_board_info(0, dns323_i2c_devices, + ARRAY_SIZE(dns323_i2c_devices)); + + orion_eth_init(&dns323_eth_data); +} + +/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */ +MACHINE_START(DNS323, "D-Link DNS-323") + /* Maintainer: Herbert Valerio Riedel */ + .phys_io = ORION_REGS_BASE, + .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = dns323_init, + .map_io = orion_map_io, + .init_irq = orion_init_irq, + .timer = &orion_timer, +MACHINE_END -- cgit v1.2.3 From eb3cef84adec0fdba1a2531bcefe438a838a57dd Mon Sep 17 00:00:00 2001 From: Tzachi Perelstein Date: Tue, 6 Nov 2007 11:18:46 +0200 Subject: [ARM] Orion defconfig Basic selections for Orion machines Signed-off-by: Tzachi Perelstein Signed-off-by: Nicolas Pitre Acked-by: Russell King --- arch/arm/configs/orion_defconfig | 1383 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 1383 insertions(+) create mode 100644 arch/arm/configs/orion_defconfig (limited to 'arch/arm') diff --git a/arch/arm/configs/orion_defconfig b/arch/arm/configs/orion_defconfig new file mode 100644 index 000000000000..9a42b2fc9f65 --- /dev/null +++ b/arch/arm/configs/orion_defconfig @@ -0,0 +1,1383 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24-rc3 +# Wed Nov 28 15:13:57 2007 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_MXC is not set +CONFIG_ARCH_ORION=y +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set + +# +# Orion Implementations +# +CONFIG_MACH_DB88F5281=y +CONFIG_MACH_RD88F5182=y +CONFIG_MACH_KUROBOX_PRO=y +CONFIG_MACH_DNS323=y + +# +# Boot options +# + +# +# Power management +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_FEROCEON=y +CONFIG_CPU_FEROCEON_OLD_ID=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_SYSCALL=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_LEDS=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +CONFIG_FTL=y +CONFIG_NFTL=y +# CONFIG_NFTL_RW is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +CONFIG_MTD_CFI_I4=y +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_ORION=y +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +CONFIG_SCSI_MVSATA=y + +# +# Sata options +# +# CONFIG_MV_SATA_SUPPORT_ATAPI is not set +# CONFIG_MV_SATA_ENABLE_1MB_IOS is not set +CONFIG_SATA_NO_DEBUG=y +# CONFIG_SATA_DEBUG_ON_ERROR is not set +# CONFIG_SATA_FULL_DEBUG is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +CONFIG_ATA=m +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_IP1000 is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_E1000E is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +CONFIG_SKGE=y +CONFIG_SKY2=y +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_TIGON3=y +# CONFIG_BNX2 is not set +CONFIG_MV643XX_ETH=y +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=m +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +CONFIG_I2C_MV64XXX=y + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_SL811_HCD=y +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=y + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +# CONFIG_USB_STORAGE_ISD200 is not set +CONFIG_USB_STORAGE_DPCM=y +# CONFIG_USB_STORAGE_USBAT is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_GPIO is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_RS5C372=y +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_M41T80_WDT is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +CONFIG_LDM_DEBUG=y +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set +CONFIG_INSTRUMENTATION=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_SAMPLES is not set +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_MANAGER=m +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y -- cgit v1.2.3 From 60ce1c20068ec2c138cdf9e5cbe583cc60883c62 Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Wed, 14 Nov 2007 08:58:30 +0100 Subject: [ARM] Orion: enable CONFIG_RTC_DRV_M41T80 for D-Link DNS-323 The D-Link DNS-323 uses a M41T80 RTC chip, so enable this driver in the Orion defconfig. Signed-off-by: Martin Michlmayr Cc: Herbert Valerio Riedel Acked-by: Nicolas Pitre Acked-by: Russell King --- arch/arm/configs/orion_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/configs/orion_defconfig b/arch/arm/configs/orion_defconfig index 9a42b2fc9f65..85b80f6b78e1 100644 --- a/arch/arm/configs/orion_defconfig +++ b/arch/arm/configs/orion_defconfig @@ -1108,7 +1108,7 @@ CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set +CONFIG_RTC_DRV_M41T80=y # CONFIG_RTC_DRV_M41T80_WDT is not set # -- cgit v1.2.3 From 144aa3db1e8faa34bb33c61131494ac879a6d978 Mon Sep 17 00:00:00 2001 From: Herbert Valerio Riedel Date: Mon, 12 Nov 2007 09:51:36 +0200 Subject: [ARM] Orion: I2C support The Orion I2C controller is the same one used in the Discovery family (MV643XX). This patch include the common platform_device stuff according to the existing i2c_mv64xxx.c conventions. Signed-off-by: Herbert Valerio Riedel Signed-off-by: Tzachi Perelstein --- arch/arm/mach-orion/common.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c index ff34827f82a5..5e20b6b32508 100644 --- a/arch/arm/mach-orion/common.c +++ b/arch/arm/mach-orion/common.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -212,6 +213,42 @@ void __init orion_eth_init(struct mv643xx_eth_platform_data *eth_data) platform_device_register(&orion_eth); } +/***************************************************************************** + * I2C controller + * (The Orion and Discovery (MV643xx) families share the same I2C controller) + ****************************************************************************/ + +static struct mv64xxx_i2c_pdata orion_i2c_pdata = { + .freq_m = 8, /* assumes 166 MHz TCLK */ + .freq_n = 3, + .timeout = 1000, /* Default timeout of 1 second */ +}; + +static struct resource orion_i2c_resources[] = { + { + .name = "i2c base", + .start = I2C_BASE, + .end = I2C_BASE + 0x20 -1, + .flags = IORESOURCE_MEM, + }, + { + .name = "i2c irq", + .start = IRQ_ORION_I2C, + .end = IRQ_ORION_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device orion_i2c = { + .name = MV64XXX_I2C_CTLR_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(orion_i2c_resources), + .resource = orion_i2c_resources, + .dev = { + .platform_data = &orion_i2c_pdata, + }, +}; + /***************************************************************************** * General ****************************************************************************/ @@ -274,4 +311,5 @@ void __init orion_init(void) platform_device_register(&orion_ehci0); if (dev == MV88F5182_DEV_ID) platform_device_register(&orion_ehci1); + platform_device_register(&orion_i2c); } -- cgit v1.2.3 From 3faf2ee870c26f6a809af3f32368f96c357ed91b Mon Sep 17 00:00:00 2001 From: Byron Bradley Date: Sat, 15 Dec 2007 20:05:49 +0000 Subject: [ARM] Orion: add support for QNAP TS-109/TS-209 This patch adds support for the Orion/MV88F5182 based QNAP TS-109/TS-209 NAS device. The driver for the S-35390A RTC chip on this board has been submitted to LKML separately. Signed-off-by: Byron Bradley Tested-by: Oyvind Repvik Tested-by: Tim Ellis Tested-by: Herbert Valerio Riedel Acked-by: Tzachi Perelstein --- arch/arm/configs/orion_defconfig | 1 + arch/arm/mach-orion/Kconfig | 6 + arch/arm/mach-orion/Makefile | 1 + arch/arm/mach-orion/ts209-setup.c | 305 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 313 insertions(+) create mode 100644 arch/arm/mach-orion/ts209-setup.c (limited to 'arch/arm') diff --git a/arch/arm/configs/orion_defconfig b/arch/arm/configs/orion_defconfig index 85b80f6b78e1..17a55def1103 100644 --- a/arch/arm/configs/orion_defconfig +++ b/arch/arm/configs/orion_defconfig @@ -147,6 +147,7 @@ CONFIG_MACH_DB88F5281=y CONFIG_MACH_RD88F5182=y CONFIG_MACH_KUROBOX_PRO=y CONFIG_MACH_DNS323=y +CONFIG_MACH_TS209=y # # Boot options diff --git a/arch/arm/mach-orion/Kconfig b/arch/arm/mach-orion/Kconfig index bdaed867e450..1dcbb6ac5a30 100644 --- a/arch/arm/mach-orion/Kconfig +++ b/arch/arm/mach-orion/Kconfig @@ -30,6 +30,12 @@ config MACH_DNS323 Say 'Y' here if you want your kernel to support the D-Link DNS-323 platform. +config MACH_TS209 + bool "QNAP TS-109/TS-209" + help + Say 'Y' here if you want your kernel to support the + QNAP TS-109/TS-209 platform. + endmenu endif diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index 237ce98ad0ef..f91d937a73e8 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o obj-$(CONFIG_MACH_DNS323) += dns323-setup.o +obj-$(CONFIG_MACH_TS209) += ts209-setup.o diff --git a/arch/arm/mach-orion/ts209-setup.c b/arch/arm/mach-orion/ts209-setup.c new file mode 100644 index 000000000000..34f88ac24ac8 --- /dev/null +++ b/arch/arm/mach-orion/ts209-setup.c @@ -0,0 +1,305 @@ +/* + * QNAP TS-109/TS-209 Board Setup + * + * Maintainer: Byron Bradley + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000 +#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M + +/**************************************************************************** + * 8MiB NOR flash. The struct mtd_partition is not in the same order as the + * partitions on the device because we want to keep compatability with + * existing QNAP firmware. + * + * Layout as used by QNAP: + * [2] 0x00000000-0x00200000 : "Kernel" + * [3] 0x00200000-0x00600000 : "RootFS1" + * [4] 0x00600000-0x00700000 : "RootFS2" + * [6] 0x00700000-0x00760000 : "NAS Config" (read-only) + * [5] 0x00760000-0x00780000 : "U-Boot Config" + * [1] 0x00780000-0x00800000 : "U-Boot" (read-only) + ***************************************************************************/ +static struct mtd_partition qnap_ts209_partitions[] = { + { + .name = "U-Boot", + .size = 0x00080000, + .offset = 0x00780000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "Kernel", + .size = 0x00200000, + .offset = 0, + }, { + .name = "RootFS1", + .size = 0x00400000, + .offset = 0x00200000, + }, { + .name = "RootFS2", + .size = 0x00100000, + .offset = 0x00600000, + }, { + .name = "U-Boot Config", + .size = 0x00020000, + .offset = 0x00760000, + }, { + .name = "NAS Config", + .size = 0x00060000, + .offset = 0x00700000, + .mask_flags = MTD_WRITEABLE, + } +}; + +static struct physmap_flash_data qnap_ts209_nor_flash_data = { + .width = 1, + .parts = qnap_ts209_partitions, + .nr_parts = ARRAY_SIZE(qnap_ts209_partitions) +}; + +static struct resource qnap_ts209_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = QNAP_TS209_NOR_BOOT_BASE, + .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device qnap_ts209_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { .platform_data = &qnap_ts209_nor_flash_data, }, + .resource = &qnap_ts209_nor_flash_resource, + .num_resources = 1, +}; + +/***************************************************************************** + * PCI + ****************************************************************************/ + +#define QNAP_TS209_PCI_SLOT0_OFFS 7 +#define QNAP_TS209_PCI_SLOT0_IRQ_PIN 6 +#define QNAP_TS209_PCI_SLOT1_IRQ_PIN 7 + +void __init qnap_ts209_pci_preinit(void) +{ + int pin; + + /* + * Configure PCI GPIO IRQ pins + */ + pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN; + if (gpio_request(pin, "PCI Int1") == 0) { + if (gpio_direction_input(pin) == 0) { + set_irq_type(gpio_to_irq(pin), IRQT_LOW); + } else { + printk(KERN_ERR "qnap_ts209_pci_preinit failed to " + "set_irq_type pin %d\n", pin); + gpio_free(pin); + } + } else { + printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request " + "%d\n", pin); + } + + pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN; + if (gpio_request(pin, "PCI Int2") == 0) { + if (gpio_direction_input(pin) == 0) { + set_irq_type(gpio_to_irq(pin), IRQT_LOW); + } else { + printk(KERN_ERR "qnap_ts209_pci_preinit failed " + "to set_irq_type pin %d\n", pin); + gpio_free(pin); + } + } else { + printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request " + "%d\n", pin); + } +} + +static int __init qnap_ts209_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + /* + * PCIE IRQ is connected internally (not GPIO) + */ + if (dev->bus->number == orion_pcie_local_bus_nr()) + return IRQ_ORION_PCIE0_INT; + + /* + * PCI IRQs are connected via GPIOs + */ + switch (slot - QNAP_TS209_PCI_SLOT0_OFFS) { + case 0: + return gpio_to_irq(QNAP_TS209_PCI_SLOT0_IRQ_PIN); + case 1: + return gpio_to_irq(QNAP_TS209_PCI_SLOT1_IRQ_PIN); + default: + return -1; + } +} + +static struct hw_pci qnap_ts209_pci __initdata = { + .nr_controllers = 2, + .preinit = qnap_ts209_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = orion_pci_sys_setup, + .scan = orion_pci_sys_scan_bus, + .map_irq = qnap_ts209_pci_map_irq, +}; + +static int __init qnap_ts209_pci_init(void) +{ + if (machine_is_ts_x09()) + pci_common_init(&qnap_ts209_pci); + + return 0; +} + +subsys_initcall(qnap_ts209_pci_init); + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data qnap_ts209_eth_data = { + .phy_addr = 8, + .force_phy_addr = 1, +}; + +/***************************************************************************** + * RTC S35390A on I2C bus + ****************************************************************************/ +static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = { + .driver_name = "rtc-s35390a", + .addr = 0x30, +}; + +/**************************************************************************** + * GPIO Attached Keys + * Power button is attached to the PIC microcontroller + ****************************************************************************/ + +#define QNAP_TS209_GPIO_KEY_MEDIA 1 +#define QNAP_TS209_GPIO_KEY_RESET 2 + +static struct gpio_keys_button qnap_ts209_buttons[] = { + { + .code = KEY_RESTART, + .gpio = QNAP_TS209_GPIO_KEY_MEDIA, + .desc = "USB Copy Button", + .active_low = 1, + }, + { + .code = KEY_POWER, + .gpio = QNAP_TS209_GPIO_KEY_RESET, + .desc = "Reset Button", + .active_low = 1, + } +}; + +static struct gpio_keys_platform_data qnap_ts209_button_data = { + .buttons = qnap_ts209_buttons, + .nbuttons = ARRAY_SIZE(qnap_ts209_buttons), +}; + +static struct platform_device qnap_ts209_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { .platform_data = &qnap_ts209_button_data, }, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static struct platform_device *qnap_ts209_devices[] __initdata = { + &qnap_ts209_nor_flash, + &qnap_ts209_button_device, +}; + +static void __init qnap_ts209_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion_init(); + + /* + * Setup flash mapping + */ + orion_setup_cpu_win(ORION_DEV_BOOT, QNAP_TS209_NOR_BOOT_BASE, + QNAP_TS209_NOR_BOOT_SIZE, -1); + + /* + * Open a special address decode windows for the PCIE WA. + */ + orion_write(ORION_REGS_BASE | 0x20074, ORION_PCIE_WA_BASE); + orion_write(ORION_REGS_BASE | 0x20070, (0x7941 | + (((ORION_PCIE_WA_SIZE >> 16) - 1)) << 16)); + + /* + * Setup Multiplexing Pins -- + * MPP[0] Reserved + * MPP[1] USB copy button (0 active) + * MPP[2] Load defaults button (0 active) + * MPP[3] GPIO RTC + * MPP[4-5] Reserved + * MPP[6] PCI Int A + * MPP[7] PCI Int B + * MPP[8-11] Reserved + * MPP[12] SATA 0 presence + * MPP[13] SATA 1 presence + * MPP[14] SATA 0 active + * MPP[15] SATA 1 active + * MPP[16] UART1 RXD + * MPP[17] UART1 TXD + * MPP[18] SW_RST (0 active) + * MPP[19] Reserved + * MPP[20] PCI clock 0 + * MPP[21] PCI clock 1 + * MPP[22] USB 0 over current + * MPP[23-25] Reserved + */ + orion_write(MPP_0_7_CTRL, 0x3); + orion_write(MPP_8_15_CTRL, 0x55550000); + orion_write(MPP_16_19_CTRL, 0x5500); + orion_gpio_set_valid_pins(0x3cc0fff); + + platform_add_devices(qnap_ts209_devices, + ARRAY_SIZE(qnap_ts209_devices)); + i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1); + orion_eth_init(&qnap_ts209_eth_data); +} + +MACHINE_START(TS209, "QNAP TS-109/TS-209") + /* Maintainer: Byron Bradley */ + .phys_io = ORION_REGS_BASE, + .io_pg_offst = ((ORION_REGS_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = qnap_ts209_init, + .map_io = orion_map_io, + .init_irq = orion_init_irq, + .timer = &orion_timer, +MACHINE_END -- cgit v1.2.3 From 8f86dda3ed8f05748f2351ae967926227a91ca2a Mon Sep 17 00:00:00 2001 From: Herbert Valerio Riedel Date: Sun, 16 Dec 2007 17:42:31 +0100 Subject: [ARM] Orion: implement power-off method for QNAP TS-109/209 Since the PIC is attached to UART1, it doesn't need a kernel device driver of its own; but powering off is something that the kernel should do, so this patch forcefully configures the UART1 for 19200 baud and sends the character that tells the PIC to cut the power. Signed-off-by: Herbert Valerio Riedel Cc: Byron Bradley Acked-by: Nicolas Pitre --- arch/arm/mach-orion/ts209-setup.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-orion/ts209-setup.c b/arch/arm/mach-orion/ts209-setup.c index 34f88ac24ac8..e3e930efd155 100644 --- a/arch/arm/mach-orion/ts209-setup.c +++ b/arch/arm/mach-orion/ts209-setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -239,6 +240,32 @@ static struct platform_device *qnap_ts209_devices[] __initdata = { &qnap_ts209_button_device, }; +/* + * QNAP TS-[12]09 specific power off method via UART1-attached PIC + */ + +#define UART1_REG(x) (UART1_BASE + ((UART_##x) << 2)) + +static void qnap_ts209_power_off(void) +{ + /* 19200 baud divisor */ + const unsigned divisor = ((ORION_TCLK + (8 * 19200)) / (16 * 19200)); + + pr_info("%s: triggering power-off...\n", __func__); + + /* hijack uart1 and reset into sane state (19200,8n1) */ + orion_write(UART1_REG(LCR), 0x83); + orion_write(UART1_REG(DLL), divisor & 0xff); + orion_write(UART1_REG(DLM), (divisor >> 8) & 0xff); + orion_write(UART1_REG(LCR), 0x03); + orion_write(UART1_REG(IER), 0x00); + orion_write(UART1_REG(FCR), 0x00); + orion_write(UART1_REG(MCR), 0x00); + + /* send the power-off command 'A' to PIC */ + orion_write(UART1_REG(TX), 'A'); +} + static void __init qnap_ts209_init(void) { /* @@ -287,6 +314,9 @@ static void __init qnap_ts209_init(void) orion_write(MPP_16_19_CTRL, 0x5500); orion_gpio_set_valid_pins(0x3cc0fff); + /* register ts209 specific power-off method */ + pm_power_off = qnap_ts209_power_off; + platform_add_devices(qnap_ts209_devices, ARRAY_SIZE(qnap_ts209_devices)); i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1); -- cgit v1.2.3