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