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