Subject: [U-Boot,v2,05/14] clk: rockchip: Add rk3328 SARADC clock support
From: David Wu <[email-masked]>
To: [email-masked], [email-masked]
Cc: [email-masked], [email-masked], [email-masked], [email-masked], [email-masked], [email-masked], David Wu <[email-masked]>
Date: Tue, 19 Sep 2017 18:57:10 +0800

The clk_saradc is dividing from the 24M, clk_saradc=24MHz/(saradc_div_con+1).
SARADC integer divider control register is 10-bits width.

Signed-off-by: David Wu <[email-masked]>
Acked-by: Philipp Tomsich <[email-masked]>
Reviewed-by: Philipp Tomsich <[email-masked]>
---

Change in v2:
 - Use extract_bits.

 drivers/clk/rockchip/clk_rk3328.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c
index c3a6650..540d910 100644
--- a/drivers/clk/rockchip/clk_rk3328.c
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <bitfield.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <errno.h>
@@ -114,7 +115,8 @@ enum {
 
 	/* CLKSEL_CON23 */
 	CLK_SARADC_DIV_CON_SHIFT	= 0,
-	CLK_SARADC_DIV_CON_MASK		= 0x3ff << CLK_SARADC_DIV_CON_SHIFT,
+	CLK_SARADC_DIV_CON_MASK		= GENMASK(9, 0),
+	CLK_SARADC_DIV_CON_WIDTH	= 10,
 
 	/* CLKSEL_CON24 */
 	CLK_PWM_PLL_SEL_CPLL		= 0,
@@ -478,6 +480,31 @@ static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz)
 	return DIV_TO_RATE(GPLL_HZ, div);
 }
 
+static ulong rk3328_saradc_get_clk(struct rk3328_cru *cru)
+{
+	u32 div, val;
+
+	val = readl(&cru->clksel_con[23]);
+	div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
+			       CLK_SARADC_DIV_CON_WIDTH);
+
+	return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rk3328_saradc_set_clk(struct rk3328_cru *cru, uint hz)
+{
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
+	assert(src_clk_div < 128);
+
+	rk_clrsetreg(&cru->clksel_con[23],
+		     CLK_SARADC_DIV_CON_MASK,
+		     src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
+
+	return rk3328_saradc_get_clk(cru);
+}
+
 static ulong rk3328_clk_get_rate(struct clk *clk)
 {
 	struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
@@ -501,6 +528,9 @@ static ulong rk3328_clk_get_rate(struct clk *clk)
 	case SCLK_PWM:
 		rate = rk3328_pwm_get_clk(priv->cru);
 		break;
+	case SCLK_SARADC:
+		rate = rk3328_saradc_get_clk(priv->cru);
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -531,6 +561,9 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
 	case SCLK_PWM:
 		ret = rk3328_pwm_set_clk(priv->cru, rate);
 		break;
+	case SCLK_SARADC:
+		ret = rk3328_saradc_set_clk(priv->cru, rate);
+		break;
 	default:
 		return -ENOENT;
 	}
-- 
2.7.4