blob: 5b08c53e8d6e53cf070c5ed3f74e0dd14737dcba [file] [log] [blame]
Aparna Mallavarapu9e014372013-10-19 15:04:58 +05301/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
2 *
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>
Aparna Mallavarapu9e014372013-10-19 15:04:58 +053039
40void hsusb_clock_init(void)
41{
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -080042 int ret;
43 struct clk *iclk, *cclk;
Aparna Mallavarapu9e014372013-10-19 15:04:58 +053044
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -080045 ret = clk_get_set_enable("usb_iface_clk", 0, 1);
46 if(ret)
47 {
48 dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
49 ASSERT(0);
50 }
51
52 ret = clk_get_set_enable("usb_core_clk", 80000000, 1);
53 if(ret)
54 {
55 dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
56 ASSERT(0);
57 }
58
59 mdelay(20);
60
61 iclk = clk_get("usb_iface_clk");
62 cclk = clk_get("usb_core_clk");
63
64 clk_disable(iclk);
65 clk_disable(cclk);
66
67 mdelay(20);
68
69 /* Start the block reset for usb */
70 writel(1, USB_HS_BCR);
71
72 mdelay(20);
73
74 /* Take usb block out of reset */
75 writel(0, USB_HS_BCR);
76
77 mdelay(20);
78
79 ret = clk_enable(iclk);
80
81 if(ret)
82 {
83 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
84 ASSERT(0);
85 }
86
87 ret = clk_enable(cclk);
88
89 if(ret)
90 {
91 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
92 ASSERT(0);
93 }
Aparna Mallavarapu9e014372013-10-19 15:04:58 +053094}
95
96void clock_init_mmc(uint32_t interface)
97{
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -080098 char clk_name[64];
99 int ret;
Aparna Mallavarapu9e014372013-10-19 15:04:58 +0530100
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -0800101 snprintf(clk_name, sizeof(clk_name), "sdc%u_iface_clk", interface);
102
103 /* enable interface clock */
104 ret = clk_get_set_enable(clk_name, 0, 1);
105 if(ret)
106 {
107 dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret);
108 ASSERT(0);
109 }
Aparna Mallavarapu9e014372013-10-19 15:04:58 +0530110}
111
112/* Configure MMC clock */
113void clock_config_mmc(uint32_t interface, uint32_t freq)
114{
Aparna Mallavarapu70e5df52014-02-27 22:51:29 -0800115 int ret;
116 uint32_t reg;
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_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
Radhika Ranjan Sonibc86e2c2014-06-11 17:46:56 +0530208 if (platform_is_msm8939())
209 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 */
266void gcc_dsi_clocks_disable(void)
267{
268 clk_disable(clk_get("mdss_esc0_clk"));
269 writel(0x0, DSI_PIXEL0_CBCR);
270 writel(0x0, DSI_BYTE0_CBCR);
271}
272
273/* Configure all the branch clocks needed by the DSI controller */
274void gcc_dsi_clocks_enable(uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
275{
276 int ret;
277
278 /* Configure Byte clock -autopll- This will not change becasue
279 byte clock does not need any divider*/
280 writel(0x100, DSI_BYTE0_CFG_RCGR);
281 writel(0x1, DSI_BYTE0_CMD_RCGR);
282 writel(0x1, DSI_BYTE0_CBCR);
283
284 /* Configure Pixel clock */
285 writel(0x100, DSI_PIXEL0_CFG_RCGR);
286 writel(0x1, DSI_PIXEL0_CMD_RCGR);
287 writel(0x1, DSI_PIXEL0_CBCR);
288
289 writel(pclk0_m, DSI_PIXEL0_M);
290 writel(pclk0_n, DSI_PIXEL0_N);
291 writel(pclk0_d, DSI_PIXEL0_D);
292
293 /* Configure ESC clock */
294 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
295 if (ret) {
296 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
297 ASSERT(0);
298 }
299}
Aparna Mallavarapu2e899672014-04-22 15:12:05 +0530300
301/* Function to asynchronously reset CE.
302 * Function assumes that all the CE clocks are off.
303 */
304static void ce_async_reset(uint8_t instance)
305{
306 /* Start the block reset for CE */
307 writel(1, GCC_CRYPTO_BCR);
308
309 udelay(2);
310
311 /* Take CE block out of reset */
312 writel(0, GCC_CRYPTO_BCR);
313
314 udelay(2);
315}
316
317void clock_ce_enable(uint8_t instance)
318{
319 int ret;
320 char clk_name[64];
321
322 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
323 ret = clk_get_set_enable(clk_name, 160000000, 1);
324 if(ret)
325 {
326 dprintf(CRITICAL, "failed to set ce%u_src_clk ret = %d\n", instance, ret);
327 ASSERT(0);
328 }
329
330 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
331 ret = clk_get_set_enable(clk_name, 0, 1);
332 if(ret)
333 {
334 dprintf(CRITICAL, "failed to set ce%u_core_clk ret = %d\n", instance, ret);
335 ASSERT(0);
336 }
337
338 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
339 ret = clk_get_set_enable(clk_name, 0, 1);
340 if(ret)
341 {
342 dprintf(CRITICAL, "failed to set ce%u_ahb_clk ret = %d\n", instance, ret);
343 ASSERT(0);
344 }
345
346 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
347 ret = clk_get_set_enable(clk_name, 0, 1);
348 if(ret)
349 {
350 dprintf(CRITICAL, "failed to set ce%u_axi_clk ret = %d\n", instance, ret);
351 ASSERT(0);
352 }
353
354 /* Wait for 48 * #pipes cycles.
355 * This is necessary as immediately after an access control reset (boot up)
356 * or a debug re-enable, the Crypto core sequentially clears its internal
357 * pipe key storage memory. If pipe key initialization writes are attempted
358 * during this time, they may be overwritten by the internal clearing logic.
359 */
360 udelay(1);
361}
362
363void clock_ce_disable(uint8_t instance)
364{
365 struct clk *ahb_clk;
366 struct clk *cclk;
367 struct clk *axi_clk;
368 struct clk *src_clk;
369 char clk_name[64];
370
371 snprintf(clk_name, sizeof(clk_name), "ce%u_src_clk", instance);
372 src_clk = clk_get(clk_name);
373
374 snprintf(clk_name, sizeof(clk_name), "ce%u_ahb_clk", instance);
375 ahb_clk = clk_get(clk_name);
376
377 snprintf(clk_name, sizeof(clk_name), "ce%u_axi_clk", instance);
378 axi_clk = clk_get(clk_name);
379
380 snprintf(clk_name, sizeof(clk_name), "ce%u_core_clk", instance);
381 cclk = clk_get(clk_name);
382
383 clk_disable(ahb_clk);
384 clk_disable(axi_clk);
385 clk_disable(cclk);
386 clk_disable(src_clk);
387
388 /* Some delay for the clocks to stabalize. */
389 udelay(1);
390}
391
392void clock_config_ce(uint8_t instance)
393{
394 /* Need to enable the clock before disabling since the clk_disable()
395 * has a check to default to nop when the clk_enable() is not called
396 * on that particular clock.
397 */
398 clock_ce_enable(instance);
399
400 clock_ce_disable(instance);
401
402 ce_async_reset(instance);
403
404 clock_ce_enable(instance);
405}
Aparna Mallavarapu3f24f3b2014-05-15 11:50:37 +0530406
407void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
408{
409 uint8_t ret = 0;
410 char clk_name[64];
411
412 struct clk *qup_clk;
413
414 if((blsp_id != BLSP_ID_1) || (qup_id != QUP_ID_1)) {
415 dprintf(CRITICAL, "Incorrect BLSP-%d or QUP-%d configuration\n", blsp_id, qup_id);
416 ASSERT(0);
417 }
418
419 snprintf(clk_name, sizeof(clk_name), "blsp1_qup2_ahb_iface_clk");
420
421 ret = clk_get_set_enable(clk_name, 0 , 1);
422
423 if (ret) {
424 dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name);
425 return;
426 }
427
428 snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup2_i2c_apps_clk");
429
430 qup_clk = clk_get(clk_name);
431
432 if (!qup_clk) {
433 dprintf(CRITICAL, "Failed to get %s\n", clk_name);
434 return;
435 }
436
437 ret = clk_enable(qup_clk);
438
439 if (ret) {
440 dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
441 return;
442 }
443}