]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/blackfin/include/asm/clock.h
Merge branch 'master' of git://www.denx.de/git/u-boot-usb
[karo-tx-uboot.git] / arch / blackfin / include / asm / clock.h
1 /*
2  * Copyright (C) 2012 Analog Devices Inc.
3  * Licensed under the GPL-2 or later.
4  */
5
6 #ifndef __CLOCK_H__
7 #define __CLOCK_H__
8
9 #include <asm/blackfin.h>
10 #ifdef PLL_CTL
11 #include <asm/mach-common/bits/pll.h>
12 # define pll_is_bypassed() (bfin_read_PLL_CTL() & BYPASS)
13 #else
14 #include <asm/mach-common/bits/cgu.h>
15 # define pll_is_bypassed() (bfin_read_CGU_STAT() & PLLBP)
16 # define bfin_read_PLL_CTL() bfin_read_CGU_CTL()
17 # define bfin_read_PLL_DIV() bfin_read_CGU_DIV()
18 # define SSEL SYSSEL
19 # define SSEL_P SYSSEL_P
20 #endif
21
22 __attribute__((always_inline))
23 static inline uint32_t early_division(uint32_t dividend, uint32_t divisor)
24 {
25         uint32_t quotient;
26         uint32_t i, j;
27
28         for (quotient = 1, i = 1; dividend > divisor; ++i) {
29                 j = divisor << i;
30                 if (j > dividend || (j & 0x80000000)) {
31                         --i;
32                         quotient += (1 << i);
33                         dividend -= (divisor << i);
34                         i = 0;
35                 }
36         }
37
38         return quotient;
39 }
40
41 __attribute__((always_inline))
42 static inline uint32_t early_get_uart_clk(void)
43 {
44         uint32_t msel, pll_ctl, vco;
45         uint32_t div, ssel, sclk, uclk;
46
47         pll_ctl = bfin_read_PLL_CTL();
48         msel = (pll_ctl & MSEL) >> MSEL_P;
49         if (msel == 0)
50                 msel = (MSEL >> MSEL_P) + 1;
51
52         vco = (CONFIG_CLKIN_HZ >> (pll_ctl & DF)) * msel;
53         sclk = vco;
54         if (!pll_is_bypassed()) {
55                 div = bfin_read_PLL_DIV();
56                 ssel = (div & SSEL) >> SSEL_P;
57 #if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS
58                 sclk = vco/ssel;
59 #else
60                 sclk = early_division(vco, ssel);
61 #endif
62         }
63         uclk = sclk;
64 #ifdef CGU_DIV
65         ssel = (div & S0SEL) >> S0SEL_P;
66         uclk = early_division(sclk, ssel);
67 #endif
68         return uclk;
69 }
70
71 #ifdef CGU_DIV
72 # define get_uart_clk get_sclk0
73 #else
74 # define get_uart_clk get_sclk
75 #endif
76
77 #endif