blob: bfae90362e53ad3a57c8c32cd16b9aef8bf6d441 [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 }
127 else if(freq == MMC_CLK_50MHZ)
128 {
129 ret = clk_get_set_enable(clk_name, 50000000, 1);
130 }
131 else if(freq == MMC_CLK_96MHZ)
132 {
133 ret = clk_get_set_enable(clk_name, 100000000, 1);
134 }
135 else if(freq == MMC_CLK_200MHZ)
136 {
137 ret = clk_get_set_enable(clk_name, 200000000, 1);
138 }
139 else
140 {
141 dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
142 ASSERT(0);
143 }
144
145
146 if(ret)
147 {
148 dprintf(CRITICAL, "failed to set sdc%u_core_clk ret = %d\n", interface, ret);
149 ASSERT(0);
150 }
151
Deepa Dinamani554b0622013-05-16 15:00:30 -0700152}
153
154/* Configure UART clock based on the UART block id*/
155void clock_config_uart_dm(uint8_t id)
156{
Sundarajan Srinivasan09374ed2013-06-18 13:29:32 -0700157 int ret;
158 char iclk[64];
159 char cclk[64];
160
161 snprintf(iclk, 64, "uart%u_iface_clk", id);
162 snprintf(cclk, 64, "uart%u_core_clk", id);
163
164 ret = clk_get_set_enable(iclk, 0, 1);
165 if(ret)
166 {
167 dprintf(CRITICAL, "failed to set uart%u_iface_clk ret = %d\n", id, ret);
168 ASSERT(0);
169 }
170
171 ret = clk_get_set_enable(cclk, 7372800, 1);
172 if(ret)
173 {
174 dprintf(CRITICAL, "failed to set uart%u_core_clk ret = %d\n", id, ret);
175 ASSERT(0);
176 }
Deepa Dinamani554b0622013-05-16 15:00:30 -0700177}
178
179/* Function to asynchronously reset CE (Crypto Engine).
180 * Function assumes that all the CE clocks are off.
181 */
182static void ce_async_reset(uint8_t instance)
183{
184}
185
186void clock_ce_enable(uint8_t instance)
187{
188}
189
190void clock_ce_disable(uint8_t instance)
191{
192}
193
194void clock_config_ce(uint8_t instance)
195{
196 /* Need to enable the clock before disabling since the clk_disable()
197 * has a check to default to nop when the clk_enable() is not called
198 * on that particular clock.
199 */
200 clock_ce_enable(instance);
201
202 clock_ce_disable(instance);
203
204 ce_async_reset(instance);
205
206 clock_ce_enable(instance);
207
208}
Amol Jadi0a4c9b42013-10-11 14:22:11 -0700209
210void clock_usb30_gdsc_enable(void)
211{
212 uint32_t reg = readl(GCC_USB30_GDSCR);
213
214 reg &= ~(0x1);
215
216 writel(reg, GCC_USB30_GDSCR);
217}
218
219/* enables usb30 interface and master clocks */
220void clock_usb30_init(void)
221{
222 int ret;
223
224 /* interface clock */
225 ret = clk_get_set_enable("usb30_iface_clk", 0, 1);
226 if(ret)
227 {
228 dprintf(CRITICAL, "failed to set usb30_iface_clk. ret = %d\n", ret);
229 ASSERT(0);
230 }
231
232 clock_usb30_gdsc_enable();
233
234 /* master clock */
235 ret = clk_get_set_enable("usb30_master_clk", 125000000, 1);
236 if(ret)
237 {
238 dprintf(CRITICAL, "failed to set usb30_master_clk. ret = %d\n", ret);
239 ASSERT(0);
240 }
241}
Dhaval Patel4a87d522013-10-18 19:02:37 -0700242
243void mdp_gdsc_ctrl(uint8_t enable)
244{
245 uint32_t reg = 0;
246 reg = readl(MDP_GDSCR);
247 if (enable) {
248 if (!(reg & GDSC_POWER_ON_BIT)) {
249 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
250 reg |= GDSC_EN_FEW_WAIT_256_MASK;
251 writel(reg, MDP_GDSCR);
252 while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)));
253 } else {
254 dprintf(INFO, "MDP GDSC already enabled\n");
255 }
256 } else {
257 reg |= BIT(0);
258 writel(reg, MDP_GDSCR);
259 while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT));
260 }
261}
262
263/* Configure MDP clock */
264void mdp_clock_enable(void)
265{
266 int ret;
267
268 /* Set MDP clock to 240MHz */
269 ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
270 if(ret)
271 {
272 dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
273 ASSERT(0);
274 }
275
276 ret = clk_get_set_enable("mdss_mdp_clk_src", 240000000, 1);
277 if(ret)
278 {
279 dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
280 ASSERT(0);
281 }
282
283 ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
284 if(ret)
285 {
286 dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
287 ASSERT(0);
288 }
289
290 ret = clk_get_set_enable("mdss_mdp_clk", 0, 1);
291 if(ret)
292 {
293 dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret);
294 ASSERT(0);
295 }
296
297 ret = clk_get_set_enable("mdss_mdp_lut_clk", 0, 1);
298 if(ret)
299 {
300 dprintf(CRITICAL, "failed to set lut_mdp clk ret = %d\n", ret);
301 ASSERT(0);
302 }
303}
304
305void mdp_clock_disable()
306{
307 clk_disable(clk_get("mdss_vsync_clk"));
308 clk_disable(clk_get("mdss_mdp_clk"));
309 clk_disable(clk_get("mdss_mdp_lut_clk"));
310 clk_disable(clk_get("mdss_mdp_clk_src"));
311 clk_disable(clk_get("mdp_ahb_clk"));
312
313}
314
315void mmss_bus_clock_enable(void)
316{
317 int ret;
318 /* Configure MMSSNOC AXI clock */
319 ret = clk_get_set_enable("mmss_mmssnoc_axi_clk", 100000000, 1);
320 if(ret)
321 {
322 dprintf(CRITICAL, "failed to set mmssnoc_axi_clk ret = %d\n", ret);
323 ASSERT(0);
324 }
325
326 /* Configure S0 AXI clock */
327 ret = clk_get_set_enable("mmss_s0_axi_clk", 100000000, 1);
328 if(ret)
329 {
330 dprintf(CRITICAL, "failed to set mmss_s0_axi_clk ret = %d\n", ret);
331 ASSERT(0);
332 }
333
334 /* Configure AXI clock */
335 ret = clk_get_set_enable("mdss_axi_clk", 100000000, 1);
336 if(ret)
337 {
338 dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
339 ASSERT(0);
340 }
341}
342
343void mmss_bus_clock_disable(void)
344{
345 /* Disable MDSS AXI clock */
346 clk_disable(clk_get("mdss_axi_clk"));
347
348 /* Disable MMSSNOC S0AXI clock */
349 clk_disable(clk_get("mmss_s0_axi_clk"));
350
351 /* Disable MMSSNOC AXI clock */
352 clk_disable(clk_get("mmss_mmssnoc_axi_clk"));
353}
354
355void mmss_dsi_clock_enable(uint32_t dsi_pixel0_cfg_rcgr, uint32_t dual_dsi,
356 uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
357{
358 int ret;
359
360 /* Configure Byte clock -autopll- This will not change because
361 byte clock does not need any divider*/
362 writel(0x100, DSI_BYTE0_CFG_RCGR);
363 writel(0x1, DSI_BYTE0_CMD_RCGR);
364 writel(0x1, DSI_BYTE0_CBCR);
365
366 /* Configure Pixel clock */
367 writel(dsi_pixel0_cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
368 writel(0x1, DSI_PIXEL0_CMD_RCGR);
369 writel(0x1, DSI_PIXEL0_CBCR);
370
371 writel(pclk0_m, DSI_PIXEL0_M);
372 writel(pclk0_n, DSI_PIXEL0_N);
373 writel(pclk0_d, DSI_PIXEL0_D);
374
375 /* Configure ESC clock */
376 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
377 if(ret)
378 {
379 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
380 ASSERT(0);
381 }
382
383 if (dual_dsi) {
384 /* Configure Byte 1 clock */
385 writel(0x100, DSI_BYTE1_CFG_RCGR);
386 writel(0x1, DSI_BYTE1_CMD_RCGR);
387 writel(0x1, DSI_BYTE1_CBCR);
388
389 /* Configure Pixel clock */
390 writel(dsi_pixel0_cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
391 writel(0x1, DSI_PIXEL1_CMD_RCGR);
392 writel(0x1, DSI_PIXEL1_CBCR);
393
394 writel(pclk0_m, DSI_PIXEL0_M);
395 writel(pclk0_n, DSI_PIXEL0_N);
396 writel(pclk0_d, DSI_PIXEL0_D);
397
398 /* Configure ESC clock */
399 ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
400 if(ret)
401 {
402 dprintf(CRITICAL, "failed to set esc1_clk ret = %d\n", ret);
403 ASSERT(0);
404 }
405 }
406}
407
408void mmss_dsi_clock_disable(uint32_t dual_dsi)
409{
410 /* Disable ESC clock */
411 clk_disable(clk_get("mdss_esc0_clk"));
412 writel(0x0, DSI_BYTE0_CBCR);
413 writel(0x0, DSI_PIXEL0_CBCR);
414
415 if (dual_dsi) {
416 /* Disable ESC clock */
417 clk_disable(clk_get("mdss_esc1_clk"));
418 writel(0x0, DSI_BYTE1_CBCR);
419 writel(0x0, DSI_PIXEL1_CBCR);
420 }
421}