]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/arm/cpu/arm926ejs/davinci/cpu.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[people/ms/u-boot.git] / arch / arm / cpu / arm926ejs / davinci / cpu.c
CommitLineData
7a4f511b
DB
1/*
2 * Copyright (C) 2004 Texas Instruments.
3 * Copyright (C) 2009 David Brownell
4 *
1a459660 5 * SPDX-License-Identifier: GPL-2.0+
7a4f511b
DB
6 */
7
8#include <common.h>
8453587e 9#include <netdev.h>
7a4f511b 10#include <asm/arch/hardware.h>
91172baf 11#include <asm/io.h>
7a4f511b 12
8f5d4687
HM
13DECLARE_GLOBAL_DATA_PTR;
14
7a4f511b
DB
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
b7e6843f 27#define PLLC_PLLDIV7 0x16c
7a4f511b
DB
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
5342a710
SP
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
91172baf 51#ifdef CONFIG_SOC_DA8XX
b7e6843f
SR
52unsigned int sysdiv[9] = {
53 PLLC_PLLDIV1, PLLC_PLLDIV2, PLLC_PLLDIV3, PLLC_PLLDIV4, PLLC_PLLDIV5,
54 PLLC_PLLDIV6, PLLC_PLLDIV7, PLLC_PLLDIV8, PLLC_PLLDIV9
91172baf
SN
55};
56
57int clk_get(enum davinci_clk_ids id)
58{
59 int pre_div;
60 int pllm;
61 int post_div;
62 int pll_out;
b7e6843f 63 unsigned int pll_base;
91172baf
SN
64
65 pll_out = CONFIG_SYS_OSCIN_FREQ;
66
67 if (id == DAVINCI_AUXCLK_CLKID)
68 goto out;
69
b7e6843f
SR
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
91172baf
SN
77 /*
78 * Lets keep this simple. Combining operations can result in
79 * unexpected approximations
80 */
b7e6843f
SR
81 pre_div = (readl(pll_base + PLLC_PREDIV) &
82 DAVINCI_PLLC_DIV_MASK) + 1;
83 pllm = readl(pll_base + PLLC_PLLM) + 1;
91172baf
SN
84
85 pll_out /= pre_div;
86 pll_out *= pllm;
87
88 if (id == DAVINCI_PLLM_CLKID)
89 goto out;
90
b7e6843f
SR
91 post_div = (readl(pll_base + PLLC_POSTDIV) &
92 DAVINCI_PLLC_DIV_MASK) + 1;
91172baf
SN
93
94 pll_out /= post_div;
95
96 if (id == DAVINCI_PLLC_CLKID)
97 goto out;
98
b7e6843f
SR
99 pll_out /= (readl(pll_base + sysdiv[id - 1]) &
100 DAVINCI_PLLC_DIV_MASK) + 1;
91172baf
SN
101
102out:
103 return pll_out;
104}
be7d2578
LW
105
106int 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
0a0522cb 116#else /* CONFIG_SOC_DA8XX */
7a4f511b 117
7a4f511b
DB
118static 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
126static 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);
29b0bef5
HS
134#elif defined(CONFIG_SOC_DM365)
135 return pll_div(pllbase, PLLC_PREDIV);
7a4f511b
DB
136#endif
137 return 1;
138}
139
140static inline unsigned pll_postdiv(volatile void *pllbase)
141{
29b0bef5 142#if defined(CONFIG_SOC_DM355) || defined(CONFIG_SOC_DM365)
7a4f511b
DB
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
151static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div)
152{
153 volatile void *pllbase = (volatile void *) pll_addr;
5342a710 154#ifdef CONFIG_SOC_DM646X
fda9c20c 155 unsigned base = CONFIG_REFCLK_FREQ / 1000;
5342a710 156#else
7a4f511b 157 unsigned base = CONFIG_SYS_HZ_CLOCK / 1000;
5342a710 158#endif
7a4f511b
DB
159
160 /* the PLL might be bypassed */
29b0bef5 161 if (readl(pllbase + PLLC_PLLCTL) & BIT(0)) {
7a4f511b 162 base /= pll_prediv(pllbase);
29b0bef5
HS
163#if defined(CONFIG_SOC_DM365)
164 base *= 2 * (readl(pllbase + PLLC_PLLM) & 0x0ff);
165#else
7a4f511b 166 base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff);
29b0bef5 167#endif
7a4f511b
DB
168 base /= pll_postdiv(pllbase);
169 }
170 return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div));
171}
172
5342a710
SP
173#ifdef DAVINCI_DM6467EVM
174unsigned int davinci_arm_clk_get()
175{
176 return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV) * 1000000;
177}
178#endif
29b0bef5
HS
179
180#if defined(CONFIG_SOC_DM365)
181unsigned int davinci_clk_get(unsigned int div)
182{
183 return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, div) * 1000000;
184}
185#endif
7a4f511b 186
8f5d4687
HM
187int set_cpu_clk_info(void)
188{
8f5d4687
HM
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;
be7d2578 207
8f5d4687
HM
208 return 0;
209}
210
be7d2578
LW
211#endif /* !CONFIG_SOC_DA8XX */
212
8453587e
BW
213/*
214 * Initializes on-chip ethernet controllers.
215 * to override, implement board_eth_init()
216 */
217int cpu_eth_init(bd_t *bis)
218{
219#if defined(CONFIG_DRIVER_TI_EMAC)
220 davinci_emac_initialize();
221#endif
222 return 0;
223}