]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/arm/ti/am335x/am335x_prcm.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / arm / ti / am335x / am335x_prcm.c
1 /*-
2  * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/bus.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/malloc.h>
36 #include <sys/rman.h>
37 #include <sys/timeet.h>
38 #include <sys/timetc.h>
39 #include <sys/watchdog.h>
40 #include <machine/bus.h>
41 #include <machine/cpu.h>
42 #include <machine/intr.h>
43
44 #include <arm/ti/tivar.h>
45 #include <arm/ti/ti_scm.h>
46 #include <arm/ti/ti_prcm.h>
47
48 #include <dev/fdt/fdt_common.h>
49 #include <dev/ofw/openfirm.h>
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52
53 #include <machine/bus.h>
54 #include <machine/fdt.h>
55
56 #define CM_PER                          0
57 #define CM_PER_L4LS_CLKSTCTRL           (CM_PER + 0x000)
58 #define CM_PER_L3S_CLKSTCTRL            (CM_PER + 0x004)
59 #define CM_PER_L3_CLKSTCTRL             (CM_PER + 0x00C)
60 #define CM_PER_CPGMAC0_CLKCTRL          (CM_PER + 0x014)
61 #define CM_PER_LCDC_CLKCTRL             (CM_PER + 0x018)
62 #define CM_PER_USB0_CLKCTRL             (CM_PER + 0x01C)
63 #define CM_PER_TPTC0_CLKCTRL            (CM_PER + 0x024)
64 #define CM_PER_UART5_CLKCTRL            (CM_PER + 0x038)
65 #define CM_PER_MMC0_CLKCTRL             (CM_PER + 0x03C)
66 #define CM_PER_I2C2_CLKCTRL             (CM_PER + 0x044)
67 #define CM_PER_I2C1_CLKCTRL             (CM_PER + 0x048)
68 #define CM_PER_UART1_CLKCTRL            (CM_PER + 0x06C)
69 #define CM_PER_UART2_CLKCTRL            (CM_PER + 0x070)
70 #define CM_PER_UART3_CLKCTRL            (CM_PER + 0x074)
71 #define CM_PER_UART4_CLKCTRL            (CM_PER + 0x078)
72 #define CM_PER_TIMER7_CLKCTRL           (CM_PER + 0x07C)
73 #define CM_PER_TIMER2_CLKCTRL           (CM_PER + 0x080)
74 #define CM_PER_TIMER3_CLKCTRL           (CM_PER + 0x084)
75 #define CM_PER_TIMER4_CLKCTRL           (CM_PER + 0x088)
76 #define CM_PER_GPIO1_CLKCTRL            (CM_PER + 0x0AC)
77 #define CM_PER_GPIO2_CLKCTRL            (CM_PER + 0x0B0)
78 #define CM_PER_GPIO3_CLKCTRL            (CM_PER + 0x0B4)
79 #define CM_PER_TPCC_CLKCTRL             (CM_PER + 0x0BC)
80 #define CM_PER_EPWMSS1_CLKCTRL          (CM_PER + 0x0CC)
81 #define CM_PER_EPWMSS0_CLKCTRL          (CM_PER + 0x0D4)
82 #define CM_PER_EPWMSS2_CLKCTRL          (CM_PER + 0x0D8)
83 #define CM_PER_L3_INSTR_CLKCTRL         (CM_PER + 0x0DC)
84 #define CM_PER_L3_CLKCTRL               (CM_PER + 0x0E0)
85 #define CM_PER_PRUSS_CLKCTRL            (CM_PER + 0x0E8)
86 #define CM_PER_TIMER5_CLKCTRL           (CM_PER + 0x0EC)
87 #define CM_PER_TIMER6_CLKCTRL           (CM_PER + 0x0F0)
88 #define CM_PER_MMC1_CLKCTRL             (CM_PER + 0x0F4)
89 #define CM_PER_MMC2_CLKCTRL             (CM_PER + 0x0F8)
90 #define CM_PER_TPTC1_CLKCTRL            (CM_PER + 0x0FC)
91 #define CM_PER_TPTC2_CLKCTRL            (CM_PER + 0x100)
92 #define CM_PER_SPINLOCK0_CLKCTRL        (CM_PER + 0x10C)
93 #define CM_PER_MAILBOX0_CLKCTRL         (CM_PER + 0x110)
94 #define CM_PER_OCPWP_L3_CLKSTCTRL       (CM_PER + 0x12C)
95 #define CM_PER_OCPWP_CLKCTRL            (CM_PER + 0x130)
96 #define CM_PER_CPSW_CLKSTCTRL           (CM_PER + 0x144)
97 #define CM_PER_PRUSS_CLKSTCTRL          (CM_PER + 0x140)
98
99 #define CM_WKUP                         0x400
100 #define CM_WKUP_CLKSTCTRL               (CM_WKUP + 0x000)
101 #define CM_WKUP_CONTROL_CLKCTRL         (CM_WKUP + 0x004)
102 #define CM_WKUP_GPIO0_CLKCTRL           (CM_WKUP + 0x008)
103 #define CM_WKUP_CM_L3_AON_CLKSTCTRL     (CM_WKUP + 0x01C)
104 #define CM_WKUP_CM_CLKSEL_DPLL_MPU      (CM_WKUP + 0x02C)
105 #define CM_WKUP_CM_IDLEST_DPLL_DISP     (CM_WKUP + 0x048)
106 #define CM_WKUP_CM_CLKSEL_DPLL_DISP     (CM_WKUP + 0x054)
107 #define CM_WKUP_CM_CLKDCOLDO_DPLL_PER   (CM_WKUP + 0x07C)
108 #define CM_WKUP_CM_CLKMODE_DPLL_DISP    (CM_WKUP + 0x098)
109 #define CM_WKUP_I2C0_CLKCTRL            (CM_WKUP + 0x0B8)
110 #define CM_WKUP_ADC_TSC_CLKCTRL         (CM_WKUP + 0x0BC)
111
112 #define CM_DPLL                         0x500
113 #define CLKSEL_TIMER7_CLK               (CM_DPLL + 0x004)
114 #define CLKSEL_TIMER2_CLK               (CM_DPLL + 0x008)
115 #define CLKSEL_TIMER3_CLK               (CM_DPLL + 0x00C)
116 #define CLKSEL_TIMER4_CLK               (CM_DPLL + 0x010)
117 #define CLKSEL_TIMER5_CLK               (CM_DPLL + 0x018)
118 #define CLKSEL_TIMER6_CLK               (CM_DPLL + 0x01C)
119 #define CLKSEL_PRUSS_OCP_CLK            (CM_DPLL + 0x030)
120
121 #define CM_RTC                          0x800
122 #define CM_RTC_RTC_CLKCTRL              (CM_RTC + 0x000)
123 #define CM_RTC_CLKSTCTRL                (CM_RTC + 0x004)
124
125 #define PRM_PER                         0xC00
126 #define PRM_PER_RSTCTRL                 (PRM_PER + 0x00)
127
128 #define PRM_DEVICE_OFFSET               0xF00
129 #define PRM_RSTCTRL                     (PRM_DEVICE_OFFSET + 0x00)
130
131 struct am335x_prcm_softc {
132         struct resource *       res[2];
133         bus_space_tag_t         bst;
134         bus_space_handle_t      bsh;
135 };
136
137 static struct resource_spec am335x_prcm_spec[] = {
138         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
139         { -1, 0 }
140 };
141
142 static struct am335x_prcm_softc *am335x_prcm_sc = NULL;
143
144 static int am335x_clk_noop_activate(struct ti_clock_dev *clkdev);
145 static int am335x_clk_generic_activate(struct ti_clock_dev *clkdev);
146 static int am335x_clk_gpio_activate(struct ti_clock_dev *clkdev);
147 static int am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev);
148 static int am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev);
149 static int am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
150 static int am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
151 static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,  unsigned int *freq);
152 static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
153 static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
154 static int am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
155 static void am335x_prcm_reset(void);
156 static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev);
157 static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev);
158 static int am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev);
159 static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev);
160
161 #define AM335X_NOOP_CLOCK_DEV(i) \
162         {       .id = (i), \
163                 .clk_activate = am335x_clk_noop_activate, \
164                 .clk_deactivate = am335x_clk_noop_deactivate, \
165                 .clk_set_source = am335x_clk_noop_set_source, \
166                 .clk_accessible = NULL, \
167                 .clk_get_source_freq = NULL \
168         }
169
170 #define AM335X_GENERIC_CLOCK_DEV(i) \
171         {       .id = (i), \
172                 .clk_activate = am335x_clk_generic_activate, \
173                 .clk_deactivate = am335x_clk_generic_deactivate, \
174                 .clk_set_source = am335x_clk_generic_set_source, \
175                 .clk_accessible = NULL, \
176                 .clk_get_source_freq = NULL \
177         }
178
179 #define AM335X_GPIO_CLOCK_DEV(i) \
180         {       .id = (i), \
181                 .clk_activate = am335x_clk_gpio_activate, \
182                 .clk_deactivate = am335x_clk_generic_deactivate, \
183                 .clk_set_source = am335x_clk_generic_set_source, \
184                 .clk_accessible = NULL, \
185                 .clk_get_source_freq = NULL \
186         }
187
188 #define AM335X_MMCHS_CLOCK_DEV(i) \
189         {       .id = (i), \
190                 .clk_activate = am335x_clk_generic_activate, \
191                 .clk_deactivate = am335x_clk_generic_deactivate, \
192                 .clk_set_source = am335x_clk_generic_set_source, \
193                 .clk_accessible = NULL, \
194                 .clk_get_source_freq = am335x_clk_hsmmc_get_source_freq \
195         }
196
197 struct ti_clock_dev ti_clk_devmap[] = {
198         /* System clocks */
199         {       .id                  = SYS_CLK,
200                 .clk_activate        = NULL,
201                 .clk_deactivate      = NULL,
202                 .clk_set_source      = NULL,
203                 .clk_accessible      = NULL,
204                 .clk_get_source_freq = am335x_clk_get_sysclk_freq,
205         },
206         /* MPU (ARM) core clocks */
207         {       .id                  = MPU_CLK,
208                 .clk_activate        = NULL,
209                 .clk_deactivate      = NULL,
210                 .clk_set_source      = NULL,
211                 .clk_accessible      = NULL,
212                 .clk_get_source_freq = am335x_clk_get_arm_fclk_freq,
213         },
214         /* CPSW Ethernet Switch core clocks */
215         {       .id                  = CPSW_CLK,
216                 .clk_activate        = am335x_clk_cpsw_activate,
217                 .clk_deactivate      = NULL,
218                 .clk_set_source      = NULL,
219                 .clk_accessible      = NULL,
220                 .clk_get_source_freq = NULL,
221         },
222
223         /* Mentor USB HS controller core clocks */
224         {       .id                  = MUSB0_CLK,
225                 .clk_activate        = am335x_clk_musb0_activate,
226                 .clk_deactivate      = NULL,
227                 .clk_set_source      = NULL,
228                 .clk_accessible      = NULL,
229                 .clk_get_source_freq = NULL,
230         },
231
232         /* LCD controller clocks */
233         {       .id                  = LCDC_CLK,
234                 .clk_activate        = am335x_clk_lcdc_activate,
235                 .clk_deactivate      = NULL,
236                 .clk_set_source      = NULL,
237                 .clk_accessible      = NULL,
238                 .clk_get_source_freq = am335x_clk_get_arm_disp_freq,
239         },
240
241         /* UART.  Uart0 clock cannot be controlled. */
242         AM335X_NOOP_CLOCK_DEV(UART0_CLK),
243         AM335X_GENERIC_CLOCK_DEV(UART1_CLK),
244         AM335X_GENERIC_CLOCK_DEV(UART2_CLK),
245         AM335X_GENERIC_CLOCK_DEV(UART3_CLK),
246         AM335X_GENERIC_CLOCK_DEV(UART4_CLK),
247         AM335X_GENERIC_CLOCK_DEV(UART5_CLK),
248
249         /* DMTimer */
250         AM335X_GENERIC_CLOCK_DEV(DMTIMER2_CLK),
251         AM335X_GENERIC_CLOCK_DEV(DMTIMER3_CLK),
252         AM335X_GENERIC_CLOCK_DEV(DMTIMER4_CLK),
253         AM335X_GENERIC_CLOCK_DEV(DMTIMER5_CLK),
254         AM335X_GENERIC_CLOCK_DEV(DMTIMER6_CLK),
255         AM335X_GENERIC_CLOCK_DEV(DMTIMER7_CLK),
256
257         /* GPIO */
258         AM335X_GPIO_CLOCK_DEV(GPIO0_CLK),
259         AM335X_GPIO_CLOCK_DEV(GPIO1_CLK),
260         AM335X_GPIO_CLOCK_DEV(GPIO2_CLK),
261         AM335X_GPIO_CLOCK_DEV(GPIO3_CLK),
262
263         /* I2C */
264         AM335X_GENERIC_CLOCK_DEV(I2C0_CLK),
265         AM335X_GENERIC_CLOCK_DEV(I2C1_CLK),
266         AM335X_GENERIC_CLOCK_DEV(I2C2_CLK),
267
268         /* TSC_ADC */
269         AM335X_GENERIC_CLOCK_DEV(TSC_ADC_CLK),
270
271         /* EDMA */
272         AM335X_GENERIC_CLOCK_DEV(EDMA_TPCC_CLK),
273         AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC0_CLK),
274         AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC1_CLK),
275         AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK),
276
277         /* MMCHS */
278         AM335X_MMCHS_CLOCK_DEV(MMC0_CLK),
279         AM335X_MMCHS_CLOCK_DEV(MMC1_CLK),
280         AM335X_MMCHS_CLOCK_DEV(MMC2_CLK),
281
282         /* PWMSS */
283         AM335X_GENERIC_CLOCK_DEV(PWMSS0_CLK),
284         AM335X_GENERIC_CLOCK_DEV(PWMSS1_CLK),
285         AM335X_GENERIC_CLOCK_DEV(PWMSS2_CLK),
286
287         /* System Mailbox clock */
288         AM335X_GENERIC_CLOCK_DEV(MAILBOX0_CLK),
289
290         /* SPINLOCK */
291         AM335X_GENERIC_CLOCK_DEV(SPINLOCK0_CLK),
292
293         /* PRU-ICSS */
294         {       .id                  = PRUSS_CLK,
295                 .clk_activate        = am335x_clk_pruss_activate,
296                 .clk_deactivate      = NULL,
297                 .clk_set_source      = NULL,
298                 .clk_accessible      = NULL,
299                 .clk_get_source_freq = NULL,
300         },
301
302         /* RTC */
303         AM335X_GENERIC_CLOCK_DEV(RTC_CLK),
304
305         {  INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
306 };
307
308 struct am335x_clk_details {
309         clk_ident_t     id;
310         uint32_t        clkctrl_reg;
311         uint32_t        clksel_reg;
312 };
313
314 #define _CLK_DETAIL(i, c, s) \
315         {       .id = (i), \
316                 .clkctrl_reg = (c), \
317                 .clksel_reg = (s), \
318         }
319
320 static struct am335x_clk_details g_am335x_clk_details[] = {
321
322         /* UART. UART0 clock not controllable. */
323         _CLK_DETAIL(UART0_CLK, 0, 0),
324         _CLK_DETAIL(UART1_CLK, CM_PER_UART1_CLKCTRL, 0),
325         _CLK_DETAIL(UART2_CLK, CM_PER_UART2_CLKCTRL, 0),
326         _CLK_DETAIL(UART3_CLK, CM_PER_UART3_CLKCTRL, 0),
327         _CLK_DETAIL(UART4_CLK, CM_PER_UART4_CLKCTRL, 0),
328         _CLK_DETAIL(UART5_CLK, CM_PER_UART5_CLKCTRL, 0),
329
330         /* DMTimer modules */
331         _CLK_DETAIL(DMTIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK),
332         _CLK_DETAIL(DMTIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK),
333         _CLK_DETAIL(DMTIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK),
334         _CLK_DETAIL(DMTIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK),
335         _CLK_DETAIL(DMTIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK),
336         _CLK_DETAIL(DMTIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK),
337
338         /* GPIO modules */
339         _CLK_DETAIL(GPIO0_CLK, CM_WKUP_GPIO0_CLKCTRL, 0),
340         _CLK_DETAIL(GPIO1_CLK, CM_PER_GPIO1_CLKCTRL, 0),
341         _CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO2_CLKCTRL, 0),
342         _CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO3_CLKCTRL, 0),
343
344         /* I2C modules */
345         _CLK_DETAIL(I2C0_CLK, CM_WKUP_I2C0_CLKCTRL, 0),
346         _CLK_DETAIL(I2C1_CLK, CM_PER_I2C1_CLKCTRL, 0),
347         _CLK_DETAIL(I2C2_CLK, CM_PER_I2C2_CLKCTRL, 0),
348
349         /* TSC_ADC module */
350         _CLK_DETAIL(TSC_ADC_CLK, CM_WKUP_ADC_TSC_CLKCTRL, 0),
351
352         /* EDMA modules */
353         _CLK_DETAIL(EDMA_TPCC_CLK, CM_PER_TPCC_CLKCTRL, 0),
354         _CLK_DETAIL(EDMA_TPTC0_CLK, CM_PER_TPTC0_CLKCTRL, 0),
355         _CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0),
356         _CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0),
357
358         /* MMCHS modules*/
359         _CLK_DETAIL(MMC0_CLK, CM_PER_MMC0_CLKCTRL, 0),
360         _CLK_DETAIL(MMC1_CLK, CM_PER_MMC1_CLKCTRL, 0),
361         _CLK_DETAIL(MMC2_CLK, CM_PER_MMC1_CLKCTRL, 0),
362
363         /* PWMSS modules */
364         _CLK_DETAIL(PWMSS0_CLK, CM_PER_EPWMSS0_CLKCTRL, 0),
365         _CLK_DETAIL(PWMSS1_CLK, CM_PER_EPWMSS1_CLKCTRL, 0),
366         _CLK_DETAIL(PWMSS2_CLK, CM_PER_EPWMSS2_CLKCTRL, 0),
367
368         _CLK_DETAIL(MAILBOX0_CLK, CM_PER_MAILBOX0_CLKCTRL, 0),
369         _CLK_DETAIL(SPINLOCK0_CLK, CM_PER_SPINLOCK0_CLKCTRL, 0),
370
371         /* RTC module */
372         _CLK_DETAIL(RTC_CLK, CM_RTC_RTC_CLKCTRL, 0),
373
374         { INVALID_CLK_IDENT, 0},
375 };
376
377 /* Read/Write macros */
378 #define prcm_read_4(reg)                \
379         bus_space_read_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg)
380 #define prcm_write_4(reg, val)          \
381         bus_space_write_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg, val)
382
383 void am335x_prcm_setup_dmtimer(int);
384
385 static int
386 am335x_prcm_probe(device_t dev)
387 {
388
389         if (!ofw_bus_status_okay(dev))
390                 return (ENXIO);
391
392         if (ofw_bus_is_compatible(dev, "am335x,prcm")) {
393                 device_set_desc(dev, "AM335x Power and Clock Management");
394                 return(BUS_PROBE_DEFAULT);
395         }
396
397         return (ENXIO);
398 }
399
400 static int
401 am335x_prcm_attach(device_t dev)
402 {
403         struct am335x_prcm_softc *sc = device_get_softc(dev);
404         unsigned int sysclk, fclk;
405
406         if (am335x_prcm_sc)
407                 return (ENXIO);
408
409         if (bus_alloc_resources(dev, am335x_prcm_spec, sc->res)) {
410                 device_printf(dev, "could not allocate resources\n");
411                 return (ENXIO);
412         }
413
414         sc->bst = rman_get_bustag(sc->res[0]);
415         sc->bsh = rman_get_bushandle(sc->res[0]);
416
417         am335x_prcm_sc = sc;
418         ti_cpu_reset = am335x_prcm_reset;
419
420         am335x_clk_get_sysclk_freq(NULL, &sysclk);
421         am335x_clk_get_arm_fclk_freq(NULL, &fclk);
422         device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n",
423                 sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000);
424
425         return (0);
426 }
427
428 static device_method_t am335x_prcm_methods[] = {
429         DEVMETHOD(device_probe,         am335x_prcm_probe),
430         DEVMETHOD(device_attach,        am335x_prcm_attach),
431         { 0, 0 }
432 };
433
434 static driver_t am335x_prcm_driver = {
435         "am335x_prcm",
436         am335x_prcm_methods,
437         sizeof(struct am335x_prcm_softc),
438 };
439
440 static devclass_t am335x_prcm_devclass;
441
442 DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver,
443         am335x_prcm_devclass, 0, 0);
444 MODULE_DEPEND(am335x_prcm, ti_scm, 1, 1, 1);
445
446 static struct am335x_clk_details*
447 am335x_clk_details(clk_ident_t id)
448 {
449         struct am335x_clk_details *walker;
450
451         for (walker = g_am335x_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
452                 if (id == walker->id)
453                         return (walker);
454         }
455
456         return NULL;
457 }
458
459 static int
460 am335x_clk_noop_activate(struct ti_clock_dev *clkdev)
461 {
462
463         return (0);
464 }
465
466 static int
467 am335x_clk_generic_activate(struct ti_clock_dev *clkdev)
468 {
469         struct am335x_prcm_softc *sc = am335x_prcm_sc;
470         struct am335x_clk_details* clk_details;
471
472         if (sc == NULL)
473                 return ENXIO;
474
475         clk_details = am335x_clk_details(clkdev->id);
476
477         if (clk_details == NULL)
478                 return (ENXIO);
479
480         /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
481         prcm_write_4(clk_details->clkctrl_reg, 2);
482         while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 2)
483                 DELAY(10);
484
485         return (0);
486 }
487
488 static int
489 am335x_clk_gpio_activate(struct ti_clock_dev *clkdev)
490 {
491         struct am335x_prcm_softc *sc = am335x_prcm_sc;
492         struct am335x_clk_details* clk_details;
493
494         if (sc == NULL)
495                 return ENXIO;
496
497         clk_details = am335x_clk_details(clkdev->id);
498
499         if (clk_details == NULL)
500                 return (ENXIO);
501
502         /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
503         /* set *_CLKCTRL register OPTFCLKEN_GPIO_1_G DBCLK[18] to FCLK_EN(1) */
504         prcm_write_4(clk_details->clkctrl_reg, 2 | (1 << 18));
505         while ((prcm_read_4(clk_details->clkctrl_reg) &
506             (3 | (1 << 18) )) != (2 | (1 << 18)))
507                 DELAY(10);
508
509         return (0);
510 }
511
512 static int
513 am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev)
514 {
515
516         return(0);
517 }
518
519 static int
520 am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev)
521 {
522         struct am335x_prcm_softc *sc = am335x_prcm_sc;
523         struct am335x_clk_details* clk_details;
524
525         if (sc == NULL)
526                 return ENXIO;
527
528         clk_details = am335x_clk_details(clkdev->id);
529
530         if (clk_details == NULL)
531                 return (ENXIO);
532
533         /* set *_CLKCTRL register MODULEMODE[1:0] to disable(0) */
534         prcm_write_4(clk_details->clkctrl_reg, 0);
535         while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 0)
536                 DELAY(10);
537
538         return (0);
539 }
540
541 static int
542 am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
543 {
544
545         return (0);
546 }
547
548 static int
549 am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
550 {
551         struct am335x_prcm_softc *sc = am335x_prcm_sc;
552         struct am335x_clk_details* clk_details;
553         uint32_t reg;
554
555         if (sc == NULL)
556                 return ENXIO;
557
558         clk_details = am335x_clk_details(clkdev->id);
559
560         if (clk_details == NULL)
561                 return (ENXIO);
562
563         switch (clksrc) {
564                 case EXT_CLK:
565                         reg = 0; /* SEL2: TCLKIN clock */
566                         break;
567                 case SYSCLK_CLK:
568                         reg = 1; /* SEL1: CLK_M_OSC clock */
569                         break;
570                 case F32KHZ_CLK:
571                         reg = 2; /* SEL3: CLK_32KHZ clock */
572                         break;
573                 default:
574                         return (ENXIO);
575         }
576
577         prcm_write_4(clk_details->clksel_reg, reg);
578         while ((prcm_read_4(clk_details->clksel_reg) & 0x3) != reg)
579                 DELAY(10);
580
581         return (0);
582 }
583
584 static int
585 am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,  unsigned int *freq)
586 {
587         *freq = 96000000;
588         return (0);
589 }
590
591 static int
592 am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
593 {
594         uint32_t ctrl_status;
595
596         /* Read the input clock freq from the control module */
597         /* control_status reg (0x40) */
598         if (ti_scm_reg_read_4(0x40, &ctrl_status))
599                 return ENXIO;
600
601         switch ((ctrl_status>>22) & 0x3) {
602         case 0x0:
603                 /* 19.2Mhz */
604                 *freq = 19200000;
605                 break;
606         case 0x1:
607                 /* 24Mhz */
608                 *freq = 24000000;
609                 break;
610         case 0x2:
611                 /* 25Mhz */
612                 *freq = 25000000;
613                 break;
614         case 0x3:
615                 /* 26Mhz */
616                 *freq = 26000000;
617                 break;
618         }
619
620         return (0);
621 }
622
623 #define DPLL_BYP_CLKSEL(reg)    ((reg>>23) & 1)
624 #define DPLL_DIV(reg)           ((reg & 0x7f)+1)
625 #define DPLL_MULT(reg)          ((reg>>8) & 0x7FF)
626
627 static int
628 am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
629 {
630         uint32_t reg;
631         uint32_t sysclk;
632
633         reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_MPU);
634
635         /*Check if we are running in bypass */
636         if (DPLL_BYP_CLKSEL(reg))
637                 return ENXIO;
638
639         am335x_clk_get_sysclk_freq(NULL, &sysclk);
640         *freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
641         return(0);
642 }
643
644 static int
645 am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
646 {
647         uint32_t reg;
648         uint32_t sysclk;
649
650         reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_DISP);
651
652         /*Check if we are running in bypass */
653         if (DPLL_BYP_CLKSEL(reg))
654                 return ENXIO;
655
656         am335x_clk_get_sysclk_freq(NULL, &sysclk);
657         *freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
658         return(0);
659 }
660
661 static void
662 am335x_prcm_reset(void)
663 {
664         prcm_write_4(PRM_RSTCTRL, (1<<1));
665 }
666
667 static int
668 am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev)
669 {
670         struct am335x_prcm_softc *sc = am335x_prcm_sc;
671
672         if (sc == NULL)
673                 return ENXIO;
674
675         /* set MODULENAME to ENABLE */
676         prcm_write_4(CM_PER_CPGMAC0_CLKCTRL, 2);
677
678         /* wait for IDLEST to become Func(0) */
679         while(prcm_read_4(CM_PER_CPGMAC0_CLKCTRL) & (3<<16));
680
681         /*set CLKTRCTRL to SW_WKUP(2) */
682         prcm_write_4(CM_PER_CPSW_CLKSTCTRL, 2);
683
684         /* wait for 125 MHz OCP clock to become active */
685         while((prcm_read_4(CM_PER_CPSW_CLKSTCTRL) & (1<<4)) == 0);
686         return(0);
687 }
688
689 static int
690 am335x_clk_musb0_activate(struct ti_clock_dev *clkdev)
691 {
692         struct am335x_prcm_softc *sc = am335x_prcm_sc;
693
694         if (sc == NULL)
695                 return ENXIO;
696
697         /* set ST_DPLL_CLKDCOLDO(9) to CLK_GATED(1) */
698         /* set DPLL_CLKDCOLDO_GATE_CTRL(8) to CLK_ENABLE(1)*/
699         prcm_write_4(CM_WKUP_CM_CLKDCOLDO_DPLL_PER, 0x300);
700
701         /*set MODULEMODE to ENABLE(2) */
702         prcm_write_4(CM_PER_USB0_CLKCTRL, 2);
703
704         /* wait for MODULEMODE to become ENABLE(2) */
705         while ((prcm_read_4(CM_PER_USB0_CLKCTRL) & 0x3) != 2)
706                 DELAY(10);
707
708         /* wait for IDLEST to become Func(0) */
709         while(prcm_read_4(CM_PER_USB0_CLKCTRL) & (3<<16))
710                 DELAY(10);
711
712         return(0);
713 }
714
715 static int
716 am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev)
717 {
718         struct am335x_prcm_softc *sc = am335x_prcm_sc;
719
720         if (sc == NULL)
721                 return (ENXIO);
722
723         /* Bypass mode */
724         prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x4);
725
726         /* Make sure it's in bypass mode */
727         while (!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
728             & (1 << 8)))
729                 DELAY(10);
730
731         /*
732          * For now set frequency to  5xSYSFREQ 
733          * More flexible control might be required
734          */
735         prcm_write_4(CM_WKUP_CM_CLKSEL_DPLL_DISP, (5 << 8) | 0);
736
737         /* Locked mode */
738         prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x7);
739
740         int timeout = 10000;
741         while ((!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
742             & (1 << 0))) && timeout--)
743                 DELAY(10);
744
745         /*set MODULEMODE to ENABLE(2) */
746         prcm_write_4(CM_PER_LCDC_CLKCTRL, 2);
747
748         /* wait for MODULEMODE to become ENABLE(2) */
749         while ((prcm_read_4(CM_PER_LCDC_CLKCTRL) & 0x3) != 2)
750                 DELAY(10);
751
752         /* wait for IDLEST to become Func(0) */
753         while(prcm_read_4(CM_PER_LCDC_CLKCTRL) & (3<<16))
754                 DELAY(10);
755
756         return (0);
757 }
758
759 static int
760 am335x_clk_pruss_activate(struct ti_clock_dev *clkdev)
761 {
762         struct am335x_prcm_softc *sc = am335x_prcm_sc;
763
764         if (sc == NULL)
765                 return (ENXIO);
766
767         /* Set MODULEMODE to ENABLE(2) */
768         prcm_write_4(CM_PER_PRUSS_CLKCTRL, 2);
769
770         /* Wait for MODULEMODE to become ENABLE(2) */
771         while ((prcm_read_4(CM_PER_PRUSS_CLKCTRL) & 0x3) != 2)
772                 DELAY(10);
773
774         /* Set CLKTRCTRL to SW_WKUP(2) */
775         prcm_write_4(CM_PER_PRUSS_CLKSTCTRL, 2);
776
777         /* Wait for the 200 MHz OCP clock to become active */
778         while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<4)) == 0)
779                 DELAY(10);
780
781         /* Wait for the 200 MHz IEP clock to become active */
782         while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<5)) == 0)
783                 DELAY(10);
784
785         /* Wait for the 192 MHz UART clock to become active */
786         while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<6)) == 0)
787                 DELAY(10);
788
789         /* Select L3F as OCP clock */
790         prcm_write_4(CLKSEL_PRUSS_OCP_CLK, 0);
791         while ((prcm_read_4(CLKSEL_PRUSS_OCP_CLK) & 0x3) != 0)
792                 DELAY(10);
793
794         /* Clear the RESET bit */
795         prcm_write_4(PRM_PER_RSTCTRL, prcm_read_4(PRM_PER_RSTCTRL) & ~2);
796
797         return (0);
798 }