diff options
Diffstat (limited to 'drivers/clk')
89 files changed, 12564 insertions, 422 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c3e3a02f7f1f..41f6c7f8e79b 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -116,6 +116,12 @@ config COMMON_CLK_CDCE925 Given a target output frequency, the driver will set the PLL and divider to best approximate the desired output. +config COMMON_CLK_CS2000_CP + tristate "Clock driver for CS2000 Fractional-N Clock Synthesizer & Clock Multiplier" + depends on I2C + help + If you say yes here you get support for the CS2000 clock multiplier. + config COMMON_CLK_S2MPS11 tristate "Clock driver for S2MPS1X/S5M8767 MFD" depends on MFD_SEC_CORE @@ -161,6 +167,12 @@ config COMMON_CLK_KEYSTONE Supports clock drivers for Keystone based SOCs. These SOCs have local a power sleep control module that gate the clock to the IPs and PLLs. +config COMMON_CLK_NXP + def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX) + select REGMAP_MMIO if ARCH_LPC32XX + ---help--- + Support for clock providers on NXP platforms. + config COMMON_CLK_PALMAS tristate "Clock driver for TI Palmas devices" depends on MFD_PALMAS @@ -175,6 +187,11 @@ config COMMON_CLK_PWM Adapter driver so that any PWM output can be (mis)used as clock signal at 50% duty cycle. +config COMMON_CLK_NXP + def_bool COMMON_CLK && ARCH_LPC18XX + ---help--- + Support for clock providers on NXP platforms. + config COMMON_CLK_PXA def_bool COMMON_CLK && ARCH_PXA ---help--- diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 366350a4a1ee..b038e3666058 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o +obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o @@ -42,6 +43,7 @@ obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o +obj-$(CONFIG_ARCH_TANGOX) += clk-tango4.o obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o obj-$(CONFIG_ARCH_U300) += clk-u300.o obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o @@ -62,8 +64,8 @@ endif obj-$(CONFIG_PLAT_ORION) += mvebu/ obj-$(CONFIG_ARCH_MESON) += meson/ obj-$(CONFIG_ARCH_MXS) += mxs/ -obj-$(CONFIG_ARCH_LPC18XX) += nxp/ obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ +obj-$(CONFIG_COMMON_CLK_NXP) += nxp/ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index d0d5076a9b94..6f99a530ead6 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -10,7 +10,6 @@ * */ -#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/clkdev.h> #include <linux/slab.h> @@ -72,8 +71,6 @@ struct clk_sam9x5_slow { #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) -static struct clk *slow_clk; - static int clk_slow_osc_prepare(struct clk_hw *hw) { struct clk_slow_osc *osc = to_clk_slow_osc(hw); @@ -360,8 +357,6 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr, clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); - else - slow_clk = clk; return clk; } @@ -433,8 +428,6 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) kfree(slowck); - else - slow_clk = clk; return clk; } @@ -462,25 +455,3 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np, of_clk_add_provider(np, of_clk_src_simple_get, clk); } - -/* - * FIXME: All slow clk users are not properly claiming it (get + prepare + - * enable) before using it. - * If all users properly claiming this clock decide that they don't need it - * anymore (or are removed), it is disabled while faulty users are still - * requiring it, and the system hangs. - * Prevent this clock from being disabled until all users are properly - * requesting it. - * Once this is done we should remove this function and the slow_clk variable. - */ -static int __init of_at91_clk_slow_retain(void) -{ - if (!slow_clk) - return 0; - - __clk_get(slow_clk); - clk_prepare_enable(slow_clk); - - return 0; -} -arch_initcall(of_at91_clk_slow_retain); diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig index 85260fb96b36..f2878459199a 100644 --- a/drivers/clk/bcm/Kconfig +++ b/drivers/clk/bcm/Kconfig @@ -1,3 +1,13 @@ +config CLK_BCM_63XX + bool "Broadcom BCM63xx clock support" + depends on ARCH_BCM_63XX || COMPILE_TEST + depends on COMMON_CLK + select COMMON_CLK_IPROC + default ARCH_BCM_63XX + help + Enable common clock framework support for Broadcom BCM63xx DSL SoCs + based on the ARM architecture + config CLK_BCM_KONA bool "Broadcom Kona CCU clock support" depends on ARCH_BCM_MOBILE || COMPILE_TEST diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index 3fc95060d875..1d79bd2c36f0 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile @@ -1,9 +1,11 @@ +obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o +obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c new file mode 100644 index 000000000000..e4f89e28b5ec --- /dev/null +++ b/drivers/clk/bcm/clk-bcm2835-aux.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2015 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clk/bcm2835.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <dt-bindings/clock/bcm2835-aux.h> + +#define BCM2835_AUXIRQ 0x00 +#define BCM2835_AUXENB 0x04 + +static int bcm2835_aux_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct clk_onecell_data *onecell; + const char *parent; + struct clk *parent_clk; + struct resource *res; + void __iomem *reg, *gate; + + parent_clk = devm_clk_get(dev, NULL); + if (IS_ERR(parent_clk)) + return PTR_ERR(parent_clk); + parent = __clk_get_name(parent_clk); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(dev, res); + if (!reg) + return -ENODEV; + + onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL); + if (!onecell) + return -ENOMEM; + onecell->clk_num = BCM2835_AUX_CLOCK_COUNT; + onecell->clks = devm_kcalloc(dev, BCM2835_AUX_CLOCK_COUNT, + sizeof(*onecell->clks), GFP_KERNEL); + if (!onecell->clks) + return -ENOMEM; + + gate = reg + BCM2835_AUXENB; + onecell->clks[BCM2835_AUX_CLOCK_UART] = + clk_register_gate(dev, "aux_uart", parent, 0, gate, 0, 0, NULL); + + onecell->clks[BCM2835_AUX_CLOCK_SPI1] = + clk_register_gate(dev, "aux_spi1", parent, 0, gate, 1, 0, NULL); + + onecell->clks[BCM2835_AUX_CLOCK_SPI2] = + clk_register_gate(dev, "aux_spi2", parent, 0, gate, 2, 0, NULL); + + of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, onecell); + + return 0; +} + +static const struct of_device_id bcm2835_aux_clk_of_match[] = { + { .compatible = "brcm,bcm2835-aux", }, + {}, +}; +MODULE_DEVICE_TABLE(of, bcm2835_aux_clk_of_match); + +static struct platform_driver bcm2835_aux_clk_driver = { + .driver = { + .name = "bcm2835-aux-clk", + .of_match_table = bcm2835_aux_clk_of_match, + }, + .probe = bcm2835_aux_clk_probe, +}; +builtin_platform_driver(bcm2835_aux_clk_driver); + +MODULE_AUTHOR("Eric Anholt <eric@anholt.net>"); +MODULE_DESCRIPTION("BCM2835 auxiliary peripheral clock driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 39bf5820297e..015e687ffabe 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -807,6 +807,16 @@ static const struct bcm2835_clock_data bcm2835_clock_emmc_data = { .frac_bits = 8, }; +static const struct bcm2835_clock_data bcm2835_clock_pwm_data = { + .name = "pwm", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_PWMCTL, + .div_reg = CM_PWMDIV, + .int_bits = 12, + .frac_bits = 12, +}; + struct bcm2835_pll { struct clk_hw hw; struct bcm2835_cprman *cprman; @@ -1148,22 +1158,24 @@ static int bcm2835_clock_is_on(struct clk_hw *hw) static u32 bcm2835_clock_choose_div(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) + unsigned long parent_rate, + bool round_up) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); const struct bcm2835_clock_data *data = clock->data; - u32 unused_frac_mask = GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0); + u32 unused_frac_mask = + GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1; u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS; + u64 rem; u32 div; - do_div(temp, rate); + rem = do_div(temp, rate); div = temp; - /* Round and mask off the unused bits */ - if (unused_frac_mask != 0) { - div += unused_frac_mask >> 1; - div &= ~unused_frac_mask; - } + /* Round up and mask off the unused bits */ + if (round_up && ((div & unused_frac_mask) != 0 || rem != 0)) + div += unused_frac_mask + 1; + div &= ~unused_frac_mask; /* Clamp to the limits. */ div = max(div, unused_frac_mask + 1); @@ -1197,16 +1209,6 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, return temp; } -static long bcm2835_clock_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *parent_rate) -{ - struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); - u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate); - - return bcm2835_clock_rate_from_divisor(clock, *parent_ |