All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sagar Dharia <sdharia@codeaurora.org>
To: gregkh@linuxfoundation.org, bp@suse.de, poeschel@lemonage.de,
	sdharia@codeaurora.org, treding@nvidia.com, broonie@kernel.org,
	gong.chen@linux.intel.com, andreas.noever@gmail.com,
	alan@linux.intel.com, mathieu.poirier@linaro.org,
	daniel@ffwll.ch, oded.gabbay@amd.com, jkosina@suse.cz,
	sharon.dvir1@mail.huji.ac.il, joe@perches.com,
	davem@davemloft.net, james.hogan@imgtec.com,
	michael.opdenacker@free-electrons.com,
	daniel.thompson@linaro.org, robh+dt@kernel.org,
	pawel.moll@arm.com, mark.rutland@arm.com,
	ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: kheitke@audience.com, mlocke@codeaurora.org,
	agross@codeaurora.org, linux-arm-msm@vger.kernel.org
Subject: [PATCH V4 6/6] slim: qcom: Add runtime-pm support using clock-pause feature
Date: Sat,  6 Feb 2016 11:44:25 -0700	[thread overview]
Message-ID: <1454784265-5194-7-git-send-email-sdharia@codeaurora.org> (raw)
In-Reply-To: <1454784265-5194-1-git-send-email-sdharia@codeaurora.org>

Slimbus HW mandates that clock-pause sequence has to be executed
before disabling relevant interface and core clocks.
Runtime-PM's autosuspend feature is used here to enter/exit low
power mode for Qualcomm's Slimbus controller. Autosuspend feature
enables driver to avoid changing power-modes too frequently since
entering clock-pause is an expensive sequence

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
---
 drivers/slimbus/slim-qcom-ctrl.c | 124 ++++++++++++++++++++++++++++++++++++++-
 drivers/slimbus/slim-qcom.h      |   1 +
 2 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/drivers/slimbus/slim-qcom-ctrl.c b/drivers/slimbus/slim-qcom-ctrl.c
index df20fb4..9cadcea 100644
--- a/drivers/slimbus/slim-qcom-ctrl.c
+++ b/drivers/slimbus/slim-qcom-ctrl.c
@@ -20,6 +20,7 @@
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/slimbus.h>
+#include <linux/pm_runtime.h>
 #include "slim-qcom.h"
 
 #define MSM_SLIM_NAME	"msm_slim_ctrl"
@@ -217,6 +218,28 @@ rx_ret_irq:
 	return IRQ_HANDLED;
 }
 
+static int msm_clk_pause_wakeup(struct slim_controller *ctrl)
+{
+	struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
+
+	clk_prepare_enable(dev->hclk);
+	clk_prepare_enable(dev->rclk);
+	writel_relaxed(1, dev->base + FRM_WAKEUP);
+	/* Make sure framer wakeup write goes through before ISR fires */
+	mb();
+	/**
+	 * HW Workaround: Currently, slave is reporting lost-sync messages
+	 * after slimbus comes out of clock pause.
+	 * Transaction with slave fail before slave reports that message
+	 * Give some time for that report to come
+	 * Slimbus wakes up in clock gear 10 at 24.576MHz. With each superframe
+	 * being 250 usecs, we wait for 5-10 superframes here to ensure
+	 * we get the message
+	 */
+	usleep_range(1250, 2500);
+	return 0;
+}
+
 static int msm_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn,
 			void *pbuf)
 {
@@ -253,6 +276,7 @@ static int msm_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn,
 	if (txn->msg && txn->msg->wbuf)
 		memcpy(puc, txn->msg->wbuf, txn->msg->num_bytes);
 
+
 	return msm_slim_queue_tx(dev, head, txn->rl, MGR_TX_MSG);
 }
 
