diff options
| author | Stephen Boyd <sboyd@kernel.org> | 2026-06-13 13:57:40 -0700 |
|---|---|---|
| committer | Stephen Boyd <sboyd@kernel.org> | 2026-06-13 13:57:40 -0700 |
| commit | df2e28941e8abbae432d019dca0911292b8f4ac7 (patch) | |
| tree | 3a3ab564023dc41ecdfbf1fd116b7513811aeb01 | |
| parent | 254f49634ee16a731174d2ae34bc50bd5f45e731 (diff) | |
| parent | a7b7c7c6c01679efef0fd2f2ca1c5114f303e4f5 (diff) | |
Merge tag 'clk-canaan-7.2' of https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux into clk-canaan
Pull Canaan k230 clock support from Conor Dooley:
- Driver and devicetree bindings for the Canaan k230 SoC clk
controller
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
* tag 'clk-canaan-7.2' of https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux:
clk: canaan: Add clock driver for Canaan K230
dt-bindings: clock: Add Canaan K230 clock controller
| -rw-r--r-- | Documentation/devicetree/bindings/clock/canaan,k230-clk.yaml | 59 | ||||
| -rw-r--r-- | drivers/clk/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/clk/Makefile | 1 | ||||
| -rw-r--r-- | drivers/clk/clk-k230.c | 2452 | ||||
| -rw-r--r-- | include/dt-bindings/clock/canaan,k230-clk.h | 220 |
5 files changed, 2738 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/clock/canaan,k230-clk.yaml b/Documentation/devicetree/bindings/clock/canaan,k230-clk.yaml new file mode 100644 index 000000000000..34c93cb5db40 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/canaan,k230-clk.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/canaan,k230-clk.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Canaan Kendryte K230 Clock + +maintainers: + - Xukai Wang <kingxukai@zohomail.com> + +description: + The Canaan K230 clock controller generates various clocks for SoC + peripherals. See include/dt-bindings/clock/canaan,k230-clk.h for + valid clock IDs. + +properties: + compatible: + const: canaan,k230-clk + + reg: + items: + - description: PLL control registers + - description: Sysclk control registers + + clocks: + items: + - description: Main external reference clock + - description: + External clock which used as the pulse input + for the timer to provide timing signals. + + clock-names: + items: + - const: osc24m + - const: timer-pulse-in + + '#clock-cells': + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + - | + clock-controller@91102000 { + compatible = "canaan,k230-clk"; + reg = <0x91102000 0x40>, + <0x91100000 0x108>; + clocks = <&osc24m>, <&timerx_pulse_in>; + clock-names = "osc24m", "timer-pulse-in"; + #clock-cells = <1>; + }; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index b2efbe9f6acb..1717ce75a907 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -480,6 +480,12 @@ config COMMON_CLK_K210 help Support for the Canaan Kendryte K210 RISC-V SoC clocks. +config COMMON_CLK_K230 + bool "Clock driver for the Canaan Kendryte K230 SoC" + depends on ARCH_CANAAN || COMPILE_TEST + help + Support for the Canaan Kendryte K230 RISC-V SoC clocks. + config COMMON_CLK_SP7021 tristate "Clock driver for Sunplus SP7021 SoC" depends on SOC_SP7021 || COMPILE_TEST diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index a3e2862ebd7e..3dbc05f76101 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o obj-$(CONFIG_COMMON_CLK_K210) += clk-k210.o +obj-$(CONFIG_COMMON_CLK_K230) += clk-k230.o obj-$(CONFIG_LMK04832) += clk-lmk04832.o obj-$(CONFIG_COMMON_CLK_LAN966X) += clk-lan966x.o obj-$(CONFIG_COMMON_CLK_LOCHNAGAR) += clk-lochnagar.o diff --git a/drivers/clk/clk-k230.c b/drivers/clk/clk-k230.c new file mode 100644 index 000000000000..cfc437038e4e --- /dev/null +++ b/drivers/clk/clk-k230.c @@ -0,0 +1,2452 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Kendryte Canaan K230 Clock Drivers + * + * Author: Xukai Wang <kingxukai@zohomail.com> + * Author: Troy Mitchell <troymitchell988@gmail.com> + */ + +#include <linux/bitfield.h> +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/iopoll.h> +#include <linux/platform_device.h> +#include <linux/rational.h> +#include <linux/spinlock.h> + +#include <dt-bindings/clock/canaan,k230-clk.h> + +/* PLL control register bits. */ +#define K230_PLL_BYPASS_ENABLE BIT(19) +#define K230_PLL_GATE_ENABLE BIT(2) +#define K230_PLL_GATE_WRITE_ENABLE BIT(18) +#define K230_PLL_OD_MASK GENMASK(27, 24) +#define K230_PLL_R_MASK GENMASK(21, 16) +#define K230_PLL_F_MASK GENMASK(12, 0) +#define K230_PLL_DIV_REG_OFFSET 0x00 +#define K230_PLL_BYPASS_REG_OFFSET 0x04 +#define K230_PLL_GATE_REG_OFFSET 0x08 +#define K230_PLL_LOCK_REG_OFFSET 0x0C + +/* PLL lock register */ +#define K230_PLL_LOCK_STATUS_MASK BIT(0) +#define K230_PLL_LOCK_TIME_DELAY 400 +#define K230_PLL_LOCK_TIMEOUT 0 + +/* K230 CLK registers offset */ +#define K230_CLK_AUDIO_CLKDIV_OFFSET 0x34 +#define K230_CLK_PDM_CLKDIV_OFFSET 0x40 +#define K230_CLK_CODEC_ADC_MCLKDIV_OFFSET 0x38 +#define K230_CLK_CODEC_DAC_MCLKDIV_OFFSET 0x3c + +#define K230_PLLX_DIV_ADDR(base, idx) \ + (K230_PLL_DIV_REG_OFFSET + (base) + (idx) * 0x10) + +#define K230_PLLX_BYPASS_ADDR(base, idx) \ + (K230_PLL_BYPASS_REG_OFFSET + (base) + (idx) * 0x10) + +#define K230_PLLX_GATE_ADDR(base, idx) \ + (K230_PLL_GATE_REG_OFFSET + (base) + (idx) * 0x10) + +#define K230_PLLX_LOCK_ADDR(base, idx) \ + (K230_PLL_LOCK_REG_OFFSET + (base) + (idx) * 0x10) + +#define K230_CLK_RATE_FORMAT_PNAME(_var, _id, \ + _mul_min, _mul_max, _mul_shift, _mul_mask, \ + _div_min, _div_max, _div_shift, _div_mask, \ + _reg, _bit, _method, _reg2, \ + _read_only, _flags, \ + _pname) \ + static struct k230_clk_rate _var = { \ + .div_reg_off = _reg, \ + .mul_reg_off = _reg2, \ + .id = _id, \ + .clk = { \ + .write_enable_bit = _bit, \ + .mul_min = _mul_min, \ + .mul_max = _mul_max, \ + .mul_shift = _mul_shift, \ + .mul_mask = _mul_mask, \ + .div_min = _div_min, \ + .div_max = _div_max, \ + .div_shift = _div_shift, \ + .div_mask = _div_mask, \ + .read_only = _read_only, \ + .hw.init = CLK_HW_INIT_FW_NAME(#_var, \ + _pname, &k230_clk_ops_##_method, \ + _flags), \ + }, \ + } + +#define K230_CLK_RATE_FORMAT(_var, _id, \ + _mul_min, _mul_max, _mul_shift, _mul_mask, \ + _div_min, _div_max, _div_shift, _div_mask, \ + _reg, _bit, _method, _reg2, \ + _read_only, _flags, \ + _phw) \ + static struct k230_clk_rate _var = { \ + .div_reg_off = _reg, \ + .mul_reg_off = _reg2, \ + .id = _id, \ + .clk = { \ + .write_enable_bit = _bit, \ + .mul_min = _mul_min, \ + .mul_max = _mul_max, \ + .mul_shift = _mul_shift, \ + .mul_mask = _mul_mask, \ + .div_min = _div_min, \ + .div_max = _div_max, \ + .div_shift = _div_shift, \ + .div_mask = _div_mask, \ + .read_only = _read_only, \ + .hw.init = CLK_HW_INIT_HW(#_var, \ + _phw, &k230_clk_ops_##_method, \ + _flags), \ + }, \ + } + +#define K230_CLK_GATE_FORMAT_PNAME(_var, _id, \ + _reg, _bit, _flags, _gate_flags, \ + _pname) \ + static struct k230_clk_gate _var = { \ + .reg_off = _reg, \ + .id = _id, \ + .clk = { \ + .bit_idx = _bit, \ + .flags = _gate_flags, \ + .hw.init = CLK_HW_INIT_FW_NAME(#_var, \ + _pname, &clk_gate_ops, _flags), \ + }, \ + } + +#define K230_CLK_GATE_FORMAT(_var, _id, \ + _reg, _bit, _flags, _gate_flags, \ + _phw) \ + static struct k230_clk_gate _var = { \ + .reg_off = _reg, \ + .id = _id, \ + .clk = { \ + .bit_idx = _bit, \ + .flags = _gate_flags, \ + .hw.init = CLK_HW_INIT_HW(#_var, \ + _phw, &clk_gate_ops, _flags), \ + }, \ + } + +#define K230_CLK_MUX_FORMAT(_var, _id, \ + _reg, _shift, _mask, _flags, _mux_flags, _pdata) \ + static struct k230_clk_mux _var = { \ + .reg_off = _reg, \ + .id = _id, \ + .clk = { \ + .flags = _mux_flags, \ + .shift = _shift, \ + .mask = _mask, \ + .hw.init = CLK_HW_INIT_PARENTS_DATA(#_var, \ + _pdata, &clk_mux_ops, _flags), \ + }, \ + } + +#define K230_CLK_FIXED_FACTOR_FORMAT(_var, \ + _mul, _div, _flags, \ + _phw) \ + static struct clk_fixed_factor _var = { \ + .mult = _mul, \ + .div = _div, \ + .hw.init = CLK_HW_INIT_HW(#_var, \ + _phw, &clk_fixed_factor_ops, _flags), \ + } + +#define K230_CLK_PLL_FORMAT(_var, _id, _flags, _pname) \ + static struct k230_pll _var = { \ + .hw.init = CLK_HW_INIT_FW_NAME(#_var, \ + _pname, &k230_pll_ops, _flags), \ + .id = _id, \ + } + +struct k230_pll { + struct clk_hw hw; + void __iomem *reg; + /* ensures mutual exclusion for concurrent register access. */ + spinlock_t *lock; + int id; +}; + +#define hw_to_k230_pll(_hw) container_of(_hw, struct k230_pll, hw) + +struct k230_clk_rate_self { + struct clk_hw hw; + void __iomem *reg; + bool read_only; + u32 write_enable_bit; + u32 mul_min; + u32 mul_max; + u32 mul_shift; + u32 mul_mask; + u32 div_min; + u32 div_max; + u32 div_shift; + u32 div_mask; + /* ensures mutual exclusion for concurrent register access. */ + spinlock_t *lock; +}; + +#define hw_to_k230_clk_rate_self(_hw) container_of(_hw, \ + struct k230_clk_rate_self, hw) + +struct k230_clk_rate { + u32 mul_reg_off; + u32 div_reg_off; + struct k230_clk_rate_self clk; + int id; +}; + +static inline struct k230_clk_rate *hw_to_k230_clk_rate(struct clk_hw *hw) +{ + return container_of(hw_to_k230_clk_rate_self(hw), struct k230_clk_rate, + clk); +} + +struct k230_clk_gate { + u32 reg_off; + struct clk_gate clk; + int id; +}; + +struct k230_clk_mux { + u32 reg_off; + struct clk_mux clk; + int id; +}; + +static int k230_pll_prepare(struct clk_hw *hw); +static int k230_pll_enable(struct clk_hw *hw); +static void k230_pll_disable(struct clk_hw *hw); +static int k230_pll_is_enabled(struct clk_hw *hw); +static unsigned long k230_pll_get_rate(struct clk_hw *hw, unsigned long parent_rate); +static int k230_clk_set_rate_mul(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate); +static int k230_clk_determine_rate_mul(struct clk_hw *hw, struct clk_rate_request *req); +static unsigned long k230_clk_get_rate_mul(struct clk_hw *hw, + unsigned long parent_rate); +static int k230_clk_set_rate_div(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate); +static int k230_clk_determine_rate_div(struct clk_hw *hw, struct clk_rate_request *req); +static unsigned long k230_clk_get_rate_div(struct clk_hw *hw, + unsigned long parent_rate); +static int k230_clk_set_rate_mul_div(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate); +static int k230_clk_determine_rate_mul_div(struct clk_hw *hw, struct clk_rate_request *req); +static unsigned long k230_clk_get_rate_mul_div(struct clk_hw *hw, + unsigned long parent_rate); + +static const struct clk_ops k230_pll_ops = { + .prepare = k230_pll_prepare, + .enable = k230_pll_enable, + .disable = k230_pll_disable, + .is_enabled = k230_pll_is_enabled, + .recalc_rate = k230_pll_get_rate, +}; + +/* clk_ops for clocks whose rate is determined by a configurable multiplier */ +static const struct clk_ops k230_clk_ops_mul = { + .set_rate = k230_clk_set_rate_mul, + .determine_rate = k230_clk_determine_rate_mul, + .recalc_rate = k230_clk_get_rate_mul, +}; + +/* clk_ops for clocks whose rate is determined by a configurable divider */ +static const struct clk_ops k230_clk_ops_div = { + .set_rate = k230_clk_set_rate_div, + .determine_rate = k230_clk_determine_rate_div, + .recalc_rate = k230_clk_get_rate_div, +}; + +/* clk_ops for clocks whose rate is determined by both a multiplier and a divider */ +static const struct clk_ops k230_clk_ops_mul_div = { + .set_rate = k230_clk_set_rate_mul_div, + .determine_rate = k230_clk_determine_rate_mul_div, + .recalc_rate = k230_clk_get_rate_mul_div, +}; + +K230_CLK_PLL_FORMAT(pll0, 0, CLK_IS_CRITICAL, NULL); +K230_CLK_PLL_FORMAT(pll1, 1, CLK_IS_CRITICAL, NULL); +K230_CLK_PLL_FORMAT(pll2, 2, CLK_IS_CRITICAL, NULL); +K230_CLK_PLL_FORMAT(pll3, 3, CLK_IS_CRITICAL, NULL); + +static struct k230_pll *k230_plls[] = { + &pll0, + &pll1, + &pll2, + &pll3, +}; + +K230_CLK_FIXED_FACTOR_FORMAT(pll0_div2, 1, 2, 0, &pll0.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll0_div3, 1, 3, 0, &pll0.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll0_div4, 1, 4, 0, &pll0.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll0_div16, 1, 16, 0, &pll0.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll1_div2, 1, 2, 0, &pll1.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll1_div3, 1, 3, 0, &pll1.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll1_div4, 1, 4, 0, &pll1.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll2_div2, 1, 2, 0, &pll2.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll2_div3, 1, 3, 0, &pll2.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll2_div4, 1, 4, 0, &pll2.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll3_div2, 1, 2, 0, &pll3.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll3_div3, 1, 3, 0, &pll3.hw); +K230_CLK_FIXED_FACTOR_FORMAT(pll3_div4, 1, 4, 0, &pll3.hw); + +static struct clk_fixed_factor *k230_pll_divs[] = { + &pll0_div2, + &pll0_div3, + &pll0_div4, + &pll0_div16, + &pll1_div2, + &pll1_div3, + &pll1_div4, + &pll2_div2, + &pll2_div3, + &pll2_div4, + &pll3_div2, + &pll3_div3, + &pll3_div4, +}; + +K230_CLK_GATE_FORMAT(cpu0_src_gate, + K230_CPU0_SRC_GATE, + 0, 0, CLK_IS_CRITICAL, 0, + &pll0_div2.hw); + +K230_CLK_RATE_FORMAT(cpu0_src_rate, + K230_CPU0_SRC_RATE, + 1, 16, 1, 0xF, + 16, 16, 0, 0x0, + 0x0, 31, mul, 0x0, + false, 0, + &cpu0_src_gate.clk.hw); + +K230_CLK_RATE_FORMAT(cpu0_axi_rate, + K230_CPU0_AXI_RATE, + 1, 1, 0, 0, + 1, 8, 6, 0x7, + 0x0, 31, div, 0x0, + 0, 0, + &cpu0_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(cpu0_plic_gate, + K230_CPU0_PLIC_GATE, + 0x0, 9, CLK_IS_CRITICAL, 0, + &cpu0_src_rate.clk.hw); + +K230_CLK_RATE_FORMAT(cpu0_plic_rate, + K230_CPU0_PLIC_RATE, + 1, 1, 0, 0, + 1, 8, 10, 0x7, + 0x0, 31, div, 0x0, + false, 0, + &cpu0_plic_gate.clk.hw); + +K230_CLK_GATE_FORMAT(cpu0_noc_ddrcp4_gate, + K230_CPU0_NOC_DDRCP4_GATE, + 0x60, 7, CLK_IS_CRITICAL, 0, + &cpu0_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(cpu0_apb_gate, + K230_CPU0_APB_GATE, + 0x0, 13, CLK_IS_CRITICAL, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(cpu0_apb_rate, + K230_CPU0_APB_RATE, + 1, 1, 0, 0, + 1, 8, 15, 0x7, + 0x0, 31, div, 0x0, + false, 0, + &cpu0_apb_gate.clk.hw); + +static const struct clk_parent_data k230_cpu1_src_mux_pdata[] = { + { .hw = &pll1_div2.hw, }, + { .hw = &pll3.hw, }, + { .hw = &pll0.hw, }, +}; + +K230_CLK_MUX_FORMAT(cpu1_src_mux, + K230_CPU1_SRC_MUX, + 0x4, 1, 0x3, + 0, 0, + k230_cpu1_src_mux_pdata); + +K230_CLK_GATE_FORMAT(cpu1_src_gate, + K230_CPU1_SRC_GATE, + 0x4, 0, CLK_IS_CRITICAL, 0, + &cpu1_src_mux.clk.hw); + +K230_CLK_RATE_FORMAT(cpu1_src_rate, + K230_CPU1_SRC_RATE, + 1, 1, 0, 0, + 1, 8, 3, 0x7, + 0x4, 31, div, 0x0, + false, 0, + &cpu1_src_gate.clk.hw); + +K230_CLK_RATE_FORMAT(cpu1_axi_rate, + K230_CPU1_AXI_RATE, + 1, 1, 0, 0, + 1, 8, 12, 0x7, + 0x4, 31, div, 0x0, + false, 0, + &cpu1_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(cpu1_plic_gate, + K230_CPU1_PLIC_GATE, + 0x4, 15, CLK_IS_CRITICAL, 0, + &cpu1_src_rate.clk.hw); + +K230_CLK_RATE_FORMAT(cpu1_plic_rate, + K230_CPU1_PLIC_RATE, + 1, 1, 0, 0, + 1, 8, 16, 0x7, + 0x4, 31, div, 0x0, + false, 0, + &cpu1_plic_gate.clk.hw); + +K230_CLK_GATE_FORMAT(cpu1_apb_gate, + K230_CPU1_APB_GATE, + 0x4, 19, CLK_IS_CRITICAL, 0, + &pll0_div4.hw); + +K230_CLK_GATE_FORMAT_PNAME(pmu_apb_gate, + K230_PMU_APB_GATE, + 0x10, 0, 0, 0, + "osc24m"); + +K230_CLK_GATE_FORMAT(hs_hclk_high_gate, + K230_HS_HCLK_HIGH_GATE, + 0x18, 1, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(hs_hclk_high_rate, + K230_HS_HCLK_HIGH_RATE, + 1, 1, 0, 0, + 1, 8, 0, 0x7, + 0x1C, 31, div, 0x0, + false, 0, + &hs_hclk_high_gate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_hclk_gate, + K230_HS_HCLK_GATE, + 0x18, 0, 0, 0, + &hs_hclk_high_rate.clk.hw); + +K230_CLK_RATE_FORMAT(hs_hclk_rate, + K230_HS_HCLK_RATE, + 1, 1, 0, 0, + 1, 8, 3, 0x7, + 0x1C, 31, div, 0x0, + false, 0, + &hs_hclk_gate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd0_ahb_gate, + K230_HS_SD0_AHB_GATE, + 0x18, 2, 0, 0, + &hs_hclk_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd1_ahb_gate, + K230_HS_SD1_AHB_GATE, + 0x18, 3, 0, 0, + &hs_hclk_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_ssi1_ahb_gate, + K230_HS_SSI1_AHB_GATE, + 0x18, 7, 0, 0, + &hs_hclk_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_ssi2_ahb_gate, + K230_HS_SSI2_AHB_GATE, + 0x18, 8, 0, 0, + &hs_hclk_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_usb0_ahb_gate, + K230_HS_USB0_AHB_GATE, + 0x18, 4, 0, 0, + &hs_hclk_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_usb1_ahb_gate, + K230_HS_USB1_AHB_GATE, + 0x18, 5, 0, 0, + &hs_hclk_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_ssi0_axi_gate, + K230_HS_SSI0_AXI_GATE, + 0x18, 27, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(hs_ssi0_axi_rate, + K230_HS_SSI0_AXI_RATE, + 1, 1, 0, 0, + 1, 8, 9, 0x7, + 0x20, 31, div, 0x0, + false, 0, + &hs_ssi0_axi_gate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_ssi1_gate, + K230_HS_SSI1_GATE, + 0x18, 25, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(hs_ssi1_rate, + K230_HS_SSI1_RATE, + 1, 1, 0, 0, + 1, 8, 3, 0x7, + 0x20, 31, div, 0x0, + false, 0, + &hs_ssi1_gate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_ssi2_gate, + K230_HS_SSI2_GATE, + 0x18, 26, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(hs_ssi2_rate, + K230_HS_SSI2_RATE, + 1, 1, 0, 0, + 1, 8, 6, 0x7, + 0x20, 31, div, 0x0, + false, 0, + &hs_ssi2_gate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_qspi_axi_src_gate, + K230_HS_QSPI_AXI_SRC_GATE, + 0x18, 28, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(hs_qspi_axi_src_rate, + K230_HS_QSPI_AXI_SRC_RATE, + 1, 1, 0, 0, + 1, 8, 12, 0x7, + 0x20, 31, div, 0x0, + false, 0, + &hs_qspi_axi_src_gate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_ssi1_axi_gate, + K230_HS_SSI1_AXI_GATE, + 0x18, 29, 0, 0, + &hs_qspi_axi_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_ssi2_axi_gate, + K230_HS_SSI2_AXI_GATE, + 0x18, 30, 0, 0, + &hs_qspi_axi_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd_card_src_gate, + K230_HS_SD_CARD_SRC_GATE, + 0x18, 11, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(hs_sd_card_src_rate, + K230_HS_SD_CARD_SRC_RATE, + 1, 1, 0, 0, + 2, 8, 12, 0x7, + 0x1C, 31, div, 0x0, + false, 0, + &hs_sd_card_src_gate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd0_card_gate, + K230_HS_SD0_CARD_GATE, + 0x18, 15, 0, 0, + &hs_sd_card_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd1_card_gate, + K230_HS_SD1_CARD_GATE, + 0x18, 19, 0, 0, + &hs_sd_card_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd_axi_src_gate, + K230_HS_SD_AXI_SRC_GATE, + 0x18, 9, 0, 0, + &pll2_div4.hw); + +K230_CLK_RATE_FORMAT(hs_sd_axi_src_rate, + K230_HS_SD_AXI_SRC_RATE, + 1, 1, 0, 0, + 1, 8, 6, 0x7, + 0x1C, 31, div, 0x0, + false, 0, + &hs_sd_axi_src_gate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd0_axi_gate, + K230_HS_SD0_AXI_GATE, + 0x18, 13, 0, 0, + &hs_sd_axi_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd1_axi_gate, + K230_HS_SD1_AXI_GATE, + 0x18, 17, 0, 0, + &hs_sd_axi_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd0_base_gate, + K230_HS_SD0_BASE_GATE, + 0x18, 14, 0, 0, + &hs_sd_axi_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd1_base_gate, + K230_HS_SD1_BASE_GATE, + 0x18, 18, 0, 0, + &hs_sd_axi_src_rate.clk.hw); + +static const struct clk_parent_data k230_hs_ssi0_mux_pdata[] = { + { .hw = &pll0_div2.hw, }, + { .hw = &pll2_div4.hw, }, +}; + +K230_CLK_MUX_FORMAT(hs_ssi0_mux, + K230_HS_SSI0_MUX, + 0x20, 18, 0x1, + 0, 0, + k230_hs_ssi0_mux_pdata); + +K230_CLK_GATE_FORMAT(hs_ssi0_gate, + K230_HS_SSI0_GATE, + 0x18, 24, CLK_IGNORE_UNUSED, 0, + &hs_ssi0_mux.clk.hw); + +K230_CLK_RATE_FORMAT(hs_usb_ref_50m_rate, + K230_HS_USB_REF_50M_RATE, + 1, 1, 0, 0, + 1, 8, 15, 0x7, + 0x20, 31, div, 0x0, + false, 0, + &pll0_div16.hw); + +K230_CLK_GATE_FORMAT_PNAME(hs_sd_timer_src_gate, + K230_HS_SD_TIMER_SRC_GATE, + 0x18, 12, 0, 0, + "osc24m"); + +K230_CLK_RATE_FORMAT(hs_sd_timer_src_rate, + K230_HS_SD_TIMER_SRC_RATE, + 1, 1, 0, 0, + 24, 32, 15, 0x1F, + 0x1C, 31, div, 0x0, + false, 0, + &hs_sd_timer_src_gate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd0_timer_gate, + K230_HS_SD0_TIMER_GATE, + 0x18, 16, 0, 0, + &hs_sd_timer_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(hs_sd1_timer_gate, + K230_HS_SD1_TIMER_GATE, + 0x18, 20, 0, 0, + &hs_sd_timer_src_rate.clk.hw); + +static const struct clk_parent_data k230_hs_usb_ref_mux_pdata[] = { + { .fw_name = "osc24m", }, + { .hw = &hs_usb_ref_50m_rate.clk.hw, }, +}; + +K230_CLK_MUX_FORMAT(hs_usb_ref_mux, + K230_HS_USB_REF_MUX, + 0x18, 23, 0x1, + 0, 0, + k230_hs_usb_ref_mux_pdata); + +K230_CLK_GATE_FORMAT(hs_usb0_ref_gate, + K230_HS_USB0_REF_GATE, + 0x18, 21, CLK_IGNORE_UNUSED, 0, + &hs_usb_ref_mux.clk.hw); + +K230_CLK_GATE_FORMAT(hs_usb1_ref_gate, + K230_HS_USB1_REF_GATE, + 0x18, 22, CLK_IGNORE_UNUSED, 0, + &hs_usb_ref_mux.clk.hw); + +K230_CLK_GATE_FORMAT(ls_apb_src_gate, + K230_LS_APB_SRC_GATE, + 0x24, 0, CLK_IS_CRITICAL, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_apb_src_rate, + K230_LS_APB_SRC_RATE, + 1, 1, 0, 0, + 1, 8, 0, 0x7, + 0x30, 31, div, 0x0, + false, 0, + &ls_apb_src_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart0_apb_gate, + K230_LS_UART0_APB_GATE, + 0x24, 1, CLK_IS_CRITICAL, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart1_apb_gate, + K230_LS_UART1_APB_GATE, + 0x24, 2, CLK_IS_CRITICAL, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart2_apb_gate, + K230_LS_UART2_APB_GATE, + 0x24, 3, CLK_IS_CRITICAL, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart3_apb_gate, + K230_LS_UART3_APB_GATE, + 0x24, 4, CLK_IS_CRITICAL, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart4_apb_gate, + K230_LS_UART4_APB_GATE, + 0x24, 5, CLK_IS_CRITICAL, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c0_apb_gate, + K230_LS_I2C0_APB_GATE, + 0x24, 6, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c1_apb_gate, + K230_LS_I2C1_APB_GATE, + 0x24, 7, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c2_apb_gate, + K230_LS_I2C2_APB_GATE, + 0x24, 8, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c3_apb_gate, + K230_LS_I2C3_APB_GATE, + 0x24, 9, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c4_apb_gate, + K230_LS_I2C4_APB_GATE, + 0x24, 10, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_gpio_apb_gate, + K230_LS_GPIO_APB_GATE, + 0x24, 11, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_pwm_apb_gate, + K230_LS_PWM_APB_GATE, + 0x24, 12, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_jamlink0_apb_gate, + K230_LS_JAMLINK0_APB_GATE, + 0x28, 4, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_jamlink1_apb_gate, + K230_LS_JAMLINK1_APB_GATE, + 0x28, 5, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_jamlink2_apb_gate, + K230_LS_JAMLINK2_APB_GATE, + 0x28, 6, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_jamlink3_apb_gate, + K230_LS_JAMLINK3_APB_GATE, + 0x28, 7, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_audio_apb_gate, + K230_LS_AUDIO_APB_GATE, + 0x24, 13, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_adc_apb_gate, + K230_LS_ADC_APB_GATE, + 0x24, 15, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_codec_apb_gate, + K230_LS_CODEC_APB_GATE, + 0x24, 14, 0, 0, + &ls_apb_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c0_gate, + K230_LS_I2C0_GATE, + 0x24, 21, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_i2c0_rate, + K230_LS_I2C0_RATE, + 1, 1, 0, 0, + 1, 8, 15, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_i2c0_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c1_gate, + K230_LS_I2C1_GATE, + 0x24, 22, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_i2c1_rate, + K230_LS_I2C1_RATE, + 1, 1, 0, 0, + 1, 8, 18, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_i2c1_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c2_gate, + K230_LS_I2C2_GATE, + 0x24, 23, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_i2c2_rate, + K230_LS_I2C2_RATE, + 1, 1, 0, 0, + 1, 8, 21, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_i2c2_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c3_gate, + K230_LS_I2C3_GATE, + 0x24, 24, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_i2c3_rate, + K230_LS_I2C3_RATE, + 1, 1, 0, 0, + 1, 8, 24, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_i2c3_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_i2c4_gate, + K230_LS_I2C4_GATE, + 0x24, 25, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_i2c4_rate, + K230_LS_I2C4_RATE, + 1, 1, 0, 0, + 1, 8, 27, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_i2c4_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_codec_adc_gate, + K230_LS_CODEC_ADC_GATE, + 0x24, 29, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_codec_adc_rate, + K230_LS_CODEC_ADC_RATE, + 0x10, 0x1B9, 14, 0x1FFF, + 0xC35, 0x3D09, 0, 0x3FFF, + 0x38, 31, mul_div, 0x38, + false, 0, + &ls_codec_adc_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_codec_dac_gate, + K230_LS_CODEC_DAC_GATE, + 0x24, 30, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_codec_dac_rate, + K230_LS_CODEC_DAC_RATE, + 0x10, 0x1B9, 14, 0x1FFF, + 0xC35, 0x3D09, 0, 0x3FFF, + 0x3C, 31, mul_div, 0x3C, + false, 0, + &ls_codec_dac_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_audio_dev_gate, + K230_LS_AUDIO_DEV_GATE, + 0x24, 28, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_audio_dev_rate, + K230_LS_AUDIO_DEV_RATE, + 0x4, 0x1B9, 16, 0x7FFF, + 0xC35, 0xF424, 0, 0xFFFF, + 0x34, 31, mul_div, 0x34, + false, 0, + &ls_audio_dev_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_pdm_gate, + K230_LS_PDM_GATE, + 0x24, 31, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_pdm_rate, + K230_LS_PDM_RATE, + 0x2, 0x1B9, 0, 0xFFFF, + 0xC35, 0x1E848, 0, 0x1FFFF, + 0x40, 0, mul_div, 0x44, + false, 0, + &ls_pdm_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_adc_gate, + K230_LS_ADC_GATE, + 0x24, 26, 0, 0, + &pll0_div4.hw); + +K230_CLK_RATE_FORMAT(ls_adc_rate, + K230_LS_ADC_RATE, + 1, 1, 0, 0, + 1, 1024, 3, 0x3FF, + 0x30, 31, div, 0x0, + false, 0, + &ls_adc_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart0_gate, + K230_LS_UART0_GATE, + 0x24, 16, CLK_IS_CRITICAL, 0, + &pll0_div16.hw); + +K230_CLK_RATE_FORMAT(ls_uart0_rate, + K230_LS_UART0_RATE, + 1, 1, 0, 0, + 1, 8, 0, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_uart0_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart1_gate, + K230_LS_UART1_GATE, + 0x24, 17, CLK_IS_CRITICAL, 0, + &pll0_div16.hw); + +K230_CLK_RATE_FORMAT(ls_uart1_rate, + K230_LS_UART1_RATE, + 1, 1, 0, 0, + 1, 8, 3, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_uart1_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart2_gate, + K230_LS_UART2_GATE, + 0x24, 18, CLK_IS_CRITICAL, 0, + &pll0_div16.hw); + +K230_CLK_RATE_FORMAT(ls_uart2_rate, + K230_LS_UART2_RATE, + 1, 1, 0, 0, + 1, 8, 6, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_uart2_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart3_gate, + K230_LS_UART3_GATE, + 0x24, 19, CLK_IS_CRITICAL, 0, + &pll0_div16.hw); + +K230_CLK_RATE_FORMAT(ls_uart3_rate, + K230_LS_UART3_RATE, + 1, 1, 0, 0, + 1, 8, 9, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_uart3_gate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_uart4_gate, + K230_LS_UART4_GATE, + 0x24, 20, CLK_IS_CRITICAL, 0, + &pll0_div16.hw); + +K230_CLK_RATE_FORMAT(ls_uart4_rate, + K230_LS_UART4_RATE, + 1, 1, 0, 0, + 1, 8, 12, 0x7, + 0x2C, 31, div, 0x0, + false, 0, + &ls_uart4_gate.clk.hw); + +K230_CLK_RATE_FORMAT(ls_jamlinkco_src_rate, + K230_LS_JAMLINKCO_SRC_RATE, + 1, 1, 0, 0, + 2, 512, 23, 0xFF, + 0x30, 31, div, 0x0, + false, 0, + &pll0_div16.hw); + +K230_CLK_GATE_FORMAT(ls_jamlink0co_gate, + K230_LS_JAMLINK0CO_GATE, + 0x28, 0, 0, 0, + &ls_jamlinkco_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_jamlink1co_gate, + K230_LS_JAMLINK1CO_GATE, + 0x28, 1, 0, 0, + &ls_jamlinkco_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_jamlink2co_gate, + K230_LS_JAMLINK2CO_GATE, + 0x28, 2, 0, 0, + &ls_jamlinkco_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT(ls_jamlink3co_gate, + K230_LS_JAMLINK3CO_GATE, + 0x28, 3, 0, 0, + &ls_jamlinkco_src_rate.clk.hw); + +K230_CLK_GATE_FORMAT_PNAME(ls_gpio_debounce_gate, + K230_LS_GPIO_DEBOUNCE_GATE, + 0x24, 27, 0, 0, + "osc24m"); + +K230_CLK_RATE_FORMAT(ls_gpio_debounce_rate, + K230_LS_GPIO_DEBOUNCE_RATE, + 1, 1, 0, 0, + 1, 1024, 13, 0x3FF, + 0x30, 31, div, 0x0, + false, 0, + &ls_gpio_debounce_gate.clk.hw); + +K230_CLK_GATE_FORMAT(sysctl_wdt0_apb_gate, + K230_SYSCTL_WDT0_APB_GATE, + 0x50, 1, 0, 0, + & |
