diff options
Diffstat (limited to 'drivers')
59 files changed, 8591 insertions, 3415 deletions
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 7a10bc9a23e7..ace7309c4369 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -35,6 +35,7 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ | |||
35 | obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ | 35 | obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ |
36 | obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o | 36 | obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o |
37 | obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ | 37 | obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ |
38 | obj-$(CONFIG_COMMON_CLK_AT91) += at91/ | ||
38 | 39 | ||
39 | obj-$(CONFIG_X86) += x86/ | 40 | obj-$(CONFIG_X86) += x86/ |
40 | 41 | ||
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile new file mode 100644 index 000000000000..46c1d3d0d66b --- /dev/null +++ b/drivers/clk/at91/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # | ||
2 | # Makefile for at91 specific clk | ||
3 | # | ||
4 | |||
5 | obj-y += pmc.o | ||
6 | obj-y += clk-main.o clk-pll.o clk-plldiv.o clk-master.o | ||
7 | obj-y += clk-system.o clk-peripheral.o clk-programmable.o | ||
8 | |||
9 | obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o | ||
10 | obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o | ||
11 | obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o | ||
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c new file mode 100644 index 000000000000..8e9e8cc0412d --- /dev/null +++ b/drivers/clk/at91/clk-main.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/of_irq.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/irq.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/wait.h> | ||
23 | |||
24 | #include "pmc.h" | ||
25 | |||
26 | #define SLOW_CLOCK_FREQ 32768 | ||
27 | #define MAINF_DIV 16 | ||
28 | #define MAINFRDY_TIMEOUT (((MAINF_DIV + 1) * USEC_PER_SEC) / \ | ||
29 | SLOW_CLOCK_FREQ) | ||
30 | #define MAINF_LOOP_MIN_WAIT (USEC_PER_SEC / SLOW_CLOCK_FREQ) | ||
31 | #define MAINF_LOOP_MAX_WAIT MAINFRDY_TIMEOUT | ||
32 | |||
33 | struct clk_main { | ||
34 | struct clk_hw hw; | ||
35 | struct at91_pmc *pmc; | ||
36 | unsigned long rate; | ||
37 | unsigned int irq; | ||
38 | wait_queue_head_t wait; | ||
39 | }; | ||
40 | |||
41 | #define to_clk_main(hw) container_of(hw, struct clk_main, hw) | ||
42 | |||
43 | static irqreturn_t clk_main_irq_handler(int irq, void *dev_id) | ||
44 | { | ||
45 | struct clk_main *clkmain = (struct clk_main *)dev_id; | ||
46 | |||
47 | wake_up(&clkmain->wait); | ||
48 | disable_irq_nosync(clkmain->irq); | ||
49 | |||
50 | return IRQ_HANDLED; | ||
51 | } | ||
52 | |||
53 | static int clk_main_prepare(struct clk_hw *hw) | ||
54 | { | ||
55 | struct clk_main *clkmain = to_clk_main(hw); | ||
56 | struct at91_pmc *pmc = clkmain->pmc; | ||
57 | unsigned long halt_time, timeout; | ||
58 | u32 tmp; | ||
59 | |||
60 | while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) { | ||
61 | enable_irq(clkmain->irq); | ||
62 | wait_event(clkmain->wait, | ||
63 | pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS); | ||
64 | } | ||
65 | |||
66 | if (clkmain->rate) | ||
67 | return 0; | ||
68 | |||
69 | timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT); | ||
70 | do { | ||
71 | halt_time = jiffies; | ||
72 | tmp = pmc_read(pmc, AT91_CKGR_MCFR); | ||
73 | if (tmp & AT91_PMC_MAINRDY) | ||
74 | return 0; | ||
75 | usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); | ||
76 | } while (time_before(halt_time, timeout)); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int clk_main_is_prepared(struct clk_hw *hw) | ||
82 | { | ||
83 | struct clk_main *clkmain = to_clk_main(hw); | ||
84 | |||
85 | return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCS); | ||
86 | } | ||
87 | |||
88 | static unsigned long clk_main_recalc_rate(struct clk_hw *hw, | ||
89 | unsigned long parent_rate) | ||
90 | { | ||
91 | u32 tmp; | ||
92 | struct clk_main *clkmain = to_clk_main(hw); | ||
93 | struct at91_pmc *pmc = clkmain->pmc; | ||
94 | |||
95 | if (clkmain->rate) | ||
96 | return clkmain->rate; | ||
97 | |||
98 | tmp = pmc_read(pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINF; | ||
99 | clkmain->rate = (tmp * parent_rate) / MAINF_DIV; | ||
100 | |||
101 | return clkmain->rate; | ||
102 | } | ||
103 | |||
104 | static const struct clk_ops main_ops = { | ||
105 | .prepare = clk_main_prepare, | ||
106 | .is_prepared = clk_main_is_prepared, | ||
107 | .recalc_rate = clk_main_recalc_rate, | ||
108 | }; | ||
109 | |||
110 | static struct clk * __init | ||
111 | at91_clk_register_main(struct at91_pmc *pmc, | ||
112 | unsigned int irq, | ||
113 | const char *name, | ||
114 | const char *parent_name, | ||
115 | unsigned long rate) | ||
116 | { | ||
117 | int ret; | ||
118 | struct clk_main *clkmain; | ||
119 | struct clk *clk = NULL; | ||
120 | struct clk_init_data init; | ||
121 | |||
122 | if (!pmc || !irq || !name) | ||
123 | return ERR_PTR(-EINVAL); | ||
124 | |||
125 | if (!rate && !parent_name) | ||
126 | return ERR_PTR(-EINVAL); | ||
127 | |||
128 | clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL); | ||
129 | if (!clkmain) | ||
130 | return ERR_PTR(-ENOMEM); | ||
131 | |||
132 | init.name = name; | ||
133 | init.ops = &main_ops; | ||
134 | init.parent_names = parent_name ? &parent_name : NULL; | ||
135 | init.num_parents = parent_name ? 1 : 0; | ||
136 | init.flags = parent_name ? 0 : CLK_IS_ROOT; | ||
137 | |||
138 | clkmain->hw.init = &init; | ||
139 | clkmain->rate = rate; | ||
140 | clkmain->pmc = pmc; | ||
141 | clkmain->irq = irq; | ||
142 | init_waitqueue_head(&clkmain->wait); | ||
143 | irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN); | ||
144 | ret = request_irq(clkmain->irq, clk_main_irq_handler, | ||
145 | IRQF_TRIGGER_HIGH, "clk-main", clkmain); | ||
146 | if (ret) | ||
147 | return ERR_PTR(ret); | ||
148 | |||
149 | clk = clk_register(NULL, &clkmain->hw); | ||
150 | if (IS_ERR(clk)) { | ||
151 | free_irq(clkmain->irq, clkmain); | ||
152 | kfree(clkmain); | ||
153 | } | ||
154 | |||
155 | return clk; | ||
156 | } | ||
157 | |||
158 | |||
159 | |||
160 | static void __init | ||
161 | of_at91_clk_main_setup(struct device_node *np, struct at91_pmc *pmc) | ||
162 | { | ||
163 | struct clk *clk; | ||
164 | unsigned int irq; | ||
165 | const char *parent_name; | ||
166 | const char *name = np->name; | ||
167 | u32 rate = 0; | ||
168 | |||
169 | parent_name = of_clk_get_parent_name(np, 0); | ||
170 | of_property_read_string(np, "clock-output-names", &name); | ||
171 | of_property_read_u32(np, "clock-frequency", &rate); | ||
172 | irq = irq_of_parse_and_map(np, 0); | ||
173 | if (!irq) | ||
174 | return; | ||
175 | |||
176 | clk = at91_clk_register_main(pmc, irq, name, parent_name, rate); | ||
177 | if (IS_ERR(clk)) | ||
178 | return; | ||
179 | |||
180 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
181 | } | ||
182 | |||
183 | void __init of_at91rm9200_clk_main_setup(struct device_node *np, | ||
184 | struct at91_pmc *pmc) | ||
185 | { | ||
186 | of_at91_clk_main_setup(np, pmc); | ||
187 | } | ||
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c new file mode 100644 index 000000000000..bd313f7816a8 --- /dev/null +++ b/drivers/clk/at91/clk-master.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/wait.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/irq.h> | ||
22 | |||
23 | #include "pmc.h" | ||
24 | |||
25 | #define MASTER_SOURCE_MAX 4 | ||
26 | |||
27 | #define MASTER_PRES_MASK 0x7 | ||
28 | #define MASTER_PRES_MAX MASTER_PRES_MASK | ||
29 | #define MASTER_DIV_SHIFT 8 | ||
30 | #define MASTER_DIV_MASK 0x3 | ||
31 | |||
32 | struct clk_master_characteristics { | ||
33 | struct clk_range output; | ||
34 | u32 divisors[4]; | ||
35 | u8 have_div3_pres; | ||
36 | }; | ||
37 | |||
38 | struct clk_master_layout { | ||
39 | u32 mask; | ||
40 | u8 pres_shift; | ||
41 | }; | ||
42 | |||
43 | #define to_clk_master(hw) container_of(hw, struct clk_master, hw) | ||
44 | |||
45 | struct clk_master { | ||
46 | struct clk_hw hw; | ||
47 | struct at91_pmc *pmc; | ||
48 | unsigned int irq; | ||
49 | wait_queue_head_t wait; | ||
50 | const struct clk_master_layout *layout; | ||
51 | const struct clk_master_characteristics *characteristics; | ||
52 | }; | ||
53 | |||
54 | static irqreturn_t clk_master_irq_handler(int irq, void *dev_id) | ||
55 | { | ||
56 | struct clk_master *master = (struct clk_master *)dev_id; | ||
57 | |||
58 | wake_up(&master->wait); | ||
59 | disable_irq_nosync(master->irq); | ||
60 | |||
61 | return IRQ_HANDLED; | ||
62 | } | ||
63 | static int clk_master_prepare(struct clk_hw *hw) | ||
64 | { | ||
65 | struct clk_master *master = to_clk_master(hw); | ||
66 | struct at91_pmc *pmc = master->pmc; | ||
67 | |||
68 | while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY)) { | ||
69 | enable_irq(master->irq); | ||
70 | wait_event(master->wait, | ||
71 | pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY); | ||
72 | } | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int clk_master_is_prepared(struct clk_hw *hw) | ||
78 | { | ||
79 | struct clk_master *master = to_clk_master(hw); | ||
80 | |||
81 | return !!(pmc_read(master->pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY); | ||
82 | } | ||
83 | |||
84 | static unsigned long clk_master_recalc_rate(struct clk_hw *hw, | ||
85 | unsigned long parent_rate) | ||
86 | { | ||
87 | u8 pres; | ||
88 | u8 div; | ||
89 | unsigned long rate = parent_rate; | ||
90 | struct clk_master *master = to_clk_master(hw); | ||
91 | struct at91_pmc *pmc = master->pmc; | ||
92 | const struct clk_master_layout *layout = master->layout; | ||
93 | const struct clk_master_characteristics *characteristics = | ||
94 | master->characteristics; | ||
95 | u32 tmp; | ||
96 | |||
97 | pmc_lock(pmc); | ||
98 | tmp = pmc_read(pmc, AT91_PMC_MCKR) & layout->mask; | ||
99 | pmc_unlock(pmc); | ||
100 | |||
101 | pres = (tmp >> layout->pres_shift) & MASTER_PRES_MASK; | ||
102 | div = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; | ||
103 | |||
104 | if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX) | ||
105 | rate /= 3; | ||
106 | else | ||
107 | rate >>= pres; | ||
108 | |||
109 | rate /= characteristics->divisors[div]; | ||
110 | |||
111 | if (rate < characteristics->output.min) | ||
112 | pr_warn("master clk is underclocked"); | ||
113 | else if (rate > characteristics->output.max) | ||
114 | pr_warn("master clk is overclocked"); | ||
115 | |||
116 | return rate; | ||
117 | } | ||
118 | |||
119 | static u8 clk_master_get_parent(struct clk_hw *hw) | ||
120 | { | ||
121 | struct clk_master *master = to_clk_master(hw); | ||
122 | struct at91_pmc *pmc = master->pmc; | ||
123 | |||
124 | return pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_CSS; | ||
125 | } | ||
126 | |||
127 | static const struct clk_ops master_ops = { | ||
128 | .prepare = clk_master_prepare, | ||
129 | .is_prepared = clk_master_is_prepared, | ||
130 | .recalc_rate = clk_master_recalc_rate, | ||
131 | .get_parent = clk_master_get_parent, | ||
132 | }; | ||
133 | |||
134 | static struct clk * __init | ||
135 | at91_clk_register_master(struct at91_pmc *pmc, unsigned int irq, | ||
136 | const char *name, int num_parents, | ||
137 | const char **parent_names, | ||
138 | const struct clk_master_layout *layout, | ||
139 | const struct clk_master_characteristics *characteristics) | ||
140 | { | ||
141 | int ret; | ||
142 | struct clk_master *master; | ||
143 | struct clk *clk = NULL; | ||
144 | struct clk_init_data init; | ||
145 | |||
146 | if (!pmc || !irq || !name || !num_parents || !parent_names) | ||
147 | return ERR_PTR(-EINVAL); | ||
148 | |||
149 | master = kzalloc(sizeof(*master), GFP_KERNEL); | ||
150 | if (!master) | ||
151 | return ERR_PTR(-ENOMEM); | ||
152 | |||
153 | init.name = name; | ||
154 | init.ops = &master_ops; | ||
155 | init.parent_names = parent_names; | ||
156 | init.num_parents = num_parents; | ||
157 | init.flags = 0; | ||
158 | |||
159 | master->hw.init = &init; | ||
160 | master->layout = layout; | ||
161 | master->characteristics = characteristics; | ||
162 | master->pmc = pmc; | ||
163 | master->irq = irq; | ||
164 | init_waitqueue_head(&master->wait); | ||
165 | irq_set_status_flags(master->irq, IRQ_NOAUTOEN); | ||
166 | ret = request_irq(master->irq, clk_master_irq_handler, | ||
167 | IRQF_TRIGGER_HIGH, "clk-master", master); | ||
168 | if (ret) | ||
169 | return ERR_PTR(ret); | ||
170 | |||
171 | clk = clk_register(NULL, &master->hw); | ||
172 | if (IS_ERR(clk)) | ||
173 | kfree(master); | ||
174 | |||
175 | return clk; | ||
176 | } | ||
177 | |||
178 | |||
179 | static const struct clk_master_layout at91rm9200_master_layout = { | ||
180 | .mask = 0x31F, | ||
181 | .pres_shift = 2, | ||
182 | }; | ||
183 | |||
184 | static const struct clk_master_layout at91sam9x5_master_layout = { | ||
185 | .mask = 0x373, | ||
186 | .pres_shift = 4, | ||
187 | }; | ||
188 | |||
189 | |||
190 | static struct clk_master_characteristics * __init | ||
191 | of_at91_clk_master_get_characteristics(struct device_node *np) | ||
192 | { | ||
193 | struct clk_master_characteristics *characteristics; | ||
194 | |||
195 | characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL); | ||
196 | if (!characteristics) | ||
197 | return NULL; | ||
198 | |||
199 | if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output)) | ||
200 | goto out_free_characteristics; | ||
201 | |||
202 | of_property_read_u32_array(np, "atmel,clk-divisors", | ||
203 | characteristics->divisors, 4); | ||
204 | |||
205 | characteristics->have_div3_pres = | ||
206 | of_property_read_bool(np, "atmel,master-clk-have-div3-pres"); | ||
207 | |||
208 | return characteristics; | ||
209 | |||
210 | out_free_characteristics: | ||
211 | kfree(characteristics); | ||
212 | return NULL; | ||
213 | } | ||
214 | |||
215 | static void __init | ||
216 | of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc, | ||
217 | const struct clk_master_layout *layout) | ||
218 | { | ||
219 | struct clk *clk; | ||
220 | int num_parents; | ||
221 | int i; | ||
222 | unsigned int irq; | ||
223 | const char *parent_names[MASTER_SOURCE_MAX]; | ||
224 | const char *name = np->name; | ||
225 | struct clk_master_characteristics *characteristics; | ||
226 | |||
227 | num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); | ||
228 | if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX) | ||
229 | return; | ||
230 | |||
231 | for (i = 0; i < num_parents; ++i) { | ||
232 | parent_names[i] = of_clk_get_parent_name(np, i); | ||
233 | if (!parent_names[i]) | ||
234 | return; | ||
235 | } | ||
236 | |||
237 | of_property_read_string(np, "clock-output-names", &name); | ||
238 | |||
239 | characteristics = of_at91_clk_master_get_characteristics(np); | ||
240 | if (!characteristics) | ||
241 | return; | ||
242 | |||
243 | irq = irq_of_parse_and_map(np, 0); | ||
244 | if (!irq) | ||
245 | return; | ||
246 | |||
247 | clk = at91_clk_register_master(pmc, irq, name, num_parents, | ||
248 | parent_names, layout, | ||
249 | characteristics); | ||
250 | if (IS_ERR(clk)) | ||
251 | goto out_free_characteristics; | ||
252 | |||
253 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
254 | return; | ||
255 | |||
256 | out_free_characteristics: | ||
257 | kfree(characteristics); | ||
258 | } | ||
259 | |||
260 | void __init of_at91rm9200_clk_master_setup(struct device_node *np, | ||
261 | struct at91_pmc *pmc) | ||
262 | { | ||
263 | of_at91_clk_master_setup(np, pmc, &at91rm9200_master_layout); | ||
264 | } | ||
265 | |||
266 | void __init of_at91sam9x5_clk_master_setup(struct device_node *np, | ||
267 | struct at91_pmc *pmc) | ||
268 | { | ||
269 | of_at91_clk_master_setup(np, pmc, &at91sam9x5_master_layout); | ||
270 | } | ||
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c new file mode 100644 index 000000000000..597fed423d7d --- /dev/null +++ b/drivers/clk/at91/clk-peripheral.c | |||
@@ -0,0 +1,410 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | #include "pmc.h" | ||
19 | |||
20 | #define PERIPHERAL_MAX 64 | ||
21 | |||
22 | #define PERIPHERAL_AT91RM9200 0 | ||
23 | #define PERIPHERAL_AT91SAM9X5 1 | ||
24 | |||
25 | #define PERIPHERAL_ID_MIN 2 | ||
26 | #define PERIPHERAL_ID_MAX 31 | ||
27 | #define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX)) | ||
28 | |||
29 | #define PERIPHERAL_RSHIFT_MASK 0x3 | ||
30 | #define PERIPHERAL_RSHIFT(val) (((val) >> 16) & PERIPHERAL_RSHIFT_MASK) | ||
31 | |||
32 | #define PERIPHERAL_MAX_SHIFT 4 | ||
33 | |||
34 | struct clk_peripheral { | ||
35 | struct clk_hw hw; | ||
36 | struct at91_pmc *pmc; | ||
37 | u32 id; | ||
38 | }; | ||
39 | |||
40 | #define to_clk_peripheral(hw) container_of(hw, struct clk_peripheral, hw) | ||
41 | |||
42 | struct clk_sam9x5_peripheral { | ||
43 | struct clk_hw hw; | ||
44 | struct at91_pmc *pmc; | ||
45 | struct clk_range range; | ||
46 | u32 id; | ||
47 | u32 div; | ||
48 | bool auto_div; | ||
49 | }; | ||
50 | |||
51 | #define to_clk_sam9x5_peripheral(hw) \ | ||
52 | container_of(hw, struct clk_sam9x5_peripheral, hw) | ||
53 | |||
54 | static int clk_peripheral_enable(struct clk_hw *hw) | ||
55 | { | ||
56 | struct clk_peripheral *periph = to_clk_peripheral(hw); | ||
57 | struct at91_pmc *pmc = periph->pmc; | ||
58 | int offset = AT91_PMC_PCER; | ||
59 | u32 id = periph->id; | ||
60 | |||
61 | if (id < PERIPHERAL_ID_MIN) | ||
62 | return 0; | ||
63 | if (id > PERIPHERAL_ID_MAX) | ||
64 | offset = AT91_PMC_PCER1; | ||
65 | pmc_write(pmc, offset, PERIPHERAL_MASK(id)); | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static void clk_peripheral_disable(struct clk_hw *hw) | ||
70 | { | ||
71 | struct clk_peripheral *periph = to_clk_peripheral(hw); | ||
72 | struct at91_pmc *pmc = periph->pmc; | ||
73 | int offset = AT91_PMC_PCDR; | ||
74 | u32 id = periph->id; | ||
75 | |||
76 | if (id < PERIPHERAL_ID_MIN) | ||
77 | return; | ||
78 | if (id > PERIPHERAL_ID_MAX) | ||
79 | offset = AT91_PMC_PCDR1; | ||
80 | pmc_write(pmc, offset, PERIPHERAL_MASK(id)); | ||
81 | } | ||
82 | |||
83 | static int clk_peripheral_is_enabled(struct clk_hw *hw) | ||
84 | { | ||
85 | struct clk_peripheral *periph = to_clk_peripheral(hw); | ||
86 | struct at91_pmc *pmc = periph->pmc; | ||
87 | int offset = AT91_PMC_PCSR; | ||
88 | u32 id = periph->id; | ||
89 | |||
90 | if (id < PERIPHERAL_ID_MIN) | ||
91 | return 1; | ||
92 | if (id > PERIPHERAL_ID_MAX) | ||
93 | offset = AT91_PMC_PCSR1; | ||
94 | return !!(pmc_read(pmc, offset) & PERIPHERAL_MASK(id)); | ||
95 | } | ||
96 | |||
97 | static const struct clk_ops peripheral_ops = { | ||
98 | .enable = clk_peripheral_enable, | ||
99 | .disable = clk_peripheral_disable, | ||
100 | .is_enabled = clk_peripheral_is_enabled, | ||
101 | }; | ||
102 | |||
103 | static struct clk * __init | ||
104 | at91_clk_register_peripheral(struct at91_pmc *pmc, const char *name, | ||
105 | const char *parent_name, u32 id) | ||
106 | { | ||
107 | struct clk_peripheral *periph; | ||
108 | struct clk *clk = NULL; | ||
109 | struct clk_init_data init; | ||
110 | |||
111 | if (!pmc || !name || !parent_name || id > PERIPHERAL_ID_MAX) | ||
112 | return ERR_PTR(-EINVAL); | ||
113 | |||
114 | periph = kzalloc(sizeof(*periph), GFP_KERNEL); | ||
115 | if (!periph) | ||
116 | return ERR_PTR(-ENOMEM); | ||
117 | |||
118 | init.name = name; | ||
119 | init.ops = &peripheral_ops; | ||
120 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
121 | init.num_parents = (parent_name ? 1 : 0); | ||
122 | init.flags = 0; | ||
123 | |||
124 | periph->id = id; | ||
125 | periph->hw.init = &init; | ||
126 | periph->pmc = pmc; | ||
127 | |||
128 | clk = clk_register(NULL, &periph->hw); | ||
129 | if (IS_ERR(clk)) | ||
130 | kfree(periph); | ||
131 | |||
132 | return clk; | ||
133 | } | ||
134 | |||
135 | static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph) | ||
136 | { | ||
137 | struct clk *parent; | ||
138 | unsigned long parent_rate; | ||
139 | int shift = 0; | ||
140 | |||
141 | if (!periph->auto_div) | ||
142 | return; | ||
143 | |||
144 | if (periph->range.max) { | ||
145 | parent = clk_get_parent_by_index(periph->hw.clk, 0); | ||
146 | parent_rate = __clk_get_rate(parent); | ||
147 | if (!parent_rate) | ||
148 | return; | ||
149 | |||
150 | for (; shift < PERIPHERAL_MAX_SHIFT; shift++) { | ||
151 | if (parent_rate >> shift <= periph->range.max) | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | periph->auto_div = false; | ||
157 | periph->div = shift; | ||
158 | } | ||
159 | |||
160 | static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) | ||
161 | { | ||
162 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | ||
163 | struct at91_pmc *pmc = periph->pmc; | ||
164 | |||
165 | if (periph->id < PERIPHERAL_ID_MIN) | ||
166 | return 0; | ||
167 | |||
168 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) | | ||
169 | AT91_PMC_PCR_CMD | | ||
170 | AT91_PMC_PCR_DIV(periph->div) | | ||
171 | AT91_PMC_PCR_EN); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static void clk_sam9x5_peripheral_disable(struct clk_hw *hw) | ||
176 | { | ||
177 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | ||
178 | struct at91_pmc *pmc = periph->pmc; | ||
179 | |||
180 | if (periph->id < PERIPHERAL_ID_MIN) | ||
181 | return; | ||
182 | |||
183 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) | | ||
184 | AT91_PMC_PCR_CMD); | ||
185 | } | ||
186 | |||
187 | static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) | ||
188 | { | ||
189 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | ||
190 | struct at91_pmc *pmc = periph->pmc; | ||
191 | int ret; | ||
192 | |||
193 | if (periph->id < PERIPHERAL_ID_MIN) | ||
194 | return 1; | ||
195 | |||
196 | pmc_lock(pmc); | ||
197 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID)); | ||
198 | ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN); | ||
199 | pmc_unlock(pmc); | ||
200 | |||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | static unsigned long | ||
205 | clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw, | ||
206 | unsigned long parent_rate) | ||
207 | { | ||
208 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | ||
209 | struct at91_pmc *pmc = periph->pmc; | ||
210 | u32 tmp; | ||
211 | |||
212 | if (periph->id < PERIPHERAL_ID_MIN) | ||
213 | return parent_rate; | ||
214 | |||
215 | pmc_lock(pmc); | ||
216 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID)); | ||
217 | tmp = pmc_read(pmc, AT91_PMC_PCR); | ||
218 | pmc_unlock(pmc); | ||
219 | |||
220 | if (tmp & AT91_PMC_PCR_EN) { | ||
221 | periph->div = PERIPHERAL_RSHIFT(tmp); | ||
222 | periph->auto_div = false; | ||
223 | } else { | ||
224 | clk_sam9x5_peripheral_autodiv(periph); | ||
225 | } | ||
226 | |||
227 | return parent_rate >> periph->div; | ||
228 | } | ||
229 | |||
230 | static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw, | ||
231 | unsigned long rate, | ||
232 | unsigned long *parent_rate) | ||
233 | { | ||
234 | int shift = 0; | ||
235 | unsigned long best_rate; | ||
236 | unsigned long best_diff; | ||
237 | unsigned long cur_rate = *parent_rate; | ||
238 | unsigned long cur_diff; | ||
239 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | ||
240 | |||
241 | if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) | ||
242 | return *parent_rate; | ||
243 | |||
244 | if (periph->range.max) { | ||
245 | for (; shift < PERIPHERAL_MAX_SHIFT; shift++) { | ||
246 | cur_rate = *parent_rate >> shift; | ||
247 | if (cur_rate <= periph->range.max) | ||
248 | break; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | if (rate >= cur_rate) | ||
253 | return cur_rate; | ||
254 | |||
255 | best_diff = cur_rate - rate; | ||
256 | best_rate = cur_rate; | ||
257 | for (; shift < PERIPHERAL_MAX_SHIFT; shift++) { | ||
258 | cur_rate = *parent_rate >> shift; | ||
259 | if (cur_rate < rate) | ||
260 | cur_diff = rate - cur_rate; | ||
261 | else | ||
262 | cur_diff = cur_rate - rate; | ||
263 | |||
264 | if (cur_diff < best_diff) { | ||
265 | best_diff = cur_diff; | ||
266 | best_rate = cur_rate; | ||
267 | } | ||
268 | |||
269 | if (!best_diff || cur_rate < rate) | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | return best_rate; | ||
274 | } | ||
275 | |||
276 | static int clk_sam9x5_peripheral_set_rate(struct clk_hw *hw, | ||
277 | unsigned long rate, | ||
278 | unsigned long parent_rate) | ||
279 | { | ||
280 | int shift; | ||
281 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | ||
282 | if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) { | ||
283 | if (parent_rate == rate) | ||
284 | return 0; | ||
285 | else | ||
286 | return -EINVAL; | ||
287 | } | ||
288 | |||
289 | if (periph->range.max && rate > periph->range.max) | ||
290 | return -EINVAL; | ||
291 | |||
292 | for (shift = 0; shift < PERIPHERAL_MAX_SHIFT; shift++) { | ||
293 | if (parent_rate >> shift == rate) { | ||
294 | periph->auto_div = false; | ||
295 | periph->div = shift; | ||
296 | return 0; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | return -EINVAL; | ||
301 | } | ||
302 | |||
303 | static const struct clk_ops sam9x5_peripheral_ops = { | ||
304 | .enable = clk_sam9x5_peripheral_enable, | ||
305 | .disable = clk_sam9x5_peripheral_disable, | ||
306 | .is_enabled = clk_sam9x5_peripheral_is_enabled, | ||
307 | .recalc_rate = clk_sam9x5_peripheral_recalc_rate, | ||
308 | .round_rate = clk_sam9x5_peripheral_round_rate, | ||
309 | .set_rate = clk_sam9x5_peripheral_set_rate, | ||
310 | }; | ||
311 | |||
312 | static struct clk * __init | ||
313 | at91_clk_register_sam9x5_peripheral(struct at91_pmc *pmc, const char *name, | ||
314 | const char *parent_name, u32 id, | ||
315 | const struct clk_range *range) | ||
316 | { | ||
317 | struct clk_sam9x5_peripheral *periph; | ||
318 | struct clk *clk = NULL; | ||
319 | struct clk_init_data init; | ||
320 | |||
321 | if (!pmc || !name || !parent_name) | ||
322 | return ERR_PTR(-EINVAL); | ||
323 | |||
324 | periph = kzalloc(sizeof(*periph), GFP_KERNEL); | ||
325 | if (!periph) | ||
326 | return ERR_PTR(-ENOMEM); | ||
327 | |||
328 | init.name = name; | ||
329 | init.ops = &sam9x5_peripheral_ops; | ||
330 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
331 | init.num_parents = (parent_name ? 1 : 0); | ||
332 | init.flags = 0; | ||
333 | |||
334 | periph->id = id; | ||
335 | periph->hw.init = &init; | ||
336 | periph->div = 0; | ||
337 | periph->pmc = pmc; | ||
338 | periph->auto_div = true; | ||
339 | periph->range = *range; | ||
340 | |||
341 | clk = clk_register(NULL, &periph->hw); | ||
342 | if (IS_ERR(clk)) | ||
343 | kfree(periph); | ||
344 | else | ||
345 | clk_sam9x5_peripheral_autodiv(periph); | ||
346 | |||
347 | return clk; | ||
348 | } | ||
349 | |||
350 | static void __init | ||
351 | of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) | ||
352 | { | ||
353 | int num; | ||
354 | u32 id; | ||
355 | struct clk *clk; | ||
356 | const char *parent_name; | ||
357 | const char *name; | ||
358 | struct device_node *periphclknp; | ||
359 | |||
360 | parent_name = of_clk_get_parent_name(np, 0); | ||
361 | if (!parent_name) | ||
362 | return; | ||
363 | |||
364 | num = of_get_child_count(np); | ||
365 | if (!num || num > PERIPHERAL_MAX) | ||
366 | return; | ||
367 | |||
368 | for_each_child_of_node(np, periphclknp) { | ||
369 | if (of_property_read_u32(periphclknp, "reg", &id)) | ||
370 | continue; | ||
371 | |||
372 | if (id >= PERIPHERAL_MAX) | ||
373 | continue; | ||
374 | |||
375 | if (of_property_read_string(np, "clock-output-names", &name)) | ||
376 | name = periphclknp->name; | ||
377 | |||
378 | if (type == PERIPHERAL_AT91RM9200) { | ||
379 | clk = at91_clk_register_peripheral(pmc, name, | ||
380 | parent_name, id); | ||
381 | } else { | ||
382 | struct clk_range range = CLK_RANGE(0, 0); | ||
383 | |||
384 | of_at91_get_clk_range(periphclknp, | ||
385 | "atmel,clk-output-range", | ||
386 | &range); | ||
387 | |||
388 | clk = at91_clk_register_sam9x5_peripheral(pmc, name, | ||
389 | parent_name, | ||
390 | id, &range); | ||
391 | } | ||
392 | |||
393 | if (IS_ERR(clk)) | ||
394 | continue; | ||
395 | |||
396 | of_clk_add_provider(periphclknp, of_clk_src_simple_get, clk); | ||
397 | } | ||
398 | } | ||
399 | |||
400 | void __init of_at91rm9200_clk_periph_setup(struct device_node *np, | ||
401 | struct at91_pmc *pmc) | ||
402 | { | ||
403 | of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91RM9200); | ||
404 | } | ||
405 | |||
406 | void __init of_at91sam9x5_clk_periph_setup(struct device_node *np, | ||
407 | struct at91_pmc *pmc) | ||
408 | { | ||
409 | of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91SAM9X5); | ||
410 | } | ||
diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c new file mode 100644 index 000000000000..cf6ed023504c --- /dev/null +++ b/drivers/clk/at91/clk-pll.c | |||
@@ -0,0 +1,531 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/wait.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/irq.h> | ||
22 | |||
23 | #include "pmc.h" | ||
24 | |||
25 | #define PLL_STATUS_MASK(id) (1 << (1 + (id))) | ||
26 | #define PLL_REG(id) (AT91_CKGR_PLLAR + ((id) * 4)) | ||
27 | #define PLL_DIV_MASK 0xff | ||
28 | #define PLL_DIV_MAX PLL_DIV_MASK | ||
29 | #define PLL_DIV(reg) ((reg) & PLL_DIV_MASK) | ||
30 | #define PLL_MUL(reg, layout) (((reg) >> (layout)->mul_shift) & \ | ||
31 | (layout)->mul_mask) | ||
32 | #define PLL_ICPR_SHIFT(id) ((id) * 16) | ||
33 | #define PLL_ICPR_MASK(id) (0xffff << PLL_ICPR_SHIFT(id)) | ||
34 | #define PLL_MAX_COUNT 0x3ff | ||
35 | #define PLL_COUNT_SHIFT 8 | ||
36 | #define PLL_OUT_SHIFT 14 | ||
37 | #define PLL_MAX_ID 1 | ||
38 | |||
39 | struct clk_pll_characteristics { | ||
40 | struct clk_range input; | ||
41 | int num_output; | ||
42 | struct clk_range *output; | ||
43 | u16 *icpll; | ||
44 | u8 *out; | ||
45 | }; | ||
46 | |||
47 | struct clk_pll_layout { | ||
48 | u32 pllr_mask; | ||
49 | u16 mul_mask; | ||
50 | u8 mul_shift; | ||
51 | }; | ||
52 | |||
53 | #define to_clk_pll(hw) container_of(hw, struct clk_pll, hw) | ||
54 | |||
55 | struct clk_pll { | ||
56 | struct clk_hw hw; | ||
57 | struct at91_pmc *pmc; | ||
58 | unsigned int irq; | ||
59 | wait_queue_head_t wait; | ||
60 | u8 id; | ||
61 | u8 div; | ||
62 | u8 range; | ||
63 | u16 mul; | ||
64 | const struct clk_pll_layout *layout; | ||
65 | const struct clk_pll_characteristics *characteristics; | ||
66 | }; | ||
67 | |||
68 | static irqreturn_t clk_pll_irq_handler(int irq, void *dev_id) | ||
69 | { | ||
70 | struct clk_pll *pll = (struct clk_pll *)dev_id; | ||
71 | |||
72 | wake_up(&pll->wait); | ||
73 | disable_irq_nosync(pll->irq); | ||
74 | |||
75 | return IRQ_HANDLED; | ||
76 | } | ||
77 | |||
78 | static int clk_pll_prepare(struct clk_hw *hw) | ||
79 | { | ||
80 | struct clk_pll *pll = to_clk_pll(hw); | ||
81 | struct at91_pmc *pmc = pll->pmc; | ||
82 | const struct clk_pll_layout *layout = pll->layout; | ||
83 | const struct clk_pll_characteristics *characteristics = | ||
84 | pll->characteristics; | ||
85 | u8 id = pll->id; | ||
86 | u32 mask = PLL_STATUS_MASK(id); | ||
87 | int offset = PLL_REG(id); | ||
88 | u8 out = 0; | ||
89 | u32 pllr, icpr; | ||
90 | u8 div; | ||
91 | u16 mul; | ||
92 | |||
93 | pllr = pmc_read(pmc, offset); | ||
94 | div = PLL_DIV(pllr); | ||
95 | mul = PLL_MUL(pllr, layout); | ||
96 | |||
97 | if ((pmc_read(pmc, AT91_PMC_SR) & mask) && | ||
98 | (div == pll->div && mul == pll->mul)) | ||
99 | return 0; | ||
100 | |||
101 | if (characteristics->out) | ||
102 | out = characteristics->out[pll->range]; | ||
103 | if (characteristics->icpll) { | ||
104 | icpr = pmc_read(pmc, AT91_PMC_PLLICPR) & ~PLL_ICPR_MASK(id); | ||
105 | icpr |= (characteristics->icpll[pll->range] << | ||
106 | PLL_ICPR_SHIFT(id)); | ||
107 | pmc_write(pmc, AT91_PMC_PLLICPR, icpr); | ||
108 | } | ||
109 | |||
110 | pllr &= ~layout->pllr_mask; | ||
111 | pllr |= layout->pllr_mask & | ||
112 | (pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) | | ||
113 | (out << PLL_OUT_SHIFT) | | ||
114 | ((pll->mul & layout->mul_mask) << layout->mul_shift)); | ||
115 | pmc_write(pmc, offset, pllr); | ||
116 | |||
117 | while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) { | ||
118 | enable_irq(pll->irq); | ||
119 | wait_event(pll->wait, | ||
120 | pmc_read(pmc, AT91_PMC_SR) & mask); | ||
121 | } | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int clk_pll_is_prepared(struct clk_hw *hw) | ||
127 | { | ||
128 | struct clk_pll *pll = to_clk_pll(hw); | ||
129 | struct at91_pmc *pmc = pll->pmc; | ||
130 | |||
131 | return !!(pmc_read(pmc, AT91_PMC_SR) & | ||
132 | PLL_STATUS_MASK(pll->id)); | ||
133 | } | ||
134 | |||
135 | static void clk_pll_unprepare(struct clk_hw *hw) | ||
136 | { | ||
137 | struct clk_pll *pll = to_clk_pll(hw); | ||
138 | struct at91_pmc *pmc = pll->pmc; | ||
139 | const struct clk_pll_layout *layout = pll->layout; | ||
140 | int offset = PLL_REG(pll->id); | ||
141 | u32 tmp = pmc_read(pmc, offset) & ~(layout->pllr_mask); | ||
142 | |||
143 | pmc_write(pmc, offset, tmp); | ||
144 | } | ||
145 | |||
146 | static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | ||
147 | unsigned long parent_rate) | ||
148 | { | ||
149 | struct clk_pll *pll = to_clk_pll(hw); | ||
150 | const struct clk_pll_layout *layout = pll->layout; | ||
151 | struct at91_pmc *pmc = pll->pmc; | ||
152 | int offset = PLL_REG(pll->id); | ||
153 | u32 tmp = pmc_read(pmc, offset) & layout->pllr_mask; | ||
154 | u8 div = PLL_DIV(tmp); | ||
155 | u16 mul = PLL_MUL(tmp, layout); | ||
156 | if (!div || !mul) | ||
157 | return 0; | ||
158 | |||
159 | return (parent_rate * (mul + 1)) / div; | ||
160 | } | ||
161 | |||
162 | static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, | ||
163 | unsigned long parent_rate, | ||
164 | u32 *div, u32 *mul, | ||
165 | u32 *index) { | ||
166 | unsigned long maxrate; | ||
167 | unsigned long minrate; | ||
168 | unsigned long divrate; | ||
169 | unsigned long bestdiv = 1; | ||
170 | unsigned long bestmul; | ||
171 | unsigned long tmpdiv; | ||
172 | unsigned long roundup; | ||
173 | unsigned long rounddown; | ||
174 | unsigned long remainder; | ||
175 | unsigned long bestremainder; | ||
176 | unsigned long maxmul; | ||
177 | unsigned long maxdiv; | ||
178 | unsigned long mindiv; | ||
179 | int i = 0; | ||
180 | const struct clk_pll_layout *layout = pll->layout; | ||
181 | const struct clk_pll_characteristics *characteristics = | ||
182 | pll->characteristics; | ||
183 | |||
184 | /* Minimum divider = 1 */ | ||
185 | /* Maximum multiplier = max_mul */ | ||
186 | maxmul = layout->mul_mask + 1; | ||
187 | maxrate = (parent_rate * maxmul) / 1; | ||
188 | |||
189 | /* Maximum divider = max_div */ | ||
190 | /* Minimum multiplier = 2 */ | ||
191 | maxdiv = PLL_DIV_MAX; | ||
192 | minrate = (parent_rate * 2) / maxdiv; | ||
193 | |||
194 | if (parent_rate < characteristics->input.min || | ||
195 | parent_rate < characteristics->input.max) | ||
196 | return -ERANGE; | ||
197 | |||
198 | if (parent_rate < minrate || parent_rate > maxrate) | ||
199 | return -ERANGE; | ||
200 | |||
201 | for (i = 0; i < characteristics->num_output; i++) { | ||
202 | if (parent_rate >= characteristics->output[i].min && | ||
203 | parent_rate <= characteristics->output[i].max) | ||
204 | break; | ||
205 | } | ||
206 | |||
207 | if (i >= characteristics->num_output) | ||
208 | return -ERANGE; | ||
209 | |||
210 | bestmul = rate / parent_rate; | ||
211 | rounddown = parent_rate % rate; | ||
212 | roundup = rate - rounddown; | ||
213 | bestremainder = roundup < rounddown ? roundup : rounddown; | ||
214 | |||
215 | if (!bestremainder) { | ||
216 | if (div) | ||
217 | *div = bestdiv; | ||
218 | if (mul) | ||
219 | *mul = bestmul; | ||
220 | if (index) | ||
221 | *index = i; | ||
222 | return rate; | ||
223 | } | ||
224 | |||
225 | maxdiv = 255 / (bestmul + 1); | ||
226 | if (parent_rate / maxdiv < characteristics->input.min) | ||
227 | maxdiv = parent_rate / characteristics->input.min; | ||
228 | mindiv = parent_rate / characteristics->input.max; | ||
229 | if (parent_rate % characteristics->input.max) | ||
230 | mindiv++; | ||
231 | |||
232 | for (tmpdiv = mindiv; tmpdiv < maxdiv; tmpdiv++) { | ||
233 | divrate = parent_rate / tmpdiv; | ||
234 | |||
235 | rounddown = rate % divrate; | ||
236 | roundup = divrate - rounddown; | ||
237 | remainder = roundup < rounddown ? roundup : rounddown; | ||
238 | |||
239 | if (remainder < bestremainder) { | ||
240 | bestremainder = remainder; | ||
241 | bestmul = rate / divrate; | ||
242 | bestdiv = tmpdiv; | ||
243 | } | ||
244 | |||
245 | if (!remainder) | ||
246 | break; | ||
247 | } | ||
248 | |||
249 | rate = (parent_rate / bestdiv) * bestmul; | ||
250 | |||
251 | if (div) | ||
252 | *div = bestdiv; | ||
253 | if (mul) | ||
254 | *mul = bestmul; | ||
255 | if (index) | ||
256 | *index = i; | ||
257 | |||
258 | return rate; | ||
259 | } | ||
260 | |||
261 | static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
262 | unsigned long *parent_rate) | ||
263 | { | ||
264 | struct clk_pll *pll = to_clk_pll(hw); | ||
265 | |||
266 | return clk_pll_get_best_div_mul(pll, rate, *parent_rate, | ||
267 | NULL, NULL, NULL); | ||
268 | } | ||
269 | |||
270 | static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
271 | unsigned long parent_rate) | ||
272 | { | ||
273 | struct clk_pll *pll = to_clk_pll(hw); | ||
274 | long ret; | ||
275 | u32 div; | ||
276 | u32 mul; | ||
277 | u32 index; | ||
278 | |||
279 | ret = clk_pll_get_best_div_mul(pll, rate, parent_rate, | ||
280 | &div, &mul, &index); | ||
281 | if (ret < 0) | ||
282 | return ret; | ||
283 | |||
284 | pll->range = index; | ||
285 | pll->div = div; | ||
286 | pll->mul = mul; | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static const struct clk_ops pll_ops = { | ||
292 | .prepare = clk_pll_prepare, | ||
293 | .unprepare = clk_pll_unprepare, | ||
294 | .is_prepared = clk_pll_is_prepared, | ||
295 | .recalc_rate = clk_pll_recalc_rate, | ||
296 | .round_rate = clk_pll_round_rate, | ||
297 | .set_rate = clk_pll_set_rate, | ||
298 | }; | ||
299 | |||
300 | static struct clk * __init | ||
301 | at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name, | ||
302 | const char *parent_name, u8 id, | ||
303 | const struct clk_pll_layout *layout, | ||
304 | const struct clk_pll_characteristics *characteristics) | ||
305 | { | ||
306 | struct clk_pll *pll; | ||
307 | struct clk *clk = NULL; | ||
308 | struct clk_init_data init; | ||
309 | int ret; | ||
310 | int offset = PLL_REG(id); | ||
311 | u32 tmp; | ||
312 | |||
313 | if (id > PLL_MAX_ID) | ||
314 | return ERR_PTR(-EINVAL); | ||
315 | |||
316 | pll = kzalloc(sizeof(*pll), GFP_KERNEL); | ||
317 | if (!pll) | ||
318 | return ERR_PTR(-ENOMEM); | ||
319 | |||
320 | init.name = name; | ||
321 | init.ops = &pll_ops; | ||
322 | init.parent_names = &parent_name; | ||
323 | init.num_parents = 1; | ||
324 | init.flags = CLK_SET_RATE_GATE; | ||
325 | |||
326 | pll->id = id; | ||
327 | pll->hw.init = &init; | ||
328 | pll->layout = layout; | ||
329 | pll->characteristics = characteristics; | ||
330 | pll->pmc = pmc; | ||
331 | pll->irq = irq; | ||
332 | tmp = pmc_read(pmc, offset) & layout->pllr_mask; | ||
333 | pll->div = PLL_DIV(tmp); | ||
334 | pll->mul = PLL_MUL(tmp, layout); | ||
335 | init_waitqueue_head(&pll->wait); | ||
336 | irq_set_status_flags(pll->irq, IRQ_NOAUTOEN); | ||
337 | ret = request_irq(pll->irq, clk_pll_irq_handler, IRQF_TRIGGER_HIGH, | ||
338 | id ? "clk-pllb" : "clk-plla", pll); | ||
339 | if (ret) | ||
340 | return ERR_PTR(ret); | ||
341 | |||
342 | clk = clk_register(NULL, &pll->hw); | ||
343 | if (IS_ERR(clk)) | ||
344 | kfree(pll); | ||
345 | |||
346 | return clk; | ||
347 | } | ||
348 | |||
349 | |||
350 | static const struct clk_pll_layout at91rm9200_pll_layout = { | ||
351 | .pllr_mask = 0x7FFFFFF, | ||
352 | .mul_shift = 16, | ||
353 | .mul_mask = 0x7FF, | ||
354 | }; | ||
355 | |||
356 | static const struct clk_pll_layout at91sam9g45_pll_layout = { | ||
357 | .pllr_mask = 0xFFFFFF, | ||
358 | .mul_shift = 16, | ||
359 | .mul_mask = 0xFF, | ||
360 | }; | ||
361 | |||
362 | static const struct clk_pll_layout at91sam9g20_pllb_layout = { | ||
363 | .pllr_mask = 0x3FFFFF, | ||
364 | .mul_shift = 16, | ||
365 | .mul_mask = 0x3F, | ||
366 | }; | ||
367 | |||
368 | static const struct clk_pll_layout sama5d3_pll_layout = { | ||
369 | .pllr_mask = 0x1FFFFFF, | ||
370 | .mul_shift = 18, | ||
371 | .mul_mask = 0x7F, | ||
372 | }; | ||
373 | |||
374 | |||
375 | static struct clk_pll_characteristics * __init | ||
376 | of_at91_clk_pll_get_characteristics(struct device_node *np) | ||
377 | { | ||
378 | int i; | ||
379 | int offset; | ||
380 | u32 tmp; | ||
381 | int num_output; | ||
382 | u32 num_cells; | ||
383 | struct clk_range input; | ||
384 | struct clk_range *output; | ||
385 | u8 *out = NULL; | ||
386 | u16 *icpll = NULL; | ||
387 | struct clk_pll_characteristics *characteristics; | ||
388 | |||
389 | if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input)) | ||
390 | return NULL; | ||
391 | |||
392 | if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells", | ||
393 | &num_cells)) | ||
394 | return NULL; | ||
395 | |||
396 | if (num_cells < 2 || num_cells > 4) | ||
397 | return NULL; | ||
398 | |||
399 | if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp)) | ||
400 | return NULL; | ||
401 | num_output = tmp / (sizeof(u32) * num_cells); | ||
402 | |||
403 | characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL); | ||
404 | if (!characteristics) | ||
405 | return NULL; | ||
406 | |||
407 | output = kzalloc(sizeof(*output) * num_output, GFP_KERNEL); | ||
408 | if (!output) | ||
409 | goto out_free_characteristics; | ||
410 | |||
411 | if (num_cells > 2) { | ||
412 | out = kzalloc(sizeof(*out) * num_output, GFP_KERNEL); | ||
413 | if (!out) | ||
414 | goto out_free_output; | ||
415 | } | ||
416 | |||
417 | if (num_cells > 3) { | ||
418 | icpll = kzalloc(sizeof(*icpll) * num_output, GFP_KERNEL); | ||
419 | if (!icpll) | ||
420 | goto out_free_output; | ||
421 | } | ||
422 | |||
423 | for (i = 0; i < num_output; i++) { | ||
424 | offset = i * num_cells; | ||
425 | if (of_property_read_u32_index(np, | ||
426 | "atmel,pll-clk-output-ranges", | ||
427 | offset, &tmp)) | ||
428 | goto out_free_output; | ||
429 | output[i].min = tmp; | ||
430 | if (of_property_read_u32_index(np, | ||
431 | "atmel,pll-clk-output-ranges", | ||
432 | offset + 1, &tmp)) | ||
433 | goto out_free_output; | ||
434 | output[i].max = tmp; | ||
435 | |||
436 | if (num_cells == 2) | ||
437 | continue; | ||
438 | |||
439 | if (of_property_read_u32_index(np, | ||
440 | "atmel,pll-clk-output-ranges", | ||
441 | offset + 2, &tmp)) | ||
442 | goto out_free_output; | ||
443 | out[i] = tmp; | ||
444 | |||
445 | if (num_cells == 3) | ||
446 | continue; | ||
447 | |||
448 | if (of_property_read_u32_index(np, | ||
449 | "atmel,pll-clk-output-ranges", | ||
450 | offset + 3, &tmp)) | ||
451 | goto out_free_output; | ||
452 | icpll[i] = tmp; | ||
453 | } | ||
454 | |||
455 | characteristics->input = input; | ||
456 | characteristics->num_output = num_output; | ||
457 | characteristics->output = output; | ||
458 | characteristics->out = out; | ||
459 | characteristics->icpll = icpll; | ||
460 | return characteristics; | ||
461 | |||
462 | out_free_output: | ||
463 | kfree(icpll); | ||
464 | kfree(out); | ||
465 | kfree(output); | ||
466 | out_free_characteristics: | ||
467 | kfree(characteristics); | ||
468 | return NULL; | ||
469 | } | ||
470 | |||
471 | static void __init | ||
472 | of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc, | ||
473 | const struct clk_pll_layout *layout) | ||
474 | { | ||
475 | u32 id; | ||
476 | unsigned int irq; | ||
477 | struct clk *clk; | ||
478 | const char *parent_name; | ||
479 | const char *name = np->name; | ||
480 | struct clk_pll_characteristics *characteristics; | ||
481 | |||
482 | if (of_property_read_u32(np, "reg", &id)) | ||
483 | return; | ||
484 | |||
485 | parent_name = of_clk_get_parent_name(np, 0); | ||
486 | |||
487 | of_property_read_string(np, "clock-output-names", &name); | ||
488 | |||
489 | characteristics = of_at91_clk_pll_get_characteristics(np); | ||
490 | if (!characteristics) | ||
491 | return; | ||
492 | |||
493 | irq = irq_of_parse_and_map(np, 0); | ||
494 | if (!irq) | ||
495 | return; | ||
496 | |||
497 | clk = at91_clk_register_pll(pmc, irq, name, parent_name, id, layout, | ||
498 | characteristics); | ||
499 | if (IS_ERR(clk)) | ||
500 | goto out_free_characteristics; | ||
501 | |||
502 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
503 | return; | ||
504 | |||
505 | out_free_characteristics: | ||
506 | kfree(characteristics); | ||
507 | } | ||
508 | |||
509 | void __init of_at91rm9200_clk_pll_setup(struct device_node *np, | ||
510 | struct at91_pmc *pmc) | ||
511 | { | ||
512 | of_at91_clk_pll_setup(np, pmc, &at91rm9200_pll_layout); | ||
513 | } | ||
514 | |||
515 | void __init of_at91sam9g45_clk_pll_setup(struct device_node *np, | ||
516 | struct at91_pmc *pmc) | ||
517 | { | ||
518 | of_at91_clk_pll_setup(np, pmc, &at91sam9g45_pll_layout); | ||
519 | } | ||
520 | |||
521 | void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np, | ||
522 | struct at91_pmc *pmc) | ||
523 | { | ||
524 | of_at91_clk_pll_setup(np, pmc, &at91sam9g20_pllb_layout); | ||
525 | } | ||
526 | |||
527 | void __init of_sama5d3_clk_pll_setup(struct device_node *np, | ||
528 | struct at91_pmc *pmc) | ||
529 | { | ||
530 | of_at91_clk_pll_setup(np, pmc, &sama5d3_pll_layout); | ||
531 | } | ||
diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c new file mode 100644 index 000000000000..ea226562bb40 --- /dev/null +++ b/drivers/clk/at91/clk-plldiv.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | #include "pmc.h" | ||
19 | |||
20 | #define to_clk_plldiv(hw) container_of(hw, struct clk_plldiv, hw) | ||
21 | |||
22 | struct clk_plldiv { | ||
23 | struct clk_hw hw; | ||
24 | struct at91_pmc *pmc; | ||
25 | }; | ||
26 | |||
27 | static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw, | ||
28 | unsigned long parent_rate) | ||
29 | { | ||
30 | struct clk_plldiv *plldiv = to_clk_plldiv(hw); | ||
31 | struct at91_pmc *pmc = plldiv->pmc; | ||
32 | |||
33 | if (pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_PLLADIV2) | ||
34 | return parent_rate / 2; | ||
35 | |||
36 | return parent_rate; | ||
37 | } | ||
38 | |||
39 | static long clk_plldiv_round_rate(struct clk_hw *hw, unsigned long rate, | ||
40 | unsigned long *parent_rate) | ||
41 | { | ||
42 | unsigned long div; | ||
43 | |||
44 | if (rate > *parent_rate) | ||
45 | return *parent_rate; | ||
46 | div = *parent_rate / 2; | ||
47 | if (rate < div) | ||
48 | return div; | ||
49 | |||
50 | if (rate - div < *parent_rate - rate) | ||
51 | return div; | ||
52 | |||
53 | return *parent_rate; | ||
54 | } | ||
55 | |||
56 | static int clk_plldiv_set_rate(struct clk_hw *hw, unsigned long rate, | ||
57 | unsigned long parent_rate) | ||
58 | { | ||
59 | struct clk_plldiv *plldiv = to_clk_plldiv(hw); | ||
60 | struct at91_pmc *pmc = plldiv->pmc; | ||
61 | u32 tmp; | ||
62 | |||
63 | if (parent_rate != rate && (parent_rate / 2) != rate) | ||
64 | return -EINVAL; | ||
65 | |||
66 | pmc_lock(pmc); | ||
67 | tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_PLLADIV2; | ||
68 | if ((parent_rate / 2) == rate) | ||
69 | tmp |= AT91_PMC_PLLADIV2; | ||
70 | pmc_write(pmc, AT91_PMC_MCKR, tmp); | ||
71 | pmc_unlock(pmc); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static const struct clk_ops plldiv_ops = { | ||
77 | .recalc_rate = clk_plldiv_recalc_rate, | ||
78 | .round_rate = clk_plldiv_round_rate, | ||
79 | .set_rate = clk_plldiv_set_rate, | ||
80 | }; | ||
81 | |||
82 | static struct clk * __init | ||
83 | at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name, | ||
84 | const char *parent_name) | ||
85 | { | ||
86 | struct clk_plldiv *plldiv; | ||
87 | struct clk *clk = NULL; | ||
88 | struct clk_init_data init; | ||
89 | |||
90 | plldiv = kzalloc(sizeof(*plldiv), GFP_KERNEL); | ||
91 | if (!plldiv) | ||
92 | return ERR_PTR(-ENOMEM); | ||
93 | |||
94 | init.name = name; | ||
95 | init.ops = &plldiv_ops; | ||
96 | init.parent_names = parent_name ? &parent_name : NULL; | ||
97 | init.num_parents = parent_name ? 1 : 0; | ||
98 | init.flags = CLK_SET_RATE_GATE; | ||
99 | |||
100 | plldiv->hw.init = &init; | ||
101 | plldiv->pmc = pmc; | ||
102 | |||
103 | clk = clk_register(NULL, &plldiv->hw); | ||
104 | |||
105 | if (IS_ERR(clk)) | ||
106 | kfree(plldiv); | ||
107 | |||
108 | return clk; | ||
109 | } | ||
110 | |||
111 | static void __init | ||
112 | of_at91_clk_plldiv_setup(struct device_node *np, struct at91_pmc *pmc) | ||
113 | { | ||
114 | struct clk *clk; | ||
115 | const char *parent_name; | ||
116 | const char *name = np->name; | ||
117 | |||
118 | parent_name = of_clk_get_parent_name(np, 0); | ||
119 | |||
120 | of_property_read_string(np, "clock-output-names", &name); | ||
121 | |||
122 | clk = at91_clk_register_plldiv(pmc, name, parent_name); | ||
123 | |||
124 | if (IS_ERR(clk)) | ||
125 | return; | ||
126 | |||
127 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
128 | return; | ||
129 | } | ||
130 | |||
131 | void __init of_at91sam9x5_clk_plldiv_setup(struct device_node *np, | ||
132 | struct at91_pmc *pmc) | ||
133 | { | ||
134 | of_at91_clk_plldiv_setup(np, pmc); | ||
135 | } | ||
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c new file mode 100644 index 000000000000..fd792b203eaf --- /dev/null +++ b/drivers/clk/at91/clk-programmable.c | |||
@@ -0,0 +1,366 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/wait.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/irq.h> | ||
22 | |||
23 | #include "pmc.h" | ||
24 | |||
25 | #define PROG_SOURCE_MAX 5 | ||
26 | #define PROG_ID_MAX 7 | ||
27 | |||
28 | #define PROG_STATUS_MASK(id) (1 << ((id) + 8)) | ||
29 | #define PROG_PRES_MASK 0x7 | ||
30 | #define PROG_MAX_RM9200_CSS 3 | ||
31 | |||
32 | struct clk_programmable_layout { | ||
33 | u8 pres_shift; | ||
34 | u8 css_mask; | ||
35 | u8 have_slck_mck; | ||
36 | }; | ||
37 | |||
38 | struct clk_programmable { | ||
39 | struct clk_hw hw; | ||
40 | struct at91_pmc *pmc; | ||
41 | unsigned int irq; | ||
42 | wait_queue_head_t wait; | ||
43 | u8 id; | ||
44 | u8 css; | ||
45 | u8 pres; | ||
46 | u8 slckmck; | ||
47 | const struct clk_programmable_layout *layout; | ||
48 | }; | ||
49 | |||
50 | #define to_clk_programmable(hw) container_of(hw, struct clk_programmable, hw) | ||
51 | |||
52 | |||
53 | static irqreturn_t clk_programmable_irq_handler(int irq, void *dev_id) | ||
54 | { | ||
55 | struct clk_programmable *prog = (struct clk_programmable *)dev_id; | ||
56 | |||
57 | wake_up(&prog->wait); | ||
58 | |||
59 | return IRQ_HANDLED; | ||
60 | } | ||
61 | |||
62 | static int clk_programmable_prepare(struct clk_hw *hw) | ||
63 | { | ||
64 | u32 tmp; | ||
65 | struct clk_programmable *prog = to_clk_programmable(hw); | ||
66 | struct at91_pmc *pmc = prog->pmc; | ||
67 | const struct clk_programmable_layout *layout = prog->layout; | ||
68 | u8 id = prog->id; | ||
69 | u32 mask = PROG_STATUS_MASK(id); | ||
70 | |||
71 | tmp = prog->css | (prog->pres << layout->pres_shift); | ||
72 | if (layout->have_slck_mck && prog->slckmck) | ||
73 | tmp |= AT91_PMC_CSSMCK_MCK; | ||
74 | |||
75 | pmc_write(pmc, AT91_PMC_PCKR(id), tmp); | ||
76 | |||
77 | while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) | ||
78 | wait_event(prog->wait, pmc_read(pmc, AT91_PMC_SR) & mask); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int clk_programmable_is_ready(struct clk_hw *hw) | ||
84 | { | ||
85 | struct clk_programmable *prog = to_clk_programmable(hw); | ||
86 | struct at91_pmc *pmc = prog->pmc; | ||
87 | |||
88 | return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_PCKR(prog->id)); | ||
89 | } | ||
90 | |||
91 | static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw, | ||
92 | unsigned long parent_rate) | ||
93 | { | ||
94 | u32 tmp; | ||
95 | struct clk_programmable *prog = to_clk_programmable(hw); | ||
96 | struct at91_pmc *pmc = prog->pmc; | ||
97 | const struct clk_programmable_layout *layout = prog->layout; | ||
98 | |||
99 | tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)); | ||
100 | prog->pres = (tmp >> layout->pres_shift) & PROG_PRES_MASK; | ||
101 | |||
102 | return parent_rate >> prog->pres; | ||
103 | } | ||
104 | |||
105 | static long clk_programmable_round_rate(struct clk_hw *hw, unsigned long rate, | ||
106 | unsigned long *parent_rate) | ||
107 | { | ||
108 | unsigned long best_rate = *parent_rate; | ||
109 | unsigned long best_diff; | ||
110 | unsigned long new_diff; | ||
111 | unsigned long cur_rate; | ||
112 | int shift = shift; | ||
113 | |||
114 | if (rate > *parent_rate) | ||
115 | return *parent_rate; | ||
116 | else | ||
117 | best_diff = *parent_rate - rate; | ||
118 | |||
119 | if (!best_diff) | ||
120 | return best_rate; | ||
121 | |||
122 | for (shift = 1; shift < PROG_PRES_MASK; shift++) { | ||
123 | cur_rate = *parent_rate >> shift; | ||
124 | |||
125 | if (cur_rate > rate) | ||
126 | new_diff = cur_rate - rate; | ||
127 | else | ||
128 | new_diff = rate - cur_rate; | ||
129 | |||
130 | if (!new_diff) | ||
131 | return cur_rate; | ||
132 | |||
133 | if (new_diff < best_diff) { | ||
134 | best_diff = new_diff; | ||
135 | best_rate = cur_rate; | ||
136 | } | ||
137 | |||
138 | if (rate > cur_rate) | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | return best_rate; | ||
143 | } | ||
144 | |||
145 | static int clk_programmable_set_parent(struct clk_hw *hw, u8 index) | ||
146 | { | ||
147 | struct clk_programmable *prog = to_clk_programmable(hw); | ||
148 | const struct clk_programmable_layout *layout = prog->layout; | ||
149 | if (index > layout->css_mask) { | ||
150 | if (index > PROG_MAX_RM9200_CSS && layout->have_slck_mck) { | ||
151 | prog->css = 0; | ||
152 | prog->slckmck = 1; | ||
153 | return 0; | ||
154 | } else { | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | prog->css = index; | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static u8 clk_programmable_get_parent(struct clk_hw *hw) | ||
164 | { | ||
165 | u32 tmp; | ||
166 | u8 ret; | ||
167 | struct clk_programmable *prog = to_clk_programmable(hw); | ||
168 | struct at91_pmc *pmc = prog->pmc; | ||
169 | const struct clk_programmable_layout *layout = prog->layout; | ||
170 | |||
171 | tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)); | ||
172 | prog->css = tmp & layout->css_mask; | ||
173 | ret = prog->css; | ||
174 | if (layout->have_slck_mck) { | ||
175 | prog->slckmck = !!(tmp & AT91_PMC_CSSMCK_MCK); | ||
176 | if (prog->slckmck && !ret) | ||
177 | ret = PROG_MAX_RM9200_CSS + 1; | ||
178 | } | ||
179 | |||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate, | ||
184 | unsigned long parent_rate) | ||
185 | { | ||
186 | struct clk_programmable *prog = to_clk_programmable(hw); | ||
187 | unsigned long best_rate = parent_rate; | ||
188 | unsigned long best_diff; | ||
189 | unsigned long new_diff; | ||
190 | unsigned long cur_rate; | ||
191 | int shift = 0; | ||
192 | |||
193 | if (rate > parent_rate) | ||
194 | return parent_rate; | ||
195 | else | ||
196 | best_diff = parent_rate - rate; | ||
197 | |||
198 | if (!best_diff) { | ||
199 | prog->pres = shift; | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | for (shift = 1; shift < PROG_PRES_MASK; shift++) { | ||
204 | cur_rate = parent_rate >> shift; | ||
205 | |||
206 | if (cur_rate > rate) | ||
207 | new_diff = cur_rate - rate; | ||
208 | else | ||
209 | new_diff = rate - cur_rate; | ||
210 | |||
211 | if (!new_diff) | ||
212 | break; | ||
213 | |||
214 | if (new_diff < best_diff) { | ||
215 | best_diff = new_diff; | ||
216 | best_rate = cur_rate; | ||
217 | } | ||
218 | |||
219 | if (rate > cur_rate) | ||
220 | break; | ||
221 | } | ||
222 | |||
223 | prog->pres = shift; | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static const struct clk_ops programmable_ops = { | ||
228 | .prepare = clk_programmable_prepare, | ||
229 | .is_prepared = clk_programmable_is_ready, | ||
230 | .recalc_rate = clk_programmable_recalc_rate, | ||
231 | .round_rate = clk_programmable_round_rate, | ||
232 | .get_parent = clk_programmable_get_parent, | ||
233 | .set_parent = clk_programmable_set_parent, | ||
234 | .set_rate = clk_programmable_set_rate, | ||
235 | }; | ||
236 | |||
237 | static struct clk * __init | ||
238 | at91_clk_register_programmable(struct at91_pmc *pmc, unsigned int irq, | ||
239 | const char *name, const char **parent_names, | ||
240 | u8 num_parents, u8 id, | ||
241 | const struct clk_programmable_layout *layout) | ||
242 | { | ||
243 | int ret; | ||
244 | struct clk_programmable *prog; | ||
245 | struct clk *clk = NULL; | ||
246 | struct clk_init_data init; | ||
247 | char irq_name[11]; | ||
248 | |||
249 | if (id > PROG_ID_MAX) | ||
250 | return ERR_PTR(-EINVAL); | ||
251 | |||
252 | prog = kzalloc(sizeof(*prog), GFP_KERNEL); | ||
253 | if (!prog) | ||
254 | return ERR_PTR(-ENOMEM); | ||
255 | |||
256 | init.name = name; | ||
257 | init.ops = &programmable_ops; | ||
258 | init.parent_names = parent_names; | ||
259 | init.num_parents = num_parents; | ||
260 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; | ||
261 | |||
262 | prog->id = id; | ||
263 | prog->layout = layout; | ||
264 | prog->hw.init = &init; | ||
265 | prog->pmc = pmc; | ||
266 | prog->irq = irq; | ||
267 | init_waitqueue_head(&prog->wait); | ||
268 | irq_set_status_flags(prog->irq, IRQ_NOAUTOEN); | ||
269 | snprintf(irq_name, sizeof(irq_name), "clk-prog%d", id); | ||
270 | ret = request_irq(prog->irq, clk_programmable_irq_handler, | ||
271 | IRQF_TRIGGER_HIGH, irq_name, prog); | ||
272 | if (ret) | ||
273 | return ERR_PTR(ret); | ||
274 | |||
275 | clk = clk_register(NULL, &prog->hw); | ||
276 | if (IS_ERR(clk)) | ||
277 | kfree(prog); | ||
278 | |||
279 | return clk; | ||
280 | } | ||
281 | |||
282 | static const struct clk_programmable_layout at91rm9200_programmable_layout = { | ||
283 | .pres_shift = 2, | ||
284 | .css_mask = 0x3, | ||
285 | .have_slck_mck = 0, | ||
286 | }; | ||
287 | |||
288 | static const struct clk_programmable_layout at91sam9g45_programmable_layout = { | ||
289 | .pres_shift = 2, | ||
290 | .css_mask = 0x3, | ||
291 | .have_slck_mck = 1, | ||
292 | }; | ||
293 | |||
294 | static const struct clk_programmable_layout at91sam9x5_programmable_layout = { | ||
295 | .pres_shift = 4, | ||
296 | .css_mask = 0x7, | ||
297 | .have_slck_mck = 0, | ||
298 | }; | ||
299 | |||
300 | static void __init | ||
301 | of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, | ||
302 | const struct clk_programmable_layout *layout) | ||
303 | { | ||
304 | int num; | ||
305 | u32 id; | ||
306 | int i; | ||
307 | unsigned int irq; | ||
308 | struct clk *clk; | ||
309 | int num_parents; | ||
310 | const char *parent_names[PROG_SOURCE_MAX]; | ||
311 | const char *name; | ||
312 | struct device_node *progclknp; | ||
313 | |||
314 | num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); | ||
315 | if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX) | ||
316 | return; | ||
317 | |||
318 | for (i = 0; i < num_parents; ++i) { | ||
319 | parent_names[i] = of_clk_get_parent_name(np, i); | ||
320 | if (!parent_names[i]) | ||
321 | return; | ||
322 | } | ||
323 | |||
324 | num = of_get_child_count(np); | ||
325 | if (!num || num > (PROG_ID_MAX + 1)) | ||
326 | return; | ||
327 | |||
328 | for_each_child_of_node(np, progclknp) { | ||
329 | if (of_property_read_u32(progclknp, "reg", &id)) | ||
330 | continue; | ||
331 | |||
332 | if (of_property_read_string(np, "clock-output-names", &name)) | ||
333 | name = progclknp->name; | ||
334 | |||
335 | irq = irq_of_parse_and_map(progclknp, 0); | ||
336 | if (!irq) | ||
337 | continue; | ||
338 | |||
339 | clk = at91_clk_register_programmable(pmc, irq, name, | ||
340 | parent_names, num_parents, | ||
341 | id, layout); | ||
342 | if (IS_ERR(clk)) | ||
343 | continue; | ||
344 | |||
345 | of_clk_add_provider(progclknp, of_clk_src_simple_get, clk); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | |||
350 | void __init of_at91rm9200_clk_prog_setup(struct device_node *np, | ||
351 | struct at91_pmc *pmc) | ||
352 | { | ||
353 | of_at91_clk_prog_setup(np, pmc, &at91rm9200_programmable_layout); | ||
354 | } | ||
355 | |||
356 | void __init of_at91sam9g45_clk_prog_setup(struct device_node *np, | ||
357 | struct at91_pmc *pmc) | ||
358 | { | ||
359 | of_at91_clk_prog_setup(np, pmc, &at91sam9g45_programmable_layout); | ||
360 | } | ||
361 | |||
362 | void __init of_at91sam9x5_clk_prog_setup(struct device_node *np, | ||
363 | struct at91_pmc *pmc) | ||
364 | { | ||
365 | of_at91_clk_prog_setup(np, pmc, &at91sam9x5_programmable_layout); | ||
366 | } | ||
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c new file mode 100644 index 000000000000..144d47ecfe63 --- /dev/null +++ b/drivers/clk/at91/clk-smd.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | #include "pmc.h" | ||
19 | |||
20 | #define SMD_SOURCE_MAX 2 | ||
21 | |||
22 | #define SMD_DIV_SHIFT 8 | ||
23 | #define SMD_MAX_DIV 0xf | ||
24 | |||
25 | struct at91sam9x5_clk_smd { | ||
26 | struct clk_hw hw; | ||
27 | struct at91_pmc *pmc; | ||
28 | }; | ||
29 | |||
30 | #define to_at91sam9x5_clk_smd(hw) \ | ||
31 | container_of(hw, struct at91sam9x5_clk_smd, hw) | ||
32 | |||
33 | static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw, | ||
34 | unsigned long parent_rate) | ||
35 | { | ||
36 | u32 tmp; | ||
37 | u8 smddiv; | ||
38 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); | ||
39 | struct at91_pmc *pmc = smd->pmc; | ||
40 | |||
41 | tmp = pmc_read(pmc, AT91_PMC_SMD); | ||
42 | smddiv = (tmp & AT91_PMC_SMD_DIV) >> SMD_DIV_SHIFT; | ||
43 | return parent_rate / (smddiv + 1); | ||
44 | } | ||
45 | |||
46 | static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long rate, | ||
47 | unsigned long *parent_rate) | ||
48 | { | ||
49 | unsigned long div; | ||
50 | unsigned long bestrate; | ||
51 | unsigned long tmp; | ||
52 | |||
53 | if (rate >= *parent_rate) | ||
54 | return *parent_rate; | ||
55 | |||
56 | div = *parent_rate / rate; | ||
57 | if (div > SMD_MAX_DIV) | ||
58 | return *parent_rate / (SMD_MAX_DIV + 1); | ||
59 | |||
60 | bestrate = *parent_rate / div; | ||
61 | tmp = *parent_rate / (div + 1); | ||
62 | if (bestrate - rate > rate - tmp) | ||
63 | bestrate = tmp; | ||
64 | |||
65 | return bestrate; | ||
66 | } | ||
67 | |||
68 | static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index) | ||
69 | { | ||
70 | u32 tmp; | ||
71 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); | ||
72 | struct at91_pmc *pmc = smd->pmc; | ||
73 | |||
74 | if (index > 1) | ||
75 | return -EINVAL; | ||
76 | tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMDS; | ||
77 | if (index) | ||
78 | tmp |= AT91_PMC_SMDS; | ||
79 | pmc_write(pmc, AT91_PMC_SMD, tmp); | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static u8 at91sam9x5_clk_smd_get_parent(struct clk_hw *hw) | ||
84 | { | ||
85 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); | ||
86 | struct at91_pmc *pmc = smd->pmc; | ||
87 | |||
88 | return pmc_read(pmc, AT91_PMC_SMD) & AT91_PMC_SMDS; | ||
89 | } | ||
90 | |||
91 | static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate, | ||
92 | unsigned long parent_rate) | ||
93 | { | ||
94 | u32 tmp; | ||
95 | struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); | ||
96 | struct at91_pmc *pmc = smd->pmc; | ||
97 | unsigned long div = parent_rate / rate; | ||
98 | |||
99 | if (parent_rate % rate || div < 1 || div > (SMD_MAX_DIV + 1)) | ||
100 | return -EINVAL; | ||
101 | tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMD_DIV; | ||
102 | tmp |= (div - 1) << SMD_DIV_SHIFT; | ||
103 | pmc_write(pmc, AT91_PMC_SMD, tmp); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static const struct clk_ops at91sam9x5_smd_ops = { | ||
109 | .recalc_rate = at91sam9x5_clk_smd_recalc_rate, | ||
110 | .round_rate = at91sam9x5_clk_smd_round_rate, | ||
111 | .get_parent = at91sam9x5_clk_smd_get_parent, | ||
112 | .set_parent = at91sam9x5_clk_smd_set_parent, | ||
113 | .set_rate = at91sam9x5_clk_smd_set_rate, | ||
114 | }; | ||
115 | |||
116 | static struct clk * __init | ||
117 | at91sam9x5_clk_register_smd(struct at91_pmc *pmc, const char *name, | ||
118 | const char **parent_names, u8 num_parents) | ||
119 | { | ||
120 | struct at91sam9x5_clk_smd *smd; | ||
121 | struct clk *clk = NULL; | ||
122 | struct clk_init_data init; | ||
123 | |||
124 | smd = kzalloc(sizeof(*smd), GFP_KERNEL); | ||
125 | if (!smd) | ||
126 | return ERR_PTR(-ENOMEM); | ||
127 | |||
128 | init.name = name; | ||
129 | init.ops = &at91sam9x5_smd_ops; | ||
130 | init.parent_names = parent_names; | ||
131 | init.num_parents = num_parents; | ||
132 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; | ||
133 | |||
134 | smd->hw.init = &init; | ||
135 | smd->pmc = pmc; | ||
136 | |||
137 | clk = clk_register(NULL, &smd->hw); | ||
138 | if (IS_ERR(clk)) | ||
139 | kfree(smd); | ||
140 | |||
141 | return clk; | ||
142 | } | ||
143 | |||
144 | void __init of_at91sam9x5_clk_smd_setup(struct device_node *np, | ||
145 | struct at91_pmc *pmc) | ||
146 | { | ||
147 | struct clk *clk; | ||
148 | int i; | ||
149 | int num_parents; | ||
150 | const char *parent_names[SMD_SOURCE_MAX]; | ||
151 | const char *name = np->name; | ||
152 | |||
153 | num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); | ||
154 | if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX) | ||
155 | return; | ||
156 | |||
157 | for (i = 0; i < num_parents; i++) { | ||
158 | parent_names[i] = of_clk_get_parent_name(np, i); | ||
159 | if (!parent_names[i]) | ||
160 | return; | ||
161 | } | ||
162 | |||
163 | of_property_read_string(np, "clock-output-names", &name); | ||
164 | |||
165 | clk = at91sam9x5_clk_register_smd(pmc, name, parent_names, | ||
166 | num_parents); | ||
167 | if (IS_ERR(clk)) | ||
168 | return; | ||
169 | |||
170 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
171 | } | ||
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c new file mode 100644 index 000000000000..8f7c0434a09f --- /dev/null +++ b/drivers/clk/at91/clk-system.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | #include "pmc.h" | ||
19 | |||
20 | #define SYSTEM_MAX_ID 31 | ||
21 | |||
22 | #define SYSTEM_MAX_NAME_SZ 32 | ||
23 | |||
24 | #define to_clk_system(hw) container_of(hw, struct clk_system, hw) | ||
25 | struct clk_system { | ||
26 | struct clk_hw hw; | ||
27 | struct at91_pmc *pmc; | ||
28 | u8 id; | ||
29 | }; | ||
30 | |||
31 | static int clk_system_enable(struct clk_hw *hw) | ||
32 | { | ||
33 | struct clk_system *sys = to_clk_system(hw); | ||
34 | struct at91_pmc *pmc = sys->pmc; | ||
35 | |||
36 | pmc_write(pmc, AT91_PMC_SCER, 1 << sys->id); | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static void clk_system_disable(struct clk_hw *hw) | ||
41 | { | ||
42 | struct clk_system *sys = to_clk_system(hw); | ||
43 | struct at91_pmc *pmc = sys->pmc; | ||
44 | |||
45 | pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id); | ||
46 | } | ||
47 | |||
48 | static int clk_system_is_enabled(struct clk_hw *hw) | ||
49 | { | ||
50 | struct clk_system *sys = to_clk_system(hw); | ||
51 | struct at91_pmc *pmc = sys->pmc; | ||
52 | |||
53 | return !!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id)); | ||
54 | } | ||
55 | |||
56 | static const struct clk_ops system_ops = { | ||
57 | .enable = clk_system_enable, | ||
58 | .disable = clk_system_disable, | ||
59 | .is_enabled = clk_system_is_enabled, | ||
60 | }; | ||
61 | |||
62 | static struct clk * __init | ||
63 | at91_clk_register_system(struct at91_pmc *pmc, const char *name, | ||
64 | const char *parent_name, u8 id) | ||
65 | { | ||
66 | struct clk_system *sys; | ||
67 | struct clk *clk = NULL; | ||
68 | struct clk_init_data init; | ||
69 | |||
70 | if (!parent_name || id > SYSTEM_MAX_ID) | ||
71 | return ERR_PTR(-EINVAL); | ||
72 | |||
73 | sys = kzalloc(sizeof(*sys), GFP_KERNEL); | ||
74 | if (!sys) | ||
75 | return ERR_PTR(-ENOMEM); | ||
76 | |||
77 | init.name = name; | ||
78 | init.ops = &system_ops; | ||
79 | init.parent_names = &parent_name; | ||
80 | init.num_parents = 1; | ||
81 | /* | ||
82 | * CLK_IGNORE_UNUSED is used to avoid ddrck switch off. | ||
83 | * TODO : we should implement a driver supporting at91 ddr controller | ||
84 | * (see drivers/memory) which would request and enable the ddrck clock. | ||
85 | * When this is done we will be able to remove CLK_IGNORE_UNUSED flag. | ||
86 | */ | ||
87 | init.flags = CLK_IGNORE_UNUSED; | ||
88 | |||
89 | sys->id = id; | ||
90 | sys->hw.init = &init; | ||
91 | sys->pmc = pmc; | ||
92 | |||
93 | clk = clk_register(NULL, &sys->hw); | ||
94 | if (IS_ERR(clk)) | ||
95 | kfree(sys); | ||
96 | |||
97 | return clk; | ||
98 | } | ||
99 | |||
100 | static void __init | ||
101 | of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc) | ||
102 | { | ||
103 | int num; | ||
104 | u32 id; | ||
105 | struct clk *clk; | ||
106 | const char *name; | ||
107 | struct device_node *sysclknp; | ||
108 | const char *parent_name; | ||
109 | |||
110 | num = of_get_child_count(np); | ||
111 | if (num > (SYSTEM_MAX_ID + 1)) | ||
112 | return; | ||
113 | |||
114 | for_each_child_of_node(np, sysclknp) { | ||
115 | if (of_property_read_u32(sysclknp, "reg", &id)) | ||
116 | continue; | ||
117 | |||
118 | if (of_property_read_string(np, "clock-output-names", &name)) | ||
119 | name = sysclknp->name; | ||
120 | |||
121 | parent_name = of_clk_get_parent_name(sysclknp, 0); | ||
122 | |||
123 | clk = at91_clk_register_system(pmc, name, parent_name, id); | ||
124 | if (IS_ERR(clk)) | ||
125 | continue; | ||
126 | |||
127 | of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | void __init of_at91rm9200_clk_sys_setup(struct device_node *np, | ||
132 | struct at91_pmc *pmc) | ||
133 | { | ||
134 | of_at91_clk_sys_setup(np, pmc); | ||
135 | } | ||
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c new file mode 100644 index 000000000000..7d1d26a4bd04 --- /dev/null +++ b/drivers/clk/at91/clk-usb.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | #include "pmc.h" | ||
19 | |||
20 | #define USB_SOURCE_MAX 2 | ||
21 | |||
22 | #define SAM9X5_USB_DIV_SHIFT 8 | ||
23 | #define SAM9X5_USB_MAX_DIV 0xf | ||
24 | |||
25 | #define RM9200_USB_DIV_SHIFT 28 | ||
26 | #define RM9200_USB_DIV_TAB_SIZE 4 | ||
27 | |||
28 | struct at91sam9x5_clk_usb { | ||
29 | struct clk_hw hw; | ||
30 | struct at91_pmc *pmc; | ||
31 | }; | ||
32 | |||
33 | #define to_at91sam9x5_clk_usb(hw) \ | ||
34 | container_of(hw, struct at91sam9x5_clk_usb, hw) | ||
35 | |||
36 | struct at91rm9200_clk_usb { | ||
37 | struct clk_hw hw; | ||
38 | struct at91_pmc *pmc; | ||
39 | u32 divisors[4]; | ||
40 | }; | ||
41 | |||
42 | #define to_at91rm9200_clk_usb(hw) \ | ||
43 | container_of(hw, struct at91rm9200_clk_usb, hw) | ||
44 | |||
45 | static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw, | ||
46 | unsigned long parent_rate) | ||
47 | { | ||
48 | u32 tmp; | ||
49 | u8 usbdiv; | ||
50 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | ||
51 | struct at91_pmc *pmc = usb->pmc; | ||
52 | |||
53 | tmp = pmc_read(pmc, AT91_PMC_USB); | ||
54 | usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT; | ||
55 | return parent_rate / (usbdiv + 1); | ||
56 | } | ||
57 | |||
58 | static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, | ||
59 | unsigned long *parent_rate) | ||
60 | { | ||
61 | unsigned long div; | ||
62 | unsigned long bestrate; | ||
63 | unsigned long tmp; | ||
64 | |||
65 | if (rate >= *parent_rate) | ||
66 | return *parent_rate; | ||
67 | |||
68 | div = *parent_rate / rate; | ||
69 | if (div >= SAM9X5_USB_MAX_DIV) | ||
70 | return *parent_rate / (SAM9X5_USB_MAX_DIV + 1); | ||
71 | |||
72 | bestrate = *parent_rate / div; | ||
73 | tmp = *parent_rate / (div + 1); | ||
74 | if (bestrate - rate > rate - tmp) | ||
75 | bestrate = tmp; | ||
76 | |||
77 | return bestrate; | ||
78 | } | ||
79 | |||
80 | static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) | ||
81 | { | ||
82 | u32 tmp; | ||
83 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | ||
84 | struct at91_pmc *pmc = usb->pmc; | ||
85 | |||
86 | if (index > 1) | ||
87 | return -EINVAL; | ||
88 | tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS; | ||
89 | if (index) | ||
90 | tmp |= AT91_PMC_USBS; | ||
91 | pmc_write(pmc, AT91_PMC_USB, tmp); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw) | ||
96 | { | ||
97 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | ||
98 | struct at91_pmc *pmc = usb->pmc; | ||
99 | |||
100 | return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS; | ||
101 | } | ||
102 | |||
103 | static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, | ||
104 | unsigned long parent_rate) | ||
105 | { | ||
106 | u32 tmp; | ||
107 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | ||
108 | struct at91_pmc *pmc = usb->pmc; | ||
109 | unsigned long div = parent_rate / rate; | ||
110 | |||
111 | if (parent_rate % rate || div < 1 || div >= SAM9X5_USB_MAX_DIV) | ||
112 | return -EINVAL; | ||
113 | |||
114 | tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV; | ||
115 | tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT; | ||
116 | pmc_write(pmc, AT91_PMC_USB, tmp); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static const struct clk_ops at91sam9x5_usb_ops = { | ||
122 | .recalc_rate = at91sam9x5_clk_usb_recalc_rate, | ||
123 | .round_rate = at91sam9x5_clk_usb_round_rate, | ||
124 | .get_parent = at91sam9x5_clk_usb_get_parent, | ||
125 | .set_parent = at91sam9x5_clk_usb_set_parent, | ||
126 | .set_rate = at91sam9x5_clk_usb_set_rate, | ||
127 | }; | ||
128 | |||
129 | static int at91sam9n12_clk_usb_enable(struct clk_hw *hw) | ||
130 | { | ||
131 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | ||
132 | struct at91_pmc *pmc = usb->pmc; | ||
133 | |||
134 | pmc_write(pmc, AT91_PMC_USB, | ||
135 | pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static void at91sam9n12_clk_usb_disable(struct clk_hw *hw) | ||
140 | { | ||
141 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | ||
142 | struct at91_pmc *pmc = usb->pmc; | ||
143 | |||
144 | pmc_write(pmc, AT91_PMC_USB, | ||
145 | pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS); | ||
146 | } | ||
147 | |||
148 | static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw) | ||
149 | { | ||
150 | struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); | ||
151 | struct at91_pmc *pmc = usb->pmc; | ||
152 | |||
153 | return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS); | ||
154 | } | ||
155 | |||
156 | static const struct clk_ops at91sam9n12_usb_ops = { | ||
157 | .enable = at91sam9n12_clk_usb_enable, | ||
158 | .disable = at91sam9n12_clk_usb_disable, | ||
159 | .is_enabled = at91sam9n12_clk_usb_is_enabled, | ||
160 | .recalc_rate = at91sam9x5_clk_usb_recalc_rate, | ||
161 | .round_rate = at91sam9x5_clk_usb_round_rate, | ||
162 | .set_rate = at91sam9x5_clk_usb_set_rate, | ||
163 | }; | ||
164 | |||
165 | static struct clk * __init | ||
166 | at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name, | ||
167 | const char **parent_names, u8 num_parents) | ||
168 | { | ||
169 | struct at91sam9x5_clk_usb *usb; | ||
170 | struct clk *clk = NULL; | ||
171 | struct clk_init_data init; | ||
172 | |||
173 | usb = kzalloc(sizeof(*usb), GFP_KERNEL); | ||
174 | if (!usb) | ||
175 | return ERR_PTR(-ENOMEM); | ||
176 | |||
177 | init.name = name; | ||
178 | init.ops = &at91sam9x5_usb_ops; | ||
179 | init.parent_names = parent_names; | ||
180 | init.num_parents = num_parents; | ||
181 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; | ||
182 | |||
183 | usb->hw.init = &init; | ||
184 | usb->pmc = pmc; | ||
185 | |||
186 | clk = clk_register(NULL, &usb->hw); | ||
187 | if (IS_ERR(clk)) | ||
188 | kfree(usb); | ||
189 | |||
190 | return clk; | ||
191 | } | ||
192 | |||
193 | static struct clk * __init | ||
194 | at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name, | ||
195 | const char *parent_name) | ||
196 | { | ||
197 | struct at91sam9x5_clk_usb *usb; | ||
198 | struct clk *clk = NULL; | ||
199 | struct clk_init_data init; | ||
200 | |||
201 | usb = kzalloc(sizeof(*usb), GFP_KERNEL); | ||
202 | if (!usb) | ||
203 | return ERR_PTR(-ENOMEM); | ||
204 | |||
205 | init.name = name; | ||
206 | init.ops = &at91sam9n12_usb_ops; | ||
207 | init.parent_names = &parent_name; | ||
208 | init.num_parents = 1; | ||
209 | init.flags = CLK_SET_RATE_GATE; | ||
210 | |||
211 | usb->hw.init = &init; | ||
212 | usb->pmc = pmc; | ||
213 | |||
214 | clk = clk_register(NULL, &usb->hw); | ||
215 | if (IS_ERR(clk)) | ||
216 | kfree(usb); | ||
217 | |||
218 | return clk; | ||
219 | } | ||
220 | |||
221 | static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw, | ||
222 | unsigned long parent_rate) | ||
223 | { | ||
224 | struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); | ||
225 | struct at91_pmc *pmc = usb->pmc; | ||
226 | u32 tmp; | ||
227 | u8 usbdiv; | ||
228 | |||
229 | tmp = pmc_read(pmc, AT91_CKGR_PLLBR); | ||
230 | usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT; | ||
231 | if (usb->divisors[usbdiv]) | ||
232 | return parent_rate / usb->divisors[usbdiv]; | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, | ||
238 | unsigned long *parent_rate) | ||
239 | { | ||
240 | struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); | ||
241 | unsigned long bestrate = 0; | ||
242 | int bestdiff = -1; | ||
243 | unsigned long tmprate; | ||
244 | int tmpdiff; | ||
245 | int i = 0; | ||
246 | |||
247 | for (i = 0; i < 4; i++) { | ||
248 | if (!usb->divisors[i]) | ||
249 | continue; | ||
250 | tmprate = *parent_rate / usb->divisors[i]; | ||
251 | if (tmprate < rate) | ||
252 | tmpdiff = rate - tmprate; | ||
253 | else | ||
254 | tmpdiff = tmprate - rate; | ||
255 | |||
256 | if (bestdiff < 0 || bestdiff > tmpdiff) { | ||
257 | bestrate = tmprate; | ||
258 | bestdiff = tmpdiff; | ||
259 | } | ||
260 | |||
261 | if (!bestdiff) | ||
262 | break; | ||
263 | } | ||
264 | |||
265 | return bestrate; | ||
266 | } | ||
267 | |||
268 | static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, | ||
269 | unsigned long parent_rate) | ||
270 | { | ||
271 | u32 tmp; | ||
272 | int i; | ||
273 | struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); | ||
274 | struct at91_pmc *pmc = usb->pmc; | ||
275 | unsigned long div = parent_rate / rate; | ||
276 | |||
277 | if (parent_rate % rate) | ||
278 | return -EINVAL; | ||
279 | for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { | ||
280 | if (usb->divisors[i] == div) { | ||
281 | tmp = pmc_read(pmc, AT91_CKGR_PLLBR) & | ||
282 | ~AT91_PMC_USBDIV; | ||
283 | tmp |= i << RM9200_USB_DIV_SHIFT; | ||
284 | pmc_write(pmc, AT91_CKGR_PLLBR, tmp); | ||
285 | return 0; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | return -EINVAL; | ||
290 | } | ||
291 | |||
292 | static const struct clk_ops at91rm9200_usb_ops = { | ||
293 | .recalc_rate = at91rm9200_clk_usb_recalc_rate, | ||
294 | .round_rate = at91rm9200_clk_usb_round_rate, | ||
295 | .set_rate = at91rm9200_clk_usb_set_rate, | ||
296 | }; | ||
297 | |||
298 | static struct clk * __init | ||
299 | at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name, | ||
300 | const char *parent_name, const u32 *divisors) | ||
301 | { | ||
302 | struct at91rm9200_clk_usb *usb; | ||
303 | struct clk *clk = NULL; | ||
304 | struct clk_init_data init; | ||
305 | |||
306 | usb = kzalloc(sizeof(*usb), GFP_KERNEL); | ||
307 | if (!usb) | ||
308 | return ERR_PTR(-ENOMEM); | ||
309 | |||
310 | init.name = name; | ||
311 | init.ops = &at91rm9200_usb_ops; | ||
312 | init.parent_names = &parent_name; | ||
313 | init.num_parents = 1; | ||
314 | init.flags = 0; | ||
315 | |||
316 | usb->hw.init = &init; | ||
317 | usb->pmc = pmc; | ||
318 | memcpy(usb->divisors, divisors, sizeof(usb->divisors)); | ||
319 | |||
320 | clk = clk_register(NULL, &usb->hw); | ||
321 | if (IS_ERR(clk)) | ||
322 | kfree(usb); | ||
323 | |||
324 | return clk; | ||
325 | } | ||
326 | |||
327 | void __init of_at91sam9x5_clk_usb_setup(struct device_node *np, | ||
328 | struct at91_pmc *pmc) | ||
329 | { | ||
330 | struct clk *clk; | ||
331 | int i; | ||
332 | int num_parents; | ||
333 | const char *parent_names[USB_SOURCE_MAX]; | ||
334 | const char *name = np->name; | ||
335 | |||
336 | num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); | ||
337 | if (num_parents <= 0 || num_parents > USB_SOURCE_MAX) | ||
338 | return; | ||
339 | |||
340 | for (i = 0; i < num_parents; i++) { | ||
341 | parent_names[i] = of_clk_get_parent_name(np, i); | ||
342 | if (!parent_names[i]) | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | of_property_read_string(np, "clock-output-names", &name); | ||
347 | |||
348 | clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents); | ||
349 | if (IS_ERR(clk)) | ||
350 | return; | ||
351 | |||
352 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
353 | } | ||
354 | |||
355 | void __init of_at91sam9n12_clk_usb_setup(struct device_node *np, | ||
356 | struct at91_pmc *pmc) | ||
357 | { | ||
358 | struct clk *clk; | ||
359 | const char *parent_name; | ||
360 | const char *name = np->name; | ||
361 | |||
362 | parent_name = of_clk_get_parent_name(np, 0); | ||
363 | if (!parent_name) | ||
364 | return; | ||
365 | |||
366 | of_property_read_string(np, "clock-output-names", &name); | ||
367 | |||
368 | clk = at91sam9n12_clk_register_usb(pmc, name, parent_name); | ||
369 | if (IS_ERR(clk)) | ||
370 | return; | ||
371 | |||
372 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
373 | } | ||
374 | |||
375 | void __init of_at91rm9200_clk_usb_setup(struct device_node *np, | ||
376 | struct at91_pmc *pmc) | ||
377 | { | ||
378 | struct clk *clk; | ||
379 | const char *parent_name; | ||
380 | const char *name = np->name; | ||
381 | u32 divisors[4] = {0, 0, 0, 0}; | ||
382 | |||
383 | parent_name = of_clk_get_parent_name(np, 0); | ||
384 | if (!parent_name) | ||
385 | return; | ||
386 | |||
387 | of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4); | ||
388 | if (!divisors[0]) | ||
389 | return; | ||
390 | |||
391 | of_property_read_string(np, "clock-output-names", &name); | ||
392 | |||
393 | clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors); | ||
394 | if (IS_ERR(clk)) | ||
395 | return; | ||
396 | |||
397 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
398 | } | ||
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c new file mode 100644 index 000000000000..ae3263bc1476 --- /dev/null +++ b/drivers/clk/at91/clk-utmi.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_address.h> | ||
18 | #include <linux/of_irq.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/wait.h> | ||
22 | |||
23 | #include "pmc.h" | ||
24 | |||
25 | #define UTMI_FIXED_MUL 40 | ||
26 | |||
27 | struct clk_utmi { | ||
28 | struct clk_hw hw; | ||
29 | struct at91_pmc *pmc; | ||
30 | unsigned int irq; | ||
31 | wait_queue_head_t wait; | ||
32 | }; | ||
33 | |||
34 | #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw) | ||
35 | |||
36 | static irqreturn_t clk_utmi_irq_handler(int irq, void *dev_id) | ||
37 | { | ||
38 | struct clk_utmi *utmi = (struct clk_utmi *)dev_id; | ||
39 | |||
40 | wake_up(&utmi->wait); | ||
41 | disable_irq_nosync(utmi->irq); | ||
42 | |||
43 | return IRQ_HANDLED; | ||
44 | } | ||
45 | |||
46 | static int clk_utmi_prepare(struct clk_hw *hw) | ||
47 | { | ||
48 | struct clk_utmi *utmi = to_clk_utmi(hw); | ||
49 | struct at91_pmc *pmc = utmi->pmc; | ||
50 | u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) | AT91_PMC_UPLLEN | | ||
51 | AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN; | ||
52 | |||
53 | pmc_write(pmc, AT91_CKGR_UCKR, tmp); | ||
54 | |||
55 | while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU)) { | ||
56 | enable_irq(utmi->irq); | ||
57 | wait_event(utmi->wait, | ||
58 | pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU); | ||
59 | } | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int clk_utmi_is_prepared(struct clk_hw *hw) | ||
65 | { | ||
66 | struct clk_utmi *utmi = to_clk_utmi(hw); | ||
67 | struct at91_pmc *pmc = utmi->pmc; | ||
68 | |||
69 | return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU); | ||
70 | } | ||
71 | |||
72 | static void clk_utmi_unprepare(struct clk_hw *hw) | ||
73 | { | ||
74 | struct clk_utmi *utmi = to_clk_utmi(hw); | ||
75 | struct at91_pmc *pmc = utmi->pmc; | ||
76 | u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN; | ||
77 | |||
78 | pmc_write(pmc, AT91_CKGR_UCKR, tmp); | ||
79 | } | ||
80 | |||
81 | static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw, | ||
82 | unsigned long parent_rate) | ||
83 | { | ||
84 | /* UTMI clk is a fixed clk multiplier */ | ||
85 | return parent_rate * UTMI_FIXED_MUL; | ||
86 | } | ||
87 | |||
88 | static const struct clk_ops utmi_ops = { | ||
89 | .prepare = clk_utmi_prepare, | ||
90 | .unprepare = clk_utmi_unprepare, | ||
91 | .is_prepared = clk_utmi_is_prepared, | ||
92 | .recalc_rate = clk_utmi_recalc_rate, | ||
93 | }; | ||
94 | |||
95 | static struct clk * __init | ||
96 | at91_clk_register_utmi(struct at91_pmc *pmc, unsigned int irq, | ||
97 | const char *name, const char *parent_name) | ||
98 | { | ||
99 | int ret; | ||
100 | struct clk_utmi *utmi; | ||
101 | struct clk *clk = NULL; | ||
102 | struct clk_init_data init; | ||
103 | |||
104 | utmi = kzalloc(sizeof(*utmi), GFP_KERNEL); | ||
105 | if (!utmi) | ||
106 | return ERR_PTR(-ENOMEM); | ||
107 | |||
108 | init.name = name; | ||
109 | init.ops = &utmi_ops; | ||
110 | init.parent_names = parent_name ? &parent_name : NULL; | ||
111 | init.num_parents = parent_name ? 1 : 0; | ||
112 | init.flags = CLK_SET_RATE_GATE; | ||
113 | |||
114 | utmi->hw.init = &init; | ||
115 | utmi->pmc = pmc; | ||
116 | utmi->irq = irq; | ||
117 | init_waitqueue_head(&utmi->wait); | ||
118 | irq_set_status_flags(utmi->irq, IRQ_NOAUTOEN); | ||
119 | ret = request_irq(utmi->irq, clk_utmi_irq_handler, | ||
120 | IRQF_TRIGGER_HIGH, "clk-utmi", utmi); | ||
121 | if (ret) | ||
122 | return ERR_PTR(ret); | ||
123 | |||
124 | clk = clk_register(NULL, &utmi->hw); | ||
125 | if (IS_ERR(clk)) | ||
126 | kfree(utmi); | ||
127 | |||
128 | return clk; | ||
129 | } | ||
130 | |||
131 | static void __init | ||
132 | of_at91_clk_utmi_setup(struct device_node *np, struct at91_pmc *pmc) | ||
133 | { | ||
134 | unsigned int irq; | ||
135 | struct clk *clk; | ||
136 | const char *parent_name; | ||
137 | const char *name = np->name; | ||
138 | |||
139 | parent_name = of_clk_get_parent_name(np, 0); | ||
140 | |||
141 | of_property_read_string(np, "clock-output-names", &name); | ||
142 | |||
143 | irq = irq_of_parse_and_map(np, 0); | ||
144 | if (!irq) | ||
145 | return; | ||
146 | |||
147 | clk = at91_clk_register_utmi(pmc, irq, name, parent_name); | ||
148 | if (IS_ERR(clk)) | ||
149 | return; | ||
150 | |||
151 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
152 | return; | ||
153 | } | ||
154 | |||
155 | void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np, | ||
156 | struct at91_pmc *pmc) | ||
157 | { | ||
158 | of_at91_clk_utmi_setup(np, pmc); | ||
159 | } | ||
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c new file mode 100644 index 000000000000..6a61477a57e0 --- /dev/null +++ b/drivers/clk/at91/pmc.c | |||
@@ -0,0 +1,395 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk/at91_pmc.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/irqchip/chained_irq.h> | ||
20 | #include <linux/irqdomain.h> | ||
21 | #include <linux/of_irq.h> | ||
22 | |||
23 | #include <asm/proc-fns.h> | ||
24 | |||
25 | #include "pmc.h" | ||
26 | |||
27 | void __iomem *at91_pmc_base; | ||
28 | EXPORT_SYMBOL_GPL(at91_pmc_base); | ||
29 | |||
30 | void at91sam9_idle(void) | ||
31 | { | ||
32 | at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); | ||
33 | cpu_do_idle(); | ||
34 | } | ||
35 | |||
36 | int of_at91_get_clk_range(struct device_node *np, const char *propname, | ||
37 | struct clk_range *range) | ||
38 | { | ||
39 | u32 min, max; | ||
40 | int ret; | ||
41 | |||
42 | ret = of_property_read_u32_index(np, propname, 0, &min); | ||
43 | if (ret) | ||
44 | return ret; | ||
45 | |||
46 | ret = of_property_read_u32_index(np, propname, 1, &max); | ||
47 | if (ret) | ||
48 | return ret; | ||
49 | |||
50 | if (range) { | ||
51 | range->min = min; | ||
52 | range->max = max; | ||
53 | } | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | EXPORT_SYMBOL_GPL(of_at91_get_clk_range); | ||
58 | |||
59 | static void pmc_irq_mask(struct irq_data *d) | ||
60 | { | ||
61 | struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); | ||
62 | |||
63 | pmc_write(pmc, AT91_PMC_IDR, 1 << d->hwirq); | ||
64 | } | ||
65 | |||
66 | static void pmc_irq_unmask(struct irq_data *d) | ||
67 | { | ||
68 | struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); | ||
69 | |||
70 | pmc_write(pmc, AT91_PMC_IER, 1 << d->hwirq); | ||
71 | } | ||
72 | |||
73 | static int pmc_irq_set_type(struct irq_data *d, unsigned type) | ||
74 | { | ||
75 | if (type != IRQ_TYPE_LEVEL_HIGH) { | ||
76 | pr_warn("PMC: type not supported (support only IRQ_TYPE_LEVEL_HIGH type)\n"); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static struct irq_chip pmc_irq = { | ||
84 | .name = "PMC", | ||
85 | .irq_disable = pmc_irq_mask, | ||
86 | .irq_mask = pmc_irq_mask, | ||
87 | .irq_unmask = pmc_irq_unmask, | ||
88 | .irq_set_type = pmc_irq_set_type, | ||
89 | }; | ||
90 | |||
91 | static struct lock_class_key pmc_lock_class; | ||
92 | |||
93 | static int pmc_irq_map(struct irq_domain *h, unsigned int virq, | ||
94 | irq_hw_number_t hw) | ||
95 | { | ||
96 | struct at91_pmc *pmc = h->host_data; | ||
97 | |||
98 | irq_set_lockdep_class(virq, &pmc_lock_class); | ||
99 | |||
100 | irq_set_chip_and_handler(virq, &pmc_irq, | ||
101 | handle_level_irq); | ||
102 | set_irq_flags(virq, IRQF_VALID); | ||
103 | irq_set_chip_data(virq, pmc); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static int pmc_irq_domain_xlate(struct irq_domain *d, | ||
109 | struct device_node *ctrlr, | ||
110 | const u32 *intspec, unsigned int intsize, | ||
111 | irq_hw_number_t *out_hwirq, | ||
112 | unsigned int *out_type) | ||
113 | { | ||
114 | struct at91_pmc *pmc = d->host_data; | ||
115 | const struct at91_pmc_caps *caps = pmc->caps; | ||
116 | |||
117 | if (WARN_ON(intsize < 1)) | ||
118 | return -EINVAL; | ||
119 | |||
120 | *out_hwirq = intspec[0]; | ||
121 | |||
122 | if (!(caps->available_irqs & (1 << *out_hwirq))) | ||
123 | return -EINVAL; | ||
124 | |||
125 | *out_type = IRQ_TYPE_LEVEL_HIGH; | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static struct irq_domain_ops pmc_irq_ops = { | ||
131 | .map = pmc_irq_map, | ||
132 | .xlate = pmc_irq_domain_xlate, | ||
133 | }; | ||
134 | |||
135 | static irqreturn_t pmc_irq_handler(int irq, void *data) | ||
136 | { | ||
137 | struct at91_pmc *pmc = (struct at91_pmc *)data; | ||
138 | unsigned long sr; | ||
139 | int n; | ||
140 | |||
141 | sr = pmc_read(pmc, AT91_PMC_SR) & pmc_read(pmc, AT91_PMC_IMR); | ||
142 | if (!sr) | ||
143 | return IRQ_NONE; | ||
144 | |||
145 | for_each_set_bit(n, &sr, BITS_PER_LONG) | ||
146 | generic_handle_irq(irq_find_mapping(pmc->irqdomain, n)); | ||
147 | |||
148 | return IRQ_HANDLED; | ||
149 | } | ||
150 | |||
151 | static const struct at91_pmc_caps at91rm9200_caps = { | ||
152 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | | ||
153 | AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | | ||
154 | AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | | ||
155 | AT91_PMC_PCK3RDY, | ||
156 | }; | ||
157 | |||
158 | static const struct at91_pmc_caps at91sam9260_caps = { | ||
159 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | | ||
160 | AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | | ||
161 | AT91_PMC_PCK1RDY, | ||
162 | }; | ||
163 | |||
164 | static const struct at91_pmc_caps at91sam9g45_caps = { | ||
165 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | | ||
166 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | | ||
167 | AT91_PMC_PCK1RDY, | ||
168 | }; | ||
169 | |||
170 | static const struct at91_pmc_caps at91sam9n12_caps = { | ||
171 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | | ||
172 | AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | | ||
173 | AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | | ||
174 | AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, | ||
175 | }; | ||
176 | |||
177 | static const struct at91_pmc_caps at91sam9x5_caps = { | ||
178 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | | ||
179 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | | ||
180 | AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | | ||
181 | AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, | ||
182 | }; | ||
183 | |||
184 | static const struct at91_pmc_caps sama5d3_caps = { | ||
185 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | | ||
186 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | | ||
187 | AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | | ||
188 | AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS | | ||
189 | AT91_PMC_CFDEV, | ||
190 | }; | ||
191 | |||
192 | static struct at91_pmc *__init at91_pmc_init(struct device_node *np, | ||
193 | void __iomem *regbase, int virq, | ||
194 | const struct at91_pmc_caps *caps) | ||
195 | { | ||
196 | struct at91_pmc *pmc; | ||
197 | |||
198 | if (!regbase || !virq || !caps) | ||
199 | return NULL; | ||
200 | |||
201 | at91_pmc_base = regbase; | ||
202 | |||
203 | pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); | ||
204 | if (!pmc) | ||
205 | return NULL; | ||
206 | |||
207 | spin_lock_init(&pmc->lock); | ||
208 | pmc->regbase = regbase; | ||
209 | pmc->virq = virq; | ||
210 | pmc->caps = caps; | ||
211 | |||
212 | pmc->irqdomain = irq_domain_add_linear(np, 32, &pmc_irq_ops, pmc); | ||
213 | |||
214 | if (!pmc->irqdomain) | ||
215 | goto out_free_pmc; | ||
216 | |||
217 | pmc_write(pmc, AT91_PMC_IDR, 0xffffffff); | ||
218 | if (request_irq(pmc->virq, pmc_irq_handler, IRQF_SHARED, "pmc", pmc)) | ||
219 | goto out_remove_irqdomain; | ||
220 | |||
221 | return pmc; | ||
222 | |||
223 | out_remove_irqdomain: | ||
224 | irq_domain_remove(pmc->irqdomain); | ||
225 | out_free_pmc: | ||
226 | kfree(pmc); | ||
227 | |||
228 | return NULL; | ||
229 | } | ||
230 | |||
231 | static const struct of_device_id pmc_clk_ids[] __initconst = { | ||
232 | /* Main clock */ | ||
233 | { | ||
234 | .compatible = "atmel,at91rm9200-clk-main", | ||
235 | .data = of_at91rm9200_clk_main_setup, | ||
236 | }, | ||
237 | /* PLL clocks */ | ||
238 | { | ||
239 | .compatible = "atmel,at91rm9200-clk-pll", | ||
240 | .data = of_at91rm9200_clk_pll_setup, | ||
241 | }, | ||
242 | { | ||
243 | .compatible = "atmel,at91sam9g45-clk-pll", | ||
244 | .data = of_at91sam9g45_clk_pll_setup, | ||
245 | }, | ||
246 | { | ||
247 | .compatible = "atmel,at91sam9g20-clk-pllb", | ||
248 | .data = of_at91sam9g20_clk_pllb_setup, | ||
249 | }, | ||
250 | { | ||
251 | .compatible = "atmel,sama5d3-clk-pll", | ||
252 | .data = of_sama5d3_clk_pll_setup, | ||
253 | }, | ||
254 | { | ||
255 | .compatible = "atmel,at91sam9x5-clk-plldiv", | ||
256 | .data = of_at91sam9x5_clk_plldiv_setup, | ||
257 | }, | ||
258 | /* Master clock */ | ||
259 | { | ||
260 | .compatible = "atmel,at91rm9200-clk-master", | ||
261 | .data = of_at91rm9200_clk_master_setup, | ||
262 | }, | ||
263 | { | ||
264 | .compatible = "atmel,at91sam9x5-clk-master", | ||
265 | .data = of_at91sam9x5_clk_master_setup, | ||
266 | }, | ||
267 | /* System clocks */ | ||
268 | { | ||
269 | .compatible = "atmel,at91rm9200-clk-system", | ||
270 | .data = of_at91rm9200_clk_sys_setup, | ||
271 | }, | ||
272 | /* Peripheral clocks */ | ||
273 | { | ||
274 | .compatible = "atmel,at91rm9200-clk-peripheral", | ||
275 | .data = of_at91rm9200_clk_periph_setup, | ||
276 | }, | ||
277 | { | ||
278 | .compatible = "atmel,at91sam9x5-clk-peripheral", | ||
279 | .data = of_at91sam9x5_clk_periph_setup, | ||
280 | }, | ||
281 | /* Programmable clocks */ | ||
282 | { | ||
283 | .compatible = "atmel,at91rm9200-clk-programmable", | ||
284 | .data = of_at91rm9200_clk_prog_setup, | ||
285 | }, | ||
286 | { | ||
287 | .compatible = "atmel,at91sam9g45-clk-programmable", | ||
288 | .data = of_at91sam9g45_clk_prog_setup, | ||
289 | }, | ||
290 | { | ||
291 | .compatible = "atmel,at91sam9x5-clk-programmable", | ||
292 | .data = of_at91sam9x5_clk_prog_setup, | ||
293 | }, | ||
294 | /* UTMI clock */ | ||
295 | #if defined(CONFIG_HAVE_AT91_UTMI) | ||
296 | { | ||
297 | .compatible = "atmel,at91sam9x5-clk-utmi", | ||
298 | .data = of_at91sam9x5_clk_utmi_setup, | ||
299 | }, | ||
300 | #endif | ||
301 | /* USB clock */ | ||
302 | #if defined(CONFIG_HAVE_AT91_USB_CLK) | ||
303 | { | ||
304 | .compatible = "atmel,at91rm9200-clk-usb", | ||
305 | .data = of_at91rm9200_clk_usb_setup, | ||
306 | }, | ||
307 | { | ||
308 | .compatible = "atmel,at91sam9x5-clk-usb", | ||
309 | .data = of_at91sam9x5_clk_usb_setup, | ||
310 | }, | ||
311 | { | ||
312 | .compatible = "atmel,at91sam9n12-clk-usb", | ||
313 | .data = of_at91sam9n12_clk_usb_setup, | ||
314 | }, | ||
315 | #endif | ||
316 | /* SMD clock */ | ||
317 | #if defined(CONFIG_HAVE_AT91_SMD) | ||
318 | { | ||
319 | .compatible = "atmel,at91sam9x5-clk-smd", | ||
320 | .data = of_at91sam9x5_clk_smd_setup, | ||
321 | }, | ||
322 | #endif | ||
323 | { /*sentinel*/ } | ||
324 | }; | ||
325 | |||
326 | static void __init of_at91_pmc_setup(struct device_node *np, | ||
327 | const struct at91_pmc_caps *caps) | ||
328 | { | ||
329 | struct at91_pmc *pmc; | ||
330 | struct device_node *childnp; | ||
331 | void (*clk_setup)(struct device_node *, struct at91_pmc *); | ||
332 | const struct of_device_id *clk_id; | ||
333 | void __iomem *regbase = of_iomap(np, 0); | ||
334 | int virq; | ||
335 | |||
336 | if (!regbase) | ||
337 | return; | ||
338 | |||
339 | virq = irq_of_parse_and_map(np, 0); | ||
340 | if (!virq) | ||
341 | return; | ||
342 | |||
343 | pmc = at91_pmc_init(np, regbase, virq, caps); | ||
344 | if (!pmc) | ||
345 | return; | ||
346 | for_each_child_of_node(np, childnp) { | ||
347 | clk_id = of_match_node(pmc_clk_ids, childnp); | ||
348 | if (!clk_id) | ||
349 | continue; | ||
350 | clk_setup = clk_id->data; | ||
351 | clk_setup(childnp, pmc); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | static void __init of_at91rm9200_pmc_setup(struct device_node *np) | ||
356 | { | ||
357 | of_at91_pmc_setup(np, &at91rm9200_caps); | ||
358 | } | ||
359 | CLK_OF_DECLARE(at91rm9200_clk_pmc, "atmel,at91rm9200-pmc", | ||
360 | of_at91rm9200_pmc_setup); | ||
361 | |||
362 | static void __init of_at91sam9260_pmc_setup(struct device_node *np) | ||
363 | { | ||
364 | of_at91_pmc_setup(np, &at91sam9260_caps); | ||
365 | } | ||
366 | CLK_OF_DECLARE(at91sam9260_clk_pmc, "atmel,at91sam9260-pmc", | ||
367 | of_at91sam9260_pmc_setup); | ||
368 | |||
369 | static void __init of_at91sam9g45_pmc_setup(struct device_node *np) | ||
370 | { | ||
371 | of_at91_pmc_setup(np, &at91sam9g45_caps); | ||
372 | } | ||
373 | CLK_OF_DECLARE(at91sam9g45_clk_pmc, "atmel,at91sam9g45-pmc", | ||
374 | of_at91sam9g45_pmc_setup); | ||
375 | |||
376 | static void __init of_at91sam9n12_pmc_setup(struct device_node *np) | ||
377 | { | ||
378 | of_at91_pmc_setup(np, &at91sam9n12_caps); | ||
379 | } | ||
380 | CLK_OF_DECLARE(at91sam9n12_clk_pmc, "atmel,at91sam9n12-pmc", | ||
381 | of_at91sam9n12_pmc_setup); | ||
382 | |||
383 | static void __init of_at91sam9x5_pmc_setup(struct device_node *np) | ||
384 | { | ||
385 | of_at91_pmc_setup(np, &at91sam9x5_caps); | ||
386 | } | ||
387 | CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc", | ||
388 | of_at91sam9x5_pmc_setup); | ||
389 | |||
390 | static void __init of_sama5d3_pmc_setup(struct device_node *np) | ||
391 | { | ||
392 | of_at91_pmc_setup(np, &sama5d3_caps); | ||
393 | } | ||
394 | CLK_OF_DECLARE(sama5d3_clk_pmc, "atmel,sama5d3-pmc", | ||
395 | of_sama5d3_pmc_setup); | ||
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h new file mode 100644 index 000000000000..441350983ccb --- /dev/null +++ b/drivers/clk/at91/pmc.h | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * drivers/clk/at91/pmc.h | ||
3 | * | ||
4 | * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef __PMC_H_ | ||
13 | #define __PMC_H_ | ||
14 | |||
15 | #include <linux/io.h> | ||
16 | #include <linux/irqdomain.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | |||
19 | struct clk_range { | ||
20 | unsigned long min; | ||
21 | unsigned long max; | ||
22 | }; | ||
23 | |||
24 | #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,} | ||
25 | |||
26 | struct at91_pmc_caps { | ||
27 | u32 available_irqs; | ||
28 | }; | ||
29 | |||
30 | struct at91_pmc { | ||
31 | void __iomem *regbase; | ||
32 | int virq; | ||
33 | spinlock_t lock; | ||
34 | const struct at91_pmc_caps *caps; | ||
35 | struct irq_domain *irqdomain; | ||
36 | }; | ||
37 | |||
38 | static inline void pmc_lock(struct at91_pmc *pmc) | ||
39 | { | ||
40 | spin_lock(&pmc->lock); | ||
41 | } | ||
42 | |||
43 | static inline void pmc_unlock(struct at91_pmc *pmc) | ||
44 | { | ||
45 | spin_unlock(&pmc->lock); | ||
46 | } | ||
47 | |||
48 | static inline u32 pmc_read(struct at91_pmc *pmc, int offset) | ||
49 | { | ||
50 | return readl(pmc->regbase + offset); | ||
51 | } | ||
52 | |||
53 | static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value) | ||
54 | { | ||
55 | writel(value, pmc->regbase + offset); | ||
56 | } | ||
57 | |||
58 | int of_at91_get_clk_range(struct device_node *np, const char *propname, | ||
59 | struct clk_range *range); | ||
60 | |||
61 | extern void __init of_at91rm9200_clk_main_setup(struct device_node *np, | ||
62 | struct at91_pmc *pmc); | ||
63 | |||
64 | extern void __init of_at91rm9200_clk_pll_setup(struct device_node *np, | ||
65 | struct at91_pmc *pmc); | ||
66 | extern void __init of_at91sam9g45_clk_pll_setup(struct device_node *np, | ||
67 | struct at91_pmc *pmc); | ||
68 | extern void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np, | ||
69 | struct at91_pmc *pmc); | ||
70 | extern void __init of_sama5d3_clk_pll_setup(struct device_node *np, | ||
71 | struct at91_pmc *pmc); | ||
72 | extern void __init of_at91sam9x5_clk_plldiv_setup(struct device_node *np, | ||
73 | struct at91_pmc *pmc); | ||
74 | |||
75 | extern void __init of_at91rm9200_clk_master_setup(struct device_node *np, | ||
76 | struct at91_pmc *pmc); | ||
77 | extern void __init of_at91sam9x5_clk_master_setup(struct device_node *np, | ||
78 | struct at91_pmc *pmc); | ||
79 | |||
80 | extern void __init of_at91rm9200_clk_sys_setup(struct device_node *np, | ||
81 | struct at91_pmc *pmc); | ||
82 | |||
83 | extern void __init of_at91rm9200_clk_periph_setup(struct device_node *np, | ||
84 | struct at91_pmc *pmc); | ||
85 | extern void __init of_at91sam9x5_clk_periph_setup(struct device_node *np, | ||
86 | struct at91_pmc *pmc); | ||
87 | |||
88 | extern void __init of_at91rm9200_clk_prog_setup(struct device_node *np, | ||
89 | struct at91_pmc *pmc); | ||
90 | extern void __init of_at91sam9g45_clk_prog_setup(struct device_node *np, | ||
91 | struct at91_pmc *pmc); | ||
92 | extern void __init of_at91sam9x5_clk_prog_setup(struct device_node *np, | ||
93 | struct at91_pmc *pmc); | ||
94 | |||
95 | #if defined(CONFIG_HAVE_AT91_UTMI) | ||
96 | extern void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np, | ||
97 | struct at91_pmc *pmc); | ||
98 | #endif | ||
99 | |||
100 | #if defined(CONFIG_HAVE_AT91_USB_CLK) | ||
101 | extern void __init of_at91rm9200_clk_usb_setup(struct device_node *np, | ||
102 | struct at91_pmc *pmc); | ||
103 | extern void __init of_at91sam9x5_clk_usb_setup(struct device_node *np, | ||
104 | struct at91_pmc *pmc); | ||
105 | extern void __init of_at91sam9n12_clk_usb_setup(struct device_node *np, | ||
106 | struct at91_pmc *pmc); | ||
107 | #endif | ||
108 | |||
109 | #if defined(CONFIG_HAVE_AT91_SMD) | ||
110 | extern void __init of_at91sam9x5_clk_smd_setup(struct device_node *np, | ||
111 | struct at91_pmc *pmc); | ||
112 | #endif | ||
113 | |||
114 | #endif /* __PMC_H_ */ | ||
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index f49fac2d193a..f7dfb72884a4 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile | |||
@@ -6,7 +6,12 @@ obj-y += clk-periph-gate.o | |||
6 | obj-y += clk-pll.o | 6 | obj-y += clk-pll.o |
7 | obj-y += clk-pll-out.o | 7 | obj-y += clk-pll-out.o |
8 | obj-y += clk-super.o | 8 | obj-y += clk-super.o |
9 | 9 | obj-y += clk-tegra-audio.o | |
10 | obj-y += clk-tegra-periph.o | ||
11 | obj-y += clk-tegra-pmc.o | ||
12 | obj-y += clk-tegra-fixed.o | ||
13 | obj-y += clk-tegra-super-gen4.o | ||
10 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o | 14 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o |
11 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o | 15 | obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o |
12 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o | 16 | obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o |
17 | obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o | ||
diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h new file mode 100644 index 000000000000..cf0c323f2c36 --- /dev/null +++ b/drivers/clk/tegra/clk-id.h | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | * This header provides IDs for clocks common between several Tegra SoCs | ||
3 | */ | ||
4 | #ifndef _TEGRA_CLK_ID_H | ||
5 | #define _TEGRA_CLK_ID_H | ||
6 | |||
7 | enum clk_id { | ||
8 | tegra_clk_actmon, | ||
9 | tegra_clk_adx, | ||
10 | tegra_clk_adx1, | ||
11 | tegra_clk_afi, | ||
12 | tegra_clk_amx, | ||
13 | tegra_clk_amx1, | ||
14 | tegra_clk_apbdma, | ||
15 | tegra_clk_apbif, | ||
16 | tegra_clk_audio0, | ||
17 | tegra_clk_audio0_2x, | ||
18 | tegra_clk_audio0_mux, | ||
19 | tegra_clk_audio1, | ||
20 | tegra_clk_audio1_2x, | ||
21 | tegra_clk_audio1_mux, | ||
22 | tegra_clk_audio2, | ||
23 | tegra_clk_audio2_2x, | ||
24 | tegra_clk_audio2_mux, | ||
25 | tegra_clk_audio3, | ||
26 | tegra_clk_audio3_2x, | ||
27 | tegra_clk_audio3_mux, | ||
28 | tegra_clk_audio4, | ||
29 | tegra_clk_audio4_2x, | ||
30 | tegra_clk_audio4_mux, | ||
31 | tegra_clk_blink, | ||
32 | tegra_clk_bsea, | ||
33 | tegra_clk_bsev, | ||
34 | tegra_clk_cclk_g, | ||
35 | tegra_clk_cclk_lp, | ||
36 | tegra_clk_cilab, | ||
37 | tegra_clk_cilcd, | ||
38 | tegra_clk_cile, | ||
39 | tegra_clk_clk_32k, | ||
40 | tegra_clk_clk72Mhz, | ||
41 | tegra_clk_clk_m, | ||
42 | tegra_clk_clk_m_div2, | ||
43 | tegra_clk_clk_m_div4, | ||
44 | tegra_clk_clk_out_1, | ||
45 | tegra_clk_clk_out_1_mux, | ||
46 | tegra_clk_clk_out_2, | ||
47 | tegra_clk_clk_out_2_mux, | ||
48 | tegra_clk_clk_out_3, | ||
49 | tegra_clk_clk_out_3_mux, | ||
50 | tegra_clk_cml0, | ||
51 | tegra_clk_cml1, | ||
52 | tegra_clk_csi, | ||
53 | tegra_clk_csite, | ||
54 | tegra_clk_csus, | ||
55 | tegra_clk_cve, | ||
56 | tegra_clk_dam0, | ||
57 | tegra_clk_dam1, | ||
58 | tegra_clk_dam2, | ||
59 | tegra_clk_d_audio, | ||
60 | tegra_clk_dds, | ||
61 | tegra_clk_dfll_ref, | ||
62 | tegra_clk_dfll_soc, | ||
63 | tegra_clk_disp1, | ||
64 | tegra_clk_disp2, | ||
65 | tegra_clk_dp2, | ||
66 | tegra_clk_dpaux, | ||
67 | tegra_clk_dsia, | ||
68 | tegra_clk_dsialp, | ||
69 | tegra_clk_dsia_mux, | ||
70 | tegra_clk_dsib, | ||
71 | tegra_clk_dsiblp, | ||
72 | tegra_clk_dsib_mux, | ||
73 | tegra_clk_dtv, | ||
74 | tegra_clk_emc, | ||
75 | tegra_clk_entropy, | ||
76 | tegra_clk_epp, | ||
77 | tegra_clk_epp_8, | ||
78 | tegra_clk_extern1, | ||
79 | tegra_clk_extern2, | ||
80 | tegra_clk_extern3, | ||
81 | tegra_clk_fuse, | ||
82 | tegra_clk_fuse_burn, | ||
83 | tegra_clk_gpu, | ||
84 | tegra_clk_gr2d, | ||
85 | tegra_clk_gr2d_8, | ||
86 | tegra_clk_gr3d, | ||
87 | tegra_clk_gr3d_8, | ||
88 | tegra_clk_hclk, | ||
89 | tegra_clk_hda, | ||
90 | tegra_clk_hda2codec_2x, | ||
91 | tegra_clk_hda2hdmi, | ||
92 | tegra_clk_hdmi, | ||
93 | tegra_clk_hdmi_audio, | ||
94 | tegra_clk_host1x, | ||
95 | tegra_clk_host1x_8, | ||
96 | tegra_clk_i2c1, | ||
97 | tegra_clk_i2c2, | ||
98 | tegra_clk_i2c3, | ||
99 | tegra_clk_i2c4, | ||
100 | tegra_clk_i2c5, | ||
101 | tegra_clk_i2c6, | ||
102 | tegra_clk_i2cslow, | ||
103 | tegra_clk_i2s0, | ||
104 | tegra_clk_i2s0_sync, | ||
105 | tegra_clk_i2s1, | ||
106 | tegra_clk_i2s1_sync, | ||
107 | tegra_clk_i2s2, | ||
108 | tegra_clk_i2s2_sync, | ||
109 | tegra_clk_i2s3, | ||
110 | tegra_clk_i2s3_sync, | ||
111 | tegra_clk_i2s4, | ||
112 | tegra_clk_i2s4_sync, | ||
113 | tegra_clk_isp, | ||
114 | tegra_clk_isp_8, | ||
115 | tegra_clk_ispb, | ||
116 | tegra_clk_kbc, | ||
117 | tegra_clk_kfuse, | ||
118 | tegra_clk_la, | ||
119 | tegra_clk_mipi, | ||
120 | tegra_clk_mipi_cal, | ||
121 | tegra_clk_mpe, | ||
122 | tegra_clk_mselect, | ||
123 | tegra_clk_msenc, | ||
124 | tegra_clk_ndflash, | ||
125 | tegra_clk_ndflash_8, | ||
126 | tegra_clk_ndspeed, | ||
127 | tegra_clk_ndspeed_8, | ||
128 | tegra_clk_nor, | ||
129 | tegra_clk_owr, | ||
130 | tegra_clk_pcie, | ||
131 | tegra_clk_pclk, | ||
132 | tegra_clk_pll_a, | ||
133 | tegra_clk_pll_a_out0, | ||
134 | tegra_clk_pll_c, | ||
135 | tegra_clk_pll_c2, | ||
136 | tegra_clk_pll_c3, | ||
137 | tegra_clk_pll_c4, | ||
138 | tegra_clk_pll_c_out1, | ||
139 | tegra_clk_pll_d, | ||
140 | tegra_clk_pll_d2, | ||
141 | tegra_clk_pll_d2_out0, | ||
142 | tegra_clk_pll_d_out0, | ||
143 | tegra_clk_pll_dp, | ||
144 | tegra_clk_pll_e_out0, | ||
145 | tegra_clk_pll_m, | ||
146 | tegra_clk_pll_m_out1, | ||
147 | tegra_clk_pll_p, | ||
148 | tegra_clk_pll_p_out1, | ||
149 | tegra_clk_pll_p_out2, | ||
150 | tegra_clk_pll_p_out2_int, | ||
151 | tegra_clk_pll_p_out3, | ||
152 | tegra_clk_pll_p_out4, | ||
153 | tegra_clk_pll_p_out5, | ||
154 | tegra_clk_pll_ref, | ||
155 | tegra_clk_pll_re_out, | ||
156 | tegra_clk_pll_re_vco, | ||
157 | tegra_clk_pll_u, | ||
158 | tegra_clk_pll_u_12m, | ||
159 | tegra_clk_pll_u_480m, | ||
160 | tegra_clk_pll_u_48m, | ||
161 | tegra_clk_pll_u_60m, | ||
162 | tegra_clk_pll_x, | ||
163 | tegra_clk_pll_x_out0, | ||
164 | tegra_clk_pwm, | ||
165 | tegra_clk_rtc, | ||
166 | tegra_clk_sata, | ||
167 | tegra_clk_sata_cold, | ||
168 | tegra_clk_sata_oob, | ||
169 | tegra_clk_sbc1, | ||
170 | tegra_clk_sbc1_8, | ||
171 | tegra_clk_sbc2, | ||
172 | tegra_clk_sbc2_8, | ||
173 | tegra_clk_sbc3, | ||
174 | tegra_clk_sbc3_8, | ||
175 | tegra_clk_sbc4, | ||
176 | tegra_clk_sbc4_8, | ||
177 | tegra_clk_sbc5, | ||
178 | tegra_clk_sbc5_8, | ||
179 | tegra_clk_sbc6, | ||
180 | tegra_clk_sbc6_8, | ||
181 | tegra_clk_sclk, | ||
182 | tegra_clk_sdmmc1, | ||
183 | tegra_clk_sdmmc2, | ||
184 | tegra_clk_sdmmc3, | ||
185 | tegra_clk_sdmmc4, | ||
186 | tegra_clk_se, | ||
187 | tegra_clk_soc_therm, | ||
188 | tegra_clk_sor0, | ||
189 | tegra_clk_sor0_lvds, | ||
190 | tegra_clk_spdif, | ||
191 | tegra_clk_spdif_2x, | ||
192 | tegra_clk_spdif_in, | ||
193 | tegra_clk_spdif_in_sync, | ||
194 | tegra_clk_spdif_mux, | ||
195 | tegra_clk_spdif_out, | ||
196 | tegra_clk_timer, | ||
197 | tegra_clk_trace, | ||
198 | tegra_clk_tsec, | ||
199 | tegra_clk_tsensor, | ||
200 | tegra_clk_tvdac, | ||
201 | tegra_clk_tvo, | ||
202 | tegra_clk_uarta, | ||
203 | tegra_clk_uartb, | ||
204 | tegra_clk_uartc, | ||
205 | tegra_clk_uartd, | ||
206 | tegra_clk_uarte, | ||
207 | tegra_clk_usb2, | ||
208 | tegra_clk_usb3, | ||
209 | tegra_clk_usbd, | ||
210 | tegra_clk_vcp, | ||
211 | tegra_clk_vde, | ||
212 | tegra_clk_vde_8, | ||
213 | tegra_clk_vfir, | ||
214 | tegra_clk_vi, | ||
215 | tegra_clk_vi_8, | ||
216 | tegra_clk_vi_9, | ||
217 | tegra_clk_vic03, | ||
218 | tegra_clk_vim2_clk, | ||
219 | tegra_clk_vimclk_sync, | ||
220 | tegra_clk_vi_sensor, | ||
221 | tegra_clk_vi_sensor2, | ||
222 | tegra_clk_vi_sensor_8, | ||
223 | tegra_clk_xusb_dev, | ||
224 | tegra_clk_xusb_dev_src, | ||
225 | tegra_clk_xusb_falcon_src, | ||
226 | tegra_clk_xusb_fs_src, | ||
227 | tegra_clk_xusb_host, | ||
228 | tegra_clk_xusb_host_src, | ||
229 | tegra_clk_xusb_hs_src, | ||
230 | tegra_clk_xusb_ss, | ||
231 | tegra_clk_xusb_ss_src, | ||
232 | tegra_clk_max, | ||
233 | }; | ||
234 | |||
235 | #endif /* _TEGRA_CLK_ID_H */ | ||
diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index bafee9895a24..507015314827 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c | |||
@@ -36,8 +36,6 @@ static DEFINE_SPINLOCK(periph_ref_lock); | |||
36 | 36 | ||
37 | #define read_rst(gate) \ | 37 | #define read_rst(gate) \ |
38 | readl_relaxed(gate->clk_base + (gate->regs->rst_reg)) | 38 | readl_relaxed(gate->clk_base + (gate->regs->rst_reg)) |
39 | #define write_rst_set(val, gate) \ | ||
40 | writel_relaxed(val, gate->clk_base + (gate->regs->rst_set_reg)) | ||
41 | #define write_rst_clr(val, gate) \ | 39 | #define write_rst_clr(val, gate) \ |
42 | writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg)) | 40 | writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg)) |
43 | 41 | ||
@@ -123,26 +121,6 @@ static void clk_periph_disable(struct clk_hw *hw) | |||
123 | spin_unlock_irqrestore(&periph_ref_lock, flags); | 121 | spin_unlock_irqrestore(&periph_ref_lock, flags); |
124 | } | 122 | } |
125 | 123 | ||
126 | void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert) | ||
127 | { | ||
128 | if (gate->flags & TEGRA_PERIPH_NO_RESET) | ||
129 | return; | ||
130 | |||
131 | if (assert) { | ||
132 | /* | ||
133 | * If peripheral is in the APB bus then read the APB bus to | ||
134 | * flush the write operation in apb bus. This will avoid the | ||
135 | * peripheral access after disabling clock | ||
136 | */ | ||
137 | if (gate->flags & TEGRA_PERIPH_ON_APB) | ||
138 | tegra_read_chipid(); | ||
139 | |||
140 | write_rst_set(periph_clk_to_bit(gate), gate); | ||
141 | } else { | ||
142 | write_rst_clr(periph_clk_to_bit(gate), gate); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | const struct clk_ops tegra_clk_periph_gate_ops = { | 124 | const struct clk_ops tegra_clk_periph_gate_ops = { |
147 | .is_enabled = clk_periph_is_enabled, | 125 | .is_enabled = clk_periph_is_enabled, |
148 | .enable = clk_periph_enable, | 126 | .enable = clk_periph_enable, |
@@ -151,12 +129,16 @@ const struct clk_ops tegra_clk_periph_gate_ops = { | |||
151 | 129 | ||
152 | struct clk *tegra_clk_register_periph_gate(const char *name, | 130 | struct clk *tegra_clk_register_periph_gate(const char *name, |
153 | const char *parent_name, u8 gate_flags, void __iomem *clk_base, | 131 | const char *parent_name, u8 gate_flags, void __iomem *clk_base, |
154 | unsigned long flags, int clk_num, | 132 | unsigned long flags, int clk_num, int *enable_refcnt) |
155 | struct tegra_clk_periph_regs *pregs, int *enable_refcnt) | ||
156 | { | 133 | { |
157 | struct tegra_clk_periph_gate *gate; | 134 | struct tegra_clk_periph_gate *gate; |
158 | struct clk *clk; | 135 | struct clk *clk; |
159 | struct clk_init_data init; | 136 | struct clk_init_data init; |
137 | struct tegra_clk_periph_regs *pregs; | ||
138 | |||
139 | pregs = get_reg_bank(clk_num); | ||
140 | if (!pregs) | ||
141 | return ERR_PTR(-EINVAL); | ||
160 | 142 | ||
161 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); | 143 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); |
162 | if (!gate) { | 144 | if (!gate) { |
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index b2309d37a963..c534043c0481 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c | |||
@@ -111,46 +111,6 @@ static void clk_periph_disable(struct clk_hw *hw) | |||
111 | gate_ops->disable(gate_hw); | 111 | gate_ops->disable(gate_hw); |
112 | } | 112 | } |
113 | 113 | ||
114 | void tegra_periph_reset_deassert(struct clk *c) | ||
115 | { | ||
116 | struct clk_hw *hw = __clk_get_hw(c); | ||
117 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
118 | struct tegra_clk_periph_gate *gate; | ||
119 | |||
120 | if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) { | ||
121 | gate = to_clk_periph_gate(hw); | ||
122 | if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) { | ||
123 | WARN_ON(1); | ||
124 | return; | ||
125 | } | ||
126 | } else { | ||
127 | gate = &periph->gate; | ||
128 | } | ||
129 | |||
130 | tegra_periph_reset(gate, 0); | ||
131 | } | ||
132 | EXPORT_SYMBOL(tegra_periph_reset_deassert); | ||
133 | |||
134 | void tegra_periph_reset_assert(struct clk *c) | ||
135 | { | ||
136 | struct clk_hw *hw = __clk_get_hw(c); | ||
137 | struct tegra_clk_periph *periph = to_clk_periph(hw); | ||
138 | struct tegra_clk_periph_gate *gate; | ||
139 | |||
140 | if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) { | ||
141 | gate = to_clk_periph_gate(hw); | ||
142 | if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) { | ||
143 | WARN_ON(1); | ||
144 | return; | ||
145 | } | ||
146 | } else { | ||
147 | gate = &periph->gate; | ||
148 | } | ||
149 | |||
150 | tegra_periph_reset(gate, 1); | ||
151 | } | ||
152 | EXPORT_SYMBOL(tegra_periph_reset_assert); | ||
153 | |||
154 | const struct clk_ops tegra_clk_periph_ops = { | 114 | const struct clk_ops tegra_clk_periph_ops = { |
155 | .get_parent = clk_periph_get_parent, | 115 | .get_parent = clk_periph_get_parent, |
156 | .set_parent = clk_periph_set_parent, | 116 | .set_parent = clk_periph_set_parent, |
@@ -170,27 +130,50 @@ const struct clk_ops tegra_clk_periph_nodiv_ops = { | |||
170 | .disable = clk_periph_disable, | 130 | .disable = clk_periph_disable, |
171 | }; | 131 | }; |
172 | 132 | ||
133 | const struct clk_ops tegra_clk_periph_no_gate_ops = { | ||
134 | .get_parent = clk_periph_get_parent, | ||
135 | .set_parent = clk_periph_set_parent, | ||
136 | .recalc_rate = clk_periph_recalc_rate, | ||
137 | .round_rate = clk_periph_round_rate, | ||
138 | .set_rate = clk_periph_set_rate, | ||
139 | }; | ||
140 | |||
173 | static struct clk *_tegra_clk_register_periph(const char *name, | 141 | static struct clk *_tegra_clk_register_periph(const char *name, |
174 | const char **parent_names, int num_parents, | 142 | const char **parent_names, int num_parents, |
175 | struct tegra_clk_periph *periph, | 143 | struct tegra_clk_periph *periph, |
176 | void __iomem *clk_base, u32 offset, bool div, | 144 | void __iomem *clk_base, u32 offset, |
177 | unsigned long flags) | 145 | unsigned long flags) |
178 | { | 146 | { |
179 | struct clk *clk; | 147 | struct clk *clk; |
180 | struct clk_init_data init; | 148 | struct clk_init_data init; |
149 | struct tegra_clk_periph_regs *bank; | ||
150 | bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); | ||
151 | |||
152 | if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) { | ||
153 | flags |= CLK_SET_RATE_PARENT; | ||
154 | init.ops = &tegra_clk_periph_nodiv_ops; | ||
155 | } else if (periph->gate.flags & TEGRA_PERIPH_NO_GATE) | ||
156 | init.ops = &tegra_clk_periph_no_gate_ops; | ||
157 | else | ||
158 | init.ops = &tegra_clk_periph_ops; | ||
181 | 159 | ||
182 | init.name = name; | 160 | init.name = name; |
183 | init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops; | ||
184 | init.flags = flags; | 161 | init.flags = flags; |
185 | init.parent_names = parent_names; | 162 | init.parent_names = parent_names; |
186 | init.num_parents = num_parents; | 163 | init.num_parents = num_parents; |
187 | 164 | ||
165 | bank = get_reg_bank(periph->gate.clk_num); | ||
166 | if (!bank) | ||
167 | return ERR_PTR(-EINVAL); | ||
168 | |||
188 | /* Data in .init is copied by clk_register(), so stack variable OK */ | 169 | /* Data in .init is copied by clk_register(), so stack variable OK */ |
189 | periph->hw.init = &init; | 170 | periph->hw.init = &init; |
190 | periph->magic = TEGRA_CLK_PERIPH_MAGIC; | 171 | periph->magic = TEGRA_CLK_PERIPH_MAGIC; |
191 | periph->mux.reg = clk_base + offset; | 172 | periph->mux.reg = clk_base + offset; |
192 | periph->divider.reg = div ? (clk_base + offset) : NULL; | 173 | periph->divider.reg = div ? (clk_base + offset) : NULL; |
193 | periph->gate.clk_base = clk_base; | 174 | periph->gate.clk_base = clk_base; |
175 | periph->gate.regs = bank; | ||
176 | periph->gate.enable_refcnt = periph_clk_enb_refcnt; | ||
194 | 177 | ||
195 | clk = clk_register(NULL, &periph->hw); | 178 | clk = clk_register(NULL, &periph->hw); |
196 | if (IS_ERR(clk)) | 179 | if (IS_ERR(clk)) |
@@ -209,7 +192,7 @@ struct clk *tegra_clk_register_periph(const char *name, | |||
209 | u32 offset, unsigned long flags) | 192 | u32 offset, unsigned long flags) |
210 | { | 193 | { |
211 | return _tegra_clk_register_periph(name, parent_names, num_parents, | 194 | return _tegra_clk_register_periph(name, parent_names, num_parents, |
212 | periph, clk_base, offset, true, flags); | 195 | periph, clk_base, offset, flags); |
213 | } | 196 | } |
214 | 197 | ||
215 | struct clk *tegra_clk_register_periph_nodiv(const char *name, | 198 | struct clk *tegra_clk_register_periph_nodiv(const char *name, |
@@ -217,6 +200,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, | |||
217 | struct tegra_clk_periph *periph, void __iomem *clk_base, | 200 | struct tegra_clk_periph *periph, void __iomem *clk_base, |
218 | u32 offset) | 201 | u32 offset) |
219 | { | 202 | { |
203 | periph->gate.flags |= TEGRA_PERIPH_NO_DIV; | ||
220 | return _tegra_clk_register_periph(name, parent_names, num_parents, | 204 | return _tegra_clk_register_periph(name, parent_names, num_parents, |
221 | periph, clk_base, offset, false, CLK_SET_RATE_PARENT); | 205 | periph, clk_base, offset, CLK_SET_RATE_PARENT); |
222 | } | 206 | } |
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 197074a57754..2dd432266ef6 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c | |||
@@ -77,7 +77,23 @@ | |||
77 | #define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT) | 77 | #define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT) |
78 | 78 | ||
79 | #define PLLE_SS_CTRL 0x68 | 79 | #define PLLE_SS_CTRL 0x68 |
80 | #define PLLE_SS_DISABLE (7 << 10) | 80 | #define PLLE_SS_CNTL_BYPASS_SS BIT(10) |
81 | #define PLLE_SS_CNTL_INTERP_RESET BIT(11) | ||
82 | #define PLLE_SS_CNTL_SSC_BYP BIT(12) | ||
83 | #define PLLE_SS_CNTL_CENTER BIT(14) | ||
84 | #define PLLE_SS_CNTL_INVERT BIT(15) | ||
85 | #define PLLE_SS_DISABLE (PLLE_SS_CNTL_BYPASS_SS | PLLE_SS_CNTL_INTERP_RESET |\ | ||
86 | PLLE_SS_CNTL_SSC_BYP) | ||
87 | #define PLLE_SS_MAX_MASK 0x1ff | ||
88 | #define PLLE_SS_MAX_VAL 0x25 | ||
89 | #define PLLE_SS_INC_MASK (0xff << 16) | ||
90 | #define PLLE_SS_INC_VAL (0x1 << 16) | ||
91 | #define PLLE_SS_INCINTRV_MASK (0x3f << 24) | ||
92 | #define PLLE_SS_INCINTRV_VAL (0x20 << 24) | ||
93 | #define PLLE_SS_COEFFICIENTS_MASK \ | ||
94 | (PLLE_SS_MAX_MASK | PLLE_SS_INC_MASK | PLLE_SS_INCINTRV_MASK) | ||
95 | #define PLLE_SS_COEFFICIENTS_VAL \ | ||
96 | (PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL) | ||
81 | 97 | ||
82 | #define PLLE_AUX_PLLP_SEL BIT(2) | 98 | #define PLLE_AUX_PLLP_SEL BIT(2) |
83 | #define PLLE_AUX_ENABLE_SWCTL BIT(4) | 99 | #define PLLE_AUX_ENABLE_SWCTL BIT(4) |
@@ -121,6 +137,36 @@ | |||
121 | #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) | 137 | #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5) |
122 | #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) | 138 | #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4) |
123 | 139 | ||
140 | #define PLLSS_MISC_KCP 0 | ||
141 | #define PLLSS_MISC_KVCO 0 | ||
142 | #define PLLSS_MISC_SETUP 0 | ||
143 | #define PLLSS_EN_SDM 0 | ||
144 | #define PLLSS_EN_SSC 0 | ||
145 | #define PLLSS_EN_DITHER2 0 | ||
146 | #define PLLSS_EN_DITHER 1 | ||
147 | #define PLLSS_SDM_RESET 0 | ||
148 | #define PLLSS_CLAMP 0 | ||
149 | #define PLLSS_SDM_SSC_MAX 0 | ||
150 | #define PLLSS_SDM_SSC_MIN 0 | ||
151 | #define PLLSS_SDM_SSC_STEP 0 | ||
152 | #define PLLSS_SDM_DIN 0 | ||
153 | #define PLLSS_MISC_DEFAULT ((PLLSS_MISC_KCP << 25) | \ | ||
154 | (PLLSS_MISC_KVCO << 24) | \ | ||
155 | PLLSS_MISC_SETUP) | ||
156 | #define PLLSS_CFG_DEFAULT ((PLLSS_EN_SDM << 31) | \ | ||
157 | (PLLSS_EN_SSC << 30) | \ | ||
158 | (PLLSS_EN_DITHER2 << 29) | \ | ||
159 | (PLLSS_EN_DITHER << 28) | \ | ||
160 | (PLLSS_SDM_RESET) << 27 | \ | ||
161 | (PLLSS_CLAMP << 22)) | ||
162 | #define PLLSS_CTRL1_DEFAULT \ | ||
163 | ((PLLSS_SDM_SSC_MAX << 16) | PLLSS_SDM_SSC_MIN) | ||
164 | #define PLLSS_CTRL2_DEFAULT \ | ||
165 | ((PLLSS_SDM_SSC_STEP << 16) | PLLSS_SDM_DIN) | ||
166 | #define PLLSS_LOCK_OVERRIDE BIT(24) | ||
167 | #define PLLSS_REF_SRC_SEL_SHIFT 25 | ||
168 | #define PLLSS_REF_SRC_SEL_MASK (3 << PLLSS_REF_SRC_SEL_SHIFT) | ||
169 | |||
124 | #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) | 170 | #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset) |
125 | #define pll_readl_base(p) pll_readl(p->params->base_reg, p) | 171 | #define pll_readl_base(p) pll_readl(p->params->base_reg, p) |
126 | #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) | 172 | #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p) |
@@ -134,7 +180,7 @@ | |||
134 | #define mask(w) ((1 << (w)) - 1) | 180 | #define mask(w) ((1 << (w)) - 1) |
135 | #define divm_mask(p) mask(p->params->div_nmp->divm_width) | 181 | #define divm_mask(p) mask(p->params->div_nmp->divm_width) |
136 | #define divn_mask(p) mask(p->params->div_nmp->divn_width) | 182 | #define divn_mask(p) mask(p->params->div_nmp->divn_width) |
137 | #define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ | 183 | #define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\ |
138 | mask(p->params->div_nmp->divp_width)) | 184 | mask(p->params->div_nmp->divp_width)) |
139 | 185 | ||
140 | #define divm_max(p) (divm_mask(p)) | 186 | #define divm_max(p) (divm_mask(p)) |
@@ -154,10 +200,10 @@ static void clk_pll_enable_lock(struct tegra_clk_pll *pll) | |||
154 | { | 200 | { |
155 | u32 val; | 201 | u32 val; |
156 | 202 | ||
157 | if (!(pll->flags & TEGRA_PLL_USE_LOCK)) | 203 | if (!(pll->params->flags & TEGRA_PLL_USE_LOCK)) |
158 | return; | 204 | return; |
159 | 205 | ||
160 | if (!(pll->flags & TEGRA_PLL_HAS_LOCK_ENABLE)) | 206 | if (!(pll->params->flags & TEGRA_PLL_HAS_LOCK_ENABLE)) |
161 | return; | 207 | return; |
162 | 208 | ||
163 | val = pll_readl_misc(pll); | 209 | val = pll_readl_misc(pll); |
@@ -171,13 +217,13 @@ static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll) | |||
171 | u32 val, lock_mask; | 217 | u32 val, lock_mask; |
172 | void __iomem *lock_addr; | 218 | void __iomem *lock_addr; |
173 | 219 | ||
174 | if (!(pll->flags & TEGRA_PLL_USE_LOCK)) { | 220 | if (!(pll->params->flags & TEGRA_PLL_USE_LOCK)) { |
175 | udelay(pll->params->lock_delay); | 221 | udelay(pll->params->lock_delay); |
176 | return 0; | 222 | return 0; |
177 | } | 223 | } |
178 | 224 | ||
179 | lock_addr = pll->clk_base; | 225 | lock_addr = pll->clk_base; |
180 | if (pll->flags & TEGRA_PLL_LOCK_MISC) | 226 | if (pll->params->flags & TEGRA_PLL_LOCK_MISC) |
181 | lock_addr += pll->params->misc_reg; | 227 | lock_addr += pll->params->misc_reg; |
182 | else | 228 | else |
183 | lock_addr += pll->params->base_reg; | 229 | lock_addr += pll->params->base_reg; |
@@ -204,7 +250,7 @@ static int clk_pll_is_enabled(struct clk_hw *hw) | |||
204 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 250 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
205 | u32 val; | 251 | u32 val; |
206 | 252 | ||
207 | if (pll->flags & TEGRA_PLLM) { | 253 | if (pll->params->flags & TEGRA_PLLM) { |
208 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 254 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
209 | if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) | 255 | if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) |
210 | return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0; | 256 | return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0; |
@@ -223,12 +269,12 @@ static void _clk_pll_enable(struct clk_hw *hw) | |||
223 | clk_pll_enable_lock(pll); | 269 | clk_pll_enable_lock(pll); |
224 | 270 | ||
225 | val = pll_readl_base(pll); | 271 | val = pll_readl_base(pll); |
226 | if (pll->flags & TEGRA_PLL_BYPASS) | 272 | if (pll->params->flags & TEGRA_PLL_BYPASS) |
227 | val &= ~PLL_BASE_BYPASS; | 273 | val &= ~PLL_BASE_BYPASS; |
228 | val |= PLL_BASE_ENABLE; | 274 | val |= PLL_BASE_ENABLE; |
229 | pll_writel_base(val, pll); | 275 | pll_writel_base(val, pll); |
230 | 276 | ||
231 | if (pll->flags & TEGRA_PLLM) { | 277 | if (pll->params->flags & TEGRA_PLLM) { |
232 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 278 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
233 | val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | 279 | val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; |
234 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 280 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
@@ -241,12 +287,12 @@ static void _clk_pll_disable(struct clk_hw *hw) | |||
241 | u32 val; | 287 | u32 val; |
242 | 288 | ||
243 | val = pll_readl_base(pll); | 289 | val = pll_readl_base(pll); |
244 | if (pll->flags & TEGRA_PLL_BYPASS) | 290 | if (pll->params->flags & TEGRA_PLL_BYPASS) |
245 | val &= ~PLL_BASE_BYPASS; | 291 | val &= ~PLL_BASE_BYPASS; |
246 | val &= ~PLL_BASE_ENABLE; | 292 | val &= ~PLL_BASE_ENABLE; |
247 | pll_writel_base(val, pll); | 293 | pll_writel_base(val, pll); |
248 | 294 | ||
249 | if (pll->flags & TEGRA_PLLM) { | 295 | if (pll->params->flags & TEGRA_PLLM) { |
250 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 296 | val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
251 | val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; | 297 | val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; |
252 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); | 298 | writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE); |
@@ -326,7 +372,7 @@ static int _get_table_rate(struct clk_hw *hw, | |||
326 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 372 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
327 | struct tegra_clk_pll_freq_table *sel; | 373 | struct tegra_clk_pll_freq_table *sel; |
328 | 374 | ||
329 | for (sel = pll->freq_table; sel->input_rate != 0; sel++) | 375 | for (sel = pll->params->freq_table; sel->input_rate != 0; sel++) |
330 | if (sel->input_rate == parent_rate && | 376 | if (sel->input_rate == parent_rate && |
331 | sel->output_rate == rate) | 377 | sel->output_rate == rate) |
332 | break; | 378 | break; |
@@ -389,12 +435,11 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | |||
389 | if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) || | 435 | if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) || |
390 | (1 << p_div) > divp_max(pll) | 436 | (1 << p_div) > divp_max(pll) |
391 | || cfg->output_rate > pll->params->vco_max) { | 437 | || cfg->output_rate > pll->params->vco_max) { |
392 | pr_err("%s: Failed to set %s rate %lu\n", | ||
393 | __func__, __clk_get_name(hw->clk), rate); | ||
394 | WARN_ON(1); | ||
395 | return -EINVAL; | 438 | return -EINVAL; |
396 | } | 439 | } |
397 | 440 | ||
441 | cfg->output_rate >>= p_div; | ||
442 | |||
398 | if (pll->params->pdiv_tohw) { | 443 | if (pll->params->pdiv_tohw) { |
399 | ret = _p_div_to_hw(hw, 1 << p_div); | 444 | ret = _p_div_to_hw(hw, 1 << p_div); |
400 | if (ret < 0) | 445 | if (ret < 0) |
@@ -414,7 +459,7 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll, | |||
414 | struct tegra_clk_pll_params *params = pll->params; | 459 | struct tegra_clk_pll_params *params = pll->params; |
415 | struct div_nmp *div_nmp = params->div_nmp; | 460 | struct div_nmp *div_nmp = params->div_nmp; |
416 | 461 | ||
417 | if ((pll->flags & TEGRA_PLLM) && | 462 | if ((params->flags & TEGRA_PLLM) && |
418 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & | 463 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & |
419 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { | 464 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { |
420 | val = pll_override_readl(params->pmc_divp_reg, pll); | 465 | val = pll_override_readl(params->pmc_divp_reg, pll); |
@@ -450,7 +495,7 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll, | |||
450 | struct tegra_clk_pll_params *params = pll->params; | 495 | struct tegra_clk_pll_params *params = pll->params; |
451 | struct div_nmp *div_nmp = params->div_nmp; | 496 | struct div_nmp *div_nmp = params->div_nmp; |
452 | 497 | ||
453 | if ((pll->flags & TEGRA_PLLM) && | 498 | if ((params->flags & TEGRA_PLLM) && |
454 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & | 499 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & |
455 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { | 500 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { |
456 | val = pll_override_readl(params->pmc_divp_reg, pll); | 501 | val = pll_override_readl(params->pmc_divp_reg, pll); |
@@ -479,11 +524,11 @@ static void _update_pll_cpcon(struct tegra_clk_pll *pll, | |||
479 | val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); | 524 | val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT); |
480 | val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; | 525 | val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT; |
481 | 526 | ||
482 | if (pll->flags & TEGRA_PLL_SET_LFCON) { | 527 | if (pll->params->flags & TEGRA_PLL_SET_LFCON) { |
483 | val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); | 528 | val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT); |
484 | if (cfg->n >= PLLDU_LFCON_SET_DIVN) | 529 | if (cfg->n >= PLLDU_LFCON_SET_DIVN) |
485 | val |= 1 << PLL_MISC_LFCON_SHIFT; | 530 | val |= 1 << PLL_MISC_LFCON_SHIFT; |
486 | } else if (pll->flags & TEGRA_PLL_SET_DCCON) { | 531 | } else if (pll->params->flags & TEGRA_PLL_SET_DCCON) { |
487 | val &= ~(1 << PLL_MISC_DCCON_SHIFT); | 532 | val &= ~(1 << PLL_MISC_DCCON_SHIFT); |
488 | if (rate >= (pll->params->vco_max >> 1)) | 533 | if (rate >= (pll->params->vco_max >> 1)) |
489 | val |= 1 << PLL_MISC_DCCON_SHIFT; | 534 | val |= 1 << PLL_MISC_DCCON_SHIFT; |
@@ -505,7 +550,7 @@ static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | |||
505 | 550 | ||
506 | _update_pll_mnp(pll, cfg); | 551 | _update_pll_mnp(pll, cfg); |
507 | 552 | ||
508 | if (pll->flags & TEGRA_PLL_HAS_CPCON) | 553 | if (pll->params->flags & TEGRA_PLL_HAS_CPCON) |
509 | _update_pll_cpcon(pll, cfg, rate); | 554 | _update_pll_cpcon(pll, cfg, rate); |
510 | 555 | ||
511 | if (state) { | 556 | if (state) { |
@@ -524,11 +569,11 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
524 | unsigned long flags = 0; | 569 | unsigned long flags = 0; |
525 | int ret = 0; | 570 | int ret = 0; |
526 | 571 | ||
527 | if (pll->flags & TEGRA_PLL_FIXED) { | 572 | if (pll->params->flags & TEGRA_PLL_FIXED) { |
528 | if (rate != pll->fixed_rate) { | 573 | if (rate != pll->params->fixed_rate) { |
529 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", | 574 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", |
530 | __func__, __clk_get_name(hw->clk), | 575 | __func__, __clk_get_name(hw->clk), |
531 | pll->fixed_rate, rate); | 576 | pll->params->fixed_rate, rate); |
532 | return -EINVAL; | 577 | return -EINVAL; |
533 | } | 578 | } |
534 | return 0; | 579 | return 0; |
@@ -536,6 +581,8 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
536 | 581 | ||
537 | if (_get_table_rate(hw, &cfg, rate, parent_rate) && | 582 | if (_get_table_rate(hw, &cfg, rate, parent_rate) && |
538 | _calc_rate(hw, &cfg, rate, parent_rate)) { | 583 | _calc_rate(hw, &cfg, rate, parent_rate)) { |
584 | pr_err("%s: Failed to set %s rate %lu\n", __func__, | ||
585 | __clk_get_name(hw->clk), rate); | ||
539 | WARN_ON(1); | 586 | WARN_ON(1); |
540 | return -EINVAL; | 587 | return -EINVAL; |
541 | } | 588 | } |
@@ -559,18 +606,16 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | |||
559 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 606 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
560 | struct tegra_clk_pll_freq_table cfg; | 607 | struct tegra_clk_pll_freq_table cfg; |
561 | 608 | ||
562 | if (pll->flags & TEGRA_PLL_FIXED) | 609 | if (pll->params->flags & TEGRA_PLL_FIXED) |
563 | return pll->fixed_rate; | 610 | return pll->params->fixed_rate; |
564 | 611 | ||
565 | /* PLLM is used for memory; we do not change rate */ | 612 | /* PLLM is used for memory; we do not change rate */ |
566 | if (pll->flags & TEGRA_PLLM) | 613 | if (pll->params->flags & TEGRA_PLLM) |
567 | return __clk_get_rate(hw->clk); | 614 | return __clk_get_rate(hw->clk); |
568 | 615 | ||
569 | if (_get_table_rate(hw, &cfg, rate, *prate) && | 616 | if (_get_table_rate(hw, &cfg, rate, *prate) && |
570 | _calc_rate(hw, &cfg, rate, *prate)) { | 617 | _calc_rate(hw, &cfg, rate, *prate)) |
571 | WARN_ON(1); | ||
572 | return -EINVAL; | 618 | return -EINVAL; |
573 | } | ||
574 | 619 | ||
575 | return cfg.output_rate; | 620 | return cfg.output_rate; |
576 | } | 621 | } |
@@ -586,17 +631,19 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, | |||
586 | 631 | ||
587 | val = pll_readl_base(pll); | 632 | val = pll_readl_base(pll); |
588 | 633 | ||
589 | if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) | 634 | if ((pll->params->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS)) |
590 | return parent_rate; | 635 | return parent_rate; |
591 | 636 | ||
592 | if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) { | 637 | if ((pll->params->flags & TEGRA_PLL_FIXED) && |
638 | !(val & PLL_BASE_OVERRIDE)) { | ||
593 | struct tegra_clk_pll_freq_table sel; | 639 | struct tegra_clk_pll_freq_table sel; |
594 | if (_get_table_rate(hw, &sel, pll->fixed_rate, parent_rate)) { | 640 | if (_get_table_rate(hw, &sel, pll->params->fixed_rate, |
641 | parent_rate)) { | ||
595 | pr_err("Clock %s has unknown fixed frequency\n", | 642 | pr_err("Clock %s has unknown fixed frequency\n", |
596 | __clk_get_name(hw->clk)); | 643 | __clk_get_name(hw->clk)); |
597 | BUG(); | 644 | BUG(); |
598 | } | 645 | } |
599 | return pll->fixed_rate; | 646 | return pll->params->fixed_rate; |
600 | } | 647 | } |
601 | 648 | ||
602 | _get_pll_mnp(pll, &cfg); | 649 | _get_pll_mnp(pll, &cfg); |
@@ -664,7 +711,7 @@ static int clk_plle_enable(struct clk_hw *hw) | |||
664 | u32 val; | 711 | u32 val; |
665 | int err; | 712 | int err; |
666 | 713 | ||
667 | if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) | 714 | if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) |
668 | return -EINVAL; | 715 | return -EINVAL; |
669 | 716 | ||
670 | clk_pll_disable(hw); | 717 | clk_pll_disable(hw); |
@@ -680,7 +727,7 @@ static int clk_plle_enable(struct clk_hw *hw) | |||
680 | return err; | 727 | return err; |
681 | } | 728 | } |
682 | 729 | ||
683 | if (pll->flags & TEGRA_PLLE_CONFIGURE) { | 730 | if (pll->params->flags & TEGRA_PLLE_CONFIGURE) { |
684 | /* configure dividers */ | 731 | /* configure dividers */ |
685 | val = pll_readl_base(pll); | 732 | val = pll_readl_base(pll); |
686 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); | 733 | val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); |
@@ -744,7 +791,7 @@ const struct clk_ops tegra_clk_plle_ops = { | |||
744 | .enable = clk_plle_enable, | 791 | .enable = clk_plle_enable, |
745 | }; | 792 | }; |
746 | 793 | ||
747 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | 794 | #if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) |
748 | 795 | ||
749 | static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, | 796 | static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, |
750 | unsigned long parent_rate) | 797 | unsigned long parent_rate) |
@@ -755,6 +802,48 @@ static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params, | |||
755 | return 1; | 802 | return 1; |
756 | } | 803 | } |
757 | 804 | ||
805 | static unsigned long _clip_vco_min(unsigned long vco_min, | ||
806 | unsigned long parent_rate) | ||
807 | { | ||
808 | return DIV_ROUND_UP(vco_min, parent_rate) * parent_rate; | ||
809 | } | ||
810 | |||
811 | static int _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, | ||
812 | void __iomem *clk_base, | ||
813 | unsigned long parent_rate) | ||
814 | { | ||
815 | u32 val; | ||
816 | u32 step_a, step_b; | ||
817 | |||
818 | switch (parent_rate) { | ||
819 | case 12000000: | ||
820 | case 13000000: | ||
821 | case 26000000: | ||
822 | step_a = 0x2B; | ||
823 | step_b = 0x0B; | ||
824 | break; | ||
825 | case 16800000: | ||
826 | step_a = 0x1A; | ||
827 | step_b = 0x09; | ||
828 | break; | ||
829 | case 19200000: | ||
830 | step_a = 0x12; | ||
831 | step_b = 0x08; | ||
832 | break; | ||
833 | default: | ||
834 | pr_err("%s: Unexpected reference rate %lu\n", | ||
835 | __func__, parent_rate); | ||
836 | WARN_ON(1); | ||
837 | return -EINVAL; | ||
838 | } | ||
839 | |||
840 | val = step_a << pll_params->stepa_shift; | ||
841 | val |= step_b << pll_params->stepb_shift; | ||
842 | writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg); | ||
843 | |||
844 | return 0; | ||
845 | } | ||
846 | |||
758 | static int clk_pll_iddq_enable(struct clk_hw *hw) | 847 | static int clk_pll_iddq_enable(struct clk_hw *hw) |
759 | { | 848 | { |
760 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 849 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
@@ -1173,7 +1262,7 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) | |||
1173 | unsigned long flags = 0; | 1262 | unsigned long flags = 0; |
1174 | unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); | 1263 | unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk)); |
1175 | 1264 | ||
1176 | if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate)) | 1265 | if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) |
1177 | return -EINVAL; | 1266 | return -EINVAL; |
1178 | 1267 | ||
1179 | if (pll->lock) | 1268 | if (pll->lock) |
@@ -1217,6 +1306,18 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) | |||
1217 | if (ret < 0) | 1306 | if (ret < 0) |
1218 | goto out; | 1307 | goto out; |
1219 | 1308 | ||
1309 | val = pll_readl(PLLE_SS_CTRL, pll); | ||
1310 | val &= ~(PLLE_SS_CNTL_CENTER | PLLE_SS_CNTL_INVERT); | ||
1311 | val &= ~PLLE_SS_COEFFICIENTS_MASK; | ||
1312 | val |= PLLE_SS_COEFFICIENTS_VAL; | ||
1313 | pll_writel(val, PLLE_SS_CTRL, pll); | ||
1314 | val &= ~(PLLE_SS_CNTL_SSC_BYP | PLLE_SS_CNTL_BYPASS_SS); | ||
1315 | pll_writel(val, PLLE_SS_CTRL, pll); | ||
1316 | udelay(1); | ||
1317 | val &= ~PLLE_SS_CNTL_INTERP_RESET; | ||
1318 | pll_writel(val, PLLE_SS_CTRL, pll); | ||
1319 | udelay(1); | ||
1320 | |||
1220 | /* TODO: enable hw control of xusb brick pll */ | 1321 | /* TODO: enable hw control of xusb brick pll */ |
1221 | 1322 | ||
1222 | out: | 1323 | out: |
@@ -1248,9 +1349,8 @@ static void clk_plle_tegra114_disable(struct clk_hw *hw) | |||
1248 | #endif | 1349 | #endif |
1249 | 1350 | ||
1250 | static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, | 1351 | static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, |
1251 | void __iomem *pmc, unsigned long fixed_rate, | 1352 | void __iomem *pmc, struct tegra_clk_pll_params *pll_params, |
1252 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, | 1353 | spinlock_t *lock) |
1253 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) | ||
1254 | { | 1354 | { |
1255 | struct tegra_clk_pll *pll; | 1355 | struct tegra_clk_pll *pll; |
1256 | 1356 | ||
@@ -1261,10 +1361,7 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, | |||
1261 | pll->clk_base = clk_base; | 1361 | pll->clk_base = clk_base; |
1262 | pll->pmc = pmc; | 1362 | pll->pmc = pmc; |
1263 | 1363 | ||
1264 | pll->freq_table = freq_table; | ||
1265 | pll->params = pll_params; | 1364 | pll->params = pll_params; |
1266 | pll->fixed_rate = fixed_rate; | ||
1267 | pll->flags = pll_flags; | ||
1268 | pll->lock = lock; | 1365 | pll->lock = lock; |
1269 | 1366 | ||
1270 | if (!pll_params->div_nmp) | 1367 | if (!pll_params->div_nmp) |
@@ -1293,17 +1390,15 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, | |||
1293 | 1390 | ||
1294 | struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, | 1391 | struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, |
1295 | void __iomem *clk_base, void __iomem *pmc, | 1392 | void __iomem *clk_base, void __iomem *pmc, |
1296 | unsigned long flags, unsigned long fixed_rate, | 1393 | unsigned long flags, struct tegra_clk_pll_params *pll_params, |
1297 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, | 1394 | spinlock_t *lock) |
1298 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) | ||
1299 | { | 1395 | { |
1300 | struct tegra_clk_pll *pll; | 1396 | struct tegra_clk_pll *pll; |
1301 | struct clk *clk; | 1397 | struct clk *clk; |
1302 | 1398 | ||
1303 | pll_flags |= TEGRA_PLL_BYPASS; | 1399 | pll_params->flags |= TEGRA_PLL_BYPASS; |
1304 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1400 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; |
1305 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1401 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); |
1306 | freq_table, lock); | ||
1307 | if (IS_ERR(pll)) | 1402 | if (IS_ERR(pll)) |
1308 | return ERR_CAST(pll); | 1403 | return ERR_CAST(pll); |
1309 | 1404 | ||
@@ -1317,17 +1412,15 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, | |||
1317 | 1412 | ||
1318 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | 1413 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, |
1319 | void __iomem *clk_base, void __iomem *pmc, | 1414 | void __iomem *clk_base, void __iomem *pmc, |
1320 | unsigned long flags, unsigned long fixed_rate, | 1415 | unsigned long flags, struct tegra_clk_pll_params *pll_params, |
1321 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, | 1416 | spinlock_t *lock) |
1322 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock) | ||
1323 | { | 1417 | { |
1324 | struct tegra_clk_pll *pll; | 1418 | struct tegra_clk_pll *pll; |
1325 | struct clk *clk; | 1419 | struct clk *clk; |
1326 | 1420 | ||
1327 | pll_flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; | 1421 | pll_params->flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS; |
1328 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1422 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; |
1329 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1423 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); |
1330 | freq_table, lock); | ||
1331 | if (IS_ERR(pll)) | 1424 | if (IS_ERR(pll)) |
1332 | return ERR_CAST(pll); | 1425 | return ERR_CAST(pll); |
1333 | 1426 | ||
@@ -1339,7 +1432,7 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | |||
1339 | return clk; | 1432 | return clk; |
1340 | } | 1433 | } |
1341 | 1434 | ||
1342 | #ifdef CONFIG_ARCH_TEGRA_114_SOC | 1435 | #if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) |
1343 | const struct clk_ops tegra_clk_pllxc_ops = { | 1436 | const struct clk_ops tegra_clk_pllxc_ops = { |
1344 | .is_enabled = clk_pll_is_enabled, | 1437 | .is_enabled = clk_pll_is_enabled, |
1345 | .enable = clk_pll_iddq_enable, | 1438 | .enable = clk_pll_iddq_enable, |
@@ -1386,21 +1479,46 @@ const struct clk_ops tegra_clk_plle_tegra114_ops = { | |||
1386 | 1479 | ||
1387 | struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, | 1480 | struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, |
1388 | void __iomem *clk_base, void __iomem *pmc, | 1481 | void __iomem *clk_base, void __iomem *pmc, |
1389 | unsigned long flags, unsigned long fixed_rate, | 1482 | unsigned long flags, |
1390 | struct tegra_clk_pll_params *pll_params, | 1483 | struct tegra_clk_pll_params *pll_params, |
1391 | u32 pll_flags, | ||
1392 | struct tegra_clk_pll_freq_table *freq_table, | ||
1393 | spinlock_t *lock) | 1484 | spinlock_t *lock) |
1394 | { | 1485 | { |
1395 | struct tegra_clk_pll *pll; | 1486 | struct tegra_clk_pll *pll; |
1396 | struct clk *clk; | 1487 | struct clk *clk, *parent; |
1488 | unsigned long parent_rate; | ||
1489 | int err; | ||
1490 | u32 val, val_iddq; | ||
1491 | |||
1492 | parent = __clk_lookup(parent_name); | ||
1493 | if (!parent) { | ||
1494 | WARN(1, "parent clk %s of %s must be registered first\n", | ||
1495 | name, parent_name); | ||
1496 | return ERR_PTR(-EINVAL); | ||
1497 | } | ||
1397 | 1498 | ||
1398 | if (!pll_params->pdiv_tohw) | 1499 | if (!pll_params->pdiv_tohw) |
1399 | return ERR_PTR(-EINVAL); | 1500 | return ERR_PTR(-EINVAL); |
1400 | 1501 | ||
1401 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1502 | parent_rate = __clk_get_rate(parent); |
1402 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1503 | |
1403 | freq_table, lock); | 1504 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); |
1505 | |||
1506 | err = _setup_dynamic_ramp(pll_params, clk_base, parent_rate); | ||
1507 | if (err) | ||
1508 | return ERR_PTR(err); | ||
1509 | |||
1510 | val = readl_relaxed(clk_base + pll_params->base_reg); | ||
1511 | val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); | ||
1512 | |||
1513 | if (val & PLL_BASE_ENABLE) | ||
1514 | WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); | ||
1515 | else { | ||
1516 | val_iddq |= BIT(pll_params->iddq_bit_idx); | ||
1517 | writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); | ||
1518 | } | ||
1519 | |||
1520 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | ||
1521 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
1404 | if (IS_ERR(pll)) | 1522 | if (IS_ERR(pll)) |
1405 | return ERR_CAST(pll); | 1523 | return ERR_CAST(pll); |
1406 | 1524 | ||
@@ -1414,19 +1532,19 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, | |||
1414 | 1532 | ||
1415 | struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, | 1533 | struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, |
1416 | void __iomem *clk_base, void __iomem *pmc, | 1534 | void __iomem *clk_base, void __iomem *pmc, |
1417 | unsigned long flags, unsigned long fixed_rate, | 1535 | unsigned long flags, |
1418 | struct tegra_clk_pll_params *pll_params, | 1536 | struct tegra_clk_pll_params *pll_params, |
1419 | u32 pll_flags, | ||
1420 | struct tegra_clk_pll_freq_table *freq_table, | ||
1421 | spinlock_t *lock, unsigned long parent_rate) | 1537 | spinlock_t *lock, unsigned long parent_rate) |
1422 | { | 1538 | { |
1423 | u32 val; | 1539 | u32 val; |
1424 | struct tegra_clk_pll *pll; | 1540 | struct tegra_clk_pll *pll; |
1425 | struct clk *clk; | 1541 | struct clk *clk; |
1426 | 1542 | ||
1427 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; | 1543 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC; |
1428 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1544 | |
1429 | freq_table, lock); | 1545 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); |
1546 | |||
1547 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
1430 | if (IS_ERR(pll)) | 1548 | if (IS_ERR(pll)) |
1431 | return ERR_CAST(pll); | 1549 | return ERR_CAST(pll); |
1432 | 1550 | ||
@@ -1461,23 +1579,32 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, | |||
1461 | 1579 | ||
1462 | struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, | 1580 | struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, |
1463 | void __iomem *clk_base, void __iomem *pmc, | 1581 | void __iomem *clk_base, void __iomem *pmc, |
1464 | unsigned long flags, unsigned long fixed_rate, | 1582 | unsigned long flags, |
1465 | struct tegra_clk_pll_params *pll_params, | 1583 | struct tegra_clk_pll_params *pll_params, |
1466 | u32 pll_flags, | ||
1467 | struct tegra_clk_pll_freq_table *freq_table, | ||
1468 | spinlock_t *lock) | 1584 | spinlock_t *lock) |
1469 | { | 1585 | { |
1470 | struct tegra_clk_pll *pll; | 1586 | struct tegra_clk_pll *pll; |
1471 | struct clk *clk; | 1587 | struct clk *clk, *parent; |
1588 | unsigned long parent_rate; | ||
1472 | 1589 | ||
1473 | if (!pll_params->pdiv_tohw) | 1590 | if (!pll_params->pdiv_tohw) |
1474 | return ERR_PTR(-EINVAL); | 1591 | return ERR_PTR(-EINVAL); |
1475 | 1592 | ||
1476 | pll_flags |= TEGRA_PLL_BYPASS; | 1593 | parent = __clk_lookup(parent_name); |
1477 | pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | 1594 | if (!parent) { |
1478 | pll_flags |= TEGRA_PLLM; | 1595 | WARN(1, "parent clk %s of %s must be registered first\n", |
1479 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1596 | name, parent_name); |
1480 | freq_table, lock); | 1597 | return ERR_PTR(-EINVAL); |
1598 | } | ||
1599 | |||
1600 | parent_rate = __clk_get_rate(parent); | ||
1601 | |||
1602 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); | ||
1603 | |||
1604 | pll_params->flags |= TEGRA_PLL_BYPASS; | ||
1605 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; | ||
1606 | pll_params->flags |= TEGRA_PLLM; | ||
1607 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
1481 | if (IS_ERR(pll)) | 1608 | if (IS_ERR(pll)) |
1482 | return ERR_CAST(pll); | 1609 | return ERR_CAST(pll); |
1483 | 1610 | ||
@@ -1491,10 +1618,8 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, | |||
1491 | 1618 | ||
1492 | struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, | 1619 | struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, |
1493 | void __iomem *clk_base, void __iomem *pmc, | 1620 | void __iomem *clk_base, void __iomem *pmc, |
1494 | unsigned long flags, unsigned long fixed_rate, | 1621 | unsigned long flags, |
1495 | struct tegra_clk_pll_params *pll_params, | 1622 | struct tegra_clk_pll_params *pll_params, |
1496 | u32 pll_flags, | ||
1497 | struct tegra_clk_pll_freq_table *freq_table, | ||
1498 | spinlock_t *lock) | 1623 | spinlock_t *lock) |
1499 | { | 1624 | { |
1500 | struct clk *parent, *clk; | 1625 | struct clk *parent, *clk; |
@@ -1507,20 +1632,21 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, | |||
1507 | return ERR_PTR(-EINVAL); | 1632 | return ERR_PTR(-EINVAL); |
1508 | 1633 | ||
1509 | parent = __clk_lookup(parent_name); | 1634 | parent = __clk_lookup(parent_name); |
1510 | if (IS_ERR(parent)) { | 1635 | if (!parent) { |
1511 | WARN(1, "parent clk %s of %s must be registered first\n", | 1636 | WARN(1, "parent clk %s of %s must be registered first\n", |
1512 | name, parent_name); | 1637 | name, parent_name); |
1513 | return ERR_PTR(-EINVAL); | 1638 | return ERR_PTR(-EINVAL); |
1514 | } | 1639 | } |
1515 | 1640 | ||
1516 | pll_flags |= TEGRA_PLL_BYPASS; | 1641 | parent_rate = __clk_get_rate(parent); |
1517 | pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags, | 1642 | |
1518 | freq_table, lock); | 1643 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); |
1644 | |||
1645 | pll_params->flags |= TEGRA_PLL_BYPASS; | ||
1646 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
1519 | if (IS_ERR(pll)) | 1647 | if (IS_ERR(pll)) |
1520 | return ERR_CAST(pll); | 1648 | return ERR_CAST(pll); |
1521 | 1649 | ||
1522 | parent_rate = __clk_get_rate(parent); | ||
1523 | |||
1524 | /* | 1650 | /* |
1525 | * Most of PLLC register fields are shadowed, and can not be read | 1651 | * Most of PLLC register fields are shadowed, and can not be read |
1526 | * directly from PLL h/w. Hence, actual PLLC boot state is unknown. | 1652 | * directly from PLL h/w. Hence, actual PLLC boot state is unknown. |
@@ -1567,17 +1693,15 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, | |||
1567 | struct clk *tegra_clk_register_plle_tegra114(const char *name, | 1693 | struct clk *tegra_clk_register_plle_tegra114(const char *name, |
1568 | const char *parent_name, | 1694 | const char *parent_name, |
1569 | void __iomem *clk_base, unsigned long flags, | 1695 | void __iomem *clk_base, unsigned long flags, |
1570 | unsigned long fixed_rate, | ||
1571 | struct tegra_clk_pll_params *pll_params, | 1696 | struct tegra_clk_pll_params *pll_params, |
1572 | struct tegra_clk_pll_freq_table *freq_table, | ||
1573 | spinlock_t *lock) | 1697 | spinlock_t *lock) |
1574 | { | 1698 | { |
1575 | struct tegra_clk_pll *pll; | 1699 | struct tegra_clk_pll *pll; |
1576 | struct clk *clk; | 1700 | struct clk *clk; |
1577 | u32 val, val_aux; | 1701 | u32 val, val_aux; |
1578 | 1702 | ||
1579 | pll = _tegra_init_pll(clk_base, NULL, fixed_rate, pll_params, | 1703 | pll_params->flags |= TEGRA_PLL_HAS_LOCK_ENABLE; |
1580 | TEGRA_PLL_HAS_LOCK_ENABLE, freq_table, lock); | 1704 | pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); |
1581 | if (IS_ERR(pll)) | 1705 | if (IS_ERR(pll)) |
1582 | return ERR_CAST(pll); | 1706 | return ERR_CAST(pll); |
1583 | 1707 | ||
@@ -1587,11 +1711,13 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, | |||
1587 | val_aux = pll_readl(pll_params->aux_reg, pll); | 1711 | val_aux = pll_readl(pll_params->aux_reg, pll); |
1588 | 1712 | ||
1589 | if (val & PLL_BASE_ENABLE) { | 1713 | if (val & PLL_BASE_ENABLE) { |
1590 | if (!(val_aux & PLLE_AUX_PLLRE_SEL)) | 1714 | if ((val_aux & PLLE_AUX_PLLRE_SEL) || |
1715 | (val_aux & PLLE_AUX_PLLP_SEL)) | ||
1591 | WARN(1, "pll_e enabled with unsupported parent %s\n", | 1716 | WARN(1, "pll_e enabled with unsupported parent %s\n", |
1592 | (val & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : "pll_ref"); | 1717 | (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : |
1718 | "pll_re_vco"); | ||
1593 | } else { | 1719 | } else { |
1594 | val_aux |= PLLE_AUX_PLLRE_SEL; | 1720 | val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); |
1595 | pll_writel(val, pll_params->aux_reg, pll); | 1721 | pll_writel(val, pll_params->aux_reg, pll); |
1596 | } | 1722 | } |
1597 | 1723 | ||
@@ -1603,3 +1729,92 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, | |||
1603 | return clk; | 1729 | return clk; |
1604 | } | 1730 | } |
1605 | #endif | 1731 | #endif |
1732 | |||
1733 | #ifdef CONFIG_ARCH_TEGRA_124_SOC | ||
1734 | const struct clk_ops tegra_clk_pllss_ops = { | ||
1735 | .is_enabled = clk_pll_is_enabled, | ||
1736 | .enable = clk_pll_iddq_enable, | ||
1737 | .disable = clk_pll_iddq_disable, | ||
1738 | .recalc_rate = clk_pll_recalc_rate, | ||
1739 | .round_rate = clk_pll_ramp_round_rate, | ||
1740 | .set_rate = clk_pllxc_set_rate, | ||
1741 | }; | ||
1742 | |||
1743 | struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, | ||
1744 | void __iomem *clk_base, unsigned long flags, | ||
1745 | struct tegra_clk_pll_params *pll_params, | ||
1746 | spinlock_t *lock) | ||
1747 | { | ||
1748 | struct tegra_clk_pll *pll; | ||
1749 | struct clk *clk, *parent; | ||
1750 | struct tegra_clk_pll_freq_table cfg; | ||
1751 | unsigned long parent_rate; | ||
1752 | u32 val; | ||
1753 | int i; | ||
1754 | |||
1755 | if (!pll_params->div_nmp) | ||
1756 | return ERR_PTR(-EINVAL); | ||
1757 | |||
1758 | parent = __clk_lookup(parent_name); | ||
1759 | if (!parent) { | ||
1760 | WARN(1, "parent clk %s of %s must be registered first\n", | ||
1761 | name, parent_name); | ||
1762 | return ERR_PTR(-EINVAL); | ||
1763 | } | ||
1764 | |||
1765 | pll_params->flags = TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_USE_LOCK; | ||
1766 | pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); | ||
1767 | if (IS_ERR(pll)) | ||
1768 | return ERR_CAST(pll); | ||
1769 | |||
1770 | val = pll_readl_base(pll); | ||
1771 | val &= ~PLLSS_REF_SRC_SEL_MASK; | ||
1772 | pll_writel_base(val, pll); | ||
1773 | |||
1774 | parent_rate = __clk_get_rate(parent); | ||
1775 | |||
1776 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); | ||
1777 | |||
1778 | /* initialize PLL to minimum rate */ | ||
1779 | |||
1780 | cfg.m = _pll_fixed_mdiv(pll_params, parent_rate); | ||
1781 | cfg.n = cfg.m * pll_params->vco_min / parent_rate; | ||
1782 | |||
1783 | for (i = 0; pll_params->pdiv_tohw[i].pdiv; i++) | ||
1784 | ; | ||
1785 | if (!i) { | ||
1786 | kfree(pll); | ||
1787 | return ERR_PTR(-EINVAL); | ||
1788 | } | ||
1789 | |||
1790 | cfg.p = pll_params->pdiv_tohw[i-1].hw_val; | ||
1791 | |||
1792 | _update_pll_mnp(pll, &cfg); | ||
1793 | |||
1794 | pll_writel_misc(PLLSS_MISC_DEFAULT, pll); | ||
1795 | pll_writel(PLLSS_CFG_DEFAULT, pll_params->ext_misc_reg[0], pll); | ||
1796 | pll_writel(PLLSS_CTRL1_DEFAULT, pll_params->ext_misc_reg[1], pll); | ||
1797 | pll_writel(PLLSS_CTRL1_DEFAULT, pll_params->ext_misc_reg[2], pll); | ||
1798 | |||
1799 | val = pll_readl_base(pll); | ||
1800 | if (val & PLL_BASE_ENABLE) { | ||
1801 | if (val & BIT(pll_params->iddq_bit_idx)) { | ||
1802 | WARN(1, "%s is on but IDDQ set\n", name); | ||
1803 | kfree(pll); | ||
1804 | return ERR_PTR(-EINVAL); | ||
1805 | } | ||
1806 | } else | ||
1807 | val |= BIT(pll_params->iddq_bit_idx); | ||
1808 | |||
1809 | val &= ~PLLSS_LOCK_OVERRIDE; | ||
1810 | pll_writel_base(val, pll); | ||
1811 | |||
1812 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | ||
1813 | &tegra_clk_pllss_ops); | ||
1814 | |||
1815 | if (IS_ERR(clk)) | ||
1816 | kfree(pll); | ||
1817 | |||
1818 | return clk; | ||
1819 | } | ||
1820 | #endif | ||
diff --git a/drivers/clk/tegra/clk-tegra-audio.c b/drivers/clk/tegra/clk-tegra-audio.c new file mode 100644 index 000000000000..5c38aab2c5b8 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-audio.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_address.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/export.h> | ||
24 | #include <linux/clk/tegra.h> | ||
25 | |||
26 | #include "clk.h" | ||
27 | #include "clk-id.h" | ||
28 | |||
29 | #define AUDIO_SYNC_CLK_I2S0 0x4a0 | ||
30 | #define AUDIO_SYNC_CLK_I2S1 0x4a4 | ||
31 | #define AUDIO_SYNC_CLK_I2S2 0x4a8 | ||
32 | #define AUDIO_SYNC_CLK_I2S3 0x4ac | ||
33 | #define AUDIO_SYNC_CLK_I2S4 0x4b0 | ||
34 | #define AUDIO_SYNC_CLK_SPDIF 0x4b4 | ||
35 | |||
36 | #define AUDIO_SYNC_DOUBLER 0x49c | ||
37 | |||
38 | #define PLLA_OUT 0xb4 | ||
39 | |||
40 | struct tegra_sync_source_initdata { | ||
41 | char *name; | ||
42 | unsigned long rate; | ||
43 | unsigned long max_rate; | ||
44 | int clk_id; | ||
45 | }; | ||
46 | |||
47 | #define SYNC(_name) \ | ||
48 | {\ | ||
49 | .name = #_name,\ | ||
50 | .rate = 24000000,\ | ||
51 | .max_rate = 24000000,\ | ||
52 | .clk_id = tegra_clk_ ## _name,\ | ||
53 | } | ||
54 | |||
55 | struct tegra_audio_clk_initdata { | ||
56 | char *gate_name; | ||
57 | char *mux_name; | ||
58 | u32 offset; | ||
59 | int gate_clk_id; | ||
60 | int mux_clk_id; | ||
61 | }; | ||
62 | |||
63 | #define AUDIO(_name, _offset) \ | ||
64 | {\ | ||
65 | .gate_name = #_name,\ | ||
66 | .mux_name = #_name"_mux",\ | ||
67 | .offset = _offset,\ | ||
68 | .gate_clk_id = tegra_clk_ ## _name,\ | ||
69 | .mux_clk_id = tegra_clk_ ## _name ## _mux,\ | ||
70 | } | ||
71 | |||
72 | struct tegra_audio2x_clk_initdata { | ||
73 | char *parent; | ||
74 | char *gate_name; | ||
75 | char *name_2x; | ||
76 | char *div_name; | ||
77 | int clk_id; | ||
78 | int clk_num; | ||
79 | u8 div_offset; | ||
80 | }; | ||
81 | |||
82 | #define AUDIO2X(_name, _num, _offset) \ | ||
83 | {\ | ||
84 | .parent = #_name,\ | ||
85 | .gate_name = #_name"_2x",\ | ||
86 | .name_2x = #_name"_doubler",\ | ||
87 | .div_name = #_name"_div",\ | ||
88 | .clk_id = tegra_clk_ ## _name ## _2x,\ | ||
89 | .clk_num = _num,\ | ||
90 | .div_offset = _offset,\ | ||
91 | } | ||
92 | |||
93 | static DEFINE_SPINLOCK(clk_doubler_lock); | ||
94 | |||
95 | static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", | ||
96 | "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", | ||
97 | }; | ||
98 | |||
99 | static struct tegra_sync_source_initdata sync_source_clks[] __initdata = { | ||
100 | SYNC(spdif_in_sync), | ||
101 | SYNC(i2s0_sync), | ||
102 | SYNC(i2s1_sync), | ||
103 | SYNC(i2s2_sync), | ||
104 | SYNC(i2s3_sync), | ||
105 | SYNC(i2s4_sync), | ||
106 | SYNC(vimclk_sync), | ||
107 | }; | ||
108 | |||
109 | static struct tegra_audio_clk_initdata audio_clks[] = { | ||
110 | AUDIO(audio0, AUDIO_SYNC_CLK_I2S0), | ||
111 | AUDIO(audio1, AUDIO_SYNC_CLK_I2S1), | ||
112 | AUDIO(audio2, AUDIO_SYNC_CLK_I2S2), | ||
113 | AUDIO(audio3, AUDIO_SYNC_CLK_I2S3), | ||
114 | AUDIO(audio4, AUDIO_SYNC_CLK_I2S4), | ||
115 | AUDIO(spdif, AUDIO_SYNC_CLK_SPDIF), | ||
116 | }; | ||
117 | |||
118 | static struct tegra_audio2x_clk_initdata audio2x_clks[] = { | ||
119 | AUDIO2X(audio0, 113, 24), | ||
120 | AUDIO2X(audio1, 114, 25), | ||
121 | AUDIO2X(audio2, 115, 26), | ||
122 | AUDIO2X(audio3, 116, 27), | ||
123 | AUDIO2X(audio4, 117, 28), | ||
124 | AUDIO2X(spdif, 118, 29), | ||
125 | }; | ||
126 | |||
127 | void __init tegra_audio_clk_init(void __iomem *clk_base, | ||
128 | void __iomem *pmc_base, struct tegra_clk *tegra_clks, | ||
129 | struct tegra_clk_pll_params *pll_a_params) | ||
130 | { | ||
131 | struct clk *clk; | ||
132 | struct clk **dt_clk; | ||
133 | int i; | ||
134 | |||
135 | /* PLLA */ | ||
136 | dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a, tegra_clks); | ||
137 | if (dt_clk) { | ||
138 | clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, | ||
139 | pmc_base, 0, pll_a_params, NULL); | ||
140 | *dt_clk = clk; | ||
141 | } | ||
142 | |||
143 | /* PLLA_OUT0 */ | ||
144 | dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a_out0, tegra_clks); | ||
145 | if (dt_clk) { | ||
146 | clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", | ||
147 | clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
148 | 8, 8, 1, NULL); | ||
149 | clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", | ||
150 | clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | | ||
151 | CLK_SET_RATE_PARENT, 0, NULL); | ||
152 | *dt_clk = clk; | ||
153 | } | ||
154 | |||
155 | for (i = 0; i < ARRAY_SIZE(sync_source_clks); i++) { | ||
156 | struct tegra_sync_source_initdata *data; | ||
157 | |||
158 | data = &sync_source_clks[i]; | ||
159 | |||
160 | dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); | ||
161 | if (!dt_clk) | ||
162 | continue; | ||
163 | |||
164 | clk = tegra_clk_register_sync_source(data->name, | ||
165 | data->rate, data->max_rate); | ||
166 | *dt_clk = clk; | ||
167 | } | ||
168 | |||
169 | for (i = 0; i < ARRAY_SIZE(audio_clks); i++) { | ||
170 | struct tegra_audio_clk_initdata *data; | ||
171 | |||
172 | data = &audio_clks[i]; | ||
173 | dt_clk = tegra_lookup_dt_id(data->mux_clk_id, tegra_clks); | ||
174 | |||
175 | if (!dt_clk) | ||
176 | continue; | ||
177 | clk = clk_register_mux(NULL, data->mux_name, mux_audio_sync_clk, | ||
178 | ARRAY_SIZE(mux_audio_sync_clk), | ||
179 | CLK_SET_RATE_NO_REPARENT, | ||
180 | clk_base + data->offset, 0, 3, 0, | ||
181 | NULL); | ||
182 | *dt_clk = clk; | ||
183 | |||
184 | dt_clk = tegra_lookup_dt_id(data->gate_clk_id, tegra_clks); | ||
185 | if (!dt_clk) | ||
186 | continue; | ||
187 | |||
188 | clk = clk_register_gate(NULL, data->gate_name, data->mux_name, | ||
189 | 0, clk_base + data->offset, 4, | ||
190 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
191 | *dt_clk = clk; | ||
192 | } | ||
193 | |||
194 | for (i = 0; i < ARRAY_SIZE(audio2x_clks); i++) { | ||
195 | struct tegra_audio2x_clk_initdata *data; | ||
196 | |||
197 | data = &audio2x_clks[i]; | ||
198 | dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); | ||
199 | if (!dt_clk) | ||
200 | continue; | ||
201 | |||
202 | clk = clk_register_fixed_factor(NULL, data->name_2x, | ||
203 | data->parent, CLK_SET_RATE_PARENT, 2, 1); | ||
204 | clk = tegra_clk_register_divider(data->div_name, | ||
205 | data->name_2x, clk_base + AUDIO_SYNC_DOUBLER, | ||
206 | 0, 0, data->div_offset, 1, 0, | ||
207 | &clk_doubler_lock); | ||
208 | clk = tegra_clk_register_periph_gate(data->gate_name, | ||
209 | data->div_name, TEGRA_PERIPH_NO_RESET, | ||
210 | clk_base, CLK_SET_RATE_PARENT, data->clk_num, | ||
211 | periph_clk_enb_refcnt); | ||
212 | *dt_clk = clk; | ||
213 | } | ||
214 | } | ||
215 | |||
diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c new file mode 100644 index 000000000000..f3b773833429 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-fixed.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_address.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/export.h> | ||
24 | #include <linux/clk/tegra.h> | ||
25 | |||
26 | #include "clk.h" | ||
27 | #include "clk-id.h" | ||
28 | |||
29 | #define OSC_CTRL 0x50 | ||
30 | #define OSC_CTRL_OSC_FREQ_SHIFT 28 | ||
31 | #define OSC_CTRL_PLL_REF_DIV_SHIFT 26 | ||
32 | |||
33 | int __init tegra_osc_clk_init(void __iomem *clk_base, | ||
34 | struct tegra_clk *tegra_clks, | ||
35 | unsigned long *input_freqs, int num, | ||
36 | unsigned long *osc_freq, | ||
37 | unsigned long *pll_ref_freq) | ||
38 | { | ||
39 | struct clk *clk; | ||
40 | struct clk **dt_clk; | ||
41 | u32 val, pll_ref_div; | ||
42 | unsigned osc_idx; | ||
43 | |||
44 | val = readl_relaxed(clk_base + OSC_CTRL); | ||
45 | osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT; | ||
46 | |||
47 | if (osc_idx < num) | ||
48 | *osc_freq = input_freqs[osc_idx]; | ||
49 | else | ||
50 | *osc_freq = 0; | ||
51 | |||
52 | if (!*osc_freq) { | ||
53 | WARN_ON(1); | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | |||
57 | dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, tegra_clks); | ||
58 | if (!dt_clk) | ||
59 | return 0; | ||
60 | |||
61 | clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, | ||
62 | *osc_freq); | ||
63 | *dt_clk = clk; | ||
64 | |||
65 | /* pll_ref */ | ||
66 | val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; | ||
67 | pll_ref_div = 1 << val; | ||
68 | dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, tegra_clks); | ||
69 | if (!dt_clk) | ||
70 | return 0; | ||
71 | |||
72 | clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", | ||
73 | 0, 1, pll_ref_div); | ||
74 | *dt_clk = clk; | ||
75 | |||
76 | if (pll_ref_freq) | ||
77 | *pll_ref_freq = *osc_freq / pll_ref_div; | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks) | ||
83 | { | ||
84 | struct clk *clk; | ||
85 | struct clk **dt_clk; | ||
86 | |||
87 | /* clk_32k */ | ||
88 | dt_clk = tegra_lookup_dt_id(tegra_clk_clk_32k, tegra_clks); | ||
89 | if (dt_clk) { | ||
90 | clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, | ||
91 | CLK_IS_ROOT, 32768); | ||
92 | *dt_clk = clk; | ||
93 | } | ||
94 | |||
95 | /* clk_m_div2 */ | ||
96 | dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div2, tegra_clks); | ||
97 | if (dt_clk) { | ||
98 | clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", | ||
99 | CLK_SET_RATE_PARENT, 1, 2); | ||
100 | *dt_clk = clk; | ||
101 | } | ||
102 | |||
103 | /* clk_m_div4 */ | ||
104 | dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div4, tegra_clks); | ||
105 | if (dt_clk) { | ||
106 | clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", | ||
107 | CLK_SET_RATE_PARENT, 1, 4); | ||
108 | *dt_clk = clk; | ||
109 | } | ||
110 | } | ||
111 | |||
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c new file mode 100644 index 000000000000..5c35885f4a7c --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-periph.c | |||
@@ -0,0 +1,674 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/clkdev.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/of_address.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/export.h> | ||
25 | #include <linux/clk/tegra.h> | ||
26 | |||
27 | #include "clk.h" | ||
28 | #include "clk-id.h" | ||
29 | |||
30 | #define CLK_SOURCE_I2S0 0x1d8 | ||
31 | #define CLK_SOURCE_I2S1 0x100 | ||
32 | #define CLK_SOURCE_I2S2 0x104 | ||
33 | #define CLK_SOURCE_NDFLASH 0x160 | ||
34 | #define CLK_SOURCE_I2S3 0x3bc | ||
35 | #define CLK_SOURCE_I2S4 0x3c0 | ||
36 | #define CLK_SOURCE_SPDIF_OUT 0x108 | ||
37 | #define CLK_SOURCE_SPDIF_IN 0x10c | ||
38 | #define CLK_SOURCE_PWM 0x110 | ||
39 | #define CLK_SOURCE_ADX 0x638 | ||
40 | #define CLK_SOURCE_ADX1 0x670 | ||
41 | #define CLK_SOURCE_AMX 0x63c | ||
42 | #define CLK_SOURCE_AMX1 0x674 | ||
43 | #define CLK_SOURCE_HDA 0x428 | ||
44 | #define CLK_SOURCE_HDA2CODEC_2X 0x3e4 | ||
45 | #define CLK_SOURCE_SBC1 0x134 | ||
46 | #define CLK_SOURCE_SBC2 0x118 | ||
47 | #define CLK_SOURCE_SBC3 0x11c | ||
48 | #define CLK_SOURCE_SBC4 0x1b4 | ||
49 | #define CLK_SOURCE_SBC5 0x3c8 | ||
50 | #define CLK_SOURCE_SBC6 0x3cc | ||
51 | #define CLK_SOURCE_SATA_OOB 0x420 | ||
52 | #define CLK_SOURCE_SATA 0x424 | ||
53 | #define CLK_SOURCE_NDSPEED 0x3f8 | ||
54 | #define CLK_SOURCE_VFIR 0x168 | ||
55 | #define CLK_SOURCE_SDMMC1 0x150 | ||
56 | #define CLK_SOURCE_SDMMC2 0x154 | ||
57 | #define CLK_SOURCE_SDMMC3 0x1bc | ||
58 | #define CLK_SOURCE_SDMMC4 0x164 | ||
59 | #define CLK_SOURCE_CVE 0x140 | ||
60 | #define CLK_SOURCE_TVO 0x188 | ||
61 | #define CLK_SOURCE_TVDAC 0x194 | ||
62 | #define CLK_SOURCE_VDE 0x1c8 | ||
63 | #define CLK_SOURCE_CSITE 0x1d4 | ||
64 | #define CLK_SOURCE_LA 0x1f8 | ||
65 | #define CLK_SOURCE_TRACE 0x634 | ||
66 | #define CLK_SOURCE_OWR 0x1cc | ||
67 | #define CLK_SOURCE_NOR 0x1d0 | ||
68 | #define CLK_SOURCE_MIPI 0x174 | ||
69 | #define CLK_SOURCE_I2C1 0x124 | ||
70 | #define CLK_SOURCE_I2C2 0x198 | ||
71 | #define CLK_SOURCE_I2C3 0x1b8 | ||
72 | #define CLK_SOURCE_I2C4 0x3c4 | ||
73 | #define CLK_SOURCE_I2C5 0x128 | ||
74 | #define CLK_SOURCE_I2C6 0x65c | ||
75 | #define CLK_SOURCE_UARTA 0x178 | ||
76 | #define CLK_SOURCE_UARTB 0x17c | ||
77 | #define CLK_SOURCE_UARTC 0x1a0 | ||
78 | #define CLK_SOURCE_UARTD 0x1c0 | ||
79 | #define CLK_SOURCE_UARTE 0x1c4 | ||
80 | #define CLK_SOURCE_3D 0x158 | ||
81 | #define CLK_SOURCE_2D 0x15c | ||
82 | #define CLK_SOURCE_MPE 0x170 | ||
83 | #define CLK_SOURCE_UARTE 0x1c4 | ||
84 | #define CLK_SOURCE_VI_SENSOR 0x1a8 | ||
85 | #define CLK_SOURCE_VI 0x148 | ||
86 | #define CLK_SOURCE_EPP 0x16c | ||
87 | #define CLK_SOURCE_MSENC 0x1f0 | ||
88 | #define CLK_SOURCE_TSEC 0x1f4 | ||
89 | #define CLK_SOURCE_HOST1X 0x180 | ||
90 | #define CLK_SOURCE_HDMI 0x18c | ||
91 | #define CLK_SOURCE_DISP1 0x138 | ||
92 | #define CLK_SOURCE_DISP2 0x13c | ||
93 | #define CLK_SOURCE_CILAB 0x614 | ||
94 | #define CLK_SOURCE_CILCD 0x618 | ||
95 | #define CLK_SOURCE_CILE 0x61c | ||
96 | #define CLK_SOURCE_DSIALP 0x620 | ||
97 | #define CLK_SOURCE_DSIBLP 0x624 | ||
98 | #define CLK_SOURCE_TSENSOR 0x3b8 | ||
99 | #define CLK_SOURCE_D_AUDIO 0x3d0 | ||
100 | #define CLK_SOURCE_DAM0 0x3d8 | ||
101 | #define CLK_SOURCE_DAM1 0x3dc | ||
102 | #define CLK_SOURCE_DAM2 0x3e0 | ||
103 | #define CLK_SOURCE_ACTMON 0x3e8 | ||
104 | #define CLK_SOURCE_EXTERN1 0x3ec | ||
105 | #define CLK_SOURCE_EXTERN2 0x3f0 | ||
106 | #define CLK_SOURCE_EXTERN3 0x3f4 | ||
107 | #define CLK_SOURCE_I2CSLOW 0x3fc | ||
108 | #define CLK_SOURCE_SE 0x42c | ||
109 | #define CLK_SOURCE_MSELECT 0x3b4 | ||
110 | #define CLK_SOURCE_DFLL_REF 0x62c | ||
111 | #define CLK_SOURCE_DFLL_SOC 0x630 | ||
112 | #define CLK_SOURCE_SOC_THERM 0x644 | ||
113 | #define CLK_SOURCE_XUSB_HOST_SRC 0x600 | ||
114 | #define CLK_SOURCE_XUSB_FALCON_SRC 0x604 | ||
115 | #define CLK_SOURCE_XUSB_FS_SRC 0x608 | ||
116 | #define CLK_SOURCE_XUSB_SS_SRC 0x610 | ||
117 | #define CLK_SOURCE_XUSB_DEV_SRC 0x60c | ||
118 | #define CLK_SOURCE_ISP 0x144 | ||
119 | #define CLK_SOURCE_SOR0 0x414 | ||
120 | #define CLK_SOURCE_DPAUX 0x418 | ||
121 | #define CLK_SOURCE_SATA_OOB 0x420 | ||
122 | #define CLK_SOURCE_SATA 0x424 | ||
123 | #define CLK_SOURCE_ENTROPY 0x628 | ||
124 | #define CLK_SOURCE_VI_SENSOR2 0x658 | ||
125 | #define CLK_SOURCE_HDMI_AUDIO 0x668 | ||
126 | #define CLK_SOURCE_VIC03 0x678 | ||
127 | #define CLK_SOURCE_CLK72MHZ 0x66c | ||
128 | |||
129 | #define MASK(x) (BIT(x) - 1) | ||
130 | |||
131 | #define MUX(_name, _parents, _offset, \ | ||
132 | _clk_num, _gate_flags, _clk_id) \ | ||
133 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | ||
134 | 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ | ||
135 | _clk_num, _gate_flags, _clk_id, _parents##_idx, 0,\ | ||
136 | NULL) | ||
137 | |||
138 | #define MUX_FLAGS(_name, _parents, _offset,\ | ||
139 | _clk_num, _gate_flags, _clk_id, flags)\ | ||
140 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | ||
141 | 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ | ||
142 | _clk_num, _gate_flags, _clk_id, _parents##_idx, flags,\ | ||
143 | NULL) | ||
144 | |||
145 | #define MUX8(_name, _parents, _offset, \ | ||
146 | _clk_num, _gate_flags, _clk_id) \ | ||
147 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | ||
148 | 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ | ||
149 | _clk_num, _gate_flags, _clk_id, _parents##_idx, 0,\ | ||
150 | NULL) | ||
151 | |||
152 | #define MUX8_NOGATE_LOCK(_name, _parents, _offset, _clk_id, _lock) \ | ||
153 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ | ||
154 | 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ | ||
155 | 0, TEGRA_PERIPH_NO_GATE, _clk_id,\ | ||
156 | _parents##_idx, 0, _lock) | ||
157 | |||
158 | #define INT(_name, _parents, _offset, \ | ||
159 | _clk_num, _gate_flags, _clk_id) \ | ||
160 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | ||
161 | 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ | ||
162 | TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ | ||
163 | _clk_id, _parents##_idx, 0, NULL) | ||
164 | |||
165 | #define INT_FLAGS(_name, _parents, _offset,\ | ||
166 | _clk_num, _gate_flags, _clk_id, flags)\ | ||
167 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | ||
168 | 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ | ||
169 | TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ | ||
170 | _clk_id, _parents##_idx, flags, NULL) | ||
171 | |||
172 | #define INT8(_name, _parents, _offset,\ | ||
173 | _clk_num, _gate_flags, _clk_id) \ | ||
174 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | ||
175 | 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ | ||
176 | TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ | ||
177 | _clk_id, _parents##_idx, 0, NULL) | ||
178 | |||
179 | #define UART(_name, _parents, _offset,\ | ||
180 | _clk_num, _clk_id) \ | ||
181 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | ||
182 | 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART| \ | ||
183 | TEGRA_DIVIDER_ROUND_UP, _clk_num, 0, _clk_id,\ | ||
184 | _parents##_idx, 0, NULL) | ||
185 | |||
186 | #define I2C(_name, _parents, _offset,\ | ||
187 | _clk_num, _clk_id) \ | ||
188 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | ||
189 | 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ | ||
190 | _clk_num, 0, _clk_id, _parents##_idx, 0, NULL) | ||
191 | |||
192 | #define XUSB(_name, _parents, _offset, \ | ||
193 | _clk_num, _gate_flags, _clk_id) \ | ||
194 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ | ||
195 | 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT| \ | ||
196 | TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags,\ | ||
197 | _clk_id, _parents##_idx, 0, NULL) | ||
198 | |||
199 | #define AUDIO(_name, _offset, _clk_num,\ | ||
200 | _gate_flags, _clk_id) \ | ||
201 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, mux_d_audio_clk, \ | ||
202 | _offset, 16, 0xE01F, 0, 0, 8, 1, \ | ||
203 | TEGRA_DIVIDER_ROUND_UP, _clk_num, _gate_flags, \ | ||
204 | _clk_id, mux_d_audio_clk_idx, 0, NULL) | ||
205 | |||
206 | #define NODIV(_name, _parents, _offset, \ | ||
207 | _mux_shift, _mux_mask, _clk_num, \ | ||
208 | _gate_flags, _clk_id, _lock) \ | ||
209 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | ||
210 | _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ | ||
211 | _clk_num, (_gate_flags) | TEGRA_PERIPH_NO_DIV,\ | ||
212 | _clk_id, _parents##_idx, 0, _lock) | ||
213 | |||
214 | #define GATE(_name, _parent_name, \ | ||
215 | _clk_num, _gate_flags, _clk_id, _flags) \ | ||
216 | { \ | ||
217 | .name = _name, \ | ||
218 | .clk_id = _clk_id, \ | ||
219 | .p.parent_name = _parent_name, \ | ||
220 | .periph = TEGRA_CLK_PERIPH(0, 0, 0, 0, 0, 0, 0, \ | ||
221 | _clk_num, _gate_flags, 0, NULL), \ | ||
222 | .flags = _flags \ | ||
223 | } | ||
224 | |||
225 | #define PLLP_BASE 0xa0 | ||
226 | #define PLLP_MISC 0xac | ||
227 | #define PLLP_OUTA 0xa4 | ||
228 | #define PLLP_OUTB 0xa8 | ||
229 | #define PLLP_OUTC 0x67c | ||
230 | |||
231 | #define PLL_BASE_LOCK BIT(27) | ||
232 | #define PLL_MISC_LOCK_ENABLE 18 | ||
233 | |||
234 | static DEFINE_SPINLOCK(PLLP_OUTA_lock); | ||
235 | static DEFINE_SPINLOCK(PLLP_OUTB_lock); | ||
236 | static DEFINE_SPINLOCK(PLLP_OUTC_lock); | ||
237 | static DEFINE_SPINLOCK(sor0_lock); | ||
238 | |||
239 | #define MUX_I2S_SPDIF(_id) \ | ||
240 | static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ | ||
241 | #_id, "pll_p",\ | ||
242 | "clk_m"}; | ||
243 | MUX_I2S_SPDIF(audio0) | ||
244 | MUX_I2S_SPDIF(audio1) | ||
245 | MUX_I2S_SPDIF(audio2) | ||
246 | MUX_I2S_SPDIF(audio3) | ||
247 | MUX_I2S_SPDIF(audio4) | ||
248 | MUX_I2S_SPDIF(audio) | ||
249 | |||
250 | #define mux_pllaout0_audio0_2x_pllp_clkm_idx NULL | ||
251 | #define mux_pllaout0_audio1_2x_pllp_clkm_idx NULL | ||
252 | #define mux_pllaout0_audio2_2x_pllp_clkm_idx NULL | ||
253 | #define mux_pllaout0_audio3_2x_pllp_clkm_idx NULL | ||
254 | #define mux_pllaout0_audio4_2x_pllp_clkm_idx NULL | ||
255 | #define mux_pllaout0_audio_2x_pllp_clkm_idx NULL | ||
256 | |||
257 | static const char *mux_pllp_pllc_pllm_clkm[] = { | ||
258 | "pll_p", "pll_c", "pll_m", "clk_m" | ||
259 | }; | ||
260 | #define mux_pllp_pllc_pllm_clkm_idx NULL | ||
261 | |||
262 | static const char *mux_pllp_pllc_pllm[] = { "pll_p", "pll_c", "pll_m" }; | ||
263 | #define mux_pllp_pllc_pllm_idx NULL | ||
264 | |||
265 | static const char *mux_pllp_pllc_clk32_clkm[] = { | ||
266 | "pll_p", "pll_c", "clk_32k", "clk_m" | ||
267 | }; | ||
268 | #define mux_pllp_pllc_clk32_clkm_idx NULL | ||
269 | |||
270 | static const char *mux_plla_pllc_pllp_clkm[] = { | ||
271 | "pll_a_out0", "pll_c", "pll_p", "clk_m" | ||
272 | }; | ||
273 | #define mux_plla_pllc_pllp_clkm_idx mux_pllp_pllc_pllm_clkm_idx | ||
274 | |||
275 | static const char *mux_pllp_pllc2_c_c3_pllm_clkm[] = { | ||
276 | "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_m", "clk_m" | ||
277 | }; | ||
278 | static u32 mux_pllp_pllc2_c_c3_pllm_clkm_idx[] = { | ||
279 | [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, | ||
280 | }; | ||
281 | |||
282 | static const char *mux_pllp_clkm[] = { | ||
283 | "pll_p", "clk_m" | ||
284 | }; | ||
285 | static u32 mux_pllp_clkm_idx[] = { | ||
286 | [0] = 0, [1] = 3, | ||
287 | }; | ||
288 | |||
289 | static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = { | ||
290 | "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0" | ||
291 | }; | ||
292 | #define mux_pllm_pllc2_c_c3_pllp_plla_idx mux_pllp_pllc2_c_c3_pllm_clkm_idx | ||
293 | |||
294 | static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { | ||
295 | "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", | ||
296 | "pll_d2_out0", "clk_m" | ||
297 | }; | ||
298 | #define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL | ||
299 | |||
300 | static const char *mux_pllm_pllc_pllp_plla[] = { | ||
301 | "pll_m", "pll_c", "pll_p", "pll_a_out0" | ||
302 | }; | ||
303 | #define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx | ||
304 | |||
305 | static const char *mux_pllp_pllc_clkm[] = { | ||
306 | "pll_p", "pll_c", "pll_m" | ||
307 | }; | ||
308 | static u32 mux_pllp_pllc_clkm_idx[] = { | ||
309 | [0] = 0, [1] = 1, [2] = 3, | ||
310 | }; | ||
311 | |||
312 | static const char *mux_pllp_pllc_clkm_clk32[] = { | ||
313 | "pll_p", "pll_c", "clk_m", "clk_32k" | ||
314 | }; | ||
315 | #define mux_pllp_pllc_clkm_clk32_idx NULL | ||
316 | |||
317 | static const char *mux_plla_clk32_pllp_clkm_plle[] = { | ||
318 | "pll_a_out0", "clk_32k", "pll_p", "clk_m", "pll_e_out0" | ||
319 | }; | ||
320 | #define mux_plla_clk32_pllp_clkm_plle_idx NULL | ||
321 | |||
322 | static const char *mux_clkm_pllp_pllc_pllre[] = { | ||
323 | "clk_m", "pll_p", "pll_c", "pll_re_out" | ||
324 | }; | ||
325 | static u32 mux_clkm_pllp_pllc_pllre_idx[] = { | ||
326 | [0] = 0, [1] = 1, [2] = 3, [3] = 5, | ||
327 | }; | ||
328 | |||
329 | static const char *mux_clkm_48M_pllp_480M[] = { | ||
330 | "clk_m", "pll_u_48M", "pll_p", "pll_u_480M" | ||
331 | }; | ||
332 | #define mux_clkm_48M_pllp_480M_idx NULL | ||
333 | |||
334 | static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = { | ||
335 | "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref" | ||
336 | }; | ||
337 | static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = { | ||
338 | [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7, | ||
339 | }; | ||
340 | |||
341 | static const char *mux_d_audio_clk[] = { | ||
342 | "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync", | ||
343 | "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", | ||
344 | }; | ||
345 | static u32 mux_d_audio_clk_idx[] = { | ||
346 | [0] = 0, [1] = 0x8000, [2] = 0xc000, [3] = 0xE000, [4] = 0xE001, | ||
347 | [5] = 0xE002, [6] = 0xE003, [7] = 0xE004, [8] = 0xE005, [9] = 0xE007, | ||
348 | }; | ||
349 | |||
350 | static const char *mux_pllp_plld_pllc_clkm[] = { | ||
351 | "pll_p", "pll_d_out0", "pll_c", "clk_m" | ||
352 | }; | ||
353 | #define mux_pllp_plld_pllc_clkm_idx NULL | ||
354 | static const char *mux_pllm_pllc_pllp_plla_clkm_pllc4[] = { | ||
355 | "pll_m", "pll_c", "pll_p", "pll_a_out0", "clk_m", "pll_c4", | ||
356 | }; | ||
357 | static u32 mux_pllm_pllc_pllp_plla_clkm_pllc4_idx[] = { | ||
358 | [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 6, [5] = 7, | ||
359 | }; | ||
360 | |||
361 | static const char *mux_pllp_clkm1[] = { | ||
362 | "pll_p", "clk_m", | ||
363 | }; | ||
364 | #define mux_pllp_clkm1_idx NULL | ||
365 | |||
366 | static const char *mux_pllp3_pllc_clkm[] = { | ||
367 | "pll_p_out3", "pll_c", "pll_c2", "clk_m", | ||
368 | }; | ||
369 | #define mux_pllp3_pllc_clkm_idx NULL | ||
370 | |||
371 | static const char *mux_pllm_pllc_pllp_plla_pllc2_c3_clkm[] = { | ||
372 | "pll_m", "pll_c", "pll_p", "pll_a", "pll_c2", "pll_c3", "clk_m" | ||
373 | }; | ||
374 | static u32 mux_pllm_pllc_pllp_plla_pllc2_c3_clkm_idx[] = { | ||
375 | [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, | ||
376 | }; | ||
377 | |||
378 | static const char *mux_pllm_pllc2_c_c3_pllp_plla_pllc4[] = { | ||
379 | "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0", "pll_c4", | ||
380 | }; | ||
381 | static u32 mux_pllm_pllc2_c_c3_pllp_plla_pllc4_idx[] = { | ||
382 | [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, [6] = 7, | ||
383 | }; | ||
384 | |||
385 | static const char *mux_clkm_plldp_sor0lvds[] = { | ||
386 | "clk_m", "pll_dp", "sor0_lvds", | ||
387 | }; | ||
388 | #define mux_clkm_plldp_sor0lvds_idx NULL | ||
389 | |||
390 | static struct tegra_periph_init_data periph_clks[] = { | ||
391 | AUDIO("d_audio", CLK_SOURCE_D_AUDIO, 106, TEGRA_PERIPH_ON_APB, tegra_clk_d_audio), | ||
392 | AUDIO("dam0", CLK_SOURCE_DAM0, 108, TEGRA_PERIPH_ON_APB, tegra_clk_dam0), | ||
393 | AUDIO("dam1", CLK_SOURCE_DAM1, 109, TEGRA_PERIPH_ON_APB, tegra_clk_dam1), | ||
394 | AUDIO("dam2", CLK_SOURCE_DAM2, 110, TEGRA_PERIPH_ON_APB, tegra_clk_dam2), | ||
395 | I2C("i2c1", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, tegra_clk_i2c1), | ||
396 | I2C("i2c2", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, tegra_clk_i2c2), | ||
397 | I2C("i2c3", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, tegra_clk_i2c3), | ||
398 | I2C("i2c4", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, tegra_clk_i2c4), | ||
399 | I2C("i2c5", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, tegra_clk_i2c5), | ||
400 | INT("vde", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde), | ||
401 | INT("vi", mux_pllm_pllc_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi), | ||
402 | INT("epp", mux_pllm_pllc_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp), | ||
403 | INT("host1x", mux_pllm_pllc_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x), | ||
404 | INT("mpe", mux_pllm_pllc_pllp_plla, CLK_SOURCE_MPE, 60, 0, tegra_clk_mpe), | ||
405 | INT("2d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d), | ||
406 | INT("3d", mux_pllm_pllc_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d), | ||
407 | INT8("vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, 0, tegra_clk_vde_8), | ||
408 | INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_8), | ||
409 | INT8("vi", mux_pllm_pllc2_c_c3_pllp_plla_pllc4, CLK_SOURCE_VI, 20, 0, tegra_clk_vi_9), | ||
410 | INT8("epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, 0, tegra_clk_epp_8), | ||
411 | INT8("msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, TEGRA_PERIPH_WAR_1005168, tegra_clk_msenc), | ||
412 | INT8("tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, 0, tegra_clk_tsec), | ||
413 | INT8("host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x_8), | ||
414 | INT8("se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), | ||
415 | INT8("2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d_8), | ||
416 | INT8("3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d_8), | ||
417 | INT8("vic03", mux_pllm_pllc_pllp_plla_pllc2_c3_clkm, CLK_SOURCE_VIC03, 178, 0, tegra_clk_vic03), | ||
418 | INT_FLAGS("mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, 0, tegra_clk_mselect, CLK_IGNORE_UNUSED), | ||
419 | MUX("i2s0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, TEGRA_PERIPH_ON_APB, tegra_clk_i2s0), | ||
420 | MUX("i2s1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, tegra_clk_i2s1), | ||
421 | MUX("i2s2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, tegra_clk_i2s2), | ||
422 | MUX("i2s3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, TEGRA_PERIPH_ON_APB, tegra_clk_i2s3), | ||
423 | MUX("i2s4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, TEGRA_PERIPH_ON_APB, tegra_clk_i2s4), | ||
424 | MUX("spdif_out", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, tegra_clk_spdif_out), | ||
425 | MUX("spdif_in", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, TEGRA_PERIPH_ON_APB, tegra_clk_spdif_in), | ||
426 | MUX("pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, TEGRA_PERIPH_ON_APB, tegra_clk_pwm), | ||
427 | MUX("adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, TEGRA_PERIPH_ON_APB, tegra_clk_adx), | ||
428 | MUX("amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, TEGRA_PERIPH_ON_APB, tegra_clk_amx), | ||
429 | MUX("hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, TEGRA_PERIPH_ON_APB, tegra_clk_hda), | ||
430 | MUX("hda2codec_2x", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, TEGRA_PERIPH_ON_APB, tegra_clk_hda2codec_2x), | ||
431 | MUX("vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, TEGRA_PERIPH_ON_APB, tegra_clk_vfir), | ||
432 | MUX("sdmmc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, tegra_clk_sdmmc1), | ||
433 | MUX("sdmmc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, tegra_clk_sdmmc2), | ||
434 | MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, tegra_clk_sdmmc3), | ||
435 | MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, tegra_clk_sdmmc4), | ||
436 | MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, tegra_clk_la), | ||
437 | MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, tegra_clk_trace), | ||
438 | MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, tegra_clk_owr), | ||
439 | MUX("nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, 0, tegra_clk_nor), | ||
440 | MUX("mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, TEGRA_PERIPH_ON_APB, tegra_clk_mipi), | ||
441 | MUX("vi_sensor", mux_pllm_pllc_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor), | ||
442 | MUX("cilab", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, 0, tegra_clk_cilab), | ||
443 | MUX("cilcd", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, 0, tegra_clk_cilcd), | ||
444 | MUX("cile", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, 0, tegra_clk_cile), | ||
445 | MUX("dsialp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, 0, tegra_clk_dsialp), | ||
446 | MUX("dsiblp", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, 0, tegra_clk_dsiblp), | ||
447 | MUX("tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, TEGRA_PERIPH_ON_APB, tegra_clk_tsensor), | ||
448 | MUX("actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, 0, tegra_clk_actmon), | ||
449 | MUX("dfll_ref", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, TEGRA_PERIPH_ON_APB, tegra_clk_dfll_ref), | ||
450 | MUX("dfll_soc", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, TEGRA_PERIPH_ON_APB, tegra_clk_dfll_soc), | ||
451 | MUX("i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, TEGRA_PERIPH_ON_APB, tegra_clk_i2cslow), | ||
452 | MUX("sbc1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1), | ||
453 | MUX("sbc2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2), | ||
454 | MUX("sbc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3), | ||
455 | MUX("sbc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, tegra_clk_sbc4), | ||
456 | MUX("sbc5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, tegra_clk_sbc5), | ||
457 | MUX("sbc6", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, tegra_clk_sbc6), | ||
458 | MUX("cve", mux_pllp_plld_pllc_clkm, CLK_SOURCE_CVE, 49, 0, tegra_clk_cve), | ||
459 | MUX("tvo", mux_pllp_plld_pllc_clkm, CLK_SOURCE_TVO, 49, 0, tegra_clk_tvo), | ||
460 | MUX("tvdac", mux_pllp_plld_pllc_clkm, CLK_SOURCE_TVDAC, 53, 0, tegra_clk_tvdac), | ||
461 | MUX("ndflash", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash), | ||
462 | MUX("ndspeed", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed), | ||
463 | MUX("sata_oob", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA_OOB, 123, TEGRA_PERIPH_ON_APB, tegra_clk_sata_oob), | ||
464 | MUX("sata", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA, 124, TEGRA_PERIPH_ON_APB, tegra_clk_sata), | ||
465 | MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1), | ||
466 | MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1), | ||
467 | MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2), | ||
468 | MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_8), | ||
469 | MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_8), | ||
470 | MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_8), | ||
471 | MUX8("sbc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC4, 68, TEGRA_PERIPH_ON_APB, tegra_clk_sbc4_8), | ||
472 | MUX8("sbc5", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC5, 104, TEGRA_PERIPH_ON_APB, tegra_clk_sbc5_8), | ||
473 | MUX8("sbc6", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC6, 105, TEGRA_PERIPH_ON_APB, tegra_clk_sbc6_8), | ||
474 | MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash_8), | ||
475 | MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed_8), | ||
476 | MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, tegra_clk_hdmi), | ||
477 | MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, tegra_clk_extern1), | ||
478 | MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, tegra_clk_extern2), | ||
479 | MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, tegra_clk_extern3), | ||
480 | MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), | ||
481 | MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), | ||
482 | MUX8("isp", mux_pllm_pllc_pllp_plla_clkm_pllc4, CLK_SOURCE_ISP, 23, TEGRA_PERIPH_ON_APB, tegra_clk_isp_8), | ||
483 | MUX8("entropy", mux_pllp_clkm1, CLK_SOURCE_ENTROPY, 149, 0, tegra_clk_entropy), | ||
484 | MUX8("hdmi_audio", mux_pllp3_pllc_clkm, CLK_SOURCE_HDMI_AUDIO, 176, TEGRA_PERIPH_NO_RESET, tegra_clk_hdmi_audio), | ||
485 | MUX8("clk72mhz", mux_pllp3_pllc_clkm, CLK_SOURCE_CLK72MHZ, 177, TEGRA_PERIPH_NO_RESET, tegra_clk_clk72Mhz), | ||
486 | MUX8_NOGATE_LOCK("sor0_lvds", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_lvds, &sor0_lock), | ||
487 | MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite, CLK_IGNORE_UNUSED), | ||
488 | NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1, NULL), | ||
489 | NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2, NULL), | ||
490 | NODIV("sor0", mux_clkm_plldp_sor0lvds, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), | ||
491 | UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, tegra_clk_uarta), | ||
492 | UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), | ||
493 | UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), | ||
494 | UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, tegra_clk_uartd), | ||
495 | UART("uarte", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTE, 65, tegra_clk_uarte), | ||
496 | XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_host_src), | ||
497 | XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src), | ||
498 | XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src), | ||
499 | XUSB("xusb_ss_src", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_ss_src), | ||
500 | XUSB("xusb_dev_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_dev_src), | ||
501 | }; | ||
502 | |||
503 | static struct tegra_periph_init_data gate_clks[] = { | ||
504 | GATE("rtc", "clk_32k", 4, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_rtc, 0), | ||
505 | GATE("timer", "clk_m", 5, 0, tegra_clk_timer, 0), | ||
506 | GATE("isp", "clk_m", 23, 0, tegra_clk_isp, 0), | ||
507 | GATE("vcp", "clk_m", 29, 0, tegra_clk_vcp, 0), | ||
508 | GATE("apbdma", "clk_m", 34, 0, tegra_clk_apbdma, 0), | ||
509 | GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0), | ||
510 | GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0), | ||
511 | GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0), | ||
512 | GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0), | ||
513 | GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0), | ||
514 | GATE("hda2hdmi", "clk_m", 128, TEGRA_PERIPH_ON_APB, tegra_clk_hda2hdmi, 0), | ||
515 | GATE("bsea", "clk_m", 62, 0, tegra_clk_bsea, 0), | ||
516 | GATE("bsev", "clk_m", 63, 0, tegra_clk_bsev, 0), | ||
517 | GATE("mipi-cal", "clk_m", 56, 0, tegra_clk_mipi_cal, 0), | ||
518 | GATE("usbd", "clk_m", 22, 0, tegra_clk_usbd, 0), | ||
519 | GATE("usb2", "clk_m", 58, 0, tegra_clk_usb2, 0), | ||
520 | GATE("usb3", "clk_m", 59, 0, tegra_clk_usb3, 0), | ||
521 | GATE("csi", "pll_p_out3", 52, 0, tegra_clk_csi, 0), | ||
522 | GATE("afi", "clk_m", 72, 0, tegra_clk_afi, 0), | ||
523 | GATE("csus", "clk_m", 92, TEGRA_PERIPH_NO_RESET, tegra_clk_csus, 0), | ||
524 | GATE("dds", "clk_m", 150, TEGRA_PERIPH_ON_APB, tegra_clk_dds, 0), | ||
525 | GATE("dp2", "clk_m", 152, TEGRA_PERIPH_ON_APB, tegra_clk_dp2, 0), | ||
526 | GATE("dtv", "clk_m", 79, TEGRA_PERIPH_ON_APB, tegra_clk_dtv, 0), | ||
527 | GATE("xusb_host", "xusb_host_src", 89, 0, tegra_clk_xusb_host, 0), | ||
528 | GATE("xusb_ss", "xusb_ss_src", 156, 0, tegra_clk_xusb_ss, 0), | ||
529 | GATE("xusb_dev", "xusb_dev_src", 95, 0, tegra_clk_xusb_dev, 0), | ||
530 | GATE("dsia", "dsia_mux", 48, 0, tegra_clk_dsia, 0), | ||
531 | GATE("dsib", "dsib_mux", 82, 0, tegra_clk_dsib, 0), | ||
532 | GATE("emc", "emc_mux", 57, 0, tegra_clk_emc, CLK_IGNORE_UNUSED), | ||
533 | GATE("sata_cold", "clk_m", 129, TEGRA_PERIPH_ON_APB, tegra_clk_sata_cold, 0), | ||
534 | GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0), | ||
535 | GATE("vim2_clk", "clk_m", 11, 0, tegra_clk_vim2_clk, 0), | ||
536 | GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0), | ||
537 | GATE("dpaux", "clk_m", 181, 0, tegra_clk_dpaux, 0), | ||
538 | GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0), | ||
539 | }; | ||
540 | |||
541 | struct pll_out_data { | ||
542 | char *div_name; | ||
543 | char *pll_out_name; | ||
544 | u32 offset; | ||
545 | int clk_id; | ||
546 | u8 div_shift; | ||
547 | u8 div_flags; | ||
548 | u8 rst_shift; | ||
549 | spinlock_t *lock; | ||
550 | }; | ||
551 | |||
552 | #define PLL_OUT(_num, _offset, _div_shift, _div_flags, _rst_shift, _id) \ | ||
553 | {\ | ||
554 | .div_name = "pll_p_out" #_num "_div",\ | ||
555 | .pll_out_name = "pll_p_out" #_num,\ | ||
556 | .offset = _offset,\ | ||
557 | .div_shift = _div_shift,\ | ||
558 | .div_flags = _div_flags | TEGRA_DIVIDER_FIXED |\ | ||
559 | TEGRA_DIVIDER_ROUND_UP,\ | ||
560 | .rst_shift = _rst_shift,\ | ||
561 | .clk_id = tegra_clk_ ## _id,\ | ||
562 | .lock = &_offset ##_lock,\ | ||
563 | } | ||
564 | |||
565 | static struct pll_out_data pllp_out_clks[] = { | ||
566 | PLL_OUT(1, PLLP_OUTA, 8, 0, 0, pll_p_out1), | ||
567 | PLL_OUT(2, PLLP_OUTA, 24, 0, 16, pll_p_out2), | ||
568 | PLL_OUT(2, PLLP_OUTA, 24, TEGRA_DIVIDER_INT, 16, pll_p_out2_int), | ||
569 | PLL_OUT(3, PLLP_OUTB, 8, 0, 0, pll_p_out3), | ||
570 | PLL_OUT(4, PLLP_OUTB, 24, 0, 16, pll_p_out4), | ||
571 | PLL_OUT(5, PLLP_OUTC, 24, 0, 16, pll_p_out5), | ||
572 | }; | ||
573 | |||
574 | static void __init periph_clk_init(void __iomem *clk_base, | ||
575 | struct tegra_clk *tegra_clks) | ||
576 | { | ||
577 | int i; | ||
578 | struct clk *clk; | ||
579 | struct clk **dt_clk; | ||
580 | |||
581 | for (i = 0; i < ARRAY_SIZE(periph_clks); i++) { | ||
582 | struct tegra_clk_periph_regs *bank; | ||
583 | struct tegra_periph_init_data *data; | ||
584 | |||
585 | data = periph_clks + i; | ||
586 | |||
587 | dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); | ||
588 | if (!dt_clk) | ||
589 | continue; | ||
590 | |||
591 | bank = get_reg_bank(data->periph.gate.clk_num); | ||
592 | if (!bank) | ||
593 | continue; | ||
594 | |||
595 | data->periph.gate.regs = bank; | ||
596 | clk = tegra_clk_register_periph(data->name, | ||
597 | data->p.parent_names, data->num_parents, | ||
598 | &data->periph, clk_base, data->offset, | ||
599 | data->flags); | ||
600 | *dt_clk = clk; | ||
601 | } | ||
602 | } | ||
603 | |||
604 | static void __init gate_clk_init(void __iomem *clk_base, | ||
605 | struct tegra_clk *tegra_clks) | ||
606 | { | ||
607 | int i; | ||
608 | struct clk *clk; | ||
609 | struct clk **dt_clk; | ||
610 | |||
611 | for (i = 0; i < ARRAY_SIZE(gate_clks); i++) { | ||
612 | struct tegra_periph_init_data *data; | ||
613 | |||
614 | data = gate_clks + i; | ||
615 | |||
616 | dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); | ||
617 | if (!dt_clk) | ||
618 | continue; | ||
619 | |||
620 | clk = tegra_clk_register_periph_gate(data->name, | ||
621 | data->p.parent_name, data->periph.gate.flags, | ||
622 | clk_base, data->flags, | ||
623 | data->periph.gate.clk_num, | ||
624 | periph_clk_enb_refcnt); | ||
625 | *dt_clk = clk; | ||
626 | } | ||
627 | } | ||
628 | |||
629 | static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base, | ||
630 | struct tegra_clk *tegra_clks, | ||
631 | struct tegra_clk_pll_params *pll_params) | ||
632 | { | ||
633 | struct clk *clk; | ||
634 | struct clk **dt_clk; | ||
635 | int i; | ||
636 | |||
637 | dt_clk = tegra_lookup_dt_id(tegra_clk_pll_p, tegra_clks); | ||
638 | if (dt_clk) { | ||
639 | /* PLLP */ | ||
640 | clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, | ||
641 | pmc_base, 0, pll_params, NULL); | ||
642 | clk_register_clkdev(clk, "pll_p", NULL); | ||
643 | *dt_clk = clk; | ||
644 | } | ||
645 | |||
646 | for (i = 0; i < ARRAY_SIZE(pllp_out_clks); i++) { | ||
647 | struct pll_out_data *data; | ||
648 | |||
649 | data = pllp_out_clks + i; | ||
650 | |||
651 | dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks); | ||
652 | if (!dt_clk) | ||
653 | continue; | ||
654 | |||
655 | clk = tegra_clk_register_divider(data->div_name, "pll_p", | ||
656 | clk_base + data->offset, 0, data->div_flags, | ||
657 | data->div_shift, 8, 1, data->lock); | ||
658 | clk = tegra_clk_register_pll_out(data->pll_out_name, | ||
659 | data->div_name, clk_base + data->offset, | ||
660 | data->rst_shift + 1, data->rst_shift, | ||
661 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
662 | data->lock); | ||
663 | *dt_clk = clk; | ||
664 | } | ||
665 | } | ||
666 | |||
667 | void __init tegra_periph_clk_init(void __iomem *clk_base, | ||
668 | void __iomem *pmc_base, struct tegra_clk *tegra_clks, | ||
669 | struct tegra_clk_pll_params *pll_params) | ||
670 | { | ||
671 | init_pllp(clk_base, pmc_base, tegra_clks, pll_params); | ||
672 | periph_clk_init(clk_base, tegra_clks); | ||
673 | gate_clk_init(clk_base, tegra_clks); | ||
674 | } | ||
diff --git a/drivers/clk/tegra/clk-tegra-pmc.c b/drivers/clk/tegra/clk-tegra-pmc.c new file mode 100644 index 000000000000..08b21c1ee867 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-pmc.c | |||
@@ -0,0 +1,132 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/clkdev.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/of_address.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/export.h> | ||
25 | #include <linux/clk/tegra.h> | ||
26 | |||
27 | #include "clk.h" | ||
28 | #include "clk-id.h" | ||
29 | |||
30 | #define PMC_CLK_OUT_CNTRL 0x1a8 | ||
31 | #define PMC_DPD_PADS_ORIDE 0x1c | ||
32 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 | ||
33 | #define PMC_CTRL 0 | ||
34 | #define PMC_CTRL_BLINK_ENB 7 | ||
35 | #define PMC_BLINK_TIMER 0x40 | ||
36 | |||
37 | struct pmc_clk_init_data { | ||
38 | char *mux_name; | ||
39 | char *gate_name; | ||
40 | const char **parents; | ||
41 | int num_parents; | ||
42 | int mux_id; | ||
43 | int gate_id; | ||
44 | char *dev_name; | ||
45 | u8 mux_shift; | ||
46 | u8 gate_shift; | ||
47 | }; | ||
48 | |||
49 | #define PMC_CLK(_num, _mux_shift, _gate_shift)\ | ||
50 | {\ | ||
51 | .mux_name = "clk_out_" #_num "_mux",\ | ||
52 | .gate_name = "clk_out_" #_num,\ | ||
53 | .parents = clk_out ##_num ##_parents,\ | ||
54 | .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\ | ||
55 | .mux_id = tegra_clk_clk_out_ ##_num ##_mux,\ | ||
56 | .gate_id = tegra_clk_clk_out_ ##_num,\ | ||
57 | .dev_name = "extern" #_num,\ | ||
58 | .mux_shift = _mux_shift,\ | ||
59 | .gate_shift = _gate_shift,\ | ||
60 | } | ||
61 | |||
62 | static DEFINE_SPINLOCK(clk_out_lock); | ||
63 | |||
64 | static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", | ||
65 | "clk_m_div4", "extern1", | ||
66 | }; | ||
67 | |||
68 | static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", | ||
69 | "clk_m_div4", "extern2", | ||
70 | }; | ||
71 | |||
72 | static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", | ||
73 | "clk_m_div4", "extern3", | ||
74 | }; | ||
75 | |||
76 | static struct pmc_clk_init_data pmc_clks[] = { | ||
77 | PMC_CLK(1, 6, 2), | ||
78 | PMC_CLK(2, 14, 10), | ||
79 | PMC_CLK(3, 22, 18), | ||
80 | }; | ||
81 | |||
82 | void __init tegra_pmc_clk_init(void __iomem *pmc_base, | ||
83 | struct tegra_clk *tegra_clks) | ||
84 | { | ||
85 | struct clk *clk; | ||
86 | struct clk **dt_clk; | ||
87 | int i; | ||
88 | |||
89 | for (i = 0; i < ARRAY_SIZE(pmc_clks); i++) { | ||
90 | struct pmc_clk_init_data *data; | ||
91 | |||
92 | data = pmc_clks + i; | ||
93 | |||
94 | dt_clk = tegra_lookup_dt_id(data->mux_id, tegra_clks); | ||
95 | if (!dt_clk) | ||
96 | continue; | ||
97 | |||
98 | clk = clk_register_mux(NULL, data->mux_name, data->parents, | ||
99 | data->num_parents, CLK_SET_RATE_NO_REPARENT, | ||
100 | pmc_base + PMC_CLK_OUT_CNTRL, data->mux_shift, | ||
101 | 3, 0, &clk_out_lock); | ||
102 | *dt_clk = clk; | ||
103 | |||
104 | |||
105 | dt_clk = tegra_lookup_dt_id(data->gate_id, tegra_clks); | ||
106 | if (!dt_clk) | ||
107 | continue; | ||
108 | |||
109 | clk = clk_register_gate(NULL, data->gate_name, data->mux_name, | ||
110 | 0, pmc_base + PMC_CLK_OUT_CNTRL, | ||
111 | data->gate_shift, 0, &clk_out_lock); | ||
112 | *dt_clk = clk; | ||
113 | clk_register_clkdev(clk, data->dev_name, data->gate_name); | ||
114 | } | ||
115 | |||
116 | /* blink */ | ||
117 | writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); | ||
118 | clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, | ||
119 | pmc_base + PMC_DPD_PADS_ORIDE, | ||
120 | PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); | ||
121 | |||
122 | dt_clk = tegra_lookup_dt_id(tegra_clk_blink, tegra_clks); | ||
123 | if (!dt_clk) | ||
124 | return; | ||
125 | |||
126 | clk = clk_register_gate(NULL, "blink", "blink_override", 0, | ||
127 | pmc_base + PMC_CTRL, | ||
128 | PMC_CTRL_BLINK_ENB, 0, NULL); | ||
129 | clk_register_clkdev(clk, "blink", NULL); | ||
130 | *dt_clk = clk; | ||
131 | } | ||
132 | |||
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c new file mode 100644 index 000000000000..05dce4aa2c11 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_address.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/export.h> | ||
24 | #include <linux/clk/tegra.h> | ||
25 | |||
26 | #include "clk.h" | ||
27 | #include "clk-id.h" | ||
28 | |||
29 | #define PLLX_BASE 0xe0 | ||
30 | #define PLLX_MISC 0xe4 | ||
31 | #define PLLX_MISC2 0x514 | ||
32 | #define PLLX_MISC3 0x518 | ||
33 | |||
34 | #define CCLKG_BURST_POLICY 0x368 | ||
35 | #define CCLKLP_BURST_POLICY 0x370 | ||
36 | #define SCLK_BURST_POLICY 0x028 | ||
37 | #define SYSTEM_CLK_RATE 0x030 | ||
38 | |||
39 | static DEFINE_SPINLOCK(sysrate_lock); | ||
40 | |||
41 | static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", | ||
42 | "pll_p", "pll_p_out2", "unused", | ||
43 | "clk_32k", "pll_m_out1" }; | ||
44 | |||
45 | static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | ||
46 | "pll_p", "pll_p_out4", "unused", | ||
47 | "unused", "pll_x" }; | ||
48 | |||
49 | static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | ||
50 | "pll_p", "pll_p_out4", "unused", | ||
51 | "unused", "pll_x", "pll_x_out0" }; | ||
52 | |||
53 | static void __init tegra_sclk_init(void __iomem *clk_base, | ||
54 | struct tegra_clk *tegra_clks) | ||
55 | { | ||
56 | struct clk *clk; | ||
57 | struct clk **dt_clk; | ||
58 | |||
59 | /* SCLK */ | ||
60 | dt_clk = tegra_lookup_dt_id(tegra_clk_sclk, tegra_clks); | ||
61 | if (dt_clk) { | ||
62 | clk = tegra_clk_register_super_mux("sclk", sclk_parents, | ||
63 | ARRAY_SIZE(sclk_parents), | ||
64 | CLK_SET_RATE_PARENT, | ||
65 | clk_base + SCLK_BURST_POLICY, | ||
66 | 0, 4, 0, 0, NULL); | ||
67 | *dt_clk = clk; | ||
68 | } | ||
69 | |||
70 | /* HCLK */ | ||
71 | dt_clk = tegra_lookup_dt_id(tegra_clk_hclk, tegra_clks); | ||
72 | if (dt_clk) { | ||
73 | clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, | ||
74 | clk_base + SYSTEM_CLK_RATE, 4, 2, 0, | ||
75 | &sysrate_lock); | ||
76 | clk = clk_register_gate(NULL, "hclk", "hclk_div", | ||
77 | CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, | ||
78 | clk_base + SYSTEM_CLK_RATE, | ||
79 | 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); | ||
80 | *dt_clk = clk; | ||
81 | } | ||
82 | |||
83 | /* PCLK */ | ||
84 | dt_clk = tegra_lookup_dt_id(tegra_clk_pclk, tegra_clks); | ||
85 | if (!dt_clk) | ||
86 | return; | ||
87 | |||
88 | clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, | ||
89 | clk_base + SYSTEM_CLK_RATE, 0, 2, 0, | ||
90 | &sysrate_lock); | ||
91 | clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT | | ||
92 | CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, | ||
93 | 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); | ||
94 | *dt_clk = clk; | ||
95 | } | ||
96 | |||
97 | void __init tegra_super_clk_gen4_init(void __iomem *clk_base, | ||
98 | void __iomem *pmc_base, | ||
99 | struct tegra_clk *tegra_clks, | ||
100 | struct tegra_clk_pll_params *params) | ||
101 | { | ||
102 | struct clk *clk; | ||
103 | struct clk **dt_clk; | ||
104 | |||
105 | /* CCLKG */ | ||
106 | dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_g, tegra_clks); | ||
107 | if (dt_clk) { | ||
108 | clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents, | ||
109 | ARRAY_SIZE(cclk_g_parents), | ||
110 | CLK_SET_RATE_PARENT, | ||
111 | clk_base + CCLKG_BURST_POLICY, | ||
112 | 0, 4, 0, 0, NULL); | ||
113 | *dt_clk = clk; | ||
114 | } | ||
115 | |||
116 | /* CCLKLP */ | ||
117 | dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks); | ||
118 | if (dt_clk) { | ||
119 | clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, | ||
120 | ARRAY_SIZE(cclk_lp_parents), | ||
121 | CLK_SET_RATE_PARENT, | ||
122 | clk_base + CCLKLP_BURST_POLICY, | ||
123 | 0, 4, 8, 9, NULL); | ||
124 | *dt_clk = clk; | ||
125 | } | ||
126 | |||
127 | tegra_sclk_init(clk_base, tegra_clks); | ||
128 | |||
129 | #if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC) | ||
130 | /* PLLX */ | ||
131 | dt_clk = tegra_lookup_dt_id(tegra_clk_pll_x, tegra_clks); | ||
132 | if (!dt_clk) | ||
133 | return; | ||
134 | |||
135 | clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, | ||
136 | pmc_base, CLK_IGNORE_UNUSED, params, NULL); | ||
137 | *dt_clk = clk; | ||
138 | |||
139 | /* PLLX_OUT0 */ | ||
140 | |||
141 | dt_clk = tegra_lookup_dt_id(tegra_clk_pll_x_out0, tegra_clks); | ||
142 | if (!dt_clk) | ||
143 | return; | ||
144 | clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", | ||
145 | CLK_SET_RATE_PARENT, 1, 2); | ||
146 | *dt_clk = clk; | ||
147 | #endif | ||
148 | } | ||
149 | |||
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 9467da7dee49..90d9d25f2228 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c | |||
@@ -23,30 +23,15 @@ | |||
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/export.h> | 24 | #include <linux/export.h> |
25 | #include <linux/clk/tegra.h> | 25 | #include <linux/clk/tegra.h> |
26 | #include <dt-bindings/clock/tegra114-car.h> | ||
26 | 27 | ||
27 | #include "clk.h" | 28 | #include "clk.h" |
29 | #include "clk-id.h" | ||
28 | 30 | ||
29 | #define RST_DEVICES_L 0x004 | ||
30 | #define RST_DEVICES_H 0x008 | ||
31 | #define RST_DEVICES_U 0x00C | ||
32 | #define RST_DFLL_DVCO 0x2F4 | 31 | #define RST_DFLL_DVCO 0x2F4 |
33 | #define RST_DEVICES_V 0x358 | ||
34 | #define RST_DEVICES_W 0x35C | ||
35 | #define RST_DEVICES_X 0x28C | ||
36 | #define RST_DEVICES_SET_L 0x300 | ||
37 | #define RST_DEVICES_CLR_L 0x304 | ||
38 | #define RST_DEVICES_SET_H 0x308 | ||
39 | #define RST_DEVICES_CLR_H 0x30c | ||
40 | #define RST_DEVICES_SET_U 0x310 | ||
41 | #define RST_DEVICES_CLR_U 0x314 | ||
42 | #define RST_DEVICES_SET_V 0x430 | ||
43 | #define RST_DEVICES_CLR_V 0x434 | ||
44 | #define RST_DEVICES_SET_W 0x438 | ||
45 | #define RST_DEVICES_CLR_W 0x43c | ||
46 | #define CPU_FINETRIM_SELECT 0x4d4 /* override default prop dlys */ | 32 | #define CPU_FINETRIM_SELECT 0x4d4 /* override default prop dlys */ |
47 | #define CPU_FINETRIM_DR 0x4d8 /* rise->rise prop dly A */ | 33 | #define CPU_FINETRIM_DR 0x4d8 /* rise->rise prop dly A */ |
48 | #define CPU_FINETRIM_R 0x4e4 /* rise->rise prop dly inc A */ | 34 | #define CPU_FINETRIM_R 0x4e4 /* rise->rise prop dly inc A */ |
49 | #define RST_DEVICES_NUM 5 | ||
50 | 35 | ||
51 | /* RST_DFLL_DVCO bitfields */ | 36 | /* RST_DFLL_DVCO bitfields */ |
52 | #define DVFS_DFLL_RESET_SHIFT 0 | 37 | #define DVFS_DFLL_RESET_SHIFT 0 |
@@ -73,25 +58,7 @@ | |||
73 | #define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */ | 58 | #define CPU_FINETRIM_R_FCPU_6_SHIFT 10 /* ftop */ |
74 | #define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT) | 59 | #define CPU_FINETRIM_R_FCPU_6_MASK (0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT) |
75 | 60 | ||
76 | #define CLK_OUT_ENB_L 0x010 | 61 | #define TEGRA114_CLK_PERIPH_BANKS 5 |
77 | #define CLK_OUT_ENB_H 0x014 | ||
78 | #define CLK_OUT_ENB_U 0x018 | ||
79 | #define CLK_OUT_ENB_V 0x360 | ||
80 | #define CLK_OUT_ENB_W 0x364 | ||
81 | #define CLK_OUT_ENB_X 0x280 | ||
82 | #define CLK_OUT_ENB_SET_L 0x320 | ||
83 | #define CLK_OUT_ENB_CLR_L 0x324 | ||
84 | #define CLK_OUT_ENB_SET_H 0x328 | ||
85 | #define CLK_OUT_ENB_CLR_H 0x32c | ||
86 | #define CLK_OUT_ENB_SET_U 0x330 | ||
87 | #define CLK_OUT_ENB_CLR_U 0x334 | ||
88 | #define CLK_OUT_ENB_SET_V 0x440 | ||
89 | #define CLK_OUT_ENB_CLR_V 0x444 | ||
90 | #define CLK_OUT_ENB_SET_W 0x448 | ||
91 | #define CLK_OUT_ENB_CLR_W 0x44c | ||
92 | #define CLK_OUT_ENB_SET_X 0x284 | ||
93 | #define CLK_OUT_ENB_CLR_X 0x288 | ||
94 | #define CLK_OUT_ENB_NUM 6 | ||
95 | 62 | ||
96 | #define PLLC_BASE 0x80 | 63 | #define PLLC_BASE 0x80 |
97 | #define PLLC_MISC2 0x88 | 64 | #define PLLC_MISC2 0x88 |
@@ -139,25 +106,6 @@ | |||
139 | #define PLLE_AUX 0x48c | 106 | #define PLLE_AUX 0x48c |
140 | #define PLLC_OUT 0x84 | 107 | #define PLLC_OUT 0x84 |
141 | #define PLLM_OUT 0x94 | 108 | #define PLLM_OUT 0x94 |
142 | #define PLLP_OUTA 0xa4 | ||
143 | #define PLLP_OUTB 0xa8 | ||
144 | #define PLLA_OUT 0xb4 | ||
145 | |||
146 | #define AUDIO_SYNC_CLK_I2S0 0x4a0 | ||
147 | #define AUDIO_SYNC_CLK_I2S1 0x4a4 | ||
148 | #define AUDIO_SYNC_CLK_I2S2 0x4a8 | ||
149 | #define AUDIO_SYNC_CLK_I2S3 0x4ac | ||
150 | #define AUDIO_SYNC_CLK_I2S4 0x4b0 | ||
151 | #define AUDIO_SYNC_CLK_SPDIF 0x4b4 | ||
152 | |||
153 | #define AUDIO_SYNC_DOUBLER 0x49c | ||
154 | |||
155 | #define PMC_CLK_OUT_CNTRL 0x1a8 | ||
156 | #define PMC_DPD_PADS_ORIDE 0x1c | ||
157 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 | ||
158 | #define PMC_CTRL 0 | ||
159 | #define PMC_CTRL_BLINK_ENB 7 | ||
160 | #define PMC_BLINK_TIMER 0x40 | ||
161 | 109 | ||
162 | #define OSC_CTRL 0x50 | 110 | #define OSC_CTRL 0x50 |
163 | #define OSC_CTRL_OSC_FREQ_SHIFT 28 | 111 | #define OSC_CTRL_OSC_FREQ_SHIFT 28 |
@@ -166,9 +114,6 @@ | |||
166 | #define PLLXC_SW_MAX_P 6 | 114 | #define PLLXC_SW_MAX_P 6 |
167 | 115 | ||
168 | #define CCLKG_BURST_POLICY 0x368 | 116 | #define CCLKG_BURST_POLICY 0x368 |
169 | #define CCLKLP_BURST_POLICY 0x370 | ||
170 | #define SCLK_BURST_POLICY 0x028 | ||
171 | #define SYSTEM_CLK_RATE 0x030 | ||
172 | 117 | ||
173 | #define UTMIP_PLL_CFG2 0x488 | 118 | #define UTMIP_PLL_CFG2 0x488 |
174 | #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) | 119 | #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) |
@@ -196,91 +141,8 @@ | |||
196 | #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) | 141 | #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) |
197 | #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) | 142 | #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) |
198 | 143 | ||
199 | #define CLK_SOURCE_I2S0 0x1d8 | ||
200 | #define CLK_SOURCE_I2S1 0x100 | ||
201 | #define CLK_SOURCE_I2S2 0x104 | ||
202 | #define CLK_SOURCE_NDFLASH 0x160 | ||
203 | #define CLK_SOURCE_I2S3 0x3bc | ||
204 | #define CLK_SOURCE_I2S4 0x3c0 | ||
205 | #define CLK_SOURCE_SPDIF_OUT 0x108 | ||
206 | #define CLK_SOURCE_SPDIF_IN 0x10c | ||
207 | #define CLK_SOURCE_PWM 0x110 | ||
208 | #define CLK_SOURCE_ADX 0x638 | ||
209 | #define CLK_SOURCE_AMX 0x63c | ||
210 | #define CLK_SOURCE_HDA 0x428 | ||
211 | #define CLK_SOURCE_HDA2CODEC_2X 0x3e4 | ||
212 | #define CLK_SOURCE_SBC1 0x134 | ||
213 | #define CLK_SOURCE_SBC2 0x118 | ||
214 | #define CLK_SOURCE_SBC3 0x11c | ||
215 | #define CLK_SOURCE_SBC4 0x1b4 | ||
216 | #define CLK_SOURCE_SBC5 0x3c8 | ||
217 | #define CLK_SOURCE_SBC6 0x3cc | ||
218 | #define CLK_SOURCE_SATA_OOB 0x420 | ||
219 | #define CLK_SOURCE_SATA 0x424 | ||
220 | #define CLK_SOURCE_NDSPEED 0x3f8 | ||
221 | #define CLK_SOURCE_VFIR 0x168 | ||
222 | #define CLK_SOURCE_SDMMC1 0x150 | ||
223 | #define CLK_SOURCE_SDMMC2 0x154 | ||
224 | #define CLK_SOURCE_SDMMC3 0x1bc | ||
225 | #define CLK_SOURCE_SDMMC4 0x164 | ||
226 | #define CLK_SOURCE_VDE 0x1c8 | ||
227 | #define CLK_SOURCE_CSITE 0x1d4 | 144 | #define CLK_SOURCE_CSITE 0x1d4 |
228 | #define CLK_SOURCE_LA 0x1f8 | ||
229 | #define CLK_SOURCE_TRACE 0x634 | ||
230 | #define CLK_SOURCE_OWR 0x1cc | ||
231 | #define CLK_SOURCE_NOR 0x1d0 | ||
232 | #define CLK_SOURCE_MIPI 0x174 | ||
233 | #define CLK_SOURCE_I2C1 0x124 | ||
234 | #define CLK_SOURCE_I2C2 0x198 | ||
235 | #define CLK_SOURCE_I2C3 0x1b8 | ||
236 | #define CLK_SOURCE_I2C4 0x3c4 | ||
237 | #define CLK_SOURCE_I2C5 0x128 | ||
238 | #define CLK_SOURCE_UARTA 0x178 | ||
239 | #define CLK_SOURCE_UARTB 0x17c | ||
240 | #define CLK_SOURCE_UARTC 0x1a0 | ||
241 | #define CLK_SOURCE_UARTD 0x1c0 | ||
242 | #define CLK_SOURCE_UARTE 0x1c4 | ||
243 | #define CLK_SOURCE_UARTA_DBG 0x178 | ||
244 | #define CLK_SOURCE_UARTB_DBG 0x17c | ||
245 | #define CLK_SOURCE_UARTC_DBG 0x1a0 | ||
246 | #define CLK_SOURCE_UARTD_DBG 0x1c0 | ||
247 | #define CLK_SOURCE_UARTE_DBG 0x1c4 | ||
248 | #define CLK_SOURCE_3D 0x158 | ||
249 | #define CLK_SOURCE_2D 0x15c | ||
250 | #define CLK_SOURCE_VI_SENSOR 0x1a8 | ||
251 | #define CLK_SOURCE_VI 0x148 | ||
252 | #define CLK_SOURCE_EPP 0x16c | ||
253 | #define CLK_SOURCE_MSENC 0x1f0 | ||
254 | #define CLK_SOURCE_TSEC 0x1f4 | ||
255 | #define CLK_SOURCE_HOST1X 0x180 | ||
256 | #define CLK_SOURCE_HDMI 0x18c | ||
257 | #define CLK_SOURCE_DISP1 0x138 | ||
258 | #define CLK_SOURCE_DISP2 0x13c | ||
259 | #define CLK_SOURCE_CILAB 0x614 | ||
260 | #define CLK_SOURCE_CILCD 0x618 | ||
261 | #define CLK_SOURCE_CILE 0x61c | ||
262 | #define CLK_SOURCE_DSIALP 0x620 | ||
263 | #define CLK_SOURCE_DSIBLP 0x624 | ||
264 | #define CLK_SOURCE_TSENSOR 0x3b8 | ||
265 | #define CLK_SOURCE_D_AUDIO 0x3d0 | ||
266 | #define CLK_SOURCE_DAM0 0x3d8 | ||
267 | #define CLK_SOURCE_DAM1 0x3dc | ||
268 | #define CLK_SOURCE_DAM2 0x3e0 | ||
269 | #define CLK_SOURCE_ACTMON 0x3e8 | ||
270 | #define CLK_SOURCE_EXTERN1 0x3ec | ||
271 | #define CLK_SOURCE_EXTERN2 0x3f0 | ||
272 | #define CLK_SOURCE_EXTERN3 0x3f4 | ||
273 | #define CLK_SOURCE_I2CSLOW 0x3fc | ||
274 | #define CLK_SOURCE_SE 0x42c | ||
275 | #define CLK_SOURCE_MSELECT 0x3b4 | ||
276 | #define CLK_SOURCE_DFLL_REF 0x62c | ||
277 | #define CLK_SOURCE_DFLL_SOC 0x630 | ||
278 | #define CLK_SOURCE_SOC_THERM 0x644 | ||
279 | #define CLK_SOURCE_XUSB_HOST_SRC 0x600 | ||
280 | #define CLK_SOURCE_XUSB_FALCON_SRC 0x604 | ||
281 | #define CLK_SOURCE_XUSB_FS_SRC 0x608 | ||
282 | #define CLK_SOURCE_XUSB_SS_SRC 0x610 | 145 | #define CLK_SOURCE_XUSB_SS_SRC 0x610 |
283 | #define CLK_SOURCE_XUSB_DEV_SRC 0x60c | ||
284 | #define CLK_SOURCE_EMC 0x19c | 146 | #define CLK_SOURCE_EMC 0x19c |
285 | 147 | ||
286 | /* PLLM override registers */ | 148 | /* PLLM override registers */ |
@@ -298,19 +160,13 @@ static struct cpu_clk_suspend_context { | |||
298 | } tegra114_cpu_clk_sctx; | 160 | } tegra114_cpu_clk_sctx; |
299 | #endif | 161 | #endif |
300 | 162 | ||
301 | static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; | ||
302 | |||
303 | static void __iomem *clk_base; | 163 | static void __iomem *clk_base; |
304 | static void __iomem *pmc_base; | 164 | static void __iomem *pmc_base; |
305 | 165 | ||
306 | static DEFINE_SPINLOCK(pll_d_lock); | 166 | static DEFINE_SPINLOCK(pll_d_lock); |
307 | static DEFINE_SPINLOCK(pll_d2_lock); | 167 | static DEFINE_SPINLOCK(pll_d2_lock); |
308 | static DEFINE_SPINLOCK(pll_u_lock); | 168 | static DEFINE_SPINLOCK(pll_u_lock); |
309 | static DEFINE_SPINLOCK(pll_div_lock); | ||
310 | static DEFINE_SPINLOCK(pll_re_lock); | 169 | static DEFINE_SPINLOCK(pll_re_lock); |
311 | static DEFINE_SPINLOCK(clk_doubler_lock); | ||
312 | static DEFINE_SPINLOCK(clk_out_lock); | ||
313 | static DEFINE_SPINLOCK(sysrate_lock); | ||
314 | 170 | ||
315 | static struct div_nmp pllxc_nmp = { | 171 | static struct div_nmp pllxc_nmp = { |
316 | .divm_shift = 0, | 172 | .divm_shift = 0, |
@@ -370,6 +226,8 @@ static struct tegra_clk_pll_params pll_c_params = { | |||
370 | .stepb_shift = 9, | 226 | .stepb_shift = 9, |
371 | .pdiv_tohw = pllxc_p, | 227 | .pdiv_tohw = pllxc_p, |
372 | .div_nmp = &pllxc_nmp, | 228 | .div_nmp = &pllxc_nmp, |
229 | .freq_table = pll_c_freq_table, | ||
230 | .flags = TEGRA_PLL_USE_LOCK, | ||
373 | }; | 231 | }; |
374 | 232 | ||
375 | static struct div_nmp pllcx_nmp = { | 233 | static struct div_nmp pllcx_nmp = { |
@@ -417,6 +275,8 @@ static struct tegra_clk_pll_params pll_c2_params = { | |||
417 | .ext_misc_reg[0] = 0x4f0, | 275 | .ext_misc_reg[0] = 0x4f0, |
418 | .ext_misc_reg[1] = 0x4f4, | 276 | .ext_misc_reg[1] = 0x4f4, |
419 | .ext_misc_reg[2] = 0x4f8, | 277 | .ext_misc_reg[2] = 0x4f8, |
278 | .freq_table = pll_cx_freq_table, | ||
279 | .flags = TEGRA_PLL_USE_LOCK, | ||
420 | }; | 280 | }; |
421 | 281 | ||
422 | static struct tegra_clk_pll_params pll_c3_params = { | 282 | static struct tegra_clk_pll_params pll_c3_params = { |
@@ -437,6 +297,8 @@ static struct tegra_clk_pll_params pll_c3_params = { | |||
437 | .ext_misc_reg[0] = 0x504, | 297 | .ext_misc_reg[0] = 0x504, |
438 | .ext_misc_reg[1] = 0x508, | 298 | .ext_misc_reg[1] = 0x508, |
439 | .ext_misc_reg[2] = 0x50c, | 299 | .ext_misc_reg[2] = 0x50c, |
300 | .freq_table = pll_cx_freq_table, | ||
301 | .flags = TEGRA_PLL_USE_LOCK, | ||
440 | }; | 302 | }; |
441 | 303 | ||
442 | static struct div_nmp pllm_nmp = { | 304 | static struct div_nmp pllm_nmp = { |
@@ -483,6 +345,8 @@ static struct tegra_clk_pll_params pll_m_params = { | |||
483 | .div_nmp = &pllm_nmp, | 345 | .div_nmp = &pllm_nmp, |
484 | .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, | 346 | .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, |
485 | .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, | 347 | .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, |
348 | .freq_table = pll_m_freq_table, | ||
349 | .flags = TEGRA_PLL_USE_LOCK, | ||
486 | }; | 350 | }; |
487 | 351 | ||
488 | static struct div_nmp pllp_nmp = { | 352 | static struct div_nmp pllp_nmp = { |
@@ -516,6 +380,9 @@ static struct tegra_clk_pll_params pll_p_params = { | |||
516 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 380 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
517 | .lock_delay = 300, | 381 | .lock_delay = 300, |
518 | .div_nmp = &pllp_nmp, | 382 | .div_nmp = &pllp_nmp, |
383 | .freq_table = pll_p_freq_table, | ||
384 | .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, | ||
385 | .fixed_rate = 408000000, | ||
519 | }; | 386 | }; |
520 | 387 | ||
521 | static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { | 388 | static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { |
@@ -543,6 +410,8 @@ static struct tegra_clk_pll_params pll_a_params = { | |||
543 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 410 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
544 | .lock_delay = 300, | 411 | .lock_delay = 300, |
545 | .div_nmp = &pllp_nmp, | 412 | .div_nmp = &pllp_nmp, |
413 | .freq_table = pll_a_freq_table, | ||
414 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, | ||
546 | }; | 415 | }; |
547 | 416 | ||
548 | static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { | 417 | static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { |
@@ -579,6 +448,9 @@ static struct tegra_clk_pll_params pll_d_params = { | |||
579 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 448 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
580 | .lock_delay = 1000, | 449 | .lock_delay = 1000, |
581 | .div_nmp = &pllp_nmp, | 450 | .div_nmp = &pllp_nmp, |
451 | .freq_table = pll_d_freq_table, | ||
452 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | ||
453 | TEGRA_PLL_USE_LOCK, | ||
582 | }; | 454 | }; |
583 | 455 | ||
584 | static struct tegra_clk_pll_params pll_d2_params = { | 456 | static struct tegra_clk_pll_params pll_d2_params = { |
@@ -594,6 +466,9 @@ static struct tegra_clk_pll_params pll_d2_params = { | |||
594 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 466 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
595 | .lock_delay = 1000, | 467 | .lock_delay = 1000, |
596 | .div_nmp = &pllp_nmp, | 468 | .div_nmp = &pllp_nmp, |
469 | .freq_table = pll_d_freq_table, | ||
470 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | ||
471 | TEGRA_PLL_USE_LOCK, | ||
597 | }; | 472 | }; |
598 | 473 | ||
599 | static struct pdiv_map pllu_p[] = { | 474 | static struct pdiv_map pllu_p[] = { |
@@ -634,6 +509,9 @@ static struct tegra_clk_pll_params pll_u_params = { | |||
634 | .lock_delay = 1000, | 509 | .lock_delay = 1000, |
635 | .pdiv_tohw = pllu_p, | 510 | .pdiv_tohw = pllu_p, |
636 | .div_nmp = &pllu_nmp, | 511 | .div_nmp = &pllu_nmp, |
512 | .freq_table = pll_u_freq_table, | ||
513 | .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | ||
514 | TEGRA_PLL_USE_LOCK, | ||
637 | }; | 515 | }; |
638 | 516 | ||
639 | static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { | 517 | static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { |
@@ -667,12 +545,15 @@ static struct tegra_clk_pll_params pll_x_params = { | |||
667 | .stepb_shift = 24, | 545 | .stepb_shift = 24, |
668 | .pdiv_tohw = pllxc_p, | 546 | .pdiv_tohw = pllxc_p, |
669 | .div_nmp = &pllxc_nmp, | 547 | .div_nmp = &pllxc_nmp, |
548 | .freq_table = pll_x_freq_table, | ||
549 | .flags = TEGRA_PLL_USE_LOCK, | ||
670 | }; | 550 | }; |
671 | 551 | ||
672 | static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { | 552 | static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { |
673 | /* PLLE special case: use cpcon field to store cml divider value */ | 553 | /* PLLE special case: use cpcon field to store cml divider value */ |
674 | {336000000, 100000000, 100, 21, 16, 11}, | 554 | {336000000, 100000000, 100, 21, 16, 11}, |
675 | {312000000, 100000000, 200, 26, 24, 13}, | 555 | {312000000, 100000000, 200, 26, 24, 13}, |
556 | {12000000, 100000000, 200, 1, 24, 13}, | ||
676 | {0, 0, 0, 0, 0, 0}, | 557 | {0, 0, 0, 0, 0, 0}, |
677 | }; | 558 | }; |
678 | 559 | ||
@@ -699,6 +580,9 @@ static struct tegra_clk_pll_params pll_e_params = { | |||
699 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, | 580 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, |
700 | .lock_delay = 300, | 581 | .lock_delay = 300, |
701 | .div_nmp = &plle_nmp, | 582 | .div_nmp = &plle_nmp, |
583 | .freq_table = pll_e_freq_table, | ||
584 | .flags = TEGRA_PLL_FIXED, | ||
585 | .fixed_rate = 100000000, | ||
702 | }; | 586 | }; |
703 | 587 | ||
704 | static struct div_nmp pllre_nmp = { | 588 | static struct div_nmp pllre_nmp = { |
@@ -725,53 +609,7 @@ static struct tegra_clk_pll_params pll_re_vco_params = { | |||
725 | .iddq_reg = PLLRE_MISC, | 609 | .iddq_reg = PLLRE_MISC, |
726 | .iddq_bit_idx = PLLRE_IDDQ_BIT, | 610 | .iddq_bit_idx = PLLRE_IDDQ_BIT, |
727 | .div_nmp = &pllre_nmp, | 611 | .div_nmp = &pllre_nmp, |
728 | }; | 612 | .flags = TEGRA_PLL_USE_LOCK, |
729 | |||
730 | /* Peripheral clock registers */ | ||
731 | |||
732 | static struct tegra_clk_periph_regs periph_l_regs = { | ||
733 | .enb_reg = CLK_OUT_ENB_L, | ||
734 | .enb_set_reg = CLK_OUT_ENB_SET_L, | ||
735 | .enb_clr_reg = CLK_OUT_ENB_CLR_L, | ||
736 | .rst_reg = RST_DEVICES_L, | ||
737 | .rst_set_reg = RST_DEVICES_SET_L, | ||
738 | .rst_clr_reg = RST_DEVICES_CLR_L, | ||
739 | }; | ||
740 | |||
741 | static struct tegra_clk_periph_regs periph_h_regs = { | ||
742 | .enb_reg = CLK_OUT_ENB_H, | ||
743 | .enb_set_reg = CLK_OUT_ENB_SET_H, | ||
744 | .enb_clr_reg = CLK_OUT_ENB_CLR_H, | ||
745 | .rst_reg = RST_DEVICES_H, | ||
746 | .rst_set_reg = RST_DEVICES_SET_H, | ||
747 | .rst_clr_reg = RST_DEVICES_CLR_H, | ||
748 | }; | ||
749 | |||
750 | static struct tegra_clk_periph_regs periph_u_regs = { | ||
751 | .enb_reg = CLK_OUT_ENB_U, | ||
752 | .enb_set_reg = CLK_OUT_ENB_SET_U, | ||
753 | .enb_clr_reg = CLK_OUT_ENB_CLR_U, | ||
754 | .rst_reg = RST_DEVICES_U, | ||
755 | .rst_set_reg = RST_DEVICES_SET_U, | ||
756 | .rst_clr_reg = RST_DEVICES_CLR_U, | ||
757 | }; | ||
758 | |||
759 | static struct tegra_clk_periph_regs periph_v_regs = { | ||
760 | .enb_reg = CLK_OUT_ENB_V, | ||
761 | .enb_set_reg = CLK_OUT_ENB_SET_V, | ||
762 | .enb_clr_reg = CLK_OUT_ENB_CLR_V, | ||
763 | .rst_reg = RST_DEVICES_V, | ||
764 | .rst_set_reg = RST_DEVICES_SET_V, | ||
765 | .rst_clr_reg = RST_DEVICES_CLR_V, | ||
766 | }; | ||
767 | |||
768 | static struct tegra_clk_periph_regs periph_w_regs = { | ||
769 | .enb_reg = CLK_OUT_ENB_W, | ||
770 | .enb_set_reg = CLK_OUT_ENB_SET_W, | ||
771 | .enb_clr_reg = CLK_OUT_ENB_CLR_W, | ||
772 | .rst_reg = RST_DEVICES_W, | ||
773 | .rst_set_reg = RST_DEVICES_SET_W, | ||
774 | .rst_clr_reg = RST_DEVICES_CLR_W, | ||
775 | }; | 613 | }; |
776 | 614 | ||
777 | /* possible OSC frequencies in Hz */ | 615 | /* possible OSC frequencies in Hz */ |
@@ -787,120 +625,6 @@ static unsigned long tegra114_input_freq[] = { | |||
787 | 625 | ||
788 | #define MASK(x) (BIT(x) - 1) | 626 | #define MASK(x) (BIT(x) - 1) |
789 | 627 | ||
790 | #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ | ||
791 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
792 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ | ||
793 | 30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num, \ | ||
794 | periph_clk_enb_refcnt, _gate_flags, _clk_id, \ | ||
795 | _parents##_idx, 0) | ||
796 | |||
797 | #define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ | ||
798 | _clk_num, _regs, _gate_flags, _clk_id, flags)\ | ||
799 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ | ||
800 | 30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num, \ | ||
801 | periph_clk_enb_refcnt, _gate_flags, _clk_id, \ | ||
802 | _parents##_idx, flags) | ||
803 | |||
804 | #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ | ||
805 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
806 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ | ||
807 | 29, MASK(3), 0, 0, 8, 1, 0, _regs, _clk_num, \ | ||
808 | periph_clk_enb_refcnt, _gate_flags, _clk_id, \ | ||
809 | _parents##_idx, 0) | ||
810 | |||
811 | #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ | ||
812 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
813 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ | ||
814 | 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ | ||
815 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
816 | _clk_id, _parents##_idx, 0) | ||
817 | |||
818 | #define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\ | ||
819 | _clk_num, _regs, _gate_flags, _clk_id, flags)\ | ||
820 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ | ||
821 | 30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ | ||
822 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
823 | _clk_id, _parents##_idx, flags) | ||
824 | |||
825 | #define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\ | ||
826 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
827 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ | ||
828 | 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\ | ||
829 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
830 | _clk_id, _parents##_idx, 0) | ||
831 | |||
832 | #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ | ||
833 | _clk_num, _regs, _clk_id) \ | ||
834 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ | ||
835 | 30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs,\ | ||
836 | _clk_num, periph_clk_enb_refcnt, 0, _clk_id, \ | ||
837 | _parents##_idx, 0) | ||
838 | |||
839 | #define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\ | ||
840 | _clk_num, _regs, _clk_id) \ | ||
841 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ | ||
842 | 30, MASK(2), 0, 0, 16, 0, 0, _regs, _clk_num, \ | ||
843 | periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0) | ||
844 | |||
845 | #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ | ||
846 | _mux_shift, _mux_mask, _clk_num, _regs, \ | ||
847 | _gate_flags, _clk_id) \ | ||
848 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\ | ||
849 | _mux_shift, _mux_mask, 0, 0, 0, 0, 0, _regs, \ | ||
850 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
851 | _clk_id, _parents##_idx, 0) | ||
852 | |||
853 | #define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \ | ||
854 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
855 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \ | ||
856 | 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ | ||
857 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
858 | _clk_id, _parents##_idx, 0) | ||
859 | |||
860 | #define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset, _clk_num,\ | ||
861 | _regs, _gate_flags, _clk_id) \ | ||
862 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \ | ||
863 | _offset, 16, 0xE01F, 0, 0, 8, 1, 0, _regs, _clk_num, \ | ||
864 | periph_clk_enb_refcnt, _gate_flags , _clk_id, \ | ||
865 | mux_d_audio_clk_idx, 0) | ||
866 | |||
867 | enum tegra114_clk { | ||
868 | rtc = 4, timer = 5, uarta = 6, sdmmc2 = 9, i2s1 = 11, i2c1 = 12, | ||
869 | ndflash = 13, sdmmc1 = 14, sdmmc4 = 15, pwm = 17, i2s2 = 18, epp = 19, | ||
870 | gr_2d = 21, usbd = 22, isp = 23, gr_3d = 24, disp2 = 26, disp1 = 27, | ||
871 | host1x = 28, vcp = 29, i2s0 = 30, apbdma = 34, kbc = 36, kfuse = 40, | ||
872 | sbc1 = 41, nor = 42, sbc2 = 44, sbc3 = 46, i2c5 = 47, dsia = 48, | ||
873 | mipi = 50, hdmi = 51, csi = 52, i2c2 = 54, uartc = 55, mipi_cal = 56, | ||
874 | emc, usb2, usb3, vde = 61, bsea = 62, bsev = 63, uartd = 65, | ||
875 | i2c3 = 67, sbc4 = 68, sdmmc3 = 69, owr = 71, csite = 73, | ||
876 | la = 76, trace = 77, soc_therm = 78, dtv = 79, ndspeed = 80, | ||
877 | i2cslow = 81, dsib = 82, tsec = 83, xusb_host = 89, msenc = 91, | ||
878 | csus = 92, mselect = 99, tsensor = 100, i2s3 = 101, i2s4 = 102, | ||
879 | i2c4 = 103, sbc5 = 104, sbc6 = 105, d_audio, apbif = 107, dam0, dam1, | ||
880 | dam2, hda2codec_2x = 111, audio0_2x = 113, audio1_2x, audio2_2x, | ||
881 | audio3_2x, audio4_2x, spdif_2x, actmon = 119, extern1 = 120, | ||
882 | extern2 = 121, extern3 = 122, hda = 125, se = 127, hda2hdmi = 128, | ||
883 | cilab = 144, cilcd = 145, cile = 146, dsialp = 147, dsiblp = 148, | ||
884 | dds = 150, dp2 = 152, amx = 153, adx = 154, xusb_ss = 156, uartb = 192, | ||
885 | vfir, spdif_in, spdif_out, vi, vi_sensor, fuse, fuse_burn, clk_32k, | ||
886 | clk_m, clk_m_div2, clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_c2, | ||
887 | pll_c3, pll_m, pll_m_out1, pll_p, pll_p_out1, pll_p_out2, pll_p_out3, | ||
888 | pll_p_out4, pll_a, pll_a_out0, pll_d, pll_d_out0, pll_d2, pll_d2_out0, | ||
889 | pll_u, pll_u_480M, pll_u_60M, pll_u_48M, pll_u_12M, pll_x, pll_x_out0, | ||
890 | pll_re_vco, pll_re_out, pll_e_out0, spdif_in_sync, i2s0_sync, | ||
891 | i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, vimclk_sync, audio0, | ||
892 | audio1, audio2, audio3, audio4, spdif, clk_out_1, clk_out_2, clk_out_3, | ||
893 | blink, xusb_host_src = 252, xusb_falcon_src, xusb_fs_src, xusb_ss_src, | ||
894 | xusb_dev_src, xusb_dev, xusb_hs_src, sclk, hclk, pclk, cclk_g, cclk_lp, | ||
895 | dfll_ref = 264, dfll_soc, | ||
896 | |||
897 | /* Mux clocks */ | ||
898 | |||
899 | audio0_mux = 300, audio1_mux, audio2_mux, audio3_mux, audio4_mux, | ||
900 | spdif_mux, clk_out_1_mux, clk_out_2_mux, clk_out_3_mux, dsia_mux, | ||
901 | dsib_mux, clk_max, | ||
902 | }; | ||
903 | |||
904 | struct utmi_clk_param { | 628 | struct utmi_clk_param { |
905 | /* Oscillator Frequency in KHz */ | 629 | /* Oscillator Frequency in KHz */ |
906 | u32 osc_frequency; | 630 | u32 osc_frequency; |
@@ -934,122 +658,11 @@ static const struct utmi_clk_param utmi_parameters[] = { | |||
934 | 658 | ||
935 | /* peripheral mux definitions */ | 659 | /* peripheral mux definitions */ |
936 | 660 | ||
937 | #define MUX_I2S_SPDIF(_id) \ | ||
938 | static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ | ||
939 | #_id, "pll_p",\ | ||
940 | "clk_m"}; | ||
941 | MUX_I2S_SPDIF(audio0) | ||
942 | MUX_I2S_SPDIF(audio1) | ||
943 | MUX_I2S_SPDIF(audio2) | ||
944 | MUX_I2S_SPDIF(audio3) | ||
945 | MUX_I2S_SPDIF(audio4) | ||
946 | MUX_I2S_SPDIF(audio) | ||
947 | |||
948 | #define mux_pllaout0_audio0_2x_pllp_clkm_idx NULL | ||
949 | #define mux_pllaout0_audio1_2x_pllp_clkm_idx NULL | ||
950 | #define mux_pllaout0_audio2_2x_pllp_clkm_idx NULL | ||
951 | #define mux_pllaout0_audio3_2x_pllp_clkm_idx NULL | ||
952 | #define mux_pllaout0_audio4_2x_pllp_clkm_idx NULL | ||
953 | #define mux_pllaout0_audio_2x_pllp_clkm_idx NULL | ||
954 | |||
955 | static const char *mux_pllp_pllc_pllm_clkm[] = { | ||
956 | "pll_p", "pll_c", "pll_m", "clk_m" | ||
957 | }; | ||
958 | #define mux_pllp_pllc_pllm_clkm_idx NULL | ||
959 | |||
960 | static const char *mux_pllp_pllc_pllm[] = { "pll_p", "pll_c", "pll_m" }; | ||
961 | #define mux_pllp_pllc_pllm_idx NULL | ||
962 | |||
963 | static const char *mux_pllp_pllc_clk32_clkm[] = { | ||
964 | "pll_p", "pll_c", "clk_32k", "clk_m" | ||
965 | }; | ||
966 | #define mux_pllp_pllc_clk32_clkm_idx NULL | ||
967 | |||
968 | static const char *mux_plla_pllc_pllp_clkm[] = { | ||
969 | "pll_a_out0", "pll_c", "pll_p", "clk_m" | ||
970 | }; | ||
971 | #define mux_plla_pllc_pllp_clkm_idx mux_pllp_pllc_pllm_clkm_idx | ||
972 | |||
973 | static const char *mux_pllp_pllc2_c_c3_pllm_clkm[] = { | ||
974 | "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_m", "clk_m" | ||
975 | }; | ||
976 | static u32 mux_pllp_pllc2_c_c3_pllm_clkm_idx[] = { | ||
977 | [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, | ||
978 | }; | ||
979 | |||
980 | static const char *mux_pllp_clkm[] = { | ||
981 | "pll_p", "clk_m" | ||
982 | }; | ||
983 | static u32 mux_pllp_clkm_idx[] = { | ||
984 | [0] = 0, [1] = 3, | ||
985 | }; | ||
986 | |||
987 | static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = { | ||
988 | "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0" | ||
989 | }; | ||
990 | #define mux_pllm_pllc2_c_c3_pllp_plla_idx mux_pllp_pllc2_c_c3_pllm_clkm_idx | ||
991 | |||
992 | static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { | ||
993 | "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", | ||
994 | "pll_d2_out0", "clk_m" | ||
995 | }; | ||
996 | #define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL | ||
997 | |||
998 | static const char *mux_pllm_pllc_pllp_plla[] = { | ||
999 | "pll_m", "pll_c", "pll_p", "pll_a_out0" | ||
1000 | }; | ||
1001 | #define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx | ||
1002 | |||
1003 | static const char *mux_pllp_pllc_clkm[] = { | ||
1004 | "pll_p", "pll_c", "pll_m" | ||
1005 | }; | ||
1006 | static u32 mux_pllp_pllc_clkm_idx[] = { | ||
1007 | [0] = 0, [1] = 1, [2] = 3, | ||
1008 | }; | ||
1009 | |||
1010 | static const char *mux_pllp_pllc_clkm_clk32[] = { | ||
1011 | "pll_p", "pll_c", "clk_m", "clk_32k" | ||
1012 | }; | ||
1013 | #define mux_pllp_pllc_clkm_clk32_idx NULL | ||
1014 | |||
1015 | static const char *mux_plla_clk32_pllp_clkm_plle[] = { | ||
1016 | "pll_a_out0", "clk_32k", "pll_p", "clk_m", "pll_e_out0" | ||
1017 | }; | ||
1018 | #define mux_plla_clk32_pllp_clkm_plle_idx NULL | ||
1019 | |||
1020 | static const char *mux_clkm_pllp_pllc_pllre[] = { | ||
1021 | "clk_m", "pll_p", "pll_c", "pll_re_out" | ||
1022 | }; | ||
1023 | static u32 mux_clkm_pllp_pllc_pllre_idx[] = { | ||
1024 | [0] = 0, [1] = 1, [2] = 3, [3] = 5, | ||
1025 | }; | ||
1026 | |||
1027 | static const char *mux_clkm_48M_pllp_480M[] = { | ||
1028 | "clk_m", "pll_u_48M", "pll_p", "pll_u_480M" | ||
1029 | }; | ||
1030 | #define mux_clkm_48M_pllp_480M_idx NULL | ||
1031 | |||
1032 | static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = { | ||
1033 | "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref" | ||
1034 | }; | ||
1035 | static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = { | ||
1036 | [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7, | ||
1037 | }; | ||
1038 | |||
1039 | static const char *mux_plld_out0_plld2_out0[] = { | 661 | static const char *mux_plld_out0_plld2_out0[] = { |
1040 | "pll_d_out0", "pll_d2_out0", | 662 | "pll_d_out0", "pll_d2_out0", |
1041 | }; | 663 | }; |
1042 | #define mux_plld_out0_plld2_out0_idx NULL | 664 | #define mux_plld_out0_plld2_out0_idx NULL |
1043 | 665 | ||
1044 | static const char *mux_d_audio_clk[] = { | ||
1045 | "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync", | ||
1046 | "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", | ||
1047 | }; | ||
1048 | static u32 mux_d_audio_clk_idx[] = { | ||
1049 | [0] = 0, [1] = 0x8000, [2] = 0xc000, [3] = 0xE000, [4] = 0xE001, | ||
1050 | [5] = 0xE002, [6] = 0xE003, [7] = 0xE004, [8] = 0xE005, [9] = 0xE007, | ||
1051 | }; | ||
1052 | |||
1053 | static const char *mux_pllmcp_clkm[] = { | 666 | static const char *mux_pllmcp_clkm[] = { |
1054 | "pll_m_out0", "pll_c_out0", "pll_p_out0", "clk_m", "pll_m_ud", | 667 | "pll_m_out0", "pll_c_out0", "pll_p_out0", "clk_m", "pll_m_ud", |
1055 | }; | 668 | }; |
@@ -1064,8 +677,253 @@ static const struct clk_div_table pll_re_div_table[] = { | |||
1064 | { .val = 0, .div = 0 }, | 677 | { .val = 0, .div = 0 }, |
1065 | }; | 678 | }; |
1066 | 679 | ||
1067 | static struct clk *clks[clk_max]; | 680 | static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { |
1068 | static struct clk_onecell_data clk_data; | 681 | [tegra_clk_rtc] = { .dt_id = TEGRA114_CLK_RTC, .present = true }, |
682 | [tegra_clk_timer] = { .dt_id = TEGRA114_CLK_TIMER, .present = true }, | ||
683 | [tegra_clk_uarta] = { .dt_id = TEGRA114_CLK_UARTA, .present = true }, | ||
684 | [tegra_clk_uartd] = { .dt_id = TEGRA114_CLK_UARTD, .present = true }, | ||
685 | [tegra_clk_sdmmc2] = { .dt_id = TEGRA114_CLK_SDMMC2, .present = true }, | ||
686 | [tegra_clk_i2s1] = { .dt_id = TEGRA114_CLK_I2S1, .present = true }, | ||
687 | [tegra_clk_i2c1] = { .dt_id = TEGRA114_CLK_I2C1, .present = true }, | ||
688 | [tegra_clk_ndflash] = { .dt_id = TEGRA114_CLK_NDFLASH, .present = true }, | ||
689 | [tegra_clk_sdmmc1] = { .dt_id = TEGRA114_CLK_SDMMC1, .present = true }, | ||
690 | [tegra_clk_sdmmc4] = { .dt_id = TEGRA114_CLK_SDMMC4, .present = true }, | ||
691 | [tegra_clk_pwm] = { .dt_id = TEGRA114_CLK_PWM, .present = true }, | ||
692 | [tegra_clk_i2s0] = { .dt_id = TEGRA114_CLK_I2S0, .present = true }, | ||
693 | [tegra_clk_i2s2] = { .dt_id = TEGRA114_CLK_I2S2, .present = true }, | ||
694 | [tegra_clk_epp_8] = { .dt_id = TEGRA114_CLK_EPP, .present = true }, | ||
695 | [tegra_clk_gr2d_8] = { .dt_id = TEGRA114_CLK_GR2D, .present = true }, | ||
696 | [tegra_clk_usbd] = { .dt_id = TEGRA114_CLK_USBD, .present = true }, | ||
697 | [tegra_clk_isp] = { .dt_id = TEGRA114_CLK_ISP, .present = true }, | ||
698 | [tegra_clk_gr3d_8] = { .dt_id = TEGRA114_CLK_GR3D, .present = true }, | ||
699 | [tegra_clk_disp2] = { .dt_id = TEGRA114_CLK_DISP2, .present = true }, | ||
700 | [tegra_clk_disp1] = { .dt_id = TEGRA114_CLK_DISP1, .present = true }, | ||
701 | [tegra_clk_host1x_8] = { .dt_id = TEGRA114_CLK_HOST1X, .present = true }, | ||
702 | [tegra_clk_vcp] = { .dt_id = TEGRA114_CLK_VCP, .present = true }, | ||
703 | [tegra_clk_apbdma] = { .dt_id = TEGRA114_CLK_APBDMA, .present = true }, | ||
704 | [tegra_clk_kbc] = { .dt_id = TEGRA114_CLK_KBC, .present = true }, | ||
705 | [tegra_clk_kfuse] = { .dt_id = TEGRA114_CLK_KFUSE, .present = true }, | ||
706 | [tegra_clk_sbc1_8] = { .dt_id = TEGRA114_CLK_SBC1, .present = true }, | ||
707 | [tegra_clk_nor] = { .dt_id = TEGRA114_CLK_NOR, .present = true }, | ||
708 | [tegra_clk_sbc2_8] = { .dt_id = TEGRA114_CLK_SBC2, .present = true }, | ||
709 | [tegra_clk_sbc3_8] = { .dt_id = TEGRA114_CLK_SBC3, .present = true }, | ||
710 | [tegra_clk_i2c5] = { .dt_id = TEGRA114_CLK_I2C5, .present = true }, | ||
711 | [tegra_clk_dsia] = { .dt_id = TEGRA114_CLK_DSIA, .present = true }, | ||
712 | [tegra_clk_mipi] = { .dt_id = TEGRA114_CLK_MIPI, .present = true }, | ||
713 | [tegra_clk_hdmi] = { .dt_id = TEGRA114_CLK_HDMI, .present = true }, | ||
714 | [tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true }, | ||
715 | [tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true }, | ||
716 | [tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true }, | ||
717 | [tegra_clk_mipi_cal] = { .dt_id = TEGRA114_CLK_MIPI_CAL, .present = true }, | ||
718 | [tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true }, | ||
719 | [tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true }, | ||
720 | [tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true }, | ||
721 | [tegra_clk_vde_8] = { .dt_id = TEGRA114_CLK_VDE, .present = true }, | ||
722 | [tegra_clk_bsea] = { .dt_id = TEGRA114_CLK_BSEA, .present = true }, | ||
723 | [tegra_clk_bsev] = { .dt_id = TEGRA114_CLK_BSEV, .present = true }, | ||
724 | [tegra_clk_i2c3] = { .dt_id = TEGRA114_CLK_I2C3, .present = true }, | ||
725 | [tegra_clk_sbc4_8] = { .dt_id = TEGRA114_CLK_SBC4, .present = true }, | ||
726 | [tegra_clk_sdmmc3] = { .dt_id = TEGRA114_CLK_SDMMC3, .present = true }, | ||
727 | [tegra_clk_owr] = { .dt_id = TEGRA114_CLK_OWR, .present = true }, | ||
728 | [tegra_clk_csite] = { .dt_id = TEGRA114_CLK_CSITE, .present = true }, | ||
729 | [tegra_clk_la] = { .dt_id = TEGRA114_CLK_LA, .present = true }, | ||
730 | [tegra_clk_trace] = { .dt_id = TEGRA114_CLK_TRACE, .present = true }, | ||
731 | [tegra_clk_soc_therm] = { .dt_id = TEGRA114_CLK_SOC_THERM, .present = true }, | ||
732 | [tegra_clk_dtv] = { .dt_id = TEGRA114_CLK_DTV, .present = true }, | ||
733 | [tegra_clk_ndspeed] = { .dt_id = TEGRA114_CLK_NDSPEED, .present = true }, | ||
734 | [tegra_clk_i2cslow] = { .dt_id = TEGRA114_CLK_I2CSLOW, .present = true }, | ||
735 | [tegra_clk_dsib] = { .dt_id = TEGRA114_CLK_DSIB, .present = true }, | ||
736 | [tegra_clk_tsec] = { .dt_id = TEGRA114_CLK_TSEC, .present = true }, | ||
737 | [tegra_clk_xusb_host] = { .dt_id = TEGRA114_CLK_XUSB_HOST, .present = true }, | ||
738 | [tegra_clk_msenc] = { .dt_id = TEGRA114_CLK_MSENC, .present = true }, | ||
739 | [tegra_clk_csus] = { .dt_id = TEGRA114_CLK_CSUS, .present = true }, | ||
740 | [tegra_clk_mselect] = { .dt_id = TEGRA114_CLK_MSELECT, .present = true }, | ||
741 | [tegra_clk_tsensor] = { .dt_id = TEGRA114_CLK_TSENSOR, .present = true }, | ||
742 | [tegra_clk_i2s3] = { .dt_id = TEGRA114_CLK_I2S3, .present = true }, | ||
743 | [tegra_clk_i2s4] = { .dt_id = TEGRA114_CLK_I2S4, .present = true }, | ||
744 | [tegra_clk_i2c4] = { .dt_id = TEGRA114_CLK_I2C4, .present = true }, | ||
745 | [tegra_clk_sbc5_8] = { .dt_id = TEGRA114_CLK_SBC5, .present = true }, | ||
746 | [tegra_clk_sbc6_8] = { .dt_id = TEGRA114_CLK_SBC6, .present = true }, | ||
747 | [tegra_clk_d_audio] = { .dt_id = TEGRA114_CLK_D_AUDIO, .present = true }, | ||
748 | [tegra_clk_apbif] = { .dt_id = TEGRA114_CLK_APBIF, .present = true }, | ||
749 | [tegra_clk_dam0] = { .dt_id = TEGRA114_CLK_DAM0, .present = true }, | ||
750 | [tegra_clk_dam1] = { .dt_id = TEGRA114_CLK_DAM1, .present = true }, | ||
751 | [tegra_clk_dam2] = { .dt_id = TEGRA114_CLK_DAM2, .present = true }, | ||
752 | [tegra_clk_hda2codec_2x] = { .dt_id = TEGRA114_CLK_HDA2CODEC_2X, .present = true }, | ||
753 | [tegra_clk_audio0_2x] = { .dt_id = TEGRA114_CLK_AUDIO0_2X, .present = true }, | ||
754 | [tegra_clk_audio1_2x] = { .dt_id = TEGRA114_CLK_AUDIO1_2X, .present = true }, | ||
755 | [tegra_clk_audio2_2x] = { .dt_id = TEGRA114_CLK_AUDIO2_2X, .present = true }, | ||
756 | [tegra_clk_audio3_2x] = { .dt_id = TEGRA114_CLK_AUDIO3_2X, .present = true }, | ||
757 | [tegra_clk_audio4_2x] = { .dt_id = TEGRA114_CLK_AUDIO4_2X, .present = true }, | ||
758 | [tegra_clk_spdif_2x] = { .dt_id = TEGRA114_CLK_SPDIF_2X, .present = true }, | ||
759 | [tegra_clk_actmon] = { .dt_id = TEGRA114_CLK_ACTMON, .present = true }, | ||
760 | [tegra_clk_extern1] = { .dt_id = TEGRA114_CLK_EXTERN1, .present = true }, | ||
761 | [tegra_clk_extern2] = { .dt_id = TEGRA114_CLK_EXTERN2, .present = true }, | ||
762 | [tegra_clk_extern3] = { .dt_id = TEGRA114_CLK_EXTERN3, .present = true }, | ||
763 | [tegra_clk_hda] = { .dt_id = TEGRA114_CLK_HDA, .present = true }, | ||
764 | [tegra_clk_se] = { .dt_id = TEGRA114_CLK_SE, .present = true }, | ||
765 | [tegra_clk_hda2hdmi] = { .dt_id = TEGRA114_CLK_HDA2HDMI, .present = true }, | ||
766 | [tegra_clk_cilab] = { .dt_id = TEGRA114_CLK_CILAB, .present = true }, | ||
767 | [tegra_clk_cilcd] = { .dt_id = TEGRA114_CLK_CILCD, .present = true }, | ||
768 | [tegra_clk_cile] = { .dt_id = TEGRA114_CLK_CILE, .present = true }, | ||
769 | [tegra_clk_dsialp] = { .dt_id = TEGRA114_CLK_DSIALP, .present = true }, | ||
770 | [tegra_clk_dsiblp] = { .dt_id = TEGRA114_CLK_DSIBLP, .present = true }, | ||
771 | [tegra_clk_dds] = { .dt_id = TEGRA114_CLK_DDS, .present = true }, | ||
772 | [tegra_clk_dp2] = { .dt_id = TEGRA114_CLK_DP2, .present = true }, | ||
773 | [tegra_clk_amx] = { .dt_id = TEGRA114_CLK_AMX, .present = true }, | ||
774 | [tegra_clk_adx] = { .dt_id = TEGRA114_CLK_ADX, .present = true }, | ||
775 | [tegra_clk_xusb_ss] = { .dt_id = TEGRA114_CLK_XUSB_SS, .present = true }, | ||
776 | [tegra_clk_uartb] = { .dt_id = TEGRA114_CLK_UARTB, .present = true }, | ||
777 | [tegra_clk_vfir] = { .dt_id = TEGRA114_CLK_VFIR, .present = true }, | ||
778 | [tegra_clk_spdif_in] = { .dt_id = TEGRA114_CLK_SPDIF_IN, .present = true }, | ||
779 | [tegra_clk_spdif_out] = { .dt_id = TEGRA114_CLK_SPDIF_OUT, .present = true }, | ||
780 | [tegra_clk_vi_8] = { .dt_id = TEGRA114_CLK_VI, .present = true }, | ||
781 | [tegra_clk_vi_sensor_8] = { .dt_id = TEGRA114_CLK_VI_SENSOR, .present = true }, | ||
782 | [tegra_clk_fuse] = { .dt_id = TEGRA114_CLK_FUSE, .present = true }, | ||
783 | [tegra_clk_fuse_burn] = { .dt_id = TEGRA114_CLK_FUSE_BURN, .present = true }, | ||
784 | [tegra_clk_clk_32k] = { .dt_id = TEGRA114_CLK_CLK_32K, .present = true }, | ||
785 | [tegra_clk_clk_m] = { .dt_id = TEGRA114_CLK_CLK_M, .present = true }, | ||
786 | [tegra_clk_clk_m_div2] = { .dt_id = TEGRA114_CLK_CLK_M_DIV2, .present = true }, | ||
787 | [tegra_clk_clk_m_div4] = { .dt_id = TEGRA114_CLK_CLK_M_DIV4, .present = true }, | ||
788 | [tegra_clk_pll_ref] = { .dt_id = TEGRA114_CLK_PLL_REF, .present = true }, | ||
789 | [tegra_clk_pll_c] = { .dt_id = TEGRA114_CLK_PLL_C, .present = true }, | ||
790 | [tegra_clk_pll_c_out1] = { .dt_id = TEGRA114_CLK_PLL_C_OUT1, .present = true }, | ||
791 | [tegra_clk_pll_c2] = { .dt_id = TEGRA114_CLK_PLL_C2, .present = true }, | ||
792 | [tegra_clk_pll_c3] = { .dt_id = TEGRA114_CLK_PLL_C3, .present = true }, | ||
793 | [tegra_clk_pll_m] = { .dt_id = TEGRA114_CLK_PLL_M, .present = true }, | ||
794 | [tegra_clk_pll_m_out1] = { .dt_id = TEGRA114_CLK_PLL_M_OUT1, .present = true }, | ||
795 | [tegra_clk_pll_p] = { .dt_id = TEGRA114_CLK_PLL_P, .present = true }, | ||
796 | [tegra_clk_pll_p_out1] = { .dt_id = TEGRA114_CLK_PLL_P_OUT1, .present = true }, | ||
797 | [tegra_clk_pll_p_out2_int] = { .dt_id = TEGRA114_CLK_PLL_P_OUT2, .present = true }, | ||
798 | [tegra_clk_pll_p_out3] = { .dt_id = TEGRA114_CLK_PLL_P_OUT3, .present = true }, | ||
799 | [tegra_clk_pll_p_out4] = { .dt_id = TEGRA114_CLK_PLL_P_OUT4, .present = true }, | ||
800 | [tegra_clk_pll_a] = { .dt_id = TEGRA114_CLK_PLL_A, .present = true }, | ||
801 | [tegra_clk_pll_a_out0] = { .dt_id = TEGRA114_CLK_PLL_A_OUT0, .present = true }, | ||
802 | [tegra_clk_pll_d] = { .dt_id = TEGRA114_CLK_PLL_D, .present = true }, | ||
803 | [tegra_clk_pll_d_out0] = { .dt_id = TEGRA114_CLK_PLL_D_OUT0, .present = true }, | ||
804 | [tegra_clk_pll_d2] = { .dt_id = TEGRA114_CLK_PLL_D2, .present = true }, | ||
805 | [tegra_clk_pll_d2_out0] = { .dt_id = TEGRA114_CLK_PLL_D2_OUT0, .present = true }, | ||
806 | [tegra_clk_pll_u] = { .dt_id = TEGRA114_CLK_PLL_U, .present = true }, | ||
807 | [tegra_clk_pll_u_480m] = { .dt_id = TEGRA114_CLK_PLL_U_480M, .present = true }, | ||
808 | [tegra_clk_pll_u_60m] = { .dt_id = TEGRA114_CLK_PLL_U_60M, .present = true }, | ||
809 | [tegra_clk_pll_u_48m] = { .dt_id = TEGRA114_CLK_PLL_U_48M, .present = true }, | ||
810 | [tegra_clk_pll_u_12m] = { .dt_id = TEGRA114_CLK_PLL_U_12M, .present = true }, | ||
811 | [tegra_clk_pll_x] = { .dt_id = TEGRA114_CLK_PLL_X, .present = true }, | ||
812 | [tegra_clk_pll_x_out0] = { .dt_id = TEGRA114_CLK_PLL_X_OUT0, .present = true }, | ||
813 | [tegra_clk_pll_re_vco] = { .dt_id = TEGRA114_CLK_PLL_RE_VCO, .present = true }, | ||
814 | [tegra_clk_pll_re_out] = { .dt_id = TEGRA114_CLK_PLL_RE_OUT, .present = true }, | ||
815 | [tegra_clk_pll_e_out0] = { .dt_id = TEGRA114_CLK_PLL_E_OUT0, .present = true }, | ||
816 | [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA114_CLK_SPDIF_IN_SYNC, .present = true }, | ||
817 | [tegra_clk_i2s0_sync] = { .dt_id = TEGRA114_CLK_I2S0_SYNC, .present = true }, | ||
818 | [tegra_clk_i2s1_sync] = { .dt_id = TEGRA114_CLK_I2S1_SYNC, .present = true }, | ||
819 | [tegra_clk_i2s2_sync] = { .dt_id = TEGRA114_CLK_I2S2_SYNC, .present = true }, | ||
820 | [tegra_clk_i2s3_sync] = { .dt_id = TEGRA114_CLK_I2S3_SYNC, .present = true }, | ||
821 | [tegra_clk_i2s4_sync] = { .dt_id = TEGRA114_CLK_I2S4_SYNC, .present = true }, | ||
822 | [tegra_clk_vimclk_sync] = { .dt_id = TEGRA114_CLK_VIMCLK_SYNC, .present = true }, | ||
823 | [tegra_clk_audio0] = { .dt_id = TEGRA114_CLK_AUDIO0, .present = true }, | ||
824 | [tegra_clk_audio1] = { .dt_id = TEGRA114_CLK_AUDIO1, .present = true }, | ||
825 | [tegra_clk_audio2] = { .dt_id = TEGRA114_CLK_AUDIO2, .present = true }, | ||
826 | [tegra_clk_audio3] = { .dt_id = TEGRA114_CLK_AUDIO3, .present = true }, | ||
827 | [tegra_clk_audio4] = { .dt_id = TEGRA114_CLK_AUDIO4, .present = true }, | ||
828 | [tegra_clk_spdif] = { .dt_id = TEGRA114_CLK_SPDIF, .present = true }, | ||
829 | [tegra_clk_clk_out_1] = { .dt_id = TEGRA114_CLK_CLK_OUT_1, .present = true }, | ||
830 | [tegra_clk_clk_out_2] = { .dt_id = TEGRA114_CLK_CLK_OUT_2, .present = true }, | ||
831 | [tegra_clk_clk_out_3] = { .dt_id = TEGRA114_CLK_CLK_OUT_3, .present = true }, | ||
832 | [tegra_clk_blink] = { .dt_id = TEGRA114_CLK_BLINK, .present = true }, | ||
833 | [tegra_clk_xusb_host_src] = { .dt_id = TEGRA114_CLK_XUSB_HOST_SRC, .present = true }, | ||
834 | [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA114_CLK_XUSB_FALCON_SRC, .present = true }, | ||
835 | [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA114_CLK_XUSB_FS_SRC, .present = true }, | ||
836 | [tegra_clk_xusb_ss_src] = { .dt_id = TEGRA114_CLK_XUSB_SS_SRC, .present = true }, | ||
837 | [tegra_clk_xusb_dev_src] = { .dt_id = TEGRA114_CLK_XUSB_DEV_SRC, .present = true }, | ||
838 | [tegra_clk_xusb_dev] = { .dt_id = TEGRA114_CLK_XUSB_DEV, .present = true }, | ||
839 | [tegra_clk_xusb_hs_src] = { .dt_id = TEGRA114_CLK_XUSB_HS_SRC, .present = true }, | ||
840 | [tegra_clk_sclk] = { .dt_id = TEGRA114_CLK_SCLK, .present = true }, | ||
841 | [tegra_clk_hclk] = { .dt_id = TEGRA114_CLK_HCLK, .present = true }, | ||
842 | [tegra_clk_pclk] = { .dt_id = TEGRA114_CLK_PCLK, .present = true }, | ||
843 | [tegra_clk_cclk_g] = { .dt_id = TEGRA114_CLK_CCLK_G, .present = true }, | ||
844 | [tegra_clk_cclk_lp] = { .dt_id = TEGRA114_CLK_CCLK_LP, .present = true }, | ||
845 | [tegra_clk_dfll_ref] = { .dt_id = TEGRA114_CLK_DFLL_REF, .present = true }, | ||
846 | [tegra_clk_dfll_soc] = { .dt_id = TEGRA114_CLK_DFLL_SOC, .present = true }, | ||
847 | [tegra_clk_audio0_mux] = { .dt_id = TEGRA114_CLK_AUDIO0_MUX, .present = true }, | ||
848 | [tegra_clk_audio1_mux] = { .dt_id = TEGRA114_CLK_AUDIO1_MUX, .present = true }, | ||
849 | [tegra_clk_audio2_mux] = { .dt_id = TEGRA114_CLK_AUDIO2_MUX, .present = true }, | ||
850 | [tegra_clk_audio3_mux] = { .dt_id = TEGRA114_CLK_AUDIO3_MUX, .present = true }, | ||
851 | [tegra_clk_audio4_mux] = { .dt_id = TEGRA114_CLK_AUDIO4_MUX, .present = true }, | ||
852 | [tegra_clk_spdif_mux] = { .dt_id = TEGRA114_CLK_SPDIF_MUX, .present = true }, | ||
853 | [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_1_MUX, .present = true }, | ||
854 | [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_2_MUX, .present = true }, | ||
855 | [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_3_MUX, .present = true }, | ||
856 | [tegra_clk_dsia_mux] = { .dt_id = TEGRA114_CLK_DSIA_MUX, .present = true }, | ||
857 | [tegra_clk_dsib_mux] = { .dt_id = TEGRA114_CLK_DSIB_MUX, .present = true }, | ||
858 | }; | ||
859 | |||
860 | static struct tegra_devclk devclks[] __initdata = { | ||
861 | { .con_id = "clk_m", .dt_id = TEGRA114_CLK_CLK_M }, | ||
862 | { .con_id = "pll_ref", .dt_id = TEGRA114_CLK_PLL_REF }, | ||
863 | { .con_id = "clk_32k", .dt_id = TEGRA114_CLK_CLK_32K }, | ||
864 | { .con_id = "clk_m_div2", .dt_id = TEGRA114_CLK_CLK_M_DIV2 }, | ||
865 | { .con_id = "clk_m_div4", .dt_id = TEGRA114_CLK_CLK_M_DIV4 }, | ||
866 | { .con_id = "pll_c", .dt_id = TEGRA114_CLK_PLL_C }, | ||
867 | { .con_id = "pll_c_out1", .dt_id = TEGRA114_CLK_PLL_C_OUT1 }, | ||
868 | { .con_id = "pll_c2", .dt_id = TEGRA114_CLK_PLL_C2 }, | ||
869 | { .con_id = "pll_c3", .dt_id = TEGRA114_CLK_PLL_C3 }, | ||
870 | { .con_id = "pll_p", .dt_id = TEGRA114_CLK_PLL_P }, | ||
871 | { .con_id = "pll_p_out1", .dt_id = TEGRA114_CLK_PLL_P_OUT1 }, | ||
872 | { .con_id = "pll_p_out2", .dt_id = TEGRA114_CLK_PLL_P_OUT2 }, | ||
873 | { .con_id = "pll_p_out3", .dt_id = TEGRA114_CLK_PLL_P_OUT3 }, | ||
874 | { .con_id = "pll_p_out4", .dt_id = TEGRA114_CLK_PLL_P_OUT4 }, | ||
875 | { .con_id = "pll_m", .dt_id = TEGRA114_CLK_PLL_M }, | ||
876 | { .con_id = "pll_m_out1", .dt_id = TEGRA114_CLK_PLL_M_OUT1 }, | ||
877 | { .con_id = "pll_x", .dt_id = TEGRA114_CLK_PLL_X }, | ||
878 | { .con_id = "pll_x_out0", .dt_id = TEGRA114_CLK_PLL_X_OUT0 }, | ||
879 | { .con_id = "pll_u", .dt_id = TEGRA114_CLK_PLL_U }, | ||
880 | { .con_id = "pll_u_480M", .dt_id = TEGRA114_CLK_PLL_U_480M }, | ||
881 | { .con_id = "pll_u_60M", .dt_id = TEGRA114_CLK_PLL_U_60M }, | ||
882 | { .con_id = "pll_u_48M", .dt_id = TEGRA114_CLK_PLL_U_48M }, | ||
883 | { .con_id = "pll_u_12M", .dt_id = TEGRA114_CLK_PLL_U_12M }, | ||
884 | { .con_id = "pll_d", .dt_id = TEGRA114_CLK_PLL_D }, | ||
885 | { .con_id = "pll_d_out0", .dt_id = TEGRA114_CLK_PLL_D_OUT0 }, | ||
886 | { .con_id = "pll_d2", .dt_id = TEGRA114_CLK_PLL_D2 }, | ||
887 | { .con_id = "pll_d2_out0", .dt_id = TEGRA114_CLK_PLL_D2_OUT0 }, | ||
888 | { .con_id = "pll_a", .dt_id = TEGRA114_CLK_PLL_A }, | ||
889 | { .con_id = "pll_a_out0", .dt_id = TEGRA114_CLK_PLL_A_OUT0 }, | ||
890 | { .con_id = "pll_re_vco", .dt_id = TEGRA114_CLK_PLL_RE_VCO }, | ||
891 | { .con_id = "pll_re_out", .dt_id = TEGRA114_CLK_PLL_RE_OUT }, | ||
892 | { .con_id = "pll_e_out0", .dt_id = TEGRA114_CLK_PLL_E_OUT0 }, | ||
893 | { .con_id = "spdif_in_sync", .dt_id = TEGRA114_CLK_SPDIF_IN_SYNC }, | ||
894 | { .con_id = "i2s0_sync", .dt_id = TEGRA114_CLK_I2S0_SYNC }, | ||
895 | { .con_id = "i2s1_sync", .dt_id = TEGRA114_CLK_I2S1_SYNC }, | ||
896 | { .con_id = "i2s2_sync", .dt_id = TEGRA114_CLK_I2S2_SYNC }, | ||
897 | { .con_id = "i2s3_sync", .dt_id = TEGRA114_CLK_I2S3_SYNC }, | ||
898 | { .con_id = "i2s4_sync", .dt_id = TEGRA114_CLK_I2S4_SYNC }, | ||
899 | { .con_id = "vimclk_sync", .dt_id = TEGRA114_CLK_VIMCLK_SYNC }, | ||
900 | { .con_id = "audio0", .dt_id = TEGRA114_CLK_AUDIO0 }, | ||
901 | { .con_id = "audio1", .dt_id = TEGRA114_CLK_AUDIO1 }, | ||
902 | { .con_id = "audio2", .dt_id = TEGRA114_CLK_AUDIO2 }, | ||
903 | { .con_id = "audio3", .dt_id = TEGRA114_CLK_AUDIO3 }, | ||
904 | { .con_id = "audio4", .dt_id = TEGRA114_CLK_AUDIO4 }, | ||
905 | { .con_id = "spdif", .dt_id = TEGRA114_CLK_SPDIF }, | ||
906 | { .con_id = "audio0_2x", .dt_id = TEGRA114_CLK_AUDIO0_2X }, | ||
907 | { .con_id = "audio1_2x", .dt_id = TEGRA114_CLK_AUDIO1_2X }, | ||
908 | { .con_id = "audio2_2x", .dt_id = TEGRA114_CLK_AUDIO2_2X }, | ||
909 | { .con_id = "audio3_2x", .dt_id = TEGRA114_CLK_AUDIO3_2X }, | ||
910 | { .con_id = "audio4_2x", .dt_id = TEGRA114_CLK_AUDIO4_2X }, | ||
911 | { .con_id = "spdif_2x", .dt_id = TEGRA114_CLK_SPDIF_2X }, | ||
912 | { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA114_CLK_EXTERN1 }, | ||
913 | { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA114_CLK_EXTERN2 }, | ||
914 | { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA114_CLK_EXTERN3 }, | ||
915 | { .con_id = "blink", .dt_id = TEGRA114_CLK_BLINK }, | ||
916 | { .con_id = "cclk_g", .dt_id = TEGRA114_CLK_CCLK_G }, | ||
917 | { .con_id = "cclk_lp", .dt_id = TEGRA114_CLK_CCLK_LP }, | ||
918 | { .con_id = "sclk", .dt_id = TEGRA114_CLK_SCLK }, | ||
919 | { .con_id = "hclk", .dt_id = TEGRA114_CLK_HCLK }, | ||
920 | { .con_id = "pclk", .dt_id = TEGRA114_CLK_PCLK }, | ||
921 | { .con_id = "fuse", .dt_id = TEGRA114_CLK_FUSE }, | ||
922 | { .dev_id = "rtc-tegra", .dt_id = TEGRA114_CLK_RTC }, | ||
923 | { .dev_id = "timer", .dt_id = TEGRA114_CLK_TIMER }, | ||
924 | }; | ||
925 | |||
926 | static struct clk **clks; | ||
1069 | 927 | ||
1070 | static unsigned long osc_freq; | 928 | static unsigned long osc_freq; |
1071 | static unsigned long pll_ref_freq; | 929 | static unsigned long pll_ref_freq; |
@@ -1086,16 +944,14 @@ static int __init tegra114_osc_clk_init(void __iomem *clk_base) | |||
1086 | /* clk_m */ | 944 | /* clk_m */ |
1087 | clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, | 945 | clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, |
1088 | osc_freq); | 946 | osc_freq); |
1089 | clk_register_clkdev(clk, "clk_m", NULL); | 947 | clks[TEGRA114_CLK_CLK_M] = clk; |
1090 | clks[clk_m] = clk; | ||
1091 | 948 | ||
1092 | /* pll_ref */ | 949 | /* pll_ref */ |
1093 | val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; | 950 | val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3; |
1094 | pll_ref_div = 1 << val; | 951 | pll_ref_div = 1 << val; |
1095 | clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", | 952 | clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", |
1096 | CLK_SET_RATE_PARENT, 1, pll_ref_div); | 953 | CLK_SET_RATE_PARENT, 1, pll_ref_div); |
1097 | clk_register_clkdev(clk, "pll_ref", NULL); | 954 | clks[TEGRA114_CLK_PLL_REF] = clk; |
1098 | clks[pll_ref] = clk; | ||
1099 | 955 | ||
1100 | pll_ref_freq = osc_freq / pll_ref_div; | 956 | pll_ref_freq = osc_freq / pll_ref_div; |
1101 | 957 | ||
@@ -1109,20 +965,17 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base) | |||
1109 | /* clk_32k */ | 965 | /* clk_32k */ |
1110 | clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, | 966 | clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, |
1111 | 32768); | 967 | 32768); |
1112 | clk_register_clkdev(clk, "clk_32k", NULL); | 968 | clks[TEGRA114_CLK_CLK_32K] = clk; |
1113 | clks[clk_32k] = clk; | ||
1114 | 969 | ||
1115 | /* clk_m_div2 */ | 970 | /* clk_m_div2 */ |
1116 | clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", | 971 | clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", |
1117 | CLK_SET_RATE_PARENT, 1, 2); | 972 | CLK_SET_RATE_PARENT, 1, 2); |
1118 | clk_register_clkdev(clk, "clk_m_div2", NULL); | 973 | clks[TEGRA114_CLK_CLK_M_DIV2] = clk; |
1119 | clks[clk_m_div2] = clk; | ||
1120 | 974 | ||
1121 | /* clk_m_div4 */ | 975 | /* clk_m_div4 */ |
1122 | clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", | 976 | clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", |
1123 | CLK_SET_RATE_PARENT, 1, 4); | 977 | CLK_SET_RATE_PARENT, 1, 4); |
1124 | clk_register_clkdev(clk, "clk_m_div4", NULL); | 978 | clks[TEGRA114_CLK_CLK_M_DIV4] = clk; |
1125 | clks[clk_m_div4] = clk; | ||
1126 | 979 | ||
1127 | } | 980 | } |
1128 | 981 | ||
@@ -1208,63 +1061,6 @@ static __init void tegra114_utmi_param_configure(void __iomem *clk_base) | |||
1208 | writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); | 1061 | writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); |
1209 | } | 1062 | } |
1210 | 1063 | ||
1211 | static void __init _clip_vco_min(struct tegra_clk_pll_params *pll_params) | ||
1212 | { | ||
1213 | pll_params->vco_min = | ||
1214 | DIV_ROUND_UP(pll_params->vco_min, pll_ref_freq) * pll_ref_freq; | ||
1215 | } | ||
1216 | |||
1217 | static int __init _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params, | ||
1218 | void __iomem *clk_base) | ||
1219 | { | ||
1220 | u32 val; | ||
1221 | u32 step_a, step_b; | ||
1222 | |||
1223 | switch (pll_ref_freq) { | ||
1224 | case 12000000: | ||
1225 | case 13000000: | ||
1226 | case 26000000: | ||
1227 | step_a = 0x2B; | ||
1228 | step_b = 0x0B; | ||
1229 | break; | ||
1230 | case 16800000: | ||
1231 | step_a = 0x1A; | ||
1232 | step_b = 0x09; | ||
1233 | break; | ||
1234 | case 19200000: | ||
1235 | step_a = 0x12; | ||
1236 | step_b = 0x08; | ||
1237 | break; | ||
1238 | default: | ||
1239 | pr_err("%s: Unexpected reference rate %lu\n", | ||
1240 | __func__, pll_ref_freq); | ||
1241 | WARN_ON(1); | ||
1242 | return -EINVAL; | ||
1243 | } | ||
1244 | |||
1245 | val = step_a << pll_params->stepa_shift; | ||
1246 | val |= step_b << pll_params->stepb_shift; | ||
1247 | writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg); | ||
1248 | |||
1249 | return 0; | ||
1250 | } | ||
1251 | |||
1252 | static void __init _init_iddq(struct tegra_clk_pll_params *pll_params, | ||
1253 | void __iomem *clk_base) | ||
1254 | { | ||
1255 | u32 val, val_iddq; | ||
1256 | |||
1257 | val = readl_relaxed(clk_base + pll_params->base_reg); | ||
1258 | val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg); | ||
1259 | |||
1260 | if (val & BIT(30)) | ||
1261 | WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx)); | ||
1262 | else { | ||
1263 | val_iddq |= BIT(pll_params->iddq_bit_idx); | ||
1264 | writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg); | ||
1265 | } | ||
1266 | } | ||
1267 | |||
1268 | static void __init tegra114_pll_init(void __iomem *clk_base, | 1064 | static void __init tegra114_pll_init(void __iomem *clk_base, |
1269 | void __iomem *pmc) | 1065 | void __iomem *pmc) |
1270 | { | 1066 | { |
@@ -1272,104 +1068,34 @@ static void __init tegra114_pll_init(void __iomem *clk_base, | |||
1272 | struct clk *clk; | 1068 | struct clk *clk; |
1273 | 1069 | ||
1274 | /* PLLC */ | 1070 | /* PLLC */ |
1275 | _clip_vco_min(&pll_c_params); | 1071 | clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, |
1276 | if (_setup_dynamic_ramp(&pll_c_params, clk_base) >= 0) { | 1072 | pmc, 0, &pll_c_params, NULL); |
1277 | _init_iddq(&pll_c_params, clk_base); | 1073 | clks[TEGRA114_CLK_PLL_C] = clk; |
1278 | clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, | 1074 | |
1279 | pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK, | 1075 | /* PLLC_OUT1 */ |
1280 | pll_c_freq_table, NULL); | 1076 | clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", |
1281 | clk_register_clkdev(clk, "pll_c", NULL); | 1077 | clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, |
1282 | clks[pll_c] = clk; | 1078 | 8, 8, 1, NULL); |
1283 | 1079 | clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", | |
1284 | /* PLLC_OUT1 */ | 1080 | clk_base + PLLC_OUT, 1, 0, |
1285 | clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", | 1081 | CLK_SET_RATE_PARENT, 0, NULL); |
1286 | clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | 1082 | clks[TEGRA114_CLK_PLL_C_OUT1] = clk; |
1287 | 8, 8, 1, NULL); | ||
1288 | clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", | ||
1289 | clk_base + PLLC_OUT, 1, 0, | ||
1290 | CLK_SET_RATE_PARENT, 0, NULL); | ||
1291 | clk_register_clkdev(clk, "pll_c_out1", NULL); | ||
1292 | clks[pll_c_out1] = clk; | ||
1293 | } | ||
1294 | 1083 | ||
1295 | /* PLLC2 */ | 1084 | /* PLLC2 */ |
1296 | _clip_vco_min(&pll_c2_params); | 1085 | clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, |
1297 | clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 0, | 1086 | &pll_c2_params, NULL); |
1298 | &pll_c2_params, TEGRA_PLL_USE_LOCK, | 1087 | clks[TEGRA114_CLK_PLL_C2] = clk; |
1299 | pll_cx_freq_table, NULL); | ||
1300 | clk_register_clkdev(clk, "pll_c2", NULL); | ||
1301 | clks[pll_c2] = clk; | ||
1302 | 1088 | ||
1303 | /* PLLC3 */ | 1089 | /* PLLC3 */ |
1304 | _clip_vco_min(&pll_c3_params); | 1090 | clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, |
1305 | clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, 0, | 1091 | &pll_c3_params, NULL); |
1306 | &pll_c3_params, TEGRA_PLL_USE_LOCK, | 1092 | clks[TEGRA114_CLK_PLL_C3] = clk; |
1307 | pll_cx_freq_table, NULL); | ||
1308 | clk_register_clkdev(clk, "pll_c3", NULL); | ||
1309 | clks[pll_c3] = clk; | ||
1310 | |||
1311 | /* PLLP */ | ||
1312 | clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc, 0, | ||
1313 | 408000000, &pll_p_params, | ||
1314 | TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, | ||
1315 | pll_p_freq_table, NULL); | ||
1316 | clk_register_clkdev(clk, "pll_p", NULL); | ||
1317 | clks[pll_p] = clk; | ||
1318 | |||
1319 | /* PLLP_OUT1 */ | ||
1320 | clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", | ||
1321 | clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | | ||
1322 | TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock); | ||
1323 | clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", | ||
1324 | clk_base + PLLP_OUTA, 1, 0, | ||
1325 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
1326 | &pll_div_lock); | ||
1327 | clk_register_clkdev(clk, "pll_p_out1", NULL); | ||
1328 | clks[pll_p_out1] = clk; | ||
1329 | |||
1330 | /* PLLP_OUT2 */ | ||
1331 | clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", | ||
1332 | clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | | ||
1333 | TEGRA_DIVIDER_ROUND_UP | TEGRA_DIVIDER_INT, 24, | ||
1334 | 8, 1, &pll_div_lock); | ||
1335 | clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", | ||
1336 | clk_base + PLLP_OUTA, 17, 16, | ||
1337 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
1338 | &pll_div_lock); | ||
1339 | clk_register_clkdev(clk, "pll_p_out2", NULL); | ||
1340 | clks[pll_p_out2] = clk; | ||
1341 | |||
1342 | /* PLLP_OUT3 */ | ||
1343 | clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", | ||
1344 | clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | | ||
1345 | TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock); | ||
1346 | clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", | ||
1347 | clk_base + PLLP_OUTB, 1, 0, | ||
1348 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
1349 | &pll_div_lock); | ||
1350 | clk_register_clkdev(clk, "pll_p_out3", NULL); | ||
1351 | clks[pll_p_out3] = clk; | ||
1352 | |||
1353 | /* PLLP_OUT4 */ | ||
1354 | clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", | ||
1355 | clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | | ||
1356 | TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, | ||
1357 | &pll_div_lock); | ||
1358 | clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", | ||
1359 | clk_base + PLLP_OUTB, 17, 16, | ||
1360 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
1361 | &pll_div_lock); | ||
1362 | clk_register_clkdev(clk, "pll_p_out4", NULL); | ||
1363 | clks[pll_p_out4] = clk; | ||
1364 | 1093 | ||
1365 | /* PLLM */ | 1094 | /* PLLM */ |
1366 | _clip_vco_min(&pll_m_params); | ||
1367 | clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, | 1095 | clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, |
1368 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, | 1096 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, |
1369 | &pll_m_params, TEGRA_PLL_USE_LOCK, | 1097 | &pll_m_params, NULL); |
1370 | pll_m_freq_table, NULL); | 1098 | clks[TEGRA114_CLK_PLL_M] = clk; |
1371 | clk_register_clkdev(clk, "pll_m", NULL); | ||
1372 | clks[pll_m] = clk; | ||
1373 | 1099 | ||
1374 | /* PLLM_OUT1 */ | 1100 | /* PLLM_OUT1 */ |
1375 | clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", | 1101 | clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", |
@@ -1378,41 +1104,20 @@ static void __init tegra114_pll_init(void __iomem *clk_base, | |||
1378 | clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", | 1104 | clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", |
1379 | clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | | 1105 | clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | |
1380 | CLK_SET_RATE_PARENT, 0, NULL); | 1106 | CLK_SET_RATE_PARENT, 0, NULL); |
1381 | clk_register_clkdev(clk, "pll_m_out1", NULL); | 1107 | clks[TEGRA114_CLK_PLL_M_OUT1] = clk; |
1382 | clks[pll_m_out1] = clk; | ||
1383 | 1108 | ||
1384 | /* PLLM_UD */ | 1109 | /* PLLM_UD */ |
1385 | clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", | 1110 | clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", |
1386 | CLK_SET_RATE_PARENT, 1, 1); | 1111 | CLK_SET_RATE_PARENT, 1, 1); |
1387 | 1112 | ||
1388 | /* PLLX */ | ||
1389 | _clip_vco_min(&pll_x_params); | ||
1390 | if (_setup_dynamic_ramp(&pll_x_params, clk_base) >= 0) { | ||
1391 | _init_iddq(&pll_x_params, clk_base); | ||
1392 | clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, | ||
1393 | pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params, | ||
1394 | TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL); | ||
1395 | clk_register_clkdev(clk, "pll_x", NULL); | ||
1396 | clks[pll_x] = clk; | ||
1397 | } | ||
1398 | |||
1399 | /* PLLX_OUT0 */ | ||
1400 | clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", | ||
1401 | CLK_SET_RATE_PARENT, 1, 2); | ||
1402 | clk_register_clkdev(clk, "pll_x_out0", NULL); | ||
1403 | clks[pll_x_out0] = clk; | ||
1404 | |||
1405 | /* PLLU */ | 1113 | /* PLLU */ |
1406 | val = readl(clk_base + pll_u_params.base_reg); | 1114 | val = readl(clk_base + pll_u_params.base_reg); |
1407 | val &= ~BIT(24); /* disable PLLU_OVERRIDE */ | 1115 | val &= ~BIT(24); /* disable PLLU_OVERRIDE */ |
1408 | writel(val, clk_base + pll_u_params.base_reg); | 1116 | writel(val, clk_base + pll_u_params.base_reg); |
1409 | 1117 | ||
1410 | clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0, | 1118 | clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0, |
1411 | 0, &pll_u_params, TEGRA_PLLU | | 1119 | &pll_u_params, &pll_u_lock); |
1412 | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | 1120 | clks[TEGRA114_CLK_PLL_U] = clk; |
1413 | TEGRA_PLL_USE_LOCK, pll_u_freq_table, &pll_u_lock); | ||
1414 | clk_register_clkdev(clk, "pll_u", NULL); | ||
1415 | clks[pll_u] = clk; | ||
1416 | 1121 | ||
1417 | tegra114_utmi_param_configure(clk_base); | 1122 | tegra114_utmi_param_configure(clk_base); |
1418 | 1123 | ||
@@ -1420,731 +1125,97 @@ static void __init tegra114_pll_init(void __iomem *clk_base, | |||
1420 | clk = clk_register_gate(NULL, "pll_u_480M", "pll_u", | 1125 | clk = clk_register_gate(NULL, "pll_u_480M", "pll_u", |
1421 | CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, | 1126 | CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, |
1422 | 22, 0, &pll_u_lock); | 1127 | 22, 0, &pll_u_lock); |
1423 | clk_register_clkdev(clk, "pll_u_480M", NULL); | 1128 | clks[TEGRA114_CLK_PLL_U_480M] = clk; |
1424 | clks[pll_u_480M] = clk; | ||
1425 | 1129 | ||
1426 | /* PLLU_60M */ | 1130 | /* PLLU_60M */ |
1427 | clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u", | 1131 | clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u", |
1428 | CLK_SET_RATE_PARENT, 1, 8); | 1132 | CLK_SET_RATE_PARENT, 1, 8); |
1429 | clk_register_clkdev(clk, "pll_u_60M", NULL); | 1133 | clks[TEGRA114_CLK_PLL_U_60M] = clk; |
1430 | clks[pll_u_60M] = clk; | ||
1431 | 1134 | ||
1432 | /* PLLU_48M */ | 1135 | /* PLLU_48M */ |
1433 | clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u", | 1136 | clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u", |
1434 | CLK_SET_RATE_PARENT, 1, 10); | 1137 | CLK_SET_RATE_PARENT, 1, 10); |
1435 | clk_register_clkdev(clk, "pll_u_48M", NULL); | 1138 | clks[TEGRA114_CLK_PLL_U_48M] = clk; |
1436 | clks[pll_u_48M] = clk; | ||
1437 | 1139 | ||
1438 | /* PLLU_12M */ | 1140 | /* PLLU_12M */ |
1439 | clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u", | 1141 | clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u", |
1440 | CLK_SET_RATE_PARENT, 1, 40); | 1142 | CLK_SET_RATE_PARENT, 1, 40); |
1441 | clk_register_clkdev(clk, "pll_u_12M", NULL); | 1143 | clks[TEGRA114_CLK_PLL_U_12M] = clk; |
1442 | clks[pll_u_12M] = clk; | ||
1443 | 1144 | ||
1444 | /* PLLD */ | 1145 | /* PLLD */ |
1445 | clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, | 1146 | clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, |
1446 | 0, &pll_d_params, | 1147 | &pll_d_params, &pll_d_lock); |
1447 | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | 1148 | clks[TEGRA114_CLK_PLL_D] = clk; |
1448 | TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d_lock); | ||
1449 | clk_register_clkdev(clk, "pll_d", NULL); | ||
1450 | clks[pll_d] = clk; | ||
1451 | 1149 | ||
1452 | /* PLLD_OUT0 */ | 1150 | /* PLLD_OUT0 */ |
1453 | clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", | 1151 | clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", |
1454 | CLK_SET_RATE_PARENT, 1, 2); | 1152 | CLK_SET_RATE_PARENT, 1, 2); |
1455 | clk_register_clkdev(clk, "pll_d_out0", NULL); | 1153 | clks[TEGRA114_CLK_PLL_D_OUT0] = clk; |
1456 | clks[pll_d_out0] = clk; | ||
1457 | 1154 | ||
1458 | /* PLLD2 */ | 1155 | /* PLLD2 */ |
1459 | clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0, | 1156 | clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0, |
1460 | 0, &pll_d2_params, | 1157 | &pll_d2_params, &pll_d2_lock); |
1461 | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | 1158 | clks[TEGRA114_CLK_PLL_D2] = clk; |
1462 | TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d2_lock); | ||
1463 | clk_register_clkdev(clk, "pll_d2", NULL); | ||
1464 | clks[pll_d2] = clk; | ||
1465 | 1159 | ||
1466 | /* PLLD2_OUT0 */ | 1160 | /* PLLD2_OUT0 */ |
1467 | clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", | 1161 | clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", |
1468 | CLK_SET_RATE_PARENT, 1, 2); | 1162 | CLK_SET_RATE_PARENT, 1, 2); |
1469 | clk_register_clkdev(clk, "pll_d2_out0", NULL); | 1163 | clks[TEGRA114_CLK_PLL_D2_OUT0] = clk; |
1470 | clks[pll_d2_out0] = clk; | ||
1471 | |||
1472 | /* PLLA */ | ||
1473 | clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc, 0, | ||
1474 | 0, &pll_a_params, TEGRA_PLL_HAS_CPCON | | ||
1475 | TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL); | ||
1476 | clk_register_clkdev(clk, "pll_a", NULL); | ||
1477 | clks[pll_a] = clk; | ||
1478 | |||
1479 | /* PLLA_OUT0 */ | ||
1480 | clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", | ||
1481 | clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
1482 | 8, 8, 1, NULL); | ||
1483 | clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", | ||
1484 | clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | | ||
1485 | CLK_SET_RATE_PARENT, 0, NULL); | ||
1486 | clk_register_clkdev(clk, "pll_a_out0", NULL); | ||
1487 | clks[pll_a_out0] = clk; | ||
1488 | 1164 | ||
1489 | /* PLLRE */ | 1165 | /* PLLRE */ |
1490 | _clip_vco_min(&pll_re_vco_params); | ||
1491 | clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, | 1166 | clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, |
1492 | 0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK, | 1167 | 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); |
1493 | NULL, &pll_re_lock, pll_ref_freq); | 1168 | clks[TEGRA114_CLK_PLL_RE_VCO] = clk; |
1494 | clk_register_clkdev(clk, "pll_re_vco", NULL); | ||
1495 | clks[pll_re_vco] = clk; | ||
1496 | 1169 | ||
1497 | clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, | 1170 | clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, |
1498 | clk_base + PLLRE_BASE, 16, 4, 0, | 1171 | clk_base + PLLRE_BASE, 16, 4, 0, |
1499 | pll_re_div_table, &pll_re_lock); | 1172 | pll_re_div_table, &pll_re_lock); |
1500 | clk_register_clkdev(clk, "pll_re_out", NULL); | 1173 | clks[TEGRA114_CLK_PLL_RE_OUT] = clk; |
1501 | clks[pll_re_out] = clk; | ||
1502 | 1174 | ||
1503 | /* PLLE */ | 1175 | /* PLLE */ |
1504 | clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_re_vco", | 1176 | clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_ref", |
1505 | clk_base, 0, 100000000, &pll_e_params, | 1177 | clk_base, 0, &pll_e_params, NULL); |
1506 | pll_e_freq_table, NULL); | 1178 | clks[TEGRA114_CLK_PLL_E_OUT0] = clk; |
1507 | clk_register_clkdev(clk, "pll_e_out0", NULL); | ||
1508 | clks[pll_e_out0] = clk; | ||
1509 | } | ||
1510 | |||
1511 | static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", | ||
1512 | "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync", | ||
1513 | }; | ||
1514 | |||
1515 | static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", | ||
1516 | "clk_m_div4", "extern1", | ||
1517 | }; | ||
1518 | |||
1519 | static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", | ||
1520 | "clk_m_div4", "extern2", | ||
1521 | }; | ||
1522 | |||
1523 | static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", | ||
1524 | "clk_m_div4", "extern3", | ||
1525 | }; | ||
1526 | |||
1527 | static void __init tegra114_audio_clk_init(void __iomem *clk_base) | ||
1528 | { | ||
1529 | struct clk *clk; | ||
1530 | |||
1531 | /* spdif_in_sync */ | ||
1532 | clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, | ||
1533 | 24000000); | ||
1534 | clk_register_clkdev(clk, "spdif_in_sync", NULL); | ||
1535 | clks[spdif_in_sync] = clk; | ||
1536 | |||
1537 | /* i2s0_sync */ | ||
1538 | clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); | ||
1539 | clk_register_clkdev(clk, "i2s0_sync", NULL); | ||
1540 | clks[i2s0_sync] = clk; | ||
1541 | |||
1542 | /* i2s1_sync */ | ||
1543 | clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); | ||
1544 | clk_register_clkdev(clk, "i2s1_sync", NULL); | ||
1545 | clks[i2s1_sync] = clk; | ||
1546 | |||
1547 | /* i2s2_sync */ | ||
1548 | clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); | ||
1549 | clk_register_clkdev(clk, "i2s2_sync", NULL); | ||
1550 | clks[i2s2_sync] = clk; | ||
1551 | |||
1552 | /* i2s3_sync */ | ||
1553 | clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); | ||
1554 | clk_register_clkdev(clk, "i2s3_sync", NULL); | ||
1555 | clks[i2s3_sync] = clk; | ||
1556 | |||
1557 | /* i2s4_sync */ | ||
1558 | clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); | ||
1559 | clk_register_clkdev(clk, "i2s4_sync", NULL); | ||
1560 | clks[i2s4_sync] = clk; | ||
1561 | |||
1562 | /* vimclk_sync */ | ||
1563 | clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); | ||
1564 | clk_register_clkdev(clk, "vimclk_sync", NULL); | ||
1565 | clks[vimclk_sync] = clk; | ||
1566 | |||
1567 | /* audio0 */ | ||
1568 | clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk, | ||
1569 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1570 | CLK_SET_RATE_NO_REPARENT, | ||
1571 | clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, | ||
1572 | NULL); | ||
1573 | clks[audio0_mux] = clk; | ||
1574 | clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, | ||
1575 | clk_base + AUDIO_SYNC_CLK_I2S0, 4, | ||
1576 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1577 | clk_register_clkdev(clk, "audio0", NULL); | ||
1578 | clks[audio0] = clk; | ||
1579 | |||
1580 | /* audio1 */ | ||
1581 | clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk, | ||
1582 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1583 | CLK_SET_RATE_NO_REPARENT, | ||
1584 | clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, | ||
1585 | NULL); | ||
1586 | clks[audio1_mux] = clk; | ||
1587 | clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, | ||
1588 | clk_base + AUDIO_SYNC_CLK_I2S1, 4, | ||
1589 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1590 | clk_register_clkdev(clk, "audio1", NULL); | ||
1591 | clks[audio1] = clk; | ||
1592 | |||
1593 | /* audio2 */ | ||
1594 | clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk, | ||
1595 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1596 | CLK_SET_RATE_NO_REPARENT, | ||
1597 | clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, | ||
1598 | NULL); | ||
1599 | clks[audio2_mux] = clk; | ||
1600 | clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, | ||
1601 | clk_base + AUDIO_SYNC_CLK_I2S2, 4, | ||
1602 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1603 | clk_register_clkdev(clk, "audio2", NULL); | ||
1604 | clks[audio2] = clk; | ||
1605 | |||
1606 | /* audio3 */ | ||
1607 | clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk, | ||
1608 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1609 | CLK_SET_RATE_NO_REPARENT, | ||
1610 | clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, | ||
1611 | NULL); | ||
1612 | clks[audio3_mux] = clk; | ||
1613 | clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, | ||
1614 | clk_base + AUDIO_SYNC_CLK_I2S3, 4, | ||
1615 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1616 | clk_register_clkdev(clk, "audio3", NULL); | ||
1617 | clks[audio3] = clk; | ||
1618 | |||
1619 | /* audio4 */ | ||
1620 | clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk, | ||
1621 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1622 | CLK_SET_RATE_NO_REPARENT, | ||
1623 | clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, | ||
1624 | NULL); | ||
1625 | clks[audio4_mux] = clk; | ||
1626 | clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, | ||
1627 | clk_base + AUDIO_SYNC_CLK_I2S4, 4, | ||
1628 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1629 | clk_register_clkdev(clk, "audio4", NULL); | ||
1630 | clks[audio4] = clk; | ||
1631 | |||
1632 | /* spdif */ | ||
1633 | clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk, | ||
1634 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1635 | CLK_SET_RATE_NO_REPARENT, | ||
1636 | clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, | ||
1637 | NULL); | ||
1638 | clks[spdif_mux] = clk; | ||
1639 | clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, | ||
1640 | clk_base + AUDIO_SYNC_CLK_SPDIF, 4, | ||
1641 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1642 | clk_register_clkdev(clk, "spdif", NULL); | ||
1643 | clks[spdif] = clk; | ||
1644 | |||
1645 | /* audio0_2x */ | ||
1646 | clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0", | ||
1647 | CLK_SET_RATE_PARENT, 2, 1); | ||
1648 | clk = tegra_clk_register_divider("audio0_div", "audio0_doubler", | ||
1649 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1, | ||
1650 | 0, &clk_doubler_lock); | ||
1651 | clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", | ||
1652 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1653 | CLK_SET_RATE_PARENT, 113, &periph_v_regs, | ||
1654 | periph_clk_enb_refcnt); | ||
1655 | clk_register_clkdev(clk, "audio0_2x", NULL); | ||
1656 | clks[audio0_2x] = clk; | ||
1657 | |||
1658 | /* audio1_2x */ | ||
1659 | clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1", | ||
1660 | CLK_SET_RATE_PARENT, 2, 1); | ||
1661 | clk = tegra_clk_register_divider("audio1_div", "audio1_doubler", | ||
1662 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1, | ||
1663 | 0, &clk_doubler_lock); | ||
1664 | clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", | ||
1665 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1666 | CLK_SET_RATE_PARENT, 114, &periph_v_regs, | ||
1667 | periph_clk_enb_refcnt); | ||
1668 | clk_register_clkdev(clk, "audio1_2x", NULL); | ||
1669 | clks[audio1_2x] = clk; | ||
1670 | |||
1671 | /* audio2_2x */ | ||
1672 | clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2", | ||
1673 | CLK_SET_RATE_PARENT, 2, 1); | ||
1674 | clk = tegra_clk_register_divider("audio2_div", "audio2_doubler", | ||
1675 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1, | ||
1676 | 0, &clk_doubler_lock); | ||
1677 | clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", | ||
1678 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1679 | CLK_SET_RATE_PARENT, 115, &periph_v_regs, | ||
1680 | periph_clk_enb_refcnt); | ||
1681 | clk_register_clkdev(clk, "audio2_2x", NULL); | ||
1682 | clks[audio2_2x] = clk; | ||
1683 | |||
1684 | /* audio3_2x */ | ||
1685 | clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3", | ||
1686 | CLK_SET_RATE_PARENT, 2, 1); | ||
1687 | clk = tegra_clk_register_divider("audio3_div", "audio3_doubler", | ||
1688 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1, | ||
1689 | 0, &clk_doubler_lock); | ||
1690 | clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", | ||
1691 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1692 | CLK_SET_RATE_PARENT, 116, &periph_v_regs, | ||
1693 | periph_clk_enb_refcnt); | ||
1694 | clk_register_clkdev(clk, "audio3_2x", NULL); | ||
1695 | clks[audio3_2x] = clk; | ||
1696 | |||
1697 | /* audio4_2x */ | ||
1698 | clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4", | ||
1699 | CLK_SET_RATE_PARENT, 2, 1); | ||
1700 | clk = tegra_clk_register_divider("audio4_div", "audio4_doubler", | ||
1701 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1, | ||
1702 | 0, &clk_doubler_lock); | ||
1703 | clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", | ||
1704 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1705 | CLK_SET_RATE_PARENT, 117, &periph_v_regs, | ||
1706 | periph_clk_enb_refcnt); | ||
1707 | clk_register_clkdev(clk, "audio4_2x", NULL); | ||
1708 | clks[audio4_2x] = clk; | ||
1709 | |||
1710 | /* spdif_2x */ | ||
1711 | clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif", | ||
1712 | CLK_SET_RATE_PARENT, 2, 1); | ||
1713 | clk = tegra_clk_register_divider("spdif_div", "spdif_doubler", | ||
1714 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1, | ||
1715 | 0, &clk_doubler_lock); | ||
1716 | clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", | ||
1717 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1718 | CLK_SET_RATE_PARENT, 118, | ||
1719 | &periph_v_regs, periph_clk_enb_refcnt); | ||
1720 | clk_register_clkdev(clk, "spdif_2x", NULL); | ||
1721 | clks[spdif_2x] = clk; | ||
1722 | } | ||
1723 | |||
1724 | static void __init tegra114_pmc_clk_init(void __iomem *pmc_base) | ||
1725 | { | ||
1726 | struct clk *clk; | ||
1727 | |||
1728 | /* clk_out_1 */ | ||
1729 | clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents, | ||
1730 | ARRAY_SIZE(clk_out1_parents), | ||
1731 | CLK_SET_RATE_NO_REPARENT, | ||
1732 | pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0, | ||
1733 | &clk_out_lock); | ||
1734 | clks[clk_out_1_mux] = clk; | ||
1735 | clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, | ||
1736 | pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, | ||
1737 | &clk_out_lock); | ||
1738 | clk_register_clkdev(clk, "extern1", "clk_out_1"); | ||
1739 | clks[clk_out_1] = clk; | ||
1740 | |||
1741 | /* clk_out_2 */ | ||
1742 | clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, | ||
1743 | ARRAY_SIZE(clk_out2_parents), | ||
1744 | CLK_SET_RATE_NO_REPARENT, | ||
1745 | pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, | ||
1746 | &clk_out_lock); | ||
1747 | clks[clk_out_2_mux] = clk; | ||
1748 | clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, | ||
1749 | pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, | ||
1750 | &clk_out_lock); | ||
1751 | clk_register_clkdev(clk, "extern2", "clk_out_2"); | ||
1752 | clks[clk_out_2] = clk; | ||
1753 | |||
1754 | /* clk_out_3 */ | ||
1755 | clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, | ||
1756 | ARRAY_SIZE(clk_out3_parents), | ||
1757 | CLK_SET_RATE_NO_REPARENT, | ||
1758 | pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, | ||
1759 | &clk_out_lock); | ||
1760 | clks[clk_out_3_mux] = clk; | ||
1761 | clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, | ||
1762 | pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, | ||
1763 | &clk_out_lock); | ||
1764 | clk_register_clkdev(clk, "extern3", "clk_out_3"); | ||
1765 | clks[clk_out_3] = clk; | ||
1766 | |||
1767 | /* blink */ | ||
1768 | /* clear the blink timer register to directly output clk_32k */ | ||
1769 | writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); | ||
1770 | clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, | ||
1771 | pmc_base + PMC_DPD_PADS_ORIDE, | ||
1772 | PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); | ||
1773 | clk = clk_register_gate(NULL, "blink", "blink_override", 0, | ||
1774 | pmc_base + PMC_CTRL, | ||
1775 | PMC_CTRL_BLINK_ENB, 0, NULL); | ||
1776 | clk_register_clkdev(clk, "blink", NULL); | ||
1777 | clks[blink] = clk; | ||
1778 | |||
1779 | } | 1179 | } |
1780 | 1180 | ||
1781 | static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4", | 1181 | static __init void tegra114_periph_clk_init(void __iomem *clk_base, |
1782 | "pll_p", "pll_p_out2", "unused", | 1182 | void __iomem *pmc_base) |
1783 | "clk_32k", "pll_m_out1" }; | ||
1784 | |||
1785 | static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | ||
1786 | "pll_p", "pll_p_out4", "unused", | ||
1787 | "unused", "pll_x" }; | ||
1788 | |||
1789 | static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | ||
1790 | "pll_p", "pll_p_out4", "unused", | ||
1791 | "unused", "pll_x", "pll_x_out0" }; | ||
1792 | |||
1793 | static void __init tegra114_super_clk_init(void __iomem *clk_base) | ||
1794 | { | 1183 | { |
1795 | struct clk *clk; | 1184 | struct clk *clk; |
1185 | u32 val; | ||
1796 | 1186 | ||
1797 | /* CCLKG */ | 1187 | /* xusb_hs_src */ |
1798 | clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents, | 1188 | val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); |
1799 | ARRAY_SIZE(cclk_g_parents), | 1189 | val |= BIT(25); /* always select PLLU_60M */ |
1800 | CLK_SET_RATE_PARENT, | 1190 | writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); |
1801 | clk_base + CCLKG_BURST_POLICY, | ||
1802 | 0, 4, 0, 0, NULL); | ||
1803 | clk_register_clkdev(clk, "cclk_g", NULL); | ||
1804 | clks[cclk_g] = clk; | ||
1805 | |||
1806 | /* CCLKLP */ | ||
1807 | clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents, | ||
1808 | ARRAY_SIZE(cclk_lp_parents), | ||
1809 | CLK_SET_RATE_PARENT, | ||
1810 | clk_base + CCLKLP_BURST_POLICY, | ||
1811 | 0, 4, 8, 9, NULL); | ||
1812 | clk_register_clkdev(clk, "cclk_lp", NULL); | ||
1813 | clks[cclk_lp] = clk; | ||
1814 | |||
1815 | /* SCLK */ | ||
1816 | clk = tegra_clk_register_super_mux("sclk", sclk_parents, | ||
1817 | ARRAY_SIZE(sclk_parents), | ||
1818 | CLK_SET_RATE_PARENT, | ||
1819 | clk_base + SCLK_BURST_POLICY, | ||
1820 | 0, 4, 0, 0, NULL); | ||
1821 | clk_register_clkdev(clk, "sclk", NULL); | ||
1822 | clks[sclk] = clk; | ||
1823 | |||
1824 | /* HCLK */ | ||
1825 | clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, | ||
1826 | clk_base + SYSTEM_CLK_RATE, 4, 2, 0, | ||
1827 | &sysrate_lock); | ||
1828 | clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT | | ||
1829 | CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, | ||
1830 | 7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); | ||
1831 | clk_register_clkdev(clk, "hclk", NULL); | ||
1832 | clks[hclk] = clk; | ||
1833 | |||
1834 | /* PCLK */ | ||
1835 | clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, | ||
1836 | clk_base + SYSTEM_CLK_RATE, 0, 2, 0, | ||
1837 | &sysrate_lock); | ||
1838 | clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT | | ||
1839 | CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE, | ||
1840 | 3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock); | ||
1841 | clk_register_clkdev(clk, "pclk", NULL); | ||
1842 | clks[pclk] = clk; | ||
1843 | } | ||
1844 | |||
1845 | static struct tegra_periph_init_data tegra_periph_clk_list[] = { | ||
1846 | TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0), | ||
1847 | TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), | ||
1848 | TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), | ||
1849 | TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3), | ||
1850 | TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4), | ||
1851 | TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), | ||
1852 | TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), | ||
1853 | TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, &periph_l_regs, TEGRA_PERIPH_ON_APB, pwm), | ||
1854 | TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, &periph_w_regs, TEGRA_PERIPH_ON_APB, adx), | ||
1855 | TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, &periph_w_regs, TEGRA_PERIPH_ON_APB, amx), | ||
1856 | TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda), | ||
1857 | TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda2codec_2x), | ||
1858 | TEGRA_INIT_DATA_MUX("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), | ||
1859 | TEGRA_INIT_DATA_MUX("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), | ||
1860 | TEGRA_INIT_DATA_MUX("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), | ||
1861 | TEGRA_INIT_DATA_MUX("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), | ||
1862 | TEGRA_INIT_DATA_MUX("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5), | ||
1863 | TEGRA_INIT_DATA_MUX("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6), | ||
1864 | TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), | ||
1865 | TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), | ||
1866 | TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), | ||
1867 | TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), | ||
1868 | TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), | ||
1869 | TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), | ||
1870 | TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), | ||
1871 | TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), | ||
1872 | TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite, CLK_IGNORE_UNUSED), | ||
1873 | TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la), | ||
1874 | TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, &periph_u_regs, TEGRA_PERIPH_ON_APB, trace), | ||
1875 | TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), | ||
1876 | TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), | ||
1877 | TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), | ||
1878 | TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, i2c1), | ||
1879 | TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, i2c2), | ||
1880 | TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, i2c3), | ||
1881 | TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, i2c4), | ||
1882 | TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, i2c5), | ||
1883 | TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta), | ||
1884 | TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb), | ||
1885 | TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc), | ||
1886 | TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd), | ||
1887 | TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, gr_3d), | ||
1888 | TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr_2d), | ||
1889 | 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), | ||
1890 | TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), | ||
1891 | TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), | ||
1892 | 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), | ||
1893 | TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, tsec), | ||
1894 | TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), | ||
1895 | TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), | ||
1896 | TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, &periph_w_regs, 0, cilab), | ||
1897 | TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, &periph_w_regs, 0, cilcd), | ||
1898 | TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, &periph_w_regs, 0, cile), | ||
1899 | TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, &periph_w_regs, 0, dsialp), | ||
1900 | TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, &periph_w_regs, 0, dsiblp), | ||
1901 | TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor), | ||
1902 | TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon), | ||
1903 | TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1), | ||
1904 | TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2), | ||
1905 | TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3), | ||
1906 | TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), | ||
1907 | 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), | ||
1908 | TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect, CLK_IGNORE_UNUSED), | ||
1909 | 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), | ||
1910 | 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), | ||
1911 | 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), | ||
1912 | 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), | ||
1913 | 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), | ||
1914 | TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_fs_src), | ||
1915 | TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_ss_src), | ||
1916 | TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, &periph_u_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_dev_src), | ||
1917 | TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, TEGRA_PERIPH_ON_APB, d_audio), | ||
1918 | TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam0), | ||
1919 | TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam1), | ||
1920 | TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam2), | ||
1921 | }; | ||
1922 | |||
1923 | static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { | ||
1924 | TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, &periph_l_regs, 0, disp1), | ||
1925 | TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, &periph_l_regs, 0, disp2), | ||
1926 | }; | ||
1927 | 1191 | ||
1928 | static __init void tegra114_periph_clk_init(void __iomem *clk_base) | 1192 | clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, |
1929 | { | 1193 | 1, 1); |
1930 | struct tegra_periph_init_data *data; | 1194 | clks[TEGRA114_CLK_XUSB_HS_SRC] = clk; |
1931 | struct clk *clk; | ||
1932 | int i; | ||
1933 | u32 val; | ||
1934 | 1195 | ||
1935 | /* apbdma */ | 1196 | /* dsia mux */ |
1936 | clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, | ||
1937 | 0, 34, &periph_h_regs, | ||
1938 | periph_clk_enb_refcnt); | ||
1939 | clks[apbdma] = clk; | ||
1940 | |||
1941 | /* rtc */ | ||
1942 | clk = tegra_clk_register_periph_gate("rtc", "clk_32k", | ||
1943 | TEGRA_PERIPH_ON_APB | | ||
1944 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1945 | 0, 4, &periph_l_regs, | ||
1946 | periph_clk_enb_refcnt); | ||
1947 | clk_register_clkdev(clk, NULL, "rtc-tegra"); | ||
1948 | clks[rtc] = clk; | ||
1949 | |||
1950 | /* kbc */ | ||
1951 | clk = tegra_clk_register_periph_gate("kbc", "clk_32k", | ||
1952 | TEGRA_PERIPH_ON_APB | | ||
1953 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1954 | 0, 36, &periph_h_regs, | ||
1955 | periph_clk_enb_refcnt); | ||
1956 | clks[kbc] = clk; | ||
1957 | |||
1958 | /* timer */ | ||
1959 | clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, | ||
1960 | 0, 5, &periph_l_regs, | ||
1961 | periph_clk_enb_refcnt); | ||
1962 | clk_register_clkdev(clk, NULL, "timer"); | ||
1963 | clks[timer] = clk; | ||
1964 | |||
1965 | /* kfuse */ | ||
1966 | clk = tegra_clk_register_periph_gate("kfuse", "clk_m", | ||
1967 | TEGRA_PERIPH_ON_APB, clk_base, 0, 40, | ||
1968 | &periph_h_regs, periph_clk_enb_refcnt); | ||
1969 | clks[kfuse] = clk; | ||
1970 | |||
1971 | /* fuse */ | ||
1972 | clk = tegra_clk_register_periph_gate("fuse", "clk_m", | ||
1973 | TEGRA_PERIPH_ON_APB, clk_base, 0, 39, | ||
1974 | &periph_h_regs, periph_clk_enb_refcnt); | ||
1975 | clks[fuse] = clk; | ||
1976 | |||
1977 | /* fuse_burn */ | ||
1978 | clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", | ||
1979 | TEGRA_PERIPH_ON_APB, clk_base, 0, 39, | ||
1980 | &periph_h_regs, periph_clk_enb_refcnt); | ||
1981 | clks[fuse_burn] = clk; | ||
1982 | |||
1983 | /* apbif */ | ||
1984 | clk = tegra_clk_register_periph_gate("apbif", "clk_m", | ||
1985 | TEGRA_PERIPH_ON_APB, clk_base, 0, 107, | ||
1986 | &periph_v_regs, periph_clk_enb_refcnt); | ||
1987 | clks[apbif] = clk; | ||
1988 | |||
1989 | /* hda2hdmi */ | ||
1990 | clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", | ||
1991 | TEGRA_PERIPH_ON_APB, clk_base, 0, 128, | ||
1992 | &periph_w_regs, periph_clk_enb_refcnt); | ||
1993 | clks[hda2hdmi] = clk; | ||
1994 | |||
1995 | /* vcp */ | ||
1996 | clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, | ||
1997 | 29, &periph_l_regs, | ||
1998 | periph_clk_enb_refcnt); | ||
1999 | clks[vcp] = clk; | ||
2000 | |||
2001 | /* bsea */ | ||
2002 | clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, | ||
2003 | 0, 62, &periph_h_regs, | ||
2004 | periph_clk_enb_refcnt); | ||
2005 | clks[bsea] = clk; | ||
2006 | |||
2007 | /* bsev */ | ||
2008 | clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, | ||
2009 | 0, 63, &periph_h_regs, | ||
2010 | periph_clk_enb_refcnt); | ||
2011 | clks[bsev] = clk; | ||
2012 | |||
2013 | /* mipi-cal */ | ||
2014 | clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base, | ||
2015 | 0, 56, &periph_h_regs, | ||
2016 | periph_clk_enb_refcnt); | ||
2017 | clks[mipi_cal] = clk; | ||
2018 | |||
2019 | /* usbd */ | ||
2020 | clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, | ||
2021 | 0, 22, &periph_l_regs, | ||
2022 | periph_clk_enb_refcnt); | ||
2023 | clks[usbd] = clk; | ||
2024 | |||
2025 | /* usb2 */ | ||
2026 | clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, | ||
2027 | 0, 58, &periph_h_regs, | ||
2028 | periph_clk_enb_refcnt); | ||
2029 | clks[usb2] = clk; | ||
2030 | |||
2031 | /* usb3 */ | ||
2032 | clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, | ||
2033 | 0, 59, &periph_h_regs, | ||
2034 | periph_clk_enb_refcnt); | ||
2035 | clks[usb3] = clk; | ||
2036 | |||
2037 | /* csi */ | ||
2038 | clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, | ||
2039 | 0, 52, &periph_h_regs, | ||
2040 | periph_clk_enb_refcnt); | ||
2041 | clks[csi] = clk; | ||
2042 | |||
2043 | /* isp */ | ||
2044 | clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, | ||
2045 | 23, &periph_l_regs, | ||
2046 | periph_clk_enb_refcnt); | ||
2047 | clks[isp] = clk; | ||
2048 | |||
2049 | /* csus */ | ||
2050 | clk = tegra_clk_register_periph_gate("csus", "clk_m", | ||
2051 | TEGRA_PERIPH_NO_RESET, clk_base, 0, 92, | ||
2052 | &periph_u_regs, periph_clk_enb_refcnt); | ||
2053 | clks[csus] = clk; | ||
2054 | |||
2055 | /* dds */ | ||
2056 | clk = tegra_clk_register_periph_gate("dds", "clk_m", | ||
2057 | TEGRA_PERIPH_ON_APB, clk_base, 0, 150, | ||
2058 | &periph_w_regs, periph_clk_enb_refcnt); | ||
2059 | clks[dds] = clk; | ||
2060 | |||
2061 | /* dp2 */ | ||
2062 | clk = tegra_clk_register_periph_gate("dp2", "clk_m", | ||
2063 | TEGRA_PERIPH_ON_APB, clk_base, 0, 152, | ||
2064 | &periph_w_regs, periph_clk_enb_refcnt); | ||
2065 | clks[dp2] = clk; | ||
2066 | |||
2067 | /* dtv */ | ||
2068 | clk = tegra_clk_register_periph_gate("dtv", "clk_m", | ||
2069 | TEGRA_PERIPH_ON_APB, clk_base, 0, 79, | ||
2070 | &periph_u_regs, periph_clk_enb_refcnt); | ||
2071 | clks[dtv] = clk; | ||
2072 | |||
2073 | /* dsia */ | ||
2074 | clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, | 1197 | clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, |
2075 | ARRAY_SIZE(mux_plld_out0_plld2_out0), | 1198 | ARRAY_SIZE(mux_plld_out0_plld2_out0), |
2076 | CLK_SET_RATE_NO_REPARENT, | 1199 | CLK_SET_RATE_NO_REPARENT, |
2077 | clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); | 1200 | clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); |
2078 | clks[dsia_mux] = clk; | 1201 | clks[TEGRA114_CLK_DSIA_MUX] = clk; |
2079 | clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base, | ||
2080 | 0, 48, &periph_h_regs, | ||
2081 | periph_clk_enb_refcnt); | ||
2082 | clks[dsia] = clk; | ||
2083 | 1202 | ||
2084 | /* dsib */ | 1203 | /* dsib mux */ |
2085 | clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, | 1204 | clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, |
2086 | ARRAY_SIZE(mux_plld_out0_plld2_out0), | 1205 | ARRAY_SIZE(mux_plld_out0_plld2_out0), |
2087 | CLK_SET_RATE_NO_REPARENT, | 1206 | CLK_SET_RATE_NO_REPARENT, |
2088 | clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); | 1207 | clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); |
2089 | clks[dsib_mux] = clk; | 1208 | clks[TEGRA114_CLK_DSIB_MUX] = clk; |
2090 | clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base, | ||
2091 | 0, 82, &periph_u_regs, | ||
2092 | periph_clk_enb_refcnt); | ||
2093 | clks[dsib] = clk; | ||
2094 | 1209 | ||
2095 | /* xusb_hs_src */ | 1210 | /* emc mux */ |
2096 | val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); | ||
2097 | val |= BIT(25); /* always select PLLU_60M */ | ||
2098 | writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); | ||
2099 | |||
2100 | clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, | ||
2101 | 1, 1); | ||
2102 | clks[xusb_hs_src] = clk; | ||
2103 | |||
2104 | /* xusb_host */ | ||
2105 | clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0, | ||
2106 | clk_base, 0, 89, &periph_u_regs, | ||
2107 | periph_clk_enb_refcnt); | ||
2108 | clks[xusb_host] = clk; | ||
2109 | |||
2110 | /* xusb_ss */ | ||
2111 | clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0, | ||
2112 | clk_base, 0, 156, &periph_w_regs, | ||
2113 | periph_clk_enb_refcnt); | ||
2114 | clks[xusb_host] = clk; | ||
2115 | |||
2116 | /* xusb_dev */ | ||
2117 | clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0, | ||
2118 | clk_base, 0, 95, &periph_u_regs, | ||
2119 | periph_clk_enb_refcnt); | ||
2120 | clks[xusb_dev] = clk; | ||
2121 | |||
2122 | /* emc */ | ||
2123 | clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, | 1211 | clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, |
2124 | ARRAY_SIZE(mux_pllmcp_clkm), | 1212 | ARRAY_SIZE(mux_pllmcp_clkm), |
2125 | CLK_SET_RATE_NO_REPARENT, | 1213 | CLK_SET_RATE_NO_REPARENT, |
2126 | clk_base + CLK_SOURCE_EMC, | 1214 | clk_base + CLK_SOURCE_EMC, |
2127 | 29, 3, 0, NULL); | 1215 | 29, 3, 0, NULL); |
2128 | clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, | ||
2129 | CLK_IGNORE_UNUSED, 57, &periph_h_regs, | ||
2130 | periph_clk_enb_refcnt); | ||
2131 | clks[emc] = clk; | ||
2132 | |||
2133 | for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { | ||
2134 | data = &tegra_periph_clk_list[i]; | ||
2135 | clk = tegra_clk_register_periph(data->name, data->parent_names, | ||
2136 | data->num_parents, &data->periph, | ||
2137 | clk_base, data->offset, data->flags); | ||
2138 | clks[data->clk_id] = clk; | ||
2139 | } | ||
2140 | 1216 | ||
2141 | for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { | 1217 | tegra_periph_clk_init(clk_base, pmc_base, tegra114_clks, |
2142 | data = &tegra_periph_nodiv_clk_list[i]; | 1218 | &pll_p_params); |
2143 | clk = tegra_clk_register_periph_nodiv(data->name, | ||
2144 | data->parent_names, data->num_parents, | ||
2145 | &data->periph, clk_base, data->offset); | ||
2146 | clks[data->clk_id] = clk; | ||
2147 | } | ||
2148 | } | 1219 | } |
2149 | 1220 | ||
2150 | /* Tegra114 CPU clock and reset control functions */ | 1221 | /* Tegra114 CPU clock and reset control functions */ |
@@ -2207,28 +1278,37 @@ static const struct of_device_id pmc_match[] __initconst = { | |||
2207 | * breaks | 1278 | * breaks |
2208 | */ | 1279 | */ |
2209 | static struct tegra_clk_init_table init_table[] __initdata = { | 1280 | static struct tegra_clk_init_table init_table[] __initdata = { |
2210 | {uarta, pll_p, 408000000, 0}, | 1281 | {TEGRA114_CLK_UARTA, TEGRA114_CLK_PLL_P, 408000000, 0}, |
2211 | {uartb, pll_p, 408000000, 0}, | 1282 | {TEGRA114_CLK_UARTB, TEGRA114_CLK_PLL_P, 408000000, 0}, |
2212 | {uartc, pll_p, 408000000, 0}, | 1283 | {TEGRA114_CLK_UARTC, TEGRA114_CLK_PLL_P, 408000000, 0}, |
2213 | {uartd, pll_p, 408000000, 0}, | 1284 | {TEGRA114_CLK_UARTD, TEGRA114_CLK_PLL_P, 408000000, 0}, |
2214 | {pll_a, clk_max, 564480000, 1}, | 1285 | {TEGRA114_CLK_PLL_A, TEGRA114_CLK_CLK_MAX, 564480000, 1}, |
2215 | {pll_a_out0, clk_max, 11289600, 1}, | 1286 | {TEGRA114_CLK_PLL_A_OUT0, TEGRA114_CLK_CLK_MAX, 11289600, 1}, |
2216 | {extern1, pll_a_out0, 0, 1}, | 1287 | {TEGRA114_CLK_EXTERN1, TEGRA114_CLK_PLL_A_OUT0, 0, 1}, |
2217 | {clk_out_1_mux, extern1, 0, 1}, | 1288 | {TEGRA114_CLK_CLK_OUT_1_MUX, TEGRA114_CLK_EXTERN1, 0, 1}, |
2218 | {clk_out_1, clk_max, 0, 1}, | 1289 | {TEGRA114_CLK_CLK_OUT_1, TEGRA114_CLK_CLK_MAX, 0, 1}, |
2219 | {i2s0, pll_a_out0, 11289600, 0}, | 1290 | {TEGRA114_CLK_I2S0, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, |
2220 | {i2s1, pll_a_out0, 11289600, 0}, | 1291 | {TEGRA114_CLK_I2S1, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, |
2221 | {i2s2, pll_a_out0, 11289600, 0}, | 1292 | {TEGRA114_CLK_I2S2, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, |
2222 | {i2s3, pll_a_out0, 11289600, 0}, | 1293 | {TEGRA114_CLK_I2S3, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, |
2223 | {i2s4, pll_a_out0, 11289600, 0}, | 1294 | {TEGRA114_CLK_I2S4, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0}, |
2224 | {dfll_soc, pll_p, 51000000, 1}, | 1295 | {TEGRA114_CLK_HOST1X, TEGRA114_CLK_PLL_P, 136000000, 0}, |
2225 | {dfll_ref, pll_p, 51000000, 1}, | 1296 | {TEGRA114_CLK_DFLL_SOC, TEGRA114_CLK_PLL_P, 51000000, 1}, |
2226 | {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ | 1297 | {TEGRA114_CLK_DFLL_REF, TEGRA114_CLK_PLL_P, 51000000, 1}, |
1298 | {TEGRA114_CLK_DISP1, TEGRA114_CLK_PLL_P, 0, 0}, | ||
1299 | {TEGRA114_CLK_DISP2, TEGRA114_CLK_PLL_P, 0, 0}, | ||
1300 | {TEGRA114_CLK_GR2D, TEGRA114_CLK_PLL_C2, 300000000, 0}, | ||
1301 | {TEGRA114_CLK_GR3D, TEGRA114_CLK_PLL_C2, 300000000, 0}, | ||
1302 | {TEGRA114_CLK_DSIALP, TEGRA114_CLK_PLL_P, 68000000, 0}, | ||
1303 | {TEGRA114_CLK_DSIBLP, TEGRA114_CLK_PLL_P, 68000000, 0}, | ||
1304 | |||
1305 | /* This MUST be the last entry. */ | ||
1306 | {TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0}, | ||
2227 | }; | 1307 | }; |
2228 | 1308 | ||
2229 | static void __init tegra114_clock_apply_init_table(void) | 1309 | static void __init tegra114_clock_apply_init_table(void) |
2230 | { | 1310 | { |
2231 | tegra_init_from_table(init_table, clks, clk_max); | 1311 | tegra_init_from_table(init_table, clks, TEGRA114_CLK_CLK_MAX); |
2232 | } | 1312 | } |
2233 | 1313 | ||
2234 | 1314 | ||
@@ -2359,7 +1439,6 @@ EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset); | |||
2359 | static void __init tegra114_clock_init(struct device_node *np) | 1439 | static void __init tegra114_clock_init(struct device_node *np) |
2360 | { | 1440 | { |
2361 | struct device_node *node; | 1441 | struct device_node *node; |
2362 | int i; | ||
2363 | 1442 | ||
2364 | clk_base = of_iomap(np, 0); | 1443 | clk_base = of_iomap(np, 0); |
2365 | if (!clk_base) { | 1444 | if (!clk_base) { |
@@ -2381,29 +1460,24 @@ static void __init tegra114_clock_init(struct device_node *np) | |||
2381 | return; | 1460 | return; |
2382 | } | 1461 | } |
2383 | 1462 | ||
1463 | clks = tegra_clk_init(clk_base, TEGRA114_CLK_CLK_MAX, | ||
1464 | TEGRA114_CLK_PERIPH_BANKS); | ||
1465 | if (!clks) | ||
1466 | return; | ||
1467 | |||
2384 | if (tegra114_osc_clk_init(clk_base) < 0) | 1468 | if (tegra114_osc_clk_init(clk_base) < 0) |
2385 | return; | 1469 | return; |
2386 | 1470 | ||
2387 | tegra114_fixed_clk_init(clk_base); | 1471 | tegra114_fixed_clk_init(clk_base); |
2388 | tegra114_pll_init(clk_base, pmc_base); | 1472 | tegra114_pll_init(clk_base, pmc_base); |
2389 | tegra114_periph_clk_init(clk_base); | 1473 | tegra114_periph_clk_init(clk_base, pmc_base); |
2390 | tegra114_audio_clk_init(clk_base); | 1474 | tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params); |
2391 | tegra114_pmc_clk_init(pmc_base); | 1475 | tegra_pmc_clk_init(pmc_base, tegra114_clks); |
2392 | tegra114_super_clk_init(clk_base); | 1476 | tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks, |
2393 | 1477 | &pll_x_params); | |
2394 | for (i = 0; i < ARRAY_SIZE(clks); i++) { | 1478 | |
2395 | if (IS_ERR(clks[i])) { | 1479 | tegra_add_of_provider(np); |
2396 | pr_err | 1480 | tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); |
2397 | ("Tegra114 clk %d: register failed with %ld\n", | ||
2398 | i, PTR_ERR(clks[i])); | ||
2399 | } | ||
2400 | if (!clks[i]) | ||
2401 | clks[i] = ERR_PTR(-EINVAL); | ||
2402 | } | ||
2403 | |||
2404 | clk_data.clks = clks; | ||
2405 | clk_data.clk_num = ARRAY_SIZE(clks); | ||
2406 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
2407 | 1481 | ||
2408 | tegra_clk_apply_init_table = tegra114_clock_apply_init_table; | 1482 | tegra_clk_apply_init_table = tegra114_clock_apply_init_table; |
2409 | 1483 | ||
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c new file mode 100644 index 000000000000..aff86b5bc745 --- /dev/null +++ b/drivers/clk/tegra/clk-tegra124.c | |||
@@ -0,0 +1,1424 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012, 2013, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/clkdev.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/of_address.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/export.h> | ||
25 | #include <linux/clk/tegra.h> | ||
26 | #include <dt-bindings/clock/tegra124-car.h> | ||
27 | |||
28 | #include "clk.h" | ||
29 | #include "clk-id.h" | ||
30 | |||
31 | #define CLK_SOURCE_CSITE 0x1d4 | ||
32 | #define CLK_SOURCE_EMC 0x19c | ||
33 | #define CLK_SOURCE_XUSB_SS_SRC 0x610 | ||
34 | |||
35 | #define PLLC_BASE 0x80 | ||
36 | #define PLLC_OUT 0x84 | ||
37 | #define PLLC_MISC2 0x88 | ||
38 | #define PLLC_MISC 0x8c | ||
39 | #define PLLC2_BASE 0x4e8 | ||
40 | #define PLLC2_MISC 0x4ec | ||
41 | #define PLLC3_BASE 0x4fc | ||
42 | #define PLLC3_MISC 0x500 | ||
43 | #define PLLM_BASE 0x90 | ||
44 | #define PLLM_OUT 0x94 | ||
45 | #define PLLM_MISC 0x9c | ||
46 | #define PLLP_BASE 0xa0 | ||
47 | #define PLLP_MISC 0xac | ||
48 | #define PLLA_BASE 0xb0 | ||
49 | #define PLLA_MISC 0xbc | ||
50 | #define PLLD_BASE 0xd0 | ||
51 | #define PLLD_MISC 0xdc | ||
52 | #define PLLU_BASE 0xc0 | ||
53 | #define PLLU_MISC 0xcc | ||
54 | #define PLLX_BASE 0xe0 | ||
55 | #define PLLX_MISC 0xe4 | ||
56 | #define PLLX_MISC2 0x514 | ||
57 | #define PLLX_MISC3 0x518 | ||
58 | #define PLLE_BASE 0xe8 | ||
59 | #define PLLE_MISC 0xec | ||
60 | #define PLLD2_BASE 0x4b8 | ||
61 | #define PLLD2_MISC 0x4bc | ||
62 | #define PLLE_AUX 0x48c | ||
63 | #define PLLRE_BASE 0x4c4 | ||
64 | #define PLLRE_MISC 0x4c8 | ||
65 | #define PLLDP_BASE 0x590 | ||
66 | #define PLLDP_MISC 0x594 | ||
67 | #define PLLC4_BASE 0x5a4 | ||
68 | #define PLLC4_MISC 0x5a8 | ||
69 | |||
70 | #define PLLC_IDDQ_BIT 26 | ||
71 | #define PLLRE_IDDQ_BIT 16 | ||
72 | #define PLLSS_IDDQ_BIT 19 | ||
73 | |||
74 | #define PLL_BASE_LOCK BIT(27) | ||
75 | #define PLLE_MISC_LOCK BIT(11) | ||
76 | #define PLLRE_MISC_LOCK BIT(24) | ||
77 | |||
78 | #define PLL_MISC_LOCK_ENABLE 18 | ||
79 | #define PLLC_MISC_LOCK_ENABLE 24 | ||
80 | #define PLLDU_MISC_LOCK_ENABLE 22 | ||
81 | #define PLLE_MISC_LOCK_ENABLE 9 | ||
82 | #define PLLRE_MISC_LOCK_ENABLE 30 | ||
83 | #define PLLSS_MISC_LOCK_ENABLE 30 | ||
84 | |||
85 | #define PLLXC_SW_MAX_P 6 | ||
86 | |||
87 | #define PMC_PLLM_WB0_OVERRIDE 0x1dc | ||
88 | #define PMC_PLLM_WB0_OVERRIDE_2 0x2b0 | ||
89 | |||
90 | #define UTMIP_PLL_CFG2 0x488 | ||
91 | #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) | ||
92 | #define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) | ||
93 | #define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0) | ||
94 | #define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2) | ||
95 | #define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4) | ||
96 | |||
97 | #define UTMIP_PLL_CFG1 0x484 | ||
98 | #define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 6) | ||
99 | #define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) | ||
100 | #define UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP BIT(17) | ||
101 | #define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16) | ||
102 | #define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP BIT(15) | ||
103 | #define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14) | ||
104 | #define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12) | ||
105 | |||
106 | #define UTMIPLL_HW_PWRDN_CFG0 0x52c | ||
107 | #define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25) | ||
108 | #define UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24) | ||
109 | #define UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET BIT(6) | ||
110 | #define UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE BIT(5) | ||
111 | #define UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL BIT(4) | ||
112 | #define UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2) | ||
113 | #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1) | ||
114 | #define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0) | ||
115 | |||
116 | /* Tegra CPU clock and reset control regs */ | ||
117 | #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 | ||
118 | |||
119 | #ifdef CONFIG_PM_SLEEP | ||
120 | static struct cpu_clk_suspend_context { | ||
121 | u32 clk_csite_src; | ||
122 | } tegra124_cpu_clk_sctx; | ||
123 | #endif | ||
124 | |||
125 | static void __iomem *clk_base; | ||
126 | static void __iomem *pmc_base; | ||
127 | |||
128 | static unsigned long osc_freq; | ||
129 | static unsigned long pll_ref_freq; | ||
130 | |||
131 | static DEFINE_SPINLOCK(pll_d_lock); | ||
132 | static DEFINE_SPINLOCK(pll_d2_lock); | ||
133 | static DEFINE_SPINLOCK(pll_e_lock); | ||
134 | static DEFINE_SPINLOCK(pll_re_lock); | ||
135 | static DEFINE_SPINLOCK(pll_u_lock); | ||
136 | |||
137 | /* possible OSC frequencies in Hz */ | ||
138 | static unsigned long tegra124_input_freq[] = { | ||
139 | [0] = 13000000, | ||
140 | [1] = 16800000, | ||
141 | [4] = 19200000, | ||
142 | [5] = 38400000, | ||
143 | [8] = 12000000, | ||
144 | [9] = 48000000, | ||
145 | [12] = 260000000, | ||
146 | }; | ||
147 | |||
148 | static const char *mux_plld_out0_plld2_out0[] = { | ||
149 | "pll_d_out0", "pll_d2_out0", | ||
150 | }; | ||
151 | #define mux_plld_out0_plld2_out0_idx NULL | ||
152 | |||
153 | static const char *mux_pllmcp_clkm[] = { | ||
154 | "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_c2", "pll_c3", | ||
155 | }; | ||
156 | #define mux_pllmcp_clkm_idx NULL | ||
157 | |||
158 | static struct div_nmp pllxc_nmp = { | ||
159 | .divm_shift = 0, | ||
160 | .divm_width = 8, | ||
161 | .divn_shift = 8, | ||
162 | .divn_width = 8, | ||
163 | .divp_shift = 20, | ||
164 | .divp_width = 4, | ||
165 | }; | ||
166 | |||
167 | static struct pdiv_map pllxc_p[] = { | ||
168 | { .pdiv = 1, .hw_val = 0 }, | ||
169 | { .pdiv = 2, .hw_val = 1 }, | ||
170 | { .pdiv = 3, .hw_val = 2 }, | ||
171 | { .pdiv = 4, .hw_val = 3 }, | ||
172 | { .pdiv = 5, .hw_val = 4 }, | ||
173 | { .pdiv = 6, .hw_val = 5 }, | ||
174 | { .pdiv = 8, .hw_val = 6 }, | ||
175 | { .pdiv = 10, .hw_val = 7 }, | ||
176 | { .pdiv = 12, .hw_val = 8 }, | ||
177 | { .pdiv = 16, .hw_val = 9 }, | ||
178 | { .pdiv = 12, .hw_val = 10 }, | ||
179 | { .pdiv = 16, .hw_val = 11 }, | ||
180 | { .pdiv = 20, .hw_val = 12 }, | ||
181 | { .pdiv = 24, .hw_val = 13 }, | ||
182 | { .pdiv = 32, .hw_val = 14 }, | ||
183 | { .pdiv = 0, .hw_val = 0 }, | ||
184 | }; | ||
185 | |||
186 | static struct tegra_clk_pll_freq_table pll_x_freq_table[] = { | ||
187 | /* 1 GHz */ | ||
188 | {12000000, 1000000000, 83, 0, 1}, /* actual: 996.0 MHz */ | ||
189 | {13000000, 1000000000, 76, 0, 1}, /* actual: 988.0 MHz */ | ||
190 | {16800000, 1000000000, 59, 0, 1}, /* actual: 991.2 MHz */ | ||
191 | {19200000, 1000000000, 52, 0, 1}, /* actual: 998.4 MHz */ | ||
192 | {26000000, 1000000000, 76, 1, 1}, /* actual: 988.0 MHz */ | ||
193 | {0, 0, 0, 0, 0, 0}, | ||
194 | }; | ||
195 | |||
196 | static struct tegra_clk_pll_params pll_x_params = { | ||
197 | .input_min = 12000000, | ||
198 | .input_max = 800000000, | ||
199 | .cf_min = 12000000, | ||
200 | .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ | ||
201 | .vco_min = 700000000, | ||
202 | .vco_max = 3000000000UL, | ||
203 | .base_reg = PLLX_BASE, | ||
204 | .misc_reg = PLLX_MISC, | ||
205 | .lock_mask = PLL_BASE_LOCK, | ||
206 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
207 | .lock_delay = 300, | ||
208 | .iddq_reg = PLLX_MISC3, | ||
209 | .iddq_bit_idx = 3, | ||
210 | .max_p = 6, | ||
211 | .dyn_ramp_reg = PLLX_MISC2, | ||
212 | .stepa_shift = 16, | ||
213 | .stepb_shift = 24, | ||
214 | .pdiv_tohw = pllxc_p, | ||
215 | .div_nmp = &pllxc_nmp, | ||
216 | .freq_table = pll_x_freq_table, | ||
217 | .flags = TEGRA_PLL_USE_LOCK, | ||
218 | }; | ||
219 | |||
220 | static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { | ||
221 | { 12000000, 624000000, 104, 1, 2}, | ||
222 | { 12000000, 600000000, 100, 1, 2}, | ||
223 | { 13000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ | ||
224 | { 16800000, 600000000, 71, 1, 2}, /* actual: 596.4 MHz */ | ||
225 | { 19200000, 600000000, 62, 1, 2}, /* actual: 595.2 MHz */ | ||
226 | { 26000000, 600000000, 92, 2, 2}, /* actual: 598.0 MHz */ | ||
227 | { 0, 0, 0, 0, 0, 0 }, | ||
228 | }; | ||
229 | |||
230 | static struct tegra_clk_pll_params pll_c_params = { | ||
231 | .input_min = 12000000, | ||
232 | .input_max = 800000000, | ||
233 | .cf_min = 12000000, | ||
234 | .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ | ||
235 | .vco_min = 600000000, | ||
236 | .vco_max = 1400000000, | ||
237 | .base_reg = PLLC_BASE, | ||
238 | .misc_reg = PLLC_MISC, | ||
239 | .lock_mask = PLL_BASE_LOCK, | ||
240 | .lock_enable_bit_idx = PLLC_MISC_LOCK_ENABLE, | ||
241 | .lock_delay = 300, | ||
242 | .iddq_reg = PLLC_MISC, | ||
243 | .iddq_bit_idx = PLLC_IDDQ_BIT, | ||
244 | .max_p = PLLXC_SW_MAX_P, | ||
245 | .dyn_ramp_reg = PLLC_MISC2, | ||
246 | .stepa_shift = 17, | ||
247 | .stepb_shift = 9, | ||
248 | .pdiv_tohw = pllxc_p, | ||
249 | .div_nmp = &pllxc_nmp, | ||
250 | .freq_table = pll_c_freq_table, | ||
251 | .flags = TEGRA_PLL_USE_LOCK, | ||
252 | }; | ||
253 | |||
254 | static struct div_nmp pllcx_nmp = { | ||
255 | .divm_shift = 0, | ||
256 | .divm_width = 2, | ||
257 | .divn_shift = 8, | ||
258 | .divn_width = 8, | ||
259 | .divp_shift = 20, | ||
260 | .divp_width = 3, | ||
261 | }; | ||
262 | |||
263 | static struct pdiv_map pllc_p[] = { | ||
264 | { .pdiv = 1, .hw_val = 0 }, | ||
265 | { .pdiv = 2, .hw_val = 1 }, | ||
266 | { .pdiv = 3, .hw_val = 2 }, | ||
267 | { .pdiv = 4, .hw_val = 3 }, | ||
268 | { .pdiv = 6, .hw_val = 4 }, | ||
269 | { .pdiv = 8, .hw_val = 5 }, | ||
270 | { .pdiv = 12, .hw_val = 6 }, | ||
271 | { .pdiv = 16, .hw_val = 7 }, | ||
272 | { .pdiv = 0, .hw_val = 0 }, | ||
273 | }; | ||
274 | |||
275 | static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = { | ||
276 | {12000000, 600000000, 100, 1, 2}, | ||
277 | {13000000, 600000000, 92, 1, 2}, /* actual: 598.0 MHz */ | ||
278 | {16800000, 600000000, 71, 1, 2}, /* actual: 596.4 MHz */ | ||
279 | {19200000, 600000000, 62, 1, 2}, /* actual: 595.2 MHz */ | ||
280 | {26000000, 600000000, 92, 2, 2}, /* actual: 598.0 MHz */ | ||
281 | {0, 0, 0, 0, 0, 0}, | ||
282 | }; | ||
283 | |||
284 | static struct tegra_clk_pll_params pll_c2_params = { | ||
285 | .input_min = 12000000, | ||
286 | .input_max = 48000000, | ||
287 | .cf_min = 12000000, | ||
288 | .cf_max = 19200000, | ||
289 | .vco_min = 600000000, | ||
290 | .vco_max = 1200000000, | ||
291 | .base_reg = PLLC2_BASE, | ||
292 | .misc_reg = PLLC2_MISC, | ||
293 | .lock_mask = PLL_BASE_LOCK, | ||
294 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
295 | .lock_delay = 300, | ||
296 | .pdiv_tohw = pllc_p, | ||
297 | .div_nmp = &pllcx_nmp, | ||
298 | .max_p = 7, | ||
299 | .ext_misc_reg[0] = 0x4f0, | ||
300 | .ext_misc_reg[1] = 0x4f4, | ||
301 | .ext_misc_reg[2] = 0x4f8, | ||
302 | .freq_table = pll_cx_freq_table, | ||
303 | .flags = TEGRA_PLL_USE_LOCK, | ||
304 | }; | ||
305 | |||
306 | static struct tegra_clk_pll_params pll_c3_params = { | ||
307 | .input_min = 12000000, | ||
308 | .input_max = 48000000, | ||
309 | .cf_min = 12000000, | ||
310 | .cf_max = 19200000, | ||
311 | .vco_min = 600000000, | ||
312 | .vco_max = 1200000000, | ||
313 | .base_reg = PLLC3_BASE, | ||
314 | .misc_reg = PLLC3_MISC, | ||
315 | .lock_mask = PLL_BASE_LOCK, | ||
316 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
317 | .lock_delay = 300, | ||
318 | .pdiv_tohw = pllc_p, | ||
319 | .div_nmp = &pllcx_nmp, | ||
320 | .max_p = 7, | ||
321 | .ext_misc_reg[0] = 0x504, | ||
322 | .ext_misc_reg[1] = 0x508, | ||
323 | .ext_misc_reg[2] = 0x50c, | ||
324 | .freq_table = pll_cx_freq_table, | ||
325 | .flags = TEGRA_PLL_USE_LOCK, | ||
326 | }; | ||
327 | |||
328 | static struct div_nmp pllss_nmp = { | ||
329 | .divm_shift = 0, | ||
330 | .divm_width = 8, | ||
331 | .divn_shift = 8, | ||
332 | .divn_width = 8, | ||
333 | .divp_shift = 20, | ||
334 | .divp_width = 4, | ||
335 | }; | ||
336 | |||
337 | static struct pdiv_map pll12g_ssd_esd_p[] = { | ||
338 | { .pdiv = 1, .hw_val = 0 }, | ||
339 | { .pdiv = 2, .hw_val = 1 }, | ||
340 | { .pdiv = 3, .hw_val = 2 }, | ||
341 | { .pdiv = 4, .hw_val = 3 }, | ||
342 | { .pdiv = 5, .hw_val = 4 }, | ||
343 | { .pdiv = 6, .hw_val = 5 }, | ||
344 | { .pdiv = 8, .hw_val = 6 }, | ||
345 | { .pdiv = 10, .hw_val = 7 }, | ||
346 | { .pdiv = 12, .hw_val = 8 }, | ||
347 | { .pdiv = 16, .hw_val = 9 }, | ||
348 | { .pdiv = 12, .hw_val = 10 }, | ||
349 | { .pdiv = 16, .hw_val = 11 }, | ||
350 | { .pdiv = 20, .hw_val = 12 }, | ||
351 | { .pdiv = 24, .hw_val = 13 }, | ||
352 | { .pdiv = 32, .hw_val = 14 }, | ||
353 | { .pdiv = 0, .hw_val = 0 }, | ||
354 | }; | ||
355 | |||
356 | static struct tegra_clk_pll_freq_table pll_c4_freq_table[] = { | ||
357 | { 12000000, 600000000, 100, 1, 1}, | ||
358 | { 13000000, 600000000, 92, 1, 1}, /* actual: 598.0 MHz */ | ||
359 | { 16800000, 600000000, 71, 1, 1}, /* actual: 596.4 MHz */ | ||
360 | { 19200000, 600000000, 62, 1, 1}, /* actual: 595.2 MHz */ | ||
361 | { 26000000, 600000000, 92, 2, 1}, /* actual: 598.0 MHz */ | ||
362 | { 0, 0, 0, 0, 0, 0 }, | ||
363 | }; | ||
364 | |||
365 | static struct tegra_clk_pll_params pll_c4_params = { | ||
366 | .input_min = 12000000, | ||
367 | .input_max = 1000000000, | ||
368 | .cf_min = 12000000, | ||
369 | .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ | ||
370 | .vco_min = 600000000, | ||
371 | .vco_max = 1200000000, | ||
372 | .base_reg = PLLC4_BASE, | ||
373 | .misc_reg = PLLC4_MISC, | ||
374 | .lock_mask = PLL_BASE_LOCK, | ||
375 | .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, | ||
376 | .lock_delay = 300, | ||
377 | .iddq_reg = PLLC4_BASE, | ||
378 | .iddq_bit_idx = PLLSS_IDDQ_BIT, | ||
379 | .pdiv_tohw = pll12g_ssd_esd_p, | ||
380 | .div_nmp = &pllss_nmp, | ||
381 | .ext_misc_reg[0] = 0x5ac, | ||
382 | .ext_misc_reg[1] = 0x5b0, | ||
383 | .ext_misc_reg[2] = 0x5b4, | ||
384 | .freq_table = pll_c4_freq_table, | ||
385 | }; | ||
386 | |||
387 | static struct pdiv_map pllm_p[] = { | ||
388 | { .pdiv = 1, .hw_val = 0 }, | ||
389 | { .pdiv = 2, .hw_val = 1 }, | ||
390 | { .pdiv = 0, .hw_val = 0 }, | ||
391 | }; | ||
392 | |||
393 | static struct tegra_clk_pll_freq_table pll_m_freq_table[] = { | ||
394 | {12000000, 800000000, 66, 1, 1}, /* actual: 792.0 MHz */ | ||
395 | {13000000, 800000000, 61, 1, 1}, /* actual: 793.0 MHz */ | ||
396 | {16800000, 800000000, 47, 1, 1}, /* actual: 789.6 MHz */ | ||
397 | {19200000, 800000000, 41, 1, 1}, /* actual: 787.2 MHz */ | ||
398 | {26000000, 800000000, 61, 2, 1}, /* actual: 793.0 MHz */ | ||
399 | {0, 0, 0, 0, 0, 0}, | ||
400 | }; | ||
401 | |||
402 | static struct div_nmp pllm_nmp = { | ||
403 | .divm_shift = 0, | ||
404 | .divm_width = 8, | ||
405 | .override_divm_shift = 0, | ||
406 | .divn_shift = 8, | ||
407 | .divn_width = 8, | ||
408 | .override_divn_shift = 8, | ||
409 | .divp_shift = 20, | ||
410 | .divp_width = 1, | ||
411 | .override_divp_shift = 27, | ||
412 | }; | ||
413 | |||
414 | static struct tegra_clk_pll_params pll_m_params = { | ||
415 | .input_min = 12000000, | ||
416 | .input_max = 500000000, | ||
417 | .cf_min = 12000000, | ||
418 | .cf_max = 19200000, /* s/w policy, h/w capability 50 MHz */ | ||
419 | .vco_min = 400000000, | ||
420 | .vco_max = 1066000000, | ||
421 | .base_reg = PLLM_BASE, | ||
422 | .misc_reg = PLLM_MISC, | ||
423 | .lock_mask = PLL_BASE_LOCK, | ||
424 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
425 | .lock_delay = 300, | ||
426 | .max_p = 2, | ||
427 | .pdiv_tohw = pllm_p, | ||
428 | .div_nmp = &pllm_nmp, | ||
429 | .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, | ||
430 | .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, | ||
431 | .freq_table = pll_m_freq_table, | ||
432 | .flags = TEGRA_PLL_USE_LOCK, | ||
433 | }; | ||
434 | |||
435 | static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { | ||
436 | /* PLLE special case: use cpcon field to store cml divider value */ | ||
437 | {336000000, 100000000, 100, 21, 16, 11}, | ||
438 | {312000000, 100000000, 200, 26, 24, 13}, | ||
439 | {13000000, 100000000, 200, 1, 26, 13}, | ||
440 | {12000000, 100000000, 200, 1, 24, 13}, | ||
441 | {0, 0, 0, 0, 0, 0}, | ||
442 | }; | ||
443 | |||
444 | static struct div_nmp plle_nmp = { | ||
445 | .divm_shift = 0, | ||
446 | .divm_width = 8, | ||
447 | .divn_shift = 8, | ||
448 | .divn_width = 8, | ||
449 | .divp_shift = 24, | ||
450 | .divp_width = 4, | ||
451 | }; | ||
452 | |||
453 | static struct tegra_clk_pll_params pll_e_params = { | ||
454 | .input_min = 12000000, | ||
455 | .input_max = 1000000000, | ||
456 | .cf_min = 12000000, | ||
457 | .cf_max = 75000000, | ||
458 | .vco_min = 1600000000, | ||
459 | .vco_max = 2400000000U, | ||
460 | .base_reg = PLLE_BASE, | ||
461 | .misc_reg = PLLE_MISC, | ||
462 | .aux_reg = PLLE_AUX, | ||
463 | .lock_mask = PLLE_MISC_LOCK, | ||
464 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, | ||
465 | .lock_delay = 300, | ||
466 | .div_nmp = &plle_nmp, | ||
467 | .freq_table = pll_e_freq_table, | ||
468 | .flags = TEGRA_PLL_FIXED, | ||
469 | .fixed_rate = 100000000, | ||
470 | }; | ||
471 | |||
472 | static const struct clk_div_table pll_re_div_table[] = { | ||
473 | { .val = 0, .div = 1 }, | ||
474 | { .val = 1, .div = 2 }, | ||
475 | { .val = 2, .div = 3 }, | ||
476 | { .val = 3, .div = 4 }, | ||
477 | { .val = 4, .div = 5 }, | ||
478 | { .val = 5, .div = 6 }, | ||
479 | { .val = 0, .div = 0 }, | ||
480 | }; | ||
481 | |||
482 | static struct div_nmp pllre_nmp = { | ||
483 | .divm_shift = 0, | ||
484 | .divm_width = 8, | ||
485 | .divn_shift = 8, | ||
486 | .divn_width = 8, | ||
487 | .divp_shift = 16, | ||
488 | .divp_width = 4, | ||
489 | }; | ||
490 | |||
491 | static struct tegra_clk_pll_params pll_re_vco_params = { | ||
492 | .input_min = 12000000, | ||
493 | .input_max = 1000000000, | ||
494 | .cf_min = 12000000, | ||
495 | .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ | ||
496 | .vco_min = 300000000, | ||
497 | .vco_max = 600000000, | ||
498 | .base_reg = PLLRE_BASE, | ||
499 | .misc_reg = PLLRE_MISC, | ||
500 | .lock_mask = PLLRE_MISC_LOCK, | ||
501 | .lock_enable_bit_idx = PLLRE_MISC_LOCK_ENABLE, | ||
502 | .lock_delay = 300, | ||
503 | .iddq_reg = PLLRE_MISC, | ||
504 | .iddq_bit_idx = PLLRE_IDDQ_BIT, | ||
505 | .div_nmp = &pllre_nmp, | ||
506 | .flags = TEGRA_PLL_USE_LOCK, | ||
507 | }; | ||
508 | |||
509 | static struct div_nmp pllp_nmp = { | ||
510 | .divm_shift = 0, | ||
511 | .divm_width = 5, | ||
512 | .divn_shift = 8, | ||
513 | .divn_width = 10, | ||
514 | .divp_shift = 20, | ||
515 | .divp_width = 3, | ||
516 | }; | ||
517 | |||
518 | static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { | ||
519 | {12000000, 216000000, 432, 12, 1, 8}, | ||
520 | {13000000, 216000000, 432, 13, 1, 8}, | ||
521 | {16800000, 216000000, 360, 14, 1, 8}, | ||
522 | {19200000, 216000000, 360, 16, 1, 8}, | ||
523 | {26000000, 216000000, 432, 26, 1, 8}, | ||
524 | {0, 0, 0, 0, 0, 0}, | ||
525 | }; | ||
526 | |||
527 | static struct tegra_clk_pll_params pll_p_params = { | ||
528 | .input_min = 2000000, | ||
529 | .input_max = 31000000, | ||
530 | .cf_min = 1000000, | ||
531 | .cf_max = 6000000, | ||
532 | .vco_min = 200000000, | ||
533 | .vco_max = 700000000, | ||
534 | .base_reg = PLLP_BASE, | ||
535 | .misc_reg = PLLP_MISC, | ||
536 | .lock_mask = PLL_BASE_LOCK, | ||
537 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
538 | .lock_delay = 300, | ||
539 | .div_nmp = &pllp_nmp, | ||
540 | .freq_table = pll_p_freq_table, | ||
541 | .fixed_rate = 408000000, | ||
542 | .flags = TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, | ||
543 | }; | ||
544 | |||
545 | static struct tegra_clk_pll_freq_table pll_a_freq_table[] = { | ||
546 | {9600000, 282240000, 147, 5, 0, 4}, | ||
547 | {9600000, 368640000, 192, 5, 0, 4}, | ||
548 | {9600000, 240000000, 200, 8, 0, 8}, | ||
549 | |||
550 | {28800000, 282240000, 245, 25, 0, 8}, | ||
551 | {28800000, 368640000, 320, 25, 0, 8}, | ||
552 | {28800000, 240000000, 200, 24, 0, 8}, | ||
553 | {0, 0, 0, 0, 0, 0}, | ||
554 | }; | ||
555 | |||
556 | static struct tegra_clk_pll_params pll_a_params = { | ||
557 | .input_min = 2000000, | ||
558 | .input_max = 31000000, | ||
559 | .cf_min = 1000000, | ||
560 | .cf_max = 6000000, | ||
561 | .vco_min = 200000000, | ||
562 | .vco_max = 700000000, | ||
563 | .base_reg = PLLA_BASE, | ||
564 | .misc_reg = PLLA_MISC, | ||
565 | .lock_mask = PLL_BASE_LOCK, | ||
566 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | ||
567 | .lock_delay = 300, | ||
568 | .div_nmp = &pllp_nmp, | ||
569 | .freq_table = pll_a_freq_table, | ||
570 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, | ||
571 | }; | ||
572 | |||
573 | static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { | ||
574 | {12000000, 216000000, 864, 12, 4, 12}, | ||
575 | {13000000, 216000000, 864, 13, 4, 12}, | ||
576 | {16800000, 216000000, 720, 14, 4, 12}, | ||
577 | {19200000, 216000000, 720, 16, 4, 12}, | ||
578 | {26000000, 216000000, 864, 26, 4, 12}, | ||
579 | |||
580 | {12000000, 594000000, 594, 12, 1, 12}, | ||
581 | {13000000, 594000000, 594, 13, 1, 12}, | ||
582 | {16800000, 594000000, 495, 14, 1, 12}, | ||
583 | {19200000, 594000000, 495, 16, 1, 12}, | ||
584 | {26000000, 594000000, 594, 26, 1, 12}, | ||
585 | |||
586 | {12000000, 1000000000, 1000, 12, 1, 12}, | ||
587 | {13000000, 1000000000, 1000, 13, 1, 12}, | ||
588 | {19200000, 1000000000, 625, 12, 1, 12}, | ||
589 | {26000000, 1000000000, 1000, 26, 1, 12}, | ||
590 | |||
591 | {0, 0, 0, 0, 0, 0}, | ||
592 | }; | ||
593 | |||
594 | static struct tegra_clk_pll_params pll_d_params = { | ||
595 | .input_min = 2000000, | ||
596 | .input_max = 40000000, | ||
597 | .cf_min = 1000000, | ||
598 | .cf_max = 6000000, | ||
599 | .vco_min = 500000000, | ||
600 | .vco_max = 1000000000, | ||
601 | .base_reg = PLLD_BASE, | ||
602 | .misc_reg = PLLD_MISC, | ||
603 | .lock_mask = PLL_BASE_LOCK, | ||
604 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | ||
605 | .lock_delay = 1000, | ||
606 | .div_nmp = &pllp_nmp, | ||
607 | .freq_table = pll_d_freq_table, | ||
608 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | ||
609 | TEGRA_PLL_USE_LOCK, | ||
610 | }; | ||
611 | |||
612 | static struct tegra_clk_pll_freq_table tegra124_pll_d2_freq_table[] = { | ||
613 | { 12000000, 148500000, 99, 1, 8}, | ||
614 | { 12000000, 594000000, 99, 1, 1}, | ||
615 | { 13000000, 594000000, 91, 1, 1}, /* actual: 591.5 MHz */ | ||
616 | { 16800000, 594000000, 71, 1, 1}, /* actual: 596.4 MHz */ | ||
617 | { 19200000, 594000000, 62, 1, 1}, /* actual: 595.2 MHz */ | ||
618 | { 26000000, 594000000, 91, 2, 1}, /* actual: 591.5 MHz */ | ||
619 | { 0, 0, 0, 0, 0, 0 }, | ||
620 | }; | ||
621 | |||
622 | static struct tegra_clk_pll_params tegra124_pll_d2_params = { | ||
623 | .input_min = 12000000, | ||
624 | .input_max = 1000000000, | ||
625 | .cf_min = 12000000, | ||
626 | .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ | ||
627 | .vco_min = 600000000, | ||
628 | .vco_max = 1200000000, | ||
629 | .base_reg = PLLD2_BASE, | ||
630 | .misc_reg = PLLD2_MISC, | ||
631 | .lock_mask = PLL_BASE_LOCK, | ||
632 | .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, | ||
633 | .lock_delay = 300, | ||
634 | .iddq_reg = PLLD2_BASE, | ||
635 | .iddq_bit_idx = PLLSS_IDDQ_BIT, | ||
636 | .pdiv_tohw = pll12g_ssd_esd_p, | ||
637 | .div_nmp = &pllss_nmp, | ||
638 | .ext_misc_reg[0] = 0x570, | ||
639 | .ext_misc_reg[1] = 0x574, | ||
640 | .ext_misc_reg[2] = 0x578, | ||
641 | .max_p = 15, | ||
642 | .freq_table = tegra124_pll_d2_freq_table, | ||
643 | }; | ||
644 | |||
645 | static struct tegra_clk_pll_freq_table pll_dp_freq_table[] = { | ||
646 | { 12000000, 600000000, 100, 1, 1}, | ||
647 | { 13000000, 600000000, 92, 1, 1}, /* actual: 598.0 MHz */ | ||
648 | { 16800000, 600000000, 71, 1, 1}, /* actual: 596.4 MHz */ | ||
649 | { 19200000, 600000000, 62, 1, 1}, /* actual: 595.2 MHz */ | ||
650 | { 26000000, 600000000, 92, 2, 1}, /* actual: 598.0 MHz */ | ||
651 | { 0, 0, 0, 0, 0, 0 }, | ||
652 | }; | ||
653 | |||
654 | static struct tegra_clk_pll_params pll_dp_params = { | ||
655 | .input_min = 12000000, | ||
656 | .input_max = 1000000000, | ||
657 | .cf_min = 12000000, | ||
658 | .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */ | ||
659 | .vco_min = 600000000, | ||
660 | .vco_max = 1200000000, | ||
661 | .base_reg = PLLDP_BASE, | ||
662 | .misc_reg = PLLDP_MISC, | ||
663 | .lock_mask = PLL_BASE_LOCK, | ||
664 | .lock_enable_bit_idx = PLLSS_MISC_LOCK_ENABLE, | ||
665 | .lock_delay = 300, | ||
666 | .iddq_reg = PLLDP_BASE, | ||
667 | .iddq_bit_idx = PLLSS_IDDQ_BIT, | ||
668 | .pdiv_tohw = pll12g_ssd_esd_p, | ||
669 | .div_nmp = &pllss_nmp, | ||
670 | .ext_misc_reg[0] = 0x598, | ||
671 | .ext_misc_reg[1] = 0x59c, | ||
672 | .ext_misc_reg[2] = 0x5a0, | ||
673 | .max_p = 5, | ||
674 | .freq_table = pll_dp_freq_table, | ||
675 | }; | ||
676 | |||
677 | static struct pdiv_map pllu_p[] = { | ||
678 | { .pdiv = 1, .hw_val = 1 }, | ||
679 | { .pdiv = 2, .hw_val = 0 }, | ||
680 | { .pdiv = 0, .hw_val = 0 }, | ||
681 | }; | ||
682 | |||
683 | static struct div_nmp pllu_nmp = { | ||
684 | .divm_shift = 0, | ||
685 | .divm_width = 5, | ||
686 | .divn_shift = 8, | ||
687 | .divn_width = 10, | ||
688 | .divp_shift = 20, | ||
689 | .divp_width = 1, | ||
690 | }; | ||
691 | |||
692 | static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { | ||
693 | {12000000, 480000000, 960, 12, 2, 12}, | ||
694 | {13000000, 480000000, 960, 13, 2, 12}, | ||
695 | {16800000, 480000000, 400, 7, 2, 5}, | ||
696 | {19200000, 480000000, 200, 4, 2, 3}, | ||
697 | {26000000, 480000000, 960, 26, 2, 12}, | ||
698 | {0, 0, 0, 0, 0, 0}, | ||
699 | }; | ||
700 | |||
701 | static struct tegra_clk_pll_params pll_u_params = { | ||
702 | .input_min = 2000000, | ||
703 | .input_max = 40000000, | ||
704 | .cf_min = 1000000, | ||
705 | .cf_max = 6000000, | ||
706 | .vco_min = 480000000, | ||
707 | .vco_max = 960000000, | ||
708 | .base_reg = PLLU_BASE, | ||
709 | .misc_reg = PLLU_MISC, | ||
710 | .lock_mask = PLL_BASE_LOCK, | ||
711 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | ||
712 | .lock_delay = 1000, | ||
713 | .pdiv_tohw = pllu_p, | ||
714 | .div_nmp = &pllu_nmp, | ||
715 | .freq_table = pll_u_freq_table, | ||
716 | .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | ||
717 | TEGRA_PLL_USE_LOCK, | ||
718 | }; | ||
719 | |||
720 | struct utmi_clk_param { | ||
721 | /* Oscillator Frequency in KHz */ | ||
722 | u32 osc_frequency; | ||
723 | /* UTMIP PLL Enable Delay Count */ | ||
724 | u8 enable_delay_count; | ||
725 | /* UTMIP PLL Stable count */ | ||
726 | u8 stable_count; | ||
727 | /* UTMIP PLL Active delay count */ | ||
728 | u8 active_delay_count; | ||
729 | /* UTMIP PLL Xtal frequency count */ | ||
730 | u8 xtal_freq_count; | ||
731 | }; | ||
732 | |||
733 | static const struct utmi_clk_param utmi_parameters[] = { | ||
734 | {.osc_frequency = 13000000, .enable_delay_count = 0x02, | ||
735 | .stable_count = 0x33, .active_delay_count = 0x05, | ||
736 | .xtal_freq_count = 0x7F}, | ||
737 | {.osc_frequency = 19200000, .enable_delay_count = 0x03, | ||
738 | .stable_count = 0x4B, .active_delay_count = 0x06, | ||
739 | .xtal_freq_count = 0xBB}, | ||
740 | {.osc_frequency = 12000000, .enable_delay_count = 0x02, | ||
741 | .stable_count = 0x2F, .active_delay_count = 0x04, | ||
742 | .xtal_freq_count = 0x76}, | ||
743 | {.osc_frequency = 26000000, .enable_delay_count = 0x04, | ||
744 | .stable_count = 0x66, .active_delay_count = 0x09, | ||
745 | .xtal_freq_count = 0xFE}, | ||
746 | {.osc_frequency = 16800000, .enable_delay_count = 0x03, | ||
747 | .stable_count = 0x41, .active_delay_count = 0x0A, | ||
748 | .xtal_freq_count = 0xA4}, | ||
749 | }; | ||
750 | |||
751 | static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { | ||
752 | [tegra_clk_ispb] = { .dt_id = TEGRA124_CLK_ISPB, .present = true }, | ||
753 | [tegra_clk_rtc] = { .dt_id = TEGRA124_CLK_RTC, .present = true }, | ||
754 | [tegra_clk_timer] = { .dt_id = TEGRA124_CLK_TIMER, .present = true }, | ||
755 | [tegra_clk_uarta] = { .dt_id = TEGRA124_CLK_UARTA, .present = true }, | ||
756 | [tegra_clk_sdmmc2] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true }, | ||
757 | [tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true }, | ||
758 | [tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true }, | ||
759 | [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true }, | ||
760 | [tegra_clk_sdmmc1] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true }, | ||
761 | [tegra_clk_sdmmc4] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true }, | ||
762 | [tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true }, | ||
763 | [tegra_clk_i2s2] = { .dt_id = TEGRA124_CLK_I2S2, .present = true }, | ||
764 | [tegra_clk_gr2d] = { .dt_id = TEGRA124_CLK_GR_2D, .present = true }, | ||
765 | [tegra_clk_usbd] = { .dt_id = TEGRA124_CLK_USBD, .present = true }, | ||
766 | [tegra_clk_isp_8] = { .dt_id = TEGRA124_CLK_ISP, .present = true }, | ||
767 | [tegra_clk_gr3d] = { .dt_id = TEGRA124_CLK_GR_3D, .present = true }, | ||
768 | [tegra_clk_disp2] = { .dt_id = TEGRA124_CLK_DISP2, .present = true }, | ||
769 | [tegra_clk_disp1] = { .dt_id = TEGRA124_CLK_DISP1, .present = true }, | ||
770 | [tegra_clk_host1x] = { .dt_id = TEGRA124_CLK_HOST1X, .present = true }, | ||
771 | [tegra_clk_vcp] = { .dt_id = TEGRA124_CLK_VCP, .present = true }, | ||
772 | [tegra_clk_i2s0] = { .dt_id = TEGRA124_CLK_I2S0, .present = true }, | ||
773 | [tegra_clk_apbdma] = { .dt_id = TEGRA124_CLK_APBDMA, .present = true }, | ||
774 | [tegra_clk_kbc] = { .dt_id = TEGRA124_CLK_KBC, .present = true }, | ||
775 | [tegra_clk_kfuse] = { .dt_id = TEGRA124_CLK_KFUSE, .present = true }, | ||
776 | [tegra_clk_sbc1] = { .dt_id = TEGRA124_CLK_SBC1, .present = true }, | ||
777 | [tegra_clk_nor] = { .dt_id = TEGRA124_CLK_NOR, .present = true }, | ||
778 | [tegra_clk_sbc2] = { .dt_id = TEGRA124_CLK_SBC2, .present = true }, | ||
779 | [tegra_clk_sbc3] = { .dt_id = TEGRA124_CLK_SBC3, .present = true }, | ||
780 | [tegra_clk_i2c5] = { .dt_id = TEGRA124_CLK_I2C5, .present = true }, | ||
781 | [tegra_clk_dsia] = { .dt_id = TEGRA124_CLK_DSIA, .present = true }, | ||
782 | [tegra_clk_mipi] = { .dt_id = TEGRA124_CLK_MIPI, .present = true }, | ||
783 | [tegra_clk_hdmi] = { .dt_id = TEGRA124_CLK_HDMI, .present = true }, | ||
784 | [tegra_clk_csi] = { .dt_id = TEGRA124_CLK_CSI, .present = true }, | ||
785 | [tegra_clk_i2c2] = { .dt_id = TEGRA124_CLK_I2C2, .present = true }, | ||
786 | [tegra_clk_uartc] = { .dt_id = TEGRA124_CLK_UARTC, .present = true }, | ||
787 | [tegra_clk_mipi_cal] = { .dt_id = TEGRA124_CLK_MIPI_CAL, .present = true }, | ||
788 | [tegra_clk_emc] = { .dt_id = TEGRA124_CLK_EMC, .present = true }, | ||
789 | [tegra_clk_usb2] = { .dt_id = TEGRA124_CLK_USB2, .present = true }, | ||
790 | [tegra_clk_usb3] = { .dt_id = TEGRA124_CLK_USB3, .present = true }, | ||
791 | [tegra_clk_vde_8] = { .dt_id = TEGRA124_CLK_VDE, .present = true }, | ||
792 | [tegra_clk_bsea] = { .dt_id = TEGRA124_CLK_BSEA, .present = true }, | ||
793 | [tegra_clk_bsev] = { .dt_id = TEGRA124_CLK_BSEV, .present = true }, | ||
794 | [tegra_clk_uartd] = { .dt_id = TEGRA124_CLK_UARTD, .present = true }, | ||
795 | [tegra_clk_i2c3] = { .dt_id = TEGRA124_CLK_I2C3, .present = true }, | ||
796 | [tegra_clk_sbc4] = { .dt_id = TEGRA124_CLK_SBC4, .present = true }, | ||
797 | [tegra_clk_sdmmc3] = { .dt_id = TEGRA124_CLK_SDMMC3, .present = true }, | ||
798 | [tegra_clk_pcie] = { .dt_id = TEGRA124_CLK_PCIE, .present = true }, | ||
799 | [tegra_clk_owr] = { .dt_id = TEGRA124_CLK_OWR, .present = true }, | ||
800 | [tegra_clk_afi] = { .dt_id = TEGRA124_CLK_AFI, .present = true }, | ||
801 | [tegra_clk_csite] = { .dt_id = TEGRA124_CLK_CSITE, .present = true }, | ||
802 | [tegra_clk_la] = { .dt_id = TEGRA124_CLK_LA, .present = true }, | ||
803 | [tegra_clk_trace] = { .dt_id = TEGRA124_CLK_TRACE, .present = true }, | ||
804 | [tegra_clk_soc_therm] = { .dt_id = TEGRA124_CLK_SOC_THERM, .present = true }, | ||
805 | [tegra_clk_dtv] = { .dt_id = TEGRA124_CLK_DTV, .present = true }, | ||
806 | [tegra_clk_ndspeed] = { .dt_id = TEGRA124_CLK_NDSPEED, .present = true }, | ||
807 | [tegra_clk_i2cslow] = { .dt_id = TEGRA124_CLK_I2CSLOW, .present = true }, | ||
808 | [tegra_clk_dsib] = { .dt_id = TEGRA124_CLK_DSIB, .present = true }, | ||
809 | [tegra_clk_tsec] = { .dt_id = TEGRA124_CLK_TSEC, .present = true }, | ||
810 | [tegra_clk_xusb_host] = { .dt_id = TEGRA124_CLK_XUSB_HOST, .present = true }, | ||
811 | [tegra_clk_msenc] = { .dt_id = TEGRA124_CLK_MSENC, .present = true }, | ||
812 | [tegra_clk_csus] = { .dt_id = TEGRA124_CLK_CSUS, .present = true }, | ||
813 | [tegra_clk_mselect] = { .dt_id = TEGRA124_CLK_MSELECT, .present = true }, | ||
814 | [tegra_clk_tsensor] = { .dt_id = TEGRA124_CLK_TSENSOR, .present = true }, | ||
815 | [tegra_clk_i2s3] = { .dt_id = TEGRA124_CLK_I2S3, .present = true }, | ||
816 | [tegra_clk_i2s4] = { .dt_id = TEGRA124_CLK_I2S4, .present = true }, | ||
817 | [tegra_clk_i2c4] = { .dt_id = TEGRA124_CLK_I2C4, .present = true }, | ||
818 | [tegra_clk_sbc5] = { .dt_id = TEGRA124_CLK_SBC5, .present = true }, | ||
819 | [tegra_clk_sbc6] = { .dt_id = TEGRA124_CLK_SBC6, .present = true }, | ||
820 | [tegra_clk_d_audio] = { .dt_id = TEGRA124_CLK_D_AUDIO, .present = true }, | ||
821 | [tegra_clk_apbif] = { .dt_id = TEGRA124_CLK_APBIF, .present = true }, | ||
822 | [tegra_clk_dam0] = { .dt_id = TEGRA124_CLK_DAM0, .present = true }, | ||
823 | [tegra_clk_dam1] = { .dt_id = TEGRA124_CLK_DAM1, .present = true }, | ||
824 | [tegra_clk_dam2] = { .dt_id = TEGRA124_CLK_DAM2, .present = true }, | ||
825 | [tegra_clk_hda2codec_2x] = { .dt_id = TEGRA124_CLK_HDA2CODEC_2X, .present = true }, | ||
826 | [tegra_clk_audio0_2x] = { .dt_id = TEGRA124_CLK_AUDIO0_2X, .present = true }, | ||
827 | [tegra_clk_audio1_2x] = { .dt_id = TEGRA124_CLK_AUDIO1_2X, .present = true }, | ||
828 | [tegra_clk_audio2_2x] = { .dt_id = TEGRA124_CLK_AUDIO2_2X, .present = true }, | ||
829 | [tegra_clk_audio3_2x] = { .dt_id = TEGRA124_CLK_AUDIO3_2X, .present = true }, | ||
830 | [tegra_clk_audio4_2x] = { .dt_id = TEGRA124_CLK_AUDIO4_2X, .present = true }, | ||
831 | [tegra_clk_spdif_2x] = { .dt_id = TEGRA124_CLK_SPDIF_2X, .present = true }, | ||
832 | [tegra_clk_actmon] = { .dt_id = TEGRA124_CLK_ACTMON, .present = true }, | ||
833 | [tegra_clk_extern1] = { .dt_id = TEGRA124_CLK_EXTERN1, .present = true }, | ||
834 | [tegra_clk_extern2] = { .dt_id = TEGRA124_CLK_EXTERN2, .present = true }, | ||
835 | [tegra_clk_extern3] = { .dt_id = TEGRA124_CLK_EXTERN3, .present = true }, | ||
836 | [tegra_clk_sata_oob] = { .dt_id = TEGRA124_CLK_SATA_OOB, .present = true }, | ||
837 | [tegra_clk_sata] = { .dt_id = TEGRA124_CLK_SATA, .present = true }, | ||
838 | [tegra_clk_hda] = { .dt_id = TEGRA124_CLK_HDA, .present = true }, | ||
839 | [tegra_clk_se] = { .dt_id = TEGRA124_CLK_SE, .present = true }, | ||
840 | [tegra_clk_hda2hdmi] = { .dt_id = TEGRA124_CLK_HDA2HDMI, .present = true }, | ||
841 | [tegra_clk_sata_cold] = { .dt_id = TEGRA124_CLK_SATA_COLD, .present = true }, | ||
842 | [tegra_clk_cilab] = { .dt_id = TEGRA124_CLK_CILAB, .present = true }, | ||
843 | [tegra_clk_cilcd] = { .dt_id = TEGRA124_CLK_CILCD, .present = true }, | ||
844 | [tegra_clk_cile] = { .dt_id = TEGRA124_CLK_CILE, .present = true }, | ||
845 | [tegra_clk_dsialp] = { .dt_id = TEGRA124_CLK_DSIALP, .present = true }, | ||
846 | [tegra_clk_dsiblp] = { .dt_id = TEGRA124_CLK_DSIBLP, .present = true }, | ||
847 | [tegra_clk_entropy] = { .dt_id = TEGRA124_CLK_ENTROPY, .present = true }, | ||
848 | [tegra_clk_dds] = { .dt_id = TEGRA124_CLK_DDS, .present = true }, | ||
849 | [tegra_clk_dp2] = { .dt_id = TEGRA124_CLK_DP2, .present = true }, | ||
850 | [tegra_clk_amx] = { .dt_id = TEGRA124_CLK_AMX, .present = true }, | ||
851 | [tegra_clk_adx] = { .dt_id = TEGRA124_CLK_ADX, .present = true }, | ||
852 | [tegra_clk_xusb_ss] = { .dt_id = TEGRA124_CLK_XUSB_SS, .present = true }, | ||
853 | [tegra_clk_i2c6] = { .dt_id = TEGRA124_CLK_I2C6, .present = true }, | ||
854 | [tegra_clk_vim2_clk] = { .dt_id = TEGRA124_CLK_VIM2_CLK, .present = true }, | ||
855 | [tegra_clk_hdmi_audio] = { .dt_id = TEGRA124_CLK_HDMI_AUDIO, .present = true }, | ||
856 | [tegra_clk_clk72Mhz] = { .dt_id = TEGRA124_CLK_CLK72MHZ, .present = true }, | ||
857 | [tegra_clk_vic03] = { .dt_id = TEGRA124_CLK_VIC03, .present = true }, | ||
858 | [tegra_clk_adx1] = { .dt_id = TEGRA124_CLK_ADX1, .present = true }, | ||
859 | [tegra_clk_dpaux] = { .dt_id = TEGRA124_CLK_DPAUX, .present = true }, | ||
860 | [tegra_clk_sor0] = { .dt_id = TEGRA124_CLK_SOR0, .present = true }, | ||
861 | [tegra_clk_sor0_lvds] = { .dt_id = TEGRA124_CLK_SOR0_LVDS, .present = true }, | ||
862 | [tegra_clk_gpu] = { .dt_id = TEGRA124_CLK_GPU, .present = true }, | ||
863 | [tegra_clk_amx1] = { .dt_id = TEGRA124_CLK_AMX1, .present = true }, | ||
864 | [tegra_clk_uartb] = { .dt_id = TEGRA124_CLK_UARTB, .present = true }, | ||
865 | [tegra_clk_vfir] = { .dt_id = TEGRA124_CLK_VFIR, .present = true }, | ||
866 | [tegra_clk_spdif_in] = { .dt_id = TEGRA124_CLK_SPDIF_IN, .present = true }, | ||
867 | [tegra_clk_spdif_out] = { .dt_id = TEGRA124_CLK_SPDIF_OUT, .present = true }, | ||
868 | [tegra_clk_vi_9] = { .dt_id = TEGRA124_CLK_VI, .present = true }, | ||
869 | [tegra_clk_vi_sensor] = { .dt_id = TEGRA124_CLK_VI_SENSOR, .present = true }, | ||
870 | [tegra_clk_fuse] = { .dt_id = TEGRA124_CLK_FUSE, .present = true }, | ||
871 | [tegra_clk_fuse_burn] = { .dt_id = TEGRA124_CLK_FUSE_BURN, .present = true }, | ||
872 | [tegra_clk_clk_32k] = { .dt_id = TEGRA124_CLK_CLK_32K, .present = true }, | ||
873 | [tegra_clk_clk_m] = { .dt_id = TEGRA124_CLK_CLK_M, .present = true }, | ||
874 | [tegra_clk_clk_m_div2] = { .dt_id = TEGRA124_CLK_CLK_M_DIV2, .present = true }, | ||
875 | [tegra_clk_clk_m_div4] = { .dt_id = TEGRA124_CLK_CLK_M_DIV4, .present = true }, | ||
876 | [tegra_clk_pll_ref] = { .dt_id = TEGRA124_CLK_PLL_REF, .present = true }, | ||
877 | [tegra_clk_pll_c] = { .dt_id = TEGRA124_CLK_PLL_C, .present = true }, | ||
878 | [tegra_clk_pll_c_out1] = { .dt_id = TEGRA124_CLK_PLL_C_OUT1, .present = true }, | ||
879 | [tegra_clk_pll_c2] = { .dt_id = TEGRA124_CLK_PLL_C2, .present = true }, | ||
880 | [tegra_clk_pll_c3] = { .dt_id = TEGRA124_CLK_PLL_C3, .present = true }, | ||
881 | [tegra_clk_pll_m] = { .dt_id = TEGRA124_CLK_PLL_M, .present = true }, | ||
882 | [tegra_clk_pll_m_out1] = { .dt_id = TEGRA124_CLK_PLL_M_OUT1, .present = true }, | ||
883 | [tegra_clk_pll_p] = { .dt_id = TEGRA124_CLK_PLL_P, .present = true }, | ||
884 | [tegra_clk_pll_p_out1] = { .dt_id = TEGRA124_CLK_PLL_P_OUT1, .present = true }, | ||
885 | [tegra_clk_pll_p_out2] = { .dt_id = TEGRA124_CLK_PLL_P_OUT2, .present = true }, | ||
886 | [tegra_clk_pll_p_out3] = { .dt_id = TEGRA124_CLK_PLL_P_OUT3, .present = true }, | ||
887 | [tegra_clk_pll_p_out4] = { .dt_id = TEGRA124_CLK_PLL_P_OUT4, .present = true }, | ||
888 | [tegra_clk_pll_a] = { .dt_id = TEGRA124_CLK_PLL_A, .present = true }, | ||
889 | [tegra_clk_pll_a_out0] = { .dt_id = TEGRA124_CLK_PLL_A_OUT0, .present = true }, | ||
890 | [tegra_clk_pll_d] = { .dt_id = TEGRA124_CLK_PLL_D, .present = true }, | ||
891 | [tegra_clk_pll_d_out0] = { .dt_id = TEGRA124_CLK_PLL_D_OUT0, .present = true }, | ||
892 | [tegra_clk_pll_d2] = { .dt_id = TEGRA124_CLK_PLL_D2, .present = true }, | ||
893 | [tegra_clk_pll_d2_out0] = { .dt_id = TEGRA124_CLK_PLL_D2_OUT0, .present = true }, | ||
894 | [tegra_clk_pll_u] = { .dt_id = TEGRA124_CLK_PLL_U, .present = true }, | ||
895 | [tegra_clk_pll_u_480m] = { .dt_id = TEGRA124_CLK_PLL_U_480M, .present = true }, | ||
896 | [tegra_clk_pll_u_60m] = { .dt_id = TEGRA124_CLK_PLL_U_60M, .present = true }, | ||
897 | [tegra_clk_pll_u_48m] = { .dt_id = TEGRA124_CLK_PLL_U_48M, .present = true }, | ||
898 | [tegra_clk_pll_u_12m] = { .dt_id = TEGRA124_CLK_PLL_U_12M, .present = true }, | ||
899 | [tegra_clk_pll_x] = { .dt_id = TEGRA124_CLK_PLL_X, .present = true }, | ||
900 | [tegra_clk_pll_x_out0] = { .dt_id = TEGRA124_CLK_PLL_X_OUT0, .present = true }, | ||
901 | [tegra_clk_pll_re_vco] = { .dt_id = TEGRA124_CLK_PLL_RE_VCO, .present = true }, | ||
902 | [tegra_clk_pll_re_out] = { .dt_id = TEGRA124_CLK_PLL_RE_OUT, .present = true }, | ||
903 | [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA124_CLK_SPDIF_IN_SYNC, .present = true }, | ||
904 | [tegra_clk_i2s0_sync] = { .dt_id = TEGRA124_CLK_I2S0_SYNC, .present = true }, | ||
905 | [tegra_clk_i2s1_sync] = { .dt_id = TEGRA124_CLK_I2S1_SYNC, .present = true }, | ||
906 | [tegra_clk_i2s2_sync] = { .dt_id = TEGRA124_CLK_I2S2_SYNC, .present = true }, | ||
907 | [tegra_clk_i2s3_sync] = { .dt_id = TEGRA124_CLK_I2S3_SYNC, .present = true }, | ||
908 | [tegra_clk_i2s4_sync] = { .dt_id = TEGRA124_CLK_I2S4_SYNC, .present = true }, | ||
909 | [tegra_clk_vimclk_sync] = { .dt_id = TEGRA124_CLK_VIMCLK_SYNC, .present = true }, | ||
910 | [tegra_clk_audio0] = { .dt_id = TEGRA124_CLK_AUDIO0, .present = true }, | ||
911 | [tegra_clk_audio1] = { .dt_id = TEGRA124_CLK_AUDIO1, .present = true }, | ||
912 | [tegra_clk_audio2] = { .dt_id = TEGRA124_CLK_AUDIO2, .present = true }, | ||
913 | [tegra_clk_audio3] = { .dt_id = TEGRA124_CLK_AUDIO3, .present = true }, | ||
914 | [tegra_clk_audio4] = { .dt_id = TEGRA124_CLK_AUDIO4, .present = true }, | ||
915 | [tegra_clk_spdif] = { .dt_id = TEGRA124_CLK_SPDIF, .present = true }, | ||
916 | [tegra_clk_clk_out_1] = { .dt_id = TEGRA124_CLK_CLK_OUT_1, .present = true }, | ||
917 | [tegra_clk_clk_out_2] = { .dt_id = TEGRA124_CLK_CLK_OUT_2, .present = true }, | ||
918 | [tegra_clk_clk_out_3] = { .dt_id = TEGRA124_CLK_CLK_OUT_3, .present = true }, | ||
919 | [tegra_clk_blink] = { .dt_id = TEGRA124_CLK_BLINK, .present = true }, | ||
920 | [tegra_clk_xusb_host_src] = { .dt_id = TEGRA124_CLK_XUSB_HOST_SRC, .present = true }, | ||
921 | [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA124_CLK_XUSB_FALCON_SRC, .present = true }, | ||
922 | [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA124_CLK_XUSB_FS_SRC, .present = true }, | ||
923 | [tegra_clk_xusb_ss_src] = { .dt_id = TEGRA124_CLK_XUSB_SS_SRC, .present = true }, | ||
924 | [tegra_clk_xusb_dev_src] = { .dt_id = TEGRA124_CLK_XUSB_DEV_SRC, .present = true }, | ||
925 | [tegra_clk_xusb_dev] = { .dt_id = TEGRA124_CLK_XUSB_DEV, .present = true }, | ||
926 | [tegra_clk_xusb_hs_src] = { .dt_id = TEGRA124_CLK_XUSB_HS_SRC, .present = true }, | ||
927 | [tegra_clk_sclk] = { .dt_id = TEGRA124_CLK_SCLK, .present = true }, | ||
928 | [tegra_clk_hclk] = { .dt_id = TEGRA124_CLK_HCLK, .present = true }, | ||
929 | [tegra_clk_pclk] = { .dt_id = TEGRA124_CLK_PCLK, .present = true }, | ||
930 | [tegra_clk_cclk_g] = { .dt_id = TEGRA124_CLK_CCLK_G, .present = true }, | ||
931 | [tegra_clk_cclk_lp] = { .dt_id = TEGRA124_CLK_CCLK_LP, .present = true }, | ||
932 | [tegra_clk_dfll_ref] = { .dt_id = TEGRA124_CLK_DFLL_REF, .present = true }, | ||
933 | [tegra_clk_dfll_soc] = { .dt_id = TEGRA124_CLK_DFLL_SOC, .present = true }, | ||
934 | [tegra_clk_vi_sensor2] = { .dt_id = TEGRA124_CLK_VI_SENSOR2, .present = true }, | ||
935 | [tegra_clk_pll_p_out5] = { .dt_id = TEGRA124_CLK_PLL_P_OUT5, .present = true }, | ||
936 | [tegra_clk_pll_c4] = { .dt_id = TEGRA124_CLK_PLL_C4, .present = true }, | ||
937 | [tegra_clk_pll_dp] = { .dt_id = TEGRA124_CLK_PLL_DP, .present = true }, | ||
938 | [tegra_clk_audio0_mux] = { .dt_id = TEGRA124_CLK_AUDIO0_MUX, .present = true }, | ||
939 | [tegra_clk_audio1_mux] = { .dt_id = TEGRA124_CLK_AUDIO1_MUX, .present = true }, | ||
940 | [tegra_clk_audio2_mux] = { .dt_id = TEGRA124_CLK_AUDIO2_MUX, .present = true }, | ||
941 | [tegra_clk_audio3_mux] = { .dt_id = TEGRA124_CLK_AUDIO3_MUX, .present = true }, | ||
942 | [tegra_clk_audio4_mux] = { .dt_id = TEGRA124_CLK_AUDIO4_MUX, .present = true }, | ||
943 | [tegra_clk_spdif_mux] = { .dt_id = TEGRA124_CLK_SPDIF_MUX, .present = true }, | ||
944 | [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_1_MUX, .present = true }, | ||
945 | [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_2_MUX, .present = true }, | ||
946 | [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true }, | ||
947 | [tegra_clk_dsia_mux] = { .dt_id = TEGRA124_CLK_DSIA_MUX, .present = true }, | ||
948 | [tegra_clk_dsib_mux] = { .dt_id = TEGRA124_CLK_DSIB_MUX, .present = true }, | ||
949 | [tegra_clk_uarte] = { .dt_id = TEGRA124_CLK_UARTE, .present = true }, | ||
950 | }; | ||
951 | |||
952 | static struct tegra_devclk devclks[] __initdata = { | ||
953 | { .con_id = "clk_m", .dt_id = TEGRA124_CLK_CLK_M }, | ||
954 | { .con_id = "pll_ref", .dt_id = TEGRA124_CLK_PLL_REF }, | ||
955 | { .con_id = "clk_32k", .dt_id = TEGRA124_CLK_CLK_32K }, | ||
956 | { .con_id = "clk_m_div2", .dt_id = TEGRA124_CLK_CLK_M_DIV2 }, | ||
957 | { .con_id = "clk_m_div4", .dt_id = TEGRA124_CLK_CLK_M_DIV4 }, | ||
958 | { .con_id = "pll_c", .dt_id = TEGRA124_CLK_PLL_C }, | ||
959 | { .con_id = "pll_c_out1", .dt_id = TEGRA124_CLK_PLL_C_OUT1 }, | ||
960 | { .con_id = "pll_c2", .dt_id = TEGRA124_CLK_PLL_C2 }, | ||
961 | { .con_id = "pll_c3", .dt_id = TEGRA124_CLK_PLL_C3 }, | ||
962 | { .con_id = "pll_p", .dt_id = TEGRA124_CLK_PLL_P }, | ||
963 | { .con_id = "pll_p_out1", .dt_id = TEGRA124_CLK_PLL_P_OUT1 }, | ||
964 | { .con_id = "pll_p_out2", .dt_id = TEGRA124_CLK_PLL_P_OUT2 }, | ||
965 | { .con_id = "pll_p_out3", .dt_id = TEGRA124_CLK_PLL_P_OUT3 }, | ||
966 | { .con_id = "pll_p_out4", .dt_id = TEGRA124_CLK_PLL_P_OUT4 }, | ||
967 | { .con_id = "pll_m", .dt_id = TEGRA124_CLK_PLL_M }, | ||
968 | { .con_id = "pll_m_out1", .dt_id = TEGRA124_CLK_PLL_M_OUT1 }, | ||
969 | { .con_id = "pll_x", .dt_id = TEGRA124_CLK_PLL_X }, | ||
970 | { .con_id = "pll_x_out0", .dt_id = TEGRA124_CLK_PLL_X_OUT0 }, | ||
971 | { .con_id = "pll_u", .dt_id = TEGRA124_CLK_PLL_U }, | ||
972 | { .con_id = "pll_u_480M", .dt_id = TEGRA124_CLK_PLL_U_480M }, | ||
973 | { .con_id = "pll_u_60M", .dt_id = TEGRA124_CLK_PLL_U_60M }, | ||
974 | { .con_id = "pll_u_48M", .dt_id = TEGRA124_CLK_PLL_U_48M }, | ||
975 | { .con_id = "pll_u_12M", .dt_id = TEGRA124_CLK_PLL_U_12M }, | ||
976 | { .con_id = "pll_d", .dt_id = TEGRA124_CLK_PLL_D }, | ||
977 | { .con_id = "pll_d_out0", .dt_id = TEGRA124_CLK_PLL_D_OUT0 }, | ||
978 | { .con_id = "pll_d2", .dt_id = TEGRA124_CLK_PLL_D2 }, | ||
979 | { .con_id = "pll_d2_out0", .dt_id = TEGRA124_CLK_PLL_D2_OUT0 }, | ||
980 | { .con_id = "pll_a", .dt_id = TEGRA124_CLK_PLL_A }, | ||
981 | { .con_id = "pll_a_out0", .dt_id = TEGRA124_CLK_PLL_A_OUT0 }, | ||
982 | { .con_id = "pll_re_vco", .dt_id = TEGRA124_CLK_PLL_RE_VCO }, | ||
983 | { .con_id = "pll_re_out", .dt_id = TEGRA124_CLK_PLL_RE_OUT }, | ||
984 | { .con_id = "spdif_in_sync", .dt_id = TEGRA124_CLK_SPDIF_IN_SYNC }, | ||
985 | { .con_id = "i2s0_sync", .dt_id = TEGRA124_CLK_I2S0_SYNC }, | ||
986 | { .con_id = "i2s1_sync", .dt_id = TEGRA124_CLK_I2S1_SYNC }, | ||
987 | { .con_id = "i2s2_sync", .dt_id = TEGRA124_CLK_I2S2_SYNC }, | ||
988 | { .con_id = "i2s3_sync", .dt_id = TEGRA124_CLK_I2S3_SYNC }, | ||
989 | { .con_id = "i2s4_sync", .dt_id = TEGRA124_CLK_I2S4_SYNC }, | ||
990 | { .con_id = "vimclk_sync", .dt_id = TEGRA124_CLK_VIMCLK_SYNC }, | ||
991 | { .con_id = "audio0", .dt_id = TEGRA124_CLK_AUDIO0 }, | ||
992 | { .con_id = "audio1", .dt_id = TEGRA124_CLK_AUDIO1 }, | ||
993 | { .con_id = "audio2", .dt_id = TEGRA124_CLK_AUDIO2 }, | ||
994 | { .con_id = "audio3", .dt_id = TEGRA124_CLK_AUDIO3 }, | ||
995 | { .con_id = "audio4", .dt_id = TEGRA124_CLK_AUDIO4 }, | ||
996 | { .con_id = "spdif", .dt_id = TEGRA124_CLK_SPDIF }, | ||
997 | { .con_id = "audio0_2x", .dt_id = TEGRA124_CLK_AUDIO0_2X }, | ||
998 | { .con_id = "audio1_2x", .dt_id = TEGRA124_CLK_AUDIO1_2X }, | ||
999 | { .con_id = "audio2_2x", .dt_id = TEGRA124_CLK_AUDIO2_2X }, | ||
1000 | { .con_id = "audio3_2x", .dt_id = TEGRA124_CLK_AUDIO3_2X }, | ||
1001 | { .con_id = "audio4_2x", .dt_id = TEGRA124_CLK_AUDIO4_2X }, | ||
1002 | { .con_id = "spdif_2x", .dt_id = TEGRA124_CLK_SPDIF_2X }, | ||
1003 | { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA124_CLK_EXTERN1 }, | ||
1004 | { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA124_CLK_EXTERN2 }, | ||
1005 | { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA124_CLK_EXTERN3 }, | ||
1006 | { .con_id = "blink", .dt_id = TEGRA124_CLK_BLINK }, | ||
1007 | { .con_id = "cclk_g", .dt_id = TEGRA124_CLK_CCLK_G }, | ||
1008 | { .con_id = "cclk_lp", .dt_id = TEGRA124_CLK_CCLK_LP }, | ||
1009 | { .con_id = "sclk", .dt_id = TEGRA124_CLK_SCLK }, | ||
1010 | { .con_id = "hclk", .dt_id = TEGRA124_CLK_HCLK }, | ||
1011 | { .con_id = "pclk", .dt_id = TEGRA124_CLK_PCLK }, | ||
1012 | { .con_id = "fuse", .dt_id = TEGRA124_CLK_FUSE }, | ||
1013 | { .dev_id = "rtc-tegra", .dt_id = TEGRA124_CLK_RTC }, | ||
1014 | { .dev_id = "timer", .dt_id = TEGRA124_CLK_TIMER }, | ||
1015 | }; | ||
1016 | |||
1017 | static struct clk **clks; | ||
1018 | |||
1019 | static void tegra124_utmi_param_configure(void __iomem *clk_base) | ||
1020 | { | ||
1021 | u32 reg; | ||
1022 | int i; | ||
1023 | |||
1024 | for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { | ||
1025 | if (osc_freq == utmi_parameters[i].osc_frequency) | ||
1026 | break; | ||
1027 | } | ||
1028 | |||
1029 | if (i >= ARRAY_SIZE(utmi_parameters)) { | ||
1030 | pr_err("%s: Unexpected oscillator freq %lu\n", __func__, | ||
1031 | osc_freq); | ||
1032 | return; | ||
1033 | } | ||
1034 | |||
1035 | reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); | ||
1036 | |||
1037 | /* Program UTMIP PLL stable and active counts */ | ||
1038 | /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */ | ||
1039 | reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0); | ||
1040 | reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count); | ||
1041 | |||
1042 | reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); | ||
1043 | |||
1044 | reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i]. | ||
1045 | active_delay_count); | ||
1046 | |||
1047 | /* Remove power downs from UTMIP PLL control bits */ | ||
1048 | reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN; | ||
1049 | reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN; | ||
1050 | reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN; | ||
1051 | |||
1052 | writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); | ||
1053 | |||
1054 | /* Program UTMIP PLL delay and oscillator frequency counts */ | ||
1055 | reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); | ||
1056 | reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); | ||
1057 | |||
1058 | reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i]. | ||
1059 | enable_delay_count); | ||
1060 | |||
1061 | reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0); | ||
1062 | reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(utmi_parameters[i]. | ||
1063 | xtal_freq_count); | ||
1064 | |||
1065 | /* Remove power downs from UTMIP PLL control bits */ | ||
1066 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; | ||
1067 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN; | ||
1068 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP; | ||
1069 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN; | ||
1070 | writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); | ||
1071 | |||
1072 | /* Setup HW control of UTMIPLL */ | ||
1073 | reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); | ||
1074 | reg |= UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET; | ||
1075 | reg &= ~UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL; | ||
1076 | reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE; | ||
1077 | writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); | ||
1078 | |||
1079 | reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); | ||
1080 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; | ||
1081 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; | ||
1082 | writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); | ||
1083 | |||
1084 | udelay(1); | ||
1085 | |||
1086 | /* Setup SW override of UTMIPLL assuming USB2.0 | ||
1087 | ports are assigned to USB2 */ | ||
1088 | reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); | ||
1089 | reg |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL; | ||
1090 | reg &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE; | ||
1091 | writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); | ||
1092 | |||
1093 | udelay(1); | ||
1094 | |||
1095 | /* Enable HW control UTMIPLL */ | ||
1096 | reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0); | ||
1097 | reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE; | ||
1098 | writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0); | ||
1099 | } | ||
1100 | |||
1101 | static __init void tegra124_periph_clk_init(void __iomem *clk_base, | ||
1102 | void __iomem *pmc_base) | ||
1103 | { | ||
1104 | struct clk *clk; | ||
1105 | u32 val; | ||
1106 | |||
1107 | /* xusb_hs_src */ | ||
1108 | val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC); | ||
1109 | val |= BIT(25); /* always select PLLU_60M */ | ||
1110 | writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC); | ||
1111 | |||
1112 | clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0, | ||
1113 | 1, 1); | ||
1114 | clks[TEGRA124_CLK_XUSB_HS_SRC] = clk; | ||
1115 | |||
1116 | /* dsia mux */ | ||
1117 | clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0, | ||
1118 | ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, | ||
1119 | clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock); | ||
1120 | clks[TEGRA124_CLK_DSIA_MUX] = clk; | ||
1121 | |||
1122 | /* dsib mux */ | ||
1123 | clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0, | ||
1124 | ARRAY_SIZE(mux_plld_out0_plld2_out0), 0, | ||
1125 | clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock); | ||
1126 | clks[TEGRA124_CLK_DSIB_MUX] = clk; | ||
1127 | |||
1128 | /* emc mux */ | ||
1129 | clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, | ||
1130 | ARRAY_SIZE(mux_pllmcp_clkm), 0, | ||
1131 | clk_base + CLK_SOURCE_EMC, | ||
1132 | 29, 3, 0, NULL); | ||
1133 | |||
1134 | /* cml0 */ | ||
1135 | clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, | ||
1136 | 0, 0, &pll_e_lock); | ||
1137 | clk_register_clkdev(clk, "cml0", NULL); | ||
1138 | clks[TEGRA124_CLK_CML0] = clk; | ||
1139 | |||
1140 | /* cml1 */ | ||
1141 | clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, | ||
1142 | 1, 0, &pll_e_lock); | ||
1143 | clk_register_clkdev(clk, "cml1", NULL); | ||
1144 | clks[TEGRA124_CLK_CML1] = clk; | ||
1145 | |||
1146 | tegra_periph_clk_init(clk_base, pmc_base, tegra124_clks, &pll_p_params); | ||
1147 | } | ||
1148 | |||
1149 | static void __init tegra124_pll_init(void __iomem *clk_base, | ||
1150 | void __iomem *pmc) | ||
1151 | { | ||
1152 | u32 val; | ||
1153 | struct clk *clk; | ||
1154 | |||
1155 | /* PLLC */ | ||
1156 | clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base, | ||
1157 | pmc, 0, &pll_c_params, NULL); | ||
1158 | clk_register_clkdev(clk, "pll_c", NULL); | ||
1159 | clks[TEGRA124_CLK_PLL_C] = clk; | ||
1160 | |||
1161 | /* PLLC_OUT1 */ | ||
1162 | clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", | ||
1163 | clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
1164 | 8, 8, 1, NULL); | ||
1165 | clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", | ||
1166 | clk_base + PLLC_OUT, 1, 0, | ||
1167 | CLK_SET_RATE_PARENT, 0, NULL); | ||
1168 | clk_register_clkdev(clk, "pll_c_out1", NULL); | ||
1169 | clks[TEGRA124_CLK_PLL_C_OUT1] = clk; | ||
1170 | |||
1171 | /* PLLC2 */ | ||
1172 | clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, | ||
1173 | &pll_c2_params, NULL); | ||
1174 | clk_register_clkdev(clk, "pll_c2", NULL); | ||
1175 | clks[TEGRA124_CLK_PLL_C2] = clk; | ||
1176 | |||
1177 | /* PLLC3 */ | ||
1178 | clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, | ||
1179 | &pll_c3_params, NULL); | ||
1180 | clk_register_clkdev(clk, "pll_c3", NULL); | ||
1181 | clks[TEGRA124_CLK_PLL_C3] = clk; | ||
1182 | |||
1183 | /* PLLM */ | ||
1184 | clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc, | ||
1185 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, | ||
1186 | &pll_m_params, NULL); | ||
1187 | clk_register_clkdev(clk, "pll_m", NULL); | ||
1188 | clks[TEGRA124_CLK_PLL_M] = clk; | ||
1189 | |||
1190 | /* PLLM_OUT1 */ | ||
1191 | clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", | ||
1192 | clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
1193 | 8, 8, 1, NULL); | ||
1194 | clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", | ||
1195 | clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | | ||
1196 | CLK_SET_RATE_PARENT, 0, NULL); | ||
1197 | clk_register_clkdev(clk, "pll_m_out1", NULL); | ||
1198 | clks[TEGRA124_CLK_PLL_M_OUT1] = clk; | ||
1199 | |||
1200 | /* PLLM_UD */ | ||
1201 | clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m", | ||
1202 | CLK_SET_RATE_PARENT, 1, 1); | ||
1203 | |||
1204 | /* PLLU */ | ||
1205 | val = readl(clk_base + pll_u_params.base_reg); | ||
1206 | val &= ~BIT(24); /* disable PLLU_OVERRIDE */ | ||
1207 | writel(val, clk_base + pll_u_params.base_reg); | ||
1208 | |||
1209 | clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0, | ||
1210 | &pll_u_params, &pll_u_lock); | ||
1211 | clk_register_clkdev(clk, "pll_u", NULL); | ||
1212 | clks[TEGRA124_CLK_PLL_U] = clk; | ||
1213 | |||
1214 | tegra124_utmi_param_configure(clk_base); | ||
1215 | |||
1216 | /* PLLU_480M */ | ||
1217 | clk = clk_register_gate(NULL, "pll_u_480M", "pll_u", | ||
1218 | CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, | ||
1219 | 22, 0, &pll_u_lock); | ||
1220 | clk_register_clkdev(clk, "pll_u_480M", NULL); | ||
1221 | clks[TEGRA124_CLK_PLL_U_480M] = clk; | ||
1222 | |||
1223 | /* PLLU_60M */ | ||
1224 | clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u", | ||
1225 | CLK_SET_RATE_PARENT, 1, 8); | ||
1226 | clk_register_clkdev(clk, "pll_u_60M", NULL); | ||
1227 | clks[TEGRA124_CLK_PLL_U_60M] = clk; | ||
1228 | |||
1229 | /* PLLU_48M */ | ||
1230 | clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u", | ||
1231 | CLK_SET_RATE_PARENT, 1, 10); | ||
1232 | clk_register_clkdev(clk, "pll_u_48M", NULL); | ||
1233 | clks[TEGRA124_CLK_PLL_U_48M] = clk; | ||
1234 | |||
1235 | /* PLLU_12M */ | ||
1236 | clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u", | ||
1237 | CLK_SET_RATE_PARENT, 1, 40); | ||
1238 | clk_register_clkdev(clk, "pll_u_12M", NULL); | ||
1239 | clks[TEGRA124_CLK_PLL_U_12M] = clk; | ||
1240 | |||
1241 | /* PLLD */ | ||
1242 | clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0, | ||
1243 | &pll_d_params, &pll_d_lock); | ||
1244 | clk_register_clkdev(clk, "pll_d", NULL); | ||
1245 | clks[TEGRA124_CLK_PLL_D] = clk; | ||
1246 | |||
1247 | /* PLLD_OUT0 */ | ||
1248 | clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", | ||
1249 | CLK_SET_RATE_PARENT, 1, 2); | ||
1250 | clk_register_clkdev(clk, "pll_d_out0", NULL); | ||
1251 | clks[TEGRA124_CLK_PLL_D_OUT0] = clk; | ||
1252 | |||
1253 | /* PLLRE */ | ||
1254 | clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, | ||
1255 | 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); | ||
1256 | clk_register_clkdev(clk, "pll_re_vco", NULL); | ||
1257 | clks[TEGRA124_CLK_PLL_RE_VCO] = clk; | ||
1258 | |||
1259 | clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0, | ||
1260 | clk_base + PLLRE_BASE, 16, 4, 0, | ||
1261 | pll_re_div_table, &pll_re_lock); | ||
1262 | clk_register_clkdev(clk, "pll_re_out", NULL); | ||
1263 | clks[TEGRA124_CLK_PLL_RE_OUT] = clk; | ||
1264 | |||
1265 | /* PLLE */ | ||
1266 | clk = tegra_clk_register_plle_tegra114("pll_e", "pll_ref", | ||
1267 | clk_base, 0, &pll_e_params, NULL); | ||
1268 | clk_register_clkdev(clk, "pll_e", NULL); | ||
1269 | clks[TEGRA124_CLK_PLL_E] = clk; | ||
1270 | |||
1271 | /* PLLC4 */ | ||
1272 | clk = tegra_clk_register_pllss("pll_c4", "pll_ref", clk_base, 0, | ||
1273 | &pll_c4_params, NULL); | ||
1274 | clk_register_clkdev(clk, "pll_c4", NULL); | ||
1275 | clks[TEGRA124_CLK_PLL_C4] = clk; | ||
1276 | |||
1277 | /* PLLDP */ | ||
1278 | clk = tegra_clk_register_pllss("pll_dp", "pll_ref", clk_base, 0, | ||
1279 | &pll_dp_params, NULL); | ||
1280 | clk_register_clkdev(clk, "pll_dp", NULL); | ||
1281 | clks[TEGRA124_CLK_PLL_DP] = clk; | ||
1282 | |||
1283 | /* PLLD2 */ | ||
1284 | clk = tegra_clk_register_pllss("pll_d2", "pll_ref", clk_base, 0, | ||
1285 | &tegra124_pll_d2_params, NULL); | ||
1286 | clk_register_clkdev(clk, "pll_d2", NULL); | ||
1287 | clks[TEGRA124_CLK_PLL_D2] = clk; | ||
1288 | |||
1289 | /* PLLD2_OUT0 ?? */ | ||
1290 | clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", | ||
1291 | CLK_SET_RATE_PARENT, 1, 2); | ||
1292 | clk_register_clkdev(clk, "pll_d2_out0", NULL); | ||
1293 | clks[TEGRA124_CLK_PLL_D2_OUT0] = clk; | ||
1294 | |||
1295 | } | ||
1296 | |||
1297 | /* Tegra124 CPU clock and reset control functions */ | ||
1298 | static void tegra124_wait_cpu_in_reset(u32 cpu) | ||
1299 | { | ||
1300 | unsigned int reg; | ||
1301 | |||
1302 | do { | ||
1303 | reg = readl(clk_base + CLK_RST_CONTROLLER_CPU_CMPLX_STATUS); | ||
1304 | cpu_relax(); | ||
1305 | } while (!(reg & (1 << cpu))); /* check CPU been reset or not */ | ||
1306 | } | ||
1307 | |||
1308 | static void tegra124_disable_cpu_clock(u32 cpu) | ||
1309 | { | ||
1310 | /* flow controller would take care in the power sequence. */ | ||
1311 | } | ||
1312 | |||
1313 | #ifdef CONFIG_PM_SLEEP | ||
1314 | static void tegra124_cpu_clock_suspend(void) | ||
1315 | { | ||
1316 | /* switch coresite to clk_m, save off original source */ | ||
1317 | tegra124_cpu_clk_sctx.clk_csite_src = | ||
1318 | readl(clk_base + CLK_SOURCE_CSITE); | ||
1319 | writel(3 << 30, clk_base + CLK_SOURCE_CSITE); | ||
1320 | } | ||
1321 | |||
1322 | static void tegra124_cpu_clock_resume(void) | ||
1323 | { | ||
1324 | writel(tegra124_cpu_clk_sctx.clk_csite_src, | ||
1325 | clk_base + CLK_SOURCE_CSITE); | ||
1326 | } | ||
1327 | #endif | ||
1328 | |||
1329 | static struct tegra_cpu_car_ops tegra124_cpu_car_ops = { | ||
1330 | .wait_for_reset = tegra124_wait_cpu_in_reset, | ||
1331 | .disable_clock = tegra124_disable_cpu_clock, | ||
1332 | #ifdef CONFIG_PM_SLEEP | ||
1333 | .suspend = tegra124_cpu_clock_suspend, | ||
1334 | .resume = tegra124_cpu_clock_resume, | ||
1335 | #endif | ||
1336 | }; | ||
1337 | |||
1338 | static const struct of_device_id pmc_match[] __initconst = { | ||
1339 | { .compatible = "nvidia,tegra124-pmc" }, | ||
1340 | {}, | ||
1341 | }; | ||
1342 | |||
1343 | static struct tegra_clk_init_table init_table[] __initdata = { | ||
1344 | {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0}, | ||
1345 | {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0}, | ||
1346 | {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0}, | ||
1347 | {TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 408000000, 0}, | ||
1348 | {TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 1}, | ||
1349 | {TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 1}, | ||
1350 | {TEGRA124_CLK_EXTERN1, TEGRA124_CLK_PLL_A_OUT0, 0, 1}, | ||
1351 | {TEGRA124_CLK_CLK_OUT_1_MUX, TEGRA124_CLK_EXTERN1, 0, 1}, | ||
1352 | {TEGRA124_CLK_CLK_OUT_1, TEGRA124_CLK_CLK_MAX, 0, 1}, | ||
1353 | {TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, | ||
1354 | {TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, | ||
1355 | {TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, | ||
1356 | {TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, | ||
1357 | {TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0}, | ||
1358 | {TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_P, 0, 0}, | ||
1359 | {TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1}, | ||
1360 | {TEGRA124_CLK_SCLK, TEGRA124_CLK_PLL_P_OUT2, 102000000, 1}, | ||
1361 | {TEGRA124_CLK_DFLL_SOC, TEGRA124_CLK_PLL_P, 51000000, 1}, | ||
1362 | {TEGRA124_CLK_DFLL_REF, TEGRA124_CLK_PLL_P, 51000000, 1}, | ||
1363 | {TEGRA124_CLK_PLL_C, TEGRA124_CLK_CLK_MAX, 768000000, 0}, | ||
1364 | {TEGRA124_CLK_PLL_C_OUT1, TEGRA124_CLK_CLK_MAX, 100000000, 0}, | ||
1365 | {TEGRA124_CLK_SBC4, TEGRA124_CLK_PLL_P, 12000000, 1}, | ||
1366 | {TEGRA124_CLK_TSEC, TEGRA124_CLK_PLL_C3, 0, 0}, | ||
1367 | {TEGRA124_CLK_MSENC, TEGRA124_CLK_PLL_C3, 0, 0}, | ||
1368 | /* This MUST be the last entry. */ | ||
1369 | {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, | ||
1370 | }; | ||
1371 | |||
1372 | static void __init tegra124_clock_apply_init_table(void) | ||
1373 | { | ||
1374 | tegra_init_from_table(init_table, clks, TEGRA124_CLK_CLK_MAX); | ||
1375 | } | ||
1376 | |||
1377 | static void __init tegra124_clock_init(struct device_node *np) | ||
1378 | { | ||
1379 | struct device_node *node; | ||
1380 | |||
1381 | clk_base = of_iomap(np, 0); | ||
1382 | if (!clk_base) { | ||
1383 | pr_err("ioremap tegra124 CAR failed\n"); | ||
1384 | return; | ||
1385 | } | ||
1386 | |||
1387 | node = of_find_matching_node(NULL, pmc_match); | ||
1388 | if (!node) { | ||
1389 | pr_err("Failed to find pmc node\n"); | ||
1390 | WARN_ON(1); | ||
1391 | return; | ||
1392 | } | ||
1393 | |||
1394 | pmc_base = of_iomap(node, 0); | ||
1395 | if (!pmc_base) { | ||
1396 | pr_err("Can't map pmc registers\n"); | ||
1397 | WARN_ON(1); | ||
1398 | return; | ||
1399 | } | ||
1400 | |||
1401 | clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX, 6); | ||
1402 | if (!clks) | ||
1403 | return; | ||
1404 | |||
1405 | if (tegra_osc_clk_init(clk_base, tegra124_clks, tegra124_input_freq, | ||
1406 | ARRAY_SIZE(tegra124_input_freq), &osc_freq, &pll_ref_freq) < 0) | ||
1407 | return; | ||
1408 | |||
1409 | tegra_fixed_clk_init(tegra124_clks); | ||
1410 | tegra124_pll_init(clk_base, pmc_base); | ||
1411 | tegra124_periph_clk_init(clk_base, pmc_base); | ||
1412 | tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params); | ||
1413 | tegra_pmc_clk_init(pmc_base, tegra124_clks); | ||
1414 | |||
1415 | tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks, | ||
1416 | &pll_x_params); | ||
1417 | tegra_add_of_provider(np); | ||
1418 | tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); | ||
1419 | |||
1420 | tegra_clk_apply_init_table = tegra124_clock_apply_init_table; | ||
1421 | |||
1422 | tegra_cpu_car_ops = &tegra124_cpu_car_ops; | ||
1423 | } | ||
1424 | CLK_OF_DECLARE(tegra124, "nvidia,tegra124-car", tegra124_clock_init); | ||
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 056f649d0d89..dbace152b2fa 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c | |||
@@ -22,30 +22,10 @@ | |||
22 | #include <linux/of_address.h> | 22 | #include <linux/of_address.h> |
23 | #include <linux/clk/tegra.h> | 23 | #include <linux/clk/tegra.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <dt-bindings/clock/tegra20-car.h> | ||
25 | 26 | ||
26 | #include "clk.h" | 27 | #include "clk.h" |
27 | 28 | #include "clk-id.h" | |
28 | #define RST_DEVICES_L 0x004 | ||
29 | #define RST_DEVICES_H 0x008 | ||
30 | #define RST_DEVICES_U 0x00c | ||
31 | #define RST_DEVICES_SET_L 0x300 | ||
32 | #define RST_DEVICES_CLR_L 0x304 | ||
33 | #define RST_DEVICES_SET_H 0x308 | ||
34 | #define RST_DEVICES_CLR_H 0x30c | ||
35 | #define RST_DEVICES_SET_U 0x310 | ||
36 | #define RST_DEVICES_CLR_U 0x314 | ||
37 | #define RST_DEVICES_NUM 3 | ||
38 | |||
39 | #define CLK_OUT_ENB_L 0x010 | ||
40 | #define CLK_OUT_ENB_H 0x014 | ||
41 | #define CLK_OUT_ENB_U 0x018 | ||
42 | #define CLK_OUT_ENB_SET_L 0x320 | ||
43 | #define CLK_OUT_ENB_CLR_L 0x324 | ||
44 | #define CLK_OUT_ENB_SET_H 0x328 | ||
45 | #define CLK_OUT_ENB_CLR_H 0x32c | ||
46 | #define CLK_OUT_ENB_SET_U 0x330 | ||
47 | #define CLK_OUT_ENB_CLR_U 0x334 | ||
48 | #define CLK_OUT_ENB_NUM 3 | ||
49 | 29 | ||
50 | #define OSC_CTRL 0x50 | 30 | #define OSC_CTRL 0x50 |
51 | #define OSC_CTRL_OSC_FREQ_MASK (3<<30) | 31 | #define OSC_CTRL_OSC_FREQ_MASK (3<<30) |
@@ -67,6 +47,8 @@ | |||
67 | #define OSC_FREQ_DET_BUSY (1<<31) | 47 | #define OSC_FREQ_DET_BUSY (1<<31) |
68 | #define OSC_FREQ_DET_CNT_MASK 0xFFFF | 48 | #define OSC_FREQ_DET_CNT_MASK 0xFFFF |
69 | 49 | ||
50 | #define TEGRA20_CLK_PERIPH_BANKS 3 | ||
51 | |||
70 | #define PLLS_BASE 0xf0 | 52 | #define PLLS_BASE 0xf0 |
71 | #define PLLS_MISC 0xf4 | 53 | #define PLLS_MISC 0xf4 |
72 | #define PLLC_BASE 0x80 | 54 | #define PLLC_BASE 0x80 |
@@ -114,34 +96,15 @@ | |||
114 | 96 | ||
115 | #define CLK_SOURCE_I2S1 0x100 | 97 | #define CLK_SOURCE_I2S1 0x100 |
116 | #define CLK_SOURCE_I2S2 0x104 | 98 | #define CLK_SOURCE_I2S2 0x104 |
117 | #define CLK_SOURCE_SPDIF_OUT 0x108 | ||
118 | #define CLK_SOURCE_SPDIF_IN 0x10c | ||
119 | #define CLK_SOURCE_PWM 0x110 | 99 | #define CLK_SOURCE_PWM 0x110 |
120 | #define CLK_SOURCE_SPI 0x114 | 100 | #define CLK_SOURCE_SPI 0x114 |
121 | #define CLK_SOURCE_SBC1 0x134 | ||
122 | #define CLK_SOURCE_SBC2 0x118 | ||
123 | #define CLK_SOURCE_SBC3 0x11c | ||
124 | #define CLK_SOURCE_SBC4 0x1b4 | ||
125 | #define CLK_SOURCE_XIO 0x120 | 101 | #define CLK_SOURCE_XIO 0x120 |
126 | #define CLK_SOURCE_TWC 0x12c | 102 | #define CLK_SOURCE_TWC 0x12c |
127 | #define CLK_SOURCE_IDE 0x144 | 103 | #define CLK_SOURCE_IDE 0x144 |
128 | #define CLK_SOURCE_NDFLASH 0x160 | ||
129 | #define CLK_SOURCE_VFIR 0x168 | ||
130 | #define CLK_SOURCE_SDMMC1 0x150 | ||
131 | #define CLK_SOURCE_SDMMC2 0x154 | ||
132 | #define CLK_SOURCE_SDMMC3 0x1bc | ||
133 | #define CLK_SOURCE_SDMMC4 0x164 | ||
134 | #define CLK_SOURCE_CVE 0x140 | ||
135 | #define CLK_SOURCE_TVO 0x188 | ||
136 | #define CLK_SOURCE_TVDAC 0x194 | ||
137 | #define CLK_SOURCE_HDMI 0x18c | 104 | #define CLK_SOURCE_HDMI 0x18c |
138 | #define CLK_SOURCE_DISP1 0x138 | 105 | #define CLK_SOURCE_DISP1 0x138 |
139 | #define CLK_SOURCE_DISP2 0x13c | 106 | #define CLK_SOURCE_DISP2 0x13c |
140 | #define CLK_SOURCE_CSITE 0x1d4 | 107 | #define CLK_SOURCE_CSITE 0x1d4 |
141 | #define CLK_SOURCE_LA 0x1f8 | ||
142 | #define CLK_SOURCE_OWR 0x1cc | ||
143 | #define CLK_SOURCE_NOR 0x1d0 | ||
144 | #define CLK_SOURCE_MIPI 0x174 | ||
145 | #define CLK_SOURCE_I2C1 0x124 | 108 | #define CLK_SOURCE_I2C1 0x124 |
146 | #define CLK_SOURCE_I2C2 0x198 | 109 | #define CLK_SOURCE_I2C2 0x198 |
147 | #define CLK_SOURCE_I2C3 0x1b8 | 110 | #define CLK_SOURCE_I2C3 0x1b8 |
@@ -151,24 +114,10 @@ | |||
151 | #define CLK_SOURCE_UARTC 0x1a0 | 114 | #define CLK_SOURCE_UARTC 0x1a0 |
152 | #define CLK_SOURCE_UARTD 0x1c0 | 115 | #define CLK_SOURCE_UARTD 0x1c0 |
153 | #define CLK_SOURCE_UARTE 0x1c4 | 116 | #define CLK_SOURCE_UARTE 0x1c4 |
154 | #define CLK_SOURCE_3D 0x158 | ||
155 | #define CLK_SOURCE_2D 0x15c | ||
156 | #define CLK_SOURCE_MPE 0x170 | ||
157 | #define CLK_SOURCE_EPP 0x16c | ||
158 | #define CLK_SOURCE_HOST1X 0x180 | ||
159 | #define CLK_SOURCE_VDE 0x1c8 | ||
160 | #define CLK_SOURCE_VI 0x148 | ||
161 | #define CLK_SOURCE_VI_SENSOR 0x1a8 | ||
162 | #define CLK_SOURCE_EMC 0x19c | 117 | #define CLK_SOURCE_EMC 0x19c |
163 | 118 | ||
164 | #define AUDIO_SYNC_CLK 0x38 | 119 | #define AUDIO_SYNC_CLK 0x38 |
165 | 120 | ||
166 | #define PMC_CTRL 0x0 | ||
167 | #define PMC_CTRL_BLINK_ENB 7 | ||
168 | #define PMC_DPD_PADS_ORIDE 0x1c | ||
169 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 | ||
170 | #define PMC_BLINK_TIMER 0x40 | ||
171 | |||
172 | /* Tegra CPU clock and reset control regs */ | 121 | /* Tegra CPU clock and reset control regs */ |
173 | #define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c | 122 | #define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c |
174 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340 | 123 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340 |
@@ -188,64 +137,32 @@ static struct cpu_clk_suspend_context { | |||
188 | } tegra20_cpu_clk_sctx; | 137 | } tegra20_cpu_clk_sctx; |
189 | #endif | 138 | #endif |
190 | 139 | ||
191 | static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; | ||
192 | |||
193 | static void __iomem *clk_base; | 140 | static void __iomem *clk_base; |
194 | static void __iomem *pmc_base; | 141 | static void __iomem *pmc_base; |
195 | 142 | ||
196 | static DEFINE_SPINLOCK(pll_div_lock); | 143 | #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ |
197 | static DEFINE_SPINLOCK(sysrate_lock); | 144 | _clk_num, _gate_flags, _clk_id) \ |
198 | 145 | TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ | |
199 | #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ | ||
200 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
201 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
202 | 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ | 146 | 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ |
203 | _regs, _clk_num, periph_clk_enb_refcnt, \ | 147 | _clk_num, \ |
204 | _gate_flags, _clk_id) | 148 | _gate_flags, _clk_id) |
205 | 149 | ||
206 | #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ | 150 | #define TEGRA_INIT_DATA_DIV16(_name, _parents, _offset, \ |
207 | _clk_num, _regs, _gate_flags, _clk_id) \ | 151 | _clk_num, _gate_flags, _clk_id) \ |
208 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | 152 | TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ |
209 | 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ | 153 | 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ |
210 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | 154 | _clk_num, _gate_flags, \ |
211 | _clk_id) | ||
212 | |||
213 | #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ | ||
214 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
215 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
216 | 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, _regs, \ | ||
217 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
218 | _clk_id) | 155 | _clk_id) |
219 | 156 | ||
220 | #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ | 157 | #define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \ |
221 | _mux_shift, _mux_width, _clk_num, _regs, \ | 158 | _mux_shift, _mux_width, _clk_num, \ |
222 | _gate_flags, _clk_id) \ | 159 | _gate_flags, _clk_id) \ |
223 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | 160 | TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ |
224 | _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ | 161 | _mux_shift, _mux_width, 0, 0, 0, 0, 0, \ |
225 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | 162 | _clk_num, _gate_flags, \ |
226 | _clk_id) | 163 | _clk_id) |
227 | 164 | ||
228 | /* IDs assigned here must be in sync with DT bindings definition | 165 | static struct clk **clks; |
229 | * for Tegra20 clocks . | ||
230 | */ | ||
231 | enum tegra20_clk { | ||
232 | cpu, ac97 = 3, rtc, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1, | ||
233 | ndflash, sdmmc1, sdmmc4, twc, pwm, i2s2, epp, gr2d = 21, usbd, isp, | ||
234 | gr3d, ide, disp2, disp1, host1x, vcp, cache2 = 31, mem, ahbdma, apbdma, | ||
235 | kbc = 36, stat_mon, pmc, fuse, kfuse, sbc1, nor, spi, sbc2, xio, sbc3, | ||
236 | dvc, dsi, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2, | ||
237 | usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3, | ||
238 | pex, owr, afi, csite, pcie_xclk, avpucq = 75, la, irama = 84, iramb, | ||
239 | iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev2, cdev1, | ||
240 | uartb = 96, vfir, spdif_in, spdif_out, vi, vi_sensor, tvo, cve, | ||
241 | osc, clk_32k, clk_m, sclk, cclk, hclk, pclk, blink, pll_a, pll_a_out0, | ||
242 | pll_c, pll_c_out1, pll_d, pll_d_out0, pll_e, pll_m, pll_m_out1, | ||
243 | pll_p, pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_s, pll_u, | ||
244 | pll_x, cop, audio, pll_ref, twd, clk_max, | ||
245 | }; | ||
246 | |||
247 | static struct clk *clks[clk_max]; | ||
248 | static struct clk_onecell_data clk_data; | ||
249 | 166 | ||
250 | static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { | 167 | static struct tegra_clk_pll_freq_table pll_c_freq_table[] = { |
251 | { 12000000, 600000000, 600, 12, 0, 8 }, | 168 | { 12000000, 600000000, 600, 12, 0, 8 }, |
@@ -383,6 +300,8 @@ static struct tegra_clk_pll_params pll_c_params = { | |||
383 | .lock_mask = PLL_BASE_LOCK, | 300 | .lock_mask = PLL_BASE_LOCK, |
384 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 301 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
385 | .lock_delay = 300, | 302 | .lock_delay = 300, |
303 | .freq_table = pll_c_freq_table, | ||
304 | .flags = TEGRA_PLL_HAS_CPCON, | ||
386 | }; | 305 | }; |
387 | 306 | ||
388 | static struct tegra_clk_pll_params pll_m_params = { | 307 | static struct tegra_clk_pll_params pll_m_params = { |
@@ -397,6 +316,8 @@ static struct tegra_clk_pll_params pll_m_params = { | |||
397 | .lock_mask = PLL_BASE_LOCK, | 316 | .lock_mask = PLL_BASE_LOCK, |
398 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 317 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
399 | .lock_delay = 300, | 318 | .lock_delay = 300, |
319 | .freq_table = pll_m_freq_table, | ||
320 | .flags = TEGRA_PLL_HAS_CPCON, | ||
400 | }; | 321 | }; |
401 | 322 | ||
402 | static struct tegra_clk_pll_params pll_p_params = { | 323 | static struct tegra_clk_pll_params pll_p_params = { |
@@ -411,6 +332,9 @@ static struct tegra_clk_pll_params pll_p_params = { | |||
411 | .lock_mask = PLL_BASE_LOCK, | 332 | .lock_mask = PLL_BASE_LOCK, |
412 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 333 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
413 | .lock_delay = 300, | 334 | .lock_delay = 300, |
335 | .freq_table = pll_p_freq_table, | ||
336 | .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON, | ||
337 | .fixed_rate = 216000000, | ||
414 | }; | 338 | }; |
415 | 339 | ||
416 | static struct tegra_clk_pll_params pll_a_params = { | 340 | static struct tegra_clk_pll_params pll_a_params = { |
@@ -425,6 +349,8 @@ static struct tegra_clk_pll_params pll_a_params = { | |||
425 | .lock_mask = PLL_BASE_LOCK, | 349 | .lock_mask = PLL_BASE_LOCK, |
426 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 350 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
427 | .lock_delay = 300, | 351 | .lock_delay = 300, |
352 | .freq_table = pll_a_freq_table, | ||
353 | .flags = TEGRA_PLL_HAS_CPCON, | ||
428 | }; | 354 | }; |
429 | 355 | ||
430 | static struct tegra_clk_pll_params pll_d_params = { | 356 | static struct tegra_clk_pll_params pll_d_params = { |
@@ -439,6 +365,8 @@ static struct tegra_clk_pll_params pll_d_params = { | |||
439 | .lock_mask = PLL_BASE_LOCK, | 365 | .lock_mask = PLL_BASE_LOCK, |
440 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 366 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
441 | .lock_delay = 1000, | 367 | .lock_delay = 1000, |
368 | .freq_table = pll_d_freq_table, | ||
369 | .flags = TEGRA_PLL_HAS_CPCON, | ||
442 | }; | 370 | }; |
443 | 371 | ||
444 | static struct pdiv_map pllu_p[] = { | 372 | static struct pdiv_map pllu_p[] = { |
@@ -460,6 +388,8 @@ static struct tegra_clk_pll_params pll_u_params = { | |||
460 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 388 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
461 | .lock_delay = 1000, | 389 | .lock_delay = 1000, |
462 | .pdiv_tohw = pllu_p, | 390 | .pdiv_tohw = pllu_p, |
391 | .freq_table = pll_u_freq_table, | ||
392 | .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON, | ||
463 | }; | 393 | }; |
464 | 394 | ||
465 | static struct tegra_clk_pll_params pll_x_params = { | 395 | static struct tegra_clk_pll_params pll_x_params = { |
@@ -474,6 +404,8 @@ static struct tegra_clk_pll_params pll_x_params = { | |||
474 | .lock_mask = PLL_BASE_LOCK, | 404 | .lock_mask = PLL_BASE_LOCK, |
475 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 405 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
476 | .lock_delay = 300, | 406 | .lock_delay = 300, |
407 | .freq_table = pll_x_freq_table, | ||
408 | .flags = TEGRA_PLL_HAS_CPCON, | ||
477 | }; | 409 | }; |
478 | 410 | ||
479 | static struct tegra_clk_pll_params pll_e_params = { | 411 | static struct tegra_clk_pll_params pll_e_params = { |
@@ -488,34 +420,160 @@ static struct tegra_clk_pll_params pll_e_params = { | |||
488 | .lock_mask = PLLE_MISC_LOCK, | 420 | .lock_mask = PLLE_MISC_LOCK, |
489 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, | 421 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, |
490 | .lock_delay = 0, | 422 | .lock_delay = 0, |
423 | .freq_table = pll_e_freq_table, | ||
424 | .flags = TEGRA_PLL_FIXED, | ||
425 | .fixed_rate = 100000000, | ||
491 | }; | 426 | }; |
492 | 427 | ||
493 | /* Peripheral clock registers */ | 428 | static struct tegra_devclk devclks[] __initdata = { |
494 | static struct tegra_clk_periph_regs periph_l_regs = { | 429 | { .con_id = "pll_c", .dt_id = TEGRA20_CLK_PLL_C }, |
495 | .enb_reg = CLK_OUT_ENB_L, | 430 | { .con_id = "pll_c_out1", .dt_id = TEGRA20_CLK_PLL_C_OUT1 }, |
496 | .enb_set_reg = CLK_OUT_ENB_SET_L, | 431 | { .con_id = "pll_p", .dt_id = TEGRA20_CLK_PLL_P }, |
497 | .enb_clr_reg = CLK_OUT_ENB_CLR_L, | 432 | { .con_id = "pll_p_out1", .dt_id = TEGRA20_CLK_PLL_P_OUT1 }, |
498 | .rst_reg = RST_DEVICES_L, | 433 | { .con_id = "pll_p_out2", .dt_id = TEGRA20_CLK_PLL_P_OUT2 }, |
499 | .rst_set_reg = RST_DEVICES_SET_L, | 434 | { .con_id = "pll_p_out3", .dt_id = TEGRA20_CLK_PLL_P_OUT3 }, |
500 | .rst_clr_reg = RST_DEVICES_CLR_L, | 435 | { .con_id = "pll_p_out4", .dt_id = TEGRA20_CLK_PLL_P_OUT4 }, |
501 | }; | 436 | { .con_id = "pll_m", .dt_id = TEGRA20_CLK_PLL_M }, |
502 | 437 | { .con_id = "pll_m_out1", .dt_id = TEGRA20_CLK_PLL_M_OUT1 }, | |
503 | static struct tegra_clk_periph_regs periph_h_regs = { | 438 | { .con_id = "pll_x", .dt_id = TEGRA20_CLK_PLL_X }, |
504 | .enb_reg = CLK_OUT_ENB_H, | 439 | { .con_id = "pll_u", .dt_id = TEGRA20_CLK_PLL_U }, |
505 | .enb_set_reg = CLK_OUT_ENB_SET_H, | 440 | { .con_id = "pll_d", .dt_id = TEGRA20_CLK_PLL_D }, |
506 | .enb_clr_reg = CLK_OUT_ENB_CLR_H, | 441 | { .con_id = "pll_d_out0", .dt_id = TEGRA20_CLK_PLL_D_OUT0 }, |
507 | .rst_reg = RST_DEVICES_H, | 442 | { .con_id = "pll_a", .dt_id = TEGRA20_CLK_PLL_A }, |
508 | .rst_set_reg = RST_DEVICES_SET_H, | 443 | { .con_id = "pll_a_out0", .dt_id = TEGRA20_CLK_PLL_A_OUT0 }, |
509 | .rst_clr_reg = RST_DEVICES_CLR_H, | 444 | { .con_id = "pll_e", .dt_id = TEGRA20_CLK_PLL_E }, |
445 | { .con_id = "cclk", .dt_id = TEGRA20_CLK_CCLK }, | ||
446 | { .con_id = "sclk", .dt_id = TEGRA20_CLK_SCLK }, | ||
447 | { .con_id = "hclk", .dt_id = TEGRA20_CLK_HCLK }, | ||
448 | { .con_id = "pclk", .dt_id = TEGRA20_CLK_PCLK }, | ||
449 | { .con_id = "fuse", .dt_id = TEGRA20_CLK_FUSE }, | ||
450 | { .con_id = "twd", .dt_id = TEGRA20_CLK_TWD }, | ||
451 | { .con_id = "audio", .dt_id = TEGRA20_CLK_AUDIO }, | ||
452 | { .con_id = "audio_2x", .dt_id = TEGRA20_CLK_AUDIO_2X }, | ||
453 | { .dev_id = "tegra20-ac97", .dt_id = TEGRA20_CLK_AC97 }, | ||
454 | { .dev_id = "tegra-apbdma", .dt_id = TEGRA20_CLK_APBDMA }, | ||
455 | { .dev_id = "rtc-tegra", .dt_id = TEGRA20_CLK_RTC }, | ||
456 | { .dev_id = "timer", .dt_id = TEGRA20_CLK_TIMER }, | ||
457 | { .dev_id = "tegra-kbc", .dt_id = TEGRA20_CLK_KBC }, | ||
458 | { .con_id = "csus", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_CSUS }, | ||
459 | { .con_id = "vcp", .dev_id = "tegra-avp", .dt_id = TEGRA20_CLK_VCP }, | ||
460 | { .con_id = "bsea", .dev_id = "tegra-avp", .dt_id = TEGRA20_CLK_BSEA }, | ||
461 | { .con_id = "bsev", .dev_id = "tegra-aes", .dt_id = TEGRA20_CLK_BSEV }, | ||
462 | { .con_id = "emc", .dt_id = TEGRA20_CLK_EMC }, | ||
463 | { .dev_id = "fsl-tegra-udc", .dt_id = TEGRA20_CLK_USBD }, | ||
464 | { .dev_id = "tegra-ehci.1", .dt_id = TEGRA20_CLK_USB2 }, | ||
465 | { .dev_id = "tegra-ehci.2", .dt_id = TEGRA20_CLK_USB3 }, | ||
466 | { .dev_id = "dsi", .dt_id = TEGRA20_CLK_DSI }, | ||
467 | { .con_id = "csi", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_CSI }, | ||
468 | { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_ISP }, | ||
469 | { .con_id = "pex", .dt_id = TEGRA20_CLK_PEX }, | ||
470 | { .con_id = "afi", .dt_id = TEGRA20_CLK_AFI }, | ||
471 | { .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 }, | ||
472 | { .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 }, | ||
473 | { .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K }, | ||
474 | { .con_id = "blink", .dt_id = TEGRA20_CLK_BLINK }, | ||
475 | { .con_id = "clk_m", .dt_id = TEGRA20_CLK_CLK_M }, | ||
476 | { .con_id = "pll_ref", .dt_id = TEGRA20_CLK_PLL_REF }, | ||
477 | { .dev_id = "tegra20-i2s.0", .dt_id = TEGRA20_CLK_I2S1 }, | ||
478 | { .dev_id = "tegra20-i2s.1", .dt_id = TEGRA20_CLK_I2S2 }, | ||
479 | { .con_id = "spdif_out", .dev_id = "tegra20-spdif", .dt_id = TEGRA20_CLK_SPDIF_OUT }, | ||
480 | { .con_id = "spdif_in", .dev_id = "tegra20-spdif", .dt_id = TEGRA20_CLK_SPDIF_IN }, | ||
481 | { .dev_id = "spi_tegra.0", .dt_id = TEGRA20_CLK_SBC1 }, | ||
482 | { .dev_id = "spi_tegra.1", .dt_id = TEGRA20_CLK_SBC2 }, | ||
483 | { .dev_id = "spi_tegra.2", .dt_id = TEGRA20_CLK_SBC3 }, | ||
484 | { .dev_id = "spi_tegra.3", .dt_id = TEGRA20_CLK_SBC4 }, | ||
485 | { .dev_id = "spi", .dt_id = TEGRA20_CLK_SPI }, | ||
486 | { .dev_id = "xio", .dt_id = TEGRA20_CLK_XIO }, | ||
487 | { .dev_id = "twc", .dt_id = TEGRA20_CLK_TWC }, | ||
488 | { .dev_id = "ide", .dt_id = TEGRA20_CLK_IDE }, | ||
489 | { .dev_id = "tegra_nand", .dt_id = TEGRA20_CLK_NDFLASH }, | ||
490 | { .dev_id = "vfir", .dt_id = TEGRA20_CLK_VFIR }, | ||
491 | { .dev_id = "csite", .dt_id = TEGRA20_CLK_CSITE }, | ||
492 | { .dev_id = "la", .dt_id = TEGRA20_CLK_LA }, | ||
493 | { .dev_id = "tegra_w1", .dt_id = TEGRA20_CLK_OWR }, | ||
494 | { .dev_id = "mipi", .dt_id = TEGRA20_CLK_MIPI }, | ||
495 | { .dev_id = "vde", .dt_id = TEGRA20_CLK_VDE }, | ||
496 | { .con_id = "vi", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_VI }, | ||
497 | { .dev_id = "epp", .dt_id = TEGRA20_CLK_EPP }, | ||
498 | { .dev_id = "mpe", .dt_id = TEGRA20_CLK_MPE }, | ||
499 | { .dev_id = "host1x", .dt_id = TEGRA20_CLK_HOST1X }, | ||
500 | { .dev_id = "3d", .dt_id = TEGRA20_CLK_GR3D }, | ||
501 | { .dev_id = "2d", .dt_id = TEGRA20_CLK_GR2D }, | ||
502 | { .dev_id = "tegra-nor", .dt_id = TEGRA20_CLK_NOR }, | ||
503 | { .dev_id = "sdhci-tegra.0", .dt_id = TEGRA20_CLK_SDMMC1 }, | ||
504 | { .dev_id = "sdhci-tegra.1", .dt_id = TEGRA20_CLK_SDMMC2 }, | ||
505 | { .dev_id = "sdhci-tegra.2", .dt_id = TEGRA20_CLK_SDMMC3 }, | ||
506 | { .dev_id = "sdhci-tegra.3", .dt_id = TEGRA20_CLK_SDMMC4 }, | ||
507 | { .dev_id = "cve", .dt_id = TEGRA20_CLK_CVE }, | ||
508 | { .dev_id = "tvo", .dt_id = TEGRA20_CLK_TVO }, | ||
509 | { .dev_id = "tvdac", .dt_id = TEGRA20_CLK_TVDAC }, | ||
510 | { .con_id = "vi_sensor", .dev_id = "tegra_camera", .dt_id = TEGRA20_CLK_VI_SENSOR }, | ||
511 | { .dev_id = "hdmi", .dt_id = TEGRA20_CLK_HDMI }, | ||
512 | { .con_id = "div-clk", .dev_id = "tegra-i2c.0", .dt_id = TEGRA20_CLK_I2C1 }, | ||
513 | { .con_id = "div-clk", .dev_id = "tegra-i2c.1", .dt_id = TEGRA20_CLK_I2C2 }, | ||
514 | { .con_id = "div-clk", .dev_id = "tegra-i2c.2", .dt_id = TEGRA20_CLK_I2C3 }, | ||
515 | { .con_id = "div-clk", .dev_id = "tegra-i2c.3", .dt_id = TEGRA20_CLK_DVC }, | ||
516 | { .dev_id = "tegra-pwm", .dt_id = TEGRA20_CLK_PWM }, | ||
517 | { .dev_id = "tegra_uart.0", .dt_id = TEGRA20_CLK_UARTA }, | ||
518 | { .dev_id = "tegra_uart.1", .dt_id = TEGRA20_CLK_UARTB }, | ||
519 | { .dev_id = "tegra_uart.2", .dt_id = TEGRA20_CLK_UARTC }, | ||
520 | { .dev_id = "tegra_uart.3", .dt_id = TEGRA20_CLK_UARTD }, | ||
521 | { .dev_id = "tegra_uart.4", .dt_id = TEGRA20_CLK_UARTE }, | ||
522 | { .dev_id = "tegradc.0", .dt_id = TEGRA20_CLK_DISP1 }, | ||
523 | { .dev_id = "tegradc.1", .dt_id = TEGRA20_CLK_DISP2 }, | ||
510 | }; | 524 | }; |
511 | 525 | ||
512 | static struct tegra_clk_periph_regs periph_u_regs = { | 526 | static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = { |
513 | .enb_reg = CLK_OUT_ENB_U, | 527 | [tegra_clk_spdif_out] = { .dt_id = TEGRA20_CLK_SPDIF_OUT, .present = true }, |
514 | .enb_set_reg = CLK_OUT_ENB_SET_U, | 528 | [tegra_clk_spdif_in] = { .dt_id = TEGRA20_CLK_SPDIF_IN, .present = true }, |
515 | .enb_clr_reg = CLK_OUT_ENB_CLR_U, | 529 | [tegra_clk_sdmmc1] = { .dt_id = TEGRA20_CLK_SDMMC1, .present = true }, |
516 | .rst_reg = RST_DEVICES_U, | 530 | [tegra_clk_sdmmc2] = { .dt_id = TEGRA20_CLK_SDMMC2, .present = true }, |
517 | .rst_set_reg = RST_DEVICES_SET_U, | 531 | [tegra_clk_sdmmc3] = { .dt_id = TEGRA20_CLK_SDMMC3, .present = true }, |
518 | .rst_clr_reg = RST_DEVICES_CLR_U, | 532 | [tegra_clk_sdmmc4] = { .dt_id = TEGRA20_CLK_SDMMC4, .present = true }, |
533 | [tegra_clk_la] = { .dt_id = TEGRA20_CLK_LA, .present = true }, | ||
534 | [tegra_clk_csite] = { .dt_id = TEGRA20_CLK_CSITE, .present = true }, | ||
535 | [tegra_clk_vfir] = { .dt_id = TEGRA20_CLK_VFIR, .present = true }, | ||
536 | [tegra_clk_mipi] = { .dt_id = TEGRA20_CLK_MIPI, .present = true }, | ||
537 | [tegra_clk_nor] = { .dt_id = TEGRA20_CLK_NOR, .present = true }, | ||
538 | [tegra_clk_rtc] = { .dt_id = TEGRA20_CLK_RTC, .present = true }, | ||
539 | [tegra_clk_timer] = { .dt_id = TEGRA20_CLK_TIMER, .present = true }, | ||
540 | [tegra_clk_kbc] = { .dt_id = TEGRA20_CLK_KBC, .present = true }, | ||
541 | [tegra_clk_csus] = { .dt_id = TEGRA20_CLK_CSUS, .present = true }, | ||
542 | [tegra_clk_vcp] = { .dt_id = TEGRA20_CLK_VCP, .present = true }, | ||
543 | [tegra_clk_bsea] = { .dt_id = TEGRA20_CLK_BSEA, .present = true }, | ||
544 | [tegra_clk_bsev] = { .dt_id = TEGRA20_CLK_BSEV, .present = true }, | ||
545 | [tegra_clk_usbd] = { .dt_id = TEGRA20_CLK_USBD, .present = true }, | ||
546 | [tegra_clk_usb2] = { .dt_id = TEGRA20_CLK_USB2, .present = true }, | ||
547 | [tegra_clk_usb3] = { .dt_id = TEGRA20_CLK_USB3, .present = true }, | ||
548 | [tegra_clk_csi] = { .dt_id = TEGRA20_CLK_CSI, .present = true }, | ||
549 | [tegra_clk_isp] = { .dt_id = TEGRA20_CLK_ISP, .present = true }, | ||
550 | [tegra_clk_clk_32k] = { .dt_id = TEGRA20_CLK_CLK_32K, .present = true }, | ||
551 | [tegra_clk_blink] = { .dt_id = TEGRA20_CLK_BLINK, .present = true }, | ||
552 | [tegra_clk_hclk] = { .dt_id = TEGRA20_CLK_HCLK, .present = true }, | ||
553 | [tegra_clk_pclk] = { .dt_id = TEGRA20_CLK_PCLK, .present = true }, | ||
554 | [tegra_clk_pll_p_out1] = { .dt_id = TEGRA20_CLK_PLL_P_OUT1, .present = true }, | ||
555 | [tegra_clk_pll_p_out2] = { .dt_id = TEGRA20_CLK_PLL_P_OUT2, .present = true }, | ||
556 | [tegra_clk_pll_p_out3] = { .dt_id = TEGRA20_CLK_PLL_P_OUT3, .present = true }, | ||
557 | [tegra_clk_pll_p_out4] = { .dt_id = TEGRA20_CLK_PLL_P_OUT4, .present = true }, | ||
558 | [tegra_clk_pll_p] = { .dt_id = TEGRA20_CLK_PLL_P, .present = true }, | ||
559 | [tegra_clk_owr] = { .dt_id = TEGRA20_CLK_OWR, .present = true }, | ||
560 | [tegra_clk_sbc1] = { .dt_id = TEGRA20_CLK_SBC1, .present = true }, | ||
561 | [tegra_clk_sbc2] = { .dt_id = TEGRA20_CLK_SBC2, .present = true }, | ||
562 | [tegra_clk_sbc3] = { .dt_id = TEGRA20_CLK_SBC3, .present = true }, | ||
563 | [tegra_clk_sbc4] = { .dt_id = TEGRA20_CLK_SBC4, .present = true }, | ||
564 | [tegra_clk_vde] = { .dt_id = TEGRA20_CLK_VDE, .present = true }, | ||
565 | [tegra_clk_vi] = { .dt_id = TEGRA20_CLK_VI, .present = true }, | ||
566 | [tegra_clk_epp] = { .dt_id = TEGRA20_CLK_EPP, .present = true }, | ||
567 | [tegra_clk_mpe] = { .dt_id = TEGRA20_CLK_MPE, .present = true }, | ||
568 | [tegra_clk_host1x] = { .dt_id = TEGRA20_CLK_HOST1X, .present = true }, | ||
569 | [tegra_clk_gr2d] = { .dt_id = TEGRA20_CLK_GR2D, .present = true }, | ||
570 | [tegra_clk_gr3d] = { .dt_id = TEGRA20_CLK_GR3D, .present = true }, | ||
571 | [tegra_clk_ndflash] = { .dt_id = TEGRA20_CLK_NDFLASH, .present = true }, | ||
572 | [tegra_clk_cve] = { .dt_id = TEGRA20_CLK_CVE, .present = true }, | ||
573 | [tegra_clk_tvo] = { .dt_id = TEGRA20_CLK_TVO, .present = true }, | ||
574 | [tegra_clk_tvdac] = { .dt_id = TEGRA20_CLK_TVDAC, .present = true }, | ||
575 | [tegra_clk_vi_sensor] = { .dt_id = TEGRA20_CLK_VI_SENSOR, .present = true }, | ||
576 | [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, | ||
519 | }; | 577 | }; |
520 | 578 | ||
521 | static unsigned long tegra20_clk_measure_input_freq(void) | 579 | static unsigned long tegra20_clk_measure_input_freq(void) |
@@ -577,10 +635,8 @@ static void tegra20_pll_init(void) | |||
577 | 635 | ||
578 | /* PLLC */ | 636 | /* PLLC */ |
579 | clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, NULL, 0, | 637 | clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, NULL, 0, |
580 | 0, &pll_c_params, TEGRA_PLL_HAS_CPCON, | 638 | &pll_c_params, NULL); |
581 | pll_c_freq_table, NULL); | 639 | clks[TEGRA20_CLK_PLL_C] = clk; |
582 | clk_register_clkdev(clk, "pll_c", NULL); | ||
583 | clks[pll_c] = clk; | ||
584 | 640 | ||
585 | /* PLLC_OUT1 */ | 641 | /* PLLC_OUT1 */ |
586 | clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", | 642 | clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", |
@@ -589,71 +645,13 @@ static void tegra20_pll_init(void) | |||
589 | clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", | 645 | clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", |
590 | clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, | 646 | clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, |
591 | 0, NULL); | 647 | 0, NULL); |
592 | clk_register_clkdev(clk, "pll_c_out1", NULL); | 648 | clks[TEGRA20_CLK_PLL_C_OUT1] = clk; |
593 | clks[pll_c_out1] = clk; | ||
594 | |||
595 | /* PLLP */ | ||
596 | clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, NULL, 0, | ||
597 | 216000000, &pll_p_params, TEGRA_PLL_FIXED | | ||
598 | TEGRA_PLL_HAS_CPCON, pll_p_freq_table, NULL); | ||
599 | clk_register_clkdev(clk, "pll_p", NULL); | ||
600 | clks[pll_p] = clk; | ||
601 | |||
602 | /* PLLP_OUT1 */ | ||
603 | clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", | ||
604 | clk_base + PLLP_OUTA, 0, | ||
605 | TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, | ||
606 | 8, 8, 1, &pll_div_lock); | ||
607 | clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", | ||
608 | clk_base + PLLP_OUTA, 1, 0, | ||
609 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
610 | &pll_div_lock); | ||
611 | clk_register_clkdev(clk, "pll_p_out1", NULL); | ||
612 | clks[pll_p_out1] = clk; | ||
613 | |||
614 | /* PLLP_OUT2 */ | ||
615 | clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", | ||
616 | clk_base + PLLP_OUTA, 0, | ||
617 | TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, | ||
618 | 24, 8, 1, &pll_div_lock); | ||
619 | clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", | ||
620 | clk_base + PLLP_OUTA, 17, 16, | ||
621 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
622 | &pll_div_lock); | ||
623 | clk_register_clkdev(clk, "pll_p_out2", NULL); | ||
624 | clks[pll_p_out2] = clk; | ||
625 | |||
626 | /* PLLP_OUT3 */ | ||
627 | clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", | ||
628 | clk_base + PLLP_OUTB, 0, | ||
629 | TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, | ||
630 | 8, 8, 1, &pll_div_lock); | ||
631 | clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", | ||
632 | clk_base + PLLP_OUTB, 1, 0, | ||
633 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
634 | &pll_div_lock); | ||
635 | clk_register_clkdev(clk, "pll_p_out3", NULL); | ||
636 | clks[pll_p_out3] = clk; | ||
637 | |||
638 | /* PLLP_OUT4 */ | ||
639 | clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", | ||
640 | clk_base + PLLP_OUTB, 0, | ||
641 | TEGRA_DIVIDER_FIXED | TEGRA_DIVIDER_ROUND_UP, | ||
642 | 24, 8, 1, &pll_div_lock); | ||
643 | clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", | ||
644 | clk_base + PLLP_OUTB, 17, 16, | ||
645 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
646 | &pll_div_lock); | ||
647 | clk_register_clkdev(clk, "pll_p_out4", NULL); | ||
648 | clks[pll_p_out4] = clk; | ||
649 | 649 | ||
650 | /* PLLM */ | 650 | /* PLLM */ |
651 | clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL, | 651 | clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, NULL, |
652 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, | 652 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, |
653 | &pll_m_params, TEGRA_PLL_HAS_CPCON, | 653 | &pll_m_params, NULL); |
654 | pll_m_freq_table, NULL); | 654 | clks[TEGRA20_CLK_PLL_M] = clk; |
655 | clk_register_clkdev(clk, "pll_m", NULL); | ||
656 | clks[pll_m] = clk; | ||
657 | 655 | ||
658 | /* PLLM_OUT1 */ | 656 | /* PLLM_OUT1 */ |
659 | clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", | 657 | clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", |
@@ -662,42 +660,32 @@ static void tegra20_pll_init(void) | |||
662 | clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", | 660 | clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", |
663 | clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | | 661 | clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | |
664 | CLK_SET_RATE_PARENT, 0, NULL); | 662 | CLK_SET_RATE_PARENT, 0, NULL); |
665 | clk_register_clkdev(clk, "pll_m_out1", NULL); | 663 | clks[TEGRA20_CLK_PLL_M_OUT1] = clk; |
666 | clks[pll_m_out1] = clk; | ||
667 | 664 | ||
668 | /* PLLX */ | 665 | /* PLLX */ |
669 | clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, NULL, 0, | 666 | clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, NULL, 0, |
670 | 0, &pll_x_params, TEGRA_PLL_HAS_CPCON, | 667 | &pll_x_params, NULL); |
671 | pll_x_freq_table, NULL); | 668 | clks[TEGRA20_CLK_PLL_X] = clk; |
672 | clk_register_clkdev(clk, "pll_x", NULL); | ||
673 | clks[pll_x] = clk; | ||
674 | 669 | ||
675 | /* PLLU */ | 670 | /* PLLU */ |
676 | clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, NULL, 0, | 671 | clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, NULL, 0, |
677 | 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON, | 672 | &pll_u_params, NULL); |
678 | pll_u_freq_table, NULL); | 673 | clks[TEGRA20_CLK_PLL_U] = clk; |
679 | clk_register_clkdev(clk, "pll_u", NULL); | ||
680 | clks[pll_u] = clk; | ||
681 | 674 | ||
682 | /* PLLD */ | 675 | /* PLLD */ |
683 | clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, NULL, 0, | 676 | clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, NULL, 0, |
684 | 0, &pll_d_params, TEGRA_PLL_HAS_CPCON, | 677 | &pll_d_params, NULL); |
685 | pll_d_freq_table, NULL); | 678 | clks[TEGRA20_CLK_PLL_D] = clk; |
686 | clk_register_clkdev(clk, "pll_d", NULL); | ||
687 | clks[pll_d] = clk; | ||
688 | 679 | ||
689 | /* PLLD_OUT0 */ | 680 | /* PLLD_OUT0 */ |
690 | clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", | 681 | clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", |
691 | CLK_SET_RATE_PARENT, 1, 2); | 682 | CLK_SET_RATE_PARENT, 1, 2); |
692 | clk_register_clkdev(clk, "pll_d_out0", NULL); | 683 | clks[TEGRA20_CLK_PLL_D_OUT0] = clk; |
693 | clks[pll_d_out0] = clk; | ||
694 | 684 | ||
695 | /* PLLA */ | 685 | /* PLLA */ |
696 | clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, NULL, 0, | 686 | clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, NULL, 0, |
697 | 0, &pll_a_params, TEGRA_PLL_HAS_CPCON, | 687 | &pll_a_params, NULL); |
698 | pll_a_freq_table, NULL); | 688 | clks[TEGRA20_CLK_PLL_A] = clk; |
699 | clk_register_clkdev(clk, "pll_a", NULL); | ||
700 | clks[pll_a] = clk; | ||
701 | 689 | ||
702 | /* PLLA_OUT0 */ | 690 | /* PLLA_OUT0 */ |
703 | clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", | 691 | clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", |
@@ -706,15 +694,12 @@ static void tegra20_pll_init(void) | |||
706 | clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", | 694 | clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", |
707 | clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | | 695 | clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | |
708 | CLK_SET_RATE_PARENT, 0, NULL); | 696 | CLK_SET_RATE_PARENT, 0, NULL); |
709 | clk_register_clkdev(clk, "pll_a_out0", NULL); | 697 | clks[TEGRA20_CLK_PLL_A_OUT0] = clk; |
710 | clks[pll_a_out0] = clk; | ||
711 | 698 | ||
712 | /* PLLE */ | 699 | /* PLLE */ |
713 | clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base, | 700 | clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base, |
714 | 0, 100000000, &pll_e_params, | 701 | 0, &pll_e_params, NULL); |
715 | 0, pll_e_freq_table, NULL); | 702 | clks[TEGRA20_CLK_PLL_E] = clk; |
716 | clk_register_clkdev(clk, "pll_e", NULL); | ||
717 | clks[pll_e] = clk; | ||
718 | } | 703 | } |
719 | 704 | ||
720 | static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | 705 | static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", |
@@ -732,40 +717,17 @@ static void tegra20_super_clk_init(void) | |||
732 | clk = tegra_clk_register_super_mux("cclk", cclk_parents, | 717 | clk = tegra_clk_register_super_mux("cclk", cclk_parents, |
733 | ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT, | 718 | ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT, |
734 | clk_base + CCLK_BURST_POLICY, 0, 4, 0, 0, NULL); | 719 | clk_base + CCLK_BURST_POLICY, 0, 4, 0, 0, NULL); |
735 | clk_register_clkdev(clk, "cclk", NULL); | 720 | clks[TEGRA20_CLK_CCLK] = clk; |
736 | clks[cclk] = clk; | ||
737 | 721 | ||
738 | /* SCLK */ | 722 | /* SCLK */ |
739 | clk = tegra_clk_register_super_mux("sclk", sclk_parents, | 723 | clk = tegra_clk_register_super_mux("sclk", sclk_parents, |
740 | ARRAY_SIZE(sclk_parents), CLK_SET_RATE_PARENT, | 724 | ARRAY_SIZE(sclk_parents), CLK_SET_RATE_PARENT, |
741 | clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); | 725 | clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); |
742 | clk_register_clkdev(clk, "sclk", NULL); | 726 | clks[TEGRA20_CLK_SCLK] = clk; |
743 | clks[sclk] = clk; | ||
744 | |||
745 | /* HCLK */ | ||
746 | clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, | ||
747 | clk_base + CLK_SYSTEM_RATE, 4, 2, 0, | ||
748 | &sysrate_lock); | ||
749 | clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT, | ||
750 | clk_base + CLK_SYSTEM_RATE, 7, | ||
751 | CLK_GATE_SET_TO_DISABLE, &sysrate_lock); | ||
752 | clk_register_clkdev(clk, "hclk", NULL); | ||
753 | clks[hclk] = clk; | ||
754 | |||
755 | /* PCLK */ | ||
756 | clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, | ||
757 | clk_base + CLK_SYSTEM_RATE, 0, 2, 0, | ||
758 | &sysrate_lock); | ||
759 | clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT, | ||
760 | clk_base + CLK_SYSTEM_RATE, 3, | ||
761 | CLK_GATE_SET_TO_DISABLE, &sysrate_lock); | ||
762 | clk_register_clkdev(clk, "pclk", NULL); | ||
763 | clks[pclk] = clk; | ||
764 | 727 | ||
765 | /* twd */ | 728 | /* twd */ |
766 | clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4); | 729 | clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4); |
767 | clk_register_clkdev(clk, "twd", NULL); | 730 | clks[TEGRA20_CLK_TWD] = clk; |
768 | clks[twd] = clk; | ||
769 | } | 731 | } |
770 | 732 | ||
771 | static const char *audio_parents[] = {"spdif_in", "i2s1", "i2s2", "unused", | 733 | static const char *audio_parents[] = {"spdif_in", "i2s1", "i2s2", "unused", |
@@ -784,18 +746,16 @@ static void __init tegra20_audio_clk_init(void) | |||
784 | clk = clk_register_gate(NULL, "audio", "audio_mux", 0, | 746 | clk = clk_register_gate(NULL, "audio", "audio_mux", 0, |
785 | clk_base + AUDIO_SYNC_CLK, 4, | 747 | clk_base + AUDIO_SYNC_CLK, 4, |
786 | CLK_GATE_SET_TO_DISABLE, NULL); | 748 | CLK_GATE_SET_TO_DISABLE, NULL); |
787 | clk_register_clkdev(clk, "audio", NULL); | 749 | clks[TEGRA20_CLK_AUDIO] = clk; |
788 | clks[audio] = clk; | ||
789 | 750 | ||
790 | /* audio_2x */ | 751 | /* audio_2x */ |
791 | clk = clk_register_fixed_factor(NULL, "audio_doubler", "audio", | 752 | clk = clk_register_fixed_factor(NULL, "audio_doubler", "audio", |
792 | CLK_SET_RATE_PARENT, 2, 1); | 753 | CLK_SET_RATE_PARENT, 2, 1); |
793 | clk = tegra_clk_register_periph_gate("audio_2x", "audio_doubler", | 754 | clk = tegra_clk_register_periph_gate("audio_2x", "audio_doubler", |
794 | TEGRA_PERIPH_NO_RESET, clk_base, | 755 | TEGRA_PERIPH_NO_RESET, clk_base, |
795 | CLK_SET_RATE_PARENT, 89, &periph_u_regs, | 756 | CLK_SET_RATE_PARENT, 89, |
796 | periph_clk_enb_refcnt); | 757 | periph_clk_enb_refcnt); |
797 | clk_register_clkdev(clk, "audio_2x", NULL); | 758 | clks[TEGRA20_CLK_AUDIO_2X] = clk; |
798 | clks[audio_2x] = clk; | ||
799 | 759 | ||
800 | } | 760 | } |
801 | 761 | ||
@@ -803,68 +763,36 @@ static const char *i2s1_parents[] = {"pll_a_out0", "audio_2x", "pll_p", | |||
803 | "clk_m"}; | 763 | "clk_m"}; |
804 | static const char *i2s2_parents[] = {"pll_a_out0", "audio_2x", "pll_p", | 764 | static const char *i2s2_parents[] = {"pll_a_out0", "audio_2x", "pll_p", |
805 | "clk_m"}; | 765 | "clk_m"}; |
806 | static const char *spdif_out_parents[] = {"pll_a_out0", "audio_2x", "pll_p", | ||
807 | "clk_m"}; | ||
808 | static const char *spdif_in_parents[] = {"pll_p", "pll_c", "pll_m"}; | ||
809 | static const char *pwm_parents[] = {"pll_p", "pll_c", "audio", "clk_m", | 766 | static const char *pwm_parents[] = {"pll_p", "pll_c", "audio", "clk_m", |
810 | "clk_32k"}; | 767 | "clk_32k"}; |
811 | static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"}; | 768 | static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"}; |
812 | static const char *mux_pllmcpa[] = {"pll_m", "pll_c", "pll_c", "pll_a"}; | ||
813 | static const char *mux_pllpdc_clkm[] = {"pll_p", "pll_d_out0", "pll_c", | 769 | static const char *mux_pllpdc_clkm[] = {"pll_p", "pll_d_out0", "pll_c", |
814 | "clk_m"}; | 770 | "clk_m"}; |
815 | static const char *mux_pllmcp_clkm[] = {"pll_m", "pll_c", "pll_p", "clk_m"}; | 771 | static const char *mux_pllmcp_clkm[] = {"pll_m", "pll_c", "pll_p", "clk_m"}; |
816 | 772 | ||
817 | static struct tegra_periph_init_data tegra_periph_clk_list[] = { | 773 | static struct tegra_periph_init_data tegra_periph_clk_list[] = { |
818 | TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra20-i2s.0", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), | 774 | TEGRA_INIT_DATA_MUX("i2s1", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S1), |
819 | TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra20-i2s.1", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), | 775 | TEGRA_INIT_DATA_MUX("i2s2", i2s2_parents, CLK_SOURCE_I2S2, 18, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S2), |
820 | TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra20-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), | 776 | TEGRA_INIT_DATA_MUX("spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_SPI), |
821 | TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra20-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), | 777 | TEGRA_INIT_DATA_MUX("xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, 0, TEGRA20_CLK_XIO), |
822 | TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), | 778 | TEGRA_INIT_DATA_MUX("twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_TWC), |
823 | TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), | 779 | TEGRA_INIT_DATA_MUX("ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, 0, TEGRA20_CLK_IDE), |
824 | TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), | 780 | TEGRA_INIT_DATA_DIV16("dvc", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_DVC), |
825 | TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), | 781 | TEGRA_INIT_DATA_DIV16("i2c1", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C1), |
826 | TEGRA_INIT_DATA_MUX("spi", NULL, "spi", mux_pllpcm_clkm, CLK_SOURCE_SPI, 43, &periph_h_regs, TEGRA_PERIPH_ON_APB, spi), | 782 | TEGRA_INIT_DATA_DIV16("i2c2", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C2), |
827 | TEGRA_INIT_DATA_MUX("xio", NULL, "xio", mux_pllpcm_clkm, CLK_SOURCE_XIO, 45, &periph_h_regs, 0, xio), | 783 | TEGRA_INIT_DATA_DIV16("i2c3", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2C3), |
828 | TEGRA_INIT_DATA_MUX("twc", NULL, "twc", mux_pllpcm_clkm, CLK_SOURCE_TWC, 16, &periph_l_regs, TEGRA_PERIPH_ON_APB, twc), | 784 | TEGRA_INIT_DATA_MUX("hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA20_CLK_HDMI), |
829 | TEGRA_INIT_DATA_MUX("ide", NULL, "ide", mux_pllpcm_clkm, CLK_SOURCE_XIO, 25, &periph_l_regs, 0, ide), | 785 | TEGRA_INIT_DATA("pwm", NULL, NULL, pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_PWM), |
830 | TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, 0, ndflash), | ||
831 | TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), | ||
832 | TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, 0, csite), | ||
833 | TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, 0, la), | ||
834 | TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), | ||
835 | TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), | ||
836 | TEGRA_INIT_DATA_MUX("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), | ||
837 | TEGRA_INIT_DATA_MUX("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), | ||
838 | TEGRA_INIT_DATA_MUX("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), | ||
839 | TEGRA_INIT_DATA_MUX("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe), | ||
840 | TEGRA_INIT_DATA_MUX("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), | ||
841 | TEGRA_INIT_DATA_MUX("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d), | ||
842 | TEGRA_INIT_DATA_MUX("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d), | ||
843 | TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), | ||
844 | TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), | ||
845 | TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), | ||
846 | TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), | ||
847 | TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), | ||
848 | TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve), | ||
849 | TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo), | ||
850 | TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac), | ||
851 | TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), | ||
852 | TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllpcm_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1), | ||
853 | TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllpcm_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2), | ||
854 | TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllpcm_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3), | ||
855 | TEGRA_INIT_DATA_DIV16("dvc", "div-clk", "tegra-i2c.3", mux_pllpcm_clkm, CLK_SOURCE_DVC, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, dvc), | ||
856 | TEGRA_INIT_DATA_MUX("hdmi", NULL, "hdmi", mux_pllpdc_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), | ||
857 | TEGRA_INIT_DATA("pwm", NULL, "tegra-pwm", pwm_parents, CLK_SOURCE_PWM, 28, 3, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, TEGRA_PERIPH_ON_APB, pwm), | ||
858 | }; | 786 | }; |
859 | 787 | ||
860 | static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { | 788 | static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { |
861 | TEGRA_INIT_DATA_NODIV("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, &periph_l_regs, TEGRA_PERIPH_ON_APB, uarta), | 789 | TEGRA_INIT_DATA_NODIV("uarta", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 30, 2, 6, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTA), |
862 | TEGRA_INIT_DATA_NODIV("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, uartb), | 790 | TEGRA_INIT_DATA_NODIV("uartb", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 30, 2, 7, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTB), |
863 | TEGRA_INIT_DATA_NODIV("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, &periph_h_regs, TEGRA_PERIPH_ON_APB, uartc), | 791 | TEGRA_INIT_DATA_NODIV("uartc", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 30, 2, 55, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTC), |
864 | TEGRA_INIT_DATA_NODIV("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, &periph_u_regs, TEGRA_PERIPH_ON_APB, uartd), | 792 | TEGRA_INIT_DATA_NODIV("uartd", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 30, 2, 65, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTD), |
865 | TEGRA_INIT_DATA_NODIV("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, &periph_u_regs, TEGRA_PERIPH_ON_APB, uarte), | 793 | TEGRA_INIT_DATA_NODIV("uarte", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 30, 2, 66, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_UARTE), |
866 | TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, &periph_l_regs, 0, disp1), | 794 | TEGRA_INIT_DATA_NODIV("disp1", mux_pllpdc_clkm, CLK_SOURCE_DISP1, 30, 2, 27, 0, TEGRA20_CLK_DISP1), |
867 | TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, &periph_l_regs, 0, disp2), | 795 | TEGRA_INIT_DATA_NODIV("disp2", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, 0, TEGRA20_CLK_DISP2), |
868 | }; | 796 | }; |
869 | 797 | ||
870 | static void __init tegra20_periph_clk_init(void) | 798 | static void __init tegra20_periph_clk_init(void) |
@@ -876,69 +804,13 @@ static void __init tegra20_periph_clk_init(void) | |||
876 | /* ac97 */ | 804 | /* ac97 */ |
877 | clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0", | 805 | clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0", |
878 | TEGRA_PERIPH_ON_APB, | 806 | TEGRA_PERIPH_ON_APB, |
879 | clk_base, 0, 3, &periph_l_regs, | 807 | clk_base, 0, 3, periph_clk_enb_refcnt); |
880 | periph_clk_enb_refcnt); | 808 | clks[TEGRA20_CLK_AC97] = clk; |
881 | clk_register_clkdev(clk, NULL, "tegra20-ac97"); | ||
882 | clks[ac97] = clk; | ||
883 | 809 | ||
884 | /* apbdma */ | 810 | /* apbdma */ |
885 | clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, | 811 | clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base, |
886 | 0, 34, &periph_h_regs, | 812 | 0, 34, periph_clk_enb_refcnt); |
887 | periph_clk_enb_refcnt); | 813 | clks[TEGRA20_CLK_APBDMA] = clk; |
888 | clk_register_clkdev(clk, NULL, "tegra-apbdma"); | ||
889 | clks[apbdma] = clk; | ||
890 | |||
891 | /* rtc */ | ||
892 | clk = tegra_clk_register_periph_gate("rtc", "clk_32k", | ||
893 | TEGRA_PERIPH_NO_RESET, | ||
894 | clk_base, 0, 4, &periph_l_regs, | ||
895 | periph_clk_enb_refcnt); | ||
896 | clk_register_clkdev(clk, NULL, "rtc-tegra"); | ||
897 | clks[rtc] = clk; | ||
898 | |||
899 | /* timer */ | ||
900 | clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, | ||
901 | 0, 5, &periph_l_regs, | ||
902 | periph_clk_enb_refcnt); | ||
903 | clk_register_clkdev(clk, NULL, "timer"); | ||
904 | clks[timer] = clk; | ||
905 | |||
906 | /* kbc */ | ||
907 | clk = tegra_clk_register_periph_gate("kbc", "clk_32k", | ||
908 | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, | ||
909 | clk_base, 0, 36, &periph_h_regs, | ||
910 | periph_clk_enb_refcnt); | ||
911 | clk_register_clkdev(clk, NULL, "tegra-kbc"); | ||
912 | clks[kbc] = clk; | ||
913 | |||
914 | /* csus */ | ||
915 | clk = tegra_clk_register_periph_gate("csus", "clk_m", | ||
916 | TEGRA_PERIPH_NO_RESET, | ||
917 | clk_base, 0, 92, &periph_u_regs, | ||
918 | periph_clk_enb_refcnt); | ||
919 | clk_register_clkdev(clk, "csus", "tengra_camera"); | ||
920 | clks[csus] = clk; | ||
921 | |||
922 | /* vcp */ | ||
923 | clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, | ||
924 | clk_base, 0, 29, &periph_l_regs, | ||
925 | periph_clk_enb_refcnt); | ||
926 | clk_register_clkdev(clk, "vcp", "tegra-avp"); | ||
927 | clks[vcp] = clk; | ||
928 | |||
929 | /* bsea */ | ||
930 | clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, | ||
931 | clk_base, 0, 62, &periph_h_regs, | ||
932 | periph_clk_enb_refcnt); | ||
933 | clk_register_clkdev(clk, "bsea", "tegra-avp"); | ||
934 | clks[bsea] = clk; | ||
935 | |||
936 | /* bsev */ | ||
937 | clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, | ||
938 | clk_base, 0, 63, &periph_h_regs, | ||
939 | periph_clk_enb_refcnt); | ||
940 | clk_register_clkdev(clk, "bsev", "tegra-aes"); | ||
941 | clks[bsev] = clk; | ||
942 | 814 | ||
943 | /* emc */ | 815 | /* emc */ |
944 | clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, | 816 | clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, |
@@ -947,130 +819,52 @@ static void __init tegra20_periph_clk_init(void) | |||
947 | clk_base + CLK_SOURCE_EMC, | 819 | clk_base + CLK_SOURCE_EMC, |
948 | 30, 2, 0, NULL); | 820 | 30, 2, 0, NULL); |
949 | clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, | 821 | clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, |
950 | 57, &periph_h_regs, periph_clk_enb_refcnt); | 822 | 57, periph_clk_enb_refcnt); |
951 | clk_register_clkdev(clk, "emc", NULL); | 823 | clks[TEGRA20_CLK_EMC] = clk; |
952 | clks[emc] = clk; | ||
953 | |||
954 | /* usbd */ | ||
955 | clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, | ||
956 | 22, &periph_l_regs, periph_clk_enb_refcnt); | ||
957 | clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); | ||
958 | clks[usbd] = clk; | ||
959 | |||
960 | /* usb2 */ | ||
961 | clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, | ||
962 | 58, &periph_h_regs, periph_clk_enb_refcnt); | ||
963 | clk_register_clkdev(clk, NULL, "tegra-ehci.1"); | ||
964 | clks[usb2] = clk; | ||
965 | |||
966 | /* usb3 */ | ||
967 | clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, | ||
968 | 59, &periph_h_regs, periph_clk_enb_refcnt); | ||
969 | clk_register_clkdev(clk, NULL, "tegra-ehci.2"); | ||
970 | clks[usb3] = clk; | ||
971 | 824 | ||
972 | /* dsi */ | 825 | /* dsi */ |
973 | clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, | 826 | clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, |
974 | 48, &periph_h_regs, periph_clk_enb_refcnt); | 827 | 48, periph_clk_enb_refcnt); |
975 | clk_register_clkdev(clk, NULL, "dsi"); | 828 | clk_register_clkdev(clk, NULL, "dsi"); |
976 | clks[dsi] = clk; | 829 | clks[TEGRA20_CLK_DSI] = clk; |
977 | |||
978 | /* csi */ | ||
979 | clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, | ||
980 | 0, 52, &periph_h_regs, | ||
981 | periph_clk_enb_refcnt); | ||
982 | clk_register_clkdev(clk, "csi", "tegra_camera"); | ||
983 | clks[csi] = clk; | ||
984 | |||
985 | /* isp */ | ||
986 | clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, | ||
987 | &periph_l_regs, periph_clk_enb_refcnt); | ||
988 | clk_register_clkdev(clk, "isp", "tegra_camera"); | ||
989 | clks[isp] = clk; | ||
990 | 830 | ||
991 | /* pex */ | 831 | /* pex */ |
992 | clk = tegra_clk_register_periph_gate("pex", "clk_m", 0, clk_base, 0, 70, | 832 | clk = tegra_clk_register_periph_gate("pex", "clk_m", 0, clk_base, 0, 70, |
993 | &periph_u_regs, periph_clk_enb_refcnt); | ||
994 | clk_register_clkdev(clk, "pex", NULL); | ||
995 | clks[pex] = clk; | ||
996 | |||
997 | /* afi */ | ||
998 | clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, | ||
999 | &periph_u_regs, periph_clk_enb_refcnt); | ||
1000 | clk_register_clkdev(clk, "afi", NULL); | ||
1001 | clks[afi] = clk; | ||
1002 | |||
1003 | /* pcie_xclk */ | ||
1004 | clk = tegra_clk_register_periph_gate("pcie_xclk", "clk_m", 0, clk_base, | ||
1005 | 0, 74, &periph_u_regs, | ||
1006 | periph_clk_enb_refcnt); | 833 | periph_clk_enb_refcnt); |
1007 | clk_register_clkdev(clk, "pcie_xclk", NULL); | 834 | clks[TEGRA20_CLK_PEX] = clk; |
1008 | clks[pcie_xclk] = clk; | ||
1009 | 835 | ||
1010 | /* cdev1 */ | 836 | /* cdev1 */ |
1011 | clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, | 837 | clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, |
1012 | 26000000); | 838 | 26000000); |
1013 | clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0, | 839 | clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0, |
1014 | clk_base, 0, 94, &periph_u_regs, | 840 | clk_base, 0, 94, periph_clk_enb_refcnt); |
1015 | periph_clk_enb_refcnt); | 841 | clks[TEGRA20_CLK_CDEV1] = clk; |
1016 | clk_register_clkdev(clk, "cdev1", NULL); | ||
1017 | clks[cdev1] = clk; | ||
1018 | 842 | ||
1019 | /* cdev2 */ | 843 | /* cdev2 */ |
1020 | clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, CLK_IS_ROOT, | 844 | clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, CLK_IS_ROOT, |
1021 | 26000000); | 845 | 26000000); |
1022 | clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0, | 846 | clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0, |
1023 | clk_base, 0, 93, &periph_u_regs, | 847 | clk_base, 0, 93, periph_clk_enb_refcnt); |
1024 | periph_clk_enb_refcnt); | 848 | clks[TEGRA20_CLK_CDEV2] = clk; |
1025 | clk_register_clkdev(clk, "cdev2", NULL); | ||
1026 | clks[cdev2] = clk; | ||
1027 | 849 | ||
1028 | for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { | 850 | for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { |
1029 | data = &tegra_periph_clk_list[i]; | 851 | data = &tegra_periph_clk_list[i]; |
1030 | clk = tegra_clk_register_periph(data->name, data->parent_names, | 852 | clk = tegra_clk_register_periph(data->name, data->p.parent_names, |
1031 | data->num_parents, &data->periph, | 853 | data->num_parents, &data->periph, |
1032 | clk_base, data->offset, data->flags); | 854 | clk_base, data->offset, data->flags); |
1033 | clk_register_clkdev(clk, data->con_id, data->dev_id); | ||
1034 | clks[data->clk_id] = clk; | 855 | clks[data->clk_id] = clk; |
1035 | } | 856 | } |
1036 | 857 | ||
1037 | for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { | 858 | for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { |
1038 | data = &tegra_periph_nodiv_clk_list[i]; | 859 | data = &tegra_periph_nodiv_clk_list[i]; |
1039 | clk = tegra_clk_register_periph_nodiv(data->name, | 860 | clk = tegra_clk_register_periph_nodiv(data->name, |
1040 | data->parent_names, | 861 | data->p.parent_names, |
1041 | data->num_parents, &data->periph, | 862 | data->num_parents, &data->periph, |
1042 | clk_base, data->offset); | 863 | clk_base, data->offset); |
1043 | clk_register_clkdev(clk, data->con_id, data->dev_id); | ||
1044 | clks[data->clk_id] = clk; | 864 | clks[data->clk_id] = clk; |
1045 | } | 865 | } |
1046 | } | ||
1047 | |||
1048 | |||
1049 | static void __init tegra20_fixed_clk_init(void) | ||
1050 | { | ||
1051 | struct clk *clk; | ||
1052 | |||
1053 | /* clk_32k */ | ||
1054 | clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, | ||
1055 | 32768); | ||
1056 | clk_register_clkdev(clk, "clk_32k", NULL); | ||
1057 | clks[clk_32k] = clk; | ||
1058 | } | ||
1059 | |||
1060 | static void __init tegra20_pmc_clk_init(void) | ||
1061 | { | ||
1062 | struct clk *clk; | ||
1063 | 866 | ||
1064 | /* blink */ | 867 | tegra_periph_clk_init(clk_base, pmc_base, tegra20_clks, &pll_p_params); |
1065 | writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); | ||
1066 | clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, | ||
1067 | pmc_base + PMC_DPD_PADS_ORIDE, | ||
1068 | PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); | ||
1069 | clk = clk_register_gate(NULL, "blink", "blink_override", 0, | ||
1070 | pmc_base + PMC_CTRL, | ||
1071 | PMC_CTRL_BLINK_ENB, 0, NULL); | ||
1072 | clk_register_clkdev(clk, "blink", NULL); | ||
1073 | clks[blink] = clk; | ||
1074 | } | 868 | } |
1075 | 869 | ||
1076 | static void __init tegra20_osc_clk_init(void) | 870 | static void __init tegra20_osc_clk_init(void) |
@@ -1084,15 +878,13 @@ static void __init tegra20_osc_clk_init(void) | |||
1084 | /* clk_m */ | 878 | /* clk_m */ |
1085 | clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT | | 879 | clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT | |
1086 | CLK_IGNORE_UNUSED, input_freq); | 880 | CLK_IGNORE_UNUSED, input_freq); |
1087 | clk_register_clkdev(clk, "clk_m", NULL); | 881 | clks[TEGRA20_CLK_CLK_M] = clk; |
1088 | clks[clk_m] = clk; | ||
1089 | 882 | ||
1090 | /* pll_ref */ | 883 | /* pll_ref */ |
1091 | pll_ref_div = tegra20_get_pll_ref_div(); | 884 | pll_ref_div = tegra20_get_pll_ref_div(); |
1092 | clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", | 885 | clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", |
1093 | CLK_SET_RATE_PARENT, 1, pll_ref_div); | 886 | CLK_SET_RATE_PARENT, 1, pll_ref_div); |
1094 | clk_register_clkdev(clk, "pll_ref", NULL); | 887 | clks[TEGRA20_CLK_PLL_REF] = clk; |
1095 | clks[pll_ref] = clk; | ||
1096 | } | 888 | } |
1097 | 889 | ||
1098 | /* Tegra20 CPU clock and reset control functions */ | 890 | /* Tegra20 CPU clock and reset control functions */ |
@@ -1226,49 +1018,49 @@ static struct tegra_cpu_car_ops tegra20_cpu_car_ops = { | |||
1226 | }; | 1018 | }; |
1227 | 1019 | ||
1228 | static struct tegra_clk_init_table init_table[] __initdata = { | 1020 | static struct tegra_clk_init_table init_table[] __initdata = { |
1229 | {pll_p, clk_max, 216000000, 1}, | 1021 | {TEGRA20_CLK_PLL_P, TEGRA20_CLK_CLK_MAX, 216000000, 1}, |
1230 | {pll_p_out1, clk_max, 28800000, 1}, | 1022 | {TEGRA20_CLK_PLL_P_OUT1, TEGRA20_CLK_CLK_MAX, 28800000, 1}, |
1231 | {pll_p_out2, clk_max, 48000000, 1}, | 1023 | {TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1}, |
1232 | {pll_p_out3, clk_max, 72000000, 1}, | 1024 | {TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1}, |
1233 | {pll_p_out4, clk_max, 24000000, 1}, | 1025 | {TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1}, |
1234 | {pll_c, clk_max, 600000000, 1}, | 1026 | {TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1}, |
1235 | {pll_c_out1, clk_max, 120000000, 1}, | 1027 | {TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 120000000, 1}, |
1236 | {sclk, pll_c_out1, 0, 1}, | 1028 | {TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 0, 1}, |
1237 | {hclk, clk_max, 0, 1}, | 1029 | {TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 0, 1}, |
1238 | {pclk, clk_max, 60000000, 1}, | 1030 | {TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 1}, |
1239 | {csite, clk_max, 0, 1}, | 1031 | {TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1}, |
1240 | {emc, clk_max, 0, 1}, | 1032 | {TEGRA20_CLK_EMC, TEGRA20_CLK_CLK_MAX, 0, 1}, |
1241 | {cclk, clk_max, 0, 1}, | 1033 | {TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1}, |
1242 | {uarta, pll_p, 0, 0}, | 1034 | {TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0}, |
1243 | {uartb, pll_p, 0, 0}, | 1035 | {TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0}, |
1244 | {uartc, pll_p, 0, 0}, | 1036 | {TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 0}, |
1245 | {uartd, pll_p, 0, 0}, | 1037 | {TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 0}, |
1246 | {uarte, pll_p, 0, 0}, | 1038 | {TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 0}, |
1247 | {pll_a, clk_max, 56448000, 1}, | 1039 | {TEGRA20_CLK_PLL_A, TEGRA20_CLK_CLK_MAX, 56448000, 1}, |
1248 | {pll_a_out0, clk_max, 11289600, 1}, | 1040 | {TEGRA20_CLK_PLL_A_OUT0, TEGRA20_CLK_CLK_MAX, 11289600, 1}, |
1249 | {cdev1, clk_max, 0, 1}, | 1041 | {TEGRA20_CLK_CDEV1, TEGRA20_CLK_CLK_MAX, 0, 1}, |
1250 | {blink, clk_max, 32768, 1}, | 1042 | {TEGRA20_CLK_BLINK, TEGRA20_CLK_CLK_MAX, 32768, 1}, |
1251 | {i2s1, pll_a_out0, 11289600, 0}, | 1043 | {TEGRA20_CLK_I2S1, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0}, |
1252 | {i2s2, pll_a_out0, 11289600, 0}, | 1044 | {TEGRA20_CLK_I2S2, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0}, |
1253 | {sdmmc1, pll_p, 48000000, 0}, | 1045 | {TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0}, |
1254 | {sdmmc3, pll_p, 48000000, 0}, | 1046 | {TEGRA20_CLK_SDMMC3, TEGRA20_CLK_PLL_P, 48000000, 0}, |
1255 | {sdmmc4, pll_p, 48000000, 0}, | 1047 | {TEGRA20_CLK_SDMMC4, TEGRA20_CLK_PLL_P, 48000000, 0}, |
1256 | {spi, pll_p, 20000000, 0}, | 1048 | {TEGRA20_CLK_SPI, TEGRA20_CLK_PLL_P, 20000000, 0}, |
1257 | {sbc1, pll_p, 100000000, 0}, | 1049 | {TEGRA20_CLK_SBC1, TEGRA20_CLK_PLL_P, 100000000, 0}, |
1258 | {sbc2, pll_p, 100000000, 0}, | 1050 | {TEGRA20_CLK_SBC2, TEGRA20_CLK_PLL_P, 100000000, 0}, |
1259 | {sbc3, pll_p, 100000000, 0}, | 1051 | {TEGRA20_CLK_SBC3, TEGRA20_CLK_PLL_P, 100000000, 0}, |
1260 | {sbc4, pll_p, 100000000, 0}, | 1052 | {TEGRA20_CLK_SBC4, TEGRA20_CLK_PLL_P, 100000000, 0}, |
1261 | {host1x, pll_c, 150000000, 0}, | 1053 | {TEGRA20_CLK_HOST1X, TEGRA20_CLK_PLL_C, 150000000, 0}, |
1262 | {disp1, pll_p, 600000000, 0}, | 1054 | {TEGRA20_CLK_DISP1, TEGRA20_CLK_PLL_P, 600000000, 0}, |
1263 | {disp2, pll_p, 600000000, 0}, | 1055 | {TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0}, |
1264 | {gr2d, pll_c, 300000000, 0}, | 1056 | {TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0}, |
1265 | {gr3d, pll_c, 300000000, 0}, | 1057 | {TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0}, |
1266 | {clk_max, clk_max, 0, 0}, /* This MUST be the last entry */ | 1058 | {TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry */ |
1267 | }; | 1059 | }; |
1268 | 1060 | ||
1269 | static void __init tegra20_clock_apply_init_table(void) | 1061 | static void __init tegra20_clock_apply_init_table(void) |
1270 | { | 1062 | { |
1271 | tegra_init_from_table(init_table, clks, clk_max); | 1063 | tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX); |
1272 | } | 1064 | } |
1273 | 1065 | ||
1274 | /* | 1066 | /* |
@@ -1277,11 +1069,11 @@ static void __init tegra20_clock_apply_init_table(void) | |||
1277 | * table under two names. | 1069 | * table under two names. |
1278 | */ | 1070 | */ |
1279 | static struct tegra_clk_duplicate tegra_clk_duplicates[] = { | 1071 | static struct tegra_clk_duplicate tegra_clk_duplicates[] = { |
1280 | TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL), | 1072 | TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "utmip-pad", NULL), |
1281 | TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), | 1073 | TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-ehci.0", NULL), |
1282 | TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), | 1074 | TEGRA_CLK_DUPLICATE(TEGRA20_CLK_USBD, "tegra-otg", NULL), |
1283 | TEGRA_CLK_DUPLICATE(cclk, NULL, "cpu"), | 1075 | TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CCLK, NULL, "cpu"), |
1284 | TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */ | 1076 | TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CLK_MAX, NULL, NULL), /* Must be the last entry */ |
1285 | }; | 1077 | }; |
1286 | 1078 | ||
1287 | static const struct of_device_id pmc_match[] __initconst = { | 1079 | static const struct of_device_id pmc_match[] __initconst = { |
@@ -1291,7 +1083,6 @@ static const struct of_device_id pmc_match[] __initconst = { | |||
1291 | 1083 | ||
1292 | static void __init tegra20_clock_init(struct device_node *np) | 1084 | static void __init tegra20_clock_init(struct device_node *np) |
1293 | { | 1085 | { |
1294 | int i; | ||
1295 | struct device_node *node; | 1086 | struct device_node *node; |
1296 | 1087 | ||
1297 | clk_base = of_iomap(np, 0); | 1088 | clk_base = of_iomap(np, 0); |
@@ -1312,30 +1103,24 @@ static void __init tegra20_clock_init(struct device_node *np) | |||
1312 | BUG(); | 1103 | BUG(); |
1313 | } | 1104 | } |
1314 | 1105 | ||
1106 | clks = tegra_clk_init(clk_base, TEGRA20_CLK_CLK_MAX, | ||
1107 | TEGRA20_CLK_PERIPH_BANKS); | ||
1108 | if (!clks) | ||
1109 | return; | ||
1110 | |||
1315 | tegra20_osc_clk_init(); | 1111 | tegra20_osc_clk_init(); |
1316 | tegra20_pmc_clk_init(); | 1112 | tegra_fixed_clk_init(tegra20_clks); |
1317 | tegra20_fixed_clk_init(); | ||
1318 | tegra20_pll_init(); | 1113 | tegra20_pll_init(); |
1319 | tegra20_super_clk_init(); | 1114 | tegra20_super_clk_init(); |
1115 | tegra_super_clk_gen4_init(clk_base, pmc_base, tegra20_clks, NULL); | ||
1320 | tegra20_periph_clk_init(); | 1116 | tegra20_periph_clk_init(); |
1321 | tegra20_audio_clk_init(); | 1117 | tegra20_audio_clk_init(); |
1118 | tegra_pmc_clk_init(pmc_base, tegra20_clks); | ||
1322 | 1119 | ||
1120 | tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX); | ||
1323 | 1121 | ||
1324 | for (i = 0; i < ARRAY_SIZE(clks); i++) { | 1122 | tegra_add_of_provider(np); |
1325 | if (IS_ERR(clks[i])) { | 1123 | tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); |
1326 | pr_err("Tegra20 clk %d: register failed with %ld\n", | ||
1327 | i, PTR_ERR(clks[i])); | ||
1328 | BUG(); | ||
1329 | } | ||
1330 | if (!clks[i]) | ||
1331 | clks[i] = ERR_PTR(-EINVAL); | ||
1332 | } | ||
1333 | |||
1334 | tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); | ||
1335 | |||
1336 | clk_data.clks = clks; | ||
1337 | clk_data.clk_num = ARRAY_SIZE(clks); | ||
1338 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
1339 | 1124 | ||
1340 | tegra_clk_apply_init_table = tegra20_clock_apply_init_table; | 1125 | tegra_clk_apply_init_table = tegra20_clock_apply_init_table; |
1341 | 1126 | ||
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index dbe7c8003c5c..8b10c38b6e3c 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c | |||
@@ -23,42 +23,9 @@ | |||
23 | #include <linux/of_address.h> | 23 | #include <linux/of_address.h> |
24 | #include <linux/clk/tegra.h> | 24 | #include <linux/clk/tegra.h> |
25 | #include <linux/tegra-powergate.h> | 25 | #include <linux/tegra-powergate.h> |
26 | 26 | #include <dt-bindings/clock/tegra30-car.h> | |
27 | #include "clk.h" | 27 | #include "clk.h" |
28 | 28 | #include "clk-id.h" | |
29 | #define RST_DEVICES_L 0x004 | ||
30 | #define RST_DEVICES_H 0x008 | ||
31 | #define RST_DEVICES_U 0x00c | ||
32 | #define RST_DEVICES_V 0x358 | ||
33 | #define RST_DEVICES_W 0x35c | ||
34 | #define RST_DEVICES_SET_L 0x300 | ||
35 | #define RST_DEVICES_CLR_L 0x304 | ||
36 | #define RST_DEVICES_SET_H 0x308 | ||
37 | #define RST_DEVICES_CLR_H 0x30c | ||
38 | #define RST_DEVICES_SET_U 0x310 | ||
39 | #define RST_DEVICES_CLR_U 0x314 | ||
40 | #define RST_DEVICES_SET_V 0x430 | ||
41 | #define RST_DEVICES_CLR_V 0x434 | ||
42 | #define RST_DEVICES_SET_W 0x438 | ||
43 | #define RST_DEVICES_CLR_W 0x43c | ||
44 | #define RST_DEVICES_NUM 5 | ||
45 | |||
46 | #define CLK_OUT_ENB_L 0x010 | ||
47 | #define CLK_OUT_ENB_H 0x014 | ||
48 | #define CLK_OUT_ENB_U 0x018 | ||
49 | #define CLK_OUT_ENB_V 0x360 | ||
50 | #define CLK_OUT_ENB_W 0x364 | ||
51 | #define CLK_OUT_ENB_SET_L 0x320 | ||
52 | #define CLK_OUT_ENB_CLR_L 0x324 | ||
53 | #define CLK_OUT_ENB_SET_H 0x328 | ||
54 | #define CLK_OUT_ENB_CLR_H 0x32c | ||
55 | #define CLK_OUT_ENB_SET_U 0x330 | ||
56 | #define CLK_OUT_ENB_CLR_U 0x334 | ||
57 | #define CLK_OUT_ENB_SET_V 0x440 | ||
58 | #define CLK_OUT_ENB_CLR_V 0x444 | ||
59 | #define CLK_OUT_ENB_SET_W 0x448 | ||
60 | #define CLK_OUT_ENB_CLR_W 0x44c | ||
61 | #define CLK_OUT_ENB_NUM 5 | ||
62 | 29 | ||
63 | #define OSC_CTRL 0x50 | 30 | #define OSC_CTRL 0x50 |
64 | #define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) | 31 | #define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) |
@@ -92,6 +59,8 @@ | |||
92 | 59 | ||
93 | #define SYSTEM_CLK_RATE 0x030 | 60 | #define SYSTEM_CLK_RATE 0x030 |
94 | 61 | ||
62 | #define TEGRA30_CLK_PERIPH_BANKS 5 | ||
63 | |||
95 | #define PLLC_BASE 0x80 | 64 | #define PLLC_BASE 0x80 |
96 | #define PLLC_MISC 0x8c | 65 | #define PLLC_MISC 0x8c |
97 | #define PLLM_BASE 0x90 | 66 | #define PLLM_BASE 0x90 |
@@ -132,88 +101,21 @@ | |||
132 | #define AUDIO_SYNC_CLK_I2S4 0x4b0 | 101 | #define AUDIO_SYNC_CLK_I2S4 0x4b0 |
133 | #define AUDIO_SYNC_CLK_SPDIF 0x4b4 | 102 | #define AUDIO_SYNC_CLK_SPDIF 0x4b4 |
134 | 103 | ||
135 | #define PMC_CLK_OUT_CNTRL 0x1a8 | ||
136 | |||
137 | #define CLK_SOURCE_I2S0 0x1d8 | ||
138 | #define CLK_SOURCE_I2S1 0x100 | ||
139 | #define CLK_SOURCE_I2S2 0x104 | ||
140 | #define CLK_SOURCE_I2S3 0x3bc | ||
141 | #define CLK_SOURCE_I2S4 0x3c0 | ||
142 | #define CLK_SOURCE_SPDIF_OUT 0x108 | 104 | #define CLK_SOURCE_SPDIF_OUT 0x108 |
143 | #define CLK_SOURCE_SPDIF_IN 0x10c | ||
144 | #define CLK_SOURCE_PWM 0x110 | 105 | #define CLK_SOURCE_PWM 0x110 |
145 | #define CLK_SOURCE_D_AUDIO 0x3d0 | 106 | #define CLK_SOURCE_D_AUDIO 0x3d0 |
146 | #define CLK_SOURCE_DAM0 0x3d8 | 107 | #define CLK_SOURCE_DAM0 0x3d8 |
147 | #define CLK_SOURCE_DAM1 0x3dc | 108 | #define CLK_SOURCE_DAM1 0x3dc |
148 | #define CLK_SOURCE_DAM2 0x3e0 | 109 | #define CLK_SOURCE_DAM2 0x3e0 |
149 | #define CLK_SOURCE_HDA 0x428 | ||
150 | #define CLK_SOURCE_HDA2CODEC_2X 0x3e4 | ||
151 | #define CLK_SOURCE_SBC1 0x134 | ||
152 | #define CLK_SOURCE_SBC2 0x118 | ||
153 | #define CLK_SOURCE_SBC3 0x11c | ||
154 | #define CLK_SOURCE_SBC4 0x1b4 | ||
155 | #define CLK_SOURCE_SBC5 0x3c8 | ||
156 | #define CLK_SOURCE_SBC6 0x3cc | ||
157 | #define CLK_SOURCE_SATA_OOB 0x420 | ||
158 | #define CLK_SOURCE_SATA 0x424 | ||
159 | #define CLK_SOURCE_NDFLASH 0x160 | ||
160 | #define CLK_SOURCE_NDSPEED 0x3f8 | ||
161 | #define CLK_SOURCE_VFIR 0x168 | ||
162 | #define CLK_SOURCE_SDMMC1 0x150 | ||
163 | #define CLK_SOURCE_SDMMC2 0x154 | ||
164 | #define CLK_SOURCE_SDMMC3 0x1bc | ||
165 | #define CLK_SOURCE_SDMMC4 0x164 | ||
166 | #define CLK_SOURCE_VDE 0x1c8 | ||
167 | #define CLK_SOURCE_CSITE 0x1d4 | ||
168 | #define CLK_SOURCE_LA 0x1f8 | ||
169 | #define CLK_SOURCE_OWR 0x1cc | ||
170 | #define CLK_SOURCE_NOR 0x1d0 | ||
171 | #define CLK_SOURCE_MIPI 0x174 | ||
172 | #define CLK_SOURCE_I2C1 0x124 | ||
173 | #define CLK_SOURCE_I2C2 0x198 | ||
174 | #define CLK_SOURCE_I2C3 0x1b8 | ||
175 | #define CLK_SOURCE_I2C4 0x3c4 | ||
176 | #define CLK_SOURCE_I2C5 0x128 | ||
177 | #define CLK_SOURCE_UARTA 0x178 | ||
178 | #define CLK_SOURCE_UARTB 0x17c | ||
179 | #define CLK_SOURCE_UARTC 0x1a0 | ||
180 | #define CLK_SOURCE_UARTD 0x1c0 | ||
181 | #define CLK_SOURCE_UARTE 0x1c4 | ||
182 | #define CLK_SOURCE_VI 0x148 | ||
183 | #define CLK_SOURCE_VI_SENSOR 0x1a8 | ||
184 | #define CLK_SOURCE_3D 0x158 | ||
185 | #define CLK_SOURCE_3D2 0x3b0 | 110 | #define CLK_SOURCE_3D2 0x3b0 |
186 | #define CLK_SOURCE_2D 0x15c | 111 | #define CLK_SOURCE_2D 0x15c |
187 | #define CLK_SOURCE_EPP 0x16c | ||
188 | #define CLK_SOURCE_MPE 0x170 | ||
189 | #define CLK_SOURCE_HOST1X 0x180 | ||
190 | #define CLK_SOURCE_CVE 0x140 | ||
191 | #define CLK_SOURCE_TVO 0x188 | ||
192 | #define CLK_SOURCE_DTV 0x1dc | ||
193 | #define CLK_SOURCE_HDMI 0x18c | 112 | #define CLK_SOURCE_HDMI 0x18c |
194 | #define CLK_SOURCE_TVDAC 0x194 | ||
195 | #define CLK_SOURCE_DISP1 0x138 | ||
196 | #define CLK_SOURCE_DISP2 0x13c | ||
197 | #define CLK_SOURCE_DSIB 0xd0 | 113 | #define CLK_SOURCE_DSIB 0xd0 |
198 | #define CLK_SOURCE_TSENSOR 0x3b8 | ||
199 | #define CLK_SOURCE_ACTMON 0x3e8 | ||
200 | #define CLK_SOURCE_EXTERN1 0x3ec | ||
201 | #define CLK_SOURCE_EXTERN2 0x3f0 | ||
202 | #define CLK_SOURCE_EXTERN3 0x3f4 | ||
203 | #define CLK_SOURCE_I2CSLOW 0x3fc | ||
204 | #define CLK_SOURCE_SE 0x42c | 114 | #define CLK_SOURCE_SE 0x42c |
205 | #define CLK_SOURCE_MSELECT 0x3b4 | ||
206 | #define CLK_SOURCE_EMC 0x19c | 115 | #define CLK_SOURCE_EMC 0x19c |
207 | 116 | ||
208 | #define AUDIO_SYNC_DOUBLER 0x49c | 117 | #define AUDIO_SYNC_DOUBLER 0x49c |
209 | 118 | ||
210 | #define PMC_CTRL 0 | ||
211 | #define PMC_CTRL_BLINK_ENB 7 | ||
212 | |||
213 | #define PMC_DPD_PADS_ORIDE 0x1c | ||
214 | #define PMC_DPD_PADS_ORIDE_BLINK_ENB 20 | ||
215 | #define PMC_BLINK_TIMER 0x40 | ||
216 | |||
217 | #define UTMIP_PLL_CFG2 0x488 | 119 | #define UTMIP_PLL_CFG2 0x488 |
218 | #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) | 120 | #define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6) |
219 | #define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) | 121 | #define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) |
@@ -266,89 +168,41 @@ static struct cpu_clk_suspend_context { | |||
266 | } tegra30_cpu_clk_sctx; | 168 | } tegra30_cpu_clk_sctx; |
267 | #endif | 169 | #endif |
268 | 170 | ||
269 | static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32]; | ||
270 | |||
271 | static void __iomem *clk_base; | 171 | static void __iomem *clk_base; |
272 | static void __iomem *pmc_base; | 172 | static void __iomem *pmc_base; |
273 | static unsigned long input_freq; | 173 | static unsigned long input_freq; |
274 | 174 | ||
275 | static DEFINE_SPINLOCK(clk_doubler_lock); | ||
276 | static DEFINE_SPINLOCK(clk_out_lock); | ||
277 | static DEFINE_SPINLOCK(pll_div_lock); | ||
278 | static DEFINE_SPINLOCK(cml_lock); | 175 | static DEFINE_SPINLOCK(cml_lock); |
279 | static DEFINE_SPINLOCK(pll_d_lock); | 176 | static DEFINE_SPINLOCK(pll_d_lock); |
280 | static DEFINE_SPINLOCK(sysrate_lock); | ||
281 | |||
282 | #define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset, \ | ||
283 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
284 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
285 | 30, 2, 0, 0, 8, 1, 0, _regs, _clk_num, \ | ||
286 | periph_clk_enb_refcnt, _gate_flags, _clk_id) | ||
287 | |||
288 | #define TEGRA_INIT_DATA_DIV16(_name, _con_id, _dev_id, _parents, _offset, \ | ||
289 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
290 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
291 | 30, 2, 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP, \ | ||
292 | _regs, _clk_num, periph_clk_enb_refcnt, \ | ||
293 | _gate_flags, _clk_id) | ||
294 | |||
295 | #define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \ | ||
296 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
297 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
298 | 29, 3, 0, 0, 8, 1, 0, _regs, _clk_num, \ | ||
299 | periph_clk_enb_refcnt, _gate_flags, _clk_id) | ||
300 | |||
301 | #define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset, \ | ||
302 | _clk_num, _regs, _gate_flags, _clk_id) \ | ||
303 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | ||
304 | 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \ | ||
305 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | ||
306 | _clk_id) | ||
307 | 177 | ||
308 | #define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\ | 178 | #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ |
309 | _clk_num, _regs, _clk_id) \ | 179 | _clk_num, _gate_flags, _clk_id) \ |
310 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | 180 | TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ |
311 | 30, 2, 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs, \ | 181 | 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ |
312 | _clk_num, periph_clk_enb_refcnt, 0, _clk_id) | 182 | _clk_num, _gate_flags, _clk_id) |
183 | |||
184 | #define TEGRA_INIT_DATA_MUX8(_name, _parents, _offset, \ | ||
185 | _clk_num, _gate_flags, _clk_id) \ | ||
186 | TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ | ||
187 | 29, 3, 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, \ | ||
188 | _clk_num, _gate_flags, _clk_id) | ||
189 | |||
190 | #define TEGRA_INIT_DATA_INT(_name, _parents, _offset, \ | ||
191 | _clk_num, _gate_flags, _clk_id) \ | ||
192 | TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ | ||
193 | 30, 2, 0, 0, 8, 1, TEGRA_DIVIDER_INT | \ | ||
194 | TEGRA_DIVIDER_ROUND_UP, _clk_num, \ | ||
195 | _gate_flags, _clk_id) | ||
313 | 196 | ||
314 | #define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \ | 197 | #define TEGRA_INIT_DATA_NODIV(_name, _parents, _offset, \ |
315 | _mux_shift, _mux_width, _clk_num, _regs, \ | 198 | _mux_shift, _mux_width, _clk_num, \ |
316 | _gate_flags, _clk_id) \ | 199 | _gate_flags, _clk_id) \ |
317 | TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parents, _offset, \ | 200 | TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ |
318 | _mux_shift, _mux_width, 0, 0, 0, 0, 0, _regs, \ | 201 | _mux_shift, _mux_width, 0, 0, 0, 0, 0,\ |
319 | _clk_num, periph_clk_enb_refcnt, _gate_flags, \ | 202 | _clk_num, _gate_flags, \ |
320 | _clk_id) | 203 | _clk_id) |
321 | 204 | ||
322 | /* | 205 | static struct clk **clks; |
323 | * IDs assigned here must be in sync with DT bindings definition | ||
324 | * for Tegra30 clocks. | ||
325 | */ | ||
326 | enum tegra30_clk { | ||
327 | cpu, rtc = 4, timer, uarta, gpio = 8, sdmmc2, i2s1 = 11, i2c1, ndflash, | ||
328 | sdmmc1, sdmmc4, pwm = 17, i2s2, epp, gr2d = 21, usbd, isp, gr3d, | ||
329 | disp2 = 26, disp1, host1x, vcp, i2s0, cop_cache, mc, ahbdma, apbdma, | ||
330 | kbc = 36, statmon, pmc, kfuse = 40, sbc1, nor, sbc2 = 44, sbc3 = 46, | ||
331 | i2c5, dsia, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2, | ||
332 | usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3, | ||
333 | pcie, owr, afi, csite, pciex, avpucq, la, dtv = 79, ndspeed, i2cslow, | ||
334 | dsib, irama = 84, iramb, iramc, iramd, cram2, audio_2x = 90, csus = 92, | ||
335 | cdev2, cdev1, cpu_g = 96, cpu_lp, gr3d2, mselect, tsensor, i2s3, i2s4, | ||
336 | i2c4, sbc5, sbc6, d_audio, apbif, dam0, dam1, dam2, hda2codec_2x, | ||
337 | atomics, audio0_2x, audio1_2x, audio2_2x, audio3_2x, audio4_2x, | ||
338 | spdif_2x, actmon, extern1, extern2, extern3, sata_oob, sata, hda, | ||
339 | se = 127, hda2hdmi, sata_cold, uartb = 160, vfir, spdif_in, spdif_out, | ||
340 | vi, vi_sensor, fuse, fuse_burn, cve, tvo, clk_32k, clk_m, clk_m_div2, | ||
341 | clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_m, pll_m_out1, pll_p, | ||
342 | pll_p_out1, pll_p_out2, pll_p_out3, pll_p_out4, pll_a, pll_a_out0, | ||
343 | pll_d, pll_d_out0, pll_d2, pll_d2_out0, pll_u, pll_x, pll_x_out0, pll_e, | ||
344 | spdif_in_sync, i2s0_sync, i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, | ||
345 | vimclk_sync, audio0, audio1, audio2, audio3, audio4, spdif, clk_out_1, | ||
346 | clk_out_2, clk_out_3, sclk, blink, cclk_g, cclk_lp, twd, cml0, cml1, | ||
347 | hclk, pclk, clk_out_1_mux = 300, clk_max | ||
348 | }; | ||
349 | |||
350 | static struct clk *clks[clk_max]; | ||
351 | static struct clk_onecell_data clk_data; | ||
352 | 206 | ||
353 | /* | 207 | /* |
354 | * Structure defining the fields for USB UTMI clocks Parameters. | 208 | * Structure defining the fields for USB UTMI clocks Parameters. |
@@ -564,6 +418,8 @@ static struct tegra_clk_pll_params pll_c_params = { | |||
564 | .lock_mask = PLL_BASE_LOCK, | 418 | .lock_mask = PLL_BASE_LOCK, |
565 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 419 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
566 | .lock_delay = 300, | 420 | .lock_delay = 300, |
421 | .freq_table = pll_c_freq_table, | ||
422 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, | ||
567 | }; | 423 | }; |
568 | 424 | ||
569 | static struct div_nmp pllm_nmp = { | 425 | static struct div_nmp pllm_nmp = { |
@@ -593,6 +449,9 @@ static struct tegra_clk_pll_params pll_m_params = { | |||
593 | .div_nmp = &pllm_nmp, | 449 | .div_nmp = &pllm_nmp, |
594 | .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, | 450 | .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, |
595 | .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE, | 451 | .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE, |
452 | .freq_table = pll_m_freq_table, | ||
453 | .flags = TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | | ||
454 | TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, | ||
596 | }; | 455 | }; |
597 | 456 | ||
598 | static struct tegra_clk_pll_params pll_p_params = { | 457 | static struct tegra_clk_pll_params pll_p_params = { |
@@ -607,6 +466,9 @@ static struct tegra_clk_pll_params pll_p_params = { | |||
607 | .lock_mask = PLL_BASE_LOCK, | 466 | .lock_mask = PLL_BASE_LOCK, |
608 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 467 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
609 | .lock_delay = 300, | 468 | .lock_delay = 300, |
469 | .freq_table = pll_p_freq_table, | ||
470 | .flags = TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, | ||
471 | .fixed_rate = 408000000, | ||
610 | }; | 472 | }; |
611 | 473 | ||
612 | static struct tegra_clk_pll_params pll_a_params = { | 474 | static struct tegra_clk_pll_params pll_a_params = { |
@@ -621,6 +483,8 @@ static struct tegra_clk_pll_params pll_a_params = { | |||
621 | .lock_mask = PLL_BASE_LOCK, | 483 | .lock_mask = PLL_BASE_LOCK, |
622 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 484 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
623 | .lock_delay = 300, | 485 | .lock_delay = 300, |
486 | .freq_table = pll_a_freq_table, | ||
487 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, | ||
624 | }; | 488 | }; |
625 | 489 | ||
626 | static struct tegra_clk_pll_params pll_d_params = { | 490 | static struct tegra_clk_pll_params pll_d_params = { |
@@ -635,6 +499,10 @@ static struct tegra_clk_pll_params pll_d_params = { | |||
635 | .lock_mask = PLL_BASE_LOCK, | 499 | .lock_mask = PLL_BASE_LOCK, |
636 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 500 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
637 | .lock_delay = 1000, | 501 | .lock_delay = 1000, |
502 | .freq_table = pll_d_freq_table, | ||
503 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | ||
504 | TEGRA_PLL_USE_LOCK, | ||
505 | |||
638 | }; | 506 | }; |
639 | 507 | ||
640 | static struct tegra_clk_pll_params pll_d2_params = { | 508 | static struct tegra_clk_pll_params pll_d2_params = { |
@@ -649,6 +517,9 @@ static struct tegra_clk_pll_params pll_d2_params = { | |||
649 | .lock_mask = PLL_BASE_LOCK, | 517 | .lock_mask = PLL_BASE_LOCK, |
650 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 518 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
651 | .lock_delay = 1000, | 519 | .lock_delay = 1000, |
520 | .freq_table = pll_d_freq_table, | ||
521 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | ||
522 | TEGRA_PLL_USE_LOCK, | ||
652 | }; | 523 | }; |
653 | 524 | ||
654 | static struct tegra_clk_pll_params pll_u_params = { | 525 | static struct tegra_clk_pll_params pll_u_params = { |
@@ -664,6 +535,8 @@ static struct tegra_clk_pll_params pll_u_params = { | |||
664 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 535 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
665 | .lock_delay = 1000, | 536 | .lock_delay = 1000, |
666 | .pdiv_tohw = pllu_p, | 537 | .pdiv_tohw = pllu_p, |
538 | .freq_table = pll_u_freq_table, | ||
539 | .flags = TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON, | ||
667 | }; | 540 | }; |
668 | 541 | ||
669 | static struct tegra_clk_pll_params pll_x_params = { | 542 | static struct tegra_clk_pll_params pll_x_params = { |
@@ -678,6 +551,9 @@ static struct tegra_clk_pll_params pll_x_params = { | |||
678 | .lock_mask = PLL_BASE_LOCK, | 551 | .lock_mask = PLL_BASE_LOCK, |
679 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, | 552 | .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
680 | .lock_delay = 300, | 553 | .lock_delay = 300, |
554 | .freq_table = pll_x_freq_table, | ||
555 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON | | ||
556 | TEGRA_PLL_USE_LOCK, | ||
681 | }; | 557 | }; |
682 | 558 | ||
683 | static struct tegra_clk_pll_params pll_e_params = { | 559 | static struct tegra_clk_pll_params pll_e_params = { |
@@ -692,116 +568,299 @@ static struct tegra_clk_pll_params pll_e_params = { | |||
692 | .lock_mask = PLLE_MISC_LOCK, | 568 | .lock_mask = PLLE_MISC_LOCK, |
693 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, | 569 | .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE, |
694 | .lock_delay = 300, | 570 | .lock_delay = 300, |
571 | .freq_table = pll_e_freq_table, | ||
572 | .flags = TEGRA_PLLE_CONFIGURE | TEGRA_PLL_FIXED, | ||
573 | .fixed_rate = 100000000, | ||
695 | }; | 574 | }; |
696 | 575 | ||
697 | /* Peripheral clock registers */ | 576 | static unsigned long tegra30_input_freq[] = { |
698 | static struct tegra_clk_periph_regs periph_l_regs = { | 577 | [0] = 13000000, |
699 | .enb_reg = CLK_OUT_ENB_L, | 578 | [1] = 16800000, |
700 | .enb_set_reg = CLK_OUT_ENB_SET_L, | 579 | [4] = 19200000, |
701 | .enb_clr_reg = CLK_OUT_ENB_CLR_L, | 580 | [5] = 38400000, |
702 | .rst_reg = RST_DEVICES_L, | 581 | [8] = 12000000, |
703 | .rst_set_reg = RST_DEVICES_SET_L, | 582 | [9] = 48000000, |
704 | .rst_clr_reg = RST_DEVICES_CLR_L, | 583 | [12] = 260000000, |
705 | }; | 584 | }; |
706 | 585 | ||
707 | static struct tegra_clk_periph_regs periph_h_regs = { | 586 | static struct tegra_devclk devclks[] __initdata = { |
708 | .enb_reg = CLK_OUT_ENB_H, | 587 | { .con_id = "pll_c", .dt_id = TEGRA30_CLK_PLL_C }, |
709 | .enb_set_reg = CLK_OUT_ENB_SET_H, | 588 | { .con_id = "pll_c_out1", .dt_id = TEGRA30_CLK_PLL_C_OUT1 }, |
710 | .enb_clr_reg = CLK_OUT_ENB_CLR_H, | 589 | { .con_id = "pll_p", .dt_id = TEGRA30_CLK_PLL_P }, |
711 | .rst_reg = RST_DEVICES_H, | 590 | { .con_id = "pll_p_out1", .dt_id = TEGRA30_CLK_PLL_P_OUT1 }, |
712 | .rst_set_reg = RST_DEVICES_SET_H, | 591 | { .con_id = "pll_p_out2", .dt_id = TEGRA30_CLK_PLL_P_OUT2 }, |
713 | .rst_clr_reg = RST_DEVICES_CLR_H, | 592 | { .con_id = "pll_p_out3", .dt_id = TEGRA30_CLK_PLL_P_OUT3 }, |
593 | { .con_id = "pll_p_out4", .dt_id = TEGRA30_CLK_PLL_P_OUT4 }, | ||
594 | { .con_id = "pll_m", .dt_id = TEGRA30_CLK_PLL_M }, | ||
595 | { .con_id = "pll_m_out1", .dt_id = TEGRA30_CLK_PLL_M_OUT1 }, | ||
596 | { .con_id = "pll_x", .dt_id = TEGRA30_CLK_PLL_X }, | ||
597 | { .con_id = "pll_x_out0", .dt_id = TEGRA30_CLK_PLL_X_OUT0 }, | ||
598 | { .con_id = "pll_u", .dt_id = TEGRA30_CLK_PLL_U }, | ||
599 | { .con_id = "pll_d", .dt_id = TEGRA30_CLK_PLL_D }, | ||
600 | { .con_id = "pll_d_out0", .dt_id = TEGRA30_CLK_PLL_D_OUT0 }, | ||
601 | { .con_id = "pll_d2", .dt_id = TEGRA30_CLK_PLL_D2 }, | ||
602 | { .con_id = "pll_d2_out0", .dt_id = TEGRA30_CLK_PLL_D2_OUT0 }, | ||
603 | { .con_id = "pll_a", .dt_id = TEGRA30_CLK_PLL_A }, | ||
604 | { .con_id = "pll_a_out0", .dt_id = TEGRA30_CLK_PLL_A_OUT0 }, | ||
605 | { .con_id = "pll_e", .dt_id = TEGRA30_CLK_PLL_E }, | ||
606 | { .con_id = "spdif_in_sync", .dt_id = TEGRA30_CLK_SPDIF_IN_SYNC }, | ||
607 | { .con_id = "i2s0_sync", .dt_id = TEGRA30_CLK_I2S0_SYNC }, | ||
608 | { .con_id = "i2s1_sync", .dt_id = TEGRA30_CLK_I2S1_SYNC }, | ||
609 | { .con_id = "i2s2_sync", .dt_id = TEGRA30_CLK_I2S2_SYNC }, | ||
610 | { .con_id = "i2s3_sync", .dt_id = TEGRA30_CLK_I2S3_SYNC }, | ||
611 | { .con_id = "i2s4_sync", .dt_id = TEGRA30_CLK_I2S4_SYNC }, | ||
612 | { .con_id = "vimclk_sync", .dt_id = TEGRA30_CLK_VIMCLK_SYNC }, | ||
613 | { .con_id = "audio0", .dt_id = TEGRA30_CLK_AUDIO0 }, | ||
614 | { .con_id = "audio1", .dt_id = TEGRA30_CLK_AUDIO1 }, | ||
615 | { .con_id = "audio2", .dt_id = TEGRA30_CLK_AUDIO2 }, | ||
616 | { .con_id = "audio3", .dt_id = TEGRA30_CLK_AUDIO3 }, | ||
617 | { .con_id = "audio4", .dt_id = TEGRA30_CLK_AUDIO4 }, | ||
618 | { .con_id = "spdif", .dt_id = TEGRA30_CLK_SPDIF }, | ||
619 | { .con_id = "audio0_2x", .dt_id = TEGRA30_CLK_AUDIO0_2X }, | ||
620 | { .con_id = "audio1_2x", .dt_id = TEGRA30_CLK_AUDIO1_2X }, | ||
621 | { .con_id = "audio2_2x", .dt_id = TEGRA30_CLK_AUDIO2_2X }, | ||
622 | { .con_id = "audio3_2x", .dt_id = TEGRA30_CLK_AUDIO3_2X }, | ||
623 | { .con_id = "audio4_2x", .dt_id = TEGRA30_CLK_AUDIO4_2X }, | ||
624 | { .con_id = "spdif_2x", .dt_id = TEGRA30_CLK_SPDIF_2X }, | ||
625 | { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA30_CLK_EXTERN1 }, | ||
626 | { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA30_CLK_EXTERN2 }, | ||
627 | { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA30_CLK_EXTERN3 }, | ||
628 | { .con_id = "blink", .dt_id = TEGRA30_CLK_BLINK }, | ||
629 | { .con_id = "cclk_g", .dt_id = TEGRA30_CLK_CCLK_G }, | ||
630 | { .con_id = "cclk_lp", .dt_id = TEGRA30_CLK_CCLK_LP }, | ||
631 | { .con_id = "sclk", .dt_id = TEGRA30_CLK_SCLK }, | ||
632 | { .con_id = "hclk", .dt_id = TEGRA30_CLK_HCLK }, | ||
633 | { .con_id = "pclk", .dt_id = TEGRA30_CLK_PCLK }, | ||
634 | { .con_id = "twd", .dt_id = TEGRA30_CLK_TWD }, | ||
635 | { .con_id = "emc", .dt_id = TEGRA30_CLK_EMC }, | ||
636 | { .con_id = "clk_32k", .dt_id = TEGRA30_CLK_CLK_32K }, | ||
637 | { .con_id = "clk_m_div2", .dt_id = TEGRA30_CLK_CLK_M_DIV2 }, | ||
638 | { .con_id = "clk_m_div4", .dt_id = TEGRA30_CLK_CLK_M_DIV4 }, | ||
639 | { .con_id = "cml0", .dt_id = TEGRA30_CLK_CML0 }, | ||
640 | { .con_id = "cml1", .dt_id = TEGRA30_CLK_CML1 }, | ||
641 | { .con_id = "clk_m", .dt_id = TEGRA30_CLK_CLK_M }, | ||
642 | { .con_id = "pll_ref", .dt_id = TEGRA30_CLK_PLL_REF }, | ||
643 | { .con_id = "csus", .dev_id = "tengra_camera", .dt_id = TEGRA30_CLK_CSUS }, | ||
644 | { .con_id = "vcp", .dev_id = "tegra-avp", .dt_id = TEGRA30_CLK_VCP }, | ||
645 | { .con_id = "bsea", .dev_id = "tegra-avp", .dt_id = TEGRA30_CLK_BSEA }, | ||
646 | { .con_id = "bsev", .dev_id = "tegra-aes", .dt_id = TEGRA30_CLK_BSEV }, | ||
647 | { .con_id = "dsia", .dev_id = "tegradc.0", .dt_id = TEGRA30_CLK_DSIA }, | ||
648 | { .con_id = "csi", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_CSI }, | ||
649 | { .con_id = "isp", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_ISP }, | ||
650 | { .con_id = "pcie", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_PCIE }, | ||
651 | { .con_id = "afi", .dev_id = "tegra-pcie", .dt_id = TEGRA30_CLK_AFI }, | ||
652 | { .con_id = "fuse", .dt_id = TEGRA30_CLK_FUSE }, | ||
653 | { .con_id = "fuse_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN }, | ||
654 | { .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF }, | ||
655 | { .con_id = "hda2hdmi", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA2HDMI }, | ||
656 | { .dev_id = "tegra-apbdma", .dt_id = TEGRA30_CLK_APBDMA }, | ||
657 | { .dev_id = "rtc-tegra", .dt_id = TEGRA30_CLK_RTC }, | ||
658 | { .dev_id = "timer", .dt_id = TEGRA30_CLK_TIMER }, | ||
659 | { .dev_id = "tegra-kbc", .dt_id = TEGRA30_CLK_KBC }, | ||
660 | { .dev_id = "fsl-tegra-udc", .dt_id = TEGRA30_CLK_USBD }, | ||
661 | { .dev_id = "tegra-ehci.1", .dt_id = TEGRA30_CLK_USB2 }, | ||
662 | { .dev_id = "tegra-ehci.2", .dt_id = TEGRA30_CLK_USB2 }, | ||
663 | { .dev_id = "kfuse-tegra", .dt_id = TEGRA30_CLK_KFUSE }, | ||
664 | { .dev_id = "tegra_sata_cold", .dt_id = TEGRA30_CLK_SATA_COLD }, | ||
665 | { .dev_id = "dtv", .dt_id = TEGRA30_CLK_DTV }, | ||
666 | { .dev_id = "tegra30-i2s.0", .dt_id = TEGRA30_CLK_I2S0 }, | ||
667 | { .dev_id = "tegra30-i2s.1", .dt_id = TEGRA30_CLK_I2S1 }, | ||
668 | { .dev_id = "tegra30-i2s.2", .dt_id = TEGRA30_CLK_I2S2 }, | ||
669 | { .dev_id = "tegra30-i2s.3", .dt_id = TEGRA30_CLK_I2S3 }, | ||
670 | { .dev_id = "tegra30-i2s.4", .dt_id = TEGRA30_CLK_I2S4 }, | ||
671 | { .con_id = "spdif_out", .dev_id = "tegra30-spdif", .dt_id = TEGRA30_CLK_SPDIF_OUT }, | ||
672 | { .con_id = "spdif_in", .dev_id = "tegra30-spdif", .dt_id = TEGRA30_CLK_SPDIF_IN }, | ||
673 | { .con_id = "d_audio", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_D_AUDIO }, | ||
674 | { .dev_id = "tegra30-dam.0", .dt_id = TEGRA30_CLK_DAM0 }, | ||
675 | { .dev_id = "tegra30-dam.1", .dt_id = TEGRA30_CLK_DAM1 }, | ||
676 | { .dev_id = "tegra30-dam.2", .dt_id = TEGRA30_CLK_DAM2 }, | ||
677 | { .con_id = "hda", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA }, | ||
678 | { .con_id = "hda2codec", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA2CODEC_2X }, | ||
679 | { .dev_id = "spi_tegra.0", .dt_id = TEGRA30_CLK_SBC1 }, | ||
680 | { .dev_id = "spi_tegra.1", .dt_id = TEGRA30_CLK_SBC2 }, | ||
681 | { .dev_id = "spi_tegra.2", .dt_id = TEGRA30_CLK_SBC3 }, | ||
682 | { .dev_id = "spi_tegra.3", .dt_id = TEGRA30_CLK_SBC4 }, | ||
683 | { .dev_id = "spi_tegra.4", .dt_id = TEGRA30_CLK_SBC5 }, | ||
684 | { .dev_id = "spi_tegra.5", .dt_id = TEGRA30_CLK_SBC6 }, | ||
685 | { .dev_id = "tegra_sata_oob", .dt_id = TEGRA30_CLK_SATA_OOB }, | ||
686 | { .dev_id = "tegra_sata", .dt_id = TEGRA30_CLK_SATA }, | ||
687 | { .dev_id = "tegra_nand", .dt_id = TEGRA30_CLK_NDFLASH }, | ||
688 | { .dev_id = "tegra_nand_speed", .dt_id = TEGRA30_CLK_NDSPEED }, | ||
689 | { .dev_id = "vfir", .dt_id = TEGRA30_CLK_VFIR }, | ||
690 | { .dev_id = "csite", .dt_id = TEGRA30_CLK_CSITE }, | ||
691 | { .dev_id = "la", .dt_id = TEGRA30_CLK_LA }, | ||
692 | { .dev_id = "tegra_w1", .dt_id = TEGRA30_CLK_OWR }, | ||
693 | { .dev_id = "mipi", .dt_id = TEGRA30_CLK_MIPI }, | ||
694 | { .dev_id = "tegra-tsensor", .dt_id = TEGRA30_CLK_TSENSOR }, | ||
695 | { .dev_id = "i2cslow", .dt_id = TEGRA30_CLK_I2CSLOW }, | ||
696 | { .dev_id = "vde", .dt_id = TEGRA30_CLK_VDE }, | ||
697 | { .con_id = "vi", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_VI }, | ||
698 | { .dev_id = "epp", .dt_id = TEGRA30_CLK_EPP }, | ||
699 | { .dev_id = "mpe", .dt_id = TEGRA30_CLK_MPE }, | ||
700 | { .dev_id = "host1x", .dt_id = TEGRA30_CLK_HOST1X }, | ||
701 | { .dev_id = "3d", .dt_id = TEGRA30_CLK_GR3D }, | ||
702 | { .dev_id = "3d2", .dt_id = TEGRA30_CLK_GR3D2 }, | ||
703 | { .dev_id = "2d", .dt_id = TEGRA30_CLK_GR2D }, | ||
704 | { .dev_id = "se", .dt_id = TEGRA30_CLK_SE }, | ||
705 | { .dev_id = "mselect", .dt_id = TEGRA30_CLK_MSELECT }, | ||
706 | { .dev_id = "tegra-nor", .dt_id = TEGRA30_CLK_NOR }, | ||
707 | { .dev_id = "sdhci-tegra.0", .dt_id = TEGRA30_CLK_SDMMC1 }, | ||
708 | { .dev_id = "sdhci-tegra.1", .dt_id = TEGRA30_CLK_SDMMC2 }, | ||
709 | { .dev_id = "sdhci-tegra.2", .dt_id = TEGRA30_CLK_SDMMC3 }, | ||
710 | { .dev_id = "sdhci-tegra.3", .dt_id = TEGRA30_CLK_SDMMC4 }, | ||
711 | { .dev_id = "cve", .dt_id = TEGRA30_CLK_CVE }, | ||
712 | { .dev_id = "tvo", .dt_id = TEGRA30_CLK_TVO }, | ||
713 | { .dev_id = "tvdac", .dt_id = TEGRA30_CLK_TVDAC }, | ||
714 | { .dev_id = "actmon", .dt_id = TEGRA30_CLK_ACTMON }, | ||
715 | { .con_id = "vi_sensor", .dev_id = "tegra_camera", .dt_id = TEGRA30_CLK_VI_SENSOR }, | ||
716 | { .con_id = "div-clk", .dev_id = "tegra-i2c.0", .dt_id = TEGRA30_CLK_I2C1 }, | ||
717 | { .con_id = "div-clk", .dev_id = "tegra-i2c.1", .dt_id = TEGRA30_CLK_I2C2 }, | ||
718 | { .con_id = "div-clk", .dev_id = "tegra-i2c.2", .dt_id = TEGRA30_CLK_I2C3 }, | ||
719 | { .con_id = "div-clk", .dev_id = "tegra-i2c.3", .dt_id = TEGRA30_CLK_I2C4 }, | ||
720 | { .con_id = "div-clk", .dev_id = "tegra-i2c.4", .dt_id = TEGRA30_CLK_I2C5 }, | ||
721 | { .dev_id = "tegra_uart.0", .dt_id = TEGRA30_CLK_UARTA }, | ||
722 | { .dev_id = "tegra_uart.1", .dt_id = TEGRA30_CLK_UARTB }, | ||
723 | { .dev_id = "tegra_uart.2", .dt_id = TEGRA30_CLK_UARTC }, | ||
724 | { .dev_id = "tegra_uart.3", .dt_id = TEGRA30_CLK_UARTD }, | ||
725 | { .dev_id = "tegra_uart.4", .dt_id = TEGRA30_CLK_UARTE }, | ||
726 | { .dev_id = "hdmi", .dt_id = TEGRA30_CLK_HDMI }, | ||
727 | { .dev_id = "extern1", .dt_id = TEGRA30_CLK_EXTERN1 }, | ||
728 | { .dev_id = "extern2", .dt_id = TEGRA30_CLK_EXTERN2 }, | ||
729 | { .dev_id = "extern3", .dt_id = TEGRA30_CLK_EXTERN3 }, | ||
730 | { .dev_id = "pwm", .dt_id = TEGRA30_CLK_PWM }, | ||
731 | { .dev_id = "tegradc.0", .dt_id = TEGRA30_CLK_DISP1 }, | ||
732 | { .dev_id = "tegradc.1", .dt_id = TEGRA30_CLK_DISP2 }, | ||
733 | { .dev_id = "tegradc.1", .dt_id = TEGRA30_CLK_DSIB }, | ||
714 | }; | 734 | }; |
715 | 735 | ||
716 | static struct tegra_clk_periph_regs periph_u_regs = { | 736 | static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { |
717 | .enb_reg = CLK_OUT_ENB_U, | 737 | [tegra_clk_clk_32k] = { .dt_id = TEGRA30_CLK_CLK_32K, .present = true }, |
718 | .enb_set_reg = CLK_OUT_ENB_SET_U, | 738 | [tegra_clk_clk_m] = { .dt_id = TEGRA30_CLK_CLK_M, .present = true }, |
719 | .enb_clr_reg = CLK_OUT_ENB_CLR_U, | 739 | [tegra_clk_clk_m_div2] = { .dt_id = TEGRA30_CLK_CLK_M_DIV2, .present = true }, |
720 | .rst_reg = RST_DEVICES_U, | 740 | [tegra_clk_clk_m_div4] = { .dt_id = TEGRA30_CLK_CLK_M_DIV4, .present = true }, |
721 | .rst_set_reg = RST_DEVICES_SET_U, | 741 | [tegra_clk_pll_ref] = { .dt_id = TEGRA30_CLK_PLL_REF, .present = true }, |
722 | .rst_clr_reg = RST_DEVICES_CLR_U, | 742 | [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA30_CLK_SPDIF_IN_SYNC, .present = true }, |
723 | }; | 743 | [tegra_clk_i2s0_sync] = { .dt_id = TEGRA30_CLK_I2S0_SYNC, .present = true }, |
744 | [tegra_clk_i2s1_sync] = { .dt_id = TEGRA30_CLK_I2S1_SYNC, .present = true }, | ||
745 | [tegra_clk_i2s2_sync] = { .dt_id = TEGRA30_CLK_I2S2_SYNC, .present = true }, | ||
746 | [tegra_clk_i2s3_sync] = { .dt_id = TEGRA30_CLK_I2S3_SYNC, .present = true }, | ||
747 | [tegra_clk_i2s4_sync] = { .dt_id = TEGRA30_CLK_I2S4_SYNC, .present = true }, | ||
748 | [tegra_clk_vimclk_sync] = { .dt_id = TEGRA30_CLK_VIMCLK_SYNC, .present = true }, | ||
749 | [tegra_clk_audio0] = { .dt_id = TEGRA30_CLK_AUDIO0, .present = true }, | ||
750 | [tegra_clk_audio1] = { .dt_id = TEGRA30_CLK_AUDIO1, .present = true }, | ||
751 | [tegra_clk_audio2] = { .dt_id = TEGRA30_CLK_AUDIO2, .present = true }, | ||
752 | [tegra_clk_audio3] = { .dt_id = TEGRA30_CLK_AUDIO3, .present = true }, | ||
753 | [tegra_clk_audio4] = { .dt_id = TEGRA30_CLK_AUDIO4, .present = true }, | ||
754 | [tegra_clk_spdif] = { .dt_id = TEGRA30_CLK_SPDIF, .present = true }, | ||
755 | [tegra_clk_audio0_mux] = { .dt_id = TEGRA30_CLK_AUDIO0_MUX, .present = true }, | ||
756 | [tegra_clk_audio1_mux] = { .dt_id = TEGRA30_CLK_AUDIO1_MUX, .present = true }, | ||
757 | [tegra_clk_audio2_mux] = { .dt_id = TEGRA30_CLK_AUDIO2_MUX, .present = true }, | ||
758 | [tegra_clk_audio3_mux] = { .dt_id = TEGRA30_CLK_AUDIO3_MUX, .present = true }, | ||
759 | [tegra_clk_audio4_mux] = { .dt_id = TEGRA30_CLK_AUDIO4_MUX, .present = true }, | ||
760 | [tegra_clk_spdif_mux] = { .dt_id = TEGRA30_CLK_SPDIF_MUX, .present = true }, | ||
761 | [tegra_clk_audio0_2x] = { .dt_id = TEGRA30_CLK_AUDIO0_2X, .present = true }, | ||
762 | [tegra_clk_audio1_2x] = { .dt_id = TEGRA30_CLK_AUDIO1_2X, .present = true }, | ||
763 | [tegra_clk_audio2_2x] = { .dt_id = TEGRA30_CLK_AUDIO2_2X, .present = true }, | ||
764 | [tegra_clk_audio3_2x] = { .dt_id = TEGRA30_CLK_AUDIO3_2X, .present = true }, | ||
765 | [tegra_clk_audio4_2x] = { .dt_id = TEGRA30_CLK_AUDIO4_2X, .present = true }, | ||
766 | [tegra_clk_spdif_2x] = { .dt_id = TEGRA30_CLK_SPDIF_2X, .present = true }, | ||
767 | [tegra_clk_clk_out_1] = { .dt_id = TEGRA30_CLK_CLK_OUT_1, .present = true }, | ||
768 | [tegra_clk_clk_out_2] = { .dt_id = TEGRA30_CLK_CLK_OUT_2, .present = true }, | ||
769 | [tegra_clk_clk_out_3] = { .dt_id = TEGRA30_CLK_CLK_OUT_3, .present = true }, | ||
770 | [tegra_clk_blink] = { .dt_id = TEGRA30_CLK_BLINK, .present = true }, | ||
771 | [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_1_MUX, .present = true }, | ||
772 | [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_2_MUX, .present = true }, | ||
773 | [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_3_MUX, .present = true }, | ||
774 | [tegra_clk_hclk] = { .dt_id = TEGRA30_CLK_HCLK, .present = true }, | ||
775 | [tegra_clk_pclk] = { .dt_id = TEGRA30_CLK_PCLK, .present = true }, | ||
776 | [tegra_clk_i2s0] = { .dt_id = TEGRA30_CLK_I2S0, .present = true }, | ||
777 | [tegra_clk_i2s1] = { .dt_id = TEGRA30_CLK_I2S1, .present = true }, | ||
778 | [tegra_clk_i2s2] = { .dt_id = TEGRA30_CLK_I2S2, .present = true }, | ||
779 | [tegra_clk_i2s3] = { .dt_id = TEGRA30_CLK_I2S3, .present = true }, | ||
780 | [tegra_clk_i2s4] = { .dt_id = TEGRA30_CLK_I2S4, .present = true }, | ||
781 | [tegra_clk_spdif_in] = { .dt_id = TEGRA30_CLK_SPDIF_IN, .present = true }, | ||
782 | [tegra_clk_hda] = { .dt_id = TEGRA30_CLK_HDA, .present = true }, | ||
783 | [tegra_clk_hda2codec_2x] = { .dt_id = TEGRA30_CLK_HDA2CODEC_2X, .present = true }, | ||
784 | [tegra_clk_sbc1] = { .dt_id = TEGRA30_CLK_SBC1, .present = true }, | ||
785 | [tegra_clk_sbc2] = { .dt_id = TEGRA30_CLK_SBC2, .present = true }, | ||
786 | [tegra_clk_sbc3] = { .dt_id = TEGRA30_CLK_SBC3, .present = true }, | ||
787 | [tegra_clk_sbc4] = { .dt_id = TEGRA30_CLK_SBC4, .present = true }, | ||
788 | [tegra_clk_sbc5] = { .dt_id = TEGRA30_CLK_SBC5, .present = true }, | ||
789 | [tegra_clk_sbc6] = { .dt_id = TEGRA30_CLK_SBC6, .present = true }, | ||
790 | [tegra_clk_ndflash] = { .dt_id = TEGRA30_CLK_NDFLASH, .present = true }, | ||
791 | [tegra_clk_ndspeed] = { .dt_id = TEGRA30_CLK_NDSPEED, .present = true }, | ||
792 | [tegra_clk_vfir] = { .dt_id = TEGRA30_CLK_VFIR, .present = true }, | ||
793 | [tegra_clk_la] = { .dt_id = TEGRA30_CLK_LA, .present = true }, | ||
794 | [tegra_clk_csite] = { .dt_id = TEGRA30_CLK_CSITE, .present = true }, | ||
795 | [tegra_clk_owr] = { .dt_id = TEGRA30_CLK_OWR, .present = true }, | ||
796 | [tegra_clk_mipi] = { .dt_id = TEGRA30_CLK_MIPI, .present = true }, | ||
797 | [tegra_clk_tsensor] = { .dt_id = TEGRA30_CLK_TSENSOR, .present = true }, | ||
798 | [tegra_clk_i2cslow] = { .dt_id = TEGRA30_CLK_I2CSLOW, .present = true }, | ||
799 | [tegra_clk_vde] = { .dt_id = TEGRA30_CLK_VDE, .present = true }, | ||
800 | [tegra_clk_vi] = { .dt_id = TEGRA30_CLK_VI, .present = true }, | ||
801 | [tegra_clk_epp] = { .dt_id = TEGRA30_CLK_EPP, .present = true }, | ||
802 | [tegra_clk_mpe] = { .dt_id = TEGRA30_CLK_MPE, .present = true }, | ||
803 | [tegra_clk_host1x] = { .dt_id = TEGRA30_CLK_HOST1X, .present = true }, | ||
804 | [tegra_clk_gr2d] = { .dt_id = TEGRA30_CLK_GR2D, .present = true }, | ||
805 | [tegra_clk_gr3d] = { .dt_id = TEGRA30_CLK_GR3D, .present = true }, | ||
806 | [tegra_clk_mselect] = { .dt_id = TEGRA30_CLK_MSELECT, .present = true }, | ||
807 | [tegra_clk_nor] = { .dt_id = TEGRA30_CLK_NOR, .present = true }, | ||
808 | [tegra_clk_sdmmc1] = { .dt_id = TEGRA30_CLK_SDMMC1, .present = true }, | ||
809 | [tegra_clk_sdmmc2] = { .dt_id = TEGRA30_CLK_SDMMC2, .present = true }, | ||
810 | [tegra_clk_sdmmc3] = { .dt_id = TEGRA30_CLK_SDMMC3, .present = true }, | ||
811 | [tegra_clk_sdmmc4] = { .dt_id = TEGRA30_CLK_SDMMC4, .present = true }, | ||
812 | [tegra_clk_cve] = { .dt_id = TEGRA30_CLK_CVE, .present = true }, | ||
813 | [tegra_clk_tvo] = { .dt_id = TEGRA30_CLK_TVO, .present = true }, | ||
814 | [tegra_clk_tvdac] = { .dt_id = TEGRA30_CLK_TVDAC, .present = true }, | ||
815 | [tegra_clk_actmon] = { .dt_id = TEGRA30_CLK_ACTMON, .present = true }, | ||
816 | [tegra_clk_vi_sensor] = { .dt_id = TEGRA30_CLK_VI_SENSOR, .present = true }, | ||
817 | [tegra_clk_i2c1] = { .dt_id = TEGRA30_CLK_I2C1, .present = true }, | ||
818 | [tegra_clk_i2c2] = { .dt_id = TEGRA30_CLK_I2C2, .present = true }, | ||
819 | [tegra_clk_i2c3] = { .dt_id = TEGRA30_CLK_I2C3, .present = true }, | ||
820 | [tegra_clk_i2c4] = { .dt_id = TEGRA30_CLK_I2C4, .present = true }, | ||
821 | [tegra_clk_i2c5] = { .dt_id = TEGRA30_CLK_I2C5, .present = true }, | ||
822 | [tegra_clk_uarta] = { .dt_id = TEGRA30_CLK_UARTA, .present = true }, | ||
823 | [tegra_clk_uartb] = { .dt_id = TEGRA30_CLK_UARTB, .present = true }, | ||
824 | [tegra_clk_uartc] = { .dt_id = TEGRA30_CLK_UARTC, .present = true }, | ||
825 | [tegra_clk_uartd] = { .dt_id = TEGRA30_CLK_UARTD, .present = true }, | ||
826 | [tegra_clk_uarte] = { .dt_id = TEGRA30_CLK_UARTE, .present = true }, | ||
827 | [tegra_clk_extern1] = { .dt_id = TEGRA30_CLK_EXTERN1, .present = true }, | ||
828 | [tegra_clk_extern2] = { .dt_id = TEGRA30_CLK_EXTERN2, .present = true }, | ||
829 | [tegra_clk_extern3] = { .dt_id = TEGRA30_CLK_EXTERN3, .present = true }, | ||
830 | [tegra_clk_disp1] = { .dt_id = TEGRA30_CLK_DISP1, .present = true }, | ||
831 | [tegra_clk_disp2] = { .dt_id = TEGRA30_CLK_DISP2, .present = true }, | ||
832 | [tegra_clk_apbdma] = { .dt_id = TEGRA30_CLK_APBDMA, .present = true }, | ||
833 | [tegra_clk_rtc] = { .dt_id = TEGRA30_CLK_RTC, .present = true }, | ||
834 | [tegra_clk_timer] = { .dt_id = TEGRA30_CLK_TIMER, .present = true }, | ||
835 | [tegra_clk_kbc] = { .dt_id = TEGRA30_CLK_KBC, .present = true }, | ||
836 | [tegra_clk_csus] = { .dt_id = TEGRA30_CLK_CSUS, .present = true }, | ||
837 | [tegra_clk_vcp] = { .dt_id = TEGRA30_CLK_VCP, .present = true }, | ||
838 | [tegra_clk_bsea] = { .dt_id = TEGRA30_CLK_BSEA, .present = true }, | ||
839 | [tegra_clk_bsev] = { .dt_id = TEGRA30_CLK_BSEV, .present = true }, | ||
840 | [tegra_clk_usbd] = { .dt_id = TEGRA30_CLK_USBD, .present = true }, | ||
841 | [tegra_clk_usb2] = { .dt_id = TEGRA30_CLK_USB2, .present = true }, | ||
842 | [tegra_clk_usb3] = { .dt_id = TEGRA30_CLK_USB3, .present = true }, | ||
843 | [tegra_clk_csi] = { .dt_id = TEGRA30_CLK_CSI, .present = true }, | ||
844 | [tegra_clk_isp] = { .dt_id = TEGRA30_CLK_ISP, .present = true }, | ||
845 | [tegra_clk_kfuse] = { .dt_id = TEGRA30_CLK_KFUSE, .present = true }, | ||
846 | [tegra_clk_fuse] = { .dt_id = TEGRA30_CLK_FUSE, .present = true }, | ||
847 | [tegra_clk_fuse_burn] = { .dt_id = TEGRA30_CLK_FUSE_BURN, .present = true }, | ||
848 | [tegra_clk_apbif] = { .dt_id = TEGRA30_CLK_APBIF, .present = true }, | ||
849 | [tegra_clk_hda2hdmi] = { .dt_id = TEGRA30_CLK_HDA2HDMI, .present = true }, | ||
850 | [tegra_clk_sata_cold] = { .dt_id = TEGRA30_CLK_SATA_COLD, .present = true }, | ||
851 | [tegra_clk_sata_oob] = { .dt_id = TEGRA30_CLK_SATA_OOB, .present = true }, | ||
852 | [tegra_clk_sata] = { .dt_id = TEGRA30_CLK_SATA, .present = true }, | ||
853 | [tegra_clk_dtv] = { .dt_id = TEGRA30_CLK_DTV, .present = true }, | ||
854 | [tegra_clk_pll_p] = { .dt_id = TEGRA30_CLK_PLL_P, .present = true }, | ||
855 | [tegra_clk_pll_p_out1] = { .dt_id = TEGRA30_CLK_PLL_P_OUT1, .present = true }, | ||
856 | [tegra_clk_pll_p_out2] = { .dt_id = TEGRA30_CLK_PLL_P_OUT2, .present = true }, | ||
857 | [tegra_clk_pll_p_out3] = { .dt_id = TEGRA30_CLK_PLL_P_OUT3, .present = true }, | ||
858 | [tegra_clk_pll_p_out4] = { .dt_id = TEGRA30_CLK_PLL_P_OUT4, .present = true }, | ||
859 | [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true }, | ||
860 | [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true }, | ||
724 | 861 | ||
725 | static struct tegra_clk_periph_regs periph_v_regs = { | ||
726 | .enb_reg = CLK_OUT_ENB_V, | ||
727 | .enb_set_reg = CLK_OUT_ENB_SET_V, | ||
728 | .enb_clr_reg = CLK_OUT_ENB_CLR_V, | ||
729 | .rst_reg = RST_DEVICES_V, | ||
730 | .rst_set_reg = RST_DEVICES_SET_V, | ||
731 | .rst_clr_reg = RST_DEVICES_CLR_V, | ||
732 | }; | 862 | }; |
733 | 863 | ||
734 | static struct tegra_clk_periph_regs periph_w_regs = { | ||
735 | .enb_reg = CLK_OUT_ENB_W, | ||
736 | .enb_set_reg = CLK_OUT_ENB_SET_W, | ||
737 | .enb_clr_reg = CLK_OUT_ENB_CLR_W, | ||
738 | .rst_reg = RST_DEVICES_W, | ||
739 | .rst_set_reg = RST_DEVICES_SET_W, | ||
740 | .rst_clr_reg = RST_DEVICES_CLR_W, | ||
741 | }; | ||
742 | |||
743 | static void tegra30_clk_measure_input_freq(void) | ||
744 | { | ||
745 | u32 osc_ctrl = readl_relaxed(clk_base + OSC_CTRL); | ||
746 | u32 auto_clk_control = osc_ctrl & OSC_CTRL_OSC_FREQ_MASK; | ||
747 | u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK; | ||
748 | |||
749 | switch (auto_clk_control) { | ||
750 | case OSC_CTRL_OSC_FREQ_12MHZ: | ||
751 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
752 | input_freq = 12000000; | ||
753 | break; | ||
754 | case OSC_CTRL_OSC_FREQ_13MHZ: | ||
755 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
756 | input_freq = 13000000; | ||
757 | break; | ||
758 | case OSC_CTRL_OSC_FREQ_19_2MHZ: | ||
759 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
760 | input_freq = 19200000; | ||
761 | break; | ||
762 | case OSC_CTRL_OSC_FREQ_26MHZ: | ||
763 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
764 | input_freq = 26000000; | ||
765 | break; | ||
766 | case OSC_CTRL_OSC_FREQ_16_8MHZ: | ||
767 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | ||
768 | input_freq = 16800000; | ||
769 | break; | ||
770 | case OSC_CTRL_OSC_FREQ_38_4MHZ: | ||
771 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2); | ||
772 | input_freq = 38400000; | ||
773 | break; | ||
774 | case OSC_CTRL_OSC_FREQ_48MHZ: | ||
775 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4); | ||
776 | input_freq = 48000000; | ||
777 | break; | ||
778 | default: | ||
779 | pr_err("Unexpected auto clock control value %d", | ||
780 | auto_clk_control); | ||
781 | BUG(); | ||
782 | return; | ||
783 | } | ||
784 | } | ||
785 | |||
786 | static unsigned int tegra30_get_pll_ref_div(void) | ||
787 | { | ||
788 | u32 pll_ref_div = readl_relaxed(clk_base + OSC_CTRL) & | ||
789 | OSC_CTRL_PLL_REF_DIV_MASK; | ||
790 | |||
791 | switch (pll_ref_div) { | ||
792 | case OSC_CTRL_PLL_REF_DIV_1: | ||
793 | return 1; | ||
794 | case OSC_CTRL_PLL_REF_DIV_2: | ||
795 | return 2; | ||
796 | case OSC_CTRL_PLL_REF_DIV_4: | ||
797 | return 4; | ||
798 | default: | ||
799 | pr_err("Invalid pll ref divider %d", pll_ref_div); | ||
800 | BUG(); | ||
801 | } | ||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | static void tegra30_utmi_param_configure(void) | 864 | static void tegra30_utmi_param_configure(void) |
806 | { | 865 | { |
807 | u32 reg; | 866 | u32 reg; |
@@ -863,11 +922,8 @@ static void __init tegra30_pll_init(void) | |||
863 | 922 | ||
864 | /* PLLC */ | 923 | /* PLLC */ |
865 | clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0, | 924 | clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0, |
866 | 0, &pll_c_params, | 925 | &pll_c_params, NULL); |
867 | TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, | 926 | clks[TEGRA30_CLK_PLL_C] = clk; |
868 | pll_c_freq_table, NULL); | ||
869 | clk_register_clkdev(clk, "pll_c", NULL); | ||
870 | clks[pll_c] = clk; | ||
871 | 927 | ||
872 | /* PLLC_OUT1 */ | 928 | /* PLLC_OUT1 */ |
873 | clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", | 929 | clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", |
@@ -876,73 +932,13 @@ static void __init tegra30_pll_init(void) | |||
876 | clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", | 932 | clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div", |
877 | clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, | 933 | clk_base + PLLC_OUT, 1, 0, CLK_SET_RATE_PARENT, |
878 | 0, NULL); | 934 | 0, NULL); |
879 | clk_register_clkdev(clk, "pll_c_out1", NULL); | 935 | clks[TEGRA30_CLK_PLL_C_OUT1] = clk; |
880 | clks[pll_c_out1] = clk; | ||
881 | |||
882 | /* PLLP */ | ||
883 | clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc_base, 0, | ||
884 | 408000000, &pll_p_params, | ||
885 | TEGRA_PLL_FIXED | TEGRA_PLL_HAS_CPCON | | ||
886 | TEGRA_PLL_USE_LOCK, pll_p_freq_table, NULL); | ||
887 | clk_register_clkdev(clk, "pll_p", NULL); | ||
888 | clks[pll_p] = clk; | ||
889 | |||
890 | /* PLLP_OUT1 */ | ||
891 | clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p", | ||
892 | clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | | ||
893 | TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, | ||
894 | &pll_div_lock); | ||
895 | clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div", | ||
896 | clk_base + PLLP_OUTA, 1, 0, | ||
897 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
898 | &pll_div_lock); | ||
899 | clk_register_clkdev(clk, "pll_p_out1", NULL); | ||
900 | clks[pll_p_out1] = clk; | ||
901 | |||
902 | /* PLLP_OUT2 */ | ||
903 | clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p", | ||
904 | clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED | | ||
905 | TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, | ||
906 | &pll_div_lock); | ||
907 | clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div", | ||
908 | clk_base + PLLP_OUTA, 17, 16, | ||
909 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
910 | &pll_div_lock); | ||
911 | clk_register_clkdev(clk, "pll_p_out2", NULL); | ||
912 | clks[pll_p_out2] = clk; | ||
913 | |||
914 | /* PLLP_OUT3 */ | ||
915 | clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p", | ||
916 | clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | | ||
917 | TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, | ||
918 | &pll_div_lock); | ||
919 | clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div", | ||
920 | clk_base + PLLP_OUTB, 1, 0, | ||
921 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
922 | &pll_div_lock); | ||
923 | clk_register_clkdev(clk, "pll_p_out3", NULL); | ||
924 | clks[pll_p_out3] = clk; | ||
925 | |||
926 | /* PLLP_OUT4 */ | ||
927 | clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p", | ||
928 | clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED | | ||
929 | TEGRA_DIVIDER_ROUND_UP, 24, 8, 1, | ||
930 | &pll_div_lock); | ||
931 | clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div", | ||
932 | clk_base + PLLP_OUTB, 17, 16, | ||
933 | CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0, | ||
934 | &pll_div_lock); | ||
935 | clk_register_clkdev(clk, "pll_p_out4", NULL); | ||
936 | clks[pll_p_out4] = clk; | ||
937 | 936 | ||
938 | /* PLLM */ | 937 | /* PLLM */ |
939 | clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, | 938 | clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, |
940 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0, | 939 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, |
941 | &pll_m_params, TEGRA_PLLM | TEGRA_PLL_HAS_CPCON | | 940 | &pll_m_params, NULL); |
942 | TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, | 941 | clks[TEGRA30_CLK_PLL_M] = clk; |
943 | pll_m_freq_table, NULL); | ||
944 | clk_register_clkdev(clk, "pll_m", NULL); | ||
945 | clks[pll_m] = clk; | ||
946 | 942 | ||
947 | /* PLLM_OUT1 */ | 943 | /* PLLM_OUT1 */ |
948 | clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", | 944 | clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", |
@@ -951,78 +947,44 @@ static void __init tegra30_pll_init(void) | |||
951 | clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", | 947 | clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div", |
952 | clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | | 948 | clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED | |
953 | CLK_SET_RATE_PARENT, 0, NULL); | 949 | CLK_SET_RATE_PARENT, 0, NULL); |
954 | clk_register_clkdev(clk, "pll_m_out1", NULL); | 950 | clks[TEGRA30_CLK_PLL_M_OUT1] = clk; |
955 | clks[pll_m_out1] = clk; | ||
956 | 951 | ||
957 | /* PLLX */ | 952 | /* PLLX */ |
958 | clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, pmc_base, 0, | 953 | clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, pmc_base, 0, |
959 | 0, &pll_x_params, TEGRA_PLL_HAS_CPCON | | 954 | &pll_x_params, NULL); |
960 | TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK, | 955 | clks[TEGRA30_CLK_PLL_X] = clk; |
961 | pll_x_freq_table, NULL); | ||
962 | clk_register_clkdev(clk, "pll_x", NULL); | ||
963 | clks[pll_x] = clk; | ||
964 | 956 | ||
965 | /* PLLX_OUT0 */ | 957 | /* PLLX_OUT0 */ |
966 | clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", | 958 | clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x", |
967 | CLK_SET_RATE_PARENT, 1, 2); | 959 | CLK_SET_RATE_PARENT, 1, 2); |
968 | clk_register_clkdev(clk, "pll_x_out0", NULL); | 960 | clks[TEGRA30_CLK_PLL_X_OUT0] = clk; |
969 | clks[pll_x_out0] = clk; | ||
970 | 961 | ||
971 | /* PLLU */ | 962 | /* PLLU */ |
972 | clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc_base, 0, | 963 | clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc_base, 0, |
973 | 0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON | | 964 | &pll_u_params, NULL); |
974 | TEGRA_PLL_SET_LFCON, | 965 | clks[TEGRA30_CLK_PLL_U] = clk; |
975 | pll_u_freq_table, | ||
976 | NULL); | ||
977 | clk_register_clkdev(clk, "pll_u", NULL); | ||
978 | clks[pll_u] = clk; | ||
979 | 966 | ||
980 | tegra30_utmi_param_configure(); | 967 | tegra30_utmi_param_configure(); |
981 | 968 | ||
982 | /* PLLD */ | 969 | /* PLLD */ |
983 | clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc_base, 0, | 970 | clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc_base, 0, |
984 | 0, &pll_d_params, TEGRA_PLL_HAS_CPCON | | 971 | &pll_d_params, &pll_d_lock); |
985 | TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, | 972 | clks[TEGRA30_CLK_PLL_D] = clk; |
986 | pll_d_freq_table, &pll_d_lock); | ||
987 | clk_register_clkdev(clk, "pll_d", NULL); | ||
988 | clks[pll_d] = clk; | ||
989 | 973 | ||
990 | /* PLLD_OUT0 */ | 974 | /* PLLD_OUT0 */ |
991 | clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", | 975 | clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d", |
992 | CLK_SET_RATE_PARENT, 1, 2); | 976 | CLK_SET_RATE_PARENT, 1, 2); |
993 | clk_register_clkdev(clk, "pll_d_out0", NULL); | 977 | clks[TEGRA30_CLK_PLL_D_OUT0] = clk; |
994 | clks[pll_d_out0] = clk; | ||
995 | 978 | ||
996 | /* PLLD2 */ | 979 | /* PLLD2 */ |
997 | clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0, | 980 | clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0, |
998 | 0, &pll_d2_params, TEGRA_PLL_HAS_CPCON | | 981 | &pll_d2_params, NULL); |
999 | TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK, | 982 | clks[TEGRA30_CLK_PLL_D2] = clk; |
1000 | pll_d_freq_table, NULL); | ||
1001 | clk_register_clkdev(clk, "pll_d2", NULL); | ||
1002 | clks[pll_d2] = clk; | ||
1003 | 983 | ||
1004 | /* PLLD2_OUT0 */ | 984 | /* PLLD2_OUT0 */ |
1005 | clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", | 985 | clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", |
1006 | CLK_SET_RATE_PARENT, 1, 2); | 986 | CLK_SET_RATE_PARENT, 1, 2); |
1007 | clk_register_clkdev(clk, "pll_d2_out0", NULL); | 987 | clks[TEGRA30_CLK_PLL_D2_OUT0] = clk; |
1008 | clks[pll_d2_out0] = clk; | ||
1009 | |||
1010 | /* PLLA */ | ||
1011 | clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc_base, | ||
1012 | 0, 0, &pll_a_params, TEGRA_PLL_HAS_CPCON | | ||
1013 | TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL); | ||
1014 | clk_register_clkdev(clk, "pll_a", NULL); | ||
1015 | clks[pll_a] = clk; | ||
1016 | |||
1017 | /* PLLA_OUT0 */ | ||
1018 | clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a", | ||
1019 | clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP, | ||
1020 | 8, 8, 1, NULL); | ||
1021 | clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div", | ||
1022 | clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED | | ||
1023 | CLK_SET_RATE_PARENT, 0, NULL); | ||
1024 | clk_register_clkdev(clk, "pll_a_out0", NULL); | ||
1025 | clks[pll_a_out0] = clk; | ||
1026 | 988 | ||
1027 | /* PLLE */ | 989 | /* PLLE */ |
1028 | clk = clk_register_mux(NULL, "pll_e_mux", pll_e_parents, | 990 | clk = clk_register_mux(NULL, "pll_e_mux", pll_e_parents, |
@@ -1030,258 +992,8 @@ static void __init tegra30_pll_init(void) | |||
1030 | CLK_SET_RATE_NO_REPARENT, | 992 | CLK_SET_RATE_NO_REPARENT, |
1031 | clk_base + PLLE_AUX, 2, 1, 0, NULL); | 993 | clk_base + PLLE_AUX, 2, 1, 0, NULL); |
1032 | clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base, | 994 | clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base, |
1033 | CLK_GET_RATE_NOCACHE, 100000000, &pll_e_params, | 995 | CLK_GET_RATE_NOCACHE, &pll_e_params, NULL); |
1034 | TEGRA_PLLE_CONFIGURE, pll_e_freq_table, NULL); | 996 | clks[TEGRA30_CLK_PLL_E] = clk; |
1035 | clk_register_clkdev(clk, "pll_e", NULL); | ||
1036 | clks[pll_e] = clk; | ||
1037 | } | ||
1038 | |||
1039 | static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync", | ||
1040 | "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",}; | ||
1041 | static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", | ||
1042 | "clk_m_div4", "extern1", }; | ||
1043 | static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", | ||
1044 | "clk_m_div4", "extern2", }; | ||
1045 | static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", | ||
1046 | "clk_m_div4", "extern3", }; | ||
1047 | |||
1048 | static void __init tegra30_audio_clk_init(void) | ||
1049 | { | ||
1050 | struct clk *clk; | ||
1051 | |||
1052 | /* spdif_in_sync */ | ||
1053 | clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000, | ||
1054 | 24000000); | ||
1055 | clk_register_clkdev(clk, "spdif_in_sync", NULL); | ||
1056 | clks[spdif_in_sync] = clk; | ||
1057 | |||
1058 | /* i2s0_sync */ | ||
1059 | clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000); | ||
1060 | clk_register_clkdev(clk, "i2s0_sync", NULL); | ||
1061 | clks[i2s0_sync] = clk; | ||
1062 | |||
1063 | /* i2s1_sync */ | ||
1064 | clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000); | ||
1065 | clk_register_clkdev(clk, "i2s1_sync", NULL); | ||
1066 | clks[i2s1_sync] = clk; | ||
1067 | |||
1068 | /* i2s2_sync */ | ||
1069 | clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000); | ||
1070 | clk_register_clkdev(clk, "i2s2_sync", NULL); | ||
1071 | clks[i2s2_sync] = clk; | ||
1072 | |||
1073 | /* i2s3_sync */ | ||
1074 | clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000); | ||
1075 | clk_register_clkdev(clk, "i2s3_sync", NULL); | ||
1076 | clks[i2s3_sync] = clk; | ||
1077 | |||
1078 | /* i2s4_sync */ | ||
1079 | clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000); | ||
1080 | clk_register_clkdev(clk, "i2s4_sync", NULL); | ||
1081 | clks[i2s4_sync] = clk; | ||
1082 | |||
1083 | /* vimclk_sync */ | ||
1084 | clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000); | ||
1085 | clk_register_clkdev(clk, "vimclk_sync", NULL); | ||
1086 | clks[vimclk_sync] = clk; | ||
1087 | |||
1088 | /* audio0 */ | ||
1089 | clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk, | ||
1090 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1091 | CLK_SET_RATE_NO_REPARENT, | ||
1092 | clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, NULL); | ||
1093 | clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0, | ||
1094 | clk_base + AUDIO_SYNC_CLK_I2S0, 4, | ||
1095 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1096 | clk_register_clkdev(clk, "audio0", NULL); | ||
1097 | clks[audio0] = clk; | ||
1098 | |||
1099 | /* audio1 */ | ||
1100 | clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk, | ||
1101 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1102 | CLK_SET_RATE_NO_REPARENT, | ||
1103 | clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, NULL); | ||
1104 | clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0, | ||
1105 | clk_base + AUDIO_SYNC_CLK_I2S1, 4, | ||
1106 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1107 | clk_register_clkdev(clk, "audio1", NULL); | ||
1108 | clks[audio1] = clk; | ||
1109 | |||
1110 | /* audio2 */ | ||
1111 | clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk, | ||
1112 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1113 | CLK_SET_RATE_NO_REPARENT, | ||
1114 | clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, NULL); | ||
1115 | clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0, | ||
1116 | clk_base + AUDIO_SYNC_CLK_I2S2, 4, | ||
1117 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1118 | clk_register_clkdev(clk, "audio2", NULL); | ||
1119 | clks[audio2] = clk; | ||
1120 | |||
1121 | /* audio3 */ | ||
1122 | clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk, | ||
1123 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1124 | CLK_SET_RATE_NO_REPARENT, | ||
1125 | clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, NULL); | ||
1126 | clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0, | ||
1127 | clk_base + AUDIO_SYNC_CLK_I2S3, 4, | ||
1128 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1129 | clk_register_clkdev(clk, "audio3", NULL); | ||
1130 | clks[audio3] = clk; | ||
1131 | |||
1132 | /* audio4 */ | ||
1133 | clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk, | ||
1134 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1135 | CLK_SET_RATE_NO_REPARENT, | ||
1136 | clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, NULL); | ||
1137 | clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0, | ||
1138 | clk_base + AUDIO_SYNC_CLK_I2S4, 4, | ||
1139 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1140 | clk_register_clkdev(clk, "audio4", NULL); | ||
1141 | clks[audio4] = clk; | ||
1142 | |||
1143 | /* spdif */ | ||
1144 | clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk, | ||
1145 | ARRAY_SIZE(mux_audio_sync_clk), | ||
1146 | CLK_SET_RATE_NO_REPARENT, | ||
1147 | clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, NULL); | ||
1148 | clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0, | ||
1149 | clk_base + AUDIO_SYNC_CLK_SPDIF, 4, | ||
1150 | CLK_GATE_SET_TO_DISABLE, NULL); | ||
1151 | clk_register_clkdev(clk, "spdif", NULL); | ||
1152 | clks[spdif] = clk; | ||
1153 | |||
1154 | /* audio0_2x */ | ||
1155 | clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0", | ||
1156 | CLK_SET_RATE_PARENT, 2, 1); | ||
1157 | clk = tegra_clk_register_divider("audio0_div", "audio0_doubler", | ||
1158 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1, 0, | ||
1159 | &clk_doubler_lock); | ||
1160 | clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div", | ||
1161 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1162 | CLK_SET_RATE_PARENT, 113, &periph_v_regs, | ||
1163 | periph_clk_enb_refcnt); | ||
1164 | clk_register_clkdev(clk, "audio0_2x", NULL); | ||
1165 | clks[audio0_2x] = clk; | ||
1166 | |||
1167 | /* audio1_2x */ | ||
1168 | clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1", | ||
1169 | CLK_SET_RATE_PARENT, 2, 1); | ||
1170 | clk = tegra_clk_register_divider("audio1_div", "audio1_doubler", | ||
1171 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1, 0, | ||
1172 | &clk_doubler_lock); | ||
1173 | clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div", | ||
1174 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1175 | CLK_SET_RATE_PARENT, 114, &periph_v_regs, | ||
1176 | periph_clk_enb_refcnt); | ||
1177 | clk_register_clkdev(clk, "audio1_2x", NULL); | ||
1178 | clks[audio1_2x] = clk; | ||
1179 | |||
1180 | /* audio2_2x */ | ||
1181 | clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2", | ||
1182 | CLK_SET_RATE_PARENT, 2, 1); | ||
1183 | clk = tegra_clk_register_divider("audio2_div", "audio2_doubler", | ||
1184 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1, 0, | ||
1185 | &clk_doubler_lock); | ||
1186 | clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div", | ||
1187 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1188 | CLK_SET_RATE_PARENT, 115, &periph_v_regs, | ||
1189 | periph_clk_enb_refcnt); | ||
1190 | clk_register_clkdev(clk, "audio2_2x", NULL); | ||
1191 | clks[audio2_2x] = clk; | ||
1192 | |||
1193 | /* audio3_2x */ | ||
1194 | clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3", | ||
1195 | CLK_SET_RATE_PARENT, 2, 1); | ||
1196 | clk = tegra_clk_register_divider("audio3_div", "audio3_doubler", | ||
1197 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1, 0, | ||
1198 | &clk_doubler_lock); | ||
1199 | clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div", | ||
1200 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1201 | CLK_SET_RATE_PARENT, 116, &periph_v_regs, | ||
1202 | periph_clk_enb_refcnt); | ||
1203 | clk_register_clkdev(clk, "audio3_2x", NULL); | ||
1204 | clks[audio3_2x] = clk; | ||
1205 | |||
1206 | /* audio4_2x */ | ||
1207 | clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4", | ||
1208 | CLK_SET_RATE_PARENT, 2, 1); | ||
1209 | clk = tegra_clk_register_divider("audio4_div", "audio4_doubler", | ||
1210 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1, 0, | ||
1211 | &clk_doubler_lock); | ||
1212 | clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div", | ||
1213 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1214 | CLK_SET_RATE_PARENT, 117, &periph_v_regs, | ||
1215 | periph_clk_enb_refcnt); | ||
1216 | clk_register_clkdev(clk, "audio4_2x", NULL); | ||
1217 | clks[audio4_2x] = clk; | ||
1218 | |||
1219 | /* spdif_2x */ | ||
1220 | clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif", | ||
1221 | CLK_SET_RATE_PARENT, 2, 1); | ||
1222 | clk = tegra_clk_register_divider("spdif_div", "spdif_doubler", | ||
1223 | clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1, 0, | ||
1224 | &clk_doubler_lock); | ||
1225 | clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div", | ||
1226 | TEGRA_PERIPH_NO_RESET, clk_base, | ||
1227 | CLK_SET_RATE_PARENT, 118, &periph_v_regs, | ||
1228 | periph_clk_enb_refcnt); | ||
1229 | clk_register_clkdev(clk, "spdif_2x", NULL); | ||
1230 | clks[spdif_2x] = clk; | ||
1231 | } | ||
1232 | |||
1233 | static void __init tegra30_pmc_clk_init(void) | ||
1234 | { | ||
1235 | struct clk *clk; | ||
1236 | |||
1237 | /* clk_out_1 */ | ||
1238 | clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents, | ||
1239 | ARRAY_SIZE(clk_out1_parents), | ||
1240 | CLK_SET_RATE_NO_REPARENT, | ||
1241 | pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0, | ||
1242 | &clk_out_lock); | ||
1243 | clks[clk_out_1_mux] = clk; | ||
1244 | clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0, | ||
1245 | pmc_base + PMC_CLK_OUT_CNTRL, 2, 0, | ||
1246 | &clk_out_lock); | ||
1247 | clk_register_clkdev(clk, "extern1", "clk_out_1"); | ||
1248 | clks[clk_out_1] = clk; | ||
1249 | |||
1250 | /* clk_out_2 */ | ||
1251 | clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents, | ||
1252 | ARRAY_SIZE(clk_out2_parents), | ||
1253 | CLK_SET_RATE_NO_REPARENT, | ||
1254 | pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0, | ||
1255 | &clk_out_lock); | ||
1256 | clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0, | ||
1257 | pmc_base + PMC_CLK_OUT_CNTRL, 10, 0, | ||
1258 | &clk_out_lock); | ||
1259 | clk_register_clkdev(clk, "extern2", "clk_out_2"); | ||
1260 | clks[clk_out_2] = clk; | ||
1261 | |||
1262 | /* clk_out_3 */ | ||
1263 | clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents, | ||
1264 | ARRAY_SIZE(clk_out3_parents), | ||
1265 | CLK_SET_RATE_NO_REPARENT, | ||
1266 | pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0, | ||
1267 | &clk_out_lock); | ||
1268 | clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0, | ||
1269 | pmc_base + PMC_CLK_OUT_CNTRL, 18, 0, | ||
1270 | &clk_out_lock); | ||
1271 | clk_register_clkdev(clk, "extern3", "clk_out_3"); | ||
1272 | clks[clk_out_3] = clk; | ||
1273 | |||
1274 | /* blink */ | ||
1275 | writel_relaxed(0, pmc_base + PMC_BLINK_TIMER); | ||
1276 | clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0, | ||
1277 | pmc_base + PMC_DPD_PADS_ORIDE, | ||
1278 | PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL); | ||
1279 | clk = clk_register_gate(NULL, "blink", "blink_override", 0, | ||
1280 | pmc_base + PMC_CTRL, | ||
1281 | PMC_CTRL_BLINK_ENB, 0, NULL); | ||
1282 | clk_register_clkdev(clk, "blink", NULL); | ||
1283 | clks[blink] = clk; | ||
1284 | |||
1285 | } | 997 | } |
1286 | 998 | ||
1287 | static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", | 999 | static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", |
@@ -1332,8 +1044,7 @@ static void __init tegra30_super_clk_init(void) | |||
1332 | CLK_SET_RATE_PARENT, | 1044 | CLK_SET_RATE_PARENT, |
1333 | clk_base + CCLKG_BURST_POLICY, | 1045 | clk_base + CCLKG_BURST_POLICY, |
1334 | 0, 4, 0, 0, NULL); | 1046 | 0, 4, 0, 0, NULL); |
1335 | clk_register_clkdev(clk, "cclk_g", NULL); | 1047 | clks[TEGRA30_CLK_CCLK_G] = clk; |
1336 | clks[cclk_g] = clk; | ||
1337 | 1048 | ||
1338 | /* | 1049 | /* |
1339 | * Clock input to cclk_lp divided from pll_p using | 1050 | * Clock input to cclk_lp divided from pll_p using |
@@ -1369,8 +1080,7 @@ static void __init tegra30_super_clk_init(void) | |||
1369 | clk_base + CCLKLP_BURST_POLICY, | 1080 | clk_base + CCLKLP_BURST_POLICY, |
1370 | TEGRA_DIVIDER_2, 4, 8, 9, | 1081 | TEGRA_DIVIDER_2, 4, 8, 9, |
1371 | NULL); | 1082 | NULL); |
1372 | clk_register_clkdev(clk, "cclk_lp", NULL); | 1083 | clks[TEGRA30_CLK_CCLK_LP] = clk; |
1373 | clks[cclk_lp] = clk; | ||
1374 | 1084 | ||
1375 | /* SCLK */ | 1085 | /* SCLK */ |
1376 | clk = tegra_clk_register_super_mux("sclk", sclk_parents, | 1086 | clk = tegra_clk_register_super_mux("sclk", sclk_parents, |
@@ -1378,142 +1088,44 @@ static void __init tegra30_super_clk_init(void) | |||
1378 | CLK_SET_RATE_PARENT, | 1088 | CLK_SET_RATE_PARENT, |
1379 | clk_base + SCLK_BURST_POLICY, | 1089 | clk_base + SCLK_BURST_POLICY, |
1380 | 0, 4, 0, 0, NULL); | 1090 | 0, 4, 0, 0, NULL); |
1381 | clk_register_clkdev(clk, "sclk", NULL); | 1091 | clks[TEGRA30_CLK_SCLK] = clk; |
1382 | clks[sclk] = clk; | ||
1383 | |||
1384 | /* HCLK */ | ||
1385 | clk = clk_register_divider(NULL, "hclk_div", "sclk", 0, | ||
1386 | clk_base + SYSTEM_CLK_RATE, 4, 2, 0, | ||
1387 | &sysrate_lock); | ||
1388 | clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT, | ||
1389 | clk_base + SYSTEM_CLK_RATE, 7, | ||
1390 | CLK_GATE_SET_TO_DISABLE, &sysrate_lock); | ||
1391 | clk_register_clkdev(clk, "hclk", NULL); | ||
1392 | clks[hclk] = clk; | ||
1393 | |||
1394 | /* PCLK */ | ||
1395 | clk = clk_register_divider(NULL, "pclk_div", "hclk", 0, | ||
1396 | clk_base + SYSTEM_CLK_RATE, 0, 2, 0, | ||
1397 | &sysrate_lock); | ||
1398 | clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT, | ||
1399 | clk_base + SYSTEM_CLK_RATE, 3, | ||
1400 | CLK_GATE_SET_TO_DISABLE, &sysrate_lock); | ||
1401 | clk_register_clkdev(clk, "pclk", NULL); | ||
1402 | clks[pclk] = clk; | ||
1403 | 1092 | ||
1404 | /* twd */ | 1093 | /* twd */ |
1405 | clk = clk_register_fixed_factor(NULL, "twd", "cclk_g", | 1094 | clk = clk_register_fixed_factor(NULL, "twd", "cclk_g", |
1406 | CLK_SET_RATE_PARENT, 1, 2); | 1095 | CLK_SET_RATE_PARENT, 1, 2); |
1407 | clk_register_clkdev(clk, "twd", NULL); | 1096 | clks[TEGRA30_CLK_TWD] = clk; |
1408 | clks[twd] = clk; | 1097 | |
1098 | tegra_super_clk_gen4_init(clk_base, pmc_base, tegra30_clks, NULL); | ||
1409 | } | 1099 | } |
1410 | 1100 | ||
1411 | static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p", | 1101 | static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p", |
1412 | "clk_m" }; | 1102 | "clk_m" }; |
1413 | static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; | 1103 | static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; |
1414 | static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; | 1104 | static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; |
1415 | static const char *i2s0_parents[] = { "pll_a_out0", "audio0_2x", "pll_p", | ||
1416 | "clk_m" }; | ||
1417 | static const char *i2s1_parents[] = { "pll_a_out0", "audio1_2x", "pll_p", | ||
1418 | "clk_m" }; | ||
1419 | static const char *i2s2_parents[] = { "pll_a_out0", "audio2_2x", "pll_p", | ||
1420 | "clk_m" }; | ||
1421 | static const char *i2s3_parents[] = { "pll_a_out0", "audio3_2x", "pll_p", | ||
1422 | "clk_m" }; | ||
1423 | static const char *i2s4_parents[] = { "pll_a_out0", "audio4_2x", "pll_p", | ||
1424 | "clk_m" }; | ||
1425 | static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p", | 1105 | static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p", |
1426 | "clk_m" }; | 1106 | "clk_m" }; |
1427 | static const char *spdif_in_parents[] = { "pll_p", "pll_c", "pll_m" }; | ||
1428 | static const char *mux_pllpc_clk32k_clkm[] = { "pll_p", "pll_c", "clk_32k", | ||
1429 | "clk_m" }; | ||
1430 | static const char *mux_pllpc_clkm_clk32k[] = { "pll_p", "pll_c", "clk_m", | ||
1431 | "clk_32k" }; | ||
1432 | static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" }; | 1107 | static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" }; |
1433 | static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c", | ||
1434 | "clk_m" }; | ||
1435 | static const char *mux_pllp_clkm[] = { "pll_p", "unused", "unused", "clk_m" }; | ||
1436 | static const char *mux_pllpmdacd2_clkm[] = { "pll_p", "pll_m", "pll_d_out0", | 1108 | static const char *mux_pllpmdacd2_clkm[] = { "pll_p", "pll_m", "pll_d_out0", |
1437 | "pll_a_out0", "pll_c", | 1109 | "pll_a_out0", "pll_c", |
1438 | "pll_d2_out0", "clk_m" }; | 1110 | "pll_d2_out0", "clk_m" }; |
1439 | static const char *mux_plla_clk32k_pllp_clkm_plle[] = { "pll_a_out0", | ||
1440 | "clk_32k", "pll_p", | ||
1441 | "clk_m", "pll_e" }; | ||
1442 | static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0", | 1111 | static const char *mux_plld_out0_plld2_out0[] = { "pll_d_out0", |
1443 | "pll_d2_out0" }; | 1112 | "pll_d2_out0" }; |
1113 | static const char *pwm_parents[] = { "pll_p", "pll_c", "clk_32k", "clk_m" }; | ||
1444 | 1114 | ||
1445 | static struct tegra_periph_init_data tegra_periph_clk_list[] = { | 1115 | static struct tegra_periph_init_data tegra_periph_clk_list[] = { |
1446 | TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", i2s0_parents, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0), | 1116 | TEGRA_INIT_DATA_MUX("spdif_out", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, TEGRA_PERIPH_ON_APB, TEGRA30_CLK_SPDIF_OUT), |
1447 | TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", i2s1_parents, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1), | 1117 | TEGRA_INIT_DATA_MUX("d_audio", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, 0, TEGRA30_CLK_D_AUDIO), |
1448 | TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", i2s2_parents, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2), | 1118 | TEGRA_INIT_DATA_MUX("dam0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, 0, TEGRA30_CLK_DAM0), |
1449 | TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", i2s3_parents, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3), | 1119 | TEGRA_INIT_DATA_MUX("dam1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, 0, TEGRA30_CLK_DAM1), |
1450 | TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", i2s4_parents, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4), | 1120 | TEGRA_INIT_DATA_MUX("dam2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, 0, TEGRA30_CLK_DAM2), |
1451 | TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", spdif_out_parents, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out), | 1121 | TEGRA_INIT_DATA_INT("3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, TEGRA_PERIPH_MANUAL_RESET, TEGRA30_CLK_GR3D2), |
1452 | TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", spdif_in_parents, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in), | 1122 | TEGRA_INIT_DATA_INT("se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, 0, TEGRA30_CLK_SE), |
1453 | TEGRA_INIT_DATA_MUX("d_audio", "d_audio", "tegra30-ahub", mux_pllacp_clkm, CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, 0, d_audio), | 1123 | TEGRA_INIT_DATA_MUX8("hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA30_CLK_HDMI), |
1454 | TEGRA_INIT_DATA_MUX("dam0", NULL, "tegra30-dam.0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, &periph_v_regs, 0, dam0), | 1124 | TEGRA_INIT_DATA("pwm", NULL, NULL, pwm_parents, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, TEGRA30_CLK_PWM), |
1455 | TEGRA_INIT_DATA_MUX("dam1", NULL, "tegra30-dam.1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, &periph_v_regs, 0, dam1), | ||
1456 | TEGRA_INIT_DATA_MUX("dam2", NULL, "tegra30-dam.2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, &periph_v_regs, 0, dam2), | ||
1457 | TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, 0, hda), | ||
1458 | TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllpcm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, 0, hda2codec_2x), | ||
1459 | TEGRA_INIT_DATA_MUX("sbc1", NULL, "spi_tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1), | ||
1460 | TEGRA_INIT_DATA_MUX("sbc2", NULL, "spi_tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2), | ||
1461 | TEGRA_INIT_DATA_MUX("sbc3", NULL, "spi_tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3), | ||
1462 | TEGRA_INIT_DATA_MUX("sbc4", NULL, "spi_tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4), | ||
1463 | TEGRA_INIT_DATA_MUX("sbc5", NULL, "spi_tegra.4", mux_pllpcm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5), | ||
1464 | TEGRA_INIT_DATA_MUX("sbc6", NULL, "spi_tegra.5", mux_pllpcm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6), | ||
1465 | TEGRA_INIT_DATA_MUX("sata_oob", NULL, "tegra_sata_oob", mux_pllpcm_clkm, CLK_SOURCE_SATA_OOB, 123, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata_oob), | ||
1466 | TEGRA_INIT_DATA_MUX("sata", NULL, "tegra_sata", mux_pllpcm_clkm, CLK_SOURCE_SATA, 124, &periph_v_regs, TEGRA_PERIPH_ON_APB, sata), | ||
1467 | TEGRA_INIT_DATA_MUX("ndflash", NULL, "tegra_nand", mux_pllpcm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_l_regs, TEGRA_PERIPH_ON_APB, ndflash), | ||
1468 | TEGRA_INIT_DATA_MUX("ndspeed", NULL, "tegra_nand_speed", mux_pllpcm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed), | ||
1469 | TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllpcm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir), | ||
1470 | TEGRA_INIT_DATA_MUX("csite", NULL, "csite", mux_pllpcm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite), | ||
1471 | TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllpcm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la), | ||
1472 | TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllpcm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr), | ||
1473 | TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllpcm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi), | ||
1474 | TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllpc_clkm_clk32k, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor), | ||
1475 | TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllpc_clk32k_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow), | ||
1476 | TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllpcm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde), | ||
1477 | TEGRA_INIT_DATA_INT("vi", "vi", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi), | ||
1478 | TEGRA_INIT_DATA_INT("epp", NULL, "epp", mux_pllmcpa, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp), | ||
1479 | TEGRA_INIT_DATA_INT("mpe", NULL, "mpe", mux_pllmcpa, CLK_SOURCE_MPE, 60, &periph_h_regs, 0, mpe), | ||
1480 | TEGRA_INIT_DATA_INT("host1x", NULL, "host1x", mux_pllmcpa, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x), | ||
1481 | TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllmcpa, CLK_SOURCE_3D, 24, &periph_l_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d), | ||
1482 | TEGRA_INIT_DATA_INT("3d2", NULL, "3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, &periph_v_regs, TEGRA_PERIPH_MANUAL_RESET, gr3d2), | ||
1483 | TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllmcpa, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr2d), | ||
1484 | TEGRA_INIT_DATA_INT("se", NULL, "se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, 0, se), | ||
1485 | TEGRA_INIT_DATA_MUX("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect), | ||
1486 | TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllpcm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor), | ||
1487 | TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllpcm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1), | ||
1488 | TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllpcm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2), | ||
1489 | TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllpcm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3), | ||
1490 | TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllpcm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4), | ||
1491 | TEGRA_INIT_DATA_MUX("cve", NULL, "cve", mux_pllpdc_clkm, CLK_SOURCE_CVE, 49, &periph_h_regs, 0, cve), | ||
1492 | TEGRA_INIT_DATA_MUX("tvo", NULL, "tvo", mux_pllpdc_clkm, CLK_SOURCE_TVO, 49, &periph_h_regs, 0, tvo), | ||
1493 | TEGRA_INIT_DATA_MUX("tvdac", NULL, "tvdac", mux_pllpdc_clkm, CLK_SOURCE_TVDAC, 53, &periph_h_regs, 0, tvdac), | ||
1494 | TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllpc_clk32k_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon), | ||
1495 | TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllmcpa, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor), | ||
1496 | TEGRA_INIT_DATA_DIV16("i2c1", "div-clk", "tegra-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2c1), | ||
1497 | TEGRA_INIT_DATA_DIV16("i2c2", "div-clk", "tegra-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c2), | ||
1498 | TEGRA_INIT_DATA_DIV16("i2c3", "div-clk", "tegra-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2c3), | ||
1499 | TEGRA_INIT_DATA_DIV16("i2c4", "div-clk", "tegra-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2c4), | ||
1500 | TEGRA_INIT_DATA_DIV16("i2c5", "div-clk", "tegra-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, TEGRA_PERIPH_ON_APB, i2c5), | ||
1501 | TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllpcm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta), | ||
1502 | TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllpcm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb), | ||
1503 | TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllpcm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc), | ||
1504 | TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllpcm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd), | ||
1505 | TEGRA_INIT_DATA_UART("uarte", NULL, "tegra_uart.4", mux_pllpcm_clkm, CLK_SOURCE_UARTE, 66, &periph_u_regs, uarte), | ||
1506 | TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi), | ||
1507 | TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1), | ||
1508 | TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2), | ||
1509 | TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32k_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3), | ||
1510 | TEGRA_INIT_DATA("pwm", NULL, "pwm", mux_pllpc_clk32k_clkm, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, &periph_l_regs, 17, periph_clk_enb_refcnt, 0, pwm), | ||
1511 | }; | 1125 | }; |
1512 | 1126 | ||
1513 | static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { | 1127 | static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { |
1514 | TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP1, 29, 3, 27, &periph_l_regs, 0, disp1), | 1128 | TEGRA_INIT_DATA_NODIV("dsib", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, 0, TEGRA30_CLK_DSIB), |
1515 | TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllpmdacd2_clkm, CLK_SOURCE_DISP2, 29, 3, 26, &periph_l_regs, 0, disp2), | ||
1516 | TEGRA_INIT_DATA_NODIV("dsib", NULL, "tegradc.1", mux_plld_out0_plld2_out0, CLK_SOURCE_DSIB, 25, 1, 82, &periph_u_regs, 0, dsib), | ||
1517 | }; | 1129 | }; |
1518 | 1130 | ||
1519 | static void __init tegra30_periph_clk_init(void) | 1131 | static void __init tegra30_periph_clk_init(void) |
@@ -1522,170 +1134,20 @@ static void __init tegra30_periph_clk_init(void) | |||
1522 | struct clk *clk; | 1134 | struct clk *clk; |
1523 | int i; | 1135 | int i; |
1524 | 1136 | ||
1525 | /* apbdma */ | ||
1526 | clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base, 0, 34, | ||
1527 | &periph_h_regs, periph_clk_enb_refcnt); | ||
1528 | clk_register_clkdev(clk, NULL, "tegra-apbdma"); | ||
1529 | clks[apbdma] = clk; | ||
1530 | |||
1531 | /* rtc */ | ||
1532 | clk = tegra_clk_register_periph_gate("rtc", "clk_32k", | ||
1533 | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, | ||
1534 | clk_base, 0, 4, &periph_l_regs, | ||
1535 | periph_clk_enb_refcnt); | ||
1536 | clk_register_clkdev(clk, NULL, "rtc-tegra"); | ||
1537 | clks[rtc] = clk; | ||
1538 | |||
1539 | /* timer */ | ||
1540 | clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base, 0, | ||
1541 | 5, &periph_l_regs, periph_clk_enb_refcnt); | ||
1542 | clk_register_clkdev(clk, NULL, "timer"); | ||
1543 | clks[timer] = clk; | ||
1544 | |||
1545 | /* kbc */ | ||
1546 | clk = tegra_clk_register_periph_gate("kbc", "clk_32k", | ||
1547 | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, | ||
1548 | clk_base, 0, 36, &periph_h_regs, | ||
1549 | periph_clk_enb_refcnt); | ||
1550 | clk_register_clkdev(clk, NULL, "tegra-kbc"); | ||
1551 | clks[kbc] = clk; | ||
1552 | |||
1553 | /* csus */ | ||
1554 | clk = tegra_clk_register_periph_gate("csus", "clk_m", | ||
1555 | TEGRA_PERIPH_NO_RESET | TEGRA_PERIPH_ON_APB, | ||
1556 | clk_base, 0, 92, &periph_u_regs, | ||
1557 | periph_clk_enb_refcnt); | ||
1558 | clk_register_clkdev(clk, "csus", "tengra_camera"); | ||
1559 | clks[csus] = clk; | ||
1560 | |||
1561 | /* vcp */ | ||
1562 | clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base, 0, 29, | ||
1563 | &periph_l_regs, periph_clk_enb_refcnt); | ||
1564 | clk_register_clkdev(clk, "vcp", "tegra-avp"); | ||
1565 | clks[vcp] = clk; | ||
1566 | |||
1567 | /* bsea */ | ||
1568 | clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base, 0, | ||
1569 | 62, &periph_h_regs, periph_clk_enb_refcnt); | ||
1570 | clk_register_clkdev(clk, "bsea", "tegra-avp"); | ||
1571 | clks[bsea] = clk; | ||
1572 | |||
1573 | /* bsev */ | ||
1574 | clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base, 0, | ||
1575 | 63, &periph_h_regs, periph_clk_enb_refcnt); | ||
1576 | clk_register_clkdev(clk, "bsev", "tegra-aes"); | ||
1577 | clks[bsev] = clk; | ||
1578 | |||
1579 | /* usbd */ | ||
1580 | clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base, 0, | ||
1581 | 22, &periph_l_regs, periph_clk_enb_refcnt); | ||
1582 | clk_register_clkdev(clk, NULL, "fsl-tegra-udc"); | ||
1583 | clks[usbd] = clk; | ||
1584 | |||
1585 | /* usb2 */ | ||
1586 | clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base, 0, | ||
1587 | 58, &periph_h_regs, periph_clk_enb_refcnt); | ||
1588 | clk_register_clkdev(clk, NULL, "tegra-ehci.1"); | ||
1589 | clks[usb2] = clk; | ||
1590 | |||
1591 | /* usb3 */ | ||
1592 | clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base, 0, | ||
1593 | 59, &periph_h_regs, periph_clk_enb_refcnt); | ||
1594 | clk_register_clkdev(clk, NULL, "tegra-ehci.2"); | ||
1595 | clks[usb3] = clk; | ||
1596 | |||
1597 | /* dsia */ | 1137 | /* dsia */ |
1598 | clk = tegra_clk_register_periph_gate("dsia", "pll_d_out0", 0, clk_base, | 1138 | clk = tegra_clk_register_periph_gate("dsia", "pll_d_out0", 0, clk_base, |
1599 | 0, 48, &periph_h_regs, | 1139 | 0, 48, periph_clk_enb_refcnt); |
1600 | periph_clk_enb_refcnt); | 1140 | clks[TEGRA30_CLK_DSIA] = clk; |
1601 | clk_register_clkdev(clk, "dsia", "tegradc.0"); | ||
1602 | clks[dsia] = clk; | ||
1603 | |||
1604 | /* csi */ | ||
1605 | clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base, | ||
1606 | 0, 52, &periph_h_regs, | ||
1607 | periph_clk_enb_refcnt); | ||
1608 | clk_register_clkdev(clk, "csi", "tegra_camera"); | ||
1609 | clks[csi] = clk; | ||
1610 | |||
1611 | /* isp */ | ||
1612 | clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0, 23, | ||
1613 | &periph_l_regs, periph_clk_enb_refcnt); | ||
1614 | clk_register_clkdev(clk, "isp", "tegra_camera"); | ||
1615 | clks[isp] = clk; | ||
1616 | 1141 | ||
1617 | /* pcie */ | 1142 | /* pcie */ |
1618 | clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0, | 1143 | clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0, |
1619 | 70, &periph_u_regs, periph_clk_enb_refcnt); | 1144 | 70, periph_clk_enb_refcnt); |
1620 | clk_register_clkdev(clk, "pcie", "tegra-pcie"); | 1145 | clks[TEGRA30_CLK_PCIE] = clk; |
1621 | clks[pcie] = clk; | ||
1622 | 1146 | ||
1623 | /* afi */ | 1147 | /* afi */ |
1624 | clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, | 1148 | clk = tegra_clk_register_periph_gate("afi", "clk_m", 0, clk_base, 0, 72, |
1625 | &periph_u_regs, periph_clk_enb_refcnt); | ||
1626 | clk_register_clkdev(clk, "afi", "tegra-pcie"); | ||
1627 | clks[afi] = clk; | ||
1628 | |||
1629 | /* pciex */ | ||
1630 | clk = tegra_clk_register_periph_gate("pciex", "pll_e", 0, clk_base, 0, | ||
1631 | 74, &periph_u_regs, periph_clk_enb_refcnt); | ||
1632 | clk_register_clkdev(clk, "pciex", "tegra-pcie"); | ||
1633 | clks[pciex] = clk; | ||
1634 | |||
1635 | /* kfuse */ | ||
1636 | clk = tegra_clk_register_periph_gate("kfuse", "clk_m", | ||
1637 | TEGRA_PERIPH_ON_APB, | ||
1638 | clk_base, 0, 40, &periph_h_regs, | ||
1639 | periph_clk_enb_refcnt); | ||
1640 | clk_register_clkdev(clk, NULL, "kfuse-tegra"); | ||
1641 | clks[kfuse] = clk; | ||
1642 | |||
1643 | /* fuse */ | ||
1644 | clk = tegra_clk_register_periph_gate("fuse", "clk_m", | ||
1645 | TEGRA_PERIPH_ON_APB, | ||
1646 | clk_base, 0, 39, &periph_h_regs, | ||
1647 | periph_clk_enb_refcnt); | ||
1648 | clk_register_clkdev(clk, "fuse", "fuse-tegra"); | ||
1649 | clks[fuse] = clk; | ||
1650 | |||
1651 | /* fuse_burn */ | ||
1652 | clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m", | ||
1653 | TEGRA_PERIPH_ON_APB, | ||
1654 | clk_base, 0, 39, &periph_h_regs, | ||
1655 | periph_clk_enb_refcnt); | 1149 | periph_clk_enb_refcnt); |
1656 | clk_register_clkdev(clk, "fuse_burn", "fuse-tegra"); | 1150 | clks[TEGRA30_CLK_AFI] = clk; |
1657 | clks[fuse_burn] = clk; | ||
1658 | |||
1659 | /* apbif */ | ||
1660 | clk = tegra_clk_register_periph_gate("apbif", "clk_m", 0, | ||
1661 | clk_base, 0, 107, &periph_v_regs, | ||
1662 | periph_clk_enb_refcnt); | ||
1663 | clk_register_clkdev(clk, "apbif", "tegra30-ahub"); | ||
1664 | clks[apbif] = clk; | ||
1665 | |||
1666 | /* hda2hdmi */ | ||
1667 | clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m", | ||
1668 | TEGRA_PERIPH_ON_APB, | ||
1669 | clk_base, 0, 128, &periph_w_regs, | ||
1670 | periph_clk_enb_refcnt); | ||
1671 | clk_register_clkdev(clk, "hda2hdmi", "tegra30-hda"); | ||
1672 | clks[hda2hdmi] = clk; | ||
1673 | |||
1674 | /* sata_cold */ | ||
1675 | clk = tegra_clk_register_periph_gate("sata_cold", "clk_m", | ||
1676 | TEGRA_PERIPH_ON_APB, | ||
1677 | clk_base, 0, 129, &periph_w_regs, | ||
1678 | periph_clk_enb_refcnt); | ||
1679 | clk_register_clkdev(clk, NULL, "tegra_sata_cold"); | ||
1680 | clks[sata_cold] = clk; | ||
1681 | |||
1682 | /* dtv */ | ||
1683 | clk = tegra_clk_register_periph_gate("dtv", "clk_m", | ||
1684 | TEGRA_PERIPH_ON_APB, | ||
1685 | clk_base, 0, 79, &periph_u_regs, | ||
1686 | periph_clk_enb_refcnt); | ||
1687 | clk_register_clkdev(clk, NULL, "dtv"); | ||
1688 | clks[dtv] = clk; | ||
1689 | 1151 | ||
1690 | /* emc */ | 1152 | /* emc */ |
1691 | clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, | 1153 | clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, |
@@ -1694,84 +1156,37 @@ static void __init tegra30_periph_clk_init(void) | |||
1694 | clk_base + CLK_SOURCE_EMC, | 1156 | clk_base + CLK_SOURCE_EMC, |
1695 | 30, 2, 0, NULL); | 1157 | 30, 2, 0, NULL); |
1696 | clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, | 1158 | clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0, |
1697 | 57, &periph_h_regs, periph_clk_enb_refcnt); | 1159 | 57, periph_clk_enb_refcnt); |
1698 | clk_register_clkdev(clk, "emc", NULL); | 1160 | clks[TEGRA30_CLK_EMC] = clk; |
1699 | clks[emc] = clk; | 1161 | |
1162 | /* cml0 */ | ||
1163 | clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, | ||
1164 | 0, 0, &cml_lock); | ||
1165 | clks[TEGRA30_CLK_CML0] = clk; | ||
1166 | |||
1167 | /* cml1 */ | ||
1168 | clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, | ||
1169 | 1, 0, &cml_lock); | ||
1170 | clks[TEGRA30_CLK_CML1] = clk; | ||
1700 | 1171 | ||
1701 | for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { | 1172 | for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { |
1702 | data = &tegra_periph_clk_list[i]; | 1173 | data = &tegra_periph_clk_list[i]; |
1703 | clk = tegra_clk_register_periph(data->name, data->parent_names, | 1174 | clk = tegra_clk_register_periph(data->name, data->p.parent_names, |
1704 | data->num_parents, &data->periph, | 1175 | data->num_parents, &data->periph, |
1705 | clk_base, data->offset, data->flags); | 1176 | clk_base, data->offset, data->flags); |
1706 | clk_register_clkdev(clk, data->con_id, data->dev_id); | ||
1707 | clks[data->clk_id] = clk; | 1177 | clks[data->clk_id] = clk; |
1708 | } | 1178 | } |
1709 | 1179 | ||
1710 | for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { | 1180 | for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) { |
1711 | data = &tegra_periph_nodiv_clk_list[i]; | 1181 | data = &tegra_periph_nodiv_clk_list[i]; |
1712 | clk = tegra_clk_register_periph_nodiv(data->name, | 1182 | clk = tegra_clk_register_periph_nodiv(data->name, |
1713 | data->parent_names, | 1183 | data->p.parent_names, |
1714 | data->num_parents, &data->periph, | 1184 | data->num_parents, &data->periph, |
1715 | clk_base, data->offset); | 1185 | clk_base, data->offset); |
1716 | clk_register_clkdev(clk, data->con_id, data->dev_id); | ||
1717 | clks[data->clk_id] = clk; | 1186 | clks[data->clk_id] = clk; |
1718 | } | 1187 | } |
1719 | } | ||
1720 | |||
1721 | static void __init tegra30_fixed_clk_init(void) | ||
1722 | { | ||
1723 | struct clk *clk; | ||
1724 | |||
1725 | /* clk_32k */ | ||
1726 | clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, | ||
1727 | 32768); | ||
1728 | clk_register_clkdev(clk, "clk_32k", NULL); | ||
1729 | clks[clk_32k] = clk; | ||
1730 | 1188 | ||
1731 | /* clk_m_div2 */ | 1189 | tegra_periph_clk_init(clk_base, pmc_base, tegra30_clks, &pll_p_params); |
1732 | clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m", | ||
1733 | CLK_SET_RATE_PARENT, 1, 2); | ||
1734 | clk_register_clkdev(clk, "clk_m_div2", NULL); | ||
1735 | clks[clk_m_div2] = clk; | ||
1736 | |||
1737 | /* clk_m_div4 */ | ||
1738 | clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m", | ||
1739 | CLK_SET_RATE_PARENT, 1, 4); | ||
1740 | clk_register_clkdev(clk, "clk_m_div4", NULL); | ||
1741 | clks[clk_m_div4] = clk; | ||
1742 | |||
1743 | /* cml0 */ | ||
1744 | clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, | ||
1745 | 0, 0, &cml_lock); | ||
1746 | clk_register_clkdev(clk, "cml0", NULL); | ||
1747 | clks[cml0] = clk; | ||
1748 | |||
1749 | /* cml1 */ | ||
1750 | clk = clk_register_gate(NULL, "cml1", "pll_e", 0, clk_base + PLLE_AUX, | ||
1751 | 1, 0, &cml_lock); | ||
1752 | clk_register_clkdev(clk, "cml1", NULL); | ||
1753 | clks[cml1] = clk; | ||
1754 | } | ||
1755 | |||
1756 | static void __init tegra30_osc_clk_init(void) | ||
1757 | { | ||
1758 | struct clk *clk; | ||
1759 | unsigned int pll_ref_div; | ||
1760 | |||
1761 | tegra30_clk_measure_input_freq(); | ||
1762 | |||
1763 | /* clk_m */ | ||
1764 | clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT, | ||
1765 | input_freq); | ||
1766 | clk_register_clkdev(clk, "clk_m", NULL); | ||
1767 | clks[clk_m] = clk; | ||
1768 | |||
1769 | /* pll_ref */ | ||
1770 | pll_ref_div = tegra30_get_pll_ref_div(); | ||
1771 | clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m", | ||
1772 | CLK_SET_RATE_PARENT, 1, pll_ref_div); | ||
1773 | clk_register_clkdev(clk, "pll_ref", NULL); | ||
1774 | clks[pll_ref] = clk; | ||
1775 | } | 1190 | } |
1776 | 1191 | ||
1777 | /* Tegra30 CPU clock and reset control functions */ | 1192 | /* Tegra30 CPU clock and reset control functions */ |
@@ -1913,48 +1328,49 @@ static struct tegra_cpu_car_ops tegra30_cpu_car_ops = { | |||
1913 | }; | 1328 | }; |
1914 | 1329 | ||
1915 | static struct tegra_clk_init_table init_table[] __initdata = { | 1330 | static struct tegra_clk_init_table init_table[] __initdata = { |
1916 | {uarta, pll_p, 408000000, 0}, | 1331 | {TEGRA30_CLK_UARTA, TEGRA30_CLK_PLL_P, 408000000, 0}, |
1917 | {uartb, pll_p, 408000000, 0}, | 1332 | {TEGRA30_CLK_UARTB, TEGRA30_CLK_PLL_P, 408000000, 0}, |
1918 | {uartc, pll_p, 408000000, 0}, | 1333 | {TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 408000000, 0}, |
1919 | {uartd, pll_p, 408000000, 0}, | 1334 | {TEGRA30_CLK_UARTD, TEGRA30_CLK_PLL_P, 408000000, 0}, |
1920 | {uarte, pll_p, 408000000, 0}, | 1335 | {TEGRA30_CLK_UARTE, TEGRA30_CLK_PLL_P, 408000000, 0}, |
1921 | {pll_a, clk_max, 564480000, 1}, | 1336 | {TEGRA30_CLK_PLL_A, TEGRA30_CLK_CLK_MAX, 564480000, 1}, |
1922 | {pll_a_out0, clk_max, 11289600, 1}, | 1337 | {TEGRA30_CLK_PLL_A_OUT0, TEGRA30_CLK_CLK_MAX, 11289600, 1}, |
1923 | {extern1, pll_a_out0, 0, 1}, | 1338 | {TEGRA30_CLK_EXTERN1, TEGRA30_CLK_PLL_A_OUT0, 0, 1}, |
1924 | {clk_out_1_mux, extern1, 0, 0}, | 1339 | {TEGRA30_CLK_CLK_OUT_1_MUX, TEGRA30_CLK_EXTERN1, 0, 0}, |
1925 | {clk_out_1, clk_max, 0, 1}, | 1340 | {TEGRA30_CLK_CLK_OUT_1, TEGRA30_CLK_CLK_MAX, 0, 1}, |
1926 | {blink, clk_max, 0, 1}, | 1341 | {TEGRA30_CLK_BLINK, TEGRA30_CLK_CLK_MAX, 0, 1}, |
1927 | {i2s0, pll_a_out0, 11289600, 0}, | 1342 | {TEGRA30_CLK_I2S0, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, |
1928 | {i2s1, pll_a_out0, 11289600, 0}, | 1343 | {TEGRA30_CLK_I2S1, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, |
1929 | {i2s2, pll_a_out0, 11289600, 0}, | 1344 | {TEGRA30_CLK_I2S2, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, |
1930 | {i2s3, pll_a_out0, 11289600, 0}, | 1345 | {TEGRA30_CLK_I2S3, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, |
1931 | {i2s4, pll_a_out0, 11289600, 0}, | 1346 | {TEGRA30_CLK_I2S4, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0}, |
1932 | {sdmmc1, pll_p, 48000000, 0}, | 1347 | {TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0}, |
1933 | {sdmmc2, pll_p, 48000000, 0}, | 1348 | {TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0}, |
1934 | {sdmmc3, pll_p, 48000000, 0}, | 1349 | {TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0}, |
1935 | {pll_m, clk_max, 0, 1}, | 1350 | {TEGRA30_CLK_PLL_M, TEGRA30_CLK_CLK_MAX, 0, 1}, |
1936 | {pclk, clk_max, 0, 1}, | 1351 | {TEGRA30_CLK_PCLK, TEGRA30_CLK_CLK_MAX, 0, 1}, |
1937 | {csite, clk_max, 0, 1}, | 1352 | {TEGRA30_CLK_CSITE, TEGRA30_CLK_CLK_MAX, 0, 1}, |
1938 | {emc, clk_max, 0, 1}, | 1353 | {TEGRA30_CLK_EMC, TEGRA30_CLK_CLK_MAX, 0, 1}, |
1939 | {mselect, clk_max, 0, 1}, | 1354 | {TEGRA30_CLK_MSELECT, TEGRA30_CLK_CLK_MAX, 0, 1}, |
1940 | {sbc1, pll_p, 100000000, 0}, | 1355 | {TEGRA30_CLK_SBC1, TEGRA30_CLK_PLL_P, 100000000, 0}, |
1941 | {sbc2, pll_p, 100000000, 0}, | 1356 | {TEGRA30_CLK_SBC2, TEGRA30_CLK_PLL_P, 100000000, 0}, |
1942 | {sbc3, pll_p, 100000000, 0}, | 1357 | {TEGRA30_CLK_SBC3, TEGRA30_CLK_PLL_P, 100000000, 0}, |
1943 | {sbc4, pll_p, 100000000, 0}, | 1358 | {TEGRA30_CLK_SBC4, TEGRA30_CLK_PLL_P, 100000000, 0}, |
1944 | {sbc5, pll_p, 100000000, 0}, | 1359 | {TEGRA30_CLK_SBC5, TEGRA30_CLK_PLL_P, 100000000, 0}, |
1945 | {sbc6, pll_p, 100000000, 0}, | 1360 | {TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0}, |
1946 | {host1x, pll_c, 150000000, 0}, | 1361 | {TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0}, |
1947 | {disp1, pll_p, 600000000, 0}, | 1362 | {TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0}, |
1948 | {disp2, pll_p, 600000000, 0}, | 1363 | {TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0}, |
1949 | {twd, clk_max, 0, 1}, | 1364 | {TEGRA30_CLK_TWD, TEGRA30_CLK_CLK_MAX, 0, 1}, |
1950 | {gr2d, pll_c, 300000000, 0}, | 1365 | {TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0}, |
1951 | {gr3d, pll_c, 300000000, 0}, | 1366 | {TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0}, |
1952 | {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */ | 1367 | {TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0}, |
1368 | {TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry. */ | ||
1953 | }; | 1369 | }; |
1954 | 1370 | ||
1955 | static void __init tegra30_clock_apply_init_table(void) | 1371 | static void __init tegra30_clock_apply_init_table(void) |
1956 | { | 1372 | { |
1957 | tegra_init_from_table(init_table, clks, clk_max); | 1373 | tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX); |
1958 | } | 1374 | } |
1959 | 1375 | ||
1960 | /* | 1376 | /* |
@@ -1963,19 +1379,18 @@ static void __init tegra30_clock_apply_init_table(void) | |||
1963 | * table under two names. | 1379 | * table under two names. |
1964 | */ | 1380 | */ |
1965 | static struct tegra_clk_duplicate tegra_clk_duplicates[] = { | 1381 | static struct tegra_clk_duplicate tegra_clk_duplicates[] = { |
1966 | TEGRA_CLK_DUPLICATE(usbd, "utmip-pad", NULL), | 1382 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_USBD, "utmip-pad", NULL), |
1967 | TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), | 1383 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_USBD, "tegra-ehci.0", NULL), |
1968 | TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), | 1384 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_USBD, "tegra-otg", NULL), |
1969 | TEGRA_CLK_DUPLICATE(bsev, "tegra-avp", "bsev"), | 1385 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEV, "tegra-avp", "bsev"), |
1970 | TEGRA_CLK_DUPLICATE(bsev, "nvavp", "bsev"), | 1386 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEV, "nvavp", "bsev"), |
1971 | TEGRA_CLK_DUPLICATE(vde, "tegra-aes", "vde"), | 1387 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VDE, "tegra-aes", "vde"), |
1972 | TEGRA_CLK_DUPLICATE(bsea, "tegra-aes", "bsea"), | 1388 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "tegra-aes", "bsea"), |
1973 | TEGRA_CLK_DUPLICATE(bsea, "nvavp", "bsea"), | 1389 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_BSEA, "nvavp", "bsea"), |
1974 | TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL), | 1390 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML1, "tegra_sata_cml", NULL), |
1975 | TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"), | 1391 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CML0, "tegra_pcie", "cml"), |
1976 | TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"), | 1392 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_VCP, "nvavp", "vcp"), |
1977 | TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"), | 1393 | TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL), /* MUST be the last entry */ |
1978 | TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */ | ||
1979 | }; | 1394 | }; |
1980 | 1395 | ||
1981 | static const struct of_device_id pmc_match[] __initconst = { | 1396 | static const struct of_device_id pmc_match[] __initconst = { |
@@ -1986,7 +1401,6 @@ static const struct of_device_id pmc_match[] __initconst = { | |||
1986 | static void __init tegra30_clock_init(struct device_node *np) | 1401 | static void __init tegra30_clock_init(struct device_node *np) |
1987 | { | 1402 | { |
1988 | struct device_node *node; | 1403 | struct device_node *node; |
1989 | int i; | ||
1990 | 1404 | ||
1991 | clk_base = of_iomap(np, 0); | 1405 | clk_base = of_iomap(np, 0); |
1992 | if (!clk_base) { | 1406 | if (!clk_base) { |
@@ -2006,29 +1420,27 @@ static void __init tegra30_clock_init(struct device_node *np) | |||
2006 | BUG(); | 1420 | BUG(); |
2007 | } | 1421 | } |
2008 | 1422 | ||
2009 | tegra30_osc_clk_init(); | 1423 | clks = tegra_clk_init(clk_base, TEGRA30_CLK_CLK_MAX, |
2010 | tegra30_fixed_clk_init(); | 1424 | TEGRA30_CLK_PERIPH_BANKS); |
1425 | if (!clks) | ||
1426 | return; | ||
1427 | |||
1428 | if (tegra_osc_clk_init(clk_base, tegra30_clks, tegra30_input_freq, | ||
1429 | ARRAY_SIZE(tegra30_input_freq), &input_freq, NULL) < 0) | ||
1430 | return; | ||
1431 | |||
1432 | |||
1433 | tegra_fixed_clk_init(tegra30_clks); | ||
2011 | tegra30_pll_init(); | 1434 | tegra30_pll_init(); |
2012 | tegra30_super_clk_init(); | 1435 | tegra30_super_clk_init(); |
2013 | tegra30_periph_clk_init(); | 1436 | tegra30_periph_clk_init(); |
2014 | tegra30_audio_clk_init(); | 1437 | tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks, &pll_a_params); |
2015 | tegra30_pmc_clk_init(); | 1438 | tegra_pmc_clk_init(pmc_base, tegra30_clks); |
2016 | |||
2017 | for (i = 0; i < ARRAY_SIZE(clks); i++) { | ||
2018 | if (IS_ERR(clks[i])) { | ||
2019 | pr_err("Tegra30 clk %d: register failed with %ld\n", | ||
2020 | i, PTR_ERR(clks[i])); | ||
2021 | BUG(); | ||
2022 | } | ||
2023 | if (!clks[i]) | ||
2024 | clks[i] = ERR_PTR(-EINVAL); | ||
2025 | } | ||
2026 | 1439 | ||
2027 | tegra_init_dup_clks(tegra_clk_duplicates, clks, clk_max); | 1440 | tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); |
2028 | 1441 | ||
2029 | clk_data.clks = clks; | 1442 | tegra_add_of_provider(np); |
2030 | clk_data.clk_num = ARRAY_SIZE(clks); | 1443 | tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); |
2031 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
2032 | 1444 | ||
2033 | tegra_clk_apply_init_table = tegra30_clock_apply_init_table; | 1445 | tegra_clk_apply_init_table = tegra30_clock_apply_init_table; |
2034 | 1446 | ||
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 86581ac1fd69..c0a7d7723510 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c | |||
@@ -18,13 +18,175 @@ | |||
18 | #include <linux/clk-provider.h> | 18 | #include <linux/clk-provider.h> |
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/clk/tegra.h> | 20 | #include <linux/clk/tegra.h> |
21 | #include <linux/reset-controller.h> | ||
22 | #include <linux/tegra-soc.h> | ||
21 | 23 | ||
22 | #include "clk.h" | 24 | #include "clk.h" |
23 | 25 | ||
26 | #define CLK_OUT_ENB_L 0x010 | ||
27 | #define CLK_OUT_ENB_H 0x014 | ||
28 | #define CLK_OUT_ENB_U 0x018 | ||
29 | #define CLK_OUT_ENB_V 0x360 | ||
30 | #define CLK_OUT_ENB_W 0x364 | ||
31 | #define CLK_OUT_ENB_X 0x280 | ||
32 | #define CLK_OUT_ENB_SET_L 0x320 | ||
33 | #define CLK_OUT_ENB_CLR_L 0x324 | ||
34 | #define CLK_OUT_ENB_SET_H 0x328 | ||
35 | #define CLK_OUT_ENB_CLR_H 0x32c | ||
36 | #define CLK_OUT_ENB_SET_U 0x330 | ||
37 | #define CLK_OUT_ENB_CLR_U 0x334 | ||
38 | #define CLK_OUT_ENB_SET_V 0x440 | ||
39 | #define CLK_OUT_ENB_CLR_V 0x444 | ||
40 | #define CLK_OUT_ENB_SET_W 0x448 | ||
41 | #define CLK_OUT_ENB_CLR_W 0x44c | ||
42 | #define CLK_OUT_ENB_SET_X 0x284 | ||
43 | #define CLK_OUT_ENB_CLR_X 0x288 | ||
44 | |||
45 | #define RST_DEVICES_L 0x004 | ||
46 | #define RST_DEVICES_H 0x008 | ||
47 | #define RST_DEVICES_U 0x00C | ||
48 | #define RST_DFLL_DVCO 0x2F4 | ||
49 | #define RST_DEVICES_V 0x358 | ||
50 | #define RST_DEVICES_W 0x35C | ||
51 | #define RST_DEVICES_X 0x28C | ||
52 | #define RST_DEVICES_SET_L 0x300 | ||
53 | #define RST_DEVICES_CLR_L 0x304 | ||
54 | #define RST_DEVICES_SET_H 0x308 | ||
55 | #define RST_DEVICES_CLR_H 0x30c | ||
56 | #define RST_DEVICES_SET_U 0x310 | ||
57 | #define RST_DEVICES_CLR_U 0x314 | ||
58 | #define RST_DEVICES_SET_V 0x430 | ||
59 | #define RST_DEVICES_CLR_V 0x434 | ||
60 | #define RST_DEVICES_SET_W 0x438 | ||
61 | #define RST_DEVICES_CLR_W 0x43c | ||
62 | #define RST_DEVICES_SET_X 0x290 | ||
63 | #define RST_DEVICES_CLR_X 0x294 | ||
64 | |||
24 | /* Global data of Tegra CPU CAR ops */ | 65 | /* Global data of Tegra CPU CAR ops */ |
25 | static struct tegra_cpu_car_ops dummy_car_ops; | 66 | static struct tegra_cpu_car_ops dummy_car_ops; |
26 | struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; | 67 | struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; |
27 | 68 | ||
69 | int *periph_clk_enb_refcnt; | ||
70 | static int periph_banks; | ||
71 | static struct clk **clks; | ||
72 | static int clk_num; | ||
73 | static struct clk_onecell_data clk_data; | ||
74 | |||
75 | static struct tegra_clk_periph_regs periph_regs[] = { | ||
76 | [0] = { | ||
77 | .enb_reg = CLK_OUT_ENB_L, | ||
78 | .enb_set_reg = CLK_OUT_ENB_SET_L, | ||
79 | .enb_clr_reg = CLK_OUT_ENB_CLR_L, | ||
80 | .rst_reg = RST_DEVICES_L, | ||
81 | .rst_set_reg = RST_DEVICES_SET_L, | ||
82 | .rst_clr_reg = RST_DEVICES_CLR_L, | ||
83 | }, | ||
84 | [1] = { | ||
85 | .enb_reg = CLK_OUT_ENB_H, | ||
86 | .enb_set_reg = CLK_OUT_ENB_SET_H, | ||
87 | .enb_clr_reg = CLK_OUT_ENB_CLR_H, | ||
88 | .rst_reg = RST_DEVICES_H, | ||
89 | .rst_set_reg = RST_DEVICES_SET_H, | ||
90 | .rst_clr_reg = RST_DEVICES_CLR_H, | ||
91 | }, | ||
92 | [2] = { | ||
93 | .enb_reg = CLK_OUT_ENB_U, | ||
94 | .enb_set_reg = CLK_OUT_ENB_SET_U, | ||
95 | .enb_clr_reg = CLK_OUT_ENB_CLR_U, | ||
96 | .rst_reg = RST_DEVICES_U, | ||
97 | .rst_set_reg = RST_DEVICES_SET_U, | ||
98 | .rst_clr_reg = RST_DEVICES_CLR_U, | ||
99 | }, | ||
100 | [3] = { | ||
101 | .enb_reg = CLK_OUT_ENB_V, | ||
102 | .enb_set_reg = CLK_OUT_ENB_SET_V, | ||
103 | .enb_clr_reg = CLK_OUT_ENB_CLR_V, | ||
104 | .rst_reg = RST_DEVICES_V, | ||
105 | .rst_set_reg = RST_DEVICES_SET_V, | ||
106 | .rst_clr_reg = RST_DEVICES_CLR_V, | ||
107 | }, | ||
108 | [4] = { | ||
109 | .enb_reg = CLK_OUT_ENB_W, | ||
110 | .enb_set_reg = CLK_OUT_ENB_SET_W, | ||
111 | .enb_clr_reg = CLK_OUT_ENB_CLR_W, | ||
112 | .rst_reg = RST_DEVICES_W, | ||
113 | .rst_set_reg = RST_DEVICES_SET_W, | ||
114 | .rst_clr_reg = RST_DEVICES_CLR_W, | ||
115 | }, | ||
116 | [5] = { | ||
117 | .enb_reg = CLK_OUT_ENB_X, | ||
118 | .enb_set_reg = CLK_OUT_ENB_SET_X, | ||
119 | .enb_clr_reg = CLK_OUT_ENB_CLR_X, | ||
120 | .rst_reg = RST_DEVICES_X, | ||
121 | .rst_set_reg = RST_DEVICES_SET_X, | ||
122 | .rst_clr_reg = RST_DEVICES_CLR_X, | ||
123 | }, | ||
124 | }; | ||
125 | |||
126 | static void __iomem *clk_base; | ||
127 | |||
128 | static int tegra_clk_rst_assert(struct reset_controller_dev *rcdev, | ||
129 | unsigned long id) | ||
130 | { | ||
131 | /* | ||
132 | * If peripheral is on the APB bus then we must read the APB bus to | ||
133 | * flush the write operation in apb bus. This will avoid peripheral | ||
134 | * access after disabling clock. Since the reset driver has no | ||
135 | * knowledge of which reset IDs represent which devices, simply do | ||
136 | * this all the time. | ||
137 | */ | ||
138 | tegra_read_chipid(); | ||
139 | |||
140 | writel_relaxed(BIT(id % 32), | ||
141 | clk_base + periph_regs[id / 32].rst_set_reg); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev, | ||
147 | unsigned long id) | ||
148 | { | ||
149 | writel_relaxed(BIT(id % 32), | ||
150 | clk_base + periph_regs[id / 32].rst_clr_reg); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | struct tegra_clk_periph_regs *get_reg_bank(int clkid) | ||
156 | { | ||
157 | int reg_bank = clkid / 32; | ||
158 | |||
159 | if (reg_bank < periph_banks) | ||
160 | return &periph_regs[reg_bank]; | ||
161 | else { | ||
162 | WARN_ON(1); | ||
163 | return NULL; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) | ||
168 | { | ||
169 | clk_base = regs; | ||
170 | |||
171 | if (WARN_ON(banks > ARRAY_SIZE(periph_regs))) | ||
172 | return NULL; | ||
173 | |||
174 | periph_clk_enb_refcnt = kzalloc(32 * banks * | ||
175 | sizeof(*periph_clk_enb_refcnt), GFP_KERNEL); | ||
176 | if (!periph_clk_enb_refcnt) | ||
177 | return NULL; | ||
178 | |||
179 | periph_banks = banks; | ||
180 | |||
181 | clks = kzalloc(num * sizeof(struct clk *), GFP_KERNEL); | ||
182 | if (!clks) | ||
183 | kfree(periph_clk_enb_refcnt); | ||
184 | |||
185 | clk_num = num; | ||
186 | |||
187 | return clks; | ||
188 | } | ||
189 | |||
28 | void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, | 190 | void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, |
29 | struct clk *clks[], int clk_max) | 191 | struct clk *clks[], int clk_max) |
30 | { | 192 | { |
@@ -74,6 +236,58 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, | |||
74 | } | 236 | } |
75 | } | 237 | } |
76 | 238 | ||
239 | static struct reset_control_ops rst_ops = { | ||
240 | .assert = tegra_clk_rst_assert, | ||
241 | .deassert = tegra_clk_rst_deassert, | ||
242 | }; | ||
243 | |||
244 | static struct reset_controller_dev rst_ctlr = { | ||
245 | .ops = &rst_ops, | ||
246 | .owner = THIS_MODULE, | ||
247 | .of_reset_n_cells = 1, | ||
248 | }; | ||
249 | |||
250 | void __init tegra_add_of_provider(struct device_node *np) | ||
251 | { | ||
252 | int i; | ||
253 | |||
254 | for (i = 0; i < clk_num; i++) { | ||
255 | if (IS_ERR(clks[i])) { | ||
256 | pr_err | ||
257 | ("Tegra clk %d: register failed with %ld\n", | ||
258 | i, PTR_ERR(clks[i])); | ||
259 | } | ||
260 | if (!clks[i]) | ||
261 | clks[i] = ERR_PTR(-EINVAL); | ||
262 | } | ||
263 | |||
264 | clk_data.clks = clks; | ||
265 | clk_data.clk_num = clk_num; | ||
266 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
267 | |||
268 | rst_ctlr.of_node = np; | ||
269 | rst_ctlr.nr_resets = clk_num * 32; | ||
270 | reset_controller_register(&rst_ctlr); | ||
271 | } | ||
272 | |||
273 | void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num) | ||
274 | { | ||
275 | int i; | ||
276 | |||
277 | for (i = 0; i < num; i++, dev_clks++) | ||
278 | clk_register_clkdev(clks[dev_clks->dt_id], dev_clks->con_id, | ||
279 | dev_clks->dev_id); | ||
280 | } | ||
281 | |||
282 | struct clk ** __init tegra_lookup_dt_id(int clk_id, | ||
283 | struct tegra_clk *tegra_clk) | ||
284 | { | ||
285 | if (tegra_clk[clk_id].present) | ||
286 | return &clks[tegra_clk[clk_id].dt_id]; | ||
287 | else | ||
288 | return NULL; | ||
289 | } | ||
290 | |||
77 | tegra_clk_apply_init_table_func tegra_clk_apply_init_table; | 291 | tegra_clk_apply_init_table_func tegra_clk_apply_init_table; |
78 | 292 | ||
79 | void __init tegra_clocks_apply_init_table(void) | 293 | void __init tegra_clocks_apply_init_table(void) |
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 07cfacd91686..16ec8d6bb87f 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h | |||
@@ -37,6 +37,8 @@ struct tegra_clk_sync_source { | |||
37 | container_of(_hw, struct tegra_clk_sync_source, hw) | 37 | container_of(_hw, struct tegra_clk_sync_source, hw) |
38 | 38 | ||
39 | extern const struct clk_ops tegra_clk_sync_source_ops; | 39 | extern const struct clk_ops tegra_clk_sync_source_ops; |
40 | extern int *periph_clk_enb_refcnt; | ||
41 | |||
40 | struct clk *tegra_clk_register_sync_source(const char *name, | 42 | struct clk *tegra_clk_register_sync_source(const char *name, |
41 | unsigned long fixed_rate, unsigned long max_rate); | 43 | unsigned long fixed_rate, unsigned long max_rate); |
42 | 44 | ||
@@ -188,12 +190,15 @@ struct tegra_clk_pll_params { | |||
188 | u32 ext_misc_reg[3]; | 190 | u32 ext_misc_reg[3]; |
189 | u32 pmc_divnm_reg; | 191 | u32 pmc_divnm_reg; |
190 | u32 pmc_divp_reg; | 192 | u32 pmc_divp_reg; |
193 | u32 flags; | ||
191 | int stepa_shift; | 194 | int stepa_shift; |
192 | int stepb_shift; | 195 | int stepb_shift; |
193 | int lock_delay; | 196 | int lock_delay; |
194 | int max_p; | 197 | int max_p; |
195 | struct pdiv_map *pdiv_tohw; | 198 | struct pdiv_map *pdiv_tohw; |
196 | struct div_nmp *div_nmp; | 199 | struct div_nmp *div_nmp; |
200 | struct tegra_clk_pll_freq_table *freq_table; | ||
201 | unsigned long fixed_rate; | ||
197 | }; | 202 | }; |
198 | 203 | ||
199 | /** | 204 | /** |
@@ -233,10 +238,7 @@ struct tegra_clk_pll { | |||
233 | struct clk_hw hw; | 238 | struct clk_hw hw; |
234 | void __iomem *clk_base; | 239 | void __iomem *clk_base; |
235 | void __iomem *pmc; | 240 | void __iomem *pmc; |
236 | u32 flags; | ||
237 | unsigned long fixed_rate; | ||
238 | spinlock_t *lock; | 241 | spinlock_t *lock; |
239 | struct tegra_clk_pll_freq_table *freq_table; | ||
240 | struct tegra_clk_pll_params *params; | 242 | struct tegra_clk_pll_params *params; |
241 | }; | 243 | }; |
242 | 244 | ||
@@ -258,56 +260,49 @@ extern const struct clk_ops tegra_clk_pll_ops; | |||
258 | extern const struct clk_ops tegra_clk_plle_ops; | 260 | extern const struct clk_ops tegra_clk_plle_ops; |
259 | struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, | 261 | struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, |
260 | void __iomem *clk_base, void __iomem *pmc, | 262 | void __iomem *clk_base, void __iomem *pmc, |
261 | unsigned long flags, unsigned long fixed_rate, | 263 | unsigned long flags, struct tegra_clk_pll_params *pll_params, |
262 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, | 264 | spinlock_t *lock); |
263 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); | ||
264 | 265 | ||
265 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, | 266 | struct clk *tegra_clk_register_plle(const char *name, const char *parent_name, |
266 | void __iomem *clk_base, void __iomem *pmc, | 267 | void __iomem *clk_base, void __iomem *pmc, |
267 | unsigned long flags, unsigned long fixed_rate, | 268 | unsigned long flags, struct tegra_clk_pll_params *pll_params, |
268 | struct tegra_clk_pll_params *pll_params, u32 pll_flags, | 269 | spinlock_t *lock); |
269 | struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock); | ||
270 | 270 | ||
271 | struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, | 271 | struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, |
272 | void __iomem *clk_base, void __iomem *pmc, | 272 | void __iomem *clk_base, void __iomem *pmc, |
273 | unsigned long flags, unsigned long fixed_rate, | 273 | unsigned long flags, |
274 | struct tegra_clk_pll_params *pll_params, | 274 | struct tegra_clk_pll_params *pll_params, |
275 | u32 pll_flags, | ||
276 | struct tegra_clk_pll_freq_table *freq_table, | ||
277 | spinlock_t *lock); | 275 | spinlock_t *lock); |
278 | 276 | ||
279 | struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, | 277 | struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, |
280 | void __iomem *clk_base, void __iomem *pmc, | 278 | void __iomem *clk_base, void __iomem *pmc, |
281 | unsigned long flags, unsigned long fixed_rate, | 279 | unsigned long flags, |
282 | struct tegra_clk_pll_params *pll_params, | 280 | struct tegra_clk_pll_params *pll_params, |
283 | u32 pll_flags, | ||
284 | struct tegra_clk_pll_freq_table *freq_table, | ||
285 | spinlock_t *lock); | 281 | spinlock_t *lock); |
286 | 282 | ||
287 | struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, | 283 | struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name, |
288 | void __iomem *clk_base, void __iomem *pmc, | 284 | void __iomem *clk_base, void __iomem *pmc, |
289 | unsigned long flags, unsigned long fixed_rate, | 285 | unsigned long flags, |
290 | struct tegra_clk_pll_params *pll_params, | 286 | struct tegra_clk_pll_params *pll_params, |
291 | u32 pll_flags, | ||
292 | struct tegra_clk_pll_freq_table *freq_table, | ||
293 | spinlock_t *lock); | 287 | spinlock_t *lock); |
294 | 288 | ||
295 | struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, | 289 | struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name, |
296 | void __iomem *clk_base, void __iomem *pmc, | 290 | void __iomem *clk_base, void __iomem *pmc, |
297 | unsigned long flags, unsigned long fixed_rate, | 291 | unsigned long flags, |
298 | struct tegra_clk_pll_params *pll_params, | 292 | struct tegra_clk_pll_params *pll_params, |
299 | u32 pll_flags, | ||
300 | struct tegra_clk_pll_freq_table *freq_table, | ||
301 | spinlock_t *lock, unsigned long parent_rate); | 293 | spinlock_t *lock, unsigned long parent_rate); |
302 | 294 | ||
303 | struct clk *tegra_clk_register_plle_tegra114(const char *name, | 295 | struct clk *tegra_clk_register_plle_tegra114(const char *name, |
304 | const char *parent_name, | 296 | const char *parent_name, |
305 | void __iomem *clk_base, unsigned long flags, | 297 | void __iomem *clk_base, unsigned long flags, |
306 | unsigned long fixed_rate, | ||
307 | struct tegra_clk_pll_params *pll_params, | 298 | struct tegra_clk_pll_params *pll_params, |
308 | struct tegra_clk_pll_freq_table *freq_table, | ||
309 | spinlock_t *lock); | 299 | spinlock_t *lock); |
310 | 300 | ||
301 | struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, | ||
302 | void __iomem *clk_base, unsigned long flags, | ||
303 | struct tegra_clk_pll_params *pll_params, | ||
304 | spinlock_t *lock); | ||
305 | |||
311 | /** | 306 | /** |
312 | * struct tegra_clk_pll_out - PLL divider down clock | 307 | * struct tegra_clk_pll_out - PLL divider down clock |
313 | * | 308 | * |
@@ -395,13 +390,13 @@ struct tegra_clk_periph_gate { | |||
395 | #define TEGRA_PERIPH_MANUAL_RESET BIT(1) | 390 | #define TEGRA_PERIPH_MANUAL_RESET BIT(1) |
396 | #define TEGRA_PERIPH_ON_APB BIT(2) | 391 | #define TEGRA_PERIPH_ON_APB BIT(2) |
397 | #define TEGRA_PERIPH_WAR_1005168 BIT(3) | 392 | #define TEGRA_PERIPH_WAR_1005168 BIT(3) |
393 | #define TEGRA_PERIPH_NO_DIV BIT(4) | ||
394 | #define TEGRA_PERIPH_NO_GATE BIT(5) | ||
398 | 395 | ||
399 | void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert); | ||
400 | extern const struct clk_ops tegra_clk_periph_gate_ops; | 396 | extern const struct clk_ops tegra_clk_periph_gate_ops; |
401 | struct clk *tegra_clk_register_periph_gate(const char *name, | 397 | struct clk *tegra_clk_register_periph_gate(const char *name, |
402 | const char *parent_name, u8 gate_flags, void __iomem *clk_base, | 398 | const char *parent_name, u8 gate_flags, void __iomem *clk_base, |
403 | unsigned long flags, int clk_num, | 399 | unsigned long flags, int clk_num, int *enable_refcnt); |
404 | struct tegra_clk_periph_regs *pregs, int *enable_refcnt); | ||
405 | 400 | ||
406 | /** | 401 | /** |
407 | * struct clk-periph - peripheral clock | 402 | * struct clk-periph - peripheral clock |
@@ -443,26 +438,26 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, | |||
443 | 438 | ||
444 | #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \ | 439 | #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \ |
445 | _div_shift, _div_width, _div_frac_width, \ | 440 | _div_shift, _div_width, _div_frac_width, \ |
446 | _div_flags, _clk_num, _enb_refcnt, _regs, \ | 441 | _div_flags, _clk_num,\ |
447 | _gate_flags, _table) \ | 442 | _gate_flags, _table, _lock) \ |
448 | { \ | 443 | { \ |
449 | .mux = { \ | 444 | .mux = { \ |
450 | .flags = _mux_flags, \ | 445 | .flags = _mux_flags, \ |
451 | .shift = _mux_shift, \ | 446 | .shift = _mux_shift, \ |
452 | .mask = _mux_mask, \ | 447 | .mask = _mux_mask, \ |
453 | .table = _table, \ | 448 | .table = _table, \ |
449 | .lock = _lock, \ | ||
454 | }, \ | 450 | }, \ |
455 | .divider = { \ | 451 | .divider = { \ |
456 | .flags = _div_flags, \ | 452 | .flags = _div_flags, \ |
457 | .shift = _div_shift, \ | 453 | .shift = _div_shift, \ |
458 | .width = _div_width, \ | 454 | .width = _div_width, \ |
459 | .frac_width = _div_frac_width, \ | 455 | .frac_width = _div_frac_width, \ |
456 | .lock = _lock, \ | ||
460 | }, \ | 457 | }, \ |
461 | .gate = { \ | 458 | .gate = { \ |
462 | .flags = _gate_flags, \ | 459 | .flags = _gate_flags, \ |
463 | .clk_num = _clk_num, \ | 460 | .clk_num = _clk_num, \ |
464 | .enable_refcnt = _enb_refcnt, \ | ||
465 | .regs = _regs, \ | ||
466 | }, \ | 461 | }, \ |
467 | .mux_ops = &clk_mux_ops, \ | 462 | .mux_ops = &clk_mux_ops, \ |
468 | .div_ops = &tegra_clk_frac_div_ops, \ | 463 | .div_ops = &tegra_clk_frac_div_ops, \ |
@@ -472,7 +467,10 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, | |||
472 | struct tegra_periph_init_data { | 467 | struct tegra_periph_init_data { |
473 | const char *name; | 468 | const char *name; |
474 | int clk_id; | 469 | int clk_id; |
475 | const char **parent_names; | 470 | union { |
471 | const char **parent_names; | ||
472 | const char *parent_name; | ||
473 | } p; | ||
476 | int num_parents; | 474 | int num_parents; |
477 | struct tegra_clk_periph periph; | 475 | struct tegra_clk_periph periph; |
478 | u32 offset; | 476 | u32 offset; |
@@ -483,20 +481,19 @@ struct tegra_periph_init_data { | |||
483 | 481 | ||
484 | #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ | 482 | #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ |
485 | _mux_shift, _mux_mask, _mux_flags, _div_shift, \ | 483 | _mux_shift, _mux_mask, _mux_flags, _div_shift, \ |
486 | _div_width, _div_frac_width, _div_flags, _regs, \ | 484 | _div_width, _div_frac_width, _div_flags, \ |
487 | _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\ | 485 | _clk_num, _gate_flags, _clk_id, _table, \ |
488 | _flags) \ | 486 | _flags, _lock) \ |
489 | { \ | 487 | { \ |
490 | .name = _name, \ | 488 | .name = _name, \ |
491 | .clk_id = _clk_id, \ | 489 | .clk_id = _clk_id, \ |
492 | .parent_names = _parent_names, \ | 490 | .p.parent_names = _parent_names, \ |
493 | .num_parents = ARRAY_SIZE(_parent_names), \ | 491 | .num_parents = ARRAY_SIZE(_parent_names), \ |
494 | .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, \ | 492 | .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, \ |
495 | _mux_flags, _div_shift, \ | 493 | _mux_flags, _div_shift, \ |
496 | _div_width, _div_frac_width, \ | 494 | _div_width, _div_frac_width, \ |
497 | _div_flags, _clk_num, \ | 495 | _div_flags, _clk_num, \ |
498 | _enb_refcnt, _regs, \ | 496 | _gate_flags, _table, _lock), \ |
499 | _gate_flags, _table), \ | ||
500 | .offset = _offset, \ | 497 | .offset = _offset, \ |
501 | .con_id = _con_id, \ | 498 | .con_id = _con_id, \ |
502 | .dev_id = _dev_id, \ | 499 | .dev_id = _dev_id, \ |
@@ -505,13 +502,13 @@ struct tegra_periph_init_data { | |||
505 | 502 | ||
506 | #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ | 503 | #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ |
507 | _mux_shift, _mux_width, _mux_flags, _div_shift, \ | 504 | _mux_shift, _mux_width, _mux_flags, _div_shift, \ |
508 | _div_width, _div_frac_width, _div_flags, _regs, \ | 505 | _div_width, _div_frac_width, _div_flags, \ |
509 | _clk_num, _enb_refcnt, _gate_flags, _clk_id) \ | 506 | _clk_num, _gate_flags, _clk_id) \ |
510 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ | 507 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ |
511 | _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ | 508 | _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ |
512 | _div_shift, _div_width, _div_frac_width, _div_flags, \ | 509 | _div_shift, _div_width, _div_frac_width, _div_flags, \ |
513 | _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ | 510 | _clk_num, _gate_flags, _clk_id,\ |
514 | NULL, 0) | 511 | NULL, 0, NULL) |
515 | 512 | ||
516 | /** | 513 | /** |
517 | * struct clk_super_mux - super clock | 514 | * struct clk_super_mux - super clock |
@@ -581,12 +578,49 @@ struct tegra_clk_duplicate { | |||
581 | }, \ | 578 | }, \ |
582 | } | 579 | } |
583 | 580 | ||
581 | struct tegra_clk { | ||
582 | int dt_id; | ||
583 | bool present; | ||
584 | }; | ||
585 | |||
586 | struct tegra_devclk { | ||
587 | int dt_id; | ||
588 | char *dev_id; | ||
589 | char *con_id; | ||
590 | }; | ||
591 | |||
584 | void tegra_init_from_table(struct tegra_clk_init_table *tbl, | 592 | void tegra_init_from_table(struct tegra_clk_init_table *tbl, |
585 | struct clk *clks[], int clk_max); | 593 | struct clk *clks[], int clk_max); |
586 | 594 | ||
587 | void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, | 595 | void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, |
588 | struct clk *clks[], int clk_max); | 596 | struct clk *clks[], int clk_max); |
589 | 597 | ||
598 | struct tegra_clk_periph_regs *get_reg_bank(int clkid); | ||
599 | struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks); | ||
600 | |||
601 | struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk); | ||
602 | |||
603 | void tegra_add_of_provider(struct device_node *np); | ||
604 | void tegra_register_devclks(struct tegra_devclk *dev_clks, int num); | ||
605 | |||
606 | void tegra_audio_clk_init(void __iomem *clk_base, | ||
607 | void __iomem *pmc_base, struct tegra_clk *tegra_clks, | ||
608 | struct tegra_clk_pll_params *pll_params); | ||
609 | |||
610 | void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base, | ||
611 | struct tegra_clk *tegra_clks, | ||
612 | struct tegra_clk_pll_params *pll_params); | ||
613 | |||
614 | void tegra_pmc_clk_init(void __iomem *pmc_base, struct tegra_clk *tegra_clks); | ||
615 | void tegra_fixed_clk_init(struct tegra_clk *tegra_clks); | ||
616 | int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *tegra_clks, | ||
617 | unsigned long *input_freqs, int num, | ||
618 | unsigned long *osc_freq, | ||
619 | unsigned long *pll_ref_freq); | ||
620 | void tegra_super_clk_gen4_init(void __iomem *clk_base, | ||
621 | void __iomem *pmc_base, struct tegra_clk *tegra_clks, | ||
622 | struct tegra_clk_pll_params *pll_params); | ||
623 | |||
590 | void tegra114_clock_tune_cpu_trimmers_high(void); | 624 | void tegra114_clock_tune_cpu_trimmers_high(void); |
591 | void tegra114_clock_tune_cpu_trimmers_low(void); | 625 | void tegra114_clock_tune_cpu_trimmers_low(void); |
592 | void tegra114_clock_tune_cpu_trimmers_init(void); | 626 | void tegra114_clock_tune_cpu_trimmers_init(void); |
diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h index 7f25cee8cec2..3ddade8a5125 100644 --- a/drivers/cpufreq/exynos-cpufreq.h +++ b/drivers/cpufreq/exynos-cpufreq.h | |||
@@ -67,3 +67,25 @@ static inline int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) | |||
67 | return -EOPNOTSUPP; | 67 | return -EOPNOTSUPP; |
68 | } | 68 | } |
69 | #endif | 69 | #endif |
70 | |||
71 | #include <plat/cpu.h> | ||
72 | #include <mach/map.h> | ||
73 | |||
74 | #define EXYNOS4_CLKSRC_CPU (S5P_VA_CMU + 0x14200) | ||
75 | #define EXYNOS4_CLKMUX_STATCPU (S5P_VA_CMU + 0x14400) | ||
76 | |||
77 | #define EXYNOS4_CLKDIV_CPU (S5P_VA_CMU + 0x14500) | ||
78 | #define EXYNOS4_CLKDIV_CPU1 (S5P_VA_CMU + 0x14504) | ||
79 | #define EXYNOS4_CLKDIV_STATCPU (S5P_VA_CMU + 0x14600) | ||
80 | #define EXYNOS4_CLKDIV_STATCPU1 (S5P_VA_CMU + 0x14604) | ||
81 | |||
82 | #define EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT (16) | ||
83 | #define EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT) | ||
84 | |||
85 | #define EXYNOS5_APLL_LOCK (S5P_VA_CMU + 0x00000) | ||
86 | #define EXYNOS5_APLL_CON0 (S5P_VA_CMU + 0x00100) | ||
87 | #define EXYNOS5_CLKMUX_STATCPU (S5P_VA_CMU + 0x00400) | ||
88 | #define EXYNOS5_CLKDIV_CPU0 (S5P_VA_CMU + 0x00500) | ||
89 | #define EXYNOS5_CLKDIV_CPU1 (S5P_VA_CMU + 0x00504) | ||
90 | #define EXYNOS5_CLKDIV_STATCPU0 (S5P_VA_CMU + 0x00600) | ||
91 | #define EXYNOS5_CLKDIV_STATCPU1 (S5P_VA_CMU + 0x00604) | ||
diff --git a/drivers/cpufreq/exynos4210-cpufreq.c b/drivers/cpufreq/exynos4210-cpufreq.c index dfd1643b0b2f..40d84c43d8f4 100644 --- a/drivers/cpufreq/exynos4210-cpufreq.c +++ b/drivers/cpufreq/exynos4210-cpufreq.c | |||
@@ -17,8 +17,6 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/cpufreq.h> | 18 | #include <linux/cpufreq.h> |
19 | 19 | ||
20 | #include <mach/regs-clock.h> | ||
21 | |||
22 | #include "exynos-cpufreq.h" | 20 | #include "exynos-cpufreq.h" |
23 | 21 | ||
24 | static struct clk *cpu_clk; | 22 | static struct clk *cpu_clk; |
diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c index efad5e657f6f..869e48297e28 100644 --- a/drivers/cpufreq/exynos4x12-cpufreq.c +++ b/drivers/cpufreq/exynos4x12-cpufreq.c | |||
@@ -17,8 +17,6 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/cpufreq.h> | 18 | #include <linux/cpufreq.h> |
19 | 19 | ||
20 | #include <mach/regs-clock.h> | ||
21 | |||
22 | #include "exynos-cpufreq.h" | 20 | #include "exynos-cpufreq.h" |
23 | 21 | ||
24 | static struct clk *cpu_clk; | 22 | static struct clk *cpu_clk; |
diff --git a/drivers/cpufreq/exynos5250-cpufreq.c b/drivers/cpufreq/exynos5250-cpufreq.c index 8feda86fe42c..5ee2ce1ad424 100644 --- a/drivers/cpufreq/exynos5250-cpufreq.c +++ b/drivers/cpufreq/exynos5250-cpufreq.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/cpufreq.h> | 18 | #include <linux/cpufreq.h> |
19 | 19 | ||
20 | #include <mach/map.h> | 20 | #include <mach/map.h> |
21 | #include <mach/regs-clock.h> | ||
22 | 21 | ||
23 | #include "exynos-cpufreq.h" | 22 | #include "exynos-cpufreq.h" |
24 | 23 | ||
diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c index bbbfe6853b18..e07b0c68c715 100644 --- a/drivers/devfreq/exynos/exynos4_bus.c +++ b/drivers/devfreq/exynos/exynos4_bus.c | |||
@@ -30,9 +30,9 @@ | |||
30 | extern unsigned int exynos_result_of_asv; | 30 | extern unsigned int exynos_result_of_asv; |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | #include <mach/regs-clock.h> | 33 | #include <mach/map.h> |
34 | 34 | ||
35 | #include <plat/map-s5p.h> | 35 | #include "exynos4_bus.h" |
36 | 36 | ||
37 | #define MAX_SAFEVOLT 1200000 /* 1.2V */ | 37 | #define MAX_SAFEVOLT 1200000 /* 1.2V */ |
38 | 38 | ||
diff --git a/drivers/devfreq/exynos/exynos4_bus.h b/drivers/devfreq/exynos/exynos4_bus.h new file mode 100644 index 000000000000..94c73c18d28c --- /dev/null +++ b/drivers/devfreq/exynos/exynos4_bus.h | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com/ | ||
4 | * | ||
5 | * EXYNOS4 BUS header | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __DEVFREQ_EXYNOS4_BUS_H | ||
13 | #define __DEVFREQ_EXYNOS4_BUS_H __FILE__ | ||
14 | |||
15 | #include <mach/map.h> | ||
16 | |||
17 | #define EXYNOS4_CLKDIV_LEFTBUS (S5P_VA_CMU + 0x04500) | ||
18 | #define EXYNOS4_CLKDIV_STAT_LEFTBUS (S5P_VA_CMU + 0x04600) | ||
19 | |||
20 | #define EXYNOS4_CLKDIV_RIGHTBUS (S5P_VA_CMU + 0x08500) | ||
21 | #define EXYNOS4_CLKDIV_STAT_RIGHTBUS (S5P_VA_CMU + 0x08600) | ||
22 | |||
23 | #define EXYNOS4_CLKDIV_TOP (S5P_VA_CMU + 0x0C510) | ||
24 | #define EXYNOS4_CLKDIV_CAM (S5P_VA_CMU + 0x0C520) | ||
25 | #define EXYNOS4_CLKDIV_MFC (S5P_VA_CMU + 0x0C528) | ||
26 | |||
27 | #define EXYNOS4_CLKDIV_STAT_TOP (S5P_VA_CMU + 0x0C610) | ||
28 | #define EXYNOS4_CLKDIV_STAT_MFC (S5P_VA_CMU + 0x0C628) | ||
29 | |||
30 | #define EXYNOS4210_CLKGATE_IP_IMAGE (S5P_VA_CMU + 0x0C930) | ||
31 | #define EXYNOS4212_CLKGATE_IP_IMAGE (S5P_VA_CMU + 0x04930) | ||
32 | |||
33 | #define EXYNOS4_CLKDIV_DMC0 (S5P_VA_CMU + 0x10500) | ||
34 | #define EXYNOS4_CLKDIV_DMC1 (S5P_VA_CMU + 0x10504) | ||
35 | #define EXYNOS4_CLKDIV_STAT_DMC0 (S5P_VA_CMU + 0x10600) | ||
36 | #define EXYNOS4_CLKDIV_STAT_DMC1 (S5P_VA_CMU + 0x10604) | ||
37 | |||
38 | #define EXYNOS4_DMC_PAUSE_CTRL (S5P_VA_CMU + 0x11094) | ||
39 | #define EXYNOS4_DMC_PAUSE_ENABLE (1 << 0) | ||
40 | |||
41 | #define EXYNOS4_CLKDIV_DMC0_ACP_SHIFT (0) | ||
42 | #define EXYNOS4_CLKDIV_DMC0_ACP_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) | ||
43 | #define EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT (4) | ||
44 | #define EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) | ||
45 | #define EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT (8) | ||
46 | #define EXYNOS4_CLKDIV_DMC0_DPHY_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) | ||
47 | #define EXYNOS4_CLKDIV_DMC0_DMC_SHIFT (12) | ||
48 | #define EXYNOS4_CLKDIV_DMC0_DMC_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) | ||
49 | #define EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT (16) | ||
50 | #define EXYNOS4_CLKDIV_DMC0_DMCD_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) | ||
51 | #define EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT (20) | ||
52 | #define EXYNOS4_CLKDIV_DMC0_DMCP_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) | ||
53 | #define EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT (24) | ||
54 | #define EXYNOS4_CLKDIV_DMC0_COPY2_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) | ||
55 | #define EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT (28) | ||
56 | #define EXYNOS4_CLKDIV_DMC0_CORETI_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT) | ||
57 | |||
58 | #define EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT (0) | ||
59 | #define EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK (0xf << EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT) | ||
60 | #define EXYNOS4_CLKDIV_DMC1_C2C_SHIFT (4) | ||
61 | #define EXYNOS4_CLKDIV_DMC1_C2C_MASK (0x7 << EXYNOS4_CLKDIV_DMC1_C2C_SHIFT) | ||
62 | #define EXYNOS4_CLKDIV_DMC1_PWI_SHIFT (8) | ||
63 | #define EXYNOS4_CLKDIV_DMC1_PWI_MASK (0xf << EXYNOS4_CLKDIV_DMC1_PWI_SHIFT) | ||
64 | #define EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT (12) | ||
65 | #define EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK (0x7 << EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT) | ||
66 | #define EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT (16) | ||
67 | #define EXYNOS4_CLKDIV_DMC1_DVSEM_MASK (0x7f << EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT) | ||
68 | #define EXYNOS4_CLKDIV_DMC1_DPM_SHIFT (24) | ||
69 | #define EXYNOS4_CLKDIV_DMC1_DPM_MASK (0x7f << EXYNOS4_CLKDIV_DMC1_DPM_SHIFT) | ||
70 | |||
71 | #define EXYNOS4_CLKDIV_MFC_SHIFT (0) | ||
72 | #define EXYNOS4_CLKDIV_MFC_MASK (0x7 << EXYNOS4_CLKDIV_MFC_SHIFT) | ||
73 | |||
74 | #define EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT (0) | ||
75 | #define EXYNOS4_CLKDIV_TOP_ACLK200_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) | ||
76 | #define EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT (4) | ||
77 | #define EXYNOS4_CLKDIV_TOP_ACLK100_MASK (0xF << EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) | ||
78 | #define EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT (8) | ||
79 | #define EXYNOS4_CLKDIV_TOP_ACLK160_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) | ||
80 | #define EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT (12) | ||
81 | #define EXYNOS4_CLKDIV_TOP_ACLK133_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) | ||
82 | #define EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT (16) | ||
83 | #define EXYNOS4_CLKDIV_TOP_ONENAND_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT) | ||
84 | #define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT (20) | ||
85 | #define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT) | ||
86 | #define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT (24) | ||
87 | #define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT) | ||
88 | |||
89 | #define EXYNOS4_CLKDIV_BUS_GDLR_SHIFT (0) | ||
90 | #define EXYNOS4_CLKDIV_BUS_GDLR_MASK (0x7 << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) | ||
91 | #define EXYNOS4_CLKDIV_BUS_GPLR_SHIFT (4) | ||
92 | #define EXYNOS4_CLKDIV_BUS_GPLR_MASK (0x7 << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT) | ||
93 | |||
94 | #define EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT (0) | ||
95 | #define EXYNOS4_CLKDIV_CAM_FIMC0_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT) | ||
96 | #define EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT (4) | ||
97 | #define EXYNOS4_CLKDIV_CAM_FIMC1_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT) | ||
98 | #define EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT (8) | ||
99 | #define EXYNOS4_CLKDIV_CAM_FIMC2_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT) | ||
100 | #define EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT (12) | ||
101 | #define EXYNOS4_CLKDIV_CAM_FIMC3_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT) | ||
102 | |||
103 | #define EXYNOS4_CLKDIV_CAM1 (S5P_VA_CMU + 0x0C568) | ||
104 | |||
105 | #define EXYNOS4_CLKDIV_STAT_CAM1 (S5P_VA_CMU + 0x0C668) | ||
106 | |||
107 | #define EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT (0) | ||
108 | #define EXYNOS4_CLKDIV_CAM1_JPEG_MASK (0xf << EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT) | ||
109 | |||
110 | #endif /* __DEVFREQ_EXYNOS4_BUS_H */ | ||
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index c823daaf9043..c10eb89a3c1b 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -292,9 +292,11 @@ config MMP_TDMA | |||
292 | bool "MMP Two-Channel DMA support" | 292 | bool "MMP Two-Channel DMA support" |
293 | depends on ARCH_MMP | 293 | depends on ARCH_MMP |
294 | select DMA_ENGINE | 294 | select DMA_ENGINE |
295 | select MMP_SRAM | ||
295 | help | 296 | help |
296 | Support the MMP Two-Channel DMA engine. | 297 | Support the MMP Two-Channel DMA engine. |
297 | This engine used for MMP Audio DMA and pxa910 SQU. | 298 | This engine used for MMP Audio DMA and pxa910 SQU. |
299 | It needs sram driver under mach-mmp. | ||
298 | 300 | ||
299 | Say Y here if you enabled MMP ADMA, otherwise say N. | 301 | Say Y here if you enabled MMP ADMA, otherwise say N. |
300 | 302 | ||
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 92caad629d99..ed610b497518 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -535,6 +535,34 @@ struct dma_chan *dma_get_slave_channel(struct dma_chan *chan) | |||
535 | } | 535 | } |
536 | EXPORT_SYMBOL_GPL(dma_get_slave_channel); | 536 | EXPORT_SYMBOL_GPL(dma_get_slave_channel); |
537 | 537 | ||
538 | struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) | ||
539 | { | ||
540 | dma_cap_mask_t mask; | ||
541 | struct dma_chan *chan; | ||
542 | int err; | ||
543 | |||
544 | dma_cap_zero(mask); | ||
545 | dma_cap_set(DMA_SLAVE, mask); | ||
546 | |||
547 | /* lock against __dma_request_channel */ | ||
548 | mutex_lock(&dma_list_mutex); | ||
549 | |||
550 | chan = private_candidate(&mask, device, NULL, NULL); | ||
551 | if (chan) { | ||
552 | err = dma_chan_get(chan); | ||
553 | if (err) { | ||
554 | pr_debug("%s: failed to get %s: (%d)\n", | ||
555 | __func__, dma_chan_name(chan), err); | ||
556 | chan = NULL; | ||
557 | } | ||
558 | } | ||
559 | |||
560 | mutex_unlock(&dma_list_mutex); | ||
561 | |||
562 | return chan; | ||
563 | } | ||
564 | EXPORT_SYMBOL_GPL(dma_get_any_slave_channel); | ||
565 | |||
538 | /** | 566 | /** |
539 | * __dma_request_channel - try to allocate an exclusive channel | 567 | * __dma_request_channel - try to allocate an exclusive channel |
540 | * @mask: capabilities that the channel must satisfy | 568 | * @mask: capabilities that the channel must satisfy |
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index 8869500ab92b..c6a01ea8bc59 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c | |||
@@ -893,33 +893,17 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec, | |||
893 | struct of_dma *ofdma) | 893 | struct of_dma *ofdma) |
894 | { | 894 | { |
895 | struct mmp_pdma_device *d = ofdma->of_dma_data; | 895 | struct mmp_pdma_device *d = ofdma->of_dma_data; |
896 | struct dma_chan *chan, *candidate; | 896 | struct dma_chan *chan; |
897 | struct mmp_pdma_chan *c; | ||
897 | 898 | ||
898 | retry: | 899 | chan = dma_get_any_slave_channel(&d->device); |
899 | candidate = NULL; | 900 | if (!chan) |
900 | |||
901 | /* walk the list of channels registered with the current instance and | ||
902 | * find one that is currently unused */ | ||
903 | list_for_each_entry(chan, &d->device.channels, device_node) | ||
904 | if (chan->client_count == 0) { | ||
905 | candidate = chan; | ||
906 | break; | ||
907 | } | ||
908 | |||
909 | if (!candidate) | ||
910 | return NULL; | 901 | return NULL; |
911 | 902 | ||
912 | /* dma_get_slave_channel will return NULL if we lost a race between | 903 | c = to_mmp_pdma_chan(chan); |
913 | * the lookup and the reservation */ | 904 | c->drcmr = dma_spec->args[0]; |
914 | chan = dma_get_slave_channel(candidate); | ||
915 | |||
916 | if (chan) { | ||
917 | struct mmp_pdma_chan *c = to_mmp_pdma_chan(chan); | ||
918 | c->drcmr = dma_spec->args[0]; | ||
919 | return chan; | ||
920 | } | ||
921 | 905 | ||
922 | goto retry; | 906 | return chan; |
923 | } | 907 | } |
924 | 908 | ||
925 | static int mmp_pdma_probe(struct platform_device *op) | 909 | static int mmp_pdma_probe(struct platform_device *op) |
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 73654e33f13b..d11bb3620f27 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * DMA driver for Nvidia's Tegra20 APB DMA controller. | 2 | * DMA driver for Nvidia's Tegra20 APB DMA controller. |
3 | * | 3 | * |
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
@@ -29,11 +29,12 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/of.h> | 30 | #include <linux/of.h> |
31 | #include <linux/of_device.h> | 31 | #include <linux/of_device.h> |
32 | #include <linux/of_dma.h> | ||
32 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
33 | #include <linux/pm.h> | 34 | #include <linux/pm.h> |
34 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
36 | #include <linux/reset.h> | ||
35 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
36 | #include <linux/clk/tegra.h> | ||
37 | 38 | ||
38 | #include "dmaengine.h" | 39 | #include "dmaengine.h" |
39 | 40 | ||
@@ -199,6 +200,7 @@ struct tegra_dma_channel { | |||
199 | void *callback_param; | 200 | void *callback_param; |
200 | 201 | ||
201 | /* Channel-slave specific configuration */ | 202 | /* Channel-slave specific configuration */ |
203 | unsigned int slave_id; | ||
202 | struct dma_slave_config dma_sconfig; | 204 | struct dma_slave_config dma_sconfig; |
203 | struct tegra_dma_channel_regs channel_reg; | 205 | struct tegra_dma_channel_regs channel_reg; |
204 | }; | 206 | }; |
@@ -208,6 +210,7 @@ struct tegra_dma { | |||
208 | struct dma_device dma_dev; | 210 | struct dma_device dma_dev; |
209 | struct device *dev; | 211 | struct device *dev; |
210 | struct clk *dma_clk; | 212 | struct clk *dma_clk; |
213 | struct reset_control *rst; | ||
211 | spinlock_t global_lock; | 214 | spinlock_t global_lock; |
212 | void __iomem *base_addr; | 215 | void __iomem *base_addr; |
213 | const struct tegra_dma_chip_data *chip_data; | 216 | const struct tegra_dma_chip_data *chip_data; |
@@ -339,6 +342,8 @@ static int tegra_dma_slave_config(struct dma_chan *dc, | |||
339 | } | 342 | } |
340 | 343 | ||
341 | memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig)); | 344 | memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig)); |
345 | if (!tdc->slave_id) | ||
346 | tdc->slave_id = sconfig->slave_id; | ||
342 | tdc->config_init = true; | 347 | tdc->config_init = true; |
343 | return 0; | 348 | return 0; |
344 | } | 349 | } |
@@ -941,7 +946,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg( | |||
941 | ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32; | 946 | ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32; |
942 | 947 | ||
943 | csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW; | 948 | csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW; |
944 | csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; | 949 | csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; |
945 | if (flags & DMA_PREP_INTERRUPT) | 950 | if (flags & DMA_PREP_INTERRUPT) |
946 | csr |= TEGRA_APBDMA_CSR_IE_EOC; | 951 | csr |= TEGRA_APBDMA_CSR_IE_EOC; |
947 | 952 | ||
@@ -1085,7 +1090,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( | |||
1085 | csr |= TEGRA_APBDMA_CSR_FLOW; | 1090 | csr |= TEGRA_APBDMA_CSR_FLOW; |
1086 | if (flags & DMA_PREP_INTERRUPT) | 1091 | if (flags & DMA_PREP_INTERRUPT) |
1087 | csr |= TEGRA_APBDMA_CSR_IE_EOC; | 1092 | csr |= TEGRA_APBDMA_CSR_IE_EOC; |
1088 | csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; | 1093 | csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; |
1089 | 1094 | ||
1090 | apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1; | 1095 | apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1; |
1091 | 1096 | ||
@@ -1205,6 +1210,25 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc) | |||
1205 | kfree(sg_req); | 1210 | kfree(sg_req); |
1206 | } | 1211 | } |
1207 | clk_disable_unprepare(tdma->dma_clk); | 1212 | clk_disable_unprepare(tdma->dma_clk); |
1213 | |||
1214 | tdc->slave_id = 0; | ||
1215 | } | ||
1216 | |||
1217 | static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec, | ||
1218 | struct of_dma *ofdma) | ||
1219 | { | ||
1220 | struct tegra_dma *tdma = ofdma->of_dma_data; | ||
1221 | struct dma_chan *chan; | ||
1222 | struct tegra_dma_channel *tdc; | ||
1223 | |||
1224 | chan = dma_get_any_slave_channel(&tdma->dma_dev); | ||
1225 | if (!chan) | ||
1226 | return NULL; | ||
1227 | |||
1228 | tdc = to_tegra_dma_chan(chan); | ||
1229 | tdc->slave_id = dma_spec->args[0]; | ||
1230 | |||
1231 | return chan; | ||
1208 | } | 1232 | } |
1209 | 1233 | ||
1210 | /* Tegra20 specific DMA controller information */ | 1234 | /* Tegra20 specific DMA controller information */ |
@@ -1282,6 +1306,12 @@ static int tegra_dma_probe(struct platform_device *pdev) | |||
1282 | return PTR_ERR(tdma->dma_clk); | 1306 | return PTR_ERR(tdma->dma_clk); |
1283 | } | 1307 | } |
1284 | 1308 | ||
1309 | tdma->rst = devm_reset_control_get(&pdev->dev, "dma"); | ||
1310 | if (IS_ERR(tdma->rst)) { | ||
1311 | dev_err(&pdev->dev, "Error: Missing reset\n"); | ||
1312 | return PTR_ERR(tdma->rst); | ||
1313 | } | ||
1314 | |||
1285 | spin_lock_init(&tdma->global_lock); | 1315 | spin_lock_init(&tdma->global_lock); |
1286 | 1316 | ||
1287 | pm_runtime_enable(&pdev->dev); | 1317 | pm_runtime_enable(&pdev->dev); |
@@ -1302,9 +1332,9 @@ static int tegra_dma_probe(struct platform_device *pdev) | |||
1302 | } | 1332 | } |
1303 | 1333 | ||
1304 | /* Reset DMA controller */ | 1334 | /* Reset DMA controller */ |
1305 | tegra_periph_reset_assert(tdma->dma_clk); | 1335 | reset_control_assert(tdma->rst); |
1306 | udelay(2); | 1336 | udelay(2); |
1307 | tegra_periph_reset_deassert(tdma->dma_clk); | 1337 | reset_control_deassert(tdma->rst); |
1308 | 1338 | ||
1309 | /* Enable global DMA registers */ | 1339 | /* Enable global DMA registers */ |
1310 | tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE); | 1340 | tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE); |
@@ -1376,10 +1406,20 @@ static int tegra_dma_probe(struct platform_device *pdev) | |||
1376 | goto err_irq; | 1406 | goto err_irq; |
1377 | } | 1407 | } |
1378 | 1408 | ||
1409 | ret = of_dma_controller_register(pdev->dev.of_node, | ||
1410 | tegra_dma_of_xlate, tdma); | ||
1411 | if (ret < 0) { | ||
1412 | dev_err(&pdev->dev, | ||
1413 | "Tegra20 APB DMA OF registration failed %d\n", ret); | ||
1414 | goto err_unregister_dma_dev; | ||
1415 | } | ||
1416 | |||
1379 | dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n", | 1417 | dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n", |
1380 | cdata->nr_channels); | 1418 | cdata->nr_channels); |
1381 | return 0; | 1419 | return 0; |
1382 | 1420 | ||
1421 | err_unregister_dma_dev: | ||
1422 | dma_async_device_unregister(&tdma->dma_dev); | ||
1383 | err_irq: | 1423 | err_irq: |
1384 | while (--i >= 0) { | 1424 | while (--i >= 0) { |
1385 | struct tegra_dma_channel *tdc = &tdma->channels[i]; | 1425 | struct tegra_dma_channel *tdc = &tdma->channels[i]; |
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index 8961ba6a34b8..8db9b3bce001 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig | |||
@@ -2,6 +2,7 @@ config DRM_TEGRA | |||
2 | bool "NVIDIA Tegra DRM" | 2 | bool "NVIDIA Tegra DRM" |
3 | depends on ARCH_TEGRA || ARCH_MULTIPLATFORM | 3 | depends on ARCH_TEGRA || ARCH_MULTIPLATFORM |
4 | depends on DRM | 4 | depends on DRM |
5 | depends on RESET_CONTROLLER | ||
5 | select TEGRA_HOST1X | 6 | select TEGRA_HOST1X |
6 | select DRM_KMS_HELPER | 7 | select DRM_KMS_HELPER |
7 | select DRM_KMS_FB_HELPER | 8 | select DRM_KMS_FB_HELPER |
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index ae1cb31ead7e..cd7f1e499616 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c | |||
@@ -8,8 +8,8 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/clk/tegra.h> | ||
12 | #include <linux/debugfs.h> | 11 | #include <linux/debugfs.h> |
12 | #include <linux/reset.h> | ||
13 | 13 | ||
14 | #include "dc.h" | 14 | #include "dc.h" |
15 | #include "drm.h" | 15 | #include "drm.h" |
@@ -712,7 +712,7 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc) | |||
712 | unsigned long value; | 712 | unsigned long value; |
713 | 713 | ||
714 | /* hardware initialization */ | 714 | /* hardware initialization */ |
715 | tegra_periph_reset_deassert(dc->clk); | 715 | reset_control_deassert(dc->rst); |
716 | usleep_range(10000, 20000); | 716 | usleep_range(10000, 20000); |
717 | 717 | ||
718 | if (dc->pipe) | 718 | if (dc->pipe) |
@@ -1187,6 +1187,12 @@ static int tegra_dc_probe(struct platform_device *pdev) | |||
1187 | return PTR_ERR(dc->clk); | 1187 | return PTR_ERR(dc->clk); |
1188 | } | 1188 | } |
1189 | 1189 | ||
1190 | dc->rst = devm_reset_control_get(&pdev->dev, "dc"); | ||
1191 | if (IS_ERR(dc->rst)) { | ||
1192 | dev_err(&pdev->dev, "failed to get reset\n"); | ||
1193 | return PTR_ERR(dc->rst); | ||
1194 | } | ||
1195 | |||
1190 | err = clk_prepare_enable(dc->clk); | 1196 | err = clk_prepare_enable(dc->clk); |
1191 | if (err < 0) | 1197 | if (err < 0) |
1192 | return err; | 1198 | return err; |
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 7da0b923131f..266aae08a3bd 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <drm/drm_fb_helper.h> | 19 | #include <drm/drm_fb_helper.h> |
20 | #include <drm/drm_fixed.h> | 20 | #include <drm/drm_fixed.h> |
21 | 21 | ||
22 | struct reset_control; | ||
23 | |||
22 | struct tegra_fb { | 24 | struct tegra_fb { |
23 | struct drm_framebuffer base; | 25 | struct drm_framebuffer base; |
24 | struct tegra_bo **planes; | 26 | struct tegra_bo **planes; |
@@ -93,6 +95,7 @@ struct tegra_dc { | |||
93 | int pipe; | 95 | int pipe; |
94 | 96 | ||
95 | struct clk *clk; | 97 | struct clk *clk; |
98 | struct reset_control *rst; | ||
96 | void __iomem *regs; | 99 | void __iomem *regs; |
97 | int irq; | 100 | int irq; |
98 | 101 | ||
diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index 4cec8f526af7..0cbb24b1ae04 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/host1x.h> | 11 | #include <linux/host1x.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/reset.h> | ||
14 | #include <linux/tegra-powergate.h> | 15 | #include <linux/tegra-powergate.h> |
15 | 16 | ||
16 | #include "drm.h" | 17 | #include "drm.h" |
@@ -22,6 +23,8 @@ struct gr3d { | |||
22 | struct host1x_channel *channel; | 23 | struct host1x_channel *channel; |
23 | struct clk *clk_secondary; | 24 | struct clk *clk_secondary; |
24 | struct clk *clk; | 25 | struct clk *clk; |
26 | struct reset_control *rst_secondary; | ||
27 | struct reset_control *rst; | ||
25 | 28 | ||
26 | DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS); | 29 | DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS); |
27 | }; | 30 | }; |
@@ -255,15 +258,29 @@ static int gr3d_probe(struct platform_device *pdev) | |||
255 | return PTR_ERR(gr3d->clk); | 258 | return PTR_ERR(gr3d->clk); |
256 | } | 259 | } |
257 | 260 | ||
261 | gr3d->rst = devm_reset_control_get(&pdev->dev, "3d"); | ||
262 | if (IS_ERR(gr3d->rst)) { | ||
263 | dev_err(&pdev->dev, "cannot get reset\n"); | ||
264 | return PTR_ERR(gr3d->rst); | ||
265 | } | ||
266 | |||
258 | if (of_device_is_compatible(np, "nvidia,tegra30-gr3d")) { | 267 | if (of_device_is_compatible(np, "nvidia,tegra30-gr3d")) { |
259 | gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2"); | 268 | gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2"); |
260 | if (IS_ERR(gr3d->clk)) { | 269 | if (IS_ERR(gr3d->clk)) { |
261 | dev_err(&pdev->dev, "cannot get secondary clock\n"); | 270 | dev_err(&pdev->dev, "cannot get secondary clock\n"); |
262 | return PTR_ERR(gr3d->clk); | 271 | return PTR_ERR(gr3d->clk); |
263 | } | 272 | } |
273 | |||
274 | gr3d->rst_secondary = devm_reset_control_get(&pdev->dev, | ||
275 | "3d2"); | ||
276 | if (IS_ERR(gr3d->rst_secondary)) { | ||
277 | dev_err(&pdev->dev, "cannot get secondary reset\n"); | ||
278 | return PTR_ERR(gr3d->rst_secondary); | ||
279 | } | ||
264 | } | 280 | } |
265 | 281 | ||
266 | err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk); | 282 | err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk, |
283 | gr3d->rst); | ||
267 | if (err < 0) { | 284 | if (err < 0) { |
268 | dev_err(&pdev->dev, "failed to power up 3D unit\n"); | 285 | dev_err(&pdev->dev, "failed to power up 3D unit\n"); |
269 | return err; | 286 | return err; |
@@ -271,7 +288,8 @@ static int gr3d_probe(struct platform_device *pdev) | |||
271 | 288 | ||
272 | if (gr3d->clk_secondary) { | 289 | if (gr3d->clk_secondary) { |
273 | err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D1, | 290 | err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D1, |
274 | gr3d->clk_secondary); | 291 | gr3d->clk_secondary, |
292 | gr3d->rst_secondary); | ||
275 | if (err < 0) { | 293 | if (err < 0) { |
276 | dev_err(&pdev->dev, | 294 | dev_err(&pdev->dev, |
277 | "failed to power up secondary 3D unit\n"); | 295 | "failed to power up secondary 3D unit\n"); |
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 0cd9bc2056e8..7f6253ea5cb5 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c | |||
@@ -8,10 +8,10 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/clk/tegra.h> | ||
12 | #include <linux/debugfs.h> | 11 | #include <linux/debugfs.h> |
13 | #include <linux/hdmi.h> | 12 | #include <linux/hdmi.h> |
14 | #include <linux/regulator/consumer.h> | 13 | #include <linux/regulator/consumer.h> |
14 | #include <linux/reset.h> | ||
15 | 15 | ||
16 | #include "hdmi.h" | 16 | #include "hdmi.h" |
17 | #include "drm.h" | 17 | #include "drm.h" |
@@ -49,6 +49,7 @@ struct tegra_hdmi { | |||
49 | 49 | ||
50 | struct clk *clk_parent; | 50 | struct clk *clk_parent; |
51 | struct clk *clk; | 51 | struct clk *clk; |
52 | struct reset_control *rst; | ||
52 | 53 | ||
53 | const struct tegra_hdmi_config *config; | 54 | const struct tegra_hdmi_config *config; |
54 | 55 | ||
@@ -731,9 +732,9 @@ static int tegra_output_hdmi_enable(struct tegra_output *output) | |||
731 | return err; | 732 | return err; |
732 | } | 733 | } |
733 | 734 | ||
734 | tegra_periph_reset_assert(hdmi->clk); | 735 | reset_control_assert(hdmi->rst); |
735 | usleep_range(1000, 2000); | 736 | usleep_range(1000, 2000); |
736 | tegra_periph_reset_deassert(hdmi->clk); | 737 | reset_control_deassert(hdmi->rst); |
737 | 738 | ||
738 | tegra_dc_writel(dc, VSYNC_H_POSITION(1), | 739 | tegra_dc_writel(dc, VSYNC_H_POSITION(1), |
739 | DC_DISP_DISP_TIMING_OPTIONS); | 740 | DC_DISP_DISP_TIMING_OPTIONS); |
@@ -912,7 +913,7 @@ static int tegra_output_hdmi_disable(struct tegra_output *output) | |||
912 | { | 913 | { |
913 | struct tegra_hdmi *hdmi = to_hdmi(output); | 914 | struct tegra_hdmi *hdmi = to_hdmi(output); |
914 | 915 | ||
915 | tegra_periph_reset_assert(hdmi->clk); | 916 | reset_control_assert(hdmi->rst); |
916 | clk_disable(hdmi->clk); | 917 | clk_disable(hdmi->clk); |
917 | regulator_disable(hdmi->pll); | 918 | regulator_disable(hdmi->pll); |
918 | 919 | ||
@@ -1338,6 +1339,12 @@ static int tegra_hdmi_probe(struct platform_device *pdev) | |||
1338 | return PTR_ERR(hdmi->clk); | 1339 | return PTR_ERR(hdmi->clk); |
1339 | } | 1340 | } |
1340 | 1341 | ||
1342 | hdmi->rst = devm_reset_control_get(&pdev->dev, "hdmi"); | ||
1343 | if (IS_ERR(hdmi->rst)) { | ||
1344 | dev_err(&pdev->dev, "failed to get reset\n"); | ||
1345 | return PTR_ERR(hdmi->rst); | ||
1346 | } | ||
1347 | |||
1341 | err = clk_prepare(hdmi->clk); | 1348 | err = clk_prepare(hdmi->clk); |
1342 | if (err < 0) | 1349 | if (err < 0) |
1343 | return err; | 1350 | return err; |
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index e661edee4d0c..9704537aee3c 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/of_device.h> | 28 | #include <linux/of_device.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/clk/tegra.h> | 30 | #include <linux/reset.h> |
31 | 31 | ||
32 | #include <asm/unaligned.h> | 32 | #include <asm/unaligned.h> |
33 | 33 | ||
@@ -160,6 +160,7 @@ struct tegra_i2c_dev { | |||
160 | struct i2c_adapter adapter; | 160 | struct i2c_adapter adapter; |
161 | struct clk *div_clk; | 161 | struct clk *div_clk; |
162 | struct clk *fast_clk; | 162 | struct clk *fast_clk; |
163 | struct reset_control *rst; | ||
163 | void __iomem *base; | 164 | void __iomem *base; |
164 | int cont_id; | 165 | int cont_id; |
165 | int irq; | 166 | int irq; |
@@ -415,9 +416,9 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) | |||
415 | return err; | 416 | return err; |
416 | } | 417 | } |
417 | 418 | ||
418 | tegra_periph_reset_assert(i2c_dev->div_clk); | 419 | reset_control_assert(i2c_dev->rst); |
419 | udelay(2); | 420 | udelay(2); |
420 | tegra_periph_reset_deassert(i2c_dev->div_clk); | 421 | reset_control_deassert(i2c_dev->rst); |
421 | 422 | ||
422 | if (i2c_dev->is_dvc) | 423 | if (i2c_dev->is_dvc) |
423 | tegra_dvc_init(i2c_dev); | 424 | tegra_dvc_init(i2c_dev); |
@@ -743,6 +744,12 @@ static int tegra_i2c_probe(struct platform_device *pdev) | |||
743 | i2c_dev->cont_id = pdev->id; | 744 | i2c_dev->cont_id = pdev->id; |
744 | i2c_dev->dev = &pdev->dev; | 745 | i2c_dev->dev = &pdev->dev; |
745 | 746 | ||
747 | i2c_dev->rst = devm_reset_control_get(&pdev->dev, "i2c"); | ||
748 | if (IS_ERR(i2c_dev->rst)) { | ||
749 | dev_err(&pdev->dev, "missing controller reset"); | ||
750 | return PTR_ERR(i2c_dev->rst); | ||
751 | } | ||
752 | |||
746 | ret = of_property_read_u32(i2c_dev->dev->of_node, "clock-frequency", | 753 | ret = of_property_read_u32(i2c_dev->dev->of_node, "clock-frequency", |
747 | &i2c_dev->bus_clk_rate); | 754 | &i2c_dev->bus_clk_rate); |
748 | if (ret) | 755 | if (ret) |
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 8508879f6faf..9757a58bc897 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/input/matrix_keypad.h> | 33 | #include <linux/input/matrix_keypad.h> |
34 | #include <linux/clk/tegra.h> | 34 | #include <linux/reset.h> |
35 | #include <linux/err.h> | 35 | #include <linux/err.h> |
36 | 36 | ||
37 | #define KBC_MAX_KPENT 8 | 37 | #define KBC_MAX_KPENT 8 |
@@ -116,6 +116,7 @@ struct tegra_kbc { | |||
116 | u32 wakeup_key; | 116 | u32 wakeup_key; |
117 | struct timer_list timer; | 117 | struct timer_list timer; |
118 | struct clk *clk; | 118 | struct clk *clk; |
119 | struct reset_control *rst; | ||
119 | const struct tegra_kbc_hw_support *hw_support; | 120 | const struct tegra_kbc_hw_support *hw_support; |
120 | int max_keys; | 121 | int max_keys; |
121 | int num_rows_and_columns; | 122 | int num_rows_and_columns; |
@@ -373,9 +374,9 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) | |||
373 | clk_prepare_enable(kbc->clk); | 374 | clk_prepare_enable(kbc->clk); |
374 | 375 | ||
375 | /* Reset the KBC controller to clear all previous status.*/ | 376 | /* Reset the KBC controller to clear all previous status.*/ |
376 | tegra_periph_reset_assert(kbc->clk); | 377 | reset_control_assert(kbc->rst); |
377 | udelay(100); | 378 | udelay(100); |
378 | tegra_periph_reset_deassert(kbc->clk); | 379 | reset_control_assert(kbc->rst); |
379 | udelay(100); | 380 | udelay(100); |
380 | 381 | ||
381 | tegra_kbc_config_pins(kbc); | 382 | tegra_kbc_config_pins(kbc); |
@@ -663,6 +664,12 @@ static int tegra_kbc_probe(struct platform_device *pdev) | |||
663 | return PTR_ERR(kbc->clk); | 664 | return PTR_ERR(kbc->clk); |
664 | } | 665 | } |
665 | 666 | ||
667 | kbc->rst = devm_reset_control_get(&pdev->dev, "kbc"); | ||
668 | if (IS_ERR(kbc->rst)) { | ||
669 | dev_err(&pdev->dev, "failed to get keyboard reset\n"); | ||
670 | return PTR_ERR(kbc->rst); | ||
671 | } | ||
672 | |||
666 | /* | 673 | /* |
667 | * The time delay between two consecutive reads of the FIFO is | 674 | * The time delay between two consecutive reads of the FIFO is |
668 | * the sum of the repeat time and the time taken for scanning | 675 | * the sum of the repeat time and the time taken for scanning |
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index b8ba2f794559..330f7e3a32dd 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -25,7 +25,6 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/clk/tegra.h> | ||
29 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
30 | #include <linux/export.h> | 29 | #include <linux/export.h> |
31 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
@@ -39,6 +38,7 @@ | |||
39 | #include <linux/of_platform.h> | 38 | #include <linux/of_platform.h> |
40 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
41 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
41 | #include <linux/reset.h> | ||
42 | #include <linux/sizes.h> | 42 | #include <linux/sizes.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/tegra-cpuidle.h> | 44 | #include <linux/tegra-cpuidle.h> |
@@ -259,10 +259,13 @@ struct tegra_pcie { | |||
259 | 259 | ||
260 | struct clk *pex_clk; | 260 | struct clk *pex_clk; |
261 | struct clk *afi_clk; | 261 | struct clk *afi_clk; |
262 | struct clk *pcie_xclk; | ||
263 | struct clk *pll_e; | 262 | struct clk *pll_e; |
264 | struct clk *cml_clk; | 263 | struct clk *cml_clk; |
265 | 264 | ||
265 | struct reset_control *pex_rst; | ||
266 | struct reset_control *afi_rst; | ||
267 | struct reset_control *pcie_xrst; | ||
268 | |||
266 | struct tegra_msi msi; | 269 | struct tegra_msi msi; |
267 | 270 | ||
268 | struct list_head ports; | 271 | struct list_head ports; |
@@ -858,7 +861,7 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | |||
858 | pads_writel(pcie, value, PADS_CTL); | 861 | pads_writel(pcie, value, PADS_CTL); |
859 | 862 | ||
860 | /* take the PCIe interface module out of reset */ | 863 | /* take the PCIe interface module out of reset */ |
861 | tegra_periph_reset_deassert(pcie->pcie_xclk); | 864 | reset_control_deassert(pcie->pcie_xrst); |
862 | 865 | ||
863 | /* finally enable PCIe */ | 866 | /* finally enable PCIe */ |
864 | value = afi_readl(pcie, AFI_CONFIGURATION); | 867 | value = afi_readl(pcie, AFI_CONFIGURATION); |
@@ -891,9 +894,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie) | |||
891 | 894 | ||
892 | /* TODO: disable and unprepare clocks? */ | 895 | /* TODO: disable and unprepare clocks? */ |
893 | 896 | ||
894 | tegra_periph_reset_assert(pcie->pcie_xclk); | 897 | reset_control_assert(pcie->pcie_xrst); |
895 | tegra_periph_reset_assert(pcie->afi_clk); | 898 | reset_control_assert(pcie->afi_rst); |
896 | tegra_periph_reset_assert(pcie->pex_clk); | 899 | reset_control_assert(pcie->pex_rst); |
897 | 900 | ||
898 | tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); | 901 | tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); |
899 | 902 | ||
@@ -921,9 +924,9 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) | |||
921 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | 924 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; |
922 | int err; | 925 | int err; |
923 | 926 | ||
924 | tegra_periph_reset_assert(pcie->pcie_xclk); | 927 | reset_control_assert(pcie->pcie_xrst); |
925 | tegra_periph_reset_assert(pcie->afi_clk); | 928 | reset_control_assert(pcie->afi_rst); |
926 | tegra_periph_reset_assert(pcie->pex_clk); | 929 | reset_control_assert(pcie->pex_rst); |
927 | 930 | ||
928 | tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); | 931 | tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); |
929 | 932 | ||
@@ -952,13 +955,14 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) | |||
952 | } | 955 | } |
953 | 956 | ||
954 | err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, | 957 | err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, |
955 | pcie->pex_clk); | 958 | pcie->pex_clk, |
959 | pcie->pex_rst); | ||
956 | if (err) { | 960 | if (err) { |
957 | dev_err(pcie->dev, "powerup sequence failed: %d\n", err); | 961 | dev_err(pcie->dev, "powerup sequence failed: %d\n", err); |
958 | return err; | 962 | return err; |
959 | } | 963 | } |
960 | 964 | ||
961 | tegra_periph_reset_deassert(pcie->afi_clk); | 965 | reset_control_deassert(pcie->afi_rst); |
962 | 966 | ||
963 | err = clk_prepare_enable(pcie->afi_clk); | 967 | err = clk_prepare_enable(pcie->afi_clk); |
964 | if (err < 0) { | 968 | if (err < 0) { |
@@ -996,10 +1000,6 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie) | |||
996 | if (IS_ERR(pcie->afi_clk)) | 1000 | if (IS_ERR(pcie->afi_clk)) |
997 | return PTR_ERR(pcie->afi_clk); | 1001 | return PTR_ERR(pcie->afi_clk); |
998 | 1002 | ||
999 | pcie->pcie_xclk = devm_clk_get(pcie->dev, "pcie_xclk"); | ||
1000 | if (IS_ERR(pcie->pcie_xclk)) | ||
1001 | return PTR_ERR(pcie->pcie_xclk); | ||
1002 | |||
1003 | pcie->pll_e = devm_clk_get(pcie->dev, "pll_e"); | 1003 | pcie->pll_e = devm_clk_get(pcie->dev, "pll_e"); |
1004 | if (IS_ERR(pcie->pll_e)) | 1004 | if (IS_ERR(pcie->pll_e)) |
1005 | return PTR_ERR(pcie->pll_e); | 1005 | return PTR_ERR(pcie->pll_e); |
@@ -1013,6 +1013,23 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie) | |||
1013 | return 0; | 1013 | return 0; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | static int tegra_pcie_resets_get(struct tegra_pcie *pcie) | ||
1017 | { | ||
1018 | pcie->pex_rst = devm_reset_control_get(pcie->dev, "pex"); | ||
1019 | if (IS_ERR(pcie->pex_rst)) | ||
1020 | return PTR_ERR(pcie->pex_rst); | ||
1021 | |||
1022 | pcie->afi_rst = devm_reset_control_get(pcie->dev, "afi"); | ||
1023 | if (IS_ERR(pcie->afi_rst)) | ||
1024 | return PTR_ERR(pcie->afi_rst); | ||
1025 | |||
1026 | pcie->pcie_xrst = devm_reset_control_get(pcie->dev, "pcie_x"); | ||
1027 | if (IS_ERR(pcie->pcie_xrst)) | ||
1028 | return PTR_ERR(pcie->pcie_xrst); | ||
1029 | |||
1030 | return 0; | ||
1031 | } | ||
1032 | |||
1016 | static int tegra_pcie_get_resources(struct tegra_pcie *pcie) | 1033 | static int tegra_pcie_get_resources(struct tegra_pcie *pcie) |
1017 | { | 1034 | { |
1018 | struct platform_device *pdev = to_platform_device(pcie->dev); | 1035 | struct platform_device *pdev = to_platform_device(pcie->dev); |
@@ -1025,6 +1042,12 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) | |||
1025 | return err; | 1042 | return err; |
1026 | } | 1043 | } |
1027 | 1044 | ||
1045 | err = tegra_pcie_resets_get(pcie); | ||
1046 | if (err) { | ||
1047 | dev_err(&pdev->dev, "failed to get resets: %d\n", err); | ||
1048 | return err; | ||
1049 | } | ||
1050 | |||
1028 | err = tegra_pcie_power_on(pcie); | 1051 | err = tegra_pcie_power_on(pcie); |
1029 | if (err) { | 1052 | if (err) { |
1030 | dev_err(&pdev->dev, "failed to power up: %d\n", err); | 1053 | dev_err(&pdev->dev, "failed to power up: %d\n", err); |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index e2dd2fbec5ee..385602f77cad 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -448,6 +448,7 @@ config SPI_MXS | |||
448 | config SPI_TEGRA114 | 448 | config SPI_TEGRA114 |
449 | tristate "NVIDIA Tegra114 SPI Controller" | 449 | tristate "NVIDIA Tegra114 SPI Controller" |
450 | depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST | 450 | depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST |
451 | depends on RESET_CONTROLLER | ||
451 | help | 452 | help |
452 | SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller | 453 | SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller |
453 | is different than the older SoCs SPI controller and also register interface | 454 | is different than the older SoCs SPI controller and also register interface |
@@ -456,6 +457,7 @@ config SPI_TEGRA114 | |||
456 | config SPI_TEGRA20_SFLASH | 457 | config SPI_TEGRA20_SFLASH |
457 | tristate "Nvidia Tegra20 Serial flash Controller" | 458 | tristate "Nvidia Tegra20 Serial flash Controller" |
458 | depends on ARCH_TEGRA || COMPILE_TEST | 459 | depends on ARCH_TEGRA || COMPILE_TEST |
460 | depends on RESET_CONTROLLER | ||
459 | help | 461 | help |
460 | SPI driver for Nvidia Tegra20 Serial flash Controller interface. | 462 | SPI driver for Nvidia Tegra20 Serial flash Controller interface. |
461 | The main usecase of this controller is to use spi flash as boot | 463 | The main usecase of this controller is to use spi flash as boot |
@@ -464,6 +466,7 @@ config SPI_TEGRA20_SFLASH | |||
464 | config SPI_TEGRA20_SLINK | 466 | config SPI_TEGRA20_SLINK |
465 | tristate "Nvidia Tegra20/Tegra30 SLINK Controller" | 467 | tristate "Nvidia Tegra20/Tegra30 SLINK Controller" |
466 | depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST | 468 | depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST |
469 | depends on RESET_CONTROLLER | ||
467 | help | 470 | help |
468 | SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. | 471 | SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface. |
469 | 472 | ||
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index aaecfb3ebf58..c8604981a058 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c | |||
@@ -17,7 +17,6 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/clk/tegra.h> | ||
21 | #include <linux/completion.h> | 20 | #include <linux/completion.h> |
22 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
23 | #include <linux/dmaengine.h> | 22 | #include <linux/dmaengine.h> |
@@ -34,6 +33,7 @@ | |||
34 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
35 | #include <linux/of.h> | 34 | #include <linux/of.h> |
36 | #include <linux/of_device.h> | 35 | #include <linux/of_device.h> |
36 | #include <linux/reset.h> | ||
37 | #include <linux/spi/spi.h> | 37 | #include <linux/spi/spi.h> |
38 | 38 | ||
39 | #define SPI_COMMAND1 0x000 | 39 | #define SPI_COMMAND1 0x000 |
@@ -174,10 +174,10 @@ struct tegra_spi_data { | |||
174 | spinlock_t lock; | 174 | spinlock_t lock; |
175 | 175 | ||
176 | struct clk *clk; | 176 | struct clk *clk; |
177 | struct reset_control *rst; | ||
177 | void __iomem *base; | 178 | void __iomem *base; |
178 | phys_addr_t phys; | 179 | phys_addr_t phys; |
179 | unsigned irq; | 180 | unsigned irq; |
180 | int dma_req_sel; | ||
181 | u32 spi_max_frequency; | 181 | u32 spi_max_frequency; |
182 | u32 cur_speed; | 182 | u32 cur_speed; |
183 | 183 | ||
@@ -600,15 +600,15 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi, | |||
600 | dma_addr_t dma_phys; | 600 | dma_addr_t dma_phys; |
601 | int ret; | 601 | int ret; |
602 | struct dma_slave_config dma_sconfig; | 602 | struct dma_slave_config dma_sconfig; |
603 | dma_cap_mask_t mask; | ||
604 | 603 | ||
605 | dma_cap_zero(mask); | 604 | dma_chan = dma_request_slave_channel_reason(tspi->dev, |
606 | dma_cap_set(DMA_SLAVE, mask); | 605 | dma_to_memory ? "rx" : "tx"); |
607 | dma_chan = dma_request_channel(mask, NULL, NULL); | 606 | if (IS_ERR(dma_chan)) { |
608 | if (!dma_chan) { | 607 | ret = PTR_ERR(dma_chan); |
609 | dev_err(tspi->dev, | 608 | if (ret != -EPROBE_DEFER) |
610 | "Dma channel is not available, will try later\n"); | 609 | dev_err(tspi->dev, |
611 | return -EPROBE_DEFER; | 610 | "Dma channel is not available: %d\n", ret); |
611 | return ret; | ||
612 | } | 612 | } |
613 | 613 | ||
614 | dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, | 614 | dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, |
@@ -619,7 +619,6 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi, | |||
619 | return -ENOMEM; | 619 | return -ENOMEM; |
620 | } | 620 | } |
621 | 621 | ||
622 | dma_sconfig.slave_id = tspi->dma_req_sel; | ||
623 | if (dma_to_memory) { | 622 | if (dma_to_memory) { |
624 | dma_sconfig.src_addr = tspi->phys + SPI_RX_FIFO; | 623 | dma_sconfig.src_addr = tspi->phys + SPI_RX_FIFO; |
625 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 624 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
@@ -918,9 +917,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi) | |||
918 | tspi->status_reg); | 917 | tspi->status_reg); |
919 | dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x\n", | 918 | dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x\n", |
920 | tspi->command1_reg, tspi->dma_control_reg); | 919 | tspi->command1_reg, tspi->dma_control_reg); |
921 | tegra_periph_reset_assert(tspi->clk); | 920 | reset_control_assert(tspi->rst); |
922 | udelay(2); | 921 | udelay(2); |
923 | tegra_periph_reset_deassert(tspi->clk); | 922 | reset_control_deassert(tspi->rst); |
924 | complete(&tspi->xfer_completion); | 923 | complete(&tspi->xfer_completion); |
925 | goto exit; | 924 | goto exit; |
926 | } | 925 | } |
@@ -990,9 +989,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_spi_data *tspi) | |||
990 | tspi->status_reg); | 989 | tspi->status_reg); |
991 | dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x\n", | 990 | dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x\n", |
992 | tspi->command1_reg, tspi->dma_control_reg); | 991 | tspi->command1_reg, tspi->dma_control_reg); |
993 | tegra_periph_reset_assert(tspi->clk); | 992 | reset_control_assert(tspi->rst); |
994 | udelay(2); | 993 | udelay(2); |
995 | tegra_periph_reset_deassert(tspi->clk); | 994 | reset_control_deassert(tspi->rst); |
996 | complete(&tspi->xfer_completion); | 995 | complete(&tspi->xfer_completion); |
997 | spin_unlock_irqrestore(&tspi->lock, flags); | 996 | spin_unlock_irqrestore(&tspi->lock, flags); |
998 | return IRQ_HANDLED; | 997 | return IRQ_HANDLED; |
@@ -1054,11 +1053,6 @@ static void tegra_spi_parse_dt(struct platform_device *pdev, | |||
1054 | struct tegra_spi_data *tspi) | 1053 | struct tegra_spi_data *tspi) |
1055 | { | 1054 | { |
1056 | struct device_node *np = pdev->dev.of_node; | 1055 | struct device_node *np = pdev->dev.of_node; |
1057 | u32 of_dma[2]; | ||
1058 | |||
1059 | if (of_property_read_u32_array(np, "nvidia,dma-request-selector", | ||
1060 | of_dma, 2) >= 0) | ||
1061 | tspi->dma_req_sel = of_dma[1]; | ||
1062 | 1056 | ||
1063 | if (of_property_read_u32(np, "spi-max-frequency", | 1057 | if (of_property_read_u32(np, "spi-max-frequency", |
1064 | &tspi->spi_max_frequency)) | 1058 | &tspi->spi_max_frequency)) |
@@ -1127,25 +1121,25 @@ static int tegra_spi_probe(struct platform_device *pdev) | |||
1127 | goto exit_free_irq; | 1121 | goto exit_free_irq; |
1128 | } | 1122 | } |
1129 | 1123 | ||
1124 | tspi->rst = devm_reset_control_get(&pdev->dev, "spi"); | ||
1125 | if (IS_ERR(tspi->rst)) { | ||
1126 | dev_err(&pdev->dev, "can not get reset\n"); | ||
1127 | ret = PTR_ERR(tspi->rst); | ||
1128 | goto exit_free_irq; | ||
1129 | } | ||
1130 | |||
1130 | tspi->max_buf_size = SPI_FIFO_DEPTH << 2; | 1131 | tspi->max_buf_size = SPI_FIFO_DEPTH << 2; |
1131 | tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; | 1132 | tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; |
1132 | 1133 | ||
1133 | if (tspi->dma_req_sel) { | 1134 | ret = tegra_spi_init_dma_param(tspi, true); |
1134 | ret = tegra_spi_init_dma_param(tspi, true); | 1135 | if (ret < 0) |
1135 | if (ret < 0) { | 1136 | goto exit_free_irq; |
1136 | dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret); | 1137 | ret = tegra_spi_init_dma_param(tspi, false); |
1137 | goto exit_free_irq; | 1138 | if (ret < 0) |
1138 | } | 1139 | goto exit_rx_dma_free; |
1139 | 1140 | tspi->max_buf_size = tspi->dma_buf_size; | |
1140 | ret = tegra_spi_init_dma_param(tspi, false); | 1141 | init_completion(&tspi->tx_dma_complete); |
1141 | if (ret < 0) { | 1142 | init_completion(&tspi->rx_dma_complete); |
1142 | dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret); | ||
1143 | goto exit_rx_dma_free; | ||
1144 | } | ||
1145 | tspi->max_buf_size = tspi->dma_buf_size; | ||
1146 | init_completion(&tspi->tx_dma_complete); | ||
1147 | init_completion(&tspi->rx_dma_complete); | ||
1148 | } | ||
1149 | 1143 | ||
1150 | init_completion(&tspi->xfer_completion); | 1144 | init_completion(&tspi->xfer_completion); |
1151 | 1145 | ||
diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 4dc8e8129459..e6f382b33818 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c | |||
@@ -32,8 +32,8 @@ | |||
32 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
33 | #include <linux/of.h> | 33 | #include <linux/of.h> |
34 | #include <linux/of_device.h> | 34 | #include <linux/of_device.h> |
35 | #include <linux/reset.h> | ||
35 | #include <linux/spi/spi.h> | 36 | #include <linux/spi/spi.h> |
36 | #include <linux/clk/tegra.h> | ||
37 | 37 | ||
38 | #define SPI_COMMAND 0x000 | 38 | #define SPI_COMMAND 0x000 |
39 | #define SPI_GO BIT(30) | 39 | #define SPI_GO BIT(30) |
@@ -118,6 +118,7 @@ struct tegra_sflash_data { | |||
118 | spinlock_t lock; | 118 | spinlock_t lock; |
119 | 119 | ||
120 | struct clk *clk; | 120 | struct clk *clk; |
121 | struct reset_control *rst; | ||
121 | void __iomem *base; | 122 | void __iomem *base; |
122 | unsigned irq; | 123 | unsigned irq; |
123 | u32 spi_max_frequency; | 124 | u32 spi_max_frequency; |
@@ -389,9 +390,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_sflash_data *tsd) | |||
389 | dev_err(tsd->dev, | 390 | dev_err(tsd->dev, |
390 | "CpuXfer 0x%08x:0x%08x\n", tsd->command_reg, | 391 | "CpuXfer 0x%08x:0x%08x\n", tsd->command_reg, |
391 | tsd->dma_control_reg); | 392 | tsd->dma_control_reg); |
392 | tegra_periph_reset_assert(tsd->clk); | 393 | reset_control_assert(tsd->rst); |
393 | udelay(2); | 394 | udelay(2); |
394 | tegra_periph_reset_deassert(tsd->clk); | 395 | reset_control_deassert(tsd->rst); |
395 | complete(&tsd->xfer_completion); | 396 | complete(&tsd->xfer_completion); |
396 | goto exit; | 397 | goto exit; |
397 | } | 398 | } |
@@ -505,6 +506,13 @@ static int tegra_sflash_probe(struct platform_device *pdev) | |||
505 | goto exit_free_irq; | 506 | goto exit_free_irq; |
506 | } | 507 | } |
507 | 508 | ||
509 | tsd->rst = devm_reset_control_get(&pdev->dev, "spi"); | ||
510 | if (IS_ERR(tsd->rst)) { | ||
511 | dev_err(&pdev->dev, "can not get reset\n"); | ||
512 | ret = PTR_ERR(tsd->rst); | ||
513 | goto exit_free_irq; | ||
514 | } | ||
515 | |||
508 | init_completion(&tsd->xfer_completion); | 516 | init_completion(&tsd->xfer_completion); |
509 | pm_runtime_enable(&pdev->dev); | 517 | pm_runtime_enable(&pdev->dev); |
510 | if (!pm_runtime_enabled(&pdev->dev)) { | 518 | if (!pm_runtime_enabled(&pdev->dev)) { |
@@ -520,9 +528,9 @@ static int tegra_sflash_probe(struct platform_device *pdev) | |||
520 | } | 528 | } |
521 | 529 | ||
522 | /* Reset controller */ | 530 | /* Reset controller */ |
523 | tegra_periph_reset_assert(tsd->clk); | 531 | reset_control_assert(tsd->rst); |
524 | udelay(2); | 532 | udelay(2); |
525 | tegra_periph_reset_deassert(tsd->clk); | 533 | reset_control_deassert(tsd->rst); |
526 | 534 | ||
527 | tsd->def_command_reg = SPI_M_S | SPI_CS_SW; | 535 | tsd->def_command_reg = SPI_M_S | SPI_CS_SW; |
528 | tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND); | 536 | tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND); |
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index e66715ba37ed..a728bb82090f 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c | |||
@@ -33,8 +33,8 @@ | |||
33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
34 | #include <linux/of.h> | 34 | #include <linux/of.h> |
35 | #include <linux/of_device.h> | 35 | #include <linux/of_device.h> |
36 | #include <linux/reset.h> | ||
36 | #include <linux/spi/spi.h> | 37 | #include <linux/spi/spi.h> |
37 | #include <linux/clk/tegra.h> | ||
38 | 38 | ||
39 | #define SLINK_COMMAND 0x000 | 39 | #define SLINK_COMMAND 0x000 |
40 | #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) | 40 | #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) |
@@ -167,10 +167,10 @@ struct tegra_slink_data { | |||
167 | spinlock_t lock; | 167 | spinlock_t lock; |
168 | 168 | ||
169 | struct clk *clk; | 169 | struct clk *clk; |
170 | struct reset_control *rst; | ||
170 | void __iomem *base; | 171 | void __iomem *base; |
171 | phys_addr_t phys; | 172 | phys_addr_t phys; |
172 | unsigned irq; | 173 | unsigned irq; |
173 | int dma_req_sel; | ||
174 | u32 spi_max_frequency; | 174 | u32 spi_max_frequency; |
175 | u32 cur_speed; | 175 | u32 cur_speed; |
176 | 176 | ||
@@ -629,15 +629,15 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi, | |||
629 | dma_addr_t dma_phys; | 629 | dma_addr_t dma_phys; |
630 | int ret; | 630 | int ret; |
631 | struct dma_slave_config dma_sconfig; | 631 | struct dma_slave_config dma_sconfig; |
632 | dma_cap_mask_t mask; | ||
633 | 632 | ||
634 | dma_cap_zero(mask); | 633 | dma_chan = dma_request_slave_channel_reason(tspi->dev, |
635 | dma_cap_set(DMA_SLAVE, mask); | 634 | dma_to_memory ? "rx" : "tx"); |
636 | dma_chan = dma_request_channel(mask, NULL, NULL); | 635 | if (IS_ERR(dma_chan)) { |
637 | if (!dma_chan) { | 636 | ret = PTR_ERR(dma_chan); |
638 | dev_err(tspi->dev, | 637 | if (ret != -EPROBE_DEFER) |
639 | "Dma channel is not available, will try later\n"); | 638 | dev_err(tspi->dev, |
640 | return -EPROBE_DEFER; | 639 | "Dma channel is not available: %d\n", ret); |
640 | return ret; | ||
641 | } | 641 | } |
642 | 642 | ||
643 | dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, | 643 | dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, |
@@ -648,7 +648,6 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi, | |||
648 | return -ENOMEM; | 648 | return -ENOMEM; |
649 | } | 649 | } |
650 | 650 | ||
651 | dma_sconfig.slave_id = tspi->dma_req_sel; | ||
652 | if (dma_to_memory) { | 651 | if (dma_to_memory) { |
653 | dma_sconfig.src_addr = tspi->phys + SLINK_RX_FIFO; | 652 | dma_sconfig.src_addr = tspi->phys + SLINK_RX_FIFO; |
654 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 653 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
@@ -884,9 +883,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) | |||
884 | dev_err(tspi->dev, | 883 | dev_err(tspi->dev, |
885 | "CpuXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, | 884 | "CpuXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, |
886 | tspi->command2_reg, tspi->dma_control_reg); | 885 | tspi->command2_reg, tspi->dma_control_reg); |
887 | tegra_periph_reset_assert(tspi->clk); | 886 | reset_control_assert(tspi->rst); |
888 | udelay(2); | 887 | udelay(2); |
889 | tegra_periph_reset_deassert(tspi->clk); | 888 | reset_control_deassert(tspi->rst); |
890 | complete(&tspi->xfer_completion); | 889 | complete(&tspi->xfer_completion); |
891 | goto exit; | 890 | goto exit; |
892 | } | 891 | } |
@@ -957,9 +956,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_slink_data *tspi) | |||
957 | dev_err(tspi->dev, | 956 | dev_err(tspi->dev, |
958 | "DmaXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, | 957 | "DmaXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, |
959 | tspi->command2_reg, tspi->dma_control_reg); | 958 | tspi->command2_reg, tspi->dma_control_reg); |
960 | tegra_periph_reset_assert(tspi->clk); | 959 | reset_control_assert(tspi->rst); |
961 | udelay(2); | 960 | udelay(2); |
962 | tegra_periph_reset_deassert(tspi->clk); | 961 | reset_control_assert(tspi->rst); |
963 | complete(&tspi->xfer_completion); | 962 | complete(&tspi->xfer_completion); |
964 | spin_unlock_irqrestore(&tspi->lock, flags); | 963 | spin_unlock_irqrestore(&tspi->lock, flags); |
965 | return IRQ_HANDLED; | 964 | return IRQ_HANDLED; |
@@ -1020,11 +1019,6 @@ static irqreturn_t tegra_slink_isr(int irq, void *context_data) | |||
1020 | static void tegra_slink_parse_dt(struct tegra_slink_data *tspi) | 1019 | static void tegra_slink_parse_dt(struct tegra_slink_data *tspi) |
1021 | { | 1020 | { |
1022 | struct device_node *np = tspi->dev->of_node; | 1021 | struct device_node *np = tspi->dev->of_node; |
1023 | u32 of_dma[2]; | ||
1024 | |||
1025 | if (of_property_read_u32_array(np, "nvidia,dma-request-selector", | ||
1026 | of_dma, 2) >= 0) | ||
1027 | tspi->dma_req_sel = of_dma[1]; | ||
1028 | 1022 | ||
1029 | if (of_property_read_u32(np, "spi-max-frequency", | 1023 | if (of_property_read_u32(np, "spi-max-frequency", |
1030 | &tspi->spi_max_frequency)) | 1024 | &tspi->spi_max_frequency)) |
@@ -1118,25 +1112,25 @@ static int tegra_slink_probe(struct platform_device *pdev) | |||
1118 | goto exit_free_irq; | 1112 | goto exit_free_irq; |
1119 | } | 1113 | } |
1120 | 1114 | ||
1115 | tspi->rst = devm_reset_control_get(&pdev->dev, "spi"); | ||
1116 | if (IS_ERR(tspi->rst)) { | ||
1117 | dev_err(&pdev->dev, "can not get reset\n"); | ||
1118 | ret = PTR_ERR(tspi->rst); | ||
1119 | goto exit_free_irq; | ||
1120 | } | ||
1121 | |||
1121 | tspi->max_buf_size = SLINK_FIFO_DEPTH << 2; | 1122 | tspi->max_buf_size = SLINK_FIFO_DEPTH << 2; |
1122 | tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; | 1123 | tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; |
1123 | 1124 | ||
1124 | if (tspi->dma_req_sel) { | 1125 | ret = tegra_slink_init_dma_param(tspi, true); |
1125 | ret = tegra_slink_init_dma_param(tspi, true); | 1126 | if (ret < 0) |
1126 | if (ret < 0) { | 1127 | goto exit_free_irq; |
1127 | dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret); | 1128 | ret = tegra_slink_init_dma_param(tspi, false); |
1128 | goto exit_free_irq; | 1129 | if (ret < 0) |
1129 | } | 1130 | goto exit_rx_dma_free; |
1130 | 1131 | tspi->max_buf_size = tspi->dma_buf_size; | |
1131 | ret = tegra_slink_init_dma_param(tspi, false); | 1132 | init_completion(&tspi->tx_dma_complete); |
1132 | if (ret < 0) { | 1133 | init_completion(&tspi->rx_dma_complete); |
1133 | dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret); | ||
1134 | goto exit_rx_dma_free; | ||
1135 | } | ||
1136 | tspi->max_buf_size = tspi->dma_buf_size; | ||
1137 | init_completion(&tspi->tx_dma_complete); | ||
1138 | init_completion(&tspi->rx_dma_complete); | ||
1139 | } | ||
1140 | 1134 | ||
1141 | init_completion(&tspi->xfer_completion); | 1135 | init_completion(&tspi->xfer_completion); |
1142 | 1136 | ||
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index bb152201e93d..3ee0b1887a54 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
39 | #include <linux/clk/tegra.h> | ||
40 | 39 | ||
41 | #include "nvec.h" | 40 | #include "nvec.h" |
42 | 41 | ||
@@ -734,9 +733,9 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) | |||
734 | 733 | ||
735 | clk_prepare_enable(nvec->i2c_clk); | 734 | clk_prepare_enable(nvec->i2c_clk); |
736 | 735 | ||
737 | tegra_periph_reset_assert(nvec->i2c_clk); | 736 | reset_control_assert(nvec->rst); |
738 | udelay(2); | 737 | udelay(2); |
739 | tegra_periph_reset_deassert(nvec->i2c_clk); | 738 | reset_control_deassert(nvec->rst); |
740 | 739 | ||
741 | val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN | | 740 | val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN | |
742 | (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT); | 741 | (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT); |
@@ -837,6 +836,12 @@ static int tegra_nvec_probe(struct platform_device *pdev) | |||
837 | return -ENODEV; | 836 | return -ENODEV; |
838 | } | 837 | } |
839 | 838 | ||
839 | nvec->rst = devm_reset_control_get(&pdev->dev, "i2c"); | ||
840 | if (IS_ERR(nvec->rst)) { | ||
841 | dev_err(nvec->dev, "failed to get controller reset\n"); | ||
842 | return PTR_ERR(nvec->rst); | ||
843 | } | ||
844 | |||
840 | nvec->base = base; | 845 | nvec->base = base; |
841 | nvec->irq = res->start; | 846 | nvec->irq = res->start; |
842 | nvec->i2c_clk = i2c_clk; | 847 | nvec->i2c_clk = i2c_clk; |
diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index e880518935fb..e271375053fa 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/notifier.h> | 25 | #include <linux/notifier.h> |
26 | #include <linux/reset.h> | ||
26 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
27 | #include <linux/workqueue.h> | 28 | #include <linux/workqueue.h> |
28 | 29 | ||
@@ -109,7 +110,8 @@ struct nvec_msg { | |||
109 | * @irq: The IRQ of the I2C device | 110 | * @irq: The IRQ of the I2C device |
110 | * @i2c_addr: The address of the I2C slave | 111 | * @i2c_addr: The address of the I2C slave |
111 | * @base: The base of the memory mapped region of the I2C device | 112 | * @base: The base of the memory mapped region of the I2C device |
112 | * @clk: The clock of the I2C device | 113 | * @i2c_clk: The clock of the I2C device |
114 | * @rst: The reset of the I2C device | ||
113 | * @notifier_list: Notifiers to be called on received messages, see | 115 | * @notifier_list: Notifiers to be called on received messages, see |
114 | * nvec_register_notifier() | 116 | * nvec_register_notifier() |
115 | * @rx_data: Received messages that have to be processed | 117 | * @rx_data: Received messages that have to be processed |
@@ -139,6 +141,7 @@ struct nvec_chip { | |||
139 | int i2c_addr; | 141 | int i2c_addr; |
140 | void __iomem *base; | 142 | void __iomem *base; |
141 | struct clk *i2c_clk; | 143 | struct clk *i2c_clk; |
144 | struct reset_control *rst; | ||
142 | struct atomic_notifier_head notifier_list; | 145 | struct atomic_notifier_head notifier_list; |
143 | struct list_head rx_data, tx_data; | 146 | struct list_head rx_data, tx_data; |
144 | struct notifier_block nvec_status_notifier; | 147 | struct notifier_block nvec_status_notifier; |
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index dfe79ccc4fb3..d5c2a287b7e7 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/of_device.h> | 34 | #include <linux/of_device.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/reset.h> | ||
37 | #include <linux/serial.h> | 38 | #include <linux/serial.h> |
38 | #include <linux/serial_8250.h> | 39 | #include <linux/serial_8250.h> |
39 | #include <linux/serial_core.h> | 40 | #include <linux/serial_core.h> |
@@ -44,8 +45,6 @@ | |||
44 | #include <linux/tty.h> | 45 | #include <linux/tty.h> |
45 | #include <linux/tty_flip.h> | 46 | #include <linux/tty_flip.h> |
46 | 47 | ||
47 | #include <linux/clk/tegra.h> | ||
48 | |||
49 | #define TEGRA_UART_TYPE "TEGRA_UART" | 48 | #define TEGRA_UART_TYPE "TEGRA_UART" |
50 | #define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE) | 49 | #define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE) |
51 | #define BYTES_TO_ALIGN(x) ((unsigned long)(x) & 0x3) | 50 | #define BYTES_TO_ALIGN(x) ((unsigned long)(x) & 0x3) |
@@ -103,6 +102,7 @@ struct tegra_uart_port { | |||
103 | const struct tegra_uart_chip_data *cdata; | 102 | const struct tegra_uart_chip_data *cdata; |
104 | 103 | ||
105 | struct clk *uart_clk; | 104 | struct clk *uart_clk; |
105 | struct reset_control *rst; | ||
106 | unsigned int current_baud; | 106 | unsigned int current_baud; |
107 | 107 | ||
108 | /* Register shadow */ | 108 | /* Register shadow */ |
@@ -120,7 +120,6 @@ struct tegra_uart_port { | |||
120 | bool rx_timeout; | 120 | bool rx_timeout; |
121 | int rx_in_progress; | 121 | int rx_in_progress; |
122 | int symb_bit; | 122 | int symb_bit; |
123 | int dma_req_sel; | ||
124 | 123 | ||
125 | struct dma_chan *rx_dma_chan; | 124 | struct dma_chan *rx_dma_chan; |
126 | struct dma_chan *tx_dma_chan; | 125 | struct dma_chan *tx_dma_chan; |
@@ -832,9 +831,9 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup) | |||
832 | clk_prepare_enable(tup->uart_clk); | 831 | clk_prepare_enable(tup->uart_clk); |
833 | 832 | ||
834 | /* Reset the UART controller to clear all previous status.*/ | 833 | /* Reset the UART controller to clear all previous status.*/ |
835 | tegra_periph_reset_assert(tup->uart_clk); | 834 | reset_control_assert(tup->rst); |
836 | udelay(10); | 835 | udelay(10); |
837 | tegra_periph_reset_deassert(tup->uart_clk); | 836 | reset_control_deassert(tup->rst); |
838 | 837 | ||
839 | tup->rx_in_progress = 0; | 838 | tup->rx_in_progress = 0; |
840 | tup->tx_in_progress = 0; | 839 | tup->tx_in_progress = 0; |
@@ -910,15 +909,14 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, | |||
910 | dma_addr_t dma_phys; | 909 | dma_addr_t dma_phys; |
911 | int ret; | 910 | int ret; |
912 | struct dma_slave_config dma_sconfig; | 911 | struct dma_slave_config dma_sconfig; |
913 | dma_cap_mask_t mask; | ||
914 | 912 | ||
915 | dma_cap_zero(mask); | 913 | dma_chan = dma_request_slave_channel_reason(tup->uport.dev, |
916 | dma_cap_set(DMA_SLAVE, mask); | 914 | dma_to_memory ? "rx" : "tx"); |
917 | dma_chan = dma_request_channel(mask, NULL, NULL); | 915 | if (IS_ERR(dma_chan)) { |
918 | if (!dma_chan) { | 916 | ret = PTR_ERR(dma_chan); |
919 | dev_err(tup->uport.dev, | 917 | dev_err(tup->uport.dev, |
920 | "Dma channel is not available, will try later\n"); | 918 | "DMA channel alloc failed: %d\n", ret); |
921 | return -EPROBE_DEFER; | 919 | return ret; |
922 | } | 920 | } |
923 | 921 | ||
924 | if (dma_to_memory) { | 922 | if (dma_to_memory) { |
@@ -938,7 +936,6 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, | |||
938 | dma_buf = tup->uport.state->xmit.buf; | 936 | dma_buf = tup->uport.state->xmit.buf; |
939 | } | 937 | } |
940 | 938 | ||
941 | dma_sconfig.slave_id = tup->dma_req_sel; | ||
942 | if (dma_to_memory) { | 939 | if (dma_to_memory) { |
943 | dma_sconfig.src_addr = tup->uport.mapbase; | 940 | dma_sconfig.src_addr = tup->uport.mapbase; |
944 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | 941 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
@@ -1222,17 +1219,8 @@ static int tegra_uart_parse_dt(struct platform_device *pdev, | |||
1222 | struct tegra_uart_port *tup) | 1219 | struct tegra_uart_port *tup) |
1223 | { | 1220 | { |
1224 | struct device_node *np = pdev->dev.of_node; | 1221 | struct device_node *np = pdev->dev.of_node; |
1225 | u32 of_dma[2]; | ||
1226 | int port; | 1222 | int port; |
1227 | 1223 | ||
1228 | if (of_property_read_u32_array(np, "nvidia,dma-request-selector", | ||
1229 | of_dma, 2) >= 0) { | ||
1230 | tup->dma_req_sel = of_dma[1]; | ||
1231 | } else { | ||
1232 | dev_err(&pdev->dev, "missing dma requestor in device tree\n"); | ||
1233 | return -EINVAL; | ||
1234 | } | ||
1235 | |||
1236 | port = of_alias_get_id(np, "serial"); | 1224 | port = of_alias_get_id(np, "serial"); |
1237 | if (port < 0) { | 1225 | if (port < 0) { |
1238 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", port); | 1226 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", port); |
@@ -1320,6 +1308,12 @@ static int tegra_uart_probe(struct platform_device *pdev) | |||
1320 | return PTR_ERR(tup->uart_clk); | 1308 | return PTR_ERR(tup->uart_clk); |
1321 | } | 1309 | } |
1322 | 1310 | ||
1311 | tup->rst = devm_reset_control_get(&pdev->dev, "serial"); | ||
1312 | if (IS_ERR(tup->rst)) { | ||
1313 | dev_err(&pdev->dev, "Couldn't get the reset\n"); | ||
1314 | return PTR_ERR(tup->rst); | ||
1315 | } | ||
1316 | |||
1323 | u->iotype = UPIO_MEM32; | 1317 | u->iotype = UPIO_MEM32; |
1324 | u->irq = platform_get_irq(pdev, 0); | 1318 | u->irq = platform_get_irq(pdev, 0); |
1325 | u->regshift = 2; | 1319 | u->regshift = 2; |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 7d8103cd3e2e..e4bf0e435af6 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -23,35 +23,34 @@ | |||
23 | 23 | ||
24 | #undef DEBUG | 24 | #undef DEBUG |
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/console.h> | ||
28 | #include <linux/ctype.h> | ||
29 | #include <linux/cpufreq.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/dmaengine.h> | ||
32 | #include <linux/dma-mapping.h> | ||
33 | #include <linux/err.h> | ||
27 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
28 | #include <linux/sh_dma.h> | 35 | #include <linux/init.h> |
29 | #include <linux/timer.h> | ||
30 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
31 | #include <linux/tty.h> | ||
32 | #include <linux/tty_flip.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/major.h> | ||
35 | #include <linux/string.h> | ||
36 | #include <linux/sysrq.h> | ||
37 | #include <linux/ioport.h> | 37 | #include <linux/ioport.h> |
38 | #include <linux/major.h> | ||
39 | #include <linux/module.h> | ||
38 | #include <linux/mm.h> | 40 | #include <linux/mm.h> |
39 | #include <linux/init.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/console.h> | ||
42 | #include <linux/platform_device.h> | ||
43 | #include <linux/serial_sci.h> | ||
44 | #include <linux/notifier.h> | 41 | #include <linux/notifier.h> |
42 | #include <linux/platform_device.h> | ||
45 | #include <linux/pm_runtime.h> | 43 | #include <linux/pm_runtime.h> |
46 | #include <linux/cpufreq.h> | ||
47 | #include <linux/clk.h> | ||
48 | #include <linux/ctype.h> | ||
49 | #include <linux/err.h> | ||
50 | #include <linux/dmaengine.h> | ||
51 | #include <linux/dma-mapping.h> | ||
52 | #include <linux/scatterlist.h> | 44 | #include <linux/scatterlist.h> |
45 | #include <linux/serial.h> | ||
46 | #include <linux/serial_sci.h> | ||
47 | #include <linux/sh_dma.h> | ||
53 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
54 | #include <linux/gpio.h> | 49 | #include <linux/string.h> |
50 | #include <linux/sysrq.h> | ||
51 | #include <linux/timer.h> | ||
52 | #include <linux/tty.h> | ||
53 | #include <linux/tty_flip.h> | ||
55 | 54 | ||
56 | #ifdef CONFIG_SUPERH | 55 | #ifdef CONFIG_SUPERH |
57 | #include <asm/sh_bios.h> | 56 | #include <asm/sh_bios.h> |
@@ -64,6 +63,10 @@ struct sci_port { | |||
64 | 63 | ||
65 | /* Platform configuration */ | 64 | /* Platform configuration */ |
66 | struct plat_sci_port *cfg; | 65 | struct plat_sci_port *cfg; |
66 | int overrun_bit; | ||
67 | unsigned int error_mask; | ||
68 | unsigned int sampling_rate; | ||
69 | |||
67 | 70 | ||
68 | /* Break timer */ | 71 | /* Break timer */ |
69 | struct timer_list break_timer; | 72 | struct timer_list break_timer; |
@@ -74,8 +77,8 @@ struct sci_port { | |||
74 | /* Function clock */ | 77 | /* Function clock */ |
75 | struct clk *fclk; | 78 | struct clk *fclk; |
76 | 79 | ||
80 | int irqs[SCIx_NR_IRQS]; | ||
77 | char *irqstr[SCIx_NR_IRQS]; | 81 | char *irqstr[SCIx_NR_IRQS]; |
78 | char *gpiostr[SCIx_NR_FNS]; | ||
79 | 82 | ||
80 | struct dma_chan *chan_tx; | 83 | struct dma_chan *chan_tx; |
81 | struct dma_chan *chan_rx; | 84 | struct dma_chan *chan_rx; |
@@ -421,9 +424,9 @@ static void sci_port_enable(struct sci_port *sci_port) | |||
421 | 424 | ||
422 | pm_runtime_get_sync(sci_port->port.dev); | 425 | pm_runtime_get_sync(sci_port->port.dev); |
423 | 426 | ||
424 | clk_enable(sci_port->iclk); | 427 | clk_prepare_enable(sci_port->iclk); |
425 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); | 428 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
426 | clk_enable(sci_port->fclk); | 429 | clk_prepare_enable(sci_port->fclk); |
427 | } | 430 | } |
428 | 431 | ||
429 | static void sci_port_disable(struct sci_port *sci_port) | 432 | static void sci_port_disable(struct sci_port *sci_port) |
@@ -431,8 +434,16 @@ static void sci_port_disable(struct sci_port *sci_port) | |||
431 | if (!sci_port->port.dev) | 434 | if (!sci_port->port.dev) |
432 | return; | 435 | return; |
433 | 436 | ||
434 | clk_disable(sci_port->fclk); | 437 | /* Cancel the break timer to ensure that the timer handler will not try |
435 | clk_disable(sci_port->iclk); | 438 | * to access the hardware with clocks and power disabled. Reset the |
439 | * break flag to make the break debouncing state machine ready for the | ||
440 | * next break. | ||
441 | */ | ||
442 | del_timer_sync(&sci_port->break_timer); | ||
443 | sci_port->break_flag = 0; | ||
444 | |||
445 | clk_disable_unprepare(sci_port->fclk); | ||
446 | clk_disable_unprepare(sci_port->iclk); | ||
436 | 447 | ||
437 | pm_runtime_put_sync(sci_port->port.dev); | 448 | pm_runtime_put_sync(sci_port->port.dev); |
438 | } | 449 | } |
@@ -557,7 +568,7 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
557 | return 1; | 568 | return 1; |
558 | 569 | ||
559 | /* Cast for ARM damage */ | 570 | /* Cast for ARM damage */ |
560 | return !!__raw_readb((void __iomem *)s->cfg->port_reg); | 571 | return !!__raw_readb((void __iomem *)(uintptr_t)s->cfg->port_reg); |
561 | } | 572 | } |
562 | 573 | ||
563 | /* ********************************************************************** * | 574 | /* ********************************************************************** * |
@@ -733,8 +744,6 @@ static void sci_break_timer(unsigned long data) | |||
733 | { | 744 | { |
734 | struct sci_port *port = (struct sci_port *)data; | 745 | struct sci_port *port = (struct sci_port *)data; |
735 | 746 | ||
736 | sci_port_enable(port); | ||
737 | |||
738 | if (sci_rxd_in(&port->port) == 0) { | 747 | if (sci_rxd_in(&port->port) == 0) { |
739 | port->break_flag = 1; | 748 | port->break_flag = 1; |
740 | sci_schedule_break_timer(port); | 749 | sci_schedule_break_timer(port); |
@@ -744,8 +753,6 @@ static void sci_break_timer(unsigned long data) | |||
744 | sci_schedule_break_timer(port); | 753 | sci_schedule_break_timer(port); |
745 | } else | 754 | } else |
746 | port->break_flag = 0; | 755 | port->break_flag = 0; |
747 | |||
748 | sci_port_disable(port); | ||
749 | } | 756 | } |
750 | 757 | ||
751 | static int sci_handle_errors(struct uart_port *port) | 758 | static int sci_handle_errors(struct uart_port *port) |
@@ -755,19 +762,15 @@ static int sci_handle_errors(struct uart_port *port) | |||
755 | struct tty_port *tport = &port->state->port; | 762 | struct tty_port *tport = &port->state->port; |
756 | struct sci_port *s = to_sci_port(port); | 763 | struct sci_port *s = to_sci_port(port); |
757 | 764 | ||
758 | /* | 765 | /* Handle overruns */ |
759 | * Handle overruns, if supported. | 766 | if (status & (1 << s->overrun_bit)) { |
760 | */ | 767 | port->icount.overrun++; |
761 | if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) { | ||
762 | if (status & (1 << s->cfg->overrun_bit)) { | ||
763 | port->icount.overrun++; | ||
764 | 768 | ||
765 | /* overrun error */ | 769 | /* overrun error */ |
766 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN)) | 770 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN)) |
767 | copied++; | 771 | copied++; |
768 | 772 | ||
769 | dev_notice(port->dev, "overrun error"); | 773 | dev_notice(port->dev, "overrun error"); |
770 | } | ||
771 | } | 774 | } |
772 | 775 | ||
773 | if (status & SCxSR_FER(port)) { | 776 | if (status & SCxSR_FER(port)) { |
@@ -829,7 +832,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port) | |||
829 | if (!reg->size) | 832 | if (!reg->size) |
830 | return 0; | 833 | return 0; |
831 | 834 | ||
832 | if ((serial_port_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) { | 835 | if ((serial_port_in(port, SCLSR) & (1 << s->overrun_bit))) { |
833 | serial_port_out(port, SCLSR, 0); | 836 | serial_port_out(port, SCLSR, 0); |
834 | 837 | ||
835 | port->icount.overrun++; | 838 | port->icount.overrun++; |
@@ -1075,19 +1078,19 @@ static int sci_request_irq(struct sci_port *port) | |||
1075 | 1078 | ||
1076 | for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { | 1079 | for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { |
1077 | struct sci_irq_desc *desc; | 1080 | struct sci_irq_desc *desc; |
1078 | unsigned int irq; | 1081 | int irq; |
1079 | 1082 | ||
1080 | if (SCIx_IRQ_IS_MUXED(port)) { | 1083 | if (SCIx_IRQ_IS_MUXED(port)) { |
1081 | i = SCIx_MUX_IRQ; | 1084 | i = SCIx_MUX_IRQ; |
1082 | irq = up->irq; | 1085 | irq = up->irq; |
1083 | } else { | 1086 | } else { |
1084 | irq = port->cfg->irqs[i]; | 1087 | irq = port->irqs[i]; |
1085 | 1088 | ||
1086 | /* | 1089 | /* |
1087 | * Certain port types won't support all of the | 1090 | * Certain port types won't support all of the |
1088 | * available interrupt sources. | 1091 | * available interrupt sources. |
1089 | */ | 1092 | */ |
1090 | if (unlikely(!irq)) | 1093 | if (unlikely(irq < 0)) |
1091 | continue; | 1094 | continue; |
1092 | } | 1095 | } |
1093 | 1096 | ||
@@ -1112,7 +1115,7 @@ static int sci_request_irq(struct sci_port *port) | |||
1112 | 1115 | ||
1113 | out_noirq: | 1116 | out_noirq: |
1114 | while (--i >= 0) | 1117 | while (--i >= 0) |
1115 | free_irq(port->cfg->irqs[i], port); | 1118 | free_irq(port->irqs[i], port); |
1116 | 1119 | ||
1117 | out_nomem: | 1120 | out_nomem: |
1118 | while (--j >= 0) | 1121 | while (--j >= 0) |
@@ -1130,16 +1133,16 @@ static void sci_free_irq(struct sci_port *port) | |||
1130 | * IRQ first. | 1133 | * IRQ first. |
1131 | */ | 1134 | */ |
1132 | for (i = 0; i < SCIx_NR_IRQS; i++) { | 1135 | for (i = 0; i < SCIx_NR_IRQS; i++) { |
1133 | unsigned int irq = port->cfg->irqs[i]; | 1136 | int irq = port->irqs[i]; |
1134 | 1137 | ||
1135 | /* | 1138 | /* |
1136 | * Certain port types won't support all of the available | 1139 | * Certain port types won't support all of the available |
1137 | * interrupt sources. | 1140 | * interrupt sources. |
1138 | */ | 1141 | */ |
1139 | if (unlikely(!irq)) | 1142 | if (unlikely(irq < 0)) |
1140 | continue; | 1143 | continue; |
1141 | 1144 | ||
1142 | free_irq(port->cfg->irqs[i], port); | 1145 | free_irq(port->irqs[i], port); |
1143 | kfree(port->irqstr[i]); | 1146 | kfree(port->irqstr[i]); |
1144 | 1147 | ||
1145 | if (SCIx_IRQ_IS_MUXED(port)) { | 1148 | if (SCIx_IRQ_IS_MUXED(port)) { |
@@ -1149,67 +1152,6 @@ static void sci_free_irq(struct sci_port *port) | |||
1149 | } | 1152 | } |
1150 | } | 1153 | } |
1151 | 1154 | ||
1152 | static const char *sci_gpio_names[SCIx_NR_FNS] = { | ||
1153 | "sck", "rxd", "txd", "cts", "rts", | ||
1154 | }; | ||
1155 | |||
1156 | static const char *sci_gpio_str(unsigned int index) | ||
1157 | { | ||
1158 | return sci_gpio_names[index]; | ||
1159 | } | ||
1160 | |||
1161 | static void sci_init_gpios(struct sci_port *port) | ||
1162 | { | ||
1163 | struct uart_port *up = &port->port; | ||
1164 | int i; | ||
1165 | |||
1166 | if (!port->cfg) | ||
1167 | return; | ||
1168 | |||
1169 | for (i = 0; i < SCIx_NR_FNS; i++) { | ||
1170 | const char *desc; | ||
1171 | int ret; | ||
1172 | |||
1173 | if (!port->cfg->gpios[i]) | ||
1174 | continue; | ||
1175 | |||
1176 | desc = sci_gpio_str(i); | ||
1177 | |||
1178 | port->gpiostr[i] = kasprintf(GFP_KERNEL, "%s:%s", | ||
1179 | dev_name(up->dev), desc); | ||
1180 | |||
1181 | /* | ||
1182 | * If we've failed the allocation, we can still continue | ||
1183 | * on with a NULL string. | ||
1184 | */ | ||
1185 | if (!port->gpiostr[i]) | ||
1186 | dev_notice(up->dev, "%s string allocation failure\n", | ||
1187 | desc); | ||
1188 | |||
1189 | ret = gpio_request(port->cfg->gpios[i], port->gpiostr[i]); | ||
1190 | if (unlikely(ret != 0)) { | ||
1191 | dev_notice(up->dev, "failed %s gpio request\n", desc); | ||
1192 | |||
1193 | /* | ||
1194 | * If we can't get the GPIO for whatever reason, | ||
1195 | * no point in keeping the verbose string around. | ||
1196 | */ | ||
1197 | kfree(port->gpiostr[i]); | ||
1198 | } | ||
1199 | } | ||
1200 | } | ||
1201 | |||
1202 | static void sci_free_gpios(struct sci_port *port) | ||
1203 | { | ||
1204 | int i; | ||
1205 | |||
1206 | for (i = 0; i < SCIx_NR_FNS; i++) | ||
1207 | if (port->cfg->gpios[i]) { | ||
1208 | gpio_free(port->cfg->gpios[i]); | ||
1209 | kfree(port->gpiostr[i]); | ||
1210 | } | ||
1211 | } | ||
1212 | |||
1213 | static unsigned int sci_tx_empty(struct uart_port *port) | 1155 | static unsigned int sci_tx_empty(struct uart_port *port) |
1214 | { | 1156 | { |
1215 | unsigned short status = serial_port_in(port, SCxSR); | 1157 | unsigned short status = serial_port_in(port, SCxSR); |
@@ -1309,7 +1251,7 @@ static int sci_dma_rx_push(struct sci_port *s, size_t count) | |||
1309 | } | 1251 | } |
1310 | 1252 | ||
1311 | if (room < count) | 1253 | if (room < count) |
1312 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | 1254 | dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n", |
1313 | count - room); | 1255 | count - room); |
1314 | if (!room) | 1256 | if (!room) |
1315 | return room; | 1257 | return room; |
@@ -1442,7 +1384,7 @@ static void work_fn_rx(struct work_struct *work) | |||
1442 | int count; | 1384 | int count; |
1443 | 1385 | ||
1444 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); | 1386 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); |
1445 | dev_dbg(port->dev, "Read %u bytes with cookie %d\n", | 1387 | dev_dbg(port->dev, "Read %zu bytes with cookie %d\n", |
1446 | sh_desc->partial, sh_desc->cookie); | 1388 | sh_desc->partial, sh_desc->cookie); |
1447 | 1389 | ||
1448 | spin_lock_irqsave(&port->lock, flags); | 1390 | spin_lock_irqsave(&port->lock, flags); |
@@ -1655,7 +1597,7 @@ static void rx_timer_fn(unsigned long arg) | |||
1655 | 1597 | ||
1656 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | 1598 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
1657 | scr &= ~0x4000; | 1599 | scr &= ~0x4000; |
1658 | enable_irq(s->cfg->irqs[1]); | 1600 | enable_irq(s->irqs[SCIx_RXI_IRQ]); |
1659 | } | 1601 | } |
1660 | serial_port_out(port, SCSCR, scr | SCSCR_RIE); | 1602 | serial_port_out(port, SCSCR, scr | SCSCR_RIE); |
1661 | dev_dbg(port->dev, "DMA Rx timed out\n"); | 1603 | dev_dbg(port->dev, "DMA Rx timed out\n"); |
@@ -1691,16 +1633,17 @@ static void sci_request_dma(struct uart_port *port) | |||
1691 | s->chan_tx = chan; | 1633 | s->chan_tx = chan; |
1692 | sg_init_table(&s->sg_tx, 1); | 1634 | sg_init_table(&s->sg_tx, 1); |
1693 | /* UART circular tx buffer is an aligned page. */ | 1635 | /* UART circular tx buffer is an aligned page. */ |
1694 | BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); | 1636 | BUG_ON((uintptr_t)port->state->xmit.buf & ~PAGE_MASK); |
1695 | sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), | 1637 | sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), |
1696 | UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK); | 1638 | UART_XMIT_SIZE, |
1639 | (uintptr_t)port->state->xmit.buf & ~PAGE_MASK); | ||
1697 | nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); | 1640 | nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); |
1698 | if (!nent) | 1641 | if (!nent) |
1699 | sci_tx_dma_release(s, false); | 1642 | sci_tx_dma_release(s, false); |
1700 | else | 1643 | else |
1701 | dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__, | 1644 | dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", __func__, |
1702 | sg_dma_len(&s->sg_tx), | 1645 | sg_dma_len(&s->sg_tx), port->state->xmit.buf, |
1703 | port->state->xmit.buf, sg_dma_address(&s->sg_tx)); | 1646 | &sg_dma_address(&s->sg_tx)); |
1704 | 1647 | ||
1705 | s->sg_len_tx = nent; | 1648 | s->sg_len_tx = nent; |
1706 | 1649 | ||
@@ -1740,7 +1683,7 @@ static void sci_request_dma(struct uart_port *port) | |||
1740 | 1683 | ||
1741 | sg_init_table(sg, 1); | 1684 | sg_init_table(sg, 1); |
1742 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, | 1685 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, |
1743 | (int)buf[i] & ~PAGE_MASK); | 1686 | (uintptr_t)buf[i] & ~PAGE_MASK); |
1744 | sg_dma_address(sg) = dma[i]; | 1687 | sg_dma_address(sg) = dma[i]; |
1745 | } | 1688 | } |
1746 | 1689 | ||
@@ -1808,20 +1751,21 @@ static void sci_shutdown(struct uart_port *port) | |||
1808 | sci_free_irq(s); | 1751 | sci_free_irq(s); |
1809 | } | 1752 | } |
1810 | 1753 | ||
1811 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | 1754 | static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, |
1812 | unsigned long freq) | 1755 | unsigned long freq) |
1813 | { | 1756 | { |
1814 | switch (algo_id) { | 1757 | if (s->sampling_rate) |
1758 | return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; | ||
1759 | |||
1760 | switch (s->cfg->scbrr_algo_id) { | ||
1815 | case SCBRR_ALGO_1: | 1761 | case SCBRR_ALGO_1: |
1816 | return ((freq + 16 * bps) / (16 * bps) - 1); | 1762 | return freq / (16 * bps); |
1817 | case SCBRR_ALGO_2: | 1763 | case SCBRR_ALGO_2: |
1818 | return ((freq + 16 * bps) / (32 * bps) - 1); | 1764 | return DIV_ROUND_CLOSEST(freq, 32 * bps) - 1; |
1819 | case SCBRR_ALGO_3: | 1765 | case SCBRR_ALGO_3: |
1820 | return (((freq * 2) + 16 * bps) / (16 * bps) - 1); | 1766 | return freq / (8 * bps); |
1821 | case SCBRR_ALGO_4: | 1767 | case SCBRR_ALGO_4: |
1822 | return (((freq * 2) + 16 * bps) / (32 * bps) - 1); | 1768 | return DIV_ROUND_CLOSEST(freq, 16 * bps) - 1; |
1823 | case SCBRR_ALGO_5: | ||
1824 | return (((freq * 1000 / 32) / bps) - 1); | ||
1825 | } | 1769 | } |
1826 | 1770 | ||
1827 | /* Warn, but use a safe default */ | 1771 | /* Warn, but use a safe default */ |
@@ -1903,12 +1847,11 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1903 | 1847 | ||
1904 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); | 1848 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); |
1905 | if (likely(baud && port->uartclk)) { | 1849 | if (likely(baud && port->uartclk)) { |
1906 | if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { | 1850 | if (s->cfg->type == PORT_HSCIF) { |
1907 | sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, | 1851 | sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, |
1908 | &cks); | 1852 | &cks); |
1909 | } else { | 1853 | } else { |
1910 | t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, | 1854 | t = sci_scbrr_calc(s, baud, port->uartclk); |
1911 | port->uartclk); | ||
1912 | for (cks = 0; t >= 256 && cks <= 3; cks++) | 1855 | for (cks = 0; t >= 256 && cks <= 3; cks++) |
1913 | t >>= 2; | 1856 | t >>= 2; |
1914 | } | 1857 | } |
@@ -2115,10 +2058,6 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
2115 | 2058 | ||
2116 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) | 2059 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) |
2117 | { | 2060 | { |
2118 | struct sci_port *s = to_sci_port(port); | ||
2119 | |||
2120 | if (ser->irq != s->cfg->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs) | ||
2121 | return -EINVAL; | ||
2122 | if (ser->baud_base < 2400) | 2061 | if (ser->baud_base < 2400) |
2123 | /* No paper tape reader for Mitch.. */ | 2062 | /* No paper tape reader for Mitch.. */ |
2124 | return -EINVAL; | 2063 | return -EINVAL; |
@@ -2151,11 +2090,13 @@ static struct uart_ops sci_uart_ops = { | |||
2151 | }; | 2090 | }; |
2152 | 2091 | ||
2153 | static int sci_init_single(struct platform_device *dev, | 2092 | static int sci_init_single(struct platform_device *dev, |
2154 | struct sci_port *sci_port, | 2093 | struct sci_port *sci_port, unsigned int index, |
2155 | unsigned int index, | 2094 | struct plat_sci_port *p, bool early) |
2156 | struct plat_sci_port *p) | ||
2157 | { | 2095 | { |
2158 | struct uart_port *port = &sci_port->port; | 2096 | struct uart_port *port = &sci_port->port; |
2097 | const struct resource *res; | ||
2098 | unsigned int sampling_rate; | ||
2099 | unsigned int i; | ||
2159 | int ret; | 2100 | int ret; |
2160 | 2101 | ||
2161 | sci_port->cfg = p; | 2102 | sci_port->cfg = p; |
@@ -2164,31 +2105,90 @@ static int sci_init_single(struct platform_device *dev, | |||
2164 | port->iotype = UPIO_MEM; | 2105 | port->iotype = UPIO_MEM; |
2165 | port->line = index; | 2106 | port->line = index; |
2166 | 2107 | ||
2108 | if (dev->num_resources) { | ||
2109 | /* Device has resources, use them. */ | ||
2110 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
2111 | if (res == NULL) | ||
2112 | return -ENOMEM; | ||
2113 | |||
2114 | port->mapbase = res->start; | ||
2115 | |||
2116 | for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) | ||
2117 | sci_port->irqs[i] = platform_get_irq(dev, i); | ||
2118 | |||
2119 | /* The SCI generates several interrupts. They can be muxed | ||
2120 | * together or connected to different interrupt lines. In the | ||
2121 | * muxed case only one interrupt resource is specified. In the | ||
2122 | * non-muxed case three or four interrupt resources are | ||
2123 | * specified, as the BRI interrupt is optional. | ||
2124 | */ | ||
2125 | if (sci_port->irqs[0] < 0) | ||
2126 | return -ENXIO; | ||
2127 | |||
2128 | if (sci_port->irqs[1] < 0) { | ||
2129 | sci_port->irqs[1] = sci_port->irqs[0]; | ||
2130 | sci_port->irqs[2] = sci_port->irqs[0]; | ||
2131 | sci_port->irqs[3] = sci_port->irqs[0]; | ||
2132 | } | ||
2133 | } else { | ||
2134 | /* No resources, use old-style platform data. */ | ||
2135 | port->mapbase = p->mapbase; | ||
2136 | for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) | ||
2137 | sci_port->irqs[i] = p->irqs[i] ? p->irqs[i] : -ENXIO; | ||
2138 | } | ||
2139 | |||
2140 | if (p->regtype == SCIx_PROBE_REGTYPE) { | ||
2141 | ret = sci_probe_regmap(p); | ||
2142 | if (unlikely(ret)) | ||
2143 | return ret; | ||
2144 | } | ||
2145 | |||
2167 | switch (p->type) { | 2146 | switch (p->type) { |
2168 | case PORT_SCIFB: | 2147 | case PORT_SCIFB: |
2169 | port->fifosize = 256; | 2148 | port->fifosize = 256; |
2149 | sci_port->overrun_bit = 9; | ||
2150 | sampling_rate = 16; | ||
2170 | break; | 2151 | break; |
2171 | case PORT_HSCIF: | 2152 | case PORT_HSCIF: |
2172 | port->fifosize = 128; | 2153 | port->fifosize = 128; |
2154 | sampling_rate = 0; | ||
2155 | sci_port->overrun_bit = 0; | ||
2173 | break; | 2156 | break; |
2174 | case PORT_SCIFA: | 2157 | case PORT_SCIFA: |
2175 | port->fifosize = 64; | 2158 | port->fifosize = 64; |
2159 | sci_port->overrun_bit = 9; | ||
2160 | sampling_rate = 16; | ||
2176 | break; | 2161 | break; |
2177 | case PORT_SCIF: | 2162 | case PORT_SCIF: |
2178 | port->fifosize = 16; | 2163 | port->fifosize = 16; |
2164 | if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) { | ||
2165 | sci_port->overrun_bit = 9; | ||
2166 | sampling_rate = 16; | ||
2167 | } else { | ||
2168 | sci_port->overrun_bit = 0; | ||
2169 | sampling_rate = 32; | ||
2170 | } | ||
2179 | break; | 2171 | break; |
2180 | default: | 2172 | default: |
2181 | port->fifosize = 1; | 2173 | port->fifosize = 1; |
2174 | sci_port->overrun_bit = 5; | ||
2175 | sampling_rate = 32; | ||
2182 | break; | 2176 | break; |
2183 | } | 2177 | } |
2184 | 2178 | ||
2185 | if (p->regtype == SCIx_PROBE_REGTYPE) { | 2179 | /* Set the sampling rate if the baud rate calculation algorithm isn't |
2186 | ret = sci_probe_regmap(p); | 2180 | * specified. |
2187 | if (unlikely(ret)) | 2181 | */ |
2188 | return ret; | 2182 | if (p->scbrr_algo_id == SCBRR_ALGO_NONE) { |
2183 | /* SCIFA on sh7723 and sh7724 need a custom sampling rate that | ||
2184 | * doesn't match the SoC datasheet, this should be investigated. | ||
2185 | * Let platform data override the sampling rate for now. | ||
2186 | */ | ||
2187 | sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate | ||
2188 | : sampling_rate; | ||
2189 | } | 2189 | } |
2190 | 2190 | ||
2191 | if (dev) { | 2191 | if (!early) { |
2192 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); | 2192 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); |
2193 | if (IS_ERR(sci_port->iclk)) { | 2193 | if (IS_ERR(sci_port->iclk)) { |
2194 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); | 2194 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); |
@@ -2208,8 +2208,6 @@ static int sci_init_single(struct platform_device *dev, | |||
2208 | 2208 | ||
2209 | port->dev = &dev->dev; | 2209 | port->dev = &dev->dev; |
2210 | 2210 | ||
2211 | sci_init_gpios(sci_port); | ||
2212 | |||
2213 | pm_runtime_enable(&dev->dev); | 2211 | pm_runtime_enable(&dev->dev); |
2214 | } | 2212 | } |
2215 | 2213 | ||
@@ -2220,32 +2218,22 @@ static int sci_init_single(struct platform_device *dev, | |||
2220 | /* | 2218 | /* |
2221 | * Establish some sensible defaults for the error detection. | 2219 | * Establish some sensible defaults for the error detection. |
2222 | */ | 2220 | */ |
2223 | if (!p->error_mask) | 2221 | sci_port->error_mask = (p->type == PORT_SCI) ? |
2224 | p->error_mask = (p->type == PORT_SCI) ? | ||
2225 | SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; | 2222 | SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; |
2226 | 2223 | ||
2227 | /* | 2224 | /* |
2228 | * Establish sensible defaults for the overrun detection, unless | 2225 | * Establish sensible defaults for the overrun detection, unless |
2229 | * the part has explicitly disabled support for it. | 2226 | * the part has explicitly disabled support for it. |
2230 | */ | 2227 | */ |
2231 | if (p->overrun_bit != SCIx_NOT_SUPPORTED) { | ||
2232 | if (p->type == PORT_SCI) | ||
2233 | p->overrun_bit = 5; | ||
2234 | else if (p->scbrr_algo_id == SCBRR_ALGO_4) | ||
2235 | p->overrun_bit = 9; | ||
2236 | else | ||
2237 | p->overrun_bit = 0; | ||
2238 | 2228 | ||
2239 | /* | 2229 | /* |
2240 | * Make the error mask inclusive of overrun detection, if | 2230 | * Make the error mask inclusive of overrun detection, if |
2241 | * supported. | 2231 | * supported. |
2242 | */ | 2232 | */ |
2243 | p->error_mask |= (1 << p->overrun_bit); | 2233 | sci_port->error_mask |= 1 << sci_port->overrun_bit; |
2244 | } | ||
2245 | 2234 | ||
2246 | port->mapbase = p->mapbase; | ||
2247 | port->type = p->type; | 2235 | port->type = p->type; |
2248 | port->flags = p->flags; | 2236 | port->flags = UPF_FIXED_PORT | p->flags; |
2249 | port->regshift = p->regshift; | 2237 | port->regshift = p->regshift; |
2250 | 2238 | ||
2251 | /* | 2239 | /* |
@@ -2255,7 +2243,7 @@ static int sci_init_single(struct platform_device *dev, | |||
2255 | * | 2243 | * |
2256 | * For the muxed case there's nothing more to do. | 2244 | * For the muxed case there's nothing more to do. |
2257 | */ | 2245 | */ |
2258 | port->irq = p->irqs[SCIx_RXI_IRQ]; | 2246 | port->irq = sci_port->irqs[SCIx_RXI_IRQ]; |
2259 | port->irqflags = 0; | 2247 | port->irqflags = 0; |
2260 | 2248 | ||
2261 | port->serial_in = sci_serial_in; | 2249 | port->serial_in = sci_serial_in; |
@@ -2270,8 +2258,6 @@ static int sci_init_single(struct platform_device *dev, | |||
2270 | 2258 | ||
2271 | static void sci_cleanup_single(struct sci_port *port) | 2259 | static void sci_cleanup_single(struct sci_port *port) |
2272 | { | 2260 | { |
2273 | sci_free_gpios(port); | ||
2274 | |||
2275 | clk_put(port->iclk); | 2261 | clk_put(port->iclk); |
2276 | clk_put(port->fclk); | 2262 | clk_put(port->fclk); |
2277 | 2263 | ||
@@ -2387,7 +2373,7 @@ static int sci_probe_earlyprintk(struct platform_device *pdev) | |||
2387 | 2373 | ||
2388 | early_serial_console.index = pdev->id; | 2374 | early_serial_console.index = pdev->id; |
2389 | 2375 | ||
2390 | sci_init_single(NULL, &sci_ports[pdev->id], pdev->id, cfg); | 2376 | sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true); |
2391 | 2377 | ||
2392 | serial_console_setup(&early_serial_console, early_serial_buf); | 2378 | serial_console_setup(&early_serial_console, early_serial_buf); |
2393 | 2379 | ||
@@ -2454,7 +2440,7 @@ static int sci_probe_single(struct platform_device *dev, | |||
2454 | return -EINVAL; | 2440 | return -EINVAL; |
2455 | } | 2441 | } |
2456 | 2442 | ||
2457 | ret = sci_init_single(dev, sciport, index, p); | 2443 | ret = sci_init_single(dev, sciport, index, p, false); |
2458 | if (ret) | 2444 | if (ret) |
2459 | return ret; | 2445 | return ret; |
2460 | 2446 | ||
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index 5aca7364634c..d5db81a0a430 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) | 9 | #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) |
10 | #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) | 10 | #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) |
11 | 11 | ||
12 | #define SCxSR_ERRORS(port) (to_sci_port(port)->cfg->error_mask) | 12 | #define SCxSR_ERRORS(port) (to_sci_port(port)->error_mask) |
13 | 13 | ||
14 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 14 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
15 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 15 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 38bf67b1a97d..52771d4c44bc 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -326,7 +326,7 @@ static int vbus_is_present(struct usba_udc *udc) | |||
326 | 326 | ||
327 | #if defined(CONFIG_ARCH_AT91SAM9RL) | 327 | #if defined(CONFIG_ARCH_AT91SAM9RL) |
328 | 328 | ||
329 | #include <mach/at91_pmc.h> | 329 | #include <linux/clk/at91_pmc.h> |
330 | 330 | ||
331 | static void toggle_bias(int is_on) | 331 | static void toggle_bias(int is_on) |
332 | { | 332 | { |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index a8f4471dae7b..af28b748e87a 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
@@ -17,7 +17,6 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/clk/tegra.h> | ||
21 | #include <linux/dma-mapping.h> | 20 | #include <linux/dma-mapping.h> |
22 | #include <linux/err.h> | 21 | #include <linux/err.h> |
23 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
@@ -29,6 +28,7 @@ | |||
29 | #include <linux/of_gpio.h> | 28 | #include <linux/of_gpio.h> |
30 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
31 | #include <linux/pm_runtime.h> | 30 | #include <linux/pm_runtime.h> |
31 | #include <linux/reset.h> | ||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/usb/ehci_def.h> | 33 | #include <linux/usb/ehci_def.h> |
34 | #include <linux/usb/tegra_usb_phy.h> | 34 | #include <linux/usb/tegra_usb_phy.h> |
@@ -62,6 +62,7 @@ static int (*orig_hub_control)(struct usb_hcd *hcd, | |||
62 | struct tegra_ehci_hcd { | 62 | struct tegra_ehci_hcd { |
63 | struct tegra_usb_phy *phy; | 63 | struct tegra_usb_phy *phy; |
64 | struct clk *clk; | 64 | struct clk *clk; |
65 | struct reset_control *rst; | ||
65 | int port_resuming; | 66 | int port_resuming; |
66 | bool needs_double_reset; | 67 | bool needs_double_reset; |
67 | enum tegra_usb_phy_port_speed port_speed; | 68 | enum tegra_usb_phy_port_speed port_speed; |
@@ -385,13 +386,20 @@ static int tegra_ehci_probe(struct platform_device *pdev) | |||
385 | goto cleanup_hcd_create; | 386 | goto cleanup_hcd_create; |
386 | } | 387 | } |
387 | 388 | ||
389 | tegra->rst = devm_reset_control_get(&pdev->dev, "usb"); | ||
390 | if (IS_ERR(tegra->rst)) { | ||
391 | dev_err(&pdev->dev, "Can't get ehci reset\n"); | ||
392 | err = PTR_ERR(tegra->rst); | ||
393 | goto cleanup_hcd_create; | ||
394 | } | ||
395 | |||
388 | err = clk_prepare_enable(tegra->clk); | 396 | err = clk_prepare_enable(tegra->clk); |
389 | if (err) | 397 | if (err) |
390 | goto cleanup_hcd_create; | 398 | goto cleanup_hcd_create; |
391 | 399 | ||
392 | tegra_periph_reset_assert(tegra->clk); | 400 | reset_control_assert(tegra->rst); |
393 | udelay(1); | 401 | udelay(1); |
394 | tegra_periph_reset_deassert(tegra->clk); | 402 | reset_control_deassert(tegra->rst); |
395 | 403 | ||
396 | u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); | 404 | u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); |
397 | if (IS_ERR(u_phy)) { | 405 | if (IS_ERR(u_phy)) { |