2008-10-21 14:06:49 +01:00
/* linux/arch/arm/plat-s3c64xx/cpu.c
*
* Copyright 2008 Openmoko , Inc .
* Copyright 2008 Simtec Electronics
* Ben Dooks < ben @ simtec . co . uk >
* http : //armlinux.simtec.co.uk/
*
* S3C64XX CPU Support
*
* 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/init.h>
# include <linux/module.h>
# include <linux/interrupt.h>
# include <linux/ioport.h>
2008-12-12 00:24:31 +00:00
# include <linux/sysdev.h>
2008-10-21 14:06:49 +01:00
# include <linux/serial_core.h>
# include <linux/platform_device.h>
# include <linux/io.h>
# include <mach/hardware.h>
# include <mach/map.h>
# include <asm/mach/arch.h>
# include <asm/mach/map.h>
# include <plat/regs-serial.h>
# include <plat/cpu.h>
# include <plat/devs.h>
# include <plat/clock.h>
2010-01-26 13:41:30 +09:00
# include <mach/s3c6400.h>
# include <mach/s3c6410.h>
2008-10-21 14:06:49 +01:00
/* table of supported CPUs */
static const char name_s3c6400 [ ] = " S3C6400 " ;
static const char name_s3c6410 [ ] = " S3C6410 " ;
static struct cpu_table cpu_ids [ ] __initdata = {
{
. idcode = 0x36400000 ,
. idmask = 0xfffff000 ,
. map_io = s3c6400_map_io ,
. init_clocks = s3c6400_init_clocks ,
. init_uarts = s3c6400_init_uarts ,
. init = s3c6400_init ,
. name = name_s3c6400 ,
} , {
. idcode = 0x36410100 ,
. idmask = 0xffffff00 ,
. map_io = s3c6410_map_io ,
. init_clocks = s3c6410_init_clocks ,
. init_uarts = s3c6410_init_uarts ,
. init = s3c6410_init ,
. name = name_s3c6410 ,
} ,
} ;
/* minimal IO mapping */
/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */
# define UART_OFFS (S3C_PA_UART & 0xfffff)
static struct map_desc s3c_iodesc [ ] __initdata = {
{
2008-10-21 14:07:13 +01:00
. virtual = ( unsigned long ) S3C_VA_SYS ,
2008-10-21 14:06:49 +01:00
. pfn = __phys_to_pfn ( S3C64XX_PA_SYSCON ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
2009-12-29 14:40:30 +00:00
} , {
. virtual = ( unsigned long ) S3C_VA_MEM ,
. pfn = __phys_to_pfn ( S3C64XX_PA_SROM ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
2008-10-21 14:06:49 +01:00
} , {
. virtual = ( unsigned long ) ( S3C_VA_UART + UART_OFFS ) ,
. pfn = __phys_to_pfn ( S3C_PA_UART ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
} , {
2010-01-07 08:59:26 +09:00
. virtual = ( unsigned long ) VA_VIC0 ,
2008-10-21 14:06:49 +01:00
. pfn = __phys_to_pfn ( S3C64XX_PA_VIC0 ) ,
. length = SZ_16K ,
. type = MT_DEVICE ,
} , {
2010-01-07 08:59:26 +09:00
. virtual = ( unsigned long ) VA_VIC1 ,
2008-10-21 14:06:49 +01:00
. pfn = __phys_to_pfn ( S3C64XX_PA_VIC1 ) ,
. length = SZ_16K ,
. type = MT_DEVICE ,
2008-10-21 14:06:57 +01:00
} , {
2008-10-21 14:07:13 +01:00
. virtual = ( unsigned long ) S3C_VA_TIMER ,
2008-10-21 14:06:57 +01:00
. pfn = __phys_to_pfn ( S3C_PA_TIMER ) ,
. length = SZ_16K ,
. type = MT_DEVICE ,
2008-10-21 14:07:07 +01:00
} , {
2008-10-21 14:07:13 +01:00
. virtual = ( unsigned long ) S3C64XX_VA_GPIO ,
2008-10-21 14:07:07 +01:00
. pfn = __phys_to_pfn ( S3C64XX_PA_GPIO ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
2008-12-12 00:24:38 +00:00
} , {
. virtual = ( unsigned long ) S3C64XX_VA_MODEM ,
. pfn = __phys_to_pfn ( S3C64XX_PA_MODEM ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
2009-05-17 23:40:30 +01:00
} , {
. virtual = ( unsigned long ) S3C_VA_WATCHDOG ,
. pfn = __phys_to_pfn ( S3C64XX_PA_WATCHDOG ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
2009-11-20 13:04:08 +01:00
} , {
. virtual = ( unsigned long ) S3C_VA_USB_HSPHY ,
. pfn = __phys_to_pfn ( S3C64XX_PA_USB_HSPHY ) ,
. length = SZ_1K ,
. type = MT_DEVICE ,
2008-10-21 14:06:49 +01:00
} ,
} ;
2008-12-12 00:24:31 +00:00
struct sysdev_class s3c64xx_sysclass = {
. name = " s3c64xx-core " ,
} ;
static struct sys_device s3c64xx_sysdev = {
. cls = & s3c64xx_sysclass ,
} ;
2010-01-26 14:32:09 +09:00
/* uart registration process */
void __init s3c6400_common_init_uarts ( struct s3c2410_uartcfg * cfg , int no )
{
s3c24xx_init_uartdevs ( " s3c6400-uart " , s3c64xx_uart_resources , cfg , no ) ;
}
2008-12-12 00:24:31 +00:00
2008-10-21 14:06:49 +01:00
/* read cpu identification code */
void __init s3c64xx_init_io ( struct map_desc * mach_desc , int size )
{
unsigned long idcode ;
/* initialise the io descriptors we need for initialisation */
iotable_init ( s3c_iodesc , ARRAY_SIZE ( s3c_iodesc ) ) ;
iotable_init ( mach_desc , size ) ;
idcode = __raw_readl ( S3C_VA_SYS + 0x118 ) ;
2009-03-24 17:31:42 +00:00
if ( ! idcode ) {
/* S3C6400 has the ID register in a different place,
* and needs a write before it can be read . */
__raw_writel ( 0x0 , S3C_VA_SYS + 0xA1C ) ;
idcode = __raw_readl ( S3C_VA_SYS + 0xA1C ) ;
}
2008-10-21 14:06:49 +01:00
s3c_init_cpu ( idcode , cpu_ids , ARRAY_SIZE ( cpu_ids ) ) ;
}
2008-12-12 00:24:31 +00:00
static __init int s3c64xx_sysdev_init ( void )
{
sysdev_class_register ( & s3c64xx_sysclass ) ;
return sysdev_register ( & s3c64xx_sysdev ) ;
}
core_initcall ( s3c64xx_sysdev_init ) ;