Commit bc840f33 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'meson-clk-5.2' of https://github.com/BayLibre/clk-meson into clk-meson

Pull Amlogic Meson clk driver updates from Neil Armstrong:

 - Adds VPU and Video Decoder clocks on Meson8b
 - Finally remove the wrong ABP Meson8b clock id
 - Adds Video Decoder, PCIe PLL & CPU Clocks on G12A
 - Re-expose SAR_ADC_SEL and CTS_OSCIN on G12A AO clock controller
 - Un-expose some AXG-Audio input clocks IDs

* tag 'meson-clk-5.2' of https://github.com/BayLibre/clk-meson:
  clk: meson: meson8b: add the video decoder clock trees
  clk: meson: meson8b: add the VPU clock trees
  clk: meson: meson8b: add support for the GP_PLL clock on Meson8m2
  clk: meson: meson8b: use a separate clock table for Meson8m2
  clk: meson-g12a: add video decoder clocks
  clk: meson-g12a: add PCIE PLL clocks
  clk: meson-pll: add reduced specific clk_ops for G12A PCIe PLL
  clk: meson: g12a: add cpu clocks
  dt-bindings: clock: meson8b: export the video decoder clocks
  dt-bindings: clock: meson8b: export the VPU clock
  dt-bindings: clock: g12a-aoclk: expose CLKID_AO_CTS_OSCIN
  dt-bindings: clock: meson8b: drop the "ABP" clock definition
  dt-bindings: clk: g12a-clkc: add VDEC clock IDs
  dt-bindings: clock: axg-audio: unexpose controller inputs
  dt-bindings: clk: g12a-clkc: add PCIE PLL clock ID
  clk: g12a-aoclk: re-export CLKID_AO_SAR_ADC_SEL clock id
  clk: meson-g12a: add cpu clock bindings
parents 9e98c678 90751f68
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -60,6 +60,26 @@
#define AUD_CLKID_MST5			6
#define AUD_CLKID_MST6			7
#define AUD_CLKID_MST7			8
#define AUD_CLKID_SLV_SCLK0		9
#define AUD_CLKID_SLV_SCLK1		10
#define AUD_CLKID_SLV_SCLK2		11
#define AUD_CLKID_SLV_SCLK3		12
#define AUD_CLKID_SLV_SCLK4		13
#define AUD_CLKID_SLV_SCLK5		14
#define AUD_CLKID_SLV_SCLK6		15
#define AUD_CLKID_SLV_SCLK7		16
#define AUD_CLKID_SLV_SCLK8		17
#define AUD_CLKID_SLV_SCLK9		18
#define AUD_CLKID_SLV_LRCLK0		19
#define AUD_CLKID_SLV_LRCLK1		20
#define AUD_CLKID_SLV_LRCLK2		21
#define AUD_CLKID_SLV_LRCLK3		22
#define AUD_CLKID_SLV_LRCLK4		23
#define AUD_CLKID_SLV_LRCLK5		24
#define AUD_CLKID_SLV_LRCLK6		25
#define AUD_CLKID_SLV_LRCLK7		26
#define AUD_CLKID_SLV_LRCLK8		27
#define AUD_CLKID_SLV_LRCLK9		28
#define AUD_CLKID_MST_A_MCLK_SEL	59
#define AUD_CLKID_MST_B_MCLK_SEL	60
#define AUD_CLKID_MST_C_MCLK_SEL	61
+26 −0
Original line number Diff line number Diff line
@@ -303,6 +303,16 @@ static int meson_clk_pll_is_enabled(struct clk_hw *hw)
	return 1;
}

static int meson_clk_pcie_pll_enable(struct clk_hw *hw)
{
	meson_clk_pll_init(hw);

	if (meson_clk_pll_wait_lock(hw))
		return -EIO;

	return 0;
}

static int meson_clk_pll_enable(struct clk_hw *hw)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
@@ -387,6 +397,22 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
	return 0;
}

/*
 * The Meson G12A PCIE PLL is fined tuned to deliver a very precise
 * 100MHz reference clock for the PCIe Analog PHY, and thus requires
 * a strict register sequence to enable the PLL.
 * To simplify, re-use the _init() op to enable the PLL and keep
 * the other ops except set_rate since the rate is fixed.
 */
