diff options
author | Sonic Zhang <sonic.zhang@analog.com> | 2013-02-05 19:10:34 +0800 |
---|---|---|
committer | Sonic Zhang <sonic.zhang@analog.com> | 2013-05-13 15:47:24 +0800 |
commit | 79f2b3992f52334b510214c6b1b60c4200133658 (patch) | |
tree | a839a67095de369dc074303ec81c493de42df0e5 /arch/blackfin/include/asm | |
parent | f4d8038439fb372c91c3a27121a911c359603bcf (diff) | |
download | u-boot-imx-79f2b3992f52334b510214c6b1b60c4200133658.zip u-boot-imx-79f2b3992f52334b510214c6b1b60c4200133658.tar.gz u-boot-imx-79f2b3992f52334b510214c6b1b60c4200133658.tar.bz2 |
blackfin: Set correct early debug serial baudrate.
Calculate the early uart clock from the system clock registers set by
the bootrom other than the predefine uboot clock macros.
Split the early baudrate setting function and the normal baudrate
setting one.
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Diffstat (limited to 'arch/blackfin/include/asm')
-rw-r--r-- | arch/blackfin/include/asm/clock.h | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/arch/blackfin/include/asm/clock.h b/arch/blackfin/include/asm/clock.h new file mode 100644 index 0000000..df6cd68 --- /dev/null +++ b/arch/blackfin/include/asm/clock.h @@ -0,0 +1,74 @@ + +/* + * 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_STAT() & DF) +#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; + sclk = early_division(vco, ssel); + } + 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 |