blob: 28cd204e08d2c34fa98204d191445f5349dffbd4 [file] [log] [blame]
Deepa Dinamani32bfad02012-11-02 12:15:05 -07001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
Deepa Dinamanica5ad852012-05-07 18:19:47 -07002 *
3 * Redistribution and use in source and binary forms, with or without
Deepa Dinamani32bfad02012-11-02 12:15:05 -07004 * 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.
Deepa Dinamanica5ad852012-05-07 18:19:47 -070015 *
Deepa Dinamani32bfad02012-11-02 12:15:05 -070016 * 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.
Deepa Dinamanica5ad852012-05-07 18:19:47 -070027 */
28
Amol Jadi29f95032012-06-22 12:52:54 -070029#include <err.h>
30#include <assert.h>
Deepa Dinamanica5ad852012-05-07 18:19:47 -070031#include <debug.h>
32#include <reg.h>
Deepa Dinamani32bfad02012-11-02 12:15:05 -070033#include <platform/timer.h>
Deepa Dinamanica5ad852012-05-07 18:19:47 -070034#include <platform/iomap.h>
Deepa Dinamanica5ad852012-05-07 18:19:47 -070035#include <mmc.h>
Amol Jadi29f95032012-06-22 12:52:54 -070036#include <clock.h>
37#include <platform/clock.h>
Deepa Dinamanica5ad852012-05-07 18:19:47 -070038
Amol Jadi29f95032012-06-22 12:52:54 -070039void hsusb_clock_init(void)
40{
41 int ret;
Deepa Dinamani0687ecd2012-08-10 16:00:26 -070042 struct clk *iclk, *cclk;
Amol Jadi29f95032012-06-22 12:52:54 -070043
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 }
Deepa Dinamani0687ecd2012-08-10 16:00:26 -070057
58 mdelay(20);
59
60 iclk = clk_get("usb_iface_clk");
61 cclk = clk_get("usb_core_clk");
62
63 /* Disable USB all clock init */
64 writel(0, USB_BOOT_CLOCK_CTL);
65
66 clk_disable(iclk);
67 clk_disable(cclk);
68
69 mdelay(20);
70
71 /* Start the block reset for usb */
72 writel(1, USB_HS_BCR);
73
74 mdelay(20);
75
76 /* Take usb block out of reset */
Deepa Dinamani32bfad02012-11-02 12:15:05 -070077 writel(0, USB_HS_BCR);
Deepa Dinamani0687ecd2012-08-10 16:00:26 -070078
79 mdelay(20);
80
81 ret = clk_enable(iclk);
Deepa Dinamani32bfad02012-11-02 12:15:05 -070082
Deepa Dinamani0687ecd2012-08-10 16:00:26 -070083 if(ret)
84 {
85 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
86 ASSERT(0);
87 }
88
89 ret = clk_enable(cclk);
90
91 if(ret)
92 {
93 dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
94 ASSERT(0);
95 }
96
Amol Jadi29f95032012-06-22 12:52:54 -070097}
Deepa Dinamanica5ad852012-05-07 18:19:47 -070098
99void clock_init_mmc(uint32_t interface)
100{
Deepa Dinamanib10c0e42012-08-10 14:36:24 -0700101 char clk_name[64];
Amol Jadi29f95032012-06-22 12:52:54 -0700102 int ret;
103
Deepa Dinamanib10c0e42012-08-10 14:36:24 -0700104 snprintf(clk_name, 64, "sdc%u_iface_clk", interface);
105
Amol Jadi29f95032012-06-22 12:52:54 -0700106 /* enable interface clock */
Deepa Dinamanib10c0e42012-08-10 14:36:24 -0700107 ret = clk_get_set_enable(clk_name, 0, 1);
Amol Jadi29f95032012-06-22 12:52:54 -0700108 if(ret)
109 {
110 dprintf(CRITICAL, "failed to set sdc1_iface_clk ret = %d\n", ret);
111 ASSERT(0);
112 }
Deepa Dinamanica5ad852012-05-07 18:19:47 -0700113}
114
115/* Configure MMC clock */
116void clock_config_mmc(uint32_t interface, uint32_t freq)
117{
Amol Jadi29f95032012-06-22 12:52:54 -0700118 int ret;
Deepa Dinamanica5ad852012-05-07 18:19:47 -0700119 uint32_t reg;
Deepa Dinamanib10c0e42012-08-10 14:36:24 -0700120 char clk_name[64];
121
122 snprintf(clk_name, 64, "sdc%u_core_clk", interface);
Deepa Dinamanica5ad852012-05-07 18:19:47 -0700123
Amol Jadi29f95032012-06-22 12:52:54 -0700124 if(freq == MMC_CLK_400KHZ)
125 {
Deepa Dinamanib10c0e42012-08-10 14:36:24 -0700126 ret = clk_get_set_enable(clk_name, 400000, 1);
Amol Jadi29f95032012-06-22 12:52:54 -0700127 }
128 else if(freq == MMC_CLK_50MHZ)
129 {
Neeti Desaiddc771b2012-08-28 18:17:04 -0700130 ret = clk_get_set_enable(clk_name, 50000000, 1);
Amol Jadi29f95032012-06-22 12:52:54 -0700131 }
132 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 Dinamanica5ad852012-05-07 18:19:47 -0700144
145 reg = 0;
146 reg |= MMC_BOOT_MCI_CLK_ENABLE;
147 reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
148 reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK;
149 writel(reg, MMC_BOOT_MCI_CLK);
Deepa Dinamanica5ad852012-05-07 18:19:47 -0700150}
151
Deepa Dinamani26e93262012-05-21 17:35:14 -0700152/* Configure UART clock based on the UART block id*/
153void clock_config_uart_dm(uint8_t id)
154{
Amol Jadi29f95032012-06-22 12:52:54 -0700155 int ret;
Deepa Dinamani26e93262012-05-21 17:35:14 -0700156
Neeti Desaiac011272012-08-29 18:24:54 -0700157
158 ret = clk_get_set_enable("uart2_iface_clk", 0, 1);
159 if(ret)
160 {
161 dprintf(CRITICAL, "failed to set uart2_iface_clk ret = %d\n", ret);
162 ASSERT(0);
163 }
164
165 ret = clk_get_set_enable("uart2_core_clk", 7372800, 1);
Amol Jadi29f95032012-06-22 12:52:54 -0700166 if(ret)
167 {
168 dprintf(CRITICAL, "failed to set uart1_core_clk ret = %d\n", ret);
169 ASSERT(0);
170 }
Deepa Dinamani26e93262012-05-21 17:35:14 -0700171}
Deepa Dinamani32bfad02012-11-02 12:15:05 -0700172
173/* Function to asynchronously reset CE.
174 * Function assumes that all the CE clocks are off.
175 */
176static void ce_async_reset(uint8_t instance)
177{
178 if (instance == 1)
179 {
180 /* TODO: Add support for instance 1. */
181 dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
182 ASSERT(0);
183 }
184 else if (instance == 2)
185 {
186 /* Start the block reset for CE */
187 writel(1, GCC_CE2_BCR);
188
189 udelay(2);
190
191 /* Take CE block out of reset */
192 writel(0, GCC_CE2_BCR);
193
194 udelay(2);
195 }
196 else
197 {
198 dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
199 ASSERT(0);
200 }
201}
202
203static void clock_ce_enable(uint8_t instance)
204{
205 int ret;
206 char clk_name[64];
207
208 snprintf(clk_name, 64, "ce%u_src_clk", instance);
209 ret = clk_get_set_enable(clk_name, 100000000, 1);
210 if(ret)
211 {
212 dprintf(CRITICAL, "failed to set ce_src_clk ret = %d\n", ret);
213 ASSERT(0);
214 }
215
216 snprintf(clk_name, 64, "ce%u_core_clk", instance);
217 ret = clk_get_set_enable(clk_name, 0, 1);
218 if(ret)
219 {
220 dprintf(CRITICAL, "failed to set ce_core_clk ret = %d\n", ret);
221 ASSERT(0);
222 }
223
224 snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
225 ret = clk_get_set_enable(clk_name, 0, 1);
226 if(ret)
227 {
228 dprintf(CRITICAL, "failed to set ce_ahb_clk ret = %d\n", ret);
229 ASSERT(0);
230 }
231
232 snprintf(clk_name, 64, "ce%u_axi_clk", instance);
233 ret = clk_get_set_enable(clk_name, 0, 1);
234 if(ret)
235 {
236 dprintf(CRITICAL, "failed to set ce_axi_clk ret = %d\n", ret);
237 ASSERT(0);
238 }
239
240 /* Wait for 48 * #pipes cycles.
241 * This is necessary as immediately after an access control reset (boot up)
242 * or a debug re-enable, the Crypto core sequentially clears its internal
243 * pipe key storage memory. If pipe key initialization writes are attempted
244 * during this time, they may be overwritten by the internal clearing logic.
245 */
246 udelay(1);
247}
248
249static void clock_ce_disable(uint8_t instance)
250{
251 struct clk *ahb_clk;
252 struct clk *cclk;
253 struct clk *axi_clk;
254 struct clk *src_clk;
255 char clk_name[64];
256
257 snprintf(clk_name, 64, "ce%u_src_clk", instance);
258 src_clk = clk_get(clk_name);
259
260 snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
261 ahb_clk = clk_get(clk_name);
262
263 snprintf(clk_name, 64, "ce%u_axi_clk", instance);
264 axi_clk = clk_get(clk_name);
265
266 snprintf(clk_name, 64, "ce%u_core_clk", instance);
267 cclk = clk_get(clk_name);
268
269 clk_disable(ahb_clk);
270 clk_disable(axi_clk);
271 clk_disable(cclk);
272 clk_disable(src_clk);
273
274 /* Some delay for the clocks to stabalize. */
275 udelay(1);
276}
277
278void clock_config_ce(uint8_t instance)
279{
280 /* Need to enable the clock before disabling since the clk_disable()
281 * has a check to default to nop when the clk_enable() is not called
282 * on that particular clock.
283 */
284 clock_ce_enable(instance);
285
286 clock_ce_disable(instance);
287
288 ce_async_reset(instance);
289
290 clock_ce_enable(instance);
291}