mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] staging: sm750fb: clean up PLL calculation code
@ 2026-10-24  7:35 himanshu bakshi
  2026-10-24  8:02 ` Greg KH
  0 siblings, 1 reply; 3+ messages in thread
From: himanshu bakshi @ 2026-10-24  7:35 UTC (permalink / raw)
  To: sudipm.mukherjee
  Cc: teddy.wang, gregkh, linux-fbdev, linux-staging, linux-kernel,
	Himanshu Bakshi

From: Himanshu Bakshi <himanshu.bakshi478@gmail.com>

Improve the PLL calculation function's documentation and
readability.

Simplify candidate selection by skipping candidates that do
not improve the frequency error, and defer updating the PLL
parameters until the best candidate has been selected.

Signed-off-by: Himanshu Bakshi <himanshu.bakshi478@gmail.com>
---
 drivers/staging/sm750fb/ddk750_chip.c | 84 +++++++++++++++++----------
 1 file changed, 54 insertions(+), 30 deletions(-)

diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c
index aa78d0bc1..74ce320b6 100644
--- a/drivers/staging/sm750fb/ddk750_chip.c
+++ b/drivers/staging/sm750fb/ddk750_chip.c
@@ -269,21 +269,18 @@ int ddk750_init_hw(struct initchip_param *p_init_param)
 }
 
 /*
- * monk liu @ 4/6/2011:
- *	re-write the calculatePLL function of ddk750.
- *	the original version function does not use
- *	some mathematics tricks and shortcut
- *	when it doing the calculation of the best N,M,D combination
- *	I think this version gives a little upgrade in speed
+ * Calculate the PLL parameters that produce the clock frequency
+ * closest to the requested frequency.
  *
- * 750 pll clock formular:
- * Request Clock = (Input Clock * M )/(N * X)
+ * The SM750 PLL uses the following formula:
  *
- * Input Clock = 14318181 hz
- * X = 2 power D
- * D ={0,1,2,3,4,5,6}
- * M = {1,...,255}
- * N = {2,...,15}
+ *     request_clock = (input_clock * M) / (N * 2^D)
+ *
+ * M ranges from 1 to 255, N from 2 to 15, and D from 0 to 6.
+ * The selected parameters minimize the difference between the
+ * resulting clock frequency and the requested frequency.
+ *
+ * Original implementation by Monk Liu @ 4/6/2011.
  */
 unsigned int sm750_calc_pll_value(unsigned int request_orig,
 				  struct pll_value *pll)
@@ -293,12 +290,15 @@ unsigned int sm750_calc_pll_value(unsigned int request_orig,
 	 * N located in 2,15 and M located in 1,255
 	 */
 	int N, M, X, d;
+	unsigned long N_best, M_best, POD_best, OD_best;
+	unsigned int diff;
 	int mini_diff;
 	unsigned int RN, quo, rem, fl_quo;
 	unsigned int input, request;
 	unsigned int tmp_clock, ret;
 	const int max_OD = 3;
 	int max_d = 6;
+	bool found_best = false;
 
 	if (sm750_get_chip_type() == SM750LE) {
 		/*
@@ -335,26 +335,50 @@ unsigned int sm750_calc_pll_value(unsigned int request_orig,
 			X = BIT(d);
 			M = quo * X;
 			M += fl_quo * X / 10000;
+
 			/* round step */
-			M += (fl_quo * X % 10000) > 5000 ? 1 : 0;
-			if (M < 256 && M > 0) {
-				unsigned int diff;
-
-				tmp_clock = pll->input_freq * M / N / X;
-				diff = abs(tmp_clock - request_orig);
-				if (diff < mini_diff) {
-					pll->M = M;
-					pll->N = N;
-					pll->POD = 0;
-					if (d > max_OD)
-						pll->POD = d - max_OD;
-					pll->OD = d - pll->POD;
-					mini_diff = diff;
-					ret = tmp_clock;
-				}
-			}
+			if ((fl_quo * X % 10000) > 5000)
+				M++;
+
+			/* Reject M values outside the supported range. */
+			if (M >= 256 || M <= 0)
+				continue;
+
+			/* Calculate the resulting clock frequency. */
+			tmp_clock = pll->input_freq * M / N / X;
+			diff = abs(tmp_clock - request_orig);
+
+			/*
+			 * Skip candidates that do not
+			 * improve the frequency error.
+			 */
+			if (diff >= mini_diff)
+				continue;
+
+			/* Update the best PLL parameters. */
+			M_best = M;
+			N_best = N;
+			POD_best = 0;
+
+			if (d > max_OD)
+				POD_best = d - max_OD;
+
+			OD_best = d - POD_best;
+			mini_diff = diff;
+			ret = tmp_clock;
+
+			found_best = true;
 		}
 	}
+
+	/* Apply the best PLL parameters if a valid candidate was found. */
+	if (found_best) {
+		pll->M = M_best;
+		pll->N = N_best;
+		pll->POD = POD_best;
+		pll->OD = OD_best;
+	}
+
 	return ret;
 }
 
-- 
2.56.0


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

* Re: [PATCH] staging: sm750fb: clean up PLL calculation code
  2026-10-24  7:35 [PATCH] staging: sm750fb: clean up PLL calculation code himanshu bakshi
@ 2026-10-24  8:02 ` Greg KH
  2026-10-24 11:50   ` Himanshu Bakshi
  0 siblings, 1 reply; 3+ messages in thread
From: Greg KH @ 2026-10-24  8:02 UTC (permalink / raw)
  To: himanshu bakshi
  Cc: sudipm.mukherjee, teddy.wang, linux-fbdev, linux-staging, linux-kernel

On Sat, Oct 24, 2026 at 01:05:49PM +0530, himanshu bakshi wrote:
> From: Himanshu Bakshi <himanshu.bakshi478@gmail.com>
> 
> Improve the PLL calculation function's documentation and
> readability.
> 
> Simplify candidate selection by skipping candidates that do
> not improve the frequency error, and defer updating the PLL
> parameters until the best candidate has been selected.

How was this found and tested?

thanks,

greg k-h

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

* Re: [PATCH] staging: sm750fb: clean up PLL calculation code
  2026-10-24  8:02 ` Greg KH
