blob: 289e360f38eda63d376bc15eb77eadadaf5f783a [file] [log] [blame]
Channagoud Kadabi196b27c2015-01-19 13:53:38 -05001/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
Channagoud Kadabi92db1122014-06-25 16:00:13 -04002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <err.h>
30#include <assert.h>
31#include <debug.h>
32#include <reg.h>
33#include <platform/timer.h>
34#include <platform/iomap.h>
35#include <mmc.h>
36#include <clock.h>
37#include <platform/clock.h>
38#include <blsp_qup.h>
39
40void hsusb_clock_init(void)
41{
42 int ret;
43 struct clk *iclk, *cclk;
44
45 ret = clk_get_set_enable("usb_iface_clk", 0, 1);
46 if(ret)
47 {
48 dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
49 ASSERT(0);
50 }
51
52 ret = clk_get_set_enable("usb_core_clk", 75000000, 1);
53 if(ret)
54 {
55 dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
56 ASSERT(0);
57 }
58
59 mdelay(20);
60
61 iclk = clk_get("usb_iface_clk");
62 cclk = clk_get("usb_core_clk");
63
64 clk_disable(iclk);
65 clk_disable(cclk);
66
67 mdelay(20);
68
69 /* Start the block reset for usb */
70 writel(1, USB_HS_BCR);
71
72 mdelay(20);
73
74 /* Take usb block out of reset */
75 writel(0, USB_HS_BCR);
76
77 mdelay(20);
78
79 ret = clk_enable(iclk);
80
81 if(ret)
82 {
83 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
84 ASSERT(0);
85 }
86
87 ret = clk_enable(cclk);
88
89 if(ret)
90 {
91 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
92 ASSERT(0);
93 }
94
95}
96
97void clock_init_mmc(uint32_t interface)
98{
99 char clk_name[64];
100 int ret;
101
102 snprintf(clk_name, sizeof(clk_name), "sdc%u_iface_clk", interface);
103
104 /* enable interface clock */
105 ret = clk_get_set_enable(clk_name, 0, 1);
106 if(ret)
107 {
108 dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret);
109 ASSERT(0);
110 }
111}
112
113/* Configure MMC clock */
114void clock_config_mmc(uint32_t interface, uint32_t freq)
115{
116 int ret;
117 char clk_name[64];
118
119 snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
120
121 /* Disalbe MCI_CLK before changing the sdcc clock */
122#ifndef MMC_SDHCI_SUPPORT
123 mmc_boot_mci_clk_disable();
124#endif
125
126 if(freq == MMC_CLK_400KHZ)
127 {
128 ret = clk_get_set_enable(clk_name, 400000, 1);
129 }
130 else if(freq == MMC_CLK_20MHZ)
131 {
132 ret = clk_get_set_enable(clk_name, 20000000, 1);
133 }
134 else if(freq == MMC_CLK_25MHZ)
135 {
136 ret = clk_get_set_enable(clk_name, 25000000, 1);
137 }
138 else if(freq == MMC_CLK_50MHZ)
139 {
140 ret = clk_get_set_enable(clk_name, 50000000, 1);
141 }
142 else if(freq == MMC_CLK_96MHZ)
143 {
144 ret = clk_get_set_enable(clk_name, 100000000, 1);
145 }
146 else if(freq == MMC_CLK_200MHZ)
147 {
148 ret = clk_get_set_enable(clk_name, 200000000, 1);
149 }
150 else
151 {
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500152 dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
153 ret = 0;
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400154 ASSERT(0);
155 }
156
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400157 if(ret)
158 {
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500159 dprintf(CRITICAL, "failed to set sdc%u_core_clk ret = %d\n", interface, ret);
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400160 ASSERT(0);
161 }
162
163 /* Enalbe MCI clock */
164#ifndef MMC_SDHCI_SUPPORT
165 mmc_boot_mci_clk_enable();
166#endif
167}
168
169/* Configure UART clock based on the UART block id*/
170void clock_config_uart_dm(uint8_t id)
171{
172 int ret;
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500173 char iclk[64];
174 char cclk[64];
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400175
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500176 snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
177 snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
178
179 ret = clk_get_set_enable(iclk, 0, 1);
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400180 if(ret)
181 {
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500182 dprintf(CRITICAL, "failed to set uart%u_iface_clk ret = %d\n", id, ret);
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400183 ASSERT(0);
184 }
185
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500186 ret = clk_get_set_enable(cclk, 7372800, 1);
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400187 if(ret)
188 {
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500189 dprintf(CRITICAL, "failed to set uart%u_core_clk ret = %d\n", id, ret);
Channagoud Kadabi92db1122014-06-25 16:00:13 -0400190 ASSERT(0);
191 }
192}
193
194/* Function to asynchronously reset CE.
195 * Function assumes that all the CE clocks are off.
196 */
197static void ce_async_reset(uint8_t instance)
198{
199 if (instance == 1)
200 {
201 /* TODO: Add support for instance 1. */
202 dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
203 ASSERT(0);
204 }
205 else if (instance == 2)
206 {
207 /* Start the block reset for CE */
208 writel(1, GCC_CE2_BCR);
209
210 udelay(2);
211
212 /* Take CE block out of reset */
213 writel(0, GCC_CE2_BCR);
214
215 udelay(2);
216 }
217 else
218 {
219 dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
220 ASSERT(0);
221 }
222}
223
224void clock_ce_enable(uint8_t instance)
225{
226 int ret;
227 char clk_name[64];
228
229 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
230 ret = clk_get_set_enable(clk_name, 100000000, 1);
231 if(ret)
232 {
233 dprintf(CRITICAL, "failed to set ce_src_clk ret = %d\n", ret);
234 ASSERT(0);
235 }
236
237 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
238 ret = clk_get_set_enable(clk_name, 0, 1);
239 if(ret)
240 {
241 dprintf(CRITICAL, "failed to set ce_core_clk ret = %d\n", ret);
242 ASSERT(0);
243 }
244
245 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
246 ret = clk_get_set_enable(clk_name, 0, 1);
247 if(ret)
248 {
249 dprintf(CRITICAL, "failed to set ce_ahb_clk ret = %d\n", ret);
250 ASSERT(0);
251 }
252
253 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
254 ret = clk_get_set_enable(clk_name, 0, 1);
255 if(ret)
256 {
257 dprintf(CRITICAL, "failed to set ce_axi_clk ret = %d\n", ret);
258 ASSERT(0);
259 }
260
261 /* Wait for 48 * #pipes cycles.
262 * This is necessary as immediately after an access control reset (boot up)
263 * or a debug re-enable, the Crypto core sequentially clears its internal
264 * pipe key storage memory. If pipe key initialization writes are attempted
265 * during this time, they may be overwritten by the internal clearing logic.
266 */
267 udelay(1);
268}
269
270void clock_ce_disable(uint8_t instance)
271{
272 struct clk *ahb_clk;
273 struct clk *cclk;
274 struct clk *axi_clk;
275 struct clk *src_clk;
276 char clk_name[64];
277
278 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
279 src_clk = clk_get(clk_name);
280
281 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
282 ahb_clk = clk_get(clk_name);
283
284 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
285 axi_clk = clk_get(clk_name);
286
287 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
288 cclk = clk_get(clk_name);
289
290 clk_disable(ahb_clk);
291 clk_disable(axi_clk);
292 clk_disable(cclk);
293 clk_disable(src_clk);
294
295 /* Some delay for the clocks to stabalize. */
296 udelay(1);
297}
298
299void clock_config_ce(uint8_t instance)
300{
301 /* Need to enable the clock before disabling since the clk_disable()
302 * has a check to default to nop when the clk_enable() is not called
303 * on that particular clock.
304 */
305 clock_ce_enable(instance);
306
307 clock_ce_disable(instance);
308
309 ce_async_reset(instance);
310
311 clock_ce_enable(instance);
312
313}
314
315void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
316{
317 uint8_t ret = 0;
318 char clk_name[64];
319
320 struct clk *qup_clk;
321
322 snprintf(clk_name, sizeof(clk_name), "blsp%u_ahb_clk", blsp_id);
323
324 ret = clk_get_set_enable(clk_name, 0 , 1);
325
326 if (ret) {
327 dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name);
328 return;
329 }
330
331 snprintf(clk_name, sizeof(clk_name), "blsp%u_qup%u_i2c_apps_clk",
332 blsp_id, (qup_id + 1));
333
334 qup_clk = clk_get(clk_name);
335
336 if (!qup_clk) {
337 dprintf(CRITICAL, "Failed to get %s\n", clk_name);
338 return;
339 }
340
341 ret = clk_enable(qup_clk);
342
343 if (ret) {
344 dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
345 return;
346 }
347}
Channagoud Kadabi196b27c2015-01-19 13:53:38 -0500348
349/* enables usb30 clocks */
350void clock_usb30_init(void)
351{
352 int ret;
353
354 ret = clk_get_set_enable("usb30_iface_clk", 0, 1);
355 if(ret)
356 {
357 dprintf(CRITICAL, "failed to set usb30_iface_clk. ret = %d\n", ret);
358 ASSERT(0);
359 }
360
361 ret = clk_get_set_enable("usb30_master_clk", 125000000, 1);
362 if(ret)
363 {
364 dprintf(CRITICAL, "failed to set usb30_master_clk. ret = %d\n", ret);
365 ASSERT(0);
366 }
367
368 ret = clk_get_set_enable("usb30_phy_aux_clk", 1200000, 1);
369 if(ret)
370 {
371 dprintf(CRITICAL, "failed to set usb30_phy_aux_clk. ret = %d\n", ret);
372 ASSERT(0);
373 }
374
375 ret = clk_get_set_enable("usb30_mock_utmi_clk", 60000000, 1);
376 if(ret)
377 {
378 dprintf(CRITICAL, "failed to set usb30_mock_utmi_clk ret = %d\n", ret);
379 ASSERT(0);
380 }
381
382 ret = clk_get_set_enable("usb30_sleep_clk", 0, 1);
383 if(ret)
384 {
385 dprintf(CRITICAL, "failed to set usb30_sleep_clk ret = %d\n", ret);
386 ASSERT(0);
387 }
388
389 ret = clk_get_set_enable("usb_phy_cfg_ahb2phy_clk", 0, 1);
390 if(ret)
391 {
392 dprintf(CRITICAL, "failed to enable usb_phy_cfg_ahb2phy_clk = %d\n", ret);
393 ASSERT(0);
394 }
395}
396
397void clock_bumpup_pipe3_clk()
398{
399 int ret = 0;
400
401 ret = clk_get_set_enable("usb30_pipe_clk", 0, 1);
402 if(ret)
403 {
404 dprintf(CRITICAL, "failed to set usb30_pipe_clk. ret = %d\n", ret);
405 ASSERT(0);
406 }
407
408 return;
409}
410