am335x_prcm.c revision 323470
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: stable/11/sys/arm/ti/am335x/am335x_prcm.c 323470 2017-09-11 22:33:29Z ian $"); 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 134struct am335x_prcm_softc { 135 struct resource * res[2]; 136 bus_space_tag_t bst; 137 bus_space_handle_t bsh; 138}; 139 140static struct resource_spec am335x_prcm_spec[] = { 141 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 142 { -1, 0 } 143}; 144 145static struct am335x_prcm_softc *am335x_prcm_sc = NULL; 146 147static int am335x_clk_noop_activate(struct ti_clock_dev *clkdev); 148static int am335x_clk_generic_activate(struct ti_clock_dev *clkdev); 149static int am335x_clk_gpio_activate(struct ti_clock_dev *clkdev); 150static int am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev); 151static int am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev); 152static int am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc); 153static int am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc); 154static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 155static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 156static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 157static int am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 158static int am335x_clk_set_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int freq); 159static void am335x_prcm_reset(void); 160static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev); 161static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev); 162static int am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev); 163static 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 205struct 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 326struct 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 338static 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 405void am335x_prcm_setup_dmtimer(int); 406 407static int 408am335x_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 422static int 423am335x_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 455static 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 461static driver_t am335x_prcm_driver = { 462 "am335x_prcm", 463 am335x_prcm_methods, 464 sizeof(struct am335x_prcm_softc), 465}; 466 467static devclass_t am335x_prcm_devclass; 468 469EARLY_DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver, 470 am335x_prcm_devclass, 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_EARLY); 471MODULE_VERSION(am335x_prcm, 1); 472MODULE_DEPEND(am335x_prcm, ti_scm, 1, 1, 1); 473 474static struct am335x_clk_details* 475am335x_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 487static int 488am335x_clk_noop_activate(struct ti_clock_dev *clkdev) 489{ 490 491 return (0); 492} 493 494static int 495am335x_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 516static int 517am335x_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 540static int 541am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev) 542{ 543 544 return(0); 545} 546 547static int 548am335x_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 569static int 570am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc) 571{ 572 573 return (0); 574} 575 576static int 577am335x_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 612static int 613am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq) 614{ 615 *freq = 96000000; 616 return (0); 617} 618 619static int 620am335x_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 656static int 657am335x_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 673static int 674am335x_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 690static int 691am335x_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 736static void 737am335x_prcm_reset(void) 738{ 739 prcm_write_4(PRM_RSTCTRL, (1<<1)); 740} 741 742static int 743am335x_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 764static int 765am335x_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 790static int 791am335x_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 817static int 818am335x_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} 857