Message ID | 20230806-pll-mipi_set_rate_parent-v5-10-db4f5ca33fc3@oltmanns.dev (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | clk: sunxi-ng: Consider alternative parent rates when determining NKM clock rate | expand |
Dne nedelja, 06. avgust 2023 ob 15:06:55 CEST je Frank Oltmanns napisal(a): > Selecting the closest rate for pll-video0 instead of the closest rate > that is less than the requested rate has no downside for this clock, > while allowing for selecting a more suitable rate, e.g. for the > connected panels. > > Furthermore, the algorithm that sets an NKM clock's parent benefits from > the closest rate. Without it, the NKM clock's rate might drift away from > the requested rate in the multiple successive calls to > ccu_nkm_determine_rate that the clk framework performs when setting a > clock rate. > > Therefore, configure pll-video0 and, in consequence, all of its > descendents to select the closest rate. > > Acked-by: Maxime Ripard <mripard@kernel.org> > Signed-off-by: Frank Oltmanns <frank@oltmanns.dev> Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com> Best regards, Jernej > --- > drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 33 > ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 > deletions(-) > > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c > b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index a139a5c438d4..73c84d20f3ee > 100644 > --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c > @@ -68,7 +68,7 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, > "pll-audio-base", BIT(28), /* lock */ > CLK_SET_RATE_UNGATE); > > -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, > "pll-video0", +static > SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, > "pll-video0", "osc24M", 0x010, > 192000000, /* Minimum rate */ > 1008000000, /* Maximum rate */ > @@ -181,6 +181,7 @@ static struct ccu_nkm pll_mipi_clk = { > .hw.init = CLK_HW_INIT("pll-mipi", "pll-video0", > &ccu_nkm_ops, > CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT), > + .features = CCU_FEATURE_CLOSEST_RATE, > }, > }; > > @@ -531,24 +532,18 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", > de_parents, > > static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" > }; static const u8 tcon0_table[] = { 0, 2, }; > -static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents, > +static SUNXI_CCU_MUX_TABLE_WITH_GATE_CLOSEST(tcon0_clk, "tcon0", > tcon0_parents, tcon0_table, 0x118, 24, 3, BIT(31), > CLK_SET_RATE_PARENT); > > static const char * const tcon1_parents[] = { "pll-video0", "pll-video1" }; > static const u8 tcon1_table[] = { 0, 2, }; > -static struct ccu_div tcon1_clk = { > - .enable = BIT(31), > - .div = _SUNXI_CCU_DIV(0, 4), > - .mux = _SUNXI_CCU_MUX_TABLE(24, 2, tcon1_table), > - .common = { > - .reg = 0x11c, > - .hw.init = CLK_HW_INIT_PARENTS("tcon1", > - tcon1_parents, > - &ccu_div_ops, > - CLK_SET_RATE_PARENT), > - }, > -}; > +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(tcon1_clk, "tcon1", > tcon1_parents, + tcon1_table, 0x11c, > + 0, 4, /* M */ > + 24, 2, /* mux */ > + BIT(31), /* gate */ > + CLK_SET_RATE_PARENT); > > static const char * const deinterlace_parents[] = { "pll-periph0", > "pll-periph1" }; static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, > "deinterlace", deinterlace_parents, @@ -578,8 +573,8 @@ static > SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x144, BIT(31), 0); > > static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" }; > -static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, > - 0x150, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT); > +static SUNXI_CCU_M_WITH_MUX_GATE_CLOSEST(hdmi_clk, "hdmi", hdmi_parents, > + 0x150, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT); > > static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", > 0x154, BIT(31), 0); > @@ -591,9 +586,9 @@ static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", > mbus_parents, > > static const char * const dsi_dphy_parents[] = { "pll-video0", > "pll-periph0" }; static const u8 dsi_dphy_table[] = { 0, 2, }; > -static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy", > - dsi_dphy_parents, dsi_dphy_table, > - 0x168, 0, 4, 8, 2, BIT(15), CLK_SET_RATE_PARENT); > +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(dsi_dphy_clk, "dsi-dphy", > + dsi_dphy_parents, dsi_dphy_table, > + 0x168, 0, 4, 8, 2, BIT(15), CLK_SET_RATE_PARENT); > > static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", > 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index a139a5c438d4..73c84d20f3ee 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -68,7 +68,7 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", BIT(28), /* lock */ CLK_SET_RATE_UNGATE); -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0", +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, "pll-video0", "osc24M", 0x010, 192000000, /* Minimum rate */ 1008000000, /* Maximum rate */ @@ -181,6 +181,7 @@ static struct ccu_nkm pll_mipi_clk = { .hw.init = CLK_HW_INIT("pll-mipi", "pll-video0", &ccu_nkm_ops, CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT), + .features = CCU_FEATURE_CLOSEST_RATE, }, }; @@ -531,24 +532,18 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" }; static const u8 tcon0_table[] = { 0, 2, }; -static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents, +static SUNXI_CCU_MUX_TABLE_WITH_GATE_CLOSEST(tcon0_clk, "tcon0", tcon0_parents, tcon0_table, 0x118, 24, 3, BIT(31), CLK_SET_RATE_PARENT); static const char * const tcon1_parents[] = { "pll-video0", "pll-video1" }; static const u8 tcon1_table[] = { 0, 2, }; -static struct ccu_div tcon1_clk = { - .enable = BIT(31), - .div = _SUNXI_CCU_DIV(0, 4), - .mux = _SUNXI_CCU_MUX_TABLE(24, 2, tcon1_table), - .common = { - .reg = 0x11c, - .hw.init = CLK_HW_INIT_PARENTS("tcon1", - tcon1_parents, - &ccu_div_ops, - CLK_SET_RATE_PARENT), - }, -}; +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(tcon1_clk, "tcon1", tcon1_parents, + tcon1_table, 0x11c, + 0, 4, /* M */ + 24, 2, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); static const char * const deinterlace_parents[] = { "pll-periph0", "pll-periph1" }; static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace", deinterlace_parents, @@ -578,8 +573,8 @@ static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x144, BIT(31), 0); static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" }; -static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, - 0x150, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT); +static SUNXI_CCU_M_WITH_MUX_GATE_CLOSEST(hdmi_clk, "hdmi", hdmi_parents, + 0x150, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT); static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x154, BIT(31), 0); @@ -591,9 +586,9 @@ static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, static const char * const dsi_dphy_parents[] = { "pll-video0", "pll-periph0" }; static const u8 dsi_dphy_table[] = { 0, 2, }; -static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy", - dsi_dphy_parents, dsi_dphy_table, - 0x168, 0, 4, 8, 2, BIT(15), CLK_SET_RATE_PARENT); +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(dsi_dphy_clk, "dsi-dphy", + dsi_dphy_parents, dsi_dphy_table, + 0x168, 0, 4, 8, 2, BIT(15), CLK_SET_RATE_PARENT); static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);