Commit 07fbf0e5 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'clk-meson-v5.8-1' of https://github.com/BayLibre/clk-meson into clk-amlogic

Pull Amlogic clk driver updates from Jerome Brunet:

- Meson8b: Updates and fixup HDMI and video clocks
- Meson8b: Fixup reset polarity
- Meson gx and g12: fix GPU glitch free mux switch

* tag 'clk-meson-v5.8-1' of https://github.com/BayLibre/clk-meson:
  clk: meson: meson8b: Don't rely on u-boot to init all GP_PLL registers
  clk: meson: meson8b: Make the CCF use the glitch-free VPU mux
  clk: meson: meson8b: Fix the vclk_div{1, 2, 4, 6, 12}_en gate bits
  clk: meson: meson8b: Fix the polarity of the RESET_N lines
  clk: meson: meson8b: Fix the first parent of vid_pll_in_sel
  clk: meson: g12a: Prepare the GPU clock tree to change at runtime
  clk: meson: gxbb: Prepare the GPU clock tree to change at runtime
  clk: meson: meson8b: make the hdmi_sys clock tree mutable
  clk: meson8b: export the HDMI system clock
parents 8f3d9f35 a29ae860
Loading
Loading
Loading
Loading
+22 −8
Original line number Diff line number Diff line
@@ -3702,7 +3702,9 @@ static struct clk_regmap g12a_hdmi = {

/*
 * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
 * muxed by a glitch-free switch.
 * muxed by a glitch-free switch. The CCF can manage this glitch-free
 * mux because it does top-to-bottom updates the each clock tree and
 * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
 */
static const struct clk_parent_data g12a_mali_0_1_parent_data[] = {
	{ .fw_name = "xtal", },
@@ -3726,7 +3728,13 @@ static struct clk_regmap g12a_mali_0_sel = {
		.ops = &clk_regmap_mux_ops,
		.parent_data = g12a_mali_0_1_parent_data,
		.num_parents = 8,
		.flags = CLK_SET_RATE_NO_REPARENT,
		/*
		 * Don't request the parent to change the rate because
		 * all GPU frequencies can be derived from the fclk_*
		 * clocks and one special GP0_PLL setting. This is
		 * important because we need the MPLL clocks for audio.
		 */
		.flags = 0,
	},
};

@@ -3743,7 +3751,7 @@ static struct clk_regmap g12a_mali_0_div = {
			&g12a_mali_0_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_NO_REPARENT,
		.flags = CLK_SET_RATE_PARENT,
	},
};

@@ -3759,7 +3767,7 @@ static struct clk_regmap g12a_mali_0 = {
			&g12a_mali_0_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
	},
};

@@ -3774,7 +3782,13 @@ static struct clk_regmap g12a_mali_1_sel = {
		.ops = &clk_regmap_mux_ops,
		.parent_data = g12a_mali_0_1_parent_data,
		.num_parents = 8,
		.flags = CLK_SET_RATE_NO_REPARENT,
		/*
		 * Don't request the parent to change the rate because
		 * all GPU frequencies can be derived from the fclk_*
		 * clocks and one special GP0_PLL setting. This is
		 * important because we need the MPLL clocks for audio.
		 */
		.flags = 0,
	},
};

@@ -3791,7 +3805,7 @@ static struct clk_regmap g12a_mali_1_div = {
			&g12a_mali_1_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_NO_REPARENT,
		.flags = CLK_SET_RATE_PARENT,
	},
};

@@ -3807,7 +3821,7 @@ static struct clk_regmap g12a_mali_1 = {
			&g12a_mali_1_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
	},
};

@@ -3827,7 +3841,7 @@ static struct clk_regmap g12a_mali = {
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_mali_parent_hws,
		.num_parents = 2,
		.flags = CLK_SET_RATE_NO_REPARENT,
		.flags = CLK_SET_RATE_PARENT,
	},
};

