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