From 1abd328ee5e2e870fa035e7882e7a278127b4ccf Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Mon, 19 Sep 2011 20:09:01 +0900 Subject: ARM: EXYNOS4: convert boot_params to atag_offset Based on "ARM: introduce atag_offset to replace boot_params" by Nicolas Pitre (2bb9839e312ed55a6d5824ffa6077ce3d7d63b1e). Since boot_params variable is deleted from machine_desc, the variable is modified in the newer board files. Cc: Nicolas Pitre Signed-off-by: Tushar Behera [kgene.kim@samsung.com: added fixing for smdkv310] Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos4/mach-origen.c | 2 +- arch/arm/mach-exynos4/mach-smdkv310.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-exynos4/mach-origen.c b/arch/arm/mach-exynos4/mach-origen.c index ed59f86001ac..b5f6f38557c9 100644 --- a/arch/arm/mach-exynos4/mach-origen.c +++ b/arch/arm/mach-exynos4/mach-origen.c @@ -100,7 +100,7 @@ static void __init origen_machine_init(void) MACHINE_START(ORIGEN, "ORIGEN") /* Maintainer: JeongHyeon Kim */ - .boot_params = S5P_PA_SDRAM + 0x100, + .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = origen_map_io, .init_machine = origen_machine_init, diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c index a16eb569a3e6..2c1a076c6a73 100644 --- a/arch/arm/mach-exynos4/mach-smdkv310.c +++ b/arch/arm/mach-exynos4/mach-smdkv310.c @@ -324,7 +324,7 @@ static void __init smdkv310_machine_init(void) MACHINE_START(SMDKV310, "SMDKV310") /* Maintainer: Kukjin Kim */ /* Maintainer: Changhwan Youn */ - .boot_params = S5P_PA_SDRAM + 0x100, + .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = smdkv310_map_io, .init_machine = smdkv310_machine_init, @@ -333,7 +333,7 @@ MACHINE_END MACHINE_START(SMDKC210, "SMDKC210") /* Maintainer: Kukjin Kim */ - .boot_params = S5P_PA_SDRAM + 0x100, + .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = smdkv310_map_io, .init_machine = smdkv310_machine_init, -- cgit v1.2.3 From 637c2afa57ec9cd0ddc8879ea0cda4d8835ba71d Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Tue, 4 Oct 2011 17:02:58 +0900 Subject: ARM: EXYNOS4: Add support PPI in external GIC To support PPI in external GIC of EXYNOS4 SoCs, gic_arch_extn.irq_eoi, irq_unmask and irq_mask are fixed. This patch is necessary because external GIC of EXYNOS4 cannot support register banking. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos4/cpu.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index 02ec52a99274..35fe8421bc34 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c @@ -198,20 +198,25 @@ void __init exynos4_init_clocks(int xtal) exynos4_setup_clocks(); } -static void exynos4_gic_irq_eoi(struct irq_data *d) +static void exynos4_gic_irq_fix_base(struct irq_data *d) { struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); gic_data->cpu_base = S5P_VA_GIC_CPU + (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); + + gic_data->dist_base = S5P_VA_GIC_DIST + + (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); } void __init exynos4_init_irq(void) { int irq; - gic_init(0, IRQ_SPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); - gic_arch_extn.irq_eoi = exynos4_gic_irq_eoi; + gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); + gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; + gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; + gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; for (irq = 0; irq < MAX_COMBINER_NR; irq++) { -- cgit v1.2.3 From 3a062281129229b50e06547af3110f8eccd2f4e4 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Tue, 4 Oct 2011 17:02:58 +0900 Subject: ARM: EXYNOS4: Add support MCT PPI for EXYNOS4212 This patch implements clock event timer using MCT PPI and make EXYNOS4212 use MCT PPI instead of MCT SPI. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos4/include/mach/entry-macro.S | 6 +++ arch/arm/mach-exynos4/include/mach/irqs.h | 2 + arch/arm/mach-exynos4/mct.c | 55 +++++++++++++++++++----- 3 files changed, 53 insertions(+), 10 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S index d7a1e281ce7a..61393dcf5559 100644 --- a/arch/arm/mach-exynos4/include/mach/entry-macro.S +++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S @@ -80,4 +80,10 @@ /* As above, this assumes that irqstat and base are preserved.. */ .macro test_for_ltirq, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + mov \tmp, #0 + cmp \irqnr, #28 + moveq \tmp, #1 + streq \irqstat, [\base, #GIC_CPU_EOI] + cmp \tmp, #0 .endm diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h index f8952f8f3757..2d3f6bcd9bc0 100644 --- a/arch/arm/mach-exynos4/include/mach/irqs.h +++ b/arch/arm/mach-exynos4/include/mach/irqs.h @@ -19,6 +19,8 @@ #define IRQ_PPI(x) S5P_IRQ(x+16) +#define IRQ_MCT_LOCALTIMER IRQ_PPI(12) + /* SPI: Shared Peripheral Interrupt */ #define IRQ_SPI(x) S5P_IRQ(x+32) diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c index ddd86864fb83..f43f3faa6495 100644 --- a/arch/arm/mach-exynos4/mct.c +++ b/arch/arm/mach-exynos4/mct.c @@ -20,12 +20,23 @@ #include #include +#include + +#include + #include +#include #include #include +enum { + MCT_INT_SPI, + MCT_INT_PPI +}; + static unsigned long clk_cnt_per_tick; static unsigned long clk_rate; +static unsigned int mct_int_type; struct mct_clock_event_device { struct clock_event_device *evt; @@ -321,9 +332,8 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode, } } -static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) +static inline int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) { - struct mct_clock_event_device *mevt = dev_id; struct clock_event_device *evt = mevt->evt; /* @@ -335,7 +345,20 @@ static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) exynos4_mct_tick_stop(mevt); /* Clear the MCT tick interrupt */ - exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); + if (__raw_readl(mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) { + exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); + return 1; + } else { + return 0; + } +} + +static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) +{ + struct mct_clock_event_device *mevt = dev_id; + struct clock_event_device *evt = mevt->evt; + + exynos4_mct_tick_clear(mevt); evt->event_handler(evt); @@ -384,13 +407,17 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) exynos4_mct_write(0x1, mct_tick[cpu].base + MCT_L_TCNTB_OFFSET); - if (cpu == 0) { - mct_tick0_event_irq.dev_id = &mct_tick[cpu]; - setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq); + if (mct_int_type == MCT_INT_SPI) { + if (cpu == 0) { + mct_tick0_event_irq.dev_id = &mct_tick[cpu]; + setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq); + } else { + mct_tick1_event_irq.dev_id = &mct_tick[cpu]; + setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq); + irq_set_affinity(IRQ_MCT_L1, cpumask_of(1)); + } } else { - mct_tick1_event_irq.dev_id = &mct_tick[cpu]; - setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq); - irq_set_affinity(IRQ_MCT_L1, cpumask_of(1)); + gic_enable_ppi(IRQ_MCT_LOCALTIMER); } } @@ -404,7 +431,10 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt) int local_timer_ack(void) { - return 0; + unsigned int cpu = smp_processor_id(); + struct mct_clock_event_device *mevt = &mct_tick[cpu]; + + return exynos4_mct_tick_clear(mevt); } #endif /* CONFIG_LOCAL_TIMERS */ @@ -419,6 +449,11 @@ static void __init exynos4_timer_resources(void) static void __init exynos4_timer_init(void) { + if (soc_is_exynos4210()) + mct_int_type = MCT_INT_SPI; + else + mct_int_type = MCT_INT_PPI; + exynos4_timer_resources(); exynos4_clocksource_init(); exynos4_clockevent_init(); -- cgit v1.2.3 From e6a275a8f92392f27e3accd6182d52627ef37258 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Tue, 4 Oct 2011 17:08:56 +0900 Subject: ARM: EXYNOS4: Add support new EXYNOS4412 SoC This patch adds Samsung EXYNOS4412 SoC support. The EXYNOS4412 integrates a ARM Cortex A9 quad-core. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos4/Kconfig | 5 +++++ arch/arm/mach-exynos4/cpu.c | 4 ++-- arch/arm/plat-s5p/cpu.c | 9 +++++++++ arch/arm/plat-samsung/include/plat/cpu.h | 8 ++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index c595bb03f417..c255d6f7ec5f 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -20,6 +20,11 @@ config SOC_EXYNOS4212 help Enable EXYNOS4212 SoC support +config SOC_EXYNOS4412 + bool + help + Enable EXYNOS4412 SoC support + config EXYNOS4_MCT bool default y diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index 35fe8421bc34..940bc12f7547 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c @@ -191,7 +191,7 @@ void __init exynos4_init_clocks(int xtal) if (soc_is_exynos4210()) exynos4210_register_clocks(); - else if (soc_is_exynos4212()) + else if (soc_is_exynos4212() || soc_is_exynos4412()) exynos4212_register_clocks(); exynos4_register_clocks(); @@ -255,7 +255,7 @@ static int __init exynos4_l2x0_cache_init(void) if (soc_is_exynos4210()) __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); - else if (soc_is_exynos4212()) + else if (soc_is_exynos4212() || soc_is_exynos4412()) __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); /* L2X0 Prefetch Control */ diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c index 909507bae2fa..7b0a28f73a68 100644 --- a/arch/arm/plat-s5p/cpu.c +++ b/arch/arm/plat-s5p/cpu.c @@ -34,6 +34,7 @@ static const char name_s5pc100[] = "S5PC100"; static const char name_s5pv210[] = "S5PV210/S5PC110"; static const char name_exynos4210[] = "EXYNOS4210"; static const char name_exynos4212[] = "EXYNOS4212"; +static const char name_exynos4412[] = "EXYNOS4412"; static struct cpu_table cpu_ids[] __initdata = { { @@ -84,6 +85,14 @@ static struct cpu_table cpu_ids[] __initdata = { .init_uarts = exynos4_init_uarts, .init = exynos4_init, .name = name_exynos4212, + }, { + .idcode = EXYNOS4412_CPU_ID, + .idmask = EXYNOS4_CPU_MASK, + .map_io = exynos4_map_io, + .init_clocks = exynos4_init_clocks, + .init_uarts = exynos4_init_uarts, + .init = exynos4_init, + .name = name_exynos4412, }, }; diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 1bbbbb420be7..54f370f0fc07 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -40,6 +40,7 @@ extern unsigned long samsung_cpu_id; #define EXYNOS4210_CPU_ID 0x43210000 #define EXYNOS4212_CPU_ID 0x43220000 +#define EXYNOS4412_CPU_ID 0xE4412200 #define EXYNOS4_CPU_MASK 0xFFFE0000 #define IS_SAMSUNG_CPU(name, id, mask) \ @@ -56,6 +57,7 @@ IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK) IS_SAMSUNG_CPU(s5pv210, S5PV210_CPU_ID, S5PV210_CPU_MASK) IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS4_CPU_MASK) IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK) +IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK) #if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \ defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \ @@ -108,6 +110,12 @@ IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK) # define soc_is_exynos4212() 0 #endif +#if defined(CONFIG_SOC_EXYNOS4412) +# define soc_is_exynos4412() is_samsung_exynos4412() +#else +# define soc_is_exynos4412() 0 +#endif + #define EXYNOS4210_REV_0 (0x0) #define EXYNOS4210_REV_1_0 (0x10) #define EXYNOS4210_REV_1_1 (0x11) -- cgit v1.2.3 From b88b1cc72e2bbb55c56f2df55b5ad59a18ad1464 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Tue, 4 Oct 2011 17:08:56 +0900 Subject: ARM: EXYNOS4: Add support clock for EXYNOS4412 This patch makes EXYNOS4412 use same clock code for EXYNOS4212 because the clock hierarchy of both SoCs are same. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos4/clock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c index f26aea3e1bbf..2a037cc221d0 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -1149,7 +1149,7 @@ static unsigned long exynos4_fout_apll_get_rate(struct clk *clk) if (soc_is_exynos4210()) return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508); - else if (soc_is_exynos4212()) + else if (soc_is_exynos4212() || soc_is_exynos4412()) return s5p_get_pll35xx(xtal_rate, __raw_readl(S5P_APLL_CON0)); else return 0; @@ -1200,7 +1200,7 @@ void __init_or_cpufreq exynos4_setup_clocks(void) vpllsrc = clk_get_rate(&clk_vpllsrc.clk); vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), __raw_readl(S5P_VPLL_CON1), pll_4650c); - } else if (soc_is_exynos4212()) { + } else if (soc_is_exynos4212() || soc_is_exynos4412()) { apll = s5p_get_pll35xx(xtal, __raw_readl(S5P_APLL_CON0)); mpll = s5p_get_pll35xx(xtal, __raw_readl(S5P_MPLL_CON0)); epll = s5p_get_pll36xx(xtal, __raw_readl(S5P_EPLL_CON0), -- cgit v1.2.3 From 90a454b4c5ef16ec71797b3dcaf454e604c786a3 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Tue, 4 Oct 2011 17:08:57 +0900 Subject: ARM: EXYNOS4: Add functions for gic interrupt handling This patch adds two functions for gic interrupt handling. 1. Add interrupt handling of 4 cores. 2. Dynamically set gic bank offset according to the type of soc. Gic bank offset of EXYNOS4412 is 0x4000 while the offset of EXYNOS4210 and EXYNOS4212 is 0x8000. This patch is necessary because EXYNOS4 socs cannot support GIC register banking as described in commit aab74d3e75364. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos4/cpu.c | 8 ++++++-- arch/arm/mach-exynos4/include/mach/entry-macro.S | 23 ++++++++++++++++++----- arch/arm/mach-exynos4/include/mach/map.h | 1 - arch/arm/mach-exynos4/platsmp.c | 5 +++-- 4 files changed, 27 insertions(+), 10 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index 940bc12f7547..a348434f17b5 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c @@ -32,6 +32,8 @@ #include #include +unsigned int gic_bank_offset __read_mostly; + extern int combiner_init(unsigned int combiner_nr, void __iomem *base, unsigned int irq_start); extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); @@ -203,16 +205,18 @@ static void exynos4_gic_irq_fix_base(struct irq_data *d) struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); gic_data->cpu_base = S5P_VA_GIC_CPU + - (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); + (gic_bank_offset * smp_processor_id()); gic_data->dist_base = S5P_VA_GIC_DIST + - (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); + (gic_bank_offset * smp_processor_id()); } void __init exynos4_init_irq(void) { int irq; + gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; + gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S index 61393dcf5559..4c9adbd87eac 100644 --- a/arch/arm/mach-exynos4/include/mach/entry-macro.S +++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S @@ -17,12 +17,25 @@ .endm .macro get_irqnr_preamble, base, tmp - ldr \base, =gic_cpu_base_addr + mov \tmp, #0 + + mrc p15, 0, \base, c0, c0, 5 + and \base, \base, #3 + cmp \base, #0 + beq 1f + + ldr \tmp, =gic_bank_offset + ldr \tmp, [\tmp] + cmp \base, #1 + beq 1f + + cmp \base, #2 + addeq \tmp, \tmp, \tmp + addne \tmp, \tmp, \tmp, LSL #1 + +1: ldr \base, =gic_cpu_base_addr ldr \base, [\base] - mrc p15, 0, \tmp, c0, c0, 5 - and \tmp, \tmp, #3 - cmp \tmp, #1 - addeq \base, \base, #EXYNOS4_GIC_BANK_OFFSET + add \base, \base, \tmp .endm .macro arch_ret_to_user, tmp1, tmp2 diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h index 7073ac730855..9f97eb8499ee 100644 --- a/arch/arm/mach-exynos4/include/mach/map.h +++ b/arch/arm/mach-exynos4/include/mach/map.h @@ -62,7 +62,6 @@ #define EXYNOS4_PA_GIC_CPU 0x10480000 #define EXYNOS4_PA_GIC_DIST 0x10490000 -#define EXYNOS4_GIC_BANK_OFFSET 0x8000 #define EXYNOS4_PA_COREPERI 0x10500000 #define EXYNOS4_PA_TWD 0x10500600 diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c index a3346e36d0ae..d5f0f299ba0d 100644 --- a/arch/arm/mach-exynos4/platsmp.c +++ b/arch/arm/mach-exynos4/platsmp.c @@ -32,6 +32,7 @@ #include +extern unsigned int gic_bank_offset; extern void exynos4_secondary_startup(void); #define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ @@ -67,9 +68,9 @@ static DEFINE_SPINLOCK(boot_lock); static void __cpuinit exynos4_gic_secondary_init(void) { void __iomem *dist_base = S5P_VA_GIC_DIST + - (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); + (gic_bank_offset * smp_processor_id()); void __iomem *cpu_base = S5P_VA_GIC_CPU + - (EXYNOS4_GIC_BANK_OFFSET * smp_processor_id()); + (gic_bank_offset * smp_processor_id()); int i; /* -- cgit v1.2.3 From c8987470a3a3e56295ee8c9130f5298e807bf4f7 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Tue, 4 Oct 2011 17:09:26 +0900 Subject: ARM: EXYNOS4: Add MCT support for EXYNOS4412 Current MCT implementation only provide 2 event timers, thus cannot support EXYNOS4412 which has 4 CPU cores. This patch fixes MCT implementation to support SoCs with 4 cores. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos4/include/mach/regs-mct.h | 5 +- arch/arm/mach-exynos4/mct.c | 113 ++++++++++++-------------- 2 files changed, 56 insertions(+), 62 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-exynos4/include/mach/regs-mct.h b/arch/arm/mach-exynos4/include/mach/regs-mct.h index ca9c8434b023..80dd02ad6d61 100644 --- a/arch/arm/mach-exynos4/include/mach/regs-mct.h +++ b/arch/arm/mach-exynos4/include/mach/regs-mct.h @@ -31,8 +31,9 @@ #define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248) #define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C) -#define EXYNOS4_MCT_L0_BASE EXYNOS4_MCTREG(0x300) -#define EXYNOS4_MCT_L1_BASE EXYNOS4_MCTREG(0x400) +#define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300) +#define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x)) +#define EXYNOS4_MCT_L_MASK (0xffffff00) #define MCT_L_TCNTB_OFFSET (0x00) #define MCT_L_ICNTB_OFFSET (0x08) diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c index f43f3faa6495..eb182f29f48f 100644 --- a/arch/arm/mach-exynos4/mct.c +++ b/arch/arm/mach-exynos4/mct.c @@ -41,9 +41,10 @@ static unsigned int mct_int_type; struct mct_clock_event_device { struct clock_event_device *evt; void __iomem *base; + char name[10]; }; -struct mct_clock_event_device mct_tick[2]; +struct mct_clock_event_device mct_tick[NR_CPUS]; static void exynos4_mct_write(unsigned int value, void *addr) { @@ -53,57 +54,53 @@ static void exynos4_mct_write(unsigned int value, void *addr) __raw_writel(value, addr); - switch ((u32) addr) { - case (u32) EXYNOS4_MCT_G_TCON: - stat_addr = EXYNOS4_MCT_G_WSTAT; - mask = 1 << 16; /* G_TCON write status */ - break; - case (u32) EXYNOS4_MCT_G_COMP0_L: - stat_addr = EXYNOS4_MCT_G_WSTAT; - mask = 1 << 0; /* G_COMP0_L write status */ - break; - case (u32) EXYNOS4_MCT_G_COMP0_U: - stat_addr = EXYNOS4_MCT_G_WSTAT; - mask = 1 << 1; /* G_COMP0_U write status */ - break; - case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR: - stat_addr = EXYNOS4_MCT_G_WSTAT; - mask = 1 << 2; /* G_COMP0_ADD_INCR write status */ - break; - case (u32) EXYNOS4_MCT_G_CNT_L: - stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; - mask = 1 << 0; /* G_CNT_L write status */ - break; - case (u32) EXYNOS4_MCT_G_CNT_U: - stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; - mask = 1 << 1; /* G_CNT_U write status */ - break; - case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCON_OFFSET): - stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET; - mask = 1 << 3; /* L0_TCON write status */ - break; - case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCON_OFFSET): - stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET; - mask = 1 << 3; /* L1_TCON write status */ - break; - case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCNTB_OFFSET): - stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET; - mask = 1 << 0; /* L0_TCNTB write status */ - break; - case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCNTB_OFFSET): - stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET; - mask = 1 << 0; /* L1_TCNTB write status */ - break; - case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_ICNTB_OFFSET): - stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET; - mask = 1 << 1; /* L0_ICNTB write status */ - break; - case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_ICNTB_OFFSET): - stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET; - mask = 1 << 1; /* L1_ICNTB write status */ - break; - default: - return; + if (likely(addr >= EXYNOS4_MCT_L_BASE(0))) { + u32 base = (u32) addr & EXYNOS4_MCT_L_MASK; + switch ((u32) addr & ~EXYNOS4_MCT_L_MASK) { + case (u32) MCT_L_TCON_OFFSET: + stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET; + mask = 1 << 3; /* L_TCON write status */ + break; + case (u32) MCT_L_ICNTB_OFFSET: + stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET; + mask = 1 << 1; /* L_ICNTB write status */ + break; + case (u32) MCT_L_TCNTB_OFFSET: + stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET; + mask = 1 << 0; /* L_TCNTB write status */ + break; + default: + return; + } + } else { + switch ((u32) addr) { + case (u32) EXYNOS4_MCT_G_TCON: + stat_addr = EXYNOS4_MCT_G_WSTAT; + mask = 1 << 16; /* G_TCON write status */ + break; + case (u32) EXYNOS4_MCT_G_COMP0_L: + stat_addr = EXYNOS4_MCT_G_WSTAT; + mask = 1 << 0; /* G_COMP0_L write status */ + break; + case (u32) EXYNOS4_MCT_G_COMP0_U: + stat_addr = EXYNOS4_MCT_G_WSTAT; + mask = 1 << 1; /* G_COMP0_U write status */ + break; + case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR: + stat_addr = EXYNOS4_MCT_G_WSTAT; + mask = 1 << 2; /* G_COMP0_ADD_INCR w status */ + break; + case (u32) EXYNOS4_MCT_G_CNT_L: + stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; + mask = 1 << 0; /* G_CNT_L write status */ + break; + case (u32) EXYNOS4_MCT_G_CNT_U: + stat_addr = EXYNOS4_MCT_G_CNT_WSTAT; + mask = 1 << 1; /* G_CNT_U write status */ + break; + default: + return; + } } /* Wait maximum 1 ms until written values are applied */ @@ -332,7 +329,7 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode, } } -static inline int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) +static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) { struct clock_event_device *evt = mevt->evt; @@ -383,14 +380,10 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) mct_tick[cpu].evt = evt; - if (cpu == 0) { - mct_tick[cpu].base = EXYNOS4_MCT_L0_BASE; - evt->name = "mct_tick0"; - } else { - mct_tick[cpu].base = EXYNOS4_MCT_L1_BASE; - evt->name = "mct_tick1"; - } + mct_tick[cpu].base = EXYNOS4_MCT_L_BASE(cpu); + sprintf(mct_tick[cpu].name, "mct_tick%d", cpu); + evt->name = mct_tick[cpu].name; evt->cpumask = cpumask_of(cpu); evt->set_next_event = exynos4_tick_set_next_event; evt->set_mode = exynos4_tick_set_mode; -- cgit v1.2.3 From 31451afd2480caf3ae15da56cf9fc3cb3fb821cb Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Tue, 4 Oct 2011 17:09:26 +0900 Subject: ARM: EXYNOS4: Add support SMDK4412 Board SMDK4412 board is same as a SMDK4212 board except that it has EXYNOS4412 SoC, thus it can share machine code with SMDK4212. This patch renames mach-smdk4212.c to mach-smdk4x12.c to support both SMDK4212 and SMDK4412 board with one machine file. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos4/Kconfig | 9 + arch/arm/mach-exynos4/Makefile | 3 +- arch/arm/mach-exynos4/mach-smdk4212.c | 292 -------------------------------- arch/arm/mach-exynos4/mach-smdk4x12.c | 302 ++++++++++++++++++++++++++++++++++ 4 files changed, 313 insertions(+), 293 deletions(-) delete mode 100644 arch/arm/mach-exynos4/mach-smdk4212.c create mode 100644 arch/arm/mach-exynos4/mach-smdk4x12.c (limited to 'arch/arm') diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index c255d6f7ec5f..fec23859388b 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -248,6 +248,15 @@ config MACH_SMDK4212 help Machine support for Samsung SMDK4212 +comment "EXYNOS4412 Boards" + +config MACH_SMDK4412 + bool "SMDK4412" + select SOC_EXYNOS4412 + select MACH_SMDK4212 + help + Machine support for Samsung SMDK4412 + endmenu comment "Configuration for HSMMC bus width" diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile index e19cd12d264e..c9b2e1f97e44 100644 --- a/arch/arm/mach-exynos4/Makefile +++ b/arch/arm/mach-exynos4/Makefile @@ -34,7 +34,8 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o obj-$(CONFIG_MACH_NURI) += mach-nuri.o obj-$(CONFIG_MACH_ORIGEN) += mach-origen.o -obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4212.o +obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4x12.o +obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o # device support diff --git a/arch/arm/mach-exynos4/mach-smdk4212.c b/arch/arm/mach-exynos4/mach-smdk4212.c deleted file mode 100644 index 3479a933a6de..000000000000 --- a/arch/arm/mach-exynos4/mach-smdk4212.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * linux/arch/arm/mach-exynos4/mach-smdk4212.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* Following are default values for UCON, ULCON and UFCON UART registers */ -#define SMDK4212_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ - S3C2410_UCON_RXILEVEL | \ - S3C2410_UCON_TXIRQMODE | \ - S3C2410_UCON_RXIRQMODE | \ - S3C2410_UCON_RXFIFO_TOI | \ - S3C2443_UCON_RXERR_IRQEN) - -#define SMDK4212_ULCON_DEFAULT S3C2410_LCON_CS8 - -#define SMDK4212_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ - S5PV210_UFCON_TXTRIG4 | \ - S5PV210_UFCON_RXTRIG4) - -static struct s3c2410_uartcfg smdk4212_uartcfgs[] __initdata = { - [0] = { - .hwport = 0, - .flags = 0, - .ucon = SMDK4212_UCON_DEFAULT, - .ulcon = SMDK4212_ULCON_DEFAULT, - .ufcon = SMDK4212_UFCON_DEFAULT, - }, - [1] = { - .hwport = 1, - .flags = 0, - .ucon = SMDK4212_UCON_DEFAULT, - .ulcon = SMDK4212_ULCON_DEFAULT, - .ufcon = SMDK4212_UFCON_DEFAULT, - }, - [2] = { - .hwport = 2, - .flags = 0, - .ucon = SMDK4212_UCON_DEFAULT, - .ulcon = SMDK4212_ULCON_DEFAULT, - .ufcon = SMDK4212_UFCON_DEFAULT, - }, - [3] = { - .hwport = 3, - .flags = 0, - .ucon = SMDK4212_UCON_DEFAULT, - .ulcon = SMDK4212_ULCON_DEFAULT, - .ufcon = SMDK4212_UFCON_DEFAULT, - }, -}; - -static struct s3c_sdhci_platdata smdk4212_hsmmc2_pdata __initdata = { - .cd_type = S3C_SDHCI_CD_INTERNAL, - .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, -#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT - .max_width = 8, - .host_caps = MMC_CAP_8_BIT_DATA, -#endif -}; - -static struct s3c_sdhci_platdata smdk4212_hsmmc3_pdata __initdata = { - .cd_type = S3C_SDHCI_CD_INTERNAL, - .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, -}; - -static struct regulator_consumer_supply max8997_buck1 = - REGULATOR_SUPPLY("vdd_arm", NULL); - -static struct regulator_consumer_supply max8997_buck2 = - REGULATOR_SUPPLY("vdd_int", NULL); - -static struct regulator_consumer_supply max8997_buck3 = - REGULATOR_SUPPLY("vdd_g3d", NULL); - -static struct regulator_init_data max8997_buck1_data = { - .constraints = { - .name = "VDD_ARM_SMDK4212", - .min_uV = 925000, - .max_uV = 1350000, - .always_on = 1, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, - .state_mem = { - .disabled = 1, - }, - }, - .num_consumer_supplies = 1, - .consumer_supplies = &max8997_buck1, -}; - -static struct regulator_init_data max8997_buck2_data = { - .constraints = { - .name = "VDD_INT_SMDK4212", - .min_uV = 950000, - .max_uV = 1150000, - .always_on = 1, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, - .state_mem = { - .disabled = 1, - }, - }, - .num_consumer_supplies = 1, - .consumer_supplies = &max8997_buck2, -}; - -static struct regulator_init_data max8997_buck3_data = { - .constraints = { - .name = "VDD_G3D_SMDK4212", - .min_uV = 950000, - .max_uV = 1150000, - .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | - REGULATOR_CHANGE_STATUS, - .state_mem = { - .disabled = 1, - }, - }, - .num_consumer_supplies = 1, - .consumer_supplies = &max8997_buck3, -}; - -static struct max8997_regulator_data smdk4212_max8997_regulators[] = { - { MAX8997_BUCK1, &max8997_buck1_data }, - { MAX8997_BUCK2, &max8997_buck2_data }, - { MAX8997_BUCK3, &max8997_buck3_data }, -}; - -static struct max8997_platform_data smdk4212_max8997_pdata = { - .num_regulators = ARRAY_SIZE(smdk4212_max8997_regulators), - .regulators = smdk4212_max8997_regulators, - - .buck1_voltage[0] = 1100000, /* 1.1V */ - .buck1_voltage[1] = 1100000, /* 1.1V */ - .buck1_voltage[2] = 1100000, /* 1.1V */ - .buck1_voltage[3] = 1100000, /* 1.1V */ - .buck1_voltage[4] = 1100000, /* 1.1V */ - .buck1_voltage[5] = 1100000, /* 1.1V */ - .buck1_voltage[6] = 1000000, /* 1.0V */ - .buck1_voltage[7] = 950000, /* 0.95V */ - - .buck2_voltage[0] = 1100000, /* 1.1V */ - .buck2_voltage[1] = 1000000, /* 1.0V */ - .buck2_voltage[2] = 950000, /* 0.95V */ - .buck2_voltage[3] = 900000, /* 0.9V */ - .buck2_voltage[4] = 1100000, /* 1.1V */ - .buck2_voltage[5] = 1000000, /* 1.0V */ - .buck2_voltage[6] = 950000, /* 0.95V */ - .buck2_voltage[7] = 900000, /* 0.9V */ - - .buck5_voltage[0] = 1100000, /* 1.1V */ - .buck5_voltage[1] = 1100000, /* 1.1V */ - .buck5_voltage[2] = 1100000, /* 1.1V */ - .buck5_voltage[3] = 1100000, /* 1.1V */ - .buck5_voltage[4] = 1100000, /* 1.1V */ - .buck5_voltage[5] = 1100000, /* 1.1V */ - .buck5_voltage[6] = 1100000, /* 1.1V */ - .buck5_voltage[7] = 1100000, /* 1.1V */ -}; - -static struct i2c_board_info smdk4212_i2c_devs0[] __initdata = { - { - I2C_BOARD_INFO("max8997", 0x66), - .platform_data = &smdk4212_max8997_pdata, - } -}; - -static struct i2c_board_info smdk4212_i2c_devs1[] __initdata = { - { I2C_BOARD_INFO("wm8994", 0x1a), } -}; - -static struct i2c_board_info smdk4212_i2c_devs3[] __initdata = { - /* nothing here yet */ -}; - -static struct i2c_board_info smdk4212_i2c_devs7[] __initdata = { - /* nothing here yet */ -}; - -static struct samsung_bl_gpio_info smdk4212_bl_gpio_info = { - .no = EXYNOS4_GPD0(1), - .func = S3C_GPIO_SFN(2), -}; - -static struct platform_pwm_backlight_data smdk4212_bl_data = { - .pwm_id = 1, - .pwm_period_ns = 1000, -}; - -static uint32_t smdk4212_keymap[] __initdata = { - /* KEY(row, col, keycode) */ - KEY(1, 0, KEY_D), KEY(1, 1, KEY_A), KEY(1, 2, KEY_B), - KEY(1, 3, KEY_E), KEY(1, 4, KEY_C) -}; - -static struct matrix_keymap_data smdk4212_keymap_data __initdata = { - .keymap = smdk4212_keymap, - .keymap_size = ARRAY_SIZE(smdk4212_keymap), -}; - -static struct samsung_keypad_platdata smdk4212_keypad_data __initdata = { - .keymap_data = &smdk4212_keymap_data, - .rows = 2, - .cols = 5, -}; - -static struct platform_device *smdk4212_devices[] __initdata = { - &s3c_device_hsmmc2, - &s3c_device_hsmmc3, - &s3c_device_i2c0, - &s3c_device_i2c1, - &s3c_device_i2c3, - &s3c_device_i2c7, - &s3c_device_rtc, - &s3c_device_wdt, - &samsung_device_keypad, -}; - -static void __init smdk4212_map_io(void) -{ - clk_xusbxti.rate = 24000000; - - s5p_init_io(NULL, 0, S5P_VA_CHIPID); - s3c24xx_init_clocks(clk_xusbxti.rate); - s3c24xx_init_uarts(smdk4212_uartcfgs, ARRAY_SIZE(smdk4212_uartcfgs)); -} - -static void __init smdk4212_machine_init(void) -{ - s3c_i2c0_set_platdata(NULL); - i2c_register_board_info(0, smdk4212_i2c_devs0, - ARRAY_SIZE(smdk4212_i2c_devs0)); - - s3c_i2c1_set_platdata(NULL); - i2c_register_board_info(1, smdk4212_i2c_devs1, - ARRAY_SIZE(smdk4212_i2c_devs1)); - - s3c_i2c3_set_platdata(NULL); - i2c_register_board_info(3, smdk4212_i2c_devs3, - ARRAY_SIZE(smdk4212_i2c_devs3)); - - s3c_i2c7_set_platdata(NULL); - i2c_register_board_info(7, smdk4212_i2c_devs7, - ARRAY_SIZE(smdk4212_i2c_devs7)); - - samsung_bl_set(&smdk4212_bl_gpio_info, &smdk4212_bl_data); - - samsung_keypad_set_platdata(&smdk4212_keypad_data); - - s3c_sdhci2_set_platdata(&smdk4212_hsmmc2_pdata); - s3c_sdhci3_set_platdata(&smdk4212_hsmmc3_pdata); - - platform_add_devices(smdk4212_devices, ARRAY_SIZE(smdk4212_devices)); -} - -MACHINE_START(SMDK4212, "SMDK4212") - /* Maintainer: Kukjin Kim */ - .boot_params = S5P_PA_SDRAM + 0x100, - .init_irq = exynos4_init_irq, - .map_io = smdk4212_map_io, - .init_machine = smdk4212_machine_init, - .timer = &exynos4_timer, -MACHINE_END diff --git a/arch/arm/mach-exynos4/mach-smdk4x12.c b/arch/arm/mach-exynos4/mach-smdk4x12.c new file mode 100644 index 000000000000..fcf2e0e23d53 --- /dev/null +++ b/arch/arm/mach-exynos4/mach-smdk4x12.c @@ -0,0 +1,302 @@ +/* + * linux/arch/arm/mach-exynos4/mach-smdk4x12.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Following are default values for UCON, ULCON and UFCON UART registers */ +#define SMDK4X12_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ + S3C2410_UCON_RXILEVEL | \ + S3C2410_UCON_TXIRQMODE | \ + S3C2410_UCON_RXIRQMODE | \ + S3C2410_UCON_RXFIFO_TOI | \ + S3C2443_UCON_RXERR_IRQEN) + +#define SMDK4X12_ULCON_DEFAULT S3C2410_LCON_CS8 + +#define SMDK4X12_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ + S5PV210_UFCON_TXTRIG4 | \ + S5PV210_UFCON_RXTRIG4) + +static struct s3c2410_uartcfg smdk4x12_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = SMDK4X12_UCON_DEFAULT, + .ulcon = SMDK4X12_ULCON_DEFAULT, + .ufcon = SMDK4X12_UFCON_DEFAULT, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = SMDK4X12_UCON_DEFAULT, + .ulcon = SMDK4X12_ULCON_DEFAULT, + .ufcon = SMDK4X12_UFCON_DEFAULT, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = SMDK4X12_UCON_DEFAULT, + .ulcon = SMDK4X12_ULCON_DEFAULT, + .ufcon = SMDK4X12_UFCON_DEFAULT, + }, + [3] = { + .hwport = 3, + .flags = 0, + .ucon = SMDK4X12_UCON_DEFAULT, + .ulcon = SMDK4X12_ULCON_DEFAULT, + .ufcon = SMDK4X12_UFCON_DEFAULT, + }, +}; + +static struct s3c_sdhci_platdata smdk4x12_hsmmc2_pdata __initdata = { + .cd_type = S3C_SDHCI_CD_INTERNAL, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT + .max_width = 8, + .host_caps = MMC_CAP_8_BIT_DATA, +#endif +}; + +static struct s3c_sdhci_platdata smdk4x12_hsmmc3_pdata __initdata = { + .cd_type = S3C_SDHCI_CD_INTERNAL, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +}; + +static struct regulator_consumer_supply max8997_buck1 = + REGULATOR_SUPPLY("vdd_arm", NULL); + +static struct regulator_consumer_supply max8997_buck2 = + REGULATOR_SUPPLY("vdd_int", NULL); + +static struct regulator_consumer_supply max8997_buck3 = + REGULATOR_SUPPLY("vdd_g3d", NULL); + +static struct regulator_init_data max8997_buck1_data = { + .constraints = { + .name = "VDD_ARM_SMDK4X12", + .min_uV = 925000, + .max_uV = 1350000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max8997_buck1, +}; + +static struct regulator_init_data max8997_buck2_data = { + .constraints = { + .name = "VDD_INT_SMDK4X12", + .min_uV = 950000, + .max_uV = 1150000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max8997_buck2, +}; + +static struct regulator_init_data max8997_buck3_data = { + .constraints = { + .name = "VDD_G3D_SMDK4X12", + .min_uV = 950000, + .max_uV = 1150000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max8997_buck3, +}; + +static struct max8997_regulator_data smdk4x12_max8997_regulators[] = { + { MAX8997_BUCK1, &max8997_buck1_data }, + { MAX8997_BUCK2, &max8997_buck2_data }, + { MAX8997_BUCK3, &max8997_buck3_data }, +}; + +static struct max8997_platform_data smdk4x12_max8997_pdata = { + .num_regulators = ARRAY_SIZE(smdk4x12_max8997_regulators), + .regulators = smdk4x12_max8997_regulators, + + .buck1_voltage[0] = 1100000, /* 1.1V */ + .buck1_voltage[1] = 1100000, /* 1.1V */ + .buck1_voltage[2] = 1100000, /* 1.1V */ + .buck1_voltage[3] = 1100000, /* 1.1V */ + .buck1_voltage[4] = 1100000, /* 1.1V */ + .buck1_voltage[5] = 1100000, /* 1.1V */ + .buck1_voltage[6] = 1000000, /* 1.0V */ + .buck1_voltage[7] = 950000, /* 0.95V */ + + .buck2_voltage[0] = 1100000, /* 1.1V */ + .buck2_voltage[1] = 1000000, /* 1.0V */ + .buck2_voltage[2] = 950000, /* 0.95V */ + .buck2_voltage[3] = 900000, /* 0.9V */ + .buck2_voltage[4] = 1100000, /* 1.1V */ + .buck2_voltage[5] = 1000000, /* 1.0V */ + .buck2_voltage[6] = 950000, /* 0.95V */ + .buck2_voltage[7] = 900000, /* 0.9V */ + + .buck5_voltage[0] = 1100000, /* 1.1V */ + .buck5_voltage[1] = 1100000, /* 1.1V */ + .buck5_voltage[2] = 1100000, /* 1.1V */ + .buck5_voltage[3] = 1100000, /* 1.1V */ + .buck5_voltage[4] = 1100000, /* 1.1V */ + .buck5_voltage[5] = 1100000, /* 1.1V */ + .buck5_voltage[6] = 1100000, /* 1.1V */ + .buck5_voltage[7] = 1100000, /* 1.1V */ +}; + +static struct i2c_board_info smdk4x12_i2c_devs0[] __initdata = { + { + I2C_BOARD_INFO("max8997", 0x66), + .platform_data = &smdk4x12_max8997_pdata, + } +}; + +static struct i2c_board_info smdk4x12_i2c_devs1[] __initdata = { + { I2C_BOARD_INFO("wm8994", 0x1a), } +}; + +static struct i2c_board_info smdk4x12_i2c_devs3[] __initdata = { + /* nothing here yet */ +}; + +static struct i2c_board_info smdk4x12_i2c_devs7[] __initdata = { + /* nothing here yet */ +}; + +static struct samsung_bl_gpio_info smdk4x12_bl_gpio_info = { + .no = EXYNOS4_GPD0(1), + .func = S3C_GPIO_SFN(2), +}; + +static struct platform_pwm_backlight_data smdk4x12_bl_data = { + .pwm_id = 1, + .pwm_period_ns = 1000, +}; + +static uint32_t smdk4x12_keymap[] __initdata = { + /* KEY(row, col, keycode) */ + KEY(1, 0, KEY_D), KEY(1, 1, KEY_A), KEY(1, 2, KEY_B), + KEY(1, 3, KEY_E), KEY(1, 4, KEY_C) +}; + +static struct matrix_keymap_data smdk4x12_keymap_data __initdata = { + .keymap = smdk4x12_keymap, + .keymap_size = ARRAY_SIZE(smdk4x12_keymap), +}; + +static struct samsung_keypad_platdata smdk4x12_keypad_data __initdata = { + .keymap_data = &smdk4x12_keymap_data, + .rows = 2, + .cols = 5, +}; + +static struct platform_device *smdk4x12_devices[] __initdata = { + &s3c_device_hsmmc2, + &s3c_device_hsmmc3, + &s3c_device_i2c0, + &s3c_device_i2c1, + &s3c_device_i2c3, + &s3c_device_i2c7, + &s3c_device_rtc, + &s3c_device_wdt, + &samsung_device_keypad, +}; + +static void __init smdk4x12_map_io(void) +{ + clk_xusbxti.rate = 24000000; + + s5p_init_io(NULL, 0, S5P_VA_CHIPID); + s3c24xx_init_clocks(clk_xusbxti.rate); + s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs)); +} + +static void __init smdk4x12_machine_init(void) +{ + s3c_i2c0_set_platdata(NULL); + i2c_register_board_info(0, smdk4x12_i2c_devs0, + ARRAY_SIZE(smdk4x12_i2c_devs0)); + + s3c_i2c1_set_platdata(NULL); + i2c_register_board_info(1, smdk4x12_i2c_devs1, + ARRAY_SIZE(smdk4x12_i2c_devs1)); + + s3c_i2c3_set_platdata(NULL); + i2c_register_board_info(3, smdk4x12_i2c_devs3, + ARRAY_SIZE(smdk4x12_i2c_devs3)); + + s3c_i2c7_set_platdata(NULL); + i2c_register_board_info(7, smdk4x12_i2c_devs7, + ARRAY_SIZE(smdk4x12_i2c_devs7)); + + samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data); + + samsung_keypad_set_platdata(&smdk4x12_keypad_data); + + s3c_sdhci2_set_platdata(&smdk4x12_hsmmc2_pdata); + s3c_sdhci3_set_platdata(&smdk4x12_hsmmc3_pdata); + + platform_add_devices(smdk4x12_devices, ARRAY_SIZE(smdk4x12_devices)); +} + +MACHINE_START(SMDK4212, "SMDK4212") + /* Maintainer: Kukjin Kim */ + .atag_offset = 0x100, + .init_irq = exynos4_init_irq, + .map_io = smdk4x12_map_io, + .init_machine = smdk4x12_machine_init, + .timer = &exynos4_timer, +MACHINE_END + +MACHINE_START(SMDK4412, "SMDK4412") + /* Maintainer: Kukjin Kim */ + /* Maintainer: Changhwan Youn */ + .atag_offset = 0x100, + .init_irq = exynos4_init_irq, + .map_io = smdk4x12_map_io, + .init_machine = smdk4x12_machine_init, + .timer = &exynos4_timer, +MACHINE_END -- cgit v1.2.3