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