am335x_prcm.c revision 257200
1171219Speter/*- 2171219Speter * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> 3171219Speter * All rights reserved. 4171219Speter * 5171219Speter * Redistribution and use in source and binary forms, with or without 6171219Speter * modification, are permitted provided that the following conditions 7171219Speter * are met: 8171219Speter * 1. Redistributions of source code must retain the above copyright 9171219Speter * notice, this list of conditions and the following disclaimer. 10171219Speter * 2. Redistributions in binary form must reproduce the above copyright 11171219Speter * notice, this list of conditions and the following disclaimer in the 12171219Speter * documentation and/or other materials provided with the distribution. 13171219Speter * 14171219Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15171219Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16171219Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17171219Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18171219Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19171219Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20171219Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21171219Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22171219Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23171219Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24171219Speter * SUCH DAMAGE. 25171219Speter */ 26171219Speter 27171219Speter#include <sys/cdefs.h> 28171219Speter__FBSDID("$FreeBSD: head/sys/arm/ti/am335x/am335x_prcm.c 257200 2013-10-27 01:34:10Z ian $"); 29171219Speter 30171219Speter#include <sys/param.h> 31171219Speter#include <sys/systm.h> 32211416Skib#include <sys/bus.h> 33211416Skib#include <sys/kernel.h> 34211416Skib#include <sys/module.h> 35171219Speter#include <sys/malloc.h> 36205997Sdelphij#include <sys/rman.h> 37205997Sdelphij#include <sys/timeet.h> 38171219Speter#include <sys/timetc.h> 39171219Speter#include <sys/watchdog.h> 40171219Speter#include <machine/bus.h> 41171219Speter#include <machine/cpu.h> 42171219Speter#include <machine/intr.h> 43171219Speter 44171219Speter#include <arm/ti/tivar.h> 45171219Speter#include <arm/ti/ti_scm.h> 46171219Speter#include <arm/ti/ti_prcm.h> 47171219Speter 48171219Speter#include <dev/fdt/fdt_common.h> 49171219Speter#include <dev/ofw/openfirm.h> 50171219Speter#include <dev/ofw/ofw_bus.h> 51171219Speter#include <dev/ofw/ofw_bus_subr.h> 52171219Speter 53171219Speter#include <machine/bus.h> 54171219Speter#include <machine/fdt.h> 55171219Speter 56171219Speter#define CM_PER 0 57211416Skib#define CM_PER_L4LS_CLKSTCTRL (CM_PER + 0x000) 58211416Skib#define CM_PER_L3S_CLKSTCTRL (CM_PER + 0x004) 59211416Skib#define CM_PER_L3_CLKSTCTRL (CM_PER + 0x00C) 60211416Skib#define CM_PER_CPGMAC0_CLKCTRL (CM_PER + 0x014) 61211416Skib#define CM_PER_LCDC_CLKCTRL (CM_PER + 0x018) 62171219Speter#define CM_PER_USB0_CLKCTRL (CM_PER + 0x01C) 63171219Speter#define CM_PER_TPTC0_CLKCTRL (CM_PER + 0x024) 64171219Speter#define CM_PER_UART5_CLKCTRL (CM_PER + 0x038) 65171219Speter#define CM_PER_MMC0_CLKCTRL (CM_PER + 0x03C) 66171219Speter#define CM_PER_I2C2_CLKCTRL (CM_PER + 0x044) 67171219Speter#define CM_PER_I2C1_CLKCTRL (CM_PER + 0x048) 68171219Speter#define CM_PER_UART1_CLKCTRL (CM_PER + 0x06C) 69171219Speter#define CM_PER_UART2_CLKCTRL (CM_PER + 0x070) 70171219Speter#define CM_PER_UART3_CLKCTRL (CM_PER + 0x074) 71#define CM_PER_UART4_CLKCTRL (CM_PER + 0x078) 72#define CM_PER_TIMER7_CLKCTRL (CM_PER + 0x07C) 73#define CM_PER_TIMER2_CLKCTRL (CM_PER + 0x080) 74#define CM_PER_TIMER3_CLKCTRL (CM_PER + 0x084) 75#define CM_PER_TIMER4_CLKCTRL (CM_PER + 0x088) 76#define CM_PER_GPIO1_CLKCTRL (CM_PER + 0x0AC) 77#define CM_PER_GPIO2_CLKCTRL (CM_PER + 0x0B0) 78#define CM_PER_GPIO3_CLKCTRL (CM_PER + 0x0B4) 79#define CM_PER_TPCC_CLKCTRL (CM_PER + 0x0BC) 80#define CM_PER_EPWMSS1_CLKCTRL (CM_PER + 0x0CC) 81#define CM_PER_EPWMSS0_CLKCTRL (CM_PER + 0x0D4) 82#define CM_PER_EPWMSS2_CLKCTRL (CM_PER + 0x0D8) 83#define CM_PER_L3_INSTR_CLKCTRL (CM_PER + 0x0DC) 84#define CM_PER_L3_CLKCTRL (CM_PER + 0x0E0) 85#define CM_PER_PRUSS_CLKCTRL (CM_PER + 0x0E8) 86#define CM_PER_TIMER5_CLKCTRL (CM_PER + 0x0EC) 87#define CM_PER_TIMER6_CLKCTRL (CM_PER + 0x0F0) 88#define CM_PER_MMC1_CLKCTRL (CM_PER + 0x0F4) 89#define CM_PER_MMC2_CLKCTRL (CM_PER + 0x0F8) 90#define CM_PER_TPTC1_CLKCTRL (CM_PER + 0x0FC) 91#define CM_PER_TPTC2_CLKCTRL (CM_PER + 0x100) 92#define CM_PER_SPINLOCK0_CLKCTRL (CM_PER + 0x10C) 93#define CM_PER_MAILBOX0_CLKCTRL (CM_PER + 0x110) 94#define CM_PER_OCPWP_L3_CLKSTCTRL (CM_PER + 0x12C) 95#define CM_PER_OCPWP_CLKCTRL (CM_PER + 0x130) 96#define CM_PER_CPSW_CLKSTCTRL (CM_PER + 0x144) 97#define CM_PER_PRUSS_CLKSTCTRL (CM_PER + 0x140) 98 99#define CM_WKUP 0x400 100#define CM_WKUP_CLKSTCTRL (CM_WKUP + 0x000) 101#define CM_WKUP_CONTROL_CLKCTRL (CM_WKUP + 0x004) 102#define CM_WKUP_GPIO0_CLKCTRL (CM_WKUP + 0x008) 103#define CM_WKUP_CM_L3_AON_CLKSTCTRL (CM_WKUP + 0x01C) 104#define CM_WKUP_CM_CLKSEL_DPLL_MPU (CM_WKUP + 0x02C) 105#define CM_WKUP_CM_IDLEST_DPLL_DISP (CM_WKUP + 0x048) 106#define CM_WKUP_CM_CLKSEL_DPLL_DISP (CM_WKUP + 0x054) 107#define CM_WKUP_CM_CLKDCOLDO_DPLL_PER (CM_WKUP + 0x07C) 108#define CM_WKUP_CM_CLKMODE_DPLL_DISP (CM_WKUP + 0x098) 109#define CM_WKUP_I2C0_CLKCTRL (CM_WKUP + 0x0B8) 110 111#define CM_DPLL 0x500 112#define CLKSEL_TIMER7_CLK (CM_DPLL + 0x004) 113#define CLKSEL_TIMER2_CLK (CM_DPLL + 0x008) 114#define CLKSEL_TIMER3_CLK (CM_DPLL + 0x00C) 115#define CLKSEL_TIMER4_CLK (CM_DPLL + 0x010) 116#define CLKSEL_TIMER5_CLK (CM_DPLL + 0x018) 117#define CLKSEL_TIMER6_CLK (CM_DPLL + 0x01C) 118#define CLKSEL_PRUSS_OCP_CLK (CM_DPLL + 0x030) 119 120#define PRM_PER 0xC00 121#define PRM_PER_RSTCTRL (PRM_PER + 0x00) 122 123#define PRM_DEVICE_OFFSET 0xF00 124#define PRM_RSTCTRL (PRM_DEVICE_OFFSET + 0x00) 125 126struct am335x_prcm_softc { 127 struct resource * res[2]; 128 bus_space_tag_t bst; 129 bus_space_handle_t bsh; 130}; 131 132static struct resource_spec am335x_prcm_spec[] = { 133 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 134 { -1, 0 } 135}; 136 137static struct am335x_prcm_softc *am335x_prcm_sc = NULL; 138 139static int am335x_clk_noop_activate(struct ti_clock_dev *clkdev); 140static int am335x_clk_generic_activate(struct ti_clock_dev *clkdev); 141static int am335x_clk_gpio_activate(struct ti_clock_dev *clkdev); 142static int am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev); 143static int am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev); 144static int am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc); 145static int am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc); 146static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 147static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 148static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 149static int am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq); 150static void am335x_prcm_reset(void); 151static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev); 152static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev); 153static int am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev); 154static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev); 155 156#define AM335X_NOOP_CLOCK_DEV(i) \ 157 { .id = (i), \ 158 .clk_activate = am335x_clk_noop_activate, \ 159 .clk_deactivate = am335x_clk_noop_deactivate, \ 160 .clk_set_source = am335x_clk_noop_set_source, \ 161 .clk_accessible = NULL, \ 162 .clk_get_source_freq = NULL \ 163 } 164 165#define AM335X_GENERIC_CLOCK_DEV(i) \ 166 { .id = (i), \ 167 .clk_activate = am335x_clk_generic_activate, \ 168 .clk_deactivate = am335x_clk_generic_deactivate, \ 169 .clk_set_source = am335x_clk_generic_set_source, \ 170 .clk_accessible = NULL, \ 171 .clk_get_source_freq = NULL \ 172 } 173 174#define AM335X_GPIO_CLOCK_DEV(i) \ 175 { .id = (i), \ 176 .clk_activate = am335x_clk_gpio_activate, \ 177 .clk_deactivate = am335x_clk_generic_deactivate, \ 178 .clk_set_source = am335x_clk_generic_set_source, \ 179 .clk_accessible = NULL, \ 180 .clk_get_source_freq = NULL \ 181 } 182 183#define AM335X_MMCHS_CLOCK_DEV(i) \ 184 { .id = (i), \ 185 .clk_activate = am335x_clk_generic_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 = am335x_clk_hsmmc_get_source_freq \ 190 } 191 192struct ti_clock_dev ti_clk_devmap[] = { 193 /* System clocks */ 194 { .id = SYS_CLK, 195 .clk_activate = NULL, 196 .clk_deactivate = NULL, 197 .clk_set_source = NULL, 198 .clk_accessible = NULL, 199 .clk_get_source_freq = am335x_clk_get_sysclk_freq, 200 }, 201 /* MPU (ARM) core clocks */ 202 { .id = MPU_CLK, 203 .clk_activate = NULL, 204 .clk_deactivate = NULL, 205 .clk_set_source = NULL, 206 .clk_accessible = NULL, 207 .clk_get_source_freq = am335x_clk_get_arm_fclk_freq, 208 }, 209 /* CPSW Ethernet Switch core clocks */ 210 { .id = CPSW_CLK, 211 .clk_activate = am335x_clk_cpsw_activate, 212 .clk_deactivate = NULL, 213 .clk_set_source = NULL, 214 .clk_accessible = NULL, 215 .clk_get_source_freq = NULL, 216 }, 217 218 /* Mentor USB HS controller core clocks */ 219 { .id = MUSB0_CLK, 220 .clk_activate = am335x_clk_musb0_activate, 221 .clk_deactivate = NULL, 222 .clk_set_source = NULL, 223 .clk_accessible = NULL, 224 .clk_get_source_freq = NULL, 225 }, 226 227 /* LCD controller clocks */ 228 { .id = LCDC_CLK, 229 .clk_activate = am335x_clk_lcdc_activate, 230 .clk_deactivate = NULL, 231 .clk_set_source = NULL, 232 .clk_accessible = NULL, 233 .clk_get_source_freq = am335x_clk_get_arm_disp_freq, 234 }, 235 236 /* UART. Uart0 clock cannot be controlled. */ 237 AM335X_NOOP_CLOCK_DEV(UART0_CLK), 238 AM335X_GENERIC_CLOCK_DEV(UART1_CLK), 239 AM335X_GENERIC_CLOCK_DEV(UART2_CLK), 240 AM335X_GENERIC_CLOCK_DEV(UART3_CLK), 241 AM335X_GENERIC_CLOCK_DEV(UART4_CLK), 242 AM335X_GENERIC_CLOCK_DEV(UART5_CLK), 243 244 /* DMTimer */ 245 AM335X_GENERIC_CLOCK_DEV(DMTIMER2_CLK), 246 AM335X_GENERIC_CLOCK_DEV(DMTIMER3_CLK), 247 AM335X_GENERIC_CLOCK_DEV(DMTIMER4_CLK), 248 AM335X_GENERIC_CLOCK_DEV(DMTIMER5_CLK), 249 AM335X_GENERIC_CLOCK_DEV(DMTIMER6_CLK), 250 AM335X_GENERIC_CLOCK_DEV(DMTIMER7_CLK), 251 252 /* GPIO */ 253 AM335X_GPIO_CLOCK_DEV(GPIO0_CLK), 254 AM335X_GPIO_CLOCK_DEV(GPIO1_CLK), 255 AM335X_GPIO_CLOCK_DEV(GPIO2_CLK), 256 AM335X_GPIO_CLOCK_DEV(GPIO3_CLK), 257 258 /* I2C */ 259 AM335X_GENERIC_CLOCK_DEV(I2C0_CLK), 260 AM335X_GENERIC_CLOCK_DEV(I2C1_CLK), 261 AM335X_GENERIC_CLOCK_DEV(I2C2_CLK), 262 263 /* EDMA */ 264 AM335X_GENERIC_CLOCK_DEV(EDMA_TPCC_CLK), 265 AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC0_CLK), 266 AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC1_CLK), 267 AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK), 268 269 /* MMCHS */ 270 AM335X_MMCHS_CLOCK_DEV(MMC0_CLK), 271 AM335X_MMCHS_CLOCK_DEV(MMC1_CLK), 272 AM335X_MMCHS_CLOCK_DEV(MMC2_CLK), 273 274 /* PWMSS */ 275 AM335X_GENERIC_CLOCK_DEV(PWMSS0_CLK), 276 AM335X_GENERIC_CLOCK_DEV(PWMSS1_CLK), 277 AM335X_GENERIC_CLOCK_DEV(PWMSS2_CLK), 278 279 /* System Mailbox clock */ 280 AM335X_GENERIC_CLOCK_DEV(MAILBOX0_CLK), 281 282 /* SPINLOCK */ 283 AM335X_GENERIC_CLOCK_DEV(SPINLOCK0_CLK), 284 285 /* PRU-ICSS */ 286 { .id = PRUSS_CLK, 287 .clk_activate = am335x_clk_pruss_activate, 288 .clk_deactivate = NULL, 289 .clk_set_source = NULL, 290 .clk_accessible = NULL, 291 .clk_get_source_freq = NULL, 292 }, 293 294 295 296 { INVALID_CLK_IDENT, NULL, NULL, NULL, NULL } 297}; 298 299struct am335x_clk_details { 300 clk_ident_t id; 301 uint32_t clkctrl_reg; 302 uint32_t clksel_reg; 303}; 304 305#define _CLK_DETAIL(i, c, s) \ 306 { .id = (i), \ 307 .clkctrl_reg = (c), \ 308 .clksel_reg = (s), \ 309 } 310 311static struct am335x_clk_details g_am335x_clk_details[] = { 312 313 /* UART. UART0 clock not controllable. */ 314 _CLK_DETAIL(UART0_CLK, 0, 0), 315 _CLK_DETAIL(UART1_CLK, CM_PER_UART1_CLKCTRL, 0), 316 _CLK_DETAIL(UART2_CLK, CM_PER_UART2_CLKCTRL, 0), 317 _CLK_DETAIL(UART3_CLK, CM_PER_UART3_CLKCTRL, 0), 318 _CLK_DETAIL(UART4_CLK, CM_PER_UART4_CLKCTRL, 0), 319 _CLK_DETAIL(UART5_CLK, CM_PER_UART5_CLKCTRL, 0), 320 321 /* DMTimer modules */ 322 _CLK_DETAIL(DMTIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK), 323 _CLK_DETAIL(DMTIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK), 324 _CLK_DETAIL(DMTIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK), 325 _CLK_DETAIL(DMTIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK), 326 _CLK_DETAIL(DMTIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK), 327 _CLK_DETAIL(DMTIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK), 328 329 /* GPIO modules */ 330 _CLK_DETAIL(GPIO0_CLK, CM_WKUP_GPIO0_CLKCTRL, 0), 331 _CLK_DETAIL(GPIO1_CLK, CM_PER_GPIO1_CLKCTRL, 0), 332 _CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO2_CLKCTRL, 0), 333 _CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO3_CLKCTRL, 0), 334 335 /* I2C modules */ 336 _CLK_DETAIL(I2C0_CLK, CM_WKUP_I2C0_CLKCTRL, 0), 337 _CLK_DETAIL(I2C1_CLK, CM_PER_I2C1_CLKCTRL, 0), 338 _CLK_DETAIL(I2C2_CLK, CM_PER_I2C2_CLKCTRL, 0), 339 340 /* EDMA modules */ 341 _CLK_DETAIL(EDMA_TPCC_CLK, CM_PER_TPCC_CLKCTRL, 0), 342 _CLK_DETAIL(EDMA_TPTC0_CLK, CM_PER_TPTC0_CLKCTRL, 0), 343 _CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0), 344 _CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0), 345 346 /* MMCHS modules*/ 347 _CLK_DETAIL(MMC0_CLK, CM_PER_MMC0_CLKCTRL, 0), 348 _CLK_DETAIL(MMC1_CLK, CM_PER_MMC1_CLKCTRL, 0), 349 _CLK_DETAIL(MMC2_CLK, CM_PER_MMC1_CLKCTRL, 0), 350 351 /* PWMSS modules */ 352 _CLK_DETAIL(PWMSS0_CLK, CM_PER_EPWMSS0_CLKCTRL, 0), 353 _CLK_DETAIL(PWMSS1_CLK, CM_PER_EPWMSS1_CLKCTRL, 0), 354 _CLK_DETAIL(PWMSS2_CLK, CM_PER_EPWMSS2_CLKCTRL, 0), 355 356 _CLK_DETAIL(MAILBOX0_CLK, CM_PER_MAILBOX0_CLKCTRL, 0), 357 _CLK_DETAIL(SPINLOCK0_CLK, CM_PER_SPINLOCK0_CLKCTRL, 0), 358 359 { INVALID_CLK_IDENT, 0}, 360}; 361 362/* Read/Write macros */ 363#define prcm_read_4(reg) \ 364 bus_space_read_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg) 365#define prcm_write_4(reg, val) \ 366 bus_space_write_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg, val) 367 368void am335x_prcm_setup_dmtimer(int); 369 370static int 371am335x_prcm_probe(device_t dev) 372{ 373 if (ofw_bus_is_compatible(dev, "am335x,prcm")) { 374 device_set_desc(dev, "AM335x Power and Clock Management"); 375 return(BUS_PROBE_DEFAULT); 376 } 377 378 return (ENXIO); 379} 380 381static int 382am335x_prcm_attach(device_t dev) 383{ 384 struct am335x_prcm_softc *sc = device_get_softc(dev); 385 unsigned int sysclk, fclk; 386 387 if (am335x_prcm_sc) 388 return (ENXIO); 389 390 if (bus_alloc_resources(dev, am335x_prcm_spec, sc->res)) { 391 device_printf(dev, "could not allocate resources\n"); 392 return (ENXIO); 393 } 394 395 sc->bst = rman_get_bustag(sc->res[0]); 396 sc->bsh = rman_get_bushandle(sc->res[0]); 397 398 am335x_prcm_sc = sc; 399 ti_cpu_reset = am335x_prcm_reset; 400 401 am335x_clk_get_sysclk_freq(NULL, &sysclk); 402 am335x_clk_get_arm_fclk_freq(NULL, &fclk); 403 device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n", 404 sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000); 405 406 return (0); 407} 408 409static device_method_t am335x_prcm_methods[] = { 410 DEVMETHOD(device_probe, am335x_prcm_probe), 411 DEVMETHOD(device_attach, am335x_prcm_attach), 412 { 0, 0 } 413}; 414 415static driver_t am335x_prcm_driver = { 416 "am335x_prcm", 417 am335x_prcm_methods, 418 sizeof(struct am335x_prcm_softc), 419}; 420 421static devclass_t am335x_prcm_devclass; 422 423DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver, 424 am335x_prcm_devclass, 0, 0); 425MODULE_DEPEND(am335x_prcm, ti_scm, 1, 1, 1); 426 427static struct am335x_clk_details* 428am335x_clk_details(clk_ident_t id) 429{ 430 struct am335x_clk_details *walker; 431 432 for (walker = g_am335x_clk_details; walker->id != INVALID_CLK_IDENT; walker++) { 433 if (id == walker->id) 434 return (walker); 435 } 436 437 return NULL; 438} 439 440static int 441am335x_clk_noop_activate(struct ti_clock_dev *clkdev) 442{ 443 444 return (0); 445} 446 447static int 448am335x_clk_generic_activate(struct ti_clock_dev *clkdev) 449{ 450 struct am335x_prcm_softc *sc = am335x_prcm_sc; 451 struct am335x_clk_details* clk_details; 452 453 if (sc == NULL) 454 return ENXIO; 455 456 clk_details = am335x_clk_details(clkdev->id); 457 458 if (clk_details == NULL) 459 return (ENXIO); 460 461 /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */ 462 prcm_write_4(clk_details->clkctrl_reg, 2); 463 while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 2) 464 DELAY(10); 465 466 return (0); 467} 468 469static int 470am335x_clk_gpio_activate(struct ti_clock_dev *clkdev) 471{ 472 struct am335x_prcm_softc *sc = am335x_prcm_sc; 473 struct am335x_clk_details* clk_details; 474 475 if (sc == NULL) 476 return ENXIO; 477 478 clk_details = am335x_clk_details(clkdev->id); 479 480 if (clk_details == NULL) 481 return (ENXIO); 482 483 /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */ 484 /* set *_CLKCTRL register OPTFCLKEN_GPIO_1_G DBCLK[18] to FCLK_EN(1) */ 485 prcm_write_4(clk_details->clkctrl_reg, 2 | (1 << 18)); 486 while ((prcm_read_4(clk_details->clkctrl_reg) & 487 (3 | (1 << 18) )) != (2 | (1 << 18))) 488 DELAY(10); 489 490 return (0); 491} 492 493static int 494am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev) 495{ 496 497 return(0); 498} 499 500static int 501am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev) 502{ 503 struct am335x_prcm_softc *sc = am335x_prcm_sc; 504 struct am335x_clk_details* clk_details; 505 506 if (sc == NULL) 507 return ENXIO; 508 509 clk_details = am335x_clk_details(clkdev->id); 510 511 if (clk_details == NULL) 512 return (ENXIO); 513 514 /* set *_CLKCTRL register MODULEMODE[1:0] to disable(0) */ 515 prcm_write_4(clk_details->clkctrl_reg, 0); 516 while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 0) 517 DELAY(10); 518 519 return (0); 520} 521 522static int 523am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc) 524{ 525 526 return (0); 527} 528 529static int 530am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc) 531{ 532 struct am335x_prcm_softc *sc = am335x_prcm_sc; 533 struct am335x_clk_details* clk_details; 534 uint32_t reg; 535 536 if (sc == NULL) 537 return ENXIO; 538 539 clk_details = am335x_clk_details(clkdev->id); 540 541 if (clk_details == NULL) 542 return (ENXIO); 543 544 switch (clksrc) { 545 case EXT_CLK: 546 reg = 0; /* SEL2: TCLKIN clock */ 547 break; 548 case SYSCLK_CLK: 549 reg = 1; /* SEL1: CLK_M_OSC clock */ 550 break; 551 case F32KHZ_CLK: 552 reg = 2; /* SEL3: CLK_32KHZ clock */ 553 break; 554 default: 555 return (ENXIO); 556 } 557 558 prcm_write_4(clk_details->clksel_reg, reg); 559 while ((prcm_read_4(clk_details->clksel_reg) & 0x3) != reg) 560 DELAY(10); 561 562 return (0); 563} 564 565static int 566am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq) 567{ 568 *freq = 96000000; 569 return (0); 570} 571 572static int 573am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq) 574{ 575 uint32_t ctrl_status; 576 577 /* Read the input clock freq from the control module */ 578 /* control_status reg (0x40) */ 579 if (ti_scm_reg_read_4(0x40, &ctrl_status)) 580 return ENXIO; 581 582 switch ((ctrl_status>>22) & 0x3) { 583 case 0x0: 584 /* 19.2Mhz */ 585 *freq = 19200000; 586 break; 587 case 0x1: 588 /* 24Mhz */ 589 *freq = 24000000; 590 break; 591 case 0x2: 592 /* 25Mhz */ 593 *freq = 25000000; 594 break; 595 case 0x3: 596 /* 26Mhz */ 597 *freq = 26000000; 598 break; 599 } 600 601 return (0); 602} 603 604#define DPLL_BYP_CLKSEL(reg) ((reg>>23) & 1) 605#define DPLL_DIV(reg) ((reg & 0x7f)+1) 606#define DPLL_MULT(reg) ((reg>>8) & 0x7FF) 607 608static int 609am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq) 610{ 611 uint32_t reg; 612 uint32_t sysclk; 613 614 reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_MPU); 615 616 /*Check if we are running in bypass */ 617 if (DPLL_BYP_CLKSEL(reg)) 618 return ENXIO; 619 620 am335x_clk_get_sysclk_freq(NULL, &sysclk); 621 *freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg)); 622 return(0); 623} 624 625static int 626am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq) 627{ 628 uint32_t reg; 629 uint32_t sysclk; 630 631 reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_DISP); 632 633 /*Check if we are running in bypass */ 634 if (DPLL_BYP_CLKSEL(reg)) 635 return ENXIO; 636 637 am335x_clk_get_sysclk_freq(NULL, &sysclk); 638 *freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg)); 639 return(0); 640} 641 642static void 643am335x_prcm_reset(void) 644{ 645 prcm_write_4(PRM_RSTCTRL, (1<<1)); 646} 647 648static int 649am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev) 650{ 651 struct am335x_prcm_softc *sc = am335x_prcm_sc; 652 653 if (sc == NULL) 654 return ENXIO; 655 656 /* set MODULENAME to ENABLE */ 657 prcm_write_4(CM_PER_CPGMAC0_CLKCTRL, 2); 658 659 /* wait for IDLEST to become Func(0) */ 660 while(prcm_read_4(CM_PER_CPGMAC0_CLKCTRL) & (3<<16)); 661 662 /*set CLKTRCTRL to SW_WKUP(2) */ 663 prcm_write_4(CM_PER_CPSW_CLKSTCTRL, 2); 664 665 /* wait for 125 MHz OCP clock to become active */ 666 while((prcm_read_4(CM_PER_CPSW_CLKSTCTRL) & (1<<4)) == 0); 667 return(0); 668} 669 670static int 671am335x_clk_musb0_activate(struct ti_clock_dev *clkdev) 672{ 673 struct am335x_prcm_softc *sc = am335x_prcm_sc; 674 675 if (sc == NULL) 676 return ENXIO; 677 678 /* set ST_DPLL_CLKDCOLDO(9) to CLK_GATED(1) */ 679 /* set DPLL_CLKDCOLDO_GATE_CTRL(8) to CLK_ENABLE(1)*/ 680 prcm_write_4(CM_WKUP_CM_CLKDCOLDO_DPLL_PER, 0x300); 681 682 /*set MODULEMODE to ENABLE(2) */ 683 prcm_write_4(CM_PER_USB0_CLKCTRL, 2); 684 685 /* wait for MODULEMODE to become ENABLE(2) */ 686 while ((prcm_read_4(CM_PER_USB0_CLKCTRL) & 0x3) != 2) 687 DELAY(10); 688 689 /* wait for IDLEST to become Func(0) */ 690 while(prcm_read_4(CM_PER_USB0_CLKCTRL) & (3<<16)) 691 DELAY(10); 692 693 return(0); 694} 695 696static int 697am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev) 698{ 699 struct am335x_prcm_softc *sc = am335x_prcm_sc; 700 701 if (sc == NULL) 702 return (ENXIO); 703 704 /* Bypass mode */ 705 prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x4); 706 707 /* Make sure it's in bypass mode */ 708 while (!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP) 709 & (1 << 8))) 710 DELAY(10); 711 712 /* 713 * For now set frequency to 5xSYSFREQ 714 * More flexible control might be required 715 */ 716 prcm_write_4(CM_WKUP_CM_CLKSEL_DPLL_DISP, (5 << 8) | 0); 717 718 /* Locked mode */ 719 prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x7); 720 721 int timeout = 10000; 722 while ((!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP) 723 & (1 << 0))) && timeout--) 724 DELAY(10); 725 726 /*set MODULEMODE to ENABLE(2) */ 727 prcm_write_4(CM_PER_LCDC_CLKCTRL, 2); 728 729 /* wait for MODULEMODE to become ENABLE(2) */ 730 while ((prcm_read_4(CM_PER_LCDC_CLKCTRL) & 0x3) != 2) 731 DELAY(10); 732 733 /* wait for IDLEST to become Func(0) */ 734 while(prcm_read_4(CM_PER_LCDC_CLKCTRL) & (3<<16)) 735 DELAY(10); 736 737 return (0); 738} 739 740static int 741am335x_clk_pruss_activate(struct ti_clock_dev *clkdev) 742{ 743 struct am335x_prcm_softc *sc = am335x_prcm_sc; 744 745 if (sc == NULL) 746 return (ENXIO); 747 748 /* Set MODULEMODE to ENABLE(2) */ 749 prcm_write_4(CM_PER_PRUSS_CLKCTRL, 2); 750 751 /* Wait for MODULEMODE to become ENABLE(2) */ 752 while ((prcm_read_4(CM_PER_PRUSS_CLKCTRL) & 0x3) != 2) 753 DELAY(10); 754 755 /* Set CLKTRCTRL to SW_WKUP(2) */ 756 prcm_write_4(CM_PER_PRUSS_CLKSTCTRL, 2); 757 758 /* Wait for the 200 MHz OCP clock to become active */ 759 while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<4)) == 0) 760 DELAY(10); 761 762 /* Wait for the 200 MHz IEP clock to become active */ 763 while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<5)) == 0) 764 DELAY(10); 765 766 /* Wait for the 192 MHz UART clock to become active */ 767 while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<6)) == 0) 768 DELAY(10); 769 770 /* Select DISP DPLL as OCP clock */ 771 prcm_write_4(CLKSEL_PRUSS_OCP_CLK, 1); 772 while ((prcm_read_4(CLKSEL_PRUSS_OCP_CLK) & 0x3) != 1) 773 DELAY(10); 774 775 /* Clear the RESET bit */ 776 prcm_write_4(PRM_PER_RSTCTRL, prcm_read_4(PRM_PER_RSTCTRL) & ~2); 777 778 return (0); 779} 780