Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp6424607ybi; Wed, 31 Jul 2019 14:13:31 -0700 (PDT) X-Google-Smtp-Source: APXvYqwDzqz4PlgK7GVoMDKgFoaS6KErdz1SyA6GJOY8WHKL94O435gepMqMpjCzMLvqLVbpvmMz X-Received: by 2002:a65:4304:: with SMTP id j4mr118353946pgq.419.1564607611166; Wed, 31 Jul 2019 14:13:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564607611; cv=none; d=google.com; s=arc-20160816; b=0yYLV0Ll7MX1+Kg2/E/oX+Gp/2Ud3rfiPOBYG5Qs4HI+Qs0AChI1veTAkiZ9Rgqyxj 7Ad3BID6ogdvwHinarh4zFrFg/JhU1ETJB25mFntIW4r/qpX5FQBPcgojR54desMyXed 8qhDGKplFUycY6D6Jid7ghCnScrgNvbby9C4PF4vXjK/SFOqow8G6MuN4O82tH9dF2aI Vnki0Njr1eAHMxgEQXrG+1aEV0OJ5WTwqFZDUtDByO3crlHgvT8QY4W88Yj2DHxBNteX Xo1NREx7NkiNae+94PGcWdayQqsPuZ/4vF0eJmqSX0iX8glPFOOoNLWBr70UWdqWxSYw NZ3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:dkim-signature:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from; bh=gPK8lOd2L0E8wxNUkaQDExJ9pyS50gN50iD6gfS3XN4=; b=TCsSd44fjtVt2tYN3iR5AOiSU2jshnUCVP103eMCZ9YQVXaQdjNsbojaY60FPgZCFy 9kdclQW9VScKeIejt+2gK/7n7EQlJ+Xd/Gzit5RIrryc918p40dNEQ2HnxXm9/9SNczh eOPI0tEssBlTvYm4ZyZ2tt0jOJwHjDZrWzoIPnSJQPIgu8ff+RoReXh7Jt7aVLyBy1We Xh12kxQX/oOvxZ77dciZKUlvMPALn792hKRSm40szXlq5ps/gMm0JKBeMCQNGf2vE9yW mCp3oI48JjBCFEylivfIRsA3g2bbe0Whr0ESUMAJndYaVcz0NvOebFNcCIXrNUQ1GwHn mz/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="K9/ouEn9"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q10si2297742pjq.46.2019.07.31.14.13.16; Wed, 31 Jul 2019 14:13:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="K9/ouEn9"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731047AbfGaVMT (ORCPT + 99 others); Wed, 31 Jul 2019 17:12:19 -0400 Received: from hqemgate14.nvidia.com ([216.228.121.143]:17166 "EHLO hqemgate14.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730391AbfGaVLK (ORCPT ); Wed, 31 Jul 2019 17:11:10 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate14.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 31 Jul 2019 14:11:10 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Wed, 31 Jul 2019 14:11:09 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Wed, 31 Jul 2019 14:11:09 -0700 Received: from HQMAIL101.nvidia.com (172.20.187.10) by HQMAIL105.nvidia.com (172.20.187.12) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 31 Jul 2019 21:11:08 +0000 Received: from hqnvemgw01.nvidia.com (172.20.150.20) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 31 Jul 2019 21:11:08 +0000 Received: from skomatineni-linux.nvidia.com (Not Verified[10.110.102.167]) by hqnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Wed, 31 Jul 2019 14:11:08 -0700 From: Sowjanya Komatineni To: , , , , , , , CC: , , , , , , , , , , , , , , , , , , Subject: [PATCH v7 13/20] clk: tegra210: Add suspend and resume support Date: Wed, 31 Jul 2019 14:10:56 -0700 Message-ID: <1564607463-28802-14-git-send-email-skomatineni@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564607463-28802-1-git-send-email-skomatineni@nvidia.com> References: <1564607463-28802-1-git-send-email-skomatineni@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 Content-Type: text/plain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1564607470; bh=gPK8lOd2L0E8wxNUkaQDExJ9pyS50gN50iD6gfS3XN4=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=K9/ouEn9Rx130msTfqblTq7y1CQgPNayS0WfCsvqOB4JxhMUyZKb36KIRPJ1We255 rm7x9Wy7pH+75JWpk6SBSVU163RCQ99CvMOTm9bFwD/zbiB8y0GzIFuVg7ndkuU/9k ip2DQmlOeECMZUCy/q9uY3gjpSVZOCkKnxXkCrTGSmD1lXxe0W1CnvyIeVJyG8ieyW yvIEecP174Til9s2U+Q+CkFa0HqjpvbE1yrDlEM/ueNiodlq3uOkHoRHGQ6y+Mk0t1 XNeBkNj6coHSDG6AYX0pDLSqo4N87lbH+M0fN1jNJs7gKtElfEpAMe16cqtFekuBZ1 sKlMs5eQ8oKEA== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds support for clk: tegra210: suspend-resume. All the CAR controller settings are lost on suspend when core power goes off. This patch has implementation for saving and restoring all PLLs and clocks context during system suspend and resume to have the clocks back to same state for normal operation. Clock driver suspend and resume are registered as syscore_ops as clocks restore need to happen before the other drivers resume to have all their clocks back to the same state as before suspend. Signed-off-by: Sowjanya Komatineni --- drivers/clk/tegra/clk-tegra210.c | 75 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 998bf60b219a..14ea9f373a84 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -9,13 +9,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include @@ -220,11 +220,15 @@ #define CLK_M_DIVISOR_SHIFT 2 #define CLK_M_DIVISOR_MASK 0x3 +#define CLK_MASK_ARM 0x44 +#define MISC_CLK_ENB 0x48 + #define RST_DFLL_DVCO 0x2f4 #define DVFS_DFLL_RESET_SHIFT 0 #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8 #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac +#define CPU_SOFTRST_CTRL 0x380 #define LVL2_CLK_GATE_OVRA 0xf8 #define LVL2_CLK_GATE_OVRC 0x3a0 @@ -2825,6 +2829,7 @@ static int tegra210_enable_pllu(void) struct tegra_clk_pll_freq_table *fentry; struct tegra_clk_pll pllu; u32 reg; + int ret; for (fentry = pll_u_freq_table; fentry->input_rate; fentry++) { if (fentry->input_rate == pll_ref_freq) @@ -2853,9 +2858,14 @@ static int tegra210_enable_pllu(void) reg |= PLL_ENABLE; writel(reg, clk_base + PLLU_BASE); - readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg, - reg & PLL_BASE_LOCK, 2, 1000); - if (!(reg & PLL_BASE_LOCK)) { + /* + * During clock resume syscore operation, same PLLU init and enable + * routines gets invoked. So, readx_poll_timeout_atomic can't be used + * here as it uses ktime_get() and timekeeping resume doesn't happen + * by that time. So, using tegra210_wait_for_mask for PLL LOCK. + */ + ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK); + if (ret) { pr_err("Timed out waiting for PLL_U to lock\n"); return -ETIMEDOUT; } @@ -3288,6 +3298,56 @@ static void tegra210_disable_cpu_clock(u32 cpu) } #ifdef CONFIG_PM_SLEEP +#define car_readl(_base, _off) readl_relaxed(clk_base + (_base) + ((_off) * 4)) +#define car_writel(_val, _base, _off) \ + writel_relaxed(_val, clk_base + (_base) + ((_off) * 4)) + +static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx; +static u32 cpu_softrst_ctx[3]; + +static int tegra210_clk_suspend(void) +{ + unsigned int i; + + clk_save_context(); + + /* + * Save the bootloader configured clock registers SPARE_REG0, + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL. + */ + spare_reg_ctx = readl_relaxed(clk_base + SPARE_REG0); + misc_clk_enb_ctx = readl_relaxed(clk_base + MISC_CLK_ENB); + clk_msk_arm_ctx = readl_relaxed(clk_base + CLK_MASK_ARM); + + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++) + cpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i); + + return 0; +} + +static void tegra210_clk_resume(void) +{ + unsigned int i; + + tegra_clk_osc_resume(clk_base); + + /* + * Restore the bootloader configured clock registers SPARE_REG0, + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL from saved context. + */ + writel_relaxed(spare_reg_ctx, clk_base + SPARE_REG0); + writel_relaxed(misc_clk_enb_ctx, clk_base + MISC_CLK_ENB); + writel_relaxed(clk_msk_arm_ctx, clk_base + CLK_MASK_ARM); + + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++) + car_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i); + + fence_udelay(5, clk_base); + + tegra210_init_pllu(); + clk_restore_context(); +} + static void tegra210_cpu_clock_suspend(void) { /* switch coresite to clk_m, save off original source */ @@ -3303,6 +3363,11 @@ static void tegra210_cpu_clock_resume(void) } #endif +static struct syscore_ops tegra_clk_syscore_ops = { + .suspend = tegra210_clk_suspend, + .resume = tegra210_clk_resume, +}; + static struct tegra_cpu_car_ops tegra210_cpu_car_ops = { .wait_for_reset = tegra210_wait_cpu_in_reset, .disable_clock = tegra210_disable_cpu_clock, @@ -3587,5 +3652,7 @@ static void __init tegra210_clock_init(struct device_node *np) tegra210_mbist_clk_init(); tegra_cpu_car_ops = &tegra210_cpu_car_ops; + + register_syscore_ops(&tegra_clk_syscore_ops); } CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); -- 2.7.4