aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Abraham <thomas.abraham@linaro.org>2013-03-09 02:01:52 -0500
committerKukjin Kim <kgene.kim@samsung.com>2013-03-09 02:01:52 -0500
commit36ba5d527e9567ed303bad6e86a5f3c2723470f6 (patch)
tree45729298d0d331a4cea1bd248dc33329dc149726
parentc371dc60aebf7ada4d5b4585ea8f46a3a06f8f04 (diff)
ARM: EXYNOS: add device tree support for MCT controller driver
Allow the MCT controller base address and interrupts to be obtained from device tree and remove unused static definitions of these. The non-dt support for Exynos5250 is removed but retained for Exynos4210 based platforms. Cc: Changhwan Youn <chaos.youn@samsung.com> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Reviewed-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r--Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt68
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs.h6
-rw-r--r--arch/arm/mach-exynos/mct.c49
3 files changed, 105 insertions, 18 deletions
diff --git a/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt b/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt
new file mode 100644
index 000000000000..cb47bfbcaeea
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt
@@ -0,0 +1,68 @@
1Samsung's Multi Core Timer (MCT)
2
3The Samsung's Multi Core Timer (MCT) module includes two main blocks, the
4global timer and CPU local timers. The global timer is a 64-bit free running
5up-counter and can generate 4 interrupts when the counter reaches one of the
6four preset counter values. The CPU local timers are 32-bit free running
7down-counters and generate an interrupt when the counter expires. There is
8one CPU local timer instantiated in MCT for every CPU in the system.
9
10Required properties:
11
12- compatible: should be "samsung,exynos4210-mct".
13 (a) "samsung,exynos4210-mct", for mct compatible with Exynos4210 mct.
14 (b) "samsung,exynos4412-mct", for mct compatible with Exynos4412 mct.
15
16- reg: base address of the mct controller and length of the address space
17 it occupies.
18
19- interrupts: the list of interrupts generated by the controller. The following
20 should be the order of the interrupts specified. The local timer interrupts
21 should be specified after the four global timer interrupts have been
22 specified.
23
24 0: Global Timer Interrupt 0
25 1: Global Timer Interrupt 1
26 2: Global Timer Interrupt 2
27 3: Global Timer Interrupt 3
28 4: Local Timer Interrupt 0
29 5: Local Timer Interrupt 1
30 6: ..
31 7: ..
32 i: Local Timer Interrupt n
33
34Example 1: In this example, the system uses only the first global timer
35 interrupt generated by MCT and the remaining three global timer
36 interrupts are unused. Two local timer interrupts have been
37 specified.
38
39 mct@10050000 {
40 compatible = "samsung,exynos4210-mct";
41 reg = <0x10050000 0x800>;
42 interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>,
43 <0 42 0>, <0 48 0>;
44 };
45
46Example 2: In this example, the MCT global and local timer interrupts are
47 connected to two seperate interrupt controllers. Hence, an
48 interrupt-map is created to map the interrupts to the respective
49 interrupt controllers.
50
51 mct@101C0000 {
52 compatible = "samsung,exynos4210-mct";
53 reg = <0x101C0000 0x800>;
54 interrupt-controller;
55 #interrups-cells = <2>;
56 interrupt-parent = <&mct_map>;
57 interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
58 <4 0>, <5 0>;
59
60 mct_map: mct-map {
61 #interrupt-cells = <2>;
62 #address-cells = <0>;
63 #size-cells = <0>;
64 interrupt-map = <0x0 0 &combiner 23 3>,
65 <0x4 0 &gic 0 120 0>,
66 <0x5 0 &gic 0 121 0>;
67 };
68 };
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index 1f4dc35cd4b9..c0e75d8dd737 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -30,8 +30,6 @@
30 30
31/* For EXYNOS4 and EXYNOS5 */ 31/* For EXYNOS4 and EXYNOS5 */
32 32
33#define EXYNOS_IRQ_MCT_LOCALTIMER IRQ_PPI(12)
34
35#define EXYNOS_IRQ_EINT16_31 IRQ_SPI(32) 33#define EXYNOS_IRQ_EINT16_31 IRQ_SPI(32)
36 34
37/* For EXYNOS4 SoCs */ 35/* For EXYNOS4 SoCs */
@@ -323,8 +321,6 @@
323#define EXYNOS5_IRQ_CEC IRQ_SPI(114) 321#define EXYNOS5_IRQ_CEC IRQ_SPI(114)
324#define EXYNOS5_IRQ_SATA IRQ_SPI(115) 322#define EXYNOS5_IRQ_SATA IRQ_SPI(115)
325 323
326#define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120)
327#define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121)
328#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123) 324#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123)
329#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124) 325#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124)
330#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125) 326#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125)
@@ -419,8 +415,6 @@
419#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4) 415#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4)
420 416
421#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) 417#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0)
422#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3)
423#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4)
424 418
425#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0) 419#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0)
426#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1) 420#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1)
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index 1061db4118aa..f34c933314f3 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -20,6 +20,8 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/percpu.h> 21#include <linux/percpu.h>
22#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/of_irq.h>
24#include <linux/of_address.h>
23 25
24#include <asm/arch_timer.h> 26#include <asm/arch_timer.h>
25#include <asm/localtimer.h> 27#include <asm/localtimer.h>
@@ -474,14 +476,16 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
474}; 476};
475#endif /* CONFIG_LOCAL_TIMERS */ 477#endif /* CONFIG_LOCAL_TIMERS */
476 478
477static void __init exynos4_timer_resources(void) 479static void __init exynos4_timer_resources(struct device_node *np)
478{ 480{
479 struct clk *mct_clk; 481 struct clk *mct_clk;
480 mct_clk = clk_get(NULL, "xtal"); 482 mct_clk = clk_get(NULL, "xtal");
481 483
482 clk_rate = clk_get_rate(mct_clk); 484 clk_rate = clk_get_rate(mct_clk);
483 485
484 reg_base = S5P_VA_SYSTIMER; 486 reg_base = np ? of_iomap(np, 0) : S5P_VA_SYSTIMER;
487 if (!reg_base)
488 panic("%s: unable to ioremap mct address space\n", __func__);
485 489
486#ifdef CONFIG_LOCAL_TIMERS 490#ifdef CONFIG_LOCAL_TIMERS
487 if (mct_int_type == MCT_INT_PPI) { 491 if (mct_int_type == MCT_INT_PPI) {
@@ -498,30 +502,51 @@ static void __init exynos4_timer_resources(void)
498#endif /* CONFIG_LOCAL_TIMERS */ 502#endif /* CONFIG_LOCAL_TIMERS */
499} 503}
500 504
505static const struct of_device_id exynos_mct_ids[] = {
506 { .compatible = "samsung,exynos4210-mct", .data = (void *)MCT_INT_SPI },
507 { .compatible = "samsung,exynos4412-mct", .data = (void *)MCT_INT_PPI },
508};
509
501void __init exynos4_timer_init(void) 510void __init exynos4_timer_init(void)
502{ 511{
512 struct device_node *np = NULL;
513 const struct of_device_id *match;
514 u32 nr_irqs, i;
515
503 if (soc_is_exynos5440()) { 516 if (soc_is_exynos5440()) {
504 arch_timer_of_register(); 517 arch_timer_of_register();
505 return; 518 return;
506 } 519 }
507 520
508 if (soc_is_exynos4210()) { 521#ifdef CONFIG_OF
522 np = of_find_matching_node_and_match(NULL, exynos_mct_ids, &match);
523#endif
524 if (np) {
525 mct_int_type = (u32)(match->data);
526
527 /* This driver uses only one global timer interrupt */
528 mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ);
529
530 /*
531 * Find out the number of local irqs specified. The local
532 * timer irqs are specified after the four global timer
533 * irqs are specified.
534 */
535#ifdef CONFIG_OF
536 nr_irqs = of_irq_count(np);
537#endif
538 for (i = MCT_L0_IRQ; i < nr_irqs; i++)
539 mct_irqs[i] = irq_of_parse_and_map(np, i);
540 } else if (soc_is_exynos4210()) {
509 mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0; 541 mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0;
510 mct_irqs[MCT_L0_IRQ] = EXYNOS4_IRQ_MCT_L0; 542 mct_irqs[MCT_L0_IRQ] = EXYNOS4_IRQ_MCT_L0;
511 mct_irqs[MCT_L1_IRQ] = EXYNOS4_IRQ_MCT_L1; 543 mct_irqs[MCT_L1_IRQ] = EXYNOS4_IRQ_MCT_L1;
512 mct_int_type = MCT_INT_SPI; 544 mct_int_type = MCT_INT_SPI;
513 } else if (soc_is_exynos5250()) {
514 mct_irqs[MCT_G0_IRQ] = EXYNOS5_IRQ_MCT_G0;
515 mct_irqs[MCT_L0_IRQ] = EXYNOS5_IRQ_MCT_L0;
516 mct_irqs[MCT_L1_IRQ] = EXYNOS5_IRQ_MCT_L1;
517 mct_int_type = MCT_INT_SPI;
518 } else { 545 } else {
519 mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0; 546 panic("unable to determine mct controller type\n");
520 mct_irqs[MCT_L0_IRQ] = EXYNOS_IRQ_MCT_LOCALTIMER;
521 mct_int_type = MCT_INT_PPI;
522 } 547 }
523 548
524 exynos4_timer_resources(); 549 exynos4_timer_resources(np);
525 exynos4_clocksource_init(); 550 exynos4_clocksource_init();
526 exynos4_clockevent_init(); 551 exynos4_clockevent_init();
527} 552}