diff options
Diffstat (limited to 'drivers')
107 files changed, 11757 insertions, 5770 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 1c4e1aa6767e..98ce9fc6e6c0 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -142,6 +142,18 @@ config COMMON_CLK_GEMINI This driver supports the SoC clocks on the Cortina Systems Gemini platform, also known as SL3516 or CS3516. +config COMMON_CLK_ASPEED + bool "Clock driver for Aspeed BMC SoCs" + depends on ARCH_ASPEED || COMPILE_TEST + default ARCH_ASPEED + select MFD_SYSCON + select RESET_CONTROLLER + ---help--- + This driver supports the SoC clocks on the Aspeed BMC platforms. + + The G4 and G5 series, including the ast2400 and ast2500, are supported + by this driver. + config COMMON_CLK_S2MPS11 tristate "Clock driver for S2MPS1X/S5M8767 MFD" depends on MFD_SEC_CORE || COMPILE_TEST @@ -236,6 +248,7 @@ source "drivers/clk/mvebu/Kconfig" source "drivers/clk/qcom/Kconfig" source "drivers/clk/renesas/Kconfig" source "drivers/clk/samsung/Kconfig" +source "drivers/clk/sprd/Kconfig" source "drivers/clk/sunxi-ng/Kconfig" source "drivers/clk/tegra/Kconfig" source "drivers/clk/ti/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f7f761b02bed..71ec41e6364f 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o +obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o @@ -67,7 +68,7 @@ obj-$(CONFIG_ARCH_MXC) += imx/ obj-$(CONFIG_MACH_INGENIC) += ingenic/ obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ obj-$(CONFIG_MACH_LOONGSON32) += loongson1/ -obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ +obj-y += mediatek/ obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/ obj-$(CONFIG_MACH_PIC32) += microchip/ ifeq ($(CONFIG_COMMON_CLK), y) @@ -85,6 +86,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ obj-$(CONFIG_ARCH_SIRF) += sirf/ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ +obj-$(CONFIG_ARCH_SPRD) += sprd/ obj-$(CONFIG_ARCH_STI) += st/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_ARCH_SUNXI) += sunxi-ng/ diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index 85a449cf61e3..0e6aab1252fc 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c @@ -204,6 +204,8 @@ at91_clk_register_programmable(struct regmap *regmap, if (ret) { kfree(prog); hw = ERR_PTR(ret); + } else { + pmc_register_pck(id); } return hw; diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 775af473fe11..1fa27f4ea538 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -22,6 +22,7 @@ #include "pmc.h" #define PMC_MAX_IDS 128 +#define PMC_MAX_PCKS 8 int of_at91_get_clk_range(struct device_node *np, const char *propname, struct clk_range *range) @@ -50,6 +51,7 @@ EXPORT_SYMBOL_GPL(of_at91_get_clk_range); static struct regmap *pmcreg; static u8 registered_ids[PMC_MAX_IDS]; +static u8 registered_pcks[PMC_MAX_PCKS]; static struct { @@ -66,8 +68,13 @@ static struct u32 pcr[PMC_MAX_IDS]; u32 audio_pll0; u32 audio_pll1; + u32 pckr[PMC_MAX_PCKS]; } pmc_cache; +/* + * As Peripheral ID 0 is invalid on AT91 chips, the identifier is stored + * without alteration in the table, and 0 is for unused clocks. + */ void pmc_register_id(u8 id) { int i; @@ -82,11 +89,30 @@ void pmc_register_id(u8 id) } } +/* + * As Programmable Clock 0 is valid on AT91 chips, there is an offset + * of 1 between the stored value and the real clock ID. + */ +void pmc_register_pck(u8 pck) +{ + int i; + + for (i = 0; i < PMC_MAX_PCKS; i++) { + if (registered_pcks[i] == 0) { + registered_pcks[i] = pck + 1; + break; + } + if (registered_pcks[i] == (pck + 1)) + break; + } +} + static int pmc_suspend(void) { int i; + u8 num; - regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.scsr); + regmap_read(pmcreg, AT91_PMC_SCSR, &pmc_cache.scsr); regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0); regmap_read(pmcreg, AT91_CKGR_UCKR, &pmc_cache.uckr); regmap_read(pmcreg, AT91_CKGR_MOR, &pmc_cache.mor); @@ -103,14 +129,29 @@ static int pmc_suspend(void) regmap_read(pmcreg, AT91_PMC_PCR, &pmc_cache.pcr[registered_ids[i]]); } + for (i = 0; registered_pcks[i]; i++) { + num = registered_pcks[i] - 1; + regmap_read(pmcreg, AT91_PMC_PCKR(num), &pmc_cache.pckr[num]); + } return 0; } +static bool pmc_ready(unsigned int mask) +{ + unsigned int status; + + regmap_read(pmcreg, AT91_PMC_SR, &status); + + return ((status & mask) == mask) ? 1 : 0; +} + static void pmc_resume(void) { - int i, ret = 0; + int i; + u8 num; u32 tmp; + u32 mask = AT91_PMC_MCKRDY | AT91_PMC_LOCKA; regmap_read(pmcreg, AT91_PMC_MCKR, &tmp); if (pmc_cache.mckr != tmp) @@ -119,7 +160,7 @@ static void pmc_resume(void) if (pmc_cache.pllar != tmp) pr_warn("PLLAR was not configured properly by the firmware\n"); - regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.scsr); + regmap_write(pmcreg, AT91_PMC_SCER, pmc_cache.scsr); regmap_write(pmcreg, AT91_PMC_PCER, pmc_cache.pcsr0); regmap_write(pmcreg, AT91_CKGR_UCKR, pmc_cache.uckr); regmap_write(pmcreg, AT91_CKGR_MOR, pmc_cache.mor); @@ -133,14 +174,16 @@ static void pmc_resume(void) pmc_cache.pcr[registered_ids[i]] | AT91_PMC_PCR_CMD); } - - if (pmc_cache.uckr & AT91_PMC_UPLLEN) { - ret = regmap_read_poll_timeout(pmcreg, AT91_PMC_SR, tmp, - !(tmp & AT91_PMC_LOCKU), - 10, 5000); - if (ret) - pr_crit("USB PLL didn't lock when resuming\n"); + for (i = 0; registered_pcks[i]; i++) { + num = registered_pcks[i] - 1; + regmap_write(pmcreg, AT91_PMC_PCKR(num), pmc_cache.pckr[num]); } + + if (pmc_cache.uckr & AT91_PMC_UPLLEN) + mask |= AT91_PMC_LOCKU; + + while (!pmc_ready(mask)) + cpu_relax(); } static struct syscore_ops pmc_syscore_ops = { diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 858e8ef7e8db..d22b1fa9ecdc 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -31,8 +31,10 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname, #ifdef CONFIG_PM void pmc_register_id(u8 id); +void pmc_register_pck(u8 pck); #else static inline void pmc_register_id(u8 id) {} +static inline void pmc_register_pck(u8 pck) {} #endif #endif /* __PMC_H_ */ diff --git a/drivers/clk/bcm/clk-cygnus.c b/drivers/clk/bcm/clk-cygnus.c index 464fdc4bc66b..b8d073e4855f 100644 --- a/drivers/clk/bcm/clk-cygnus.c +++ b/drivers/clk/bcm/clk-cygnus.c @@ -269,23 +269,10 @@ static void __init cygnus_asiu_init(struct device_node *node) } CLK_OF_DECLARE(cygnus_asiu_clk, "brcm,cygnus-asiu-clk", cygnus_asiu_init); -/* - * AUDIO PLL VCO frequency parameter table - * - * PLL output frequency = ((ndiv_int + ndiv_frac / 2^20) * - * (parent clock rate / pdiv) - * - * On Cygnus, parent is the 25MHz oscillator - */ -static const struct iproc_pll_vco_param audiopll_vco_params[] = { - /* rate (Hz) ndiv_int ndiv_frac pdiv */ - { 1354750204UL, 54, 199238, 1 }, - { 1769470191UL, 70, 816639, 1 }, -}; - static const struct iproc_pll_ctrl audiopll = { .flags = IPROC_CLK_PLL_NEEDS_SW_CFG | IPROC_CLK_PLL_HAS_NDIV_FRAC | - IPROC_CLK_PLL_USER_MODE_ON | IPROC_CLK_PLL_RESET_ACTIVE_LOW, + IPROC_CLK_PLL_USER_MODE_ON | IPROC_CLK_PLL_RESET_ACTIVE_LOW | + IPROC_CLK_PLL_CALC_PARAM, .reset = RESET_VAL(0x5c, 0, 1), .dig_filter = DF_VAL(0x48, 0, 3, 6, 4, 3, 3), .sw_ctrl = SW_CTRL_VAL(0x4, 0), @@ -300,8 +287,7 @@ static const struct iproc_pll_ctrl audiopll = { static const struct iproc_clk_ctrl audiopll_clk[] = { [BCM_CYGNUS_AUDIOPLL_CH0] = { .channel = BCM_CYGNUS_AUDIOPLL_CH0, - .flags = IPROC_CLK_AON | - IPROC_CLK_MCLK_DIV_BY_2, + .flags = IPROC_CLK_AON | IPROC_CLK_MCLK_DIV_BY_2, .enable = ENABLE_VAL(0x14, 8, 10, 9), .mdiv = REG_VAL(0x14, 0, 8), }, @@ -321,9 +307,8 @@ static const struct iproc_clk_ctrl audiopll_clk[] = { static void __init cygnus_audiopll_clk_init(struct device_node *node) { - iproc_pll_clk_setup(node, &audiopll, audiopll_vco_params, - ARRAY_SIZE(audiopll_vco_params), audiopll_clk, - ARRAY_SIZE(audiopll_clk)); + iproc_pll_clk_setup(node, &audiopll, NULL, 0, + audiopll_clk, ARRAY_SIZE(audiopll_clk)); } CLK_OF_DECLARE(cygnus_audiopll, "brcm,cygnus-audiopll", cygnus_audiopll_clk_init); diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c index 375d8dd80d45..43a58ae5a89d 100644 --- a/drivers/clk/bcm/clk-iproc-pll.c +++ b/drivers/clk/bcm/clk-iproc-pll.c @@ -69,16 +69,6 @@ enum vco_freq_range { VCO_MAX = 4000000000U, }; -struct iproc_pll; - -struct iproc_clk { - struct clk_hw hw; - const char *name; - struct iproc_pll *pll; - unsigned long rate; - const struct iproc_clk_ctrl *ctrl; -}; - struct iproc_pll { void __iomem *status_base; void __iomem *control_base; @@ |