blob: 6b72ac9f285291a600c0ecf5d1aba8bd836c0ef9 [file] [log] [blame]
Jayant Shekhare1c955f2016-01-14 14:33:46 +05301/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +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#include <err.h>
29#include <assert.h>
30#include <debug.h>
31#include <reg.h>
32#include <platform/timer.h>
33#include <platform/iomap.h>
34#include <mmc.h>
35#include <clock.h>
36#include <platform/clock.h>
37#include <platform.h>
38
39#define MAX_LOOPS 500
40
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +053041/*
42 * Disable power collapse using GDSCR:
43 * Globally Distributed Switch Controller Register
44 */
45void clock_usb30_gdsc_enable(void)
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +053046{
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +053047 uint32_t reg = readl(GCC_USB30_GDSCR);
48
49 reg &= ~(0x1);
50
51 writel(reg, GCC_USB30_GDSCR);
52}
53
54/* enables usb30 clocks */
55void clock_usb30_init(void)
56{
57 int ret;
58
59 ret = clk_get_set_enable("usb30_iface_clk", 0, 1);
60 if(ret)
61 {
62 dprintf(CRITICAL, "failed to set usb30_iface_clk. ret = %d\n", ret);
63 ASSERT(0);
64 }
65
66 clock_usb30_gdsc_enable();
67
68 ret = clk_get_set_enable("usb30_master_clk", 133330000, 1);
69 if(ret)
70 {
71 dprintf(CRITICAL, "failed to set usb30_master_clk. ret = %d\n", ret);
72 ASSERT(0);
73 }
74 ret = clk_get_set_enable("usb30_pipe_clk", 0, 1);
75 if(ret)
76 {
77 dprintf(CRITICAL, "failed to set usb30_pipe_clk. ret = %d\n", ret);
78 ASSERT(0);
79 }
80
81 ret = clk_get_set_enable("usb30_aux_clk", 19200000, 1);
82 if(ret)
83 {
84 dprintf(CRITICAL, "failed to set usb30_aux_clk. ret = %d\n", ret);
85 ASSERT(0);
86 }
87
88 ret = clk_get_set_enable("usb30_mock_utmi_clk", 60000000, 1);
89 if(ret)
90 {
91 dprintf(CRITICAL, "failed to set usb30_mock_utmi_clk ret = %d\n", ret);
92 ASSERT(0);
93 }
94
95 ret = clk_get_set_enable("usb30_sleep_clk", 0, 1);
96 if(ret)
97 {
98 dprintf(CRITICAL, "failed to set usb30_sleep_clk ret = %d\n", ret);
99 ASSERT(0);
100 }
101
102 ret = clk_get_set_enable("usb_phy_cfg_ahb_clk", 0, 1);
103 if(ret)
104 {
105 dprintf(CRITICAL, "failed to set usb_phy_cfg_ahb_clk ret = %d\n", ret);
106 ASSERT(0);
107 }
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530108}
109
110void clock_init_mmc(uint32_t interface)
111{
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +0530112 char clk_name[64];
113 int ret;
114
115 snprintf(clk_name, sizeof(clk_name), "sdc%u_iface_clk", interface);
116
117 /* enable interface clock */
118 ret = clk_get_set_enable(clk_name, 0, 1);
119 if(ret)
120 {
121 dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret);
122 ASSERT(0);
123 }
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530124}
125
126/* Configure MMC clock */
127void clock_config_mmc(uint32_t interface, uint32_t freq)
128{
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +0530129 int ret = 1;
P.V. Phani Kumar40fa1352015-08-13 18:15:03 +0530130 char clk_name[64];
131
132 snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +0530133
134 if(freq == MMC_CLK_400KHZ)
135 {
136 ret = clk_get_set_enable(clk_name, 400000, 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_177MHZ)
143 {
144 ret = clk_get_set_enable(clk_name, 177770000, 1);
145 }
146 else if(freq == MMC_CLK_192MHZ)
147 {
148 ret = clk_get_set_enable(clk_name, 192000000, 1);
149 }
150 else if(freq == MMC_CLK_200MHZ)
151 {
152 ret = clk_get_set_enable(clk_name, 200000000, 1);
153 }
154 else if(freq == MMC_CLK_400MHZ)
155 {
156 ret = clk_get_set_enable(clk_name, 384000000, 1);
157 }
158 else
159 {
160 dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
161 ASSERT(0);
162 }
163
164 if(ret)
165 {
166 dprintf(CRITICAL, "failed to set %s ret = %d\n", clk_name, ret);
167 ASSERT(0);
168 }
169}
170
171void clock_bumpup_pipe3_clk()
172{
173 int ret =0;
174 ret = clk_get_set_enable("usb30_pipe_clk", 0, true);
175
176 if(ret)
177 {
178 dprintf(CRITICAL, "failed to set usb30_pipe_clk. ret = %d\n", ret);
179 ASSERT(0);
180 }
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530181}
182
183/* Configure UART clock based on the UART block id*/
184void clock_config_uart_dm(uint8_t id)
185{
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +0530186 int ret;
187 char iclk[64];
188 char cclk[64];
189
190 snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
191 snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
192
193 ret = clk_get_set_enable(iclk, 0, 1);
194 if(ret)
195 {
196 dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret);
197 ASSERT(0);
198 }
199
200 ret = clk_get_set_enable(cclk, 7372800, 1);
201 if(ret)
202 {
203 dprintf(CRITICAL, "failed to set %s ret = %d\n", cclk, ret);
204 ASSERT(0);
205 }
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530206}
207
Jayant Shekhare1c955f2016-01-14 14:33:46 +0530208/* Control the MDSS GDSC */
209void mdp_gdsc_ctrl(uint8_t enable)
210{
211 uint32_t reg = 0;
212 reg = readl(MDP_GDSCR);
213 if (enable) {
214 if (!(reg & GDSC_POWER_ON_BIT)) {
215 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
216 reg |= GDSC_EN_FEW_WAIT_256_MASK;
217 writel(reg, MDP_GDSCR);
218 while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)));
219 } else {
220 dprintf(SPEW, "MDP GDSC already enabled\n");
221 }
222 } else {
223 reg |= BIT(0);
224 writel(reg, MDP_GDSCR);
225 while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT));
226 }
227}
228
229/* Enable all the MDP branch clocks */
230void mdp_clock_enable(void)
231{
232 int ret;
233
234 ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
235 if(ret)
236 {
237 dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
238 ASSERT(0);
239 }
240
241 /* Set MDP clock to 320MHz */
242 ret = clk_get_set_enable("mdss_mdp_clk_src", 320000000, 1);
243
244 if(ret)
245 {
246 dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
247 ASSERT(0);
248 }
249
250 ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
251 if(ret)
252 {
253 dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
254 ASSERT(0);
255 }
256
257 ret = clk_get_set_enable("mdss_mdp_clk", 0, 1);
258 if(ret)
259 {
260 dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret);
261 ASSERT(0);
262 }
263}
264
265/* Disable all the MDP branch clocks */
266void mdp_clock_disable(void)
267{
268 clk_disable(clk_get("mdss_vsync_clk"));
269 clk_disable(clk_get("mdss_mdp_clk"));
270 clk_disable(clk_get("mdss_mdp_clk_src"));
271 clk_disable(clk_get("mdp_ahb_clk"));
272}
273
274/* Disable all the bus clocks needed by MDSS */
275void mdss_bus_clocks_disable(void)
276{
277 /* Disable MDSS AXI clock */
278 clk_disable(clk_get("mdss_axi_clk"));
279}
280
281/* Enable all the bus clocks needed by MDSS */
282void mdss_bus_clocks_enable(void)
283{
284 int ret;
285
286 /* Configure AXI clock */
287 ret = clk_get_set_enable("mdss_axi_clk", 0, 1);
288 if(ret)
289 {
290 dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
291 ASSERT(0);
292 }
293}
294
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530295/* Function to asynchronously reset CE.
296 * Function assumes that all the CE clocks are off.
297 */
298static void ce_async_reset(uint8_t instance)
299{
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +0530300 /* Start the block reset for CE */
301 writel(1, GCC_CRYPTO_BCR);
302
303 udelay(2);
304
305 /* Take CE block out of reset */
306 writel(0, GCC_CRYPTO_BCR);
307
308 udelay(2);
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530309}
310
311void clock_ce_enable(uint8_t instance)
312{
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +0530313 int ret;
314 char clk_name[64];
315
316 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
317 ret = clk_get_set_enable(clk_name, 160000000, 1);
318 if(ret)
319 {
320 dprintf(CRITICAL, "failed to set ce%u_src_clk ret = %d\n", instance, ret);
321 ASSERT(0);
322 }
323
324 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
325 ret = clk_get_set_enable(clk_name, 0, 1);
326 if(ret)
327 {
328 dprintf(CRITICAL, "failed to set ce%u_core_clk ret = %d\n", instance, ret);
329 ASSERT(0);
330 }
331
332 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
333 ret = clk_get_set_enable(clk_name, 0, 1);
334 if(ret)
335 {
336 dprintf(CRITICAL, "failed to set ce%u_ahb_clk ret = %d\n", instance, ret);
337 ASSERT(0);
338 }
339
340 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
341 ret = clk_get_set_enable(clk_name, 0, 1);
342 if(ret)
343 {
344 dprintf(CRITICAL, "failed to set ce%u_axi_clk ret = %d\n", instance, ret);
345 ASSERT(0);
346 }
347
348 /* Wait for 48 * #pipes cycles.
349 * This is necessary as immediately after an access control reset (boot up)
350 * or a debug re-enable, the Crypto core sequentially clears its internal
351 * pipe key storage memory. If pipe key initialization writes are attempted
352 * during this time, they may be overwritten by the internal clearing logic.
353 */
354 udelay(1);
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530355}
356
357void clock_ce_disable(uint8_t instance)
358{
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +0530359 struct clk *ahb_clk;
360 struct clk *cclk;
361 struct clk *axi_clk;
362 struct clk *src_clk;
363 char clk_name[64];
364
365 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
366 src_clk = clk_get(clk_name);
367
368 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
369 ahb_clk = clk_get(clk_name);
370
371 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
372 axi_clk = clk_get(clk_name);
373
374 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
375 cclk = clk_get(clk_name);
376
377 clk_disable(ahb_clk);
378 clk_disable(axi_clk);
379 clk_disable(cclk);
380 clk_disable(src_clk);
381
382 /* Some delay for the clocks to stabalize. */
383 udelay(1);
Aparna Mallavarapu01fc00a2015-06-01 20:37:05 +0530384}
385
386void clock_config_ce(uint8_t instance)
387{
388 /* Need to enable the clock before disabling since the clk_disable()
389 * has a check to default to nop when the clk_enable() is not called
390 * on that particular clock.
391 */
392 clock_ce_enable(instance);
393
394 clock_ce_disable(instance);
395
396 ce_async_reset(instance);
397
398 clock_ce_enable(instance);
399}
P.V. Phani Kumar9451ebe2015-12-26 16:31:18 +0530400
401
402void clock_reset_usb_phy()
403{
404 int ret;
405
406 struct clk *phy_reset_clk = NULL;
407 struct clk *pipe_reset_clk = NULL;
408 struct clk *master_clk = NULL;
409
410 master_clk = clk_get("usb30_master_clk");
411 ASSERT(master_clk);
412
413 /* Look if phy com clock is present */
414 phy_reset_clk = clk_get("usb30_phy_reset");
415 ASSERT(phy_reset_clk);
416
417 pipe_reset_clk = clk_get("usb30_pipe_clk");
418 ASSERT(pipe_reset_clk);
419
420 /* ASSERT */
421 ret = clk_reset(master_clk, CLK_RESET_ASSERT);
422 if (ret)
423 {
424 dprintf(CRITICAL, "Failed to assert usb30_master_reset clk\n");
425 return;
426 }
427 ret = clk_reset(phy_reset_clk, CLK_RESET_ASSERT);
428
429 if (ret)
430 {
431 dprintf(CRITICAL, "Failed to assert usb30_phy_reset clk\n");
432 goto deassert_master_clk;
433 }
434
435 ret = clk_reset(pipe_reset_clk, CLK_RESET_ASSERT);
436 if (ret)
437 {
438 dprintf(CRITICAL, "Failed to assert usb30_pipe_clk\n");
439 goto deassert_phy_clk;
440 }
441
442 udelay(100);
443
444 /* DEASSERT */
445 ret = clk_reset(pipe_reset_clk, CLK_RESET_DEASSERT);
446 if (ret)
447 {
448 dprintf(CRITICAL, "Failed to deassert usb_pipe_clk\n");
449 return;
450 }
451
452deassert_phy_clk:
453
454 ret = clk_reset(phy_reset_clk, CLK_RESET_DEASSERT);
455 if (ret)
456 {
457 dprintf(CRITICAL, "Failed to deassert usb30_phy_com_reset clk\n");
458 return;
459 }
460
461deassert_master_clk:
462
463 ret = clk_reset(master_clk, CLK_RESET_DEASSERT);
464 if (ret)
465 {
466 dprintf(CRITICAL, "Failed to deassert usb30_master clk\n");
467 return;
468 }
469}
Jayant Shekhare1c955f2016-01-14 14:33:46 +0530470
471static void rcg_update_config(uint32_t reg)
472{
473 int i;
474
475 for (i = 0; i < MAX_LOOPS; i++) {
476 if (!(readl(reg) & BIT(0)))
477 return;
478 udelay(1);
479 }
480
481 dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
482 ASSERT(0);
483}
484
485static void branch_clk_halt_check(uint32_t reg)
486{
487 int i;
488
489 for (i = 0; i < MAX_LOOPS; i++) {
490 if (!(readl(reg) & BIT(31)))
491 return;
492 udelay(1);
493 }
494
495 dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
496 ASSERT(0);
497}
498
499void mmss_dsi_clock_enable(uint32_t cfg_rcgr, uint32_t flags,
500 uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
501{
502 int ret;
503
504 if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
505 /* Enable DSI0 branch clocks */
506
507 writel(cfg_rcgr, DSI_BYTE0_CFG_RCGR);
508 writel(0x1, DSI_BYTE0_CMD_RCGR);
509 rcg_update_config(DSI_BYTE0_CMD_RCGR);
510 writel(0x1, DSI_BYTE0_CBCR);
511 branch_clk_halt_check(DSI_BYTE0_CBCR);
512
513 writel(cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
514 writel(pclk0_m, DSI_PIXEL0_M);
515 writel(pclk0_n, DSI_PIXEL0_N);
516 writel(pclk0_d, DSI_PIXEL0_D);
517 writel(0x1, DSI_PIXEL0_CMD_RCGR);
518 rcg_update_config(DSI_PIXEL0_CMD_RCGR);
519 writel(0x1, DSI_PIXEL0_CBCR);
520 branch_clk_halt_check(DSI_PIXEL0_CBCR);
521
522 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
523 if(ret)
524 {
525 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
526 ASSERT(0);
527 }
528 }
529
530 if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
531 /* Enable DSI1 branch clocks */
532 writel(cfg_rcgr, DSI_BYTE1_CFG_RCGR);
533 writel(0x1, DSI_BYTE1_CMD_RCGR);
534 rcg_update_config(DSI_BYTE1_CMD_RCGR);
535 writel(0x1, DSI_BYTE1_CBCR);
536 branch_clk_halt_check(DSI_BYTE1_CBCR);
537
538 writel(cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
539 writel(pclk0_m, DSI_PIXEL1_M);
540 writel(pclk0_n, DSI_PIXEL1_N);
541 writel(pclk0_d, DSI_PIXEL1_D);
542 writel(0x1, DSI_PIXEL1_CMD_RCGR);
543 rcg_update_config(DSI_PIXEL1_CMD_RCGR);
544 writel(0x1, DSI_PIXEL1_CBCR);
545 branch_clk_halt_check(DSI_PIXEL1_CBCR);
546
547 ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
548 if(ret)
549 {
550 dprintf(CRITICAL, "failed to set esc1_clk ret = %d\n", ret);
551 ASSERT(0);
552 }
553 }
554}
555
556void mmss_dsi_clock_disable(uint32_t flags)
557{
558 if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
559 clk_disable(clk_get("mdss_esc0_clk"));
560 writel(0x0, DSI_BYTE0_CBCR);
561 writel(0x0, DSI_PIXEL0_CBCR);
562 }
563
564 if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
565 clk_disable(clk_get("mdss_esc1_clk"));
566 writel(0x0, DSI_BYTE1_CBCR);
567 writel(0x0, DSI_PIXEL1_CBCR);
568 }
569}