1 /* $NetBSD: tegra210_car.c,v 1.27 2021/01/27 03:10:19 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2015-2017 Jared McNeill <jmcneill (at) invisible.ca> 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 ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * 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 __KERNEL_RCSID(0, "$NetBSD: tegra210_car.c,v 1.27 2021/01/27 03:10:19 thorpej Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/device.h> 35 #include <sys/intr.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/rndsource.h> 39 #include <sys/atomic.h> 40 #include <sys/kmem.h> 41 42 #include <dev/clk/clk_backend.h> 43 44 #include <arm/nvidia/tegra_reg.h> 45 #include <arm/nvidia/tegra210_carreg.h> 46 #include <arm/nvidia/tegra_clock.h> 47 #include <arm/nvidia/tegra_pmcreg.h> 48 #include <arm/nvidia/tegra_var.h> 49 50 #include <dev/fdt/fdtvar.h> 51 52 static int tegra210_car_match(device_t, cfdata_t, void *); 53 static void tegra210_car_attach(device_t, device_t, void *); 54 55 static struct clk *tegra210_car_clock_decode(device_t, int, const void *, 56 size_t); 57 58 static const struct fdtbus_clock_controller_func tegra210_car_fdtclock_funcs = { 59 .decode = tegra210_car_clock_decode 60 }; 61 62 /* DT clock ID to clock name mappings */ 63 static struct tegra210_car_clock_id { 64 const char *name; 65 u_int id; 66 } tegra210_car_clock_ids[] = { 67 { "ISPB", 3 }, 68 { "RTC", 4 }, 69 { "TIMER", 5 }, 70 { "UARTA", 6 }, 71 { "GPIO", 8 }, 72 { "SDMMC2", 9 }, 73 { "I2S1", 11 }, 74 { "I2C1", 12 }, 75 { "SDMMC1", 14 }, 76 { "SDMMC4", 15 }, 77 { "PWM", 17 }, 78 { "I2S2", 18 }, 79 { "USBD", 22 }, 80 { "ISP", 23 }, 81 { "DISP2", 26 }, 82 { "DISP1", 27 }, 83 { "HOST1X", 28 }, 84 { "I2S0", 30 }, 85 { "MC", 32 }, 86 { "AHBDMA", 33 }, 87 { "APBDMA", 34 }, 88 { "PMC", 38 }, 89 { "KFUSE", 40 }, 90 { "SBC1", 41 }, 91 { "SBC2", 44 }, 92 { "SBC3", 46 }, 93 { "I2C5", 47 }, 94 { "DSIA", 48 }, 95 { "CSI", 52 }, 96 { "I2C2", 54 }, 97 { "UARTC", 55 }, 98 { "MIPI_CAL", 56 }, 99 { "EMC", 57 }, 100 { "USB2", 58 }, 101 { "BSEV", 63 }, 102 { "UARTD", 65 }, 103 { "I2C3", 67 }, 104 { "SBC4", 68 }, 105 { "SDMMC3", 69 }, 106 { "PCIE", 70 }, 107 { "OWR", 71 }, 108 { "AFI", 72 }, 109 { "CSITE", 73 }, 110 { "SOC_THERM", 78 }, 111 { "DTV", 79 }, 112 { "I2CSLOW", 81 }, 113 { "DSIB", 82 }, 114 { "TSEC", 83 }, 115 { "XUSB_HOST", 89 }, 116 { "CSUS", 92 }, 117 { "MSELECT", 99 }, 118 { "TSENSOR", 100 }, 119 { "I2S3", 101 }, 120 { "I2S4", 102 }, 121 { "I2C4", 103 }, 122 { "D_AUDIO", 106 }, 123 { "APB2APE", 107 }, 124 { "HDA2CODEC_2X", 111 }, 125 { "SPDIF_2X", 118 }, 126 { "ACTMON", 119 }, 127 { "EXTERN1", 120 }, 128 { "EXTERN2", 121 }, 129 { "EXTERN3", 122 }, 130 { "SATA_OOB", 123 }, 131 { "SATA", 124 }, 132 { "HDA", 125 }, 133 { "HDA2HDMI", 128 }, 134 { "XUSB_GATE", 143 }, 135 { "CILAB", 144 }, 136 { "CILCD", 145 }, 137 { "CILE", 146 }, 138 { "DSIALP", 147 }, 139 { "DSIBLP", 148 }, 140 { "ENTROPY", 149 }, 141 { "XUSB_SS", 156 }, 142 { "DMIC1", 161 }, 143 { "DMIC2", 162 }, 144 { "I2C6", 166 }, 145 { "VIM2_CLK", 171 }, 146 { "MIPIBIF", 173 }, 147 { "CLK72MHZ", 177 }, 148 { "VIC03", 178 }, 149 { "DPAUX", 181 }, 150 { "SOR0", 182 }, 151 { "SOR1", 183 }, 152 { "GPU", 184 }, 153 { "DBGAPB", 185 }, 154 { "PLL_P_OUT_ADSP", 187 }, 155 { "PLL_G_REF", 189 }, 156 { "SDMMC_LEGACY", 193 }, 157 { "NVDEC", 194 }, 158 { "NVJPG", 195 }, 159 { "DMIC3", 197 }, 160 { "APE", 198 }, 161 { "MAUD", 202 }, 162 { "TSECB", 206 }, 163 { "DPAUX1", 207 }, 164 { "VI_I2C", 208 }, 165 { "HSIC_TRK", 209 }, 166 { "USB2_TRK", 210 }, 167 { "QSPI", 211 }, 168 { "UARTAPE", 212 }, 169 { "NVENC", 219 }, 170 { "SOR_SAFE", 222 }, 171 { "PLL_P_OUT_CPU", 223 }, 172 { "UARTB", 224 }, 173 { "VFIR", 225 }, 174 { "SPDIF_IN", 226 }, 175 { "SPDIF_OUT", 227 }, 176 { "VI", 228 }, 177 { "VI_SENSOR", 229 }, 178 { "FUSE", 230 }, 179 { "FUSE_BURN", 231 }, 180 { "CLK_32K", 232 }, 181 { "CLK_M", 233 }, 182 { "CLK_M_DIV2", 234 }, 183 { "CLK_M_DIV4", 235 }, 184 { "PLL_REF", 236 }, 185 { "PLL_C", 237 }, 186 { "PLL_C_OUT1", 238 }, 187 { "PLL_C2", 239 }, 188 { "PLL_C3", 240 }, 189 { "PLL_M", 241 }, 190 { "PLL_M_OUT1", 242 }, 191 { "PLL_P", 243 }, 192 { "PLL_P_OUT1", 244 }, 193 { "PLL_P_OUT2", 245 }, 194 { "PLL_P_OUT3", 246 }, 195 { "PLL_P_OUT4", 247 }, 196 { "PLL_A", 248 }, 197 { "PLL_A_OUT0", 249 }, 198 { "PLL_D", 250 }, 199 { "PLL_D_OUT0", 251 }, 200 { "PLL_D2", 252 }, 201 { "PLL_D2_OUT0", 253 }, 202 { "PLL_U", 254 }, 203 { "PLL_U_480M", 255 }, 204 { "PLL_U_60M", 256 }, 205 { "PLL_U_48M", 257 }, 206 { "PLL_X", 259 }, 207 { "PLL_X_OUT0", 260 }, 208 { "PLL_RE_VCO", 261 }, 209 { "PLL_RE_OUT", 262 }, 210 { "PLL_E", 263 }, 211 { "SPDIF_IN_SYNC", 264 }, 212 { "I2S0_SYNC", 265 }, 213 { "I2S1_SYNC", 266 }, 214 { "I2S2_SYNC", 267 }, 215 { "I2S3_SYNC", 268 }, 216 { "I2S4_SYNC", 269 }, 217 { "VIMCLK_SYNC", 270 }, 218 { "AUDIO0", 271 }, 219 { "AUDIO1", 272 }, 220 { "AUDIO2", 273 }, 221 { "AUDIO3", 274 }, 222 { "AUDIO4", 275 }, 223 { "SPDIF", 276 }, 224 { "CLK_OUT_1", 277 }, 225 { "CLK_OUT_2", 278 }, 226 { "CLK_OUT_3", 279 }, 227 { "BLINK", 280 }, 228 { "SOR1_SRC", 282 }, 229 { "XUSB_HOST_SRC", 284 }, 230 { "XUSB_FALCON_SRC", 285 }, 231 { "XUSB_FS_SRC", 286 }, 232 { "XUSB_SS_SRC", 287 }, 233 { "XUSB_DEV_SRC", 288 }, 234 { "XUSB_DEV", 289 }, 235 { "XUSB_HS_SRC", 290 }, 236 { "SCLK", 291 }, 237 { "HCLK", 292 }, 238 { "PCLK", 293 }, 239 { "CCLK_G", 294 }, 240 { "CCLK_LP", 295 }, 241 { "DFLL_REF", 296 }, 242 { "DFLL_SOC", 297 }, 243 { "VI_SENSOR2", 298 }, 244 { "PLL_P_OUT5", 299 }, 245 { "CML0", 300 }, 246 { "CML1", 301 }, 247 { "PLL_C4", 302 }, 248 { "PLL_DP", 303 }, 249 { "PLL_E_MUX", 304 }, 250 { "PLL_MB", 305 }, 251 { "PLL_A1", 306 }, 252 { "PLL_D_DSI_OUT", 307 }, 253 { "PLL_C4_OUT0", 308 }, 254 { "PLL_C4_OUT1", 309 }, 255 { "PLL_C4_OUT2", 310 }, 256 { "PLL_C4_OUT3", 311 }, 257 { "PLL_U_OUT", 312 }, 258 { "PLL_U_OUT1", 313 }, 259 { "PLL_U_OUT2", 314 }, 260 { "USB2_HSIC_TRK", 315 }, 261 { "PLL_P_OUT_HSIO", 316 }, 262 { "PLL_P_OUT_XUSB", 317 }, 263 { "XUSB_SSP_SRC", 318 }, 264 { "PLL_RE_OUT1", 319 }, 265 { "AUDIO0_MUX", 350 }, 266 { "AUDIO1_MUX", 351 }, 267 { "AUDIO2_MUX", 352 }, 268 { "AUDIO3_MUX", 353 }, 269 { "AUDIO4_MUX", 354 }, 270 { "SPDIF_MUX", 355 }, 271 { "CLK_OUT_1_MUX", 356 }, 272 { "CLK_OUT_2_MUX", 357 }, 273 { "CLK_OUT_3_MUX", 358 }, 274 { "DSIA_MUX", 359 }, 275 { "DSIB_MUX", 360 }, 276 { "SOR0_LVDS", 361 }, 277 { "XUSB_SS_DIV2", 362 }, 278 { "PLL_M_UD", 363 }, 279 { "PLL_C_UD", 364 }, 280 { "SCLK_MUX", 365 }, 281 }; 282 283 static struct clk *tegra210_car_clock_get(void *, const char *); 284 static void tegra210_car_clock_put(void *, struct clk *); 285 static u_int tegra210_car_clock_get_rate(void *, struct clk *); 286 static int tegra210_car_clock_set_rate(void *, struct clk *, u_int); 287 static int tegra210_car_clock_enable(void *, struct clk *); 288 static int tegra210_car_clock_disable(void *, struct clk *); 289 static int tegra210_car_clock_set_parent(void *, struct clk *, 290 struct clk *); 291 static struct clk *tegra210_car_clock_get_parent(void *, struct clk *); 292 293 static const struct clk_funcs tegra210_car_clock_funcs = { 294 .get = tegra210_car_clock_get, 295 .put = tegra210_car_clock_put, 296 .get_rate = tegra210_car_clock_get_rate, 297 .set_rate = tegra210_car_clock_set_rate, 298 .enable = tegra210_car_clock_enable, 299 .disable = tegra210_car_clock_disable, 300 .set_parent = tegra210_car_clock_set_parent, 301 .get_parent = tegra210_car_clock_get_parent, 302 }; 303 304 #define CLK_FIXED(_name, _rate) { \ 305 .base = { .name = (_name) }, .type = TEGRA_CLK_FIXED, \ 306 .u = { .fixed = { .rate = (_rate) } } \ 307 } 308 309 #define CLK_PLL(_name, _parent, _base, _divm, _divn, _divp) { \ 310 .base = { .name = (_name) }, .type = TEGRA_CLK_PLL, \ 311 .parent = (_parent), \ 312 .u = { \ 313 .pll = { \ 314 .base_reg = (_base), \ 315 .divm_mask = (_divm), \ 316 .divn_mask = (_divn), \ 317 .divp_mask = (_divp), \ 318 } \ 319 } \ 320 } 321 322 #define CLK_MUX(_name, _reg, _bits, _p) { \ 323 .base = { .name = (_name) }, .type = TEGRA_CLK_MUX, \ 324 .u = { \ 325 .mux = { \ 326 .nparents = __arraycount(_p), \ 327 .parents = (_p), \ 328 .reg = (_reg), \ 329 .bits = (_bits) \ 330 } \ 331 } \ 332 } 333 334 #define CLK_FIXED_DIV(_name, _parent, _div) { \ 335 .base = { .name = (_name) }, .type = TEGRA_CLK_FIXED_DIV, \ 336 .parent = (_parent), \ 337 .u = { \ 338 .fixed_div = { \ 339 .div = (_div) \ 340 } \ 341 } \ 342 } 343 344 #define CLK_DIV(_name, _parent, _reg, _bits) { \ 345 .base = { .name = (_name) }, .type = TEGRA_CLK_DIV, \ 346 .parent = (_parent), \ 347 .u = { \ 348 .div = { \ 349 .reg = (_reg), \ 350 .bits = (_bits) \ 351 } \ 352 } \ 353 } 354 355 #define CLK_GATE(_name, _parent, _set, _clr, _bits) { \ 356 .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \ 357 .type = TEGRA_CLK_GATE, \ 358 .parent = (_parent), \ 359 .u = { \ 360 .gate = { \ 361 .set_reg = (_set), \ 362 .clr_reg = (_clr), \ 363 .bits = (_bits), \ 364 } \ 365 } \ 366 } 367 368 #define CLK_GATE_L(_name, _parent, _bits) \ 369 CLK_GATE(_name, _parent, \ 370 CAR_CLK_ENB_L_SET_REG, CAR_CLK_ENB_L_CLR_REG, \ 371 _bits) 372 373 #define CLK_GATE_H(_name, _parent, _bits) \ 374 CLK_GATE(_name, _parent, \ 375 CAR_CLK_ENB_H_SET_REG, CAR_CLK_ENB_H_CLR_REG, \ 376 _bits) 377 378 #define CLK_GATE_U(_name, _parent, _bits) \ 379 CLK_GATE(_name, _parent, \ 380 CAR_CLK_ENB_U_SET_REG, CAR_CLK_ENB_U_CLR_REG, \ 381 _bits) 382 383 #define CLK_GATE_V(_name, _parent, _bits) \ 384 CLK_GATE(_name, _parent, \ 385 CAR_CLK_ENB_V_SET_REG, CAR_CLK_ENB_V_CLR_REG, \ 386 _bits) 387 388 #define CLK_GATE_W(_name, _parent, _bits) \ 389 CLK_GATE(_name, _parent, \ 390 CAR_CLK_ENB_W_SET_REG, CAR_CLK_ENB_W_CLR_REG, \ 391 _bits) 392 393 #define CLK_GATE_X(_name, _parent, _bits) \ 394 CLK_GATE(_name, _parent, \ 395 CAR_CLK_ENB_X_SET_REG, CAR_CLK_ENB_X_CLR_REG, \ 396 _bits) 397 398 #define CLK_GATE_Y(_name, _parent, _bits) \ 399 CLK_GATE(_name, _parent, \ 400 CAR_CLK_ENB_Y_SET_REG, CAR_CLK_ENB_Y_CLR_REG, \ 401 _bits) 402 403 404 #define CLK_GATE_SIMPLE(_name, _parent, _reg, _bits) \ 405 CLK_GATE(_name, _parent, _reg, _reg, _bits) 406 407 static const char *mux_uart_p[] = 408 { "PLL_P", "PLL_C2", "PLL_C", "PLL_C4_OUT0", 409 NULL, "PLL_C4_OUT1", "CLK_M", "PLL_C4_OUT2" }; 410 411 static const char *mux_sdmmc1_p[] = 412 { "PLL_P", "PLL_A", "PLL_C", "PLL_C4_OUT0", 413 "PLL_M", "PLL_E", "CLK_M", "PLL_C4_OUT0" }; 414 415 static const char *mux_sdmmc2_4_p[] = 416 { "PLL_P", "PLL_C4_OUT2"/*LJ*/, "PLL_C4_OUT0"/*LJ*/, "PLL_C4_OUT2", 417 "PLL_M", "PLL_E", "CLK_M", "PLL_C4_OUT0" }; 418 419 static const char *mux_sdmmc3_p[] = 420 { "PLL_P", "PLL_A", "PLL_C", "PLL_C4_OUT2", 421 "PLL_C4_OUT1", "PLL_E", "CLK_M", "PLL_C4_OUT0" }; 422 423 static const char *mux_i2c_p[] = 424 { "PLL_P", "PLL_C2_OUT0", "PLL_C", "PLL_C4_OUT0", 425 NULL, "PLL_C4_OUT1", "CLK_M", "PLL_C4_OUT2" }; 426 427 static const char *mux_xusb_host_p[] = 428 { "CLK_M", "PLL_P", NULL, NULL, 429 NULL, "PLL_REF", NULL, NULL }; 430 431 static const char *mux_xusb_fs_p[] = 432 { "CLK_M", NULL, "PLL_U_48M", NULL, 433 "PLL_P", NULL, "PLL_U_480M", NULL }; 434 435 static const char *mux_xusb_ss_p[] = 436 { "CLK_M", "PLL_REF", "CLK_32K", "PLL_U_480M", 437 NULL, NULL, NULL, NULL }; 438 439 static const char *mux_mselect_p[] = 440 { "PLL_P", "PLL_C2", "PLL_C", "PLL_C4_OUT2", 441 "PLL_C4_OUT1", "CLK_S", "CLK_M", "PLL_C4_OUT0" }; 442 443 static const char *mux_tsensor_p[] = 444 { "PLL_P", "PLL_C2", "PLL_C", "PLL_C4_OUT0", 445 "CLK_M", "PLL_C4_OUT1", "CLK_S", "PLL_C4_OUT2" }; 446 447 static const char *mux_soc_therm_p[] = 448 { "CLK_M", "PLL_C", "PLL_P", "PLL_A", 449 "PLL_C2", "PLL_C4_OUT0", "PLL_C4_OUT1", "PLL_C4_OUT2" }; 450 451 static const char *mux_hda2codec_2x_p[] = 452 { "PLL_P", "PLL_C2", "PLL_C4_OUT0", "PLL_A", 453 "PLL_A", "PLL_C4_OUT1", "CLK_M", "PLL_C4_OUT2" }; 454 455 static const char *mux_hda_p[] = 456 { "PLL_P", "PLL_C2", "PLL_C", "PLL_C4_OUT0", 457 NULL, "PLL_C4_OUT1", "CLK_M", "PLL_C4_OUT2" }; 458 459 static const char *mux_sata_p[] = 460 { "PLL_P", NULL, "PLL_C", NULL, NULL, NULL, "CLK_M" }; 461 462 static struct tegra_clk tegra210_car_clocks[] = { 463 CLK_FIXED("CLK_M", TEGRA210_REF_FREQ), 464 465 CLK_PLL("PLL_P", "CLK_M", CAR_PLLP_BASE_REG, 466 CAR_PLLP_BASE_DIVM, CAR_PLLP_BASE_DIVN, CAR_PLLP_BASE_DIVP), 467 CLK_PLL("PLL_C", "CLK_M", CAR_PLLC_BASE_REG, 468 CAR_PLLC_BASE_DIVM, CAR_PLLC_BASE_DIVN, CAR_PLLC_BASE_DIVP), 469 CLK_PLL("PLL_U", "CLK_M", CAR_PLLU_BASE_REG, 470 CAR_PLLU_BASE_DIVM, CAR_PLLU_BASE_DIVN, CAR_PLLU_BASE_DIVP), 471 CLK_PLL("PLL_X", "CLK_M", CAR_PLLX_BASE_REG, 472 CAR_PLLX_BASE_DIVM, CAR_PLLX_BASE_DIVN, CAR_PLLX_BASE_DIVP), 473 CLK_PLL("PLL_E", "CLK_M", CAR_PLLE_BASE_REG, 474 CAR_PLLE_BASE_DIVM, CAR_PLLE_BASE_DIVN, CAR_PLLE_BASE_DIVP_CML), 475 CLK_PLL("PLL_D", "CLK_M", CAR_PLLD_BASE_REG, 476 CAR_PLLD_BASE_DIVM, CAR_PLLD_BASE_DIVN, CAR_PLLD_BASE_DIVP), 477 CLK_PLL("PLL_D2", "CLK_M", CAR_PLLD2_BASE_REG, 478 CAR_PLLD2_BASE_DIVM, CAR_PLLD2_BASE_DIVN, CAR_PLLD2_BASE_DIVP), 479 CLK_PLL("PLL_REF", "CLK_M", CAR_PLLREFE_BASE_REG, 480 CAR_PLLREFE_BASE_DIVM, CAR_PLLREFE_BASE_DIVN, CAR_PLLREFE_BASE_DIVP), 481 482 CLK_FIXED_DIV("PLL_U_480M", "PLL_U", 1), 483 CLK_FIXED_DIV("PLL_U_48M", "PLL_U", 10), 484 485 CLK_MUX("MUX_UARTA", CAR_CLKSRC_UARTA_REG, CAR_CLKSRC_UART_SRC, 486 mux_uart_p), 487 CLK_MUX("MUX_UARTB", CAR_CLKSRC_UARTB_REG, CAR_CLKSRC_UART_SRC, 488 mux_uart_p), 489 CLK_MUX("MUX_UARTC", CAR_CLKSRC_UARTC_REG, CAR_CLKSRC_UART_SRC, 490 mux_uart_p), 491 CLK_MUX("MUX_UARTD", CAR_CLKSRC_UARTD_REG, CAR_CLKSRC_UART_SRC, 492 mux_uart_p), 493 494 CLK_MUX("MUX_SDMMC1", CAR_CLKSRC_SDMMC1_REG, CAR_CLKSRC_SDMMC_SRC, 495 mux_sdmmc1_p), 496 CLK_MUX("MUX_SDMMC2", CAR_CLKSRC_SDMMC2_REG, CAR_CLKSRC_SDMMC_SRC, 497 mux_sdmmc2_4_p), 498 CLK_MUX("MUX_SDMMC3", CAR_CLKSRC_SDMMC3_REG, CAR_CLKSRC_SDMMC_SRC, 499 mux_sdmmc3_p), 500 CLK_MUX("MUX_SDMMC4", CAR_CLKSRC_SDMMC4_REG, CAR_CLKSRC_SDMMC_SRC, 501 mux_sdmmc2_4_p), 502 503 CLK_MUX("MUX_I2C1", CAR_CLKSRC_I2C1_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), 504 CLK_MUX("MUX_I2C2", CAR_CLKSRC_I2C2_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), 505 CLK_MUX("MUX_I2C3", CAR_CLKSRC_I2C3_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), 506 CLK_MUX("MUX_I2C4", CAR_CLKSRC_I2C4_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), 507 CLK_MUX("MUX_I2C5", CAR_CLKSRC_I2C5_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), 508 CLK_MUX("MUX_I2C6", CAR_CLKSRC_I2C6_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), 509 510 CLK_MUX("MUX_XUSB_HOST", 511 CAR_CLKSRC_XUSB_HOST_REG, CAR_CLKSRC_XUSB_HOST_SRC, 512 mux_xusb_host_p), 513 CLK_MUX("MUX_XUSB_FALCON", 514 CAR_CLKSRC_XUSB_FALCON_REG, CAR_CLKSRC_XUSB_FALCON_SRC, 515 mux_xusb_host_p), 516 CLK_MUX("MUX_XUSB_SS", 517 CAR_CLKSRC_XUSB_SS_REG, CAR_CLKSRC_XUSB_SS_SRC, 518 mux_xusb_ss_p), 519 CLK_MUX("MUX_XUSB_FS", 520 CAR_CLKSRC_XUSB_FS_REG, CAR_CLKSRC_XUSB_FS_SRC, 521 mux_xusb_fs_p), 522 523 CLK_MUX("MUX_MSELECT", 524 CAR_CLKSRC_MSELECT_REG, CAR_CLKSRC_MSELECT_SRC, 525 mux_mselect_p), 526 527 CLK_MUX("MUX_TSENSOR", 528 CAR_CLKSRC_TSENSOR_REG, CAR_CLKSRC_TSENSOR_SRC, 529 mux_tsensor_p), 530 CLK_MUX("MUX_SOC_THERM", 531 CAR_CLKSRC_SOC_THERM_REG, CAR_CLKSRC_SOC_THERM_SRC, 532 mux_soc_therm_p), 533 534 CLK_MUX("MUX_HDA2CODEC_2X", 535 CAR_CLKSRC_HDA2CODEC_2X_REG, CAR_CLKSRC_HDA2CODEC_2X_SRC, 536 mux_hda2codec_2x_p), 537 CLK_MUX("MUX_HDA", 538 CAR_CLKSRC_HDA_REG, CAR_CLKSRC_HDA_SRC, 539 mux_hda_p), 540 541 CLK_MUX("MUX_SATA_OOB", 542 CAR_CLKSRC_SATA_OOB_REG , CAR_CLKSRC_SATA_OOB_SRC, 543 mux_sata_p), 544 CLK_MUX("MUX_SATA", 545 CAR_CLKSRC_SATA_REG, CAR_CLKSRC_SATA_SRC, 546 mux_sata_p), 547 548 CLK_DIV("DIV_UARTA", "MUX_UARTA", 549 CAR_CLKSRC_UARTA_REG, CAR_CLKSRC_UART_DIV), 550 CLK_DIV("DIV_UARTB", "MUX_UARTB", 551 CAR_CLKSRC_UARTB_REG, CAR_CLKSRC_UART_DIV), 552 CLK_DIV("DIV_UARTC", "MUX_UARTC", 553 CAR_CLKSRC_UARTC_REG, CAR_CLKSRC_UART_DIV), 554 CLK_DIV("DIV_UARTD", "MUX_UARTD", 555 CAR_CLKSRC_UARTD_REG, CAR_CLKSRC_UART_DIV), 556 557 CLK_DIV("DIV_SDMMC1", "MUX_SDMMC1", 558 CAR_CLKSRC_SDMMC1_REG, CAR_CLKSRC_SDMMC_DIV), 559 CLK_DIV("DIV_SDMMC2", "MUX_SDMMC2", 560 CAR_CLKSRC_SDMMC2_REG, CAR_CLKSRC_SDMMC_DIV), 561 CLK_DIV("DIV_SDMMC3", "MUX_SDMMC3", 562 CAR_CLKSRC_SDMMC3_REG, CAR_CLKSRC_SDMMC_DIV), 563 CLK_DIV("DIV_SDMMC4", "MUX_SDMMC4", 564 CAR_CLKSRC_SDMMC4_REG, CAR_CLKSRC_SDMMC_DIV), 565 566 CLK_DIV("DIV_I2C1", "MUX_I2C1", 567 CAR_CLKSRC_I2C1_REG, CAR_CLKSRC_I2C_DIV), 568 CLK_DIV("DIV_I2C2", "MUX_I2C2", 569 CAR_CLKSRC_I2C2_REG, CAR_CLKSRC_I2C_DIV), 570 CLK_DIV("DIV_I2C3", "MUX_I2C3", 571 CAR_CLKSRC_I2C3_REG, CAR_CLKSRC_I2C_DIV), 572 CLK_DIV("DIV_I2C4", "MUX_I2C4", 573 CAR_CLKSRC_I2C4_REG, CAR_CLKSRC_I2C_DIV), 574 CLK_DIV("DIV_I2C5", "MUX_I2C5", 575 CAR_CLKSRC_I2C5_REG, CAR_CLKSRC_I2C_DIV), 576 CLK_DIV("DIV_I2C6", "MUX_I2C6", 577 CAR_CLKSRC_I2C6_REG, CAR_CLKSRC_I2C_DIV), 578 579 CLK_DIV("XUSB_HOST_SRC", "MUX_XUSB_HOST", 580 CAR_CLKSRC_XUSB_HOST_REG, CAR_CLKSRC_XUSB_HOST_DIV), 581 CLK_DIV("XUSB_SS_SRC", "MUX_XUSB_SS", 582 CAR_CLKSRC_XUSB_SS_REG, CAR_CLKSRC_XUSB_SS_DIV), 583 CLK_DIV("XUSB_FS_SRC", "MUX_XUSB_FS", 584 CAR_CLKSRC_XUSB_FS_REG, CAR_CLKSRC_XUSB_FS_DIV), 585 CLK_DIV("XUSB_FALCON_SRC", "MUX_XUSB_FALCON", 586 CAR_CLKSRC_XUSB_FALCON_REG, CAR_CLKSRC_XUSB_FALCON_DIV), 587 CLK_DIV("USB2_HSIC_TRK", "CLK_M", 588 CAR_CLKSRC_USB2_HSIC_TRK_REG, CAR_CLKSRC_USB2_HSIC_TRK_DIV), 589 CLK_DIV("DIV_PLL_U_OUT1", "PLL_U", 590 CAR_PLLU_OUTA_REG, CAR_PLLU_OUTA_OUT1_RATIO), 591 CLK_DIV("DIV_PLL_U_OUT2", "PLL_U", 592 CAR_PLLU_OUTA_REG, CAR_PLLU_OUTA_OUT2_RATIO), 593 594 CLK_DIV("DIV_MSELECT", "MUX_MSELECT", 595 CAR_CLKSRC_MSELECT_REG, CAR_CLKSRC_MSELECT_DIV), 596 597 CLK_DIV("DIV_TSENSOR", "MUX_TSENSOR", 598 CAR_CLKSRC_TSENSOR_REG, CAR_CLKSRC_TSENSOR_DIV), 599 CLK_DIV("DIV_SOC_THERM", "MUX_SOC_THERM", 600 CAR_CLKSRC_SOC_THERM_REG, CAR_CLKSRC_SOC_THERM_DIV), 601 602 CLK_DIV("DIV_HDA2CODEC_2X", "MUX_HDA2CODEC_2X", 603 CAR_CLKSRC_HDA2CODEC_2X_REG, CAR_CLKSRC_HDA2CODEC_2X_DIV), 604 CLK_DIV("DIV_HDA", "MUX_HDA", 605 CAR_CLKSRC_HDA_REG, CAR_CLKSRC_HDA_DIV), 606 607 CLK_DIV("DIV_SATA_OOB", "MUX_SATA_OOB", 608 CAR_CLKSRC_SATA_OOB_REG, CAR_CLKSRC_SATA_OOB_DIV), 609 CLK_DIV("DIV_SATA", "MUX_SATA", 610 CAR_CLKSRC_SATA_REG, CAR_CLKSRC_SATA_DIV), 611 612 CLK_GATE_SIMPLE("PLL_U_OUT1", "DIV_PLL_U_OUT1", 613 CAR_PLLU_OUTA_REG, CAR_PLLU_OUTA_OUT1_CLKEN), 614 CLK_GATE_SIMPLE("PLL_U_OUT2", "DIV_PLL_U_OUT2", 615 CAR_PLLU_OUTA_REG, CAR_PLLU_OUTA_OUT2_CLKEN), 616 617 CLK_GATE_SIMPLE("CML0", "PLL_E", 618 CAR_PLLE_AUX_REG, CAR_PLLE_AUX_CML0_OEN), 619 CLK_GATE_SIMPLE("CML1", "PLL_E", 620 CAR_PLLE_AUX_REG, CAR_PLLE_AUX_CML1_OEN), 621 622 CLK_GATE_L("UARTA", "DIV_UARTA", CAR_DEV_L_UARTA), 623 CLK_GATE_L("UARTB", "DIV_UARTB", CAR_DEV_L_UARTB), 624 CLK_GATE_H("UARTC", "DIV_UARTC", CAR_DEV_H_UARTC), 625 CLK_GATE_U("UARTD", "DIV_UARTD", CAR_DEV_U_UARTD), 626 CLK_GATE_L("SDMMC1", "DIV_SDMMC1", CAR_DEV_L_SDMMC1), 627 CLK_GATE_L("SDMMC2", "DIV_SDMMC2", CAR_DEV_L_SDMMC2), 628 CLK_GATE_U("SDMMC3", "DIV_SDMMC3", CAR_DEV_U_SDMMC3), 629 CLK_GATE_L("SDMMC4", "DIV_SDMMC4", CAR_DEV_L_SDMMC4), 630 CLK_GATE_L("I2C1", "DIV_I2C1", CAR_DEV_L_I2C1), 631 CLK_GATE_H("I2C2", "DIV_I2C2", CAR_DEV_H_I2C2), 632 CLK_GATE_U("I2C3", "DIV_I2C3", CAR_DEV_U_I2C3), 633 CLK_GATE_V("I2C4", "DIV_I2C4", CAR_DEV_V_I2C4), 634 CLK_GATE_H("I2C5", "DIV_I2C5", CAR_DEV_H_I2C5), 635 CLK_GATE_X("I2C6", "DIV_I2C6", CAR_DEV_X_I2C6), 636 CLK_GATE_W("XUSB_GATE", "CLK_M", CAR_DEV_W_XUSB), 637 CLK_GATE_U("XUSB_HOST", "XUSB_HOST_SRC", CAR_DEV_U_XUSB_HOST), 638 CLK_GATE_W("XUSB_SS", "XUSB_SS_SRC", CAR_DEV_W_XUSB_SS), 639 CLK_GATE_H("FUSE", "CLK_M", CAR_DEV_H_FUSE), 640 CLK_GATE_Y("USB2_TRK", "USB2_HSIC_TRK", CAR_DEV_Y_USB2_TRK), 641 CLK_GATE_Y("HSIC_TRK", "USB2_HSIC_TRK", CAR_DEV_Y_HSIC_TRK), 642 CLK_GATE_H("APBDMA", "CLK_M", CAR_DEV_H_APBDMA), 643 CLK_GATE_L("USBD", "PLL_U_480M", CAR_DEV_L_USBD), 644 CLK_GATE_H("USB2", "PLL_U_480M", CAR_DEV_H_USB2), 645 CLK_GATE_V("MSELECT", "DIV_MSELECT", CAR_DEV_V_MSELECT), 646 CLK_GATE_U("PCIE", "CLK_M", CAR_DEV_U_PCIE), 647 CLK_GATE_U("AFI", "MSELECT", CAR_DEV_U_AFI), 648 CLK_GATE_V("TSENSOR", "DIV_TSENSOR", CAR_DEV_V_TSENSOR), 649 CLK_GATE_U("SOC_THERM", "DIV_SOC_THERM", CAR_DEV_U_SOC_THERM), 650 CLK_GATE_W("HDA2HDMI", "CLK_M", CAR_DEV_W_HDA2HDMICODEC), 651 CLK_GATE_V("HDA2CODEC_2X", "DIV_HDA2CODEC_2X", CAR_DEV_V_HDA2CODEC_2X), 652 CLK_GATE_V("HDA", "DIV_HDA", CAR_DEV_V_HDA), 653 654 CLK_GATE_V("SATA_OOB", "DIV_SATA_OOB", CAR_DEV_V_SATA_OOB), 655 CLK_GATE_V("SATA", "DIV_SATA", CAR_DEV_V_SATA), 656 }; 657 658 struct tegra210_init_parent { 659 const char *clock; 660 const char *parent; 661 u_int rate; 662 u_int enable; 663 } tegra210_init_parents[] = { 664 { "SDMMC1", "PLL_P", 0, 0 }, 665 { "SDMMC2", "PLL_P", 0, 0 }, 666 { "SDMMC3", "PLL_P", 0, 0 }, 667 { "SDMMC4", "PLL_P", 0, 0 }, 668 { "SOC_THERM", "PLL_P", 0, 0 }, 669 { "TSENSOR", "CLK_M", 0, 0 }, 670 { "XUSB_GATE", NULL, 0, 1 }, 671 { "XUSB_HOST_SRC", "PLL_P", 102000000, 0 }, 672 { "XUSB_FALCON_SRC", "PLL_P", 204000000, 0 }, 673 { "XUSB_SS_SRC", "PLL_U_480M", 120000000, 0 }, 674 { "XUSB_FS_SRC", "PLL_U_48M", 48000000, 0 }, 675 { "PLL_U_OUT1", NULL, 48000000, 1 }, 676 { "PLL_U_OUT2", NULL, 60000000, 1 }, 677 { "CML0", NULL, 0, 1 }, 678 { "CML1", NULL, 0, 0 }, 679 { "AFI", NULL, 0, 1 }, 680 { "PCIE", NULL, 0, 1 }, 681 { "SATA", "PLL_P", 104000000, 0 }, 682 { "SATA_OOB", "PLL_P", 204000000, 0 }, 683 }; 684 685 struct tegra210_car_rst { 686 u_int set_reg; 687 u_int clr_reg; 688 u_int mask; 689 }; 690 691 static struct tegra210_car_reset_reg { 692 u_int set_reg; 693 u_int clr_reg; 694 } tegra210_car_reset_regs[] = { 695 { CAR_RST_DEV_L_SET_REG, CAR_RST_DEV_L_CLR_REG }, 696 { CAR_RST_DEV_H_SET_REG, CAR_RST_DEV_H_CLR_REG }, 697 { CAR_RST_DEV_U_SET_REG, CAR_RST_DEV_U_CLR_REG }, 698 { CAR_RST_DEV_V_SET_REG, CAR_RST_DEV_V_CLR_REG }, 699 { CAR_RST_DEV_W_SET_REG, CAR_RST_DEV_W_CLR_REG }, 700 { CAR_RST_DEV_X_SET_REG, CAR_RST_DEV_X_CLR_REG }, 701 { CAR_RST_DEV_Y_SET_REG, CAR_RST_DEV_Y_CLR_REG }, 702 }; 703 704 static void * tegra210_car_reset_acquire(device_t, const void *, size_t); 705 static void tegra210_car_reset_release(device_t, void *); 706 static int tegra210_car_reset_assert(device_t, void *); 707 static int tegra210_car_reset_deassert(device_t, void *); 708 709 static const struct fdtbus_reset_controller_func tegra210_car_fdtreset_funcs = { 710 .acquire = tegra210_car_reset_acquire, 711 .release = tegra210_car_reset_release, 712 .reset_assert = tegra210_car_reset_assert, 713 .reset_deassert = tegra210_car_reset_deassert, 714 }; 715 716 struct tegra210_car_softc { 717 device_t sc_dev; 718 bus_space_tag_t sc_bst; 719 bus_space_handle_t sc_bsh; 720 721 struct clk_domain sc_clkdom; 722 723 u_int sc_clock_cells; 724 u_int sc_reset_cells; 725 726 kmutex_t sc_rndlock; 727 krndsource_t sc_rndsource; 728 }; 729 730 static void tegra210_car_init(struct tegra210_car_softc *); 731 static void tegra210_car_utmip_init(struct tegra210_car_softc *); 732 static void tegra210_car_xusb_init(struct tegra210_car_softc *); 733 static void tegra210_car_watchdog_init(struct tegra210_car_softc *); 734 static void tegra210_car_parent_init(struct tegra210_car_softc *); 735 736 737 CFATTACH_DECL_NEW(tegra210_car, sizeof(struct tegra210_car_softc), 738 tegra210_car_match, tegra210_car_attach, NULL, NULL); 739 740 static const struct device_compatible_entry compat_data[] = { 741 { .compat = "nvidia,tegra210-car" }, 742 DEVICE_COMPAT_EOL 743 }; 744 745 static int 746 tegra210_car_match(device_t parent, cfdata_t cf, void *aux) 747 { 748 struct fdt_attach_args * const faa = aux; 749 750 #if 0 751 return of_compatible_match(faa->faa_phandle, compat_data); 752 #else 753 return of_compatible_match(faa->faa_phandle, compat_data) ? 999 : 0; 754 #endif 755 } 756 757 static void 758 tegra210_car_attach(device_t parent, device_t self, void *aux) 759 { 760 struct tegra210_car_softc * const sc = device_private(self); 761 struct fdt_attach_args * const faa = aux; 762 const int phandle = faa->faa_phandle; 763 bus_addr_t addr; 764 bus_size_t size; 765 int error, n; 766 767 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 768 aprint_error(": couldn't get registers\n"); 769 return; 770 } 771 772 sc->sc_dev = self; 773 sc->sc_bst = faa->faa_bst; 774 error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); 775 if (error) { 776 aprint_error(": couldn't map %#" PRIxBUSADDR ": %d", addr, error); 777 return; 778 } 779 if (of_getprop_uint32(phandle, "#clock-cells", &sc->sc_clock_cells)) 780 sc->sc_clock_cells = 1; 781 if (of_getprop_uint32(phandle, "#reset-cells", &sc->sc_reset_cells)) 782 sc->sc_reset_cells = 1; 783 784 aprint_naive("\n"); 785 aprint_normal(": CAR\n"); 786 787 sc->sc_clkdom.name = device_xname(self); 788 sc->sc_clkdom.funcs = &tegra210_car_clock_funcs; 789 sc->sc_clkdom.priv = sc; 790 for (n = 0; n < __arraycount(tegra210_car_clocks); n++) { 791 tegra210_car_clocks[n].base.domain = &sc->sc_clkdom; 792 clk_attach(&tegra210_car_clocks[n].base); 793 } 794 795 fdtbus_register_clock_controller(self, phandle, 796 &tegra210_car_fdtclock_funcs); 797 fdtbus_register_reset_controller(self, phandle, 798 &tegra210_car_fdtreset_funcs); 799 800 tegra210_car_init(sc); 801 802 #ifdef TEGRA210_CAR_DEBUG 803 for (n = 0; n < __arraycount(tegra210_car_clocks); n++) { 804 struct clk *clk = TEGRA_CLK_BASE(&tegra210_car_clocks[n]); 805 struct clk *clk_parent = clk_get_parent(clk); 806 device_printf(self, "clk %s (parent %s): ", clk->name, 807 clk_parent ? clk_parent->name : "none"); 808 printf("%u Hz\n", clk_get_rate(clk)); 809 } 810 #endif 811 } 812 813 static void 814 tegra210_car_init(struct tegra210_car_softc *sc) 815 { 816 tegra210_car_parent_init(sc); 817 tegra210_car_utmip_init(sc); 818 tegra210_car_xusb_init(sc); 819 tegra210_car_watchdog_init(sc); 820 } 821 822 static void 823 tegra210_car_parent_init(struct tegra210_car_softc *sc) 824 { 825 struct clk *clk, *clk_parent; 826 int error; 827 u_int n; 828 829 for (n = 0; n < __arraycount(tegra210_init_parents); n++) { 830 clk = clk_get(&sc->sc_clkdom, tegra210_init_parents[n].clock); 831 KASSERTMSG(clk != NULL, "tegra210 clock %s not found", tegra210_init_parents[n].clock); 832 833 if (tegra210_init_parents[n].parent != NULL) { 834 clk_parent = clk_get(&sc->sc_clkdom, 835 tegra210_init_parents[n].parent); 836 KASSERT(clk_parent != NULL); 837 838 error = clk_set_parent(clk, clk_parent); 839 if (error) { 840 aprint_error_dev(sc->sc_dev, 841 "couldn't set '%s' parent to '%s': %d\n", 842 clk->name, clk_parent->name, error); 843 } 844 clk_put(clk_parent); 845 } 846 if (tegra210_init_parents[n].rate != 0) { 847 error = clk_set_rate(clk, tegra210_init_parents[n].rate); 848 if (error) { 849 aprint_error_dev(sc->sc_dev, 850 "couldn't set '%s' rate to %u Hz: %d\n", 851 clk->name, tegra210_init_parents[n].rate, 852 error); 853 } 854 } 855 if (tegra210_init_parents[n].enable) { 856 error = clk_enable(clk); 857 if (error) { 858 aprint_error_dev(sc->sc_dev, 859 "couldn't enable '%s': %d\n", clk->name, 860 error); 861 } 862 } 863 clk_put(clk); 864 } 865 } 866 867 static void 868 tegra210_car_utmip_init(struct tegra210_car_softc *sc) 869 { 870 bus_space_tag_t bst = sc->sc_bst; 871 bus_space_handle_t bsh = sc->sc_bsh; 872 873 /* 874 * Set up the UTMI PLL. 875 */ 876 tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG3_REG, 877 0, CAR_UTMIP_PLL_CFG3_REF_SRC_SEL); 878 tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG3_REG, 879 0, CAR_UTMIP_PLL_CFG3_REF_DIS); 880 tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG, 881 0, CAR_UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE); 882 delay(10); 883 /* TODO UTMIP_PLL_CFG0 */ 884 tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG, 885 CAR_UTMIP_PLL_CFG2_PHY_XTAL_CLOCKEN, 0); 886 tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG, 887 0, CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT); /* Don't care */ 888 tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG, 889 0, CAR_UTMIP_PLL_CFG2_STABLE_COUNT); 890 tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG, 891 0, CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT); 892 tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG, 893 0x3, CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT); 894 895 bus_space_write_4(bst, bsh, CAR_CLK_ENB_U_SET_REG, CAR_DEV_U_AFI); 896 bus_space_write_4(bst, bsh, CAR_CLK_ENB_U_SET_REG, CAR_DEV_U_PCIE); 897 898 bus_space_write_4(bst, bsh, CAR_RST_DEV_L_CLR_REG, CAR_DEV_L_USBD); 899 bus_space_write_4(bst, bsh, CAR_RST_DEV_H_CLR_REG, CAR_DEV_H_USB2); 900 bus_space_write_4(bst, bsh, CAR_RST_DEV_W_CLR_REG, CAR_DEV_W_XUSB); 901 bus_space_write_4(bst, bsh, CAR_RST_DEV_U_CLR_REG, CAR_DEV_U_AFI); 902 bus_space_write_4(bst, bsh, CAR_RST_DEV_U_CLR_REG, CAR_DEV_U_PCIE); 903 bus_space_write_4(bst, bsh, CAR_RST_DEV_U_CLR_REG, CAR_DEV_U_PCIEXCLK); 904 bus_space_write_4(bst, bsh, CAR_RST_DEV_Y_CLR_REG, CAR_DEV_Y_PEX_USB_UPHY); 905 bus_space_write_4(bst, bsh, CAR_RST_DEV_Y_CLR_REG, CAR_DEV_Y_SATA_USB_UPHY); 906 907 tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG, 908 CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERUP | 909 CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERUP | 910 CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERUP, 911 CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERDOWN | 912 CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERDOWN | 913 CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERDOWN); 914 915 /* 916 * Set up UTMI PLL under hardware control 917 */ 918 tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG, 0, 919 CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERUP | CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERDOWN); 920 tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG, 921 0, CAR_UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL); 922 tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG, 923 CAR_UTMIPLL_HW_PWRDN_CFG0_IDDQ_PD_INCLUDE, 0); 924 tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG, 925 0, CAR_UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL); 926 tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG, 927 CAR_UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET, 0); 928 tegra_reg_set_clear(bst, bsh, CLK_RST_CONTROLLER_XUSB_PLL_CFG0_REG, 929 0, CLK_RST_CONTROLLER_XUSB_PLL_CFG0_UTMIPLL_LOCK_DLY); 930 delay(1); 931 tegra_reg_set_clear(bst, bsh, CAR_UTMIPLL_HW_PWRDN_CFG0_REG, 932 CAR_UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE, 0); 933 } 934 935 static void 936 tegra210_car_xusb_init(struct tegra210_car_softc *sc) 937 { 938 const bus_space_tag_t bst = sc->sc_bst; 939 const bus_space_handle_t bsh = sc->sc_bsh; 940 uint32_t val; 941 942 /* 943 * Set up the PLLU. 944 */ 945 tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG, CAR_PLLU_BASE_OVERRIDE, 0); 946 tegra_reg_set_clear(bst, bsh, CAR_PLLU_MISC_REG, CAR_PLLU_MISC_IDDQ, 0); 947 tegra_reg_set_clear(bst, bsh, CAR_PLLU_MISC_REG, 0, CAR_PLLU_MISC_IDDQ); 948 tegra_reg_set_clear(bst, bsh, CAR_PLLU_OUTA_REG, 0, CAR_PLLU_OUTA_OUT1_RSTN); 949 tegra_reg_set_clear(bst, bsh, CAR_PLLU_OUTA_REG, 0, CAR_PLLU_OUTA_OUT2_RSTN); 950 delay(5); 951 tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG, 952 __SHIFTIN(0x19, CAR_PLLU_BASE_DIVN) | 953 __SHIFTIN(0x2, CAR_PLLU_BASE_DIVM) | 954 __SHIFTIN(0x1, CAR_PLLU_BASE_DIVP), 955 CAR_PLLU_BASE_DIVN | CAR_PLLU_BASE_DIVM | CAR_PLLU_BASE_DIVP); 956 tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG, CAR_PLLU_BASE_ENABLE, 0); 957 do { 958 delay(2); 959 val = bus_space_read_4(bst, bsh, CAR_PLLU_BASE_REG); 960 } while ((val & CAR_PLLU_BASE_LOCK) == 0); 961 tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG, CAR_PLLU_BASE_CLKENABLE_ICUSB, 0); 962 tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG, CAR_PLLU_BASE_CLKENABLE_HSIC, 0); 963 tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG, CAR_PLLU_BASE_CLKENABLE_USB, 0); 964 tegra_reg_set_clear(bst, bsh, CAR_PLLU_OUTA_REG, CAR_PLLU_OUTA_OUT1_RSTN, 0); 965 tegra_reg_set_clear(bst, bsh, CAR_PLLU_OUTA_REG, CAR_PLLU_OUTA_OUT2_RSTN, 0); 966 delay(2); 967 968 /* 969 * Now switch PLLU to hw controlled mode. 970 */ 971 tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG, 0, CAR_PLLU_BASE_OVERRIDE); 972 tegra_reg_set_clear(bst, bsh, CLK_RST_CONTROLLER_PLLU_HW_PWRDN_CFG0_REG, 973 CLK_RST_CONTROLLER_PLLU_HW_PWRDN_CFG0_IDDQ_PD_INCLUDE | 974 CLK_RST_CONTROLLER_PLLU_HW_PWRDN_CFG0_USE_SWITCH_DETECT | 975 CLK_RST_CONTROLLER_PLLU_HW_PWRDN_CFG0_USE_LOCKDET, 976 CLK_RST_CONTROLLER_PLLU_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL | 977 CLK_RST_CONTROLLER_PLLU_HW_PWRDN_CFG0_CLK_SWITCH_SWCTL); 978 tegra_reg_set_clear(bst, bsh, CLK_RST_CONTROLLER_XUSB_PLL_CFG0_REG, 0, 979 CLK_RST_CONTROLLER_XUSB_PLL_CFG0_PLLU_LOCK_DLY); 980 delay(1); 981 tegra_reg_set_clear(bst, bsh, CLK_RST_CONTROLLER_PLLU_HW_PWRDN_CFG0_REG, 982 CLK_RST_CONTROLLER_PLLU_HW_PWRDN_CFG0_SEQ_ENABLE, 0); 983 delay(1); 984 tegra_reg_set_clear(bst, bsh, CAR_PLLU_BASE_REG, 0, CAR_PLLU_BASE_CLKENABLE_USB); 985 986 /* 987 * Set up PLLREFE 988 */ 989 tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_MISC_REG, 990 0, CAR_PLLREFE_MISC_IDDQ); 991 delay(5); 992 tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_BASE_REG, 993 __SHIFTIN(0x4, CAR_PLLREFE_BASE_DIVM) | 994 __SHIFTIN(0x41, CAR_PLLREFE_BASE_DIVN) | 995 __SHIFTIN(0x0, CAR_PLLREFE_BASE_DIVP) | 996 __SHIFTIN(0x0, CAR_PLLREFE_BASE_KCP), 997 CAR_PLLREFE_BASE_DIVM | 998 CAR_PLLREFE_BASE_DIVN | 999 CAR_PLLREFE_BASE_DIVP | 1000 CAR_PLLREFE_BASE_KCP); 1001 tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_BASE_REG, 1002 CAR_PLLREFE_BASE_ENABLE, 0); 1003 do { 1004 delay(2); 1005 val = bus_space_read_4(bst, bsh, CAR_PLLREFE_MISC_REG); 1006 } while ((val & CAR_PLLREFE_MISC_LOCK) == 0); 1007 1008 /* 1009 * Set up the PLLE. 1010 */ 1011 tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, 0, CAR_PLLE_AUX_REF_SEL_PLLREFE); 1012 tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, 0, CAR_PLLE_AUX_REF_SRC); 1013 tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG, 0, CAR_PLLE_MISC_IDDQ_OVERRIDE); 1014 delay(5); 1015 tegra_reg_set_clear(bst, bsh, CAR_PLLE_BASE_REG, 1016 __SHIFTIN(0xe, CAR_PLLE_BASE_DIVP_CML) | 1017 __SHIFTIN(0x7d, CAR_PLLE_BASE_DIVN) | 1018 __SHIFTIN(0x2, CAR_PLLE_BASE_DIVM), 1019 CAR_PLLE_BASE_DIVP_CML | 1020 CAR_PLLE_BASE_DIVN | 1021 CAR_PLLE_BASE_DIVM); 1022 tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG, 1023 CAR_PLLE_MISC_PTS, 1024 CAR_PLLE_MISC_KCP | CAR_PLLE_MISC_VREG_CTRL | CAR_PLLE_MISC_KVCO); 1025 tegra_reg_set_clear(bst, bsh, CAR_PLLE_BASE_REG, CAR_PLLE_BASE_ENABLE, 0); 1026 do { 1027 delay(2); 1028 val = bus_space_read_4(bst, bsh, CAR_PLLE_MISC_REG); 1029 } while ((val & CAR_PLLE_MISC_LOCK) == 0); 1030 tegra_reg_set_clear(bst, bsh, CAR_PLLE_SS_CNTL_REG, 1031 __SHIFTIN(1, CAR_PLLE_SS_CNTL_SSCINC) | 1032 __SHIFTIN(0x23, CAR_PLLE_SS_CNTL_SSCINCINTRV) | 1033 __SHIFTIN(0x21, CAR_PLLE_SS_CNTL_SSCMAX), 1034 CAR_PLLE_SS_CNTL_SSCINC | 1035 CAR_PLLE_SS_CNTL_SSCINCINTRV | 1036 CAR_PLLE_SS_CNTL_SSCMAX | 1037 CAR_PLLE_SS_CNTL_SSCINVERT | 1038 CAR_PLLE_SS_CNTL_SSCCENTER | 1039 CAR_PLLE_SS_CNTL_BYPASS_SS | 1040 CAR_PLLE_SS_CNTL_SSCBYP); 1041 delay(1); 1042 tegra_reg_set_clear(bst, bsh, CAR_PLLE_SS_CNTL_REG, 0, CAR_PLLE_SS_CNTL_INTERP_RESET); 1043 tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG, 0, CAR_PLLE_MISC_IDDQ_SWCTL); 1044 tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, 0, CAR_PLLE_AUX_SS_SWCTL); 1045 tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, 0, CAR_PLLE_AUX_ENABLE_SWCTL); 1046 tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, CAR_PLLE_AUX_SS_SEQ_INCLUDE, 0); 1047 tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, CAR_PLLE_AUX_USE_LOCKDET, 0); 1048 delay(1); 1049 tegra_reg_set_clear(bst, bsh, CAR_PLLE_AUX_REG, CAR_PLLE_AUX_SEQ_ENABLE, 0); 1050 1051 bus_space_write_4(bst, bsh, CAR_CLK_ENB_W_SET_REG, CAR_DEV_W_XUSB); 1052 bus_space_write_4(bst, bsh, CAR_CLK_ENB_W_SET_REG, CAR_DEV_W_XUSB_PADCTL); 1053 } 1054 1055 static void 1056 tegra210_car_watchdog_init(struct tegra210_car_softc *sc) 1057 { 1058 const bus_space_tag_t bst = sc->sc_bst; 1059 const bus_space_handle_t bsh = sc->sc_bsh; 1060 1061 /* Enable watchdog timer reset for system */ 1062 tegra_reg_set_clear(bst, bsh, CAR_RST_SOURCE_REG, 1063 CAR_RST_SOURCE_WDT_EN|CAR_RST_SOURCE_WDT_SYS_RST_EN, 0); 1064 } 1065 1066 static struct tegra_clk * 1067 tegra210_car_clock_find(const char *name) 1068 { 1069 u_int n; 1070 1071 for (n = 0; n < __arraycount(tegra210_car_clocks); n++) { 1072 if (strcmp(tegra210_car_clocks[n].base.name, name) == 0) { 1073 return &tegra210_car_clocks[n]; 1074 } 1075 } 1076 1077 return NULL; 1078 } 1079 1080 static struct tegra_clk * 1081 tegra210_car_clock_find_by_id(u_int clock_id) 1082 { 1083 u_int n; 1084 1085 for (n = 0; n < __arraycount(tegra210_car_clock_ids); n++) { 1086 if (tegra210_car_clock_ids[n].id == clock_id) { 1087 const char *name = tegra210_car_clock_ids[n].name; 1088 return tegra210_car_clock_find(name); 1089 } 1090 } 1091 1092 return NULL; 1093 } 1094 1095 static struct clk * 1096 tegra210_car_clock_decode(device_t dev, int cc_phandle, const void *data, 1097 size_t len) 1098 { 1099 struct tegra210_car_softc * const sc = device_private(dev); 1100 struct tegra_clk *tclk; 1101 1102 if (len != sc->sc_clock_cells * 4) { 1103 return NULL; 1104 } 1105 1106 const u_int clock_id = be32dec(data); 1107 1108 tclk = tegra210_car_clock_find_by_id(clock_id); 1109 if (tclk) 1110 return TEGRA_CLK_BASE(tclk); 1111 1112 return NULL; 1113 } 1114 1115 static struct clk * 1116 tegra210_car_clock_get(void *priv, const char *name) 1117 { 1118 struct tegra_clk *tclk; 1119 1120 tclk = tegra210_car_clock_find(name); 1121 if (tclk == NULL) 1122 return NULL; 1123 1124 atomic_inc_uint(&tclk->refcnt); 1125 1126 return TEGRA_CLK_BASE(tclk); 1127 } 1128 1129 static void 1130 tegra210_car_clock_put(void *priv, struct clk *clk) 1131 { 1132 struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); 1133 1134 KASSERT(tclk->refcnt > 0); 1135 1136 atomic_dec_uint(&tclk->refcnt); 1137 } 1138 1139 static u_int 1140 tegra210_car_clock_get_rate_pll(struct tegra210_car_softc *sc, 1141 struct tegra_clk *tclk) 1142 { 1143 struct tegra_pll_clk *tpll = &tclk->u.pll; 1144 struct tegra_clk *tclk_parent; 1145 bus_space_tag_t bst = sc->sc_bst; 1146 bus_space_handle_t bsh = sc->sc_bsh; 1147 u_int divm, divn, divp; 1148 uint64_t rate; 1149 1150 KASSERT(tclk->type == TEGRA_CLK_PLL); 1151 1152 tclk_parent = tegra210_car_clock_find(tclk->parent); 1153 KASSERT(tclk_parent != NULL); 1154 1155 const u_int rate_parent = tegra210_car_clock_get_rate(sc, 1156 TEGRA_CLK_BASE(tclk_parent)); 1157 1158 const uint32_t base = bus_space_read_4(bst, bsh, tpll->base_reg); 1159 divm = __SHIFTOUT(base, tpll->divm_mask); 1160 divn = __SHIFTOUT(base, tpll->divn_mask); 1161 if (tpll->base_reg == CAR_PLLU_BASE_REG) { 1162 divp = __SHIFTOUT(base, tpll->divp_mask) ? 0 : 1; 1163 } else if (tpll->base_reg == CAR_PLLP_BASE_REG) { 1164 /* XXX divp is not applied to PLLP's primary output */ 1165 divp = 0; 1166 } else if (tpll->base_reg == CAR_PLLE_BASE_REG) { 1167 divp = 0; 1168 divm *= __SHIFTOUT(base, tpll->divp_mask); 1169 } else { 1170 divp = __SHIFTOUT(base, tpll->divp_mask); 1171 } 1172 1173 rate = (uint64_t)rate_parent * divn; 1174 return rate / (divm << divp); 1175 } 1176 1177 static int 1178 tegra210_car_clock_set_rate_pll(struct tegra210_car_softc *sc, 1179 struct tegra_clk *tclk, u_int rate) 1180 { 1181 struct tegra_pll_clk *tpll = &tclk->u.pll; 1182 bus_space_tag_t bst = sc->sc_bst; 1183 bus_space_handle_t bsh = sc->sc_bsh; 1184 struct clk *clk_parent; 1185 uint32_t bp, base; 1186 1187 clk_parent = tegra210_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk)); 1188 if (clk_parent == NULL) 1189 return EIO; 1190 const u_int rate_parent = tegra210_car_clock_get_rate(sc, clk_parent); 1191 if (rate_parent == 0) 1192 return EIO; 1193 1194 if (tpll->base_reg == CAR_PLLX_BASE_REG) { 1195 const u_int divm = 1; 1196 const u_int divn = rate / rate_parent; 1197 const u_int divp = 0; 1198 1199 bp = bus_space_read_4(bst, bsh, CAR_CCLKG_BURST_POLICY_REG); 1200 bp &= ~CAR_CCLKG_BURST_POLICY_CPU_STATE; 1201 bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CPU_STATE_IDLE, 1202 CAR_CCLKG_BURST_POLICY_CPU_STATE); 1203 bp &= ~CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE; 1204 bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_CLKM, 1205 CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE); 1206 bus_space_write_4(bst, bsh, CAR_CCLKG_BURST_POLICY_REG, bp); 1207 1208 base = bus_space_read_4(bst, bsh, CAR_PLLX_BASE_REG); 1209 base &= ~CAR_PLLX_BASE_DIVM; 1210 base &= ~CAR_PLLX_BASE_DIVN; 1211 base &= ~CAR_PLLX_BASE_DIVP; 1212 base |= __SHIFTIN(divm, CAR_PLLX_BASE_DIVM); 1213 base |= __SHIFTIN(divn, CAR_PLLX_BASE_DIVN); 1214 base |= __SHIFTIN(divp, CAR_PLLX_BASE_DIVP); 1215 bus_space_write_4(bst, bsh, CAR_PLLX_BASE_REG, base); 1216 1217 tegra_reg_set_clear(bst, bsh, CAR_PLLX_MISC_REG, 1218 CAR_PLLX_MISC_LOCK_ENABLE, 0); 1219 do { 1220 delay(2); 1221 base = bus_space_read_4(bst, bsh, tpll->base_reg); 1222 } while ((base & CAR_PLLX_BASE_LOCK) == 0); 1223 delay(100); 1224 1225 bp &= ~CAR_CCLKG_BURST_POLICY_CPU_STATE; 1226 bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CPU_STATE_RUN, 1227 CAR_CCLKG_BURST_POLICY_CPU_STATE); 1228 bp &= ~CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE; 1229 bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_PLLX_OUT0_LJ, 1230 CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE); 1231 bus_space_write_4(bst, bsh, CAR_CCLKG_BURST_POLICY_REG, bp); 1232 1233 return 0; 1234 } else if (tpll->base_reg == CAR_PLLD2_BASE_REG) { 1235 const u_int divm = 1; 1236 const u_int pldiv = 1; 1237 const u_int divn = (rate << pldiv) / rate_parent; 1238 1239 /* Set frequency */ 1240 tegra_reg_set_clear(bst, bsh, tpll->base_reg, 1241 __SHIFTIN(divm, CAR_PLLD2_BASE_DIVM) | 1242 __SHIFTIN(divn, CAR_PLLD2_BASE_DIVN) | 1243 __SHIFTIN(pldiv, CAR_PLLD2_BASE_DIVP), 1244 CAR_PLLD2_BASE_REF_SRC_SEL | 1245 CAR_PLLD2_BASE_DIVM | 1246 CAR_PLLD2_BASE_DIVN | 1247 CAR_PLLD2_BASE_DIVP); 1248 1249 return 0; 1250 } else { 1251 aprint_error_dev(sc->sc_dev, "failed to set %s rate to %u\n", 1252 tclk->base.name, rate); 1253 /* TODO */ 1254 return EOPNOTSUPP; 1255 } 1256 } 1257 1258 static int 1259 tegra210_car_clock_set_parent_mux(struct tegra210_car_softc *sc, 1260 struct tegra_clk *tclk, struct tegra_clk *tclk_parent) 1261 { 1262 struct tegra_mux_clk *tmux = &tclk->u.mux; 1263 bus_space_tag_t bst = sc->sc_bst; 1264 bus_space_handle_t bsh = sc->sc_bsh; 1265 uint32_t v; 1266 u_int src; 1267 1268 KASSERT(tclk->type == TEGRA_CLK_MUX); 1269 1270 for (src = 0; src < tmux->nparents; src++) { 1271 if (tmux->parents[src] == NULL) { 1272 continue; 1273 } 1274 if (strcmp(tmux->parents[src], tclk_parent->base.name) == 0) { 1275 break; 1276 } 1277 } 1278 if (src == tmux->nparents) { 1279 return EINVAL; 1280 } 1281 1282 v = bus_space_read_4(bst, bsh, tmux->reg); 1283 v &= ~tmux->bits; 1284 v |= __SHIFTIN(src, tmux->bits); 1285 bus_space_write_4(bst, bsh, tmux->reg, v); 1286 1287 return 0; 1288 } 1289 1290 static struct tegra_clk * 1291 tegra210_car_clock_get_parent_mux(struct tegra210_car_softc *sc, 1292 struct tegra_clk *tclk) 1293 { 1294 struct tegra_mux_clk *tmux = &tclk->u.mux; 1295 bus_space_tag_t bst = sc->sc_bst; 1296 bus_space_handle_t bsh = sc->sc_bsh; 1297 1298 KASSERT(tclk->type == TEGRA_CLK_MUX); 1299 1300 const uint32_t v = bus_space_read_4(bst, bsh, tmux->reg); 1301 const u_int src = __SHIFTOUT(v, tmux->bits); 1302 1303 KASSERT(src < tmux->nparents); 1304 1305 if (tmux->parents[src] == NULL) { 1306 return NULL; 1307 } 1308 1309 return tegra210_car_clock_find(tmux->parents[src]); 1310 } 1311 1312 static u_int 1313 tegra210_car_clock_get_rate_fixed_div(struct tegra210_car_softc *sc, 1314 struct tegra_clk *tclk) 1315 { 1316 struct tegra_fixed_div_clk *tfixed_div = &tclk->u.fixed_div; 1317 struct clk *clk_parent; 1318 1319 clk_parent = tegra210_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk)); 1320 if (clk_parent == NULL) 1321 return 0; 1322 const u_int parent_rate = tegra210_car_clock_get_rate(sc, clk_parent); 1323 1324 return parent_rate / tfixed_div->div; 1325 } 1326 1327 static u_int 1328 tegra210_car_clock_get_rate_div(struct tegra210_car_softc *sc, 1329 struct tegra_clk *tclk) 1330 { 1331 struct tegra_div_clk *tdiv = &tclk->u.div; 1332 bus_space_tag_t bst = sc->sc_bst; 1333 bus_space_handle_t bsh = sc->sc_bsh; 1334 struct clk *clk_parent; 1335 u_int rate; 1336 1337 KASSERT(tclk->type == TEGRA_CLK_DIV); 1338 1339 clk_parent = tegra210_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk)); 1340 const u_int parent_rate = tegra210_car_clock_get_rate(sc, clk_parent); 1341 1342 const uint32_t v = bus_space_read_4(bst, bsh, tdiv->reg); 1343 u_int raw_div = __SHIFTOUT(v, tdiv->bits); 1344 1345 switch (tdiv->reg) { 1346 case CAR_CLKSRC_I2C1_REG: 1347 case CAR_CLKSRC_I2C2_REG: 1348 case CAR_CLKSRC_I2C3_REG: 1349 case CAR_CLKSRC_I2C4_REG: 1350 case CAR_CLKSRC_I2C5_REG: 1351 case CAR_CLKSRC_I2C6_REG: 1352 rate = parent_rate / (raw_div + 1); 1353 break; 1354 case CAR_CLKSRC_UARTA_REG: 1355 case CAR_CLKSRC_UARTB_REG: 1356 case CAR_CLKSRC_UARTC_REG: 1357 case CAR_CLKSRC_UARTD_REG: 1358 if (v & CAR_CLKSRC_UART_DIV_ENB) { 1359 rate = parent_rate / ((raw_div / 2) + 1); 1360 } else { 1361 rate = parent_rate; 1362 } 1363 break; 1364 case CAR_CLKSRC_SDMMC2_REG: 1365 case CAR_CLKSRC_SDMMC4_REG: 1366 switch (__SHIFTOUT(v, CAR_CLKSRC_SDMMC_SRC)) { 1367 case 1: 1368 case 2: 1369 case 5: 1370 raw_div = 0; /* ignore divisor for _LJ options */ 1371 break; 1372 } 1373 /* FALLTHROUGH */ 1374 default: 1375 rate = parent_rate / ((raw_div / 2) + 1); 1376 break; 1377 } 1378 1379 return rate; 1380 } 1381 1382 static int 1383 tegra210_car_clock_set_rate_div(struct tegra210_car_softc *sc, 1384 struct tegra_clk *tclk, u_int rate) 1385 { 1386 struct tegra_div_clk *tdiv = &tclk->u.div; 1387 bus_space_tag_t bst = sc->sc_bst; 1388 bus_space_handle_t bsh = sc->sc_bsh; 1389 struct clk *clk_parent; 1390 u_int raw_div; 1391 uint32_t v; 1392 1393 KASSERT(tclk->type == TEGRA_CLK_DIV); 1394 1395 clk_parent = tegra210_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk)); 1396 if (clk_parent == NULL) 1397 return EINVAL; 1398 const u_int parent_rate = tegra210_car_clock_get_rate(sc, clk_parent); 1399 1400 v = bus_space_read_4(bst, bsh, tdiv->reg); 1401 1402 raw_div = __SHIFTOUT(tdiv->bits, tdiv->bits); 1403 1404 switch (tdiv->reg) { 1405 case CAR_CLKSRC_UARTA_REG: 1406 case CAR_CLKSRC_UARTB_REG: 1407 case CAR_CLKSRC_UARTC_REG: 1408 case CAR_CLKSRC_UARTD_REG: 1409 if (rate == parent_rate) { 1410 v &= ~CAR_CLKSRC_UART_DIV_ENB; 1411 } else if (rate) { 1412 v |= CAR_CLKSRC_UART_DIV_ENB; 1413 raw_div = (parent_rate / rate) * 2; 1414 if (raw_div >= 2) 1415 raw_div -= 2; 1416 } 1417 break; 1418 case CAR_CLKSRC_I2C1_REG: 1419 case CAR_CLKSRC_I2C2_REG: 1420 case CAR_CLKSRC_I2C3_REG: 1421 case CAR_CLKSRC_I2C4_REG: 1422 case CAR_CLKSRC_I2C5_REG: 1423 case CAR_CLKSRC_I2C6_REG: 1424 if (rate) 1425 raw_div = (parent_rate / rate) - 1; 1426 break; 1427 case CAR_CLKSRC_SDMMC1_REG: 1428 case CAR_CLKSRC_SDMMC2_REG: 1429 case CAR_CLKSRC_SDMMC3_REG: 1430 case CAR_CLKSRC_SDMMC4_REG: 1431 if (rate) { 1432 for (raw_div = 0x00; raw_div <= 0xff; raw_div++) { 1433 u_int calc_rate = 1434 parent_rate / ((raw_div / 2) + 1); 1435 if (calc_rate <= rate) 1436 break; 1437 } 1438 if (raw_div == 0x100) 1439 return EINVAL; 1440 } 1441 break; 1442 default: 1443 if (rate) { 1444 raw_div = (parent_rate / rate) * 2; 1445 if (raw_div >= 2) 1446 raw_div -= 2; 1447 } 1448 break; 1449 } 1450 1451 v &= ~tdiv->bits; 1452 v |= __SHIFTIN(raw_div, tdiv->bits); 1453 1454 bus_space_write_4(bst, bsh, tdiv->reg, v); 1455 1456 return 0; 1457 } 1458 1459 static int 1460 tegra210_car_clock_enable_gate(struct tegra210_car_softc *sc, 1461 struct tegra_clk *tclk, bool enable) 1462 { 1463 struct tegra_gate_clk *tgate = &tclk->u.gate; 1464 bus_space_tag_t bst = sc->sc_bst; 1465 bus_space_handle_t bsh = sc->sc_bsh; 1466 bus_size_t reg; 1467 1468 KASSERT(tclk->type == TEGRA_CLK_GATE); 1469 1470 if (tgate->set_reg == tgate->clr_reg) { 1471 uint32_t v = bus_space_read_4(bst, bsh, tgate->set_reg); 1472 if (enable) { 1473 v |= tgate->bits; 1474 } else { 1475 v &= ~tgate->bits; 1476 } 1477 bus_space_write_4(bst, bsh, tgate->set_reg, v); 1478 } else { 1479 if (enable) { 1480 reg = tgate->set_reg; 1481 } else { 1482 reg = tgate->clr_reg; 1483 } 1484 bus_space_write_4(bst, bsh, reg, tgate->bits); 1485 } 1486 1487 return 0; 1488 } 1489 1490 static u_int 1491 tegra210_car_clock_get_rate(void *priv, struct clk *clk) 1492 { 1493 struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); 1494 struct clk *clk_parent; 1495 1496 switch (tclk->type) { 1497 case TEGRA_CLK_FIXED: 1498 return tclk->u.fixed.rate; 1499 case TEGRA_CLK_PLL: 1500 return tegra210_car_clock_get_rate_pll(priv, tclk); 1501 case TEGRA_CLK_MUX: 1502 case TEGRA_CLK_GATE: 1503 clk_parent = tegra210_car_clock_get_parent(priv, clk); 1504 if (clk_parent == NULL) 1505 return EINVAL; 1506 return tegra210_car_clock_get_rate(priv, clk_parent); 1507 case TEGRA_CLK_FIXED_DIV: 1508 return tegra210_car_clock_get_rate_fixed_div(priv, tclk); 1509 case TEGRA_CLK_DIV: 1510 return tegra210_car_clock_get_rate_div(priv, tclk); 1511 default: 1512 panic("tegra210: unknown tclk type %d", tclk->type); 1513 } 1514 } 1515 1516 static int 1517 tegra210_car_clock_set_rate(void *priv, struct clk *clk, u_int rate) 1518 { 1519 struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); 1520 struct clk *clk_parent; 1521 1522 KASSERT((clk->flags & CLK_SET_RATE_PARENT) == 0); 1523 1524 switch (tclk->type) { 1525 case TEGRA_CLK_FIXED: 1526 case TEGRA_CLK_MUX: 1527 return EIO; 1528 case TEGRA_CLK_FIXED_DIV: 1529 clk_parent = tegra210_car_clock_get_parent(priv, clk); 1530 if (clk_parent == NULL) 1531 return EIO; 1532 return tegra210_car_clock_set_rate(priv, clk_parent, 1533 rate * tclk->u.fixed_div.div); 1534 case TEGRA_CLK_GATE: 1535 return EINVAL; 1536 case TEGRA_CLK_PLL: 1537 return tegra210_car_clock_set_rate_pll(priv, tclk, rate); 1538 case TEGRA_CLK_DIV: 1539 return tegra210_car_clock_set_rate_div(priv, tclk, rate); 1540 default: 1541 panic("tegra210: unknown tclk type %d", tclk->type); 1542 } 1543 } 1544 1545 static int 1546 tegra210_car_clock_enable(void *priv, struct clk *clk) 1547 { 1548 struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); 1549 struct clk *clk_parent; 1550 1551 if (tclk->type != TEGRA_CLK_GATE) { 1552 clk_parent = tegra210_car_clock_get_parent(priv, clk); 1553 if (clk_parent == NULL) 1554 return 0; 1555 return tegra210_car_clock_enable(priv, clk_parent); 1556 } 1557 1558 return tegra210_car_clock_enable_gate(priv, tclk, true); 1559 } 1560 1561 static int 1562 tegra210_car_clock_disable(void *priv, struct clk *clk) 1563 { 1564 struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); 1565 1566 if (tclk->type != TEGRA_CLK_GATE) 1567 return EINVAL; 1568 1569 return tegra210_car_clock_enable_gate(priv, tclk, false); 1570 } 1571 1572 static int 1573 tegra210_car_clock_set_parent(void *priv, struct clk *clk, 1574 struct clk *clk_parent) 1575 { 1576 struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); 1577 struct tegra_clk *tclk_parent = TEGRA_CLK_PRIV(clk_parent); 1578 struct clk *nclk_parent; 1579 1580 if (tclk->type != TEGRA_CLK_MUX) { 1581 nclk_parent = tegra210_car_clock_get_parent(priv, clk); 1582 if (nclk_parent == clk_parent || nclk_parent == NULL) 1583 return EINVAL; 1584 return tegra210_car_clock_set_parent(priv, nclk_parent, 1585 clk_parent); 1586 } 1587 1588 return tegra210_car_clock_set_parent_mux(priv, tclk, tclk_parent); 1589 } 1590 1591 static struct clk * 1592 tegra210_car_clock_get_parent(void *priv, struct clk *clk) 1593 { 1594 struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); 1595 struct tegra_clk *tclk_parent = NULL; 1596 1597 switch (tclk->type) { 1598 case TEGRA_CLK_FIXED: 1599 case TEGRA_CLK_PLL: 1600 case TEGRA_CLK_FIXED_DIV: 1601 case TEGRA_CLK_DIV: 1602 case TEGRA_CLK_GATE: 1603 if (tclk->parent) { 1604 tclk_parent = tegra210_car_clock_find(tclk->parent); 1605 } 1606 break; 1607 case TEGRA_CLK_MUX: 1608 tclk_parent = tegra210_car_clock_get_parent_mux(priv, tclk); 1609 break; 1610 } 1611 1612 if (tclk_parent == NULL) 1613 return NULL; 1614 1615 return TEGRA_CLK_BASE(tclk_parent); 1616 } 1617 1618 static void * 1619 tegra210_car_reset_acquire(device_t dev, const void *data, size_t len) 1620 { 1621 struct tegra210_car_softc * const sc = device_private(dev); 1622 struct tegra210_car_rst *rst; 1623 1624 if (len != sc->sc_reset_cells * 4) 1625 return NULL; 1626 1627 const u_int reset_id = be32dec(data); 1628 1629 if (reset_id >= __arraycount(tegra210_car_reset_regs) * 32) 1630 return NULL; 1631 1632 const u_int reg = reset_id / 32; 1633 1634 rst = kmem_alloc(sizeof(*rst), KM_SLEEP); 1635 rst->set_reg = tegra210_car_reset_regs[reg].set_reg; 1636 rst->clr_reg = tegra210_car_reset_regs[reg].clr_reg; 1637 rst->mask = __BIT(reset_id % 32); 1638 1639 return rst; 1640 } 1641 1642 static void 1643 tegra210_car_reset_release(device_t dev, void *priv) 1644 { 1645 struct tegra210_car_rst *rst = priv; 1646 1647 kmem_free(rst, sizeof(*rst)); 1648 } 1649 1650 static int 1651 tegra210_car_reset_assert(device_t dev, void *priv) 1652 { 1653 struct tegra210_car_softc * const sc = device_private(dev); 1654 struct tegra210_car_rst *rst = priv; 1655 1656 bus_space_write_4(sc->sc_bst, sc->sc_bsh, rst->set_reg, rst->mask); 1657 1658 return 0; 1659 } 1660 1661 static int 1662 tegra210_car_reset_deassert(device_t dev, void *priv) 1663 { 1664 struct tegra210_car_softc * const sc = device_private(dev); 1665 struct tegra210_car_rst *rst = priv; 1666 1667 bus_space_write_4(sc->sc_bst, sc->sc_bsh, rst->clr_reg, rst->mask); 1668 1669 return 0; 1670 } 1671 1672 void 1673 tegra210_car_xusbio_enable_hw_control(void) 1674 { 1675 device_t dev = device_find_by_driver_unit("tegra210car", 0); 1676 KASSERT(dev != NULL); 1677 struct tegra210_car_softc * const sc = device_private(dev); 1678 bus_space_tag_t bst = sc->sc_bst; 1679 bus_space_handle_t bsh = sc->sc_bsh; 1680 1681 tegra_reg_set_clear(bst, bsh, CAR_XUSBIO_PLL_CFG0_REG, 1682 0, 1683 CAR_XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL | 1684 CAR_XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL); 1685 tegra_reg_set_clear(bst, bsh, CAR_XUSBIO_PLL_CFG0_REG, 1686 CAR_XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ | 1687 CAR_XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET, 1688 0); 1689 } 1690 1691 void 1692 tegra210_car_xusbio_enable_hw_seq(void) 1693 { 1694 device_t dev = device_find_by_driver_unit("tegra210car", 0); 1695 KASSERT(dev != NULL); 1696 struct tegra210_car_softc * const sc = device_private(dev); 1697 bus_space_tag_t bst = sc->sc_bst; 1698 bus_space_handle_t bsh = sc->sc_bsh; 1699 1700 tegra_reg_set_clear(bst, bsh, CAR_XUSBIO_PLL_CFG0_REG, 1701 CAR_XUSBIO_PLL_CFG0_SEQ_ENABLE, 0); 1702 } 1703 1704 void 1705 tegra210_car_sata_enable_hw_control(void) 1706 { 1707 device_t dev = device_find_by_driver_unit("tegra210car", 0); 1708 KASSERT(dev != NULL); 1709 struct tegra210_car_softc * const sc = device_private(dev); 1710 bus_space_tag_t bst = sc->sc_bst; 1711 bus_space_handle_t bsh = sc->sc_bsh; 1712 1713 tegra_reg_set_clear(bst, bsh, CAR_SATA_PLL_CFG0_REG, 1714 0, 1715 CAR_SATA_PLL_CFG0_PADPLL_RESET_SWCTL); 1716 tegra_reg_set_clear(bst, bsh, CAR_SATA_PLL_CFG0_REG, 1717 CAR_SATA_PLL_CFG0_SEQ_PADPLL_SLEEP_IDDQ | 1718 CAR_SATA_PLL_CFG0_PADPLL_USE_LOCKDET, 1719 0); 1720 } 1721 1722 void 1723 tegra210_car_sata_enable_hw_seq(void) 1724 { 1725 device_t dev = device_find_by_driver_unit("tegra210car", 0); 1726 KASSERT(dev != NULL); 1727 struct tegra210_car_softc * const sc = device_private(dev); 1728 bus_space_tag_t bst = sc->sc_bst; 1729 bus_space_handle_t bsh = sc->sc_bsh; 1730 1731 tegra_reg_set_clear(bst, bsh, CAR_SATA_PLL_CFG0_REG, 1732 CAR_SATA_PLL_CFG0_SEQ_ENABLE, 0); 1733 } 1734 1735