blob: 663a6cef3bde41c6eae3fed65c34b239f73e2c6b [file] [log] [blame]
vijay kumardd51c592015-01-05 12:46:28 +05301/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Aparna Mallavarapu9e014372013-10-19 15:04:58 +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>
Aparna Mallavarapu3f24f3b2014-05-15 11:50:37 +053038#include <blsp_qup.h>
Unnati Gandhibd9dbea2014-07-17 14:30:29 +053039#include <platform.h>
Aparna Mallavarapu9e014372013-10-19 15:04:58 +053040
41void hsusb_clock_init(void)
42{
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -080043 int ret;
44 struct clk *iclk, *cclk;
Aparna Mallavarapu9e014372013-10-19 15:04:58 +053045
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -080046 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
53 ret = clk_get_set_enable("usb_core_clk", 80000000, 1);
54 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 Mallavarapu9e014372013-10-19 15:04:58 +053095}
96
97void clock_init_mmc(uint32_t interface)
98{
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -080099 char clk_name[64];
100 int ret;
Aparna Mallavarapu9e014372013-10-19 15:04:58 +0530101
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -0800102 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 Mallavarapu9e014372013-10-19 15:04:58 +0530111}
112
113/* Configure MMC clock */
114void clock_config_mmc(uint32_t interface, uint32_t freq)
115{
Unnati Gandhibd9dbea2014-07-17 14:30:29 +0530116 int ret = 1;
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -0800117 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_200MHZ)
130 {
131 ret = clk_get_set_enable(clk_name, 200000000, 1);
132 }
133 else if(freq == MMC_CLK_177MHZ)
134 {
135 ret = clk_get_set_enable(clk_name, 177770000, 1);
136 }
137 else
138 {
139 dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
140 ASSERT(0);
141 }
142
143 if(ret)
144 {
145 dprintf(CRITICAL, "failed to set %s ret = %d\n", clk_name, ret);
146 ASSERT(0);
147 }
Aparna Mallavarapu9e014372013-10-19 15:04:58 +0530148}
149
150/* Configure UART clock based on the UART block id*/
151void clock_config_uart_dm(uint8_t id)
152{
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -0800153 int ret;
154 char iclk[64];
155 char cclk[64];
Aparna Mallavarapu9e014372013-10-19 15:04:58 +0530156
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -0800157 snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
158 snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
Aparna Mallavarapu9e014372013-10-19 15:04:58 +0530159
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -0800160 ret = clk_get_set_enable(iclk, 0, 1);
161 if(ret)
162 {
163 dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret);
164 ASSERT(0);
165 }
Aparna Mallavarapu9e014372013-10-19 15:04:58 +0530166
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -0800167 ret = clk_get_set_enable(cclk, 7372800, 1);
168 if(ret)
169 {
170 dprintf(CRITICAL, "failed to set %s ret = %d\n", cclk, ret);
171 ASSERT(0);
172 }
Aparna Mallavarapu9e014372013-10-19 15:04:58 +0530173}
Padmanabhan Komandurudd778b92014-03-21 19:25:17 +0530174
175/* Control the MDSS GDSC */
176void mdp_gdsc_ctrl(uint8_t enable)
177{
178 uint32_t reg = 0;
179 reg = readl(MDP_GDSCR);
180 if (enable) {
181 if (!(reg & GDSC_POWER_ON_BIT)) {
182 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
183 reg |= GDSC_EN_FEW_WAIT_256_MASK;
184 writel(reg, MDP_GDSCR);
185 while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)));
186 } else {
187 dprintf(SPEW, "MDP GDSC already enabled\n");
188 }
189 } else {
190 reg |= BIT(0);
191 writel(reg, MDP_GDSCR);
192 while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT));
193 }
194}
195
196/* Enable all the MDP branch clocks */
197void mdp_clock_enable(void)
198{
199 int ret;
200
201 ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
202 if(ret)
203 {
204 dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
205 ASSERT(0);
206 }
207
vijay kumardd51c592015-01-05 12:46:28 +0530208 if (platform_is_msm8939() || platform_is_msm8929())
Radhika Ranjan Sonibc86e2c2014-06-11 17:46:56 +0530209 ret = clk_get_set_enable("mdss_mdp_clk_src", 307200000, 1);
210 else
211 /* Set MDP clock to 320MHz */
212 ret = clk_get_set_enable("mdss_mdp_clk_src", 320000000, 1);
213
Padmanabhan Komandurudd778b92014-03-21 19:25:17 +0530214 if(ret)
215 {
216 dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
217 ASSERT(0);
218 }
219
220 ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
221 if(ret)
222 {
223 dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
224 ASSERT(0);
225 }
226
227 ret = clk_get_set_enable("mdss_mdp_clk", 0, 1);
228 if(ret)
229 {
230 dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret);
231 ASSERT(0);
232 }
233}
234
235/* Disable all the MDP branch clocks */
236void mdp_clock_disable(void)
237{
238 clk_disable(clk_get("mdss_vsync_clk"));
239 clk_disable(clk_get("mdss_mdp_clk"));
240 clk_disable(clk_get("mdss_mdp_clk_src"));
241 clk_disable(clk_get("mdp_ahb_clk"));
242}
243
244/* Disable all the bus clocks needed by MDSS */
245void mdss_bus_clocks_disable(void)
246{
247 /* Disable MDSS AXI clock */
248 clk_disable(clk_get("mdss_axi_clk"));
249}
250
251/* Enable all the bus clocks needed by MDSS */
252void mdss_bus_clocks_enable(void)
253{
254 int ret;
255
256 /* Configure AXI clock */
257 ret = clk_get_set_enable("mdss_axi_clk", 0, 1);
258 if(ret)
259 {
260 dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
261 ASSERT(0);
262 }
263}
264
265/* Disable all the branch clocks needed by the DSI controller */
Vineet Bajaje022da62014-07-24 19:13:34 +0530266void gcc_dsi_clocks_disable(uint8_t dual_dsi)
Padmanabhan Komandurudd778b92014-03-21 19:25:17 +0530267{
268 clk_disable(clk_get("mdss_esc0_clk"));
269 writel(0x0, DSI_PIXEL0_CBCR);
270 writel(0x0, DSI_BYTE0_CBCR);
Vineet Bajaje022da62014-07-24 19:13:34 +0530271 if (dual_dsi) {
272 clk_disable(clk_get("mdss_esc1_clk"));
273 writel(0x0, DSI_PIXEL1_CBCR);
274 writel(0x0, DSI_BYTE1_CBCR);
275 }
Padmanabhan Komandurudd778b92014-03-21 19:25:17 +0530276}
277
278/* Configure all the branch clocks needed by the DSI controller */
Vineet Bajaje022da62014-07-24 19:13:34 +0530279void gcc_dsi_clocks_enable(uint8_t dual_dsi, uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
Padmanabhan Komandurudd778b92014-03-21 19:25:17 +0530280{
281 int ret;
282
283 /* Configure Byte clock -autopll- This will not change becasue
284 byte clock does not need any divider*/
285 writel(0x100, DSI_BYTE0_CFG_RCGR);
286 writel(0x1, DSI_BYTE0_CMD_RCGR);
287 writel(0x1, DSI_BYTE0_CBCR);
288
289 /* Configure Pixel clock */
290 writel(0x100, DSI_PIXEL0_CFG_RCGR);
291 writel(0x1, DSI_PIXEL0_CMD_RCGR);
292 writel(0x1, DSI_PIXEL0_CBCR);
293
294 writel(pclk0_m, DSI_PIXEL0_M);
295 writel(pclk0_n, DSI_PIXEL0_N);
296 writel(pclk0_d, DSI_PIXEL0_D);
297
298 /* Configure ESC clock */
299 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
300 if (ret) {
301 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
302 ASSERT(0);
303 }
Vineet Bajaje022da62014-07-24 19:13:34 +0530304
305 if (dual_dsi) {
306 /* Configure Byte clock -autopll- This will not change becasue
307 byte clock does not need any divider*/
308 writel(0x100, DSI_BYTE1_CFG_RCGR);
309 writel(0x1, DSI_BYTE1_CMD_RCGR);
310 writel(0x1, DSI_BYTE1_CBCR);
311
312 /* Configure Pixel clock */
313 writel(0x100, DSI_PIXEL1_CFG_RCGR);
314 writel(0x1, DSI_PIXEL1_CMD_RCGR);
315 writel(0x1, DSI_PIXEL1_CBCR);
316
317 writel(pclk0_m, DSI_PIXEL1_M);
318 writel(pclk0_n, DSI_PIXEL1_N);
319 writel(pclk0_d, DSI_PIXEL1_D);
320
321 /* Configure ESC clock */
322 ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
323 if (ret) {
324 dprintf(CRITICAL, "failed to set esc1_clk ret = %d\n", ret);
325 ASSERT(0);
326 }
327 }
Padmanabhan Komandurudd778b92014-03-21 19:25:17 +0530328}
Aparna Mallavarapu2e899672014-04-22 15:12:05 +0530329
330/* Function to asynchronously reset CE.
331 * Function assumes that all the CE clocks are off.
332 */
333static void ce_async_reset(uint8_t instance)
334{
335 /* Start the block reset for CE */
336 writel(1, GCC_CRYPTO_BCR);
337
338 udelay(2);
339
340 /* Take CE block out of reset */
341 writel(0, GCC_CRYPTO_BCR);
342
343 udelay(2);
344}
345
346void clock_ce_enable(uint8_t instance)
347{
348 int ret;
349 char clk_name[64];
350
351 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
352 ret = clk_get_set_enable(clk_name, 160000000, 1);
353 if(ret)
354 {
355 dprintf(CRITICAL, "failed to set ce%u_src_clk ret = %d\n", instance, ret);
356 ASSERT(0);
357 }
358
359 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
360 ret = clk_get_set_enable(clk_name, 0, 1);
361 if(ret)
362 {
363 dprintf(CRITICAL, "failed to set ce%u_core_clk ret = %d\n", instance, ret);
364 ASSERT(0);
365 }
366
367 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
368 ret = clk_get_set_enable(clk_name, 0, 1);
369 if(ret)
370 {
371 dprintf(CRITICAL, "failed to set ce%u_ahb_clk ret = %d\n", instance, ret);
372 ASSERT(0);
373 }
374
375 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
376 ret = clk_get_set_enable(clk_name, 0, 1);
377 if(ret)
378 {
379 dprintf(CRITICAL, "failed to set ce%u_axi_clk ret = %d\n", instance, ret);
380 ASSERT(0);
381 }
382
383 /* Wait for 48 * #pipes cycles.
384 * This is necessary as immediately after an access control reset (boot up)
385 * or a debug re-enable, the Crypto core sequentially clears its internal
386 * pipe key storage memory. If pipe key initialization writes are attempted
387 * during this time, they may be overwritten by the internal clearing logic.
388 */
389 udelay(1);
390}
391
392void clock_ce_disable(uint8_t instance)
393{
394 struct clk *ahb_clk;
395 struct clk *cclk;
396 struct clk *axi_clk;
397 struct clk *src_clk;
398 char clk_name[64];
399
400 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
401 src_clk = clk_get(clk_name);
402
403 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
404 ahb_clk = clk_get(clk_name);
405
406 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
407 axi_clk = clk_get(clk_name);
408
409 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
410 cclk = clk_get(clk_name);
411
412 clk_disable(ahb_clk);
413 clk_disable(axi_clk);
414 clk_disable(cclk);
415 clk_disable(src_clk);
416
417 /* Some delay for the clocks to stabalize. */
418 udelay(1);
419}
420
421void clock_config_ce(uint8_t instance)
422{
423 /* Need to enable the clock before disabling since the clk_disable()
424 * has a check to default to nop when the clk_enable() is not called
425 * on that particular clock.
426 */
427 clock_ce_enable(instance);
428
429 clock_ce_disable(instance);
430
431 ce_async_reset(instance);
432
433 clock_ce_enable(instance);
434}
Aparna Mallavarapu3f24f3b2014-05-15 11:50:37 +0530435
436void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
437{
438 uint8_t ret = 0;
439 char clk_name[64];
440
441 struct clk *qup_clk;
442
443 if((blsp_id != BLSP_ID_1) || (qup_id != QUP_ID_1)) {
444 dprintf(CRITICAL, "Incorrect BLSP-%d or QUP-%d configuration\n", blsp_id, qup_id);
445 ASSERT(0);
446 }
447
448 snprintf(clk_name, sizeof(clk_name), "blsp1_qup2_ahb_iface_clk");
449
450 ret = clk_get_set_enable(clk_name, 0 , 1);
451
452 if (ret) {
453 dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name);
454 return;
455 }
456
457 snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup2_i2c_apps_clk");
458
459 qup_clk = clk_get(clk_name);
460
461 if (!qup_clk) {
462 dprintf(CRITICAL, "Failed to get %s\n", clk_name);
463 return;
464 }
465
466 ret = clk_enable(qup_clk);
467
468 if (ret) {
469 dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
470 return;
471 }
472}