aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-01-10 09:57:27 -0500
committerLinus Walleij <linus.walleij@linaro.org>2014-02-13 05:20:42 -0500
commit09c978bc7bdcfc3db91801454273a4330e1933bf (patch)
treef823a7d102900acb711ec831574a04f3ff36f45c
parent9cf31380598466a6ce1d95e68a3f89582eaddc13 (diff)
ARM: integrator: switch to fetch clocks from device tree
This atomic commit changes the Integrator clock implementation and the machines to register clocks from the device tree and use these instead of the previous hard-coded clocks. In the clock implementation all hard-coded clocks and the special initialization function call goes away, and is replaced by two compatible strings for the two clocks available on the core module. Cc: Mike Turquette <mturquette@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/clock/arm-integrator.txt34
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c19
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c6
-rw-r--r--drivers/clk/versatile/clk-integrator.c80
-rw-r--r--include/linux/platform_data/clk-integrator.h1
5 files changed, 80 insertions, 60 deletions
diff --git a/Documentation/devicetree/bindings/clock/arm-integrator.txt b/Documentation/devicetree/bindings/clock/arm-integrator.txt
new file mode 100644
index 000000000000..652914b17b95
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/arm-integrator.txt
@@ -0,0 +1,34 @@
1Clock bindings for ARM Integrator Core Module clocks
2
3Auxilary Oscillator Clock
4
5This is a configurable clock fed from a 24 MHz chrystal,
6used for generating e.g. video clocks. It is located on the
7core module and there is only one of these.
8
9This clock node *must* be a subnode of the core module, since
10it obtains the base address for it's address range from its
11parent node.
12
13
14Required properties:
15- compatible: must be "arm,integrator-cm-auxosc"
16- #clock-cells: must be <0>
17
18Optional properties:
19- clocks: parent clock(s)
20
21Example:
22
23core-module@10000000 {
24 xtal24mhz: xtal24mhz@24M {
25 #clock-cells = <0>;
26 compatible = "fixed-clock";
27 clock-frequency = <24000000>;
28 };
29 auxosc: cm_aux_osc@25M {
30 #clock-cells = <0>;
31 compatible = "arm,integrator-cm-auxosc";
32 clocks = <&xtal24mhz>;
33 };
34};
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 17c0fe627435..fedcd2fab094 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -42,6 +42,7 @@
42#include <linux/sys_soc.h> 42#include <linux/sys_soc.h>
43#include <linux/termios.h> 43#include <linux/termios.h>
44#include <linux/sched_clock.h> 44#include <linux/sched_clock.h>
45#include <linux/clk-provider.h>
45 46
46#include <mach/hardware.h> 47#include <mach/hardware.h>
47#include <mach/platform.h> 48#include <mach/platform.h>
@@ -402,10 +403,7 @@ static void __init ap_of_timer_init(void)
402 struct clk *clk; 403 struct clk *clk;
403 unsigned long rate; 404 unsigned long rate;
404 405
405 clk = clk_get_sys("ap_timer", NULL); 406 of_clk_init(NULL);
406 BUG_ON(IS_ERR(clk));
407 clk_prepare_enable(clk);
408 rate = clk_get_rate(clk);
409 407
410 err = of_property_read_string(of_aliases, 408 err = of_property_read_string(of_aliases,
411 "arm,timer-primary", &path); 409 "arm,timer-primary", &path);
@@ -415,6 +413,12 @@ static void __init ap_of_timer_init(void)
415 base = of_iomap(node, 0); 413 base = of_iomap(node, 0);
416 if (WARN_ON(!base)) 414 if (WARN_ON(!base))
417 return; 415 return;
416
417 clk = of_clk_get(node, 0);
418 BUG_ON(IS_ERR(clk));
419 clk_prepare_enable(clk);
420 rate = clk_get_rate(clk);
421
418 writel(0, base + TIMER_CTRL); 422 writel(0, base + TIMER_CTRL);
419 integrator_clocksource_init(rate, base); 423 integrator_clocksource_init(rate, base);
420 424
@@ -427,6 +431,12 @@ static void __init ap_of_timer_init(void)
427 if (WARN_ON(!base)) 431 if (WARN_ON(!base))
428 return; 432 return;
429 irq = irq_of_parse_and_map(node, 0); 433 irq = irq_of_parse_and_map(node, 0);
434
435 clk = of_clk_get(node, 0);
436 BUG_ON(IS_ERR(clk));
437 clk_prepare_enable(clk);
438 rate = clk_get_rate(clk);
439
430 writel(0, base + TIMER_CTRL); 440 writel(0, base + TIMER_CTRL);
431 integrator_clockevent_init(rate, base, irq); 441 integrator_clockevent_init(rate, base, irq);
432} 442}
@@ -440,7 +450,6 @@ static void __init ap_init_irq_of(void)
440{ 450{
441 cm_init(); 451 cm_init();
442 of_irq_init(fpga_irq_of_match); 452 of_irq_init(fpga_irq_of_match);
443 integrator_clk_init(false);
444} 453}
445 454
446/* For the Device Tree, add in the UART callbacks as AUXDATA */ 455/* For the Device Tree, add in the UART callbacks as AUXDATA */
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index a3ef961e4a93..0ad5f60598c8 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -23,7 +23,6 @@
23#include <linux/irqchip/versatile-fpga.h> 23#include <linux/irqchip/versatile-fpga.h>
24#include <linux/gfp.h> 24#include <linux/gfp.h>
25#include <linux/mtd/physmap.h> 25#include <linux/mtd/physmap.h>
26#include <linux/platform_data/clk-integrator.h>
27#include <linux/of_irq.h> 26#include <linux/of_irq.h>
28#include <linux/of_address.h> 27#include <linux/of_address.h>
29#include <linux/of_platform.h> 28#include <linux/of_platform.h>
@@ -33,8 +32,6 @@
33#include <mach/platform.h> 32#include <mach/platform.h>
34#include <asm/setup.h> 33#include <asm/setup.h>
35#include <asm/mach-types.h> 34#include <asm/mach-types.h>
36#include <asm/hardware/arm_timer.h>
37#include <asm/hardware/icst.h>
38 35
39#include <mach/lm.h> 36#include <mach/lm.h>
40 37
@@ -43,8 +40,6 @@
43#include <asm/mach/map.h> 40#include <asm/mach/map.h>
44#include <asm/mach/time.h> 41#include <asm/mach/time.h>
45 42
46#include <asm/hardware/timer-sp.h>
47
48#include <plat/clcd.h> 43#include <plat/clcd.h>
49#include <plat/sched_clock.h> 44#include <plat/sched_clock.h>
50 45
@@ -250,7 +245,6 @@ static void __init intcp_init_irq_of(void)
250{ 245{
251 cm_init(); 246 cm_init();
252 of_irq_init(fpga_irq_of_match); 247 of_irq_init(fpga_irq_of_match);
253 integrator_clk_init(true);
254} 248}
255 249
256/* 250/*
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c
index bda8967e09c2..19864b5690e9 100644
--- a/drivers/clk/versatile/clk-integrator.c
+++ b/drivers/clk/versatile/clk-integrator.c
@@ -10,20 +10,17 @@
10#include <linux/clk.h> 10#include <linux/clk.h>
11#include <linux/clkdev.h> 11#include <linux/clkdev.h>
12#include <linux/err.h> 12#include <linux/err.h>
13#include <linux/platform_data/clk-integrator.h> 13#include <linux/of.h>
14 14#include <linux/of_address.h>
15#include <mach/hardware.h>
16#include <mach/platform.h>
17 15
18#include "clk-icst.h" 16#include "clk-icst.h"
19 17
20/* 18#define INTEGRATOR_HDR_LOCK_OFFSET 0x14
21 * Implementation of the ARM Integrator/AP and Integrator/CP clock tree.
22 * Inspired by portions of:
23 * plat-versatile/clock.c and plat-versatile/include/plat/clock.h
24 */
25 19
26static const struct icst_params cp_auxvco_params = { 20/* Base offset for the core module */
21static void __iomem *cm_base;
22
23static const struct icst_params cp_auxosc_params = {
27 .ref = 24000000, 24 .ref = 24000000,
28 .vco_max = ICST525_VCO_MAX_5V, 25 .vco_max = ICST525_VCO_MAX_5V,
29 .vco_min = ICST525_VCO_MIN, 26 .vco_min = ICST525_VCO_MIN,
@@ -35,50 +32,37 @@ static const struct icst_params cp_auxvco_params = {
35 .idx2s = icst525_idx2s, 32 .idx2s = icst525_idx2s,
36}; 33};
37 34
38static const struct clk_icst_desc __initdata cp_icst_desc = { 35static const struct clk_icst_desc __initdata cm_auxosc_desc = {
39 .params = &cp_auxvco_params, 36 .params = &cp_auxosc_params,
40 .vco_offset = 0x1c, 37 .vco_offset = 0x1c,
41 .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET, 38 .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET,
42}; 39};
43 40
44/* 41static void __init of_integrator_cm_osc_setup(struct device_node *np)
45 * integrator_clk_init() - set up the integrator clock tree
46 * @is_cp: pass true if it's the Integrator/CP else AP is assumed
47 */
48void __init integrator_clk_init(bool is_cp)
49{ 42{
50 struct clk *clk; 43 struct clk *clk = ERR_PTR(-EINVAL);
51 44 const char *clk_name = np->name;
52 /* APB clock dummy */ 45 const struct clk_icst_desc *desc = &cm_auxosc_desc;
53 clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
54 clk_register_clkdev(clk, "apb_pclk", NULL);
55
56 /* UART reference clock */
57 clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT,
58 14745600);
59 clk_register_clkdev(clk, NULL, "uart0");
60 clk_register_clkdev(clk, NULL, "uart1");
61 if (is_cp)
62 clk_register_clkdev(clk, NULL, "mmci");
63
64 /* 24 MHz clock */
65 clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT,
66 24000000);
67 clk_register_clkdev(clk, NULL, "kmi0");
68 clk_register_clkdev(clk, NULL, "kmi1");
69 if (!is_cp)
70 clk_register_clkdev(clk, NULL, "ap_timer");
71 46
72 if (!is_cp) 47 if (!cm_base) {
73 return; 48 /* Remap the core module base if not done yet */
49 struct device_node *parent;
74 50
75 /* 1 MHz clock */ 51 parent = of_get_parent(np);
76 clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT, 52 if (!np) {
77 1000000); 53 pr_err("no parent on core module clock\n");
78 clk_register_clkdev(clk, NULL, "sp804"); 54 return;
55 }
56 cm_base = of_iomap(parent, 0);
57 if (!cm_base) {
58 pr_err("could not remap core module base\n");
59 return;
60 }
61 }
79 62
80 /* ICST VCO clock used on the Integrator/CP CLCD */ 63 clk = icst_clk_register(NULL, desc, clk_name, cm_base);
81 clk = icst_clk_register(NULL, &cp_icst_desc, "icst", 64 if (!IS_ERR(clk))
82 __io_address(INTEGRATOR_HDR_BASE)); 65 of_clk_add_provider(np, of_clk_src_simple_get, clk);
83 clk_register_clkdev(clk, NULL, "clcd");
84} 66}
67CLK_OF_DECLARE(integrator_cm_auxosc_clk,
68 "arm,integrator-cm-auxosc", of_integrator_cm_osc_setup);
diff --git a/include/linux/platform_data/clk-integrator.h b/include/linux/platform_data/clk-integrator.h
index 280edac9d0a5..addd48cac625 100644
--- a/include/linux/platform_data/clk-integrator.h
+++ b/include/linux/platform_data/clk-integrator.h
@@ -1,3 +1,2 @@
1void integrator_clk_init(bool is_cp);
2void integrator_impd1_clk_init(void __iomem *base, unsigned int id); 1void integrator_impd1_clk_init(void __iomem *base, unsigned int id);
3void integrator_impd1_clk_exit(unsigned int id); 2void integrator_impd1_clk_exit(unsigned int id);