xref: /freebsd/sys/arm/ti/omap4/omap4_prcm_clks.c (revision f5f7c05209ca2c3748fd8b27c5e80ffad49120eb)
1 /*-
2  * Copyright (c) 2011
3  *	Ben Gray <ben.r.gray@gmail.com>.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the company nor the name of the author may be used to
15  *    endorse or promote products derived from this software without specific
16  *    prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/bus.h>
38 #include <sys/resource.h>
39 #include <sys/rman.h>
40 #include <sys/lock.h>
41 #include <sys/malloc.h>
42 
43 #include <machine/bus.h>
44 #include <machine/cpu.h>
45 #include <machine/cpufunc.h>
46 #include <machine/frame.h>
47 #include <machine/resource.h>
48 #include <machine/intr.h>
49 
50 #include <arm/ti/tivar.h>
51 #include <arm/ti/ti_prcm.h>
52 #include <arm/ti/omap4/omap4_reg.h>
53 
54 #include <dev/fdt/fdt_common.h>
55 #include <dev/ofw/openfirm.h>
56 #include <dev/ofw/ofw_bus.h>
57 #include <dev/ofw/ofw_bus_subr.h>
58 
59 /*
60  *	This file defines the clock configuration for the OMAP4xxx series of
61  *	devices.
62  *
63  *	How This is Suppose to Work
64  *	===========================
65  *	- There is a top level omap_prcm module that defines all OMAP SoC drivers
66  *	should use to enable/disable the system clocks regardless of the version
67  *	of OMAP device they are running on.  This top level PRCM module is just
68  *	a thin shim to chip specific functions that perform the donkey work of
69  *	configuring the clock - this file is the 'donkey' for OMAP44xx devices.
70  *
71  *	- The key bit in this file is the omap_clk_devmap array, it's
72  *	used by the omap_prcm driver to determine what clocks are valid and which
73  *	functions to call to manipulate them.
74  *
75  *	- In essence you just need to define some callbacks for each of the
76  *	clocks and then you're done.
77  *
78  *	- The other thing that is worth noting is that when the omap_prcm device
79  *	is registered you typically pass in some memory ranges which are the
80  *	SYS_MEMORY resources.  These resources are in turn allocated using
81  *	bus_allocate_resources(...) and the resource handles are passed to all
82  *	individual clock callback handlers.
83  *
84  *
85  *
86  *	OMAP4 devices are different from the previous OMAP3 devices in that there
87  *	is no longer a separate functional and interface clock for each module,
88  *	instead there is typically an interface clock that spans many modules.
89  *
90  */
91 
92 #define FREQ_96MHZ    96000000
93 #define FREQ_64MHZ    64000000
94 #define FREQ_48MHZ    48000000
95 #define FREQ_32KHZ    32000
96 
97 /**
98  *	We need three memory regions to cover all the clock configuration registers.
99  *
100  *	   PRM Instance -  0x4A30 6000 : 0x4A30 8000
101  *	   CM1 Instance -  0x4A00 4000 : 0x4A00 5000
102  *	   CM2 Instance -  0x4A00 8000 : 0x4A00 A000
103  *
104  */
105 #define PRM_INSTANCE_MEM_REGION    0
106 #define CM1_INSTANCE_MEM_REGION    1
107 #define CM2_INSTANCE_MEM_REGION    2
108 
109 /**
110  *	Address offsets from the PRM memory region to the top level clock control
111  *	registers.
112  */
113 #define CKGEN_PRM_OFFSET               0x00000100UL
114 #define MPU_PRM_OFFSET                 0x00000300UL
115 #define DSP_PRM_OFFSET                 0x00000400UL
116 #define ABE_PRM_OFFSET                 0x00000500UL
117 #define ALWAYS_ON_PRM_OFFSET           0x00000600UL
118 #define CORE_PRM_OFFSET                0x00000700UL
119 #define IVAHD_PRM_OFFSET               0x00000F00UL
120 #define CAM_PRM_OFFSET                 0x00001000UL
121 #define DSS_PRM_OFFSET                 0x00001100UL
122 #define SGX_PRM_OFFSET                 0x00001200UL
123 #define L3INIT_PRM_OFFSET              0x00001300UL
124 #define L4PER_PRM_OFFSET               0x00001400UL
125 #define WKUP_PRM_OFFSET                0x00001700UL
126 #define WKUP_CM_OFFSET                 0x00001800UL
127 #define EMU_PRM_OFFSET                 0x00001900UL
128 #define EMU_CM_OFFSET                  0x00001A00UL
129 #define DEVICE_PRM_OFFSET              0x00001B00UL
130 #define INSTR_PRM_OFFSET               0x00001F00UL
131 
132 #define CM_ABE_DSS_SYS_CLKSEL_OFFSET   (CKGEN_PRM_OFFSET + 0x0000UL)
133 #define CM_L4_WKUP_CLKSELL_OFFSET      (CKGEN_PRM_OFFSET + 0x0008UL)
134 #define CM_ABE_PLL_REF_CLKSEL_OFFSET   (CKGEN_PRM_OFFSET + 0x000CUL)
135 #define CM_SYS_CLKSEL_OFFSET           (CKGEN_PRM_OFFSET + 0x0010UL)
136 
137 /**
138  *	Address offsets from the CM1 memory region to the top level clock control
139  *	registers.
140  */
141 #define CKGEN_CM1_OFFSET               0x00000100UL
142 #define MPU_CM1_OFFSET                 0x00000300UL
143 #define DSP_CM1_OFFSET                 0x00000400UL
144 #define ABE_CM1_OFFSET                 0x00000500UL
145 #define RESTORE_CM1_OFFSET             0x00000E00UL
146 #define INSTR_CM1_OFFSET               0x00000F00UL
147 
148 #define CM_CLKSEL_DPLL_MPU             (CKGEN_CM1_OFFSET + 0x006CUL)
149 
150 /**
151  *	Address offsets from the CM2 memory region to the top level clock control
152  *	registers.
153  */
154 #define INTRCONN_SOCKET_CM2_OFFSET     0x00000000UL
155 #define CKGEN_CM2_OFFSET               0x00000100UL
156 #define ALWAYS_ON_CM2_OFFSET           0x00000600UL
157 #define CORE_CM2_OFFSET                0x00000700UL
158 #define IVAHD_CM2_OFFSET               0x00000F00UL
159 #define CAM_CM2_OFFSET                 0x00001000UL
160 #define DSS_CM2_OFFSET                 0x00001100UL
161 #define SGX_CM2_OFFSET                 0x00001200UL
162 #define L3INIT_CM2_OFFSET              0x00001300UL
163 #define L4PER_CM2_OFFSET               0x00001400UL
164 #define RESTORE_CM2_OFFSET             0x00001E00UL
165 #define INSTR_CM2_OFFSET               0x00001F00UL
166 
167 #define CLKCTRL_MODULEMODE_MASK       0x00000003UL
168 #define CLKCTRL_MODULEMODE_DISABLE    0x00000000UL
169 #define CLKCTRL_MODULEMODE_AUTO       0x00000001UL
170 #define CLKCTRL_MODULEMODE_ENABLE     0x00000001UL
171 
172 #define CLKCTRL_IDLEST_MASK           0x00030000UL
173 #define CLKCTRL_IDLEST_ENABLED        0x00000000UL
174 #define CLKCTRL_IDLEST_WAKING         0x00010000UL
175 #define CLKCTRL_IDLEST_IDLE           0x00020000UL
176 #define CLKCTRL_IDLEST_DISABLED       0x00030000UL
177 
178 static struct resource_spec omap4_scm_res_spec[] = {
179 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },	/* Control memory window */
180 	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },	/* Control memory window */
181 	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },	/* Control memory window */
182 	{ -1, 0 }
183 };
184 
185 struct omap4_prcm_softc {
186 	struct resource	*sc_res[3];
187 };
188 
189 static struct omap4_prcm_softc *omap4_prcm_sc;
190 
191 static int omap4_clk_generic_activate(struct ti_clock_dev *clkdev);
192 static int omap4_clk_generic_deactivate(struct ti_clock_dev *clkdev);
193 static int omap4_clk_generic_accessible(struct ti_clock_dev *clkdev);
194 static int omap4_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
195 static int omap4_clk_generic_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
196 
197 static int omap4_clk_gptimer_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
198 static int omap4_clk_gptimer_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
199 
200 static int omap4_clk_hsmmc_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
201 static int omap4_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
202 
203 static int omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
204 static int omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev);
205 static int omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev);
206 static int omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev);
207 
208 static int omap4_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
209 static int omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
210 
211 /**
212  *	omap_clk_devmap - Array of clock devices available on OMAP4xxx devices
213  *
214  *	This map only defines which clocks are valid and the callback functions
215  *	for clock activate, deactivate, etc.  It is used by the top level omap_prcm
216  *	driver.
217  *
218  *	The actual details of the clocks (config registers, bit fields, sources,
219  *	etc) are in the private g_omap3_clk_details array below.
220  *
221  */
222 
223 #define OMAP4_GENERIC_CLOCK_DEV(i) \
224 	{	.id = (i), \
225 		.clk_activate = omap4_clk_generic_activate, \
226 		.clk_deactivate = omap4_clk_generic_deactivate, \
227 		.clk_set_source = omap4_clk_generic_set_source, \
228 		.clk_accessible = omap4_clk_generic_accessible, \
229 		.clk_get_source_freq = omap4_clk_generic_get_source_freq \
230 	}
231 
232 #define OMAP4_GPTIMER_CLOCK_DEV(i) \
233 	{	.id = (i), \
234 		.clk_activate = omap4_clk_generic_activate, \
235 		.clk_deactivate = omap4_clk_generic_deactivate, \
236 		.clk_set_source = omap4_clk_gptimer_set_source, \
237 		.clk_accessible = omap4_clk_generic_accessible, \
238 		.clk_get_source_freq = omap4_clk_gptimer_get_source_freq \
239 	}
240 
241 #define OMAP4_HSMMC_CLOCK_DEV(i) \
242 	{	.id = (i), \
243 		.clk_activate = omap4_clk_generic_activate, \
244 		.clk_deactivate = omap4_clk_generic_deactivate, \
245 		.clk_set_source = omap4_clk_hsmmc_set_source, \
246 		.clk_accessible = omap4_clk_generic_accessible, \
247 		.clk_get_source_freq = omap4_clk_hsmmc_get_source_freq \
248 	}
249 
250 #define OMAP4_HSUSBHOST_CLOCK_DEV(i) \
251 	{	.id = (i), \
252 		.clk_activate = omap4_clk_hsusbhost_activate, \
253 		.clk_deactivate = omap4_clk_hsusbhost_deactivate, \
254 		.clk_set_source = omap4_clk_hsusbhost_set_source, \
255 		.clk_accessible = omap4_clk_hsusbhost_accessible, \
256 		.clk_get_source_freq = NULL \
257 	}
258 
259 
260 struct ti_clock_dev ti_clk_devmap[] = {
261 
262 	/* System clocks */
263 	{	.id                  = SYS_CLK,
264 		.clk_activate        = NULL,
265 		.clk_deactivate      = NULL,
266 		.clk_set_source      = NULL,
267 		.clk_accessible      = NULL,
268 		.clk_get_source_freq = omap4_clk_get_sysclk_freq,
269 	},
270 	/* MPU (ARM) core clocks */
271 	{	.id                  = MPU_CLK,
272 		.clk_activate        = NULL,
273 		.clk_deactivate      = NULL,
274 		.clk_set_source      = NULL,
275 		.clk_accessible      = NULL,
276 		.clk_get_source_freq = omap4_clk_get_arm_fclk_freq,
277 	},
278 
279 
280 	/* UART device clocks */
281 	OMAP4_GENERIC_CLOCK_DEV(UART1_CLK),
282 	OMAP4_GENERIC_CLOCK_DEV(UART2_CLK),
283 	OMAP4_GENERIC_CLOCK_DEV(UART3_CLK),
284 	OMAP4_GENERIC_CLOCK_DEV(UART4_CLK),
285 
286 	/* Timer device source clocks */
287 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER1_CLK),
288 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER2_CLK),
289 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER3_CLK),
290 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER4_CLK),
291 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER5_CLK),
292 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER6_CLK),
293 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER7_CLK),
294 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER8_CLK),
295 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER9_CLK),
296 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER10_CLK),
297 	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER11_CLK),
298 
299 	/* MMC device clocks (MMC1 and MMC2 can have different input clocks) */
300 	OMAP4_HSMMC_CLOCK_DEV(MMC1_CLK),
301 	OMAP4_HSMMC_CLOCK_DEV(MMC2_CLK),
302 	OMAP4_GENERIC_CLOCK_DEV(MMC3_CLK),
303 	OMAP4_GENERIC_CLOCK_DEV(MMC4_CLK),
304 	OMAP4_GENERIC_CLOCK_DEV(MMC5_CLK),
305 
306 	/* USB HS (high speed TLL, EHCI and OHCI) */
307 	OMAP4_HSUSBHOST_CLOCK_DEV(USBTLL_CLK),
308 	OMAP4_HSUSBHOST_CLOCK_DEV(USBHSHOST_CLK),
309 	OMAP4_HSUSBHOST_CLOCK_DEV(USBFSHOST_CLK),
310 	OMAP4_HSUSBHOST_CLOCK_DEV(USBP1_PHY_CLK),
311 	OMAP4_HSUSBHOST_CLOCK_DEV(USBP2_PHY_CLK),
312 	OMAP4_HSUSBHOST_CLOCK_DEV(USBP1_UTMI_CLK),
313 	OMAP4_HSUSBHOST_CLOCK_DEV(USBP2_UTMI_CLK),
314 	OMAP4_HSUSBHOST_CLOCK_DEV(USBP1_HSIC_CLK),
315 	OMAP4_HSUSBHOST_CLOCK_DEV(USBP2_HSIC_CLK),
316 
317 	/* GPIO */
318 	OMAP4_GENERIC_CLOCK_DEV(GPIO1_CLK),
319 	OMAP4_GENERIC_CLOCK_DEV(GPIO2_CLK),
320 	OMAP4_GENERIC_CLOCK_DEV(GPIO3_CLK),
321 	OMAP4_GENERIC_CLOCK_DEV(GPIO4_CLK),
322 	OMAP4_GENERIC_CLOCK_DEV(GPIO5_CLK),
323 	OMAP4_GENERIC_CLOCK_DEV(GPIO6_CLK),
324 
325 	/* sDMA */
326 	OMAP4_GENERIC_CLOCK_DEV(SDMA_CLK),
327 
328 	/* I2C */
329 	OMAP4_GENERIC_CLOCK_DEV(I2C1_CLK),
330 	OMAP4_GENERIC_CLOCK_DEV(I2C2_CLK),
331 	OMAP4_GENERIC_CLOCK_DEV(I2C3_CLK),
332 	OMAP4_GENERIC_CLOCK_DEV(I2C4_CLK),
333 
334 	{  INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
335 };
336 
337 /**
338  *	omap4_clk_details - Stores details for all the different clocks supported
339  *
340  *	Whenever an operation on a clock is being performed (activated, deactivated,
341  *	etc) this array is looked up to find the correct register and bit(s) we
342  *	should be modifying.
343  *
344  */
345 struct omap4_clk_details {
346 	clk_ident_t id;
347 
348 	uint32_t    mem_region;
349 	uint32_t    clksel_reg;
350 
351 	int32_t     src_freq;
352 
353 	uint32_t    enable_mode;
354 };
355 
356 #define OMAP4_GENERIC_CLOCK_DETAILS(i, f, m, r, e) \
357 	{	.id = (i), \
358 		.mem_region = (m), \
359 		.clksel_reg = (r), \
360 		.src_freq = (f), \
361 		.enable_mode = (e), \
362 	}
363 
364 static struct omap4_clk_details g_omap4_clk_details[] = {
365 
366 	/* UART */
367 	OMAP4_GENERIC_CLOCK_DETAILS(UART1_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
368 		(L4PER_CM2_OFFSET + 0x0140), CLKCTRL_MODULEMODE_ENABLE),
369 	OMAP4_GENERIC_CLOCK_DETAILS(UART2_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
370 		(L4PER_CM2_OFFSET + 0x0148), CLKCTRL_MODULEMODE_ENABLE),
371 	OMAP4_GENERIC_CLOCK_DETAILS(UART3_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
372 		(L4PER_CM2_OFFSET + 0x0140), CLKCTRL_MODULEMODE_ENABLE),
373 	OMAP4_GENERIC_CLOCK_DETAILS(UART4_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
374 		(L4PER_CM2_OFFSET + 0x0148), CLKCTRL_MODULEMODE_ENABLE),
375 
376 	/* General purpose timers */
377 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER1_CLK,  -1, PRM_INSTANCE_MEM_REGION,
378 		(WKUP_CM_OFFSET + 0x040), CLKCTRL_MODULEMODE_ENABLE),
379 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER2_CLK,  -1, CM2_INSTANCE_MEM_REGION,
380 		(L4PER_CM2_OFFSET + 0x038), CLKCTRL_MODULEMODE_ENABLE),
381 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER3_CLK,  -1, CM2_INSTANCE_MEM_REGION,
382 		(L4PER_CM2_OFFSET + 0x040), CLKCTRL_MODULEMODE_ENABLE),
383 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER4_CLK,  -1, CM2_INSTANCE_MEM_REGION,
384 		(L4PER_CM2_OFFSET + 0x048), CLKCTRL_MODULEMODE_ENABLE),
385 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER5_CLK,  -1, CM1_INSTANCE_MEM_REGION,
386 		(ABE_CM1_OFFSET + 0x068), CLKCTRL_MODULEMODE_ENABLE),
387 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER6_CLK,  -1, CM1_INSTANCE_MEM_REGION,
388 		(ABE_CM1_OFFSET + 0x070), CLKCTRL_MODULEMODE_ENABLE),
389 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER7_CLK,  -1, CM1_INSTANCE_MEM_REGION,
390 		(ABE_CM1_OFFSET + 0x078), CLKCTRL_MODULEMODE_ENABLE),
391 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER8_CLK,  -1, CM1_INSTANCE_MEM_REGION,
392 		(ABE_CM1_OFFSET + 0x080), CLKCTRL_MODULEMODE_ENABLE),
393 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER9_CLK,  -1, CM2_INSTANCE_MEM_REGION,
394 		(L4PER_CM2_OFFSET + 0x050), CLKCTRL_MODULEMODE_ENABLE),
395 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER10_CLK, -1, CM2_INSTANCE_MEM_REGION,
396 		(L4PER_CM2_OFFSET + 0x028), CLKCTRL_MODULEMODE_ENABLE),
397 	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER11_CLK, -1, CM2_INSTANCE_MEM_REGION,
398 		(L4PER_CM2_OFFSET + 0x030), CLKCTRL_MODULEMODE_ENABLE),
399 
400 	/* HSMMC (MMC1 and MMC2 can have different input clocks) */
401 	OMAP4_GENERIC_CLOCK_DETAILS(MMC1_CLK, -1, CM2_INSTANCE_MEM_REGION,
402 		(L3INIT_CM2_OFFSET + 0x028), /*CLKCTRL_MODULEMODE_ENABLE*/2),
403 	OMAP4_GENERIC_CLOCK_DETAILS(MMC2_CLK, -1, CM2_INSTANCE_MEM_REGION,
404 		(L3INIT_CM2_OFFSET + 0x030), /*CLKCTRL_MODULEMODE_ENABLE*/2),
405 	OMAP4_GENERIC_CLOCK_DETAILS(MMC3_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
406 		(L4PER_CM2_OFFSET + 0x120), /*CLKCTRL_MODULEMODE_ENABLE*/2),
407 	OMAP4_GENERIC_CLOCK_DETAILS(MMC4_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
408 		(L4PER_CM2_OFFSET + 0x128), /*CLKCTRL_MODULEMODE_ENABLE*/2),
409 	OMAP4_GENERIC_CLOCK_DETAILS(MMC5_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
410 	       (L4PER_CM2_OFFSET + 0x160), /*CLKCTRL_MODULEMODE_ENABLE*/1),
411 
412 	/* GPIO modules */
413 	OMAP4_GENERIC_CLOCK_DETAILS(GPIO1_CLK, -1, PRM_INSTANCE_MEM_REGION,
414 		(WKUP_CM_OFFSET + 0x038), CLKCTRL_MODULEMODE_AUTO),
415 	OMAP4_GENERIC_CLOCK_DETAILS(GPIO2_CLK, -1, CM2_INSTANCE_MEM_REGION,
416 		(L4PER_CM2_OFFSET + 0x060), CLKCTRL_MODULEMODE_AUTO),
417 	OMAP4_GENERIC_CLOCK_DETAILS(GPIO3_CLK, -1, CM2_INSTANCE_MEM_REGION,
418 		(L4PER_CM2_OFFSET + 0x068), CLKCTRL_MODULEMODE_AUTO),
419 	OMAP4_GENERIC_CLOCK_DETAILS(GPIO4_CLK, -1, CM2_INSTANCE_MEM_REGION,
420 		(L4PER_CM2_OFFSET + 0x070), CLKCTRL_MODULEMODE_AUTO),
421 	OMAP4_GENERIC_CLOCK_DETAILS(GPIO5_CLK, -1, CM2_INSTANCE_MEM_REGION,
422 		(L4PER_CM2_OFFSET + 0x078), CLKCTRL_MODULEMODE_AUTO),
423 	OMAP4_GENERIC_CLOCK_DETAILS(GPIO6_CLK, -1, CM2_INSTANCE_MEM_REGION,
424 		(L4PER_CM2_OFFSET + 0x080), CLKCTRL_MODULEMODE_AUTO),
425 
426 	/* sDMA block */
427 	OMAP4_GENERIC_CLOCK_DETAILS(SDMA_CLK, -1, CM2_INSTANCE_MEM_REGION,
428 		(CORE_CM2_OFFSET + 0x300), CLKCTRL_MODULEMODE_AUTO),
429 
430 	/* I2C modules */
431 	OMAP4_GENERIC_CLOCK_DETAILS(I2C1_CLK, -1, CM2_INSTANCE_MEM_REGION,
432 		(L4PER_CM2_OFFSET + 0x0A0), CLKCTRL_MODULEMODE_ENABLE),
433 	OMAP4_GENERIC_CLOCK_DETAILS(I2C2_CLK, -1, CM2_INSTANCE_MEM_REGION,
434 		(L4PER_CM2_OFFSET + 0x0A8), CLKCTRL_MODULEMODE_ENABLE),
435 	OMAP4_GENERIC_CLOCK_DETAILS(I2C3_CLK, -1, CM2_INSTANCE_MEM_REGION,
436 		(L4PER_CM2_OFFSET + 0x0B0), CLKCTRL_MODULEMODE_ENABLE),
437 	OMAP4_GENERIC_CLOCK_DETAILS(I2C4_CLK, -1, CM2_INSTANCE_MEM_REGION,
438 		(L4PER_CM2_OFFSET + 0x0B8), CLKCTRL_MODULEMODE_ENABLE),
439 
440 	{ INVALID_CLK_IDENT, 0, 0, 0, 0 },
441 };
442 
443 /**
444  *	MAX_MODULE_ENABLE_WAIT - the number of loops to wait for the module to come
445  *	alive.
446  *
447  */
448 #define MAX_MODULE_ENABLE_WAIT    100
449 
450 /**
451  *	ARRAY_SIZE - Macro to return the number of elements in a static const array.
452  *
453  */
454 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
455 
456 /**
457  *	omap4_clk_details - writes a 32-bit value to one of the timer registers
458  *	@timer: Timer device context
459  *	@off: The offset of a register from the timer register address range
460  *	@val: The value to write into the register
461  *
462  *
463  *	RETURNS:
464  *	nothing
465  */
466 static struct omap4_clk_details*
467 omap4_clk_details(clk_ident_t id)
468 {
469 	struct omap4_clk_details *walker;
470 
471 	for (walker = g_omap4_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
472 		if (id == walker->id)
473 			return (walker);
474 	}
475 
476 	return NULL;
477 }
478 
479 /**
480  *	omap4_clk_generic_activate - checks if a module is accessible
481  *	@module: identifier for the module to check, see omap3_prcm.h for a list
482  *	         of possible modules.
483  *	         Example: OMAP3_MODULE_MMC1
484  *
485  *
486  *
487  *	LOCKING:
488  *	Inherits the locks from the omap_prcm driver, no internal locking.
489  *
490  *	RETURNS:
491  *	Returns 0 on success or a positive error code on failure.
492  */
493 static int
494 omap4_clk_generic_activate(struct ti_clock_dev *clkdev)
495 {
496 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
497 	struct omap4_clk_details* clk_details;
498 	struct resource* clk_mem_res;
499 	uint32_t clksel;
500 	unsigned int i;
501 
502 	if (sc == NULL)
503 		return ENXIO;
504 
505 	clk_details = omap4_clk_details(clkdev->id);
506 
507 	if (clk_details == NULL)
508 		return (ENXIO);
509 
510 	clk_mem_res = sc->sc_res[clk_details->mem_region];
511 
512 	if (clk_mem_res == NULL)
513 		return (EINVAL);
514 
515 	/* All the 'generic' clocks have a CLKCTRL register which is more or less
516 	 * generic - the have at least two fielda called MODULEMODE and IDLEST.
517 	 */
518 	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
519 	clksel &= ~CLKCTRL_MODULEMODE_MASK;
520 	clksel |=  clk_details->enable_mode;
521 	bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
522 
523 	/* Now poll on the IDLEST register to tell us if the module has come up.
524 	 * TODO: We need to take into account the parent clocks.
525 	 */
526 
527 	/* Try MAX_MODULE_ENABLE_WAIT number of times to check if enabled */
528 	for (i = 0; i < MAX_MODULE_ENABLE_WAIT; i++) {
529 		clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
530 		if ((clksel & CLKCTRL_IDLEST_MASK) == CLKCTRL_IDLEST_ENABLED)
531 			break;
532 		DELAY(10);
533 	}
534 
535 	/* Check the enabled state */
536 	if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED) {
537 		printf("Error: failed to enable module with clock %d\n", clkdev->id);
538 		printf("Error: 0x%08x => 0x%08x\n", clk_details->clksel_reg, clksel);
539 		return (ETIMEDOUT);
540 	}
541 
542 	return (0);
543 }
544 
545 /**
546  *	omap4_clk_generic_deactivate - checks if a module is accessible
547  *	@module: identifier for the module to check, see omap3_prcm.h for a list
548  *	         of possible modules.
549  *	         Example: OMAP3_MODULE_MMC1
550  *
551  *
552  *
553  *	LOCKING:
554  *	Inherits the locks from the omap_prcm driver, no internal locking.
555  *
556  *	RETURNS:
557  *	Returns 0 on success or a positive error code on failure.
558  */
559 static int
560 omap4_clk_generic_deactivate(struct ti_clock_dev *clkdev)
561 {
562 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
563 	struct omap4_clk_details* clk_details;
564 	struct resource* clk_mem_res;
565 	uint32_t clksel;
566 
567 	if (sc == NULL)
568 		return ENXIO;
569 
570 	clk_details = omap4_clk_details(clkdev->id);
571 
572 	if (clk_details == NULL)
573 		return (ENXIO);
574 
575 	clk_mem_res = sc->sc_res[clk_details->mem_region];
576 
577 	if (clk_mem_res == NULL)
578 		return (EINVAL);
579 
580 	/* All the 'generic' clocks have a CLKCTRL register which is more or less
581 	 * generic - the have at least two fielda called MODULEMODE and IDLEST.
582 	 */
583 	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
584 	clksel &= ~CLKCTRL_MODULEMODE_MASK;
585 	clksel |=  CLKCTRL_MODULEMODE_DISABLE;
586 	bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
587 
588 	return (0);
589 }
590 
591 /**
592  *	omap4_clk_generic_set_source - checks if a module is accessible
593  *	@module: identifier for the module to check, see omap3_prcm.h for a list
594  *	         of possible modules.
595  *	         Example: OMAP3_MODULE_MMC1
596  *
597  *
598  *
599  *	LOCKING:
600  *	Inherits the locks from the omap_prcm driver, no internal locking.
601  *
602  *	RETURNS:
603  *	Returns 0 on success or a positive error code on failure.
604  */
605 static int
606 omap4_clk_generic_set_source(struct ti_clock_dev *clkdev,
607                              clk_src_t clksrc)
608 {
609 
610 	return (0);
611 }
612 
613 /**
614  *	omap4_clk_generic_accessible - checks if a module is accessible
615  *	@module: identifier for the module to check, see omap3_prcm.h for a list
616  *	         of possible modules.
617  *	         Example: OMAP3_MODULE_MMC1
618  *
619  *
620  *
621  *	LOCKING:
622  *	Inherits the locks from the omap_prcm driver, no internal locking.
623  *
624  *	RETURNS:
625  *	Returns 0 on success or a negative error code on failure.
626  */
627 static int
628 omap4_clk_generic_accessible(struct ti_clock_dev *clkdev)
629 {
630 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
631 	struct omap4_clk_details* clk_details;
632 	struct resource* clk_mem_res;
633 	uint32_t clksel;
634 
635 	if (sc == NULL)
636 		return ENXIO;
637 
638 	clk_details = omap4_clk_details(clkdev->id);
639 
640 	if (clk_details == NULL)
641 		return (ENXIO);
642 
643 	clk_mem_res = sc->sc_res[clk_details->mem_region];
644 
645 	if (clk_mem_res == NULL)
646 		return (EINVAL);
647 
648 	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
649 
650 	/* Check the enabled state */
651 	if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED)
652 		return (0);
653 
654 	return (1);
655 }
656 
657 /**
658  *	omap4_clk_generic_get_source_freq - checks if a module is accessible
659  *	@module: identifier for the module to check, see omap3_prcm.h for a list
660  *	         of possible modules.
661  *	         Example: OMAP3_MODULE_MMC1
662  *
663  *
664  *
665  *	LOCKING:
666  *	Inherits the locks from the omap_prcm driver, no internal locking.
667  *
668  *	RETURNS:
669  *	Returns 0 on success or a negative error code on failure.
670  */
671 static int
672 omap4_clk_generic_get_source_freq(struct ti_clock_dev *clkdev,
673                                   unsigned int *freq
674                                   )
675 {
676 	struct omap4_clk_details* clk_details = omap4_clk_details(clkdev->id);
677 
678 	if (clk_details == NULL)
679 		return (ENXIO);
680 
681 	/* Simply return the stored frequency */
682 	if (freq)
683 		*freq = (unsigned int)clk_details->src_freq;
684 
685 	return (0);
686 }
687 
688 
689 /**
690  *	omap4_clk_gptimer_set_source - checks if a module is accessible
691  *	@module: identifier for the module to check, see omap3_prcm.h for a list
692  *	         of possible modules.
693  *	         Example: OMAP3_MODULE_MMC1
694  *
695  *
696  *
697  *	LOCKING:
698  *	Inherits the locks from the omap_prcm driver, no internal locking.
699  *
700  *	RETURNS:
701  *	Returns 0 on success or a negative error code on failure.
702  */
703 static int
704 omap4_clk_gptimer_set_source(struct ti_clock_dev *clkdev,
705                              clk_src_t clksrc)
706 {
707 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
708 	struct omap4_clk_details* clk_details;
709 	struct resource* clk_mem_res;
710 
711 	if (sc == NULL)
712 		return ENXIO;
713 
714 	clk_details = omap4_clk_details(clkdev->id);
715 
716 	if (clk_details == NULL)
717 		return (ENXIO);
718 
719 	clk_mem_res = sc->sc_res[clk_details->mem_region];
720 
721 	if (clk_mem_res == NULL)
722 		return (EINVAL);
723 
724 	/* TODO: Implement */
725 
726 	return (0);
727 }
728 
729 /**
730  *	omap4_clk_gptimer_get_source_freq - checks if a module is accessible
731  *	@module: identifier for the module to check, see omap3_prcm.h for a list
732  *	         of possible modules.
733  *	         Example: OMAP3_MODULE_MMC1
734  *
735  *
736  *
737  *	LOCKING:
738  *	Inherits the locks from the omap_prcm driver, no internal locking.
739  *
740  *	RETURNS:
741  *	Returns 0 on success or a negative error code on failure.
742  */
743 static int
744 omap4_clk_gptimer_get_source_freq(struct ti_clock_dev *clkdev,
745                                   unsigned int *freq
746                                   )
747 {
748 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
749 	struct omap4_clk_details* clk_details;
750 	struct resource* clk_mem_res;
751 	uint32_t clksel;
752 	unsigned int src_freq;
753 
754 	if (sc == NULL)
755 		return ENXIO;
756 
757 	clk_details = omap4_clk_details(clkdev->id);
758 
759 	if (clk_details == NULL)
760 		return (ENXIO);
761 
762 	clk_mem_res = sc->sc_res[clk_details->mem_region];
763 
764 	if (clk_mem_res == NULL)
765 		return (EINVAL);
766 
767 	/* Need to read the CLKSEL field to determine the clock source */
768 	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
769 	if (clksel & (0x1UL << 24))
770 		src_freq = FREQ_32KHZ;
771 	else
772 		omap4_clk_get_sysclk_freq(NULL, &src_freq);
773 
774 	/* Return the frequency */
775 	if (freq)
776 		*freq = src_freq;
777 
778 	return (0);
779 }
780 
781 /**
782  *	omap4_clk_hsmmc_set_source - sets the source clock (freq)
783  *	@clkdev: pointer to the clockdev structure (id field will contain clock id)
784  *
785  *	The MMC 1 and 2 clocks can be source from either a 64MHz or 96MHz clock.
786  *
787  *	LOCKING:
788  *	Inherits the locks from the omap_prcm driver, no internal locking.
789  *
790  *	RETURNS:
791  *	Returns 0 on success or a negative error code on failure.
792  */
793 static int
794 omap4_clk_hsmmc_set_source(struct ti_clock_dev *clkdev,
795                            clk_src_t clksrc)
796 {
797 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
798 	struct omap4_clk_details* clk_details;
799 	struct resource* clk_mem_res;
800 	uint32_t clksel;
801 
802 	if (sc == NULL)
803 		return ENXIO;
804 
805 	clk_details = omap4_clk_details(clkdev->id);
806 
807 	if (clk_details == NULL)
808 		return (ENXIO);
809 
810 	clk_mem_res = sc->sc_res[clk_details->mem_region];
811 
812 	if (clk_mem_res == NULL)
813 		return (EINVAL);
814 
815 	/* For MMC modules 3, 4 & 5 you can't change the freq, it's always 48MHz */
816 	if ((clkdev->id == MMC3_CLK) || (clkdev->id == MMC4_CLK) ||
817 	    (clkdev->id == MMC5_CLK)) {
818 		if (clksrc != F48MHZ_CLK)
819 			return (EINVAL);
820 		return 0;
821 	}
822 
823 
824 	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
825 
826 	/* Bit 24 is set if 96MHz clock or cleared for 64MHz clock */
827 	if (clksrc == F64MHZ_CLK)
828 		clksel &= ~(0x1UL << 24);
829 	else if (clksrc == F96MHZ_CLK)
830 		clksel |= (0x1UL << 24);
831 	else
832 		return (EINVAL);
833 
834 	bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
835 
836 	return (0);
837 }
838 
839 /**
840  *	omap4_clk_hsmmc_get_source_freq - checks if a module is accessible
841  *	@clkdev: pointer to the clockdev structure (id field will contain clock id)
842  *
843  *
844  *
845  *	LOCKING:
846  *	Inherits the locks from the omap_prcm driver, no internal locking.
847  *
848  *	RETURNS:
849  *	Returns 0 on success or a negative error code on failure.
850  */
851 static int
852 omap4_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,
853                                 unsigned int *freq
854                                 )
855 {
856 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
857 	struct omap4_clk_details* clk_details;
858 	struct resource* clk_mem_res;
859 	uint32_t clksel;
860 	unsigned int src_freq;
861 
862 	if (sc == NULL)
863 		return ENXIO;
864 
865 	clk_details = omap4_clk_details(clkdev->id);
866 
867 	if (clk_details == NULL)
868 		return (ENXIO);
869 
870 	clk_mem_res = sc->sc_res[clk_details->mem_region];
871 
872 	if (clk_mem_res == NULL)
873 		return (EINVAL);
874 
875 	switch (clkdev->id) {
876 	case MMC1_CLK:
877 	case MMC2_CLK:
878 		/* Need to read the CLKSEL field to determine the clock source */
879 		clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
880 		if (clksel & (0x1UL << 24))
881 			src_freq = FREQ_96MHZ;
882 		else
883 			src_freq = FREQ_64MHZ;
884 		break;
885 	case MMC3_CLK:
886 	case MMC4_CLK:
887 	case MMC5_CLK:
888 		src_freq = FREQ_48MHZ;
889 		break;
890 	default:
891 		return (EINVAL);
892 	}
893 
894 	/* Return the frequency */
895 	if (freq)
896 		*freq = src_freq;
897 
898 	return (0);
899 }
900 
901 /**
902  *	omap4_clk_get_sysclk_freq - gets the sysclk frequency
903  *	@sc: pointer to the clk module/device context
904  *
905  *	Read the clocking information from the power-control/boot-strap registers,
906  *  and stored in two global variables.
907  *
908  *	RETURNS:
909  *	nothing, values are saved in global variables
910  */
911 static int
912 omap4_clk_get_sysclk_freq(struct ti_clock_dev *clkdev,
913                           unsigned int *freq)
914 {
915 	uint32_t clksel;
916 	uint32_t sysclk;
917 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
918 
919 	if (sc == NULL)
920 		return ENXIO;
921 
922 	/* Read the input clock freq from the configuration register (CM_SYS_CLKSEL) */
923 	clksel = bus_read_4(sc->sc_res[PRM_INSTANCE_MEM_REGION], CM_SYS_CLKSEL_OFFSET);
924 	switch (clksel & 0x7) {
925 	case 0x1:
926 		/* 12Mhz */
927 		sysclk = 12000000;
928 		break;
929 	case 0x3:
930 		/* 16.8Mhz */
931 		sysclk = 16800000;
932 		break;
933 	case 0x4:
934 		/* 19.2Mhz */
935 		sysclk = 19200000;
936 		break;
937 	case 0x5:
938 		/* 26Mhz */
939 		sysclk = 26000000;
940 		break;
941 	case 0x7:
942 		/* 38.4Mhz */
943 		sysclk = 38400000;
944 		break;
945 	default:
946 		panic("%s: Invalid clock freq", __func__);
947 	}
948 
949 	/* Return the value */
950 	if (freq)
951 		*freq = sysclk;
952 
953 	return (0);
954 }
955 
956 /**
957  *	omap4_clk_get_arm_fclk_freq - gets the MPU clock frequency
958  *	@clkdev: ignored
959  *	@freq: pointer which upon return will contain the freq in hz
960  *	@mem_res: array of allocated memory resources
961  *
962  *	Reads the frequency setting information registers and returns the value
963  *	in the freq variable.
964  *
965  *	RETURNS:
966  *	returns 0 on success, a positive error code on failure.
967  */
968 static int
969 omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev,
970                             unsigned int *freq)
971 {
972 	uint32_t clksel;
973 	uint32_t pll_mult, pll_div;
974 	uint32_t mpuclk, sysclk;
975 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
976 
977 	if (sc == NULL)
978 		return ENXIO;
979 
980 	/* Read the clksel register which contains the DPLL multiple and divide
981 	 * values.  These are applied to the sysclk.
982 	 */
983 	clksel = bus_read_4(sc->sc_res[CM1_INSTANCE_MEM_REGION], CM_CLKSEL_DPLL_MPU);
984 
985 	pll_mult = ((clksel >> 8) & 0x7ff);
986 	pll_div = (clksel & 0x7f) + 1;
987 
988 
989 	/* Get the system clock freq */
990 	omap4_clk_get_sysclk_freq(NULL, &sysclk);
991 
992 
993 	/* Calculate the MPU freq */
994 	mpuclk = (sysclk * pll_mult) / pll_div;
995 
996 	/* Return the value */
997 	if (freq)
998 		*freq = mpuclk;
999 
1000 	return (0);
1001 }
1002 
1003 /**
1004  *	omap4_clk_hsusbhost_activate - activates the USB clocks for the given module
1005  *	@clkdev: pointer to the clock device structure.
1006  *	@mem_res: array of memory resouces allocated by the top level PRCM driver.
1007  *
1008  *	The USB clocking setup seems to be a bit more tricky than the other modules,
1009  *	to start with the clocking diagram for the HS host module shows 13 different
1010  *	clocks.  So to try and make it easier to follow the clocking activation
1011  *	and deactivation is handled in it's own set of callbacks.
1012  *
1013  *	LOCKING:
1014  *	Inherits the locks from the omap_prcm driver, no internal locking.
1015  *
1016  *	RETURNS:
1017  *	Returns 0 on success or a positive error code on failure.
1018  */
1019 
1020 struct dpll_param {
1021 	unsigned int m;
1022 	unsigned int n;
1023 	unsigned int m2;
1024 	unsigned int m3;
1025 	unsigned int m4;
1026 	unsigned int m5;
1027 	unsigned int m6;
1028 	unsigned int m7;
1029 };
1030 /* USB parameters */
1031 struct dpll_param usb_dpll_param[7] = {
1032 	/* 12M values */
1033 	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1034 	/* 13M values */
1035 	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1036 	/* 16.8M values */
1037 	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1038 	/* 19.2M values */
1039 	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1040 	/* 26M values */
1041 	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1042 	/* 27M values */
1043 	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1044 	/* 38.4M values */
1045 #ifdef CONFIG_OMAP4_SDC
1046 	{0x32, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0},
1047 #else
1048 	{0x32, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0},
1049 #endif
1050 };
1051 static int
1052 omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev)
1053 {
1054 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
1055 	struct resource* clk_mem_res;
1056 	uint32_t clksel_reg_off;
1057 	uint32_t clksel;
1058 	unsigned int i;
1059 
1060 	if (sc == NULL)
1061 		return ENXIO;
1062 
1063 	switch (clkdev->id) {
1064 	case USBTLL_CLK:
1065 		/* For the USBTLL module we need to enable the following clocks:
1066 		 *  - INIT_L4_ICLK  (will be enabled by bootloader)
1067 		 *  - TLL_CH0_FCLK
1068 		 *  - TLL_CH1_FCLK
1069 		 */
1070 
1071 		/* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
1072 		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1073 		clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
1074 
1075 		/* Enable the module and also enable the optional func clocks for
1076 		 * channels 0 & 1 (is this needed ?)
1077 		 */
1078 		clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1079 		clksel &= ~CLKCTRL_MODULEMODE_MASK;
1080 		clksel |=  CLKCTRL_MODULEMODE_ENABLE;
1081 
1082 		clksel |= (0x1 << 8); /* USB-HOST optional clock: USB_CH0_CLK */
1083 		clksel |= (0x1 << 9); /* USB-HOST optional clock: USB_CH1_CLK */
1084 		break;
1085 
1086 	case USBHSHOST_CLK:
1087 	case USBP1_PHY_CLK:
1088 	case USBP2_PHY_CLK:
1089 	case USBP1_UTMI_CLK:
1090 	case USBP2_UTMI_CLK:
1091 	case USBP1_HSIC_CLK:
1092 	case USBP2_HSIC_CLK:
1093 		/* For the USB HS HOST module we need to enable the following clocks:
1094 		 *  - INIT_L4_ICLK     (will be enabled by bootloader)
1095 		 *  - INIT_L3_ICLK     (will be enabled by bootloader)
1096 		 *  - INIT_48MC_FCLK
1097 		 *  - UTMI_ROOT_GFCLK  (UTMI only, create a new clock for that ?)
1098 		 *  - UTMI_P1_FCLK     (UTMI only, create a new clock for that ?)
1099 		 *  - UTMI_P2_FCLK     (UTMI only, create a new clock for that ?)
1100 		 *  - HSIC_P1_60       (HSIC only, create a new clock for that ?)
1101 		 *  - HSIC_P1_480      (HSIC only, create a new clock for that ?)
1102 		 *  - HSIC_P2_60       (HSIC only, create a new clock for that ?)
1103 		 *  - HSIC_P2_480      (HSIC only, create a new clock for that ?)
1104 		 */
1105 
1106 		/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
1107 		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1108 		clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
1109 		clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1110 		/* Enable the module and also enable the optional func clocks */
1111 		if (clkdev->id == USBHSHOST_CLK) {
1112 			clksel &= ~CLKCTRL_MODULEMODE_MASK;
1113 			clksel |=  /*CLKCTRL_MODULEMODE_ENABLE*/2;
1114 
1115 			clksel |= (0x1 << 15); /* USB-HOST clock control: FUNC48MCLK */
1116 		}
1117 
1118 		else if (clkdev->id == USBP1_UTMI_CLK)
1119 			clksel |= (0x1 << 8);  /* UTMI_P1_CLK */
1120 		else if (clkdev->id == USBP2_UTMI_CLK)
1121 			clksel |= (0x1 << 9);  /* UTMI_P2_CLK */
1122 
1123 		else if (clkdev->id == USBP1_HSIC_CLK)
1124 			clksel |= (0x5 << 11);  /* HSIC60M_P1_CLK + HSIC480M_P1_CLK */
1125 		else if (clkdev->id == USBP2_HSIC_CLK)
1126 			clksel |= (0x5 << 12);  /* HSIC60M_P2_CLK + HSIC480M_P2_CLK */
1127 
1128 		break;
1129 
1130 	default:
1131 		return (EINVAL);
1132 	}
1133 
1134 	bus_write_4(clk_mem_res, clksel_reg_off, clksel);
1135 
1136 	/* Try MAX_MODULE_ENABLE_WAIT number of times to check if enabled */
1137 	for (i = 0; i < MAX_MODULE_ENABLE_WAIT; i++) {
1138 		clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1139 		if ((clksel & CLKCTRL_IDLEST_MASK) == CLKCTRL_IDLEST_ENABLED)
1140 			break;
1141 	}
1142 
1143 	/* Check the enabled state */
1144 	if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED) {
1145 		printf("Error: HERE failed to enable module with clock %d\n", clkdev->id);
1146 		printf("Error: 0x%08x => 0x%08x\n", clksel_reg_off, clksel);
1147 		return (ETIMEDOUT);
1148 	}
1149 
1150 	return (0);
1151 }
1152 
1153 /**
1154  *	omap4_clk_generic_deactivate - checks if a module is accessible
1155  *	@clkdev: pointer to the clock device structure.
1156  *	@mem_res: array of memory resouces allocated by the top level PRCM driver.
1157  *
1158  *
1159  *
1160  *	LOCKING:
1161  *	Inherits the locks from the omap_prcm driver, no internal locking.
1162  *
1163  *	RETURNS:
1164  *	Returns 0 on success or a positive error code on failure.
1165  */
1166 static int
1167 omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev)
1168 {
1169 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
1170 	struct resource* clk_mem_res;
1171 	uint32_t clksel_reg_off;
1172 	uint32_t clksel;
1173 
1174 	if (sc == NULL)
1175 		return ENXIO;
1176 
1177 	switch (clkdev->id) {
1178 	case USBTLL_CLK:
1179 		/* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
1180 		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1181 		clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
1182 
1183 		clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1184 		clksel &= ~CLKCTRL_MODULEMODE_MASK;
1185 		clksel |=  CLKCTRL_MODULEMODE_DISABLE;
1186 		break;
1187 
1188 	case USBHSHOST_CLK:
1189 	case USBP1_PHY_CLK:
1190 	case USBP2_PHY_CLK:
1191 	case USBP1_UTMI_CLK:
1192 	case USBP2_UTMI_CLK:
1193 	case USBP1_HSIC_CLK:
1194 	case USBP2_HSIC_CLK:
1195 		/* For the USB HS HOST module we need to enable the following clocks:
1196 		 *  - INIT_L4_ICLK     (will be enabled by bootloader)
1197 		 *  - INIT_L3_ICLK     (will be enabled by bootloader)
1198 		 *  - INIT_48MC_FCLK
1199 		 *  - UTMI_ROOT_GFCLK  (UTMI only, create a new clock for that ?)
1200 		 *  - UTMI_P1_FCLK     (UTMI only, create a new clock for that ?)
1201 		 *  - UTMI_P2_FCLK     (UTMI only, create a new clock for that ?)
1202 		 *  - HSIC_P1_60       (HSIC only, create a new clock for that ?)
1203 		 *  - HSIC_P1_480      (HSIC only, create a new clock for that ?)
1204 		 *  - HSIC_P2_60       (HSIC only, create a new clock for that ?)
1205 		 *  - HSIC_P2_480      (HSIC only, create a new clock for that ?)
1206 		 */
1207 
1208 		/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
1209 		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1210 		clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
1211 		clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1212 
1213 		/* Enable the module and also enable the optional func clocks */
1214 		if (clkdev->id == USBHSHOST_CLK) {
1215 			clksel &= ~CLKCTRL_MODULEMODE_MASK;
1216 			clksel |=  CLKCTRL_MODULEMODE_DISABLE;
1217 
1218 			clksel &= ~(0x1 << 15); /* USB-HOST clock control: FUNC48MCLK */
1219 		}
1220 
1221 		else if (clkdev->id == USBP1_UTMI_CLK)
1222 			clksel &= ~(0x1 << 8);  /* UTMI_P1_CLK */
1223 		else if (clkdev->id == USBP2_UTMI_CLK)
1224 			clksel &= ~(0x1 << 9);  /* UTMI_P2_CLK */
1225 
1226 		else if (clkdev->id == USBP1_HSIC_CLK)
1227 			clksel &= ~(0x5 << 11);  /* HSIC60M_P1_CLK + HSIC480M_P1_CLK */
1228 		else if (clkdev->id == USBP2_HSIC_CLK)
1229 			clksel &= ~(0x5 << 12);  /* HSIC60M_P2_CLK + HSIC480M_P2_CLK */
1230 
1231 		break;
1232 
1233 	default:
1234 		return (EINVAL);
1235 	}
1236 
1237 	bus_write_4(clk_mem_res, clksel_reg_off, clksel);
1238 
1239 	return (0);
1240 }
1241 
1242 /**
1243  *	omap4_clk_hsusbhost_accessible - checks if a module is accessible
1244  *	@clkdev: pointer to the clock device structure.
1245  *	@mem_res: array of memory resouces allocated by the top level PRCM driver.
1246  *
1247  *
1248  *
1249  *	LOCKING:
1250  *	Inherits the locks from the omap_prcm driver, no internal locking.
1251  *
1252  *	RETURNS:
1253  *	Returns 0 if module is not enable, 1 if module is enabled or a negative
1254  *	error code on failure.
1255  */
1256 static int
1257 omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev)
1258 {
1259 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
1260 	struct resource* clk_mem_res;
1261 	uint32_t clksel_reg_off;
1262 	uint32_t clksel;
1263 
1264 	if (sc == NULL)
1265 		return ENXIO;
1266 
1267 	if (clkdev->id == USBTLL_CLK) {
1268 		/* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
1269 		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1270 		clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
1271 	}
1272 	else if (clkdev->id == USBHSHOST_CLK) {
1273 		/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
1274 		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1275 		clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
1276 	}
1277 	else {
1278 		return (EINVAL);
1279 	}
1280 
1281 	clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1282 
1283 	/* Check the enabled state */
1284 	if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED)
1285 		return (0);
1286 
1287 	return (1);
1288 }
1289 
1290 /**
1291  *	omap4_clk_hsusbhost_set_source - sets the source clocks
1292  *	@clkdev: pointer to the clock device structure.
1293  *	@clksrc: the clock source ID for the given clock.
1294  *	@mem_res: array of memory resouces allocated by the top level PRCM driver.
1295  *
1296  *
1297  *
1298  *	LOCKING:
1299  *	Inherits the locks from the omap_prcm driver, no internal locking.
1300  *
1301  *	RETURNS:
1302  *	Returns 0 if sucessful otherwise a negative error code on failure.
1303  */
1304 static int
1305 omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev,
1306                                clk_src_t clksrc)
1307 {
1308 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
1309 	struct resource* clk_mem_res;
1310 	uint32_t clksel_reg_off;
1311 	uint32_t clksel;
1312 	unsigned int bit;
1313 
1314 	if (sc == NULL)
1315 		return ENXIO;
1316 
1317 	if (clkdev->id == USBP1_PHY_CLK)
1318 		bit = 24;
1319 	else if (clkdev->id != USBP2_PHY_CLK)
1320 		bit = 25;
1321 	else
1322 		return (EINVAL);
1323 
1324 	/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
1325 	clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1326 	clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
1327 	clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1328 
1329 	/* Set the clock source to either external or internal */
1330 	if (clksrc == EXT_CLK)
1331 		clksel |= (0x1 << bit);
1332 	else
1333 		clksel &= ~(0x1 << bit);
1334 
1335 	bus_write_4(clk_mem_res, clksel_reg_off, clksel);
1336 
1337 	return (0);
1338 }
1339 
1340 #define PRM_RSTCTRL		0x1b00
1341 #define PRM_RSTCTRL_RESET	0x2
1342 
1343 static void
1344 omap4_prcm_reset(void)
1345 {
1346 	struct omap4_prcm_softc *sc = omap4_prcm_sc;
1347 	bus_write_4(sc->sc_res[0], PRM_RSTCTRL,
1348 	    bus_read_4(sc->sc_res[0], PRM_RSTCTRL) | PRM_RSTCTRL_RESET);
1349 	bus_read_4(sc->sc_res[0], PRM_RSTCTRL);
1350 }
1351 
1352 /**
1353  *	omap4_prcm_probe - probe function for the driver
1354  *	@dev: prcm device handle
1355  *
1356  *	Simply sets the name of the driver module.
1357  *
1358  *	LOCKING:
1359  *	None
1360  *
1361  *	RETURNS:
1362  *	Always returns 0
1363  */
1364 static int
1365 omap4_prcm_probe(device_t dev)
1366 {
1367 	if (!ofw_bus_is_compatible(dev, "ti,omap4_prcm"))
1368 		return (ENXIO);
1369 
1370 	device_set_desc(dev, "TI OMAP Power, Reset and Clock Management");
1371 	return (0);
1372 }
1373 
1374 /**
1375  *	omap_prcm_attach - attach function for the driver
1376  *	@dev: prcm device handle
1377  *
1378  *	Allocates and sets up the driver context, this simply entails creating a
1379  *	bus mappings for the PRCM register set.
1380  *
1381  *	LOCKING:
1382  *	None
1383  *
1384  *	RETURNS:
1385  *	Always returns 0
1386  */
1387 static int
1388 omap4_prcm_attach(device_t dev)
1389 {
1390 	struct omap4_prcm_softc *sc = device_get_softc(dev);
1391 
1392 	if (bus_alloc_resources(dev, omap4_scm_res_spec, sc->sc_res)) {
1393 		device_printf(dev, "could not allocate resources\n");
1394 		return (ENXIO);
1395 	}
1396 
1397 	omap4_prcm_sc = sc;
1398 	ti_cpu_reset = omap4_prcm_reset;
1399 
1400 	return (0);
1401 }
1402 
1403 static device_method_t omap4_prcm_methods[] = {
1404 	DEVMETHOD(device_probe, omap4_prcm_probe),
1405 	DEVMETHOD(device_attach, omap4_prcm_attach),
1406 	{0, 0},
1407 };
1408 
1409 static driver_t omap4_prcm_driver = {
1410 	"omap4_prcm",
1411 	omap4_prcm_methods,
1412 	sizeof(struct omap4_prcm_softc),
1413 };
1414 
1415 static devclass_t omap4_prcm_devclass;
1416 
1417 DRIVER_MODULE(omap4_prcm, simplebus, omap4_prcm_driver, omap4_prcm_devclass, 0, 0);
1418 MODULE_VERSION(omap4_prcm, 1);
1419