[OpenWrt-Devel] [PATCH 1/7] tegra: add new target

Tomasz Maciej Nowak tomek_n at o2.pl
Mon Mar 4 13:53:20 EST 2019


New target introduces initial support for NVIDIA Tegra SoC based devices.
It focuses on Tegra 2 CPUs, for successors supporting NEON instruction
set the target should be split in two subtargets.
This initial commit doesn't create any device image, it's groundwork
for further additions.

Signed-off-by: Tomasz Maciej Nowak <tomek_n at o2.pl>
---
 package/kernel/linux/modules/input.mk         |  18 +
 package/kernel/linux/modules/netdevices.mk    |   4 +-
 package/kernel/linux/modules/sound.mk         |  52 ++
 package/kernel/linux/modules/video.mk         |  36 ++
 target/linux/generic/config-4.14              |   1 +
 target/linux/tegra/Makefile                   |  29 ++
 target/linux/tegra/base-files/etc/inittab     |   4 +
 .../base-files/lib/preinit/79_move_config     |  22 +
 .../tegra/base-files/lib/upgrade/platform.sh  | 103 ++++
 target/linux/tegra/config-4.14                | 487 ++++++++++++++++++
 target/linux/tegra/image/Makefile             |  47 ++
 target/linux/tegra/image/generic-bootscript   |   6 +
 ...interrupts-due-to-tegra2-silicon-bug.patch |  77 +++
 13 files changed, 884 insertions(+), 2 deletions(-)
 create mode 100644 target/linux/tegra/Makefile
 create mode 100644 target/linux/tegra/base-files/etc/inittab
 create mode 100644 target/linux/tegra/base-files/lib/preinit/79_move_config
 create mode 100644 target/linux/tegra/base-files/lib/upgrade/platform.sh
 create mode 100644 target/linux/tegra/config-4.14
 create mode 100644 target/linux/tegra/image/Makefile
 create mode 100644 target/linux/tegra/image/generic-bootscript
 create mode 100644 target/linux/tegra/patches-4.14/100-serial8250-on-tegra-hsuart-recover-from-spurious-interrupts-due-to-tegra2-silicon-bug.patch

diff --git a/package/kernel/linux/modules/input.mk b/package/kernel/linux/modules/input.mk
index 99257b6725..a890c4e56a 100644
--- a/package/kernel/linux/modules/input.mk
+++ b/package/kernel/linux/modules/input.mk
@@ -226,3 +226,21 @@ define KernelPackage/input-uinput/description
 endef
 
 $(eval $(call KernelPackage,input-uinput))
+
+
+define KernelPackage/keyboard-tegra
+  SUBMENU:=$(INPUT_MODULES_MENU)
+  TITLE:=Tegra keypad support
+  DEPENDS:=@TARGET_tegra +kmod-input-matrixkmap
+  KCONFIG:= \
+	CONFIG_KEYBOARD_TEGRA \
+	CONFIG_INPUT_KEYBOARD=y
+  FILES:=$(LINUX_DIR)/drivers/input/keyboard/tegra-kbc.ko
+  AUTOLOAD:=$(call AutoProbe,tegra-kbc)
+endef
+
+define KernelPackage/keyboard-tegra/description
+ Enable support for NVIDIA Tegra keypad controller.
+endef
+
+$(eval $(call KernelPackage,keyboard-tegra))
diff --git a/package/kernel/linux/modules/netdevices.mk b/package/kernel/linux/modules/netdevices.mk
index fbc24b8405..2e29a5441f 100644
--- a/package/kernel/linux/modules/netdevices.mk
+++ b/package/kernel/linux/modules/netdevices.mk
@@ -113,7 +113,7 @@ $(eval $(call KernelPackage,mii))
 define KernelPackage/mdio-gpio
   SUBMENU:=$(NETWORK_DEVICES_MENU)
   TITLE:= Supports GPIO lib-based MDIO busses
-  DEPENDS:=+kmod-libphy @GPIO_SUPPORT +(TARGET_armvirt||TARGET_brcm2708_bcm2708||TARGET_samsung):kmod-of-mdio
+  DEPENDS:=+kmod-libphy @GPIO_SUPPORT +(TARGET_armvirt||TARGET_brcm2708_bcm2708||TARGET_samsung||TARGET_tegra):kmod-of-mdio
   KCONFIG:= \
 	CONFIG_MDIO_BITBANG \
 	CONFIG_MDIO_GPIO