const struct clk_ops meson_clk_pcie_pll_ops = {
	.recalc_rate	= meson_clk_pll_recalc_rate,
	.round_rate	= meson_clk_pll_round_rate,
	.is_enabled	= meson_clk_pll_is_enabled,
	.enable		= meson_clk_pcie_pll_enable,
	.disable	= meson_clk_pll_disable
};
EXPORT_SYMBOL_GPL(meson_clk_pcie_pll_ops);

const struct clk_ops meson_clk_pll_ops = {
	.init		= meson_clk_pll_init,
	.recalc_rate	= meson_clk_pll_recalc_rate,
+1 −0
Original line number Diff line number Diff line
@@ -45,5 +45,6 @@ struct meson_clk_pll_data {

extern const struct clk_ops meson_clk_pll_ro_ops;
extern const struct clk_ops meson_clk_pll_ops;
extern const struct clk_ops meson_clk_pcie_pll_ops;

#endif /* __MESON_CLK_PLL_H */
+0 −2
Original line number Diff line number Diff line
@@ -16,9 +16,7 @@
 * to expose, such as the internal muxes and dividers of composite clocks,
 * will remain defined here.
 */
#define CLKID_AO_SAR_ADC_SEL	16
#define CLKID_AO_SAR_ADC_DIV	17
#define CLKID_AO_CTS_OSCIN	19
#define CLKID_AO_32K_PRE	20
#define CLKID_AO_32K_DIV	21
#define CLKID_AO_32K_SEL	22
+631 −0
Original line number Diff line number Diff line
@@ -150,6 +150,318 @@ static struct clk_regmap g12a_sys_pll = {
	},
};

static struct clk_regmap g12a_sys_pll_div16_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "sys_pll_div16_en",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_names = (const char *[]){ "sys_pll" },
		.num_parents = 1,
		/*
		 * This clock is used to debug the sys_pll range
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_fixed_factor g12a_sys_pll_div16 = {
	.mult = 1,
	.div = 16,
	.hw.init = &(struct clk_init_data){
		.name = "sys_pll_div16",
		.ops = &clk_fixed_factor_ops,
		.parent_names = (const char *[]){ "sys_pll_div16_en" },
		.num_parents = 1,
	},
};

/* Datasheet names this field as "premux0" */
static struct clk_regmap g12a_cpu_clk_premux0 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x3,
		.shift = 0,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn0_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_names = (const char *[]){ IN_PREFIX "xtal",
						  "fclk_div2",
						  "fclk_div3" },
		.num_parents = 3,
	},
};

/* Datasheet names this field as "mux0_divn_tcnt" */
static struct clk_regmap g12a_cpu_clk_mux0_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.shift = 4,
		.width = 6,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn0_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_dyn0_sel" },
		.num_parents = 1,
	},
};

/* Datasheet names this field as "postmux0" */
static struct clk_regmap g12a_cpu_clk_postmux0 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x1,
		.shift = 2,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn0",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_dyn0_sel",
						  "cpu_clk_dyn0_div" },
		.num_parents = 2,
	},
};

/* Datasheet names this field as "premux1" */
static struct clk_regmap g12a_cpu_clk_premux1 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x3,
		.shift = 16,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn1_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_names = (const char *[]){ IN_PREFIX "xtal",
						  "fclk_div2",
						  "fclk_div3" },
		.num_parents = 3,
	},
};

/* Datasheet names this field as "Mux1_divn_tcnt" */
static struct clk_regmap g12a_cpu_clk_mux1_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.shift = 20,
		.width = 6,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn1_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_dyn1_sel" },
		.num_parents = 1,
	},
};

/* Datasheet names this field as "postmux1" */
static struct clk_regmap g12a_cpu_clk_postmux1 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x1,
		.shift = 18,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn1",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_dyn1_sel",
						  "cpu_clk_dyn1_div" },
		.num_parents = 2,
	},
};

/* Datasheet names this field as "Final_dyn_mux_sel" */
static struct clk_regmap g12a_cpu_clk_dyn = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x1,
		.shift = 10,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_dyn0",
						  "cpu_clk_dyn1" },
		.num_parents = 2,
	},
};

