Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1117687/?format=api
{ "id": 1117687, "url": "http://patchwork.ozlabs.org/api/patches/1117687/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/1560843991-24123-12-git-send-email-skomatineni@nvidia.com/", "project": { "id": 42, "url": "http://patchwork.ozlabs.org/api/projects/42/?format=api", "name": "Linux GPIO development", "link_name": "linux-gpio", "list_id": "linux-gpio.vger.kernel.org", "list_email": "linux-gpio@vger.kernel.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1560843991-24123-12-git-send-email-skomatineni@nvidia.com>", "list_archive_url": null, "date": "2019-06-18T07:46:25", "name": "[V3,11/17] clk: tegra210: support for Tegra210 clocks suspend and resume", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "511ed878a978c110407fcd5f0e4e74feaf61b52d", "submitter": { "id": 75554, "url": "http://patchwork.ozlabs.org/api/people/75554/?format=api", "name": "Sowjanya Komatineni", "email": "skomatineni@nvidia.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-gpio/patch/1560843991-24123-12-git-send-email-skomatineni@nvidia.com/mbox/", "series": [ { "id": 114436, "url": "http://patchwork.ozlabs.org/api/series/114436/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/list/?series=114436", "date": "2019-06-18T07:46:16", "name": "SC7 entry and exit support for Tegra210", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/114436/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1117687/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1117687/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<linux-gpio-owner@vger.kernel.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=linux-gpio-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=pass (p=none dis=none) header.from=nvidia.com", "ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=nvidia.com header.i=@nvidia.com\n\theader.b=\"DWI6L8Ui\"; dkim-atps=neutral" ], "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 45SgCx4DmPz9s4V\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 18 Jun 2019 17:47:41 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1729110AbfFRHrI (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tTue, 18 Jun 2019 03:47:08 -0400", "from hqemgate16.nvidia.com ([216.228.121.65]:14155 \"EHLO\n\thqemgate16.nvidia.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1729140AbfFRHrH (ORCPT\n\t<rfc822; linux-gpio@vger.kernel.org>); Tue, 18 Jun 2019 03:47:07 -0400", "from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by\n\thqemgate16.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA)\n\tid <B5d0896f80001>; Tue, 18 Jun 2019 00:47:04 -0700", "from hqmail.nvidia.com ([172.20.161.6])\n\tby hqpgpgate102.nvidia.com (PGP Universal service);\n\tTue, 18 Jun 2019 00:47:05 -0700", "from HQMAIL110.nvidia.com (172.18.146.15) by HQMAIL107.nvidia.com\n\t(172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3;\n\tTue, 18 Jun 2019 07:47:04 +0000", "from HQMAIL108.nvidia.com (172.18.146.13) by hqmail110.nvidia.com\n\t(172.18.146.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3;\n\tTue, 18 Jun 2019 07:47:04 +0000", "from hqnvemgw02.nvidia.com (172.16.227.111) by HQMAIL108.nvidia.com\n\t(172.18.146.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via\n\tFrontend Transport; Tue, 18 Jun 2019 07:47:03 +0000", "from skomatineni-linux.nvidia.com (Not Verified[10.2.168.217]) by\n\thqnvemgw02.nvidia.com with Trustwave SEG (v7, 5, 8, 10121)\n\tid <B5d0896f50004>; Tue, 18 Jun 2019 00:47:04 -0700" ], "X-PGP-Universal": "processed;\n\tby hqpgpgate102.nvidia.com on Tue, 18 Jun 2019 00:47:05 -0700", "From": "Sowjanya Komatineni <skomatineni@nvidia.com>", "To": "<thierry.reding@gmail.com>, <jonathanh@nvidia.com>,\n\t<tglx@linutronix.de>, <jason@lakedaemon.net>,\n\t<marc.zyngier@arm.com>, <linus.walleij@linaro.org>,\n\t<stefan@agner.ch>, <mark.rutland@arm.com>", "CC": "<pdeschrijver@nvidia.com>, <pgaikwad@nvidia.com>,\n\t<sboyd@kernel.org>, <linux-clk@vger.kernel.org>,\n\t<linux-gpio@vger.kernel.org>, <jckuo@nvidia.com>,\n\t<josephl@nvidia.com>, <talho@nvidia.com>, <skomatineni@nvidia.com>,\n\t<linux-tegra@vger.kernel.org>, <linux-kernel@vger.kernel.org>,\n\t<mperttunen@nvidia.com>, <spatra@nvidia.com>, <robh+dt@kernel.org>,\n\t<digetx@gmail.com>, <devicetree@vger.kernel.org>", "Subject": "[PATCH V3 11/17] clk: tegra210: support for Tegra210 clocks suspend\n\tand resume", "Date": "Tue, 18 Jun 2019 00:46:25 -0700", "Message-ID": "<1560843991-24123-12-git-send-email-skomatineni@nvidia.com>", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": "<1560843991-24123-1-git-send-email-skomatineni@nvidia.com>", "References": "<1560843991-24123-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;\n\tt=1560844024; bh=SGcqTwvLQqwf1tE0nNYcxmB0duJ1Yuf1/djbG6n28AE=;\n\th=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer:\n\tIn-Reply-To:References:X-NVConfidentiality:MIME-Version:\n\tContent-Type;\n\tb=DWI6L8UiRvOIoa3VkwUYVGNn1EyJJhVBini8WE2AIFGM9hdSlJHvD9XLa/nVnTwAK\n\t4p4jmrN/fnoM1exu97UXMoYrmsazlXEod4ifZOs/LAywWxqX+TSt4+k5+o/+mTsu8r\n\tMsI8C1Jhips8SFjJAzWS5Kw1RbGqHxr6ffCS3TS9gm9tYDnLu/XmtYzYhwZtK4mdzR\n\tO20G6sKIpoAmkmlfOKnfee+EtP++tJ95GJ51TizktV0qlQFlhBoyAbr/jtUyfsgA4U\n\tiVzMx4AtnsdFgR3Nct8rVxDvq+v/L89spqvxEPyFtvDq829dggwWtESUJLKdF4WHEN\n\tuxvf6PbgOedhw==", "Sender": "linux-gpio-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<linux-gpio.vger.kernel.org>", "X-Mailing-List": "linux-gpio@vger.kernel.org" }, "content": "This patch adds system suspend and resume support for Tegra210\nclocks.\n\nAll the CAR controller settings are lost on suspend when core power\ngoes off.\n\nThis patch has implementation for saving and restoring all the PLLs\nand clocks context during system suspend and resume to have the\nsystem back to operating state.\n\nSigned-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>\n---\n drivers/clk/tegra/clk-tegra210.c | 218 +++++++++++++++++++++++++++++++++++++--\n 1 file changed, 211 insertions(+), 7 deletions(-)", "diff": "diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c\nindex e1ba62d2b1a0..c34d92e871f4 100644\n--- a/drivers/clk/tegra/clk-tegra210.c\n+++ b/drivers/clk/tegra/clk-tegra210.c\n@@ -9,10 +9,12 @@\n #include <linux/clkdev.h>\n #include <linux/of.h>\n #include <linux/of_address.h>\n+#include <linux/of_platform.h>\n #include <linux/delay.h>\n #include <linux/export.h>\n #include <linux/mutex.h>\n #include <linux/clk/tegra.h>\n+#include <linux/syscore_ops.h>\n #include <dt-bindings/clock/tegra210-car.h>\n #include <dt-bindings/reset/tegra210-car.h>\n #include <linux/iopoll.h>\n@@ -20,6 +22,7 @@\n #include <soc/tegra/pmc.h>\n \n #include \"clk.h\"\n+#include \"clk-dfll.h\"\n #include \"clk-id.h\"\n \n /*\n@@ -36,6 +39,8 @@\n #define CLK_SOURCE_LA 0x1f8\n #define CLK_SOURCE_SDMMC2 0x154\n #define CLK_SOURCE_SDMMC4 0x164\n+#define CLK_OUT_ENB_Y 0x298\n+#define CLK_ENB_PLLP_OUT_CPU BIT(31)\n \n #define PLLC_BASE 0x80\n #define PLLC_OUT 0x84\n@@ -225,6 +230,7 @@\n \n #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8\n #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac\n+#define CPU_SOFTRST_CTRL 0x380\n \n #define LVL2_CLK_GATE_OVRA 0xf8\n #define LVL2_CLK_GATE_OVRC 0x3a0\n@@ -2820,6 +2826,7 @@ static int tegra210_enable_pllu(void)\n \tstruct tegra_clk_pll_freq_table *fentry;\n \tstruct tegra_clk_pll pllu;\n \tu32 reg;\n+\tint ret;\n \n \tfor (fentry = pll_u_freq_table; fentry->input_rate; fentry++) {\n \t\tif (fentry->input_rate == pll_ref_freq)\n@@ -2836,7 +2843,7 @@ static int tegra210_enable_pllu(void)\n \treg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]);\n \treg &= ~BIT(pllu.params->iddq_bit_idx);\n \twritel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]);\n-\tudelay(5);\n+\tfence_udelay(5, clk_base);\n \n \treg = readl_relaxed(clk_base + PLLU_BASE);\n \treg &= ~GENMASK(20, 0);\n@@ -2844,13 +2851,13 @@ static int tegra210_enable_pllu(void)\n \treg |= fentry->n << 8;\n \treg |= fentry->p << 16;\n \twritel(reg, clk_base + PLLU_BASE);\n-\tudelay(1);\n+\tfence_udelay(1, clk_base);\n \treg |= PLL_ENABLE;\n \twritel(reg, clk_base + PLLU_BASE);\n+\tfence_udelay(1, clk_base);\n \n-\treadl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg,\n-\t\t\t\t\t reg & PLL_BASE_LOCK, 2, 1000);\n-\tif (!(reg & PLL_BASE_LOCK)) {\n+\tret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK);\n+\tif (ret) {\n \t\tpr_err(\"Timed out waiting for PLL_U to lock\\n\");\n \t\treturn -ETIMEDOUT;\n \t}\n@@ -2890,12 +2897,12 @@ static int tegra210_init_pllu(void)\n \t\treg = readl_relaxed(clk_base + XUSB_PLL_CFG0);\n \t\treg &= ~XUSB_PLL_CFG0_PLLU_LOCK_DLY_MASK;\n \t\twritel_relaxed(reg, clk_base + XUSB_PLL_CFG0);\n-\t\tudelay(1);\n+\t\tfence_udelay(1, clk_base);\n \n \t\treg = readl_relaxed(clk_base + PLLU_HW_PWRDN_CFG0);\n \t\treg |= PLLU_HW_PWRDN_CFG0_SEQ_ENABLE;\n \t\twritel_relaxed(reg, clk_base + PLLU_HW_PWRDN_CFG0);\n-\t\tudelay(1);\n+\t\tfence_udelay(1, clk_base);\n \n \t\treg = readl_relaxed(clk_base + PLLU_BASE);\n \t\treg &= ~PLLU_BASE_CLKENABLE_USB;\n@@ -3282,6 +3289,188 @@ static void tegra210_disable_cpu_clock(u32 cpu)\n }\n \n #ifdef CONFIG_PM_SLEEP\n+static u32 cpu_softrst_ctx[3];\n+static struct platform_device *dfll_pdev;\n+static u32 *periph_clk_src_ctx;\n+struct periph_source_bank {\n+\tu32 start;\n+\tu32 end;\n+};\n+\n+static struct periph_source_bank periph_srcs[] = {\n+\t[0] = {\n+\t\t.start = 0x100,\n+\t\t.end = 0x198,\n+\t},\n+\t[1] = {\n+\t\t.start = 0x1a0,\n+\t\t.end = 0x1f8,\n+\t},\n+\t[2] = {\n+\t\t.start = 0x3b4,\n+\t\t.end = 0x42c,\n+\t},\n+\t[3] = {\n+\t\t.start = 0x49c,\n+\t\t.end = 0x4b4,\n+\t},\n+\t[4] = {\n+\t\t.start = 0x560,\n+\t\t.end = 0x564,\n+\t},\n+\t[5] = {\n+\t\t.start = 0x600,\n+\t\t.end = 0x678,\n+\t},\n+\t[6] = {\n+\t\t.start = 0x694,\n+\t\t.end = 0x6a0,\n+\t},\n+\t[7] = {\n+\t\t.start = 0x6b8,\n+\t\t.end = 0x718,\n+\t},\n+};\n+\n+/* This array lists the valid clocks for each periph clk bank */\n+static u32 periph_clks_on[] = {\n+\t0xdcd7dff9,\n+\t0x87d1f3e7,\n+\t0xf3fed3fa,\n+\t0xffc18cfb,\n+\t0x793fb7ff,\n+\t0x3fe66fff,\n+\t0xfc1fc7ff,\n+};\n+\n+static struct platform_device *dfll_pdev;\n+#define car_readl(_base, _off) readl_relaxed(clk_base + (_base) + ((_off) * 4))\n+#define car_writel(_val, _base, _off) \\\n+\t\twritel_relaxed(_val, clk_base + (_base) + ((_off) * 4))\n+\n+static u32 * __init tegra210_init_suspend_ctx(void)\n+{\n+\tint i, size = 0;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(periph_srcs); i++)\n+\t\tsize += periph_srcs[i].end - periph_srcs[i].start + 4;\n+\n+\tperiph_clk_src_ctx = kmalloc(size, GFP_KERNEL);\n+\n+\treturn periph_clk_src_ctx;\n+}\n+\n+static int tegra210_clk_suspend(void)\n+{\n+\tint i;\n+\tunsigned long off;\n+\tstruct device_node *node;\n+\tu32 *clk_rst_ctx = periph_clk_src_ctx;\n+\tu32 val;\n+\n+\ttegra_cclkg_burst_policy_save_context();\n+\n+\tif (!dfll_pdev) {\n+\t\tnode = of_find_compatible_node(NULL, NULL,\n+\t\t\t\t\t \"nvidia,tegra210-dfll\");\n+\t\tif (node)\n+\t\t\tdfll_pdev = of_find_device_by_node(node);\n+\t\tof_node_put(node);\n+\t\tif (!dfll_pdev)\n+\t\t\tpr_err(\"dfll node not found. no suspend for dfll\\n\");\n+\t}\n+\n+\tif (dfll_pdev)\n+\t\ttegra_dfll_suspend(dfll_pdev);\n+\n+\t/* Enable PLLP_OUT_CPU after dfll suspend */\n+\tval = car_readl(CLK_OUT_ENB_Y, 0);\n+\tval |= CLK_ENB_PLLP_OUT_CPU;\n+\tcar_writel(val, CLK_OUT_ENB_Y, 0);\n+\n+\ttegra_clk_periph_suspend(clk_base);\n+\n+\tfor (i = 0; i < ARRAY_SIZE(periph_srcs); i++)\n+\t\tfor (off = periph_srcs[i].start; off <= periph_srcs[i].end;\n+\t\t off += 4)\n+\t\t\t*clk_rst_ctx++ = car_readl(off, 0);\n+\n+\ttegra_sclk_cclklp_burst_policy_save_context();\n+\n+\tfor (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)\n+\t\tcpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i);\n+\n+\tclk_save_context();\n+\n+\treturn 0;\n+}\n+\n+static void tegra210_clk_resume(void)\n+{\n+\tint i;\n+\tunsigned long off;\n+\tu32 val;\n+\tu32 *clk_rst_ctx = periph_clk_src_ctx;\n+\tstruct clk_hw *parent;\n+\tstruct clk *clk;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)\n+\t\tcar_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i);\n+\n+\ttegra_clk_osc_resume(clk_base);\n+\n+\t/*\n+\t * restore all the plls before configuring clocks and resetting\n+\t * the devices.\n+\t */\n+\ttegra210_init_pllu();\n+\ttegra_sclk_cpulp_burst_policy_restore_context();\n+\tclk_restore_context();\n+\n+\t/* enable all clocks before configuring clock sources */\n+\ttegra_clk_periph_force_on(periph_clks_on, ARRAY_SIZE(periph_clks_on),\n+\t\t\t\t clk_base);\n+\t/* wait for all writes to happen to have all the clocks enabled */\n+\twmb();\n+\tfence_udelay(2, clk_base);\n+\n+\t/* restore all the devices clock sources */\n+\tfor (i = 0; i < ARRAY_SIZE(periph_srcs); i++)\n+\t\tfor (off = periph_srcs[i].start; off <= periph_srcs[i].end;\n+\t\t off += 4)\n+\t\t\tcar_writel(*clk_rst_ctx++, off, 0);\n+\n+\t/* propagate and restore resets, restore clock state */\n+\tfence_udelay(5, clk_base);\n+\ttegra_clk_periph_resume(clk_base);\n+\n+\t/*\n+\t * restore CPUG clocks:\n+\t * - enable DFLL in open loop mode\n+\t * - switch CPUG to DFLL clock source\n+\t * - close DFLL loop\n+\t * - sync PLLX state\n+\t */\n+\tif (dfll_pdev)\n+\t\ttegra_dfll_resume(dfll_pdev, false);\n+\n+\ttegra_cclkg_burst_policy_restore_context();\n+\tfence_udelay(2, clk_base);\n+\n+\tif (dfll_pdev)\n+\t\ttegra_dfll_resume(dfll_pdev, true);\n+\n+\tparent = clk_hw_get_parent(__clk_get_hw(clks[TEGRA210_CLK_CCLK_G]));\n+\tclk = clks[TEGRA210_CLK_PLL_X];\n+\tif (parent != __clk_get_hw(clk))\n+\t\ttegra_clk_sync_state_pll(__clk_get_hw(clk));\n+\n+\t/* Disable PLL_OUT_CPU after DFLL resume */\n+\tval = car_readl(CLK_OUT_ENB_Y, 0);\n+\tval &= ~CLK_ENB_PLLP_OUT_CPU;\n+\tcar_writel(val, CLK_OUT_ENB_Y, 0);\n+}\n+\n static void tegra210_cpu_clock_suspend(void)\n {\n \t/* switch coresite to clk_m, save off original source */\n@@ -3295,8 +3484,20 @@ static void tegra210_cpu_clock_resume(void)\n \twritel(tegra210_cpu_clk_sctx.clk_csite_src,\n \t\t\t\tclk_base + CLK_SOURCE_CSITE);\n }\n+#else\n+#define tegra210_clk_suspend\tNULL\n+#define tegra210_clk_resume\tNULL\n+static inline u32 *tegra210_init_suspend_ctx(void)\n+{\n+\treturn NULL;\n+}\n #endif\n \n+static struct syscore_ops tegra_clk_syscore_ops = {\n+\t.suspend = tegra210_clk_suspend,\n+\t.resume = tegra210_clk_resume,\n+};\n+\n static struct tegra_cpu_car_ops tegra210_cpu_car_ops = {\n \t.wait_for_reset\t= tegra210_wait_cpu_in_reset,\n \t.disable_clock\t= tegra210_disable_cpu_clock,\n@@ -3580,5 +3781,8 @@ static void __init tegra210_clock_init(struct device_node *np)\n \ttegra210_mbist_clk_init();\n \n \ttegra_cpu_car_ops = &tegra210_cpu_car_ops;\n+\n+\tif (tegra210_init_suspend_ctx())\n+\t\tregister_syscore_ops(&tegra_clk_syscore_ops);\n }\n CLK_OF_DECLARE(tegra210, \"nvidia,tegra210-car\", tegra210_clock_init);\n", "prefixes": [ "V3", "11/17" ] }