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