summaryrefslogtreecommitdiff
path: root/sys/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/arm')
-rw-r--r--sys/arch/arm/arm/cpufunc_asm_xscale.S498
-rw-r--r--sys/arch/arm/conf/ldscript.head25
-rw-r--r--sys/arch/arm/conf/ldscript.tail52
-rw-r--r--sys/arch/arm/sa11x0/sa1111_reg.h128
-rw-r--r--sys/arch/arm/sa11x0/sa11x0_ost.c369
-rw-r--r--sys/arch/arm/sa11x0/sa11x0_ostreg.h80
-rw-r--r--sys/arch/arm/sa11x0/sa11x0_reg.h78
-rw-r--r--sys/arch/arm/sa11x0/sa11x0_var.h76
-rw-r--r--sys/arch/arm/xscale/files.pxa2x059
-rw-r--r--sys/arch/arm/xscale/pxa2x0.c393
-rw-r--r--sys/arch/arm/xscale/pxa2x0_a4x_io.S103
-rw-r--r--sys/arch/arm/xscale/pxa2x0_a4x_space.c138
-rw-r--r--sys/arch/arm/xscale/pxa2x0_com.c149
-rw-r--r--sys/arch/arm/xscale/pxa2x0_dma.c75
-rw-r--r--sys/arch/arm/xscale/pxa2x0_gpio.c518
-rw-r--r--sys/arch/arm/xscale/pxa2x0_gpio.h62
-rw-r--r--sys/arch/arm/xscale/pxa2x0_intr.c465
-rw-r--r--sys/arch/arm/xscale/pxa2x0_intr.h192
-rw-r--r--sys/arch/arm/xscale/pxa2x0_lcd.c743
-rw-r--r--sys/arch/arm/xscale/pxa2x0_lcd.h149
-rw-r--r--sys/arch/arm/xscale/pxa2x0_space.c267
-rw-r--r--sys/arch/arm/xscale/pxa2x0reg.h612
-rw-r--r--sys/arch/arm/xscale/pxa2x0var.h89
-rw-r--r--sys/arch/arm/xscale/pxapcicvar.h87
24 files changed, 5407 insertions, 0 deletions
diff --git a/sys/arch/arm/arm/cpufunc_asm_xscale.S b/sys/arch/arm/arm/cpufunc_asm_xscale.S
new file mode 100644
index 00000000000..56610025b84
--- /dev/null
+++ b/sys/arch/arm/arm/cpufunc_asm_xscale.S
@@ -0,0 +1,498 @@
+/* $NetBSD: cpufunc_asm_xscale.S,v 1.16 2002/08/17 16:36:32 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Allen Briggs and Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2001 Matt Thomas.
+ * Copyright (c) 1997,1998 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Causality Limited.
+ * 4. The name of Causality Limited may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * XScale assembly functions for CPU / MMU / TLB specific operations
+ */
+
+#include <machine/cpu.h>
+#include <machine/asm.h>
+
+/*
+ * Size of the XScale core D-cache.
+ */
+#define DCACHE_SIZE 0x00008000
+
+#ifndef CACHE_CLEAN_BLOCK_INTR
+.Lblock_userspace_access:
+ .word _C_LABEL(block_userspace_access)
+#endif
+
+/*
+ * CPWAIT -- Canonical method to wait for CP15 update.
+ * From: Intel 80200 manual, section 2.3.3.
+ *
+ * NOTE: Clobbers the specified temp reg.
+ */
+#define CPWAIT_BRANCH \
+ sub pc, pc, #4
+
+#define CPWAIT(tmp) \
+ mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\
+ mov tmp, tmp /* wait for it to complete */ ;\
+ CPWAIT_BRANCH /* branch to next insn */
+
+#define CPWAIT_AND_RETURN_SHIFTER lsr #32
+
+#define CPWAIT_AND_RETURN(tmp) \
+ mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\
+ /* Wait for it to complete and branch to the return address */ \
+ sub pc, lr, tmp, CPWAIT_AND_RETURN_SHIFTER
+
+ENTRY(xscale_cpwait)
+ CPWAIT_AND_RETURN(r0)
+
+/*
+ * We need a separate cpu_control() entry point, since we have to
+ * invalidate the Branch Target Buffer in the event the BPRD bit
+ * changes in the control register.
+ */
+ENTRY(xscale_control)
+ mrc p15, 0, r3, c1, c0, 0 /* Read the control register */
+ bic r2, r3, r0 /* Clear bits */
+ eor r2, r2, r1 /* XOR bits */
+
+ teq r2, r3 /* Only write if there was a change */
+ mcrne p15, 0, r0, c7, c5, 6 /* Invalidate the BTB */
+ mcrne p15, 0, r2, c1, c0, 0 /* Write new control register */
+ mov r0, r3 /* Return old value */
+
+ CPWAIT_AND_RETURN(r1)
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(xscale_setttb)
+#ifdef CACHE_CLEAN_BLOCK_INTR
+ mrs r3, cpsr_all
+ orr r1, r3, #(I32_bit | F32_bit)
+ msr cpsr_all, r1
+#else
+ ldr r3, .Lblock_userspace_access
+ ldr r2, [r3]
+ orr r1, r2, #1
+ str r1, [r3]
+#endif
+ stmfd sp!, {r0-r3, lr}
+ bl _C_LABEL(xscale_cache_cleanID)
+ mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ and BTB */
+ mcr p15, 0, r0, c7, c10, 4 /* drain write and fill buffer */
+
+ CPWAIT(r0)
+
+ ldmfd sp!, {r0-r3, lr}
+
+ /* Write the TTB */
+ mcr p15, 0, r0, c2, c0, 0
+
+ /* If we have updated the TTB we must flush the TLB */
+ mcr p15, 0, r0, c8, c7, 0 /* invalidate I+D TLB */
+
+ /* The cleanID above means we only need to flush the I cache here */
+ mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ and BTB */
+
+ CPWAIT(r0)
+
+#ifdef CACHE_CLEAN_BLOCK_INTR
+ msr cpsr_all, r3
+#else
+ str r2, [r3]
+#endif
+ mov pc, lr
+
+/*
+ * TLB functions
+ *
+ * Note: We don't need to worry about issuing a CPWAIT after
+ * TLB operations, because we expect a pmap_update() to follow.
+ */
+ENTRY(xscale_tlb_flushID_SE)
+ mcr p15, 0, r0, c8, c6, 1 /* flush D tlb single entry */
+ mcr p15, 0, r0, c8, c5, 1 /* flush I tlb single entry */
+ mov pc, lr
+
+/*
+ * Cache functions
+ */
+ENTRY(xscale_cache_flushID)
+ mcr p15, 0, r0, c7, c7, 0 /* flush I+D cache */
+ CPWAIT_AND_RETURN(r0)
+
+ENTRY(xscale_cache_flushI)
+ mcr p15, 0, r0, c7, c5, 0 /* flush I cache */
+ CPWAIT_AND_RETURN(r0)
+
+ENTRY(xscale_cache_flushD)
+ mcr p15, 0, r0, c7, c6, 0 /* flush D cache */
+ CPWAIT_AND_RETURN(r0)
+
+ENTRY(xscale_cache_flushI_SE)
+ mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */
+ CPWAIT_AND_RETURN(r0)
+
+ENTRY(xscale_cache_flushD_SE)
+ /*
+ * Errata (rev < 2): Must clean-dcache-line to an address
+ * before invalidate-dcache-line to an address, or dirty
+ * bits will not be cleared in the dcache array.
+ */
+ mcr p15, 0, r0, c7, c10, 1
+ mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
+ CPWAIT_AND_RETURN(r0)
+
+ENTRY(xscale_cache_cleanD_E)
+ mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
+ CPWAIT_AND_RETURN(r0)
+
+/*
+ * Information for the XScale cache clean/purge functions:
+ *
+ * * Virtual address of the memory region to use
+ * * Size of memory region
+ *
+ * Note the virtual address for the Data cache clean operation
+ * does not need to be backed by physical memory, since no loads
+ * will actually be performed by the allocate-line operation.
+ *
+ * Note that the Mini-Data cache MUST be cleaned by executing
+ * loads from memory mapped into a region reserved exclusively
+ * for cleaning of the Mini-Data cache.
+ */
+ .data
+
+ .global _C_LABEL(xscale_cache_clean_addr)
+_C_LABEL(xscale_cache_clean_addr):
+ .word 0x00000000
+
+ .global _C_LABEL(xscale_cache_clean_size)
+_C_LABEL(xscale_cache_clean_size):
+ .word DCACHE_SIZE
+
+# .global _C_LABEL(xscale_minidata_clean_addr)
+#_C_LABEL(xscale_minidata_clean_addr):
+# .word 0x00000000
+
+# .global _C_LABEL(xscale_minidata_clean_size)
+#_C_LABEL(xscale_minidata_clean_size):
+# .word 0x00000800
+
+ .text
+
+.Lxscale_cache_clean_addr:
+ .word _C_LABEL(xscale_cache_clean_addr)
+.Lxscale_cache_clean_size:
+ .word _C_LABEL(xscale_cache_clean_size)
+
+.Lxscale_minidata_clean_addr:
+ .word _C_LABEL(xscale_minidata_clean_addr)
+.Lxscale_minidata_clean_size:
+ .word _C_LABEL(xscale_minidata_clean_size)
+
+#ifdef CACHE_CLEAN_BLOCK_INTR
+#define XSCALE_CACHE_CLEAN_BLOCK \
+ mrs r3, cpsr_all ; \
+ orr r0, r3, #(I32_bit | F32_bit) ; \
+ msr cpsr_all, r0
+
+#define XSCALE_CACHE_CLEAN_UNBLOCK \
+ msr cpsr_all, r3
+#else
+#define XSCALE_CACHE_CLEAN_BLOCK \
+ ldr r3, .Lblock_userspace_access ; \
+ ldr ip, [r3] ; \
+ orr r0, ip, #1 ; \
+ str r0, [r3]
+
+#define XSCALE_CACHE_CLEAN_UNBLOCK \
+ str ip, [r3]
+#endif /* CACHE_CLEAN_BLOCK_INTR */
+
+#define XSCALE_CACHE_CLEAN_PROLOGUE \
+ XSCALE_CACHE_CLEAN_BLOCK ; \
+ ldr r2, .Lxscale_cache_clean_addr ; \
+ ldmia r2, {r0, r1} ; \
+ /* \
+ * BUG ALERT! \
+ * \
+ * The XScale core has a strange cache eviction bug, which \
+ * requires us to use 2x the cache size for the cache clean \
+ * and for that area to be aligned to 2 * cache size. \
+ * \
+ * The work-around is to use 2 areas for cache clean, and to \
+ * alternate between them whenever this is done. No one knows \
+ * why the work-around works (mmm!). \
+ */ \
+ eor r0, r0, #(DCACHE_SIZE) ; \
+ str r0, [r2] ; \
+ add r0, r0, r1
+
+#define XSCALE_CACHE_CLEAN_EPILOGUE \
+ XSCALE_CACHE_CLEAN_UNBLOCK
+
+ENTRY_NP(xscale_cache_syncI)
+ENTRY_NP(xscale_cache_purgeID)
+ mcr p15, 0, r0, c7, c5, 0 /* flush I cache (D cleaned below) */
+ENTRY_NP(xscale_cache_cleanID)
+ENTRY_NP(xscale_cache_purgeD)
+ENTRY(xscale_cache_cleanD)
+ XSCALE_CACHE_CLEAN_PROLOGUE
+
+1: subs r0, r0, #32
+ mcr p15, 0, r0, c7, c2, 5 /* allocate cache line */
+ subs r1, r1, #32
+ bne 1b
+
+ CPWAIT(r0)
+
+ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
+
+ CPWAIT(r0)
+
+ XSCALE_CACHE_CLEAN_EPILOGUE
+ mov pc, lr
+
+/*
+ * Clean the mini-data cache.
+ *
+ * It's expected that we only use the mini-data cache for
+ * kernel addresses, so there is no need to purge it on
+ * context switch, and no need to prevent userspace access
+ * while we clean it.
+ */
+ENTRY(xscale_cache_clean_minidata)
+ ldr r2, .Lxscale_minidata_clean_addr
+ ldmia r2, {r0, r1}
+1: ldr r3, [r0], #32
+ subs r1, r1, #32
+ bne 1b
+
+ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
+
+ CPWAIT_AND_RETURN(r1)
+
+ENTRY(xscale_cache_purgeID_E)
+ mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
+ CPWAIT(r1)
+ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
+ mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */
+ mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
+ CPWAIT_AND_RETURN(r1)
+
+ENTRY(xscale_cache_purgeD_E)
+ mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
+ CPWAIT(r1)
+ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
+ mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
+ CPWAIT_AND_RETURN(r1)
+
+/*
+ * Soft functions
+ */
+/* xscale_cache_syncI is identical to xscale_cache_purgeID */
+
+ENTRY(xscale_cache_cleanID_rng)
+ENTRY(xscale_cache_cleanD_rng)
+ cmp r1, #0x4000
+ bcs _C_LABEL(xscale_cache_cleanID)
+
+ and r2, r0, #0x1f
+ add r1, r1, r2
+ bic r0, r0, #0x1f
+
+1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
+ add r0, r0, #32
+ subs r1, r1, #32
+ bhi 1b
+
+ CPWAIT(r0)
+
+ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
+
+ CPWAIT_AND_RETURN(r0)
+
+ENTRY(xscale_cache_purgeID_rng)
+ cmp r1, #0x4000
+ bcs _C_LABEL(xscale_cache_purgeID)
+
+ and r2, r0, #0x1f
+ add r1, r1, r2
+ bic r0, r0, #0x1f
+
+1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
+ mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
+ mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */
+ add r0, r0, #32
+ subs r1, r1, #32
+ bhi 1b
+
+ CPWAIT(r0)
+
+ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
+
+ CPWAIT_AND_RETURN(r0)
+
+ENTRY(xscale_cache_purgeD_rng)
+ cmp r1, #0x4000
+ bcs _C_LABEL(xscale_cache_purgeD)
+
+ and r2, r0, #0x1f
+ add r1, r1, r2
+ bic r0, r0, #0x1f
+
+1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
+ mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
+ add r0, r0, #32
+ subs r1, r1, #32
+ bhi 1b
+
+ CPWAIT(r0)
+
+ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
+
+ CPWAIT_AND_RETURN(r0)
+
+ENTRY(xscale_cache_syncI_rng)
+ cmp r1, #0x4000
+ bcs _C_LABEL(xscale_cache_syncI)
+
+ and r2, r0, #0x1f
+ add r1, r1, r2
+ bic r0, r0, #0x1f
+
+1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */
+ mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */
+ add r0, r0, #32
+ subs r1, r1, #32
+ bhi 1b
+
+ CPWAIT(r0)
+
+ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
+
+ CPWAIT_AND_RETURN(r0)
+
+ENTRY(xscale_cache_flushD_rng)
+ and r2, r0, #0x1f
+ add r1, r1, r2
+ bic r0, r0, #0x1f
+
+1: mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */
+ add r0, r0, #32
+ subs r1, r1, #32
+ bhi 1b
+
+ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
+
+ CPWAIT_AND_RETURN(r0)
+
+/*
+ * Context switch.
+ *
+ * These is the CPU-specific parts of the context switcher cpu_switch()
+ * These functions actually perform the TTB reload.
+ *
+ * NOTE: Special calling convention
+ * r1, r4-r13 must be preserved
+ */
+ENTRY(xscale_context_switch)
+ /*
+ * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
+ * Thus the data cache will contain only kernel data and the
+ * instruction cache will contain only kernel code, and all
+ * kernel mappings are shared by all processes.
+ */
+
+ /* Write the TTB */
+ mcr p15, 0, r0, c2, c0, 0
+
+ /* If we have updated the TTB we must flush the TLB */
+ mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */
+
+ CPWAIT_AND_RETURN(r0)
+
+/*
+ * xscale_cpu_sleep
+ *
+ * This is called when there is nothing on any of the run queues.
+ * We go into IDLE mode so that any IRQ or FIQ will awaken us.
+ *
+ * If this is called with anything other than ARM_SLEEP_MODE_IDLE,
+ * ignore it.
+ */
+ENTRY(xscale_cpu_sleep)
+ tst r0, #0x00000000
+ bne 1f
+ mov r0, #0x1
+ mcr p14, 0, r0, c7, c0, 0
+
+1:
+ mov pc, lr
diff --git a/sys/arch/arm/conf/ldscript.head b/sys/arch/arm/conf/ldscript.head
new file mode 100644
index 00000000000..58e099f1d5d
--- /dev/null
+++ b/sys/arch/arm/conf/ldscript.head
@@ -0,0 +1,25 @@
+/* $NetBSD: ldscript.evbarm,v 1.2 2003/03/05 23:54:22 thorpej Exp $
+*/
+
+OUTPUT_ARCH(arm)
+ENTRY(KERNEL_BASE_phys)
+SECTIONS
+{
+ KERNEL_BASE_phys = @KERNEL_BASE_PHYS@;
+ KERNEL_BASE_virt = @KERNEL_BASE_VIRT@;
+
+ /* Kernel start: */
+ .start (KERNEL_BASE_phys) :
+ {
+ *(.start)
+ } =0
+
+ /* Read-only sections, merged into text segment: */
+ .text (KERNEL_BASE_virt + SIZEOF(.start)) :
+ AT (LOADADDR(.start) + SIZEOF(.start))
+ {
+ *(.text)
+ *(.text.*)
+ *(.stub)
+ *(.glue_7t) *(.glue_7)
+ *(.rodata) *(.rodata.*)
diff --git a/sys/arch/arm/conf/ldscript.tail b/sys/arch/arm/conf/ldscript.tail
new file mode 100644
index 00000000000..b6af89f2632
--- /dev/null
+++ b/sys/arch/arm/conf/ldscript.tail
@@ -0,0 +1,52 @@
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ /* Adjust the address for the data segment to start on the next page
+ boundary. */
+ . = ALIGN(0x8000);
+ .data :
+ AT (LOADADDR(.text) + (ADDR(.data) - ADDR(.text)))
+ {
+ __data_start = . ;
+ *(.data)
+ *(.data.*)
+ }
+ .sdata :
+ AT (LOADADDR(.data) + (ADDR(.sdata) - ADDR(.data)))
+ {
+ *(.sdata)
+ *(.sdata.*)
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ PROVIDE (___sbss_start = .);
+ *(.dynsbss)
+ *(.sbss)
+ *(.sbss.*)
+ *(.scommon)
+ PROVIDE (__sbss_end = .);
+ PROVIDE (___sbss_end = .);
+ }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = .;
+ _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+ PROVIDE (end = .);
+}
+
diff --git a/sys/arch/arm/sa11x0/sa1111_reg.h b/sys/arch/arm/sa11x0/sa1111_reg.h
new file mode 100644
index 00000000000..f34a7dcaf81
--- /dev/null
+++ b/sys/arch/arm/sa11x0/sa1111_reg.h
@@ -0,0 +1,128 @@
+/* $NetBSD: sa1111_reg.h,v 1.3 2002/12/18 04:09:31 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by IWAMOTO Toshihiro.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ARM_SA11X0_SA1111_REG_H
+#define _ARM_SA11X0_SA1111_REG_H
+
+
+/* Interrupt Controller */
+
+/* number of interrupt bits */
+#define SACCIC_LEN 55
+
+/* System Bus Interface */
+#define SACCSBI_SKCR 0x0000
+#define SKCR_PLLBYPASS (1<<0)
+#define SKCR_RCLKEN (1<<1)
+#define SKCR_SLEEP (1<<2)
+#define SKCR_DOZE (1<<3)
+#define SKCR_VCOOFF (1<<4)
+#define SKCR_RDYEN (1<<7)
+#define SKCR_SELAC (1<<8) /* AC Link or I2S */
+#define SKCR_NOEEN (1<<12) /* Enable nOE */
+#define SACCSBI_SMCR 0x0004
+#define SACCSBI_SKID 0x0008
+
+/* System Controller */
+#define SACCSC_SKPCR 0x0200
+
+/* USB Host Controller */
+#define SACCUSB_REVISION 0x0400
+#define SACCUSB_CONTROL 0x0404
+#define SACCUSB_STATUS 0x0408
+#define SACCUSB_RESET 0x051C
+
+/* Interrupt Controller */
+#define SACCIC_INTTEST0 0x1600
+#define SACCIC_INTTEST1 0x1604
+#define SACCIC_INTEN0 0x1608
+#define SACCIC_INTEN1 0x160C
+#define SACCIC_INTPOL0 0x1610
+#define SACCIC_INTPOL1 0x1614
+#define SACCIC_INTTSTSEL 0x1618
+#define SACCIC_INTSTATCLR0 0x161C
+#define SACCIC_INTSTATCLR1 0x1620
+#define SACCIC_INTSET0 0x1624
+#define SACCIC_INTSET1 0x1628
+#define SACCIC_WAKE_EN0 0x162C
+#define SACCIC_WAKE_EN1 0x1630
+#define SACCIC_WAKE_POL0 0x1634
+#define SACCIC_WAKE_POL1 0x1638
+
+/* GPIO registers */
+#define SACCGPIOA_DDR 0x1000 /* data direction */
+#define SACCGPIOA_DVR 0x1004 /* data value */
+#define SACCGPIOA_SDR 0x1008 /* sleep direction */
+#define SACCGPIOA_SSR 0x100C /* sleep state */
+#define SACCGPIOB_DDR 0x1010
+#define SACCGPIOB_DVR 0x1014
+#define SACCGPIOB_SDR 0x1018
+#define SACCGPIOB_SSR 0x101C
+#define SACCGPIOC_DDR 0x1020
+#define SACCGPIOC_DVR 0x1024
+#define SACCGPIOC_SDR 0x1028
+#define SACCGPIOC_SSR 0x102C
+
+#define SACC_KBD0 0x0a00
+#define SACC_KBD1 0x0c00
+
+#define SACCKBD_CR 0x00
+#define KBDCR_FKC (1<<0) /* Force MSCLK/TPCLK low */
+#define KBDCR_FKD (1<<1) /* Force MSDATA/TPDATA low */
+#define KBDCR_ENA (1<<3) /* Enable */
+#define SACCKBD_STAT 0x04
+#define KBDSTAT_KBC (1<<0) /* KBCLK pin value */
+#define KBDSTAT_KBD (1<<1) /* KBDATA pin value */
+#define KBDSTAT_RXP (1<<2) /* Parity */
+#define KBDSTAT_ENA (1<<3) /* Enable */
+#define KBDSTAT_RXB (1<<4) /* Rx busy */
+#define KBDSTAT_RXF (1<<5) /* Rx full */
+#define KBDSTAT_TXB (1<<6) /* Tx busy */
+#define KBDSTAT_TXE (1<<7) /* Tx empty */
+#define KBDSTAT_STP (1<<8) /* Stop bit error */
+#define SACCKBD_DATA 0x08
+#define SACCKBD_CLKDIV 0x0c
+#define KBDCLKDIV_DIV8 0
+#define KBDCLKDIV_DIV4 1
+#define KBDCLKDIV_DIV2 2
+#define SACCKBD_CLKPRECNT 0x10
+#define SACCKBD_KBDITR 0x14 /* Interrupt test */
+
+#define SACCKBD_SIZE 0x18
+
+#endif /* _ARM_SA11X0_SA1111_REG_H */
diff --git a/sys/arch/arm/sa11x0/sa11x0_ost.c b/sys/arch/arm/sa11x0/sa11x0_ost.c
new file mode 100644
index 00000000000..76a02f3080b
--- /dev/null
+++ b/sys/arch/arm/sa11x0/sa11x0_ost.c
@@ -0,0 +1,369 @@
+/* $NetBSD: sa11x0_ost.c,v 1.11 2003/07/15 00:24:51 lukem Exp $ */
+
+/*
+ * Copyright (c) 1997 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by IWAMOTO Toshihiro and Ichiro FUKUHARA.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+/*
+__KERNEL_RCSID(0, "$NetBSD: sa11x0_ost.c,v 1.11 2003/07/15 00:24:51 lukem Exp $");
+*/
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/time.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <arm/cpufunc.h>
+
+#include <arm/sa11x0/sa11x0_reg.h>
+#include <arm/sa11x0/sa11x0_var.h>
+#include <arm/sa11x0/sa11x0_ostreg.h>
+
+static int saost_match(struct device *, void *, void *);
+static void saost_attach(struct device *, struct device *, void *);
+
+int gettick(void);
+static int clockintr(void *);
+static int statintr(void *);
+void rtcinit(void);
+
+struct saost_softc {
+ struct device sc_dev;
+ bus_addr_t sc_baseaddr;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+
+ u_int32_t sc_clock_count;
+ u_int32_t sc_statclock_count;
+ u_int32_t sc_statclock_step;
+};
+
+static struct saost_softc *saost_sc = NULL;
+
+#define TIMER_FREQUENCY 3686400 /* 3.6864MHz */
+#define TICKS_PER_MICROSECOND (TIMER_FREQUENCY/1000000)
+
+#ifndef STATHZ
+#define STATHZ 64
+#endif
+
+#if 0
+CFATTACH_DECL(saost, sizeof(struct saost_softc),
+ saost_match, saost_attach, NULL, NULL);
+#endif
+
+struct cfattach saost_ca = {
+ sizeof (struct saost_softc), saost_match, saost_attach
+};
+
+struct cfdriver saost_cd = {
+ NULL, "saost", DV_DULL
+};
+
+static int
+saost_match(parent, match, aux)
+ struct device *parent;
+ void *match;
+ void *aux;
+{
+ return (1);
+}
+
+void
+saost_attach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct saost_softc *sc = (struct saost_softc*)self;
+ struct sa11x0_attach_args *sa = aux;
+
+ printf("\n");
+
+ sc->sc_iot = sa->sa_iot;
+ sc->sc_baseaddr = sa->sa_addr;
+
+ saost_sc = sc;
+
+ if(bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0,
+ &sc->sc_ioh))
+ panic("%s: Cannot map registers", self->dv_xname);
+
+ /* disable all channel and clear interrupt status */
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_IR, 0);
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_SR, 0xf);
+
+ printf("%s: SA-11x0 OS Timer\n", sc->sc_dev.dv_xname);
+}
+
+static int
+clockintr(arg)
+ void *arg;
+{
+ struct clockframe *frame = arg;
+ u_int32_t oscr, nextmatch, oldmatch;
+ int s;
+
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_SR, 1);
+
+ /* schedule next clock intr */
+ oldmatch = saost_sc->sc_clock_count;
+ nextmatch = oldmatch + TIMER_FREQUENCY / hz;
+
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_MR0,
+ nextmatch);
+ oscr = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_CR);
+
+ if ((nextmatch > oldmatch &&
+ (oscr > nextmatch || oscr < oldmatch)) ||
+ (nextmatch < oldmatch && oscr > nextmatch && oscr < oldmatch)) {
+ /*
+ * we couldn't set the matching register in time.
+ * just set it to some value so that next interrupt happens.
+ * XXX is it possible to compansate lost interrupts?
+ */
+
+ s = splhigh();
+ oscr = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_CR);
+ nextmatch = oscr + 10;
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_MR0, nextmatch);
+ splx(s);
+ }
+
+ saost_sc->sc_clock_count = nextmatch;
+ hardclock(frame);
+
+ return(1);
+}
+
+static int
+statintr(arg)
+ void *arg;
+{
+ struct clockframe *frame = arg;
+ u_int32_t oscr, nextmatch, oldmatch;
+ int s;
+
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_SR, 2);
+
+ /* schedule next clock intr */
+ oldmatch = saost_sc->sc_statclock_count;
+ nextmatch = oldmatch + saost_sc->sc_statclock_step;
+
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_MR1,
+ nextmatch);
+ oscr = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_CR);
+
+ if ((nextmatch > oldmatch &&
+ (oscr > nextmatch || oscr < oldmatch)) ||
+ (nextmatch < oldmatch && oscr > nextmatch && oscr < oldmatch)) {
+ /*
+ * we couldn't set the matching register in time.
+ * just set it to some value so that next interrupt happens.
+ * XXX is it possible to compansate lost interrupts?
+ */
+
+ s = splhigh();
+ oscr = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_CR);
+ nextmatch = oscr + 10;
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_MR1, nextmatch);
+ splx(s);
+ }
+
+ saost_sc->sc_statclock_count = nextmatch;
+ statclock(frame);
+
+ return(1);
+}
+
+
+void
+setstatclockrate(hz)
+ int hz;
+{
+ u_int32_t count;
+
+ saost_sc->sc_statclock_step = TIMER_FREQUENCY / hz;
+ count = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_CR);
+ count += saost_sc->sc_statclock_step;
+ saost_sc->sc_statclock_count = count;
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_MR1, count);
+}
+
+void
+cpu_initclocks()
+{
+ stathz = STATHZ;
+ profhz = stathz;
+ saost_sc->sc_statclock_step = TIMER_FREQUENCY / stathz;
+
+ printf("clock: hz=%d stathz = %d\n", hz, stathz);
+
+ /* Use the channels 0 and 1 for hardclock and statclock, respectively */
+ saost_sc->sc_clock_count = TIMER_FREQUENCY / hz;
+ saost_sc->sc_statclock_count = TIMER_FREQUENCY / stathz;
+
+ sa11x0_intr_establish(0, 26, 1, IPL_CLOCK, clockintr, 0);
+ sa11x0_intr_establish(0, 27, 1, IPL_CLOCK, statintr, 0);
+
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_SR, 0xf);
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_IR, 3);
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_MR0,
+ saost_sc->sc_clock_count);
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_MR1,
+ saost_sc->sc_statclock_count);
+
+ /* Zero the counter value */
+ bus_space_write_4(saost_sc->sc_iot, saost_sc->sc_ioh, SAOST_CR, 0);
+}
+
+int
+gettick()
+{
+ int counter;
+ u_int savedints;
+ savedints = disable_interrupts(I32_bit);
+
+ counter = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_CR);
+
+ restore_interrupts(savedints);
+ return counter;
+}
+
+void
+microtime(tvp)
+ register struct timeval *tvp;
+{
+ int s, tm, deltatm;
+ static struct timeval lasttime;
+
+ if(saost_sc == NULL) {
+ tvp->tv_sec = 0;
+ tvp->tv_usec = 0;
+ return;
+ }
+
+ s = splhigh();
+ tm = bus_space_read_4(saost_sc->sc_iot, saost_sc->sc_ioh,
+ SAOST_CR);
+
+ deltatm = saost_sc->sc_clock_count - tm;
+
+#ifdef OST_DEBUG
+ printf("deltatm = %d\n",deltatm);
+#endif
+
+ *tvp = time;
+ tvp->tv_usec++; /* XXX */
+ while (tvp->tv_usec >= 1000000) {
+ tvp->tv_sec++;
+ tvp->tv_usec -= 1000000;
+ }
+
+ if (tvp->tv_sec == lasttime.tv_sec &&
+ tvp->tv_usec <= lasttime.tv_usec &&
+ (tvp->tv_usec = lasttime.tv_usec + 1) >= 1000000)
+ {
+ tvp->tv_sec++;
+ tvp->tv_usec -= 1000000;
+ }
+ lasttime = *tvp;
+ splx(s);
+}
+
+void
+delay(usecs)
+ u_int usecs;
+{
+ u_int32_t tick, otick, delta;
+ int j, csec, usec;
+
+ csec = usecs / 10000;
+ usec = usecs % 10000;
+
+ usecs = (TIMER_FREQUENCY / 100) * csec
+ + (TIMER_FREQUENCY / 100) * usec / 10000;
+
+ if (! saost_sc) {
+ /* clock isn't initialized yet */
+ for(; usecs > 0; usecs--)
+ for(j = 100; j > 0; j--)
+ ;
+ return;
+ }
+
+ otick = gettick();
+
+ while (1) {
+ for(j = 100; j > 0; j--)
+ ;
+ tick = gettick();
+ delta = tick - otick;
+ if (delta > usecs)
+ break;
+ usecs -= delta;
+ otick = tick;
+ }
+}
+
+void
+resettodr()
+{
+}
+
+void
+inittodr(base)
+ time_t base;
+{
+ time.tv_sec = base;
+ time.tv_usec = 0;
+}
diff --git a/sys/arch/arm/sa11x0/sa11x0_ostreg.h b/sys/arch/arm/sa11x0/sa11x0_ostreg.h
new file mode 100644
index 00000000000..0db7282c265
--- /dev/null
+++ b/sys/arch/arm/sa11x0/sa11x0_ostreg.h
@@ -0,0 +1,80 @@
+/* $NetBSD: sa11x0_ostreg.h,v 1.1 2001/07/08 23:37:53 rjs Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc. All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Ichiro FUKUHARA.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * SA-11x0 OS Timer Register
+ */
+
+/* OS Timer Match Register */
+#define SAOST_MR0 0x00
+#define SAOST_MR1 0x04
+#define SAOST_MR2 0x08
+#define SAOST_MR3 0x0C
+
+/* OS Timer Count Register */
+#define SAOST_CR 0x10
+
+/* OS Timer Status Register */
+#define SAOST_SR 0x14
+#define SR_CH0 (1<<0)
+#define SR_CH1 (1<<1)
+#define SR_CH2 (1<<2)
+#define SR_CH3 (1<<3)
+
+/* OS Timer Watchdog Match Enable Register */
+#define SAOST_WR 0x18
+
+/* OS Timer Interrupt Enable Register */
+#define SAOST_IR 0x1C
+
+/*
+ * SA-1110 Real Time Clock
+ */
+
+/* RTC Alarm Register */
+#define SARTC_AR 0x00
+
+/* RTC Counter Register */
+#define SARTC_CR 0x04
+
+/* RTC Trim Register */
+#define SARTC_TR 0x08
+
+/* RTC Status Register */
+#define SARTC_SR 0x0C
+
+/* end of sa11x0_ostreg.h */
diff --git a/sys/arch/arm/sa11x0/sa11x0_reg.h b/sys/arch/arm/sa11x0/sa11x0_reg.h
new file mode 100644
index 00000000000..3c94c1725ee
--- /dev/null
+++ b/sys/arch/arm/sa11x0/sa11x0_reg.h
@@ -0,0 +1,78 @@
+/* $NetBSD: sa11x0_reg.h,v 1.4 2002/07/19 18:26:56 ichiro Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc. All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by IWAMOTO Toshihiro.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ARM_SA11X0_REG_H_
+#define _ARM_SA11X0_REG_H_
+
+/* Physical register base addresses */
+#define SAOST_BASE 0x90000000 /* OS Timer */
+#define SARTC_BASE 0x90010000 /* Real-Time Clock */
+#define SAPMR_BASE 0x90020000 /* Power Manager */
+#define SARCR_BASE 0x90030000 /* Reset Controller */
+#define SAGPIO_BASE 0x90040000 /* GPIO */
+#define SAIPIC_BASE 0x90050000 /* Interrupt Controller */
+#define SAPPC_BASE 0x90060000 /* Peripheral Pin Controller */
+#define SAUDC_BASE 0x80000000 /* USB Device Controller*/
+#define SACOM1_BASE 0x80010000 /* GPCLK/UART 1 */
+#define SACOM3_HW_BASE 0x80050000 /* UART 3 */
+#define SAMCP_BASE 0x80060000 /* MCP Controller */
+#define SASSP_BASE 0x80070000 /* Synchronous serial port */
+
+#define SADMAC_BASE 0xB0000000 /* DMA Controller */
+#define SALCD_BASE 0xB0100000 /* LCD */
+
+/* Register base virtual addresses mapped by initarm() */
+#define SACOM3_BASE 0xd000d000
+
+/* Interrupt controller registers */
+#define SAIPIC_NPORTS 9
+#define SAIPIC_IP 0x00 /* IRQ pending register */
+#define SAIPIC_MR 0x04 /* Mask register */
+#define SAIPIC_LR 0x08 /* Level register */
+#define SAIPIC_FP 0x10 /* FIQ pending register */
+#define SAIPIC_PR 0x20 /* Pending register */
+#define SAIPIC_CR 0x0C /* Control register */
+
+/* width of interrupt controller */
+#define ICU_LEN 32
+
+/* Reset controller registers */
+#define SARCR_RSRR 0x0 /* Software reset register */
+#define SARCR_RCSR 0x4 /* Reset status register */
+#define SARCR_TUCR 0x8 /* Test Unit control reg */
+
+#endif /* _ARM_SA11X0_REG_H_ */
diff --git a/sys/arch/arm/sa11x0/sa11x0_var.h b/sys/arch/arm/sa11x0/sa11x0_var.h
new file mode 100644
index 00000000000..5c966a0bd92
--- /dev/null
+++ b/sys/arch/arm/sa11x0/sa11x0_var.h
@@ -0,0 +1,76 @@
+/* $NetBSD: sa11x0_var.h,v 1.4 2003/04/14 14:18:41 rjs Exp $ */
+
+/*-
+ * Copyright (c) 2001, The NetBSD Foundation, Inc. All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by IWAMOTO Toshihiro and Ichiro FUKUHARA.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _SA11X0_VAR_H
+#define _SA11X0_VAR_H
+
+#include <sys/conf.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+struct sa11x0_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+ bus_space_handle_t sc_gpioh;
+ bus_space_handle_t sc_ppch;
+ bus_space_handle_t sc_dmach;
+ bus_space_handle_t sc_reseth;
+ u_int32_t sc_intrmask;
+};
+
+/* Attach args all devices */
+
+typedef void *sa11x0_chipset_tag_t;
+
+struct sa11x0_attach_args {
+ sa11x0_chipset_tag_t sa_sc;
+ bus_space_tag_t sa_iot; /* Bus tag */
+ bus_addr_t sa_addr; /* i/o address */
+ bus_size_t sa_size;
+
+ int sa_intr;
+ int sa_gpio;
+};
+
+void *sa11x0_intr_establish(sa11x0_chipset_tag_t, int, int, int,
+ int (*)(void *), void *);
+void sa11x0_intr_disestablish(sa11x0_chipset_tag_t, void *);
+
+#endif /* _SA11X0_VAR_H */
diff --git a/sys/arch/arm/xscale/files.pxa2x0 b/sys/arch/arm/xscale/files.pxa2x0
new file mode 100644
index 00000000000..406c82f944c
--- /dev/null
+++ b/sys/arch/arm/xscale/files.pxa2x0
@@ -0,0 +1,59 @@
+# $NetBSD: files.pxa2x0,v 1.6 2004/05/01 19:09:14 thorpej Exp $
+#
+# Configuration info for Intel PXA2[51]0 CPU support
+#
+
+file arch/arm/arm/softintr.c # Use the generic ARM soft interrupt code.
+
+# PXA2[51]0's integrated peripherals bus.
+define pxaip { [addr=-1], [size=0], [intr=-1], [index=-1]}
+device pxaip
+attach pxaip at mainbus
+file arch/arm/xscale/pxa2x0.c
+file arch/arm/arm/irq_dispatch.S
+file arch/arm/xscale/pxa2x0_space.c
+#file arch/arm/xscale/pxa2x0_freqchg.S
+file arch/arm/xscale/pxa2x0_dma.c
+#file arch/arm/xscale/pxa2x0_i2c.c
+
+# Cotulla integrated peripherals.
+
+# INTC controller
+device pxaintc
+attach pxaintc at pxaip
+file arch/arm/xscale/pxa2x0_intr.c pxaintc needs-flag
+#defflag opt_pxa2x0_gpio.h PXAGPIO_HAS_GPION_INTRS
+
+# GPIO controller
+device pxagpio
+attach pxagpio at pxaip
+file arch/arm/xscale/pxa2x0_gpio.c pxagpio needs-flag
+
+# clock device
+# PXA2x0's built-in timer is compatible to SA-1110.
+device saost
+attach saost at pxaip
+file arch/arm/sa11x0/sa11x0_ost.c saost needs-flag
+
+# NS16550 compatible serial ports
+attach com at pxaip with pxauart
+file arch/arm/xscale/pxa2x0_com.c pxauart
+file arch/arm/xscale/pxa2x0_a4x_space.c pxauart | obio
+file arch/arm/xscale/pxa2x0_a4x_io.S pxauart | obio
+#defflag opt_com.h FFUARTCONSOLE STUARTCONSOLE BTUARTCONSOLE
+
+# LCD controller
+device lcd: wsemuldisplaydev, rasops16, rasops8, rasops4
+file arch/arm/xscale/pxa2x0_lcd.c lcd needs-flag
+
+include "dev/pcmcia/files.pcmcia"
+
+# PCMCIA controller
+device pxapcic: pcmciabus
+attach pxapcic at pxaip
+file arch/arm/xscale/pxa2x0_pcic.c pxapcic
+
+# XXX this is a hack to use dev/pcmcia without fdc.c
+device fdc
+
+file arch/arm/xscale/pxacom.c com & pxauart needs-flag
diff --git a/sys/arch/arm/xscale/pxa2x0.c b/sys/arch/arm/xscale/pxa2x0.c
new file mode 100644
index 00000000000..99d6dc4d569
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0.c
@@ -0,0 +1,393 @@
+/* $NetBSD: pxa2x0.c,v 1.5 2003/12/12 16:42:44 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2002 Genetec Corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Autoconfiguration support for the Intel PXA2[15]0 application
+ * processor. This code is derived from arm/sa11x0/sa11x0.c
+ */
+
+/*-
+ * Copyright (c) 2001, The NetBSD Foundation, Inc. All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by IWAMOTO Toshihiro and Ichiro FUKUHARA.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ */
+/*-
+ * Copyright (c) 1999
+ * Shin Takemura and PocketBSD Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the PocketBSD project
+ * and its contributors.
+ * 4. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+/*
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0.c,v 1.5 2003/12/12 16:42:44 thorpej Exp $");
+*/
+
+#include "pxaintc.h"
+#include "pxagpio.h"
+#if 0
+#include "pxadmac.h" /* Not yet */
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/reboot.h>
+
+#include <machine/cpu.h>
+#include <machine/bus.h>
+
+#include <arm/cpufunc.h>
+#include <arm/mainbus/mainbus.h>
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+
+struct pxaip_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_bust;
+ bus_dma_tag_t sc_dmat;
+ bus_space_handle_t sc_bush_clk;
+};
+
+/* prototypes */
+static int pxaip_match(struct device *, void *, void *);
+static void pxaip_attach(struct device *, struct device *, void *);
+static int pxaip_search(struct device *, void *, void *);
+static void pxaip_attach_critical(struct pxaip_softc *);
+static int pxaip_print(void *, const char *);
+
+int pxaip_measure_cpuclock(struct pxaip_softc *);
+
+/* attach structures */
+#ifdef __NetBSD__
+CFATTACH_DECL(pxaip, sizeof(struct pxaip_softc),
+ pxaip_match, pxaip_attach, NULL, NULL);
+#else
+struct cfattach pxaip_ca = {
+ sizeof(struct pxaip_softc), pxaip_match, pxaip_attach
+};
+
+struct cfdriver pxaip_cd = {
+ NULL, "pxaip", DV_DULL
+};
+#endif
+
+static struct pxaip_softc *pxaip_sc;
+
+static int
+pxaip_match(struct device *parent, void *match, void *aux)
+{
+
+ return 1;
+}
+
+static void
+pxaip_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct pxaip_softc *sc = (struct pxaip_softc *)self;
+ int cpuclock;
+
+ pxaip_sc = sc;
+ sc->sc_bust = &pxa2x0_bs_tag;
+ sc->sc_dmat = &pxa2x0_bus_dma_tag;
+
+ printf(": PXA2x0 Onchip Peripheral Bus ");
+
+ if (bus_space_map(sc->sc_bust, PXA2X0_CLKMAN_BASE, PXA2X0_CLKMAN_SIZE,
+ 0, &sc->sc_bush_clk))
+ panic("pxaip_attach: failed to map CLKMAN");
+
+ /*
+ * Calculate clock speed
+ * This takes 2 secs at most.
+ */
+#if 0
+ cpuclock = pxaip_measure_cpuclock(sc) / 1000;
+#else
+ cpuclock = 398108;
+
+#endif
+ printf(" CPU clock = %d.%03d MHz\n", cpuclock/1000, cpuclock%1000 );
+
+ /*
+ * Attach critical devices
+ */
+ pxaip_attach_critical(sc);
+
+ /*
+ * Attach all other devices
+ */
+ config_search(pxaip_search, self, sc);
+
+}
+
+static int
+pxaip_search(struct device *parent, void *c, void *aux)
+{
+ struct pxaip_softc *sc = aux;
+ struct pxaip_attach_args aa;
+ struct cfdata *cf = c;
+
+ aa.pxa_iot = sc->sc_bust;
+ aa.pxa_dmat = sc->sc_dmat;
+#if 0
+ aa.pxa_addr = cf->cf_addr;
+ aa.pxa_size = cf->cf_size;
+ aa.pxa_intr = cf->cf_intr;
+ aa.pxa_index = cf->cf_index;
+#else
+ aa.pxa_addr = (cf->cf_loc)[0];
+ aa.pxa_size = (cf->cf_loc)[1];
+ aa.pxa_intr = (cf->cf_loc)[2];
+ aa.pxa_index = (cf->cf_loc)[3];
+#endif
+
+ config_found(parent, &aa, pxaip_print);
+
+ return 0;
+}
+
+static void
+pxaip_attach_critical(struct pxaip_softc *sc)
+{
+ struct pxaip_attach_args aa;
+
+ aa.pxa_iot = sc->sc_bust;
+ aa.pxa_dmat = sc->sc_dmat;
+ aa.pxa_addr = PXA2X0_INTCTL_BASE;
+ aa.pxa_size = PXA2X0_INTCTL_SIZE;
+ aa.pxa_intr = -1;
+ if (config_found(&sc->sc_dev, &aa, pxaip_print) == NULL)
+ panic("pxaip_attach_critical: failed to attach INTC!");
+
+#if NPXAGPIO > 0
+ aa.pxa_iot = sc->sc_bust;
+ aa.pxa_dmat = sc->sc_dmat;
+ aa.pxa_addr = PXA2X0_GPIO_BASE;
+ aa.pxa_size = PXA2X0_GPIO_SIZE;
+ aa.pxa_intr = -1;
+ if (config_found(&sc->sc_dev, &aa, pxaip_print) == NULL)
+ panic("pxaip_attach_critical: failed to attach GPIO!");
+#endif
+
+#if NPXADMAC > 0
+ aa.pxa_iot = sc->sc_bust;
+ aa.pxa_dmat = sc->sc_dmat;
+ aa.pxa_addr = PXA2X0_DMAC_BASE;
+ aa.pxa_size = PXA2X0_DMAC_SIZE;
+ aa.pxa_intr = PXA2X0_INT_DMA;
+ if (config_found(&sc->sc_dev, &aa, pxaip_print) == NULL)
+ panic("pxaip_attach_critical: failed to attach DMAC!");
+#endif
+}
+
+static int
+pxaip_print(void *aux, const char *name)
+{
+ struct pxaip_attach_args *sa = (struct pxaip_attach_args*)aux;
+
+ if (sa->pxa_addr != -1) {
+ printf(" addr 0x%lx", sa->pxa_addr);
+ if (sa->pxa_size > -1)
+ printf("-0x%lx", sa->pxa_addr + sa->pxa_size-1);
+ }
+ if (sa->pxa_intr != -1)
+ printf(" intr %d", sa->pxa_intr);
+
+ return (UNCONF);
+}
+
+static inline uint32_t
+read_clock_counter(void)
+{
+ uint32_t x;
+ __asm __volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (x) );
+
+ return x;
+}
+
+int
+pxaip_measure_cpuclock(struct pxaip_softc *sc)
+{
+ uint32_t rtc0, rtc1, start, end;
+ uint32_t pmcr_save;
+ bus_space_handle_t ioh;
+ int irq;
+
+ if (bus_space_map(sc->sc_bust, PXA2X0_RTC_BASE, PXA2X0_RTC_SIZE, 0,
+ &ioh))
+ panic("pxaip_measure_cpuclock: can't map RTC");
+
+ irq = disable_interrupts(I32_bit|F32_bit);
+
+ __asm __volatile( "mrc p14, 0, %0, c0, c0, 0" : "=r" (pmcr_save) );
+ /* Enable clock counter */
+ __asm __volatile( "mcr p14, 0, %0, c0, c0, 0" : : "r" (0x0001) );
+
+ rtc0 = bus_space_read_4(sc->sc_bust, ioh, RTC_RCNR);
+ /* Wait for next second starts */
+ while ((rtc1 = bus_space_read_4(sc->sc_bust, ioh, RTC_RCNR)) == rtc0)
+ ;
+ start = read_clock_counter();
+ while(rtc1 == bus_space_read_4(sc->sc_bust, ioh, RTC_RCNR))
+ ; /* Wait for 1sec */
+ end = read_clock_counter();
+
+ __asm __volatile( "mcr p14, 0, %0, c0, c0, 0" : : "r" (pmcr_save) );
+ restore_interrupts(irq);
+
+ bus_space_unmap(sc->sc_bust, ioh, PXA2X0_RTC_SIZE);
+
+ return end - start;
+}
+
+void
+pxa2x0_turbo_mode( int f )
+{
+ __asm __volatile("mcr p14, 0, %0, c6, c0, 0" : : "r" (f));
+}
+
+void
+pxa2x0_probe_sdram(vaddr_t memctl_va, paddr_t *start, paddr_t *size)
+{
+ u_int32_t mdcnfg, dwid, dcac, drac, dnb;
+ int i;
+
+ mdcnfg = *((volatile u_int32_t *)(memctl_va + MEMCTL_MDCNFG));
+
+ /*
+ * Scan all 4 SDRAM banks
+ */
+ for (i = 0; i < PXA2X0_SDRAM_BANKS; i++) {
+ start[i] = 0;
+ size[i] = 0;
+
+ switch (i) {
+ case 0:
+ case 1:
+ if ((i == 0 && (mdcnfg & MDCNFG_DE0) == 0) ||
+ (i == 1 && (mdcnfg & MDCNFG_DE1) == 0))
+ continue;
+ dwid = mdcnfg >> MDCNFD_DWID01_SHIFT;
+ dcac = mdcnfg >> MDCNFD_DCAC01_SHIFT;
+ drac = mdcnfg >> MDCNFD_DRAC01_SHIFT;
+ dnb = mdcnfg >> MDCNFD_DNB01_SHIFT;
+ break;
+
+ case 2:
+ case 3:
+ if ((i == 2 && (mdcnfg & MDCNFG_DE2) == 0) ||
+ (i == 3 && (mdcnfg & MDCNFG_DE3) == 0))
+ continue;
+ dwid = mdcnfg >> MDCNFD_DWID23_SHIFT;
+ dcac = mdcnfg >> MDCNFD_DCAC23_SHIFT;
+ drac = mdcnfg >> MDCNFD_DRAC23_SHIFT;
+ dnb = mdcnfg >> MDCNFD_DNB23_SHIFT;
+ break;
+ default:
+ panic("pxa2x0_probe_sdram: impossible");
+ }
+
+ dwid = 2 << (1 - (dwid & MDCNFD_DWID_MASK)); /* 16/32 width */
+ dcac = 1 << ((dcac & MDCNFD_DCAC_MASK) + 8); /* 8-11 columns */
+ drac = 1 << ((drac & MDCNFD_DRAC_MASK) + 11); /* 11-13 rows */
+ dnb = 2 << (dnb & MDCNFD_DNB_MASK); /* # of banks */
+
+ size[i] = (paddr_t)(dwid * dcac * drac * dnb);
+ start[i] = PXA2X0_SDRAM0_START + (i * PXA2X0_SDRAM_BANK_SIZE);
+ }
+}
+
+void
+pxa2x0_clkman_config(u_int clk, int enable)
+{
+ struct pxaip_softc *sc;
+ u_int32_t rv;
+
+ KDASSERT(pxaip_sc != NULL);
+ sc = pxaip_sc;
+
+ rv = bus_space_read_4(sc->sc_bust, sc->sc_bush_clk, CLKMAN_CKEN);
+ rv &= ~clk;
+
+ if (enable)
+ rv |= clk;
+
+ bus_space_write_4(sc->sc_bust, sc->sc_bush_clk, CLKMAN_CKEN, rv);
+}
diff --git a/sys/arch/arm/xscale/pxa2x0_a4x_io.S b/sys/arch/arm/xscale/pxa2x0_a4x_io.S
new file mode 100644
index 00000000000..475aae4610f
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_a4x_io.S
@@ -0,0 +1,103 @@
+/* $NetBSD: pxa2x0_a4x_io.S,v 1.1 2002/10/19 19:31:39 bsh Exp $ */
+
+/*
+ * Copyright (c) 2002 Genetec Corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * There are simple bus space functions for IO registers mapped at
+ * 32-bit aligned positions. offset is multiplied by 4.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * bus_space I/O functions with offset*4
+ */
+
+/*
+ * read single
+ */
+
+ENTRY(a4x_bs_r_1)
+ ldrb r0, [r1, r2, LSL #2]
+ mov pc, lr
+
+ENTRY(a4x_bs_r_2)
+ mov r2, r2, LSL #2
+ ldrh r0, [r1, r2]
+ mov pc, lr
+
+ENTRY(a4x_bs_r_4)
+ ldr r0, [r1, r2, LSL #2]
+ mov pc, lr
+
+/*
+ * write single
+ */
+
+ENTRY(a4x_bs_w_1)
+ strb r3, [r1, r2, LSL #2]
+ mov pc, lr
+
+ENTRY(a4x_bs_w_2)
+ mov r2, r2, LSL #2
+ strh r3, [r1, r2]
+ mov pc, lr
+
+ENTRY(a4x_bs_w_4)
+ str r3, [r1, r2, LSL #2]
+ mov pc, lr
+
+/*
+ * read multiple
+ */
+ENTRY(a4x_bs_rm_1)
+ mov r2, r2, LSL #2
+ b generic_bs_rm_1
+
+ENTRY(a4x_bs_rm_2)
+ mov r2, r2, LSL #2
+ b generic_armv4_bs_rm_2
+
+
+
+/*
+ * write multiple
+ */
+ENTRY(a4x_bs_wm_1)
+ mov r2, r2, LSL #2
+ b generic_bs_wm_1
+
+ENTRY(a4x_bs_wm_2)
+ mov r2, r2, LSL #2
+ b generic_armv4_bs_wm_2
diff --git a/sys/arch/arm/xscale/pxa2x0_a4x_space.c b/sys/arch/arm/xscale/pxa2x0_a4x_space.c
new file mode 100644
index 00000000000..e2f0ac82e04
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_a4x_space.c
@@ -0,0 +1,138 @@
+/* $NetBSD: pxa2x0_a4x_space.c,v 1.2 2003/07/15 00:24:54 lukem Exp $ */
+
+/*
+ * Copyright (c) 2002 Genetec Corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Bus space tag for 8/16-bit devices on 32-bit bus.
+ * all registers are located at the address of multiple of 4.
+ */
+
+#include <sys/cdefs.h>
+/*
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_a4x_space.c,v 1.2 2003/07/15 00:24:54 lukem Exp $");
+*/
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/bus.h>
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(pxa2x0);
+bs_protos(a4x);
+bs_protos(generic);
+bs_protos(generic_armv4);
+bs_protos(bs_notimpl);
+
+struct bus_space pxa2x0_a4x_bs_tag = {
+ /* cookie */
+ (void *) 0,
+
+ /* mapping/unmapping */
+ pxa2x0_bs_map,
+ pxa2x0_bs_unmap,
+ pxa2x0_bs_subregion,
+
+ /* allocation/deallocation */
+ pxa2x0_bs_alloc, /* not implemented */
+ pxa2x0_bs_free, /* not implemented */
+
+ /* get kernel virtual address */
+ pxa2x0_bs_vaddr,
+
+ /* mmap */
+ bs_notimpl_bs_mmap,
+
+ /* barrier */
+ pxa2x0_bs_barrier,
+
+ /* read (single) */
+ a4x_bs_r_1,
+ a4x_bs_r_2,
+ a4x_bs_r_4,
+ bs_notimpl_bs_r_8,
+
+ /* read multiple */
+ a4x_bs_rm_1,
+ a4x_bs_rm_2,
+ bs_notimpl_bs_rm_4,
+ bs_notimpl_bs_rm_8,
+
+ /* read region */
+ bs_notimpl_bs_rr_1,
+ bs_notimpl_bs_rr_2,
+ bs_notimpl_bs_rr_4,
+ bs_notimpl_bs_rr_8,
+
+ /* write (single) */
+ a4x_bs_w_1,
+ a4x_bs_w_2,
+ a4x_bs_w_4,
+ bs_notimpl_bs_w_8,
+
+ /* write multiple */
+ a4x_bs_wm_1,
+ a4x_bs_wm_2,
+ bs_notimpl_bs_wm_4,
+ bs_notimpl_bs_wm_8,
+
+ /* write region */
+ bs_notimpl_bs_wr_1,
+ bs_notimpl_bs_wr_2,
+ bs_notimpl_bs_wr_4,
+ bs_notimpl_bs_wr_8,
+
+ /* set multiple */
+ bs_notimpl_bs_sm_1,
+ bs_notimpl_bs_sm_2,
+ bs_notimpl_bs_sm_4,
+ bs_notimpl_bs_sm_8,
+
+ /* set region */
+ bs_notimpl_bs_sr_1,
+ bs_notimpl_bs_sr_2,
+ bs_notimpl_bs_sr_4,
+ bs_notimpl_bs_sr_8,
+
+ /* copy */
+ bs_notimpl_bs_c_1,
+ bs_notimpl_bs_c_2,
+ bs_notimpl_bs_c_4,
+ bs_notimpl_bs_c_8,
+};
+
+
+
diff --git a/sys/arch/arm/xscale/pxa2x0_com.c b/sys/arch/arm/xscale/pxa2x0_com.c
new file mode 100644
index 00000000000..6ad04cdd01f
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_com.c
@@ -0,0 +1,149 @@
+/* $NetBSD: pxa2x0_com.c,v 1.4 2003/07/15 00:24:55 lukem Exp $ */
+
+/*
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+/*
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_com.c,v 1.4 2003/07/15 00:24:55 lukem Exp $");
+*/
+
+#ifndef COM_PXA2X0
+#error "You must use options COM_PXA2X0 to get PXA2x0 serial port support"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/termios.h>
+
+#include <machine/intr.h>
+#include <machine/bus.h>
+
+#include <arm/xscale/pxacomreg.h>
+#include <arm/xscale/pxacomvar.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+
+static int pxauart_match(struct device *, void *, void *);
+static void pxauart_attach(struct device *, struct device *, void *);
+
+#ifdef __NetBSD__
+CFATTACH_DECL(pxauart, sizeof(struct com_softc),
+ pxauart_match, pxauart_attach, NULL, NULL);
+#else
+struct cfattach pxauart_ca = {
+ sizeof (struct com_softc), pxauart_match, pxauart_attach
+};
+
+struct cfdriver pxauart_cd = {
+ NULL, "pxauart", DV_DULL
+};
+#endif
+
+static int
+pxauart_match(struct device *parent, void *cf, void *aux)
+{
+ struct pxaip_attach_args *pxa = aux;
+ bus_space_tag_t bt = &pxa2x0_a4x_bs_tag; /* XXX: This sucks */
+ bus_space_handle_t bh;
+ int rv;
+
+ switch (pxa->pxa_addr) {
+ case PXA2X0_FFUART_BASE:
+ if (pxa->pxa_intr != PXA2X0_INT_FFUART)
+ return (0);
+ break;
+
+ case PXA2X0_STUART_BASE:
+ if (pxa->pxa_intr != PXA2X0_INT_STUART)
+ return (0);
+ break;
+
+ case PXA2X0_BTUART_BASE: /* XXX: Config file option ... */
+ if (pxa->pxa_intr != PXA2X0_INT_BTUART)
+ return (0);
+ break;
+
+ default:
+ return (0);
+ }
+
+ pxa->pxa_size = 0x20;
+
+ {
+ extern bus_addr_t comconsaddr;
+
+ if (comconsaddr == pxa->pxa_addr)
+ return (1);
+ }
+
+ if (bus_space_map(bt, pxa->pxa_addr, pxa->pxa_size, 0, &bh))
+ return (0);
+
+ /* Make sure the UART is enabled */
+ bus_space_write_1(bt, bh, com_ier, IER_EUART);
+
+ rv = comprobe1(bt, bh);
+ bus_space_unmap(bt, bh, pxa->pxa_size);
+
+ return (rv);
+}
+
+static void
+pxauart_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct com_softc *sc = (struct com_softc *)self;
+ struct pxaip_attach_args *pxa = aux;
+
+ sc->sc_iot = &pxa2x0_a4x_bs_tag; /* XXX: This sucks */
+ sc->sc_iobase = pxa->pxa_addr;
+ sc->sc_frequency = PXA2X0_COM_FREQ;
+
+#if 0
+ if (com_is_console(sc->sc_iot, sc->sc_iobase, &sc->sc_ioh) == 0 &&
+ bus_space_map(sc->sc_iot, sc->sc_iobase, pxa->pxa_size, 0,
+ &sc->sc_ioh)) {
+ printf(": can't map registers\n");
+ return;
+ }
+#endif
+ bus_space_map(sc->sc_iot, sc->sc_iobase, pxa->pxa_size, 0, &sc->sc_ioh);
+
+ com_attach_subr(sc);
+
+ pxa2x0_intr_establish(pxa->pxa_intr, IPL_SERIAL, comintr, sc);
+}
diff --git a/sys/arch/arm/xscale/pxa2x0_dma.c b/sys/arch/arm/xscale/pxa2x0_dma.c
new file mode 100644
index 00000000000..14c655e2486
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_dma.c
@@ -0,0 +1,75 @@
+/* $NetBSD: pxa2x0_dma.c,v 1.3 2003/08/07 16:58:35 bsh Exp $ */
+
+/*
+ * Copyright (c) 2002 Genetec Corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * bus dma tag for PXA2[15]0 processor.
+ * (Currently used only for LCD frame buffer)
+ */
+
+#include <sys/cdefs.h>
+/*
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_dma.c,v 1.3 2003/08/07 16:58:35 bsh Exp $");
+*/
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+
+#include <uvm/uvm_extern.h>
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+struct arm32_bus_dma_tag pxa2x0_bus_dma_tag = {
+ 0,
+ 0,
+ NULL,
+ _bus_dmamap_create,
+ _bus_dmamap_destroy,
+ _bus_dmamap_load,
+ _bus_dmamap_load_mbuf,
+ _bus_dmamap_load_uio,
+ _bus_dmamap_load_raw,
+ _bus_dmamap_unload,
+ _bus_dmamap_sync,
+ _bus_dmamem_alloc,
+ _bus_dmamem_free,
+ _bus_dmamem_map,
+ _bus_dmamem_unmap,
+ _bus_dmamem_mmap,
+};
+
diff --git a/sys/arch/arm/xscale/pxa2x0_gpio.c b/sys/arch/arm/xscale/pxa2x0_gpio.c
new file mode 100644
index 00000000000..f7b97502ff8
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_gpio.c
@@ -0,0 +1,518 @@
+/* $NetBSD: pxa2x0_gpio.c,v 1.2 2003/07/15 00:24:55 lukem Exp $ */
+
+/*
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+/*
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_gpio.c,v 1.2 2003/07/15 00:24:55 lukem Exp $");
+*/
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/intr.h>
+#include <machine/bus.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/pxa2x0_gpio.h>
+
+struct gpio_irq_handler {
+ struct gpio_irq_handler *gh_next;
+ int (*gh_func)(void *);
+ void *gh_arg;
+ int gh_spl;
+ u_int gh_gpio;
+};
+
+struct pxagpio_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_bust;
+ bus_space_handle_t sc_bush;
+ void *sc_irqcookie[3];
+ u_int32_t sc_mask[3];
+#ifdef PXAGPIO_HAS_GPION_INTRS
+ struct gpio_irq_handler *sc_handlers[GPIO_NPINS];
+#else
+ struct gpio_irq_handler *sc_handlers[2];
+#endif
+};
+
+static int pxagpio_match(struct device *, void *, void *);
+static void pxagpio_attach(struct device *, struct device *, void *);
+
+#ifdef __NetBSD__
+CFATTACH_DECL(pxagpio, sizeof(struct pxagpio_softc),
+ pxagpio_match, pxagpio_attach, NULL, NULL);
+#else
+struct cfattach pxagpio_ca = {
+ sizeof (struct pxagpio_softc), pxagpio_match, pxagpio_attach
+};
+
+struct cfdriver pxagpio_cd = {
+ NULL, "pxagpio", DV_DULL
+};
+
+#endif
+
+static struct pxagpio_softc *pxagpio_softc;
+static vaddr_t pxagpio_regs;
+#define GPIO_BOOTSTRAP_REG(reg) \
+ (*((volatile u_int32_t *)(pxagpio_regs + (reg))))
+
+static int gpio_intr0(void *);
+static int gpio_intr1(void *);
+#ifdef PXAGPIO_HAS_GPION_INTRS
+static int gpio_dispatch(struct pxagpio_softc *, int);
+static int gpio_intrN(void *);
+#endif
+
+static __inline u_int32_t
+pxagpio_reg_read(struct pxagpio_softc *sc, int reg)
+{
+ if (__predict_true(sc != NULL))
+ return (bus_space_read_4(sc->sc_bust, sc->sc_bush, reg));
+ else
+ if (pxagpio_regs)
+ return (GPIO_BOOTSTRAP_REG(reg));
+ panic("pxagpio_reg_read: not bootstrapped");
+}
+
+static __inline void
+pxagpio_reg_write(struct pxagpio_softc *sc, int reg, u_int32_t val)
+{
+ if (__predict_true(sc != NULL))
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, val);
+ else
+ if (pxagpio_regs)
+ GPIO_BOOTSTRAP_REG(reg) = val;
+ else
+ panic("pxagpio_reg_write: not bootstrapped");
+ return;
+}
+
+static int
+pxagpio_match(struct device *parent, void *cf, void *aux)
+{
+ struct pxaip_attach_args *pxa = aux;
+
+ if (pxagpio_softc != NULL || pxa->pxa_addr != PXA2X0_GPIO_BASE)
+ return (0);
+
+ pxa->pxa_size = PXA2X0_GPIO_SIZE;
+
+ return (1);
+}
+
+void
+pxagpio_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct pxagpio_softc *sc = (struct pxagpio_softc *)self;
+ struct pxaip_attach_args *pxa = aux;
+
+ sc->sc_bust = pxa->pxa_iot;
+
+ printf(": GPIO Controller\n");
+
+ if (bus_space_map(sc->sc_bust, pxa->pxa_addr, pxa->pxa_size, 0,
+ &sc->sc_bush)) {
+ printf("%s: Can't map registers!\n", sc->sc_dev.dv_xname);
+ return;
+ }
+
+ memset(sc->sc_handlers, 0, sizeof(sc->sc_handlers));
+
+ /*
+ * Disable all GPIO interrupts
+ */
+ pxagpio_reg_write(sc, GPIO_GRER0, 0);
+ pxagpio_reg_write(sc, GPIO_GRER1, 0);
+ pxagpio_reg_write(sc, GPIO_GRER2, 0);
+ pxagpio_reg_write(sc, GPIO_GFER0, 0);
+ pxagpio_reg_write(sc, GPIO_GFER1, 0);
+ pxagpio_reg_write(sc, GPIO_GFER2, 0);
+ pxagpio_reg_write(sc, GPIO_GEDR0, ~0);
+ pxagpio_reg_write(sc, GPIO_GEDR1, ~0);
+ pxagpio_reg_write(sc, GPIO_GEDR2, ~0);
+
+#ifdef PXAGPIO_HAS_GPION_INTRS
+ sc->sc_irqcookie[2] = pxa2x0_intr_establish(PXA2X0_INT_GPION, IPL_BIO,
+ gpio_intrN, sc);
+ if (sc->sc_irqcookie[2] == NULL) {
+ printf("%s: failed to hook main GPIO interrupt\n",
+ sc->sc_dev.dv_xname);
+ return;
+ }
+
+#endif
+
+ sc->sc_irqcookie[0] = sc->sc_irqcookie[1] = NULL;
+
+ pxagpio_softc = sc;
+}
+
+void
+pxa2x0_gpio_bootstrap(vaddr_t gpio_regs)
+{
+
+ pxagpio_regs = gpio_regs;
+}
+
+void *
+pxa2x0_gpio_intr_establish(u_int gpio, int level, int spl, int (*func)(void *),
+ void *arg, char *name)
+{
+ struct pxagpio_softc *sc = pxagpio_softc;
+ struct gpio_irq_handler *gh;
+ u_int32_t bit, reg;
+
+#ifdef DEBUG
+#ifdef PXAGPIO_HAS_GPION_INTRS
+ if (gpio >= GPIO_NPINS)
+ panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio);
+#else
+ if (gpio > 1)
+ panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio);
+#endif
+#endif
+
+ if (!GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(gpio)))
+ panic("pxa2x0_gpio_intr_establish: Pin %d not GPIO_IN", gpio);
+
+ switch (level) {
+ case IST_EDGE_FALLING:
+ case IST_EDGE_RISING:
+ case IST_EDGE_BOTH:
+ break;
+
+ default:
+ panic("pxa2x0_gpio_intr_establish: bad level: %d", level);
+ break;
+ }
+
+ MALLOC(gh, struct gpio_irq_handler *, sizeof(struct gpio_irq_handler),
+ M_DEVBUF, M_NOWAIT);
+
+ gh->gh_func = func;
+ gh->gh_arg = arg;
+ gh->gh_spl = spl;
+ gh->gh_gpio = gpio;
+
+ gh->gh_next = sc->sc_handlers[gpio];
+ sc->sc_handlers[gpio] = gh;
+
+ if (gpio == 0) {
+ KDASSERT(sc->sc_irqcookie[0] == NULL);
+ sc->sc_irqcookie[0] = pxa2x0_intr_establish(PXA2X0_INT_GPIO0,
+ spl, gpio_intr0, sc);
+ KDASSERT(sc->sc_irqcookie[0]);
+ } else
+ if (gpio == 1) {
+ KDASSERT(sc->sc_irqcookie[1] == NULL);
+ sc->sc_irqcookie[1] = pxa2x0_intr_establish(PXA2X0_INT_GPIO1,
+ spl, gpio_intr1, sc);
+ KDASSERT(sc->sc_irqcookie[1]);
+ }
+
+ bit = GPIO_BIT(gpio);
+ sc->sc_mask[GPIO_BANK(gpio)] |= bit;
+
+ switch (level) {
+ case IST_EDGE_FALLING:
+ reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio));
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), reg | bit);
+ break;
+
+ case IST_EDGE_RISING:
+ reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio));
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), reg | bit);
+ break;
+
+ case IST_EDGE_BOTH:
+ reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio));
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), reg | bit);
+ reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio));
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), reg | bit);
+ break;
+ }
+
+ return (gh);
+}
+
+void
+pxa2x0_gpio_intr_disestablish(void *cookie)
+{
+ struct pxagpio_softc *sc = pxagpio_softc;
+ struct gpio_irq_handler *gh = cookie;
+ u_int32_t bit, reg;
+
+ bit = GPIO_BIT(gh->gh_gpio);
+
+ reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio));
+ reg &= ~bit;
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio), reg);
+ reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio));
+ reg &= ~bit;
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio), reg);
+
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gh->gh_gpio), bit);
+
+ sc->sc_mask[GPIO_BANK(gh->gh_gpio)] &= ~bit;
+ sc->sc_handlers[gh->gh_gpio] = NULL;
+
+ if (gh->gh_gpio == 0) {
+#if 0
+ pxa2x0_intr_disestablish(sc->sc_irqcookie[0]);
+ sc->sc_irqcookie[0] = NULL;
+#else
+ panic("pxa2x0_gpio_intr_disestablish: can't unhook GPIO#0");
+#endif
+ } else
+ if (gh->gh_gpio == 1) {
+#if 0
+ pxa2x0_intr_disestablish(sc->sc_irqcookie[1]);
+ sc->sc_irqcookie[0] = NULL;
+#else
+ panic("pxa2x0_gpio_intr_disestablish: can't unhook GPIO#0");
+#endif
+ }
+
+ FREE(gh, M_DEVBUF);
+}
+
+static int
+gpio_intr0(void *arg)
+{
+ struct pxagpio_softc *sc = arg;
+
+#ifdef DIAGNOSTIC
+ if (sc->sc_handlers[0] == NULL) {
+ printf("%s: stray GPIO#0 edge interrupt\n",
+ sc->sc_dev.dv_xname);
+ return (0);
+ }
+#endif
+
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 0),
+ GPIO_BIT(0));
+
+ return ((sc->sc_handlers[0]->gh_func)(sc->sc_handlers[0]->gh_arg));
+}
+
+static int
+gpio_intr1(void *arg)
+{
+ struct pxagpio_softc *sc = arg;
+
+#ifdef DIAGNOSTIC
+ if (sc->sc_handlers[1] == NULL) {
+ printf("%s: stray GPIO#1 edge interrupt\n",
+ sc->sc_dev.dv_xname);
+ return (0);
+ }
+#endif
+
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 1),
+ GPIO_BIT(1));
+
+ return ((sc->sc_handlers[1]->gh_func)(sc->sc_handlers[1]->gh_arg));
+}
+
+#ifdef PXAGPIO_HAS_GPION_INTRS
+static int
+gpio_dispatch(struct pxagpio_softc *sc, int gpio_base)
+{
+ struct gpio_irq_handler **ghp, *gh;
+ int i, s, handled, pins;
+ u_int32_t gedr, mask;
+ int bank;
+
+ /* Fetch bitmap of pending interrupts on this GPIO bank */
+ gedr = pxagpio_reg_read(sc, GPIO_REG(GPIO_GEDR0, gpio_base));
+
+ /* Don't handle GPIO 0/1 here */
+ if (gpio_base == 0)
+ gedr &= ~(GPIO_BIT(0) | GPIO_BIT(1));
+
+ /* Bail early if there are no pending interrupts in this bank */
+ if (gedr == 0)
+ return (0);
+
+ /* Acknowledge pending interrupts. */
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio_base), gedr);
+
+ bank = GPIO_BANK(gpio_base);
+
+ /*
+ * We're only interested in those for which we have a handler
+ * registered
+ */
+#ifdef DEBUG
+ if ((gedr & sc->sc_mask[bank]) == 0) {
+ printf("%s: stray GPIO interrupt. Bank %d, GEDR 0x%08x, mask 0x%08x\n",
+ sc->sc_dev.dv_xname, bank, gedr, sc->sc_mask[bank]);
+ return (1); /* XXX: Pretend we dealt with it */
+ }
+#endif
+
+ gedr &= sc->sc_mask[bank];
+ ghp = &sc->sc_handlers[gpio_base];
+ pins = (gpio_base < 64) ? 32 : 17;
+ handled = 0;
+
+ for (i = 0, mask = 1; i < pins && gedr; i++, ghp++, mask <<= 1) {
+ if ((gedr & mask) == 0)
+ continue;
+ gedr &= ~mask;
+
+ if ((gh = *ghp) == NULL) {
+ printf("%s: unhandled GPIO interrupt. GPIO#%d\n",
+ sc->sc_dev.dv_xname, gpio_base + i);
+ continue;
+ }
+
+ s = _splraise(gh->gh_spl);
+ do {
+ handled |= (gh->gh_func)(gh->gh_arg);
+ gh = gh->gh_next;
+ } while (gh != NULL);
+ splx(s);
+ }
+
+ return (handled);
+}
+
+static int
+gpio_intrN(void *arg)
+{
+ struct pxagpio_softc *sc = arg;
+ int handled;
+
+ handled = gpio_dispatch(sc, 0);
+ handled |= gpio_dispatch(sc, 32);
+ handled |= gpio_dispatch(sc, 64);
+
+ return (handled);
+}
+#endif /* PXAGPIO_HAS_GPION_INTRS */
+
+u_int
+pxa2x0_gpio_get_function(u_int gpio)
+{
+ struct pxagpio_softc *sc = pxagpio_softc;
+ u_int32_t rv, io;
+
+ KDASSERT(gpio < GPIO_NPINS);
+
+ rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio);
+ rv = GPIO_FN(rv);
+
+ io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio));
+ if (io & GPIO_BIT(gpio))
+ rv |= GPIO_OUT;
+
+ io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio));
+ if (io & GPIO_BIT(gpio))
+ rv |= GPIO_SET;
+
+ return (rv);
+}
+
+u_int
+pxa2x0_gpio_set_function(u_int gpio, u_int fn)
+{
+ struct pxagpio_softc *sc = pxagpio_softc;
+ u_int32_t rv, bit;
+ u_int oldfn;
+
+ KDASSERT(gpio < GPIO_NPINS);
+
+ oldfn = pxa2x0_gpio_get_function(gpio);
+
+ if (GPIO_FN(fn) == GPIO_FN(oldfn) &&
+ GPIO_FN_IS_OUT(fn) == GPIO_FN_IS_OUT(oldfn)) {
+ /*
+ * The pin's function is not changing.
+ * For Alternate Functions and GPIO input, we can just
+ * return now.
+ * For GPIO output pins, check the initial state is
+ * the same.
+ *
+ * Return 'fn' instead of 'oldfn' so the caller can
+ * reliably detect that we didn't change anything.
+ * (The initial state might be different for non-
+ * GPIO output pins).
+ */
+ if (!GPIO_IS_GPIO_OUT(fn) ||
+ GPIO_FN_IS_SET(fn) == GPIO_FN_IS_SET(oldfn))
+ return (fn);
+ }
+
+ /*
+ * See section 4.1.3.7 of the PXA2x0 Developer's Manual for
+ * the correct procedure for changing GPIO pin functions.
+ */
+
+ bit = GPIO_BIT(gpio);
+
+ /*
+ * 1. Configure the correct set/clear state of the pin
+ */
+ if (GPIO_FN_IS_SET(fn))
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit);
+ else
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit);
+
+ /*
+ * 2. Configure the pin as an input or output as appropriate
+ */
+ rv = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
+ if (GPIO_FN_IS_OUT(fn))
+ rv |= bit;
+ pxagpio_reg_write(sc, GPIO_REG(GPIO_GPDR0, gpio), rv);
+
+ /*
+ * 3. Configure the pin's function
+ */
+ bit = GPIO_FN_MASK << GPIO_FN_SHIFT(gpio);
+ fn = GPIO_FN(fn) << GPIO_FN_SHIFT(gpio);
+ rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) & ~bit;
+ pxagpio_reg_write(sc, GPIO_FN_REG(gpio), rv | fn);
+
+ return (oldfn);
+}
diff --git a/sys/arch/arm/xscale/pxa2x0_gpio.h b/sys/arch/arm/xscale/pxa2x0_gpio.h
new file mode 100644
index 00000000000..50b64023a18
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_gpio.h
@@ -0,0 +1,62 @@
+/* $wasabi$ */
+
+/*
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PXA2X0_GPIO_H
+#define _PXA2X0_GPIO_H
+
+/*
+ * If you want to fiddle with GPIO registers before the
+ * driver has been autoconfigured (e.g. from initarm()),
+ * call this function with the virtual address of the
+ * GPIO controller's registers
+ */
+extern void pxa2x0_gpio_bootstrap(vaddr_t);
+
+/*
+ * GPIO pin function query/manipulation functions
+ */
+extern u_int pxa2x0_gpio_get_function(u_int);
+extern u_int pxa2x0_gpio_set_function(u_int, u_int);
+
+/*
+ * Establish/Disestablish interrupt handlers for GPIO pins
+ */
+extern void *pxa2x0_gpio_intr_establish(u_int, int, int,
+ int (*)(void *), void *, char *);
+extern void pxa2x0_gpio_intr_disestablish(void *);
+
+#endif /* _PXA2X0_GPIO_H */
diff --git a/sys/arch/arm/xscale/pxa2x0_intr.c b/sys/arch/arm/xscale/pxa2x0_intr.c
new file mode 100644
index 00000000000..91ded6e782a
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_intr.c
@@ -0,0 +1,465 @@
+/* $NetBSD: pxa2x0_intr.c,v 1.5 2003/07/15 00:24:55 lukem Exp $ */
+
+/*
+ * Copyright (c) 2002 Genetec Corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * IRQ handler for the Intel PXA2X0 processor.
+ * It has integrated interrupt controller.
+ */
+
+#include <sys/cdefs.h>
+/*
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_intr.c,v 1.5 2003/07/15 00:24:55 lukem Exp $");
+*/
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <uvm/uvm_extern.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/lock.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/pxa2x0_intr.h>
+#include <arm/sa11x0/sa11x0_var.h>
+
+/*
+ * INTC autoconf glue
+ */
+static int pxaintc_match(struct device *, void *, void *);
+static void pxaintc_attach(struct device *, struct device *, void *);
+
+#ifdef __NetBSD__
+CFATTACH_DECL(pxaintc, sizeof(struct device),
+ pxaintc_match, pxaintc_attach, NULL, NULL);
+#else
+struct cfattach pxaintc_ca = {
+ sizeof(struct device), pxaintc_match, pxaintc_attach
+};
+
+struct cfdriver pxaintc_cd = {
+ NULL, "pxaintc", DV_DULL
+};
+
+#endif
+
+static int pxaintc_attached;
+
+static int stray_interrupt(void *);
+static void init_interrupt_masks(void);
+
+/*
+ * interrupt dispatch table.
+ */
+#ifdef MULTIPLE_HANDLERS_ON_ONE_IRQ
+struct intrhand {
+ TAILQ_ENTRY(intrhand) ih_list; /* link on intrq list */
+ int (*ih_func)(void *); /* handler */
+ void *ih_arg; /* arg for handler */
+};
+#endif
+
+static struct {
+#ifdef MULTIPLE_HANDLERS_ON_ONE_IRQ
+ TAILQ_HEAD(,intrhand) list;
+#else
+ pxa2x0_irq_handler_t func;
+#endif
+ void *cookie; /* NULL for stackframe */
+ /* struct evbnt ev; */
+} handler[ICU_LEN];
+
+__volatile int softint_pending;
+__volatile int current_spl_level;
+__volatile int intr_mask;
+/* interrupt masks for each level */
+int pxa2x0_imask[NIPL];
+static int extirq_level[ICU_LEN];
+
+
+static int
+pxaintc_match(struct device *parent, void *cf, void *aux)
+{
+ struct pxaip_attach_args *pxa = aux;
+
+ if (pxaintc_attached || pxa->pxa_addr != PXA2X0_INTCTL_BASE)
+ return (0);
+
+ return (1);
+}
+
+void
+pxaintc_attach(struct device *parent, struct device *self, void *args)
+{
+ int i;
+
+ pxaintc_attached = 1;
+
+ printf(": Interrupt Controller\n");
+
+#define SAIPIC_ICCR 0x14
+
+ write_icu(SAIPIC_ICCR, 1);
+ write_icu(SAIPIC_MR, 0);
+
+ for(i = 0; i < sizeof handler / sizeof handler[0]; ++i){
+ handler[i].func = stray_interrupt;
+ handler[i].cookie = (void *)(u_int32_t) i;
+ extirq_level[i] = IPL_SERIAL;
+ }
+
+ init_interrupt_masks();
+
+ _splraise(IPL_SERIAL);
+ enable_interrupts(I32_bit);
+}
+
+/*
+ * Invoked very early on from the board-specific initarm(), in order to
+ * inform us the virtual address of the interrupt controller's registers.
+ */
+vaddr_t pxaic_base;
+void
+pxa2x0_intr_bootstrap(vaddr_t addr)
+{
+
+ pxaic_base = addr;
+}
+
+static __inline void
+__raise(int ipl)
+{
+
+ if (current_spl_level < ipl)
+ pxa2x0_setipl(ipl);
+}
+
+
+/*
+ * Map a software interrupt queue to an interrupt priority level.
+ */
+static const int si_to_ipl[SI_NQUEUES] = {
+ IPL_SOFT, /* SI_SOFT */
+ IPL_SOFTCLOCK, /* SI_SOFTCLOCK */
+ IPL_SOFTNET, /* SI_SOFTNET */
+ IPL_SOFTSERIAL, /* SI_SOFTSERIAL */
+};
+
+/*
+ * called from irq_entry.
+ */
+void
+pxa2x0_irq_handler(void *arg)
+{
+ struct clockframe *frame = arg;
+ uint32_t irqbits;
+ int irqno;
+ int saved_spl_level;
+
+ saved_spl_level = current_spl_level;
+
+ /* get pending IRQs */
+ irqbits = read_icu(SAIPIC_IP);
+
+ while ((irqno = find_first_bit(irqbits)) >= 0) {
+ /* XXX: Shuould we handle IRQs in priority order? */
+
+ /* raise spl to stop interrupts of lower priorities */
+ if (saved_spl_level < extirq_level[irqno])
+ pxa2x0_setipl(extirq_level[irqno]);
+
+#ifdef notyet
+ /* Enable interrupt */
+#endif
+#ifndef MULTIPLE_HANDLERS_ON_ONE_IRQ
+ (* handler[irqno].func)(
+ handler[irqno].cookie == 0
+ ? frame : handler[irqno].cookie );
+#else
+ /* process all handlers for this interrupt.
+ XXX not yet */
+#endif
+
+#ifdef notyet
+ /* Disable interrupt */
+#endif
+
+ irqbits &= ~(1<<irqno);
+ }
+
+ /* restore spl to that was when this interrupt happen */
+ pxa2x0_setipl(saved_spl_level);
+
+ if(softint_pending & intr_mask)
+ pxa2x0_do_pending();
+}
+
+static int
+stray_interrupt(void *cookie)
+{
+ int irqno = (int)cookie;
+ printf("stray interrupt %d\n", irqno);
+
+ if (PXA2X0_IRQ_MIN <= irqno && irqno < ICU_LEN){
+ int save = disable_interrupts(I32_bit);
+ write_icu(SAIPIC_MR,
+ read_icu(SAIPIC_MR) & ~(1U<<irqno));
+ restore_interrupts(save);
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * Interrupt Mask Handling
+ */
+
+void
+pxa2x0_update_intr_masks(int irqno, int level)
+{
+ int mask = 1U<<irqno;
+ int psw = disable_interrupts(I32_bit);
+ int i;
+
+ for(i = 0; i < level; ++i)
+ pxa2x0_imask[i] |= mask; /* Enable interrupt at lower level */
+
+ for( ; i < NIPL-1; ++i)
+ pxa2x0_imask[i] &= ~mask; /* Disable itnerrupt at upper level */
+
+ /*
+ * Enforce a heirarchy that gives "slow" device (or devices with
+ * limited input buffer space/"real-time" requirements) a better
+ * chance at not dropping data.
+ */
+ pxa2x0_imask[IPL_BIO] &= pxa2x0_imask[IPL_SOFTNET];
+ pxa2x0_imask[IPL_NET] &= pxa2x0_imask[IPL_BIO];
+ pxa2x0_imask[IPL_SOFTSERIAL] &= pxa2x0_imask[IPL_NET];
+ pxa2x0_imask[IPL_TTY] &= pxa2x0_imask[IPL_SOFTSERIAL];
+
+ /*
+ * splvm() blocks all interrupts that use the kernel memory
+ * allocation facilities.
+ */
+ pxa2x0_imask[IPL_VM] &= pxa2x0_imask[IPL_TTY];
+
+ /*
+ * Audio devices are not allowed to perform memory allocation
+ * in their interrupt routines, and they have fairly "real-time"
+ * requirements, so give them a high interrupt priority.
+ */
+ pxa2x0_imask[IPL_AUDIO] &= pxa2x0_imask[IPL_VM];
+
+ /*
+ * splclock() must block anything that uses the scheduler.
+ */
+ pxa2x0_imask[IPL_CLOCK] &= pxa2x0_imask[IPL_AUDIO];
+
+ /*
+ * splhigh() must block "everything".
+ */
+ pxa2x0_imask[IPL_HIGH] &= pxa2x0_imask[IPL_STATCLOCK];
+
+ /*
+ * XXX We need serial drivers to run at the absolute highest priority
+ * in order to avoid overruns, so serial > high.
+ */
+ pxa2x0_imask[IPL_SERIAL] &= pxa2x0_imask[IPL_HIGH];
+
+ write_icu(SAIPIC_MR, pxa2x0_imask[current_spl_level]);
+
+ restore_interrupts(psw);
+}
+
+
+static void
+init_interrupt_masks(void)
+{
+
+ memset(pxa2x0_imask, 0, sizeof(pxa2x0_imask));
+
+ /*
+ * IPL_NONE has soft interrupts enabled only, at least until
+ * hardware handlers are installed.
+ */
+ pxa2x0_imask[IPL_NONE] =
+ SI_TO_IRQBIT(SI_SOFT) |
+ SI_TO_IRQBIT(SI_SOFTCLOCK) |
+ SI_TO_IRQBIT(SI_SOFTNET) |
+ SI_TO_IRQBIT(SI_SOFTSERIAL);
+
+ /*
+ * Initialize the soft interrupt masks to block themselves.
+ */
+ pxa2x0_imask[IPL_SOFT] = ~SI_TO_IRQBIT(SI_SOFT);
+ pxa2x0_imask[IPL_SOFTCLOCK] = ~SI_TO_IRQBIT(SI_SOFTCLOCK);
+ pxa2x0_imask[IPL_SOFTNET] = ~SI_TO_IRQBIT(SI_SOFTNET);
+ pxa2x0_imask[IPL_SOFTSERIAL] = ~SI_TO_IRQBIT(SI_SOFTSERIAL);
+
+ pxa2x0_imask[IPL_SOFT] &= pxa2x0_imask[IPL_NONE];
+
+ /*
+ * splsoftclock() is the only interface that users of the
+ * generic software interrupt facility have to block their
+ * soft intrs, so splsoftclock() must also block IPL_SOFT.
+ */
+ pxa2x0_imask[IPL_SOFTCLOCK] &= pxa2x0_imask[IPL_SOFT];
+
+ /*
+ * splsoftnet() must also block splsoftclock(), since we don't
+ * want timer-driven network events to occur while we're
+ * processing incoming packets.
+ */
+ pxa2x0_imask[IPL_SOFTNET] &= pxa2x0_imask[IPL_SOFTCLOCK];
+}
+
+void
+pxa2x0_do_pending(void)
+{
+ static __cpu_simple_lock_t processing = __SIMPLELOCK_UNLOCKED;
+ int oldirqstate, spl_save;
+
+ if (__cpu_simple_lock_try(&processing) == 0)
+ return;
+
+ spl_save = current_spl_level;
+
+ oldirqstate = disable_interrupts(I32_bit);
+
+#if 1
+#define DO_SOFTINT(si,ipl) \
+ if ((softint_pending & intr_mask) & SI_TO_IRQBIT(si)) { \
+ softint_pending &= ~SI_TO_IRQBIT(si); \
+ __raise(ipl); \
+ restore_interrupts(oldirqstate); \
+ softintr_dispatch(si); \
+ oldirqstate = disable_interrupts(I32_bit); \
+ pxa2x0_setipl(spl_save); \
+ }
+
+ do {
+ DO_SOFTINT(SI_SOFTSERIAL,IPL_SOFTSERIAL);
+ DO_SOFTINT(SI_SOFTNET, IPL_SOFTNET);
+ DO_SOFTINT(SI_SOFTCLOCK, IPL_SOFTCLOCK);
+ DO_SOFTINT(SI_SOFT, IPL_SOFT);
+ } while( softint_pending & intr_mask );
+#else
+ while( (si = find_first_bit(softint_pending & intr_mask)) >= 0 ){
+ softint_pending &= ~SI_TO_IRQBIT(si);
+ __raise(si_to_ipl(si));
+ restore_interrupts(oldirqstate);
+ softintr_dispatch(si);
+ oldirqstate = disable_interrupts(I32_bit);
+ pxa2x0_setipl(spl_save);
+ }
+#endif
+
+ __cpu_simple_unlock(&processing);
+
+ restore_interrupts(oldirqstate);
+}
+
+
+#undef splx
+void
+splx(int ipl)
+{
+
+ pxa2x0_splx(ipl);
+}
+
+#undef _splraise
+int
+_splraise(int ipl)
+{
+
+ return pxa2x0_splraise(ipl);
+}
+
+#undef _spllower
+int
+_spllower(int ipl)
+{
+
+ return pxa2x0_spllower(ipl);
+}
+
+#undef _setsoftintr
+void
+_setsoftintr(int si)
+{
+
+ return pxa2x0_setsoftintr(si);
+}
+
+void *
+pxa2x0_intr_establish(int irqno, int level,
+ int (*func)(void *), void *cookie)
+{
+ int psw;
+
+ if (irqno < PXA2X0_IRQ_MIN || irqno >= ICU_LEN)
+ panic("intr_establish: bogus irq number %d", irqno);
+
+ psw = disable_interrupts(I32_bit);
+
+ handler[irqno].cookie = cookie;
+ handler[irqno].func = func;
+ extirq_level[irqno] = level;
+ pxa2x0_update_intr_masks(irqno, level);
+
+ intr_mask = pxa2x0_imask[current_spl_level];
+
+ restore_interrupts(psw);
+
+ return (&handler[irqno]);
+}
+
+/*
+ * Glue for drivers of sa11x0 compatible integrated logics.
+ */
+void *
+sa11x0_intr_establish(sa11x0_chipset_tag_t ic, int irq, int type, int level,
+ int (*ih_fun)(void *), void *ih_arg)
+{
+
+ return pxa2x0_intr_establish(irq, level, ih_fun, ih_arg);
+}
diff --git a/sys/arch/arm/xscale/pxa2x0_intr.h b/sys/arch/arm/xscale/pxa2x0_intr.h
new file mode 100644
index 00000000000..e2927875cf0
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_intr.h
@@ -0,0 +1,192 @@
+/* $NetBSD: pxa2x0_intr.h,v 1.4 2003/07/05 06:53:08 dogcow Exp $ */
+
+/* Derived from i80321_intr.h */
+
+/*
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PXA2X0_INTR_H_
+#define _PXA2X0_INTR_H_
+
+#define ARM_IRQ_HANDLER _C_LABEL(pxa2x0_irq_handler)
+
+#ifndef _LOCORE
+
+#define __NEWINTR /* enables new hooks in cpu_fork()/cpu_switch() */
+
+#include <arm/armreg.h>
+#include <arm/cpufunc.h>
+#if 0
+#include <arm/cpu.h>
+#include <machine/atomic.h>
+#endif
+#include <machine/intr.h>
+#include <arm/softintr.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+
+extern vaddr_t pxaic_base; /* Shared with pxa2x0_irq.S */
+#define read_icu(offset) (*(volatile uint32_t *)(pxaic_base+(offset)))
+#define write_icu(offset,value) \
+ (*(volatile uint32_t *)(pxaic_base+(offset))=(value))
+
+extern __volatile int current_spl_level;
+extern __volatile int intr_mask;
+extern __volatile int softint_pending;
+extern int pxa2x0_imask[];
+void pxa2x0_do_pending(void);
+
+#define SI_TO_IRQBIT(si) (1U<<(si))
+#if 0
+/*
+ * Cotulla's integrated ICU doesn't have IRQ0..7, so
+ * we map software interrupts to bit 0..3
+ */
+
+static __inline void
+pxa2x0_setipl(int new)
+{
+ current_spl_level = new;
+ intr_mask = pxa2x0_imask[current_spl_level];
+ write_icu( SAIPIC_MR, intr_mask );
+}
+
+
+static __inline void
+pxa2x0_splx(int new)
+{
+ int psw;
+
+ psw = disable_interrupts(I32_bit);
+ pxa2x0_setipl(new);
+ restore_interrupts(psw);
+
+ /* If there are software interrupts to process, do it. */
+ if (softint_pending & intr_mask)
+ pxa2x0_do_pending();
+}
+
+
+static __inline int
+pxa2x0_splraise(int ipl)
+{
+ int old, psw;
+
+ old = current_spl_level;
+ if( ipl > current_spl_level ){
+ psw = disable_interrupts(I32_bit);
+ pxa2x0_setipl(ipl);
+ restore_interrupts(psw);
+ }
+
+ return (old);
+}
+
+static __inline int
+pxa2x0_spllower(int ipl)
+{
+ int old = current_spl_level;
+ int psw = disable_interrupts(I32_bit);
+ pxa2x0_splx(ipl);
+ restore_interrupts(psw);
+ return(old);
+}
+
+static __inline void
+pxa2x0_setsoftintr(int si)
+{
+ atomic_set_bit( (u_int *)&softint_pending, SI_TO_IRQBIT(si) );
+
+ /* Process unmasked pending soft interrupts. */
+ if ( softint_pending & intr_mask )
+ pxa2x0_do_pending();
+}
+#endif
+void pxa2x0_setipl(int new);
+void pxa2x0_splx(int new);
+int pxa2x0_splraise(int ipl);
+int pxa2x0_spllower(int ipl);
+void pxa2x0_setsoftintr(int si);
+
+
+/*
+ * An useful function for interrupt handlers.
+ * XXX: This shouldn't be here.
+ */
+static __inline int
+find_first_bit( uint32_t bits )
+{
+ int count;
+
+ /* since CLZ is available only on ARMv5, this isn't portable
+ * to all ARM CPUs. This file is for PXA2[15]0 processor.
+ */
+ asm( "clz %0, %1" : "=r" (count) : "r" (bits) );
+ return 31-count;
+}
+
+
+int _splraise(int);
+int _spllower(int);
+void splx(int);
+void _setsoftintr(int);
+
+#if !defined(EVBARM_SPL_NOINLINE)
+
+#define splx(new) pxa2x0_splx(new)
+#define _spllower(ipl) pxa2x0_spllower(ipl)
+#define _splraise(ipl) pxa2x0_splraise(ipl)
+#define _setsoftintr(si) pxa2x0_setsoftintr(si)
+
+#endif /* !EVBARM_SPL_NOINTR */
+
+/*
+ * This function *MUST* be called very early on in a port's
+ * initarm() function, before ANY spl*() functions are called.
+ *
+ * The parameter is the virtual address of the PXA2x0's Interrupt
+ * Controller registers.
+ */
+void pxa2x0_intr_bootstrap(vaddr_t);
+
+void pxa2x0_irq_handler(void *);
+void *pxa2x0_intr_establish(int irqno, int level,
+ int (*func)(void *), void *cookie);
+void pxa2x0_update_intr_masks(int irqno, int level);
+extern __volatile int current_spl_level;
+
+#endif /* ! _LOCORE */
+
+#endif /* _PXA2X0_INTR_H_ */
diff --git a/sys/arch/arm/xscale/pxa2x0_lcd.c b/sys/arch/arm/xscale/pxa2x0_lcd.c
new file mode 100644
index 00000000000..7dac0e6c77f
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_lcd.c
@@ -0,0 +1,743 @@
+/* $NetBSD: pxa2x0_lcd.c,v 1.8 2003/10/03 07:24:05 bsh Exp $ */
+
+/*
+ * Copyright (c) 2002 Genetec Corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Support PXA2[15]0's integrated LCD controller.
+ */
+
+#include <sys/cdefs.h>
+/*
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_lcd.c,v 1.8 2003/10/03 07:24:05 bsh Exp $");
+*/
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h> /* for cold */
+
+#include <uvm/uvm_extern.h>
+
+#include <dev/cons.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wscons_callbacks.h>
+#include <dev/rasops/rasops.h>
+#include <dev/wsfont/wsfont.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <arm/cpufunc.h>
+
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0_lcd.h>
+#include <arm/xscale/pxa2x0_gpio.h>
+
+#include "wsdisplay.h"
+
+int lcdintr(void *);
+
+void
+pxa2x0_lcd_geometry(struct pxa2x0_lcd_softc *sc,
+ const struct lcd_panel_geometry *info)
+{
+ int lines;
+ bus_space_tag_t iot = sc->iot;
+ bus_space_handle_t ioh = sc->ioh;
+ uint32_t ccr0;
+
+ sc->geometry = info;
+
+ ccr0 = LCCR0_IMASK;
+ if (info->panel_info & LCDPANEL_ACTIVE)
+ ccr0 |= LCCR0_PAS; /* active mode */
+ if ((info->panel_info & (LCDPANEL_DUAL|LCDPANEL_ACTIVE))
+ == LCDPANEL_DUAL)
+ ccr0 |= LCCR0_SDS; /* dual panel */
+ if (info->panel_info & LCDPANEL_MONOCHROME)
+ ccr0 |= LCCR0_CMS;
+ bus_space_write_4(iot, ioh, LCDC_LCCR0, ccr0);
+
+ bus_space_write_4(iot, ioh, LCDC_LCCR1,
+ (info->panel_width-1)
+ | ((info->hsync_pulse_width-1)<<10)
+ | ((info->end_line_wait-1)<<16)
+ | ((info->beg_line_wait-1)<<24));
+
+ if (info->panel_info & LCDPANEL_DUAL)
+ lines = info->panel_height/2 + info->extra_lines;
+ else
+ lines = info->panel_height + info->extra_lines;
+
+ bus_space_write_4(iot, ioh, LCDC_LCCR2,
+ (lines-1)
+ | (info->vsync_pulse_width<<10)
+ | (info->end_frame_wait<<16)
+ | (info->beg_frame_wait<<24));
+
+ bus_space_write_4(iot, ioh, LCDC_LCCR3,
+ (info->pixel_clock_div<<0)
+ | (info->ac_bias << 8)
+ | ((info->panel_info &
+ (LCDPANEL_VSP|LCDPANEL_HSP|LCDPANEL_PCP|LCDPANEL_OEP))
+ <<20)
+ | (4 << 24) /* 16bpp */
+ | ((info->panel_info & LCDPANEL_DPC) ? (1<<27) : 0)
+ );
+}
+
+void
+pxa2x0_lcd_attach_sub(struct pxa2x0_lcd_softc *sc,
+ struct pxaip_attach_args *pxa, const struct lcd_panel_geometry *geom)
+{
+ bus_space_tag_t iot = pxa->pxa_iot;
+ bus_space_handle_t ioh;
+ int error, nldd;
+
+ sc->n_screens = 0;
+ LIST_INIT(&sc->screens);
+
+ /* map controller registers */
+ error = bus_space_map(iot, PXA2X0_LCDC_BASE,
+ PXA2X0_LCDC_SIZE, 0, &ioh);
+ if (error) {
+ printf(": failed to map registers %d", error);
+ return;
+ }
+
+ sc->iot = iot;
+ sc->ioh = ioh;
+ sc->dma_tag = &pxa2x0_bus_dma_tag;
+
+ sc->ih = pxa2x0_intr_establish(17, IPL_BIO, lcdintr, sc);
+ if (sc->ih == NULL)
+ printf("%s: unable to establish interrupt at irq %d",
+ sc->dev.dv_xname, 17);
+
+ /* Initialize LCD controller */
+
+ /* enable clock */
+ pxa2x0_clkman_config(CKEN_LCD, 1);
+
+ bus_space_write_4(iot, ioh, LCDC_LCCR0, LCCR0_IMASK);
+
+ /*
+ * setup GP[77:58] for LCD
+ */
+ /* Always use [FLP]CLK, ACBIAS */
+ pxa2x0_gpio_set_function(74, GPIO_ALT_FN_2_OUT);
+ pxa2x0_gpio_set_function(75, GPIO_ALT_FN_2_OUT);
+ pxa2x0_gpio_set_function(76, GPIO_ALT_FN_2_OUT);
+ pxa2x0_gpio_set_function(77, GPIO_ALT_FN_2_OUT);
+
+ if ((geom->panel_info & LCDPANEL_ACTIVE) ||
+ ((geom->panel_info & (LCDPANEL_MONOCHROME|LCDPANEL_DUAL)) ==
+ LCDPANEL_DUAL)) {
+ /* active and color dual panel need L_DD[15:0] */
+ nldd = 16;
+ } else
+ if ((geom->panel_info & LCDPANEL_DUAL) ||
+ !(geom->panel_info & LCDPANEL_MONOCHROME)) {
+ /* dual or color need L_DD[7:0] */
+ nldd = 8;
+ } else {
+ /* Otherwise just L_DD[3:0] */
+ nldd = 4;
+ }
+
+ while (nldd--)
+ pxa2x0_gpio_set_function(58 + nldd, GPIO_ALT_FN_2_OUT);
+
+ pxa2x0_lcd_geometry(sc, geom);
+}
+
+
+int
+lcdintr(void *arg)
+{
+ struct pxa2x0_lcd_softc *sc = arg;
+ bus_space_tag_t iot = sc->iot;
+ bus_space_handle_t ioh = sc->ioh;
+
+ static uint32_t status;
+
+ status = bus_space_read_4(iot, ioh, LCDC_LCSR);
+ /* Clear stickey status bits */
+ bus_space_write_4(iot, ioh, LCDC_LCSR, status);
+
+ return 1;
+}
+
+void
+pxa2x0_lcd_start_dma(struct pxa2x0_lcd_softc *sc,
+ struct pxa2x0_lcd_screen *scr)
+{
+ uint32_t tmp;
+ bus_space_tag_t iot = sc->iot;
+ bus_space_handle_t ioh = sc->ioh;
+ int val, save;
+
+ save = disable_interrupts(I32_bit);
+
+ switch (scr->depth) {
+ case 1: val = 0; break;
+ case 2: val = 1; break;
+ case 4: val = 2; break;
+ case 8: val = 3; break;
+ case 16: /* FALLTHROUGH */
+ default:
+ val = 4; break;
+ }
+
+ tmp = bus_space_read_4(iot, ioh, LCDC_LCCR3);
+ bus_space_write_4(iot, ioh, LCDC_LCCR3,
+ (tmp & ~LCCR3_BPP) | (val << LCCR3_BPP_SHIFT));
+
+ bus_space_write_4(iot, ioh, LCDC_FDADR0,
+ scr->depth == 16 ? scr->dma_desc_pa :
+ scr->dma_desc_pa + 2 * sizeof (struct lcd_dma_descriptor));
+ bus_space_write_4(iot, ioh, LCDC_FDADR1,
+ scr->dma_desc_pa + 1 * sizeof (struct lcd_dma_descriptor));
+
+ /* clear status */
+ bus_space_write_4(iot, ioh, LCDC_LCSR, 0);
+
+ delay(1000); /* ??? */
+
+ /* Enable LCDC */
+ tmp = bus_space_read_4(iot, ioh, LCDC_LCCR0);
+ /*tmp &= ~LCCR0_SFM;*/
+ bus_space_write_4(iot, ioh, LCDC_LCCR0, tmp | LCCR0_ENB);
+
+ restore_interrupts(save);
+
+}
+
+
+#if NWSDISPLAY > 0
+static void
+pxa2x0_lcd_stop_dma(struct pxa2x0_lcd_softc *sc)
+{
+ /* Stop LCD DMA after current frame */
+ bus_space_write_4(sc->iot, sc->ioh, LCDC_LCCR0,
+ LCCR0_DIS |
+ bus_space_read_4(sc->iot, sc->ioh, LCDC_LCCR0));
+
+ /* wait for disabling done.
+ XXX: use interrupt. */
+ while (LCCR0_ENB &
+ bus_space_read_4(sc->iot, sc->ioh, LCDC_LCCR0))
+ ;
+
+ bus_space_write_4(sc->iot, sc->ioh, LCDC_LCCR0,
+ ~LCCR0_DIS &
+ bus_space_read_4(sc->iot, sc->ioh, LCDC_LCCR0));
+}
+#endif
+
+#define _rgb(r,g,b) (((r)<<11) | ((g)<<5) | b)
+#define rgb(r,g,b) _rgb((r)>>1,g,(b)>>1)
+
+#define L 0x1f /* low intensity */
+#define H 0x3f /* hight intensity */
+
+static uint16_t basic_color_map[] = {
+ rgb( 0, 0, 0), /* black */
+ rgb( L, 0, 0), /* red */
+ rgb( 0, L, 0), /* green */
+ rgb( L, L, 0), /* brown */
+ rgb( 0, 0, L), /* blue */
+ rgb( L, 0, L), /* magenta */
+ rgb( 0, L, L), /* cyan */
+ _rgb(0x1c,0x38,0x1c), /* white */
+
+ rgb( L, L, L), /* black */
+ rgb( H, 0, 0), /* red */
+ rgb( 0, H, 0), /* green */
+ rgb( H, H, 0), /* brown */
+ rgb( 0, 0, H), /* blue */
+ rgb( H, 0, H), /* magenta */
+ rgb( 0, H, H), /* cyan */
+ rgb( H, H, H)
+};
+
+#undef H
+#undef L
+
+static void
+init_pallet(uint16_t *buf, int depth)
+{
+ int i;
+
+ /* convert RGB332 to RGB565 */
+ switch (depth) {
+ case 8:
+ case 4:
+#if 0
+ for (i=0; i <= 255; ++i) {
+ buf[i] = ((9 * ((i>>5) & 0x07)) <<11) |
+ ((9 * ((i>>2) & 0x07)) << 5) |
+ ((21 * (i & 0x03))/2);
+ }
+#else
+ memcpy(buf, basic_color_map, sizeof basic_color_map);
+ for (i=16; i < (1<<depth); ++i)
+ buf[i] = 0xffff;
+#endif
+ break;
+ case 16:
+ /* pallet is not needed */
+ break;
+ default:
+ /* other depths are not supported */
+ break;
+ }
+}
+
+struct pxa2x0_lcd_screen *
+pxa2x0_lcd_new_screen(struct pxa2x0_lcd_softc *sc,
+ int depth)
+{
+ struct pxa2x0_lcd_screen *scr = NULL;
+ int width, height;
+ bus_size_t size;
+ int error, pallet_size;
+ int busdma_flag = (cold ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
+ struct lcd_dma_descriptor *desc;
+ paddr_t buf_pa, desc_pa;
+
+ width = sc->geometry->panel_width;
+ height = sc->geometry->panel_height;
+ pallet_size = 0;
+
+ switch (depth) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ pallet_size = (1<<depth) * sizeof (uint16_t);
+ /* FALLTHROUGH */
+ case 16:
+ size = roundup(width,4)*depth/8 * height;
+ break;
+ default:
+ printf("%s: Unknown depth (%d)\n", sc->dev.dv_xname, depth);
+ return NULL;
+ }
+
+ scr = malloc(sizeof *scr, M_DEVBUF,
+ (cold ? M_NOWAIT : M_WAITOK));
+
+ if (scr == NULL)
+ return NULL;
+
+ bzero (scr, sizeof *scr);
+
+ scr->nsegs = 0;
+ scr->depth = depth;
+ scr->buf_size = size;
+ scr->buf_va = NULL;
+ size = roundup(size,16) + 3 * sizeof (struct lcd_dma_descriptor)
+ + pallet_size;
+
+ error = bus_dmamem_alloc(sc->dma_tag, size, 16, 0,
+ scr->segs, 1, &(scr->nsegs), busdma_flag);
+
+ if (error || scr->nsegs != 1) {
+ /* XXX: Actually we can handle nsegs>1 case by means
+ of multiple DMA descriptors for a panel. it will
+ makes code here a bit hairly */
+ goto bad;
+ }
+
+ error = bus_dmamem_map(sc->dma_tag, scr->segs, scr->nsegs,
+ size, (caddr_t *)&(scr->buf_va), busdma_flag | BUS_DMA_COHERENT);
+ if (error)
+ goto bad;
+
+
+ memset (scr->buf_va, 0, scr->buf_size);
+
+ /* map memory for DMA */
+ if (bus_dmamap_create(sc->dma_tag, 1024*1024*2, 1,
+ 1024*1024*2, 0, busdma_flag, &scr->dma))
+ goto bad;
+ error = bus_dmamap_load(sc->dma_tag, scr->dma,
+ scr->buf_va, size, NULL, busdma_flag);
+ if (error) {
+ goto bad;
+ }
+
+ buf_pa = scr->segs[0].ds_addr;
+ desc_pa = buf_pa + roundup(size, PAGE_SIZE) - 3*sizeof *desc;
+
+ /* make descriptors at the top of mapped memory */
+ desc = (struct lcd_dma_descriptor *)(
+ (caddr_t)(scr->buf_va) + roundup(size, PAGE_SIZE) -
+ 3*sizeof *desc);
+
+ desc[0].fdadr = desc_pa;
+ desc[0].fsadr = buf_pa;
+ desc[0].ldcmd = scr->buf_size;
+
+ if (pallet_size) {
+ init_pallet((uint16_t *)((char *)desc - pallet_size), depth);
+
+ desc[2].fdadr = desc_pa; /* chain to panel 0 */
+ desc[2].fsadr = desc_pa - pallet_size;
+ desc[2].ldcmd = pallet_size | LDCMD_PAL;
+ }
+
+ if (sc->geometry->panel_info & LCDPANEL_DUAL) {
+ /* Dual panel */
+ desc[1].fdadr = desc_pa + sizeof *desc;
+ desc[1].fsadr = buf_pa + scr->buf_size/2;
+ desc[0].ldcmd = desc[1].ldcmd = scr->buf_size/2;
+
+ }
+
+#if 0
+ desc[0].ldcmd |= LDCMD_SOFINT;
+ desc[1].ldcmd |= LDCMD_SOFINT;
+#endif
+
+ scr->dma_desc = desc;
+ scr->dma_desc_pa = desc_pa;
+ scr->map_size = size; /* used when unmap this. */
+
+ LIST_INSERT_HEAD(&(sc->screens), scr, link);
+ sc->n_screens++;
+
+ return scr;
+
+ bad:
+ if (scr) {
+ if (scr->buf_va)
+ bus_dmamem_unmap(sc->dma_tag, scr->buf_va, size);
+ if (scr->nsegs)
+ bus_dmamem_free(sc->dma_tag, scr->segs, scr->nsegs);
+ free(scr, M_DEVBUF);
+ }
+ return NULL;
+}
+
+
+#if NWSDISPLAY > 0
+
+/*
+ * Initialize struct wsscreen_descr based on values calculated by
+ * raster operation subsystem.
+ */
+int
+pxa2x0_lcd_setup_wsscreen(struct pxa2x0_wsscreen_descr *descr,
+ const struct lcd_panel_geometry *geom,
+ const char *fontname)
+{
+ int width = geom->panel_width;
+ int height = geom->panel_height;
+ int cookie = -1;
+ struct rasops_info rinfo;
+
+ memset(&rinfo, 0, sizeof rinfo);
+
+#if 0
+ if (fontname) {
+ wsfont_init();
+ cookie = wsfont_find((char *)fontname, 0, 0, 0,
+ WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R);
+ if (cookie < 0 ||
+ wsfont_lock(cookie, &rinfo.ri_font))
+ return -1;
+ }
+ else {
+ /* let rasops_init() choose any font */
+ }
+#endif
+
+ /* let rasops_init calculate # of cols and rows in character */
+ rinfo.ri_flg = 0;
+ rinfo.ri_depth = descr->depth;
+ rinfo.ri_bits = NULL;
+ rinfo.ri_width = width;
+ rinfo.ri_height = height;
+ rinfo.ri_stride = width * rinfo.ri_depth / 8;
+ rinfo.ri_wsfcookie = cookie;
+
+ rasops_init(&rinfo, 100, 100);
+
+ descr->c.nrows = rinfo.ri_rows;
+ descr->c.ncols = rinfo.ri_cols;
+ descr->c.capabilities = rinfo.ri_caps;
+
+
+ return cookie;
+}
+
+
+int
+pxa2x0_lcd_show_screen(void *v, void *cookie, int waitok,
+ void (*cb)(void *, int, int), void *cbarg)
+{
+ struct pxa2x0_lcd_softc *sc = v;
+ struct pxa2x0_lcd_screen *scr = cookie, *old;
+
+ old = sc->active;
+ if (old == scr)
+ return 0;
+
+ if (old)
+ pxa2x0_lcd_stop_dma(sc);
+
+ pxa2x0_lcd_start_dma(sc, scr);
+
+ sc->active = scr;
+ return 0;
+}
+
+int
+pxa2x0_lcd_alloc_screen(void *v, const struct wsscreen_descr *_type,
+ void **cookiep, int *curxp, int *curyp, long *attrp)
+{
+ struct pxa2x0_lcd_softc *sc = v;
+ struct pxa2x0_lcd_screen *scr;
+ struct pxa2x0_wsscreen_descr *type = (struct pxa2x0_wsscreen_descr *)_type;
+
+ scr = pxa2x0_lcd_new_screen(sc, type->depth);
+ if (scr == NULL)
+ return -1;
+
+ /*
+ * initialize raster operation for this screen.
+ */
+ scr->rinfo.ri_flg = 0;
+ scr->rinfo.ri_depth = type->depth;
+ scr->rinfo.ri_bits = scr->buf_va;
+ scr->rinfo.ri_width = sc->geometry->panel_width;
+ scr->rinfo.ri_height = sc->geometry->panel_height;
+ scr->rinfo.ri_stride = scr->rinfo.ri_width * scr->rinfo.ri_depth / 8;
+ scr->rinfo.ri_wsfcookie = -1; /* XXX */
+
+ rasops_init(&scr->rinfo, type->c.nrows, type->c.ncols);
+
+ scr->rinfo.ri_ops.alloc_attr(&scr->rinfo, 0, 0, 0, attrp);
+
+
+ *cookiep = scr;
+ *curxp = 0;
+ *curyp = 0;
+
+ return 0;
+}
+
+
+void
+pxa2x0_lcd_free_screen(void *v, void *cookie)
+{
+ struct pxa2x0_lcd_softc *sc = v;
+ struct pxa2x0_lcd_screen *scr = cookie;
+
+ LIST_REMOVE(scr, link);
+ sc->n_screens--;
+ if (scr == sc->active) {
+ /* at first, we need to stop LCD DMA */
+ sc->active = NULL;
+
+ printf("lcd_free on active screen\n");
+
+ pxa2x0_lcd_stop_dma(sc);
+ }
+
+ if (scr->buf_va)
+ bus_dmamem_unmap(sc->dma_tag, scr->buf_va, scr->map_size);
+
+ if (scr->nsegs > 0)
+ bus_dmamem_free(sc->dma_tag, scr->segs, scr->nsegs);
+
+ free(scr, M_DEVBUF);
+}
+
+int
+pxa2x0_lcd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct pxa2x0_lcd_softc *sc = v;
+ struct wsdisplay_fbinfo *wsdisp_info;
+ uint32_t ccr0;
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_UNKNOWN; /* XXX */
+ return 0;
+
+ case WSDISPLAYIO_GINFO:
+ wsdisp_info = (struct wsdisplay_fbinfo *)data;
+
+ wsdisp_info->height = sc->geometry->panel_height;
+ wsdisp_info->width = sc->geometry->panel_width;
+ wsdisp_info->depth = 16; /* XXX */
+ wsdisp_info->cmsize = 0;
+ return 0;
+
+ case WSDISPLAYIO_GETCMAP:
+ case WSDISPLAYIO_PUTCMAP:
+ return EINVAL; /* XXX Colormap */
+
+ case WSDISPLAYIO_SVIDEO:
+ if (*(int *)data == WSDISPLAYIO_VIDEO_ON) {
+ /* turn it on */
+ }
+ else {
+ /* start LCD shutdown */
+ /* sleep until interrupt */
+ }
+ return 0;
+
+ case WSDISPLAYIO_GVIDEO:
+ ccr0 = bus_space_read_4(sc->iot, sc->ioh, LCDC_LCCR0);
+ *(u_int *)data = (ccr0 & (LCCR0_ENB|LCCR0_DIS)) == LCCR0_ENB ?
+ WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF;
+ return 0;
+
+
+
+ case WSDISPLAYIO_GCURPOS:
+ case WSDISPLAYIO_SCURPOS:
+ case WSDISPLAYIO_GCURMAX:
+ case WSDISPLAYIO_GCURSOR:
+ case WSDISPLAYIO_SCURSOR:
+ return -1; /* XXX */
+ }
+
+ return -1;
+}
+
+paddr_t
+pxa2x0_lcd_mmap(void *v, off_t offset, int prot)
+{
+ struct pxa2x0_lcd_softc *sc = v;
+ struct pxa2x0_lcd_screen *screen = sc->active; /* ??? */
+
+ if (screen == NULL)
+ return -1;
+
+ return bus_dmamem_mmap(sc->dma_tag, screen->segs, screen->nsegs,
+ offset, prot, BUS_DMA_WAITOK|BUS_DMA_COHERENT);
+ return -1;
+}
+
+
+static void
+pxa2x0_lcd_cursor(void *cookie, int on, int row, int col)
+{
+ struct pxa2x0_lcd_screen *scr = cookie;
+
+ (* scr->rinfo.ri_ops.cursor)(&scr->rinfo, on, row, col);
+}
+
+static int
+pxa2x0_lcd_mapchar(void *cookie, int c, unsigned int *cp)
+{
+ struct pxa2x0_lcd_screen *scr = cookie;
+
+ return (* scr->rinfo.ri_ops.mapchar)(&scr->rinfo, c, cp);
+}
+
+static void
+pxa2x0_lcd_putchar(void *cookie, int row, int col, u_int uc, long attr)
+{
+ struct pxa2x0_lcd_screen *scr = cookie;
+
+ (* scr->rinfo.ri_ops.putchar)(&scr->rinfo,
+ row, col, uc, attr);
+}
+
+static void
+pxa2x0_lcd_copycols(void *cookie, int row, int src, int dst, int num)
+{
+ struct pxa2x0_lcd_screen *scr = cookie;
+
+ (* scr->rinfo.ri_ops.copycols)(&scr->rinfo,
+ row, src, dst, num);
+}
+
+static void
+pxa2x0_lcd_erasecols(void *cookie, int row, int col, int num, long attr)
+{
+ struct pxa2x0_lcd_screen *scr = cookie;
+
+ (* scr->rinfo.ri_ops.erasecols)(&scr->rinfo,
+ row, col, num, attr);
+}
+
+static void
+pxa2x0_lcd_copyrows(void *cookie, int src, int dst, int num)
+{
+ struct pxa2x0_lcd_screen *scr = cookie;
+
+ (* scr->rinfo.ri_ops.copyrows)(&scr->rinfo,
+ src, dst, num);
+}
+
+static void
+pxa2x0_lcd_eraserows(void *cookie, int row, int num, long attr)
+{
+ struct pxa2x0_lcd_screen *scr = cookie;
+
+ (* scr->rinfo.ri_ops.eraserows)(&scr->rinfo,
+ row, num, attr);
+}
+
+static int
+pxa2x0_lcd_alloc_attr(void *cookie, int fg, int bg, int flg, long *attr)
+{
+ struct pxa2x0_lcd_screen *scr = cookie;
+
+ return scr->rinfo.ri_ops.alloc_attr(&scr->rinfo, fg, bg, flg, attr);
+}
+
+
+const struct wsdisplay_emulops pxa2x0_lcd_emulops = {
+ pxa2x0_lcd_cursor,
+ pxa2x0_lcd_mapchar,
+ pxa2x0_lcd_putchar,
+ pxa2x0_lcd_copycols,
+ pxa2x0_lcd_erasecols,
+ pxa2x0_lcd_copyrows,
+ pxa2x0_lcd_eraserows,
+ pxa2x0_lcd_alloc_attr
+};
+
+#endif /* NWSDISPLAY > 0 */
diff --git a/sys/arch/arm/xscale/pxa2x0_lcd.h b/sys/arch/arm/xscale/pxa2x0_lcd.h
new file mode 100644
index 00000000000..7750f2f3ba1
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_lcd.h
@@ -0,0 +1,149 @@
+/* $NetBSD: pxa2x0_lcd.h,v 1.2 2003/06/17 09:43:14 bsh Exp $ */
+/*
+ * Copyright (c) 2002 Genetec Corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef _ARM_XSCALE_PXA2X0_LCD_H
+#define _ARM_XSCALE_PXA2X0_LCD_H
+
+#include <dev/rasops/rasops.h>
+#include <machine/bus.h>
+
+/* LCD Contoroller */
+
+struct lcd_dma_descriptor {
+ uint32_t fdadr; /* next frame descriptor */
+ uint32_t fsadr; /* frame start address */
+ uint32_t fidr; /* frame ID */
+ uint32_t ldcmd; /* DMA command */
+#define LDCMD_PAL (1U<<26) /* Pallet buffer */
+#define LDCMD_SOFINT (1U<<22) /* Start of Frame interrupt */
+#define LDCMD_EOFINT (1U<<21) /* End of Frame interrupt */
+};
+
+
+struct pxa2x0_lcd_screen {
+ LIST_ENTRY(pxa2x0_lcd_screen) link;
+
+ /* Frame buffer */
+ bus_dmamap_t dma;
+ bus_dma_segment_t segs[1];
+ int nsegs;
+ size_t buf_size;
+ size_t map_size;
+ void *buf_va;
+ int depth;
+
+ /* DMA frame descriptor */
+ struct lcd_dma_descriptor *dma_desc;
+ paddr_t dma_desc_pa;
+
+ /* rasterop */
+ struct rasops_info rinfo;
+};
+
+struct pxa2x0_lcd_softc {
+ struct device dev;
+ /* control register */
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ bus_dma_tag_t dma_tag;
+
+ const struct lcd_panel_geometry *geometry;
+
+ int n_screens;
+ LIST_HEAD(, pxa2x0_lcd_screen) screens;
+ struct pxa2x0_lcd_screen *active;
+ void *ih; /* interrupt handler */
+};
+
+void pxa2x0_lcd_attach_sub(struct pxa2x0_lcd_softc *, struct pxaip_attach_args *,
+ const struct lcd_panel_geometry *);
+void pxa2x0_lcd_start_dma(struct pxa2x0_lcd_softc *, struct pxa2x0_lcd_screen *);
+
+struct lcd_panel_geometry {
+ short panel_width;
+ short panel_height;
+ short extra_lines;
+
+ short panel_info;
+#define LCDPANEL_VSP (1<<0) /* L_FCLK pin is active low */
+#define LCDPANEL_HSP (1<<1) /* L_LCLK pin is active low */
+#define LCDPANEL_PCP (1<<2) /* use L_PCLK falling edge */
+#define LCDPANEL_OEP (1<<3) /* L_BIAS pin is active low */
+#define LCDPANEL_DPC (1<<4) /* double pixel clock mode */
+
+#define LCDPANEL_DUAL (1<<5) /* Dual or single */
+#define LCDPANEL_SINGLE 0
+#define LCDPANEL_ACTIVE (1<<6) /* Active or Passive */
+#define LCDPANEL_PASSIVE 0
+#define LCDPANEL_MONOCHROME (1<<7) /* depth=1 */
+
+ short pixel_clock_div; /* pixel clock divider */
+ short ac_bias; /* AC bias pin frequency */
+
+ short hsync_pulse_width; /* Horizontao sync pulse width */
+ short beg_line_wait; /* beginning of line wait (BLW) */
+ short end_line_wait; /* end of line pxel wait (ELW) */
+
+ short vsync_pulse_width; /* vertical sync pulse width */
+ short beg_frame_wait; /* beginning of frame wait (BFW) */
+ short end_frame_wait; /* end of frame wait (EFW) */
+};
+
+void pxa2x0_lcd_geometry(struct pxa2x0_lcd_softc *,
+ const struct lcd_panel_geometry *);
+struct pxa2x0_lcd_screen *pxa2x0_lcd_new_screen(
+ struct pxa2x0_lcd_softc *, int depth);
+
+/*
+ * we need bits-per-pixel value to configure wsdisplay screen
+ */
+struct pxa2x0_wsscreen_descr {
+ struct wsscreen_descr c; /* standard descriptor */
+ int depth; /* bits per pixel */
+};
+
+int pxa2x0_lcd_setup_wsscreen(struct pxa2x0_wsscreen_descr *,
+ const struct lcd_panel_geometry *, const char * );
+
+int pxa2x0_lcd_show_screen(void *, void *, int, void (*)(void *, int, int), void *);
+int pxa2x0_lcd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p);
+paddr_t pxa2x0_lcd_mmap(void *, off_t, int);
+int pxa2x0_lcd_alloc_screen(void *, const struct wsscreen_descr *,
+ void **, int *, int *, long *);
+void pxa2x0_lcd_free_screen(void *, void *);
+
+extern const struct wsdisplay_emulops pxa2x0_lcd_emulops;
+
+#endif /* _ARM_XSCALE_PXA2X0_LCD_H */
diff --git a/sys/arch/arm/xscale/pxa2x0_space.c b/sys/arch/arm/xscale/pxa2x0_space.c
new file mode 100644
index 00000000000..30690b5707d
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_space.c
@@ -0,0 +1,267 @@
+/* $NetBSD: pxa2x0_space.c,v 1.5 2004/06/07 19:45:22 nathanw Exp $ */
+
+/*
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1997 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Ichiro FUKUHARA.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mark Brinicombe.
+ * 4. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * bus_space functions for Intel PXA2[51]0 application processor.
+ * Derived from i80321_space.c.
+ */
+
+#include <sys/cdefs.h>
+/*
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_space.c,v 1.5 2004/06/07 19:45:22 nathanw Exp $");
+*/
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/bus.h>
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(pxa2x0);
+bs_protos(generic);
+bs_protos(generic_armv4);
+bs_protos(bs_notimpl);
+
+struct bus_space pxa2x0_bs_tag = {
+ /* cookie */
+ (void *) 0,
+
+ /* mapping/unmapping */
+ pxa2x0_bs_map,
+ pxa2x0_bs_unmap,
+ pxa2x0_bs_subregion,
+
+ /* allocation/deallocation */
+ pxa2x0_bs_alloc, /* not implemented */
+ pxa2x0_bs_free, /* not implemented */
+
+ /* get kernel virtual address */
+ pxa2x0_bs_vaddr,
+
+ /* mmap */
+ bs_notimpl_bs_mmap,
+
+ /* barrier */
+ pxa2x0_bs_barrier,
+
+ /* read (single) */
+ generic_bs_r_1,
+ generic_armv4_bs_r_2,
+ generic_bs_r_4,
+ bs_notimpl_bs_r_8,
+
+ /* read multiple */
+ generic_bs_rm_1,
+ generic_armv4_bs_rm_2,
+ generic_bs_rm_4,
+ bs_notimpl_bs_rm_8,
+
+ /* read region */
+ generic_bs_rr_1,
+ generic_armv4_bs_rr_2,
+ generic_bs_rr_4,
+ bs_notimpl_bs_rr_8,
+
+ /* write (single) */
+ generic_bs_w_1,
+ generic_armv4_bs_w_2,
+ generic_bs_w_4,
+ bs_notimpl_bs_w_8,
+
+ /* write multiple */
+ generic_bs_wm_1,
+ generic_armv4_bs_wm_2,
+ generic_bs_wm_4,
+ bs_notimpl_bs_wm_8,
+
+ /* write region */
+ generic_bs_wr_1,
+ generic_armv4_bs_wr_2,
+ generic_bs_wr_4,
+ bs_notimpl_bs_wr_8,
+
+ /* set multiple */
+ bs_notimpl_bs_sm_1,
+ bs_notimpl_bs_sm_2,
+ bs_notimpl_bs_sm_4,
+ bs_notimpl_bs_sm_8,
+
+ /* set region */
+ generic_bs_sr_1,
+ generic_armv4_bs_sr_2,
+ bs_notimpl_bs_sr_4,
+ bs_notimpl_bs_sr_8,
+
+ /* copy */
+ bs_notimpl_bs_c_1,
+ generic_armv4_bs_c_2,
+ bs_notimpl_bs_c_4,
+ bs_notimpl_bs_c_8,
+};
+
+int
+pxa2x0_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
+ int flag, bus_space_handle_t *bshp)
+{
+ u_long startpa, endpa, pa;
+ vaddr_t va;
+ pt_entry_t *pte;
+
+ if ((u_long)bpa > (u_long)KERNEL_BASE) {
+ /* Some IO registers (ex. UART ports for console)
+ are mapped to fixed address by board specific
+ routine. */
+ *bshp = bpa;
+ return(0);
+ }
+
+ startpa = trunc_page(bpa);
+ endpa = round_page(bpa + size);
+
+ /* XXX use extent manager to check duplicate mapping */
+
+ va = uvm_km_valloc(kernel_map, endpa - startpa);
+ if (! va)
+ return(ENOMEM);
+
+ *bshp = (bus_space_handle_t)(va + (bpa - startpa));
+
+ for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
+ pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
+ if ((flag & BUS_SPACE_MAP_CACHEABLE) == 0) {
+ pte = vtopte(va);
+ *pte &= ~L2_S_CACHE_MASK;
+ PTE_SYNC(pte);
+ /* XXX: pmap_kenter_pa() also does PTE_SYNC(). a bit of
+ * waste.
+ */
+ }
+ }
+ pmap_update(pmap_kernel());
+
+ return(0);
+}
+
+void
+pxa2x0_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
+{
+
+ if (bsh > (u_long)KERNEL_BASE)
+ return;
+
+ uvm_km_free(kernel_map, bsh, size);
+}
+
+
+int
+pxa2x0_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
+ bus_size_t size, bus_space_handle_t *nbshp)
+{
+
+ *nbshp = bsh + offset;
+ return (0);
+}
+
+void
+pxa2x0_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset,
+ bus_size_t len, int flags)
+{
+
+ /* Nothing to do. */
+}
+
+void *
+pxa2x0_bs_vaddr(void *t, bus_space_handle_t bsh)
+{
+
+ return ((void *)bsh);
+}
+
+
+int
+pxa2x0_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
+ bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
+ bus_addr_t *bpap, bus_space_handle_t *bshp)
+{
+
+ panic("pxa2x0_io_bs_alloc(): not implemented\n");
+}
+
+void
+pxa2x0_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
+{
+
+ panic("pxa2x0_io_bs_free(): not implemented\n");
+}
+
diff --git a/sys/arch/arm/xscale/pxa2x0reg.h b/sys/arch/arm/xscale/pxa2x0reg.h
new file mode 100644
index 00000000000..53b8bde042d
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0reg.h
@@ -0,0 +1,612 @@
+/* $NetBSD: pxa2x0reg.h,v 1.4 2003/06/11 20:43:01 scw Exp $ */
+
+/*
+ * Copyright (c) 2002 Genetec Corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+ * Intel PXA2[15]0 processor is XScale based integrated CPU
+ *
+ * Reference:
+ * Intel(r) PXA250 and PXA210 Application Processors
+ * Developer's Manual
+ * (278522-001.pdf)
+ */
+#ifndef _ARM_XSCALE_PXA2X0REG_H_
+#define _ARM_XSCALE_PXA2X0REG_H_
+
+/* Borrow some register definitions from sa11x0 */
+#include <arm/sa11x0/sa11x0_reg.h>
+
+#ifndef _LOCORE
+#include <sys/types.h> /* for uint32_t */
+#endif
+
+/*
+ * Chip select domains
+ */
+#define PXA2X0_CS0_START 0x00000000
+#define PXA2X0_CS1_START 0x04000000
+#define PXA2X0_CS2_START 0x08000000
+#define PXA2X0_CS3_START 0x0c000000
+#define PXA2X0_CS4_START 0x10000000
+#define PXA2X0_CS5_START 0x14000000
+
+#define PXA2X0_PCMCIA_SLOT0 0x20000000
+#define PXA2X0_PCMCIA_SLOT1 0x30000000
+
+#define PXA2X0_PERIPH_START 0x40000000
+/* #define PXA2X0_MEMCTL_START 0x48000000 */
+#define PXA2X0_PERIPH_END 0x480fffff
+
+#define PXA2X0_SDRAM0_START 0xa0000000
+#define PXA2X0_SDRAM1_START 0xa4000000
+#define PXA2X0_SDRAM2_START 0xa8000000
+#define PXA2X0_SDRAM3_START 0xac000000
+#define PXA2X0_SDRAM_BANKS 4
+#define PXA2X0_SDRAM_BANK_SIZE 0x04000000
+
+/*
+ * Physical address of integrated peripherals
+ */
+
+#define PXA2X0_DMAC_BASE 0x40000000
+#define PXA2X0_DMAC_SIZE 0x300
+#define PXA2X0_FFUART_BASE 0x40100000 /* Full Function UART */
+#define PXA2X0_BTUART_BASE 0x40200000 /* Bluetooth UART */
+#define PXA2X0_I2C_BASE 0x40300000
+#define PXA2X0_I2C_SIZE 0x000016a4
+#define PXA2X0_I2S_BASE 0x40400000
+#define PXA2X0_AC97_BASE 0x40500000
+#define PXA2X0_AC97_SIZE 0x600
+#define PXA2X0_USBDC_BASE 0x40600000 /* USB Client */
+#define PXA2X0_USBDC_SIZE 0x0e04
+#define PXA2X0_STUART_BASE 0x40700000 /* Standard UART */
+#define PXA2X0_ICP_BASE 0x40800000
+#define PXA2X0_RTC_BASE 0x40900000
+#define PXA2X0_RTC_SIZE 0x10
+#define PXA2X0_OST_BASE 0x40a00000 /* OS Timer */
+#define PXA2X0_PWM0_BASE 0x40b00000
+#define PXA2X0_PWM1_BASE 0x40c00000
+#define PXA2X0_INTCTL_BASE 0x40d00000 /* Interrupt controller */
+#define PXA2X0_INTCTL_SIZE 0x20
+#define PXA2X0_GPIO_BASE 0x40e00000
+#define PXA2X0_GPIO_SIZE 0x70
+#define PXA2X0_POWMAN_BASE 0x40f00000 /* Power management */
+#define PXA2X0_SSP_BASE 0x41000000
+#define PXA2X0_MMC_BASE 0x41100000 /* MultiMediaCard */
+#define PXA2X0_MMC_SIZE 0x48
+#define PXA2X0_CLKMAN_BASE 0x41300000 /* Clock Manager */
+#define PXA2X0_CLKMAN_SIZE 12
+#define PXA2X0_LCDC_BASE 0x44000000 /* LCD Controller */
+#define PXA2X0_LCDC_SIZE 0x220
+#define PXA2X0_MEMCTL_BASE 0x48000000 /* Memory Controller */
+#define PXA2X0_MEMCTL_SIZE 0x48
+
+/* width of interrupt controller */
+#define ICU_LEN 32 /* but [0..7,15,16] is not used */
+#define ICU_INT_HWMASK 0xffffff00
+#define PXA2X0_IRQ_MIN 8 /* 0..7 are not used by integrated
+ peripherals */
+
+#define PXA2X0_INT_GPIO0 8
+#define PXA2X0_INT_GPIO1 9
+#define PXA2X0_INT_GPION 10 /* irq from GPIO[2..80] */
+#define PXA2X0_INT_USB 11
+#define PXA2X0_INT_PMU 12
+#define PXA2X0_INT_I2S 13
+#define PXA2X0_INT_AC97 14
+#define PXA2X0_INT_LCD 17
+#define PXA2X0_INT_I2C 18
+#define PXA2X0_INT_ICP 19
+#define PXA2X0_INT_STUART 20
+#define PXA2X0_INT_BTUART 21
+#define PXA2X0_INT_FFUART 22
+#define PXA2X0_INT_MMC 23
+#define PXA2X0_INT_SSP 24
+#define PXA2X0_INT_DMA 25
+#define PXA2X0_INT_OST0 26
+#define PXA2X0_INT_OST1 27
+#define PXA2X0_INT_OST2 28
+#define PXA2X0_INT_OST3 29
+#define PXA2X0_INT_RTCHZ 30
+#define PXA2X0_INT_ALARM 31 /* RTC Alarm interrupt */
+
+/* DMAC */
+#define DMAC_N_CHANNELS 16
+#define DMAC_N_PRIORITIES 3
+
+#define DMAC_DCSR(n) ((n)*4)
+#define DCSR_BUSERRINTR (1<<0) /* bus error interrupt */
+#define DCSR_STARTINR (1<<1) /* start interrupt */
+#define DCSR_ENDINTR (1<<2) /* end interrupt */
+#define DCSR_STOPSTATE (1<<3) /* channel is not running */
+#define DCSR_REQPEND (1<<8) /* request pending */
+#define DCSR_STOPIRQEN (1<<29) /* stop interrupt enable */
+#define DCSR_NODESCFETCH (1<<30) /* no-descriptor fetch mode */
+#define DCSR_RUN (1<<31)
+#define DMAC_DINT 0x00f0 /* DAM interrupt */
+#define DMAC_DINT_MASK 0xffffu
+#define DMAC_DRCMR(n) (0x100+(n)*4) /* Channel map register */
+#define DRCMR_CHLNUM 0x0f /* channel number */
+#define DRCMR_MAPVLD (1<<7) /* map valid */
+#define DMAC_DDADR(n) (0x0200+(n)*16)
+#define DDADR_STOP (1<<0)
+#define DMAC_DSADR(n) (0x0204+(n)*16)
+#define DMAC_DTADR(n) (0x0208+(n)*16)
+#define DMAC_DCMD(n) (0x020c+(n)*16)
+#define DCMD_LENGTH_MASK 0x1fff
+#define DCMD_WIDTH_SHIFT 14
+#define DCMD_WIDTH_0 (0<<DCMD_WIDTH_SHIFT) /* for mem-to-mem transfer*/
+#define DCMD_WIDTH_1 (1<<DCMD_WIDTH_SHIFT)
+#define DCMD_WIDTH_2 (2<<DCMD_WIDTH_SHIFT)
+#define DCMD_WIDTH_4 (3<<DCMD_WIDTH_SHIFT)
+#define DCMD_SIZE_SHIFT 16
+#define DCMD_SIZE_8 (1<<DCMD_SIZE_SHIFT)
+#define DCMD_SIZE_16 (2<<DCMD_SIZE_SHIFT)
+#define DCMD_SIZE_32 (3<<DCMD_SIZE_SHIFT)
+#define DCMD_LITTLE_ENDIEN (0<<18)
+#define DCMD_ENDIRQEN (1<<21)
+#define DCMD_STARTIRQEN (1<<22)
+#define DCMD_FLOWTRG (1<<28) /* flow control by target */
+#define DCMD_FLOWSRC (1<<29) /* flow control by source */
+#define DCMD_INCTRGADDR (1<<30) /* increment target address */
+#define DCMD_INCSRCADDR (1<<31) /* increment source address */
+
+#ifndef __ASSEMBLER__
+/* DMA descriptor */
+struct pxa2x0_dma_desc {
+ volatile uint32_t dd_ddadr;
+#define DMAC_DESC_LAST 0x1
+ volatile uint32_t dd_dsadr;
+ volatile uint32_t dd_dtadr;
+ volatile uint32_t dd_dcmd; /* command and length */
+};
+#endif
+
+/* UART */
+#define PXA2X0_COM_FREQ 14745600L
+
+/* I2C */
+#define I2C_IBMR 0x1680 /* Bus monitor register */
+#define I2C_IDBR 0x1688 /* Data buffer */
+#define I2C_ICR 0x1690 /* Control register */
+#define ICR_START (1<<0)
+#define ICR_STOP (1<<1)
+#define ICR_ACKNAK (1<<2)
+#define ICR_TB (1<<3)
+#define ICR_MA (1<<4)
+#define I2C_ISR 0x1698 /* Status register */
+#define I2C_ISAR 0x16a0 /* Slave address */
+
+/* Clock Manager */
+#define CLKMAN_CCCR 0x00 /* Core Clock Configuration */
+#define CCCR_TURBO_X1 (2<<7)
+#define CCCR_TURBO_X15 (3<<7) /* x 1.5 */
+#define CCCR_TURBO_X2 (4<<7)
+#define CCCR_TURBO_X25 (5<<7) /* x 2.5 */
+#define CCCR_TURBO_X3 (6<<7) /* x 3.0 */
+#define CCCR_RUN_X1 (1<<5)
+#define CCCR_RUN_X2 (2<<5)
+#define CCCR_RUN_X4 (3<<5)
+#define CCCR_MEM_X27 (1<<0) /* x27, 99.53MHz */
+#define CCCR_MEM_X32 (2<<0) /* x32, 117,96MHz */
+#define CCCR_MEM_X36 (3<<0) /* x26, 132.71MHz */
+#define CCCR_MEM_X40 (4<<0) /* x27, 99.53MHz */
+#define CCCR_MEM_X45 (5<<0) /* x27, 99.53MHz */
+#define CCCR_MEM_X9 (0x1f<<0) /* x9, 33.2MHz */
+
+#define CLKMAN_CKEN 0x04 /* Clock Enable Register */
+#define CLKMAN_OSCC 0x08 /* Osillcator Configuration Register */
+
+#define CCCR_N_SHIFT 7
+#define CCCR_N_MASK (0x07<<CCCR_N_SHIFT)
+#define CCCR_M_SHIFT 5
+#define CCCR_M_MASK (0x03<<CCCR_M_SHIFT)
+#define CCCR_L_MASK 0x1f
+
+#define CKEN_PWM0 (1<<0)
+#define CKEN_PWM1 (1<<1)
+#define CKEN_AC97 (1<<2)
+#define CKEN_SSP (1<<3)
+#define CKEN_STUART (1<<5)
+#define CKEN_FFUART (1<<6)
+#define CKEN_BTUART (1<<7)
+#define CKEN_I2S (1<<8)
+#define CKEN_USB (1<<11)
+#define CKEN_MMC (1<<12)
+#define CKEN_FICP (1<<13)
+#define CKEN_I2C (1<<14)
+#define CKEN_LCD (1<<16)
+
+#define OSCC_OOK (1<<0) /* 32.768KHz oscillator status */
+#define OSCC_OON (1<<1) /* 32.768KHz oscillator */
+
+/*
+ * RTC
+ */
+#define RTC_RCNR 0x0000 /* count register */
+#define RTC_RTAR 0x0004 /* alarm register */
+#define RTC_RTSR 0x0008 /* status register */
+#define RTC_RTTR 0x000c /* trim register */
+/*
+ * GPIO
+ */
+#define GPIO_GPLR0 0x00 /* Level reg [31:0] */
+#define GPIO_GPLR1 0x04 /* Level reg [63:32] */
+#define GPIO_GPLR2 0x08 /* Level reg [80:64] */
+
+#define GPIO_GPDR0 0x0c /* dir reg [31:0] */
+#define GPIO_GPDR1 0x10 /* dir reg [63:32] */
+#define GPIO_GPDR2 0x14 /* dir reg [80:64] */
+
+#define GPIO_GPSR0 0x18 /* set reg [31:0] */
+#define GPIO_GPSR1 0x1c /* set reg [63:32] */
+#define GPIO_GPSR2 0x20 /* set reg [80:64] */
+
+#define GPIO_GPCR0 0x24 /* clear reg [31:0] */
+#define GPIO_GPCR1 0x28 /* clear reg [63:32] */
+#define GPIO_GPCR2 0x2c /* clear reg [80:64] */
+
+#define GPIO_GPER0 0x30 /* rising edge [31:0] */
+#define GPIO_GPER1 0x34 /* rising edge [63:32] */
+#define GPIO_GPER2 0x38 /* rising edge [80:64] */
+
+#define GPIO_GRER0 0x30 /* rising edge [31:0] */
+#define GPIO_GRER1 0x34 /* rising edge [63:32] */
+#define GPIO_GRER2 0x38 /* rising edge [80:64] */
+
+#define GPIO_GFER0 0x3c /* falling edge [31:0] */
+#define GPIO_GFER1 0x40 /* falling edge [63:32] */
+#define GPIO_GFER2 0x44 /* falling edge [80:64] */
+
+#define GPIO_GEDR0 0x48 /* edge detect [31:0] */
+#define GPIO_GEDR1 0x4c /* edge detect [63:32] */
+#define GPIO_GEDR2 0x50 /* edge detect [80:64] */
+
+#define GPIO_GAFR0_L 0x54 /* alternate function [15:0] */
+#define GPIO_GAFR0_U 0x58 /* alternate function [31:16] */
+#define GPIO_GAFR1_L 0x5c /* alternate function [47:32] */
+#define GPIO_GAFR1_U 0x60 /* alternate function [63:48] */
+#define GPIO_GAFR2_L 0x64 /* alternate function [79:64] */
+#define GPIO_GAFR2_U 0x68 /* alternate function [80] */
+
+#define GPIO_REG(r, pin) ((r) + (((pin) / 32) * 4))
+#define GPIO_BANK(pin) ((pin) / 32)
+#define GPIO_BIT(pin) (1u << ((pin) & 0x1f))
+#define GPIO_FN_REG(pin) (GPIO_GAFR0_L + (((pin) / 16) * 4))
+#define GPIO_FN_SHIFT(pin) ((pin & 0xf) * 2)
+
+#define GPIO_IN 0x00 /* Regular GPIO input pin */
+#define GPIO_OUT 0x10 /* Regular GPIO output pin */
+#define GPIO_ALT_FN_1_IN 0x01 /* Alternate function 1 input */
+#define GPIO_ALT_FN_1_OUT 0x11 /* Alternate function 1 output */
+#define GPIO_ALT_FN_2_IN 0x02 /* Alternate function 2 input */
+#define GPIO_ALT_FN_2_OUT 0x12 /* Alternate function 2 output */
+#define GPIO_ALT_FN_3_IN 0x03 /* Alternate function 3 input */
+#define GPIO_ALT_FN_3_OUT 0x13 /* Alternate function 3 output */
+#define GPIO_SET 0x20 /* Initial state is Set */
+#define GPIO_CLR 0x00 /* Initial state is Clear */
+
+#define GPIO_FN_MASK 0x03
+#define GPIO_FN_IS_OUT(n) ((n) & GPIO_OUT)
+#define GPIO_FN_IS_SET(n) ((n) & GPIO_SET)
+#define GPIO_FN(n) ((n) & GPIO_FN_MASK)
+#define GPIO_IS_GPIO(n) (GPIO_FN(n) == 0)
+#define GPIO_IS_GPIO_IN(n) (((n) & (GPIO_FN_MASK|GPIO_OUT)) == GPIO_IN)
+#define GPIO_IS_GPIO_OUT(n) (((n) & (GPIO_FN_MASK|GPIO_OUT)) == GPIO_OUT)
+
+#define GPIO_NPINS 85
+
+/*
+ * memory controller
+ */
+
+#define MEMCTL_MDCNFG 0x0000
+#define MDCNFG_DE0 (1<<0)
+#define MDCNFG_DE1 (1<<1)
+#define MDCNFD_DWID01_SHIFT 2
+#define MDCNFD_DCAC01_SHIFT 3
+#define MDCNFD_DRAC01_SHIFT 5
+#define MDCNFD_DNB01_SHIFT 7
+#define MDCNFG_DE2 (1<<16)
+#define MDCNFG_DE3 (1<<17)
+#define MDCNFD_DWID23_SHIFT 18
+#define MDCNFD_DCAC23_SHIFT 19
+#define MDCNFD_DRAC23_SHIFT 21
+#define MDCNFD_DNB23_SHIFT 23
+
+#define MDCNFD_DWID_MASK 0x1
+#define MDCNFD_DCAC_MASK 0x3
+#define MDCNFD_DRAC_MASK 0x3
+#define MDCNFD_DNB_MASK 0x1
+
+#define MEMCTL_MDREFR 0x04 /* refresh control register */
+#define MDREFR_DRI 0xfff
+#define MDREFR_E0PIN (1<<12)
+#define MDREFR_K0RUN (1<<13) /* SDCLK0 enable */
+#define MDREFR_K0DB2 (1<<14) /* SDCLK0 1/2 freq */
+#define MDREFR_E1PIN (1<<15)
+#define MDREFR_K1RUN (1<<16) /* SDCLK1 enable */
+#define MDREFR_K1DB2 (1<<17) /* SDCLK1 1/2 freq */
+#define MDREFR_K2RUN (1<<18) /* SDCLK2 enable */
+#define MDREFR_K2DB2 (1<<19) /* SDCLK2 1/2 freq */
+#define MDREFR_APD (1<<20) /* Auto Power Down */
+#define MDREFR_SLFRSH (1<<22) /* Self Refresh */
+#define MDREFR_K0FREE (1<<23) /* SDCLK0 free run */
+#define MDREFR_K1FREE (1<<24) /* SDCLK1 free run */
+#define MDREFR_K2FREE (1<<25) /* SDCLK2 free run */
+
+#define MEMCTL_MSC0 0x08 /* Asychronous Statis memory Control CS[01] */
+#define MEMCTL_MSC1 0x0c /* Asychronous Statis memory Control CS[23] */
+#define MEMCTL_MSC2 0x10 /* Asychronous Statis memory Control CS[45] */
+#define MSC_RBUFF_SHIFT 15 /* return data buffer */
+#define MSC_RBUFF (1<<MSC_RBUFF_SHIFT)
+#define MSC_RRR_SHIFT 12 /* recovery time */
+#define MSC_RRR (7<<MSC_RRR_SHIFT)
+#define MSC_RDN_SHIFT 8 /* ROM delay next access */
+#define MSC_RDN (0x0f<<MSC_RDN_SHIFT)
+#define MSC_RDF_SHIFT 4 /* ROM delay first access*/
+#define MSC_RDF (0x0f<<MSC_RDF_SHIFT)
+#define MSC_RBW_SHIFT 3 /* 32/16 bit bus */
+#define MSC_RBW (1<<MSC_RBW_SHIFT)
+#define MSC_RT_SHIFT 0 /* type */
+#define MSC_RT (7<<MSC_RT_SHIFT)
+#define MSC_RT_NONBURST 0
+#define MSC_RT_SRAM 1
+#define MSC_RT_BURST4 2
+#define MSC_RT_BURST8 3
+#define MSC_RT_VLIO 4
+
+/* expansion memory timing configuration */
+#define MEMCTL_MCMEM(n) (0x28+4*(n))
+#define MEMCTL_MCATT(n) (0x30+4*(n))
+#define MEMCTL_MCIO(n) (0x38+4*(n))
+
+#define MC_HOLD_SHIFT 14
+#define MC_ASST_SHIFT 7
+#define MC_SET_SHIFT 0
+#define MC_TIMING_VAL(hold,asst,set) (((hold)<<MC_HOLD_SHIFT)| \
+ ((asst)<<MC_ASST_SHIFT)|((set)<<MC_SET_SHIFT))
+
+#define MEMCTL_MECR 0x14 /* Expansion memory configuration */
+#define MECR_NOS (1<<0) /* Number of sockets */
+#define MECR_CIT (1<<1) /* Card-is-there */
+
+#define MEMCTL_MDMRS 0x0040
+
+/*
+ * LCD Controller
+ */
+#define LCDC_LCCR0 0x000 /* Controller Control Register 0 */
+#define LCCR0_ENB (1U<<0) /* LCD Controller Enable */
+#define LCCR0_CMS (1U<<1) /* Color/Mono select */
+#define LCCR0_SDS (1U<<2) /* Single/Dual -panel */
+#define LCCR0_LDM (1U<<3) /* LCD Disable Done Mask */
+#define LCCR0_SFM (1U<<4) /* Start of Frame Mask */
+#define LCCR0_IUM (1U<<5) /* Input FIFO Underrun Mask */
+#define LCCR0_EFM (1U<<6) /* End of Frame Mask */
+#define LCCR0_PAS (1U<<7) /* Passive/Active Display select */
+#define LCCR0_DPD (1U<<9) /* Double-Pixel Data pin mode */
+#define LCCR0_DIS (1U<<10) /* LCD Disable */
+#define LCCR0_QDM (1U<<11) /* LCD Quick Disable Mask */
+#define LCCR0_BM (1U<<20) /* Branch Mask */
+#define LCCR0_OUM (1U<<21) /* Output FIFO Underrun Mask */
+
+#define LCCR0_IMASK (LCCR0_LDM|LCCR0_SFM|LCCR0_IUM|LCCR0_EFM|LCCR0_QDM|LCCR0_BM|LCCR0_OUM)
+
+
+#define LCDC_LCCR1 0x004 /* Controller Control Register 1 */
+#define LCDC_LCCR2 0x008 /* Controller Control Register 2 */
+#define LCDC_LCCR3 0x00c /* Controller Control Register 2 */
+#define LCCR3_BPP_SHIFT 24 /* Bits per pixel */
+#define LCCR3_BPP (0x07<<LCCR3_BPP_SHIFT)
+#define LCDC_FBR0 0x020 /* DMA ch0 frame branch register */
+#define LCDC_FBR1 0x024 /* DMA ch1 frame branch register */
+#define LCDC_LCSR 0x038 /* controller status register */
+#define LCSR_LDD (1U<<0) /* LCD disable done */
+#define LCSR_SOF (1U<<1) /* Start of frame */
+#define LCDC_LIIDR 0x03c /* controller interrupt ID Register */
+#define LCDC_TRGBR 0x040 /* TMED RGB Speed Register */
+#define LCDC_TCR 0x044 /* TMED Control Register */
+#define LCDC_FDADR0 0x200 /* DMA ch0 frame descriptor address */
+#define LCDC_FSADR0 0x204 /* DMA ch0 frame source address */
+#define LCDC_FIDR0 0x208 /* DMA ch0 frame ID register */
+#define LCDC_LDCMD0 0x20c /* DMA ch0 command register */
+#define LCDC_FDADR1 0x210 /* DMA ch1 frame descriptor address */
+#define LCDC_FSADR1 0x214 /* DMA ch1 frame source address */
+#define LCDC_FIDR1 0x218 /* DMA ch1 frame ID register */
+#define LCDC_LDCMD1 0x21c /* DMA ch1 command register */
+
+/*
+ * MMC/SD controller
+ */
+#define MMC_STRPCL 0x00 /* start/stop MMC clock */
+#define STRPCL_NOOP 0
+#define STRPCL_STOP 1 /* stop MMC clock */
+#define STRPCL_START 2 /* start MMC clock */
+#define MMC_STAT 0x04 /* status register */
+#define STAT_READ_TIME_OUT (1<<0)
+#define STAT_TIMEOUT_RESPONSE (1<<1)
+#define STAT_CRC_WRITE_ERROR (1<<2)
+#define STAT_CRC_READ_ERROR (1<<3)
+#define STAT_SPI_READ_ERROR_TOKEN (1<<4)
+#define STAT_RES_CRC_ERR (1<<5)
+#define STAT_XMIT_FIFO_EMPTY (1<<6)
+#define STAT_RECV_FIFO_FULL (1<<7)
+#define STAT_CLK_EN (1<<8)
+#define STAT_DATA_TRAN_DONE (1<<11)
+#define STAT_PRG_DONE (1<<12)
+#define STAT_END_CMD_RES (1<<13)
+#define MMC_CLKRT 0x08 /* MMC clock rate */
+#define CLKRT_20M 0
+#define CLKRT_10M 1
+#define CLKRT_5M 2
+#define CLKRT_2_5M 3
+#define CLKRT_1_25M 4
+#define CLKRT_625K 5
+#define CLKRT_312K 6
+#define MMC_SPI 0x0c /* SPI mode control */
+#define SPI_EN (1<<0) /* enable SPI mode */
+#define SPI_CRC_ON (1<<1) /* enable CRC generation */
+#define SPI_CS_EN (1<<2) /* Enable CS[01] */
+#define SPI_CS_ADDRESS (1<<3) /* CS0/CS1 */
+#define MMC_CMDAT 0x10 /* command/response/data */
+#define CMDAT_RESPONSE_FORMAT 0x03
+#define CMDAT_RESPONSE_FORMAT_NO 0 /* no response */
+#define CMDAT_RESPONSE_FORMAT_R1 1 /* R1, R1b, R4, R5 */
+#define CMDAT_RESPONSE_FORMAT_R2 2
+#define CMDAT_RESPONSE_FORMAT_R3 3
+#define CMDAT_DATA_EN (1<<2)
+#define CMDAT_WRITE (1<<3) /* 1=write 0=read operation */
+#define CMDAT_STREAM_BLOCK (1<<4) /* stream mode */
+#define CMDAT_BUSY (1<<5) /* busy signal is expected */
+#define CMDAT_INIT (1<<6) /* preceede command with 80 clocks */
+#define CMDAT_MMC_DMA_EN (1<<7) /* DMA enable */
+#define MMC_RESTO 0x14 /* expected response time out */
+#define MMC_RDTO 0x18 /* expected data read time out */
+#define MMC_BLKLEN 0x1c /* block length of data transaction */
+#define MMC_NOB 0x20 /* number of blocks (block mode) */
+#define MMC_PRTBUF 0x24 /* partial MMC_TXFIFO written */
+#define PRTBUF_BUF_PART_FULL (1<<0) /* buffer partially full */
+#define MMC_I_MASK 0x28 /* interrupt mask */
+#define MMC_I_REG 0x2c /* interrupt register */
+#define MMC_I_DATA_TRAN_DONE (1<<0)
+#define MMC_I_PRG_DONE (1<<1)
+#define MMC_I_END_CMD_RES (1<<2)
+#define MMC_I_STOP_CMD (1<<3)
+#define MMC_I_CLK_IS_OFF (1<<4)
+#define MMC_I_RXFIFO_RD_REQ (1<<5)
+#define MMC_I_TXFIFO_WR_REQ (1<<6)
+#define MMC_CMD 0x30 /* index of current command */
+#define MMC_ARGH 0x34 /* MSW part of the current command arg */
+#define MMC_ARGL 0x38 /* LSW part of the current command arg */
+#define MMC_RES 0x3c /* response FIFO */
+#define MMC_RXFIFO 0x40 /* receive FIFO */
+#define MMC_TXFIFO 0x44 /* transmit FIFO */
+
+/*
+ * AC97
+ */
+#define AC97_N_CODECS 2
+#define AC97_GCR 0x000c /* Global control register */
+#define GCR_GIE (1<<0) /* interrupt enable */
+#define GCR_COLD_RST (1<<1)
+#define GCR_WARM_RST (1<<2)
+#define GCR_ACLINK_OFF (1<<3)
+#define GCR_PRIRES_IEN (1<<4) /* Primary resume interrupt enable */
+#define GCR_SECRES_IEN (1<<5) /* Secondary resume interrupt enable */
+#define GCR_PRIRDY_IEN (1<<8) /* Primary ready interrupt enable */
+#define GCR_SECRDY_IEN (1<<9) /* Primary ready interrupt enable */
+#define GCR_SDONE_IE (1<<18) /* Status done interrupt enable */
+#define GCR_CDONE_IE (1<<19) /* Command done interrupt enable */
+
+#define AC97_GSR 0x001c /* Global status register */
+#define GSR_GSCI (1<<0) /* codec GPI status change interrupt */
+#define GSR_MIINT (1<<1) /* modem in interrupt */
+#define GSR_MOINT (1<<2) /* modem out interrupt */
+#define GSR_PIINT (1<<5) /* PCM in interrupt */
+#define GSR_POINT (1<<6) /* PCM out interrupt */
+#define GSR_MINT (1<<7) /* Mic in interrupt */
+#define GSR_PCR (1<<8) /* primary code ready */
+#define GSR_SCR (1<<9) /* secondary code ready */
+#define GSR_PRIRES (1<<10) /* primary resume interrupt */
+#define GSR_SECRES (1<<11) /* secondary resume interrupt */
+#define GSR_BIT1SLT12 (1<<12) /* Bit 1 of slot 12 */
+#define GSR_BIT2SLT12 (1<<13) /* Bit 2 of slot 12 */
+#define GSR_BIT3SLT12 (1<<14) /* Bit 3 of slot 12 */
+#define GSR_RDCS (1<<15) /* Read completion status */
+#define GSR_SDONE (1<<18) /* status done */
+#define GSR_CDONE (1<<19) /* command done */
+
+#define AC97_POCR 0x0000 /* PCM-out control */
+#define AC97_PICR 0x0004 /* PCM-in control */
+#define AC97_POSR 0x0010 /* PCM-out status */
+#define AC97_PISR 0x0014 /* PCM-out status */
+#define AC97_MCCR 0x0008 /* MIC-in control register */
+#define AC97_MCSR 0x0018 /* MIC-in status register */
+#define AC97_MICR 0x0100 /* Modem-in control register */
+#define AC97_MISR 0x0108 /* Modem-in status register */
+#define AC97_MOCR 0x0110 /* Modem-out control register */
+#define AC97_MOSR 0x0118 /* Modem-out status register */
+#define AC97_FEFIE (1<<3) /* fifo error interrupt enable */
+#define AC97_FIFOE (1<<4) /* fifo error */
+
+#define AC97_CAR 0x0020 /* Codec access register */
+#define CAR_CAIP (1<<0) /* Codec access in progress */
+
+#define AC97_PCDR 0x0040 /* PCM data register */
+#define AC97_MCDR 0x0060 /* MIC-in data register */
+#define AC97_MODR 0x0140 /* Modem data register */
+
+/* address to access codec registers */
+#define AC97_PRIAUDIO 0x0200 /* Primary audio codec */
+#define AC97_SECAUDIO 0x0300 /* Secondary autio codec */
+#define AC97_PRIMODEM 0x0400 /* Primary modem codec */
+#define AC97_SECMODEM 0x0500 /* Secondary modem codec */
+#define AC97_CODEC_BASE(c) (AC97_PRIAUDIO + ((c) * 0x100))
+
+/*
+ * USB device controller
+ */
+#define USBDC_UDCCR 0x0000 /* UDC control register */
+#define USBDC_UDCCS(n) (0x0010+4*(n)) /* Endpoint Control/Status Registers */
+#define USBDC_UICR0 0x0050 /* UDC Interrupt Control Register 0 */
+#define USBDC_UICR1 0x0054 /* UDC Interrupt Control Register 1 */
+#define USBDC_USIR0 0x0058 /* UDC Status Interrupt Register 0 */
+#define USBDC_USIR1 0x005C /* UDC Status Interrupt Register 1 */
+#define USBDC_UFNHR 0x0060 /* UDC Frame Number Register High */
+#define USBDC_UFNLR 0x0064 /* UDC Frame Number Register Low */
+#define USBDC_UBCR2 0x0068 /* UDC Byte Count Register 2 */
+#define USBDC_UBCR4 0x006C /* UDC Byte Count Register 4 */
+#define USBDC_UBCR7 0x0070 /* UDC Byte Count Register 7 */
+#define USBDC_UBCR9 0x0074 /* UDC Byte Count Register 9 */
+#define USBDC_UBCR12 0x0078 /* UDC Byte Count Register 12 */
+#define USBDC_UBCR14 0x007C /* UDC Byte Count Register 14 */
+#define USBDC_UDDR0 0x0080 /* UDC Endpoint 0 Data Register */
+#define USBDC_UDDR1 0x0100 /* UDC Endpoint 1 Data Register */
+#define USBDC_UDDR2 0x0180 /* UDC Endpoint 2 Data Register */
+#define USBDC_UDDR3 0x0200 /* UDC Endpoint 3 Data Register */
+#define USBDC_UDDR4 0x0400 /* UDC Endpoint 4 Data Register */
+#define USBDC_UDDR5 0x00A0 /* UDC Endpoint 5 Data Register */
+#define USBDC_UDDR6 0x0600 /* UDC Endpoint 6 Data Register */
+#define USBDC_UDDR7 0x0680 /* UDC Endpoint 7 Data Register */
+#define USBDC_UDDR8 0x0700 /* UDC Endpoint 8 Data Register */
+#define USBDC_UDDR9 0x0900 /* UDC Endpoint 9 Data Register */
+#define USBDC_UDDR10 0x00C0 /* UDC Endpoint 10 Data Register */
+#define USBDC_UDDR11 0x0B00 /* UDC Endpoint 11 Data Register */
+#define USBDC_UDDR12 0x0B80 /* UDC Endpoint 12 Data Register */
+#define USBDC_UDDR13 0x0C00 /* UDC Endpoint 13 Data Register */
+#define USBDC_UDDR14 0x0E00 /* UDC Endpoint 14 Data Register */
+#define USBDC_UDDR15 0x00E0 /* UDC Endpoint 15 Data Register */
+#endif /* _ARM_XSCALE_PXA2X0REG_H_ */
diff --git a/sys/arch/arm/xscale/pxa2x0var.h b/sys/arch/arm/xscale/pxa2x0var.h
new file mode 100644
index 00000000000..b4daaf821d3
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0var.h
@@ -0,0 +1,89 @@
+/* $NetBSD: pxa2x0var.h,v 1.2 2003/06/05 13:48:28 scw Exp $ */
+
+/*
+ * Copyright (c) 2002 Genetec Corporation. All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef _ARM_XSCALE_PXA2X0VAR_H_
+#define _ARM_XSCALE_PXA2X0VAR_H_
+
+#include <arm/sa11x0/sa11x0_var.h>
+
+/* PXA2X0's integrated peripheral bus. */
+
+typedef int (* pxa2x0_irq_handler_t)(void *);
+
+struct pxaip_attach_args {
+ struct sa11x0_attach_args pxa_sa;
+ bus_dma_tag_t pxa_dmat;
+ int pxa_index; /* to specify device by index number */
+
+#define pxa_iot pxa_sa.sa_iot
+#define pxa_addr pxa_sa.sa_addr
+#define pxa_size pxa_sa.sa_size
+#define pxa_intr pxa_sa.sa_intr
+};
+
+#define cf_addr cf_loc[0]
+#define cf_size cf_loc[1]
+#define cf_intr cf_loc[2]
+#define cf_index cf_loc[3]
+
+
+extern struct bus_space pxa2x0_bs_tag;
+extern struct arm32_bus_dma_tag pxa2x0_bus_dma_tag;
+extern struct bus_space pxa2x0_a4x_bs_tag;
+
+/* misc. */
+extern void pxa2x0_fcs_init(void);
+extern void pxa2x0_freq_change(int);
+extern void pxa2x0_turbo_mode(int);
+extern int pxa2x0_i2c_master_tx( int, uint8_t *, int );
+
+/*
+ * Probe the memory controller to deterimine which SDRAM are
+ * populated, and what size of SDRAM is present in each bank.
+ *
+ * This routine should be called from a port's initarm()
+ * function, with the first parameter set to the address
+ * of the memory controller's registers.
+ */
+extern void pxa2x0_probe_sdram(vaddr_t, paddr_t *, psize_t *);
+
+/*
+ * Configure one or more clock enables in the Clock Manager's
+ * CKEN register.
+ */
+extern void pxa2x0_clkman_config(u_int, int);
+
+#endif /* _ARM_XSCALE_PXA2X0VAR_H_ */
diff --git a/sys/arch/arm/xscale/pxapcicvar.h b/sys/arch/arm/xscale/pxapcicvar.h
new file mode 100644
index 00000000000..fadc3fdf4a4
--- /dev/null
+++ b/sys/arch/arm/xscale/pxapcicvar.h
@@ -0,0 +1,87 @@
+struct pxapcic_socket {
+ struct pxapcic_softc *sc;
+ int socket; /* socket number */
+ struct device *pcmcia;
+ /*
+ struct pxapcic_tag *pcictag;
+ */
+
+ int flags;
+
+ int power_capability;
+
+ void *pcictag_cookie; /* opaque data for pcictag functions */
+};
+
+/* event */
+#define PXAPCIC_EVENT_INSERTION 0
+#define PXAPCIC_EVENT_REMOVAL 1
+
+/* laststatus */
+#define PXAPCIC_FLAG_CARDD 0
+#define PXAPCIC_FLAG_CARDP 1
+
+struct pxapcic_tag {
+ int (*read)(struct pxapcic_socket *, int);
+ void (*write)(struct pxapcic_socket *, int, int);
+ void (*set_power)(struct pxapcic_socket *, int);
+ void (*clear_intr)(int);
+ void *(*intr_establish)(struct pxapcic_socket *, int,
+ int (*)(void *), void *);
+ void (*intr_disestablish)(struct pxapcic_socket *, void *);
+};
+
+
+struct pxapcic_softc {
+ struct device sc_dev;
+ struct pxapcic_socket sc_socket[2];
+
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_scooph;
+
+ struct proc *sc_event_thread;
+ void *sc_irq;
+ int sc_gpio;
+ int sc_shutdown;
+};
+
+
+#define SCOOP_REG_MCR 0x00
+#define SCOOP_REG_CDR 0x04
+#define SCOOP_REG_CSR 0x08
+#define SCOOP_REG_CPR 0x0C
+#define SCOOP_REG_CCR 0x10
+#define SCOOP_REG_IRR 0x14
+#define SCOOP_REG_IRM 0x14
+#define SCOOP_REG_IMR 0x18
+#define SCOOP_REG_ISR 0x1C
+#define SCOOP_REG_GPCR 0x20
+#define SCOOP_REG_GPWR 0x24
+#define SCOOP_REG_GPRR 0x28
+
+#define SCP_CDR_DETECT 0x0002
+
+#define SCP_CSR_READY 0x0002
+#define SCP_CSR_MISSING 0x0004
+#define SCP_CSR_WPROT 0x0008
+#define SCP_CSR_BVD1 0x0010
+#define SCP_CSR_BVD2 0x0020
+#define SCP_CSR_3V 0x0040
+#define SCP_CSR_PWR 0x0080
+
+#define SCP_CPR_OFF 0x0000
+#define SCP_CPR_3V 0x0001
+#define SCP_CPR_5V 0x0002
+#define SCP_CPR_PWR 0x0080
+
+
+#define SCP_MCR_IOCARD 0x0010
+#define SCP_CCR_RESET 0x0080
+
+#define SCP_IMR_READY 0x0002
+#define SCP_IMR_DETECT 0x0004
+#define SCP_IMR_WRPROT 0x0008
+#define SCP_IMR_STSCHG 0x0010
+#define SCP_IMR_BATWARN 0x0020
+#define SCP_IMR_UNKN0 0x0040
+#define SCP_IMR_UNKN1 0x0080