Module Name: src Committed By: skrll Date: Sat Jan 18 17:20:05 UTC 2025
Modified Files: src/sys/arch/riscv/starfive: jh7100_clkc.c Log Message: risc-v: add support for the StarFive JH7100 audio clocks To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/arch/riscv/starfive/jh7100_clkc.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/riscv/starfive/jh7100_clkc.c diff -u src/sys/arch/riscv/starfive/jh7100_clkc.c:1.4 src/sys/arch/riscv/starfive/jh7100_clkc.c:1.5 --- src/sys/arch/riscv/starfive/jh7100_clkc.c:1.4 Wed Sep 18 08:31:50 2024 +++ src/sys/arch/riscv/starfive/jh7100_clkc.c Sat Jan 18 17:20:05 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: jh7100_clkc.c,v 1.4 2024/09/18 08:31:50 skrll Exp $ */ +/* $NetBSD: jh7100_clkc.c,v 1.5 2025/01/18 17:20:05 skrll Exp $ */ /*- * Copyright (c) 2023 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: jh7100_clkc.c,v 1.4 2024/09/18 08:31:50 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: jh7100_clkc.c,v 1.5 2025/01/18 17:20:05 skrll Exp $"); #include <sys/param.h> @@ -133,6 +133,38 @@ __KERNEL_RCSID(0, "$NetBSD: jh7100_clkc. #define JH7100_NCLKS 189 +#define JH7100_AUDCLK_ADC_MCLK 0 +#define JH7100_AUDCLK_I2S1_MCLK 1 +#define JH7100_AUDCLK_I2SADC_APB 2 +#define JH7100_AUDCLK_I2SADC_BCLK 3 +#define JH7100_AUDCLK_I2SADC_BCLK_N 4 +#define JH7100_AUDCLK_I2SADC_LRCLK 5 +#define JH7100_AUDCLK_PDM_APB 6 +#define JH7100_AUDCLK_PDM_MCLK 7 +#define JH7100_AUDCLK_I2SVAD_APB 8 +#define JH7100_AUDCLK_SPDIF 9 +#define JH7100_AUDCLK_SPDIF_APB 10 +#define JH7100_AUDCLK_PWMDAC_APB 11 +#define JH7100_AUDCLK_DAC_MCLK 12 +#define JH7100_AUDCLK_I2SDAC_APB 13 +#define JH7100_AUDCLK_I2SDAC_BCLK 14 +#define JH7100_AUDCLK_I2SDAC_BCLK_N 15 +#define JH7100_AUDCLK_I2SDAC_LRCLK 16 +#define JH7100_AUDCLK_I2S1_APB 17 +#define JH7100_AUDCLK_I2S1_BCLK 18 +#define JH7100_AUDCLK_I2S1_BCLK_N 19 +#define JH7100_AUDCLK_I2S1_LRCLK 20 +#define JH7100_AUDCLK_I2SDAC16K_APB 21 +#define JH7100_AUDCLK_APB0_BUS 22 +#define JH7100_AUDCLK_DMA1P_AHB 23 +#define JH7100_AUDCLK_USB_APB 24 +#define JH7100_AUDCLK_USB_LPM 25 +#define JH7100_AUDCLK_USB_STB 26 +#define JH7100_AUDCLK_APB_EN 27 +#define JH7100_AUDCLK_VAD_MEM 28 + +#define JH7100_AUDCLK_NCLKS 29 + static const char *cpundbus_root_parents[] = { "osc_sys", "pll0_out", "pll1_out", "pll2_out", @@ -279,8 +311,112 @@ static struct jh71x0_clkc_clk jh7100_clo }; +static const char *adc_mclk_parents[] = { + "audio_src", "audio_12288", +}; + +static const char *i2s1_mclk_parents[] = { + "audio_src", "audio_12288", +}; + +static const char *i2sadc_bclk_parents[] = { + "adc_mclk", "i2sadc_bclk_iopad" +}; + +static const char *i2sadc_lrclk_parents[] = { + "i2sadc_bclk_n", "i2sadc_lrclk_iopad", "i2sadc_bclk", +}; + +static const char *pdm_mclk_parents[] = { + "audio_src", "audio_12288", +}; + +static const char *spdif_parents[] = { + "audio_src", "audio_12288", +}; + +static const char *dac_mclk_parents[] = { + "audio_src", "audio_12288", +}; + +static const char *i2sdac_bclk_parents[] = { + "dac_mclk", "i2sadc_blk_iopad", +}; + +static const char *i2sdac_lrclk_parents[] = { + "i2s1_mclk", "i2sadc_blk_iopad", +}; + +static const char *i2s1_bclk_parents[] = { + "i2s1_mclk", "i2sadc_blk_iopad", +}; + +static const char *i2s1_lrclk_parents[] = { + "i2s1_bclk_n", "i2sadc_lrclk_iopad", +}; + +static const char *vad_mem_parents[] = { + "vad_intmem", "audio_12288", +}; + + +static struct jh71x0_clkc_clk jh7100_audclk_clocks[] = { + JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 15, adc_mclk_parents), + JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 15, i2s1_mclk_parents), + + JH71X0CLKC_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", "apb0_bus"), + + JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, i2sadc_bclk_parents), + + JH71X0CLKC_INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", "i2sadc_bclk"), + JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, i2sadc_lrclk_parents), + JH71X0CLKC_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", "apb0_bus"), + JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 15, pdm_mclk_parents), + JH71X0CLKC_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", "apb0_bus"), + JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_SPDIF, "spdif", 15, spdif_parents), + JH71X0CLKC_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", "apb0_bus"), + JH71X0CLKC_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", "apb0_bus"), + JH71X0CLKC_MUXDIVGATE(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 15, dac_mclk_parents), + JH71X0CLKC_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", "apb0_bus"), + JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, i2sdac_bclk_parents), + JH71X0CLKC_INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", "i2sdac_bclk"), + JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, i2sdac_lrclk_parents), + JH71X0CLKC_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", "apb0_bus"), + JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, i2s1_bclk_parents), + JH71X0CLKC_INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", "i2s1_bclk"), + JH71X0CLKC_MUXDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, i2s1_lrclk_parents), + JH71X0CLKC_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", "apb0_bus"), + JH71X0CLKC_DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, "dom7ahb_bus"), + JH71X0CLKC_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", "dom7ahb_bus"), + JH71X0CLKC_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", /*CLK_IGNORE_UNUSED,*/ "apb_en"), + JH71X0CLKC_GATEDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", /*CLK_IGNORE_UNUSED,*/ 4, "usb_apb"), + JH71X0CLKC_GATEDIV(JH7100_AUDCLK_USB_STB, "usb_stb", /*CLK_IGNORE_UNUSED,*/ 3, "usb_apb"), + JH71X0CLKC_DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, "dom7ahb_bus"), + JH71X0CLKC_MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", vad_mem_parents), +}; + +struct jh7100_clk_config { + const char *jhcc_name; + struct jh71x0_clkc_clk *jhcc_clocks; + size_t jhcc_nclks; +}; + +static struct jh7100_clk_config jh7100_clk_config = { + .jhcc_name = "System", + .jhcc_clocks = jh7100_clocks, + .jhcc_nclks = __arraycount(jh7100_clocks), +}; + + +static struct jh7100_clk_config jh7110_audclk_config = { + .jhcc_name = "Audio", + .jhcc_clocks = jh7100_audclk_clocks, + .jhcc_nclks = __arraycount(jh7100_audclk_clocks), +}; + static const struct device_compatible_entry compat_data[] = { - { .compat = "starfive,jh7100-clkgen" }, + { .compat = "starfive,jh7100-clkgen", .data = &jh7100_clk_config }, + { .compat = "starfive,jh7100-audclk", .data = &jh7110_audclk_config }, DEVICE_COMPAT_EOL }; @@ -323,6 +459,7 @@ jh7100_clkc_attach(device_t parent, devi struct jh71x0_clkc_softc * const sc = device_private(self); struct fdt_attach_args * const faa = aux; const int phandle = faa->faa_phandle; + char infomsg[128] = ""; bus_addr_t addr; bus_size_t size; int error; @@ -342,26 +479,35 @@ jh7100_clkc_attach(device_t parent, devi return; } - struct clk * const osclk = fdtbus_clock_get(phandle, "osc_sys"); - if (osclk == NULL) { - aprint_error(": couldn't get osc_sys\n"); - return; - } - u_int osclk_rate = clk_get_rate(osclk); + const struct jh7100_clk_config *jhcc = + of_compatible_lookup(phandle, compat_data)->data; + KASSERT(jhcc != NULL); + + if (jhcc == &jh7100_clk_config) { + struct clk * const osclk = fdtbus_clock_get(phandle, "osc_sys"); + if (osclk == NULL) { + aprint_error(": couldn't get osc_sys\n"); + return; + } + u_int osclk_rate = clk_get_rate(osclk); + + struct clk * const oaclk = fdtbus_clock_get(phandle, "osc_aud"); + if (oaclk == NULL) { + aprint_error(": couldn't get osc_aud\n"); + return; + } + u_int oaclk_rate = clk_get_rate(oaclk); - struct clk * const oaclk = fdtbus_clock_get(phandle, "osc_aud"); - if (oaclk == NULL) { - aprint_error(": couldn't get osc_aud\n"); - return; + snprintf(infomsg, sizeof(infomsg), "(OSC0 %u Hz, OSC1 %u Hz)", + osclk_rate, oaclk_rate); } - u_int oaclk_rate = clk_get_rate(oaclk); sc->sc_clkdom.name = device_xname(self); sc->sc_clkdom.funcs = &jh71x0_clkc_funcs; sc->sc_clkdom.priv = sc; - sc->sc_clk = jh7100_clocks; - sc->sc_nclks = __arraycount(jh7100_clocks); + sc->sc_clk = jhcc->jhcc_clocks; + sc->sc_nclks = jhcc->jhcc_nclks; for (size_t id = 0; id < sc->sc_nclks; id++) { if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN) continue; @@ -371,8 +517,7 @@ jh7100_clkc_attach(device_t parent, devi } aprint_naive("\n"); - aprint_normal(": JH7100 (OSC0 %u Hz, OSC1 %u Hz)\n", - osclk_rate, oaclk_rate); + aprint_normal(": JH7100 %s clocks %s\n", jhcc->jhcc_name, infomsg); for (size_t id = 0; id < sc->sc_nclks; id++) { if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)