+22 −18
Original line number Diff line number Diff line
@@ -957,7 +957,9 @@ static struct clk_regmap gxbb_sar_adc_clk = {

/*
 * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
 * muxed by a glitch-free switch.
 * muxed by a glitch-free switch. The CCF can manage this glitch-free
 * mux because it does top-to-bottom updates the each clock tree and
 * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
 */

static const struct clk_parent_data gxbb_mali_0_1_parent_data[] = {
@@ -980,14 +982,15 @@ static struct clk_regmap gxbb_mali_0_sel = {
	.hw.init = &(struct clk_init_data){
		.name = "mali_0_sel",
		.ops = &clk_regmap_mux_ops,
		/*
		 * bits 10:9 selects from 8 possible parents:
		 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
		 * fclk_div4, fclk_div3, fclk_div5
		 */
		.parent_data = gxbb_mali_0_1_parent_data,
		.num_parents = 8,
		.flags = CLK_SET_RATE_NO_REPARENT,
		/*
		 * Don't request the parent to change the rate because
		 * all GPU frequencies can be derived from the fclk_*
		 * clocks and one special GP0_PLL setting. This is
		 * important because we need the MPLL clocks for audio.
		 */
		.flags = 0,
	},
};

@@ -1004,7 +1007,7 @@ static struct clk_regmap gxbb_mali_0_div = {
			&gxbb_mali_0_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_NO_REPARENT,
		.flags = CLK_SET_RATE_PARENT,
	},
};

@@ -1020,7 +1023,7 @@ static struct clk_regmap gxbb_mali_0 = {
			&gxbb_mali_0_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
	},
};

@@ -1033,14 +1036,15 @@ static struct clk_regmap gxbb_mali_1_sel = {
	.hw.init = &(struct clk_init_data){
		.name = "mali_1_sel",
		.ops = &clk_regmap_mux_ops,
		/*
		 * bits 10:9 selects from 8 possible parents:
		 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
		 * fclk_div4, fclk_div3, fclk_div5
		 */
		.parent_data = gxbb_mali_0_1_parent_data,
		.num_parents = 8,
		.flags = CLK_SET_RATE_NO_REPARENT,
		/*
		 * Don't request the parent to change the rate because
		 * all GPU frequencies can be derived from the fclk_*
		 * clocks and one special GP0_PLL setting. This is
		 * important because we need the MPLL clocks for audio.
		 */
		.flags = 0,
	},
};

@@ -1057,7 +1061,7 @@ static struct clk_regmap gxbb_mali_1_div = {
			&gxbb_mali_1_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_NO_REPARENT,
		.flags = CLK_SET_RATE_PARENT,
	},
};

@@ -1073,7 +1077,7 @@ static struct clk_regmap gxbb_mali_1 = {
			&gxbb_mali_1_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
	},
};

@@ -1093,7 +1097,7 @@ static struct clk_regmap gxbb_mali = {
		.ops = &clk_regmap_mux_ops,
		.parent_hws = gxbb_mali_parent_hws,
		.num_parents = 2,
		.flags = CLK_SET_RATE_NO_REPARENT,
		.flags = CLK_SET_RATE_PARENT,
	},
};

