diff --git a/config/Config-images.in b/config/Config-images.in
index 47f3dfc0d960..805932ab6e06 100644
--- a/config/Config-images.in
+++ b/config/Config-images.in
@@ -294,7 +294,7 @@ menu "Target Images"
 		int "Kernel partition size (in MiB)"
 		depends on USES_BOOT_PART
 		default 8 if TARGET_apm821xx_sata
-		default 64 if TARGET_bcm27xx
+		default 64 if TARGET_bcm27xx || TARGET_tegra_armv8
 		default 128 if TARGET_armsr
 		default 16
 
diff --git a/package/firmware/cypress-firmware/Makefile b/package/firmware/cypress-firmware/Makefile
index 2b354b9eae62..a398d75207e3 100644
--- a/package/firmware/cypress-firmware/Makefile
+++ b/package/firmware/cypress-firmware/Makefile
@@ -210,6 +210,9 @@ define Package/cypress-firmware-4354-sdio/install
 	$(LN) \
 		../cypress/cyfmac4354-sdio.bin \
 		$(1)/lib/firmware/brcm/brcmfmac4354-sdio.bin
+	$(LN) \
+		../cypress/cyfmac4354-sdio.bin \
+		$(1)/lib/firmware/brcm/brcmfmac4354-sdio.nvidia,p2371-2180.bin
 	$(LN) \
 		../cypress/cyfmac4354-sdio.clm_blob \
 		$(1)/lib/firmware/brcm/brcmfmac4354-sdio.clm_blob
diff --git a/package/kernel/linux/modules/crypto.mk b/package/kernel/linux/modules/crypto.mk
index ce2216354703..8d01587415b0 100644
--- a/package/kernel/linux/modules/crypto.mk
+++ b/package/kernel/linux/modules/crypto.mk
@@ -974,7 +974,7 @@ define KernelPackage/crypto-sha1/octeon
   AUTOLOAD+=$(call AutoLoad,09,octeon-sha1)
 endef
 
-KernelPackage/crypto-sha1/tegra=$(KernelPackage/crypto-sha1/arm)
+KernelPackage/crypto-sha1/tegra/armv7=$(KernelPackage/crypto-sha1/arm)
 
 define KernelPackage/crypto-sha1/mpc85xx
   FILES+=$(LINUX_DIR)/arch/powerpc/crypto/sha1-ppc-spe.ko
@@ -1102,7 +1102,7 @@ define KernelPackage/crypto-sha512/octeon
   AUTOLOAD+=$(call AutoLoad,09,octeon-sha512)
 endef
 
-KernelPackage/crypto-sha512/tegra=$(KernelPackage/crypto-sha512/arm)
+KernelPackage/crypto-sha512/tegra/armv7=$(KernelPackage/crypto-sha512/arm)
 
 ifndef CONFIG_TARGET_uml
 define KernelPackage/crypto-sha512/x86_64
diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk
index b1366245ffab..a970a08e6b2c 100644
--- a/package/kernel/linux/modules/usb.mk
+++ b/package/kernel/linux/modules/usb.mk
@@ -1914,7 +1914,8 @@ $(eval $(call KernelPackage,chaoskey))
 
 define KernelPackage/usb-xhci-tegra
   TITLE:=xHCI support for Tegra SoCs
-  DEPENDS:=@TARGET_tegra +kmod-usb-xhci-hcd +kmod-usb-roles
+  DEPENDS:=@TARGET_tegra +kmod-usb-xhci-hcd +kmod-usb-roles \
+	+TARGET_tegra_armv8:t210-usb-firmware
   KCONFIG:= \
 	  CONFIG_USB_XHCI_TEGRA \
 	  CONFIG_PHY_TEGRA_XUSB=m
diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk
index a6f42cd19af2..20201447b741 100644
--- a/package/kernel/mac80211/broadcom.mk
+++ b/package/kernel/mac80211/broadcom.mk
@@ -437,6 +437,7 @@ define KernelPackage/brcmfmac/config
 		default y if TARGET_starfive
 		default y if TARGET_rockchip
 		default y if TARGET_sunxi
+		default y if TARGET_tegra_armv8
 		default n
 		help
 		  Enable support for cards attached to an SDIO bus.
diff --git a/target/linux/tegra/Makefile b/target/linux/tegra/Makefile
index 433510e23d6a..5f287cfd0d02 100644
--- a/target/linux/tegra/Makefile
+++ b/target/linux/tegra/Makefile
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 BOARD := tegra
 BOARDNAME := NVIDIA Tegra
 FEATURES := audio boot-part display ext4 fpu gpio pci pcie rootfs-part rtc squashfs usb
-SUBTARGETS := armv7
+SUBTARGETS := armv7 armv8
 
 KERNEL_PATCHVER := 6.6
 
diff --git a/target/linux/tegra/armv7/config-6.6 b/target/linux/tegra/armv7/config-6.6
new file mode 100644
index 000000000000..1fcd6118e50b
--- /dev/null
+++ b/target/linux/tegra/armv7/config-6.6
@@ -0,0 +1,296 @@
+CONFIG_AC97_BUS=y
+# CONFIG_AHCI_TEGRA is not set
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+# CONFIG_ARCH_TEGRA_114_SOC is not set
+# CONFIG_ARCH_TEGRA_124_SOC is not set
+CONFIG_ARCH_TEGRA_2x_SOC=y
+# CONFIG_ARCH_TEGRA_3x_SOC is not set
+CONFIG_ARM=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_HEAVY_MB=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_PATCH_IDIV=y
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_TEGRA124_CPUFREQ is not set
+CONFIG_ARM_TEGRA20_CPUFREQ=y
+CONFIG_ARM_TEGRA_CPUIDLE=y
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ASN1=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BOUNCE=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CLZ_TAB=y
+CONFIG_CMA_AREAS=7
+CONFIG_CMA_SIZE_MBYTES=16
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_STAT is not set
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_SPECTRE=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+CONFIG_CRYPTO_AES_ARM=y
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_GENIV=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LZ4=y
+CONFIG_CRYPTO_LZ4HC=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_RSA=y
+CONFIG_CRYPTO_SEQIV=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA1_ARM=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA256_ARM=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SHA512_ARM=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
+CONFIG_DDR=y
+CONFIG_DEBUG_ALIGN_RODATA=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+# CONFIG_DEVFREQ_THERMAL is not set
+CONFIG_DRM=y
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_DISPLAY_DP_HELPER=y
+CONFIG_DRM_DISPLAY_HDMI_HELPER=y
+CONFIG_DRM_DISPLAY_HELPER=y
+CONFIG_DRM_DP_AUX_BUS=y
+CONFIG_DRM_FBDEV_EMULATION=y
+CONFIG_DRM_FBDEV_OVERALLOC=100
+CONFIG_DRM_KMS_HELPER=y
+CONFIG_DRM_MIPI_DSI=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_BRIDGE=y
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+CONFIG_DRM_TEGRA=y
+# CONFIG_DRM_TEGRA_DEBUG is not set
+# CONFIG_DRM_TEGRA_STAGING is not set
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_FB_CORE=y
+CONFIG_FB_DEFERRED_IO=y
+CONFIG_FB_DMAMEM_HELPERS=y
+CONFIG_FB_IOMEM_FOPS=y
+CONFIG_FB_SYSMEM_HELPERS=y
+CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_FOPS=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_VDSO_32=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_HAVE_SMP=y
+CONFIG_HDMI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_PERIODIC=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_INPUT_VIVALDIFMAP=y
+CONFIG_IRQSTACKS=y
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KMAP_LOCAL=y
+CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
+CONFIG_LZ4HC_COMPRESS=y
+CONFIG_LZ4_COMPRESS=y
+CONFIG_LZ4_DECOMPRESS=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_MEDIA_CONTROLLER_REQUEST_API=y
+CONFIG_MEDIA_PLATFORM_DRIVERS=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_SUPPORT_FILTER=y
+# CONFIG_MFD_ACER_A500_EC is not set
+# CONFIG_MFD_NVEC is not set
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MPILIB=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+# CONFIG_NEON is not set
+CONFIG_NR_CPUS=4
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PCIEAER=y
+CONFIG_PCIEASPM=y
+CONFIG_PCIEASPM_DEFAULT=y
+# CONFIG_PCIEASPM_PERFORMANCE is not set
+# CONFIG_PCIEASPM_POWERSAVE is not set
+# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIE_PME=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHY_TEGRA_XUSB=y
+CONFIG_PINCTRL_TEGRA20=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_PL353_SMC=y
+# CONFIG_PM_DEVFREQ_EVENT is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_RAS=y
+CONFIG_REGMAP_SPI=y
+# CONFIG_RTC_DRV_CMOS is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SND=y
+CONFIG_SND_AUDIO_GRAPH_CARD=y
+# CONFIG_SND_COMPRESS_OFFLOAD is not set
+CONFIG_SND_DMAENGINE_PCM=y
+# CONFIG_SND_HDA_TEGRA is not set
+CONFIG_SND_JACK=y
+CONFIG_SND_JACK_INPUT_DEV=y
+# CONFIG_SND_PCI is not set
+CONFIG_SND_PCM=y
+CONFIG_SND_PCM_ELD=y
+CONFIG_SND_PCM_IEC958=y
+# CONFIG_SND_PROC_FS is not set
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_SND_SIMPLE_CARD_UTILS=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
+CONFIG_SND_SOC_HDMI_CODEC=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+CONFIG_SND_SOC_TEGRA=y
+# CONFIG_SND_SOC_TEGRA186_ASRC is not set
+# CONFIG_SND_SOC_TEGRA186_DSPK is not set
+CONFIG_SND_SOC_TEGRA20_AC97=y
+CONFIG_SND_SOC_TEGRA20_DAS=y
+CONFIG_SND_SOC_TEGRA20_I2S=y
+CONFIG_SND_SOC_TEGRA20_SPDIF=y
+# CONFIG_SND_SOC_TEGRA210_ADMAIF is not set
+# CONFIG_SND_SOC_TEGRA210_ADX is not set
+# CONFIG_SND_SOC_TEGRA210_AHUB is not set
+# CONFIG_SND_SOC_TEGRA210_AMX is not set
+# CONFIG_SND_SOC_TEGRA210_DMIC is not set
+# CONFIG_SND_SOC_TEGRA210_I2S is not set
+# CONFIG_SND_SOC_TEGRA210_MIXER is not set
+# CONFIG_SND_SOC_TEGRA210_MVC is not set
+# CONFIG_SND_SOC_TEGRA210_OPE is not set
+# CONFIG_SND_SOC_TEGRA210_SFC is not set
+# CONFIG_SND_SOC_TEGRA30_AHUB is not set
+# CONFIG_SND_SOC_TEGRA30_I2S is not set
+# CONFIG_SND_SOC_TEGRA_ALC5632 is not set
+# CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD is not set
+CONFIG_SND_SOC_TEGRA_MACHINE_DRV=y
+# CONFIG_SND_SOC_TEGRA_MAX98088 is not set
+# CONFIG_SND_SOC_TEGRA_MAX98090 is not set
+# CONFIG_SND_SOC_TEGRA_RT5631 is not set
+# CONFIG_SND_SOC_TEGRA_RT5640 is not set
+# CONFIG_SND_SOC_TEGRA_RT5677 is not set
+# CONFIG_SND_SOC_TEGRA_SGTL5000 is not set
+CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
+# CONFIG_SND_SOC_TEGRA_WM8753 is not set
+# CONFIG_SND_SOC_TEGRA_WM8903 is not set
+# CONFIG_SND_SOC_TEGRA_WM9712 is not set
+CONFIG_SND_SOC_TLV320AIC23=y
+CONFIG_SND_SOC_TLV320AIC23_I2C=y
+# CONFIG_SND_USB is not set
+CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+# CONFIG_SPI_TEGRA114 is not set
+CONFIG_SPI_TEGRA20_SFLASH=y
+CONFIG_SPI_TEGRA20_SLINK=y
+# CONFIG_SPI_TEGRA210_QUAD is not set
+CONFIG_SRAM=y
+CONFIG_SRAM_EXEC=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_TEGRA186_TIMER is not set
+CONFIG_TEGRA20_EMC=y
+# CONFIG_TEGRA210_ADMA is not set
+# CONFIG_TEGRA_ACONNECT is not set
+CONFIG_TEGRA_GMI=y
+CONFIG_TEGRA_HOST1X=y
+CONFIG_TEGRA_HOST1X_CONTEXT_BUS=y
+CONFIG_TEGRA_HOST1X_FIREWALL=y
+# CONFIG_TEGRA_IOMMU_GART is not set
+# CONFIG_TEGRA_IOMMU_SMMU is not set
+# CONFIG_TEGRA_IVC is not set
+# CONFIG_TEGRA_SOCTHERM is not set
+# CONFIG_UCLAMP_TASK is not set
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+# CONFIG_USB_TEGRA_XUDC is not set
+# CONFIG_USB_XHCI_TEGRA is not set
+CONFIG_USE_OF=y
+CONFIG_V4L2_H264=y
+CONFIG_V4L2_MEM2MEM_DEV=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VIDEOBUF2_CORE=y
+CONFIG_VIDEOBUF2_DMA_CONTIG=y
+CONFIG_VIDEOBUF2_DMA_SG=y
+CONFIG_VIDEOBUF2_MEMOPS=y
+CONFIG_VIDEOBUF2_V4L2=y
+CONFIG_VIDEO_CMDLINE=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_NOMODESET=y
+CONFIG_VIDEO_TEGRA_VDE=y
+CONFIG_VIDEO_V4L2_I2C=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/tegra/armv8/config-6.6 b/target/linux/tegra/armv8/config-6.6
new file mode 100644
index 000000000000..e4ed7d76d47a
--- /dev/null
+++ b/target/linux/tegra/armv8/config-6.6
@@ -0,0 +1,230 @@
+CONFIG_64BIT=y
+CONFIG_AHCI_TEGRA=y
+CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
+CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
+CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_FORCE_MAX_ORDER=10
+CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=24
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+# CONFIG_ARCH_TEGRA_132_SOC is not set
+# CONFIG_ARCH_TEGRA_186_SOC is not set
+# CONFIG_ARCH_TEGRA_194_SOC is not set
+CONFIG_ARCH_TEGRA_210_SOC=y
+# CONFIG_ARCH_TEGRA_234_SOC is not set
+CONFIG_ARCH_WANTS_NO_INSTR=y
+CONFIG_ARCH_WANTS_THP_SWAP=y
+CONFIG_ARM64=y
+CONFIG_ARM64_4K_PAGES=y
+CONFIG_ARM64_ERRATUM_1319367=y
+CONFIG_ARM64_ERRATUM_832075=y
+CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
+CONFIG_ARM64_PAGE_SHIFT=12
+CONFIG_ARM64_PA_BITS=48
+CONFIG_ARM64_PA_BITS_48=y
+CONFIG_ARM64_SME=y
+CONFIG_ARM64_SVE=y
+CONFIG_ARM64_TAGGED_ADDR_ABI=y
+CONFIG_ARM64_VA_BITS=39
+CONFIG_ARM64_VA_BITS_39=y
+CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_FFA_SMCCC=y
+CONFIG_ARM_FFA_TRANSPORT=y
+CONFIG_ARM_GIC_PM=y
+CONFIG_ARM_GIC_V2M=y
+CONFIG_ARM_GIC_V3=y
+CONFIG_ARM_GIC_V3_ITS=y
+CONFIG_ARM_GIC_V3_ITS_PCI=y
+# CONFIG_ARM_MHU_V2 is not set
+CONFIG_ARM_PSCI_FW=y
+# CONFIG_ARM_SMMU_V3 is not set
+# CONFIG_ARM_SMMU is not set
+CONFIG_ARM_TEGRA124_CPUFREQ=y
+# CONFIG_ARM_TEGRA186_CPUFREQ is not set
+# CONFIG_ARM_TEGRA20_CPUFREQ is not set
+CONFIG_ARM_TEGRA_DEVFREQ=y
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
+CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
+CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
+CONFIG_CLK_TEGRA_BPMP=y
+CONFIG_CMA_AREAS=20
+CONFIG_CMA_SIZE_MBYTES=64
+# CONFIG_COMMON_CLK_MAX77686 is not set
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_THERMAL=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CRC7=y
+CONFIG_CRC_ITU_T=y
+CONFIG_DEVFREQ_THERMAL=y
+CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+# CONFIG_DRM_TEGRA is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_EEPROM_AT24=y
+CONFIG_FIXED_PHY=y
+CONFIG_FRAME_POINTER=y
+CONFIG_FREEZER=y
+CONFIG_FUNCTION_ALIGNMENT=4
+CONFIG_FUNCTION_ALIGNMENT_4B=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_CACHE=y
+CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GPIO_MAX77620=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_HW_CONSOLE=y
+CONFIG_I2C_CCGX_UCSI=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_TEGRA_BPMP=y
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_IOMMUFD is not set
+CONFIG_IOMMU_API=y
+# CONFIG_IOMMU_DEBUGFS is not set
+# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
+CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
+# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
+CONFIG_IOMMU_DMA=y
+# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
+# CONFIG_IOMMU_IO_PGTABLE_DART is not set
+# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IRQ_MSI_IOMMU=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_MAX77620_THERMAL is not set
+CONFIG_MAX77620_WATCHDOG=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_MAX77620=y
+# CONFIG_MFD_NVEC is not set
+CONFIG_MFD_SYSCON=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_NEED_SG_DMA_FLAGS=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=8
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF_IOMMU=y
+CONFIG_OF_MDIO=y
+CONFIG_PARTITION_PERCPU=y
+CONFIG_PER_VMA_LOCK=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+# CONFIG_PHY_TEGRA_XUSB is not set
+CONFIG_PINCTRL_MAX77620=y
+CONFIG_PINCTRL_TEGRA210=y
+CONFIG_PM_DEVFREQ_EVENT=y
+CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_RESTART=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+# CONFIG_RAVE_SP_CORE is not set
+CONFIG_REGMAP_IRQ=y
+CONFIG_REGULATOR_MAX77620=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_RELAY=y
+CONFIG_RELOCATABLE=y
+CONFIG_RESET_TEGRA_BPMP=y
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
+CONFIG_RTC_DRV_MAX77686=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_HOST=y
+CONFIG_SATA_PMP=y
+CONFIG_SCHED_THERMAL_PRESSURE=y
+CONFIG_SDIO_UART=y
+CONFIG_SENSORS_INA3221=y
+CONFIG_SENSORS_PWM_FAN=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+CONFIG_SERIAL_TEGRA_TCU=y
+CONFIG_SERIAL_TEGRA_TCU_CONSOLE=y
+# CONFIG_SND_HDA_TEGRA is not set
+# CONFIG_SND_SOC_TEGRA is not set
+CONFIG_SOC_TEGRA_POWERGATE_BPMP=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPI_TEGRA114=y
+# CONFIG_SPI_TEGRA20_SFLASH is not set
+# CONFIG_SPI_TEGRA20_SLINK is not set
+CONFIG_SPI_TEGRA210_QUAD=y
+CONFIG_STAGING_MEDIA=y
+# CONFIG_STAGING_MEDIA_DEPRECATED is not set
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+# CONFIG_TEGRA186_GPC_DMA is not set
+# CONFIG_TEGRA186_TIMER is not set
+CONFIG_TEGRA210_ADMA=y
+CONFIG_TEGRA210_EMC=y
+CONFIG_TEGRA210_EMC_TABLE=y
+CONFIG_TEGRA_ACONNECT=y
+CONFIG_TEGRA_BPMP=y
+CONFIG_TEGRA_BPMP_THERMAL=y
+CONFIG_TEGRA_CLK_DFLL=y
+# CONFIG_TEGRA_GMI is not set
+CONFIG_TEGRA_IOMMU_SMMU=y
+CONFIG_TEGRA_IVC=y
+CONFIG_TEGRA_SOCTHERM=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_BANG_BANG=y
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
+# CONFIG_UCLAMP_TASK is not set
+CONFIG_UNMAP_KERNEL_AT_EL0=y
+CONFIG_USB_OTG=y
+CONFIG_USB_XHCI_HCD=y
+# CONFIG_USB_XHCI_PLATFORM is not set
+CONFIG_V4L2_ASYNC=y
+CONFIG_V4L2_FWNODE=y
+# CONFIG_VIDEO_MAX96712 is not set
+CONFIG_VIDEO_TEGRA=y
+# CONFIG_VIDEO_TEGRA_TPG is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_ZONE_DMA32=y
diff --git a/target/linux/tegra/armv8/target.mk b/target/linux/tegra/armv8/target.mk
new file mode 100644
index 000000000000..1726f0e867b5
--- /dev/null
+++ b/target/linux/tegra/armv8/target.mk
@@ -0,0 +1,9 @@
+ARCH := aarch64
+BOARDNAME := NVIDIA Tegra ARMv8
+CPU_TYPE := cortex-a57
+FEATURES += usbgadget
+KERNELNAME := Image dtbs
+
+define Target/Description
+	Build firmware images for NVIDIA Tegra ARMv8 SoC based boards.
+endef
diff --git a/target/linux/tegra/base-files/etc/hotplug.d/ieee80211/10-fix-wifi-mac b/target/linux/tegra/base-files/etc/hotplug.d/ieee80211/10-fix-wifi-mac
new file mode 100644
index 000000000000..331e544121ba
--- /dev/null
+++ b/target/linux/tegra/base-files/etc/hotplug.d/ieee80211/10-fix-wifi-mac
@@ -0,0 +1,22 @@
+#!/bin/ash
+
+[ "$ACTION" = "add" ] || exit 0
+
+PHYNBR=${DEVPATH##*/phy}
+
+[ -n $PHYNBR ] || exit 0
+
+. /lib/functions.sh
+. /lib/functions/system.sh
+
+board=$(board_name)
+
+case "$board" in
+	# Workaround for boards without updated U-Boot
+	nvidia,p2371-2180)
+		[ "$PHYNBR" -eq 0 ] && \
+			get_mac_binary /sys/devices/platform/7000c500.i2c/i2c-1/1-0050/eeprom 0x32 \
+				| awk -F':' 'OFS=":" {print $6,$5,$4,$3,$2,$1}' \
+				> /sys${DEVPATH}/macaddress
+		;;
+esac
diff --git a/target/linux/tegra/base-files/etc/inittab b/target/linux/tegra/base-files/etc/inittab
index b944a93ada4b..7e263dfeb2c8 100644
--- a/target/linux/tegra/base-files/etc/inittab
+++ b/target/linux/tegra/base-files/etc/inittab
@@ -2,3 +2,4 @@
 ::shutdown:/etc/init.d/rcS K shutdown
 ::askconsole:/usr/libexec/login.sh
 tty1::askfirst:/usr/libexec/login.sh
