mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-15 09:27:35 +00:00
ab80b65957
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>
78 lines
1.6 KiB
C
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
|