summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/Kconfig6
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/clk-k230.c2452
-rw-r--r--drivers/clk/renesas/clk-r8a73a4.c2
-rw-r--r--drivers/clk/renesas/clk-r8a7740.c2
-rw-r--r--drivers/clk/renesas/r8a779g0-cpg-mssr.c1
-rw-r--r--drivers/clk/renesas/r9a07g043-cpg.c2
-rw-r--r--drivers/clk/renesas/r9a07g044-cpg.c2
-rw-r--r--drivers/clk/renesas/r9a08g045-cpg.c13
-rw-r--r--drivers/clk/renesas/r9a08g046-cpg.c355
-rw-r--r--drivers/clk/renesas/r9a09g011-cpg.c7
-rw-r--r--drivers/clk/renesas/r9a09g047-cpg.c84
-rw-r--r--drivers/clk/renesas/r9a09g077-cpg.c1
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.c3
-rw-r--r--drivers/clk/renesas/rzg2l-cpg.c88
-rw-r--r--drivers/clk/renesas/rzg2l-cpg.h18
-rw-r--r--drivers/clk/renesas/rzv2h-cpg.c181
-rw-r--r--drivers/clk/renesas/rzv2h-cpg.h12
-rw-r--r--drivers/clk/socfpga/clk-agilex.c2
19 files changed, 3192 insertions, 40 deletions
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,
+ &pll0_div16.hw);
+
+K230_CLK_GATE_FORMAT(sysctl_wdt1_apb_gate,
+ K230_SYSCTL_WDT1_APB_GATE,
+ 0x50, 2, 0, 0,
+ &pll0_div16.hw);
+
+K230_CLK_GATE_FORMAT(sysctl_timer_apb_gate,
+ K230_SYSCTL_TIMER_APB_GATE,
+ 0x50, 3, 0, 0,
+ &pll0_div16.hw);
+
+K230_CLK_GATE_FORMAT(sysctl_iomux_apb_gate,
+ K230_SYSCTL_IOMUX_APB_GATE,
+ 0x50, 20, 0, 0,
+ &pll0_div16.hw);
+
+K230_CLK_GATE_FORMAT(sysctl_mailbox_apb_gate,
+ K230_SYSCTL_MAILBOX_APB_GATE,
+ 0x50, 4, 0, 0,
+ &pll0_div16.hw);
+
+K230_CLK_GATE_FORMAT(sysctl_hdi_gate,
+ K230_SYSCTL_HDI_GATE,
+ 0x50, 21, 0, 0,
+ &pll0_div4.hw);
+
+K230_CLK_RATE_FORMAT(sysctl_hdi_rate,
+ K230_SYSCTL_HDI_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 28, 0x7,
+ 0x58, 31, div, 0x0,
+ false, 0,
+ &sysctl_hdi_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(sysctl_time_stamp_gate,
+ K230_SYSCTL_TIME_STAMP_GATE,
+ 0x50, 19, CLK_IS_CRITICAL, 0,
+ &pll1_div4.hw);
+
+K230_CLK_RATE_FORMAT(sysctl_time_stamp_rate,
+ K230_SYSCTL_TIME_STAMP_RATE,
+ 1, 1, 0, 0,
+ 1, 32, 15, 0x1F,
+ 0x58, 31, div, 0x0,
+ false, 0,
+ &sysctl_time_stamp_gate.clk.hw);
+
+K230_CLK_RATE_FORMAT_PNAME(sysctl_temp_sensor_rate,
+ K230_SYSCTL_TEMP_SENSOR_RATE,
+ 1, 1, 0, 0,
+ 1, 256, 20, 0xFF,
+ 0x58, 31, div, 0x0,
+ false, 0,
+ "osc24m");
+
+K230_CLK_GATE_FORMAT_PNAME(sysctl_wdt0_gate,
+ K230_SYSCTL_WDT0_GATE,
+ 0x50, 5, 0, 0,
+ "osc24m");
+
+K230_CLK_RATE_FORMAT(sysctl_wdt0_rate,
+ K230_SYSCTL_WDT0_RATE,
+ 1, 1, 0, 0,
+ 1, 64, 3, 0x3F,
+ 0x58, 31, div, 0x0,
+ false, 0,
+ &sysctl_wdt0_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT_PNAME(sysctl_wdt1_gate,
+ K230_SYSCTL_WDT1_GATE,
+ 0x50, 6, 0, 0,
+ "osc24m");
+
+K230_CLK_RATE_FORMAT(sysctl_wdt1_rate,
+ K230_SYSCTL_WDT1_RATE,
+ 1, 1, 0, 0,
+ 1, 64, 9, 0x3F,
+ 0x58, 31, div, 0x0,
+ false, 0,
+ &sysctl_wdt1_gate.clk.hw);
+
+K230_CLK_RATE_FORMAT(timer0_src_rate,
+ K230_TIMER0_SRC_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 0, 0x7,
+ 0x54, 31, div, 0x0,
+ false, 0,
+ &pll0_div16.hw);
+
+K230_CLK_RATE_FORMAT(timer1_src_rate,
+ K230_TIMER1_SRC_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 3, 0x7,
+ 0x54, 31, div, 0x0,
+ false, 0,
+ &pll0_div16.hw);
+
+K230_CLK_RATE_FORMAT(timer2_src_rate,
+ K230_TIMER2_SRC_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 6, 0x7,
+ 0x54, 31, div, 0x0,
+ false, 0,
+ &pll0_div16.hw);
+
+K230_CLK_RATE_FORMAT(timer3_src_rate,
+ K230_TIMER3_SRC_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 9, 0x7,
+ 0x54, 31, div, 0x0,
+ false, 0,
+ &pll0_div16.hw);
+
+K230_CLK_RATE_FORMAT(timer4_src_rate,
+ K230_TIMER4_SRC_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 12, 0x7,
+ 0x54, 31, div, 0x0,
+ false, 0,
+ &pll0_div16.hw);
+
+K230_CLK_RATE_FORMAT(timer5_src_rate,
+ K230_TIMER5_SRC_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 15, 0x7,
+ 0x54, 31, div, 0x0,
+ false, 0,
+ &pll0_div16.hw);
+
+static const struct clk_parent_data k230_timer0_mux_pdata[] = {
+ { .fw_name = "timer-pulse-in", },
+ { .hw = &timer0_src_rate.clk.hw, },
+};
+
+K230_CLK_MUX_FORMAT(timer0_mux,
+ K230_TIMER0_MUX,
+ 0x50, 7, 0x1,
+ 0, 0,
+ k230_timer0_mux_pdata);
+
+K230_CLK_GATE_FORMAT(timer0_gate,
+ K230_TIMER0_GATE,
+ 0x50, 13, CLK_IGNORE_UNUSED, 0,
+ &timer0_mux.clk.hw);
+
+static const struct clk_parent_data k230_timer1_mux_pdata[] = {
+ { .fw_name = "timer-pulse-in", },
+ { .hw = &timer1_src_rate.clk.hw, },
+};
+
+K230_CLK_MUX_FORMAT(timer1_mux,
+ K230_TIMER1_MUX,
+ 0x50, 8, 0x1,
+ 0, 0,
+ k230_timer1_mux_pdata);
+
+K230_CLK_GATE_FORMAT(timer1_gate,
+ K230_TIMER1_GATE,
+ 0x50, 14, CLK_IGNORE_UNUSED, 0,
+ &timer1_mux.clk.hw);
+
+static const struct clk_parent_data k230_timer2_mux_pdata[] = {
+ { .fw_name = "timer-pulse-in", },
+ { .hw = &timer2_src_rate.clk.hw, },
+};
+
+K230_CLK_MUX_FORMAT(timer2_mux,
+ K230_TIMER2_MUX,
+ 0x50, 9, 0x1,
+ 0, 0,
+ k230_timer2_mux_pdata);
+
+K230_CLK_GATE_FORMAT(timer2_gate,
+ K230_TIMER2_GATE,
+ 0x50, 15, CLK_IGNORE_UNUSED, 0,
+ &timer2_mux.clk.hw);
+
+static const struct clk_parent_data k230_timer3_mux_pdata[] = {
+ { .fw_name = "timer-pulse-in", },
+ { .hw = &timer3_src_rate.clk.hw, },
+};
+
+K230_CLK_MUX_FORMAT(timer3_mux,
+ K230_TIMER3_MUX,
+ 0x50, 10, 0x1,
+ 0, 0,
+ k230_timer3_mux_pdata);
+
+K230_CLK_GATE_FORMAT(timer3_gate,
+ K230_TIMER3_GATE,
+ 0x50, 16, CLK_IGNORE_UNUSED, 0,
+ &timer3_mux.clk.hw);
+
+static const struct clk_parent_data k230_timer4_mux_pdata[] = {
+ { .fw_name = "timer-pulse-in", },
+ { .hw = &timer4_src_rate.clk.hw, },
+};
+
+K230_CLK_MUX_FORMAT(timer4_mux,
+ K230_TIMER4_MUX,
+ 0x50, 11, 0x1,
+ 0, 0,
+ k230_timer4_mux_pdata);
+
+K230_CLK_GATE_FORMAT(timer4_gate,
+ K230_TIMER4_GATE,
+ 0x50, 17, CLK_IGNORE_UNUSED, 0,
+ &timer4_mux.clk.hw);
+
+static const struct clk_parent_data k230_timer5_mux_pdata[] = {
+ { .fw_name = "timer-pulse-in", },
+ { .hw = &timer5_src_rate.clk.hw, },
+};
+
+K230_CLK_MUX_FORMAT(timer5_mux,
+ K230_TIMER5_MUX,
+ 0x50, 12, 0x1,
+ 0, 0,
+ k230_timer5_mux_pdata);
+
+K230_CLK_GATE_FORMAT(timer5_gate,
+ K230_TIMER5_GATE,
+ 0x50, 18, CLK_IGNORE_UNUSED, 0,
+ &timer5_mux.clk.hw);
+
+K230_CLK_GATE_FORMAT(shrm_apb_gate,
+ K230_SHRM_APB_GATE,
+ 0x5C, 0, 0, 0,
+ &pll0_div4.hw);
+
+K230_CLK_RATE_FORMAT(shrm_apb_rate,
+ K230_SHRM_APB_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 18, 0x7,
+ 0x5C, 31, div, 0x0,
+ false, 0,
+ &shrm_apb_gate.clk.hw);
+
+static const struct clk_parent_data k230_shrm_sram_mux_pdata[] = {
+ { .hw = &pll3_div2.hw, },
+ { .hw = &pll0_div2.hw, },
+};
+
+K230_CLK_MUX_FORMAT(shrm_sram_mux,
+ K230_SHRM_SRAM_MUX,
+ 0x50, 14, 0x1,
+ 0, 0,
+ k230_shrm_sram_mux_pdata);
+
+K230_CLK_GATE_FORMAT(shrm_sram_gate,
+ K230_SHRM_SRAM_GATE,
+ 0x5c, 10, CLK_IGNORE_UNUSED, 0,
+ &shrm_sram_mux.clk.hw);
+
+K230_CLK_FIXED_FACTOR_FORMAT(shrm_sram_div2,
+ 1, 2, 0,
+ &shrm_sram_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(shrm_axi_slave_gate,
+ K230_SHRM_AXI_SLAVE_GATE,
+ 0x5C, 11, CLK_IGNORE_UNUSED, 0,
+ &shrm_sram_div2.hw);
+
+K230_CLK_GATE_FORMAT(shrm_axi_gate,
+ K230_SHRM_AXI_GATE,
+ 0x5C, 12, 0, 0,
+ &pll0_div4.hw);
+
+K230_CLK_GATE_FORMAT(shrm_nonai2d_axi_gate,
+ K230_SHRM_NONAI2D_AXI_GATE,
+ 0x5C, 9, 0, 0,
+ &shrm_axi_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(shrm_decompress_axi_gate,
+ K230_SHRM_DECOMPRESS_AXI_GATE,
+ 0x5C, 7, CLK_IGNORE_UNUSED, 0,
+ &shrm_sram_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(shrm_sdma_axi_gate,
+ K230_SHRM_SDMA_AXI_GATE,
+ 0x5C, 5, 0, 0,
+ &shrm_axi_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(shrm_pdma_axi_gate,
+ K230_SHRM_PDMA_AXI_GATE,
+ 0x5C, 3, 0, 0,
+ &shrm_axi_gate.clk.hw);
+
+static const struct clk_parent_data k230_ddrc_src_mux_pdata[] = {
+ { .hw = &pll0_div2.hw, },
+ { .hw = &pll0_div3.hw, },
+ { .hw = &pll2_div4.hw, },
+};
+
+K230_CLK_MUX_FORMAT(ddrc_src_mux,
+ K230_DDRC_SRC_MUX,
+ 0x60, 0, 0x3,
+ 0, 0,
+ k230_ddrc_src_mux_pdata);
+
+K230_CLK_GATE_FORMAT(ddrc_src_gate,
+ K230_DDRC_SRC_GATE,
+ 0x60, 2, CLK_IGNORE_UNUSED, 0,
+ &ddrc_src_mux.clk.hw);
+
+K230_CLK_RATE_FORMAT(ddrc_src_rate,
+ K230_DDRC_SRC_RATE,
+ 1, 1, 0, 0,
+ 1, 16, 10, 0xF,
+ 0x60, 31, div, 0x0,
+ false, 0,
+ &ddrc_src_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(ddrc_bypass_gate,
+ K230_DDRC_BYPASS_GATE,
+ 0x60, 8, 0, 0,
+ &pll2_div4.hw);
+
+K230_CLK_GATE_FORMAT(ddrc_apb_gate,
+ K230_DDRC_APB_GATE,
+ 0x60, 9, 0, 0,
+ &pll0_div4.hw);
+
+K230_CLK_RATE_FORMAT(ddrc_apb_rate,
+ K230_DDRC_APB_RATE,
+ 1, 1, 0, 0,
+ 1, 16, 14, 0xF,
+ 0x60, 31, div, 0x0,
+ false, 0,
+ &ddrc_apb_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(display_ahb_gate,
+ K230_DISPLAY_AHB_GATE,
+ 0x74, 0, 0, 0,
+ &pll0_div4.hw);
+
+K230_CLK_RATE_FORMAT(display_ahb_rate,
+ K230_DISPLAY_AHB_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 0, 0x7,
+ 0x78, 31, div, 0x0,
+ false, 0,
+ &display_ahb_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(display_axi_gate,
+ K230_DISPLAY_AXI_GATE,
+ 0x74, 1, 0, 0,
+ &pll0_div4.hw);
+
+K230_CLK_RATE_FORMAT(display_clkext_rate,
+ K230_DISPLAY_CLKEXT_RATE,
+ 1, 1, 0, 0,
+ 1, 16, 16, 0xF,
+ 0x78, 31, div, 0x0,
+ false, 0,
+ &pll0_div3.hw);
+
+K230_CLK_GATE_FORMAT(display_gpu_gate,
+ K230_DISPLAY_GPU_GATE,
+ 0x74, 6, 0, 0,
+ &pll0_div3.hw);
+
+K230_CLK_RATE_FORMAT(display_gpu_rate,
+ K230_DISPLAY_GPU_RATE,
+ 1, 1, 0, 0,
+ 1, 16, 20, 0xF,
+ 0x78, 31, div, 0x0,
+ false, 0,
+ &display_gpu_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(display_dpip_gate,
+ K230_DISPLAY_DPIP_GATE,
+ 0x74, 2, 0, 0,
+ &pll1_div4.hw);
+
+K230_CLK_RATE_FORMAT(display_dpip_rate,
+ K230_DISPLAY_DPIP_RATE,
+ 1, 1, 0, 0,
+ 1, 256, 3, 0xFF,
+ 0x78, 31, div, 0x0,
+ false, 0,
+ &display_dpip_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(display_cfg_gate,
+ K230_DISPLAY_CFG_GATE,
+ 0x74, 4, 0, 0,
+ &pll1_div4.hw);
+
+K230_CLK_RATE_FORMAT(display_cfg_rate,
+ K230_DISPLAY_CFG_RATE,
+ 1, 1, 0, 0,
+ 1, 32, 11, 0x1F,
+ 0x78, 31, div, 0x0,
+ false, 0,
+ &display_cfg_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT_PNAME(display_ref_gate,
+ K230_DISPLAY_REF_GATE,
+ 0x74, 3, 0, 0,
+ "osc24m");
+
+K230_CLK_GATE_FORMAT(vpu_src_gate,
+ K230_VPU_SRC_GATE,
+ 0xC, 0, 0, 0,
+ &pll0_div2.hw);
+
+K230_CLK_RATE_FORMAT(vpu_src_rate,
+ K230_VPU_SRC_RATE,
+ 1, 16, 1, 0xF,
+ 16, 16, 0, 0,
+ 0x0, 31, mul, 0xC,
+ false, 0,
+ &vpu_src_gate.clk.hw);
+
+K230_CLK_RATE_FORMAT(vpu_axi_src_rate,
+ K230_VPU_AXI_SRC_RATE,
+ 1, 1, 0, 0,
+ 1, 16, 6, 0xF,
+ 0xC, 31, div, 0x0,
+ false, 0,
+ &vpu_src_rate.clk.hw);
+
+K230_CLK_GATE_FORMAT(vpu_axi_gate,
+ K230_VPU_AXI_GATE,
+ 0xC, 5, 0, 0,
+ &vpu_axi_src_rate.clk.hw);
+
+K230_CLK_GATE_FORMAT(vpu_ddrcp2_gate,
+ K230_VPU_DDRCP2_GATE,
+ 0x60, 5, 0, 0,
+ &vpu_axi_src_rate.clk.hw);
+
+K230_CLK_GATE_FORMAT(vpu_cfg_gate,
+ K230_VPU_CFG_GATE,
+ 0xC, 10, 0, 0,
+ &pll0_div4.hw);
+
+K230_CLK_RATE_FORMAT(vpu_cfg_rate,
+ K230_VPU_CFG_RATE,
+ 1, 1, 0, 0,
+ 1, 16, 11, 0xF,
+ 0xC, 31, div, 0x0,
+ false, 0,
+ &vpu_cfg_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(sec_apb_gate,
+ K230_SEC_APB_GATE,
+ 0x80, 0, 0, 0,
+ &pll1_div4.hw);
+
+K230_CLK_RATE_FORMAT(sec_apb_rate,
+ K230_SEC_APB_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 1, 0x7,
+ 0x80, 31, div, 0x0,
+ false, 0,
+ &sec_apb_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(sec_fix_gate,
+ K230_SEC_FIX_GATE,
+ 0x80, 5, 0, 0,
+ &pll1_div4.hw);
+
+K230_CLK_RATE_FORMAT(sec_fix_rate,
+ K230_SEC_FIX_RATE,
+ 1, 1, 0, 0,
+ 1, 32, 6, 0x1F,
+ 0x80, 31, div, 0x0,
+ false, 0,
+ &sec_fix_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(sec_axi_gate,
+ K230_SEC_AXI_GATE,
+ 0x80, 4, 0, 0,
+ &pll1_div4.hw);
+
+K230_CLK_RATE_FORMAT(sec_axi_rate,
+ K230_SEC_AXI_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 11, 0x3,
+ 0x80, 31, div, 0,
+ false, 0,
+ &sec_axi_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(usb_480m_gate,
+ K230_USB_480M_GATE,
+ 0x100, 0, 0, 0,
+ &pll1.hw);
+
+K230_CLK_RATE_FORMAT(usb_480m_rate,
+ K230_USB_480M_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 1, 0x7,
+ 0x100, 31, div, 0,
+ false, 0,
+ &usb_480m_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(usb_100m_gate,
+ K230_USB_100M_GATE,
+ 0x100, 0, 0, 0,
+ &pll0_div4.hw);
+
+K230_CLK_RATE_FORMAT(usb_100m_rate,
+ K230_USB_100M_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 4, 0x7,
+ 0x100, 31, div, 0,
+ false, 0,
+ &usb_100m_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(dphy_dft_gate,
+ K230_DPHY_DFT_GATE,
+ 0x100, 0, 0, 0,
+ &pll0.hw);
+
+K230_CLK_RATE_FORMAT(dphy_dft_rate,
+ K230_DPHY_DFT_RATE,
+ 1, 1, 0, 0,
+ 1, 16, 1, 0xF,
+ 0x104, 31, div, 0,
+ false, 0,
+ &dphy_dft_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(spi2axi_gate,
+ K230_SPI2AXI_GATE,
+ 0x108, 0, 0, 0,
+ &pll0_div4.hw);
+
+K230_CLK_RATE_FORMAT(spi2axi_rate,
+ K230_SPI2AXI_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 1, 0x7,
+ 0x108, 31, div, 0x0,
+ false, 0,
+ &spi2axi_gate.clk.hw);
+
+static const struct clk_parent_data k230_ai_src_mux_pdata[] = {
+ { .hw = &pll0_div2.hw, },
+ { .hw = &pll3_div2.hw, },
+};
+
+K230_CLK_MUX_FORMAT(ai_src_mux,
+ K230_AI_SRC_MUX,
+ 0x8, 2, 0x1,
+ 0, 0,
+ k230_ai_src_mux_pdata);
+
+K230_CLK_GATE_FORMAT(ai_src_gate,
+ K230_AI_SRC_GATE,
+ 0x8, 0, CLK_IGNORE_UNUSED, 0,
+ &ai_src_mux.clk.hw);
+
+K230_CLK_RATE_FORMAT(ai_src_rate,
+ K230_AI_SRC_RATE,
+ 1, 1, 0, 0,
+ 1, 8, 3, 0x7,
+ 0x8, 31, div, 0x0,
+ false, 0,
+ &ai_src_gate.clk.hw);
+
+K230_CLK_GATE_FORMAT(ai_axi_gate,
+ K230_AI_AXI_GATE,
+ 0x8, 10, 0, 0,
+ &pll0_div4.hw);
+
+static const struct clk_parent_data k230_camera0_mux_pdata[] = {
+ { .hw = &pll1_div3.hw, },
+ { .hw = &pll1_div4.hw, },
+ { .hw = &pll0_div4.hw, },
+};
+
+K230_CLK_MUX_FORMAT(camera0_mux,
+ K230_CAMERA0_MUX,
+ 0x6C, 3, 0x3,
+ 0, 0,
+ k230_camera0_mux_pdata);
+
+K230_CLK_GATE_FORMAT(camera0_gate,
+ K230_CAMERA0_GATE,
+ 0x6C, 0, CLK_IGNORE_UNUSED, 0,
+ &camera0_mux.clk.hw);
+
+K230_CLK_RATE_FORMAT(camera0_rate,
+ K230_CAMERA0_RATE,
+ 1, 1, 0, 0,
+ 1, 32, 5, 0x1f,
+ 0x6C, 31, div, 0x0,
+ false, 0,
+ &camera0_gate.clk.hw);
+
+static const struct clk_parent_data k230_camera1_mux_pdata[] = {
+ { .hw = &pll1_div3.hw, },
+ { .hw = &pll1_div4.hw, },
+ { .hw = &pll0_div4.hw, },
+};
+
+K230_CLK_MUX_FORMAT(camera1_mux,
+ K230_CAMERA1_MUX,
+ 0x6C, 10, 0x3,
+ 0, 0,
+ k230_camera1_mux_pdata);
+
+K230_CLK_GATE_FORMAT(camera1_gate,
+ K230_CAMERA1_GATE,
+ 0x6C, 1, CLK_IGNORE_UNUSED, 0,
+ &camera1_mux.clk.hw);
+
+K230_CLK_RATE_FORMAT(camera1_rate,
+ K230_CAMERA1_RATE,
+ 1, 1, 0, 0,
+ 1, 32, 12, 0x1f,
+ 0x6C, 31, div, 0x0,
+ false, 0,
+ &camera1_gate.clk.hw);
+
+static const struct clk_parent_data k230_camera2_mux_pdata[] = {
+ { .hw = &pll1_div3.hw, },
+ { .hw = &pll1_div4.hw, },
+ { .hw = &pll0_div4.hw, },
+};
+
+K230_CLK_MUX_FORMAT(camera2_mux,
+ K230_CAMERA2_MUX,
+ 0x6C, 17, 0x3,
+ 0, 0,
+ k230_camera2_mux_pdata);
+
+K230_CLK_GATE_FORMAT(camera2_gate,
+ K230_CAMERA2_GATE,
+ 0x6C, 2, CLK_IGNORE_UNUSED, 0,
+ &camera2_mux.clk.hw);
+
+K230_CLK_RATE_FORMAT(camera2_rate,
+ K230_CAMERA2_RATE,
+ 1, 1, 0, 0,
+ 1, 32, 19, 0x1f,
+ 0x6C, 31, div, 0x0,
+ false, 0,
+ &camera2_gate.clk.hw);
+
+static struct k230_clk_mux *k230_clk_muxs[] = {
+ &hs_ssi0_mux,
+ &hs_usb_ref_mux,
+ &cpu1_src_mux,
+ &timer0_mux,
+ &timer1_mux,
+ &timer2_mux,
+ &timer3_mux,
+ &timer4_mux,
+ &timer5_mux,
+ &shrm_sram_mux,
+ &ddrc_src_mux,
+ &ai_src_mux,
+ &camera0_mux,
+ &camera1_mux,
+ &camera2_mux,
+};
+
+#define K230_CLK_MUX_NUM ARRAY_SIZE(k230_clk_muxs)
+
+static struct k230_clk_gate *k230_clk_gates[] = {
+ &cpu0_src_gate,
+ &cpu0_plic_gate,
+ &cpu0_noc_ddrcp4_gate,
+ &cpu0_apb_gate,
+ &cpu1_src_gate,
+ &cpu1_plic_gate,
+ &cpu1_apb_gate,
+ &pmu_apb_gate,
+ &hs_hclk_high_gate,
+ &hs_hclk_gate,
+ &hs_sd0_ahb_gate,
+ &hs_sd1_ahb_gate,
+ &hs_ssi1_ahb_gate,
+ &hs_ssi2_ahb_gate,
+ &hs_usb0_ahb_gate,
+ &hs_usb1_ahb_gate,
+ &hs_ssi0_axi_gate,
+ &hs_ssi1_gate,
+ &hs_ssi2_gate,
+ &hs_qspi_axi_src_gate,
+ &hs_ssi1_axi_gate,
+ &hs_ssi2_axi_gate,
+ &hs_sd_card_src_gate,
+ &hs_sd0_card_gate,
+ &hs_sd1_card_gate,
+ &hs_sd_axi_src_gate,
+ &hs_sd0_axi_gate,
+ &hs_sd1_axi_gate,
+ &hs_sd0_base_gate,
+ &hs_sd1_base_gate,
+ &hs_ssi0_gate,
+ &hs_sd_timer_src_gate,
+ &hs_sd0_timer_gate,
+ &hs_sd1_timer_gate,
+ &hs_usb0_ref_gate,
+ &hs_usb1_ref_gate,
+ &ls_apb_src_gate,
+ &ls_uart0_apb_gate,
+ &ls_uart1_apb_gate,
+ &ls_uart2_apb_gate,
+ &ls_uart3_apb_gate,
+ &ls_uart4_apb_gate,
+ &ls_i2c0_apb_gate,
+ &ls_i2c1_apb_gate,
+ &ls_i2c2_apb_gate,
+ &ls_i2c3_apb_gate,
+ &ls_i2c4_apb_gate,
+ &ls_gpio_apb_gate,
+ &ls_pwm_apb_gate,
+ &ls_jamlink0_apb_gate,
+ &ls_jamlink1_apb_gate,
+ &ls_jamlink2_apb_gate,
+ &ls_jamlink3_apb_gate,
+ &ls_audio_apb_gate,
+ &ls_adc_apb_gate,
+ &ls_codec_apb_gate,
+ &ls_i2c0_gate,
+ &ls_i2c1_gate,
+ &ls_i2c2_gate,
+ &ls_i2c3_gate,
+ &ls_i2c4_gate,
+ &ls_codec_adc_gate,
+ &ls_codec_dac_gate,
+ &ls_audio_dev_gate,
+ &ls_pdm_gate,
+ &ls_adc_gate,
+ &ls_uart0_gate,
+ &ls_uart1_gate,
+ &ls_uart2_gate,
+ &ls_uart3_gate,
+ &ls_uart4_gate,
+ &ls_jamlink0co_gate,
+ &ls_jamlink1co_gate,
+ &ls_jamlink2co_gate,
+ &ls_jamlink3co_gate,
+ &ls_gpio_debounce_gate,
+ &sysctl_wdt0_apb_gate,
+ &sysctl_wdt1_apb_gate,
+ &sysctl_timer_apb_gate,
+ &sysctl_iomux_apb_gate,
+ &sysctl_mailbox_apb_gate,
+ &sysctl_hdi_gate,
+ &sysctl_time_stamp_gate,
+ &sysctl_wdt0_gate,
+ &sysctl_wdt1_gate,
+ &timer0_gate,
+ &timer1_gate,
+ &timer2_gate,
+ &timer3_gate,
+ &timer4_gate,
+ &timer5_gate,
+ &shrm_apb_gate,
+ &shrm_sram_gate,
+ &shrm_axi_gate,
+ &shrm_axi_slave_gate,
+ &shrm_nonai2d_axi_gate,
+ &shrm_decompress_axi_gate,
+ &shrm_sdma_axi_gate,
+ &shrm_pdma_axi_gate,
+ &ddrc_src_gate,
+ &ddrc_bypass_gate,
+ &ddrc_apb_gate,
+ &display_ahb_gate,
+ &display_axi_gate,
+ &display_gpu_gate,
+ &display_dpip_gate,
+ &display_cfg_gate,
+ &display_ref_gate,
+ &vpu_src_gate,
+ &vpu_axi_gate,
+ &vpu_ddrcp2_gate,
+ &vpu_cfg_gate,
+ &sec_apb_gate,
+ &sec_fix_gate,
+ &sec_axi_gate,
+ &usb_480m_gate,
+ &usb_100m_gate,
+ &dphy_dft_gate,
+ &spi2axi_gate,
+ &ai_src_gate,
+ &ai_axi_gate,
+ &camera0_gate,
+ &camera1_gate,
+ &camera2_gate,
+};
+
+#define K230_CLK_GATE_NUM ARRAY_SIZE(k230_clk_gates)
+
+static struct k230_clk_rate *k230_clk_rates[] = {
+ &cpu0_src_rate,
+ &cpu0_axi_rate,
+ &cpu0_plic_rate,
+ &cpu0_apb_rate,
+ &cpu1_src_rate,
+ &cpu1_axi_rate,
+ &cpu1_plic_rate,
+ &hs_hclk_high_rate,
+ &hs_hclk_rate,
+ &hs_ssi0_axi_rate,
+ &hs_ssi1_rate,
+ &hs_ssi2_rate,
+ &hs_qspi_axi_src_rate,
+ &hs_sd_card_src_rate,
+ &hs_sd_axi_src_rate,
+ &hs_usb_ref_50m_rate,
+ &hs_sd_timer_src_rate,
+ &ls_apb_src_rate,
+ &ls_gpio_debounce_rate,
+ &ls_i2c0_rate,
+ &ls_i2c1_rate,
+ &ls_i2c2_rate,
+ &ls_i2c3_rate,
+ &ls_i2c4_rate,
+ &ls_codec_adc_rate,
+ &ls_codec_dac_rate,
+ &ls_audio_dev_rate,
+ &ls_pdm_rate,
+ &ls_adc_rate,
+ &ls_uart0_rate,
+ &ls_uart1_rate,
+ &ls_uart2_rate,
+ &ls_uart3_rate,
+ &ls_uart4_rate,
+ &ls_jamlinkco_src_rate,
+ &sysctl_hdi_rate,
+ &sysctl_time_stamp_rate,
+ &sysctl_temp_sensor_rate,
+ &sysctl_wdt0_rate,
+ &sysctl_wdt1_rate,
+ &timer0_src_rate,
+ &timer1_src_rate,
+ &timer2_src_rate,
+ &timer3_src_rate,
+ &timer4_src_rate,
+ &timer5_src_rate,
+ &shrm_apb_rate,
+ &ddrc_src_rate,
+ &ddrc_apb_rate,
+ &display_ahb_rate,
+ &display_clkext_rate,
+ &display_gpu_rate,
+ &display_dpip_rate,
+ &display_cfg_rate,
+ &vpu_src_rate,
+ &vpu_axi_src_rate,
+ &vpu_cfg_rate,
+ &sec_apb_rate,
+ &sec_fix_rate,
+ &sec_axi_rate,
+ &usb_480m_rate,
+ &usb_100m_rate,
+ &dphy_dft_rate,
+ &spi2axi_rate,
+ &ai_src_rate,
+ &camera0_rate,
+ &camera1_rate,
+ &camera2_rate,
+};
+
+#define K230_CLK_RATE_NUM ARRAY_SIZE(k230_clk_rates)
+
+#define K230_CLK_NUM (K230_CLK_MUX_NUM + K230_CLK_GATE_NUM + K230_CLK_RATE_NUM + 1)
+
+static int k230_pll_prepare(struct clk_hw *hw)
+{
+ struct k230_pll *pll = hw_to_k230_pll(hw);
+ u32 reg;
+
+ /* wait for PLL lock until it reaches lock status */
+ return readl_poll_timeout(K230_PLLX_LOCK_ADDR(pll->reg, pll->id), reg,
+ reg & K230_PLL_LOCK_STATUS_MASK,
+ K230_PLL_LOCK_TIME_DELAY, K230_PLL_LOCK_TIMEOUT);
+}
+
+static inline bool k230_pll_hw_is_enabled(struct k230_pll *pll)
+{
+ return readl(K230_PLLX_GATE_ADDR(pll->reg, pll->id)) & K230_PLL_GATE_ENABLE;
+}
+
+static void k230_pll_enable_hw(struct k230_pll *pll)
+{
+ u32 reg;
+
+ if (k230_pll_hw_is_enabled(pll))
+ return;
+
+ reg = readl(K230_PLLX_GATE_ADDR(pll->reg, pll->id));
+ reg |= K230_PLL_GATE_ENABLE | K230_PLL_GATE_WRITE_ENABLE;
+ writel(reg, K230_PLLX_GATE_ADDR(pll->reg, pll->id));
+}
+
+static int k230_pll_enable(struct clk_hw *hw)
+{
+ struct k230_pll *pll = hw_to_k230_pll(hw);
+
+ guard(spinlock)(pll->lock);
+
+ k230_pll_enable_hw(pll);
+
+ return 0;
+}
+
+static void k230_pll_disable(struct clk_hw *hw)
+{
+ struct k230_pll *pll = hw_to_k230_pll(hw);
+ u32 reg;
+
+ guard(spinlock)(pll->lock);
+
+ reg = readl(K230_PLLX_GATE_ADDR(pll->reg, pll->id));
+ reg &= ~(K230_PLL_GATE_ENABLE);
+ reg |= (K230_PLL_GATE_WRITE_ENABLE);
+ writel(reg, K230_PLLX_GATE_ADDR(pll->reg, pll->id));
+}
+
+static int k230_pll_is_enabled(struct clk_hw *hw)
+{
+ return k230_pll_hw_is_enabled(hw_to_k230_pll(hw));
+}
+
+static unsigned long k230_pll_get_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct k230_pll *pll = hw_to_k230_pll(hw);
+ u32 reg;
+ u32 r, f, od;
+
+ guard(spinlock)(pll->lock);
+
+ reg = readl(K230_PLLX_BYPASS_ADDR(pll->reg, pll->id));
+ if (reg & K230_PLL_BYPASS_ENABLE)
+ return parent_rate;
+
+ reg = readl(K230_PLLX_LOCK_ADDR(pll->reg, pll->id));
+ if (!(reg & (K230_PLL_LOCK_STATUS_MASK)))
+ return 0;
+
+ reg = readl(K230_PLLX_DIV_ADDR(pll->reg, pll->id));
+ r = FIELD_GET(K230_PLL_R_MASK, reg) + 1;
+ f = FIELD_GET(K230_PLL_F_MASK, reg) + 1;
+ od = FIELD_GET(K230_PLL_OD_MASK, reg) + 1;
+
+ return mul_u64_u32_div(parent_rate, f, r * od);
+}
+
+static int k230_register_plls(struct platform_device *pdev, spinlock_t *lock,
+ void __iomem *reg)
+{
+ int i, ret;
+ struct k230_pll *pll;
+
+ for (i = 0; i < ARRAY_SIZE(k230_plls); i++) {
+ const char *name;
+
+ pll = k230_plls[i];
+
+ name = pll->hw.init->name;
+ pll->lock = lock;
+ pll->reg = reg;
+
+ ret = devm_clk_hw_register(&pdev->dev, &pll->hw);
+ if (ret)
+ return ret;
+
+ ret = devm_clk_hw_register_clkdev(&pdev->dev, &pll->hw, name, NULL);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int k230_register_pll_divs(struct platform_device *pdev)
+{
+ struct clk_fixed_factor *pll_div;
+ int ret;
+
+ for (int i = 0; i < ARRAY_SIZE(k230_pll_divs); i++) {
+ const char *name;
+
+ pll_div = k230_pll_divs[i];
+
+ name = pll_div->hw.init->name;
+
+ ret = devm_clk_hw_register(&pdev->dev, &pll_div->hw);
+ if (ret)
+ return ret;
+
+ ret = devm_clk_hw_register_clkdev(&pdev->dev, &pll_div->hw,
+ name, NULL);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static unsigned long k230_clk_get_rate_mul(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct k230_clk_rate *clk = hw_to_k230_clk_rate(hw);
+ struct k230_clk_rate_self *rate_self = &clk->clk;
+ u32 mul, div;
+
+ guard(spinlock)(rate_self->lock);
+
+ div = rate_self->div_max;
+ mul = (readl(rate_self->reg + clk->mul_reg_off) >> rate_self->mul_shift)
+ & rate_self->mul_mask;
+
+ return mul_u64_u32_div(parent_rate, mul + 1, div);
+}
+
+static unsigned long k230_clk_get_rate_div(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct k230_clk_rate *clk = hw_to_k230_clk_rate(hw);
+ struct k230_clk_rate_self *rate_self = &clk->clk;
+ u32 mul, div;
+
+ guard(spinlock)(rate_self->lock);
+
+ mul = rate_self->mul_max;
+ div = (readl(rate_self->reg + clk->div_reg_off) >> rate_self->div_shift)
+ & rate_self->div_mask;
+
+ return mul_u64_u32_div(parent_rate, mul, div + 1);
+}
+
+static unsigned long k230_clk_get_rate_mul_div(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct k230_clk_rate *clk = hw_to_k230_clk_rate(hw);
+ struct k230_clk_rate_self *rate_self = &clk->clk;
+ u32 mul, div;
+
+ guard(spinlock)(rate_self->lock);
+
+ div = (readl(rate_self->reg + clk->div_reg_off) >> rate_self->div_shift)
+ & rate_self->div_mask;
+ mul = (readl(rate_self->reg + clk->mul_reg_off) >> rate_self->mul_shift)
+ & rate_self->mul_mask;
+
+ return mul_u64_u32_div(parent_rate, mul, div);
+}
+
+static int k230_clk_find_approximate_mul(u32 mul_min, u32 mul_max,
+ u32 div_min, u32 div_max,
+ unsigned long rate, unsigned long parent_rate,
+ u32 *div, u32 *mul)
+{
+ long abs_min;
+ long abs_current;
+ long perfect_divide;
+
+ if (!rate || !parent_rate || !mul_min)
+ return -EINVAL;
+
+ perfect_divide = (long)((parent_rate * 1000) / rate);
+ abs_min = abs(perfect_divide -
+ (long)(((long)div_max * 1000) / (long)mul_min));
+ *mul = mul_min;
+
+ for (u32 i = mul_min + 1; i <= mul_max; i++) {
+ abs_current = abs(perfect_divide -
+ (long)(((long)div_max * 1000) / (long)i));
+
+ if (abs_min > abs_current) {
+ abs_min = abs_current;
+ *mul = i;
+ }
+ }
+
+ *div = div_max;
+
+ return 0;
+}
+
+static int k230_clk_find_approximate_div(u32 mul_min, u32 mul_max,
+ u32 div_min, u32 div_max,
+ unsigned long rate, unsigned long parent_rate,
+ u32 *div, u32 *mul)
+{
+ long abs_min;
+ long abs_current;
+ long perfect_divide;
+
+ if (!rate || !parent_rate || !mul_max)
+ return -EINVAL;
+
+ perfect_divide = (long)((parent_rate * 1000) / rate);
+ abs_min = abs(perfect_divide -
+ (long)(((long)div_min * 1000) / (long)mul_max));
+ *div = div_min;
+
+ for (u32 i = div_min + 1; i <= div_max; i++) {
+ abs_current = abs(perfect_divide -
+ (long)(((long)i * 1000) / (long)mul_max));
+
+ if (abs_min > abs_current) {
+ abs_min = abs_current;
+ *div = i;
+ }
+ }
+
+ *mul = mul_max;
+
+ return 0;
+}
+
+static int k230_clk_find_approximate_mul_div(u32 mul_min, u32 mul_max,
+ u32 div_min, u32 div_max,
+ unsigned long rate,
+ unsigned long parent_rate,
+ u32 *div, u32 *mul)
+{
+ unsigned long best_mul, best_div;
+
+ if (!rate || !parent_rate || !mul_min)
+ return -EINVAL;
+
+ rational_best_approximation(rate, parent_rate,
+ (unsigned long)mul_max, (unsigned long)div_max,
+ &best_mul, &best_div);
+
+ if (best_mul < mul_min)
+ best_mul = mul_min;
+
+ if (best_div < div_min)
+ best_div = div_min;
+
+ *mul = (u32)best_mul;
+ *div = (u32)best_div;
+
+ return 0;
+}
+
+static int k230_clk_determine_rate_mul(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ int ret;
+ struct k230_clk_rate_self *rate_self = hw_to_k230_clk_rate_self(hw);
+ unsigned long rate = req->rate;
+ unsigned long parent_rate = req->best_parent_rate;
+ u32 div, mul;
+
+ ret = k230_clk_find_approximate_mul(rate_self->mul_min, rate_self->mul_max,
+ rate_self->div_min, rate_self->div_max,
+ rate, parent_rate, &div, &mul);
+ if (ret)
+ return ret;
+
+ req->rate = mul_u64_u32_div(parent_rate, mul, div);
+
+ return 0;
+}
+
+static int k230_clk_determine_rate_div(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ int ret;
+ struct k230_clk_rate_self *rate_self = hw_to_k230_clk_rate_self(hw);
+ unsigned long rate = req->rate;
+ unsigned long parent_rate = req->best_parent_rate;
+ u32 div, mul;
+
+ ret = k230_clk_find_approximate_div(rate_self->mul_min, rate_self->mul_max,
+ rate_self->div_min, rate_self->div_max,
+ rate, parent_rate, &div, &mul);
+ if (ret)
+ return ret;
+
+ req->rate = mul_u64_u32_div(parent_rate, mul, div);
+
+ return 0;
+}
+
+static int k230_clk_determine_rate_mul_div(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ int ret;
+ struct k230_clk_rate_self *rate_self = hw_to_k230_clk_rate_self(hw);
+ unsigned long rate = req->rate;
+ unsigned long parent_rate = req->best_parent_rate;
+ u32 div, mul;
+
+ ret = k230_clk_find_approximate_mul_div(rate_self->mul_min, rate_self->mul_max,
+ rate_self->div_min, rate_self->div_max,
+ rate, parent_rate, &div, &mul);
+ if (ret)
+ return ret;
+
+ req->rate = mul_u64_u32_div(parent_rate, mul, div);
+
+ return 0;
+}
+
+static int k230_clk_set_rate_mul(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ int ret;
+ struct k230_clk_rate *clk = hw_to_k230_clk_rate(hw);
+ struct k230_clk_rate_self *rate_self = &clk->clk;
+ u32 div, mul, mul_reg;
+
+ if (rate > parent_rate)
+ return -EINVAL;
+
+ if (rate_self->read_only)
+ return 0;
+
+ ret = k230_clk_find_approximate_mul(rate_self->mul_min, rate_self->mul_max,
+ rate_self->div_min, rate_self->div_max,
+ rate, parent_rate, &div, &mul);
+ if (ret)
+ return ret;
+
+ guard(spinlock)(rate_self->lock);
+
+ mul_reg = readl(rate_self->reg + clk->mul_reg_off);
+ mul_reg |= ((mul - 1) & rate_self->mul_mask) << (rate_self->mul_shift);
+ mul_reg |= BIT(rate_self->write_enable_bit);
+ writel(mul_reg, rate_self->reg + clk->mul_reg_off);
+
+ return 0;
+}
+
+static int k230_clk_set_rate_div(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ int ret;
+ struct k230_clk_rate *clk = hw_to_k230_clk_rate(hw);
+ struct k230_clk_rate_self *rate_self = &clk->clk;
+ u32 div, mul, div_reg;
+
+ if (rate > parent_rate)
+ return -EINVAL;
+
+ if (rate_self->read_only)
+ return 0;
+
+ ret = k230_clk_find_approximate_div(rate_self->mul_min, rate_self->mul_max,
+ rate_self->div_min, rate_self->div_max,
+ rate, parent_rate, &div, &mul);
+ if (ret)
+ return ret;
+
+ guard(spinlock)(rate_self->lock);
+
+ div_reg = readl(rate_self->reg + clk->div_reg_off);
+ div_reg |= ((div - 1) & rate_self->div_mask) << (rate_self->div_shift);
+ div_reg |= BIT(rate_self->write_enable_bit);
+ writel(div_reg, rate_self->reg + clk->div_reg_off);
+
+ return 0;
+}
+
+static int k230_clk_set_rate_mul_div(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ int ret;
+ struct k230_clk_rate *clk = hw_to_k230_clk_rate(hw);
+ struct k230_clk_rate_self *rate_self = &clk->clk;
+ u32 div, mul, div_reg, mul_reg;
+
+ if (rate > parent_rate)
+ return -EINVAL;
+
+ if (rate_self->read_only)
+ return 0;
+
+ ret = k230_clk_find_approximate_mul_div(rate_self->mul_min, rate_self->mul_max,
+ rate_self->div_min, rate_self->div_max,
+ rate, parent_rate, &div, &mul);
+ if (ret)
+ return ret;
+
+ guard(spinlock)(rate_self->lock);
+
+ div_reg = readl(rate_self->reg + clk->div_reg_off);
+ div_reg |= ((div - 1) & rate_self->div_mask) << (rate_self->div_shift);
+ div_reg |= BIT(rate_self->write_enable_bit);
+ writel(div_reg, rate_self->reg + clk->div_reg_off);
+
+ mul_reg = readl(rate_self->reg + clk->mul_reg_off);
+ mul_reg |= ((mul - 1) & rate_self->mul_mask) << (rate_self->mul_shift);
+ mul_reg |= BIT(rate_self->write_enable_bit);
+ writel(mul_reg, rate_self->reg + clk->mul_reg_off);
+
+ return 0;
+}
+
+static int k230_register_clk(int id, struct clk_hw *hw, struct device *dev,
+ struct clk_hw_onecell_data *hw_data)
+{
+ int ret;
+
+ ret = devm_clk_hw_register(dev, hw);
+ if (ret)
+ return ret;
+
+ hw_data->hws[id] = hw;
+
+ return 0;
+}
+
+static int k230_register_clks(struct platform_device *pdev,
+ struct clk_hw_onecell_data *hw_data,
+ spinlock_t *lock, void __iomem *reg)
+{
+ int i, ret;
+ struct device *dev = &pdev->dev;
+ struct clk_fixed_factor *fixed_factor = &shrm_sram_div2;
+ struct k230_clk_mux *mux;
+ struct k230_clk_gate *gate;
+ struct k230_clk_rate *rate;
+
+ for (i = 0; i < K230_CLK_MUX_NUM; i++) {
+ mux = k230_clk_muxs[i];
+ mux->clk.lock = lock;
+ mux->clk.reg = reg + mux->reg_off;
+
+ ret = k230_register_clk(mux->id, &mux->clk.hw, dev, hw_data);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < K230_CLK_GATE_NUM; i++) {
+ gate = k230_clk_gates[i];
+ gate->clk.lock = lock;
+ gate->clk.reg = reg + gate->reg_off;
+
+ ret = k230_register_clk(gate->id, &gate->clk.hw, dev, hw_data);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < K230_CLK_RATE_NUM; i++) {
+ rate = k230_clk_rates[i];
+ rate->clk.lock = lock;
+ rate->clk.reg = reg;
+
+ ret = k230_register_clk(rate->id, &rate->clk.hw, dev, hw_data);
+ if (ret)
+ return ret;
+ }
+
+ ret = k230_register_clk(K230_SHRM_SRAM_DIV2, &fixed_factor->hw, dev, hw_data);
+ if (ret)
+ return ret;
+
+ return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, hw_data);
+}
+
+static int k230_clk_init_plls(struct platform_device *pdev)
+{
+ int ret;
+ void __iomem *reg;
+ /* used for all the plls */
+ spinlock_t *lock;
+
+ lock = devm_kzalloc(&pdev->dev, sizeof(*lock), GFP_KERNEL);
+ if (!lock)
+ return -ENOMEM;
+
+ spin_lock_init(lock);
+
+ reg = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(reg))
+ return PTR_ERR(reg);
+
+ ret = k230_register_plls(pdev, lock, reg);
+ if (ret)
+ return ret;
+
+ ret = k230_register_pll_divs(pdev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int k230_clk_init_clks(struct platform_device *pdev,
+ struct clk_hw_onecell_data *hw_data)
+{
+ int ret;
+ void __iomem *reg;
+ /* used for all the clocks */
+ spinlock_t *lock;
+
+ lock = devm_kzalloc(&pdev->dev, sizeof(*lock), GFP_KERNEL);
+ if (!lock)
+ return -ENOMEM;
+
+ spin_lock_init(lock);
+
+ hw_data->num = K230_CLK_NUM;
+
+ reg = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(reg))
+ return PTR_ERR(reg);
+
+ ret = k230_register_clks(pdev, hw_data, lock, reg);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int k230_clk_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct clk_hw_onecell_data *hw_data;
+
+ hw_data = devm_kzalloc(&pdev->dev, struct_size(hw_data, hws, K230_CLK_NUM),
+ GFP_KERNEL);
+ if (!hw_data)
+ return -ENOMEM;
+
+ ret = k230_clk_init_plls(pdev);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "init plls failed\n");
+
+ ret = k230_clk_init_clks(pdev, hw_data);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "init clks failed\n");
+
+ return 0;
+}
+
+static const struct of_device_id k230_clk_ids[] = {
+ { .compatible = "canaan,k230-clk" },
+ { /* Sentinel */ }
+};
+
+static struct platform_driver k230_clk_driver = {
+ .driver = {
+ .name = "k230_clock_controller",
+ .of_match_table = k230_clk_ids,
+ },
+ .probe = k230_clk_probe,
+};
+builtin_platform_driver(k230_clk_driver);
diff --git a/drivers/clk/renesas/clk-r8a73a4.c b/drivers/clk/renesas/clk-r8a73a4.c
index 7f47644396e6..1a2bbc5e9299 100644
--- a/drivers/clk/renesas/clk-r8a73a4.c
+++ b/drivers/clk/renesas/clk-r8a73a4.c
@@ -42,6 +42,8 @@ static struct div4_clk div4_clks[] = {
{ "b", CPG_FRQCRA, 8 },
{ "m1", CPG_FRQCRA, 4 },
{ "m2", CPG_FRQCRA, 0 },
+ { "ztr", CPG_FRQCRB, 20 },
+ { "zt", CPG_FRQCRB, 16 },
{ "zx", CPG_FRQCRB, 12 },
{ "zs", CPG_FRQCRB, 8 },
{ "hp", CPG_FRQCRB, 4 },
diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c
index 635d59ead499..31a79674583e 100644
--- a/drivers/clk/renesas/clk-r8a7740.c
+++ b/drivers/clk/renesas/clk-r8a7740.c
@@ -37,6 +37,8 @@ static struct div4_clk div4_clks[] = {
{ "zg", CPG_FRQCRA, 16 },
{ "b", CPG_FRQCRA, 8 },
{ "m1", CPG_FRQCRA, 4 },
+ { "ztr", CPG_FRQCRB, 20 },
+ { "zt", CPG_FRQCRB, 16 },
{ "hp", CPG_FRQCRB, 4 },
{ "hpp", CPG_FRQCRC, 20 },
{ "usbp", CPG_FRQCRC, 16 },
diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
index 015b9773cc55..54ba76ff5ab0 100644
--- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
@@ -245,6 +245,7 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
DEF_MOD("fcpvx0", 1100, R8A779G0_CLK_S0D1_VIO),
DEF_MOD("fcpvx1", 1101, R8A779G0_CLK_S0D1_VIO),
DEF_MOD("tsn", 2723, R8A779G0_CLK_S0D4_HSC),
+ DEF_MOD("dsc", 2819, R8A779G0_CLK_VIOBUSD2),
DEF_MOD("ssiu", 2926, R8A779G0_CLK_S0D6_PER),
DEF_MOD("ssi", 2927, R8A779G0_CLK_S0D6_PER),
};
diff --git a/drivers/clk/renesas/r9a07g043-cpg.c b/drivers/clk/renesas/r9a07g043-cpg.c
index 70944ef8c5b8..59d6ee2e888f 100644
--- a/drivers/clk/renesas/r9a07g043-cpg.c
+++ b/drivers/clk/renesas/r9a07g043-cpg.c
@@ -103,7 +103,7 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
/* Internal Core Clocks */
DEF_FIXED(".osc", R9A07G043_OSCCLK, CLK_EXTAL, 1, 1),
DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000),
- DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, PLL146_CONF(0)),
+ DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, CPG_SAM_PLL_CONF(0)),
DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3),
DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
DEF_FIXED(".clk_800", CLK_PLL2_800, CLK_PLL2, 1, 2),
diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c
index 2d3487203bf5..913cca6dd46f 100644
--- a/drivers/clk/renesas/r9a07g044-cpg.c
+++ b/drivers/clk/renesas/r9a07g044-cpg.c
@@ -159,7 +159,7 @@ static const struct {
/* Internal Core Clocks */
DEF_FIXED(".osc", R9A07G044_OSCCLK, CLK_EXTAL, 1, 1),
DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000),
- DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, PLL146_CONF(0)),
+ DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, CPG_SAM_PLL_CONF(0)),
DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3),
DEF_FIXED(".pll2_533", CLK_PLL2_533, CLK_PLL2, 1, 3),
DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3),
diff --git a/drivers/clk/renesas/r9a08g045-cpg.c b/drivers/clk/renesas/r9a08g045-cpg.c
index 1232fec913eb..624fc5e6fb24 100644
--- a/drivers/clk/renesas/r9a08g045-cpg.c
+++ b/drivers/clk/renesas/r9a08g045-cpg.c
@@ -9,7 +9,6 @@
#include <linux/device.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/pm_domain.h>
#include <dt-bindings/clock/r9a08g045-cpg.h>
@@ -50,16 +49,6 @@
#define G3S_SEL_SDHI1 SEL_PLL_PACK(G3S_CPG_SDHI_DSEL, 4, 2)
#define G3S_SEL_SDHI2 SEL_PLL_PACK(G3S_CPG_SDHI_DSEL, 8, 2)
-/* PLL 1/4/6 configuration registers macro. */
-#define G3S_PLL146_CONF(clk1, clk2, setting) ((clk1) << 22 | (clk2) << 12 | (setting))
-
-#define DEF_G3S_MUX(_name, _id, _conf, _parent_names, _mux_flags, _clk_flags) \
- DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = (_conf), \
- .parent_names = (_parent_names), \
- .num_parents = ARRAY_SIZE((_parent_names)), \
- .mux_flags = CLK_MUX_HIWORD_MASK | (_mux_flags), \
- .flag = (_clk_flags))
-
enum clk_ids {
/* Core Clock Outputs exported to DT */
LAST_DT_CORE_CLK = R9A08G045_SWD,
@@ -134,7 +123,7 @@ static const struct cpg_core_clk r9a08g045_core_clks[] __initconst = {
/* Internal Core Clocks */
DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000),
- DEF_G3S_PLL(".pll1", CLK_PLL1, CLK_EXTAL, G3S_PLL146_CONF(0x4, 0x8, 0x100),
+ DEF_G3S_PLL(".pll1", CLK_PLL1, CLK_EXTAL, CPG_PLL_CONF(0, 0x100),
1100000000UL),
DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3),
DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3),
diff --git a/drivers/clk/renesas/r9a08g046-cpg.c b/drivers/clk/renesas/r9a08g046-cpg.c
index 6759957980f2..a57638734ce7 100644
--- a/drivers/clk/renesas/r9a08g046-cpg.c
+++ b/drivers/clk/renesas/r9a08g046-cpg.c
@@ -17,17 +17,69 @@
/* RZ/G3L Specific registers. */
#define G3L_CPG_PL2_DDIV (0x204)
#define G3L_CPG_PL3_DDIV (0x208)
+#define G3L_CPG_CA55CORE_DDIV (0x234)
+#define G3L_CPG_RSCI_DDIV (0x238)
+#define G3L_CPG_RSPI_DDIV (0x23c)
#define G3L_CLKDIVSTATUS (0x280)
+#define G3L_CPG_ETH_SSEL (0x410)
+#define G3L_CPG_RSCI_SSEL (0x414)
+#define G3L_CPG_RSPI_SSEL (0x418)
+#define G3L_CPG_ETH_SDIV (0x434)
/* RZ/G3L Specific division configuration. */
#define G3L_DIVPL2A DDIV_PACK(G3L_CPG_PL2_DDIV, 0, 2)
#define G3L_DIVPL2B DDIV_PACK(G3L_CPG_PL2_DDIV, 4, 2)
#define G3L_DIVPL3A DDIV_PACK(G3L_CPG_PL3_DDIV, 0, 2)
+#define G3L_DIV_CA55_CORE0 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 0, 3)
+#define G3L_DIV_CA55_CORE1 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 4, 3)
+#define G3L_DIV_CA55_CORE2 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 8, 3)
+#define G3L_DIV_CA55_CORE3 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 12, 3)
+#define G3L_DIV_RSCI0 DDIV_PACK(G3L_CPG_RSCI_DDIV, 0, 2)
+#define G3L_DIV_RSCI1 DDIV_PACK(G3L_CPG_RSCI_DDIV, 2, 2)
+#define G3L_DIV_RSCI2 DDIV_PACK(G3L_CPG_RSCI_DDIV, 4, 2)
+#define G3L_DIV_RSCI3 DDIV_PACK(G3L_CPG_RSCI_DDIV, 6, 2)
+#define G3L_DIV_RSPI0 DDIV_PACK(G3L_CPG_RSPI_DDIV, 0, 2)
+#define G3L_DIV_RSPI1 DDIV_PACK(G3L_CPG_RSPI_DDIV, 2, 2)
+#define G3L_DIV_RSPI2 DDIV_PACK(G3L_CPG_RSPI_DDIV, 4, 2)
+#define G3L_SDIV_ETH_A DDIV_PACK(G3L_CPG_ETH_SDIV, 0, 2)
+#define G3L_SDIV_ETH_B DDIV_PACK(G3L_CPG_ETH_SDIV, 4, 1)
+#define G3L_SDIV_ETH_C DDIV_PACK(G3L_CPG_ETH_SDIV, 8, 2)
+#define G3L_SDIV_ETH_D DDIV_PACK(G3L_CPG_ETH_SDIV, 12, 1)
/* RZ/G3L Clock status configuration. */
#define G3L_DIVPL2A_STS DDIV_PACK(G3L_CLKDIVSTATUS, 4, 1)
#define G3L_DIVPL2B_STS DDIV_PACK(G3L_CLKDIVSTATUS, 5, 1)
#define G3L_DIVPL3A_STS DDIV_PACK(G3L_CLKDIVSTATUS, 8, 1)
+#define G3L_DIV_CA55_CORE0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 12, 1)
+#define G3L_DIV_CA55_CORE1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 13, 1)
+#define G3L_DIV_CA55_CORE2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 14, 1)
+#define G3L_DIV_CA55_CORE3_STS DDIV_PACK(G3L_CLKDIVSTATUS, 15, 1)
+#define G3L_DIV_RSCI0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 16, 1)
+#define G3L_DIV_RSCI1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 17, 1)
+#define G3L_DIV_RSCI2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 18, 1)
+#define G3L_DIV_RSCI3_STS DDIV_PACK(G3L_CLKDIVSTATUS, 19, 1)
+#define G3L_DIV_RSPI0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 20, 1)
+#define G3L_DIV_RSPI1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 21, 1)
+#define G3L_DIV_RSPI2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 22, 1)
+
+/* RZ/G3L Specific clocks select. */
+#define G3L_SEL_ETH0_TX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 0, 1)
+#define G3L_SEL_ETH0_RX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 1, 1)
+#define G3L_SEL_ETH0_RM SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 2, 1)
+#define G3L_SEL_ETH0_CLK_TX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 3, 1)
+#define G3L_SEL_ETH0_CLK_RX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 4, 1)
+#define G3L_SEL_ETH1_TX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 8, 1)
+#define G3L_SEL_ETH1_RX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 9, 1)
+#define G3L_SEL_ETH1_RM SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 10, 1)
+#define G3L_SEL_ETH1_CLK_TX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 11, 1)
+#define G3L_SEL_ETH1_CLK_RX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 12, 1)
+#define G3L_SEL_RSCI0 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 0, 2)
+#define G3L_SEL_RSCI1 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 2, 2)
+#define G3L_SEL_RSCI2 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 4, 2)
+#define G3L_SEL_RSCI3 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 6, 2)
+#define G3L_SEL_RSPI0 SEL_PLL_PACK(G3L_CPG_RSPI_SSEL, 0, 2)
+#define G3L_SEL_RSPI1 SEL_PLL_PACK(G3L_CPG_RSPI_SSEL, 2, 2)
+#define G3L_SEL_RSPI2 SEL_PLL_PACK(G3L_CPG_RSPI_SSEL, 4, 2)
enum clk_ids {
/* Core Clock Outputs exported to DT */
@@ -41,16 +93,72 @@ enum clk_ids {
CLK_ETH1_RXC_RX_CLK_IN,
/* Internal Core Clocks */
+ CLK_PLL1,
CLK_PLL2,
CLK_PLL2_DIV2,
+ CLK_PLL2_DIV2_4,
+ CLK_PLL2_DIV5,
+ CLK_PLL2_DIV6,
+ CLK_PLL2_DIV7,
CLK_PLL3,
CLK_PLL3_DIV2,
+ CLK_PLL6,
+ CLK_PLL6_DIV10,
+ CLK_SEL_ETH0_TX,
+ CLK_SEL_ETH0_RX,
+ CLK_SEL_ETH0_RM,
+ CLK_SEL_ETH1_TX,
+ CLK_SEL_ETH1_RX,
+ CLK_SEL_ETH1_RM,
+ CLK_SEL_RSCI0,
+ CLK_SEL_RSCI1,
+ CLK_SEL_RSCI2,
+ CLK_SEL_RSCI3,
+ CLK_SEL_RSPI0,
+ CLK_SEL_RSPI1,
+ CLK_SEL_RSPI2,
+ CLK_ETH0_TR,
+ CLK_ETH0_RM,
+ CLK_ETH1_TR,
+ CLK_ETH1_RM,
/* Module Clocks */
MOD_CLK_BASE,
};
/* Divider tables */
+static const struct clk_div_table dtable_1_8[] = {
+ { 0, 1 },
+ { 1, 2 },
+ { 2, 4 },
+ { 3, 8 },
+ { 0, 0 },
+};
+
+static const struct clk_div_table dtable_1_32[] = {
+ { 0, 1 },
+ { 1, 2 },
+ { 2, 4 },
+ { 3, 8 },
+ { 4, 16 },
+ { 5, 32 },
+ { 0, 0 },
+};
+
+static const struct clk_div_table dtable_2_20[] = {
+ { 0, 2 },
+ { 1, 20 },
+ { 0, 0 },
+};
+
+static const struct clk_div_table dtable_2_16[] = {
+ { 0, 2 },
+ { 1, 4 },
+ { 2, 8 },
+ { 3, 16 },
+ { 0, 0 },
+};
+
static const struct clk_div_table dtable_4_128[] = {
{ 0, 4 },
{ 1, 8 },
@@ -59,6 +167,13 @@ static const struct clk_div_table dtable_4_128[] = {
{ 0, 0 },
};
+static const struct clk_div_table dtable_4_200[] = {
+ { 0, 4 },
+ { 1, 20 },
+ { 2, 200 },
+ { 0, 0 },
+};
+
static const struct clk_div_table dtable_8_256[] = {
{ 0, 8 },
{ 1, 16 },
@@ -67,6 +182,19 @@ static const struct clk_div_table dtable_8_256[] = {
{ 0, 0 },
};
+/* Mux clock names tables. */
+static const char * const sel_eth0_tx[] = { ".div_eth0_tr", "eth0_txc_tx_clk" };
+static const char * const sel_eth0_rx[] = { ".div_eth0_tr", "eth0_rxc_rx_clk" };
+static const char * const sel_eth0_rm[] = { ".pll6_div10", "eth0_rxc_rx_clk" };
+static const char * const sel_eth1_tx[] = { ".div_eth1_tr", "eth1_txc_tx_clk" };
+static const char * const sel_eth1_rx[] = { ".div_eth1_tr", "eth1_rxc_rx_clk" };
+static const char * const sel_eth1_rm[] = { ".pll6_div10", "eth1_rxc_rx_clk" };
+static const char * const sel_rsci_rspi[] = { ".pll2_div5", ".pll2_div6", ".pll2_div7", ".pll2_div2_4" };
+static const char * const sel_eth0_clk_tx_i[] = { ".sel_eth0_tx", ".div_eth0_rm" };
+static const char * const sel_eth0_clk_rx_i[] = { ".sel_eth0_rx", ".div_eth0_rm" };
+static const char * const sel_eth1_clk_tx_i[] = { ".sel_eth1_tx", ".div_eth1_rm" };
+static const char * const sel_eth1_clk_rx_i[] = { ".sel_eth1_rx", ".div_eth1_rm" };
+
static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = {
/* External Clock Inputs */
DEF_INPUT("extal", CLK_EXTAL),
@@ -76,18 +204,82 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = {
DEF_INPUT("eth1_rxc_rx_clk", CLK_ETH1_RXC_RX_CLK_IN),
/* Internal Core Clocks */
+ DEF_G3L_PLL(".pll1", CLK_PLL1, CLK_EXTAL, CPG_PLL_CONF(0, 0x100),
+ 1200000000UL),
DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 200, 3),
DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3),
+ DEF_G3L_PLL(".pll6", CLK_PLL6, CLK_EXTAL, CPG_PLL_CONF(0x50, 0),
+ 500000000UL),
DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
+ DEF_FIXED(".pll2_div2_4", CLK_PLL2_DIV2_4, CLK_PLL2_DIV2, 1, 4),
+ DEF_FIXED(".pll2_div5", CLK_PLL2_DIV5, CLK_PLL2, 1, 5),
+ DEF_FIXED(".pll2_div6", CLK_PLL2_DIV6, CLK_PLL2, 1, 6),
+ DEF_FIXED(".pll2_div7", CLK_PLL2_DIV7, CLK_PLL2, 1, 7),
DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
+ DEF_FIXED(".pll6_div10", CLK_PLL6_DIV10, CLK_PLL6, 1, 10),
+ DEF_MUX(".sel_rsci0", CLK_SEL_RSCI0, G3L_SEL_RSCI0, sel_rsci_rspi),
+ DEF_MUX(".sel_rsci1", CLK_SEL_RSCI1, G3L_SEL_RSCI1, sel_rsci_rspi),
+ DEF_MUX(".sel_rsci2", CLK_SEL_RSCI2, G3L_SEL_RSCI2, sel_rsci_rspi),
+ DEF_MUX(".sel_rsci3", CLK_SEL_RSCI3, G3L_SEL_RSCI3, sel_rsci_rspi),
+ DEF_MUX(".sel_rspi0", CLK_SEL_RSPI0, G3L_SEL_RSPI0, sel_rsci_rspi),
+ DEF_MUX(".sel_rspi1", CLK_SEL_RSPI1, G3L_SEL_RSPI1, sel_rsci_rspi),
+ DEF_MUX(".sel_rspi2", CLK_SEL_RSPI2, G3L_SEL_RSPI2, sel_rsci_rspi),
+ DEF_MUX(".sel_eth0_tx", CLK_SEL_ETH0_TX, G3L_SEL_ETH0_TX, sel_eth0_tx),
+ DEF_MUX(".sel_eth0_rx", CLK_SEL_ETH0_RX, G3L_SEL_ETH0_RX, sel_eth0_rx),
+ DEF_MUX(".sel_eth0_rm", CLK_SEL_ETH0_RM, G3L_SEL_ETH0_RM, sel_eth0_rm),
+ DEF_MUX(".sel_eth1_tx", CLK_SEL_ETH1_TX, G3L_SEL_ETH1_TX, sel_eth1_tx),
+ DEF_MUX(".sel_eth1_rx", CLK_SEL_ETH1_RX, G3L_SEL_ETH1_RX, sel_eth1_rx),
+ DEF_MUX(".sel_eth1_rm", CLK_SEL_ETH1_RM, G3L_SEL_ETH1_RM, sel_eth1_rm),
+ DEF_DIV(".div_eth0_tr", CLK_ETH0_TR, CLK_PLL6, G3L_SDIV_ETH_A, dtable_4_200),
+ DEF_DIV(".div_eth1_tr", CLK_ETH1_TR, CLK_PLL6, G3L_SDIV_ETH_C, dtable_4_200),
+ DEF_DIV(".div_eth0_rm", CLK_ETH0_RM, CLK_SEL_ETH0_RM, G3L_SDIV_ETH_B, dtable_2_20),
+ DEF_DIV(".div_eth1_rm", CLK_ETH1_RM, CLK_SEL_ETH1_RM, G3L_SDIV_ETH_D, dtable_2_20),
/* Core output clk */
+ DEF_G3S_DIV("IC0", R9A08G046_CLK_IC0, CLK_PLL1, G3L_DIV_CA55_CORE0, G3L_DIV_CA55_CORE0_STS,
+ dtable_1_32, 0, 0, 0, NULL),
+ DEF_G3S_DIV("IC1", R9A08G046_CLK_IC1, CLK_PLL1, G3L_DIV_CA55_CORE1, G3L_DIV_CA55_CORE1_STS,
+ dtable_1_32, 0, 0, 0, NULL),
+ DEF_G3S_DIV("IC2", R9A08G046_CLK_IC2, CLK_PLL1, G3L_DIV_CA55_CORE2, G3L_DIV_CA55_CORE2_STS,
+ dtable_1_32, 0, 0, 0, NULL),
+ DEF_G3S_DIV("IC3", R9A08G046_CLK_IC3, CLK_PLL1, G3L_DIV_CA55_CORE3, G3L_DIV_CA55_CORE3_STS,
+ dtable_1_32, 0, 0, 0, NULL),
DEF_G3S_DIV("P0", R9A08G046_CLK_P0, CLK_PLL2_DIV2, G3L_DIVPL2B, G3L_DIVPL2B_STS,
dtable_8_256, 0, 0, 0, NULL),
DEF_G3S_DIV("P1", R9A08G046_CLK_P1, CLK_PLL3_DIV2, G3L_DIVPL3A, G3L_DIVPL3A_STS,
dtable_4_128, 0, 0, 0, NULL),
DEF_G3S_DIV("P3", R9A08G046_CLK_P3, CLK_PLL2_DIV2, G3L_DIVPL2A, G3L_DIVPL2A_STS,
dtable_4_128, 0, 0, 0, NULL),
+ DEF_G3S_DIV("P13", R9A08G046_CLK_P13, CLK_SEL_RSCI0, G3L_DIV_RSCI0, G3L_DIV_RSCI0_STS,
+ dtable_2_16, 0, 100000000UL, 0, NULL),
+ DEF_G3S_DIV("P14", R9A08G046_CLK_P14, CLK_SEL_RSCI1, G3L_DIV_RSCI1, G3L_DIV_RSCI1_STS,
+ dtable_2_16, 0, 100000000UL, 0, NULL),
+ DEF_G3S_DIV("P15", R9A08G046_CLK_P15, CLK_SEL_RSCI2, G3L_DIV_RSCI2, G3L_DIV_RSCI2_STS,
+ dtable_2_16, 0, 100000000UL, 0, NULL),
+ DEF_G3S_DIV("P16", R9A08G046_CLK_P16, CLK_SEL_RSCI3, G3L_DIV_RSCI3, G3L_DIV_RSCI3_STS,
+ dtable_2_16, 0, 100000000UL, 0, NULL),
+ DEF_G3S_DIV("P17", R9A08G046_CLK_P17, CLK_SEL_RSPI0, G3L_DIV_RSPI0, G3L_DIV_RSPI0_STS,
+ dtable_1_8, 0, 200000000UL, 0, NULL),
+ DEF_G3S_DIV("P18", R9A08G046_CLK_P18, CLK_SEL_RSPI1, G3L_DIV_RSPI1, G3L_DIV_RSPI1_STS,
+ dtable_1_8, 0, 200000000UL, 0, NULL),
+ DEF_G3S_DIV("P19", R9A08G046_CLK_P19, CLK_SEL_RSPI2, G3L_DIV_RSPI2, G3L_DIV_RSPI2_STS,
+ dtable_1_8, 0, 200000000UL, 0, NULL),
+ DEF_FIXED("HP", R9A08G046_CLK_HP, CLK_PLL6_DIV10, 1, 1),
+ DEF_MUX_FLAGS("ETHTX01", R9A08G046_CLK_ETHTX01, G3L_SEL_ETH0_CLK_TX_I, sel_eth0_clk_tx_i,
+ CLK_SET_RATE_PARENT),
+ DEF_MUX_FLAGS("ETHRX01", R9A08G046_CLK_ETHRX01, G3L_SEL_ETH0_CLK_RX_I, sel_eth0_clk_rx_i,
+ CLK_SET_RATE_PARENT),
+ DEF_MUX_FLAGS("ETHTX11", R9A08G046_CLK_ETHTX11, G3L_SEL_ETH1_CLK_TX_I, sel_eth1_clk_tx_i,
+ CLK_SET_RATE_PARENT),
+ DEF_MUX_FLAGS("ETHRX11", R9A08G046_CLK_ETHRX11, G3L_SEL_ETH1_CLK_RX_I, sel_eth1_clk_rx_i,
+ CLK_SET_RATE_PARENT),
+ DEF_FIXED("ETHRM0", R9A08G046_CLK_ETHRM0, CLK_SEL_ETH0_RM, 1, 1),
+ DEF_FIXED("ETHTX02", R9A08G046_CLK_ETHTX02, CLK_SEL_ETH0_TX, 1, 1),
+ DEF_FIXED("ETHRX02", R9A08G046_CLK_ETHRX02, CLK_SEL_ETH0_RX, 1, 1),
+ DEF_FIXED("ETHRM1", R9A08G046_CLK_ETHRM1, CLK_SEL_ETH1_RM, 1, 1),
+ DEF_FIXED("ETHTX12", R9A08G046_CLK_ETHTX12, CLK_SEL_ETH1_TX, 1, 1),
+ DEF_FIXED("ETHRX12", R9A08G046_CLK_ETHRX12, CLK_SEL_ETH1_RX, 1, 1),
+ DEF_FIXED("OSCCLK", R9A08G046_OSCCLK, CLK_EXTAL, 1, 1),
};
static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = {
@@ -101,8 +293,116 @@ static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = {
MSTOP(BUS_REG1, BIT(2))),
DEF_MOD("dmac_pclk", R9A08G046_DMAC_PCLK, R9A08G046_CLK_P3, 0x52c, 1,
MSTOP(BUS_REG1, BIT(3))),
+ DEF_MOD("wdt0_pclk", R9A08G046_WDT0_PCLK, R9A08G046_CLK_P0, 0x548, 0,
+ MSTOP(BUS_REG0, BIT(0))),
+ DEF_MOD("wdt0_clk", R9A08G046_WDT0_CLK, R9A08G046_OSCCLK, 0x548, 1,
+ MSTOP(BUS_REG0, BIT(0))),
+ DEF_MOD("ssi0_pclk2", R9A08G046_SSI0_PCLK2, R9A08G046_CLK_P0, 0x570, 0,
+ MSTOP(BUS_MCPU1, BIT(10))),
+ DEF_MOD("ssi0_pclk_sfr", R9A08G046_SSI0_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 1,
+ MSTOP(BUS_MCPU1, BIT(10))),
+ DEF_MOD("ssi1_pclk2", R9A08G046_SSI1_PCLK2, R9A08G046_CLK_P0, 0x570, 2,
+ MSTOP(BUS_MCPU1, BIT(11))),
+ DEF_MOD("ssi1_pclk_sfr", R9A08G046_SSI1_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 3,
+ MSTOP(BUS_MCPU1, BIT(11))),
+ DEF_MOD("ssi2_pclk2", R9A08G046_SSI2_PCLK2, R9A08G046_CLK_P0, 0x570, 4,
+ MSTOP(BUS_MCPU1, BIT(12))),
+ DEF_MOD("ssi2_pclk_sfr", R9A08G046_SSI2_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 5,
+ MSTOP(BUS_MCPU1, BIT(12))),
+ DEF_MOD("ssi3_pclk2", R9A08G046_SSI3_PCLK2, R9A08G046_CLK_P0, 0x570, 6,
+ MSTOP(BUS_MCPU1, BIT(13))),
+ DEF_MOD("ssi3_pclk_sfr", R9A08G046_SSI3_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 7,
+ MSTOP(BUS_MCPU1, BIT(13))),
+ DEF_MOD("eth0_clk_axi", R9A08G046_ETH0_CLK_AXI, R9A08G046_CLK_P1, 0x57c, 0,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_MOD("eth1_clk_axi", R9A08G046_ETH1_CLK_AXI, R9A08G046_CLK_P1, 0x57c, 1,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_MOD("eth0_clk_chi", R9A08G046_ETH0_CLK_CHI, R9A08G046_CLK_P1, 0x57c, 2,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_MOD("eth1_clk_chi", R9A08G046_ETH1_CLK_CHI, R9A08G046_CLK_P1, 0x57c, 3,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_COUPLED("eth0_tx_i", R9A08G046_ETH0_CLK_TX_I, R9A08G046_CLK_ETHTX01, 0x57c, 4,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_COUPLED("eth0_tx_180_i", R9A08G046_ETH0_CLK_TX_180_I, R9A08G046_CLK_ETHTX02, 0x57c, 4,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_COUPLED("eth1_tx_i", R9A08G046_ETH1_CLK_TX_I, R9A08G046_CLK_ETHTX11, 0x57c, 5,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_COUPLED("eth1_tx_180_i", R9A08G046_ETH1_CLK_TX_180_I, R9A08G046_CLK_ETHTX12, 0x57c, 5,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_COUPLED("eth0_rx_i", R9A08G046_ETH0_CLK_RX_I, R9A08G046_CLK_ETHRX01, 0x57c, 6,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_COUPLED("eth0_rx_180_i", R9A08G046_ETH0_CLK_RX_180_I, R9A08G046_CLK_ETHRX02, 0x57c, 6,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_COUPLED("eth1_rx_i", R9A08G046_ETH1_CLK_RX_I, R9A08G046_CLK_ETHRX11, 0x57c, 7,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_COUPLED("eth1_rx_180_i", R9A08G046_ETH1_CLK_RX_180_I, R9A08G046_CLK_ETHRX12, 0x57c, 7,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_MOD("eth0_ptp_ref_i", R9A08G046_ETH0_CLK_PTP_REF_I, R9A08G046_CLK_HP, 0x57c, 8,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_MOD("eth1_ptp_ref_i", R9A08G046_ETH1_CLK_PTP_REF_I, R9A08G046_CLK_HP, 0x57c, 9,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_MOD("eth0_rmii_i", R9A08G046_ETH0_CLK_RMII_I, R9A08G046_CLK_ETHRM0, 0x57c, 10,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_MOD("eth1_rmii_i", R9A08G046_ETH1_CLK_RMII_I, R9A08G046_CLK_ETHRM1, 0x57c, 11,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_COUPLED("eth0_tx_i_rmii", R9A08G046_ETH0_CLK_TX_I_RMII, R9A08G046_CLK_ETHTX01, 0x57c, 12,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_COUPLED("eth0_rx_i_rmii", R9A08G046_ETH0_CLK_RX_I_RMII, R9A08G046_CLK_ETHRX01, 0x57c, 12,
+ MSTOP(BUS_PERI_COM, BIT(2))),
+ DEF_COUPLED("eth1_tx_i_rmii", R9A08G046_ETH1_CLK_TX_I_RMII, R9A08G046_CLK_ETHTX11, 0x57c, 13,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_COUPLED("eth1_rx_i_rmii", R9A08G046_ETH1_CLK_RX_I_RMII, R9A08G046_CLK_ETHRX11, 0x57c, 13,
+ MSTOP(BUS_PERI_COM, BIT(3))),
+ DEF_MOD("i2c0_pclk", R9A08G046_I2C0_PCLK, R9A08G046_CLK_P0, 0x580, 0,
+ MSTOP(BUS_MCPU2, BIT(10))),
+ DEF_MOD("i2c1_pclk", R9A08G046_I2C1_PCLK, R9A08G046_CLK_P0, 0x580, 1,
+ MSTOP(BUS_MCPU2, BIT(11))),
+ DEF_MOD("i2c2_pclk", R9A08G046_I2C2_PCLK, R9A08G046_CLK_P0, 0x580, 2,
+ MSTOP(BUS_MCPU2, BIT(12))),
+ DEF_MOD("i2c3_pclk", R9A08G046_I2C3_PCLK, R9A08G046_CLK_P0, 0x580, 3,
+ MSTOP(BUS_MCPU2, BIT(13))),
DEF_MOD("scif0_clk_pck", R9A08G046_SCIF0_CLK_PCK, R9A08G046_CLK_P0, 0x584, 0,
MSTOP(BUS_MCPU2, BIT(1))),
+ DEF_MOD("scif1_clk_pck", R9A08G046_SCIF1_CLK_PCK, R9A08G046_CLK_P0, 0x584, 1,
+ MSTOP(BUS_MCPU2, BIT(2))),
+ DEF_MOD("scif2_clk_pck", R9A08G046_SCIF2_CLK_PCK, R9A08G046_CLK_P0, 0x584, 2,
+ MSTOP(BUS_MCPU2, BIT(3))),
+ DEF_MOD("scif3_clk_pck", R9A08G046_SCIF3_CLK_PCK, R9A08G046_CLK_P0, 0x584, 3,
+ MSTOP(BUS_MCPU2, BIT(4))),
+ DEF_MOD("scif4_clk_pck", R9A08G046_SCIF4_CLK_PCK, R9A08G046_CLK_P0, 0x584, 4,
+ MSTOP(BUS_MCPU2, BIT(5))),
+ DEF_MOD("scif5_clk_pck", R9A08G046_SCIF5_CLK_PCK, R9A08G046_CLK_P0, 0x584, 5,
+ MSTOP(BUS_MCPU3, BIT(4))),
+ DEF_MOD("rspi0_pclk", R9A08G046_RSPI0_PCLK, R9A08G046_CLK_P3, 0x590, 0,
+ MSTOP(BUS_MCPU1, BIT(14))),
+ DEF_MOD("rspi1_pclk", R9A08G046_RSPI1_PCLK, R9A08G046_CLK_P3, 0x590, 1,
+ MSTOP(BUS_MCPU1, BIT(15))),
+ DEF_MOD("rspi2_pclk", R9A08G046_RSPI2_PCLK, R9A08G046_CLK_P3, 0x590, 2,
+ MSTOP(BUS_MCPU2, BIT(0))),
+ DEF_MOD("rspi0_tclk", R9A08G046_RSPI0_TCLK, R9A08G046_CLK_P17, 0x590, 8,
+ MSTOP(BUS_MCPU1, BIT(14))),
+ DEF_MOD("rspi1_tclk", R9A08G046_RSPI1_TCLK, R9A08G046_CLK_P18, 0x590, 9,
+ MSTOP(BUS_MCPU1, BIT(15))),
+ DEF_MOD("rspi2_tclk", R9A08G046_RSPI2_TCLK, R9A08G046_CLK_P19, 0x590, 10,
+ MSTOP(BUS_MCPU2, BIT(0))),
+ DEF_MOD("gpio_hclk", R9A08G046_GPIO_HCLK, R9A08G046_OSCCLK, 0x598, 0,
+ MSTOP(BUS_PERI_CPU, BIT(6))),
+ DEF_MOD("rsci0_pclk", R9A08G046_RSCI0_PCLK, R9A08G046_CLK_P0, 0x618, 0,
+ MSTOP(BUS_MCPU2, BIT(7))),
+ DEF_MOD("rsci1_pclk", R9A08G046_RSCI1_PCLK, R9A08G046_CLK_P0, 0x618, 1,
+ MSTOP(BUS_MCPU2, BIT(8))),
+ DEF_MOD("rsci2_pclk", R9A08G046_RSCI2_PCLK, R9A08G046_CLK_P0, 0x618, 2,
+ MSTOP(BUS_MCPU3, BIT(11))),
+ DEF_MOD("rsci3_pclk", R9A08G046_RSCI3_PCLK, R9A08G046_CLK_P0, 0x618, 3,
+ MSTOP(BUS_MCPU3, BIT(12))),
+ DEF_MOD("rsci0_tclk", R9A08G046_RSCI0_TCLK, R9A08G046_CLK_P13, 0x618, 8,
+ MSTOP(BUS_MCPU2, BIT(7))),
+ DEF_MOD("rsci1_tclk", R9A08G046_RSCI1_TCLK, R9A08G046_CLK_P14, 0x618, 9,
+ MSTOP(BUS_MCPU2, BIT(8))),
+ DEF_MOD("rsci2_tclk", R9A08G046_RSCI2_TCLK, R9A08G046_CLK_P15, 0x618, 10,
+ MSTOP(BUS_MCPU3, BIT(11))),
+ DEF_MOD("rsci3_tclk", R9A08G046_RSCI3_TCLK, R9A08G046_CLK_P16, 0x618, 11,
+ MSTOP(BUS_MCPU3, BIT(12))),
};
static const struct rzg2l_reset r9a08g046_resets[] = {
@@ -111,11 +411,45 @@ static const struct rzg2l_reset r9a08g046_resets[] = {
DEF_RST(R9A08G046_IA55_RESETN, 0x818, 0),
DEF_RST(R9A08G046_DMAC_ARESETN, 0x82c, 0),
DEF_RST(R9A08G046_DMAC_RST_ASYNC, 0x82c, 1),
+ DEF_RST(R9A08G046_WDT0_PRESETN, 0x848, 0),
+ DEF_RST(R9A08G046_SSI0_RST_M2_REG, 0x870, 0),
+ DEF_RST(R9A08G046_SSI1_RST_M2_REG, 0x870, 1),
+ DEF_RST(R9A08G046_SSI2_RST_M2_REG, 0x870, 2),
+ DEF_RST(R9A08G046_SSI3_RST_M2_REG, 0x870, 3),
+ DEF_RST(R9A08G046_ETH0_ARESET_N, 0x87c, 0),
+ DEF_RST(R9A08G046_ETH1_ARESET_N, 0x87c, 1),
+ DEF_RST(R9A08G046_I2C0_MRST, 0x880, 0),
+ DEF_RST(R9A08G046_I2C1_MRST, 0x880, 1),
+ DEF_RST(R9A08G046_I2C2_MRST, 0x880, 2),
+ DEF_RST(R9A08G046_I2C3_MRST, 0x880, 3),
DEF_RST(R9A08G046_SCIF0_RST_SYSTEM_N, 0x884, 0),
+ DEF_RST(R9A08G046_SCIF1_RST_SYSTEM_N, 0x884, 1),
+ DEF_RST(R9A08G046_SCIF2_RST_SYSTEM_N, 0x884, 2),
+ DEF_RST(R9A08G046_SCIF3_RST_SYSTEM_N, 0x884, 3),
+ DEF_RST(R9A08G046_SCIF4_RST_SYSTEM_N, 0x884, 4),
+ DEF_RST(R9A08G046_SCIF5_RST_SYSTEM_N, 0x884, 5),
+ DEF_RST(R9A08G046_RSPI0_PRESETN, 0x890, 0),
+ DEF_RST(R9A08G046_RSPI1_PRESETN, 0x890, 1),
+ DEF_RST(R9A08G046_RSPI2_PRESETN, 0x890, 2),
+ DEF_RST(R9A08G046_RSPI0_TRESETN, 0x890, 8),
+ DEF_RST(R9A08G046_RSPI1_TRESETN, 0x890, 9),
+ DEF_RST(R9A08G046_RSPI2_TRESETN, 0x890, 10),
+ DEF_RST(R9A08G046_GPIO_RSTN, 0x898, 0),
+ DEF_RST(R9A08G046_GPIO_PORT_RESETN, 0x898, 1),
+ DEF_RST(R9A08G046_GPIO_SPARE_RESETN, 0x898, 2),
+ DEF_RST(R9A08G046_RSCI0_PRESETN, 0x918, 0),
+ DEF_RST(R9A08G046_RSCI1_PRESETN, 0x918, 1),
+ DEF_RST(R9A08G046_RSCI2_PRESETN, 0x918, 2),
+ DEF_RST(R9A08G046_RSCI3_PRESETN, 0x918, 3),
+ DEF_RST(R9A08G046_RSCI0_TRESETN, 0x918, 8),
+ DEF_RST(R9A08G046_RSCI1_TRESETN, 0x918, 9),
+ DEF_RST(R9A08G046_RSCI2_TRESETN, 0x918, 10),
+ DEF_RST(R9A08G046_RSCI3_TRESETN, 0x918, 11),
};
static const unsigned int r9a08g046_crit_mod_clks[] __initconst = {
MOD_CLK_BASE + R9A08G046_GIC600_GICCLK,
+ MOD_CLK_BASE + R9A08G046_IA55_PCLK,
MOD_CLK_BASE + R9A08G046_IA55_CLK,
MOD_CLK_BASE + R9A08G046_DMAC_ACLK,
};
@@ -125,6 +459,23 @@ static const unsigned int r9a08g046_crit_resets[] = {
R9A08G046_DMAC_RST_ASYNC,
};
+static const unsigned int r9a08g046_no_pm_mod_clks[] = {
+ MOD_CLK_BASE + R9A08G046_ETH0_CLK_TX_I,
+ MOD_CLK_BASE + R9A08G046_ETH0_CLK_TX_180_I,
+ MOD_CLK_BASE + R9A08G046_ETH0_CLK_RX_I,
+ MOD_CLK_BASE + R9A08G046_ETH0_CLK_RX_180_I,
+ MOD_CLK_BASE + R9A08G046_ETH0_CLK_RMII_I,
+ MOD_CLK_BASE + R9A08G046_ETH0_CLK_TX_I_RMII,
+ MOD_CLK_BASE + R9A08G046_ETH0_CLK_RX_I_RMII,
+ MOD_CLK_BASE + R9A08G046_ETH1_CLK_TX_I,
+ MOD_CLK_BASE + R9A08G046_ETH1_CLK_TX_180_I,
+ MOD_CLK_BASE + R9A08G046_ETH1_CLK_RX_I,
+ MOD_CLK_BASE + R9A08G046_ETH1_CLK_RX_180_I,
+ MOD_CLK_BASE + R9A08G046_ETH1_CLK_RMII_I,
+ MOD_CLK_BASE + R9A08G046_ETH1_CLK_TX_I_RMII,
+ MOD_CLK_BASE + R9A08G046_ETH1_CLK_RX_I_RMII,
+};
+
const struct rzg2l_cpg_info r9a08g046_cpg_info = {
/* Core Clocks */
.core_clks = r9a08g046_core_clks,
@@ -141,6 +492,10 @@ const struct rzg2l_cpg_info r9a08g046_cpg_info = {
.num_mod_clks = ARRAY_SIZE(r9a08g046_mod_clks),
.num_hw_mod_clks = R9A08G046_BSC_X_BCK_BSC + 1,
+ /* No PM modules Clocks */
+ .no_pm_mod_clks = r9a08g046_no_pm_mod_clks,
+ .num_no_pm_mod_clks = ARRAY_SIZE(r9a08g046_no_pm_mod_clks),
+
/* Resets */
.resets = r9a08g046_resets,
.num_resets = R9A08G046_BSC_X_PRESET_BSC + 1, /* Last reset ID + 1 */
diff --git a/drivers/clk/renesas/r9a09g011-cpg.c b/drivers/clk/renesas/r9a09g011-cpg.c
index ba25429c244d..a99ab1375f07 100644
--- a/drivers/clk/renesas/r9a09g011-cpg.c
+++ b/drivers/clk/renesas/r9a09g011-cpg.c
@@ -16,11 +16,6 @@
#include "rzg2l-cpg.h"
-#define RZV2M_SAMPLL4_CLK1 0x104
-#define RZV2M_SAMPLL4_CLK2 0x108
-
-#define PLL4_CONF (RZV2M_SAMPLL4_CLK1 << 22 | RZV2M_SAMPLL4_CLK2 << 12)
-
#define DIV_A DDIV_PACK(0x200, 0, 3)
#define DIV_B DDIV_PACK(0x204, 0, 2)
#define DIV_D DDIV_PACK(0x204, 4, 2)
@@ -131,7 +126,7 @@ static const struct cpg_core_clk r9a09g011_core_clks[] __initconst = {
DEF_FIXED(".pll2_400", CLK_PLL2_400, CLK_PLL2_800, 1, 2),
DEF_FIXED(".pll2_200", CLK_PLL2_200, CLK_PLL2_800, 1, 4),
DEF_FIXED(".pll2_100", CLK_PLL2_100, CLK_PLL2_800, 1, 8),
- DEF_SAMPLL(".pll4", CLK_PLL4, CLK_MAIN_2, PLL4_CONF),
+ DEF_SAMPLL(".pll4", CLK_PLL4, CLK_MAIN_2, CPG_SAM_PLL_CONF(0x100)),
DEF_DIV_RO(".diva", CLK_DIV_A, CLK_PLL1, DIV_A, dtable_diva),
DEF_DIV_RO(".divb", CLK_DIV_B, CLK_PLL2_400, DIV_B, dtable_divb),
diff --git a/drivers/clk/renesas/r9a09g047-cpg.c b/drivers/clk/renesas/r9a09g047-cpg.c
index e59ac4a05a7f..94158b6834e6 100644
--- a/drivers/clk/renesas/r9a09g047-cpg.c
+++ b/drivers/clk/renesas/r9a09g047-cpg.c
@@ -6,6 +6,7 @@
*/
#include <linux/clk-provider.h>
+#include <linux/clk/renesas.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -30,6 +31,8 @@ enum clk_ids {
CLK_PLLCA55,
CLK_PLLVDO,
CLK_PLLETH,
+ CLK_PLLDSI0,
+ CLK_PLLDSI1,
/* Internal Core Clocks */
CLK_PLLCM33_DIV3,
@@ -57,6 +60,8 @@ enum clk_ids {
CLK_PLLETH_DIV_125_FIX,
CLK_CSDIV_PLLETH_GBE0,
CLK_CSDIV_PLLETH_GBE1,
+ CLK_SMUX2_DSI0_CLK,
+ CLK_SMUX2_DSI1_CLK,
CLK_SMUX2_GBE0_TXCLK,
CLK_SMUX2_GBE0_RXCLK,
CLK_SMUX2_GBE1_TXCLK,
@@ -64,6 +69,12 @@ enum clk_ids {
CLK_PLLDTY_DIV16,
CLK_PLLVDO_CRU0,
CLK_PLLVDO_GPU,
+ CLK_PLLETH_DIV4_LPCLK,
+ CLK_PLLETH_LPCLK,
+ CLK_PLLDSI0_DIV7,
+ CLK_PLLDSI1_DIV7,
+ CLK_PLLDSI0_CSDIV,
+ CLK_PLLDSI1_CSDIV,
/* Module Clocks */
MOD_CLK_BASE,
@@ -91,6 +102,18 @@ static const struct clk_div_table dtable_2_16[] = {
{0, 0},
};
+static const struct clk_div_table dtable_2_16_plldsi[] = {
+ {0, 2},
+ {1, 4},
+ {2, 6},
+ {3, 8},
+ {4, 10},
+ {5, 12},
+ {6, 14},
+ {7, 16},
+ {0, 0},
+};
+
static const struct clk_div_table dtable_2_64[] = {
{0, 2},
{1, 4},
@@ -107,7 +130,23 @@ static const struct clk_div_table dtable_2_100[] = {
{0, 0},
};
+static const struct clk_div_table dtable_16_128[] = {
+ {0, 16},
+ {1, 32},
+ {2, 64},
+ {3, 128},
+ {0, 0},
+};
+
+RZG3E_CPG_PLL_DSI0_LIMITS(rzg3e_cpg_pll_dsi0_limits);
+RZG3E_CPG_PLL_DSI1_LIMITS(rzg3e_cpg_pll_dsi1_limits);
+
+#define PLLDSI0 PLL_PACK_LIMITS(0xc0, 1, 0, &rzg3e_cpg_pll_dsi0_limits)
+#define PLLDSI1 PLL_PACK_LIMITS(0x160, 1, 1, &rzg3e_cpg_pll_dsi1_limits)
+
/* Mux clock tables */
+static const char * const smux2_dsi0_clk[] = { ".plldsi0_div7", ".plldsi0_csdiv" };
+static const char * const smux2_dsi1_clk[] = { ".plldsi1_div7", ".plldsi1_csdiv" };
static const char * const smux2_gbe0_rxclk[] = { ".plleth_gbe0", "et0_rxclk" };
static const char * const smux2_gbe0_txclk[] = { ".plleth_gbe0", "et0_txclk" };
static const char * const smux2_gbe1_rxclk[] = { ".plleth_gbe1", "et1_rxclk" };
@@ -128,6 +167,8 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = {
DEF_PLL(".pllca55", CLK_PLLCA55, CLK_QEXTAL, PLLCA55),
DEF_FIXED(".plleth", CLK_PLLETH, CLK_QEXTAL, 125, 3),
DEF_FIXED(".pllvdo", CLK_PLLVDO, CLK_QEXTAL, 105, 2),
+ DEF_PLLDSI(".plldsi0", CLK_PLLDSI0, CLK_QEXTAL, PLLDSI0),
+ DEF_PLLDSI(".plldsi1", CLK_PLLDSI1, CLK_QEXTAL, PLLDSI1),
/* Internal Core Clocks */
DEF_FIXED(".pllcm33_div3", CLK_PLLCM33_DIV3, CLK_PLLCM33, 1, 3),
@@ -171,6 +212,21 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = {
DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4),
DEF_DDIV(".pllvdo_gpu", CLK_PLLVDO_GPU, CLK_PLLVDO, CDDIV3_DIVCTL1, dtable_2_64),
+ DEF_FIXED(".plleth_div4_lpclk", CLK_PLLETH_DIV4_LPCLK, CLK_PLLETH, 1, 4),
+ DEF_CSDIV(".plleth_lpclk", CLK_PLLETH_LPCLK, CLK_PLLETH_DIV4_LPCLK,
+ CSDIV0_DIVCTL2, dtable_16_128),
+
+ DEF_PLLDSI_DIV(".plldsi0_csdiv", CLK_PLLDSI0_CSDIV, CLK_PLLDSI0,
+ CSDIV1_DIVCTL2, dtable_2_16_plldsi),
+ DEF_PLLDSI_DIV(".plldsi1_csdiv", CLK_PLLDSI1_CSDIV, CLK_PLLDSI1,
+ CSDIV1_DIVCTL3, dtable_2_16_plldsi),
+ DEF_FIXED(".plldsi0_div7", CLK_PLLDSI0_DIV7, CLK_PLLDSI0, 1, 7),
+ DEF_FIXED(".plldsi1_div7", CLK_PLLDSI1_DIV7, CLK_PLLDSI1, 1, 7),
+ DEF_PLLDSI_SMUX(".smux2_dsi0_clk", CLK_SMUX2_DSI0_CLK,
+ SSEL3_SELCTL0, smux2_dsi0_clk),
+ DEF_PLLDSI_SMUX(".smux2_dsi1_clk", CLK_SMUX2_DSI1_CLK,
+ SSEL3_SELCTL1, smux2_dsi1_clk),
+
/* Core Clocks */
DEF_FIXED("sys_0_pclk", R9A09G047_SYS_0_PCLK, CLK_QEXTAL, 1, 1),
DEF_DDIV("ca55_0_coreclk0", R9A09G047_CA55_0_CORECLK0, CLK_PLLCA55,
@@ -452,6 +508,22 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = {
BUS_MSTOP(9, BIT(4))),
DEF_MOD("cru_0_pclk", CLK_PLLDTY_DIV16, 13, 4, 6, 20,
BUS_MSTOP(9, BIT(4))),
+ DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8,
+ BUS_MSTOP(9, BIT(15) | BIT(14))),
+ DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9,
+ BUS_MSTOP(9, BIT(15) | BIT(14))),
+ DEF_MOD("dsi_0_vclk1", CLK_SMUX2_DSI0_CLK, 14, 10, 7, 10,
+ BUS_MSTOP(9, BIT(15) | BIT(14))),
+ DEF_MOD("dsi_0_lpclk", CLK_PLLETH_LPCLK, 14, 11, 7, 11,
+ BUS_MSTOP(9, BIT(15) | BIT(14))),
+ DEF_MOD("dsi_0_pllref_clk", CLK_QEXTAL, 14, 12, 7, 12,
+ BUS_MSTOP(9, BIT(15) | BIT(14))),
+ DEF_MOD("lcdc_0_clk_a", CLK_PLLDTY_ACPU_DIV2, 14, 13, 7, 13,
+ BUS_MSTOP(10, BIT(3) | BIT(2) | BIT(1))),
+ DEF_MOD("lcdc_0_clk_p", CLK_PLLDTY_DIV16, 14, 14, 7, 14,
+ BUS_MSTOP(10, BIT(3) | BIT(2) | BIT(1))),
+ DEF_MOD("lcdc_0_clk_d", CLK_SMUX2_DSI0_CLK, 14, 15, 7, 15,
+ BUS_MSTOP(10, BIT(3) | BIT(2) | BIT(1))),
DEF_MOD("ge3d_clk", CLK_PLLVDO_GPU, 15, 0, 7, 16,
BUS_MSTOP(3, BIT(4))),
DEF_MOD("ge3d_axi_clk", CLK_PLLDTY_ACPU_DIV2, 15, 1, 7, 17,
@@ -460,6 +532,14 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = {
BUS_MSTOP(3, BIT(4))),
DEF_MOD("tsu_1_pclk", CLK_QEXTAL, 16, 10, 8, 10,
BUS_MSTOP(2, BIT(15))),
+ DEF_MOD("dsi_0_vclk2", CLK_SMUX2_DSI1_CLK, 25, 0, 10, 21,
+ BUS_MSTOP(9, BIT(15) | BIT(14))),
+ DEF_MOD("lcdc_1_clk_a", CLK_PLLDTY_ACPU_DIV2, 26, 8, 10, 30,
+ BUS_MSTOP(13, BIT(5) | BIT(4) | BIT(3))),
+ DEF_MOD("lcdc_1_clk_p", CLK_PLLDTY_DIV16, 26, 9, 10, 31,
+ BUS_MSTOP(13, BIT(5) | BIT(4) | BIT(3))),
+ DEF_MOD("lcdc_1_clk_d", CLK_SMUX2_DSI1_CLK, 26, 10, 11, 0,
+ BUS_MSTOP(13, BIT(5) | BIT(4) | BIT(3))),
};
static const struct rzv2h_reset r9a09g047_resets[] __initconst = {
@@ -535,10 +615,14 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = {
DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */
DEF_RST(12, 6, 5, 23), /* CRU_0_ARESETN */
DEF_RST(12, 7, 5, 24), /* CRU_0_S_RESETN */
+ DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */
+ DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */
+ DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */
DEF_RST(13, 13, 6, 14), /* GE3D_RESETN */
DEF_RST(13, 14, 6, 15), /* GE3D_AXI_RESETN */
DEF_RST(13, 15, 6, 16), /* GE3D_ACE_RESETN */
DEF_RST(15, 8, 7, 9), /* TSU_1_PRESETN */
+ DEF_RST(17, 14, 8, 15), /* LCDC_1_RESET_N */
};
const struct rzv2h_cpg_info r9a09g047_cpg_info __initconst = {
diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c
index 93b15e06a19b..f777601a23b9 100644
--- a/drivers/clk/renesas/r9a09g077-cpg.c
+++ b/drivers/clk/renesas/r9a09g077-cpg.c
@@ -257,6 +257,7 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
DEF_MOD("spi0", 104, CLK_SPI0ASYNC),
DEF_MOD("spi1", 105, CLK_SPI1ASYNC),
DEF_MOD("spi2", 106, CLK_SPI2ASYNC),
+ DEF_MOD("mtu3", 200, R9A09G077_CLK_PCLKH),
DEF_MOD("adc0", 206, R9A09G077_CLK_PCLKH),
DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH),
DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM),
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 26ea85cfaa02..5b84cbee030b 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -370,6 +370,9 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
struct clk *clk;
int range_check;
+ if (clkspec->args_count != 2)
+ return ERR_PTR(-EINVAL);
+
switch (clkspec->args[0]) {
case CPG_CORE:
type = "core";
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index abfd8634d2be..51c9e19e1575 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -58,15 +58,22 @@
#define RZG3S_DIV_NF GENMASK(12, 1)
#define RZG3S_SEL_PLL BIT(0)
+#define CPG_PLL1_SETTING_OFFSET(conf) FIELD_GET(GENMASK(11, 0), (conf))
+#define CPG_PLL_STBY_OFFSET(conf) FIELD_GET(GENMASK(23, 12), (conf))
+#define CPG_PLL_STBY_RESETB_WEN BIT(16)
+#define CPG_PLL_STBY_RESETB BIT(0)
+#define CPG_PLL_CLK1_OFFSET(x) (CPG_PLL_STBY_OFFSET(x) + 0x4)
+#define CPG_PLL_CLK2_OFFSET(x) (CPG_PLL_STBY_OFFSET(x) + 0x8)
+#define CPG_PLL_MON_OFFSET(x) (CPG_PLL_STBY_OFFSET(x) + 0xc)
+#define CPG_PLL_MON_LOCK BIT(4)
+#define CPG_PLL_MON_RESETB BIT(0)
+
#define CLK_ON_R(reg) (reg)
#define CLK_MON_R(reg) (0x180 + (reg))
#define CLK_RST_R(reg) (reg)
#define CLK_MRST_R(reg) (0x180 + (reg))
#define GET_REG_OFFSET(val) ((val >> 20) & 0xfff)
-#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff)
-#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff)
-#define GET_REG_SAMPLL_SETTING(val) ((val) & 0xfff)
#define CPG_WEN_BIT BIT(16)
@@ -1086,8 +1093,8 @@ static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
if (pll_clk->type != CLK_TYPE_SAM_PLL)
return parent_rate;
- val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
- val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf));
+ val1 = readl(priv->base + CPG_PLL_CLK1_OFFSET(pll_clk->conf));
+ val2 = readl(priv->base + CPG_PLL_CLK2_OFFSET(pll_clk->conf));
rate = mul_u64_u32_shr(parent_rate, (MDIV(val1) << 16) + KDIV(val1),
16 + SDIV(val2));
@@ -1107,17 +1114,14 @@ static unsigned long rzg3s_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
u32 nir, nfr, mr, pr, val, setting;
u64 rate;
- if (pll_clk->type != CLK_TYPE_G3S_PLL)
- return parent_rate;
-
- setting = GET_REG_SAMPLL_SETTING(pll_clk->conf);
+ setting = CPG_PLL1_SETTING_OFFSET(pll_clk->conf);
if (setting) {
val = readl(priv->base + setting);
if (val & RZG3S_SEL_PLL)
return pll_clk->default_rate;
}
- val = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
+ val = readl(priv->base + CPG_PLL_CLK1_OFFSET(pll_clk->conf));
pr = 1 << FIELD_GET(RZG3S_DIV_P, val);
/* Hardware interprets values higher than 8 as p = 16. */
@@ -1178,6 +1182,61 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
return pll_clk->hw.clk;
}
+static int rzg3l_cpg_pll_clk_is_enabled(struct clk_hw *hw)
+{
+ struct pll_clk *pll_clk = to_pll(hw);
+ struct rzg2l_cpg_priv *priv = pll_clk->priv;
+ u32 val = readl(priv->base + CPG_PLL_MON_OFFSET(pll_clk->conf));
+ u32 mon_val = CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK;
+
+ /* Ensure both RESETB and LOCK bits are set */
+ return (mon_val == (val & mon_val));
+}
+
+static int rzg3l_cpg_pll_clk_endisable(struct clk_hw *hw, bool enable)
+{
+ struct pll_clk *pll_clk = to_pll(hw);
+ struct rzg2l_cpg_priv *priv = pll_clk->priv;
+ u32 mon_mask = CPG_PLL_MON_RESETB | CPG_PLL_MON_LOCK;
+ u32 val = CPG_PLL_STBY_RESETB_WEN;
+ u32 stby_offset, mon_offset;
+ u32 mon_val = 0;
+ int ret;
+
+ stby_offset = CPG_PLL_STBY_OFFSET(pll_clk->conf);
+ mon_offset = CPG_PLL_MON_OFFSET(pll_clk->conf);
+
+ if (enable) {
+ val |= CPG_PLL_STBY_RESETB;
+ mon_val = mon_mask;
+ }
+
+ writel(val, priv->base + stby_offset);
+
+ /* ensure PLL is in normal/standby mode */
+ ret = readl_poll_timeout_atomic(priv->base + mon_offset, val,
+ mon_val == (val & mon_mask), 10, 100);
+ if (ret)
+ dev_err(priv->dev, "Failed to %s PLL 0x%x/%pC\n", enable ?
+ "enable" : "disable", stby_offset, hw->clk);
+
+ return ret;
+}
+
+static int rzg3l_cpg_pll_clk_enable(struct clk_hw *hw)
+{
+ if (rzg3l_cpg_pll_clk_is_enabled(hw))
+ return 0;
+
+ return rzg3l_cpg_pll_clk_endisable(hw, true);
+}
+
+static const struct clk_ops rzg3l_cpg_pll_ops = {
+ .is_enabled = rzg3l_cpg_pll_clk_is_enabled,
+ .enable = rzg3l_cpg_pll_clk_enable,
+ .recalc_rate = rzg3s_cpg_pll_clk_recalc_rate,
+};
+
static struct clk
*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec,
void *data)
@@ -1261,6 +1320,9 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
case CLK_TYPE_SAM_PLL:
clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg2l_cpg_pll_ops);
break;
+ case CLK_TYPE_G3L_PLL:
+ clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3l_cpg_pll_ops);
+ break;
case CLK_TYPE_G3S_PLL:
clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3s_cpg_pll_ops);
break;
@@ -1340,10 +1402,10 @@ struct mod_clock {
#define to_mod_clock(_hw) container_of(_hw, struct mod_clock, hw)
#define for_each_mod_clock(mod_clock, hw, priv) \
- for (unsigned int i = 0; (priv) && i < (priv)->num_mod_clks; i++) \
- if ((priv)->clks[(priv)->num_core_clks + i] == ERR_PTR(-ENOENT)) \
+ for (unsigned int __i = 0; (priv) && __i < (priv)->num_mod_clks; __i++) \
+ if ((priv)->clks[(priv)->num_core_clks + __i] == ERR_PTR(-ENOENT)) \
continue; \
- else if (((hw) = __clk_get_hw((priv)->clks[(priv)->num_core_clks + i])) && \
+ else if (((hw) = __clk_get_hw((priv)->clks[(priv)->num_core_clks + __i])) && \
((mod_clock) = to_mod_clock(hw)))
/* Need to be called with a lock held to avoid concurrent access to mstop->usecnt. */
diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h
index 10baf9e71a6e..bd6169f62538 100644
--- a/drivers/clk/renesas/rzg2l-cpg.h
+++ b/drivers/clk/renesas/rzg2l-cpg.h
@@ -58,11 +58,8 @@
#define CPG_CLKSTATUS_SELSDHI0_STS BIT(28)
#define CPG_CLKSTATUS_SELSDHI1_STS BIT(29)
-/* n = 0/1/2 for PLL1/4/6 */
-#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n))
-#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n))
-
-#define PLL146_CONF(n) (CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12)
+#define CPG_SAM_PLL_CONF(stby) ((stby) << 12)
+#define CPG_PLL_CONF(stby, setting) ((stby) << 12 | (setting))
#define DDIV_PACK(offset, bitpos, size) \
(((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
@@ -123,6 +120,7 @@ enum clk_types {
CLK_TYPE_IN, /* External Clock Input */
CLK_TYPE_FF, /* Fixed Factor Clock */
CLK_TYPE_SAM_PLL,
+ CLK_TYPE_G3L_PLL,
CLK_TYPE_G3S_PLL,
/* Clock with divider */
@@ -152,6 +150,9 @@ enum clk_types {
DEF_TYPE(_name, _id, _type, .parent = _parent)
#define DEF_SAMPLL(_name, _id, _parent, _conf) \
DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf)
+#define DEF_G3L_PLL(_name, _id, _parent, _conf, _default_rate) \
+ DEF_TYPE(_name, _id, CLK_TYPE_G3L_PLL, .parent = _parent, .conf = _conf, \
+ .default_rate = _default_rate)
#define DEF_G3S_PLL(_name, _id, _parent, _conf, _default_rate) \
DEF_TYPE(_name, _id, CLK_TYPE_G3S_PLL, .parent = _parent, .conf = _conf, \
.default_rate = _default_rate)
@@ -174,11 +175,14 @@ enum clk_types {
.invalid_rate = _invalid_rate, \
.max_rate = _max_rate, .flag = (_clk_flags), \
.notifier = _notif)
-#define DEF_MUX(_name, _id, _conf, _parent_names) \
+#define DEF_MUX_FLAGS(_name, _id, _conf, _parent_names, _flag) \
DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \
.parent_names = _parent_names, \
.num_parents = ARRAY_SIZE(_parent_names), \
- .mux_flags = CLK_MUX_HIWORD_MASK)
+ .mux_flags = CLK_MUX_HIWORD_MASK, \
+ .flag = _flag)
+#define DEF_MUX(_name, _id, _conf, _parent_names) \
+ DEF_MUX_FLAGS(_name, _id, _conf, _parent_names, 0)
#define DEF_MUX_RO(_name, _id, _conf, _parent_names) \
DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \
.parent_names = _parent_names, \
diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c
index f6c47fb89bca..e271c04cee34 100644
--- a/drivers/clk/renesas/rzv2h-cpg.c
+++ b/drivers/clk/renesas/rzv2h-cpg.c
@@ -76,6 +76,11 @@
/* On RZ/G3E SoC we have two DSI PLLs */
#define MAX_CPG_DSI_PLL 2
+#define CPG_PLLDSI_SMUX_LVDS_DUTY_NUM 4
+#define CPG_PLLDSI_SMUX_LVDS_DUTY_DEN 7
+#define CPG_PLLDSI_SMUX_DSI_RGB_DUTY_NUM 1
+#define CPG_PLLDSI_SMUX_DSI_RGB_DUTY_DEN 2
+
/**
* struct rzv2h_pll_dsi_info - PLL DSI information, holds the limits and parameters
*
@@ -418,6 +423,20 @@ bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits,
}
EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_divs_pars, "RZV2H_CPG");
+/**
+ * struct rzv2h_plldsi_mux_clk - PLL DSI MUX clock
+ *
+ * @priv: CPG private data
+ * @mux: mux clk
+ */
+struct rzv2h_plldsi_mux_clk {
+ struct rzv2h_cpg_priv *priv;
+ struct clk_mux mux;
+};
+
+#define to_plldsi_clk_mux(_mux) \
+ container_of(_mux, struct rzv2h_plldsi_mux_clk, mux)
+
static unsigned long rzv2h_cpg_plldsi_div_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
@@ -649,6 +668,165 @@ static int rzv2h_cpg_plldsi_set_rate(struct clk_hw *hw, unsigned long rate,
return rzv2h_cpg_pll_set_rate(pll_clk, &dsi_info->pll_dsi_parameters.pll, true);
}
+static u8 rzv2h_cpg_plldsi_smux_get_parent(struct clk_hw *hw)
+{
+ return clk_mux_ops.get_parent(hw);
+}
+
+static int rzv2h_cpg_plldsi_smux_set_parent(struct clk_hw *hw, u8 index)
+{
+ return clk_mux_ops.set_parent(hw, index);
+}
+
+static int rzv2h_cpg_plldsi_smux_lvds_determine_rate(struct rzv2h_cpg_priv *priv,
+ struct pll_clk *pll_clk,
+ struct clk_rate_request *req)
+{
+ struct rzv2h_pll_div_pars *dsi_params;
+ struct rzv2h_pll_dsi_info *dsi_info;
+ u8 lvds_table[] = { 7 };
+ u64 rate_millihz;
+
+ dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance];
+ dsi_params = &dsi_info->pll_dsi_parameters;
+
+ rate_millihz = mul_u32_u32(req->rate, MILLI);
+ if (!rzv2h_get_pll_divs_pars(dsi_info->pll_dsi_limits, dsi_params,
+ lvds_table, ARRAY_SIZE(lvds_table), rate_millihz)) {
+ dev_err(priv->dev, "failed to determine rate for req->rate: %lu\n",
+ req->rate);
+ return -EINVAL;
+ }
+
+ req->rate = DIV_ROUND_CLOSEST_ULL(dsi_params->div.freq_millihz, MILLI);
+ req->best_parent_rate = req->rate;
+ dsi_info->req_pll_dsi_rate = req->best_parent_rate * dsi_params->div.divider_value;
+
+ return 0;
+}
+
+static int rzv2h_cpg_plldsi_smux_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_mux *mux = to_clk_mux(hw);
+ struct rzv2h_plldsi_mux_clk *dsi_mux = to_plldsi_clk_mux(mux);
+ struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw));
+ struct rzv2h_cpg_priv *priv = dsi_mux->priv;
+
+ /*
+ * For LVDS output (parent index 0), calculate PLL parameters with
+ * fixed divider value of 7. For DSI/RGB output (parent index 1) skip
+ * PLL calculation here as it's handled by determine_rate of the
+ * divider (up one level).
+ */
+ if (!clk_mux_ops.get_parent(hw))
+ return rzv2h_cpg_plldsi_smux_lvds_determine_rate(priv, pll_clk, req);
+
+ req->best_parent_rate = req->rate;
+ return 0;
+}
+
+static int rzv2h_cpg_plldsi_smux_get_duty_cycle(struct clk_hw *hw,
+ struct clk_duty *duty)
+{
+ u8 parent = clk_mux_ops.get_parent(hw);
+
+ /*
+ * CDIV7_DSIx_CLK - LVDS path (div7) - duty 4/7.
+ * CSDIV_DSIx - DSI/RGB path (csdiv) - duty 1/2.
+ */
+ if (parent == 0) {
+ duty->num = CPG_PLLDSI_SMUX_LVDS_DUTY_NUM;
+ duty->den = CPG_PLLDSI_SMUX_LVDS_DUTY_DEN;
+ } else {
+ duty->num = CPG_PLLDSI_SMUX_DSI_RGB_DUTY_NUM;
+ duty->den = CPG_PLLDSI_SMUX_DSI_RGB_DUTY_DEN;
+ }
+
+ return 0;
+}
+
+static int rzv2h_cpg_plldsi_smux_set_duty_cycle(struct clk_hw *hw,
+ struct clk_duty *duty)
+{
+ struct clk_hw *parent_hw;
+ u8 parent_idx;
+
+ /*
+ * Select parent based on requested duty cycle:
+ * - If duty > 50% (num/den > 1/2), select LVDS path (parent 0)
+ * - Otherwise, select DSI/RGB path (parent 1)
+ */
+ if (duty->num * CPG_PLLDSI_SMUX_DSI_RGB_DUTY_DEN >
+ duty->den * CPG_PLLDSI_SMUX_DSI_RGB_DUTY_NUM)
+ parent_idx = 0;
+ else
+ parent_idx = 1;
+
+ if (parent_idx >= clk_hw_get_num_parents(hw))
+ return -EINVAL;
+
+ parent_hw = clk_hw_get_parent_by_index(hw, parent_idx);
+ if (!parent_hw)
+ return -EINVAL;
+
+ return clk_hw_set_parent(hw, parent_hw);
+}
+
+static const struct clk_ops rzv2h_cpg_plldsi_smux_ops = {
+ .determine_rate = rzv2h_cpg_plldsi_smux_determine_rate,
+ .get_parent = rzv2h_cpg_plldsi_smux_get_parent,
+ .set_parent = rzv2h_cpg_plldsi_smux_set_parent,
+ .get_duty_cycle = rzv2h_cpg_plldsi_smux_get_duty_cycle,
+ .set_duty_cycle = rzv2h_cpg_plldsi_smux_set_duty_cycle,
+};
+
+static struct clk * __init
+rzv2h_cpg_plldsi_smux_clk_register(const struct cpg_core_clk *core,
+ struct rzv2h_cpg_priv *priv)
+{
+ struct rzv2h_plldsi_mux_clk *clk_hw_data;
+ struct clk_init_data init;
+ struct clk_hw *clk_hw;
+ struct smuxed smux;
+ int ret;
+
+ smux = core->cfg.smux;
+
+ if (smux.shift + smux.width > 16) {
+ dev_err(priv->dev, "mux value exceeds LOWORD field\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);
+ if (!clk_hw_data)
+ return ERR_PTR(-ENOMEM);
+
+ clk_hw_data->priv = priv;
+
+ init.name = core->name;
+ init.ops = &rzv2h_cpg_plldsi_smux_ops;
+ init.flags = core->flag;
+ init.parent_names = core->parent_names;
+ init.num_parents = core->num_parents;
+
+ clk_hw_data->mux.reg = priv->base + smux.offset;
+
+ clk_hw_data->mux.shift = smux.shift;
+ clk_hw_data->mux.mask = clk_div_mask(smux.width);
+ clk_hw_data->mux.flags = core->mux_flags;
+ clk_hw_data->mux.lock = &priv->rmw_lock;
+
+ clk_hw = &clk_hw_data->mux.hw;
+ clk_hw->init = &init;
+
+ ret = devm_clk_hw_register(priv->dev, clk_hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return clk_hw->clk;
+}
+
static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw)
{
struct pll_clk *pll_clk = to_pll(hw);
@@ -1085,6 +1263,9 @@ rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core,
case CLK_TYPE_PLLDSI_DIV:
clk = rzv2h_cpg_plldsi_div_clk_register(core, priv);
break;
+ case CLK_TYPE_PLLDSI_SMUX:
+ clk = rzv2h_cpg_plldsi_smux_clk_register(core, priv);
+ break;
default:
goto fail;
}
diff --git a/drivers/clk/renesas/rzv2h-cpg.h b/drivers/clk/renesas/rzv2h-cpg.h
index dc957bdaf5e9..dec0f7b621d6 100644
--- a/drivers/clk/renesas/rzv2h-cpg.h
+++ b/drivers/clk/renesas/rzv2h-cpg.h
@@ -121,6 +121,7 @@ struct fixed_mod_conf {
#define CPG_SSEL0 (0x300)
#define CPG_SSEL1 (0x304)
+#define CPG_SSEL3 (0x30C)
#define CPG_CDDIV0 (0x400)
#define CPG_CDDIV1 (0x404)
#define CPG_CDDIV2 (0x408)
@@ -148,6 +149,7 @@ struct fixed_mod_conf {
#define CSDIV0_DIVCTL2 DDIV_PACK(CPG_CSDIV0, 8, 2, CSDIV_NO_MON)
#define CSDIV0_DIVCTL3 DDIV_PACK_NO_RMW(CPG_CSDIV0, 12, 2, CSDIV_NO_MON)
#define CSDIV1_DIVCTL2 DDIV_PACK(CPG_CSDIV1, 8, 4, CSDIV_NO_MON)
+#define CSDIV1_DIVCTL3 DDIV_PACK(CPG_CSDIV1, 12, 4, CSDIV_NO_MON)
#define SSEL0_SELCTL2 SMUX_PACK(CPG_SSEL0, 8, 1)
#define SSEL0_SELCTL3 SMUX_PACK(CPG_SSEL0, 12, 1)
@@ -155,6 +157,8 @@ struct fixed_mod_conf {
#define SSEL1_SELCTL1 SMUX_PACK(CPG_SSEL1, 4, 1)
#define SSEL1_SELCTL2 SMUX_PACK(CPG_SSEL1, 8, 1)
#define SSEL1_SELCTL3 SMUX_PACK(CPG_SSEL1, 12, 1)
+#define SSEL3_SELCTL0 SMUX_PACK(CPG_SSEL3, 0, 1)
+#define SSEL3_SELCTL1 SMUX_PACK(CPG_SSEL3, 4, 1)
#define BUS_MSTOP_IDX_MASK GENMASK(31, 16)
#define BUS_MSTOP_BITS_MASK GENMASK(15, 0)
@@ -203,6 +207,7 @@ enum clk_types {
CLK_TYPE_SMUX, /* Static Mux */
CLK_TYPE_PLLDSI, /* PLLDSI */
CLK_TYPE_PLLDSI_DIV, /* PLLDSI divider */
+ CLK_TYPE_PLLDSI_SMUX, /* PLLDSI Static Mux */
};
#define DEF_TYPE(_name, _id, _type...) \
@@ -241,6 +246,13 @@ enum clk_types {
.dtable = _dtable, \
.parent = _parent, \
.flag = CLK_SET_RATE_PARENT)
+#define DEF_PLLDSI_SMUX(_name, _id, _smux_packed, _parent_names) \
+ DEF_TYPE(_name, _id, CLK_TYPE_PLLDSI_SMUX, \
+ .cfg.smux = _smux_packed, \
+ .parent_names = _parent_names, \
+ .num_parents = ARRAY_SIZE(_parent_names), \
+ .flag = CLK_SET_RATE_PARENT, \
+ .mux_flags = CLK_MUX_HIWORD_MASK)
/**
* struct rzv2h_mod_clk - Module Clocks definitions
diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c
index 8dd94f64756b..2bdea1997b5e 100644
--- a/drivers/clk/socfpga/clk-agilex.c
+++ b/drivers/clk/socfpga/clk-agilex.c
@@ -259,6 +259,8 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
0, 0x3C, 0, 0, 0},
{ AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
0, 0x40, 0, 0, 0},
+ { AGILEX_L3_MAIN_FREE_CLK, "l3_main_free_clk", "noc_free_clk", NULL,
+ 1, 0, 0, 1, 0, 0},
{ AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
0, 4, 0x30, 1},
{ AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),