From patchwork Mon Jul 30 08:11:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enric Balletbo i Serra X-Patchwork-Id: 10548701 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C3AC61751 for ; Mon, 30 Jul 2018 08:13:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B49922873E for ; Mon, 30 Jul 2018 08:13:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A700F293F9; Mon, 30 Jul 2018 08:13:16 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 289172873E for ; Mon, 30 Jul 2018 08:13:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=zSuwJxl8+qoPzXo7ps7EJpxuoJSGmvcCurfDsLZ7kfw=; b=inxozNnpshOj/D86If2paJVMQf sSXp/BF6kkkoWAJD9wXQQuib9lg+8/Sxw5nl7fJH4iHzNK6+8SlilQ6LhLEdQaGyQXNJL2ZvCjGe6 gUaU8PqCsF21jQMHB0RvYTHdCoTGggSt5XZWmDXXNmp9P6aPBFfgUu29bXcHt8lgi5OknAc6aFHCp Dtqp8dKhO3MLGEolGXWZEM5VGdJtXtJu9OjIfKG33uZthjcBdlhxKH+Y3zcyVAGLubpPnC+4gGJUQ yPCtmS5AJR9xisS3nRvusuydCt/5SuKXWjfoAERBHG0vBxQ1bHwHXwV0OqrNMvDKy7fQjYObWLtKP 9vzb6dUQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fk3Ij-0006tt-DG; Mon, 30 Jul 2018 08:13:09 +0000 Received: from bhuna.collabora.co.uk ([46.235.227.227]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fk3Hj-0005q9-9B; Mon, 30 Jul 2018 08:12:14 +0000 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: eballetbo) with ESMTPSA id 0850327E23E From: Enric Balletbo i Serra To: MyungJoo Ham , Kyungmin Park , Chanwoo Choi , Rob Herring , Will Deacon , Heiko Stuebner , Michael Turquette , Stephen Boyd , Sandy Huang , David Airlie Subject: [PATCH 5/8] devfreq: rk3399_dmc / clk: rockchip: Disable DDR clk timeout on suspend. Date: Mon, 30 Jul 2018 10:11:21 +0200 Message-Id: <20180730081124.30698-6-enric.balletbo@collabora.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180730081124.30698-1-enric.balletbo@collabora.com> References: <20180730081124.30698-1-enric.balletbo@collabora.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180730_011208_502005_BE9FDC78 X-CRM114-Status: GOOD ( 15.66 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lin Huang , linux-pm@vger.kernel.org, Derek Basehore , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-rockchip@lists.infradead.org, Sean Paul , kernel@collabora.com, robin.murphy@arm.com, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Derek Basehore This disables the timeout for the DDR clk when the governor is suspended or stopped. This makes sure that the suspend frequency is set. It also makes sure that the userspace governor will be able to change the frequency without failing. Signed-off-by: Derek Basehore Signed-off-by: Enric Balletbo i Serra --- Changes in v1: None drivers/clk/rockchip/clk-ddr.c | 21 ++++++++++++++++++--- drivers/devfreq/rk3399_dmc.c | 20 +++++++++++++++----- drivers/devfreq/rk3399_dmc_priv.h | 1 + 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c index 707be1bd8910..de00590af167 100644 --- a/drivers/clk/rockchip/clk-ddr.c +++ b/drivers/clk/rockchip/clk-ddr.c @@ -32,6 +32,7 @@ struct rockchip_ddrclk { int div_shift; int div_width; int ddr_flag; + bool timeout_en; unsigned long cached_rate; struct work_struct set_rate_work; struct mutex lock; @@ -52,8 +53,9 @@ static void rockchip_ddrclk_set_rate_func(struct work_struct *work) mutex_lock(&ddrclk->lock); for (i = 0; i < DDRCLK_SET_RATE_MAX_RETRIES; i++) { - ret = raw_notifier_call_chain(&ddrclk->sync_chain, 0, &timeout); - if (ret == NOTIFY_BAD) + ret = raw_notifier_call_chain(&ddrclk->sync_chain, 0, + &timeout); + if (ddrclk->timeout_en && ret == NOTIFY_BAD) goto out; /* @@ -63,7 +65,8 @@ static void rockchip_ddrclk_set_rate_func(struct work_struct *work) * at the wrong time. */ local_irq_disable(); - if (ktime_after(ktime_add_ns(ktime_get(), DMC_MIN_VBLANK_NS), + if (ddrclk->timeout_en && + ktime_after(ktime_add_ns(ktime_get(), DMC_MIN_VBLANK_NS), timeout)) { local_irq_enable(); continue; @@ -79,6 +82,17 @@ static void rockchip_ddrclk_set_rate_func(struct work_struct *work) mutex_unlock(&ddrclk->lock); } +void rockchip_ddrclk_set_timeout_en(struct clk *clk, bool enable) +{ + struct clk_hw *hw = __clk_get_hw(clk); + struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw); + + mutex_lock(&ddrclk->lock); + ddrclk->timeout_en = enable; + mutex_unlock(&ddrclk->lock); +} +EXPORT_SYMBOL(rockchip_ddrclk_set_timeout_en); + int rockchip_ddrclk_register_sync_nb(struct clk *clk, struct notifier_block *nb) { struct clk_hw *hw = __clk_get_hw(clk); @@ -232,6 +246,7 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, ddrclk->div_shift = div_shift; ddrclk->div_width = div_width; ddrclk->ddr_flag = ddr_flag; + ddrclk->timeout_en = true; mutex_init(&ddrclk->lock); INIT_WORK(&ddrclk->set_rate_work, rockchip_ddrclk_set_rate_func); RAW_INIT_NOTIFIER_HEAD(&ddrclk->sync_chain); diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c index b4ac9ee605be..323c888b542a 100644 --- a/drivers/devfreq/rk3399_dmc.c +++ b/drivers/devfreq/rk3399_dmc.c @@ -312,14 +312,18 @@ int rockchip_dmcfreq_register_clk_sync_nb(struct devfreq *devfreq, * one notifier is not generally possible. Thus, if more than one sync * notifier is registered, disable dmcfreq. */ - if (dmcfreq->num_sync_nb == 1 && dmcfreq->disable_count <= 0) + if (dmcfreq->num_sync_nb == 1 && dmcfreq->disable_count <= 0) { + rockchip_ddrclk_set_timeout_en(dmcfreq->dmc_clk, false); devfreq_suspend_device(devfreq); + } ret = rockchip_ddrclk_register_sync_nb(dmcfreq->dmc_clk, nb); if (ret == 0) dmcfreq->num_sync_nb++; - else if (dmcfreq->num_sync_nb == 1 && dmcfreq->disable_count <= 0) + else if (dmcfreq->num_sync_nb == 1 && dmcfreq->disable_count <= 0) { + rockchip_ddrclk_set_timeout_en(dmcfreq->dmc_clk, true); devfreq_resume_device(devfreq); + } mutex_unlock(&dmcfreq->en_lock); return ret; @@ -336,8 +340,10 @@ int rockchip_dmcfreq_unregister_clk_sync_nb(struct devfreq *devfreq, ret = rockchip_ddrclk_unregister_sync_nb(dmcfreq->dmc_clk, nb); if (ret == 0) { dmcfreq->num_sync_nb--; - if (dmcfreq->num_sync_nb == 1 && dmcfreq->disable_count <= 0) + if (dmcfreq->num_sync_nb == 1 && dmcfreq->disable_count <= 0) { + rockchip_ddrclk_set_timeout_en(dmcfreq->dmc_clk, true); devfreq_resume_device(devfreq); + } } mutex_unlock(&dmcfreq->en_lock); @@ -352,8 +358,10 @@ int rockchip_dmcfreq_block(struct devfreq *devfreq) int ret = 0; mutex_lock(&dmcfreq->en_lock); - if (dmcfreq->num_sync_nb <= 1 && dmcfreq->disable_count <= 0) + if (dmcfreq->num_sync_nb <= 1 && dmcfreq->disable_count <= 0) { + rockchip_ddrclk_set_timeout_en(dmcfreq->dmc_clk, false); ret = devfreq_suspend_device(devfreq); + } if (!ret) dmcfreq->disable_count++; @@ -369,8 +377,10 @@ int rockchip_dmcfreq_unblock(struct devfreq *devfreq) int ret = 0; mutex_lock(&dmcfreq->en_lock); - if (dmcfreq->num_sync_nb <= 1 && dmcfreq->disable_count == 1) + if (dmcfreq->num_sync_nb <= 1 && dmcfreq->disable_count == 1) { + rockchip_ddrclk_set_timeout_en(dmcfreq->dmc_clk, true); ret = devfreq_resume_device(devfreq); + } if (!ret) dmcfreq->disable_count--; diff --git a/drivers/devfreq/rk3399_dmc_priv.h b/drivers/devfreq/rk3399_dmc_priv.h index 8ac0340a4990..1ad46f4b15cc 100644 --- a/drivers/devfreq/rk3399_dmc_priv.h +++ b/drivers/devfreq/rk3399_dmc_priv.h @@ -7,6 +7,7 @@ #ifndef __RK3399_DMC_PRIV_H #define __RK3399_DMC_PRIV_H +void rockchip_ddrclk_set_timeout_en(struct clk *clk, bool enable); void rockchip_ddrclk_wait_set_rate(struct clk *clk); int rockchip_ddrclk_register_sync_nb(struct clk *clk, struct notifier_block *nb);