@ 2026-10-24 11:50   ` Himanshu Bakshi
  0 siblings, 0 replies; 3+ messages in thread
From: Himanshu Bakshi @ 2026-10-24 11:50 UTC (permalink / raw)
  To: Greg KH
  Cc: sudipm.mukherjee, teddy.wang, linux-fbdev, linux-staging, linux-kernel

Hi Greg,

I found this while reviewing sm750_calc_pll_value() and looking for a
cleaner way to handle the PLL candidate calculation.

I tested the change as follows:

Built the sm750fb driver successfully using make -j2
M=drivers/staging/sm750fb W=1.

Ran a standalone C differential regression test comparing the original
and modified algorithms across 2,010,084 test cases, including
frequency sweeps, boundary values, and randomized requests.

Compared the return values and resulting PLL fields. All tested cases matched.

The differential test uses standalone copies of the original and
modified algorithms rather than executing the function inside the
kernel, so it verifies that the two implementations behave identically
over the tested inputs. I have not tested this on physical SM750
hardware. If by any chance you would like to see the test c file, let
me know.

Thanks and Regards,
Himanshu Bakshi


On Sat, Oct 24, 2026 at 1:32 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Sat, Oct 24, 2026 at 01:05:49PM +0530, himanshu bakshi wrote:
> > From: Himanshu Bakshi <himanshu.bakshi478@gmail.com>
> >
> > Improve the PLL calculation function's documentation and
> > readability.
> >
> > Simplify candidate selection by skipping candidates that do
> > not improve the frequency error, and defer updating the PLL
> > parameters until the best candidate has been selected.
>
> How was this found and tested?
>
> thanks,
>
> greg k-h

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

end of thread, other threads:[~2026-10-24 11:50 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-24  7:35 [PATCH] staging: sm750fb: clean up PLL calculation code himanshu bakshi
2026-10-24  8:02 ` Greg KH
2026-10-24 11:50   ` Himanshu Bakshi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®