Commit 21330497 authored by Tony Lindgren's avatar Tony Lindgren Committed by Michael Turquette

clk: ti: Add support for dm814x ADPLL

On dm814x we have 13 ADPLLs with 3 to 4 outputs on each. The
ADPLLs have several dividers and muxes controlled by a shared
control register for each PLL.

Note that for the clocks to work as device drivers for booting on
dm814x, this patch depends on "ARM: OMAP2+: Change core_initcall
levels to postcore_initcall" that has already been merged.

Also note that this patch does not implement clk_set_rate for the
PLL, that will be posted later on when available.

Cc: Stephen Boyd <sboyd@codeaurora.org>
Acked-by: default avatarTero Kristo <t-kristo@ti.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarMichael Turquette <mturquette@baylibre.com>
parent 92e963f5
Binding for Texas Instruments ADPLL clock.
Binding status: Unstable - ABI compatibility may be broken in the future
This binding uses the common clock binding[1]. It assumes a
register-mapped ADPLL with two to three selectable input clocks
and three to four children.
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be one of "ti,dm814-adpll-s-clock" or
"ti,dm814-adpll-lj-clock" depending on the type of the ADPLL
- #clock-cells : from common clock binding; shall be set to 1.
- clocks : link phandles of parent clocks clkinp and clkinpulow, note
that the adpll-s-clock also has an optional clkinphif
- reg : address and length of the register set for controlling the ADPLL.
Examples:
adpll_mpu_ck: adpll@40 {
#clock-cells = <1>;
compatible = "ti,dm814-adpll-s-clock";
reg = <0x40 0x40>;
clocks = <&devosc_ck &devosc_ck &devosc_ck>;
clock-names = "clkinp", "clkinpulow", "clkinphif";
clock-output-names = "481c5040.adpll.dcoclkldo",
"481c5040.adpll.clkout",
"481c5040.adpll.clkoutx2",
"481c5040.adpll.clkouthif";
};
adpll_dsp_ck: adpll@80 {
#clock-cells = <1>;
compatible = "ti,dm814-adpll-lj-clock";
reg = <0x80 0x30>;
clocks = <&devosc_ck &devosc_ck>;
clock-names = "clkinp", "clkinpulow";
clock-output-names = "481c5080.adpll.dcoclkldo",
"481c5080.adpll.clkout",
"481c5080.adpll.clkoutldo";
};
...@@ -203,6 +203,7 @@ config COMMON_CLK_CDCE706 ...@@ -203,6 +203,7 @@ config COMMON_CLK_CDCE706
source "drivers/clk/bcm/Kconfig" source "drivers/clk/bcm/Kconfig"
source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/hisilicon/Kconfig"
source "drivers/clk/qcom/Kconfig" source "drivers/clk/qcom/Kconfig"
source "drivers/clk/ti/Kconfig"
endmenu endmenu
......
config COMMON_CLK_TI_ADPLL
tristate "Clock driver for dm814x ADPLL"
depends on ARCH_OMAP2PLUS || COMPILE_TEST
default y if SOC_TI81XX
---help---
ADPLL clock driver for the dm814x SoC using common clock framework.
...@@ -18,3 +18,5 @@ obj-$(CONFIG_SOC_AM43XX) += $(clk-common) dpll3xxx.o clk-43xx.o ...@@ -18,3 +18,5 @@ obj-$(CONFIG_SOC_AM43XX) += $(clk-common) dpll3xxx.o clk-43xx.o
ifdef CONFIG_ATAGS ifdef CONFIG_ATAGS
obj-$(CONFIG_ARCH_OMAP3) += clk-3xxx-legacy.o obj-$(CONFIG_ARCH_OMAP3) += clk-3xxx-legacy.o
endif endif
obj-$(CONFIG_COMMON_CLK_TI_ADPLL) += adpll.o
This diff is collapsed.
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/clk/ti.h> #include <linux/clk/ti.h>
#include <linux/of_platform.h>
#include "clock.h" #include "clock.h"
...@@ -27,11 +29,62 @@ static struct ti_dt_clk dm814_clks[] = { ...@@ -27,11 +29,62 @@ static struct ti_dt_clk dm814_clks[] = {
{ .node_name = NULL }, { .node_name = NULL },
}; };
static bool timer_clocks_initialized;
int __init dm814x_adpll_early_init(void)
{
struct device_node *np;
if (!timer_clocks_initialized)
return -ENODEV;
np = of_find_node_by_name(NULL, "pllss");
if (!np) {
pr_err("Could not find node for plls\n");
return -ENODEV;
}
of_platform_populate(np, NULL, NULL, NULL);
return 0;
}
core_initcall(dm814x_adpll_early_init);
static const char * const init_clocks[] = {
"pll040clkout", /* MPU 481c5040.adpll.clkout */
"pll290clkout", /* DDR 481c5290.adpll.clkout */
};
int __init dm814x_adpll_enable_init_clocks(void)
{
int i, err;
if (!timer_clocks_initialized)
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(init_clocks); i++) {
struct clk *clock;
clock = clk_get(NULL, init_clocks[i]);
if (WARN(IS_ERR(clock), "could not find init clock %s\n",
init_clocks[i]))
continue;
err = clk_prepare_enable(clock);
if (WARN(err, "could not enable init clock %s\n",
init_clocks[i]))
continue;
}
return 0;
}
postcore_initcall(dm814x_adpll_enable_init_clocks);
int __init dm814x_dt_clk_init(void) int __init dm814x_dt_clk_init(void)
{ {
ti_dt_clocks_register(dm814_clks); ti_dt_clocks_register(dm814_clks);
omap2_clk_disable_autoidle_all(); omap2_clk_disable_autoidle_all();
omap2_clk_enable_init_clocks(NULL, 0); omap2_clk_enable_init_clocks(NULL, 0);
timer_clocks_initialized = true;
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment