1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2601fbec7SMasahiro Yamada /*
3601fbec7SMasahiro Yamada * Copyright (C) 2004 Texas Instruments.
4601fbec7SMasahiro Yamada * Copyright (C) 2009 David Brownell
5601fbec7SMasahiro Yamada */
6601fbec7SMasahiro Yamada
7601fbec7SMasahiro Yamada #include <common.h>
8601fbec7SMasahiro Yamada #include <netdev.h>
9601fbec7SMasahiro Yamada #include <asm/arch/hardware.h>
10601fbec7SMasahiro Yamada #include <asm/io.h>
11601fbec7SMasahiro Yamada
12601fbec7SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR;
13601fbec7SMasahiro Yamada
14601fbec7SMasahiro Yamada /* offsets from PLL controller base */
15601fbec7SMasahiro Yamada #define PLLC_PLLCTL 0x100
16601fbec7SMasahiro Yamada #define PLLC_PLLM 0x110
17601fbec7SMasahiro Yamada #define PLLC_PREDIV 0x114
18601fbec7SMasahiro Yamada #define PLLC_PLLDIV1 0x118
19601fbec7SMasahiro Yamada #define PLLC_PLLDIV2 0x11c
20601fbec7SMasahiro Yamada #define PLLC_PLLDIV3 0x120
21601fbec7SMasahiro Yamada #define PLLC_POSTDIV 0x128
22601fbec7SMasahiro Yamada #define PLLC_BPDIV 0x12c
23601fbec7SMasahiro Yamada #define PLLC_PLLDIV4 0x160
24601fbec7SMasahiro Yamada #define PLLC_PLLDIV5 0x164
25601fbec7SMasahiro Yamada #define PLLC_PLLDIV6 0x168
26601fbec7SMasahiro Yamada #define PLLC_PLLDIV7 0x16c
27601fbec7SMasahiro Yamada #define PLLC_PLLDIV8 0x170
28601fbec7SMasahiro Yamada #define PLLC_PLLDIV9 0x174
29601fbec7SMasahiro Yamada
30601fbec7SMasahiro Yamada /* SOC-specific pll info */
31601fbec7SMasahiro Yamada #ifdef CONFIG_SOC_DM355
32601fbec7SMasahiro Yamada #define ARM_PLLDIV PLLC_PLLDIV1
33601fbec7SMasahiro Yamada #define DDR_PLLDIV PLLC_PLLDIV1
34601fbec7SMasahiro Yamada #endif
35601fbec7SMasahiro Yamada
36601fbec7SMasahiro Yamada #ifdef CONFIG_SOC_DM644X
37601fbec7SMasahiro Yamada #define ARM_PLLDIV PLLC_PLLDIV2
38601fbec7SMasahiro Yamada #define DSP_PLLDIV PLLC_PLLDIV1
39601fbec7SMasahiro Yamada #define DDR_PLLDIV PLLC_PLLDIV2
40601fbec7SMasahiro Yamada #endif
41601fbec7SMasahiro Yamada
42601fbec7SMasahiro Yamada #ifdef CONFIG_SOC_DM646X
43601fbec7SMasahiro Yamada #define DSP_PLLDIV PLLC_PLLDIV1
44601fbec7SMasahiro Yamada #define ARM_PLLDIV PLLC_PLLDIV2
45601fbec7SMasahiro Yamada #define DDR_PLLDIV PLLC_PLLDIV1
46601fbec7SMasahiro Yamada #endif
47601fbec7SMasahiro Yamada
48601fbec7SMasahiro Yamada #ifdef CONFIG_SOC_DA8XX
49601fbec7SMasahiro Yamada unsigned int sysdiv[9] = {
50601fbec7SMasahiro Yamada PLLC_PLLDIV1, PLLC_PLLDIV2, PLLC_PLLDIV3, PLLC_PLLDIV4, PLLC_PLLDIV5,
51601fbec7SMasahiro Yamada PLLC_PLLDIV6, PLLC_PLLDIV7, PLLC_PLLDIV8, PLLC_PLLDIV9
52601fbec7SMasahiro Yamada };
53601fbec7SMasahiro Yamada
clk_get(enum davinci_clk_ids id)54601fbec7SMasahiro Yamada int clk_get(enum davinci_clk_ids id)
55601fbec7SMasahiro Yamada {
56601fbec7SMasahiro Yamada int pre_div;
57601fbec7SMasahiro Yamada int pllm;
58601fbec7SMasahiro Yamada int post_div;
59601fbec7SMasahiro Yamada int pll_out;
60601fbec7SMasahiro Yamada unsigned int pll_base;
61601fbec7SMasahiro Yamada
62601fbec7SMasahiro Yamada pll_out = CONFIG_SYS_OSCIN_FREQ;
63601fbec7SMasahiro Yamada
64601fbec7SMasahiro Yamada if (id == DAVINCI_AUXCLK_CLKID)
65601fbec7SMasahiro Yamada goto out;
66601fbec7SMasahiro Yamada
67601fbec7SMasahiro Yamada if ((id >> 16) == 1)
68601fbec7SMasahiro Yamada pll_base = (unsigned int)davinci_pllc1_regs;
69601fbec7SMasahiro Yamada else
70601fbec7SMasahiro Yamada pll_base = (unsigned int)davinci_pllc0_regs;
71601fbec7SMasahiro Yamada
72601fbec7SMasahiro Yamada id &= 0xFFFF;
73601fbec7SMasahiro Yamada
74601fbec7SMasahiro Yamada /*
75601fbec7SMasahiro Yamada * Lets keep this simple. Combining operations can result in
76601fbec7SMasahiro Yamada * unexpected approximations
77601fbec7SMasahiro Yamada */
78601fbec7SMasahiro Yamada pre_div = (readl(pll_base + PLLC_PREDIV) &
79601fbec7SMasahiro Yamada DAVINCI_PLLC_DIV_MASK) + 1;
80601fbec7SMasahiro Yamada pllm = readl(pll_base + PLLC_PLLM) + 1;
81601fbec7SMasahiro Yamada
82601fbec7SMasahiro Yamada pll_out /= pre_div;
83601fbec7SMasahiro Yamada pll_out *= pllm;
84601fbec7SMasahiro Yamada
85601fbec7SMasahiro Yamada if (id == DAVINCI_PLLM_CLKID)
86601fbec7SMasahiro Yamada goto out;
87601fbec7SMasahiro Yamada
88601fbec7SMasahiro Yamada post_div = (readl(pll_base + PLLC_POSTDIV) &
89601fbec7SMasahiro Yamada DAVINCI_PLLC_DIV_MASK) + 1;
90601fbec7SMasahiro Yamada
91601fbec7SMasahiro Yamada pll_out /= post_div;
92601fbec7SMasahiro Yamada
93601fbec7SMasahiro Yamada if (id == DAVINCI_PLLC_CLKID)
94601fbec7SMasahiro Yamada goto out;
95601fbec7SMasahiro Yamada
96601fbec7SMasahiro Yamada pll_out /= (readl(pll_base + sysdiv[id - 1]) &
97601fbec7SMasahiro Yamada DAVINCI_PLLC_DIV_MASK) + 1;
98601fbec7SMasahiro Yamada
99601fbec7SMasahiro Yamada out:
100601fbec7SMasahiro Yamada return pll_out;
101601fbec7SMasahiro Yamada }
102601fbec7SMasahiro Yamada
set_cpu_clk_info(void)103601fbec7SMasahiro Yamada int set_cpu_clk_info(void)
104601fbec7SMasahiro Yamada {
105601fbec7SMasahiro Yamada gd->bd->bi_arm_freq = clk_get(DAVINCI_ARM_CLKID) / 1000000;
106601fbec7SMasahiro Yamada /* DDR PHY uses an x2 input clock */
107601fbec7SMasahiro Yamada gd->bd->bi_ddr_freq = cpu_is_da830() ? 0 :
108601fbec7SMasahiro Yamada (clk_get(DAVINCI_DDR_CLKID) / 1000000);
109601fbec7SMasahiro Yamada gd->bd->bi_dsp_freq = 0;
110601fbec7SMasahiro Yamada return 0;
111601fbec7SMasahiro Yamada }
112601fbec7SMasahiro Yamada
113601fbec7SMasahiro Yamada #else /* CONFIG_SOC_DA8XX */
114601fbec7SMasahiro Yamada
pll_div(volatile void * pllbase,unsigned offset)115601fbec7SMasahiro Yamada static unsigned pll_div(volatile void *pllbase, unsigned offset)
116601fbec7SMasahiro Yamada {
117601fbec7SMasahiro Yamada u32 div;
118601fbec7SMasahiro Yamada
119601fbec7SMasahiro Yamada div = REG(pllbase + offset);
120601fbec7SMasahiro Yamada return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1;
121601fbec7SMasahiro Yamada }
122601fbec7SMasahiro Yamada
pll_prediv(volatile void * pllbase)123601fbec7SMasahiro Yamada static inline unsigned pll_prediv(volatile void *pllbase)
124601fbec7SMasahiro Yamada {
125601fbec7SMasahiro Yamada #ifdef CONFIG_SOC_DM355
126601fbec7SMasahiro Yamada /* this register read seems to fail on pll0 */
127601fbec7SMasahiro Yamada if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE)
128601fbec7SMasahiro Yamada return 8;
129601fbec7SMasahiro Yamada else
130601fbec7SMasahiro Yamada return pll_div(pllbase, PLLC_PREDIV);
131601fbec7SMasahiro Yamada #elif defined(CONFIG_SOC_DM365)
132601fbec7SMasahiro Yamada return pll_div(pllbase, PLLC_PREDIV);
133601fbec7SMasahiro Yamada #endif
134601fbec7SMasahiro Yamada return 1;
135601fbec7SMasahiro Yamada }
136601fbec7SMasahiro Yamada
pll_postdiv(volatile void * pllbase)137601fbec7SMasahiro Yamada static inline unsigned pll_postdiv(volatile void *pllbase)
138601fbec7SMasahiro Yamada {
139601fbec7SMasahiro Yamada #if defined(CONFIG_SOC_DM355) || defined(CONFIG_SOC_DM365)
140601fbec7SMasahiro Yamada return pll_div(pllbase, PLLC_POSTDIV);
141601fbec7SMasahiro Yamada #elif defined(CONFIG_SOC_DM6446)
142601fbec7SMasahiro Yamada if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE)
143601fbec7SMasahiro Yamada return pll_div(pllbase, PLLC_POSTDIV);
144601fbec7SMasahiro Yamada #endif
145601fbec7SMasahiro Yamada return 1;
146601fbec7SMasahiro Yamada }
147601fbec7SMasahiro Yamada
pll_sysclk_mhz(unsigned pll_addr,unsigned div)148601fbec7SMasahiro Yamada static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div)
149601fbec7SMasahiro Yamada {
150601fbec7SMasahiro Yamada volatile void *pllbase = (volatile void *) pll_addr;
151601fbec7SMasahiro Yamada #ifdef CONFIG_SOC_DM646X
152601fbec7SMasahiro Yamada unsigned base = CONFIG_REFCLK_FREQ / 1000;
153601fbec7SMasahiro Yamada #else
154601fbec7SMasahiro Yamada unsigned base = CONFIG_SYS_HZ_CLOCK / 1000;
155601fbec7SMasahiro Yamada #endif
156601fbec7SMasahiro Yamada
157601fbec7SMasahiro Yamada /* the PLL might be bypassed */
158601fbec7SMasahiro Yamada if (readl(pllbase + PLLC_PLLCTL) & BIT(0)) {
159601fbec7SMasahiro Yamada base /= pll_prediv(pllbase);
160601fbec7SMasahiro Yamada #if defined(CONFIG_SOC_DM365)
161601fbec7SMasahiro Yamada base *= 2 * (readl(pllbase + PLLC_PLLM) & 0x0ff);
162601fbec7SMasahiro Yamada #else
163601fbec7SMasahiro Yamada base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff);
164601fbec7SMasahiro Yamada #endif
165601fbec7SMasahiro Yamada base /= pll_postdiv(pllbase);
166601fbec7SMasahiro Yamada }
167601fbec7SMasahiro Yamada return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div));
168601fbec7SMasahiro Yamada }
169601fbec7SMasahiro Yamada
170601fbec7SMasahiro Yamada #ifdef DAVINCI_DM6467EVM
davinci_arm_clk_get()171601fbec7SMasahiro Yamada unsigned int davinci_arm_clk_get()
172601fbec7SMasahiro Yamada {
173601fbec7SMasahiro Yamada return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV) * 1000000;
174601fbec7SMasahiro Yamada }
175601fbec7SMasahiro Yamada #endif
176601fbec7SMasahiro Yamada
177601fbec7SMasahiro Yamada #if defined(CONFIG_SOC_DM365)
davinci_clk_get(unsigned int div)178601fbec7SMasahiro Yamada unsigned int davinci_clk_get(unsigned int div)
179601fbec7SMasahiro Yamada {
180601fbec7SMasahiro Yamada return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, div) * 1000000;
181601fbec7SMasahiro Yamada }
182601fbec7SMasahiro Yamada #endif
183601fbec7SMasahiro Yamada
set_cpu_clk_info(void)184601fbec7SMasahiro Yamada int set_cpu_clk_info(void)
185601fbec7SMasahiro Yamada {
186601fbec7SMasahiro Yamada unsigned int pllbase = DAVINCI_PLL_CNTRL0_BASE;
187601fbec7SMasahiro Yamada #if defined(CONFIG_SOC_DM365)
188601fbec7SMasahiro Yamada pllbase = DAVINCI_PLL_CNTRL1_BASE;
189601fbec7SMasahiro Yamada #endif
190601fbec7SMasahiro Yamada gd->bd->bi_arm_freq = pll_sysclk_mhz(pllbase, ARM_PLLDIV);
191601fbec7SMasahiro Yamada
192601fbec7SMasahiro Yamada #ifdef DSP_PLLDIV
193601fbec7SMasahiro Yamada gd->bd->bi_dsp_freq =
194601fbec7SMasahiro Yamada pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, DSP_PLLDIV);
195601fbec7SMasahiro Yamada #else
196601fbec7SMasahiro Yamada gd->bd->bi_dsp_freq = 0;
197601fbec7SMasahiro Yamada #endif
198601fbec7SMasahiro Yamada
199601fbec7SMasahiro Yamada pllbase = DAVINCI_PLL_CNTRL1_BASE;
200601fbec7SMasahiro Yamada #if defined(CONFIG_SOC_DM365)
201601fbec7SMasahiro Yamada pllbase = DAVINCI_PLL_CNTRL0_BASE;
202601fbec7SMasahiro Yamada #endif
203601fbec7SMasahiro Yamada gd->bd->bi_ddr_freq = pll_sysclk_mhz(pllbase, DDR_PLLDIV) / 2;
204601fbec7SMasahiro Yamada
205601fbec7SMasahiro Yamada return 0;
206601fbec7SMasahiro Yamada }
207601fbec7SMasahiro Yamada
208601fbec7SMasahiro Yamada #endif /* !CONFIG_SOC_DA8XX */
209601fbec7SMasahiro Yamada
210601fbec7SMasahiro Yamada /*
211601fbec7SMasahiro Yamada * Initializes on-chip ethernet controllers.
212601fbec7SMasahiro Yamada * to override, implement board_eth_init()
213601fbec7SMasahiro Yamada */
cpu_eth_init(bd_t * bis)214601fbec7SMasahiro Yamada int cpu_eth_init(bd_t *bis)
215601fbec7SMasahiro Yamada {
216601fbec7SMasahiro Yamada #if defined(CONFIG_DRIVER_TI_EMAC)
217601fbec7SMasahiro Yamada davinci_emac_initialize();
218601fbec7SMasahiro Yamada #endif
219601fbec7SMasahiro Yamada return 0;
220601fbec7SMasahiro Yamada }
221