+ttyGS0::askfirst:/usr/libexec/login.sh
diff --git a/target/linux/tegra/base-files/lib/preinit/81_load_serial_gadget b/target/linux/tegra/base-files/lib/preinit/81_load_serial_gadget
new file mode 100644
index 000000000000..97f3be548457
--- /dev/null
+++ b/target/linux/tegra/base-files/lib/preinit/81_load_serial_gadget
@@ -0,0 +1,11 @@
+. /lib/functions.sh
+
+load_serial_gadget() {
+	case $(board_name) in
+	nvidia,p2371-2180)
+		modprobe g_serial
+		;;
+	esac
+}
+
+boot_hook_add preinit_main load_serial_gadget
diff --git a/target/linux/tegra/config-6.6 b/target/linux/tegra/config-6.6
index 9cecf9f6932a..274e0b29867d 100644
--- a/target/linux/tegra/config-6.6
+++ b/target/linux/tegra/config-6.6
@@ -1,72 +1,27 @@
-CONFIG_AC97_BUS=y
-# CONFIG_AHCI_TEGRA is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_STACKWALK=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_TEGRA=y
-# CONFIG_ARCH_TEGRA_114_SOC is not set
-# CONFIG_ARCH_TEGRA_124_SOC is not set
-CONFIG_ARCH_TEGRA_2x_SOC=y
-# CONFIG_ARCH_TEGRA_3x_SOC is not set
-CONFIG_ARM=y
 CONFIG_ARM_AMBA=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_ERRATA_720789=y
-CONFIG_ARM_ERRATA_754327=y
-CONFIG_ARM_ERRATA_764369=y
 CONFIG_ARM_GIC=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
 # CONFIG_ARM_PL172_MPMC is not set
-# CONFIG_ARM_SMMU is not set
-# CONFIG_ARM_TEGRA124_CPUFREQ is not set
-CONFIG_ARM_TEGRA20_CPUFREQ=y
-CONFIG_ARM_TEGRA_CPUIDLE=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_THUMBEE=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ASN1=y
 CONFIG_ATA=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
 CONFIG_BLK_DEV_BSG=y
 CONFIG_BLK_DEV_BSG_COMMON=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_MQ_PCI=y
 CONFIG_BLK_PM=y
-CONFIG_BOUNCE=y
 CONFIG_BUFFER_HEAD=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
 CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
 CONFIG_CC_NO_ARRAY_BOUNDS=y
 CONFIG_CLKSRC_MMIO=y
 CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
 CONFIG_CMA=y
 CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
 # CONFIG_CMA_DEBUG is not set
 # CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=16
 # CONFIG_CMA_SIZE_SEL_MAX is not set
 CONFIG_CMA_SIZE_SEL_MBYTES=y
 # CONFIG_CMA_SIZE_SEL_MIN is not set
@@ -80,17 +35,7 @@ CONFIG_CONTEXT_TRACKING_IDLE=y
 CONFIG_CONTIG_ALLOC=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
 CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
 CONFIG_CPU_FREQ_GOV_ATTR_SET=y
 CONFIG_CPU_FREQ_GOV_COMMON=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
@@ -99,69 +44,23 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
-# CONFIG_CPU_FREQ_STAT is not set
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_CPU_MITIGATIONS=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
 CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
 CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_AES_ARM=y
 CONFIG_CRYPTO_CRC32=y
 CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECHAINIV=y
-CONFIG_CRYPTO_GENIV=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_JITTERENTROPY=y
 CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
 CONFIG_CRYPTO_LIB_GF128MUL=y
 CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
 CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZ4=y
-CONFIG_CRYPTO_LZ4HC=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_RSA=y
-CONFIG_CRYPTO_SEQIV=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA1_ARM=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA256_ARM=y
-CONFIG_CRYPTO_SHA3=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_SHA512_ARM=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_TWOFISH_COMMON=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
 CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DDR=y
-CONFIG_DEBUG_ALIGN_RODATA=y
 CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
 # CONFIG_DEVFREQ_GOV_PASSIVE is not set
 # CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
 # CONFIG_DEVFREQ_GOV_POWERSAVE is not set
 CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
 # CONFIG_DEVFREQ_GOV_USERSPACE is not set
-CONFIG_DEVFREQ_THERMAL=y
 # CONFIG_DEVPORT is not set
 CONFIG_DMADEVICES=y
 CONFIG_DMA_CMA=y
@@ -169,49 +68,18 @@ CONFIG_DMA_ENGINE=y
 CONFIG_DMA_OF=y
 CONFIG_DMA_OPS=y
 CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DNOTIFY=y
-CONFIG_DRM=y
-CONFIG_DRM_BRIDGE=y
-CONFIG_DRM_DISPLAY_DP_HELPER=y
-CONFIG_DRM_DISPLAY_HDMI_HELPER=y
-CONFIG_DRM_DISPLAY_HELPER=y
-CONFIG_DRM_DP_AUX_BUS=y
-CONFIG_DRM_FBDEV_EMULATION=y
-CONFIG_DRM_FBDEV_OVERALLOC=100
-CONFIG_DRM_KMS_HELPER=y
-CONFIG_DRM_MIPI_DSI=y
-CONFIG_DRM_PANEL=y
-CONFIG_DRM_PANEL_BRIDGE=y
-CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
-CONFIG_DRM_TEGRA=y
-# CONFIG_DRM_TEGRA_DEBUG is not set
-# CONFIG_DRM_TEGRA_STAGING is not set
 CONFIG_DTC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
 CONFIG_EDAC_SUPPORT=y
 CONFIG_EXCLUSIVE_SYSTEM_RAM=y
 CONFIG_EXT4_FS=y
 CONFIG_EXTCON=y
 CONFIG_F2FS_FS=y
-CONFIG_FB=y
-CONFIG_FB_CORE=y
-CONFIG_FB_DEFERRED_IO=y
-CONFIG_FB_DMAMEM_HELPERS=y
-CONFIG_FB_IOMEM_FOPS=y
-CONFIG_FB_SYSMEM_HELPERS=y
-CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y
-CONFIG_FB_SYS_COPYAREA=y
-CONFIG_FB_SYS_FILLRECT=y
-CONFIG_FB_SYS_FOPS=y
-CONFIG_FB_SYS_IMAGEBLIT=y
 CONFIG_FIX_EARLYCON_MEM=y
 CONFIG_FS_IOMAP=y
 CONFIG_FS_MBCACHE=y
-CONFIG_FUNCTION_ALIGNMENT=0
 CONFIG_FW_LOADER_PAGED_BUF=y
 CONFIG_FW_LOADER_SYSFS=y
 CONFIG_GCC10_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
 CONFIG_GENERIC_ALLOCATOR=y
 CONFIG_GENERIC_ARCH_TOPOLOGY=y
 CONFIG_GENERIC_BUG=y
@@ -224,7 +92,6 @@ CONFIG_GENERIC_GETTIMEOFDAY=y
 CONFIG_GENERIC_IDLE_POLL_SETUP=y
 CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
 CONFIG_GENERIC_IRQ_MIGRATION=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
 CONFIG_GENERIC_IRQ_SHOW=y
 CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
 CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
@@ -239,77 +106,39 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
 CONFIG_GENERIC_STRNCPY_FROM_USER=y
 CONFIG_GENERIC_STRNLEN_USER=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GENERIC_VDSO_32=y
 CONFIG_GLOB=y
 CONFIG_GPIOLIB_IRQCHIP=y
 CONFIG_GPIO_CDEV=y
 CONFIG_GPIO_TEGRA=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_HAS_DMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HDMI=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
 CONFIG_HOTPLUG_CORE_SYNC=y
 CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
 CONFIG_HOTPLUG_CPU=y
 CONFIG_HWMON=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
 CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_COMPAT=y
 CONFIG_I2C_TEGRA=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_INPUT=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INPUT_VIVALDIFMAP=y
 CONFIG_INTERCONNECT=y
-# CONFIG_IOMMUFD is not set
-CONFIG_IOMMU_API=y
-# CONFIG_IOMMU_DEBUGFS is not set
-# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
-CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
-# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
 CONFIG_IOMMU_IOVA=y
-# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
-# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
-CONFIG_IOMMU_SUPPORT=y
 CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
 CONFIG_IRQ_DOMAIN=y
 CONFIG_IRQ_DOMAIN_HIERARCHY=y
 CONFIG_IRQ_FORCED_THREADING=y
 CONFIG_IRQ_WORK=y
 CONFIG_JBD2=y
 CONFIG_KCMP=y
-CONFIG_KEYBOARD_ATKBD=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
 CONFIG_LIBFDT=y
 CONFIG_LOCK_DEBUGGING_SUPPORT=y
 CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZ4HC_COMPRESS=y
-CONFIG_LZ4_COMPRESS=y
-CONFIG_LZ4_DECOMPRESS=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_MEDIA_CONTROLLER_REQUEST_API=y
-CONFIG_MEDIA_PLATFORM_DRIVERS=y
-CONFIG_MEDIA_PLATFORM_SUPPORT=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_MEDIA_SUPPORT_FILTER=y
 CONFIG_MEMORY=y
 CONFIG_MEMORY_ISOLATION=y
-# CONFIG_MFD_ACER_A500_EC is not set
-# CONFIG_MFD_NVEC is not set
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
 CONFIG_MIGRATION=y
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK=y
@@ -320,20 +149,15 @@ CONFIG_MMC_SDHCI_IO_ACCESSORS=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_TEGRA=y
 CONFIG_MMU_LAZY_TLB_REFCOUNT=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MPILIB=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
 CONFIG_MUTEX_SPIN_ON_OWNER=y
 CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_SRCU_NMI_SAFE=y
-# CONFIG_NEON is not set
 CONFIG_NET_EGRESS=y
 CONFIG_NET_FLOW_LIMIT=y
 CONFIG_NET_INGRESS=y
 CONFIG_NET_XGRESS=y
 CONFIG_NLS=y
-CONFIG_NR_CPUS=4
 CONFIG_NVMEM=y
 CONFIG_NVMEM_LAYOUTS=y
 CONFIG_OF=y
@@ -341,46 +165,24 @@ CONFIG_OF_ADDRESS=y
 CONFIG_OF_EARLY_FLATTREE=y
 CONFIG_OF_FLATTREE=y
 CONFIG_OF_GPIO=y
-CONFIG_OF_IOMMU=y
 CONFIG_OF_IRQ=y
 CONFIG_OF_KOBJ=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
 CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
 CONFIG_PAGE_POOL=y
 CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
 CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
 CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
 CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEASPM=y
-CONFIG_PCIEASPM_DEFAULT=y
-# CONFIG_PCIEASPM_PERFORMANCE is not set
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_PME=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_DOMAINS_GENERIC=y
 CONFIG_PCI_MSI=y
 CONFIG_PCI_TEGRA=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHY_TEGRA_XUSB=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_TEGRA=y
