/* * OMAP2/3/4 DPLL clock functions * * Copyright (C) 2005-2008 Texas Instruments, Inc. * Copyright (C) 2004-2010 Nokia Corporation * * Contacts: * Richard Woodruff * Paul Walmsley * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #undef DEBUG #include #include #include #include #include #include "soc.h" #include "clock.h" #include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" /* DPLL rate rounding: minimum DPLL multiplier, divider values */ #define DPLL_MIN_MULTIPLIER 2 #define DPLL_MIN_DIVIDER 1 /* Possible error results from _dpll_test_mult */ #define DPLL_MULT_UNDERFLOW -1 /* * Scale factor to mitigate roundoff errors in DPLL rate rounding. * The higher the scale factor, the greater the risk of arithmetic overflow, * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR * must be a power of DPLL_SCALE_BASE. */ #define DPLL_SCALE_FACTOR 64 #define DPLL_SCALE_BASE 2 #define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) /* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */ #define OMAP3430_DPLL_FINT_BAND1_MIN 750000 #define OMAP3430_DPLL_FINT_BAND1_MAX 2100000 #define OMAP3430_DPLL_FINT_BAND2_MIN 7500000 #define OMAP3430_DPLL_FINT_BAND2_MAX 21000000 /* * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx. * From device data manual section 4.3 "DPLL and DLL Specifications". */ #define OMAP3PLUS_DPLL_FINT_JTYPE_MIN 500000 #define OMAP3PLUS_DPLL_FINT_JTYPE_MAX 2500000 #define OMAP3PLUS_DPLL_FINT_MIN 32000 #define OMAP3PLUS_DPLL_FINT_MAX 52000000 /* _dpll_test_fint() return codes */ #define DPLL_FINT_UNDERFLOW -1 #define DPLL_FINT_INVALID -2 /* Private functions */ /* * _dpll_test_fint - test whether an Fint value is valid for the DPLL * @clk: DPLL struct clk to test * @n: divider value (N) to test * * Tests whether a particular divider @n will result in a valid DPLL * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate * (assuming that it is counting N upwards), or -2 if the enclosing loop * should skip to the next iteration (again assuming N is increasing). */ static int _dpll_test_fint(struct clk_hw_omap *clk, u8 n) { struct dpll_data *dd; long fint, fint_min, fint_max; int ret = 0; dd = clk->dpll_data; /* DPLL divider must result in a valid jitter correction val */ fint = __clk_get_rate(__clk_get_parent(clk->hw.clk)) / n; if (cpu_is_omap24xx()) { /* Should not be called for OMAP2, so warn if it is called */ WARN(1, "No fint limits available for OMAP2!\n"); return DPLL_FINT_INVALID; } else if (cpu_is_omap3430()) { fint_min = OMAP3430_DPLL_FINT_BAND1_MIN; fint_max = OMAP3430_DPLL_FINT_BAND2_MAX; } else if (dd->flags & DPLL_J_TYPE) { fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN; fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX;