2011-12-23 02:31:28 +04:00
/*
* Copyright ( c ) 2010 - 2011 Samsung Electronics Co . , Ltd .
2010-08-31 11:30:51 +04:00
* http : //www.samsung.com
2009-06-23 16:40:15 +04:00
*
* Copyright 2009 Samsung Electronics Co .
* Byungho Min < bhmin @ samsung . com >
*
2011-12-23 02:31:28 +04:00
* Common Codes for S5PC100
2009-06-23 16:40:15 +04:00
*
* 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 .
2011-12-23 02:31:28 +04:00
*/
2009-06-23 16:40:15 +04:00
# include <linux/kernel.h>
# include <linux/types.h>
# include <linux/interrupt.h>
# include <linux/list.h>
# include <linux/timer.h>
# include <linux/init.h>
# include <linux/clk.h>
# include <linux/io.h>
2011-12-22 04:01:38 +04:00
# include <linux/device.h>
2009-06-23 16:40:15 +04:00
# include <linux/serial_core.h>
# include <linux/platform_device.h>
2010-10-02 07:48:12 +04:00
# include <linux/sched.h>
2009-06-23 16:40:15 +04:00
2011-12-23 02:31:28 +04:00
# include <asm/irq.h>
# include <asm/proc-fns.h>
2012-03-28 21:30:01 +04:00
# include <asm/system_misc.h>
2009-06-23 16:40:15 +04:00
# include <asm/mach/arch.h>
# include <asm/mach/map.h>
# include <asm/mach/irq.h>
# include <mach/map.h>
2011-12-23 02:31:28 +04:00
# include <mach/hardware.h>
2010-05-20 09:51:08 +04:00
# include <mach/regs-clock.h>
2009-06-23 16:40:15 +04:00
# include <plat/cpu.h>
# include <plat/devs.h>
# include <plat/clock.h>
2010-05-20 09:51:08 +04:00
# include <plat/sdhci.h>
2010-06-30 16:50:24 +04:00
# include <plat/adc-core.h>
2011-12-23 02:31:28 +04:00
# include <plat/ata-core.h>
2010-08-11 05:02:37 +04:00
# include <plat/fb-core.h>
2011-12-23 02:31:28 +04:00
# include <plat/iic-core.h>
# include <plat/onenand-core.h>
# include <plat/regs-serial.h>
2011-12-23 02:35:21 +04:00
# include <plat/watchdog-reset.h>
2011-12-23 02:31:28 +04:00
# include "common.h"
2010-05-20 10:59:05 +04:00
2011-12-23 02:31:28 +04:00
static const char name_s5pc100 [ ] = " S5PC100 " ;
static struct cpu_table cpu_ids [ ] __initdata = {
{
. idcode = S5PC100_CPU_ID ,
. idmask = S5PC100_CPU_MASK ,
. map_io = s5pc100_map_io ,
. init_clocks = s5pc100_init_clocks ,
. init_uarts = s5pc100_init_uarts ,
. init = s5pc100_init ,
. name = name_s5pc100 ,
} ,
} ;
2009-06-23 16:40:15 +04:00
/* Initial IO mappings */
static struct map_desc s5pc100_iodesc [ ] __initdata = {
2010-05-20 09:51:08 +04:00
{
2011-12-23 02:31:28 +04:00
. virtual = ( unsigned long ) S5P_VA_CHIPID ,
. pfn = __phys_to_pfn ( S5PC100_PA_CHIPID ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
} , {
. virtual = ( unsigned long ) S3C_VA_SYS ,
. pfn = __phys_to_pfn ( S5PC100_PA_SYSCON ) ,
. length = SZ_64K ,
. type = MT_DEVICE ,
} , {
. virtual = ( unsigned long ) S3C_VA_TIMER ,
. pfn = __phys_to_pfn ( S5PC100_PA_TIMER ) ,
. length = SZ_16K ,
. type = MT_DEVICE ,
} , {
. virtual = ( unsigned long ) S3C_VA_WATCHDOG ,
. pfn = __phys_to_pfn ( S5PC100_PA_WATCHDOG ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
} , {
. virtual = ( unsigned long ) S5P_VA_SROMC ,
. pfn = __phys_to_pfn ( S5PC100_PA_SROMC ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
} , {
2010-05-20 09:51:08 +04:00
. virtual = ( unsigned long ) S5P_VA_SYSTIMER ,
. pfn = __phys_to_pfn ( S5PC100_PA_SYSTIMER ) ,
. length = SZ_16K ,
. type = MT_DEVICE ,
2010-08-31 11:30:51 +04:00
} , {
. virtual = ( unsigned long ) S5P_VA_GPIO ,
. pfn = __phys_to_pfn ( S5PC100_PA_GPIO ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
} , {
. virtual = ( unsigned long ) VA_VIC0 ,
. pfn = __phys_to_pfn ( S5PC100_PA_VIC0 ) ,
. length = SZ_16K ,
. type = MT_DEVICE ,
} , {
. virtual = ( unsigned long ) VA_VIC1 ,
. pfn = __phys_to_pfn ( S5PC100_PA_VIC1 ) ,
. length = SZ_16K ,
. type = MT_DEVICE ,
2010-05-20 09:51:08 +04:00
} , {
. virtual = ( unsigned long ) VA_VIC2 ,
2010-08-31 11:30:51 +04:00
. pfn = __phys_to_pfn ( S5PC100_PA_VIC2 ) ,
2010-05-20 09:51:08 +04:00
. length = SZ_16K ,
. type = MT_DEVICE ,
2010-08-31 11:30:51 +04:00
} , {
. virtual = ( unsigned long ) S3C_VA_UART ,
. pfn = __phys_to_pfn ( S3C_PA_UART ) ,
. length = SZ_512K ,
. type = MT_DEVICE ,
2010-05-20 09:51:08 +04:00
} , {
. virtual = ( unsigned long ) S5PC100_VA_OTHERS ,
. pfn = __phys_to_pfn ( S5PC100_PA_OTHERS ) ,
. length = SZ_4K ,
. type = MT_DEVICE ,
}
2009-06-23 16:40:15 +04:00
} ;
2011-12-23 02:31:28 +04:00
/*
* s5pc100_map_io
2009-06-23 16:40:15 +04:00
*
2011-12-23 02:31:28 +04:00
* register the standard CPU IO areas
*/
2009-06-23 16:40:15 +04:00
2011-12-23 02:31:28 +04:00
void __init s5pc100_init_io ( struct map_desc * mach_desc , int size )
2009-06-23 16:40:15 +04:00
{
2011-12-23 02:31:28 +04:00
/* initialize the io descriptors we need for initialization */
2009-06-23 16:40:15 +04:00
iotable_init ( s5pc100_iodesc , ARRAY_SIZE ( s5pc100_iodesc ) ) ;
2011-12-23 02:31:28 +04:00
if ( mach_desc )
iotable_init ( mach_desc , size ) ;
/* detect cpu id and rev. */
s5p_init_cpu ( S5P_VA_CHIPID ) ;
s3c_init_cpu ( samsung_cpu_id , cpu_ids , ARRAY_SIZE ( cpu_ids ) ) ;
}
2009-06-23 16:40:15 +04:00
2011-12-23 02:31:28 +04:00
void __init s5pc100_map_io ( void )
{
2009-06-23 16:40:15 +04:00
/* initialise device information early */
2009-11-17 10:41:23 +03:00
s5pc100_default_sdhci0 ( ) ;
s5pc100_default_sdhci1 ( ) ;
s5pc100_default_sdhci2 ( ) ;
2009-11-17 10:41:21 +03:00
2010-06-30 16:50:24 +04:00
s3c_adc_setname ( " s3c64xx-adc " ) ;
2009-11-17 10:41:21 +03:00
/* the i2c devices are directly compatible with s3c2440 */
s3c_i2c0_setname ( " s3c2440-i2c " ) ;
s3c_i2c1_setname ( " s3c2440-i2c " ) ;
2010-05-20 10:59:05 +04:00
s3c_onenand_setname ( " s5pc100-onenand " ) ;
2010-08-11 05:02:37 +04:00
s3c_fb_setname ( " s5pc100-fb " ) ;
2010-06-08 12:02:08 +04:00
s3c_cfcon_setname ( " s5pc100-pata " ) ;
2009-06-23 16:40:15 +04:00
}
void __init s5pc100_init_clocks ( int xtal )
{
2010-05-20 09:51:08 +04:00
printk ( KERN_DEBUG " %s: initializing clocks \n " , __func__ ) ;
2009-06-23 16:40:15 +04:00
s3c24xx_register_baseclocks ( xtal ) ;
2010-05-20 09:51:08 +04:00
s5p_register_clocks ( xtal ) ;
2009-06-23 16:40:15 +04:00
s5pc100_register_clocks ( ) ;
s5pc100_setup_clocks ( ) ;
}
void __init s5pc100_init_irq ( void )
{
2010-05-20 09:51:08 +04:00
u32 vic [ ] = { ~ 0 , ~ 0 , ~ 0 } ;
2009-06-23 16:40:15 +04:00
/* VIC0, VIC1, and VIC2 are fully populated. */
2010-05-20 09:51:08 +04:00
s5p_init_irq ( vic , ARRAY_SIZE ( vic ) ) ;
2009-06-23 16:40:15 +04:00
}
2011-12-22 04:01:38 +04:00
static struct bus_type s5pc100_subsys = {
. name = " s5pc100-core " ,
. dev_name = " s5pc100-core " ,
2009-06-23 16:40:15 +04:00
} ;
2011-12-22 04:01:38 +04:00
static struct device s5pc100_dev = {
. bus = & s5pc100_subsys ,
2009-06-23 16:40:15 +04:00
} ;
static int __init s5pc100_core_init ( void )
{
2011-12-22 04:01:38 +04:00
return subsys_system_register ( & s5pc100_subsys , NULL ) ;
2009-06-23 16:40:15 +04:00
}
core_initcall ( s5pc100_core_init ) ;
int __init s5pc100_init ( void )
{
2010-05-20 09:51:08 +04:00
printk ( KERN_INFO " S5PC100: Initializing architecture \n " ) ;
2012-01-06 11:08:09 +04:00
return device_register ( & s5pc100_dev ) ;
2009-06-23 16:40:15 +04:00
}
2011-12-23 02:31:28 +04:00
/* uart registration process */
void __init s5pc100_init_uarts ( struct s3c2410_uartcfg * cfg , int no )
{
s3c24xx_init_uartdevs ( " s3c6400-uart " , s5p_uart_resources , cfg , no ) ;
}
2011-12-23 02:35:21 +04:00
void s5pc100_restart ( char mode , const char * cmd )
{
if ( mode ! = ' s ' )
arch_wdt_reset ( ) ;
soft_restart ( 0 ) ;
}