alarm-tegra-x1 / device-tree/tegra210-nintendo-switch.dts

raw file 31331 bytes
// SPDX-License-Identifier: GPL-2.0
/*
 * Nintendo Switch (Tegra X1 "ODIN" / ODNX02-A2) — mainline device tree.
 *
 * Stage 1: enough hardware to boot, talk, and mount a root filesystem.
 *   - CPU / GIC / timers / PMC come from tegra210.dtsi
 *   - console on UART-A (the retail Switch has no wired UART, so this is only
 *     useful for a modded board; the real console is the USB gadget below)
 *   - microSD (sdmmc1) so the ext4 root can be mounted
 *   - XUSB device controller (xudc) so the switchroot initramfs can create the
 *     configfs ACM gadget that gives us /dev/ttyGS0 — the only practical
 *     console on a retail unit
 *
 * Deliberately NOT here yet (stage 2/3): the MAX77620 PMIC + its regulators,
 * the BCM4356 over PCIe, the DSI panel and the PWM backlight. Fixed regulators
 * stand in for the PMIC so stage 1 does not depend on a driver that has not
 * been validated yet.
 *
 * Note the path references such as &{/mmc@700b0000}: tegra210.dtsi defines
 * these nodes without labels, so they can only be addressed by absolute path.
 */

/dts-v1/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/gpio/tegra-gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/mfd/max77620.h>

#include "tegra210.dtsi"

