1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] 4 * 5 * Copyright (C) 2011 Andreas Bießmann 6 * Copyright (C) 2005 David Brownell 7 * Copyright (C) 2005 Ivan Kokshaysky 8 * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> 9 */ 10 #include <common.h> 11 #include <asm/io.h> 12 #include <asm/arch/hardware.h> 13 #include <asm/arch/at91_pmc.h> 14 #include <asm/arch/clk.h> 15 16 #if !defined(CONFIG_AT91FAMILY) 17 # error You need to define CONFIG_AT91FAMILY in your board config! 18 #endif 19 20 #define EN_PLLB_TIMEOUT 500 21 22 DECLARE_GLOBAL_DATA_PTR; 23 24 static unsigned long at91_css_to_rate(unsigned long css) 25 { 26 switch (css) { 27 case AT91_PMC_MCKR_CSS_SLOW: 28 return CONFIG_SYS_AT91_SLOW_CLOCK; 29 case AT91_PMC_MCKR_CSS_MAIN: 30 return gd->arch.main_clk_rate_hz; 31 case AT91_PMC_MCKR_CSS_PLLA: 32 return gd->arch.plla_rate_hz; 33 case AT91_PMC_MCKR_CSS_PLLB: 34 return gd->arch.pllb_rate_hz; 35 } 36 37 return 0; 38 } 39 40 #ifdef CONFIG_USB_ATMEL 41 static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq) 42 { 43 unsigned i, div = 0, mul = 0, diff = 1 << 30; 44 unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; 45 46 /* PLL output max 240 MHz (or 180 MHz per errata) */ 47 if (out_freq > 240000000) 48 goto fail; 49 50 for (i = 1; i < 256; i++) { 51 int diff1; 52 unsigned input, mul1; 53 54 /* 55 * PLL input between 1MHz and 32MHz per spec, but lower 56 * frequences seem necessary in some cases so allow 100K. 57 * Warning: some newer products need 2MHz min. 58 */ 59 input = main_freq / i; 60 if (input < 100000) 61 continue; 62 if (input > 32000000) 63 continue; 64 65 mul1 = out_freq / input; 66 if (mul1 > 2048) 67 continue; 68 if (mul1 < 2) 69 goto fail; 70 71 diff1 = out_freq - input * mul1; 72 if (diff1 < 0) 73 diff1 = -diff1; 74 if (diff > diff1) { 75 diff = diff1; 76 div = i; 77 mul = mul1; 78 if (diff == 0) 79 break; 80 } 81 } 82 if (i == 256 && diff > (out_freq >> 5)) 83 goto fail; 84 return ret | ((mul - 1) << 16) | div; 85 fail: 86 return 0; 87 } 88 #endif 89 90 static u32 at91_pll_rate(u32 freq, u32 reg) 91 { 92 unsigned mul, div; 93 94 div = reg & 0xff; 95 mul = (reg >> 16) & 0x7ff; 96 if (div && mul) { 97 freq /= div; 98 freq *= mul + 1; 99 } else 100 freq = 0; 101 102 return freq; 103 } 104 105 int at91_clock_init(unsigned long main_clock) 106 { 107 unsigned freq, mckr; 108 at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; 109 #ifndef CONFIG_SYS_AT91_MAIN_CLOCK 110 unsigned tmp; 111 /* 112 * When the bootloader initialized the main oscillator correctly, 113 * there's no problem using the cycle counter. But if it didn't, 114 * or when using oscillator bypass mode, we must be told the speed 115 * of the main clock. 116 */ 117 if (!main_clock) { 118 do { 119 tmp = readl(&pmc->mcfr); 120 } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); 121 tmp &= AT91_PMC_MCFR_MAINF_MASK; 122 main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); 123 } 124 #endif 125 gd->arch.main_clk_rate_hz = main_clock; 126 127 /* report if PLLA is more than mildly overclocked */ 128 gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); 129 130 #ifdef CONFIG_USB_ATMEL 131 /* 132 * USB clock init: choose 48 MHz PLLB value, 133 * disable 48MHz clock during usb peripheral suspend. 134 * 135 * REVISIT: assumes MCK doesn't derive from PLLB! 136 */ 137 gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | 138 AT91_PMC_PLLBR_USBDIV_2; 139 gd->arch.pllb_rate_hz = at91_pll_rate(main_clock, 140 gd->arch.at91_pllb_usb_init); 141 #endif 142 143 /* 144 * MCK and CPU derive from one of those primary clocks. 145 * For now, assume this parentage won't change. 146 */ 147 mckr = readl(&pmc->mckr); 148 gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); 149 freq = gd->arch.mck_rate_hz; 150 151 freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ 152 /* mdiv */ 153 gd->arch.mck_rate_hz = freq / 154 (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); 155 gd->arch.cpu_clk_rate_hz = freq; 156 157 return 0; 158 } 159 160 int at91_pllb_clk_enable(u32 pllbr) 161 { 162 struct at91_pmc *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; 163 ulong start_time, tmp_time; 164 165 start_time = get_timer(0); 166 writel(pllbr, &pmc->pllbr); 167 while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB) { 168 tmp_time = get_timer(0); 169 if ((tmp_time - start_time) > EN_PLLB_TIMEOUT) { 170 printf("ERROR: failed to enable PLLB\n"); 171 return -1; 172 } 173 } 174 175 return 0; 176 } 177 178 int at91_pllb_clk_disable(void) 179 { 180 struct at91_pmc *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; 181 ulong start_time, tmp_time; 182 183 start_time = get_timer(0); 184 writel(0, &pmc->pllbr); 185 while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != 0) { 186 tmp_time = get_timer(0); 187 if ((tmp_time - start_time) > EN_PLLB_TIMEOUT) { 188 printf("ERROR: failed to disable PLLB\n"); 189 return -1; 190 } 191 } 192 193 return 0; 194 } 195