]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/arm/ti/omap4/omap4_prcm_clks.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / arm / ti / omap4 / omap4_prcm_clks.c
1 /*-
2  * Copyright (c) 2011
3  *      Ben Gray <ben.r.gray@gmail.com>.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the company nor the name of the author may be used to
15  *    endorse or promote products derived from this software without specific
16  *    prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/bus.h>
38 #include <sys/resource.h>
39 #include <sys/rman.h>
40 #include <sys/lock.h>
41 #include <sys/malloc.h>
42
43 #include <machine/bus.h>
44 #include <machine/cpu.h>
45 #include <machine/cpufunc.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/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>
58
59 /*
60  *      This file defines the clock configuration for the OMAP4xxx series of
61  *      devices.
62  *
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.
70  *
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.
74  *
75  *      - In essence you just need to define some callbacks for each of the
76  *      clocks and then you're done.
77  *
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. 
83  *
84  *
85  *
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.
89  */
90
91 #define FREQ_96MHZ    96000000
92 #define FREQ_64MHZ    64000000
93 #define FREQ_48MHZ    48000000
94 #define FREQ_32KHZ    32000
95
96 /**
97  *      We need three memory regions to cover all the clock configuration registers.
98  *      
99  *         PRM Instance -  0x4A30 6000 : 0x4A30 8000
100  *         CM1 Instance -  0x4A00 4000 : 0x4A00 5000
101  *         CM2 Instance -  0x4A00 8000 : 0x4A00 A000
102  *
103  */
104 #define PRM_INSTANCE_MEM_REGION    0
105 #define CM1_INSTANCE_MEM_REGION    1
106 #define CM2_INSTANCE_MEM_REGION    2
107
108 /**
109  *      Address offsets from the PRM memory region to the top level clock control
110  *      registers.
111  */
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
130
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)
135
136 /**
137  *      Address offsets from the CM1 memory region to the top level clock control
138  *      registers.
139  */
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
146
147 #define CM_CLKSEL_DPLL_MPU             (CKGEN_CM1_OFFSET + 0x006CUL)
148
149 /**
150  *      Address offsets from the CM2 memory region to the top level clock control
151  *      registers.
152  */
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
165
166 #define CLKCTRL_MODULEMODE_MASK       0x00000003UL
167 #define CLKCTRL_MODULEMODE_DISABLE    0x00000000UL
168 #define CLKCTRL_MODULEMODE_AUTO       0x00000001UL
169 #define CLKCTRL_MODULEMODE_ENABLE     0x00000001UL
170
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
176
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 */
181         { -1, 0 }
182 };
183
184 struct omap4_prcm_softc {
185         struct resource *sc_res[3];
186 };
187
188 static struct omap4_prcm_softc *omap4_prcm_sc;
189
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);
195
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);
198
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);
201
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);
206
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);
209
210 /**
211  *      omap_clk_devmap - Array of clock devices available on OMAP4xxx devices
212  *
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
215  *      driver.
216  *
217  *      The actual details of the clocks (config registers, bit fields, sources,
218  *      etc) are in the private g_omap3_clk_details array below.
219  *
220  */
221
222 #define OMAP4_GENERIC_CLOCK_DEV(i) \
223         {       .id = (i), \
224                 .clk_activate = omap4_clk_generic_activate, \
225                 .clk_deactivate = omap4_clk_generic_deactivate, \
226                 .clk_set_source = omap4_clk_generic_set_source, \
227                 .clk_accessible = omap4_clk_generic_accessible, \
228                 .clk_get_source_freq = omap4_clk_generic_get_source_freq \
229         }
230
231 #define OMAP4_GPTIMER_CLOCK_DEV(i) \
232         {       .id = (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 \
238         }
239
240 #define OMAP4_HSMMC_CLOCK_DEV(i) \
241         {       .id = (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 \
247         }
248
249 #define OMAP4_HSUSBHOST_CLOCK_DEV(i) \
250         {       .id = (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 \
256         }
257
258
259 struct ti_clock_dev ti_clk_devmap[] = {
260
261         /* System clocks */
262         {       .id                  = SYS_CLK,
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,
268         },
269         /* MPU (ARM) core clocks */
270         {       .id                  = MPU_CLK,
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,
276         },
277
278
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),
284         
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),
297         
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),
304
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),
315         
316         /* GPIO */
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),
323         
324         /* sDMA */
325         OMAP4_GENERIC_CLOCK_DEV(SDMA_CLK),      
326
327         /* I2C */
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),
332
333         {  INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
334 };
335
336 /**
337  *      omap4_clk_details - Stores details for all the different clocks supported
338  *
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.
342  *
343  */
344 struct omap4_clk_details {
345         clk_ident_t id;
346         
347         uint32_t    mem_region;
348         uint32_t    clksel_reg;
349         
350         int32_t     src_freq;
351         
352         uint32_t    enable_mode;
353 };
354
355 #define OMAP4_GENERIC_CLOCK_DETAILS(i, f, m, r, e) \
356         {       .id = (i), \
357                 .mem_region = (m), \
358                 .clksel_reg = (r), \
359                 .src_freq = (f), \
360                 .enable_mode = (e), \
361         }
362
363 static struct omap4_clk_details g_omap4_clk_details[] = {
364
365         /* UART */
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),
374
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),
398
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),
410         
411         /* GPIO modules */
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),
424                 
425         /* sDMA block */
426         OMAP4_GENERIC_CLOCK_DETAILS(SDMA_CLK, -1, CM2_INSTANCE_MEM_REGION,
427                 (CORE_CM2_OFFSET + 0x300), CLKCTRL_MODULEMODE_AUTO),
428
429         /* I2C modules */
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),
438
439         { INVALID_CLK_IDENT, 0, 0, 0, 0 },
440 };
441
442 /**
443  *      MAX_MODULE_ENABLE_WAIT - the number of loops to wait for the module to come
444  *      alive.
445  *
446  */
447 #define MAX_MODULE_ENABLE_WAIT    100
448         
449 /**
450  *      ARRAY_SIZE - Macro to return the number of elements in a static const array.
451  *
452  */
453 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
454
455 /**
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
460  *
461  *
462  *      RETURNS:
463  *      nothing
464  */
465 static struct omap4_clk_details*
466 omap4_clk_details(clk_ident_t id)
467 {
468         struct omap4_clk_details *walker;
469
470         for (walker = g_omap4_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
471                 if (id == walker->id)
472                         return (walker);
473         }
474
475         return NULL;
476 }
477         
478 /**
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
483  *      
484  *      
485  *
486  *      LOCKING:
487  *      Inherits the locks from the omap_prcm driver, no internal locking.
488  *
489  *      RETURNS:
490  *      Returns 0 on success or a positive error code on failure.
491  */
492 static int
493 omap4_clk_generic_activate(struct ti_clock_dev *clkdev)
494 {
495         struct omap4_prcm_softc *sc = omap4_prcm_sc;
496         struct omap4_clk_details* clk_details;
497         struct resource* clk_mem_res;
498         uint32_t clksel;
499         unsigned int i;
500
501         if (sc == NULL)
502                 return ENXIO;
503
504         clk_details = omap4_clk_details(clkdev->id);
505
506         if (clk_details == NULL)
507                 return (ENXIO);
508
509         clk_mem_res = sc->sc_res[clk_details->mem_region];
510
511         if (clk_mem_res == NULL)
512                 return (EINVAL);
513         
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.
516          */
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);
521
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.
524          */
525         
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)
530                         break;
531                 DELAY(10);
532         }
533                 
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);
538                 return (ETIMEDOUT);
539         }
540         
541         return (0);
542 }
543
544 /**
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
549  *      
550  *      
551  *
552  *      LOCKING:
553  *      Inherits the locks from the omap_prcm driver, no internal locking.
554  *
555  *      RETURNS:
556  *      Returns 0 on success or a positive error code on failure.
557  */
558 static int
559 omap4_clk_generic_deactivate(struct ti_clock_dev *clkdev)
560 {
561         struct omap4_prcm_softc *sc = omap4_prcm_sc;
562         struct omap4_clk_details* clk_details;
563         struct resource* clk_mem_res;
564         uint32_t clksel;
565
566         if (sc == NULL)
567                 return ENXIO;
568
569         clk_details = omap4_clk_details(clkdev->id);
570
571         if (clk_details == NULL)
572                 return (ENXIO);
573
574         clk_mem_res = sc->sc_res[clk_details->mem_region];
575
576         if (clk_mem_res == NULL)
577                 return (EINVAL);
578         
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.
581          */
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);
586
587         return (0);
588 }
589
590 /**
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
595  *      
596  *      
597  *
598  *      LOCKING:
599  *      Inherits the locks from the omap_prcm driver, no internal locking.
600  *
601  *      RETURNS:
602  *      Returns 0 on success or a positive error code on failure.
603  */
604 static int
605 omap4_clk_generic_set_source(struct ti_clock_dev *clkdev,
606                              clk_src_t clksrc)
607 {
608
609         return (0);
610 }
611
612 /**
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
617  *      
618  *      
619  *
620  *      LOCKING:
621  *      Inherits the locks from the omap_prcm driver, no internal locking.
622  *
623  *      RETURNS:
624  *      Returns 0 on success or a negative error code on failure.
625  */
626 static int
627 omap4_clk_generic_accessible(struct ti_clock_dev *clkdev)
628 {
629         struct omap4_prcm_softc *sc = omap4_prcm_sc;
630         struct omap4_clk_details* clk_details;
631         struct resource* clk_mem_res;
632         uint32_t clksel;
633
634         if (sc == NULL)
635                 return ENXIO;
636
637         clk_details = omap4_clk_details(clkdev->id);
638
639         if (clk_details == NULL)
640                 return (ENXIO);
641
642         clk_mem_res = sc->sc_res[clk_details->mem_region];
643
644         if (clk_mem_res == NULL)
645                 return (EINVAL);
646         
647         clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
648                 
649         /* Check the enabled state */
650         if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED)
651                 return (0);
652         
653         return (1);
654 }
655
656 /**
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
661  *      
662  *      
663  *
664  *      LOCKING:
665  *      Inherits the locks from the omap_prcm driver, no internal locking.
666  *
667  *      RETURNS:
668  *      Returns 0 on success or a negative error code on failure.
669  */
670 static int
671 omap4_clk_generic_get_source_freq(struct ti_clock_dev *clkdev,
672                                   unsigned int *freq
673                                   )
674 {
675         struct omap4_clk_details* clk_details = omap4_clk_details(clkdev->id);
676
677         if (clk_details == NULL)
678                 return (ENXIO);
679         
680         /* Simply return the stored frequency */
681         if (freq)
682                 *freq = (unsigned int)clk_details->src_freq;
683         
684         return (0);
685 }
686
687
688 /**
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
693  *      
694  *      
695  *
696  *      LOCKING:
697  *      Inherits the locks from the omap_prcm driver, no internal locking.
698  *
699  *      RETURNS:
700  *      Returns 0 on success or a negative error code on failure.
701  */
702 static int
703 omap4_clk_gptimer_set_source(struct ti_clock_dev *clkdev,
704                              clk_src_t clksrc)
705 {
706         struct omap4_prcm_softc *sc = omap4_prcm_sc;
707         struct omap4_clk_details* clk_details;
708         struct resource* clk_mem_res;
709
710         if (sc == NULL)
711                 return ENXIO;
712
713         clk_details = omap4_clk_details(clkdev->id);
714
715         if (clk_details == NULL)
716                 return (ENXIO);
717
718         clk_mem_res = sc->sc_res[clk_details->mem_region];
719
720         if (clk_mem_res == NULL)
721                 return (EINVAL);
722         
723         /* TODO: Implement */
724         
725         return (0);
726 }
727
728 /**
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
733  *      
734  *      
735  *
736  *      LOCKING:
737  *      Inherits the locks from the omap_prcm driver, no internal locking.
738  *
739  *      RETURNS:
740  *      Returns 0 on success or a negative error code on failure.
741  */
742 static int
743 omap4_clk_gptimer_get_source_freq(struct ti_clock_dev *clkdev,
744                                   unsigned int *freq
745                                   )
746 {
747         struct omap4_prcm_softc *sc = omap4_prcm_sc;
748         struct omap4_clk_details* clk_details;
749         struct resource* clk_mem_res;
750         uint32_t clksel;
751         unsigned int src_freq;
752
753         if (sc == NULL)
754                 return ENXIO;
755
756         clk_details = omap4_clk_details(clkdev->id);
757
758         if (clk_details == NULL)
759                 return (ENXIO);
760
761         clk_mem_res = sc->sc_res[clk_details->mem_region];
762
763         if (clk_mem_res == NULL)
764                 return (EINVAL);
765         
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;
770         else
771                 omap4_clk_get_sysclk_freq(NULL, &src_freq);
772         
773         /* Return the frequency */
774         if (freq)
775                 *freq = src_freq;
776         
777         return (0);
778 }
779
780 /**
781  *      omap4_clk_hsmmc_set_source - sets the source clock (freq)
782  *      @clkdev: pointer to the clockdev structure (id field will contain clock id)
783  *      
784  *      The MMC 1 and 2 clocks can be source from either a 64MHz or 96MHz clock.
785  *
786  *      LOCKING:
787  *      Inherits the locks from the omap_prcm driver, no internal locking.
788  *
789  *      RETURNS:
790  *      Returns 0 on success or a negative error code on failure.
791  */
792 static int
793 omap4_clk_hsmmc_set_source(struct ti_clock_dev *clkdev,
794                            clk_src_t clksrc)
795 {
796         struct omap4_prcm_softc *sc = omap4_prcm_sc;
797         struct omap4_clk_details* clk_details;
798         struct resource* clk_mem_res;
799         uint32_t clksel;
800
801         if (sc == NULL)
802                 return ENXIO;
803
804         clk_details = omap4_clk_details(clkdev->id);
805
806         if (clk_details == NULL)
807                 return (ENXIO);
808
809         clk_mem_res = sc->sc_res[clk_details->mem_region];
810
811         if (clk_mem_res == NULL)
812                 return (EINVAL);
813                 
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)
818                         return (EINVAL);
819                 return 0;
820         }
821
822         
823         clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
824
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);
830         else
831                 return (EINVAL);
832                 
833         bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
834         
835         return (0);
836 }
837
838 /**
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)
841  *      
842  *      
843  *
844  *      LOCKING:
845  *      Inherits the locks from the omap_prcm driver, no internal locking.
846  *
847  *      RETURNS:
848  *      Returns 0 on success or a negative error code on failure.
849  */
850 static int
851 omap4_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,
852                                 unsigned int *freq
853                                 )
854 {
855         struct omap4_prcm_softc *sc = omap4_prcm_sc;
856         struct omap4_clk_details* clk_details;
857         struct resource* clk_mem_res;
858         uint32_t clksel;
859         unsigned int src_freq;
860
861         if (sc == NULL)
862                 return ENXIO;
863
864         clk_details = omap4_clk_details(clkdev->id);
865
866         if (clk_details == NULL)
867                 return (ENXIO);
868
869         clk_mem_res = sc->sc_res[clk_details->mem_region];
870
871         if (clk_mem_res == NULL)
872                 return (EINVAL);
873         
874         switch (clkdev->id) {
875         case MMC1_CLK:
876         case MMC2_CLK:
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;
881                 else
882                         src_freq = FREQ_64MHZ;
883                 break;
884         case MMC3_CLK:
885         case MMC4_CLK:
886         case MMC5_CLK:
887                 src_freq = FREQ_48MHZ;
888                 break;
889         default:
890                 return (EINVAL);
891         }
892                 
893         /* Return the frequency */
894         if (freq)
895                 *freq = src_freq;
896         
897         return (0);
898 }
899
900 /**
901  *      omap4_clk_get_sysclk_freq - gets the sysclk frequency
902  *      @sc: pointer to the clk module/device context
903  *
904  *      Read the clocking information from the power-control/boot-strap registers,
905  *  and stored in two global variables.
906  *
907  *      RETURNS:
908  *      nothing, values are saved in global variables
909  */
910 static int
911 omap4_clk_get_sysclk_freq(struct ti_clock_dev *clkdev,
912                           unsigned int *freq)
913 {
914         uint32_t clksel;
915         uint32_t sysclk;
916         struct omap4_prcm_softc *sc = omap4_prcm_sc;
917         
918         if (sc == NULL)
919                 return ENXIO;
920
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) {
924         case 0x1:
925                 /* 12Mhz */
926                 sysclk = 12000000;
927                 break;
928         case 0x3:
929                 /* 16.8Mhz */
930                 sysclk = 16800000;
931                 break;
932         case 0x4:
933                 /* 19.2Mhz */
934                 sysclk = 19200000;
935                 break;
936         case 0x5:
937                 /* 26Mhz */
938                 sysclk = 26000000;
939                 break;
940         case 0x7:
941                 /* 38.4Mhz */
942                 sysclk = 38400000;
943                 break;
944         default:
945                 panic("%s: Invalid clock freq", __func__);
946         }
947
948         /* Return the value */
949         if (freq)
950                 *freq = sysclk;
951                 
952         return (0);
953 }
954
955 /**
956  *      omap4_clk_get_arm_fclk_freq - gets the MPU clock frequency
957  *      @clkdev: ignored
958  *      @freq: pointer which upon return will contain the freq in hz
959  *      @mem_res: array of allocated memory resources
960  *
961  *      Reads the frequency setting information registers and returns the value
962  *      in the freq variable.
963  *
964  *      RETURNS:
965  *      returns 0 on success, a positive error code on failure.
966  */
967 static int
968 omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev,
969                             unsigned int *freq)
970 {
971         uint32_t clksel;
972         uint32_t pll_mult, pll_div;
973         uint32_t mpuclk, sysclk;
974         struct omap4_prcm_softc *sc = omap4_prcm_sc;
975
976         if (sc == NULL)
977                 return ENXIO;
978
979         /* Read the clksel register which contains the DPLL multiple and divide
980          * values.  These are applied to the sysclk.
981          */
982         clksel = bus_read_4(sc->sc_res[CM1_INSTANCE_MEM_REGION], CM_CLKSEL_DPLL_MPU);
983
984         pll_mult = ((clksel >> 8) & 0x7ff);
985         pll_div = (clksel & 0x7f) + 1;
986         
987         
988         /* Get the system clock freq */
989         omap4_clk_get_sysclk_freq(NULL, &sysclk);
990
991
992         /* Calculate the MPU freq */
993         mpuclk = ((uint64_t)sysclk * pll_mult) / pll_div;
994
995         /* Return the value */
996         if (freq)
997                 *freq = mpuclk;
998                 
999         return (0);
1000 }
1001
1002 /**
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.
1006  *      
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.
1011  *
1012  *      LOCKING:
1013  *      Inherits the locks from the omap_prcm driver, no internal locking.
1014  *
1015  *      RETURNS:
1016  *      Returns 0 on success or a positive error code on failure.
1017  */
1018
1019 struct dpll_param {
1020         unsigned int m;
1021         unsigned int n;
1022         unsigned int m2;
1023         unsigned int m3;
1024         unsigned int m4;
1025         unsigned int m5;
1026         unsigned int m6;
1027         unsigned int m7;
1028 };
1029 /* USB parameters */
1030 struct dpll_param usb_dpll_param[7] = {
1031         /* 12M values */
1032         {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1033         /* 13M values */
1034         {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1035         /* 16.8M values */
1036         {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1037         /* 19.2M values */
1038         {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1039         /* 26M values */
1040         {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1041         /* 27M values */
1042         {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
1043         /* 38.4M values */
1044 #ifdef CONFIG_OMAP4_SDC
1045         {0x32, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0},
1046 #else
1047         {0x32, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0},
1048 #endif
1049 };
1050 static int
1051 omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev)
1052 {
1053         struct omap4_prcm_softc *sc = omap4_prcm_sc;
1054         struct resource* clk_mem_res;
1055         uint32_t clksel_reg_off;
1056         uint32_t clksel;
1057         unsigned int i;
1058
1059         if (sc == NULL)
1060                 return ENXIO;
1061
1062         switch (clkdev->id) {
1063         case USBTLL_CLK:
1064                 /* For the USBTLL module we need to enable the following clocks:
1065                  *  - INIT_L4_ICLK  (will be enabled by bootloader)
1066                  *  - TLL_CH0_FCLK
1067                  *  - TLL_CH1_FCLK
1068                  */
1069
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;
1073         
1074                 /* Enable the module and also enable the optional func clocks for
1075                  * channels 0 & 1 (is this needed ?)
1076                  */
1077                 clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1078                 clksel &= ~CLKCTRL_MODULEMODE_MASK;
1079                 clksel |=  CLKCTRL_MODULEMODE_ENABLE;
1080                 
1081                 clksel |= (0x1 << 8); /* USB-HOST optional clock: USB_CH0_CLK */
1082                 clksel |= (0x1 << 9); /* USB-HOST optional clock: USB_CH1_CLK */
1083                 break;
1084
1085         case USBHSHOST_CLK:
1086         case USBP1_PHY_CLK:
1087         case USBP2_PHY_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)
1095                  *  - INIT_48MC_FCLK
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 ?)
1103                  */
1104
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;
1113
1114                         clksel |= (0x1 << 15); /* USB-HOST clock control: FUNC48MCLK */
1115                 }
1116                 
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 */
1121
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 */
1126                 
1127                 break;
1128         
1129         default:
1130                 return (EINVAL);
1131         }
1132         
1133         bus_write_4(clk_mem_res, clksel_reg_off, clksel);
1134         
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)
1139                         break;
1140         }
1141                 
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);
1146                 return (ETIMEDOUT);
1147         }
1148         
1149         return (0);
1150 }
1151
1152 /**
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.
1156  *      
1157  *      
1158  *
1159  *      LOCKING:
1160  *      Inherits the locks from the omap_prcm driver, no internal locking.
1161  *
1162  *      RETURNS:
1163  *      Returns 0 on success or a positive error code on failure.
1164  */
1165 static int
1166 omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev)
1167 {
1168         struct omap4_prcm_softc *sc = omap4_prcm_sc;
1169         struct resource* clk_mem_res;
1170         uint32_t clksel_reg_off;
1171         uint32_t clksel;
1172
1173         if (sc == NULL)
1174                 return ENXIO;
1175
1176         switch (clkdev->id) {
1177         case USBTLL_CLK:
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;
1181         
1182                 clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1183                 clksel &= ~CLKCTRL_MODULEMODE_MASK;
1184                 clksel |=  CLKCTRL_MODULEMODE_DISABLE;
1185                 break;
1186
1187         case USBHSHOST_CLK:
1188         case USBP1_PHY_CLK:
1189         case USBP2_PHY_CLK:
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)
1197                  *  - INIT_48MC_FCLK
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 ?)
1205                  */
1206
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);
1211
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;
1216
1217                         clksel &= ~(0x1 << 15); /* USB-HOST clock control: FUNC48MCLK */
1218                 }
1219                 
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 */
1224
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 */
1229                 
1230                 break;
1231         
1232         default:
1233                 return (EINVAL);
1234         }
1235         
1236         bus_write_4(clk_mem_res, clksel_reg_off, clksel);
1237
1238         return (0);
1239 }
1240
1241 /**
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.
1245  *      
1246  *      
1247  *
1248  *      LOCKING:
1249  *      Inherits the locks from the omap_prcm driver, no internal locking.
1250  *
1251  *      RETURNS:
1252  *      Returns 0 if module is not enable, 1 if module is enabled or a negative
1253  *      error code on failure.
1254  */
1255 static int
1256 omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev)
1257 {
1258         struct omap4_prcm_softc *sc = omap4_prcm_sc;
1259         struct resource* clk_mem_res;
1260         uint32_t clksel_reg_off;
1261         uint32_t clksel;
1262
1263         if (sc == NULL)
1264                 return ENXIO;
1265
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;
1270         }
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;
1275         }
1276         else {
1277                 return (EINVAL);
1278         }
1279
1280         clksel = bus_read_4(clk_mem_res, clksel_reg_off);
1281                 
1282         /* Check the enabled state */
1283         if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED)
1284                 return (0);
1285         
1286         return (1);
1287 }
1288
1289 /**
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.
1294  *      
1295  *      
1296  *
1297  *      LOCKING:
1298  *      Inherits the locks from the omap_prcm driver, no internal locking.
1299  *
1300  *      RETURNS:
1301  *      Returns 0 if sucessful otherwise a negative error code on failure.
1302  */
1303 static int
1304 omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev,
1305                                clk_src_t clksrc)
1306 {
1307         struct omap4_prcm_softc *sc = omap4_prcm_sc;
1308         struct resource* clk_mem_res;
1309         uint32_t clksel_reg_off;
1310         uint32_t clksel;
1311         unsigned int bit;
1312
1313         if (sc == NULL)
1314                 return ENXIO;
1315
1316         if (clkdev->id == USBP1_PHY_CLK)
1317                 bit = 24;
1318         else if (clkdev->id != USBP2_PHY_CLK)
1319                 bit = 25;
1320         else
1321                 return (EINVAL);
1322         
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);
1327         
1328         /* Set the clock source to either external or internal */
1329         if (clksrc == EXT_CLK)
1330                 clksel |= (0x1 << bit);
1331         else
1332                 clksel &= ~(0x1 << bit);
1333         
1334         bus_write_4(clk_mem_res, clksel_reg_off, clksel);
1335
1336         return (0);
1337 }
1338
1339 #define PRM_RSTCTRL             0x1b00
1340 #define PRM_RSTCTRL_RESET       0x2
1341
1342 static void
1343 omap4_prcm_reset(void)
1344 {
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);
1349 }
1350
1351 /**
1352  *      omap4_prcm_probe - probe function for the driver
1353  *      @dev: prcm device handle
1354  *
1355  *      Simply sets the name of the driver module.
1356  *
1357  *      LOCKING:
1358  *      None
1359  *
1360  *      RETURNS:
1361  *      Always returns 0
1362  */
1363 static int
1364 omap4_prcm_probe(device_t dev)
1365 {
1366
1367         if (!ofw_bus_status_okay(dev))
1368                 return (ENXIO);
1369
1370         if (!ofw_bus_is_compatible(dev, "ti,omap4_prcm"))
1371                 return (ENXIO);
1372
1373         device_set_desc(dev, "TI OMAP Power, Reset and Clock Management");
1374         return (0);
1375 }
1376
1377 /**
1378  *      omap_prcm_attach - attach function for the driver
1379  *      @dev: prcm device handle
1380  *
1381  *      Allocates and sets up the driver context, this simply entails creating a
1382  *      bus mappings for the PRCM register set.
1383  *
1384  *      LOCKING:
1385  *      None
1386  *
1387  *      RETURNS:
1388  *      Always returns 0
1389  */
1390
1391 extern uint32_t platform_arm_tmr_freq;
1392
1393 static int
1394 omap4_prcm_attach(device_t dev)
1395 {
1396         struct omap4_prcm_softc *sc = device_get_softc(dev);
1397         unsigned int freq;
1398
1399         if (bus_alloc_resources(dev, omap4_scm_res_spec, sc->sc_res)) {
1400                 device_printf(dev, "could not allocate resources\n");
1401                 return (ENXIO);
1402         }
1403
1404         omap4_prcm_sc = sc;
1405         ti_cpu_reset = omap4_prcm_reset;
1406         omap4_clk_get_arm_fclk_freq(NULL, &freq);
1407         arm_tmr_change_frequency(freq / 2);
1408
1409         return (0);
1410 }
1411
1412 static device_method_t omap4_prcm_methods[] = {
1413         DEVMETHOD(device_probe, omap4_prcm_probe),
1414         DEVMETHOD(device_attach, omap4_prcm_attach),
1415         {0, 0},
1416 };
1417
1418 static driver_t omap4_prcm_driver = {
1419         "omap4_prcm",
1420         omap4_prcm_methods,
1421         sizeof(struct omap4_prcm_softc),
1422 };
1423
1424 static devclass_t omap4_prcm_devclass;
1425
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);