From patchwork Fri Apr 27 08:19:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Taniya Das X-Patchwork-Id: 10367701 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B124E601D3 for ; Fri, 27 Apr 2018 08:20:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A086C28471 for ; Fri, 27 Apr 2018 08:20:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 929AD29327; Fri, 27 Apr 2018 08:20:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AD66128471 for ; Fri, 27 Apr 2018 08:20:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757657AbeD0ITt (ORCPT ); Fri, 27 Apr 2018 04:19:49 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:38294 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757587AbeD0ITp (ORCPT ); Fri, 27 Apr 2018 04:19:45 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 972C060FEE; Fri, 27 Apr 2018 08:19:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1524817184; bh=2rGIftixQ8YW81TM2Scb8P3TV10sUBP7fZEZkFgCqi0=; h=From:To:Cc:Subject:Date:From; b=J6o4EpdJL2bGmrfZ8Oqx+R3T+K3YMT0CPErcxI2sj9vpUQ3PAwX0l+HCfp2woYTHb 1/TXzNa3UILsAbsibTCr3lfWusEMFFdssAiN6px1GFbudi2Mciyzf6i4GsErCZYNyW 8pNiMVJMkdKqBBukZkLVPZfwZWaH9YeDEKBavRyA= Received: from tdas-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: tdas@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id F324C60881; Fri, 27 Apr 2018 08:19:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1524817183; bh=2rGIftixQ8YW81TM2Scb8P3TV10sUBP7fZEZkFgCqi0=; h=From:To:Cc:Subject:Date:From; b=TixXbTd+boTrKSyxWtJtWdYiBZAum41e7xOLQTZuIkBP6tnis3wue2DX03QIkOjmr 6fKKEGo22x5QyH8e9+QfWAlMg0alcb0u+OLCcbzvPgvysMv0TlmYhxyz8XamuoHe60 QIGFdWD2NMLe/rh+D/Tc7xPNebjo3UjMnkoCBffE= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org F324C60881 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=tdas@codeaurora.org From: Taniya Das To: Stephen Boyd , Michael Turquette Cc: Andy Gross , David Brown , Rajendra Nayak , Odelu Kukatla , Amit Nischal , linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Taniya Das Subject: [PATCH] clk: qcom: gdsc: Add support to poll CFG register to check GDSC state Date: Fri, 27 Apr 2018 13:49:31 +0530 Message-Id: <1524817171-7258-1-git-send-email-tdas@codeaurora.org> X-Mailer: git-send-email 1.9.1 Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Amit Nischal The default behavior of the GDSC enable/disable sequence is to poll the status bits of either the actual GDSCR or the corresponding HW_CTRL registers. On targets which have support for a CFG_GDSCR register, the status bits might not show the correct state of the GDSC, especially in the disable sequence, where the status bit will be cleared even before the core is completely power collapsed. On targets with this issue, poll the power on/off bits in the CFG_GDSCR register instead to correctly determine the GDSC state. Signed-off-by: Amit Nischal Signed-off-by: Taniya Das --- drivers/clk/qcom/gdsc.c | 42 ++++++++++++++++++++++++++---------------- drivers/clk/qcom/gdsc.h | 1 + 2 files changed, 27 insertions(+), 16 deletions(-) -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index a4f3580..f8a9501 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -32,6 +32,11 @@ #define SW_COLLAPSE_MASK BIT(0) #define GMEM_CLAMP_IO_MASK BIT(0) +/* CFG_GDSCR */ +#define GDSC_POWER_UP_COMPLETE BIT(16) +#define GDSC_POWER_DOWN_COMPLETE BIT(15) +#define CFG_GDSCR_OFFSET 0x4 + /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */ #define EN_REST_WAIT_VAL (0x2 << 20) #define EN_FEW_WAIT_VAL (0x8 << 16) @@ -44,15 +49,28 @@ #define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd) -static int gdsc_is_enabled(struct gdsc *sc, unsigned int reg) +static int gdsc_is_enabled(struct gdsc *sc, bool en) { + unsigned int reg; u32 val; int ret; + if (sc->flags & POLL_CFG_GDSCR) + reg = sc->gdscr + CFG_GDSCR_OFFSET; + else + reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr; + ret = regmap_read(sc->regmap, reg, &val); if (ret) return ret; + if (sc->flags & POLL_CFG_GDSCR) { + if (en) + return !!(val & GDSC_POWER_UP_COMPLETE); + else + return !(val & GDSC_POWER_DOWN_COMPLETE); + } + return !!(val & PWR_ON_MASK); } @@ -63,17 +81,17 @@ static int gdsc_hwctrl(struct gdsc *sc, bool en) return regmap_update_bits(sc->regmap, sc->gdscr, HW_CONTROL_MASK, val); } -static int gdsc_poll_status(struct gdsc *sc, unsigned int reg, bool en) +static int gdsc_poll_status(struct gdsc *sc, bool en) { ktime_t start; start = ktime_get(); do { - if (gdsc_is_enabled(sc, reg) == en) + if (gdsc_is_enabled(sc, en) == en) return 0; } while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US); - if (gdsc_is_enabled(sc, reg) == en) + if (gdsc_is_enabled(sc, en) == en) return 0; return -ETIMEDOUT; @@ -83,7 +101,6 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en) { int ret; u32 val = en ? 0 : SW_COLLAPSE_MASK; - unsigned int status_reg = sc->gdscr; ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val); if (ret) @@ -100,8 +117,7 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en) return 0; } - if (sc->gds_hw_ctrl) { - status_reg = sc->gds_hw_ctrl; + if (sc->gds_hw_ctrl) /* * The gds hw controller asserts/de-asserts the status bit soon * after it receives a power on/off request from a master. @@ -113,9 +129,8 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en) * and polling the status bit. */ udelay(1); - } - return gdsc_poll_status(sc, status_reg, en); + return gdsc_poll_status(sc, en); } static inline int gdsc_deassert_reset(struct gdsc *sc) @@ -222,8 +237,6 @@ static int gdsc_disable(struct generic_pm_domain *domain) /* Turn off HW trigger mode if supported */ if (sc->flags & HW_CTRL) { - unsigned int reg; - ret = gdsc_hwctrl(sc, false); if (ret < 0) return ret; @@ -235,8 +248,7 @@ static int gdsc_disable(struct generic_pm_domain *domain) */ udelay(1); - reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr; - ret = gdsc_poll_status(sc, reg, true); + ret = gdsc_poll_status(sc, true); if (ret) return ret; } @@ -258,7 +270,6 @@ static int gdsc_init(struct gdsc *sc) { u32 mask, val; int on, ret; - unsigned int reg; /* * Disable HW trigger: collapse/restore occur based on registers writes. @@ -279,8 +290,7 @@ static int gdsc_init(struct gdsc *sc) return ret; } - reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr; - on = gdsc_is_enabled(sc, reg); + on = gdsc_is_enabled(sc, true); if (on < 0) return on; diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 3964834..ac5f844 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -53,6 +53,7 @@ struct gdsc { #define VOTABLE BIT(0) #define CLAMP_IO BIT(1) #define HW_CTRL BIT(2) +#define POLL_CFG_GDSCR BIT(5) struct reset_controller_dev *rcdev; unsigned int *resets; unsigned int reset_count;