diff options
author | Lee Jones <lee.jones@linaro.org> | 2012-01-12 12:50:11 +0000 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2012-01-12 12:50:11 +0000 |
commit | 72108d578689febd3579bf16be470328ded6c6d9 (patch) | |
tree | cc36ad5306ce823f8e98956c8f048f48017be3cc /arch/arm/mach-exynos4 | |
parent | 330f78a83c1f47055427e10a68733af77b2cbac8 (diff) | |
parent | 2150f72fe35397cc6d6ce39866bd0462cfbcc916 (diff) |
Automatically merging tracking-igloo_kernel-other into merging-stable-linaro-ux500-3.1stable-linaro-ux500-3.1
Conflicting files:
Diffstat (limited to 'arch/arm/mach-exynos4')
-rw-r--r-- | arch/arm/mach-exynos4/Kconfig | 22 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/Makefile.boot | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/clock.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/cpu.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/cpuidle.c | 152 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/dev-tmu.c | 68 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/include/mach/cpufreq.h | 39 | ||||
-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/pmu.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-armlex4210.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-nuri.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-origen.c | 109 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-smdkc210.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-smdkv310.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/mach-universal_c210.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/platsmp.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/pm.c | 87 | ||||
-rw-r--r-- | arch/arm/mach-exynos4/sleep.S | 29 |
20 files changed, 484 insertions, 113 deletions
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index 0c77ab99fa1..f83526865d1 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -46,6 +46,17 @@ config EXYNOS4_DEV_DWMCI help Compile in platform device definitions for DWMCI +config EXYNOS4_DEV_TMU + bool "Exynos4 tmu device support" + default n + depends on ARCH_EXYNOS4 + ---help--- + Compile in platform device definitions for TMU. This macro also + enables compilation hwmon base TMU driver and also allows compilation + of the platform device files. The platform data in this case is trip + temperature and some tmu h/w configurations related parameter. + + config EXYNOS4_SETUP_I2C1 bool help @@ -218,6 +229,17 @@ config MACH_NURI help Machine support for Samsung Mobile NURI Board. +config MACH_ORIGEN + bool "ORIGEN" + select CPU_EXYNOS4210 + select S3C_DEV_RTC + select S3C_DEV_WDT + select S3C_DEV_HSMMC2 + select EXYNOS4_DEV_TMU + select EXYNOS4_SETUP_SDHCI + help + Machine support for ORIGEN based on Samsung EXYNOS4210 + endmenu comment "Configuration for HSMMC bus width" diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile index b7fe1d7b0b1..8e5c098db7c 100644 --- a/arch/arm/mach-exynos4/Makefile +++ b/arch/arm/mach-exynos4/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o obj-$(CONFIG_MACH_ARMLEX4210) += mach-armlex4210.o obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o obj-$(CONFIG_MACH_NURI) += mach-nuri.o +obj-$(CONFIG_MACH_ORIGEN) += mach-origen.o # device support @@ -38,6 +39,7 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o +obj-$(CONFIG_EXYNOS4_DEV_TMU) += dev-tmu.o obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o diff --git a/arch/arm/mach-exynos4/Makefile.boot b/arch/arm/mach-exynos4/Makefile.boot index d65956ffb43..fcee6b5384a 100644 --- a/arch/arm/mach-exynos4/Makefile.boot +++ b/arch/arm/mach-exynos4/Makefile.boot @@ -1,2 +1,4 @@ zreladdr-y := 0x40008000 params_phys-y := 0x40000100 + +dtb-$(CONFIG_MACH_SMDKV310) += exynos4-smdkv310.dtb diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c index 86964d2e9e1..b90920e526f 100644 --- a/arch/arm/mach-exynos4/clock.c +++ b/arch/arm/mach-exynos4/clock.c @@ -468,6 +468,10 @@ static struct clk init_clocks_off[] = { .enable = exynos4_clk_ip_peril_ctrl, .ctrlbit = (1 << 15), }, { + .name = "tmu_apbif", + .enable = exynos4_clk_ip_perir_ctrl, + .ctrlbit = (1 << 17), + }, { .name = "keypad", .enable = exynos4_clk_ip_perir_ctrl, .ctrlbit = (1 << 16), diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index 746d6fc6d39..c1cb39df589 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c @@ -11,6 +11,7 @@ #include <linux/sched.h> #include <linux/sysdev.h> +#include <asm/cacheflush.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> @@ -31,6 +32,7 @@ #include <mach/regs-irq.h> #include <mach/regs-pmu.h> +#include <mach/pmu.h> extern int combiner_init(unsigned int combiner_nr, void __iomem *base, unsigned int irq_start); @@ -221,16 +223,34 @@ core_initcall(exynos4_core_init); #ifdef CONFIG_CACHE_L2X0 static int __init exynos4_l2x0_cache_init(void) { - /* TAG, Data Latency Control: 2cycle */ - __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); - __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); + if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) { - /* L2X0 Prefetch Control */ - __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); + l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC; + /* TAG, Data Latency Control: 2 cycles */ + l2x0_saved_regs.tag_latency = 0x110; + l2x0_saved_regs.data_latency = 0x110; + l2x0_saved_regs.prefetch_ctrl = 0x30000007; + l2x0_saved_regs.pwr_ctrl = + (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN); - /* L2X0 Power Control */ - __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, - S5P_VA_L2CC + L2X0_POWER_CTRL); + l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs); + + __raw_writel(l2x0_saved_regs.tag_latency, + S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); + __raw_writel(l2x0_saved_regs.data_latency, + S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); + + /* L2X0 Prefetch Control */ + __raw_writel(l2x0_saved_regs.prefetch_ctrl, + S5P_VA_L2CC + L2X0_PREFETCH_CTRL); + + /* L2X0 Power Control */ + __raw_writel(l2x0_saved_regs.pwr_ctrl, + S5P_VA_L2CC + L2X0_POWER_CTRL); + + clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long)); + clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs)); + } l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); @@ -240,6 +260,15 @@ static int __init exynos4_l2x0_cache_init(void) early_initcall(exynos4_l2x0_cache_init); #endif +int exynos4_subrev(void) +{ + static int subrev = -1; + if (unlikely(subrev < 0)) + subrev = readl(S5P_VA_CHIPID) & 0xf; + + return subrev; +} + int __init exynos4_init(void) { printk(KERN_INFO "EXYNOS4: Initializing architecture\n"); diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c index bf7e96f2793..6d527610c5a 100644 --- a/arch/arm/mach-exynos4/cpuidle.c +++ b/arch/arm/mach-exynos4/cpuidle.c @@ -11,22 +11,48 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/cpuidle.h> +#include <linux/cpu_pm.h> #include <linux/io.h> - +#include <linux/suspend.h> +#include <linux/err.h> #include <asm/proc-fns.h> +#include <asm/smp_scu.h> +#include <asm/suspend.h> +#include <asm/unified.h> +#include <mach/regs-pmu.h> +#include <mach/pmu.h> + +#include <plat/exynos4.h> +#include <plat/cpu.h> + +#define REG_DIRECTGO_ADDR (exynos4_subrev() == 0 ?\ + (S5P_VA_SYSRAM + 0x24) : S5P_INFORM7) +#define REG_DIRECTGO_FLAG (exynos4_subrev() == 0 ?\ + (S5P_VA_SYSRAM + 0x20) : S5P_INFORM6) static int exynos4_enter_idle(struct cpuidle_device *dev, struct cpuidle_state *state); +static int exynos4_enter_lowpower(struct cpuidle_device *dev, + struct cpuidle_state *state); + static struct cpuidle_state exynos4_cpuidle_set[] = { [0] = { .enter = exynos4_enter_idle, .exit_latency = 1, .target_residency = 100000, .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "IDLE", + .name = "C0", .desc = "ARM clock gating(WFI)", }, + [1] = { + .enter = exynos4_enter_lowpower, + .exit_latency = 300, + .target_residency = 100000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C1", + .desc = "ARM power down", + }, }; static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device); @@ -36,6 +62,96 @@ static struct cpuidle_driver exynos4_idle_driver = { .owner = THIS_MODULE, }; +/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */ +static void exynos4_set_wakeupmask(void) +{ + __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK); +} + +static unsigned int g_pwr_ctrl, g_diag_reg; + +static void save_cpu_arch_register(void) +{ + /*read power control register*/ + asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc"); + /*read diagnostic register*/ + asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc"); + return; +} + +static void restore_cpu_arch_register(void) +{ + /*write power control register*/ + asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc"); + /*write diagnostic register*/ + asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc"); + return; +} + +static int idle_finisher(unsigned long flags) +{ + cpu_do_idle(); + return 1; +} + +static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, + struct cpuidle_state *state) +{ + struct timeval before, after; + int idle_time; + unsigned long tmp; + + local_irq_disable(); + do_gettimeofday(&before); + + exynos4_set_wakeupmask(); + + /* Set value of power down register for aftr mode */ + exynos4_sys_powerdown_conf(SYS_AFTR); + + save_cpu_arch_register(); + + /* Setting Central Sequence Register for power down mode */ + tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + tmp &= ~S5P_CENTRAL_LOWPWR_CFG; + __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + + cpu_pm_enter(); + cpu_cluster_pm_enter(); + + cpu_suspend(0, idle_finisher); + + scu_enable(S5P_VA_SCU); + + cpu_cluster_pm_exit(); + cpu_pm_exit(); + + restore_cpu_arch_register(); + + /* + * If PMU failed while entering sleep mode, WFI will be + * ignored by PMU and then exiting cpu_do_idle(). + * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically + * in this situation. + */ + tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) { + tmp |= S5P_CENTRAL_LOWPWR_CFG; + __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + } + + /* Clear wakeup state register */ + __raw_writel(0x0, S5P_WAKEUP_STAT); + + do_gettimeofday(&after); + + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); + + return idle_time; +} + static int exynos4_enter_idle(struct cpuidle_device *dev, struct cpuidle_state *state) { @@ -55,6 +171,26 @@ static int exynos4_enter_idle(struct cpuidle_device *dev, return idle_time; } +static int exynos4_enter_lowpower(struct cpuidle_device *dev, + struct cpuidle_state *state) +{ + struct cpuidle_state *new_state = state; + + /* This mode only can be entered when Core1 is offline */ + if (num_online_cpus() > 1) { + BUG_ON(!dev->safe_state); + new_state = dev->safe_state; + } + dev->last_state = new_state; + + if (new_state == &dev->states[0]) + return exynos4_enter_idle(dev, new_state); + else + return exynos4_enter_core0_aftr(dev, new_state); + + return exynos4_enter_idle(dev, new_state); +} + static int __init exynos4_init_cpuidle(void) { int i, max_cpuidle_state, cpu_id; @@ -66,8 +202,11 @@ static int __init exynos4_init_cpuidle(void) device = &per_cpu(exynos4_cpuidle_device, cpu_id); device->cpu = cpu_id; - device->state_count = (sizeof(exynos4_cpuidle_set) / + if (cpu_id == 0) + device->state_count = (sizeof(exynos4_cpuidle_set) / sizeof(struct cpuidle_state)); + else + device->state_count = 1; /* Support IDLE only */ max_cpuidle_state = device->state_count; @@ -76,11 +215,18 @@ static int __init exynos4_init_cpuidle(void) sizeof(struct cpuidle_state)); } + device->safe_state = &device->states[0]; + if (cpuidle_register_device(device)) { printk(KERN_ERR "CPUidle register device failed\n,"); return -EIO; } } + + __raw_writel(BSYM(virt_to_phys(s3c_cpu_resume)), + REG_DIRECTGO_ADDR); + __raw_writel(0xfcba0d10, REG_DIRECTGO_FLAG); + return 0; } device_initcall(exynos4_init_cpuidle); diff --git a/arch/arm/mach-exynos4/dev-tmu.c b/arch/arm/mach-exynos4/dev-tmu.c new file mode 100644 index 00000000000..c1e9e9648b6 --- /dev/null +++ b/arch/arm/mach-exynos4/dev-tmu.c @@ -0,0 +1,68 @@ +/* linux/arch/arm/mach-exynos4/dev-tmu.c + * + * Copyright 2011 by SAMSUNG + * + * 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/string.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/platform_data/exynos4_tmu.h> +#include <asm/irq.h> + +#include <mach/irqs.h> +#include <mach/map.h> +#include <plat/devs.h> + +static struct resource exynos4_tmu_resource[] = { + [0] = { + .start = EXYNOS4_PA_TMU, + .end = EXYNOS4_PA_TMU + 0xFFFF - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TMU_TRIG0, + .end = IRQ_TMU_TRIG0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct exynos4_tmu_platform_data default_tmu_data = { + .threshold = 55, + .trigger_levels[0] = 0xFF, + .trigger_levels[1] = 5, + .trigger_levels[2] = 20, + .trigger_levels[3] = 30, + .trigger_level0_en = 0, + .trigger_level1_en = 1, + .trigger_level2_en = 1, + .trigger_level3_en = 1, + .gain = 15, + .reference_voltage = 7, + .cal_type = TYPE_ONE_POINT_TRIMMING, + .freq_tab[0] = { + .freq_clip_pctg[0] = 50, + }, + .freq_tab[1] = { + .freq_clip_pctg[0] = 99, + }, + .freq_tab[2] = { + .freq_clip_pctg[0] = 99, + }, + .level_count = 3, +}; + +struct platform_device exynos4_device_tmu = { + .name = "exynos4-tmu", + .id = -1, + .num_resources = ARRAY_SIZE(exynos4_tmu_resource), + .resource = exynos4_tmu_resource, + .dev = { + .platform_data = &default_tmu_data, + }, +}; +EXPORT_SYMBOL(exynos4_device_tmu); diff --git a/arch/arm/mach-exynos4/include/mach/cpufreq.h b/arch/arm/mach-exynos4/include/mach/cpufreq.h new file mode 100644 index 00000000000..7e0093111da --- /dev/null +++ b/arch/arm/mach-exynos4/include/mach/cpufreq.h @@ -0,0 +1,39 @@ +/* linux/arch/arm/mach-exynos4/include/mach/cpufreq.h + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * EXYNOS4 - CPUFreq 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. + */ + +/* + * CPU frequency level index for using cpufreq lock API + * This should be same with cpufreq_frequency_table + */ +enum cpufreq_level_request { + CPU_L0, /* 1200MHz */ + CPU_L1, /* 1000MHz */ + CPU_L2, /* 800MHz */ + CPU_L3, /* 500MHz */ + CPU_L4, /* 200MHz */ + CPU_LEVEL_END, +}; + +enum cpufreq_lock_ID { + DVFS_LOCK_ID_G2D, /* G2D */ + DVFS_LOCK_ID_TV, /* TV */ + DVFS_LOCK_ID_MFC, /* MFC */ + DVFS_LOCK_ID_USB, /* USB */ + DVFS_LOCK_ID_CAM, /* CAM */ + DVFS_LOCK_ID_PM, /* PM */ + DVFS_LOCK_ID_USER, /* USER */ + DVFS_LOCK_ID_END, +}; + +int exynos4_cpufreq_lock(unsigned int nId, + enum cpufreq_level_request cpufreq_level); +void exynos4_cpufreq_lock_free(unsigned int nId); diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h index f8952f8f375..94e87a9172c 100644 --- a/arch/arm/mach-exynos4/include/mach/irqs.h +++ b/arch/arm/mach-exynos4/include/mach/irqs.h @@ -119,6 +119,8 @@ #define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128)) #define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y) +#define IRQ_TMU_TRIG0 COMBINER_IRQ(2, 4) +#define IRQ_TMU_TRIG1 COMBINER_IRQ(3, 4) #define IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0) #define IRQ_SYSMMU_SSS_0 COMBINER_IRQ(4, 1) #define IRQ_SYSMMU_FIMC0_0 COMBINER_IRQ(4, 2) diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h index d32296dc65e..233525bfa43 100644 --- a/arch/arm/mach-exynos4/include/mach/map.h +++ b/arch/arm/mach-exynos4/include/mach/map.h @@ -66,6 +66,7 @@ #define EXYNOS4_PA_COREPERI 0x10500000 #define EXYNOS4_PA_TWD 0x10500600 #define EXYNOS4_PA_L2CC 0x10502000 +#define EXYNOS4_PA_TMU 0x100C0000 #define EXYNOS4_PA_MDMA 0x10810000 #define EXYNOS4_PA_PDMA0 0x12680000 diff --git a/arch/arm/mach-exynos4/include/mach/pmu.h b/arch/arm/mach-exynos4/include/mach/pmu.h index a952904b010..31d1ed8e3c6 100644 --- a/arch/arm/mach-exynos4/include/mach/pmu.h +++ b/arch/arm/mach-exynos4/include/mach/pmu.h @@ -20,6 +20,8 @@ enum sys_powerdown { NUM_SYS_POWERDOWN, }; +extern unsigned long l2x0_regs_phys; extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); +extern void s3c_cpu_resume(void); #endif /* __ASM_ARCH_PMU_H */ diff --git a/arch/arm/mach-exynos4/mach-armlex4210.c b/arch/arm/mach-exynos4/mach-armlex4210.c index b482c6285fc..f0ca6c157d2 100644 --- a/arch/arm/mach-exynos4/mach-armlex4210.c +++ b/arch/arm/mach-exynos4/mach-armlex4210.c @@ -207,7 +207,7 @@ static void __init armlex4210_machine_init(void) MACHINE_START(ARMLEX4210, "ARMLEX4210") /* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */ - .boot_params = S5P_PA_SDRAM + 0x100, + .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = armlex4210_map_io, .init_machine = armlex4210_machine_init, diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c index 43be71b799c..6e0536818bf 100644 --- a/arch/arm/mach-exynos4/mach-nuri.c +++ b/arch/arm/mach-exynos4/mach-nuri.c @@ -1152,7 +1152,7 @@ static void __init nuri_machine_init(void) MACHINE_START(NURI, "NURI") /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ - .boot_params = S5P_PA_SDRAM + 0x100, + .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = nuri_map_io, .init_machine = nuri_machine_init, diff --git a/arch/arm/mach-exynos4/mach-origen.c b/arch/arm/mach-exynos4/mach-origen.c new file mode 100644 index 00000000000..74180441852 --- /dev/null +++ b/arch/arm/mach-exynos4/mach-origen.c @@ -0,0 +1,109 @@ +/* linux/arch/arm/mach-exynos4/mach-origen.c + * + * Copyright (c) 2011 Insignal Co., Ltd. + * http://www.insignal.co.kr/ + * + * 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/serial_core.h> +#include <linux/gpio.h> +#include <linux/mmc/host.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/input.h> + +#include <asm/mach/arch.h> +#include <asm/mach-types.h> + +#include <plat/regs-serial.h> +#include <plat/exynos4.h> +#include <plat/cpu.h> +#include <plat/devs.h> +#include <plat/sdhci.h> +#include <plat/iic.h> + +#include <mach/map.h> + +/* Following are default values for UCON, ULCON and UFCON UART registers */ +#define ORIGEN_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ + S3C2410_UCON_RXILEVEL | \ + S3C2410_UCON_TXIRQMODE | \ + S3C2410_UCON_RXIRQMODE | \ + S3C2410_UCON_RXFIFO_TOI | \ + S3C2443_UCON_RXERR_IRQEN) + +#define ORIGEN_ULCON_DEFAULT S3C2410_LCON_CS8 + +#define ORIGEN_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ + S5PV210_UFCON_TXTRIG4 | \ + S5PV210_UFCON_RXTRIG4) + +static struct s3c2410_uartcfg origen_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = ORIGEN_UCON_DEFAULT, + .ulcon = ORIGEN_ULCON_DEFAULT, + .ufcon = ORIGEN_UFCON_DEFAULT, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = ORIGEN_UCON_DEFAULT, + .ulcon = ORIGEN_ULCON_DEFAULT, + .ufcon = ORIGEN_UFCON_DEFAULT, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = ORIGEN_UCON_DEFAULT, + .ulcon = ORIGEN_ULCON_DEFAULT, + .ufcon = ORIGEN_UFCON_DEFAULT, + }, + [3] = { + .hwport = 3, + .flags = 0, + .ucon = ORIGEN_UCON_DEFAULT, + .ulcon = ORIGEN_ULCON_DEFAULT, + .ufcon = ORIGEN_UFCON_DEFAULT, + }, +}; + +static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = { + .cd_type = S3C_SDHCI_CD_GPIO, + .ext_cd_gpio = EXYNOS4_GPK2(2), + .ext_cd_gpio_invert = 1, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +}; + +static struct platform_device *origen_devices[] __initdata = { + &s3c_device_hsmmc2, + &s3c_device_rtc, + &s3c_device_wdt, + &exynos4_device_tmu, +}; + +static void __init origen_map_io(void) +{ + s5p_init_io(NULL, 0, S5P_VA_CHIPID); + s3c24xx_init_clocks(24000000); + s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs)); +} + +static void __init origen_machine_init(void) +{ + s3c_sdhci2_set_platdata(&origen_hsmmc2_pdata); + platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices)); +} + +MACHINE_START(ORIGEN, "ORIGEN") + /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */ + .atag_offset = 0x100, + .init_irq = exynos4_init_irq, + .map_io = origen_map_io, + .init_machine = origen_machine_init, + .timer = &exynos4_timer, +MACHINE_END diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c index a7c65e05c1e..b24ddd7ad8f 100644 --- a/arch/arm/mach-exynos4/mach-smdkc210.c +++ b/arch/arm/mach-exynos4/mach-smdkc210.c @@ -301,7 +301,7 @@ static void __init smdkc210_machine_init(void) 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 = smdkc210_map_io, .init_machine = smdkc210_machine_init, diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c index ea414955686..1d7bf2138dd 100644 --- a/arch/arm/mach-exynos4/mach-smdkv310.c +++ b/arch/arm/mach-exynos4/mach-smdkv310.c @@ -252,12 +252,18 @@ static void __init smdkv310_machine_init(void) platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices)); } +static char const *smdkv310_dt_compat[] __initdata = { + "samsung,smdkv310", + NULL +}; + 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, .timer = &exynos4_timer, + .dt_compat = smdkv310_dt_compat, MACHINE_END diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos4/mach-universal_c210.c index b3b5d891100..2aac6f755c8 100644 --- a/arch/arm/mach-exynos4/mach-universal_c210.c +++ b/arch/arm/mach-exynos4/mach-universal_c210.c @@ -762,7 +762,7 @@ static void __init universal_machine_init(void) MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ - .boot_params = S5P_PA_SDRAM + 0x100, + .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = universal_map_io, .init_machine = universal_machine_init, diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c index df6ef1b2f98..c345b783cde 100644 --- a/arch/arm/mach-exynos4/platsmp.c +++ b/arch/arm/mach-exynos4/platsmp.c @@ -30,9 +30,11 @@ #include <mach/regs-clock.h> #include <mach/regs-pmu.h> +#include <plat/exynos4.h> + extern void exynos4_secondary_startup(void); -#define CPU1_BOOT_REG S5P_VA_SYSRAM +#define CPU1_BOOT_REG (exynos4_subrev() == 0 ? S5P_VA_SYSRAM : S5P_INFORM5) /* * control for which core is the next to come out of the secondary @@ -193,12 +195,10 @@ void __init smp_init_cpus(void) ncores = scu_base ? scu_get_core_count(scu_base) : 1; /* sanity check */ - if (ncores > NR_CPUS) { - printk(KERN_WARNING - "EXYNOS4: no. of cores (%d) greater than configured " - "maximum of %d - clipping\n", - ncores, NR_CPUS); - ncores = NR_CPUS; + if (ncores > nr_cpu_ids) { + pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", + ncores, nr_cpu_ids); + ncores = nr_cpu_ids; } for (i = 0; i < ncores; i++) @@ -218,5 +218,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) * until it receives a soft interrupt, and then the * secondary CPU branches to this address. */ - __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)), S5P_VA_SYSRAM); + __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)), + CPU1_BOOT_REG); } diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos4/pm.c index bc6ca9482de..47d5428887d 100644 --- a/arch/arm/mach-exynos4/pm.c +++ b/arch/arm/mach-exynos4/pm.c @@ -131,78 +131,6 @@ static struct sleep_save exynos4_core_save[] = { SAVE_ITEM(S5P_CLKGATE_SCLKCPU), SAVE_ITEM(S5P_CLKGATE_IP_CPU), - /* GIC side */ - SAVE_ITEM(S5P_VA_GIC_CPU + 0x000), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x004), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x008), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x014), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x018), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x000), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x004), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x100), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x104), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x108), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x300), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x304), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x308), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x400), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x404), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x408), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x410), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x414), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x418), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x420), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x424), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x428), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x430), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x434), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x438), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x440), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x444), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x448), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x450), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x454), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x458), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C), - - SAVE_ITEM(S5P_VA_GIC_DIST + 0x800), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x804), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x808), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x810), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x814), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x818), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x820), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x824), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x828), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x830), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x834), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x838), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x840), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x844), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x848), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x850), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x854), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x858), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C), - - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000), SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010), SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020), @@ -222,13 +150,6 @@ static struct sleep_save exynos4_core_save[] = { SAVE_ITEM(S5P_SROM_BC3), }; -static struct sleep_save exynos4_l2cc_save[] = { - SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL), - SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL), - SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL), - SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL), - SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL), -}; /* For Cortex-A9 Diagnostic and Power control register */ static unsigned int save_arm_register[2]; @@ -249,7 +170,6 @@ static void exynos4_pm_prepare(void) u32 tmp; s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); - s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save)); s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); @@ -462,13 +382,6 @@ static void exynos4_pm_resume(void) exynos4_scu_enable(S5P_VA_SCU); -#ifdef CONFIG_CACHE_L2X0 - s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save)); - outer_inv_all(); - /* enable L2X0*/ - writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL); -#endif - early_wakeup: return; } diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/mach-exynos4/sleep.S index 0984078f1eb..3284213a1a3 100644 --- a/arch/arm/mach-exynos4/sleep.S +++ b/arch/arm/mach-exynos4/sleep.S @@ -27,8 +27,8 @@ */ #include <linux/linkage.h> -#include <asm/assembler.h> -#include <asm/memory.h> +#include <asm/asm-offsets.h> +#include <asm/hardware/cache-l2x0.h> .text @@ -49,6 +49,31 @@ * other way of restoring the stack pointer after sleep, and we * must not write to the code segment (code is read-only) */ + .align + .data ENTRY(s3c_cpu_resume) + adr r0, l2x0_regs_phys + ldr r0, [r0] + ldr r1, [r0, #L2X0_R_PHY_BASE] + ldr r2, [r1, #L2X0_CTRL] + tst r2, #0x1 + bne resume_l2on + ldr r2, [r0, #L2X0_R_AUX_CTRL] + str r2, [r1, #L2X0_AUX_CTRL] + ldr r2, [r0, #L2X0_R_TAG_LATENCY] + str r2, [r1, #L2X0_TAG_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_DATA_LATENCY] + str r2, [r1, #L2X0_DATA_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_PREFETCH_CTRL] + str r2, [r1, #L2X0_PREFETCH_CTRL] + ldr r2, [r0, #L2X0_R_PWR_CTRL] + str r2, [r1, #L2X0_POWER_CTRL] + mov r2, #1 + str r2, [r1, #L2X0_CTRL] +resume_l2on: b cpu_resume +ENDPROC(s3c_cpu_resume) + .globl l2x0_regs_phys +l2x0_regs_phys: + .long 0 |