blob: db4113ed7d3a78f73b372ee8da9d459604bc0426 [file] [log] [blame]
Channagoud Kadabide6bab02015-01-21 10:39:46 -08001/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Channagoud Kadabied60a8b2014-06-27 15:35:09 -07002 *
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 <stdint.h>
30#include <debug.h>
31#include <reg.h>
32#include <mmc.h>
33#include <clock.h>
34#include <platform/timer.h>
35#include <platform/clock.h>
36#include <platform/iomap.h>
37#include <pm8x41.h>
38
39void clock_init_mmc(uint32_t interface)
40{
41 char clk_name[64];
42 int ret;
43
44 snprintf(clk_name, sizeof(clk_name), "sdc%u_iface_clk", interface);
45
46 /* enable interface clock */
47 ret = clk_get_set_enable(clk_name, 0, true);
48 if(ret)
49 {
50 dprintf(CRITICAL, "failed to set sdc%u_iface_clk ret = %d\n", interface, ret);
51 ASSERT(0);
52 }
53}
54
55/* Configure MMC clock */
56void clock_config_mmc(uint32_t interface, uint32_t freq)
57{
58 int ret = 0;
59 char clk_name[64];
60
61 snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
62
63 if(freq == MMC_CLK_400KHZ)
64 {
65 ret = clk_get_set_enable(clk_name, 400000, true);
66 }
67 else if(freq == MMC_CLK_50MHZ)
68 {
69 ret = clk_get_set_enable(clk_name, 50000000, true);
70 }
71 else if(freq == MMC_CLK_96MHZ)
72 {
Channagoud Kadabi99d23702015-02-02 20:52:17 -080073 ret = clk_get_set_enable(clk_name, 96000000, true);
Channagoud Kadabied60a8b2014-06-27 15:35:09 -070074 }
75 else if(freq == MMC_CLK_192MHZ)
76 {
77 ret = clk_get_set_enable(clk_name, 192000000, true);
78 }
Channagoud Kadabi99d23702015-02-02 20:52:17 -080079 else if(freq == MMC_CLK_400MHZ)
80 {
81 ret = clk_get_set_enable(clk_name, 384000000, 1);
82 }
Channagoud Kadabied60a8b2014-06-27 15:35:09 -070083 else
84 {
85 dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
86 ASSERT(0);
87 }
88
89 if(ret)
90 {
91 dprintf(CRITICAL, "failed to set sdc%u_core_clk ret = %d\n", interface, ret);
92 ASSERT(0);
93 }
94}
95
96/* Configure UART clock based on the UART block id*/
97void clock_config_uart_dm(uint8_t id)
98{
99 int ret;
100 char iclk[64];
101 char cclk[64];
102
103 snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
104 snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
105
106 ret = clk_get_set_enable(iclk, 0, true);
107 if(ret)
108 {
109 dprintf(CRITICAL, "failed to set uart%u_iface_clk ret = %d\n", id, ret);
110 ASSERT(0);
111 }
112
113 ret = clk_get_set_enable(cclk, 7372800, true);
114 if(ret)
115 {
116 dprintf(CRITICAL, "failed to set uart%u_core_clk ret = %d\n", id, ret);
117 ASSERT(0);
118 }
119}
120
121/* Function to asynchronously reset CE (Crypto Engine).
122 * Function assumes that all the CE clocks are off.
123 */
124static void ce_async_reset(uint8_t instance)
125{
Channagoud Kadabi037c8b82015-02-05 12:09:32 -0800126 if (instance == 1)
127 {
128 /* Start the block reset for CE */
129 writel(1, GCC_CE1_BCR);
130 udelay(2);
131 /* Take CE block out of reset */
132 writel(0, GCC_CE1_BCR);
133 udelay(2);
134 }
135 else
136 {
137 dprintf(CRITICAL, "Unsupported CE instance: %u\n", instance);
138 ASSERT(0);
139 }
Channagoud Kadabied60a8b2014-06-27 15:35:09 -0700140}
141
142void clock_ce_enable(uint8_t instance)
143{
144}
145
146void clock_ce_disable(uint8_t instance)
147{
148}
149
150void clock_config_ce(uint8_t instance)
151{
152 /* Need to enable the clock before disabling since the clk_disable()
153 * has a check to default to nop when the clk_enable() is not called
154 * on that particular clock.
155 */
156 clock_ce_enable(instance);
157
158 clock_ce_disable(instance);
159
160 ce_async_reset(instance);
161
162 clock_ce_enable(instance);
163
164}
165
166void clock_usb30_gdsc_enable(void)
167{
168 uint32_t reg = readl(GCC_USB30_GDSCR);
169
170 reg &= ~(0x1);
171
172 writel(reg, GCC_USB30_GDSCR);
173}
174
175/* enables usb30 clocks */
176void clock_usb30_init(void)
177{
178 int ret;
179
180 ret = clk_get_set_enable("usb30_iface_clk", 0, true);
181 if(ret)
182 {
183 dprintf(CRITICAL, "failed to set usb30_iface_clk. ret = %d\n", ret);
184 ASSERT(0);
185 }
186
187 clock_usb30_gdsc_enable();
188
Channagoud Kadabidf233d22015-02-11 11:56:48 -0800189 ret = clk_get_set_enable("usb30_master_clk", 150000000, true);
Channagoud Kadabied60a8b2014-06-27 15:35:09 -0700190 if(ret)
191 {
192 dprintf(CRITICAL, "failed to set usb30_master_clk. ret = %d\n", ret);
193 ASSERT(0);
194 }
195
Channagoud Kadabidf233d22015-02-11 11:56:48 -0800196 ret = clk_get_set_enable("gcc_aggre2_usb3_axi_clk", 150000000, true);
197 if (ret)
198 {
199 dprintf(CRITICAL, "failed to set aggre2_usb3_axi_clk, ret = %d\n", ret);
200 ASSERT(0);
201 }
202
Channagoud Kadabied60a8b2014-06-27 15:35:09 -0700203 ret = clk_get_set_enable("usb30_phy_aux_clk", 1200000, true);
204 if(ret)
205 {
206 dprintf(CRITICAL, "failed to set usb30_phy_aux_clk. ret = %d\n", ret);
207 ASSERT(0);
208 }
209
210 ret = clk_get_set_enable("usb30_mock_utmi_clk", 60000000, true);
211 if(ret)
212 {
213 dprintf(CRITICAL, "failed to set usb30_mock_utmi_clk ret = %d\n", ret);
214 ASSERT(0);
215 }
216
217 ret = clk_get_set_enable("usb30_sleep_clk", 0, true);
218 if(ret)
219 {
220 dprintf(CRITICAL, "failed to set usb30_sleep_clk ret = %d\n", ret);
221 ASSERT(0);
222 }
223
224 ret = clk_get_set_enable("usb_phy_cfg_ahb2phy_clk", 0, true);
225 if(ret)
226 {
227 dprintf(CRITICAL, "failed to enable usb_phy_cfg_ahb2phy_clk = %d\n", ret);
228 ASSERT(0);
229 }
Channagoud Kadabied60a8b2014-06-27 15:35:09 -0700230}
231
232void clock_bumpup_pipe3_clk()
233{
234 int ret = 0;
235
236 ret = clk_get_set_enable("usb30_pipe_clk", 0, true);
237 if(ret)
238 {
239 dprintf(CRITICAL, "failed to set usb30_pipe_clk. ret = %d\n", ret);
240 ASSERT(0);
241 }
242
243 return;
244}
245
246void clock_reset_usb_phy()
247{
248 int ret;
249
250 struct clk *phy_reset_clk = NULL;
251 struct clk *pipe_reset_clk = NULL;
Channagoud Kadabia42fb7d2015-06-24 12:50:01 -0700252 struct clk *master_clk = NULL;
253
254 master_clk = clk_get("usb30_master_clk");
255 ASSERT(master_clk);
Channagoud Kadabied60a8b2014-06-27 15:35:09 -0700256
257 /* Look if phy com clock is present */
258 phy_reset_clk = clk_get("usb30_phy_reset");
259 ASSERT(phy_reset_clk);
260
261 pipe_reset_clk = clk_get("usb30_pipe_clk");
262 ASSERT(pipe_reset_clk);
263
264 /* ASSERT */
Channagoud Kadabia42fb7d2015-06-24 12:50:01 -0700265 ret = clk_reset(master_clk, CLK_RESET_ASSERT);
266 if (ret)
267 {
268 dprintf(CRITICAL, "Failed to assert usb30_master_reset clk\n");
269 return;
270 }
Channagoud Kadabied60a8b2014-06-27 15:35:09 -0700271 ret = clk_reset(phy_reset_clk, CLK_RESET_ASSERT);
272
273 if (ret)
274 {
275 dprintf(CRITICAL, "Failed to assert usb30_phy_reset clk\n");
Channagoud Kadabia42fb7d2015-06-24 12:50:01 -0700276 goto deassert_master_clk;
Channagoud Kadabied60a8b2014-06-27 15:35:09 -0700277 }
278
279 ret = clk_reset(pipe_reset_clk, CLK_RESET_ASSERT);
280 if (ret)
281 {
282 dprintf(CRITICAL, "Failed to assert usb30_pipe_clk\n");
283 goto deassert_phy_clk;
284 }
285
286 udelay(100);
287
288 /* DEASSERT */
289 ret = clk_reset(pipe_reset_clk, CLK_RESET_DEASSERT);
290 if (ret)
291 {
292 dprintf(CRITICAL, "Failed to deassert usb_pipe_clk\n");
293 return;
294 }
295
296deassert_phy_clk:
297
298 ret = clk_reset(phy_reset_clk, CLK_RESET_DEASSERT);
299 if (ret)
300 {
301 dprintf(CRITICAL, "Failed to deassert usb30_phy_com_reset clk\n");
302 return;
303 }
Channagoud Kadabia42fb7d2015-06-24 12:50:01 -0700304deassert_master_clk:
305
306 ret = clk_reset(master_clk, CLK_RESET_DEASSERT);
307 if (ret)
308 {
309 dprintf(CRITICAL, "Failed to deassert usb30_master clk\n");
310 return;
311 }
312
Channagoud Kadabied60a8b2014-06-27 15:35:09 -0700313}
Dhaval Patel0f3cbeb2015-03-17 11:52:12 -0700314
315void mmss_gdsc_enable()
316{
317 uint32_t reg = 0;
318
319 reg = readl(MMAGIC_BIMC_GDSCR);
320 if (!(reg & GDSC_POWER_ON_BIT)) {
321 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
322 reg |= GDSC_EN_FEW_WAIT_256_MASK;
323 writel(reg, MMAGIC_BIMC_GDSCR);
324 while(!(readl(MMAGIC_BIMC_GDSCR) & (GDSC_POWER_ON_BIT)));
325 } else {
326 dprintf(SPEW, "MMAGIC BIMC GDSC already enabled\n");
327 }
328
329 reg = readl(MMAGIC_MDSS_GDSCR);
330 if (!(reg & GDSC_POWER_ON_BIT)) {
331 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
332 reg |= GDSC_EN_FEW_WAIT_256_MASK;
333 writel(reg, MMAGIC_MDSS_GDSCR);
334 while(!(readl(MMAGIC_MDSS_GDSCR) & (GDSC_POWER_ON_BIT)));
335 } else {
336 dprintf(SPEW, "MMAGIC MDSS GDSC already enabled\n");
337 }
338
339 reg = readl(MDSS_GDSCR);
340 if (!(reg & GDSC_POWER_ON_BIT)) {
341 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
342 reg |= GDSC_EN_FEW_WAIT_256_MASK;
343 writel(reg, MDSS_GDSCR);
344 while(!(readl(MDSS_GDSCR) & (GDSC_POWER_ON_BIT)));
345 } else {
346 dprintf(SPEW, "MDSS GDSC already enabled\n");
347 }
348}
349
350void mmss_gdsc_disable()
351{
352 uint32_t reg = 0;
353
354 reg = readl(MDSS_GDSCR);
355 reg |= BIT(0);
356 writel(reg, MDSS_GDSCR);
357 while(readl(MDSS_GDSCR) & (GDSC_POWER_ON_BIT));
358
359 reg = readl(MMAGIC_MDSS_GDSCR);
360 reg |= BIT(0);
361 writel(reg, MMAGIC_MDSS_GDSCR);
362 while(readl(MMAGIC_MDSS_GDSCR) & (GDSC_POWER_ON_BIT));
363
364 reg = readl(MMAGIC_BIMC_GDSCR);
365 reg |= BIT(0);
366 writel(reg, MMAGIC_BIMC_GDSCR);
367 while(readl(MMAGIC_BIMC_GDSCR) & (GDSC_POWER_ON_BIT));
368}
369
370void video_gdsc_enable()
371{
372 uint32_t reg = 0;
373
374 reg = readl(MMAGIC_VIDEO_GDSCR);
375 if (!(reg & GDSC_POWER_ON_BIT)) {
376 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
377 reg |= GDSC_EN_FEW_WAIT_256_MASK;
378 writel(reg, MMAGIC_VIDEO_GDSCR);
379 while(!(readl(MMAGIC_VIDEO_GDSCR) & (GDSC_POWER_ON_BIT)));
380 } else {
381 dprintf(SPEW, "VIDEO BIMC GDSC already enabled\n");
382 }
383
384 reg = readl(VIDEO_GDSCR);
385 if (!(reg & GDSC_POWER_ON_BIT)) {
386 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
387 reg |= GDSC_EN_FEW_WAIT_256_MASK;
388 writel(reg, VIDEO_GDSCR);
389 while(!(readl(VIDEO_GDSCR) & (GDSC_POWER_ON_BIT)));
390 } else {
391 dprintf(SPEW, "VIDEO GDSC already enabled\n");
392 }
393}
394
395void video_gdsc_disable()
396{
397 uint32_t reg = 0;
398
399 reg = readl(VIDEO_GDSCR);
400 reg |= BIT(0);
401 writel(reg, VIDEO_GDSCR);
402 while(readl(VIDEO_GDSCR) & (GDSC_POWER_ON_BIT));
403
404 reg = readl(MMAGIC_VIDEO_GDSCR);
405 reg |= BIT(0);
406 writel(reg, MMAGIC_VIDEO_GDSCR);
407 while(readl(MMAGIC_VIDEO_GDSCR) & (GDSC_POWER_ON_BIT));
408}
409
410/* Configure MDP clock */
411void mdp_clock_enable(void)
412{
413 int ret;
414
415 ret = clk_get_set_enable("mmss_mmagic_ahb_clk", 19200000, 1);
416 if(ret)
417 {
418 dprintf(CRITICAL, "failed to set mmagic_ahb_clk ret = %d\n", ret);
419 ASSERT(0);
420 }
421
422 ret = clk_get_set_enable("smmu_mdp_ahb_clk", 0, 1);
423 if(ret)
424 {
425 dprintf(CRITICAL, "failed to set smmu_mdp_ahb_clk ret = %d\n", ret);
426 ASSERT(0);
427 }
428
429 ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
430 if(ret)
431 {
432 dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
433 ASSERT(0);
434 }
435
436 ret = clk_get_set_enable("mdss_mdp_clk", 320000000, 1);
437 if(ret)
438 {
439 dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
440 ASSERT(0);
441 }
442
443 ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
444 if(ret)
445 {
446 dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
447 ASSERT(0);
448 }
449
450}
451
452void mdp_clock_disable()
453{
454 clk_disable(clk_get("mdss_vsync_clk"));
455 clk_disable(clk_get("mdss_mdp_clk"));
456 clk_disable(clk_get("mdp_ahb_clk"));
457 clk_disable(clk_get("smmu_mdp_ahb_clk"));
458 clk_disable(clk_get("mmss_mmagic_ahb_clk"));
459}
460
461void mmss_bus_clock_enable(void)
462{
463 int ret;
464 ret = clk_get_set_enable("mmss_mmagic_axi_clk", 320000000, 1);
465 if(ret)
466 {
467 dprintf(CRITICAL, "failed to set mmss_mmagic_axi_clk ret = %d\n", ret);
468 ASSERT(0);
469 }
470
471 ret = clk_get_set_enable("mmagic_bimc_axi_clk", 320000000, 1);
472 if(ret)
473 {
474 dprintf(CRITICAL, "failed to set mmss_s0_axi_clk ret = %d\n", ret);
475 ASSERT(0);
476 }
477
478 ret = clk_get_set_enable("mmss_s0_axi_clk", 320000000, 1);
479 if(ret)
480 {
481 dprintf(CRITICAL, "failed to set mmss_s0_axi_clk ret = %d\n", ret);
482 ASSERT(0);
483 }
484
485 ret = clk_get_set_enable("mmagic_mdss_axi_clk", 320000000, 1);
486 if(ret)
487 {
488 dprintf(CRITICAL, "failed to set mmss_mmagic_axi_clk ret = %d\n", ret);
489 ASSERT(0);
490 }
491
492 ret = clk_get_set_enable("smmu_mdp_axi_clk", 320000000, 1);
493 if(ret)
494 {
495 dprintf(CRITICAL, "failed to set smmu_mdp_axi_clk ret = %d\n", ret);
496 ASSERT(0);
497 }
498
499 ret = clk_get_set_enable("mdss_axi_clk", 320000000, 1);
500 if(ret)
501 {
502 dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
503 ASSERT(0);
504 }
505}
506
507void mmss_bus_clock_disable(void)
508{
509 clk_disable(clk_get("mdss_axi_clk"));
510 clk_disable(clk_get("smmu_mdp_axi_clk"));
511 clk_disable(clk_get("mmagic_mdss_axi_clk"));
512 clk_disable(clk_get("mmss_s0_axi_clk"));
513 clk_disable(clk_get("mmagic_bimc_axi_clk"));
514 clk_disable(clk_get("mmss_mmagic_axi_clk"));
515}
516
Aravind Venkateswaran9586be62015-05-20 00:51:06 -0700517void mmss_dsi_clock_enable(uint32_t cfg_rcgr, uint32_t flags)
Dhaval Patel0f3cbeb2015-03-17 11:52:12 -0700518{
519 int ret;
520
521 if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
522 /* Enable DSI0 branch clocks */
523
Aravind Venkateswaran9586be62015-05-20 00:51:06 -0700524 writel(cfg_rcgr, DSI_BYTE0_CFG_RCGR);
Dhaval Patel0f3cbeb2015-03-17 11:52:12 -0700525 writel(0x1, DSI_BYTE0_CMD_RCGR);
526 writel(0x1, DSI_BYTE0_CBCR);
527
Aravind Venkateswaran9586be62015-05-20 00:51:06 -0700528 writel(cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
Dhaval Patel0f3cbeb2015-03-17 11:52:12 -0700529 writel(0x1, DSI_PIXEL0_CMD_RCGR);
530 writel(0x1, DSI_PIXEL0_CBCR);
531
532 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
533 if(ret)
534 {
535 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
536 ASSERT(0);
537 }
538 }
539
540 if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
541 /* Enable DSI1 branch clocks */
Aravind Venkateswaran9586be62015-05-20 00:51:06 -0700542 writel(cfg_rcgr, DSI_BYTE1_CFG_RCGR);
Dhaval Patel0f3cbeb2015-03-17 11:52:12 -0700543 writel(0x1, DSI_BYTE1_CMD_RCGR);
544 writel(0x1, DSI_BYTE1_CBCR);
545
Aravind Venkateswaran9586be62015-05-20 00:51:06 -0700546 writel(cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
Dhaval Patel0f3cbeb2015-03-17 11:52:12 -0700547 writel(0x1, DSI_PIXEL1_CMD_RCGR);
548 writel(0x1, DSI_PIXEL1_CBCR);
549
550 ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
551 if(ret)
552 {
553 dprintf(CRITICAL, "failed to set esc1_clk ret = %d\n", ret);
554 ASSERT(0);
555 }
556 }
557}
558
559void mmss_dsi_clock_disable(uint32_t flags)
560{
561 if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
562 clk_disable(clk_get("mdss_esc0_clk"));
563 writel(0x0, DSI_BYTE0_CBCR);
564 writel(0x0, DSI_PIXEL0_CBCR);
565 }
566
567 if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
568 clk_disable(clk_get("mdss_esc1_clk"));
569 writel(0x0, DSI_BYTE1_CBCR);
570 writel(0x0, DSI_PIXEL1_CBCR);
571 }
572}