From patchwork Thu Mar 21 14:58:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anson Huang X-Patchwork-Id: 2310851 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 9AD5040213 for ; Thu, 21 Mar 2013 02:01:30 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UIUlr-0003la-9y; Thu, 21 Mar 2013 01:58:23 +0000 Received: from db3ehsobe002.messaging.microsoft.com ([213.199.154.140] helo=db3outboundpool.messaging.microsoft.com) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UIUlm-0003k7-Uu for linux-arm-kernel@lists.infradead.org; Thu, 21 Mar 2013 01:58:20 +0000 Received: from mail2-db3-R.bigfish.com (10.3.81.241) by DB3EHSOBE005.bigfish.com (10.3.84.25) with Microsoft SMTP Server id 14.1.225.23; Thu, 21 Mar 2013 01:58:10 +0000 Received: from mail2-db3 (localhost [127.0.0.1]) by mail2-db3-R.bigfish.com (Postfix) with ESMTP id EF706440231; Thu, 21 Mar 2013 01:58:09 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 3 X-BigFish: VS3(zzzz1f42h1ee6h1de0h1202h1e76h1d1ah1d2ah1082kzz8275bhz2dh2a8h668h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1155h) Received: from mail2-db3 (localhost.localdomain [127.0.0.1]) by mail2-db3 (MessageSwitch) id 1363831088633789_6497; Thu, 21 Mar 2013 01:58:08 +0000 (UTC) Received: from DB3EHSMHS002.bigfish.com (unknown [10.3.81.226]) by mail2-db3.bigfish.com (Postfix) with ESMTP id 8E6E32C0086; Thu, 21 Mar 2013 01:58:08 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by DB3EHSMHS002.bigfish.com (10.3.87.102) with Microsoft SMTP Server (TLS) id 14.1.225.23; Thu, 21 Mar 2013 01:58:08 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-005.039d.mgd.msft.net (10.84.1.17) with Microsoft SMTP Server (TLS) id 14.2.328.11; Thu, 21 Mar 2013 01:58:05 +0000 Received: from ubuntu.ap.freescale.net (ubuntu.ap.freescale.net [10.192.242.118]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id r2L1w3ul030912; Wed, 20 Mar 2013 18:58:04 -0700 From: Anson Huang To: Subject: [PATCH V3 3/3] ARM: imx: enable RBC to support anatop LPM mode Date: Thu, 21 Mar 2013 10:58:06 -0400 Message-ID: <1363877886-26538-1-git-send-email-b20788@freescale.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130320_215819_199123_1658EDBC X-CRM114-Status: GOOD ( 15.98 ) X-Spam-Score: 0.6 (/) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (0.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [213.199.154.140 listed in list.dnswl.org] 3.2 DATE_IN_FUTURE_12_24 Date: is 12 to 24 hours after Received: date -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: shawn.guo@linaro.org, linux@arm.linux.org.uk, kernel@pengutronix.de X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org RBC is to control whether some ANATOP sub modules can enter lpm mode when SOC is into STOP mode, if RBC is enabled and PMIC_VSTBY_REQ is set, ANATOP will have below behaviors: 1. Digital LDOs(CORE, SOC and PU) are bypassed; 2. Analog LDOs(1P1, 2P5, 3P0) are disabled; As the 2P5 is necessary for DRAM IO pre-drive in STOP mode, so we need to enable weak 2P5 in STOP mode when 2P5 LDO is disabled. For RBC settings, there are some rules as below due to hardware design: 1. All interrupts must be masked during operating RBC registers; 2. At least 2 CKIL(32K) cycles is needed after the RBC setting is changed. Signed-off-by: Anson Huang --- arch/arm/mach-imx/anatop.c | 19 ++++++++++++++++++ arch/arm/mach-imx/clk-imx6q.c | 43 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/common.h | 2 ++ arch/arm/mach-imx/gpc.c | 23 +++++++++++++++++++++- 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index b396b92..8b18b3c 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -19,17 +19,34 @@ #define REG_SET 0x4 #define REG_CLR 0x8 +#define ANADIG_REG_2P5 0x130 #define ANADIG_REG_CORE 0x140 +#define ANADIG_ANA_MISC0 0x150 #define ANADIG_USB1_CHRG_DETECT 0x1b0 #define ANADIG_USB2_CHRG_DETECT 0x210 #define ANADIG_DIGPROG 0x260 +#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 #define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000 #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 static struct regmap *anatop; +static void imx_anatop_enable_weak2p5(bool enable) +{ + u32 reg, val; + + regmap_read(anatop, ANADIG_ANA_MISC0, &val); + + /* can only be enabled when stop_mode_config is clear. */ + reg = ANADIG_REG_2P5; + reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ? + REG_SET : REG_CLR; + regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG); +} + static void imx_anatop_enable_fet_odrive(bool enable) { regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR), @@ -38,12 +55,14 @@ static void imx_anatop_enable_fet_odrive(bool enable) void imx_anatop_pre_suspend(void) { + imx_anatop_enable_weak2p5(true); imx_anatop_enable_fet_odrive(true); } void imx_anatop_post_resume(void) { imx_anatop_enable_fet_odrive(false); + imx_anatop_enable_weak2p5(false); } void imx_anatop_usb_chrg_detect_disable(void) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 96ed9a3..d20306c 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,8 @@ #define CCR 0x0 #define BM_CCR_WB_COUNT (0x7 << 16) +#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21) +#define BM_CCR_RBC_EN (0x1 << 27) #define CCGR0 0x68 #define CCGR1 0x6c @@ -70,6 +73,44 @@ void imx6q_set_chicken_bit(void) writel_relaxed(val, ccm_base + CGPR); } +static void imx6q_enable_rbc(bool enable) +{ + u32 val; + static bool last_rbc_mode; + + if (last_rbc_mode == enable) + return; + /* + * need to mask all interrupts in GPC before + * operating RBC configurations + */ + imx_gpc_mask_all(); + + /* configure RBC enable bit */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_EN; + val |= enable ? BM_CCR_RBC_EN : 0; + writel_relaxed(val, ccm_base + CCR); + + /* configure RBC count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_BYPASS_COUNT; + val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0; + writel(val, ccm_base + CCR); + + /* + * need to delay at least 2 cycles of CKIL(32K) + * due to hardware design requirement, which is + * ~61us, here we use 65us for safe + */ + udelay(65); + + /* restore GPC interrupt mask settings */ + imx_gpc_restore_all(); + + last_rbc_mode = enable; +} + static void imx6q_enable_wb(bool enable) { u32 val; @@ -101,6 +142,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) switch (mode) { case WAIT_CLOCKED: imx6q_enable_wb(false); + imx6q_enable_rbc(false); break; case WAIT_UNCLOCKED: val |= 0x1 << BP_CLPCR_LPM; @@ -120,6 +162,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) val |= BM_CLPCR_VSTBY; val |= BM_CLPCR_SBYOS; imx6q_enable_wb(true); + imx6q_enable_rbc(true); break; default: return -EINVAL; diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 69451a9..4494169 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -129,6 +129,8 @@ extern void imx_src_prepare_restart(void); extern void imx_gpc_init(void); extern void imx_gpc_pre_suspend(void); extern void imx_gpc_post_resume(void); +extern void imx_gpc_mask_all(void); +extern void imx_gpc_restore_all(void); extern void imx_anatop_init(void); extern void imx_anatop_pre_suspend(void); extern void imx_anatop_post_resume(void); diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index a96ccc7..c20445c 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -68,6 +68,27 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } +void imx_gpc_mask_all(void) +{ + void __iomem *reg_imr1 = gpc_base + GPC_IMR1; + int i; + + for (i = 0; i < IMR_NUM; i++) { + gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4); + writel_relaxed(~0, reg_imr1 + i * 4); + } + +} + +void imx_gpc_restore_all(void) +{ + void __iomem *reg_imr1 = gpc_base + GPC_IMR1; + int i; + + for (i = 0; i < IMR_NUM; i++) + writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); +} + static void imx_gpc_irq_unmask(struct irq_data *d) { void __iomem *reg;