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