@@ -276,13 +300,13 @@ static int msm_set_laddr(struct slim_controller *ctrl,
 	buf[5] = ead->instance;
 	/* Logical address for this EA */
 	buf[6] = laddr;
+
 	/**
 	 * Retries are needed since bus may lose sync when multiple devices
 	 * are coming up and reporting present
 	 */
 	msg.wbuf = buf;
 	msg.num_bytes = 7;
-
 	ret = slim_processtxn(&dev->ctrl, &txn);
 
 	if (ret)
@@ -413,6 +437,8 @@ static int msm_slim_probe(struct platform_device *pdev)
 
 	dev->ctrl.set_laddr = msm_set_laddr;
 	dev->ctrl.xfer_msg = msm_xfer_msg;
+	dev->ctrl.wakeup =  msm_clk_pause_wakeup;
+
 	dev->ctrl.tx.n = MSM_TX_MSGS;
 	dev->ctrl.rx.n = MSM_RX_MSGS;
 	dev->ctrl.tx.sl_sz = SLIM_MSGQ_BUF_LEN;
@@ -510,6 +536,12 @@ static int msm_slim_probe(struct platform_device *pdev)
 	 */
 	mb();
 
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, MSM_SLIM_AUTOSUSPEND);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
 	dev_dbg(dev->dev, "MSM SB controller is up:ver:0x%x!\n", dev->ver);
 	return 0;
 
@@ -527,11 +559,100 @@ static int msm_slim_remove(struct platform_device *pdev)
 {
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
 
+	pm_runtime_disable(&pdev->dev);
 	slim_del_controller(&dev->ctrl);
 	destroy_workqueue(dev->rxwq);
 	return 0;
 }
 
