diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:54:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:54:50 -0400 |
commit | 92295f632cefbdf15d46e9ac5f0fc3cfade35259 (patch) | |
tree | 5b3820d4ed135ccbef540781d99a46137959bbb6 /drivers | |
parent | 750b2d7b93f2ba19f4f238cc641bda22fe07c155 (diff) | |
parent | 45e3ec3784aec0d194740b75b547bfabca448ff3 (diff) |
Merge tag 'clk-for-linus-3.11' of git://git.linaro.org/people/mturquette/linux
Pull clock framework updates from Mike Turquette:
"The common clock framework changes for 3.11 include new clock drivers
across several different platforms and architectures, fixes to
existing drivers, a MAINTAINERS file fix and improvements to the basic
clock types that allow them to be of use to more platforms than before.
Only a few fixes to the core framework are included with most all of
the changes landing in the various clock drivers themselves."
* tag 'clk-for-linus-3.11' of git://git.linaro.org/people/mturquette/linux: (55 commits)
clk: tegra: fix ifdef for tegra_periph_reset_assert inline
clk: tegra: provide tegra_periph_reset_assert alternative
clk: exynos4: Fix clock aliases for cpufreq related clocks
clk: samsung: Add MUX_FA macro to pass flag and alias
clk: add support for Rockchip gate clocks
clk: vexpress: Make the clock drivers directly available for arm64
clk: vexpress: Use full node name to identify individual clocks
clk: tegra: T114: add DFLL DVCO reset control
clk: tegra: T114: add DFLL source clocks
clk: tegra: T114: add FCPU clock shaper programming, needed by the DFLL
clk: gate: add CLK_GATE_HIWORD_MASK
clk: divider: add CLK_DIVIDER_HIWORD_MASK flag
clk: mux: add CLK_MUX_HIWORD_MASK
clk: Always notify whole subtree when reparenting
MAINTAINERS: make drivers/clk entry match subdirs
clk: honor CLK_GET_RATE_NOCACHE in clk_set_rate
clk: use clk_get_rate() for debugfs
clk: tegra: Use override bits when needed
clk: tegra: override bits for Tegra30 PLLM
clk: tegra: override bits for Tegra114 PLLM
...
Diffstat (limited to 'drivers')
30 files changed, 1887 insertions, 292 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 0357ac44638b..51380d655d1a 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -42,7 +42,7 @@ config COMMON_CLK_WM831X | |||
42 | 42 | ||
43 | config COMMON_CLK_VERSATILE | 43 | config COMMON_CLK_VERSATILE |
44 | bool "Clock driver for ARM Reference designs" | 44 | bool "Clock driver for ARM Reference designs" |
45 | depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS | 45 | depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64 |
46 | ---help--- | 46 | ---help--- |
47 | Supports clocking on ARM Reference designs: | 47 | Supports clocking on ARM Reference designs: |
48 | - Integrator/AP and Integrator/CP | 48 | - Integrator/AP and Integrator/CP |
@@ -58,7 +58,6 @@ config COMMON_CLK_MAX77686 | |||
58 | config COMMON_CLK_SI5351 | 58 | config COMMON_CLK_SI5351 |
59 | tristate "Clock driver for SiLabs 5351A/B/C" | 59 | tristate "Clock driver for SiLabs 5351A/B/C" |
60 | depends on I2C | 60 | depends on I2C |
61 | depends on OF | ||
62 | select REGMAP_I2C | 61 | select REGMAP_I2C |
63 | select RATIONAL | 62 | select RATIONAL |
64 | ---help--- | 63 | ---help--- |
@@ -81,6 +80,13 @@ config COMMON_CLK_AXI_CLKGEN | |||
81 | Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx | 80 | Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx |
82 | FPGAs. It is commonly used in Analog Devices' reference designs. | 81 | FPGAs. It is commonly used in Analog Devices' reference designs. |
83 | 82 | ||
83 | config CLK_PPC_CORENET | ||
84 | bool "Clock driver for PowerPC corenet platforms" | ||
85 | depends on PPC_E500MC && OF | ||
86 | ---help--- | ||
87 | This adds the clock driver support for Freescale PowerPC corenet | ||
88 | platforms using common clock framework. | ||
89 | |||
84 | endmenu | 90 | endmenu |
85 | 91 | ||
86 | source "drivers/clk/mvebu/Kconfig" | 92 | source "drivers/clk/mvebu/Kconfig" |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f9cf7085ef70..4038c2bdf334 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-composite.o | |||
13 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o | 13 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o |
14 | obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o | 14 | obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o |
15 | obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o | 15 | obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o |
16 | obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o | ||
16 | obj-$(CONFIG_ARCH_MXS) += mxs/ | 17 | obj-$(CONFIG_ARCH_MXS) += mxs/ |
17 | obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ | 18 | obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ |
18 | obj-$(CONFIG_PLAT_SPEAR) += spear/ | 19 | obj-$(CONFIG_PLAT_SPEAR) += spear/ |
@@ -24,6 +25,7 @@ ifeq ($(CONFIG_COMMON_CLK), y) | |||
24 | obj-$(CONFIG_ARCH_MMP) += mmp/ | 25 | obj-$(CONFIG_ARCH_MMP) += mmp/ |
25 | endif | 26 | endif |
26 | obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o | 27 | obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o |
28 | obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ | ||
27 | obj-$(CONFIG_ARCH_SUNXI) += sunxi/ | 29 | obj-$(CONFIG_ARCH_SUNXI) += sunxi/ |
28 | obj-$(CONFIG_ARCH_U8500) += ux500/ | 30 | obj-$(CONFIG_ARCH_U8500) += ux500/ |
29 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o | 31 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o |
@@ -39,3 +41,4 @@ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o | |||
39 | obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o | 41 | obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o |
40 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o | 42 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o |
41 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o | 43 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o |
44 | obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o | ||
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 6d9674160430..6d55eb2cb959 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c | |||
@@ -150,6 +150,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, | |||
150 | struct clk_divider *divider = to_clk_divider(hw); | 150 | struct clk_divider *divider = to_clk_divider(hw); |
151 | int i, bestdiv = 0; | 151 | int i, bestdiv = 0; |
152 | unsigned long parent_rate, best = 0, now, maxdiv; | 152 | unsigned long parent_rate, best = 0, now, maxdiv; |
153 | unsigned long parent_rate_saved = *best_parent_rate; | ||
153 | 154 | ||
154 | if (!rate) | 155 | if (!rate) |
155 | rate = 1; | 156 | rate = 1; |
@@ -173,6 +174,15 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, | |||
173 | for (i = 1; i <= maxdiv; i++) { | 174 | for (i = 1; i <= maxdiv; i++) { |
174 | if (!_is_valid_div(divider, i)) | 175 | if (!_is_valid_div(divider, i)) |
175 | continue; | 176 | continue; |
177 | if (rate * i == parent_rate_saved) { | ||
178 | /* | ||
179 | * It's the most ideal case if the requested rate can be | ||
180 | * divided from parent clock without needing to change | ||
181 | * parent rate, so return the divider immediately. | ||
182 | */ | ||
183 | *best_parent_rate = parent_rate_saved; | ||
184 | return i; | ||
185 | } | ||
176 | parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), | 186 | parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), |
177 | MULT_ROUND_UP(rate, i)); | 187 | MULT_ROUND_UP(rate, i)); |
178 | now = parent_rate / i; | 188 | now = parent_rate / i; |
@@ -217,8 +227,12 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, | |||
217 | if (divider->lock) | 227 | if (divider->lock) |
218 | spin_lock_irqsave(divider->lock, flags); | 228 | spin_lock_irqsave(divider->lock, flags); |
219 | 229 | ||
220 | val = readl(divider->reg); | 230 | if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { |
221 | val &= ~(div_mask(divider) << divider->shift); | 231 | val = div_mask(divider) << (divider->shift + 16); |
232 | } else { | ||
233 | val = readl(divider->reg); | ||
234 | val &= ~(div_mask(divider) << divider->shift); | ||
235 | } | ||
222 | val |= value << divider->shift; | 236 | val |= value << divider->shift; |
223 | writel(val, divider->reg); | 237 | writel(val, divider->reg); |
224 | 238 | ||
@@ -245,6 +259,13 @@ static struct clk *_register_divider(struct device *dev, const char *name, | |||
245 | struct clk *clk; | 259 | struct clk *clk; |
246 | struct clk_init_data init; | 260 | struct clk_init_data init; |
247 | 261 | ||
262 | if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { | ||
263 | if (width + shift > 16) { | ||
264 | pr_warn("divider value exceeds LOWORD field\n"); | ||
265 | return ERR_PTR(-EINVAL); | ||
266 | } | ||
267 | } | ||
268 | |||
248 | /* allocate the divider */ | 269 | /* allocate the divider */ |
249 | div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); | 270 | div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); |
250 | if (!div) { | 271 | if (!div) { |
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 15114febfd92..790306e921c8 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c | |||
@@ -53,12 +53,18 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable) | |||
53 | if (gate->lock) | 53 | if (gate->lock) |
54 | spin_lock_irqsave(gate->lock, flags); | 54 | spin_lock_irqsave(gate->lock, flags); |
55 | 55 | ||
56 | reg = readl(gate->reg); | 56 | if (gate->flags & CLK_GATE_HIWORD_MASK) { |
57 | 57 | reg = BIT(gate->bit_idx + 16); | |
58 | if (set) | 58 | if (set) |
59 | reg |= BIT(gate->bit_idx); | 59 | reg |= BIT(gate->bit_idx); |
60 | else | 60 | } else { |
61 | reg &= ~BIT(gate->bit_idx); | 61 | reg = readl(gate->reg); |
62 | |||
63 | if (set) | ||
64 | reg |= BIT(gate->bit_idx); | ||
65 | else | ||
66 | reg &= ~BIT(gate->bit_idx); | ||
67 | } | ||
62 | 68 | ||
63 | writel(reg, gate->reg); | 69 | writel(reg, gate->reg); |
64 | 70 | ||
@@ -121,6 +127,13 @@ struct clk *clk_register_gate(struct device *dev, const char *name, | |||
121 | struct clk *clk; | 127 | struct clk *clk; |
122 | struct clk_init_data init; | 128 | struct clk_init_data init; |
123 | 129 | ||
130 | if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { | ||
131 | if (bit_idx > 16) { | ||
132 | pr_err("gate bit exceeds LOWORD field\n"); | ||
133 | return ERR_PTR(-EINVAL); | ||
134 | } | ||
135 | } | ||
136 | |||
124 | /* allocate the gate */ | 137 | /* allocate the gate */ |
125 | gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); | 138 | gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); |
126 | if (!gate) { | 139 | if (!gate) { |
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 25b1734560d0..614444ca40cd 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c | |||
@@ -86,8 +86,12 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) | |||
86 | if (mux->lock) | 86 | if (mux->lock) |
87 | spin_lock_irqsave(mux->lock, flags); | 87 | spin_lock_irqsave(mux->lock, flags); |
88 | 88 | ||
89 | val = readl(mux->reg); | 89 | if (mux->flags & CLK_MUX_HIWORD_MASK) { |
90 | val &= ~(mux->mask << mux->shift); | 90 | val = mux->mask << (mux->shift + 16); |
91 | } else { | ||
92 | val = readl(mux->reg); | ||
93 | val &= ~(mux->mask << mux->shift); | ||
94 | } | ||
91 | val |= index << mux->shift; | 95 | val |= index << mux->shift; |
92 | writel(val, mux->reg); | 96 | writel(val, mux->reg); |
93 | 97 | ||
@@ -111,6 +115,15 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name, | |||
111 | struct clk_mux *mux; | 115 | struct clk_mux *mux; |
112 | struct clk *clk; | 116 | struct clk *clk; |
113 | struct clk_init_data init; | 117 | struct clk_init_data init; |
118 | u8 width = 0; | ||
119 | |||
120 | if (clk_mux_flags & CLK_MUX_HIWORD_MASK) { | ||
121 | width = fls(mask) - ffs(mask) + 1; | ||
122 | if (width + shift > 16) { | ||
123 | pr_err("mux value exceeds LOWORD field\n"); | ||
124 | return ERR_PTR(-EINVAL); | ||
125 | } | ||
126 | } | ||
114 | 127 | ||
115 | /* allocate the mux */ | 128 | /* allocate the mux */ |
116 | mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); | 129 | mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); |
diff --git a/drivers/clk/clk-nspire.c b/drivers/clk/clk-nspire.c new file mode 100644 index 000000000000..a378db7b2382 --- /dev/null +++ b/drivers/clk/clk-nspire.c | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2, as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | |||
17 | #define MHZ (1000 * 1000) | ||
18 | |||
19 | #define BASE_CPU_SHIFT 1 | ||
20 | #define BASE_CPU_MASK 0x7F | ||
21 | |||
22 | #define CPU_AHB_SHIFT 12 | ||
23 | #define CPU_AHB_MASK 0x07 | ||
24 | |||
25 | #define FIXED_BASE_SHIFT 8 | ||
26 | #define FIXED_BASE_MASK 0x01 | ||
27 | |||
28 | #define CLASSIC_BASE_SHIFT 16 | ||
29 | #define CLASSIC_BASE_MASK 0x1F | ||
30 | |||
31 | #define CX_BASE_SHIFT 15 | ||
32 | #define CX_BASE_MASK 0x3F | ||
33 | |||
34 | #define CX_UNKNOWN_SHIFT 21 | ||
35 | #define CX_UNKNOWN_MASK 0x03 | ||
36 | |||
37 | struct nspire_clk_info { | ||
38 | u32 base_clock; | ||
39 | u16 base_cpu_ratio; | ||
40 | u16 base_ahb_ratio; | ||
41 | }; | ||
42 | |||
43 | |||
44 | #define EXTRACT(var, prop) (((var)>>prop##_SHIFT) & prop##_MASK) | ||
45 | static void nspire_clkinfo_cx(u32 val, struct nspire_clk_info *clk) | ||
46 | { | ||
47 | if (EXTRACT(val, FIXED_BASE)) | ||
48 | clk->base_clock = 48 * MHZ; | ||
49 | else | ||
50 | clk->base_clock = 6 * EXTRACT(val, CX_BASE) * MHZ; | ||
51 | |||
52 | clk->base_cpu_ratio = EXTRACT(val, BASE_CPU) * EXTRACT(val, CX_UNKNOWN); | ||
53 | clk->base_ahb_ratio = clk->base_cpu_ratio * (EXTRACT(val, CPU_AHB) + 1); | ||
54 | } | ||
55 | |||
56 | static void nspire_clkinfo_classic(u32 val, struct nspire_clk_info *clk) | ||
57 | { | ||
58 | if (EXTRACT(val, FIXED_BASE)) | ||
59 | clk->base_clock = 27 * MHZ; | ||
60 | else | ||
61 | clk->base_clock = (300 - 6 * EXTRACT(val, CLASSIC_BASE)) * MHZ; | ||
62 | |||
63 | clk->base_cpu_ratio = EXTRACT(val, BASE_CPU) * 2; | ||
64 | clk->base_ahb_ratio = clk->base_cpu_ratio * (EXTRACT(val, CPU_AHB) + 1); | ||
65 | } | ||
66 | |||
67 | static void __init nspire_ahbdiv_setup(struct device_node *node, | ||
68 | void (*get_clkinfo)(u32, struct nspire_clk_info *)) | ||
69 | { | ||
70 | u32 val; | ||
71 | void __iomem *io; | ||
72 | struct clk *clk; | ||
73 | const char *clk_name = node->name; | ||
74 | const char *parent_name; | ||
75 | struct nspire_clk_info info; | ||
76 | |||
77 | io = of_iomap(node, 0); | ||
78 | if (!io) | ||
79 | return; | ||
80 | val = readl(io); | ||
81 | iounmap(io); | ||
82 | |||
83 | get_clkinfo(val, &info); | ||
84 | |||
85 | of_property_read_string(node, "clock-output-names", &clk_name); | ||
86 | parent_name = of_clk_get_parent_name(node, 0); | ||
87 | |||
88 | clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, | ||
89 | 1, info.base_ahb_ratio); | ||
90 | if (!IS_ERR(clk)) | ||
91 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
92 | } | ||
93 | |||
94 | static void __init nspire_ahbdiv_setup_cx(struct device_node *node) | ||
95 | { | ||
96 | nspire_ahbdiv_setup(node, nspire_clkinfo_cx); | ||
97 | } | ||
98 | |||
99 | static void __init nspire_ahbdiv_setup_classic(struct device_node *node) | ||
100 | { | ||
101 | nspire_ahbdiv_setup(node, nspire_clkinfo_classic); | ||
102 | } | ||
103 | |||
104 | CLK_OF_DECLARE(nspire_ahbdiv_cx, "lsi,nspire-cx-ahb-divider", | ||
105 | nspire_ahbdiv_setup_cx); | ||
106 | CLK_OF_DECLARE(nspire_ahbdiv_classic, "lsi,nspire-classic-ahb-divider", | ||
107 | nspire_ahbdiv_setup_classic); | ||
108 | |||
109 | static void __init nspire_clk_setup(struct device_node *node, | ||
110 | void (*get_clkinfo)(u32, struct nspire_clk_info *)) | ||
111 | { | ||
112 | u32 val; | ||
113 | void __iomem *io; | ||
114 | struct clk *clk; | ||
115 | const char *clk_name = node->name; | ||
116 | struct nspire_clk_info info; | ||
117 | |||
118 | io = of_iomap(node, 0); | ||
119 | if (!io) | ||
120 | return; | ||
121 | val = readl(io); | ||
122 | iounmap(io); | ||
123 | |||
124 | get_clkinfo(val, &info); | ||
125 | |||
126 | of_property_read_string(node, "clock-output-names", &clk_name); | ||
127 | |||
128 | clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, | ||
129 | info.base_clock); | ||
130 | if (!IS_ERR(clk)) | ||
131 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
132 | else | ||
133 | return; | ||
134 | |||
135 | pr_info("TI-NSPIRE Base: %uMHz CPU: %uMHz AHB: %uMHz\n", | ||
136 | info.base_clock / MHZ, | ||
137 | info.base_clock / info.base_cpu_ratio / MHZ, | ||
138 | info.base_clock / info.base_ahb_ratio / MHZ); | ||
139 | } | ||
140 | |||
141 | static void __init nspire_clk_setup_cx(struct device_node *node) | ||
142 | { | ||
143 | nspire_clk_setup(node, nspire_clkinfo_cx); | ||
144 | } | ||
145 | |||
146 | static void __init nspire_clk_setup_classic(struct device_node *node) | ||
147 | { | ||
148 | nspire_clk_setup(node, nspire_clkinfo_classic); | ||
149 | } | ||
150 | |||
151 | CLK_OF_DECLARE(nspire_clk_cx, "lsi,nspire-cx-clock", nspire_clk_setup_cx); | ||
152 | CLK_OF_DECLARE(nspire_clk_classic, "lsi,nspire-classic-clock", | ||
153 | nspire_clk_setup_classic); | ||
diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c new file mode 100644 index 000000000000..e9587073bd32 --- /dev/null +++ b/drivers/clk/clk-ppc-corenet.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * clock driver for Freescale PowerPC corenet SoCs. | ||
9 | */ | ||
10 | #include <linux/clk-provider.h> | ||
11 | #include <linux/io.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/of_platform.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/slab.h> | ||
17 | |||
18 | struct cmux_clk { | ||
19 | struct clk_hw hw; | ||
20 | void __iomem *reg; | ||
21 | u32 flags; | ||
22 | }; | ||
23 | |||
24 | #define PLL_KILL BIT(31) | ||
25 | #define CLKSEL_SHIFT 27 | ||
26 | #define CLKSEL_ADJUST BIT(0) | ||
27 | #define to_cmux_clk(p) container_of(p, struct cmux_clk, hw) | ||
28 | |||
29 | static void __iomem *base; | ||
30 | static unsigned int clocks_per_pll; | ||
31 | |||
32 | static int cmux_set_parent(struct clk_hw *hw, u8 idx) | ||
33 | { | ||
34 | struct cmux_clk *clk = to_cmux_clk(hw); | ||
35 | u32 clksel; | ||
36 | |||
37 | clksel = ((idx / clocks_per_pll) << 2) + idx % clocks_per_pll; | ||
38 | if (clk->flags & CLKSEL_ADJUST) | ||
39 | clksel += 8; | ||
40 | clksel = (clksel & 0xf) << CLKSEL_SHIFT; | ||
41 | iowrite32be(clksel, clk->reg); | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | static u8 cmux_get_parent(struct clk_hw *hw) | ||
47 | { | ||
48 | struct cmux_clk *clk = to_cmux_clk(hw); | ||
49 | u32 clksel; | ||
50 | |||
51 | clksel = ioread32be(clk->reg); | ||
52 | clksel = (clksel >> CLKSEL_SHIFT) & 0xf; | ||
53 | if (clk->flags & CLKSEL_ADJUST) | ||
54 | clksel -= 8; | ||
55 | clksel = (clksel >> 2) * clocks_per_pll + clksel % 4; | ||
56 | |||
57 | return clksel; | ||
58 | } | ||
59 | |||
60 | const struct clk_ops cmux_ops = { | ||
61 | .get_parent = cmux_get_parent, | ||
62 | .set_parent = cmux_set_parent, | ||
63 | }; | ||
64 | |||
65 | static void __init core_mux_init(struct device_node *np) | ||
66 | { | ||
67 | struct clk *clk; | ||
68 | struct clk_init_data init; | ||
69 | struct cmux_clk *cmux_clk; | ||
70 | struct device_node *node; | ||
71 | int rc, count, i; | ||
72 | u32 offset; | ||
73 | const char *clk_name; | ||
74 | const char **parent_names; | ||
75 | |||
76 | rc = of_property_read_u32(np, "reg", &offset); | ||
77 | if (rc) { | ||
78 | pr_err("%s: could not get reg property\n", np->name); | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | /* get the input clock source count */ | ||
83 | count = of_property_count_strings(np, "clock-names"); | ||
84 | if (count < 0) { | ||
85 | pr_err("%s: get clock count error\n", np->name); | ||
86 | return; | ||
87 | } | ||
88 | parent_names = kzalloc((sizeof(char *) * count), GFP_KERNEL); | ||
89 | if (!parent_names) { | ||
90 | pr_err("%s: could not allocate parent_names\n", __func__); | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | for (i = 0; i < count; i++) | ||
95 | parent_names[i] = of_clk_get_parent_name(np, i); | ||
96 | |||
97 | cmux_clk = kzalloc(sizeof(struct cmux_clk), GFP_KERNEL); | ||
98 | if (!cmux_clk) { | ||
99 | pr_err("%s: could not allocate cmux_clk\n", __func__); | ||
100 | goto err_name; | ||
101 | } | ||
102 | cmux_clk->reg = base + offset; | ||
103 | |||
104 | node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen"); | ||
105 | if (node && (offset >= 0x80)) | ||
106 | cmux_clk->flags = CLKSEL_ADJUST; | ||
107 | |||
108 | rc = of_property_read_string_index(np, "clock-output-names", | ||
109 | 0, &clk_name); | ||
110 | if (rc) { | ||
111 | pr_err("%s: read clock names error\n", np->name); | ||
112 | goto err_clk; | ||
113 | } | ||
114 | |||
115 | init.name = clk_name; | ||
116 | init.ops = &cmux_ops; | ||
117 | init.parent_names = parent_names; | ||
118 | init.num_parents = count; | ||
119 | init.flags = 0; | ||
120 | cmux_clk->hw.init = &init; | ||
121 | |||
122 | clk = clk_register(NULL, &cmux_clk->hw); | ||
123 | if (IS_ERR(clk)) { | ||
124 | pr_err("%s: could not register clock\n", clk_name); | ||
125 | goto err_clk; | ||
126 | } | ||
127 | |||
128 | rc = of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
129 | if (rc) { | ||
130 | pr_err("Could not register clock provider for node:%s\n", | ||
131 | np->name); | ||
132 | goto err_clk; | ||
133 | } | ||
134 | goto err_name; | ||
135 | |||
136 | err_clk: | ||
137 | kfree(cmux_clk); | ||
138 | err_name: | ||
139 | /* free *_names because they are reallocated when registered */ | ||
140 | kfree(parent_names); | ||
141 | } | ||
142 | |||
143 | static void __init core_pll_init(struct device_node *np) | ||
144 | { | ||
145 | u32 offset, mult; | ||
146 | int i, rc, count; | ||
147 | const char *clk_name, *parent_name; | ||
148 | struct clk_onecell_data *onecell_data; | ||
149 | struct clk **subclks; | ||
150 | |||
151 | rc = of_property_read_u32(np, "reg", &offset); | ||
152 | if (rc) { | ||
153 | pr_err("%s: could not get reg property\n", np->name); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | /* get the multiple of PLL */ | ||
158 | mult = ioread32be(base + offset); | ||
159 | |||
160 | /* check if this PLL is disabled */ | ||
161 | if (mult & PLL_KILL) { | ||
162 | pr_debug("PLL:%s is disabled\n", np->name); | ||
163 | return; | ||
164 | } | ||
165 | mult = (mult >> 1) & 0x3f; | ||
166 | |||
167 | parent_name = of_clk_get_parent_name(np, 0); | ||
168 | if (!parent_name) { | ||
169 | pr_err("PLL: %s must have a parent\n", np->name); | ||
170 | return; | ||
171 | } | ||
172 | |||
173 | count = of_property_count_strings(np, "clock-output-names"); | ||
174 | if (count < 0 || count > 4) { | ||
175 | pr_err("%s: clock is not supported\n", np->name); | ||
176 | return; | ||
177 | } | ||
178 | |||
179 | /* output clock number per PLL */ | ||
180 | clocks_per_pll = count; | ||
181 | |||
182 | subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL); | ||
183 | if (!subclks) { | ||
184 | pr_err("%s: could not allocate subclks\n", __func__); | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); | ||
189 | if (!onecell_data) { | ||
190 | pr_err("%s: could not allocate onecell_data\n", __func__); | ||
191 | goto err_clks; | ||
192 | } | ||
193 | |||
194 | for (i = 0; i < count; i++) { | ||
195 | rc = of_property_read_string_index(np, "clock-output-names", | ||
196 | i, &clk_name); | ||
197 | if (rc) { | ||
198 | pr_err("%s: could not get clock names\n", np->name); | ||
199 | goto err_cell; | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * when count == 4, there are 4 output clocks: | ||
204 | * /1, /2, /3, /4 respectively | ||
205 | * when count < 4, there are at least 2 output clocks: | ||
206 | * /1, /2, (/4, if count == 3) respectively. | ||
207 | */ | ||
208 | if (count == 4) | ||
209 | subclks[i] = clk_register_fixed_factor(NULL, clk_name, | ||
210 | parent_name, 0, mult, 1 + i); | ||
211 | else | ||
212 | |||
213 | subclks[i] = clk_register_fixed_factor(NULL, clk_name, | ||
214 | parent_name, 0, mult, 1 << i); | ||
215 | |||
216 | if (IS_ERR(subclks[i])) { | ||
217 | pr_err("%s: could not register clock\n", clk_name); | ||
218 | goto err_cell; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | onecell_data->clks = subclks; | ||
223 | onecell_data->clk_num = count; | ||
224 | |||
225 | rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data); | ||
226 | if (rc) { | ||
227 | pr_err("Could not register clk provider for node:%s\n", | ||
228 | np->name); | ||
229 | goto err_cell; | ||
230 | } | ||
231 | |||
232 | return; | ||
233 | err_cell: | ||
234 | kfree(onecell_data); | ||
235 | err_clks: | ||
236 | kfree(subclks); | ||
237 | } | ||
238 | |||
239 | static const struct of_device_id clk_match[] __initconst = { | ||
240 | { .compatible = "fixed-clock", .data = of_fixed_clk_setup, }, | ||
241 | { .compatible = "fsl,core-pll-clock", .data = core_pll_init, }, | ||
242 | { .compatible = "fsl,core-mux-clock", .data = core_mux_init, }, | ||
243 | {} | ||
244 | }; | ||
245 | |||
246 | static int __init ppc_corenet_clk_probe(struct platform_device *pdev) | ||
247 | { | ||
248 | struct device_node *np; | ||
249 | |||
250 | np = pdev->dev.of_node; | ||
251 | base = of_iomap(np, 0); | ||
252 | if (!base) { | ||
253 | dev_err(&pdev->dev, "iomap error\n"); | ||
254 | return -ENOMEM; | ||
255 | } | ||
256 | of_clk_init(clk_match); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static const struct of_device_id ppc_clk_ids[] __initconst = { | ||
262 | { .compatible = "fsl,qoriq-clockgen-1.0", }, | ||
263 | { .compatible = "fsl,qoriq-clockgen-2.0", }, | ||
264 | {} | ||
265 | }; | ||
266 | |||
267 | static struct platform_driver ppc_corenet_clk_driver = { | ||
268 | .driver = { | ||
269 | .name = "ppc_corenet_clock", | ||
270 | .owner = THIS_MODULE, | ||
271 | .of_match_table = ppc_clk_ids, | ||
272 | }, | ||
273 | .probe = ppc_corenet_clk_probe, | ||
274 | }; | ||
275 | |||
276 | static int __init ppc_corenet_clk_init(void) | ||
277 | { | ||
278 | return platform_driver_register(&ppc_corenet_clk_driver); | ||
279 | } | ||
280 | subsys_initcall(ppc_corenet_clk_init); | ||
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 24f553673b72..c50e83744b0a 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c | |||
@@ -851,6 +851,41 @@ static int _si5351_clkout_set_drive_strength( | |||
851 | return 0; | 851 | return 0; |
852 | } | 852 | } |
853 | 853 | ||
854 | static int _si5351_clkout_set_disable_state( | ||
855 | struct si5351_driver_data *drvdata, int num, | ||
856 | enum si5351_disable_state state) | ||
857 | { | ||
858 | u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE : | ||
859 | SI5351_CLK7_4_DISABLE_STATE; | ||
860 | u8 shift = (num < 4) ? (2 * num) : (2 * (num-4)); | ||
861 | u8 mask = SI5351_CLK_DISABLE_STATE_MASK << shift; | ||
862 | u8 val; | ||
863 | |||
864 | if (num > 8) | ||
865 | return -EINVAL; | ||
866 | |||
867 | switch (state) { | ||
868 | case SI5351_DISABLE_LOW: | ||
869 | val = SI5351_CLK_DISABLE_STATE_LOW; | ||
870 | break; | ||
871 | case SI5351_DISABLE_HIGH: | ||
872 | val = SI5351_CLK_DISABLE_STATE_HIGH; | ||
873 | break; | ||
874 | case SI5351_DISABLE_FLOATING: | ||
875 | val = SI5351_CLK_DISABLE_STATE_FLOAT; | ||
876 | break; | ||
877 | case SI5351_DISABLE_NEVER: | ||
878 | val = SI5351_CLK_DISABLE_STATE_NEVER; | ||
879 | break; | ||
880 | default: | ||
881 | return 0; | ||
882 | } | ||
883 | |||
884 | si5351_set_bits(drvdata, reg, mask, val << shift); | ||
885 | |||
886 | return 0; | ||
887 | } | ||
888 | |||
854 | static int si5351_clkout_prepare(struct clk_hw *hw) | 889 | static int si5351_clkout_prepare(struct clk_hw *hw) |
855 | { | 890 | { |
856 | struct si5351_hw_data *hwdata = | 891 | struct si5351_hw_data *hwdata = |
@@ -1225,6 +1260,33 @@ static int si5351_dt_parse(struct i2c_client *client) | |||
1225 | } | 1260 | } |
1226 | } | 1261 | } |
1227 | 1262 | ||
1263 | if (!of_property_read_u32(child, "silabs,disable-state", | ||
1264 | &val)) { | ||
1265 | switch (val) { | ||
1266 | case 0: | ||
1267 | pdata->clkout[num].disable_state = | ||
1268 | SI5351_DISABLE_LOW; | ||
1269 | break; | ||
1270 | case 1: | ||
1271 | pdata->clkout[num].disable_state = | ||
1272 | SI5351_DISABLE_HIGH; | ||
1273 | break; | ||
1274 | case 2: | ||
1275 | pdata->clkout[num].disable_state = | ||
1276 | SI5351_DISABLE_FLOATING; | ||
1277 | break; | ||
1278 | case 3: | ||
1279 | pdata->clkout[num].disable_state = | ||
1280 | SI5351_DISABLE_NEVER; | ||
1281 | break; | ||
1282 | default: | ||
1283 | dev_err(&client->dev, | ||
1284 | "invalid disable state %d for clkout %d\n", | ||
1285 | val, num); | ||
1286 | return -EINVAL; | ||
1287 | } | ||
1288 | } | ||
1289 | |||
1228 | if (!of_property_read_u32(child, "clock-frequency", &val)) | 1290 | if (!of_property_read_u32(child, "clock-frequency", &val)) |
1229 | pdata->clkout[num].rate = val; | 1291 | pdata->clkout[num].rate = val; |
1230 | 1292 | ||
@@ -1281,9 +1343,6 @@ static int si5351_i2c_probe(struct i2c_client *client, | |||
1281 | 1343 | ||
1282 | /* Disable interrupts */ | 1344 | /* Disable interrupts */ |
1283 | si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0); | 1345 | si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0); |
1284 | /* Set disabled output drivers to drive low */ | ||
1285 | si5351_reg_write(drvdata, SI5351_CLK3_0_DISABLE_STATE, 0x00); | ||
1286 | si5351_reg_write(drvdata, SI5351_CLK7_4_DISABLE_STATE, 0x00); | ||
1287 | /* Ensure pll select is on XTAL for Si5351A/B */ | 1346 | /* Ensure pll select is on XTAL for Si5351A/B */ |
1288 | if (drvdata->variant != SI5351_VARIANT_C) | 1347 | if (drvdata->variant != SI5351_VARIANT_C) |
1289 | si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, | 1348 | si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, |
@@ -1327,6 +1386,15 @@ static int si5351_i2c_probe(struct i2c_client *client, | |||
1327 | n, pdata->clkout[n].drive); | 1386 | n, pdata->clkout[n].drive); |
1328 | return ret; | 1387 | return ret; |
1329 | } | 1388 | } |
1389 | |||
1390 | ret = _si5351_clkout_set_disable_state(drvdata, n, | ||
1391 | pdata->clkout[n].disable_state); | ||
1392 | if (ret) { | ||
1393 | dev_err(&client->dev, | ||
1394 | "failed set disable state of clkout%d to %d\n", | ||
1395 | n, pdata->clkout[n].disable_state); | ||
1396 | return ret; | ||
1397 | } | ||
1330 | } | 1398 | } |
1331 | 1399 | ||
1332 | /* register xtal input clock gate */ | 1400 | /* register xtal input clock gate */ |
@@ -1500,7 +1568,10 @@ static int si5351_i2c_probe(struct i2c_client *client, | |||
1500 | } | 1568 | } |
1501 | 1569 | ||
1502 | static const struct i2c_device_id si5351_i2c_ids[] = { | 1570 | static const struct i2c_device_id si5351_i2c_ids[] = { |
1503 | { "silabs,si5351", 0 }, | 1571 | { "si5351a", 0 }, |
1572 | { "si5351a-msop", 0 }, | ||
1573 | { "si5351b", 0 }, | ||
1574 | { "si5351c", 0 }, | ||
1504 | { } | 1575 | { } |
1505 | }; | 1576 | }; |
1506 | MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids); | 1577 | MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids); |
diff --git a/drivers/clk/clk-si5351.h b/drivers/clk/clk-si5351.h index af41b5080f43..c0dbf2676872 100644 --- a/drivers/clk/clk-si5351.h +++ b/drivers/clk/clk-si5351.h | |||
@@ -81,6 +81,7 @@ | |||
81 | 81 | ||
82 | #define SI5351_CLK3_0_DISABLE_STATE 24 | 82 | #define SI5351_CLK3_0_DISABLE_STATE 24 |
83 | #define SI5351_CLK7_4_DISABLE_STATE 25 | 83 | #define SI5351_CLK7_4_DISABLE_STATE 25 |
84 | #define SI5351_CLK_DISABLE_STATE_MASK 3 | ||
84 | #define SI5351_CLK_DISABLE_STATE_LOW 0 | 85 | #define SI5351_CLK_DISABLE_STATE_LOW 0 |
85 | #define SI5351_CLK_DISABLE_STATE_HIGH 1 | 86 | #define SI5351_CLK_DISABLE_STATE_HIGH 1 |
86 | #define SI5351_CLK_DISABLE_STATE_FLOAT 2 | 87 | #define SI5351_CLK_DISABLE_STATE_FLOAT 2 |
diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c index 3af729b1b89d..1ada79a28052 100644 --- a/drivers/clk/clk-twl6040.c +++ b/drivers/clk/clk-twl6040.c | |||
@@ -95,14 +95,14 @@ static int twl6040_clk_probe(struct platform_device *pdev) | |||
95 | if (IS_ERR(clkdata->clk)) | 95 | if (IS_ERR(clkdata->clk)) |
96 | return PTR_ERR(clkdata->clk); | 96 | return PTR_ERR(clkdata->clk); |
97 | 97 | ||
98 | dev_set_drvdata(&pdev->dev, clkdata); | 98 | platform_set_drvdata(pdev, clkdata); |
99 | 99 | ||
100 | return 0; | 100 | return 0; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int twl6040_clk_remove(struct platform_device *pdev) | 103 | static int twl6040_clk_remove(struct platform_device *pdev) |
104 | { | 104 | { |
105 | struct twl6040_clk *clkdata = dev_get_drvdata(&pdev->dev); | 105 | struct twl6040_clk *clkdata = platform_get_drvdata(pdev); |
106 | 106 | ||
107 | clk_unregister(clkdata->clk); | 107 | clk_unregister(clkdata->clk); |
108 | 108 | ||
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 553ac35bcc91..82306f5fb9c2 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c | |||
@@ -42,6 +42,7 @@ struct clk_device { | |||
42 | #define PLL_TYPE_VT8500 0 | 42 | #define PLL_TYPE_VT8500 0 |
43 | #define PLL_TYPE_WM8650 1 | 43 | #define PLL_TYPE_WM8650 1 |
44 | #define PLL_TYPE_WM8750 2 | 44 | #define PLL_TYPE_WM8750 2 |
45 | #define PLL_TYPE_WM8850 3 | ||
45 | 46 | ||
46 | struct clk_pll { | 47 | struct clk_pll { |
47 | struct clk_hw hw; | 48 | struct clk_hw hw; |
@@ -156,10 +157,6 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, | |||
156 | 157 | ||
157 | divisor = parent_rate / rate; | 158 | divisor = parent_rate / rate; |
158 | 159 | ||
159 | /* If prate / rate would be decimal, incr the divisor */ | ||
160 | if (rate * divisor < parent_rate) | ||
161 | divisor++; | ||
162 | |||
163 | if (divisor == cdev->div_mask + 1) | 160 | if (divisor == cdev->div_mask + 1) |
164 | divisor = 0; | 161 | divisor = 0; |
165 | 162 | ||
@@ -327,6 +324,15 @@ CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init); | |||
327 | #define WM8750_BITS_TO_VAL(f, m, d1, d2) \ | 324 | #define WM8750_BITS_TO_VAL(f, m, d1, d2) \ |
328 | ((f << 24) | ((m - 1) << 16) | ((d1 - 1) << 8) | d2) | 325 | ((f << 24) | ((m - 1) << 16) | ((d1 - 1) << 8) | d2) |
329 | 326 | ||
327 | /* Helper macros for PLL_WM8850 */ | ||
328 | #define WM8850_PLL_MUL(x) ((((x >> 16) & 0x7F) + 1) * 2) | ||
329 | #define WM8850_PLL_DIV(x) ((((x >> 8) & 1) + 1) * (1 << (x & 3))) | ||
330 | |||
331 | #define WM8850_BITS_TO_FREQ(r, m, d1, d2) \ | ||
332 | (r * ((m + 1) * 2) / ((d1+1) * (1 << d2))) | ||
333 | |||
334 | #define WM8850_BITS_TO_VAL(m, d1, d2) \ | ||
335 | ((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2) | ||
330 | 336 | ||
331 | static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, | 337 | static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, |
332 | u32 *multiplier, u32 *prediv) | 338 | u32 *multiplier, u32 *prediv) |
@@ -466,6 +472,49 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, | |||
466 | *divisor2 = best_div2; | 472 | *divisor2 = best_div2; |
467 | } | 473 | } |
468 | 474 | ||
475 | static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, | ||
476 | u32 *multiplier, u32 *divisor1, u32 *divisor2) | ||
477 | { | ||
478 | u32 mul, div1, div2; | ||
479 | u32 best_mul, best_div1, best_div2; | ||
480 | unsigned long tclk, rate_err, best_err; | ||
481 | |||
482 | best_err = (unsigned long)-1; | ||
483 | |||
484 | /* Find the closest match (lower or equal to requested) */ | ||
485 | for (div1 = 1; div1 >= 0; div1--) | ||
486 | for (div2 = 3; div2 >= 0; div2--) | ||
487 | for (mul = 0; mul <= 127; mul++) { | ||
488 | tclk = parent_rate * ((mul + 1) * 2) / | ||
489 | ((div1 + 1) * (1 << div2)); | ||
490 | if (tclk > rate) | ||
491 | continue; | ||
492 | /* error will always be +ve */ | ||
493 | rate_err = rate - tclk; | ||
494 | if (rate_err == 0) { | ||
495 | *multiplier = mul; | ||
496 | *divisor1 = div1; | ||
497 | *divisor2 = div2; | ||
498 | return; | ||
499 | } | ||
500 | |||
501 | if (rate_err < best_err) { | ||
502 | best_err = rate_err; | ||
503 | best_mul = mul; | ||
504 | best_div1 = div1; | ||
505 | best_div2 = div2; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | /* if we got here, it wasn't an exact match */ | ||
510 | pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, | ||
511 | rate - best_err); | ||
512 | |||
513 | *multiplier = best_mul; | ||
514 | *divisor1 = best_div1; | ||
515 | *divisor2 = best_div2; | ||
516 | } | ||
517 | |||
469 | static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, | 518 | static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, |
470 | unsigned long parent_rate) | 519 | unsigned long parent_rate) |
471 | { | 520 | { |
@@ -489,6 +538,10 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
489 | wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); | 538 | wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); |
490 | pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); | 539 | pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); |
491 | break; | 540 | break; |
541 | case PLL_TYPE_WM8850: | ||
542 | wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); | ||
543 | pll_val = WM8850_BITS_TO_VAL(mul, div1, div2); | ||
544 | break; | ||
492 | default: | 545 | default: |
493 | pr_err("%s: invalid pll type\n", __func__); | 546 | pr_err("%s: invalid pll type\n", __func__); |
494 | return 0; | 547 | return 0; |
@@ -525,6 +578,10 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate, | |||
525 | wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); | 578 | wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); |
526 | round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); | 579 | round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); |
527 | break; | 580 | break; |
581 | case PLL_TYPE_WM8850: | ||
582 | wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2); | ||
583 | round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2); | ||
584 | break; | ||
528 | default: | 585 | default: |
529 | round_rate = 0; | 586 | round_rate = 0; |
530 | } | 587 | } |
@@ -552,6 +609,10 @@ static unsigned long vtwm_pll_recalc_rate(struct clk_hw *hw, | |||
552 | pll_freq = parent_rate * WM8750_PLL_MUL(pll_val); | 609 | pll_freq = parent_rate * WM8750_PLL_MUL(pll_val); |
553 | pll_freq /= WM8750_PLL_DIV(pll_val); | 610 | pll_freq /= WM8750_PLL_DIV(pll_val); |
554 | break; | 611 | break; |
612 | case PLL_TYPE_WM8850: | ||
613 | pll_freq = parent_rate * WM8850_PLL_MUL(pll_val); | ||
614 | pll_freq /= WM8850_PLL_DIV(pll_val); | ||
615 | break; | ||
555 | default: | 616 | default: |
556 | pll_freq = 0; | 617 | pll_freq = 0; |
557 | } | 618 | } |
@@ -628,6 +689,12 @@ static void __init wm8750_pll_init(struct device_node *node) | |||
628 | } | 689 | } |
629 | CLK_OF_DECLARE(wm8750_pll, "wm,wm8750-pll-clock", wm8750_pll_init); | 690 | CLK_OF_DECLARE(wm8750_pll, "wm,wm8750-pll-clock", wm8750_pll_init); |
630 | 691 | ||
692 | static void __init wm8850_pll_init(struct device_node *node) | ||
693 | { | ||
694 | vtwm_pll_clk_init(node, PLL_TYPE_WM8850); | ||
695 | } | ||
696 | CLK_OF_DECLARE(wm8850_pll, "wm,wm8850-pll-clock", wm8850_pll_init); | ||
697 | |||
631 | void __init vtwm_clk_init(void __iomem *base) | 698 | void __init vtwm_clk_init(void __iomem *base) |
632 | { | 699 | { |
633 | if (!base) | 700 | if (!base) |
diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c index 16ed06808554..1b3f8c9b98cc 100644 --- a/drivers/clk/clk-wm831x.c +++ b/drivers/clk/clk-wm831x.c | |||
@@ -97,7 +97,7 @@ static int wm831x_fll_prepare(struct clk_hw *hw) | |||
97 | struct wm831x *wm831x = clkdata->wm831x; | 97 | struct wm831x *wm831x = clkdata->wm831x; |
98 | int ret; | 98 | int ret; |
99 | 99 | ||
100 | ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_2, | 100 | ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_1, |
101 | WM831X_FLL_ENA, WM831X_FLL_ENA); | 101 | WM831X_FLL_ENA, WM831X_FLL_ENA); |
102 | if (ret != 0) | 102 | if (ret != 0) |
103 | dev_crit(wm831x->dev, "Failed to enable FLL: %d\n", ret); | 103 | dev_crit(wm831x->dev, "Failed to enable FLL: %d\n", ret); |
@@ -114,9 +114,9 @@ static void wm831x_fll_unprepare(struct clk_hw *hw) | |||
114 | struct wm831x *wm831x = clkdata->wm831x; | 114 | struct wm831x *wm831x = clkdata->wm831x; |
115 | int ret; | 115 | int ret; |
116 | 116 | ||
117 | ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_2, WM831X_FLL_ENA, 0); | 117 | ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_1, WM831X_FLL_ENA, 0); |
118 | if (ret != 0) | 118 | if (ret != 0) |
119 | dev_crit(wm831x->dev, "Failed to disaable FLL: %d\n", ret); | 119 | dev_crit(wm831x->dev, "Failed to disable FLL: %d\n", ret); |
120 | } | 120 | } |
121 | 121 | ||
122 | static unsigned long wm831x_fll_recalc_rate(struct clk_hw *hw, | 122 | static unsigned long wm831x_fll_recalc_rate(struct clk_hw *hw, |
@@ -299,8 +299,8 @@ static void wm831x_clkout_unprepare(struct clk_hw *hw) | |||
299 | } | 299 | } |
300 | 300 | ||
301 | static const char *wm831x_clkout_parents[] = { | 301 | static const char *wm831x_clkout_parents[] = { |
302 | "xtal", | ||
303 | "fll", | 302 | "fll", |
303 | "xtal", | ||
304 | }; | 304 | }; |
305 | 305 | ||
306 | static u8 wm831x_clkout_get_parent(struct clk_hw *hw) | 306 | static u8 wm831x_clkout_get_parent(struct clk_hw *hw) |
@@ -318,9 +318,9 @@ static u8 wm831x_clkout_get_parent(struct clk_hw *hw) | |||
318 | } | 318 | } |
319 | 319 | ||
320 | if (ret & WM831X_CLKOUT_SRC) | 320 | if (ret & WM831X_CLKOUT_SRC) |
321 | return 0; | ||
322 | else | ||
323 | return 1; | 321 | return 1; |
322 | else | ||
323 | return 0; | ||
324 | } | 324 | } |
325 | 325 | ||
326 | static int wm831x_clkout_set_parent(struct clk_hw *hw, u8 parent) | 326 | static int wm831x_clkout_set_parent(struct clk_hw *hw, u8 parent) |
@@ -384,7 +384,7 @@ static int wm831x_clk_probe(struct platform_device *pdev) | |||
384 | if (IS_ERR(clkdata->clkout)) | 384 | if (IS_ERR(clkdata->clkout)) |
385 | return PTR_ERR(clkdata->clkout); | 385 | return PTR_ERR(clkdata->clkout); |
386 | 386 | ||
387 | dev_set_drvdata(&pdev->dev, clkdata); | 387 | platform_set_drvdata(pdev, clkdata); |
388 | 388 | ||
389 | return 0; | 389 | return 0; |
390 | } | 390 | } |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 1144e8c7579d..54a191c5bbf0 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -107,7 +107,7 @@ static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level) | |||
107 | seq_printf(s, "%*s%-*s %-11d %-12d %-10lu", | 107 | seq_printf(s, "%*s%-*s %-11d %-12d %-10lu", |
108 | level * 3 + 1, "", | 108 | level * 3 + 1, "", |
109 | 30 - level * 3, c->name, | 109 | 30 - level * 3, c->name, |
110 | c->enable_count, c->prepare_count, c->rate); | 110 | c->enable_count, c->prepare_count, clk_get_rate(c)); |
111 | seq_printf(s, "\n"); | 111 | seq_printf(s, "\n"); |
112 | } | 112 | } |
113 | 113 | ||
@@ -166,7 +166,7 @@ static void clk_dump_one(struct seq_file *s, struct clk *c, int level) | |||
166 | seq_printf(s, "\"%s\": { ", c->name); | 166 | seq_printf(s, "\"%s\": { ", c->name); |
167 | seq_printf(s, "\"enable_count\": %d,", c->enable_count); | 167 | seq_printf(s, "\"enable_count\": %d,", c->enable_count); |
168 | seq_printf(s, "\"prepare_count\": %d,", c->prepare_count); | 168 | seq_printf(s, "\"prepare_count\": %d,", c->prepare_count); |
169 | seq_printf(s, "\"rate\": %lu", c->rate); | 169 | seq_printf(s, "\"rate\": %lu", clk_get_rate(c)); |
170 | } | 170 | } |
171 | 171 | ||
172 | static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level) | 172 | static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level) |
@@ -534,7 +534,7 @@ static int clk_disable_unused(void) | |||
534 | 534 | ||
535 | return 0; | 535 | return 0; |
536 | } | 536 | } |
537 | late_initcall(clk_disable_unused); | 537 | late_initcall_sync(clk_disable_unused); |
538 | 538 | ||
539 | /*** helper functions ***/ | 539 | /*** helper functions ***/ |
540 | 540 | ||
@@ -1216,7 +1216,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
1216 | clk_prepare_lock(); | 1216 | clk_prepare_lock(); |
1217 | 1217 | ||
1218 | /* bail early if nothing to do */ | 1218 | /* bail early if nothing to do */ |
1219 | if (rate == clk->rate) | 1219 | if (rate == clk_get_rate(clk)) |
1220 | goto out; | 1220 | goto out; |
1221 | 1221 | ||
1222 | if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) { | 1222 | if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) { |
@@ -1377,23 +1377,33 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) | |||
1377 | unsigned long flags; | 1377 | unsigned long flags; |
1378 | int ret = 0; | 1378 | int ret = 0; |
1379 | struct clk *old_parent = clk->parent; | 1379 | struct clk *old_parent = clk->parent; |
1380 | bool migrated_enable = false; | ||
1381 | 1380 | ||
1382 | /* migrate prepare */ | 1381 | /* |
1383 | if (clk->prepare_count) | 1382 | * Migrate prepare state between parents and prevent race with |
1383 | * clk_enable(). | ||
1384 | * | ||
1385 | * If the clock is not prepared, then a race with | ||
1386 | * clk_enable/disable() is impossible since we already have the | ||
1387 | * prepare lock (future calls to clk_enable() need to be preceded by | ||
1388 | * a clk_prepare()). | ||
1389 | * | ||
1390 | * If the clock is prepared, migrate the prepared state to the new | ||
1391 | * parent and also protect against a race with clk_enable() by | ||
1392 | * forcing the clock and the new parent on. This ensures that all | ||
1393 | * future calls to clk_enable() are practically NOPs with respect to | ||
1394 | * hardware and software states. | ||
1395 | * | ||
1396 | * See also: Comment for clk_set_parent() below. | ||
1397 | */ | ||
1398 | if (clk->prepare_count) { | ||
1384 | __clk_prepare(parent); | 1399 | __clk_prepare(parent); |
1385 | 1400 | clk_enable(parent); | |
1386 | flags = clk_enable_lock(); | 1401 | clk_enable(clk); |
1387 | |||
1388 | /* migrate enable */ | ||
1389 | if (clk->enable_count) { | ||
1390 | __clk_enable(parent); | ||
1391 | migrated_enable = true; | ||
1392 | } | 1402 | } |
1393 | 1403 | ||
1394 | /* update the clk tree topology */ | 1404 | /* update the clk tree topology */ |
1405 | flags = clk_enable_lock(); | ||
1395 | clk_reparent(clk, parent); | 1406 | clk_reparent(clk, parent); |
1396 | |||
1397 | clk_enable_unlock(flags); | 1407 | clk_enable_unlock(flags); |
1398 | 1408 | ||
1399 | /* change clock input source */ | 1409 | /* change clock input source */ |
@@ -1401,43 +1411,27 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) | |||
1401 | ret = clk->ops->set_parent(clk->hw, p_index); | 1411 | ret = clk->ops->set_parent(clk->hw, p_index); |
1402 | 1412 | ||
1403 | if (ret) { | 1413 | if (ret) { |
1404 | /* | ||
1405 | * The error handling is tricky due to that we need to release | ||
1406 | * the spinlock while issuing the .set_parent callback. This | ||
1407 | * means the new parent might have been enabled/disabled in | ||
1408 | * between, which must be considered when doing rollback. | ||
1409 | */ | ||
1410 | flags = clk_enable_lock(); | 1414 | flags = clk_enable_lock(); |
1411 | |||
1412 | clk_reparent(clk, old_parent); | 1415 | clk_reparent(clk, old_parent); |
1413 | |||
1414 | if (migrated_enable && clk->enable_count) { | ||
1415 | __clk_disable(parent); | ||
1416 | } else if (migrated_enable && (clk->enable_count == 0)) { | ||
1417 | __clk_disable(old_parent); | ||
1418 | } else if (!migrated_enable && clk->enable_count) { | ||
1419 | __clk_disable(parent); | ||
1420 | __clk_enable(old_parent); | ||
1421 | } | ||
1422 | |||
1423 | clk_enable_unlock(flags); | 1416 | clk_enable_unlock(flags); |
1424 | 1417 | ||
1425 | if (clk->prepare_count) | 1418 | if (clk->prepare_count) { |
1419 | clk_disable(clk); | ||
1420 | clk_disable(parent); | ||
1426 | __clk_unprepare(parent); | 1421 | __clk_unprepare(parent); |
1427 | 1422 | } | |
1428 | return ret; | 1423 | return ret; |
1429 | } | 1424 | } |
1430 | 1425 | ||
1431 | /* clean up enable for old parent if migration was done */ | 1426 | /* |
1432 | if (migrated_enable) { | 1427 | * Finish the migration of prepare state and undo the changes done |
1433 | flags = clk_enable_lock(); | 1428 | * for preventing a race with clk_enable(). |
1434 | __clk_disable(old_parent); | 1429 | */ |
1435 | clk_enable_unlock(flags); | 1430 | if (clk->prepare_count) { |
1436 | } | 1431 | clk_disable(clk); |
1437 | 1432 | clk_disable(old_parent); | |
1438 | /* clean up prepare for old parent if migration was done */ | ||
1439 | if (clk->prepare_count) | ||
1440 | __clk_unprepare(old_parent); | 1433 | __clk_unprepare(old_parent); |
1434 | } | ||
1441 | 1435 | ||
1442 | /* update debugfs with new clk tree topology */ | 1436 | /* update debugfs with new clk tree topology */ |
1443 | clk_debug_reparent(clk, parent); | 1437 | clk_debug_reparent(clk, parent); |
@@ -1449,12 +1443,17 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) | |||
1449 | * @clk: the mux clk whose input we are switching | 1443 | * @clk: the mux clk whose input we are switching |
1450 | * @parent: the new input to clk | 1444 | * @parent: the new input to clk |
1451 | * | 1445 | * |
1452 | * Re-parent clk to use parent as it's new input source. If clk has the | 1446 | * Re-parent clk to use parent as its new input source. If clk is in |
1453 | * CLK_SET_PARENT_GATE flag set then clk must be gated for this | 1447 | * prepared state, the clk will get enabled for the duration of this call. If |
1454 | * operation to succeed. After successfully changing clk's parent | 1448 | * that's not acceptable for a specific clk (Eg: the consumer can't handle |
1455 | * clk_set_parent will update the clk topology, sysfs topology and | 1449 | * that, the reparenting is glitchy in hardware, etc), use the |
1456 | * propagate rate recalculation via __clk_recalc_rates. Returns 0 on | 1450 | * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared. |
1457 | * success, -EERROR otherwise. | 1451 | * |
1452 | * After successfully changing clk's parent clk_set_parent will update the | ||
1453 | * clk topology, sysfs topology and propagate rate recalculation via | ||
1454 | * __clk_recalc_rates. | ||
1455 | * | ||
1456 | * Returns 0 on success, -EERROR otherwise. | ||
1458 | */ | 1457 | */ |
1459 | int clk_set_parent(struct clk *clk, struct clk *parent) | 1458 | int clk_set_parent(struct clk *clk, struct clk *parent) |
1460 | { | 1459 | { |
@@ -1494,8 +1493,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) | |||
1494 | } | 1493 | } |
1495 | 1494 | ||
1496 | /* propagate PRE_RATE_CHANGE notifications */ | 1495 | /* propagate PRE_RATE_CHANGE notifications */ |
1497 | if (clk->notifier_count) | 1496 | ret = __clk_speculate_rates(clk, p_rate); |
1498 | ret = __clk_speculate_rates(clk, p_rate); | ||
1499 | 1497 | ||
1500 | /* abort if a driver objects */ | 1498 | /* abort if a driver objects */ |
1501 | if (ret & NOTIFY_STOP_MASK) | 1499 | if (ret & NOTIFY_STOP_MASK) |
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile new file mode 100644 index 000000000000..8d3aefad2e73 --- /dev/null +++ b/drivers/clk/rockchip/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Rockchip Clock specific Makefile | ||
3 | # | ||
4 | |||
5 | obj-y += clk-rockchip.o | ||
diff --git a/drivers/clk/rockchip/clk-rockchip.c b/drivers/clk/rockchip/clk-rockchip.c new file mode 100644 index 000000000000..967c141b1a20 --- /dev/null +++ b/drivers/clk/rockchip/clk-rockchip.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 MundoReader S.L. | ||
3 | * Author: Heiko Stuebner <heiko@sntech.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/clkdev.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | |||
21 | static DEFINE_SPINLOCK(clk_lock); | ||
22 | |||
23 | /* | ||
24 | * Gate clocks | ||
25 | */ | ||
26 | |||
27 | static void __init rk2928_gate_clk_init(struct device_node *node, | ||
28 | void *data) | ||
29 | { | ||
30 | struct clk_onecell_data *clk_data; | ||
31 | const char *clk_parent; | ||
32 | const char *clk_name; | ||
33 | void __iomem *reg; | ||
34 | void __iomem *reg_idx; | ||
35 | int flags; | ||
36 | int qty; | ||
37 | int reg_bit; | ||
38 | int clkflags = CLK_SET_RATE_PARENT; | ||
39 | int i; | ||
40 | |||
41 | qty = of_property_count_strings(node, "clock-output-names"); | ||
42 | if (qty < 0) { | ||
43 | pr_err("%s: error in clock-output-names %d\n", __func__, qty); | ||
44 | return; | ||
45 | } | ||
46 | |||
47 | if (qty == 0) { | ||
48 | pr_info("%s: nothing to do\n", __func__); | ||
49 | return; | ||
50 | } | ||
51 | |||
52 | reg = of_iomap(node, 0); | ||
53 | |||
54 | clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); | ||
55 | if (!clk_data) | ||
56 | return; | ||
57 | |||
58 | clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL); | ||
59 | if (!clk_data->clks) { | ||
60 | kfree(clk_data); | ||
61 | return; | ||
62 | } | ||
63 | |||
64 | flags = CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE; | ||
65 | |||
66 | for (i = 0; i < qty; i++) { | ||
67 | of_property_read_string_index(node, "clock-output-names", | ||
68 | i, &clk_name); | ||
69 | |||
70 | /* ignore empty slots */ | ||
71 | if (!strcmp("reserved", clk_name)) | ||
72 | continue; | ||
73 | |||
74 | clk_parent = of_clk_get_parent_name(node, i); | ||
75 | |||
76 | /* keep all gates untouched for now */ | ||
77 | clkflags |= CLK_IGNORE_UNUSED; | ||
78 | |||
79 | reg_idx = reg + (4 * (i / 16)); | ||
80 | reg_bit = (i % 16); | ||
81 | |||
82 | clk_data->clks[i] = clk_register_gate(NULL, clk_name, | ||
83 | clk_parent, clkflags, | ||
84 | reg_idx, reg_bit, | ||
85 | flags, | ||
86 | &clk_lock); | ||
87 | WARN_ON(IS_ERR(clk_data->clks[i])); | ||
88 | } | ||
89 | |||
90 | clk_data->clk_num = qty; | ||
91 | |||
92 | of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
93 | } | ||
94 | CLK_OF_DECLARE(rk2928_gate, "rockchip,rk2928-gate-clk", rk2928_gate_clk_init); | ||
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index addc738a06fb..1bdb882c845b 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c | |||
@@ -356,8 +356,8 @@ struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = { | |||
356 | 356 | ||
357 | /* list of mux clocks supported in all exynos4 soc's */ | 357 | /* list of mux clocks supported in all exynos4 soc's */ |
358 | struct samsung_mux_clock exynos4_mux_clks[] __initdata = { | 358 | struct samsung_mux_clock exynos4_mux_clks[] __initdata = { |
359 | MUX_F(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, | 359 | MUX_FA(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, |
360 | CLK_SET_RATE_PARENT, 0), | 360 | CLK_SET_RATE_PARENT, 0, "mout_apll"), |
361 | MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), | 361 | MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), |
362 | MUX(none, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1), | 362 | MUX(none, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1), |
363 | MUX(none, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), | 363 | MUX(none, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), |
@@ -385,9 +385,9 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { | |||
385 | MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1), | 385 | MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1), |
386 | MUX(none, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4), | 386 | MUX(none, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4), |
387 | MUX(none, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4), | 387 | MUX(none, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4), |
388 | MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "sclk_mpll"), | 388 | MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "mout_mpll"), |
389 | MUX_A(mout_core, "mout_core", mout_core_p4210, | 389 | MUX_A(mout_core, "mout_core", mout_core_p4210, |
390 | SRC_CPU, 16, 1, "mout_core"), | 390 | SRC_CPU, 16, 1, "moutcore"), |
391 | MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, | 391 | MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, |
392 | SRC_TOP0, 8, 1, "sclk_vpll"), | 392 | SRC_TOP0, 8, 1, "sclk_vpll"), |
393 | MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4), | 393 | MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4), |
@@ -424,8 +424,8 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { | |||
424 | 424 | ||
425 | /* list of mux clocks supported in exynos4x12 soc */ | 425 | /* list of mux clocks supported in exynos4x12 soc */ |
426 | struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { | 426 | struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { |
427 | MUX(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12, | 427 | MUX_A(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12, |
428 | SRC_CPU, 24, 1), | 428 | SRC_CPU, 24, 1, "mout_mpll"), |
429 | MUX(none, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1), | 429 | MUX(none, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1), |
430 | MUX(none, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1), | 430 | MUX(none, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1), |
431 | MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12, | 431 | MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12, |
@@ -449,7 +449,8 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { | |||
449 | SRC_DMC, 12, 1, "sclk_mpll"), | 449 | SRC_DMC, 12, 1, "sclk_mpll"), |
450 | MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, | 450 | MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, |
451 | SRC_TOP0, 8, 1, "sclk_vpll"), | 451 | SRC_TOP0, 8, 1, "sclk_vpll"), |
452 | MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1), | 452 | MUX_A(mout_core, "mout_core", mout_core_p4x12, |
453 | SRC_CPU, 16, 1, "moutcore"), | ||
453 | MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4), | 454 | MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4), |
454 | MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4), | 455 | MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4), |
455 | MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4), | 456 | MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4), |
@@ -537,7 +538,7 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = { | |||
537 | DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8), | 538 | DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8), |
538 | DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4), | 539 | DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4), |
539 | DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4), | 540 | DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4), |
540 | DIV_A(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3, "arm_clk"), | 541 | DIV_A(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3, "armclk"), |
541 | DIV_A(sclk_apll, "sclk_apll", "mout_apll", | 542 | DIV_A(sclk_apll, "sclk_apll", "mout_apll", |
542 | DIV_CPU0, 24, 3, "sclk_apll"), | 543 | DIV_CPU0, 24, 3, "sclk_apll"), |
543 | DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4, | 544 | DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4, |
@@ -1070,9 +1071,9 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so | |||
1070 | pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" | 1071 | pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" |
1071 | "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", | 1072 | "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", |
1072 | exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", | 1073 | exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", |
1073 | _get_rate("sclk_apll"), _get_rate("sclk_mpll"), | 1074 | _get_rate("sclk_apll"), _get_rate("mout_mpll"), |
1074 | _get_rate("sclk_epll"), _get_rate("sclk_vpll"), | 1075 | _get_rate("sclk_epll"), _get_rate("sclk_vpll"), |
1075 | _get_rate("arm_clk")); | 1076 | _get_rate("armclk")); |
1076 | } | 1077 | } |
1077 | 1078 | ||
1078 | 1079 | ||
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index e4ad6ea9aa76..2f7dba20ced8 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h | |||
@@ -144,6 +144,9 @@ struct samsung_mux_clock { | |||
144 | #define MUX_F(_id, cname, pnames, o, s, w, f, mf) \ | 144 | #define MUX_F(_id, cname, pnames, o, s, w, f, mf) \ |
145 | __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL) | 145 | __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL) |
146 | 146 | ||
147 | #define MUX_FA(_id, cname, pnames, o, s, w, f, mf, a) \ | ||
148 | __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, a) | ||
149 | |||
147 | /** | 150 | /** |
148 | * @id: platform specific id of the clock. | 151 | * @id: platform specific id of the clock. |
149 | * struct samsung_div_clock: information about div clock | 152 | * struct samsung_div_clock: information about div clock |
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 8492ad1d5360..412912bbba53 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -239,7 +239,7 @@ struct mux_data { | |||
239 | u8 shift; | 239 | u8 shift; |
240 | }; | 240 | }; |
241 | 241 | ||
242 | static const __initconst struct mux_data cpu_data = { | 242 | static const __initconst struct mux_data cpu_mux_data = { |
243 | .shift = 16, | 243 | .shift = 16, |
244 | }; | 244 | }; |
245 | 245 | ||
@@ -333,22 +333,34 @@ struct gates_data { | |||
333 | DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE); | 333 | DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE); |
334 | }; | 334 | }; |
335 | 335 | ||
336 | static const __initconst struct gates_data axi_gates_data = { | 336 | static const __initconst struct gates_data sun4i_axi_gates_data = { |
337 | .mask = {1}, | 337 | .mask = {1}, |
338 | }; | 338 | }; |
339 | 339 | ||
340 | static const __initconst struct gates_data ahb_gates_data = { | 340 | static const __initconst struct gates_data sun4i_ahb_gates_data = { |
341 | .mask = {0x7F77FFF, 0x14FB3F}, | 341 | .mask = {0x7F77FFF, 0x14FB3F}, |
342 | }; | 342 | }; |
343 | 343 | ||
344 | static const __initconst struct gates_data apb0_gates_data = { | 344 | static const __initconst struct gates_data sun5i_a13_ahb_gates_data = { |
345 | .mask = {0x107067e7, 0x185111}, | ||
346 | }; | ||
347 | |||
348 | static const __initconst struct gates_data sun4i_apb0_gates_data = { | ||
345 | .mask = {0x4EF}, | 349 | .mask = {0x4EF}, |
346 | }; | 350 | }; |
347 | 351 | ||
348 | static const __initconst struct gates_data apb1_gates_data = { | 352 | static const __initconst struct gates_data sun5i_a13_apb0_gates_data = { |
353 | .mask = {0x61}, | ||
354 | }; | ||
355 | |||
356 | static const __initconst struct gates_data sun4i_apb1_gates_data = { | ||
349 | .mask = {0xFF00F7}, | 357 | .mask = {0xFF00F7}, |
350 | }; | 358 | }; |
351 | 359 | ||
360 | static const __initconst struct gates_data sun5i_a13_apb1_gates_data = { | ||
361 | .mask = {0xa0007}, | ||
362 | }; | ||
363 | |||
352 | static void __init sunxi_gates_clk_setup(struct device_node *node, | 364 | static void __init sunxi_gates_clk_setup(struct device_node *node, |
353 | struct gates_data *data) | 365 | struct gates_data *data) |
354 | { | 366 | { |
@@ -421,17 +433,20 @@ static const __initconst struct of_device_id clk_div_match[] = { | |||
421 | 433 | ||
422 | /* Matches for mux clocks */ | 434 | /* Matches for mux clocks */ |
423 | static const __initconst struct of_device_id clk_mux_match[] = { | 435 | static const __initconst struct of_device_id clk_mux_match[] = { |
424 | {.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_data,}, | 436 | {.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_mux_data,}, |
425 | {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &apb1_mux_data,}, | 437 | {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &apb1_mux_data,}, |
426 | {} | 438 | {} |
427 | }; | 439 | }; |
428 | 440 | ||
429 | /* Matches for gate clocks */ | 441 | /* Matches for gate clocks */ |
430 | static const __initconst struct of_device_id clk_gates_match[] = { | 442 | static const __initconst struct of_device_id clk_gates_match[] = { |
431 | {.compatible = "allwinner,sun4i-axi-gates-clk", .data = &axi_gates_data,}, | 443 | {.compatible = "allwinner,sun4i-axi-gates-clk", .data = &sun4i_axi_gates_data,}, |
432 | {.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &ahb_gates_data,}, | 444 | {.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &sun4i_ahb_gates_data,}, |
433 | {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &apb0_gates_data,}, | 445 | {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,}, |
434 | {.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &apb1_gates_data,}, | 446 | {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, |
447 | {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, | ||
448 | {.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, | ||
449 | {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, | ||
435 | {} | 450 | {} |
436 | }; | 451 | }; |
437 | 452 | ||
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 17c2cc086eb4..197074a57754 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c | |||
@@ -117,10 +117,6 @@ | |||
117 | #define PLLCX_MISC2_DEFAULT 0x30211200 | 117 | #define PLLCX_MISC2_DEFAULT 0x30211200 |
118 | #define PLLCX_MISC3_DEFAULT 0x200 | 118 | #define PLLCX_MISC3_DEFAULT 0x200 |
119 | 119 | ||
120 | #define PMC_PLLM_WB0_OVERRIDE 0x1dc | ||
121 | #define PMC_PLLM_WB0_OVERRIDE_2 0x2b0 | ||
122 | #define PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK BIT(27) | ||
123 | |||
124 | #define PMC_SATA_PWRGT 0x1ac | 120 | #define PMC_SATA_PWRGT 0x1ac |
125 | #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) | 121 | #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) |
126 | #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) | 122 | #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) |
@@ -128,38 +124,31 @@ | |||
128 | #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) | 124 | #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) |
129 | #define pll_readl_base(p) pll_readl(p->params->base_reg, p) | 125 | #define pll_readl_base(p) pll_readl(p->params->base_reg, p) |
130 | #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) | 126 | #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) |
127 | #define pll_override_readl(offset, p) readl_relaxed(p->pmc + offset) | ||
131 | 128 | ||
132 | #define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset) | 129 | #define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset) |
133 | #define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p) | 130 | #define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p) |
134 | #define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p) | 131 | #define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p) |
132 | #define pll_override_writel(val, offset, p) writel(val, p->pmc + offset) | ||
135 | 133 | ||
136 | #define mask(w) ((1 << (w)) - 1) | 134 | #define mask(w) ((1 << (w)) - 1) |
137 | #define divm_mask(p) mask(p->divm_width) | 135 | #define divm_mask(p) mask(p->params->div_nmp->divm_width) |
138 | #define divn_mask(p) mask(p->divn_width) | 136 | #define divn_mask(p) mask(p->params->div_nmp->divn_width) |
139 | #define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ | 137 | #define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ |
140 | mask(p->divp_width)) | 138 | mask(p->params->div_nmp->divp_width)) |
141 | 139 | ||
142 | #define divm_max(p) (divm_mask(p)) | 140 | #define divm_max(p) (divm_mask(p)) |
143 | #define divn_max(p) (divn_mask(p)) | 141 | #define divn_max(p) (divn_mask(p)) |
144 | #define divp_max(p) (1 << (divp_mask(p))) | 142 | #define divp_max(p) (1 << (divp_mask(p))) |
145 | 143 | ||
146 | 144 | static struct div_nmp default_nmp = { | |
147 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | 145 | .divn_shift = PLL_BASE_DIVN_SHIFT, |
148 | /* PLLXC has 4-bit PDIV, but entry 15 is not allowed in h/w */ | 146 | .divn_width = PLL_BASE_DIVN_WIDTH, |
149 | #define PLLXC_PDIV_MAX 14 | 147 | .divm_shift = PLL_BASE_DIVM_SHIFT, |
150 | 148 | .divm_width = PLL_BASE_DIVM_WIDTH, | |
151 | /* non-monotonic mapping below is not a typo */ | 149 | .divp_shift = PLL_BASE_DIVP_SHIFT, |
152 | static u8 pllxc_p[PLLXC_PDIV_MAX + 1] = { | 150 | .divp_width = PLL_BASE_DIVP_WIDTH, |
153 | /* PDIV: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 */ | ||
154 | /* p: */ 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 12, 16, 20, 24, 32 | ||
155 | }; | ||
156 | |||
157 | #define PLLCX_PDIV_MAX 7 | ||
158 | static u8 pllcx_p[PLLCX_PDIV_MAX + 1] = { | ||
159 | /* PDIV: 0, 1, 2, 3, 4, 5, 6, 7 */ | ||
160 | /* p: */ 1, 2, 3, 4, 6, 8, 12, 16 | ||
161 | }; | 151 | }; |
162 | #endif | ||
163 | 152 | ||
164 | static void clk_pll_enable_lock(struct tegra_clk_pll *pll) | 153 | static void clk_pll_enable_lock(struct tegra_clk_pll *pll) |
165 | { | 154 | { |
@@ -297,6 +286,39 @@ static void clk_pll_disable(struct clk_hw *hw) | |||
297 | spin_unlock_irqrestore(pll->lock, flags); | 286 | spin_unlock_irqrestore(pll->lock, flags); |
298 | } | 287 | } |
299 | 288 | ||
289 | static int _p_div_to_hw(struct clk_hw *hw, u8 p_div) | ||
290 | { | ||
291 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
292 | struct pdiv_map *p_tohw = pll->params->pdiv_tohw; | ||
293 | |||
294 | if (p_tohw) { | ||
295 | while (p_tohw->pdiv) { | ||
296 | if (p_div <= p_tohw->pdiv) | ||
297 | return p_tohw->hw_val; | ||
298 | p_tohw++; | ||
299 | } | ||
300 | return -EINVAL; | ||
301 | } | ||
302 | return -EINVAL; | ||
303 | } | ||
304 | |||
305 | static int _hw_to_p_div(struct clk_hw *hw, u8 p_div_hw) | ||
306 | { | ||
307 | struct tegra_clk_pll *pll = to_clk_pll(hw); | ||
308 | struct pdiv_map *p_tohw = pll->params->pdiv_tohw; | ||
309 | |||
310 | if (p_tohw) { | ||
311 | while (p_tohw->pdiv) { | ||
312 | if (p_div_hw == p_tohw->hw_val) | ||
313 | return p_tohw->pdiv; | ||
314 | p_tohw++; | ||
315 | } | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | |||
319 | return 1 << p_div_hw; | ||
320 | } | ||
321 | |||
300 | static int _get_table_rate(struct clk_hw *hw, | 322 | static int _get_table_rate(struct clk_hw *hw, |
301 | struct tegra_clk_pll_freq_table *cfg, | 323 | struct tegra_clk_pll_freq_table *cfg, |
302 | unsigned long rate, unsigned long parent_rate) | 324 | unsigned long rate, unsigned long parent_rate) |
@@ -326,9 +348,9 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | |||
326 | unsigned long rate, unsigned long parent_rate) | 348 | unsigned long rate, unsigned long parent_rate) |
327 | { | 349 | { |
328 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 350 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
329 | struct pdiv_map *p_tohw = pll->params->pdiv_tohw; | ||
330 | unsigned long cfreq; | 351 | unsigned long cfreq; |
331 | u32 p_div = 0; | 352 | u32 p_div = 0; |
353 | int ret; | ||
332 | 354 | ||
333 | switch (parent_rate) { | 355 | switch (parent_rate) { |
334 | case 12000000: | 356 | case 12000000: |
@@ -369,20 +391,16 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | |||
369 | || cfg->output_rate > pll->params->vco_max) { | 391 | || cfg->output_rate > pll->params->vco_max) { |
370 | pr_err("%s: Failed to set %s rate %lu\n", | 392 | pr_err("%s: Failed to set %s rate %lu\n", |
371 | __func__, __clk_get_name(hw->clk), rate); | 393 | __func__, __clk_get_name(hw->clk), rate); |
394 | WARN_ON(1); | ||
372 | return -EINVAL; | 395 | return -EINVAL; |
373 | } | 396 | } |
374 | 397 | ||
375 | if (p_tohw) { | 398 | if (pll->params->pdiv_tohw) { |
376 | p_div = 1 << p_div; | 399 | ret = _p_div_to_hw(hw, 1 << p_div); |
377 | while (p_tohw->pdiv) { | 400 | if (ret < 0) |
378 | if (p_div <= p_tohw->pdiv) { | 401 | return ret; |
379 | cfg->p = p_tohw->hw_val; | 402 | else |
380 | break; | 403 | cfg->p = ret; |
381 | } | ||
382 | p_tohw++; | ||
383 | } | ||
384 | if (!p_tohw->pdiv) | ||
385 | return -EINVAL; | ||
386 | } else | 404 | } else |
387 | cfg->p = p_div; | 405 | cfg->p = p_div; |
388 | 406 | ||
@@ -393,29 +411,61 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll, | |||
393 | struct tegra_clk_pll_freq_table *cfg) | 411 | struct tegra_clk_pll_freq_table *cfg) |
394 | { | 412 | { |
395 | u32 val; | 413 | u32 val; |
414 | struct tegra_clk_pll_params *params = pll->params; | ||
415 | struct div_nmp *div_nmp = params->div_nmp; | ||
416 | |||
417 | if ((pll->flags & TEGRA_PLLM) && | ||
418 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & | ||
419 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { | ||
420 | val = pll_override_readl(params->pmc_divp_reg, pll); | ||
421 | val &= ~(divp_mask(pll) << div_nmp->override_divp_shift); | ||
422 | val |= cfg->p << div_nmp->override_divp_shift; | ||
423 | pll_override_writel(val, params->pmc_divp_reg, pll); | ||
424 | |||
425 | val = pll_override_readl(params->pmc_divnm_reg, pll); | ||
426 | val &= ~(divm_mask(pll) << div_nmp->override_divm_shift) | | ||
427 | ~(divn_mask(pll) << div_nmp->override_divn_shift); | ||
428 | val |= (cfg->m << div_nmp->override_divm_shift) | | ||
429 | (cfg->n << div_nmp->override_divn_shift); | ||
430 | pll_override_writel(val, params->pmc_divnm_reg, pll); | ||
431 | } else { | ||
432 | val = pll_readl_base(pll); | ||
396 | 433 | ||
397 | val = pll_readl_base(pll); | 434 | val &= ~((divm_mask(pll) << div_nmp->divm_shift) | |
435 | (divn_mask(pll) << div_nmp->divn_shift) | | ||
436 | (divp_mask(pll) << div_nmp->divp_shift)); | ||
398 | 437 | ||
399 | val &= ~((divm_mask(pll) << pll->divm_shift) | | 438 | val |= ((cfg->m << div_nmp->divm_shift) | |
400 | (divn_mask(pll) << pll->divn_shift) | | 439 | (cfg->n << div_nmp->divn_shift) | |
401 | (divp_mask(pll) << pll->divp_shift)); | 440 | (cfg->p << div_nmp->divp_shift)); |
402 | val |= ((cfg->m << pll->divm_shift) | | ||
403 | (cfg->n << pll->divn_shift) | | ||
404 | (cfg->p << pll->divp_shift)); | ||
405 | 441 | ||
406 | pll_writel_base(val, pll); | 442 | pll_writel_base(val, pll); |
443 | } | ||
407 | } | 444 | } |
408 | 445 | ||
409 | static void _get_pll_mnp(struct tegra_clk_pll *pll, | 446 | static void _get_pll_mnp(struct tegra_clk_pll *pll, |
410 | struct tegra_clk_pll_freq_table *cfg) | 447 | struct tegra_clk_pll_freq_table *cfg) |
411 | { | 448 | { |
412 | u32 val; | 449 | u32 val; |
450 | struct tegra_clk_pll_params *params = pll->params; | ||
451 | struct div_nmp *div_nmp = params->div_nmp; | ||
452 | |||
453 | if ((pll->flags & TEGRA_PLLM) && | ||
454 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & | ||
455 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { | ||
456 | val = pll_override_readl(params->pmc_divp_reg, pll); | ||
457 | cfg->p = (val >> div_nmp->override_divp_shift) & divp_mask(pll); | ||
458 | |||
459 | val = pll_override_readl(params->pmc_divnm_reg, pll); | ||
460 | cfg->m = (val >> div_nmp->override_divm_shift) & divm_mask(pll); | ||
461 | cfg->n = (val >> div_nmp->override_divn_shift) & divn_mask(pll); | ||
462 | } else { | ||
463 | val = pll_readl_base(pll); | ||
413 | 464 | ||
414 | val = pll_readl_base(pll); | 465 | cfg->m = (val >> div_nmp->divm_shift) & divm_mask(pll); |
415 | 466 | cfg->n = (val >> div_nmp->divn_shift) & divn_mask(pll); | |
416 | cfg->m = (val >> pll->divm_shift) & (divm_mask(pll)); | 467 | cfg->p = (val >> div_nmp->divp_shift) & divp_mask(pll); |
417 | cfg->n = (val >> pll->divn_shift) & (divn_mask(pll)); | 468 | } |
418 | cfg->p = (val >> pll->divp_shift) & (divp_mask(pll)); | ||
419 | } | 469 | } |
420 | 470 | ||
421 | static void _update_pll_cpcon(struct tegra_clk_pll *pll, | 471 | static void _update_pll_cpcon(struct tegra_clk_pll *pll, |
@@ -485,9 +535,10 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
485 | } | 535 | } |
486 | 536 | ||
487 | if (_get_table_rate(hw, &cfg, rate, parent_rate) && | 537 | if (_get_table_rate(hw, &cfg, rate, parent_rate) && |
488 | _calc_rate(hw, &cfg, rate, parent_rate)) | 538 | _calc_rate(hw, &cfg, rate, parent_rate)) { |
539 | WARN_ON(1); | ||
489 | return -EINVAL; | 540 | return -EINVAL; |
490 | 541 | } | |
491 | if (pll->lock) | 542 | if (pll->lock) |
492 | spin_lock_irqsave(pll->lock, flags); | 543 | spin_lock_irqsave(pll->lock, flags); |
493 | 544 | ||
@@ -507,7 +558,6 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | |||
507 | { | 558 | { |
508 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 559 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
509 | struct tegra_clk_pll_freq_table cfg; | 560 | struct tegra_clk_pll_freq_table cfg; |
510 | u64 output_rate = *prate; | ||
511 | 561 | ||
512 | if (pll->flags & TEGRA_PLL_FIXED) | 562 | if (pll->flags & TEGRA_PLL_FIXED) |
513 | return pll->fixed_rate; | 563 | return pll->fixed_rate; |
@@ -517,13 +567,12 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | |||
517 | return __clk_get_rate(hw->clk); | 567 | return __clk_get_rate(hw->clk); |
518 | 568 | ||
519 | if (_get_table_rate(hw, &cfg, rate, *prate) && | 569 | if (_get_table_rate(hw, &cfg, rate, *prate) && |
520 | _calc_rate(hw, &cfg, rate, *prate)) | 570 | _calc_rate(hw, &cfg, rate, *prate)) { |
571 | WARN_ON(1); | ||
521 | return -EINVAL; | 572 | return -EINVAL; |
573 | } | ||
522 | 574 | ||
523 | output_rate *= cfg.n; | 575 | return cfg.output_rate; |
524 | do_div(output_rate, cfg.m * (1 << cfg.p)); | ||
525 | |||
526 | return output_rate; | ||
527 | } | 576 | } |
528 | 577 | ||
529 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | 578 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, |
@@ -531,7 +580,6 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | |||
531 | { | 580 | { |
532 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 581 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
533 | struct tegra_clk_pll_freq_table cfg; | 582 | struct tegra_clk_pll_freq_table cfg; |
534 | struct pdiv_map *p_tohw = pll->params->pdiv_tohw; | ||
535 | u32 val; | 583 | u32 val; |
536 | u64 rate = parent_rate; | 584 | u64 rate = parent_rate; |
537 | int pdiv; | 585 | int pdiv; |
@@ -553,21 +601,11 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | |||
553 | 601 | ||
554 | _get_pll_mnp(pll, &cfg); | 602 | _get_pll_mnp(pll, &cfg); |
555 | 603 | ||
556 | if (p_tohw) { | 604 | pdiv = _hw_to_p_div(hw, cfg.p); |
557 | while (p_tohw->pdiv) { | 605 | if (pdiv < 0) { |
558 | if (cfg.p == p_tohw->hw_val) { | 606 | WARN_ON(1); |
559 | pdiv = p_tohw->pdiv; | 607 | pdiv = 1; |
560 | break; | 608 | } |
561 | } | ||
562 | p_tohw++; | ||
563 | } | ||
564 | |||
565 | if (!p_tohw->pdiv) { | ||
566 | WARN_ON(1); | ||
567 | pdiv = 1; | ||
568 | } | ||
569 | } else | ||
570 | pdiv = 1 << cfg.p; | ||
571 | 609 | ||
572 | cfg.m *= pdiv; | 610 | cfg.m *= pdiv; |
573 | 611 | ||
@@ -647,9 +685,9 @@ static int clk_plle_enable(struct clk_hw *hw) | |||
647 | val = pll_readl_base(pll); | 685 | val = pll_readl_base(pll); |
648 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); | 686 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); |
649 | val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); | 687 | val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); |
650 | val |= sel.m << pll->divm_shift; | 688 | val |= sel.m << pll->params->div_nmp->divm_shift; |
651 | val |= sel.n << pll->divn_shift; | 689 | val |= sel.n << pll->params->div_nmp->divn_shift; |
652 | val |= sel.p << pll->divp_shift; | 690 | val |= sel.p << pll->params->div_nmp->divp_shift; |
653 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; | 691 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; |
654 | pll_writel_base(val, pll); | 692 | pll_writel_base(val, pll); |
655 | } | 693 | } |
@@ -680,9 +718,9 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw, | |||
680 | u32 divn = 0, divm = 0, divp = 0; | 718 | u32 divn = 0, divm = 0, divp = 0; |
681 | u64 rate = parent_rate; | 719 | u64 rate = parent_rate; |
682 | 720 | ||
683 | divp = (val >> pll->divp_shift) & (divp_mask(pll)); | 721 | divp = (val >> pll->params->div_nmp->divp_shift) & (divp_mask(pll)); |
684 | divn = (val >> pll->divn_shift) & (divn_mask(pll)); | 722 | divn = (val >> pll->params->div_nmp->divn_shift) & (divn_mask(pll)); |
685 | divm = (val >> pll->divm_shift) & (divm_mask(pll)); | 723 | divm = (val >> pll->params->div_nmp->divm_shift) & (divm_mask(pll)); |
686 | divm *= divp; | 724 | divm *= divp; |
687 | 725 | ||
688 | rate *= divn; | 726 | rate *= divn; |
@@ -769,16 +807,22 @@ static int _calc_dynamic_ramp_rate(struct clk_hw *hw, | |||
769 | { | 807 | { |
770 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 808 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
771 | unsigned int p; | 809 | unsigned int p; |
810 | int p_div; | ||
772 | 811 | ||
773 | if (!rate) | 812 | if (!rate) |
774 | return -EINVAL; | 813 | return -EINVAL; |
775 | 814 | ||
776 | p = DIV_ROUND_UP(pll->params->vco_min, rate); | 815 | p = DIV_ROUND_UP(pll->params->vco_min, rate); |
777 | cfg->m = _pll_fixed_mdiv(pll->params, parent_rate); | 816 | cfg->m = _pll_fixed_mdiv(pll->params, parent_rate); |
778 | cfg->p = p; | 817 | cfg->output_rate = rate * p; |
779 | cfg->output_rate = rate * cfg->p; | ||
780 | cfg->n = cfg->output_rate * cfg->m / parent_rate; | 818 | cfg->n = cfg->output_rate * cfg->m / parent_rate; |
781 | 819 | ||
820 | p_div = _p_div_to_hw(hw, p); | ||
821 | if (p_div < 0) | ||
822 | return p_div; | ||
823 | else | ||
824 | cfg->p = p_div; | ||
825 | |||
782 | if (cfg->n > divn_max(pll) || cfg->output_rate > pll->params->vco_max) | 826 | if (cfg->n > divn_max(pll) || cfg->output_rate > pll->params->vco_max) |
783 | return -EINVAL; | 827 | return -EINVAL; |
784 | 828 | ||
@@ -790,18 +834,25 @@ static int _pll_ramp_calc_pll(struct clk_hw *hw, | |||
790 | unsigned long rate, unsigned long parent_rate) | 834 | unsigned long rate, unsigned long parent_rate) |
791 | { | 835 | { |
792 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 836 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
793 | int err = 0; | 837 | int err = 0, p_div; |
794 | 838 | ||
795 | err = _get_table_rate(hw, cfg, rate, parent_rate); | 839 | err = _get_table_rate(hw, cfg, rate, parent_rate); |
796 | if (err < 0) | 840 | if (err < 0) |
797 | err = _calc_dynamic_ramp_rate(hw, cfg, rate, parent_rate); | 841 | err = _calc_dynamic_ramp_rate(hw, cfg, rate, parent_rate); |
798 | else if (cfg->m != _pll_fixed_mdiv(pll->params, parent_rate)) { | 842 | else { |
843 | if (cfg->m != _pll_fixed_mdiv(pll->params, parent_rate)) { | ||
799 | WARN_ON(1); | 844 | WARN_ON(1); |
800 | err = -EINVAL; | 845 | err = -EINVAL; |
801 | goto out; | 846 | goto out; |
847 | } | ||
848 | p_div = _p_div_to_hw(hw, cfg->p); | ||
849 | if (p_div < 0) | ||
850 | return p_div; | ||
851 | else | ||
852 | cfg->p = p_div; | ||
802 | } | 853 | } |
803 | 854 | ||
804 | if (!cfg->p || (cfg->p > pll->params->max_p)) | 855 | if (cfg->p > pll->params->max_p) |
805 | err = -EINVAL; | 856 | err = -EINVAL; |
806 | 857 | ||
807 | out: | 858 | out: |
@@ -815,7 +866,6 @@ static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate, | |||
815 | struct tegra_clk_pll_freq_table cfg, old_cfg; | 866 | struct tegra_clk_pll_freq_table cfg, old_cfg; |
816 | unsigned long flags = 0; | 867 | unsigned long flags = 0; |
817 | int ret = 0; | 868 | int ret = 0; |
818 | u8 old_p; | ||
819 | 869 | ||
820 | ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate); | 870 | ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate); |
821 | if (ret < 0) | 871 | if (ret < 0) |
@@ -826,11 +876,8 @@ static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate, | |||
826 | 876 | ||
827 | _get_pll_mnp(pll, &old_cfg); | 877 | _get_pll_mnp(pll, &old_cfg); |
828 | 878 | ||
829 | old_p = pllxc_p[old_cfg.p]; | 879 | if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p) |
830 | if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_p != cfg.p) { | ||
831 | cfg.p -= 1; | ||
832 | ret = _program_pll(hw, &cfg, rate); | 880 | ret = _program_pll(hw, &cfg, rate); |
833 | } | ||
834 | 881 | ||
835 | if (pll->lock) | 882 | if (pll->lock) |
836 | spin_unlock_irqrestore(pll->lock, flags); | 883 | spin_unlock_irqrestore(pll->lock, flags); |
@@ -842,15 +889,19 @@ static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate, | |||
842 | unsigned long *prate) | 889 | unsigned long *prate) |
843 | { | 890 | { |
844 | struct tegra_clk_pll_freq_table cfg; | 891 | struct tegra_clk_pll_freq_table cfg; |
845 | int ret = 0; | 892 | int ret = 0, p_div; |
846 | u64 output_rate = *prate; | 893 | u64 output_rate = *prate; |
847 | 894 | ||
848 | ret = _pll_ramp_calc_pll(hw, &cfg, rate, *prate); | 895 | ret = _pll_ramp_calc_pll(hw, &cfg, rate, *prate); |
849 | if (ret < 0) | 896 | if (ret < 0) |
850 | return ret; | 897 | return ret; |
851 | 898 | ||
899 | p_div = _hw_to_p_div(hw, cfg.p); | ||
900 | if (p_div < 0) | ||
901 | return p_div; | ||
902 | |||
852 | output_rate *= cfg.n; | 903 | output_rate *= cfg.n; |
853 | do_div(output_rate, cfg.m * cfg.p); | 904 | do_div(output_rate, cfg.m * p_div); |
854 | 905 | ||
855 | return output_rate; | 906 | return output_rate; |
856 | } | 907 | } |
@@ -862,7 +913,6 @@ static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate, | |||
862 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 913 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
863 | unsigned long flags = 0; | 914 | unsigned long flags = 0; |
864 | int state, ret = 0; | 915 | int state, ret = 0; |
865 | u32 val; | ||
866 | 916 | ||
867 | if (pll->lock) | 917 | if (pll->lock) |
868 | spin_lock_irqsave(pll->lock, flags); | 918 | spin_lock_irqsave(pll->lock, flags); |
@@ -881,22 +931,7 @@ static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate, | |||
881 | if (ret < 0) | 931 | if (ret < 0) |
882 | goto out; | 932 | goto out; |
883 | 933 | ||
884 | cfg.p -= 1; | 934 | _update_pll_mnp(pll, &cfg); |
885 | |||
886 | val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE); | ||
887 | if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) { | ||
888 | val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE_2); | ||
889 | val = cfg.p ? (val | PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK) : | ||
890 | (val & ~PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK); | ||
891 | writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE_2); | ||
892 | |||
893 | val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE); | ||
894 | val &= ~(divn_mask(pll) | divm_mask(pll)); | ||
895 | val |= (cfg.m << pll->divm_shift) | (cfg.n << pll->divn_shift); | ||
896 | writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE); | ||
897 | } else | ||
898 | _update_pll_mnp(pll, &cfg); | ||
899 | |||
900 | 935 | ||
901 | out: | 936 | out: |
902 | if (pll->lock) | 937 | if (pll->lock) |
@@ -1010,13 +1045,10 @@ static int _pllcx_update_dynamic_coef(struct tegra_clk_pll *pll, | |||
1010 | static int clk_pllc_set_rate(struct clk_hw *hw, unsigned long rate, | 1045 | static int clk_pllc_set_rate(struct clk_hw *hw, unsigned long rate, |
1011 | unsigned long parent_rate) | 1046 | unsigned long parent_rate) |
1012 | { | 1047 | { |
1013 | struct tegra_clk_pll_freq_table cfg; | 1048 | struct tegra_clk_pll_freq_table cfg, old_cfg; |
1014 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 1049 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
1015 | unsigned long flags = 0; | 1050 | unsigned long flags = 0; |
1016 | int state, ret = 0; | 1051 | int state, ret = 0; |
1017 | u32 val; | ||
1018 | u16 old_m, old_n; | ||
1019 | u8 old_p; | ||
1020 | 1052 | ||
1021 | if (pll->lock) | 1053 | if (pll->lock) |
1022 | spin_lock_irqsave(pll->lock, flags); | 1054 | spin_lock_irqsave(pll->lock, flags); |
@@ -1025,21 +1057,16 @@ static int clk_pllc_set_rate(struct clk_hw *hw, unsigned long rate, | |||
1025 | if (ret < 0) | 1057 | if (ret < 0) |
1026 | goto out; | 1058 | goto out; |
1027 | 1059 | ||
1028 | val = pll_readl_base(pll); | 1060 | _get_pll_mnp(pll, &old_cfg); |
1029 | old_m = (val >> pll->divm_shift) & (divm_mask(pll)); | ||
1030 | old_n = (val >> pll->divn_shift) & (divn_mask(pll)); | ||
1031 | old_p = pllcx_p[(val >> pll->divp_shift) & (divp_mask(pll))]; | ||
1032 | 1061 | ||
1033 | if (cfg.m != old_m) { | 1062 | if (cfg.m != old_cfg.m) { |
1034 | WARN_ON(1); | 1063 | WARN_ON(1); |
1035 | goto out; | 1064 | goto out; |
1036 | } | 1065 | } |
1037 | 1066 | ||
1038 | if (old_n == cfg.n && old_p == cfg.p) | 1067 | if (old_cfg.n == cfg.n && old_cfg.p == cfg.p) |
1039 | goto out; | 1068 | goto out; |
1040 | 1069 | ||
1041 | cfg.p -= 1; | ||
1042 | |||
1043 | state = clk_pll_is_enabled(hw); | 1070 | state = clk_pll_is_enabled(hw); |
1044 | if (state) | 1071 | if (state) |
1045 | _clk_pllc_disable(hw); | 1072 | _clk_pllc_disable(hw); |
@@ -1178,8 +1205,8 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) | |||
1178 | val = pll_readl_base(pll); | 1205 | val = pll_readl_base(pll); |
1179 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); | 1206 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); |
1180 | val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); | 1207 | val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); |
1181 | val |= sel.m << pll->divm_shift; | 1208 | val |= sel.m << pll->params->div_nmp->divm_shift; |
1182 | val |= sel.n << pll->divn_shift; | 1209 | val |= sel.n << pll->params->div_nmp->divn_shift; |
1183 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; | 1210 | val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; |
1184 | pll_writel_base(val, pll); | 1211 | pll_writel_base(val, pll); |
1185 | udelay(1); | 1212 | udelay(1); |
@@ -1240,12 +1267,8 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, | |||
1240 | pll->flags = pll_flags; | 1267 | pll->flags = pll_flags; |
1241 | pll->lock = lock; | 1268 | pll->lock = lock; |
1242 | 1269 | ||
1243 | pll->divp_shift = PLL_BASE_DIVP_SHIFT; | 1270 | if (!pll_params->div_nmp) |
1244 | pll->divp_width = PLL_BASE_DIVP_WIDTH; | 1271 | pll_params->div_nmp = &default_nmp; |
1245 | pll->divn_shift = PLL_BASE_DIVN_SHIFT; | ||
1246 | pll->divn_width = PLL_BASE_DIVN_WIDTH; | ||
1247 | pll->divm_shift = PLL_BASE_DIVM_SHIFT; | ||
1248 | pll->divm_width = PLL_BASE_DIVM_WIDTH; | ||
1249 | 1272 | ||
1250 | return pll; | 1273 | return pll; |
1251 | } | 1274 | } |
@@ -1401,7 +1424,7 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, | |||
1401 | struct tegra_clk_pll *pll; | 1424 | struct tegra_clk_pll *pll; |
1402 | struct clk *clk; | 1425 | struct clk *clk; |
1403 | 1426 | ||
1404 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1427 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; |
1405 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1428 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, |
1406 | freq_table, lock); | 1429 | freq_table, lock); |
1407 | if (IS_ERR(pll)) | 1430 | if (IS_ERR(pll)) |
@@ -1428,7 +1451,6 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, | |||
1428 | val &= ~BIT(29); | 1451 | val &= ~BIT(29); |
1429 | pll_writel_misc(val, pll); | 1452 | pll_writel_misc(val, pll); |
1430 | 1453 | ||
1431 | pll_flags |= TEGRA_PLL_LOCK_MISC; | ||
1432 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | 1454 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, |
1433 | &tegra_clk_pllre_ops); | 1455 | &tegra_clk_pllre_ops); |
1434 | if (IS_ERR(clk)) | 1456 | if (IS_ERR(clk)) |
@@ -1453,6 +1475,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, | |||
1453 | 1475 | ||
1454 | pll_flags |= TEGRA_PLL_BYPASS; | 1476 | pll_flags |= TEGRA_PLL_BYPASS; |
1455 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1477 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; |
1478 | pll_flags |= TEGRA_PLLM; | ||
1456 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1479 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, |
1457 | freq_table, lock); | 1480 | freq_table, lock); |
1458 | if (IS_ERR(pll)) | 1481 | if (IS_ERR(pll)) |
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 40d939d091bf..b6015cb4fc01 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/of.h> | 21 | #include <linux/of.h> |
22 | #include <linux/of_address.h> | 22 | #include <linux/of_address.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/export.h> | ||
24 | #include <linux/clk/tegra.h> | 25 | #include <linux/clk/tegra.h> |
25 | 26 | ||
26 | #include "clk.h" | 27 | #include "clk.h" |
@@ -28,6 +29,7 @@ | |||
28 | #define RST_DEVICES_L 0x004 | 29 | #define RST_DEVICES_L 0x004 |
29 | #define RST_DEVICES_H 0x008 | 30 | #define RST_DEVICES_H 0x008 |
30 | #define RST_DEVICES_U 0x00C | 31 | #define RST_DEVICES_U 0x00C |
32 | #define RST_DFLL_DVCO 0x2F4 | ||
31 | #define RST_DEVICES_V 0x358 | 33 | #define RST_DEVICES_V 0x358 |
32 | #define RST_DEVICES_W 0x35C | 34 | #define RST_DEVICES_W 0x35C |
33 | #define RST_DEVICES_X 0x28C | 35 | #define RST_DEVICES_X 0x28C |
@@ -41,8 +43,36 @@ | |||
41 | #define RST_DEVICES_CLR_V 0x434 | 43 | #define RST_DEVICES_CLR_V 0x434 |
42 | #define RST_DEVICES_SET_W 0x438 | 44 | #define RST_DEVICES_SET_W 0x438 |
43 | #define RST_DEVICES_CLR_W 0x43c | 45 | #define RST_DEVICES_CLR_W 0x43c |
46 | #define CPU_FINETRIM_SELECT 0x4d4 /* override default prop dlys */ | ||
47 | #define CPU_FINETRIM_DR 0x4d8 /* rise->rise prop dly A */ | ||
48 | #define CPU_FINETRIM_R 0x4e4 /* rise->rise prop dly inc A */ | ||
44 | #define RST_DEVICES_NUM 5 | 49 | #define RST_DEVICES_NUM 5 |
45 | 50 | ||
51 | /* RST_DFLL_DVCO bitfields */ | ||
52 | #define DVFS_DFLL_RESET_SHIFT 0 | ||
53 | |||
54 | /* CPU_FINETRIM_SELECT and CPU_FINETRIM_DR bitfields */ | ||
55 | #define CPU_FINETRIM_1_FCPU_1 BIT(0) /* fcpu0 */ | ||
56 | #define CPU_FINETRIM_1_FCPU_2 BIT(1) /* fcpu1 */ | ||
57 | #define CPU_FINETRIM_1_FCPU_3 BIT(2) /* fcpu2 */ | ||
58 | #define CPU_FINETRIM_1_FCPU_4 BIT(3) /* fcpu3 */ | ||
59 | #define CPU_FINETRIM_1_FCPU_5 BIT(4) /* fl2 */ | ||
60 | #define CPU_FINETRIM_1_FCPU_6 BIT(5) /* ftop */ | ||
61 | |||
62 | /* CPU_FINETRIM_R bitfields */ | ||
63 | #define CPU_FINETRIM_R_FCPU_1_SHIFT 0 /* fcpu0 */ | ||
64 | #define CPU_FINETRIM_R_FCPU_1_MASK (0x3 << CPU_FINETRIM_R_FCPU_1_SHIFT) | ||
65 | #define CPU_FINETRIM_R_FCPU_2_SHIFT 2 /* fcpu1 */ | ||
66 | #define CPU_FINETRIM_R_FCPU_2_MASK (0x3 << CPU_FINETRIM_R_FCPU_2_SHIFT) | ||
67 | #define CPU_FINETRIM_R_FCPU_3_SHIFT 4 /* fcpu2 */ | ||
68 | #define CPU_FINETRIM_R_FCPU_3_MASK (0x3 << CPU_FINETRIM_R_FCPU_3_SHIFT) | ||
69 | #define CPU_FINETRIM_R_FCPU_4_SHIFT 6 /* fcpu3 */ | ||
70 | #define CPU_FINETRIM_R_FCPU_4_MASK (0x3 << CPU_FINETRIM_R_FCPU_4_SHIFT) | ||
71 | #define CPU_FINETRIM_R_FCPU_5_SHIFT 8 /* fl2 */ | ||
72 | #define CPU_FINETRIM_R_FCPU_5_MASK (0x3 << CPU_FINETRIM_R_FCPU_5_SHIFT) | ||
73 | #define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */ | ||
74 | #define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT) | ||
75 | |||
46 | #define CLK_OUT_ENB_L 0x010 | 76 | #define CLK_OUT_ENB_L 0x010 |
47 | #define CLK_OUT_ENB_H 0x014 | 77 | #define CLK_OUT_ENB_H 0x014 |
48 | #define CLK_OUT_ENB_U 0x018 | 78 | #define CLK_OUT_ENB_U 0x018 |
@@ -127,6 +157,7 @@ | |||
127 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 | 157 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 |
128 | #define PMC_CTRL 0 | 158 | #define PMC_CTRL 0 |
129 | #define PMC_CTRL_BLINK_ENB 7 | 159 | #define PMC_CTRL_BLINK_ENB 7 |
160 | #define PMC_BLINK_TIMER 0x40 | ||
130 | 161 | ||
131 | #define OSC_CTRL 0x50 | 162 | #define OSC_CTRL 0x50 |
132 | #define OSC_CTRL_OSC_FREQ_SHIFT 28 | 163 | #define OSC_CTRL_OSC_FREQ_SHIFT 28 |
@@ -242,6 +273,8 @@ | |||
242 | #define CLK_SOURCE_I2CSLOW 0x3fc | 273 | #define CLK_SOURCE_I2CSLOW 0x3fc |
243 | #define CLK_SOURCE_SE 0x42c | 274 | #define CLK_SOURCE_SE 0x42c |
244 | #define CLK_SOURCE_MSELECT 0x3b4 | 275 | #define CLK_SOURCE_MSELECT 0x3b4 |
276 | #define CLK_SOURCE_DFLL_REF 0x62c | ||
277 | #define CLK_SOURCE_DFLL_SOC 0x630 | ||
245 | #define CLK_SOURCE_SOC_THERM 0x644 | 278 | #define CLK_SOURCE_SOC_THERM 0x644 |
246 | #define CLK_SOURCE_XUSB_HOST_SRC 0x600 | 279 | #define CLK_SOURCE_XUSB_HOST_SRC 0x600 |
247 | #define CLK_SOURCE_XUSB_FALCON_SRC 0x604 | 280 | #define CLK_SOURCE_XUSB_FALCON_SRC 0x604 |
@@ -250,6 +283,10 @@ | |||
250 | #define CLK_SOURCE_XUSB_DEV_SRC 0x60c | 283 | #define CLK_SOURCE_XUSB_DEV_SRC 0x60c |
251 | #define CLK_SOURCE_EMC 0x19c | 284 | #define CLK_SOURCE_EMC 0x19c |
252 | 285 | ||
286 | /* PLLM override registers */ | ||
287 | #define PMC_PLLM_WB0_OVERRIDE 0x1dc | ||
288 | #define PMC_PLLM_WB0_OVERRIDE_2 0x2b0 | ||
289 | |||
253 | /* Tegra CPU clock and reset control regs */ | 290 | /* Tegra CPU clock and reset control regs */ |
254 | #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 | 291 | #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 |
255 | 292 | ||
@@ -267,6 +304,15 @@ static DEFINE_SPINLOCK(clk_doubler_lock); | |||
267 | static DEFINE_SPINLOCK(clk_out_lock); | 304 | static DEFINE_SPINLOCK(clk_out_lock); |
268 | static DEFINE_SPINLOCK(sysrate_lock); | 305 | static DEFINE_SPINLOCK(sysrate_lock); |
269 | 306 | ||
307 | static struct div_nmp pllxc_nmp = { | ||
308 | .divm_shift = 0, | ||
309 | .divm_width = 8, | ||
310 | .divn_shift = 8, | ||
311 | .divn_width = 8, | ||
312 | .divp_shift = 20, | ||
313 | .divp_width = 4, | ||
314 | }; | ||
315 | |||
270 | static struct pdiv_map pllxc_p[] = { | 316 | static struct pdiv_map pllxc_p[] = { |
271 | { .pdiv = 1, .hw_val = 0 }, | 317 | { .pdiv = 1, .hw_val = 0 }, |
272 | { .pdiv = 2, .hw_val = 1 }, | 318 | { .pdiv = 2, .hw_val = 1 }, |
@@ -315,6 +361,16 @@ static struct tegra_clk_pll_params pll_c_params = { | |||
315 | .stepa_shift = 17, | 361 | .stepa_shift = 17, |
316 | .stepb_shift = 9, | 362 | .stepb_shift = 9, |
317 | .pdiv_tohw = pllxc_p, | 363 | .pdiv_tohw = pllxc_p, |
364 | .div_nmp = &pllxc_nmp, | ||
365 | }; | ||
366 | |||
367 | static struct div_nmp pllcx_nmp = { | ||
368 | .divm_shift = 0, | ||
369 | .divm_width = 2, | ||
370 | .divn_shift = 8, | ||
371 | .divn_width = 8, | ||
372 | .divp_shift = 20, | ||
373 | .divp_width = 3, | ||
318 | }; | 374 | }; |
319 | 375 | ||
320 | static struct pdiv_map pllc_p[] = { | 376 | static struct pdiv_map pllc_p[] = { |
@@ -348,6 +404,8 @@ static struct tegra_clk_pll_params pll_c2_params = { | |||
348 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 404 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
349 | .lock_delay = 300, | 405 | .lock_delay = 300, |
350 | .pdiv_tohw = pllc_p, | 406 | .pdiv_tohw = pllc_p, |
407 | .div_nmp = &pllcx_nmp, | ||
408 | .max_p = 7, | ||
351 | .ext_misc_reg[0] = 0x4f0, | 409 | .ext_misc_reg[0] = 0x4f0, |
352 | .ext_misc_reg[1] = 0x4f4, | 410 | .ext_misc_reg[1] = 0x4f4, |
353 | .ext_misc_reg[2] = 0x4f8, | 411 | .ext_misc_reg[2] = 0x4f8, |
@@ -366,11 +424,25 @@ static struct tegra_clk_pll_params pll_c3_params = { | |||
366 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 424 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
367 | .lock_delay = 300, | 425 | .lock_delay = 300, |
368 | .pdiv_tohw = pllc_p, | 426 | .pdiv_tohw = pllc_p, |
427 | .div_nmp = &pllcx_nmp, | ||
428 | .max_p = 7, | ||
369 | .ext_misc_reg[0] = 0x504, | 429 | .ext_misc_reg[0] = 0x504, |
370 | .ext_misc_reg[1] = 0x508, | 430 | .ext_misc_reg[1] = 0x508, |
371 | .ext_misc_reg[2] = 0x50c, | 431 | .ext_misc_reg[2] = 0x50c, |
372 | }; | 432 | }; |
373 | 433 | ||
434 | static struct div_nmp pllm_nmp = { | ||
435 | .divm_shift = 0, | ||
436 | .divm_width = 8, | ||
437 | .override_divm_shift = 0, | ||
438 | .divn_shift = 8, | ||
439 | .divn_width = 8, | ||
440 | .override_divn_shift = 8, | ||
441 | .divp_shift = 20, | ||
442 | .divp_width = 1, | ||
443 | .override_divp_shift = 27, | ||
444 | }; | ||
445 | |||
374 | static struct pdiv_map pllm_p[] = { | 446 | static struct pdiv_map pllm_p[] = { |
375 | { .pdiv = 1, .hw_val = 0 }, | 447 | { .pdiv = 1, .hw_val = 0 }, |
376 | { .pdiv = 2, .hw_val = 1 }, | 448 | { .pdiv = 2, .hw_val = 1 }, |
@@ -400,6 +472,18 @@ static struct tegra_clk_pll_params pll_m_params = { | |||
400 | .lock_delay = 300, | 472 | .lock_delay = 300, |
401 | .max_p = 2, | 473 | .max_p = 2, |
402 | .pdiv_tohw = pllm_p, | 474 | .pdiv_tohw = pllm_p, |
475 | .div_nmp = &pllm_nmp, | ||
476 | .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, | ||
477 | .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, | ||
478 | }; | ||
479 | |||
480 | static struct div_nmp pllp_nmp = { | ||
481 | .divm_shift = 0, | ||
482 | .divm_width = 5, | ||
483 | .divn_shift = 8, | ||
484 | .divn_width = 10, | ||
485 | .divp_shift = 20, | ||
486 | .divp_width = 3, | ||
403 | }; | 487 | }; |
404 | 488 | ||
405 | static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { | 489 | static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { |
@@ -423,6 +507,7 @@ static struct tegra_clk_pll_params pll_p_params = { | |||
423 | .lock_mask = PLL_BASE_LOCK, | 507 | .lock_mask = PLL_BASE_LOCK, |
424 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 508 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
425 | .lock_delay = 300, | 509 | .lock_delay = 300, |
510 | .div_nmp = &pllp_nmp, | ||
426 | }; | 511 | }; |
427 | 512 | ||
428 | static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { | 513 | static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { |
@@ -449,6 +534,7 @@ static struct tegra_clk_pll_params pll_a_params = { | |||
449 | .lock_mask = PLL_BASE_LOCK, | 534 | .lock_mask = PLL_BASE_LOCK, |
450 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 535 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
451 | .lock_delay = 300, | 536 | .lock_delay = 300, |
537 | .div_nmp = &pllp_nmp, | ||
452 | }; | 538 | }; |
453 | 539 | ||
454 | static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { | 540 | static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { |
@@ -484,6 +570,7 @@ static struct tegra_clk_pll_params pll_d_params = { | |||
484 | .lock_mask = PLL_BASE_LOCK, | 570 | .lock_mask = PLL_BASE_LOCK, |
485 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 571 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
486 | .lock_delay = 1000, | 572 | .lock_delay = 1000, |
573 | .div_nmp = &pllp_nmp, | ||
487 | }; | 574 | }; |
488 | 575 | ||
489 | static struct tegra_clk_pll_params pll_d2_params = { | 576 | static struct tegra_clk_pll_params pll_d2_params = { |
@@ -498,6 +585,7 @@ static struct tegra_clk_pll_params pll_d2_params = { | |||
498 | .lock_mask = PLL_BASE_LOCK, | 585 | .lock_mask = PLL_BASE_LOCK, |
499 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 586 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
500 | .lock_delay = 1000, | 587 | .lock_delay = 1000, |
588 | .div_nmp = &pllp_nmp, | ||
501 | }; | 589 | }; |
502 | 590 | ||
503 | static struct pdiv_map pllu_p[] = { | 591 | static struct pdiv_map pllu_p[] = { |
@@ -506,6 +594,15 @@ static struct pdiv_map pllu_p[] = { | |||
506 | { .pdiv = 0, .hw_val = 0 }, | 594 | { .pdiv = 0, .hw_val = 0 }, |
507 | }; | 595 | }; |
508 | 596 | ||
597 | static struct div_nmp pllu_nmp = { | ||
598 | .divm_shift = 0, | ||
599 | .divm_width = 5, | ||
600 | .divn_shift = 8, | ||
601 | .divn_width = 10, | ||
602 | .divp_shift = 20, | ||
603 | .divp_width = 1, | ||
604 | }; | ||
605 | |||
509 | static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { | 606 | static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { |
510 | {12000000, 480000000, 960, 12, 0, 12}, | 607 | {12000000, 480000000, 960, 12, 0, 12}, |
511 | {13000000, 480000000, 960, 13, 0, 12}, | 608 | {13000000, 480000000, 960, 13, 0, 12}, |
@@ -528,6 +625,7 @@ static struct tegra_clk_pll_params pll_u_params = { | |||
528 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 625 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
529 | .lock_delay = 1000, | 626 | .lock_delay = 1000, |
530 | .pdiv_tohw = pllu_p, | 627 | .pdiv_tohw = pllu_p, |
628 | .div_nmp = &pllu_nmp, | ||
531 | }; | 629 | }; |
532 | 630 | ||
533 | static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { | 631 | static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { |
@@ -560,6 +658,7 @@ static struct tegra_clk_pll_params pll_x_params = { | |||
560 | .stepa_shift = 16, | 658 | .stepa_shift = 16, |
561 | .stepb_shift = 24, | 659 | .stepb_shift = 24, |
562 | .pdiv_tohw = pllxc_p, | 660 | .pdiv_tohw = pllxc_p, |
661 | .div_nmp = &pllxc_nmp, | ||
563 | }; | 662 | }; |
564 | 663 | ||
565 | static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { | 664 | static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { |
@@ -569,6 +668,15 @@ static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { | |||
569 | {0, 0, 0, 0, 0, 0}, | 668 | {0, 0, 0, 0, 0, 0}, |
570 | }; | 669 | }; |
571 | 670 | ||
671 | static struct div_nmp plle_nmp = { | ||
672 | .divm_shift = 0, | ||
673 | .divm_width = 8, | ||
674 | .divn_shift = 8, | ||
675 | .divn_width = 8, | ||
676 | .divp_shift = 24, | ||
677 | .divp_width = 4, | ||
678 | }; | ||
679 | |||
572 | static struct tegra_clk_pll_params pll_e_params = { | 680 | static struct tegra_clk_pll_params pll_e_params = { |
573 | .input_min = 12000000, | 681 | .input_min = 12000000, |
574 | .input_max = 1000000000, | 682 | .input_max = 1000000000, |
@@ -582,6 +690,16 @@ static struct tegra_clk_pll_params pll_e_params = { | |||
582 | .lock_mask = PLLE_MISC_LOCK, | 690 | .lock_mask = PLLE_MISC_LOCK, |
583 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, | 691 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, |
584 | .lock_delay = 300, | 692 | .lock_delay = 300, |
693 | .div_nmp = &plle_nmp, | ||
694 | }; | ||
695 | |||
696 | static struct div_nmp pllre_nmp = { | ||
697 | .divm_shift = 0, | ||
698 | .divm_width = 8, | ||
699 | .divn_shift = 8, | ||
700 | .divn_width = 8, | ||
701 | .divp_shift = 16, | ||
702 | .divp_width = 4, | ||
585 | }; | 703 | }; |
586 | 704 | ||
587 | static struct tegra_clk_pll_params pll_re_vco_params = { | 705 | static struct tegra_clk_pll_params pll_re_vco_params = { |
@@ -598,6 +716,7 @@ static struct tegra_clk_pll_params pll_re_vco_params = { | |||
598 | .lock_delay = 300, | 716 | .lock_delay = 300, |
599 | .iddq_reg = PLLRE_MISC, | 717 | .iddq_reg = PLLRE_MISC, |
600 | .iddq_bit_idx = PLLRE_IDDQ_BIT, | 718 | .iddq_bit_idx = PLLRE_IDDQ_BIT, |
719 | .div_nmp = &pllre_nmp, | ||
601 | }; | 720 | }; |
602 | 721 | ||
603 | /* Peripheral clock registers */ | 722 | /* Peripheral clock registers */ |
@@ -765,6 +884,7 @@ enum tegra114_clk { | |||
765 | audio1, audio2, audio3, audio4, spdif, clk_out_1, clk_out_2, clk_out_3, | 884 | audio1, audio2, audio3, audio4, spdif, clk_out_1, clk_out_2, clk_out_3, |
766 | blink, xusb_host_src = 252, xusb_falcon_src, xusb_fs_src, xusb_ss_src, | 885 | blink, xusb_host_src = 252, xusb_falcon_src, xusb_fs_src, xusb_ss_src, |
767 | xusb_dev_src, xusb_dev, xusb_hs_src, sclk, hclk, pclk, cclk_g, cclk_lp, | 886 | xusb_dev_src, xusb_dev, xusb_hs_src, sclk, hclk, pclk, cclk_g, cclk_lp, |
887 | dfll_ref = 264, dfll_soc, | ||
768 | 888 | ||
769 | /* Mux clocks */ | 889 | /* Mux clocks */ |
770 | 890 | ||
@@ -1202,8 +1322,8 @@ static void __init tegra114_pll_init(void __iomem *clk_base, | |||
1202 | /* PLLP_OUT2 */ | 1322 | /* PLLP_OUT2 */ |
1203 | clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", | 1323 | clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", |
1204 | clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | | 1324 | clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | |
1205 | TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, | 1325 | TEGRA_DIVIDER_ROUND_UP | TEGRA_DIVIDER_INT, 24, |
1206 | &pll_div_lock); | 1326 | 8, 1, &pll_div_lock); |
1207 | clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", | 1327 | clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", |
1208 | clk_base + PLLP_OUTA, 17, 16, | 1328 | clk_base + PLLP_OUTA, 17, 16, |
1209 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | 1329 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, |
@@ -1605,7 +1725,7 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) | |||
1605 | 1725 | ||
1606 | /* clk_out_2 */ | 1726 | /* clk_out_2 */ |
1607 | clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, | 1727 | clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, |
1608 | ARRAY_SIZE(clk_out1_parents), 0, | 1728 | ARRAY_SIZE(clk_out2_parents), 0, |
1609 | pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, | 1729 | pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, |
1610 | &clk_out_lock); | 1730 | &clk_out_lock); |
1611 | clks[clk_out_2_mux] = clk; | 1731 | clks[clk_out_2_mux] = clk; |
@@ -1617,7 +1737,7 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) | |||
1617 | 1737 | ||
1618 | /* clk_out_3 */ | 1738 | /* clk_out_3 */ |
1619 | clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, | 1739 | clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, |
1620 | ARRAY_SIZE(clk_out1_parents), 0, | 1740 | ARRAY_SIZE(clk_out3_parents), 0, |
1621 | pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, | 1741 | pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, |
1622 | &clk_out_lock); | 1742 | &clk_out_lock); |
1623 | clks[clk_out_3_mux] = clk; | 1743 | clks[clk_out_3_mux] = clk; |
@@ -1628,6 +1748,8 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) | |||
1628 | clks[clk_out_3] = clk; | 1748 | clks[clk_out_3] = clk; |
1629 | 1749 | ||
1630 | /* blink */ | 1750 | /* blink */ |
1751 | /* clear the blink timer register to directly output clk_32k */ | ||
1752 | writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); | ||
1631 | clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, | 1753 | clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, |
1632 | pmc_base + PMC_DPD_PADS_ORIDE, | 1754 | pmc_base + PMC_DPD_PADS_ORIDE, |
1633 | PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); | 1755 | PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); |
@@ -1640,7 +1762,7 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) | |||
1640 | } | 1762 | } |
1641 | 1763 | ||
1642 | static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", | 1764 | static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", |
1643 | "pll_p_out3", "pll_p_out2", "unused", | 1765 | "pll_p", "pll_p_out2", "unused", |
1644 | "clk_32k", "pll_m_out1" }; | 1766 | "clk_32k", "pll_m_out1" }; |
1645 | 1767 | ||
1646 | static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | 1768 | static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", |
@@ -1750,7 +1872,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { | |||
1750 | TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), | 1872 | TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), |
1751 | TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), | 1873 | TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), |
1752 | TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), | 1874 | TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), |
1753 | TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_h_regs, TEGRA_PERIPH_WAR_1005168, msenc), | 1875 | TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_u_regs, TEGRA_PERIPH_WAR_1005168, msenc), |
1754 | TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, tsec), | 1876 | TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, tsec), |
1755 | TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), | 1877 | TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), |
1756 | TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), | 1878 | TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), |
@@ -1767,6 +1889,8 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { | |||
1767 | TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), | 1889 | TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), |
1768 | TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, se), | 1890 | TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, se), |
1769 | TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect, CLK_IGNORE_UNUSED), | 1891 | TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect, CLK_IGNORE_UNUSED), |
1892 | TEGRA_INIT_DATA_MUX("dfll_ref", "ref", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, dfll_ref), | ||
1893 | TEGRA_INIT_DATA_MUX("dfll_soc", "soc", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, dfll_soc), | ||
1770 | TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, soc_therm), | 1894 | TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, soc_therm), |
1771 | TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_host_src), | 1895 | TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_host_src), |
1772 | TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_falcon_src), | 1896 | TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_falcon_src), |
@@ -2028,6 +2152,10 @@ static const struct of_device_id pmc_match[] __initconst = { | |||
2028 | {}, | 2152 | {}, |
2029 | }; | 2153 | }; |
2030 | 2154 | ||
2155 | /* | ||
2156 | * dfll_soc/dfll_ref apparently must be kept enabled, otherwise I2C5 | ||
2157 | * breaks | ||
2158 | */ | ||
2031 | static __initdata struct tegra_clk_init_table init_table[] = { | 2159 | static __initdata struct tegra_clk_init_table init_table[] = { |
2032 | {uarta, pll_p, 408000000, 0}, | 2160 | {uarta, pll_p, 408000000, 0}, |
2033 | {uartb, pll_p, 408000000, 0}, | 2161 | {uartb, pll_p, 408000000, 0}, |
@@ -2043,6 +2171,8 @@ static __initdata struct tegra_clk_init_table init_table[] = { | |||
2043 | {i2s2, pll_a_out0, 11289600, 0}, | 2171 | {i2s2, pll_a_out0, 11289600, 0}, |
2044 | {i2s3, pll_a_out0, 11289600, 0}, | 2172 | {i2s3, pll_a_out0, 11289600, 0}, |
2045 | {i2s4, pll_a_out0, 11289600, 0}, | 2173 | {i2s4, pll_a_out0, 11289600, 0}, |
2174 | {dfll_soc, pll_p, 51000000, 1}, | ||
2175 | {dfll_ref, pll_p, 51000000, 1}, | ||
2046 | {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ | 2176 | {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ |
2047 | }; | 2177 | }; |
2048 | 2178 | ||
@@ -2051,7 +2181,132 @@ static void __init tegra114_clock_apply_init_table(void) | |||
2051 | tegra_init_from_table(init_table, clks, clk_max); | 2181 | tegra_init_from_table(init_table, clks, clk_max); |
2052 | } | 2182 | } |
2053 | 2183 | ||
2054 | void __init tegra114_clock_init(struct device_node *np) | 2184 | |
2185 | /** | ||
2186 | * tegra114_car_barrier - wait for pending writes to the CAR to complete | ||
2187 | * | ||
2188 | * Wait for any outstanding writes to the CAR MMIO space from this CPU | ||
2189 | * to complete before continuing execution. No return value. | ||
2190 | */ | ||
2191 | static void tegra114_car_barrier(void) | ||
2192 | { | ||
2193 | wmb(); /* probably unnecessary */ | ||
2194 | readl_relaxed(clk_base + CPU_FINETRIM_SELECT); | ||
2195 | } | ||
2196 | |||
2197 | /** | ||
2198 | * tegra114_clock_tune_cpu_trimmers_high - use high-voltage propagation delays | ||
2199 | * | ||
2200 | * When the CPU rail voltage is in the high-voltage range, use the | ||
2201 | * built-in hardwired clock propagation delays in the CPU clock | ||
2202 | * shaper. No return value. | ||
2203 | */ | ||
2204 | void tegra114_clock_tune_cpu_trimmers_high(void) | ||
2205 | { | ||
2206 | u32 select = 0; | ||
2207 | |||
2208 | /* Use hardwired rise->rise & fall->fall clock propagation delays */ | ||
2209 | select |= ~(CPU_FINETRIM_1_FCPU_1 | CPU_FINETRIM_1_FCPU_2 | | ||
2210 | CPU_FINETRIM_1_FCPU_3 | CPU_FINETRIM_1_FCPU_4 | | ||
2211 | CPU_FINETRIM_1_FCPU_5 | CPU_FINETRIM_1_FCPU_6); | ||
2212 | writel_relaxed(select, clk_base + CPU_FINETRIM_SELECT); | ||
2213 | |||
2214 | tegra114_car_barrier(); | ||
2215 | } | ||
2216 | EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_high); | ||
2217 | |||
2218 | /** | ||
2219 | * tegra114_clock_tune_cpu_trimmers_low - use low-voltage propagation delays | ||
2220 | * | ||
2221 | * When the CPU rail voltage is in the low-voltage range, use the | ||
2222 | * extended clock propagation delays set by | ||
2223 | * tegra114_clock_tune_cpu_trimmers_init(). The intention is to | ||
2224 | * maintain the input clock duty cycle that the FCPU subsystem | ||
2225 | * expects. No return value. | ||
2226 | */ | ||
2227 | void tegra114_clock_tune_cpu_trimmers_low(void) | ||
2228 | { | ||
2229 | u32 select = 0; | ||
2230 | |||
2231 | /* | ||
2232 | * Use software-specified rise->rise & fall->fall clock | ||
2233 | * propagation delays (from | ||
2234 | * tegra114_clock_tune_cpu_trimmers_init() | ||
2235 | */ | ||
2236 | select |= (CPU_FINETRIM_1_FCPU_1 | CPU_FINETRIM_1_FCPU_2 | | ||
2237 | CPU_FINETRIM_1_FCPU_3 | CPU_FINETRIM_1_FCPU_4 | | ||
2238 | CPU_FINETRIM_1_FCPU_5 | CPU_FINETRIM_1_FCPU_6); | ||
2239 | writel_relaxed(select, clk_base + CPU_FINETRIM_SELECT); | ||
2240 | |||
2241 | tegra114_car_barrier(); | ||
2242 | } | ||
2243 | EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_low); | ||
2244 | |||
2245 | /** | ||
2246 | * tegra114_clock_tune_cpu_trimmers_init - set up and enable clk prop delays | ||
2247 | * | ||
2248 | * Program extended clock propagation delays into the FCPU clock | ||
2249 | * shaper and enable them. XXX Define the purpose - peak current | ||
2250 | * reduction? No return value. | ||
2251 | */ | ||
2252 | /* XXX Initial voltage rail state assumption issues? */ | ||
2253 | void tegra114_clock_tune_cpu_trimmers_init(void) | ||
2254 | { | ||
2255 | u32 dr = 0, r = 0; | ||
2256 | |||
2257 | /* Increment the rise->rise clock delay by four steps */ | ||
2258 | r |= (CPU_FINETRIM_R_FCPU_1_MASK | CPU_FINETRIM_R_FCPU_2_MASK | | ||
2259 | CPU_FINETRIM_R_FCPU_3_MASK | CPU_FINETRIM_R_FCPU_4_MASK | | ||
2260 | CPU_FINETRIM_R_FCPU_5_MASK | CPU_FINETRIM_R_FCPU_6_MASK); | ||
2261 | writel_relaxed(r, clk_base + CPU_FINETRIM_R); | ||
2262 | |||
2263 | /* | ||
2264 | * Use the rise->rise clock propagation delay specified in the | ||
2265 | * r field | ||
2266 | */ | ||
2267 | dr |= (CPU_FINETRIM_1_FCPU_1 | CPU_FINETRIM_1_FCPU_2 | | ||
2268 | CPU_FINETRIM_1_FCPU_3 | CPU_FINETRIM_1_FCPU_4 | | ||
2269 | CPU_FINETRIM_1_FCPU_5 | CPU_FINETRIM_1_FCPU_6); | ||
2270 | writel_relaxed(dr, clk_base + CPU_FINETRIM_DR); | ||
2271 | |||
2272 | tegra114_clock_tune_cpu_trimmers_low(); | ||
2273 | } | ||
2274 | EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_init); | ||
2275 | |||
2276 | /** | ||
2277 | * tegra114_clock_assert_dfll_dvco_reset - assert the DFLL's DVCO reset | ||
2278 | * | ||
2279 | * Assert the reset line of the DFLL's DVCO. No return value. | ||
2280 | */ | ||
2281 | void tegra114_clock_assert_dfll_dvco_reset(void) | ||
2282 | { | ||
2283 | u32 v; | ||
2284 | |||
2285 | v = readl_relaxed(clk_base + RST_DFLL_DVCO); | ||
2286 | v |= (1 << DVFS_DFLL_RESET_SHIFT); | ||
2287 | writel_relaxed(v, clk_base + RST_DFLL_DVCO); | ||
2288 | tegra114_car_barrier(); | ||
2289 | } | ||
2290 | EXPORT_SYMBOL(tegra114_clock_assert_dfll_dvco_reset); | ||
2291 | |||
2292 | /** | ||
2293 | * tegra114_clock_deassert_dfll_dvco_reset - deassert the DFLL's DVCO reset | ||
2294 | * | ||
2295 | * Deassert the reset line of the DFLL's DVCO, allowing the DVCO to | ||
2296 | * operate. No return value. | ||
2297 | */ | ||
2298 | void tegra114_clock_deassert_dfll_dvco_reset(void) | ||
2299 | { | ||
2300 | u32 v; | ||
2301 | |||
2302 | v = readl_relaxed(clk_base + RST_DFLL_DVCO); | ||
2303 | v &= ~(1 << DVFS_DFLL_RESET_SHIFT); | ||
2304 | writel_relaxed(v, clk_base + RST_DFLL_DVCO); | ||
2305 | tegra114_car_barrier(); | ||
2306 | } | ||
2307 | EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset); | ||
2308 | |||
2309 | static void __init tegra114_clock_init(struct device_node *np) | ||
2055 | { | 2310 | { |
2056 | struct device_node *node; | 2311 | struct device_node *node; |
2057 | int i; | 2312 | int i; |
@@ -2104,3 +2359,4 @@ void __init tegra114_clock_init(struct device_node *np) | |||
2104 | 2359 | ||
2105 | tegra_cpu_car_ops = &tegra114_cpu_car_ops; | 2360 | tegra_cpu_car_ops = &tegra114_cpu_car_ops; |
2106 | } | 2361 | } |
2362 | CLK_OF_DECLARE(tegra114, "nvidia,tegra114-car", tegra114_clock_init); | ||
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 075db0c99edb..759ca47be753 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c | |||
@@ -1287,7 +1287,7 @@ static const struct of_device_id pmc_match[] __initconst = { | |||
1287 | {}, | 1287 | {}, |
1288 | }; | 1288 | }; |
1289 | 1289 | ||
1290 | void __init tegra20_clock_init(struct device_node *np) | 1290 | static void __init tegra20_clock_init(struct device_node *np) |
1291 | { | 1291 | { |
1292 | int i; | 1292 | int i; |
1293 | struct device_node *node; | 1293 | struct device_node *node; |
@@ -1339,3 +1339,4 @@ void __init tegra20_clock_init(struct device_node *np) | |||
1339 | 1339 | ||
1340 | tegra_cpu_car_ops = &tegra20_cpu_car_ops; | 1340 | tegra_cpu_car_ops = &tegra20_cpu_car_ops; |
1341 | } | 1341 | } |
1342 | CLK_OF_DECLARE(tegra20, "nvidia,tegra20-car", tegra20_clock_init); | ||
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index ba99e3844106..e2c6ca0431d6 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c | |||
@@ -252,6 +252,9 @@ | |||
252 | #define CLK_RESET_CCLK_RUN_POLICY 2 | 252 | #define CLK_RESET_CCLK_RUN_POLICY 2 |
253 | #define CLK_RESET_CCLK_BURST_POLICY_PLLX 8 | 253 | #define CLK_RESET_CCLK_BURST_POLICY_PLLX 8 |
254 | 254 | ||
255 | /* PLLM override registers */ | ||
256 | #define PMC_PLLM_WB0_OVERRIDE 0x1dc | ||
257 | |||
255 | #ifdef CONFIG_PM_SLEEP | 258 | #ifdef CONFIG_PM_SLEEP |
256 | static struct cpu_clk_suspend_context { | 259 | static struct cpu_clk_suspend_context { |
257 | u32 pllx_misc; | 260 | u32 pllx_misc; |
@@ -563,6 +566,18 @@ static struct tegra_clk_pll_params pll_c_params = { | |||
563 | .lock_delay = 300, | 566 | .lock_delay = 300, |
564 | }; | 567 | }; |
565 | 568 | ||
569 | static struct div_nmp pllm_nmp = { | ||
570 | .divn_shift = 8, | ||
571 | .divn_width = 10, | ||
572 | .override_divn_shift = 5, | ||
573 | .divm_shift = 0, | ||
574 | .divm_width = 5, | ||
575 | .override_divm_shift = 0, | ||
576 | .divp_shift = 20, | ||
577 | .divp_width = 3, | ||
578 | .override_divp_shift = 15, | ||
579 | }; | ||
580 | |||
566 | static struct tegra_clk_pll_params pll_m_params = { | 581 | static struct tegra_clk_pll_params pll_m_params = { |
567 | .input_min = 2000000, | 582 | .input_min = 2000000, |
568 | .input_max = 31000000, | 583 | .input_max = 31000000, |
@@ -575,6 +590,9 @@ static struct tegra_clk_pll_params pll_m_params = { | |||
575 | .lock_mask = PLL_BASE_LOCK, | 590 | .lock_mask = PLL_BASE_LOCK, |
576 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 591 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
577 | .lock_delay = 300, | 592 | .lock_delay = 300, |
593 | .div_nmp = &pllm_nmp, | ||
594 | .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, | ||
595 | .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE, | ||
578 | }; | 596 | }; |
579 | 597 | ||
580 | static struct tegra_clk_pll_params pll_p_params = { | 598 | static struct tegra_clk_pll_params pll_p_params = { |
@@ -1223,7 +1241,7 @@ static void __init tegra30_pmc_clk_init(void) | |||
1223 | 1241 | ||
1224 | /* clk_out_2 */ | 1242 | /* clk_out_2 */ |
1225 | clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, | 1243 | clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, |
1226 | ARRAY_SIZE(clk_out1_parents), 0, | 1244 | ARRAY_SIZE(clk_out2_parents), 0, |
1227 | pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, | 1245 | pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, |
1228 | &clk_out_lock); | 1246 | &clk_out_lock); |
1229 | clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, | 1247 | clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, |
@@ -1234,7 +1252,7 @@ static void __init tegra30_pmc_clk_init(void) | |||
1234 | 1252 | ||
1235 | /* clk_out_3 */ | 1253 | /* clk_out_3 */ |
1236 | clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, | 1254 | clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, |
1237 | ARRAY_SIZE(clk_out1_parents), 0, | 1255 | ARRAY_SIZE(clk_out3_parents), 0, |
1238 | pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, | 1256 | pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, |
1239 | &clk_out_lock); | 1257 | &clk_out_lock); |
1240 | clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, | 1258 | clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, |
@@ -1954,7 +1972,7 @@ static const struct of_device_id pmc_match[] __initconst = { | |||
1954 | {}, | 1972 | {}, |
1955 | }; | 1973 | }; |
1956 | 1974 | ||
1957 | void __init tegra30_clock_init(struct device_node *np) | 1975 | static void __init tegra30_clock_init(struct device_node *np) |
1958 | { | 1976 | { |
1959 | struct device_node *node; | 1977 | struct device_node *node; |
1960 | int i; | 1978 | int i; |
@@ -2005,3 +2023,4 @@ void __init tegra30_clock_init(struct device_node *np) | |||
2005 | 2023 | ||
2006 | tegra_cpu_car_ops = &tegra30_cpu_car_ops; | 2024 | tegra_cpu_car_ops = &tegra30_cpu_car_ops; |
2007 | } | 2025 | } |
2026 | CLK_OF_DECLARE(tegra30, "nvidia,tegra30-car", tegra30_clock_init); | ||
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 923ca7ee4694..86581ac1fd69 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c | |||
@@ -74,18 +74,6 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | static const struct of_device_id tegra_dt_clk_match[] = { | ||
78 | { .compatible = "nvidia,tegra20-car", .data = tegra20_clock_init }, | ||
79 | { .compatible = "nvidia,tegra30-car", .data = tegra30_clock_init }, | ||
80 | { .compatible = "nvidia,tegra114-car", .data = tegra114_clock_init }, | ||
81 | { } | ||
82 | }; | ||
83 | |||
84 | void __init tegra_clocks_init(void) | ||
85 | { | ||
86 | of_clk_init(tegra_dt_clk_match); | ||
87 | } | ||
88 | |||
89 | tegra_clk_apply_init_table_func tegra_clk_apply_init_table; | 77 | tegra_clk_apply_init_table_func tegra_clk_apply_init_table; |
90 | 78 | ||
91 | void __init tegra_clocks_apply_init_table(void) | 79 | void __init tegra_clocks_apply_init_table(void) |
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index e0565620d68e..07cfacd91686 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h | |||
@@ -128,6 +128,31 @@ struct pdiv_map { | |||
128 | }; | 128 | }; |
129 | 129 | ||
130 | /** | 130 | /** |
131 | * struct div_nmp - offset and width of m,n and p fields | ||
132 | * | ||
133 | * @divn_shift: shift to the feedback divider bit field | ||
134 | * @divn_width: width of the feedback divider bit field | ||
135 | * @divm_shift: shift to the input divider bit field | ||
136 | * @divm_width: width of the input divider bit field | ||
137 | * @divp_shift: shift to the post divider bit field | ||
138 | * @divp_width: width of the post divider bit field | ||
139 | * @override_divn_shift: shift to the feedback divider bitfield in override reg | ||
140 | * @override_divm_shift: shift to the input divider bitfield in override reg | ||
141 | * @override_divp_shift: shift to the post divider bitfield in override reg | ||
142 | */ | ||
143 | struct div_nmp { | ||
144 | u8 divn_shift; | ||
145 | u8 divn_width; | ||
146 | u8 divm_shift; | ||
147 | u8 divm_width; | ||
148 | u8 divp_shift; | ||
149 | u8 divp_width; | ||
150 | u8 override_divn_shift; | ||
151 | u8 override_divm_shift; | ||
152 | u8 override_divp_shift; | ||
153 | }; | ||
154 | |||
155 | /** | ||
131 | * struct clk_pll_params - PLL parameters | 156 | * struct clk_pll_params - PLL parameters |
132 | * | 157 | * |
133 | * @input_min: Minimum input frequency | 158 | * @input_min: Minimum input frequency |
@@ -161,11 +186,14 @@ struct tegra_clk_pll_params { | |||
161 | u32 aux_reg; | 186 | u32 aux_reg; |
162 | u32 dyn_ramp_reg; | 187 | u32 dyn_ramp_reg; |
163 | u32 ext_misc_reg[3]; | 188 | u32 ext_misc_reg[3]; |
189 | u32 pmc_divnm_reg; | ||
190 | u32 pmc_divp_reg; | ||
164 | int stepa_shift; | 191 | int stepa_shift; |
165 | int stepb_shift; | 192 | int stepb_shift; |
166 | int lock_delay; | 193 | int lock_delay; |
167 | int max_p; | 194 | int max_p; |
168 | struct pdiv_map *pdiv_tohw; | 195 | struct pdiv_map *pdiv_tohw; |
196 | struct div_nmp *div_nmp; | ||
169 | }; | 197 | }; |
170 | 198 | ||
171 | /** | 199 | /** |
@@ -179,12 +207,6 @@ struct tegra_clk_pll_params { | |||
179 | * @flags: PLL flags | 207 | * @flags: PLL flags |
180 | * @fixed_rate: PLL rate if it is fixed | 208 | * @fixed_rate: PLL rate if it is fixed |
181 | * @lock: register lock | 209 | * @lock: register lock |
182 | * @divn_shift: shift to the feedback divider bit field | ||
183 | * @divn_width: width of the feedback divider bit field | ||
184 | * @divm_shift: shift to the input divider bit field | ||
185 | * @divm_width: width of the input divider bit field | ||
186 | * @divp_shift: shift to the post divider bit field | ||
187 | * @divp_width: width of the post divider bit field | ||
188 | * | 210 | * |
189 | * Flags: | 211 | * Flags: |
190 | * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for | 212 | * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for |
@@ -214,12 +236,6 @@ struct tegra_clk_pll { | |||
214 | u32 flags; | 236 | u32 flags; |
215 | unsigned long fixed_rate; | 237 | unsigned long fixed_rate; |
216 | spinlock_t *lock; | 238 | spinlock_t *lock; |
217 | u8 divn_shift; | ||
218 | u8 divn_width; | ||
219 | u8 divm_shift; | ||
220 | u8 divm_width; | ||
221 | u8 divp_shift; | ||
222 | u8 divp_width; | ||
223 | struct tegra_clk_pll_freq_table *freq_table; | 239 | struct tegra_clk_pll_freq_table *freq_table; |
224 | struct tegra_clk_pll_params *params; | 240 | struct tegra_clk_pll_params *params; |
225 | }; | 241 | }; |
@@ -571,23 +587,11 @@ void tegra_init_from_table(struct tegra_clk_init_table *tbl, | |||
571 | void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, | 587 | void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, |
572 | struct clk *clks[], int clk_max); | 588 | struct clk *clks[], int clk_max); |
573 | 589 | ||
574 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | 590 | void tegra114_clock_tune_cpu_trimmers_high(void); |
575 | void tegra20_clock_init(struct device_node *np); | 591 | void tegra114_clock_tune_cpu_trimmers_low(void); |
576 | #else | 592 | void tegra114_clock_tune_cpu_trimmers_init(void); |
577 | static inline void tegra20_clock_init(struct device_node *np) {} | 593 | void tegra114_clock_assert_dfll_dvco_reset(void); |
578 | #endif /* CONFIG_ARCH_TEGRA_2x_SOC */ | 594 | void tegra114_clock_deassert_dfll_dvco_reset(void); |
579 | |||
580 | #ifdef CONFIG_ARCH_TEGRA_3x_SOC | ||
581 | void tegra30_clock_init(struct device_node *np); | ||
582 | #else | ||
583 | static inline void tegra30_clock_init(struct device_node *np) {} | ||
584 | #endif /* CONFIG_ARCH_TEGRA_3x_SOC */ | ||
585 | |||
586 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | ||
587 | void tegra114_clock_init(struct device_node *np); | ||
588 | #else | ||
589 | static inline void tegra114_clock_init(struct device_node *np) {} | ||
590 | #endif /* CONFIG_ARCH_TEGRA114_SOC */ | ||
591 | 595 | ||
592 | typedef void (*tegra_clk_apply_init_table_func)(void); | 596 | typedef void (*tegra_clk_apply_init_table_func)(void); |
593 | extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; | 597 | extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; |
diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c index a0fca004abc1..e7bd62cf60b3 100644 --- a/drivers/clk/ux500/abx500-clk.c +++ b/drivers/clk/ux500/abx500-clk.c | |||
@@ -45,7 +45,7 @@ static int ab8500_reg_clks(struct device *dev) | |||
45 | CLK_IS_ROOT); | 45 | CLK_IS_ROOT); |
46 | clk_register_clkdev(clk, "sysclk", "ab8500-usb.0"); | 46 | clk_register_clkdev(clk, "sysclk", "ab8500-usb.0"); |
47 | clk_register_clkdev(clk, "sysclk", "ab-iddet.0"); | 47 | clk_register_clkdev(clk, "sysclk", "ab-iddet.0"); |
48 | clk_register_clkdev(clk, "sysclk", "ab85xx-codec.0"); | 48 | clk_register_clkdev(clk, "sysclk", "snd-soc-mop500.0"); |
49 | clk_register_clkdev(clk, "sysclk", "shrm_bus"); | 49 | clk_register_clkdev(clk, "sysclk", "shrm_bus"); |
50 | 50 | ||
51 | /* ab8500_sysclk2 */ | 51 | /* ab8500_sysclk2 */ |
@@ -70,19 +70,19 @@ static int ab8500_reg_clks(struct device *dev) | |||
70 | AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, | 70 | AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, |
71 | AB8500_SYSULPCLKCTRL1_ULPCLKREQ, | 71 | AB8500_SYSULPCLKCTRL1_ULPCLKREQ, |
72 | 38400000, 9000, CLK_IS_ROOT); | 72 | 38400000, 9000, CLK_IS_ROOT); |
73 | clk_register_clkdev(clk, "ulpclk", "ab85xx-codec.0"); | 73 | clk_register_clkdev(clk, "ulpclk", "snd-soc-mop500.0"); |
74 | 74 | ||
75 | /* ab8500_intclk */ | 75 | /* ab8500_intclk */ |
76 | clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2, | 76 | clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2, |
77 | intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0); | 77 | intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0); |
78 | clk_register_clkdev(clk, "intclk", "ab85xx-codec.0"); | 78 | clk_register_clkdev(clk, "intclk", "snd-soc-mop500.0"); |
79 | clk_register_clkdev(clk, NULL, "ab8500-pwm.1"); | 79 | clk_register_clkdev(clk, NULL, "ab8500-pwm.1"); |
80 | 80 | ||
81 | /* ab8500_audioclk */ | 81 | /* ab8500_audioclk */ |
82 | clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk", | 82 | clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk", |
83 | AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, | 83 | AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, |
84 | AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0); | 84 | AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0); |
85 | clk_register_clkdev(clk, "audioclk", "ab85xx-codec.0"); | 85 | clk_register_clkdev(clk, "audioclk", "ab8500-codec.0"); |
86 | 86 | ||
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
diff --git a/drivers/clk/ux500/u8540_clk.c b/drivers/clk/ux500/u8540_clk.c index 10adfd2ead21..f26258869deb 100644 --- a/drivers/clk/ux500/u8540_clk.c +++ b/drivers/clk/ux500/u8540_clk.c | |||
@@ -12,10 +12,568 @@ | |||
12 | #include <linux/clk-provider.h> | 12 | #include <linux/clk-provider.h> |
13 | #include <linux/mfd/dbx500-prcmu.h> | 13 | #include <linux/mfd/dbx500-prcmu.h> |
14 | #include <linux/platform_data/clk-ux500.h> | 14 | #include <linux/platform_data/clk-ux500.h> |
15 | |||
16 | #include "clk.h" | 15 | #include "clk.h" |
17 | 16 | ||
18 | void u8540_clk_init(void) | 17 | void u8540_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base, |
18 | u32 clkrst5_base, u32 clkrst6_base) | ||
19 | { | 19 | { |
20 | /* register clocks here */ | 20 | struct clk *clk; |
21 | |||
22 | /* Clock sources. */ | ||
23 | /* Fixed ClockGen */ | ||
24 | clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0, | ||
25 | CLK_IS_ROOT|CLK_IGNORE_UNUSED); | ||
26 | clk_register_clkdev(clk, "soc0_pll", NULL); | ||
27 | |||
28 | clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1, | ||
29 | CLK_IS_ROOT|CLK_IGNORE_UNUSED); | ||
30 | clk_register_clkdev(clk, "soc1_pll", NULL); | ||
31 | |||
32 | clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR, | ||
33 | CLK_IS_ROOT|CLK_IGNORE_UNUSED); | ||
34 | clk_register_clkdev(clk, "ddr_pll", NULL); | ||
35 | |||
36 | clk = clk_register_fixed_rate(NULL, "rtc32k", NULL, | ||
37 | CLK_IS_ROOT|CLK_IGNORE_UNUSED, | ||
38 | 32768); | ||
39 | clk_register_clkdev(clk, "clk32k", NULL); | ||
40 | clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); | ||
41 | |||
42 | clk = clk_register_fixed_rate(NULL, "ulp38m4", NULL, | ||
43 | CLK_IS_ROOT|CLK_IGNORE_UNUSED, | ||
44 | 38400000); | ||
45 | |||
46 | clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT); | ||
47 | clk_register_clkdev(clk, NULL, "UART"); | ||
48 | |||
49 | /* msp02clk needs a abx500 clk as parent. Handle by abx500 clk driver */ | ||
50 | clk = clk_reg_prcmu_gate("msp02clk", "ab9540_sysclk12_b1", | ||
51 | PRCMU_MSP02CLK, 0); | ||
52 | clk_register_clkdev(clk, NULL, "MSP02"); | ||
53 | |||
54 | clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT); | ||
55 | clk_register_clkdev(clk, NULL, "MSP1"); | ||
56 | |||
57 | clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT); | ||
58 | clk_register_clkdev(clk, NULL, "I2C"); | ||
59 | |||
60 | clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT); | ||
61 | clk_register_clkdev(clk, NULL, "slim"); | ||
62 | |||
63 | clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT); | ||
64 | clk_register_clkdev(clk, NULL, "PERIPH1"); | ||
65 | |||
66 | clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT); | ||
67 | clk_register_clkdev(clk, NULL, "PERIPH2"); | ||
68 | |||
69 | clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT); | ||
70 | clk_register_clkdev(clk, NULL, "PERIPH3"); | ||
71 | |||
72 | clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT); | ||
73 | clk_register_clkdev(clk, NULL, "PERIPH5"); | ||
74 | |||
75 | clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT); | ||
76 | clk_register_clkdev(clk, NULL, "PERIPH6"); | ||
77 | |||
78 | clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT); | ||
79 | clk_register_clkdev(clk, NULL, "PERIPH7"); | ||
80 | |||
81 | clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0, | ||
82 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
83 | clk_register_clkdev(clk, NULL, "lcd"); | ||
84 | clk_register_clkdev(clk, "lcd", "mcde"); | ||
85 | |||
86 | clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BML8580CLK, | ||
87 | CLK_IS_ROOT); | ||
88 | clk_register_clkdev(clk, NULL, "bml"); | ||
89 | |||
90 | clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0, | ||
91 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
92 | |||
93 | clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0, | ||
94 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
95 | |||
96 | clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0, | ||
97 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
98 | clk_register_clkdev(clk, NULL, "hdmi"); | ||
99 | clk_register_clkdev(clk, "hdmi", "mcde"); | ||
100 | |||
101 | clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT); | ||
102 | clk_register_clkdev(clk, NULL, "apeat"); | ||
103 | |||
104 | clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK, | ||
105 | CLK_IS_ROOT); | ||
106 | clk_register_clkdev(clk, NULL, "apetrace"); | ||
107 | |||
108 | clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT); | ||
109 | clk_register_clkdev(clk, NULL, "mcde"); | ||
110 | clk_register_clkdev(clk, "mcde", "mcde"); | ||
111 | clk_register_clkdev(clk, NULL, "dsilink.0"); | ||
112 | clk_register_clkdev(clk, NULL, "dsilink.1"); | ||
113 | clk_register_clkdev(clk, NULL, "dsilink.2"); | ||
114 | |||
115 | clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, | ||
116 | CLK_IS_ROOT); | ||
117 | clk_register_clkdev(clk, NULL, "ipi2"); | ||
118 | |||
119 | clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, | ||
120 | CLK_IS_ROOT); | ||
121 | clk_register_clkdev(clk, NULL, "dsialt"); | ||
122 | |||
123 | clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT); | ||
124 | clk_register_clkdev(clk, NULL, "dma40.0"); | ||
125 | |||
126 | clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT); | ||
127 | clk_register_clkdev(clk, NULL, "b2r2"); | ||
128 | clk_register_clkdev(clk, NULL, "b2r2_core"); | ||
129 | clk_register_clkdev(clk, NULL, "U8500-B2R2.0"); | ||
130 | clk_register_clkdev(clk, NULL, "b2r2_1_core"); | ||
131 | |||
132 | clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0, | ||
133 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
134 | clk_register_clkdev(clk, NULL, "tv"); | ||
135 | clk_register_clkdev(clk, "tv", "mcde"); | ||
136 | |||
137 | clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT); | ||
138 | clk_register_clkdev(clk, NULL, "SSP"); | ||
139 | |||
140 | clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT); | ||
141 | clk_register_clkdev(clk, NULL, "rngclk"); | ||
142 | |||
143 | clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT); | ||
144 | clk_register_clkdev(clk, NULL, "uicc"); | ||
145 | |||
146 | clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT); | ||
147 | clk_register_clkdev(clk, NULL, "mtu0"); | ||
148 | clk_register_clkdev(clk, NULL, "mtu1"); | ||
149 | |||
150 | clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, | ||
151 | PRCMU_SDMMCCLK, 100000000, | ||
152 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
153 | clk_register_clkdev(clk, NULL, "sdmmc"); | ||
154 | |||
155 | clk = clk_reg_prcmu_opp_volt_scalable("sdmmchclk", NULL, | ||
156 | PRCMU_SDMMCHCLK, 400000000, | ||
157 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
158 | clk_register_clkdev(clk, NULL, "sdmmchclk"); | ||
159 | |||
160 | clk = clk_reg_prcmu_gate("hvaclk", NULL, PRCMU_HVACLK, CLK_IS_ROOT); | ||
161 | clk_register_clkdev(clk, NULL, "hva"); | ||
162 | |||
163 | clk = clk_reg_prcmu_gate("g1clk", NULL, PRCMU_G1CLK, CLK_IS_ROOT); | ||
164 | clk_register_clkdev(clk, NULL, "g1"); | ||
165 | |||
166 | clk = clk_reg_prcmu_scalable("spare1clk", NULL, PRCMU_SPARE1CLK, 0, | ||
167 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
168 | clk_register_clkdev(clk, "dsilcd", "mcde"); | ||
169 | |||
170 | clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk", | ||
171 | PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE); | ||
172 | clk_register_clkdev(clk, "dsihs2", "mcde"); | ||
173 | clk_register_clkdev(clk, "hs_clk", "dsilink.2"); | ||
174 | |||
175 | clk = clk_reg_prcmu_scalable("dsilcd_pll", "spare1clk", | ||
176 | PRCMU_PLLDSI_LCD, 0, CLK_SET_RATE_GATE); | ||
177 | clk_register_clkdev(clk, "dsilcd_pll", "mcde"); | ||
178 | |||
179 | clk = clk_reg_prcmu_scalable("dsi0clk", "dsi_pll", | ||
180 | PRCMU_DSI0CLK, 0, CLK_SET_RATE_GATE); | ||
181 | clk_register_clkdev(clk, "dsihs0", "mcde"); | ||
182 | |||
183 | clk = clk_reg_prcmu_scalable("dsi0lcdclk", "dsilcd_pll", | ||
184 | PRCMU_DSI0CLK_LCD, 0, CLK_SET_RATE_GATE); | ||
185 | clk_register_clkdev(clk, "dsihs0", "mcde"); | ||
186 | clk_register_clkdev(clk, "hs_clk", "dsilink.0"); | ||
187 | |||
188 | clk = clk_reg_prcmu_scalable("dsi1clk", "dsi_pll", | ||
189 | PRCMU_DSI1CLK, 0, CLK_SET_RATE_GATE); | ||
190 | clk_register_clkdev(clk, "dsihs1", "mcde"); | ||
191 | |||
192 | clk = clk_reg_prcmu_scalable("dsi1lcdclk", "dsilcd_pll", | ||
193 | PRCMU_DSI1CLK_LCD, 0, CLK_SET_RATE_GATE); | ||
194 | clk_register_clkdev(clk, "dsihs1", "mcde"); | ||
195 | clk_register_clkdev(clk, "hs_clk", "dsilink.1"); | ||
196 | |||
197 | clk = clk_reg_prcmu_scalable("dsi0escclk", "tvclk", | ||
198 | PRCMU_DSI0ESCCLK, 0, CLK_SET_RATE_GATE); | ||
199 | clk_register_clkdev(clk, "lp_clk", "dsilink.0"); | ||
200 | clk_register_clkdev(clk, "dsilp0", "mcde"); | ||
201 | |||
202 | clk = clk_reg_prcmu_scalable("dsi1escclk", "tvclk", | ||
203 | PRCMU_DSI1ESCCLK, 0, CLK_SET_RATE_GATE); | ||
204 | clk_register_clkdev(clk, "lp_clk", "dsilink.1"); | ||
205 | clk_register_clkdev(clk, "dsilp1", "mcde"); | ||
206 | |||
207 | clk = clk_reg_prcmu_scalable("dsi2escclk", "tvclk", | ||
208 | PRCMU_DSI2ESCCLK, 0, CLK_SET_RATE_GATE); | ||
209 | clk_register_clkdev(clk, "lp_clk", "dsilink.2"); | ||
210 | clk_register_clkdev(clk, "dsilp2", "mcde"); | ||
211 | |||
212 | clk = clk_reg_prcmu_scalable_rate("armss", NULL, | ||
213 | PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED); | ||
214 | clk_register_clkdev(clk, "armss", NULL); | ||
215 | |||
216 | clk = clk_register_fixed_factor(NULL, "smp_twd", "armss", | ||
217 | CLK_IGNORE_UNUSED, 1, 2); | ||
218 | clk_register_clkdev(clk, NULL, "smp_twd"); | ||
219 | |||
220 | /* PRCC P-clocks */ | ||
221 | /* Peripheral 1 : PRCC P-clocks */ | ||
222 | clk = clk_reg_prcc_pclk("p1_pclk0", "per1clk", clkrst1_base, | ||
223 | BIT(0), 0); | ||
224 | clk_register_clkdev(clk, "apb_pclk", "uart0"); | ||
225 | |||
226 | clk = clk_reg_prcc_pclk("p1_pclk1", "per1clk", clkrst1_base, | ||
227 | BIT(1), 0); | ||
228 | clk_register_clkdev(clk, "apb_pclk", "uart1"); | ||
229 | |||
230 | clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", clkrst1_base, | ||
231 | BIT(2), 0); | ||
232 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); | ||
233 | |||
234 | clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", clkrst1_base, | ||
235 | BIT(3), 0); | ||
236 | clk_register_clkdev(clk, "apb_pclk", "msp0"); | ||
237 | clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.0"); | ||
238 | |||
239 | clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", clkrst1_base, | ||
240 | BIT(4), 0); | ||
241 | clk_register_clkdev(clk, "apb_pclk", "msp1"); | ||
242 | clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.1"); | ||
243 | |||
244 | clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", clkrst1_base, | ||
245 | BIT(5), 0); | ||
246 | clk_register_clkdev(clk, "apb_pclk", "sdi0"); | ||
247 | |||
248 | clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", clkrst1_base, | ||
249 | BIT(6), 0); | ||
250 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); | ||
251 | |||
252 | clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", clkrst1_base, | ||
253 | BIT(7), 0); | ||
254 | clk_register_clkdev(clk, NULL, "spi3"); | ||
255 | |||
256 | clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", clkrst1_base, | ||
257 | BIT(8), 0); | ||
258 | clk_register_clkdev(clk, "apb_pclk", "slimbus0"); | ||
259 | |||
260 | clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", clkrst1_base, | ||
261 | BIT(9), 0); | ||
262 | clk_register_clkdev(clk, NULL, "gpio.0"); | ||
263 | clk_register_clkdev(clk, NULL, "gpio.1"); | ||
264 | clk_register_clkdev(clk, NULL, "gpioblock0"); | ||
265 | clk_register_clkdev(clk, "apb_pclk", "ab85xx-codec.0"); | ||
266 | |||
267 | clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", clkrst1_base, | ||
268 | BIT(10), 0); | ||
269 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); | ||
270 | |||
271 | clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", clkrst1_base, | ||
272 | BIT(11), 0); | ||
273 | clk_register_clkdev(clk, "apb_pclk", "msp3"); | ||
274 | clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.3"); | ||
275 | |||
276 | /* Peripheral 2 : PRCC P-clocks */ | ||
277 | clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", clkrst2_base, | ||
278 | BIT(0), 0); | ||
279 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); | ||
280 | |||
281 | clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", clkrst2_base, | ||
282 | BIT(1), 0); | ||
283 | clk_register_clkdev(clk, NULL, "spi2"); | ||
284 | |||
285 | clk = clk_reg_prcc_pclk("p2_pclk2", "per2clk", clkrst2_base, | ||
286 | BIT(2), 0); | ||
287 | clk_register_clkdev(clk, NULL, "spi1"); | ||
288 | |||
289 | clk = clk_reg_prcc_pclk("p2_pclk3", "per2clk", clkrst2_base, | ||
290 | BIT(3), 0); | ||
291 | clk_register_clkdev(clk, NULL, "pwl"); | ||
292 | |||
293 | clk = clk_reg_prcc_pclk("p2_pclk4", "per2clk", clkrst2_base, | ||
294 | BIT(4), 0); | ||
295 | clk_register_clkdev(clk, "apb_pclk", "sdi4"); | ||
296 | |||
297 | clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", clkrst2_base, | ||
298 | BIT(5), 0); | ||
299 | clk_register_clkdev(clk, "apb_pclk", "msp2"); | ||
300 | clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.2"); | ||
301 | |||
302 | clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", clkrst2_base, | ||
303 | BIT(6), 0); | ||
304 | clk_register_clkdev(clk, "apb_pclk", "sdi1"); | ||
305 | |||
306 | clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", clkrst2_base, | ||
307 | BIT(7), 0); | ||
308 | clk_register_clkdev(clk, "apb_pclk", "sdi3"); | ||
309 | |||
310 | clk = clk_reg_prcc_pclk("p2_pclk8", "per2clk", clkrst2_base, | ||
311 | BIT(8), 0); | ||
312 | clk_register_clkdev(clk, NULL, "spi0"); | ||
313 | |||
314 | clk = clk_reg_prcc_pclk("p2_pclk9", "per2clk", clkrst2_base, | ||
315 | BIT(9), 0); | ||
316 | clk_register_clkdev(clk, "hsir_hclk", "ste_hsi.0"); | ||
317 | |||
318 | clk = clk_reg_prcc_pclk("p2_pclk10", "per2clk", clkrst2_base, | ||
319 | BIT(10), 0); | ||
320 | clk_register_clkdev(clk, "hsit_hclk", "ste_hsi.0"); | ||
321 | |||
322 | clk = clk_reg_prcc_pclk("p2_pclk11", "per2clk", clkrst2_base, | ||
323 | BIT(11), 0); | ||
324 | clk_register_clkdev(clk, NULL, "gpio.6"); | ||
325 | clk_register_clkdev(clk, NULL, "gpio.7"); | ||
326 | clk_register_clkdev(clk, NULL, "gpioblock1"); | ||
327 | |||
328 | clk = clk_reg_prcc_pclk("p2_pclk12", "per2clk", clkrst2_base, | ||
329 | BIT(12), 0); | ||
330 | clk_register_clkdev(clk, "msp4-pclk", "ab85xx-codec.0"); | ||
331 | |||
332 | /* Peripheral 3 : PRCC P-clocks */ | ||
333 | clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", clkrst3_base, | ||
334 | BIT(0), 0); | ||
335 | clk_register_clkdev(clk, NULL, "fsmc"); | ||
336 | |||
337 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", clkrst3_base, | ||
338 | BIT(1), 0); | ||
339 | clk_register_clkdev(clk, "apb_pclk", "ssp0"); | ||
340 | |||
341 | clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", clkrst3_base, | ||
342 | BIT(2), 0); | ||
343 | clk_register_clkdev(clk, "apb_pclk", "ssp1"); | ||
344 | |||
345 | clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", clkrst3_base, | ||
346 | BIT(3), 0); | ||
347 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); | ||
348 | |||
349 | clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", clkrst3_base, | ||
350 | BIT(4), 0); | ||
351 | clk_register_clkdev(clk, "apb_pclk", "sdi2"); | ||
352 | |||
353 | clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", clkrst3_base, | ||
354 | BIT(5), 0); | ||
355 | clk_register_clkdev(clk, "apb_pclk", "ske"); | ||
356 | clk_register_clkdev(clk, "apb_pclk", "nmk-ske-keypad"); | ||
357 | |||
358 | clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", clkrst3_base, | ||
359 | BIT(6), 0); | ||
360 | clk_register_clkdev(clk, "apb_pclk", "uart2"); | ||
361 | |||
362 | clk = clk_reg_prcc_pclk("p3_pclk7", "per3clk", clkrst3_base, | ||
363 | BIT(7), 0); | ||
364 | clk_register_clkdev(clk, "apb_pclk", "sdi5"); | ||
365 | |||
366 | clk = clk_reg_prcc_pclk("p3_pclk8", "per3clk", clkrst3_base, | ||
367 | BIT(8), 0); | ||
368 | clk_register_clkdev(clk, NULL, "gpio.2"); | ||
369 | clk_register_clkdev(clk, NULL, "gpio.3"); | ||
370 | clk_register_clkdev(clk, NULL, "gpio.4"); | ||
371 | clk_register_clkdev(clk, NULL, "gpio.5"); | ||
372 | clk_register_clkdev(clk, NULL, "gpioblock2"); | ||
373 | |||
374 | clk = clk_reg_prcc_pclk("p3_pclk9", "per3clk", clkrst3_base, | ||
375 | BIT(9), 0); | ||
376 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.5"); | ||
377 | |||
378 | clk = clk_reg_prcc_pclk("p3_pclk10", "per3clk", clkrst3_base, | ||
379 | BIT(10), 0); | ||
380 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.6"); | ||
381 | |||
382 | clk = clk_reg_prcc_pclk("p3_pclk11", "per3clk", clkrst3_base, | ||
383 | BIT(11), 0); | ||
384 | clk_register_clkdev(clk, "apb_pclk", "uart3"); | ||
385 | |||
386 | clk = clk_reg_prcc_pclk("p3_pclk12", "per3clk", clkrst3_base, | ||
387 | BIT(12), 0); | ||
388 | clk_register_clkdev(clk, "apb_pclk", "uart4"); | ||
389 | |||
390 | /* Peripheral 5 : PRCC P-clocks */ | ||
391 | clk = clk_reg_prcc_pclk("p5_pclk0", "per5clk", clkrst5_base, | ||
392 | BIT(0), 0); | ||
393 | clk_register_clkdev(clk, "usb", "musb-ux500.0"); | ||
394 | clk_register_clkdev(clk, "usbclk", "ab-iddet.0"); | ||
395 | |||
396 | clk = clk_reg_prcc_pclk("p5_pclk1", "per5clk", clkrst5_base, | ||
397 | BIT(1), 0); | ||
398 | clk_register_clkdev(clk, NULL, "gpio.8"); | ||
399 | clk_register_clkdev(clk, NULL, "gpioblock3"); | ||
400 | |||
401 | /* Peripheral 6 : PRCC P-clocks */ | ||
402 | clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", clkrst6_base, | ||
403 | BIT(0), 0); | ||
404 | clk_register_clkdev(clk, "apb_pclk", "rng"); | ||
405 | |||
406 | clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", clkrst6_base, | ||
407 | BIT(1), 0); | ||
408 | clk_register_clkdev(clk, NULL, "cryp0"); | ||
409 | clk_register_clkdev(clk, NULL, "cryp1"); | ||
410 | |||
411 | clk = clk_reg_prcc_pclk("p6_pclk2", "per6clk", clkrst6_base, | ||
412 | BIT(2), 0); | ||
413 | clk_register_clkdev(clk, NULL, "hash0"); | ||
414 | |||
415 | clk = clk_reg_prcc_pclk("p6_pclk3", "per6clk", clkrst6_base, | ||
416 | BIT(3), 0); | ||
417 | clk_register_clkdev(clk, NULL, "pka"); | ||
418 | |||
419 | clk = clk_reg_prcc_pclk("p6_pclk4", "per6clk", clkrst6_base, | ||
420 | BIT(4), 0); | ||
421 | clk_register_clkdev(clk, NULL, "db8540-hash1"); | ||
422 | |||
423 | clk = clk_reg_prcc_pclk("p6_pclk5", "per6clk", clkrst6_base, | ||
424 | BIT(5), 0); | ||
425 | clk_register_clkdev(clk, NULL, "cfgreg"); | ||
426 | |||
427 | clk = clk_reg_prcc_pclk("p6_pclk6", "per6clk", clkrst6_base, | ||
428 | BIT(6), 0); | ||
429 | clk_register_clkdev(clk, "apb_pclk", "mtu0"); | ||
430 | |||
431 | clk = clk_reg_prcc_pclk("p6_pclk7", "per6clk", clkrst6_base, | ||
432 | BIT(7), 0); | ||
433 | clk_register_clkdev(clk, "apb_pclk", "mtu1"); | ||
434 | |||
435 | /* | ||
436 | * PRCC K-clocks ==> see table PRCC_PCKEN/PRCC_KCKEN | ||
437 | * This differs from the internal implementation: | ||
438 | * We don't use the PERPIH[n| clock as parent, since those _should_ | ||
439 | * only be used as parents for the P-clocks. | ||
440 | * TODO: "parentjoin" with corresponding P-clocks for all K-clocks. | ||
441 | */ | ||
442 | |||
443 | /* Peripheral 1 : PRCC K-clocks */ | ||
444 | clk = clk_reg_prcc_kclk("p1_uart0_kclk", "uartclk", | ||
445 | clkrst1_base, BIT(0), CLK_SET_RATE_GATE); | ||
446 | clk_register_clkdev(clk, NULL, "uart0"); | ||
447 | |||
448 | clk = clk_reg_prcc_kclk("p1_uart1_kclk", "uartclk", | ||
449 | clkrst1_base, BIT(1), CLK_SET_RATE_GATE); | ||
450 | clk_register_clkdev(clk, NULL, "uart1"); | ||
451 | |||
452 | clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", | ||
453 | clkrst1_base, BIT(2), CLK_SET_RATE_GATE); | ||
454 | clk_register_clkdev(clk, NULL, "nmk-i2c.1"); | ||
455 | |||
456 | clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", | ||
457 | clkrst1_base, BIT(3), CLK_SET_RATE_GATE); | ||
458 | clk_register_clkdev(clk, NULL, "msp0"); | ||
459 | clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.0"); | ||
460 | |||
461 | clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", | ||
462 | clkrst1_base, BIT(4), CLK_SET_RATE_GATE); | ||
463 | clk_register_clkdev(clk, NULL, "msp1"); | ||
464 | clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.1"); | ||
465 | |||
466 | clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmchclk", | ||
467 | clkrst1_base, BIT(5), CLK_SET_RATE_GATE); | ||
468 | clk_register_clkdev(clk, NULL, "sdi0"); | ||
469 | |||
470 | clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", | ||
471 | clkrst1_base, BIT(6), CLK_SET_RATE_GATE); | ||
472 | clk_register_clkdev(clk, NULL, "nmk-i2c.2"); | ||
473 | |||
474 | clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", | ||
475 | clkrst1_base, BIT(8), CLK_SET_RATE_GATE); | ||
476 | clk_register_clkdev(clk, NULL, "slimbus0"); | ||
477 | |||
478 | clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", | ||
479 | clkrst1_base, BIT(9), CLK_SET_RATE_GATE); | ||
480 | clk_register_clkdev(clk, NULL, "nmk-i2c.4"); | ||
481 | |||
482 | clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", | ||
483 | clkrst1_base, BIT(10), CLK_SET_RATE_GATE); | ||
484 | clk_register_clkdev(clk, NULL, "msp3"); | ||
485 | clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.3"); | ||
486 | |||
487 | /* Peripheral 2 : PRCC K-clocks */ | ||
488 | clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", | ||
489 | clkrst2_base, BIT(0), CLK_SET_RATE_GATE); | ||
490 | clk_register_clkdev(clk, NULL, "nmk-i2c.3"); | ||
491 | |||
492 | clk = clk_reg_prcc_kclk("p2_pwl_kclk", "rtc32k", | ||
493 | clkrst2_base, BIT(1), CLK_SET_RATE_GATE); | ||
494 | clk_register_clkdev(clk, NULL, "pwl"); | ||
495 | |||
496 | clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmchclk", | ||
497 | clkrst2_base, BIT(2), CLK_SET_RATE_GATE); | ||
498 | clk_register_clkdev(clk, NULL, "sdi4"); | ||
499 | |||
500 | clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", | ||
501 | clkrst2_base, BIT(3), CLK_SET_RATE_GATE); | ||
502 | clk_register_clkdev(clk, NULL, "msp2"); | ||
503 | clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.2"); | ||
504 | |||
505 | clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmchclk", | ||
506 | clkrst2_base, BIT(4), CLK_SET_RATE_GATE); | ||
507 | clk_register_clkdev(clk, NULL, "sdi1"); | ||
508 | |||
509 | clk = clk_reg_prcc_kclk("p2_sdi3_kclk", "sdmmcclk", | ||
510 | clkrst2_base, BIT(5), CLK_SET_RATE_GATE); | ||
511 | clk_register_clkdev(clk, NULL, "sdi3"); | ||
512 | |||
513 | clk = clk_reg_prcc_kclk("p2_ssirx_kclk", "hsirxclk", | ||
514 | clkrst2_base, BIT(6), | ||
515 | CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT); | ||
516 | clk_register_clkdev(clk, "hsir_hsirxclk", "ste_hsi.0"); | ||
517 | |||
518 | clk = clk_reg_prcc_kclk("p2_ssitx_kclk", "hsitxclk", | ||
519 | clkrst2_base, BIT(7), | ||
520 | CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT); | ||
521 | clk_register_clkdev(clk, "hsit_hsitxclk", "ste_hsi.0"); | ||
522 | |||
523 | /* Should only be 9540, but might be added for 85xx as well */ | ||
524 | clk = clk_reg_prcc_kclk("p2_msp4_kclk", "msp02clk", | ||
525 | clkrst2_base, BIT(9), CLK_SET_RATE_GATE); | ||
526 | clk_register_clkdev(clk, NULL, "msp4"); | ||
527 | clk_register_clkdev(clk, "msp4", "ab85xx-codec.0"); | ||
528 | |||
529 | /* Peripheral 3 : PRCC K-clocks */ | ||
530 | clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", | ||
531 | clkrst3_base, BIT(1), CLK_SET_RATE_GATE); | ||
532 | clk_register_clkdev(clk, NULL, "ssp0"); | ||
533 | |||
534 | clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", | ||
535 | clkrst3_base, BIT(2), CLK_SET_RATE_GATE); | ||
536 | clk_register_clkdev(clk, NULL, "ssp1"); | ||
537 | |||
538 | clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", | ||
539 | clkrst3_base, BIT(3), CLK_SET_RATE_GATE); | ||
540 | clk_register_clkdev(clk, NULL, "nmk-i2c.0"); | ||
541 | |||
542 | clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmchclk", | ||
543 | clkrst3_base, BIT(4), CLK_SET_RATE_GATE); | ||
544 | clk_register_clkdev(clk, NULL, "sdi2"); | ||
545 | |||
546 | clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k", | ||
547 | clkrst3_base, BIT(5), CLK_SET_RATE_GATE); | ||
548 | clk_register_clkdev(clk, NULL, "ske"); | ||
549 | clk_register_clkdev(clk, NULL, "nmk-ske-keypad"); | ||
550 | |||
551 | clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk", | ||
552 | clkrst3_base, BIT(6), CLK_SET_RATE_GATE); | ||
553 | clk_register_clkdev(clk, NULL, "uart2"); | ||
554 | |||
555 | clk = clk_reg_prcc_kclk("p3_sdi5_kclk", "sdmmcclk", | ||
556 | clkrst3_base, BIT(7), CLK_SET_RATE_GATE); | ||
557 | clk_register_clkdev(clk, NULL, "sdi5"); | ||
558 | |||
559 | clk = clk_reg_prcc_kclk("p3_i2c5_kclk", "i2cclk", | ||
560 | clkrst3_base, BIT(8), CLK_SET_RATE_GATE); | ||
561 | clk_register_clkdev(clk, NULL, "nmk-i2c.5"); | ||
562 | |||
563 | clk = clk_reg_prcc_kclk("p3_i2c6_kclk", "i2cclk", | ||
564 | clkrst3_base, BIT(9), CLK_SET_RATE_GATE); | ||
565 | clk_register_clkdev(clk, NULL, "nmk-i2c.6"); | ||
566 | |||
567 | clk = clk_reg_prcc_kclk("p3_uart3_kclk", "uartclk", | ||
568 | clkrst3_base, BIT(10), CLK_SET_RATE_GATE); | ||
569 | clk_register_clkdev(clk, NULL, "uart3"); | ||
570 | |||
571 | clk = clk_reg_prcc_kclk("p3_uart4_kclk", "uartclk", | ||
572 | clkrst3_base, BIT(11), CLK_SET_RATE_GATE); | ||
573 | clk_register_clkdev(clk, NULL, "uart4"); | ||
574 | |||
575 | /* Peripheral 6 : PRCC K-clocks */ | ||
576 | clk = clk_reg_prcc_kclk("p6_rng_kclk", "rngclk", | ||
577 | clkrst6_base, BIT(0), CLK_SET_RATE_GATE); | ||
578 | clk_register_clkdev(clk, NULL, "rng"); | ||
21 | } | 579 | } |
diff --git a/drivers/clk/ux500/u9540_clk.c b/drivers/clk/ux500/u9540_clk.c index dbc0191e16c8..44794782e7e0 100644 --- a/drivers/clk/ux500/u9540_clk.c +++ b/drivers/clk/ux500/u9540_clk.c | |||
@@ -12,10 +12,10 @@ | |||
12 | #include <linux/clk-provider.h> | 12 | #include <linux/clk-provider.h> |
13 | #include <linux/mfd/dbx500-prcmu.h> | 13 | #include <linux/mfd/dbx500-prcmu.h> |
14 | #include <linux/platform_data/clk-ux500.h> | 14 | #include <linux/platform_data/clk-ux500.h> |
15 | |||
16 | #include "clk.h" | 15 | #include "clk.h" |
17 | 16 | ||
18 | void u9540_clk_init(void) | 17 | void u9540_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base, |
18 | u32 clkrst5_base, u32 clkrst6_base) | ||
19 | { | 19 | { |
20 | /* register clocks here */ | 20 | /* register clocks here */ |
21 | } | 21 | } |
diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index 256c8be74df8..2dc8b41a339d 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c | |||
@@ -107,7 +107,7 @@ void __init vexpress_osc_of_setup(struct device_node *node) | |||
107 | osc->func = vexpress_config_func_get_by_node(node); | 107 | osc->func = vexpress_config_func_get_by_node(node); |
108 | if (!osc->func) { | 108 | if (!osc->func) { |
109 | pr_err("Failed to obtain config func for node '%s'!\n", | 109 | pr_err("Failed to obtain config func for node '%s'!\n", |
110 | node->name); | 110 | node->full_name); |
111 | goto error; | 111 | goto error; |
112 | } | 112 | } |
113 | 113 | ||
@@ -119,7 +119,7 @@ void __init vexpress_osc_of_setup(struct device_node *node) | |||
119 | 119 | ||
120 | of_property_read_string(node, "clock-output-names", &init.name); | 120 | of_property_read_string(node, "clock-output-names", &init.name); |
121 | if (!init.name) | 121 | if (!init.name) |
122 | init.name = node->name; | 122 | init.name = node->full_name; |
123 | 123 | ||
124 | init.ops = &vexpress_osc_ops; | 124 | init.ops = &vexpress_osc_ops; |
125 | init.flags = CLK_IS_ROOT; | 125 | init.flags = CLK_IS_ROOT; |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 66f80973596b..a292a1deff9a 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -480,6 +480,7 @@ struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = { | |||
480 | CLK_MGT_ENTRY(PER6CLK, PLL_DIV, true), | 480 | CLK_MGT_ENTRY(PER6CLK, PLL_DIV, true), |
481 | CLK_MGT_ENTRY(PER7CLK, PLL_DIV, true), | 481 | CLK_MGT_ENTRY(PER7CLK, PLL_DIV, true), |
482 | CLK_MGT_ENTRY(LCDCLK, PLL_FIX, true), | 482 | CLK_MGT_ENTRY(LCDCLK, PLL_FIX, true), |
483 | CLK_MGT_ENTRY(BML8580CLK, PLL_DIV, true), | ||
483 | CLK_MGT_ENTRY(BMLCLK, PLL_DIV, true), | 484 | CLK_MGT_ENTRY(BMLCLK, PLL_DIV, true), |
484 | CLK_MGT_ENTRY(HSITXCLK, PLL_DIV, true), | 485 | CLK_MGT_ENTRY(HSITXCLK, PLL_DIV, true), |
485 | CLK_MGT_ENTRY(HSIRXCLK, PLL_DIV, true), | 486 | CLK_MGT_ENTRY(HSIRXCLK, PLL_DIV, true), |
diff --git a/drivers/mfd/dbx500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h index d14836ed2114..ca355dd423a6 100644 --- a/drivers/mfd/dbx500-prcmu-regs.h +++ b/drivers/mfd/dbx500-prcmu-regs.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #define PRCM_PER7CLK_MGT (0x040) | 32 | #define PRCM_PER7CLK_MGT (0x040) |
33 | #define PRCM_LCDCLK_MGT (0x044) | 33 | #define PRCM_LCDCLK_MGT (0x044) |
34 | #define PRCM_BMLCLK_MGT (0x04C) | 34 | #define PRCM_BMLCLK_MGT (0x04C) |
35 | #define PRCM_BML8580CLK_MGT (0x108) | ||
35 | #define PRCM_HSITXCLK_MGT (0x050) | 36 | #define PRCM_HSITXCLK_MGT (0x050) |
36 | #define PRCM_HSIRXCLK_MGT (0x054) | 37 | #define PRCM_HSIRXCLK_MGT (0x054) |
37 | #define PRCM_HDMICLK_MGT (0x058) | 38 | #define PRCM_HDMICLK_MGT (0x058) |