1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Freescale i.MX23/i.MX28 clock setup code 4 * 5 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 6 * on behalf of DENX Software Engineering GmbH 7 * 8 * Based on code from LTIB: 9 * Copyright (C) 2010 Freescale Semiconductor, Inc. 10 */ 11 12 #include <common.h> 13 #include <linux/errno.h> 14 #include <asm/io.h> 15 #include <asm/arch/clock.h> 16 #include <asm/arch/imx-regs.h> 17 18 /* 19 * The PLL frequency is 480MHz and XTAL frequency is 24MHz 20 * iMX23: datasheet section 4.2 21 * iMX28: datasheet section 10.2 22 */ 23 #define PLL_FREQ_KHZ 480000 24 #define PLL_FREQ_COEF 18 25 #define XTAL_FREQ_KHZ 24000 26 27 #define PLL_FREQ_MHZ (PLL_FREQ_KHZ / 1000) 28 #define XTAL_FREQ_MHZ (XTAL_FREQ_KHZ / 1000) 29 30 #if defined(CONFIG_MX23) 31 #define MXC_SSPCLK_MAX MXC_SSPCLK0 32 #elif defined(CONFIG_MX28) 33 #define MXC_SSPCLK_MAX MXC_SSPCLK3 34 #endif 35 36 static uint32_t mxs_get_pclk(void) 37 { 38 struct mxs_clkctrl_regs *clkctrl_regs = 39 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 40 41 uint32_t clkctrl, clkseq, div; 42 uint8_t clkfrac, frac; 43 44 clkctrl = readl(&clkctrl_regs->hw_clkctrl_cpu); 45 46 /* No support of fractional divider calculation */ 47 if (clkctrl & 48 (CLKCTRL_CPU_DIV_XTAL_FRAC_EN | CLKCTRL_CPU_DIV_CPU_FRAC_EN)) { 49 return 0; 50 } 51 52 clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq); 53 54 /* XTAL Path */ 55 if (clkseq & CLKCTRL_CLKSEQ_BYPASS_CPU) { 56 div = (clkctrl & CLKCTRL_CPU_DIV_XTAL_MASK) >> 57 CLKCTRL_CPU_DIV_XTAL_OFFSET; 58 return XTAL_FREQ_MHZ / div; 59 } 60 61 /* REF Path */ 62 clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]); 63 frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK; 64 div = clkctrl & CLKCTRL_CPU_DIV_CPU_MASK; 65 return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div; 66 } 67 68 static uint32_t mxs_get_hclk(void) 69 { 70 struct mxs_clkctrl_regs *clkctrl_regs = 71 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 72 73 uint32_t div; 74 uint32_t clkctrl; 75 76 clkctrl = readl(&clkctrl_regs->hw_clkctrl_hbus); 77 78 /* No support of fractional divider calculation */ 79 if (clkctrl & CLKCTRL_HBUS_DIV_FRAC_EN) 80 return 0; 81 82 div = clkctrl & CLKCTRL_HBUS_DIV_MASK; 83 return mxs_get_pclk() / div; 84 } 85 86 static uint32_t mxs_get_emiclk(void) 87 { 88 struct mxs_clkctrl_regs *clkctrl_regs = 89 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 90 91 uint32_t clkctrl, clkseq, div; 92 uint8_t clkfrac, frac; 93 94 clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq); 95 clkctrl = readl(&clkctrl_regs->hw_clkctrl_emi); 96 97 /* XTAL Path */ 98 if (clkseq & CLKCTRL_CLKSEQ_BYPASS_EMI) { 99 div = (clkctrl & CLKCTRL_EMI_DIV_XTAL_MASK) >> 100 CLKCTRL_EMI_DIV_XTAL_OFFSET; 101 return XTAL_FREQ_MHZ / div; 102 } 103 104 /* REF Path */ 105 clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]); 106 frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK; 107 div = clkctrl & CLKCTRL_EMI_DIV_EMI_MASK; 108 return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div; 109 } 110 111 static uint32_t mxs_get_gpmiclk(void) 112 { 113 struct mxs_clkctrl_regs *clkctrl_regs = 114 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 115 #if defined(CONFIG_MX23) 116 uint8_t *reg = 117 &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]; 118 #elif defined(CONFIG_MX28) 119 uint8_t *reg = 120 &clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_GPMI]; 121 #endif 122 uint32_t clkctrl, clkseq, div; 123 uint8_t clkfrac, frac; 124 125 clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq); 126 clkctrl = readl(&clkctrl_regs->hw_clkctrl_gpmi); 127 128 /* XTAL Path */ 129 if (clkseq & CLKCTRL_CLKSEQ_BYPASS_GPMI) { 130 div = clkctrl & CLKCTRL_GPMI_DIV_MASK; 131 return XTAL_FREQ_MHZ / div; 132 } 133 134 /* REF Path */ 135 clkfrac = readb(reg); 136 frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK; 137 div = clkctrl & CLKCTRL_GPMI_DIV_MASK; 138 return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div; 139 } 140 141 /* 142 * Set IO clock frequency, in kHz 143 */ 144 void mxs_set_ioclk(enum mxs_ioclock io, uint32_t freq) 145 { 146 struct mxs_clkctrl_regs *clkctrl_regs = 147 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 148 uint32_t div; 149 int io_reg; 150 151 if (freq == 0) 152 return; 153 154 if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1)) 155 return; 156 157 div = (PLL_FREQ_KHZ * PLL_FREQ_COEF) / freq; 158 159 if (div < 18) 160 div = 18; 161 162 if (div > 35) 163 div = 35; 164 165 io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */ 166 writeb(CLKCTRL_FRAC_CLKGATE, 167 &clkctrl_regs->hw_clkctrl_frac0_set[io_reg]); 168 writeb(CLKCTRL_FRAC_CLKGATE | (div & CLKCTRL_FRAC_FRAC_MASK), 169 &clkctrl_regs->hw_clkctrl_frac0[io_reg]); 170 writeb(CLKCTRL_FRAC_CLKGATE, 171 &clkctrl_regs->hw_clkctrl_frac0_clr[io_reg]); 172 } 173 174 /* 175 * Get IO clock, returns IO clock in kHz 176 */ 177 static uint32_t mxs_get_ioclk(enum mxs_ioclock io) 178 { 179 struct mxs_clkctrl_regs *clkctrl_regs = 180 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 181 uint8_t ret; 182 int io_reg; 183 184 if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1)) 185 return 0; 186 187 io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */ 188 189 ret = readb(&clkctrl_regs->hw_clkctrl_frac0[io_reg]) & 190 CLKCTRL_FRAC_FRAC_MASK; 191 192 return (PLL_FREQ_KHZ * PLL_FREQ_COEF) / ret; 193 } 194 195 /* 196 * Configure SSP clock frequency, in kHz 197 */ 198 void mxs_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal) 199 { 200 struct mxs_clkctrl_regs *clkctrl_regs = 201 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 202 uint32_t clk, clkreg; 203 204 if (ssp > MXC_SSPCLK_MAX) 205 return; 206 207 clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) + 208 (ssp * sizeof(struct mxs_register_32)); 209 210 clrbits_le32(clkreg, CLKCTRL_SSP_CLKGATE); 211 while (readl(clkreg) & CLKCTRL_SSP_CLKGATE) 212 ; 213 214 if (xtal) 215 clk = XTAL_FREQ_KHZ; 216 else 217 clk = mxs_get_ioclk(ssp >> 1); 218 219 if (freq > clk) 220 return; 221 222 /* Calculate the divider and cap it if necessary */ 223 clk /= freq; 224 if (clk > CLKCTRL_SSP_DIV_MASK) 225 clk = CLKCTRL_SSP_DIV_MASK; 226 227 clrsetbits_le32(clkreg, CLKCTRL_SSP_DIV_MASK, clk); 228 while (readl(clkreg) & CLKCTRL_SSP_BUSY) 229 ; 230 231 if (xtal) 232 writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp, 233 &clkctrl_regs->hw_clkctrl_clkseq_set); 234 else 235 writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp, 236 &clkctrl_regs->hw_clkctrl_clkseq_clr); 237 } 238 239 /* 240 * Return SSP frequency, in kHz 241 */ 242 static uint32_t mxs_get_sspclk(enum mxs_sspclock ssp) 243 { 244 struct mxs_clkctrl_regs *clkctrl_regs = 245 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 246 uint32_t clkreg; 247 uint32_t clk, tmp; 248 249 if (ssp > MXC_SSPCLK_MAX) 250 return 0; 251 252 tmp = readl(&clkctrl_regs->hw_clkctrl_clkseq); 253 if (tmp & (CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp)) 254 return XTAL_FREQ_KHZ; 255 256 clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) + 257 (ssp * sizeof(struct mxs_register_32)); 258 259 tmp = readl(clkreg) & CLKCTRL_SSP_DIV_MASK; 260 261 if (tmp == 0) 262 return 0; 263 264 clk = mxs_get_ioclk(ssp >> 1); 265 266 return clk / tmp; 267 } 268 269 /* 270 * Set SSP/MMC bus frequency, in kHz) 271 */ 272 void mxs_set_ssp_busclock(unsigned int bus, uint32_t freq) 273 { 274 struct mxs_ssp_regs *ssp_regs; 275 const enum mxs_sspclock clk = mxs_ssp_clock_by_bus(bus); 276 const uint32_t sspclk = mxs_get_sspclk(clk); 277 uint32_t reg; 278 uint32_t divide, rate, tgtclk; 279 280 ssp_regs = mxs_ssp_regs_by_bus(bus); 281 282 /* 283 * SSP bit rate = SSPCLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE)), 284 * CLOCK_DIVIDE has to be an even value from 2 to 254, and 285 * CLOCK_RATE could be any integer from 0 to 255. 286 */ 287 for (divide = 2; divide < 254; divide += 2) { 288 rate = sspclk / freq / divide; 289 if (rate <= 256) 290 break; 291 } 292 293 tgtclk = sspclk / divide / rate; 294 while (tgtclk > freq) { 295 rate++; 296 tgtclk = sspclk / divide / rate; 297 } 298 if (rate > 256) 299 rate = 256; 300 301 /* Always set timeout the maximum */ 302 reg = SSP_TIMING_TIMEOUT_MASK | 303 (divide << SSP_TIMING_CLOCK_DIVIDE_OFFSET) | 304 ((rate - 1) << SSP_TIMING_CLOCK_RATE_OFFSET); 305 writel(reg, &ssp_regs->hw_ssp_timing); 306 307 debug("SPI%d: Set freq rate to %d KHz (requested %d KHz)\n", 308 bus, tgtclk, freq); 309 } 310 311 void mxs_set_lcdclk(uint32_t __maybe_unused lcd_base, uint32_t freq) 312 { 313 struct mxs_clkctrl_regs *clkctrl_regs = 314 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 315 uint32_t fp, x, k_rest, k_best, x_best, tk; 316 int32_t k_best_l = 999, k_best_t = 0, x_best_l = 0xff, x_best_t = 0xff; 317 318 if (freq == 0) 319 return; 320 321 #if defined(CONFIG_MX23) 322 writel(CLKCTRL_CLKSEQ_BYPASS_PIX, &clkctrl_regs->hw_clkctrl_clkseq_clr); 323 #elif defined(CONFIG_MX28) 324 writel(CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF, &clkctrl_regs->hw_clkctrl_clkseq_clr); 325 #endif 326 327 /* 328 * / 18 \ 1 1 329 * freq kHz = | 480000000 Hz * -- | * --- * ------ 330 * \ x / k 1000 331 * 332 * 480000000 Hz 18 333 * ------------ * -- 334 * freq kHz x 335 * k = ------------------- 336 * 1000 337 */ 338 339 fp = ((PLL_FREQ_KHZ * 1000) / freq) * 18; 340 341 for (x = 18; x <= 35; x++) { 342 tk = fp / x; 343 if ((tk / 1000 == 0) || (tk / 1000 > 255)) 344 continue; 345 346 k_rest = tk % 1000; 347 348 if (k_rest < (k_best_l % 1000)) { 349 k_best_l = tk; 350 x_best_l = x; 351 } 352 353 if (k_rest > (k_best_t % 1000)) { 354 k_best_t = tk; 355 x_best_t = x; 356 } 357 } 358 359 if (1000 - (k_best_t % 1000) > (k_best_l % 1000)) { 360 k_best = k_best_l; 361 x_best = x_best_l; 362 } else { 363 k_best = k_best_t; 364 x_best = x_best_t; 365 } 366 367 k_best /= 1000; 368 369 #if defined(CONFIG_MX23) 370 writeb(CLKCTRL_FRAC_CLKGATE, 371 &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_PIX]); 372 writeb(CLKCTRL_FRAC_CLKGATE | (x_best & CLKCTRL_FRAC_FRAC_MASK), 373 &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_PIX]); 374 writeb(CLKCTRL_FRAC_CLKGATE, 375 &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_PIX]); 376 377 writel(CLKCTRL_PIX_CLKGATE, 378 &clkctrl_regs->hw_clkctrl_pix_set); 379 clrsetbits_le32(&clkctrl_regs->hw_clkctrl_pix, 380 CLKCTRL_PIX_DIV_MASK | CLKCTRL_PIX_CLKGATE, 381 k_best << CLKCTRL_PIX_DIV_OFFSET); 382 383 while (readl(&clkctrl_regs->hw_clkctrl_pix) & CLKCTRL_PIX_BUSY) 384 ; 385 #elif defined(CONFIG_MX28) 386 writeb(CLKCTRL_FRAC_CLKGATE, 387 &clkctrl_regs->hw_clkctrl_frac1_set[CLKCTRL_FRAC1_PIX]); 388 writeb(CLKCTRL_FRAC_CLKGATE | (x_best & CLKCTRL_FRAC_FRAC_MASK), 389 &clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_PIX]); 390 writeb(CLKCTRL_FRAC_CLKGATE, 391 &clkctrl_regs->hw_clkctrl_frac1_clr[CLKCTRL_FRAC1_PIX]); 392 393 writel(CLKCTRL_DIS_LCDIF_CLKGATE, 394 &clkctrl_regs->hw_clkctrl_lcdif_set); 395 clrsetbits_le32(&clkctrl_regs->hw_clkctrl_lcdif, 396 CLKCTRL_DIS_LCDIF_DIV_MASK | CLKCTRL_DIS_LCDIF_CLKGATE, 397 k_best << CLKCTRL_DIS_LCDIF_DIV_OFFSET); 398 399 while (readl(&clkctrl_regs->hw_clkctrl_lcdif) & CLKCTRL_DIS_LCDIF_BUSY) 400 ; 401 #endif 402 } 403 404 uint32_t mxc_get_clock(enum mxc_clock clk) 405 { 406 switch (clk) { 407 case MXC_ARM_CLK: 408 return mxs_get_pclk() * 1000000; 409 case MXC_GPMI_CLK: 410 return mxs_get_gpmiclk() * 1000000; 411 case MXC_AHB_CLK: 412 case MXC_IPG_CLK: 413 return mxs_get_hclk() * 1000000; 414 case MXC_EMI_CLK: 415 return mxs_get_emiclk(); 416 case MXC_IO0_CLK: 417 return mxs_get_ioclk(MXC_IOCLK0); 418 case MXC_IO1_CLK: 419 return mxs_get_ioclk(MXC_IOCLK1); 420 case MXC_XTAL_CLK: 421 return XTAL_FREQ_KHZ * 1000; 422 case MXC_SSP0_CLK: 423 return mxs_get_sspclk(MXC_SSPCLK0); 424 #ifdef CONFIG_MX28 425 case MXC_SSP1_CLK: 426 return mxs_get_sspclk(MXC_SSPCLK1); 427 case MXC_SSP2_CLK: 428 return mxs_get_sspclk(MXC_SSPCLK2); 429 case MXC_SSP3_CLK: 430 return mxs_get_sspclk(MXC_SSPCLK3); 431 #endif 432 } 433 434 return 0; 435 } 436