162011840SMasahiro Yamada /*
262011840SMasahiro Yamada * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c]
362011840SMasahiro Yamada *
462011840SMasahiro Yamada * Copyright (C) 2005 David Brownell
562011840SMasahiro Yamada * Copyright (C) 2005 Ivan Kokshaysky
662011840SMasahiro Yamada * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
762011840SMasahiro Yamada * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
8c1900055SWenyou Yang * Copyright (C) 2015 Wenyou Yang <wenyou.yang@atmel.com>
962011840SMasahiro Yamada *
1062011840SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+
1162011840SMasahiro Yamada */
1262011840SMasahiro Yamada
1362011840SMasahiro Yamada #include <common.h>
14*1221ce45SMasahiro Yamada #include <linux/errno.h>
1562011840SMasahiro Yamada #include <asm/io.h>
1662011840SMasahiro Yamada #include <asm/arch/hardware.h>
1762011840SMasahiro Yamada #include <asm/arch/at91_pmc.h>
1862011840SMasahiro Yamada #include <asm/arch/clk.h>
1962011840SMasahiro Yamada
2062011840SMasahiro Yamada #if !defined(CONFIG_AT91FAMILY)
2162011840SMasahiro Yamada # error You need to define CONFIG_AT91FAMILY in your board config!
2262011840SMasahiro Yamada #endif
2362011840SMasahiro Yamada
2462011840SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR;
2562011840SMasahiro Yamada
at91_css_to_rate(unsigned long css)2662011840SMasahiro Yamada static unsigned long at91_css_to_rate(unsigned long css)
2762011840SMasahiro Yamada {
2862011840SMasahiro Yamada switch (css) {
2962011840SMasahiro Yamada case AT91_PMC_MCKR_CSS_SLOW:
3062011840SMasahiro Yamada return CONFIG_SYS_AT91_SLOW_CLOCK;
3162011840SMasahiro Yamada case AT91_PMC_MCKR_CSS_MAIN:
3262011840SMasahiro Yamada return gd->arch.main_clk_rate_hz;
3362011840SMasahiro Yamada case AT91_PMC_MCKR_CSS_PLLA:
3462011840SMasahiro Yamada return gd->arch.plla_rate_hz;
3562011840SMasahiro Yamada }
3662011840SMasahiro Yamada
3762011840SMasahiro Yamada return 0;
3862011840SMasahiro Yamada }
3962011840SMasahiro Yamada
at91_pll_rate(u32 freq,u32 reg)4062011840SMasahiro Yamada static u32 at91_pll_rate(u32 freq, u32 reg)
4162011840SMasahiro Yamada {
4262011840SMasahiro Yamada unsigned mul, div;
4362011840SMasahiro Yamada
4462011840SMasahiro Yamada div = reg & 0xff;
4562011840SMasahiro Yamada mul = (reg >> 18) & 0x7f;
4662011840SMasahiro Yamada if (div && mul) {
4762011840SMasahiro Yamada freq /= div;
4862011840SMasahiro Yamada freq *= mul + 1;
4962011840SMasahiro Yamada } else {
5062011840SMasahiro Yamada freq = 0;
5162011840SMasahiro Yamada }
5262011840SMasahiro Yamada
5362011840SMasahiro Yamada return freq;
5462011840SMasahiro Yamada }
5562011840SMasahiro Yamada
at91_clock_init(unsigned long main_clock)5662011840SMasahiro Yamada int at91_clock_init(unsigned long main_clock)
5762011840SMasahiro Yamada {
5862011840SMasahiro Yamada unsigned freq, mckr;
5962011840SMasahiro Yamada struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
6062011840SMasahiro Yamada #ifndef CONFIG_SYS_AT91_MAIN_CLOCK
6162011840SMasahiro Yamada unsigned tmp;
6262011840SMasahiro Yamada /*
6362011840SMasahiro Yamada * When the bootloader initialized the main oscillator correctly,
6462011840SMasahiro Yamada * there's no problem using the cycle counter. But if it didn't,
6562011840SMasahiro Yamada * or when using oscillator bypass mode, we must be told the speed
6662011840SMasahiro Yamada * of the main clock.
6762011840SMasahiro Yamada */
6862011840SMasahiro Yamada if (!main_clock) {
6962011840SMasahiro Yamada do {
7062011840SMasahiro Yamada tmp = readl(&pmc->mcfr);
7162011840SMasahiro Yamada } while (!(tmp & AT91_PMC_MCFR_MAINRDY));
7262011840SMasahiro Yamada tmp &= AT91_PMC_MCFR_MAINF_MASK;
7362011840SMasahiro Yamada main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
7462011840SMasahiro Yamada }
7562011840SMasahiro Yamada #endif
7662011840SMasahiro Yamada gd->arch.main_clk_rate_hz = main_clock;
7762011840SMasahiro Yamada
7862011840SMasahiro Yamada /* report if PLLA is more than mildly overclocked */
7962011840SMasahiro Yamada gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
8062011840SMasahiro Yamada
8162011840SMasahiro Yamada /*
8262011840SMasahiro Yamada * MCK and CPU derive from one of those primary clocks.
8362011840SMasahiro Yamada * For now, assume this parentage won't change.
8462011840SMasahiro Yamada */
8562011840SMasahiro Yamada mckr = readl(&pmc->mckr);
8662011840SMasahiro Yamada
8762011840SMasahiro Yamada /* plla divisor by 2 */
8862011840SMasahiro Yamada if (mckr & (1 << 12))
8962011840SMasahiro Yamada gd->arch.plla_rate_hz >>= 1;
9062011840SMasahiro Yamada
9162011840SMasahiro Yamada gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
9262011840SMasahiro Yamada freq = gd->arch.mck_rate_hz;
9362011840SMasahiro Yamada
9462011840SMasahiro Yamada /* prescale */
9562011840SMasahiro Yamada freq >>= mckr & AT91_PMC_MCKR_PRES_MASK;
9662011840SMasahiro Yamada
9762011840SMasahiro Yamada switch (mckr & AT91_PMC_MCKR_MDIV_MASK) {
9862011840SMasahiro Yamada case AT91_PMC_MCKR_MDIV_2:
9962011840SMasahiro Yamada gd->arch.mck_rate_hz = freq / 2;
10062011840SMasahiro Yamada break;
10162011840SMasahiro Yamada case AT91_PMC_MCKR_MDIV_3:
10262011840SMasahiro Yamada gd->arch.mck_rate_hz = freq / 3;
10362011840SMasahiro Yamada break;
10462011840SMasahiro Yamada case AT91_PMC_MCKR_MDIV_4:
10562011840SMasahiro Yamada gd->arch.mck_rate_hz = freq / 4;
10662011840SMasahiro Yamada break;
10762011840SMasahiro Yamada default:
10862011840SMasahiro Yamada break;
10962011840SMasahiro Yamada }
11062011840SMasahiro Yamada
11162011840SMasahiro Yamada gd->arch.cpu_clk_rate_hz = freq;
11262011840SMasahiro Yamada
11362011840SMasahiro Yamada return 0;
11462011840SMasahiro Yamada }
11562011840SMasahiro Yamada
at91_plla_init(u32 pllar)11662011840SMasahiro Yamada void at91_plla_init(u32 pllar)
11762011840SMasahiro Yamada {
11862011840SMasahiro Yamada struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
11962011840SMasahiro Yamada
12062011840SMasahiro Yamada writel(pllar, &pmc->pllar);
12162011840SMasahiro Yamada while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
12262011840SMasahiro Yamada ;
12362011840SMasahiro Yamada }
12462011840SMasahiro Yamada
at91_mck_init(u32 mckr)12562011840SMasahiro Yamada void at91_mck_init(u32 mckr)
12662011840SMasahiro Yamada {
12762011840SMasahiro Yamada struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
12862011840SMasahiro Yamada u32 tmp;
12962011840SMasahiro Yamada
13062011840SMasahiro Yamada tmp = readl(&pmc->mckr);
13162011840SMasahiro Yamada tmp &= ~(AT91_PMC_MCKR_CSS_MASK |
13262011840SMasahiro Yamada AT91_PMC_MCKR_PRES_MASK |
13362011840SMasahiro Yamada AT91_PMC_MCKR_MDIV_MASK |
13462011840SMasahiro Yamada AT91_PMC_MCKR_PLLADIV_2);
13562011840SMasahiro Yamada #ifdef CPU_HAS_H32MXDIV
13662011840SMasahiro Yamada tmp &= ~AT91_PMC_MCKR_H32MXDIV;
13762011840SMasahiro Yamada #endif
13862011840SMasahiro Yamada
13962011840SMasahiro Yamada tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK |
14062011840SMasahiro Yamada AT91_PMC_MCKR_PRES_MASK |
14162011840SMasahiro Yamada AT91_PMC_MCKR_MDIV_MASK |
14262011840SMasahiro Yamada AT91_PMC_MCKR_PLLADIV_2);
14362011840SMasahiro Yamada #ifdef CPU_HAS_H32MXDIV
14462011840SMasahiro Yamada tmp |= mckr & AT91_PMC_MCKR_H32MXDIV;
14562011840SMasahiro Yamada #endif
14662011840SMasahiro Yamada
14762011840SMasahiro Yamada writel(tmp, &pmc->mckr);
14862011840SMasahiro Yamada
14962011840SMasahiro Yamada while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
15062011840SMasahiro Yamada ;
15162011840SMasahiro Yamada }
15262011840SMasahiro Yamada
at91_enable_periph_generated_clk(u32 id,u32 clk_source,u32 div)153c1900055SWenyou Yang int at91_enable_periph_generated_clk(u32 id, u32 clk_source, u32 div)
154c1900055SWenyou Yang {
155c1900055SWenyou Yang struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
156c1900055SWenyou Yang u32 regval, status;
157c1900055SWenyou Yang u32 timeout = 1000;
158c1900055SWenyou Yang
159c1900055SWenyou Yang if (id > AT91_PMC_PCR_PID_MASK)
160c1900055SWenyou Yang return -EINVAL;
161c1900055SWenyou Yang
162c1900055SWenyou Yang if (div > 0xff)
163c1900055SWenyou Yang return -EINVAL;
164c1900055SWenyou Yang
1654adf6a71SWenyou Yang if (clk_source == GCK_CSS_UPLL_CLK) {
1664adf6a71SWenyou Yang if (at91_upll_clk_enable())
1674adf6a71SWenyou Yang return -ENODEV;
1684adf6a71SWenyou Yang }
1694adf6a71SWenyou Yang
170c1900055SWenyou Yang writel(id, &pmc->pcr);
171c1900055SWenyou Yang regval = readl(&pmc->pcr);
172c1900055SWenyou Yang regval &= ~AT91_PMC_PCR_GCKCSS;
173c1900055SWenyou Yang regval &= ~AT91_PMC_PCR_GCKDIV;
174c1900055SWenyou Yang
175c1900055SWenyou Yang switch (clk_source) {
176c1900055SWenyou Yang case GCK_CSS_SLOW_CLK:
177c1900055SWenyou Yang regval |= AT91_PMC_PCR_GCKCSS_SLOW_CLK;
178c1900055SWenyou Yang break;
179c1900055SWenyou Yang case GCK_CSS_MAIN_CLK:
180c1900055SWenyou Yang regval |= AT91_PMC_PCR_GCKCSS_MAIN_CLK;
181c1900055SWenyou Yang break;
182c1900055SWenyou Yang case GCK_CSS_PLLA_CLK:
183c1900055SWenyou Yang regval |= AT91_PMC_PCR_GCKCSS_PLLA_CLK;
184c1900055SWenyou Yang break;
185c1900055SWenyou Yang case GCK_CSS_UPLL_CLK:
186c1900055SWenyou Yang regval |= AT91_PMC_PCR_GCKCSS_UPLL_CLK;
187c1900055SWenyou Yang break;
188c1900055SWenyou Yang case GCK_CSS_MCK_CLK:
189c1900055SWenyou Yang regval |= AT91_PMC_PCR_GCKCSS_MCK_CLK;
190c1900055SWenyou Yang break;
191c1900055SWenyou Yang case GCK_CSS_AUDIO_CLK:
192c1900055SWenyou Yang regval |= AT91_PMC_PCR_GCKCSS_AUDIO_CLK;
193c1900055SWenyou Yang break;
194c1900055SWenyou Yang default:
195c1900055SWenyou Yang printf("Error GCK clock source selection!\n");
196c1900055SWenyou Yang return -EINVAL;
197c1900055SWenyou Yang }
198c1900055SWenyou Yang
199c1900055SWenyou Yang regval |= AT91_PMC_PCR_CMD_WRITE |
200c1900055SWenyou Yang AT91_PMC_PCR_GCKDIV_(div) |
201c1900055SWenyou Yang AT91_PMC_PCR_GCKEN;
202c1900055SWenyou Yang
203c1900055SWenyou Yang writel(regval, &pmc->pcr);
204c1900055SWenyou Yang
205c1900055SWenyou Yang do {
206c1900055SWenyou Yang udelay(1);
207c1900055SWenyou Yang status = readl(&pmc->sr);
208c1900055SWenyou Yang } while ((!!(--timeout)) && (!(status & AT91_PMC_GCKRDY)));
209c1900055SWenyou Yang
210c1900055SWenyou Yang if (!timeout)
211c1900055SWenyou Yang printf("Timeout waiting for GCK ready!\n");
212c1900055SWenyou Yang
213c1900055SWenyou Yang return 0;
214c1900055SWenyou Yang }
215c1900055SWenyou Yang
at91_get_periph_generated_clk(u32 id)216c1900055SWenyou Yang u32 at91_get_periph_generated_clk(u32 id)
217c1900055SWenyou Yang {
218c1900055SWenyou Yang struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
219c1900055SWenyou Yang u32 regval, clk_source, div;
220c1900055SWenyou Yang u32 freq;
221c1900055SWenyou Yang
222c1900055SWenyou Yang if (id > AT91_PMC_PCR_PID_MASK)
223c1900055SWenyou Yang return 0;
224c1900055SWenyou Yang
225c1900055SWenyou Yang writel(id, &pmc->pcr);
226c1900055SWenyou Yang regval = readl(&pmc->pcr);
227c1900055SWenyou Yang
228c1900055SWenyou Yang clk_source = regval & AT91_PMC_PCR_GCKCSS;
229c1900055SWenyou Yang switch (clk_source) {
230c1900055SWenyou Yang case AT91_PMC_PCR_GCKCSS_SLOW_CLK:
231c1900055SWenyou Yang freq = CONFIG_SYS_AT91_SLOW_CLOCK;
232c1900055SWenyou Yang break;
233c1900055SWenyou Yang case AT91_PMC_PCR_GCKCSS_MAIN_CLK:
234c1900055SWenyou Yang freq = gd->arch.main_clk_rate_hz;
235c1900055SWenyou Yang break;
236c1900055SWenyou Yang case AT91_PMC_PCR_GCKCSS_PLLA_CLK:
237c1900055SWenyou Yang freq = gd->arch.plla_rate_hz;
238c1900055SWenyou Yang break;
2397a91e1a3SWenyou Yang case AT91_PMC_PCR_GCKCSS_UPLL_CLK:
2407a91e1a3SWenyou Yang freq = AT91_UTMI_PLL_CLK_FREQ;
2417a91e1a3SWenyou Yang break;
2427a91e1a3SWenyou Yang case AT91_PMC_PCR_GCKCSS_MCK_CLK:
2437a91e1a3SWenyou Yang freq = gd->arch.mck_rate_hz;
2447a91e1a3SWenyou Yang break;
245c1900055SWenyou Yang default:
246c1900055SWenyou Yang printf("Improper GCK clock source selection!\n");
247c1900055SWenyou Yang freq = 0;
248c1900055SWenyou Yang break;
249c1900055SWenyou Yang }
250c1900055SWenyou Yang
251c1900055SWenyou Yang div = ((regval & AT91_PMC_PCR_GCKDIV) >> AT91_PMC_PCR_GCKDIV_OFFSET);
252c1900055SWenyou Yang div += 1;
253c1900055SWenyou Yang
254c1900055SWenyou Yang return freq / div;
255c1900055SWenyou Yang }
256