-CONFIG_PINCTRL_TEGRA20=y
 CONFIG_PINCTRL_TEGRA_XUSB=y
-CONFIG_PL310_ERRATA_727915=y
-CONFIG_PL310_ERRATA_769419=y
-CONFIG_PL353_SMC=y
 CONFIG_PM=y
 CONFIG_PM_CLK=y
 CONFIG_PM_DEVFREQ=y
-# CONFIG_PM_DEVFREQ_EVENT is not set
 CONFIG_PM_GENERIC_DOMAINS=y
 CONFIG_PM_GENERIC_DOMAINS_OF=y
 CONFIG_PM_OPP=y
@@ -388,18 +190,15 @@ CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_PTP_1588_CLOCK_OPTIONAL=y
 CONFIG_PWM=y
 CONFIG_PWM_SYSFS=y
 CONFIG_PWM_TEGRA=y
 CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
 CONFIG_RATIONAL=y
 CONFIG_REGMAP=y
 CONFIG_REGMAP_I2C=y
 CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
@@ -407,119 +206,35 @@ CONFIG_RESET_CONTROLLER=y
 CONFIG_RFS_ACCEL=y
 CONFIG_RPS=y
 CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_CMOS is not set
 CONFIG_RTC_DRV_TEGRA=y
 CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_NVMEM=y
 CONFIG_RWSEM_SPIN_ON_OWNER=y
 CONFIG_SCSI=y
 CONFIG_SCSI_COMMON=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_PROC_FS is not set
 CONFIG_SERIAL_8250_FSL=y
 CONFIG_SERIAL_8250_TEGRA=y
 CONFIG_SERIAL_MCTRL_GPIO=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_TEGRA=y
 CONFIG_SERIO=y
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SGL_ALLOC=y
+CONFIG_SERIO_SERPORT=y
 CONFIG_SG_POOL=y
 CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SND=y
-CONFIG_SND_AUDIO_GRAPH_CARD=y
-# CONFIG_SND_COMPRESS_OFFLOAD is not set
-CONFIG_SND_DMAENGINE_PCM=y
-# CONFIG_SND_HDA_TEGRA is not set
-CONFIG_SND_JACK=y
-CONFIG_SND_JACK_INPUT_DEV=y
-# CONFIG_SND_PCI is not set
-CONFIG_SND_PCM=y
-CONFIG_SND_PCM_ELD=y
-CONFIG_SND_PCM_IEC958=y
-# CONFIG_SND_PROC_FS is not set
-CONFIG_SND_SIMPLE_CARD=y
-CONFIG_SND_SIMPLE_CARD_UTILS=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_AC97_BUS=y
-CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
-CONFIG_SND_SOC_HDMI_CODEC=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-CONFIG_SND_SOC_TEGRA=y
-# CONFIG_SND_SOC_TEGRA186_ASRC is not set
-# CONFIG_SND_SOC_TEGRA186_DSPK is not set
-CONFIG_SND_SOC_TEGRA20_AC97=y
-CONFIG_SND_SOC_TEGRA20_DAS=y
-CONFIG_SND_SOC_TEGRA20_I2S=y
-CONFIG_SND_SOC_TEGRA20_SPDIF=y
-# CONFIG_SND_SOC_TEGRA210_ADMAIF is not set
-# CONFIG_SND_SOC_TEGRA210_ADX is not set
-# CONFIG_SND_SOC_TEGRA210_AHUB is not set
-# CONFIG_SND_SOC_TEGRA210_AMX is not set
-# CONFIG_SND_SOC_TEGRA210_DMIC is not set
-# CONFIG_SND_SOC_TEGRA210_I2S is not set
-# CONFIG_SND_SOC_TEGRA210_MIXER is not set
-# CONFIG_SND_SOC_TEGRA210_MVC is not set
-# CONFIG_SND_SOC_TEGRA210_OPE is not set
-# CONFIG_SND_SOC_TEGRA210_SFC is not set
-# CONFIG_SND_SOC_TEGRA30_AHUB is not set
-# CONFIG_SND_SOC_TEGRA30_I2S is not set
-# CONFIG_SND_SOC_TEGRA_ALC5632 is not set
-# CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD is not set
-CONFIG_SND_SOC_TEGRA_MACHINE_DRV=y
-# CONFIG_SND_SOC_TEGRA_MAX98088 is not set
-# CONFIG_SND_SOC_TEGRA_MAX98090 is not set
-# CONFIG_SND_SOC_TEGRA_RT5631 is not set
-# CONFIG_SND_SOC_TEGRA_RT5640 is not set
-# CONFIG_SND_SOC_TEGRA_RT5677 is not set
-# CONFIG_SND_SOC_TEGRA_SGTL5000 is not set
-CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
-# CONFIG_SND_SOC_TEGRA_WM8753 is not set
-# CONFIG_SND_SOC_TEGRA_WM8903 is not set
-# CONFIG_SND_SOC_TEGRA_WM9712 is not set
-CONFIG_SND_SOC_TLV320AIC23=y
-CONFIG_SND_SOC_TLV320AIC23_I2C=y
-# CONFIG_SND_USB is not set
 CONFIG_SOCK_RX_QUEUE_MAPPING=y
 CONFIG_SOC_BUS=y
-CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER=y
 CONFIG_SOC_TEGRA_FLOWCTRL=y
 CONFIG_SOC_TEGRA_FUSE=y
 CONFIG_SOC_TEGRA_PMC=y
 CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SPARSE_IRQ=y
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 CONFIG_SPI_MEM=y
-# CONFIG_SPI_TEGRA114 is not set
-CONFIG_SPI_TEGRA20_SFLASH=y
-CONFIG_SPI_TEGRA20_SLINK=y
-# CONFIG_SPI_TEGRA210_QUAD is not set
 CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SWP_EMULATE=y
 CONFIG_SYNC_FILE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_TEGRA186_TIMER is not set
 CONFIG_TEGRA20_APB_DMA=y
-CONFIG_TEGRA20_EMC=y
-# CONFIG_TEGRA210_ADMA is not set
-# CONFIG_TEGRA_ACONNECT is not set
 CONFIG_TEGRA_AHB=y
-CONFIG_TEGRA_GMI=y
-CONFIG_TEGRA_HOST1X=y
-CONFIG_TEGRA_HOST1X_CONTEXT_BUS=y
-CONFIG_TEGRA_HOST1X_FIREWALL=y
-CONFIG_TEGRA_IOMMU_GART=y
-# CONFIG_TEGRA_IOMMU_SMMU is not set
-# CONFIG_TEGRA_IVC is not set
 CONFIG_TEGRA_MC=y
-CONFIG_TEGRA_SOCTHERM=y
 CONFIG_TEGRA_TIMER=y
 CONFIG_TEGRA_WATCHDOG=y
 CONFIG_THREAD_INFO_IN_TASK=y
@@ -528,9 +243,6 @@ CONFIG_TIMER_OF=y
 CONFIG_TIMER_PROBE=y
 CONFIG_TREE_RCU=y
 CONFIG_TREE_SRCU=y
-# CONFIG_UCLAMP_TASK is not set
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
 CONFIG_USB=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_HOST=y
@@ -546,35 +258,10 @@ CONFIG_USB_PHY=y
 CONFIG_USB_ROLE_SWITCH=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_TEGRA_PHY=y
-# CONFIG_USB_TEGRA_XUDC is not set
 CONFIG_USB_ULPI=y
 CONFIG_USB_ULPI_BUS=y
 CONFIG_USB_ULPI_VIEWPORT=y
-# CONFIG_USB_XHCI_TEGRA is not set
-CONFIG_USE_OF=y
-CONFIG_V4L2_H264=y
-CONFIG_V4L2_MEM2MEM_DEV=y
-CONFIG_V4L_MEM2MEM_DRIVERS=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VIDEOBUF2_CORE=y
-CONFIG_VIDEOBUF2_DMA_CONTIG=y
-CONFIG_VIDEOBUF2_DMA_SG=y
-CONFIG_VIDEOBUF2_MEMOPS=y
-CONFIG_VIDEOBUF2_V4L2=y
-CONFIG_VIDEO_CMDLINE=y
-CONFIG_VIDEO_DEV=y
-CONFIG_VIDEO_NOMODESET=y
-CONFIG_VIDEO_TEGRA_VDE=y
-CONFIG_VIDEO_V4L2_I2C=y
 CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
 CONFIG_XPS=y
 CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
 CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/tegra/image/Makefile b/target/linux/tegra/image/Makefile
index 3b38fcdde684..3a6a583000bf 100644
--- a/target/linux/tegra/image/Makefile
+++ b/target/linux/tegra/image/Makefile
@@ -34,7 +34,7 @@ define Device/Default
   DEVICE_DTS_DIR := $$(DTS_DIR)/nvidia
   IMAGES := sdcard.img.gz
   IMAGE/sdcard.img.gz := append-rootfs | pad-extra 128k | tegra-sdcard | gzip | append-metadata
-  KERNEL_NAME := zImage
+  KERNEL_NAME := $(if $(CONFIG_ARCH_64BIT),Image,zImage)
   KERNEL := kernel-bin
   PROFILES := Default
 endef
diff --git a/target/linux/tegra/image/armv8.mk b/target/linux/tegra/image/armv8.mk
new file mode 100644
index 000000000000..2aae94012546
--- /dev/null
+++ b/target/linux/tegra/image/armv8.mk
@@ -0,0 +1,11 @@
+define Device/nvidia_jetson-tx1
+  DEVICE_VENDOR := NVIDIA
+  DEVICE_MODEL := Jetson TX1 Developer Kit
+  DEVICE_DTS := tegra210-p2371-2180
+  DEVICE_PACKAGES := brcmfmac-nvram-4354-sdio cypress-firmware-4354-sdio \
+	kmod-bluetooth kmod-brcmfmac kmod-usb-gadget-serial kmod-usb-hid \
+	kmod-usb-net-rtl8152 kmod-usb-udc-tegra kmod-usb-xhci-tegra \
+	wpad-basic-mbedtls
+  SUPPORTED_DEVICES := nvidia,p2371-2180
+endef
+TARGET_DEVICES += nvidia_jetson-tx1
diff --git a/target/linux/tegra/image/bootscript.txt b/target/linux/tegra/image/bootscript.txt
index 5d4620c4d200..f8806f57c356 100644
--- a/target/linux/tegra/image/bootscript.txt
+++ b/target/linux/tegra/image/bootscript.txt
@@ -1,8 +1,15 @@
 part uuid ${devtype} ${devnum}:2 ptuuid
 
 setenv bootargs "root=PARTUUID=${ptuuid} rw rootwait"
+if test "${cpu}" = armv7; then
+	setenv kernel_name zImage
+	setenv boot_cmd bootz
+elif test "${cpu}" = armv8; then
+	setenv kernel_name Image
+	setenv boot_cmd booti
+fi
 
-load ${devtype} ${devnum}:${bootpart} ${kernel_addr_r} zImage
+load ${devtype} ${devnum}:${bootpart} ${kernel_addr_r} ${kernel_name}
 load ${devtype} ${devnum}:${bootpart} ${fdt_addr_r} ${soc}-${board}.dtb
 
