All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ritesh Harjani <riteshh@codeaurora.org>
To: ulf.hansson@linaro.org, linux-mmc@vger.kernel.org,
	adrian.hunter@intel.com, shawn.lin@rock-chips.com,
	sboyd@codeaurora.org
Cc: devicetree@vger.kernel.org, linux-clk@vger.kernel.org,
	david.brown@linaro.org, andy.gross@linaro.org,
	linux-arm-msm@vger.kernel.org, georgi.djakov@linaro.org,
	alex.lemberg@sandisk.com, mateusz.nowak@intel.com,
	Yuliy.Izrailov@sandisk.com, asutoshd@codeaurora.org,
	kdorfman@codeaurora.org, david.griego@linaro.org,
	stummala@codeaurora.org, venkatg@codeaurora.org,
	rnayak@codeaurora.org, pramod.gurav@linaro.org
Subject: [PATCH v6 02/14] clk: qcom: Add rcg ops to return floor value closest to the requested rate
Date: Mon,  7 Nov 2016 16:54:25 +0530	[thread overview]
Message-ID: <1478517877-23733-3-git-send-email-riteshh@codeaurora.org> (raw)
In-Reply-To: <1478517877-23733-1-git-send-email-riteshh@codeaurora.org>

From: Rajendra Nayak <rnayak@codeaurora.org>

The default behaviour with clk_rcg2_ops is for the
clk_round_rate()/clk_set_rate() to return/set a ceil clock
rate closest to the requested rate by looking up the corresponding
frequency table.
However, we do have some instances (mainly sdcc on various platforms)
of clients expecting a clk_set_rate() to set a floor value instead.
Add a new clk_rcg2_floor_ops to handle this for such specific
rcg instances

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
 drivers/clk/qcom/clk-rcg.h  |  1 +
 drivers/clk/qcom/clk-rcg2.c | 75 +++++++++++++++++++++++++++++++++++++++------
 drivers/clk/qcom/common.c   | 26 ++++++++++++++++
 drivers/clk/qcom/common.h   |  2 ++
 4 files changed, 95 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index b904c33..1b3e8d2 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -173,6 +173,7 @@ struct clk_rcg2 {
 #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
 
 extern const struct clk_ops clk_rcg2_ops;
+extern const struct clk_ops clk_rcg2_floor_ops;
 extern const struct clk_ops clk_rcg2_shared_ops;
 extern const struct clk_ops clk_edp_pixel_ops;
 extern const struct clk_ops clk_byte_ops;
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index a071bba..04433a6 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -47,6 +47,11 @@
 #define N_REG			0xc
 #define D_REG			0x10
 
+enum {
+	FLOOR,
+	CEIL,
+};
+
 static int clk_rcg2_is_enabled(struct clk_hw *hw)
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
@@ -176,15 +181,25 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
 	return calc_rate(parent_rate, m, n, mode, hid_div);
 }
 
-static int _freq_tbl_determine_rate(struct clk_hw *hw,
-		const struct freq_tbl *f, struct clk_rate_request *req)
+static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
+				    struct clk_rate_request *req, bool match)
 {
 	unsigned long clk_flags, rate = req->rate;
 	struct clk_hw *p;
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 	int index;
 
-	f = qcom_find_freq(f, rate);
+	switch (match) {
+	case FLOOR:
+		f = qcom_find_freq_floor(f, rate);
+		break;
+	case CEIL:
+		f = qcom_find_freq(f, rate);
+		break;
+	default:
+		return -EINVAL;
+	};
+
 	if (!f)
 		return -EINVAL;
 
@@ -221,7 +236,15 @@ static int clk_rcg2_determine_rate(struct clk_hw *hw,
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 
-	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req);
+	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, CEIL);
+}
+
+static int clk_rcg2_determine_floor_rate(struct clk_hw *hw,
+					 struct clk_rate_request *req)
+{
+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR);
 }
 
 static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
@@ -265,12 +288,23 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
 	return update_config(rcg);
 }
 
-static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
+static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
+			       bool match)
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 	const struct freq_tbl *f;
 
-	f = qcom_find_freq(rcg->freq_tbl, rate);
+	switch (match) {
+	case FLOOR:
+		f = qcom_find_freq_floor(rcg->freq_tbl, rate);
+		break;
+	case CEIL:
+		f = qcom_find_freq(rcg->freq_tbl, rate);
+		break;
+	default:
+		return -EINVAL;
+	};
+
 	if (!f)
 		return -EINVAL;
 
