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