diff --git a/patch/kernel/rk3399-legacy/helios64-remove-pcie-ep-gpios.patch b/patch/kernel/rk3399-legacy/helios64-remove-pcie-ep-gpios.patch new file mode 100644 index 0000000000..0abb4226d8 --- /dev/null +++ b/patch/kernel/rk3399-legacy/helios64-remove-pcie-ep-gpios.patch @@ -0,0 +1,25 @@ +From 30d236ba51bfe40fd8b9e63351d5efc6534b5a94 Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Tue, 15 Sep 2020 13:58:07 +0700 +Subject: [PATCH] Remove PCIE ep-gpios from Helios64 + +Signed-off-by: Aditya Prayoga +--- + arch/arm64/boot/dts/rockchip/rk3399-helios64.dts | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts +index d5401fd67..7d553a52a 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts +@@ -822,7 +822,6 @@ + + &pcie0 { + bus-scan-delay-ms = <2000>; +- ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; + num-lanes = <2>; + max-link-speed = <2>; + pinctrl-names = "default"; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch b/patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch new file mode 100644 index 0000000000..b92ef21259 --- /dev/null +++ b/patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch @@ -0,0 +1,158 @@ +From fe6dc940b5306c9503d9dc18e7a3fd4a841d37d6 Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Fri, 18 Sep 2020 09:05:53 +0700 +Subject: [PATCH] port pcie changes from ayufan rockchip64 + +Signed-off-by: Aditya Prayoga +--- + Documentation/kernel-parameters.txt | 8 ++++++ + drivers/pci/host/pcie-rockchip.c | 44 ++++++++++++++++++++++++++--- + 2 files changed, 48 insertions(+), 4 deletions(-) + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index 7f4b9aa01..284c97c76 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -3043,6 +3043,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + nomsi Do not use MSI for native PCIe PME signaling (this makes + all PCIe root ports use INTx for all services). + ++ pcie_rk_bus_scan_delay= [PCIE] Delay in ms before ++ scanning PCIe bus in Rockchip PCIe host driver. Some PCIe ++ cards seem to need delays that can be several hundred ms. ++ If set to greater than or equal to 0 this parameter will ++ override delay that can be set in device tree. ++ Values less than 0 mean that this parameter is ignored. ++ default=-1 ++ + pcmv= [HW,PCMCIA] BadgePAD 4 + + pd_ignore_unused +diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c +index 350c8f0df..913362cf7 100644 +--- a/drivers/pci/host/pcie-rockchip.c ++++ b/drivers/pci/host/pcie-rockchip.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -153,6 +154,7 @@ + PCIE_CORE_INT_CT | PCIE_CORE_INT_UTC | \ + PCIE_CORE_INT_MMVC) + ++#define PCIE_RC_CONFIG_NORMAL_BASE 0x800000 + #define PCIE_RC_CONFIG_BASE 0xa00000 + #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) + #define PCIE_RC_CONFIG_SCC_SHIFT 16 +@@ -255,8 +257,12 @@ struct rockchip_pcie { + int wait_ep; + struct dma_trx_obj *dma_obj; + struct list_head resources; ++ u32 bus_scan_delay; + }; + ++static int bus_scan_delay = -1; ++core_param(pcie_rk_bus_scan_delay, bus_scan_delay, int, S_IRUGO); ++ + static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) + { + return readl(rockchip->apb_base + reg); +@@ -355,7 +361,9 @@ static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip, + static int rockchip_pcie_rd_own_conf(struct rockchip_pcie *rockchip, + int where, int size, u32 *val) + { +- void __iomem *addr = rockchip->apb_base + PCIE_RC_CONFIG_BASE + where; ++ void __iomem *addr; ++ ++ addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + where; + + if (!IS_ALIGNED((uintptr_t)addr, size)) { + *val = 0; +@@ -379,11 +387,13 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip, + int where, int size, u32 val) + { + u32 mask, tmp, offset; ++ void __iomem *addr; + + offset = where & ~0x3; ++ addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + offset; + + if (size == 4) { +- writel(val, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset); ++ writel(val, addr); + return PCIBIOS_SUCCESSFUL; + } + +@@ -394,9 +404,9 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip, + * corrupt RW1C bits in adjacent registers. But the hardware + * doesn't support smaller writes. + */ +- tmp = readl(rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset) & mask; ++ tmp = readl(addr) & mask; + tmp |= val << ((where & 0x3) * 8); +- writel(tmp, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset); ++ writel(tmp, addr); + + return PCIBIOS_SUCCESSFUL; + } +@@ -677,6 +687,11 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) + status |= PCI_EXP_LNKCTL_CCC; + rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); + ++ /* Set RC's RCB to 128 */ ++ status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); ++ status |= PCI_EXP_LNKCTL_RCB; ++ rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); ++ + /* Enable Gen1 training */ + rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, + PCIE_CLIENT_CONFIG); +@@ -1103,6 +1118,14 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) + dev_info(dev, "no vpcie0v9 regulator found\n"); + } + ++ err = of_property_read_u32(node, "bus-scan-delay-ms", &rockchip->bus_scan_delay); ++ if (err) { ++ dev_info(dev, "no bus-scan-delay-ms in device tree, default 0 ms\n"); ++ rockchip->bus_scan_delay = 0; ++ } else { ++ dev_info(dev, "bus-scan-delay-ms in device tree is %u ms\n", rockchip->bus_scan_delay); ++ } ++ + mem = of_parse_phandle(node, "memory-region", 0); + if (!mem) { + dev_warn(dev, "missing \"memory-region\" property\n"); +@@ -1432,6 +1455,7 @@ static int rockchip_pcie_really_probe(struct rockchip_pcie *rockchip) + int err; + struct pci_bus *bus, *child; + struct device *dev = rockchip->dev; ++ u32 delay = 0; + + err = rockchip_pcie_init_port(rockchip); + if (err) +@@ -1443,6 +1467,18 @@ static int rockchip_pcie_really_probe(struct rockchip_pcie *rockchip) + if (err) + return err; + ++ /* Prefer command-line param over device tree */ ++ if (bus_scan_delay > 0) { ++ delay = bus_scan_delay; ++ dev_info(dev, "wait %u ms (from command-line) before bus scan\n", delay); ++ } else if (rockchip->bus_scan_delay > 0 && bus_scan_delay < 0) { ++ delay = rockchip->bus_scan_delay; ++ dev_info(dev, "wait %u ms (from device tree) before bus scan\n", delay); ++ } ++ if (delay > 0) { ++ msleep(delay); ++ } ++ + bus = pci_scan_root_bus(dev, 0, &rockchip_pcie_ops, + rockchip, &rockchip->resources); + if (!bus) +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch.disabled b/patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch.disabled deleted file mode 100644 index 04d4cdb892..0000000000 --- a/patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch.disabled +++ /dev/null @@ -1,241 +0,0 @@ -From e5467fb60570c9c300e9d412b9d5386cbb9951ba Mon Sep 17 00:00:00 2001 -From: Aditya Prayoga -Date: Mon, 18 May 2020 09:42:14 +0700 -Subject: [PATCH] port pcie changes from ayufan rockchip64 - -Signed-off-by: Aditya Prayoga ---- - drivers/pci/host/pcie-rockchip.c | 119 +++++++++++++++++++++++++------ - 1 file changed, 96 insertions(+), 23 deletions(-) - -diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c -index 87291016d..1823323f8 100644 ---- a/drivers/pci/host/pcie-rockchip.c -+++ b/drivers/pci/host/pcie-rockchip.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -153,6 +154,7 @@ - PCIE_CORE_INT_CT | PCIE_CORE_INT_UTC | \ - PCIE_CORE_INT_MMVC) - -+#define PCIE_RC_CONFIG_NORMAL_BASE 0x800000 - #define PCIE_RC_CONFIG_BASE 0xa00000 - #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) - #define PCIE_RC_CONFIG_SCC_SHIFT 16 -@@ -189,6 +191,8 @@ - #define IB_ROOT_PORT_REG_SIZE_SHIFT 3 - #define AXI_WRAPPER_IO_WRITE 0x6 - #define AXI_WRAPPER_MEM_WRITE 0x2 -+#define AXI_WRAPPER_TYPE0_CFG 0xa -+#define AXI_WRAPPER_TYPE1_CFG 0xb - #define AXI_WRAPPER_CFG0 0xa - #define AXI_WRAPPER_NOR_MSG 0xc - -@@ -213,6 +217,7 @@ - #define RC_REGION_0_ADDR_TRANS_H 0x00000000 - #define RC_REGION_0_ADDR_TRANS_L 0x00000000 - #define RC_REGION_0_PASS_BITS (25 - 1) -+#define RC_REGION_0_TYPE_MASK GENMASK(3, 0) - #define MAX_AXI_WRAPPER_REGION_NUM 33 - - struct rockchip_pcie { -@@ -253,8 +258,12 @@ struct rockchip_pcie { - int wait_ep; - struct dma_trx_obj *dma_obj; - struct list_head resources; -+ u32 bus_scan_delay; - }; - -+static int bus_scan_delay = -1; -+core_param(pcie_rk_bus_scan_delay, bus_scan_delay, int, S_IRUGO); -+ - static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) - { - return readl(rockchip->apb_base + reg); -@@ -330,7 +339,9 @@ static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip, - static int rockchip_pcie_rd_own_conf(struct rockchip_pcie *rockchip, - int where, int size, u32 *val) - { -- void __iomem *addr = rockchip->apb_base + PCIE_RC_CONFIG_BASE + where; -+ void __iomem *addr; -+ -+ addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + where; - - if (!IS_ALIGNED((uintptr_t)addr, size)) { - *val = 0; -@@ -354,11 +365,13 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip, - int where, int size, u32 val) - { - u32 mask, tmp, offset; -+ void __iomem *addr; - - offset = where & ~0x3; -+ addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + offset; - - if (size == 4) { -- writel(val, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset); -+ writel(val, addr); - return PCIBIOS_SUCCESSFUL; - } - -@@ -369,13 +382,33 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip, - * corrupt RW1C bits in adjacent registers. But the hardware - * doesn't support smaller writes. - */ -- tmp = readl(rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset) & mask; -+ tmp = readl(addr) & mask; - tmp |= val << ((where & 0x3) * 8); -- writel(tmp, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset); -+ writel(tmp, addr); - - return PCIBIOS_SUCCESSFUL; - } - -+static void rockchip_pcie_cfg_configuration_accesses( -+ struct rockchip_pcie *rockchip, u32 type) -+{ -+ u32 ob_desc_0; -+ -+ /* Configuration Accesses for region 0 */ -+ rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); -+ -+ rockchip_pcie_write(rockchip, -+ (RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS), -+ PCIE_CORE_OB_REGION_ADDR0); -+ rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H, -+ PCIE_CORE_OB_REGION_ADDR1); -+ ob_desc_0 = rockchip_pcie_read(rockchip, PCIE_CORE_OB_REGION_DESC0); -+ ob_desc_0 &= ~(RC_REGION_0_TYPE_MASK); -+ ob_desc_0 |= (type | (0x1 << 23)); -+ rockchip_pcie_write(rockchip, ob_desc_0, PCIE_CORE_OB_REGION_DESC0); -+ rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1); -+} -+ - static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip, - struct pci_bus *bus, u32 devfn, - int where, int size, u32 *val) -@@ -385,11 +418,23 @@ static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip, - busdev = PCIE_ECAM_ADDR(bus->number, PCI_SLOT(devfn), - PCI_FUNC(devfn), where); - -+ if (bus->number > 0x1f) { -+ *val = 0; -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ } -+ - if (!IS_ALIGNED(busdev, size)) { - *val = 0; - return PCIBIOS_BAD_REGISTER_NUMBER; - } - -+ if (bus->parent->number == rockchip->root_bus_nr) -+ rockchip_pcie_cfg_configuration_accesses(rockchip, -+ AXI_WRAPPER_TYPE0_CFG); -+ else -+ rockchip_pcie_cfg_configuration_accesses(rockchip, -+ AXI_WRAPPER_TYPE1_CFG); -+ - if (size == 4) { - *val = readl(rockchip->reg_base + busdev); - } else if (size == 2) { -@@ -411,9 +456,19 @@ static int rockchip_pcie_wr_other_conf(struct rockchip_pcie *rockchip, - - busdev = PCIE_ECAM_ADDR(bus->number, PCI_SLOT(devfn), - PCI_FUNC(devfn), where); -+ -+ if (bus->number > 0x1f) -+ return PCIBIOS_DEVICE_NOT_FOUND; - if (!IS_ALIGNED(busdev, size)) - return PCIBIOS_BAD_REGISTER_NUMBER; - -+ if (bus->parent->number == rockchip->root_bus_nr) -+ rockchip_pcie_cfg_configuration_accesses(rockchip, -+ AXI_WRAPPER_TYPE0_CFG); -+ else -+ rockchip_pcie_cfg_configuration_accesses(rockchip, -+ AXI_WRAPPER_TYPE1_CFG); -+ - if (size == 4) - writel(val, rockchip->reg_base + busdev); - else if (size == 2) -@@ -638,6 +693,11 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) - status |= PCI_EXP_LNKCTL_CCC; - rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); - -+ /* Set RC's RCB to 128 */ -+ status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); -+ status |= PCI_EXP_LNKCTL_RCB; -+ rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); -+ - /* Enable Gen1 training */ - rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, - PCIE_CLIENT_CONFIG); -@@ -696,15 +756,8 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) - rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LINK_CAP); - } - -- rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); -- -- rockchip_pcie_write(rockchip, -- (RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS), -- PCIE_CORE_OB_REGION_ADDR0); -- rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H, -- PCIE_CORE_OB_REGION_ADDR1); -- rockchip_pcie_write(rockchip, 0x0080000a, PCIE_CORE_OB_REGION_DESC0); -- rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1); -+ rockchip_pcie_cfg_configuration_accesses(rockchip, -+ AXI_WRAPPER_TYPE0_CFG); - - return 0; - } -@@ -1067,6 +1120,14 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) - dev_info(dev, "no vpcie0v9 regulator found\n"); - } - -+ err = of_property_read_u32(node, "bus-scan-delay-ms", &rockchip->bus_scan_delay); -+ if (err) { -+ dev_info(dev, "no bus-scan-delay-ms in device tree, default 0 ms\n"); -+ rockchip->bus_scan_delay = 0; -+ } else { -+ dev_info(dev, "bus-scan-delay-ms in device tree is %u ms\n", rockchip->bus_scan_delay); -+ } -+ - mem = of_parse_phandle(node, "memory-region", 0); - if (!mem) { - dev_warn(dev, "missing \"memory-region\" property\n"); -@@ -1396,6 +1457,7 @@ static int rockchip_pcie_really_probe(struct rockchip_pcie *rockchip) - int err; - struct pci_bus *bus, *child; - struct device *dev = rockchip->dev; -+ u32 delay = 0; - - err = rockchip_pcie_init_port(rockchip); - if (err) -@@ -1407,6 +1469,18 @@ static int rockchip_pcie_really_probe(struct rockchip_pcie *rockchip) - if (err) - return err; - -+ /* Prefer command-line param over device tree */ -+ if (bus_scan_delay > 0) { -+ delay = bus_scan_delay; -+ dev_info(dev, "wait %u ms (from command-line) before bus scan\n", delay); -+ } else if (rockchip->bus_scan_delay > 0 && bus_scan_delay < 0) { -+ delay = rockchip->bus_scan_delay; -+ dev_info(dev, "wait %u ms (from device tree) before bus scan\n", delay); -+ } -+ if (delay > 0) { -+ msleep(delay); -+ } -+ - bus = pci_scan_root_bus(dev, 0, &rockchip_pcie_ops, - rockchip, &rockchip->resources); - if (!bus) --- -Created with Armbian build tools https://github.com/armbian/build - diff --git a/patch/kernel/rockchip64-current/helios64-remove-pcie-ep-gpios.patch b/patch/kernel/rockchip64-current/helios64-remove-pcie-ep-gpios.patch new file mode 100644 index 0000000000..9ef0d9fd1c --- /dev/null +++ b/patch/kernel/rockchip64-current/helios64-remove-pcie-ep-gpios.patch @@ -0,0 +1,25 @@ +From e7e9a3a959927094d59b67f46ecc1c5d50190ce8 Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Tue, 15 Sep 2020 13:42:02 +0700 +Subject: [PATCH] Remove PCIE ep-gpios from Helios64 + +Signed-off-by: Aditya Prayoga +--- + arch/arm64/boot/dts/rockchip/rk3399-helios64.dts | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts +index c065ba82d..002c93912 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts +@@ -721,7 +721,6 @@ + }; + + &pcie0 { +- ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; + num-lanes = <2>; + max-link-speed = <2>; + pinctrl-names = "default"; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/rockchip64-current/rk3399-pci-rockchip-support-ep-gpio-undefined-case.patch b/patch/kernel/rockchip64-current/rk3399-pci-rockchip-support-ep-gpio-undefined-case.patch new file mode 100644 index 0000000000..95a6dd68f6 --- /dev/null +++ b/patch/kernel/rockchip64-current/rk3399-pci-rockchip-support-ep-gpio-undefined-case.patch @@ -0,0 +1,29 @@ +From 002593cfe8fc7539a6aa2dfb246d832e0b8b8516 Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Tue, 15 Sep 2020 13:29:45 +0700 +Subject: [PATCH] PCI: rockchip: support ep-gpio undefined case + +Signed-off-by: Aditya Prayoga +--- + drivers/pci/controller/pcie-rockchip.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c +index c53d1322a..e4f42591d 100644 +--- a/drivers/pci/controller/pcie-rockchip.c ++++ b/drivers/pci/controller/pcie-rockchip.c +@@ -119,9 +119,9 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) + } + + if (rockchip->is_rc) { +- rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH); ++ rockchip->ep_gpio = devm_gpiod_get_optional(dev, "ep", GPIOD_OUT_HIGH); + if (IS_ERR(rockchip->ep_gpio)) { +- dev_err(dev, "missing ep-gpios property in node\n"); ++ dev_err(dev, "invalid ep-gpios property in node\n"); + return PTR_ERR(rockchip->ep_gpio); + } + } +-- +Created with Armbian build tools https://github.com/armbian/build +