am335x_prcm.c revision 297395
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 297395 2016-03-29 19:11:04Z loos $"); 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#define CM_PER 0 56#define CM_PER_L4LS_CLKSTCTRL (CM_PER + 0x000) 57#define CM_PER_L3S_CLKSTCTRL (CM_PER + 0x004) 58#define CM_PER_L3_CLKSTCTRL (CM_PER + 0x00C) 59#define CM_PER_CPGMAC0_CLKCTRL (CM_PER + 0x014) 60#define CM_PER_LCDC_CLKCTRL (CM_PER + 0x018) 61#define CM_PER_USB0_CLKCTRL (CM_PER + 0x01C) 62#define CM_PER_TPTC0_CLKCTRL (CM_PER + 0x024) 63#define CM_PER_UART5_CLKCTRL (CM_PER + 0x038) 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_SPI0_CLKCTRL (CM_PER + 0x04C) 68#define CM_PER_SPI1_CLKCTRL (CM_PER + 0x050) 69#define CM_PER_UART1_CLKCTRL (CM_PER + 0x06C) 70#define CM_PER_UART2_CLKCTRL (CM_PER + 0x070) 71#define CM_PER_UART3_CLKCTRL (CM_PER + 0x074) 72#define CM_PER_UART4_CLKCTRL (CM_PER + 0x078) 73#define CM_PER_TIMER7_CLKCTRL (CM_PER + 0x07C) 74#define CM_PER_TIMER2_CLKCTRL (CM_PER + 0x080) 75#define CM_PER_TIMER3_CLKCTRL (CM_PER + 0x084) 76#define CM_PER_TIMER4_CLKCTRL (CM_PER + 0x088) 77#define CM_PER_GPIO1_CLKCTRL (CM_PER + 0x0AC) 78#define CM_PER_GPIO2_CLKCTRL (CM_PER + 0x0B0) 79#define CM_PER_GPIO3_CLKCTRL (CM_PER + 0x0B4) 80#define CM_PER_TPCC_CLKCTRL (CM_PER + 0x0BC) 81#define CM_PER_EPWMSS1_CLKCTRL (CM_PER + 0x0CC) 82#define CM_PER_EPWMSS0_CLKCTRL (CM_PER + 0x0D4) 83#define CM_PER_EPWMSS2_CLKCTRL (CM_PER + 0x0D8) 84#define CM_PER_L3_INSTR_CLKCTRL (CM_PER + 0x0DC) 85#define CM_PER_L3_CLKCTRL (CM_PER + 0x0E0) 86#define CM_PER_PRUSS_CLKCTRL (CM_PER + 0x0E8) 87#define CM_PER_TIMER5_CLKCTRL (CM_PER + 0x0EC) 88#define CM_PER_TIMER6_CLKCTRL (CM_PER + 0x0F0) 89#define CM_PER_MMC1_CLKCTRL (CM_PER + 0x0F4) 90#define CM_PER_MMC2_CLKCTRL (CM_PER + 0x0F8) 91#define CM_PER_TPTC1_CLKCTRL (CM_PER + 0x0FC) 92#define CM_PER_TPTC2_CLKCTRL (CM_PER + 0x100) 93#define CM_PER_SPINLOCK0_CLKCTRL (CM_PER + 0x10C) 94#define CM_PER_MAILBOX0_CLKCTRL (CM_PER + 0x110) 95#define CM_PER_OCPWP_L3_CLKSTCTRL (CM_PER + 0x12C) 96#define CM_PER_OCPWP_CLKCTRL (CM_PER + 0x130) 97#define CM_PER_CPSW_CLKSTCTRL (CM_PER + 0x144) 98#define CM_PER_PRUSS_CLKSTCTRL (CM_PER + 0x140) 99 100#define CM_WKUP 0x400 101#define CM_WKUP_CLKSTCTRL (CM_WKUP + 0x000) 102#define CM_WKUP_CONTROL_CLKCTRL (CM_WKUP + 0x004) 103#define CM_WKUP_GPIO0_CLKCTRL (CM_WKUP + 0x008) 104#define CM_WKUP_CM_L3_AON_CLKSTCTRL (CM_WKUP + 0x01C) 105#define CM_WKUP_CM_CLKSEL_DPLL_MPU (CM_WKUP + 0x02C) 106#define CM_WKUP_CM_IDLEST_DPLL_DISP (CM_WKUP + 0x048) 107#define CM_WKUP_CM_CLKSEL_DPLL_DISP (CM_WKUP + 0x054) 108#define CM_WKUP_CM_CLKDCOLDO_DPLL_PER (CM_WKUP + 0x07C) 109#define CM_WKUP_CM_CLKMODE_DPLL_DISP (CM_WKUP + 0x098) 110#define CM_WKUP_I2C0_CLKCTRL (CM_WKUP + 0x0B8) 111#define CM_WKUP_ADC_TSC_CLKCTRL (CM_WKUP + 0x0BC) 112 113#define CM_DPLL 0x500 114#define CLKSEL_TIMER7_CLK (CM_DPLL + 0x004) 115#define CLKSEL_TIMER2_CLK (CM_DPLL + 0x008) 116#define CLKSEL_TIMER3_CLK (CM_DPLL + 0x00C) 117#define CLKSEL_TIMER4_CLK (CM_DPLL + 0x010) 118#define CLKSEL_TIMER5_CLK (CM_DPLL + 0x018) 119#define CLKSEL_TIMER6_CLK (CM_DPLL + 0x01C) 120#define CLKSEL_PRUSS_OCP_CLK (CM_DPLL + 0x030) 121 122#define CM_RTC 0x800 123#define CM_RTC_RTC_CLKCTRL (CM_RTC + 0x000) 124#define CM_RTC_CLKSTCTRL (CM_RTC + 0x004) 125 126#define PRM_PER 0xC00 127#define PRM_PER_RSTCTRL (PRM_PER + 0x00) 128 129#define PRM_DEVICE_OFFSET 0xF00 130#define PRM_RSTCTRL (PRM_DEVICE_OFFSET + 0x00) 131 132struct am335x_prcm_softc { 133 struct resource * res[2]; 134 bus_space_tag_t bst; 135 bus_space_handle_t bsh; 136}; 137 138static struct resource_spec am335x_prcm_spec[] = { 139 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 140 { -1, 0 } 141}; 142 143static struct am335x_prcm_softc *am335x_prcm_sc = NULL; 144 145static int am335x_clk_noop_activate(struct ti_clock_dev *clkdev); 146static int am335x_clk_generic_activate(struct ti_clock_dev *clkdev); 147static int am335x_clk_gpio_activate(struct ti_clock_dev *clkdev); 148static int am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev); 149static int am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev); 150static int am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc); 151static int am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc); 152static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 153static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 154static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 155static int am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 156static int am335x_clk_set_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int freq); 157static void am335x_prcm_reset(void); 158static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev); 159static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev); 160static int am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev); 161static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev); 162 163#define AM335X_NOOP_CLOCK_DEV(i) \ 164 { .id = (i), \ 165 .clk_activate = am335x_clk_noop_activate, \ 166 .clk_deactivate = am335x_clk_noop_deactivate, \ 167 .clk_set_source = am335x_clk_noop_set_source, \ 168 .clk_accessible = NULL, \ 169 .clk_get_source_freq = NULL, \ 170 .clk_set_source_freq = NULL \ 171 } 172 173#define AM335X_GENERIC_CLOCK_DEV(i) \ 174 { .id = (i), \ 175 .clk_activate = am335x_clk_generic_activate, \ 176 .clk_deactivate = am335x_clk_generic_deactivate, \ 177 .clk_set_source = am335x_clk_generic_set_source, \ 178 .clk_accessible = NULL, \ 179 .clk_get_source_freq = NULL, \ 180 .clk_set_source_freq = NULL \ 181 } 182 183#define AM335X_GPIO_CLOCK_DEV(i) \ 184 { .id = (i), \ 185 .clk_activate = am335x_clk_gpio_activate, \ 186 .clk_deactivate = am335x_clk_generic_deactivate, \ 187 .clk_set_source = am335x_clk_generic_set_source, \ 188 .clk_accessible = NULL, \ 189 .clk_get_source_freq = NULL, \ 190 .clk_set_source_freq = NULL \ 191 } 192 193#define AM335X_MMCHS_CLOCK_DEV(i) \ 194 { .id = (i), \ 195 .clk_activate = am335x_clk_generic_activate, \ 196 .clk_deactivate = am335x_clk_generic_deactivate, \ 197 .clk_set_source = am335x_clk_generic_set_source, \ 198 .clk_accessible = NULL, \ 199 .clk_get_source_freq = am335x_clk_hsmmc_get_source_freq, \ 200 .clk_set_source_freq = NULL \ 201 } 202 203struct ti_clock_dev ti_am335x_clk_devmap[] = { 204 /* System clocks */ 205 { .id = SYS_CLK, 206 .clk_activate = NULL, 207 .clk_deactivate = NULL, 208 .clk_set_source = NULL, 209 .clk_accessible = NULL, 210 .clk_get_source_freq = am335x_clk_get_sysclk_freq, 211 .clk_set_source_freq = NULL, 212 }, 213 /* MPU (ARM) core clocks */ 214 { .id = MPU_CLK, 215 .clk_activate = NULL, 216 .clk_deactivate = NULL, 217 .clk_set_source = NULL, 218 .clk_accessible = NULL, 219 .clk_get_source_freq = am335x_clk_get_arm_fclk_freq, 220 .clk_set_source_freq = NULL, 221 }, 222 /* CPSW Ethernet Switch core clocks */ 223 { .id = CPSW_CLK, 224 .clk_activate = am335x_clk_cpsw_activate, 225 .clk_deactivate = NULL, 226 .clk_set_source = NULL, 227 .clk_accessible = NULL, 228 .clk_get_source_freq = NULL, 229 .clk_set_source_freq = NULL, 230 }, 231 232 /* Mentor USB HS controller core clocks */ 233 { .id = MUSB0_CLK, 234 .clk_activate = am335x_clk_musb0_activate, 235 .clk_deactivate = NULL, 236 .clk_set_source = NULL, 237 .clk_accessible = NULL, 238 .clk_get_source_freq = NULL, 239 .clk_set_source_freq = NULL, 240 }, 241 242 /* LCD controller clocks */ 243 { .id = LCDC_CLK, 244 .clk_activate = am335x_clk_lcdc_activate, 245 .clk_deactivate = NULL, 246 .clk_set_source = NULL, 247 .clk_accessible = NULL, 248 .clk_get_source_freq = am335x_clk_get_arm_disp_freq, 249 .clk_set_source_freq = am335x_clk_set_arm_disp_freq, 250 }, 251 252 /* UART */ 253 AM335X_NOOP_CLOCK_DEV(UART1_CLK), 254 AM335X_GENERIC_CLOCK_DEV(UART2_CLK), 255 AM335X_GENERIC_CLOCK_DEV(UART3_CLK), 256 AM335X_GENERIC_CLOCK_DEV(UART4_CLK), 257 AM335X_GENERIC_CLOCK_DEV(UART5_CLK), 258 AM335X_GENERIC_CLOCK_DEV(UART6_CLK), 259 260 /* DMTimer */ 261 AM335X_GENERIC_CLOCK_DEV(TIMER2_CLK), 262 AM335X_GENERIC_CLOCK_DEV(TIMER3_CLK), 263 AM335X_GENERIC_CLOCK_DEV(TIMER4_CLK), 264 AM335X_GENERIC_CLOCK_DEV(TIMER5_CLK), 265 AM335X_GENERIC_CLOCK_DEV(TIMER6_CLK), 266 AM335X_GENERIC_CLOCK_DEV(TIMER7_CLK), 267 268 /* GPIO, we use hwmods as reference, not units in spec */ 269 AM335X_GPIO_CLOCK_DEV(GPIO1_CLK), 270 AM335X_GPIO_CLOCK_DEV(GPIO2_CLK), 271 AM335X_GPIO_CLOCK_DEV(GPIO3_CLK), 272 AM335X_GPIO_CLOCK_DEV(GPIO4_CLK), 273 274 /* I2C we use hwmods as reference, not units in spec */ 275 AM335X_GENERIC_CLOCK_DEV(I2C1_CLK), 276 AM335X_GENERIC_CLOCK_DEV(I2C2_CLK), 277 AM335X_GENERIC_CLOCK_DEV(I2C3_CLK), 278 279 /* McSPI we use hwmods as reference, not units in spec */ 280 AM335X_GENERIC_CLOCK_DEV(SPI0_CLK), 281 AM335X_GENERIC_CLOCK_DEV(SPI1_CLK), 282 283 /* TSC_ADC */ 284 AM335X_GENERIC_CLOCK_DEV(TSC_ADC_CLK), 285 286 /* EDMA */ 287 AM335X_GENERIC_CLOCK_DEV(EDMA_TPCC_CLK), 288 AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC0_CLK), 289 AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC1_CLK), 290 AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK), 291 292 /* MMCHS */ 293 AM335X_MMCHS_CLOCK_DEV(MMC1_CLK), 294 AM335X_MMCHS_CLOCK_DEV(MMC2_CLK), 295 AM335X_MMCHS_CLOCK_DEV(MMC3_CLK), 296 297 /* PWMSS */ 298 AM335X_GENERIC_CLOCK_DEV(PWMSS0_CLK), 299 AM335X_GENERIC_CLOCK_DEV(PWMSS1_CLK), 300 AM335X_GENERIC_CLOCK_DEV(PWMSS2_CLK), 301 302 /* System Mailbox clock */ 303 AM335X_GENERIC_CLOCK_DEV(MAILBOX0_CLK), 304 305 /* SPINLOCK */ 306 AM335X_GENERIC_CLOCK_DEV(SPINLOCK0_CLK), 307 308 /* PRU-ICSS */ 309 { .id = PRUSS_CLK, 310 .clk_activate = am335x_clk_pruss_activate, 311 .clk_deactivate = NULL, 312 .clk_set_source = NULL, 313 .clk_accessible = NULL, 314 .clk_get_source_freq = NULL, 315 .clk_set_source_freq = NULL, 316 }, 317 318 /* RTC */ 319 AM335X_GENERIC_CLOCK_DEV(RTC_CLK), 320 321 { INVALID_CLK_IDENT, NULL, NULL, NULL, NULL } 322}; 323 324struct am335x_clk_details { 325 clk_ident_t id; 326 uint32_t clkctrl_reg; 327 uint32_t clksel_reg; 328}; 329 330#define _CLK_DETAIL(i, c, s) \ 331 { .id = (i), \ 332 .clkctrl_reg = (c), \ 333 .clksel_reg = (s), \ 334 } 335 336static struct am335x_clk_details g_am335x_clk_details[] = { 337 338 /* UART. UART0 clock not controllable. */ 339 _CLK_DETAIL(UART1_CLK, 0, 0), 340 _CLK_DETAIL(UART2_CLK, CM_PER_UART1_CLKCTRL, 0), 341 _CLK_DETAIL(UART3_CLK, CM_PER_UART2_CLKCTRL, 0), 342 _CLK_DETAIL(UART4_CLK, CM_PER_UART3_CLKCTRL, 0), 343 _CLK_DETAIL(UART5_CLK, CM_PER_UART4_CLKCTRL, 0), 344 _CLK_DETAIL(UART6_CLK, CM_PER_UART5_CLKCTRL, 0), 345 346 /* DMTimer modules */ 347 _CLK_DETAIL(TIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK), 348 _CLK_DETAIL(TIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK), 349 _CLK_DETAIL(TIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK), 350 _CLK_DETAIL(TIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK), 351 _CLK_DETAIL(TIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK), 352 _CLK_DETAIL(TIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK), 353 354 /* GPIO modules, hwmods start with gpio1 */ 355 _CLK_DETAIL(GPIO1_CLK, CM_WKUP_GPIO0_CLKCTRL, 0), 356 _CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO1_CLKCTRL, 0), 357 _CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO2_CLKCTRL, 0), 358 _CLK_DETAIL(GPIO4_CLK, CM_PER_GPIO3_CLKCTRL, 0), 359 360 /* I2C modules, hwmods start with i2c1 */ 361 _CLK_DETAIL(I2C1_CLK, CM_WKUP_I2C0_CLKCTRL, 0), 362 _CLK_DETAIL(I2C2_CLK, CM_PER_I2C1_CLKCTRL, 0), 363 _CLK_DETAIL(I2C3_CLK, CM_PER_I2C2_CLKCTRL, 0), 364 365 /* McSPI modules, hwmods start with spi0 */ 366 _CLK_DETAIL(SPI0_CLK, CM_PER_SPI0_CLKCTRL, 0), 367 _CLK_DETAIL(SPI1_CLK, CM_PER_SPI1_CLKCTRL, 0), 368 369 /* TSC_ADC module */ 370 _CLK_DETAIL(TSC_ADC_CLK, CM_WKUP_ADC_TSC_CLKCTRL, 0), 371 372 /* EDMA modules */ 373 _CLK_DETAIL(EDMA_TPCC_CLK, CM_PER_TPCC_CLKCTRL, 0), 374 _CLK_DETAIL(EDMA_TPTC0_CLK, CM_PER_TPTC0_CLKCTRL, 0), 375 _CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0), 376 _CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0), 377 378 /* MMCHS modules, hwmods start with mmc1*/ 379 _CLK_DETAIL(MMC1_CLK, CM_PER_MMC0_CLKCTRL, 0), 380 _CLK_DETAIL(MMC2_CLK, CM_PER_MMC1_CLKCTRL, 0), 381 _CLK_DETAIL(MMC3_CLK, CM_PER_MMC1_CLKCTRL, 0), 382 383 /* PWMSS modules */ 384 _CLK_DETAIL(PWMSS0_CLK, CM_PER_EPWMSS0_CLKCTRL, 0), 385 _CLK_DETAIL(PWMSS1_CLK, CM_PER_EPWMSS1_CLKCTRL, 0), 386 _CLK_DETAIL(PWMSS2_CLK, CM_PER_EPWMSS2_CLKCTRL, 0), 387 388 _CLK_DETAIL(MAILBOX0_CLK, CM_PER_MAILBOX0_CLKCTRL, 0), 389 _CLK_DETAIL(SPINLOCK0_CLK, CM_PER_SPINLOCK0_CLKCTRL, 0), 390 391 /* RTC module */ 392 _CLK_DETAIL(RTC_CLK, CM_RTC_RTC_CLKCTRL, 0), 393 394 { INVALID_CLK_IDENT, 0}, 395}; 396 397/* Read/Write macros */ 398#define prcm_read_4(reg) \ 399 bus_space_read_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg) 400#define prcm_write_4(reg, val) \ 401 bus_space_write_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg, val) 402 403void am335x_prcm_setup_dmtimer(int); 404 405static int 406am335x_prcm_probe(device_t dev) 407{ 408 409 if (!ofw_bus_status_okay(dev)) 410 return (ENXIO); 411 412 if (ofw_bus_is_compatible(dev, "ti,am3-prcm")) { 413 device_set_desc(dev, "AM335x Power and Clock Management"); 414 return(BUS_PROBE_DEFAULT); 415 } 416 417 return (ENXIO); 418} 419 420static int 421am335x_prcm_attach(device_t dev) 422{ 423 struct am335x_prcm_softc *sc = device_get_softc(dev); 424 unsigned int sysclk, fclk; 425 426 if (am335x_prcm_sc) 427 return (ENXIO); 428 429 if (bus_alloc_resources(dev, am335x_prcm_spec, sc->res)) { 430 device_printf(dev, "could not allocate resources\n"); 431 return (ENXIO); 432 } 433 434 sc->bst = rman_get_bustag(sc->res[0]); 435 sc->bsh = rman_get_bushandle(sc->res[0]); 436 437 am335x_prcm_sc = sc; 438 ti_cpu_reset = am335x_prcm_reset; 439 440 if (am335x_clk_get_sysclk_freq(NULL, &sysclk) != 0) 441 sysclk = 0; 442 if (am335x_clk_get_arm_fclk_freq(NULL, &fclk) != 0) 443 fclk = 0; 444 if (sysclk && fclk) 445 device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n", 446 sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000); 447 else 448 device_printf(dev, "can't read frequencies yet (SCM device not ready?)\n"); 449 450 return (0); 451} 452 453static device_method_t am335x_prcm_methods[] = { 454 DEVMETHOD(device_probe, am335x_prcm_probe), 455 DEVMETHOD(device_attach, am335x_prcm_attach), 456 { 0, 0 } 457}; 458 459static driver_t am335x_prcm_driver = { 460 "am335x_prcm", 461 am335x_prcm_methods, 462 sizeof(struct am335x_prcm_softc), 463}; 464 465static devclass_t am335x_prcm_devclass; 466 467DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver, 468 am335x_prcm_devclass, 0, 0); 469MODULE_VERSION(am335x_prcm, 1); 470MODULE_DEPEND(am335x_prcm, ti_scm, 1, 1, 1); 471 472static struct am335x_clk_details* 473am335x_clk_details(clk_ident_t id) 474{ 475 struct am335x_clk_details *walker; 476 477 for (walker = g_am335x_clk_details; walker->id != INVALID_CLK_IDENT; walker++) { 478 if (id == walker->id) 479 return (walker); 480 } 481 482 return NULL; 483} 484 485static int 486am335x_clk_noop_activate(struct ti_clock_dev *clkdev) 487{ 488 489 return (0); 490} 491 492static int 493am335x_clk_generic_activate(struct ti_clock_dev *clkdev) 494{ 495 struct am335x_prcm_softc *sc = am335x_prcm_sc; 496 struct am335x_clk_details* clk_details; 497 498 if (sc == NULL) 499 return ENXIO; 500 501 clk_details = am335x_clk_details(clkdev->id); 502 503 if (clk_details == NULL) 504 return (ENXIO); 505 506 /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */ 507 prcm_write_4(clk_details->clkctrl_reg, 2); 508 while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 2) 509 DELAY(10); 510 511 return (0); 512} 513 514static int 515am335x_clk_gpio_activate(struct ti_clock_dev *clkdev) 516{ 517 struct am335x_prcm_softc *sc = am335x_prcm_sc; 518 struct am335x_clk_details* clk_details; 519 520 if (sc == NULL) 521 return ENXIO; 522 523 clk_details = am335x_clk_details(clkdev->id); 524 525 if (clk_details == NULL) 526 return (ENXIO); 527 528 /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */ 529 /* set *_CLKCTRL register OPTFCLKEN_GPIO_1_G DBCLK[18] to FCLK_EN(1) */ 530 prcm_write_4(clk_details->clkctrl_reg, 2 | (1 << 18)); 531 while ((prcm_read_4(clk_details->clkctrl_reg) & 532 (3 | (1 << 18) )) != (2 | (1 << 18))) 533 DELAY(10); 534 535 return (0); 536} 537 538static int 539am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev) 540{ 541 542 return(0); 543} 544 545static int 546am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev) 547{ 548 struct am335x_prcm_softc *sc = am335x_prcm_sc; 549 struct am335x_clk_details* clk_details; 550 551 if (sc == NULL) 552 return ENXIO; 553 554 clk_details = am335x_clk_details(clkdev->id); 555 556 if (clk_details == NULL) 557 return (ENXIO); 558 559 /* set *_CLKCTRL register MODULEMODE[1:0] to disable(0) */ 560 prcm_write_4(clk_details->clkctrl_reg, 0); 561 while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 0) 562 DELAY(10); 563 564 return (0); 565} 566 567static int 568am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc) 569{ 570 571 return (0); 572} 573 574static int 575am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc) 576{ 577 struct am335x_prcm_softc *sc = am335x_prcm_sc; 578 struct am335x_clk_details* clk_details; 579 uint32_t reg; 580 581 if (sc == NULL) 582 return ENXIO; 583 584 clk_details = am335x_clk_details(clkdev->id); 585 586 if (clk_details == NULL) 587 return (ENXIO); 588 589 switch (clksrc) { 590 case EXT_CLK: 591 reg = 0; /* SEL2: TCLKIN clock */ 592 break; 593 case SYSCLK_CLK: 594 reg = 1; /* SEL1: CLK_M_OSC clock */ 595 break; 596 case F32KHZ_CLK: 597 reg = 2; /* SEL3: CLK_32KHZ clock */ 598 break; 599 default: 600 return (ENXIO); 601 } 602 603 prcm_write_4(clk_details->clksel_reg, reg); 604 while ((prcm_read_4(clk_details->clksel_reg) & 0x3) != reg) 605 DELAY(10); 606 607 return (0); 608} 609 610static int 611am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq) 612{ 613 *freq = 96000000; 614 return (0); 615} 616 617static int 618am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq) 619{ 620 uint32_t ctrl_status; 621 622 /* Read the input clock freq from the control module */ 623 /* control_status reg (0x40) */ 624 if (ti_scm_reg_read_4(0x40, &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 655static int 656am335x_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 672static int 673am335x_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 689static int 690am335x_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 735static void 736am335x_prcm_reset(void) 737{ 738 prcm_write_4(PRM_RSTCTRL, (1<<1)); 739} 740 741static int 742am335x_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 763static int 764am335x_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 789static int 790am335x_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 816static int 817am335x_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} 856