summaryrefslogtreecommitdiffstats
path: root/debian/patches/features/arm64
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/features/arm64')
-rw-r--r--debian/patches/features/arm64/arm64-compat-Implement-misalignment-fixups-for-multi.patch480
-rw-r--r--debian/patches/features/arm64/arm64-dts-raspberry-Add-support-for-the-CM4.patch423
-rw-r--r--debian/patches/features/arm64/arm64-dts-rockchip-Add-basic-support-for-Kobol-s-Hel.patch419
-rw-r--r--debian/patches/features/arm64/arm64-dts-rockchip-Add-support-for-PCIe-on-helios64.patch113
-rw-r--r--debian/patches/features/arm64/arm64-dts-rockchip-Add-support-for-two-PWM-fans-on-h.patch61
-rw-r--r--debian/patches/features/arm64/arm64-dts-rockchip-Rely-on-SoC-external-pull-up-on-p.patch32
-rw-r--r--debian/patches/features/arm64/arm64-dts-rockchip-kobol-helios64-Add-mmc-aliases.patch30
7 files changed, 1558 insertions, 0 deletions
diff --git a/debian/patches/features/arm64/arm64-compat-Implement-misalignment-fixups-for-multi.patch b/debian/patches/features/arm64/arm64-compat-Implement-misalignment-fixups-for-multi.patch
new file mode 100644
index 000000000..303e69f83
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-compat-Implement-misalignment-fixups-for-multi.patch
@@ -0,0 +1,480 @@
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Fri, 1 Jul 2022 15:53:22 +0200
+Subject: arm64: compat: Implement misalignment fixups for multiword loads
+Origin: https://git.kernel.org/linus/3fc24ef32d3b9368f4c103dcd21d6a3f959b4870
+
+The 32-bit ARM kernel implements fixups on behalf of user space when
+using LDM/STM or LDRD/STRD instructions on addresses that are not 32-bit
+aligned. This is not something that is supported by the architecture,
+but was done anyway to increase compatibility with user space software,
+which mostly targeted x86 at the time and did not care about aligned
+accesses.
+
+This feature is one of the remaining impediments to being able to switch
+to 64-bit kernels on 64-bit capable hardware running 32-bit user space,
+so let's implement it for the arm64 compat layer as well.
+
+Note that the intent is to implement the exact same handling of
+misaligned multi-word loads and stores as the 32-bit kernel does,
+including what appears to be missing support for user space programs
+that rely on SETEND to switch to a different byte order and back. Also,
+like the 32-bit ARM version, we rely on the faulting address reported by
+the CPU to infer the memory address, instead of decoding the instruction
+fully to obtain this information.
+
+This implementation is taken from the 32-bit ARM tree, with all pieces
+removed that deal with instructions other than LDRD/STRD and LDM/STM, or
+that deal with alignment exceptions taken in kernel mode.
+
+Cc: debian-arm@lists.debian.org
+Cc: Vagrant Cascadian <vagrant@debian.org>
+Cc: Riku Voipio <riku.voipio@iki.fi>
+Cc: Steve McIntyre <steve@einval.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20220701135322.3025321-1-ardb@kernel.org
+[catalin.marinas@arm.com: change the option to 'default n']
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+---
+ arch/arm64/Kconfig | 3 +
+ arch/arm64/include/asm/exception.h | 1 +
+ arch/arm64/kernel/Makefile | 1 +
+ arch/arm64/kernel/compat_alignment.c | 387 +++++++++++++++++++++++++++
+ arch/arm64/mm/fault.c | 3 +
+ 5 files changed, 395 insertions(+)
+ create mode 100644 arch/arm64/kernel/compat_alignment.c
+
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -1328,6 +1328,9 @@ config THUMB2_COMPAT_VDSO
+ Compile the compat vDSO with '-mthumb -fomit-frame-pointer' if y,
+ otherwise with '-marm'.
+
++config COMPAT_ALIGNMENT_FIXUPS
++ bool "Fix up misaligned multi-word loads and stores in user space"
++
+ menuconfig ARMV8_DEPRECATED
+ bool "Emulate deprecated/obsolete ARMv8 instructions"
+ depends on SYSCTL
+--- a/arch/arm64/include/asm/exception.h
++++ b/arch/arm64/include/asm/exception.h
+@@ -47,6 +47,7 @@ void do_el0_sys(unsigned long esr, struc
+ void do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs);
+ void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr);
+ void do_el0_cp15(unsigned long esr, struct pt_regs *regs);
++int do_compat_alignment_fixup(unsigned long addr, struct pt_regs *regs);
+ void do_el0_svc(struct pt_regs *regs);
+ void do_el0_svc_compat(struct pt_regs *regs);
+ void do_el0_fpac(struct pt_regs *regs, unsigned long esr);
+--- a/arch/arm64/kernel/Makefile
++++ b/arch/arm64/kernel/Makefile
+@@ -28,6 +28,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
+ obj-$(CONFIG_COMPAT) += sys32.o signal32.o \
+ sys_compat.o
+ obj-$(CONFIG_COMPAT) += sigreturn32.o
++obj-$(CONFIG_COMPAT_ALIGNMENT_FIXUPS) += compat_alignment.o
+ obj-$(CONFIG_KUSER_HELPERS) += kuser32.o
+ obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
+ obj-$(CONFIG_MODULES) += module.o
+--- /dev/null
++++ b/arch/arm64/kernel/compat_alignment.c
+@@ -0,0 +1,387 @@
++// SPDX-License-Identifier: GPL-2.0-only
++// based on arch/arm/mm/alignment.c
++
++#include <linux/compiler.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/perf_event.h>
++#include <linux/uaccess.h>
++
++#include <asm/exception.h>
++#include <asm/ptrace.h>
++#include <asm/traps.h>
++
++/*
++ * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
++ *
++ * Speed optimisations and better fault handling by Russell King.
++ */
++#define CODING_BITS(i) (i & 0x0e000000)
++
++#define LDST_P_BIT(i) (i & (1 << 24)) /* Preindex */
++#define LDST_U_BIT(i) (i & (1 << 23)) /* Add offset */
++#define LDST_W_BIT(i) (i & (1 << 21)) /* Writeback */
++#define LDST_L_BIT(i) (i & (1 << 20)) /* Load */
++
++#define LDST_P_EQ_U(i) ((((i) ^ ((i) >> 1)) & (1 << 23)) == 0)
++
++#define LDSTHD_I_BIT(i) (i & (1 << 22)) /* double/half-word immed */
++
++#define RN_BITS(i) ((i >> 16) & 15) /* Rn */
++#define RD_BITS(i) ((i >> 12) & 15) /* Rd */
++#define RM_BITS(i) (i & 15) /* Rm */
++
++#define REGMASK_BITS(i) (i & 0xffff)
++
++#define BAD_INSTR 0xdeadc0de
++
++/* Thumb-2 32 bit format per ARMv7 DDI0406A A6.3, either f800h,e800h,f800h */
++#define IS_T32(hi16) \
++ (((hi16) & 0xe000) == 0xe000 && ((hi16) & 0x1800))
++
++union offset_union {
++ unsigned long un;
++ signed long sn;
++};
++
++#define TYPE_ERROR 0
++#define TYPE_FAULT 1
++#define TYPE_LDST 2
++#define TYPE_DONE 3
++
++static void
++do_alignment_finish_ldst(unsigned long addr, u32 instr, struct pt_regs *regs,
++ union offset_union offset)
++{
++ if (!LDST_U_BIT(instr))
++ offset.un = -offset.un;
++
++ if (!LDST_P_BIT(instr))
++ addr += offset.un;
++
++ if (!LDST_P_BIT(instr) || LDST_W_BIT(instr))
++ regs->regs[RN_BITS(instr)] = addr;
++}
++
++static int
++do_alignment_ldrdstrd(unsigned long addr, u32 instr, struct pt_regs *regs)
++{
++ unsigned int rd = RD_BITS(instr);
++ unsigned int rd2;
++ int load;
++
++ if ((instr & 0xfe000000) == 0xe8000000) {
++ /* ARMv7 Thumb-2 32-bit LDRD/STRD */
++ rd2 = (instr >> 8) & 0xf;
++ load = !!(LDST_L_BIT(instr));
++ } else if (((rd & 1) == 1) || (rd == 14)) {
++ return TYPE_ERROR;
++ } else {
++ load = ((instr & 0xf0) == 0xd0);
++ rd2 = rd + 1;
++ }
++
++ if (load) {
++ unsigned int val, val2;
++
++ if (get_user(val, (u32 __user *)addr) ||
++ get_user(val2, (u32 __user *)(addr + 4)))
++ return TYPE_FAULT;
++ regs->regs[rd] = val;
++ regs->regs[rd2] = val2;
++ } else {
++ if (put_user(regs->regs[rd], (u32 __user *)addr) ||
++ put_user(regs->regs[rd2], (u32 __user *)(addr + 4)))
++ return TYPE_FAULT;
++ }
++ return TYPE_LDST;
++}
++
++/*
++ * LDM/STM alignment handler.
++ *
++ * There are 4 variants of this instruction:
++ *
++ * B = rn pointer before instruction, A = rn pointer after instruction
++ * ------ increasing address ----->
++ * | | r0 | r1 | ... | rx | |
++ * PU = 01 B A
++ * PU = 11 B A
++ * PU = 00 A B
++ * PU = 10 A B
++ */
++static int
++do_alignment_ldmstm(unsigned long addr, u32 instr, struct pt_regs *regs)
++{
++ unsigned int rd, rn, nr_regs, regbits;
++ unsigned long eaddr, newaddr;
++ unsigned int val;
++
++ /* count the number of registers in the mask to be transferred */
++ nr_regs = hweight16(REGMASK_BITS(instr)) * 4;
++
++ rn = RN_BITS(instr);
++ newaddr = eaddr = regs->regs[rn];
++
++ if (!LDST_U_BIT(instr))
++ nr_regs = -nr_regs;
++ newaddr += nr_regs;
++ if (!LDST_U_BIT(instr))
++ eaddr = newaddr;
++
++ if (LDST_P_EQ_U(instr)) /* U = P */
++ eaddr += 4;
++
++ for (regbits = REGMASK_BITS(instr), rd = 0; regbits;
++ regbits >>= 1, rd += 1)
++ if (regbits & 1) {
++ if (LDST_L_BIT(instr)) {
++ if (get_user(val, (u32 __user *)eaddr))
++ return TYPE_FAULT;
++ if (rd < 15)
++ regs->regs[rd] = val;
++ else
++ regs->pc = val;
++ } else {
++ /*
++ * The PC register has a bias of +8 in ARM mode
++ * and +4 in Thumb mode. This means that a read
++ * of the value of PC should account for this.
++ * Since Thumb does not permit STM instructions
++ * to refer to PC, just add 8 here.
++ */
++ val = (rd < 15) ? regs->regs[rd] : regs->pc + 8;
++ if (put_user(val, (u32 __user *)eaddr))
++ return TYPE_FAULT;
++ }
++ eaddr += 4;
++ }
++
++ if (LDST_W_BIT(instr))
++ regs->regs[rn] = newaddr;
++
++ return TYPE_DONE;
++}
++
++/*
++ * Convert Thumb multi-word load/store instruction forms to equivalent ARM
++ * instructions so we can reuse ARM userland alignment fault fixups for Thumb.
++ *
++ * This implementation was initially based on the algorithm found in
++ * gdb/sim/arm/thumbemu.c. It is basically just a code reduction of same
++ * to convert only Thumb ld/st instruction forms to equivalent ARM forms.
++ *
++ * NOTES:
++ * 1. Comments below refer to ARM ARM DDI0100E Thumb Instruction sections.
++ * 2. If for some reason we're passed an non-ld/st Thumb instruction to
++ * decode, we return 0xdeadc0de. This should never happen under normal
++ * circumstances but if it does, we've got other problems to deal with
++ * elsewhere and we obviously can't fix those problems here.
++ */
++
++static unsigned long thumb2arm(u16 tinstr)
++{
++ u32 L = (tinstr & (1<<11)) >> 11;
++
++ switch ((tinstr & 0xf800) >> 11) {
++ /* 6.6.1 Format 1: */
++ case 0xc000 >> 11: /* 7.1.51 STMIA */
++ case 0xc800 >> 11: /* 7.1.25 LDMIA */
++ {
++ u32 Rn = (tinstr & (7<<8)) >> 8;
++ u32 W = ((L<<Rn) & (tinstr&255)) ? 0 : 1<<21;
++
++ return 0xe8800000 | W | (L<<20) | (Rn<<16) |
++ (tinstr&255);
++ }
++
++ /* 6.6.1 Format 2: */
++ case 0xb000 >> 11: /* 7.1.48 PUSH */
++ case 0xb800 >> 11: /* 7.1.47 POP */
++ if ((tinstr & (3 << 9)) == 0x0400) {
++ static const u32 subset[4] = {
++ 0xe92d0000, /* STMDB sp!,{registers} */
++ 0xe92d4000, /* STMDB sp!,{registers,lr} */
++ 0xe8bd0000, /* LDMIA sp!,{registers} */
++ 0xe8bd8000 /* LDMIA sp!,{registers,pc} */
++ };
++ return subset[(L<<1) | ((tinstr & (1<<8)) >> 8)] |
++ (tinstr & 255); /* register_list */
++ }
++ fallthrough; /* for illegal instruction case */
++
++ default:
++ return BAD_INSTR;
++ }
++}
++
++/*
++ * Convert Thumb-2 32 bit LDM, STM, LDRD, STRD to equivalent instruction
++ * handlable by ARM alignment handler, also find the corresponding handler,
++ * so that we can reuse ARM userland alignment fault fixups for Thumb.
++ *
++ * @pinstr: original Thumb-2 instruction; returns new handlable instruction
++ * @regs: register context.
++ * @poffset: return offset from faulted addr for later writeback
++ *
++ * NOTES:
++ * 1. Comments below refer to ARMv7 DDI0406A Thumb Instruction sections.
++ * 2. Register name Rt from ARMv7 is same as Rd from ARMv6 (Rd is Rt)
++ */
++static void *
++do_alignment_t32_to_handler(u32 *pinstr, struct pt_regs *regs,
++ union offset_union *poffset)
++{
++ u32 instr = *pinstr;
++ u16 tinst1 = (instr >> 16) & 0xffff;
++ u16 tinst2 = instr & 0xffff;
++
++ switch (tinst1 & 0xffe0) {
++ /* A6.3.5 Load/Store multiple */
++ case 0xe880: /* STM/STMIA/STMEA,LDM/LDMIA, PUSH/POP T2 */
++ case 0xe8a0: /* ...above writeback version */
++ case 0xe900: /* STMDB/STMFD, LDMDB/LDMEA */
++ case 0xe920: /* ...above writeback version */
++ /* no need offset decision since handler calculates it */
++ return do_alignment_ldmstm;
++
++ case 0xf840: /* POP/PUSH T3 (single register) */
++ if (RN_BITS(instr) == 13 && (tinst2 & 0x09ff) == 0x0904) {
++ u32 L = !!(LDST_L_BIT(instr));
++ const u32 subset[2] = {
++ 0xe92d0000, /* STMDB sp!,{registers} */
++ 0xe8bd0000, /* LDMIA sp!,{registers} */
++ };
++ *pinstr = subset[L] | (1<<RD_BITS(instr));
++ return do_alignment_ldmstm;
++ }
++ /* Else fall through for illegal instruction case */
++ break;
++
++ /* A6.3.6 Load/store double, STRD/LDRD(immed, lit, reg) */
++ case 0xe860:
++ case 0xe960:
++ case 0xe8e0:
++ case 0xe9e0:
++ poffset->un = (tinst2 & 0xff) << 2;
++ fallthrough;
++
++ case 0xe940:
++ case 0xe9c0:
++ return do_alignment_ldrdstrd;
++
++ /*
++ * No need to handle load/store instructions up to word size
++ * since ARMv6 and later CPUs can perform unaligned accesses.
++ */
++ default:
++ break;
++ }
++ return NULL;
++}
++
++static int alignment_get_arm(struct pt_regs *regs, __le32 __user *ip, u32 *inst)
++{
++ __le32 instr = 0;
++ int fault;
++
++ fault = get_user(instr, ip);
++ if (fault)
++ return fault;
++
++ *inst = __le32_to_cpu(instr);
++ return 0;
++}
++
++static int alignment_get_thumb(struct pt_regs *regs, __le16 __user *ip, u16 *inst)
++{
++ __le16 instr = 0;
++ int fault;
++
++ fault = get_user(instr, ip);
++ if (fault)
++ return fault;
++
++ *inst = __le16_to_cpu(instr);
++ return 0;
++}
++
++int do_compat_alignment_fixup(unsigned long addr, struct pt_regs *regs)
++{
++ union offset_union offset;
++ unsigned long instrptr;
++ int (*handler)(unsigned long addr, u32 instr, struct pt_regs *regs);
++ unsigned int type;
++ u32 instr = 0;
++ u16 tinstr = 0;
++ int isize = 4;
++ int thumb2_32b = 0;
++ int fault;
++
++ instrptr = instruction_pointer(regs);
++
++ if (compat_thumb_mode(regs)) {
++ __le16 __user *ptr = (__le16 __user *)(instrptr & ~1);
++
++ fault = alignment_get_thumb(regs, ptr, &tinstr);
++ if (!fault) {
++ if (IS_T32(tinstr)) {
++ /* Thumb-2 32-bit */
++ u16 tinst2;
++ fault = alignment_get_thumb(regs, ptr + 1, &tinst2);
++ instr = ((u32)tinstr << 16) | tinst2;
++ thumb2_32b = 1;
++ } else {
++ isize = 2;
++ instr = thumb2arm(tinstr);
++ }
++ }
++ } else {
++ fault = alignment_get_arm(regs, (__le32 __user *)instrptr, &instr);
++ }
++
++ if (fault)
++ return 1;
++
++ switch (CODING_BITS(instr)) {
++ case 0x00000000: /* 3.13.4 load/store instruction extensions */
++ if (LDSTHD_I_BIT(instr))
++ offset.un = (instr & 0xf00) >> 4 | (instr & 15);
++ else
++ offset.un = regs->regs[RM_BITS(instr)];
++
++ if ((instr & 0x001000f0) == 0x000000d0 || /* LDRD */
++ (instr & 0x001000f0) == 0x000000f0) /* STRD */
++ handler = do_alignment_ldrdstrd;
++ else
++ return 1;
++ break;
++
++ case 0x08000000: /* ldm or stm, or thumb-2 32bit instruction */
++ if (thumb2_32b) {
++ offset.un = 0;
++ handler = do_alignment_t32_to_handler(&instr, regs, &offset);
++ } else {
++ offset.un = 0;
++ handler = do_alignment_ldmstm;
++ }
++ break;
++
++ default:
++ return 1;
++ }
++
++ type = handler(addr, instr, regs);
++
++ if (type == TYPE_ERROR || type == TYPE_FAULT)
++ return 1;
++
++ if (type == TYPE_LDST)
++ do_alignment_finish_ldst(addr, instr, regs, offset);
++
++ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->pc);
++ arm64_skip_faulting_instruction(regs, isize);
++
++ return 0;
++}
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -610,6 +610,9 @@ static int __kprobes do_translation_faul
+ static int do_alignment_fault(unsigned long addr, unsigned int esr,
+ struct pt_regs *regs)
+ {
++ if (IS_ENABLED(CONFIG_COMPAT_ALIGNMENT_FIXUPS) &&
++ compat_user_mode(regs))
++ return do_compat_alignment_fixup(addr, regs);
+ do_bad_area(addr, esr, regs);
+ return 0;
+ }
diff --git a/debian/patches/features/arm64/arm64-dts-raspberry-Add-support-for-the-CM4.patch b/debian/patches/features/arm64/arm64-dts-raspberry-Add-support-for-the-CM4.patch
new file mode 100644
index 000000000..8619cfcdd
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-raspberry-Add-support-for-the-CM4.patch
@@ -0,0 +1,423 @@
+From: Cyril Brulebois <cyril@debamax.com>
+Date: Mon, 03 Jan 2022 21:59:36 +0100
+Subject: arm64: dts: Add support for Raspberry Pi Compute Module 4 IO Board
+
+It was introduced in mainline during the v5.16 release cycle. Since
+many broadcom includes were reworked since v5.10, adding support would
+involve more than cherry-picking a DTS addition that uses a few
+includes.
+
+To avoid side effects on other models, introduce a DTS that leverages
+some existing includes (bcm2711.dtsi and bcm283x-rpi-usb-host.dtsi)
+and describes the rest without re-using parts of the Raspberry Pi 4 B
+model.
+
+To avoid phandle rotation (0x16, 0x17, and 0x18) across 3 nodes
+(dma@7e007000, i2c@7e205000, and interrupt-controller@7ef00100), and the
+related changes in other nodes referencing them, hardcode 0x16 as the
+phandle for interrupt-controller@7ef00100. This leads to an empty dtdiff
+between this new DTB and the one produced by a v5.16-rc8 build.
+
+Authored-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Cyril Brulebois <cyril@debamax.com>
+
+--- a/arch/arm64/boot/dts/broadcom/Makefile
++++ b/arch/arm64/boot/dts/broadcom/Makefile
+@@ -1,5 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-4-b.dtb \
++ bcm2711-rpi-cm4-io.dtb \
+ bcm2837-rpi-3-a-plus.dtb \
+ bcm2837-rpi-3-b.dtb \
+ bcm2837-rpi-3-b-plus.dtb \
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
+@@ -0,0 +1,2 @@
++// SPDX-License-Identifier: GPL-2.0
++#include "arm/bcm2711-rpi-cm4-io.dts"
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -93,6 +93,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2837-rpi-3-b-plus.dtb \
+ bcm2837-rpi-cm3-io3.dtb \
+ bcm2711-rpi-4-b.dtb \
++ bcm2711-rpi-cm4-io.dtb \
+ bcm2835-rpi-zero.dtb \
+ bcm2835-rpi-zero-w.dtb
+ dtb-$(CONFIG_ARCH_BCM_5301X) += \
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
+@@ -0,0 +1,373 @@
++/dts-v1/;
++
++#include "bcm2711.dtsi"
++#include "bcm283x-rpi-usb-host.dtsi"
++
++/ {
++ model = "Raspberry Pi Compute Module 4 IO Board";
++ compatible = "raspberrypi,4-compute-module\0brcm,bcm2711";
++
++ aliases {
++ emmc2bus = "/emmc2bus";
++ ethernet0 = "/scb/ethernet@7d580000";
++ pcie0 = "/scb/pcie@7d500000";
++ blconfig = &blconfig;
++ };
++
++ chosen {
++ stdout-path = "serial1:115200n8";
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-act {
++ label = "ACT";
++ default-state = "keep";
++ linux,default-trigger = "heartbeat";
++ gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
++ };
++
++ led-pwr {
++ label = "PWR";
++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
++ default-state = "keep";
++ linux,default-trigger = "default-on";
++ };
++ };
++
++ soc {
++ aon_intr: interrupt-controller@7ef00100 {
++ compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
++ reg = <0x7ef00100 0x30>;
++ phandle = <0x16>;
++ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ firmware: firmware {
++ compatible = "raspberrypi,bcm2835-firmware\0simple-mfd";
++ #address-cells = <0x01>;
++ #size-cells = <0x01>;
++ mboxes = <&mailbox>;
++ dma-ranges;
++
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <0x01>;
++ };
++
++ expgpio: gpio {
++ compatible = "raspberrypi,firmware-gpio";
++ gpio-controller;
++ #gpio-cells = <2>;
++ status = "okay";
++ gpio-line-names = "BT_ON", "WL_ON", "PWR_LED_OFF", "ANT1", "VDD_SD_IO_SEL", "CAM_GPIO", "SD_PWR_ON", "ANT2";
++ ant1-hog {
++ gpio-hog;
++ gpios = <0x03 0x00>;
++ output-high;
++ line-name = "ant1";
++ };
++
++ ant2-hog {
++ gpio-hog;
++ gpios = <0x07 0x00>;
++ output-low;
++ line-name = "ant2";
++ };
++ };
++
++ reset {
++ compatible = "raspberrypi,firmware-reset";
++ #reset-cells = <1>;
++ };
++ };
++
++ power: power {
++ compatible = "raspberrypi,bcm2835-power";
++ firmware = <&firmware>;
++ #power-domain-cells = <1>;
++ };
++
++ mailbox@7e00b840 {
++ compatible = "brcm,bcm2835-vchiq";
++ reg = <0x7e00b840 0x3c>;
++ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
++ };
++
++ vec@7ec13000 {
++ compatible = "brcm,bcm2711-vec";
++ reg = <0x7ec13000 0x1000>;
++ clocks = <&clocks BCM2835_CLOCK_VEC>;
++ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ power-domains = <&power /* RPI_POWER_DOMAIN_VEC = */ 7>;
++ };
++ };
++
++ memory@0 {
++ device_type = "memory";
++ reg = <0x00 0x00 0x00>;
++ };
++
++ wifi_pwrseq: wifi-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ reset-gpios = <&expgpio 0x01 0x01>;
++ };
++
++ sd_io_1v8_reg: sd_io_1v8_reg {
++ compatible = "regulator-gpio";
++ regulator-name = "vdd-sd-io";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ regulator-settling-time-us = <5000>;
++ gpios = <&expgpio 0x04 GPIO_ACTIVE_HIGH>;
++ states = <1800000 0x1>,
++ <3300000 0x0>;
++ status = "okay";
++ };
++
++ sd_vcc_reg: sd_vcc_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc-sd";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ enable-active-high;
++ gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>;
++ };
++};
++
++&ddc0 {
++ status = "okay";
++};
++
++&ddc1 {
++ status = "okay";
++};
++
++&dsi0 {
++ power-domains = <&power 17>;
++};
++
++&dsi1 {
++ compatible = "brcm,bcm2711-dsi1";
++ power-domains = <&power 18>;
++};
++
++&emmc2 {
++ status = "okay";
++ bus-width = <8>;
++ vqmmc-supply = <&sd_io_1v8_reg>;
++ vmmc-supply = <&sd_vcc_reg>;
++ broken-cd;
++ mmc-hs200-1_8v;
++};
++
++&gpio {
++ pinctrl-names = "default";
++ /*
++ * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and
++ * the official GPU firmware DT blob.
++ *
++ * Legend:
++ * "FOO" = GPIO line named "FOO" on the schematic
++ * "FOO_N" = GPIO line named "FOO" on schematic, active low
++ */
++ gpio-line-names = "ID_SDA",
++ "ID_SCL",
++ "SDA1",
++ "SCL1",
++ "GPIO_GCLK",
++ "GPIO5",
++ "GPIO6",
++ "SPI_CE1_N",
++ "SPI_CE0_N",
++ "SPI_MISO",
++ "SPI_MOSI",
++ "SPI_SCLK",
++ "GPIO12",
++ "GPIO13",
++ /* Serial port */
++ "TXD1",
++ "RXD1",
++ "GPIO16",
++ "GPIO17",
++ "GPIO18",
++ "GPIO19",
++ "GPIO20",
++ "GPIO21",
++ "GPIO22",
++ "GPIO23",
++ "GPIO24",
++ "GPIO25",
++ "GPIO26",
++ "GPIO27",
++ "RGMII_MDIO",
++ "RGMIO_MDC",
++ /* Used by BT module */
++ "CTS0",
++ "RTS0",
++ "TXD0",
++ "RXD0",
++ /* Used by Wifi */
++ "SD1_CLK",
++ "SD1_CMD",
++ "SD1_DATA0",
++ "SD1_DATA1",
++ "SD1_DATA2",
++ "SD1_DATA3",
++ /* Shared with SPI flash */
++ "PWM0_MISO",
++ "PWM1_MOSI",
++ "STATUS_LED_G_CLK",
++ "SPIFLASH_CE_N",
++ "SDA0",
++ "SCL0",
++ "RGMII_RXCLK",
++ "RGMII_RXCTL",
++ "RGMII_RXD0",
++ "RGMII_RXD1",
++ "RGMII_RXD2",
++ "RGMII_RXD3",
++ "RGMII_TXCLK",
++ "RGMII_TXCTL",
++ "RGMII_TXD0",
++ "RGMII_TXD1",
++ "RGMII_TXD2",
++ "RGMII_TXD3";
++
++ gpioout {
++ brcm,pins = <0x06>;
++ brcm,function = <0x01>;
++ };
++
++ alt0 {
++ brcm,pins = <0x04 0x05 0x07 0x08 0x09 0x0a 0x0b>;
++ brcm,function = <0x04>;
++ };
++};
++
++&hdmi0 {
++ status = "okay";
++ interrupt-parent = <&aon_intr>;
++ interrupts = <0>, <1>, <2>, <3>, <4>, <5>;
++ interrupt-names = "cec-tx", "cec-rx", "cec-low", "wakeup", "hpd-connected", "hpd-removed";
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
++ wifi-2.4ghz-coexistence;
++};
++
++&hdmi1 {
++ status = "okay";
++ interrupt-parent = <&aon_intr>;
++ interrupts = <8>, <7>, <6>, <9>, <10>, <11>;
++ interrupt-names = "cec-tx", "cec-rx", "cec-low", "wakeup", "hpd-connected", "hpd-removed";
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
++ wifi-2.4ghz-coexistence;
++};
++
++&hvs {
++ clocks = <&firmware_clocks 4>;
++};
++
++&i2c0 {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0_gpio0>;
++ clock-frequency = <100000>;
++};
++
++&i2c1 {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_gpio2>;
++ clock-frequency = <100000>;
++};
++
++&genet {
++ status = "okay";
++ phy-handle = <&ethphy0>;
++ phy-mode = "rgmii-rxid";
++};
++
++&genet_mdio {
++ ethphy0: ethernet-phy@0 {
++ reg = <0>;
++ };
++};
++
++&pixelvalve0 {
++ status = "okay";
++};
++
++&pixelvalve1 {
++ status = "okay";
++};
++
++&pixelvalve2 {
++ status = "okay";
++};
++
++&pixelvalve4 {
++ status = "okay";
++};
++
++&rmem {
++ blconfig: nvram@0 {
++ compatible = "raspberrypi,bootloader-config", "nvmem-rmem";
++ #address-cells = <0x01>;
++ #size-cells = <0x01>;
++ reg = <0x00 0x00 0x00>;
++ no-map;
++ status = "disabled";
++ };
++};
++
++&sdhci {
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc_gpio34>;
++ bus-width = <4>;
++ non-removable;
++ mmc-pwrseq = <&wifi_pwrseq>;
++
++ wifi@1 {
++ reg = <0x01>;
++ compatible = "brcm,bcm4329-fmac";
++ };
++};
++
++&uart0 {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
++ uart-has-rtscts;
++
++ bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <0x1e8480>;
++ shutdown-gpios = <&expgpio 0x00 0x00>;
++ };
++};
++
++&uart1 {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1_gpio14>;
++};
++
++&usb {
++ power-domains = <&power 6>;
++};
++
++&vc4 {
++ status = "okay";
++};
++
++/delete-node/ &vec;
diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Add-basic-support-for-Kobol-s-Hel.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Add-basic-support-for-Kobol-s-Hel.patch
new file mode 100644
index 000000000..deeed7034
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-rockchip-Add-basic-support-for-Kobol-s-Hel.patch
@@ -0,0 +1,419 @@
+From: Uwe Kleine-König <uwe@kleine-koenig.org>
+Date: Wed, 14 Oct 2020 22:00:30 +0200
+Subject: arm64: dts: rockchip: Add basic support for Kobol's Helios64
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=09e006cfb43e8ec38afe28278b210dab72e6cac8
+
+The hardware is described in detail on Kobol's wiki at
+https://wiki.kobol.io/helios64/intro/.
+
+Up to now the following peripherals are working:
+
+ - UART
+ - Micro-SD card
+ - eMMC
+ - ethernet port 1
+ - status LED
+ - temperature sensor on i2c bus 2
+
+Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Link: https://lore.kernel.org/r/20201014200030.845759-3-uwe@kleine-koenig.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 1 +
+ .../dts/rockchip/rk3399-kobol-helios64.dts | 372 ++++++++++++++++++
+ 2 files changed, 373 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+
+diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
+index 26661c7b736b..28b26a874313 100644
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -26,6 +26,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-hugsun-x99.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-captain.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-v.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-kobol-helios64.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-leez-p710.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopc-t4.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-m4.dtb
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+new file mode 100644
+index 000000000000..2a561be724b2
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+@@ -0,0 +1,372 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2020 Aditya Prayoga <aditya@kobol.io>
++ */
++
++/*
++ * The Kobol Helios64 is a board designed to operate as a NAS and optionally
++ * ships with an enclosing that can host five 2.5" hard disks.
++ *
++ * See https://wiki.kobol.io/helios64/intro/ for further details.
++ */
++
++/dts-v1/;
++#include "rk3399.dtsi"
++#include "rk3399-opp.dtsi"
++
++/ {
++ model = "Kobol Helios64";
++ compatible = "kobol,helios64", "rockchip,rk3399";
++
++ avdd_1v8_s0: avdd-1v8-s0 {
++ compatible = "regulator-fixed";
++ regulator-name = "avdd_1v8_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc3v3_sys_s3>;
++ };
++
++ clkin_gmac: external-gmac-clock {
++ compatible = "fixed-clock";
++ clock-frequency = <125000000>;
++ clock-output-names = "clkin_gmac";
++ #clock-cells = <0>;
++ };
++
++ leds {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&sys_grn_led_on &sys_red_led_on>;
++
++ led-0 {
++ label = "helios64:green:status";
++ gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
++ default-state = "on";
++ };
++
++ led-1 {
++ label = "helios64:red:fault";
++ gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
++ default-state = "keep";
++ };
++ };
++
++ vcc1v8_sys_s0: vcc1v8-sys-s0 {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc1v8_sys_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc1v8_sys_s3>;
++ };
++
++ vcc3v0_sd: vcc3v0-sd {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;
++ regulator-name = "vcc3v0_sd";
++ regulator-boot-on;
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc0_pwr_h>;
++ vin-supply = <&vcc3v3_sys_s3>;
++ };
++
++ vcc3v3_sys_s3: vcc_lan: vcc3v3-sys-s3 {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_sys_s3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ };
++ };
++
++ vcc5v0_sys: vcc5v0-sys {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc12v_dcin_bkup>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ };
++ };
++
++ vcc12v_dcin: vcc12v-dcin {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc12v_dcin";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <12000000>;
++ regulator-max-microvolt = <12000000>;
++ };
++
++ vcc12v_dcin_bkup: vcc12v-dcin-bkup {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc12v_dcin_bkup";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <12000000>;
++ regulator-max-microvolt = <12000000>;
++ vin-supply = <&vcc12v_dcin>;
++ };
++};
++
++/*
++ * The system doesn't run stable with cpu freq enabled, so disallow the lower
++ * frequencies until this problem is properly understood and resolved.
++ */
++&cluster0_opp {
++ /delete-node/ opp00;
++ /delete-node/ opp01;
++ /delete-node/ opp02;
++ /delete-node/ opp03;
++ /delete-node/ opp04;
++};
++
++&cluster1_opp {
++ /delete-node/ opp00;
++ /delete-node/ opp01;
++ /delete-node/ opp02;
++ /delete-node/ opp03;
++ /delete-node/ opp04;
++ /delete-node/ opp05;
++ /delete-node/ opp06;
++};
++
++&cpu_b0 {
++ cpu-supply = <&vdd_cpu_b>;
++};
++
++&cpu_b1 {
++ cpu-supply = <&vdd_cpu_b>;
++};
++
++&cpu_l0 {
++ cpu-supply = <&vdd_cpu_l>;
++};
++
++&cpu_l1 {
++ cpu-supply = <&vdd_cpu_l>;
++};
++
++&cpu_l2 {
++ cpu-supply = <&vdd_cpu_l>;
++};
++
++&cpu_l3 {
++ cpu-supply = <&vdd_cpu_l>;
++};
++
++&emmc_phy {
++ status = "okay";
++};
++
++&gmac {
++ assigned-clock-parents = <&clkin_gmac>;
++ assigned-clocks = <&cru SCLK_RMII_SRC>;
++ clock_in_out = "input";
++ phy-mode = "rgmii";
++ phy-supply = <&vcc_lan>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&rgmii_pins &gphy_reset>;
++ rx_delay = <0x20>;
++ tx_delay = <0x28>;
++ snps,reset-active-low;
++ snps,reset-delays-us = <0 10000 50000>;
++ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
++ status = "okay";
++};
++
++&i2c0 {
++ clock-frequency = <400000>;
++ i2c-scl-rising-time-ns = <168>;
++ i2c-scl-falling-time-ns = <4>;
++ status = "okay";
++
++ rk808: pmic@1b {
++ compatible = "rockchip,rk808";
++ reg = <0x1b>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
++ clock-output-names = "xin32k", "rk808-clkout2";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pmic_int_l>;
++ vcc1-supply = <&vcc5v0_sys>;
++ vcc2-supply = <&vcc5v0_sys>;
++ vcc3-supply = <&vcc5v0_sys>;
++ vcc4-supply = <&vcc5v0_sys>;
++ vcc6-supply = <&vcc5v0_sys>;
++ vcc7-supply = <&vcc5v0_sys>;
++ vcc8-supply = <&vcc3v3_sys_s3>;
++ vcc9-supply = <&vcc5v0_sys>;
++ vcc10-supply = <&vcc5v0_sys>;
++ vcc11-supply = <&vcc5v0_sys>;
++ vcc12-supply = <&vcc3v3_sys_s3>;
++ vddio-supply = <&vcc3v0_s3>;
++ wakeup-source;
++ #clock-cells = <1>;
++
++ regulators {
++ vdd_cpu_l: DCDC_REG2 {
++ regulator-name = "vdd_cpu_l";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc1v8_sys_s3: DCDC_REG4 {
++ regulator-name = "vcc1v8_sys_s3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ vcc_sdio_s0: LDO_REG4 {
++ regulator-name = "vcc_sdio_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3000000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3000000>;
++ };
++ };
++
++ vcc3v0_s3: LDO_REG8 {
++ regulator-name = "vcc3v0_s3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3000000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3000000>;
++ };
++ };
++ };
++ };
++
++ vdd_cpu_b: regulator@40 {
++ compatible = "silergy,syr827";
++ reg = <0x40>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu_b";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <712500>;
++ regulator-max-microvolt = <1500000>;
++ regulator-ramp-delay = <1000>;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++ i2c-scl-rising-time-ns = <160>;
++ i2c-scl-falling-time-ns = <30>;
++ status = "okay";
++
++ temp@4c {
++ compatible = "national,lm75";
++ reg = <0x4c>;
++ };
++};
++
++&io_domains {
++ audio-supply = <&vcc1v8_sys_s0>;
++ bt656-supply = <&vcc1v8_sys_s0>;
++ gpio1830-supply = <&vcc3v0_s3>;
++ sdmmc-supply = <&vcc_sdio_s0>;
++ status = "okay";
++};
++
++&pinctrl {
++ gmac {
++ gphy_reset: gphy-reset {
++ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>;
++ };
++ };
++
++ leds {
++ sys_grn_led_on: sys-grn-led-on {
++ rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
++ };
++
++ sys_red_led_on: sys-red-led-on {
++ rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>;
++ };
++ };
++
++ pmic {
++ pmic_int_l: pmic-int-l {
++ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ vcc3v0-sd {
++ sdmmc0_pwr_h: sdmmc0-pwr-h {
++ rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++};
++
++&pmu_io_domains {
++ pmu1830-supply = <&vcc3v0_s3>;
++ status = "okay";
++};
++
++&sdhci {
++ bus-width = <8>;
++ mmc-hs200-1_8v;
++ non-removable;
++ vqmmc-supply = <&vcc1v8_sys_s0>;
++ status = "okay";
++};
++
++&sdmmc {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
++ disable-wp;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
++ vmmc-supply = <&vcc3v0_sd>;
++ vqmmc-supply = <&vcc_sdio_s0>;
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
++};
+--
+2.28.0
+
diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Add-support-for-PCIe-on-helios64.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Add-support-for-PCIe-on-helios64.patch
new file mode 100644
index 000000000..6abebd080
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-rockchip-Add-support-for-PCIe-on-helios64.patch
@@ -0,0 +1,113 @@
+From: Uwe Kleine-König <uwe@kleine-koenig.org>
+Date: Mon, 10 May 2021 11:09:32 +0200
+Subject: arm64: dts: rockchip: Add support for PCIe on helios64
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/patch/?id=5a65adfa2ad1542f856fc7de3999d51f3a35d2e2
+
+This is enough to make the SATA controller visible:
+
+# lspci
+00:00.0 PCI bridge: Fuzhou Rockchip Electronics Co., Ltd RK3399 PCI Express Root Port
+01:00.0 SATA controller: JMicron Technology Corp. JMB58x AHCI SATA controller
+
+Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Link: https://lore.kernel.org/r/20210510090932.970447-1-uwe@kleine-koenig.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../dts/rockchip/rk3399-kobol-helios64.dts | 53 +++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+index 9d4a0885fd12..037dc5cdc3f3 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+@@ -23,6 +23,16 @@ aliases {
+ mmc1 = &sdhci;
+ };
+
++ avdd_0v9_s0: avdd-0v9-s0 {
++ compatible = "regulator-fixed";
++ regulator-name = "avdd_0v9_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ vin-supply = <&vcc1v8_sys_s3>;
++ };
++
+ avdd_1v8_s0: avdd-1v8-s0 {
+ compatible = "regulator-fixed";
+ regulator-name = "avdd_1v8_s0";
+@@ -72,6 +82,18 @@ led-1 {
+ };
+ };
+
++ pcie_power: pcie-power {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>;
++ pinctrl-0 = <&pcie_pwr>;
++ pinctrl-names = "default";
++ regulator-boot-on;
++ regulator-name = "pcie_power";
++ startup-delay-us = <10000>;
++ vin-supply = <&vcc5v0_perdev>;
++ };
++
+ vcc1v8_sys_s0: vcc1v8-sys-s0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc1v8_sys_s0";
+@@ -109,6 +131,16 @@ regulator-state-mem {
+ };
+ };
+
++ vcc5v0_perdev: vcc5v0-perdev {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_perdev";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc12v_dcin_bkup>;
++ };
++
+ vcc5v0_sys: vcc5v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+@@ -331,6 +363,20 @@ &io_domains {
+ status = "okay";
+ };
+
++&pcie_phy {
++ status = "okay";
++};
++
++&pcie0 {
++ num-lanes = <2>;
++ status = "okay";
++
++ vpcie12v-supply = <&vcc12v_dcin>;
++ vpcie3v3-supply = <&pcie_power>;
++ vpcie1v8-supply = <&avdd_1v8_s0>;
++ vpcie0v9-supply = <&avdd_0v9_s0>;
++};
++
+ &pinctrl {
+ gmac {
+ gphy_reset: gphy-reset {
+@@ -348,6 +394,13 @@ sys_red_led_on: sys-red-led-on {
+ };
+ };
+
++ pcie {
++ pcie_pwr: pcie-pwr {
++ rockchip,pins =
++ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+--
+2.30.2
+
diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Add-support-for-two-PWM-fans-on-h.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Add-support-for-two-PWM-fans-on-h.patch
new file mode 100644
index 000000000..9755e0b8c
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-rockchip-Add-support-for-two-PWM-fans-on-h.patch
@@ -0,0 +1,61 @@
+From: Uwe Kleine-König <uwe@kleine-koenig.org>
+Date: Mon, 10 May 2021 11:06:07 +0200
+Subject: arm64: dts: rockchip: Add support for two PWM fans on
+ helios64
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/patch/?id=271b66414df0b172c936b3cfd1894b7939f84165
+
+On the helios64 board the two connectors P6 and P7 are supposed to
+power two fans. Add the corresponding pwm-fan devices.
+
+Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Link: https://lore.kernel.org/r/20210510090607.970145-1-uwe@kleine-koenig.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../dts/rockchip/rk3399-kobol-helios64.dts | 24 +++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+index 19485b552bc4..9d4a0885fd12 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+@@ -40,6 +40,20 @@ clkin_gmac: external-gmac-clock {
+ #clock-cells = <0>;
+ };
+
++ fan1 {
++ /* fan connected to P7 */
++ compatible = "pwm-fan";
++ pwms = <&pwm0 0 40000 0>;
++ cooling-levels = <0 80 170 255>;
++ };
++
++ fan2 {
++ /* fan connected to P6 */
++ compatible = "pwm-fan";
++ pwms = <&pwm1 0 40000 0>;
++ cooling-levels = <0 80 170 255>;
++ };
++
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+@@ -352,6 +366,16 @@ &pmu_io_domains {
+ status = "okay";
+ };
+
++&pwm0 {
++ /* pwm-fan on P7 */
++ status = "okay";
++};
++
++&pwm1 {
++ /* pwm-fan on P6 */
++ status = "okay";
++};
++
+ &sdhci {
+ bus-width = <8>;
+ mmc-hs200-1_8v;
+--
+2.30.2
+
diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-Rely-on-SoC-external-pull-up-on-p.patch b/debian/patches/features/arm64/arm64-dts-rockchip-Rely-on-SoC-external-pull-up-on-p.patch
new file mode 100644
index 000000000..ef6dab336
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-rockchip-Rely-on-SoC-external-pull-up-on-p.patch
@@ -0,0 +1,32 @@
+From: Uwe Kleine-König <uwe@kleine-koenig.org>
+Date: Sun, 24 Jan 2021 22:03:28 +0100
+Subject: arm64: dts: rockchip: Rely on SoC external pull up on pmic-int-l on Helios64
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=1e58ba111421375c5948c3e8145bdd84b06ac095
+
+According to the schematic there is an external pull up, so there is no
+need to enable the internal one additionally. Using no pull up matches
+the vendor device tree.
+
+Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Link: https://lore.kernel.org/r/20210124210328.611707-2-uwe@kleine-koenig.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+index 2a561be724b2..66c725a34220 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+@@ -331,7 +331,7 @@ sys_red_led_on: sys-red-led-on {
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+- rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
++ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+--
+2.30.2
+
diff --git a/debian/patches/features/arm64/arm64-dts-rockchip-kobol-helios64-Add-mmc-aliases.patch b/debian/patches/features/arm64/arm64-dts-rockchip-kobol-helios64-Add-mmc-aliases.patch
new file mode 100644
index 000000000..ad4b53de9
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-rockchip-kobol-helios64-Add-mmc-aliases.patch
@@ -0,0 +1,30 @@
+From: Uwe Kleine-König <ukleinek@debian.org>
+Date: Wed, 29 Mar 2021 09:45:58 +0100
+Subject: arm64: dts: rockchip: kobol-helios64: Add mmc aliases
+
+This patch is part of commit 5dcbe7e3862d ("arm64: dts: rockchip: move mmc
+aliases to board dts on rk3399") upstream. It is applied here only for Kobol's
+helios64 to simplify conflict resolution for some further patches. It currently
+is a noop as the same aliases already exist in rk3399.dtsi.
+
+Link: https://lore.kernel.org/r/20210324122235.1059292-7-heiko@sntech.de
+---
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+index 66c725a34220..19485b552bc4 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+@@ -18,6 +18,11 @@ / {
+ model = "Kobol Helios64";
+ compatible = "kobol,helios64", "rockchip,rk3399";
+
++ aliases {
++ mmc0 = &sdmmc;
++ mmc1 = &sdhci;
++ };
++
+ avdd_1v8_s0: avdd-1v8-s0 {
+ compatible = "regulator-fixed";
+ regulator-name = "avdd_1v8_s0";
+--
+2.30.2
+