From: Ranjani Vaidyanathan Date: Thu, 2 Feb 2012 11:31:52 +0000 (-0600) Subject: ENGR00173586-1 [MX6] Add support to source GPT from 24MHz X-Git-Tag: v3.0.35-fsl~1562 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=3a2ac766ad3da43e6ed628709e0c3eb227266394;p=karo-tx-linux.git ENGR00173586-1 [MX6] Add support to source GPT from 24MHz On MX6Q TO1.1, MX6DL/S and MX6Solo, GPT can be sourced from a constant source (better for frequency scaling). Currently we set the GPT clock to 3MHz (24MHz div by 8). Signed-off-by: Ranjani Vaidyanathan --- diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 9a340ccf8dac..a8d1982b1b08 100755 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,4 +86,5 @@ extern void mx51_efikamx_reset(void); extern int mx53_revision(void); extern int mx50_revision(void); extern int mx53_display_revision(void); +extern unsigned long mx6_timer_rate(void); #endif diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index dd6b74e378c1..437921fdd2c2 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -58,7 +58,13 @@ #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ #define V2_TCTL_CLK_IPG (1 << 6) #define V2_TCTL_CLK_PER (2 << 6) -#define V2_TCTL_FRR (1 << 9) +#define V2_TCTL_CLK_OSC_DIV8 (5 << 6) +#define V2_TCTL_CLK_OSC (7 << 6) +#define V2_TCTL_FRR (1 << 9) +#define V2_TCTL_ENABLE24M (1 << 10) +#define V2_TPRER_PRE24M_DIV8 7 +#define V2_TPRER_PRE24M_MASK 0xF +#define V2_TPRER_PRE24M_OFFSET 12 #define V2_IR 0x0c #define V2_TSTAT 0x08 #define V2_TSTAT_OF1 (1 << 0) @@ -73,6 +79,10 @@ static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; static void __iomem *timer_base; +#ifdef CONFIG_ARCH_MX6 +extern int mx6q_revision(void); +#endif + static inline void gpt_irq_disable(void) { unsigned int tmp; @@ -289,9 +299,38 @@ static int __init mxc_clockevent_init(struct clk *timer_clk) return 0; } +#ifdef CONFIG_ARCH_MX6 +unsigned long mx6_timer_rate() +{ + struct clk *osc_clk = clk_get(NULL, "osc"); + u32 parent_rate = clk_get_rate(osc_clk); + + u32 reg = __raw_readl(timer_base + MXC_TCTL); + u32 div; + + clk_put(osc_clk); + + if ((reg & V2_TCTL_CLK_OSC_DIV8) == V2_TCTL_CLK_OSC_DIV8) { + if (cpu_is_mx6q()) + /* For MX6Q, only options are 24MHz or 24MHz/8*/ + return parent_rate / 8; + else { + /* For MX6DLS and MX6Solo, the rate is based on the + * divider value set in prescalar register. */ + div = __raw_readl(timer_base + MXC_TPRER); + div = (div >> V2_TPRER_PRE24M_OFFSET) & + V2_TPRER_PRE24M_MASK; + return parent_rate / (div + 1); + } + } + return 0; +} +#endif + void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) { uint32_t tctl_val; + u32 reg; clk_enable(timer_clk); @@ -304,9 +343,24 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) __raw_writel(0, timer_base + MXC_TCTL); __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ - if (timer_is_v2()) - tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; - else + if (timer_is_v2()) { + if (cpu_is_mx5() || + mx6q_revision() == IMX_CHIP_REVISION_1_0) + tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | + V2_TCTL_WAITEN | MXC_TCTL_TEN; + else { + tctl_val = V2_TCTL_CLK_OSC_DIV8 | V2_TCTL_FRR | + V2_TCTL_WAITEN | MXC_TCTL_TEN; + if (!cpu_is_mx6q()) { + reg = __raw_readl(timer_base + MXC_TPRER); + reg |= (V2_TPRER_PRE24M_DIV8 << + V2_TPRER_PRE24M_OFFSET); + __raw_writel(reg, timer_base + MXC_TPRER); + /* Enable the 24MHz input clock. */ + tctl_val |= V2_TCTL_ENABLE24M; + } + } + } else tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; __raw_writel(tctl_val, timer_base + MXC_TCTL);