blob: 855b77bd2d7ba099b2435121ebb593e9fd7a9ebe [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) {
287 if (reg & 0x1) {
288 reg &= ~(BIT(0) | GDSC_EN_FEW_WAIT_MASK);
289 reg |= GDSC_EN_FEW_WAIT_256_MASK;
290 writel(reg, MDP_GDSCR);
291 }
292
293 while(readl(MDP_GDSCR) & ((GDSC_POWER_ON_BIT) | (GDSC_POWER_ON_STATUS_BIT)));
294 } else {
295 reg &= ~BIT(0);
296 writel(reg, MDP_GDSCR);
297 while(!(readl(MDP_GDSCR) & ((GDSC_POWER_ON_BIT))));
298 }
299}
300
301/* Configure MDP clock */
302void mdp_clock_init(void)
303{
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
314 ret = clk_get_set_enable("mdss_mdp_clk_src", 100000000, 1);
315 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
343void mdp_clock_disable(void)
344{
345 writel(0x0, DSI_BYTE0_CBCR);
346 writel(0x0, DSI_PIXEL0_CBCR);
347 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
354/* Initialize all clocks needed by Display */
355void mmss_clock_init(uint32_t dsi_pixel0_cfg_rcgr)
356{
357 int ret;
358
359 /* Configure Byte clock */
360 writel(0x100, DSI_BYTE0_CFG_RCGR);
361 writel(0x1, DSI_BYTE0_CMD_RCGR);
362 writel(0x1, DSI_BYTE0_CBCR);
363
364 /* Configure ESC clock */
365 ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
366 if(ret)
367 {
368 dprintf(CRITICAL, "failed to set esc0_clk ret = %d\n", ret);
369 ASSERT(0);
370 }
371
372 /* 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 }
395
396 /* Configure Pixel clock */
397 writel(dsi_pixel0_cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
398 writel(0x1, DSI_PIXEL0_CMD_RCGR);
399 writel(0x1, DSI_PIXEL0_CBCR);
400}
401
402void mmss_clock_disable(void)
403{
404
405 /* Disable ESC clock */
406 clk_disable(clk_get("mdss_esc0_clk"));
407
408 /* Disable MDSS AXI clock */
409 clk_disable(clk_get("mdss_axi_clk"));
410
411 /* Disable MMSSNOC S0AXI clock */
412 clk_disable(clk_get("mmss_s0_axi_clk"));
413
414 /* Disable MMSSNOC AXI clock */
415 clk_disable(clk_get("mmss_mmssnoc_axi_clk"));
416
417}