/*1* OMAP2/3/4 DPLL clock functions2*3* Copyright (C) 2005-2008 Texas Instruments, Inc.4* Copyright (C) 2004-2010 Nokia Corporation5*6* Contacts:7* Richard Woodruff <[email protected]>8* Paul Walmsley9*10* This program is free software; you can redistribute it and/or modify11* it under the terms of the GNU General Public License version 2 as12* published by the Free Software Foundation.13*/14#undef DEBUG1516#include <linux/kernel.h>17#include <linux/errno.h>18#include <linux/clk.h>19#include <linux/io.h>2021#include <asm/div64.h>2223#include <plat/clock.h>2425#include "clock.h"26#include "cm-regbits-24xx.h"27#include "cm-regbits-34xx.h"2829/* DPLL rate rounding: minimum DPLL multiplier, divider values */30#define DPLL_MIN_MULTIPLIER 231#define DPLL_MIN_DIVIDER 13233/* Possible error results from _dpll_test_mult */34#define DPLL_MULT_UNDERFLOW -13536/*37* Scale factor to mitigate roundoff errors in DPLL rate rounding.38* The higher the scale factor, the greater the risk of arithmetic overflow,39* but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR40* must be a power of DPLL_SCALE_BASE.41*/42#define DPLL_SCALE_FACTOR 6443#define DPLL_SCALE_BASE 244#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \45(DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))4647/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */48#define DPLL_FINT_BAND1_MIN 75000049#define DPLL_FINT_BAND1_MAX 210000050#define DPLL_FINT_BAND2_MIN 750000051#define DPLL_FINT_BAND2_MAX 210000005253/* _dpll_test_fint() return codes */54#define DPLL_FINT_UNDERFLOW -155#define DPLL_FINT_INVALID -25657/* Private functions */5859/*60* _dpll_test_fint - test whether an Fint value is valid for the DPLL61* @clk: DPLL struct clk to test62* @n: divider value (N) to test63*64* Tests whether a particular divider @n will result in a valid DPLL65* internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter66* Correction". Returns 0 if OK, -1 if the enclosing loop can terminate67* (assuming that it is counting N upwards), or -2 if the enclosing loop68* should skip to the next iteration (again assuming N is increasing).69*/70static int _dpll_test_fint(struct clk *clk, u8 n)71{72struct dpll_data *dd;73long fint;74int ret = 0;7576dd = clk->dpll_data;7778/* DPLL divider must result in a valid jitter correction val */79fint = clk->parent->rate / n;80if (fint < DPLL_FINT_BAND1_MIN) {8182pr_debug("rejecting n=%d due to Fint failure, "83"lowering max_divider\n", n);84dd->max_divider = n;85ret = DPLL_FINT_UNDERFLOW;8687} else if (fint > DPLL_FINT_BAND1_MAX &&88fint < DPLL_FINT_BAND2_MIN) {8990pr_debug("rejecting n=%d due to Fint failure\n", n);91ret = DPLL_FINT_INVALID;9293} else if (fint > DPLL_FINT_BAND2_MAX) {9495pr_debug("rejecting n=%d due to Fint failure, "96"boosting min_divider\n", n);97dd->min_divider = n;98ret = DPLL_FINT_INVALID;99100}101102return ret;103}104105static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,106unsigned int m, unsigned int n)107{108unsigned long long num;109110num = (unsigned long long)parent_rate * m;111do_div(num, n);112return num;113}114115/*116* _dpll_test_mult - test a DPLL multiplier value117* @m: pointer to the DPLL m (multiplier) value under test118* @n: current DPLL n (divider) value under test119* @new_rate: pointer to storage for the resulting rounded rate120* @target_rate: the desired DPLL rate121* @parent_rate: the DPLL's parent clock rate122*123* This code tests a DPLL multiplier value, ensuring that the124* resulting rate will not be higher than the target_rate, and that125* the multiplier value itself is valid for the DPLL. Initially, the126* integer pointed to by the m argument should be prescaled by127* multiplying by DPLL_SCALE_FACTOR. The code will replace this with128* a non-scaled m upon return. This non-scaled m will result in a129* new_rate as close as possible to target_rate (but not greater than130* target_rate) given the current (parent_rate, n, prescaled m)131* triple. Returns DPLL_MULT_UNDERFLOW in the event that the132* non-scaled m attempted to underflow, which can allow the calling133* function to bail out early; or 0 upon success.134*/135static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,136unsigned long target_rate,137unsigned long parent_rate)138{139int r = 0, carry = 0;140141/* Unscale m and round if necessary */142if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)143carry = 1;144*m = (*m / DPLL_SCALE_FACTOR) + carry;145146/*147* The new rate must be <= the target rate to avoid programming148* a rate that is impossible for the hardware to handle149*/150*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);151if (*new_rate > target_rate) {152(*m)--;153*new_rate = 0;154}155156/* Guard against m underflow */157if (*m < DPLL_MIN_MULTIPLIER) {158*m = DPLL_MIN_MULTIPLIER;159*new_rate = 0;160r = DPLL_MULT_UNDERFLOW;161}162163if (*new_rate == 0)164*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);165166return r;167}168169/* Public functions */170171void omap2_init_dpll_parent(struct clk *clk)172{173u32 v;174struct dpll_data *dd;175176dd = clk->dpll_data;177if (!dd)178return;179180v = __raw_readl(dd->control_reg);181v &= dd->enable_mask;182v >>= __ffs(dd->enable_mask);183184/* Reparent the struct clk in case the dpll is in bypass */185if (cpu_is_omap24xx()) {186if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||187v == OMAP2XXX_EN_DPLL_FRBYPASS)188clk_reparent(clk, dd->clk_bypass);189} else if (cpu_is_omap34xx()) {190if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||191v == OMAP3XXX_EN_DPLL_FRBYPASS)192clk_reparent(clk, dd->clk_bypass);193} else if (cpu_is_omap44xx()) {194if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||195v == OMAP4XXX_EN_DPLL_FRBYPASS ||196v == OMAP4XXX_EN_DPLL_MNBYPASS)197clk_reparent(clk, dd->clk_bypass);198}199return;200}201202/**203* omap2_get_dpll_rate - returns the current DPLL CLKOUT rate204* @clk: struct clk * of a DPLL205*206* DPLLs can be locked or bypassed - basically, enabled or disabled.207* When locked, the DPLL output depends on the M and N values. When208* bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock209* or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and210* 2 are bypassed with dpll1_fclk and dpll2_fclk respectively211* (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.212* Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is213* locked, or the appropriate bypass rate if the DPLL is bypassed, or 0214* if the clock @clk is not a DPLL.215*/216u32 omap2_get_dpll_rate(struct clk *clk)217{218long long dpll_clk;219u32 dpll_mult, dpll_div, v;220struct dpll_data *dd;221222dd = clk->dpll_data;223if (!dd)224return 0;225226/* Return bypass rate if DPLL is bypassed */227v = __raw_readl(dd->control_reg);228v &= dd->enable_mask;229v >>= __ffs(dd->enable_mask);230231if (cpu_is_omap24xx()) {232if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||233v == OMAP2XXX_EN_DPLL_FRBYPASS)234return dd->clk_bypass->rate;235} else if (cpu_is_omap34xx()) {236if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||237v == OMAP3XXX_EN_DPLL_FRBYPASS)238return dd->clk_bypass->rate;239} else if (cpu_is_omap44xx()) {240if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||241v == OMAP4XXX_EN_DPLL_FRBYPASS ||242v == OMAP4XXX_EN_DPLL_MNBYPASS)243return dd->clk_bypass->rate;244}245246v = __raw_readl(dd->mult_div1_reg);247dpll_mult = v & dd->mult_mask;248dpll_mult >>= __ffs(dd->mult_mask);249dpll_div = v & dd->div1_mask;250dpll_div >>= __ffs(dd->div1_mask);251252dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;253do_div(dpll_clk, dpll_div + 1);254255return dpll_clk;256}257258/* DPLL rate rounding code */259260/**261* omap2_dpll_round_rate - round a target rate for an OMAP DPLL262* @clk: struct clk * for a DPLL263* @target_rate: desired DPLL clock rate264*265* Given a DPLL and a desired target rate, round the target rate to a266* possible, programmable rate for this DPLL. Attempts to select the267* minimum possible n. Stores the computed (m, n) in the DPLL's268* dpll_data structure so set_rate() will not need to call this269* (expensive) function again. Returns ~0 if the target rate cannot270* be rounded, or the rounded rate upon success.271*/272long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)273{274int m, n, r, scaled_max_m;275unsigned long scaled_rt_rp;276unsigned long new_rate = 0;277struct dpll_data *dd;278279if (!clk || !clk->dpll_data)280return ~0;281282dd = clk->dpll_data;283284pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",285clk->name, target_rate);286287scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);288scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;289290dd->last_rounded_rate = 0;291292for (n = dd->min_divider; n <= dd->max_divider; n++) {293294/* Is the (input clk, divider) pair valid for the DPLL? */295r = _dpll_test_fint(clk, n);296if (r == DPLL_FINT_UNDERFLOW)297break;298else if (r == DPLL_FINT_INVALID)299continue;300301/* Compute the scaled DPLL multiplier, based on the divider */302m = scaled_rt_rp * n;303304/*305* Since we're counting n up, a m overflow means we306* can bail out completely (since as n increases in307* the next iteration, there's no way that m can308* increase beyond the current m)309*/310if (m > scaled_max_m)311break;312313r = _dpll_test_mult(&m, n, &new_rate, target_rate,314dd->clk_ref->rate);315316/* m can't be set low enough for this n - try with a larger n */317if (r == DPLL_MULT_UNDERFLOW)318continue;319320pr_debug("clock: %s: m = %d: n = %d: new_rate = %ld\n",321clk->name, m, n, new_rate);322323if (target_rate == new_rate) {324dd->last_rounded_m = m;325dd->last_rounded_n = n;326dd->last_rounded_rate = target_rate;327break;328}329}330331if (target_rate != new_rate) {332pr_debug("clock: %s: cannot round to rate %ld\n", clk->name,333target_rate);334return ~0;335}336337return target_rate;338}339340341342