1/* 2 * Marvell PXA27x family clocks 3 * 4 * Copyright (C) 2014 Robert Jarzmik 5 * 6 * Heavily inspired from former arch/arm/mach-pxa/clock.c. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; version 2 of the License. 11 * 12 */ 13#include <linux/clk-provider.h> 14#include <mach/pxa2xx-regs.h> 15#include <linux/io.h> 16#include <linux/clk.h> 17#include <linux/clkdev.h> 18#include <linux/of.h> 19 20#include <dt-bindings/clock/pxa-clock.h> 21#include "clk-pxa.h" 22 23#define KHz 1000 24#define MHz (1000 * 1000) 25 26enum { 27 PXA_CORE_13Mhz = 0, 28 PXA_CORE_RUN, 29 PXA_CORE_TURBO, 30}; 31 32enum { 33 PXA_BUS_13Mhz = 0, 34 PXA_BUS_RUN, 35}; 36 37enum { 38 PXA_LCD_13Mhz = 0, 39 PXA_LCD_RUN, 40}; 41 42enum { 43 PXA_MEM_13Mhz = 0, 44 PXA_MEM_SYSTEM_BUS, 45 PXA_MEM_RUN, 46}; 47 48static const char * const get_freq_khz[] = { 49 "core", "run", "cpll", "memory", 50 "system_bus" 51}; 52 53/* 54 * Get the clock frequency as reflected by CCSR and the turbo flag. 55 * We assume these values have been applied via a fcs. 56 * If info is not 0 we also display the current settings. 57 */ 58unsigned int pxa27x_get_clk_frequency_khz(int info) 59{ 60 struct clk *clk; 61 unsigned long clks[5]; 62 int i; 63 64 for (i = 0; i < 5; i++) { 65 clk = clk_get(NULL, get_freq_khz[i]); 66 if (IS_ERR(clk)) { 67 clks[i] = 0; 68 } else { 69 clks[i] = clk_get_rate(clk); 70 clk_put(clk); 71 } 72 } 73 if (info) { 74 pr_info("Run Mode clock: %ld.%02ldMHz\n", 75 clks[1] / 1000000, (clks[1] % 1000000) / 10000); 76 pr_info("Turbo Mode clock: %ld.%02ldMHz\n", 77 clks[2] / 1000000, (clks[2] % 1000000) / 10000); 78 pr_info("Memory clock: %ld.%02ldMHz\n", 79 clks[3] / 1000000, (clks[3] % 1000000) / 10000); 80 pr_info("System bus clock: %ld.%02ldMHz\n", 81 clks[4] / 1000000, (clks[4] % 1000000) / 10000); 82 } 83 return (unsigned int)clks[0]; 84} 85 86bool pxa27x_is_ppll_disabled(void) 87{ 88 unsigned long ccsr = CCSR; 89 90 return ccsr & (1 << CCCR_PPDIS_BIT); 91} 92 93#define PXA27X_CKEN(dev_id, con_id, parents, mult_hp, div_hp, \ 94 bit, is_lp, flags) \ 95 PXA_CKEN(dev_id, con_id, bit, parents, 1, 1, mult_hp, div_hp, \ 96 is_lp, &CKEN, CKEN_ ## bit, flags) 97#define PXA27X_PBUS_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ 98 PXA27X_CKEN(dev_id, con_id, pxa27x_pbus_parents, mult_hp, \ 99 div_hp, bit, pxa27x_is_ppll_disabled, 0) 100 101PARENTS(pxa27x_pbus) = { "osc_13mhz", "ppll_312mhz" }; 102PARENTS(pxa27x_sbus) = { "system_bus", "system_bus" }; 103PARENTS(pxa27x_32Mhz_bus) = { "osc_32_768khz", "osc_32_768khz" }; 104PARENTS(pxa27x_lcd_bus) = { "lcd_base", "lcd_base" }; 105PARENTS(pxa27x_membus) = { "lcd_base", "lcd_base" }; 106 107#define PXA27X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \ 108 PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ 109 &CKEN, CKEN_ ## bit, 0) 110#define PXA27X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \ 111 PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ 112 &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) 113 114static struct pxa_clk_cken pxa27x_clocks[] = { 115 PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1), 116 PXA27X_PBUS_CKEN("pxa2xx-uart.1", NULL, BTUART, 2, 42, 1), 117 PXA27X_PBUS_CKEN("pxa2xx-uart.2", NULL, STUART, 2, 42, 1), 118 PXA27X_PBUS_CKEN("pxa2xx-i2s", NULL, I2S, 2, 51, 0), 119 PXA27X_PBUS_CKEN("pxa2xx-i2c.0", NULL, I2C, 2, 19, 0), 120 PXA27X_PBUS_CKEN("pxa27x-udc", NULL, USB, 2, 13, 5), 121 PXA27X_PBUS_CKEN("pxa2xx-mci.0", NULL, MMC, 2, 32, 0), 122 PXA27X_PBUS_CKEN("pxa2xx-ir", "FICPCLK", FICP, 2, 13, 0), 123 PXA27X_PBUS_CKEN("pxa27x-ohci", NULL, USBHOST, 2, 13, 0), 124 PXA27X_PBUS_CKEN("pxa2xx-i2c.1", NULL, PWRI2C, 1, 24, 0), 125 PXA27X_PBUS_CKEN("pxa27x-ssp.0", NULL, SSP1, 1, 24, 0), 126 PXA27X_PBUS_CKEN("pxa27x-ssp.1", NULL, SSP2, 1, 24, 0), 127 PXA27X_PBUS_CKEN("pxa27x-ssp.2", NULL, SSP3, 1, 24, 0), 128 PXA27X_PBUS_CKEN("pxa27x-pwm.0", NULL, PWM0, 1, 24, 0), 129 PXA27X_PBUS_CKEN("pxa27x-pwm.1", NULL, PWM1, 1, 24, 0), 130 PXA27X_PBUS_CKEN(NULL, "MSLCLK", MSL, 2, 13, 0), 131 PXA27X_PBUS_CKEN(NULL, "USIMCLK", USIM, 2, 13, 0), 132 PXA27X_PBUS_CKEN(NULL, "MSTKCLK", MEMSTK, 2, 32, 0), 133 PXA27X_PBUS_CKEN(NULL, "AC97CLK", AC97, 1, 1, 0), 134 PXA27X_PBUS_CKEN(NULL, "AC97CONFCLK", AC97CONF, 1, 1, 0), 135 PXA27X_PBUS_CKEN(NULL, "OSTIMER0", OSTIMER, 1, 96, 0), 136 137 PXA27X_CKEN_1RATE("pxa27x-keypad", NULL, KEYPAD, 138 pxa27x_32Mhz_bus_parents, 0), 139 PXA27X_CKEN_1RATE(NULL, "IMCLK", IM, pxa27x_sbus_parents, 0), 140 PXA27X_CKEN_1RATE("pxa2xx-fb", NULL, LCD, pxa27x_lcd_bus_parents, 0), 141 PXA27X_CKEN_1RATE("pxa27x-camera.0", NULL, CAMERA, 142 pxa27x_lcd_bus_parents, 0), 143 PXA27X_CKEN_1RATE_AO("pxa2xx-pcmcia", NULL, MEMC, 144 pxa27x_membus_parents, 0), 145 146}; 147 148static unsigned long clk_pxa27x_cpll_get_rate(struct clk_hw *hw, 149 unsigned long parent_rate) 150{ 151 unsigned long clkcfg; 152 unsigned int t, ht; 153 unsigned int l, L, n2, N; 154 unsigned long ccsr = CCSR; 155 156 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 157 t = clkcfg & (1 << 0); 158 ht = clkcfg & (1 << 2); 159 160 l = ccsr & CCSR_L_MASK; 161 n2 = (ccsr & CCSR_N2_MASK) >> CCSR_N2_SHIFT; 162 L = l * parent_rate; 163 N = (L * n2) / 2; 164 165 return t ? N : L; 166} 167PARENTS(clk_pxa27x_cpll) = { "osc_13mhz" }; 168RATE_RO_OPS(clk_pxa27x_cpll, "cpll"); 169 170static unsigned long clk_pxa27x_lcd_base_get_rate(struct clk_hw *hw, 171 unsigned long parent_rate) 172{ 173 unsigned int l, osc_forced; 174 unsigned long ccsr = CCSR; 175 unsigned long cccr = CCCR; 176 177 l = ccsr & CCSR_L_MASK; 178 osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 179 if (osc_forced) { 180 if (cccr & (1 << CCCR_LCD_26_BIT)) 181 return parent_rate * 2; 182 else 183 return parent_rate; 184 } 185 186 if (l <= 7) 187 return parent_rate; 188 if (l <= 16) 189 return parent_rate / 2; 190 return parent_rate / 4; 191} 192 193static u8 clk_pxa27x_lcd_base_get_parent(struct clk_hw *hw) 194{ 195 unsigned int osc_forced; 196 unsigned long ccsr = CCSR; 197 198 osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 199 if (osc_forced) 200 return PXA_LCD_13Mhz; 201 else 202 return PXA_LCD_RUN; 203} 204 205PARENTS(clk_pxa27x_lcd_base) = { "osc_13mhz", "run" }; 206MUX_RO_RATE_RO_OPS(clk_pxa27x_lcd_base, "lcd_base"); 207 208static void __init pxa27x_register_plls(void) 209{ 210 clk_register_fixed_rate(NULL, "osc_13mhz", NULL, 211 CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, 212 13 * MHz); 213 clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, 214 CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, 215 32768 * KHz); 216 clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); 217 clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1); 218} 219 220static unsigned long clk_pxa27x_core_get_rate(struct clk_hw *hw, 221 unsigned long parent_rate) 222{ 223 unsigned long clkcfg; 224 unsigned int t, ht, b, osc_forced; 225 unsigned long ccsr = CCSR; 226 227 osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 228 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 229 t = clkcfg & (1 << 0); 230 ht = clkcfg & (1 << 2); 231 b = clkcfg & (1 << 3); 232 233 if (osc_forced) 234 return parent_rate; 235 if (ht) 236 return parent_rate / 2; 237 else 238 return parent_rate; 239} 240 241static u8 clk_pxa27x_core_get_parent(struct clk_hw *hw) 242{ 243 unsigned long clkcfg; 244 unsigned int t, ht, b, osc_forced; 245 unsigned long ccsr = CCSR; 246 247 osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 248 if (osc_forced) 249 return PXA_CORE_13Mhz; 250 251 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 252 t = clkcfg & (1 << 0); 253 ht = clkcfg & (1 << 2); 254 b = clkcfg & (1 << 3); 255 256 if (ht || t) 257 return PXA_CORE_TURBO; 258 return PXA_CORE_RUN; 259} 260PARENTS(clk_pxa27x_core) = { "osc_13mhz", "run", "cpll" }; 261MUX_RO_RATE_RO_OPS(clk_pxa27x_core, "core"); 262 263static unsigned long clk_pxa27x_run_get_rate(struct clk_hw *hw, 264 unsigned long parent_rate) 265{ 266 unsigned long ccsr = CCSR; 267 unsigned int n2 = (ccsr & CCSR_N2_MASK) >> CCSR_N2_SHIFT; 268 269 return (parent_rate / n2) * 2; 270} 271PARENTS(clk_pxa27x_run) = { "cpll" }; 272RATE_RO_OPS(clk_pxa27x_run, "run"); 273 274static void __init pxa27x_register_core(void) 275{ 276 clk_register_clk_pxa27x_cpll(); 277 clk_register_clk_pxa27x_run(); 278 279 clkdev_pxa_register(CLK_CORE, "core", NULL, 280 clk_register_clk_pxa27x_core()); 281} 282 283static unsigned long clk_pxa27x_system_bus_get_rate(struct clk_hw *hw, 284 unsigned long parent_rate) 285{ 286 unsigned long clkcfg; 287 unsigned int b, osc_forced; 288 unsigned long ccsr = CCSR; 289 290 osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 291 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 292 b = clkcfg & (1 << 3); 293 294 if (osc_forced) 295 return parent_rate; 296 if (b) 297 return parent_rate / 2; 298 else 299 return parent_rate; 300} 301 302static u8 clk_pxa27x_system_bus_get_parent(struct clk_hw *hw) 303{ 304 unsigned int osc_forced; 305 unsigned long ccsr = CCSR; 306 307 osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 308 if (osc_forced) 309 return PXA_BUS_13Mhz; 310 else 311 return PXA_BUS_RUN; 312} 313 314PARENTS(clk_pxa27x_system_bus) = { "osc_13mhz", "run" }; 315MUX_RO_RATE_RO_OPS(clk_pxa27x_system_bus, "system_bus"); 316 317static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw, 318 unsigned long parent_rate) 319{ 320 unsigned int a, l, osc_forced; 321 unsigned long cccr = CCCR; 322 unsigned long ccsr = CCSR; 323 324 osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 325 a = cccr & (1 << CCCR_A_BIT); 326 l = ccsr & CCSR_L_MASK; 327 328 if (osc_forced || a) 329 return parent_rate; 330 if (l <= 10) 331 return parent_rate; 332 if (l <= 20) 333 return parent_rate / 2; 334 return parent_rate / 4; 335} 336 337static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw) 338{ 339 unsigned int osc_forced, a; 340 unsigned long cccr = CCCR; 341 unsigned long ccsr = CCSR; 342 343 osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); 344 a = cccr & (1 << CCCR_A_BIT); 345 if (osc_forced) 346 return PXA_MEM_13Mhz; 347 if (a) 348 return PXA_MEM_SYSTEM_BUS; 349 else 350 return PXA_MEM_RUN; 351} 352 353PARENTS(clk_pxa27x_memory) = { "osc_13mhz", "system_bus", "run" }; 354MUX_RO_RATE_RO_OPS(clk_pxa27x_memory, "memory"); 355 356static void __init pxa27x_base_clocks_init(void) 357{ 358 pxa27x_register_plls(); 359 pxa27x_register_core(); 360 clk_register_clk_pxa27x_system_bus(); 361 clk_register_clk_pxa27x_memory(); 362 clk_register_clk_pxa27x_lcd_base(); 363} 364 365static int __init pxa27x_clocks_init(void) 366{ 367 pxa27x_base_clocks_init(); 368 return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks)); 369} 370postcore_initcall(pxa27x_clocks_init); 371