+85 −35
Original line number Diff line number Diff line
@@ -1077,7 +1077,7 @@ static struct clk_regmap meson8b_vid_pll_in_sel = {
		 * Meson8m2: vid2_pll
		 */
		.parent_hws = (const struct clk_hw *[]) {
			&meson8b_hdmi_pll_dco.hw
			&meson8b_hdmi_pll_lvds_out.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
@@ -1213,7 +1213,7 @@ static struct clk_regmap meson8b_vclk_in_en = {

static struct clk_regmap meson8b_vclk_div1_gate = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_DIV,
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 0,
	},
	.hw.init = &(struct clk_init_data){
@@ -1243,7 +1243,7 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = {

static struct clk_regmap meson8b_vclk_div2_div_gate = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_DIV,
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 1,
	},
	.hw.init = &(struct clk_init_data){
@@ -1273,7 +1273,7 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = {

static struct clk_regmap meson8b_vclk_div4_div_gate = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_DIV,
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 2,
	},
	.hw.init = &(struct clk_init_data){
@@ -1303,7 +1303,7 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = {

static struct clk_regmap meson8b_vclk_div6_div_gate = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_DIV,
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 3,
	},
	.hw.init = &(struct clk_init_data){
@@ -1333,7 +1333,7 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = {

static struct clk_regmap meson8b_vclk_div12_div_gate = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_DIV,
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 4,
	},
	.hw.init = &(struct clk_init_data){
@@ -1725,7 +1725,7 @@ static struct clk_regmap meson8b_hdmi_sys_sel = {
	},
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_sys_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.ops = &clk_regmap_mux_ops,
		/* FIXME: all other parents are unknown */
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
@@ -1745,7 +1745,7 @@ static struct clk_regmap meson8b_hdmi_sys_div = {
	},
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_sys_div",
		.ops = &clk_regmap_divider_ro_ops,
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&meson8b_hdmi_sys_sel.hw
		},
@@ -1761,7 +1761,7 @@ static struct clk_regmap meson8b_hdmi_sys = {
	},
	.hw.init = &(struct clk_init_data) {
		.name = "hdmi_sys",
		.ops = &clk_regmap_gate_ro_ops,
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&meson8b_hdmi_sys_div.hw
		},
@@ -1918,6 +1918,13 @@ static struct clk_regmap meson8b_mali = {
	},
};

static const struct reg_sequence meson8m2_gp_pll_init_regs[] = {
	{ .reg = HHI_GP_PLL_CNTL2,	.def = 0x59c88000 },
	{ .reg = HHI_GP_PLL_CNTL3,	.def = 0xca463823 },
	{ .reg = HHI_GP_PLL_CNTL4,	.def = 0x0286a027 },
	{ .reg = HHI_GP_PLL_CNTL5,	.def = 0x00003000 },
};

static const struct pll_params_table meson8m2_gp_pll_params_table[] = {
	PLL_PARAMS(182, 3),
	{ /* sentinel */ },
@@ -1951,6 +1958,8 @@ static struct clk_regmap meson8m2_gp_pll_dco = {
			.width   = 1,
		},
		.table = meson8m2_gp_pll_params_table,
		.init_regs = meson8m2_gp_pll_init_regs,
		.init_count = ARRAY_SIZE(meson8m2_gp_pll_init_regs),
	},
	.hw.init = &(struct clk_init_data){
		.name = "gp_pll_dco",
@@ -2063,7 +2072,7 @@ static struct clk_regmap meson8b_vpu_0 = {
			&meson8b_vpu_0_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
	},
};

@@ -2134,10 +2143,18 @@ static struct clk_regmap meson8b_vpu_1 = {
			&meson8b_vpu_1_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
	},
};

/*
 * The VPU clock has two two identical clock trees (vpu_0 and vpu_1)
 * muxed by a glitch-free switch on Meson8b and Meson8m2. The CCF can
 * actually manage this glitch-free mux because it does top-to-bottom
 * updates the each clock tree and switches to the "inactive" one when
 * CLK_SET_RATE_GATE is set.
 * Meson8 only has vpu_0 and no glitch-free mux.
 */
static struct clk_regmap meson8b_vpu = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VPU_CLK_CNTL,
@@ -2152,7 +2169,7 @@ static struct clk_regmap meson8b_vpu = {
			&meson8b_vpu_1.hw,
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_NO_REPARENT,
		.flags = CLK_SET_RATE_PARENT,
	},
};

@@ -3506,54 +3523,87 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
static const struct meson8b_clk_reset_line {
	u32 reg;
	u8 bit_idx;
	bool active_low;
} meson8b_clk_reset_bits[] = {
	[CLKC_RESET_L2_CACHE_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 30,
		.active_low = false,
	},
	[CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 29,
		.active_low = false,
	},
	[CLKC_RESET_SCU_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 28,
		.active_low = false,
	},
	[CLKC_RESET_CPU3_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 27,
		.active_low = false,
	},
	[CLKC_RESET_CPU2_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 26,
		.active_low = false,
	},
	[CLKC_RESET_CPU1_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 25,
		.active_low = false,
	},
	[CLKC_RESET_CPU0_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 24,
		.active_low = false,
	},
	[CLKC_RESET_A5_GLOBAL_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 18,
		.active_low = false,
	},
	[CLKC_RESET_A5_AXI_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 17,
		.active_low = false,
	},
	[CLKC_RESET_A5_ABP_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
		.reg = HHI_SYS_CPU_CLK_CNTL0,
		.bit_idx = 16,
		.active_low = false,
	},
	[CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
		.reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
		.reg = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 30,
		.active_low = false,
	},
	[CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = {
		.reg = HHI_VID_CLK_CNTL, .bit_idx = 15
		.reg = HHI_VID_CLK_CNTL,
		.bit_idx = 15,
		.active_low = false,
	},
	[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
		.reg = HHI_VID_DIVIDER_CNTL,
		.bit_idx = 7,
		.active_low = false,
	},
	[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
		.reg = HHI_VID_DIVIDER_CNTL,
		.bit_idx = 3,
		.active_low = false,
	},
	[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = {
		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
		.reg = HHI_VID_DIVIDER_CNTL,
		.bit_idx = 1,
		.active_low = true,
	},
	[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = {
		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
		.reg = HHI_VID_DIVIDER_CNTL,
		.bit_idx = 0,
		.active_low = true,
	},
};

@@ -3562,22 +3612,22 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
{
	struct meson8b_clk_reset *meson8b_clk_reset =
		container_of(rcdev, struct meson8b_clk_reset, reset);
	unsigned long flags;
	const struct meson8b_clk_reset_line *reset;
	unsigned int value = 0;
	unsigned long flags;

	if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
		return -EINVAL;

	reset = &meson8b_clk_reset_bits[id];

	if (assert != reset->active_low)
		value = BIT(reset->bit_idx);

	spin_lock_irqsave(&meson_clk_lock, flags);

	if (assert)
		regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
				   BIT(reset->bit_idx), BIT(reset->bit_idx));
	else
	regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
				   BIT(reset->bit_idx), 0);
			   BIT(reset->bit_idx), value);

	spin_unlock_irqrestore(&meson_clk_lock, flags);

+4 −1
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@
 * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
 */
#define HHI_GP_PLL_CNTL			0x40  /* 0x10 offset in data sheet */
#define HHI_GP_PLL_CNTL2		0x44  /* 0x11 offset in data sheet */
#define HHI_GP_PLL_CNTL3		0x48  /* 0x12 offset in data sheet */
#define HHI_GP_PLL_CNTL4		0x4C  /* 0x13 offset in data sheet */
#define HHI_GP_PLL_CNTL5		0x50  /* 0x14 offset in data sheet */
#define HHI_VIID_CLK_DIV		0x128 /* 0x4a offset in data sheet */
#define HHI_VIID_CLK_CNTL		0x12c /* 0x4b offset in data sheet */
#define HHI_GCLK_MPEG0			0x140 /* 0x50 offset in data sheet */
@@ -146,7 +150,6 @@
#define CLKID_CTS_VDAC0		171
#define CLKID_HDMI_SYS_SEL	172
#define CLKID_HDMI_SYS_DIV	173
#define CLKID_HDMI_SYS		174
#define CLKID_MALI_0_SEL	175
#define CLKID_MALI_0_DIV	176
#define CLKID_MALI_0		177
+1 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@
#define CLKID_PERIPH		126
#define CLKID_AXI		128
#define CLKID_L2_DRAM		130
#define CLKID_HDMI_SYS		174
#define CLKID_VPU		190
#define CLKID_VDEC_1		196
#define CLKID_VDEC_HCODEC	199