/ {
	model = "Nintendo Switch (ODNX02-A2)";
	compatible = "nintendo,switch", "nvidia,tegra210";

	aliases {
		serial0 = &uarta;
		mmc0 = "/mmc@700b0000";
	};

	chosen {
		/*
		 * No stdout-path here: the obvious target (serial0 = &uarta) is
		 * disabled on this board, so pointing stdout-path at it just leaves
		 * the kernel without a console. The console is selected explicitly
		 * with console=tty0 on the kernel command line instead.
		 *
		 * access=m2 is what the switchroot initramfs greps for; usb_logging
		 * makes it create the ACM gadget. Keep both: without usb_logging the
		 * unit boots silent, and without access=m2 it will not hand over.
		 */
		bootargs = "console=tty0 keep_bootcon loglevel=7 rootwait rw access=m2 usb_logging auto_rootdev_disable";

		#address-cells = <2>;
		#size-cells = <2>;

		/*
		 * The framebuffer hekate/U-Boot already set up, so a failed boot is
		 * not silent. of_platform looks for exactly this (a "simple-framebuffer"
		 * child of /chosen) and simpledrm binds to it, giving fb0 -> fbcon ->
		 * console=tty0 on the built-in display, before any display driver runs.
		 *
		 * Geometry is the panel's native orientation: 720x1280 with the DC
		 * rotating 90 degrees (nvidia,out-rotation = 90 in the L4T tree), so
		 * the scanout buffer is portrait. Address/size match the L4T kernel
		 * command line (tegra_fbmem=0x400000@0xf5a00000) and switch-fb.c.
		 */
		framebuffer@f5a00000 {
			compatible = "simple-framebuffer";
			reg = <0x0 0xf5a00000 0x0 0x00400000>;
			width = <720>;
			height = <1280>;
			stride = <2880>;
			format = "a8r8g8b8";
		};
	};

	/*
	 * Keep the allocator off the framebuffer region: it lives inside the
	 * memory@80000000 range but belongs to the bootloader.
	 *
	 * Deliberately NOT "no-map": simpledrm ioremaps this range, and keeping it
	 * in the linear map removes a way for that mapping to fail.
	 */
	reserved-memory {
		#address-cells = <2>;
		#size-cells = <2>;
		ranges;

		framebuffer@f5a00000 {
			reg = <0x0 0xf5a00000 0x0 0x00400000>;
		};

		/*
		 * The same 2 MB region at 0xb0000000 that the L4T device tree
		 * reserves (there as compatible = "nvidia,ramoops"). The kernel has
		 * no console on this board and dies before userspace, so pstore is
		 * the only way to see the boot log: PSTORE_CONSOLE streams it into
		 * this buffer continuously, so a hang is recorded too, not just a
		 * panic. The boot script copies it to the SD for reading on a PC.
		 */
		ramoops@b0000000 {
			compatible = "ramoops";
			reg = <0x0 0xb0000000 0x0 0x00200000>;
			record-size = <0x20000>;	/* 128 KiB panic/dmesg record */
			console-size = <0x80000>;	/* 512 KiB continuous log */
			pmsg-size = <0x20000>;		/* 128 KiB */
			max-reason = <2>;		/* KMSG_DUMP_OOPS */
		};
	};

	memory@80000000 {
		device_type = "memory";
		/*
		 * 2 GiB, matching the L4T device tree ("reg = <0x0 0x80000000 0x0
		 * 0x80000000>"). Do NOT widen this to the module's physical 4 GiB:
		 * Tegra X1 does not map DRAM as one contiguous 4 GiB block from
		 * 0x80000000, so a 4 GiB node hands the kernel memory it cannot
		 * address and it dies during memblock/paging init — before any
		 * console exists, which is a completely silent failure.
		 * U-Boot patches this node with the real banks when it boots Linux.
		 */
		reg = <0x0 0x80000000 0x0 0x80000000>;
	};

	/*
	 * 32.768 kHz clock feeding the PMC. tegra210.dtsi's pmc@7000e400
	 * references &clk32k_in, so every T210 board has to provide it or dtc
	 * fails with "Reference to non-existent node or label".
	 */
	clk32k_in: clock-32k {
		compatible = "fixed-clock";
		clock-frequency = <32768>;
		#clock-cells = <0>;
	};

	/*
	 * PSCI + CPU enable-method.
	 *
	 * tegra210.dtsi declares the CPUs but provides NEITHER an enable-method nor
	 * a /psci node -- every T210 board has to add both (see tegra210-p3450-0000
	 * and tegra210-smaug). Without them arm64 never sets cpu_ops, and SMP
	 * bring-up dereferences a NULL pointer before console init: a completely
	 * silent death with nothing in the printk buffer and no output anywhere.
	 * This was the reason the first boots produced nothing at all.
	 *
	 * bl31.bin (ATF, loaded by hekate) provides the SMC-based PSCI service.
	 */
	cpus {
		cpu@0 {
			enable-method = "psci";
		};

		cpu@1 {
			enable-method = "psci";
		};

		cpu@2 {
			enable-method = "psci";
		};

		cpu@3 {
			enable-method = "psci";
		};
	};

	/*
	 * The arm64 arch timer needs the counter frequency from either CNTFRQ_EL0
	 * (programmed by firmware) or this property. tegra210.dtsi omits it, and
	 * this U-Boot does not set CNTFRQ_EL0 -- the L4T bootstack instead relies
	 * on the device tree, which is why the L4T tree carries
	 * clock-frequency = <0x124f800>.
	 *
	 * Without it arch_timer_detect_rate() fails, the kernel has no clock, and
	 * calibrate_delay() spins forever waiting for a jiffy that never arrives.
	 * That is a silent hang -- and with no timer there is no lockup detection,
	 * so no panic and no pstore dump either. It matches every observation,
	 * including why the identical kernel boots fine under QEMU (which provides
	 * the counter) and why it never reached userspace here.
	 *
	 * 19200000 Hz (19.2 MHz) is the T210 system counter.
	 */
	timer {
		clock-frequency = <19200000>;
	};

	psci {
		compatible = "arm,psci-1.0";
		method = "smc";
	};

	/* Stage-1 stand-ins for the MAX77620 rails. */
	vdd_3v3_sys: regulator-vdd-3v3-sys {
		compatible = "regulator-fixed";
		regulator-name = "vdd_3v3_sys";
		regulator-min-microvolt = <3300000>;
		regulator-max-microvolt = <3300000>;
		regulator-always-on;
	};

	vdd_1v8_sys: regulator-vdd-1v8-sys {
		compatible = "regulator-fixed";
		regulator-name = "vdd_1v8_sys";
		regulator-min-microvolt = <1800000>;
		regulator-max-microvolt = <1800000>;
		regulator-always-on;
	};

	vdd_1v05_pex: regulator-vdd-1v05-pex {
		compatible = "regulator-fixed";
		regulator-name = "vdd_1v05_pex";
		regulator-min-microvolt = <1050000>;
		regulator-max-microvolt = <1050000>;
		regulator-always-on;
	};

	/*
	 * MicroSD. This is the card the root filesystem lives on, so it is the
	 * single most important peripheral for stage 1.
	 */
	mmc@700b0000 {
		status = "okay";
		bus-width = <4>;

		/*
		 * Card detect. The L4T tree gives this node
		 * cd-gpios = <0x5c 0xc9 0x00> plus cd-inverted: phandle 0x5c is the
		 * GPIO controller and 0xc9 == 201 == TEGRA_GPIO(Z, 1), active low.
		 * Mainline's own T210 board (Jetson Nano, tegra210-p3450-0000) uses
		 * exactly the same pin for SDMMC1.
		 *
		 * Without it the SDHCI controller falls back to its own card-detect
		 * bit, which is not wired on this board. It reports "no card", no
		 * mmcblk0 is ever created, and the kernel dies at
		 * "VFS: Unable to mount root fs on unknown-block(0,0)".
		 */
		cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
		disable-wp;

		/*
		 * The SD pads run at 3.3 V and there is no way to switch them: the
		 * rails below are regulator-fixed stand-ins, not the real MAX77620.
		 * So report 3.3 V for the I/O rail too -- otherwise the core asks
		 * for a 1.8 V UHS signal the hardware cannot produce -- and mark
		 * 1.8 V unsupported so the card stays at high speed.
		 */
		no-1-8-v;
		vmmc-supply = <&vdd_3v3_sys>;
		vqmmc-supply = <&vdd_3v3_sys>;
	};

	/* USB-C port: device mode (the console). */
	padctl@7009f000 {
		status = "okay";

		avdd-pll-utmip-supply = <&vdd_1v8_sys>;
		avdd-pll-uerefe-supply = <&vdd_1v05_pex>;
		dvdd-pex-pll-supply = <&vdd_1v05_pex>;
		hvdd-pex-pll-e-supply = <&vdd_1v8_sys>;

		pads {
			usb2 {
				status = "okay";

				lanes {
					usb2-0 {
						nvidia,function = "xusb";
						status = "okay";
					};

					usb2-1 {
						nvidia,function = "xusb";
						status = "okay";
					};

					usb2-2 {
						nvidia,function = "xusb";
						status = "okay";
					};
				};
			};

			pcie {
				status = "okay";

				lanes {
					pcie-0 {
						nvidia,function = "pcie-x1";
						status = "okay";
					};

					pcie-1 {
						nvidia,function = "pcie-x4";
						status = "okay";
					};

					pcie-2 {
						nvidia,function = "pcie-x4";
						status = "okay";
					};

					pcie-3 {
						nvidia,function = "pcie-x4";
						status = "okay";
					};

					pcie-4 {
						nvidia,function = "pcie-x4";
						status = "okay";
					};
				};
			};
		};

		ports {
			/*
			 * The USB-C port. It is the console, so it must come up as
			 * a *device*. mode "otg" (or "peripheral") is mandatory to
			 * pair with usb-role-switch, which the driver requires --
			 * without that property it returns -EINVAL and the whole
			 * padctl fails to probe:
			 *
			 *   usb2-0: usb-role-switch not found for otg mode
			 *   tegra-xusb-padctl: failed to setup XUSB ports: -22
			 *
			 * role-switch-default-mode = "peripheral" makes the port
			 * default to the device role without needing an ID pin or
			 * an external role-switch driver.
			 */
			usb2-0 {
				status = "okay";
				mode = "otg";
				usb-role-switch;
				role-switch-default-mode = "peripheral";
				vbus-supply = <&vdd_3v3_sys>;
			};

			usb2-1 {
				status = "okay";
				mode = "host";
			};

			usb2-2 {
				status = "okay";
				mode = "host";
			};
		};
	};

	usb@700d0000 {
		status = "okay";
		phys = <&{/padctl@7009f000/pads/usb2/lanes/usb2-0}>;
		/*
		 * The driver looks this PHY up by name: tegra_xudc_probe() builds
		 * "usb2-%d" and calls devm_phy_optional_get(), then registers its
		 * VBUS notifier on the usb_phy it finds. Because the lookup is
		 * *optional*, a wrong name here fails silently: usbphy[0] stays
		 * NULL, the notifier is never registered, xudc->device_mode never
		 * becomes true, and the device never connects to a host -- the
		 * gadget binds and /dev/ttyGS0 appears, but nothing enumerates.
		 */
		phy-names = "usb2-0";
		/*
		 * The published USB gadget that /sbin/init builds is what we
		 * actually want here, not a role switch.
		 */
		dr_mode = "peripheral";
	};

	usb@70090000 {
		status = "okay";
		phys = <&{/padctl@7009f000/pads/usb2/lanes/usb2-0}>,
		       <&{/padctl@7009f000/pads/usb2/lanes/usb2-1}>,
		       <&{/padctl@7009f000/pads/usb2/lanes/usb2-2}>;
		phy-names = "usb2-0", "usb2-1", "usb2-2";
	};

	/*
	 * PCIe, for the BCM4356 WiFi.
	 *
	 * The L4T tree puts the WiFi on PCIe port 1 (`pci@2,0`), one lane, on the
	 * padctl's `pcie-0` lane, and leaves port 0 unused with
	 * `nvidia,sw-link-disable`. Mainline wants exactly three supplies on T210
	 * -- see tegra_pcie_get_regulators() in drivers/pci/controller/pci-tegra.c,
	 * which matches "nvidia,tegra210-pcie" and asks for hvddio-pex,
	 * dvddio-pex and vddio-pex-ctl and nothing else.
	 *
	 * Without this node the controller stays disabled, nothing is logged
	 * about PCIe at all, and there is no wlan0.
	 */
	pcie@1003000 {
		/*
		 * Disabled again. switchroot's mainline tree enables both ports and
		 * carries lanes pcie-1..pcie-4, and both of those were gaps here --
		 * but adding them did NOT make the endpoint answer config cycles.
		 * The kernel still panics on the first config read:
		 *
		 *   SError Interrupt ... pci_generic_config_read
		 *   tegra_pcie_config_read / tegra_pcie_probe
		 *
		 * So the missing lanes were not the cause. What is established, for
		 * whoever picks this up:
		 *
		 *   - the controller must be enabled, and it trains the link
		 *   - the BCM4356 is powered from MAX77620 sd3/ldo1/ldo7; ldo1
		 *     ("vdd-pex") is off in L4T until a consumer enables it, and that
		 *     is what made the link train at all
		 *   - the gating pins (wifi_en_ph0, wifi_rst_ph1) are muxed and driven
		 *   - the endpoint still does not respond, so the next lead is a
		 *     proper reset pulse on wifi_rst after the rails are stable,
		 *     rather than driving it high from the first instant
		 *
		 * The ports, lanes and supplies below are kept so re-enabling is one
		 * line once the endpoint is understood.
		 */
		status = "disabled";

		hvddio-pex-supply = <&vdd_1v8_sys>;
		dvddio-pex-supply = <&vdd_1v05_pex>;
		vddio-pex-ctl-supply = <&vdd_1v8_sys>;

		pinctrl-names = "default";
		pinctrl-0 = <&wifi_pins>;

		pci@1,0 {
			status = "okay";
			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>,
			       <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>,
			       <&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>,
			       <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
			phy-names = "pcie-0", "pcie-1", "pcie-2", "pcie-3";
			nvidia,num-lanes = <4>;
		};

		pci@2,0 {
			status = "okay";
			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>;
			phy-names = "pcie-0";
			nvidia,num-lanes = <1>;
		};
	};

	/*
	 * The BCM4356 is gated by two dedicated Tegra pins, and nothing
	 * configures them in mainline. Both show up unconfigured in the pinctrl
	 * debugfs pinconf dump, the chip is therefore never enabled and never
	 * released from reset, and PCIe reports "link 1 down, ignoring" -- the
	 * controller is fine, the device is dead.
	 *
	 * mainline's pinctrl-tegra210.c knows both pins by name (they are real
	 * PINGROUP entries). Mux them as GPIO outputs; the hogs below then drive
	 * them high. The L4T tree configures the same two pins the same way.
	 */
	pinmux@700008d4 {
		wifi_pins: wifi-pins {
			wifi-en-ph0 {
				nvidia,pins = "wifi_en_ph0";
				nvidia,function = "rsvd0";
				nvidia,pull = <TEGRA_PIN_PULL_UP>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
				nvidia,open-drain = <TEGRA_PIN_DISABLE>;
			};

			wifi-rst-ph1 {
				nvidia,pins = "wifi_rst_ph1";
				nvidia,function = "rsvd0";
				nvidia,pull = <TEGRA_PIN_PULL_UP>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
				nvidia,open-drain = <TEGRA_PIN_DISABLE>;
			};
		};

		/*
		 * i2c3 leaves the SoC on the gen3_i2c pins. The vendor DT and
		 * switchroot's both configure these two; switchroot does it via
		 * a single pinmux_default group applied by the pinmux node, we
		 * do it per device. Without it the bus is left tri-stated, the
		 * touchscreen at 0x49 never acknowledges, and probe fails with
		 * -110.
		 */
		i2c3_pins: i2c3-pins {
			gen3-i2c-scl-pf0 {
				nvidia,pins = "gen3_i2c_scl_pf0";
				nvidia,function = "i2c3";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
			};

			gen3-i2c-sda-pf1 {
				nvidia,pins = "gen3_i2c_sda_pf1";
				nvidia,function = "i2c3";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
				nvidia,io-high-voltage = <TEGRA_PIN_DISABLE>;
			};
		};

		/*
		 * The touchscreen's interrupt pin. It is deliberately not used
		 * as an interrupt (see the node below), but it still has to be
		 * terminated: the vendor DT configures it as a GPIO input with
		 * a pull-up, and leaving it floating is what made the
		 * level-low interrupt assert continuously.
		 */
		touch_pins: touch-pins {
			touch-int-px1 {
				nvidia,pins = "touch_int_px1";
				nvidia,function = "rsvd0";
				nvidia,pull = <TEGRA_PIN_PULL_UP>;
				nvidia,tristate = <TEGRA_PIN_ENABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};
		};

		/*
		 * The Joy-Con rail UARTs. These are ordinary pinmux pins, not
		 * padctl lanes, so configuring them cannot disturb the USB/PCIe
		 * lanes the console depends on. uartb carries the right Joy-Con,
		 * uartc the left; switchroot's DT uses the same pins and
		 * functions.
		 */
		uartb_pins: uartb-pins {
			uart2-tx-pg0 {
				nvidia,pins = "uart2_tx_pg0";
				nvidia,function = "uartb";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
			};

			uart2-rx-pg1 {
				nvidia,pins = "uart2_rx_pg1";
				nvidia,function = "uartb";
				nvidia,pull = <TEGRA_PIN_PULL_UP>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};

			uart2-rts-pg2 {
				nvidia,pins = "uart2_rts_pg2";
				nvidia,function = "uartb";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
			};

			uart2-cts-pg3 {
				nvidia,pins = "uart2_cts_pg3";
				nvidia,function = "uartb";
				nvidia,pull = <TEGRA_PIN_PULL_UP>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};
		};

		uartc_pins: uartc-pins {
			uart3-tx-pd1 {
				nvidia,pins = "uart3_tx_pd1";
				nvidia,function = "uartc";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
			};

			uart3-rx-pd2 {
				nvidia,pins = "uart3_rx_pd2";
				nvidia,function = "uartc";
				nvidia,pull = <TEGRA_PIN_PULL_UP>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};

			uart3-rts-pd3 {
				nvidia,pins = "uart3_rts_pd3";
				nvidia,function = "uartc";
				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
			};

			uart3-cts-pd4 {
				nvidia,pins = "uart3_cts_pd4";
				nvidia,function = "uartc";
				nvidia,pull = <TEGRA_PIN_PULL_UP>;
				nvidia,tristate = <TEGRA_PIN_DISABLE>;
				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
			};
		};
	};

	gpio@6000d000 {
		wifi-en-hog {
			gpio-hog;
			gpios = <TEGRA_GPIO(H, 0) GPIO_ACTIVE_HIGH>;
			output-high;
			line-name = "wifi-en";
		};

		wifi-rst-hog {
			gpio-hog;
			gpios = <TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
			output-high;
			line-name = "wifi-rst";
		};
	};

	/*
	 * The PMIC, and the real reason the PCIe link never trained.
	 *
	 * The BCM4356 is powered from three MAX77620 rails: sd3 ("vdd-1v8"),
	 * ldo1 ("vdd-pex") and ldo7 ("vdd-gen-pll-edp"). In the L4T tree the
	 * PCIe controller takes them as hvddio-pex / dvddio-pex / vddio-pex-ctl
	 * and the padctl takes them as avdd-pll-uerefe / dvdd-pex-pll, and
	 * enabling them is what powers the chip.
	 *
	 * Crucially, ldo1 and ldo7 have neither regulator-boot-on nor
	 * regulator-always-on in L4T: they are *off* until a consumer asks for
	 * them. Our device tree stood in for these with regulator-fixed
	 * regulators, which the kernel treats as always-on but which never touch
	 * the PMIC -- so ldo1 and ldo7 stayed off, the chip stayed unpowered, and
	 * PCIe reported "link 1 down" regardless of what the gating pins did.
	 *
	 * These three rails are declared regulator-always-on as a bring-up
	 * shortcut. It keeps every existing consumer on its regulator-fixed
	 * stand-in -- so a PMIC that fails to probe cannot break the working USB
	 * or SD paths -- while actually switching the PEX rails on. Wiring the
	 * consumers to these rails directly is the tidier follow-up once the
	 * PMIC is proven.
	 *
	 * The interrupt is GIC SPI 86: the L4T node carries
	 * "interrupts = <0x00 0x56 0x00>" with the parent inherited (the GIC),
	 * and 0x56 is 86. Mainline's own T210 board, tegra210-p2894, uses
	 * <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH> for the same PMIC.
	 */
	i2c@7000d000 {
		status = "okay";
		clock-frequency = <400000>;

		/*
		 * Deliberately NO pinctrl state here. An earlier attempt added one
		 * (pwr_i2c_scl_py3 / pwr_i2c_sda_py4 -> "i2cpmu") copying L4T, and
		 * it broke the PMIC outright:
		 *
		 *   max77620 0-003c: Failed to read CID: -110
		 *   max77620 0-003c: probe with driver max77620 failed with error -110
		 *
		 * Without it the PMIC probes fine, because U-Boot has already left
		 * the power-I2C pins in a working state and the Tegra pinmux driver
		 * only writes pins a DT state names. Overriding them was strictly
		 * worse.
		 */
		max77620: max77620@3c {
			compatible = "maxim,max77620";
			reg = <0x3c>;
			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;

			interrupt-controller;
			#interrupt-cells = <2>;

			gpio-controller;
			#gpio-cells = <2>;

			pinctrl-names = "default";
			pinctrl-0 = <&max77620_default>;

			/*
			 * Copied from the L4T tree. gpio2 and gpio3 are not plain
			 * GPIOs on this board: they are FPS outputs, and the 3.3 V
			 * rail the WiFi I/O needs is gated by that sequencer, not
			 * by software. Leaving the PMIC's pinmux and fps nodes out
			 * (as the first attempt did) leaves the sequencer
			 * unconfigured and that rail off.
			 */
			max77620_default: pinmux {
				gpio0 {
					pins = "gpio0";
					function = "gpio";
				};

				gpio1 {
					pins = "gpio1";
					function = "gpio";
				};

				gpio2 {
					pins = "gpio2";
					function = "fps-out";
					maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
					maxim,active-fps-power-up-slot = <0>;
					maxim,active-fps-power-down-slot = <7>;
				};

				gpio3 {
					pins = "gpio3";
					function = "fps-out";
					maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
					maxim,active-fps-power-up-slot = <4>;
					maxim,active-fps-power-down-slot = <2>;
				};

				gpio4 {
					pins = "gpio4";
					function = "32k-out1";
				};

				gpio5-7 {
					pins = "gpio5", "gpio6", "gpio7";
					function = "gpio";
				};
			};

			/* Children are matched by node name: fps%d. */
			fps {
				fps0 {
					maxim,shutdown-fps-time-period-us = <5120>;
					maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
				};

				fps1 {
					maxim,shutdown-fps-time-period-us = <5120>;
					maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN1>;
					maxim,device-state-on-disabled-event = <MAX77620_FPS_INACTIVE_STATE_SLEEP>;
				};

				fps2 {
					maxim,shutdown-fps-time-period-us = <5120>;
					maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
				};
			};

			regulators {
				max77620_sd3: sd3 {
					regulator-name = "vdd-1v8";
					regulator-min-microvolt = <1800000>;
					regulator-max-microvolt = <1800000>;
					regulator-boot-on;
					regulator-always-on;
					maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
				};

				max77620_ldo1: ldo1 {
					regulator-name = "vdd-pex";
					regulator-min-microvolt = <1050000>;
					regulator-max-microvolt = <1050000>;
					regulator-always-on;
					maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
				};

				max77620_ldo7: ldo7 {
					regulator-name = "vdd-gen-pll-edp";
					regulator-min-microvolt = <1050000>;
					regulator-max-microvolt = <1050000>;
					regulator-always-on;
					maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
				};

				/*
				 * The touchscreen's analogue rail -- the vendor DT
				 * calls it "vdd-tp-2v9", and this is the same
				 * ldo6. Not always-on: the stmfts driver enables
				 * it itself through its "avdd" supply. It *is*
				 * boot-on, matching the vendor, so the rail is
				 * live before the driver's first I2C access.
				 * FPS_SRC_NONE keeps the PMIC's FPS machinery
				 * from gating it behind a power-up slot.
				 */
				avdd_touchscreen: ldo6 {
					regulator-name = "AVDD_TOUCHSCREEN";
					regulator-min-microvolt = <2900000>;
					regulator-max-microvolt = <2900000>;
					regulator-boot-on;
					regulator-always-on;
					maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
				};
			};
		};
	};

	/*
	 * Touchscreen. An STMicroelectronics FTS controller at 0x49 on i2c3,
	 * interrupting on PX1. The wiring, the rails and the IRQ-enable
	 * register come from switchroot's DT (reference/switchroot-mainline/).
	 *
	 * The controller powers up with its interrupt generation masked, which
	 * is why interrupt-enable-reg is needed at all: without it the reset
	 * command's status event never arrives and the driver times out. That
	 * support is patches/kernel-stmfts-switch.patch.
	 *
	 * The native axes are 1280x720 while the panel is 720x1280 -- the
	 * digitiser is rotated relative to the display, hence swapped-x-y.
	 * The driver applies it through touchscreen_report_pos().
	 *
	 * No pinctrl state here, for the same reason i2c@7000d000 has none:
	 * the bootloader leaves the pins muxed, and adding a state is what
	 * broke the PMIC on the other bus.
	 */
	i2c@7000c500 {
		status = "okay";
		clock-frequency = <400000>;

		pinctrl-names = "default";
		pinctrl-0 = <&i2c3_pins>;

		touchscreen@49 {
			compatible = "st,stmfts";
			reg = <0x49>;

			/*
			 * No "interrupts" here, on purpose. The pin is level-low
			 * and nothing terminates it, so the interrupt asserts
			 * continuously: the handler then runs non-stop, eats the
			 * controller's ready event before the reset can read it,
			 * and starves the poll loop on the mutex. The symptom is
			 * a probe that fails with -110 after ~90 seconds.
			 *
			 * The pin is still configured (touch_pins above) so it
			 * is not left floating, and everything is driven by the
			 * driver's poll thread instead. Re-enable this once PX1
			 * is understood.
			 */
			pinctrl-names = "default";
			pinctrl-0 = <&touch_pins>;

			/*
			 * No "interrupt-enable-reg" either. switchroot's patch
			 * 0011 used it (0x2c = 0x48) to make the controller
			 * signal its status event by interrupt, but this driver
			 * polls the event FIFO instead, and this part answers
			 * that write with an error event.
			 */
			avdd-supply = <&avdd_touchscreen>;
			vdd-supply = <&vdd_touchscreen>;

			touchscreen-size-x = <1280>;
			touchscreen-size-y = <720>;
			touchscreen-swapped-x-y;
		};
	};

	/*
	 * Joy-Con rails. These are UARTs and the controllers speak HID over
	 * them -- a path mainline's hid-nintendo does not cover (that one is
	 * USB/Bluetooth). The driver is drivers/joycon.c, installed into the
	 * tree by install_switch_joycon().
	 *
	 * Deliberately no nvidia,invert-txd / nvidia,invert-rts, unlike
	 * switchroot's DT: mainline's serial-tegra.c does not implement those
	 * properties (TEGRA_UART_IRDA_CSR is defined there and never used).
	 * Testing without inversion first, since if the rails talk the property
	 * was vestigial -- and the IRDA_CSR bit layout would otherwise have to
	 * come from the vendor driver rather than be guessed.
	 */
	serial@70006040 {
		status = "okay";
		compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart";

		pinctrl-names = "default";
		pinctrl-0 = <&uartb_pins>;

		/* right Joy-Con */
		joycon {
			compatible = "nintendo,joycon-uart";
			charge-gpios = <&gpio TEGRA_GPIO(K, 3) GPIO_ACTIVE_HIGH>;
		};
	};

	serial@70006200 {
		status = "okay";
		compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart";

		pinctrl-names = "default";
		pinctrl-0 = <&uartc_pins>;

		/* left Joy-Con */
		joycon {
			compatible = "nintendo,joycon-uart";
			charge-gpios = <&gpio TEGRA_GPIO(CC, 3) GPIO_ACTIVE_HIGH>;
		};
	};

	/*
	 * Display. The panel is a JDI LPM062M326A (720x1280 DSI) -- identified
	 * from switchroot's mainline device tree, along with the wiring, the
	 * rails and the backlight below. The vendor kernel keeps the panel's
	 * timings and init sequence in C, which is why none of this could be
	 * derived from the L4T device tree.
	 *
	 * See reference/switchroot-mainline/README.md and
	 * device-tree/panel-jdi-lpm062m326a.c.
	 */
	pwm@7000a000 {
		status = "okay";
	};

	backlight: backlight {
		compatible = "pwm-backlight";
		pwms = <&pwm 0 35000>;
		pwm-names = "backlight";
		brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
				     17 18 19 20 21 22 23 24 25 26 27 28 29 30
				     31 32 33 34 35 36 37 38 39 40 41 42 43 44
				     45 46 47 48 49 50 51 52 53 54 55 56 57 58
				     59 60 61 62 63 64 65 66 67 68 69 70 71 72
				     73 74 75 76 77 78 79 80 81 82 83 84 85 86
				     87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
		default-brightness-level = <80>;

		/* Backlight enable, PV1 -- the L4T tree calls this lcd-bl-en. */
		enable-gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
	};

	/* Panel rails, from the L4T tree and switchroot's DT. */
	pavdd: regulator-pavdd {
		compatible = "regulator-fixed";
		regulator-name = "pavdd";
		regulator-min-microvolt = <5400000>;
		regulator-max-microvolt = <5400000>;
		gpio = <&gpio TEGRA_GPIO(I, 0) GPIO_ACTIVE_HIGH>;
		enable-active-high;
	};

	navdd: regulator-navdd {
		compatible = "regulator-fixed";
		regulator-name = "navdd";
		regulator-min-microvolt = <5400000>;
		regulator-max-microvolt = <5400000>;
		gpio = <&gpio TEGRA_GPIO(I, 1) GPIO_ACTIVE_HIGH>;
		enable-active-high;
	};

	vdd_dsi_csi: regulator-dsi-csi {
		compatible = "regulator-fixed";
		regulator-name = "AVDD_DSI_CSI_1V2";
		regulator-min-microvolt = <1200000>;
		regulator-max-microvolt = <1200000>;
		gpio = <&max77620 7 GPIO_ACTIVE_HIGH>;
		enable-active-high;
		regulator-always-on;
		regulator-boot-on;
	};

	/*
	 * The touchscreen's digital rail, gated by PJ7. The driver switches it
	 * through its "vdd" supply, but it is also always-on: the probe fails
	 * (see patches/kernel-stmfts-switch.patch), and on failure the driver
	 * disables its supplies, which powers the controller down and takes
	 * 0x49 off the bus. Keeping VIO up leaves the chip addressable with
	 * i2ctransfer after a failed probe, which is how the protocol below
	 * was worked out. Revert to a plain switched rail once the driver
	 * probes cleanly.
	 */
	vdd_touchscreen: regulator-touchscreen {
		compatible = "regulator-fixed";
		regulator-name = "vdd_touchscreen";
		regulator-min-microvolt = <1800000>;
		regulator-max-microvolt = <1800000>;
		gpio = <&gpio TEGRA_GPIO(J, 7) GPIO_ACTIVE_HIGH>;
		enable-active-high;
		regulator-always-on;
	};
};

/*
 * The DC and the DSI are children of host1x@50000000 in tegra210.dtsi, so they
 * must be addressed by full path or by label.
 *
 * Writing `dsi@54300000` at the root instead -- as this tree did at first --
 * creates a *second*, disconnected node, because a device tree merges by path.
 * The real DSI then stays "disabled", the panel never attaches, and the result
 * is a DRM device with no connectors: card0 and renderD128 but no DSI-1.
 */
&{/host1x@50000000/dc@54200000} {
	status = "okay";
};

&dsia {
	status = "okay";

	avdd-dsi-csi-supply = <&vdd_dsi_csi>;

	panel@0 {
		compatible = "jdi,lpm062m326a";
		reg = <0>;

		reset-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
		vdd1-supply = <&pavdd>;
		vdd2-supply = <&navdd>;
		backlight = <&backlight>;
	};
};