From: Greg Kroah-Hartman Date: Mon, 15 Oct 2012 20:23:43 +0000 (-0700) Subject: 3.6-stable patches X-Git-Tag: v3.0.47~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0005325de0a770fc38ce3ab5017f7efd4b9ad7dd;p=thirdparty%2Fkernel%2Fstable-queue.git 3.6-stable patches added patches: mips-ath79-fix-cpu-ddr-frequency-calculation-for-srif-plls.patch --- diff --git a/queue-3.6/mips-ath79-fix-cpu-ddr-frequency-calculation-for-srif-plls.patch b/queue-3.6/mips-ath79-fix-cpu-ddr-frequency-calculation-for-srif-plls.patch new file mode 100644 index 00000000000..db66d1ff130 --- /dev/null +++ b/queue-3.6/mips-ath79-fix-cpu-ddr-frequency-calculation-for-srif-plls.patch @@ -0,0 +1,209 @@ +From 97541ccfb9db2bb9cd1dde6344d5834438d14bda Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sat, 8 Sep 2012 14:02:21 +0200 +Subject: MIPS: ath79: Fix CPU/DDR frequency calculation for SRIF PLLs + +From: Gabor Juhos + +commit 97541ccfb9db2bb9cd1dde6344d5834438d14bda upstream. + +Besides the CPU and DDR PLLs, the CPU and DDR frequencies +can be derived from other PLLs in the SRIF block on the +AR934x SoCs. The current code does not checks if the SRIF +PLLs are used and this can lead to incorrectly calculated +CPU/DDR frequencies. + +Fix it by calculating the frequencies from SRIF PLLs if +those are used on a given board. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/4324/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/ath79/clock.c | 109 ++++++++++++++++++------- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 23 +++++ + 2 files changed, 104 insertions(+), 28 deletions(-) + +--- a/arch/mips/ath79/clock.c ++++ b/arch/mips/ath79/clock.c +@@ -17,6 +17,8 @@ + #include + #include + ++#include ++ + #include + #include + #include "common.h" +@@ -166,11 +168,34 @@ static void __init ar933x_clocks_init(vo + ath79_uart_clk.rate = ath79_ref_clk.rate; + } + ++static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, ++ u32 frac, u32 out_div) ++{ ++ u64 t; ++ u32 ret; ++ ++ t = ath79_ref_clk.rate; ++ t *= nint; ++ do_div(t, ref_div); ++ ret = t; ++ ++ t = ath79_ref_clk.rate; ++ t *= nfrac; ++ do_div(t, ref_div * frac); ++ ret += t; ++ ++ ret /= (1 << out_div); ++ return ret; ++} ++ + static void __init ar934x_clocks_init(void) + { +- u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; ++ u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; + u32 cpu_pll, ddr_pll; + u32 bootstrap; ++ void __iomem *dpll_base; ++ ++ dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); + + bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); + if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) +@@ -178,33 +203,59 @@ static void __init ar934x_clocks_init(vo + else + ath79_ref_clk.rate = 25 * 1000 * 1000; + +- pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); +- out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & +- AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; +- ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & +- AR934X_PLL_CPU_CONFIG_REFDIV_MASK; +- nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & +- AR934X_PLL_CPU_CONFIG_NINT_MASK; +- frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & +- AR934X_PLL_CPU_CONFIG_NFRAC_MASK; +- +- cpu_pll = nint * ath79_ref_clk.rate / ref_div; +- cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6)); +- cpu_pll /= (1 << out_div); +- +- pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); +- out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & +- AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; +- ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & +- AR934X_PLL_DDR_CONFIG_REFDIV_MASK; +- nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & +- AR934X_PLL_DDR_CONFIG_NINT_MASK; +- frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & +- AR934X_PLL_DDR_CONFIG_NFRAC_MASK; +- +- ddr_pll = nint * ath79_ref_clk.rate / ref_div; +- ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10)); +- ddr_pll /= (1 << out_div); ++ pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); ++ if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { ++ out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & ++ AR934X_SRIF_DPLL2_OUTDIV_MASK; ++ pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG); ++ nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & ++ AR934X_SRIF_DPLL1_NINT_MASK; ++ nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; ++ ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & ++ AR934X_SRIF_DPLL1_REFDIV_MASK; ++ frac = 1 << 18; ++ } else { ++ pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); ++ out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_REFDIV_MASK; ++ nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_NINT_MASK; ++ nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_NFRAC_MASK; ++ frac = 1 << 6; ++ } ++ ++ cpu_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint, ++ nfrac, frac, out_div); ++ ++ pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); ++ if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { ++ out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & ++ AR934X_SRIF_DPLL2_OUTDIV_MASK; ++ pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG); ++ nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & ++ AR934X_SRIF_DPLL1_NINT_MASK; ++ nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; ++ ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & ++ AR934X_SRIF_DPLL1_REFDIV_MASK; ++ frac = 1 << 18; ++ } else { ++ pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); ++ out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_REFDIV_MASK; ++ nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_NINT_MASK; ++ nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_NFRAC_MASK; ++ frac = 1 << 10; ++ } ++ ++ ddr_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint, ++ nfrac, frac, out_div); + + clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); + +@@ -240,6 +291,8 @@ static void __init ar934x_clocks_init(vo + + ath79_wdt_clk.rate = ath79_ref_clk.rate; + ath79_uart_clk.rate = ath79_ref_clk.rate; ++ ++ iounmap(dpll_base); + } + + void __init ath79_clocks_init(void) +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -63,6 +63,8 @@ + + #define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) + #define AR934X_WMAC_SIZE 0x20000 ++#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) ++#define AR934X_SRIF_SIZE 0x1000 + + /* + * DDR_CTRL block +@@ -399,4 +401,25 @@ + #define AR933X_GPIO_COUNT 30 + #define AR934X_GPIO_COUNT 23 + ++/* ++ * SRIF block ++ */ ++#define AR934X_SRIF_CPU_DPLL1_REG 0x1c0 ++#define AR934X_SRIF_CPU_DPLL2_REG 0x1c4 ++#define AR934X_SRIF_CPU_DPLL3_REG 0x1c8 ++ ++#define AR934X_SRIF_DDR_DPLL1_REG 0x240 ++#define AR934X_SRIF_DDR_DPLL2_REG 0x244 ++#define AR934X_SRIF_DDR_DPLL3_REG 0x248 ++ ++#define AR934X_SRIF_DPLL1_REFDIV_SHIFT 27 ++#define AR934X_SRIF_DPLL1_REFDIV_MASK 0x1f ++#define AR934X_SRIF_DPLL1_NINT_SHIFT 18 ++#define AR934X_SRIF_DPLL1_NINT_MASK 0x1ff ++#define AR934X_SRIF_DPLL1_NFRAC_MASK 0x0003ffff ++ ++#define AR934X_SRIF_DPLL2_LOCAL_PLL BIT(30) ++#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13 ++#define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7 ++ + #endif /* __ASM_MACH_AR71XX_REGS_H */ diff --git a/queue-3.6/series b/queue-3.6/series index 4c18aa2471f..700de2dd0a7 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -49,3 +49,4 @@ mac80211-use-ieee80211_free_txskb-to-fix-possible-skb-leaks.patch md-raid10-use-correct-limit-variable.patch kdb-vt_console-fix-missed-data-due-to-pager-overruns.patch pktgen-fix-crash-when-generating-ipv6-packets.patch +mips-ath79-fix-cpu-ddr-frequency-calculation-for-srif-plls.patch