2011-01-04 21:28:14 +01:00
/*
* Atheros AR71XX / AR724X / AR913X common routines
*
2012-03-14 10:45:22 +01:00
* Copyright ( C ) 2010 - 2011 Jaiganesh Narayanan < jnarayanan @ atheros . com >
2011-01-04 21:28:14 +01:00
* Copyright ( C ) 2011 Gabor Juhos < juhosg @ openwrt . org >
*
2012-03-14 10:45:22 +01:00
* Parts of this file are based on Atheros ' 2.6 .15 / 2.6 .31 BSP
*
2011-01-04 21:28:14 +01:00
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation .
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/init.h>
# include <linux/err.h>
# include <linux/clk.h>
2012-09-08 14:02:21 +02:00
# include <asm/div64.h>
2011-01-04 21:28:14 +01:00
# include <asm/mach-ath79/ath79.h>
# include <asm/mach-ath79/ar71xx_regs.h>
# include "common.h"
# define AR71XX_BASE_FREQ 40000000
# define AR724X_BASE_FREQ 5000000
# define AR913X_BASE_FREQ 5000000
struct clk {
unsigned long rate ;
} ;
static struct clk ath79_ref_clk ;
static struct clk ath79_cpu_clk ;
static struct clk ath79_ddr_clk ;
static struct clk ath79_ahb_clk ;
static struct clk ath79_wdt_clk ;
static struct clk ath79_uart_clk ;
static void __init ar71xx_clocks_init ( void )
{
2013-08-28 10:41:46 +02:00
unsigned long ref_rate ;
unsigned long cpu_rate ;
unsigned long ddr_rate ;
unsigned long ahb_rate ;
2011-01-04 21:28:14 +01:00
u32 pll ;
u32 freq ;
u32 div ;
2013-08-28 10:41:46 +02:00
ref_rate = AR71XX_BASE_FREQ ;
2011-01-04 21:28:14 +01:00
pll = ath79_pll_rr ( AR71XX_PLL_REG_CPU_CONFIG ) ;
div = ( ( pll > > AR71XX_PLL_DIV_SHIFT ) & AR71XX_PLL_DIV_MASK ) + 1 ;
2013-08-28 10:41:46 +02:00
freq = div * ref_rate ;
2011-01-04 21:28:14 +01:00
div = ( ( pll > > AR71XX_CPU_DIV_SHIFT ) & AR71XX_CPU_DIV_MASK ) + 1 ;
2013-08-28 10:41:46 +02:00
cpu_rate = freq / div ;
2011-01-04 21:28:14 +01:00
div = ( ( pll > > AR71XX_DDR_DIV_SHIFT ) & AR71XX_DDR_DIV_MASK ) + 1 ;
2013-08-28 10:41:46 +02:00
ddr_rate = freq / div ;
2011-01-04 21:28:14 +01:00
div = ( ( ( pll > > AR71XX_AHB_DIV_SHIFT ) & AR71XX_AHB_DIV_MASK ) + 1 ) * 2 ;
2013-08-28 10:41:46 +02:00
ahb_rate = cpu_rate / div ;
ath79_ref_clk . rate = ref_rate ;
ath79_cpu_clk . rate = cpu_rate ;
ath79_ddr_clk . rate = ddr_rate ;
ath79_ahb_clk . rate = ahb_rate ;
2011-01-04 21:28:14 +01:00
ath79_wdt_clk . rate = ath79_ahb_clk . rate ;
ath79_uart_clk . rate = ath79_ahb_clk . rate ;
}
static void __init ar724x_clocks_init ( void )
{
2013-08-28 10:41:46 +02:00
unsigned long ref_rate ;
unsigned long cpu_rate ;
unsigned long ddr_rate ;
unsigned long ahb_rate ;
2011-01-04 21:28:14 +01:00
u32 pll ;
u32 freq ;
u32 div ;
2013-08-28 10:41:46 +02:00
ref_rate = AR724X_BASE_FREQ ;
2011-01-04 21:28:14 +01:00
pll = ath79_pll_rr ( AR724X_PLL_REG_CPU_CONFIG ) ;
div = ( ( pll > > AR724X_PLL_DIV_SHIFT ) & AR724X_PLL_DIV_MASK ) ;
2013-08-28 10:41:46 +02:00
freq = div * ref_rate ;
2011-01-04 21:28:14 +01:00
div = ( ( pll > > AR724X_PLL_REF_DIV_SHIFT ) & AR724X_PLL_REF_DIV_MASK ) ;
freq * = div ;
2013-08-28 10:41:46 +02:00
cpu_rate = freq ;
2011-01-04 21:28:14 +01:00
div = ( ( pll > > AR724X_DDR_DIV_SHIFT ) & AR724X_DDR_DIV_MASK ) + 1 ;
2013-08-28 10:41:46 +02:00
ddr_rate = freq / div ;
2011-01-04 21:28:14 +01:00
div = ( ( ( pll > > AR724X_AHB_DIV_SHIFT ) & AR724X_AHB_DIV_MASK ) + 1 ) * 2 ;
2013-08-28 10:41:46 +02:00
ahb_rate = cpu_rate / div ;
ath79_ref_clk . rate = ref_rate ;
ath79_cpu_clk . rate = cpu_rate ;
ath79_ddr_clk . rate = ddr_rate ;
ath79_ahb_clk . rate = ahb_rate ;
2011-01-04 21:28:14 +01:00
ath79_wdt_clk . rate = ath79_ahb_clk . rate ;
ath79_uart_clk . rate = ath79_ahb_clk . rate ;
}
static void __init ar913x_clocks_init ( void )
{
2013-08-28 10:41:46 +02:00
unsigned long ref_rate ;
unsigned long cpu_rate ;
unsigned long ddr_rate ;
unsigned long ahb_rate ;
2011-01-04 21:28:14 +01:00
u32 pll ;
u32 freq ;
u32 div ;
2013-08-28 10:41:46 +02:00
ref_rate = AR913X_BASE_FREQ ;
2011-01-04 21:28:14 +01:00
pll = ath79_pll_rr ( AR913X_PLL_REG_CPU_CONFIG ) ;
div = ( ( pll > > AR913X_PLL_DIV_SHIFT ) & AR913X_PLL_DIV_MASK ) ;
2013-08-28 10:41:46 +02:00
freq = div * ref_rate ;
2011-01-04 21:28:14 +01:00
2013-08-28 10:41:46 +02:00
cpu_rate = freq ;
2011-01-04 21:28:14 +01:00
div = ( ( pll > > AR913X_DDR_DIV_SHIFT ) & AR913X_DDR_DIV_MASK ) + 1 ;
2013-08-28 10:41:46 +02:00
ddr_rate = freq / div ;
2011-01-04 21:28:14 +01:00
div = ( ( ( pll > > AR913X_AHB_DIV_SHIFT ) & AR913X_AHB_DIV_MASK ) + 1 ) * 2 ;
2013-08-28 10:41:46 +02:00
ahb_rate = cpu_rate / div ;
ath79_ref_clk . rate = ref_rate ;
ath79_cpu_clk . rate = cpu_rate ;
ath79_ddr_clk . rate = ddr_rate ;
ath79_ahb_clk . rate = ahb_rate ;
2011-01-04 21:28:14 +01:00
ath79_wdt_clk . rate = ath79_ahb_clk . rate ;
ath79_uart_clk . rate = ath79_ahb_clk . rate ;
}
2011-06-20 21:26:04 +02:00
static void __init ar933x_clocks_init ( void )
{
2013-08-28 10:41:46 +02:00
unsigned long ref_rate ;
unsigned long cpu_rate ;
unsigned long ddr_rate ;
unsigned long ahb_rate ;
2011-06-20 21:26:04 +02:00
u32 clock_ctrl ;
u32 cpu_config ;
u32 freq ;
u32 t ;
t = ath79_reset_rr ( AR933X_RESET_REG_BOOTSTRAP ) ;
if ( t & AR933X_BOOTSTRAP_REF_CLK_40 )
2013-08-28 10:41:46 +02:00
ref_rate = ( 40 * 1000 * 1000 ) ;
2011-06-20 21:26:04 +02:00
else
2013-08-28 10:41:46 +02:00
ref_rate = ( 25 * 1000 * 1000 ) ;
2011-06-20 21:26:04 +02:00
clock_ctrl = ath79_pll_rr ( AR933X_PLL_CLOCK_CTRL_REG ) ;
if ( clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS ) {
2013-08-28 10:41:46 +02:00
cpu_rate = ref_rate ;
ahb_rate = ref_rate ;
ddr_rate = ref_rate ;
2011-06-20 21:26:04 +02:00
} else {
cpu_config = ath79_pll_rr ( AR933X_PLL_CPU_CONFIG_REG ) ;
t = ( cpu_config > > AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT ) &
AR933X_PLL_CPU_CONFIG_REFDIV_MASK ;
2013-08-28 10:41:46 +02:00
freq = ref_rate / t ;
2011-06-20 21:26:04 +02:00
t = ( cpu_config > > AR933X_PLL_CPU_CONFIG_NINT_SHIFT ) &
AR933X_PLL_CPU_CONFIG_NINT_MASK ;
freq * = t ;
t = ( cpu_config > > AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT ) &
AR933X_PLL_CPU_CONFIG_OUTDIV_MASK ;
if ( t = = 0 )
t = 1 ;
freq > > = t ;
t = ( ( clock_ctrl > > AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT ) &
AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK ) + 1 ;
2013-08-28 10:41:46 +02:00
cpu_rate = freq / t ;
2011-06-20 21:26:04 +02:00
t = ( ( clock_ctrl > > AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT ) &
AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK ) + 1 ;
2013-08-28 10:41:46 +02:00
ddr_rate = freq / t ;
2011-06-20 21:26:04 +02:00
t = ( ( clock_ctrl > > AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT ) &
AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK ) + 1 ;
2013-08-28 10:41:46 +02:00
ahb_rate = freq / t ;
2011-06-20 21:26:04 +02:00
}
2013-08-28 10:41:46 +02:00
ath79_ref_clk . rate = ref_rate ;
ath79_cpu_clk . rate = cpu_rate ;
ath79_ddr_clk . rate = ddr_rate ;
ath79_ahb_clk . rate = ahb_rate ;
2013-08-28 10:41:42 +02:00
ath79_wdt_clk . rate = ath79_ahb_clk . rate ;
2011-06-20 21:26:04 +02:00
ath79_uart_clk . rate = ath79_ref_clk . rate ;
}
2012-09-08 14:02:21 +02:00
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 ;
2013-08-28 10:41:43 +02:00
t = ref ;
2012-09-08 14:02:21 +02:00
t * = nint ;
do_div ( t , ref_div ) ;
ret = t ;
2013-08-28 10:41:43 +02:00
t = ref ;
2012-09-08 14:02:21 +02:00
t * = nfrac ;
do_div ( t , ref_div * frac ) ;
ret + = t ;
ret / = ( 1 < < out_div ) ;
return ret ;
}
2012-03-14 10:45:22 +01:00
static void __init ar934x_clocks_init ( void )
{
2013-08-28 10:41:46 +02:00
unsigned long ref_rate ;
unsigned long cpu_rate ;
unsigned long ddr_rate ;
unsigned long ahb_rate ;
2012-09-08 14:02:21 +02:00
u32 pll , out_div , ref_div , nint , nfrac , frac , clk_ctrl , postdiv ;
2012-03-14 10:45:22 +01:00
u32 cpu_pll , ddr_pll ;
u32 bootstrap ;
2012-09-08 14:02:21 +02:00
void __iomem * dpll_base ;
dpll_base = ioremap ( AR934X_SRIF_BASE , AR934X_SRIF_SIZE ) ;
2012-03-14 10:45:22 +01:00
bootstrap = ath79_reset_rr ( AR934X_RESET_REG_BOOTSTRAP ) ;
2013-01-22 12:59:30 +01:00
if ( bootstrap & AR934X_BOOTSTRAP_REF_CLK_40 )
2013-08-28 10:41:46 +02:00
ref_rate = 40 * 1000 * 1000 ;
2012-03-14 10:45:22 +01:00
else
2013-08-28 10:41:46 +02:00
ref_rate = 25 * 1000 * 1000 ;
2012-03-14 10:45:22 +01:00
2012-09-08 14:02:21 +02:00
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 ;
}
2013-08-28 10:41:46 +02:00
cpu_pll = ar934x_get_pll_freq ( ref_rate , ref_div , nint ,
2012-09-08 14:02:21 +02:00
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 ;
}
2013-08-28 10:41:46 +02:00
ddr_pll = ar934x_get_pll_freq ( ref_rate , ref_div , nint ,
2012-09-08 14:02:21 +02:00
nfrac , frac , out_div ) ;
2012-03-14 10:45:22 +01:00
clk_ctrl = ath79_pll_rr ( AR934X_PLL_CPU_DDR_CLK_CTRL_REG ) ;
postdiv = ( clk_ctrl > > AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT ) &
AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK ;
if ( clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS )
2013-08-28 10:41:46 +02:00
cpu_rate = ref_rate ;
2012-03-14 10:45:22 +01:00
else if ( clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL )
2013-08-28 10:41:46 +02:00
cpu_rate = cpu_pll / ( postdiv + 1 ) ;
2012-03-14 10:45:22 +01:00
else
2013-08-28 10:41:46 +02:00
cpu_rate = ddr_pll / ( postdiv + 1 ) ;
2012-03-14 10:45:22 +01:00
postdiv = ( clk_ctrl > > AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT ) &
AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK ;
if ( clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS )
2013-08-28 10:41:46 +02:00
ddr_rate = ref_rate ;
2012-03-14 10:45:22 +01:00
else if ( clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL )
2013-08-28 10:41:46 +02:00
ddr_rate = ddr_pll / ( postdiv + 1 ) ;
2012-03-14 10:45:22 +01:00
else
2013-08-28 10:41:46 +02:00
ddr_rate = cpu_pll / ( postdiv + 1 ) ;
2012-03-14 10:45:22 +01:00
postdiv = ( clk_ctrl > > AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT ) &
AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK ;
if ( clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS )
2013-08-28 10:41:46 +02:00
ahb_rate = ref_rate ;
2012-03-14 10:45:22 +01:00
else if ( clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL )
2013-08-28 10:41:46 +02:00
ahb_rate = ddr_pll / ( postdiv + 1 ) ;
2012-03-14 10:45:22 +01:00
else
2013-08-28 10:41:46 +02:00
ahb_rate = cpu_pll / ( postdiv + 1 ) ;
ath79_ref_clk . rate = ref_rate ;
ath79_cpu_clk . rate = cpu_rate ;
ath79_ddr_clk . rate = ddr_rate ;
ath79_ahb_clk . rate = ahb_rate ;
2012-03-14 10:45:22 +01:00
ath79_wdt_clk . rate = ath79_ref_clk . rate ;
ath79_uart_clk . rate = ath79_ref_clk . rate ;
2012-09-08 14:02:21 +02:00
iounmap ( dpll_base ) ;
2012-03-14 10:45:22 +01:00
}
2013-02-15 13:38:17 +00:00
static void __init qca955x_clocks_init ( void )
{
2013-08-28 10:41:46 +02:00
unsigned long ref_rate ;
unsigned long cpu_rate ;
unsigned long ddr_rate ;
unsigned long ahb_rate ;
2013-02-15 13:38:17 +00:00
u32 pll , out_div , ref_div , nint , frac , clk_ctrl , postdiv ;
u32 cpu_pll , ddr_pll ;
u32 bootstrap ;
bootstrap = ath79_reset_rr ( QCA955X_RESET_REG_BOOTSTRAP ) ;
if ( bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40 )
2013-08-28 10:41:46 +02:00
ref_rate = 40 * 1000 * 1000 ;
2013-02-15 13:38:17 +00:00
else
2013-08-28 10:41:46 +02:00
ref_rate = 25 * 1000 * 1000 ;
2013-02-15 13:38:17 +00:00
pll = ath79_pll_rr ( QCA955X_PLL_CPU_CONFIG_REG ) ;
out_div = ( pll > > QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT ) &
QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK ;
ref_div = ( pll > > QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT ) &
QCA955X_PLL_CPU_CONFIG_REFDIV_MASK ;
nint = ( pll > > QCA955X_PLL_CPU_CONFIG_NINT_SHIFT ) &
QCA955X_PLL_CPU_CONFIG_NINT_MASK ;
frac = ( pll > > QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT ) &
QCA955X_PLL_CPU_CONFIG_NFRAC_MASK ;
2013-08-28 10:41:46 +02:00
cpu_pll = nint * ref_rate / ref_div ;
cpu_pll + = frac * ref_rate / ( ref_div * ( 1 < < 6 ) ) ;
2013-02-15 13:38:17 +00:00
cpu_pll / = ( 1 < < out_div ) ;
pll = ath79_pll_rr ( QCA955X_PLL_DDR_CONFIG_REG ) ;
out_div = ( pll > > QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT ) &
QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK ;
ref_div = ( pll > > QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT ) &
QCA955X_PLL_DDR_CONFIG_REFDIV_MASK ;
nint = ( pll > > QCA955X_PLL_DDR_CONFIG_NINT_SHIFT ) &
QCA955X_PLL_DDR_CONFIG_NINT_MASK ;
frac = ( pll > > QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT ) &
QCA955X_PLL_DDR_CONFIG_NFRAC_MASK ;
2013-08-28 10:41:46 +02:00
ddr_pll = nint * ref_rate / ref_div ;
ddr_pll + = frac * ref_rate / ( ref_div * ( 1 < < 10 ) ) ;
2013-02-15 13:38:17 +00:00
ddr_pll / = ( 1 < < out_div ) ;
clk_ctrl = ath79_pll_rr ( QCA955X_PLL_CLK_CTRL_REG ) ;
postdiv = ( clk_ctrl > > QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT ) &
QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK ;
if ( clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS )
2013-08-28 10:41:46 +02:00
cpu_rate = ref_rate ;
2013-02-15 13:38:17 +00:00
else if ( clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL )
2013-08-28 10:41:46 +02:00
cpu_rate = ddr_pll / ( postdiv + 1 ) ;
2013-02-15 13:38:17 +00:00
else
2013-08-28 10:41:46 +02:00
cpu_rate = cpu_pll / ( postdiv + 1 ) ;
2013-02-15 13:38:17 +00:00
postdiv = ( clk_ctrl > > QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT ) &
QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK ;
if ( clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS )
2013-08-28 10:41:46 +02:00
ddr_rate = ref_rate ;
2013-02-15 13:38:17 +00:00
else if ( clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL )
2013-08-28 10:41:46 +02:00
ddr_rate = cpu_pll / ( postdiv + 1 ) ;
2013-02-15 13:38:17 +00:00
else
2013-08-28 10:41:46 +02:00
ddr_rate = ddr_pll / ( postdiv + 1 ) ;
2013-02-15 13:38:17 +00:00
postdiv = ( clk_ctrl > > QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT ) &
QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK ;
if ( clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS )
2013-08-28 10:41:46 +02:00
ahb_rate = ref_rate ;
2013-02-15 13:38:17 +00:00
else if ( clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL )
2013-08-28 10:41:46 +02:00
ahb_rate = ddr_pll / ( postdiv + 1 ) ;
2013-02-15 13:38:17 +00:00
else
2013-08-28 10:41:46 +02:00
ahb_rate = cpu_pll / ( postdiv + 1 ) ;
ath79_ref_clk . rate = ref_rate ;
ath79_cpu_clk . rate = cpu_rate ;
ath79_ddr_clk . rate = ddr_rate ;
ath79_ahb_clk . rate = ahb_rate ;
2013-02-15 13:38:17 +00:00
ath79_wdt_clk . rate = ath79_ref_clk . rate ;
ath79_uart_clk . rate = ath79_ref_clk . rate ;
}
2011-01-04 21:28:14 +01:00
void __init ath79_clocks_init ( void )
{
if ( soc_is_ar71xx ( ) )
ar71xx_clocks_init ( ) ;
else if ( soc_is_ar724x ( ) )
ar724x_clocks_init ( ) ;
else if ( soc_is_ar913x ( ) )
ar913x_clocks_init ( ) ;
2011-06-20 21:26:04 +02:00
else if ( soc_is_ar933x ( ) )
ar933x_clocks_init ( ) ;
2012-03-14 10:45:22 +01:00
else if ( soc_is_ar934x ( ) )
ar934x_clocks_init ( ) ;
2013-02-15 13:38:17 +00:00
else if ( soc_is_qca955x ( ) )
qca955x_clocks_init ( ) ;
2011-01-04 21:28:14 +01:00
else
BUG ( ) ;
}
2013-08-28 10:41:44 +02:00
unsigned long __init
ath79_get_sys_clk_rate ( const char * id )
{
struct clk * clk ;
unsigned long rate ;
clk = clk_get ( NULL , id ) ;
if ( IS_ERR ( clk ) )
panic ( " unable to get %s clock, err=%d " , id , ( int ) PTR_ERR ( clk ) ) ;
rate = clk_get_rate ( clk ) ;
clk_put ( clk ) ;
return rate ;
}
2011-01-04 21:28:14 +01:00
/*
* Linux clock API
*/
struct clk * clk_get ( struct device * dev , const char * id )
{
if ( ! strcmp ( id , " ref " ) )
return & ath79_ref_clk ;
if ( ! strcmp ( id , " cpu " ) )
return & ath79_cpu_clk ;
if ( ! strcmp ( id , " ddr " ) )
return & ath79_ddr_clk ;
if ( ! strcmp ( id , " ahb " ) )
return & ath79_ahb_clk ;
if ( ! strcmp ( id , " wdt " ) )
return & ath79_wdt_clk ;
if ( ! strcmp ( id , " uart " ) )
return & ath79_uart_clk ;
return ERR_PTR ( - ENOENT ) ;
}
EXPORT_SYMBOL ( clk_get ) ;
int clk_enable ( struct clk * clk )
{
return 0 ;
}
EXPORT_SYMBOL ( clk_enable ) ;
void clk_disable ( struct clk * clk )
{
}
EXPORT_SYMBOL ( clk_disable ) ;
unsigned long clk_get_rate ( struct clk * clk )
{
return clk - > rate ;
}
EXPORT_SYMBOL ( clk_get_rate ) ;
void clk_put ( struct clk * clk )
{
}
EXPORT_SYMBOL ( clk_put ) ;