diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-25 14:28:06 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-25 14:28:06 -0800 |
commit | 5d8a00eee2ed2e548a5d21b0edf495f3f7bf8bb4 (patch) | |
tree | fdc6c7754a5ea2a8a31df53e181e632e6e84b44f /drivers/clk/mvebu | |
parent | 7067739df23ffd641ca99c967830e0ed2ba39eab (diff) | |
parent | f59de563358eb9351b7f8f0ba2d3be2ebb70b93d (diff) | |
download | lwn-5d8a00eee2ed2e548a5d21b0edf495f3f7bf8bb4.tar.gz lwn-5d8a00eee2ed2e548a5d21b0edf495f3f7bf8bb4.zip |
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd:
"The usual collection of new drivers, non-critical fixes, and updates
to existing clk drivers. The bulk of the work is on Allwinner and
Rockchip SoCs, but there's also an Intel Atom driver in here too.
New Drivers:
- Tegra BPMP firmware
- Hisilicon hi3660 SoCs
- Rockchip rk3328 SoCs
- Intel Atom PMC
- STM32F746
- IDT VersaClock 5P49V5923 and 5P49V5933
- Marvell mv98dx3236 SoCs
- Allwinner V3s SoCs
Removed Drivers:
- Samsung Exynos4415 SoCs
Updates:
- Migrate ABx500 to OF
- Qualcomm IPQ4019 CPU clks and general PLL support
- Qualcomm MSM8974 RPM
- Rockchip non-critical fixes and clk id additions
- Samsung Exynos4412 CPUs
- Socionext UniPhier NAND and eMMC support
- ZTE zx296718 i2s and other audio clks
- Renesas CAN and MSIOF clks for R-Car M3-W
- Renesas resets for R-Car Gen2 and Gen3 and RZ/G1
- TI CDCE913, CDCE937, and CDCE949 clk generators
- Marvell Armada ap806 CPU frequencies
- STM32F4* I2S/SAI support
- Broadcom BCM2835 DSI support
- Allwinner sun5i and A80 conversion to new style clk bindings"
* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (130 commits)
clk: renesas: mstp: ensure register writes complete
clk: qcom: Do not drop device node twice
clk: mvebu: adjust clock handling for the CP110 system controller
clk: mvebu: Expand mv98dx3236-core-clock support
clk: zte: add i2s clocks for zx296718
clk: sunxi-ng: sun9i-a80: Fix wrong pointer passed to PTR_ERR()
clk: sunxi-ng: select SUNXI_CCU_MULT for sun5i
clk: sunxi-ng: Check kzalloc() for errors and cleanup error path
clk: tegra: Add BPMP clock driver
clk: uniphier: add eMMC clock for LD11 and LD20 SoCs
clk: uniphier: add NAND clock for all UniPhier SoCs
ARM: dts: sun9i: Switch to new clock bindings
clk: sunxi-ng: Add A80 Display Engine CCU
clk: sunxi-ng: Add A80 USB CCU
clk: sunxi-ng: Add A80 CCU
clk: sunxi-ng: Support separately grouped PLL lock status register
clk: sunxi-ng: mux: Get closest parent rate possible with CLK_SET_RATE_PARENT
clk: sunxi-ng: mux: honor CLK_SET_RATE_NO_REPARENT flag
clk: sunxi-ng: mux: Fix determine_rate for mux clocks with pre-dividers
clk: qcom: SDHCI enablement on Nexus 5X / 6P
...
Diffstat (limited to 'drivers/clk/mvebu')
-rw-r--r-- | drivers/clk/mvebu/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/mvebu/ap806-system-controller.c | 28 | ||||
-rw-r--r-- | drivers/clk/mvebu/armada-xp.c | 26 | ||||
-rw-r--r-- | drivers/clk/mvebu/clk-corediv.c | 23 | ||||
-rw-r--r-- | drivers/clk/mvebu/clk-cpu.c | 8 | ||||
-rw-r--r-- | drivers/clk/mvebu/cp110-system-controller.c | 13 | ||||
-rw-r--r-- | drivers/clk/mvebu/mv98dx3236.c | 180 |
7 files changed, 272 insertions, 8 deletions
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index d9ae97fb43c4..d71c7fd5da16 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile @@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-xtal.o obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-periph.o -obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o +obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o mv98dx3236.o obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index 8181b919f062..f17702107ac5 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -55,21 +55,39 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev) freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK; switch (freq_mode) { - case 0x0 ... 0x5: + case 0x0: + case 0x1: cpuclk_freq = 2000; break; - case 0x6 ... 0xB: + case 0x6: + case 0x7: cpuclk_freq = 1800; break; - case 0xC ... 0x11: + case 0x4: + case 0xB: + case 0xD: cpuclk_freq = 1600; break; - case 0x12 ... 0x16: + case 0x1a: cpuclk_freq = 1400; break; - case 0x17 ... 0x19: + case 0x14: + case 0x17: cpuclk_freq = 1300; break; + case 0x19: + cpuclk_freq = 1200; + break; + case 0x13: + case 0x1d: + cpuclk_freq = 1000; + break; + case 0x1c: + cpuclk_freq = 800; + break; + case 0x1b: + cpuclk_freq = 600; + break; default: dev_err(&pdev->dev, "invalid SAR value\n"); return -EINVAL; diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c index b3094315a3c0..0ec44ae9a2a2 100644 --- a/drivers/clk/mvebu/armada-xp.c +++ b/drivers/clk/mvebu/armada-xp.c @@ -52,6 +52,12 @@ static u32 __init axp_get_tclk_freq(void __iomem *sar) return 250000000; } +/* MV98DX3236 TCLK frequency is fixed to 200MHz */ +static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar) +{ + return 200000000; +} + static const u32 axp_cpu_freqs[] __initconst = { 1000000000, 1066000000, @@ -89,6 +95,12 @@ static u32 __init axp_get_cpu_freq(void __iomem *sar) return cpu_freq; } +/* MV98DX3236 CLK frequency is fixed to 800MHz */ +static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar) +{ + return 800000000; +} + static const int axp_nbclk_ratios[32][2] __initconst = { {0, 1}, {1, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 1}, {2, 3}, @@ -158,6 +170,11 @@ static const struct coreclk_soc_desc axp_coreclks = { .num_ratios = ARRAY_SIZE(axp_coreclk_ratios), }; +static const struct coreclk_soc_desc mv98dx3236_coreclks = { + .get_tclk_freq = mv98dx3236_get_tclk_freq, + .get_cpu_freq = mv98dx3236_get_cpu_freq, +}; + /* * Clock Gating Control */ @@ -195,6 +212,15 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = { { } }; +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = { + { "ge1", NULL, 3, 0 }, + { "ge0", NULL, 4, 0 }, + { "pex00", NULL, 5, 0 }, + { "sdio", NULL, 17, 0 }, + { "xor0", NULL, 22, 0 }, + { } +}; + static void __init axp_clk_init(struct device_node *np) { struct device_node *cgnp = diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c index d1e5863d3375..8491979f4096 100644 --- a/drivers/clk/mvebu/clk-corediv.c +++ b/drivers/clk/mvebu/clk-corediv.c @@ -71,6 +71,10 @@ static const struct clk_corediv_desc mvebu_corediv_desc[] = { { .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */ }; +static const struct clk_corediv_desc mv98dx3236_corediv_desc[] = { + { .mask = 0x0f, .offset = 6, .fieldbit = 26 }, /* NAND clock */ +}; + #define to_corediv_clk(p) container_of(p, struct clk_corediv, hw) static int clk_corediv_is_enabled(struct clk_hw *hwclk) @@ -232,6 +236,18 @@ static const struct clk_corediv_soc_desc armada375_corediv_soc = { .ratio_offset = 0x4, }; +static const struct clk_corediv_soc_desc mv98dx3236_corediv_soc = { + .descs = mv98dx3236_corediv_desc, + .ndescs = ARRAY_SIZE(mv98dx3236_corediv_desc), + .ops = { + .recalc_rate = clk_corediv_recalc_rate, + .round_rate = clk_corediv_round_rate, + .set_rate = clk_corediv_set_rate, + }, + .ratio_reload = BIT(10), + .ratio_offset = 0x8, +}; + static void __init mvebu_corediv_clk_init(struct device_node *node, const struct clk_corediv_soc_desc *soc_desc) @@ -313,3 +329,10 @@ static void __init armada380_corediv_clk_init(struct device_node *node) } CLK_OF_DECLARE(armada380_corediv_clk, "marvell,armada-380-corediv-clock", armada380_corediv_clk_init); + +static void __init mv98dx3236_corediv_clk_init(struct device_node *node) +{ + return mvebu_corediv_clk_init(node, &mv98dx3236_corediv_soc); +} +CLK_OF_DECLARE(mv98dx3236_corediv_clk, "marvell,mv98dx3236-corediv-clock", + mv98dx3236_corediv_clk_init); diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index 5837eb8a212f..044892b6534d 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c @@ -245,3 +245,11 @@ cpuclk_out: CLK_OF_DECLARE(armada_xp_cpu_clock, "marvell,armada-xp-cpu-clock", of_cpu_clk_setup); + +static void __init of_mv98dx3236_cpu_clk_setup(struct device_node *node) +{ + of_clk_add_provider(node, of_clk_src_simple_get, NULL); +} + +CLK_OF_DECLARE(mv98dx3236_cpu_clock, "marvell,mv98dx3236-cpu-clock", + of_mv98dx3236_cpu_clk_setup); diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c index 32e5b43c086f..6b11d7b3e0e0 100644 --- a/drivers/clk/mvebu/cp110-system-controller.c +++ b/drivers/clk/mvebu/cp110-system-controller.c @@ -64,8 +64,11 @@ enum { #define CP110_GATE_NAND 2 #define CP110_GATE_PPV2 3 #define CP110_GATE_SDIO 4 +#define CP110_GATE_MG 5 +#define CP110_GATE_MG_CORE 6 #define CP110_GATE_XOR1 7 #define CP110_GATE_XOR0 8 +#define CP110_GATE_GOP_DP 9 #define CP110_GATE_PCIE_X1_0 11 #define CP110_GATE_PCIE_X1_1 12 #define CP110_GATE_PCIE_X4 13 @@ -73,7 +76,7 @@ enum { #define CP110_GATE_SATA 15 #define CP110_GATE_SATA_USB 16 #define CP110_GATE_MAIN 17 -#define CP110_GATE_SDMMC 18 +#define CP110_GATE_SDMMC_GOP 18 #define CP110_GATE_SLOW_IO 21 #define CP110_GATE_USB3H0 22 #define CP110_GATE_USB3H1 23 @@ -296,6 +299,11 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) "gate-clock-output-names", CP110_GATE_MAIN, &parent); break; + case CP110_GATE_MG: + of_property_read_string_index(np, + "gate-clock-output-names", + CP110_GATE_MG_CORE, &parent); + break; case CP110_GATE_NAND: parent = nand_name; break; @@ -303,9 +311,10 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) parent = ppv2_name; break; case CP110_GATE_SDIO: + case CP110_GATE_GOP_DP: of_property_read_string_index(np, "gate-clock-output-names", - CP110_GATE_SDMMC, &parent); + CP110_GATE_SDMMC_GOP, &parent); break; case CP110_GATE_XOR1: case CP110_GATE_XOR0: diff --git a/drivers/clk/mvebu/mv98dx3236.c b/drivers/clk/mvebu/mv98dx3236.c new file mode 100644 index 000000000000..6e203af73cac --- /dev/null +++ b/drivers/clk/mvebu/mv98dx3236.c @@ -0,0 +1,180 @@ +/* + * Marvell MV98DX3236 SoC clocks + * + * Copyright (C) 2012 Marvell + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> + * Andrew Lunn <andrew@lunn.ch> + * + * 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/kernel.h> +#include <linux/clk-provider.h> +#include <linux/io.h> +#include <linux/of.h> +#include "common.h" + + +/* + * For 98DX4251 Sample At Reset the CPU, DDR and Main PLL clocks are all + * defined at the same time + * + * SAR1[20:18] : CPU frequency DDR frequency MPLL frequency + * 0 = 400 MHz 400 MHz 800 MHz + * 2 = 667 MHz 667 MHz 2000 MHz + * 3 = 800 MHz 800 MHz 1600 MHz + * others reserved. + * + * For 98DX3236 Sample At Reset the CPU, DDR and Main PLL clocks are all + * defined at the same time + * + * SAR1[20:18] : CPU frequency DDR frequency MPLL frequency + * 1 = 667 MHz 667 MHz 2000 MHz + * 2 = 400 MHz 400 MHz 400 MHz + * 3 = 800 MHz 800 MHz 800 MHz + * 5 = 800 MHz 400 MHz 800 MHz + * others reserved. + */ + +#define SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT 18 +#define SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT_MASK 0x7 + +static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar) +{ + /* Tclk = 200MHz, no SaR dependency */ + return 200000000; +} + +static const u32 mv98dx3236_cpu_frequencies[] __initconst = { + 0, + 667000000, + 400000000, + 800000000, + 0, + 800000000, + 0, 0, +}; + +static const u32 mv98dx4251_cpu_frequencies[] __initconst = { + 400000000, + 0, + 667000000, + 800000000, + 0, 0, 0, 0, +}; + +static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar) +{ + u32 cpu_freq = 0; + u8 cpu_freq_select = 0; + + cpu_freq_select = ((readl(sar) >> SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT) & + SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT_MASK); + + if (of_machine_is_compatible("marvell,armadaxp-98dx4251")) + cpu_freq = mv98dx4251_cpu_frequencies[cpu_freq_select]; + else if (of_machine_is_compatible("marvell,armadaxp-98dx3236")) + cpu_freq = mv98dx3236_cpu_frequencies[cpu_freq_select]; + + if (!cpu_freq) + pr_err("CPU freq select unsupported %d\n", cpu_freq_select); + + return cpu_freq; +} + +enum { + MV98DX3236_CPU_TO_DDR, + MV98DX3236_CPU_TO_MPLL +}; + +static const struct coreclk_ratio mv98dx3236_core_ratios[] __initconst = { + { .id = MV98DX3236_CPU_TO_DDR, .name = "ddrclk" }, + { .id = MV98DX3236_CPU_TO_MPLL, .name = "mpll" }, +}; + +static const int __initconst mv98dx3236_cpu_mpll_ratios[8][2] = { + {0, 1}, {3, 1}, {1, 1}, {1, 1}, + {0, 1}, {1, 1}, {0, 1}, {0, 1}, +}; + +static const int __initconst mv98dx3236_cpu_ddr_ratios[8][2] = { + {0, 1}, {1, 1}, {1, 1}, {1, 1}, + {0, 1}, {1, 2}, {0, 1}, {0, 1}, +}; + +static const int __initconst mv98dx4251_cpu_mpll_ratios[8][2] = { + {2, 1}, {0, 1}, {3, 1}, {2, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, +}; + +static const int __initconst mv98dx4251_cpu_ddr_ratios[8][2] = { + {1, 1}, {0, 1}, {1, 1}, {1, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, +}; + +static void __init mv98dx3236_get_clk_ratio( + void __iomem *sar, int id, int *mult, int *div) +{ + u32 opt = ((readl(sar) >> SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT) & + SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT_MASK); + + switch (id) { + case MV98DX3236_CPU_TO_DDR: + if (of_machine_is_compatible("marvell,armadaxp-98dx4251")) { + *mult = mv98dx4251_cpu_ddr_ratios[opt][0]; + *div = mv98dx4251_cpu_ddr_ratios[opt][1]; + } else if (of_machine_is_compatible("marvell,armadaxp-98dx3236")) { + *mult = mv98dx3236_cpu_ddr_ratios[opt][0]; + *div = mv98dx3236_cpu_ddr_ratios[opt][1]; + } + break; + case MV98DX3236_CPU_TO_MPLL: + if (of_machine_is_compatible("marvell,armadaxp-98dx4251")) { + *mult = mv98dx4251_cpu_mpll_ratios[opt][0]; + *div = mv98dx4251_cpu_mpll_ratios[opt][1]; + } else if (of_machine_is_compatible("marvell,armadaxp-98dx3236")) { + *mult = mv98dx3236_cpu_mpll_ratios[opt][0]; + *div = mv98dx3236_cpu_mpll_ratios[opt][1]; + } + break; + } +} + +static const struct coreclk_soc_desc mv98dx3236_core_clocks = { + .get_tclk_freq = mv98dx3236_get_tclk_freq, + .get_cpu_freq = mv98dx3236_get_cpu_freq, + .get_clk_ratio = mv98dx3236_get_clk_ratio, + .ratios = mv98dx3236_core_ratios, + .num_ratios = ARRAY_SIZE(mv98dx3236_core_ratios), +}; + + +/* + * Clock Gating Control + */ + +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = { + { "ge1", NULL, 3, 0 }, + { "ge0", NULL, 4, 0 }, + { "pex00", NULL, 5, 0 }, + { "sdio", NULL, 17, 0 }, + { "usb0", NULL, 18, 0 }, + { "xor0", NULL, 22, 0 }, + { } +}; + +static void __init mv98dx3236_clk_init(struct device_node *np) +{ + struct device_node *cgnp = + of_find_compatible_node(NULL, NULL, "marvell,mv98dx3236-gating-clock"); + + mvebu_coreclk_setup(np, &mv98dx3236_core_clocks); + + if (cgnp) + mvebu_clk_gating_setup(cgnp, mv98dx3236_gating_desc); +} +CLK_OF_DECLARE(mv98dx3236_clk, "marvell,mv98dx3236-core-clock", mv98dx3236_clk_init); |