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