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