+/**
+ * If PM_RUNTIME is not defined, these 2 functions become helper
+ * functions to be called from system suspend/resume.
+ */
+#ifdef CONFIG_PM
+static int msm_slim_runtime_suspend(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
+	int ret;
+
+	dev_dbg(device, "pm_runtime: suspending...\n");
+	ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED);
+	if (ret)
+		dev_err(device, "clk pause not entered:%d", ret);
+	else {
+		clk_disable_unprepare(dev->hclk);
+		clk_disable_unprepare(dev->rclk);
+	}
+	return ret;
+}
+
+static int msm_slim_runtime_resume(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
+	int ret = 0;
+
+	dev_dbg(device, "pm_runtime: resuming...\n");
+	ret = slim_ctrl_clk_pause(&dev->ctrl, true, 0);
+	if (ret)
+		dev_err(device, "clk pause not exited:%d", ret);
+	return ret;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int msm_slim_suspend(struct device *dev)
+{
+	int ret = 0;
+
+	if (!pm_runtime_enabled(dev) ||
+		(!pm_runtime_suspended(dev))) {
+		dev_dbg(dev, "system suspend");
+		ret = msm_slim_runtime_suspend(dev);
+	}
+	if (ret == -EISCONN) {
+		/**
+		* If the clock pause failed due to active channels, there is
+		* a possibility that some audio stream is active during suspend.
+		* (e.g. modem usecase during suspend)
+		* We dont want to return suspend failure in that case so that
+		* display and relevant components can still go to suspend.
+		* If there is some other error, then it should prevent
+		* system level suspend
+		*/
+		ret = 0;
+	}
+	return ret;
+}
+
+static int msm_slim_resume(struct device *dev)
+{
+	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
+		int ret;
+
+		dev_dbg(dev, "system resume");
+		ret = msm_slim_runtime_resume(dev);
+		if (!ret) {
+			pm_runtime_mark_last_busy(dev);
+			pm_request_autosuspend(dev);
+		}
+		return ret;
+
+	}
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops msm_slim_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(msm_slim_suspend, msm_slim_resume)
+	SET_RUNTIME_PM_OPS(
+			   msm_slim_runtime_suspend,
+			   msm_slim_runtime_resume,
+			   NULL
+	)
+};
+
 static const struct of_device_id msm_slim_dt_match[] = {
 	{
 		.compatible = "qcom,slim-msm",
@@ -546,6 +667,7 @@ static struct platform_driver msm_slim_driver = {
 		.name = MSM_SLIM_NAME,
 		.owner = THIS_MODULE,
 		.of_match_table = msm_slim_dt_match,
+		.pm = &msm_slim_dev_pm_ops,
 	},
 };
 module_platform_driver(msm_slim_driver);
diff --git a/drivers/slimbus/slim-qcom.h b/drivers/slimbus/slim-qcom.h
index 0ad59c3..8b1d649 100644
--- a/drivers/slimbus/slim-qcom.h
+++ b/drivers/slimbus/slim-qcom.h
@@ -23,6 +23,7 @@
 		((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16))
 
 #define SLIM_ROOT_FREQ 24576000
+#define MSM_SLIM_AUTOSUSPEND 1000
 
 /* MAX message size over control channel */
 #define SLIM_MSGQ_BUF_LEN	40
-- 
1.8.2.1

  parent reply	other threads:[~2016-02-06 18:44 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-06 18:44 [PATCH V4 0/6] Introduce framework for SLIMbus device drivers Sagar Dharia
2016-02-06 18:44 ` Sagar Dharia
     [not found] ` <1454784265-5194-1-git-send-email-sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-02-06 18:44   ` [PATCH V4 1/6] SLIMbus: Device management on SLIMbus Sagar Dharia
2016-02-06 18:44     ` Sagar Dharia
     [not found]     ` <1454784265-5194-2-git-send-email-sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-03-05  5:01       ` Mark Brown
2016-03-05  5:01         ` Mark Brown
2016-02-06 18:44 ` [PATCH V4 2/6] of/slimbus: OF helper for SLIMbus Sagar Dharia
2016-02-08 20:24   ` Rob Herring
2016-02-06 18:44 ` [PATCH V4 3/6] slimbus: Add messaging APIs to slimbus framework Sagar Dharia
2016-03-05  5:13   ` Mark Brown
2016-02-06 18:44 ` [PATCH V4 4/6] slim: qcom: Add Qualcomm Slimbus controller driver Sagar Dharia
2016-02-08 20:26   ` Rob Herring
     [not found]   ` <1454784265-5194-5-git-send-email-sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-03-05  5:23     ` Mark Brown
2016-03-05  5:23       ` Mark Brown
2016-04-15 16:17       ` Sagar Dharia
2016-04-18  9:19         ` Mark Brown
2016-04-18 22:42           ` Sagar Dharia
2016-02-06 18:44 ` [PATCH V4 5/6] slimbus: Add support for 'clock-pause' feature Sagar Dharia
2016-02-06 18:44 ` Sagar Dharia [this message]
2016-03-05  5:29   ` [PATCH V4 6/6] slim: qcom: Add runtime-pm support using clock-pause feature Mark Brown
2016-03-05  5:31 ` [PATCH V4 0/6] Introduce framework for SLIMbus device drivers Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1454784265-5194-7-git-send-email-sdharia@codeaurora.org \
    --to=sdharia@codeaurora.org \
    --cc=agross@codeaurora.org \
    --cc=alan@linux.intel.com \
    --cc=andreas.noever@gmail.com \
    --cc=bp@suse.de \
    --cc=broonie@kernel.org \
    --cc=daniel.thompson@linaro.org \
    --cc=daniel@ffwll.ch \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=galak@codeaurora.org \
    --cc=gong.chen@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=james.hogan@imgtec.com \
    --cc=jkosina@suse.cz \
    --cc=joe@perches.com \
    --cc=kheitke@audience.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mathieu.poirier@linaro.org \
    --cc=michael.opdenacker@free-electrons.com \
    --cc=mlocke@codeaurora.org \
    --cc=oded.gabbay@amd.com \
    --cc=pawel.moll@arm.com \
    --cc=poeschel@lemonage.de \
    --cc=robh+dt@kernel.org \
    --cc=sharon.dvir1@mail.huji.ac.il \
    --cc=treding@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.