summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2018-11-28 17:30:07 +0800
committerChen-Yu Tsai <wens@csie.org>2018-11-30 11:54:39 +0800
commit01a7ea763fc46fd21692dfc070009d2c1cbc1b07 (patch)
tree12947f27c24ef5f6885b2992db54f5d84965335c
parent5e06aa50524b45a834b1f22b3160b93fb3adabc4 (diff)
downloadlinux-01a7ea763fc46fd21692dfc070009d2c1cbc1b07.tar.bz2
clk: sunxi-ng: r40: Force LOSC parent to RTC LOSC output
On the R40, in addition to a mux between the RTC's own RC oscillator and an external 32768 Hz crystal, which are muxed inside the RTC module, the CCU also has its own RC oscillator, which runs at around 2 MHz, and can be muxed with the LOSC output from the RTC. This muxed output is called "SYS 32K" in the module clock diagram, but otherwise referred to as the LOSC throughout the CCU documentation. The RC oscillator is not very accurate, even though it has an undocumented calibration function. We really want a precise clock at 32768 Hz, instead of something at around 32 KHz. This patch forces the SYS 32K clock to use the RTC output as its parent, and doesn't bother registering the internal oscillator nor a clock mux. Acked-by: Maxime Ripard <maxime.ripard@bootlin.com> Acked-by: Stephen Boyd <sboyd@kernel.org> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-r40.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
index 582ebd41d20d..a22d11aa38ba 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
@@ -1284,6 +1284,9 @@ static struct regmap_config sun8i_r40_ccu_regmap_config = {
.writeable_reg = sun8i_r40_ccu_regmap_accessible_reg,
};
+#define SUN8I_R40_SYS_32K_CLK_REG 0x310
+#define SUN8I_R40_SYS_32K_CLK_KEY (0x16AA << 16)
+
static int sun8i_r40_ccu_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -1312,6 +1315,14 @@ static int sun8i_r40_ccu_probe(struct platform_device *pdev)
val &= ~GENMASK(25, 20);
writel(val, reg + SUN8I_R40_USB_CLK_REG);
+ /*
+ * Force SYS 32k (otherwise known as LOSC throughout the CCU)
+ * clock parent to LOSC output from RTC module instead of the
+ * CCU's internal RC oscillator divided output.
+ */
+ writel(SUN8I_R40_SYS_32K_CLK_KEY | BIT(8),
+ reg + SUN8I_R40_SYS_32K_CLK_REG);
+
regmap = devm_regmap_init_mmio(&pdev->dev, reg,
&sun8i_r40_ccu_regmap_config);
if (IS_ERR(regmap))