-bootz ${kernel_addr_r} - ${fdt_addr_r}
+${boot_cmd} ${kernel_addr_r} - ${fdt_addr_r}
diff --git a/target/linux/tegra/patches-6.6/001-v6.7-iommu-Add-iommu_ops-identity_domain.patch b/target/linux/tegra/patches-6.6/001-v6.7-iommu-Add-iommu_ops-identity_domain.patch
new file mode 100644
index 000000000000..efdd17ed0b26
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/001-v6.7-iommu-Add-iommu_ops-identity_domain.patch
@@ -0,0 +1,95 @@
+From df31b298477e65a01deff0af352be3a61524d930 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:34 -0300
+Subject: [PATCH 1/2] iommu: Add iommu_ops->identity_domain
+
+This allows a driver to set a global static to an IDENTITY domain and
+the core code will automatically use it whenever an IDENTITY domain
+is requested.
+
+By making it always available it means the IDENTITY can be used in error
+handling paths to force the iommu driver into a known state. Devices
+implementing global static identity domains should avoid failing their
+attach_dev ops.
+
+To make global static domains simpler allow drivers to omit their free
+function and update the iommufd selftest.
+
+Convert rockchip to use the new mechanism.
+
+Tested-by: Steven Price <steven.price@arm.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/1-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c            | 6 +++++-
+ drivers/iommu/iommufd/selftest.c | 5 -----
+ include/linux/iommu.h            | 3 +++
+ 4 files changed, 9 insertions(+), 14 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -1979,6 +1979,9 @@ static struct iommu_domain *__iommu_doma
+ 	if (bus == NULL || bus->iommu_ops == NULL)
+ 		return NULL;
+ 
++	if (alloc_type == IOMMU_DOMAIN_IDENTITY && bus->iommu_ops->identity_domain)
++		return bus->iommu_ops->identity_domain;
++
+ 	domain = bus->iommu_ops->domain_alloc(alloc_type);
+ 	if (!domain)
+ 		return NULL;
+@@ -2012,7 +2015,8 @@ void iommu_domain_free(struct iommu_doma
+ 	if (domain->type == IOMMU_DOMAIN_SVA)
+ 		mmdrop(domain->mm);
+ 	iommu_put_dma_cookie(domain);
+-	domain->ops->free(domain);
++	if (domain->ops->free)
++		domain->ops->free(domain);
+ }
+ EXPORT_SYMBOL_GPL(iommu_domain_free);
+ 
+--- a/drivers/iommu/iommufd/selftest.c
++++ b/drivers/iommu/iommufd/selftest.c
+@@ -126,10 +126,6 @@ struct selftest_obj {
+ 	};
+ };
+ 
+-static void mock_domain_blocking_free(struct iommu_domain *domain)
+-{
+-}
+-
+ static int mock_domain_nop_attach(struct iommu_domain *domain,
+ 				  struct device *dev)
+ {
+@@ -137,7 +133,6 @@ static int mock_domain_nop_attach(struct
+ }
+ 
+ static const struct iommu_domain_ops mock_blocking_ops = {
+-	.free = mock_domain_blocking_free,
+ 	.attach_dev = mock_domain_nop_attach,
+ };
+ 
+--- a/include/linux/iommu.h
++++ b/include/linux/iommu.h
+@@ -260,6 +260,8 @@ struct iommu_iotlb_gather {
+  *                    will be blocked by the hardware.
+  * @pgsize_bitmap: bitmap of all possible supported page sizes
+  * @owner: Driver module providing these ops
++ * @identity_domain: An always available, always attachable identity
++ *                   translation.
+  */
+ struct iommu_ops {
+ 	bool (*capable)(struct device *dev, enum iommu_cap);
+@@ -294,6 +296,7 @@ struct iommu_ops {
+ 	const struct iommu_domain_ops *default_domain_ops;
+ 	unsigned long pgsize_bitmap;
+ 	struct module *owner;
++	struct iommu_domain *identity_domain;
+ };
+ 
+ /**
diff --git a/target/linux/tegra/patches-6.6/002-v6.7-iommu-Add-IOMMU_DOMAIN_PLATFORM.patch b/target/linux/tegra/patches-6.6/002-v6.7-iommu-Add-IOMMU_DOMAIN_PLATFORM.patch
new file mode 100644
index 000000000000..c224eee334ac
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/002-v6.7-iommu-Add-IOMMU_DOMAIN_PLATFORM.patch
@@ -0,0 +1,134 @@
+From 1c68cbc64fe6ac01dc242ba562344303031a76fb Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:35 -0300
+Subject: [PATCH 2/2] iommu: Add IOMMU_DOMAIN_PLATFORM
+
+This is used when the iommu driver is taking control of the dma_ops,
+currently only on S390 and power spapr. It is designed to preserve the
+original ops->detach_dev() semantic that these S390 was built around.
+
+Provide an opaque domain type and a 'default_domain' ops value that allows
+the driver to trivially force any single domain as the default domain.
+
+Update iommufd selftest to use this instead of set_platform_dma_ops
+
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/2-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c            | 13 +++++++++++++
+ drivers/iommu/iommufd/selftest.c | 14 +++++---------
+ include/linux/iommu.h            |  8 ++++++++
+ 3 files changed, 26 insertions(+), 9 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -184,6 +184,8 @@ static const char *iommu_domain_type_str
+ 	case IOMMU_DOMAIN_DMA:
+ 	case IOMMU_DOMAIN_DMA_FQ:
+ 		return "Translated";
++	case IOMMU_DOMAIN_PLATFORM:
++		return "Platform";
+ 	default:
+ 		return "Unknown";
+ 	}
+@@ -1751,6 +1753,17 @@ iommu_group_alloc_default_domain(struct
+ 
+ 	lockdep_assert_held(&group->mutex);
+ 
++	/*
++	 * Allow legacy drivers to specify the domain that will be the default
++	 * domain. This should always be either an IDENTITY/BLOCKED/PLATFORM
++	 * domain. Do not use in new drivers.
++	 */
++	if (bus->iommu_ops->default_domain) {
++		if (req_type)
++			return ERR_PTR(-EINVAL);
++		return bus->iommu_ops->default_domain;
++	}
++
+ 	if (req_type)
+ 		return __iommu_group_alloc_default_domain(bus, group, req_type);
+ 
+--- a/drivers/iommu/iommufd/selftest.c
++++ b/drivers/iommu/iommufd/selftest.c
+@@ -296,14 +296,6 @@ static bool mock_domain_capable(struct d
+ 	return cap == IOMMU_CAP_CACHE_COHERENCY;
+ }
+ 
+-static void mock_domain_set_plaform_dma_ops(struct device *dev)
+-{
+-	/*
+-	 * mock doesn't setup default domains because we can't hook into the
+-	 * normal probe path
+-	 */
+-}
+-
+ static struct iommu_device mock_iommu_device = {
+ };
+ 
+@@ -313,12 +305,16 @@ static struct iommu_device *mock_probe_d
+ }
+ 
+ static const struct iommu_ops mock_ops = {
++	/*
++	 * IOMMU_DOMAIN_BLOCKED cannot be returned from def_domain_type()
++	 * because it is zero.
++	 */
++	.default_domain = &mock_blocking_domain,
+ 	.owner = THIS_MODULE,
+ 	.pgsize_bitmap = MOCK_IO_PAGE_SIZE,
+ 	.hw_info = mock_domain_hw_info,
+ 	.domain_alloc = mock_domain_alloc,
+ 	.capable = mock_domain_capable,
+-	.set_platform_dma_ops = mock_domain_set_plaform_dma_ops,
+ 	.device_group = generic_device_group,
+ 	.probe_device = mock_probe_device,
+ 	.default_domain_ops =
+--- a/include/linux/iommu.h
++++ b/include/linux/iommu.h
+@@ -64,6 +64,7 @@ struct iommu_domain_geometry {
+ #define __IOMMU_DOMAIN_DMA_FQ	(1U << 3)  /* DMA-API uses flush queue    */
+ 
+ #define __IOMMU_DOMAIN_SVA	(1U << 4)  /* Shared process address space */
++#define __IOMMU_DOMAIN_PLATFORM	(1U << 5)
+ 
+ #define IOMMU_DOMAIN_ALLOC_FLAGS ~__IOMMU_DOMAIN_DMA_FQ
+ /*
+@@ -81,6 +82,8 @@ struct iommu_domain_geometry {
+  *				  invalidation.
+  *	IOMMU_DOMAIN_SVA	- DMA addresses are shared process addresses
+  *				  represented by mm_struct's.
++ *	IOMMU_DOMAIN_PLATFORM	- Legacy domain for drivers that do their own
++ *				  dma_api stuff. Do not use in new drivers.
+  */
+ #define IOMMU_DOMAIN_BLOCKED	(0U)
+ #define IOMMU_DOMAIN_IDENTITY	(__IOMMU_DOMAIN_PT)
+@@ -91,6 +94,7 @@ struct iommu_domain_geometry {
+ 				 __IOMMU_DOMAIN_DMA_API |	\
+ 				 __IOMMU_DOMAIN_DMA_FQ)
+ #define IOMMU_DOMAIN_SVA	(__IOMMU_DOMAIN_SVA)
++#define IOMMU_DOMAIN_PLATFORM	(__IOMMU_DOMAIN_PLATFORM)
+ 
+ struct iommu_domain {
+ 	unsigned type;
+@@ -262,6 +266,9 @@ struct iommu_iotlb_gather {
+  * @owner: Driver module providing these ops
+  * @identity_domain: An always available, always attachable identity
+  *                   translation.
++ * @default_domain: If not NULL this will always be set as the default domain.
++ *                  This should be an IDENTITY/BLOCKED/PLATFORM domain.
++ *                  Do not use in new drivers.
+  */
+ struct iommu_ops {
+ 	bool (*capable)(struct device *dev, enum iommu_cap);
+@@ -297,6 +304,7 @@ struct iommu_ops {
+ 	unsigned long pgsize_bitmap;
+ 	struct module *owner;
+ 	struct iommu_domain *identity_domain;
++	struct iommu_domain *default_domain;
+ };
+ 
+ /**
diff --git a/target/linux/tegra/patches-6.6/003-v6.7-iommu-Reorganize-iommu_get_default_domain_type-to-re.patch b/target/linux/tegra/patches-6.6/003-v6.7-iommu-Reorganize-iommu_get_default_domain_type-to-re.patch
new file mode 100644
index 000000000000..54213597da6a
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/003-v6.7-iommu-Reorganize-iommu_get_default_domain_type-to-re.patch
@@ -0,0 +1,184 @@
+From 59ddce4418da483c932bc7a08b88d6ba14020e83 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:41 -0300
+Subject: [PATCH 1/2] iommu: Reorganize iommu_get_default_domain_type() to
+ respect def_domain_type()
+
+Except for dart (which forces IOMMU_DOMAIN_DMA) every driver returns 0 or
+IDENTITY from ops->def_domain_type().
+
+The drivers that return IDENTITY have some kind of good reason, typically
+that quirky hardware really can't support anything other than IDENTITY.
+
+Arrange things so that if the driver says it needs IDENTITY then
+iommu_get_default_domain_type() either fails or returns IDENTITY.  It will
+not ignore the driver's override to IDENTITY.
+
+Split the function into two steps, reducing the group device list to the
+driver's def_domain_type() and the untrusted flag.
+
+Then compute the result based on those two reduced variables. Fully reject
+combining untrusted with IDENTITY.
+
+Remove the debugging print on the iommu_group_store_type() failure path,
+userspace should not be able to trigger kernel prints.
+
+This makes the next patch cleaner that wants to force IDENTITY always for
+ARM_IOMMU because there is no support for DMA.
+
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/8-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c | 115 ++++++++++++++++++++++++++++--------------
+ 1 file changed, 78 insertions(+), 37 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -1717,19 +1717,6 @@ struct iommu_group *fsl_mc_device_group(
+ }
+ EXPORT_SYMBOL_GPL(fsl_mc_device_group);
+ 
+-static int iommu_get_def_domain_type(struct device *dev)
+-{
+-	const struct iommu_ops *ops = dev_iommu_ops(dev);
+-
+-	if (dev_is_pci(dev) && to_pci_dev(dev)->untrusted)
+-		return IOMMU_DOMAIN_DMA;
+-
+-	if (ops->def_domain_type)
+-		return ops->def_domain_type(dev);
+-
+-	return 0;
+-}
+-
+ static struct iommu_domain *
+ __iommu_group_alloc_default_domain(const struct bus_type *bus,
+ 				   struct iommu_group *group, int req_type)
+@@ -1740,6 +1727,23 @@ __iommu_group_alloc_default_domain(const
+ }
+ 
+ /*
++ * Returns the iommu_ops for the devices in an iommu group.
++ *
++ * It is assumed that all devices in an iommu group are managed by a single
++ * IOMMU unit. Therefore, this returns the dev_iommu_ops of the first device
++ * in the group.
++ */
++static const struct iommu_ops *group_iommu_ops(struct iommu_group *group)
++{
++	struct group_device *device =
++		list_first_entry(&group->devices, struct group_device, list);
++
++	lockdep_assert_held(&group->mutex);
++
++	return dev_iommu_ops(device->dev);
++}
++
++/*
+  * req_type of 0 means "auto" which means to select a domain based on
+  * iommu_def_domain_type or what the driver actually supports.
+  */
+@@ -1821,40 +1825,77 @@ static int iommu_bus_notifier(struct not
+ 	return 0;
+ }
+ 
+-/* A target_type of 0 will select the best domain type and cannot fail */
++/*
++ * Combine the driver's chosen def_domain_type across all the devices in a
++ * group. Drivers must give a consistent result.
++ */
++static int iommu_get_def_domain_type(struct iommu_group *group,
++				     struct device *dev, int cur_type)
++{
++	const struct iommu_ops *ops = group_iommu_ops(group);
++	int type;
++
++	if (!ops->def_domain_type)
++		return cur_type;
++
++	type = ops->def_domain_type(dev);
++	if (!type || cur_type == type)
++		return cur_type;
++	if (!cur_type)
++		return type;
++
++	dev_err_ratelimited(
++		dev,
++		"IOMMU driver error, requesting conflicting def_domain_type, %s and %s, for devices in group %u.\n",
++		iommu_domain_type_str(cur_type), iommu_domain_type_str(type),
++		group->id);
++
++	/*
++	 * Try to recover, drivers are allowed to force IDENITY or DMA, IDENTITY
++	 * takes precedence.
++	 */
++	if (type == IOMMU_DOMAIN_IDENTITY)
++		return type;
++	return cur_type;
++}
++
++/*
++ * A target_type of 0 will select the best domain type. 0 can be returned in
++ * this case meaning the global default should be used.
++ */
+ static int iommu_get_default_domain_type(struct iommu_group *group,
+ 					 int target_type)
+ {
+-	int best_type = target_type;
++	struct device *untrusted = NULL;
+ 	struct group_device *gdev;
+-	struct device *last_dev;
++	int driver_type = 0;
+ 
+ 	lockdep_assert_held(&group->mutex);
+-
+ 	for_each_group_device(group, gdev) {
+-		unsigned int type = iommu_get_def_domain_type(gdev->dev);
++		driver_type = iommu_get_def_domain_type(group, gdev->dev,
++							driver_type);
+ 
+-		if (best_type && type && best_type != type) {
+-			if (target_type) {
+-				dev_err_ratelimited(
+-					gdev->dev,
+-					"Device cannot be in %s domain\n",
+-					iommu_domain_type_str(target_type));
+-				return -1;
+-			}
+-
+-			dev_warn(
+-				gdev->dev,
+-				"Device needs domain type %s, but device %s in the same iommu group requires type %s - using default\n",
+-				iommu_domain_type_str(type), dev_name(last_dev),
+-				iommu_domain_type_str(best_type));
+-			return 0;
++		if (dev_is_pci(gdev->dev) && to_pci_dev(gdev->dev)->untrusted)
++			untrusted = gdev->dev;
++	}
++
++	if (untrusted) {
++		if (driver_type && driver_type != IOMMU_DOMAIN_DMA) {
++			dev_err_ratelimited(
++				untrusted,
++				"Device is not trusted, but driver is overriding group %u to %s, refusing to probe.\n",
++				group->id, iommu_domain_type_str(driver_type));
++			return -1;
+ 		}
+-		if (!best_type)
+-			best_type = type;
+-		last_dev = gdev->dev;
++		driver_type = IOMMU_DOMAIN_DMA;
++	}
++
++	if (target_type) {
++		if (driver_type && target_type != driver_type)
++			return -1;
++		return target_type;
+ 	}
+-	return best_type;
++	return driver_type;
+ }
+ 
+ static void iommu_group_do_probe_finalize(struct device *dev)
diff --git a/target/linux/tegra/patches-6.6/004-v6.7-iommu-Allow-an-IDENTITY-domain-as-the-default_domain.patch b/target/linux/tegra/patches-6.6/004-v6.7-iommu-Allow-an-IDENTITY-domain-as-the-default_domain.patch
new file mode 100644
index 000000000000..8fa76f9ee6f4
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/004-v6.7-iommu-Allow-an-IDENTITY-domain-as-the-default_domain.patch
@@ -0,0 +1,104 @@
+From e98befd010bd56b8b3f2afea2d600e30df023e6b Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:42 -0300
+Subject: [PATCH 2/2] iommu: Allow an IDENTITY domain as the default_domain in
+ ARM32
+
+Even though dma-iommu.c and CONFIG_ARM_DMA_USE_IOMMU do approximately the
+same stuff, the way they relate to the IOMMU core is quiet different.
+
+dma-iommu.c expects the core code to setup an UNMANAGED domain (of type
+IOMMU_DOMAIN_DMA) and then configures itself to use that domain. This
+becomes the default_domain for the group.
+
+ARM_DMA_USE_IOMMU does not use the default_domain, instead it directly
+allocates an UNMANAGED domain and operates it just like an external
+driver. In this case group->default_domain is NULL.
+
+If the driver provides a global static identity_domain then automatically
+use it as the default_domain when in ARM_DMA_USE_IOMMU mode.
+
+This allows drivers that implemented default_domain == NULL as an IDENTITY
+translation to trivially get a properly labeled non-NULL default_domain on
+ARM32 configs.
+
+With this arrangment when ARM_DMA_USE_IOMMU wants to disconnect from the
+device the normal detach_domain flow will restore the IDENTITY domain as
+the default domain. Overall this makes attach_dev() of the IDENTITY domain
+called in the same places as detach_dev().
+
+This effectively migrates these drivers to default_domain mode. For
+drivers that support ARM64 they will gain support for the IDENTITY
+translation mode for the dma_api and behave in a uniform way.
+
+Drivers use this by setting ops->identity_domain to a static singleton
+iommu_domain that implements the identity attach. If the core detects
+ARM_DMA_USE_IOMMU mode then it automatically attaches the IDENTITY domain
+during probe.
+
+Drivers can continue to prevent the use of DMA translation by returning
+IOMMU_DOMAIN_IDENTITY from def_domain_type, this will completely prevent
+IOMMU_DMA from running but will not impact ARM_DMA_USE_IOMMU.
+
+This allows removing the set_platform_dma_ops() from every remaining
+driver.
+
+Remove the set_platform_dma_ops from rockchip and mkt_v1 as all it does
+is set an existing global static identity domain. mkt_v1 does not support
+IOMMU_DOMAIN_DMA and it does not compile on ARM64 so this transformation
+is safe.
+
+Tested-by: Steven Price <steven.price@arm.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/9-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c          | 21 ++++++++++++++++++++-
+ drivers/iommu/mtk_iommu_v1.c   | 12 ------------
+ drivers/iommu/rockchip-iommu.c | 10 ----------
+ 3 files changed, 20 insertions(+), 23 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -1866,17 +1866,36 @@ static int iommu_get_def_domain_type(str
+ static int iommu_get_default_domain_type(struct iommu_group *group,
+ 					 int target_type)
+ {
++	const struct iommu_ops *ops = group_iommu_ops(group);
+ 	struct device *untrusted = NULL;
+ 	struct group_device *gdev;
+ 	int driver_type = 0;
+ 
+ 	lockdep_assert_held(&group->mutex);
++
++	/*
++	 * ARM32 drivers supporting CONFIG_ARM_DMA_USE_IOMMU can declare an
++	 * identity_domain and it will automatically become their default
++	 * domain. Later on ARM_DMA_USE_IOMMU will install its UNMANAGED domain.
++	 * Override the selection to IDENTITY if we are sure the driver supports
++	 * it.
++	 */
++	if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) && ops->identity_domain)
++		driver_type = IOMMU_DOMAIN_IDENTITY;
++
+ 	for_each_group_device(group, gdev) {
+ 		driver_type = iommu_get_def_domain_type(group, gdev->dev,
+ 							driver_type);
+ 
+-		if (dev_is_pci(gdev->dev) && to_pci_dev(gdev->dev)->untrusted)
++		if (dev_is_pci(gdev->dev) && to_pci_dev(gdev->dev)->untrusted) {
++			/*
++			 * No ARM32 using systems will set untrusted, it cannot
++			 * work.
++			 */
++			if (WARN_ON(IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)))
++				return -1;
+ 			untrusted = gdev->dev;
++		}
+ 	}
+ 
+ 	if (untrusted) {
diff --git a/target/linux/tegra/patches-6.6/005-v6.7-iommu-tegra-smmu-Implement-an-IDENTITY-domain.patch b/target/linux/tegra/patches-6.6/005-v6.7-iommu-tegra-smmu-Implement-an-IDENTITY-domain.patch
new file mode 100644
index 000000000000..c98872587d3c
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/005-v6.7-iommu-tegra-smmu-Implement-an-IDENTITY-domain.patch
@@ -0,0 +1,90 @@
+From c8cc2655cc6c7ff832827ad5bc1a8f3df165706d Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:44 -0300
+Subject: [PATCH 1/2] iommu/tegra-smmu: Implement an IDENTITY domain
+
+What tegra-smmu does during tegra_smmu_set_platform_dma() is actually
+putting the iommu into identity mode.
+
+Move to the new core support for ARM_DMA_USE_IOMMU by defining
+ops->identity_domain.
+
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/11-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/tegra-smmu.c | 37 ++++++++++++++++++++++++++++++++-----
+ 1 file changed, 32 insertions(+), 5 deletions(-)
+
+--- a/drivers/iommu/tegra-smmu.c
++++ b/drivers/iommu/tegra-smmu.c
+@@ -511,23 +511,39 @@ disable:
+ 	return err;
+ }
+ 
+-static void tegra_smmu_set_platform_dma(struct device *dev)
++static int tegra_smmu_identity_attach(struct iommu_domain *identity_domain,
++				      struct device *dev)
+ {
+ 	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+ 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+-	struct tegra_smmu_as *as = to_smmu_as(domain);
+-	struct tegra_smmu *smmu = as->smmu;
++	struct tegra_smmu_as *as;
++	struct tegra_smmu *smmu;
+ 	unsigned int index;
+ 
+ 	if (!fwspec)
+-		return;
++		return -ENODEV;
++
++	if (domain == identity_domain || !domain)
++		return 0;
+ 
++	as = to_smmu_as(domain);
++	smmu = as->smmu;
+ 	for (index = 0; index < fwspec->num_ids; index++) {
+ 		tegra_smmu_disable(smmu, fwspec->ids[index], as->id);
+ 		tegra_smmu_as_unprepare(smmu, as);
+ 	}
++	return 0;
+ }
+ 
++static struct iommu_domain_ops tegra_smmu_identity_ops = {
++	.attach_dev = tegra_smmu_identity_attach,
++};
++
++static struct iommu_domain tegra_smmu_identity_domain = {
++	.type = IOMMU_DOMAIN_IDENTITY,
++	.ops = &tegra_smmu_identity_ops,
++};
++
+ static void tegra_smmu_set_pde(struct tegra_smmu_as *as, unsigned long iova,
+ 			       u32 value)
+ {
+@@ -962,11 +978,22 @@ static int tegra_smmu_of_xlate(struct de
+ 	return iommu_fwspec_add_ids(dev, &id, 1);
+ }
+ 
++static int tegra_smmu_def_domain_type(struct device *dev)
++{
++	/*
++	 * FIXME: For now we want to run all translation in IDENTITY mode, due
++	 * to some device quirks. Better would be to just quirk the troubled
++	 * devices.
++	 */
++	return IOMMU_DOMAIN_IDENTITY;
++}
++
+ static const struct iommu_ops tegra_smmu_ops = {
++	.identity_domain = &tegra_smmu_identity_domain,
++	.def_domain_type = &tegra_smmu_def_domain_type,
+ 	.domain_alloc = tegra_smmu_domain_alloc,
+ 	.probe_device = tegra_smmu_probe_device,
+ 	.device_group = tegra_smmu_device_group,
+-	.set_platform_dma_ops = tegra_smmu_set_platform_dma,
+ 	.of_xlate = tegra_smmu_of_xlate,
+ 	.pgsize_bitmap = SZ_4K,
+ 	.default_domain_ops = &(const struct iommu_domain_ops) {
diff --git a/target/linux/tegra/patches-6.6/006-v6.7-iommu-tegra-smmu-Support-DMA-domains-in-tegra.patch b/target/linux/tegra/patches-6.6/006-v6.7-iommu-tegra-smmu-Support-DMA-domains-in-tegra.patch
new file mode 100644
index 000000000000..f3b52da97cd4
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/006-v6.7-iommu-tegra-smmu-Support-DMA-domains-in-tegra.patch
@@ -0,0 +1,36 @@
+From f128094f347f578279e551488796d0a0067cbdff Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:45 -0300
+Subject: [PATCH 2/2] iommu/tegra-smmu: Support DMA domains in tegra
+
+All ARM64 iommu drivers should support IOMMU_DOMAIN_DMA to enable
+dma-iommu.c.
+
+tegra is blocking dma-iommu usage, and also default_domain's, because it
+wants an identity translation. This is needed for some device quirk. The
+correct way to do this is to support IDENTITY domains and use
+ops->def_domain_type() to return IOMMU_DOMAIN_IDENTITY for only the quirky
+devices.
+
+Add support for IOMMU_DOMAIN_DMA and force IOMMU_DOMAIN_IDENTITY mode for
+everything so no behavior changes.
+
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/12-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/tegra-smmu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iommu/tegra-smmu.c
++++ b/drivers/iommu/tegra-smmu.c
+@@ -276,7 +276,7 @@ static struct iommu_domain *tegra_smmu_d
+ {
+ 	struct tegra_smmu_as *as;
+ 
+-	if (type != IOMMU_DOMAIN_UNMANAGED)
++	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
+ 		return NULL;
+ 
+ 	as = kzalloc(sizeof(*as), GFP_KERNEL);
diff --git a/target/linux/tegra/patches-6.6/007-v6.7-iommu-Remove-ops-set_platform_dma_ops.patch b/target/linux/tegra/patches-6.6/007-v6.7-iommu-Remove-ops-set_platform_dma_ops.patch
new file mode 100644
index 000000000000..bcae313d7055
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/007-v6.7-iommu-Remove-ops-set_platform_dma_ops.patch
@@ -0,0 +1,102 @@
+From 24b1d476167df3e30c7a53b67765bf3c787c5160 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:48 -0300
+Subject: [PATCH] iommu: Remove ops->set_platform_dma_ops()
+
+All drivers are now using IDENTITY or PLATFORM domains for what this did,
+we can remove it now. It is no longer possible to attach to a NULL domain.
+
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Tested-by: Steven Price <steven.price@arm.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/15-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c | 30 +++++-------------------------
+ include/linux/iommu.h |  4 ----
+ 2 files changed, 5 insertions(+), 29 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -2352,21 +2352,8 @@ static int __iommu_group_set_domain_inte
+ 	if (group->domain == new_domain)
+ 		return 0;
+ 
+-	/*
+-	 * New drivers should support default domains, so set_platform_dma()
+-	 * op will never be called. Otherwise the NULL domain represents some
+-	 * platform specific behavior.
+-	 */
+-	if (!new_domain) {
+-		for_each_group_device(group, gdev) {
+-			const struct iommu_ops *ops = dev_iommu_ops(gdev->dev);
+-
+-			if (!WARN_ON(!ops->set_platform_dma_ops))
+-				ops->set_platform_dma_ops(gdev->dev);
+-		}
+-		group->domain = NULL;
+-		return 0;
+-	}
++	if (WARN_ON(!new_domain))
++		return -EINVAL;
+ 
+ 	/*
+ 	 * Changing the domain is done by calling attach_dev() on the new
+@@ -2402,19 +2389,15 @@ err_revert:
+ 	 */
+ 	last_gdev = gdev;
+ 	for_each_group_device(group, gdev) {
+-		const struct iommu_ops *ops = dev_iommu_ops(gdev->dev);
+-
+ 		/*
+-		 * If set_platform_dma_ops is not present a NULL domain can
+-		 * happen only for first probe, in which case we leave
+-		 * group->domain as NULL and let release clean everything up.
++		 * A NULL domain can happen only for first probe, in which case
++		 * we leave group->domain as NULL and let release clean
++		 * everything up.
+ 		 */
+ 		if (group->domain)
+ 			WARN_ON(__iommu_device_set_domain(
+ 				group, gdev->dev, group->domain,
+ 				IOMMU_SET_DOMAIN_MUST_SUCCEED));
+-		else if (ops->set_platform_dma_ops)
+-			ops->set_platform_dma_ops(gdev->dev);
+ 		if (gdev == last_gdev)
+ 			break;
+ 	}
+@@ -3037,9 +3020,6 @@ static int iommu_setup_default_domain(st
+ 	/*
+ 	 * There are still some drivers which don't support default domains, so
+ 	 * we ignore the failure and leave group->default_domain NULL.
+-	 *
+-	 * We assume that the iommu driver starts up the device in
+-	 * 'set_platform_dma_ops' mode if it does not support default domains.
+ 	 */
+ 	dom = iommu_group_alloc_default_domain(group, req_type);
+ 	if (!dom) {
+--- a/include/linux/iommu.h
++++ b/include/linux/iommu.h
+@@ -243,9 +243,6 @@ struct iommu_iotlb_gather {
+  * @release_device: Remove device from iommu driver handling
+  * @probe_finalize: Do final setup work after the device is added to an IOMMU
+  *                  group and attached to the groups domain
+- * @set_platform_dma_ops: Returning control back to the platform DMA ops. This op
+- *                        is to support old IOMMU drivers, new drivers should use
+- *                        default domains, and the common IOMMU DMA ops.
+  * @device_group: find iommu group for a particular device
+  * @get_resv_regions: Request list of reserved regions for a device
+  * @of_xlate: add OF master IDs to iommu grouping
+@@ -280,7 +277,6 @@ struct iommu_ops {
+ 	struct iommu_device *(*probe_device)(struct device *dev);
+ 	void (*release_device)(struct device *dev);
+ 	void (*probe_finalize)(struct device *dev);
+-	void (*set_platform_dma_ops)(struct device *dev);
+ 	struct iommu_group *(*device_group)(struct device *dev);
+ 
+ 	/* Request/Free a list of reserved regions for a device */
diff --git a/target/linux/tegra/patches-6.6/008-v6.7-iommu-Require-a-default_domain-for-all-iommu-drivers.patch b/target/linux/tegra/patches-6.6/008-v6.7-iommu-Require-a-default_domain-for-all-iommu-drivers.patch
new file mode 100644
index 000000000000..5b89f6718d24
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/008-v6.7-iommu-Require-a-default_domain-for-all-iommu-drivers.patch
@@ -0,0 +1,127 @@
+From 98ac73f99bc44fba8a14252ffb0bad02459f7008 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:53 -0300
+Subject: [PATCH 1/7] iommu: Require a default_domain for all iommu drivers
+
+At this point every iommu driver will cause a default_domain to be
+selected, so we can finally remove this gap from the core code.
+
+The following table explains what each driver supports and what the
+resulting default_domain will be:
+
+                                        ops->defaut_domain
+                    IDENTITY   DMA  PLATFORM    v      ARM32          dma-iommu  ARCH
+amd/iommu.c             Y       Y                       N/A             either
+apple-dart.c            Y       Y                       N/A             either
+arm-smmu.c              Y       Y                       IDENTITY        either
+qcom_iommu.c            G       Y                       IDENTITY        either
+arm-smmu-v3.c           Y       Y                       N/A             either
+exynos-iommu.c          G       Y                       IDENTITY        either
+fsl_pamu_domain.c                       Y       Y       N/A             N/A     PLATFORM
+intel/iommu.c           Y       Y                       N/A             either
+ipmmu-vmsa.c            G       Y                       IDENTITY        either
+msm_iommu.c             G                               IDENTITY        N/A
+mtk_iommu.c             G       Y                       IDENTITY        either
+mtk_iommu_v1.c          G                               IDENTITY        N/A
+omap-iommu.c            G                               IDENTITY        N/A
+rockchip-iommu.c        G       Y                       IDENTITY        either
+s390-iommu.c                            Y       Y       N/A             N/A     PLATFORM
+sprd-iommu.c                    Y                       N/A             DMA
+sun50i-iommu.c          G       Y                       IDENTITY        either
+tegra-smmu.c            G       Y                       IDENTITY        IDENTITY
+virtio-iommu.c          Y       Y                       N/A             either
+spapr                                   Y       Y       N/A             N/A     PLATFORM
+ * G means ops->identity_domain is used
+ * N/A means the driver will not compile in this configuration
+
+ARM32 drivers select an IDENTITY default domain through either the
+ops->identity_domain or directly requesting an IDENTIY domain through
+alloc_domain().
+
+In ARM64 mode tegra-smmu will still block the use of dma-iommu.c and
+forces an IDENTITY domain.
+
+S390 uses a PLATFORM domain to represent when the dma_ops are set to the
+s390 iommu code.
+
+fsl_pamu uses an PLATFORM domain.
+
+POWER SPAPR uses PLATFORM and blocking to enable its weird VFIO mode.
+
+The x86 drivers continue unchanged.
+
+After this patch group->default_domain is only NULL for a short period
+during bus iommu probing while all the groups are constituted. Otherwise
+it is always !NULL.
+
+This completes changing the iommu subsystem driver contract to a system
+where the current iommu_domain always represents some form of translation
+and the driver is continuously asserting a definable translation mode.
+
+It resolves the confusion that the original ops->detach_dev() caused
+around what translation, exactly, is the IOMMU performing after
+detach. There were at least three different answers to that question in
+the tree, they are all now clearly named with domain types.
+
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Niklas Schnelle <schnelle@linux.ibm.com>
+Tested-by: Steven Price <steven.price@arm.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/20-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c | 22 +++++++---------------
+ 1 file changed, 7 insertions(+), 15 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -1866,7 +1866,6 @@ static int iommu_get_def_domain_type(str
+ static int iommu_get_default_domain_type(struct iommu_group *group,
+ 					 int target_type)
+ {
+-	const struct iommu_ops *ops = group_iommu_ops(group);
+ 	struct device *untrusted = NULL;
+ 	struct group_device *gdev;
+ 	int driver_type = 0;
+@@ -1877,11 +1876,13 @@ static int iommu_get_default_domain_type
+ 	 * ARM32 drivers supporting CONFIG_ARM_DMA_USE_IOMMU can declare an
+ 	 * identity_domain and it will automatically become their default
+ 	 * domain. Later on ARM_DMA_USE_IOMMU will install its UNMANAGED domain.
+-	 * Override the selection to IDENTITY if we are sure the driver supports
+-	 * it.
++	 * Override the selection to IDENTITY.
+ 	 */
+-	if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) && ops->identity_domain)
++	if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
++		static_assert(!(IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) &&
++				IS_ENABLED(CONFIG_IOMMU_DMA)));
+ 		driver_type = IOMMU_DOMAIN_IDENTITY;
++	}
+ 
+ 	for_each_group_device(group, gdev) {
+ 		driver_type = iommu_get_def_domain_type(group, gdev->dev,
+@@ -3017,18 +3018,9 @@ static int iommu_setup_default_domain(st
+ 	if (req_type < 0)
+ 		return -EINVAL;
+ 
+-	/*
+-	 * There are still some drivers which don't support default domains, so
+-	 * we ignore the failure and leave group->default_domain NULL.
+-	 */
+ 	dom = iommu_group_alloc_default_domain(group, req_type);
+-	if (!dom) {
+-		/* Once in default_domain mode we never leave */
+-		if (group->default_domain)
+-			return -ENODEV;
+-		group->default_domain = NULL;
+-		return 0;
+-	}
++	if (!dom)
++		return -ENODEV;
+ 
+ 	if (group->default_domain == dom)
+ 		return 0;
diff --git a/target/linux/tegra/patches-6.6/009-v6.7-iommu-Add-__iommu_group_domain_alloc.patch b/target/linux/tegra/patches-6.6/009-v6.7-iommu-Add-__iommu_group_domain_alloc.patch
new file mode 100644
index 000000000000..8cabfb648448
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/009-v6.7-iommu-Add-__iommu_group_domain_alloc.patch
@@ -0,0 +1,171 @@
+From 8359cf39acba72606736f453f54432ac9dc28523 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:54 -0300
+Subject: [PATCH 2/7] iommu: Add __iommu_group_domain_alloc()
+
+Allocate a domain from a group. Automatically obtains the iommu_ops to use
+from the device list of the group. Convert the internal callers to use it.
+
+Tested-by: Steven Price <steven.price@arm.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/21-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c | 59 +++++++++++++++++++++----------------------
+ 1 file changed, 29 insertions(+), 30 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -96,8 +96,8 @@ static const char * const iommu_group_re
+ static int iommu_bus_notifier(struct notifier_block *nb,
+ 			      unsigned long action, void *data);
+ static void iommu_release_device(struct device *dev);
+-static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus,
+-						 unsigned type);
++static struct iommu_domain *
++__iommu_group_domain_alloc(struct iommu_group *group, unsigned int type);
+ static int __iommu_attach_device(struct iommu_domain *domain,
+ 				 struct device *dev);
+ static int __iommu_attach_group(struct iommu_domain *domain,
+@@ -1718,12 +1718,11 @@ struct iommu_group *fsl_mc_device_group(
+ EXPORT_SYMBOL_GPL(fsl_mc_device_group);
+ 
+ static struct iommu_domain *
+-__iommu_group_alloc_default_domain(const struct bus_type *bus,
+-				   struct iommu_group *group, int req_type)
++__iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
+ {
+ 	if (group->default_domain && group->default_domain->type == req_type)
+ 		return group->default_domain;
+-	return __iommu_domain_alloc(bus, req_type);
++	return __iommu_group_domain_alloc(group, req_type);
+ }
+ 
+ /*
+@@ -1750,9 +1749,7 @@ static const struct iommu_ops *group_iom
+ static struct iommu_domain *
+ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
+ {
+-	const struct bus_type *bus =
+-		list_first_entry(&group->devices, struct group_device, list)
+-			->dev->bus;
++	const struct iommu_ops *ops = group_iommu_ops(group);
+ 	struct iommu_domain *dom;
+ 
+ 	lockdep_assert_held(&group->mutex);
+@@ -1762,24 +1759,24 @@ iommu_group_alloc_default_domain(struct
+ 	 * domain. This should always be either an IDENTITY/BLOCKED/PLATFORM
+ 	 * domain. Do not use in new drivers.
+ 	 */
+-	if (bus->iommu_ops->default_domain) {
++	if (ops->default_domain) {
+ 		if (req_type)
+ 			return ERR_PTR(-EINVAL);
+-		return bus->iommu_ops->default_domain;
++		return ops->default_domain;
+ 	}
+ 
+ 	if (req_type)
+-		return __iommu_group_alloc_default_domain(bus, group, req_type);
++		return __iommu_group_alloc_default_domain(group, req_type);
+ 
+ 	/* The driver gave no guidance on what type to use, try the default */
+-	dom = __iommu_group_alloc_default_domain(bus, group, iommu_def_domain_type);
++	dom = __iommu_group_alloc_default_domain(group, iommu_def_domain_type);
+ 	if (dom)
+ 		return dom;
+ 
+ 	/* Otherwise IDENTITY and DMA_FQ defaults will try DMA */
+ 	if (iommu_def_domain_type == IOMMU_DOMAIN_DMA)
+ 		return NULL;
+-	dom = __iommu_group_alloc_default_domain(bus, group, IOMMU_DOMAIN_DMA);
++	dom = __iommu_group_alloc_default_domain(group, IOMMU_DOMAIN_DMA);
+ 	if (!dom)
+ 		return NULL;
+ 
+@@ -2044,19 +2041,16 @@ void iommu_set_fault_handler(struct iomm
+ }
+ EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
+ 
+-static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus,
+-						 unsigned type)
++static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops,
++						 unsigned int type)
+ {
+ 	struct iommu_domain *domain;
+ 	unsigned int alloc_type = type & IOMMU_DOMAIN_ALLOC_FLAGS;
+ 
+-	if (bus == NULL || bus->iommu_ops == NULL)
+-		return NULL;
++	if (alloc_type == IOMMU_DOMAIN_IDENTITY && ops->identity_domain)
++		return ops->identity_domain;
+ 
+-	if (alloc_type == IOMMU_DOMAIN_IDENTITY && bus->iommu_ops->identity_domain)
+-		return bus->iommu_ops->identity_domain;
+-
+-	domain = bus->iommu_ops->domain_alloc(alloc_type);
++	domain = ops->domain_alloc(alloc_type);
+ 	if (!domain)
+ 		return NULL;
+ 
+@@ -2066,10 +2060,10 @@ static struct iommu_domain *__iommu_doma
+ 	 * may override this later
+ 	 */
+ 	if (!domain->pgsize_bitmap)
+-		domain->pgsize_bitmap = bus->iommu_ops->pgsize_bitmap;
++		domain->pgsize_bitmap = ops->pgsize_bitmap;
+ 
+ 	if (!domain->ops)
+-		domain->ops = bus->iommu_ops->default_domain_ops;
++		domain->ops = ops->default_domain_ops;
+ 
+ 	if (iommu_is_dma_domain(domain) && iommu_get_dma_cookie(domain)) {
+ 		iommu_domain_free(domain);
+@@ -2078,9 +2072,17 @@ static struct iommu_domain *__iommu_doma
+ 	return domain;
+ }
+ 
++static struct iommu_domain *
++__iommu_group_domain_alloc(struct iommu_group *group, unsigned int type)
++{
++	return __iommu_domain_alloc(group_iommu_ops(group), type);
++}
++
+ struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus)
+ {
+-	return __iommu_domain_alloc(bus, IOMMU_DOMAIN_UNMANAGED);
++	if (bus == NULL || bus->iommu_ops == NULL)
++		return NULL;
++	return __iommu_domain_alloc(bus->iommu_ops, IOMMU_DOMAIN_UNMANAGED);
+ }
+ EXPORT_SYMBOL_GPL(iommu_domain_alloc);
+ 
+@@ -3240,21 +3242,18 @@ void iommu_device_unuse_default_domain(s
+ 
+ static int __iommu_group_alloc_blocking_domain(struct iommu_group *group)
+ {
+-	struct group_device *dev =
+-		list_first_entry(&group->devices, struct group_device, list);
+-
+ 	if (group->blocking_domain)
+ 		return 0;
+ 
+ 	group->blocking_domain =
+-		__iommu_domain_alloc(dev->dev->bus, IOMMU_DOMAIN_BLOCKED);
++		__iommu_group_domain_alloc(group, IOMMU_DOMAIN_BLOCKED);
+ 	if (!group->blocking_domain) {
+ 		/*
+ 		 * For drivers that do not yet understand IOMMU_DOMAIN_BLOCKED
+ 		 * create an empty domain instead.
+ 		 */
+-		group->blocking_domain = __iommu_domain_alloc(
+-			dev->dev->bus, IOMMU_DOMAIN_UNMANAGED);
++		group->blocking_domain = __iommu_group_domain_alloc(
++			group, IOMMU_DOMAIN_UNMANAGED);
+ 		if (!group->blocking_domain)
+ 			return -EINVAL;
+ 	}
diff --git a/target/linux/tegra/patches-6.6/010-v6.7-iommu-Add-ops-domain_alloc_paging.patch b/target/linux/tegra/patches-6.6/010-v6.7-iommu-Add-ops-domain_alloc_paging.patch
new file mode 100644
index 000000000000..0eaca4ce8661
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/010-v6.7-iommu-Add-ops-domain_alloc_paging.patch
@@ -0,0 +1,101 @@
+From 4601cd2d7c4c82c4bafc822e1ff630a709eff206 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:55 -0300
+Subject: [PATCH 3/7] iommu: Add ops->domain_alloc_paging()
+
+This callback requests the driver to create only a __IOMMU_DOMAIN_PAGING
+domain, so it saves a few lines in a lot of drivers needlessly checking
+the type.
+
+More critically, this allows us to sweep out all the
+IOMMU_DOMAIN_UNMANAGED and IOMMU_DOMAIN_DMA checks from a lot of the
+drivers, simplifying what is going on in the code and ultimately removing
+the now-unused special cases in drivers where they did not support
+IOMMU_DOMAIN_DMA.
+
+domain_alloc_paging() should return a struct iommu_domain that is
+functionally compatible with ARM_DMA_USE_IOMMU, dma-iommu.c and iommufd.
+
+Be forwards looking and pass in a 'struct device *' argument. We can
+provide this when allocating the default_domain. No drivers will look at
+this.
+
+Tested-by: Steven Price <steven.price@arm.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/22-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c | 17 ++++++++++++++---
+ include/linux/iommu.h |  3 +++
+ 2 files changed, 17 insertions(+), 3 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -2042,6 +2042,7 @@ void iommu_set_fault_handler(struct iomm
+ EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
+ 
+ static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops,
++						 struct device *dev,
+ 						 unsigned int type)
+ {
+ 	struct iommu_domain *domain;
+@@ -2049,8 +2050,13 @@ static struct iommu_domain *__iommu_doma
+ 
+ 	if (alloc_type == IOMMU_DOMAIN_IDENTITY && ops->identity_domain)
+ 		return ops->identity_domain;
++	else if (type & __IOMMU_DOMAIN_PAGING && ops->domain_alloc_paging)
++		domain = ops->domain_alloc_paging(dev);
++	else if (ops->domain_alloc)
++		domain = ops->domain_alloc(alloc_type);
++	else
++		return NULL;
+ 
+-	domain = ops->domain_alloc(alloc_type);
+ 	if (!domain)
+ 		return NULL;
+ 
+@@ -2075,14 +2081,19 @@ static struct iommu_domain *__iommu_doma
+ static struct iommu_domain *
+ __iommu_group_domain_alloc(struct iommu_group *group, unsigned int type)
+ {
+-	return __iommu_domain_alloc(group_iommu_ops(group), type);
++	struct device *dev =
++		list_first_entry(&group->devices, struct group_device, list)
++			->dev;
++
++	return __iommu_domain_alloc(group_iommu_ops(group), dev, type);
+ }
+ 
+ struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus)
+ {
+ 	if (bus == NULL || bus->iommu_ops == NULL)
+ 		return NULL;
+-	return __iommu_domain_alloc(bus->iommu_ops, IOMMU_DOMAIN_UNMANAGED);
++	return __iommu_domain_alloc(bus->iommu_ops, NULL,
++				    IOMMU_DOMAIN_UNMANAGED);
+ }
+ EXPORT_SYMBOL_GPL(iommu_domain_alloc);
+ 
+--- a/include/linux/iommu.h
++++ b/include/linux/iommu.h
+@@ -239,6 +239,8 @@ struct iommu_iotlb_gather {
+  *           use. The information type is one of enum iommu_hw_info_type defined
+  *           in include/uapi/linux/iommufd.h.
+  * @domain_alloc: allocate iommu domain
++ * @domain_alloc_paging: Allocate an iommu_domain that can be used for
++ *                       UNMANAGED, DMA, and DMA_FQ domain types.
+  * @probe_device: Add device to iommu driver handling
+  * @release_device: Remove device from iommu driver handling
+  * @probe_finalize: Do final setup work after the device is added to an IOMMU
+@@ -273,6 +275,7 @@ struct iommu_ops {
+ 
+ 	/* Domain allocation and freeing by the iommu driver */
+ 	struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
++	struct iommu_domain *(*domain_alloc_paging)(struct device *dev);
+ 
+ 	struct iommu_device *(*probe_device)(struct device *dev);
+ 	void (*release_device)(struct device *dev);
diff --git a/target/linux/tegra/patches-6.6/011-v6.7-iommu-Convert-simple-drivers-with-DOMAIN_DMA-to-doma.patch b/target/linux/tegra/patches-6.6/011-v6.7-iommu-Convert-simple-drivers-with-DOMAIN_DMA-to-doma.patch
new file mode 100644
index 000000000000..8f38bfc98146
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/011-v6.7-iommu-Convert-simple-drivers-with-DOMAIN_DMA-to-doma.patch
@@ -0,0 +1,50 @@
+From 3529375e7777b0f9b77c53df9a7da122bd165ae7 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 13 Sep 2023 10:43:56 -0300
+Subject: [PATCH 4/7] iommu: Convert simple drivers with DOMAIN_DMA to
+ domain_alloc_paging()
+
+These drivers are all trivially converted since the function is only
+called if the domain type is going to be
+IOMMU_DOMAIN_UNMANAGED/DMA.
+
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Steven Price <steven.price@arm.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Tested-by: Yong Wu <yong.wu@mediatek.com>  #For mtk_iommu.c
+Link: https://lore.kernel.org/r/23-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/tegra-smmu.c              | 7 ++-----
+ 8 files changed, 17 insertions(+), 40 deletions(-)
+
+--- a/drivers/iommu/tegra-smmu.c
++++ b/drivers/iommu/tegra-smmu.c
+@@ -272,13 +272,10 @@ static void tegra_smmu_free_asid(struct
+ 	clear_bit(id, smmu->asids);
+ }
+ 
+-static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type)
++static struct iommu_domain *tegra_smmu_domain_alloc_paging(struct device *dev)
+ {
+ 	struct tegra_smmu_as *as;
+ 
+-	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
+-		return NULL;
+-
+ 	as = kzalloc(sizeof(*as), GFP_KERNEL);
+ 	if (!as)
+ 		return NULL;
+@@ -991,7 +988,7 @@ static int tegra_smmu_def_domain_type(st
+ static const struct iommu_ops tegra_smmu_ops = {
+ 	.identity_domain = &tegra_smmu_identity_domain,
+ 	.def_domain_type = &tegra_smmu_def_domain_type,
+-	.domain_alloc = tegra_smmu_domain_alloc,
++	.domain_alloc_paging = tegra_smmu_domain_alloc_paging,
+ 	.probe_device = tegra_smmu_probe_device,
+ 	.device_group = tegra_smmu_device_group,
+ 	.of_xlate = tegra_smmu_of_xlate,
diff --git a/target/linux/tegra/patches-6.6/012-v6.7-iommu-Remove-useless-group-refcounting.patch b/target/linux/tegra/patches-6.6/012-v6.7-iommu-Remove-useless-group-refcounting.patch
new file mode 100644
index 000000000000..8626c5291e5a
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/012-v6.7-iommu-Remove-useless-group-refcounting.patch
@@ -0,0 +1,239 @@
+From e946f8e3e62bf05da21a14658f8cb05e2a616260 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Tue, 22 Aug 2023 13:15:56 -0300
+Subject: [PATCH 6/7] iommu: Remove useless group refcounting
+
+Several functions obtain the group reference and then release it before
+returning. This gives the impression that the refcount is protecting
+something for the duration of the function.
+
+In truth all of these functions are called in places that know a device
+driver is probed to the device and our locking rules already require
+that dev->iommu_group cannot change while a driver is attached to the
+struct device.
+
+If this was not the case then this code is already at risk of triggering
+UAF as it is racy if the dev->iommu_group is concurrently going to
+NULL/free. refcount debugging will throw a WARN if kobject_get() is
+called on a 0 refcount object to highlight the bug.
+
+Remove the confusing refcounting and leave behind a comment about the
+restriction.
+
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/1-v1-c869a95191f2+5e8-iommu_single_grp_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c | 57 ++++++++++++++++---------------------------
+ 1 file changed, 21 insertions(+), 36 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -2153,10 +2153,10 @@ static int __iommu_attach_device(struct
+  */
+ int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
+ {
+-	struct iommu_group *group;
++	/* Caller must be a probed driver on dev */
++	struct iommu_group *group = dev->iommu_group;
+ 	int ret;
+ 
+-	group = iommu_group_get(dev);
+ 	if (!group)
+ 		return -ENODEV;
+ 
+@@ -2173,8 +2173,6 @@ int iommu_attach_device(struct iommu_dom
+ 
+ out_unlock:
+ 	mutex_unlock(&group->mutex);
+-	iommu_group_put(group);
+-
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(iommu_attach_device);
+@@ -2189,9 +2187,9 @@ int iommu_deferred_attach(struct device
+ 
+ void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
+ {
+-	struct iommu_group *group;
++	/* Caller must be a probed driver on dev */
++	struct iommu_group *group = dev->iommu_group;
+ 
+-	group = iommu_group_get(dev);
+ 	if (!group)
+ 		return;
+ 
+@@ -2203,24 +2201,18 @@ void iommu_detach_device(struct iommu_do
+ 
+ out_unlock:
+ 	mutex_unlock(&group->mutex);
+-	iommu_group_put(group);
+ }
+ EXPORT_SYMBOL_GPL(iommu_detach_device);
+ 
+ struct iommu_domain *iommu_get_domain_for_dev(struct device *dev)
+ {
+-	struct iommu_domain *domain;
+-	struct iommu_group *group;
++	/* Caller must be a probed driver on dev */
++	struct iommu_group *group = dev->iommu_group;
+ 
+-	group = iommu_group_get(dev);
+ 	if (!group)
+ 		return NULL;
+ 
+-	domain = group->domain;
+-
+-	iommu_group_put(group);
+-
+-	return domain;
++	return group->domain;
+ }
+ EXPORT_SYMBOL_GPL(iommu_get_domain_for_dev);
+ 
+@@ -3204,7 +3196,8 @@ static bool iommu_is_default_domain(stru
+  */
+ int iommu_device_use_default_domain(struct device *dev)
+ {
+-	struct iommu_group *group = iommu_group_get(dev);
++	/* Caller is the driver core during the pre-probe path */
++	struct iommu_group *group = dev->iommu_group;
+ 	int ret = 0;
+ 
+ 	if (!group)
+@@ -3223,8 +3216,6 @@ int iommu_device_use_default_domain(stru
+ 
+ unlock_out:
+ 	mutex_unlock(&group->mutex);
+-	iommu_group_put(group);
+-
+ 	return ret;
+ }
+ 
+@@ -3238,7 +3229,8 @@ unlock_out:
+  */
+ void iommu_device_unuse_default_domain(struct device *dev)
+ {
+-	struct iommu_group *group = iommu_group_get(dev);
++	/* Caller is the driver core during the post-probe path */
++	struct iommu_group *group = dev->iommu_group;
+ 
+ 	if (!group)
+ 		return;
+@@ -3248,7 +3240,6 @@ void iommu_device_unuse_default_domain(s
+ 		group->owner_cnt--;
+ 
+ 	mutex_unlock(&group->mutex);
+-	iommu_group_put(group);
+ }
+ 
+ static int __iommu_group_alloc_blocking_domain(struct iommu_group *group)
+@@ -3332,13 +3323,13 @@ EXPORT_SYMBOL_GPL(iommu_group_claim_dma_
+  */
+ int iommu_device_claim_dma_owner(struct device *dev, void *owner)
+ {
+-	struct iommu_group *group;
++	/* Caller must be a probed driver on dev */
++	struct iommu_group *group = dev->iommu_group;
+ 	int ret = 0;
+ 
+ 	if (WARN_ON(!owner))
+ 		return -EINVAL;
+ 
+-	group = iommu_group_get(dev);
+ 	if (!group)
+ 		return -ENODEV;
+ 
+@@ -3355,8 +3346,6 @@ int iommu_device_claim_dma_owner(struct
+ 	ret = __iommu_take_dma_ownership(group, owner);
+ unlock_out:
+ 	mutex_unlock(&group->mutex);
+-	iommu_group_put(group);
+-
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(iommu_device_claim_dma_owner);
+@@ -3394,7 +3383,8 @@ EXPORT_SYMBOL_GPL(iommu_group_release_dm
+  */
+ void iommu_device_release_dma_owner(struct device *dev)
+ {
+-	struct iommu_group *group = iommu_group_get(dev);
++	/* Caller must be a probed driver on dev */
++	struct iommu_group *group = dev->iommu_group;
+ 
+ 	mutex_lock(&group->mutex);
+ 	if (group->owner_cnt > 1)
+@@ -3402,7 +3392,6 @@ void iommu_device_release_dma_owner(stru
+ 	else
+ 		__iommu_release_dma_ownership(group);
+ 	mutex_unlock(&group->mutex);
+-	iommu_group_put(group);
+ }
+ EXPORT_SYMBOL_GPL(iommu_device_release_dma_owner);
+ 
+@@ -3474,14 +3463,14 @@ static void __iommu_remove_group_pasid(s
+ int iommu_attach_device_pasid(struct iommu_domain *domain,
+ 			      struct device *dev, ioasid_t pasid)
+ {
+-	struct iommu_group *group;
++	/* Caller must be a probed driver on dev */
++	struct iommu_group *group = dev->iommu_group;
+ 	void *curr;
+ 	int ret;
+ 
+ 	if (!domain->ops->set_dev_pasid)
+ 		return -EOPNOTSUPP;
+ 
+-	group = iommu_group_get(dev);
+ 	if (!group)
+ 		return -ENODEV;
+ 
+@@ -3497,8 +3486,6 @@ int iommu_attach_device_pasid(struct iom
+ 		xa_erase(&group->pasid_array, pasid);
+ out_unlock:
+ 	mutex_unlock(&group->mutex);
+-	iommu_group_put(group);
+-
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(iommu_attach_device_pasid);
+@@ -3515,14 +3502,13 @@ EXPORT_SYMBOL_GPL(iommu_attach_device_pa
+ void iommu_detach_device_pasid(struct iommu_domain *domain, struct device *dev,
+ 			       ioasid_t pasid)
+ {
+-	struct iommu_group *group = iommu_group_get(dev);
++	/* Caller must be a probed driver on dev */
++	struct iommu_group *group = dev->iommu_group;
+ 
+ 	mutex_lock(&group->mutex);
+ 	__iommu_remove_group_pasid(group, pasid);
+ 	WARN_ON(xa_erase(&group->pasid_array, pasid) != domain);
+ 	mutex_unlock(&group->mutex);
+-
+-	iommu_group_put(group);
+ }
+ EXPORT_SYMBOL_GPL(iommu_detach_device_pasid);
+ 
+@@ -3544,10 +3530,10 @@ struct iommu_domain *iommu_get_domain_fo
+ 						    ioasid_t pasid,
+ 						    unsigned int type)
+ {
++	/* Caller must be a probed driver on dev */
++	struct iommu_group *group = dev->iommu_group;
+ 	struct iommu_domain *domain;
+-	struct iommu_group *group;
+ 
+-	group = iommu_group_get(dev);
+ 	if (!group)
+ 		return NULL;
+ 
+@@ -3556,7 +3542,6 @@ struct iommu_domain *iommu_get_domain_fo
+ 	if (type && domain && domain->type != type)
+ 		domain = ERR_PTR(-EBUSY);
+ 	xa_unlock(&group->pasid_array);
+-	iommu_group_put(group);
+ 
+ 	return domain;
+ }
diff --git a/target/linux/tegra/patches-6.6/013-v6.7-iommu-Add-generic_single_device_group.patch b/target/linux/tegra/patches-6.6/013-v6.7-iommu-Add-generic_single_device_group.patch
new file mode 100644
index 000000000000..e4ef659b56f7
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/013-v6.7-iommu-Add-generic_single_device_group.patch
@@ -0,0 +1,110 @@
+From e8f52d84cf0b6d1862ab62f7ed705f78690d11b2 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Tue, 22 Aug 2023 13:15:57 -0300
+Subject: [PATCH 7/7] iommu: Add generic_single_device_group()
+
+This implements the common pattern seen in drivers of a single iommu_group
+for the entire iommu driver instance. Implement this in core code so the
+drivers that want this can select it from their ops.
+
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/2-v1-c869a95191f2+5e8-iommu_single_grp_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c | 28 +++++++++++++++++++++++++++-
+ include/linux/iommu.h |  3 +++
+ 2 files changed, 30 insertions(+), 1 deletion(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -292,6 +292,10 @@ void iommu_device_unregister(struct iomm
+ 	spin_lock(&iommu_device_lock);
+ 	list_del(&iommu->list);
+ 	spin_unlock(&iommu_device_lock);
++
++	/* Pairs with the alloc in generic_single_device_group() */
++	iommu_group_put(iommu->singleton_group);
++	iommu->singleton_group = NULL;
+ }
+ EXPORT_SYMBOL_GPL(iommu_device_unregister);
+ 
+@@ -406,6 +410,7 @@ static int iommu_init_device(struct devi
+ 		ret = PTR_ERR(iommu_dev);
+ 		goto err_module_put;
+ 	}
++	dev->iommu->iommu_dev = iommu_dev;
+ 
+ 	ret = iommu_device_link(iommu_dev, dev);
+ 	if (ret)
+@@ -420,7 +425,6 @@ static int iommu_init_device(struct devi
+ 	}
+ 	dev->iommu_group = group;
+ 
+-	dev->iommu->iommu_dev = iommu_dev;
+ 	dev->iommu->max_pasids = dev_iommu_get_max_pasids(dev);
+ 	if (ops->is_attach_deferred)
+ 		dev->iommu->attach_deferred = ops->is_attach_deferred(dev);
+@@ -434,6 +438,7 @@ err_release:
+ err_module_put:
+ 	module_put(ops->owner);
+ err_free:
++	dev->iommu->iommu_dev = NULL;
+ 	dev_iommu_free(dev);
+ 	return ret;
+ }
+@@ -1637,6 +1642,27 @@ struct iommu_group *generic_device_group
+ EXPORT_SYMBOL_GPL(generic_device_group);
+ 
+ /*
++ * Generic device_group call-back function. It just allocates one
++ * iommu-group per iommu driver instance shared by every device
++ * probed by that iommu driver.
++ */
++struct iommu_group *generic_single_device_group(struct device *dev)
++{
++	struct iommu_device *iommu = dev->iommu->iommu_dev;
++
++	if (!iommu->singleton_group) {
++		struct iommu_group *group;
++
++		group = iommu_group_alloc();
++		if (IS_ERR(group))
++			return group;
++		iommu->singleton_group = group;
++	}
++	return iommu_group_ref_get(iommu->singleton_group);
++}
++EXPORT_SYMBOL_GPL(generic_single_device_group);
++
++/*
+  * Use standard PCI bus topology, isolation features, and DMA alias quirks
+  * to find or create an IOMMU group for a device.
+  */
+--- a/include/linux/iommu.h
++++ b/include/linux/iommu.h
+@@ -378,6 +378,7 @@ struct iommu_domain_ops {
+  * @list: Used by the iommu-core to keep a list of registered iommus
+  * @ops: iommu-ops for talking to this iommu
+  * @dev: struct device for sysfs handling
++ * @singleton_group: Used internally for drivers that have only one group
+  * @max_pasids: number of supported PASIDs
+  */
+ struct iommu_device {
+@@ -385,6 +386,7 @@ struct iommu_device {
+ 	const struct iommu_ops *ops;
+ 	struct fwnode_handle *fwnode;
+ 	struct device *dev;
++	struct iommu_group *singleton_group;
+ 	u32 max_pasids;
+ };
+ 
+@@ -648,6 +650,7 @@ extern struct iommu_group *pci_device_gr
+ extern struct iommu_group *generic_device_group(struct device *dev);
+ /* FSL-MC device grouping function */
+ struct iommu_group *fsl_mc_device_group(struct device *dev);
++extern struct iommu_group *generic_single_device_group(struct device *dev);
+ 
+ /**
+  * struct iommu_fwspec - per-device IOMMU instance data
diff --git a/target/linux/tegra/patches-6.6/014-v6.7-iommu-Do-not-use-IOMMU_DOMAIN_DMA-if-CONFIG_IOMMU_DM.patch b/target/linux/tegra/patches-6.6/014-v6.7-iommu-Do-not-use-IOMMU_DOMAIN_DMA-if-CONFIG_IOMMU_DM.patch
new file mode 100644
index 000000000000..542f0d18c2f2
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/014-v6.7-iommu-Do-not-use-IOMMU_DOMAIN_DMA-if-CONFIG_IOMMU_DM.patch
@@ -0,0 +1,46 @@
+From 0f6a90436a5771fc9f6ca0d1e64f7549219e6c3c Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Tue, 3 Oct 2023 13:52:36 -0300
+Subject: [PATCH 1/2] iommu: Do not use IOMMU_DOMAIN_DMA if CONFIG_IOMMU_DMA is
+ not enabled
+
+msm_iommu platforms do not select either CONFIG_IOMMU_DMA or
+CONFIG_ARM_DMA_USE_IOMMU so they create a IOMMU_DOMAIN_DMA domain by
+default and never populate it. This acts like a BLOCKED domain and breaks
+the GPU driver on the platform.
+
+Detect this and force use of IDENTITY instead.
+
+Fixes: 98ac73f99bc4 ("iommu: Require a default_domain for all iommu drivers")
+Reported-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/linux-iommu/CAA8EJprz7VVmBG68U9zLuqPd0UdSRHYoLDJSP6tCj6H6qanuTQ@mail.gmail.com/
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/0-v1-20700abdf239+19c-iommu_no_dma_iommu_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -1922,6 +1922,18 @@ static int iommu_get_default_domain_type
+ 		}
+ 	}
+ 
++	/*
++	 * If the common dma ops are not selected in kconfig then we cannot use
++	 * IOMMU_DOMAIN_DMA at all. Force IDENTITY if nothing else has been
++	 * selected.
++	 */
++	if (!IS_ENABLED(CONFIG_IOMMU_DMA)) {
++		if (WARN_ON(driver_type == IOMMU_DOMAIN_DMA))
++			return -1;
++		if (!driver_type)
++			driver_type = IOMMU_DOMAIN_IDENTITY;
++	}
++
+ 	if (untrusted) {
+ 		if (driver_type && driver_type != IOMMU_DOMAIN_DMA) {
+ 			dev_err_ratelimited(
diff --git a/target/linux/tegra/patches-6.6/015-v6.7-iommu-Fix-return-code-in-iommu_group_alloc_default_d.patch b/target/linux/tegra/patches-6.6/015-v6.7-iommu-Fix-return-code-in-iommu_group_alloc_default_d.patch
new file mode 100644
index 000000000000..9f7914ad98ce
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/015-v6.7-iommu-Fix-return-code-in-iommu_group_alloc_default_d.patch
@@ -0,0 +1,29 @@
+From b85b4f30846bb169c114e99ceee17cc119f02a4b Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@nvidia.com>
+Date: Wed, 4 Oct 2023 09:08:32 -0300
+Subject: [PATCH 2/2] iommu: Fix return code in
+ iommu_group_alloc_default_domain()
+
+This function returns NULL on errors, not ERR_PTR.
+
+Fixes: 1c68cbc64fe6 ("iommu: Add IOMMU_DOMAIN_PLATFORM")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/8fb75157-6c81-4a9c-9992-d73d49902fa8@moroto.mountain
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/0-v2-ee2bae9af0f2+96-iommu_ga_err_ptr_jgg@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+---
+ drivers/iommu/iommu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -1787,7 +1787,7 @@ iommu_group_alloc_default_domain(struct
+ 	 */
+ 	if (ops->default_domain) {
+ 		if (req_type)
+-			return ERR_PTR(-EINVAL);
++			return NULL;
+ 		return ops->default_domain;
+ 	}
+ 
diff --git a/target/linux/tegra/patches-6.6/016-v6.12-arm64-tegra-Fix-gpio-for-P2597-vmmc-regulator.patch b/target/linux/tegra/patches-6.6/016-v6.12-arm64-tegra-Fix-gpio-for-P2597-vmmc-regulator.patch
new file mode 100644
index 000000000000..278dda0ee9e8
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/016-v6.12-arm64-tegra-Fix-gpio-for-P2597-vmmc-regulator.patch
@@ -0,0 +1,28 @@
+From 46a26db82748a9434fae662738ff80e350b179ee Mon Sep 17 00:00:00 2001
+From: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
+Date: Thu, 15 Aug 2024 16:50:39 +0100
+Subject: [PATCH 1/2] arm64: tegra: Fix gpio for P2597 vmmc regulator
+
+The current declaration is off-by-one and actually corresponds to the
+wp-gpio of the external slot.
+
+Tested on a P2597 board.
+
+Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
+Tested-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+---
+ arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
+@@ -1603,7 +1603,7 @@
+ 		regulator-name = "VDD_3V3_SD";
+ 		regulator-min-microvolt = <3300000>;
+ 		regulator-max-microvolt = <3300000>;
+-		gpio = <&gpio TEGRA_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
++		gpio = <&gpio TEGRA_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
+ 		enable-active-high;
+ 		vin-supply = <&vdd_3v3_sys>;
+ 
diff --git a/target/linux/tegra/patches-6.6/017-v6.12-arm64-tegra-Add-wp-gpio-for-P2597-s-external-card-sl.patch b/target/linux/tegra/patches-6.6/017-v6.12-arm64-tegra-Add-wp-gpio-for-P2597-s-external-card-sl.patch
new file mode 100644
index 000000000000..1b97ea0bd589
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/017-v6.12-arm64-tegra-Add-wp-gpio-for-P2597-s-external-card-sl.patch
@@ -0,0 +1,27 @@
+From ebe899563a83c9bb578248eb4a4d56414275d9fa Mon Sep 17 00:00:00 2001
+From: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
+Date: Thu, 15 Aug 2024 16:50:40 +0100
+Subject: [PATCH 2/2] arm64: tegra: Add wp-gpio for P2597's external card slot
+
+Add the definition for the wp-gpio of the P2597's external card slot,
+enabling this functionality.
+
+Tested on a P2597 board.
+
+Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
+Tested-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+---
+ arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
+@@ -1517,6 +1517,7 @@
+ 		bus-width = <4>;
+ 
+ 		cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
++		wp-gpios = <&gpio TEGRA_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
+ 
+ 		vqmmc-supply = <&vddio_sdmmc>;
+ 		vmmc-supply = <&vdd_3v3_sd>;
diff --git a/target/linux/tegra/patches-6.6/018-v6.12-arm64-tegra-Wire-up-power-sensors-on-Jetson-TX1-DevK.patch b/target/linux/tegra/patches-6.6/018-v6.12-arm64-tegra-Wire-up-power-sensors-on-Jetson-TX1-DevK.patch
new file mode 100644
index 000000000000..aa776666f592
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/018-v6.12-arm64-tegra-Wire-up-power-sensors-on-Jetson-TX1-DevK.patch
@@ -0,0 +1,112 @@
+From 3ed4e0986028867d1a2fe68da933dd935b12af9e Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Wed, 21 Aug 2024 20:58:03 +0200
+Subject: [PATCH 1/3] arm64: tegra: Wire up power sensors on Jetson TX1 DevKit
+
+One INA3221 sensor is located on P2180 module and the other two are on
+P2597 base board.
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+---
+ .../arm64/boot/dts/nvidia/tegra210-p2180.dtsi | 29 +++++++++++
+ .../arm64/boot/dts/nvidia/tegra210-p2597.dtsi | 50 +++++++++++++++++++
+ 2 files changed, 79 insertions(+)
+
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+@@ -33,6 +33,35 @@
+ 		status = "okay";
+ 	};
+ 
++	i2c@7000c400 {
++		status = "okay";
++
++		power-sensor@40 {
++			compatible = "ti,ina3221";
++			reg = <0x40>;
++			#address-cells = <1>;
++			#size-cells = <0>;
++
++			input@0 {
++				reg = <0x0>;
++				label = "VDD_IN";
++				shunt-resistor-micro-ohms = <20000>;
++			};
++
++			input@1 {
++				reg = <0x1>;
++				label = "VDD_GPU";
++				shunt-resistor-micro-ohms = <10000>;
++			};
++
++			input@2 {
++				reg = <0x2>;
++				label = "VDD_CPU";
++				shunt-resistor-micro-ohms = <10000>;
++			};
++		};
++	};
++
+ 	i2c@7000c500 {
+ 		status = "okay";
+ 
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
+@@ -1319,6 +1319,56 @@
+ 		status = "okay";
+ 		clock-frequency = <100000>;
+ 
++		power-sensor@42 {
++			compatible = "ti,ina3221";
++			reg = <0x42>;
++			#address-cells = <1>;
++			#size-cells = <0>;
++
++			input@0 {
++				reg = <0x0>;
++				label = "VDD_MUX";
++				shunt-resistor-micro-ohms = <20000>;
++			};
++
++			input@1 {
++				reg = <0x1>;
++				label = "VDD_5V_IO_SYS";
++				shunt-resistor-micro-ohms = <5000>;
++			};
++
++			input@2 {
++				reg = <0x2>;
++				label = "VDD_3V3_SYS";
++				shunt-resistor-micro-ohms = <10000>;
++			};
++		};
++
++		power-sensor@43 {
++			compatible = "ti,ina3221";
++			reg = <0x43>;
++			#address-cells = <1>;
++			#size-cells = <0>;
++
++			input@0 {
++				reg = <0x0>;
++				label = "VDD_3V3_IO";
++				shunt-resistor-micro-ohms = <10000>;
++			};
++
++			input@1 {
++				reg = <0x1>;
++				label = "VDD_1V8_IO";
++				shunt-resistor-micro-ohms = <10000>;
++			};
++
++			input@2 {
++				reg = <0x2>;
++				label = "VDD_M2_IN";
++				shunt-resistor-micro-ohms = <10000>;
++			};
++		};
++
+ 		exp1: gpio@74 {
+ 			compatible = "ti,tca9539";
+ 			reg = <0x74>;
diff --git a/target/linux/tegra/patches-6.6/019-v6.12-arm64-tegra-Wire-up-Bluetooth-on-Jetson-TX1-module.patch b/target/linux/tegra/patches-6.6/019-v6.12-arm64-tegra-Wire-up-Bluetooth-on-Jetson-TX1-module.patch
new file mode 100644
index 000000000000..d0f5ac7a12cc
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/019-v6.12-arm64-tegra-Wire-up-Bluetooth-on-Jetson-TX1-module.patch
@@ -0,0 +1,43 @@
+From 6eba6471bbb7e3bf27e2b540fb7282848a58cd17 Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Wed, 21 Aug 2024 20:58:04 +0200
+Subject: [PATCH 2/3] arm64: tegra: Wire up Bluetooth on Jetson TX1 module
+
+P2180 modules have Bluetooth in form of BCM4354 chip, and kernel driver
+supports this one, so enable it for all users. The necessary firmware
+can be obtained from Jetson Linux Archive. bcm4354.hcd file is located
+in "Driver Package (BSP)" in
+nv_tegra/l4t_deb_packages/nvidia-l4t-firmware_<version>_arm64.deb
+archive.
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+---
+ arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+@@ -33,6 +33,22 @@
+ 		status = "okay";
+ 	};
+ 
++	serial@70006300 {
++		/delete-property/ reg-shift;
++		status = "okay";
++		compatible = "nvidia,tegra30-hsuart";
++		reset-names = "serial";
++
++		bluetooth {
++			compatible = "brcm,bcm43540-bt";
++			device-wakeup-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
++			shutdown-gpios = <&gpio TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
++			interrupt-parent = <&gpio>;
++			interrupts = <TEGRA_GPIO(H, 5) IRQ_TYPE_LEVEL_LOW>;
++			interrupt-names = "host-wakeup";
++		};
++	};
++
+ 	i2c@7000c400 {
+ 		status = "okay";
+ 
diff --git a/target/linux/tegra/patches-6.6/020-v6.12-arm64-tegra-Wire-up-WiFi-on-Jetson-TX1-module.patch b/target/linux/tegra/patches-6.6/020-v6.12-arm64-tegra-Wire-up-WiFi-on-Jetson-TX1-module.patch
new file mode 100644
index 000000000000..b695373b301f
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/020-v6.12-arm64-tegra-Wire-up-WiFi-on-Jetson-TX1-module.patch
@@ -0,0 +1,48 @@
+From a50d5dcd28154c1a38aa1d72b1678715aecf5464 Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Wed, 21 Aug 2024 20:58:05 +0200
+Subject: [PATCH 3/3] arm64: tegra: Wire up WiFi on Jetson TX1 module
+
+P2180 modules have WiFi in form of BCM4354 chip, and kernel driver
+supports this one, so enable it for all users. The necessary calibration
+file can be obtained from Jetson Linux Archive. nvram.txt file is
+located in "Driver Package (BSP)" in
+nv_tegra/l4t_deb_packages/nvidia-l4t-firmware_<version>_arm64.deb
+archive. The rest of necessary blobs can be obtained from official
+Linux Firmware repository or (newer ones) from Infineon
+ifx-linux-firmware repository (look in older releases).
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+---
+ .../arm64/boot/dts/nvidia/tegra210-p2180.dtsi | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+@@ -340,6 +340,25 @@
+ 		nvidia,sys-clock-req-active-high;
+ 	};
+ 
++	mmc@700b0200 {
++		status = "okay";
++		bus-width = <4>;
++		non-removable;
++		power-gpios = <&gpio TEGRA_GPIO(H, 0) GPIO_ACTIVE_HIGH>;
++		vqmmc-supply = <&vdd_1v8>;
++		vmmc-supply = <&vdd_3v3_sys>;
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		wifi@1 {
++			compatible = "brcm,bcm4354-fmac";
++			reg = <1>;
++			interrupt-parent = <&gpio>;
++			interrupts = <TEGRA_GPIO(H, 2) IRQ_TYPE_LEVEL_HIGH>;
++			interrupt-names = "host-wake";
++		};
++	};
++
+ 	/* eMMC */
+ 	mmc@700b0600 {
+ 		status = "okay";
diff --git a/target/linux/tegra/patches-6.6/021-v6.13-arm64-tegra-Add-SDMMC-sdr104-offsets-for-Tegra-X1.patch b/target/linux/tegra/patches-6.6/021-v6.13-arm64-tegra-Add-SDMMC-sdr104-offsets-for-Tegra-X1.patch
new file mode 100644
index 000000000000..1310ce4bf0de
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/021-v6.13-arm64-tegra-Add-SDMMC-sdr104-offsets-for-Tegra-X1.patch
@@ -0,0 +1,29 @@
+From 87b90082179daf87969ad9ff44032acc59d9086a Mon Sep 17 00:00:00 2001
+From: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
+Date: Mon, 23 Sep 2024 19:24:51 +0100
+Subject: [PATCH] arm64: tegra: Add SDMMC sdr104-offsets for Tegra X1
+
+Define the sdr104-specific offsets, preventing the driver from
+defaulting to the 1.8V offsets, which cause the system to hang during
+the SDR104 mode calibration.
+
+The zeroing of these values was chosen since it restores functionality
+and no better suggestions are provided by the Tegra X1 TRM.
+
+Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+---
+ arch/arm64/boot/dts/nvidia/tegra210.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+@@ -1218,6 +1218,8 @@
+ 		nvidia,pad-autocal-pull-down-offset-3v3 = <0x7d>;
+ 		nvidia,pad-autocal-pull-up-offset-1v8 = <0x7b>;
+ 		nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
++		nvidia,pad-autocal-pull-up-offset-sdr104 = <0x0>;
++		nvidia,pad-autocal-pull-down-offset-sdr104 = <0x0>;
+ 		nvidia,default-tap = <0x2>;
+ 		nvidia,default-trim = <0x4>;
+ 		assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
diff --git a/target/linux/tegra/patches-6.6/102-Revert-Bluetooth-hci_bcm-do-not-mark-valid-bd_addr-a.patch b/target/linux/tegra/patches-6.6/102-Revert-Bluetooth-hci_bcm-do-not-mark-valid-bd_addr-a.patch
new file mode 100644
index 000000000000..d07c39dbbcf6
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/102-Revert-Bluetooth-hci_bcm-do-not-mark-valid-bd_addr-a.patch
@@ -0,0 +1,27 @@
+From 344cb1d9e869381a9d47d41b74b3c386ede1976b Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Tue, 6 Aug 2024 22:12:58 +0200
+Subject: [PATCH] Revert "Bluetooth: hci_bcm: do not mark valid bd_addr as
+ invalid"
+
+This reverts commit 56b7f325db139c9255b1eb1d1e741576d5f8fa34, as driver
+sets the invalid flag, there is no way to asign address provided by
+local-bd-address property.
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+---
+ drivers/bluetooth/hci_bcm.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -643,8 +643,7 @@ static int bcm_setup(struct hci_uart *hu
+ 	 * Allow the bootloader to set a valid address through the
+ 	 * device tree.
+ 	 */
+-	if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks))
+-		set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hu->hdev->quirks);
++	set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hu->hdev->quirks);
+ 
+ 	if (!bcm_request_irq(bcm))
+ 		err = bcm_setup_sleep(hu);
diff --git a/target/linux/tegra/patches-6.6/103-arm64-tegra-wire-up-PWM-fan-on-Jetson-TX1-DevKit-bas.patch b/target/linux/tegra/patches-6.6/103-arm64-tegra-wire-up-PWM-fan-on-Jetson-TX1-DevKit-bas.patch
new file mode 100644
index 000000000000..794d61dbef08
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/103-arm64-tegra-wire-up-PWM-fan-on-Jetson-TX1-DevKit-bas.patch
@@ -0,0 +1,49 @@
+From a78c520ec94aeab2c9dc8e1f46597c4174ff957d Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Tue, 16 Jul 2024 20:29:13 +0200
+Subject: [PATCH 1/2] arm64: tegra: wire up PWM fan on Jetson TX1 DevKit base
+ board
+
+With enabling Bluetooth and WiFi the P2180 module starts to warm up, so
+to keep it cool, enable PWM fan connected to J15 header on P2597 base
+board. No colling map yet specified, as the polarity seems to be
+inverted(?) and 255 value in sysfs is no rotation and 0 is the highest
+rotation speed. Needs to be investigated.
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+---
+ arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
+@@ -1605,6 +1605,14 @@
+ 		};
+ 	};
+ 
++	pwm-fan {
++		compatible = "pwm-fan";
++		pwms = <&pwm 3 45334>;
++		fan-supply = <&vdd_fan>;
++		interrupt-parent = <&gpio>;
++		interrupts = <TEGRA_GPIO(K, 7) IRQ_TYPE_EDGE_BOTH>;
++	};
++
+ 	vdd_sys_mux: regulator-vdd-sys-mux {
+ 		compatible = "regulator-fixed";
+ 		regulator-name = "VDD_SYS_MUX";
+@@ -1760,4 +1768,14 @@
+ 		enable-active-high;
+ 		vin-supply = <&vdd_5v0_sys>;
+ 	};
++
++	vdd_fan: regulator-vdd-fan {
++		compatible = "regulator-fixed";
++		regulator-name = "VDD_FAN_5V0";
++		regulator-min-microvolt = <5000000>;
++		regulator-max-microvolt = <5000000>;
++		regulator-enable-ramp-delay = <284>;
++		gpio = <&exp1 4 GPIO_ACTIVE_LOW>;
++		vin-supply = <&vdd_5v0_sys>;
++	};
+ };
diff --git a/target/linux/tegra/patches-6.6/104-arm64-tegra-add-cooling-maps-for-Jetson-TX1-module.patch b/target/linux/tegra/patches-6.6/104-arm64-tegra-add-cooling-maps-for-Jetson-TX1-module.patch
new file mode 100644
index 000000000000..560db75d54cb
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/104-arm64-tegra-add-cooling-maps-for-Jetson-TX1-module.patch
@@ -0,0 +1,127 @@
+From 99beee4f0cd5d3a6f30e1829d823c11cb8b54bac Mon Sep 17 00:00:00 2001
+From: Tomasz Maciej Nowak <tmn505@gmail.com>
+Date: Thu, 18 Jul 2024 15:46:16 +0200
+Subject: [PATCH 2/2] arm64: tegra: add cooling maps for Jetson TX1 module
+
+The PWM signals are indeed inverted, so work around it by specifying
+colling levels in reverse order, since driver does not implement
+inverted polarity.
+
+Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
+---
+ .../arm64/boot/dts/nvidia/tegra210-p2180.dtsi | 85 +++++++++++++++++++
+ .../arm64/boot/dts/nvidia/tegra210-p2597.dtsi |  4 +-
+ 2 files changed, 88 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+@@ -402,6 +402,91 @@
+ 		method = "smc";
+ 	};
+ 
++	thermal-zones {
++		cpu-thermal {
++			trips {
++				cpu_trip_critical: critical {
++					temperature = <94000>;
++					hysteresis = <0>;
++					type = "critical";
++				};
++
++				cpu_trip_hot: hot {
++					temperature = <86000>;
++					hysteresis = <1000>;
++					type = "hot";
++				};
++
++				cpu_trip_active_78: active-78 {
++					temperature = <78000>;
++					hysteresis = <2000>;
++					type = "active";
++				};
++
++				cpu_trip_active_70: active-70 {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "active";
++				};
++
++				cpu_trip_active_60: active-60 {
++					temperature = <60000>;
++					hysteresis = <2000>;
++					type = "active";
++				};
++
++				cpu_trip_active_50: active-50 {
++					temperature = <50000>;
++					hysteresis = <2000>;
++					type = "active";
++				};
++
++				cpu_trip_passive: passive {
++					temperature = <23000>;
++					hysteresis = <2000>;
++					type = "passive";
++				};
++			};
++
++			cooling-maps {
++				cpu-critical {
++					cooling-device = <&fan 6 6>;
++					trip = <&cpu_trip_critical>;
++				};
++
++				cpu-hot {
++					cooling-device = <&fan 5 5>;
++					trip = <&cpu_trip_hot>;
++				};
++
++				cpu-active-78 {
++					cooling-device = <&fan 4 4>;
++					trip = <&cpu_trip_active_78>;
++				};
++
++				cpu-active-70 {
++					cooling-device = <&fan 3 3>;
++					trip = <&cpu_trip_active_70>;
++				};
++
++				cpu-active-60 {
++					cooling-device = <&fan 2 2>;
++					trip = <&cpu_trip_active_60>;
++				};
++
++				cpu-active-50 {
++					cooling-device = <&fan 1 1>;
++					trip = <&cpu_trip_active_50>;
++				};
++
++				cpu-passive {
++					cooling-device = <&fan 0 0>;
++					trip = <&cpu_trip_passive>;
++				};
++			};
++		};
++	};
++
+ 	vdd_gpu: regulator-vdd-gpu {
+ 		compatible = "pwm-regulator";
+ 		pwms = <&pwm 1 8000>;
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
+@@ -1605,12 +1605,14 @@
+ 		};
+ 	};
+ 
+-	pwm-fan {
++	fan: pwm-fan {
+ 		compatible = "pwm-fan";
+ 		pwms = <&pwm 3 45334>;
+ 		fan-supply = <&vdd_fan>;
+ 		interrupt-parent = <&gpio>;
+ 		interrupts = <TEGRA_GPIO(K, 7) IRQ_TYPE_EDGE_BOTH>;
++		cooling-levels = <255 192 160 128 96 64 0>;
++		#cooling-cells = <2>;
+ 	};
+ 
+ 	vdd_sys_mux: regulator-vdd-sys-mux {
diff --git a/target/linux/tegra/patches-6.6/105-arm64-tegra-keep-crucial-sysfs-paths-constant.patch b/target/linux/tegra/patches-6.6/105-arm64-tegra-keep-crucial-sysfs-paths-constant.patch
new file mode 100644
index 000000000000..8e4e422da55b
--- /dev/null
+++ b/target/linux/tegra/patches-6.6/105-arm64-tegra-keep-crucial-sysfs-paths-constant.patch
@@ -0,0 +1,14 @@
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+@@ -8,9 +8,11 @@
+ 	compatible = "nvidia,p2180", "nvidia,tegra210";
+ 
+ 	aliases {
++		mmc1 = "/mmc@700b0200";
+ 		rtc0 = "/i2c@7000d000/pmic@3c";
+ 		rtc1 = "/rtc@7000e000";
+ 		serial0 = &uarta;
++		serial3 = &uartd;
+ 	};
+ 
+ 	chosen {
