aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos/common.c')
-rw-r--r--arch/arm/mach-exynos/common.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 745e304ad0de..027c9e7f0d13 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -10,12 +10,14 @@
10 */ 10 */
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/bitops.h>
13#include <linux/interrupt.h> 14#include <linux/interrupt.h>
14#include <linux/irq.h> 15#include <linux/irq.h>
15#include <linux/irqchip.h> 16#include <linux/irqchip.h>
16#include <linux/io.h> 17#include <linux/io.h>
17#include <linux/device.h> 18#include <linux/device.h>
18#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <clocksource/samsung_pwm.h>
19#include <linux/sched.h> 21#include <linux/sched.h>
20#include <linux/serial_core.h> 22#include <linux/serial_core.h>
21#include <linux/of.h> 23#include <linux/of.h>
@@ -302,6 +304,13 @@ static struct map_desc exynos5440_iodesc0[] __initdata = {
302 }, 304 },
303}; 305};
304 306
307static struct samsung_pwm_variant exynos4_pwm_variant = {
308 .bits = 32,
309 .div_base = 0,
310 .has_tint_cstat = true,
311 .tclk_mask = 0,
312};
313
305void exynos4_restart(char mode, const char *cmd) 314void exynos4_restart(char mode, const char *cmd)
306{ 315{
307 __raw_writel(0x1, S5P_SWRESET); 316 __raw_writel(0x1, S5P_SWRESET);
@@ -317,9 +326,16 @@ void exynos5_restart(char mode, const char *cmd)
317 val = 0x1; 326 val = 0x1;
318 addr = EXYNOS_SWRESET; 327 addr = EXYNOS_SWRESET;
319 } else if (of_machine_is_compatible("samsung,exynos5440")) { 328 } else if (of_machine_is_compatible("samsung,exynos5440")) {
329 u32 status;
320 np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock"); 330 np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
331
332 addr = of_iomap(np, 0) + 0xbc;
333 status = __raw_readl(addr);
334
321 addr = of_iomap(np, 0) + 0xcc; 335 addr = of_iomap(np, 0) + 0xcc;
322 val = (0xfff << 20) | (0x1 << 16); 336 val = __raw_readl(addr);
337
338 val = (val & 0xffff0000) | (status & 0xffff);
323 } else { 339 } else {
324 pr_err("%s: cannot support non-DT\n", __func__); 340 pr_err("%s: cannot support non-DT\n", __func__);
325 return; 341 return;
@@ -442,8 +458,20 @@ static void __init exynos5440_map_io(void)
442 iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0)); 458 iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0));
443} 459}
444 460
461void __init exynos_set_timer_source(u8 channels)
462{
463 exynos4_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
464 exynos4_pwm_variant.output_mask &= ~channels;
465}
466
445void __init exynos_init_time(void) 467void __init exynos_init_time(void)
446{ 468{
469 unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
470 EXYNOS4_IRQ_TIMER0_VIC, EXYNOS4_IRQ_TIMER1_VIC,
471 EXYNOS4_IRQ_TIMER2_VIC, EXYNOS4_IRQ_TIMER3_VIC,
472 EXYNOS4_IRQ_TIMER4_VIC,
473 };
474
447 if (of_have_populated_dt()) { 475 if (of_have_populated_dt()) {
448#ifdef CONFIG_OF 476#ifdef CONFIG_OF
449 of_clk_init(NULL); 477 of_clk_init(NULL);
@@ -455,7 +483,14 @@ void __init exynos_init_time(void)
455 exynos4_clk_init(NULL, !soc_is_exynos4210(), S5P_VA_CMU, readl(S5P_VA_CHIPID + 8) & 1); 483 exynos4_clk_init(NULL, !soc_is_exynos4210(), S5P_VA_CMU, readl(S5P_VA_CHIPID + 8) & 1);
456 exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f); 484 exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
457#endif 485#endif
458 mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0, EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1); 486#ifdef CONFIG_CLKSRC_SAMSUNG_PWM
487 if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
488 samsung_pwm_clocksource_init(S3C_VA_TIMER,
489 timer_irqs, &exynos4_pwm_variant);
490 else
491#endif
492 mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0,
493 EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1);
459 } 494 }
460} 495}
461 496