aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 14:00:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 14:00:07 -0400
commit1ead65812486cda65093683a99b8907a7242fa93 (patch)
tree094684870815537aae4aedb69c10d669ba29f0af /arch/arm
parentb6d739e9581272f0bbbd6edd15340fb8e108df96 (diff)
parentb97f0291a2504291aef850077f98cab68a5a2f33 (diff)
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer changes from Thomas Gleixner: "This assorted collection provides: - A new timer based timer broadcast feature for systems which do not provide a global accessible timer device. That allows those systems to put CPUs into deep idle states where the per cpu timer device stops. - A few NOHZ_FULL related improvements to the timer wheel - The usual updates to timer devices found in ARM SoCs - Small improvements and updates all over the place" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits) tick: Remove code duplication in tick_handle_periodic() tick: Fix spelling mistake in tick_handle_periodic() x86: hpet: Use proper destructor for delayed work workqueue: Provide destroy_delayed_work_on_stack() clocksource: CMT, MTU2, TMU and STI should depend on GENERIC_CLOCKEVENTS timer: Remove code redundancy while calling get_nohz_timer_target() hrtimer: Rearrange comments in the order struct members are declared timer: Use variable head instead of &work_list in __run_timers() clocksource: exynos_mct: silence a static checker warning arm: zynq: Add support for cpufreq arm: zynq: Don't use arm_global_timer with cpufreq clocksource/cadence_ttc: Overhaul clocksource frequency adjustment clocksource/cadence_ttc: Call clockevents_update_freq() with IRQs enabled clocksource: Add Kconfig entries for CMT, MTU2, TMU and STI sh: Remove Kconfig entries for TMU, CMT and MTU2 ARM: shmobile: Remove CMT, TMU and STI Kconfig entries clocksource: armada-370-xp: Use atomic access for shared registers clocksource: orion: Use atomic access for shared registers clocksource: timer-keystone: Delete unnecessary variable clocksource: timer-keystone: introduce clocksource driver for Keystone ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/boot/dts/sun4i-a10.dtsi2
-rw-r--r--arch/arm/boot/dts/sun5i-a10s.dtsi2
-rw-r--r--arch/arm/boot/dts/sun5i-a13.dtsi2
-rw-r--r--arch/arm/boot/dts/sun6i-a31.dtsi2
-rw-r--r--arch/arm/boot/dts/sun7i-a20.dtsi2
-rw-r--r--arch/arm/boot/dts/zynq-7000.dtsi6
-rw-r--r--arch/arm/mach-shmobile/Kconfig36
-rw-r--r--arch/arm/mach-u300/Makefile2
-rw-r--r--arch/arm/mach-u300/timer.c451
-rw-r--r--arch/arm/mach-zynq/Kconfig4
-rw-r--r--arch/arm/mach-zynq/common.c3
11 files changed, 36 insertions, 476 deletions
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index d4d2763f4794..2ce61228d5f9 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -403,7 +403,7 @@
403 }; 403 };
404 404
405 timer@01c20c00 { 405 timer@01c20c00 {
406 compatible = "allwinner,sun4i-timer"; 406 compatible = "allwinner,sun4i-a10-timer";
407 reg = <0x01c20c00 0x90>; 407 reg = <0x01c20c00 0x90>;
408 interrupts = <22>; 408 interrupts = <22>;
409 clocks = <&osc24M>; 409 clocks = <&osc24M>;
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 79fd412005b0..29dd32d8e77e 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -366,7 +366,7 @@
366 }; 366 };
367 367
368 timer@01c20c00 { 368 timer@01c20c00 {
369 compatible = "allwinner,sun4i-timer"; 369 compatible = "allwinner,sun4i-a10-timer";
370 reg = <0x01c20c00 0x90>; 370 reg = <0x01c20c00 0x90>;
371 interrupts = <22>; 371 interrupts = <22>;
372 clocks = <&osc24M>; 372 clocks = <&osc24M>;
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index c463fd730c91..e63bb383b43d 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -329,7 +329,7 @@
329 }; 329 };
330 330
331 timer@01c20c00 { 331 timer@01c20c00 {
332 compatible = "allwinner,sun4i-timer"; 332 compatible = "allwinner,sun4i-a10-timer";
333 reg = <0x01c20c00 0x90>; 333 reg = <0x01c20c00 0x90>;
334 interrupts = <22>; 334 interrupts = <22>;
335 clocks = <&osc24M>; 335 clocks = <&osc24M>;
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 5256ad9be52c..996fff54c8a2 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -231,7 +231,7 @@
231 }; 231 };
232 232
233 timer@01c20c00 { 233 timer@01c20c00 {
234 compatible = "allwinner,sun4i-timer"; 234 compatible = "allwinner,sun4i-a10-timer";
235 reg = <0x01c20c00 0xa0>; 235 reg = <0x01c20c00 0xa0>;
236 interrupts = <0 18 4>, 236 interrupts = <0 18 4>,
237 <0 19 4>, 237 <0 19 4>,
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 6f25cf559ad0..dddc8ac2d522 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -435,7 +435,7 @@
435 }; 435 };
436 436
437 timer@01c20c00 { 437 timer@01c20c00 {
438 compatible = "allwinner,sun4i-timer"; 438 compatible = "allwinner,sun4i-a10-timer";
439 reg = <0x01c20c00 0x90>; 439 reg = <0x01c20c00 0x90>;
440 interrupts = <0 22 4>, 440 interrupts = <0 22 4>,
441 <0 23 4>, 441 <0 23 4>,
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index 8b67b19392ec..789d0bacc110 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -24,6 +24,12 @@
24 device_type = "cpu"; 24 device_type = "cpu";
25 reg = <0>; 25 reg = <0>;
26 clocks = <&clkc 3>; 26 clocks = <&clkc 3>;
27 operating-points = <
28 /* kHz uV */
29 666667 1000000
30 333334 1000000
31 222223 1000000
32 >;
27 }; 33 };
28 34
29 cpu@1 { 35 cpu@1 {
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 05fa505df585..f6db7dcae3f4 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -24,17 +24,21 @@ comment "Renesas ARM SoCs System Type"
24 24
25config ARCH_EMEV2 25config ARCH_EMEV2
26 bool "Emma Mobile EV2" 26 bool "Emma Mobile EV2"
27 select SYS_SUPPORTS_EM_STI
27 28
28config ARCH_R7S72100 29config ARCH_R7S72100
29 bool "RZ/A1H (R7S72100)" 30 bool "RZ/A1H (R7S72100)"
31 select SYS_SUPPORTS_SH_MTU2
30 32
31config ARCH_R8A7790 33config ARCH_R8A7790
32 bool "R-Car H2 (R8A77900)" 34 bool "R-Car H2 (R8A77900)"
33 select RENESAS_IRQC 35 select RENESAS_IRQC
36 select SYS_SUPPORTS_SH_CMT
34 37
35config ARCH_R8A7791 38config ARCH_R8A7791
36 bool "R-Car M2 (R8A77910)" 39 bool "R-Car M2 (R8A77910)"
37 select RENESAS_IRQC 40 select RENESAS_IRQC
41 select SYS_SUPPORTS_SH_CMT
38 42
39comment "Renesas ARM SoCs Board Type" 43comment "Renesas ARM SoCs Board Type"
40 44
@@ -68,6 +72,8 @@ config ARCH_SH7372
68 select ARM_CPU_SUSPEND if PM || CPU_IDLE 72 select ARM_CPU_SUSPEND if PM || CPU_IDLE
69 select CPU_V7 73 select CPU_V7
70 select SH_CLK_CPG 74 select SH_CLK_CPG
75 select SYS_SUPPORTS_SH_CMT
76 select SYS_SUPPORTS_SH_TMU
71 77
72config ARCH_SH73A0 78config ARCH_SH73A0
73 bool "SH-Mobile AG5 (R8A73A00)" 79 bool "SH-Mobile AG5 (R8A73A00)"
@@ -77,6 +83,8 @@ config ARCH_SH73A0
77 select I2C 83 select I2C
78 select SH_CLK_CPG 84 select SH_CLK_CPG
79 select RENESAS_INTC_IRQPIN 85 select RENESAS_INTC_IRQPIN
86 select SYS_SUPPORTS_SH_CMT
87 select SYS_SUPPORTS_SH_TMU
80 88
81config ARCH_R8A73A4 89config ARCH_R8A73A4
82 bool "R-Mobile APE6 (R8A73A40)" 90 bool "R-Mobile APE6 (R8A73A40)"
@@ -87,6 +95,8 @@ config ARCH_R8A73A4
87 select RENESAS_IRQC 95 select RENESAS_IRQC
88 select ARCH_HAS_CPUFREQ 96 select ARCH_HAS_CPUFREQ
89 select ARCH_HAS_OPP 97 select ARCH_HAS_OPP
98 select SYS_SUPPORTS_SH_CMT
99 select SYS_SUPPORTS_SH_TMU
90 100
91config ARCH_R8A7740 101config ARCH_R8A7740
92 bool "R-Mobile A1 (R8A77400)" 102 bool "R-Mobile A1 (R8A77400)"
@@ -95,6 +105,8 @@ config ARCH_R8A7740
95 select CPU_V7 105 select CPU_V7
96 select SH_CLK_CPG 106 select SH_CLK_CPG
97 select RENESAS_INTC_IRQPIN 107 select RENESAS_INTC_IRQPIN
108 select SYS_SUPPORTS_SH_CMT
109 select SYS_SUPPORTS_SH_TMU
98 110
99config ARCH_R8A7778 111config ARCH_R8A7778
100 bool "R-Car M1A (R8A77781)" 112 bool "R-Car M1A (R8A77781)"
@@ -104,6 +116,7 @@ config ARCH_R8A7778
104 select ARM_GIC 116 select ARM_GIC
105 select USB_ARCH_HAS_EHCI 117 select USB_ARCH_HAS_EHCI
106 select USB_ARCH_HAS_OHCI 118 select USB_ARCH_HAS_OHCI
119 select SYS_SUPPORTS_SH_TMU
107 120
108config ARCH_R8A7779 121config ARCH_R8A7779
109 bool "R-Car H1 (R8A77790)" 122 bool "R-Car H1 (R8A77790)"
@@ -114,6 +127,7 @@ config ARCH_R8A7779
114 select USB_ARCH_HAS_EHCI 127 select USB_ARCH_HAS_EHCI
115 select USB_ARCH_HAS_OHCI 128 select USB_ARCH_HAS_OHCI
116 select RENESAS_INTC_IRQPIN 129 select RENESAS_INTC_IRQPIN
130 select SYS_SUPPORTS_SH_TMU
117 131
118config ARCH_R8A7790 132config ARCH_R8A7790
119 bool "R-Car H2 (R8A77900)" 133 bool "R-Car H2 (R8A77900)"
@@ -123,6 +137,7 @@ config ARCH_R8A7790
123 select MIGHT_HAVE_PCI 137 select MIGHT_HAVE_PCI
124 select SH_CLK_CPG 138 select SH_CLK_CPG
125 select RENESAS_IRQC 139 select RENESAS_IRQC
140 select SYS_SUPPORTS_SH_CMT
126 141
127config ARCH_R8A7791 142config ARCH_R8A7791
128 bool "R-Car M2 (R8A77910)" 143 bool "R-Car M2 (R8A77910)"
@@ -132,6 +147,7 @@ config ARCH_R8A7791
132 select MIGHT_HAVE_PCI 147 select MIGHT_HAVE_PCI
133 select SH_CLK_CPG 148 select SH_CLK_CPG
134 select RENESAS_IRQC 149 select RENESAS_IRQC
150 select SYS_SUPPORTS_SH_CMT
135 151
136config ARCH_EMEV2 152config ARCH_EMEV2
137 bool "Emma Mobile EV2" 153 bool "Emma Mobile EV2"
@@ -141,6 +157,7 @@ config ARCH_EMEV2
141 select MIGHT_HAVE_PCI 157 select MIGHT_HAVE_PCI
142 select USE_OF 158 select USE_OF
143 select AUTO_ZRELADDR 159 select AUTO_ZRELADDR
160 select SYS_SUPPORTS_EM_STI
144 161
145config ARCH_R7S72100 162config ARCH_R7S72100
146 bool "RZ/A1H (R7S72100)" 163 bool "RZ/A1H (R7S72100)"
@@ -148,6 +165,7 @@ config ARCH_R7S72100
148 select ARM_GIC 165 select ARM_GIC
149 select CPU_V7 166 select CPU_V7
150 select SH_CLK_CPG 167 select SH_CLK_CPG
168 select SYS_SUPPORTS_SH_MTU2
151 169
152comment "Renesas ARM SoCs Board Type" 170comment "Renesas ARM SoCs Board Type"
153 171
@@ -321,24 +339,6 @@ config SHMOBILE_TIMER_HZ
321 want to select a HZ value such as 128 that can evenly divide RCLK. 339 want to select a HZ value such as 128 that can evenly divide RCLK.
322 A HZ value that does not divide evenly may cause timer drift. 340 A HZ value that does not divide evenly may cause timer drift.
323 341
324config SH_TIMER_CMT
325 bool "CMT timer driver"
326 default y
327 help
328 This enables build of the CMT timer driver.
329
330config SH_TIMER_TMU
331 bool "TMU timer driver"
332 default y
333 help
334 This enables build of the TMU timer driver.
335
336config EM_TIMER_STI
337 bool "STI timer driver"
338 default y
339 help
340 This enables build of the STI timer driver.
341
342endmenu 342endmenu
343 343
344endif 344endif
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile
index 0f362b64fb87..3ec74ac95bc1 100644
--- a/arch/arm/mach-u300/Makefile
+++ b/arch/arm/mach-u300/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the linux kernel, U300 machine. 2# Makefile for the linux kernel, U300 machine.
3# 3#
4 4
5obj-y := core.o timer.o 5obj-y := core.o
6obj-m := 6obj-m :=
7obj-n := 7obj-n :=
8obj- := 8obj- :=
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
deleted file mode 100644
index fe08fd34c0ce..000000000000
--- a/arch/arm/mach-u300/timer.c
+++ /dev/null
@@ -1,451 +0,0 @@
1/*
2 *
3 * arch/arm/mach-u300/timer.c
4 *
5 *
6 * Copyright (C) 2007-2009 ST-Ericsson AB
7 * License terms: GNU General Public License (GPL) version 2
8 * Timer COH 901 328, runs the OS timer interrupt.
9 * Author: Linus Walleij <linus.walleij@stericsson.com>
10 */
11#include <linux/interrupt.h>
12#include <linux/time.h>
13#include <linux/timex.h>
14#include <linux/clockchips.h>
15#include <linux/clocksource.h>
16#include <linux/types.h>
17#include <linux/io.h>
18#include <linux/clk.h>
19#include <linux/err.h>
20#include <linux/irq.h>
21#include <linux/delay.h>
22#include <linux/of_address.h>
23#include <linux/of_irq.h>
24#include <linux/sched_clock.h>
25
26/* Generic stuff */
27#include <asm/mach/map.h>
28#include <asm/mach/time.h>
29
30/*
31 * APP side special timer registers
32 * This timer contains four timers which can fire an interrupt each.
33 * OS (operating system) timer @ 32768 Hz
34 * DD (device driver) timer @ 1 kHz
35 * GP1 (general purpose 1) timer @ 1MHz
36 * GP2 (general purpose 2) timer @ 1MHz
37 */
38
39/* Reset OS Timer 32bit (-/W) */
40#define U300_TIMER_APP_ROST (0x0000)
41#define U300_TIMER_APP_ROST_TIMER_RESET (0x00000000)
42/* Enable OS Timer 32bit (-/W) */
43#define U300_TIMER_APP_EOST (0x0004)
44#define U300_TIMER_APP_EOST_TIMER_ENABLE (0x00000000)
45/* Disable OS Timer 32bit (-/W) */
46#define U300_TIMER_APP_DOST (0x0008)
47#define U300_TIMER_APP_DOST_TIMER_DISABLE (0x00000000)
48/* OS Timer Mode Register 32bit (-/W) */
49#define U300_TIMER_APP_SOSTM (0x000c)
50#define U300_TIMER_APP_SOSTM_MODE_CONTINUOUS (0x00000000)
51#define U300_TIMER_APP_SOSTM_MODE_ONE_SHOT (0x00000001)
52/* OS Timer Status Register 32bit (R/-) */
53#define U300_TIMER_APP_OSTS (0x0010)
54#define U300_TIMER_APP_OSTS_TIMER_STATE_MASK (0x0000000F)
55#define U300_TIMER_APP_OSTS_TIMER_STATE_IDLE (0x00000001)
56#define U300_TIMER_APP_OSTS_TIMER_STATE_ACTIVE (0x00000002)
57#define U300_TIMER_APP_OSTS_ENABLE_IND (0x00000010)
58#define U300_TIMER_APP_OSTS_MODE_MASK (0x00000020)
59#define U300_TIMER_APP_OSTS_MODE_CONTINUOUS (0x00000000)
60#define U300_TIMER_APP_OSTS_MODE_ONE_SHOT (0x00000020)
61#define U300_TIMER_APP_OSTS_IRQ_ENABLED_IND (0x00000040)
62#define U300_TIMER_APP_OSTS_IRQ_PENDING_IND (0x00000080)
63/* OS Timer Current Count Register 32bit (R/-) */
64#define U300_TIMER_APP_OSTCC (0x0014)
65/* OS Timer Terminal Count Register 32bit (R/W) */
66#define U300_TIMER_APP_OSTTC (0x0018)
67/* OS Timer Interrupt Enable Register 32bit (-/W) */
68#define U300_TIMER_APP_OSTIE (0x001c)
69#define U300_TIMER_APP_OSTIE_IRQ_DISABLE (0x00000000)
70#define U300_TIMER_APP_OSTIE_IRQ_ENABLE (0x00000001)
71/* OS Timer Interrupt Acknowledge Register 32bit (-/W) */
72#define U300_TIMER_APP_OSTIA (0x0020)
73#define U300_TIMER_APP_OSTIA_IRQ_ACK (0x00000080)
74
75/* Reset DD Timer 32bit (-/W) */
76#define U300_TIMER_APP_RDDT (0x0040)
77#define U300_TIMER_APP_RDDT_TIMER_RESET (0x00000000)
78/* Enable DD Timer 32bit (-/W) */
79#define U300_TIMER_APP_EDDT (0x0044)
80#define U300_TIMER_APP_EDDT_TIMER_ENABLE (0x00000000)
81/* Disable DD Timer 32bit (-/W) */
82#define U300_TIMER_APP_DDDT (0x0048)
83#define U300_TIMER_APP_DDDT_TIMER_DISABLE (0x00000000)
84/* DD Timer Mode Register 32bit (-/W) */
85#define U300_TIMER_APP_SDDTM (0x004c)
86#define U300_TIMER_APP_SDDTM_MODE_CONTINUOUS (0x00000000)
87#define U300_TIMER_APP_SDDTM_MODE_ONE_SHOT (0x00000001)
88/* DD Timer Status Register 32bit (R/-) */
89#define U300_TIMER_APP_DDTS (0x0050)
90#define U300_TIMER_APP_DDTS_TIMER_STATE_MASK (0x0000000F)
91#define U300_TIMER_APP_DDTS_TIMER_STATE_IDLE (0x00000001)
92#define U300_TIMER_APP_DDTS_TIMER_STATE_ACTIVE (0x00000002)
93#define U300_TIMER_APP_DDTS_ENABLE_IND (0x00000010)
94#define U300_TIMER_APP_DDTS_MODE_MASK (0x00000020)
95#define U300_TIMER_APP_DDTS_MODE_CONTINUOUS (0x00000000)
96#define U300_TIMER_APP_DDTS_MODE_ONE_SHOT (0x00000020)
97#define U300_TIMER_APP_DDTS_IRQ_ENABLED_IND (0x00000040)
98#define U300_TIMER_APP_DDTS_IRQ_PENDING_IND (0x00000080)
99/* DD Timer Current Count Register 32bit (R/-) */
100#define U300_TIMER_APP_DDTCC (0x0054)
101/* DD Timer Terminal Count Register 32bit (R/W) */
102#define U300_TIMER_APP_DDTTC (0x0058)
103/* DD Timer Interrupt Enable Register 32bit (-/W) */
104#define U300_TIMER_APP_DDTIE (0x005c)
105#define U300_TIMER_APP_DDTIE_IRQ_DISABLE (0x00000000)
106#define U300_TIMER_APP_DDTIE_IRQ_ENABLE (0x00000001)
107/* DD Timer Interrupt Acknowledge Register 32bit (-/W) */
108#define U300_TIMER_APP_DDTIA (0x0060)
109#define U300_TIMER_APP_DDTIA_IRQ_ACK (0x00000080)
110
111/* Reset GP1 Timer 32bit (-/W) */
112#define U300_TIMER_APP_RGPT1 (0x0080)
113#define U300_TIMER_APP_RGPT1_TIMER_RESET (0x00000000)
114/* Enable GP1 Timer 32bit (-/W) */
115#define U300_TIMER_APP_EGPT1 (0x0084)
116#define U300_TIMER_APP_EGPT1_TIMER_ENABLE (0x00000000)
117/* Disable GP1 Timer 32bit (-/W) */
118#define U300_TIMER_APP_DGPT1 (0x0088)
119#define U300_TIMER_APP_DGPT1_TIMER_DISABLE (0x00000000)
120/* GP1 Timer Mode Register 32bit (-/W) */
121#define U300_TIMER_APP_SGPT1M (0x008c)
122#define U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS (0x00000000)
123#define U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT (0x00000001)
124/* GP1 Timer Status Register 32bit (R/-) */
125#define U300_TIMER_APP_GPT1S (0x0090)
126#define U300_TIMER_APP_GPT1S_TIMER_STATE_MASK (0x0000000F)
127#define U300_TIMER_APP_GPT1S_TIMER_STATE_IDLE (0x00000001)
128#define U300_TIMER_APP_GPT1S_TIMER_STATE_ACTIVE (0x00000002)
129#define U300_TIMER_APP_GPT1S_ENABLE_IND (0x00000010)
130#define U300_TIMER_APP_GPT1S_MODE_MASK (0x00000020)
131#define U300_TIMER_APP_GPT1S_MODE_CONTINUOUS (0x00000000)
132#define U300_TIMER_APP_GPT1S_MODE_ONE_SHOT (0x00000020)
133#define U300_TIMER_APP_GPT1S_IRQ_ENABLED_IND (0x00000040)
134#define U300_TIMER_APP_GPT1S_IRQ_PENDING_IND (0x00000080)
135/* GP1 Timer Current Count Register 32bit (R/-) */
136#define U300_TIMER_APP_GPT1CC (0x0094)
137/* GP1 Timer Terminal Count Register 32bit (R/W) */
138#define U300_TIMER_APP_GPT1TC (0x0098)
139/* GP1 Timer Interrupt Enable Register 32bit (-/W) */
140#define U300_TIMER_APP_GPT1IE (0x009c)
141#define U300_TIMER_APP_GPT1IE_IRQ_DISABLE (0x00000000)
142#define U300_TIMER_APP_GPT1IE_IRQ_ENABLE (0x00000001)
143/* GP1 Timer Interrupt Acknowledge Register 32bit (-/W) */
144#define U300_TIMER_APP_GPT1IA (0x00a0)
145#define U300_TIMER_APP_GPT1IA_IRQ_ACK (0x00000080)
146
147/* Reset GP2 Timer 32bit (-/W) */
148#define U300_TIMER_APP_RGPT2 (0x00c0)
149#define U300_TIMER_APP_RGPT2_TIMER_RESET (0x00000000)
150/* Enable GP2 Timer 32bit (-/W) */
151#define U300_TIMER_APP_EGPT2 (0x00c4)
152#define U300_TIMER_APP_EGPT2_TIMER_ENABLE (0x00000000)
153/* Disable GP2 Timer 32bit (-/W) */
154#define U300_TIMER_APP_DGPT2 (0x00c8)
155#define U300_TIMER_APP_DGPT2_TIMER_DISABLE (0x00000000)
156/* GP2 Timer Mode Register 32bit (-/W) */
157#define U300_TIMER_APP_SGPT2M (0x00cc)
158#define U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS (0x00000000)
159#define U300_TIMER_APP_SGPT2M_MODE_ONE_SHOT (0x00000001)
160/* GP2 Timer Status Register 32bit (R/-) */
161#define U300_TIMER_APP_GPT2S (0x00d0)
162#define U300_TIMER_APP_GPT2S_TIMER_STATE_MASK (0x0000000F)
163#define U300_TIMER_APP_GPT2S_TIMER_STATE_IDLE (0x00000001)
164#define U300_TIMER_APP_GPT2S_TIMER_STATE_ACTIVE (0x00000002)
165#define U300_TIMER_APP_GPT2S_ENABLE_IND (0x00000010)
166#define U300_TIMER_APP_GPT2S_MODE_MASK (0x00000020)
167#define U300_TIMER_APP_GPT2S_MODE_CONTINUOUS (0x00000000)
168#define U300_TIMER_APP_GPT2S_MODE_ONE_SHOT (0x00000020)
169#define U300_TIMER_APP_GPT2S_IRQ_ENABLED_IND (0x00000040)
170#define U300_TIMER_APP_GPT2S_IRQ_PENDING_IND (0x00000080)
171/* GP2 Timer Current Count Register 32bit (R/-) */
172#define U300_TIMER_APP_GPT2CC (0x00d4)
173/* GP2 Timer Terminal Count Register 32bit (R/W) */
174#define U300_TIMER_APP_GPT2TC (0x00d8)
175/* GP2 Timer Interrupt Enable Register 32bit (-/W) */
176#define U300_TIMER_APP_GPT2IE (0x00dc)
177#define U300_TIMER_APP_GPT2IE_IRQ_DISABLE (0x00000000)
178#define U300_TIMER_APP_GPT2IE_IRQ_ENABLE (0x00000001)
179/* GP2 Timer Interrupt Acknowledge Register 32bit (-/W) */
180#define U300_TIMER_APP_GPT2IA (0x00e0)
181#define U300_TIMER_APP_GPT2IA_IRQ_ACK (0x00000080)
182
183/* Clock request control register - all four timers */
184#define U300_TIMER_APP_CRC (0x100)
185#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001)
186
187static void __iomem *u300_timer_base;
188
189struct u300_clockevent_data {
190 struct clock_event_device cevd;
191 unsigned ticks_per_jiffy;
192};
193
194/*
195 * The u300_set_mode() function is always called first, if we
196 * have oneshot timer active, the oneshot scheduling function
197 * u300_set_next_event() is called immediately after.
198 */
199static void u300_set_mode(enum clock_event_mode mode,
200 struct clock_event_device *evt)
201{
202 struct u300_clockevent_data *cevdata =
203 container_of(evt, struct u300_clockevent_data, cevd);
204
205 switch (mode) {
206 case CLOCK_EVT_MODE_PERIODIC:
207 /* Disable interrupts on GPT1 */
208 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
209 u300_timer_base + U300_TIMER_APP_GPT1IE);
210 /* Disable GP1 while we're reprogramming it. */
211 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
212 u300_timer_base + U300_TIMER_APP_DGPT1);
213 /*
214 * Set the periodic mode to a certain number of ticks per
215 * jiffy.
216 */
217 writel(cevdata->ticks_per_jiffy,
218 u300_timer_base + U300_TIMER_APP_GPT1TC);
219 /*
220 * Set continuous mode, so the timer keeps triggering
221 * interrupts.
222 */
223 writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS,
224 u300_timer_base + U300_TIMER_APP_SGPT1M);
225 /* Enable timer interrupts */
226 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
227 u300_timer_base + U300_TIMER_APP_GPT1IE);
228 /* Then enable the OS timer again */
229 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
230 u300_timer_base + U300_TIMER_APP_EGPT1);
231 break;
232 case CLOCK_EVT_MODE_ONESHOT:
233 /* Just break; here? */
234 /*
235 * The actual event will be programmed by the next event hook,
236 * so we just set a dummy value somewhere at the end of the
237 * universe here.
238 */
239 /* Disable interrupts on GPT1 */
240 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
241 u300_timer_base + U300_TIMER_APP_GPT1IE);
242 /* Disable GP1 while we're reprogramming it. */
243 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
244 u300_timer_base + U300_TIMER_APP_DGPT1);
245 /*
246 * Expire far in the future, u300_set_next_event() will be
247 * called soon...
248 */
249 writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC);
250 /* We run one shot per tick here! */
251 writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
252 u300_timer_base + U300_TIMER_APP_SGPT1M);
253 /* Enable interrupts for this timer */
254 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
255 u300_timer_base + U300_TIMER_APP_GPT1IE);
256 /* Enable timer */
257 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
258 u300_timer_base + U300_TIMER_APP_EGPT1);
259 break;
260 case CLOCK_EVT_MODE_UNUSED:
261 case CLOCK_EVT_MODE_SHUTDOWN:
262 /* Disable interrupts on GP1 */
263 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
264 u300_timer_base + U300_TIMER_APP_GPT1IE);
265 /* Disable GP1 */
266 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
267 u300_timer_base + U300_TIMER_APP_DGPT1);
268 break;
269 case CLOCK_EVT_MODE_RESUME:
270 /* Ignore this call */
271 break;
272 }
273}
274
275/*
276 * The app timer in one shot mode obviously has to be reprogrammed
277 * in EXACTLY this sequence to work properly. Do NOT try to e.g. replace
278 * the interrupt disable + timer disable commands with a reset command,
279 * it will fail miserably. Apparently (and I found this the hard way)
280 * the timer is very sensitive to the instruction order, though you don't
281 * get that impression from the data sheet.
282 */
283static int u300_set_next_event(unsigned long cycles,
284 struct clock_event_device *evt)
285
286{
287 /* Disable interrupts on GPT1 */
288 writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
289 u300_timer_base + U300_TIMER_APP_GPT1IE);
290 /* Disable GP1 while we're reprogramming it. */
291 writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
292 u300_timer_base + U300_TIMER_APP_DGPT1);
293 /* Reset the General Purpose timer 1. */
294 writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
295 u300_timer_base + U300_TIMER_APP_RGPT1);
296 /* IRQ in n * cycles */
297 writel(cycles, u300_timer_base + U300_TIMER_APP_GPT1TC);
298 /*
299 * We run one shot per tick here! (This is necessary to reconfigure,
300 * the timer will tilt if you don't!)
301 */
302 writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
303 u300_timer_base + U300_TIMER_APP_SGPT1M);
304 /* Enable timer interrupts */
305 writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
306 u300_timer_base + U300_TIMER_APP_GPT1IE);
307 /* Then enable the OS timer again */
308 writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
309 u300_timer_base + U300_TIMER_APP_EGPT1);
310 return 0;
311}
312
313static struct u300_clockevent_data u300_clockevent_data = {
314 /* Use general purpose timer 1 as clock event */
315 .cevd = {
316 .name = "GPT1",
317 /* Reasonably fast and accurate clock event */
318 .rating = 300,
319 .features = CLOCK_EVT_FEAT_PERIODIC |
320 CLOCK_EVT_FEAT_ONESHOT,
321 .set_next_event = u300_set_next_event,
322 .set_mode = u300_set_mode,
323 },
324};
325
326/* Clock event timer interrupt handler */
327static irqreturn_t u300_timer_interrupt(int irq, void *dev_id)
328{
329 struct clock_event_device *evt = &u300_clockevent_data.cevd;
330 /* ACK/Clear timer IRQ for the APP GPT1 Timer */
331
332 writel(U300_TIMER_APP_GPT1IA_IRQ_ACK,
333 u300_timer_base + U300_TIMER_APP_GPT1IA);
334 evt->event_handler(evt);
335 return IRQ_HANDLED;
336}
337
338static struct irqaction u300_timer_irq = {
339 .name = "U300 Timer Tick",
340 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
341 .handler = u300_timer_interrupt,
342};
343
344/*
345 * Override the global weak sched_clock symbol with this
346 * local implementation which uses the clocksource to get some
347 * better resolution when scheduling the kernel. We accept that
348 * this wraps around for now, since it is just a relative time
349 * stamp. (Inspired by OMAP implementation.)
350 */
351
352static u64 notrace u300_read_sched_clock(void)
353{
354 return readl(u300_timer_base + U300_TIMER_APP_GPT2CC);
355}
356
357static unsigned long u300_read_current_timer(void)
358{
359 return readl(u300_timer_base + U300_TIMER_APP_GPT2CC);
360}
361
362static struct delay_timer u300_delay_timer;
363
364/*
365 * This sets up the system timers, clock source and clock event.
366 */
367static void __init u300_timer_init_of(struct device_node *np)
368{
369 unsigned int irq;
370 struct clk *clk;
371 unsigned long rate;
372
373 u300_timer_base = of_iomap(np, 0);
374 if (!u300_timer_base)
375 panic("could not ioremap system timer\n");
376
377 /* Get the IRQ for the GP1 timer */
378 irq = irq_of_parse_and_map(np, 2);
379 if (!irq)
380 panic("no IRQ for system timer\n");
381
382 pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq);
383
384 /* Clock the interrupt controller */
385 clk = of_clk_get(np, 0);
386 BUG_ON(IS_ERR(clk));
387 clk_prepare_enable(clk);
388 rate = clk_get_rate(clk);
389
390 u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
391
392 sched_clock_register(u300_read_sched_clock, 32, rate);
393
394 u300_delay_timer.read_current_timer = &u300_read_current_timer;
395 u300_delay_timer.freq = rate;
396 register_current_timer_delay(&u300_delay_timer);
397
398 /*
399 * Disable the "OS" and "DD" timers - these are designed for Symbian!
400 * Example usage in cnh1601578 cpu subsystem pd_timer_app.c
401 */
402 writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE,
403 u300_timer_base + U300_TIMER_APP_CRC);
404 writel(U300_TIMER_APP_ROST_TIMER_RESET,
405 u300_timer_base + U300_TIMER_APP_ROST);
406 writel(U300_TIMER_APP_DOST_TIMER_DISABLE,
407 u300_timer_base + U300_TIMER_APP_DOST);
408 writel(U300_TIMER_APP_RDDT_TIMER_RESET,
409 u300_timer_base + U300_TIMER_APP_RDDT);
410 writel(U300_TIMER_APP_DDDT_TIMER_DISABLE,
411 u300_timer_base + U300_TIMER_APP_DDDT);
412
413 /* Reset the General Purpose timer 1. */
414 writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
415 u300_timer_base + U300_TIMER_APP_RGPT1);
416
417 /* Set up the IRQ handler */
418 setup_irq(irq, &u300_timer_irq);
419
420 /* Reset the General Purpose timer 2 */
421 writel(U300_TIMER_APP_RGPT2_TIMER_RESET,
422 u300_timer_base + U300_TIMER_APP_RGPT2);
423 /* Set this timer to run around forever */
424 writel(0xFFFFFFFFU, u300_timer_base + U300_TIMER_APP_GPT2TC);
425 /* Set continuous mode so it wraps around */
426 writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS,
427 u300_timer_base + U300_TIMER_APP_SGPT2M);
428 /* Disable timer interrupts */
429 writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE,
430 u300_timer_base + U300_TIMER_APP_GPT2IE);
431 /* Then enable the GP2 timer to use as a free running us counter */
432 writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
433 u300_timer_base + U300_TIMER_APP_EGPT2);
434
435 /* Use general purpose timer 2 as clock source */
436 if (clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC,
437 "GPT2", rate, 300, 32, clocksource_mmio_readl_up))
438 pr_err("timer: failed to initialize U300 clock source\n");
439
440 /* Configure and register the clockevent */
441 clockevents_config_and_register(&u300_clockevent_data.cevd, rate,
442 1, 0xffffffff);
443
444 /*
445 * TODO: init and register the rest of the timers too, they can be
446 * used by hrtimers!
447 */
448}
449
450CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer",
451 u300_timer_init_of);
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index 6b04260aa142..f03e75bd0b2b 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -2,6 +2,8 @@ config ARCH_ZYNQ
2 bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7 2 bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
3 select ARM_AMBA 3 select ARM_AMBA
4 select ARM_GIC 4 select ARM_GIC
5 select ARCH_HAS_CPUFREQ
6 select ARCH_HAS_OPP
5 select COMMON_CLK 7 select COMMON_CLK
6 select CPU_V7 8 select CPU_V7
7 select GENERIC_CLOCKEVENTS 9 select GENERIC_CLOCKEVENTS
@@ -13,6 +15,6 @@ config ARCH_ZYNQ
13 select HAVE_SMP 15 select HAVE_SMP
14 select SPARSE_IRQ 16 select SPARSE_IRQ
15 select CADENCE_TTC_TIMER 17 select CADENCE_TTC_TIMER
16 select ARM_GLOBAL_TIMER 18 select ARM_GLOBAL_TIMER if !CPU_FREQ
17 help 19 help
18 Support for Xilinx Zynq ARM Cortex A9 Platform 20 Support for Xilinx Zynq ARM Cortex A9 Platform
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index 8c09a8393fb6..a39be8e80856 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -64,6 +64,8 @@ static struct platform_device zynq_cpuidle_device = {
64 */ 64 */
65static void __init zynq_init_machine(void) 65static void __init zynq_init_machine(void)
66{ 66{
67 struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
68
67 /* 69 /*
68 * 64KB way size, 8-way associativity, parity disabled 70 * 64KB way size, 8-way associativity, parity disabled
69 */ 71 */
@@ -72,6 +74,7 @@ static void __init zynq_init_machine(void)
72 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 74 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
73 75
74 platform_device_register(&zynq_cpuidle_device); 76 platform_device_register(&zynq_cpuidle_device);
77 platform_device_register_full(&devinfo);
75} 78}
76 79
77static void __init zynq_timer_init(void) 80static void __init zynq_timer_init(void)