162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * OMAP2/3/4 DPLL clock functions
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2005-2008 Texas Instruments, Inc.
662306a36Sopenharmony_ci * Copyright (C) 2004-2010 Nokia Corporation
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Contacts:
962306a36Sopenharmony_ci * Richard Woodruff <r-woodruff2@ti.com>
1062306a36Sopenharmony_ci * Paul Walmsley
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci#undef DEBUG
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/kernel.h>
1562306a36Sopenharmony_ci#include <linux/errno.h>
1662306a36Sopenharmony_ci#include <linux/clk.h>
1762306a36Sopenharmony_ci#include <linux/clk-provider.h>
1862306a36Sopenharmony_ci#include <linux/io.h>
1962306a36Sopenharmony_ci#include <linux/clk/ti.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#include <asm/div64.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include "clock.h"
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/* DPLL rate rounding: minimum DPLL multiplier, divider values */
2662306a36Sopenharmony_ci#define DPLL_MIN_MULTIPLIER		2
2762306a36Sopenharmony_ci#define DPLL_MIN_DIVIDER		1
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/* Possible error results from _dpll_test_mult */
3062306a36Sopenharmony_ci#define DPLL_MULT_UNDERFLOW		-1
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/*
3362306a36Sopenharmony_ci * Scale factor to mitigate roundoff errors in DPLL rate rounding.
3462306a36Sopenharmony_ci * The higher the scale factor, the greater the risk of arithmetic overflow,
3562306a36Sopenharmony_ci * but the closer the rounded rate to the target rate.  DPLL_SCALE_FACTOR
3662306a36Sopenharmony_ci * must be a power of DPLL_SCALE_BASE.
3762306a36Sopenharmony_ci */
3862306a36Sopenharmony_ci#define DPLL_SCALE_FACTOR		64
3962306a36Sopenharmony_ci#define DPLL_SCALE_BASE			2
4062306a36Sopenharmony_ci#define DPLL_ROUNDING_VAL		((DPLL_SCALE_BASE / 2) * \
4162306a36Sopenharmony_ci					 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci/*
4462306a36Sopenharmony_ci * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx.
4562306a36Sopenharmony_ci * From device data manual section 4.3 "DPLL and DLL Specifications".
4662306a36Sopenharmony_ci */
4762306a36Sopenharmony_ci#define OMAP3PLUS_DPLL_FINT_JTYPE_MIN	500000
4862306a36Sopenharmony_ci#define OMAP3PLUS_DPLL_FINT_JTYPE_MAX	2500000
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/* _dpll_test_fint() return codes */
5162306a36Sopenharmony_ci#define DPLL_FINT_UNDERFLOW		-1
5262306a36Sopenharmony_ci#define DPLL_FINT_INVALID		-2
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* Private functions */
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/*
5762306a36Sopenharmony_ci * _dpll_test_fint - test whether an Fint value is valid for the DPLL
5862306a36Sopenharmony_ci * @clk: DPLL struct clk to test
5962306a36Sopenharmony_ci * @n: divider value (N) to test
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci * Tests whether a particular divider @n will result in a valid DPLL
6262306a36Sopenharmony_ci * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
6362306a36Sopenharmony_ci * Correction".  Returns 0 if OK, -1 if the enclosing loop can terminate
6462306a36Sopenharmony_ci * (assuming that it is counting N upwards), or -2 if the enclosing loop
6562306a36Sopenharmony_ci * should skip to the next iteration (again assuming N is increasing).
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_cistatic int _dpll_test_fint(struct clk_hw_omap *clk, unsigned int n)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	struct dpll_data *dd;
7062306a36Sopenharmony_ci	long fint, fint_min, fint_max;
7162306a36Sopenharmony_ci	int ret = 0;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	dd = clk->dpll_data;
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	/* DPLL divider must result in a valid jitter correction val */
7662306a36Sopenharmony_ci	fint = clk_hw_get_rate(clk_hw_get_parent(&clk->hw)) / n;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	if (dd->flags & DPLL_J_TYPE) {
7962306a36Sopenharmony_ci		fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN;
8062306a36Sopenharmony_ci		fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX;
8162306a36Sopenharmony_ci	} else {
8262306a36Sopenharmony_ci		fint_min = ti_clk_get_features()->fint_min;
8362306a36Sopenharmony_ci		fint_max = ti_clk_get_features()->fint_max;
8462306a36Sopenharmony_ci	}
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	if (!fint_min || !fint_max) {
8762306a36Sopenharmony_ci		WARN(1, "No fint limits available!\n");
8862306a36Sopenharmony_ci		return DPLL_FINT_INVALID;
8962306a36Sopenharmony_ci	}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	if (fint < ti_clk_get_features()->fint_min) {
9262306a36Sopenharmony_ci		pr_debug("rejecting n=%d due to Fint failure, lowering max_divider\n",
9362306a36Sopenharmony_ci			 n);
9462306a36Sopenharmony_ci		dd->max_divider = n;
9562306a36Sopenharmony_ci		ret = DPLL_FINT_UNDERFLOW;
9662306a36Sopenharmony_ci	} else if (fint > ti_clk_get_features()->fint_max) {
9762306a36Sopenharmony_ci		pr_debug("rejecting n=%d due to Fint failure, boosting min_divider\n",
9862306a36Sopenharmony_ci			 n);
9962306a36Sopenharmony_ci		dd->min_divider = n;
10062306a36Sopenharmony_ci		ret = DPLL_FINT_INVALID;
10162306a36Sopenharmony_ci	} else if (fint > ti_clk_get_features()->fint_band1_max &&
10262306a36Sopenharmony_ci		   fint < ti_clk_get_features()->fint_band2_min) {
10362306a36Sopenharmony_ci		pr_debug("rejecting n=%d due to Fint failure\n", n);
10462306a36Sopenharmony_ci		ret = DPLL_FINT_INVALID;
10562306a36Sopenharmony_ci	}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	return ret;
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cistatic unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
11162306a36Sopenharmony_ci					    unsigned int m, unsigned int n)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	unsigned long long num;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	num = (unsigned long long)parent_rate * m;
11662306a36Sopenharmony_ci	do_div(num, n);
11762306a36Sopenharmony_ci	return num;
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/*
12162306a36Sopenharmony_ci * _dpll_test_mult - test a DPLL multiplier value
12262306a36Sopenharmony_ci * @m: pointer to the DPLL m (multiplier) value under test
12362306a36Sopenharmony_ci * @n: current DPLL n (divider) value under test
12462306a36Sopenharmony_ci * @new_rate: pointer to storage for the resulting rounded rate
12562306a36Sopenharmony_ci * @target_rate: the desired DPLL rate
12662306a36Sopenharmony_ci * @parent_rate: the DPLL's parent clock rate
12762306a36Sopenharmony_ci *
12862306a36Sopenharmony_ci * This code tests a DPLL multiplier value, ensuring that the
12962306a36Sopenharmony_ci * resulting rate will not be higher than the target_rate, and that
13062306a36Sopenharmony_ci * the multiplier value itself is valid for the DPLL.  Initially, the
13162306a36Sopenharmony_ci * integer pointed to by the m argument should be prescaled by
13262306a36Sopenharmony_ci * multiplying by DPLL_SCALE_FACTOR.  The code will replace this with
13362306a36Sopenharmony_ci * a non-scaled m upon return.  This non-scaled m will result in a
13462306a36Sopenharmony_ci * new_rate as close as possible to target_rate (but not greater than
13562306a36Sopenharmony_ci * target_rate) given the current (parent_rate, n, prescaled m)
13662306a36Sopenharmony_ci * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
13762306a36Sopenharmony_ci * non-scaled m attempted to underflow, which can allow the calling
13862306a36Sopenharmony_ci * function to bail out early; or 0 upon success.
13962306a36Sopenharmony_ci */
14062306a36Sopenharmony_cistatic int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
14162306a36Sopenharmony_ci			   unsigned long target_rate,
14262306a36Sopenharmony_ci			   unsigned long parent_rate)
14362306a36Sopenharmony_ci{
14462306a36Sopenharmony_ci	int r = 0, carry = 0;
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	/* Unscale m and round if necessary */
14762306a36Sopenharmony_ci	if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
14862306a36Sopenharmony_ci		carry = 1;
14962306a36Sopenharmony_ci	*m = (*m / DPLL_SCALE_FACTOR) + carry;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	/*
15262306a36Sopenharmony_ci	 * The new rate must be <= the target rate to avoid programming
15362306a36Sopenharmony_ci	 * a rate that is impossible for the hardware to handle
15462306a36Sopenharmony_ci	 */
15562306a36Sopenharmony_ci	*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
15662306a36Sopenharmony_ci	if (*new_rate > target_rate) {
15762306a36Sopenharmony_ci		(*m)--;
15862306a36Sopenharmony_ci		*new_rate = 0;
15962306a36Sopenharmony_ci	}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	/* Guard against m underflow */
16262306a36Sopenharmony_ci	if (*m < DPLL_MIN_MULTIPLIER) {
16362306a36Sopenharmony_ci		*m = DPLL_MIN_MULTIPLIER;
16462306a36Sopenharmony_ci		*new_rate = 0;
16562306a36Sopenharmony_ci		r = DPLL_MULT_UNDERFLOW;
16662306a36Sopenharmony_ci	}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	if (*new_rate == 0)
16962306a36Sopenharmony_ci		*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	return r;
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci/**
17562306a36Sopenharmony_ci * _omap2_dpll_is_in_bypass - check if DPLL is in bypass mode or not
17662306a36Sopenharmony_ci * @v: bitfield value of the DPLL enable
17762306a36Sopenharmony_ci *
17862306a36Sopenharmony_ci * Checks given DPLL enable bitfield to see whether the DPLL is in bypass
17962306a36Sopenharmony_ci * mode or not. Returns 1 if the DPLL is in bypass, 0 otherwise.
18062306a36Sopenharmony_ci */
18162306a36Sopenharmony_cistatic int _omap2_dpll_is_in_bypass(u32 v)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	u8 mask, val;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	mask = ti_clk_get_features()->dpll_bypass_vals;
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci	/*
18862306a36Sopenharmony_ci	 * Each set bit in the mask corresponds to a bypass value equal
18962306a36Sopenharmony_ci	 * to the bitshift. Go through each set-bit in the mask and
19062306a36Sopenharmony_ci	 * compare against the given register value.
19162306a36Sopenharmony_ci	 */
19262306a36Sopenharmony_ci	while (mask) {
19362306a36Sopenharmony_ci		val = __ffs(mask);
19462306a36Sopenharmony_ci		mask ^= (1 << val);
19562306a36Sopenharmony_ci		if (v == val)
19662306a36Sopenharmony_ci			return 1;
19762306a36Sopenharmony_ci	}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	return 0;
20062306a36Sopenharmony_ci}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/* Public functions */
20362306a36Sopenharmony_ciu8 omap2_init_dpll_parent(struct clk_hw *hw)
20462306a36Sopenharmony_ci{
20562306a36Sopenharmony_ci	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
20662306a36Sopenharmony_ci	u32 v;
20762306a36Sopenharmony_ci	struct dpll_data *dd;
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	dd = clk->dpll_data;
21062306a36Sopenharmony_ci	if (!dd)
21162306a36Sopenharmony_ci		return -EINVAL;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
21462306a36Sopenharmony_ci	v &= dd->enable_mask;
21562306a36Sopenharmony_ci	v >>= __ffs(dd->enable_mask);
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	/* Reparent the struct clk in case the dpll is in bypass */
21862306a36Sopenharmony_ci	if (_omap2_dpll_is_in_bypass(v))
21962306a36Sopenharmony_ci		return 1;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	return 0;
22262306a36Sopenharmony_ci}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci/**
22562306a36Sopenharmony_ci * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
22662306a36Sopenharmony_ci * @clk: struct clk * of a DPLL
22762306a36Sopenharmony_ci *
22862306a36Sopenharmony_ci * DPLLs can be locked or bypassed - basically, enabled or disabled.
22962306a36Sopenharmony_ci * When locked, the DPLL output depends on the M and N values.  When
23062306a36Sopenharmony_ci * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
23162306a36Sopenharmony_ci * or sys_clk.  Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
23262306a36Sopenharmony_ci * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
23362306a36Sopenharmony_ci * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
23462306a36Sopenharmony_ci * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
23562306a36Sopenharmony_ci * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
23662306a36Sopenharmony_ci * if the clock @clk is not a DPLL.
23762306a36Sopenharmony_ci */
23862306a36Sopenharmony_ciunsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
23962306a36Sopenharmony_ci{
24062306a36Sopenharmony_ci	u64 dpll_clk;
24162306a36Sopenharmony_ci	u32 dpll_mult, dpll_div, v;
24262306a36Sopenharmony_ci	struct dpll_data *dd;
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	dd = clk->dpll_data;
24562306a36Sopenharmony_ci	if (!dd)
24662306a36Sopenharmony_ci		return 0;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	/* Return bypass rate if DPLL is bypassed */
24962306a36Sopenharmony_ci	v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
25062306a36Sopenharmony_ci	v &= dd->enable_mask;
25162306a36Sopenharmony_ci	v >>= __ffs(dd->enable_mask);
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	if (_omap2_dpll_is_in_bypass(v))
25462306a36Sopenharmony_ci		return clk_hw_get_rate(dd->clk_bypass);
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg);
25762306a36Sopenharmony_ci	dpll_mult = v & dd->mult_mask;
25862306a36Sopenharmony_ci	dpll_mult >>= __ffs(dd->mult_mask);
25962306a36Sopenharmony_ci	dpll_div = v & dd->div1_mask;
26062306a36Sopenharmony_ci	dpll_div >>= __ffs(dd->div1_mask);
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	dpll_clk = (u64)clk_hw_get_rate(dd->clk_ref) * dpll_mult;
26362306a36Sopenharmony_ci	do_div(dpll_clk, dpll_div + 1);
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	return dpll_clk;
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci/* DPLL rate rounding code */
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci/**
27162306a36Sopenharmony_ci * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
27262306a36Sopenharmony_ci * @hw: struct clk_hw containing the struct clk * for a DPLL
27362306a36Sopenharmony_ci * @target_rate: desired DPLL clock rate
27462306a36Sopenharmony_ci * @parent_rate: parent's DPLL clock rate
27562306a36Sopenharmony_ci *
27662306a36Sopenharmony_ci * Given a DPLL and a desired target rate, round the target rate to a
27762306a36Sopenharmony_ci * possible, programmable rate for this DPLL.  Attempts to select the
27862306a36Sopenharmony_ci * minimum possible n.  Stores the computed (m, n) in the DPLL's
27962306a36Sopenharmony_ci * dpll_data structure so set_rate() will not need to call this
28062306a36Sopenharmony_ci * (expensive) function again.  Returns ~0 if the target rate cannot
28162306a36Sopenharmony_ci * be rounded, or the rounded rate upon success.
28262306a36Sopenharmony_ci */
28362306a36Sopenharmony_cilong omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
28462306a36Sopenharmony_ci			   unsigned long *parent_rate)
28562306a36Sopenharmony_ci{
28662306a36Sopenharmony_ci	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
28762306a36Sopenharmony_ci	int m, n, r, scaled_max_m;
28862306a36Sopenharmony_ci	int min_delta_m = INT_MAX, min_delta_n = INT_MAX;
28962306a36Sopenharmony_ci	unsigned long scaled_rt_rp;
29062306a36Sopenharmony_ci	unsigned long new_rate = 0;
29162306a36Sopenharmony_ci	struct dpll_data *dd;
29262306a36Sopenharmony_ci	unsigned long ref_rate;
29362306a36Sopenharmony_ci	long delta;
29462306a36Sopenharmony_ci	long prev_min_delta = LONG_MAX;
29562306a36Sopenharmony_ci	const char *clk_name;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	if (!clk || !clk->dpll_data)
29862306a36Sopenharmony_ci		return ~0;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	dd = clk->dpll_data;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	if (dd->max_rate && target_rate > dd->max_rate)
30362306a36Sopenharmony_ci		target_rate = dd->max_rate;
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	ref_rate = clk_hw_get_rate(dd->clk_ref);
30662306a36Sopenharmony_ci	clk_name = clk_hw_get_name(hw);
30762306a36Sopenharmony_ci	pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n",
30862306a36Sopenharmony_ci		 clk_name, target_rate);
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	scaled_rt_rp = target_rate / (ref_rate / DPLL_SCALE_FACTOR);
31162306a36Sopenharmony_ci	scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	dd->last_rounded_rate = 0;
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	for (n = dd->min_divider; n <= dd->max_divider; n++) {
31662306a36Sopenharmony_ci		/* Is the (input clk, divider) pair valid for the DPLL? */
31762306a36Sopenharmony_ci		r = _dpll_test_fint(clk, n);
31862306a36Sopenharmony_ci		if (r == DPLL_FINT_UNDERFLOW)
31962306a36Sopenharmony_ci			break;
32062306a36Sopenharmony_ci		else if (r == DPLL_FINT_INVALID)
32162306a36Sopenharmony_ci			continue;
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci		/* Compute the scaled DPLL multiplier, based on the divider */
32462306a36Sopenharmony_ci		m = scaled_rt_rp * n;
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci		/*
32762306a36Sopenharmony_ci		 * Since we're counting n up, a m overflow means we
32862306a36Sopenharmony_ci		 * can bail out completely (since as n increases in
32962306a36Sopenharmony_ci		 * the next iteration, there's no way that m can
33062306a36Sopenharmony_ci		 * increase beyond the current m)
33162306a36Sopenharmony_ci		 */
33262306a36Sopenharmony_ci		if (m > scaled_max_m)
33362306a36Sopenharmony_ci			break;
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci		r = _dpll_test_mult(&m, n, &new_rate, target_rate,
33662306a36Sopenharmony_ci				    ref_rate);
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci		/* m can't be set low enough for this n - try with a larger n */
33962306a36Sopenharmony_ci		if (r == DPLL_MULT_UNDERFLOW)
34062306a36Sopenharmony_ci			continue;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci		/* skip rates above our target rate */
34362306a36Sopenharmony_ci		delta = target_rate - new_rate;
34462306a36Sopenharmony_ci		if (delta < 0)
34562306a36Sopenharmony_ci			continue;
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci		if (delta < prev_min_delta) {
34862306a36Sopenharmony_ci			prev_min_delta = delta;
34962306a36Sopenharmony_ci			min_delta_m = m;
35062306a36Sopenharmony_ci			min_delta_n = n;
35162306a36Sopenharmony_ci		}
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci		pr_debug("clock: %s: m = %d: n = %d: new_rate = %lu\n",
35462306a36Sopenharmony_ci			 clk_name, m, n, new_rate);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci		if (delta == 0)
35762306a36Sopenharmony_ci			break;
35862306a36Sopenharmony_ci	}
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	if (prev_min_delta == LONG_MAX) {
36162306a36Sopenharmony_ci		pr_debug("clock: %s: cannot round to rate %lu\n",
36262306a36Sopenharmony_ci			 clk_name, target_rate);
36362306a36Sopenharmony_ci		return ~0;
36462306a36Sopenharmony_ci	}
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	dd->last_rounded_m = min_delta_m;
36762306a36Sopenharmony_ci	dd->last_rounded_n = min_delta_n;
36862306a36Sopenharmony_ci	dd->last_rounded_rate = target_rate - prev_min_delta;
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	return dd->last_rounded_rate;
37162306a36Sopenharmony_ci}
372