2007-02-11 20:31:01 +03:00
/* linux/arch/arm/mach-s3c2440/mach-anubis.c
2005-09-07 14:49:23 +04:00
*
2008-07-03 14:24:43 +04:00
* Copyright ( c ) 2003 - 2005 , 2008 Simtec Electronics
2005-09-07 14:49:23 +04:00
* http : //armlinux.simtec.co.uk/
* Ben Dooks < ben @ simtec . co . uk >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/kernel.h>
# include <linux/types.h>
# include <linux/interrupt.h>
# include <linux/list.h>
# include <linux/timer.h>
# include <linux/init.h>
2006-12-18 01:22:26 +03:00
# include <linux/serial_core.h>
2005-10-29 22:07:23 +04:00
# include <linux/platform_device.h>
2008-07-03 14:24:38 +04:00
# include <linux/ata_platform.h>
2008-07-03 14:24:43 +04:00
# include <linux/i2c.h>
2008-09-06 15:10:45 +04:00
# include <linux/io.h>
2007-07-12 13:47:35 +04:00
# include <linux/sm501.h>
# include <linux/sm501-regs.h>
2005-09-07 14:49:23 +04:00
# include <asm/mach/arch.h>
# include <asm/mach/map.h>
# include <asm/mach/irq.h>
2008-08-05 19:14:15 +04:00
# include <mach/anubis-map.h>
# include <mach/anubis-irq.h>
# include <mach/anubis-cpld.h>
2005-09-07 14:49:23 +04:00
2008-08-05 19:14:15 +04:00
# include <mach/hardware.h>
2005-09-07 14:49:23 +04:00
# include <asm/irq.h>
# include <asm/mach-types.h>
2007-07-22 19:05:25 +04:00
# include <asm/plat-s3c/regs-serial.h>
2008-08-05 19:14:15 +04:00
# include <mach/regs-gpio.h>
# include <mach/regs-mem.h>
# include <mach/regs-lcd.h>
2007-07-22 19:05:25 +04:00
# include <asm/plat-s3c/nand.h>
2005-09-07 14:49:23 +04:00
# include <linux/mtd/mtd.h>
# include <linux/mtd/nand.h>
# include <linux/mtd/nand_ecc.h>
# include <linux/mtd/partitions.h>
2007-07-11 13:14:53 +04:00
# include <net/ax88796.h>
2007-02-11 20:31:01 +03:00
# include <asm/plat-s3c24xx/clock.h>
# include <asm/plat-s3c24xx/devs.h>
# include <asm/plat-s3c24xx/cpu.h>
2005-09-07 14:49:23 +04:00
# define COPYRIGHT ", (c) 2005 Simtec Electronics"
static struct map_desc anubis_iodesc [ ] __initdata = {
/* ISA IO areas */
2005-11-09 17:05:30 +03:00
{
. virtual = ( u32 ) S3C24XX_VA_ISA_BYTE ,
. pfn = __phys_to_pfn ( 0x0 ) ,
. length = SZ_4M ,
2006-07-26 23:16:39 +04:00
. type = MT_DEVICE ,
2005-11-09 17:05:30 +03:00
} , {
. virtual = ( u32 ) S3C24XX_VA_ISA_WORD ,
. pfn = __phys_to_pfn ( 0x0 ) ,
2006-07-26 23:16:39 +04:00
. length = SZ_4M ,
. type = MT_DEVICE ,
2005-11-09 17:05:30 +03:00
} ,
2005-09-07 14:49:23 +04:00
/* we could possibly compress the next set down into a set of smaller tables
* pagetables , but that would mean using an L2 section , and it still means
* we cannot actually feed the same register to an LDR due to 16 K spacing
*/
/* CPLD control registers */
2005-11-09 17:05:30 +03:00
{
. virtual = ( u32 ) ANUBIS_VA_CTRL1 ,
. pfn = __phys_to_pfn ( ANUBIS_PA_CTRL1 ) ,
. length = SZ_4K ,
2006-07-26 23:16:39 +04:00
. type = MT_DEVICE ,
2005-11-09 17:05:30 +03:00
} , {
2007-06-06 13:01:04 +04:00
. virtual = ( u32 ) ANUBIS_VA_IDREG ,
. pfn = __phys_to_pfn ( ANUBIS_PA_IDREG ) ,
2005-11-09 17:05:30 +03:00
. length = SZ_4K ,
2006-07-26 23:16:39 +04:00
. type = MT_DEVICE ,
2005-11-09 17:05:30 +03:00
} ,
2005-09-07 14:49:23 +04:00
} ;
# define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
# define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
# define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c24xx_uart_clksrc anubis_serial_clocks [ ] = {
[ 0 ] = {
. name = " uclk " ,
. divisor = 1 ,
. min_baud = 0 ,
. max_baud = 0 ,
} ,
[ 1 ] = {
. name = " pclk " ,
. divisor = 1 ,
. min_baud = 0 ,
2006-07-26 23:16:39 +04:00
. max_baud = 0 ,
2005-09-07 14:49:23 +04:00
}
} ;
2006-06-19 02:04:05 +04:00
static struct s3c2410_uartcfg anubis_uartcfgs [ ] __initdata = {
2005-09-07 14:49:23 +04:00
[ 0 ] = {
. hwport = 0 ,
. flags = 0 ,
. ucon = UCON ,
. ulcon = ULCON ,
. ufcon = UFCON ,
. clocks = anubis_serial_clocks ,
2006-07-26 23:16:39 +04:00
. clocks_size = ARRAY_SIZE ( anubis_serial_clocks ) ,
2005-09-07 14:49:23 +04:00
} ,
[ 1 ] = {
. hwport = 2 ,
. flags = 0 ,
. ucon = UCON ,
. ulcon = ULCON ,
. ufcon = UFCON ,
. clocks = anubis_serial_clocks ,
2006-07-26 23:16:39 +04:00
. clocks_size = ARRAY_SIZE ( anubis_serial_clocks ) ,
2005-09-07 14:49:23 +04:00
} ,
} ;
/* NAND Flash on Anubis board */
static int external_map [ ] = { 2 } ;
static int chip0_map [ ] = { 0 } ;
static int chip1_map [ ] = { 1 } ;
2005-10-12 22:58:07 +04:00
static struct mtd_partition anubis_default_nand_part [ ] = {
2005-09-07 14:49:23 +04:00
[ 0 ] = {
. name = " Boot Agent " ,
. size = SZ_16K ,
2006-07-26 23:16:39 +04:00
. offset = 0 ,
2005-09-07 14:49:23 +04:00
} ,
[ 1 ] = {
. name = " /boot " ,
. size = SZ_4M - SZ_16K ,
. offset = SZ_16K ,
} ,
[ 2 ] = {
. name = " user1 " ,
. offset = SZ_4M ,
. size = SZ_32M - SZ_4M ,
} ,
[ 3 ] = {
. name = " user2 " ,
. offset = SZ_32M ,
. size = MTDPART_SIZ_FULL ,
}
} ;
2007-07-11 14:10:42 +04:00
static struct mtd_partition anubis_default_nand_part_large [ ] = {
[ 0 ] = {
. name = " Boot Agent " ,
. size = SZ_128K ,
. offset = 0 ,
} ,
[ 1 ] = {
. name = " /boot " ,
. size = SZ_4M - SZ_128K ,
. offset = SZ_128K ,
} ,
[ 2 ] = {
. name = " user1 " ,
. offset = SZ_4M ,
. size = SZ_32M - SZ_4M ,
} ,
[ 3 ] = {
. name = " user2 " ,
. offset = SZ_32M ,
. size = MTDPART_SIZ_FULL ,
}
} ;
2005-09-07 14:49:23 +04:00
/* the Anubis has 3 selectable slots for nand-flash, the two
* on - board chip areas , as well as the external slot .
*
* Note , there is no current hot - plug support for the External
* socket .
*/
static struct s3c2410_nand_set anubis_nand_sets [ ] = {
[ 1 ] = {
. name = " External " ,
. nr_chips = 1 ,
. nr_map = external_map ,
. nr_partitions = ARRAY_SIZE ( anubis_default_nand_part ) ,
2006-07-26 23:16:39 +04:00
. partitions = anubis_default_nand_part ,
2005-09-07 14:49:23 +04:00
} ,
[ 0 ] = {
. name = " chip0 " ,
. nr_chips = 1 ,
. nr_map = chip0_map ,
. nr_partitions = ARRAY_SIZE ( anubis_default_nand_part ) ,
2006-07-26 23:16:39 +04:00
. partitions = anubis_default_nand_part ,
2005-09-07 14:49:23 +04:00
} ,
[ 2 ] = {
. name = " chip1 " ,
. nr_chips = 1 ,
. nr_map = chip1_map ,
. nr_partitions = ARRAY_SIZE ( anubis_default_nand_part ) ,
2006-07-26 23:16:39 +04:00
. partitions = anubis_default_nand_part ,
2005-09-07 14:49:23 +04:00
} ,
} ;
static void anubis_nand_select ( struct s3c2410_nand_set * set , int slot )
{
unsigned int tmp ;
slot = set - > nr_map [ slot ] & 3 ;
pr_debug ( " anubis_nand: selecting slot %d (set %p,%p) \n " ,
slot , set , set - > nr_map ) ;
tmp = __raw_readb ( ANUBIS_VA_CTRL1 ) ;
tmp & = ~ ANUBIS_CTRL1_NANDSEL ;
tmp | = slot ;
pr_debug ( " anubis_nand: ctrl1 now %02x \n " , tmp ) ;
__raw_writeb ( tmp , ANUBIS_VA_CTRL1 ) ;
}
static struct s3c2410_platform_nand anubis_nand_info = {
. tacls = 25 ,
2006-04-02 13:32:46 +04:00
. twrph0 = 55 ,
. twrph1 = 40 ,
2005-09-07 14:49:23 +04:00
. nr_sets = ARRAY_SIZE ( anubis_nand_sets ) ,
. sets = anubis_nand_sets ,
. select_chip = anubis_nand_select ,
} ;
2006-06-19 21:30:04 +04:00
/* IDE channels */
2008-07-03 14:24:38 +04:00
struct pata_platform_info anubis_ide_platdata = {
. ioport_shift = 5 ,
} ;
2006-06-19 21:30:04 +04:00
static struct resource anubis_ide0_resource [ ] = {
{
. start = S3C2410_CS3 ,
. end = S3C2410_CS3 + ( 8 * 32 ) - 1 ,
. flags = IORESOURCE_MEM ,
} , {
2008-07-03 14:24:38 +04:00
. start = S3C2410_CS3 + ( 1 < < 26 ) + ( 6 * 32 ) ,
. end = S3C2410_CS3 + ( 1 < < 26 ) + ( 7 * 32 ) - 1 ,
2006-06-19 21:30:04 +04:00
. flags = IORESOURCE_MEM ,
} , {
. start = IRQ_IDE0 ,
. end = IRQ_IDE0 ,
. flags = IORESOURCE_IRQ ,
} ,
} ;
static struct platform_device anubis_device_ide0 = {
2008-07-03 14:24:38 +04:00
. name = " pata_platform " ,
2006-06-19 21:30:04 +04:00
. id = 0 ,
. num_resources = ARRAY_SIZE ( anubis_ide0_resource ) ,
. resource = anubis_ide0_resource ,
2008-07-03 14:24:38 +04:00
. dev = {
. platform_data = & anubis_ide_platdata ,
. coherent_dma_mask = ~ 0 ,
} ,
2006-06-19 21:30:04 +04:00
} ;
static struct resource anubis_ide1_resource [ ] = {
{
. start = S3C2410_CS4 ,
. end = S3C2410_CS4 + ( 8 * 32 ) - 1 ,
. flags = IORESOURCE_MEM ,
} , {
2008-07-03 14:24:38 +04:00
. start = S3C2410_CS4 + ( 1 < < 26 ) + ( 6 * 32 ) ,
. end = S3C2410_CS4 + ( 1 < < 26 ) + ( 7 * 32 ) - 1 ,
2006-06-19 21:30:04 +04:00
. flags = IORESOURCE_MEM ,
} , {
. start = IRQ_IDE0 ,
. end = IRQ_IDE0 ,
. flags = IORESOURCE_IRQ ,
} ,
} ;
static struct platform_device anubis_device_ide1 = {
2008-07-03 14:24:38 +04:00
. name = " pata_platform " ,
2006-06-19 21:30:04 +04:00
. id = 1 ,
. num_resources = ARRAY_SIZE ( anubis_ide1_resource ) ,
. resource = anubis_ide1_resource ,
2008-07-03 14:24:38 +04:00
. dev = {
. platform_data = & anubis_ide_platdata ,
. coherent_dma_mask = ~ 0 ,
} ,
2006-06-19 21:30:04 +04:00
} ;
2005-09-07 14:49:23 +04:00
2007-07-11 13:14:53 +04:00
/* Asix AX88796 10/100 ethernet controller */
static struct ax_plat_data anubis_asix_platdata = {
. flags = AXFLG_MAC_FROMDEV ,
. wordlength = 2 ,
. dcr_val = 0x48 ,
. rcr_val = 0x40 ,
} ;
static struct resource anubis_asix_resource [ ] = {
[ 0 ] = {
. start = S3C2410_CS5 ,
. end = S3C2410_CS5 + ( 0x20 * 0x20 ) - 1 ,
. flags = IORESOURCE_MEM
} ,
[ 1 ] = {
. start = IRQ_ASIX ,
. end = IRQ_ASIX ,
. flags = IORESOURCE_IRQ
}
} ;
static struct platform_device anubis_device_asix = {
. name = " ax88796 " ,
. id = 0 ,
. num_resources = ARRAY_SIZE ( anubis_asix_resource ) ,
. resource = anubis_asix_resource ,
. dev = {
. platform_data = & anubis_asix_platdata ,
}
} ;
2007-07-12 13:47:35 +04:00
/* SM501 */
static struct resource anubis_sm501_resource [ ] = {
[ 0 ] = {
. start = S3C2410_CS2 ,
. end = S3C2410_CS2 + SZ_8M ,
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
. start = S3C2410_CS2 + SZ_64M - SZ_2M ,
. end = S3C2410_CS2 + SZ_64M - 1 ,
. flags = IORESOURCE_MEM ,
} ,
[ 2 ] = {
. start = IRQ_EINT0 ,
. end = IRQ_EINT0 ,
. flags = IORESOURCE_IRQ ,
} ,
} ;
static struct sm501_initdata anubis_sm501_initdata = {
. gpio_high = {
. set = 0x3F000000 , /* 24bit panel */
. mask = 0x0 ,
} ,
. misc_timing = {
. set = 0x010100 , /* SDRAM timing */
. mask = 0x1F1F00 ,
} ,
. misc_control = {
. set = SM501_MISC_PNL_24BIT ,
. mask = 0 ,
} ,
/* set the SDRAM and bus clocks */
. mclk = 72 * MHZ ,
. m1xclk = 144 * MHZ ,
} ;
static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c [ ] = {
[ 0 ] = {
. pin_scl = 44 ,
. pin_sda = 45 ,
} ,
[ 1 ] = {
. pin_scl = 40 ,
. pin_sda = 41 ,
} ,
} ;
static struct sm501_platdata anubis_sm501_platdata = {
. init = & anubis_sm501_initdata ,
. gpio_i2c = anubis_sm501_gpio_i2c ,
. gpio_i2c_nr = ARRAY_SIZE ( anubis_sm501_gpio_i2c ) ,
} ;
static struct platform_device anubis_device_sm501 = {
. name = " sm501 " ,
. id = 0 ,
. num_resources = ARRAY_SIZE ( anubis_sm501_resource ) ,
. resource = anubis_sm501_resource ,
. dev = {
. platform_data = & anubis_sm501_platdata ,
} ,
} ;
2005-09-07 14:49:23 +04:00
/* Standard Anubis devices */
static struct platform_device * anubis_devices [ ] __initdata = {
& s3c_device_usb ,
& s3c_device_wdt ,
& s3c_device_adc ,
& s3c_device_i2c ,
& s3c_device_rtc ,
& s3c_device_nand ,
2006-06-19 21:30:04 +04:00
& anubis_device_ide0 ,
& anubis_device_ide1 ,
2007-07-11 13:14:53 +04:00
& anubis_device_asix ,
2007-07-12 13:47:35 +04:00
& anubis_device_sm501 ,
2005-09-07 14:49:23 +04:00
} ;
2008-07-15 20:17:48 +04:00
static struct clk * anubis_clocks [ ] __initdata = {
2005-09-07 14:49:23 +04:00
& s3c24xx_dclk0 ,
& s3c24xx_dclk1 ,
& s3c24xx_clkout0 ,
& s3c24xx_clkout1 ,
& s3c24xx_uclk ,
} ;
2008-07-03 14:24:43 +04:00
/* I2C devices. */
static struct i2c_board_info anubis_i2c_devs [ ] __initdata = {
{
I2C_BOARD_INFO ( " tps65011 " , 0x48 ) ,
. irq = IRQ_EINT20 ,
}
} ;
2005-09-20 20:24:33 +04:00
static void __init anubis_map_io ( void )
2005-09-07 14:49:23 +04:00
{
/* initialise the clocks */
2008-04-16 03:12:39 +04:00
s3c24xx_dclk0 . parent = & clk_upll ;
2005-09-07 14:49:23 +04:00
s3c24xx_dclk0 . rate = 12 * 1000 * 1000 ;
2008-04-16 03:12:39 +04:00
s3c24xx_dclk1 . parent = & clk_upll ;
2005-09-07 14:49:23 +04:00
s3c24xx_dclk1 . rate = 24 * 1000 * 1000 ;
s3c24xx_clkout0 . parent = & s3c24xx_dclk0 ;
s3c24xx_clkout1 . parent = & s3c24xx_dclk1 ;
s3c24xx_uclk . parent = & s3c24xx_clkout1 ;
2007-04-20 14:15:27 +04:00
s3c24xx_register_clocks ( anubis_clocks , ARRAY_SIZE ( anubis_clocks ) ) ;
2005-09-07 14:49:23 +04:00
s3c_device_nand . dev . platform_data = & anubis_nand_info ;
s3c24xx_init_io ( anubis_iodesc , ARRAY_SIZE ( anubis_iodesc ) ) ;
s3c24xx_init_clocks ( 0 ) ;
s3c24xx_init_uarts ( anubis_uartcfgs , ARRAY_SIZE ( anubis_uartcfgs ) ) ;
2007-07-11 14:10:42 +04:00
/* check for the newer revision boards with large page nand */
if ( ( __raw_readb ( ANUBIS_VA_IDREG ) & ANUBIS_IDREG_REVMASK ) > = 4 ) {
printk ( KERN_INFO " ANUBIS-B detected (revision %d) \n " ,
__raw_readb ( ANUBIS_VA_IDREG ) & ANUBIS_IDREG_REVMASK ) ;
anubis_nand_sets [ 0 ] . partitions = anubis_default_nand_part_large ;
anubis_nand_sets [ 0 ] . nr_partitions = ARRAY_SIZE ( anubis_default_nand_part_large ) ;
} else {
/* ensure that the GPIO is setup */
s3c2410_gpio_setpin ( S3C2410_GPA0 , 1 ) ;
}
2005-09-07 14:49:23 +04:00
}
2007-04-20 14:19:16 +04:00
static void __init anubis_init ( void )
{
platform_add_devices ( anubis_devices , ARRAY_SIZE ( anubis_devices ) ) ;
2008-07-03 14:24:43 +04:00
i2c_register_board_info ( 0 , anubis_i2c_devs ,
ARRAY_SIZE ( anubis_i2c_devs ) ) ;
2007-04-20 14:19:16 +04:00
}
2005-09-07 14:49:23 +04:00
MACHINE_START ( ANUBIS , " Simtec-Anubis " )
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
. phys_io = S3C2410_PA_UART ,
. io_pg_offst = ( ( ( u32 ) S3C24XX_VA_UART ) > > 18 ) & 0xfffc ,
. boot_params = S3C2410_SDRAM_PA + 0x100 ,
. map_io = anubis_map_io ,
2007-04-20 14:19:16 +04:00
. init_machine = anubis_init ,
2005-09-07 14:49:23 +04:00
. init_irq = s3c24xx_init_irq ,
. timer = & s3c24xx_timer ,
MACHINE_END