Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/sunxi Add support for H3 audio PLL and digital ...
details: https://anonhg.NetBSD.org/src/rev/f8a46b7d18c0
branches: trunk
changeset: 355621:f8a46b7d18c0
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun Aug 06 17:14:37 2017 +0000
description:
Add support for H3 audio PLL and digital audio part.
diffstat:
sys/arch/arm/sunxi/sun8i_h3_ccu.c | 27 +++++++++++++++++-
sys/arch/arm/sunxi/sunxi_ccu.h | 24 ++++++++++++++--
sys/arch/arm/sunxi/sunxi_ccu_nkmp.c | 52 ++++++++++++++++++++++++++++++++++--
3 files changed, 95 insertions(+), 8 deletions(-)
diffs (242 lines):
diff -r 65b80f041aa1 -r f8a46b7d18c0 sys/arch/arm/sunxi/sun8i_h3_ccu.c
--- a/sys/arch/arm/sunxi/sun8i_h3_ccu.c Sun Aug 06 17:13:15 2017 +0000
+++ b/sys/arch/arm/sunxi/sun8i_h3_ccu.c Sun Aug 06 17:14:37 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sun8i_h3_ccu.c,v 1.9 2017/08/05 17:50:53 jmcneill Exp $ */
+/* $NetBSD: sun8i_h3_ccu.c,v 1.10 2017/08/06 17:14:37 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: sun8i_h3_ccu.c,v 1.9 2017/08/05 17:50:53 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: sun8i_h3_ccu.c,v 1.10 2017/08/06 17:14:37 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -41,6 +41,7 @@
#include <arm/sunxi/sunxi_ccu.h>
#include <arm/sunxi/sun8i_h3_ccu.h>
+#define PLL_AUDIO_CTRL_REG 0x008
#define PLL_PERIPH0_CTRL_REG 0x028
#define AHB1_APB1_CFG_REG 0x054
#define APB2_CFG_REG 0x058
@@ -55,6 +56,7 @@
#define SDMMC2_CLK_REG 0x090
#define USBPHY_CFG_REG 0x0cc
#define MBUS_RST_REG 0x0fc
+#define AC_DIG_CLK_REG 0x140
#define BUS_SOFT_RST_REG0 0x2c0
#define BUS_SOFT_RST_REG1 0x2c4
#define BUS_SOFT_RST_REG2 0x2c8
@@ -141,6 +143,11 @@
static const char *apb2_parents[] = { "losc", "hosc", "pll_periph0" };
static const char *mod_parents[] = { "hosc", "pll_periph0", "pll_periph1" };
+static const struct sunxi_ccu_nkmp_tbl sunx8_h3_ac_dig_table[] = {
+ { 24576000, 13, 0, 0, 13 },
+ { 0 }
+};
+
static struct sunxi_ccu_clk sun8i_h3_ccu_clks[] = {
SUNXI_CCU_NKMP(H3_CLK_PLL_PERIPH0, "pll_periph0", "hosc",
PLL_PERIPH0_CTRL_REG, /* reg */
@@ -151,6 +158,17 @@
__BIT(31), /* enable */
SUNXI_CCU_NKMP_DIVIDE_BY_TWO),
+ SUNXI_CCU_NKMP_TABLE(H3_CLK_PLL_AUDIO_BASE, "pll_audio", "hosc",
+ PLL_AUDIO_CTRL_REG, /* reg */
+ __BITS(14,8), /* n */
+ 0, /* k */
+ __BITS(4,0), /* m */
+ __BITS(19,16), /* p */
+ __BIT(31), /* enable */
+ __BIT(28), /* lock */
+ sunx8_h3_ac_dig_table, /* table */
+ 0),
+
SUNXI_CCU_PREDIV(H3_CLK_AHB1, "ahb1", ahb1_parents,
AHB1_APB1_CFG_REG, /* reg */
__BITS(7,6), /* prediv */
@@ -203,6 +221,9 @@
SUNXI_CCU_PHASE(H3_CLK_MMC2_OUTPUT, "mmc2_output", "mmc2",
SDMMC2_CLK_REG, __BITS(10,8)),
+ SUNXI_CCU_GATE(H3_CLK_AC_DIG, "ac_dig", "pll_audio",
+ AC_DIG_CLK_REG, 31),
+
SUNXI_CCU_GATE(H3_CLK_BUS_DMA, "bus-dma", "ahb1",
BUS_CLK_GATING_REG0, 6),
SUNXI_CCU_GATE(H3_CLK_BUS_MMC0, "bus-mmc0", "ahb1",
@@ -232,6 +253,8 @@
SUNXI_CCU_GATE(H3_CLK_BUS_OHCI3, "bus-ohci3", "ahb2",
BUS_CLK_GATING_REG0, 31),
+ SUNXI_CCU_GATE(H3_CLK_BUS_CODEC, "bus-codec", "apb1",
+ BUS_CLK_GATING_REG2, 0),
SUNXI_CCU_GATE(H3_CLK_BUS_PIO, "bus-pio", "apb1",
BUS_CLK_GATING_REG2, 5),
diff -r 65b80f041aa1 -r f8a46b7d18c0 sys/arch/arm/sunxi/sunxi_ccu.h
--- a/sys/arch/arm/sunxi/sunxi_ccu.h Sun Aug 06 17:13:15 2017 +0000
+++ b/sys/arch/arm/sunxi/sunxi_ccu.h Sun Aug 06 17:14:37 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_ccu.h,v 1.7 2017/07/17 23:26:17 jmcneill Exp $ */
+/* $NetBSD: sunxi_ccu.h,v 1.8 2017/08/06 17:14:37 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -79,6 +79,7 @@
[_id] = { \
.type = SUNXI_CCU_GATE, \
.base.name = (_name), \
+ .base.flags = CLK_SET_RATE_PARENT, \
.u.gate.parent = (_pname), \
.u.gate.reg = (_reg), \
.u.gate.mask = __BIT(_bit), \
@@ -86,6 +87,14 @@
.get_parent = sunxi_ccu_gate_get_parent, \
}
+struct sunxi_ccu_nkmp_tbl {
+ u_int rate;
+ uint32_t n;
+ uint32_t k;
+ uint32_t m;
+ uint32_t p;
+};
+
struct sunxi_ccu_nkmp {
bus_size_t reg;
const char *parent;
@@ -96,6 +105,7 @@
uint32_t lock;
uint32_t enable;
uint32_t flags;
+ const struct sunxi_ccu_nkmp_tbl *table;
#define SUNXI_CCU_NKMP_DIVIDE_BY_TWO __BIT(0)
#define SUNXI_CCU_NKMP_FACTOR_N_EXACT __BIT(1)
};
@@ -109,8 +119,8 @@
const char *sunxi_ccu_nkmp_get_parent(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
-#define SUNXI_CCU_NKMP(_id, _name, _parent, _reg, _n, _k, _m, \
- _p, _enable, _flags) \
+#define SUNXI_CCU_NKMP_TABLE(_id, _name, _parent, _reg, _n, _k, _m, \
+ _p, _enable, _lock, _tbl, _flags) \
[_id] = { \
.type = SUNXI_CCU_NKMP, \
.base.name = (_name), \
@@ -122,12 +132,20 @@
.u.nkmp.p = (_p), \
.u.nkmp.enable = (_enable), \
.u.nkmp.flags = (_flags), \
+ .u.nkmp.lock = (_lock), \
+ .u.nkmp.table = (_tbl), \
.enable = sunxi_ccu_nkmp_enable, \
.get_rate = sunxi_ccu_nkmp_get_rate, \
.set_rate = sunxi_ccu_nkmp_set_rate, \
.get_parent = sunxi_ccu_nkmp_get_parent, \
}
+#define SUNXI_CCU_NKMP(_id, _name, _parent, _reg, _n, _k, _m, \
+ _p, _enable, _flags) \
+ SUNXI_CCU_NKMP_TABLE(_id, _name, _parent, _reg, _n, _k, _m, \
+ _p, _enable, 0, NULL, _flags)
+
+
struct sunxi_ccu_nm {
bus_size_t reg;
const char **parents;
diff -r 65b80f041aa1 -r f8a46b7d18c0 sys/arch/arm/sunxi/sunxi_ccu_nkmp.c
--- a/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c Sun Aug 06 17:13:15 2017 +0000
+++ b/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c Sun Aug 06 17:14:37 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_ccu_nkmp.c,v 1.4 2017/07/06 22:10:14 jmcneill Exp $ */
+/* $NetBSD: sunxi_ccu_nkmp.c,v 1.5 2017/08/06 17:14:37 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_nkmp.c,v 1.4 2017/07/06 22:10:14 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_nkmp.c,v 1.5 2017/08/06 17:14:37 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -42,6 +42,7 @@
{
struct sunxi_ccu_nkmp *nkmp = &clk->u.nkmp;
uint32_t val;
+ int retry;
KASSERT(clk->type == SUNXI_CCU_NKMP);
@@ -55,6 +56,17 @@
val &= ~nkmp->enable;
CCU_WRITE(sc, nkmp->reg, val);
+ if (enable && nkmp->lock) {
+ for (retry = 1000; retry > 0; retry--) {
+ val = CCU_READ(sc, nkmp->reg);
+ if (val & nkmp->lock)
+ break;
+ delay(100);
+ }
+ if (retry == 0)
+ return ETIMEDOUT;
+ }
+
return 0;
}
@@ -115,7 +127,41 @@
sunxi_ccu_nkmp_set_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk, u_int rate)
{
- return EIO;
+ struct sunxi_ccu_nkmp *nkmp = &clk->u.nkmp;
+ const struct sunxi_ccu_nkmp_tbl *tab;
+ uint32_t val;
+
+ KASSERT(clk->type == SUNXI_CCU_NKMP);
+
+ if (nkmp->table == NULL || rate == 0)
+ return EIO;
+
+ for (tab = nkmp->table; tab->rate > 0; tab++)
+ if (tab->rate == rate)
+ break;
+ if (tab->rate == 0)
+ return EINVAL;
+
+ val = CCU_READ(sc, nkmp->reg);
+ if (nkmp->n) {
+ val &= ~nkmp->n;
+ val |= __SHIFTIN(tab->n, nkmp->n);
+ }
+ if (nkmp->k) {
+ val &= ~nkmp->k;
+ val |= __SHIFTIN(tab->k, nkmp->k);
+ }
+ if (nkmp->m) {
+ val &= ~nkmp->m;
+ val |= __SHIFTIN(tab->m, nkmp->m);
+ }
+ if (nkmp->p) {
+ val &= ~nkmp->p;
+ val |= __SHIFTIN(tab->p, nkmp->p);
+ }
+ CCU_WRITE(sc, nkmp->reg, val);
+
+ return 0;
}
const char *
Home |
Main Index |
Thread Index |
Old Index