diff options
27 files changed, 765 insertions, 72 deletions
diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c index 187287aa57ab..ac249e46a21c 100644 --- a/arch/arm/mach-exynos/clock.c +++ b/arch/arm/mach-exynos/clock.c | |||
@@ -472,6 +472,11 @@ static struct clk init_clocks_off[] = { | |||
472 | .enable = exynos4_clk_ip_cam_ctrl, | 472 | .enable = exynos4_clk_ip_cam_ctrl, |
473 | .ctrlbit = (1 << 5), | 473 | .ctrlbit = (1 << 5), |
474 | }, { | 474 | }, { |
475 | .name = "jpeg", | ||
476 | .id = 0, | ||
477 | .enable = exynos4_clk_ip_cam_ctrl, | ||
478 | .ctrlbit = (1 << 6), | ||
479 | }, { | ||
475 | .name = "fimc", | 480 | .name = "fimc", |
476 | .devname = "exynos4-fimc.0", | 481 | .devname = "exynos4-fimc.0", |
477 | .enable = exynos4_clk_ip_cam_ctrl, | 482 | .enable = exynos4_clk_ip_cam_ctrl, |
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 031c1e5b3dfe..7f1f2687147d 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 | ||
49 | static const char name_exynos4210[] = "EXYNOS4210"; | 53 | static const char name_exynos4210[] = "EXYNOS4210"; |
50 | static const char name_exynos4212[] = "EXYNOS4212"; | 54 | static const char name_exynos4212[] = "EXYNOS4212"; |
@@ -173,7 +177,12 @@ static struct map_desc exynos4_iodesc[] __initdata = { | |||
173 | }, { | 177 | }, { |
174 | .virtual = (unsigned long)S5P_VA_DMC0, | 178 | .virtual = (unsigned long)S5P_VA_DMC0, |
175 | .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), | 179 | .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), |
176 | .length = SZ_4K, | 180 | .length = SZ_64K, |
181 | .type = MT_DEVICE, | ||
182 | }, { | ||
183 | .virtual = (unsigned long)S5P_VA_DMC1, | ||
184 | .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1), | ||
185 | .length = SZ_64K, | ||
177 | .type = MT_DEVICE, | 186 | .type = MT_DEVICE, |
178 | }, { | 187 | }, { |
179 | .virtual = (unsigned long)S3C_VA_USB_HSPHY, | 188 | .virtual = (unsigned long)S3C_VA_USB_HSPHY, |
@@ -433,23 +442,48 @@ core_initcall(exynos4_core_init); | |||
433 | #ifdef CONFIG_CACHE_L2X0 | 442 | #ifdef CONFIG_CACHE_L2X0 |
434 | static int __init exynos4_l2x0_cache_init(void) | 443 | static int __init exynos4_l2x0_cache_init(void) |
435 | { | 444 | { |
436 | /* TAG, Data Latency Control: 2cycle */ | 445 | int ret; |
437 | __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); | 446 | ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK); |
447 | if (!ret) { | ||
448 | l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs); | ||
449 | clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long)); | ||
450 | return 0; | ||
451 | } | ||
438 | 452 | ||
439 | if (soc_is_exynos4210()) | 453 | if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) { |
440 | __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); | 454 | l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC; |
441 | else if (soc_is_exynos4212() || soc_is_exynos4412()) | 455 | /* TAG, Data Latency Control: 2 cycles */ |
442 | __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); | 456 | l2x0_saved_regs.tag_latency = 0x110; |
457 | |||
458 | if (soc_is_exynos4212() || soc_is_exynos4412()) | ||
459 | l2x0_saved_regs.data_latency = 0x120; | ||
460 | else | ||
461 | l2x0_saved_regs.data_latency = 0x110; | ||
462 | |||
463 | l2x0_saved_regs.prefetch_ctrl = 0x30000007; | ||
464 | l2x0_saved_regs.pwr_ctrl = | ||
465 | (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN); | ||
443 | 466 | ||
444 | /* L2X0 Prefetch Control */ | 467 | l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs); |
445 | __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); | ||
446 | 468 | ||
447 | /* L2X0 Power Control */ | 469 | __raw_writel(l2x0_saved_regs.tag_latency, |
448 | __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, | 470 | S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); |
449 | S5P_VA_L2CC + L2X0_POWER_CTRL); | 471 | __raw_writel(l2x0_saved_regs.data_latency, |
472 | S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); | ||
450 | 473 | ||
451 | l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); | 474 | /* L2X0 Prefetch Control */ |
475 | __raw_writel(l2x0_saved_regs.prefetch_ctrl, | ||
476 | S5P_VA_L2CC + L2X0_PREFETCH_CTRL); | ||
477 | |||
478 | /* L2X0 Power Control */ | ||
479 | __raw_writel(l2x0_saved_regs.pwr_ctrl, | ||
480 | S5P_VA_L2CC + L2X0_POWER_CTRL); | ||
481 | |||
482 | clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long)); | ||
483 | clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs)); | ||
484 | } | ||
452 | 485 | ||
486 | l2x0_init(S5P_VA_L2CC, L2_AUX_VAL, L2_AUX_MASK); | ||
453 | return 0; | 487 | return 0; |
454 | } | 488 | } |
455 | 489 | ||
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index 4ebb382c5979..33ab4e7558af 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 | ||
20 | static int exynos4_enter_idle(struct cpuidle_device *dev, | 37 | static int exynos4_enter_idle(struct cpuidle_device *dev, |
21 | struct cpuidle_driver *drv, | 38 | struct cpuidle_driver *drv, |
22 | int index); | 39 | int index); |
40 | static int exynos4_enter_lowpower(struct cpuidle_device *dev, | ||
41 | struct cpuidle_driver *drv, | ||
42 | int index); | ||
23 | 43 | ||
24 | static struct cpuidle_state exynos4_cpuidle_set[] = { | 44 | static 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 | ||
35 | static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device); | 63 | static 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 */ | ||
71 | static void exynos4_set_wakeupmask(void) | ||
72 | { | ||
73 | __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK); | ||
74 | } | ||
75 | |||
76 | static unsigned int g_pwr_ctrl, g_diag_reg; | ||
77 | |||
78 | static 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 | |||
87 | static 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 | |||
96 | static int idle_finisher(unsigned long flags) | ||
97 | { | ||
98 | cpu_do_idle(); | ||
99 | return 1; | ||
100 | } | ||
101 | |||
102 | static 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 | |||
42 | static int exynos4_enter_idle(struct cpuidle_device *dev, | 163 | static 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 | ||
184 | static 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 | |||
63 | static int __init exynos4_init_cpuidle(void) | 200 | static 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 | } |
92 | device_initcall(exynos4_init_cpuidle); | 235 | device_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 c754a22a2bb3..a8cd65fcc685 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h | |||
@@ -31,6 +31,10 @@ | |||
31 | #define EXYNOS4_PA_FIMC2 0x11820000 | 31 | #define EXYNOS4_PA_FIMC2 0x11820000 |
32 | #define EXYNOS4_PA_FIMC3 0x11830000 | 32 | #define EXYNOS4_PA_FIMC3 0x11830000 |
33 | 33 | ||
34 | #define EXYNOS4_PA_JPEG 0x11840000 | ||
35 | |||
36 | #define EXYNOS4_PA_G2D 0x12800000 | ||
37 | |||
34 | #define EXYNOS4_PA_I2S0 0x03830000 | 38 | #define EXYNOS4_PA_I2S0 0x03830000 |
35 | #define EXYNOS4_PA_I2S1 0xE3100000 | 39 | #define EXYNOS4_PA_I2S1 0xE3100000 |
36 | #define EXYNOS4_PA_I2S2 0xE2A00000 | 40 | #define EXYNOS4_PA_I2S2 0xE2A00000 |
@@ -57,6 +61,7 @@ | |||
57 | #define EXYNOS4_PA_KEYPAD 0x100A0000 | 61 | #define EXYNOS4_PA_KEYPAD 0x100A0000 |
58 | 62 | ||
59 | #define EXYNOS4_PA_DMC0 0x10400000 | 63 | #define EXYNOS4_PA_DMC0 0x10400000 |
64 | #define EXYNOS4_PA_DMC1 0x10410000 | ||
60 | 65 | ||
61 | #define EXYNOS4_PA_COMBINER 0x10440000 | 66 | #define EXYNOS4_PA_COMBINER 0x10440000 |
62 | 67 | ||
@@ -162,6 +167,8 @@ | |||
162 | #define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1 | 167 | #define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1 |
163 | #define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2 | 168 | #define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2 |
164 | #define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3 | 169 | #define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3 |
170 | #define S5P_PA_JPEG EXYNOS4_PA_JPEG | ||
171 | #define S5P_PA_G2D EXYNOS4_PA_G2D | ||
165 | #define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0 | 172 | #define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0 |
166 | #define S5P_PA_HDMI EXYNOS4_PA_HDMI | 173 | #define S5P_PA_HDMI EXYNOS4_PA_HDMI |
167 | #define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY | 174 | #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 632dd5630138..e76b7faba66b 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 | ||
25 | extern unsigned long l2x0_regs_phys; | ||
25 | struct exynos4_pmu_conf { | 26 | struct 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 | ||
30 | extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); | 31 | extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); |
32 | extern 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 85b5527d0918..3e894ba25b01 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 | |||
32 | enum { | 34 | enum { |
33 | MCT_INT_SPI, | 35 | MCT_INT_SPI, |
34 | MCT_INT_PPI | 36 | MCT_INT_PPI |
35 | }; | 37 | }; |
36 | 38 | ||
37 | static unsigned long clk_cnt_per_tick; | ||
38 | static unsigned long clk_rate; | 39 | static unsigned long clk_rate; |
39 | static unsigned int mct_int_type; | 40 | static unsigned int mct_int_type; |
40 | 41 | ||
@@ -205,11 +206,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles, | |||
205 | static void exynos4_comp_set_mode(enum clock_event_mode mode, | 206 | static 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 | ||
249 | static void exynos4_clockevent_init(void) | 253 | static 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 = |
@@ -314,12 +316,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode, | |||
314 | struct clock_event_device *evt) | 316 | struct clock_event_device *evt) |
315 | { | 317 | { |
316 | struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); | 318 | struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); |
319 | unsigned long cycles_per_jiffy; | ||
317 | 320 | ||
318 | exynos4_mct_tick_stop(mevt); | 321 | exynos4_mct_tick_stop(mevt); |
319 | 322 | ||
320 | switch (mode) { | 323 | switch (mode) { |
321 | case CLOCK_EVT_MODE_PERIODIC: | 324 | case CLOCK_EVT_MODE_PERIODIC: |
322 | exynos4_mct_tick_start(clk_cnt_per_tick, mevt); | 325 | cycles_per_jiffy = |
326 | (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); | ||
327 | exynos4_mct_tick_start(cycles_per_jiffy, mevt); | ||
323 | break; | 328 | break; |
324 | 329 | ||
325 | case CLOCK_EVT_MODE_ONESHOT: | 330 | case CLOCK_EVT_MODE_ONESHOT: |
@@ -393,7 +398,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) | |||
393 | evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; | 398 | evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; |
394 | evt->rating = 450; | 399 | evt->rating = 450; |
395 | 400 | ||
396 | clockevents_calc_mult_shift(evt, clk_rate / 2, 5); | 401 | clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5); |
397 | evt->max_delta_ns = | 402 | evt->max_delta_ns = |
398 | clockevent_delta2ns(0x7fffffff, evt); | 403 | clockevent_delta2ns(0x7fffffff, evt); |
399 | evt->min_delta_ns = | 404 | evt->min_delta_ns = |
@@ -401,7 +406,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) | |||
401 | 406 | ||
402 | clockevents_register_device(evt); | 407 | clockevents_register_device(evt); |
403 | 408 | ||
404 | exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET); | 409 | exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); |
405 | 410 | ||
406 | if (mct_int_type == MCT_INT_SPI) { | 411 | if (mct_int_type == MCT_INT_SPI) { |
407 | if (cpu == 0) { | 412 | if (cpu == 0) { |
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index e19013051772..481682745e7d 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 | ||
158 | static 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 */ |
167 | static unsigned int save_arm_register[2]; | 160 | static 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 | |||
398 | early_wakeup: | 383 | early_wakeup: |
399 | return; | 384 | return; |
400 | } | 385 | } |
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index dd20c66cd700..326ea3a98725 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig | |||
@@ -83,6 +83,11 @@ config S3C64XX_SETUP_SPI | |||
83 | help | 83 | help |
84 | Common setup code for SPI GPIO configurations | 84 | Common setup code for SPI GPIO configurations |
85 | 85 | ||
86 | config S3C64XX_SETUP_USB_PHY | ||
87 | bool | ||
88 | help | ||
89 | Common setup code for USB PHY controller | ||
90 | |||
86 | # S36400 Macchine support | 91 | # S36400 Macchine support |
87 | 92 | ||
88 | config MACH_SMDK6400 | 93 | config MACH_SMDK6400 |
@@ -157,6 +162,7 @@ config MACH_SMDK6410 | |||
157 | select S3C64XX_SETUP_IDE | 162 | select S3C64XX_SETUP_IDE |
158 | select S3C64XX_SETUP_FB_24BPP | 163 | select S3C64XX_SETUP_FB_24BPP |
159 | select S3C64XX_SETUP_KEYPAD | 164 | select S3C64XX_SETUP_KEYPAD |
165 | select S3C64XX_SETUP_USB_PHY | ||
160 | help | 166 | help |
161 | Machine support for the Samsung SMDK6410 | 167 | Machine support for the Samsung SMDK6410 |
162 | 168 | ||
@@ -256,6 +262,7 @@ config MACH_SMARTQ | |||
256 | select S3C_DEV_USB_HOST | 262 | select S3C_DEV_USB_HOST |
257 | select S3C64XX_SETUP_SDHCI | 263 | select S3C64XX_SETUP_SDHCI |
258 | select S3C64XX_SETUP_FB_24BPP | 264 | select S3C64XX_SETUP_FB_24BPP |
265 | select S3C64XX_SETUP_USB_PHY | ||
259 | select SAMSUNG_DEV_ADC | 266 | select SAMSUNG_DEV_ADC |
260 | select SAMSUNG_DEV_PWM | 267 | select SAMSUNG_DEV_PWM |
261 | select SAMSUNG_DEV_TS | 268 | select SAMSUNG_DEV_TS |
@@ -283,6 +290,7 @@ config MACH_WLF_CRAGG_6410 | |||
283 | select S3C64XX_SETUP_FB_24BPP | 290 | select S3C64XX_SETUP_FB_24BPP |
284 | select S3C64XX_SETUP_KEYPAD | 291 | select S3C64XX_SETUP_KEYPAD |
285 | select S3C64XX_SETUP_SPI | 292 | select S3C64XX_SETUP_SPI |
293 | select S3C64XX_SETUP_USB_PHY | ||
286 | select SAMSUNG_DEV_ADC | 294 | select SAMSUNG_DEV_ADC |
287 | select SAMSUNG_DEV_KEYPAD | 295 | select SAMSUNG_DEV_KEYPAD |
288 | select S3C_DEV_USB_HOST | 296 | select S3C_DEV_USB_HOST |
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 1822ac2eba31..f9ce1dc28ce4 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_CPU_S3C6410) += s3c6410.o | |||
22 | # PM | 22 | # PM |
23 | 23 | ||
24 | obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o | 24 | obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o |
25 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | ||
25 | 26 | ||
26 | # DMA support | 27 | # DMA support |
27 | 28 | ||
@@ -42,6 +43,7 @@ obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o | |||
42 | obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o | 43 | obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o |
43 | obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o | 44 | obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o |
44 | obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o | 45 | obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o |
46 | obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o | ||
45 | 47 | ||
46 | # Machine support | 48 | # Machine support |
47 | 49 | ||
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index aebbcc291b4e..52f079a691cb 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c | |||
@@ -207,6 +207,15 @@ static struct clk init_clocks_off[] = { | |||
207 | .enable = s3c64xx_sclk_ctrl, | 207 | .enable = s3c64xx_sclk_ctrl, |
208 | .ctrlbit = S3C_CLKCON_SCLK_MMC2_48, | 208 | .ctrlbit = S3C_CLKCON_SCLK_MMC2_48, |
209 | }, { | 209 | }, { |
210 | .name = "ac97", | ||
211 | .parent = &clk_p, | ||
212 | .ctrlbit = S3C_CLKCON_PCLK_AC97, | ||
213 | }, { | ||
214 | .name = "cfcon", | ||
215 | .parent = &clk_h, | ||
216 | .enable = s3c64xx_hclk_ctrl, | ||
217 | .ctrlbit = S3C_CLKCON_HCLK_IHOST, | ||
218 | }, { | ||
210 | .name = "dma0", | 219 | .name = "dma0", |
211 | .parent = &clk_h, | 220 | .parent = &clk_h, |
212 | .enable = s3c64xx_hclk_ctrl, | 221 | .enable = s3c64xx_hclk_ctrl, |
@@ -216,6 +225,107 @@ static struct clk init_clocks_off[] = { | |||
216 | .parent = &clk_h, | 225 | .parent = &clk_h, |
217 | .enable = s3c64xx_hclk_ctrl, | 226 | .enable = s3c64xx_hclk_ctrl, |
218 | .ctrlbit = S3C_CLKCON_HCLK_DMA1, | 227 | .ctrlbit = S3C_CLKCON_HCLK_DMA1, |
228 | }, { | ||
229 | .name = "3dse", | ||
230 | .parent = &clk_h, | ||
231 | .enable = s3c64xx_hclk_ctrl, | ||
232 | .ctrlbit = S3C_CLKCON_HCLK_3DSE, | ||
233 | }, { | ||
234 | .name = "hclk_secur", | ||
235 | .parent = &clk_h, | ||
236 | .enable = s3c64xx_hclk_ctrl, | ||
237 | .ctrlbit = S3C_CLKCON_HCLK_SECUR, | ||
238 | }, { | ||
239 | .name = "sdma1", | ||
240 | .parent = &clk_h, | ||
241 | .enable = s3c64xx_hclk_ctrl, | ||
242 | .ctrlbit = S3C_CLKCON_HCLK_SDMA1, | ||
243 | }, { | ||
244 | .name = "sdma0", | ||
245 | .parent = &clk_h, | ||
246 | .enable = s3c64xx_hclk_ctrl, | ||
247 | .ctrlbit = S3C_CLKCON_HCLK_SDMA0, | ||
248 | }, { | ||
249 | .name = "hclk_jpeg", | ||
250 | .parent = &clk_h, | ||
251 | .enable = s3c64xx_hclk_ctrl, | ||
252 | .ctrlbit = S3C_CLKCON_HCLK_JPEG, | ||
253 | }, { | ||
254 | .name = "camif", | ||
255 | .parent = &clk_h, | ||
256 | .enable = s3c64xx_hclk_ctrl, | ||
257 | .ctrlbit = S3C_CLKCON_HCLK_CAMIF, | ||
258 | }, { | ||
259 | .name = "hclk_scaler", | ||
260 | .parent = &clk_h, | ||
261 | .enable = s3c64xx_hclk_ctrl, | ||
262 | .ctrlbit = S3C_CLKCON_HCLK_SCALER, | ||
263 | }, { | ||
264 | .name = "2d", | ||
265 | .parent = &clk_h, | ||
266 | .enable = s3c64xx_hclk_ctrl, | ||
267 | .ctrlbit = S3C_CLKCON_HCLK_2D, | ||
268 | }, { | ||
269 | .name = "tv", | ||
270 | .parent = &clk_h, | ||
271 | .enable = s3c64xx_hclk_ctrl, | ||
272 | .ctrlbit = S3C_CLKCON_HCLK_TV, | ||
273 | }, { | ||
274 | .name = "post0", | ||
275 | .parent = &clk_h, | ||
276 | .enable = s3c64xx_hclk_ctrl, | ||
277 | .ctrlbit = S3C_CLKCON_HCLK_POST0, | ||
278 | }, { | ||
279 | .name = "rot", | ||
280 | .parent = &clk_h, | ||
281 | .enable = s3c64xx_hclk_ctrl, | ||
282 | .ctrlbit = S3C_CLKCON_HCLK_ROT, | ||
283 | }, { | ||
284 | .name = "hclk_mfc", | ||
285 | .parent = &clk_h, | ||
286 | .enable = s3c64xx_hclk_ctrl, | ||
287 | .ctrlbit = S3C_CLKCON_HCLK_MFC, | ||
288 | }, { | ||
289 | .name = "pclk_mfc", | ||
290 | .parent = &clk_p, | ||
291 | .enable = s3c64xx_pclk_ctrl, | ||
292 | .ctrlbit = S3C_CLKCON_PCLK_MFC, | ||
293 | }, { | ||
294 | .name = "dac27", | ||
295 | .enable = s3c64xx_sclk_ctrl, | ||
296 | .ctrlbit = S3C_CLKCON_SCLK_DAC27, | ||
297 | }, { | ||
298 | .name = "tv27", | ||
299 | .enable = s3c64xx_sclk_ctrl, | ||
300 | .ctrlbit = S3C_CLKCON_SCLK_TV27, | ||
301 | }, { | ||
302 | .name = "scaler27", | ||
303 | .enable = s3c64xx_sclk_ctrl, | ||
304 | .ctrlbit = S3C_CLKCON_SCLK_SCALER27, | ||
305 | }, { | ||
306 | .name = "sclk_scaler", | ||
307 | .enable = s3c64xx_sclk_ctrl, | ||
308 | .ctrlbit = S3C_CLKCON_SCLK_SCALER, | ||
309 | }, { | ||
310 | .name = "post0_27", | ||
311 | .enable = s3c64xx_sclk_ctrl, | ||
312 | .ctrlbit = S3C_CLKCON_SCLK_POST0_27, | ||
313 | }, { | ||
314 | .name = "secur", | ||
315 | .enable = s3c64xx_sclk_ctrl, | ||
316 | .ctrlbit = S3C_CLKCON_SCLK_SECUR, | ||
317 | }, { | ||
318 | .name = "sclk_mfc", | ||
319 | .enable = s3c64xx_sclk_ctrl, | ||
320 | .ctrlbit = S3C_CLKCON_SCLK_MFC, | ||
321 | }, { | ||
322 | .name = "cam", | ||
323 | .enable = s3c64xx_sclk_ctrl, | ||
324 | .ctrlbit = S3C_CLKCON_SCLK_CAM, | ||
325 | }, { | ||
326 | .name = "sclk_jpeg", | ||
327 | .enable = s3c64xx_sclk_ctrl, | ||
328 | .ctrlbit = S3C_CLKCON_SCLK_JPEG, | ||
219 | }, | 329 | }, |
220 | }; | 330 | }; |
221 | 331 | ||
@@ -289,16 +399,7 @@ static struct clk init_clocks[] = { | |||
289 | .name = "watchdog", | 399 | .name = "watchdog", |
290 | .parent = &clk_p, | 400 | .parent = &clk_p, |
291 | .ctrlbit = S3C_CLKCON_PCLK_WDT, | 401 | .ctrlbit = S3C_CLKCON_PCLK_WDT, |
292 | }, { | 402 | }, |
293 | .name = "ac97", | ||
294 | .parent = &clk_p, | ||
295 | .ctrlbit = S3C_CLKCON_PCLK_AC97, | ||
296 | }, { | ||
297 | .name = "cfcon", | ||
298 | .parent = &clk_h, | ||
299 | .enable = s3c64xx_hclk_ctrl, | ||
300 | .ctrlbit = S3C_CLKCON_HCLK_IHOST, | ||
301 | } | ||
302 | }; | 403 | }; |
303 | 404 | ||
304 | static struct clk clk_hsmmc0 = { | 405 | static struct clk clk_hsmmc0 = { |
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c new file mode 100644 index 000000000000..179460f38db7 --- /dev/null +++ b/arch/arm/mach-s3c64xx/cpuidle.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* linux/arch/arm/mach-s3c64xx/cpuidle.c | ||
2 | * | ||
3 | * Copyright (c) 2011 Wolfson Microelectronics, plc | ||
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
5 | * http://www.samsung.com | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/cpuidle.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/export.h> | ||
17 | #include <linux/time.h> | ||
18 | |||
19 | #include <asm/proc-fns.h> | ||
20 | |||
21 | #include <mach/map.h> | ||
22 | |||
23 | #include <mach/regs-sys.h> | ||
24 | #include <mach/regs-syscon-power.h> | ||
25 | |||
26 | static int s3c64xx_enter_idle(struct cpuidle_device *dev, | ||
27 | struct cpuidle_driver *drv, | ||
28 | int index) | ||
29 | { | ||
30 | struct timeval before, after; | ||
31 | unsigned long tmp; | ||
32 | int idle_time; | ||
33 | |||
34 | local_irq_disable(); | ||
35 | do_gettimeofday(&before); | ||
36 | |||
37 | /* Setup PWRCFG to enter idle mode */ | ||
38 | tmp = __raw_readl(S3C64XX_PWR_CFG); | ||
39 | tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK; | ||
40 | tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE; | ||
41 | __raw_writel(tmp, S3C64XX_PWR_CFG); | ||
42 | |||
43 | cpu_do_idle(); | ||
44 | |||
45 | do_gettimeofday(&after); | ||
46 | local_irq_enable(); | ||
47 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | ||
48 | (after.tv_usec - before.tv_usec); | ||
49 | |||
50 | dev->last_residency = idle_time; | ||
51 | return index; | ||
52 | } | ||
53 | |||
54 | static struct cpuidle_state s3c64xx_cpuidle_set[] = { | ||
55 | [0] = { | ||
56 | .enter = s3c64xx_enter_idle, | ||
57 | .exit_latency = 1, | ||
58 | .target_residency = 1, | ||
59 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
60 | .name = "IDLE", | ||
61 | .desc = "System active, ARM gated", | ||
62 | }, | ||
63 | }; | ||
64 | |||
65 | static struct cpuidle_driver s3c64xx_cpuidle_driver = { | ||
66 | .name = "s3c64xx_cpuidle", | ||
67 | .owner = THIS_MODULE, | ||
68 | .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set), | ||
69 | }; | ||
70 | |||
71 | static struct cpuidle_device s3c64xx_cpuidle_device = { | ||
72 | .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set), | ||
73 | }; | ||
74 | |||
75 | static int __init s3c64xx_init_cpuidle(void) | ||
76 | { | ||
77 | int ret; | ||
78 | |||
79 | memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set, | ||
80 | sizeof(s3c64xx_cpuidle_set)); | ||
81 | cpuidle_register_driver(&s3c64xx_cpuidle_driver); | ||
82 | |||
83 | ret = cpuidle_register_device(&s3c64xx_cpuidle_device); | ||
84 | if (ret) { | ||
85 | pr_err("Failed to register cpuidle device: %d\n", ret); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | device_initcall(s3c64xx_init_cpuidle); | ||
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 8077f650eb0e..3b56bd9cb880 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <plat/sdhci.h> | 59 | #include <plat/sdhci.h> |
60 | #include <plat/gpio-cfg.h> | 60 | #include <plat/gpio-cfg.h> |
61 | #include <plat/s3c64xx-spi.h> | 61 | #include <plat/s3c64xx-spi.h> |
62 | #include <plat/udc-hs.h> | ||
62 | 63 | ||
63 | #include <plat/keypad.h> | 64 | #include <plat/keypad.h> |
64 | #include <plat/clock.h> | 65 | #include <plat/clock.h> |
@@ -698,6 +699,8 @@ static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = { | |||
698 | .cfg_gpio = crag6410_cfg_sdhci0, | 699 | .cfg_gpio = crag6410_cfg_sdhci0, |
699 | }; | 700 | }; |
700 | 701 | ||
702 | static struct s3c_hsotg_plat crag6410_hsotg_pdata; | ||
703 | |||
701 | static void __init crag6410_machine_init(void) | 704 | static void __init crag6410_machine_init(void) |
702 | { | 705 | { |
703 | /* Open drain IRQs need pullups */ | 706 | /* Open drain IRQs need pullups */ |
@@ -722,6 +725,7 @@ static void __init crag6410_machine_init(void) | |||
722 | s3c_i2c0_set_platdata(&i2c0_pdata); | 725 | s3c_i2c0_set_platdata(&i2c0_pdata); |
723 | s3c_i2c1_set_platdata(&i2c1_pdata); | 726 | s3c_i2c1_set_platdata(&i2c1_pdata); |
724 | s3c_fb_set_platdata(&crag6410_lcd_pdata); | 727 | s3c_fb_set_platdata(&crag6410_lcd_pdata); |
728 | s3c_hsotg_set_platdata(&crag6410_hsotg_pdata); | ||
725 | 729 | ||
726 | i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); | 730 | i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); |
727 | i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); | 731 | i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); |
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index ce31db136231..ce745e19aa27 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c | |||
@@ -187,6 +187,8 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = { | |||
187 | }, | 187 | }, |
188 | }; | 188 | }; |
189 | 189 | ||
190 | static struct s3c_hsotg_plat smartq_hsotg_pdata; | ||
191 | |||
190 | static int __init smartq_lcd_setup_gpio(void) | 192 | static int __init smartq_lcd_setup_gpio(void) |
191 | { | 193 | { |
192 | int ret; | 194 | int ret; |
@@ -383,6 +385,7 @@ void __init smartq_map_io(void) | |||
383 | void __init smartq_machine_init(void) | 385 | void __init smartq_machine_init(void) |
384 | { | 386 | { |
385 | s3c_i2c0_set_platdata(NULL); | 387 | s3c_i2c0_set_platdata(NULL); |
388 | s3c_hsotg_set_platdata(&smartq_hsotg_pdata); | ||
386 | s3c_hwmon_set_platdata(&smartq_hwmon_pdata); | 389 | s3c_hwmon_set_platdata(&smartq_hwmon_pdata); |
387 | s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata); | 390 | s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata); |
388 | s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata); | 391 | s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata); |
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index ca6fc204f0ea..d55bc96d9582 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c | |||
@@ -72,6 +72,7 @@ | |||
72 | #include <plat/keypad.h> | 72 | #include <plat/keypad.h> |
73 | #include <plat/backlight.h> | 73 | #include <plat/backlight.h> |
74 | #include <plat/regs-fb-v4.h> | 74 | #include <plat/regs-fb-v4.h> |
75 | #include <plat/udc-hs.h> | ||
75 | 76 | ||
76 | #include "common.h" | 77 | #include "common.h" |
77 | 78 | ||
@@ -631,6 +632,8 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = { | |||
631 | .pwm_id = 1, | 632 | .pwm_id = 1, |
632 | }; | 633 | }; |
633 | 634 | ||
635 | static struct s3c_hsotg_plat smdk6410_hsotg_pdata; | ||
636 | |||
634 | static void __init smdk6410_map_io(void) | 637 | static void __init smdk6410_map_io(void) |
635 | { | 638 | { |
636 | u32 tmp; | 639 | u32 tmp; |
@@ -659,6 +662,7 @@ static void __init smdk6410_machine_init(void) | |||
659 | s3c_i2c0_set_platdata(NULL); | 662 | s3c_i2c0_set_platdata(NULL); |
660 | s3c_i2c1_set_platdata(NULL); | 663 | s3c_i2c1_set_platdata(NULL); |
661 | s3c_fb_set_platdata(&smdk6410_lcd_pdata); | 664 | s3c_fb_set_platdata(&smdk6410_lcd_pdata); |
665 | s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata); | ||
662 | 666 | ||
663 | samsung_keypad_set_platdata(&smdk6410_keypad_data); | 667 | samsung_keypad_set_platdata(&smdk6410_keypad_data); |
664 | 668 | ||
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c new file mode 100644 index 000000000000..f6757e02d7db --- /dev/null +++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Samsung Electronics Co.Ltd | ||
3 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <mach/map.h> | ||
18 | #include <mach/regs-sys.h> | ||
19 | #include <plat/cpu.h> | ||
20 | #include <plat/regs-usb-hsotg-phy.h> | ||
21 | #include <plat/usb-phy.h> | ||
22 | |||
23 | static int s3c_usb_otgphy_init(struct platform_device *pdev) | ||
24 | { | ||
25 | struct clk *xusbxti; | ||
26 | u32 phyclk; | ||
27 | |||
28 | writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS); | ||
29 | |||
30 | /* set clock frequency for PLL */ | ||
31 | phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK; | ||
32 | |||
33 | xusbxti = clk_get(&pdev->dev, "xusbxti"); | ||
34 | if (xusbxti && !IS_ERR(xusbxti)) { | ||
35 | switch (clk_get_rate(xusbxti)) { | ||
36 | case 12 * MHZ: | ||
37 | phyclk |= S3C_PHYCLK_CLKSEL_12M; | ||
38 | break; | ||
39 | case 24 * MHZ: | ||
40 | phyclk |= S3C_PHYCLK_CLKSEL_24M; | ||
41 | break; | ||
42 | default: | ||
43 | case 48 * MHZ: | ||
44 | /* default reference clock */ | ||
45 | break; | ||
46 | } | ||
47 | clk_put(xusbxti); | ||
48 | } | ||
49 | |||
50 | /* TODO: select external clock/oscillator */ | ||
51 | writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK); | ||
52 | |||
53 | /* set to normal OTG PHY */ | ||
54 | writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR); | ||
55 | mdelay(1); | ||
56 | |||
57 | /* reset OTG PHY and Link */ | ||
58 | writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK, | ||
59 | S3C_RSTCON); | ||
60 | udelay(20); /* at-least 10uS */ | ||
61 | writel(0, S3C_RSTCON); | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int s3c_usb_otgphy_exit(struct platform_device *pdev) | ||
67 | { | ||
68 | writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN | | ||
69 | S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR); | ||
70 | |||
71 | writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | int s5p_usb_phy_init(struct platform_device *pdev, int type) | ||
77 | { | ||
78 | if (type == S5P_USB_PHY_DEVICE) | ||
79 | return s3c_usb_otgphy_init(pdev); | ||
80 | |||
81 | return -EINVAL; | ||
82 | } | ||
83 | |||
84 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) | ||
85 | { | ||
86 | if (type == S5P_USB_PHY_DEVICE) | ||
87 | return s3c_usb_otgphy_exit(pdev); | ||
88 | |||
89 | return -EINVAL; | ||
90 | } | ||
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 2cdc42e838b8..82525e3831e9 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig | |||
@@ -65,6 +65,11 @@ config S5PV210_SETUP_SPI | |||
65 | help | 65 | help |
66 | Common setup code for SPI GPIO configurations. | 66 | Common setup code for SPI GPIO configurations. |
67 | 67 | ||
68 | config S5PV210_SETUP_USB_PHY | ||
69 | bool | ||
70 | help | ||
71 | Common setup code for USB PHY controller | ||
72 | |||
68 | menu "S5PC110 Machines" | 73 | menu "S5PC110 Machines" |
69 | 74 | ||
70 | config MACH_AQUILA | 75 | config MACH_AQUILA |
@@ -107,6 +112,7 @@ config MACH_GONI | |||
107 | select S5PV210_SETUP_KEYPAD | 112 | select S5PV210_SETUP_KEYPAD |
108 | select S5PV210_SETUP_SDHCI | 113 | select S5PV210_SETUP_SDHCI |
109 | select S5PV210_SETUP_FIMC | 114 | select S5PV210_SETUP_FIMC |
115 | select S5PV210_SETUP_USB_PHY | ||
110 | help | 116 | help |
111 | Machine support for Samsung GONI board | 117 | Machine support for Samsung GONI board |
112 | S5PC110(MCP) is one of package option of S5PV210 | 118 | S5PC110(MCP) is one of package option of S5PV210 |
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 76a121dd52b4..1c4e41998a10 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile | |||
@@ -39,3 +39,4 @@ obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o | |||
39 | obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o | 39 | obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o |
40 | obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o | 40 | obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o |
41 | obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o | 41 | obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o |
42 | obj-$(CONFIG_S5PV210_SETUP_USB_PHY) += setup-usb-phy.o | ||
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h index 26691d39d0f4..cccb1eddaa38 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-sys.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-sys.h | |||
@@ -13,7 +13,3 @@ | |||
13 | #define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C) | 13 | #define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C) |
14 | #define S5PV210_USB_PHY0_EN (1 << 0) | 14 | #define S5PV210_USB_PHY0_EN (1 << 0) |
15 | #define S5PV210_USB_PHY1_EN (1 << 1) | 15 | #define S5PV210_USB_PHY1_EN (1 << 1) |
16 | |||
17 | /* compatibility defines for s3c-hsotg driver */ | ||
18 | #define S3C64XX_OTHERS S5PV210_USB_PHY_CON | ||
19 | #define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN | ||
diff --git a/arch/arm/mach-s5pv210/setup-usb-phy.c b/arch/arm/mach-s5pv210/setup-usb-phy.c new file mode 100644 index 000000000000..be39cf4aa91b --- /dev/null +++ b/arch/arm/mach-s5pv210/setup-usb-phy.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Samsung Electronics Co.Ltd | ||
3 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundationr | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk.h> | ||
11 | #include <linux/delay.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <mach/map.h> | ||
16 | #include <mach/regs-sys.h> | ||
17 | #include <plat/cpu.h> | ||
18 | #include <plat/regs-usb-hsotg-phy.h> | ||
19 | #include <plat/usb-phy.h> | ||
20 | |||
21 | static int s5pv210_usb_otgphy_init(struct platform_device *pdev) | ||
22 | { | ||
23 | struct clk *xusbxti; | ||
24 | u32 phyclk; | ||
25 | |||
26 | writel(readl(S5PV210_USB_PHY_CON) | S5PV210_USB_PHY0_EN, | ||
27 | S5PV210_USB_PHY_CON); | ||
28 | |||
29 | /* set clock frequency for PLL */ | ||
30 | phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK; | ||
31 | |||
32 | xusbxti = clk_get(&pdev->dev, "xusbxti"); | ||
33 | if (xusbxti && !IS_ERR(xusbxti)) { | ||
34 | switch (clk_get_rate(xusbxti)) { | ||
35 | case 12 * MHZ: | ||
36 | phyclk |= S3C_PHYCLK_CLKSEL_12M; | ||
37 | break; | ||
38 | case 24 * MHZ: | ||
39 | phyclk |= S3C_PHYCLK_CLKSEL_24M; | ||
40 | break; | ||
41 | default: | ||
42 | case 48 * MHZ: | ||
43 | /* default reference clock */ | ||
44 | break; | ||
45 | } | ||
46 | clk_put(xusbxti); | ||
47 | } | ||
48 | |||
49 | /* TODO: select external clock/oscillator */ | ||
50 | writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK); | ||
51 | |||
52 | /* set to normal OTG PHY */ | ||
53 | writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR); | ||
54 | mdelay(1); | ||
55 | |||
56 | /* reset OTG PHY and Link */ | ||
57 | writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK, | ||
58 | S3C_RSTCON); | ||
59 | udelay(20); /* at-least 10uS */ | ||
60 | writel(0, S3C_RSTCON); | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int s5pv210_usb_otgphy_exit(struct platform_device *pdev) | ||
66 | { | ||
67 | writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN | | ||
68 | S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR); | ||
69 | |||
70 | writel(readl(S5PV210_USB_PHY_CON) & ~S5PV210_USB_PHY0_EN, | ||
71 | S5PV210_USB_PHY_CON); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | int s5p_usb_phy_init(struct platform_device *pdev, int type) | ||
77 | { | ||
78 | if (type == S5P_USB_PHY_DEVICE) | ||
79 | return s5pv210_usb_otgphy_init(pdev); | ||
80 | |||
81 | return -EINVAL; | ||
82 | } | ||
83 | |||
84 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) | ||
85 | { | ||
86 | if (type == S5P_USB_PHY_DEVICE) | ||
87 | return s5pv210_usb_otgphy_exit(pdev); | ||
88 | |||
89 | return -EINVAL; | ||
90 | } | ||
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 8167ce66188c..7a308699f816 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig | |||
@@ -80,6 +80,16 @@ config S5P_DEV_FIMC3 | |||
80 | help | 80 | help |
81 | Compile in platform device definitions for FIMC controller 3 | 81 | Compile in platform device definitions for FIMC controller 3 |
82 | 82 | ||
83 | config S5P_DEV_JPEG | ||
84 | bool | ||
85 | help | ||
86 | Compile in platform device definitions for JPEG codec | ||
87 | |||
88 | config S5P_DEV_G2D | ||
89 | bool | ||
90 | help | ||
91 | Compile in platform device definitions for G2D device | ||
92 | |||
83 | config S5P_DEV_FIMD0 | 93 | config S5P_DEV_FIMD0 |
84 | bool | 94 | bool |
85 | help | 95 | help |
diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-s5p/sleep.S index 0fd591bfc9fd..006bd01eda02 100644 --- a/arch/arm/plat-s5p/sleep.S +++ b/arch/arm/plat-s5p/sleep.S | |||
@@ -23,9 +23,18 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/linkage.h> | 25 | #include <linux/linkage.h> |
26 | #include <asm/assembler.h> | 26 | #include <asm/asm-offsets.h> |
27 | #include <asm/hardware/cache-l2x0.h> | ||
27 | 28 | ||
28 | .text | 29 | /* |
30 | * The following code is located into the .data section. This is to | ||
31 | * allow l2x0_regs_phys to be accessed with a relative load while we | ||
32 | * can't rely on any MMU translation. We could have put l2x0_regs_phys | ||
33 | * in the .text section as well, but some setups might insist on it to | ||
34 | * be truly read-only. (Reference from: arch/arm/kernel/sleep.S) | ||
35 | */ | ||
36 | .data | ||
37 | .align | ||
29 | 38 | ||
30 | /* | 39 | /* |
31 | * sleep magic, to allow the bootloader to check for an valid | 40 | * sleep magic, to allow the bootloader to check for an valid |
@@ -39,11 +48,34 @@ | |||
39 | * s3c_cpu_resume | 48 | * s3c_cpu_resume |
40 | * | 49 | * |
41 | * resume code entry for bootloader to call | 50 | * resume code entry for bootloader to call |
42 | * | ||
43 | * we must put this code here in the data segment as we have no | ||
44 | * other way of restoring the stack pointer after sleep, and we | ||
45 | * must not write to the code segment (code is read-only) | ||
46 | */ | 51 | */ |
47 | 52 | ||
48 | ENTRY(s3c_cpu_resume) | 53 | ENTRY(s3c_cpu_resume) |
54 | #ifdef CONFIG_CACHE_L2X0 | ||
55 | adr r0, l2x0_regs_phys | ||
56 | ldr r0, [r0] | ||
57 | ldr r1, [r0, #L2X0_R_PHY_BASE] | ||
58 | ldr r2, [r1, #L2X0_CTRL] | ||
59 | tst r2, #0x1 | ||
60 | bne resume_l2on | ||
61 | ldr r2, [r0, #L2X0_R_AUX_CTRL] | ||
62 | str r2, [r1, #L2X0_AUX_CTRL] | ||
63 | ldr r2, [r0, #L2X0_R_TAG_LATENCY] | ||
64 | str r2, [r1, #L2X0_TAG_LATENCY_CTRL] | ||
65 | ldr r2, [r0, #L2X0_R_DATA_LATENCY] | ||
66 | str r2, [r1, #L2X0_DATA_LATENCY_CTRL] | ||
67 | ldr r2, [r0, #L2X0_R_PREFETCH_CTRL] | ||
68 | str r2, [r1, #L2X0_PREFETCH_CTRL] | ||
69 | ldr r2, [r0, #L2X0_R_PWR_CTRL] | ||
70 | str r2, [r1, #L2X0_POWER_CTRL] | ||
71 | mov r2, #1 | ||
72 | str r2, [r1, #L2X0_CTRL] | ||
73 | resume_l2on: | ||
74 | #endif | ||
49 | b cpu_resume | 75 | b cpu_resume |
76 | ENDPROC(s3c_cpu_resume) | ||
77 | #ifdef CONFIG_CACHE_L2X0 | ||
78 | .globl l2x0_regs_phys | ||
79 | l2x0_regs_phys: | ||
80 | .long 0 | ||
81 | #endif | ||
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 10f71179071f..65c5eca475e7 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c | |||
@@ -84,31 +84,35 @@ static int clk_null_enable(struct clk *clk, int enable) | |||
84 | 84 | ||
85 | int clk_enable(struct clk *clk) | 85 | int clk_enable(struct clk *clk) |
86 | { | 86 | { |
87 | unsigned long flags; | ||
88 | |||
87 | if (IS_ERR(clk) || clk == NULL) | 89 | if (IS_ERR(clk) || clk == NULL) |
88 | return -EINVAL; | 90 | return -EINVAL; |
89 | 91 | ||
90 | clk_enable(clk->parent); | 92 | clk_enable(clk->parent); |
91 | 93 | ||
92 | spin_lock(&clocks_lock); | 94 | spin_lock_irqsave(&clocks_lock, flags); |
93 | 95 | ||
94 | if ((clk->usage++) == 0) | 96 | if ((clk->usage++) == 0) |
95 | (clk->enable)(clk, 1); | 97 | (clk->enable)(clk, 1); |
96 | 98 | ||
97 | spin_unlock(&clocks_lock); | 99 | spin_unlock_irqrestore(&clocks_lock, flags); |
98 | return 0; | 100 | return 0; |
99 | } | 101 | } |
100 | 102 | ||
101 | void clk_disable(struct clk *clk) | 103 | void clk_disable(struct clk *clk) |
102 | { | 104 | { |
105 | unsigned long flags; | ||
106 | |||
103 | if (IS_ERR(clk) || clk == NULL) | 107 | if (IS_ERR(clk) || clk == NULL) |
104 | return; | 108 | return; |
105 | 109 | ||
106 | spin_lock(&clocks_lock); | 110 | spin_lock_irqsave(&clocks_lock, flags); |
107 | 111 | ||
108 | if ((--clk->usage) == 0) | 112 | if ((--clk->usage) == 0) |
109 | (clk->enable)(clk, 0); | 113 | (clk->enable)(clk, 0); |
110 | 114 | ||
111 | spin_unlock(&clocks_lock); | 115 | spin_unlock_irqrestore(&clocks_lock, flags); |
112 | clk_disable(clk->parent); | 116 | clk_disable(clk->parent); |
113 | } | 117 | } |
114 | 118 | ||
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c index a976c023b286..5f197dcaf10c 100644 --- a/arch/arm/plat-samsung/dev-backlight.c +++ b/arch/arm/plat-samsung/dev-backlight.c | |||
@@ -77,7 +77,7 @@ static struct platform_device samsung_dfl_bl_device __initdata = { | |||
77 | * @gpio_info: structure containing GPIO info for PWM timer | 77 | * @gpio_info: structure containing GPIO info for PWM timer |
78 | * @bl_data: structure containing Backlight control data | 78 | * @bl_data: structure containing Backlight control data |
79 | */ | 79 | */ |
80 | void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, | 80 | void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, |
81 | struct platform_pwm_backlight_data *bl_data) | 81 | struct platform_pwm_backlight_data *bl_data) |
82 | { | 82 | { |
83 | int ret = 0; | 83 | int ret = 0; |
@@ -115,6 +115,8 @@ void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, | |||
115 | samsung_bl_data->init = bl_data->init; | 115 | samsung_bl_data->init = bl_data->init; |
116 | if (bl_data->notify) | 116 | if (bl_data->notify) |
117 | samsung_bl_data->notify = bl_data->notify; | 117 | samsung_bl_data->notify = bl_data->notify; |
118 | if (bl_data->notify_after) | ||
119 | samsung_bl_data->notify_after = bl_data->notify_after; | ||
118 | if (bl_data->exit) | 120 | if (bl_data->exit) |
119 | samsung_bl_data->exit = bl_data->exit; | 121 | samsung_bl_data->exit = bl_data->exit; |
120 | if (bl_data->check_fb) | 122 | if (bl_data->check_fb) |
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index f10768e988d4..eb3ba1385b06 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <plat/sdhci.h> | 57 | #include <plat/sdhci.h> |
58 | #include <plat/ts.h> | 58 | #include <plat/ts.h> |
59 | #include <plat/udc.h> | 59 | #include <plat/udc.h> |
60 | #include <plat/udc-hs.h> | ||
60 | #include <plat/usb-control.h> | 61 | #include <plat/usb-control.h> |
61 | #include <plat/usb-phy.h> | 62 | #include <plat/usb-phy.h> |
62 | #include <plat/regs-iic.h> | 63 | #include <plat/regs-iic.h> |
@@ -267,6 +268,52 @@ struct platform_device s5p_device_fimc3 = { | |||
267 | }; | 268 | }; |
268 | #endif /* CONFIG_S5P_DEV_FIMC3 */ | 269 | #endif /* CONFIG_S5P_DEV_FIMC3 */ |
269 | 270 | ||
271 | /* G2D */ | ||
272 | |||
273 | #ifdef CONFIG_S5P_DEV_G2D | ||
274 | static struct resource s5p_g2d_resource[] = { | ||
275 | [0] = { | ||
276 | .start = S5P_PA_G2D, | ||
277 | .end = S5P_PA_G2D + SZ_4K - 1, | ||
278 | .flags = IORESOURCE_MEM, | ||
279 | }, | ||
280 | [1] = { | ||
281 | .start = IRQ_2D, | ||
282 | .end = IRQ_2D, | ||
283 | .flags = IORESOURCE_IRQ, | ||
284 | }, | ||
285 | }; | ||
286 | |||
287 | struct platform_device s5p_device_g2d = { | ||
288 | .name = "s5p-g2d", | ||
289 | .id = 0, | ||
290 | .num_resources = ARRAY_SIZE(s5p_g2d_resource), | ||
291 | .resource = s5p_g2d_resource, | ||
292 | .dev = { | ||
293 | .dma_mask = &samsung_device_dma_mask, | ||
294 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
295 | }, | ||
296 | }; | ||
297 | #endif /* CONFIG_S5P_DEV_G2D */ | ||
298 | |||
299 | #ifdef CONFIG_S5P_DEV_JPEG | ||
300 | static struct resource s5p_jpeg_resource[] = { | ||
301 | [0] = DEFINE_RES_MEM(S5P_PA_JPEG, SZ_4K), | ||
302 | [1] = DEFINE_RES_IRQ(IRQ_JPEG), | ||
303 | }; | ||
304 | |||
305 | struct platform_device s5p_device_jpeg = { | ||
306 | .name = "s5p-jpeg", | ||
307 | .id = 0, | ||
308 | .num_resources = ARRAY_SIZE(s5p_jpeg_resource), | ||
309 | .resource = s5p_jpeg_resource, | ||
310 | .dev = { | ||
311 | .dma_mask = &samsung_device_dma_mask, | ||
312 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
313 | }, | ||
314 | }; | ||
315 | #endif /* CONFIG_S5P_DEV_JPEG */ | ||
316 | |||
270 | /* FIMD0 */ | 317 | /* FIMD0 */ |
271 | 318 | ||
272 | #ifdef CONFIG_S5P_DEV_FIMD0 | 319 | #ifdef CONFIG_S5P_DEV_FIMD0 |
@@ -769,7 +816,7 @@ struct platform_device s3c_device_cfcon = { | |||
769 | .resource = s3c_cfcon_resource, | 816 | .resource = s3c_cfcon_resource, |
770 | }; | 817 | }; |
771 | 818 | ||
772 | void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) | 819 | void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) |
773 | { | 820 | { |
774 | s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata), | 821 | s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata), |
775 | &s3c_device_cfcon); | 822 | &s3c_device_cfcon); |
@@ -887,7 +934,7 @@ struct platform_device s5p_device_mfc_r = { | |||
887 | 934 | ||
888 | #ifdef CONFIG_S5P_DEV_CSIS0 | 935 | #ifdef CONFIG_S5P_DEV_CSIS0 |
889 | static struct resource s5p_mipi_csis0_resource[] = { | 936 | static struct resource s5p_mipi_csis0_resource[] = { |
890 | [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_4K), | 937 | [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_16K), |
891 | [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0), | 938 | [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0), |
892 | }; | 939 | }; |
893 | 940 | ||
@@ -901,7 +948,7 @@ struct platform_device s5p_device_mipi_csis0 = { | |||
901 | 948 | ||
902 | #ifdef CONFIG_S5P_DEV_CSIS1 | 949 | #ifdef CONFIG_S5P_DEV_CSIS1 |
903 | static struct resource s5p_mipi_csis1_resource[] = { | 950 | static struct resource s5p_mipi_csis1_resource[] = { |
904 | [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_4K), | 951 | [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_16K), |
905 | [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1), | 952 | [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1), |
906 | }; | 953 | }; |
907 | 954 | ||
@@ -1049,7 +1096,7 @@ struct platform_device s3c64xx_device_onenand1 = { | |||
1049 | .resource = s3c64xx_onenand1_resources, | 1096 | .resource = s3c64xx_onenand1_resources, |
1050 | }; | 1097 | }; |
1051 | 1098 | ||
1052 | void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata) | 1099 | void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata) |
1053 | { | 1100 | { |
1054 | s3c_set_platdata(pdata, sizeof(struct onenand_platform_data), | 1101 | s3c_set_platdata(pdata, sizeof(struct onenand_platform_data), |
1055 | &s3c64xx_device_onenand1); | 1102 | &s3c64xx_device_onenand1); |
@@ -1423,6 +1470,19 @@ struct platform_device s3c_device_usb_hsotg = { | |||
1423 | .coherent_dma_mask = DMA_BIT_MASK(32), | 1470 | .coherent_dma_mask = DMA_BIT_MASK(32), |
1424 | }, | 1471 | }, |
1425 | }; | 1472 | }; |
1473 | |||
1474 | void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd) | ||
1475 | { | ||
1476 | struct s3c_hsotg_plat *npd; | ||
1477 | |||
1478 | npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat), | ||
1479 | &s3c_device_usb_hsotg); | ||
1480 | |||
1481 | if (!npd->phy_init) | ||
1482 | npd->phy_init = s5p_usb_phy_init; | ||
1483 | if (!npd->phy_exit) | ||
1484 | npd->phy_exit = s5p_usb_phy_exit; | ||
1485 | } | ||
1426 | #endif /* CONFIG_S3C_DEV_USB_HSOTG */ | 1486 | #endif /* CONFIG_S3C_DEV_USB_HSOTG */ |
1427 | 1487 | ||
1428 | /* USB High Spped 2.0 Device (Gadget) */ | 1488 | /* USB High Spped 2.0 Device (Gadget) */ |
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 4214ea0ff8fe..5e7972de3ed5 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h | |||
@@ -79,6 +79,8 @@ extern struct platform_device s5p_device_fimc1; | |||
79 | extern struct platform_device s5p_device_fimc2; | 79 | extern struct platform_device s5p_device_fimc2; |
80 | extern struct platform_device s5p_device_fimc3; | 80 | extern struct platform_device s5p_device_fimc3; |
81 | extern struct platform_device s5p_device_fimc_md; | 81 | extern struct platform_device s5p_device_fimc_md; |
82 | extern struct platform_device s5p_device_jpeg; | ||
83 | extern struct platform_device s5p_device_g2d; | ||
82 | extern struct platform_device s5p_device_fimd0; | 84 | extern struct platform_device s5p_device_fimd0; |
83 | extern struct platform_device s5p_device_hdmi; | 85 | extern struct platform_device s5p_device_hdmi; |
84 | extern struct platform_device s5p_device_i2c_hdmiphy; | 86 | extern struct platform_device s5p_device_i2c_hdmiphy; |
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h index a111ad871833..fcf279662067 100644 --- a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h +++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h | |||
@@ -25,8 +25,9 @@ | |||
25 | #define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY) | 25 | #define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY) |
26 | 26 | ||
27 | #define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00) | 27 | #define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00) |
28 | #define SRC_PHYPWR_OTG_DISABLE (1 << 4) | 28 | #define S3C_PHYPWR_NORMAL_MASK (0x19 << 0) |
29 | #define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3) | 29 | #define S3C_PHYPWR_OTG_DISABLE (1 << 4) |
30 | #define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3) | ||
30 | #define SRC_PHYPWR_FORCE_SUSPEND (1 << 1) | 31 | #define SRC_PHYPWR_FORCE_SUSPEND (1 << 1) |
31 | 32 | ||
32 | #define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04) | 33 | #define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04) |
@@ -42,7 +43,7 @@ | |||
42 | 43 | ||
43 | #define S3C_RSTCON S3C_HSOTG_PHYREG(0x08) | 44 | #define S3C_RSTCON S3C_HSOTG_PHYREG(0x08) |
44 | #define S3C_RSTCON_PHYCLK (1 << 2) | 45 | #define S3C_RSTCON_PHYCLK (1 << 2) |
45 | #define S3C_RSTCON_HCLK (1 << 2) | 46 | #define S3C_RSTCON_HCLK (1 << 1) |
46 | #define S3C_RSTCON_PHY (1 << 0) | 47 | #define S3C_RSTCON_PHY (1 << 0) |
47 | 48 | ||
48 | #define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20) | 49 | #define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20) |
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h index a22a4f2eea94..c9e3667cb2b1 100644 --- a/arch/arm/plat-samsung/include/plat/udc-hs.h +++ b/arch/arm/plat-samsung/include/plat/udc-hs.h | |||
@@ -26,4 +26,9 @@ enum s3c_hsotg_dmamode { | |||
26 | struct s3c_hsotg_plat { | 26 | struct s3c_hsotg_plat { |
27 | enum s3c_hsotg_dmamode dma; | 27 | enum s3c_hsotg_dmamode dma; |
28 | unsigned int is_osc : 1; | 28 | unsigned int is_osc : 1; |
29 | |||
30 | int (*phy_init)(struct platform_device *pdev, int type); | ||
31 | int (*phy_exit)(struct platform_device *pdev, int type); | ||
29 | }; | 32 | }; |
33 | |||
34 | extern void s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd); | ||