devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Khiem Nguyen <khiem.nguyen.xt@rvc.renesas.com>
To: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Simon Horman <horms+renesas@verge.net.au>,
	Magnus Damm <damm+renesas@opensource.se>,
	Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	"linux-clk@vger.kernel.org" <linux-clk@vger.kernel.org>,
	"linux-renesas-soc@vger.kernel.org"
	<linux-renesas-soc@vger.kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	Toru Oishi <toru.oishi.zj@rvc.renesas.com>,
	"Khiem Trong. Nguyen" <khiem.nguyen.xt@rvc.renesas.com>
Subject: [RFC 1/4] clk: renesas: rcar-gen3-cpg: Add Z clock
Date: Tue, 10 May 2016 11:42:16 +0700	[thread overview]
Message-ID: <573166A8.1030101@rvc.renesas.com> (raw)
In-Reply-To: <1462372543-31835-1-git-send-email-geert+renesas@glider.be>

Base on Dien Pham work.

Signed-off-by: Khiem Nguyen <khiem.nguyen.xt@rvc.renesas.com>
---
  drivers/clk/renesas/rcar-gen3-cpg.c | 143 
++++++++++++++++++++++++++++++++++++
  drivers/clk/renesas/rcar-gen3-cpg.h |   1 +
  2 files changed, 144 insertions(+)

diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c 
b/drivers/clk/renesas/rcar-gen3-cpg.c
index bb4f2f9..45209ac 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -28,6 +28,146 @@
  #define CPG_PLL2CR		0x002c
  #define CPG_PLL4CR		0x01f4

