clk: ti: Add support for dm814x ADPLL
Subsystems (3)
PATCH v3 1/1 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".
Also note that this patch does not implement clk_set_rate for the PLL, that will be posted later on when available.
---
Changes from v2 to v3 are listed below, hopefully I addressed everybody's comments,please check and let me know if I missed something.
After review, it is suggested that Tero applies this patch into an immutable branch against v4.4-rc1 that then gets submitted as a pull request along with other omap clock patches to Mike and Stephen. That way I can merge the clock driver too into my omap-for-v4.5/soc branch.
Changes since v2:
Addressed comments from RMK:
- Use clkdev_create() and set up separate con id from name in format "pll260dcoclkldo" to avoid the MAX_CON_ID limitations
Addressed comments from Tero:
- Change register access to use offsets from d->regs instead of setting up separate void __iomem * registers
- Change ti_adpll_clkout_set_parent() to return -EAGAIN if unavailable parent is selected
Addressed comments from Matthijs:
- Standardize on "dcoclkldo" output name and use that name also for TRM "clkdcoldo"
- Use "bypass" name instead of "ulow" used in TRM
- Use 16-bit register access in ti_adpll_recalc_rate() to simplify the code
- Use ti_adpll_set_idle_bypass() naming to make it clear it's the idle mode
- Check PLL lock for both ti_adpll_is_prepared() and ti_adpll_wait_lock()
--- .../devicetree/bindings/clock/ti/adpll.txt | 43 + drivers/clk/Kconfig | 1 + drivers/clk/ti/Kconfig | 6 + drivers/clk/ti/Makefile | 2 + drivers/clk/ti/adpll.c | 1003 ++++++++++++++++++++ drivers/clk/ti/clk-814x.c | 53 ++ 6 files changed, 1108 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/ti/adpll.txt create mode 100644 drivers/clk/ti/Kconfig create mode 100644 drivers/clk/ti/adpll.c
Documentation/devicetree/bindings/clock/ti/adpll.txt new file +43 -0
@@ -0,0 +1,43 @@ +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 0. +- 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 at 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-indices = <0>, <1>, <2>, <3>; + clock-output-names = "481c5040.adpll.dcoclkldo", + "481c5040.adpll.clkout", + "481c5040.adpll.clkoutx2", + "481c5040.adpll.clkouthif"; + }; + + adpll_dsp_ck: adpll at 80 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x80 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-indices = <0>, <1>, <2>; + clock-output-names = "481c5080.adpll.dcoclkldo", + "481c5080.adpll.clkout", + "481c5080.adpll.clkoutldo"; + };
drivers/clk/Kconfig +1 -0
@@ -190,6 +190,7 @@ config COMMON_CLK_CDCE706 source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" +source "drivers/clk/ti/Kconfig" source "drivers/clk/qcom/Kconfig" endmenu
drivers/clk/ti/Kconfig new file +6 -0
@@ -0,0 +1,6 @@ +config COMMON_CLK_TI_ADPLL + tristate "Clock driver for dm814x ADPLL" + depends on ARCH_OMAP2PLUS + default y if SOC_TI81XX + ---help--- + ADPLL clock driver for the dm814x SoC using common clock framework.
drivers/clk/ti/Makefile +2 -0
@@ -18,3 +18,5 @@ obj-$(CONFIG_SOC_AM43XX) += $(clk-common) dpll3xxx.o clk-43xx.o ifdef CONFIG_ATAGS obj-$(CONFIG_ARCH_OMAP3) += clk-3xxx-legacy.o endif + +obj-$(CONFIG_COMMON_CLK_TI_ADPLL) += adpll.o
drivers/clk/ti/adpll.c new file +1003 -0
1,003 lines not on this page · raw message
drivers/clk/ti/clk-814x.c +53 -0
72 lines not on this page · raw message
Signature · 1 line
2.6.2
PATCH v3 1/1 clk: ti: Add support for dm814x ADPLL
Quoted 11 lines · Tony Lindgren
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_initcalllevels topostcore_initcall".Also note that this patch does not implement
clk_set_ratefor the PLL, that will be posted later on when available.
Quoted 7 lines
Cc Michael Turquette <[email protected]>Cc Stephen Boyd <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>---
Changes from v2 to v3 are listed below, hopefully I addressed everybody's comments,please check and let me know if I missed something.
Everybody OK with this version as no more comments?
I found a few issues that are worth merging while testing:
- We want to create the clkdev entry for all clocks, not just outputs
- ti_adpll_wait_lock loops did not do the right thing
- We want to use CLK_GET_RATE_NOCACHE in ti_adpll_init_dco
Diff against v3 below for reference, will also send out v4 separately.
Regards,
Tony
8< ---------------------
drivers/clk/ti/adpll.c +5 -4
@@ -228,9 +228,6 @@ static int ti_adpll_setup_clock(struct ti_adpll_data *d, struct clk *clock, d->clocks[index].clk = clock; d->clocks[index].unregister = unregister; -if (output_index <0 ) -return 0 ; -/* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */ postfix =strrchr (name,'.' );if (strlen (postfix) >1 ) {
@@ -246,6 +243,9 @@ static int ti_adpll_setup_clock(struct ti_adpll_data *d, struct clk *clock,dev_warn (d->dev,"no con_id for clock %s\n" , name); } +if (output_index <0 ) +return 0 ; + d->outputs.clks[output_index] = clock; d->outputs.clk_num++;
@@ -418,7 +418,7 @@ static int ti_adpll_wait_lock(struct ti_adpll_data *d)if (ti_adpll_is_locked (d))return 0 ;usleep_range (200 ,300 ); - }while (retries-- <=0 ); + }while (retries--);dev_err (d->dev,"pll failed to lock\n" );return -ETIMEDOUT ;
@@ -527,6 +527,7 @@ static int ti_adpll_init_dco(struct ti_adpll_data *d) init.parent_names = d->parent_names; init.num_parents = d->c->nr_max_inputs; init.ops = &ti_adpll_ops; + init.flags =CLK_GET_RATE_NOCACHE ; d->dco.hw.init = &init;if (d->c->is_type_s)