u-boot/arch/blackfin/include/asm/clock.h
Sonic Zhang ab80b65957 blackfin: Correct early serial mess output in BYPASS boot mode.
The early serial should not be configured again in initcode() for BYPASS
boot mode and in start() for the other LDR boot modes.

In BYPASS boot mode, the start up code is located in Nor flash address other
than the DRAM address defined in link script. The code embedded string can't
be addressed by its compile time symbol. Calculate it according to the flash
offset.

Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
2013-05-13 15:47:24 +08:00

78 lines
1.6 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_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