/* Datasheet names this field as "Final_mux_sel" */
static struct clk_regmap g12a_cpu_clk = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x1,
		.shift = 11,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_dyn",
						  "sys_pll" },
		.num_parents = 2,
	},
};

static struct clk_regmap g12a_cpu_clk_div16_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 1,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_div16_en",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk" },
		.num_parents = 1,
		/*
		 * This clock is used to debug the cpu_clk range
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_fixed_factor g12a_cpu_clk_div16 = {
	.mult = 1,
	.div = 16,
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_div16",
		.ops = &clk_fixed_factor_ops,
		.parent_names = (const char *[]){ "cpu_clk_div16_en" },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_apb_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.shift = 3,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_apb_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk" },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_apb = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 1,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_apb",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_apb_div" },
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12a_cpu_clk_atb_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.shift = 6,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_atb_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk" },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_atb = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 17,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_atb",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_atb_div" },
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12a_cpu_clk_axi_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.shift = 9,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_axi_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk" },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_axi = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 18,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_axi",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_axi_div" },
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12a_cpu_clk_trace_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.shift = 20,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_trace_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk" },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_trace = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 23,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_trace",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_names = (const char *[]){ "cpu_clk_trace_div" },
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static const struct pll_mult_range g12a_gp0_pll_mult_range = {
	.min = 55,
	.max = 255,
@@ -302,6 +614,118 @@ static struct clk_regmap g12a_hifi_pll = {
	},
};

/*
 * The Meson G12A PCIE PLL is fined tuned to deliver a very precise
 * 100MHz reference clock for the PCIe Analog PHY, and thus requires
 * a strict register sequence to enable the PLL.
 */
static const struct reg_sequence g12a_pcie_pll_init_regs[] = {
	{ .reg = HHI_PCIE_PLL_CNTL0,	.def = 0x20090496 },
	{ .reg = HHI_PCIE_PLL_CNTL0,	.def = 0x30090496 },
	{ .reg = HHI_PCIE_PLL_CNTL1,	.def = 0x00000000 },
	{ .reg = HHI_PCIE_PLL_CNTL2,	.def = 0x00001100 },
	{ .reg = HHI_PCIE_PLL_CNTL3,	.def = 0x10058e00 },
	{ .reg = HHI_PCIE_PLL_CNTL4,	.def = 0x000100c0 },
	{ .reg = HHI_PCIE_PLL_CNTL5,	.def = 0x68000048 },
	{ .reg = HHI_PCIE_PLL_CNTL5,	.def = 0x68000068, .delay_us = 20 },
	{ .reg = HHI_PCIE_PLL_CNTL4,	.def = 0x008100c0, .delay_us = 10 },
	{ .reg = HHI_PCIE_PLL_CNTL0,	.def = 0x34090496 },
	{ .reg = HHI_PCIE_PLL_CNTL0,	.def = 0x14090496, .delay_us = 10 },
	{ .reg = HHI_PCIE_PLL_CNTL2,	.def = 0x00001000 },
};

/* Keep a single entry table for recalc/round_rate() ops */
static const struct pll_params_table g12a_pcie_pll_table[] = {
	PLL_PARAMS(150, 1),
	{0, 0},
};

