blob: 9efe09b4f1ffd06f4ca8315f6e0f06f94bee3fe7 [file] [log] [blame]
lijuang0d955da2019-04-02 15:58:29 +08001/* Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved.
Aparna Mallavarapuca676882015-01-19 20:39:06 +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
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -070039#define MAX_LOOPS 500
40
Aparna Mallavarapuca676882015-01-19 20:39:06 +053041void hsusb_clock_init(void)
42{
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +053043 int ret;
44 struct clk *iclk, *cclk;
Aparna Mallavarapuca676882015-01-19 20:39:06 +053045
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +053046 ret = clk_get_set_enable("usb_iface_clk", 0, 1);
47 if(ret)
48 {
49 dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
50 ASSERT(0);
51 }
52
Aparna Mallavarapuf47a8682015-04-20 13:22:08 +053053 ret = clk_get_set_enable("usb_core_clk", 133330000, 1);
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +053054 if(ret)
55 {
56 dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
57 ASSERT(0);
58 }
59
60 mdelay(20);
61
62 iclk = clk_get("usb_iface_clk");
63 cclk = clk_get("usb_core_clk");
64
65 clk_disable(iclk);
66 clk_disable(cclk);
67
68 mdelay(20);
69
70 /* Start the block reset for usb */
71 writel(1, USB_HS_BCR);
72
73 mdelay(20);
74
75 /* Take usb block out of reset */
76 writel(0, USB_HS_BCR);
77
78 mdelay(20);
79
80 ret = clk_enable(iclk);
81
82 if(ret)
83 {
84 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
85 ASSERT(0);
86 }
87
88 ret = clk_enable(cclk);
89
90 if(ret)
91 {
92 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
93 ASSERT(0);
94 }
Aparna Mallavarapuca676882015-01-19 20:39:06 +053095}
96
97void clock_init_mmc(uint32_t interface)
98{
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +053099 char clk_name[64];
100 int ret;
Aparna Mallavarapuca676882015-01-19 20:39:06 +0530101
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +0530102 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 }
Aparna Mallavarapuca676882015-01-19 20:39:06 +0530111}
112
113/* Configure MMC clock */
114void clock_config_mmc(uint32_t interface, uint32_t freq)
115{
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +0530116 int ret = 1;
117 char clk_name[64];
118
119 snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
120
121 if(freq == MMC_CLK_400KHZ)
122 {
123 ret = clk_get_set_enable(clk_name, 400000, 1);
124 }
125 else if(freq == MMC_CLK_50MHZ)
126 {
127 ret = clk_get_set_enable(clk_name, 50000000, 1);
128 }
129 else if(freq == MMC_CLK_177MHZ)
130 {
131 ret = clk_get_set_enable(clk_name, 177770000, 1);
132 }
133 else if(freq == MMC_CLK_192MHZ)
134 {
vijay kumara0a74722015-09-04 15:45:49 +0530135 if (platform_is_msm8956() && platform_is_msm8976_v_1_1())
136
137 ret = clk_get_set_enable(clk_name, 186400000, 1);
138 else
139
140 ret = clk_get_set_enable(clk_name, 192000000, 1);
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +0530141 }
142 else if(freq == MMC_CLK_200MHZ)
143 {
144 ret = clk_get_set_enable(clk_name, 200000000, 1);
145 }
146 else if(freq == MMC_CLK_400MHZ)
147 {
vijay kumara0a74722015-09-04 15:45:49 +0530148 if (platform_is_msm8956() && platform_is_msm8976_v_1_1())
149
150 ret = clk_get_set_enable(clk_name, 372800000, 1);
151 else
152
153 ret = clk_get_set_enable(clk_name, 384000000, 1);
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +0530154 }
155 else
156 {
157 dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
158 ASSERT(0);
159 }
160
161 if(ret)
162 {
163 dprintf(CRITICAL, "failed to set %s ret = %d\n", clk_name, ret);
164 ASSERT(0);
165 }
Aparna Mallavarapuca676882015-01-19 20:39:06 +0530166}
167
168/* Configure UART clock based on the UART block id*/
169void clock_config_uart_dm(uint8_t id)
170{
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +0530171 int ret;
172 char iclk[64];
173 char cclk[64];
Aparna Mallavarapuca676882015-01-19 20:39:06 +0530174
Aparna Mallavarapu7b638e62015-03-26 05:51:57 +0530175 snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
176 snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
177
178 ret = clk_get_set_enable(iclk, 0, 1);
179 if(ret)
180 {
181 dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret);
182 ASSERT(0);
183 }
184
185 ret = clk_get_set_enable(cclk, 7372800, 1);
186 if(ret)
187 {
188 dprintf(CRITICAL, "failed to set %s ret = %d\n", cclk, ret);
189 ASSERT(0);
190 }
Aparna Mallavarapuca676882015-01-19 20:39:06 +0530191}
192
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700193/* Control the MDSS GDSC */
194void mdp_gdsc_ctrl(uint8_t enable)
195{
196 uint32_t reg = 0;
197 reg = readl(MDP_GDSCR);
198 if (enable) {
199 if (!(reg & GDSC_POWER_ON_BIT)) {
200 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
201 reg |= GDSC_EN_FEW_WAIT_256_MASK;
202 writel(reg, MDP_GDSCR);
203 while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)));
204 } else {
205 dprintf(SPEW, "MDP GDSC already enabled\n");
206 }
207 } else {
208 reg |= BIT(0);
209 writel(reg, MDP_GDSCR);
210 while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT));
211 }
212}
213
214/* Enable all the MDP branch clocks */
215void mdp_clock_enable(void)
216{
217 int ret;
218
219 ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
220 if(ret)
221 {
222 dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
223 ASSERT(0);
224 }
225
226 /* Set MDP clock to 320MHz */
227 ret = clk_get_set_enable("mdss_mdp_clk_src", 320000000, 1);
228
229 if(ret)
230 {
231 dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
232 ASSERT(0);
233 }
234
235 ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
236 if(ret)
237 {
238 dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
239 ASSERT(0);
240 }
241
242 ret = clk_get_set_enable("mdss_mdp_clk", 0, 1);
243 if(ret)
244 {
245 dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret);
246 ASSERT(0);
247 }
248}
249
250/* Disable all the MDP branch clocks */
251void mdp_clock_disable(void)
252{
253 clk_disable(clk_get("mdss_vsync_clk"));
254 clk_disable(clk_get("mdss_mdp_clk"));
255 clk_disable(clk_get("mdss_mdp_clk_src"));
256 clk_disable(clk_get("mdp_ahb_clk"));
257}
258
259/* Disable all the bus clocks needed by MDSS */
260void mdss_bus_clocks_disable(void)
261{
262 /* Disable MDSS AXI clock */
263 clk_disable(clk_get("mdss_axi_clk"));
264}
265
266/* Enable all the bus clocks needed by MDSS */
267void mdss_bus_clocks_enable(void)
268{
269 int ret;
270
271 /* Configure AXI clock */
272 ret = clk_get_set_enable("mdss_axi_clk", 0, 1);
273 if(ret)
274 {
275 dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
276 ASSERT(0);
277 }
278}
279
Padmanabhan Komanduru36e609f2015-05-04 12:52:26 -0700280static void rcg_update_config(uint32_t reg)
281{
282 int i;
283
284 for (i = 0; i < MAX_LOOPS; i++) {
285 if (!(readl(reg) & BIT(0)))
286 return;
287 udelay(1);
288 }
289
290 dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
291 ASSERT(0);
292}
293
294static void branch_clk_halt_check(uint32_t reg)
295{
296 int i;
297
298 for (i = 0; i < MAX_LOOPS; i++) {
299 if (!(readl(reg) & BIT(31)))
300 return;
301 udelay(1);
302 }
303
304 dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
305 ASSERT(0);
306}
307
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700308/* Disable all the branch clocks needed by the DSI controller */
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530309void gcc_dsi_clocks_disable(uint32_t flags)
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700310{
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530311 if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
312 clk_disable(clk_get("mdss_esc0_clk"));
313 writel(0x0, DSI_PIXEL0_CBCR);
314 writel(0x0, DSI_BYTE0_CBCR);
315 }
316
317 if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
318 clk_disable(clk_get("mdss_esc1_clk"));
319 writel(0x0, DSI_PIXEL1_CBCR);
320 writel(0x0, DSI_BYTE1_CBCR);
321 }
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700322}
323
Padmanabhan Komanduru62eec852018-05-14 12:27:30 +0530324void gcc_dsi_lp_clock_enable(uint32_t flags)
325{
326 int ret = 0;
327
328 if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
329 /* Configure ESC clock */
330 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
331 if (ret) {
332 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n",
333 ret);
334 ASSERT(0);
335 }
336 }
337
338 if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
339 /* Configure ESC clock */
340 ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
341 if (ret) {
342 dprintf(CRITICAL, "failed to set esc1_clk ret = %d\n",
343 ret);
344 ASSERT(0);
345 }
346 }
347}
348
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700349/* Configure all the branch clocks needed by the DSI controller */
Padmanabhan Komanduru62eec852018-05-14 12:27:30 +0530350void gcc_dsi_hs_clocks_enable(uint32_t flags, bool use_dsi1_pll, uint8_t pclk0_m,
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530351 uint8_t pclk0_n, uint8_t pclk0_d)
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700352{
Padmanabhan Komanduru2a6c3452015-09-09 18:46:06 +0530353 int dsi0_cfg_rcgr, dsi1_cfg_rcgr = 0;
354
355 dsi0_cfg_rcgr = BIT(8); /* DSI0 can only be sourced from PLL0 */
356
357 /*
358 * DSI1<->PLL1 for 1.) 8956 v1.0 always 2.) Single DSI cases on DSI1
359 * DSI1<->PLL0 for 8956 v1.1 split DSI cases
360 */
361 if (!platform_is_msm8976_v_1_1() || use_dsi1_pll)
362 dsi1_cfg_rcgr = BIT(8);
363 else if (flags == (MMSS_DSI_CLKS_FLAG_DSI0 | MMSS_DSI_CLKS_FLAG_DSI1))
364 dsi1_cfg_rcgr = BIT(8) | BIT(9);
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700365
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530366 if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
367 /* Enable DSI0 branch clocks */
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700368
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530369 /* Set the source for DSI0 byte RCG */
Padmanabhan Komanduru2a6c3452015-09-09 18:46:06 +0530370 writel(dsi0_cfg_rcgr, DSI_BYTE0_CFG_RCGR);
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530371 /* Set the update RCG bit */
372 writel(0x1, DSI_BYTE0_CMD_RCGR);
373 rcg_update_config(DSI_BYTE0_CMD_RCGR);
374 /* Enable the branch clock */
375 writel(0x1, DSI_BYTE0_CBCR);
376 branch_clk_halt_check(DSI_BYTE0_CBCR);
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700377
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530378 /* Configure Pixel clock */
379 /* Set the source for DSI0 pixel RCG */
Padmanabhan Komanduru2a6c3452015-09-09 18:46:06 +0530380 writel(dsi0_cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530381 /* Set the MND for DSI0 pixel clock */
382 writel(pclk0_m, DSI_PIXEL0_M);
383 writel(pclk0_n, DSI_PIXEL0_N);
384 writel(pclk0_d, DSI_PIXEL0_D);
385 /* Set the update RCG bit */
386 writel(0x1, DSI_PIXEL0_CMD_RCGR);
387 rcg_update_config(DSI_PIXEL0_CMD_RCGR);
388 /* Enable the branch clock */
389 writel(0x1, DSI_PIXEL0_CBCR);
390 branch_clk_halt_check(DSI_PIXEL0_CBCR);
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530391 }
392
393 if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
394 /* Enable DSI1 branch clocks */
395
396 /* Set the source for DSI1 byte RCG */
Padmanabhan Komanduru2a6c3452015-09-09 18:46:06 +0530397 writel(dsi1_cfg_rcgr, DSI_BYTE1_CFG_RCGR);
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530398 /* Set the update RCG bit */
399 writel(0x1, DSI_BYTE1_CMD_RCGR);
400 rcg_update_config(DSI_BYTE1_CMD_RCGR);
401 /* Enable the branch clock */
402 writel(0x1, DSI_BYTE1_CBCR);
403 branch_clk_halt_check(DSI_BYTE1_CBCR);
404
405 /* Configure Pixel clock */
406 /* Set the source for DSI1 pixel RCG */
Padmanabhan Komanduru2a6c3452015-09-09 18:46:06 +0530407 writel(dsi1_cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
Padmanabhan Komanduru82ae7132015-06-08 15:46:33 +0530408 /* Set the MND for DSI1 pixel clock */
409 writel(pclk0_m, DSI_PIXEL1_M);
410 writel(pclk0_n, DSI_PIXEL1_N);
411 writel(pclk0_d, DSI_PIXEL1_D);
412 /* Set the update RCG bit */
413 writel(0x1, DSI_PIXEL1_CMD_RCGR);
414 rcg_update_config(DSI_PIXEL1_CMD_RCGR);
415 /* Enable the branch clock */
416 writel(0x1, DSI_PIXEL1_CBCR);
417 branch_clk_halt_check(DSI_PIXEL1_CBCR);
Padmanabhan Komandurufba66322015-04-13 12:47:31 -0700418 }
419}
420
Aparna Mallavarapuca676882015-01-19 20:39:06 +0530421void clock_ce_enable(uint8_t instance)
422{
Aparna Mallavarapu1e8b0932015-03-29 23:38:13 +0530423 int ret;
424 char clk_name[64];
425
426 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
427 ret = clk_get_set_enable(clk_name, 160000000, 1);
428 if(ret)
429 {
430 dprintf(CRITICAL, "failed to set ce%u_src_clk ret = %d\n", instance, ret);
431 ASSERT(0);
432 }
433
434 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
435 ret = clk_get_set_enable(clk_name, 0, 1);
436 if(ret)
437 {
438 dprintf(CRITICAL, "failed to set ce%u_core_clk ret = %d\n", instance, ret);
439 ASSERT(0);
440 }
441
442 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
443 ret = clk_get_set_enable(clk_name, 0, 1);
444 if(ret)
445 {
446 dprintf(CRITICAL, "failed to set ce%u_ahb_clk ret = %d\n", instance, ret);
447 ASSERT(0);
448 }
449
450 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
451 ret = clk_get_set_enable(clk_name, 0, 1);
452 if(ret)
453 {
454 dprintf(CRITICAL, "failed to set ce%u_axi_clk ret = %d\n", instance, ret);
455 ASSERT(0);
456 }
457
458 /* Wait for 48 * #pipes cycles.
459 * This is necessary as immediately after an access control reset (boot up)
460 * or a debug re-enable, the Crypto core sequentially clears its internal
461 * pipe key storage memory. If pipe key initialization writes are attempted
462 * during this time, they may be overwritten by the internal clearing logic.
463 */
464 udelay(1);
Aparna Mallavarapuca676882015-01-19 20:39:06 +0530465
466}
467
468void clock_ce_disable(uint8_t instance)
469{
Aparna Mallavarapu1e8b0932015-03-29 23:38:13 +0530470 struct clk *ahb_clk;
471 struct clk *cclk;
472 struct clk *axi_clk;
473 struct clk *src_clk;
474 char clk_name[64];
475
476 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
477 src_clk = clk_get(clk_name);
478
479 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
480 ahb_clk = clk_get(clk_name);
481
482 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
483 axi_clk = clk_get(clk_name);
484
485 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
486 cclk = clk_get(clk_name);
487
488 clk_disable(ahb_clk);
489 clk_disable(axi_clk);
490 clk_disable(cclk);
491 clk_disable(src_clk);
492
493 /* Some delay for the clocks to stabalize. */
494 udelay(1);
Aparna Mallavarapuca676882015-01-19 20:39:06 +0530495
496}
497
498void clock_config_ce(uint8_t instance)
499{
500 /* Need to enable the clock before disabling since the clk_disable()
501 * has a check to default to nop when the clk_enable() is not called
502 * on that particular clock.
503 */
504 clock_ce_enable(instance);
505
506 clock_ce_disable(instance);
507
Aparna Mallavarapuca676882015-01-19 20:39:06 +0530508 clock_ce_enable(instance);
509}