Module Name: src
Committed By: jmcneill
Date: Sun Nov 17 17:33:17 UTC 2019
Modified Files:
src/sys/arch/arm/sunxi: sun50i_a64_ccu.c sunxi_ccu_div.c
Log Message:
Add support for A64 I2S clocks.
To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/sunxi/sun50i_a64_ccu.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/sunxi/sunxi_ccu_div.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/sunxi/sun50i_a64_ccu.c
diff -u src/sys/arch/arm/sunxi/sun50i_a64_ccu.c:1.13 src/sys/arch/arm/sunxi/sun50i_a64_ccu.c:1.14
--- src/sys/arch/arm/sunxi/sun50i_a64_ccu.c:1.13 Mon Jul 1 21:06:47 2019
+++ src/sys/arch/arm/sunxi/sun50i_a64_ccu.c Sun Nov 17 17:33:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sun50i_a64_ccu.c,v 1.13 2019/07/01 21:06:47 jmcneill Exp $ */
+/* $NetBSD: sun50i_a64_ccu.c,v 1.14 2019/11/17 17:33:17 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: sun50i_a64_ccu.c,v 1.13 2019/07/01 21:06:47 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: sun50i_a64_ccu.c,v 1.14 2019/11/17 17:33:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -60,6 +60,9 @@ __KERNEL_RCSID(1, "$NetBSD: sun50i_a64_c
#define SDMMC0_CLK_REG 0x088
#define SDMMC1_CLK_REG 0x08c
#define SDMMC2_CLK_REG 0x090
+#define I2SPCM0_CLK_REG 0x0b0
+#define I2SPCM1_CLK_REG 0x0b4
+#define I2SPCM2_CLK_REG 0x0b8
#define USBPHY_CFG_REG 0x0cc
#define DRAM_CFG_REG 0x0f4
#define MBUS_RST_REG 0x0fc
@@ -154,6 +157,7 @@ static const char *mmc_parents[] = { "ho
static const char *ths_parents[] = { "hosc", NULL, NULL, NULL };
static const char *de_parents[] = { "pll_periph0_2x", "pll_de" };
static const char *hdmi_parents[] = { "pll_video0", "pll_video1" };
+static const char *i2s_parents[] = { "pll_audio_8x", "pll_audio_4x", "pll_audio_2x", "pll_audio" };
static const char *tcon1_parents[] = { "pll_video0", NULL, "pll_video1", NULL };
static const char *gpu_parents[] = { "pll_gpu" };
@@ -407,6 +411,26 @@ static struct sunxi_ccu_clk sun50i_a64_c
SUNXI_CCU_GATE(A64_CLK_HDMI_DDC, "hdmi-ddc", "hosc",
HDMI_SLOW_CLK_REG, 31),
+ SUNXI_CCU_DIV_GATE(A64_CLK_I2S0, "i2s0", i2s_parents,
+ I2SPCM0_CLK_REG, /* reg */
+ 0, /* div */
+ __BITS(17,16), /* sel */
+ __BIT(31), /* enable */
+ 0),
+ SUNXI_CCU_DIV_GATE(A64_CLK_I2S1, "i2s1", i2s_parents,
+ I2SPCM1_CLK_REG, /* reg */
+ 0, /* div */
+ __BITS(17,16), /* sel */
+ __BIT(31), /* enable */
+ 0),
+ SUNXI_CCU_DIV_GATE(A64_CLK_I2S2, "i2s2", i2s_parents,
+ I2SPCM2_CLK_REG, /* reg */
+ 0, /* div */
+ __BITS(17,16), /* sel */
+ __BIT(31), /* enable */
+ 0),
+
+
SUNXI_CCU_DIV_GATE(A64_CLK_TCON1, "tcon1", tcon1_parents,
TCON1_CLK_REG, /* reg */
__BITS(3,0), /* div */
Index: src/sys/arch/arm/sunxi/sunxi_ccu_div.c
diff -u src/sys/arch/arm/sunxi/sunxi_ccu_div.c:1.5 src/sys/arch/arm/sunxi/sunxi_ccu_div.c:1.6
--- src/sys/arch/arm/sunxi/sunxi_ccu_div.c:1.5 Mon Mar 19 16:19:17 2018
+++ src/sys/arch/arm/sunxi/sunxi_ccu_div.c Sun Nov 17 17:33:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_ccu_div.c,v 1.5 2018/03/19 16:19:17 bouyer Exp $ */
+/* $NetBSD: sunxi_ccu_div.c,v 1.6 2019/11/17 17:33:17 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_div.c,v 1.5 2018/03/19 16:19:17 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_div.c,v 1.6 2019/11/17 17:33:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -98,6 +98,38 @@ sunxi_ccu_div_get_rate(struct sunxi_ccu_
return rate / ratio;
}
+static int
+sunxi_ccu_div_select_parent(struct sunxi_ccu_softc *sc,
+ struct sunxi_ccu_clk *clk, u_int new_rate)
+{
+ struct sunxi_ccu_div *div = &clk->u.div;
+ struct sunxi_ccu_clk *clk_parent;
+ struct clk *best_parent;
+ u_int index, best_diff;
+ const char *pname;
+
+ best_parent = NULL;
+ best_diff = ~0u;
+ for (index = 0; index < div->nparents; index++) {
+ pname = div->parents[index];
+ if (pname == NULL)
+ continue;
+ clk_parent = sunxi_ccu_clock_find(sc, pname);
+ if (clk_parent == NULL)
+ continue;
+ const u_int rate = clk_get_rate(&clk_parent->base);
+ const u_int diff = abs((int)rate - (int)new_rate);
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_parent = &clk_parent->base;
+ }
+ }
+ if (best_diff == ~0u)
+ return EINVAL;
+
+ return clk_set_parent(&clk->base, best_parent);
+}
+
int
sunxi_ccu_div_set_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk, u_int new_rate)
@@ -119,7 +151,7 @@ sunxi_ccu_div_set_rate(struct sunxi_ccu_
if ((div->flags & SUNXI_CCU_DIV_SET_RATE_PARENT) != 0)
return clk_set_rate(clkp_parent, new_rate);
else
- return ENXIO;
+ return sunxi_ccu_div_select_parent(sc, clk, new_rate);
}
val = CCU_READ(sc, div->reg);