|
@@ -18,6 +18,8 @@
|
|
#include <linux/clk.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/clkdev.h>
|
|
#include <linux/clkdev.h>
|
|
#include <linux/clk-provider.h>
|
|
#include <linux/clk-provider.h>
|
|
|
|
+#include <linux/of.h>
|
|
|
|
+#include <linux/of_address.h>
|
|
#include <dt-bindings/clock/ath79-clk.h>
|
|
#include <dt-bindings/clock/ath79-clk.h>
|
|
|
|
|
|
#include <asm/div64.h>
|
|
#include <asm/div64.h>
|
|
@@ -25,6 +27,7 @@
|
|
#include <asm/mach-ath79/ath79.h>
|
|
#include <asm/mach-ath79/ath79.h>
|
|
#include <asm/mach-ath79/ar71xx_regs.h>
|
|
#include <asm/mach-ath79/ar71xx_regs.h>
|
|
#include "common.h"
|
|
#include "common.h"
|
|
|
|
+#include "machtypes.h"
|
|
|
|
|
|
#define AR71XX_BASE_FREQ 40000000
|
|
#define AR71XX_BASE_FREQ 40000000
|
|
#define AR724X_BASE_FREQ 40000000
|
|
#define AR724X_BASE_FREQ 40000000
|
|
@@ -87,37 +90,48 @@ static void __init ar71xx_clocks_init(void)
|
|
clk_add_alias("uart", NULL, "ahb", NULL);
|
|
clk_add_alias("uart", NULL, "ahb", NULL);
|
|
}
|
|
}
|
|
|
|
|
|
-static void __init ar724x_clocks_init(void)
|
|
|
|
|
|
+static struct clk * __init ath79_reg_ffclk(const char *name,
|
|
|
|
+ const char *parent_name, unsigned int mult, unsigned int div)
|
|
{
|
|
{
|
|
- unsigned long ref_rate;
|
|
|
|
- unsigned long cpu_rate;
|
|
|
|
- unsigned long ddr_rate;
|
|
|
|
- unsigned long ahb_rate;
|
|
|
|
- u32 pll;
|
|
|
|
- u32 freq;
|
|
|
|
- u32 div;
|
|
|
|
|
|
+ struct clk *clk;
|
|
|
|
|
|
- ref_rate = AR724X_BASE_FREQ;
|
|
|
|
- pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
|
|
|
|
|
|
+ clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div);
|
|
|
|
+ if (!clk)
|
|
|
|
+ panic("failed to allocate %s clock structure", name);
|
|
|
|
|
|
- div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
|
|
|
|
- freq = div * ref_rate;
|
|
|
|
|
|
+ return clk;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base)
|
|
|
|
+{
|
|
|
|
+ u32 pll;
|
|
|
|
+ u32 mult, div, ddr_div, ahb_div;
|
|
|
|
|
|
|
|
+ pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG);
|
|
|
|
+
|
|
|
|
+ mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
|
|
div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2;
|
|
div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2;
|
|
- freq /= div;
|
|
|
|
|
|
|
|
- cpu_rate = freq;
|
|
|
|
|
|
+ ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
|
|
|
|
+ ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
|
|
|
|
|
|
- div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
|
|
|
|
- ddr_rate = freq / div;
|
|
|
|
|
|
+ clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div);
|
|
|
|
+ clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div);
|
|
|
|
+ clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div);
|
|
|
|
+}
|
|
|
|
|
|
- div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
|
|
|
|
- ahb_rate = cpu_rate / div;
|
|
|
|
|
|
+static void __init ar724x_clocks_init(void)
|
|
|
|
+{
|
|
|
|
+ struct clk *ref_clk;
|
|
|
|
|
|
- ath79_add_sys_clkdev("ref", ref_rate);
|
|
|
|
- clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate);
|
|
|
|
- clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate);
|
|
|
|
- clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate);
|
|
|
|
|
|
+ ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ);
|
|
|
|
+
|
|
|
|
+ ar724x_clk_init(ref_clk, ath79_pll_base);
|
|
|
|
+
|
|
|
|
+ /* just make happy plat_time_init() from arch/mips/ath79/setup.c */
|
|
|
|
+ clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL);
|
|
|
|
+ clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL);
|
|
|
|
+ clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL);
|
|
|
|
|
|
clk_add_alias("wdt", NULL, "ahb", NULL);
|
|
clk_add_alias("wdt", NULL, "ahb", NULL);
|
|
clk_add_alias("uart", NULL, "ahb", NULL);
|
|
clk_add_alias("uart", NULL, "ahb", NULL);
|
|
@@ -420,8 +434,6 @@ void __init ath79_clocks_init(void)
|
|
qca955x_clocks_init();
|
|
qca955x_clocks_init();
|
|
else
|
|
else
|
|
BUG();
|
|
BUG();
|
|
-
|
|
|
|
- of_clk_init(NULL);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
unsigned long __init
|
|
unsigned long __init
|
|
@@ -448,8 +460,42 @@ static void __init ath79_clocks_init_dt(struct device_node *np)
|
|
|
|
|
|
CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt);
|
|
CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt);
|
|
CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt);
|
|
CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt);
|
|
-CLK_OF_DECLARE(ar9130, "qca,ar9130-pll", ath79_clocks_init_dt);
|
|
|
|
CLK_OF_DECLARE(ar9330, "qca,ar9330-pll", ath79_clocks_init_dt);
|
|
CLK_OF_DECLARE(ar9330, "qca,ar9330-pll", ath79_clocks_init_dt);
|
|
CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt);
|
|
CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt);
|
|
CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt);
|
|
CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt);
|
|
|
|
+
|
|
|
|
+static void __init ath79_clocks_init_dt_ng(struct device_node *np)
|
|
|
|
+{
|
|
|
|
+ struct clk *ref_clk;
|
|
|
|
+ void __iomem *pll_base;
|
|
|
|
+ const char *dnfn = of_node_full_name(np);
|
|
|
|
+
|
|
|
|
+ ref_clk = of_clk_get(np, 0);
|
|
|
|
+ if (IS_ERR(ref_clk)) {
|
|
|
|
+ pr_err("%s: of_clk_get failed\n", dnfn);
|
|
|
|
+ goto err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pll_base = of_iomap(np, 0);
|
|
|
|
+ if (!pll_base) {
|
|
|
|
+ pr_err("%s: can't map pll registers\n", dnfn);
|
|
|
|
+ goto err_clk;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ar724x_clk_init(ref_clk, pll_base);
|
|
|
|
+
|
|
|
|
+ if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
|
|
|
|
+ pr_err("%s: could not register clk provider\n", dnfn);
|
|
|
|
+ goto err_clk;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+err_clk:
|
|
|
|
+ clk_put(ref_clk);
|
|
|
|
+
|
|
|
|
+err:
|
|
|
|
+ return;
|
|
|
|
+}
|
|
|
|
+CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng);
|
|
#endif
|
|
#endif
|