@@ -261,7 +261,7 @@ $(eval $(call KernelPackage,switch-rtl8306))
 define KernelPackage/switch-rtl8366-smi
   SUBMENU:=$(NETWORK_DEVICES_MENU)
   TITLE:=Realtek RTL8366 SMI switch interface support
-  DEPENDS:=@GPIO_SUPPORT +kmod-swconfig +(TARGET_armvirt||TARGET_brcm2708_bcm2708||TARGET_samsung):kmod-of-mdio
+  DEPENDS:=@GPIO_SUPPORT +kmod-swconfig +(TARGET_armvirt||TARGET_brcm2708_bcm2708||TARGET_samsung||TARGET_tegra):kmod-of-mdio
   KCONFIG:=CONFIG_RTL8366_SMI
   FILES:=$(LINUX_DIR)/drivers/net/phy/rtl8366_smi.ko
   AUTOLOAD:=$(call AutoLoad,42,rtl8366_smi)
diff --git a/package/kernel/linux/modules/sound.mk b/package/kernel/linux/modules/sound.mk
index bf4bd5d7c0..0c20cc6c9d 100644
--- a/package/kernel/linux/modules/sound.mk
+++ b/package/kernel/linux/modules/sound.mk
@@ -273,6 +273,58 @@ endef
 $(eval $(call KernelPackage,sound-soc-gw_avila))
 
 
+define KernelPackage/sound-soc-tegra20
+  TITLE:=Tegra 2 built-in SoC Audio support
+  KCONFIG:= \
+	CONFIG_SND_SOC_TEGRA \
+	CONFIG_SND_SOC_TEGRA20_AC97 \
+	CONFIG_SND_SOC_TEGRA20_DAS \
+	CONFIG_SND_SOC_TEGRA20_I2S \
+	CONFIG_SND_HDA_TEGRA=n \
+	CONFIG_SND_SOC_TEGRA30_AHUB=n \
+	CONFIG_SND_SOC_TEGRA30_I2S=n \
+	CONFIG_SND_SOC_TEGRA_TRIMSLICE=n \
+	CONFIG_SND_SOC_TEGRA_ALC5632=n \
+	CONFIG_SND_SOC_TEGRA_MAX98090=n \
+	CONFIG_SND_SOC_TEGRA_RT5640=n \
+	CONFIG_SND_SOC_TEGRA_RT5677=n \
+	CONFIG_SND_SOC_TEGRA_SGTL5000=n \
+	CONFIG_SND_SOC_TEGRA_WM8753=n \
+	CONFIG_SND_SOC_TEGRA_WM8903=n \
+	CONFIG_SND_SOC_TEGRA_WM9712=n
+  FILES:= \
+	$(LINUX_DIR)/sound/soc/tegra/snd-soc-tegra-utils.ko \
+	$(LINUX_DIR)/sound/soc/tegra/snd-soc-tegra-pcm.ko \
+	$(LINUX_DIR)/sound/soc/tegra/snd-soc-tegra20-das.ko \
+	$(LINUX_DIR)/sound/soc/tegra/snd-soc-tegra20-i2s.ko
+  AUTOLOAD:=$(call AutoProbe,snd-soc-tegra-utils snd-soc-tegra-pcm snd-soc-tegra20-das snd-soc-tegra20-i2s)
+  DEPENDS:= @TARGET_tegra +kmod-regmap-mmio +kmod-sound-soc-core +kmod-sound-soc-ac97
+  $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-soc-tegra20/description
+ Kernel support for Tegra 2 built-in SoC Audio
+endef
+
+$(eval $(call KernelPackage,sound-soc-tegra20))
+
+
+define KernelPackage/sound-soc-tegra20-spdif
+  TITLE:=Tegra 2 built-in SoC S/PDIF support
+  KCONFIG:= CONFIG_SND_SOC_TEGRA20_SPDIF
+  FILES:= $(LINUX_DIR)/sound/soc/tegra/snd-soc-tegra20-spdif.ko
+  AUTOLOAD:=$(call AutoProbe,snd-soc-tegra20-spdif)
+  DEPENDS:= @TARGET_tegra +kmod-sound-soc-tegra20
+  $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-soc-tegra20-spdif/description
+ Kernel support for Tegra 2 built-in SoC S/PDIF
+endef
+
+$(eval $(call KernelPackage,sound-soc-tegra20-spdif))
+
+
 define KernelPackage/pcspkr
   DEPENDS:=@TARGET_x86 +kmod-input-core
   TITLE:=PC speaker support
