linux-phy.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate
@ 2025-05-04 20:40 Adam Ford
  2025-05-04 20:40 ` [PATCH 2/3] phy: freescale: fsl-samsung-hdmi: Refactor finding PHY settings Adam Ford
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Adam Ford @ 2025-05-04 20:40 UTC (permalink / raw)
  To: linux-phy
  Cc: dominique.martinet, frieder.schrempf, u.kleine-koenig, aford,
	Adam Ford, Vinod Koul, Kishon Vijay Abraham I, linux-kernel

phy_clk_round_rate sounds like a generic helper function.  In
reality, it is unique to the phy-fsl-samsung-hdmi. Rename
phy_clk_round_rate to fsl_samsung_hdmi_phy_clk_round_rate.
No functional change intended.

Suggested-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Signed-off-by: Adam Ford <aford173@gmail.com>

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 10fbe8dee116..40f33e5ac6f5 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -531,8 +531,8 @@ static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
 	return frac_div_clk;
 }
 
-static long phy_clk_round_rate(struct clk_hw *hw,
-			       unsigned long rate, unsigned long *parent_rate)
+static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw,
+						unsigned long rate, unsigned long *parent_rate)
 {
 	const struct phy_config *fract_div_phy;
 	u32 int_div_clk;
@@ -616,7 +616,7 @@ static int phy_clk_set_rate(struct clk_hw *hw,
 
 static const struct clk_ops phy_clk_ops = {
 	.recalc_rate = phy_clk_recalc_rate,
-	.round_rate = phy_clk_round_rate,
+	.round_rate = fsl_samsung_hdmi_phy_clk_round_rate,
 	.set_rate = phy_clk_set_rate,
 };
 
-- 
2.48.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] phy: freescale: fsl-samsung-hdmi: Refactor finding PHY settings
  2025-05-04 20:40 [PATCH 1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate Adam Ford
@ 2025-05-04 20:40 ` Adam Ford
  2025-05-04 20:40 ` [PATCH 3/3] phy: freescale: fsl-samsung-hdmi: Improve LUT search for best clock Adam Ford
  2025-05-14 11:37 ` [PATCH 1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Adam Ford @ 2025-05-04 20:40 UTC (permalink / raw)
  To: linux-phy
  Cc: dominique.martinet, frieder.schrempf, u.kleine-koenig, aford,
	Adam Ford, Vinod Koul, Kishon Vijay Abraham I, linux-kernel

There are two functions, round_rate and set_rate that duplicate
a lot of the same work, so simplify the code by creating a helper
function that will identify the phy settings for a desired clock
rate and return the structure with the corresponding settings.
From this structure, the round_rate and set_rate can both get what
they need to achieve the clock setting closest to the desired rate
as possible while minimizing the duplicated code.

Also rename phy_clk_set_rate to fsl_samsung_hdmi_phy_clk_set_rate.

Suggested-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Signed-off-by: Adam Ford <aford173@gmail.com>

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 40f33e5ac6f5..a081f07681db 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -456,6 +456,8 @@ static int fsl_samsung_hdmi_phy_configure(struct fsl_samsung_hdmi_phy *phy,
 	int i, ret;
 	u8 val;
 
+	phy->cur_cfg = cfg;
+
 	/* HDMI PHY init */
 	writeb(REG33_FIX_DA, phy->regs + PHY_REG(33));
 
@@ -521,18 +523,9 @@ static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned
 	/* pll_div_regs 3-6 are fixed and pre-defined already */
 }
 
-static u32 fsl_samsung_hdmi_phy_get_closest_rate(unsigned long rate,
-						 u32 int_div_clk, u32 frac_div_clk)
-{
-	/* Calculate the absolute value of the differences and return whichever is closest */
-	if (abs((long)rate - (long)int_div_clk) < abs((long)(rate - (long)frac_div_clk)))
-		return int_div_clk;
-
-	return frac_div_clk;
-}
-
-static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw,
-						unsigned long rate, unsigned long *parent_rate)
+static
+const struct phy_config *fsl_samsung_hdmi_phy_find_settings(struct fsl_samsung_hdmi_phy *phy,
+							    unsigned long rate)
 {
 	const struct phy_config *fract_div_phy;
 	u32 int_div_clk;
@@ -541,83 +534,66 @@ static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw,
 
 	/* If the clock is out of range return error instead of searching */
 	if (rate > 297000000 || rate < 22250000)
-		return -EINVAL;
+		return NULL;
 
 	/* Search the fractional divider lookup table */
 	fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
+	if (fract_div_phy->pixclk == rate) {
+		dev_dbg(phy->dev, "fractional divider match = %u\n", fract_div_phy->pixclk);
+		return fract_div_phy;
+	}
 
-	/* If the rate is an exact match, return that value */
-	if (rate == fract_div_phy->pixclk)
-		return fract_div_phy->pixclk;
-
-	/* If the exact match isn't found, calculate the integer divider */
+	/* Calculate the integer divider */
 	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
+	fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
+	if (int_div_clk == rate) {
+		dev_dbg(phy->dev, "integer divider match = %u\n", calculated_phy_pll_cfg.pixclk);
+		return &calculated_phy_pll_cfg;
+	}
 
-	/* If the int_div_clk rate is an exact match, return that value */
-	if (int_div_clk == rate)
-		return int_div_clk;
+	/* Calculate the absolute value of the differences and return whichever is closest */
+	if (abs((long)rate - (long)int_div_clk) <
+	    abs((long)rate - (long)fract_div_phy->pixclk)) {
+		dev_dbg(phy->dev, "integer divider = %u\n", calculated_phy_pll_cfg.pixclk);
+		return &calculated_phy_pll_cfg;
+	}
 
-	/* If neither rate is an exact match, use the value from the LUT */
-	return fract_div_phy->pixclk;
-}
+	dev_dbg(phy->dev, "fractional divider = %u\n", phy->cur_cfg->pixclk);
 
