blob: 05ae03c09a304043884f3b61a6acff969d93b4ae [file] [log] [blame]
Sonic Zhang79f2b392013-02-05 19:10:34 +08001/*
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>
Sonic Zhangab80b652012-11-30 17:39:32 +080012# define pll_is_bypassed() (bfin_read_PLL_CTL() & BYPASS)
Sonic Zhang79f2b392013-02-05 19:10:34 +080013#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))
23static 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))
42static 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;
Sonic Zhangab80b652012-11-30 17:39:32 +080057#if CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS
58 sclk = vco/ssel;
59#else
Sonic Zhang79f2b392013-02-05 19:10:34 +080060 sclk = early_division(vco, ssel);
Sonic Zhangab80b652012-11-30 17:39:32 +080061#endif
Sonic Zhang79f2b392013-02-05 19:10:34 +080062 }
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
Sonic Zhangd6a320d2014-01-28 13:53:34 +080071extern u_long get_vco(void);
72extern u_long get_cclk(void);
73extern u_long get_sclk(void);
74
Sonic Zhang79f2b392013-02-05 19:10:34 +080075#ifdef CGU_DIV
Sonic Zhangd6a320d2014-01-28 13:53:34 +080076extern u_long get_sclk0(void);
77extern u_long get_sclk1(void);
78extern u_long get_dclk(void);
Sonic Zhang79f2b392013-02-05 19:10:34 +080079# define get_uart_clk get_sclk0
Sonic Zhangd6a320d2014-01-28 13:53:34 +080080# define get_i2c_clk get_sclk0
Scott Jiang9f9a65c2014-05-30 16:43:34 +080081# define get_spi_clk get_sclk1
Sonic Zhang79f2b392013-02-05 19:10:34 +080082#else
83# define get_uart_clk get_sclk
Sonic Zhangd6a320d2014-01-28 13:53:34 +080084# define get_i2c_clk get_sclk
85# define get_spi_clk get_sclk
Sonic Zhang79f2b392013-02-05 19:10:34 +080086#endif
87
88#endif