blob: 503ad7b8ec53f887f48c3e9f5b5b559c4f1d7ef8 [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{
Deepa Dinamanieb182372013-02-04 15:53:58 -0800115 int ret;
Deepa Dinamani645e9b12012-12-21 14:23:40 -0800116 uint32_t reg;
Deepa Dinamanieb182372013-02-04 15:53:58 -0800117 char clk_name[64];
118
119 snprintf(clk_name, 64, "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 }
Channagoud Kadabi2a4e6f92013-05-02 17:07:13 -0700129 else if(freq == MMC_CLK_200MHZ)
130 {
131 ret = clk_get_set_enable(clk_name, 200000000, 1);
132 }
Deepa Dinamanieb182372013-02-04 15:53:58 -0800133 else
134 {
135 dprintf(CRITICAL, "sdc frequency (%d) is not supported\n", freq);
136 ASSERT(0);
137 }
138
139
140 if(ret)
141 {
142 dprintf(CRITICAL, "failed to set sdc1_core_clk ret = %d\n", ret);
143 ASSERT(0);
144 }
Deepa Dinamani645e9b12012-12-21 14:23:40 -0800145}
146
147/* Configure UART clock based on the UART block id*/
148void clock_config_uart_dm(uint8_t id)
149{
Deepa Dinamanieb182372013-02-04 15:53:58 -0800150 int ret;
151
152 ret = clk_get_set_enable("uart3_iface_clk", 0, 1);
153 if(ret)
154 {
155 dprintf(CRITICAL, "failed to set uart3_iface_clk ret = %d\n", ret);
156 ASSERT(0);
157 }
158
159 ret = clk_get_set_enable("uart3_core_clk", 7372800, 1);
160 if(ret)
161 {
162 dprintf(CRITICAL, "failed to set uart3_core_clk ret = %d\n", ret);
163 ASSERT(0);
164 }
Deepa Dinamani645e9b12012-12-21 14:23:40 -0800165}
166
Deepa Dinamanic51ad202013-04-02 14:58:56 -0700167/* Function to asynchronously reset CE.
168 * Function assumes that all the CE clocks are off.
169 */
170static void ce_async_reset(uint8_t instance)
171{
172 if (instance == 1)
173 {
174 /* Start the block reset for CE */
175 writel(1, GCC_CE1_BCR);
176
177 udelay(2);
178
179 /* Take CE block out of reset */
180 writel(0, GCC_CE1_BCR);
181
182 udelay(2);
183 }
184 else
185 {
186 dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
187 ASSERT(0);
188 }
189}
190
191void clock_ce_enable(uint8_t instance)
192{
193 int ret;
194 char clk_name[64];
195
196 snprintf(clk_name, 64, "ce%u_src_clk", instance);
197 ret = clk_get_set_enable(clk_name, 100000000, 1);
198 if(ret)
199 {
200 dprintf(CRITICAL, "failed to set ce_src_clk ret = %d\n", ret);
201 ASSERT(0);
202 }
203
204 snprintf(clk_name, 64, "ce%u_core_clk", instance);
205 ret = clk_get_set_enable(clk_name, 0, 1);
206 if(ret)
207 {
208 dprintf(CRITICAL, "failed to set ce_core_clk ret = %d\n", ret);
209 ASSERT(0);
210 }
211
212 snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
213 ret = clk_get_set_enable(clk_name, 0, 1);
214 if(ret)
215 {
216 dprintf(CRITICAL, "failed to set ce_ahb_clk ret = %d\n", ret);
217 ASSERT(0);
218 }
219
220 snprintf(clk_name, 64, "ce%u_axi_clk", instance);
221 ret = clk_get_set_enable(clk_name, 0, 1);
222 if(ret)
223 {
224 dprintf(CRITICAL, "failed to set ce_axi_clk ret = %d\n", ret);
225 ASSERT(0);
226 }
227
228 /* Wait for 48 * #pipes cycles.
229 * This is necessary as immediately after an access control reset (boot up)
230 * or a debug re-enable, the Crypto core sequentially clears its internal
231 * pipe key storage memory. If pipe key initialization writes are attempted
232 * during this time, they may be overwritten by the internal clearing logic.
233 */
234 udelay(1);
235}
236
237void clock_ce_disable(uint8_t instance)
238{
239 struct clk *ahb_clk;
240 struct clk *cclk;
241 struct clk *axi_clk;
242 struct clk *src_clk;
243 char clk_name[64];
244
245 snprintf(clk_name, 64, "ce%u_src_clk", instance);
246 src_clk = clk_get(clk_name);
247
248 snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
249 ahb_clk = clk_get(clk_name);
250
251 snprintf(clk_name, 64, "ce%u_axi_clk", instance);
252 axi_clk = clk_get(clk_name);
253
254 snprintf(clk_name, 64, "ce%u_core_clk", instance);
255 cclk = clk_get(clk_name);
256
257 clk_disable(ahb_clk);
258 clk_disable(axi_clk);
259 clk_disable(cclk);
260 clk_disable(src_clk);
261
262 /* Some delay for the clocks to stabalize. */
263 udelay(1);
264}
265
Deepa Dinamani6bb87d52013-02-26 14:37:36 -0800266void clock_config_ce(uint8_t instance)
267{
Deepa Dinamanic51ad202013-04-02 14:58:56 -0700268 /* Need to enable the clock before disabling since the clk_disable()
269 * has a check to default to nop when the clk_enable() is not called
270 * on that particular clock.
271 */
272 clock_ce_enable(instance);
273
274 clock_ce_disable(instance);
275
276 ce_async_reset(instance);
277
278 clock_ce_enable(instance);
279
Deepa Dinamani6bb87d52013-02-26 14:37:36 -0800280}
281
Ray Zhang955c55f2013-05-25 23:07:50 +0800282void mdp_gdsc_ctrl(uint8_t enable)
283{
284 uint32_t reg = 0;
285 reg = readl(MDP_GDSCR);
286 if (enable) {
Jayant Shekharf56bd562013-11-08 10:57:40 +0530287 if (!(reg & GDSC_POWER_ON_BIT)) {
Ray Zhang955c55f2013-05-25 23:07:50 +0800288 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
289 reg |= GDSC_EN_FEW_WAIT_256_MASK;
290 writel(reg, MDP_GDSCR);
Jayant Shekharf56bd562013-11-08 10:57:40 +0530291 while(!(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT)));
292 } else {
293 dprintf(SPEW, "MDP GDSC already enabled\n");
Ray Zhang955c55f2013-05-25 23:07:50 +0800294 }
Ray Zhang955c55f2013-05-25 23:07:50 +0800295 } else {
Jayant Shekharf56bd562013-11-08 10:57:40 +0530296 reg |= BIT(0);
Ray Zhang955c55f2013-05-25 23:07:50 +0800297 writel(reg, MDP_GDSCR);
Jayant Shekharf56bd562013-11-08 10:57:40 +0530298 while(readl(MDP_GDSCR) & (GDSC_POWER_ON_BIT));
Ray Zhang955c55f2013-05-25 23:07:50 +0800299 }
300}
301
Aravind Venkateswaranf5bdd4b2013-09-19 15:05:31 -0700302/* Enable all the MDP branch clocks */
303void mdp_clock_enable(void)
Ray Zhang955c55f2013-05-25 23:07:50 +0800304{
305 int ret;
306
307 /* Set MDP clock to 100MHz */
308 ret = clk_get_set_enable("mdp_ahb_clk", 0, 1);
309 if(ret)
310 {
311 dprintf(CRITICAL, "failed to set mdp_ahb_clk ret = %d\n", ret);
312 ASSERT(0);
313 }
314
Jayant Shekhar04cd8aa2013-10-21 16:42:02 +0530315 ret = clk_get_set_enable("mdss_mdp_clk_src", 200000000, 1);
Ray Zhang955c55f2013-05-25 23:07:50 +0800316 if(ret)
317 {
318 dprintf(CRITICAL, "failed to set mdp_clk_src ret = %d\n", ret);
319 ASSERT(0);
320 }
321
322 ret = clk_get_set_enable("mdss_vsync_clk", 0, 1);
323 if(ret)
324 {
325 dprintf(CRITICAL, "failed to set mdss vsync clk ret = %d\n", ret);
326 ASSERT(0);
327 }
328
329 ret = clk_get_set_enable("mdss_mdp_clk", 0, 1);
330 if(ret)
331 {
332 dprintf(CRITICAL, "failed to set mdp_clk ret = %d\n", ret);
333 ASSERT(0);
334 }
335
336 ret = clk_get_set_enable("mdss_mdp_lut_clk", 0, 1);
337 if(ret)
338 {
339 dprintf(CRITICAL, "failed to set lut_mdp clk ret = %d\n", ret);
340 ASSERT(0);
341 }
342}
343
Aravind Venkateswaranf5bdd4b2013-09-19 15:05:31 -0700344/* Disable all the MDP branch clocks */
Ray Zhang955c55f2013-05-25 23:07:50 +0800345void mdp_clock_disable(void)
346{
Ray Zhang955c55f2013-05-25 23:07:50 +0800347 clk_disable(clk_get("mdss_vsync_clk"));
348 clk_disable(clk_get("mdss_mdp_clk"));
349 clk_disable(clk_get("mdss_mdp_lut_clk"));
350 clk_disable(clk_get("mdss_mdp_clk_src"));
351 clk_disable(clk_get("mdp_ahb_clk"));
352}
353
Aravind Venkateswaranf5bdd4b2013-09-19 15:05:31 -0700354/* Disable all the bus clocks needed by MDP */
355void mmss_bus_clocks_disable(void)
356{
357 /* Disable MDSS AXI clock */
358 clk_disable(clk_get("mdss_axi_clk"));
359
360 /* Disable MMSSNOC S0AXI clock */
361 clk_disable(clk_get("mmss_s0_axi_clk"));
362
363 /* Disable MMSSNOC AXI clock */
364 clk_disable(clk_get("mmss_mmssnoc_axi_clk"));
365}
366
367/* Enable all the bus clocks needed by MDP */
368void mmss_bus_clocks_enable(void)
Ray Zhang955c55f2013-05-25 23:07:50 +0800369{
370 int ret;
371
Ray Zhang955c55f2013-05-25 23:07:50 +0800372 /* Configure MMSSNOC AXI clock */
373 ret = clk_get_set_enable("mmss_mmssnoc_axi_clk", 100000000, 1);
374 if(ret)
375 {
376 dprintf(CRITICAL, "failed to set mmssnoc_axi_clk ret = %d\n", ret);
377 ASSERT(0);
378 }
379
380 /* Configure MMSSNOC AXI clock */
381 ret = clk_get_set_enable("mmss_s0_axi_clk", 100000000, 1);
382 if(ret)
383 {
384 dprintf(CRITICAL, "failed to set mmss_s0_axi_clk ret = %d\n", ret);
385 ASSERT(0);
386 }
387
388 /* Configure AXI clock */
389 ret = clk_get_set_enable("mdss_axi_clk", 100000000, 1);
390 if(ret)
391 {
392 dprintf(CRITICAL, "failed to set mdss_axi_clk ret = %d\n", ret);
393 ASSERT(0);
394 }
Ray Zhang955c55f2013-05-25 23:07:50 +0800395}
396
Aravind Venkateswaranf5bdd4b2013-09-19 15:05:31 -0700397/* Disable all the branch clocks needed by the DSI controller */
398void mmss_dsi_clocks_disable(void)
399{
400 clk_disable(clk_get("mdss_esc0_clk"));
401 writel(0x0, DSI_PIXEL0_CBCR);
402 writel(0x0, DSI_BYTE0_CBCR);
403}
404
405/* Configure all the branch clocks needed by the DSI controller */
406void mmss_dsi_clocks_enable(uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
Arpita Banerjee20886922013-05-24 16:21:53 -0700407{
408 int ret;
409
410 /* Configure Byte clock -autopll- This will not change becasue
411 byte clock does not need any divider*/
412 writel(0x100, DSI_BYTE0_CFG_RCGR);
413 writel(0x1, DSI_BYTE0_CMD_RCGR);
414 writel(0x1, DSI_BYTE0_CBCR);
415
Arpita Banerjee20886922013-05-24 16:21:53 -0700416 /* Configure Pixel clock */
417 writel(0x100, DSI_PIXEL0_CFG_RCGR);
418 writel(0x1, DSI_PIXEL0_CMD_RCGR);
419 writel(0x1, DSI_PIXEL0_CBCR);
420
421 writel(pclk0_m, DSI_PIXEL0_M);
422 writel(pclk0_n, DSI_PIXEL0_N);
423 writel(pclk0_d, DSI_PIXEL0_D);
Arpita Banerjee20886922013-05-24 16:21:53 -0700424
Aravind Venkateswaranf5bdd4b2013-09-19 15:05:31 -0700425 /* Configure ESC clock */
426 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
427 if (ret) {
428 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
429 ASSERT(0);
430 }
Ray Zhang955c55f2013-05-25 23:07:50 +0800431}