blob: 48e25acf81fd6a56ae36df9000ed926c35d57d9f [file] [log] [blame]
Baochu Xu6788fad2017-12-05 18:45:28 +08001/* Copyright (c) 2014-2015,2018, The Linux Foundation. All rights reserved.
Unnati Gandhib3820bc2014-07-04 16:56:27 +05302 *
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
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -070040#define MAX_LOOPS 500
41
Unnati Gandhib3820bc2014-07-04 16:56:27 +053042void hsusb_clock_init(void)
43{
Unnati Gandhi8e4711b2014-10-13 05:03:00 +053044 int ret;
45 struct clk *iclk, *cclk;
Unnati Gandhib3820bc2014-07-04 16:56:27 +053046
Unnati Gandhi8e4711b2014-10-13 05:03:00 +053047 ret = clk_get_set_enable("usb_iface_clk", 0, 1);
48 if(ret)
49 {
50 dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
51 ASSERT(0);
52 }
53
54 ret = clk_get_set_enable("usb_core_clk", 80000000, 1);
55 if(ret)
56 {
57 dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
58 ASSERT(0);
59 }
60
61 mdelay(20);
62
63 iclk = clk_get("usb_iface_clk");
64 cclk = clk_get("usb_core_clk");
65
66 clk_disable(iclk);
67 clk_disable(cclk);
68
69 mdelay(20);
70
71 /* Start the block reset for usb */
72 writel(1, USB_HS_BCR);
73
74 mdelay(20);
75
76 /* Take usb block out of reset */
77 writel(0, USB_HS_BCR);
78
79 mdelay(20);
80
81 ret = clk_enable(iclk);
82
83 if(ret)
84 {
85 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
86 ASSERT(0);
87 }
88
89 ret = clk_enable(cclk);
90
91 if(ret)
92 {
93 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
94 ASSERT(0);
95 }
Unnati Gandhib3820bc2014-07-04 16:56:27 +053096}
97
98void clock_init_mmc(uint32_t interface)
99{
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530100 char clk_name[64];
101 int ret;
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530102
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530103 snprintf(clk_name, sizeof(clk_name), "sdc%u_iface_clk", interface);
104
105 /* enable interface clock */
106 ret = clk_get_set_enable(clk_name, 0, 1);
107 if(ret)
108 {
109 dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret);
110 ASSERT(0);
111 }
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530112}
113
114/* Configure MMC clock */
115void clock_config_mmc(uint32_t interface, uint32_t freq)
116{
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530117 int ret;
118 char clk_name[64];
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530119
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530120 snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
121
122 if(freq == MMC_CLK_400KHZ)
123 {
124 ret = clk_get_set_enable(clk_name, 400000, 1);
125 }
126 else if(freq == MMC_CLK_50MHZ)
127 {
128 ret = clk_get_set_enable(clk_name, 50000000, 1);
129 }
130 else if(freq == MMC_CLK_200MHZ)
131 {
132 ret = clk_get_set_enable(clk_name, 200000000, 1);
133 }
134 else if(freq == MMC_CLK_177MHZ)
135 {
136 ret = clk_get_set_enable(clk_name, 177770000, 1);
137 }
138 else
139 {
140 dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
141 ASSERT(0);
142 }
143
144 if(ret)
145 {
146 dprintf(CRITICAL, "failed to set %s ret = %d\n", clk_name, ret);
147 ASSERT(0);
148 }
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530149}
150
151/* Configure UART clock based on the UART block id*/
152void clock_config_uart_dm(uint8_t id)
153{
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530154 int ret;
155 char iclk[64];
156 char cclk[64];
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530157
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530158 snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
159 snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
160
161 ret = clk_get_set_enable(iclk, 0, 1);
162 if(ret)
163 {
164 dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret);
165 ASSERT(0);
166 }
167
168 ret = clk_get_set_enable(cclk, 7372800, 1);
169 if(ret)
170 {
171 dprintf(CRITICAL, "failed to set %s ret = %d\n", cclk, ret);
172 ASSERT(0);
173 }
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530174}
175
176/* Function to asynchronously reset CE.
177 * Function assumes that all the CE clocks are off.
178 */
179static void ce_async_reset(uint8_t instance)
180{
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530181 /* Start the block reset for CE */
182 writel(1, GCC_CRYPTO_BCR);
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530183
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530184 udelay(2);
185
186 /* Take CE block out of reset */
187 writel(0, GCC_CRYPTO_BCR);
188
189 udelay(2);
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530190}
191
192void clock_ce_enable(uint8_t instance)
193{
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530194 int ret;
195 char clk_name[64];
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530196
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530197 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
198 ret = clk_get_set_enable(clk_name, 160000000, 1);
199 if(ret)
200 {
201 dprintf(CRITICAL, "failed to set ce%u_src_clk ret = %d\n", instance, ret);
202 ASSERT(0);
203 }
204
205 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
206 ret = clk_get_set_enable(clk_name, 0, 1);
207 if(ret)
208 {
209 dprintf(CRITICAL, "failed to set ce%u_core_clk ret = %d\n", instance, ret);
210 ASSERT(0);
211 }
212
213 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
214 ret = clk_get_set_enable(clk_name, 0, 1);
215 if(ret)
216 {
217 dprintf(CRITICAL, "failed to set ce%u_ahb_clk ret = %d\n", instance, ret);
218 ASSERT(0);
219 }
220
221 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
222 ret = clk_get_set_enable(clk_name, 0, 1);
223 if(ret)
224 {
225 dprintf(CRITICAL, "failed to set ce%u_axi_clk ret = %d\n", instance, ret);
226 ASSERT(0);
227 }
228
229 /* Wait for 48 * #pipes cycles.
230 * This is necessary as immediately after an access control reset (boot up)
231 * or a debug re-enable, the Crypto core sequentially clears its internal
232 * pipe key storage memory. If pipe key initialization writes are attempted
233 * during this time, they may be overwritten by the internal clearing logic.
234 */
235 udelay(1);
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530236}
237
238void clock_ce_disable(uint8_t instance)
239{
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530240 struct clk *ahb_clk;
241 struct clk *cclk;
242 struct clk *axi_clk;
243 struct clk *src_clk;
244 char clk_name[64];
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530245
Unnati Gandhi8e4711b2014-10-13 05:03:00 +0530246 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
247 src_clk = clk_get(clk_name);
248
249 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
250 ahb_clk = clk_get(clk_name);
251
252 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
253 axi_clk = clk_get(clk_name);
254
255 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
256 cclk = clk_get(clk_name);
257
258 clk_disable(ahb_clk);
259 clk_disable(axi_clk);
260 clk_disable(cclk);
261 clk_disable(src_clk);
262
263 /* Some delay for the clocks to stabalize. */
264 udelay(1);
Unnati Gandhib3820bc2014-07-04 16:56:27 +0530265}
266
267void clock_config_ce(uint8_t instance)
268{
269 /* Need to enable the clock before disabling since the clk_disable()
270 * has a check to default to nop when the clk_enable() is not called
271 * on that particular clock.
272 */
273 clock_ce_enable(instance);
274
275 clock_ce_disable(instance);
276
277 ce_async_reset(instance);
278
279 clock_ce_enable(instance);
280}
Shivaraj Shetty720fd6b2014-10-30 19:15:26 +0530281
282/* Control the MDSS GDSC */
283void mdp_gdsc_ctrl(uint8_t enable)
284{
285 uint32_t reg = 0;
286 reg = readl(MDP_GDSCR);
287 if (enable) {
288 if (!(reg & GDSC_POWER_ON_BIT)) {
289 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
290 reg |= GDSC_EN_FEW_WAIT_256_MASK;
291 writel(reg, MDP_GDSCR);
292 while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)));
293 } else {
294 dprintf(SPEW, "MDP GDSC already enabled\n");
295 }
296 } else {
297 reg |= BIT(0);
298 writel(reg, MDP_GDSCR);
299 while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT));
300 }
301}
302
303/* Enable all the MDP branch clocks */
304void mdp_clock_enable(void)
305{
306 int ret;
307
308 ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
309 if (ret) {
310 dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
311 ASSERT(0);
312 }
313
314 /* Set MDP clock to 160MHz */
315 ret = clk_get_set_enable("mdss_mdp_clk_src", 160000000, 1);
316 if (ret) {
317 dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
318 ASSERT(0);
319 }
320
321 ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
322 if (ret) {
323 dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
324 ASSERT(0);
325 }
326
327 ret = clk_get_set_enable("mdss_mdp_clk", 0, 1);
328 if (ret) {
329 dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret);
330 ASSERT(0);
331 }
332}
333
334/* Disable all the MDP branch clocks */
335void mdp_clock_disable(void)
336{
337 clk_disable(clk_get("mdss_vsync_clk"));
338 clk_disable(clk_get("mdss_mdp_clk"));
339 clk_disable(clk_get("mdss_mdp_clk_src"));
340 clk_disable(clk_get("mdp_ahb_clk"));
341}
342
343/* Disable all the bus clocks needed by MDSS */
344void mdss_bus_clocks_disable(void)
345{
346 /* Disable MDSS AXI clock */
347 clk_disable(clk_get("mdss_axi_clk"));
348}
349
350/* Enable all the bus clocks needed by MDSS */
351void mdss_bus_clocks_enable(void)
352{
353 int ret;
354
355 /* Configure AXI clock */
356 ret = clk_get_set_enable("mdss_axi_clk", 0, 1);
357 if (ret) {
358 dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
359 ASSERT(0);
360 }
361}
362
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -0700363static void rcg_update_config(uint32_t reg)
364{
365 int i;
366
367 for (i = 0; i < MAX_LOOPS; i++) {
368 if (!(readl(reg) & BIT(0)))
369 return;
370 udelay(1);
371 }
372
373 dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
374 ASSERT(0);
375}
376
377static void branch_clk_halt_check(uint32_t reg)
378{
379 int i;
380
381 for (i = 0; i < MAX_LOOPS; i++) {
382 if (!(readl(reg) & BIT(31)))
383 return;
384 udelay(1);
385 }
386
387 dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
388 ASSERT(0);
389}
390
Shivaraj Shetty720fd6b2014-10-30 19:15:26 +0530391/* Disable all the branch clocks needed by the DSI controller */
392void gcc_dsi_clocks_disable(void)
393{
394 clk_disable(clk_get("mdss_esc0_clk"));
395 writel(0x0, DSI_PIXEL0_CBCR);
396 writel(0x0, DSI_BYTE0_CBCR);
397}
398
399/* Configure all the branch clocks needed by the DSI controller */
400void gcc_dsi_clocks_enable(uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
401{
402 int ret;
403
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -0700404 /*
405 * Configure Byte clock -autopll- This will not change becasue
406 * byte clock does not need any divider
407 */
408 /* Set the source for DSI0 byte RCG */
Shivaraj Shetty720fd6b2014-10-30 19:15:26 +0530409 writel(0x100, DSI_BYTE0_CFG_RCGR);
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -0700410 /* Set the update RCG bit */
Shivaraj Shetty720fd6b2014-10-30 19:15:26 +0530411 writel(0x1, DSI_BYTE0_CMD_RCGR);
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -0700412 rcg_update_config(DSI_BYTE0_CMD_RCGR);
413 /* Enable the branch clock */
Shivaraj Shetty720fd6b2014-10-30 19:15:26 +0530414 writel(0x1, DSI_BYTE0_CBCR);
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -0700415 branch_clk_halt_check(DSI_BYTE0_CBCR);
Shivaraj Shetty720fd6b2014-10-30 19:15:26 +0530416
417 /* Configure Pixel clock */
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -0700418 /* Set the source for DSI0 pixel RCG */
Shivaraj Shetty720fd6b2014-10-30 19:15:26 +0530419 writel(0x100, DSI_PIXEL0_CFG_RCGR);
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -0700420 /* Set the MND for DSI0 pixel clock */
Shivaraj Shetty720fd6b2014-10-30 19:15:26 +0530421 writel(pclk0_m, DSI_PIXEL0_M);
422 writel(pclk0_n, DSI_PIXEL0_N);
423 writel(pclk0_d, DSI_PIXEL0_D);
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -0700424 /* Set the update RCG bit */
425 writel(0x1, DSI_PIXEL0_CMD_RCGR);
426 rcg_update_config(DSI_PIXEL0_CMD_RCGR);
427 /* Enable the branch clock */
428 writel(0x1, DSI_PIXEL0_CBCR);
429 branch_clk_halt_check(DSI_PIXEL0_CBCR);
Shivaraj Shetty720fd6b2014-10-30 19:15:26 +0530430
431 /* Configure ESC clock */
432 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
433 if (ret) {
434 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
435 ASSERT(0);
436 }
437}
Unnati Gandhi88cf23b2014-12-10 15:39:12 +0530438
439void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
440{
441 uint8_t ret = 0;
442 char clk_name[64];
443
444 struct clk *qup_clk;
445 qup_id = qup_id + 1;
446
447 if((blsp_id != BLSP_ID_1)) {
448 dprintf(CRITICAL, "Incorrect BLSP-%d configuration\n", blsp_id);
449 ASSERT(0);
450 }
451
452 snprintf(clk_name, sizeof(clk_name), "blsp1_qup%u_ahb_iface_clk", qup_id);
453
454 ret = clk_get_set_enable(clk_name, 0 , 1);
455
456 if (ret) {
457 dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name);
458 return;
459 }
460
461 snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup%u_i2c_apps_clk", qup_id);
462
463 qup_clk = clk_get(clk_name);
464
465 if (!qup_clk) {
466 dprintf(CRITICAL, "Failed to get %s\n", clk_name);
467 return;
468 }
469
470 ret = clk_enable(qup_clk);
471
472 if (ret) {
473 dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
474 return;
475 }
476}
Baochu Xu6788fad2017-12-05 18:45:28 +0800477
478/* Configure spi clock */
479void clock_config_blsp_spi(uint8_t blsp_id, uint8_t qup_id)
480{
481 uint8_t ret = 0;
482 char clk_name[64];
483
484 struct clk *qup_clk;
485 qup_id = qup_id + 1;
486
487 if((blsp_id != BLSP_ID_1)) {
488 dprintf(CRITICAL, "Incorrect BLSP-%d configuration\n", blsp_id);
489 ASSERT(0);
490 }
491
492 snprintf(clk_name, sizeof(clk_name), "blsp1_ahb_iface_clk");
493
494 ret = clk_get_set_enable(clk_name, 0 , 1);
495
496 if (ret) {
497 dprintf(CRITICAL, "%s: Failed to enable %s clock\n", __func__, clk_name);
498 return;
499 }
500
501 snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup%u_spi_apps_clk", qup_id);
502
503 /* Set the highest clk frequency by default for good performance. */
504 ret = clk_get_set_enable(clk_name, 50000000, 1);
505
506 if (ret) {
507 dprintf(CRITICAL, "%s: Failed to enable %s\n", __func__, clk_name);
508 return;
509 }
510}