diff mbox series

[v3,8/8] clk: sunxi-ng: a64: select closest rate for pll-video0

Message ID 20230702-pll-mipi_set_rate_parent-v3-8-46dcb8aa9cbc@oltmanns.dev (mailing list archive)
State Superseded, archived
Headers show
Series clk: sunxi-ng: Consider alternative parent rates when determining NKM clock rate | expand

Commit Message

Frank Oltmanns July 2, 2023, 5:55 p.m. UTC
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.

Signed-off-by: Frank Oltmanns <frank@oltmanns.dev>
---
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

Comments

Maxime Ripard July 3, 2023, 7:50 a.m. UTC | #1
On Sun, Jul 02, 2023 at 07:55:27PM +0200, Frank Oltmanns wrote:
> @@ -541,7 +542,7 @@ 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),
> +	.div		= _SUNXI_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ROUND_CLOSEST),
>  	.mux		= _SUNXI_CCU_MUX_TABLE(24, 2, tcon1_table),
>  	.common		= {
>  		.reg		= 0x11c,
> @@ -549,6 +550,7 @@ static struct ccu_div tcon1_clk = {
>  						      tcon1_parents,
>  						      &ccu_div_ops,
>  						      CLK_SET_RATE_PARENT),
> +		.features	= CCU_FEATURE_CLOSEST_RATE,
>  	},
>  };

I'm not super comfortable with having to set it twice for dividers (or
composite clocks). Could we set CLK_DIVIDER_ROUND_CLOSEST automatically
if CCU_FEATURE_CLOSEST_RATE is set?

I'm guessing we would need it for muxes as well?

Maxime
Frank Oltmanns July 3, 2023, 9:28 a.m. UTC | #2
On 2023-07-03 at 09:50:05 +0200, Maxime Ripard <maxime@cerno.tech> wrote:
> [[PGP Signed Part:Undecided]]
> On Sun, Jul 02, 2023 at 07:55:27PM +0200, Frank Oltmanns wrote:
>> @@ -541,7 +542,7 @@ 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),
>> +	.div		= _SUNXI_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ROUND_CLOSEST),
>>  	.mux		= _SUNXI_CCU_MUX_TABLE(24, 2, tcon1_table),
>>  	.common		= {
>>  		.reg		= 0x11c,
>> @@ -549,6 +550,7 @@ static struct ccu_div tcon1_clk = {
>>  						      tcon1_parents,
>>  						      &ccu_div_ops,
>>  						      CLK_SET_RATE_PARENT),
>> +		.features	= CCU_FEATURE_CLOSEST_RATE,
>>  	},
>>  };
>
> I'm not super comfortable with having to set it twice for dividers (or
> composite clocks). Could we set CLK_DIVIDER_ROUND_CLOSEST automatically
> if CCU_FEATURE_CLOSEST_RATE is set?

You're of course right. If I'm not mistaken, I can use
SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST that I introduced in div patch
(PATCH 7). Otherwise I'll create a similar macro for use with tcon1.

>
> I'm guessing we would need it for muxes as well?
>

Yes, it's already in the mux and div patches.

Best regards,
  Frank

>
> Maxime
>
> [[End of PGP Signed Part]]
diff mbox series

Patch

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index ebfab1fdbb96..016432ff3bde 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -81,7 +81,7 @@  static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
 						BIT(31),	/* gate */
 						BIT(28),	/* lock */
 						CLK_SET_RATE_UNGATE,
-						0);		/* features */
+						CCU_FEATURE_CLOSEST_RATE);
 
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
 					"osc24M", 0x018,
@@ -183,6 +183,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,
 	},
 };
 
@@ -533,7 +534,7 @@  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);
 
@@ -541,7 +542,7 @@  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),
+	.div		= _SUNXI_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ROUND_CLOSEST),
 	.mux		= _SUNXI_CCU_MUX_TABLE(24, 2, tcon1_table),
 	.common		= {
 		.reg		= 0x11c,
@@ -549,6 +550,7 @@  static struct ccu_div tcon1_clk = {
 						      tcon1_parents,
 						      &ccu_div_ops,
 						      CLK_SET_RATE_PARENT),
+		.features	= CCU_FEATURE_CLOSEST_RATE,
 	},
 };
 
@@ -580,8 +582,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);
@@ -593,9 +595,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);