blob: f92f940f16c8661cd52e6f24f934a0fbd6b7122a [file] [log] [blame]
V S Ramanjaneya Kumar T713be572013-08-02 11:00:10 +05301/* 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 <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#include <blsp_qup.h>
39
40void hsusb_clock_init(void)
41{
42 int ret;
43 struct clk *iclk, *cclk;
44
45 ret = clk_get_set_enable("usb_iface_clk", 0, 1);
46 if(ret)
47 {
48 dprintf(CRITICAL, "failed to set usb_iface_clk ret = %d\n", ret);
49 ASSERT(0);
50 }
51
52 ret = clk_get_set_enable("usb_core_clk", 75000000, 1);
53 if(ret)
54 {
55 dprintf(CRITICAL, "failed to set usb_core_clk ret = %d\n", ret);
56 ASSERT(0);
57 }
58
59 mdelay(20);
60
61 iclk = clk_get("usb_iface_clk");
62 cclk = clk_get("usb_core_clk");
63
64 clk_disable(iclk);
65 clk_disable(cclk);
66
67 mdelay(20);
68
69 /* Start the block reset for usb */
70 writel(1, USB_HS_BCR);
71
72 mdelay(20);
73
74 /* Take usb block out of reset */
75 writel(0, USB_HS_BCR);
76
77 mdelay(20);
78
79 ret = clk_enable(iclk);
80
81 if(ret)
82 {
83 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
84 ASSERT(0);
85 }
86
87 ret = clk_enable(cclk);
88
89 if(ret)
90 {
91 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
92 ASSERT(0);
93 }
94
95}
96
97void clock_init_mmc(uint32_t interface)
98{
99 char clk_name[64];
100 int ret;
101
102 snprintf(clk_name, 64, "sdc%u_iface_clk", interface);
103
104 /* enable interface clock */
105 ret = clk_get_set_enable(clk_name, 0, 1);
106 if(ret)
107 {
108 dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret);
109 ASSERT(0);
110 }
111}
112
113/* Configure MMC clock */
114void clock_config_mmc(uint32_t interface, uint32_t freq)
115{
116 int ret;
117 uint32_t reg;
118 char clk_name[64];
119
120 snprintf(clk_name, 64, "sdc%u_core_clk", interface);
121
122 /* Disalbe MCI_CLK before changing the sdcc clock */
123#ifndef MMC_SDHCI_SUPPORT
124 mmc_boot_mci_clk_disable();
125#endif
126
127 if(freq == MMC_CLK_400KHZ)
128 {
129 ret = clk_get_set_enable(clk_name, 400000, 1);
130 }
131 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 }
139 else if(freq == MMC_CLK_200MHZ)
140 {
141 ret = clk_get_set_enable(clk_name, 200000000, 1);
142 }
143 else
144 {
145 dprintf(CRITICAL, "sdc frequency (%d) is not supported\n", freq);
146 ASSERT(0);
147 }
148
149
150 if(ret)
151 {
152 dprintf(CRITICAL, "failed to set sdc1_core_clk ret = %d\n", ret);
153 ASSERT(0);
154 }
155
156 /* Enalbe MCI clock */
157#ifndef MMC_SDHCI_SUPPORT
158 mmc_boot_mci_clk_enable();
159#endif
160}
161
162/* Configure UART clock based on the UART block id*/
163void clock_config_uart_dm(uint8_t id)
164{
165 int ret;
166 char str[256];
167
168 sprintf(str, "uart%d_iface_clk", id);
169 ret = clk_get_set_enable(str, 0, 1);
170 if(ret)
171 {
172 dprintf(CRITICAL, "failed to set uart2_iface_clk ret = %d\n", ret);
173 ASSERT(0);
174 }
175
176 sprintf(str, "uart%d_core_clk", id);
177 ret = clk_get_set_enable(str, 7372800, 1);
178 if(ret)
179 {
180 dprintf(CRITICAL, "failed to set uart1_core_clk ret = %d\n", ret);
181 ASSERT(0);
182 }
183}
184
185/* Function to asynchronously reset CE.
186 * Function assumes that all the CE clocks are off.
187 */
188static void ce_async_reset(uint8_t instance)
189{
190 if (instance == 1)
191 {
192 /* TODO: Add support for instance 1. */
193 dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
194 ASSERT(0);
195 }
196 else if (instance == 2)
197 {
198 /* Start the block reset for CE */
199 writel(1, GCC_CE2_BCR);
200
201 udelay(2);
202
203 /* Take CE block out of reset */
204 writel(0, GCC_CE2_BCR);
205
206 udelay(2);
207 }
208 else
209 {
210 dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
211 ASSERT(0);
212 }
213}
214
215void clock_ce_enable(uint8_t instance)
216{
217 int ret;
218 char clk_name[64];
219
220 snprintf(clk_name, 64, "ce%u_src_clk", instance);
221 ret = clk_get_set_enable(clk_name, 100000000, 1);
222 if(ret)
223 {
224 dprintf(CRITICAL, "failed to set ce_src_clk ret = %d\n", ret);
225 ASSERT(0);
226 }
227
228 snprintf(clk_name, 64, "ce%u_core_clk", instance);
229 ret = clk_get_set_enable(clk_name, 0, 1);
230 if(ret)
231 {
232 dprintf(CRITICAL, "failed to set ce_core_clk ret = %d\n", ret);
233 ASSERT(0);
234 }
235
236 snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
237 ret = clk_get_set_enable(clk_name, 0, 1);
238 if(ret)
239 {
240 dprintf(CRITICAL, "failed to set ce_ahb_clk ret = %d\n", ret);
241 ASSERT(0);
242 }
243
244 snprintf(clk_name, 64, "ce%u_axi_clk", instance);
245 ret = clk_get_set_enable(clk_name, 0, 1);
246 if(ret)
247 {
248 dprintf(CRITICAL, "failed to set ce_axi_clk ret = %d\n", ret);
249 ASSERT(0);
250 }
251
252 /* Wait for 48 * #pipes cycles.
253 * This is necessary as immediately after an access control reset (boot up)
254 * or a debug re-enable, the Crypto core sequentially clears its internal
255 * pipe key storage memory. If pipe key initialization writes are attempted
256 * during this time, they may be overwritten by the internal clearing logic.
257 */
258 udelay(1);
259}
260
261void clock_ce_disable(uint8_t instance)
262{
263 struct clk *ahb_clk;
264 struct clk *cclk;
265 struct clk *axi_clk;
266 struct clk *src_clk;
267 char clk_name[64];
268
269 snprintf(clk_name, 64, "ce%u_src_clk", instance);
270 src_clk = clk_get(clk_name);
271
272 snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
273 ahb_clk = clk_get(clk_name);
274
275 snprintf(clk_name, 64, "ce%u_axi_clk", instance);
276 axi_clk = clk_get(clk_name);
277
278 snprintf(clk_name, 64, "ce%u_core_clk", instance);
279 cclk = clk_get(clk_name);
280
281 clk_disable(ahb_clk);
282 clk_disable(axi_clk);
283 clk_disable(cclk);
284 clk_disable(src_clk);
285
286 /* Some delay for the clocks to stabalize. */
287 udelay(1);
288}
289
290void clock_config_ce(uint8_t instance)
291{
292 /* Need to enable the clock before disabling since the clk_disable()
293 * has a check to default to nop when the clk_enable() is not called
294 * on that particular clock.
295 */
296 clock_ce_enable(instance);
297
298 clock_ce_disable(instance);
299
300 ce_async_reset(instance);
301
302 clock_ce_enable(instance);
303
304}
305
306void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
307{
308 uint8_t ret = 0;
309 char clk_name[64];
310
311 struct clk *qup_clk;
312
313 snprintf(clk_name, 64, "blsp%u_ahb_clk", blsp_id);
314
315 ret = clk_get_set_enable(clk_name, 0 , 1);
316
317 if (ret) {
318 dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name);
319 return;
320 }
321
322 snprintf(clk_name, 64, "blsp%u_qup%u_i2c_apps_clk", blsp_id,
323 (qup_id + 1));
324
325 qup_clk = clk_get(clk_name);
326
327 if (!qup_clk) {
328 dprintf(CRITICAL, "Failed to get %s\n", clk_name);
329 return;
330 }
331
332 ret = clk_enable(qup_clk);
333
334 if (ret) {
335 dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
336 return;
337 }
338}