summaryrefslogtreecommitdiff
path: root/arch/blackfin/include/asm
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2013-02-05 19:10:34 +0800
committerSonic Zhang <sonic.zhang@analog.com>2013-05-13 15:47:24 +0800
commit79f2b3992f52334b510214c6b1b60c4200133658 (patch)
treea839a67095de369dc074303ec81c493de42df0e5 /arch/blackfin/include/asm
parentf4d8038439fb372c91c3a27121a911c359603bcf (diff)
downloadu-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.h74
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