Re: [PATCH 4/6] clk: actions: Fix AHPPREDIV-H-AHB clock chain on Owl S500 SoC
From: Manivannan Sadhasivam <hidden>
Date: 2021-03-16 05:46:49
Also in:
linux-arm-kernel, linux-clk, lkml
On Mon, Mar 08, 2021 at 07:18:29PM +0200, Cristian Ciocaltea wrote:
There are a few issues with the setup of the Actions Semi Owl S500 SoC's clock chain involving AHPPREDIV, H and AHB clocks: * AHBPREDIV clock is defined as a muxer only, although it also acts as a divider. * H clock is defined as a standard divider, although the raw value zero is not supported.
What do you mean by not supported? The datasheet lists "0" as the valid divisor value for divide by 1. Rest looks good to me. Thanks, Mani
quoted hunk ↗ jump to hunk
* AHB is defined as a multi-rate factor clock, but it is actually just a fixed pass clock. Let's provide the following fixes: * Change AHBPREDIV clock to an ungated OWL_COMP_DIV definition. * Add a clock div table 'h_div_table' for the H clock to drop the unsupported 0 rate and use the correct register shift value in the OWL_DIVIDER definition. * Drop the unneeded 'ahb_factor_table[]' and change AHB clock to an ungated OWL_COMP_FIXED_FACTOR definition. Fixes: ed6b4795ece4 ("clk: actions: Add clock driver for S500 SoC") Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@gmail.com> --- drivers/clk/actions/owl-s500.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c index abe8874353de..b9e434173b4f 100644 --- a/drivers/clk/actions/owl-s500.c +++ b/drivers/clk/actions/owl-s500.c@@ -151,9 +151,9 @@ static struct clk_factor_table hde_factor_table[] = { { 0, 0, 0 }, }; -static struct clk_factor_table ahb_factor_table[] = { - { 1, 1, 2 }, { 2, 1, 3 }, - { 0, 0, 0 }, +static struct clk_div_table h_div_table[] = { + { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 0, 0 }, }; static struct clk_div_table rmii_ref_div_table[] = {@@ -184,7 +184,6 @@ static struct clk_div_table nand_div_table[] = { /* mux clock */ static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT); -static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT); /* gate clocks */ static OWL_GATE(gpio_clk, "gpio_clk", "apb_clk", CMU_DEVCLKEN0, 18, 0, 0);@@ -197,16 +196,25 @@ static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0); static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0); /* divider clocks */ -static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0); +static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 2, 2, h_div_table, 0, 0); static OWL_DIVIDER(apb_clk, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0); static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0); /* factor clocks */ -static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0); static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 4, de_factor_table, 0, 0); static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 4, de_factor_table, 0, 0); /* composite clocks */ +static OWL_COMP_DIV(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, + OWL_MUX_HW(CMU_BUSCLK1, 8, 3), + { 0 }, + OWL_DIVIDER_HW(CMU_BUSCLK1, 12, 2, 0, NULL), + 0); + +static OWL_COMP_FIXED_FACTOR(ahb_clk, "ahb_clk", "h_clk", + { 0 }, + 1, 1, CLK_SET_RATE_PARENT); + static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p, OWL_MUX_HW(CMU_VCECLK, 4, 2), OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0),-- 2.30.1