162011840SMasahiro Yamada /* 262011840SMasahiro Yamada * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] 362011840SMasahiro Yamada * 462011840SMasahiro Yamada * Copyright (C) 2011 Andreas Bießmann 562011840SMasahiro Yamada * Copyright (C) 2005 David Brownell 662011840SMasahiro Yamada * Copyright (C) 2005 Ivan Kokshaysky 762011840SMasahiro Yamada * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> 862011840SMasahiro Yamada * 962011840SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 1062011840SMasahiro Yamada */ 1162011840SMasahiro Yamada #include <common.h> 1262011840SMasahiro Yamada #include <asm/io.h> 1362011840SMasahiro Yamada #include <asm/arch/hardware.h> 1462011840SMasahiro Yamada #include <asm/arch/at91_pmc.h> 1562011840SMasahiro Yamada #include <asm/arch/clk.h> 1662011840SMasahiro Yamada 1762011840SMasahiro Yamada #if !defined(CONFIG_AT91FAMILY) 1862011840SMasahiro Yamada # error You need to define CONFIG_AT91FAMILY in your board config! 1962011840SMasahiro Yamada #endif 2062011840SMasahiro Yamada 21*be5e485cSWenyou Yang #define EN_PLLB_TIMEOUT 500 22*be5e485cSWenyou Yang 2362011840SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR; 2462011840SMasahiro Yamada 2562011840SMasahiro Yamada static unsigned long at91_css_to_rate(unsigned long css) 2662011840SMasahiro Yamada { 2762011840SMasahiro Yamada switch (css) { 2862011840SMasahiro Yamada case AT91_PMC_MCKR_CSS_SLOW: 2962011840SMasahiro Yamada return CONFIG_SYS_AT91_SLOW_CLOCK; 3062011840SMasahiro Yamada case AT91_PMC_MCKR_CSS_MAIN: 3162011840SMasahiro Yamada return gd->arch.main_clk_rate_hz; 3262011840SMasahiro Yamada case AT91_PMC_MCKR_CSS_PLLA: 3362011840SMasahiro Yamada return gd->arch.plla_rate_hz; 3462011840SMasahiro Yamada case AT91_PMC_MCKR_CSS_PLLB: 3562011840SMasahiro Yamada return gd->arch.pllb_rate_hz; 3662011840SMasahiro Yamada } 3762011840SMasahiro Yamada 3862011840SMasahiro Yamada return 0; 3962011840SMasahiro Yamada } 4062011840SMasahiro Yamada 4162011840SMasahiro Yamada #ifdef CONFIG_USB_ATMEL 4262011840SMasahiro Yamada static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq) 4362011840SMasahiro Yamada { 4462011840SMasahiro Yamada unsigned i, div = 0, mul = 0, diff = 1 << 30; 4562011840SMasahiro Yamada unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; 4662011840SMasahiro Yamada 4762011840SMasahiro Yamada /* PLL output max 240 MHz (or 180 MHz per errata) */ 4862011840SMasahiro Yamada if (out_freq > 240000000) 4962011840SMasahiro Yamada goto fail; 5062011840SMasahiro Yamada 5162011840SMasahiro Yamada for (i = 1; i < 256; i++) { 5262011840SMasahiro Yamada int diff1; 5362011840SMasahiro Yamada unsigned input, mul1; 5462011840SMasahiro Yamada 5562011840SMasahiro Yamada /* 5662011840SMasahiro Yamada * PLL input between 1MHz and 32MHz per spec, but lower 5762011840SMasahiro Yamada * frequences seem necessary in some cases so allow 100K. 5862011840SMasahiro Yamada * Warning: some newer products need 2MHz min. 5962011840SMasahiro Yamada */ 6062011840SMasahiro Yamada input = main_freq / i; 6162011840SMasahiro Yamada if (input < 100000) 6262011840SMasahiro Yamada continue; 6362011840SMasahiro Yamada if (input > 32000000) 6462011840SMasahiro Yamada continue; 6562011840SMasahiro Yamada 6662011840SMasahiro Yamada mul1 = out_freq / input; 6762011840SMasahiro Yamada if (mul1 > 2048) 6862011840SMasahiro Yamada continue; 6962011840SMasahiro Yamada if (mul1 < 2) 7062011840SMasahiro Yamada goto fail; 7162011840SMasahiro Yamada 7262011840SMasahiro Yamada diff1 = out_freq - input * mul1; 7362011840SMasahiro Yamada if (diff1 < 0) 7462011840SMasahiro Yamada diff1 = -diff1; 7562011840SMasahiro Yamada if (diff > diff1) { 7662011840SMasahiro Yamada diff = diff1; 7762011840SMasahiro Yamada div = i; 7862011840SMasahiro Yamada mul = mul1; 7962011840SMasahiro Yamada if (diff == 0) 8062011840SMasahiro Yamada break; 8162011840SMasahiro Yamada } 8262011840SMasahiro Yamada } 8362011840SMasahiro Yamada if (i == 256 && diff > (out_freq >> 5)) 8462011840SMasahiro Yamada goto fail; 8562011840SMasahiro Yamada return ret | ((mul - 1) << 16) | div; 8662011840SMasahiro Yamada fail: 8762011840SMasahiro Yamada return 0; 8862011840SMasahiro Yamada } 8962011840SMasahiro Yamada #endif 9062011840SMasahiro Yamada 9162011840SMasahiro Yamada static u32 at91_pll_rate(u32 freq, u32 reg) 9262011840SMasahiro Yamada { 9362011840SMasahiro Yamada unsigned mul, div; 9462011840SMasahiro Yamada 9562011840SMasahiro Yamada div = reg & 0xff; 9662011840SMasahiro Yamada mul = (reg >> 16) & 0x7ff; 9762011840SMasahiro Yamada if (div && mul) { 9862011840SMasahiro Yamada freq /= div; 9962011840SMasahiro Yamada freq *= mul + 1; 10062011840SMasahiro Yamada } else 10162011840SMasahiro Yamada freq = 0; 10262011840SMasahiro Yamada 10362011840SMasahiro Yamada return freq; 10462011840SMasahiro Yamada } 10562011840SMasahiro Yamada 10662011840SMasahiro Yamada int at91_clock_init(unsigned long main_clock) 10762011840SMasahiro Yamada { 10862011840SMasahiro Yamada unsigned freq, mckr; 10962011840SMasahiro Yamada at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; 11062011840SMasahiro Yamada #ifndef CONFIG_SYS_AT91_MAIN_CLOCK 11162011840SMasahiro Yamada unsigned tmp; 11262011840SMasahiro Yamada /* 11362011840SMasahiro Yamada * When the bootloader initialized the main oscillator correctly, 11462011840SMasahiro Yamada * there's no problem using the cycle counter. But if it didn't, 11562011840SMasahiro Yamada * or when using oscillator bypass mode, we must be told the speed 11662011840SMasahiro Yamada * of the main clock. 11762011840SMasahiro Yamada */ 11862011840SMasahiro Yamada if (!main_clock) { 11962011840SMasahiro Yamada do { 12062011840SMasahiro Yamada tmp = readl(&pmc->mcfr); 12162011840SMasahiro Yamada } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); 12262011840SMasahiro Yamada tmp &= AT91_PMC_MCFR_MAINF_MASK; 12362011840SMasahiro Yamada main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); 12462011840SMasahiro Yamada } 12562011840SMasahiro Yamada #endif 12662011840SMasahiro Yamada gd->arch.main_clk_rate_hz = main_clock; 12762011840SMasahiro Yamada 12862011840SMasahiro Yamada /* report if PLLA is more than mildly overclocked */ 12962011840SMasahiro Yamada gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); 13062011840SMasahiro Yamada 13162011840SMasahiro Yamada #ifdef CONFIG_USB_ATMEL 13262011840SMasahiro Yamada /* 13362011840SMasahiro Yamada * USB clock init: choose 48 MHz PLLB value, 13462011840SMasahiro Yamada * disable 48MHz clock during usb peripheral suspend. 13562011840SMasahiro Yamada * 13662011840SMasahiro Yamada * REVISIT: assumes MCK doesn't derive from PLLB! 13762011840SMasahiro Yamada */ 13862011840SMasahiro Yamada gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | 13962011840SMasahiro Yamada AT91_PMC_PLLBR_USBDIV_2; 14062011840SMasahiro Yamada gd->arch.pllb_rate_hz = at91_pll_rate(main_clock, 14162011840SMasahiro Yamada gd->arch.at91_pllb_usb_init); 14262011840SMasahiro Yamada #endif 14362011840SMasahiro Yamada 14462011840SMasahiro Yamada /* 14562011840SMasahiro Yamada * MCK and CPU derive from one of those primary clocks. 14662011840SMasahiro Yamada * For now, assume this parentage won't change. 14762011840SMasahiro Yamada */ 14862011840SMasahiro Yamada mckr = readl(&pmc->mckr); 14962011840SMasahiro Yamada gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); 15062011840SMasahiro Yamada freq = gd->arch.mck_rate_hz; 15162011840SMasahiro Yamada 15262011840SMasahiro Yamada freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ 15362011840SMasahiro Yamada /* mdiv */ 15462011840SMasahiro Yamada gd->arch.mck_rate_hz = freq / 15562011840SMasahiro Yamada (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); 15662011840SMasahiro Yamada gd->arch.cpu_clk_rate_hz = freq; 15762011840SMasahiro Yamada 15862011840SMasahiro Yamada return 0; 15962011840SMasahiro Yamada } 160*be5e485cSWenyou Yang 161*be5e485cSWenyou Yang int at91_pllb_clk_enable(u32 pllbr) 162*be5e485cSWenyou Yang { 163*be5e485cSWenyou Yang struct at91_pmc *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; 164*be5e485cSWenyou Yang ulong start_time, tmp_time; 165*be5e485cSWenyou Yang 166*be5e485cSWenyou Yang start_time = get_timer(0); 167*be5e485cSWenyou Yang writel(pllbr, &pmc->pllbr); 168*be5e485cSWenyou Yang while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB) { 169*be5e485cSWenyou Yang tmp_time = get_timer(0); 170*be5e485cSWenyou Yang if ((tmp_time - start_time) > EN_PLLB_TIMEOUT) { 171*be5e485cSWenyou Yang printf("ERROR: failed to enable PLLB\n"); 172*be5e485cSWenyou Yang return -1; 173*be5e485cSWenyou Yang } 174*be5e485cSWenyou Yang } 175*be5e485cSWenyou Yang 176*be5e485cSWenyou Yang return 0; 177*be5e485cSWenyou Yang } 178*be5e485cSWenyou Yang 179*be5e485cSWenyou Yang int at91_pllb_clk_disable(void) 180*be5e485cSWenyou Yang { 181*be5e485cSWenyou Yang struct at91_pmc *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; 182*be5e485cSWenyou Yang ulong start_time, tmp_time; 183*be5e485cSWenyou Yang 184*be5e485cSWenyou Yang start_time = get_timer(0); 185*be5e485cSWenyou Yang writel(0, &pmc->pllbr); 186*be5e485cSWenyou Yang while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != 0) { 187*be5e485cSWenyou Yang tmp_time = get_timer(0); 188*be5e485cSWenyou Yang if ((tmp_time - start_time) > EN_PLLB_TIMEOUT) { 189*be5e485cSWenyou Yang printf("ERROR: failed to disable PLLB\n"); 190*be5e485cSWenyou Yang return -1; 191*be5e485cSWenyou Yang } 192*be5e485cSWenyou Yang } 193*be5e485cSWenyou Yang 194*be5e485cSWenyou Yang return 0; 195*be5e485cSWenyou Yang } 196