u-boot-brain/arch/blackfin/include/asm/clock.h
Sonic Zhang 79f2b3992f 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>
2013-05-13 15:47:24 +08:00

75 lines
1.5 KiB
C

/*
* 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