summaryrefslogtreecommitdiffstats
path: root/utils/hwstub/stub
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2013-07-18 23:55:35 +0200
committerMarcin Bukat <marcin.bukat@gmail.com>2013-11-24 00:10:36 +0100
commit8e633385912494ff5e871ec4c264d3a7db46fb98 (patch)
treea8d6b23861969b7df72bb79695ad742082ce2b02 /utils/hwstub/stub
parent1ed57aaa5049d2bbe4e94bed6674bd405e98a4a5 (diff)
downloadrockbox-8e633385912494ff5e871ec4c264d3a7db46fb98.tar.gz
rockbox-8e633385912494ff5e871ec4c264d3a7db46fb98.tar.bz2
rockbox-8e633385912494ff5e871ec4c264d3a7db46fb98.zip
hwstub rk27xx port
Change-Id: I85ac57117911544b65ccd56eb16303e30be67cab
Diffstat (limited to 'utils/hwstub/stub')
-rw-r--r--utils/hwstub/stub/SOURCES8
-rw-r--r--utils/hwstub/stub/hwstub.make4
-rw-r--r--utils/hwstub/stub/rk27xx/Makefile14
-rw-r--r--utils/hwstub/stub/rk27xx/convert_to_rkw.txt2
-rw-r--r--utils/hwstub/stub/rk27xx/crt0.S164
-rw-r--r--utils/hwstub/stub/rk27xx/hwstub.lds88
-rw-r--r--utils/hwstub/stub/rk27xx/rk27xx.h1158
-rw-r--r--utils/hwstub/stub/rk27xx/target-config.h9
-rw-r--r--utils/hwstub/stub/rk27xx/target.c172
-rw-r--r--utils/hwstub/stub/rk27xx/usb_drv_rk27xx.c313
-rw-r--r--utils/hwstub/stub/stmp/crt0.S (renamed from utils/hwstub/stub/crt0.S)0
-rw-r--r--utils/hwstub/stub/stmp/hwstub.lds (renamed from utils/hwstub/stub/hwstub.lds)2
12 files changed, 1929 insertions, 5 deletions
diff --git a/utils/hwstub/stub/SOURCES b/utils/hwstub/stub/SOURCES
index bfb847c21b..fb87d64ccd 100644
--- a/utils/hwstub/stub/SOURCES
+++ b/utils/hwstub/stub/SOURCES
@@ -1,5 +1,4 @@
main.c
-crt0.S
logf.c
memcpy.S
memmove.S
@@ -7,6 +6,11 @@ memset.S
string.c
format.c
#ifdef CONFIG_STMP
-usb_drv_arc.c
+stmp/crt0.S
stmp/target.c
+usb_drv_arc.c
+#elif defined(CONFIG_RK27XX)
+rk27xx/crt0.S
+rk27xx/usb_drv_rk27xx.c
+rk27xx/target.c
#endif
diff --git a/utils/hwstub/stub/hwstub.make b/utils/hwstub/stub/hwstub.make
index d40fa87755..c1dd9f0f0f 100644
--- a/utils/hwstub/stub/hwstub.make
+++ b/utils/hwstub/stub/hwstub.make
@@ -1,5 +1,5 @@
INCLUDES+=-I$(ROOT_DIR)
-LINKER_FILE=$(ROOT_DIR)/hwstub.lds
+LINKER_FILE=hwstub.lds
TMP_LDS=$(BUILD_DIR)/link.lds
TMP_MAP=$(BUILD_DIR)/hwstub.map
CFLAGS=$(GCCOPTS) $(DEFINES) -W -Wall -Wundef -O -nostdlib -ffreestanding -Wstrict-prototypes -pipe -std=gnu99 -fomit-frame-pointer -Wno-pointer-sign -Wno-override-init $(INCLUDES)
@@ -12,7 +12,7 @@ SRC:=$(shell cat $(ROOT_DIR)/SOURCES | $(CC) $(INCLUDES) \
SRC:=$(foreach src,$(SRC),$(BUILD_DIR)/$(src))
OBJ=$(SRC:.c=.o)
OBJ:=$(OBJ:.S=.o)
-OBJ_EXCEPT_CRT0=$(filter-out $(BUILD_DIR)/crt0.o,$(OBJ))
+OBJ_EXCEPT_CRT0=$(filter-out $(BUILD_DIR)/%/crt0.o,$(OBJ))
EXEC_ELF=$(BUILD_DIR)/hwstub.elf
EXEC_BIN=$(BUILD_DIR)/hwstub.bin
DEPS=$(foreach obj,$(OBJ),$(obj).d)
diff --git a/utils/hwstub/stub/rk27xx/Makefile b/utils/hwstub/stub/rk27xx/Makefile
new file mode 100644
index 0000000000..937655327c
--- /dev/null
+++ b/utils/hwstub/stub/rk27xx/Makefile
@@ -0,0 +1,14 @@
+#
+# common
+#
+CC=arm-elf-eabi-gcc
+LD=arm-elf-eabi-gcc
+AS=arm-elf-eabi-gcc
+OC=arm-elf-eabi-objcopy
+DEFINES=
+INCLUDES=-I$(CURDIR)
+GCCOPTS=-march=armv5te
+BUILD_DIR=$(CURDIR)/build/
+ROOT_DIR=$(CURDIR)/..
+
+include ../hwstub.make
diff --git a/utils/hwstub/stub/rk27xx/convert_to_rkw.txt b/utils/hwstub/stub/rk27xx/convert_to_rkw.txt
new file mode 100644
index 0000000000..85d0d3cc71
--- /dev/null
+++ b/utils/hwstub/stub/rk27xx/convert_to_rkw.txt
@@ -0,0 +1,2 @@
+/home/wodz/rockbox-dev/bin/arm-elf-eabi-objcopy -O binary hwstub.elf hwstub.bin
+/home/wodz/rockbox/tools/scramble -rkw -modelnum=73 hwstub.bin hwstub.rkw
diff --git a/utils/hwstub/stub/rk27xx/crt0.S b/utils/hwstub/stub/rk27xx/crt0.S
new file mode 100644
index 0000000000..0c702eca91
--- /dev/null
+++ b/utils/hwstub/stub/rk27xx/crt0.S
@@ -0,0 +1,164 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2008 by Marcoen Hirschberg
+ * Copyright (C) 2008 by Denes Balatoni
+ * Copyright (C) 2010 by Marcin Bukat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+ .extern INT_UDC
+
+ .global start
+ .global entry_point
+
+ /* Exception vectors */
+ .section .intvect,"ax",%progbits
+ ldr pc, =start
+ ldr pc, =start
+ ldr pc, =start
+ ldr pc, =start
+ ldr pc, =start
+ ldr pc, =start
+ ldr pc, =irq_handler
+ ldr pc, =start
+ .ltorg
+
+ .section .text,"ax",%progbits
+start:
+ msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
+
+ sub r4, pc, #12 /* copy running address, accomodate
+ * for prefetch (-8) and msr instr (-4)
+ */
+
+ ldr r0, =0xefff0000 /* cache controler base address */
+ ldrh r1, [r0]
+ strh r1, [r0] /* global cache disable */
+
+ ldr r2, =_relocstart
+ ldr r3, =_relocend
+
+ cmp r2, r4
+ beq entry_point /* skip copying if we are in place already */
+1:
+ cmp r3, r2
+ ldrhi r1, [r4], #4
+ strhi r1, [r2], #4
+ bhi 1b
+
+entry_point_jmp:
+ ldr pc, =entry_point
+
+entry_point:
+ mov r0, #0x18000000
+ add r0, r0, #0x1c000
+
+ /* setup ARM core freq = 200MHz
+ * AHB bus freq (HCLK) = 100MHz
+ * APB bus freq (PCLK) = 50MHz
+ * Note: it seems there is no way to run AHB bus at ARM freq
+ * bit2 in DIVCON1 must have different meaning to what datasheet
+ * states. It influences SDRAM read speed but does not change
+ * APB freq
+ */
+ ldr r1, [r0,#0x14] /* SCU_DIVCON1 */
+ bic r1, r1, #0x1f
+ orr r1, r1, #9 /* ((1<<3)|(1<<0)) ARM slow mode, HCLK:PCLK = 2:1 */
+ str r1, [r0,#0x14]
+
+ ldr r1,=0x1850310 /* ((1<<24)|(1<<23)|(5<<16)|(49<<4)) */
+ str r1, [r0,#0x08]
+
+ ldr r2,=0x40000
+1:
+ ldr r1, [r0,#0x2c] /* SCU_STATUS */
+ tst r1, #1 /* ARM pll lock */
+ bne 1f
+ subs r2, r2, #1
+ bne 1b
+1:
+ ldr r1, [r0,#0x14] /* SCU_DIVCON1 */
+ bic r1, #1 /* leave ARM slow mode */
+ str r1, [r0,#0x14]
+
+ /* remap iram to 0x00000000 */
+ ldr r1,=0xdeadbeef
+ str r1, [r0, #4]
+
+ /* Copy interrupt vectors to iram */
+ ldr r2, =_intvectstart
+ ldr r3, =_intvectend
+ ldr r4, =_intvectcopy
+1:
+ cmp r3, r2
+ ldrhi r1, [r4], #4
+ strhi r1, [r2], #4
+ bhi 1b
+
+ /* Initialise bss section to zero */
+ ldr r2, =_edata
+ ldr r3, =_end
+ mov r4, #0
+1:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 1b
+
+ /* Set up stack for IRQ mode */
+ msr cpsr_c, #0xd2
+ ldr sp, =_irqstackend
+
+ /* Set up stack for FIQ mode */
+ msr cpsr_c, #0xd1
+ ldr sp, =_fiqstackend
+
+ /* Let svc, abort and undefined modes use irq stack */
+ msr cpsr_c, #0xd3
+ ldr sp, =_irqstackend
+ msr cpsr_c, #0xd7
+ ldr sp, =_irqstackend
+ msr cpsr_c, #0xdb
+ ldr sp, =_irqstackend
+
+ /* Switch to sys mode */
+ msr cpsr_c, #0xdf
+
+ /* Set up some stack and munge it with 0xdeadbeef */
+ ldr sp, =stackend
+ ldr r2, =stackbegin
+ ldr r3, =0xdeadbeef
+1:
+ cmp sp, r2
+ strhi r3, [r2], #4
+ bhi 1b
+
+ /* Jump to C code */
+ b main
+
+/* copy from rockbox code - context save may be excessive but who cares */
+irq_handler:
+ stmfd sp!, {r0-r5, ip, lr} /* store context */
+ ldr r4, =0x18080000 /* INTC base */
+ ldr r5, [r4, #0x104] /* INTC_ISR */
+ and r5, r5, #0x1f /* irq_no = INTC_ISR & 0x1f */
+ cmp r5, #0x10 /* UDC irq */
+ bleq INT_UDC /* handle it */
+ mov r3, #1
+ lsl r5, r3, r5 /* clear interrupt */
+ str r5, [r4, #0x118] /* INTC_ICCR = (1<<irq_no) */
+ ldmfd sp!, {r0-r5, ip, lr} /* restore context */
+ subs pc, lr, #4
diff --git a/utils/hwstub/stub/rk27xx/hwstub.lds b/utils/hwstub/stub/rk27xx/hwstub.lds
new file mode 100644
index 0000000000..89b2b1961d
--- /dev/null
+++ b/utils/hwstub/stub/rk27xx/hwstub.lds
@@ -0,0 +1,88 @@
+ENTRY(start)
+OUTPUT_FORMAT(elf32-littlearm)
+OUTPUT_ARCH(arm)
+STARTUP(rk27xx/crt0.o)
+
+#define DRAMORIG 0x60000000
+#define DRAMSIZE (16 * 0x100000)
+#define DRAM_END_ADDRESS (DRAMORIG + DRAMSIZE)
+
+#define IRAMORIG 0x00000000
+#define IRAMSIZE 4K
+
+MEMORY
+{
+ DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
+ IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+}
+
+SECTIONS
+{
+ .relocstart (NOLOAD) : {
+ _relocstart = .;
+ } > DRAM
+
+ .text : {
+ oc_codestart = .;
+ *(.init.text)
+ *(.text*)
+ *(.icode*)
+ *(.glue_7*)
+ } > DRAM
+
+ .intvect : {
+ _intvectstart = . ;
+ KEEP(*(.intvect))
+ _intvectend = . ;
+ } > IRAM AT > DRAM
+ _intvectcopy = LOADADDR(.intvect) ;
+
+ .rodata : {
+ *(.rodata*)
+ *(.irodata*)
+ . = ALIGN(0x4);
+ } > DRAM
+
+ .data : {
+ *(.data*)
+ *(.idata*)
+ . = ALIGN(0x4);
+ } > DRAM
+
+ .relocend (NOLOAD) : {
+ _relocend = .;
+ } > DRAM
+
+ .stack (NOLOAD) :
+ {
+ *(.stack)
+ oc_stackstart = .;
+ _stackbegin = .;
+ stackbegin = .;
+ . += 0x2000;
+ _stackend = .;
+ stackend = .;
+ _irqstackbegin = .;
+ . += 0x400;
+ _irqstackend = .;
+ _fiqstackbegin = .;
+ . += 0x400;
+ _fiqstackend = .;
+ oc_stackend = .;
+ } > DRAM
+
+ .bss (NOLOAD) : {
+ _edata = .;
+ *(.bss*);
+ *(.ibss);
+ *(COMMON);
+ . = ALIGN(0x4);
+ _end = .;
+ oc_codeend = .;
+ oc_bufferstart = .;
+ } > DRAM
+
+ .dramend DRAM_END_ADDRESS (NOLOAD) : {
+ oc_bufferend = .;
+ } > DRAM
+}
diff --git a/utils/hwstub/stub/rk27xx/rk27xx.h b/utils/hwstub/stub/rk27xx/rk27xx.h
new file mode 100644
index 0000000000..3c1c34529b
--- /dev/null
+++ b/utils/hwstub/stub/rk27xx/rk27xx.h
@@ -0,0 +1,1158 @@
+/* ARM part only for now */
+#define AHB_SRAM 0x00000000
+
+#define ARM_BUS0_BASE 0x18000000
+#define ARM_BUS1_BASE 0x18400000
+
+#define FLASH_BANK0 0x10000000
+#define FLASH_BANK1 0x11000000
+
+/* Timers */
+#define APB0_TIMER (ARM_BUS0_BASE + 0x00000000)
+#define TMR0LR (*(volatile unsigned long *)(APB0_TIMER + 0x00))
+#define TMR0CVR (*(volatile unsigned long *)(APB0_TIMER + 0x04))
+#define TMR0CON (*(volatile unsigned long *)(APB0_TIMER + 0x08))
+
+#define TMR1LR (*(volatile unsigned long *)(APB0_TIMER + 0x10))
+#define TMR1CVR (*(volatile unsigned long *)(APB0_TIMER + 0x14))
+#define TMR1CON (*(volatile unsigned long *)(APB0_TIMER + 0x18))
+
+#define TMR2LR (*(volatile unsigned long *)(APB0_TIMER + 0x20))
+#define TMR2CVR (*(volatile unsigned long *)(APB0_TIMER + 0x24))
+#define TMR2CON (*(volatile unsigned long *)(APB0_TIMER + 0x28))
+
+/* UART0 */
+#define APB0_UART0 (ARM_BUS0_BASE + 0x00004000)
+#define UART0_RBR (*(volatile unsigned long *)(APB0_UART0 + 0x00))
+#define UART0_THR (*(volatile unsigned long *)(APB0_UART0 + 0x00))
+#define UART0_DLL (*(volatile unsigned long *)(APB0_UART0 + 0x00))
+#define UART0_DLH (*(volatile unsigned long *)(APB0_UART0 + 0x04))
+#define UART0_IER (*(volatile unsigned long *)(APB0_UART0 + 0x04))
+#define UART0_IIR (*(volatile unsigned long *)(APB0_UART0 + 0x08))
+#define UART0_FCR (*(volatile unsigned long *)(APB0_UART0 + 0x08))
+#define UART0_LCR (*(volatile unsigned long *)(APB0_UART0 + 0x0C))
+#define UART0_MCR (*(volatile unsigned long *)(APB0_UART0 + 0x10))
+#define UART0_LSR (*(volatile unsigned long *)(APB0_UART0 + 0x14))
+#define UART0_MSR (*(volatile unsigned long *)(APB0_UART0 + 0x18))
+
+/* UART1 */
+#define APB0_UART1 (ARM_BUS0_BASE + 0x00008000)
+#define UART1_RBR (*(volatile unsigned long *)(APB0_UART1 + 0x00))
+#define UART1_THR (*(volatile unsigned long *)(APB0_UART1 + 0x00))
+#define UART1_DLL (*(volatile unsigned long *)(APB0_UART1 + 0x00))
+#define UART1_DLH (*(volatile unsigned long *)(APB0_UART1 + 0x04))
+#define UART1_IER (*(volatile unsigned long *)(APB0_UART1 + 0x04))
+#define UART1_IIR (*(volatile unsigned long *)(APB0_UART1 + 0x08))
+#define UART1_FCR (*(volatile unsigned long *)(APB0_UART1 + 0x08))
+#define UART1_LCR (*(volatile unsigned long *)(APB0_UART1 + 0x0C))
+#define UART1_MCR (*(volatile unsigned long *)(APB0_UART1 + 0x10))
+#define UART1_LSR (*(volatile unsigned long *)(APB0_UART1 + 0x14))
+#define UART1_MSR (*(volatile unsigned long *)(APB0_UART1 + 0x18))
+
+/* GPIO ports A,B,C,D */
+#define APB0_GPIO0 (ARM_BUS0_BASE + 0x0000C000)
+#define GPIO_PADR (*(volatile unsigned long *)(APB0_GPIO0 + 0x00))
+#define GPIO_PACON (*(volatile unsigned long *)(APB0_GPIO0 + 0x04))
+#define GPIO_PBDR (*(volatile unsigned long *)(APB0_GPIO0 + 0x08))
+#define GPIO_PBCON (*(volatile unsigned long *)(APB0_GPIO0 + 0x0C))
+#define GPIO_PCDR (*(volatile unsigned long *)(APB0_GPIO0 + 0x10))
+#define GPIO_PCCON (*(volatile unsigned long *)(APB0_GPIO0 + 0x14))
+#define GPIO_PDDR (*(volatile unsigned long *)(APB0_GPIO0 + 0x18))
+#define GPIO_PDCON (*(volatile unsigned long *)(APB0_GPIO0 + 0x1C))
+#define GPIO_TEST (*(volatile unsigned long *)(APB0_GPIO0 + 0x20))
+#define GPIO_IEA (*(volatile unsigned long *)(APB0_GPIO0 + 0x24))
+#define GPIO_IEB (*(volatile unsigned long *)(APB0_GPIO0 + 0x28))
+#define GPIO_IEC (*(volatile unsigned long *)(APB0_GPIO0 + 0x2C))
+#define GPIO_IED (*(volatile unsigned long *)(APB0_GPIO0 + 0x30))
+#define GPIO_ISA (*(volatile unsigned long *)(APB0_GPIO0 + 0x34))
+#define GPIO_ISB (*(volatile unsigned long *)(APB0_GPIO0 + 0x38))
+#define GPIO_ISC (*(volatile unsigned long *)(APB0_GPIO0 + 0x3C))
+#define GPIO_ISD (*(volatile unsigned long *)(APB0_GPIO0 + 0x40))
+#define GPIO_IBEA (*(volatile unsigned long *)(APB0_GPIO0 + 0x44))
+#define GPIO_IBEB (*(volatile unsigned long *)(APB0_GPIO0 + 0x48))
+#define GPIO_IBEC (*(volatile unsigned long *)(APB0_GPIO0 + 0x4C))
+#define GPIO_IBED (*(volatile unsigned long *)(APB0_GPIO0 + 0x50))
+#define GPIO_IEVA (*(volatile unsigned long *)(APB0_GPIO0 + 0x54))
+#define GPIO_IEVB (*(volatile unsigned long *)(APB0_GPIO0 + 0x58))
+#define GPIO_IEVC (*(volatile unsigned long *)(APB0_GPIO0 + 0x5C))
+#define GPIO_IEVD (*(volatile unsigned long *)(APB0_GPIO0 + 0x60))
+#define GPIO_ICA (*(volatile unsigned long *)(APB0_GPIO0 + 0x64))
+#define GPIO_ICB (*(volatile unsigned long *)(APB0_GPIO0 + 0x68))
+#define GPIO_ICC (*(volatile unsigned long *)(APB0_GPIO0 + 0x6C))
+#define GPIO_ICD (*(volatile unsigned long *)(APB0_GPIO0 + 0x70))
+#define GPIO_ISR (*(volatile unsigned long *)(APB0_GPIO0 + 0x74))
+
+/* Watchdog */
+#define APB0_WDT (ARM_BUS0_BASE + 0x00010000)
+#define WDTLR (*(volatile unsigned long *)(APB0_WDT + 0x00))
+#define WDTCVR (*(volatile unsigned long *)(APB0_WDT + 0x04))
+#define WDTCON (*(volatile unsigned long *)(APB0_WDT + 0x08))
+
+/* RTC module documentation missing */
+#define APB0_RTC (ARM_BUS0_BASE + 0x00014000)
+#define RTC_TIME (*(volatile unsigned long *)(APB0_RTC + 0x00))
+#define RTC_DATE (*(volatile unsigned long *)(APB0_RTC + 0x04))
+#define RTC_TALARM (*(volatile unsigned long *)(APB0_RTC + 0x08))
+#define RTC_DALARM (*(volatile unsigned long *)(APB0_RTC + 0x0C))
+#define RTC_CTRL (*(volatile unsigned long *)(APB0_RTC + 0x10))
+#define RTC_RESET (*(volatile unsigned long *)(APB0_RTC + 0x14))
+#define RTC_PWOFF (*(volatile unsigned long *)(APB0_RTC + 0x18))
+#define RTC_PWFAIL (*(volatile unsigned long *)(APB0_RTC + 0x1C))
+
+/* SPI */
+#define APB0_SPI (ARM_BUS0_BASE + 0x00018000)
+#define SPI_TXR (*(volatile unsigned long *)(APB0_SPI + 0x00))
+#define SPI_RXR (*(volatile unsigned long *)(APB0_SPI + 0x00))
+#define SPI_IER (*(volatile unsigned long *)(APB0_SPI + 0x04))
+#define SPI_FCR (*(volatile unsigned long *)(APB0_SPI + 0x08))
+#define SPI_FWCR (*(volatile unsigned long *)(APB0_SPI + 0x0C))
+#define SPI_DLYCR (*(volatile unsigned long *)(APB0_SPI + 0x10))
+#define SPI_TXCR (*(volatile unsigned long *)(APB0_SPI + 0x14))
+#define SPI_RXCR (*(volatile unsigned long *)(APB0_SPI + 0x18))
+#define SPI_SSCR (*(volatile unsigned long *)(APB0_SPI + 0x1C))
+#define SPI_ISR (*(volatile unsigned long *)(APB0_SPI + 0x20))
+
+/* SCU module */
+#define APB0_SCU (ARM_BUS0_BASE + 0x0001C000)
+#define SCU_ID (*(volatile unsigned long *)(APB0_SCU + 0x00))
+#define SCU_REMAP (*(volatile unsigned long *)(APB0_SCU + 0x04))
+#define SCU_PLLCON1 (*(volatile unsigned long *)(APB0_SCU + 0x08))
+#define SCU_PLLCON2 (*(volatile unsigned long *)(APB0_SCU + 0x0C))
+#define SCU_PLLCON3 (*(volatile unsigned long *)(APB0_SCU + 0x10))
+#define SCU_DIVCON1 (*(volatile unsigned long *)(APB0_SCU + 0x14))
+#define SCU_CLKCFG (*(volatile unsigned long *)(APB0_SCU + 0x18))
+#define CLKCFG_OTP (1<<0)
+#define CLKCFG_DSP (1<<1)
+#define CLKCFG_SDRAM (1<<2)
+#define CLKCFG_HDMA (1<<3)
+#define CLKCFG_DWDMA (1<<4)
+#define CLKCFG_UHC (1<<5)
+#define CLKCFG_UDC (1<<6)
+/* 7 - 8 reserved */
+#define CLKCFG_NAND (1<<9)
+#define CLKCFG_A2A (1<<10)
+#define CLKCFG_SRAM (1<<11)
+#define CLKCFG_HCLK_LCDC (1<<12)
+#define CLKCFG_LCDC (1<<13)
+#define CLKCFG_HCLK_VIP (1<<14)
+#define CLKCFG_VIP (1<<15)
+#define CLKCFG_I2S (1<<16)
+#define CLKCFG_PCLK_I2S (1<<17)
+#define CLKCFG_UART0 (1<<18)
+#define CLKCFG_UART1 (1<<19)
+#define CLKCFG_I2C (1<<20)
+#define CLKCFG_SPI (1<<21)
+#define CLKCFG_SD (1<<22)
+#define CLKCFG_PCLK_LSADC (1<<23)
+#define CLKCFG_LSADC (1<<24)
+#define CLKCFG_HCLK_HSADC (1<<25)
+#define CLKCFG_HSADC (1<<26)
+#define CLKCFG_GPIO (1<<27)
+#define CLKCFG_TIMER (1<<28)
+#define CLKCFG_PWM (1<<29)
+#define CLKCFG_RTC (1<<30)
+#define CLKCFG_WDT (1<<31)
+
+#define SCU_RSTCFG (*(volatile unsigned long *)(APB0_SCU + 0x1C))
+#define RSTCFG_UHC (1<<0)
+#define RSTCFG_UDC (1<<1)
+#define RSTCFG_LCDC (1<<2)
+#define RSTCFG_VIP (1<<3)
+#define RSTCFG_DSP_CORE (1<<4)
+#define RSTCFG_DSP_PERI (1<<5)
+#define RSTCFG_CODEC (1<<6)
+#define RSTCFG_LSADC (1<<7)
+#define RSTCFG_HSADC (1<<8)
+#define RSTCFG_SD (1<<9)
+#define RSTCFG_MAILBOX (1<<10)
+#define RSTCFG_ECT (1<<11)
+#define RSTCFG_ARM_CORE (1<<12)
+/* 13 - 31 reserved */
+
+#define SCU_PWM (*(volatile unsigned long *)(APB0_SCU + 0x20))
+#define SCU_CPUPD (*(volatile unsigned long *)(APB0_SCU + 0x24))
+#define SCU_CHIPCFG (*(volatile unsigned long *)(APB0_SCU + 0x28))
+#define SCU_STATUS (*(volatile unsigned long *)(APB0_SCU + 0x2C))
+#define SCU_IOMUXA_CON (*(volatile unsigned long *)(APB0_SCU + 0x30))
+/* 20 - 31 reserved */
+#define IOMUX_I2S_PAD (1<<19)
+#define IOMUX_I2S_CODEC (0<<19)
+#define IOMUX_I2C_PAD (1<<18)
+#define IOMUX_I2C_CODEC (0<<18)
+#define IOMUX_GPIO_B7 (2<<16)
+#define IOMUX_NAND_CS3 (1<<16)
+#define IOMUX_I2C_SDA (0<<16)
+#define IOMUX_GPIO_B6 (2<<14)
+#define IOMUX_NAND_CS2 (1<<14)
+#define IOMUX_I2C_SCL (0<<14)
+#define IOMUX_SPI (2<<12)
+#define IOMUX_SD (1<<12)
+#define IOMUX_GPIO_B05 (0<<12)
+#define IOMUX_LCD_VSYNC (1<<11)
+#define IOMUX_GPIO_A7 (0<<11)
+#define IOMUX_LCD_DEN (1<<10)
+#define IOMUX_GPIO_A6 (0<<10)
+#define IOMUX_NAND_CS1 (1<<9)
+#define IOMUX_GPIO_A5 (0<<9)
+#define IOMUX_LCD_D22 (1<<8)
+#define IOMUX_GPIO_A4 (0<<8)
+#define IOMUX_UART0_NRTS (2<<6)
+#define IOMUX_LCD_D20 (1<<6)
+#define IOMUX_GPIO_A3 (0<<6)
+#define IOMUX_UART0_NCTS (2<<4)
+#define IOMUX_LCD_D18 (1<<4)
+#define IOMUX_GPIO_A2 (0<<4)
+#define IOMUX_UART0_TXD (2<<2)
+#define IOMUX_LCD_D17 (1<<2)
+#define IOMUX_GPIO_A1 (0<<2)
+#define IOMUX_UART0_RXD (2<<0)
+#define IOMUX_LCD_D16 (1<<0)
+#define IOMUX_GPIO_A0 (0<<0)
+
+#define SCU_IOMUXB_CON (*(volatile unsigned long *)(APB0_SCU + 0x34))
+/* bits 31 - 23 reserved */
+#define IOMUX_HADC (1<<22)
+#define IOMUX_VIP (0<<22)
+#define IOMUX_SDRAM_CKE (1<<21)
+#define IOMUX_GPIO_D3 (0<<21)
+#define IOMUX_UHC_VBUS (1<<20)
+#define IOMUX_GPIO_F4 (0<<20)
+#define IOMUX_UHC_OCUR (1<<19)
+#define IOMUX_GPIO_F3 (0<<19)
+#define IOMUX_GPIO_F2 (1<<18)
+#define IOMUX_SDRAM_A12 (0<<18)
+#define IOMUX_GPIO_F1 (1<<17)
+#define IOMUX_SDRAM_A11 (0<<17)
+#define IOMUX_VIP_CLK (1<<16)
+#define IOMUX_GPIO_F0 (0<<16)
+#define IOMUX_LCD_D815 (1<<15)
+#define IOMUX_GPIO_E07 (0<<15)
+#define IOMUX_PWM3 (1<<14)
+#define IOMUX_GPIO_D7 (0<<14)
+#define IOMUX_PWM2 (1<<13)
+#define IOMUX_GPIO_D6 (0<<13)
+#define IOMUX_PWM1 (1<<12)
+#define IOMUX_GPIO_D5 (0<<12)
+#define IOMUX_PWM0 (1<<11)
+#define IOMUX_GPIO_D4 (0<<11)
+#define IOMUX_SD_WPA (1<<10)
+#define IOMUX_GPIO_D2 (0<<10)
+#define IOMUX_UART1_RXD (2<<8)
+#define IOMUX_SD_CDA (1<<8)
+#define IOMUX_GPIO_D1 (0<<8)
+#define IOMUX_UART1_TXD (2<<6)
+#define IOMUX_SD_PCA (1<<6)
+#define IOMUX_GPIO_D0 (0<<6)
+#define IOMUX_STMEM_CS1 (1<<5)
+#define IOMUX_GPIO_C7 (0<<5)
+#define IOMUX_I2S_CLK (1<<4)
+#define IOMUX_GPIO_C6 (0<<4)
+#define IOMUX_I2S_SDO (1<<3)
+#define IOMUX_GPIO_C5 (0<<3)
+#define IOMUX_I2S_SDI (1<<2)
+#define IOMUX_GPIO_C4 (0<<2)
+#define IOMUX_I2S_LRCK (1<<1)
+#define IOMUX_GPIO_C3 (0<<1)
+#define IOMUX_I2S_SCLK (1<<0)
+#define IOMUX_GPIO_C2 (0<<0)
+
+#define SCU_GPIOUPCON (*(volatile unsigned long *)(APB0_SCU + 0x38))
+#define SCU_DIVCON2 (*(volatile unsigned long *)(APB0_SCU + 0x3C))
+
+/* I2C controller */
+#define APB0_I2C (ARM_BUS0_BASE + 0x00020000)
+#define I2C_MTXR (*(volatile unsigned long *)(APB0_I2C + 0x00))
+#define I2C_MRXR (*(volatile unsigned long *)(APB0_I2C + 0x04))
+#define I2C_STXR (*(volatile unsigned long *)(APB0_I2C + 0x08))
+#define I2C_SRXR (*(volatile unsigned long *)(APB0_I2C + 0x0C))
+#define I2C_SADDR (*(volatile unsigned long *)(APB0_I2C + 0x10))
+#define I2C_IER (*(volatile unsigned long *)(APB0_I2C + 0x14))
+#define I2C_ISR (*(volatile unsigned long *)(APB0_I2C + 0x18))
+#define I2C_LCMR (*(volatile unsigned long *)(APB0_I2C + 0x1C))
+#define I2C_LSR (*(volatile unsigned long *)(APB0_I2C + 0x20))
+#define I2C_CONR (*(volatile unsigned long *)(APB0_I2C + 0x24))
+#define I2C_OPR (*(volatile unsigned long *)(APB0_I2C + 0x28))
+
+/* SD card controller */
+#define APB0_SD (ARM_BUS0_BASE + 0x00024000)
+#define MMU_CTRL (*(volatile unsigned long *)(APB0_SD + 0x00))
+#define MMU_BIG_ENDIAN (1<<12)
+#define MMU_DMA_START (1<<11)
+#define MMU_DMA_WRITE (1<<10)
+#define MMU_MMU0_BUFI (0<<9)
+#define MMU_MMU0_BUFII (1<<9)
+#define MMU_CPU_BUFI (0<<8)
+#define MMU_CPU_BUFII (1<<8)
+#define MMU_BUFII_RESET (1<<7)
+#define MMU_BUFII_END (1<<6)
+#define MMU_BUFII_BYTE (0<<4)
+#define MMU_BUFII_HALFWORD (1<<4)
+#define MMU_BUFII_WORD (3<<4)
+#define MMU_BUFI_RESET (1<<3)
+#define MMU_BUFI_END (1<<2)
+#define MMU_BUFI_BYTE (0<<0)
+#define MMU_BUFI_HALFWORD (1<<0)
+#define MMU_BUFI_WORD (3<<0)
+
+#define MMU_PNRI (*(volatile unsigned long *)(APB0_SD + 0x04))
+#define CUR_PNRI (*(volatile unsigned long *)(APB0_SD + 0x08))
+#define MMU_PNRII (*(volatile unsigned long *)(APB0_SD + 0x0C))
+#define CUR_PNRII (*(volatile unsigned long *)(APB0_SD + 0x10))
+#define MMU_ADDR (*(volatile unsigned long *)(APB0_SD + 0x14))
+#define CUR_ADDR (*(volatile unsigned long *)(APB0_SD + 0x18))
+#define MMU_DATA (*(volatile unsigned long *)(APB0_SD + 0x1C))
+
+#define SD_CTRL (*(volatile unsigned long *)(APB0_SD + 0x20))
+#define SD_PWR_CD (1<<13)
+#define SD_PWR_CPU (0<<13)
+#define SD_DETECT_CDDAT3 (1<<12)
+#define SD_DETECT_MECH (0<<12)
+#define SD_CLOCK_DIS (1<<11)
+#define SD_CLOCK_EN (0<<11)
+#define SD_DIV(x) ((x)&0x7ff)
+
+#define SD_INT (*(volatile unsigned long *)(APB0_SD + 0x24))
+#define CMD_RES_STAT (1<<6)
+#define DATA_XFER_STAT (1<<5)
+#define CD_DETECT_STAT (1<<4)
+#define CMD_RES_INT_EN (1<<2)
+#define DATA_XFER_INT_EN (1<<1)
+#define CD_DETECT_IN_EN (1<<0)
+
+#define SD_CARD (*(volatile unsigned long *)(APB0_SD + 0x28))
+#define SD_CARD_SELECT (1<<7)
+#define SD_CARD_PWR_EN (1<<6)
+#define SD_CARD_DETECT_INT_EN (1<<5)
+#define SD_CARD_BSY (1<<2)
+#define SD_CARD_WRITE_PROTECT (1<<1)
+#define SD_CARD_DETECT (1<<0)
+
+#define SD_CMDREST (*(volatile unsigned long *)(APB0_SD + 0x30))
+#define CMD_XFER_START (1<<13)
+#define CMD_XFER_END (0<<13)
+#define RES_XFER_START (1<<12)
+#define RES_XFER_END (0<<12)
+#define RES_R1 (0<<9)
+#define RES_R1b (1<<9)
+#define RES_R2 (2<<9)
+#define RES_R3 (3<<9)
+#define RES_R6 (6<<9)
+#define CMD_RES_ERROR (1<<8)
+/* bits 0-5 cmd index */
+
+#define SD_CMDRES (*(volatile unsigned long *)(APB0_SD + 0x34))
+#define STAT_CMD_XFER_START (1<<8)
+#define STAT_RES_XFER_START (1<<7)
+#define STAT_CMD_RES_ERR (1<<6)
+#define STAT_CMD_RES_BUS_ERR (1<<5)
+#define STAT_RES_TIMEOUT_ERR (1<<4)
+#define STAT_RES_STARTBIT_ERR (1<<3)
+#define STAT_RES_INDEX_ERR (1<<2)
+#define STAT_RES_CRC_ERR (1<<1)
+#define STAT_RES_ENDBIT_ERR (1<<0)
+
+#define SD_DATAT (*(volatile unsigned long *)(APB0_SD + 0x3C))
+#define DATA_XFER_START (1<<13)
+#define DATA_XFER_WRITE (1<<12)
+#define DATA_XFER_READ (0<<12)
+#define DATA_BUS_4LINES (1<<11) /* rk2705/6/8 does not support this mode */
+#define DATA_BUS_1LINE (0<<11)
+#define DATA_XFER_DMA_EN (1<<10)
+#define DATA_XFER_DMA_DIS (0<<10)
+#define DATA_XFER_MULTI (1<<9)
+#define DATA_XFER_SINGLE (0<<9)
+#define DATA_XFER_ERR (1<<8)
+#define DATA_BUS_ERR (1<<7)
+#define DATA_TIMEOUT_ERR (1<<6)
+#define DATA_CRC_ERR (1<<5)
+#define READ_DAT_STARTBIT_ERR (1<<4)
+#define READ_DAT_ENDBIT_ERR (1<<3)
+#define WRITE_DAT_NOERR (2<<0)
+#define WRITE_DAT_CRC_ERR (5<<0)
+#define WRITE_DAT_NO_RES (7<<0)
+
+#define SD_CMD (*(volatile unsigned long *)(APB0_SD + 0x40))
+#define SD_RES3 (*(volatile unsigned long *)(APB0_SD + 0x44))
+#define SD_RES2 (*(volatile unsigned long *)(APB0_SD + 0x48))
+#define SD_RES1 (*(volatile unsigned long *)(APB0_SD + 0x4C))
+#define SD_RES0 (*(volatile unsigned long *)(APB0_SD + 0x50))
+
+/* I2S controller */
+#define APB0_I2S (ARM_BUS0_BASE + 0x00028000)
+#define I2S_OPR (*(volatile unsigned long *)(APB0_I2S + 0x00))
+#define I2S_TXR (*(volatile unsigned long *)(APB0_I2S + 0x04))
+#define I2S_RXR (*(volatile unsigned long *)(APB0_I2S + 0x08))
+#define I2S_TXCTL (*(volatile unsigned long *)(APB0_I2S + 0x0C))
+#define I2S_RXCTL (*(volatile unsigned long *)(APB0_I2S + 0x10))
+#define I2S_FIFOSTS (*(volatile unsigned long *)(APB0_I2S + 0x14))
+#define I2S_IER (*(volatile unsigned long *)(APB0_I2S + 0x18))
+#define I2S_ISR (*(volatile unsigned long *)(APB0_I2S + 0x1C))
+
+/* PWM timer */
+#define APB0_PWM (ARM_BUS0_BASE + 0x0002C000)
+#define PWMT0_CNTR (*(volatile unsigned long *)(APB0_PWM + 0x00))
+#define PWMT0_HRC (*(volatile unsigned long *)(APB0_PWM + 0x04))
+#define PWMT0_LRC (*(volatile unsigned long *)(APB0_PWM + 0x08))
+#define PWMT0_CTRL (*(volatile unsigned long *)(APB0_PWM + 0x0C))
+#define PWMT1_CNTR (*(volatile unsigned long *)(APB0_PWM + 0x10))
+#define PWMT1_HRC (*(volatile unsigned long *)(APB0_PWM + 0x14))
+#define PWMT1_LRC (*(volatile unsigned long *)(APB0_PWM + 0x18))
+#define PWMT1_CTRL (*(volatile unsigned long *)(APB0_PWM + 0x1C))
+#define PWMT2_CNTR (*(volatile unsigned long *)(APB0_PWM + 0x20))
+#define PWMT2_HRC (*(volatile unsigned long *)(APB0_PWM + 0x24))
+#define PWMT2_LRC (*(volatile unsigned long *)(APB0_PWM + 0x28))
+#define PWMT2_CTRL (*(volatile unsigned long *)(APB0_PWM + 0x2C))
+#define PWMT3_CNTR (*(volatile unsigned long *)(APB0_PWM + 0x30))
+#define PWMT3_HRC (*(volatile unsigned long *)(APB0_PWM + 0x34))
+#define PWMT3_LRC (*(volatile unsigned long *)(APB0_PWM + 0x38))
+#define PWMT3_CTRL (*(volatile unsigned long *)(APB0_PWM + 0x3C))
+
+/* ADC converter */
+#define APB0_ADC0 (ARM_BUS0_BASE + 0x00030000)
+#define ADC_DATA (*(volatile unsigned long *)(APB0_ADC0 + 0x00))
+#define ADC_STAT (*(volatile unsigned long *)(APB0_ADC0 + 0x04))
+#define ADC_CTRL (*(volatile unsigned long *)(APB0_ADC0 + 0x08))
+
+/* 0x18034000 - 0x18038000 reserved */
+
+/* GPIO ports E,F */
+#define APB0_GPIO1 (ARM_BUS0_BASE + 0x00038000)
+#define GPIO_PEDR (*(volatile unsigned long *)(APB0_GPIO1 + 0x00))
+#define GPIO_PECON (*(volatile unsigned long *)(APB0_GPIO1 + 0x04))
+#define GPIO_PFDR (*(volatile unsigned long *)(APB0_GPIO1 + 0x08))
+#define GPIO_PFCON (*(volatile unsigned long *)(APB0_GPIO1 + 0x0C))
+
+#define GPIO1_TEST (*(volatile unsigned long *)(APB0_GPIO1 + 0x20))
+#define GPIO_IEE (*(volatile unsigned long *)(APB0_GPIO1 + 0x24))
+#define GPIO_IEF (*(volatile unsigned long *)(APB0_GPIO1 + 0x28))
+
+#define GPIO_ISE (*(volatile unsigned long *)(APB0_GPIO1 + 0x34))
+#define GPIO_ISF (*(volatile unsigned long *)(APB0_GPIO1 + 0x38))
+
+#define GPIO_IBEE (*(volatile unsigned long *)(APB0_GPIO1 + 0x44))
+#define GPIO_IBEF (*(volatile unsigned long *)(APB0_GPIO1 + 0x48))
+
+#define GPIO_IEVE (*(volatile unsigned long *)(APB0_GPIO1 + 0x54))
+#define GPIO_IEVF (*(volatile unsigned long *)(APB0_GPIO1 + 0x58))
+
+#define GPIO_ICE (*(volatile unsigned long *)(APB0_GPIO1 + 0x64))
+#define GPIO_ICF (*(volatile unsigned long *)(APB0_GPIO1 + 0x68))
+
+#define GPIO1_ISR (*(volatile unsigned long *)(APB0_GPIO1 + 0x74))
+
+
+/* 0x1803C000 - 0x18080000 reserved */
+
+/* Interrupt controller */
+#define AHB0_INTC (ARM_BUS0_BASE + 0x00080000)
+#define INTC_SCR0 (*(volatile unsigned long *)(AHB0_INTC + 0x00))
+#define INTC_SCR1 (*(volatile unsigned long *)(AHB0_INTC + 0x04))
+#define INTC_SCR2 (*(volatile unsigned long *)(AHB0_INTC + 0x08))
+#define INTC_SCR3 (*(volatile unsigned long *)(AHB0_INTC + 0x0C))
+#define INTC_SCR4 (*(volatile unsigned long *)(AHB0_INTC + 0x10))
+#define INTC_SCR5 (*(volatile unsigned long *)(AHB0_INTC + 0x14))
+#define INTC_SCR6 (*(volatile unsigned long *)(AHB0_INTC + 0x18))
+#define INTC_SCR7 (*(volatile unsigned long *)(AHB0_INTC + 0x1C))
+#define INTC_SCR8 (*(volatile unsigned long *)(AHB0_INTC + 0x20))
+#define INTC_SCR9 (*(volatile unsigned long *)(AHB0_INTC + 0x24))
+#define INTC_SCR10 (*(volatile unsigned long *)(AHB0_INTC + 0x28))
+#define INTC_SCR11 (*(volatile unsigned long *)(AHB0_INTC + 0x2C))
+#define INTC_SCR12 (*(volatile unsigned long *)(AHB0_INTC + 0x30))
+#define INTC_SCR13 (*(volatile unsigned long *)(AHB0_INTC + 0x34))
+#define INTC_SCR14 (*(volatile unsigned long *)(AHB0_INTC + 0x38))
+#define INTC_SCR15 (*(volatile unsigned long *)(AHB0_INTC + 0x3C))
+#define INTC_SCR16 (*(volatile unsigned long *)(AHB0_INTC + 0x40))
+#define INTC_SCR17 (*(volatile unsigned long *)(AHB0_INTC + 0x44))
+#define INTC_SCR18 (*(volatile unsigned long *)(AHB0_INTC + 0x48))
+#define INTC_SCR19 (*(volatile unsigned long *)(AHB0_INTC + 0x4C))
+#define INTC_SCR20 (*(volatile unsigned long *)(AHB0_INTC + 0x50))
+#define INTC_SCR21 (*(volatile unsigned long *)(AHB0_INTC + 0x54))
+#define INTC_SCR22 (*(volatile unsigned long *)(AHB0_INTC + 0x58))
+#define INTC_SCR23 (*(volatile unsigned long *)(AHB0_INTC + 0x5C))
+#define INTC_SCR24 (*(volatile unsigned long *)(AHB0_INTC + 0x60))
+#define INTC_SCR25 (*(volatile unsigned long *)(AHB0_INTC + 0x64))
+#define INTC_SCR26 (*(volatile unsigned long *)(AHB0_INTC + 0x68))
+#define INTC_SCR27 (*(volatile unsigned long *)(AHB0_INTC + 0x6C))
+#define INTC_SCR28 (*(volatile unsigned long *)(AHB0_INTC + 0x70))
+#define INTC_SCR29 (*(volatile unsigned long *)(AHB0_INTC + 0x74))
+#define INTC_SCR30 (*(volatile unsigned long *)(AHB0_INTC + 0x78))
+#define INTC_SCR31 (*(volatile unsigned long *)(AHB0_INTC + 0x7C))
+
+#define INTC_ISR (*(volatile unsigned long *)(AHB0_INTC + 0x104))
+#define INTC_IPR (*(volatile unsigned long *)(AHB0_INTC + 0x108))
+#define INTC_IMR (*(volatile unsigned long *)(AHB0_INTC + 0x10C))
+
+#define INTC_IECR (*(volatile unsigned long *)(AHB0_INTC + 0x114))
+#define INTC_ICCR (*(volatile unsigned long *)(AHB0_INTC + 0x118))
+#define INTC_ISCR (*(volatile unsigned long *)(AHB0_INTC + 0x11C))
+
+#define IRQ_ARM_UART0 (1<<0)
+#define IRQ_ARM_UART1 (1<<1)
+#define IRQ_ARM_TIMER0 (1<<2)
+#define IRQ_ARM_TIMER1 (1<<3)
+#define IRQ_ARM_TIMER2 (1<<4)
+#define IRQ_ARM_GPIO0 (1<<5)
+#define IRQ_ARM_SW (1<<6)
+#define IRQ_ARM_MAILBOX (1<<7)
+#define IRQ_ARM_RTC (1<<8)
+#define IRQ_ARM_SCU (1<<9)
+#define IRQ_ARM_SD (1<<10)
+#define IRQ_ARM_SPI (1<<11)
+#define IRQ_ARM_HDMA (1<<12)
+#define IRQ_ARM_A2A (1<<13)
+#define IRQ_ARM_I2C (1<<14)
+#define IRQ_ARM_I2S (1<<15)
+#define IRQ_ARM_UDC (1<<16)
+#define IRQ_ARM_UHC (1<<17)
+#define IRQ_ARM_PWM0 (1<<18)
+#define IRQ_ARM_PWM1 (1<<19)
+#define IRQ_ARM_PWM2 (1<<20)
+#define IRQ_ARM_PWM3 (1<<21)
+#define IRQ_ARM_ADC (1<<22)
+#define IRQ_ARM_GPIO1 (1<<23)
+#define IRQ_ARM_VIP (1<<24)
+#define IRQ_ARM_DWDMA (1<<25)
+#define IRQ_ARM_NANDC (1<<26)
+#define IRQ_ARM_LCDC (1<<27)
+#define IRQ_ARM_DSP (1<<28)
+#define IRQ_ARM_SW1 (1<<29)
+#define IRQ_ARM_SW2 (1<<30)
+#define IRQ_ARM_SW3 (1<<31)
+
+#define INTC_TEST (*(volatile unsigned long *)(AHB0_INTC + 0x124))
+
+/* Bus arbiter module */
+#define AHB0_ARBITER (ARM_BUS0_BASE + 0x00084000)
+#define ARB_MODE (*(volatile unsigned long *)(AHB0_ARBITER + 0x00))
+#define ARB_PRIO1 (*(volatile unsigned long *)(AHB0_ARBITER + 0x04))
+#define ARB_PRIO2 (*(volatile unsigned long *)(AHB0_ARBITER + 0x08))
+#define ARB_PRIO3 (*(volatile unsigned long *)(AHB0_ARBITER + 0x0C))
+#define ARB_PRIO4 (*(volatile unsigned long *)(AHB0_ARBITER + 0x10))
+#define ARB_PRIO5 (*(volatile unsigned long *)(AHB0_ARBITER + 0x14))
+#define ARB_PRIO6 (*(volatile unsigned long *)(AHB0_ARBITER + 0x18))
+#define ARB_PRIO7 (*(volatile unsigned long *)(AHB0_ARBITER + 0x1C))
+#define ARB_PRIO8 (*(volatile unsigned long *)(AHB0_ARBITER + 0x20))
+#define ARB_PRIO9 (*(volatile unsigned long *)(AHB0_ARBITER + 0x24))
+#define ARB_PRIO10 (*(volatile unsigned long *)(AHB0_ARBITER + 0x28))
+#define ARB_PRIO11 (*(volatile unsigned long *)(AHB0_ARBITER + 0x2C))
+#define ARB_PRIO12 (*(volatile unsigned long *)(AHB0_ARBITER + 0x30))
+#define ARB_PRIO13 (*(volatile unsigned long *)(AHB0_ARBITER + 0x34))
+#define ARB_PRIO14 (*(volatile unsigned long *)(AHB0_ARBITER + 0x38))
+#define ARB_PRIO15 (*(volatile unsigned long *)(AHB0_ARBITER + 0x3C))
+
+/* Interprocessor communication module */
+#define AHB0_CPU_MAILBOX (ARM_BUS0_BASE + 0x00088000)
+#define MAILBOX_ID (*(volatile unsigned long *)(AHB0_CPU_MAILBOX + 0x00))
+#define H2C_STA (*(volatile unsigned long *)(AHB0_CPU_MAILBOX + 0x10))
+#define H2C0_DATA (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x20))
+#define H2C0_CMD (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x24))
+#define H2C1_DATA (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x28))
+#define H2C1_CMD (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x2C))
+#define H2C2_DATA (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x30))
+#define H2C2_CMD (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x24))
+#define H2C3_DATA (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x38))
+#define H2C3_CMD (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x3C))
+
+#define C2H_STA (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x40))
+#define C2H0_DATA (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x50))
+#define C2H0_CMD (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x54))
+#define C2H1_DATA (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x58))
+#define C2H1_CMD (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x5C))
+#define C2H2_DATA (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x60))
+#define C2H2_CMD (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x64))
+#define C2H3_DATA (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x68))
+#define C2H3_CMD (*(volatile unsigned long *)(AHB0_CPU_MAILBOC + 0x6C))
+
+/* Debug module */
+#define AHB0_CPU_DEBUGIF (ARM_BUS0_BASE + 0x0008C000)
+
+/* AHB DMA */
+#define AHB0_HDMA (ARM_BUS0_BASE + 0x00090000)
+#define HDMA_CON0 (*(volatile unsigned long *)(AHB0_HDMA + 0x00))
+#define HDMA_CON1 (*(volatile unsigned long *)(AHB0_HDMA + 0x04))
+#define HDMA_ISRC0 (*(volatile unsigned long *)(AHB0_HDMA + 0x08))
+#define HDMA_IDST0 (*(volatile unsigned long *)(AHB0_HDMA + 0x0C))
+#define HDMA_ICNT0 (*(volatile unsigned long *)(AHB0_HDMA + 0x10))
+#define HDMA_ISRC1 (*(volatile unsigned long *)(AHB0_HDMA + 0x14))
+#define HDMA_IDST1 (*(volatile unsigned long *)(AHB0_HDMA + 0x18))
+#define HDMA_ICNT1 (*(volatile unsigned long *)(AHB0_HDMA + 0x1C))
+#define HDMA_CSRC0 (*(volatile unsigned long *)(AHB0_HDMA + 0x20))
+#define HDMA_CDST0 (*(volatile unsigned long *)(AHB0_HDMA + 0x24))
+#define HDMA_CCNT0 (*(volatile unsigned long *)(AHB0_HDMA + 0x28))
+#define HDMA_CSRC1 (*(volatile unsigned long *)(AHB0_HDMA + 0x2C))
+#define HDMA_CDST1 (*(volatile unsigned long *)(AHB0_HDMA + 0x30))
+#define HDMA_CCNT1 (*(volatile unsigned long *)(AHB0_HDMA + 0x34))
+#define HDMA_ISR (*(volatile unsigned long *)(AHB0_HDMA + 0x38))
+#define HDMA_DSR (*(volatile unsigned long *)(AHB0_HDMA + 0x3C))
+#define HDMA_ISCNT0 (*(volatile unsigned long *)(AHB0_HDMA + 0x40))
+#define HDMA_IPNCNTD0 (*(volatile unsigned long *)(AHB0_HDMA + 0x44))
+#define HDMA_IADDR_BS0 (*(volatile unsigned long *)(AHB0_HDMA + 0x48))
+#define HDMA_ISCNT1 (*(volatile unsigned long *)(AHB0_HDMA + 0x4C))
+#define HDMA_IPNCNTD1 (*(volatile unsigned long *)(AHB0_HDMA + 0x50))
+#define HDMA_IADDR_BS1 (*(volatile unsigned long *)(AHB0_HDMA + 0x54))
+#define HDMA_CSCNT0 (*(volatile unsigned long *)(AHB0_HDMA + 0x58))
+#define HDMA_CPNCNTD0 (*(volatile unsigned long *)(AHB0_HDMA + 0x5C))
+#define HDMA_CADDR_BS0 (*(volatile unsigned long *)(AHB0_HDMA + 0x60))
+#define HDMA_CSCNT1 (*(volatile unsigned long *)(AHB0_HDMA + 0x64))
+#define HDMA_CPNCNTD1 (*(volatile unsigned long *)(AHB0_HDMA + 0x68))
+#define HDMA_CADDR_BS1 (*(volatile unsigned long *)(AHB0_HDMA + 0x6C))
+#define HDMA_PACNT0 (*(volatile unsigned long *)(AHB0_HDMA + 0x70))
+#define HDMA_PACNT1 (*(volatile unsigned long *)(AHB0_HDMA + 0x74))
+
+/* AHB-to-AHB bridge controller */
+#define AHB0_A2A_DMA (ARM_BUS0_BASE + 0x00094000)
+#define A2A_CON0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x00))
+#define A2A_ISRC0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x04))
+#define A2A_IDST0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x08))
+#define A2A_ICNT0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x0C))
+#define A2A_CSRC0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x10))
+#define A2A_CDST0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x14))
+#define A2A_CCNT0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x18))
+#define A2A_CON1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x1C))
+#define A2A_ISRC1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x20))
+#define A2A_IDST1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x24))
+#define A2A_ICNT1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x28))
+#define A2A_CSRC1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x2C))
+#define A2A_CDST1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x30))
+#define A2A_CCNT1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x34))
+#define A2A_INT_STS (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x38))
+#define A2A_DMA_STS (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x3C))
+#define A2A_ERR_ADR0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x40))
+#define A2A_ERR_OP0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x44))
+#define A2A_ERR_ADR1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x48))
+#define A2A_ERR_OP1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x4C))
+#define A2A_LCNT0 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x50))
+#define A2A_LCNT1 (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x54))
+#define A2A_DOMAIN (*(volatile unsigned long *)(AHB0_A2A_DMA + 0x58))
+
+/* 0x18098000 - 0x180A000 reserved */
+
+/* USB device controller */
+#define AHB0_UDC (ARM_BUS0_BASE + 0x000A0000)
+#define PHY_TEST_EN (*(volatile unsigned long *)(AHB0_UDC + 0x00))
+#define PHY_TEST (*(volatile unsigned long *)(AHB0_UDC + 0x04))
+#define DEV_CTL (*(volatile unsigned long *)(AHB0_UDC + 0x08))
+#define DEV_RMTWKP (1<<2)
+#define DEV_SELF_PWR (1<<3)
+#define DEV_SOFT_CN (1<<4)
+#define DEV_RESUME (1<<5)
+#define DEV_PHY16BIT (1<<6)
+#define SOFT_POR (1<<7)
+#define CSR_DONE (1<<8)
+
+#define DEV_INFO (*(volatile unsigned long *)(AHB0_UDC + 0x10))
+#define DEV_EN (1<<7)
+#define VBUS_STS (1<<20)
+#define DEV_SPEED (3<<21)
+
+#define EN_INT (*(volatile unsigned long *)(AHB0_UDC + 0x14))
+#define EN_SOF_INTR (1<<0)
+#define EN_SETUP_INTR (1<<1)
+#define EN_IN0_INTR (1<<2)
+#define EN_OUT0_INTR (1<<3)
+#define EN_USBRST_INTR (1<<4)
+#define EN_RESUME_INTR (1<<5)
+#define EN_SUSP_INTR (1<<6)
+/* bit 7 reserved */
+#define EN_BOUT1_INTR (1<<8)
+#define EN_BIN2_INTR (1<<9)
+#define EN_IIN3_INTR (1<<10)
+#define EN_BOUT4_INTR (1<<11)
+#define EN_BIN5_INTR (1<<12)
+#define EN_IIN6_INTR (1<<13)
+#define EN_BOUT7_INTR (1<<14)
+#define EN_BIN8_INTR (1<<15)
+#define EN_IIN9_INTR (1<<16)
+#define EN_BOUT10_INTR (1<<17)
+#define EN_BIN11_INTR (1<<18)
+#define EN_IIN12_INTR (1<<19)
+#define EN_BOUT13_INTR (1<<20)
+#define EN_BIN14_INTR (1<<21)
+#define EN_IIN15_INTR (1<<22)
+/* bits 23-26 TEST */
+/* bits 27-31 reserved */
+
+#define INT2FLAG (*(volatile unsigned long *)(AHB0_UDC + 0x18))
+#define SOF_INTR (1<<0)
+#define SETUP_INTR (1<<1)
+#define IN0_INTR (1<<2)
+#define OUT0_INTR (1<<3)
+#define USBRST_INTR (1<<4)
+#define RESUME_INTR (1<<5)
+#define SUSP_INTR (1<<6)
+#define CONN_INTR (1<<7) /* marked as reserved in DS */
+#define BOUT1_INTR (1<<8)
+#define BIN2_INTR (1<<9)
+#define IIN3_INTR (1<<10)
+#define BOUT4_INTR (1<<11)
+#define BIN5_INTR (1<<12)
+#define IIN6_INTR (1<<13)
+#define BOUT7_INTR (1<<14)
+#define BIN8_INTR (1<<15)
+#define IIN9_INTR (1<<16)
+#define BOUT10_INTR (1<<17)
+#define BIN11_INTR (1<<18)
+#define IIN12_INTR (1<<19)
+#define BOUT13_INTR (1<<20)
+#define BIN14_INTR (1<<21)
+#define IIN15_INTR (1<<22)
+/* bits 23-26 TEST */
+/* bits 27-31 reserved */
+
+#define INTCON (*(volatile unsigned long *)(AHB0_UDC + 0x1C))
+#define UDC_INTEN (1<<0)
+#define UDC_INTEDGE_TRIG (1<<1)
+#define UDC_INTHIGH_ACT (1<<2)
+
+#define SETUP1 (*(volatile unsigned long *)(AHB0_UDC + 0x20))
+#define SETUP2 (*(volatile unsigned long *)(AHB0_UDC + 0x24))
+#define AHBCON (*(volatile unsigned long *)(AHB0_UDC + 0x28))
+#define RX0STAT (*(volatile unsigned long *)(AHB0_UDC + 0x30))
+#define RX0CON (*(volatile unsigned long *)(AHB0_UDC + 0x34))
+#define RX0DMACTLO (*(volatile unsigned long *)(AHB0_UDC + 0x38))
+#define RX0DMAOUTLMADDR (*(volatile unsigned long *)(AHB0_UDC + 0x3C))
+#define TX0STAT (*(volatile unsigned long *)(AHB0_UDC + 0x40))
+#define TX0CON (*(volatile unsigned long *)(AHB0_UDC + 0x44))
+#define TX0BUF (*(volatile unsigned long *)(AHB0_UDC + 0x48))
+#define TX0DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0x4C))
+#define TX0DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0x50))
+#define RX1STAT (*(volatile unsigned long *)(AHB0_UDC + 0x54))
+#define RX1CON (*(volatile unsigned long *)(AHB0_UDC + 0x58))
+#define RX1DMACTLO (*(volatile unsigned long *)(AHB0_UDC + 0x5C))
+#define RX1DMAOUTLMADDR (*(volatile unsigned long *)(AHB0_UDC + 0x60))
+#define TX2STAT (*(volatile unsigned long *)(AHB0_UDC + 0x64))
+#define TX2CON (*(volatile unsigned long *)(AHB0_UDC + 0x68))
+#define TX2BUF (*(volatile unsigned long *)(AHB0_UDC + 0x6C))
+#define TX2DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0x70))
+#define TX2DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0x74))
+#define TX3STAT (*(volatile unsigned long *)(AHB0_UDC + 0x78))
+#define TX3CON (*(volatile unsigned long *)(AHB0_UDC + 0x7C))
+#define TX3BUF (*(volatile unsigned long *)(AHB0_UDC + 0x80))
+#define TX3DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0x84))
+#define TX3DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0x88))
+#define RX4STAT (*(volatile unsigned long *)(AHB0_UDC + 0x8C))
+#define RX4CON (*(volatile unsigned long *)(AHB0_UDC + 0x90))
+#define RX4DMACTLO (*(volatile unsigned long *)(AHB0_UDC + 0x94))
+#define RX4DMAOUTLMADDR (*(volatile unsigned long *)(AHB0_UDC + 0x98))
+#define TX5STAT (*(volatile unsigned long *)(AHB0_UDC + 0x9C))
+#define TX5CON (*(volatile unsigned long *)(AHB0_UDC + 0xA0))
+#define TX5BUF (*(volatile unsigned long *)(AHB0_UDC + 0xA4))
+#define TX5DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0xA8))
+#define TX5DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0xAC))
+#define TX6STAT (*(volatile unsigned long *)(AHB0_UDC + 0xB0))
+#define TX6CON (*(volatile unsigned long *)(AHB0_UDC + 0xB4))
+#define TX6BUF (*(volatile unsigned long *)(AHB0_UDC + 0xB8))
+#define TX6DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0xBC))
+#define TX6DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0xC0))
+#define RX7STAT (*(volatile unsigned long *)(AHB0_UDC + 0xC4))
+#define RX7CON (*(volatile unsigned long *)(AHB0_UDC + 0xC8))
+#define RX7DMACTLO (*(volatile unsigned long *)(AHB0_UDC + 0xCC))
+#define RX7DMAOUTLMADDR (*(volatile unsigned long *)(AHB0_UDC + 0xD0))
+#define TX8STAT (*(volatile unsigned long *)(AHB0_UDC + 0xD4))
+#define TX8CON (*(volatile unsigned long *)(AHB0_UDC + 0xD8))
+#define TX8BUF (*(volatile unsigned long *)(AHB0_UDC + 0xDC))
+#define TX8DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0xE0))
+#define TX8DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0xE4))
+#define TX9STAT (*(volatile unsigned long *)(AHB0_UDC + 0xE8))
+#define TX9CON (*(volatile unsigned long *)(AHB0_UDC + 0xEC))
+#define TX9BUF (*(volatile unsigned long *)(AHB0_UDC + 0xF0))
+#define TX9DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0xF4))
+#define TX9DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0xF8))
+#define RX10STAT (*(volatile unsigned long *)(AHB0_UDC + 0xFC))
+#define RX10CON (*(volatile unsigned long *)(AHB0_UDC + 0x100))
+#define RX10DMACTLO (*(volatile unsigned long *)(AHB0_UDC + 0x104))
+#define RX10DMAOUTLMADDR (*(volatile unsigned long *)(AHB0_UDC + 0x108))
+#define TX11STAT (*(volatile unsigned long *)(AHB0_UDC + 0x10C))
+#define TX11CON (*(volatile unsigned long *)(AHB0_UDC + 0x110))
+#define TX11BUF (*(volatile unsigned long *)(AHB0_UDC + 0x114))
+#define TX11DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0x118))
+#define TX11DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0x11C))
+#define TX12STAT (*(volatile unsigned long *)(AHB0_UDC + 0x120))
+#define TX12CON (*(volatile unsigned long *)(AHB0_UDC + 0x124))
+#define TX12BUF (*(volatile unsigned long *)(AHB0_UDC + 0x128))
+#define TX12DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0x12C))
+#define TX12DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0x130))
+#define RX13STAT (*(volatile unsigned long *)(AHB0_UDC + 0x134))
+#define RX13CON (*(volatile unsigned long *)(AHB0_UDC + 0x138))
+#define RX13DMACTLO (*(volatile unsigned long *)(AHB0_UDC + 0x13C))
+#define RX13DMAOUTLMADDR (*(volatile unsigned long *)(AHB0_UDC + 0x140))
+#define TX14STAT (*(volatile unsigned long *)(AHB0_UDC + 0x144))
+#define TX14CON (*(volatile unsigned long *)(AHB0_UDC + 0x148))
+#define TX14BUF (*(volatile unsigned long *)(AHB0_UDC + 0x14C))
+#define TX14DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0x150))
+#define TX14DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0x154))
+#define TX15STAT (*(volatile unsigned long *)(AHB0_UDC + 0x158))
+#define TX15CON (*(volatile unsigned long *)(AHB0_UDC + 0x15C))
+#define TX15BUF (*(volatile unsigned long *)(AHB0_UDC + 0x160))
+#define TX15DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0x164))
+#define TX15DMALM_IADDR (*(volatile unsigned long *)(AHB0_UDC + 0x168))
+
+/* RXnSTAT bits */
+/* bits 10:0 RXLEN */
+/* bits 15:11 reserved */
+#define RXVOID (1<<16)
+#define RXERR (1<<17)
+#define RXACK (1<<18)
+#define RXCFINT (1<<19) /* reserved for EP0 */
+/* bits 23:20 reserved */
+#define RXFULL (1<<24)
+#define RXOVF (1<<25)
+/* bits 31:26 reserved */
+
+/* RXnCON bits */
+#define RXFFRC (1<<0)
+#define RXCLR (1<<1)
+#define RXSTALL (1<<2)
+#define RXNAK (1<<3)
+#define RXEPEN (1<<4)
+#define RXVOIDINTEN (1<<5)
+#define RXERRINTEN (1<<6)
+#define RXACKINTEN (1<<7)
+/* bits 31:8 reserved for EP0 */
+/* bits 31:14 reserved for others */
+
+/* TxnSTAT */
+/* bits 10:0 TXLEN */
+/* bits 15:11 reserved */
+#define TXVOID (1<<16)
+#define TXERR (1<<17)
+#define TXACK (1<<18)
+#define TXDMADN (1<<19) /* reserved for EP0 */
+#define TXCFINT (1<<20) /* reserved for EP0 */
+/* bits 31:21 reserved */
+
+/* TXnCON bits */
+#define TXCLR (1<<0)
+#define TXSTALL (1<<1)
+#define TXNAK (1<<2)
+#define TXEPEN (1<<3) /* reserved for EP0 */
+#define TXVOIDINTEN (1<<4)
+#define TXERRINTEN (1<<5)
+#define TXACKINTEN (1<<6)
+#define TXDMADNEN (1<<7) /* reserved for EP0 */
+/* bits 31:8 reserved */
+
+/* TXnBUF bits */
+#define TXFULL (1<<0)
+#define TXURF (1<<1)
+#define TXDS0 (1<<2) /* reserved for EP0 */
+#define TXDS1 (1<<3) /* reserved for EP0 */
+/* bits 31:4 reserved */
+
+/* DMA bits */
+#define DMA_START (1<<0)
+/* bits 31:1 reserved */
+
+/* USB host controller */
+#define AHB0_UHC (ARM_BUS0_BASE + 0x000A4000)
+/* documentation missing */
+
+/* 0x180A8000 - 0x180B0000 reserved */
+
+/* Static/SDRAM memory controller */
+#define AHB0_SDRSTMC (ARM_BUS0_BASE + 0x000B0000)
+#define MCSDR_MODE (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x100))
+#define MCSDR_ADDMAP (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x104))
+#define MCSDR_ADDCFG (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x108))
+#define MCSDR_BASIC (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x10C))
+#define MCSDR_T_REF (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x110))
+#define MCSDR_T_RFC (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x114))
+#define MCSDR_T_MRD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x118))
+#define MCSDR_T_RP (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x120))
+#define MCSDR_T_RCD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x124))
+
+#define MCST0_T_CEWD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x200))
+#define MCST0_T_CE2WE (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x204))
+#define MCST0_WEWD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x208))
+#define MCST0_T_WE2CE (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x20C))
+#define MCST0_T_CEWDR (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x210))
+#define MCST0_T_CE2RD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x214))
+#define MCST0_T_RDWD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x218))
+#define MCST0_T_RD2CE (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x21C))
+#define MCST0_BASIC (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x220))
+
+#define MCST1_T_CEWD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x300))
+#define MCST1_T_CE2WE (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x304))
+#define MCST1_WEWD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x308))
+#define MCST1_T_WE2CE (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x30C))
+#define MCST1_T_CEWDR (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x310))
+#define MCST1_T_CE2RD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x314))
+#define MCST1_T_RDWD (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x318))
+#define MCST1_T_RD2CE (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x31C))
+#define MCST1_BASIC (*(volatile unsigned long *)(AHB0_SDRSTMC + 0x320))
+
+/* 0x180B4000 - 0x180C000 reserved */
+
+/* VIP - video input processor */
+#define AHB0_VIP (ARM_BUS0_BASE + 0x000C0000)
+
+/* 0x180C4000 - 0x180E8000 reserved */
+
+/* NAND flash controller */
+#define AHB0_NANDC (ARM_BUS0_BASE + 0x000E8000)
+
+#define FMCTL (*(volatile unsigned long *)(AHB0_NANDC))
+#define FM_RDY (1<<5) /* status of line R/B# */
+#define FM_PROTECT (1<<4) /* WP# line (active low) */
+/* bits 0-3 are chip selects */
+
+#define FMWAIT (*(volatile unsigned long *)(AHB0_NANDC + 0x04))
+#define FLCTL (*(volatile unsigned long *)(AHB0_NANDC + 0x08))
+#define FL_RDY (1<<12)
+#define FL_COR_EN (1<<11)
+#define FL_INT_EN (1<<10)
+#define FL_XFER_EN (1<<9)
+#define FL_INTCLR_EN (1<<8)
+/* bits 3-7 unknown */
+#define FL_START (1<<2)
+#define FL_WR (1<<1)
+#define FL_RST (1<<0)
+
+#define BCHCTL (*(volatile unsigned long *)(AHB0_NANDC + 0x0C))
+/* bit 13 is used but unknown */
+/* bit 12 is used but unknown */
+#define BCH_WR (1<<1)
+#define BCH_RST (1<<0)
+
+#define BCHST (*(volatile unsigned long *)(AHB0_NANDC + 0xD0))
+/* bit 2 ERR ?? */
+/* bit 0 ?? */
+
+#define FLASH_DATA(n) (*(volatile unsigned char *)(AHB0_NANDC + 0x200 + (n<<9)))
+#define FLASH_ADDR(n) (*(volatile unsigned char *)(AHB0_NANDC + 0x204 + (n<<9)))
+#define FLASH_CMD(n) (*(volatile unsigned char *)(AHB0_NANDC + 0x208 + (n<<9)))
+
+#define PAGE_BUF (*(volatile unsigned char *)(AHB0_NANDC + 0xA00))
+#define SPARE_BUF (*(volatile unsigned char *)(AHB0_NANDC + 0x1200))
+
+#define AHB0_ROM (ARM_BUS0_BASE + 0x000EC000)
+#define AHB0_ES3 (ARM_BUS0_BASE + 0x000F4000)
+#define AHB0_ES4 (ARM_BUS0_BASE + 0x000F8000)
+#define AHB0_ES5 (ARM_BUS0_BASE + 0x000FC000)
+#define AHB0_ES6 (ARM_BUS0_BASE + 0x00100000)
+#define AHB0_EMD_SRAM (ARM_BUS0_BASE + 0x00200000)
+
+/* 0x18204000 - 0x1840000 reserved */
+
+/* 0x18400000 - 0x18484000 reserved*/
+
+#define AHB1_ARBITER 0x18484000
+/* 0x18488000 - 0x186E8000 reserved*/
+
+/* LCD controller */
+#define AHB1_LCDC 0x186E8000
+#define LCDC_CTRL (*(volatile unsigned long *)(AHB1_LCDC + 0x00))
+/* bits 14-31 reserved */
+#define ALPHA24B (1<<13)
+#define UVBUFEXCH (1<<12)
+#define ALPHA(x) (((x)&0x07)<<9)
+#define Y_MIX (1<<8)
+#define LCDC_MCU (1<<7)
+#define RGB24B (1<<6)
+#define START_EVEN (1<<5)
+#define EVEN_EN (1<<4)
+#define RGB_DUMMY(x) (((x)&0x03)<<2)
+#define LCDC_EN (1<<1)
+#define LCDC_STOP (1<<0)
+#define MCU_CTRL (*(volatile unsigned long *)(AHB1_LCDC + 0x04))
+
+#define ALPHA_BASE(x) (((x)&0x3f)<<8)
+#define MCU_CTRL_FIFO_EN (1<<6)
+#define MCU_CTRL_RS_HIGH (1<<5)
+#define MCU_CTRL_BUFF_WRITE (1<<2)
+#define MCU_CTRL_BUFF_START (1<<1)
+#define MCU_CTRL_BYPASS (1<<0)
+
+#define HOR_PERIOD (*(volatile unsigned long *)(AHB1_LCDC + 0x08))
+#define VERT_PERIOD (*(volatile unsigned long *)(AHB1_LCDC + 0x0C))
+#define HOR_PW (*(volatile unsigned long *)(AHB1_LCDC + 0x10))
+#define VERT_PW (*(volatile unsigned long *)(AHB1_LCDC + 0x14))
+#define HOR_BP (*(volatile unsigned long *)(AHB1_LCDC + 0x18))
+#define VERT_BP (*(volatile unsigned long *)(AHB1_LCDC + 0x1C))
+#define HOR_ACT (*(volatile unsigned long *)(AHB1_LCDC + 0x20))
+#define VERT_ACT (*(volatile unsigned long *)(AHB1_LCDC + 0x24))
+#define LINE0_YADDR (*(volatile unsigned long *)(AHB1_LCDC + 0x28))
+#define LINE_ALPHA_EN (1<<14)
+#define LINE_SCALE_EN (1<<13)
+#define LINE_GBR (1<<12)
+#define LINE_RGB (0<<12)
+#define LINE_YUV_SRC (1<<11)
+#define LINE_RGB_SRC (0<<11)
+/* bits 0-10 Y_BASE */
+
+#define LINE0_UVADDR (*(volatile unsigned long *)(AHB1_LCDC + 0x2C))
+#define LINE1_YADDR (*(volatile unsigned long *)(AHB1_LCDC + 0x30))
+#define LINE1_UVADDR (*(volatile unsigned long *)(AHB1_LCDC + 0x34))
+#define LINE2_YADDR (*(volatile unsigned long *)(AHB1_LCDC + 0x38))
+#define LINE2_UVADDR (*(volatile unsigned long *)(AHB1_LCDC + 0x3C))
+#define LINE3_YADDR (*(volatile unsigned long *)(AHB1_LCDC + 0x40))
+#define LINE3_UVADDR (*(volatile unsigned long *)(AHB1_LCDC + 0x44))
+#define START_X (*(volatile unsigned long *)(AHB1_LCDC + 0x48))
+#define START_Y (*(volatile unsigned long *)(AHB1_LCDC + 0x4C))
+#define DELTA_X (*(volatile unsigned long *)(AHB1_LCDC + 0x50))
+#define DELTA_Y (*(volatile unsigned long *)(AHB1_LCDC + 0x54))
+#define LCDC_INTR_MASK (*(volatile unsigned long *)(AHB1_LCDC + 0x58))
+#define INTR_MASK_LINE (1<<3)
+#define INTR_MASK_EVENLINE (0<<3)
+#define INTR_MASK_BUFF (1<<2)
+#define INTR_MASK_VERT (1<<1)
+#define INTR_MASK_HOR (1<<0)
+
+#define ALPHA_ALX (*(volatile unsigned long *)(AHB1_LCDC + 0x5C))
+#define ALPHA_ATY (*(volatile unsigned long *)(AHB1_LCDC + 0x60))
+#define ALPHA_ARX (*(volatile unsigned long *)(AHB1_LCDC + 0x64))
+#define ALPHA_ABY (*(volatile unsigned long *)(AHB1_LCDC + 0x68))
+
+#define ALPHA_BLX (*(volatile unsigned long *)(AHB1_LCDC + 0x6C))
+#define ALPHA_BTY (*(volatile unsigned long *)(AHB1_LCDC + 0x70))
+#define ALPHA_BRX (*(volatile unsigned long *)(AHB1_LCDC + 0x74))
+#define ALPHA_BBY (*(volatile unsigned long *)(AHB1_LCDC + 0x78))
+
+#define LCDC_STA (*(volatile unsigned long *)(AHB1_LCDC + 0x7C))
+#define LCDC_MCU_IDLE (1<<12)
+
+#define LCD_COMMAND (*(volatile unsigned long *)(AHB1_LCDC + 0x1000))
+#define LCD_DATA (*(volatile unsigned long *)(AHB1_LCDC + 0x1004))
+
+#define LCD_BUFF ((volatile void *)(AHB1_LCDC + 0x2000))
+/* High speed ADC interface */
+#define AHB1_HS_ADC 0x186EC000
+#define HSADC_DATA (*(volatile unsigned long *)(AHB1_HS_ADC + 0x00))
+#define HSADC_CTRL (*(volatile unsigned long *)(AHB1_HS_ADC + 0x04))
+#define HSADC_IER (*(volatile unsigned long *)(AHB1_HS_ADC + 0x08))
+#define HSADC_ISR (*(volatile unsigned long *)(AHB1_HS_ADC + 0x0C))
+
+/* AHB-to-AHB DMA controller */
+#define AHB1_DWDMA 0x186F0000
+#define DWDMA_SAR(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x00 + 0x58*n))
+#define DWDMA_DAR(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x08 + 0x58*n))
+#define DWDMA_LLP(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x10 + 0x58*n))
+#define DWDMA_CTL_L(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x18 + 0x58*n))
+#define CTLL_LLP_SRC_EN (1<<28)
+#define CTLL_LLP_DST_EN (1<<27)
+#define CTLL_SMS_M2 (1<<25)
+#define CTLL_SMS_M1 (0<<25)
+#define CTLL_DMS_M2 (1<<23)
+#define CTLL_DMS_M1 (0<<23)
+#define CTLL_FC_PER2PER (3<<20)
+#define CTLL_FC_PER2MEM (2<<20)
+#define CTLL_FC_MEM2PER (1<<20)
+#define CTLL_FC_MEM2MEM (0<<20)
+/* bit 19 reserved */
+#define CTLL_DST_SCATTER_EN (1<<18)
+#define CTLL_SRC_GATHER_EN (1<<17)
+#define CTLL_SRC_MSIZE_32 (4<<14)
+#define CTLL_SRC_MSIZE_16 (3<<14)
+#define CTLL_SRC_MSIZE_8 (2<<14)
+#define CTLL_SRC_MSIZE_4 (1<<14)
+#define CTLL_SRC_MSIZE_1 (0<<14)
+#define CTLL_DST_MSIZE_32 (4<<11)
+#define CTLL_DST_MSIZE_16 (3<<11)
+#define CTLL_DST_MSIZE_8 (2<<11)
+#define CTLL_DST_MSIZE_4 (1<<11)
+#define CTLL_DST_MSIZE_1 (0<<11)
+#define CTLL_SINC_NO (2<<9)
+#define CTLL_SINC_DEC (1<<9)
+#define CTLL_SINC_INC (0<<9)
+#define CTLL_DINC_NO (2<<7)
+#define CTLL_DINC_DEC (1<<7)
+#define CTLL_DINC_INC (0<<7)
+#define CTLL_SRC_TR_WIDTH_32 (2<<4)
+#define CTLL_SRC_TR_WIDTH_16 (1<<4)
+#define CTLL_SRC_TR_WIDTH_8 (0<<4)
+#define CTLL_DST_TR_WIDTH_32 (2<<1)
+#define CTLL_DST_TR_WIDTH_16 (1<<1)
+#define CTLL_DST_TR_WIDTH_8 (0<<1)
+#define CTLL_INT_EN (1<<0)
+
+#define DWDMA_CTL_H(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x1C + 0x58*n))
+#define DWDMA_SSTAT(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x20 + 0x58*n))
+#define DWDMA_DSTAT(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x28 + 0x58*n))
+#define DWDMA_SSTATAR(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x30 + 0x58*n))
+#define DWDMA_DSTATAR(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x38 + 0x58*n))
+#define DWDMA_CFG_L(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x40 + 0x58*n))
+#define CFGL_RELOAD_DST (1<<31)
+#define CFGL_RELOAD_SRC (1<<30)
+#define CFGL_MAX_ABRST(n) ((n)<<20)
+#define CFGL_SRC_HS_POL_LOW (1<<19)
+#define CFGL_DST_HS_POL_LOW (1<<18)
+#define CFGL_LOCK_B (1<<17)
+#define CFGL_LOCK_CH (1<<16)
+#define CFGL_LOCK_B_L(n) (((n)&0x03)<<14)
+#define CFGL_LOCK_CH_L(n) (((n)&0x03)<<12)
+#define CFGL_HS_SEL_SRC (1<<11)
+#define CFGL_HS_SEL_DST (1<<10)
+#define CFGL_FIFO_EMPTY (1<<9)
+#define CFGL_CH_SUSP (1<<8)
+#define CFGL_CH_PRIOR(n) (((n) & 0x03)<<5)
+/* bits 0-4 reserved */
+#define DWDMA_CFG_H(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x44 + 0x58*n))
+#define CFGH_DST_PER(n) (((n)&0x0F)<<11)
+#define CFGH_SRC_PER(n) (((n)&0x0F)<<7)
+#define CFGH_SRC_UPD_EN (1<<6)
+#define CFGH_DST_UPD_EN (1<<5)
+#define CFGH_PROTCTL(n) (((n)&0x07)<<2)
+#define CFGH_FIFO_MODE (1<<1)
+#define CFGH_FC_MODE (1<<0)
+
+#define DWDMA_SGR(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x48 + 0x58*n))
+#define DWDMA_DSR(n) (*(volatile unsigned long *)(AHB1_DWDMA + 0x50 + 0x58*n))
+
+#define DWDMA_RAW_TFR (*(volatile unsigned long *)(AHB1_DWDMA + 0x2C0))
+#define DWDMA_RAW_BLOCK (*(volatile unsigned long *)(AHB1_DWDMA + 0x2C8))
+#define DWDMA_RAW_SRCTRAN (*(volatile unsigned long *)(AHB1_DWDMA + 0x2D0))
+#define DWDMA_RAW_DSTTRAN (*(volatile unsigned long *)(AHB1_DWDMA + 0x2D8))
+#define DWDMA_RAW_ERR (*(volatile unsigned long *)(AHB1_DWDMA + 0x2E0))
+
+#define DWDMA_STATUS_TFR (*(volatile unsigned long *)(AHB1_DWDMA + 0x2E8))
+#define DWDMA_STATUS_BLOCK (*(volatile unsigned long *)(AHB1_DWDMA + 0x2F0))
+#define DWDMA_STATUS_SRCTRAN (*(volatile unsigned long *)(AHB1_DWDMA + 0x2F8))
+#define DWDMA_STATUS_DSTTRAN (*(volatile unsigned long *)(AHB1_DWDMA + 0x300))
+#define DWDMA_STATUS_ERR (*(volatile unsigned long *)(AHB1_DWDMA + 0x308))
+
+#define DWDMA_MASK_TFR (*(volatile unsigned long *)(AHB1_DWDMA + 0x310))
+#define DWDMA_MASK_BLOCK (*(volatile unsigned long *)(AHB1_DWDMA + 0x318))
+#define DWDMA_MASK_SRCTRAN (*(volatile unsigned long *)(AHB1_DWDMA + 0x320))
+#define DWDMA_MASK_DSTTRAN (*(volatile unsigned long *)(AHB1_DWDMA + 0x328))
+#define DWDMA_MASK_ERR (*(volatile unsigned long *)(AHB1_DWDMA + 0x330))
+
+#define DWDMA_CLEAR_TFR (*(volatile unsigned long *)(AHB1_DWDMA + 0x338))
+#define DWDMA_CLEAR_BLOCK (*(volatile unsigned long *)(AHB1_DWDMA + 0x340))
+#define DWDMA_CLEAR_SRCTRAN (*(volatile unsigned long *)(AHB1_DWDMA + 0x348))
+#define DWDMA_CLEAR_DSTTRAN (*(volatile unsigned long *)(AHB1_DWDMA + 0x350))
+#define DWDMA_CLEAR_ERR (*(volatile unsigned long *)(AHB1_DWDMA + 0x358))
+
+#define DWDMA_STATUS_INT (*(volatile unsigned long *)(AHB1_DWDMA + 0x360))
+
+#define DWDMA_REQ_SRC (*(volatile unsigned long *)(AHB1_DWDMA + 0x368))
+#define DWDMA_REQ_DST (*(volatile unsigned long *)(AHB1_DWDMA + 0x370))
+#define DWDMA_S_REQ_SRC (*(volatile unsigned long *)(AHB1_DWDMA + 0x378))
+#define DWDMA_S_REQ_DST (*(volatile unsigned long *)(AHB1_DWDMA + 0x380))
+#define DWDMA_L_REQ_SRC (*(volatile unsigned long *)(AHB1_DWDMA + 0x388))
+#define DWDMA_L_REQ_DST (*(volatile unsigned long *)(AHB1_DWDMA + 0x390))
+
+#define DWDMA_DMA_CFG (*(volatile unsigned long *)(AHB1_DWDMA + 0x398))
+#define GLOB_EN (1<<0)
+#define DWDMA_DMA_CHEN (*(volatile unsigned long *)(AHB1_DWDMA + 0x3A0))
+#define DMACHEN_CH0 (0x101<<0)
+#define DMACHEN_CH1 (0x101<<1)
+#define DMACHEN_CH2 (0x101<<2)
+#define DMACHEN_CH3 (0x101<<3)
+
+/* ARM7 cache controller */
+#define ARM_CACHE_CTRL 0xEFFF0000
+#define DEVID (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x00))
+#define CACHEOP (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x04))
+#define CACHELKDN (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x08))
+
+#define MEMMAPA (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x10))
+#define MEMMAPB (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x14))
+#define MEMMAPC (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x18))
+#define MEMMAPD (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x1C))
+#define PFCNTRA_CTRL (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x20))
+#define PFCNTRA (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x24))
+#define PFCNTRB_CTRL (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x28))
+#define PFCNTRB (*(volatile unsigned long *)(ARM_CACHE_CTRL + 0x2C))
+
+/* Timer frequency */
+#define TIMER_FREQ 50000000
diff --git a/utils/hwstub/stub/rk27xx/target-config.h b/utils/hwstub/stub/rk27xx/target-config.h
new file mode 100644
index 0000000000..6af214efaf
--- /dev/null
+++ b/utils/hwstub/stub/rk27xx/target-config.h
@@ -0,0 +1,9 @@
+#define CONFIG_RK27XX
+#define IRAM_ORIG 0x60000000
+#define IRAM_SIZE 0x8000
+#define DRAM_ORIG 0x60000000
+#define DRAM_SIZE (MEMORYSIZE * 0x100000)
+#define CPU_ARM
+#define ARM_ARCH 5
+#define USB_BASE 0x180A000
+#define USB_NUM_ENDPOINTS 2
diff --git a/utils/hwstub/stub/rk27xx/target.c b/utils/hwstub/stub/rk27xx/target.c
new file mode 100644
index 0000000000..f9efccaef0
--- /dev/null
+++ b/utils/hwstub/stub/rk27xx/target.c
@@ -0,0 +1,172 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 by Marcin Bukat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "stddef.h"
+#include "target.h"
+#include "system.h"
+#include "logf.h"
+#include "rk27xx.h"
+
+#define HZ 1000000
+
+enum rk27xx_family_t
+{
+ UNKNOWN,
+ REV_A,
+ REV_B,
+};
+
+static enum rk27xx_family_t g_rk27xx_family = UNKNOWN;
+static int g_atexit = HWSTUB_ATEXIT_OFF;
+
+static void _enable_irq(void)
+{
+ asm volatile ("mrs r0, cpsr\n"
+ "bic r0, r0, #0x80\n"
+ "msr cpsr_c, r0\n"
+ );
+}
+
+static void power_off(void)
+{
+ GPIO_PCCON &= ~(1<<0);
+ while(1);
+}
+
+static void rk27xx_reset(void)
+{
+ /* use Watchdog to reset */
+ SCU_CLKCFG &= ~CLKCFG_WDT;
+ WDTLR = 1;
+ WDTCON = (1<<4) | (1<<3);
+
+ /* Wait for reboot to kick in */
+ while(1);
+}
+
+/* us may be at most 2^31/200 (~10 seconds) for 200MHz max cpu freq */
+void target_udelay(int us)
+{
+ unsigned cycles_per_us;
+ unsigned delay;
+
+ cycles_per_us = (200000000 + 999999) / 1000000;
+
+ delay = (us * cycles_per_us) / 5;
+
+ asm volatile(
+ "1: subs %0, %0, #1 \n" /* 1 cycle */
+ " nop \n" /* 1 cycle */
+ " bne 1b \n" /* 3 cycles */
+ : : "r"(delay)
+ );
+}
+
+void target_mdelay(int ms)
+{
+ return target_udelay(ms * 1000);
+}
+
+void target_init(void)
+{
+ /* ungate all clocks */
+ SCU_CLKCFG = 0;
+
+ /* keep act line */
+ GPIO_PCDR |= (1<<0);
+ GPIO_PCCON |= (1<<0);
+
+ /* disable watchdog */
+ WDTCON &= ~(1<<3);
+
+ /* enable UDC interrupt */
+ INTC_IMR = (1<<16);
+ INTC_IECR = (1<<16);
+
+ EN_INT = EN_SUSP_INTR | /* Enable Suspend Interrupt */
+ EN_RESUME_INTR | /* Enable Resume Interrupt */
+ EN_USBRST_INTR | /* Enable USB Reset Interrupt */
+ EN_OUT0_INTR | /* Enable OUT Token receive Interrupt EP0 */
+ EN_IN0_INTR | /* Enable IN Token transmits Interrupt EP0 */
+ EN_SETUP_INTR; /* Enable SETUP Packet Receive Interrupt */
+
+ /* 6. configure INTCON */
+ INTCON = UDC_INTHIGH_ACT | /* interrupt high active */
+ UDC_INTEN; /* enable EP0 interrupts */
+
+ /* enable irq */
+ _enable_irq();
+
+ /* detect revision */
+ uint32_t rk27xx_id = SCU_ID;
+
+ if(rk27xx_id == 0xa1000604)
+ {
+ logf("identified rk27xx REV_A \n");
+ g_rk27xx_family = REV_A;
+ }
+ else if(rk27xx_id == 0xa100027b)
+ {
+ logf("identified rk27xx REV_B \n");
+ g_rk27xx_family = REV_B;
+ }
+ else
+ {
+ logf("unknown rk27xx revision \n");
+ }
+}
+
+static struct usb_resp_info_target_t g_target =
+{
+ .id = HWSTUB_TARGET_RK27,
+ .name = "Rockchip RK27XX"
+};
+
+int target_get_info(int info, void **buffer)
+{
+ if(info == HWSTUB_INFO_TARGET)
+ {
+ *buffer = &g_target;
+ return sizeof(g_target);
+ }
+ else
+ return -1;
+}
+
+int target_atexit(int method)
+{
+ g_atexit = method;
+ return 0;
+}
+
+void target_exit(void)
+{
+ switch(g_atexit)
+ {
+ case HWSTUB_ATEXIT_OFF:
+ power_off();
+ // fallthrough in case of return
+ case HWSTUB_ATEXIT_REBOOT:
+ rk27xx_reset();
+ // fallthrough in case of return
+ case HWSTUB_ATEXIT_NOP:
+ default:
+ return;
+ }
+}
diff --git a/utils/hwstub/stub/rk27xx/usb_drv_rk27xx.c b/utils/hwstub/stub/rk27xx/usb_drv_rk27xx.c
new file mode 100644
index 0000000000..6a9293334a
--- /dev/null
+++ b/utils/hwstub/stub/rk27xx/usb_drv_rk27xx.c
@@ -0,0 +1,313 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2011 by Marcin Bukat
+ * Copyright (C) 2012 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "usb_drv.h"
+#include "config.h"
+#include "memory.h"
+#include "target.h"
+#include "rk27xx.h"
+
+typedef volatile uint32_t reg32;
+
+#define USB_FULL_SPEED 0
+#define USB_HIGH_SPEED 1
+
+/* max allowed packet size definitions */
+#define CTL_MAX_SIZE 64
+
+struct endpoint_t {
+ const int type; /* EP type */
+ const int dir; /* DIR_IN/DIR_OUT */
+ const unsigned int intr_mask;
+ bool allocated; /* flag to mark EPs taken */
+ volatile void *buf; /* tx/rx buffer address */
+ volatile int len; /* size of the transfer (bytes) */
+ volatile int cnt; /* number of bytes transfered/received */
+};
+
+static struct endpoint_t ctrlep[2] = {
+ {USB_ENDPOINT_XFER_CONTROL, DIR_OUT, 0, true, NULL, 0, 0},
+ {USB_ENDPOINT_XFER_CONTROL, DIR_IN, 0, true, NULL, 0, 0}
+};
+
+volatile bool setup_data_valid = false;
+static volatile uint32_t setup_data[2];
+
+static volatile bool usb_drv_send_done = false;
+
+void usb_drv_configure_endpoint(int ep_num, int type)
+{
+ /* not needed as we use EP0 only */
+ (void)ep_num;
+ (void)type;
+}
+
+int usb_drv_recv_setup(struct usb_ctrlrequest *req)
+{
+ while (!setup_data_valid)
+ ;
+
+ memcpy(req, (void *)setup_data, sizeof(struct usb_ctrlrequest));
+ setup_data_valid = false;
+ return 0;
+}
+
+static void setup_irq_handler(void)
+{
+ /* copy setup data from packet */
+ setup_data[0] = SETUP1;
+ setup_data[1] = SETUP2;
+
+ /* ack upper layer we have setup data */
+ setup_data_valid = true;
+}
+
+/* service ep0 IN transaction */
+static void ctr_write(void)
+{
+ int xfer_size = MIN(ctrlep[DIR_IN].cnt, CTL_MAX_SIZE);
+
+ while (TX0BUF & TXFULL) /* TX0FULL flag */
+ ;
+
+ TX0STAT = xfer_size; /* size of the transfer */
+ TX0DMALM_IADDR = (uint32_t)ctrlep[DIR_IN].buf; /* local buffer address */
+ TX0DMAINCTL = DMA_START; /* start DMA */
+ TX0CON &= ~TXNAK; /* clear NAK */
+
+ /* Decrement by max packet size is intentional.
+ * This way if we have final packet short one we will get negative len
+ * after transfer, which in turn indicates we *don't* need to send
+ * zero length packet. If the final packet is max sized packet we will
+ * get zero len after transfer which indicates we need to send
+ * zero length packet to signal host end of the transfer.
+ */
+ ctrlep[DIR_IN].cnt -= CTL_MAX_SIZE;
+ ctrlep[DIR_IN].buf += xfer_size;
+}
+
+static void ctr_read(void)
+{
+ int xfer_size = RX0STAT & 0xffff;
+
+ /* clear NAK bit */
+ RX0CON &= ~RXNAK;
+
+ ctrlep[DIR_OUT].cnt -= xfer_size;
+ ctrlep[DIR_OUT].buf += xfer_size;
+
+ RX0DMAOUTLMADDR = (uint32_t)ctrlep[DIR_OUT].buf; /* buffer address */
+ RX0DMACTLO = DMA_START; /* start DMA */
+}
+
+static void udc_phy_reset(void)
+{
+ DEV_CTL |= SOFT_POR;
+ target_mdelay(10); /* min 10ms */
+ DEV_CTL &= ~SOFT_POR;
+}
+
+static void udc_soft_connect(void)
+{
+ DEV_CTL |= CSR_DONE |
+ DEV_SOFT_CN |
+ DEV_SELF_PWR;
+}
+
+/* return port speed */
+int usb_drv_port_speed(void)
+{
+ return ((DEV_INFO & DEV_SPEED) ? USB_FULL_SPEED : USB_HIGH_SPEED);
+}
+
+/* Set the address (usually it's in a register).
+ * There is a problem here: some controller want the address to be set between
+ * control out and ack and some want to wait for the end of the transaction.
+ * In the first case, you need to write some code special code when getting
+ * setup packets and ignore this function (have a look at other drives)
+ */
+void usb_drv_set_address(int address)
+{
+ (void)address;
+ /* UDC sets this automaticaly */
+}
+
+int usb_drv_send(int endpoint, void *ptr, int length)
+{
+ (void)endpoint;
+ struct endpoint_t *ep = &ctrlep[DIR_IN];
+
+ ep->buf = ptr;
+ ep->len = ep->cnt = length;
+
+ ctr_write();
+
+ /* wait for transfer to end */
+ while(!usb_drv_send_done)
+ ;
+
+ usb_drv_send_done = false;
+
+ return 0;
+}
+
+/* Setup a receive transfer. (non blocking) */
+int usb_drv_recv(int endpoint, void* ptr, int length)
+{
+ (void)endpoint;
+ struct endpoint_t *ep = &ctrlep[DIR_OUT];
+
+ ep->buf = ptr;
+ ep->len = ep->cnt = length;
+
+ /* clear NAK bit */
+ RX0CON &= ~RXNAK;
+ RX0DMAOUTLMADDR = (uint32_t)ptr; /* buffer address */
+ RX0DMACTLO = DMA_START; /* start DMA */
+
+ return 0;
+}
+
+/* Stall the endpoint. Usually set a flag in the controller */
+void usb_drv_stall(int endpoint, bool stall, bool in)
+{
+ /* ctrl only anyway */
+ (void)endpoint;
+
+ if(in)
+ {
+ if(stall)
+ TX0CON |= TXSTALL;
+ else
+ TX0CON &= ~TXSTALL;
+ }
+ else
+ {
+ if (stall)
+ RX0CON |= RXSTALL;
+ else
+ RX0CON &= ~RXSTALL; /* doc says Auto clear by UDC 2.0 */
+ }
+}
+
+/* one time init (once per connection) - basicaly enable usb core */
+void usb_drv_init(void)
+{
+ udc_phy_reset();
+ target_mdelay(10); /* wait at least 10ms */
+ udc_soft_connect();
+
+ EN_INT = EN_SUSP_INTR | /* Enable Suspend Irq */
+ EN_RESUME_INTR | /* Enable Resume Irq */
+ EN_USBRST_INTR | /* Enable USB Reset Irq */
+ EN_OUT0_INTR | /* Enable OUT Token receive Irq EP0 */
+ EN_IN0_INTR | /* Enable IN Token transmit Irq EP0 */
+ EN_SETUP_INTR; /* Enable SETUP Packet Receive Irq */
+
+ INTCON = UDC_INTHIGH_ACT | /* interrupt high active */
+ UDC_INTEN; /* enable EP0 irqs */
+}
+
+/* turn off usb core */
+void usb_drv_exit(void)
+{
+ /* udc module reset */
+ SCU_RSTCFG |= (1<<1);
+ target_udelay(10);
+ SCU_RSTCFG &= ~(1<<1);
+}
+
+/* UDC ISR function */
+void INT_UDC(void)
+{
+ uint32_t txstat, rxstat;
+
+ /* read what caused UDC irq */
+ uint32_t intsrc = INT2FLAG & 0x7fffff;
+
+ if (intsrc & USBRST_INTR) /* usb reset */
+ {
+ EN_INT = EN_SUSP_INTR | /* Enable Suspend Irq */
+ EN_RESUME_INTR | /* Enable Resume Irq */
+ EN_USBRST_INTR | /* Enable USB Reset Irq */
+ EN_OUT0_INTR | /* Enable OUT Token receive Irq EP0 */
+ EN_IN0_INTR | /* Enable IN Token transmit Irq EP0 */
+ EN_SETUP_INTR; /* Enable SETUP Packet Receive Irq */
+
+ TX0CON = TXACKINTEN | /* Set as one to enable the EP0 tx irq */
+ TXNAK; /* Set as one to response NAK handshake */
+
+ RX0CON = RXACKINTEN |
+ RXEPEN | /* Endpoint 0 Enable. When cleared the
+ * endpoint does not respond to an SETUP
+ * or OUT token */
+ RXNAK; /* Set as one to response NAK handshake */
+ }
+
+ if (intsrc & SETUP_INTR) /* setup interrupt */
+ {
+ setup_irq_handler();
+ }
+
+ if (intsrc & IN0_INTR) /* ep0 in interrupt */
+ {
+ txstat = TX0STAT; /* read clears flags */
+
+ /* TODO handle errors */
+ if (txstat & TXACK) /* check TxACK flag */
+ {
+ if (ctrlep[DIR_IN].cnt > 0)
+ {
+ /* we still have data to send */
+ ctr_write();
+ }
+ else
+ {
+ if (ctrlep[DIR_IN].cnt == 0)
+ ctr_write();
+
+ /* final ack received */
+ usb_drv_send_done = true;
+ }
+ }
+ }
+
+ if (intsrc & OUT0_INTR) /* ep0 out interrupt */
+ {
+ rxstat = RX0STAT;
+
+ /* TODO handle errors */
+ if (rxstat & RXACK) /* RxACK */
+ {
+ if (ctrlep[DIR_OUT].cnt > 0)
+ ctr_read();
+ }
+ }
+
+ if (intsrc & RESUME_INTR) /* usb resume */
+ {
+ TX0CON |= TXCLR; /* TxClr */
+ TX0CON &= ~TXCLR;
+
+ RX0CON |= RXCLR; /* RxClr */
+ RX0CON &= ~RXCLR;
+ }
+}
diff --git a/utils/hwstub/stub/crt0.S b/utils/hwstub/stub/stmp/crt0.S
index 8b2197823e..8b2197823e 100644
--- a/utils/hwstub/stub/crt0.S
+++ b/utils/hwstub/stub/stmp/crt0.S
diff --git a/utils/hwstub/stub/hwstub.lds b/utils/hwstub/stub/stmp/hwstub.lds
index 549e4ab96c..8e3f4e68ba 100644
--- a/utils/hwstub/stub/hwstub.lds
+++ b/utils/hwstub/stub/stmp/hwstub.lds
@@ -23,7 +23,7 @@
ENTRY(start)
OUTPUT_FORMAT(elf32-littlearm)
OUTPUT_ARCH(arm)
-STARTUP(crt0.o)
+STARTUP(stmp/crt0.o)
#define IRAM_END_ADDR (IRAM_ORIG + IRAM_SIZE)