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