am335x_prcm.c revision 239281
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: head/sys/arm/ti/am335x/am335x_prcm.c 239281 2012-08-15 06:31:32Z gonzo $");
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/frame.h>
43#include <machine/intr.h>
44
45#include <arm/ti/tivar.h>
46#include <arm/ti/ti_scm.h>
47#include <arm/ti/ti_prcm.h>
48
49#include <dev/fdt/fdt_common.h>
50#include <dev/ofw/openfirm.h>
51#include <dev/ofw/ofw_bus.h>
52#include <dev/ofw/ofw_bus_subr.h>
53
54#include <machine/bus.h>
55#include <machine/fdt.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_USB0_CLKCTRL		(CM_PER + 0x01C)
63#define CM_PER_TPTC0_CLKCTRL		(CM_PER + 0x024)
64#define CM_PER_MMC0_CLKCTRL		(CM_PER + 0x03C)
65#define CM_PER_I2C2_CLKCTRL		(CM_PER + 0x044)
66#define CM_PER_I2C1_CLKCTRL		(CM_PER + 0x048)
67#define CM_PER_TIMER7_CLKCTRL		(CM_PER + 0x07C)
68#define CM_PER_TIMER2_CLKCTRL		(CM_PER + 0x080)
69#define CM_PER_TIMER3_CLKCTRL		(CM_PER + 0x084)
70#define CM_PER_TIMER4_CLKCTRL		(CM_PER + 0x088)
71#define CM_PER_GPIO1_CLKCTRL		(CM_PER + 0x0AC)
72#define CM_PER_GPIO2_CLKCTRL		(CM_PER + 0x0B0)
73#define CM_PER_GPIO3_CLKCTRL		(CM_PER + 0x0B4)
74#define CM_PER_TPCC_CLKCTRL		(CM_PER + 0x0BC)
75#define CM_PER_L3_INSTR_CLKCTRL		(CM_PER + 0x0DC)
76#define CM_PER_L3_CLKCTRL		(CM_PER + 0x0E0)
77#define CM_PER_TIMER5_CLKCTRL		(CM_PER + 0x0EC)
78#define CM_PER_TIMER6_CLKCTRL		(CM_PER + 0x0F0)
79#define CM_PER_MMC1_CLKCTRL		(CM_PER + 0x0F4)
80#define CM_PER_MMC2_CLKCTRL		(CM_PER + 0x0F8)
81#define CM_PER_TPTC1_CLKCTRL		(CM_PER + 0x0FC)
82#define CM_PER_TPTC2_CLKCTRL		(CM_PER + 0x100)
83#define CM_PER_OCPWP_L3_CLKSTCTRL	(CM_PER + 0x12C)
84#define CM_PER_OCPWP_CLKCTRL		(CM_PER + 0x130)
85#define CM_PER_CPSW_CLKSTCTRL		(CM_PER + 0x144)
86
87#define CM_WKUP				0x400
88#define CM_WKUP_CLKSTCTRL		(CM_WKUP + 0x000)
89#define CM_WKUP_CONTROL_CLKCTRL		(CM_WKUP + 0x004)
90#define CM_WKUP_GPIO0_CLKCTRL		(CM_WKUP + 0x008)
91#define CM_WKUP_CM_L3_AON_CLKSTCTRL	(CM_WKUP + 0x01C)
92#define CM_WKUP_CM_CLKSEL_DPLL_MPU	(CM_WKUP + 0x02C)
93#define CM_WKUP_CM_CLKDCOLDO_DPLL_PER	(CM_WKUP + 0x07C)
94#define CM_WKUP_I2C0_CLKCTRL		(CM_WKUP + 0x0B8)
95
96#define CM_DPLL				0x500
97#define CLKSEL_TIMER7_CLK		(CM_DPLL + 0x004)
98#define CLKSEL_TIMER2_CLK		(CM_DPLL + 0x008)
99#define CLKSEL_TIMER3_CLK		(CM_DPLL + 0x00C)
100#define CLKSEL_TIMER4_CLK		(CM_DPLL + 0x010)
101#define CLKSEL_TIMER5_CLK		(CM_DPLL + 0x018)
102#define CLKSEL_TIMER6_CLK		(CM_DPLL + 0x01C)
103
104#define PRM_DEVICE_OFFSET		0xF00
105#define PRM_RSTCTRL			(PRM_DEVICE_OFFSET + 0x00)
106
107struct am335x_prcm_softc {
108	struct resource *	res[2];
109	bus_space_tag_t		bst;
110	bus_space_handle_t	bsh;
111};
112
113static struct resource_spec am335x_prcm_spec[] = {
114	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
115	{ -1, 0 }
116};
117
118static struct am335x_prcm_softc *am335x_prcm_sc = NULL;
119
120static int am335x_clk_generic_activate(struct ti_clock_dev *clkdev);
121static int am335x_clk_gpio_activate(struct ti_clock_dev *clkdev);
122static int am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev);
123static int am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
124static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,  unsigned int *freq);
125static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
126static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
127static void am335x_prcm_reset(void);
128static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev);
129static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev);
130
131#define AM335X_GENERIC_CLOCK_DEV(i) \
132	{	.id = (i), \
133		.clk_activate = am335x_clk_generic_activate, \
134		.clk_deactivate = am335x_clk_generic_deactivate, \
135		.clk_set_source = am335x_clk_generic_set_source, \
136		.clk_accessible = NULL, \
137		.clk_get_source_freq = NULL \
138	}
139
140#define AM335X_GPIO_CLOCK_DEV(i) \
141	{	.id = (i), \
142		.clk_activate = am335x_clk_gpio_activate, \
143		.clk_deactivate = am335x_clk_generic_deactivate, \
144		.clk_set_source = am335x_clk_generic_set_source, \
145		.clk_accessible = NULL, \
146		.clk_get_source_freq = NULL \
147	}
148
149#define AM335X_MMCHS_CLOCK_DEV(i) \
150	{	.id = (i), \
151		.clk_activate = am335x_clk_generic_activate, \
152		.clk_deactivate = am335x_clk_generic_deactivate, \
153		.clk_set_source = am335x_clk_generic_set_source, \
154		.clk_accessible = NULL, \
155		.clk_get_source_freq = am335x_clk_hsmmc_get_source_freq \
156	}
157
158struct ti_clock_dev ti_clk_devmap[] = {
159	/* System clocks */
160	{	.id                  = SYS_CLK,
161		.clk_activate        = NULL,
162		.clk_deactivate      = NULL,
163		.clk_set_source      = NULL,
164		.clk_accessible      = NULL,
165		.clk_get_source_freq = am335x_clk_get_sysclk_freq,
166	},
167	/* MPU (ARM) core clocks */
168	{	.id                  = MPU_CLK,
169		.clk_activate        = NULL,
170		.clk_deactivate      = NULL,
171		.clk_set_source      = NULL,
172		.clk_accessible      = NULL,
173		.clk_get_source_freq = am335x_clk_get_arm_fclk_freq,
174	},
175	/* CPSW Ethernet Switch core clocks */
176	{	.id                  = CPSW_CLK,
177		.clk_activate        = am335x_clk_cpsw_activate,
178		.clk_deactivate      = NULL,
179		.clk_set_source      = NULL,
180		.clk_accessible      = NULL,
181		.clk_get_source_freq = NULL,
182	},
183
184	/* Mentor USB HS controller core clocks */
185	{	.id                  = MUSB0_CLK,
186		.clk_activate        = am335x_clk_musb0_activate,
187		.clk_deactivate      = NULL,
188		.clk_set_source      = NULL,
189		.clk_accessible      = NULL,
190		.clk_get_source_freq = NULL,
191	},
192
193	/* DMTimer */
194	AM335X_GENERIC_CLOCK_DEV(DMTIMER2_CLK),
195	AM335X_GENERIC_CLOCK_DEV(DMTIMER3_CLK),
196	AM335X_GENERIC_CLOCK_DEV(DMTIMER4_CLK),
197	AM335X_GENERIC_CLOCK_DEV(DMTIMER5_CLK),
198	AM335X_GENERIC_CLOCK_DEV(DMTIMER6_CLK),
199	AM335X_GENERIC_CLOCK_DEV(DMTIMER7_CLK),
200
201	/* GPIO */
202	AM335X_GPIO_CLOCK_DEV(GPIO0_CLK),
203	AM335X_GPIO_CLOCK_DEV(GPIO1_CLK),
204	AM335X_GPIO_CLOCK_DEV(GPIO2_CLK),
205	AM335X_GPIO_CLOCK_DEV(GPIO3_CLK),
206
207	/* I2C */
208	AM335X_GENERIC_CLOCK_DEV(I2C0_CLK),
209	AM335X_GENERIC_CLOCK_DEV(I2C1_CLK),
210	AM335X_GENERIC_CLOCK_DEV(I2C2_CLK),
211
212	/* EDMA */
213	AM335X_GENERIC_CLOCK_DEV(EDMA_TPCC_CLK),
214	AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC0_CLK),
215	AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC1_CLK),
216	AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK),
217
218	/* MMCHS */
219	AM335X_MMCHS_CLOCK_DEV(MMC0_CLK),
220	AM335X_MMCHS_CLOCK_DEV(MMC1_CLK),
221	AM335X_MMCHS_CLOCK_DEV(MMC2_CLK),
222
223	{  INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
224};
225
226struct am335x_clk_details {
227	clk_ident_t	id;
228	uint32_t	clkctrl_reg;
229	uint32_t	clksel_reg;
230};
231
232#define _CLK_DETAIL(i, c, s) \
233	{	.id = (i), \
234		.clkctrl_reg = (c), \
235		.clksel_reg = (s), \
236	}
237
238static struct am335x_clk_details g_am335x_clk_details[] = {
239
240	/* DMTimer modules */
241	_CLK_DETAIL(DMTIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK),
242	_CLK_DETAIL(DMTIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK),
243	_CLK_DETAIL(DMTIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK),
244	_CLK_DETAIL(DMTIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK),
245	_CLK_DETAIL(DMTIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK),
246	_CLK_DETAIL(DMTIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK),
247
248	/* GPIO modules */
249	_CLK_DETAIL(GPIO0_CLK, CM_WKUP_GPIO0_CLKCTRL, 0),
250	_CLK_DETAIL(GPIO1_CLK, CM_PER_GPIO1_CLKCTRL, 0),
251	_CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO2_CLKCTRL, 0),
252	_CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO3_CLKCTRL, 0),
253
254	/* I2C modules */
255	_CLK_DETAIL(I2C0_CLK, CM_WKUP_I2C0_CLKCTRL, 0),
256	_CLK_DETAIL(I2C1_CLK, CM_PER_I2C1_CLKCTRL, 0),
257	_CLK_DETAIL(I2C2_CLK, CM_PER_I2C2_CLKCTRL, 0),
258
259	/* EDMA modules */
260	_CLK_DETAIL(EDMA_TPCC_CLK, CM_PER_TPCC_CLKCTRL, 0),
261	_CLK_DETAIL(EDMA_TPTC0_CLK, CM_PER_TPTC0_CLKCTRL, 0),
262	_CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0),
263	_CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0),
264
265	/* MMCHS modules*/
266	_CLK_DETAIL(MMC0_CLK, CM_PER_MMC0_CLKCTRL, 0),
267	_CLK_DETAIL(MMC1_CLK, CM_PER_MMC1_CLKCTRL, 0),
268	_CLK_DETAIL(MMC2_CLK, CM_PER_MMC1_CLKCTRL, 0),
269
270	{ INVALID_CLK_IDENT, 0},
271};
272
273/* Read/Write macros */
274#define prcm_read_4(reg)		\
275	bus_space_read_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg)
276#define prcm_write_4(reg, val)		\
277	bus_space_write_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg, val)
278
279void am335x_prcm_setup_dmtimer(int);
280
281static int
282am335x_prcm_probe(device_t dev)
283{
284	if (ofw_bus_is_compatible(dev, "am335x,prcm")) {
285		device_set_desc(dev, "AM335x Power and Clock Management");
286		return(BUS_PROBE_DEFAULT);
287	}
288
289	return (ENXIO);
290}
291
292static int
293am335x_prcm_attach(device_t dev)
294{
295	struct am335x_prcm_softc *sc = device_get_softc(dev);
296	unsigned int sysclk, fclk;
297
298	if (am335x_prcm_sc)
299		return (ENXIO);
300
301	if (bus_alloc_resources(dev, am335x_prcm_spec, sc->res)) {
302		device_printf(dev, "could not allocate resources\n");
303		return (ENXIO);
304	}
305
306	sc->bst = rman_get_bustag(sc->res[0]);
307	sc->bsh = rman_get_bushandle(sc->res[0]);
308
309	am335x_prcm_sc = sc;
310	ti_cpu_reset = am335x_prcm_reset;
311
312	am335x_clk_get_sysclk_freq(NULL, &sysclk);
313	am335x_clk_get_arm_fclk_freq(NULL, &fclk);
314	device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n",
315		sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000);
316
317	return (0);
318}
319
320static device_method_t am335x_prcm_methods[] = {
321	DEVMETHOD(device_probe,		am335x_prcm_probe),
322	DEVMETHOD(device_attach,	am335x_prcm_attach),
323	{ 0, 0 }
324};
325
326static driver_t am335x_prcm_driver = {
327	"am335x_prcm",
328	am335x_prcm_methods,
329	sizeof(struct am335x_prcm_softc),
330};
331
332static devclass_t am335x_prcm_devclass;
333
334DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver,
335	am335x_prcm_devclass, 0, 0);
336MODULE_DEPEND(am335x_prcm, ti_scm, 1, 1, 1);
337
338static struct am335x_clk_details*
339am335x_clk_details(clk_ident_t id)
340{
341	struct am335x_clk_details *walker;
342
343	for (walker = g_am335x_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
344		if (id == walker->id)
345			return (walker);
346	}
347
348	return NULL;
349}
350
351static int
352am335x_clk_generic_activate(struct ti_clock_dev *clkdev)
353{
354	struct am335x_prcm_softc *sc = am335x_prcm_sc;
355	struct am335x_clk_details* clk_details;
356
357	if (sc == NULL)
358		return ENXIO;
359
360	clk_details = am335x_clk_details(clkdev->id);
361
362	if (clk_details == NULL)
363		return (ENXIO);
364
365	/* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
366	prcm_write_4(clk_details->clkctrl_reg, 2);
367	while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 2)
368		DELAY(10);
369
370	return (0);
371}
372
373static int
374am335x_clk_gpio_activate(struct ti_clock_dev *clkdev)
375{
376	struct am335x_prcm_softc *sc = am335x_prcm_sc;
377	struct am335x_clk_details* clk_details;
378
379	if (sc == NULL)
380		return ENXIO;
381
382	clk_details = am335x_clk_details(clkdev->id);
383
384	if (clk_details == NULL)
385		return (ENXIO);
386
387	/* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
388	/* set *_CLKCTRL register OPTFCLKEN_GPIO_1_G DBCLK[18] to FCLK_EN(1) */
389	prcm_write_4(clk_details->clkctrl_reg, 2 | (1 << 18));
390	while ((prcm_read_4(clk_details->clkctrl_reg) &
391	    (3 | (1 << 18) )) != (2 | (1 << 18)))
392		DELAY(10);
393
394	return (0);
395}
396
397static int
398am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev)
399{
400	struct am335x_prcm_softc *sc = am335x_prcm_sc;
401	struct am335x_clk_details* clk_details;
402
403	if (sc == NULL)
404		return ENXIO;
405
406	clk_details = am335x_clk_details(clkdev->id);
407
408	if (clk_details == NULL)
409		return (ENXIO);
410
411	/* set *_CLKCTRL register MODULEMODE[1:0] to disable(0) */
412	prcm_write_4(clk_details->clkctrl_reg, 0);
413	while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 0)
414		DELAY(10);
415
416	return (0);
417}
418
419static int
420am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
421{
422	struct am335x_prcm_softc *sc = am335x_prcm_sc;
423	struct am335x_clk_details* clk_details;
424	uint32_t reg;
425
426	if (sc == NULL)
427		return ENXIO;
428
429	clk_details = am335x_clk_details(clkdev->id);
430
431	if (clk_details == NULL)
432		return (ENXIO);
433
434	switch (clksrc) {
435		case EXT_CLK:
436			reg = 0; /* SEL2: TCLKIN clock */
437			break;
438		case SYSCLK_CLK:
439			reg = 1; /* SEL1: CLK_M_OSC clock */
440			break;
441		case F32KHZ_CLK:
442			reg = 2; /* SEL3: CLK_32KHZ clock */
443			break;
444		default:
445			return (ENXIO);
446	}
447
448	prcm_write_4(clk_details->clksel_reg, reg);
449	while ((prcm_read_4(clk_details->clksel_reg) & 0x3) != reg)
450		DELAY(10);
451
452	return (0);
453}
454
455static int
456am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,  unsigned int *freq)
457{
458	*freq = 96000000;
459	return (0);
460}
461
462static int
463am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
464{
465	uint32_t ctrl_status;
466
467	/* Read the input clock freq from the control module */
468	/* control_status reg (0x40) */
469	if (ti_scm_reg_read_4(0x40, &ctrl_status))
470		return ENXIO;
471
472	switch ((ctrl_status>>22) & 0x3) {
473	case 0x0:
474		/* 19.2Mhz */
475		*freq = 19200000;
476		break;
477	case 0x1:
478		/* 24Mhz */
479		*freq = 24000000;
480		break;
481	case 0x2:
482		/* 25Mhz */
483		*freq = 25000000;
484		break;
485	case 0x3:
486		/* 26Mhz */
487		*freq = 26000000;
488		break;
489	}
490
491	return (0);
492}
493
494static int
495am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
496{
497	uint32_t reg;
498	uint32_t sysclk;
499#define DPLL_BYP_CLKSEL(reg)	((reg>>23) & 1)
500#define DPLL_DIV(reg)		((reg & 0x7f)+1)
501#define DPLL_MULT(reg)		((reg>>8) & 0x7FF)
502
503	reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_MPU);
504
505	/*Check if we are running in bypass */
506	if (DPLL_BYP_CLKSEL(reg))
507		return ENXIO;
508
509	am335x_clk_get_sysclk_freq(NULL, &sysclk);
510	*freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
511	return(0);
512}
513
514static void
515am335x_prcm_reset(void)
516{
517	prcm_write_4(PRM_RSTCTRL, (1<<1));
518}
519
520static int
521am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev)
522{
523	struct am335x_prcm_softc *sc = am335x_prcm_sc;
524
525	if (sc == NULL)
526		return ENXIO;
527
528	/* set MODULENAME to ENABLE */
529	prcm_write_4(CM_PER_CPGMAC0_CLKCTRL, 2);
530
531	/* wait for IDLEST to become Func(0) */
532	while(prcm_read_4(CM_PER_CPGMAC0_CLKCTRL) & (3<<16));
533
534	/*set CLKTRCTRL to SW_WKUP(2) */
535	prcm_write_4(CM_PER_CPSW_CLKSTCTRL, 2);
536
537	/* wait for 125 MHz OCP clock to become active */
538	while((prcm_read_4(CM_PER_CPSW_CLKSTCTRL) & (1<<4)) == 0);
539	return(0);
540}
541
542static int
543am335x_clk_musb0_activate(struct ti_clock_dev *clkdev)
544{
545	struct am335x_prcm_softc *sc = am335x_prcm_sc;
546
547	if (sc == NULL)
548		return ENXIO;
549
550	/* set ST_DPLL_CLKDCOLDO(9) to CLK_GATED(1) */
551	/* set DPLL_CLKDCOLDO_GATE_CTRL(8) to CLK_ENABLE(1)*/
552        prcm_write_4(CM_WKUP_CM_CLKDCOLDO_DPLL_PER, 0x300);
553
554	/*set MODULEMODE to ENABLE(2) */
555	prcm_write_4(CM_PER_USB0_CLKCTRL, 2);
556
557	/* wait for MODULEMODE to become ENABLE(2) */
558	while ((prcm_read_4(CM_PER_USB0_CLKCTRL) & 0x3) != 2)
559		DELAY(10);
560
561	/* wait for IDLEST to become Func(0) */
562	while(prcm_read_4(CM_PER_USB0_CLKCTRL) & (3<<16))
563		DELAY(10);
564
565	return(0);
566}
567
568
569