]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/ti/am335x/am335x_prcm.c
Update clang to trunk r290819 and resolve conflicts.
[FreeBSD/FreeBSD.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/ofw/openfirm.h>
49 #include <dev/ofw/ofw_bus.h>
50 #include <dev/ofw/ofw_bus_subr.h>
51
52 #include <machine/bus.h>
53
54 #include "am335x_scm.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_SPI0_CLKCTRL             (CM_PER + 0x04C)
69 #define CM_PER_SPI1_CLKCTRL             (CM_PER + 0x050)
70 #define CM_PER_UART1_CLKCTRL            (CM_PER + 0x06C)
71 #define CM_PER_UART2_CLKCTRL            (CM_PER + 0x070)
72 #define CM_PER_UART3_CLKCTRL            (CM_PER + 0x074)
73 #define CM_PER_UART4_CLKCTRL            (CM_PER + 0x078)
74 #define CM_PER_TIMER7_CLKCTRL           (CM_PER + 0x07C)
75 #define CM_PER_TIMER2_CLKCTRL           (CM_PER + 0x080)
76 #define CM_PER_TIMER3_CLKCTRL           (CM_PER + 0x084)
77 #define CM_PER_TIMER4_CLKCTRL           (CM_PER + 0x088)
78 #define CM_PER_GPIO1_CLKCTRL            (CM_PER + 0x0AC)
79 #define CM_PER_GPIO2_CLKCTRL            (CM_PER + 0x0B0)
80 #define CM_PER_GPIO3_CLKCTRL            (CM_PER + 0x0B4)
81 #define CM_PER_TPCC_CLKCTRL             (CM_PER + 0x0BC)
82 #define CM_PER_EPWMSS1_CLKCTRL          (CM_PER + 0x0CC)
83 #define CM_PER_EPWMSS0_CLKCTRL          (CM_PER + 0x0D4)
84 #define CM_PER_EPWMSS2_CLKCTRL          (CM_PER + 0x0D8)
85 #define CM_PER_L3_INSTR_CLKCTRL         (CM_PER + 0x0DC)
86 #define CM_PER_L3_CLKCTRL               (CM_PER + 0x0E0)
87 #define CM_PER_PRUSS_CLKCTRL            (CM_PER + 0x0E8)
88 #define CM_PER_TIMER5_CLKCTRL           (CM_PER + 0x0EC)
89 #define CM_PER_TIMER6_CLKCTRL           (CM_PER + 0x0F0)
90 #define CM_PER_MMC1_CLKCTRL             (CM_PER + 0x0F4)
91 #define CM_PER_MMC2_CLKCTRL             (CM_PER + 0x0F8)
92 #define CM_PER_TPTC1_CLKCTRL            (CM_PER + 0x0FC)
93 #define CM_PER_TPTC2_CLKCTRL            (CM_PER + 0x100)
94 #define CM_PER_SPINLOCK0_CLKCTRL        (CM_PER + 0x10C)
95 #define CM_PER_MAILBOX0_CLKCTRL         (CM_PER + 0x110)
96 #define CM_PER_OCPWP_L3_CLKSTCTRL       (CM_PER + 0x12C)
97 #define CM_PER_OCPWP_CLKCTRL            (CM_PER + 0x130)
98 #define CM_PER_CPSW_CLKSTCTRL           (CM_PER + 0x144)
99 #define CM_PER_PRUSS_CLKSTCTRL          (CM_PER + 0x140)
100
101 #define CM_WKUP                         0x400
102 #define CM_WKUP_CLKSTCTRL               (CM_WKUP + 0x000)
103 #define CM_WKUP_CONTROL_CLKCTRL         (CM_WKUP + 0x004)
104 #define CM_WKUP_GPIO0_CLKCTRL           (CM_WKUP + 0x008)
105 #define CM_WKUP_CM_L3_AON_CLKSTCTRL     (CM_WKUP + 0x01C)
106 #define CM_WKUP_CM_CLKSEL_DPLL_MPU      (CM_WKUP + 0x02C)
107 #define CM_WKUP_CM_IDLEST_DPLL_DISP     (CM_WKUP + 0x048)
108 #define CM_WKUP_CM_CLKSEL_DPLL_DISP     (CM_WKUP + 0x054)
109 #define CM_WKUP_CM_CLKDCOLDO_DPLL_PER   (CM_WKUP + 0x07C)
110 #define CM_WKUP_CM_CLKMODE_DPLL_DISP    (CM_WKUP + 0x098)
111 #define CM_WKUP_I2C0_CLKCTRL            (CM_WKUP + 0x0B8)
112 #define CM_WKUP_ADC_TSC_CLKCTRL         (CM_WKUP + 0x0BC)
113
114 #define CM_DPLL                         0x500
115 #define CLKSEL_TIMER7_CLK               (CM_DPLL + 0x004)
116 #define CLKSEL_TIMER2_CLK               (CM_DPLL + 0x008)
117 #define CLKSEL_TIMER3_CLK               (CM_DPLL + 0x00C)
118 #define CLKSEL_TIMER4_CLK               (CM_DPLL + 0x010)
119 #define CLKSEL_TIMER5_CLK               (CM_DPLL + 0x018)
120 #define CLKSEL_TIMER6_CLK               (CM_DPLL + 0x01C)
121 #define CLKSEL_PRUSS_OCP_CLK            (CM_DPLL + 0x030)
122
123 #define CM_RTC                          0x800
124 #define CM_RTC_RTC_CLKCTRL              (CM_RTC + 0x000)
125 #define CM_RTC_CLKSTCTRL                (CM_RTC + 0x004)
126
127 #define PRM_PER                         0xC00
128 #define PRM_PER_RSTCTRL                 (PRM_PER + 0x00)
129
130 #define PRM_DEVICE_OFFSET               0xF00
131 #define PRM_RSTCTRL                     (PRM_DEVICE_OFFSET + 0x00)
132
133 struct am335x_prcm_softc {
134         struct resource *       res[2];
135         bus_space_tag_t         bst;
136         bus_space_handle_t      bsh;
137 };
138
139 static struct resource_spec am335x_prcm_spec[] = {
140         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
141         { -1, 0 }
142 };
143
144 static struct am335x_prcm_softc *am335x_prcm_sc = NULL;
145
146 static int am335x_clk_noop_activate(struct ti_clock_dev *clkdev);
147 static int am335x_clk_generic_activate(struct ti_clock_dev *clkdev);
148 static int am335x_clk_gpio_activate(struct ti_clock_dev *clkdev);
149 static int am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev);
150 static int am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev);
151 static int am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
152 static int am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
153 static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,  unsigned int *freq);
154 static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
155 static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
156 static int am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
157 static int am335x_clk_set_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int freq);
158 static void am335x_prcm_reset(void);
159 static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev);
160 static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev);
161 static int am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev);
162 static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev);
163
164 #define AM335X_NOOP_CLOCK_DEV(i) \
165         {       .id = (i), \
166                 .clk_activate = am335x_clk_noop_activate, \
167                 .clk_deactivate = am335x_clk_noop_deactivate, \
168                 .clk_set_source = am335x_clk_noop_set_source, \
169                 .clk_accessible = NULL, \
170                 .clk_get_source_freq = NULL, \
171                 .clk_set_source_freq = NULL \
172         }
173
174 #define AM335X_GENERIC_CLOCK_DEV(i) \
175         {       .id = (i), \
176                 .clk_activate = am335x_clk_generic_activate, \
177                 .clk_deactivate = am335x_clk_generic_deactivate, \
178                 .clk_set_source = am335x_clk_generic_set_source, \
179                 .clk_accessible = NULL, \
180                 .clk_get_source_freq = NULL, \
181                 .clk_set_source_freq = NULL \
182         }
183
184 #define AM335X_GPIO_CLOCK_DEV(i) \
185         {       .id = (i), \
186                 .clk_activate = am335x_clk_gpio_activate, \
187                 .clk_deactivate = am335x_clk_generic_deactivate, \
188                 .clk_set_source = am335x_clk_generic_set_source, \
189                 .clk_accessible = NULL, \
190                 .clk_get_source_freq = NULL, \
191                 .clk_set_source_freq = NULL \
192         }
193
194 #define AM335X_MMCHS_CLOCK_DEV(i) \
195         {       .id = (i), \
196                 .clk_activate = am335x_clk_generic_activate, \
197                 .clk_deactivate = am335x_clk_generic_deactivate, \
198                 .clk_set_source = am335x_clk_generic_set_source, \
199                 .clk_accessible = NULL, \
200                 .clk_get_source_freq = am335x_clk_hsmmc_get_source_freq, \
201                 .clk_set_source_freq = NULL \
202         }
203
204 struct ti_clock_dev ti_am335x_clk_devmap[] = {
205         /* System clocks */
206         {       .id                  = SYS_CLK,
207                 .clk_activate        = NULL,
208                 .clk_deactivate      = NULL,
209                 .clk_set_source      = NULL,
210                 .clk_accessible      = NULL,
211                 .clk_get_source_freq = am335x_clk_get_sysclk_freq,
212                 .clk_set_source_freq = NULL,
213         },
214         /* MPU (ARM) core clocks */
215         {       .id                  = MPU_CLK,
216                 .clk_activate        = NULL,
217                 .clk_deactivate      = NULL,
218                 .clk_set_source      = NULL,
219                 .clk_accessible      = NULL,
220                 .clk_get_source_freq = am335x_clk_get_arm_fclk_freq,
221                 .clk_set_source_freq = NULL,
222         },
223         /* CPSW Ethernet Switch core clocks */
224         {       .id                  = CPSW_CLK,
225                 .clk_activate        = am335x_clk_cpsw_activate,
226                 .clk_deactivate      = NULL,
227                 .clk_set_source      = NULL,
228                 .clk_accessible      = NULL,
229                 .clk_get_source_freq = NULL,
230                 .clk_set_source_freq = NULL,
231         },
232
233         /* Mentor USB HS controller core clocks */
234         {       .id                  = MUSB0_CLK,
235                 .clk_activate        = am335x_clk_musb0_activate,
236                 .clk_deactivate      = NULL,
237                 .clk_set_source      = NULL,
238                 .clk_accessible      = NULL,
239                 .clk_get_source_freq = NULL,
240                 .clk_set_source_freq = NULL,
241         },
242
243         /* LCD controller clocks */
244         {       .id                  = LCDC_CLK,
245                 .clk_activate        = am335x_clk_lcdc_activate,
246                 .clk_deactivate      = NULL,
247                 .clk_set_source      = NULL,
248                 .clk_accessible      = NULL,
249                 .clk_get_source_freq = am335x_clk_get_arm_disp_freq,
250                 .clk_set_source_freq = am335x_clk_set_arm_disp_freq,
251         },
252
253         /* UART */
254         AM335X_NOOP_CLOCK_DEV(UART1_CLK),
255         AM335X_GENERIC_CLOCK_DEV(UART2_CLK),
256         AM335X_GENERIC_CLOCK_DEV(UART3_CLK),
257         AM335X_GENERIC_CLOCK_DEV(UART4_CLK),
258         AM335X_GENERIC_CLOCK_DEV(UART5_CLK),
259         AM335X_GENERIC_CLOCK_DEV(UART6_CLK),
260
261         /* DMTimer */
262         AM335X_GENERIC_CLOCK_DEV(TIMER2_CLK),
263         AM335X_GENERIC_CLOCK_DEV(TIMER3_CLK),
264         AM335X_GENERIC_CLOCK_DEV(TIMER4_CLK),
265         AM335X_GENERIC_CLOCK_DEV(TIMER5_CLK),
266         AM335X_GENERIC_CLOCK_DEV(TIMER6_CLK),
267         AM335X_GENERIC_CLOCK_DEV(TIMER7_CLK),
268
269         /* GPIO, we use hwmods as reference, not units in spec */
270         AM335X_GPIO_CLOCK_DEV(GPIO1_CLK),
271         AM335X_GPIO_CLOCK_DEV(GPIO2_CLK),
272         AM335X_GPIO_CLOCK_DEV(GPIO3_CLK),
273         AM335X_GPIO_CLOCK_DEV(GPIO4_CLK),
274
275         /* I2C we use hwmods as reference, not units in spec */
276         AM335X_GENERIC_CLOCK_DEV(I2C1_CLK),
277         AM335X_GENERIC_CLOCK_DEV(I2C2_CLK),
278         AM335X_GENERIC_CLOCK_DEV(I2C3_CLK),
279
280         /* McSPI we use hwmods as reference, not units in spec */
281         AM335X_GENERIC_CLOCK_DEV(SPI0_CLK),
282         AM335X_GENERIC_CLOCK_DEV(SPI1_CLK),
283
284         /* TSC_ADC */
285         AM335X_GENERIC_CLOCK_DEV(TSC_ADC_CLK),
286
287         /* EDMA */
288         AM335X_GENERIC_CLOCK_DEV(EDMA_TPCC_CLK),
289         AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC0_CLK),
290         AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC1_CLK),
291         AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK),
292
293         /* MMCHS */
294         AM335X_MMCHS_CLOCK_DEV(MMC1_CLK),
295         AM335X_MMCHS_CLOCK_DEV(MMC2_CLK),
296         AM335X_MMCHS_CLOCK_DEV(MMC3_CLK),
297
298         /* PWMSS */
299         AM335X_GENERIC_CLOCK_DEV(PWMSS0_CLK),
300         AM335X_GENERIC_CLOCK_DEV(PWMSS1_CLK),
301         AM335X_GENERIC_CLOCK_DEV(PWMSS2_CLK),
302
303         /* System Mailbox clock */
304         AM335X_GENERIC_CLOCK_DEV(MAILBOX0_CLK),
305
306         /* SPINLOCK */
307         AM335X_GENERIC_CLOCK_DEV(SPINLOCK0_CLK),
308
309         /* PRU-ICSS */
310         {       .id                  = PRUSS_CLK,
311                 .clk_activate        = am335x_clk_pruss_activate,
312                 .clk_deactivate      = NULL,
313                 .clk_set_source      = NULL,
314                 .clk_accessible      = NULL,
315                 .clk_get_source_freq = NULL,
316                 .clk_set_source_freq = NULL,
317         },
318
319         /* RTC */
320         AM335X_GENERIC_CLOCK_DEV(RTC_CLK),
321
322         {  INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
323 };
324
325 struct am335x_clk_details {
326         clk_ident_t     id;
327         uint32_t        clkctrl_reg;
328         uint32_t        clksel_reg;
329 };
330
331 #define _CLK_DETAIL(i, c, s) \
332         {       .id = (i), \
333                 .clkctrl_reg = (c), \
334                 .clksel_reg = (s), \
335         }
336
337 static struct am335x_clk_details g_am335x_clk_details[] = {
338
339         /* UART. UART0 clock not controllable. */
340         _CLK_DETAIL(UART1_CLK, 0, 0),
341         _CLK_DETAIL(UART2_CLK, CM_PER_UART1_CLKCTRL, 0),
342         _CLK_DETAIL(UART3_CLK, CM_PER_UART2_CLKCTRL, 0),
343         _CLK_DETAIL(UART4_CLK, CM_PER_UART3_CLKCTRL, 0),
344         _CLK_DETAIL(UART5_CLK, CM_PER_UART4_CLKCTRL, 0),
345         _CLK_DETAIL(UART6_CLK, CM_PER_UART5_CLKCTRL, 0),
346
347         /* DMTimer modules */
348         _CLK_DETAIL(TIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK),
349         _CLK_DETAIL(TIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK),
350         _CLK_DETAIL(TIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK),
351         _CLK_DETAIL(TIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK),
352         _CLK_DETAIL(TIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK),
353         _CLK_DETAIL(TIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK),
354
355         /* GPIO modules, hwmods start with gpio1 */
356         _CLK_DETAIL(GPIO1_CLK, CM_WKUP_GPIO0_CLKCTRL, 0),
357         _CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO1_CLKCTRL, 0),
358         _CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO2_CLKCTRL, 0),
359         _CLK_DETAIL(GPIO4_CLK, CM_PER_GPIO3_CLKCTRL, 0),
360
361         /* I2C modules, hwmods start with i2c1 */
362         _CLK_DETAIL(I2C1_CLK, CM_WKUP_I2C0_CLKCTRL, 0),
363         _CLK_DETAIL(I2C2_CLK, CM_PER_I2C1_CLKCTRL, 0),
364         _CLK_DETAIL(I2C3_CLK, CM_PER_I2C2_CLKCTRL, 0),
365
366         /* McSPI modules, hwmods start with spi0 */
367         _CLK_DETAIL(SPI0_CLK, CM_PER_SPI0_CLKCTRL, 0),
368         _CLK_DETAIL(SPI1_CLK, CM_PER_SPI1_CLKCTRL, 0),
369
370         /* TSC_ADC module */
371         _CLK_DETAIL(TSC_ADC_CLK, CM_WKUP_ADC_TSC_CLKCTRL, 0),
372
373         /* EDMA modules */
374         _CLK_DETAIL(EDMA_TPCC_CLK, CM_PER_TPCC_CLKCTRL, 0),
375         _CLK_DETAIL(EDMA_TPTC0_CLK, CM_PER_TPTC0_CLKCTRL, 0),
376         _CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0),
377         _CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0),
378
379         /* MMCHS modules, hwmods start with mmc1*/
380         _CLK_DETAIL(MMC1_CLK, CM_PER_MMC0_CLKCTRL, 0),
381         _CLK_DETAIL(MMC2_CLK, CM_PER_MMC1_CLKCTRL, 0),
382         _CLK_DETAIL(MMC3_CLK, CM_PER_MMC1_CLKCTRL, 0),
383
384         /* PWMSS modules */
385         _CLK_DETAIL(PWMSS0_CLK, CM_PER_EPWMSS0_CLKCTRL, 0),
386         _CLK_DETAIL(PWMSS1_CLK, CM_PER_EPWMSS1_CLKCTRL, 0),
387         _CLK_DETAIL(PWMSS2_CLK, CM_PER_EPWMSS2_CLKCTRL, 0),
388
389         _CLK_DETAIL(MAILBOX0_CLK, CM_PER_MAILBOX0_CLKCTRL, 0),
390         _CLK_DETAIL(SPINLOCK0_CLK, CM_PER_SPINLOCK0_CLKCTRL, 0),
391
392         /* RTC module */
393         _CLK_DETAIL(RTC_CLK, CM_RTC_RTC_CLKCTRL, 0),
394
395         { INVALID_CLK_IDENT, 0},
396 };
397
398 /* Read/Write macros */
399 #define prcm_read_4(reg)                \
400         bus_space_read_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg)
401 #define prcm_write_4(reg, val)          \
402         bus_space_write_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg, val)
403
404 void am335x_prcm_setup_dmtimer(int);
405
406 static int
407 am335x_prcm_probe(device_t dev)
408 {
409
410         if (!ofw_bus_status_okay(dev))
411                 return (ENXIO);
412
413         if (ofw_bus_is_compatible(dev, "ti,am3-prcm")) {
414                 device_set_desc(dev, "AM335x Power and Clock Management");
415                 return(BUS_PROBE_DEFAULT);
416         }
417
418         return (ENXIO);
419 }
420
421 static int
422 am335x_prcm_attach(device_t dev)
423 {
424         struct am335x_prcm_softc *sc = device_get_softc(dev);
425         unsigned int sysclk, fclk;
426
427         if (am335x_prcm_sc)
428                 return (ENXIO);
429
430         if (bus_alloc_resources(dev, am335x_prcm_spec, sc->res)) {
431                 device_printf(dev, "could not allocate resources\n");
432                 return (ENXIO);
433         }
434
435         sc->bst = rman_get_bustag(sc->res[0]);
436         sc->bsh = rman_get_bushandle(sc->res[0]);
437
438         am335x_prcm_sc = sc;
439         ti_cpu_reset = am335x_prcm_reset;
440
441         if (am335x_clk_get_sysclk_freq(NULL, &sysclk) != 0)
442                 sysclk = 0;
443         if (am335x_clk_get_arm_fclk_freq(NULL, &fclk) != 0)
444                 fclk = 0;
445         if (sysclk && fclk)
446                 device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n",
447                     sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000);
448         else
449                 device_printf(dev, "can't read frequencies yet (SCM device not ready?)\n");
450
451         return (0);
452 }
453
454 static device_method_t am335x_prcm_methods[] = {
455         DEVMETHOD(device_probe,         am335x_prcm_probe),
456         DEVMETHOD(device_attach,        am335x_prcm_attach),
457         { 0, 0 }
458 };
459
460 static driver_t am335x_prcm_driver = {
461         "am335x_prcm",
462         am335x_prcm_methods,
463         sizeof(struct am335x_prcm_softc),
464 };
465
466 static devclass_t am335x_prcm_devclass;
467
468 DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver,
469         am335x_prcm_devclass, 0, 0);
470 MODULE_VERSION(am335x_prcm, 1);
471 MODULE_DEPEND(am335x_prcm, ti_scm, 1, 1, 1);
472
473 static struct am335x_clk_details*
474 am335x_clk_details(clk_ident_t id)
475 {
476         struct am335x_clk_details *walker;
477
478         for (walker = g_am335x_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
479                 if (id == walker->id)
480                         return (walker);
481         }
482
483         return NULL;
484 }
485
486 static int
487 am335x_clk_noop_activate(struct ti_clock_dev *clkdev)
488 {
489
490         return (0);
491 }
492
493 static int
494 am335x_clk_generic_activate(struct ti_clock_dev *clkdev)
495 {
496         struct am335x_prcm_softc *sc = am335x_prcm_sc;
497         struct am335x_clk_details* clk_details;
498
499         if (sc == NULL)
500                 return ENXIO;
501
502         clk_details = am335x_clk_details(clkdev->id);
503
504         if (clk_details == NULL)
505                 return (ENXIO);
506
507         /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
508         prcm_write_4(clk_details->clkctrl_reg, 2);
509         while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 2)
510                 DELAY(10);
511
512         return (0);
513 }
514
515 static int
516 am335x_clk_gpio_activate(struct ti_clock_dev *clkdev)
517 {
518         struct am335x_prcm_softc *sc = am335x_prcm_sc;
519         struct am335x_clk_details* clk_details;
520
521         if (sc == NULL)
522                 return ENXIO;
523
524         clk_details = am335x_clk_details(clkdev->id);
525
526         if (clk_details == NULL)
527                 return (ENXIO);
528
529         /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
530         /* set *_CLKCTRL register OPTFCLKEN_GPIO_1_G DBCLK[18] to FCLK_EN(1) */
531         prcm_write_4(clk_details->clkctrl_reg, 2 | (1 << 18));
532         while ((prcm_read_4(clk_details->clkctrl_reg) &
533             (3 | (1 << 18) )) != (2 | (1 << 18)))
534                 DELAY(10);
535
536         return (0);
537 }
538
539 static int
540 am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev)
541 {
542
543         return(0);
544 }
545
546 static int
547 am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev)
548 {
549         struct am335x_prcm_softc *sc = am335x_prcm_sc;
550         struct am335x_clk_details* clk_details;
551
552         if (sc == NULL)
553                 return ENXIO;
554
555         clk_details = am335x_clk_details(clkdev->id);
556
557         if (clk_details == NULL)
558                 return (ENXIO);
559
560         /* set *_CLKCTRL register MODULEMODE[1:0] to disable(0) */
561         prcm_write_4(clk_details->clkctrl_reg, 0);
562         while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 0)
563                 DELAY(10);
564
565         return (0);
566 }
567
568 static int
569 am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
570 {
571
572         return (0);
573 }
574
575 static int
576 am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
577 {
578         struct am335x_prcm_softc *sc = am335x_prcm_sc;
579         struct am335x_clk_details* clk_details;
580         uint32_t reg;
581
582         if (sc == NULL)
583                 return ENXIO;
584
585         clk_details = am335x_clk_details(clkdev->id);
586
587         if (clk_details == NULL)
588                 return (ENXIO);
589
590         switch (clksrc) {
591                 case EXT_CLK:
592                         reg = 0; /* SEL2: TCLKIN clock */
593                         break;
594                 case SYSCLK_CLK:
595                         reg = 1; /* SEL1: CLK_M_OSC clock */
596                         break;
597                 case F32KHZ_CLK:
598                         reg = 2; /* SEL3: CLK_32KHZ clock */
599                         break;
600                 default:
601                         return (ENXIO);
602         }
603
604         prcm_write_4(clk_details->clksel_reg, reg);
605         while ((prcm_read_4(clk_details->clksel_reg) & 0x3) != reg)
606                 DELAY(10);
607
608         return (0);
609 }
610
611 static int
612 am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,  unsigned int *freq)
613 {
614         *freq = 96000000;
615         return (0);
616 }
617
618 static int
619 am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
620 {
621         uint32_t ctrl_status;
622
623         /* Read the input clock freq from the control module. */
624         if (ti_scm_reg_read_4(SCM_CTRL_STATUS, &ctrl_status))
625                 return (ENXIO);
626
627         switch ((ctrl_status>>22) & 0x3) {
628         case 0x0:
629                 /* 19.2Mhz */
630                 *freq = 19200000;
631                 break;
632         case 0x1:
633                 /* 24Mhz */
634                 *freq = 24000000;
635                 break;
636         case 0x2:
637                 /* 25Mhz */
638                 *freq = 25000000;
639                 break;
640         case 0x3:
641                 /* 26Mhz */
642                 *freq = 26000000;
643                 break;
644         }
645
646         return (0);
647 }
648
649 #define DPLL_BYP_CLKSEL(reg)    ((reg>>23) & 1)
650 #define DPLL_DIV(reg)           ((reg & 0x7f)+1)
651 #define DPLL_MULT(reg)          ((reg>>8) & 0x7FF)
652 #define DPLL_MAX_MUL            0x800
653 #define DPLL_MAX_DIV            0x80
654
655 static int
656 am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
657 {
658         uint32_t reg;
659         uint32_t sysclk;
660
661         reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_MPU);
662
663         /*Check if we are running in bypass */
664         if (DPLL_BYP_CLKSEL(reg))
665                 return ENXIO;
666
667         am335x_clk_get_sysclk_freq(NULL, &sysclk);
668         *freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
669         return(0);
670 }
671
672 static int
673 am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
674 {
675         uint32_t reg;
676         uint32_t sysclk;
677
678         reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_DISP);
679
680         /*Check if we are running in bypass */
681         if (DPLL_BYP_CLKSEL(reg))
682                 return ENXIO;
683
684         am335x_clk_get_sysclk_freq(NULL, &sysclk);
685         *freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
686         return(0);
687 }
688
689 static int
690 am335x_clk_set_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int freq)
691 {
692         uint32_t sysclk;
693         uint32_t mul, div;
694         uint32_t i, j;
695         unsigned int delta, min_delta;
696
697         am335x_clk_get_sysclk_freq(NULL, &sysclk);
698
699         /* Bypass mode */
700         prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x4);
701
702         /* Make sure it's in bypass mode */
703         while (!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
704             & (1 << 8)))
705                 DELAY(10);
706
707         /* Dumb and non-optimal implementation */
708         min_delta = freq;
709         for (i = 1; i < DPLL_MAX_MUL; i++) {
710                 for (j = 1; j < DPLL_MAX_DIV; j++) {
711                         delta = abs(freq - i*(sysclk/j));
712                         if (delta < min_delta) {
713                                 mul = i;
714                                 div = j;
715                                 min_delta = delta;
716                         }
717                         if (min_delta == 0)
718                                 break;
719                 }
720         }
721
722         prcm_write_4(CM_WKUP_CM_CLKSEL_DPLL_DISP, (mul << 8) | (div - 1));
723
724         /* Locked mode */
725         prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x7);
726
727         int timeout = 10000;
728         while ((!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
729             & (1 << 0))) && timeout--)
730                 DELAY(10);
731
732         return(0);
733 }
734
735 static void
736 am335x_prcm_reset(void)
737 {
738         prcm_write_4(PRM_RSTCTRL, (1<<1));
739 }
740
741 static int
742 am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev)
743 {
744         struct am335x_prcm_softc *sc = am335x_prcm_sc;
745
746         if (sc == NULL)
747                 return ENXIO;
748
749         /* set MODULENAME to ENABLE */
750         prcm_write_4(CM_PER_CPGMAC0_CLKCTRL, 2);
751
752         /* wait for IDLEST to become Func(0) */
753         while(prcm_read_4(CM_PER_CPGMAC0_CLKCTRL) & (3<<16));
754
755         /*set CLKTRCTRL to SW_WKUP(2) */
756         prcm_write_4(CM_PER_CPSW_CLKSTCTRL, 2);
757
758         /* wait for 125 MHz OCP clock to become active */
759         while((prcm_read_4(CM_PER_CPSW_CLKSTCTRL) & (1<<4)) == 0);
760         return(0);
761 }
762
763 static int
764 am335x_clk_musb0_activate(struct ti_clock_dev *clkdev)
765 {
766         struct am335x_prcm_softc *sc = am335x_prcm_sc;
767
768         if (sc == NULL)
769                 return ENXIO;
770
771         /* set ST_DPLL_CLKDCOLDO(9) to CLK_GATED(1) */
772         /* set DPLL_CLKDCOLDO_GATE_CTRL(8) to CLK_ENABLE(1)*/
773         prcm_write_4(CM_WKUP_CM_CLKDCOLDO_DPLL_PER, 0x300);
774
775         /*set MODULEMODE to ENABLE(2) */
776         prcm_write_4(CM_PER_USB0_CLKCTRL, 2);
777
778         /* wait for MODULEMODE to become ENABLE(2) */
779         while ((prcm_read_4(CM_PER_USB0_CLKCTRL) & 0x3) != 2)
780                 DELAY(10);
781
782         /* wait for IDLEST to become Func(0) */
783         while(prcm_read_4(CM_PER_USB0_CLKCTRL) & (3<<16))
784                 DELAY(10);
785
786         return(0);
787 }
788
789 static int
790 am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev)
791 {
792         struct am335x_prcm_softc *sc = am335x_prcm_sc;
793
794         if (sc == NULL)
795                 return (ENXIO);
796
797         /*
798          * For now set frequency to 2*VGA_PIXEL_CLOCK 
799          */
800         am335x_clk_set_arm_disp_freq(clkdev, 25175000*2);
801
802         /*set MODULEMODE to ENABLE(2) */
803         prcm_write_4(CM_PER_LCDC_CLKCTRL, 2);
804
805         /* wait for MODULEMODE to become ENABLE(2) */
806         while ((prcm_read_4(CM_PER_LCDC_CLKCTRL) & 0x3) != 2)
807                 DELAY(10);
808
809         /* wait for IDLEST to become Func(0) */
810         while(prcm_read_4(CM_PER_LCDC_CLKCTRL) & (3<<16))
811                 DELAY(10);
812
813         return (0);
814 }
815
816 static int
817 am335x_clk_pruss_activate(struct ti_clock_dev *clkdev)
818 {
819         struct am335x_prcm_softc *sc = am335x_prcm_sc;
820
821         if (sc == NULL)
822                 return (ENXIO);
823
824         /* Set MODULEMODE to ENABLE(2) */
825         prcm_write_4(CM_PER_PRUSS_CLKCTRL, 2);
826
827         /* Wait for MODULEMODE to become ENABLE(2) */
828         while ((prcm_read_4(CM_PER_PRUSS_CLKCTRL) & 0x3) != 2)
829                 DELAY(10);
830
831         /* Set CLKTRCTRL to SW_WKUP(2) */
832         prcm_write_4(CM_PER_PRUSS_CLKSTCTRL, 2);
833
834         /* Wait for the 200 MHz OCP clock to become active */
835         while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<4)) == 0)
836                 DELAY(10);
837
838         /* Wait for the 200 MHz IEP clock to become active */
839         while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<5)) == 0)
840                 DELAY(10);
841
842         /* Wait for the 192 MHz UART clock to become active */
843         while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<6)) == 0)
844                 DELAY(10);
845
846         /* Select L3F as OCP clock */
847         prcm_write_4(CLKSEL_PRUSS_OCP_CLK, 0);
848         while ((prcm_read_4(CLKSEL_PRUSS_OCP_CLK) & 0x3) != 0)
849                 DELAY(10);
850
851         /* Clear the RESET bit */
852         prcm_write_4(PRM_PER_RSTCTRL, prcm_read_4(PRM_PER_RSTCTRL) & ~2);
853
854         return (0);
855 }