+/** Modify for Z-clock
+ * 
-----------------------------------------------------------------------------
+ * Z Clock
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.  clk->rate = parent->rate * mult / 32
+ * parent - fixed parent.  No clk_set_parent support
+ */
+#define CPG_FRQCRB			0x00000004
+#define CPG_FRQCRB_KICK			BIT(31)
+#define CPG_FRQCRC			0x000000e0
+#define CPG_FRQCRC_ZFC_MASK		(0x1f << 8)
+#define CPG_FRQCRC_ZFC_SHIFT		8
+
+
+struct cpg_z_clk {
+	struct clk_hw hw;
+	void __iomem *reg;
+	void __iomem *kick_reg;
+};
+
+#define to_z_clk(_hw)	container_of(_hw, struct cpg_z_clk, hw)
+
+static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct cpg_z_clk *zclk = to_z_clk(hw);
+	unsigned int mult;
+	unsigned int val;
+	unsigned long rate;
+
+	val = (clk_readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK)
+	    >> CPG_FRQCRC_ZFC_SHIFT;
+	mult = 32 - val;
+
+	rate = div_u64((u64)parent_rate * mult + 16, 32);
+	/* Round to closest value at 100MHz unit */
+	rate = 100000000*DIV_ROUND_CLOSEST(rate, 100000000);
+	return rate;
+}
+
+static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long *parent_rate)
+{
+	unsigned long prate  = *parent_rate;
+	unsigned int mult;
+
+	if (!prate)
+		prate = 1;
+
+	mult = div_u64((u64)rate * 32 + prate/2, prate);
+	mult = clamp(mult, 1U, 32U);
+
+	return *parent_rate / 32 * mult;
+}
+
+static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long parent_rate)
+{
+	struct cpg_z_clk *zclk = to_z_clk(hw);
+	unsigned int mult;
+	u32 val, kick;
+	unsigned int i;
+
+	mult = div_u64((u64)rate * 32 + parent_rate/2, parent_rate);
+	mult = clamp(mult, 1U, 32U);
+
+	if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
+		return -EBUSY;
+
+	val = clk_readl(zclk->reg);
+	val &= ~CPG_FRQCRC_ZFC_MASK;
+	val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT;
+	clk_writel(val, zclk->reg);
+
+	/*
+	 * Set KICK bit in FRQCRB to update hardware setting and wait for
+	 * clock change completion.
+	 */
+	kick = clk_readl(zclk->kick_reg);
+	kick |= CPG_FRQCRB_KICK;
+	clk_writel(kick, zclk->kick_reg);
+
+	/*
+	 * Note: There is no HW information about the worst case latency.
+	 *
+	 * Using experimental measurements, it seems that no more than
+	 * ~10 iterations are needed, independently of the CPU rate.
+	 * Since this value might be dependent of external xtal rate, pll1
+	 * rate or even the other emulation clocks rate, use 1000 as a
+	 * "super" safe value.
+	 */
+	for (i = 1000; i; i--) {
+		if (!(clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK))
+			return 0;
+
+		cpu_relax();
+	}
+
+	return -ETIMEDOUT;
+}
+
+static const struct clk_ops cpg_z_clk_ops = {
+	.recalc_rate = cpg_z_clk_recalc_rate,
+	.round_rate = cpg_z_clk_round_rate,
+	.set_rate = cpg_z_clk_set_rate,
+};
+
+static struct clk * __init cpg_z_clk_register(const struct cpg_core_clk 
*core,
+					      void __iomem *base,
+					      const char *parent_name)
+{
+	struct clk_init_data init;
+	struct cpg_z_clk *zclk;
+	struct clk *clk;
+
+	zclk = kzalloc(sizeof(*zclk), GFP_KERNEL);
+	if (!zclk)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = core->name;
+	init.ops = &cpg_z_clk_ops;
+	init.flags = CLK_SET_RATE_GATE;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	zclk->reg = base + CPG_FRQCRC;
+	zclk->kick_reg = base + CPG_FRQCRB;
+	zclk->hw.init = &init;
+
+	clk = clk_register(NULL, &zclk->hw);
+	if (IS_ERR(clk))
+		kfree(zclk);
+
+	return clk;
+}
+
+/** End of modifying for Z-clock */

  /*
   * SDn Clock
@@ -325,6 +465,9 @@ struct clk * __init 
rcar_gen3_cpg_clk_register(struct device *dev,
  		writel(value, base + CPG_RCKCR);
  		break;

+	case CLK_TYPE_GEN3_Z:
+		return cpg_z_clk_register(core, base, __clk_get_name(parent));
+
  	default:
  		return ERR_PTR(-EINVAL);
  	}
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h 
b/drivers/clk/renesas/rcar-gen3-cpg.h
index f699085..03c26e1 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -20,6 +20,7 @@ enum rcar_gen3_clk_types {
  	CLK_TYPE_GEN3_PLL4,
  	CLK_TYPE_GEN3_SD,
  	CLK_TYPE_GEN3_R,
+	CLK_TYPE_GEN3_Z,
  };

  #define DEF_GEN3_SD(_name, _id, _parent, _offset)	\
-- 
1.9.1


  parent reply	other threads:[~2016-05-10  4:42 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-04 14:35 [PATCH 0/4] clk: renesas: cpg-mssr: Add support for R-Car M3-W Geert Uytterhoeven
2016-05-04 14:35 ` [PATCH 2/4] clk: renesas: Add r8a7796 CPG Core Clock Definitions Geert Uytterhoeven
     [not found] ` <1462372543-31835-1-git-send-email-geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
2016-05-04 14:35   ` [PATCH 1/4] clk: renesas: cpg-mssr: Document r8a7796 support Geert Uytterhoeven
2016-05-05 22:13     ` Rob Herring
2016-05-04 14:35   ` [PATCH 3/4] clk: renesas: cpg-mssr: Extract common R-Car Gen3 support code Geert Uytterhoeven
2016-05-04 14:35 ` [PATCH 4/4] clk: renesas: cpg-mssr: Add support for R-Car M3-W Geert Uytterhoeven
2016-05-10  4:40 ` [RFC 0/4] Add Z clock support Khiem Nguyen
2016-05-13  8:55   ` Geert Uytterhoeven
2016-05-10  4:42 ` Khiem Nguyen [this message]
2016-05-13  8:54   ` [RFC 1/4] clk: renesas: rcar-gen3-cpg: Add Z clock Geert Uytterhoeven
2016-09-23  8:32   ` Geert Uytterhoeven
2016-05-10  4:43 ` [RFC 2/4] clk: renesas: r8a7795: " Khiem Nguyen
2016-05-10  4:44   ` [RFC 3/4] clk: renesas: r8a7796: " Khiem Nguyen
2016-05-10  7:39     ` Geert Uytterhoeven
2016-05-10  4:46   ` [RFC 4/4] arm64: dts: r8a7795: Add Z clock scaling support Khiem Nguyen
2016-05-17 13:03     ` Geert Uytterhoeven
2016-05-13  8:55   ` [RFC 2/4] clk: renesas: r8a7795: Add Z clock Geert Uytterhoeven
2016-05-26  2:35 ` [PATCH 0/4] clk: renesas: cpg-mssr: Add support for R-Car M3-W Simon Horman
2016-05-26  6:55   ` Geert Uytterhoeven
2016-05-27  0:49     ` Simon Horman

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=573166A8.1030101@rvc.renesas.com \
    --to=khiem.nguyen.xt@rvc.renesas.com \
    --cc=damm+renesas@opensource.se \
    --cc=devicetree@vger.kernel.org \
    --cc=geert+renesas@glider.be \
    --cc=horms+renesas@verge.net.au \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=sboyd@codeaurora.org \
    --cc=toru.oishi.zj@rvc.renesas.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).