Module Name: src Committed By: jmcneill Date: Sun Aug 6 17:14:37 UTC 2017
Modified Files: src/sys/arch/arm/sunxi: sun8i_h3_ccu.c sunxi_ccu.h sunxi_ccu_nkmp.c Log Message: Add support for H3 audio PLL and digital audio part. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/sunxi/sun8i_h3_ccu.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/sunxi/sunxi_ccu.h cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.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/sun8i_h3_ccu.c diff -u src/sys/arch/arm/sunxi/sun8i_h3_ccu.c:1.9 src/sys/arch/arm/sunxi/sun8i_h3_ccu.c:1.10 --- src/sys/arch/arm/sunxi/sun8i_h3_ccu.c:1.9 Sat Aug 5 17:50:53 2017 +++ src/sys/arch/arm/sunxi/sun8i_h3_ccu.c Sun Aug 6 17:14:37 2017 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ __KERNEL_RCSID(1, "$NetBSD: sun8i_h3_ccu #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 @@ __KERNEL_RCSID(1, "$NetBSD: sun8i_h3_ccu #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 *apb1_parents[] = { "a 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 @@ static struct sunxi_ccu_clk sun8i_h3_ccu __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 @@ static struct sunxi_ccu_clk sun8i_h3_ccu 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 @@ static struct sunxi_ccu_clk sun8i_h3_ccu 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), Index: src/sys/arch/arm/sunxi/sunxi_ccu.h diff -u src/sys/arch/arm/sunxi/sunxi_ccu.h:1.7 src/sys/arch/arm/sunxi/sunxi_ccu.h:1.8 --- src/sys/arch/arm/sunxi/sunxi_ccu.h:1.7 Mon Jul 17 23:26:17 2017 +++ src/sys/arch/arm/sunxi/sunxi_ccu.h Sun Aug 6 17:14:37 2017 @@ -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 <jmcne...@invisible.ca> @@ -79,6 +79,7 @@ const char *sunxi_ccu_gate_get_parent(st [_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 @@ const char *sunxi_ccu_gate_get_parent(st .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 @@ struct sunxi_ccu_nkmp { 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 @@ int sunxi_ccu_nkmp_set_rate(struct sunxi 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 @@ const char *sunxi_ccu_nkmp_get_parent(st .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; Index: src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c diff -u src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c:1.4 src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c:1.5 --- src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c:1.4 Thu Jul 6 22:10:14 2017 +++ src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c Sun Aug 6 17:14:37 2017 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ sunxi_ccu_nkmp_enable(struct sunxi_ccu_s { struct sunxi_ccu_nkmp *nkmp = &clk->u.nkmp; uint32_t val; + int retry; KASSERT(clk->type == SUNXI_CCU_NKMP); @@ -55,6 +56,17 @@ sunxi_ccu_nkmp_enable(struct sunxi_ccu_s 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 @@ int 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 *