-static int phy_use_fract_div(struct fsl_samsung_hdmi_phy *phy, const struct phy_config *fract_div_phy)
-{
-	phy->cur_cfg = fract_div_phy;
-	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: using fractional divider rate = %u\n",
-		phy->cur_cfg->pixclk);
-	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+	return fract_div_phy;
 }
 
-static int phy_use_integer_div(struct fsl_samsung_hdmi_phy *phy,
-			       const struct phy_config *int_div_clk)
+static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw,
+						unsigned long rate, unsigned long *parent_rate)
 {
-	phy->cur_cfg  = &calculated_phy_pll_cfg;
-	dev_dbg(phy->dev, "fsl_samsung_hdmi_phy: integer divider rate = %u\n",
-		phy->cur_cfg->pixclk);
-	return fsl_samsung_hdmi_phy_configure(phy, phy->cur_cfg);
+	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
+	const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, rate);
+
+	if (target_settings == NULL)
+		return -EINVAL;
+
+	dev_dbg(phy->dev, "round_rate, closest rate = %u\n", target_settings->pixclk);
+	return target_settings->pixclk;
 }
 
-static int phy_clk_set_rate(struct clk_hw *hw,
+static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw,
 			    unsigned long rate, unsigned long parent_rate)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
-	const struct phy_config *fract_div_phy;
-	u32 int_div_clk;
-	u16 m;
-	u8 p, s;
-
-	/* Search the fractional divider lookup table */
-	fract_div_phy = fsl_samsung_hdmi_phy_lookup_rate(rate);
+	const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, rate);
 
-	/* If the rate is an exact match, use that value */
-	if (fract_div_phy->pixclk == rate)
-		return phy_use_fract_div(phy, fract_div_phy);
+	if (target_settings == NULL)
+		return -EINVAL;
 
-	/*
-	 * If the rate from the fractional divider is not exact, check the integer divider,
-	 * and use it if that value is an exact match.
-	 */
-	int_div_clk = fsl_samsung_hdmi_phy_find_pms(rate, &p, &m, &s);
-	fsl_samsung_hdmi_calculate_phy(&calculated_phy_pll_cfg, int_div_clk, p, m, s);
-	if (int_div_clk == rate)
-		return phy_use_integer_div(phy, &calculated_phy_pll_cfg);
+	dev_dbg(phy->dev,  "set_rate, closest rate = %u\n", target_settings->pixclk);
 
-	/*
-	 * Compare the difference between the integer clock and the fractional clock against
-	 * the desired clock and which whichever is closest.
-	 */
-	if (fsl_samsung_hdmi_phy_get_closest_rate(rate, int_div_clk,
-						  fract_div_phy->pixclk) == fract_div_phy->pixclk)
-		return phy_use_fract_div(phy, fract_div_phy);
-	else
-		return phy_use_integer_div(phy, &calculated_phy_pll_cfg);
+	return fsl_samsung_hdmi_phy_configure(phy, target_settings);
 }
 
 static const struct clk_ops phy_clk_ops = {
 	.recalc_rate = phy_clk_recalc_rate,
 	.round_rate = fsl_samsung_hdmi_phy_clk_round_rate,
-	.set_rate = phy_clk_set_rate,
+	.set_rate = fsl_samsung_hdmi_phy_clk_set_rate,
 };
 
 static int phy_clk_register(struct fsl_samsung_hdmi_phy *phy)
