linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kever Yang <kever.yang@rock-chips.com>
To: Mike Turquette <mturquette@linaro.org>, Heiko Stuebner <heiko@sntech.de>
Cc: dianders@chromium.org, sonnyrao@chromium.org,
	addy.ke@rock-chips.com, cf@rock-chips.com, fzf@rock-chips.com,
	ykk@rock-chips.com, yzq@rock-chips.com, dkl@rock-chips.com,
	huangtao@rock-chips.com, Kever Yang <kever.yang@rock-chips.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH 4/5] clk: rockchip: add the vop_determine_rate for vop dclock
Date: Tue,  4 Nov 2014 15:52:38 +0800	[thread overview]
Message-ID: <1415087559-19444-5-git-send-email-kever.yang@rock-chips.com> (raw)
In-Reply-To: <1415087559-19444-1-git-send-email-kever.yang@rock-chips.com>

Rk3288 has 5 PLLs(APLL, DPLL, CPLL, GPLL, NPLL),
APLL is for CPU clock only and DPLL is for DRAM clock only,
and other 3 PLls used for all other peripherals.
We have to make a total solution for how to campatible all
kinds of clock requirement by on chip peripheral controllers.

Some controllers like I2S and HDMI need accurate frequency while
others controllers accept clock rate with margin.

According to our experience on rk3288, we prefer to use CPLL and GPLL fixed
at 400MHz and 594MHz for general use for most peripheral.

The fraction divider should be enough for I2S controller.

The HDMI is the most diffical one if we have to support all the
resolution requirement for frequency. Most people use 720p and
1080 i/p resolution with 74.25MHz/148.5MHz, which can get clock
rate from 594MHz(maybe from GPLL). some other resolution like
640*480 will use 25.175MHz, which is hard to get from general
used PLLs.

So it is better to make HDMI controller has the right to change
the PLL frequency and get the clock rate it wants.

We set NPLL to 500MHz as default, if HDMI can get what it need
from existent clock provider, then change its divider and switch
to that parent; if not, we have to change the NPLL's output
and always make CPLL&GPLL not change.

This patch add vop_determinate_rate as a div_ops to handle
the HDMI clock things.

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
---

 drivers/clk/rockchip/clk-rk3288.c | 69 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 48412e9..0151140 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -14,6 +14,7 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/clk-private.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <dt-bindings/clock/rk3288-cru.h>
@@ -25,6 +26,7 @@
 enum rk3288_plls {
 	apll, dpll, cpll, gpll, npll,
 };
+const struct clk_ops dclk_vop_ops;
 
 struct rockchip_pll_rate_table rk3288_pll_rates[] = {
 	RK3066_PLL_RATE(2208000000, 1, 92, 1),
@@ -766,6 +768,73 @@ static const char *rk3288_critical_clocks[] __initconst = {
 	"aclk_peri",
 	"hclk_peri",
 };
+#define DCLK_VOP_PARENT_NPLL 2
+
+long dclk_vop_determine_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long *best_parent_rate,
+					struct clk **best_parent_p)
+{
+	struct clk *clk = hw->clk, *parent;
+	unsigned long parent_rate, best = 0;
+	int num_parents = clk->num_parents;
+	int i;
+
+	/*
+	 * check if one of the generic plls can provide a cleanly dividable
+	 * rate without changing them.
+	 */
+	for (i = 0; i < (num_parents - 1); i++) {
+		parent = clk_get_parent_by_index(clk, i);
+		parent_rate = __clk_get_rate(parent);
+		if (parent_rate % rate == 0) {
+			*best_parent_p = parent;
+			*best_parent_rate = parent_rate;
+			return rate;
+		}
+	}
+
+	/* take the npll and set its rate to something suitable */
+	for (i = 0; rk3288_pll_rates[i].rate != 0; i++) {
+		if (rk3288_pll_rates[i].rate % rate == 0) {
+			*best_parent_p = clk_get_parent_by_index(clk,
+						DCLK_VOP_PARENT_NPLL);
+			*best_parent_rate = rk3288_pll_rates[i].rate;
+			return rk3288_pll_rates[i].rate;
+		}
+	}
+
+	/*
+	 * We were not able to find a matching rate, so falling back
+	 * to finding the fastest rate < rate.
+	 * We allow the npll to change its rate while the other plls
+	 * are not allowed to change.
+	 */
+	for (i = 0; i < num_parents; i++) {
+		parent = clk_get_parent_by_index(clk, i);
+		if (!parent)
+			continue;
+
+		if (i == DCLK_VOP_PARENT_NPLL)
+			parent_rate = __clk_round_rate(parent, rate);
+		else
+			parent_rate = __clk_get_rate(parent);
+		if (parent_rate <= rate && parent_rate > best) {
+			int div = DIV_ROUND_UP(parent_rate, rate);
+			*best_parent_p = parent;
+			*best_parent_rate = parent_rate;
+			best = DIV_ROUND_UP(parent_rate, div);
+		}
+	}
+
+	return best;
+}
+
+
+const struct clk_ops dclk_vop_ops = {
+	.recalc_rate = clk_divider_recalc_rate,
+	.set_rate = clk_divider_set_rate,
+	.determine_rate = dclk_vop_determine_rate,
+};
 
 static void __init rk3288_clk_init(struct device_node *np)
 {
-- 
1.9.1


  parent reply	other threads:[~2014-11-04  7:55 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-04  7:52 [PATCH 0/5] clk: rockchip: add full support for HDMI clock on rk3288 Kever Yang
2014-11-04  7:52 ` [PATCH 1/5] clk: rockchip: add some clock rate into rate table for rk3288 Kever Yang
2014-11-04  7:52 ` [PATCH 2/5] clk: divider: make clk_divider_recalc/set_rate available Kever Yang
2014-11-04  7:52 ` [PATCH 3/5] clk: rockchip: introduce the div_ops handling for composite branches Kever Yang
2014-11-04  7:52 ` Kever Yang [this message]
2014-11-04  7:52 ` [PATCH 5/5] clk: rockchip: change DCLK_VOP0 to use new COMPOSITE_DIVOPS Kever Yang
2014-11-06 21:06 ` [PATCH 0/5] clk: rockchip: add full support for HDMI clock on rk3288 Heiko Stübner
2014-11-13  8:52   ` Kever Yang
2014-11-13 22:59     ` Doug Anderson
     [not found]       ` <20141114014605.25314.49766@quantum>
2014-11-14  8:58         ` Kever Yang
2016-01-19 12:02       ` Tomeu Vizoso
2016-01-20 16:50         ` Doug Anderson
2016-01-21  9:03           ` Tomeu Vizoso
2016-01-21 20:11             ` Doug Anderson
2016-01-22 14:00               ` Tomeu Vizoso
2016-01-22 17:07                 ` Doug Anderson
2016-01-26  8:28                   ` Tomeu Vizoso
2016-01-26 16:32                     ` Doug Anderson
2016-01-27 10:20                       ` Tomeu Vizoso
2016-01-27 16:46                         ` Doug Anderson

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=1415087559-19444-5-git-send-email-kever.yang@rock-chips.com \
    --to=kever.yang@rock-chips.com \
    --cc=addy.ke@rock-chips.com \
    --cc=cf@rock-chips.com \
    --cc=dianders@chromium.org \
    --cc=dkl@rock-chips.com \
    --cc=fzf@rock-chips.com \
    --cc=heiko@sntech.de \
    --cc=huangtao@rock-chips.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=mturquette@linaro.org \
    --cc=sonnyrao@chromium.org \
    --cc=ykk@rock-chips.com \
    --cc=yzq@rock-chips.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).