diff options
Diffstat (limited to 'arch/blackfin/include/asm/clock.h')
| -rw-r--r-- | arch/blackfin/include/asm/clock.h | 78 | 
1 files changed, 78 insertions, 0 deletions
| diff --git a/arch/blackfin/include/asm/clock.h b/arch/blackfin/include/asm/clock.h new file mode 100644 index 000000000..f1fcd4049 --- /dev/null +++ b/arch/blackfin/include/asm/clock.h @@ -0,0 +1,78 @@ + +/* + * Copyright (C) 2012 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include <asm/blackfin.h> +#ifdef PLL_CTL +#include <asm/mach-common/bits/pll.h> +# define pll_is_bypassed() (bfin_read_PLL_CTL() & BYPASS) +#else +#include <asm/mach-common/bits/cgu.h> +# define pll_is_bypassed() (bfin_read_CGU_STAT() & PLLBP) +# define bfin_read_PLL_CTL() bfin_read_CGU_CTL() +# define bfin_read_PLL_DIV() bfin_read_CGU_DIV() +# define SSEL SYSSEL +# define SSEL_P SYSSEL_P +#endif + +__attribute__((always_inline)) +static inline uint32_t early_division(uint32_t dividend, uint32_t divisor) +{ +	uint32_t quotient; +	uint32_t i, j; + +	for (quotient = 1, i = 1; dividend > divisor; ++i) { +		j = divisor << i; +		if (j > dividend || (j & 0x80000000)) { +			--i; +			quotient += (1 << i); +			dividend -= (divisor << i); +			i = 0; +		} +	} + +	return quotient; +} + +__attribute__((always_inline)) +static inline uint32_t early_get_uart_clk(void) +{ +	uint32_t msel, pll_ctl, vco; +	uint32_t div, ssel, sclk, uclk; + +	pll_ctl = bfin_read_PLL_CTL(); +	msel = (pll_ctl & MSEL) >> MSEL_P; +	if (msel == 0) +		msel = (MSEL >> MSEL_P) + 1; + +	vco = (CONFIG_CLKIN_HZ >> (pll_ctl & DF)) * msel; +	sclk = vco; +	if (!pll_is_bypassed()) { +		div = bfin_read_PLL_DIV(); +		ssel = (div & SSEL) >> SSEL_P; +#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS +		sclk = vco/ssel; +#else +		sclk = early_division(vco, ssel); +#endif +	} +	uclk = sclk; +#ifdef CGU_DIV +	ssel = (div & S0SEL) >> S0SEL_P; +	uclk = early_division(sclk, ssel); +#endif +	return uclk; +} + +#ifdef CGU_DIV +# define get_uart_clk get_sclk0 +#else +# define get_uart_clk get_sclk +#endif + +#endif |