Module Name: src Committed By: jmcneill Date: Fri Jul 21 01:01:22 UTC 2017
Modified Files: src/sys/arch/arm/nvidia: files.tegra tegra124_car.c tegra124_carreg.h tegra_reg.h src/sys/arch/evbarm/conf: TEGRA Added Files: src/sys/arch/arm/nvidia: tegra210_car.c tegra210_carreg.h Log Message: Add support for NVIDIA Tegra X1. To generate a diff of this commit: cvs rdiff -u -r1.40 -r1.41 src/sys/arch/arm/nvidia/files.tegra cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/nvidia/tegra124_car.c cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/nvidia/tegra124_carreg.h cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/nvidia/tegra210_car.c \ src/sys/arch/arm/nvidia/tegra210_carreg.h cvs rdiff -u -r1.23 -r1.24 src/sys/arch/arm/nvidia/tegra_reg.h cvs rdiff -u -r1.25 -r1.26 src/sys/arch/evbarm/conf/TEGRA Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/nvidia/files.tegra diff -u src/sys/arch/arm/nvidia/files.tegra:1.40 src/sys/arch/arm/nvidia/files.tegra:1.41 --- src/sys/arch/arm/nvidia/files.tegra:1.40 Fri Jun 2 00:09:56 2017 +++ src/sys/arch/arm/nvidia/files.tegra Fri Jul 21 01:01:22 2017 @@ -1,4 +1,4 @@ -# $NetBSD: files.tegra,v 1.40 2017/06/02 00:09:56 jmcneill Exp $ +# $NetBSD: files.tegra,v 1.41 2017/07/21 01:01:22 jmcneill Exp $ # # Configuration info for NVIDIA Tegra ARM Peripherals # @@ -47,11 +47,16 @@ device tegrafuse attach tegrafuse at fdt with tegra_fuse file arch/arm/nvidia/tegra_fuse.c tegra_fuse -# Clock and Reset controller +# Clock and Reset controller (T124) device tegra124car: clk attach tegra124car at fdt with tegra124_car file arch/arm/nvidia/tegra124_car.c tegra124_car +# Clock and Reset controller (T210) +device tegra210car: clk +attach tegra210car at fdt with tegra210_car +file arch/arm/nvidia/tegra210_car.c tegra210_car + # GPIO controller device tegragpio: gpiobus attach tegragpio at fdt with tegra_gpio Index: src/sys/arch/arm/nvidia/tegra124_car.c diff -u src/sys/arch/arm/nvidia/tegra124_car.c:1.13 src/sys/arch/arm/nvidia/tegra124_car.c:1.14 --- src/sys/arch/arm/nvidia/tegra124_car.c:1.13 Sat Apr 29 11:00:17 2017 +++ src/sys/arch/arm/nvidia/tegra124_car.c Fri Jul 21 01:01:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra124_car.c,v 1.13 2017/04/29 11:00:17 jmcneill Exp $ */ +/* $NetBSD: tegra124_car.c,v 1.14 2017/07/21 01:01:22 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.13 2017/04/29 11:00:17 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.14 2017/07/21 01:01:22 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -427,7 +427,7 @@ static const char *mux_xusb_fs_p[] = { "clk_m", NULL, "pll_u_48", NULL, "pll_p_out0", NULL, "pll_u_480" }; static struct tegra_clk tegra124_car_clocks[] = { - CLK_FIXED("clk_m", TEGRA_REF_FREQ), + CLK_FIXED("clk_m", TEGRA124_REF_FREQ), CLK_PLL("pll_p", "clk_m", CAR_PLLP_BASE_REG, CAR_PLLP_BASE_DIVM, CAR_PLLP_BASE_DIVN, CAR_PLLP_BASE_DIVP), Index: src/sys/arch/arm/nvidia/tegra124_carreg.h diff -u src/sys/arch/arm/nvidia/tegra124_carreg.h:1.5 src/sys/arch/arm/nvidia/tegra124_carreg.h:1.6 --- src/sys/arch/arm/nvidia/tegra124_carreg.h:1.5 Sun Jan 22 17:40:06 2017 +++ src/sys/arch/arm/nvidia/tegra124_carreg.h Fri Jul 21 01:01:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra124_carreg.h,v 1.5 2017/01/22 17:40:06 jakllsch Exp $ */ +/* $NetBSD: tegra124_carreg.h,v 1.6 2017/07/21 01:01:22 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -29,6 +29,8 @@ #ifndef _ARM_TEGRA124_CARREG_H #define _ARM_TEGRA124_CARREG_H +#define TEGRA124_REF_FREQ 12000000 + #define CAR_RST_SOURCE_REG 0x00 #define CAR_RST_SOURCE_WDT_EN __BIT(5) #define CAR_RST_SOURCE_WDT_SEL __BIT(4) Index: src/sys/arch/arm/nvidia/tegra_reg.h diff -u src/sys/arch/arm/nvidia/tegra_reg.h:1.23 src/sys/arch/arm/nvidia/tegra_reg.h:1.24 --- src/sys/arch/arm/nvidia/tegra_reg.h:1.23 Tue May 30 22:55:26 2017 +++ src/sys/arch/arm/nvidia/tegra_reg.h Fri Jul 21 01:01:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: tegra_reg.h,v 1.23 2017/05/30 22:55:26 jmcneill Exp $ */ +/* $NetBSD: tegra_reg.h,v 1.24 2017/07/21 01:01:22 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -73,8 +73,6 @@ #define TEGRA_APB_VBASE 0xfc000000 #define TEGRA_AHB_A2_VBASE 0xfd000000 -#define TEGRA_REF_FREQ 12000000 - /* APB */ #define TEGRA_MPIO_OFFSET 0x00000000 #define TEGRA_MPIO_SIZE 0x4000 Index: src/sys/arch/evbarm/conf/TEGRA diff -u src/sys/arch/evbarm/conf/TEGRA:1.25 src/sys/arch/evbarm/conf/TEGRA:1.26 --- src/sys/arch/evbarm/conf/TEGRA:1.25 Thu Jul 20 01:54:50 2017 +++ src/sys/arch/evbarm/conf/TEGRA Fri Jul 21 01:01:22 2017 @@ -1,7 +1,7 @@ # -# $NetBSD: TEGRA,v 1.25 2017/07/20 01:54:50 jmcneill Exp $ +# $NetBSD: TEGRA,v 1.26 2017/07/21 01:01:22 jmcneill Exp $ # -# NVIDIA Tegra K1 (T124) +# NVIDIA Tegra family SoCs # include "arch/evbarm/conf/std.tegra" @@ -16,6 +16,7 @@ makeoptions DTS=" " options CPU_CORTEXA15 +options CPU_CORTEXA57 options SOC_TEGRA124 options SOC_TEGRA210 options MULTIPROCESSOR @@ -74,7 +75,8 @@ tegrafuse* at fdt? pass 4 # FUSE tegrapmc* at fdt? pass 4 # PMC # Clock and Reset controller -tegra124car* at fdt? pass 3 # CAR +tegra124car* at fdt? pass 3 # CAR (T124) +tegra210car* at fdt? pass 3 # CAR (T210) # GPIO controller tegragpio* at fdt? pass 2 # GPIO Added files: Index: src/sys/arch/arm/nvidia/tegra210_car.c diff -u /dev/null src/sys/arch/arm/nvidia/tegra210_car.c:1.1 --- /dev/null Fri Jul 21 01:01:22 2017 +++ src/sys/arch/arm/nvidia/tegra210_car.c Fri Jul 21 01:01:22 2017 @@ -0,0 +1,1370 @@ +/* $NetBSD: tegra210_car.c,v 1.1 2017/07/21 01:01:22 jmcneill Exp $ */ + +/*- + * Copyright (c) 2015-2017 Jared McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: tegra210_car.c,v 1.1 2017/07/21 01:01:22 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/rndpool.h> +#include <sys/rndsource.h> +#include <sys/atomic.h> +#include <sys/kmem.h> + +#include <dev/clk/clk_backend.h> + +#include <arm/nvidia/tegra_reg.h> +#include <arm/nvidia/tegra210_carreg.h> +#include <arm/nvidia/tegra_clock.h> +#include <arm/nvidia/tegra_pmcreg.h> +#include <arm/nvidia/tegra_var.h> + +#include <dev/fdt/fdtvar.h> + +static int tegra210_car_match(device_t, cfdata_t, void *); +static void tegra210_car_attach(device_t, device_t, void *); + +static struct clk *tegra210_car_clock_decode(device_t, const void *, size_t); + +static const struct fdtbus_clock_controller_func tegra210_car_fdtclock_funcs = { + .decode = tegra210_car_clock_decode +}; + +/* DT clock ID to clock name mappings */ +static struct tegra210_car_clock_id { + const char *name; + u_int id; +} tegra210_car_clock_ids[] = { + { "ISPB", 3 }, + { "RTC", 4 }, + { "TIMER", 5 }, + { "UARTA", 6 }, + { "GPIO", 8 }, + { "SDMMC2", 9 }, + { "I2S1", 11 }, + { "I2C1", 12 }, + { "SDMMC1", 14 }, + { "SDMMC4", 15 }, + { "PWM", 17 }, + { "I2S2", 18 }, + { "USBD", 22 }, + { "ISP", 23 }, + { "DISP2", 26 }, + { "DISP1", 27 }, + { "HOST1X", 28 }, + { "I2S0", 30 }, + { "MC", 32 }, + { "AHBDMA", 33 }, + { "APBDMA", 34 }, + { "PMC", 38 }, + { "KFUSE", 40 }, + { "SBC1", 41 }, + { "SBC2", 44 }, + { "SBC3", 46 }, + { "I2C5", 47 }, + { "DSIA", 48 }, + { "CSI", 52 }, + { "I2C2", 54 }, + { "UARTC", 55 }, + { "MIPI_CAL", 56 }, + { "EMC", 57 }, + { "USB2", 58 }, + { "BSEV", 63 }, + { "UARTD", 65 }, + { "I2C3", 67 }, + { "SBC4", 68 }, + { "SDMMC3", 69 }, + { "PCIE", 70 }, + { "OWR", 71 }, + { "AFI", 72 }, + { "CSITE", 73 }, + { "SOC_THERM", 78 }, + { "DTV", 79 }, + { "I2CSLOW", 81 }, + { "DSIB", 82 }, + { "TSEC", 83 }, + { "XUSB_HOST", 89 }, + { "CSUS", 92 }, + { "MSELECT", 99 }, + { "TSENSOR", 100 }, + { "I2S3", 101 }, + { "I2S4", 102 }, + { "I2C4", 103 }, + { "D_AUDIO", 106 }, + { "APB2APE", 107 }, + { "HDA2CODEC_2X", 111 }, + { "SPDIF_2X", 118 }, + { "ACTMON", 119 }, + { "EXTERN1", 120 }, + { "EXTERN2", 121 }, + { "EXTERN3", 122 }, + { "SATA_OOB", 123 }, + { "SATA", 124 }, + { "HDA", 125 }, + { "HDA2HDMI", 128 }, + { "XUSB_GATE", 143 }, + { "CILAB", 144 }, + { "CILCD", 145 }, + { "CILE", 146 }, + { "DSIALP", 147 }, + { "DSIBLP", 148 }, + { "ENTROPY", 149 }, + { "XUSB_SS", 156 }, + { "DMIC1", 161 }, + { "DMIC2", 162 }, + { "I2C6", 166 }, + { "VIM2_CLK", 171 }, + { "MIPIBIF", 173 }, + { "CLK72MHZ", 177 }, + { "VIC03", 178 }, + { "DPAUX", 181 }, + { "SOR0", 182 }, + { "SOR1", 183 }, + { "GPU", 184 }, + { "DBGAPB", 185 }, + { "PLL_P_OUT_ADSP", 187 }, + { "PLL_G_REF", 189 }, + { "SDMMC_LEGACY", 193 }, + { "NVDEC", 194 }, + { "NVJPG", 195 }, + { "DMIC3", 197 }, + { "APE", 198 }, + { "MAUD", 202 }, + { "TSECB", 206 }, + { "DPAUX1", 207 }, + { "VI_I2C", 208 }, + { "HSIC_TRK", 209 }, + { "USB2_TRK", 210 }, + { "QSPI", 211 }, + { "UARTAPE", 212 }, + { "NVENC", 219 }, + { "SOR_SAFE", 222 }, + { "PLL_P_OUT_CPU", 223 }, + { "UARTB", 224 }, + { "VFIR", 225 }, + { "SPDIF_IN", 226 }, + { "SPDIF_OUT", 227 }, + { "VI", 228 }, + { "VI_SENSOR", 229 }, + { "FUSE", 230 }, + { "FUSE_BURN", 231 }, + { "CLK_32K", 232 }, + { "CLK_M", 233 }, + { "CLK_M_DIV2", 234 }, + { "CLK_M_DIV4", 235 }, + { "PLL_REF", 236 }, + { "PLL_C", 237 }, + { "PLL_C_OUT1", 238 }, + { "PLL_C2", 239 }, + { "PLL_C3", 240 }, + { "PLL_M", 241 }, + { "PLL_M_OUT1", 242 }, + { "PLL_P", 243 }, + { "PLL_P_OUT1", 244 }, + { "PLL_P_OUT2", 245 }, + { "PLL_P_OUT3", 246 }, + { "PLL_P_OUT4", 247 }, + { "PLL_A", 248 }, + { "PLL_A_OUT0", 249 }, + { "PLL_D", 250 }, + { "PLL_D_OUT0", 251 }, + { "PLL_D2", 252 }, + { "PLL_D2_OUT0", 253 }, + { "PLL_U", 254 }, + { "PLL_U_480M", 255 }, + { "PLL_U_60M", 256 }, + { "PLL_U_48M", 257 }, + { "PLL_X", 259 }, + { "PLL_X_OUT0", 260 }, + { "PLL_RE_VCO", 261 }, + { "PLL_RE_OUT", 262 }, + { "PLL_E", 263 }, + { "SPDIF_IN_SYNC", 264 }, + { "I2S0_SYNC", 265 }, + { "I2S1_SYNC", 266 }, + { "I2S2_SYNC", 267 }, + { "I2S3_SYNC", 268 }, + { "I2S4_SYNC", 269 }, + { "VIMCLK_SYNC", 270 }, + { "AUDIO0", 271 }, + { "AUDIO1", 272 }, + { "AUDIO2", 273 }, + { "AUDIO3", 274 }, + { "AUDIO4", 275 }, + { "SPDIF", 276 }, + { "CLK_OUT_1", 277 }, + { "CLK_OUT_2", 278 }, + { "CLK_OUT_3", 279 }, + { "BLINK", 280 }, + { "SOR1_SRC", 282 }, + { "XUSB_HOST_SRC", 284 }, + { "XUSB_FALCON_SRC", 285 }, + { "XUSB_FS_SRC", 286 }, + { "XUSB_SS_SRC", 287 }, + { "XUSB_DEV_SRC", 288 }, + { "XUSB_DEV", 289 }, + { "XUSB_HS_SRC", 290 }, + { "SCLK", 291 }, + { "HCLK", 292 }, + { "PCLK", 293 }, + { "CCLK_G", 294 }, + { "CCLK_LP", 295 }, + { "DFLL_REF", 296 }, + { "DFLL_SOC", 297 }, + { "VI_SENSOR2", 298 }, + { "PLL_P_OUT5", 299 }, + { "CML0", 300 }, + { "CML1", 301 }, + { "PLL_C4", 302 }, + { "PLL_DP", 303 }, + { "PLL_E_MUX", 304 }, + { "PLL_MB", 305 }, + { "PLL_A1", 306 }, + { "PLL_D_DSI_OUT", 307 }, + { "PLL_C4_OUT0", 308 }, + { "PLL_C4_OUT1", 309 }, + { "PLL_C4_OUT2", 310 }, + { "PLL_C4_OUT3", 311 }, + { "PLL_U_OUT", 312 }, + { "PLL_U_OUT1", 313 }, + { "PLL_U_OUT2", 314 }, + { "USB2_HSIC_TRK", 315 }, + { "PLL_P_OUT_HSIO", 316 }, + { "PLL_P_OUT_XUSB", 317 }, + { "XUSB_SSP_SRC", 318 }, + { "PLL_RE_OUT1", 319 }, + { "AUDIO0_MUX", 350 }, + { "AUDIO1_MUX", 351 }, + { "AUDIO2_MUX", 352 }, + { "AUDIO3_MUX", 353 }, + { "AUDIO4_MUX", 354 }, + { "SPDIF_MUX", 355 }, + { "CLK_OUT_1_MUX", 356 }, + { "CLK_OUT_2_MUX", 357 }, + { "CLK_OUT_3_MUX", 358 }, + { "DSIA_MUX", 359 }, + { "DSIB_MUX", 360 }, + { "SOR0_LVDS", 361 }, + { "XUSB_SS_DIV2", 362 }, + { "PLL_M_UD", 363 }, + { "PLL_C_UD", 364 }, + { "SCLK_MUX", 365 }, +}; + +static struct clk *tegra210_car_clock_get(void *, const char *); +static void tegra210_car_clock_put(void *, struct clk *); +static u_int tegra210_car_clock_get_rate(void *, struct clk *); +static int tegra210_car_clock_set_rate(void *, struct clk *, u_int); +static int tegra210_car_clock_enable(void *, struct clk *); +static int tegra210_car_clock_disable(void *, struct clk *); +static int tegra210_car_clock_set_parent(void *, struct clk *, + struct clk *); +static struct clk *tegra210_car_clock_get_parent(void *, struct clk *); + +static const struct clk_funcs tegra210_car_clock_funcs = { + .get = tegra210_car_clock_get, + .put = tegra210_car_clock_put, + .get_rate = tegra210_car_clock_get_rate, + .set_rate = tegra210_car_clock_set_rate, + .enable = tegra210_car_clock_enable, + .disable = tegra210_car_clock_disable, + .set_parent = tegra210_car_clock_set_parent, + .get_parent = tegra210_car_clock_get_parent, +}; + +#define CLK_FIXED(_name, _rate) { \ + .base = { .name = (_name) }, .type = TEGRA_CLK_FIXED, \ + .u = { .fixed = { .rate = (_rate) } } \ +} + +#define CLK_PLL(_name, _parent, _base, _divm, _divn, _divp) { \ + .base = { .name = (_name) }, .type = TEGRA_CLK_PLL, \ + .parent = (_parent), \ + .u = { \ + .pll = { \ + .base_reg = (_base), \ + .divm_mask = (_divm), \ + .divn_mask = (_divn), \ + .divp_mask = (_divp), \ + } \ + } \ +} + +#define CLK_MUX(_name, _reg, _bits, _p) { \ + .base = { .name = (_name) }, .type = TEGRA_CLK_MUX, \ + .u = { \ + .mux = { \ + .nparents = __arraycount(_p), \ + .parents = (_p), \ + .reg = (_reg), \ + .bits = (_bits) \ + } \ + } \ +} + +#define CLK_FIXED_DIV(_name, _parent, _div) { \ + .base = { .name = (_name) }, .type = TEGRA_CLK_FIXED_DIV, \ + .parent = (_parent), \ + .u = { \ + .fixed_div = { \ + .div = (_div) \ + } \ + } \ +} + +#define CLK_DIV(_name, _parent, _reg, _bits) { \ + .base = { .name = (_name) }, .type = TEGRA_CLK_DIV, \ + .parent = (_parent), \ + .u = { \ + .div = { \ + .reg = (_reg), \ + .bits = (_bits) \ + } \ + } \ +} + +#define CLK_GATE(_name, _parent, _set, _clr, _bits) { \ + .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \ + .type = TEGRA_CLK_GATE, \ + .parent = (_parent), \ + .u = { \ + .gate = { \ + .set_reg = (_set), \ + .clr_reg = (_clr), \ + .bits = (_bits), \ + } \ + } \ +} + +#define CLK_GATE_L(_name, _parent, _bits) \ + CLK_GATE(_name, _parent, \ + CAR_CLK_ENB_L_SET_REG, CAR_CLK_ENB_L_CLR_REG, \ + _bits) + +#define CLK_GATE_H(_name, _parent, _bits) \ + CLK_GATE(_name, _parent, \ + CAR_CLK_ENB_H_SET_REG, CAR_CLK_ENB_H_CLR_REG, \ + _bits) + +#define CLK_GATE_U(_name, _parent, _bits) \ + CLK_GATE(_name, _parent, \ + CAR_CLK_ENB_U_SET_REG, CAR_CLK_ENB_U_CLR_REG, \ + _bits) + +#define CLK_GATE_V(_name, _parent, _bits) \ + CLK_GATE(_name, _parent, \ + CAR_CLK_ENB_V_SET_REG, CAR_CLK_ENB_V_CLR_REG, \ + _bits) + +#define CLK_GATE_W(_name, _parent, _bits) \ + CLK_GATE(_name, _parent, \ + CAR_CLK_ENB_W_SET_REG, CAR_CLK_ENB_W_CLR_REG, \ + _bits) + +#define CLK_GATE_X(_name, _parent, _bits) \ + CLK_GATE(_name, _parent, \ + CAR_CLK_ENB_X_SET_REG, CAR_CLK_ENB_X_CLR_REG, \ + _bits) + +#define CLK_GATE_Y(_name, _parent, _bits) \ + CLK_GATE(_name, _parent, \ + CAR_CLK_ENB_Y_SET_REG, CAR_CLK_ENB_Y_CLR_REG, \ + _bits) + + +#define CLK_GATE_SIMPLE(_name, _parent, _reg, _bits) \ + CLK_GATE(_name, _parent, _reg, _reg, _bits) + +static const char *mux_uart_p[] = + { "PLL_P", "PLL_C2", "PLL_C", "PLL_C4_OUT0", + NULL, "PLL_C4_OUT1", "CLK_M", "PLL_C4_OUT2" }; + +static const char *mux_sdmmc1_p[] = + { "PLL_P", "PLL_A", "PLL_C", "PLL_C4_OUT0", + "PLL_M", "PLL_E", "CLK_M", "PLL_C4_OUT0" }; + +static const char *mux_sdmmc2_4_p[] = + { "PLL_P", "PLL_C4_OUT2"/*LJ*/, "PLL_C4_OUT0"/*LJ*/, "PLL_C4_OUT2", + "PLL_M", "PLL_E", "CLK_M", "PLL_C4_OUT0" }; + +static const char *mux_sdmmc3_p[] = + { "PLL_P", "PLL_A", "PLL_C", "PLL_C4_OUT2", + "PLL_C4_OUT1", "PLL_E", "CLK_M", "PLL_C4_OUT0" }; + +static const char *mux_i2c_p[] = + { "PLL_P", "PLL_C2_OUT0", "PLL_C", "PLL_C4_OUT0", + NULL, "PLL_C4_OUT1", "CLK_M", "PLL_C4_OUT2" }; + +static struct tegra_clk tegra210_car_clocks[] = { + CLK_FIXED("CLK_M", TEGRA210_REF_FREQ), + + CLK_PLL("PLL_P", "CLK_M", CAR_PLLP_BASE_REG, + CAR_PLLP_BASE_DIVM, CAR_PLLP_BASE_DIVN, CAR_PLLP_BASE_DIVP), + CLK_PLL("PLL_C", "CLK_M", CAR_PLLC_BASE_REG, + CAR_PLLC_BASE_DIVM, CAR_PLLC_BASE_DIVN, CAR_PLLC_BASE_DIVP), + CLK_PLL("PLL_U", "CLK_M", CAR_PLLU_BASE_REG, + CAR_PLLU_BASE_DIVM, CAR_PLLU_BASE_DIVN, CAR_PLLU_BASE_DIVP), + CLK_PLL("PLL_X", "CLK_M", CAR_PLLX_BASE_REG, + CAR_PLLX_BASE_DIVM, CAR_PLLX_BASE_DIVN, CAR_PLLX_BASE_DIVP), + CLK_PLL("PLL_E", "CLK_M", CAR_PLLE_BASE_REG, + CAR_PLLE_BASE_DIVM, CAR_PLLE_BASE_DIVN, CAR_PLLE_BASE_DIVP_CML), + CLK_PLL("PLL_D", "CLK_M", CAR_PLLD_BASE_REG, + CAR_PLLD_BASE_DIVM, CAR_PLLD_BASE_DIVN, CAR_PLLD_BASE_DIVP), + CLK_PLL("PLL_D2", "CLK_M", CAR_PLLD2_BASE_REG, + CAR_PLLD2_BASE_DIVM, CAR_PLLD2_BASE_DIVN, CAR_PLLD2_BASE_DIVP), + CLK_PLL("PLL_REF", "CLK_M", CAR_PLLREFE_BASE_REG, + CAR_PLLREFE_BASE_DIVM, CAR_PLLREFE_BASE_DIVN, CAR_PLLREFE_BASE_DIVP), + + CLK_MUX("MUX_UARTA", CAR_CLKSRC_UARTA_REG, CAR_CLKSRC_UART_SRC, + mux_uart_p), + CLK_MUX("MUX_UARTB", CAR_CLKSRC_UARTB_REG, CAR_CLKSRC_UART_SRC, + mux_uart_p), + CLK_MUX("MUX_UARTC", CAR_CLKSRC_UARTC_REG, CAR_CLKSRC_UART_SRC, + mux_uart_p), + CLK_MUX("MUX_UARTD", CAR_CLKSRC_UARTD_REG, CAR_CLKSRC_UART_SRC, + mux_uart_p), + + CLK_MUX("MUX_SDMMC1", CAR_CLKSRC_SDMMC1_REG, CAR_CLKSRC_SDMMC_SRC, + mux_sdmmc1_p), + CLK_MUX("MUX_SDMMC2", CAR_CLKSRC_SDMMC2_REG, CAR_CLKSRC_SDMMC_SRC, + mux_sdmmc2_4_p), + CLK_MUX("MUX_SDMMC3", CAR_CLKSRC_SDMMC3_REG, CAR_CLKSRC_SDMMC_SRC, + mux_sdmmc3_p), + CLK_MUX("MUX_SDMMC4", CAR_CLKSRC_SDMMC4_REG, CAR_CLKSRC_SDMMC_SRC, + mux_sdmmc2_4_p), + + CLK_MUX("MUX_I2C1", CAR_CLKSRC_I2C1_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), + CLK_MUX("MUX_I2C2", CAR_CLKSRC_I2C2_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), + CLK_MUX("MUX_I2C3", CAR_CLKSRC_I2C3_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), + CLK_MUX("MUX_I2C4", CAR_CLKSRC_I2C4_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), + CLK_MUX("MUX_I2C5", CAR_CLKSRC_I2C5_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), + CLK_MUX("MUX_I2C6", CAR_CLKSRC_I2C6_REG, CAR_CLKSRC_I2C_SRC, mux_i2c_p), + + CLK_DIV("DIV_UARTA", "MUX_UARTA", + CAR_CLKSRC_UARTA_REG, CAR_CLKSRC_UART_DIV), + CLK_DIV("DIV_UARTB", "MUX_UARTB", + CAR_CLKSRC_UARTB_REG, CAR_CLKSRC_UART_DIV), + CLK_DIV("DIV_UARTC", "MUX_UARTC", + CAR_CLKSRC_UARTC_REG, CAR_CLKSRC_UART_DIV), + CLK_DIV("DIV_UARTD", "MUX_UARTD", + CAR_CLKSRC_UARTD_REG, CAR_CLKSRC_UART_DIV), + + CLK_DIV("DIV_SDMMC1", "MUX_SDMMC1", + CAR_CLKSRC_SDMMC1_REG, CAR_CLKSRC_SDMMC_DIV), + CLK_DIV("DIV_SDMMC2", "MUX_SDMMC2", + CAR_CLKSRC_SDMMC2_REG, CAR_CLKSRC_SDMMC_DIV), + CLK_DIV("DIV_SDMMC3", "MUX_SDMMC3", + CAR_CLKSRC_SDMMC3_REG, CAR_CLKSRC_SDMMC_DIV), + CLK_DIV("DIV_SDMMC4", "MUX_SDMMC4", + CAR_CLKSRC_SDMMC4_REG, CAR_CLKSRC_SDMMC_DIV), + + CLK_DIV("DIV_I2C1", "MUX_I2C1", + CAR_CLKSRC_I2C1_REG, CAR_CLKSRC_I2C_DIV), + CLK_DIV("DIV_I2C2", "MUX_I2C2", + CAR_CLKSRC_I2C2_REG, CAR_CLKSRC_I2C_DIV), + CLK_DIV("DIV_I2C3", "MUX_I2C3", + CAR_CLKSRC_I2C3_REG, CAR_CLKSRC_I2C_DIV), + CLK_DIV("DIV_I2C4", "MUX_I2C4", + CAR_CLKSRC_I2C4_REG, CAR_CLKSRC_I2C_DIV), + CLK_DIV("DIV_I2C5", "MUX_I2C5", + CAR_CLKSRC_I2C5_REG, CAR_CLKSRC_I2C_DIV), + CLK_DIV("DIV_I2C6", "MUX_I2C6", + CAR_CLKSRC_I2C6_REG, CAR_CLKSRC_I2C_DIV), + + CLK_GATE_L("UARTA", "DIV_UARTA", CAR_DEV_L_UARTA), + CLK_GATE_L("UARTB", "DIV_UARTB", CAR_DEV_L_UARTB), + CLK_GATE_H("UARTC", "DIV_UARTC", CAR_DEV_H_UARTC), + CLK_GATE_U("UARTD", "DIV_UARTD", CAR_DEV_U_UARTD), + CLK_GATE_L("SDMMC1", "DIV_SDMMC1", CAR_DEV_L_SDMMC1), + CLK_GATE_L("SDMMC2", "DIV_SDMMC2", CAR_DEV_L_SDMMC2), + CLK_GATE_U("SDMMC3", "DIV_SDMMC3", CAR_DEV_U_SDMMC3), + CLK_GATE_L("SDMMC4", "DIV_SDMMC4", CAR_DEV_L_SDMMC4), + CLK_GATE_L("I2C1", "DIV_I2C1", CAR_DEV_L_I2C1), + CLK_GATE_H("I2C2", "DIV_I2C2", CAR_DEV_H_I2C2), + CLK_GATE_U("I2C3", "DIV_I2C3", CAR_DEV_U_I2C3), + CLK_GATE_V("I2C4", "DIV_I2C4", CAR_DEV_V_I2C4), + CLK_GATE_H("I2C5", "DIV_I2C5", CAR_DEV_H_I2C5), + CLK_GATE_X("I2C6", "DIV_I2C6", CAR_DEV_X_I2C6), +}; + +struct tegra210_init_parent { + const char *clock; + const char *parent; +} tegra210_init_parents[] = { + { "SDMMC1", "PLL_P" }, + { "SDMMC2", "PLL_P" }, + { "SDMMC3", "PLL_P" }, + { "SDMMC4", "PLL_P" }, +}; + +struct tegra210_car_rst { + u_int set_reg; + u_int clr_reg; + u_int mask; +}; + +static struct tegra210_car_reset_reg { + u_int set_reg; + u_int clr_reg; +} tegra210_car_reset_regs[] = { + { CAR_RST_DEV_L_SET_REG, CAR_RST_DEV_L_CLR_REG }, + { CAR_RST_DEV_H_SET_REG, CAR_RST_DEV_H_CLR_REG }, + { CAR_RST_DEV_U_SET_REG, CAR_RST_DEV_U_CLR_REG }, + { CAR_RST_DEV_V_SET_REG, CAR_RST_DEV_V_CLR_REG }, + { CAR_RST_DEV_W_SET_REG, CAR_RST_DEV_W_CLR_REG }, + { CAR_RST_DEV_X_SET_REG, CAR_RST_DEV_X_CLR_REG }, + { CAR_RST_DEV_Y_SET_REG, CAR_RST_DEV_Y_CLR_REG }, +}; + +static void * tegra210_car_reset_acquire(device_t, const void *, size_t); +static void tegra210_car_reset_release(device_t, void *); +static int tegra210_car_reset_assert(device_t, void *); +static int tegra210_car_reset_deassert(device_t, void *); + +static const struct fdtbus_reset_controller_func tegra210_car_fdtreset_funcs = { + .acquire = tegra210_car_reset_acquire, + .release = tegra210_car_reset_release, + .reset_assert = tegra210_car_reset_assert, + .reset_deassert = tegra210_car_reset_deassert, +}; + +struct tegra210_car_softc { + device_t sc_dev; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + + struct clk_domain sc_clkdom; + + u_int sc_clock_cells; + u_int sc_reset_cells; + + kmutex_t sc_rndlock; + krndsource_t sc_rndsource; +}; + +static void tegra210_car_init(struct tegra210_car_softc *); +static void tegra210_car_watchdog_init(struct tegra210_car_softc *); +static void tegra210_car_parent_init(struct tegra210_car_softc *); + +CFATTACH_DECL_NEW(tegra210_car, sizeof(struct tegra210_car_softc), + tegra210_car_match, tegra210_car_attach, NULL, NULL); + +static int +tegra210_car_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { "nvidia,tegra210-car", NULL }; + struct fdt_attach_args * const faa = aux; + +#if 0 + return of_match_compatible(faa->faa_phandle, compatible); +#else + if (of_match_compatible(faa->faa_phandle, compatible) == 0) + return 0; + + return 999; +#endif +} + +static void +tegra210_car_attach(device_t parent, device_t self, void *aux) +{ + struct tegra210_car_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + int error, n; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_bst = faa->faa_bst; + error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); + if (error) { + aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); + return; + } + if (of_getprop_uint32(phandle, "#clock-cells", &sc->sc_clock_cells)) + sc->sc_clock_cells = 1; + if (of_getprop_uint32(phandle, "#reset-cells", &sc->sc_reset_cells)) + sc->sc_reset_cells = 1; + + aprint_naive("\n"); + aprint_normal(": CAR\n"); + + sc->sc_clkdom.funcs = &tegra210_car_clock_funcs; + sc->sc_clkdom.priv = sc; + for (n = 0; n < __arraycount(tegra210_car_clocks); n++) + tegra210_car_clocks[n].base.domain = &sc->sc_clkdom; + + fdtbus_register_clock_controller(self, phandle, + &tegra210_car_fdtclock_funcs); + fdtbus_register_reset_controller(self, phandle, + &tegra210_car_fdtreset_funcs); + + tegra210_car_init(sc); + +#ifdef TEGRA210_CAR_DEBUG + for (n = 0; n < __arraycount(tegra210_car_clocks); n++) { + struct clk *clk = TEGRA_CLK_BASE(&tegra210_car_clocks[n]); + struct clk *clk_parent = clk_get_parent(clk); + device_printf(self, "clk %s (parent %s): ", clk->name, + clk_parent ? clk_parent->name : "none"); + printf("%u Hz\n", clk_get_rate(clk)); + } +#endif +} + +static void +tegra210_car_init(struct tegra210_car_softc *sc) +{ + tegra210_car_parent_init(sc); +#if notyet + tegra210_car_utmip_init(sc); + tegra210_car_xusb_init(sc); +#endif + tegra210_car_watchdog_init(sc); +} + +static void +tegra210_car_parent_init(struct tegra210_car_softc *sc) +{ + struct clk *clk, *clk_parent; + int error; + u_int n; + + for (n = 0; n < __arraycount(tegra210_init_parents); n++) { + clk = clk_get(&sc->sc_clkdom, tegra210_init_parents[n].clock); + KASSERT(clk != NULL); + clk_parent = clk_get(&sc->sc_clkdom, + tegra210_init_parents[n].parent); + KASSERT(clk_parent != NULL); + + error = clk_set_parent(clk, clk_parent); + if (error) { + aprint_error_dev(sc->sc_dev, + "couldn't set '%s' parent to '%s': %d\n", + clk->name, clk_parent->name, error); + } + clk_put(clk_parent); + clk_put(clk); + } +} + +#if notyet +static void +tegra210_car_utmip_init(struct tegra210_car_softc *sc) +{ + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + + const u_int enable_dly_count = 0x02; + const u_int stable_count = 0x2f; + const u_int active_dly_count = 0x04; + const u_int xtal_freq_count = 0x76; + + tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG2_REG, + __SHIFTIN(stable_count, CAR_UTMIP_PLL_CFG2_STABLE_COUNT) | + __SHIFTIN(active_dly_count, CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT), + CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERDOWN | + CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERDOWN | + CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERDOWN | + CAR_UTMIP_PLL_CFG2_STABLE_COUNT | + CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT); + + tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG, + __SHIFTIN(enable_dly_count, CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT) | + __SHIFTIN(xtal_freq_count, CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT), + CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT | + CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT); + + tegra_reg_set_clear(bst, bsh, CAR_UTMIP_PLL_CFG1_REG, + 0, + CAR_UTMIP_PLL_CFG1_PLLU_POWERDOWN | + CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERDOWN); + +} + +static void +tegra210_car_xusb_init(struct tegra210_car_softc *sc) +{ + const bus_space_tag_t bst = sc->sc_bst; + const bus_space_handle_t bsh = sc->sc_bsh; + uint32_t val; + + /* XXX do this all better */ + + bus_space_write_4(bst, bsh, CAR_CLK_ENB_W_SET_REG, CAR_DEV_W_XUSB); + + tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_MISC_REG, + 0, CAR_PLLREFE_MISC_IDDQ); + val = __SHIFTIN(25, CAR_PLLREFE_BASE_DIVN) | + __SHIFTIN(1, CAR_PLLREFE_BASE_DIVM); + bus_space_write_4(bst, bsh, CAR_PLLREFE_BASE_REG, val); + + tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_MISC_REG, + 0, CAR_PLLREFE_MISC_LOCK_OVERRIDE); + tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_BASE_REG, + CAR_PLLREFE_BASE_ENABLE, 0); + tegra_reg_set_clear(bst, bsh, CAR_PLLREFE_MISC_REG, + CAR_PLLREFE_MISC_LOCK_ENABLE, 0); + + do { + delay(2); + val = bus_space_read_4(bst, bsh, CAR_PLLREFE_MISC_REG); + } while ((val & CAR_PLLREFE_MISC_LOCK) == 0); + + tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG, + CAR_PLLE_MISC_IDDQ_SWCTL, CAR_PLLE_MISC_IDDQ_OVERRIDE); + tegra_reg_set_clear(bst, bsh, CAR_PLLE_BASE_REG, + CAR_PLLE_BASE_ENABLE, 0); + tegra_reg_set_clear(bst, bsh, CAR_PLLE_MISC_REG, + CAR_PLLE_MISC_LOCK_ENABLE, 0); + + do { + delay(2); + val = bus_space_read_4(bst, bsh, CAR_PLLE_MISC_REG); + } while ((val & CAR_PLLE_MISC_LOCK) == 0); + + tegra_reg_set_clear(bst, bsh, CAR_CLKSRC_XUSB_SS_REG, + CAR_CLKSRC_XUSB_SS_HS_CLK_BYPASS, 0); +} +#endif + +static void +tegra210_car_watchdog_init(struct tegra210_car_softc *sc) +{ + const bus_space_tag_t bst = sc->sc_bst; + const bus_space_handle_t bsh = sc->sc_bsh; + + /* Enable watchdog timer reset for system */ + tegra_reg_set_clear(bst, bsh, CAR_RST_SOURCE_REG, + CAR_RST_SOURCE_WDT_EN|CAR_RST_SOURCE_WDT_SYS_RST_EN, 0); +} + +static struct tegra_clk * +tegra210_car_clock_find(const char *name) +{ + u_int n; + + for (n = 0; n < __arraycount(tegra210_car_clocks); n++) { + if (strcmp(tegra210_car_clocks[n].base.name, name) == 0) { + return &tegra210_car_clocks[n]; + } + } + + return NULL; +} + +static struct tegra_clk * +tegra210_car_clock_find_by_id(u_int clock_id) +{ + u_int n; + + for (n = 0; n < __arraycount(tegra210_car_clock_ids); n++) { + if (tegra210_car_clock_ids[n].id == clock_id) { + const char *name = tegra210_car_clock_ids[n].name; + return tegra210_car_clock_find(name); + } + } + + return NULL; +} + +static struct clk * +tegra210_car_clock_decode(device_t dev, const void *data, size_t len) +{ + struct tegra210_car_softc * const sc = device_private(dev); + struct tegra_clk *tclk; + + if (len != sc->sc_clock_cells * 4) { + return NULL; + } + + const u_int clock_id = be32dec(data); + + tclk = tegra210_car_clock_find_by_id(clock_id); + if (tclk) + return TEGRA_CLK_BASE(tclk); + + return NULL; +} + +static struct clk * +tegra210_car_clock_get(void *priv, const char *name) +{ + struct tegra_clk *tclk; + + tclk = tegra210_car_clock_find(name); + if (tclk == NULL) + return NULL; + + atomic_inc_uint(&tclk->refcnt); + + return TEGRA_CLK_BASE(tclk); +} + +static void +tegra210_car_clock_put(void *priv, struct clk *clk) +{ + struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); + + KASSERT(tclk->refcnt > 0); + + atomic_dec_uint(&tclk->refcnt); +} + +static u_int +tegra210_car_clock_get_rate_pll(struct tegra210_car_softc *sc, + struct tegra_clk *tclk) +{ + struct tegra_pll_clk *tpll = &tclk->u.pll; + struct tegra_clk *tclk_parent; + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + u_int divm, divn, divp; + uint64_t rate; + + KASSERT(tclk->type == TEGRA_CLK_PLL); + + tclk_parent = tegra210_car_clock_find(tclk->parent); + KASSERT(tclk_parent != NULL); + + const u_int rate_parent = tegra210_car_clock_get_rate(sc, + TEGRA_CLK_BASE(tclk_parent)); + + const uint32_t base = bus_space_read_4(bst, bsh, tpll->base_reg); + divm = __SHIFTOUT(base, tpll->divm_mask); + divn = __SHIFTOUT(base, tpll->divn_mask); + if (tpll->base_reg == CAR_PLLU_BASE_REG) { + divp = __SHIFTOUT(base, tpll->divp_mask) ? 0 : 1; + } else if (tpll->base_reg == CAR_PLLP_BASE_REG) { + /* XXX divp is not applied to PLLP's primary output */ + divp = 0; + } else { + divp = __SHIFTOUT(base, tpll->divp_mask); + } + + rate = (uint64_t)rate_parent * divn; + return rate / (divm << divp); +} + +static int +tegra210_car_clock_set_rate_pll(struct tegra210_car_softc *sc, + struct tegra_clk *tclk, u_int rate) +{ + struct tegra_pll_clk *tpll = &tclk->u.pll; + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + struct clk *clk_parent; + uint32_t bp, base; + + clk_parent = tegra210_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk)); + if (clk_parent == NULL) + return EIO; + const u_int rate_parent = tegra210_car_clock_get_rate(sc, clk_parent); + if (rate_parent == 0) + return EIO; + + if (tpll->base_reg == CAR_PLLX_BASE_REG) { + const u_int divm = 1; + const u_int divn = rate / rate_parent; + const u_int divp = 0; + + bp = bus_space_read_4(bst, bsh, CAR_CCLKG_BURST_POLICY_REG); + bp &= ~CAR_CCLKG_BURST_POLICY_CPU_STATE; + bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CPU_STATE_IDLE, + CAR_CCLKG_BURST_POLICY_CPU_STATE); + bp &= ~CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE; + bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_CLKM, + CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE); + bus_space_write_4(bst, bsh, CAR_CCLKG_BURST_POLICY_REG, bp); + + base = bus_space_read_4(bst, bsh, CAR_PLLX_BASE_REG); + base &= ~CAR_PLLX_BASE_DIVM; + base &= ~CAR_PLLX_BASE_DIVN; + base &= ~CAR_PLLX_BASE_DIVP; + base |= __SHIFTIN(divm, CAR_PLLX_BASE_DIVM); + base |= __SHIFTIN(divn, CAR_PLLX_BASE_DIVN); + base |= __SHIFTIN(divp, CAR_PLLX_BASE_DIVP); + bus_space_write_4(bst, bsh, CAR_PLLX_BASE_REG, base); + + tegra_reg_set_clear(bst, bsh, CAR_PLLX_MISC_REG, + CAR_PLLX_MISC_LOCK_ENABLE, 0); + do { + delay(2); + base = bus_space_read_4(bst, bsh, tpll->base_reg); + } while ((base & CAR_PLLX_BASE_LOCK) == 0); + delay(100); + + bp &= ~CAR_CCLKG_BURST_POLICY_CPU_STATE; + bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CPU_STATE_RUN, + CAR_CCLKG_BURST_POLICY_CPU_STATE); + bp &= ~CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE; + bp |= __SHIFTIN(CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_PLLX_OUT0_LJ, + CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE); + bus_space_write_4(bst, bsh, CAR_CCLKG_BURST_POLICY_REG, bp); + + return 0; + } else if (tpll->base_reg == CAR_PLLD2_BASE_REG) { + const u_int divm = 1; + const u_int pldiv = 1; + const u_int divn = (rate << pldiv) / rate_parent; + + /* Set frequency */ + tegra_reg_set_clear(bst, bsh, tpll->base_reg, + __SHIFTIN(divm, CAR_PLLD2_BASE_DIVM) | + __SHIFTIN(divn, CAR_PLLD2_BASE_DIVN) | + __SHIFTIN(pldiv, CAR_PLLD2_BASE_DIVP), + CAR_PLLD2_BASE_REF_SRC_SEL | + CAR_PLLD2_BASE_DIVM | + CAR_PLLD2_BASE_DIVN | + CAR_PLLD2_BASE_DIVP); + + return 0; + } else { + /* TODO */ + return EOPNOTSUPP; + } +} + +static int +tegra210_car_clock_set_parent_mux(struct tegra210_car_softc *sc, + struct tegra_clk *tclk, struct tegra_clk *tclk_parent) +{ + struct tegra_mux_clk *tmux = &tclk->u.mux; + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + uint32_t v; + u_int src; + + KASSERT(tclk->type == TEGRA_CLK_MUX); + + for (src = 0; src < tmux->nparents; src++) { + if (tmux->parents[src] == NULL) { + continue; + } + if (strcmp(tmux->parents[src], tclk_parent->base.name) == 0) { + break; + } + } + if (src == tmux->nparents) { + return EINVAL; + } + + v = bus_space_read_4(bst, bsh, tmux->reg); + v &= ~tmux->bits; + v |= __SHIFTIN(src, tmux->bits); + bus_space_write_4(bst, bsh, tmux->reg, v); + + return 0; +} + +static struct tegra_clk * +tegra210_car_clock_get_parent_mux(struct tegra210_car_softc *sc, + struct tegra_clk *tclk) +{ + struct tegra_mux_clk *tmux = &tclk->u.mux; + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + + KASSERT(tclk->type == TEGRA_CLK_MUX); + + const uint32_t v = bus_space_read_4(bst, bsh, tmux->reg); + const u_int src = __SHIFTOUT(v, tmux->bits); + + KASSERT(src < tmux->nparents); + + if (tmux->parents[src] == NULL) { + return NULL; + } + + return tegra210_car_clock_find(tmux->parents[src]); +} + +static u_int +tegra210_car_clock_get_rate_fixed_div(struct tegra210_car_softc *sc, + struct tegra_clk *tclk) +{ + struct tegra_fixed_div_clk *tfixed_div = &tclk->u.fixed_div; + struct clk *clk_parent; + + clk_parent = tegra210_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk)); + if (clk_parent == NULL) + return 0; + const u_int parent_rate = tegra210_car_clock_get_rate(sc, clk_parent); + + return parent_rate / tfixed_div->div; +} + +static u_int +tegra210_car_clock_get_rate_div(struct tegra210_car_softc *sc, + struct tegra_clk *tclk) +{ + struct tegra_div_clk *tdiv = &tclk->u.div; + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + struct clk *clk_parent; + u_int rate; + + KASSERT(tclk->type == TEGRA_CLK_DIV); + + clk_parent = tegra210_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk)); + const u_int parent_rate = tegra210_car_clock_get_rate(sc, clk_parent); + + const uint32_t v = bus_space_read_4(bst, bsh, tdiv->reg); + u_int raw_div = __SHIFTOUT(v, tdiv->bits); + + switch (tdiv->reg) { + case CAR_CLKSRC_I2C1_REG: + case CAR_CLKSRC_I2C2_REG: + case CAR_CLKSRC_I2C3_REG: + case CAR_CLKSRC_I2C4_REG: + case CAR_CLKSRC_I2C5_REG: + case CAR_CLKSRC_I2C6_REG: + rate = parent_rate / (raw_div + 1); + break; + case CAR_CLKSRC_UARTA_REG: + case CAR_CLKSRC_UARTB_REG: + case CAR_CLKSRC_UARTC_REG: + case CAR_CLKSRC_UARTD_REG: + if (v & CAR_CLKSRC_UART_DIV_ENB) { + rate = parent_rate / ((raw_div / 2) + 1); + } else { + rate = parent_rate; + } + break; + case CAR_CLKSRC_SDMMC2_REG: + case CAR_CLKSRC_SDMMC4_REG: + switch (__SHIFTOUT(v, CAR_CLKSRC_SDMMC_SRC)) { + case 1: + case 2: + case 5: + raw_div = 0; /* ignore divisor for _LJ options */ + break; + } + /* FALLTHROUGH */ + default: + rate = parent_rate / ((raw_div / 2) + 1); + break; + } + + return rate; +} + +static int +tegra210_car_clock_set_rate_div(struct tegra210_car_softc *sc, + struct tegra_clk *tclk, u_int rate) +{ + struct tegra_div_clk *tdiv = &tclk->u.div; + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + struct clk *clk_parent; + u_int raw_div; + uint32_t v; + + KASSERT(tclk->type == TEGRA_CLK_DIV); + + clk_parent = tegra210_car_clock_get_parent(sc, TEGRA_CLK_BASE(tclk)); + if (clk_parent == NULL) + return EINVAL; + const u_int parent_rate = tegra210_car_clock_get_rate(sc, clk_parent); + + v = bus_space_read_4(bst, bsh, tdiv->reg); + + raw_div = __SHIFTOUT(tdiv->bits, tdiv->bits); + + switch (tdiv->reg) { + case CAR_CLKSRC_UARTA_REG: + case CAR_CLKSRC_UARTB_REG: + case CAR_CLKSRC_UARTC_REG: + case CAR_CLKSRC_UARTD_REG: + if (rate == parent_rate) { + v &= ~CAR_CLKSRC_UART_DIV_ENB; + } else if (rate) { + v |= CAR_CLKSRC_UART_DIV_ENB; + raw_div = (parent_rate / rate) * 2 - 1; + } + break; + case CAR_CLKSRC_I2C1_REG: + case CAR_CLKSRC_I2C2_REG: + case CAR_CLKSRC_I2C3_REG: + case CAR_CLKSRC_I2C4_REG: + case CAR_CLKSRC_I2C5_REG: + case CAR_CLKSRC_I2C6_REG: + if (rate) + raw_div = (parent_rate / rate) - 1; + break; + case CAR_CLKSRC_SDMMC1_REG: + case CAR_CLKSRC_SDMMC2_REG: + case CAR_CLKSRC_SDMMC3_REG: + case CAR_CLKSRC_SDMMC4_REG: + if (rate) { + for (raw_div = 0x00; raw_div <= 0xff; raw_div++) { + u_int calc_rate = + parent_rate / ((raw_div / 2) + 1); + if (calc_rate <= rate) + break; + } + if (raw_div == 0x100) + return EINVAL; + } + break; + default: + if (rate) + raw_div = (parent_rate / rate) * 2 - 1; + break; + } + + v &= ~tdiv->bits; + v |= __SHIFTIN(raw_div, tdiv->bits); + + bus_space_write_4(bst, bsh, tdiv->reg, v); + + return 0; +} + +static int +tegra210_car_clock_enable_gate(struct tegra210_car_softc *sc, + struct tegra_clk *tclk, bool enable) +{ + struct tegra_gate_clk *tgate = &tclk->u.gate; + bus_space_tag_t bst = sc->sc_bst; + bus_space_handle_t bsh = sc->sc_bsh; + bus_size_t reg; + + KASSERT(tclk->type == TEGRA_CLK_GATE); + + if (tgate->set_reg == tgate->clr_reg) { + uint32_t v = bus_space_read_4(bst, bsh, tgate->set_reg); + if (enable) { + v |= tgate->bits; + } else { + v &= ~tgate->bits; + } + bus_space_write_4(bst, bsh, tgate->set_reg, v); + } else { + if (enable) { + reg = tgate->set_reg; + } else { + reg = tgate->clr_reg; + } + bus_space_write_4(bst, bsh, reg, tgate->bits); + } + + return 0; +} + +static u_int +tegra210_car_clock_get_rate(void *priv, struct clk *clk) +{ + struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); + struct clk *clk_parent; + + switch (tclk->type) { + case TEGRA_CLK_FIXED: + return tclk->u.fixed.rate; + case TEGRA_CLK_PLL: + return tegra210_car_clock_get_rate_pll(priv, tclk); + case TEGRA_CLK_MUX: + case TEGRA_CLK_GATE: + clk_parent = tegra210_car_clock_get_parent(priv, clk); + if (clk_parent == NULL) + return EINVAL; + return tegra210_car_clock_get_rate(priv, clk_parent); + case TEGRA_CLK_FIXED_DIV: + return tegra210_car_clock_get_rate_fixed_div(priv, tclk); + case TEGRA_CLK_DIV: + return tegra210_car_clock_get_rate_div(priv, tclk); + default: + panic("tegra210: unknown tclk type %d", tclk->type); + } +} + +static int +tegra210_car_clock_set_rate(void *priv, struct clk *clk, u_int rate) +{ + struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); + struct clk *clk_parent; + + KASSERT((clk->flags & CLK_SET_RATE_PARENT) == 0); + + switch (tclk->type) { + case TEGRA_CLK_FIXED: + case TEGRA_CLK_MUX: + return EIO; + case TEGRA_CLK_FIXED_DIV: + clk_parent = tegra210_car_clock_get_parent(priv, clk); + if (clk_parent == NULL) + return EIO; + return tegra210_car_clock_set_rate(priv, clk_parent, + rate * tclk->u.fixed_div.div); + case TEGRA_CLK_GATE: + return EINVAL; + case TEGRA_CLK_PLL: + return tegra210_car_clock_set_rate_pll(priv, tclk, rate); + case TEGRA_CLK_DIV: + return tegra210_car_clock_set_rate_div(priv, tclk, rate); + default: + panic("tegra210: unknown tclk type %d", tclk->type); + } +} + +static int +tegra210_car_clock_enable(void *priv, struct clk *clk) +{ + struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); + struct clk *clk_parent; + + if (tclk->type != TEGRA_CLK_GATE) { + clk_parent = tegra210_car_clock_get_parent(priv, clk); + if (clk_parent == NULL) + return 0; + return tegra210_car_clock_enable(priv, clk_parent); + } + + return tegra210_car_clock_enable_gate(priv, tclk, true); +} + +static int +tegra210_car_clock_disable(void *priv, struct clk *clk) +{ + struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); + + if (tclk->type != TEGRA_CLK_GATE) + return EINVAL; + + return tegra210_car_clock_enable_gate(priv, tclk, false); +} + +static int +tegra210_car_clock_set_parent(void *priv, struct clk *clk, + struct clk *clk_parent) +{ + struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); + struct tegra_clk *tclk_parent = TEGRA_CLK_PRIV(clk_parent); + struct clk *nclk_parent; + + if (tclk->type != TEGRA_CLK_MUX) { + nclk_parent = tegra210_car_clock_get_parent(priv, clk); + if (nclk_parent == clk_parent || nclk_parent == NULL) + return EINVAL; + return tegra210_car_clock_set_parent(priv, nclk_parent, + clk_parent); + } + + return tegra210_car_clock_set_parent_mux(priv, tclk, tclk_parent); +} + +static struct clk * +tegra210_car_clock_get_parent(void *priv, struct clk *clk) +{ + struct tegra_clk *tclk = TEGRA_CLK_PRIV(clk); + struct tegra_clk *tclk_parent = NULL; + + switch (tclk->type) { + case TEGRA_CLK_FIXED: + case TEGRA_CLK_PLL: + case TEGRA_CLK_FIXED_DIV: + case TEGRA_CLK_DIV: + case TEGRA_CLK_GATE: + if (tclk->parent) { + tclk_parent = tegra210_car_clock_find(tclk->parent); + } + break; + case TEGRA_CLK_MUX: + tclk_parent = tegra210_car_clock_get_parent_mux(priv, tclk); + break; + } + + if (tclk_parent == NULL) + return NULL; + + return TEGRA_CLK_BASE(tclk_parent); +} + +static void * +tegra210_car_reset_acquire(device_t dev, const void *data, size_t len) +{ + struct tegra210_car_softc * const sc = device_private(dev); + struct tegra210_car_rst *rst; + + if (len != sc->sc_reset_cells * 4) + return NULL; + + const u_int reset_id = be32dec(data); + + if (reset_id >= __arraycount(tegra210_car_reset_regs) * 32) + return NULL; + + const u_int reg = reset_id / 32; + + rst = kmem_alloc(sizeof(*rst), KM_SLEEP); + rst->set_reg = tegra210_car_reset_regs[reg].set_reg; + rst->clr_reg = tegra210_car_reset_regs[reg].clr_reg; + rst->mask = __BIT(reset_id % 32); + + return rst; +} + +static void +tegra210_car_reset_release(device_t dev, void *priv) +{ + struct tegra210_car_rst *rst = priv; + + kmem_free(rst, sizeof(*rst)); +} + +static int +tegra210_car_reset_assert(device_t dev, void *priv) +{ + struct tegra210_car_softc * const sc = device_private(dev); + struct tegra210_car_rst *rst = priv; + + bus_space_write_4(sc->sc_bst, sc->sc_bsh, rst->set_reg, rst->mask); + + return 0; +} + +static int +tegra210_car_reset_deassert(device_t dev, void *priv) +{ + struct tegra210_car_softc * const sc = device_private(dev); + struct tegra210_car_rst *rst = priv; + + bus_space_write_4(sc->sc_bst, sc->sc_bsh, rst->clr_reg, rst->mask); + + return 0; +} Index: src/sys/arch/arm/nvidia/tegra210_carreg.h diff -u /dev/null src/sys/arch/arm/nvidia/tegra210_carreg.h:1.1 --- /dev/null Fri Jul 21 01:01:22 2017 +++ src/sys/arch/arm/nvidia/tegra210_carreg.h Fri Jul 21 01:01:22 2017 @@ -0,0 +1,549 @@ +/* $NetBSD: tegra210_carreg.h,v 1.1 2017/07/21 01:01:22 jmcneill Exp $ */ + +/*- + * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ARM_TEGRA210_CARREG_H +#define _ARM_TEGRA210_CARREG_H + +#define TEGRA210_REF_FREQ 38400000 + +#define CAR_RST_SOURCE_REG 0x00 +#define CAR_RST_SOURCE_WDT_EN __BIT(5) +#define CAR_RST_SOURCE_WDT_SEL __BIT(4) +#define CAR_RST_SOURCE_WDT_SYS_RST_EN __BIT(2) +#define CAR_RST_SOURCE_WDT_COP_RST_EN __BIT(1) +#define CAR_RST_SOURCE_WDT_CPU_RST_EN __BIT(0) + +#define CAR_CLK_OUT_ENB_L_REG 0x10 +#define CAR_CLK_OUT_ENB_H_REG 0x14 +#define CAR_CLK_OUT_ENB_U_REG 0x18 + +#define CAR_PLLP_BASE_REG 0xa0 +#define CAR_PLLP_BASE_BYPASS __BIT(31) +#define CAR_PLLP_BASE_ENABLE __BIT(30) +#define CAR_PLLP_BASE_REF_DIS __BIT(29) +#define CAR_PLLP_BASE_OVERRIDE __BIT(28) +#define CAR_PLLP_BASE_LOCK __BIT(27) +#define CAR_PLLP_BASE_DIVP __BITS(24,20) +#define CAR_PLLP_BASE_DIVN __BITS(17,10) +#define CAR_PLLP_BASE_DIVM __BITS(7,0) + +#define CAR_PLLP_OUTA_REG 0xa4 +#define CAR_PLLP_OUTA_OUT1_RATIO __BITS(15,8) +#define CAR_PLLP_OUTA_OUT1_OVRRIDE __BIT(2) +#define CAR_PLLP_OUTA_OUT1_CLKEN __BIT(1) +#define CAR_PLLP_OUTA_OUT1_RSTN __BIT(0) +#define CAR_PLLP_OUTB_REG 0xa8 +#define CAR_PLLP_OUTB_OUT4_RATIO __BITS(31,24) +#define CAR_PLLP_OUTB_OUT4_OVRRIDE __BIT(18) +#define CAR_PLLP_OUTB_OUT4_CLKEN __BIT(17) +#define CAR_PLLP_OUTB_OUT4_RSTN __BIT(16) +#define CAR_PLLP_OUTB_OUT3_RATIO __BITS(15,8) +#define CAR_PLLP_OUTB_OUT3_OVRRIDE __BIT(2) +#define CAR_PLLP_OUTB_OUT3_CLKEN __BIT(1) +#define CAR_PLLP_OUTB_OUT3_RSTN __BIT(0) +#define CAR_PLLP_OUTC_REG 0x67c +#define CAR_PLLP_OUTC_OUT5_RATIO __BITS(31,24) +#define CAR_PLLP_OUTC_OUT5_OVERRIDE __BIT(18) +#define CAR_PLLP_OUTC_OUT5_CLKEN __BIT(17) +#define CAR_PLLP_OUTC_OUT5_RSTN __BIT(16) +#define CAR_PLLP_MISC_REG 0xac + +#define CAR_PLLC_BASE_REG 0x80 +#define CAR_PLLC_BASE_BYPASS __BIT(31) +#define CAR_PLLC_BASE_ENABLE __BIT(30) +#define CAR_PLLC_BASE_REF_DIS __BIT(29) +#define CAR_PLLC_BASE_LOCK_OVERRIDE __BIT(27) +#define CAR_PLLC_BASE_LOCK __BIT(26) +#define CAR_PLLC_BASE_DIVP __BITS(24,20) +#define CAR_PLLC_BASE_DIVN __BITS(17,10) +#define CAR_PLLC_BASE_DIVM __BITS(7,0) + +#define CAR_PLLU_BASE_REG 0xc0 +#define CAR_PLLU_BASE_BYPASS __BIT(31) +#define CAR_PLLU_BASE_ENABLE __BIT(30) +#define CAR_PLLU_BASE_REF_DIS __BIT(29) +#define CAR_PLLU_BASE_LOCK __BIT(27) +#define CAR_PLLU_BASE_CLKENABLE_48M __BIT(25) +#define CAR_PLLU_BASE_OVERRIDE __BIT(24) +#define CAR_PLLU_BASE_CLKENABLE_ICUSB __BIT(23) +#define CAR_PLLU_BASE_CLKENABLE_HSIC __BIT(22) +#define CAR_PLLU_BASE_CLKENABLE_USB __BIT(21) +#define CAR_PLLU_BASE_DIVP __BITS(20,16) +#define CAR_PLLU_BASE_DIVN __BITS(15,8) +#define CAR_PLLU_BASE_DIVM __BITS(4,0) + +#define CAR_PLLD_BASE_REG 0xd0 +#define CAR_PLLD_BASE_BYPASS __BIT(31) +#define CAR_PLLD_BASE_ENABLE __BIT(30) +#define CAR_PLLD_BASE_REF_DIS __BIT(29) +#define CAR_PLLD_BASE_LOCK __BIT(27) +#define CAR_PLLD_BASE_DSIA_CLK_SRC __BIT(25) +#define CAR_PLLD_BASE_CSI_CLK_SRC __BIT(23) +#define CAR_PLLD_BASE_DIVP __BITS(22,20) +#define CAR_PLLD_BASE_DIVN __BITS(18,11) +#define CAR_PLLD_BASE_DIVM __BITS(7,0) + +#define CAR_PLLD_MISC_REG 0xdc + +#define CAR_PLLX_BASE_REG 0xe0 +#define CAR_PLLX_BASE_BYPASS __BIT(31) +#define CAR_PLLX_BASE_ENABLE __BIT(30) +#define CAR_PLLX_BASE_REF_DIS __BIT(29) +#define CAR_PLLX_BASE_LOCK __BIT(27) +#define CAR_PLLX_BASE_DIVP __BITS(24,20) +#define CAR_PLLX_BASE_DIVN __BITS(15,8) +#define CAR_PLLX_BASE_DIVM __BITS(7,0) + +#define CAR_PLLX_MISC_REG 0xe4 +#define CAR_PLLX_MISC_FO_G_DISABLE __BIT(28) +#define CAR_PLLX_MISC_PTS __BITS(23,22) +#define CAR_PLLX_MISC_LOCK_ENABLE __BIT(18) + +#define CAR_PLLE_BASE_REG 0xe8 +#define CAR_PLLE_BASE_ENABLE __BIT(31) +#define CAR_PLLE_BASE_LOCK_OVERRIDE __BIT(30) +#define CAR_PLLE_BASE_FDIV4B __BIT(29) +#define CAR_PLLE_BASE_DIVP_CML __BITS(28,24) +#define CAR_PLLE_BASE_EXT_SETUP_23_16 __BITS(23,16) +#define CAR_PLLE_BASE_DIVN __BITS(15,8) +#define CAR_PLLE_BASE_DIVM __BITS(7,0) + +#define CAR_PLLE_MISC_REG 0xec +#define CAR_PLLE_MISC_SETUP __BITS(31,16) +#define CAR_PLLE_MISC_ENABLE __BIT(15) +#define CAR_PLLE_MISC_IDDQ_SWCTL __BIT(14) +#define CAR_PLLE_MISC_IDDQ_OVERRIDE __BIT(13) +#define CAR_PLLE_MISC_LOCK __BIT(11) +#define CAR_PLLE_MISC_LOCK_ENABLE __BIT(9) + +#define CAR_PLLD2_BASE_REG 0x4b8 +#define CAR_PLLD2_BASE_BYPASS __BIT(31) +#define CAR_PLLD2_BASE_ENABLE __BIT(30) +#define CAR_PLLD2_BASE_REF_DIS __BIT(29) +#define CAR_PLLD2_BASE_FREQLOCK __BIT(28) +#define CAR_PLLD2_BASE_LOCK __BIT(27) +#define CAR_PLLD2_BASE_REF_SRC_SEL __BITS(26,25) +#define CAR_PLLD2_BASE_REF_SRC_SEL_PLL_D 0 +#define CAR_PLLD2_BASE_REF_SRC_SEL_PLL_D2 1 +#define CAR_PLLD2_BASE_LOCK_OVERRIDE __BIT(24) +#define CAR_PLLD2_BASE_DIVP __BITS(23,19) +#define CAR_PLLD2_BASE_IDDQ __BIT(18) +#define CAR_PLLD2_BASE_PTS __BIT(16) +#define CAR_PLLD2_BASE_DIVN __BITS(15,8) +#define CAR_PLLD2_BASE_DIVM __BITS(7,0) + +#define CAR_PLLD2_MISC_REG 0x4bc +#define CAR_PLLD2_MISC_LOCK_ENABLE __BIT(30) +#define CAR_PLLD2_MISC_KCP __BITS(26,25) +#define CAR_PLLD2_MISC_KVCO __BIT(24) +#define CAR_PLLD2_MISC_SETUP __BITS(23,0) + +#define CAR_CLKSRC_I2C1_REG 0x124 +#define CAR_CLKSRC_I2C2_REG 0x198 +#define CAR_CLKSRC_I2C3_REG 0x1b8 +#define CAR_CLKSRC_I2C4_REG 0x3c4 +#define CAR_CLKSRC_I2C5_REG 0x128 +#define CAR_CLKSRC_I2C6_REG 0x65c + +#define CAR_CLKSRC_I2C_SRC __BITS(31,29) +#define CAR_CLKSRC_I2C_SRC_PLLP_OUT0 0 +#define CAR_CLKSRC_I2C_SRC_PLLC2_OUT0 1 +#define CAR_CLKSRC_I2C_SRC_PLLC_OUT0 2 +#define CAR_CLKSRC_I2C_SRC_PLLC4_OUT0 3 +#define CAR_CLKSRC_I2C_SRC_PLLC4_OUT1 5 +#define CAR_CLKSRC_I2C_SRC_CLK_M 6 +#define CAR_CLKSRC_I2C_SRC_PLLC4_OUT2 7 +#define CAR_CLKSRC_I2C_DIV __BITS(15,0) + +#define CAR_CLKSRC_SPI1_REG 0x134 +#define CAR_CLKSRC_SPI2_REG 0x118 +#define CAR_CLKSRC_SPI3_REG 0x11c +#define CAR_CLKSRC_SPI4_REG 0x1b4 +#define CAR_CLKSRC_SPI5_REG 0x3c8 +#define CAR_CLKSRC_SPI6_REG 0x3cc + +#define CAR_CLKSRC_SPI_SRC __BITS(31,29) +#define CAR_CLKSRC_SPI_SRC_PLLP_OUT0 0 +#define CAR_CLKSRC_SPI_SRC_PLLC2_OUT0 1 +#define CAR_CLKSRC_SPI_SRC_PLLC_OUT0 2 +#define CAR_CLKSRC_SPI_SRC_PLLC4_OUT0 3 +#define CAR_CLKSRC_SPI_SRC_PLLC4_OUT1 5 +#define CAR_CLKSRC_SPI_SRC_CLK_M 6 +#define CAR_CLKSRC_SPI_SRC_PLLC4_OUT2 7 +#define CAR_CLKSRC_SPI_DIV __BITS(7,0) + +#define CAR_CLKSRC_UARTA_REG 0x178 +#define CAR_CLKSRC_UARTB_REG 0x17c +#define CAR_CLKSRC_UARTC_REG 0x1a0 +#define CAR_CLKSRC_UARTD_REG 0x1c0 + +#define CAR_CLKSRC_UART_SRC __BITS(31,29) +#define CAR_CLKSRC_UART_SRC_PLLP_OUT0 0 +#define CAR_CLKSRC_UART_SRC_PLLC2_OUT0 1 +#define CAR_CLKSRC_UART_SRC_PLLC_OUT0 2 +#define CAR_CLKSRC_UART_SRC_PLLC4_OUT0 3 +#define CAR_CLKSRC_UART_SRC_PLLC4_OUT1 5 +#define CAR_CLKSRC_UART_SRC_CLK_M 6 +#define CAR_CLKSRC_UART_SRC_PLLC4_OUT2 7 +#define CAR_CLKSRC_UART_DIV_ENB __BIT(24) +#define CAR_CLKSRC_UART_DIV __BITS(15,0) + +#define CAR_CLKSRC_SDMMC1_REG 0x150 +#define CAR_CLKSRC_SDMMC2_REG 0x154 +#define CAR_CLKSRC_SDMMC4_REG 0x164 +#define CAR_CLKSRC_SDMMC3_REG 0x1bc + +#define CAR_CLKSRC_SDMMC_SRC __BITS(31,29) +/* CAR_CLKSRC_SDMMC_SRC_* differs for each instance */ +#define CAR_CLKSRC_SDMMC_DIV __BITS(7,0) + +#define CAR_CLKSRC_DISP1_REG 0x138 +#define CAR_CLKSRC_DISP2_REG 0x13c +#define CAR_CLKSRC_DISP_SRC __BITS(31,29) +#define CAR_CLKSRC_DISP_SRC_PLLP_OUT0 0 +#define CAR_CLKSRC_DISP_SRC_PLLD_OUT 1 +#define CAR_CLKSRC_DISP_SRC_PLLD_OUT0 2 /* DISP1 only */ +#define CAR_CLKSRC_DISP_SRC_PLLD2_OUT0 5 +#define CAR_CLKSRC_DISP_SRC_CLK_M 6 + +#define CAR_CLKSRC_HOST1X_REG 0x180 +#define CAR_CLKSRC_HOST1X_SRC __BITS(31,29) +#define CAR_CLKSRC_HOST1X_IDLE_DIVISOR __BITS(15,8) +#define CAR_CLKSRC_HOST1X_CLK_DIVISOR __BITS(7,0) + +#define CAR_RST_DEV_L_SET_REG 0x300 +#define CAR_RST_DEV_L_CLR_REG 0x304 +#define CAR_RST_DEV_H_SET_REG 0x308 +#define CAR_RST_DEV_H_CLR_REG 0x30c +#define CAR_RST_DEV_U_SET_REG 0x310 +#define CAR_RST_DEV_U_CLR_REG 0x314 +#define CAR_RST_DEV_V_SET_REG 0x430 +#define CAR_RST_DEV_V_CLR_REG 0x434 +#define CAR_RST_DEV_W_SET_REG 0x438 +#define CAR_RST_DEV_W_CLR_REG 0x43c +#define CAR_RST_DEV_X_SET_REG 0x290 +#define CAR_RST_DEV_X_CLR_REG 0x294 +#define CAR_RST_DEV_Y_SET_REG 0x2a8 +#define CAR_RST_DEV_Y_CLR_REG 0x2ac + +#define CAR_CLK_ENB_L_SET_REG 0x320 +#define CAR_CLK_ENB_L_CLR_REG 0x324 +#define CAR_CLK_ENB_H_SET_REG 0x328 +#define CAR_CLK_ENB_H_CLR_REG 0x32c +#define CAR_CLK_ENB_U_SET_REG 0x330 +#define CAR_CLK_ENB_U_CLR_REG 0x334 +#define CAR_CLK_ENB_V_SET_REG 0x440 +#define CAR_CLK_ENB_V_CLR_REG 0x444 +#define CAR_CLK_ENB_W_SET_REG 0x448 +#define CAR_CLK_ENB_W_CLR_REG 0x44c +#define CAR_CLK_ENB_X_SET_REG 0x284 +#define CAR_CLK_ENB_X_CLR_REG 0x288 +#define CAR_CLK_ENB_Y_SET_REG 0x29c +#define CAR_CLK_ENB_Y_CLR_REG 0x2a0 + +#define CAR_DEV_L_CACHE2 __BIT(31) +#define CAR_DEV_L_I2S1 __BIT(30) +#define CAR_DEV_L_HOST1X __BIT(28) +#define CAR_DEV_L_DISP1 __BIT(27) +#define CAR_DEV_L_DISP2 __BIT(26) +#define CAR_DEV_L_ISP __BIT(23) +#define CAR_DEV_L_USBD __BIT(22) +#define CAR_DEV_L_VI __BIT(20) +#define CAR_DEV_L_I2S3 __BIT(18) +#define CAR_DEV_L_PWM __BIT(17) +#define CAR_DEV_L_SDMMC4 __BIT(15) +#define CAR_DEV_L_SDMMC1 __BIT(14) +#define CAR_DEV_L_I2C1 __BIT(12) +#define CAR_DEV_L_I2S2 __BIT(11) +#define CAR_DEV_L_SPDIF __BIT(10) +#define CAR_DEV_L_SDMMC2 __BIT(9) +#define CAR_DEV_L_GPIO __BIT(8) +#define CAR_DEV_L_UARTB __BIT(7) +#define CAR_DEV_L_UARTA __BIT(6) +#define CAR_DEV_L_TMR __BIT(5) +#define CAR_DEV_L_RTC __BIT(4) +#define CAR_DEV_L_ISPB __BIT(3) +#define CAR_DEV_L_TRIG_SYS __BIT(2) +#define CAR_DEV_L_COP __BIT(1) +#define CAR_DEV_L_CPU __BIT(0) + +#define CAR_DEV_U_XUSB_DEV __BIT(31) +#define CAR_DEV_U_DEV1_OUT __BIT(30) +#define CAR_DEV_U_DEV2_OUT __BIT(29) +#define CAR_DEV_U_SUS_OUT __BIT(28) +#define CAR_DEV_U_MSENC __BIT(27) +#define CAR_DEV_U_XUSB_HOST __BIT(25) +#define CAR_DEV_U_CRAM2 __BIT(24) +#define CAR_DEV_U_IRAMD __BIT(23) +#define CAR_DEV_U_IRAMC __BIT(22) +#define CAR_DEV_U_IRAMB __BIT(21) +#define CAR_DEV_U_IRAMA __BIT(20) +#define CAR_DEV_U_TSEC __BIT(19) +#define CAR_DEV_U_DSIB __BIT(18) +#define CAR_DEV_U_I2C_SLOW __BIT(17) +#define CAR_DEV_U_DTV __BIT(15) +#define CAR_DEV_U_SOC_THERM __BIT(14) +#define CAR_DEV_U_PCIEXCLK __BIT(10) +#define CAR_DEV_U_CSITE __BIT(9) +#define CAR_DEV_U_AFI __BIT(8) +#define CAR_DEV_U_PCIE __BIT(6) +#define CAR_DEV_U_SDMMC3 __BIT(5) +#define CAR_DEV_U_SPI4 __BIT(4) +#define CAR_DEV_U_I2C3 __BIT(3) +#define CAR_DEV_U_UARTD __BIT(1) + +#define CAR_DEV_H_BSEV __BIT(31) +#define CAR_DEV_H_USB2 __BIT(26) +#define CAR_DEV_H_EMC __BIT(25) +#define CAR_DEV_H_MIPI_CAL __BIT(24) +#define CAR_DEV_H_UARTC __BIT(23) +#define CAR_DEV_H_I2C2 __BIT(22) +#define CAR_DEV_H_CSI __BIT(20) +#define CAR_DEV_H_DSI __BIT(16) +#define CAR_DEV_H_I2C5 __BIT(15) +#define CAR_DEV_H_SPI3 __BIT(14) +#define CAR_DEV_H_SPI2 __BIT(12) +#define CAR_DEV_H_SPI1 __BIT(9) +#define CAR_DEV_H_KFUSE __BIT(8) +#define CAR_DEV_H_FUSE __BIT(7) +#define CAR_DEV_H_PMC __BIT(6) +#define CAR_DEV_H_STAT_MON __BIT(5) +#define CAR_DEV_H_APBDMA __BIT(2) +#define CAR_DEV_H_AHBDMA __BIT(1) +#define CAR_DEV_H_MEM __BIT(0) + +#define CAR_DEV_V_HDA __BIT(29) +#define CAR_DEV_V_SATA __BIT(28) +#define CAR_DEV_V_SATA_OOB __BIT(27) +#define CAR_DEV_V_EXTPERIPH3 __BIT(26) +#define CAR_DEV_V_EXTPERIPH2 __BIT(25) +#define CAR_DEV_V_EXTPERIPH1 __BIT(24) +#define CAR_DEV_V_ACTMON __BIT(23) +#define CAR_DEV_V_SPDIF_DOUBLER __BIT(22) +#define CAR_DEV_V_ATOMICS __BIT(16) +#define CAR_DEV_V_HDA2CODEC_2X __BIT(15) +#define CAR_DEV_V_APB2APE __BIT(11) +#define CAR_DEV_V_AHUB __BIT(10) +#define CAR_DEV_V_I2C4 __BIT(7) +#define CAR_DEV_V_I2S5 __BIT(6) +#define CAR_DEV_V_I2S4 __BIT(5) +#define CAR_DEV_V_TSENSOR __BIT(4) +#define CAR_DEV_V_MSELECT __BIT(3) +#define CAR_DEV_V_CPULP __BIT(1) +#define CAR_DEV_V_CPUG __BIT(0) + +#define CAR_DEV_W_MC1 __BIT(30) +#define CAR_DEV_W_EMC_DLL __BIT(29) +#define CAR_DEV_W_XUSB_SS __BIT(28) +#define CAR_DEV_W_DVFS __BIT(27) +#define CAR_DEV_W_ENTROPY __BIT(21) +#define CAR_DEV_W_DSIB_LP __BIT(20) +#define CAR_DEV_W_DSIA_LP __BIT(19) +#define CAR_DEV_W_CILEF __BIT(18) +#define CAR_DEV_W_CILCD __BIT(17) +#define CAR_DEV_W_CILAB __BIT(16) +#define CAR_DEV_W_XUSB __BIT(15) +#define CAR_DEV_W_XUSB_PADCTL __BIT(14) +#define CAR_DEV_W_MIPI_IOBIST __BIT(13) +#define CAR_DEV_W_SATA_IOBIST __BIT(12) +#define CAR_DEV_W_EMC_IOBIST __BIT(10) +#define CAR_DEV_W_PCIE2_IOBIST __BIT(9) +#define CAR_DEV_W_CEC __BIT(8) +#define CAR_DEV_W_PCIERX5 __BIT(7) +#define CAR_DEV_W_PCIERX4 __BIT(6) +#define CAR_DEV_W_PCIERX3 __BIT(5) +#define CAR_DEV_W_PCIERX2 __BIT(4) +#define CAR_DEV_W_PCIERX1 __BIT(3) +#define CAR_DEV_W_PCIERX0 __BIT(2) +#define CAR_DEV_W_SATACOLD __BIT(1) +#define CAR_DEV_W_HDA2HDMICODEC __BIT(0) + +#define CAR_DEV_X_PLLG_REF __BIT(29) +#define CAR_DEV_X_PLLA_ADSP __BIT(28) +#define CAR_DEV_X_PLLP_ADSP __BIT(27) +#define CAR_DEV_X_HPLL_ADSP __BIT(26) +#define CAR_DEV_X_DBGAPB __BIT(25) +#define CAR_DEV_X_GPU __BIT(24) +#define CAR_DEV_X_SOR1 __BIT(23) +#define CAR_DEV_X_SOR0 __BIT(22) +#define CAR_DEV_X_DPAUX __BIT(21) +#define CAR_DEV_X_VIC __BIT(18) +#define CAR_DEV_X_UART_FST_MIPI_CAL __BIT(17) +#define CAR_DEV_X_EMC_DLL __BIT(14) +#define CAR_DEV_X_VIM2_CLK __BIT(11) +#define CAR_DEV_X_MC_BBC __BIT(10) +#define CAR_DEV_X_MC_CPU __BIT(9) +#define CAR_DEV_X_MC_CBPA __BIT(8) +#define CAR_DEV_X_MC_CAPA __BIT(7) +#define CAR_DEV_X_I2C6 __BIT(6) +#define CAR_DEV_X_CAM_MCLK2 __BIT(5) +#define CAR_DEV_X_CAM_MCLK __BIT(4) +#define CAR_DEV_X_ETR __BIT(3) +#define CAR_DEV_X_SPARE __BIT(0) + +#define CAR_CCLKG_BURST_POLICY_REG 0x368 +#define CAR_CCLKG_BURST_POLICY_CPU_STATE __BITS(31,28) +#define CAR_CCLKG_BURST_POLICY_CPU_STATE_IDLE 1 +#define CAR_CCLKG_BURST_POLICY_CPU_STATE_RUN 2 +#define CAR_CCLKG_BURST_POLICY_CWAKEUP_IDLE_SOURCE __BITS(3,0) +#define CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_CLKM 0 +#define CAR_CCLKG_BURST_POLICY_CWAKEUP_SOURCE_PLLX_OUT0_LJ 8 + +#define CAR_CLKSRC_TSENSOR_REG 0x3b8 +#define CAR_CLKSRC_TSENSOR_SRC __BITS(31,29) +#define CAR_CLKSRC_TSENSOR_SRC_CLK_M 4 +#define CAR_CLKSRC_TSENSOR_DIV __BITS(7,0) + +#define CAR_CLKSRC_HDA2CODEC_2X_REG 0x3e4 +#define CAR_CLKSRC_HDA2CODEC_2X_SRC __BITS(31,29) +#define CAR_CLKSRC_HDA2CODEC_2X_DIV __BITS(7,0) + +#define CAR_CLKSRC_SATA_OOB_REG 0x420 +#define CAR_CLKSRC_SATA_OOB_SRC __BITS(31,29) +#define CAR_CLKSRC_SATA_OOB_DIV __BITS(7,0) + +#define CAR_CLKSRC_SATA_REG 0x424 +#define CAR_CLKSRC_SATA_SRC __BITS(31,29) +#define CAR_CLKSRC_SATA_AUX_CLK_ENB __BIT(24) +#define CAR_CLKSRC_SATA_DIV __BITS(7,0) + +#define CAR_CLKSRC_HDA_REG 0x428 +#define CAR_CLKSRC_HDA_SRC __BITS(31,29) +#define CAR_CLKSRC_HDA_DIV __BITS(7,0) + +#define CAR_UTMIP_PLL_CFG0_REG 0x480 + +#define CAR_UTMIP_PLL_CFG1_REG 0x484 +#define CAR_UTMIP_PLL_CFG1_ENABLE_DLY_COUNT __BITS(31,27) +#define CAR_UTMIP_PLL_CFG1_PLLU_POWERUP __BIT(17) +#define CAR_UTMIP_PLL_CFG1_PLLU_POWERDOWN __BIT(16) +#define CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERUP __BIT(15) +#define CAR_UTMIP_PLL_CFG1_PLL_ENABLE_POWERDOWN __BIT(14) +#define CAR_UTMIP_PLL_CFG1_XTAL_FREQ_COUNT __BITS(11,0) + +#define CAR_UTMIP_PLL_CFG2_REG 0x488 +#define CAR_UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT __BITS(23,18) +#define CAR_UTMIP_PLL_CFG2_STABLE_COUNT __BITS(17,6) +#define CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERUP __BIT(5) +#define CAR_UTMIP_PLL_CFG2_PD_SAMP_C_POWERDOWN __BIT(4) +#define CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERUP __BIT(3) +#define CAR_UTMIP_PLL_CFG2_PD_SAMP_B_POWERDOWN __BIT(2) +#define CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERUP __BIT(1) +#define CAR_UTMIP_PLL_CFG2_PD_SAMP_A_POWERDOWN __BIT(0) + +#define CAR_PLLE_AUX_REG 0x48c +#define CAR_PLLE_AUX_SS_SEQ_INCLUDE __BIT(31) +#define CAR_PLLE_AUX_REF_SEL_PLLREFE __BIT(28) +#define CAR_PLLE_AUX_SEQ_STATE __BITS(27,26) +#define CAR_PLLE_AUX_SEQ_START_STATE __BIT(25) +#define CAR_PLLE_AUX_SEQ_ENABLE __BIT(24) +#define CAR_PLLE_AUX_SS_DLY __BITS(23,16) +#define CAR_PLLE_AUX_LOCK_DLY __BITS(15,8) +#define CAR_PLLE_AUX_FAST_PT __BIT(7) +#define CAR_PLLE_AUX_SS_SWCTL __BIT(6) +#define CAR_PLLE_AUX_CONFIG_SWCTL __BIT(5) +#define CAR_PLLE_AUX_ENABLE_SWCTL __BIT(4) +#define CAR_PLLE_AUX_USE_LOCKDET __BIT(3) +#define CAR_PLLE_AUX_REF_SRC __BIT(2) +#define CAR_PLLE_AUX_CML1_OEN __BIT(1) +#define CAR_PLLE_AUX_CML0_OEN __BIT(0) + +#define CAR_SATA_PLL_CFG0_REG 0x490 +#define CAR_SATA_PLL_CFG0_SEQ_STATE __BITS(27,26) +#define CAR_SATA_PLL_CFG0_SEQ_START_STATE __BIT(25) +#define CAR_SATA_PLL_CFG0_SEQ_ENABLE __BIT(24) +#define CAR_SATA_PLL_CFG0_SEQ_PADPLL_PD_INPUT_VALUE __BIT(7) +#define CAR_SATA_PLL_CFG0_SEQ_LANE_PD_INPUT_VALUE __BIT(6) +#define CAR_SATA_PLL_CFG0_SEQ_RESET_INPUT_VALUE __BIT(5) +#define CAR_SATA_PLL_CFG0_SEQ_IN_SWCTL __BIT(4) +#define CAR_SATA_PLL_CFG0_PADPLL_USE_LOCKDET __BIT(2) +#define CAR_SATA_PLL_CFG0_PADPLL_RESET_OVERRIDE_VALUE __BIT(1) +#define CAR_SATA_PLL_CFG0_PADPLL_RESET_SWCTL __BIT(0) + +#define CAR_SATA_PLL_CFG1_REG 0x494 +#define CAR_SATA_PLL_CFG1_LANE_IDDQ2_PADPLL_RESET_DLY __BITS(31,24) +#define CAR_SATA_PLL_CFG1_PADPLL_IDDQ2LANE_SLUMBER_DLY __BITS(23,16) +#define CAR_SATA_PLL_CFG1_PADPLL_PU_POST_DLY __BITS(15,8) +#define CAR_SATA_PLL_CFG1_LANE_IDDQ2_PADPLL_IDDQ_DLY __BITS(7,0) + +#define CAR_PLLREFE_BASE_REG 0x4c4 +#define CAR_PLLREFE_BASE_BYPASS __BIT(31) +#define CAR_PLLREFE_BASE_ENABLE __BIT(30) +#define CAR_PLLREFE_BASE_REF_DIS __BIT(29) +#define CAR_PLLREFE_BASE_KCP __BITS(28,27) +#define CAR_PLLREFE_BASE_KVCO __BIT(26) +#define CAR_PLLREFE_BASE_DIVP __BITS(20,16) +#define CAR_PLLREFE_BASE_DIVN __BITS(15,8) +#define CAR_PLLREFE_BASE_DIVM __BITS(7,0) + +#define CAR_PLLREFE_MISC_REG 0x4c8 +#define CAR_PLLREFE_MISC_LOCK_ENABLE __BIT(30) +#define CAR_PLLREFE_MISC_LOCK_OVERRIDE __BIT(29) +#define CAR_PLLREFE_MISC_FREQLOCK __BIT(28) +#define CAR_PLLREFE_MISC_LOCK __BIT(27) +#define CAR_PLLREFE_MISC_PTS __BITS(26,25) +#define CAR_PLLREFE_MISC_IDDQ __BIT(24) +#define CAR_PLLREFE_MISC_SETUP __BITS(23,0) + +#define CAR_XUSBIO_PLL_CFG0_REG 0x51c +#define CAR_XUSBIO_PLL_CFG0_SEQ_STATE __BITS(27,26) +#define CAR_XUSBIO_PLL_CFG0_SEQ_START_STATE __BIT(25) +#define CAR_XUSBIO_PLL_CFG0_SEQ_ENABLE __BIT(24) +#define CAR_XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET __BIT(6) +#define CAR_XUSBIO_PLL_CFG0_SEQ_RESET_INPUT_VALUE __BIT(5) +#define CAR_XUSBIO_PLL_CFG0_SEQ_IN_SWCTL __BIT(4) +#define CAR_XUSBIO_PLL_CFG0_CLK_ENABLE_OVERRIDE __BIT(3) +#define CAR_XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL __BIT(2) +#define CAR_XUSBIO_PLL_CFG0_PADPLL_RESET_OVERRIDE_VALUE __BIT(1) +#define CAR_XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL __BIT(0) + +#define CAR_CLKSRC_XUSB_HOST_REG 0x600 +#define CAR_CLKSRC_XUSB_HOST_SRC __BITS(31,29) +#define CAR_CLKSRC_XUSB_HOST_DIV __BITS(7,0) + +#define CAR_CLKSRC_XUSB_FALCON_REG 0x604 +#define CAR_CLKSRC_XUSB_FALCON_SRC __BITS(31,29) +#define CAR_CLKSRC_XUSB_FALCON_DIV __BITS(7,0) + +#define CAR_CLKSRC_XUSB_FS_REG 0x608 +#define CAR_CLKSRC_XUSB_FS_SRC __BITS(31,29) +#define CAR_CLKSRC_XUSB_FS_DIV __BITS(7,0) + +#define CAR_CLKSRC_XUSB_SS_REG 0x610 +#define CAR_CLKSRC_XUSB_SS_SRC __BITS(31,29) +#define CAR_CLKSRC_XUSB_SS_HS_CLK_BYPASS __BIT(25) +#define CAR_CLKSRC_XUSB_SS_SS_CLK_BYPASS __BIT(24) +#define CAR_CLKSRC_XUSB_SS_DIV __BITS(7,0) + +#define CAR_CLKSRC_SOC_THERM_REG 0x644 +#define CAR_CLKSRC_SOC_THERM_SRC __BITS(31,29) +#define CAR_CLKSRC_SOC_THERM_SRC_PLLP_OUT0 2 +#define CAR_CLKSRC_SOC_THERM_DDLL_SEL __BITS(11,10) +#define CAR_CLKSRC_SOC_THERM_DIV __BITS(7,0) + +#endif /* _ARM_TEGRA210_CARREG_H */