ARM: Exynos: Enable device tree support for MCT controller
Subsystems (5)
cover ARM: Exynos: Enable device tree support for MCT controller
This patch series adds device tree support for Exynos4/5 MCT controller. This series depends on the device tree and smp support patches for Exynos4x12 posted by Tomasz Figa. This patch series has been tested on Exynos4210 based Origen board, Exynos4412 based SMDK board and Exynos5250 based SMDK board.
Thomas Abraham (5):
ARM: Exynos: add a register base address variable in mct controller driver
ARM: Exynos: prepare an array of MCT interrupt numbers and use it
ARM: Exynos: add device tree support for MCT controller driver
ARM: Exynos: remove static io-remapping of mct registers for Exynos5
ARM: dts: add mct device tree node for all supported Exynos SoC's
.../bindings/timer/samsung,exynos4210-mct.txt | 70 ++++++++ arch/arm/boot/dts/exynos4210.dtsi | 8 + arch/arm/boot/dts/exynos4212.dtsi | 10 + arch/arm/boot/dts/exynos4412.dtsi | 8 + arch/arm/boot/dts/exynos5250.dtsi | 21 +++ arch/arm/mach-exynos/common.c | 5 - arch/arm/mach-exynos/include/mach/irqs.h | 6 - arch/arm/mach-exynos/include/mach/map.h | 1 - arch/arm/mach-exynos/include/mach/regs-mct.h | 53 ------ arch/arm/mach-exynos/mct.c | 176 +++++++++++++------- 10 files changed, 234 insertions(+), 124 deletions(-) create mode 100644 Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt delete mode 100644 arch/arm/mach-exynos/include/mach/regs-mct.h
PATCH 1/5 ARM: Exynos: add a register base address variable in mct controller driver
All the MCT register read/writes use a fixed remapped address S5P_VA_SYSTIMER. With device tree support for MCT controller, it is possible to remove the static remap of the MCT controller address space and do the remap during the initialization of the MCT controller with the physical address obtained from the device tree.
So in preparation of adding device tree support for MCT controller, add a new register base address variable that will hold the remapped MCT controller base address and convert all MCT register read/writes to use this new variable as the base address instead of the fixed S5P_VA_SYSTIMER.
While at it, the MCT register offset and bit mask definitions are moved into the MCT controller driver file since there are no other consumers of these definitions.
--- arch/arm/mach-exynos/include/mach/regs-mct.h | 53 -------------- arch/arm/mach-exynos/mct.c | 97 ++++++++++++++++--------- 2 files changed, 62 insertions(+), 88 deletions(-) delete mode 100644 arch/arm/mach-exynos/include/mach/regs-mct.h
arch/arm/mach-exynos/include/mach/regs-mct.h deleted +0 -53
@@ -1,53 +0,0 @@ -/* arch/arm/mach-exynos4/include/mach/regs-mct.h -* -* Copyright (c) 2011 Samsung Electronics Co., Ltd. -* http://www.samsung.com -* -* EXYNOS4 MCT configutation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_REGS_MCT_H -#define __ASM_ARCH_REGS_MCT_H __FILE__ - -#include <mach/map.h> - -#define EXYNOS4_MCTREG (x) (S5P_VA_SYSTIMER + (x)) - -#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100) -#define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104) -#define EXYNOS4_MCT_G_CNT_WSTAT EXYNOS4_MCTREG(0x110) - -#define EXYNOS4_MCT_G_COMP0_L EXYNOS4_MCTREG(0x200) -#define EXYNOS4_MCT_G_COMP0_U EXYNOS4_MCTREG(0x204) -#define EXYNOS4_MCT_G_COMP0_ADD_INCR EXYNOS4_MCTREG(0x208) - -#define EXYNOS4_MCT_G_TCON EXYNOS4_MCTREG(0x240) - -#define EXYNOS4_MCT_G_INT_CSTAT EXYNOS4_MCTREG(0x244) -#define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248) -#define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C) - -#define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300) -#define EXYNOS4_MCT_L_BASE (x) (_EXYNOS4_MCT_L_BASE + (0x100 * x)) -#define EXYNOS4_MCT_L_MASK (0xffffff00) - -#define MCT_L_TCNTB_OFFSET (0x00) -#define MCT_L_ICNTB_OFFSET (0x08) -#define MCT_L_TCON_OFFSET (0x20) -#define MCT_L_INT_CSTAT_OFFSET (0x30) -#define MCT_L_INT_ENB_OFFSET (0x34) -#define MCT_L_WSTAT_OFFSET (0x40) - -#define MCT_G_TCON_START (1 << 8) -#define MCT_G_TCON_COMP0_AUTO_INC (1 << 1) -#define MCT_G_TCON_COMP0_ENABLE (1 << 0) - -#define MCT_L_TCON_INTERVAL_MODE (1 << 2) -#define MCT_L_TCON_INT_START (1 << 1) -#define MCT_L_TCON_TIMER_START (1 << 0) - -#endif /* __ASM_ARCH_REGS_MCT_H */
arch/arm/mach-exynos/mct.c +62 -35
212 lines not on this page · raw message
Signature · 1 line
1.6.6.rc2
PATCH 2/5 ARM: Exynos: prepare an array of MCT interrupt numbers and use it
In reply to Thomas AbrahamInstead of using soc_is_xxx macro at more than one place in the MCT controller driver to decide the MCT interrpt number to be setup, populate a table of known MCT global and local timer interrupts and use the values in table to setup the MCT interrupts.
This also helps in adding device tree support for MCT controller driver by allowing the driver to retrieve interrupt numbers from device tree and populating them into this table, thereby supporting both legacy and dt functionality to co-exist.
--- arch/arm/mach-exynos/mct.c | 57 +++++++++++++++++++++++++++---------------- 1 files changed, 36 insertions(+), 21 deletions(-)
arch/arm/mach-exynos/mct.c +36 -21
@@ -64,9 +64,22 @@ enum {MCT_INT_PPI }; +enum { +MCT_G0_IRQ , +MCT_G1_IRQ , +MCT_G2_IRQ , +MCT_G3_IRQ , +MCT_L0_IRQ , +MCT_L1_IRQ , +MCT_L2_IRQ , +MCT_L3_IRQ , +MCT_NR_IRQS , +}; +static void __iomem *reg_base;static unsigned long clk_rate;static unsigned int mct_int_type; +static int mct_irqs[MCT_NR_IRQS ];struct mct_clock_event_device {struct clock_event_device *evt;
@@ -285,11 +298,7 @@ static void exynos4_clockevent_init(void)clockevent_delta2ns (0xf , &mct_comp_device); mct_comp_device.cpumask =cpumask_of (0 );clockevents_register_device (&mct_comp_device); - -if (soc_is_exynos5250 ()) -setup_irq (EXYNOS5_IRQ_MCT_G0 , &mct_comp_event_irq); -else -setup_irq (EXYNOS4_IRQ_MCT_G0 , &mct_comp_event_irq); +setup_irq (mct_irqs[MCT_G0_IRQ ], &mct_comp_event_irq); }#ifdef CONFIG_LOCAL_TIMERS
@@ -413,7 +422,6 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt) {struct mct_clock_event_device *mevt;unsigned int cpu =smp_processor_id (); -int mct_lx_irq; mevt =this_cpu_ptr (&percpu_mct_tick); mevt->evt = evt;
@@ -440,21 +448,17 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)if (mct_int_type ==MCT_INT_SPI ) {if (cpu ==0 ) { - mct_lx_irq =soc_is_exynos4210 () ?EXYNOS4_IRQ_MCT_L0 : -EXYNOS5_IRQ_MCT_L0 ; mct_tick0_event_irq.dev_id = mevt; - evt->irq = mct_lx_irq; -setup_irq (mct_lx_irq, &mct_tick0_event_irq); + evt->irq = mct_irqs[MCT_L0_IRQ ]; +setup_irq (evt->irq, &mct_tick0_event_irq); }else { - mct_lx_irq =soc_is_exynos4210 () ?EXYNOS4_IRQ_MCT_L1 : -EXYNOS5_IRQ_MCT_L1 ; mct_tick1_event_irq.dev_id = mevt; - evt->irq = mct_lx_irq; -setup_irq (mct_lx_irq, &mct_tick1_event_irq); -irq_set_affinity (mct_lx_irq,cpumask_of (1 )); + evt->irq = mct_irqs[MCT_L1_IRQ ]; +setup_irq (evt->irq, &mct_tick1_event_irq); +irq_set_affinity (evt->irq,cpumask_of (1 )); } }else { -enable_percpu_irq (EXYNOS_IRQ_MCT_LOCALTIMER ,0 ); +enable_percpu_irq (mct_irqs[MCT_L0_IRQ ],0 ); }return 0 ;
@@ -470,7 +474,7 @@ static void exynos4_local_timer_stop(struct clock_event_device *evt)else remove_irq (evt->irq, &mct_tick1_event_irq); else -disable_percpu_irq (EXYNOS_IRQ_MCT_LOCALTIMER ); +disable_percpu_irq (mct_irqs [MCT_L0_IRQ ]); }static struct local_timer_ops exynos4_mct_tick_ops__cpuinitdata = {
@@ -492,11 +496,11 @@ static void __init exynos4_timer_resources(void)if (mct_int_type ==MCT_INT_PPI ) {int err; - err =request_percpu_irq (EXYNOS_IRQ_MCT_LOCALTIMER , + err =request_percpu_irq (mct_irqs[MCT_L0_IRQ ], exynos4_mct_tick_isr,"MCT" , &percpu_mct_tick);WARN (err,"MCT: can't request IRQ %d (%d)\n" , -EXYNOS_IRQ_MCT_LOCALTIMER , err); + mct_irqs[MCT_L0_IRQ ], err); }local_timer_register (&exynos4_mct_tick_ops);
@@ -505,10 +509,21 @@ static void __init exynos4_timer_resources(void)static void __init exynos4_timer_init (void ) { -if ((soc_is_exynos4210 ()) || (soc_is_exynos5250 ())) +if (soc_is_exynos4210 ()) { + mct_irqs[MCT_G0_IRQ ] =EXYNOS4_IRQ_MCT_G0 ; + mct_irqs[MCT_L0_IRQ ] =EXYNOS4_IRQ_MCT_L0 ; + mct_irqs[MCT_L1_IRQ ] =EXYNOS4_IRQ_MCT_L1 ; mct_int_type =MCT_INT_SPI ; -else + }else if (soc_is_exynos5250 ()) { + mct_irqs[MCT_G0_IRQ ] =EXYNOS5_IRQ_MCT_G0 ; + mct_irqs[MCT_L0_IRQ ] =EXYNOS5_IRQ_MCT_L0 ; + mct_irqs[MCT_L1_IRQ ] =EXYNOS5_IRQ_MCT_L1 ; + mct_int_type =MCT_INT_SPI ; + }else { + mct_irqs[MCT_G0_IRQ ] =EXYNOS4_IRQ_MCT_G0 ; + mct_irqs[MCT_L0_IRQ ] =EXYNOS_IRQ_MCT_LOCALTIMER ; mct_int_type =MCT_INT_PPI ; + }exynos4_timer_resources ();exynos4_clocksource_init ();
Signature · 1 line
1.6.6.rc2
PATCH 3/5 ARM: Exynos: add device tree support for MCT controller driver
In reply to Thomas AbrahamAllow 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.
--- .../bindings/timer/samsung,exynos4210-mct.txt | 70 ++++++++++++++++++++ arch/arm/mach-exynos/include/mach/irqs.h | 6 -- arch/arm/mach-exynos/mct.c | 42 ++++++++---- 3 files changed, 99 insertions(+), 19 deletions(-) create mode 100644 Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +70 -0
@@ -0,0 +1,70 @@ +Samsung's Multi Core Timer (MCT) + +The Samsung's Multi Core Timer (MCT) module includes two main blocks, the +global timer and CPU local timers. The global timer is a 64-bit free running +up-counter and can generate 4 interrupts when the counter reaches one of the +four preset counter values. The CPU local timers are 32-bit free running +down-counters and generates an interrupt when the counter expires. There is +one CPU local timer instantiated in MCT for every CPU in the system. + +Required properties: + +- compatible: should be "samsung,exynos4210-mct". +- reg: base address of the mct controller and length of the address space + it occupies. +- interrupts: the list of interrupts generated by the controller. The following + should be the order of the interrupts specified. The local timer interrupts + should be specified after the four global timer interrupts have been + specified. + + 0: Global Timer Interrupt 0 + 1: Global Timer Interrupt 1 + 2: Global Timer Interrupt 2 + 3: Global Timer Interrupt 3 + 4: Local Timer Interrupt 0 + 5: Local Timer Interrupt 1 + 6: .. + 7: .. + i: Local Timer Interrupt n + +- samsung,mct-nr-local-irqs: The number of local timer interrupts supported + by the MCT controller. + +Example 1: In this example, the system uses only the first global timer + interrupt generated by MCT and the remaining three global timer + interrupts are unused. Two local timer interrupts have been + specified. + + mct@10050000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x10050000 0x800>; + interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>, + <0 42 0>, <0 48 0>; + samsung,mct-nr-local-irqs = <4>; + }; + +Example 2: In this example, the MCT global and local timer interrupts are + connected to two seperate interrupt controllers. Hence, an + interrupt-map is created to map the interrupts to the respective + interrupt controllers. + + mct@101C0000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x101C0000 0x800>; + interrupt-controller; + #interrups-cells = <2>; + interrupt-parent = <&mct_map>; + interrupts = <0 0>, <1 0>, <2 0>, <3 0>, + <4 0>, <5 0>; + samsung,mct-nr-local-irqs = <2>; + + mct_map: mct-map { + compatible = "samsung,mct-map"; + #interrupt-cells = <2>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = <0x0 0 &combiner 23 3>, + <0x4 0 &gic 0 120 0>, + <0x5 0 &gic 0 121 0>; + }; + };
arch/arm/mach-exynos/include/mach/irqs.h +0 -6
@@ -30,8 +30,6 @@/* For EXYNOS4 and EXYNOS5 */ -#define EXYNOS_IRQ_MCT_LOCALTIMER IRQ_PPI(12) -#define EXYNOS_IRQ_EINT16_31 IRQ_SPI(32)/* For EXYNOS4 SoCs */
@@ -320,8 +318,6 @@#define EXYNOS5_IRQ_CEC IRQ_SPI(114)#define EXYNOS5_IRQ_SATA IRQ_SPI(115) -#define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120) -#define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121)#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123)#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124)#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125)
@@ -411,8 +407,6 @@#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4)#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) -#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3) -#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4)#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0)#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1)
arch/arm/mach-exynos/mct.c +29 -13
72 lines not on this page · raw message
Signature · 1 line
1.6.6.rc2
PATCH 3/5 ARM: Exynos: add device tree support for MCT controller driver
Hi Thomas,
Quoted 19 lines · Thomas Abraham
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<[email protected]>Signed-off-by Thomas Abraham<[email protected]>--- .../bindings/timer/samsung,exynos4210-mct.txt | 70 ++++++++++++++++++++ arch/arm/mach-exynos/include/mach/irqs.h | 6 -- arch/arm/mach-exynos/mct.c | 42 ++++++++---- 3 files changed, 99 insertions(+), 19 deletions(-)create mode 100644
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txtDocumentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +0
-0
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt line 7
Quoted 7 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +7
-0@@ -0,0 +1,70 @@ +Samsung's Multi Core Timer (MCT) + +The Samsung's Multi Core Timer (MCT) module includes two main blocks, the +global timer and CPU local timers. The global timer is a 64-bit free running +up-counter and can generate 4 interrupts when the counter reaches one of the +four preset counter values. The CPU local timers are 32-bit free running +down-counters and generates an interrupt when the counter expires. There is
s/generates/generate ?
Quoted 26 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +26
-0+one CPU local timer instantiated in MCT for every CPU in the system. + +Required properties: + +- compatible: should be "samsung,exynos4210-mct". +- reg: base address of the mct controller and length of the address space + it occupies. +- interrupts: the list of interrupts generated by the controller. The following + should be the order of the interrupts specified. The local timer interrupts + should be specified after the four global timer interrupts have been + specified. + + 0: Global Timer Interrupt 0 + 1: Global Timer Interrupt 1 + 2: Global Timer Interrupt 2 + 3: Global Timer Interrupt 3 + 4: Local Timer Interrupt 0 + 5: Local Timer Interrupt 1 + 6: .. + 7: .. + i: Local Timer Interrupt n + +- samsung,mct-nr-local-irqs: The number of local timer interrupts supported + by the MCT controller. + +Example 1: In this example, the system uses only the first global timer
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt
Quoted 10 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +10
-0+ interrupt generated by MCT and the remaining three global timer + interrupts are unused. Two local timer interrupts have been + specified. + + mct at 10050000 { + compatible = "samsung,exynos4210-mct"; + reg =<0x10050000 0x800>; + interrupts =<0 57 0>,<0 0 0>,<0 0 0>,<0 0 0>, + <0 42 0>,<0 48 0>; + samsung,mct-nr-local-irqs =<4>;
Then this means the MCT supports 4 local interrupts but only 2 are specified here ? Doesn't the code below expect
samsung,mct-nr-local-irqs = <2>;
in this case ? Or should interrupts really be
interrupts =<0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>, <0 42 0>, <0 48 0>, <0 0 0>, <0 0 0>;
?
Quoted 6 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +6
-0+ }; + +Example 2: In this example, the MCT global and local timer interrupts are + connected to two seperate interrupt controllers. Hence, an + interrupt-map is created to map the interrupts to the respective + interrupt controllers.
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt
Quoted 10 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +10
-0+ + mct at 101C0000 { + compatible = "samsung,exynos4210-mct"; + reg =<0x101C0000 0x800>; + interrupt-controller; + #interrups-cells =<2>; + interrupt-parent =<&mct_map>; + interrupts =<0 0>,<1 0>,<2 0>,<3 0>, + <4 0>,<5 0>; + samsung,mct-nr-local-irqs =<2>;
Here the samsung,mct-nr-local-irqs' value matches what's specified in the interrupts property.
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt line 62
Quoted 3 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +3
-0+ + mct_map: mct-map { + compatible = "samsung,mct-map";
Do we need a compatible property in sub-nodes like this one ? Wouldn't it be sufficient to reference this node, for example by name ?
Quoted 57 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +8
-0+ #interrupt-cells =<2>; + #address-cells =<0>; + #size-cells =<0>; + interrupt-map =<0x0 0&combiner 23 3>, + <0x4 0&gic 0 120 0>, + <0x5 0&gic 0 121 0>; + }; + };arch/arm/mach-exynos/include/mach/irqs.h +0
-6@@ -30,8 +30,6 @@/* For EXYNOS4 and EXYNOS5 */ -#define EXYNOS_IRQ_MCT_LOCALTIMER IRQ_PPI(12) -#define EXYNOS_IRQ_EINT16_31 IRQ_SPI(32)/* For EXYNOS4 SoCs */ @@ -320,8 +318,6 @@#define EXYNOS5_IRQ_CEC IRQ_SPI(114)#define EXYNOS5_IRQ_SATA IRQ_SPI(115) -#define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120) -#define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121)#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123)#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124)#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125)@@ -411,8 +407,6 @@#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4)#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) -#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3) -#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4)#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0)#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1)arch/arm/mach-exynos/mct.c +3
-0@@ -19,6 +19,9 @@#include <linux/platform_device.h> #include <linux/delay.h> #include <linux/percpu.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> #include <asm/hardware/gic.h> #include <asm/localtimer.h> @@ -483,14 +486,16 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = { };#endif /* CONFIG_LOCAL_TIMERS */
arch/arm/mach-exynos/mct.c static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = { · line 496
Quoted 10 lines
arch/arm/mach-exynos/mct.c +2
-2-static void __init exynos4_timer_resources (void ) +static void __init exynos4_timer_resources (struct device_node *np) {struct clk *mct_clk; mct_clk =clk_get (NULL ,"xtal" ); clk_rate =clk_get_rate (mct_clk); - reg_base =S5P_VA_SYSTIMER ; + reg_base = (np) ?of_iomap (np,0 ) :S5P_VA_SYSTIMER ;
nit: Parentheses around np look redundant.
arch/arm/mach-exynos/mct.c static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = { · line 498
Quoted 2 lines
arch/arm/mach-exynos/mct.c +2
-0+if (!reg_base) +panic ("%s: unable to ioremap mct address space\n" , __func__);
How about adding a line like:
#define pr_fmt(fmt) "%s: " fmt, __func__
on top of this file and dropping "%s: " and __func__ in those panic() calls ? It would make the logs more consistent across whole file.
Quoted 7 lines
arch/arm/mach-exynos/mct.c +0
-1#ifdef CONFIG_LOCAL_TIMERS if (mct_int_type ==MCT_INT_PPI ) {@@ -509,23 +514,34 @@ static void __init exynos4_timer_resources(void)static void __init exynos4_timer_init (void ) { -if (soc_is_exynos4210 ()) {
arch/arm/mach-exynos/mct.c static void __init exynos4_timer_resources(void) · line 526
Quoted 10 lines
arch/arm/mach-exynos/mct.c +10
-0+struct device_node *np; +u32 nr_irqs, i; + + np =of_find_compatible_node (NULL ,NULL ,"samsung,exynos4210-mct" ); +if (np) { +if (of_machine_is_compatible ("samsung,exynos4210" ) || +of_machine_is_compatible ("samsung,exynos5250" )) + mct_int_type =MCT_INT_SPI ; +else + mct_int_type =MCT_INT_PPI ;
Does it make sense to specify this mct_int_type as a property of the mct node ?
Quoted 21 lines
arch/arm/mach-exynos/mct.c +11
-6+ +if (of_property_read_u32 (np,"samsung,mct-nr-local-irqs" , + &nr_irqs)) +panic ("%s: number of local irqs not specified\n" , + __func__); + + mct_irqs[MCT_G0_IRQ ] =irq_of_parse_and_map (np,MCT_G0_IRQ ); +for (i =0 ; i< nr_irqs; i++) + mct_irqs[MCT_L0_IRQ + i] = +irq_of_parse_and_map (np,MCT_L0_IRQ + i); + }else if (soc_is_exynos4210 ()) { mct_irqs[MCT_G0_IRQ ] =EXYNOS4_IRQ_MCT_G0 ; mct_irqs[MCT_L0_IRQ ] =EXYNOS4_IRQ_MCT_L0 ; mct_irqs[MCT_L1_IRQ ] =EXYNOS4_IRQ_MCT_L1 ; mct_int_type =MCT_INT_SPI ; - }else if (soc_is_exynos5250 ()) { - mct_irqs[MCT_G0_IRQ ] =EXYNOS5_IRQ_MCT_G0 ; - mct_irqs[MCT_L0_IRQ ] =EXYNOS5_IRQ_MCT_L0 ; - mct_irqs[MCT_L1_IRQ ] =EXYNOS5_IRQ_MCT_L1 ; - mct_int_type =MCT_INT_SPI ; - }else {
arch/arm/mach-exynos/mct.c static void __init exynos4_timer_resources(void) · line 547
Quoted 10 lines
arch/arm/mach-exynos/mct.c +1
-4- mct_irqs[MCT_G0_IRQ ] =EXYNOS4_IRQ_MCT_G0 ; - mct_irqs[MCT_L0_IRQ ] =EXYNOS_IRQ_MCT_LOCALTIMER ; - mct_int_type =MCT_INT_PPI ; } -exynos4_timer_resources (); +exynos4_timer_resources (np);exynos4_clocksource_init ();exynos4_clockevent_init (); }
--
Regards,
Sylwester
PATCH 3/5 ARM: Exynos: add device tree support for MCT controller driver
Hi Sylwester,
Thanks for your comments.
Quoted 34 lines · Sylwester Nawrocki
Hi Thomas,
Quoted 30 lines · Thomas Abraham
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<[email protected]>Signed-off-by Thomas Abraham<[email protected]>--- .../bindings/timer/samsung,exynos4210-mct.txt | 70 ++++++++++++++++++++ arch/arm/mach-exynos/include/mach/irqs.h | 6 -- arch/arm/mach-exynos/mct.c | 42 ++++++++---- 3 files changed, 99 insertions(+), 19 deletions(-)create mode 100644
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txtdiff --git
a/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txtb/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txtnew file mode 100644
index 0000000..c53fd93Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +4
-0@@ -0,0 +1,70 @@ +Samsung's Multi Core Timer (MCT) + +The Samsung's Multi Core Timer (MCT) module includes two main blocks, the +global timer and CPU local timers. The global timer is a 64-bit freerunning
Quoted 8 lines
Quoted 5 lines
+up-counter and can generate 4 interrupts when the counter reaches one of the
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +2
-0+four preset counter values. The CPU local timers are 32-bit free running +down-counters and generates an interrupt when the counter expires. Thereis
s/generates/generate ?
Ok.
Quoted 48 lines
Quoted 31 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +8
-0+one CPU local timer instantiated in MCT for every CPU in the system. + +Required properties: + +- compatible: should be "samsung,exynos4210-mct". +- reg: base address of the mct controller and length of the address space + it occupies. +- interrupts: the list of interrupts generated by the controller. Thefollowing
+ should be the order of the interrupts specified. The local timer interruptsDocumentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +14
-0+ should be specified after the four global timer interrupts have been + specified. + + 0: Global Timer Interrupt 0 + 1: Global Timer Interrupt 1 + 2: Global Timer Interrupt 2 + 3: Global Timer Interrupt 3 + 4: Local Timer Interrupt 0 + 5: Local Timer Interrupt 1 + 6: .. + 7: .. + i: Local Timer Interrupt n + +- samsung,mct-nr-local-irqs: The number of local timer interruptssupported
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +3
-0+ by the MCT controller. + +Example 1: In this example, the system uses only the first global timerDocumentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt
Quoted 10 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +10
-0+ interrupt generated by MCT and the remaining three global timer + interrupts are unused. Two local timer interrupts have been + specified. + + mct at 10050000 { + compatible = "samsung,exynos4210-mct"; + reg =<0x10050000 0x800>; + interrupts =<0 57 0>,<0 0 0>,<0 0 0>,<0 0 0>, + <0 42 0>,<0 48 0>; + samsung,mct-nr-local-irqs =<4>;Then this means the MCT supports 4 local interrupts but only 2 are specified here ? Doesn't the code below expect
samsung,mct-nr-local-irqs = <2>;
Quoted 7 lines
in this case ? Or should interrupts really be
interrupts =<0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>, <0 42 0>, <0 48 0>, <0 0 0>, <0 0 0>;?
No, that was a typo. It should be samsung,mct-nr-local-irqs = <2>. Thanks for spotting this.
Quoted 24 lines
Quoted 8 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +5
-0+ }; + +Example 2: In this example, the MCT global and local timer interrupts are + connected to two seperate interrupt controllers. Hence, an + interrupt-map is created to map the interrupts to therespective
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +1
-0+ interrupt controllers.Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt
Quoted 10 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +10
-0+ + mct at 101C0000 { + compatible = "samsung,exynos4210-mct"; + reg =<0x101C0000 0x800>; + interrupt-controller; + #interrups-cells =<2>; + interrupt-parent =<&mct_map>; + interrupts =<0 0>,<1 0>,<2 0>,<3 0>, + <4 0>,<5 0>; + samsung,mct-nr-local-irqs =<2>;Here the samsung,mct-nr-local-irqs' value matches what's specified in the interrupts property.
Quoted 7 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt line 62
Quoted 3 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +3
-0+ + mct_map: mct-map { + compatible = "samsung,mct-map";Do we need a compatible property in sub-nodes like this one ? Wouldn't it be sufficient to reference this node, for example by name ?
Yes, it is not really required. I will remove it.
Quoted 67 lines
Quoted 67 lines
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file +8
-0+ #interrupt-cells =<2>; + #address-cells =<0>; + #size-cells =<0>; + interrupt-map =<0x0 0&combiner 23 3>, + <0x4 0&gic 0 120 0>, + <0x5 0&gic 0 121 0>; + }; + };arch/arm/mach-exynos/include/mach/irqs.h +0
-6@@ -30,8 +30,6 @@/* For EXYNOS4 and EXYNOS5 */ -#define EXYNOS_IRQ_MCT_LOCALTIMER IRQ_PPI(12) -#define EXYNOS_IRQ_EINT16_31 IRQ_SPI(32)/* For EXYNOS4 SoCs */ @@ -320,8 +318,6 @@#define EXYNOS5_IRQ_CEC IRQ_SPI(114)#define EXYNOS5_IRQ_SATA IRQ_SPI(115) -#define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120) -#define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121)#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123)#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124)#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125)@@ -411,8 +407,6 @@#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4)#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) -#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3) -#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4)#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0)#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1)arch/arm/mach-exynos/mct.c +4
-1@@ -19,6 +19,9 @@#include <linux/platform_device.h> #include <linux/delay.h> #include <linux/percpu.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> #include <asm/hardware/gic.h> #include <asm/localtimer.h> @@ -483,14 +486,16 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = { };#endif /* CONFIG_LOCAL_TIMERS */ -static void __init exynos4_timer_resources (void ) +static void __init exynos4_timer_resources (struct device_node *np) {struct clk *mct_clk; mct_clk =clk_get (NULL ,"xtal" );
Quoted 7 lines
arch/arm/mach-exynos/mct.c static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = { · line 496
Quoted 4 lines
arch/arm/mach-exynos/mct.c +1
-1clk_rate =clk_get_rate (mct_clk); - reg_base =S5P_VA_SYSTIMER ; + reg_base = (np) ?of_iomap (np,0 ) :S5P_VA_SYSTIMER ;nit: Parentheses around np look redundant.
Ok.
Quoted 7 lines
arch/arm/mach-exynos/mct.c static struct local_timer_ops exynos4_mct_tick_ops · line 500
Quoted 5 lines
arch/arm/mach-exynos/mct.c +2
-0+if (!reg_base) +panic ("%s: unable to ioremap mct address space\n" , __func__);
Quoted 6 lines
How about adding a line like:
#define
pr_fmt(fmt)"%s: " fmt,__func__on top of this file and dropping "%s: " and
__func__in thosepanic()calls ? It would make the logs more consistent across whole file.
Ok.
Quoted 16 lines
Quoted 16 lines
arch/arm/mach-exynos/mct.c +0
-0#ifdef CONFIG_LOCAL_TIMERS if (mct_int_type == MCT_INT_PPI) {arch/arm/mach-exynos/mct.c +6
-1@@ -509,23 +514,34 @@ static void __init exynos4_timer_resources(void)static void __init exynos4_timer_init (void ) { -if (soc_is_exynos4210 ()) { +struct device_node *np; +u32 nr_irqs, i; + + np =of_find_compatible_node (NULL ,NULL ,"samsung,exynos4210-mct" ); +if (np) { + if (of_machine_is_compatible("samsung,exynos4210") ||
Quoted 8 lines
arch/arm/mach-exynos/mct.c static void __init exynos4_timer_resources(void) · line 526
Quoted 4 lines
arch/arm/mach-exynos/mct.c +4
-0+ of_machine_is_compatible("samsung,exynos5250")) + mct_int_type =MCT_INT_SPI ; + else + mct_int_type =MCT_INT_PPI ;Does it make sense to specify this
mct_int_typeas a property of the mct node ?
The MCT bindings are independent of the system integration details. There could be a system that uses MCT controller but not GIC controller.
Thanks,
Thomas.
PATCH 4/5 ARM: Exynos: remove static io-remapping of mct registers for Exynos5
In reply to Thomas AbrahamWith device tree support enabled for MCT controller, the static io-remapping of the MCT controller address space is removed for Exynos5 platforms (which supports only device tree based boot).
--- arch/arm/mach-exynos/common.c | 5 ----- arch/arm/mach-exynos/include/mach/map.h | 1 - 2 files changed, 0 insertions(+), 6 deletions(-)
arch/arm/mach-exynos/common.c +0 -5
@@ -234,11 +234,6 @@ static struct map_desc exynos5_iodesc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S5P_VA_SYSTIMER, - .pfn = __phys_to_pfn(EXYNOS5_PA_SYSTIMER), - .length = SZ_4K, - .type = MT_DEVICE, - }, { .virtual = (unsigned long)S5P_VA_SYSRAM, .pfn = __phys_to_pfn(EXYNOS5_PA_SYSRAM), .length = SZ_4K,
arch/arm/mach-exynos/include/mach/map.h +0 -1
@@ -64,7 +64,6 @@#define EXYNOS5_PA_CMU 0x10010000#define EXYNOS4_PA_SYSTIMER 0x10050000 -#define EXYNOS5_PA_SYSTIMER 0x101C0000#define EXYNOS4_PA_WATCHDOG 0x10060000#define EXYNOS5_PA_WATCHDOG 0x101D0000
Signature · 1 line
1.6.6.rc2
PATCH 5/5 ARM: dts: add mct device tree node for all supported Exynos SoC's
In reply to Thomas AbrahamAdd MCT device tree node for Exynos4210, Exynos4212, Exynos4412 and Exynos5250.
--- arch/arm/boot/dts/exynos4210.dtsi | 8 ++++++++ arch/arm/boot/dts/exynos4212.dtsi | 10 ++++++++++ arch/arm/boot/dts/exynos4412.dtsi | 8 ++++++++ arch/arm/boot/dts/exynos5250.dtsi | 21 +++++++++++++++++++++ 4 files changed, 47 insertions(+), 0 deletions(-)
arch/arm/boot/dts/exynos4210.dtsi +8 -0
@@ -42,6 +42,14 @@ <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>; }; + mct@10050000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x10050000 0x800>; + interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>, + <0 42 0>, <0 48 0>; + samsung,mct-nr-local-irqs = <4>; + }; + pinctrl_0: pinctrl@11400000 { compatible = "samsung,pinctrl-exynos4210"; reg = <0x11400000 0x1000>;
arch/arm/boot/dts/exynos4212.dtsi +10 -0
@@ -25,4 +25,14 @@ gic:interrupt-controller@10490000 { cpu-offset = <0x8000>; }; + + mct@10050000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x10050000 0x800>; + interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>, + <1 12 0>, <1 12 0>; + samsung,mct-nr-local-irqs = <2>; + }; + + };
arch/arm/boot/dts/exynos4412.dtsi +8 -0
@@ -25,4 +25,12 @@ gic:interrupt-controller@10490000 { cpu-offset = <0x4000>; }; + + mct@10050000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x10050000 0x800>; + interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>, + <1 12 0>, <1 12 0>, <1 12 0>, <1 12 0>; + samsung,mct-nr-local-irqs = <4>; + }; };
arch/arm/boot/dts/exynos5250.dtsi +21 -0
@@ -56,6 +56,27 @@ <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; }; + mct@101C0000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x101C0000 0x800>; + interrupt-controller; + #interrups-cells = <2>; + interrupt-parent = <&mct_map>; + interrupts = <0 0>, <1 0>, <2 0>, <3 0>, + <4 0>, <5 0>; + samsung,mct-nr-local-irqs = <2>; + + mct_map: mct-map { + compatible = "samsung,mct-map"; + #interrupt-cells = <2>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = <0x0 0 &combiner 23 3>, + <0x4 0 &gic 0 120 0>, + <0x5 0 &gic 0 121 0>; + }; + }; + watchdog { compatible = "samsung,s3c2410-wdt"; reg = <0x101D0000 0x100>;
Signature · 1 line
1.6.6.rc2