diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-exynos4/Kconfig | 14 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/clock.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/cpu.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/include/mach/entry-macro.S | 29 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/include/mach/irqs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/include/mach/map.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/include/mach/regs-mct.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-origen.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-smdk4x12.c (renamed from arch/arm/mach-exynos4/mach-smdk4212.c) | 128 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-smdkv310.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mct.c | 166 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/platsmp.c | 5 | ||||
-rw-r--r-- | arch/arm/plat-s5p/cpu.c | 9 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/cpu.h | 8 |
15 files changed, 251 insertions, 150 deletions
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index b6722decff9d..2dad16c8cf79 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 @@ -276,6 +281,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/clock.c b/arch/arm/mach-exynos4/clock.c index a25c81836759..db616916d7a4 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -1283,7 +1283,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; @@ -1399,7 +1399,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), diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index 2aa3df003683..5b1765b37f75 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c @@ -33,6 +33,8 @@ #include <mach/regs-irq.h> #include <mach/regs-pmu.h> +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); @@ -193,27 +195,34 @@ 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(); 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_bank_offset * smp_processor_id()); + + gic_data->dist_base = S5P_VA_GIC_DIST + + (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_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; + gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; for (irq = 0; irq < MAX_COMBINER_NR; irq++) { @@ -252,7 +261,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/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S index d7a1e281ce7a..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 @@ -80,4 +93,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 62093b9339db..dfd4b7eecb90 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/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h index 1bea7d139bb0..918a979181af 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/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/mach-origen.c b/arch/arm/mach-exynos4/mach-origen.c index 18909cf6c07d..71db8480bb5a 100644 --- a/arch/arm/mach-exynos4/mach-origen.c +++ b/arch/arm/mach-exynos4/mach-origen.c @@ -671,7 +671,7 @@ static void __init origen_machine_init(void) MACHINE_START(ORIGEN, "ORIGEN") /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */ - .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-smdk4212.c b/arch/arm/mach-exynos4/mach-smdk4x12.c index 3479a933a6de..fcf2e0e23d53 100644 --- a/arch/arm/mach-exynos4/mach-smdk4212.c +++ b/arch/arm/mach-exynos4/mach-smdk4x12.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-exynos4/mach-smdk4212.c + * linux/arch/arm/mach-exynos4/mach-smdk4x12.c * * Copyright (c) 2011 Samsung Electronics Co., Ltd. * http://www.samsung.com @@ -37,51 +37,51 @@ #include <mach/map.h> /* Following are default values for UCON, ULCON and UFCON UART registers */ -#define SMDK4212_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ +#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 SMDK4212_ULCON_DEFAULT S3C2410_LCON_CS8 +#define SMDK4X12_ULCON_DEFAULT S3C2410_LCON_CS8 -#define SMDK4212_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ +#define SMDK4X12_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ S5PV210_UFCON_TXTRIG4 | \ S5PV210_UFCON_RXTRIG4) -static struct s3c2410_uartcfg smdk4212_uartcfgs[] __initdata = { +static struct s3c2410_uartcfg smdk4x12_uartcfgs[] __initdata = { [0] = { .hwport = 0, .flags = 0, - .ucon = SMDK4212_UCON_DEFAULT, - .ulcon = SMDK4212_ULCON_DEFAULT, - .ufcon = SMDK4212_UFCON_DEFAULT, + .ucon = SMDK4X12_UCON_DEFAULT, + .ulcon = SMDK4X12_ULCON_DEFAULT, + .ufcon = SMDK4X12_UFCON_DEFAULT, }, [1] = { .hwport = 1, .flags = 0, - .ucon = SMDK4212_UCON_DEFAULT, - .ulcon = SMDK4212_ULCON_DEFAULT, - .ufcon = SMDK4212_UFCON_DEFAULT, + .ucon = SMDK4X12_UCON_DEFAULT, + .ulcon = SMDK4X12_ULCON_DEFAULT, + .ufcon = SMDK4X12_UFCON_DEFAULT, }, [2] = { .hwport = 2, .flags = 0, - .ucon = SMDK4212_UCON_DEFAULT, - .ulcon = SMDK4212_ULCON_DEFAULT, - .ufcon = SMDK4212_UFCON_DEFAULT, + .ucon = SMDK4X12_UCON_DEFAULT, + .ulcon = SMDK4X12_ULCON_DEFAULT, + .ufcon = SMDK4X12_UFCON_DEFAULT, }, [3] = { .hwport = 3, .flags = 0, - .ucon = SMDK4212_UCON_DEFAULT, - .ulcon = SMDK4212_ULCON_DEFAULT, - .ufcon = SMDK4212_UFCON_DEFAULT, + .ucon = SMDK4X12_UCON_DEFAULT, + .ulcon = SMDK4X12_ULCON_DEFAULT, + .ufcon = SMDK4X12_UFCON_DEFAULT, }, }; -static struct s3c_sdhci_platdata smdk4212_hsmmc2_pdata __initdata = { +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 @@ -90,7 +90,7 @@ static struct s3c_sdhci_platdata smdk4212_hsmmc2_pdata __initdata = { #endif }; -static struct s3c_sdhci_platdata smdk4212_hsmmc3_pdata __initdata = { +static struct s3c_sdhci_platdata smdk4x12_hsmmc3_pdata __initdata = { .cd_type = S3C_SDHCI_CD_INTERNAL, .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, }; @@ -106,7 +106,7 @@ static struct regulator_consumer_supply max8997_buck3 = static struct regulator_init_data max8997_buck1_data = { .constraints = { - .name = "VDD_ARM_SMDK4212", + .name = "VDD_ARM_SMDK4X12", .min_uV = 925000, .max_uV = 1350000, .always_on = 1, @@ -121,7 +121,7 @@ static struct regulator_init_data max8997_buck1_data = { static struct regulator_init_data max8997_buck2_data = { .constraints = { - .name = "VDD_INT_SMDK4212", + .name = "VDD_INT_SMDK4X12", .min_uV = 950000, .max_uV = 1150000, .always_on = 1, @@ -136,7 +136,7 @@ static struct regulator_init_data max8997_buck2_data = { static struct regulator_init_data max8997_buck3_data = { .constraints = { - .name = "VDD_G3D_SMDK4212", + .name = "VDD_G3D_SMDK4X12", .min_uV = 950000, .max_uV = 1150000, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | @@ -149,15 +149,15 @@ static struct regulator_init_data max8997_buck3_data = { .consumer_supplies = &max8997_buck3, }; -static struct max8997_regulator_data smdk4212_max8997_regulators[] = { +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 smdk4212_max8997_pdata = { - .num_regulators = ARRAY_SIZE(smdk4212_max8997_regulators), - .regulators = smdk4212_max8997_regulators, +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 */ @@ -187,53 +187,53 @@ static struct max8997_platform_data smdk4212_max8997_pdata = { .buck5_voltage[7] = 1100000, /* 1.1V */ }; -static struct i2c_board_info smdk4212_i2c_devs0[] __initdata = { +static struct i2c_board_info smdk4x12_i2c_devs0[] __initdata = { { I2C_BOARD_INFO("max8997", 0x66), - .platform_data = &smdk4212_max8997_pdata, + .platform_data = &smdk4x12_max8997_pdata, } }; -static struct i2c_board_info smdk4212_i2c_devs1[] __initdata = { +static struct i2c_board_info smdk4x12_i2c_devs1[] __initdata = { { I2C_BOARD_INFO("wm8994", 0x1a), } }; -static struct i2c_board_info smdk4212_i2c_devs3[] __initdata = { +static struct i2c_board_info smdk4x12_i2c_devs3[] __initdata = { /* nothing here yet */ }; -static struct i2c_board_info smdk4212_i2c_devs7[] __initdata = { +static struct i2c_board_info smdk4x12_i2c_devs7[] __initdata = { /* nothing here yet */ }; -static struct samsung_bl_gpio_info smdk4212_bl_gpio_info = { +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 smdk4212_bl_data = { +static struct platform_pwm_backlight_data smdk4x12_bl_data = { .pwm_id = 1, .pwm_period_ns = 1000, }; -static uint32_t smdk4212_keymap[] __initdata = { +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 smdk4212_keymap_data __initdata = { - .keymap = smdk4212_keymap, - .keymap_size = ARRAY_SIZE(smdk4212_keymap), +static struct matrix_keymap_data smdk4x12_keymap_data __initdata = { + .keymap = smdk4x12_keymap, + .keymap_size = ARRAY_SIZE(smdk4x12_keymap), }; -static struct samsung_keypad_platdata smdk4212_keypad_data __initdata = { - .keymap_data = &smdk4212_keymap_data, +static struct samsung_keypad_platdata smdk4x12_keypad_data __initdata = { + .keymap_data = &smdk4x12_keymap_data, .rows = 2, .cols = 5, }; -static struct platform_device *smdk4212_devices[] __initdata = { +static struct platform_device *smdk4x12_devices[] __initdata = { &s3c_device_hsmmc2, &s3c_device_hsmmc3, &s3c_device_i2c0, @@ -245,48 +245,58 @@ static struct platform_device *smdk4212_devices[] __initdata = { &samsung_device_keypad, }; -static void __init smdk4212_map_io(void) +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(smdk4212_uartcfgs, ARRAY_SIZE(smdk4212_uartcfgs)); + s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs)); } -static void __init smdk4212_machine_init(void) +static void __init smdk4x12_machine_init(void) { s3c_i2c0_set_platdata(NULL); - i2c_register_board_info(0, smdk4212_i2c_devs0, - ARRAY_SIZE(smdk4212_i2c_devs0)); + i2c_register_board_info(0, smdk4x12_i2c_devs0, + ARRAY_SIZE(smdk4x12_i2c_devs0)); s3c_i2c1_set_platdata(NULL); - i2c_register_board_info(1, smdk4212_i2c_devs1, - ARRAY_SIZE(smdk4212_i2c_devs1)); + i2c_register_board_info(1, smdk4x12_i2c_devs1, + ARRAY_SIZE(smdk4x12_i2c_devs1)); s3c_i2c3_set_platdata(NULL); - i2c_register_board_info(3, smdk4212_i2c_devs3, - ARRAY_SIZE(smdk4212_i2c_devs3)); + i2c_register_board_info(3, smdk4x12_i2c_devs3, + ARRAY_SIZE(smdk4x12_i2c_devs3)); s3c_i2c7_set_platdata(NULL); - i2c_register_board_info(7, smdk4212_i2c_devs7, - ARRAY_SIZE(smdk4212_i2c_devs7)); + i2c_register_board_info(7, smdk4x12_i2c_devs7, + ARRAY_SIZE(smdk4x12_i2c_devs7)); - samsung_bl_set(&smdk4212_bl_gpio_info, &smdk4212_bl_data); + samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data); - samsung_keypad_set_platdata(&smdk4212_keypad_data); + samsung_keypad_set_platdata(&smdk4x12_keypad_data); - s3c_sdhci2_set_platdata(&smdk4212_hsmmc2_pdata); - s3c_sdhci3_set_platdata(&smdk4212_hsmmc3_pdata); + s3c_sdhci2_set_platdata(&smdk4x12_hsmmc2_pdata); + s3c_sdhci3_set_platdata(&smdk4x12_hsmmc3_pdata); - platform_add_devices(smdk4212_devices, ARRAY_SIZE(smdk4212_devices)); + platform_add_devices(smdk4x12_devices, ARRAY_SIZE(smdk4x12_devices)); } MACHINE_START(SMDK4212, "SMDK4212") /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ - .boot_params = S5P_PA_SDRAM + 0x100, + .atag_offset = 0x100, .init_irq = exynos4_init_irq, - .map_io = smdk4212_map_io, - .init_machine = smdk4212_machine_init, + .map_io = smdk4x12_map_io, + .init_machine = smdk4x12_machine_init, + .timer = &exynos4_timer, +MACHINE_END + +MACHINE_START(SMDK4412, "SMDK4412") + /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ + /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */ + .atag_offset = 0x100, + .init_irq = exynos4_init_irq, + .map_io = smdk4x12_map_io, + .init_machine = smdk4x12_machine_init, .timer = &exynos4_timer, MACHINE_END diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c index 35a763e9a659..cec2afabe7b4 100644 --- a/arch/arm/mach-exynos4/mach-smdkv310.c +++ b/arch/arm/mach-exynos4/mach-smdkv310.c @@ -372,7 +372,7 @@ static void __init smdkv310_machine_init(void) MACHINE_START(SMDKV310, "SMDKV310") /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */ - .boot_params = S5P_PA_SDRAM + 0x100, + .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = smdkv310_map_io, .init_machine = smdkv310_machine_init, @@ -382,7 +382,7 @@ MACHINE_END MACHINE_START(SMDKC210, "SMDKC210") /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ - .boot_params = S5P_PA_SDRAM + 0x100, + .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = smdkv310_map_io, .init_machine = smdkv310_machine_init, diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c index ddd86864fb83..eb182f29f48f 100644 --- a/arch/arm/mach-exynos4/mct.c +++ b/arch/arm/mach-exynos4/mct.c @@ -20,19 +20,31 @@ #include <linux/delay.h> #include <linux/percpu.h> +#include <asm/hardware/gic.h> + +#include <plat/cpu.h> + #include <mach/map.h> +#include <mach/irqs.h> #include <mach/regs-mct.h> #include <asm/mach/time.h> +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; 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) { @@ -42,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 */ @@ -321,9 +329,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 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 +342,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); @@ -360,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; @@ -384,13 +400,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 +424,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 +442,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(); 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 <plat/cpu.h> +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; /* 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) |