diff --git a/package/kernel/linux/modules/video.mk b/package/kernel/linux/modules/video.mk
index f11431dc2d..8f630a8d19 100644
--- a/package/kernel/linux/modules/video.mk
+++ b/package/kernel/linux/modules/video.mk
@@ -354,6 +354,42 @@ endef
 
 $(eval $(call KernelPackage,drm-radeon))
 
+define KernelPackage/drm-tegra
+  SUBMENU:=$(VIDEO_MENU)
+  TITLE:=NVIDIA Tegra DRM support
+  DEPENDS:=@TARGET_tegra +kmod-drm +kmod-fb +kmod-fb-cfb-copyarea +kmod-fb-cfb-imgblt +kmod-fb-cfb-fillrect +kmod-fb-sys-fops
+  KCONFIG:=CONFIG_DRM_TEGRA \
+	CONFIG_DRM_TEGRA_DEBUG=n \
+	CONFIG_DRM_TEGRA_STAGING=n \
+	CONFIG_DRM_FBDEV_EMULATION=y \
+	CONFIG_DRM_FBDEV_OVERALLOC=100 \
+	CONFIG_TEGRA_HOST1X \
+	CONFIG_TEGRA_HOST1X_FIREWALL=y \
+	CONFIG_DRM_KMS_HELPER \
+	CONFIG_FB_SYS_FILLRECT \
+	CONFIG_FB_SYS_COPYAREA \
+	CONFIG_FB_SYS_IMAGEBLIT \
+	CONFIG_DRM_KMS_FB_HELPER=y \
+	CONFIG_DRM_GEM_CMA_HELPER=y \
+	CONFIG_DRM_KMS_CMA_HELPER=y
+  FILES:= \
+	$(LINUX_DIR)/drivers/gpu/drm/tegra/tegra-drm.ko \
+	$(LINUX_DIR)/drivers/gpu/host1x/host1x.ko \
+	$(LINUX_DIR)/drivers/video/fbdev/core/syscopyarea.ko \
+	$(LINUX_DIR)/drivers/video/fbdev/core/sysfillrect.ko \
+	$(LINUX_DIR)/drivers/video/fbdev/core/sysimgblt.ko \
+	$(LINUX_DIR)/drivers/gpu/drm/drm_kms_helper.ko \
+	$(LINUX_DIR)/drivers/iommu/iova.ko
+  AUTOLOAD:=$(call AutoLoad,05,host1x iova tegra-drm)
+endef
+
+define KernelPackage/drm-tegra/description
+  Direct Rendering Manager (DRM) support for NVIDIA Tegra
+endef
+
+$(eval $(call KernelPackage,drm-tegra))
+
+
 #
 # Video Capture
 #
diff --git a/target/linux/generic/config-4.14 b/target/linux/generic/config-4.14
index cabdd9d01d..60e877c94e 100644
--- a/target/linux/generic/config-4.14
+++ b/target/linux/generic/config-4.14
@@ -5498,6 +5498,7 @@ CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
 # CONFIG_USB_WUSB is not set
 # CONFIG_USB_WUSB_CBAF is not set
 # CONFIG_USB_XHCI_HCD is not set
+# CONFIG_USB_XHCI_TEGRA is not set
 # CONFIG_USB_XUSBATM is not set
 # CONFIG_USB_YUREX is not set
 # CONFIG_USB_ZD1201 is not set
