3 * Ben Gray <ben.r.gray@gmail.com>.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the company nor the name of the author may be used to
15 * endorse or promote products derived from this software without specific
16 * prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
38 #include <sys/resource.h>
41 #include <sys/malloc.h>
43 #include <machine/bus.h>
44 #include <machine/cpu.h>
45 #include <machine/cpufunc.h>
46 #include <machine/resource.h>
47 #include <machine/intr.h>
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>
54 #include <dev/fdt/fdt_common.h>
55 #include <dev/ofw/openfirm.h>
56 #include <dev/ofw/ofw_bus.h>
57 #include <dev/ofw/ofw_bus_subr.h>
60 * This file defines the clock configuration for the OMAP4xxx series of
63 * How This is Suppose to Work
64 * ===========================
65 * - There is a top level omap_prcm module that defines all OMAP SoC drivers
66 * should use to enable/disable the system clocks regardless of the version
67 * of OMAP device they are running on. This top level PRCM module is just
68 * a thin shim to chip specific functions that perform the donkey work of
69 * configuring the clock - this file is the 'donkey' for OMAP44xx devices.
71 * - The key bit in this file is the omap_clk_devmap array, it's
72 * used by the omap_prcm driver to determine what clocks are valid and which
73 * functions to call to manipulate them.
75 * - In essence you just need to define some callbacks for each of the
76 * clocks and then you're done.
78 * - The other thing that is worth noting is that when the omap_prcm device
79 * is registered you typically pass in some memory ranges which are the
80 * SYS_MEMORY resources. These resources are in turn allocated using
81 * bus_allocate_resources(...) and the resource handles are passed to all
82 * individual clock callback handlers.
86 * OMAP4 devices are different from the previous OMAP3 devices in that there
87 * is no longer a separate functional and interface clock for each module,
88 * instead there is typically an interface clock that spans many modules.
91 #define FREQ_96MHZ 96000000
92 #define FREQ_64MHZ 64000000
93 #define FREQ_48MHZ 48000000
94 #define FREQ_32KHZ 32000
97 * We need three memory regions to cover all the clock configuration registers.
99 * PRM Instance - 0x4A30 6000 : 0x4A30 8000
100 * CM1 Instance - 0x4A00 4000 : 0x4A00 5000
101 * CM2 Instance - 0x4A00 8000 : 0x4A00 A000
104 #define PRM_INSTANCE_MEM_REGION 0
105 #define CM1_INSTANCE_MEM_REGION 1
106 #define CM2_INSTANCE_MEM_REGION 2
109 * Address offsets from the PRM memory region to the top level clock control
112 #define CKGEN_PRM_OFFSET 0x00000100UL
113 #define MPU_PRM_OFFSET 0x00000300UL
114 #define DSP_PRM_OFFSET 0x00000400UL
115 #define ABE_PRM_OFFSET 0x00000500UL
116 #define ALWAYS_ON_PRM_OFFSET 0x00000600UL
117 #define CORE_PRM_OFFSET 0x00000700UL
118 #define IVAHD_PRM_OFFSET 0x00000F00UL
119 #define CAM_PRM_OFFSET 0x00001000UL
120 #define DSS_PRM_OFFSET 0x00001100UL
121 #define SGX_PRM_OFFSET 0x00001200UL
122 #define L3INIT_PRM_OFFSET 0x00001300UL
123 #define L4PER_PRM_OFFSET 0x00001400UL
124 #define WKUP_PRM_OFFSET 0x00001700UL
125 #define WKUP_CM_OFFSET 0x00001800UL
126 #define EMU_PRM_OFFSET 0x00001900UL
127 #define EMU_CM_OFFSET 0x00001A00UL
128 #define DEVICE_PRM_OFFSET 0x00001B00UL
129 #define INSTR_PRM_OFFSET 0x00001F00UL
131 #define CM_ABE_DSS_SYS_CLKSEL_OFFSET (CKGEN_PRM_OFFSET + 0x0000UL)
132 #define CM_L4_WKUP_CLKSELL_OFFSET (CKGEN_PRM_OFFSET + 0x0008UL)
133 #define CM_ABE_PLL_REF_CLKSEL_OFFSET (CKGEN_PRM_OFFSET + 0x000CUL)
134 #define CM_SYS_CLKSEL_OFFSET (CKGEN_PRM_OFFSET + 0x0010UL)
137 * Address offsets from the CM1 memory region to the top level clock control
140 #define CKGEN_CM1_OFFSET 0x00000100UL
141 #define MPU_CM1_OFFSET 0x00000300UL
142 #define DSP_CM1_OFFSET 0x00000400UL
143 #define ABE_CM1_OFFSET 0x00000500UL
144 #define RESTORE_CM1_OFFSET 0x00000E00UL
145 #define INSTR_CM1_OFFSET 0x00000F00UL
147 #define CM_CLKSEL_DPLL_MPU (CKGEN_CM1_OFFSET + 0x006CUL)
150 * Address offsets from the CM2 memory region to the top level clock control
153 #define INTRCONN_SOCKET_CM2_OFFSET 0x00000000UL
154 #define CKGEN_CM2_OFFSET 0x00000100UL
155 #define ALWAYS_ON_CM2_OFFSET 0x00000600UL
156 #define CORE_CM2_OFFSET 0x00000700UL
157 #define IVAHD_CM2_OFFSET 0x00000F00UL
158 #define CAM_CM2_OFFSET 0x00001000UL
159 #define DSS_CM2_OFFSET 0x00001100UL
160 #define SGX_CM2_OFFSET 0x00001200UL
161 #define L3INIT_CM2_OFFSET 0x00001300UL
162 #define L4PER_CM2_OFFSET 0x00001400UL
163 #define RESTORE_CM2_OFFSET 0x00001E00UL
164 #define INSTR_CM2_OFFSET 0x00001F00UL
166 #define CLKCTRL_MODULEMODE_MASK 0x00000003UL
167 #define CLKCTRL_MODULEMODE_DISABLE 0x00000000UL
168 #define CLKCTRL_MODULEMODE_AUTO 0x00000001UL
169 #define CLKCTRL_MODULEMODE_ENABLE 0x00000001UL
171 #define CLKCTRL_IDLEST_MASK 0x00030000UL
172 #define CLKCTRL_IDLEST_ENABLED 0x00000000UL
173 #define CLKCTRL_IDLEST_WAKING 0x00010000UL
174 #define CLKCTRL_IDLEST_IDLE 0x00020000UL
175 #define CLKCTRL_IDLEST_DISABLED 0x00030000UL
177 static struct resource_spec omap4_scm_res_spec[] = {
178 { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Control memory window */
179 { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* Control memory window */
180 { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* Control memory window */
184 struct omap4_prcm_softc {
185 struct resource *sc_res[3];
188 static struct omap4_prcm_softc *omap4_prcm_sc;
190 static int omap4_clk_generic_activate(struct ti_clock_dev *clkdev);
191 static int omap4_clk_generic_deactivate(struct ti_clock_dev *clkdev);
192 static int omap4_clk_generic_accessible(struct ti_clock_dev *clkdev);
193 static int omap4_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
194 static int omap4_clk_generic_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
196 static int omap4_clk_gptimer_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
197 static int omap4_clk_gptimer_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
199 static int omap4_clk_hsmmc_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
200 static int omap4_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
202 static int omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
203 static int omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev);
204 static int omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev);
205 static int omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev);
207 static int omap4_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
208 static int omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
211 * omap_clk_devmap - Array of clock devices available on OMAP4xxx devices
213 * This map only defines which clocks are valid and the callback functions
214 * for clock activate, deactivate, etc. It is used by the top level omap_prcm
217 * The actual details of the clocks (config registers, bit fields, sources,
218 * etc) are in the private g_omap3_clk_details array below.
222 #define OMAP4_GENERIC_CLOCK_DEV(i) \
224 .clk_activate = omap4_clk_generic_activate, \
225 .clk_deactivate = omap4_clk_generic_deactivate, \
226 .clk_set_source = omap4_clk_generic_set_source, \
227 .clk_accessible = omap4_clk_generic_accessible, \
228 .clk_get_source_freq = omap4_clk_generic_get_source_freq \
231 #define OMAP4_GPTIMER_CLOCK_DEV(i) \
233 .clk_activate = omap4_clk_generic_activate, \
234 .clk_deactivate = omap4_clk_generic_deactivate, \
235 .clk_set_source = omap4_clk_gptimer_set_source, \
236 .clk_accessible = omap4_clk_generic_accessible, \
237 .clk_get_source_freq = omap4_clk_gptimer_get_source_freq \
240 #define OMAP4_HSMMC_CLOCK_DEV(i) \
242 .clk_activate = omap4_clk_generic_activate, \
243 .clk_deactivate = omap4_clk_generic_deactivate, \
244 .clk_set_source = omap4_clk_hsmmc_set_source, \
245 .clk_accessible = omap4_clk_generic_accessible, \
246 .clk_get_source_freq = omap4_clk_hsmmc_get_source_freq \
249 #define OMAP4_HSUSBHOST_CLOCK_DEV(i) \
251 .clk_activate = omap4_clk_hsusbhost_activate, \
252 .clk_deactivate = omap4_clk_hsusbhost_deactivate, \
253 .clk_set_source = omap4_clk_hsusbhost_set_source, \
254 .clk_accessible = omap4_clk_hsusbhost_accessible, \
255 .clk_get_source_freq = NULL \
259 struct ti_clock_dev ti_clk_devmap[] = {
263 .clk_activate = NULL,
264 .clk_deactivate = NULL,
265 .clk_set_source = NULL,
266 .clk_accessible = NULL,
267 .clk_get_source_freq = omap4_clk_get_sysclk_freq,
269 /* MPU (ARM) core clocks */
271 .clk_activate = NULL,
272 .clk_deactivate = NULL,
273 .clk_set_source = NULL,
274 .clk_accessible = NULL,
275 .clk_get_source_freq = omap4_clk_get_arm_fclk_freq,
279 /* UART device clocks */
280 OMAP4_GENERIC_CLOCK_DEV(UART1_CLK),
281 OMAP4_GENERIC_CLOCK_DEV(UART2_CLK),
282 OMAP4_GENERIC_CLOCK_DEV(UART3_CLK),
283 OMAP4_GENERIC_CLOCK_DEV(UART4_CLK),
285 /* Timer device source clocks */
286 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER1_CLK),
287 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER2_CLK),
288 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER3_CLK),
289 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER4_CLK),
290 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER5_CLK),
291 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER6_CLK),
292 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER7_CLK),
293 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER8_CLK),
294 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER9_CLK),
295 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER10_CLK),
296 OMAP4_GPTIMER_CLOCK_DEV(GPTIMER11_CLK),
298 /* MMC device clocks (MMC1 and MMC2 can have different input clocks) */
299 OMAP4_HSMMC_CLOCK_DEV(MMC1_CLK),
300 OMAP4_HSMMC_CLOCK_DEV(MMC2_CLK),
301 OMAP4_GENERIC_CLOCK_DEV(MMC3_CLK),
302 OMAP4_GENERIC_CLOCK_DEV(MMC4_CLK),
303 OMAP4_GENERIC_CLOCK_DEV(MMC5_CLK),
305 /* USB HS (high speed TLL, EHCI and OHCI) */
306 OMAP4_HSUSBHOST_CLOCK_DEV(USBTLL_CLK),
307 OMAP4_HSUSBHOST_CLOCK_DEV(USBHSHOST_CLK),
308 OMAP4_HSUSBHOST_CLOCK_DEV(USBFSHOST_CLK),
309 OMAP4_HSUSBHOST_CLOCK_DEV(USBP1_PHY_CLK),
310 OMAP4_HSUSBHOST_CLOCK_DEV(USBP2_PHY_CLK),
311 OMAP4_HSUSBHOST_CLOCK_DEV(USBP1_UTMI_CLK),
312 OMAP4_HSUSBHOST_CLOCK_DEV(USBP2_UTMI_CLK),
313 OMAP4_HSUSBHOST_CLOCK_DEV(USBP1_HSIC_CLK),
314 OMAP4_HSUSBHOST_CLOCK_DEV(USBP2_HSIC_CLK),
317 OMAP4_GENERIC_CLOCK_DEV(GPIO1_CLK),
318 OMAP4_GENERIC_CLOCK_DEV(GPIO2_CLK),
319 OMAP4_GENERIC_CLOCK_DEV(GPIO3_CLK),
320 OMAP4_GENERIC_CLOCK_DEV(GPIO4_CLK),
321 OMAP4_GENERIC_CLOCK_DEV(GPIO5_CLK),
322 OMAP4_GENERIC_CLOCK_DEV(GPIO6_CLK),
325 OMAP4_GENERIC_CLOCK_DEV(SDMA_CLK),
328 OMAP4_GENERIC_CLOCK_DEV(I2C1_CLK),
329 OMAP4_GENERIC_CLOCK_DEV(I2C2_CLK),
330 OMAP4_GENERIC_CLOCK_DEV(I2C3_CLK),
331 OMAP4_GENERIC_CLOCK_DEV(I2C4_CLK),
333 { INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
337 * omap4_clk_details - Stores details for all the different clocks supported
339 * Whenever an operation on a clock is being performed (activated, deactivated,
340 * etc) this array is looked up to find the correct register and bit(s) we
341 * should be modifying.
344 struct omap4_clk_details {
352 uint32_t enable_mode;
355 #define OMAP4_GENERIC_CLOCK_DETAILS(i, f, m, r, e) \
360 .enable_mode = (e), \
363 static struct omap4_clk_details g_omap4_clk_details[] = {
366 OMAP4_GENERIC_CLOCK_DETAILS(UART1_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
367 (L4PER_CM2_OFFSET + 0x0140), CLKCTRL_MODULEMODE_ENABLE),
368 OMAP4_GENERIC_CLOCK_DETAILS(UART2_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
369 (L4PER_CM2_OFFSET + 0x0148), CLKCTRL_MODULEMODE_ENABLE),
370 OMAP4_GENERIC_CLOCK_DETAILS(UART3_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
371 (L4PER_CM2_OFFSET + 0x0140), CLKCTRL_MODULEMODE_ENABLE),
372 OMAP4_GENERIC_CLOCK_DETAILS(UART4_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
373 (L4PER_CM2_OFFSET + 0x0148), CLKCTRL_MODULEMODE_ENABLE),
375 /* General purpose timers */
376 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER1_CLK, -1, PRM_INSTANCE_MEM_REGION,
377 (WKUP_CM_OFFSET + 0x040), CLKCTRL_MODULEMODE_ENABLE),
378 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER2_CLK, -1, CM2_INSTANCE_MEM_REGION,
379 (L4PER_CM2_OFFSET + 0x038), CLKCTRL_MODULEMODE_ENABLE),
380 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER3_CLK, -1, CM2_INSTANCE_MEM_REGION,
381 (L4PER_CM2_OFFSET + 0x040), CLKCTRL_MODULEMODE_ENABLE),
382 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER4_CLK, -1, CM2_INSTANCE_MEM_REGION,
383 (L4PER_CM2_OFFSET + 0x048), CLKCTRL_MODULEMODE_ENABLE),
384 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER5_CLK, -1, CM1_INSTANCE_MEM_REGION,
385 (ABE_CM1_OFFSET + 0x068), CLKCTRL_MODULEMODE_ENABLE),
386 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER6_CLK, -1, CM1_INSTANCE_MEM_REGION,
387 (ABE_CM1_OFFSET + 0x070), CLKCTRL_MODULEMODE_ENABLE),
388 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER7_CLK, -1, CM1_INSTANCE_MEM_REGION,
389 (ABE_CM1_OFFSET + 0x078), CLKCTRL_MODULEMODE_ENABLE),
390 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER8_CLK, -1, CM1_INSTANCE_MEM_REGION,
391 (ABE_CM1_OFFSET + 0x080), CLKCTRL_MODULEMODE_ENABLE),
392 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER9_CLK, -1, CM2_INSTANCE_MEM_REGION,
393 (L4PER_CM2_OFFSET + 0x050), CLKCTRL_MODULEMODE_ENABLE),
394 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER10_CLK, -1, CM2_INSTANCE_MEM_REGION,
395 (L4PER_CM2_OFFSET + 0x028), CLKCTRL_MODULEMODE_ENABLE),
396 OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER11_CLK, -1, CM2_INSTANCE_MEM_REGION,
397 (L4PER_CM2_OFFSET + 0x030), CLKCTRL_MODULEMODE_ENABLE),
399 /* HSMMC (MMC1 and MMC2 can have different input clocks) */
400 OMAP4_GENERIC_CLOCK_DETAILS(MMC1_CLK, -1, CM2_INSTANCE_MEM_REGION,
401 (L3INIT_CM2_OFFSET + 0x028), /*CLKCTRL_MODULEMODE_ENABLE*/2),
402 OMAP4_GENERIC_CLOCK_DETAILS(MMC2_CLK, -1, CM2_INSTANCE_MEM_REGION,
403 (L3INIT_CM2_OFFSET + 0x030), /*CLKCTRL_MODULEMODE_ENABLE*/2),
404 OMAP4_GENERIC_CLOCK_DETAILS(MMC3_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
405 (L4PER_CM2_OFFSET + 0x120), /*CLKCTRL_MODULEMODE_ENABLE*/2),
406 OMAP4_GENERIC_CLOCK_DETAILS(MMC4_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
407 (L4PER_CM2_OFFSET + 0x128), /*CLKCTRL_MODULEMODE_ENABLE*/2),
408 OMAP4_GENERIC_CLOCK_DETAILS(MMC5_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
409 (L4PER_CM2_OFFSET + 0x160), /*CLKCTRL_MODULEMODE_ENABLE*/1),
412 OMAP4_GENERIC_CLOCK_DETAILS(GPIO1_CLK, -1, PRM_INSTANCE_MEM_REGION,
413 (WKUP_CM_OFFSET + 0x038), CLKCTRL_MODULEMODE_AUTO),
414 OMAP4_GENERIC_CLOCK_DETAILS(GPIO2_CLK, -1, CM2_INSTANCE_MEM_REGION,
415 (L4PER_CM2_OFFSET + 0x060), CLKCTRL_MODULEMODE_AUTO),
416 OMAP4_GENERIC_CLOCK_DETAILS(GPIO3_CLK, -1, CM2_INSTANCE_MEM_REGION,
417 (L4PER_CM2_OFFSET + 0x068), CLKCTRL_MODULEMODE_AUTO),
418 OMAP4_GENERIC_CLOCK_DETAILS(GPIO4_CLK, -1, CM2_INSTANCE_MEM_REGION,
419 (L4PER_CM2_OFFSET + 0x070), CLKCTRL_MODULEMODE_AUTO),
420 OMAP4_GENERIC_CLOCK_DETAILS(GPIO5_CLK, -1, CM2_INSTANCE_MEM_REGION,
421 (L4PER_CM2_OFFSET + 0x078), CLKCTRL_MODULEMODE_AUTO),
422 OMAP4_GENERIC_CLOCK_DETAILS(GPIO6_CLK, -1, CM2_INSTANCE_MEM_REGION,
423 (L4PER_CM2_OFFSET + 0x080), CLKCTRL_MODULEMODE_AUTO),
426 OMAP4_GENERIC_CLOCK_DETAILS(SDMA_CLK, -1, CM2_INSTANCE_MEM_REGION,
427 (CORE_CM2_OFFSET + 0x300), CLKCTRL_MODULEMODE_AUTO),
430 OMAP4_GENERIC_CLOCK_DETAILS(I2C1_CLK, -1, CM2_INSTANCE_MEM_REGION,
431 (L4PER_CM2_OFFSET + 0x0A0), CLKCTRL_MODULEMODE_ENABLE),
432 OMAP4_GENERIC_CLOCK_DETAILS(I2C2_CLK, -1, CM2_INSTANCE_MEM_REGION,
433 (L4PER_CM2_OFFSET + 0x0A8), CLKCTRL_MODULEMODE_ENABLE),
434 OMAP4_GENERIC_CLOCK_DETAILS(I2C3_CLK, -1, CM2_INSTANCE_MEM_REGION,
435 (L4PER_CM2_OFFSET + 0x0B0), CLKCTRL_MODULEMODE_ENABLE),
436 OMAP4_GENERIC_CLOCK_DETAILS(I2C4_CLK, -1, CM2_INSTANCE_MEM_REGION,
437 (L4PER_CM2_OFFSET + 0x0B8), CLKCTRL_MODULEMODE_ENABLE),
439 { INVALID_CLK_IDENT, 0, 0, 0, 0 },
443 * MAX_MODULE_ENABLE_WAIT - the number of loops to wait for the module to come
447 #define MAX_MODULE_ENABLE_WAIT 100
450 * ARRAY_SIZE - Macro to return the number of elements in a static const array.
453 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
456 * omap4_clk_details - writes a 32-bit value to one of the timer registers
457 * @timer: Timer device context
458 * @off: The offset of a register from the timer register address range
459 * @val: The value to write into the register
465 static struct omap4_clk_details*
466 omap4_clk_details(clk_ident_t id)
468 struct omap4_clk_details *walker;
470 for (walker = g_omap4_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
471 if (id == walker->id)
479 * omap4_clk_generic_activate - checks if a module is accessible
480 * @module: identifier for the module to check, see omap3_prcm.h for a list
481 * of possible modules.
482 * Example: OMAP3_MODULE_MMC1
487 * Inherits the locks from the omap_prcm driver, no internal locking.
490 * Returns 0 on success or a positive error code on failure.
493 omap4_clk_generic_activate(struct ti_clock_dev *clkdev)
495 struct omap4_prcm_softc *sc = omap4_prcm_sc;
496 struct omap4_clk_details* clk_details;
497 struct resource* clk_mem_res;
504 clk_details = omap4_clk_details(clkdev->id);
506 if (clk_details == NULL)
509 clk_mem_res = sc->sc_res[clk_details->mem_region];
511 if (clk_mem_res == NULL)
514 /* All the 'generic' clocks have a CLKCTRL register which is more or less
515 * generic - the have at least two fielda called MODULEMODE and IDLEST.
517 clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
518 clksel &= ~CLKCTRL_MODULEMODE_MASK;
519 clksel |= clk_details->enable_mode;
520 bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
522 /* Now poll on the IDLEST register to tell us if the module has come up.
523 * TODO: We need to take into account the parent clocks.
526 /* Try MAX_MODULE_ENABLE_WAIT number of times to check if enabled */
527 for (i = 0; i < MAX_MODULE_ENABLE_WAIT; i++) {
528 clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
529 if ((clksel & CLKCTRL_IDLEST_MASK) == CLKCTRL_IDLEST_ENABLED)
534 /* Check the enabled state */
535 if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED) {
536 printf("Error: failed to enable module with clock %d\n", clkdev->id);
537 printf("Error: 0x%08x => 0x%08x\n", clk_details->clksel_reg, clksel);
545 * omap4_clk_generic_deactivate - checks if a module is accessible
546 * @module: identifier for the module to check, see omap3_prcm.h for a list
547 * of possible modules.
548 * Example: OMAP3_MODULE_MMC1
553 * Inherits the locks from the omap_prcm driver, no internal locking.
556 * Returns 0 on success or a positive error code on failure.
559 omap4_clk_generic_deactivate(struct ti_clock_dev *clkdev)
561 struct omap4_prcm_softc *sc = omap4_prcm_sc;
562 struct omap4_clk_details* clk_details;
563 struct resource* clk_mem_res;
569 clk_details = omap4_clk_details(clkdev->id);
571 if (clk_details == NULL)
574 clk_mem_res = sc->sc_res[clk_details->mem_region];
576 if (clk_mem_res == NULL)
579 /* All the 'generic' clocks have a CLKCTRL register which is more or less
580 * generic - the have at least two fielda called MODULEMODE and IDLEST.
582 clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
583 clksel &= ~CLKCTRL_MODULEMODE_MASK;
584 clksel |= CLKCTRL_MODULEMODE_DISABLE;
585 bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
591 * omap4_clk_generic_set_source - checks if a module is accessible
592 * @module: identifier for the module to check, see omap3_prcm.h for a list
593 * of possible modules.
594 * Example: OMAP3_MODULE_MMC1
599 * Inherits the locks from the omap_prcm driver, no internal locking.
602 * Returns 0 on success or a positive error code on failure.
605 omap4_clk_generic_set_source(struct ti_clock_dev *clkdev,
613 * omap4_clk_generic_accessible - checks if a module is accessible
614 * @module: identifier for the module to check, see omap3_prcm.h for a list
615 * of possible modules.
616 * Example: OMAP3_MODULE_MMC1
621 * Inherits the locks from the omap_prcm driver, no internal locking.
624 * Returns 0 on success or a negative error code on failure.
627 omap4_clk_generic_accessible(struct ti_clock_dev *clkdev)
629 struct omap4_prcm_softc *sc = omap4_prcm_sc;
630 struct omap4_clk_details* clk_details;
631 struct resource* clk_mem_res;
637 clk_details = omap4_clk_details(clkdev->id);
639 if (clk_details == NULL)
642 clk_mem_res = sc->sc_res[clk_details->mem_region];
644 if (clk_mem_res == NULL)
647 clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
649 /* Check the enabled state */
650 if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED)
657 * omap4_clk_generic_get_source_freq - checks if a module is accessible
658 * @module: identifier for the module to check, see omap3_prcm.h for a list
659 * of possible modules.
660 * Example: OMAP3_MODULE_MMC1
665 * Inherits the locks from the omap_prcm driver, no internal locking.
668 * Returns 0 on success or a negative error code on failure.
671 omap4_clk_generic_get_source_freq(struct ti_clock_dev *clkdev,
675 struct omap4_clk_details* clk_details = omap4_clk_details(clkdev->id);
677 if (clk_details == NULL)
680 /* Simply return the stored frequency */
682 *freq = (unsigned int)clk_details->src_freq;
689 * omap4_clk_gptimer_set_source - checks if a module is accessible
690 * @module: identifier for the module to check, see omap3_prcm.h for a list
691 * of possible modules.
692 * Example: OMAP3_MODULE_MMC1
697 * Inherits the locks from the omap_prcm driver, no internal locking.
700 * Returns 0 on success or a negative error code on failure.
703 omap4_clk_gptimer_set_source(struct ti_clock_dev *clkdev,
706 struct omap4_prcm_softc *sc = omap4_prcm_sc;
707 struct omap4_clk_details* clk_details;
708 struct resource* clk_mem_res;
713 clk_details = omap4_clk_details(clkdev->id);
715 if (clk_details == NULL)
718 clk_mem_res = sc->sc_res[clk_details->mem_region];
720 if (clk_mem_res == NULL)
723 /* TODO: Implement */
729 * omap4_clk_gptimer_get_source_freq - checks if a module is accessible
730 * @module: identifier for the module to check, see omap3_prcm.h for a list
731 * of possible modules.
732 * Example: OMAP3_MODULE_MMC1
737 * Inherits the locks from the omap_prcm driver, no internal locking.
740 * Returns 0 on success or a negative error code on failure.
743 omap4_clk_gptimer_get_source_freq(struct ti_clock_dev *clkdev,
747 struct omap4_prcm_softc *sc = omap4_prcm_sc;
748 struct omap4_clk_details* clk_details;
749 struct resource* clk_mem_res;
751 unsigned int src_freq;
756 clk_details = omap4_clk_details(clkdev->id);
758 if (clk_details == NULL)
761 clk_mem_res = sc->sc_res[clk_details->mem_region];
763 if (clk_mem_res == NULL)
766 /* Need to read the CLKSEL field to determine the clock source */
767 clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
768 if (clksel & (0x1UL << 24))
769 src_freq = FREQ_32KHZ;
771 omap4_clk_get_sysclk_freq(NULL, &src_freq);
773 /* Return the frequency */
781 * omap4_clk_hsmmc_set_source - sets the source clock (freq)
782 * @clkdev: pointer to the clockdev structure (id field will contain clock id)
784 * The MMC 1 and 2 clocks can be source from either a 64MHz or 96MHz clock.
787 * Inherits the locks from the omap_prcm driver, no internal locking.
790 * Returns 0 on success or a negative error code on failure.
793 omap4_clk_hsmmc_set_source(struct ti_clock_dev *clkdev,
796 struct omap4_prcm_softc *sc = omap4_prcm_sc;
797 struct omap4_clk_details* clk_details;
798 struct resource* clk_mem_res;
804 clk_details = omap4_clk_details(clkdev->id);
806 if (clk_details == NULL)
809 clk_mem_res = sc->sc_res[clk_details->mem_region];
811 if (clk_mem_res == NULL)
814 /* For MMC modules 3, 4 & 5 you can't change the freq, it's always 48MHz */
815 if ((clkdev->id == MMC3_CLK) || (clkdev->id == MMC4_CLK) ||
816 (clkdev->id == MMC5_CLK)) {
817 if (clksrc != F48MHZ_CLK)
823 clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
825 /* Bit 24 is set if 96MHz clock or cleared for 64MHz clock */
826 if (clksrc == F64MHZ_CLK)
827 clksel &= ~(0x1UL << 24);
828 else if (clksrc == F96MHZ_CLK)
829 clksel |= (0x1UL << 24);
833 bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
839 * omap4_clk_hsmmc_get_source_freq - checks if a module is accessible
840 * @clkdev: pointer to the clockdev structure (id field will contain clock id)
845 * Inherits the locks from the omap_prcm driver, no internal locking.
848 * Returns 0 on success or a negative error code on failure.
851 omap4_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,
855 struct omap4_prcm_softc *sc = omap4_prcm_sc;
856 struct omap4_clk_details* clk_details;
857 struct resource* clk_mem_res;
859 unsigned int src_freq;
864 clk_details = omap4_clk_details(clkdev->id);
866 if (clk_details == NULL)
869 clk_mem_res = sc->sc_res[clk_details->mem_region];
871 if (clk_mem_res == NULL)
874 switch (clkdev->id) {
877 /* Need to read the CLKSEL field to determine the clock source */
878 clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
879 if (clksel & (0x1UL << 24))
880 src_freq = FREQ_96MHZ;
882 src_freq = FREQ_64MHZ;
887 src_freq = FREQ_48MHZ;
893 /* Return the frequency */
901 * omap4_clk_get_sysclk_freq - gets the sysclk frequency
902 * @sc: pointer to the clk module/device context
904 * Read the clocking information from the power-control/boot-strap registers,
905 * and stored in two global variables.
908 * nothing, values are saved in global variables
911 omap4_clk_get_sysclk_freq(struct ti_clock_dev *clkdev,
916 struct omap4_prcm_softc *sc = omap4_prcm_sc;
921 /* Read the input clock freq from the configuration register (CM_SYS_CLKSEL) */
922 clksel = bus_read_4(sc->sc_res[PRM_INSTANCE_MEM_REGION], CM_SYS_CLKSEL_OFFSET);
923 switch (clksel & 0x7) {
945 panic("%s: Invalid clock freq", __func__);
948 /* Return the value */
956 * omap4_clk_get_arm_fclk_freq - gets the MPU clock frequency
958 * @freq: pointer which upon return will contain the freq in hz
959 * @mem_res: array of allocated memory resources
961 * Reads the frequency setting information registers and returns the value
962 * in the freq variable.
965 * returns 0 on success, a positive error code on failure.
968 omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev,
972 uint32_t pll_mult, pll_div;
973 uint32_t mpuclk, sysclk;
974 struct omap4_prcm_softc *sc = omap4_prcm_sc;
979 /* Read the clksel register which contains the DPLL multiple and divide
980 * values. These are applied to the sysclk.
982 clksel = bus_read_4(sc->sc_res[CM1_INSTANCE_MEM_REGION], CM_CLKSEL_DPLL_MPU);
984 pll_mult = ((clksel >> 8) & 0x7ff);
985 pll_div = (clksel & 0x7f) + 1;
988 /* Get the system clock freq */
989 omap4_clk_get_sysclk_freq(NULL, &sysclk);
992 /* Calculate the MPU freq */
993 mpuclk = ((uint64_t)sysclk * pll_mult) / pll_div;
995 /* Return the value */
1003 * omap4_clk_hsusbhost_activate - activates the USB clocks for the given module
1004 * @clkdev: pointer to the clock device structure.
1005 * @mem_res: array of memory resources allocated by the top level PRCM driver.
1007 * The USB clocking setup seems to be a bit more tricky than the other modules,
1008 * to start with the clocking diagram for the HS host module shows 13 different
1009 * clocks. So to try and make it easier to follow the clocking activation
1010 * and deactivation is handled in it's own set of callbacks.
1013 * Inherits the locks from the omap_prcm driver, no internal locking.
1016 * Returns 0 on success or a positive error code on failure.
1029 /* USB parameters */
1030 struct dpll_param usb_dpll_param[7] = {
1032 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1034 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1036 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1038 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1040 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1042 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1044 #ifdef CONFIG_OMAP4_SDC
1045 {0x32, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0},
1047 {0x32, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0},
1051 omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev)
1053 struct omap4_prcm_softc *sc = omap4_prcm_sc;
1054 struct resource* clk_mem_res;
1055 uint32_t clksel_reg_off;
1062 switch (clkdev->id) {
1064 /* For the USBTLL module we need to enable the following clocks:
1065 * - INIT_L4_ICLK (will be enabled by bootloader)
1070 /* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
1071 clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1072 clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
1074 /* Enable the module and also enable the optional func clocks for
1075 * channels 0 & 1 (is this needed ?)
1077 clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1078 clksel &= ~CLKCTRL_MODULEMODE_MASK;
1079 clksel |= CLKCTRL_MODULEMODE_ENABLE;
1081 clksel |= (0x1 << 8); /* USB-HOST optional clock: USB_CH0_CLK */
1082 clksel |= (0x1 << 9); /* USB-HOST optional clock: USB_CH1_CLK */
1088 case USBP1_UTMI_CLK:
1089 case USBP2_UTMI_CLK:
1090 case USBP1_HSIC_CLK:
1091 case USBP2_HSIC_CLK:
1092 /* For the USB HS HOST module we need to enable the following clocks:
1093 * - INIT_L4_ICLK (will be enabled by bootloader)
1094 * - INIT_L3_ICLK (will be enabled by bootloader)
1096 * - UTMI_ROOT_GFCLK (UTMI only, create a new clock for that ?)
1097 * - UTMI_P1_FCLK (UTMI only, create a new clock for that ?)
1098 * - UTMI_P2_FCLK (UTMI only, create a new clock for that ?)
1099 * - HSIC_P1_60 (HSIC only, create a new clock for that ?)
1100 * - HSIC_P1_480 (HSIC only, create a new clock for that ?)
1101 * - HSIC_P2_60 (HSIC only, create a new clock for that ?)
1102 * - HSIC_P2_480 (HSIC only, create a new clock for that ?)
1105 /* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
1106 clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1107 clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
1108 clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1109 /* Enable the module and also enable the optional func clocks */
1110 if (clkdev->id == USBHSHOST_CLK) {
1111 clksel &= ~CLKCTRL_MODULEMODE_MASK;
1112 clksel |= /*CLKCTRL_MODULEMODE_ENABLE*/2;
1114 clksel |= (0x1 << 15); /* USB-HOST clock control: FUNC48MCLK */
1117 else if (clkdev->id == USBP1_UTMI_CLK)
1118 clksel |= (0x1 << 8); /* UTMI_P1_CLK */
1119 else if (clkdev->id == USBP2_UTMI_CLK)
1120 clksel |= (0x1 << 9); /* UTMI_P2_CLK */
1122 else if (clkdev->id == USBP1_HSIC_CLK)
1123 clksel |= (0x5 << 11); /* HSIC60M_P1_CLK + HSIC480M_P1_CLK */
1124 else if (clkdev->id == USBP2_HSIC_CLK)
1125 clksel |= (0x5 << 12); /* HSIC60M_P2_CLK + HSIC480M_P2_CLK */
1133 bus_write_4(clk_mem_res, clksel_reg_off, clksel);
1135 /* Try MAX_MODULE_ENABLE_WAIT number of times to check if enabled */
1136 for (i = 0; i < MAX_MODULE_ENABLE_WAIT; i++) {
1137 clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1138 if ((clksel & CLKCTRL_IDLEST_MASK) == CLKCTRL_IDLEST_ENABLED)
1142 /* Check the enabled state */
1143 if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED) {
1144 printf("Error: HERE failed to enable module with clock %d\n", clkdev->id);
1145 printf("Error: 0x%08x => 0x%08x\n", clksel_reg_off, clksel);
1153 * omap4_clk_generic_deactivate - checks if a module is accessible
1154 * @clkdev: pointer to the clock device structure.
1155 * @mem_res: array of memory resources allocated by the top level PRCM driver.
1160 * Inherits the locks from the omap_prcm driver, no internal locking.
1163 * Returns 0 on success or a positive error code on failure.
1166 omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev)
1168 struct omap4_prcm_softc *sc = omap4_prcm_sc;
1169 struct resource* clk_mem_res;
1170 uint32_t clksel_reg_off;
1176 switch (clkdev->id) {
1178 /* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
1179 clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1180 clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
1182 clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1183 clksel &= ~CLKCTRL_MODULEMODE_MASK;
1184 clksel |= CLKCTRL_MODULEMODE_DISABLE;
1190 case USBP1_UTMI_CLK:
1191 case USBP2_UTMI_CLK:
1192 case USBP1_HSIC_CLK:
1193 case USBP2_HSIC_CLK:
1194 /* For the USB HS HOST module we need to enable the following clocks:
1195 * - INIT_L4_ICLK (will be enabled by bootloader)
1196 * - INIT_L3_ICLK (will be enabled by bootloader)
1198 * - UTMI_ROOT_GFCLK (UTMI only, create a new clock for that ?)
1199 * - UTMI_P1_FCLK (UTMI only, create a new clock for that ?)
1200 * - UTMI_P2_FCLK (UTMI only, create a new clock for that ?)
1201 * - HSIC_P1_60 (HSIC only, create a new clock for that ?)
1202 * - HSIC_P1_480 (HSIC only, create a new clock for that ?)
1203 * - HSIC_P2_60 (HSIC only, create a new clock for that ?)
1204 * - HSIC_P2_480 (HSIC only, create a new clock for that ?)
1207 /* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
1208 clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1209 clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
1210 clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1212 /* Enable the module and also enable the optional func clocks */
1213 if (clkdev->id == USBHSHOST_CLK) {
1214 clksel &= ~CLKCTRL_MODULEMODE_MASK;
1215 clksel |= CLKCTRL_MODULEMODE_DISABLE;
1217 clksel &= ~(0x1 << 15); /* USB-HOST clock control: FUNC48MCLK */
1220 else if (clkdev->id == USBP1_UTMI_CLK)
1221 clksel &= ~(0x1 << 8); /* UTMI_P1_CLK */
1222 else if (clkdev->id == USBP2_UTMI_CLK)
1223 clksel &= ~(0x1 << 9); /* UTMI_P2_CLK */
1225 else if (clkdev->id == USBP1_HSIC_CLK)
1226 clksel &= ~(0x5 << 11); /* HSIC60M_P1_CLK + HSIC480M_P1_CLK */
1227 else if (clkdev->id == USBP2_HSIC_CLK)
1228 clksel &= ~(0x5 << 12); /* HSIC60M_P2_CLK + HSIC480M_P2_CLK */
1236 bus_write_4(clk_mem_res, clksel_reg_off, clksel);
1242 * omap4_clk_hsusbhost_accessible - checks if a module is accessible
1243 * @clkdev: pointer to the clock device structure.
1244 * @mem_res: array of memory resources allocated by the top level PRCM driver.
1249 * Inherits the locks from the omap_prcm driver, no internal locking.
1252 * Returns 0 if module is not enable, 1 if module is enabled or a negative
1253 * error code on failure.
1256 omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev)
1258 struct omap4_prcm_softc *sc = omap4_prcm_sc;
1259 struct resource* clk_mem_res;
1260 uint32_t clksel_reg_off;
1266 if (clkdev->id == USBTLL_CLK) {
1267 /* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
1268 clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1269 clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
1271 else if (clkdev->id == USBHSHOST_CLK) {
1272 /* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
1273 clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1274 clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
1280 clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1282 /* Check the enabled state */
1283 if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED)
1290 * omap4_clk_hsusbhost_set_source - sets the source clocks
1291 * @clkdev: pointer to the clock device structure.
1292 * @clksrc: the clock source ID for the given clock.
1293 * @mem_res: array of memory resources allocated by the top level PRCM driver.
1298 * Inherits the locks from the omap_prcm driver, no internal locking.
1301 * Returns 0 if sucessful otherwise a negative error code on failure.
1304 omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev,
1307 struct omap4_prcm_softc *sc = omap4_prcm_sc;
1308 struct resource* clk_mem_res;
1309 uint32_t clksel_reg_off;
1316 if (clkdev->id == USBP1_PHY_CLK)
1318 else if (clkdev->id != USBP2_PHY_CLK)
1323 /* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
1324 clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
1325 clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
1326 clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1328 /* Set the clock source to either external or internal */
1329 if (clksrc == EXT_CLK)
1330 clksel |= (0x1 << bit);
1332 clksel &= ~(0x1 << bit);
1334 bus_write_4(clk_mem_res, clksel_reg_off, clksel);
1339 #define PRM_RSTCTRL 0x1b00
1340 #define PRM_RSTCTRL_RESET 0x2
1343 omap4_prcm_reset(void)
1345 struct omap4_prcm_softc *sc = omap4_prcm_sc;
1346 bus_write_4(sc->sc_res[0], PRM_RSTCTRL,
1347 bus_read_4(sc->sc_res[0], PRM_RSTCTRL) | PRM_RSTCTRL_RESET);
1348 bus_read_4(sc->sc_res[0], PRM_RSTCTRL);
1352 * omap4_prcm_probe - probe function for the driver
1353 * @dev: prcm device handle
1355 * Simply sets the name of the driver module.
1364 omap4_prcm_probe(device_t dev)
1367 if (!ofw_bus_status_okay(dev))
1370 if (!ofw_bus_is_compatible(dev, "ti,omap4_prcm"))
1373 device_set_desc(dev, "TI OMAP Power, Reset and Clock Management");
1378 * omap_prcm_attach - attach function for the driver
1379 * @dev: prcm device handle
1381 * Allocates and sets up the driver context, this simply entails creating a
1382 * bus mappings for the PRCM register set.
1391 extern uint32_t platform_arm_tmr_freq;
1394 omap4_prcm_attach(device_t dev)
1396 struct omap4_prcm_softc *sc = device_get_softc(dev);
1399 if (bus_alloc_resources(dev, omap4_scm_res_spec, sc->sc_res)) {
1400 device_printf(dev, "could not allocate resources\n");
1405 ti_cpu_reset = omap4_prcm_reset;
1406 omap4_clk_get_arm_fclk_freq(NULL, &freq);
1407 arm_tmr_change_frequency(freq / 2);
1412 static device_method_t omap4_prcm_methods[] = {
1413 DEVMETHOD(device_probe, omap4_prcm_probe),
1414 DEVMETHOD(device_attach, omap4_prcm_attach),
1418 static driver_t omap4_prcm_driver = {
1421 sizeof(struct omap4_prcm_softc),
1424 static devclass_t omap4_prcm_devclass;
1426 EARLY_DRIVER_MODULE(omap4_prcm, simplebus, omap4_prcm_driver,
1427 omap4_prcm_devclass, 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_EARLY);
1428 MODULE_VERSION(omap4_prcm, 1);