-- 
2.48.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] phy: freescale: fsl-samsung-hdmi: Improve LUT search for best clock
  2025-05-04 20:40 [PATCH 1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate Adam Ford
  2025-05-04 20:40 ` [PATCH 2/3] phy: freescale: fsl-samsung-hdmi: Refactor finding PHY settings Adam Ford
@ 2025-05-04 20:40 ` Adam Ford
  2025-05-14 11:37 ` [PATCH 1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Adam Ford @ 2025-05-04 20:40 UTC (permalink / raw)
  To: linux-phy
  Cc: dominique.martinet, frieder.schrempf, u.kleine-koenig, aford,
	Adam Ford, Vinod Koul, Kishon Vijay Abraham I, linux-kernel

Searching the look-up-table runs so long as the frequency in the
table is at or below the desired rate.  This works well in most
cases, but the next entry in the LUT might be closer to the
nominal value than the lower one.  Add some logic to check
the higer value is any closer to the nominal value and use it.

Signed-off-by: Adam Ford <aford173@gmail.com>

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index a081f07681db..191c282246d9 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -510,7 +510,14 @@ static const struct phy_config *fsl_samsung_hdmi_phy_lookup_rate(unsigned long r
 		if (phy_pll_cfg[i].pixclk <= rate)
 			break;
 
-	return &phy_pll_cfg[i];
+	/* If there is an exact match, or the array has been searched, return the value*/
+	if (phy_pll_cfg[i].pixclk == rate || i + 1 > ARRAY_SIZE(phy_pll_cfg) - 1)
+		return &phy_pll_cfg[i];
+
+	/* See if the next entry is closer to nominal than this one */
+	return (abs((long) rate - (long) phy_pll_cfg[i].pixclk) <
+		abs((long) rate - (long) phy_pll_cfg[i+1].pixclk) ?
+		&phy_pll_cfg[i] : &phy_pll_cfg[i+1]);
 }
 
 static void fsl_samsung_hdmi_calculate_phy(struct phy_config *cal_phy, unsigned long rate,
-- 
2.48.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate
  2025-05-04 20:40 [PATCH 1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate Adam Ford
  2025-05-04 20:40 ` [PATCH 2/3] phy: freescale: fsl-samsung-hdmi: Refactor finding PHY settings Adam Ford
  2025-05-04 20:40 ` [PATCH 3/3] phy: freescale: fsl-samsung-hdmi: Improve LUT search for best clock Adam Ford
@ 2025-05-14 11:37 ` Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Vinod Koul @ 2025-05-14 11:37 UTC (permalink / raw)
  To: linux-phy, Adam Ford
  Cc: dominique.martinet, frieder.schrempf, u.kleine-koenig, aford,
	Kishon Vijay Abraham I, linux-kernel


On Sun, 04 May 2025 15:40:40 -0500, Adam Ford wrote:
> phy_clk_round_rate sounds like a generic helper function.  In
> reality, it is unique to the phy-fsl-samsung-hdmi. Rename
> phy_clk_round_rate to fsl_samsung_hdmi_phy_clk_round_rate.
> No functional change intended.
> 
> 

Applied, thanks!

[1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate
      commit: be79213b4f9ab6e5abf870b97f8a1cab5bf049b3
[2/3] phy: freescale: fsl-samsung-hdmi: Refactor finding PHY settings
      commit: 41db4623346777be6ce694338b5adc570c4b671d
[3/3] phy: freescale: fsl-samsung-hdmi: Improve LUT search for best clock
      commit: 46a87260fc4f719f58e07a53cc1b70a38d98da37

Best regards,
-- 
~Vinod



-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-05-14 15:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-04 20:40 [PATCH 1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate Adam Ford
2025-05-04 20:40 ` [PATCH 2/3] phy: freescale: fsl-samsung-hdmi: Refactor finding PHY settings Adam Ford
2025-05-04 20:40 ` [PATCH 3/3] phy: freescale: fsl-samsung-hdmi: Improve LUT search for best clock Adam Ford
2025-05-14 11:37 ` [PATCH 1/3] phy: freescale: fsl-samsung-hdmi: Rename phy_clk_round_rate Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).