diff --git a/target/linux/tegra/Makefile b/target/linux/tegra/Makefile
new file mode 100644
index 0000000000..57cb902cfd
--- /dev/null
+++ b/target/linux/tegra/Makefile
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2017-2019 Tomasz Maciej Nowak <tomek_n at o2.pl>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+ARCH := arm
+BOARD := tegra
+BOARDNAME := NVIDIA Tegra
+FEATURES := audio boot-part display ext4 fpu gpio pci pcie rootfs-part rtc squashfs usb
+CPU_TYPE := cortex-a9
+CPU_SUBTYPE := vfpv3
+MAINTAINER := Tomasz Maciej Nowak <tomek_n at o2.pl>
+
+KERNEL_PATCHVER := 4.14
+
+include $(INCLUDE_DIR)/target.mk
+
+KERNELNAME := zImage dtbs
+
+DEFAULT_PACKAGES += e2fsprogs mkf2fs partx-utils
+
+define Target/Description
+	Build firmware image for NVIDIA Tegra SoC devices.
+endef
+
+$(eval $(call BuildTarget))
diff --git a/target/linux/tegra/base-files/etc/inittab b/target/linux/tegra/base-files/etc/inittab
new file mode 100644
index 0000000000..b944a93ada
--- /dev/null
+++ b/target/linux/tegra/base-files/etc/inittab
@@ -0,0 +1,4 @@
+::sysinit:/etc/init.d/rcS S boot
+::shutdown:/etc/init.d/rcS K shutdown
+::askconsole:/usr/libexec/login.sh
+tty1::askfirst:/usr/libexec/login.sh
diff --git a/target/linux/tegra/base-files/lib/preinit/79_move_config b/target/linux/tegra/base-files/lib/preinit/79_move_config
new file mode 100644
index 0000000000..2a451a5efd
--- /dev/null
+++ b/target/linux/tegra/base-files/lib/preinit/79_move_config
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+move_config() {
+	local partdev
+
+	. /lib/upgrade/common.sh
+
+	if export_bootdevice && export_partdevice partdev 1; then
+		mkdir -p /boot
+		if mount -o ro,noatime "/dev/$partdev" /boot; then
+			if [ -f /boot/sysupgrade.tgz ]; then
+				mount /boot -o remount,rw,noatime
+				mv -f /boot/sysupgrade.tgz /
+			fi
+			umount /boot
+			rm -fR /boot
+		fi
+	fi
+}
+
+boot_hook_add preinit_mount_root move_config
+
diff --git a/target/linux/tegra/base-files/lib/upgrade/platform.sh b/target/linux/tegra/base-files/lib/upgrade/platform.sh
new file mode 100644
index 0000000000..be453bdf9f
--- /dev/null
+++ b/target/linux/tegra/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,103 @@
+REQUIRE_IMAGE_METADATA=1
+
+get_magic_at() {
+	local pos="$2"
+	get_image "$1" | dd bs=1 count=2 skip="$pos" 2>/dev/null | hexdump -v -n 2 -e '1/1 "%02x"'
+}
+
+platform_check_image() {
+	local diskdev partdev diff
+
+	[ "$#" -gt 1 ] && return 1
+
+	case "$(get_magic_at "$1" 510)" in
+		55aa) ;;
+		*)
+			echo "Failed to verify MBR boot signature."
+			return 1
+		;;
+	esac
+
+	export_bootdevice && export_partdevice diskdev 0 || {
+		echo "Unable to determine upgrade device"
+		return 1
+	}
+
+	get_partitions "/dev/$diskdev" bootdisk
+
+	#extract the boot sector from the image
+	get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
+
+	get_partitions /tmp/image.bs image
+
+	#compare tables
+	diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
+
+	rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
+
+	if [ -n "$diff" ]; then
+		echo "Partition layout has changed. Full image will be written."
+		ask_bool 0 "Abort" && exit 1
+		return 0
+	fi
+}
+
+platform_copy_config() {
+	local partdev
+
+	if export_partdevice partdev 1; then
+		mount -o rw,noatime "/dev/$partdev" /mnt
+		cp -af "$CONF_TAR" /mnt/
+		umount /mnt
+	fi
+}
+
+platform_do_upgrade() {
+	local diskdev partdev diff
+
+	export_bootdevice && export_partdevice diskdev 0 || {
+		echo "Unable to determine upgrade device"
+		return 1
+	}
+
+	sync
+
+	if [ "$SAVE_PARTITIONS" = "1" ]; then
+		get_partitions "/dev/$diskdev" bootdisk
+
+		#extract the boot sector from the image
+		get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
+
+		get_partitions /tmp/image.bs image
+
+		#compare tables
+		diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
+	else
+		diff=1
+	fi
+
+	if [ -n "$diff" ]; then
+		get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
+
+		# Separate removal and addtion is necessary; otherwise, partition 1
+		# will be missing if it overlaps with the old partition 2
+		partx -d - "/dev/$diskdev"
+		partx -a - "/dev/$diskdev"
+
+		return 0
+	fi
+
+	#iterate over each partition from the image and write it to the boot disk
+	while read part start size; do
+		if export_partdevice partdev $part; then
+			echo "Writing image to /dev/$partdev..."
+			get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
+		else
+			echo "Unable to find partition $part device, skipped."
+		fi
+	done < /tmp/partmap.image
+
+	#copy partition uuid
+	echo "Writing new UUID to /dev/$diskdev..."
+	get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
+}
diff --git a/target/linux/tegra/config-4.14 b/target/linux/tegra/config-4.14
new file mode 100644
index 0000000000..139eb68ae5
--- /dev/null
+++ b/target/linux/tegra/config-4.14
@@ -0,0 +1,487 @@
+# CONFIG_AHCI_TEGRA is not set
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAS_SET_MEMORY=y
+CONFIG_ARCH_HAS_SG_CHAIN=y
+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y
+CONFIG_ARCH_NR_GPIO=1024
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_ARCH_SUPPORTS_FIRMWARE=y
+CONFIG_ARCH_SUPPORTS_TRUSTED_FOUNDATIONS=y
+CONFIG_ARCH_SUPPORTS_UPROBES=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_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_HAS_SG_CHAIN=y
+CONFIG_ARM_HEAVY_MB=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_LPAE is not set
+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_SP805_WATCHDOG is not set
+CONFIG_ARM_TEGRA20_CPUFREQ=y
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ASN1=y
+CONFIG_ATA=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_SCSI_REQUEST=y
+CONFIG_BOUNCE=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CLKDEV_LOOKUP=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
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+CONFIG_COMMON_CLK=y
+# CONFIG_CPUFREQ_DT is not set
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+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
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+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_HOTPLUG_STATE_CONTROL is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=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_ACOMP2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_AES_ARM=y
+CONFIG_CRYPTO_AKCIPHER=y
+CONFIG_CRYPTO_AKCIPHER2=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_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LZ4=y
+CONFIG_CRYPTO_LZ4HC=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_NULL2=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_SHA512_ARM=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_ALIGN_RODATA=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+# CONFIG_DEBUG_UART_8250 is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEVPORT is not set
+CONFIG_DMADEVICES=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DNOTIFY=y
+CONFIG_DTC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXTCON=y
+# CONFIG_F2FS_CHECK_FS is not set
+CONFIG_F2FS_FS=y
+CONFIG_F2FS_FS_POSIX_ACL=y
+# CONFIG_F2FS_FS_SECURITY is not set
+CONFIG_F2FS_FS_XATTR=y
+CONFIG_F2FS_STAT_FS=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FRAME_POINTER=y
+CONFIG_FREEZER=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_TEGRA=y
+# CONFIG_GRO_CELLS is not set
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+CONFIG_HAVE_ARCH_BITREVERSE=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_SMCCC=y
+CONFIG_HAVE_ARM_TWD=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_HAVE_EBPF_JIT=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_SMP=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_UID16=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HWMON=y
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_TEGRA=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_IOMMU_API=y
+CONFIG_IOMMU_HELPER=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_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+# CONFIG_JFFS2_FS is not set
+CONFIG_KALLSYMS=y
+CONFIG_LIBFDT=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_MANDATORY_FILE_LOCKING=y
+# CONFIG_MDIO_BUS is not set
+CONFIG_MEMORY=y
+CONFIG_MEMORY_ISOLATION=y
+# CONFIG_MFD_NVEC is not set
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_TEGRA=y
+# CONFIG_MMC_TIFM_SD is not set
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MPILIB=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MULTI_IRQ_HANDLER=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+# CONFIG_NEON is not set
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NLS=y
+CONFIG_NO_BOOTMEM=y
+CONFIG_NR_CPUS=4
+CONFIG_NVMEM=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_ADDRESS_PCI=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IOMMU=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_RESERVED_MEM=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_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEASPM=y
+# CONFIG_PCIEASPM_DEBUG is not set
+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_MSI_IRQ_DOMAIN=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_588369 is not set
+CONFIG_PL310_ERRATA_727915=y
+# CONFIG_PL310_ERRATA_753970 is not set
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_OPP=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_PWM=y
+CONFIG_PWM_SYSFS=y
+CONFIG_PWM_TEGRA=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
+# CONFIG_RCU_EXPERT is not set
+CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_RCU_STALL_COMMON=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
+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_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_SCHED_INFO is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_SERIAL_8250_FSL=y
+# CONFIG_SERIAL_AMBA_PL011 is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_TEGRA=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SOC_BUS=y
+CONFIG_SOC_TEGRA_FLOWCTRL=y
+CONFIG_SOC_TEGRA_FUSE=y
+CONFIG_SOC_TEGRA_PMC=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+# CONFIG_SPI_TEGRA114 is not set
+CONFIG_SPI_TEGRA20_SFLASH=y
+CONFIG_SPI_TEGRA20_SLINK=y
+CONFIG_SRCU=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWIOTLB=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_TEGRA20_APB_DMA=y
+CONFIG_TEGRA20_MC=y
+CONFIG_TEGRA_AHB=y
+CONFIG_TEGRA_GMI=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_TIMER=y
+CONFIG_TEGRA_WATCHDOG=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_TRUSTED_FOUNDATIONS=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_USB=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_CHIPIDEA_OF=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_EHCI_TEGRA=y
+CONFIG_USB_PHY=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USE_OF=y
+CONFIG_VDSO=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_VFIO is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_WATCHDOG_CORE=y
+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
new file mode 100644
index 0000000000..757e5b823f
--- /dev/null
+++ b/target/linux/tegra/image/Makefile
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2017-2019 Tomasz Maciej Nowak <tomek_n at o2.pl>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+SIGNATURE:=$(shell printf "%.8s" $(SOURCE_DATE_EPOCH))
+
+define Build/tegra-sdcard
+	rm -fR $@.boot
+	mkdir -p $@.boot
+	$(CP) $(KDIR)/$(KERNEL_NAME) $@.boot
+	$(if $(DEVICE_DTS),\
+		$(foreach dtb,$(DEVICE_DTS),$(CP) $(DTS_DIR)/$(dtb).dtb $@.boot), \
+		$(CP) $(DTS_DIR)/*.dtb $@.boot)
+	sed \
+		-e 's#@ROOT@#$(SIGNATURE)#g' \
+		-e 's#@KERNEL@#$(KERNEL_NAME)#g' \
+		$(BOOT_SCRIPT) > $@-boot.scr
+	mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
+		-n '$(DEVICE_TITLE) OpenWrt bootscript' \
+		-d $@-boot.scr \
+		$@.boot/boot.scr
+
+	PADDING="$(CONFIG_TARGET_IMAGES_PAD)" \
+	SIGNATURE="$(SIGNATURE)" \
+	$(SCRIPT_DIR)/gen_image_generic.sh \
+		$@ \
+		$(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
+		$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
+		2048
+endef
+
+DEVICE_VARS += BOOT_SCRIPT
+define Device/Default
+  BOOT_SCRIPT := generic-bootscript
+  IMAGES := sdcard.img.gz
+  IMAGE/sdcard.img.gz := tegra-sdcard | gzip | append-metadata
+  KERNEL_NAME := zImage
+  KERNEL := kernel-bin
+  PROFILES := Default
+endef
+
+$(eval $(call BuildImage))
diff --git a/target/linux/tegra/image/generic-bootscript b/target/linux/tegra/image/generic-bootscript
new file mode 100644
index 0000000000..7e86afdf5f
--- /dev/null
+++ b/target/linux/tegra/image/generic-bootscript
@@ -0,0 +1,6 @@
+setenv bootargs "root=PARTUUID=@ROOT at -02 rw rootwait console=ttyS0,115200 console=tty0"
+
+load ${devtype} ${devnum}:${bootpart} ${kernel_addr_r} /@KERNEL@
+load ${devtype} ${devnum}:${bootpart} ${fdt_addr_r} /${soc}-${board}.dtb
+
+bootz ${kernel_addr_r} - ${fdt_addr_r}
diff --git a/target/linux/tegra/patches-4.14/100-serial8250-on-tegra-hsuart-recover-from-spurious-interrupts-due-to-tegra2-silicon-bug.patch b/target/linux/tegra/patches-4.14/100-serial8250-on-tegra-hsuart-recover-from-spurious-interrupts-due-to-tegra2-silicon-bug.patch
new file mode 100644
index 0000000000..cfbc5d9c4f
--- /dev/null
+++ b/target/linux/tegra/patches-4.14/100-serial8250-on-tegra-hsuart-recover-from-spurious-interrupts-due-to-tegra2-silicon-bug.patch
@@ -0,0 +1,77 @@
+From patchwork Fri Jul 13 11:32:42 2018
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: serial8250 on tegra hsuart: recover from spurious interrupts due to
+ tegra2 silicon bug
+X-Patchwork-Submitter: "David R. Piegdon" <lkml at p23q.org>
+X-Patchwork-Id: 943440
+Message-Id: <4676ea34-69ce-5422-1ded-94218b89f7d9 at p23q.org>
+To: linux-tegra at vger.kernel.org
+Date: Fri, 13 Jul 2018 11:32:42 +0000
+From: "David R. Piegdon" <lkml at p23q.org>
+List-Id: <linux-tegra.vger.kernel.org>
+
+Hi,
+a while back I sent a few mails regarding spurious interrupts in the
+UARTA (hsuart) block of the Tegra2 SoC, when using the 8250 driver for
+it instead of the hsuart driver. After going down a pretty deep
+debugging/testing hole, I think I found a patch that fixes the issue. So
+far testing in a reboot-cycle suggests that the error frequency dropped
+from >3% of all reboots to at least <0.05% of all reboots. Tests
+continue to run over the weekend.
+
+The patch below already is a second iteration; the first did not reset
+the MCR or contain the lines below '// clear interrupts'. This resulted
+in no more spurious interrupts, but in a few % of spurious interrupts
+that were recovered the UART block did not receive any characters any
+more. So further resetting was required to fully reacquire operational
+state of the UART block.
+
+I'd love any comments/suggestions on this!
+
+Cheers,
+
+David
+
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -140,6 +140,38 @@ static irqreturn_t serial8250_interrupt(
+ 				"serial8250: too much work for irq%d\n", irq);
+ 			break;
+ 		}
++
++#ifdef CONFIG_ARCH_TEGRA_2x_SOC
++		if (!handled && (port->type == PORT_TEGRA)) {
++			/*
++			 * Fix Tegra 2 CPU silicon bug where sometimes
++			 * "TX holding register empty" interrupts result in a
++			 * bad (metastable?) state in Tegras HSUART IP core.
++			 * Only way to recover seems to be to reset all
++			 * interrupts as well as the TX queue and the MCR.
++			 * But we don't want to loose any outgoing characters,
++			 * so only do it if the RX and TX queues are empty.
++			 */
++			unsigned char lsr = port->serial_in(port, UART_LSR);
++			const unsigned char fifo_empty_mask =
++						(UART_LSR_TEMT | UART_LSR_THRE);
++			if (((lsr & (UART_LSR_DR | fifo_empty_mask)) ==
++							fifo_empty_mask)) {
++				port->serial_out(port, UART_IER, 0);
++				port->serial_out(port, UART_MCR, 0);
++				serial8250_clear_and_reinit_fifos(up);
++				port->serial_out(port, UART_MCR, up->mcr);
++				port->serial_out(port, UART_IER, up->ier);
++				// clear interrupts
++				serial_port_in(port, UART_LSR);
++				serial_port_in(port, UART_RX);
++				serial_port_in(port, UART_IIR);
++				serial_port_in(port, UART_MSR);
++				up->lsr_saved_flags = 0;
++				up->msr_saved_flags = 0;
++			}
++		}
++#endif
+ 	} while (l != end);
+ 
+ 	spin_unlock(&i->lock);
-- 
2.21.0


_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list