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