All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ziyuan Xu <xzy.xu@rock-chips.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 16/33] rockchip: clk: rk3288: add support for the clock phase
Date: Mon, 15 May 2017 14:07:10 +0800	[thread overview]
Message-ID: <1494828447-24332-16-git-send-email-xzy.xu@rock-chips.com> (raw)
In-Reply-To: <1494828447-24332-1-git-send-email-xzy.xu@rock-chips.com>

This patch adds phase adjustment for mmc clock(ciu_sample), which is
used to select the optimal sampling point of a data input.

The phase shift is achieved through 255 delay elements(40-80
picoseconds),  and calculate the number of delay element via clock
frequency.

Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
---

 drivers/clk/rockchip/clk_rk3288.c | 124 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
index b924a3b..3279e01 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -514,6 +514,7 @@ static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate,
 	switch (periph) {
 	case HCLK_EMMC:
 	case SCLK_EMMC:
+	case SCLK_EMMC_SAMPLE:
 		con = readl(&cru->cru_clksel_con[12]);
 		mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
 		div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
@@ -669,7 +670,9 @@ static ulong rk3288_clk_get_rate(struct clk *clk)
 	case HCLK_SDMMC:
 	case HCLK_SDIO0:
 	case SCLK_EMMC:
+	case SCLK_EMMC_SAMPLE:
 	case SCLK_SDMMC:
+	case SCLK_SDMMC_SAMPLE:
 	case SCLK_SDIO0:
 		new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id);
 		break;
@@ -784,9 +787,130 @@ static ulong rk3288_clk_set_rate(struct clk *clk, ulong rate)
 	return new_rate;
 }
 
