diff options
author | Gregory CLEMENT <gregory.clement@free-electrons.com> | 2016-07-19 09:42:18 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2016-08-15 17:07:04 -0400 |
commit | 7ea8250406a6abe2f057c2096249c63b788b728f (patch) | |
tree | d82db60e5cbe8c03ab5b930d20d0eba2c5e34fcc | |
parent | cedfbc309d62f8f029dc0c3b926452cc84796023 (diff) |
clk: mvebu: Add the xtal clock for Armada 3700 SoC
This clock is the parent of all the Armada 3700 clocks. It is a fixed
rate clock which depends on the gpio configuration read when resetting
the SoC.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-rw-r--r-- | drivers/clk/mvebu/Kconfig | 3 | ||||
-rw-r--r-- | drivers/clk/mvebu/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/mvebu/armada-37xx-xtal.c | 91 |
3 files changed, 95 insertions, 0 deletions
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index 3165da77d525..fddc8ac5faff 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig | |||
@@ -24,6 +24,9 @@ config ARMADA_39X_CLK | |||
24 | bool | 24 | bool |
25 | select MVEBU_CLK_COMMON | 25 | select MVEBU_CLK_COMMON |
26 | 26 | ||
27 | config ARMADA_37XX_CLK | ||
28 | bool | ||
29 | |||
27 | config ARMADA_XP_CLK | 30 | config ARMADA_XP_CLK |
28 | bool | 31 | bool |
29 | select MVEBU_CLK_COMMON | 32 | select MVEBU_CLK_COMMON |
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index 7172ef65693d..4257a36d0219 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile | |||
@@ -6,6 +6,7 @@ obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o | |||
6 | obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o | 6 | obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o |
7 | obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o | 7 | obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o |
8 | obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o | 8 | obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o |
9 | obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-xtal.o | ||
9 | obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o | 10 | obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o |
10 | obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o | 11 | obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o |
11 | obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o | 12 | obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o |
diff --git a/drivers/clk/mvebu/armada-37xx-xtal.c b/drivers/clk/mvebu/armada-37xx-xtal.c new file mode 100644 index 000000000000..612d65ede10a --- /dev/null +++ b/drivers/clk/mvebu/armada-37xx-xtal.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Marvell Armada 37xx SoC xtal clocks | ||
3 | * | ||
4 | * Copyright (C) 2016 Marvell | ||
5 | * | ||
6 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/clk-provider.h> | ||
14 | #include <linux/mfd/syscon.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/regmap.h> | ||
17 | |||
18 | #define NB_GPIO1_LATCH 0xC | ||
19 | #define XTAL_MODE BIT(31) | ||
20 | |||
21 | static int armada_3700_xtal_clock_probe(struct platform_device *pdev) | ||
22 | { | ||
23 | struct device_node *np = pdev->dev.of_node; | ||
24 | const char *xtal_name = "xtal"; | ||
25 | struct device_node *parent; | ||
26 | struct regmap *regmap; | ||
27 | struct clk_hw *xtal_hw; | ||
28 | unsigned int rate; | ||
29 | u32 reg; | ||
30 | int ret; | ||
31 | |||
32 | xtal_hw = devm_kzalloc(&pdev->dev, sizeof(*xtal_hw), GFP_KERNEL); | ||
33 | if (!xtal_hw) | ||
34 | return -ENOMEM; | ||
35 | |||
36 | platform_set_drvdata(pdev, xtal_hw); | ||
37 | |||
38 | parent = np->parent; | ||
39 | if (!parent) { | ||
40 | dev_err(&pdev->dev, "no parent\n"); | ||
41 | return -ENODEV; | ||
42 | } | ||
43 | |||
44 | regmap = syscon_node_to_regmap(parent); | ||
45 | if (IS_ERR(regmap)) { | ||
46 | dev_err(&pdev->dev, "cannot get regmap\n"); | ||
47 | return PTR_ERR(regmap); | ||
48 | } | ||
49 | |||
50 | ret = regmap_read(regmap, NB_GPIO1_LATCH, ®); | ||
51 | if (ret) { | ||
52 | dev_err(&pdev->dev, "cannot read from regmap\n"); | ||
53 | return ret; | ||
54 | } | ||
55 | |||
56 | if (reg & XTAL_MODE) | ||
57 | rate = 40000000; | ||
58 | else | ||
59 | rate = 25000000; | ||
60 | |||
61 | of_property_read_string_index(np, "clock-output-names", 0, &xtal_name); | ||
62 | xtal_hw = clk_hw_register_fixed_rate(NULL, xtal_name, NULL, 0, rate); | ||
63 | if (IS_ERR(xtal_hw)) | ||
64 | return PTR_ERR(xtal_hw); | ||
65 | ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, xtal_hw); | ||
66 | |||
67 | return ret; | ||
68 | } | ||
69 | |||
70 | static int armada_3700_xtal_clock_remove(struct platform_device *pdev) | ||
71 | { | ||
72 | of_clk_del_provider(pdev->dev.of_node); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static const struct of_device_id armada_3700_xtal_clock_of_match[] = { | ||
78 | { .compatible = "marvell,armada-3700-xtal-clock", }, | ||
79 | { } | ||
80 | }; | ||
81 | |||
82 | static struct platform_driver armada_3700_xtal_clock_driver = { | ||
83 | .probe = armada_3700_xtal_clock_probe, | ||
84 | .remove = armada_3700_xtal_clock_remove, | ||
85 | .driver = { | ||
86 | .name = "marvell-armada-3700-xtal-clock", | ||
87 | .of_match_table = armada_3700_xtal_clock_of_match, | ||
88 | }, | ||
89 | }; | ||
90 | |||
91 | builtin_platform_driver(armada_3700_xtal_clock_driver); | ||