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