]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/arm926ejs/davinci/cpu.c
ARM: tegra: collect SoC sources into mach-tegra
[people/ms/u-boot.git] / arch / arm / cpu / arm926ejs / davinci / cpu.c
1 /*
2 * Copyright (C) 2004 Texas Instruments.
3 * Copyright (C) 2009 David Brownell
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8 #include <common.h>
9 #include <netdev.h>
10 #include <asm/arch/hardware.h>
11 #include <asm/io.h>
12
13 DECLARE_GLOBAL_DATA_PTR;
14
15 /* offsets from PLL controller base */
16 #define PLLC_PLLCTL 0x100
17 #define PLLC_PLLM 0x110
18 #define PLLC_PREDIV 0x114
19 #define PLLC_PLLDIV1 0x118
20 #define PLLC_PLLDIV2 0x11c
21 #define PLLC_PLLDIV3 0x120
22 #define PLLC_POSTDIV 0x128
23 #define PLLC_BPDIV 0x12c
24 #define PLLC_PLLDIV4 0x160
25 #define PLLC_PLLDIV5 0x164
26 #define PLLC_PLLDIV6 0x168
27 #define PLLC_PLLDIV7 0x16c
28 #define PLLC_PLLDIV8 0x170
29 #define PLLC_PLLDIV9 0x174
30
31 #define BIT(x) (1 << (x))
32
33 /* SOC-specific pll info */
34 #ifdef CONFIG_SOC_DM355
35 #define ARM_PLLDIV PLLC_PLLDIV1
36 #define DDR_PLLDIV PLLC_PLLDIV1
37 #endif
38
39 #ifdef CONFIG_SOC_DM644X
40 #define ARM_PLLDIV PLLC_PLLDIV2
41 #define DSP_PLLDIV PLLC_PLLDIV1
42 #define DDR_PLLDIV PLLC_PLLDIV2
43 #endif
44
45 #ifdef CONFIG_SOC_DM646X
46 #define DSP_PLLDIV PLLC_PLLDIV1
47 #define ARM_PLLDIV PLLC_PLLDIV2
48 #define DDR_PLLDIV PLLC_PLLDIV1
49 #endif
50
51 #ifdef CONFIG_SOC_DA8XX
52 unsigned int sysdiv[9] = {
53 PLLC_PLLDIV1, PLLC_PLLDIV2, PLLC_PLLDIV3, PLLC_PLLDIV4, PLLC_PLLDIV5,
54 PLLC_PLLDIV6, PLLC_PLLDIV7, PLLC_PLLDIV8, PLLC_PLLDIV9
55 };
56
57 int clk_get(enum davinci_clk_ids id)
58 {
59 int pre_div;
60 int pllm;
61 int post_div;
62 int pll_out;
63 unsigned int pll_base;
64
65 pll_out = CONFIG_SYS_OSCIN_FREQ;
66
67 if (id == DAVINCI_AUXCLK_CLKID)
68 goto out;
69
70 if ((id >> 16) == 1)
71 pll_base = (unsigned int)davinci_pllc1_regs;
72 else
73 pll_base = (unsigned int)davinci_pllc0_regs;
74
75 id &= 0xFFFF;
76
77 /*
78 * Lets keep this simple. Combining operations can result in
79 * unexpected approximations
80 */
81 pre_div = (readl(pll_base + PLLC_PREDIV) &
82 DAVINCI_PLLC_DIV_MASK) + 1;
83 pllm = readl(pll_base + PLLC_PLLM) + 1;
84
85 pll_out /= pre_div;
86 pll_out *= pllm;
87
88 if (id == DAVINCI_PLLM_CLKID)
89 goto out;
90
91 post_div = (readl(pll_base + PLLC_POSTDIV) &
92 DAVINCI_PLLC_DIV_MASK) + 1;
93
94 pll_out /= post_div;
95
96 if (id == DAVINCI_PLLC_CLKID)
97 goto out;
98
99 pll_out /= (readl(pll_base + sysdiv[id - 1]) &
100 DAVINCI_PLLC_DIV_MASK) + 1;
101
102 out:
103 return pll_out;
104 }
105
106 int set_cpu_clk_info(void)
107 {
108 gd->bd->bi_arm_freq = clk_get(DAVINCI_ARM_CLKID) / 1000000;
109 /* DDR PHY uses an x2 input clock */
110 gd->bd->bi_ddr_freq = cpu_is_da830() ? 0 :
111 (clk_get(DAVINCI_DDR_CLKID) / 1000000);
112 gd->bd->bi_dsp_freq = 0;
113 return 0;
114 }
115
116 #else /* CONFIG_SOC_DA8XX */
117
118 static unsigned pll_div(volatile void *pllbase, unsigned offset)
119 {
120 u32 div;
121
122 div = REG(pllbase + offset);
123 return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1;
124 }
125
126 static inline unsigned pll_prediv(volatile void *pllbase)
127 {
128 #ifdef CONFIG_SOC_DM355
129 /* this register read seems to fail on pll0 */
130 if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE)
131 return 8;
132 else
133 return pll_div(pllbase, PLLC_PREDIV);
134 #elif defined(CONFIG_SOC_DM365)
135 return pll_div(pllbase, PLLC_PREDIV);
136 #endif
137 return 1;
138 }
139
140 static inline unsigned pll_postdiv(volatile void *pllbase)
141 {
142 #if defined(CONFIG_SOC_DM355) || defined(CONFIG_SOC_DM365)
143 return pll_div(pllbase, PLLC_POSTDIV);
144 #elif defined(CONFIG_SOC_DM6446)
145 if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE)
146 return pll_div(pllbase, PLLC_POSTDIV);
147 #endif
148 return 1;
149 }
150
151 static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div)
152 {
153 volatile void *pllbase = (volatile void *) pll_addr;
154 #ifdef CONFIG_SOC_DM646X
155 unsigned base = CONFIG_REFCLK_FREQ / 1000;
156 #else
157 unsigned base = CONFIG_SYS_HZ_CLOCK / 1000;
158 #endif
159
160 /* the PLL might be bypassed */
161 if (readl(pllbase + PLLC_PLLCTL) & BIT(0)) {
162 base /= pll_prediv(pllbase);
163 #if defined(CONFIG_SOC_DM365)
164 base *= 2 * (readl(pllbase + PLLC_PLLM) & 0x0ff);
165 #else
166 base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff);
167 #endif
168 base /= pll_postdiv(pllbase);
169 }
170 return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div));
171 }
172
173 #ifdef DAVINCI_DM6467EVM
174 unsigned int davinci_arm_clk_get()
175 {
176 return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV) * 1000000;
177 }
178 #endif
179
180 #if defined(CONFIG_SOC_DM365)
181 unsigned int davinci_clk_get(unsigned int div)
182 {
183 return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, div) * 1000000;
184 }
185 #endif
186
187 int set_cpu_clk_info(void)
188 {
189 unsigned int pllbase = DAVINCI_PLL_CNTRL0_BASE;
190 #if defined(CONFIG_SOC_DM365)
191 pllbase = DAVINCI_PLL_CNTRL1_BASE;
192 #endif
193 gd->bd->bi_arm_freq = pll_sysclk_mhz(pllbase, ARM_PLLDIV);
194
195 #ifdef DSP_PLLDIV
196 gd->bd->bi_dsp_freq =
197 pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, DSP_PLLDIV);
198 #else
199 gd->bd->bi_dsp_freq = 0;
200 #endif
201
202 pllbase = DAVINCI_PLL_CNTRL1_BASE;
203 #if defined(CONFIG_SOC_DM365)
204 pllbase = DAVINCI_PLL_CNTRL0_BASE;
205 #endif
206 gd->bd->bi_ddr_freq = pll_sysclk_mhz(pllbase, DDR_PLLDIV) / 2;
207
208 return 0;
209 }
210
211 #endif /* !CONFIG_SOC_DA8XX */
212
213 /*
214 * Initializes on-chip ethernet controllers.
215 * to override, implement board_eth_init()
216 */
217 int cpu_eth_init(bd_t *bis)
218 {
219 #if defined(CONFIG_DRIVER_TI_EMAC)
220 davinci_emac_initialize();
221 #endif
222 return 0;
223 }