blob: 873eedaeae092474d43c914eb85e9677466753e1 [file] [log] [blame]
Deepa Dinamani554b0622013-05-16 15:00:30 -07001/* Copyright (c) 2013, 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 <stdint.h>
30#include <debug.h>
31#include <reg.h>
32#include <mmc.h>
33#include <clock.h>
34#include <platform/clock.h>
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -070035#include <platform/iomap.h>
Deepa Dinamani554b0622013-05-16 15:00:30 -070036
37void hsusb_clock_init(void)
38{
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -070039 int ret;
40 struct clk *iclk, *cclk;
41
42 ret = clk_get_set_enable("usb_iface_clk", 0, 1);
43 if(ret)
44 {
45 dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
46 ASSERT(0);
47 }
48
49 ret = clk_get_set_enable("usb_core_clk", 75000000, 1);
50 if(ret)
51 {
52 dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
53 ASSERT(0);
54 }
55
56 /* Wait for the clocks to be stable since we are disabling soon after. */
57 mdelay(1);
58
59 iclk = clk_get("usb_iface_clk");
60 cclk = clk_get("usb_core_clk");
61
62 clk_disable(iclk);
63 clk_disable(cclk);
64
65 /* Wait for the clock disable to complete. */
66 mdelay(1);
67
68 /* Start the block reset for usb */
69 writel(1, USB_HS_BCR);
70
71 /* Wait for reset to complete. */
72 mdelay(1);
73
74 /* Take usb block out of reset */
75 writel(0, USB_HS_BCR);
76
77 /* Wait for the block to be brought out of reset. */
78 mdelay(1);
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 }
95
Deepa Dinamani554b0622013-05-16 15:00:30 -070096}
97
98void clock_init_mmc(uint32_t interface)
99{
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -0700100 char clk_name[64];
101 int ret;
102
103 snprintf(clk_name, 64, "sdc%u_iface_clk", interface);
104
105 /* enable interface clock */
106 ret = clk_get_set_enable(clk_name, 0, 1);
107 if(ret)
108 {
109 dprintf(CRITICAL, "failed to set sdc%u_iface_clk ret = %d\n", interface, ret);
110 ASSERT(0);
111 }
Deepa Dinamani554b0622013-05-16 15:00:30 -0700112}
113
114/* Configure MMC clock */
115void clock_config_mmc(uint32_t interface, uint32_t freq)
116{
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -0700117 int ret;
118 uint32_t reg;
119 char clk_name[64];
120
121 snprintf(clk_name, 64, "sdc%u_core_clk", interface);
122
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -0700123 if(freq == MMC_CLK_400KHZ)
124 {
125 ret = clk_get_set_enable(clk_name, 400000, 1);
126 }
Channagoud Kadabi908353c2013-09-23 11:38:48 -0700127 else if(freq == MMC_CLK_25MHZ)
128 {
129 ret = clk_get_set_enable(clk_name, 25000000, 1);
130 }
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -0700131 else if(freq == MMC_CLK_50MHZ)
132 {
133 ret = clk_get_set_enable(clk_name, 50000000, 1);
134 }
135 else if(freq == MMC_CLK_96MHZ)
136 {
137 ret = clk_get_set_enable(clk_name, 100000000, 1);
138 }
Channagoud Kadabide9b2d32013-11-08 13:24:47 -0800139 else if(freq == MMC_CLK_192MHZ)
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -0700140 {
Channagoud Kadabi908353c2013-09-23 11:38:48 -0700141 ret = clk_get_set_enable(clk_name, 192000000, 1);
142 }
Channagoud Kadabide9b2d32013-11-08 13:24:47 -0800143 else if(freq == MMC_CLK_200MHZ)
144 {
145 ret = clk_get_set_enable(clk_name, 200000000, 1);
146 }
Channagoud Kadabi908353c2013-09-23 11:38:48 -0700147 else if(freq == MMC_CLK_400MHZ)
148 {
149 ret = clk_get_set_enable(clk_name, 384000000, 1);
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -0700150 }
151 else
152 {
153 dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
154 ASSERT(0);
155 }
156
157
158 if(ret)
159 {
160 dprintf(CRITICAL, "failed to set sdc%u_core_clk ret = %d\n", interface, ret);
161 ASSERT(0);
162 }
163
Deepa Dinamani554b0622013-05-16 15:00:30 -0700164}
165
Channagoud Kadabi908353c2013-09-23 11:38:48 -0700166/* Configure clocks for SDCC Calibration circuit */
167void clock_config_cdc(uint32_t interface)
168{
169 int ret = 0;
170 char clk_name[64];
171
172 snprintf(clk_name, sizeof(clk_name), "gcc_sdcc%u_cdccal_sleep_clk", interface);
173
174 ret = clk_get_set_enable(clk_name, 0 , 1);
175 if (ret)
176 {
177 dprintf(CRITICAL, "Failed to enable clock: %s\n", clk_name);
178 ASSERT(0);
179 }
180
181 snprintf(clk_name, sizeof(clk_name), "gcc_sdcc%u_cdccal_ff_clk", interface);
182 ret = clk_get_set_enable(clk_name, 0 , 1);
183 if (ret)
184 {
185 dprintf(CRITICAL, "Failed to enable clock: %s\n", clk_name);
186 ASSERT(0);
187 }
188}
189
Deepa Dinamani554b0622013-05-16 15:00:30 -0700190/* Configure UART clock based on the UART block id*/
191void clock_config_uart_dm(uint8_t id)
192{
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -0700193 int ret;
194 char iclk[64];
195 char cclk[64];
196
197 snprintf(iclk, 64, "uart%u_iface_clk", id);
198 snprintf(cclk, 64, "uart%u_core_clk", id);
199
200 ret = clk_get_set_enable(iclk, 0, 1);
201 if(ret)
202 {
203 dprintf(CRITICAL, "failed to set uart%u_iface_clk ret = %d\n", id, ret);
204 ASSERT(0);
205 }
206
207 ret = clk_get_set_enable(cclk, 7372800, 1);
208 if(ret)
209 {
210 dprintf(CRITICAL, "failed to set uart%u_core_clk ret = %d\n", id, ret);
211 ASSERT(0);
212 }
Deepa Dinamani554b0622013-05-16 15:00:30 -0700213}
214
215/* Function to asynchronously reset CE (Crypto Engine).
216 * Function assumes that all the CE clocks are off.
217 */
218static void ce_async_reset(uint8_t instance)
219{
220}
221
222void clock_ce_enable(uint8_t instance)
223{
224}
225
226void clock_ce_disable(uint8_t instance)
227{
228}
229
230void clock_config_ce(uint8_t instance)
231{
232 /* Need to enable the clock before disabling since the clk_disable()
233 * has a check to default to nop when the clk_enable() is not called
234 * on that particular clock.
235 */
236 clock_ce_enable(instance);
237
238 clock_ce_disable(instance);
239
240 ce_async_reset(instance);
241
242 clock_ce_enable(instance);
243
244}
Amol Jadi0a4c9b42013-10-11 14:22:11 -0700245
246void clock_usb30_gdsc_enable(void)
247{
248 uint32_t reg = readl(GCC_USB30_GDSCR);
249
250 reg &= ~(0x1);
251
252 writel(reg, GCC_USB30_GDSCR);
253}
254
255/* enables usb30 interface and master clocks */
256void clock_usb30_init(void)
257{
258 int ret;
259
260 /* interface clock */
261 ret = clk_get_set_enable("usb30_iface_clk", 0, 1);
262 if(ret)
263 {
264 dprintf(CRITICAL, "failed to set usb30_iface_clk. ret = %d\n", ret);
265 ASSERT(0);
266 }
267
268 clock_usb30_gdsc_enable();
269
270 /* master clock */
271 ret = clk_get_set_enable("usb30_master_clk", 125000000, 1);
272 if(ret)
273 {
274 dprintf(CRITICAL, "failed to set usb30_master_clk. ret = %d\n", ret);
275 ASSERT(0);
276 }
277}
Dhaval Patel4a87d522013-10-18 19:02:37 -0700278
279void mdp_gdsc_ctrl(uint8_t enable)
280{
281 uint32_t reg = 0;
282 reg = readl(MDP_GDSCR);
283 if (enable) {
284 if (!(reg & GDSC_POWER_ON_BIT)) {
285 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
286 reg |= GDSC_EN_FEW_WAIT_256_MASK;
287 writel(reg, MDP_GDSCR);
288 while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)));
289 } else {
290 dprintf(INFO, "MDP GDSC already enabled\n");
291 }
292 } else {
293 reg |= BIT(0);
294 writel(reg, MDP_GDSCR);
295 while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT));
296 }
297}
298
299/* Configure MDP clock */
300void mdp_clock_enable(void)
301{
302 int ret;
303
304 /* Set MDP clock to 240MHz */
305 ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
306 if(ret)
307 {
308 dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
309 ASSERT(0);
310 }
311
312 ret = clk_get_set_enable("mdss_mdp_clk_src", 240000000, 1);
313 if(ret)
314 {
315 dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
316 ASSERT(0);
317 }
318
319 ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
320 if(ret)
321 {
322 dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
323 ASSERT(0);
324 }
325
326 ret = clk_get_set_enable("mdss_mdp_clk", 0, 1);
327 if(ret)
328 {
329 dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret);
330 ASSERT(0);
331 }
332
333 ret = clk_get_set_enable("mdss_mdp_lut_clk", 0, 1);
334 if(ret)
335 {
336 dprintf(CRITICAL, "failed to set lut_mdp clk ret = %d\n", ret);
337 ASSERT(0);
338 }
339}
340
341void mdp_clock_disable()
342{
343 clk_disable(clk_get("mdss_vsync_clk"));
344 clk_disable(clk_get("mdss_mdp_clk"));
345 clk_disable(clk_get("mdss_mdp_lut_clk"));
346 clk_disable(clk_get("mdss_mdp_clk_src"));
347 clk_disable(clk_get("mdp_ahb_clk"));
348
349}
350
351void mmss_bus_clock_enable(void)
352{
353 int ret;
354 /* Configure MMSSNOC AXI clock */
355 ret = clk_get_set_enable("mmss_mmssnoc_axi_clk", 100000000, 1);
356 if(ret)
357 {
358 dprintf(CRITICAL, "failed to set mmssnoc_axi_clk ret = %d\n", ret);
359 ASSERT(0);
360 }
361
362 /* Configure S0 AXI clock */
363 ret = clk_get_set_enable("mmss_s0_axi_clk", 100000000, 1);
364 if(ret)
365 {
366 dprintf(CRITICAL, "failed to set mmss_s0_axi_clk ret = %d\n", ret);
367 ASSERT(0);
368 }
369
370 /* Configure AXI clock */
371 ret = clk_get_set_enable("mdss_axi_clk", 100000000, 1);
372 if(ret)
373 {
374 dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
375 ASSERT(0);
376 }
377}
378
379void mmss_bus_clock_disable(void)
380{
381 /* Disable MDSS AXI clock */
382 clk_disable(clk_get("mdss_axi_clk"));
383
384 /* Disable MMSSNOC S0AXI clock */
385 clk_disable(clk_get("mmss_s0_axi_clk"));
386
387 /* Disable MMSSNOC AXI clock */
388 clk_disable(clk_get("mmss_mmssnoc_axi_clk"));
389}
390
391void mmss_dsi_clock_enable(uint32_t dsi_pixel0_cfg_rcgr, uint32_t dual_dsi,
392 uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
393{
394 int ret;
395
396 /* Configure Byte clock -autopll- This will not change because
397 byte clock does not need any divider*/
398 writel(0x100, DSI_BYTE0_CFG_RCGR);
399 writel(0x1, DSI_BYTE0_CMD_RCGR);
400 writel(0x1, DSI_BYTE0_CBCR);
401
402 /* Configure Pixel clock */
403 writel(dsi_pixel0_cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
404 writel(0x1, DSI_PIXEL0_CMD_RCGR);
405 writel(0x1, DSI_PIXEL0_CBCR);
406
407 writel(pclk0_m, DSI_PIXEL0_M);
408 writel(pclk0_n, DSI_PIXEL0_N);
409 writel(pclk0_d, DSI_PIXEL0_D);
410
411 /* Configure ESC clock */
412 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
413 if(ret)
414 {
415 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
416 ASSERT(0);
417 }
418
419 if (dual_dsi) {
420 /* Configure Byte 1 clock */
421 writel(0x100, DSI_BYTE1_CFG_RCGR);
422 writel(0x1, DSI_BYTE1_CMD_RCGR);
423 writel(0x1, DSI_BYTE1_CBCR);
424
425 /* Configure Pixel clock */
426 writel(dsi_pixel0_cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
427 writel(0x1, DSI_PIXEL1_CMD_RCGR);
428 writel(0x1, DSI_PIXEL1_CBCR);
429
Dhaval Patel3980fc02013-10-25 12:16:52 -0700430 writel(pclk0_m, DSI_PIXEL1_M);
431 writel(pclk0_n, DSI_PIXEL1_N);
432 writel(pclk0_d, DSI_PIXEL1_D);
Dhaval Patel4a87d522013-10-18 19:02:37 -0700433
434 /* Configure ESC clock */
435 ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
436 if(ret)
437 {
438 dprintf(CRITICAL, "failed to set esc1_clk ret = %d\n", ret);
439 ASSERT(0);
440 }
441 }
442}
443
444void mmss_dsi_clock_disable(uint32_t dual_dsi)
445{
446 /* Disable ESC clock */
447 clk_disable(clk_get("mdss_esc0_clk"));
448 writel(0x0, DSI_BYTE0_CBCR);
449 writel(0x0, DSI_PIXEL0_CBCR);
450
451 if (dual_dsi) {
452 /* Disable ESC clock */
453 clk_disable(clk_get("mdss_esc1_clk"));
454 writel(0x0, DSI_BYTE1_CBCR);
455 writel(0x0, DSI_PIXEL1_CBCR);
456 }
457}