From patchwork Tue Oct 28 09:40:34 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ye.Li" X-Patchwork-Id: 404139 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 7AAFD14007B for ; Tue, 28 Oct 2014 20:42:13 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8A526A740E; Tue, 28 Oct 2014 10:42:11 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OVGS6kjTr4Jg; Tue, 28 Oct 2014 10:42:11 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C6F3DA73F0; Tue, 28 Oct 2014 10:42:10 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A88DEA73F7 for ; Tue, 28 Oct 2014 10:42:05 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8KScgK2-UOrx for ; Tue, 28 Oct 2014 10:42:05 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from na01-bn1-obe.outbound.protection.outlook.com (mail-bn1bon0142.outbound.protection.outlook.com [157.56.111.142]) by theia.denx.de (Postfix) with ESMTPS id 16E83A73EA for ; Tue, 28 Oct 2014 10:42:01 +0100 (CET) Received: from BY2PR03CA048.namprd03.prod.outlook.com (10.141.249.21) by BY2PR03MB255.namprd03.prod.outlook.com (10.242.37.22) with Microsoft SMTP Server (TLS) id 15.1.6.9; Tue, 28 Oct 2014 09:41:58 +0000 Received: from BN1BFFO11FD031.protection.gbl (2a01:111:f400:7c10::1:118) by BY2PR03CA048.outlook.office365.com (2a01:111:e400:2c5d::21) with Microsoft SMTP Server (TLS) id 15.1.6.9 via Frontend Transport; Tue, 28 Oct 2014 09:41:58 +0000 Received: from az84smr01.freescale.net (192.88.158.2) by BN1BFFO11FD031.mail.protection.outlook.com (10.58.144.94) with Microsoft SMTP Server (TLS) id 15.0.1049.20 via Frontend Transport; Tue, 28 Oct 2014 09:41:57 +0000 Received: from [az84smr01.freescale.net ([10.192.185.118]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id s9S9fkTl015460; Tue, 28 Oct 2014 02:41:52 -0700 From: Ye.Li To: Date: Tue, 28 Oct 2014 17:40:34 +0800 Message-ID: <1414489238-3947-1-git-send-email-B37916@freescale.com> X-Mailer: git-send-email 1.7.4.1 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:CAL; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(189002)(199003)(46102003)(99396003)(69596002)(19580395003)(68736004)(77096002)(102836001)(19580405001)(89996001)(48376002)(6806004)(104166001)(92726001)(85852003)(80022003)(50466002)(76482002)(47776003)(20776003)(4396001)(88136002)(36756003)(50226001)(92566001)(84676001)(77156001)(85306004)(93916002)(81156004)(106466001)(229853001)(87286001)(110136001)(50986999)(87936001)(21056001)(2351001)(105606002)(26826002)(44976005)(97736003)(120916001)(62966002)(104016003)(64706001)(95666004)(107046002)(31966008); DIR:OUT; SFP:1102; SCL:1; SRVR:BY2PR03MB255; H:az84smr01.freescale.net; FPR:; MLV:ovrnspm; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Antispam: UriScan:; X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;SRVR:BY2PR03MB255; X-Forefront-PRVS: 0378F1E47A Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=Ye.Li@freescale.com; X-OriginatorOrg: freescale.com Cc: fabio.estevam@freescale.com, u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 1/5] imx: gpt: Add High frequency clock source support for GPT X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.13 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Introduce a new configuration "CONFIG_MXC_GPT_HCLK". When it is set, the GPT will select a high frequency clock as clock source. Otherwise, the GPT will stay to use 32Khz OSC as clock source. In the implementation, since only the GPT on i.MX6 series provide the clock source option for 24Mhz OSC. For others (only i.MX5 and i.MX6 compile the driver), if the configuration is set, the perclk will be selected as clock source. MX6Q/D Rev 1.0 and MX6SL are special in the implementation, because they don't have the 24Mhz OSC clock source option, so also select the perclk for them. For MX6SL, we will set the OSC 24Mhz to perclk in CCM, so eventually the clock comes from OSC 24Mhz. Signed-off-by: Ye.Li --- Changes since v1: - Modify the patch message content to clear the implementation. - Remove the change for copyright date. arch/arm/imx-common/timer.c | 74 +++++++++++++++++++++++++++++++++++++----- 1 files changed, 65 insertions(+), 9 deletions(-) diff --git a/arch/arm/imx-common/timer.c b/arch/arm/imx-common/timer.c index c63f78f..aec0566 100644 --- a/arch/arm/imx-common/timer.c +++ b/arch/arm/imx-common/timer.c @@ -12,6 +12,7 @@ #include #include #include +#include /* General purpose timers registers */ struct mxc_gpt { @@ -26,23 +27,60 @@ static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR; /* General purpose timers bitfields */ #define GPTCR_SWR (1 << 15) /* Software reset */ +#define GPTCR_24MEN (1 << 10) /* Enable 24MHz clock input from crystal */ #define GPTCR_FRR (1 << 9) /* Freerun / restart */ -#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */ +#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source 32khz */ +#define GPTCR_CLKSOURCE_OSC (5 << 6) /* Clock source OSC */ +#define GPTCR_CLKSOURCE_PRE (1 << 6) /* Clock source PRECLK */ +#define GPTCR_CLKSOURCE_MASK (0x7 << 6) #define GPTCR_TEN 1 /* Timer enable */ +#define GPTPR_PRESCALER24M_SHIFT 12 +#define GPTPR_PRESCALER24M_MASK (0xF << GPTPR_PRESCALER24M_SHIFT) + DECLARE_GLOBAL_DATA_PTR; +static inline int gpt_has_clk_source_osc(void) +{ +#if defined(CONFIG_MX6) + if (((is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) + && (is_soc_rev(CHIP_REV_1_0) > 0)) + || is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO) + || is_cpu_type(MXC_CPU_MX6SX)) + return 1; + + return 0; +#else + return 0; +#endif +} + +static inline ulong gpt_get_clk(void) +{ +#ifdef CONFIG_MXC_GPT_HCLK + if (gpt_has_clk_source_osc()) + return MXC_HCLK >> 3; + else + return mxc_get_clock(MXC_IPG_PERCLK); +#else + return MXC_CLK32; +#endif +} static inline unsigned long long tick_to_time(unsigned long long tick) { + ulong gpt_clk = gpt_get_clk(); + tick *= CONFIG_SYS_HZ; - do_div(tick, MXC_CLK32); + do_div(tick, gpt_clk); return tick; } static inline unsigned long long us_to_tick(unsigned long long usec) { - usec = usec * MXC_CLK32 + 999999; + ulong gpt_clk = gpt_get_clk(); + + usec = usec * gpt_clk + 999999; do_div(usec, 1000000); return usec; @@ -59,11 +97,29 @@ int timer_init(void) for (i = 0; i < 100; i++) __raw_writel(0, &cur_gpt->control); - __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ - - /* Freerun Mode, PERCLK1 input */ i = __raw_readl(&cur_gpt->control); - __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control); + i &= ~GPTCR_CLKSOURCE_MASK; + +#ifdef CONFIG_MXC_GPT_HCLK + if (gpt_has_clk_source_osc()) { + i |= GPTCR_CLKSOURCE_OSC | GPTCR_TEN; + + /* For DL/S, SX, they has 24M OSC Enable bit and need to set prescaler */ + if (is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO) + || is_cpu_type(MXC_CPU_MX6SX)) { + i |= GPTCR_24MEN; + + /* Produce 3Mhz clock */ + __raw_writel((7 << GPTPR_PRESCALER24M_SHIFT), &cur_gpt->prescaler); + } + } else { + i |= GPTCR_CLKSOURCE_PRE | GPTCR_TEN; + } +#else + __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */ + i |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; +#endif + __raw_writel(i, &cur_gpt->control); gd->arch.tbl = __raw_readl(&cur_gpt->counter); gd->arch.tbu = 0; @@ -86,7 +142,7 @@ ulong get_timer_masked(void) { /* * get_ticks() returns a long long (64 bit), it wraps in - * 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ + * 2^64 / GPT_CLK = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in * 5 * 10^6 days - long enough. */ @@ -117,5 +173,5 @@ void __udelay(unsigned long usec) */ ulong get_tbclk(void) { - return MXC_CLK32; + return gpt_get_clk(); }