blob: 31f66613effdc9691af05309629480f8dea4db33 [file] [log] [blame]
Hao Zhang4dca7f02014-07-16 00:59:23 +03001/*
2 * Keystone2: get clk rate for K2E
3 *
4 * (C) Copyright 2012-2014
5 * Texas Instruments Incorporated, <www.ti.com>
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 */
9
10#include <common.h>
11#include <asm/arch/clock.h>
12#include <asm/arch/clock_defs.h>
13
14const struct keystone_pll_regs keystone_pll_regs[] = {
15 [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1},
16 [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1},
17 [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1},
18};
19
Vitaly Andrianov61f66fd2014-07-25 22:23:19 +030020int dev_speeds[] = {
21 SPD800,
22 SPD850,
23 SPD1000,
24 SPD1250,
25 SPD1350,
26 SPD1400,
27 SPD1500,
28 SPD1400,
29 SPD1350,
30 SPD1250,
31 SPD1000,
32 SPD850,
33 SPD800
34};
35
Hao Zhang4dca7f02014-07-16 00:59:23 +030036/**
37 * pll_freq_get - get pll frequency
38 * Fout = Fref * NF(mult) / NR(prediv) / OD
39 * @pll: pll identifier
40 */
41static unsigned long pll_freq_get(int pll)
42{
43 unsigned long mult = 1, prediv = 1, output_div = 2;
44 unsigned long ret;
45 u32 tmp, reg;
46
47 if (pll == CORE_PLL) {
48 ret = external_clk[sys_clk];
49 if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) {
50 /* PLL mode */
51 tmp = __raw_readl(KS2_MAINPLLCTL0);
52 prediv = (tmp & PLL_DIV_MASK) + 1;
53 mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) |
54 (pllctl_reg_read(pll, mult) &
55 PLLM_MULT_LO_MASK)) + 1;
56 output_div = ((pllctl_reg_read(pll, secctl) >>
57 PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1;
58
59 ret = ret / prediv / output_div * mult;
60 }
61 } else {
62 switch (pll) {
63 case PASS_PLL:
64 ret = external_clk[pa_clk];
65 reg = KS2_PASSPLLCTL0;
66 break;
67 case DDR3_PLL:
68 ret = external_clk[ddr3_clk];
69 reg = KS2_DDR3APLLCTL0;
70 break;
71 default:
72 return 0;
73 }
74
75 tmp = __raw_readl(reg);
76
77 if (!(tmp & PLLCTL_BYPASS)) {
78 /* Bypass disabled */
79 prediv = (tmp & PLL_DIV_MASK) + 1;
80 mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1;
81 output_div = ((tmp >> PLL_CLKOD_SHIFT) &
82 PLL_CLKOD_MASK) + 1;
83 ret = ((ret / prediv) * mult) / output_div;
84 }
85 }
86
87 return ret;
88}
89
90unsigned long clk_get_rate(unsigned int clk)
91{
92 switch (clk) {
93 case core_pll_clk: return pll_freq_get(CORE_PLL);
94 case pass_pll_clk: return pll_freq_get(PASS_PLL);
95 case ddr3_pll_clk: return pll_freq_get(DDR3_PLL);
96 case sys_clk0_1_clk:
97 case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1);
98 case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2);
99 case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3);
100 case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4);
101 case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2;
102 case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3;
103 case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4;
104 case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6;
105 case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8;
106 case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12;
107 case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24;
108 case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3;
109 case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4;
110 case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6;
111 case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12;
112 default:
113 break;
114 }
115
116 return 0;
117}