blob: a6523d5112a6feabad20b8162d998ee1c7ed9e3c [file] [log] [blame]
Deepa Dinamani645e9b12012-12-21 14:23:40 -08001/* Copyright (c) 2012-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 <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>
38
39void hsusb_clock_init(void)
40{
Deepa Dinamanieb182372013-02-04 15:53:58 -080041 int ret;
42 struct clk *iclk, *cclk;
43
44 ret = clk_get_set_enable("usb_iface_clk", 0, 1);
45 if(ret)
46 {
47 dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
48 ASSERT(0);
49 }
50
51 ret = clk_get_set_enable("usb_core_clk", 75000000, 1);
52 if(ret)
53 {
54 dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
55 ASSERT(0);
56 }
57
58 mdelay(20);
59
60 iclk = clk_get("usb_iface_clk");
61 cclk = clk_get("usb_core_clk");
62
Deepa Dinamanieb182372013-02-04 15:53:58 -080063 clk_disable(iclk);
64 clk_disable(cclk);
65
66 mdelay(20);
67
68 /* Start the block reset for usb */
69 writel(1, USB_HS_BCR);
70
71 mdelay(20);
72
73 /* Take usb block out of reset */
74 writel(0, USB_HS_BCR);
75
76 mdelay(20);
77
78 ret = clk_enable(iclk);
79
80 if(ret)
81 {
82 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
83 ASSERT(0);
84 }
85
86 ret = clk_enable(cclk);
87
88 if(ret)
89 {
90 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
91 ASSERT(0);
92 }
Deepa Dinamani645e9b12012-12-21 14:23:40 -080093
94}
95
96void clock_init_mmc(uint32_t interface)
97{
Deepa Dinamanieb182372013-02-04 15:53:58 -080098 char clk_name[64];
99 int ret;
100
101 snprintf(clk_name, 64, "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 }
Deepa Dinamani645e9b12012-12-21 14:23:40 -0800110}
111
112/* Configure MMC clock */
113void clock_config_mmc(uint32_t interface, uint32_t freq)
114{
vijay kumar3335f0e2014-10-27 22:36:49 +0530115 int ret = 0;
Deepa Dinamanieb182372013-02-04 15:53:58 -0800116 char clk_name[64];
117
118 snprintf(clk_name, 64, "sdc%u_core_clk", interface);
119
120 if(freq == MMC_CLK_400KHZ)
121 {
122 ret = clk_get_set_enable(clk_name, 400000, 1);
123 }
124 else if(freq == MMC_CLK_50MHZ)
125 {
126 ret = clk_get_set_enable(clk_name, 50000000, 1);
127 }
Channagoud Kadabi2a4e6f92013-05-02 17:07:13 -0700128 else if(freq == MMC_CLK_200MHZ)
129 {
130 ret = clk_get_set_enable(clk_name, 200000000, 1);
131 }
Deepa Dinamanieb182372013-02-04 15:53:58 -0800132 else
133 {
134 dprintf(CRITICAL, "sdc frequency (%d) is not supported\n", freq);
135 ASSERT(0);
136 }
137
138
139 if(ret)
140 {
141 dprintf(CRITICAL, "failed to set sdc1_core_clk ret = %d\n", ret);
142 ASSERT(0);
143 }
Deepa Dinamani645e9b12012-12-21 14:23:40 -0800144}
145
146/* Configure UART clock based on the UART block id*/
147void clock_config_uart_dm(uint8_t id)
148{
Deepa Dinamanieb182372013-02-04 15:53:58 -0800149 int ret;
150
151 ret = clk_get_set_enable("uart3_iface_clk", 0, 1);
152 if(ret)
153 {
154 dprintf(CRITICAL, "failed to set uart3_iface_clk ret = %d\n", ret);
155 ASSERT(0);
156 }
157
158 ret = clk_get_set_enable("uart3_core_clk", 7372800, 1);
159 if(ret)
160 {
161 dprintf(CRITICAL, "failed to set uart3_core_clk ret = %d\n", ret);
162 ASSERT(0);
163 }
Deepa Dinamani645e9b12012-12-21 14:23:40 -0800164}
165
Deepa Dinamanic51ad202013-04-02 14:58:56 -0700166/* Function to asynchronously reset CE.
167 * Function assumes that all the CE clocks are off.
168 */
169static void ce_async_reset(uint8_t instance)
170{
171 if (instance == 1)
172 {
173 /* Start the block reset for CE */
174 writel(1, GCC_CE1_BCR);
175
176 udelay(2);
177
178 /* Take CE block out of reset */
179 writel(0, GCC_CE1_BCR);
180
181 udelay(2);
182 }
183 else
184 {
185 dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
186 ASSERT(0);
187 }
188}
189
190void clock_ce_enable(uint8_t instance)
191{
192 int ret;
193 char clk_name[64];
194
195 snprintf(clk_name, 64, "ce%u_src_clk", instance);
196 ret = clk_get_set_enable(clk_name, 100000000, 1);
197 if(ret)
198 {
199 dprintf(CRITICAL, "failed to set ce_src_clk ret = %d\n", ret);
200 ASSERT(0);
201 }
202
203 snprintf(clk_name, 64, "ce%u_core_clk", instance);
204 ret = clk_get_set_enable(clk_name, 0, 1);
205 if(ret)
206 {
207 dprintf(CRITICAL, "failed to set ce_core_clk ret = %d\n", ret);
208 ASSERT(0);
209 }
210
211 snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
212 ret = clk_get_set_enable(clk_name, 0, 1);
213 if(ret)
214 {
215 dprintf(CRITICAL, "failed to set ce_ahb_clk ret = %d\n", ret);
216 ASSERT(0);
217 }
218
219 snprintf(clk_name, 64, "ce%u_axi_clk", instance);
220 ret = clk_get_set_enable(clk_name, 0, 1);
221 if(ret)
222 {
223 dprintf(CRITICAL, "failed to set ce_axi_clk ret = %d\n", ret);
224 ASSERT(0);
225 }
226
227 /* Wait for 48 * #pipes cycles.
228 * This is necessary as immediately after an access control reset (boot up)
229 * or a debug re-enable, the Crypto core sequentially clears its internal
230 * pipe key storage memory. If pipe key initialization writes are attempted
231 * during this time, they may be overwritten by the internal clearing logic.
232 */
233 udelay(1);
234}
235
236void clock_ce_disable(uint8_t instance)
237{
238 struct clk *ahb_clk;
239 struct clk *cclk;
240 struct clk *axi_clk;
241 struct clk *src_clk;
242 char clk_name[64];
243
244 snprintf(clk_name, 64, "ce%u_src_clk", instance);
245 src_clk = clk_get(clk_name);
246
247 snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
248 ahb_clk = clk_get(clk_name);
249
250 snprintf(clk_name, 64, "ce%u_axi_clk", instance);
251 axi_clk = clk_get(clk_name);
252
253 snprintf(clk_name, 64, "ce%u_core_clk", instance);
254 cclk = clk_get(clk_name);
255
256 clk_disable(ahb_clk);
257 clk_disable(axi_clk);
258 clk_disable(cclk);
259 clk_disable(src_clk);
260
261 /* Some delay for the clocks to stabalize. */
262 udelay(1);
263}
264
Deepa Dinamani6bb87d52013-02-26 14:37:36 -0800265void clock_config_ce(uint8_t instance)
266{
Deepa Dinamanic51ad202013-04-02 14:58:56 -0700267 /* Need to enable the clock before disabling since the clk_disable()
268 * has a check to default to nop when the clk_enable() is not called
269 * on that particular clock.
270 */
271 clock_ce_enable(instance);
272
273 clock_ce_disable(instance);
274
275 ce_async_reset(instance);
276
277 clock_ce_enable(instance);
278
Deepa Dinamani6bb87d52013-02-26 14:37:36 -0800279}
280
Ray Zhang955c55f2013-05-25 23:07:50 +0800281void mdp_gdsc_ctrl(uint8_t enable)
282{
283 uint32_t reg = 0;
284 reg = readl(MDP_GDSCR);
285 if (enable) {
Jayant Shekharf7d1c842013-11-08 10:57:40 +0530286 if (!(reg & GDSC_POWER_ON_BIT)) {
Ray Zhang955c55f2013-05-25 23:07:50 +0800287 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
288 reg |= GDSC_EN_FEW_WAIT_256_MASK;
289 writel(reg, MDP_GDSCR);
Jayant Shekharf7d1c842013-11-08 10:57:40 +0530290 while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)));
291 } else {
292 dprintf(SPEW, "MDP GDSC already enabled\n");
Ray Zhang955c55f2013-05-25 23:07:50 +0800293 }
Ray Zhang955c55f2013-05-25 23:07:50 +0800294 } else {
Jayant Shekharf7d1c842013-11-08 10:57:40 +0530295 reg |= BIT(0);
Ray Zhang955c55f2013-05-25 23:07:50 +0800296 writel(reg, MDP_GDSCR);
Jayant Shekharf7d1c842013-11-08 10:57:40 +0530297 while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT));
Ray Zhang955c55f2013-05-25 23:07:50 +0800298 }
299}
300
Aravind Venkateswaran8970b5f2013-09-19 15:05:31 -0700301/* Enable all the MDP branch clocks */
302void mdp_clock_enable(void)
Ray Zhang955c55f2013-05-25 23:07:50 +0800303{
304 int ret;
305
306 /* Set MDP clock to 100MHz */
307 ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
308 if(ret)
309 {
310 dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
311 ASSERT(0);
312 }
313
Jayant Shekhar4ccdbfc2013-10-21 16:42:02 +0530314 ret = clk_get_set_enable("mdss_mdp_clk_src", 200000000, 1);
Ray Zhang955c55f2013-05-25 23:07:50 +0800315 if(ret)
316 {
317 dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
318 ASSERT(0);
319 }
320
321 ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
322 if(ret)
323 {
324 dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
325 ASSERT(0);
326 }
327
328 ret = clk_get_set_enable("mdss_mdp_clk", 0, 1);
329 if(ret)
330 {
331 dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret);
332 ASSERT(0);
333 }
334
335 ret = clk_get_set_enable("mdss_mdp_lut_clk", 0, 1);
336 if(ret)
337 {
338 dprintf(CRITICAL, "failed to set lut_mdp clk ret = %d\n", ret);
339 ASSERT(0);
340 }
341}
342
Aravind Venkateswaran8970b5f2013-09-19 15:05:31 -0700343/* Disable all the MDP branch clocks */
Ray Zhang955c55f2013-05-25 23:07:50 +0800344void mdp_clock_disable(void)
345{
Ray Zhang955c55f2013-05-25 23:07:50 +0800346 clk_disable(clk_get("mdss_vsync_clk"));
347 clk_disable(clk_get("mdss_mdp_clk"));
348 clk_disable(clk_get("mdss_mdp_lut_clk"));
349 clk_disable(clk_get("mdss_mdp_clk_src"));
350 clk_disable(clk_get("mdp_ahb_clk"));
351}
352
Aravind Venkateswaran8970b5f2013-09-19 15:05:31 -0700353/* Disable all the bus clocks needed by MDP */
354void mmss_bus_clocks_disable(void)
355{
356 /* Disable MDSS AXI clock */
357 clk_disable(clk_get("mdss_axi_clk"));
358
359 /* Disable MMSSNOC S0AXI clock */
360 clk_disable(clk_get("mmss_s0_axi_clk"));
361
362 /* Disable MMSSNOC AXI clock */
363 clk_disable(clk_get("mmss_mmssnoc_axi_clk"));
364}
365
366/* Enable all the bus clocks needed by MDP */
367void mmss_bus_clocks_enable(void)
Ray Zhang955c55f2013-05-25 23:07:50 +0800368{
369 int ret;
370
Ray Zhang955c55f2013-05-25 23:07:50 +0800371 /* Configure MMSSNOC AXI clock */
372 ret = clk_get_set_enable("mmss_mmssnoc_axi_clk", 100000000, 1);
373 if(ret)
374 {
375 dprintf(CRITICAL, "failed to set mmssnoc_axi_clk ret = %d\n", ret);
376 ASSERT(0);
377 }
378
379 /* Configure MMSSNOC AXI clock */
380 ret = clk_get_set_enable("mmss_s0_axi_clk", 100000000, 1);
381 if(ret)
382 {
383 dprintf(CRITICAL, "failed to set mmss_s0_axi_clk ret = %d\n", ret);
384 ASSERT(0);
385 }
386
387 /* Configure AXI clock */
388 ret = clk_get_set_enable("mdss_axi_clk", 100000000, 1);
389 if(ret)
390 {
391 dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
392 ASSERT(0);
393 }
Ray Zhang955c55f2013-05-25 23:07:50 +0800394}
395
Aravind Venkateswaran8970b5f2013-09-19 15:05:31 -0700396/* Disable all the branch clocks needed by the DSI controller */
397void mmss_dsi_clocks_disable(void)
398{
399 clk_disable(clk_get("mdss_esc0_clk"));
400 writel(0x0, DSI_PIXEL0_CBCR);
401 writel(0x0, DSI_BYTE0_CBCR);
402}
403
404/* Configure all the branch clocks needed by the DSI controller */
405void mmss_dsi_clocks_enable(uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
Arpita Banerjee20886922013-05-24 16:21:53 -0700406{
407 int ret;
408
409 /* Configure Byte clock -autopll- This will not change becasue
410 byte clock does not need any divider*/
411 writel(0x100, DSI_BYTE0_CFG_RCGR);
412 writel(0x1, DSI_BYTE0_CMD_RCGR);
413 writel(0x1, DSI_BYTE0_CBCR);
414
Arpita Banerjee20886922013-05-24 16:21:53 -0700415 /* Configure Pixel clock */
416 writel(0x100, DSI_PIXEL0_CFG_RCGR);
417 writel(0x1, DSI_PIXEL0_CMD_RCGR);
418 writel(0x1, DSI_PIXEL0_CBCR);
419
420 writel(pclk0_m, DSI_PIXEL0_M);
421 writel(pclk0_n, DSI_PIXEL0_N);
422 writel(pclk0_d, DSI_PIXEL0_D);
Arpita Banerjee20886922013-05-24 16:21:53 -0700423
Aravind Venkateswaran8970b5f2013-09-19 15:05:31 -0700424 /* Configure ESC clock */
425 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
426 if (ret) {
427 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
428 ASSERT(0);
429 }
Ray Zhang955c55f2013-05-25 23:07:50 +0800430}