+#define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
+#define ROCKCHIP_MMC_DEGREE_MASK	0x3
+#define ROCKCHIP_MMC_DELAYNUM_OFFSET	2
+#define ROCKCHIP_MMC_DELAYNUM_MASK	(0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+
+#define PSECS_PER_SEC 1000000000000LL
+/*
+ * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
+ * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
+ */
+#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
+
+int rockchip_mmc_get_phase(struct clk *clk)
+{
+	struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3288_cru *cru = priv->cru;
+	u32 raw_value, delay_num;
+	u16 degrees = 0;
+	ulong rate;
+
+	rate = rk3288_clk_get_rate(clk);
+
+	if (rate < 0)
+		return rate;
+
+	if (clk->id == SCLK_EMMC_SAMPLE)
+		raw_value = readl(&cru->cru_emmc_con[1]);
+	else
+		raw_value = readl(&cru->cru_sdmmc_con[1]);
+
+	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
+
+	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
+		/* degrees/delaynum * 10000 */
+		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
+					36 * (rate / 1000000);
+
+		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
+		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
+		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
+	}
+
+	return degrees % 360;
+}
+
+int rockchip_mmc_set_phase(struct clk *clk, u32 degrees)
+{
+	struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
+	struct rk3288_cru *cru = priv->cru;
+	u8 nineties, remainder, delay_num;
+	u32 raw_value, delay;
+	ulong rate;
+
+	rate = rk3288_clk_get_rate(clk);
+
+	if (rate < 0)
+		return rate;
+
+	nineties = degrees / 90;
+	remainder = (degrees % 90);
+
+	/*
+	 * Convert to delay; do a little extra work to make sure we
+	 * don't overflow 32-bit / 64-bit numbers.
+	 */
+	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
+	delay *= remainder;
+	delay = DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
+				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
+
+	delay_num = (u8)min_t(u32, delay, 255);
+
+	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
+	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
+	raw_value |= nineties;
+
+	if (clk->id == SCLK_EMMC_SAMPLE)
+		writel(raw_value | 0xffff0000, &cru->cru_emmc_con[1]);
+	else
+		writel(raw_value | 0xffff0000, &cru->cru_sdmmc_con[1]);
+
+	debug("mmc set_phase(%d) delay_nums=%u reg=%#x actual_degrees=%d\n",
+	      degrees, delay_num, raw_value, rockchip_mmc_get_phase(clk));
+
+	return 0;
+}
+
+static int rk3288_clk_get_phase(struct clk *clk)
+{
+	int ret;
+
+	switch (clk->id) {
+	case SCLK_EMMC_SAMPLE:
+	case SCLK_SDMMC_SAMPLE:
+		ret = rockchip_mmc_get_phase(clk);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return ret;
+}
+
+static int rk3288_clk_set_phase(struct clk *clk, int degrees)
+{
+	int ret;
+
+	switch (clk->id) {
+	case SCLK_EMMC_SAMPLE:
+	case SCLK_SDMMC_SAMPLE:
+		ret = rockchip_mmc_set_phase(clk, degrees);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return ret;
+}
+
 static struct clk_ops rk3288_clk_ops = {
 	.get_rate	= rk3288_clk_get_rate,
 	.set_rate	= rk3288_clk_set_rate,
+	.get_phase	= rk3288_clk_get_phase,
+	.set_phase	= rk3288_clk_set_phase,
 };
 
 static int rk3288_clk_ofdata_to_platdata(struct udevice *dev)
-- 
2.7.4

  parent reply	other threads:[~2017-05-15  6:07 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-15  6:06 [U-Boot] [PATCH 01/33] mmc: select the available type from host_caps and card_caps Ziyuan Xu
2017-05-15  6:06 ` [U-Boot] [PATCH 02/33] mmc: add set_timing entry for timing selection Ziyuan Xu
2017-05-15  6:06 ` [U-Boot] [PATCH 03/33] mmc: xenon_sdhci: drop redundant timing definitions Ziyuan Xu
2017-05-15  6:06 ` [U-Boot] [PATCH 04/33] mmc: rework high speed mode selection Ziyuan Xu
2017-05-15  6:06 ` [U-Boot] [PATCH 05/33] mmc: sdhci: fix HISPD bit setting Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 06/33] mmc: add card_busy to query card status Ziyuan Xu
2017-05-25 13:02   ` Jaehoon Chung
2017-05-15  6:07 ` [U-Boot] [PATCH 07/33] mmc: dw_mmc: implement card_busy detection Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 08/33] mmc: sdhci: " Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 09/33] mmc: rework mmc_switch for non-send_status scenario Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 10/33] mmc: add support for HS200 mode of eMMC4.5 Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 11/33] mmc: rework ddr mode judgement with timing Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 12/33] mmc: remove tran_speed from struct mmc Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 13/33] cmd: mmc: show the current speed mode Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 14/33] clk: introduce clk_phase get/set function & callback Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 15/33] rockchip: clk: rk3288: fix mmc clock setting Ziyuan Xu
2017-05-15  6:07 ` Ziyuan Xu [this message]
2017-05-15  6:07 ` [U-Boot] [PATCH 17/33] rockchip: clk: rk3399: fix emmc " Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 18/33] mmc: dw_mmc: add the support for the tuning scheme Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 19/33] mmc: dw_mmc: rockchip: implement tuning with clock phase framework Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 20/33] mmc: dw_mmc: reset controller after data error Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 21/33] mmc: add DDR52 support for eMMC card Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 22/33] mmc: dw_mmc: rockchip: fix data crc error on ddr52 8bit mode Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 23/33] mmc: dw_mmc: fix bus width setting Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 24/33] mmc: sdhci: rockchip: " Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 25/33] mmc: sdhci: update host->clock after clock setting Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 26/33] mmc: sdhci: add support for UHS timing Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 27/33] mmc: sdhci: rename set_clock callback Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 28/33] mmc: sdhci: export sdhci_set_clock() Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 29/33] mmc: sdhci: rockchip: add phy support Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 30/33] mmc: sdhci: add the support for tuning Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 31/33] mmc: add support for HS400 mode of eMMC5.0 Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 32/33] dts: rk3399: change the maximum eMMC clock frequency to 150MHz Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 33/33] SPL: tiny-printf: add "X" modifier Ziyuan Xu
2017-05-16  0:18 ` [U-Boot] [PATCH 01/33] mmc: select the available type from host_caps and card_caps Simon Glass
2017-05-16  1:15   ` Ziyuan
2017-05-16  1:55     ` Jaehoon Chung
2017-05-16  2:22       ` Ziyuan
2017-05-25  8:12       ` Ziyuan
2017-05-25 10:50         ` Jaehoon Chung
2017-05-25 13:08         ` Jaehoon Chung
2017-06-05  0:50           ` Ziyuan
2017-06-05  1:13             ` Jaehoon Chung
2017-05-17  1:38     ` Simon Glass

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=1494828447-24332-16-git-send-email-xzy.xu@rock-chips.com \
    --to=xzy.xu@rock-chips.com \
    --cc=u-boot@lists.denx.de \
    /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.