diff --git a/bootloader/SOURCES b/bootloader/SOURCES index 3e173386e7..9448515a58 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES @@ -69,4 +69,7 @@ main-pp.c show_logo.c #elif defined(MPIO_HD200) || defined(MPIO_HD300) mpio_hd200_hd300.c +#elif defined(RK27_GENERIC) +rk27xx.c +show_logo.c #endif diff --git a/bootloader/rk27xx.c b/bootloader/rk27xx.c new file mode 100644 index 0000000000..37778db6dc --- /dev/null +++ b/bootloader/rk27xx.c @@ -0,0 +1,45 @@ +#include "config.h" +#include +#include +#include +#include "inttypes.h" +#include "string.h" +#include "cpu.h" +#include "system.h" +#include "lcd.h" +#include "kernel.h" +#include "thread.h" +#include "backlight.h" +#include "backlight-target.h" +#include "font.h" +#include "common.h" +#include "version.h" + +extern int show_logo( void ); +void main(void) +{ + + _backlight_init(); + + system_init(); + kernel_init(); + enable_irq(); + + lcd_init_device(); + _backlight_on(); + font_init(); + lcd_setfont(FONT_SYSFIXED); + + show_logo(); + sleep(HZ*2); + + while(1) + { + reset_screen(); + printf("GPIOA: 0x%0x", GPIO_PADR); + printf("GPIOB: 0x%0x", GPIO_PBDR); + printf("GPIOC: 0x%0x", GPIO_PCDR); + printf("GPIOD: 0x%0x", GPIO_PDDR); + sleep(HZ/10); + } +} diff --git a/firmware/SOURCES b/firmware/SOURCES index 6d4ef9fe2b..eee0c864eb 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -210,6 +210,9 @@ target/arm/ata-nand-telechips.c #if (CONFIG_STORAGE & STORAGE_NAND) && (CONFIG_NAND == NAND_SAMSUNG) target/arm/s5l8700/ata-nand-s5l8700.c #endif +#if (CONFIG_STORAGE & STORAGE_NAND) && (CONFIG_NAND == NAND_RK27XX) +target/arm/rk27xx/ata-nand-rk27xx.c +#endif #if (CONFIG_STORAGE & STORAGE_ATA) && !defined(IPOD_6G) drivers/ata.c #endif @@ -473,6 +476,8 @@ target/arm/i2c-telechips.c target/arm/s5l8700/i2c-s5l8700.c #elif CONFIG_I2C == I2C_S5L8702 target/arm/s5l8702/i2c-s5l8702.c +#elif CONFIG_I2C == I2C_RK27XX +target/arm/rk27xx/i2c-rk27xx.c #endif #if CONFIG_CPU == PNX0101 @@ -562,6 +567,8 @@ target/arm/s5l8700/crt0.S target/arm/s5l8702/crt0.S #elif CONFIG_CPU==IMX233 target/arm/imx233/crt0.S +#elif CONFIG_CPU==RK27XX +target/arm/rk27xx/crt0.S #elif defined(CPU_ARM) target/arm/crt0.S #endif /* defined(CPU_*) */ @@ -1604,6 +1611,23 @@ target/arm/s5l8702/ipod6g/adc-ipod6g.c #endif #endif +#ifndef SIMULATOR +#if CONFIG_CPU == RK27XX +target/arm/rk27xx/kernel-rk27xx.c +target/arm/rk27xx/system-rk27xx.c +target/arm/rk27xx/timer-rk27xx.c +target/arm/rk27xx/backlight-rk27xx.c +target/arm/rk27xx/lcd-rk27xx.c +target/arm/rk27xx/adc-rk27xx.c +target/arm/rk27xx/sd-rk27xx.c +target/arm/rk27xx/ftl-rk27xx.c +#endif + +#if defined(RK27_GENERIC) +target/arm/rk27xx/rk27generic/button-rk27generic.c +#endif +#endif + #ifndef SIMULATOR #if CONFIG_CPU == JZ4732 target/mips/ingenic_jz47xx/ata-nand-jz4740.c diff --git a/firmware/export/config.h b/firmware/export/config.h index 003f68335a..2c7c6e89db 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -75,6 +75,7 @@ #define AT91SAM9260 9260 #define AS3525v2 35252 #define IMX233 233 +#define RK27XX 2700 /* platforms * bit fields to allow PLATFORM_HOSTED to be OR'ed e.g. with a @@ -222,6 +223,7 @@ #define LCD_VIBE500 39 /* as used by the Packard Bell Vibe 500 */ #define LCD_IPOD6G 40 /* as used by the iPod Nano 2nd Generation */ #define LCD_FUZEPLUS 41 +#define LCD_SPFD5420A 42 /* rk27xx */ /* LCD_PIXELFORMAT */ #define HORIZONTAL_PACKING 1 @@ -260,6 +262,7 @@ Lyre prototype 1 */ #define I2C_AS3525 15 #define I2C_S5L8702 16 /* Same as S5L8700, but with two channels */ #define I2C_IMX233 17 +#define I2C_RK27XX 18 /* CONFIG_LED */ #define LED_REAL 1 /* SW controlled LED (Archos recorders, player) */ @@ -271,6 +274,7 @@ Lyre prototype 1 */ #define NAND_TCC 2 #define NAND_SAMSUNG 3 #define NAND_CC 4 /* ChinaChip */ +#define NAND_RK27XX 5 /* CONFIG_RTC */ #define RTC_M41ST84W 1 /* Archos Recorder */ @@ -448,6 +452,8 @@ Lyre prototype 1 */ #include "config/mpiohd200.h" #elif defined(MPIO_HD300) #include "config/mpiohd300.h" +#elif defined(RK27_GENERIC) +#include "config/rk27generic.h" #elif defined(SDLAPP) #include "config/sdlapp.h" #elif defined(ANDROID) @@ -533,8 +539,8 @@ Lyre prototype 1 */ #elif defined(CPU_TCC77X) || defined(CPU_TCC780X) || (CONFIG_CPU == DM320) \ || (CONFIG_CPU == AT91SAM9260) || (CONFIG_CPU == AS3525v2) \ - || (CONFIG_CPU == S5L8702) || (CONFIG_PLATFORM & PLATFORM_ANDROID) \ - || (CONFIG_CPU == IMX233) + || (CONFIG_CPU == S5L8702) || (CONFIG_CPU == IMX233) \ + || (CONFIG_CPU == RK27XX) ||(CONFIG_PLATFORM & PLATFORM_ANDROID) #define CPU_ARM #define ARM_ARCH 5 /* ARMv5 */ @@ -774,7 +780,8 @@ Lyre prototype 1 */ #if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) \ || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \ || defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \ - || defined(APPLICATION) || (CONFIG_CPU == PP5002) + || defined(APPLICATION) || (CONFIG_CPU == PP5002) \ + || (CONFIG_CPU == RK27XX) #define HAVE_SEMAPHORE_OBJECTS #endif diff --git a/firmware/export/config/rk27generic.h b/firmware/export/config/rk27generic.h new file mode 100644 index 0000000000..5427d1fed4 --- /dev/null +++ b/firmware/export/config/rk27generic.h @@ -0,0 +1,175 @@ +/* + * This config file is for Rockchip rk27xx reference design + */ +#define TARGET_TREE /* this target is using the target tree system */ + +/* For Rolo and boot loader */ +#define MODEL_NUMBER 78 + +#define MODEL_NAME "Rockchip 27xx generic" + +/* define this if you have recording possibility */ +/* #define HAVE_RECORDING */ + +/* Define bitmask of input sources - recordable bitmask can be defined + explicitly if different */ +#define INPUT_SRC_CAPS (SRC_CAP_LINEIN) + +/* define the bitmask of hardware sample rates */ +#define HW_SAMPR_CAPS (SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11 \ + | SAMPR_CAP_48 | SAMPR_CAP_24 | SAMPR_CAP_12 \ + | SAMPR_CAP_32 | SAMPR_CAP_16 | SAMPR_CAP_8) + +/* define the bitmask of recording sample rates */ +#define REC_SAMPR_CAPS (SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11 \ + | SAMPR_CAP_48 | SAMPR_CAP_24 | SAMPR_CAP_12 \ + | SAMPR_CAP_32 | SAMPR_CAP_16 | SAMPR_CAP_8) + +/* define this if you have a bitmap LCD display */ +#define HAVE_LCD_BITMAP + +/* define this if you can flip your LCD */ +/* #define HAVE_LCD_FLIP */ + +/* define this if you have a colour LCD */ +#define HAVE_LCD_COLOR + +/* define this if you want album art for this target */ +#define HAVE_ALBUMART + +/* define this to enable bitmap scaling */ +#define HAVE_BMP_SCALING + +/* define this to enable JPEG decoding */ +#define HAVE_JPEG + +/* define this if you can invert the colours on your LCD */ +/* #define HAVE_LCD_INVERT */ + +/* define this if you have access to the quickscreen */ +#define HAVE_QUICKSCREEN + +/* define this if you have access to the pitchscreen */ +#define HAVE_PITCHSCREEN + +/* define this if you would like tagcache to build on this target */ +#define HAVE_TAGCACHE + +/* define this if you have a flash memory storage */ +#define HAVE_FLASH_STORAGE + +#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) + +#define CONFIG_NAND NAND_RK27XX + +/* commented for now */ +/* #define HAVE_HOTSWAP */ + +#define NUM_DRIVES 2 +#define SECTOR_SIZE 512 + +/* for small(ish) SD cards */ +#define HAVE_FAT16SUPPORT + +/* LCD dimensions */ +#define LCD_WIDTH 400 +#define LCD_HEIGHT 240 +#define LCD_DEPTH 16 /* pseudo 262.144 colors */ +#define LCD_PIXELFORMAT RGB565 /* rgb565 */ + +/* Define this if the LCD can shut down */ +/* #define HAVE_LCD_SHUTDOWN */ + +/* Define this if your LCD can be enabled/disabled */ +/* #define HAVE_LCD_ENABLE */ + +/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE + should be defined as well. */ +#ifndef BOOTLOADER +/* TODO: #define HAVE_LCD_SLEEP */ +/* TODO: #define HAVE_LCD_SLEEP_SETTING */ +#endif + +#define CONFIG_KEYPAD IPOD_4G_PAD + +/* Define this to enable morse code input */ +#define HAVE_MORSE_INPUT + +/* Define this if you do software codec */ +#define CONFIG_CODEC SWCODEC + +/* define this if you have a real-time clock */ +/* #define CONFIG_RTC RTC_NANO2G */ + +/* Define if the device can wake from an RTC alarm */ +/* #define HAVE_RTC_ALARM */ + +#define CONFIG_LCD LCD_SPFD5420A + +/* Define the type of audio codec */ +/* #define HAVE_RK27XX_CODEC */ + +/* #define HAVE_PCM_DMA_ADDRESS */ + +/* Define this for LCD backlight available */ +#define HAVE_BACKLIGHT + +/* Doesn't work so comment it out for now */ +/* #define HAVE_BACKLIGHT_BRIGHTNESS */ + +/* Define this if you have a software controlled poweroff */ +#define HAVE_SW_POWEROFF + +/* The number of bytes reserved for loadable codecs */ +#define CODEC_SIZE 0x100000 + +/* The number of bytes reserved for loadable plugins */ +#define PLUGIN_BUFFER_SIZE 0x80000 + +/* TODO: Figure out real values */ +#define BATTERY_CAPACITY_DEFAULT 400 /* default battery capacity */ +#define BATTERY_CAPACITY_MIN 300 /* min. capacity selectable */ +#define BATTERY_CAPACITY_MAX 500 /* max. capacity selectable */ +#define BATTERY_CAPACITY_INC 10 /* capacity increment */ +#define BATTERY_TYPES_COUNT 1 /* only one type */ + +/* Hardware controlled charging with monitoring */ +#define CONFIG_CHARGING CHARGING_MONITOR + +/* define current usage levels */ +/* TODO: #define CURRENT_NORMAL + * TODO: #define CURRENT_BACKLIGHT 23 + */ + +/* define this if the unit can be powered or charged via USB */ +#define HAVE_USB_POWER + +/* Define this if your LCD can set contrast */ +/* #define HAVE_LCD_CONTRAST */ + +/* The exact type of CPU */ +#define CONFIG_CPU RK27XX + +/* I2C interface */ +#define CONFIG_I2C I2C_RK27XX + +/* Define this to the CPU frequency */ +#define CPU_FREQ 200000000 + +/* define this if the hardware can be powered off while charging */ +#define HAVE_POWEROFF_WHILE_CHARGING + +/* Offset ( in the firmware file's header ) to the file CRC */ +#define FIRMWARE_OFFSET_FILE_CRC 0 + +/* Offset ( in the firmware file's header ) to the real data */ +#define FIRMWARE_OFFSET_FILE_DATA 8 + +#define STORAGE_NEEDS_ALIGN + +/* Define this if you have adjustable CPU frequency */ +/* #define HAVE_ADJUSTABLE_CPU_FREQ */ + +#define BOOTFILE_EXT "rk27" +#define BOOTFILE "rockbox." BOOTFILE_EXT +#define BOOTDIR "/.rockbox" diff --git a/firmware/export/cpu.h b/firmware/export/cpu.h index 777e36f62d..7405319822 100644 --- a/firmware/export/cpu.h +++ b/firmware/export/cpu.h @@ -77,3 +77,6 @@ #if CONFIG_CPU == IMX233 #include "imx233.h" #endif +#if CONFIG_CPU == RK27XX +#include "rk27xx.h" +#endif diff --git a/firmware/export/i2c-rk27xx.h b/firmware/export/i2c-rk27xx.h new file mode 100644 index 0000000000..96baf566a7 --- /dev/null +++ b/firmware/export/i2c-rk27xx.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bertrik Sikken + * + * 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. + * + ****************************************************************************/ + +#ifndef _I2C_RK27XX_H +#define _I2C_RK27XX_H + +#include "config.h" + +void i2c_init(void); +int i2c_write(unsigned char slave, int address, int len, const unsigned char *data); +int i2c_read(unsigned char slave, int address, int len, unsigned char *data); + +#endif /* _I2C_RK27XX_H */ + diff --git a/firmware/export/rk27xx.h b/firmware/export/rk27xx.h new file mode 100644 index 0000000000..a5cd396a33 --- /dev/null +++ b/firmware/export/rk27xx.h @@ -0,0 +1,1022 @@ +/* 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 SCU_RSTCFG (*(volatile unsigned long *)(APB0_SCU + 0x1C)) +#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 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_INFO (*(volatile unsigned long *)(AHB0_UDC + 0x10)) +#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) +/* bit 7 reserved */ +#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 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 RX0FFRC (1<<0) +#define RX0CLR (1<<1) +#define RX0STALL (1<<2) +#define RX0NAK (1<<3) +#define EP0EN (1<<4) +#define RX0VOIDINTEN (1<<5) +#define RX0ERRINTEN (1<<6) +#define RX0ACKINTEN (1<<7) +/* bits 8-31 reserved */ + +#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 TX0CLR (1<<0) +#define TX0STALL (1<<1) +#define TX0NAK (1<<2) +/* bit 3 reserved */ +#define TX0VOIDINTEN (1<<4) +#define TX0ERRINTEN (1<<5) +#define TX0ACKINTEN (1<<6) +/* bits 7-31 reserved */ + +#define TX0BUF (*(volatile unsigned long *)(AHB0_UDC + 0x48)) +#define TX0FULL (1<<0) +#define TX0URF (1<<1) +/* bits 2-31 reserved */ + +#define TX0DMAINCTL (*(volatile unsigned long *)(AHB0_UDC + 0x4C)) +#define TX0DMAINSTA (1<<0) +/* bits 1-31 reserved */ + +#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)) + +/* 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_ACT (*(volatile unsigned long *)(AHB1_LCDC + 0x18)) +#define VERT_ACT (*(volatile unsigned long *)(AHB1_LCDC + 0x1C)) +#define HOR_BP (*(volatile unsigned long *)(AHB1_LCDC + 0x20)) +#define VERT_BP (*(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 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 unsigned long *)(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_CNTRL 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)) + diff --git a/firmware/target/arm/rk27xx/adc-rk27xx.c b/firmware/target/arm/rk27xx/adc-rk27xx.c new file mode 100644 index 0000000000..c8bbae7514 --- /dev/null +++ b/firmware/target/arm/rk27xx/adc-rk27xx.c @@ -0,0 +1,47 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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 "config.h" +#include "cpu.h" +#include "system.h" +#include "kernel.h" +#include "thread.h" +#include "adc.h" + +unsigned int adc_scan(int channel) +{ + ADC_CTRL = (1<<4) | (1<<3) | (channel & (NUM_ADC_CHANNELS - 1)); + + /* wait for conversion ready ~10us */ + while (ADC_STAT & 0x01); + + /* 10bits result */ + return (ADC_DATA & 0x3ff); +} + +void adc_init(void) +{ + /* ADC clock divider to reach max 1MHz */ + SCU_DIVCON1 = (SCU_DIVCON1 & ~(0xff<<10)) | (49<<10); + + /* enable clocks for ADC */ + SCU_CLKCFG |= 3<<23; +} diff --git a/firmware/target/arm/rk27xx/adc-target.h b/firmware/target/arm/rk27xx/adc-target.h new file mode 100644 index 0000000000..f6b8c98bb9 --- /dev/null +++ b/firmware/target/arm/rk27xx/adc-target.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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. + * + ****************************************************************************/ +#ifndef _ADC_TARGET_H_ +#define _ADC_TARGET_H_ + +#define NUM_ADC_CHANNELS 4 + +#define ADC_BATTERY 0 +#define ADC_UNKNOWN_1 1 +#define ADC_UNKNOWN_2 2 +#define ADC_VREF 3 /* that is what datasheet says */ + +#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */ + +#endif diff --git a/firmware/target/arm/rk27xx/ata-nand-rk27xx.c b/firmware/target/arm/rk27xx/ata-nand-rk27xx.c new file mode 100644 index 0000000000..dad49d48d2 --- /dev/null +++ b/firmware/target/arm/rk27xx/ata-nand-rk27xx.c @@ -0,0 +1,118 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 Dave Chapman + * + * 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 "config.h" +#include "system.h" +#include +#include "thread.h" +#include "disk.h" +#include "storage.h" +#include "panic.h" +#include "usb.h" +#include "ftl-target.h" +#include "nand-target.h" + +/* This file provides only STUBS for now */ + +/** static, private data **/ +static bool initialized = false; + +/* API Functions */ +int nand_read_sectors(IF_MD2(int drive,) unsigned long start, int incount, + void* inbuf) +{ + (void)drive; + return ftl_read(start, incount, inbuf); +} + +int nand_write_sectors(IF_MD2(int drive,) unsigned long start, int count, + const void* outbuf) +{ + (void)drive; + return ftl_write(start, count, outbuf); +} + +void nand_spindown(int seconds) +{ + (void)seconds; +} + +void nand_sleep(void) +{ + nand_power_down(); +} + +void nand_sleepnow(void) +{ + nand_power_down(); +} + +void nand_spin(void) +{ + nand_set_active(); +} + +void nand_enable(bool on) +{ + (void)on; +} + +void nand_get_info(IF_MD2(int drive,) struct storage_info *info) +{ + (void)drive; + uint32_t ppb = ftl_banks * (*ftl_nand_type).pagesperblock; + (*info).sector_size = SECTOR_SIZE; + (*info).num_sectors = (*ftl_nand_type).userblocks * ppb; + (*info).vendor = "Apple"; + (*info).product = "iPod Nano 2G"; + (*info).revision = "1.0"; +} + +long nand_last_disk_activity(void) +{ + return nand_last_activity(); +} + +#ifdef HAVE_STORAGE_FLUSH +int nand_flush(void) +{ + int rc = ftl_sync(); + if (rc != 0) panicf("Failed to unmount flash: %X", rc); + return rc; +} +#endif + +int nand_init(void) +{ + if (ftl_init()) return 1; + + initialized = true; + return 0; +} + +#ifdef CONFIG_STORAGE_MULTI +int nand_num_drives(int first_drive) +{ + /* We don't care which logical drive number(s) we have been assigned */ + (void)first_drive; + + return 1; +} +#endif diff --git a/firmware/target/arm/rk27xx/backlight-rk27xx.c b/firmware/target/arm/rk27xx/backlight-rk27xx.c new file mode 100644 index 0000000000..0d871924ea --- /dev/null +++ b/firmware/target/arm/rk27xx/backlight-rk27xx.c @@ -0,0 +1,86 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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 + +#include "config.h" +#include "backlight.h" +#include "backlight-target.h" +#include "system.h" + +bool _backlight_init(void) +{ + /* configure PD4 as output */ + GPIO_PDCON |= (1<<4); + + /* set PD4 low (backlight off) */ + GPIO_PDDR &= ~(1<<4); + + /* IOMUXB - set PWM0 pin as GPIO */ + SCU_IOMUXB_CON &= ~(1 << 11); /* type<<11< ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Marcoen Hirschberg + * + * 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. + * + ****************************************************************************/ +#ifndef BACKLIGHT_TARGET_H +#define BACKLIGHT_TARGET_H + +bool _backlight_init(void); +void _backlight_on(void); +void _backlight_off(void); +void _backlight_set_brightness(int brightness); + +#endif diff --git a/firmware/target/arm/rk27xx/boot.lds b/firmware/target/arm/rk27xx/boot.lds new file mode 100644 index 0000000000..b7bc9beac0 --- /dev/null +++ b/firmware/target/arm/rk27xx/boot.lds @@ -0,0 +1,81 @@ +#include "config.h" + +ENTRY(start) +#ifdef ROCKBOX_LITTLE_ENDIAN +OUTPUT_FORMAT(elf32-littlearm) +#else +OUTPUT_FORMAT(elf32-bigarm) +#endif +OUTPUT_ARCH(arm) +STARTUP(target/arm/rk27xx/crt0.o) + +#define DRAMORIG 0x60000000 +#define DRAMSIZE (MEMORYSIZE * 0x100000) + +#define IRAMORIG 0x00000000 +#define IRAMSIZE 4K + +MEMORY +{ + DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE + IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE +} + +SECTIONS +{ + .intvect : { + _intvectstart = . ; + *(.intvect) + _intvectend = _newstart ; + } > IRAM AT > DRAM + _intvectcopy = LOADADDR(.intvect) ; + + .text : { + *(.init.text) + *(.text*) + *(.glue_7*) + } > DRAM + + .data : { + *(.rodata*) + *(.data*) + *(.ncdata*); + . = ALIGN(0x4); + } > DRAM + + .idata : { + _datastart = . ; + *(.irodata) + *(.icode) + *(.idata) + . = ALIGN(0x4); + _dataend = . ; + } > DRAM + _datacopy = LOADADDR(.idata) ; + + .stack (NOLOAD) : + { + *(.stack) + _stackbegin = .; + stackbegin = .; + . += 0x2000; + _stackend = .; + stackend = .; + _irqstackbegin = .; + . += 0x400; + _irqstackend = .; + _fiqstackbegin = .; + . += 0x400; + _fiqstackend = .; + } > DRAM + + .bss (NOLOAD) : { + _edata = .; + *(.bss*); + *(.ibss); + *(.ncbss*); + *(COMMON); + . = ALIGN(0x4); + _end = .; + } > DRAM +} diff --git a/firmware/target/arm/rk27xx/crt0.S b/firmware/target/arm/rk27xx/crt0.S new file mode 100644 index 0000000000..032c637458 --- /dev/null +++ b/firmware/target/arm/rk27xx/crt0.S @@ -0,0 +1,209 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: crt0.S 18776 2008-10-11 18:32:17Z gevaerts $ + * + * 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. + * + ****************************************************************************/ +#define ASM +#include "config.h" +#include "cpu.h" + + .section .intvect,"ax",%progbits + .global start + .global _newstart + /* Exception vectors */ +start: + b _newstart + ldr pc, =undef_instr_handler + ldr pc, =software_int_handler + ldr pc, =prefetch_abort_handler + ldr pc, =data_abort_handler + ldr pc, =reserved_handler + ldr pc, =irq_handler + ldr pc, =fiq_handler + .ltorg +_newstart: + ldr pc, =newstart2 + .section .init.text,"ax",%progbits +newstart2: + msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ + + mov r0, #0x18000000 + add r0, r0, #0x1c000 + + /* setup ARM core freq = 200MHz */ + /* AHB bus freq (HCLK) = 100MHz */ + /* APB bus freq (PCLK) = 50MHz */ + ldr r1, [r0,#0x14] /* SCU_DIVCON1 */ + orr r1, #9 /* ARM slow mode, HCLK:PCLK = 2:1 */ + str r1, [r0,#0x14] + + ldr r1,=0x01970c70 /* (1<<24) | (1<<23) | (23<<16) | (199<<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, #1 + bne 1b +1: + ldr r1, [r0,#0x14] /* SCU_DIVCON1 */ + bic r1, #5 /* leave ARM slow mode, ARMclk:HCLK = 2:1 */ + str r1, [r0,#0x14] + +#if defined(BOOTLOADER) + /* remap iram to 0x00000000 */ + ldr r1,=0xdeadbeef + str r1, [r0, #4] +#endif + +#if 0 + /* setup caches */ + ldr r0, =0xefff0000 /* cache controler base address */ + ldrh r1, [r0] + strh r1, [r0] /* global cache disable */ + + /* setup uncached regions */ + mov r1, #0x18000000 + orr r1, r1, #0xfe + str r1, [r0,#0x10] /* MemMapA BUS0IP, 32MB */ + str r1, [r0,#0x14] /* MemMapB BUS0IP, 32MB */ + mov r1, #0x30000000 + orr r1, r1, #0xfe + str r1, [r0,#0x18] /* MemMapC DSPMEM, 32MB */ + mov r1, #0xee000000 /* 0xefff0000 & 0xfe000000 */ + orr r1, r1, #0xfe + str r1, [r0,#0x1c] /* MemMapD cache controller, 32MB */ + + mov r1, #2 /* invalidate way opcode */ + str r1, [r0,#4] /* invalidate way0 */ +1: + ldr r2, [r0,#4] + tst r2, #3 + bne 1b /* wait for invalidate to complete */ + + orr r1, r1, #0x80000000 + str r1, [r0,#4] /* invalidate way1 */ +1: + ldr r2, [r0,#4] + tst r2, #3 + bne 1b /* wait for invalidate to complete */ + + ldr r1, [r0] + orr r1, r1, #0x80000000 + str r1, [r0] /* global cache enable */ +#endif + + /* 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 + +#ifndef BOOTLOADER + /* Copy icode and data to ram */ + ldr r2, =_iramstart + ldr r3, =_iramend + ldr r4, =_iramcopy +1: + cmp r3, r2 + ldrhi r1, [r4], #4 + strhi r1, [r2], #4 + bhi 1b + + /* Initialise ibss section to zero */ + ldr r2, =_iedata + ldr r3, =_iend + mov r4, #0 +1: + cmp r3, r2 + strhi r4, [r2], #4 + bhi 1b +#endif + + /* 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 + + /* 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 abort and undefined modes use IRQ stack */ + msr cpsr_c, #0xd7 + ldr sp, =_irqstackend + msr cpsr_c, #0xdb + ldr sp, =_irqstackend + + /* Switch back to supervisor mode */ + msr cpsr_c, #0xd3 + + bl main + + .text +/* .global UIE*/ + +/* All illegal exceptions call into UIE with exception address as first + * parameter. This is calculated differently depending on which exception + * we're in. Second parameter is exception number, used for a string lookup + * in UIE. */ +undef_instr_handler: + sub r0, lr, #4 + mov r1, #0 + b UIE + +/* We run supervisor mode most of the time, and should never see a software + * exception being thrown. Perhaps make it illegal and call UIE? */ +software_int_handler: +reserved_handler: + movs pc, lr + +prefetch_abort_handler: + sub r0, lr, #4 + mov r1, #1 + b UIE + +data_abort_handler: + sub r0, lr, #8 + mov r1, #2 + b UIE diff --git a/firmware/target/arm/rk27xx/ftl-rk27xx.c b/firmware/target/arm/rk27xx/ftl-rk27xx.c new file mode 100644 index 0000000000..40248ab6f3 --- /dev/null +++ b/firmware/target/arm/rk27xx/ftl-rk27xx.c @@ -0,0 +1,56 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 by Bertrik Sikken + * + * 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 "config.h" +#include "ftl-target.h" + +/* this file provides empty STUBS for now */ + +uint32_t ftl_init(void) +{ + /* TODO implement */ + return 0; +} + +uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer) +{ + /* TODO implement */ + (void)sector; + (void)count; + (void)buffer; + return 0; +} + +uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer) +{ + /* TODO implement */ + (void)sector; + (void)count; + (void)buffer; + return 0; +} + +uint32_t ftl_sync(void) +{ + /* TODO implement */ + return 0; +} + diff --git a/firmware/target/arm/rk27xx/ftl-target.h b/firmware/target/arm/rk27xx/ftl-target.h new file mode 100644 index 0000000000..ad4dc04db1 --- /dev/null +++ b/firmware/target/arm/rk27xx/ftl-target.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Michael Sparmann + * + * 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. + * + ****************************************************************************/ + +#ifndef __FTL_TARGET_H__ +#define __FTL_TARGET_H__ + +#include "config.h" +#include "inttypes.h" + +#ifdef BOOTLOADER +/* Bootloaders don't need write access */ +#define FTL_READONLY +#endif + +/* Pointer to an info structure regarding the flash type used */ +const struct nand_device_info_type* ftl_nand_type; + +/* Number of banks we detected a chip on */ +uint32_t ftl_banks; + +uint32_t ftl_init(void); +uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer); +uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer); +uint32_t ftl_sync(void); + + +#endif diff --git a/firmware/target/arm/rk27xx/i2c-rk27xx.c b/firmware/target/arm/rk27xx/i2c-rk27xx.c new file mode 100644 index 0000000000..34a6f49a32 --- /dev/null +++ b/firmware/target/arm/rk27xx/i2c-rk27xx.c @@ -0,0 +1,242 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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 "config.h" +#include "system.h" +#include "kernel.h" +#include "i2c-rk27xx.h" + +/* NOT TESTED YET */ + +/* Driver for the rockchip rk27xx built-in I2C controller in master mode + + Both the i2c_read and i2c_write function take the following arguments: + * slave, the address of the i2c slave device to read from / write to + * address, optional sub-address in the i2c slave (unused if -1) + * len, number of bytes to be transfered + * data, pointer to data to be transfered + A return value other than 0 indicates an error. +*/ + +static struct mutex i2c_mtx; + +static bool i2c_write_byte(uint8_t data, bool start) +{ + long timeout = current_tick + HZ / 50; + + /* START */ + I2C_CONR |= (1<<3) | (1<<2); /* master port enable, transmit bit */ + I2C_MTXR = data; + + if (start) + I2C_LCMR = (1<<2) | (1<<0); /* resume op, start bit */ + else + I2C_LCMR = (1<<2); /* resume op */ + + I2C_CONR &= ~(1<<4); /* ACK enable */ + + /* wait for ACK from slave */ + while ( !(I2C_ISR & (1<<0)) || (I2C_LSR & (1<<0)) ) + if (TIME_AFTER(current_tick, timeout)) + return false; + + /* clear status bit */ + I2C_ISR &= ~(1<<0); + + return true; +} + +static bool i2c_read_byte(unsigned char *data) +{ + long timeout = current_tick + HZ / 50; + + I2C_LCMR = (1<<2); /* resume op */ + + while (I2C_ISR & (1<<1)) + if (TIME_AFTER(current_tick, timeout)) + return false; + + *data = I2C_MRXR; + + /* clear status bit */ + I2C_ISR &= ~(1<<1); + + return true; +} + +static bool i2c_stop(void) +{ + long timeout = current_tick + HZ / 50; + + I2C_CONR &= ~(1<<4); + I2C_LCMR |= (1<<2) | (1<<1); /* resume op, stop */ + + while (I2C_LCMR & (1<<1)) + if (TIME_AFTER(current_tick, timeout)) + return false; + + return true; +} + +/* route i2c bus to internal codec or external bus + * internal codec has 0x27 i2c slave address so + * access to this address is routed to internal bus. + * All other addresses are routed to external pads + */ +static void i2c_iomux(unsigned char slave) +{ + unsigned long muxa = SCU_IOMUXA_CON & ~(0x1f<<14); + + if (slave == (0x27<<1)) + { + /* internal codec */ + SCU_IOMUXA_CON = muxa | (1<<16) | (1<<14); + } + else + { + /* external I2C bus */ + SCU_IOMUXA_CON = muxa | (1<<18); + } +} + +void i2c_init(void) +{ + mutex_init(&i2c_mtx); + + SCU_CLKCFG &= ~(1<< 20); + + I2C_OPR |= (1<<7); /* reset state machine */ + sleep(HZ/100); + I2C_OPR &= ~((1<<7) | (1<<6)); /* clear ENABLE bit, deasert reset */ + + /* set I2C divider to stay within allowed SCL freq limit + * APBfreq = 50Mhz + * SCLfreq = (APBfreq/5*(I2CCDVR[5:3] + 1) * 2^((I2CCDVR[2:0] + 1)) + */ + I2C_OPR = (I2C_OPR & ~(0x3F)) | (6<<3) | 1<<0; + + I2C_IER = 0x00; + + I2C_OPR |= (1<<6); /* enable i2c core */ +} + +int i2c_write(unsigned char slave, int address, int len, + const unsigned char *data) +{ + mutex_lock(&i2c_mtx); + + i2c_iomux(slave); + + /* START */ + if (! i2c_write_byte(slave & ~1, true)) + { + mutex_unlock(&i2c_mtx); + return 1; + } + + if (address >= 0) + { + if (! i2c_write_byte(address, false)) + { + mutex_unlock(&i2c_mtx); + return 2; + } + } + + /* write data */ + while (len--) + { + if (! i2c_write_byte(*data++, false)) + { + mutex_unlock(&i2c_mtx); + return 4; + } + } + + /* STOP */ + if (! i2c_stop()) + { + mutex_unlock(&i2c_mtx); + return 5; + } + + mutex_unlock(&i2c_mtx); + return 0; +} + +int i2c_read(unsigned char slave, int address, int len, unsigned char *data) +{ + mutex_lock(&i2c_mtx); + + i2c_iomux(slave); + + if (address >= 0) + { + /* START */ + if (! i2c_write_byte(slave & ~1, true)) + { + mutex_unlock(&i2c_mtx); + return 1; + } + + /* write address */ + if (! i2c_write_byte(address, false)) + { + mutex_unlock(&i2c_mtx); + return 2; + } + } + + /* (repeated) START */ + if (! i2c_write_byte(slave | 1, true)) + { + mutex_unlock(&i2c_mtx); + return 3; + } + + I2C_CONR &= ~(1<<3); /* clear transmit bit (switch to receive mode) */ + + while (len) + { + if (! i2c_read_byte(data++)) + { + mutex_unlock(&i2c_mtx); + return 4; + } + + if (len == 1) + I2C_CONR |= (1<<4); /* NACK */ + else + I2C_CONR &= ~(1<<4); /* ACK */ + + len--; + } + + /* STOP */ + if (! i2c_stop()) + { + mutex_unlock(&i2c_mtx); + return 5; + } + + mutex_unlock(&i2c_mtx); + return 0; +} diff --git a/firmware/target/arm/rk27xx/kernel-rk27xx.c b/firmware/target/arm/rk27xx/kernel-rk27xx.c new file mode 100644 index 0000000000..d54a09dd1f --- /dev/null +++ b/firmware/target/arm/rk27xx/kernel-rk27xx.c @@ -0,0 +1,54 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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 "config.h" +#include "system.h" +#include "kernel.h" + +/* rockchip rk27xx driver for the kernel timer */ + +/* sys timer ISR */ +void INT_TIMER0(void) +{ + /* clear interrupt */ + TMR0CON &= ~0x04; + + call_tick_tasks(); /* Run through the list of tick tasks */ +} + +/* this assumes 50MHz APB bus frequency */ +void tick_start(unsigned int interval_in_ms) +{ + unsigned int cycles = 50000 * interval_in_ms; + + /* enable timer clock */ + SCU_CLKCFG &= (1<<28); + + /* configure timer0 */ + TMR0LR = cycles; + TMR0CON = (1<<8) | (1<<7) | (1<<1); /* periodic, 1/1, interrupt enable */ + + /* unmask timer0 interrupt */ + INTC_IMR |= 0x04; + + /* enable timer0 interrupt */ + INTC_IECR |= 0x04; +} + diff --git a/firmware/target/arm/rk27xx/lcd-rk27xx.c b/firmware/target/arm/rk27xx/lcd-rk27xx.c new file mode 100644 index 0000000000..bb71458195 --- /dev/null +++ b/firmware/target/arm/rk27xx/lcd-rk27xx.c @@ -0,0 +1,304 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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 "config.h" +#include "kernel.h" +#include "lcd.h" +#include "system.h" +#include "cpu.h" +#include "spfd5420a.h" + +static inline void delay_nop(int cycles) +{ + asm volatile ("1: subs %[n], %[n], #1 \n\t" + " bne 1b" + : + : [n] "r" (cycles)); +} + +static unsigned int lcd_data_transform(unsigned int data) +{ + /* 18 bit interface */ + unsigned int r, g, b; + r = (data & 0x0000fc00)<<8; + /* g = ((data & 0x00000300) >> 2) | ((data & 0x000000e0) >> 3); */ + g = ((data & 0x00000300) << 6) | ((data & 0x000000e0) << 5); + b = (data & 0x00000001f) << 3; + + return (r | g | b); +} + +/* converts RGB565 pixel into internal lcd bus format */ +static unsigned int lcd_pixel_transform(unsigned short rgb565) +{ + unsigned int r, g, b; + b = rgb565 & 0x1f; + g = (rgb565 >> 5) & 0x3f; + r = (rgb565 >> 11) & 0x1f; + + return r<<19 | g<<10 | b<<3; +} + +static void lcd_cmd(unsigned int cmd) +{ + LCD_COMMAND = lcd_data_transform(cmd); +} + +static void lcd_data(unsigned int data) +{ + LCD_DATA = lcd_data_transform(data); +} + +static void lcd_write_reg(unsigned int reg, unsigned int val) +{ + lcd_cmd(reg); + lcd_data(val); +} + +static void lcdctrl_bypass(unsigned int on_off) +{ + while (!(LCDC_STA & LCDC_MCU_IDLE)); + + if (on_off) + MCU_CTRL |= MCU_CTRL_BYPASS; + else + MCU_CTRL &= ~MCU_CTRL_BYPASS; +} + +/* This part is unclear. I am unable to use buffered/FIFO based writes + * to lcd. Depending on settings of IF I get various patterns on display + * but not what I want to display apparently. + */ +static void lcdctrl_init(void) +{ + /* alpha b111 + * stop at current frame complete + * MCU mode + * 24b RGB + */ + LCDC_CTRL = ALPHA(7) | LCDC_STOP | LCDC_MCU | RGB24B; + MCU_CTRL = ALPHA_BASE(0x3f) | MCU_CTRL_BYPASS; + + HOR_ACT = 400 + 3; /* define horizonatal active region */ + VERT_ACT = 240; /* define vertical active region */ + VERT_PERIOD = 0xfff; /* CSn/WEn/RDn signal timings */ + + LINE0_YADDR = LINE_ALPHA_EN | 0x7fe; + LINE1_YADDR = LINE_ALPHA_EN | ((1 * 400) - 2); + LINE2_YADDR = LINE_ALPHA_EN | ((2 * 400) - 2); + LINE3_YADDR = LINE_ALPHA_EN | ((3 * 400) - 2); + + LINE0_UVADDR = 0x7fe + 1; + LINE1_UVADDR = ((1 * 400) - 2 + 1); + LINE2_UVADDR = ((2 * 400) - 2 + 1); + LINE3_UVADDR = ((3 * 400) - 2 + 1); + +#if 0 + LINE0_YADDR = 0; + LINE1_YADDR = (1 * 400); + LINE2_YADDR = (2 * 400); + LINE3_YADDR = (3 * 400); + + LINE0_UVADDR = 1; + LINE1_UVADDR = (1 * 400) + 1; + LINE2_UVADDR = (2 * 400) + 1; + LINE3_UVADDR = (3 * 400) + 1; + + START_X = 0; + START_Y = 0; + DELTA_X = 0x200; /* no scaling */ + DELTA_Y = 0x200; /* no scaling */ +#endif + LCDC_INTR_MASK = INTR_MASK_LINE; /* INTR_MASK_EVENLINE; */ +} + +/* configure pins to drive lcd in 18bit mode */ +static void iomux_lcd(void) +{ + unsigned long muxa; + + muxa = SCU_IOMUXA_CON & ~(IOMUX_LCD_VSYNC|IOMUX_LCD_DEN|0xff); + muxa |= IOMUX_LCD_D18|IOMUX_LCD_D20|IOMUX_LCD_D22|IOMUX_LCD_D17|IOMUX_LCD_D16; + + SCU_IOMUXA_CON = muxa; + SCU_IOMUXB_CON |= IOMUX_LCD_D815; +} + +/* not tested */ +static void lcd_sleep(unsigned int sleep) +{ + if (sleep) + { + /* enter sleep mode */ + lcd_write_reg(DISPLAY_CTRL1, 0x0170); + delay_nop(50); + lcd_write_reg(DISPLAY_CTRL1, 0x0000); + delay_nop(50); + lcd_write_reg(PWR_CTRL1, 0x14B4); + } + else + { + /* return to normal operation */ + lcd_write_reg(PWR_CTRL1, 0x14B0); + delay_nop(50); + lcd_write_reg(DISPLAY_CTRL1, 0x0173); + } + + lcd_cmd(GRAM_WRITE); +} + +void lcd_init_device() +{ + unsigned int x, y; + + iomux_lcd(); /* setup pins for 18bit lcd interface */ + lcdctrl_init(); /* basic lcdc module configuration */ + + lcdctrl_bypass(1); /* run in bypass mode - all writes goes directly to lcd controller */ + + lcd_write_reg(RESET, 0x0001); + delay_nop(10000); + lcd_write_reg(RESET, 0x0000); + delay_nop(10000); + lcd_write_reg(IF_ENDIAN, 0x0000); /* order of receiving data */ + lcd_write_reg(DRIVER_OUT_CTRL, 0x0000); + lcd_write_reg(ENTRY_MODE, 0x1038); + lcd_write_reg(WAVEFORM_CTRL, 0x0100); + lcd_write_reg(SHAPENING_CTRL, 0x0000); + lcd_write_reg(DISPLAY_CTRL2, 0x0808); + lcd_write_reg(LOW_PWR_CTRL1, 0x0001); + lcd_write_reg(LOW_PWR_CTRL2, 0x0010); + lcd_write_reg(EXT_DISP_CTRL1, 0x0000); + lcd_write_reg(EXT_DISP_CTRL2, 0x0000); + lcd_write_reg(BASE_IMG_SIZE, 0x3100); + lcd_write_reg(BASE_IMG_CTRL, 0x0001); + lcd_write_reg(VSCROLL_CTRL, 0x0000); + lcd_write_reg(PART1_POS, 0x0000); + lcd_write_reg(PART1_START, 0x0000); + lcd_write_reg(PART1_END, 0x018F); + lcd_write_reg(PART2_POS, 0x0000); + lcd_write_reg(PART2_START, 0x0000); + lcd_write_reg(PART2_END, 0x0000); + + lcd_write_reg(PANEL_IF_CTRL1, 0x0011); + delay_nop(10000); + lcd_write_reg(PANEL_IF_CTRL2, 0x0202); + lcd_write_reg(PANEL_IF_CTRL3, 0x0300); + delay_nop(10000); + lcd_write_reg(PANEL_IF_CTRL4, 0x021E); + lcd_write_reg(PANEL_IF_CTRL5, 0x0202); + lcd_write_reg(PANEL_IF_CTRL6, 0x0100); + lcd_write_reg(FRAME_MKR_CTRL, 0x0000); + lcd_write_reg(MDDI_CTRL, 0x0000); + + lcd_write_reg(GAMMA_CTRL1, 0x0101); + lcd_write_reg(GAMMA_CTRL2, 0x0000); + lcd_write_reg(GAMMA_CTRL3, 0x0016); + lcd_write_reg(GAMMA_CTRL4, 0x2913); + lcd_write_reg(GAMMA_CTRL5, 0x260B); + lcd_write_reg(GAMMA_CTRL6, 0x0101); + lcd_write_reg(GAMMA_CTRL7, 0x1204); + lcd_write_reg(GAMMA_CTRL8, 0x0415); + lcd_write_reg(GAMMA_CTRL9, 0x0205); + lcd_write_reg(GAMMA_CTRL10, 0x0303); + lcd_write_reg(GAMMA_CTRL11, 0x0E05); + lcd_write_reg(GAMMA_CTRL12, 0x0D01); + lcd_write_reg(GAMMA_CTRL13, 0x010D); + lcd_write_reg(GAMMA_CTRL14, 0x050E); + lcd_write_reg(GAMMA_CTRL15, 0x0303); + lcd_write_reg(GAMMA_CTRL16, 0x0502); + + /* power on */ + lcd_write_reg(DISPLAY_CTRL1, 0x0001); + lcd_write_reg(PWR_CTRL6, 0x0001); + lcd_write_reg(PWR_CTRL7, 0x0060); + delay_nop(50000); + lcd_write_reg(PWR_CTRL1, 0x16B0); + delay_nop(10000); + lcd_write_reg(PWR_CTRL2, 0x0147); + delay_nop(10000); + lcd_write_reg(PWR_CTRL3, 0x0117); + delay_nop(10000); + lcd_write_reg(PWR_CTRL4, 0x2F00); + delay_nop(50000); + lcd_write_reg(VCOM_HV2, 0x0000); /* src 0x0090 */ + delay_nop(10000); + lcd_write_reg(VCOM_HV1, 0x0008); /* src 0x000A */ + lcd_write_reg(PWR_CTRL3, 0x01BE); + delay_nop(10000); + + /* addresses setup */ + lcd_write_reg(WINDOW_H_START, 0x0000); + lcd_write_reg(WINDOW_H_END, 0x00EF); /* 239 */ + lcd_write_reg(WINDOW_V_START, 0x0000); + lcd_write_reg(WINDOW_V_END, 0x018F); /* 399 */ + lcd_write_reg(GRAM_H_ADDR, 0x0000); + lcd_write_reg(GRAM_V_ADDR, 0x0000); + + /* display on */ + lcd_write_reg(DISPLAY_CTRL1, 0x0021); + delay_nop(40000); + lcd_write_reg(DISPLAY_CTRL1, 0x0061); + delay_nop(100000); + lcd_write_reg(DISPLAY_CTRL1, 0x0173); + delay_nop(300000); + + + /* clear screen */ + lcd_cmd(GRAM_WRITE); + + for (x=0; x<400; x++) + for(y=0; y<240; y++) + lcd_data(0x000000); + + lcd_sleep(0); +} + +/* This is ugly hack. We drive lcd in bypass mode + * where all writes goes directly to lcd controller. + * This is suboptimal at best. IF module povides + * FIFO, internal sram buffer, hardware scaller, + * DMA signals, hardware alpha blending and more. + * BUT the fact is that I have no idea how to use + * this modes. Datasheet floating around is very + * unclean in this regard and OF uses ackward + * lcd update routines which are hard to understand. + * Moreover OF sets some bits in IF module registers + * which are referred as reseved in datasheet. + */ +void lcd_update() +{ + unsigned int x,y; + + for (y=0; y<240; y++) + for (x=0; x<400; x++) + LCD_DATA = lcd_pixel_transform(lcd_framebuffer[y][x]); +} + +/* not implemented yet */ +void lcd_update_rect(int x, int y, int width, int height) +{ + (void)x; + (void)y; + (void)width; + (void)height; + lcd_update(); +} diff --git a/firmware/target/arm/rk27xx/nand-target.h b/firmware/target/arm/rk27xx/nand-target.h new file mode 100644 index 0000000000..dee690e5e6 --- /dev/null +++ b/firmware/target/arm/rk27xx/nand-target.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Michael Sparmann + * + * 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. + * + ****************************************************************************/ + +#ifndef __NAND_TARGET_H__ +#define __NAND_TARGET_H__ + +#include "config.h" +#include "inttypes.h" + + +struct nand_device_info_type +{ + uint32_t id; + uint16_t blocks; + uint16_t userblocks; + uint16_t pagesperblock; + uint8_t blocksizeexponent; + uint8_t tunk1; + uint8_t twp; + uint8_t tunk2; + uint8_t tunk3; +} __attribute__((packed)); + +uint32_t nand_read_page(uint32_t bank, uint32_t page, void* databuffer, + void* sparebuffer, uint32_t doecc, + uint32_t checkempty); +uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer, + void* sparebuffer, uint32_t doecc); +uint32_t nand_block_erase(uint32_t bank, uint32_t page); + +const struct nand_device_info_type* nand_get_device_type(uint32_t bank); +uint32_t nand_reset(uint32_t bank); +uint32_t nand_device_init(void); +void nand_set_active(void); +long nand_last_activity(void); +void nand_power_up(void); +void nand_power_down(void); + + +#endif diff --git a/firmware/target/arm/rk27xx/rk27generic/button-rk27generic.c b/firmware/target/arm/rk27xx/rk27generic/button-rk27generic.c new file mode 100644 index 0000000000..cd60482b0f --- /dev/null +++ b/firmware/target/arm/rk27xx/rk27generic/button-rk27generic.c @@ -0,0 +1,39 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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 "config.h" +#include "cpu.h" +#include "system.h" +#include "button.h" + +void button_init_device(void) +{ + /* setup button gpios as input */ + GPIO_PCCON &= ~(BUTTON_MAIN); +} + +/* + * Get button pressed from hardware + */ +int button_read_device(void) +{ + return (GPIO_PCDR & BUTTON_MAIN); +} diff --git a/firmware/target/arm/rk27xx/rk27generic/button-target.h b/firmware/target/arm/rk27xx/rk27generic/button-target.h new file mode 100644 index 0000000000..cc14dfc32b --- /dev/null +++ b/firmware/target/arm/rk27xx/rk27generic/button-target.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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. + * + ****************************************************************************/ +#ifndef _BUTTON_TARGET_H_ +#define _BUTTON_TARGET_H_ + +#include +#include "config.h" + +void button_init_device(void); +int button_read_device(void); + +/* Main unit's buttons */ +/* values assigned corespond to GPIOs numbers */ +#define BUTTON_PLAY 0x00000002 + +#define BUTTON_REW 0x00000008 +#define BUTTON_FF 0x00000004 +#define BUTTON_VOL 0x00000040 +#define BUTTON_M 0x00000010 + +#define BUTTON_LEFT BUTTON_REW +#define BUTTON_RIGHT BUTTON_FF +#define BUTTON_ON BUTTON_PLAY + +#define BUTTON_REMOTE 0 + +#define BUTTON_MAIN (BUTTON_PLAY|BUTTON_REW|BUTTON_FF|\ + BUTTON_VOL|BUTTON_M) + +#define POWEROFF_BUTTON BUTTON_PLAY +#define POWEROFF_COUNT 30 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c new file mode 100644 index 0000000000..c5a23ad00d --- /dev/null +++ b/firmware/target/arm/rk27xx/sd-rk27xx.c @@ -0,0 +1,719 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 Daniel Ankers + * Copyright © 2008-2009 Rafaël Carré + * Copyright (C) 2011 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 "config.h" /* for HAVE_MULTIVOLUME */ +#include "fat.h" +#include "thread.h" +#include "gcc_extensions.h" +#include "led.h" +#include "sdmmc.h" +#include "system.h" +#include "kernel.h" +#include "cpu.h" +#include +#include +#include +#include "panic.h" +#include "stdbool.h" +#include "ata_idle_notify.h" +#include "sd.h" +#include "usb.h" + +#ifdef HAVE_HOTSWAP +#include "disk.h" +#endif + +#include "lcd.h" +#include +#include "sysfont.h" + +#define RES_NO (-1) + +static tCardInfo card_info; + +/* for compatibility */ +static long last_disk_activity = -1; + +static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; +static const char sd_thread_name[] = "ata/sd"; +static struct mutex sd_mtx SHAREDBSS_ATTR; +static struct event_queue sd_queue; +#ifndef BOOTLOADER +bool sd_enabled = false; +#endif + +static struct semaphore transfer_completion_signal; +static struct semaphore command_completion_signal; +static volatile bool retry; +static volatile int cmd_error; + +/* interrupt handler for SD */ +void INT_SD(void) +{ + const int status = SD_INT; + + SD_INT = 0; /* disable sd interrupts, clear pending interrupts */ + + /* cmd and response status pending */ + if(status & CMD_RES_STAT) + { + /* get the status */ + cmd_error = SD_CMDRES; + semaphore_release(&command_completion_signal); + } + + /* data transfer status pending */ + if(status & DATA_XFER_STAT) + { + cmd_error = SD_DATAT; + if (cmd_error & DATA_XFER_ERR) + retry = true; + + semaphore_release(&transfer_completion_signal); + } + + SD_INT = CMD_RES_INT_EN | DATA_XFER_INT_EN; +} + +/* Exchange buffers - the one where SD module puts into/reads from + * data and the one controlled by MCU. This allows some overlap + * in transfer operations and should increase throuput. + */ +static void mmu_switch_buff(void) +{ + static unsigned int i = 0; + + if (i++ & 0x01) + { + MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET | + MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD; + } + else + { + MMU_CTRL = MMU_MMU0_BUFI | MMU_CPU_BUFII | MMU_BUFII_RESET | + MMU_BUFII_WORD | MMU_BUFI_RESET | MMU_BUFI_BYTE; + } +} + +/* Reset internal pointers of the MMU submodule */ +static void mmu_buff_reset(void) +{ + MMU_CTRL |= MMU_BUFII_RESET | MMU_BUFI_RESET; +} + +/* My generic device uses PC7 pin, active low */ +static inline bool card_detect_target(void) +{ + return !(GPIO_PCDR & 0x80); +} + +/* Send command to the SD card. Command finish is signaled in ISR */ +static bool send_cmd(const int cmd, const int arg, const int res, + unsigned long *response) +{ + SD_CMD = arg; + + if (res > 0) + SD_CMDREST = CMD_XFER_START | RES_XFER_START | res | cmd; + else + SD_CMDREST = CMD_XFER_START | RES_XFER_END | RES_R1 | cmd; + + semaphore_wait(&command_completion_signal, TIMEOUT_BLOCK); + + /* Handle command responses & errors */ + if(res != RES_NO) + { + if(cmd_error & STAT_CMD_RES_ERR) + return false; + + if(res == RES_R2) + { + response[0] = SD_RES3; + response[1] = SD_RES2; + response[2] = SD_RES1; + response[3] = SD_RES0; + } + else + response[0] = SD_RES3; + } + return true; +} + +#if 0 +/* for some misterious reason the card does not report itself as being in TRAN + * but transfers are successful. Rockchip OF does not check the card state + * after SELECT. I checked two different cards. + */ +static void print_card_status(void) +{ + unsigned long response; + send_cmd(SD_SEND_STATUS, card_info.rca, RES_R1, + &response); + + printf("card status: 0x%0x, state: 0x%0x", response, (response>>9)&0xf); +} + +static int sd_wait_for_tran_state(void) +{ + unsigned long response; + unsigned int timeout = current_tick + 5*HZ; + int cmd_retry = 10; + + while (1) + { + while (!send_cmd(SD_SEND_STATUS, card_info.rca, RES_R1, + &response) && cmd_retry > 0) + { + cmd_retry--; + } + + if (cmd_retry <= 0) + { + return -1; + } + + if (((response >> 9) & 0xf) == SD_TRAN) + { + return 0; + } + + if(TIME_AFTER(current_tick, timeout)) + { + return -10 * ((response >> 9) & 0xf); + } + + last_disk_activity = current_tick; + } +} +#endif + +static bool sd_wait_card_busy(void) +{ + unsigned int timeout = current_tick + 5*HZ; + + while (!(SD_CARD & SD_CARD_BSY)) + { + if(TIME_AFTER(current_tick, timeout)) + return false; + } + + return true; +} + +static int sd_init_card(void) +{ + unsigned long response; + long init_timeout; + bool sd_v2 = false; + + card_info.rca = 0; + + /* assume 50 MHz APB freq / 125 = 400 kHz */ + SD_CTRL = (SD_CTRL & ~(0x7FF)) | 0x7D; + + /* 100 - 400kHz clock required for Identification Mode */ + /* Start of Card Identification Mode ************************************/ + + /* CMD0 Go Idle */ + if(!send_cmd(SD_GO_IDLE_STATE, 0, RES_NO, NULL)) + return -1; + + sleep(1); + + /* CMD8 Check for v2 sd card. Must be sent before using ACMD41 + Non v2 cards will not respond to this command*/ + if(send_cmd(SD_SEND_IF_COND, 0x1AA, RES_R6, &response)) + if((response & 0xFFF) == 0x1AA) + sd_v2 = true; + + /* timeout for initialization is 1sec, from SD Specification 2.00 */ + init_timeout = current_tick + HZ; + + do { + /* this timeout is the only valid error for this loop*/ + if(TIME_AFTER(current_tick, init_timeout)) + return -2; + + if(!send_cmd(SD_APP_CMD, card_info.rca, RES_R1, &response)) + return -3; + + sleep(1); /* bus conflict otherwise */ + + /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */ + if(!send_cmd(SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)), + RES_R3, &card_info.ocr)) + return -4; + } while(!(card_info.ocr & (1<<31)) ); + + /* CMD2 send CID */ + if(!send_cmd(SD_ALL_SEND_CID, 0, RES_R2, card_info.cid)) + return -5; + + /* CMD3 send RCA */ + if(!send_cmd(SD_SEND_RELATIVE_ADDR, 0, RES_R6, &card_info.rca)) + return -6; + + /* End of Card Identification Mode ************************************/ + + /* Card back to full speed 25MHz*/ + SD_CTRL = (SD_CTRL & ~0x7FF) | 1; /* FIXME check this divider - OF uses 0 here*/ + + /* CMD9 send CSD */ + if(!send_cmd(SD_SEND_CSD, card_info.rca, RES_R2, card_info.csd)) + return -11; + + sd_parse_csd(&card_info); + + if(!send_cmd(SD_SELECT_CARD, card_info.rca, RES_R1b, &response)) + return -20; + + if (!sd_wait_card_busy()) + return -21; + + card_info.initialized = 1; + + return 0; +} + +static void sd_thread(void) NORETURN_ATTR; +static void sd_thread(void) +{ + struct queue_event ev; + bool idle_notified = false; + + while (1) + { + queue_wait_w_tmo(&sd_queue, &ev, HZ); + + switch ( ev.id ) + { +#ifdef HAVE_HOTSWAP + case SYS_HOTSWAP_INSERTED: + case SYS_HOTSWAP_EXTRACTED: + { + int microsd_init = 1; + fat_lock(); /* lock-out FAT activity first - + prevent deadlocking via disk_mount that + would cause a reverse-order attempt with + another thread */ + mutex_lock(&sd_mtx); /* lock-out card activity - direct calls + into driver that bypass the fat cache */ + + /* We now have exclusive control of fat cache and ata */ + + disk_unmount(sd_first_drive); /* release "by force", ensure file + descriptors aren't leaked and any busy + ones are invalid if mounting */ + /* Force card init for new card, re-init for re-inserted one or + * clear if the last attempt to init failed with an error. */ + card_info.initialized = 0; + + if (ev.id == SYS_HOTSWAP_INSERTED) + { + sd_enable(true); + microsd_init = sd_init_card(sd_first_drive); + if (microsd_init < 0) /* initialisation failed */ + panicf("microSD init failed : %d", microsd_init); + + microsd_init = disk_mount(sd_first_drive); /* 0 if fail */ + } + + /* + * Mount succeeded, or this was an EXTRACTED event, + * in both cases notify the system about the changed filesystems + */ + if (microsd_init) + queue_broadcast(SYS_FS_CHANGED, 0); + + sd_enable(false); + + /* Access is now safe */ + mutex_unlock(&sd_mtx); + fat_unlock(); + } + break; +#endif + case SYS_TIMEOUT: + if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ))) + { + idle_notified = false; + } + else if (!idle_notified) + { + call_storage_idle_notifys(false); + idle_notified = true; + } + break; + + case SYS_USB_CONNECTED: + usb_acknowledge(SYS_USB_CONNECTED_ACK); + /* Wait until the USB cable is extracted again */ + usb_wait_for_disconnect(&sd_queue); + + break; + } + } +} + +static void init_controller(void) +{ + /* reset SD module */ + SCU_RSTCFG |= (1<<9); + sleep(1); + SCU_RSTCFG &= ~(1<<9); + + /* set pins functions as SD signals */ + SCU_IOMUXA_CON |= IOMUX_SD; + + /* enable and unmask SD interrupts in interrupt controller */ + INTC_IMR |= (1<<10); + INTC_IECR |= (1<<10); + + SD_CTRL = SD_PWR_CPU | SD_DETECT_MECH | SD_CLOCK_EN | 0x7D; + SD_INT = CMD_RES_INT_EN | DATA_XFER_INT_EN; + SD_CARD = SD_CARD_SELECT | SD_CARD_PWR_EN; + + /* setup mmu buffers */ + MMU_PNRI = 0x1ff; + MMU_PNRII = 0x1ff; + MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET | + MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD; + +} + +int sd_init(void) +{ + int ret; + + semaphore_init(&transfer_completion_signal, 1, 0); + semaphore_init(&command_completion_signal, 1, 0); + + init_controller(); + + ret = sd_init_card(); + if(ret < 0) + return ret; + + /* init mutex */ + mutex_init(&sd_mtx); + + queue_init(&sd_queue, true); + create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0, + sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU)); + + return 0; +} + +int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, + void* buf) +{ +#ifdef HAVE_MULTIDRIVE + (void)drive; +#endif + unsigned long response; + unsigned int retry_cnt = 0; + int cnt, ret = 0; + unsigned char *dst; + + mutex_lock(&sd_mtx); + sd_enable(true); + + if (count <= 0 || start + count > card_info.numblocks) + return -1; + + if(!(card_info.ocr & (1<<30))) + start <<= 9; /* not SDHC */ + + /* setup A2A DMA CH0 */ + A2A_ISRC0 = (unsigned long)(&MMU_DATA); + A2A_ICNT0 = 512; + A2A_LCNT0 = 1; + A2A_DOMAIN = 0; + + while (retry_cnt++ < 20) + { + cnt = count; + dst = (unsigned char *)buf; + + ret = 0; + retry = false; /* reset retry flag */ + mmu_buff_reset(); /* reset recive buff state */ + + /* issue read command to the card */ + if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response)) + { + ret = -4; + continue; + } + + while (cnt > 0) + { + if (cnt == 1) + { + /* last block to tranfer */ + SD_DATAT = DATA_XFER_START | DATA_XFER_READ | + DATA_BUS_1LINE | DATA_XFER_DMA_DIS | + DATA_XFER_SINGLE; + } + else + { + /* more than one block to transfer */ + SD_DATAT = DATA_XFER_START | DATA_XFER_READ | + DATA_BUS_1LINE | DATA_XFER_DMA_DIS | + DATA_XFER_MULTI; + } + + /* wait for transfer completion */ + semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); + + if (retry) + { + /* data transfer error */ + ret = -5; + break; + } + + /* exchange buffers */ + mmu_switch_buff(); + + last_disk_activity = current_tick; + + /* transfer data from receive buffer to the dest + * for (i=0; i<(512/4); i++) + * *dst++ = MMU_DATA; + * + * below is DMA version in software mode. + * SD module provides DMAreq signals and all this + * can be done in hardware in theory but I can't + * figure this out. OF doesn't use DMA at all. + */ + A2A_IDST0 = (unsigned long)dst; + A2A_CON0 = (3<<9) | (1<<6) | (1<<3) | (2<<1) | (1<<0); + + /* wait for DMA engine to finish transfer */ + while (A2A_DMA_STS & 1); + + dst += 512; + cnt--; + } /* while (cnt > 0) */ + + if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response)) + ret = -6; + + /* transfer successfull - leave retry loop */ + if (ret == 0) + break; + } + + sd_enable(false); + mutex_unlock(&sd_mtx); + + return ret; +} + +/* Not tested */ +int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count, + const void* buf) +{ +#ifdef HAVE_MULTIDRIVE + (void) drive; +#endif +#if defined(BOOTLOADER) /* we don't need write support in bootloader */ + (void) start; + (void) count; + (void) buf; + return -1; +#else + unsigned long response; + unsigned int retry_cnt = 0; + int cnt, ret = 0; + unsigned char *src; + bool card_selected = false; + + mutex_lock(&sd_mtx); + sd_enable(true); + + if (count <= 0 || start + count > card_info.numblocks) + return -1; + + if(!(card_info.ocr & (1<<30))) + start <<= 9; /* not SDHC */ + + /* setup A2A DMA CH0 */ + A2A_IDST0 = (unsigned long)(&MMU_DATA); + A2A_ICNT0 = 512; + A2A_LCNT0 = 1; + A2A_DOMAIN = 0; + + while (retry_cnt++ < 20) + { + cnt = count; + src = (unsigned char *)buf; + + ret = 0; + retry = false; /* reset retry flag */ + mmu_buff_reset(); /* reset recive buff state */ + + if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) + { + ret = -3; + continue; + } + + while (cnt > 0) + { + /* transfer data from receive buffer to the dest + * for (i=0; i<(512/4); i++) + * MMU_DATA = *src++; + * + * Below is DMA version in software mode. + */ + + A2A_ISRC0 = (unsigned long)src; + A2A_CON0 = (3<<9) | (1<<5) | (1<<3) | (2<<1) | (1<<0); + + while (A2A_DMA_STS & 1); + + src += 512; + + /* exchange buffers */ + mmu_switch_buff(); + + if (cnt == 1) + { + /* last block to tranfer */ + SD_DATAT = DATA_XFER_START | DATA_XFER_WRITE | + DATA_BUS_1LINE | DATA_XFER_DMA_DIS | + DATA_XFER_SINGLE; + + } + else + { + /* more than one block to transfer */ + SD_DATAT = DATA_XFER_START | DATA_XFER_WRITE | + DATA_BUS_1LINE | DATA_XFER_DMA_DIS | + DATA_XFER_MULTI; + + } + + /* wait for transfer completion */ + semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); + + if (retry) + { + /* data transfer error */ + ret = -3; + break; + } + + cnt--; + } /* while (cnt > 0) */ + + if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response)) + ret = -4; + + if (!sd_wait_card_busy()) + ret = -5; + + /* transfer successfull - leave retry loop */ + if (ret == 0) + break; + } + + sd_enable(false); + mutex_unlock(&sd_mtx); + + return ret; + +#endif /* defined(BOOTLOADER) */ +} + +void sd_enable(bool on) +{ + /* enable or disable clock signal for SD module */ + if (on) + { + SCU_CLKCFG &= ~(1<<22); + } + else + { + SCU_CLKCFG |= (1<<22); + } +} + +#ifndef BOOTLOADER +long sd_last_disk_activity(void) +{ + return last_disk_activity; +} + +tCardInfo *card_get_info_target(int card_no) +{ + (void)card_no; + return &card_info; +} +#endif /* BOOTLOADER */ + +#ifdef HAVE_HOTSWAP +/* Not complete and disabled in config */ +bool sd_removable(IF_MD_NONVOID(int drive)) +{ + (void)drive; + return true; +} + +bool sd_present(IF_MD_NONVOID(int drive)) +{ + (void)drive; + return card_detect_target(); +} + +static int sd_oneshot_callback(struct timeout *tmo) +{ + (void)tmo; + + /* This is called only if the state was stable for 300ms - check state + * and post appropriate event. */ + if (card_detect_target()) + { + queue_broadcast(SYS_HOTSWAP_INSERTED, 0); + } + else + queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); + + return 0; +} + +/* interrupt handler for SD detect */ + +#endif /* HAVE_HOTSWAP */ + +#ifdef CONFIG_STORAGE_MULTI +int sd_num_drives(int first_drive) +{ + (void)first_drive; + + /* we have only one SD drive */ + return 1; +} +#endif /* CONFIG_STORAGE_MULTI */ diff --git a/firmware/target/arm/rk27xx/spfd5420a.h b/firmware/target/arm/rk27xx/spfd5420a.h new file mode 100644 index 0000000000..fcb998dfd1 --- /dev/null +++ b/firmware/target/arm/rk27xx/spfd5420a.h @@ -0,0 +1,107 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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. + * + ****************************************************************************/ + +#define ID_READ 0x000 +#define DRIVER_OUT_CTRL 0x001 +#define WAVEFORM_CTRL 0x002 +#define ENTRY_MODE 0x003 +/* 0x004 - 0x005 reserved */ +#define SHAPENING_CTRL 0x006 /* not present in datasheet */ +#define DISPLAY_CTRL1 0x007 +#define DISPLAY_CTRL2 0x008 +#define LOW_PWR_CTRL1 0x009 +/* 0x00A reserved */ +#define LOW_PWR_CTRL2 0x00B +#define EXT_DISP_CTRL1 0x00C +/* 0x00D - 0x00E reserved */ +#define EXT_DISP_CTRL2 0x00F +#define PANEL_IF_CTRL1 0x010 +#define PANEL_IF_CTRL2 0x011 +#define PANEL_IF_CTRL3 0x012 +/* 0x013 - 0x01F reserved */ +#define PANEL_IF_CTRL4 0x020 +#define PANEL_IF_CTRL5 0x021 +#define PANEL_IF_CTRL6 0x022 +/* 0x023 - 0x08F reserved */ +#define FRAME_MKR_CTRL 0x090 +/* 0x091 reserved */ +#define MDDI_CTRL 0x092 /* not present in datasheet */ +/* 0x093 - 0x0FF reserved */ +#define PWR_CTRL1 0x100 +#define PWR_CTRL2 0x101 +#define PWR_CTRL3 0x102 +#define PWR_CTRL4 0x103 /* amplitude to VCOM */ +/* 0x104 - 0x106 reserved */ +#define PWR_CTRL5 0x107 +/* 0x108 - 0x10F reserved */ +#define PWR_CTRL6 0x110 +#define PWR_CTRL7 0x112 /* not present in datasheet */ +/* 0x113 - 0x1FF reserved */ +#define GRAM_H_ADDR 0x200 +#define GRAM_V_ADDR 0x201 +#define GRAM_READ 0x202 +#define GRAM_WRITE 0x202 +/* 0x203 - 0x20F reserved */ +#define WINDOW_H_START 0x210 +#define WINDOW_H_END 0x211 +#define WINDOW_V_START 0x212 +#define WINDOW_V_END 0x213 +/* 0x214 - 0x27F reserved */ +#define NVM_READ 0x280 +#define NVM_WRITE 0x280 +#define VCOM_HV1 0x281 +#define VCOM_HV2 0x282 +/* 0x283 - 0x2FF reserved */ +#define GAMMA_CTRL1 0x300 +#define GAMMA_CTRL2 0x301 +#define GAMMA_CTRL3 0x302 +#define GAMMA_CTRL4 0x303 +#define GAMMA_CTRL5 0x304 +#define GAMMA_CTRL6 0x305 +#define GAMMA_CTRL7 0x306 +#define GAMMA_CTRL8 0x307 +#define GAMMA_CTRL9 0x308 +#define GAMMA_CTRL10 0x309 +#define GAMMA_CTRL11 0x30A +#define GAMMA_CTRL12 0x30B +#define GAMMA_CTRL13 0x30C +#define GAMMA_CTRL14 0x30D +#define GAMMA_CTRL15 0x30E +#define GAMMA_CTRL16 0x30F +/* 0x310 - 0x3FF reserved */ +#define BASE_IMG_SIZE 0x400 +#define BASE_IMG_CTRL 0x401 +/* 0x402 - 0x403 reserved */ +#define VSCROLL_CTRL 0x404 +/* 0x405 - 0x4FF reserved */ +#define PART1_POS 0x500 +#define PART1_START 0x501 +#define PART1_END 0x502 +#define PART2_POS 0x503 +#define PART2_START 0x504 +#define PART2_END 0x505 +/* 0x506 - 0x5FF reserved */ +#define RESET 0x600 /* not present in datasheet */ +/* 0x601 - 0x605 */ +#define IF_ENDIAN 0x606 +/* 0x607 - 0x6EF reserved */ +#define NVM_CTRL 0x6F0 +/* 0x6F1 - 0xFFF reserved */ diff --git a/firmware/target/arm/rk27xx/system-rk27xx.c b/firmware/target/arm/rk27xx/system-rk27xx.c new file mode 100644 index 0000000000..67024a5fea --- /dev/null +++ b/firmware/target/arm/rk27xx/system-rk27xx.c @@ -0,0 +1,164 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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 "kernel.h" +#include "system.h" +#include "panic.h" +#include "system-target.h" + +#define default_interrupt(name) \ + extern __attribute__((weak,alias("UIRQ"))) void name (void) + +void irq_handler(void) __attribute__((interrupt ("IRQ"), naked)); +void fiq_handler(void) __attribute__((interrupt ("FIQ"), naked, \ + weak, alias("fiq_dummy"))); + +default_interrupt(INT_UART0); +default_interrupt(INT_UART1); +default_interrupt(INT_TIMER0); +default_interrupt(INT_TIMER1); +default_interrupt(INT_TIMER2); +default_interrupt(INT_GPIO0); +default_interrupt(INT_SW_INT0); +default_interrupt(INT_AHB0_MAILBOX); +default_interrupt(INT_RTC); +default_interrupt(INT_SCU); +default_interrupt(INT_SD); +default_interrupt(INT_SPI); +default_interrupt(INT_HDMA); +default_interrupt(INT_A2A_BRIDGE); +default_interrupt(INT_I2C); +default_interrupt(INT_I2S); +default_interrupt(INT_UDC); +default_interrupt(INT_UHC); +default_interrupt(INT_PWM0); +default_interrupt(INT_PWM1); +default_interrupt(INT_PWM2); +default_interrupt(INT_ADC); +default_interrupt(INT_GPIO1); +default_interrupt(INT_VIP); +default_interrupt(INT_DWDMA); +default_interrupt(INT_NANDC); +default_interrupt(INT_LCDC); +default_interrupt(INT_DSP); +default_interrupt(INT_SW_INT1); +default_interrupt(INT_SW_INT2); +default_interrupt(INT_SW_INT3); + +static void (* const irqvector[])(void) = +{ + INT_UART0,INT_UART1,INT_TIMER0,INT_TIMER1,INT_TIMER2,INT_GPIO0,INT_SW_INT0,INT_AHB0_MAILBOX, + INT_RTC,INT_SCU,INT_SD,INT_SPI,INT_HDMA,INT_A2A_BRIDGE,INT_I2C, + INT_I2S,INT_UDC,INT_UHC,INT_PWM0,INT_PWM1,INT_PWM2,INT_ADC,INT_GPIO1, + INT_VIP,INT_DWDMA,INT_NANDC,INT_LCDC,INT_DSP,INT_SW_INT1,INT_SW_INT2,INT_SW_INT3 +}; + +static const char * const irqname[] = +{ + "INT_UART0","INT_UART1","INT_TIMER0","INT_TIMER1","INT_TIMER2","INT_GPIO0","INT_SW_INT0","INT_AHB0_MAILBOX", + "INT_RTC","INT_SCU","INT_SD","INT_SPI","INT_HDMA","INT_A2A_BRIDGE","INT_I2C", + "INT_I2S","INT_UDC","INT_UHC","INT_PWM0","INT_PWM1","INT_PWM2","INT_ADC","INT_GPIO1", + "INT_VIP","INT_DWDMA","INT_NANDC","INT_LCDC","INT_DSP","INT_SW_INT1","INT_SW_INT2","INT_SW_INT3" +}; + +static void UIRQ(void) +{ + unsigned int offset = INTC_ISR & 0x1f; + panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]); +} + +void irq_handler(void) +{ + /* + * Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c + */ + + asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ + "sub sp, sp, #8 \n"); /* Reserve stack */ + + int irq_no = INTC_ISR & 0x1f; + + irqvector[irq_no](); + + /* clear interrupt */ + INTC_ICCR = (1 << irq_no); + + asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */ + "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ + "subs pc, lr, #4 \n"); /* Return from IRQ */ +} + +void fiq_dummy(void) +{ + asm volatile ( + "subs pc, lr, #4 \r\n" + ); +} + + +void system_init(void) +{ + return; +} + +/* not tested */ +void system_reboot(void) +{ + /* use Watchdog to reset */ + WDTLR = 1; + WDTCON = (1<<4) | (1<<3); + + /* Wait for reboot to kick in */ + while(1); +} + +void system_exception_wait(void) +{ + while(1); +} + +int system_memory_guard(int newmode) +{ + (void)newmode; + return 0; +} + +/* usecs may be at most 2^32/200 (~21 seconds) for 200MHz max cpu freq */ +void udelay(unsigned usecs) +{ + unsigned cycles_per_usec; + unsigned delay; + + if (cpu_frequency == CPUFREQ_MAX) { + cycles_per_usec = (CPUFREQ_MAX + 999999) / 1000000; + } else { + cycles_per_usec = (CPUFREQ_NORMAL + 999999) / 1000000; + } + + delay = (usecs * cycles_per_usec + 3) / 4; + + asm volatile( + "1: subs %0, %0, #1 \n" /* 1 cycle */ + " bne 1b \n" /* 3 cycles */ + : : "r"(delay) + ); +} + diff --git a/firmware/target/arm/rk27xx/system-target.h b/firmware/target/arm/rk27xx/system-target.h new file mode 100644 index 0000000000..fb904091b1 --- /dev/null +++ b/firmware/target/arm/rk27xx/system-target.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 Rafaël Carré + * Copyright (C) 2011 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. + * + ****************************************************************************/ +#ifndef SYSTEM_TARGET_H +#define SYSTEM_TARGET_H + +#include "system-arm.h" +#include "panic.h" + +void udelay(unsigned usecs); +static inline void mdelay(unsigned msecs) +{ + udelay(1000 * msecs); +} + +/* this needs more testing */ +static inline void core_sleep(void) +{ + enable_irq(); + SCU_CPUPD = 0xdeedbabe; +} + +#define CPUFREQ_NORMAL 200000000 +#define CPUFREQ_MAX 200000000 + +#endif /* SYSTEM_TARGET_H */ diff --git a/firmware/target/arm/rk27xx/timer-rk27xx.c b/firmware/target/arm/rk27xx/timer-rk27xx.c new file mode 100644 index 0000000000..4493ccdfa9 --- /dev/null +++ b/firmware/target/arm/rk27xx/timer-rk27xx.c @@ -0,0 +1,74 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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 "config.h" + +#include "inttypes.h" +#include "system.h" +#include "timer.h" + +void INT_TIMER1(void) +{ + /* clear interrupt */ + TMR1CON &= ~(1<<2); + + if (pfn_timer != NULL) + { + pfn_timer(); + } +} + +bool timer_set(long cycles, bool start) +{ + /* optionally unregister any previously registered timer user */ + if (start) + { + if (pfn_unregister != NULL) + { + pfn_unregister(); + pfn_unregister = NULL; + } + } + + TMR1LR = cycles; + TMR1CON = (1<<7) | (1<<1); /* periodic, 1/1 */ + + /* unmask timer1 interrupt */ + INTC_IMR |= (1<<3); + + /* enable timer1 interrupt */ + INTC_IECR |= (1<<3); + + return true; +} + +bool timer_start(void) +{ + TMR1CON |= (1 << 8); /* timer1 enable */ + + return true; +} + +void timer_stop(void) +{ + TMR1CON &= ~(1 << 8); /* timer1 disable */ +} + diff --git a/firmware/target/arm/thread-arm.c b/firmware/target/arm/thread-arm.c index 84a3aecbd7..83bdb9288d 100644 --- a/firmware/target/arm/thread-arm.c +++ b/firmware/target/arm/thread-arm.c @@ -109,7 +109,7 @@ static inline void core_sleep(void) } #else /* Skip this if special code is required and implemented */ -#ifndef CPU_PP +#if !(defined(CPU_PP)) && CONFIG_CPU != RK27XX static inline void core_sleep(void) { #warning core_sleep not implemented, battery life will be decreased diff --git a/tools/configure b/tools/configure index 96953c8b50..d988e75d63 100755 --- a/tools/configure +++ b/tools/configure @@ -500,6 +500,13 @@ arm1176jzscc () { endian="little" } +arm7ejscc () { + findarmgcc + GCCOPTS="$CCOPTS -march=armv5te" + GCCOPTIMIZE="-fomit-frame-pointer" + endian="little" +} + mipselcc () { prefixtools mipsel-elf- # mips is predefined, but we want it for paths. use __mips instead @@ -1271,8 +1278,8 @@ cat <