PCI: Disable MPS configuration by default
[linux-btrfs-devel.git] / arch / mips / ath79 / clock.c
blob680bde99a26c3bf8ad314549b8d7ee16cbcdbfe0
1 /*
2 * Atheros AR71XX/AR724X/AR913X common routines
4 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 */
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/err.h>
15 #include <linux/clk.h>
17 #include <asm/mach-ath79/ath79.h>
18 #include <asm/mach-ath79/ar71xx_regs.h>
19 #include "common.h"
21 #define AR71XX_BASE_FREQ 40000000
22 #define AR724X_BASE_FREQ 5000000
23 #define AR913X_BASE_FREQ 5000000
25 struct clk {
26 unsigned long rate;
29 static struct clk ath79_ref_clk;
30 static struct clk ath79_cpu_clk;
31 static struct clk ath79_ddr_clk;
32 static struct clk ath79_ahb_clk;
33 static struct clk ath79_wdt_clk;
34 static struct clk ath79_uart_clk;
36 static void __init ar71xx_clocks_init(void)
38 u32 pll;
39 u32 freq;
40 u32 div;
42 ath79_ref_clk.rate = AR71XX_BASE_FREQ;
44 pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
46 div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
47 freq = div * ath79_ref_clk.rate;
49 div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
50 ath79_cpu_clk.rate = freq / div;
52 div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
53 ath79_ddr_clk.rate = freq / div;
55 div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
56 ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
58 ath79_wdt_clk.rate = ath79_ahb_clk.rate;
59 ath79_uart_clk.rate = ath79_ahb_clk.rate;
62 static void __init ar724x_clocks_init(void)
64 u32 pll;
65 u32 freq;
66 u32 div;
68 ath79_ref_clk.rate = AR724X_BASE_FREQ;
69 pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
71 div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
72 freq = div * ath79_ref_clk.rate;
74 div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
75 freq *= div;
77 ath79_cpu_clk.rate = freq;
79 div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
80 ath79_ddr_clk.rate = freq / div;
82 div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
83 ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
85 ath79_wdt_clk.rate = ath79_ahb_clk.rate;
86 ath79_uart_clk.rate = ath79_ahb_clk.rate;
89 static void __init ar913x_clocks_init(void)
91 u32 pll;
92 u32 freq;
93 u32 div;
95 ath79_ref_clk.rate = AR913X_BASE_FREQ;
96 pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
98 div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK);
99 freq = div * ath79_ref_clk.rate;
101 ath79_cpu_clk.rate = freq;
103 div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1;
104 ath79_ddr_clk.rate = freq / div;
106 div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2;
107 ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
109 ath79_wdt_clk.rate = ath79_ahb_clk.rate;
110 ath79_uart_clk.rate = ath79_ahb_clk.rate;
113 void __init ath79_clocks_init(void)
115 if (soc_is_ar71xx())
116 ar71xx_clocks_init();
117 else if (soc_is_ar724x())
118 ar724x_clocks_init();
119 else if (soc_is_ar913x())
120 ar913x_clocks_init();
121 else
122 BUG();
124 pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, "
125 "Ref:%lu.%03luMHz",
126 ath79_cpu_clk.rate / 1000000,
127 (ath79_cpu_clk.rate / 1000) % 1000,
128 ath79_ddr_clk.rate / 1000000,
129 (ath79_ddr_clk.rate / 1000) % 1000,
130 ath79_ahb_clk.rate / 1000000,
131 (ath79_ahb_clk.rate / 1000) % 1000,
132 ath79_ref_clk.rate / 1000000,
133 (ath79_ref_clk.rate / 1000) % 1000);
137 * Linux clock API
139 struct clk *clk_get(struct device *dev, const char *id)
141 if (!strcmp(id, "ref"))
142 return &ath79_ref_clk;
144 if (!strcmp(id, "cpu"))
145 return &ath79_cpu_clk;
147 if (!strcmp(id, "ddr"))
148 return &ath79_ddr_clk;
150 if (!strcmp(id, "ahb"))
151 return &ath79_ahb_clk;
153 if (!strcmp(id, "wdt"))
154 return &ath79_wdt_clk;
156 if (!strcmp(id, "uart"))
157 return &ath79_uart_clk;
159 return ERR_PTR(-ENOENT);
161 EXPORT_SYMBOL(clk_get);
163 int clk_enable(struct clk *clk)
165 return 0;
167 EXPORT_SYMBOL(clk_enable);
169 void clk_disable(struct clk *clk)
172 EXPORT_SYMBOL(clk_disable);
174 unsigned long clk_get_rate(struct clk *clk)
176 return clk->rate;
178 EXPORT_SYMBOL(clk_get_rate);
180 void clk_put(struct clk *clk)
183 EXPORT_SYMBOL(clk_put);