1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
20b96af68SPaul Walmsley /*
30b96af68SPaul Walmsley * OMAP2/3/4 DPLL clock functions
40b96af68SPaul Walmsley *
50b96af68SPaul Walmsley * Copyright (C) 2005-2008 Texas Instruments, Inc.
60b96af68SPaul Walmsley * Copyright (C) 2004-2010 Nokia Corporation
70b96af68SPaul Walmsley *
80b96af68SPaul Walmsley * Contacts:
90b96af68SPaul Walmsley * Richard Woodruff <r-woodruff2@ti.com>
100b96af68SPaul Walmsley * Paul Walmsley
110b96af68SPaul Walmsley */
120b96af68SPaul Walmsley #undef DEBUG
130b96af68SPaul Walmsley
140b96af68SPaul Walmsley #include <linux/kernel.h>
150b96af68SPaul Walmsley #include <linux/errno.h>
16a53ad8efSStephen Boyd #include <linux/clk.h>
1732cc0021SMike Turquette #include <linux/clk-provider.h>
180b96af68SPaul Walmsley #include <linux/io.h>
19b138b028STero Kristo #include <linux/clk/ti.h>
200b96af68SPaul Walmsley
210b96af68SPaul Walmsley #include <asm/div64.h>
220b96af68SPaul Walmsley
230b96af68SPaul Walmsley #include "clock.h"
240b96af68SPaul Walmsley
250b96af68SPaul Walmsley /* DPLL rate rounding: minimum DPLL multiplier, divider values */
2693340a22SPaul Walmsley #define DPLL_MIN_MULTIPLIER 2
270b96af68SPaul Walmsley #define DPLL_MIN_DIVIDER 1
280b96af68SPaul Walmsley
290b96af68SPaul Walmsley /* Possible error results from _dpll_test_mult */
300b96af68SPaul Walmsley #define DPLL_MULT_UNDERFLOW -1
310b96af68SPaul Walmsley
320b96af68SPaul Walmsley /*
330b96af68SPaul Walmsley * Scale factor to mitigate roundoff errors in DPLL rate rounding.
340b96af68SPaul Walmsley * The higher the scale factor, the greater the risk of arithmetic overflow,
350b96af68SPaul Walmsley * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
360b96af68SPaul Walmsley * must be a power of DPLL_SCALE_BASE.
370b96af68SPaul Walmsley */
380b96af68SPaul Walmsley #define DPLL_SCALE_FACTOR 64
390b96af68SPaul Walmsley #define DPLL_SCALE_BASE 2
400b96af68SPaul Walmsley #define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
410b96af68SPaul Walmsley (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
420b96af68SPaul Walmsley
431194d7b8SJon Hunter /*
441194d7b8SJon Hunter * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx.
451194d7b8SJon Hunter * From device data manual section 4.3 "DPLL and DLL Specifications".
461194d7b8SJon Hunter */
471194d7b8SJon Hunter #define OMAP3PLUS_DPLL_FINT_JTYPE_MIN 500000
481194d7b8SJon Hunter #define OMAP3PLUS_DPLL_FINT_JTYPE_MAX 2500000
490b96af68SPaul Walmsley
500b96af68SPaul Walmsley /* _dpll_test_fint() return codes */
510b96af68SPaul Walmsley #define DPLL_FINT_UNDERFLOW -1
520b96af68SPaul Walmsley #define DPLL_FINT_INVALID -2
530b96af68SPaul Walmsley
540b96af68SPaul Walmsley /* Private functions */
550b96af68SPaul Walmsley
560b96af68SPaul Walmsley /*
570b96af68SPaul Walmsley * _dpll_test_fint - test whether an Fint value is valid for the DPLL
580b96af68SPaul Walmsley * @clk: DPLL struct clk to test
590b96af68SPaul Walmsley * @n: divider value (N) to test
600b96af68SPaul Walmsley *
610b96af68SPaul Walmsley * Tests whether a particular divider @n will result in a valid DPLL
620b96af68SPaul Walmsley * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
630b96af68SPaul Walmsley * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
640b96af68SPaul Walmsley * (assuming that it is counting N upwards), or -2 if the enclosing loop
650b96af68SPaul Walmsley * should skip to the next iteration (again assuming N is increasing).
660b96af68SPaul Walmsley */
_dpll_test_fint(struct clk_hw_omap * clk,unsigned int n)676340c872STero Kristo static int _dpll_test_fint(struct clk_hw_omap *clk, unsigned int n)
680b96af68SPaul Walmsley {
690b96af68SPaul Walmsley struct dpll_data *dd;
701194d7b8SJon Hunter long fint, fint_min, fint_max;
710b96af68SPaul Walmsley int ret = 0;
720b96af68SPaul Walmsley
730b96af68SPaul Walmsley dd = clk->dpll_data;
740b96af68SPaul Walmsley
750b96af68SPaul Walmsley /* DPLL divider must result in a valid jitter correction val */
76a53ad8efSStephen Boyd fint = clk_hw_get_rate(clk_hw_get_parent(&clk->hw)) / n;
770b96af68SPaul Walmsley
78a24886e2STero Kristo if (dd->flags & DPLL_J_TYPE) {
791194d7b8SJon Hunter fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN;
801194d7b8SJon Hunter fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX;
811194d7b8SJon Hunter } else {
82f3b19aa5STero Kristo fint_min = ti_clk_get_features()->fint_min;
83f3b19aa5STero Kristo fint_max = ti_clk_get_features()->fint_max;
841194d7b8SJon Hunter }
851194d7b8SJon Hunter
86a24886e2STero Kristo if (!fint_min || !fint_max) {
87a24886e2STero Kristo WARN(1, "No fint limits available!\n");
88a24886e2STero Kristo return DPLL_FINT_INVALID;
89a24886e2STero Kristo }
90a24886e2STero Kristo
91f3b19aa5STero Kristo if (fint < ti_clk_get_features()->fint_min) {
927852ec05SPaul Walmsley pr_debug("rejecting n=%d due to Fint failure, lowering max_divider\n",
937852ec05SPaul Walmsley n);
940b96af68SPaul Walmsley dd->max_divider = n;
950b96af68SPaul Walmsley ret = DPLL_FINT_UNDERFLOW;
96f3b19aa5STero Kristo } else if (fint > ti_clk_get_features()->fint_max) {
977852ec05SPaul Walmsley pr_debug("rejecting n=%d due to Fint failure, boosting min_divider\n",
987852ec05SPaul Walmsley n);
990b96af68SPaul Walmsley dd->min_divider = n;
1000b96af68SPaul Walmsley ret = DPLL_FINT_INVALID;
101f3b19aa5STero Kristo } else if (fint > ti_clk_get_features()->fint_band1_max &&
102f3b19aa5STero Kristo fint < ti_clk_get_features()->fint_band2_min) {
1031194d7b8SJon Hunter pr_debug("rejecting n=%d due to Fint failure\n", n);
1041194d7b8SJon Hunter ret = DPLL_FINT_INVALID;
1050b96af68SPaul Walmsley }
1060b96af68SPaul Walmsley
1070b96af68SPaul Walmsley return ret;
1080b96af68SPaul Walmsley }
1090b96af68SPaul Walmsley
_dpll_compute_new_rate(unsigned long parent_rate,unsigned int m,unsigned int n)1100b96af68SPaul Walmsley static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
1110b96af68SPaul Walmsley unsigned int m, unsigned int n)
1120b96af68SPaul Walmsley {
1130b96af68SPaul Walmsley unsigned long long num;
1140b96af68SPaul Walmsley
1150b96af68SPaul Walmsley num = (unsigned long long)parent_rate * m;
1160b96af68SPaul Walmsley do_div(num, n);
1170b96af68SPaul Walmsley return num;
1180b96af68SPaul Walmsley }
1190b96af68SPaul Walmsley
1200b96af68SPaul Walmsley /*
1210b96af68SPaul Walmsley * _dpll_test_mult - test a DPLL multiplier value
1220b96af68SPaul Walmsley * @m: pointer to the DPLL m (multiplier) value under test
1230b96af68SPaul Walmsley * @n: current DPLL n (divider) value under test
1240b96af68SPaul Walmsley * @new_rate: pointer to storage for the resulting rounded rate
1250b96af68SPaul Walmsley * @target_rate: the desired DPLL rate
1260b96af68SPaul Walmsley * @parent_rate: the DPLL's parent clock rate
1270b96af68SPaul Walmsley *
1280b96af68SPaul Walmsley * This code tests a DPLL multiplier value, ensuring that the
1290b96af68SPaul Walmsley * resulting rate will not be higher than the target_rate, and that
1300b96af68SPaul Walmsley * the multiplier value itself is valid for the DPLL. Initially, the
1310b96af68SPaul Walmsley * integer pointed to by the m argument should be prescaled by
1320b96af68SPaul Walmsley * multiplying by DPLL_SCALE_FACTOR. The code will replace this with
1330b96af68SPaul Walmsley * a non-scaled m upon return. This non-scaled m will result in a
1340b96af68SPaul Walmsley * new_rate as close as possible to target_rate (but not greater than
1350b96af68SPaul Walmsley * target_rate) given the current (parent_rate, n, prescaled m)
1360b96af68SPaul Walmsley * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
1370b96af68SPaul Walmsley * non-scaled m attempted to underflow, which can allow the calling
1380b96af68SPaul Walmsley * function to bail out early; or 0 upon success.
1390b96af68SPaul Walmsley */
_dpll_test_mult(int * m,int n,unsigned long * new_rate,unsigned long target_rate,unsigned long parent_rate)1400b96af68SPaul Walmsley static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
1410b96af68SPaul Walmsley unsigned long target_rate,
1420b96af68SPaul Walmsley unsigned long parent_rate)
1430b96af68SPaul Walmsley {
1440b96af68SPaul Walmsley int r = 0, carry = 0;
1450b96af68SPaul Walmsley
1460b96af68SPaul Walmsley /* Unscale m and round if necessary */
1470b96af68SPaul Walmsley if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
1480b96af68SPaul Walmsley carry = 1;
1490b96af68SPaul Walmsley *m = (*m / DPLL_SCALE_FACTOR) + carry;
1500b96af68SPaul Walmsley
1510b96af68SPaul Walmsley /*
1520b96af68SPaul Walmsley * The new rate must be <= the target rate to avoid programming
1530b96af68SPaul Walmsley * a rate that is impossible for the hardware to handle
1540b96af68SPaul Walmsley */
1550b96af68SPaul Walmsley *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
1560b96af68SPaul Walmsley if (*new_rate > target_rate) {
1570b96af68SPaul Walmsley (*m)--;
1580b96af68SPaul Walmsley *new_rate = 0;
1590b96af68SPaul Walmsley }
1600b96af68SPaul Walmsley
1610b96af68SPaul Walmsley /* Guard against m underflow */
1620b96af68SPaul Walmsley if (*m < DPLL_MIN_MULTIPLIER) {
1630b96af68SPaul Walmsley *m = DPLL_MIN_MULTIPLIER;
1640b96af68SPaul Walmsley *new_rate = 0;
1650b96af68SPaul Walmsley r = DPLL_MULT_UNDERFLOW;
1660b96af68SPaul Walmsley }
1670b96af68SPaul Walmsley
1680b96af68SPaul Walmsley if (*new_rate == 0)
1690b96af68SPaul Walmsley *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
1700b96af68SPaul Walmsley
1710b96af68SPaul Walmsley return r;
1720b96af68SPaul Walmsley }
1730b96af68SPaul Walmsley
1745f84aeb6STero Kristo /**
1755f84aeb6STero Kristo * _omap2_dpll_is_in_bypass - check if DPLL is in bypass mode or not
1765f84aeb6STero Kristo * @v: bitfield value of the DPLL enable
1775f84aeb6STero Kristo *
1785f84aeb6STero Kristo * Checks given DPLL enable bitfield to see whether the DPLL is in bypass
1795f84aeb6STero Kristo * mode or not. Returns 1 if the DPLL is in bypass, 0 otherwise.
1805f84aeb6STero Kristo */
_omap2_dpll_is_in_bypass(u32 v)1815f84aeb6STero Kristo static int _omap2_dpll_is_in_bypass(u32 v)
1825f84aeb6STero Kristo {
183512d91cbSTero Kristo u8 mask, val;
184512d91cbSTero Kristo
185f3b19aa5STero Kristo mask = ti_clk_get_features()->dpll_bypass_vals;
186512d91cbSTero Kristo
187512d91cbSTero Kristo /*
188512d91cbSTero Kristo * Each set bit in the mask corresponds to a bypass value equal
189512d91cbSTero Kristo * to the bitshift. Go through each set-bit in the mask and
190512d91cbSTero Kristo * compare against the given register value.
191512d91cbSTero Kristo */
192512d91cbSTero Kristo while (mask) {
193512d91cbSTero Kristo val = __ffs(mask);
194512d91cbSTero Kristo mask ^= (1 << val);
195512d91cbSTero Kristo if (v == val)
1965f84aeb6STero Kristo return 1;
1975f84aeb6STero Kristo }
1985f84aeb6STero Kristo
1995f84aeb6STero Kristo return 0;
2005f84aeb6STero Kristo }
2015f84aeb6STero Kristo
2020b96af68SPaul Walmsley /* Public functions */
omap2_init_dpll_parent(struct clk_hw * hw)20332cc0021SMike Turquette u8 omap2_init_dpll_parent(struct clk_hw *hw)
20432cc0021SMike Turquette {
20532cc0021SMike Turquette struct clk_hw_omap *clk = to_clk_hw_omap(hw);
2060b96af68SPaul Walmsley u32 v;
2070b96af68SPaul Walmsley struct dpll_data *dd;
2080b96af68SPaul Walmsley
2090b96af68SPaul Walmsley dd = clk->dpll_data;
2100b96af68SPaul Walmsley if (!dd)
21132cc0021SMike Turquette return -EINVAL;
2120b96af68SPaul Walmsley
2136c0afb50STero Kristo v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
2140b96af68SPaul Walmsley v &= dd->enable_mask;
2150b96af68SPaul Walmsley v >>= __ffs(dd->enable_mask);
2160b96af68SPaul Walmsley
217241d3a8dSPaul Walmsley /* Reparent the struct clk in case the dpll is in bypass */
2185f84aeb6STero Kristo if (_omap2_dpll_is_in_bypass(v))
21932cc0021SMike Turquette return 1;
2205f84aeb6STero Kristo
22132cc0021SMike Turquette return 0;
2220b96af68SPaul Walmsley }
2230b96af68SPaul Walmsley
2240b96af68SPaul Walmsley /**
2250b96af68SPaul Walmsley * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
2260b96af68SPaul Walmsley * @clk: struct clk * of a DPLL
2270b96af68SPaul Walmsley *
2280b96af68SPaul Walmsley * DPLLs can be locked or bypassed - basically, enabled or disabled.
2290b96af68SPaul Walmsley * When locked, the DPLL output depends on the M and N values. When
2300b96af68SPaul Walmsley * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
2310b96af68SPaul Walmsley * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
2320b96af68SPaul Walmsley * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
2330b96af68SPaul Walmsley * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
2340b96af68SPaul Walmsley * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
2350b96af68SPaul Walmsley * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
2360b96af68SPaul Walmsley * if the clock @clk is not a DPLL.
2370b96af68SPaul Walmsley */
omap2_get_dpll_rate(struct clk_hw_omap * clk)23832cc0021SMike Turquette unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
2390b96af68SPaul Walmsley {
240df976f5dSNicolas Pitre u64 dpll_clk;
2410b96af68SPaul Walmsley u32 dpll_mult, dpll_div, v;
2420b96af68SPaul Walmsley struct dpll_data *dd;
2430b96af68SPaul Walmsley
2440b96af68SPaul Walmsley dd = clk->dpll_data;
2450b96af68SPaul Walmsley if (!dd)
2460b96af68SPaul Walmsley return 0;
2470b96af68SPaul Walmsley
2480b96af68SPaul Walmsley /* Return bypass rate if DPLL is bypassed */
2496c0afb50STero Kristo v = ti_clk_ll_ops->clk_readl(&dd->control_reg);
2500b96af68SPaul Walmsley v &= dd->enable_mask;
2510b96af68SPaul Walmsley v >>= __ffs(dd->enable_mask);
2520b96af68SPaul Walmsley
2535f84aeb6STero Kristo if (_omap2_dpll_is_in_bypass(v))
254b6f51284STero Kristo return clk_hw_get_rate(dd->clk_bypass);
2550b96af68SPaul Walmsley
2566c0afb50STero Kristo v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg);
2570b96af68SPaul Walmsley dpll_mult = v & dd->mult_mask;
2580b96af68SPaul Walmsley dpll_mult >>= __ffs(dd->mult_mask);
2590b96af68SPaul Walmsley dpll_div = v & dd->div1_mask;
2600b96af68SPaul Walmsley dpll_div >>= __ffs(dd->div1_mask);
2610b96af68SPaul Walmsley
262b6f51284STero Kristo dpll_clk = (u64)clk_hw_get_rate(dd->clk_ref) * dpll_mult;
2630b96af68SPaul Walmsley do_div(dpll_clk, dpll_div + 1);
2640b96af68SPaul Walmsley
2650b96af68SPaul Walmsley return dpll_clk;
2660b96af68SPaul Walmsley }
2670b96af68SPaul Walmsley
2680b96af68SPaul Walmsley /* DPLL rate rounding code */
2690b96af68SPaul Walmsley
2700b96af68SPaul Walmsley /**
2710b96af68SPaul Walmsley * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
272ed1b7dd7SLee Jones * @hw: struct clk_hw containing the struct clk * for a DPLL
2730b96af68SPaul Walmsley * @target_rate: desired DPLL clock rate
274ed1b7dd7SLee Jones * @parent_rate: parent's DPLL clock rate
2750b96af68SPaul Walmsley *
276241d3a8dSPaul Walmsley * Given a DPLL and a desired target rate, round the target rate to a
277241d3a8dSPaul Walmsley * possible, programmable rate for this DPLL. Attempts to select the
278241d3a8dSPaul Walmsley * minimum possible n. Stores the computed (m, n) in the DPLL's
279241d3a8dSPaul Walmsley * dpll_data structure so set_rate() will not need to call this
280241d3a8dSPaul Walmsley * (expensive) function again. Returns ~0 if the target rate cannot
281241d3a8dSPaul Walmsley * be rounded, or the rounded rate upon success.
2820b96af68SPaul Walmsley */
omap2_dpll_round_rate(struct clk_hw * hw,unsigned long target_rate,unsigned long * parent_rate)28332cc0021SMike Turquette long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
28432cc0021SMike Turquette unsigned long *parent_rate)
28532cc0021SMike Turquette {
28632cc0021SMike Turquette struct clk_hw_omap *clk = to_clk_hw_omap(hw);
287241d3a8dSPaul Walmsley int m, n, r, scaled_max_m;
2880a263444SPaul Walmsley int min_delta_m = INT_MAX, min_delta_n = INT_MAX;
289241d3a8dSPaul Walmsley unsigned long scaled_rt_rp;
290241d3a8dSPaul Walmsley unsigned long new_rate = 0;
2910b96af68SPaul Walmsley struct dpll_data *dd;
2925dcc3b97SRajendra Nayak unsigned long ref_rate;
2930a263444SPaul Walmsley long delta;
2940a263444SPaul Walmsley long prev_min_delta = LONG_MAX;
2955dcc3b97SRajendra Nayak const char *clk_name;
2960b96af68SPaul Walmsley
2970b96af68SPaul Walmsley if (!clk || !clk->dpll_data)
2980b96af68SPaul Walmsley return ~0;
2990b96af68SPaul Walmsley
3000b96af68SPaul Walmsley dd = clk->dpll_data;
3010b96af68SPaul Walmsley
302c5cc2a0bSTero Kristo if (dd->max_rate && target_rate > dd->max_rate)
303c5cc2a0bSTero Kristo target_rate = dd->max_rate;
304c5cc2a0bSTero Kristo
305b6f51284STero Kristo ref_rate = clk_hw_get_rate(dd->clk_ref);
306a53ad8efSStephen Boyd clk_name = clk_hw_get_name(hw);
3070cc1d944STomi Valkeinen pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n",
3085dcc3b97SRajendra Nayak clk_name, target_rate);
3090b96af68SPaul Walmsley
3105dcc3b97SRajendra Nayak scaled_rt_rp = target_rate / (ref_rate / DPLL_SCALE_FACTOR);
3110b96af68SPaul Walmsley scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
3120b96af68SPaul Walmsley
3130b96af68SPaul Walmsley dd->last_rounded_rate = 0;
3140b96af68SPaul Walmsley
3150b96af68SPaul Walmsley for (n = dd->min_divider; n <= dd->max_divider; n++) {
3160b96af68SPaul Walmsley /* Is the (input clk, divider) pair valid for the DPLL? */
3170b96af68SPaul Walmsley r = _dpll_test_fint(clk, n);
3180b96af68SPaul Walmsley if (r == DPLL_FINT_UNDERFLOW)
3190b96af68SPaul Walmsley break;
3200b96af68SPaul Walmsley else if (r == DPLL_FINT_INVALID)
3210b96af68SPaul Walmsley continue;
3220b96af68SPaul Walmsley
3230b96af68SPaul Walmsley /* Compute the scaled DPLL multiplier, based on the divider */
3240b96af68SPaul Walmsley m = scaled_rt_rp * n;
3250b96af68SPaul Walmsley
3260b96af68SPaul Walmsley /*
3270b96af68SPaul Walmsley * Since we're counting n up, a m overflow means we
3280b96af68SPaul Walmsley * can bail out completely (since as n increases in
3290b96af68SPaul Walmsley * the next iteration, there's no way that m can
3300b96af68SPaul Walmsley * increase beyond the current m)
3310b96af68SPaul Walmsley */
3320b96af68SPaul Walmsley if (m > scaled_max_m)
3330b96af68SPaul Walmsley break;
3340b96af68SPaul Walmsley
3350b96af68SPaul Walmsley r = _dpll_test_mult(&m, n, &new_rate, target_rate,
3365dcc3b97SRajendra Nayak ref_rate);
3370b96af68SPaul Walmsley
3380b96af68SPaul Walmsley /* m can't be set low enough for this n - try with a larger n */
3390b96af68SPaul Walmsley if (r == DPLL_MULT_UNDERFLOW)
3400b96af68SPaul Walmsley continue;
3410b96af68SPaul Walmsley
3420a263444SPaul Walmsley /* skip rates above our target rate */
3430a263444SPaul Walmsley delta = target_rate - new_rate;
3440a263444SPaul Walmsley if (delta < 0)
3450a263444SPaul Walmsley continue;
3460a263444SPaul Walmsley
3470a263444SPaul Walmsley if (delta < prev_min_delta) {
3480a263444SPaul Walmsley prev_min_delta = delta;
3490a263444SPaul Walmsley min_delta_m = m;
3500a263444SPaul Walmsley min_delta_n = n;
3510a263444SPaul Walmsley }
3520a263444SPaul Walmsley
3530cc1d944STomi Valkeinen pr_debug("clock: %s: m = %d: n = %d: new_rate = %lu\n",
3545dcc3b97SRajendra Nayak clk_name, m, n, new_rate);
3550b96af68SPaul Walmsley
3560a263444SPaul Walmsley if (delta == 0)
3570b96af68SPaul Walmsley break;
3580b96af68SPaul Walmsley }
3590b96af68SPaul Walmsley
3600a263444SPaul Walmsley if (prev_min_delta == LONG_MAX) {
3610cc1d944STomi Valkeinen pr_debug("clock: %s: cannot round to rate %lu\n",
3625dcc3b97SRajendra Nayak clk_name, target_rate);
3630b96af68SPaul Walmsley return ~0;
3640b96af68SPaul Walmsley }
3650b96af68SPaul Walmsley
3660a263444SPaul Walmsley dd->last_rounded_m = min_delta_m;
3670a263444SPaul Walmsley dd->last_rounded_n = min_delta_n;
3680a263444SPaul Walmsley dd->last_rounded_rate = target_rate - prev_min_delta;
3690a263444SPaul Walmsley
3700a263444SPaul Walmsley return dd->last_rounded_rate;
3710b96af68SPaul Walmsley }
372