Root/target/linux/ar71xx/patches-3.3/137-MIPS-ath79-fix-CPU-DDR-frequency-calculation-for-SRI.patch

1From 3f735e202d5099a5b7c621443bea365b87b0e3bb Mon Sep 17 00:00:00 2001
2From: Gabor Juhos <juhosg@openwrt.org>
3Date: Sat, 8 Sep 2012 12:12:50 +0200
4Subject: [PATCH] MIPS: ath79: fix CPU/DDR frequency calculation for SRIF PLLs
5
6Besides the CPU and DDR PLLs, the CPU and DDR frequencies
7can be derived from other PLLs in the SRIF block on the
8AR934x SoCs. The current code does not checks if the SRIF
9PLLs are used and this can lead to incorrectly calculated
10CPU/DDR frequencies.
11
12Fix it by calculating the frequencies from SRIF PLLs if
13those are used on a given board.
14
15Cc: <stable@vger.kernel.org>
16Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
17---
18This depends on the following patch:
19'MIPS: ath79: use correct fractional dividers for {CPU,DDR}_PLL on AR934x'
20https://patchwork.linux-mips.org/patch/4305/
21
22 arch/mips/ath79/clock.c | 109 ++++++++++++++++++------
23 arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 23 +++++
24 2 files changed, 104 insertions(+), 28 deletions(-)
25
26--- a/arch/mips/ath79/clock.c
27+++ b/arch/mips/ath79/clock.c
28@@ -17,6 +17,8 @@
29 #include <linux/err.h>
30 #include <linux/clk.h>
31 
32+#include <asm/div64.h>
33+
34 #include <asm/mach-ath79/ath79.h>
35 #include <asm/mach-ath79/ar71xx_regs.h>
36 #include "common.h"
37@@ -166,11 +168,34 @@ static void __init ar933x_clocks_init(vo
38     ath79_uart_clk.rate = ath79_ref_clk.rate;
39 }
40 
41+static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
42+ u32 frac, u32 out_div)
43+{
44+ u64 t;
45+ u32 ret;
46+
47+ t = ath79_ref_clk.rate;
48+ t *= nint;
49+ do_div(t, ref_div);
50+ ret = t;
51+
52+ t = ath79_ref_clk.rate;
53+ t *= nfrac;
54+ do_div(t, ref_div * frac);
55+ ret += t;
56+
57+ ret /= (1 << out_div);
58+ return ret;
59+}
60+
61 static void __init ar934x_clocks_init(void)
62 {
63- u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
64+ u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
65     u32 cpu_pll, ddr_pll;
66     u32 bootstrap;
67+ void __iomem *dpll_base;
68+
69+ dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE);
70 
71     bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
72     if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
73@@ -178,33 +203,59 @@ static void __init ar934x_clocks_init(vo
74     else
75         ath79_ref_clk.rate = 25 * 1000 * 1000;
76 
77- pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
78- out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
79- AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
80- ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
81- AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
82- nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
83- AR934X_PLL_CPU_CONFIG_NINT_MASK;
84- frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
85- AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
86-
87- cpu_pll = nint * ath79_ref_clk.rate / ref_div;
88- cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6));
89- cpu_pll /= (1 << out_div);
90-
91- pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
92- out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
93- AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
94- ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
95- AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
96- nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
97- AR934X_PLL_DDR_CONFIG_NINT_MASK;
98- frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
99- AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
100-
101- ddr_pll = nint * ath79_ref_clk.rate / ref_div;
102- ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10));
103- ddr_pll /= (1 << out_div);
104+ pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
105+ if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
106+ out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
107+ AR934X_SRIF_DPLL2_OUTDIV_MASK;
108+ pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG);
109+ nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
110+ AR934X_SRIF_DPLL1_NINT_MASK;
111+ nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
112+ ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
113+ AR934X_SRIF_DPLL1_REFDIV_MASK;
114+ frac = 1 << 18;
115+ } else {
116+ pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
117+ out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
118+ AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
119+ ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
120+ AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
121+ nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
122+ AR934X_PLL_CPU_CONFIG_NINT_MASK;
123+ nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
124+ AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
125+ frac = 1 << 6;
126+ }
127+
128+ cpu_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint,
129+ nfrac, frac, out_div);
130+
131+ pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG);
132+ if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
133+ out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
134+ AR934X_SRIF_DPLL2_OUTDIV_MASK;
135+ pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG);
136+ nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
137+ AR934X_SRIF_DPLL1_NINT_MASK;
138+ nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
139+ ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
140+ AR934X_SRIF_DPLL1_REFDIV_MASK;
141+ frac = 1 << 18;
142+ } else {
143+ pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
144+ out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
145+ AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
146+ ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
147+ AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
148+ nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
149+ AR934X_PLL_DDR_CONFIG_NINT_MASK;
150+ nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
151+ AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
152+ frac = 1 << 10;
153+ }
154+
155+ ddr_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint,
156+ nfrac, frac, out_div);
157 
158     clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
159 
160@@ -240,6 +291,8 @@ static void __init ar934x_clocks_init(vo
161 
162     ath79_wdt_clk.rate = ath79_ref_clk.rate;
163     ath79_uart_clk.rate = ath79_ref_clk.rate;
164+
165+ iounmap(dpll_base);
166 }
167 
168 void __init ath79_clocks_init(void)
169--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
170+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
171@@ -65,6 +65,8 @@
172 #define AR934X_WMAC_SIZE 0x20000
173 #define AR934X_EHCI_BASE 0x1b000000
174 #define AR934X_EHCI_SIZE 0x200
175+#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000)
176+#define AR934X_SRIF_SIZE 0x1000
177 
178 /*
179  * DDR_CTRL block
180@@ -405,4 +407,25 @@
181 #define AR933X_GPIO_COUNT 30
182 #define AR934X_GPIO_COUNT 23
183 
184+/*
185+ * SRIF block
186+ */
187+#define AR934X_SRIF_CPU_DPLL1_REG 0x1c0
188+#define AR934X_SRIF_CPU_DPLL2_REG 0x1c4
189+#define AR934X_SRIF_CPU_DPLL3_REG 0x1c8
190+
191+#define AR934X_SRIF_DDR_DPLL1_REG 0x240
192+#define AR934X_SRIF_DDR_DPLL2_REG 0x244
193+#define AR934X_SRIF_DDR_DPLL3_REG 0x248
194+
195+#define AR934X_SRIF_DPLL1_REFDIV_SHIFT 27
196+#define AR934X_SRIF_DPLL1_REFDIV_MASK 0x1f
197+#define AR934X_SRIF_DPLL1_NINT_SHIFT 18
198+#define AR934X_SRIF_DPLL1_NINT_MASK 0x1ff
199+#define AR934X_SRIF_DPLL1_NFRAC_MASK 0x0003ffff
200+
201+#define AR934X_SRIF_DPLL2_LOCAL_PLL BIT(30)
202+#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13
203+#define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7
204+
205 #endif /* __ASM_MACH_AR71XX_REGS_H */
206

Archive Download this file



interactive