aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-03-15 17:22:00 -0400
committerArnd Bergmann <arnd@arndb.de>2012-03-15 17:22:00 -0400
commit853a0231e057c04255a848f6998f84faaa635c58 (patch)
treef9aef1ce29410437f39746515bc7fbab9ef90a52 /arch/arm/mach-exynos
parente7051e9dab77ddeaddbe12364939ae239d92ca73 (diff)
parent4d2e4d7f2c2b1a4382286821a59fa2f4012cb748 (diff)
Merge branch 'samsung/soc' into next/soc2
* samsung/soc: ARM: EXYNOS: fix cycle count for periodic mode of clock event timers ARM: EXYNOS: add support JPEG ARM: EXYNOS: Add DMC1, allow PPMU access for DMC ARM: SAMSUNG: Correct MIPI-CSIS io memory resource definition ARM: SAMSUNG: fix __init attribute on regarding s3c_set_platdata() ARM: SAMSUNG: Add __init attribute to samsung_bl_set() ARM: S5PV210: Add usb otg phy control ARM: S3C64XX: Add usb otg phy control ARM: EXYNOS: Enable l2 configuration through device tree ARM: EXYNOS: remove useless code to save/restore L2 ARM: EXYNOS: save L2 settings during bootup ARM: S5P: add L2 early resume code ARM: EXYNOS: Add support AFTR mode on EXYNOS4210 ARM: SAMSUNG: use spin_lock_irqsave() in clk_{enable,disable} ARM: S3C64XX: Define some additional always off clocks ARM: S3C64XX: Reduce residency requirement for cpuidle WFI mode ARM: SAMSUNG: Add a callback 'notify_after' for PWM backlight control ARM: SAMSUNG: add G2D to plat-s5p and mach-exynos ARM: S3C64XX: Gate some more clocks by default ARM: S3C64XX: Add basic cpuidle driver Conflicts: arch/arm/mach-exynos/clock.c arch/arm/mach-exynos/common.c This merges the earlier samsung support into the next/soc2 branch to resolve conflicts between commits in the earlier work and the exynos5 branch. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-exynos')
-rw-r--r--arch/arm/mach-exynos/clock-exynos4.c5
-rw-r--r--arch/arm/mach-exynos/common.c60
-rw-r--r--arch/arm/mach-exynos/cpuidle.c151
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h7
-rw-r--r--arch/arm/mach-exynos/include/mach/pmu.h2
-rw-r--r--arch/arm/mach-exynos/mct.c21
-rw-r--r--arch/arm/mach-exynos/pm.c15
7 files changed, 221 insertions, 40 deletions
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
index 6504d8b1f8e..df54c2a9222 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -471,6 +471,11 @@ static struct clk exynos4_init_clocks_off[] = {
471 .enable = exynos4_clk_ip_cam_ctrl, 471 .enable = exynos4_clk_ip_cam_ctrl,
472 .ctrlbit = (1 << 5), 472 .ctrlbit = (1 << 5),
473 }, { 473 }, {
474 .name = "jpeg",
475 .id = 0,
476 .enable = exynos4_clk_ip_cam_ctrl,
477 .ctrlbit = (1 << 6),
478 }, {
474 .name = "fimc", 479 .name = "fimc",
475 .devname = "exynos4-fimc.0", 480 .devname = "exynos4-fimc.0",
476 .enable = exynos4_clk_ip_cam_ctrl, 481 .enable = exynos4_clk_ip_cam_ctrl,
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index cbbaca54966..66742e91464 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -26,10 +26,12 @@
26#include <asm/hardware/gic.h> 26#include <asm/hardware/gic.h>
27#include <asm/mach/map.h> 27#include <asm/mach/map.h>
28#include <asm/mach/irq.h> 28#include <asm/mach/irq.h>
29#include <asm/cacheflush.h>
29 30
30#include <mach/regs-irq.h> 31#include <mach/regs-irq.h>
31#include <mach/regs-pmu.h> 32#include <mach/regs-pmu.h>
32#include <mach/regs-gpio.h> 33#include <mach/regs-gpio.h>
34#include <mach/pmu.h>
33 35
34#include <plat/cpu.h> 36#include <plat/cpu.h>
35#include <plat/clock.h> 37#include <plat/clock.h>
@@ -45,6 +47,8 @@
45#include <plat/regs-serial.h> 47#include <plat/regs-serial.h>
46 48
47#include "common.h" 49#include "common.h"
50#define L2_AUX_VAL 0x7C470001
51#define L2_AUX_MASK 0xC200ffff
48 52
49static const char name_exynos4210[] = "EXYNOS4210"; 53static const char name_exynos4210[] = "EXYNOS4210";
50static const char name_exynos4212[] = "EXYNOS4212"; 54static const char name_exynos4212[] = "EXYNOS4212";
@@ -189,7 +193,12 @@ static struct map_desc exynos4_iodesc[] __initdata = {
189 }, { 193 }, {
190 .virtual = (unsigned long)S5P_VA_DMC0, 194 .virtual = (unsigned long)S5P_VA_DMC0,
191 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), 195 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
192 .length = SZ_4K, 196 .length = SZ_64K,
197 .type = MT_DEVICE,
198 }, {
199 .virtual = (unsigned long)S5P_VA_DMC1,
200 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
201 .length = SZ_64K,
193 .type = MT_DEVICE, 202 .type = MT_DEVICE,
194 }, { 203 }, {
195 .virtual = (unsigned long)S3C_VA_USB_HSPHY, 204 .virtual = (unsigned long)S3C_VA_USB_HSPHY,
@@ -592,23 +601,48 @@ static int __init exynos4_l2x0_cache_init(void)
592 if (soc_is_exynos5250()) 601 if (soc_is_exynos5250())
593 return 0; 602 return 0;
594 603
595 /* TAG, Data Latency Control: 2cycle */ 604 int ret;
596 __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); 605 ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
606 if (!ret) {
607 l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
608 clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
609 return 0;
610 }
611
612 if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) {
613 l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC;
614 /* TAG, Data Latency Control: 2 cycles */
615 l2x0_saved_regs.tag_latency = 0x110;
597 616
598 if (soc_is_exynos4210()) 617 if (soc_is_exynos4212() || soc_is_exynos4412())
599 __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); 618 l2x0_saved_regs.data_latency = 0x120;
600 else if (soc_is_exynos4212() || soc_is_exynos4412()) 619 else
601 __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); 620 l2x0_saved_regs.data_latency = 0x110;
621
622 l2x0_saved_regs.prefetch_ctrl = 0x30000007;
623 l2x0_saved_regs.pwr_ctrl =
624 (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN);
602 625
603 /* L2X0 Prefetch Control */ 626 l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
604 __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
605 627
606 /* L2X0 Power Control */ 628 __raw_writel(l2x0_saved_regs.tag_latency,
607 __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, 629 S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
608 S5P_VA_L2CC + L2X0_POWER_CTRL); 630 __raw_writel(l2x0_saved_regs.data_latency,
631 S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
609 632
610 l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); 633 /* L2X0 Prefetch Control */
634 __raw_writel(l2x0_saved_regs.prefetch_ctrl,
635 S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
636
637 /* L2X0 Power Control */
638 __raw_writel(l2x0_saved_regs.pwr_ctrl,
639 S5P_VA_L2CC + L2X0_POWER_CTRL);
640
641 clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
642 clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs));
643 }
611 644
645 l2x0_init(S5P_VA_L2CC, L2_AUX_VAL, L2_AUX_MASK);
612 return 0; 646 return 0;
613} 647}
614early_initcall(exynos4_l2x0_cache_init); 648early_initcall(exynos4_l2x0_cache_init);
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c
index 4ebb382c597..33ab4e7558a 100644
--- a/arch/arm/mach-exynos/cpuidle.c
+++ b/arch/arm/mach-exynos/cpuidle.c
@@ -11,25 +11,53 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/cpuidle.h> 13#include <linux/cpuidle.h>
14#include <linux/cpu_pm.h>
14#include <linux/io.h> 15#include <linux/io.h>
15#include <linux/export.h> 16#include <linux/export.h>
16#include <linux/time.h> 17#include <linux/time.h>
17 18
18#include <asm/proc-fns.h> 19#include <asm/proc-fns.h>
20#include <asm/smp_scu.h>
21#include <asm/suspend.h>
22#include <asm/unified.h>
23#include <mach/regs-pmu.h>
24#include <mach/pmu.h>
25
26#include <plat/cpu.h>
27
28#define REG_DIRECTGO_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \
29 S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
30 (S5P_VA_SYSRAM + 0x24) : S5P_INFORM0))
31#define REG_DIRECTGO_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \
32 S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
33 (S5P_VA_SYSRAM + 0x20) : S5P_INFORM1))
34
35#define S5P_CHECK_AFTR 0xFCBA0D10
19 36
20static int exynos4_enter_idle(struct cpuidle_device *dev, 37static int exynos4_enter_idle(struct cpuidle_device *dev,
21 struct cpuidle_driver *drv, 38 struct cpuidle_driver *drv,
22 int index); 39 int index);
40static int exynos4_enter_lowpower(struct cpuidle_device *dev,
41 struct cpuidle_driver *drv,
42 int index);
23 43
24static struct cpuidle_state exynos4_cpuidle_set[] = { 44static struct cpuidle_state exynos4_cpuidle_set[] __initdata = {
25 [0] = { 45 [0] = {
26 .enter = exynos4_enter_idle, 46 .enter = exynos4_enter_idle,
27 .exit_latency = 1, 47 .exit_latency = 1,
28 .target_residency = 100000, 48 .target_residency = 100000,
29 .flags = CPUIDLE_FLAG_TIME_VALID, 49 .flags = CPUIDLE_FLAG_TIME_VALID,
30 .name = "IDLE", 50 .name = "C0",
31 .desc = "ARM clock gating(WFI)", 51 .desc = "ARM clock gating(WFI)",
32 }, 52 },
53 [1] = {
54 .enter = exynos4_enter_lowpower,
55 .exit_latency = 300,
56 .target_residency = 100000,
57 .flags = CPUIDLE_FLAG_TIME_VALID,
58 .name = "C1",
59 .desc = "ARM power down",
60 },
33}; 61};
34 62
35static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device); 63static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
@@ -39,9 +67,102 @@ static struct cpuidle_driver exynos4_idle_driver = {
39 .owner = THIS_MODULE, 67 .owner = THIS_MODULE,
40}; 68};
41 69
70/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
71static void exynos4_set_wakeupmask(void)
72{
73 __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK);
74}
75
76static unsigned int g_pwr_ctrl, g_diag_reg;
77
78static void save_cpu_arch_register(void)
79{
80 /*read power control register*/
81 asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc");
82 /*read diagnostic register*/
83 asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
84 return;
85}
86
87static void restore_cpu_arch_register(void)
88{
89 /*write power control register*/
90 asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc");
91 /*write diagnostic register*/
92 asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
93 return;
94}
95
96static int idle_finisher(unsigned long flags)
97{
98 cpu_do_idle();
99 return 1;
100}
101
102static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,
103 struct cpuidle_driver *drv,
104 int index)
105{
106 struct timeval before, after;
107 int idle_time;
108 unsigned long tmp;
109
110 local_irq_disable();
111 do_gettimeofday(&before);
112
113 exynos4_set_wakeupmask();
114
115 /* Set value of power down register for aftr mode */
116 exynos4_sys_powerdown_conf(SYS_AFTR);
117
118 __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR);
119 __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG);
120
121 save_cpu_arch_register();
122
123 /* Setting Central Sequence Register for power down mode */
124 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
125 tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
126 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
127
128 cpu_pm_enter();
129 cpu_suspend(0, idle_finisher);
130
131#ifdef CONFIG_SMP
132 scu_enable(S5P_VA_SCU);
133#endif
134 cpu_pm_exit();
135
136 restore_cpu_arch_register();
137
138 /*
139 * If PMU failed while entering sleep mode, WFI will be
140 * ignored by PMU and then exiting cpu_do_idle().
141 * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
142 * in this situation.
143 */
144 tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
145 if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
146 tmp |= S5P_CENTRAL_LOWPWR_CFG;
147 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
148 }
149
150 /* Clear wakeup state register */
151 __raw_writel(0x0, S5P_WAKEUP_STAT);
152
153 do_gettimeofday(&after);
154
155 local_irq_enable();
156 idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
157 (after.tv_usec - before.tv_usec);
158
159 dev->last_residency = idle_time;
160 return index;
161}
162
42static int exynos4_enter_idle(struct cpuidle_device *dev, 163static int exynos4_enter_idle(struct cpuidle_device *dev,
43 struct cpuidle_driver *drv, 164 struct cpuidle_driver *drv,
44 int index) 165 int index)
45{ 166{
46 struct timeval before, after; 167 struct timeval before, after;
47 int idle_time; 168 int idle_time;
@@ -60,6 +181,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev,
60 return index; 181 return index;
61} 182}
62 183
184static int exynos4_enter_lowpower(struct cpuidle_device *dev,
185 struct cpuidle_driver *drv,
186 int index)
187{
188 int new_index = index;
189
190 /* This mode only can be entered when other core's are offline */
191 if (num_online_cpus() > 1)
192 new_index = drv->safe_state_index;
193
194 if (new_index == 0)
195 return exynos4_enter_idle(dev, drv, new_index);
196 else
197 return exynos4_enter_core0_aftr(dev, drv, new_index);
198}
199
63static int __init exynos4_init_cpuidle(void) 200static int __init exynos4_init_cpuidle(void)
64{ 201{
65 int i, max_cpuidle_state, cpu_id; 202 int i, max_cpuidle_state, cpu_id;
@@ -74,19 +211,25 @@ static int __init exynos4_init_cpuidle(void)
74 memcpy(&drv->states[i], &exynos4_cpuidle_set[i], 211 memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
75 sizeof(struct cpuidle_state)); 212 sizeof(struct cpuidle_state));
76 } 213 }
214 drv->safe_state_index = 0;
77 cpuidle_register_driver(&exynos4_idle_driver); 215 cpuidle_register_driver(&exynos4_idle_driver);
78 216
79 for_each_cpu(cpu_id, cpu_online_mask) { 217 for_each_cpu(cpu_id, cpu_online_mask) {
80 device = &per_cpu(exynos4_cpuidle_device, cpu_id); 218 device = &per_cpu(exynos4_cpuidle_device, cpu_id);
81 device->cpu = cpu_id; 219 device->cpu = cpu_id;
82 220
83 device->state_count = drv->state_count; 221 if (cpu_id == 0)
222 device->state_count = (sizeof(exynos4_cpuidle_set) /
223 sizeof(struct cpuidle_state));
224 else
225 device->state_count = 1; /* Support IDLE only */
84 226
85 if (cpuidle_register_device(device)) { 227 if (cpuidle_register_device(device)) {
86 printk(KERN_ERR "CPUidle register device failed\n,"); 228 printk(KERN_ERR "CPUidle register device failed\n,");
87 return -EIO; 229 return -EIO;
88 } 230 }
89 } 231 }
232
90 return 0; 233 return 0;
91} 234}
92device_initcall(exynos4_init_cpuidle); 235device_initcall(exynos4_init_cpuidle);
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index bf90bb0ab2b..188d87d6ec4 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -32,6 +32,10 @@
32#define EXYNOS4_PA_FIMC2 0x11820000 32#define EXYNOS4_PA_FIMC2 0x11820000
33#define EXYNOS4_PA_FIMC3 0x11830000 33#define EXYNOS4_PA_FIMC3 0x11830000
34 34
35#define EXYNOS4_PA_JPEG 0x11840000
36
37#define EXYNOS4_PA_G2D 0x12800000
38
35#define EXYNOS4_PA_I2S0 0x03830000 39#define EXYNOS4_PA_I2S0 0x03830000
36#define EXYNOS4_PA_I2S1 0xE3100000 40#define EXYNOS4_PA_I2S1 0xE3100000
37#define EXYNOS4_PA_I2S2 0xE2A00000 41#define EXYNOS4_PA_I2S2 0xE2A00000
@@ -67,6 +71,7 @@
67#define EXYNOS4_PA_KEYPAD 0x100A0000 71#define EXYNOS4_PA_KEYPAD 0x100A0000
68 72
69#define EXYNOS4_PA_DMC0 0x10400000 73#define EXYNOS4_PA_DMC0 0x10400000
74#define EXYNOS4_PA_DMC1 0x10410000
70 75
71#define EXYNOS4_PA_COMBINER 0x10440000 76#define EXYNOS4_PA_COMBINER 0x10440000
72#define EXYNOS5_PA_COMBINER 0x10440000 77#define EXYNOS5_PA_COMBINER 0x10440000
@@ -179,6 +184,8 @@
179#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1 184#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1
180#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2 185#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2
181#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3 186#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3
187#define S5P_PA_JPEG EXYNOS4_PA_JPEG
188#define S5P_PA_G2D EXYNOS4_PA_G2D
182#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0 189#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0
183#define S5P_PA_HDMI EXYNOS4_PA_HDMI 190#define S5P_PA_HDMI EXYNOS4_PA_HDMI
184#define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY 191#define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY
diff --git a/arch/arm/mach-exynos/include/mach/pmu.h b/arch/arm/mach-exynos/include/mach/pmu.h
index 632dd563013..e76b7faba66 100644
--- a/arch/arm/mach-exynos/include/mach/pmu.h
+++ b/arch/arm/mach-exynos/include/mach/pmu.h
@@ -22,11 +22,13 @@ enum sys_powerdown {
22 NUM_SYS_POWERDOWN, 22 NUM_SYS_POWERDOWN,
23}; 23};
24 24
25extern unsigned long l2x0_regs_phys;
25struct exynos4_pmu_conf { 26struct exynos4_pmu_conf {
26 void __iomem *reg; 27 void __iomem *reg;
27 unsigned int val[NUM_SYS_POWERDOWN]; 28 unsigned int val[NUM_SYS_POWERDOWN];
28}; 29};
29 30
30extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); 31extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode);
32extern void s3c_cpu_resume(void);
31 33
32#endif /* __ASM_ARCH_PMU_H */ 34#endif /* __ASM_ARCH_PMU_H */
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index 1016515dc9a..cae3e2dae2e 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -29,12 +29,13 @@
29#include <mach/regs-mct.h> 29#include <mach/regs-mct.h>
30#include <asm/mach/time.h> 30#include <asm/mach/time.h>
31 31
32#define TICK_BASE_CNT 1
33
32enum { 34enum {
33 MCT_INT_SPI, 35 MCT_INT_SPI,
34 MCT_INT_PPI 36 MCT_INT_PPI
35}; 37};
36 38
37static unsigned long clk_cnt_per_tick;
38static unsigned long clk_rate; 39static unsigned long clk_rate;
39static unsigned int mct_int_type; 40static unsigned int mct_int_type;
40 41
@@ -205,11 +206,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles,
205static void exynos4_comp_set_mode(enum clock_event_mode mode, 206static void exynos4_comp_set_mode(enum clock_event_mode mode,
206 struct clock_event_device *evt) 207 struct clock_event_device *evt)
207{ 208{
209 unsigned long cycles_per_jiffy;
208 exynos4_mct_comp0_stop(); 210 exynos4_mct_comp0_stop();
209 211
210 switch (mode) { 212 switch (mode) {
211 case CLOCK_EVT_MODE_PERIODIC: 213 case CLOCK_EVT_MODE_PERIODIC:
212 exynos4_mct_comp0_start(mode, clk_cnt_per_tick); 214 cycles_per_jiffy =
215 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
216 exynos4_mct_comp0_start(mode, cycles_per_jiffy);
213 break; 217 break;
214 218
215 case CLOCK_EVT_MODE_ONESHOT: 219 case CLOCK_EVT_MODE_ONESHOT:
@@ -248,9 +252,7 @@ static struct irqaction mct_comp_event_irq = {
248 252
249static void exynos4_clockevent_init(void) 253static void exynos4_clockevent_init(void)
250{ 254{
251 clk_cnt_per_tick = clk_rate / 2 / HZ; 255 clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5);
252
253 clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
254 mct_comp_device.max_delta_ns = 256 mct_comp_device.max_delta_ns =
255 clockevent_delta2ns(0xffffffff, &mct_comp_device); 257 clockevent_delta2ns(0xffffffff, &mct_comp_device);
256 mct_comp_device.min_delta_ns = 258 mct_comp_device.min_delta_ns =
@@ -317,12 +319,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
317 struct clock_event_device *evt) 319 struct clock_event_device *evt)
318{ 320{
319 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); 321 struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
322 unsigned long cycles_per_jiffy;
320 323
321 exynos4_mct_tick_stop(mevt); 324 exynos4_mct_tick_stop(mevt);
322 325
323 switch (mode) { 326 switch (mode) {
324 case CLOCK_EVT_MODE_PERIODIC: 327 case CLOCK_EVT_MODE_PERIODIC:
325 exynos4_mct_tick_start(clk_cnt_per_tick, mevt); 328 cycles_per_jiffy =
329 (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
330 exynos4_mct_tick_start(cycles_per_jiffy, mevt);
326 break; 331 break;
327 332
328 case CLOCK_EVT_MODE_ONESHOT: 333 case CLOCK_EVT_MODE_ONESHOT:
@@ -396,7 +401,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
396 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 401 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
397 evt->rating = 450; 402 evt->rating = 450;
398 403
399 clockevents_calc_mult_shift(evt, clk_rate / 2, 5); 404 clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5);
400 evt->max_delta_ns = 405 evt->max_delta_ns =
401 clockevent_delta2ns(0x7fffffff, evt); 406 clockevent_delta2ns(0x7fffffff, evt);
402 evt->min_delta_ns = 407 evt->min_delta_ns =
@@ -404,7 +409,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
404 409
405 clockevents_register_device(evt); 410 clockevents_register_device(evt);
406 411
407 exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET); 412 exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
408 413
409 if (mct_int_type == MCT_INT_SPI) { 414 if (mct_int_type == MCT_INT_SPI) {
410 if (cpu == 0) { 415 if (cpu == 0) {
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index f105bd2b676..428cfeb5772 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -155,13 +155,6 @@ static struct sleep_save exynos4_core_save[] = {
155 SAVE_ITEM(S5P_SROM_BC3), 155 SAVE_ITEM(S5P_SROM_BC3),
156}; 156};
157 157
158static struct sleep_save exynos4_l2cc_save[] = {
159 SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
160 SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
161 SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
162 SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
163 SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
164};
165 158
166/* For Cortex-A9 Diagnostic and Power control register */ 159/* For Cortex-A9 Diagnostic and Power control register */
167static unsigned int save_arm_register[2]; 160static unsigned int save_arm_register[2];
@@ -182,7 +175,6 @@ static void exynos4_pm_prepare(void)
182 u32 tmp; 175 u32 tmp;
183 176
184 s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); 177 s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
185 s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
186 s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); 178 s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
187 s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); 179 s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
188 180
@@ -388,13 +380,6 @@ static void exynos4_pm_resume(void)
388 scu_enable(S5P_VA_SCU); 380 scu_enable(S5P_VA_SCU);
389#endif 381#endif
390 382
391#ifdef CONFIG_CACHE_L2X0
392 s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
393 outer_inv_all();
394 /* enable L2X0*/
395 writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
396#endif
397
398early_wakeup: 383early_wakeup:
399 return; 384 return;
400} 385}