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