@@ -280,13 +314,25 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
 static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
 			    unsigned long parent_rate)
 {
-	return __clk_rcg2_set_rate(hw, rate);
+	return __clk_rcg2_set_rate(hw, rate, CEIL);
+}
+
+static int clk_rcg2_set_floor_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long parent_rate)
+{
+	return __clk_rcg2_set_rate(hw, rate, FLOOR);
 }
 
 static int clk_rcg2_set_rate_and_parent(struct clk_hw *hw,
 		unsigned long rate, unsigned long parent_rate, u8 index)
 {
-	return __clk_rcg2_set_rate(hw, rate);
+	return __clk_rcg2_set_rate(hw, rate, CEIL);
+}
+
+static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw,
+		unsigned long rate, unsigned long parent_rate, u8 index)
+{
+	return __clk_rcg2_set_rate(hw, rate, FLOOR);
 }
 
 const struct clk_ops clk_rcg2_ops = {
@@ -300,6 +346,17 @@ static int clk_rcg2_set_rate_and_parent(struct clk_hw *hw,
 };
 EXPORT_SYMBOL_GPL(clk_rcg2_ops);
 
+const struct clk_ops clk_rcg2_floor_ops = {
+	.is_enabled = clk_rcg2_is_enabled,
+	.get_parent = clk_rcg2_get_parent,
+	.set_parent = clk_rcg2_set_parent,
+	.recalc_rate = clk_rcg2_recalc_rate,
+	.determine_rate = clk_rcg2_determine_floor_rate,
+	.set_rate = clk_rcg2_set_floor_rate,
+	.set_rate_and_parent = clk_rcg2_set_floor_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops);
+
 static int clk_rcg2_shared_force_enable(struct clk_hw *hw, unsigned long rate)
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
@@ -323,7 +380,7 @@ static int clk_rcg2_shared_force_enable(struct clk_hw *hw, unsigned long rate)
 		pr_err("%s: RCG did not turn on\n", name);
 
 	/* set clock rate */
-	ret = __clk_rcg2_set_rate(hw, rate);
+	ret = __clk_rcg2_set_rate(hw, rate, CEIL);
 	if (ret)
 		return ret;
 
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index fffcbaf..cf6b87f 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -46,6 +46,32 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate)
 }
 EXPORT_SYMBOL_GPL(qcom_find_freq);
 
