From 66a8950949c12a2600ff62e78b24f42ef8f6d28e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 5 Sep 2012 12:28:51 -0700 Subject: ARM: msm: Don't touch GIC registers outside of GIC code The MSM code has some antiquated register writes to set up the PPIs to be edge triggered. Now that we have the percpu irq interface we don't need this code so let's remove it and update the percpu irq user (msm_timer) to set the irq type. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-msm/timer.c') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 812808254936..36bbc60b699f 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -151,7 +151,7 @@ static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt) *__this_cpu_ptr(msm_evt.percpu_evt) = evt; clockevents_register_device(evt); - enable_percpu_irq(evt->irq, 0); + enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING); return 0; } @@ -219,7 +219,7 @@ static void __init msm_timer_init(void) res = request_percpu_irq(ce->irq, msm_timer_interrupt, ce->name, msm_evt.percpu_evt); if (!res) { - enable_percpu_irq(ce->irq, 0); + enable_percpu_irq(ce->irq, IRQ_TYPE_EDGE_RISING); #ifdef CONFIG_LOCAL_TIMERS local_timer_register(&msm_local_timer_ops); #endif -- cgit v1.2.3 From 4312a7ef9cd744849e16ef4bdeb7ca6beec9ec76 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 5 Sep 2012 12:28:52 -0700 Subject: ARM: msm: Allow timer.c to compile on multiple targets The timer code relies on #defines from mach/iomap.h, cpu_is_*() checks, and a global irq #define. All this makes this file impossible to compile in a mult-target build. Therefore, make a sys_timer struct for each SoC so that machine descriptors can reference the correct timer. Then go through and replace all the defines with raw values that are passed to a common initialization function. This paves the way to adding DT support to this code as well as allows us to compile this file on multiple targets at the same time. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 120 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 84 insertions(+), 36 deletions(-) (limited to 'arch/arm/mach-msm/timer.c') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 36bbc60b699f..ddb870117659 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -1,7 +1,7 @@ /* * * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. + * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -26,9 +26,7 @@ #include #include -#include -#include -#include +#include "common.h" #define TIMER_MATCH_VAL 0x0000 #define TIMER_COUNT_VAL 0x0004 @@ -36,7 +34,7 @@ #define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1) #define TIMER_ENABLE_EN BIT(0) #define TIMER_CLEAR 0x000C -#define DGT_CLK_CTL 0x0034 +#define DGT_CLK_CTL 0x0030 #define DGT_CLK_CTL_DIV_4 0x3 #define GPT_HZ 32768 @@ -172,44 +170,21 @@ static notrace u32 msm_sched_clock_read(void) return msm_clocksource.read(&msm_clocksource); } -static void __init msm_timer_init(void) +static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, + bool percpu) { struct clock_event_device *ce = &msm_clockevent; struct clocksource *cs = &msm_clocksource; int res; - u32 dgt_hz; - - if (cpu_is_msm7x01()) { - event_base = MSM_CSR_BASE; - source_base = MSM_CSR_BASE + 0x10; - dgt_hz = 19200000 >> MSM_DGT_SHIFT; /* 600 KHz */ - cs->read = msm_read_timer_count_shift; - cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)); - } else if (cpu_is_msm7x30()) { - event_base = MSM_CSR_BASE + 0x04; - source_base = MSM_CSR_BASE + 0x24; - dgt_hz = 24576000 / 4; - } else if (cpu_is_qsd8x50()) { - event_base = MSM_CSR_BASE; - source_base = MSM_CSR_BASE + 0x10; - dgt_hz = 19200000 / 4; - } else if (cpu_is_msm8x60() || cpu_is_msm8960()) { - event_base = MSM_TMR_BASE + 0x04; - /* Use CPU0's timer as the global clock source. */ - source_base = MSM_TMR0_BASE + 0x24; - dgt_hz = 27000000 / 4; - writel_relaxed(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); - } else - BUG(); writel_relaxed(0, event_base + TIMER_ENABLE); writel_relaxed(0, event_base + TIMER_CLEAR); writel_relaxed(~0, event_base + TIMER_MATCH_VAL); ce->cpumask = cpumask_of(0); + ce->irq = irq; - ce->irq = INT_GP_TIMER_EXP; clockevents_config_and_register(ce, GPT_HZ, 4, 0xffffffff); - if (cpu_is_msm8x60() || cpu_is_msm8960()) { + if (percpu) { msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *); if (!msm_evt.percpu_evt) { pr_err("memory allocation failed for %s\n", ce->name); @@ -238,10 +213,83 @@ err: res = clocksource_register_hz(cs, dgt_hz); if (res) pr_err("clocksource_register failed\n"); - setup_sched_clock(msm_sched_clock_read, - cpu_is_msm7x01() ? 32 - MSM_DGT_SHIFT : 32, dgt_hz); + setup_sched_clock(msm_sched_clock_read, sched_bits, dgt_hz); } -struct sys_timer msm_timer = { - .init = msm_timer_init +static int __init msm_timer_map(phys_addr_t event, phys_addr_t source) +{ + event_base = ioremap(event, SZ_64); + if (!event_base) { + pr_err("Failed to map event base\n"); + return 1; + } + source_base = ioremap(source, SZ_64); + if (!source_base) { + pr_err("Failed to map source base\n"); + return 1; + } + return 0; +} + +static void __init msm7x01_timer_init(void) +{ + struct clocksource *cs = &msm_clocksource; + + if (msm_timer_map(0xc0100000, 0xc0100010)) + return; + cs->read = msm_read_timer_count_shift; + cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)); + /* 600 KHz */ + msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7, + false); +} + +struct sys_timer msm7x01_timer = { + .init = msm7x01_timer_init +}; + +static void __init msm7x30_timer_init(void) +{ + if (msm_timer_map(0xc0100004, 0xc0100024)) + return; + msm_timer_init(24576000 / 4, 32, 1, false); +} + +struct sys_timer msm7x30_timer = { + .init = msm7x30_timer_init +}; + +static void __init msm8x60_timer_init(void) +{ + if (msm_timer_map(0x02000004, 0x02040024)) + return; + writel_relaxed(DGT_CLK_CTL_DIV_4, event_base + DGT_CLK_CTL); + msm_timer_init(27000000 / 4, 32, 17, true); +} + +struct sys_timer msm8x60_timer = { + .init = msm8x60_timer_init +}; + +static void __init msm8960_timer_init(void) +{ + if (msm_timer_map(0x0200A004, 0x0208A024)) + return; + writel_relaxed(DGT_CLK_CTL_DIV_4, event_base + DGT_CLK_CTL); + msm_timer_init(27000000 / 4, 32, 17, true); +} + +struct sys_timer msm8960_timer = { + .init = msm8960_timer_init +}; + +static void __init qsd8x50_timer_init(void) +{ + if (msm_timer_map(0xAC100000, 0xAC100010)) + return; + msm_timer_init(19200000 / 4, 32, 7, false); +} + +struct sys_timer qsd8x50_timer = { + .init = qsd8x50_timer_init }; -- cgit v1.2.3 From 6e3321631ac2eca99b3289b83ea1f290b1a8bd92 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 5 Sep 2012 12:28:53 -0700 Subject: ARM: msm: Add DT support to msm_timer Add support to setup the MSM timer via information obtained from the devicetree. Signed-off-by: Stephen Boyd [davidb@codeaurora.org: Remove leading zeros] Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'arch/arm/mach-msm/timer.c') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index ddb870117659..b17a39db991e 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include #include @@ -216,6 +219,90 @@ err: setup_sched_clock(msm_sched_clock_read, sched_bits, dgt_hz); } +#ifdef CONFIG_OF +static const struct of_device_id msm_dgt_match[] __initconst = { + { .compatible = "qcom,msm-dgt" }, + { }, +}; + +static const struct of_device_id msm_gpt_match[] __initconst = { + { .compatible = "qcom,msm-gpt" }, + { }, +}; + +static void __init msm_dt_timer_init(void) +{ + struct device_node *np; + u32 freq; + int irq; + struct resource res; + u32 percpu_offset; + void __iomem *dgt_clk_ctl; + + np = of_find_matching_node(NULL, msm_gpt_match); + if (!np) { + pr_err("Can't find GPT DT node\n"); + return; + } + + event_base = of_iomap(np, 0); + if (!event_base) { + pr_err("Failed to map event base\n"); + return; + } + + irq = irq_of_parse_and_map(np, 0); + if (irq <= 0) { + pr_err("Can't get irq\n"); + return; + } + of_node_put(np); + + np = of_find_matching_node(NULL, msm_dgt_match); + if (!np) { + pr_err("Can't find DGT DT node\n"); + return; + } + + if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) + percpu_offset = 0; + + if (of_address_to_resource(np, 0, &res)) { + pr_err("Failed to parse DGT resource\n"); + return; + } + + source_base = ioremap(res.start + percpu_offset, resource_size(&res)); + if (!source_base) { + pr_err("Failed to map source base\n"); + return; + } + + if (!of_address_to_resource(np, 1, &res)) { + dgt_clk_ctl = ioremap(res.start + percpu_offset, + resource_size(&res)); + if (!dgt_clk_ctl) { + pr_err("Failed to map DGT control base\n"); + return; + } + writel_relaxed(DGT_CLK_CTL_DIV_4, dgt_clk_ctl); + iounmap(dgt_clk_ctl); + } + + if (of_property_read_u32(np, "clock-frequency", &freq)) { + pr_err("Unknown frequency\n"); + return; + } + of_node_put(np); + + msm_timer_init(freq, 32, irq, !!percpu_offset); +} + +struct sys_timer msm_dt_timer = { + .init = msm_dt_timer_init +}; +#endif + static int __init msm_timer_map(phys_addr_t event, phys_addr_t source) { event_base = ioremap(event, SZ_64); -- cgit v1.2.3 From 5b67bfbae6612c4caa28fa52ced7cf1c122a185e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 5 Sep 2012 12:28:55 -0700 Subject: ARM: msm: Make 8660 a DT only target We don't plan to support anything besides devicetree on these targets so remove all other machine support. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'arch/arm/mach-msm/timer.c') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index b17a39db991e..27ade4f1ee16 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -346,18 +346,6 @@ struct sys_timer msm7x30_timer = { .init = msm7x30_timer_init }; -static void __init msm8x60_timer_init(void) -{ - if (msm_timer_map(0x02000004, 0x02040024)) - return; - writel_relaxed(DGT_CLK_CTL_DIV_4, event_base + DGT_CLK_CTL); - msm_timer_init(27000000 / 4, 32, 17, true); -} - -struct sys_timer msm8x60_timer = { - .init = msm8x60_timer_init -}; - static void __init msm8960_timer_init(void) { if (msm_timer_map(0x0200A004, 0x0208A024)) -- cgit v1.2.3 From 0607fa5884f1759b396a0e1c07be561515daddc8 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 5 Sep 2012 12:28:59 -0700 Subject: ARM: msm: Remove non-DT targets from 8960 Remove the non-DT targets supported by 8960. This makes 8960 a device tree only target. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'arch/arm/mach-msm/timer.c') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 27ade4f1ee16..7a49195f7a92 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -37,7 +37,6 @@ #define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1) #define TIMER_ENABLE_EN BIT(0) #define TIMER_CLEAR 0x000C -#define DGT_CLK_CTL 0x0030 #define DGT_CLK_CTL_DIV_4 0x3 #define GPT_HZ 32768 @@ -346,18 +345,6 @@ struct sys_timer msm7x30_timer = { .init = msm7x30_timer_init }; -static void __init msm8960_timer_init(void) -{ - if (msm_timer_map(0x0200A004, 0x0208A024)) - return; - writel_relaxed(DGT_CLK_CTL_DIV_4, event_base + DGT_CLK_CTL); - msm_timer_init(27000000 / 4, 32, 17, true); -} - -struct sys_timer msm8960_timer = { - .init = msm8960_timer_init -}; - static void __init qsd8x50_timer_init(void) { if (msm_timer_map(0xAC100000, 0xAC100010)) -- cgit v1.2.3