diff options
Diffstat (limited to 'arch/arm/plat-samsung')
-rw-r--r-- | arch/arm/plat-samsung/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/plat-samsung/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/common-smdk.h | 15 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/cpu.h | 4 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/irq.h | 116 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/s3c2410.h | 31 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/s3c2412.h | 32 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/s3c2416.h | 37 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/s3c2443.h | 36 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/s3c244x.h | 42 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/s5p-time.h | 40 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/samsung-time.h | 53 | ||||
-rw-r--r-- | arch/arm/plat-samsung/samsung-time.c (renamed from arch/arm/plat-samsung/s5p-time.c) | 138 | ||||
-rw-r--r-- | arch/arm/plat-samsung/time.c | 287 |
14 files changed, 124 insertions, 712 deletions
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index a9d52167e16e..b708b3e56d27 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig | |||
@@ -70,7 +70,7 @@ config S3C_LOWLEVEL_UART_PORT | |||
70 | 70 | ||
71 | # timer options | 71 | # timer options |
72 | 72 | ||
73 | config S5P_HRT | 73 | config SAMSUNG_HRT |
74 | bool | 74 | bool |
75 | select SAMSUNG_DEV_PWM | 75 | select SAMSUNG_DEV_PWM |
76 | help | 76 | help |
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 3a7c64d1814a..a23c460299a1 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile | |||
@@ -12,8 +12,7 @@ obj- := | |||
12 | # Objects we always build independent of SoC choice | 12 | # Objects we always build independent of SoC choice |
13 | 13 | ||
14 | obj-y += init.o cpu.o | 14 | obj-y += init.o cpu.o |
15 | obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o | 15 | obj-$(CONFIG_SAMSUNG_HRT) += samsung-time.o |
16 | obj-$(CONFIG_S5P_HRT) += s5p-time.o | ||
17 | 16 | ||
18 | obj-$(CONFIG_SAMSUNG_CLOCK) += clock.o | 17 | obj-$(CONFIG_SAMSUNG_CLOCK) += clock.o |
19 | obj-$(CONFIG_SAMSUNG_CLOCK) += pwm-clock.o | 18 | obj-$(CONFIG_SAMSUNG_CLOCK) += pwm-clock.o |
diff --git a/arch/arm/plat-samsung/include/plat/common-smdk.h b/arch/arm/plat-samsung/include/plat/common-smdk.h deleted file mode 100644 index ba028f1ed30b..000000000000 --- a/arch/arm/plat-samsung/include/plat/common-smdk.h +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/common-smdk.h | ||
2 | * | ||
3 | * Copyright (c) 2006 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Common code for SMDK2410 and SMDK2440 boards | ||
7 | * | ||
8 | * http://www.fluff.org/ben/smdk2440/ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | extern void smdk_machine_init(void); | ||
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 37703ef6dfc7..e126644cadf4 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h | |||
@@ -192,10 +192,6 @@ extern void s3c24xx_init_uartdevs(char *name, | |||
192 | struct s3c24xx_uart_resources *res, | 192 | struct s3c24xx_uart_resources *res, |
193 | struct s3c2410_uartcfg *cfg, int no); | 193 | struct s3c2410_uartcfg *cfg, int no); |
194 | 194 | ||
195 | /* timer for 2410/2440 */ | ||
196 | |||
197 | extern void s3c24xx_timer_init(void); | ||
198 | |||
199 | extern struct syscore_ops s3c2410_pm_syscore_ops; | 195 | extern struct syscore_ops s3c2410_pm_syscore_ops; |
200 | extern struct syscore_ops s3c2412_pm_syscore_ops; | 196 | extern struct syscore_ops s3c2412_pm_syscore_ops; |
201 | extern struct syscore_ops s3c2416_pm_syscore_ops; | 197 | extern struct syscore_ops s3c2416_pm_syscore_ops; |
diff --git a/arch/arm/plat-samsung/include/plat/irq.h b/arch/arm/plat-samsung/include/plat/irq.h deleted file mode 100644 index e21a89bc26c9..000000000000 --- a/arch/arm/plat-samsung/include/plat/irq.h +++ /dev/null | |||
@@ -1,116 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/irq.h | ||
2 | * | ||
3 | * Copyright (c) 2004-2005 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Header file for S3C24XX CPU IRQ support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/io.h> | ||
14 | |||
15 | #include <mach/hardware.h> | ||
16 | #include <mach/regs-irq.h> | ||
17 | #include <mach/regs-gpio.h> | ||
18 | |||
19 | #define irqdbf(x...) | ||
20 | #define irqdbf2(x...) | ||
21 | |||
22 | #define EXTINT_OFF (IRQ_EINT4 - 4) | ||
23 | |||
24 | /* these are exported for arch/arm/mach-* usage */ | ||
25 | extern struct irq_chip s3c_irq_level_chip; | ||
26 | extern struct irq_chip s3c_irq_chip; | ||
27 | |||
28 | static inline void s3c_irqsub_mask(unsigned int irqno, | ||
29 | unsigned int parentbit, | ||
30 | int subcheck) | ||
31 | { | ||
32 | unsigned long mask; | ||
33 | unsigned long submask; | ||
34 | |||
35 | submask = __raw_readl(S3C2410_INTSUBMSK); | ||
36 | mask = __raw_readl(S3C2410_INTMSK); | ||
37 | |||
38 | submask |= (1UL << (irqno - IRQ_S3CUART_RX0)); | ||
39 | |||
40 | /* check to see if we need to mask the parent IRQ */ | ||
41 | |||
42 | if ((submask & subcheck) == subcheck) | ||
43 | __raw_writel(mask | parentbit, S3C2410_INTMSK); | ||
44 | |||
45 | /* write back masks */ | ||
46 | __raw_writel(submask, S3C2410_INTSUBMSK); | ||
47 | |||
48 | } | ||
49 | |||
50 | static inline void s3c_irqsub_unmask(unsigned int irqno, | ||
51 | unsigned int parentbit) | ||
52 | { | ||
53 | unsigned long mask; | ||
54 | unsigned long submask; | ||
55 | |||
56 | submask = __raw_readl(S3C2410_INTSUBMSK); | ||
57 | mask = __raw_readl(S3C2410_INTMSK); | ||
58 | |||
59 | submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0)); | ||
60 | mask &= ~parentbit; | ||
61 | |||
62 | /* write back masks */ | ||
63 | __raw_writel(submask, S3C2410_INTSUBMSK); | ||
64 | __raw_writel(mask, S3C2410_INTMSK); | ||
65 | } | ||
66 | |||
67 | |||
68 | static inline void s3c_irqsub_maskack(unsigned int irqno, | ||
69 | unsigned int parentmask, | ||
70 | unsigned int group) | ||
71 | { | ||
72 | unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); | ||
73 | |||
74 | s3c_irqsub_mask(irqno, parentmask, group); | ||
75 | |||
76 | __raw_writel(bit, S3C2410_SUBSRCPND); | ||
77 | |||
78 | /* only ack parent if we've got all the irqs (seems we must | ||
79 | * ack, all and hope that the irq system retriggers ok when | ||
80 | * the interrupt goes off again) | ||
81 | */ | ||
82 | |||
83 | if (1) { | ||
84 | __raw_writel(parentmask, S3C2410_SRCPND); | ||
85 | __raw_writel(parentmask, S3C2410_INTPND); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | static inline void s3c_irqsub_ack(unsigned int irqno, | ||
90 | unsigned int parentmask, | ||
91 | unsigned int group) | ||
92 | { | ||
93 | unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); | ||
94 | |||
95 | __raw_writel(bit, S3C2410_SUBSRCPND); | ||
96 | |||
97 | /* only ack parent if we've got all the irqs (seems we must | ||
98 | * ack, all and hope that the irq system retriggers ok when | ||
99 | * the interrupt goes off again) | ||
100 | */ | ||
101 | |||
102 | if (1) { | ||
103 | __raw_writel(parentmask, S3C2410_SRCPND); | ||
104 | __raw_writel(parentmask, S3C2410_INTPND); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | /* exported for use in arch/arm/mach-s3c2410 */ | ||
109 | |||
110 | #ifdef CONFIG_PM | ||
111 | extern int s3c_irq_wake(struct irq_data *data, unsigned int state); | ||
112 | #else | ||
113 | #define s3c_irq_wake NULL | ||
114 | #endif | ||
115 | |||
116 | extern int s3c_irqext_type(struct irq_data *d, unsigned int type); | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c2410.h b/arch/arm/plat-samsung/include/plat/s3c2410.h deleted file mode 100644 index 55b0e5f51e97..000000000000 --- a/arch/arm/plat-samsung/include/plat/s3c2410.h +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/s3c2410.h | ||
2 | * | ||
3 | * Copyright (c) 2004 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Header file for s3c2410 machine directory | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifdef CONFIG_CPU_S3C2410 | ||
15 | |||
16 | extern int s3c2410_init(void); | ||
17 | extern int s3c2410a_init(void); | ||
18 | |||
19 | extern void s3c2410_map_io(void); | ||
20 | |||
21 | extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no); | ||
22 | |||
23 | extern void s3c2410_init_clocks(int xtal); | ||
24 | |||
25 | #else | ||
26 | #define s3c2410_init_clocks NULL | ||
27 | #define s3c2410_init_uarts NULL | ||
28 | #define s3c2410_map_io NULL | ||
29 | #define s3c2410_init NULL | ||
30 | #define s3c2410a_init NULL | ||
31 | #endif | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c2412.h b/arch/arm/plat-samsung/include/plat/s3c2412.h deleted file mode 100644 index cbae50ddacc8..000000000000 --- a/arch/arm/plat-samsung/include/plat/s3c2412.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/s3c2412.h | ||
2 | * | ||
3 | * Copyright (c) 2006 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Header file for s3c2412 cpu support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifdef CONFIG_CPU_S3C2412 | ||
14 | |||
15 | extern int s3c2412_init(void); | ||
16 | |||
17 | extern void s3c2412_map_io(void); | ||
18 | |||
19 | extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no); | ||
20 | |||
21 | extern void s3c2412_init_clocks(int xtal); | ||
22 | |||
23 | extern int s3c2412_baseclk_add(void); | ||
24 | |||
25 | extern void s3c2412_restart(char mode, const char *cmd); | ||
26 | #else | ||
27 | #define s3c2412_init_clocks NULL | ||
28 | #define s3c2412_init_uarts NULL | ||
29 | #define s3c2412_map_io NULL | ||
30 | #define s3c2412_init NULL | ||
31 | #define s3c2412_restart NULL | ||
32 | #endif | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h deleted file mode 100644 index f27399a3c68d..000000000000 --- a/arch/arm/plat-samsung/include/plat/s3c2416.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/s3c2416.h | ||
2 | * | ||
3 | * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com> | ||
4 | * | ||
5 | * Header file for s3c2416 cpu support | ||
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 | #ifdef CONFIG_CPU_S3C2416 | ||
13 | |||
14 | struct s3c2410_uartcfg; | ||
15 | |||
16 | extern int s3c2416_init(void); | ||
17 | |||
18 | extern void s3c2416_map_io(void); | ||
19 | |||
20 | extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no); | ||
21 | |||
22 | extern void s3c2416_init_clocks(int xtal); | ||
23 | |||
24 | extern int s3c2416_baseclk_add(void); | ||
25 | |||
26 | extern void s3c2416_restart(char mode, const char *cmd); | ||
27 | |||
28 | extern void s3c2416_init_irq(void); | ||
29 | extern struct syscore_ops s3c2416_irq_syscore_ops; | ||
30 | |||
31 | #else | ||
32 | #define s3c2416_init_clocks NULL | ||
33 | #define s3c2416_init_uarts NULL | ||
34 | #define s3c2416_map_io NULL | ||
35 | #define s3c2416_init NULL | ||
36 | #define s3c2416_restart NULL | ||
37 | #endif | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h deleted file mode 100644 index 71b88ec48956..000000000000 --- a/arch/arm/plat-samsung/include/plat/s3c2443.h +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/s3c2443.h | ||
2 | * | ||
3 | * Copyright (c) 2004-2005 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Header file for s3c2443 cpu support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifdef CONFIG_CPU_S3C2443 | ||
14 | |||
15 | struct s3c2410_uartcfg; | ||
16 | |||
17 | extern int s3c2443_init(void); | ||
18 | |||
19 | extern void s3c2443_map_io(void); | ||
20 | |||
21 | extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no); | ||
22 | |||
23 | extern void s3c2443_init_clocks(int xtal); | ||
24 | |||
25 | extern int s3c2443_baseclk_add(void); | ||
26 | |||
27 | extern void s3c2443_restart(char mode, const char *cmd); | ||
28 | |||
29 | extern void s3c2443_init_irq(void); | ||
30 | #else | ||
31 | #define s3c2443_init_clocks NULL | ||
32 | #define s3c2443_init_uarts NULL | ||
33 | #define s3c2443_map_io NULL | ||
34 | #define s3c2443_init NULL | ||
35 | #define s3c2443_restart NULL | ||
36 | #endif | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c244x.h b/arch/arm/plat-samsung/include/plat/s3c244x.h deleted file mode 100644 index ea0c961b7603..000000000000 --- a/arch/arm/plat-samsung/include/plat/s3c244x.h +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/s3c244x.h | ||
2 | * | ||
3 | * Copyright (c) 2004-2005 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Header file for S3C2440 and S3C2442 cpu support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) | ||
14 | |||
15 | extern void s3c244x_map_io(void); | ||
16 | |||
17 | extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no); | ||
18 | |||
19 | extern void s3c244x_init_clocks(int xtal); | ||
20 | |||
21 | #else | ||
22 | #define s3c244x_init_clocks NULL | ||
23 | #define s3c244x_init_uarts NULL | ||
24 | #endif | ||
25 | |||
26 | #ifdef CONFIG_CPU_S3C2440 | ||
27 | extern int s3c2440_init(void); | ||
28 | |||
29 | extern void s3c2440_map_io(void); | ||
30 | #else | ||
31 | #define s3c2440_init NULL | ||
32 | #define s3c2440_map_io NULL | ||
33 | #endif | ||
34 | |||
35 | #ifdef CONFIG_CPU_S3C2442 | ||
36 | extern int s3c2442_init(void); | ||
37 | |||
38 | extern void s3c2442_map_io(void); | ||
39 | #else | ||
40 | #define s3c2442_init NULL | ||
41 | #define s3c2442_map_io NULL | ||
42 | #endif | ||
diff --git a/arch/arm/plat-samsung/include/plat/s5p-time.h b/arch/arm/plat-samsung/include/plat/s5p-time.h deleted file mode 100644 index 9c96f3586ce0..000000000000 --- a/arch/arm/plat-samsung/include/plat/s5p-time.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/s5p-time.h | ||
2 | * | ||
3 | * Copyright 2011 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * Header file for s5p time support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_PLAT_S5P_TIME_H | ||
14 | #define __ASM_PLAT_S5P_TIME_H __FILE__ | ||
15 | |||
16 | /* S5P HR-Timer Clock mode */ | ||
17 | enum s5p_timer_mode { | ||
18 | S5P_PWM0, | ||
19 | S5P_PWM1, | ||
20 | S5P_PWM2, | ||
21 | S5P_PWM3, | ||
22 | S5P_PWM4, | ||
23 | }; | ||
24 | |||
25 | struct s5p_timer_source { | ||
26 | unsigned int event_id; | ||
27 | unsigned int source_id; | ||
28 | }; | ||
29 | |||
30 | /* Be able to sleep for atleast 4 seconds (usually more) */ | ||
31 | #define S5PTIMER_MIN_RANGE 4 | ||
32 | |||
33 | #define TCNT_MAX 0xffffffff | ||
34 | #define NON_PERIODIC 0 | ||
35 | #define PERIODIC 1 | ||
36 | |||
37 | extern void __init s5p_set_timer_source(enum s5p_timer_mode event, | ||
38 | enum s5p_timer_mode source); | ||
39 | extern void s5p_timer_init(void); | ||
40 | #endif /* __ASM_PLAT_S5P_TIME_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h new file mode 100644 index 000000000000..4cc99bb1f176 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/samsung-time.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/samsung-time.h | ||
2 | * | ||
3 | * Copyright 2011 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * Header file for samsung s3c and s5p time support | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_PLAT_SAMSUNG_TIME_H | ||
14 | #define __ASM_PLAT_SAMSUNG_TIME_H __FILE__ | ||
15 | |||
16 | /* SAMSUNG HR-Timer Clock mode */ | ||
17 | enum samsung_timer_mode { | ||
18 | SAMSUNG_PWM0, | ||
19 | SAMSUNG_PWM1, | ||
20 | SAMSUNG_PWM2, | ||
21 | SAMSUNG_PWM3, | ||
22 | SAMSUNG_PWM4, | ||
23 | }; | ||
24 | |||
25 | struct samsung_timer_source { | ||
26 | unsigned int event_id; | ||
27 | unsigned int source_id; | ||
28 | }; | ||
29 | |||
30 | /* Be able to sleep for atleast 4 seconds (usually more) */ | ||
31 | #define SAMSUNG_TIMER_MIN_RANGE 4 | ||
32 | |||
33 | #if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S5PC100) | ||
34 | #define TCNT_MAX 0xffff | ||
35 | #define TSCALER_DIV 25 | ||
36 | #define TDIV 50 | ||
37 | #define TSIZE 16 | ||
38 | #else | ||
39 | #define TCNT_MAX 0xffffffff | ||
40 | #define TSCALER_DIV 2 | ||
41 | #define TDIV 2 | ||
42 | #define TSIZE 32 | ||
43 | #endif | ||
44 | |||
45 | #define NON_PERIODIC 0 | ||
46 | #define PERIODIC 1 | ||
47 | |||
48 | extern void __init samsung_set_timer_source(enum samsung_timer_mode event, | ||
49 | enum samsung_timer_mode source); | ||
50 | |||
51 | extern void __init samsung_timer_init(void); | ||
52 | |||
53 | #endif /* __ASM_PLAT_SAMSUNG_TIME_H */ | ||
diff --git a/arch/arm/plat-samsung/s5p-time.c b/arch/arm/plat-samsung/samsung-time.c index e92510cf82ee..f899cbc9b288 100644 --- a/arch/arm/plat-samsung/s5p-time.c +++ b/arch/arm/plat-samsung/samsung-time.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | 2 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. |
3 | * http://www.samsung.com/ | 3 | * http://www.samsung.com/ |
4 | * | 4 | * |
5 | * S5P - Common hr-timer support | 5 | * samsung - Common hr-timer support (s3c and s5p) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 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 | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -25,41 +25,41 @@ | |||
25 | #include <mach/map.h> | 25 | #include <mach/map.h> |
26 | #include <plat/devs.h> | 26 | #include <plat/devs.h> |
27 | #include <plat/regs-timer.h> | 27 | #include <plat/regs-timer.h> |
28 | #include <plat/s5p-time.h> | 28 | #include <plat/samsung-time.h> |
29 | 29 | ||
30 | static struct clk *tin_event; | 30 | static struct clk *tin_event; |
31 | static struct clk *tin_source; | 31 | static struct clk *tin_source; |
32 | static struct clk *tdiv_event; | 32 | static struct clk *tdiv_event; |
33 | static struct clk *tdiv_source; | 33 | static struct clk *tdiv_source; |
34 | static struct clk *timerclk; | 34 | static struct clk *timerclk; |
35 | static struct s5p_timer_source timer_source; | 35 | static struct samsung_timer_source timer_source; |
36 | static unsigned long clock_count_per_tick; | 36 | static unsigned long clock_count_per_tick; |
37 | static void s5p_timer_resume(void); | 37 | static void samsung_timer_resume(void); |
38 | 38 | ||
39 | static void s5p_time_stop(enum s5p_timer_mode mode) | 39 | static void samsung_time_stop(enum samsung_timer_mode mode) |
40 | { | 40 | { |
41 | unsigned long tcon; | 41 | unsigned long tcon; |
42 | 42 | ||
43 | tcon = __raw_readl(S3C2410_TCON); | 43 | tcon = __raw_readl(S3C2410_TCON); |
44 | 44 | ||
45 | switch (mode) { | 45 | switch (mode) { |
46 | case S5P_PWM0: | 46 | case SAMSUNG_PWM0: |
47 | tcon &= ~S3C2410_TCON_T0START; | 47 | tcon &= ~S3C2410_TCON_T0START; |
48 | break; | 48 | break; |
49 | 49 | ||
50 | case S5P_PWM1: | 50 | case SAMSUNG_PWM1: |
51 | tcon &= ~S3C2410_TCON_T1START; | 51 | tcon &= ~S3C2410_TCON_T1START; |
52 | break; | 52 | break; |
53 | 53 | ||
54 | case S5P_PWM2: | 54 | case SAMSUNG_PWM2: |
55 | tcon &= ~S3C2410_TCON_T2START; | 55 | tcon &= ~S3C2410_TCON_T2START; |
56 | break; | 56 | break; |
57 | 57 | ||
58 | case S5P_PWM3: | 58 | case SAMSUNG_PWM3: |
59 | tcon &= ~S3C2410_TCON_T3START; | 59 | tcon &= ~S3C2410_TCON_T3START; |
60 | break; | 60 | break; |
61 | 61 | ||
62 | case S5P_PWM4: | 62 | case SAMSUNG_PWM4: |
63 | tcon &= ~S3C2410_TCON_T4START; | 63 | tcon &= ~S3C2410_TCON_T4START; |
64 | break; | 64 | break; |
65 | 65 | ||
@@ -70,7 +70,7 @@ static void s5p_time_stop(enum s5p_timer_mode mode) | |||
70 | __raw_writel(tcon, S3C2410_TCON); | 70 | __raw_writel(tcon, S3C2410_TCON); |
71 | } | 71 | } |
72 | 72 | ||
73 | static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) | 73 | static void samsung_time_setup(enum samsung_timer_mode mode, unsigned long tcnt) |
74 | { | 74 | { |
75 | unsigned long tcon; | 75 | unsigned long tcon; |
76 | 76 | ||
@@ -79,27 +79,27 @@ static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) | |||
79 | tcnt--; | 79 | tcnt--; |
80 | 80 | ||
81 | switch (mode) { | 81 | switch (mode) { |
82 | case S5P_PWM0: | 82 | case SAMSUNG_PWM0: |
83 | tcon &= ~(0x0f << 0); | 83 | tcon &= ~(0x0f << 0); |
84 | tcon |= S3C2410_TCON_T0MANUALUPD; | 84 | tcon |= S3C2410_TCON_T0MANUALUPD; |
85 | break; | 85 | break; |
86 | 86 | ||
87 | case S5P_PWM1: | 87 | case SAMSUNG_PWM1: |
88 | tcon &= ~(0x0f << 8); | 88 | tcon &= ~(0x0f << 8); |
89 | tcon |= S3C2410_TCON_T1MANUALUPD; | 89 | tcon |= S3C2410_TCON_T1MANUALUPD; |
90 | break; | 90 | break; |
91 | 91 | ||
92 | case S5P_PWM2: | 92 | case SAMSUNG_PWM2: |
93 | tcon &= ~(0x0f << 12); | 93 | tcon &= ~(0x0f << 12); |
94 | tcon |= S3C2410_TCON_T2MANUALUPD; | 94 | tcon |= S3C2410_TCON_T2MANUALUPD; |
95 | break; | 95 | break; |
96 | 96 | ||
97 | case S5P_PWM3: | 97 | case SAMSUNG_PWM3: |
98 | tcon &= ~(0x0f << 16); | 98 | tcon &= ~(0x0f << 16); |
99 | tcon |= S3C2410_TCON_T3MANUALUPD; | 99 | tcon |= S3C2410_TCON_T3MANUALUPD; |
100 | break; | 100 | break; |
101 | 101 | ||
102 | case S5P_PWM4: | 102 | case SAMSUNG_PWM4: |
103 | tcon &= ~(0x07 << 20); | 103 | tcon &= ~(0x07 << 20); |
104 | tcon |= S3C2410_TCON_T4MANUALUPD; | 104 | tcon |= S3C2410_TCON_T4MANUALUPD; |
105 | break; | 105 | break; |
@@ -114,14 +114,14 @@ static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) | |||
114 | __raw_writel(tcon, S3C2410_TCON); | 114 | __raw_writel(tcon, S3C2410_TCON); |
115 | } | 115 | } |
116 | 116 | ||
117 | static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) | 117 | static void samsung_time_start(enum samsung_timer_mode mode, bool periodic) |
118 | { | 118 | { |
119 | unsigned long tcon; | 119 | unsigned long tcon; |
120 | 120 | ||
121 | tcon = __raw_readl(S3C2410_TCON); | 121 | tcon = __raw_readl(S3C2410_TCON); |
122 | 122 | ||
123 | switch (mode) { | 123 | switch (mode) { |
124 | case S5P_PWM0: | 124 | case SAMSUNG_PWM0: |
125 | tcon |= S3C2410_TCON_T0START; | 125 | tcon |= S3C2410_TCON_T0START; |
126 | tcon &= ~S3C2410_TCON_T0MANUALUPD; | 126 | tcon &= ~S3C2410_TCON_T0MANUALUPD; |
127 | 127 | ||
@@ -131,7 +131,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) | |||
131 | tcon &= ~S3C2410_TCON_T0RELOAD; | 131 | tcon &= ~S3C2410_TCON_T0RELOAD; |
132 | break; | 132 | break; |
133 | 133 | ||
134 | case S5P_PWM1: | 134 | case SAMSUNG_PWM1: |
135 | tcon |= S3C2410_TCON_T1START; | 135 | tcon |= S3C2410_TCON_T1START; |
136 | tcon &= ~S3C2410_TCON_T1MANUALUPD; | 136 | tcon &= ~S3C2410_TCON_T1MANUALUPD; |
137 | 137 | ||
@@ -141,7 +141,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) | |||
141 | tcon &= ~S3C2410_TCON_T1RELOAD; | 141 | tcon &= ~S3C2410_TCON_T1RELOAD; |
142 | break; | 142 | break; |
143 | 143 | ||
144 | case S5P_PWM2: | 144 | case SAMSUNG_PWM2: |
145 | tcon |= S3C2410_TCON_T2START; | 145 | tcon |= S3C2410_TCON_T2START; |
146 | tcon &= ~S3C2410_TCON_T2MANUALUPD; | 146 | tcon &= ~S3C2410_TCON_T2MANUALUPD; |
147 | 147 | ||
@@ -151,7 +151,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) | |||
151 | tcon &= ~S3C2410_TCON_T2RELOAD; | 151 | tcon &= ~S3C2410_TCON_T2RELOAD; |
152 | break; | 152 | break; |
153 | 153 | ||
154 | case S5P_PWM3: | 154 | case SAMSUNG_PWM3: |
155 | tcon |= S3C2410_TCON_T3START; | 155 | tcon |= S3C2410_TCON_T3START; |
156 | tcon &= ~S3C2410_TCON_T3MANUALUPD; | 156 | tcon &= ~S3C2410_TCON_T3MANUALUPD; |
157 | 157 | ||
@@ -161,7 +161,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) | |||
161 | tcon &= ~S3C2410_TCON_T3RELOAD; | 161 | tcon &= ~S3C2410_TCON_T3RELOAD; |
162 | break; | 162 | break; |
163 | 163 | ||
164 | case S5P_PWM4: | 164 | case SAMSUNG_PWM4: |
165 | tcon |= S3C2410_TCON_T4START; | 165 | tcon |= S3C2410_TCON_T4START; |
166 | tcon &= ~S3C2410_TCON_T4MANUALUPD; | 166 | tcon &= ~S3C2410_TCON_T4MANUALUPD; |
167 | 167 | ||
@@ -178,24 +178,24 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) | |||
178 | __raw_writel(tcon, S3C2410_TCON); | 178 | __raw_writel(tcon, S3C2410_TCON); |
179 | } | 179 | } |
180 | 180 | ||
181 | static int s5p_set_next_event(unsigned long cycles, | 181 | static int samsung_set_next_event(unsigned long cycles, |
182 | struct clock_event_device *evt) | 182 | struct clock_event_device *evt) |
183 | { | 183 | { |
184 | s5p_time_setup(timer_source.event_id, cycles); | 184 | samsung_time_setup(timer_source.event_id, cycles); |
185 | s5p_time_start(timer_source.event_id, NON_PERIODIC); | 185 | samsung_time_start(timer_source.event_id, NON_PERIODIC); |
186 | 186 | ||
187 | return 0; | 187 | return 0; |
188 | } | 188 | } |
189 | 189 | ||
190 | static void s5p_set_mode(enum clock_event_mode mode, | 190 | static void samsung_set_mode(enum clock_event_mode mode, |
191 | struct clock_event_device *evt) | 191 | struct clock_event_device *evt) |
192 | { | 192 | { |
193 | s5p_time_stop(timer_source.event_id); | 193 | samsung_time_stop(timer_source.event_id); |
194 | 194 | ||
195 | switch (mode) { | 195 | switch (mode) { |
196 | case CLOCK_EVT_MODE_PERIODIC: | 196 | case CLOCK_EVT_MODE_PERIODIC: |
197 | s5p_time_setup(timer_source.event_id, clock_count_per_tick); | 197 | samsung_time_setup(timer_source.event_id, clock_count_per_tick); |
198 | s5p_time_start(timer_source.event_id, PERIODIC); | 198 | samsung_time_start(timer_source.event_id, PERIODIC); |
199 | break; | 199 | break; |
200 | 200 | ||
201 | case CLOCK_EVT_MODE_ONESHOT: | 201 | case CLOCK_EVT_MODE_ONESHOT: |
@@ -206,24 +206,24 @@ static void s5p_set_mode(enum clock_event_mode mode, | |||
206 | break; | 206 | break; |
207 | 207 | ||
208 | case CLOCK_EVT_MODE_RESUME: | 208 | case CLOCK_EVT_MODE_RESUME: |
209 | s5p_timer_resume(); | 209 | samsung_timer_resume(); |
210 | break; | 210 | break; |
211 | } | 211 | } |
212 | } | 212 | } |
213 | 213 | ||
214 | static void s5p_timer_resume(void) | 214 | static void samsung_timer_resume(void) |
215 | { | 215 | { |
216 | /* event timer restart */ | 216 | /* event timer restart */ |
217 | s5p_time_setup(timer_source.event_id, clock_count_per_tick); | 217 | samsung_time_setup(timer_source.event_id, clock_count_per_tick); |
218 | s5p_time_start(timer_source.event_id, PERIODIC); | 218 | samsung_time_start(timer_source.event_id, PERIODIC); |
219 | 219 | ||
220 | /* source timer restart */ | 220 | /* source timer restart */ |
221 | s5p_time_setup(timer_source.source_id, TCNT_MAX); | 221 | samsung_time_setup(timer_source.source_id, TCNT_MAX); |
222 | s5p_time_start(timer_source.source_id, PERIODIC); | 222 | samsung_time_start(timer_source.source_id, PERIODIC); |
223 | } | 223 | } |
224 | 224 | ||
225 | void __init s5p_set_timer_source(enum s5p_timer_mode event, | 225 | void __init samsung_set_timer_source(enum samsung_timer_mode event, |
226 | enum s5p_timer_mode source) | 226 | enum samsung_timer_mode source) |
227 | { | 227 | { |
228 | s3c_device_timer[event].dev.bus = &platform_bus_type; | 228 | s3c_device_timer[event].dev.bus = &platform_bus_type; |
229 | s3c_device_timer[source].dev.bus = &platform_bus_type; | 229 | s3c_device_timer[source].dev.bus = &platform_bus_type; |
@@ -233,14 +233,14 @@ void __init s5p_set_timer_source(enum s5p_timer_mode event, | |||
233 | } | 233 | } |
234 | 234 | ||
235 | static struct clock_event_device time_event_device = { | 235 | static struct clock_event_device time_event_device = { |
236 | .name = "s5p_event_timer", | 236 | .name = "samsung_event_timer", |
237 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 237 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
238 | .rating = 200, | 238 | .rating = 200, |
239 | .set_next_event = s5p_set_next_event, | 239 | .set_next_event = samsung_set_next_event, |
240 | .set_mode = s5p_set_mode, | 240 | .set_mode = samsung_set_mode, |
241 | }; | 241 | }; |
242 | 242 | ||
243 | static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id) | 243 | static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id) |
244 | { | 244 | { |
245 | struct clock_event_device *evt = dev_id; | 245 | struct clock_event_device *evt = dev_id; |
246 | 246 | ||
@@ -249,14 +249,14 @@ static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id) | |||
249 | return IRQ_HANDLED; | 249 | return IRQ_HANDLED; |
250 | } | 250 | } |
251 | 251 | ||
252 | static struct irqaction s5p_clock_event_irq = { | 252 | static struct irqaction samsung_clock_event_irq = { |
253 | .name = "s5p_time_irq", | 253 | .name = "samsung_time_irq", |
254 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 254 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
255 | .handler = s5p_clock_event_isr, | 255 | .handler = samsung_clock_event_isr, |
256 | .dev_id = &time_event_device, | 256 | .dev_id = &time_event_device, |
257 | }; | 257 | }; |
258 | 258 | ||
259 | static void __init s5p_clockevent_init(void) | 259 | static void __init samsung_clockevent_init(void) |
260 | { | 260 | { |
261 | unsigned long pclk; | 261 | unsigned long pclk; |
262 | unsigned long clock_rate; | 262 | unsigned long clock_rate; |
@@ -267,8 +267,8 @@ static void __init s5p_clockevent_init(void) | |||
267 | 267 | ||
268 | tscaler = clk_get_parent(tdiv_event); | 268 | tscaler = clk_get_parent(tdiv_event); |
269 | 269 | ||
270 | clk_set_rate(tscaler, pclk / 2); | 270 | clk_set_rate(tscaler, pclk / TSCALER_DIV); |
271 | clk_set_rate(tdiv_event, pclk / 2); | 271 | clk_set_rate(tdiv_event, pclk / TDIV); |
272 | clk_set_parent(tin_event, tdiv_event); | 272 | clk_set_parent(tin_event, tdiv_event); |
273 | 273 | ||
274 | clock_rate = clk_get_rate(tin_event); | 274 | clock_rate = clk_get_rate(tin_event); |
@@ -278,22 +278,22 @@ static void __init s5p_clockevent_init(void) | |||
278 | clockevents_config_and_register(&time_event_device, clock_rate, 1, -1); | 278 | clockevents_config_and_register(&time_event_device, clock_rate, 1, -1); |
279 | 279 | ||
280 | irq_number = timer_source.event_id + IRQ_TIMER0; | 280 | irq_number = timer_source.event_id + IRQ_TIMER0; |
281 | setup_irq(irq_number, &s5p_clock_event_irq); | 281 | setup_irq(irq_number, &samsung_clock_event_irq); |
282 | } | 282 | } |
283 | 283 | ||
284 | static void __iomem *s5p_timer_reg(void) | 284 | static void __iomem *samsung_timer_reg(void) |
285 | { | 285 | { |
286 | unsigned long offset = 0; | 286 | unsigned long offset = 0; |
287 | 287 | ||
288 | switch (timer_source.source_id) { | 288 | switch (timer_source.source_id) { |
289 | case S5P_PWM0: | 289 | case SAMSUNG_PWM0: |
290 | case S5P_PWM1: | 290 | case SAMSUNG_PWM1: |
291 | case S5P_PWM2: | 291 | case SAMSUNG_PWM2: |
292 | case S5P_PWM3: | 292 | case SAMSUNG_PWM3: |
293 | offset = (timer_source.source_id * 0x0c) + 0x14; | 293 | offset = (timer_source.source_id * 0x0c) + 0x14; |
294 | break; | 294 | break; |
295 | 295 | ||
296 | case S5P_PWM4: | 296 | case SAMSUNG_PWM4: |
297 | offset = 0x40; | 297 | offset = 0x40; |
298 | break; | 298 | break; |
299 | 299 | ||
@@ -312,9 +312,9 @@ static void __iomem *s5p_timer_reg(void) | |||
312 | * this wraps around for now, since it is just a relative time | 312 | * this wraps around for now, since it is just a relative time |
313 | * stamp. (Inspired by U300 implementation.) | 313 | * stamp. (Inspired by U300 implementation.) |
314 | */ | 314 | */ |
315 | static u32 notrace s5p_read_sched_clock(void) | 315 | static u32 notrace samsung_read_sched_clock(void) |
316 | { | 316 | { |
317 | void __iomem *reg = s5p_timer_reg(); | 317 | void __iomem *reg = samsung_timer_reg(); |
318 | 318 | ||
319 | if (!reg) | 319 | if (!reg) |
320 | return 0; | 320 | return 0; |
@@ -322,29 +322,29 @@ static u32 notrace s5p_read_sched_clock(void) | |||
322 | return ~__raw_readl(reg); | 322 | return ~__raw_readl(reg); |
323 | } | 323 | } |
324 | 324 | ||
325 | static void __init s5p_clocksource_init(void) | 325 | static void __init samsung_clocksource_init(void) |
326 | { | 326 | { |
327 | unsigned long pclk; | 327 | unsigned long pclk; |
328 | unsigned long clock_rate; | 328 | unsigned long clock_rate; |
329 | 329 | ||
330 | pclk = clk_get_rate(timerclk); | 330 | pclk = clk_get_rate(timerclk); |
331 | 331 | ||
332 | clk_set_rate(tdiv_source, pclk / 2); | 332 | clk_set_rate(tdiv_source, pclk / TDIV); |
333 | clk_set_parent(tin_source, tdiv_source); | 333 | clk_set_parent(tin_source, tdiv_source); |
334 | 334 | ||
335 | clock_rate = clk_get_rate(tin_source); | 335 | clock_rate = clk_get_rate(tin_source); |
336 | 336 | ||
337 | s5p_time_setup(timer_source.source_id, TCNT_MAX); | 337 | samsung_time_setup(timer_source.source_id, TCNT_MAX); |
338 | s5p_time_start(timer_source.source_id, PERIODIC); | 338 | samsung_time_start(timer_source.source_id, PERIODIC); |
339 | 339 | ||
340 | setup_sched_clock(s5p_read_sched_clock, 32, clock_rate); | 340 | setup_sched_clock(samsung_read_sched_clock, TSIZE, clock_rate); |
341 | 341 | ||
342 | if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer", | 342 | if (clocksource_mmio_init(samsung_timer_reg(), "samsung_clocksource_timer", |
343 | clock_rate, 250, 32, clocksource_mmio_readl_down)) | 343 | clock_rate, 250, TSIZE, clocksource_mmio_readl_down)) |
344 | panic("s5p_clocksource_timer: can't register clocksource\n"); | 344 | panic("samsung_clocksource_timer: can't register clocksource\n"); |
345 | } | 345 | } |
346 | 346 | ||
347 | static void __init s5p_timer_resources(void) | 347 | static void __init samsung_timer_resources(void) |
348 | { | 348 | { |
349 | 349 | ||
350 | unsigned long event_id = timer_source.event_id; | 350 | unsigned long event_id = timer_source.event_id; |
@@ -386,9 +386,9 @@ static void __init s5p_timer_resources(void) | |||
386 | clk_enable(tin_source); | 386 | clk_enable(tin_source); |
387 | } | 387 | } |
388 | 388 | ||
389 | void __init s5p_timer_init(void) | 389 | void __init samsung_timer_init(void) |
390 | { | 390 | { |
391 | s5p_timer_resources(); | 391 | samsung_timer_resources(); |
392 | s5p_clockevent_init(); | 392 | samsung_clockevent_init(); |
393 | s5p_clocksource_init(); | 393 | samsung_clocksource_init(); |
394 | } | 394 | } |
diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c deleted file mode 100644 index 73defd00c3e4..000000000000 --- a/arch/arm/plat-samsung/time.c +++ /dev/null | |||
@@ -1,287 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/time.c | ||
2 | * | ||
3 | * Copyright (C) 2003-2005 Simtec Electronics | ||
4 | * Ben Dooks, <ben@simtec.co.uk> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/clk.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/syscore_ops.h> | ||
31 | |||
32 | #include <asm/mach-types.h> | ||
33 | |||
34 | #include <asm/irq.h> | ||
35 | #include <mach/map.h> | ||
36 | #include <plat/regs-timer.h> | ||
37 | #include <mach/regs-irq.h> | ||
38 | #include <asm/mach/time.h> | ||
39 | #include <mach/tick.h> | ||
40 | |||
41 | #include <plat/clock.h> | ||
42 | #include <plat/cpu.h> | ||
43 | |||
44 | static unsigned long timer_startval; | ||
45 | static unsigned long timer_usec_ticks; | ||
46 | |||
47 | #ifndef TICK_MAX | ||
48 | #define TICK_MAX (0xffff) | ||
49 | #endif | ||
50 | |||
51 | #define TIMER_USEC_SHIFT 16 | ||
52 | |||
53 | /* we use the shifted arithmetic to work out the ratio of timer ticks | ||
54 | * to usecs, as often the peripheral clock is not a nice even multiple | ||
55 | * of 1MHz. | ||
56 | * | ||
57 | * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok | ||
58 | * for the current HZ value of 200 without producing overflows. | ||
59 | * | ||
60 | * Original patch by Dimitry Andric, updated by Ben Dooks | ||
61 | */ | ||
62 | |||
63 | |||
64 | /* timer_mask_usec_ticks | ||
65 | * | ||
66 | * given a clock and divisor, make the value to pass into timer_ticks_to_usec | ||
67 | * to scale the ticks into usecs | ||
68 | */ | ||
69 | |||
70 | static inline unsigned long | ||
71 | timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk) | ||
72 | { | ||
73 | unsigned long den = pclk / 1000; | ||
74 | |||
75 | return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den; | ||
76 | } | ||
77 | |||
78 | /* timer_ticks_to_usec | ||
79 | * | ||
80 | * convert timer ticks to usec. | ||
81 | */ | ||
82 | |||
83 | static inline unsigned long timer_ticks_to_usec(unsigned long ticks) | ||
84 | { | ||
85 | unsigned long res; | ||
86 | |||
87 | res = ticks * timer_usec_ticks; | ||
88 | res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */ | ||
89 | |||
90 | return res >> TIMER_USEC_SHIFT; | ||
91 | } | ||
92 | |||
93 | /*** | ||
94 | * Returns microsecond since last clock interrupt. Note that interrupts | ||
95 | * will have been disabled by do_gettimeoffset() | ||
96 | * IRQs are disabled before entering here from do_gettimeofday() | ||
97 | */ | ||
98 | |||
99 | static u32 s3c2410_gettimeoffset(void) | ||
100 | { | ||
101 | unsigned long tdone; | ||
102 | unsigned long tval; | ||
103 | |||
104 | /* work out how many ticks have gone since last timer interrupt */ | ||
105 | |||
106 | tval = __raw_readl(S3C2410_TCNTO(4)); | ||
107 | tdone = timer_startval - tval; | ||
108 | |||
109 | /* check to see if there is an interrupt pending */ | ||
110 | |||
111 | if (s3c24xx_ostimer_pending()) { | ||
112 | /* re-read the timer, and try and fix up for the missed | ||
113 | * interrupt. Note, the interrupt may go off before the | ||
114 | * timer has re-loaded from wrapping. | ||
115 | */ | ||
116 | |||
117 | tval = __raw_readl(S3C2410_TCNTO(4)); | ||
118 | tdone = timer_startval - tval; | ||
119 | |||
120 | if (tval != 0) | ||
121 | tdone += timer_startval; | ||
122 | } | ||
123 | |||
124 | return timer_ticks_to_usec(tdone) * 1000; | ||
125 | } | ||
126 | |||
127 | |||
128 | /* | ||
129 | * IRQ handler for the timer | ||
130 | */ | ||
131 | static irqreturn_t | ||
132 | s3c2410_timer_interrupt(int irq, void *dev_id) | ||
133 | { | ||
134 | timer_tick(); | ||
135 | return IRQ_HANDLED; | ||
136 | } | ||
137 | |||
138 | static struct irqaction s3c2410_timer_irq = { | ||
139 | .name = "S3C2410 Timer Tick", | ||
140 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | ||
141 | .handler = s3c2410_timer_interrupt, | ||
142 | }; | ||
143 | |||
144 | #define use_tclk1_12() ( \ | ||
145 | machine_is_bast() || \ | ||
146 | machine_is_vr1000() || \ | ||
147 | machine_is_anubis() || \ | ||
148 | machine_is_osiris()) | ||
149 | |||
150 | static struct clk *tin; | ||
151 | static struct clk *tdiv; | ||
152 | static struct clk *timerclk; | ||
153 | |||
154 | /* | ||
155 | * Set up timer interrupt, and return the current time in seconds. | ||
156 | * | ||
157 | * Currently we only use timer4, as it is the only timer which has no | ||
158 | * other function that can be exploited externally | ||
159 | */ | ||
160 | static void s3c2410_timer_setup (void) | ||
161 | { | ||
162 | unsigned long tcon; | ||
163 | unsigned long tcnt; | ||
164 | unsigned long tcfg1; | ||
165 | unsigned long tcfg0; | ||
166 | |||
167 | tcnt = TICK_MAX; /* default value for tcnt */ | ||
168 | |||
169 | /* configure the system for whichever machine is in use */ | ||
170 | |||
171 | if (use_tclk1_12()) { | ||
172 | /* timer is at 12MHz, scaler is 1 */ | ||
173 | timer_usec_ticks = timer_mask_usec_ticks(1, 12000000); | ||
174 | tcnt = 12000000 / HZ; | ||
175 | |||
176 | tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
177 | tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; | ||
178 | tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1; | ||
179 | __raw_writel(tcfg1, S3C2410_TCFG1); | ||
180 | } else { | ||
181 | unsigned long pclk; | ||
182 | struct clk *tscaler; | ||
183 | |||
184 | /* for the h1940 (and others), we use the pclk from the core | ||
185 | * to generate the timer values. since values around 50 to | ||
186 | * 70MHz are not values we can directly generate the timer | ||
187 | * value from, we need to pre-scale and divide before using it. | ||
188 | * | ||
189 | * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz | ||
190 | * (8.45 ticks per usec) | ||
191 | */ | ||
192 | |||
193 | pclk = clk_get_rate(timerclk); | ||
194 | |||
195 | /* configure clock tick */ | ||
196 | |||
197 | timer_usec_ticks = timer_mask_usec_ticks(6, pclk); | ||
198 | |||
199 | tscaler = clk_get_parent(tdiv); | ||
200 | |||
201 | clk_set_rate(tscaler, pclk / 3); | ||
202 | clk_set_rate(tdiv, pclk / 6); | ||
203 | clk_set_parent(tin, tdiv); | ||
204 | |||
205 | tcnt = clk_get_rate(tin) / HZ; | ||
206 | } | ||
207 | |||
208 | tcon = __raw_readl(S3C2410_TCON); | ||
209 | tcfg0 = __raw_readl(S3C2410_TCFG0); | ||
210 | tcfg1 = __raw_readl(S3C2410_TCFG1); | ||
211 | |||
212 | /* timers reload after counting zero, so reduce the count by 1 */ | ||
213 | |||
214 | tcnt--; | ||
215 | |||
216 | printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n", | ||
217 | tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks); | ||
218 | |||
219 | /* check to see if timer is within 16bit range... */ | ||
220 | if (tcnt > TICK_MAX) { | ||
221 | panic("setup_timer: HZ is too small, cannot configure timer!"); | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | __raw_writel(tcfg1, S3C2410_TCFG1); | ||
226 | __raw_writel(tcfg0, S3C2410_TCFG0); | ||
227 | |||
228 | timer_startval = tcnt; | ||
229 | __raw_writel(tcnt, S3C2410_TCNTB(4)); | ||
230 | |||
231 | /* ensure timer is stopped... */ | ||
232 | |||
233 | tcon &= ~(7<<20); | ||
234 | tcon |= S3C2410_TCON_T4RELOAD; | ||
235 | tcon |= S3C2410_TCON_T4MANUALUPD; | ||
236 | |||
237 | __raw_writel(tcon, S3C2410_TCON); | ||
238 | __raw_writel(tcnt, S3C2410_TCNTB(4)); | ||
239 | __raw_writel(tcnt, S3C2410_TCMPB(4)); | ||
240 | |||
241 | /* start the timer running */ | ||
242 | tcon |= S3C2410_TCON_T4START; | ||
243 | tcon &= ~S3C2410_TCON_T4MANUALUPD; | ||
244 | __raw_writel(tcon, S3C2410_TCON); | ||
245 | } | ||
246 | |||
247 | static void __init s3c2410_timer_resources(void) | ||
248 | { | ||
249 | struct platform_device tmpdev; | ||
250 | |||
251 | tmpdev.dev.bus = &platform_bus_type; | ||
252 | tmpdev.id = 4; | ||
253 | |||
254 | timerclk = clk_get(NULL, "timers"); | ||
255 | if (IS_ERR(timerclk)) | ||
256 | panic("failed to get clock for system timer"); | ||
257 | |||
258 | clk_enable(timerclk); | ||
259 | |||
260 | if (!use_tclk1_12()) { | ||
261 | tmpdev.id = 4; | ||
262 | tmpdev.dev.init_name = "s3c24xx-pwm.4"; | ||
263 | tin = clk_get(&tmpdev.dev, "pwm-tin"); | ||
264 | if (IS_ERR(tin)) | ||
265 | panic("failed to get pwm-tin clock for system timer"); | ||
266 | |||
267 | tdiv = clk_get(&tmpdev.dev, "pwm-tdiv"); | ||
268 | if (IS_ERR(tdiv)) | ||
269 | panic("failed to get pwm-tdiv clock for system timer"); | ||
270 | } | ||
271 | |||
272 | clk_enable(tin); | ||
273 | } | ||
274 | |||
275 | static struct syscore_ops s3c24xx_syscore_ops = { | ||
276 | .resume = s3c2410_timer_setup, | ||
277 | }; | ||
278 | |||
279 | void __init s3c24xx_timer_init(void) | ||
280 | { | ||
281 | arch_gettimeoffset = s3c2410_gettimeoffset; | ||
282 | |||
283 | s3c2410_timer_resources(); | ||
284 | s3c2410_timer_setup(); | ||
285 | setup_irq(IRQ_TIMER4, &s3c2410_timer_irq); | ||
286 | register_syscore_ops(&s3c24xx_syscore_ops); | ||
287 | } | ||