+const
+struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f,
+				      unsigned long rate)
+{
+	int size = 0;
+
+	if (!f)
+		return NULL;
+
+	/*
+	 * The freq table has entries in the ascending order of frequencies
+	 * To find the floor for a given frequency, we need to do a reverse
+	 * lookup of the table
+	 */
+	for (; f->freq; f++, size++)
+		;
+
+	for (f--; size; f--, size--)
+		if (rate >= f->freq)
+			return f;
+
+	/* could not find any rates lower than *rate* */
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(qcom_find_freq_floor);
+
 int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, u8 src)
 {
 	int i, num_parents = clk_hw_get_num_parents(hw);
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
index ae9bdeb..76886a1 100644
--- a/drivers/clk/qcom/common.h
+++ b/drivers/clk/qcom/common.h
@@ -34,6 +34,8 @@ struct qcom_cc_desc {
 
 extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
 					     unsigned long rate);
+extern const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f,
+						   unsigned long rate);
 extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map,
 			       u8 src);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.


  reply	other threads:[~2016-11-07 11:24 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-07 11:24 [PATCH v6 00/14] mmc: sdhci-msm: Add clk-rates, DDR, HS400 support Ritesh Harjani
2016-11-07 11:24 ` Ritesh Harjani [this message]
     [not found]   ` <1478517877-23733-3-git-send-email-riteshh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-07 13:51     ` [PATCH v6 02/14] clk: qcom: Add rcg ops to return floor value closest to the requested rate kbuild test robot
2016-11-07 13:51       ` kbuild test robot
2016-11-08 23:02     ` Stephen Boyd
2016-11-08 23:02       ` Stephen Boyd
2016-11-09 11:53       ` Ritesh Harjani
2016-11-07 13:51   ` [PATCH] clk: qcom: fix semicolon.cocci warnings kbuild test robot
2016-11-07 11:24 ` [PATCH v6 03/14] clk: qcom: Move all sdcc rcgs to use clk_rcg2_floor_ops Ritesh Harjani
     [not found] ` <1478517877-23733-1-git-send-email-riteshh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-07 11:24   ` [PATCH v6 01/14] clk: Add clk_hw_get_clk() helper API to be used by clk providers Ritesh Harjani
2016-11-07 11:24     ` Ritesh Harjani
     [not found]     ` <1478517877-23733-2-git-send-email-riteshh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-08  3:37       ` Rajendra Nayak
2016-11-08  3:37         ` Rajendra Nayak
     [not found]         ` <58214862.8080604-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-08  4:08           ` Ritesh Harjani
2016-11-08  4:08             ` Ritesh Harjani
2016-11-07 11:24   ` [PATCH v6 04/14] mmc: sdhci-msm: Change poor style writel/readl of registers Ritesh Harjani
2016-11-07 11:24     ` Ritesh Harjani
2016-11-08 23:07     ` Stephen Boyd
     [not found]       ` <20161108230724.GO16026-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-09 11:55         ` Ritesh Harjani
2016-11-09 11:55           ` Ritesh Harjani
2016-11-07 11:24   ` [PATCH v6 10/14] arm64: dts: qcom: msm8916: Add ddr support to sdhc1 Ritesh Harjani
2016-11-07 11:24     ` Ritesh Harjani
2016-11-07 11:24   ` [PATCH v6 12/14] mmc: sdhci-msm: Save the calculated tuning phase Ritesh Harjani
2016-11-07 11:24     ` Ritesh Harjani
2016-11-08 12:41     ` Adrian Hunter
2016-11-07 11:24 ` [PATCH v6 05/14] mmc: sdhci-msm: Update DLL reset sequence Ritesh Harjani
2016-11-08 23:06   ` Stephen Boyd
     [not found]     ` <20161108230622.GN16026-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-08 23:14       ` Arnd Bergmann
2016-11-08 23:14         ` Arnd Bergmann
2016-11-09 12:06     ` Ritesh Harjani
2016-11-09 20:43       ` Stephen Boyd
2016-11-14  6:03         ` Ritesh Harjani
2016-11-07 11:24 ` [PATCH v6 06/14] mmc: sdhci-msm: Add get_min_clock() and get_max_clock() callback Ritesh Harjani
     [not found]   ` <1478517877-23733-7-git-send-email-riteshh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-08 12:15     ` Adrian Hunter
2016-11-08 12:15       ` Adrian Hunter
2016-11-07 11:24 ` [PATCH v6 07/14] mmc: sdhci-msm: Enable few quirks Ritesh Harjani
2016-11-07 11:24 ` [PATCH v6 08/14] mmc: sdhci-msm: Implement set_clock callback for sdhci-msm Ritesh Harjani
2016-11-08 12:16   ` Adrian Hunter
2016-11-07 11:24 ` [PATCH v6 09/14] mmc: sdhci-msm: Add clock changes for DDR mode Ritesh Harjani
2016-11-08 12:20   ` Adrian Hunter
2016-11-07 11:24 ` [PATCH v6 11/14] mmc: sdhci-msm: Add HS400 platform support Ritesh Harjani
2016-11-08 12:37   ` Adrian Hunter
2016-11-07 11:24 ` [PATCH v6 13/14] mmc: sdhci-msm: Add calibration tuning for CDCLP533 circuit Ritesh Harjani
2016-11-08 12:50   ` Adrian Hunter
2016-11-07 11:24 ` [PATCH v6 14/14] sdhci: sdhci-msm: update dll configuration Ritesh Harjani
     [not found]   ` <1478517877-23733-15-git-send-email-riteshh-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-08 12:57     ` Adrian Hunter
2016-11-08 12:57       ` Adrian Hunter

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=1478517877-23733-3-git-send-email-riteshh@codeaurora.org \
    --to=riteshh@codeaurora.org \
    --cc=Yuliy.Izrailov@sandisk.com \
    --cc=adrian.hunter@intel.com \
    --cc=alex.lemberg@sandisk.com \
    --cc=andy.gross@linaro.org \
    --cc=asutoshd@codeaurora.org \
    --cc=david.brown@linaro.org \
    --cc=david.griego@linaro.org \
    --cc=devicetree@vger.kernel.org \
    --cc=georgi.djakov@linaro.org \
    --cc=kdorfman@codeaurora.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=mateusz.nowak@intel.com \
    --cc=pramod.gurav@linaro.org \
    --cc=rnayak@codeaurora.org \
    --cc=sboyd@codeaurora.org \
    --cc=shawn.lin@rock-chips.com \
    --cc=stummala@codeaurora.org \
    --cc=ulf.hansson@linaro.org \
    --cc=venkatg@codeaurora.org \
    /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.