Skip to content

Commit

Permalink
clk: mvebu: Add the xtal clock for Armada 3700 SoC
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
gclement authored and bebarino committed Aug 15, 2016
1 parent cedfbc3 commit 7ea8250
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
3 changes: 3 additions & 0 deletions drivers/clk/mvebu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ config ARMADA_39X_CLK
bool
select MVEBU_CLK_COMMON

config ARMADA_37XX_CLK
bool

config ARMADA_XP_CLK
bool
select MVEBU_CLK_COMMON
Expand Down
1 change: 1 addition & 0 deletions drivers/clk/mvebu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o
obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o
obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o
obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o
obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-xtal.o
obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o
obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o
obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o
Expand Down
91 changes: 91 additions & 0 deletions drivers/clk/mvebu/armada-37xx-xtal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Marvell Armada 37xx SoC xtal clocks
*
* Copyright (C) 2016 Marvell
*
* Gregory CLEMENT <gregory.clement@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/

#include <linux/clk-provider.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#define NB_GPIO1_LATCH 0xC
#define XTAL_MODE BIT(31)

static int armada_3700_xtal_clock_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
const char *xtal_name = "xtal";
struct device_node *parent;
struct regmap *regmap;
struct clk_hw *xtal_hw;
unsigned int rate;
u32 reg;
int ret;

xtal_hw = devm_kzalloc(&pdev->dev, sizeof(*xtal_hw), GFP_KERNEL);
if (!xtal_hw)
return -ENOMEM;

platform_set_drvdata(pdev, xtal_hw);

parent = np->parent;
if (!parent) {
dev_err(&pdev->dev, "no parent\n");
return -ENODEV;
}

regmap = syscon_node_to_regmap(parent);
if (IS_ERR(regmap)) {
dev_err(&pdev->dev, "cannot get regmap\n");
return PTR_ERR(regmap);
}

ret = regmap_read(regmap, NB_GPIO1_LATCH, &reg);
if (ret) {
dev_err(&pdev->dev, "cannot read from regmap\n");
return ret;
}

if (reg & XTAL_MODE)
rate = 40000000;
else
rate = 25000000;

of_property_read_string_index(np, "clock-output-names", 0, &xtal_name);
xtal_hw = clk_hw_register_fixed_rate(NULL, xtal_name, NULL, 0, rate);
if (IS_ERR(xtal_hw))
return PTR_ERR(xtal_hw);
ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, xtal_hw);

return ret;
}

static int armada_3700_xtal_clock_remove(struct platform_device *pdev)
{
of_clk_del_provider(pdev->dev.of_node);

return 0;
}

static const struct of_device_id armada_3700_xtal_clock_of_match[] = {
{ .compatible = "marvell,armada-3700-xtal-clock", },
{ }
};

static struct platform_driver armada_3700_xtal_clock_driver = {
.probe = armada_3700_xtal_clock_probe,
.remove = armada_3700_xtal_clock_remove,
.driver = {
.name = "marvell-armada-3700-xtal-clock",
.of_match_table = armada_3700_xtal_clock_of_match,
},
};

builtin_platform_driver(armada_3700_xtal_clock_driver);

0 comments on commit 7ea8250

Please sign in to comment.