xref: /openbmc/u-boot/arch/arm/mach-davinci/cpu.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
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