clk-pxa25x.c (fd13f8117f7a2d4054bf420ec1428e918a24a480) | clk-pxa25x.c (3c816d950a494ae6e16b1fa017af29bc53cb7791) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Marvell PXA25x family clocks 4 * 5 * Copyright (C) 2014 Robert Jarzmik 6 * 7 * Heavily inspired from former arch/arm/mach-pxa/pxa25x.c. 8 * 9 * For non-devicetree platforms. Once pxa is fully converted to devicetree, this 10 * should go away. 11 */ 12#include <linux/clk-provider.h> 13#include <linux/clk.h> 14#include <linux/clkdev.h> 15#include <linux/io.h> 16#include <linux/of.h> | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Marvell PXA25x family clocks 4 * 5 * Copyright (C) 2014 Robert Jarzmik 6 * 7 * Heavily inspired from former arch/arm/mach-pxa/pxa25x.c. 8 * 9 * For non-devicetree platforms. Once pxa is fully converted to devicetree, this 10 * should go away. 11 */ 12#include <linux/clk-provider.h> 13#include <linux/clk.h> 14#include <linux/clkdev.h> 15#include <linux/io.h> 16#include <linux/of.h> |
17#include <mach/pxa2xx-regs.h> | |
18#include <linux/soc/pxa/smemc.h> 19 20#include <dt-bindings/clock/pxa-clock.h> 21#include "clk-pxa.h" | 17#include <linux/soc/pxa/smemc.h> 18 19#include <dt-bindings/clock/pxa-clock.h> 20#include "clk-pxa.h" |
21#include "clk-pxa2xx.h" |
|
22 23#define KHz 1000 24#define MHz (1000 * 1000) 25 26enum { 27 PXA_CORE_RUN = 0, 28 PXA_CORE_TURBO, 29}; --- 4 unchanged lines hidden (view full) --- 34#define PXA25x_CCCR(N2, M, L) (N2 << 7 | M << 5 | L) 35 36/* Define the refresh period in mSec for the SDRAM and the number of rows */ 37#define SDRAM_TREF 64 /* standard 64ms SDRAM */ 38 39/* 40 * Various clock factors driven by the CCCR register. 41 */ | 22 23#define KHz 1000 24#define MHz (1000 * 1000) 25 26enum { 27 PXA_CORE_RUN = 0, 28 PXA_CORE_TURBO, 29}; --- 4 unchanged lines hidden (view full) --- 34#define PXA25x_CCCR(N2, M, L) (N2 << 7 | M << 5 | L) 35 36/* Define the refresh period in mSec for the SDRAM and the number of rows */ 37#define SDRAM_TREF 64 /* standard 64ms SDRAM */ 38 39/* 40 * Various clock factors driven by the CCCR register. 41 */ |
42static void __iomem *clk_regs; |
|
42 43/* Crystal Frequency to Memory Frequency Multiplier (L) */ 44static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, }; 45 46/* Memory Frequency to Run Mode Frequency Multiplier (M) */ 47static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 }; 48 49/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */ --- 42 unchanged lines hidden (view full) --- 92 } 93 94 return (unsigned int)clks[0] / KHz; 95} 96 97static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw, 98 unsigned long parent_rate) 99{ | 43 44/* Crystal Frequency to Memory Frequency Multiplier (L) */ 45static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, }; 46 47/* Memory Frequency to Run Mode Frequency Multiplier (M) */ 48static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 }; 49 50/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */ --- 42 unchanged lines hidden (view full) --- 93 } 94 95 return (unsigned int)clks[0] / KHz; 96} 97 98static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw, 99 unsigned long parent_rate) 100{ |
100 unsigned long cccr = readl(CCCR); | 101 unsigned long cccr = readl(clk_regs + CCCR); |
101 unsigned int m = M_clk_mult[(cccr >> 5) & 0x03]; 102 103 return parent_rate / m; 104} 105PARENTS(clk_pxa25x_memory) = { "run" }; 106RATE_RO_OPS(clk_pxa25x_memory, "memory"); 107 108PARENTS(pxa25x_pbus95) = { "ppll_95_85mhz", "ppll_95_85mhz" }; --- 87 unchanged lines hidden (view full) --- 196} 197 198PARENTS(clk_pxa25x_core) = { "run", "cpll" }; 199MUX_OPS(clk_pxa25x_core, "core", CLK_SET_RATE_PARENT); 200 201static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw, 202 unsigned long parent_rate) 203{ | 102 unsigned int m = M_clk_mult[(cccr >> 5) & 0x03]; 103 104 return parent_rate / m; 105} 106PARENTS(clk_pxa25x_memory) = { "run" }; 107RATE_RO_OPS(clk_pxa25x_memory, "memory"); 108 109PARENTS(pxa25x_pbus95) = { "ppll_95_85mhz", "ppll_95_85mhz" }; --- 87 unchanged lines hidden (view full) --- 197} 198 199PARENTS(clk_pxa25x_core) = { "run", "cpll" }; 200MUX_OPS(clk_pxa25x_core, "core", CLK_SET_RATE_PARENT); 201 202static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw, 203 unsigned long parent_rate) 204{ |
204 unsigned long cccr = readl(CCCR); | 205 unsigned long cccr = readl(clk_regs + CCCR); |
205 unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07]; 206 207 return (parent_rate / n2) * 2; 208} 209PARENTS(clk_pxa25x_run) = { "cpll" }; 210RATE_RO_OPS(clk_pxa25x_run, "run"); 211 212static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw, 213 unsigned long parent_rate) 214{ | 206 unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07]; 207 208 return (parent_rate / n2) * 2; 209} 210PARENTS(clk_pxa25x_run) = { "cpll" }; 211RATE_RO_OPS(clk_pxa25x_run, "run"); 212 213static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw, 214 unsigned long parent_rate) 215{ |
215 unsigned long clkcfg, cccr = readl(CCCR); | 216 unsigned long clkcfg, cccr = readl(clk_regs + CCCR); |
216 unsigned int l, m, n2, t; 217 218 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 219 t = clkcfg & (1 << 0); 220 l = L_clk_mult[(cccr >> 0) & 0x1f]; 221 m = M_clk_mult[(cccr >> 5) & 0x03]; 222 n2 = N2_clk_mult[(cccr >> 7) & 0x07]; 223 --- 15 unchanged lines hidden (view full) --- 239 pr_debug("%s(rate=%lu parent_rate=%lu)\n", __func__, rate, parent_rate); 240 for (i = 0; i < ARRAY_SIZE(pxa25x_freqs); i++) 241 if (pxa25x_freqs[i].cpll == rate) 242 break; 243 244 if (i >= ARRAY_SIZE(pxa25x_freqs)) 245 return -EINVAL; 246 | 217 unsigned int l, m, n2, t; 218 219 asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); 220 t = clkcfg & (1 << 0); 221 l = L_clk_mult[(cccr >> 0) & 0x1f]; 222 m = M_clk_mult[(cccr >> 5) & 0x03]; 223 n2 = N2_clk_mult[(cccr >> 7) & 0x07]; 224 --- 15 unchanged lines hidden (view full) --- 240 pr_debug("%s(rate=%lu parent_rate=%lu)\n", __func__, rate, parent_rate); 241 for (i = 0; i < ARRAY_SIZE(pxa25x_freqs); i++) 242 if (pxa25x_freqs[i].cpll == rate) 243 break; 244 245 if (i >= ARRAY_SIZE(pxa25x_freqs)) 246 return -EINVAL; 247 |
247 pxa2xx_cpll_change(&pxa25x_freqs[i], mdrefr_dri, CCCR); | 248 pxa2xx_cpll_change(&pxa25x_freqs[i], mdrefr_dri, clk_regs + CCCR); |
248 249 return 0; 250} 251PARENTS(clk_pxa25x_cpll) = { "osc_3_6864mhz" }; 252RATE_OPS(clk_pxa25x_cpll, "cpll"); 253 254static void __init pxa25x_register_core(void) 255{ --- 60 unchanged lines hidden (view full) --- 316 for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) { 317 d = &dummy_clks[i]; 318 name = d->dev_id ? d->dev_id : d->con_id; 319 clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1); 320 clk_register_clkdev(clk, d->con_id, d->dev_id); 321 } 322} 323 | 249 250 return 0; 251} 252PARENTS(clk_pxa25x_cpll) = { "osc_3_6864mhz" }; 253RATE_OPS(clk_pxa25x_cpll, "cpll"); 254 255static void __init pxa25x_register_core(void) 256{ --- 60 unchanged lines hidden (view full) --- 317 for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) { 318 d = &dummy_clks[i]; 319 name = d->dev_id ? d->dev_id : d->con_id; 320 clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1); 321 clk_register_clkdev(clk, d->con_id, d->dev_id); 322 } 323} 324 |
324int __init pxa25x_clocks_init(void) | 325int __init pxa25x_clocks_init(void __iomem *regs) |
325{ | 326{ |
327 clk_regs = regs; |
|
326 pxa25x_base_clocks_init(); 327 pxa25x_dummy_clocks_init(); | 328 pxa25x_base_clocks_init(); 329 pxa25x_dummy_clocks_init(); |
328 return clk_pxa_cken_init(pxa25x_clocks, ARRAY_SIZE(pxa25x_clocks)); | 330 return clk_pxa_cken_init(pxa25x_clocks, ARRAY_SIZE(pxa25x_clocks), clk_regs); |
329} 330 331static void __init pxa25x_dt_clocks_init(struct device_node *np) 332{ | 331} 332 333static void __init pxa25x_dt_clocks_init(struct device_node *np) 334{ |
333 pxa25x_clocks_init(); | 335 pxa25x_clocks_init(ioremap(0x41300000ul, 0x10)); |
334 clk_pxa_dt_common_init(np); 335} 336CLK_OF_DECLARE(pxa25x_clks, "marvell,pxa250-core-clocks", 337 pxa25x_dt_clocks_init); | 336 clk_pxa_dt_common_init(np); 337} 338CLK_OF_DECLARE(pxa25x_clks, "marvell,pxa250-core-clocks", 339 pxa25x_dt_clocks_init); |