static struct clk_regmap g12a_pcie_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.m = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 0,
			.width   = 8,
		},
		.n = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 10,
			.width   = 5,
		},
		.frac = {
			.reg_off = HHI_PCIE_PLL_CNTL1,
			.shift   = 0,
			.width   = 12,
		},
		.l = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 31,
			.width   = 1,
		},
		.rst = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 29,
			.width   = 1,
		},
		.table = g12a_pcie_pll_table,
		.init_regs = g12a_pcie_pll_init_regs,
		.init_count = ARRAY_SIZE(g12a_pcie_pll_init_regs),
	},
	.hw.init = &(struct clk_init_data){
		.name = "pcie_pll_dco",
		.ops = &meson_clk_pcie_pll_ops,
		.parent_names = (const char *[]){ IN_PREFIX "xtal" },
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_pcie_pll_dco_div2 = {
	.mult = 1,
	.div = 2,
	.hw.init = &(struct clk_init_data){
		.name = "pcie_pll_dco_div2",
		.ops = &clk_fixed_factor_ops,
		.parent_names = (const char *[]){ "pcie_pll_dco" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_pcie_pll_od = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_PCIE_PLL_CNTL0,
		.shift = 16,
		.width = 5,
		.flags = CLK_DIVIDER_ROUND_CLOSEST |
			 CLK_DIVIDER_ONE_BASED |
			 CLK_DIVIDER_ALLOW_ZERO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "pcie_pll_od",
		.ops = &clk_regmap_divider_ops,
		.parent_names = (const char *[]){ "pcie_pll_dco_div2" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_fixed_factor g12a_pcie_pll = {
	.mult = 1,
	.div = 2,
	.hw.init = &(struct clk_init_data){
		.name = "pcie_pll_pll",
		.ops = &clk_fixed_factor_ops,
		.parent_names = (const char *[]){ "pcie_pll_od" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_hdmi_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
@@ -1071,6 +1495,151 @@ static struct clk_regmap g12a_vpu = {
	},
};

/* VDEC clocks */

static const char * const g12a_vdec_parent_names[] = {
	"fclk_div2p5", "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7",
	"hifi_pll", "gp0_pll",
};

static struct clk_regmap g12a_vdec_1_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VDEC_CLK_CNTL,
		.mask = 0x7,
		.shift = 9,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_1_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_names = g12a_vdec_parent_names,
		.num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_1_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VDEC_CLK_CNTL,
		.shift = 0,
		.width = 7,
		.flags = CLK_DIVIDER_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_1_div",
		.ops = &clk_regmap_divider_ops,
		.parent_names = (const char *[]){ "vdec_1_sel" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_1 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VDEC_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vdec_1",
		.ops = &clk_regmap_gate_ops,
		.parent_names = (const char *[]){ "vdec_1_div" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevcf_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.mask = 0x7,
		.shift = 9,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_hevcf_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_names = g12a_vdec_parent_names,
		.num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevcf_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.shift = 0,
		.width = 7,
		.flags = CLK_DIVIDER_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_hevcf_div",
		.ops = &clk_regmap_divider_ops,
		.parent_names = (const char *[]){ "vdec_hevcf_sel" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevcf = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vdec_hevcf",
		.ops = &clk_regmap_gate_ops,
		.parent_names = (const char *[]){ "vdec_hevcf_div" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevc_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.mask = 0x7,
		.shift = 25,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_hevc_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_names = g12a_vdec_parent_names,
		.num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevc_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.shift = 16,
		.width = 7,
		.flags = CLK_DIVIDER_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_hevc_div",
		.ops = &clk_regmap_divider_ops,
		.parent_names = (const char *[]){ "vdec_hevc_sel" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevc = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vdec_hevc",
		.ops = &clk_regmap_gate_ops,
		.parent_names = (const char *[]){ "vdec_hevc_div" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* VAPB Clock */

static const char * const g12a_vapb_parent_names[] = {
@@ -2167,6 +2736,39 @@ static struct clk_hw_onecell_data g12a_hw_onecell_data = {
		[CLKID_MALI]			= &g12a_mali.hw,
		[CLKID_MPLL_5OM_DIV]		= &g12a_mpll_50m_div.hw,
		[CLKID_MPLL_5OM]		= &g12a_mpll_50m.hw,
		[CLKID_SYS_PLL_DIV16_EN]	= &g12a_sys_pll_div16_en.hw,
		[CLKID_SYS_PLL_DIV16]		= &g12a_sys_pll_div16.hw,
		[CLKID_CPU_CLK_DYN0_SEL]	= &g12a_cpu_clk_premux0.hw,
		[CLKID_CPU_CLK_DYN0_DIV]	= &g12a_cpu_clk_mux0_div.hw,
		[CLKID_CPU_CLK_DYN0]		= &g12a_cpu_clk_postmux0.hw,
		[CLKID_CPU_CLK_DYN1_SEL]	= &g12a_cpu_clk_premux1.hw,
		[CLKID_CPU_CLK_DYN1_DIV]	= &g12a_cpu_clk_mux1_div.hw,
		[CLKID_CPU_CLK_DYN1]		= &g12a_cpu_clk_postmux1.hw,
		[CLKID_CPU_CLK_DYN]		= &g12a_cpu_clk_dyn.hw,
		[CLKID_CPU_CLK]			= &g12a_cpu_clk.hw,
		[CLKID_CPU_CLK_DIV16_EN]	= &g12a_cpu_clk_div16_en.hw,
		[CLKID_CPU_CLK_DIV16]		= &g12a_cpu_clk_div16.hw,
		[CLKID_CPU_CLK_APB_DIV]		= &g12a_cpu_clk_apb_div.hw,
		[CLKID_CPU_CLK_APB]		= &g12a_cpu_clk_apb.hw,
		[CLKID_CPU_CLK_ATB_DIV]		= &g12a_cpu_clk_atb_div.hw,
		[CLKID_CPU_CLK_ATB]		= &g12a_cpu_clk_atb.hw,
		[CLKID_CPU_CLK_AXI_DIV]		= &g12a_cpu_clk_axi_div.hw,
		[CLKID_CPU_CLK_AXI]		= &g12a_cpu_clk_axi.hw,
		[CLKID_CPU_CLK_TRACE_DIV]	= &g12a_cpu_clk_trace_div.hw,
		[CLKID_CPU_CLK_TRACE]		= &g12a_cpu_clk_trace.hw,
		[CLKID_PCIE_PLL_DCO]		= &g12a_pcie_pll_dco.hw,
		[CLKID_PCIE_PLL_DCO_DIV2]	= &g12a_pcie_pll_dco_div2.hw,
		[CLKID_PCIE_PLL_OD]		= &g12a_pcie_pll_od.hw,
		[CLKID_PCIE_PLL]		= &g12a_pcie_pll.hw,
		[CLKID_VDEC_1_SEL]		= &g12a_vdec_1_sel.hw,
		[CLKID_VDEC_1_DIV]		= &g12a_vdec_1_div.hw,
		[CLKID_VDEC_1]			= &g12a_vdec_1.hw,
		[CLKID_VDEC_HEVC_SEL]		= &g12a_vdec_hevc_sel.hw,
		[CLKID_VDEC_HEVC_DIV]		= &g12a_vdec_hevc_div.hw,
		[CLKID_VDEC_HEVC]		= &g12a_vdec_hevc.hw,
		[CLKID_VDEC_HEVCF_SEL]		= &g12a_vdec_hevcf_sel.hw,
		[CLKID_VDEC_HEVCF_DIV]		= &g12a_vdec_hevcf_div.hw,
		[CLKID_VDEC_HEVCF]		= &g12a_vdec_hevcf.hw,
		[NR_CLKS]			= NULL,
	},
	.num = NR_CLKS,
@@ -2335,6 +2937,35 @@ static struct clk_regmap *const g12a_clk_regmaps[] = {
	&g12a_mali_1,
	&g12a_mali,
	&g12a_mpll_50m,
	&g12a_sys_pll_div16_en,
	&g12a_cpu_clk_premux0,
	&g12a_cpu_clk_mux0_div,
	&g12a_cpu_clk_postmux0,
	&g12a_cpu_clk_premux1,
	&g12a_cpu_clk_mux1_div,
	&g12a_cpu_clk_postmux1,
	&g12a_cpu_clk_dyn,
	&g12a_cpu_clk,
	&g12a_cpu_clk_div16_en,
	&g12a_cpu_clk_apb_div,
	&g12a_cpu_clk_apb,
	&g12a_cpu_clk_atb_div,
	&g12a_cpu_clk_atb,
	&g12a_cpu_clk_axi_div,
	&g12a_cpu_clk_axi,
	&g12a_cpu_clk_trace_div,
	&g12a_cpu_clk_trace,
	&g12a_pcie_pll_od,
	&g12a_pcie_pll_dco,
	&g12a_vdec_1_sel,
	&g12a_vdec_1_div,
	&g12a_vdec_1,
	&g12a_vdec_hevc_sel,
	&g12a_vdec_hevc_div,
	&g12a_vdec_hevc,
	&g12a_vdec_hevcf_sel,
	&g12a_vdec_hevcf_div,
	&g12a_vdec_hevcf,
};

static const struct meson_eeclkc_data g12a_clkc_data = {
Loading