Full Code of quintus-lab/openwrt-rockchip for AI

master 1e0e7f892836 cached
134 files
2.1 MB
559.1k tokens
1 requests
Download .txt
Showing preview only (2,238K chars total). Download the full file or copy to clipboard to get everything.
Repository: quintus-lab/openwrt-rockchip
Branch: master
Commit: 1e0e7f892836
Files: 134
Total size: 2.1 MB

Directory structure:
gitextract_5hrojddq/

├── .github/
│   └── workflows/
│       └── openwrt-rockchip.yml
├── .gitignore
├── LICENSE
├── README.md
├── body-origin.md
├── not_use_file/
│   ├── 0002-rockchip-rngd.patch
│   ├── 0003-add_rockchip_k510_support.patch
│   ├── 0003-new_rk33xx_support_with_ARMv8_CE_k5.10.patch
│   ├── 0003-new_rockchip_support_k510.patch
│   ├── 0003-rockchip-fixes-re-boot-with-UHS-cards.patch
│   ├── 0004-add-new-rk33xx-support.patch
│   ├── 0004-uboot-add-r4s-support.patch
│   ├── 0005-target-5.10-r4s-support.patch
│   ├── 0005-target-add-r4s-support.patch
│   ├── 0006-config54.patch
│   ├── 0006-target-5.10-rockchip-support.patch
│   ├── 0009-rockchip-add-support-for-OrangePi-R1-Plus.patch-old
│   ├── 0009-rockchip-introduce-vendor-USB3-inno-driver.patch
│   ├── 0010-rk3328_refresh_usb3_nodes_k5.10.patch
│   ├── 005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
│   ├── 007-arm64-dts-rockchip-Add-RK3328-idle-state.patch
│   ├── 01-prepare_package.sh
│   ├── 02-convert_translation.sh
│   ├── 1002-add-fullconenat-and-shortcut-fe-support.patch
│   ├── 1002-luci-app-firewall_add_sfe_switch.patch
│   ├── 1003-shortcut-fe.patch
│   ├── 1004-fullconenat.patch
│   ├── 1004-netconntrack.patch
│   ├── 18.06.seed
│   ├── 18.06.sh
│   ├── 2000-zzz-default.patch
│   ├── 2001-ssr-plus-tls-181.patch
│   ├── 2001-ssr-plus-tls.patch
│   ├── 2002-luci-app-freq-r2s.patch
│   ├── 2002-luci-app-freq-r4s.patch
│   ├── 3829.patch
│   ├── 900-add-filter-aaaa-option.patch
│   ├── 911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch
│   ├── 991-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch
│   ├── 998-rockchip-enable-i2c0-on-NanoPi-R2S.patch
│   ├── 999-unlock-1608mhz-rk3328.patch
│   ├── Friendlywrt_archive/
│   │   ├── 000-fullconenat.patch
│   │   ├── 000-kernel-add-full_cone_nat.patch
│   │   ├── 001-cpu-enable_autocore.patch
│   │   ├── 002-enable-O3.patch
│   │   ├── base_rk3328.seed
│   │   ├── check
│   │   ├── check_inet.sh
│   │   ├── defconfig.override
│   │   ├── luci-app-r2sflasher_1.0-4_all.ipk
│   │   ├── opt.seed
│   │   ├── patch_kernel_5.4.sh
│   │   ├── r2s-mwan3.yml
│   │   ├── r2s-opt.yml
│   │   ├── r2s-slim-test.yml
│   │   ├── r2s-slim.yml
│   │   ├── r2s-tiny.yml
│   │   ├── r2s_step/
│   │   │   ├── 00_init_env.sh
│   │   │   ├── 01_friendlywrt.sh
│   │   │   ├── 02_rebase2lean.sh
│   │   │   ├── 03_kernel.sh
│   │   │   ├── 04_fullcone_1.5g.sh
│   │   │   ├── 06_mod_opt.sh
│   │   │   ├── 06_mod_slim.sh
│   │   │   ├── 09_load_config.sh
│   │   │   └── 10_fix_rootfs.sh
│   │   ├── slim.seed
│   │   ├── slim.seed copy
│   │   ├── test.seed
│   │   ├── tiny.seed
│   │   └── update.sh
│   ├── Remove old artifacts.yml
│   ├── Support-hardware-random-number-generator-for-RK3328.patch
│   ├── cleanup.yml
│   ├── cod.seed
│   ├── customization.yml
│   ├── dnsmasq-add-filter-aaaa-option.patch
│   ├── for_r2s_18.06.patch
│   ├── for_r2s_19.07_config-default.patch
│   ├── fullconenat/
│   │   ├── Makefile
│   │   ├── files/
│   │   │   └── Makefile
│   │   └── patches/
│   │       └── 000-printk.patch
│   ├── k5.10.20.patch
│   ├── kernel_crypto-add-rk3328-crypto-support.patch
│   ├── luci-add-filter-aaaa-option.patch
│   ├── luci-app-firewall_add_sfe_switch.patch
│   ├── luci-app-freq.patch
│   ├── luci_network-add-packet-steering.patch
│   ├── modules/
│   │   └── cryptodev-linux/
│   │       └── Makefile
│   ├── nanopi-openwrt copy.yml
│   ├── origin-full.seed
│   ├── origin-full.sh
│   ├── origin-full.yml
│   ├── origin-slim.seed
│   ├── purge-slim.seed
│   ├── purge-slim.yml
│   ├── purge_artifacts.sh
│   ├── r2s-18.06.yml
│   ├── shortcut-fe
│   ├── ssr-plus-tls.patch
│   ├── use_json_object_new_int64.patch
│   ├── zzz-default-settings-18.06
│   ├── zzz.patch
│   └── zzzzz.patch
├── patches/
│   ├── 0000-use_json_object_new_int64.patch
│   ├── 0001-tools-add-upx-ucl-support.patch
│   ├── 0003-rockchip-rk3328-dmc.patch
│   ├── 0004-add-new-rk33xx-support-k510.patch
│   ├── 0006-support-rk33xx-HWRNG.patch
│   ├── 0007-optimize_for_rk3399.patch
│   ├── 0008-mbedtls-Implements-AES-and-GCM-with-ARMv8-Crypto-Ext.patch
│   ├── 0009-rockchip-add-support-for-OrangePi-R1-Plus.patch
│   ├── 1001-dnsmasq_add_filter_aaaa_option.patch
│   ├── 1002-fw3_fullconenat.patch
│   ├── 1003-luci-app-firewall_add_fullcone.patch
│   ├── 2001-add-5.14-support.patch
│   ├── 2002-rockchip-add-5.14-support.patch
│   ├── 2003-mod-for-k514.patch
│   ├── 910-mini-ttl.patch
│   └── 911-dnsmasq-filter-aaaa.patch
├── script/
│   ├── free_disk_space.sh
│   ├── origin-slim.sh
│   ├── step.sh
│   └── zzz-default-settings
├── seed/
│   ├── k514.seed
│   ├── nanopi.seed
│   ├── r2s.seed
│   ├── r4s.seed
│   └── rockchip.seed
└── step/
    ├── 00-prepare_5.10.sh
    ├── 01-prepare_package.sh
    ├── 02-remove_upx.sh
    ├── 03-create_acl_for_luci.sh
    └── 04-k5.14.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/openwrt-rockchip.yml
================================================
#=================================================
# Description: Build OpenWrt using GitHub Actions
# Lisence: MIT

name: OpenWRT-snapshot

on:
#  release:
#    types: published
  push:
    branches:
      - master
    paths:
      - '.github/workflows/openwrt-rockchip.yml'
      - 'step/01-prepare_package.sh'
      - 'step/00-prepare_5.10.sh'
      - 'seed/rockchip.seed'
  schedule:
    - cron: 35 20 * * 2,5
  watch:
    types: started

jobs:
    openwrt-master:
      runs-on: ubuntu-18.04
      if: github.event.repository.owner.id == github.event.sender.id

      steps:
      - name: Checkout
        uses: actions/checkout@main

      - name: Show CPU Model and Free Space
        run: |
          echo -e "Total CPU cores\t: $(nproc)"
          cat /proc/cpuinfo | grep 'model name'
          free -h

      - name: Set env
        run: |
          echo "SSH_ACTIONS=false" >> $GITHUB_ENV
          echo "UPLOAD_BIN_DIR=false" >> $GITHUB_ENV
          echo "UPLOAD_FIRMWARE=true" >> $GITHUB_ENV
          echo "UPLOAD_RELEASE=true" >> $GITHUB_ENV
          echo "TZ=Asia/Shanghai" >>$GITHUB_ENV
          echo "Build_Date=$(date +%Y.%m.%d)" >> $GITHUB_ENV
          
      - name: Show env
        run: echo $GITHUB_ENV

      - name: free disk space
        run: |
          df -h
          sudo swapoff -a
          sudo rm -f /swapfile
          sudo apt clean
          docker rmi $(docker image ls -aq)
          df -h
          /bin/bash ./script/free_disk_space.sh

      - name: Initialization environment
        env:
          DEBIAN_FRONTEND: noninteractive
        run: |
          sudo -E rm -rf /etc/apt/sources.list.d
          sudo -E apt-get update -y
          sudo -E apt-get install -y build-essential rsync asciidoc binutils bzip2 gawk gettext git libncurses5-dev libz-dev patch unzip zlib1g-dev lib32gcc1 libc6-dev-i386 subversion flex uglifyjs git-core p7zip p7zip-full msmtp libssl-dev texinfo libreadline-dev libglib2.0-dev xmlto qemu-utils upx libelf-dev autoconf automake libtool autopoint ccache curl wget vim nano python3 python3-pip python3-ply haveged lrzsz device-tree-compiler scons
          wget -qO - https://raw.githubusercontent.com/friendlyarm/build-env-on-ubuntu-bionic/master/install.sh | sed 's/python-/python3-/g' | /bin/bash
          sudo -E apt-get clean -y
          git config --global user.name 'GitHub Actions' && git config --global user.email 'noreply@github.com'
          df -h

      - name: Install OpenWrt source
        run: |
          git clone -b master --single-branch https://git.openwrt.org/openwrt/openwrt.git openwrt

      - name: Prepare openwrt
        run: |
          cd openwrt
          cp -r ../step/* ./
          /bin/bash 00-prepare_5.10.sh

      - name: Prepare application packages
        run: |
          cd openwrt
          /bin/bash 01-prepare_package.sh

      - name: Add ACL
        run: |
          cd openwrt
          /bin/bash 03-create_acl_for_luci.sh -a

      - name: Load Multiple devices Config
        run: |
          cd openwrt
          mv ../seed/rockchip.seed .config
          make defconfig
          cp .config  rockchip_multi.config

#      - name: Download package
#        id: package
#        run: |
#          cd openwrt
#          make download -j10
#          find dl -size -1024c -exec ls -l {} \;
#          find dl -size -1024c -exec rm -f {} \;
#
#      - name: Make toolchain-aarch64
#        id: compiletoolchain
#        continue-on-error: true
#        run: |
#          cd openwrt
#          let make_process=$(nproc)+1
#          make toolchain/install -j${make_process} V=s

#      - name: If toolchain Error
#        if: steps.compiletoolchain.outcome == 'failure'
#        run: |
#          echo '================================================================'
#          cd openwrt && make toolchain/install -j1 V=s


      - name: Compile OpenWRT for R2S & R4S & R1 plus
        id: compileopenwrt
        continue-on-error: true
        run: |
          cd openwrt
          let make_process=$(nproc)+1
          make -j${make_process} V=s || make -j${make_process} V=s

      - name: If compile openwrt Error
        if: steps.compileopenwrt.outcome == 'failure'
        run: |
          cat openwrt/.config
          echo '================================================================'
          cd openwrt && make -j1 V=s

      - name: Organize files
        id: organize
        run: |
          rm -rf ./artifact/
          mkdir -p ./artifact/
          mv openwrt/bin/targets/rockchip/armv8/*sysupgrade.img* ./artifact/
          cd ./artifact/
          ls -Ahl
          gzip -d *.gz && exit 0
          gzip *.img
          sha256sum openwrt*r2s* | tee R2S-QC-$(date +%Y-%m-%d).sha256sum
          sha256sum openwrt*r4s* | tee R4S-QC-$(date +%Y-%m-%d).sha256sum
          sha256sum openwrt*r1-plus* | tee R1-plus-QC-$(date +%Y-%m-%d).sha256sum
          ls -Ahl
          zip R2S-QC-$(date +%Y-%m-%d)-snapshot.zip *r2s* R2S*.sha256sum
          zip R4S-QC-$(date +%Y-%m-%d)-snapshot.zip *r4s* R4S*.sha256sum
          zip R1-plus-QC-$(date +%Y-%m-%d)-snapshot.zip *r1-plus* R1-plus*.sha256sum        
          cp ../openwrt/*.config ./
          ls -Ahl

      - name: Upload artifact master
        uses: actions/upload-artifact@main
        if: env.UPLOAD_FIRMWARE == 'true' && !cancelled()
        with:
          name: OpenWRT_NanoPi_firmware
          path: ./artifact/*.zip


      - name: Compile OpenWRT for kernel 5.14
        id: compile514
        run: |
          cd openwrt
          /bin/bash 04-k5.14.sh
          mv ../seed/k514.seed .config
          make defconfig
          let make_process=$(nproc)+1
          make -j${make_process} V=s || make -j${make_process} V=s

      - name: If compile openwrt 5.14 Error
        if: steps.compile514.outcome == 'failure'
        run: |
          cat openwrt/.config
          echo '================================================================'
          cd openwrt && make -j1 V=s

      - name: Organize k5.14 files
        id: organize514
        run: |
          rm -rf ./artifact514/
          mkdir -p ./artifact514/
          mv openwrt/bin/targets/rockchip/armv8/*sysupgrade.img* ./artifact514/
          cd ./artifact514/
          ls -Ahl
          gzip -d *.gz && exit 0
          gzip *.img
          sha256sum openwrt*r2s* | tee R2S-QC-k514.sha256sum
          sha256sum openwrt*r4s* | tee R4S-QC-k514.sha256sum
          sha256sum openwrt*r1-plus* | tee R1-plus-QC-k514.sha256sum
          ls -Ahl
          zip R2S-QC-$(date +%Y-%m-%d)-k514.zip *r2s* R2S*.sha256sum
          zip R4S-QC-$(date +%Y-%m-%d)-k514.zip *r4s* R4S*.sha256sum
          zip R1-plus-QC-$(date +%Y-%m-%d)-k514.zip *r1-plus* R1-plus*.sha256sum        
          ls -Ahl

      - name: Upload k5.14 firmware
        uses: actions/upload-artifact@main
        with:
          name: openwrt kernel 5.14 firmware
          path: ./artifact514/*.zip

      - name: Create release for master
        id: create_release
        uses: ncipollo/release-action@v1.8.8
        if: env.UPLOAD_RELEASE == 'true' && !cancelled()
        with:
          name: OpenWRT-rockchip-kernel 5.10 daily update
          allowUpdates: true
          tag: snapshot
          commit: master
          replacesArtifacts: true
          token: ${{ secrets.RELEASES_TOKEN }}
          bodyFile: "body-origin.md"
          artifacts: ./artifact/*.zip,./artifact/*.config

    Cleanup-Old-Artifacts:
      needs: [openwrt-master]
      runs-on: ubuntu-18.04
      steps:
      - name: Cleanup Old Action Artifacts
        uses: kolpav/purge-artifacts-action@v1
        with:
          token: ${{ github.token }}
          expire-in: 14d
    Cleanup-Workflow-Runs:
      needs: Cleanup-Old-Artifacts
      runs-on: ubuntu-18.04
      steps:
      - name: Cleanup Workflow Runs
        uses: GitRML/delete-workflow-runs@v1.2.1
        with:
          token: ${{ github.token }}
          repository: ${{ github.repository }}
          retain_days: 14


================================================
FILE: .gitignore
================================================

*/.DS_Store
.DS_Store



================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2020 quintus

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
## OpenWrt for Rockchip rk3328/rk3399, include Nanopi R2S/R4S and OrangePi R1 plus 
#### ⚠ WARNING: USE IT UNDER YOUR OWN RISK. Non profit use only ⚠ 
[![OpenWRT-snapshot](https://github.com/quintus-lab/OpenWRT-Rockchip/actions/workflows/openwrt-rockchip.yml/badge.svg?branch=master)](https://github.com/quintus-lab/OpenWRT-Rockchip/actions/workflows/openwrt-rockchip.yml)
[![OpenWRT-21.02](https://github.com/quintus-lab/OpenWRT-Rockchip/actions/workflows/openwrt-rockchip-2102.yml/badge.svg?branch=21.02)](https://github.com/quintus-lab/OpenWRT-Rockchip/actions/workflows/openwrt-rockchip-2102.yml)

##### Download: [Releases](https://github.com/quintus-lab/OpenWRT-R2S-R4S/releases) or [Actions](https://github.com/quintus-lab/Openwrt-R2S-R4S/actions) \(Login Needed\)
- - -
## Introduction
- ### Usage
0. OpenWRT Official master source code + CTCGFW & Lean's packages code <br/>
1. Default Management IP addr is [192.168.1.1](192.168.1.1), username: `root`  , no password<br/>
 Please setup the login password **as soon as possible** once you logined.
2. Once you flashed the firmware into SD card, you may simply use "Upgrade" function<br/>
 in LuCI (no need to decompress the **.gz** archive) if you want to update it.
3. Support USB LTE Hilink Dongle and USB Tethering. 
4. Can keeping configurations in upgrade is **suggested**, it's totally unnecessary to drop them.

- ### Applications
  AccessControl, ADbyby, CFDisk, DDNS, DiskMan, FRP, Gost, SpeedTest-CLI, SSRPlus, Socat, Stress-ng, Tmate, UPNP, Wake-On-LAN, WireGuard, ZeroTier etc.
- - -

### Thanks to Bigwigs:

- [CN_SZTL](https://github.com/1715173329)
- [QiuSimons](https://github.com/QiuSimons)
- [CTCGFW](https://github.com/project-openwrt/openwrt)
- [AmadeusGhost](https://github.com/AmadeusGhost)
- [Lean](https://github.com/coolsnowwolf/lede)

### License
[MIT](https://github.com/quintus-lab/Openwrt-R2S-R4S/blob/master/LICENSE)

🇹🇼🇨🇦🇺🇸🇭🇰


#### Screenshot
![R2S](pic/r2s.png)
![R4S](pic/r4s.png)
![R2S NAT Throughput](pic/NAT_Throughput.jpg)


================================================
FILE: body-origin.md
================================================
***OpenWRT master with Kernel 5.10 daily update***
support: nanopi-r2s nanopi-r4s orangepi-r1-plus

================================================
FILE: not_use_file/0002-rockchip-rngd.patch
================================================
From a13fecb3fdaf3ed707400d6950dd8934304ba563 Mon Sep 17 00:00:00 2001
From: CN_SZTL <cnsztl@project-openwrt.eu.org>
Date: Sun, 29 Nov 2020 11:30:32 +0800
Subject: [PATCH] rockchip: move hwRNG driver to files

---
 .../drivers/char/hw_random/rockchip-rng.c     | 340 +++++++++++++++++
 1 files changed, 340 insertions(+)
 create mode 100644 target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c

diff --git a/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c b/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c
new file mode 100644
index 0000000000..718762f996
--- /dev/null
+++ b/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * rockchip-rng.c Random Number Generator driver for the Rockchip
+ *
+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd.
+ * Author: Lin Jinhan <troy.lin@rock-chips.com>
+ *
+ */
+#include <linux/clk.h>
+#include <linux/hw_random.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#define _SBF(s, v)	((v) << (s))
+#define HIWORD_UPDATE(val, mask, shift) \
+			((val) << (shift) | (mask) << ((shift) + 16))
+
+#define ROCKCHIP_AUTOSUSPEND_DELAY		100
+#define ROCKCHIP_POLL_PERIOD_US			100
+#define ROCKCHIP_POLL_TIMEOUT_US		10000
+#define RK_MAX_RNG_BYTE				(32)
+
+/* start of CRYPTO V1 register define */
+#define CRYPTO_V1_CTRL				0x0008
+#define CRYPTO_V1_RNG_START			BIT(8)
+#define CRYPTO_V1_RNG_FLUSH			BIT(9)
+
+#define CRYPTO_V1_TRNG_CTRL			0x0200
+#define CRYPTO_V1_OSC_ENABLE			BIT(16)
+#define CRYPTO_V1_TRNG_SAMPLE_PERIOD(x)		(x)
+
+#define CRYPTO_V1_TRNG_DOUT_0			0x0204
+/* end of CRYPTO V1 register define */
+
+/* start of CRYPTO V2 register define */
+#define CRYPTO_V2_RNG_CTL			0x0400
+#define CRYPTO_V2_RNG_64_BIT_LEN		_SBF(4, 0x00)
+#define CRYPTO_V2_RNG_128_BIT_LEN		_SBF(4, 0x01)
+#define CRYPTO_V2_RNG_192_BIT_LEN		_SBF(4, 0x02)
+#define CRYPTO_V2_RNG_256_BIT_LEN		_SBF(4, 0x03)
+#define CRYPTO_V2_RNG_FATESY_SOC_RING		_SBF(2, 0x00)
+#define CRYPTO_V2_RNG_SLOWER_SOC_RING_0		_SBF(2, 0x01)
+#define CRYPTO_V2_RNG_SLOWER_SOC_RING_1		_SBF(2, 0x02)
+#define CRYPTO_V2_RNG_SLOWEST_SOC_RING		_SBF(2, 0x03)
+#define CRYPTO_V2_RNG_ENABLE			BIT(1)
+#define CRYPTO_V2_RNG_START			BIT(0)
+#define CRYPTO_V2_RNG_SAMPLE_CNT		0x0404
+#define CRYPTO_V2_RNG_DOUT_0			0x0410
+/* end of CRYPTO V2 register define */
+
+struct rk_rng_soc_data {
+	const char * const *clks;
+	int clks_num;
+	int (*rk_rng_read)(struct hwrng *rng, void *buf, size_t max, bool wait);
+};
+
+struct rk_rng {
+	struct device		*dev;
+	struct hwrng		rng;
+	void __iomem		*mem;
+	struct rk_rng_soc_data	*soc_data;
+	u32			clk_num;
+	struct clk_bulk_data	*clk_bulks;
+};
+
+static const char * const rk_rng_v1_clks[] = {
+	"hclk_crypto",
+	"clk_crypto",
+};
+
+static const char * const rk_rng_v2_clks[] = {
+	"hclk_crypto",
+	"aclk_crypto",
+	"clk_crypto",
+	"clk_crypto_apk",
+};
+
+static void rk_rng_writel(struct rk_rng *rng, u32 val, u32 offset)
+{
+	__raw_writel(val, rng->mem + offset);
+}
+
+static u32 rk_rng_readl(struct rk_rng *rng, u32 offset)
+{
+	return __raw_readl(rng->mem + offset);
+}
+
+static int rk_rng_init(struct hwrng *rng)
+{
+	int ret;
+	struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
+
+	dev_dbg(rk_rng->dev, "clk_bulk_prepare_enable.\n");
+
+	ret = clk_bulk_prepare_enable(rk_rng->clk_num, rk_rng->clk_bulks);
+	if (ret < 0) {
+		dev_err(rk_rng->dev, "failed to enable clks %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void rk_rng_cleanup(struct hwrng *rng)
+{
+	struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
+
+	dev_dbg(rk_rng->dev, "clk_bulk_disable_unprepare.\n");
+	clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks);
+}
+
+static void rk_rng_read_regs(struct rk_rng *rng, u32 offset, void *buf,
+			     size_t size)
+{
+	u32 i;
+
+	for (i = 0; i < size; i += 4)
+		*(u32 *)(buf + i) = be32_to_cpu(rk_rng_readl(rng, offset + i));
+}
+
+static int rk_rng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+	int ret = 0;
+	u32 reg_ctrl = 0;
+	struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
+
+	ret = pm_runtime_get_sync(rk_rng->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(rk_rng->dev);
+		return ret;
+	}
+
+	/* enable osc_ring to get entropy, sample period is set as 100 */
+	reg_ctrl = CRYPTO_V1_OSC_ENABLE | CRYPTO_V1_TRNG_SAMPLE_PERIOD(100);
+	rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_TRNG_CTRL);
+
+	reg_ctrl = HIWORD_UPDATE(CRYPTO_V1_RNG_START, CRYPTO_V1_RNG_START, 0);
+
+	rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL);
+
+	ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V1_CTRL, reg_ctrl,
+				 !(reg_ctrl & CRYPTO_V1_RNG_START),
+				 ROCKCHIP_POLL_PERIOD_US,
+				 ROCKCHIP_POLL_TIMEOUT_US);
+	if (ret < 0)
+		goto out;
+
+	ret = min_t(size_t, max, RK_MAX_RNG_BYTE);
+
+	rk_rng_read_regs(rk_rng, CRYPTO_V1_TRNG_DOUT_0, buf, ret);
+
+out:
+	/* close TRNG */
+	rk_rng_writel(rk_rng, HIWORD_UPDATE(0, CRYPTO_V1_RNG_START, 0),
+		      CRYPTO_V1_CTRL);
+
+	pm_runtime_mark_last_busy(rk_rng->dev);
+	pm_runtime_put_sync_autosuspend(rk_rng->dev);
+
+	return ret;
+}
+
+static int rk_rng_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+	int ret = 0;
+	u32 reg_ctrl = 0;
+	struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
+
+	ret = pm_runtime_get_sync(rk_rng->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(rk_rng->dev);
+		return ret;
+	}
+
+	/* enable osc_ring to get entropy, sample period is set as 100 */
+	rk_rng_writel(rk_rng, 100, CRYPTO_V2_RNG_SAMPLE_CNT);
+
+	reg_ctrl |= CRYPTO_V2_RNG_256_BIT_LEN;
+	reg_ctrl |= CRYPTO_V2_RNG_SLOWER_SOC_RING_0;
+	reg_ctrl |= CRYPTO_V2_RNG_ENABLE;
+	reg_ctrl |= CRYPTO_V2_RNG_START;
+
+	rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0),
+			CRYPTO_V2_RNG_CTL);
+
+	ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V2_RNG_CTL, reg_ctrl,
+				 !(reg_ctrl & CRYPTO_V2_RNG_START),
+				 ROCKCHIP_POLL_PERIOD_US,
+				 ROCKCHIP_POLL_TIMEOUT_US);
+	if (ret < 0)
+		goto out;
+
+	ret = min_t(size_t, max, RK_MAX_RNG_BYTE);
+
+	rk_rng_read_regs(rk_rng, CRYPTO_V2_RNG_DOUT_0, buf, ret);
+
+out:
+	/* close TRNG */
+	rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), CRYPTO_V2_RNG_CTL);
+
+	pm_runtime_mark_last_busy(rk_rng->dev);
+	pm_runtime_put_sync_autosuspend(rk_rng->dev);
+
+	return ret;
+}
+
+static const struct rk_rng_soc_data rk_rng_v1_soc_data = {
+	.clks_num = ARRAY_SIZE(rk_rng_v1_clks),
+	.clks = rk_rng_v1_clks,
+	.rk_rng_read = rk_rng_v1_read,
+};
+
+static const struct rk_rng_soc_data rk_rng_v2_soc_data = {
+	.clks_num = ARRAY_SIZE(rk_rng_v2_clks),
+	.clks = rk_rng_v2_clks,
+	.rk_rng_read = rk_rng_v2_read,
+};
+
+static const struct of_device_id rk_rng_dt_match[] = {
+	{
+		.compatible = "rockchip,cryptov1-rng",
+		.data = (void *)&rk_rng_v1_soc_data,
+	},
+	{
+		.compatible = "rockchip,cryptov2-rng",
+		.data = (void *)&rk_rng_v2_soc_data,
+	},
+	{ },
+};
+
+MODULE_DEVICE_TABLE(of, rk_rng_dt_match);
+
+static int rk_rng_probe(struct platform_device *pdev)
+{
+	int i;
+	int ret;
+	struct rk_rng *rk_rng;
+	struct device_node *np = pdev->dev.of_node;
+	const struct of_device_id *match;
+
+	dev_dbg(&pdev->dev, "probing...\n");
+	rk_rng = devm_kzalloc(&pdev->dev, sizeof(struct rk_rng), GFP_KERNEL);
+	if (!rk_rng)
+		return -ENOMEM;
+
+	match = of_match_node(rk_rng_dt_match, np);
+	rk_rng->soc_data = (struct rk_rng_soc_data *)match->data;
+
+	rk_rng->dev = &pdev->dev;
+	rk_rng->rng.name    = "rockchip";
+#ifndef CONFIG_PM
+	rk_rng->rng.init    = rk_rng_init;
+	rk_rng->rng.cleanup = rk_rng_cleanup,
+#endif
+	rk_rng->rng.read    = rk_rng->soc_data->rk_rng_read;
+	rk_rng->rng.quality = 1000;
+
+	rk_rng->clk_bulks =
+		devm_kzalloc(&pdev->dev, sizeof(*rk_rng->clk_bulks) *
+			     rk_rng->soc_data->clks_num, GFP_KERNEL);
+
+	rk_rng->clk_num = rk_rng->soc_data->clks_num;
+
+	for (i = 0; i < rk_rng->soc_data->clks_num; i++)
+		rk_rng->clk_bulks[i].id = rk_rng->soc_data->clks[i];
+
+	rk_rng->mem = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
+	if (IS_ERR(rk_rng->mem))
+		return PTR_ERR(rk_rng->mem);
+
+	ret = devm_clk_bulk_get(&pdev->dev, rk_rng->clk_num,
+				rk_rng->clk_bulks);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to get clks property\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, rk_rng);
+
+	pm_runtime_set_autosuspend_delay(&pdev->dev,
+					ROCKCHIP_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	ret = devm_hwrng_register(&pdev->dev, &rk_rng->rng);
+	if (ret) {
+		pm_runtime_dont_use_autosuspend(&pdev->dev);
+		pm_runtime_disable(&pdev->dev);
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int rk_rng_runtime_suspend(struct device *dev)
+{
+	struct rk_rng *rk_rng = dev_get_drvdata(dev);
+
+	rk_rng_cleanup(&rk_rng->rng);
+
+	return 0;
+}
+
+static int rk_rng_runtime_resume(struct device *dev)
+{
+	struct rk_rng *rk_rng = dev_get_drvdata(dev);
+
+	return rk_rng_init(&rk_rng->rng);
+}
+
+static const struct dev_pm_ops rk_rng_pm_ops = {
+	SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend,
+				rk_rng_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
+#endif
+
+static struct platform_driver rk_rng_driver = {
+	.driver	= {
+		.name	= "rockchip-rng",
+#ifdef CONFIG_PM
+		.pm	= &rk_rng_pm_ops,
+#endif
+		.of_match_table = rk_rng_dt_match,
+	},
+	.probe	= rk_rng_probe,
+};
+
+module_platform_driver(rk_rng_driver);
+
+MODULE_DESCRIPTION("ROCKCHIP H/W Random Number Generator driver");
+MODULE_AUTHOR("Lin Jinhan <troy.lin@rock-chips.com>");
+MODULE_LICENSE("GPL v2");
+


================================================
FILE: not_use_file/0003-add_rockchip_k510_support.patch
================================================
From 6ecff10072972d26d4b63c007516d4b8cd0cb07d Thu Mar 4 5:25:25 2021
From: quintus-lab<noreply@github.com>
Date: Thu, 4 Mar 2021 17:25:25 +0800
Subject: [PATCH] add_rockchip_k5.10_support 	

Hardware
--------
RockChip RK3399 ARM64 (6 cores)
1GB DDR3 or 4GB LPDDR4 RAM
2x 1000 Base-T
3 LEDs (LAN / WAN / SYS)
1 Button (Reset)
Micro-SD slot
2x USB 3.0 Port

Installation
------------
Uncompress the OpenWrt sysupgrade and write it to a micro SD card using dd.

Signed-off-by: Tianling Shen <cnsztl@gmail.com>
Co-authored-by: Jensen Huang <jensenhuang@friendlyarm.com>
Signed-off-by: Jensen Huang <jensenhuang@friendlyarm.com>
Co-authored-by: Marty Jones <mj8263788@gmail.com>
Signed-off-by: Marty Jones <mj8263788@gmail.com>
--------
modified:   package/boot/uboot-rockchip/Makefile 	
new file:   package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch
new file:   package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch
new file:   package/boot/uboot-rockchip/patches/202-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
new file:   target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch
new file:   target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch
modified:   target/linux/rockchip/Makefile 	
modified:   target/linux/rockchip/armv8/base-files/etc/board.d/01_leds 	
modified:   target/linux/rockchip/armv8/base-files/etc/board.d/02_network 	
modified:   target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity 
modified:   target/linux/rockchip/armv8/config-5.10 	
modified:   target/linux/rockchip/image/armv8.mk 	
new file:   target/linux/rockchip/image/nanopi-r4s.bootscript 	
new file:   target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
new file:   target/linux/rockchip/patches-5.10/105-mmc-core-set-initial-signal-voltage-on-power-off.patch
new file:   target/linux/rockchip/patches-5.10/200-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
new file:   target/linux/rockchip/patches-5.10/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch
new file:   target/linux/rockchip/patches-5.10/801-char-add-support-for-rockchip-hardware-random-number.patch
new file:   target/linux/rockchip/patches-5.10/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch
new file:   target/linux/rockchip/patches-5.10/911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch
new file:   target/linux/rockchip/patches-5.10/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch
new file:   target/linux/rockchip/patches-5.10/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch

---
 package/boot/uboot-rockchip/Makefile          |  11 +
 ...split-nanopi-r4-rk3399-out-of-evb_rk.patch | 509 ++++++++++++++++++
 ...9-Add-support-for-multiple-DDR-types.patch | 256 +++++++++
 ...Add-support-for-FriendlyARM-NanoPi-R.patch | 313 +++++++++++
 ...el-name-in-proc-cpuinfo-for-64bit-ta.patch |  38 ++
 ...k-events-support-multiple-registrant.patch | 291 ++++++++++
 target/linux/rockchip/Makefile                |   2 +-
 .../armv8/base-files/etc/board.d/01_leds      |   3 +-
 .../armv8/base-files/etc/board.d/02_network   |  12 +-
 .../etc/hotplug.d/net/40-net-smp-affinity     |   4 +
 target/linux/rockchip/armv8/config-5.10       |   4 +
 target/linux/rockchip/image/armv8.mk          |  10 +
 .../rockchip/image/nanopi-r4s.bootscript      |   8 +
 ...add-compatible-to-NanoPi-R2S-etherne.patch |  25 +
 ...-initial-signal-voltage-on-power-off.patch |  35 ++
 ...Add-support-for-FriendlyARM-NanoPi-R.patch | 218 ++++++++
 ...8-add-i2c0-controller-for-nanopi-r2s.patch |  22 +
 ...-for-rockchip-hardware-random-number.patch |  45 ++
 ...ip-add-hardware-random-number-genera.patch |  50 ++
 ...adjust-default-coherent_pool-to-2MiB.patch |  28 +
 ...ip-add-more-cpu-operating-points-for.patch |  44 ++
 ...overclock-to-2.2-1.8-GHz-for-NanoPi4.patch | 186 +++++++
 22 files changed, 2107 insertions(+), 7 deletions(-)
 create mode 100644 package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch
 create mode 100644 package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch
 create mode 100644 package/boot/uboot-rockchip/patches/202-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
 create mode 100644 target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch
 create mode 100644 target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch
 create mode 100644 target/linux/rockchip/image/nanopi-r4s.bootscript
 create mode 100644 target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
 create mode 100644 target/linux/rockchip/patches-5.10/105-mmc-core-set-initial-signal-voltage-on-power-off.patch
 create mode 100644 target/linux/rockchip/patches-5.10/200-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
 create mode 100644 target/linux/rockchip/patches-5.10/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch
 create mode 100644 target/linux/rockchip/patches-5.10/801-char-add-support-for-rockchip-hardware-random-number.patch
 create mode 100644 target/linux/rockchip/patches-5.10/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch
 create mode 100644 target/linux/rockchip/patches-5.10/911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch
 create mode 100644 target/linux/rockchip/patches-5.10/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch
 create mode 100644 target/linux/rockchip/patches-5.10/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch

diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile
index 393e8c3a9f..6253679834 100644
--- a/package/boot/uboot-rockchip/Makefile
+++ b/package/boot/uboot-rockchip/Makefile
@@ -38,6 +38,16 @@ endef
 
 # RK3399 boards
 
+define U-Boot/nanopi-r4s-rk3399
+  BUILD_SUBTARGET:=armv8
+  NAME:=NanoPi R4S
+  BUILD_DEVICES:= \
+    friendlyarm_nanopi-r4s
+  DEPENDS:=+PACKAGE_u-boot-nanopi-r4s-rk3399:arm-trusted-firmware-rockchip
+  PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip
+  ATF:=rk3399_bl31.elf
+endef
+
 define U-Boot/rock-pi-4-rk3399
   BUILD_SUBTARGET:=armv8
   NAME:=Rock Pi 4
@@ -59,6 +69,7 @@ define U-Boot/rockpro64-rk3399
 endef
 
 UBOOT_TARGETS := \
+  nanopi-r4s-rk3399 \
   rock-pi-4-rk3399 \
   rockpro64-rk3399 \
   nanopi-r2s-rk3328
diff --git a/package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch b/package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch
new file mode 100644
index 0000000000..d8a118dd2e
--- /dev/null
+++ b/package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch
@@ -0,0 +1,509 @@
+From a765bb2678b6d1666caafef0fcf88fba88b5b26f Mon Sep 17 00:00:00 2001
+From: hmz007 <hmz007@gmail.com>
+Date: Fri, 18 Dec 2020 17:10:35 +0800
+Subject: [PATCH] rockchip: rk3399: split nanopi-r4-rk3399 out of evb_rk3399
+
+nanopi-r4-rk3399 board has multiple DDR types. Currently we don't have any code
+are compatible with these devices. Since multiple DDR types is specific to
+nanopi-r4-rk3399 board, split it into its own board file and add code
+support here.
+
+Signed-off-by: hmz007 <hmz007@gmail.com>
+[Improved commit message and Kconfig description]
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+ arch/arm/mach-rockchip/rk3399/Kconfig |  15 +++
+ board/friendlyarm/nanopi4/Kconfig     |  15 +++
+ board/friendlyarm/nanopi4/MAINTAINERS |   5 +
+ board/friendlyarm/nanopi4/Makefile    |   8 ++
+ board/friendlyarm/nanopi4/hwrev.c     | 185 ++++++++++++++++++++++++++
+ board/friendlyarm/nanopi4/hwrev.h     |  27 ++++
+ board/friendlyarm/nanopi4/nanopi4.c   | 148 +++++++++++++++++++++
+ drivers/clk/rockchip/clk_rk3399.c     |   2 +
+ include/configs/nanopi4.h             |  24 ++++
+ 9 files changed, 429 insertions(+)
+ create mode 100644 board/friendlyarm/nanopi4/Kconfig
+ create mode 100644 board/friendlyarm/nanopi4/MAINTAINERS
+ create mode 100644 board/friendlyarm/nanopi4/Makefile
+ create mode 100644 board/friendlyarm/nanopi4/hwrev.c
+ create mode 100644 board/friendlyarm/nanopi4/hwrev.h
+ create mode 100644 board/friendlyarm/nanopi4/nanopi4.c
+ create mode 100644 include/configs/nanopi4.h
+
+--- a/arch/arm/mach-rockchip/rk3399/Kconfig
++++ b/arch/arm/mach-rockchip/rk3399/Kconfig
+@@ -109,6 +109,20 @@ config TARGET_ROC_PC_RK3399
+ 	   * wide voltage input(5V-15V), dual cell battery
+ 	   * Wifi/BT accessible via expansion board M.2
+ 
++config TARGET_NANOPI4_RK3399
++	bool "FriendlyElec NanoPi4 board"
++	help
++	  NanoPi4 is SBC produced by FriendlyElec. Key features:
++
++	   * Rockchip RK3399
++	   * 1/2/4GB Dual-Channel DDR3/LPDDR4
++	   * SD card slot
++	   * Gigabit ethernet
++	   * PCIe
++	   * USB 3.0, 2.0
++	   * USB Type C power
++	   * GPIO expansion ports
++
+ endchoice
+ 
+ config ROCKCHIP_BOOT_MODE_REG
+@@ -152,6 +166,7 @@ config SYS_BOOTCOUNT_ADDR
+ endif # BOOTCOUNT_LIMIT
+ 
+ source "board/firefly/roc-pc-rk3399/Kconfig"
++source "board/friendlyarm/nanopi4/Kconfig"
+ source "board/google/gru/Kconfig"
+ source "board/pine64/pinebook-pro-rk3399/Kconfig"
+ source "board/pine64/rockpro64_rk3399/Kconfig"
+--- /dev/null
++++ b/board/friendlyarm/nanopi4/Kconfig
+@@ -0,0 +1,15 @@
++if TARGET_NANOPI4_RK3399
++
++config SYS_BOARD
++	default "nanopi4"
++
++config SYS_VENDOR
++	default "friendlyarm"
++
++config SYS_CONFIG_NAME
++	default "nanopi4"
++
++config BOARD_SPECIFIC_OPTIONS
++	def_bool y
++
++endif
+--- /dev/null
++++ b/board/friendlyarm/nanopi4/MAINTAINERS
+@@ -0,0 +1,5 @@
++NanoPi 4 Series
++M:      FriendlyElec <support@friendlyarm.com>
++S:      Maintained
++F:      board/friendlyarm/nanopi4/
++F:      include/configs/nanopi4.h
+--- /dev/null
++++ b/board/friendlyarm/nanopi4/Makefile
+@@ -0,0 +1,8 @@
++#
++# Copyright (C) Guangzhou FriendlyELEC Computer Tech. Co., Ltd.
++# (http://www.friendlyarm.com)
++#
++# SPDX-License-Identifier:     GPL-2.0+
++#
++
++obj-y	+= nanopi4.o hwrev.o
+--- /dev/null
++++ b/board/friendlyarm/nanopi4/hwrev.c
+@@ -0,0 +1,185 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright (c) 2020 FriendlyElec Computer Tech. Co., Ltd.
++ * (http://www.friendlyarm.com)
++ */
++
++#include <common.h>
++#include <dm.h>
++#include <linux/delay.h>
++#include <log.h>
++#include <asm/io.h>
++#include <asm/gpio.h>
++#include <asm/arch-rockchip/gpio.h>
++
++/*
++ * ID info:
++ *  ID : Volts : ADC value :   Bucket
++ *  ==   =====   =========   ===========
++ *   0 : 0.102V:        58 :    0 -   81
++ *   1 : 0.211V:       120 :   82 -  150
++ *   2 : 0.319V:       181 :  151 -  211
++ *   3 : 0.427V:       242 :  212 -  274
++ *   4 : 0.542V:       307 :  275 -  342
++ *   5 : 0.666V:       378 :  343 -  411
++ *   6 : 0.781V:       444 :  412 -  477
++ *   7 : 0.900V:       511 :  478 -  545
++ *   8 : 1.023V:       581 :  546 -  613
++ *   9 : 1.137V:       646 :  614 -  675
++ *  10 : 1.240V:       704 :  676 -  733
++ *  11 : 1.343V:       763 :  734 -  795
++ *  12 : 1.457V:       828 :  796 -  861
++ *  13 : 1.576V:       895 :  862 -  925
++ *  14 : 1.684V:       956 :  926 -  989
++ *  15 : 1.800V:      1023 :  990 - 1023
++ */
++static const int id_readings[] = {
++	 81, 150, 211, 274, 342, 411, 477, 545,
++	613, 675, 733, 795, 861, 925, 989, 1023
++};
++
++static int cached_board_id = -1;
++
++#define SARADC_BASE		0xFF100000
++#define SARADC_DATA		(SARADC_BASE + 0)
++#define SARADC_CTRL		(SARADC_BASE + 8)
++
++static u32 get_saradc_value(int chn)
++{
++	int timeout = 0;
++	u32 adc_value = 0;
++
++	writel(0, SARADC_CTRL);
++	udelay(2);
++
++	writel(0x28 | chn, SARADC_CTRL);
++	udelay(50);
++
++	timeout = 0;
++	do {
++		if (readl(SARADC_CTRL) & 0x40) {
++			adc_value = readl(SARADC_DATA) & 0x3FF;
++			goto stop_adc;
++		}
++
++		udelay(10);
++	} while (timeout++ < 100);
++
++stop_adc:
++	writel(0, SARADC_CTRL);
++
++	return adc_value;
++}
++
++static uint32_t get_adc_index(int chn)
++{
++	int i;
++	int adc_reading;
++
++	if (cached_board_id != -1)
++		return cached_board_id;
++
++	adc_reading = get_saradc_value(chn);
++	for (i = 0; i < ARRAY_SIZE(id_readings); i++) {
++		if (adc_reading <= id_readings[i]) {
++			debug("ADC reading %d, ID %d\n", adc_reading, i);
++			cached_board_id = i;
++			return i;
++		}
++	}
++
++	/* should die for impossible value */
++	return 0;
++}
++
++/*
++ * Board revision list: <GPIO4_D1 | GPIO4_D0>
++ *  0b00 - NanoPC-T4
++ *  0b01 - NanoPi M4
++ *
++ * Extended by ADC_IN4
++ * Group A:
++ *  0x04 - NanoPi NEO4
++ *  0x06 - SOC-RK3399
++ *  0x07 - SOC-RK3399 V2
++ *  0x09 - NanoPi R4S 1GB
++ *  0x0A - NanoPi R4S 4GB
++ *
++ * Group B:
++ *  0x21 - NanoPi M4 Ver2.0
++ *  0x22 - NanoPi M4B
++ */
++static int pcb_rev = -1;
++
++void bd_hwrev_init(void)
++{
++#define GPIO4_BASE	0xff790000
++	struct rockchip_gpio_regs *regs = (void *)GPIO4_BASE;
++
++#ifdef CONFIG_SPL_BUILD
++	struct udevice *dev;
++
++	if (uclass_get_device_by_driver(UCLASS_CLK,
++				DM_GET_DRIVER(clk_rk3399), &dev))
++		return;
++#endif
++
++	if (pcb_rev >= 0)
++		return;
++
++	/* D1, D0: input mode */
++	clrbits_le32(&regs->swport_ddr, (0x3 << 24));
++	pcb_rev = (readl(&regs->ext_port) >> 24) & 0x3;
++
++	if (pcb_rev == 0x3) {
++		/* Revision group A: 0x04 ~ 0x13 */
++		pcb_rev = 0x4 + get_adc_index(4);
++
++	} else if (pcb_rev == 0x1) {
++		int idx = get_adc_index(4);
++
++		/* Revision group B: 0x21 ~ 0x2f */
++		if (idx > 0) {
++			pcb_rev = 0x20 + idx;
++		}
++	}
++}
++
++#ifdef CONFIG_SPL_BUILD
++static struct board_ddrtype {
++	int rev;
++	const char *type;
++} ddrtypes[] = {
++	{ 0x00, "lpddr3-samsung-4GB-1866" },
++	{ 0x01, "lpddr3-samsung-4GB-1866" },
++	{ 0x04,   "ddr3-1866" },
++	{ 0x06,   "ddr3-1866" },
++	{ 0x07, "lpddr4-100"  },
++	{ 0x09,   "ddr3-1866" },
++	{ 0x0a, "lpddr4-100"  },
++	{ 0x21, "lpddr4-100"  },
++	{ 0x22,   "ddr3-1866" },
++};
++
++const char *rk3399_get_ddrtype(void) {
++	int i;
++
++	bd_hwrev_init();
++	printf("Board: rev%02x\n", pcb_rev);
++
++	for (i = 0; i < ARRAY_SIZE(ddrtypes); i++) {
++		if (ddrtypes[i].rev == pcb_rev)
++			return ddrtypes[i].type;
++	}
++
++	/* fallback to first subnode (ie, first included dtsi) */
++	return NULL;
++}
++#endif
++
++/* To override __weak symbols */
++u32 get_board_rev(void)
++{
++	return pcb_rev;
++}
++
+--- /dev/null
++++ b/board/friendlyarm/nanopi4/hwrev.h
+@@ -0,0 +1,27 @@
++/*
++ * Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd.
++ * (http://www.friendlyarm.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, you can access it online at
++ * http://www.gnu.org/licenses/gpl-2.0.html.
++ */
++
++#ifndef __BD_HW_REV_H__
++#define __BD_HW_REV_H__
++
++extern void bd_hwrev_config_gpio(void);
++extern void bd_hwrev_init(void);
++extern u32 get_board_rev(void);
++
++#endif /* __BD_HW_REV_H__ */
+--- /dev/null
++++ b/board/friendlyarm/nanopi4/nanopi4.c
+@@ -0,0 +1,148 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright (c) 2020 FriendlyElec Computer Tech. Co., Ltd.
++ * (http://www.friendlyarm.com)
++ */
++
++#include <common.h>
++#include <dm.h>
++#include <env.h>
++#include <hash.h>
++#include <linux/bitops.h>
++#include <i2c.h>
++#include <init.h>
++#include <net.h>
++#include <netdev.h>
++#include <syscon.h>
++#include <asm/arch-rockchip/bootrom.h>
++#include <asm/arch-rockchip/clock.h>
++#include <asm/arch-rockchip/grf_rk3399.h>
++#include <asm/arch-rockchip/hardware.h>
++#include <asm/arch-rockchip/misc.h>
++#include <asm/io.h>
++#include <asm/setup.h>
++#include <u-boot/sha256.h>
++
++#ifdef CONFIG_MISC_INIT_R
++static void setup_iodomain(void)
++{
++	struct rk3399_grf_regs *grf =
++	    syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
++
++	/* BT565 and AUDIO is in 1.8v domain */
++	rk_setreg(&grf->io_vsel, BIT(0) | BIT(1));
++}
++
++static int __maybe_unused mac_read_from_generic_eeprom(u8 *addr)
++{
++	struct udevice *i2c_dev;
++	int ret;
++
++	/* Microchip 24AA02xxx EEPROMs with EUI-48 Node Identity */
++	ret = i2c_get_chip_for_busnum(2, 0x51, 1, &i2c_dev);
++	if (!ret)
++		ret = dm_i2c_read(i2c_dev, 0xfa, addr, 6);
++
++	return ret;
++}
++
++static void setup_macaddr(void)
++{
++#if CONFIG_IS_ENABLED(CMD_NET)
++	int ret;
++	const char *cpuid = env_get("cpuid#");
++	u8 hash[SHA256_SUM_LEN];
++	int size = sizeof(hash);
++	u8 mac_addr[6];
++	int from_eeprom = 0;
++	int lockdown = 0;
++
++#ifndef CONFIG_ENV_IS_NOWHERE
++	lockdown = env_get_yesno("lockdown") == 1;
++#endif
++	if (lockdown && env_get("ethaddr"))
++		return;
++
++	ret = mac_read_from_generic_eeprom(mac_addr);
++	if (!ret && is_valid_ethaddr(mac_addr)) {
++		eth_env_set_enetaddr("ethaddr", mac_addr);
++		from_eeprom = 1;
++	}
++
++	if (!cpuid) {
++		debug("%s: could not retrieve 'cpuid#'\n", __func__);
++		return;
++	}
++
++	ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size);
++	if (ret) {
++		debug("%s: failed to calculate SHA256\n", __func__);
++		return;
++	}
++
++	/* Copy 6 bytes of the hash to base the MAC address on */
++	memcpy(mac_addr, hash, 6);
++
++	/* Make this a valid MAC address and set it */
++	mac_addr[0] &= 0xfe;  /* clear multicast bit */
++	mac_addr[0] |= 0x02;  /* set local assignment bit (IEEE802) */
++
++	if (from_eeprom) {
++		eth_env_set_enetaddr("eth1addr", mac_addr);
++	} else {
++		eth_env_set_enetaddr("ethaddr", mac_addr);
++
++		if (lockdown && env_get("eth1addr"))
++			return;
++
++		/* Ugly, copy another 4 bytes to generate a similar address */
++		memcpy(mac_addr + 2, hash + 8, 4);
++		if (!memcmp(hash + 2, hash + 8, 4))
++			mac_addr[5] ^= 0xff;
++
++		eth_env_set_enetaddr("eth1addr", mac_addr);
++	}
++#endif
++
++	return;
++}
++
++int misc_init_r(void)
++{
++	const u32 cpuid_offset = 0x7;
++	const u32 cpuid_length = 0x10;
++	u8 cpuid[cpuid_length];
++	int ret;
++
++	setup_iodomain();
++
++	ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
++	if (ret)
++		return ret;
++
++	ret = rockchip_cpuid_set(cpuid, cpuid_length);
++	if (ret)
++		return ret;
++
++	setup_macaddr();
++	bd_hwrev_init();
++
++	return 0;
++}
++#endif
++
++#ifdef CONFIG_SERIAL_TAG
++void get_board_serial(struct tag_serialnr *serialnr)
++{
++	char *serial_string;
++	u64 serial = 0;
++
++	serial_string = env_get("serial#");
++
++	if (serial_string)
++		serial = simple_strtoull(serial_string, NULL, 16);
++
++	serialnr->high = (u32)(serial >> 32);
++	serialnr->low = (u32)(serial & 0xffffffff);
++}
++#endif
+diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
+index 22c373a623..38975c0c65 100644
+--- a/drivers/clk/rockchip/clk_rk3399.c
++++ b/drivers/clk/rockchip/clk_rk3399.c
+@@ -1351,6 +1351,8 @@ static void rkclk_init(struct rockchip_cru *cru)
+ 		     pclk_div << PCLK_PERILP1_DIV_CON_SHIFT |
+ 		     hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
+ 		     HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
++
++	rk3399_saradc_set_clk(cru, 1000000);
+ }
+ #endif
+ 
+--- /dev/null
++++ b/include/configs/nanopi4.h
+@@ -0,0 +1,24 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/*
++ * Copyright (C) Guangzhou FriendlyELEC Computer Tech. Co., Ltd.
++ * (http://www.friendlyarm.com)
++ *
++ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
++ */
++
++#ifndef __CONFIG_NANOPI4_H__
++#define __CONFIG_NANOPI4_H__
++
++#define ROCKCHIP_DEVICE_SETTINGS \
++		"stdin=serial,usbkbd\0" \
++		"stdout=serial,vidconsole\0" \
++		"stderr=serial,vidconsole\0"
++
++#include <configs/rk3399_common.h>
++
++#define SDRAM_BANK_SIZE			(2UL << 30)
++
++#define CONFIG_SERIAL_TAG
++#define CONFIG_REVISION_TAG
++
++#endif
diff --git a/package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch b/package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch
new file mode 100644
index 0000000000..b624bcc763
--- /dev/null
+++ b/package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch
@@ -0,0 +1,256 @@
+From a9447b7b60a3c5195d0fabbe5aa9c32d047ec997 Mon Sep 17 00:00:00 2001
+From: hmz007 <hmz007@gmail.com>
+Date: Sat, 19 Dec 2020 19:39:14 +0800
+Subject: [PATCH] ram: rk3399: Add support for multiple DDR types
+
+Move rockchip,sdram-params to named subnode to include
+multiple sdram parameters, and then read the parameters
+(by subnode name, first subnode or current node) before
+rk3399_dmc_init().
+
+Signed-off-by: hmz007 <hmz007@gmail.com>
+---
+ arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi      |  6 ++-
+ arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi      |  5 +-
+ arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi      |  6 ++-
+ .../arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi |  3 ++
+ .../arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi |  3 ++
+ .../rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi |  3 ++
+ arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi     |  3 ++
+ drivers/ram/rockchip/sdram_rk3399.c           | 49 +++++++++++++++----
+ 8 files changed, 64 insertions(+), 14 deletions(-)
+
+--- a/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
++++ b/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
+@@ -4,7 +4,9 @@
+  */
+ 
+ &dmc {
+-        rockchip,sdram-params = <
++	ddr3-1333 {
++	u-boot,dm-pre-reloc;
++	rockchip,sdram-params = <
+ 		0x1
+ 		0xa
+ 		0x3
+@@ -1536,5 +1538,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+-
+--- a/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
++++ b/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
+@@ -4,7 +4,9 @@
+  */
+ 
+ &dmc {
+-        rockchip,sdram-params = <
++	ddr3-1600 {
++	u-boot,dm-pre-reloc;
++	rockchip,sdram-params = <
+ 		0x1
+ 		0xa
+ 		0x3
+@@ -1536,4 +1538,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+--- a/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
++++ b/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
+@@ -4,7 +4,9 @@
+  */
+ 
+ &dmc {
+-        rockchip,sdram-params = <
++	ddr3-1866 {
++	u-boot,dm-pre-reloc;
++	rockchip,sdram-params = <
+ 		0x1
+ 		0xa
+ 		0x3
+@@ -1536,5 +1538,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+-
+--- a/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
++++ b/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
+@@ -5,6 +5,8 @@
+  */
+ 
+ &dmc {
++	lpddr3-2GB-1600 {
++	u-boot,dm-pre-reloc;
+ 	rockchip,sdram-params = <
+ 		0x1
+ 		0xa
+@@ -1537,4 +1539,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+--- a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
++++ b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
+@@ -4,6 +4,8 @@
+  */
+ 
+ &dmc {
++	lpddr3-4GB-1600 {
++	u-boot,dm-pre-reloc;
+ 	rockchip,sdram-params = <
+ 		0x2
+ 		0xa
+@@ -1536,4 +1538,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+--- a/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
++++ b/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
+@@ -4,6 +4,8 @@
+  */
+ 
+ &dmc {
++	lpddr3-samsung-4GB-1866 {
++	u-boot,dm-pre-reloc;
+ 	rockchip,sdram-params = <
+ 		0x2
+ 		0xa
+@@ -1543,4 +1545,5 @@
+ 		0x01010000	/* DENALI_PHY_957_DATA */
+ 		0x00000000	/* DENALI_PHY_958_DATA */
+ 	>;
++	};
+ };
+--- a/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
++++ b/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
+@@ -6,6 +6,8 @@
+  */
+ 
+ &dmc {
++	lpddr4-100 {
++	u-boot,dm-pre-reloc;
+ 	rockchip,sdram-params = <
+ 		0x2
+ 		0xa
+@@ -1538,4 +1540,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+--- a/drivers/ram/rockchip/sdram_rk3399.c
++++ b/drivers/ram/rockchip/sdram_rk3399.c
+@@ -1625,7 +1625,6 @@ static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
+ 	rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
+ }
+ 
+-#if !defined(CONFIG_RAM_RK3399_LPDDR4)
+ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
+ 			       struct rk3399_sdram_params *params)
+ {
+@@ -1715,8 +1714,8 @@ void modify_param(const struct chan_info *chan,
+ 	clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
+ 	clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
+ }
+-#else
+ 
++#if defined(CONFIG_RAM_RK3399_LPDDR4)
+ struct rk3399_sdram_params dfs_cfgs_lpddr4[] = {
+ #include "sdram-rk3399-lpddr4-400.inc"
+ #include "sdram-rk3399-lpddr4-800.inc"
+@@ -3011,20 +3010,40 @@ static int sdram_init(struct dram_info *dram,
+ 	return 0;
+ }
+ 
++__weak const char *rk3399_get_ddrtype(void)
++{
++	return NULL;
++}
++
+ static int rk3399_dmc_ofdata_to_platdata(struct udevice *dev)
+ {
+ #if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ 	struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
++	ofnode node = { .np = NULL };
++	const char *name;
+ 	int ret;
+ 
+-	ret = dev_read_u32_array(dev, "rockchip,sdram-params",
+-				 (u32 *)&plat->sdram_params,
+-				 sizeof(plat->sdram_params) / sizeof(u32));
++	name = rk3399_get_ddrtype();
++	if (name)
++		node = dev_read_subnode(dev, name);
++	if (!ofnode_valid(node)) {
++		debug("Failed to read subnode %s\n", name);
++		node = dev_read_first_subnode(dev);
++	}
++
++	/* fallback to current node */
++	if (!ofnode_valid(node))
++		node = dev_ofnode(dev);
++
++	ret = ofnode_read_u32_array(node, "rockchip,sdram-params",
++				    (u32 *)&plat->sdram_params,
++				    sizeof(plat->sdram_params) / sizeof(u32));
+ 	if (ret) {
+ 		printf("%s: Cannot read rockchip,sdram-params %d\n",
+ 		       __func__, ret);
+ 		return ret;
+ 	}
++
+ 	ret = regmap_init_mem(dev_ofnode(dev), &plat->map);
+ 	if (ret)
+ 		printf("%s: regmap failed %d\n", __func__, ret);
+@@ -3051,18 +3070,20 @@ static int conv_of_platdata(struct udevice *dev)
+ #endif
+ 
+ static const struct sdram_rk3399_ops rk3399_ops = {
+-#if !defined(CONFIG_RAM_RK3399_LPDDR4)
+ 	.data_training_first = data_training_first,
+ 	.set_rate_index = switch_to_phy_index1,
+ 	.modify_param = modify_param,
+ 	.get_phy_index_params = get_phy_index_params,
+-#else
++};
++
++#if defined(CONFIG_RAM_RK3399_LPDDR4)
++static const struct sdram_rk3399_ops lpddr4_ops = {
+ 	.data_training_first = lpddr4_mr_detect,
+ 	.set_rate_index = lpddr4_set_rate,
+ 	.modify_param = lpddr4_modify_param,
+ 	.get_phy_index_params = lpddr4_get_phy_index_params,
+-#endif
+ };
++#endif
+ 
+ static int rk3399_dmc_init(struct udevice *dev)
+ {
+@@ -3081,7 +3102,17 @@ static int rk3399_dmc_init(struct udevice *dev)
+ 		return ret;
+ #endif
+ 
+-	priv->ops = &rk3399_ops;
++	if (params->base.dramtype == LPDDR4) {
++#if defined(CONFIG_RAM_RK3399_LPDDR4)
++		priv->ops = &lpddr4_ops;
++#else
++		printf("LPDDR4 support is disable\n");
++		return -EINVAL;
++#endif
++	} else {
++		priv->ops = &rk3399_ops;
++	}
++
+ 	priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
+ 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ 	priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
diff --git a/package/boot/uboot-rockchip/patches/202-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch b/package/boot/uboot-rockchip/patches/202-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
new file mode 100644
index 0000000000..74c7c3f4a5
--- /dev/null
+++ b/package/boot/uboot-rockchip/patches/202-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
@@ -0,0 +1,313 @@
+From 8dc76bbce30c3f63f290f008f8410c00fee13c9a Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Fri, 8 Jan 2021 05:55:50 +0000
+Subject: [PATCH] rockchip: rk3399: Add support for FriendlyARM NanoPi R4S
+
+This adds support for the NanoPi R4S from FriendlyArm.
+
+Rockchip RK3399 SoC
+1GB DDR3 or 4GB LPDDR4 RAM
+Gigabit Ethernet (WAN)
+Gigabit Ethernet (PCIe) (LAN)
+USB 3.0 Host Port x 2
+MicroSD slot
+Reset button
+WAN - LAN - SYS LED
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+Co-authored-by: Jensen Huang <jensenhuang@friendlyarm.com>
+Signed-off-by: Jensen Huang <jensenhuang@friendlyarm.com>
+Co-authored-by: Marty Jones <mj8263788@gmail.com>
+Signed-off-by: Marty Jones <mj8263788@gmail.com>
+---
+ arch/arm/dts/Makefile                      |   1 +
+ arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi |   9 ++
+ arch/arm/dts/rk3399-nanopi-r4s.dts         | 178 +++++++++++++++++++++
+ board/friendlyarm/nanopi4/MAINTAINERS      |   6 +
+ configs/nanopi-r4s-rk3399_defconfig        |  63 ++++++++
+ 5 files changed, 257 insertions(+)
+ create mode 100644 arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
+ create mode 100644 arch/arm/dts/rk3399-nanopi-r4s.dts
+ create mode 100644 configs/nanopi-r4s-rk3399_defconfig
+
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -132,6 +132,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \
+ 	rk3399-nanopi-m4.dtb \
+ 	rk3399-nanopi-m4-2gb.dtb \
+ 	rk3399-nanopi-neo4.dtb \
++	rk3399-nanopi-r4s.dtb \
+ 	rk3399-orangepi.dtb \
+ 	rk3399-pinebook-pro.dtb \
+ 	rk3399-puma-haikou.dtb \
+--- /dev/null
++++ b/arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
+@@ -0,0 +1,9 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * (C) Copyright 2020 Jensen Huang <jensenhuang@friendlyarm.com>
++ */
++
++#include "rk3399-nanopi4-u-boot.dtsi"
++#include "rk3399-sdram-lpddr4-100.dtsi"
++#include "rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi"
++#include "rk3399-sdram-ddr3-1866.dtsi"
+--- /dev/null
++++ b/arch/arm/dts/rk3399-nanopi-r4s.dts
+@@ -0,0 +1,178 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2020 Jensen Huang <jensenhuang@friendlyarm.com>
++ * Copyright (c) 2020 Marty Jones <mj8263788@gmail.com>
++ * Copyright (c) 2020 Tianling Shen <cnsztl@gmail.com>
++ */
++
++/dts-v1/;
++#include "rk3399-nanopi4.dtsi"
++
++/ {
++	model = "FriendlyElec NanoPi R4S";
++	compatible = "friendlyarm,nanopi-r4s", "rockchip,rk3399";
++
++	aliases {
++		led-boot = &sys_led;
++		led-failsafe = &sys_led;
++		led-running = &sys_led;
++		led-upgrade = &sys_led;
++	};
++
++	/delete-node/ gpio-leds;
++	gpio-leds {
++		compatible = "gpio-leds";
++		pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>;
++		pinctrl-names = "default";
++
++		lan_led: led-0 {
++			gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>;
++			label = "nanopi-r4s:green:lan";
++		};
++
++		sys_led: led-1 {
++			gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
++			label = "nanopi-r4s:red:sys";
++		};
++
++		wan_led: led-2 {
++			gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
++			label = "nanopi-r4s:green:wan";
++		};
++	};
++
++	/delete-node/ gpio-keys;
++	gpio-keys {
++		compatible = "gpio-keys";
++		pinctrl-names = "default";
++		pinctrl-0 = <&reset_button_pin>;
++
++		reset {
++			debounce-interval = <50>;
++			gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_LOW>;
++			label = "reset";
++			linux,code = <KEY_RESTART>;
++		};
++	};
++
++	vdd_5v: vdd-5v {
++		compatible = "regulator-fixed";
++		regulator-name = "vdd_5v";
++		regulator-always-on;
++		regulator-boot-on;
++	};
++
++	fan: pwm-fan {
++		compatible = "pwm-fan";
++		/*
++		 * With 20KHz PWM and an EVERCOOL EC4007H12SA fan, these levels
++		 * work out to 0, ~1200, ~3000, and 5000RPM respectively.
++		 */
++		cooling-levels = <0 12 18 255>;
++		#cooling-cells = <2>;
++		fan-supply = <&vdd_5v>;
++		pwms = <&pwm1 0 50000 0>;
++	};
++};
++
++&cpu_thermal {
++	trips {
++		cpu_warm: cpu_warm {
++			temperature = <55000>;
++			hysteresis = <2000>;
++			type = "active";
++		};
++
++		cpu_hot: cpu_hot {
++			temperature = <65000>;
++			hysteresis = <2000>;
++			type = "active";
++		};
++	};
++
++	cooling-maps {
++		map2 {
++			trip = <&cpu_warm>;
++			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
++		};
++
++		map3 {
++			trip = <&cpu_hot>;
++			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
++		};
++	};
++};
++
++&emmc_phy {
++	status = "disabled";
++};
++
++&fusb0 {
++	status = "disabled";
++};
++
++&pcie0 {
++	max-link-speed = <1>;
++	num-lanes = <1>;
++	vpcie3v3-supply = <&vcc3v3_sys>;
++
++	pcie@0 {
++		reg = <0x00000000 0 0 0 0>;
++		#address-cells = <3>;
++		#size-cells = <2>;
++	};
++};
++
++&pinctrl {
++	/delete-node/ gpio-leds;
++	gpio-leds {
++		lan_led_pin: lan-led-pin {
++			rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
++		};
++
++		sys_led_pin: sys-led-pin {
++			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
++		};
++
++		wan_led_pin: wan-led-pin {
++			rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
++		};
++	};
++
++	/delete-node/ rockchip-key;
++	rockchip-key {
++		reset_button_pin: reset-button-pin {
++			rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>;
++		};
++	};
++};
++
++&sdhci {
++	status = "disabled";
++};
++
++&sdio0 {
++	status = "disabled";
++};
++
++&sdmmc {
++	sd-uhs-sdr12;
++	sd-uhs-sdr25;
++	sd-uhs-sdr50;
++};
++
++&u2phy0_host {
++	phy-supply = <&vdd_5v>;
++};
++
++&u2phy1_host {
++	status = "disabled";
++};
++
++&usbdrd_dwc3_0 {
++	dr_mode = "host";
++};
++
++&vcc3v3_sys {
++	vin-supply = <&vcc5v0_sys>;
++};
+--- a/board/friendlyarm/nanopi4/MAINTAINERS
++++ b/board/friendlyarm/nanopi4/MAINTAINERS
+@@ -3,3 +3,9 @@ M:      FriendlyElec <support@friendlyarm.com>
+ S:      Maintained
+ F:      board/friendlyarm/nanopi4/
+ F:      include/configs/nanopi4.h
++
++NANOPI-R4S
++M:      Tianling Shen <cnsztl@gmail.com>
++S:      Maintained
++F:      configs/nanopi-r4s-rk3399_defconfig
++F:      arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
+--- /dev/null
++++ b/configs/nanopi-r4s-rk3399_defconfig
+@@ -0,0 +1,63 @@
++CONFIG_ARM=y
++CONFIG_ARCH_ROCKCHIP=y
++CONFIG_SYS_TEXT_BASE=0x00200000
++CONFIG_NR_DRAM_BANKS=1
++CONFIG_ENV_OFFSET=0x3F8000
++CONFIG_ROCKCHIP_RK3399=y
++CONFIG_TARGET_NANOPI4_RK3399=y
++CONFIG_DEBUG_UART_BASE=0xFF1A0000
++CONFIG_DEBUG_UART_CLOCK=24000000
++CONFIG_DEFAULT_DEVICE_TREE="rk3399-nanopi-r4s"
++CONFIG_DEBUG_UART=y
++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-nanopi-r4s.dtb"
++CONFIG_MISC_INIT_R=y
++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
++CONFIG_SPL_STACK_R=y
++CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
++CONFIG_TPL=y
++CONFIG_CMD_BOOTZ=y
++CONFIG_CMD_GPT=y
++CONFIG_CMD_MMC=y
++CONFIG_CMD_USB=y
++# CONFIG_CMD_SETEXPR is not set
++CONFIG_CMD_TIME=y
++CONFIG_SPL_OF_CONTROL=y
++CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
++CONFIG_ENV_IS_IN_MMC=y
++CONFIG_SYS_RELOC_GD_ENV_ADDR=y
++CONFIG_SYS_MMC_ENV_DEV=1
++CONFIG_ROCKCHIP_GPIO=y
++CONFIG_SYS_I2C_ROCKCHIP=y
++CONFIG_MMC_DW=y
++CONFIG_MMC_DW_ROCKCHIP=y
++CONFIG_MMC_SDHCI=y
++CONFIG_MMC_SDHCI_ROCKCHIP=y
++CONFIG_DM_ETH=y
++CONFIG_ETH_DESIGNWARE=y
++CONFIG_GMAC_ROCKCHIP=y
++CONFIG_PMIC_RK8XX=y
++CONFIG_REGULATOR_PWM=y
++CONFIG_REGULATOR_RK8XX=y
++CONFIG_PWM_ROCKCHIP=y
++CONFIG_RAM_RK3399_LPDDR4=y
++CONFIG_BAUDRATE=1500000
++CONFIG_DEBUG_UART_SHIFT=2
++CONFIG_SYSRESET=y
++CONFIG_USB=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_XHCI_DWC3=y
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_GENERIC=y
++CONFIG_USB_KEYBOARD=y
++CONFIG_USB_HOST_ETHER=y
++CONFIG_USB_ETHER_ASIX=y
++CONFIG_USB_ETHER_ASIX88179=y
++CONFIG_USB_ETHER_MCS7830=y
++CONFIG_USB_ETHER_RTL8152=y
++CONFIG_USB_ETHER_SMSC95XX=y
++CONFIG_DM_VIDEO=y
++CONFIG_DISPLAY=y
++CONFIG_VIDEO_ROCKCHIP=y
++CONFIG_DISPLAY_ROCKCHIP_HDMI=y
++CONFIG_SPL_TINY_MEMSET=y
++CONFIG_ERRNO_STR=y
diff --git a/target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch b/target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch
new file mode 100644
index 0000000000..70cfadca9c
--- /dev/null
+++ b/target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch
@@ -0,0 +1,38 @@
+From: Sumit Gupta <sumitg@nvidia.com>
+To: <catalin.marinas@arm.com>, <linux-arm-kernel@lists.infradead.org>,
+	<linux-kernel@vger.kernel.org>
+Cc: <will.deacon@arm.com>, <suzuki.poulose@arm.com>,
+	<james.morse@arm.com>, <mark.rutland@arm.com>,
+	<yang.shi@linaro.org>, <julien.grall@arm.com>,
+	<steve.capper@linaro.org>, <bbasu@nvidia.com>,
+	<linux-tegra@vger.kernel.org>, Sumit Gupta <sumitg@nvidia.com>
+Subject: [PATCH] arm64: cpuinfo: Add "model name" in /proc/cpuinfo for 64bit tasks also
+Date: Mon, 29 Aug 2016 14:32:25 +0530
+Message-ID: <1472461345-28219-1-git-send-email-sumitg@nvidia.com> (raw)
+
+Removed restriction of displaying model name for 32 bit tasks only.
+Because of this Processor details were not displayed in
+"System setting -> Details" in Ubuntu model name display is generic
+and can be printed for 64 bit also.
+
+model name : ARMv8 Processor rev X (v8l)
+
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+---
+ arch/arm64/kernel/cpuinfo.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/arm64/kernel/cpuinfo.c
++++ b/arch/arm64/kernel/cpuinfo.c
+@@ -148,9 +148,8 @@ static int c_show(struct seq_file *m, vo
+ 		 * "processor".  Give glibc what it expects.
+ 		 */
+ 		seq_printf(m, "processor\t: %d\n", i);
+-		if (compat)
+-			seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
+-				   MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
++		seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
++			   MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
+ 
+ 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+ 			   loops_per_jiffy / (500000UL/HZ),
diff --git a/target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch b/target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch
new file mode 100644
index 0000000000..2981c3d906
--- /dev/null
+++ b/target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch
@@ -0,0 +1,291 @@
+--- a/include/net/netfilter/nf_conntrack_ecache.h
++++ b/include/net/netfilter/nf_conntrack_ecache.h
+@@ -72,6 +72,10 @@ struct nf_ct_event {
+ 	int report;
+ };
+ 
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
++extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
++#else
+ struct nf_ct_event_notifier {
+ 	int (*fcn)(unsigned int events, struct nf_ct_event *item);
+ };
+@@ -80,6 +84,7 @@ int nf_conntrack_register_notifier(struc
+ 				   struct nf_ct_event_notifier *nb);
+ void nf_conntrack_unregister_notifier(struct net *net,
+ 				      struct nf_ct_event_notifier *nb);
++#endif
+ 
+ void nf_ct_deliver_cached_events(struct nf_conn *ct);
+ int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
+@@ -105,11 +110,13 @@ static inline void
+ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
+ {
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
+-	struct net *net = nf_ct_net(ct);
+ 	struct nf_conntrack_ecache *e;
++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++	struct net *net = nf_ct_net(ct);
+ 
+ 	if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
+ 		return;
++#endif
+ 
+ 	e = nf_ct_ecache_find(ct);
+ 	if (e == NULL)
+@@ -124,10 +131,12 @@ nf_conntrack_event_report(enum ip_conntr
+ 			  u32 portid, int report)
+ {
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
+ 	const struct net *net = nf_ct_net(ct);
+ 
+ 	if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
+ 		return 0;
++#endif
+ 
+ 	return nf_conntrack_eventmask_report(1 << event, ct, portid, report);
+ #else
+@@ -139,10 +148,12 @@ static inline int
+ nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
+ {
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
+ 	const struct net *net = nf_ct_net(ct);
+ 
+ 	if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
+ 		return 0;
++#endif
+ 
+ 	return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
+ #else
+--- a/include/net/netns/conntrack.h
++++ b/include/net/netns/conntrack.h
+@@ -112,7 +112,11 @@ struct netns_ct {
+ 
+ 	struct ct_pcpu __percpu *pcpu_lists;
+ 	struct ip_conntrack_stat __percpu *stat;
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++	struct atomic_notifier_head nf_conntrack_chain;
++#else
+ 	struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
++#endif
+ 	struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
+ 	struct nf_ip_net	nf_ct_proto;
+ #if defined(CONFIG_NF_CONNTRACK_LABELS)
+--- a/net/netfilter/Kconfig
++++ b/net/netfilter/Kconfig
+@@ -136,6 +136,14 @@ config NF_CONNTRACK_EVENTS
+ 
+ 	  If unsure, say `N'.
+ 
++config NF_CONNTRACK_CHAIN_EVENTS
++	bool "Register multiple callbacks to ct events"
++	depends on NF_CONNTRACK_EVENTS
++	help
++	  Support multiple registrations.
++
++	  If unsure, say `N'.
++
+ config NF_CONNTRACK_TIMEOUT
+ 	bool  'Connection tracking timeout'
+ 	depends on NETFILTER_ADVANCED
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -2748,6 +2748,9 @@ int nf_conntrack_init_net(struct net *ne
+ 	nf_conntrack_helper_pernet_init(net);
+ 	nf_conntrack_proto_pernet_init(net);
+ 
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++	ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain);
++#endif
+ 	return 0;
+ 
+ err_expect:
+--- a/net/netfilter/nf_conntrack_ecache.c
++++ b/net/netfilter/nf_conntrack_ecache.c
+@@ -17,6 +17,9 @@
+ #include <linux/stddef.h>
+ #include <linux/err.h>
+ #include <linux/percpu.h>
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++#include <linux/notifier.h>
++#endif
+ #include <linux/kernel.h>
+ #include <linux/netdevice.h>
+ #include <linux/slab.h>
+@@ -129,7 +132,35 @@ static void ecache_work(struct work_stru
+ 	if (delay >= 0)
+ 		schedule_delayed_work(&ctnet->ecache_dwork, delay);
+ }
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
++				  u32 portid, int report)
++{
++	struct nf_conntrack_ecache *e;
++	struct net *net = nf_ct_net(ct);
++
++	e = nf_ct_ecache_find(ct);
++	if (e == NULL)
++		return 0;
++
++	if (nf_ct_is_confirmed(ct)) {
++		struct nf_ct_event item = {
++			.ct = ct,
++			.portid	= e->portid ? e->portid : portid,
++			.report = report
++		};
++		/* This is a resent of a destroy event? If so, skip missed */
++		unsigned long missed = e->portid ? 0 : e->missed;
++
++		if (!((eventmask | missed) & e->ctmask))
++			return 0;
+ 
++		atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item);
++	}
++
++	return 0;
++}
++#else
+ int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
+ 				  u32 portid, int report)
+ {
+@@ -184,10 +215,52 @@ out_unlock:
+ 	rcu_read_unlock();
+ 	return ret;
+ }
++#endif
+ EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report);
+ 
+ /* deliver cached events and clear cache entry - must be called with locally
+  * disabled softirqs */
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++void nf_ct_deliver_cached_events(struct nf_conn *ct)
++{
++	unsigned long events, missed;
++	struct nf_conntrack_ecache *e;
++	struct nf_ct_event item;
++	struct net *net = nf_ct_net(ct);
++
++	e = nf_ct_ecache_find(ct);
++	if (e == NULL)
++		return;
++
++	events = xchg(&e->cache, 0);
++
++	if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events)
++		return;
++
++	/* We make a copy of the missed event cache without taking
++	 * the lock, thus we may send missed events twice. However,
++	 * this does not harm and it happens very rarely. */
++	missed = e->missed;
++
++	if (!((events | missed) & e->ctmask))
++		return;
++
++	item.ct = ct;
++	item.portid = 0;
++	item.report = 0;
++
++	atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
++			events | missed,
++			&item);
++
++	if (likely(!missed))
++		return;
++
++	spin_lock_bh(&ct->lock);
++		e->missed &= ~missed;
++	spin_unlock_bh(&ct->lock);
++}
++#else
+ void nf_ct_deliver_cached_events(struct nf_conn *ct)
+ {
+ 	struct net *net = nf_ct_net(ct);
+@@ -238,6 +311,7 @@ void nf_ct_deliver_cached_events(struct
+ out_unlock:
+ 	rcu_read_unlock();
+ }
++#endif
+ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
+ 
+ void nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
+@@ -270,6 +344,13 @@ out_unlock:
+ 	rcu_read_unlock();
+ }
+ 
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++int nf_conntrack_register_notifier(struct net *net,
++				   struct notifier_block *nb)
++{
++        return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
++}
++#else
+ int nf_conntrack_register_notifier(struct net *net,
+ 				   struct nf_ct_event_notifier *new)
+ {
+@@ -290,8 +371,15 @@ out_unlock:
+ 	mutex_unlock(&nf_ct_ecache_mutex);
+ 	return ret;
+ }
++#endif
+ EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
+ 
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
++{
++	return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
++}
++#else
+ void nf_conntrack_unregister_notifier(struct net *net,
+ 				      struct nf_ct_event_notifier *new)
+ {
+@@ -305,6 +393,7 @@ void nf_conntrack_unregister_notifier(st
+ 	mutex_unlock(&nf_ct_ecache_mutex);
+ 	/* synchronize_rcu() is called from ctnetlink_exit. */
+ }
++#endif
+ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
+ 
+ int nf_ct_expect_register_notifier(struct net *net,
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -703,13 +703,20 @@ static size_t ctnetlink_nlmsg_size(const
+ }
+ 
+ static int
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++ctnetlink_conntrack_event(struct notifier_block *this, unsigned long events, void *ptr)
++#else
+ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
++#endif
+ {
+ 	const struct nf_conntrack_zone *zone;
+ 	struct net *net;
+ 	struct nlmsghdr *nlh;
+ 	struct nfgenmsg *nfmsg;
+ 	struct nlattr *nest_parms;
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++	struct nf_ct_event *item = (struct nf_ct_event *)ptr;
++#endif
+ 	struct nf_conn *ct = item->ct;
+ 	struct sk_buff *skb;
+ 	unsigned int type;
+@@ -3783,9 +3790,15 @@ static int ctnetlink_stat_exp_cpu(struct
+ }
+ 
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++static struct notifier_block ctnl_notifier = {
++	.notifier_call = ctnetlink_conntrack_event,
++};
++#else
+ static struct nf_ct_event_notifier ctnl_notifier = {
+ 	.fcn = ctnetlink_conntrack_event,
+ };
++#endif
+ 
+ static struct nf_exp_event_notifier ctnl_notifier_exp = {
+ 	.fcn = ctnetlink_expect_event,
diff --git a/target/linux/rockchip/Makefile b/target/linux/rockchip/Makefile
index 7aeb0a3d55..f7b6995911 100644
--- a/target/linux/rockchip/Makefile
+++ b/target/linux/rockchip/Makefile
@@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
 
 BOARD:=rockchip
 BOARDNAME:=Rockchip
-FEATURES:=ext4 audio usb usbgadget display gpio fpu rootfs-part boot-part squashfs
+FEATURES:=ext4 audio usb usbgadget display gpio fpu pci pcie rootfs-part boot-part squashfs
 SUBTARGETS:=armv8
 
 KERNEL_PATCHVER=5.4
diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
index bba3e2aa56..77655d426a 100755
--- a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
+++ b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
@@ -9,7 +9,8 @@ boardname="${board##*,}"
 board_config_update
 
 case $board in
-friendlyarm,nanopi-r2s)
+friendlyarm,nanopi-r2s|\
+friendlyarm,nanopi-r4s)
 	ucidef_set_led_netdev "wan" "WAN" "$boardname:green:wan" "eth0"
 	ucidef_set_led_netdev "lan" "LAN" "$boardname:green:lan" "eth1"
 	;;
diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
index 48133c81a1..d8acaabe27 100755
--- a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
+++ b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
@@ -8,7 +8,8 @@ rockchip_setup_interfaces()
 	local board="$1"
 
 	case "$board" in
-	friendlyarm,nanopi-r2s)
+	friendlyarm,nanopi-r2s|\
+	friendlyarm,nanopi-r4s)
 		ucidef_set_interfaces_lan_wan 'eth1' 'eth0'
 		;;
 	*)
@@ -17,9 +18,9 @@ rockchip_setup_interfaces()
 	esac
 }
 
-nanopi_r2s_generate_mac()
+nanopi_generate_mac()
 {
-	local sd_hash=$(sha256sum /sys/devices/platform/ff500000.dwmmc/mmc_host/mmc0/mmc0:*/cid)
+	local sd_hash=$(sha256sum /sys/devices/platform/*.dwmmc/mmc_host/mmc0/mmc0:*/cid)
 	local mac_base=$(macaddr_canonicalize "$(echo "${sd_hash}" | dd bs=1 count=12 2>/dev/null)")
 	echo "$(macaddr_unsetbit_mc "$(macaddr_setbit_la "${mac_base}")")"
 }
@@ -32,8 +33,9 @@ rockchip_setup_macs()
 	local label_mac=""
 
 	case "$board" in
-	friendlyarm,nanopi-r2s)
-		wan_mac=$(nanopi_r2s_generate_mac)
+	friendlyarm,nanopi-r2s|\
+	friendlyarm,nanopi-r4s)
+		wan_mac=$(nanopi_generate_mac)
 		lan_mac=$(macaddr_add "$wan_mac" +1)
 		;;
 	esac
diff --git a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
index 44716258bf..9e4a4cf4fc 100644
--- a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
+++ b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
@@ -26,5 +26,9 @@ friendlyarm,nanopi-r2s)
 	set_interface_core 2 "eth0"
 	set_interface_core 4 "eth1" "xhci-hcd:usb3"
 	;;
+friendlyarm,nanopi-r4s)
+	set_interface_core 10 "eth0"
+	set_interface_core 20 "eth1"
+	;;
 esac
 
diff --git a/target/linux/rockchip/armv8/config-5.10 b/target/linux/rockchip/armv8/config-5.10
index eaef238c92..c29c76a345 100644
--- a/target/linux/rockchip/armv8/config-5.10
+++ b/target/linux/rockchip/armv8/config-5.10
@@ -162,6 +162,10 @@ CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_CRC32=y
 CONFIG_CRYPTO_CRC32C=y
 CONFIG_CRYPTO_CRCT10DIF=y
+# CONFIG_CRYPTO_DEV_ROCKCHIP is not set
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_MANAGER=y
diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk
index 24b1c38137..23a29ccaac 100644
--- a/target/linux/rockchip/image/armv8.mk
+++ b/target/linux/rockchip/image/armv8.mk
@@ -12,6 +12,16 @@ define Device/friendlyarm_nanopi-r2s
 endef
 TARGET_DEVICES += friendlyarm_nanopi-r2s
 
+define Device/friendlyarm_nanopi-r4s
+  DEVICE_VENDOR := FriendlyARM
+  DEVICE_MODEL := NanoPi R4S
+  SOC := rk3399
+  UBOOT_DEVICE_NAME := nanopi-r4s-rk3399
+  IMAGE/sysupgrade.img.gz := boot-common | boot-script nanopi-r4s | pine64-img | gzip | append-metadata
+  DEVICE_PACKAGES := kmod-r8169 -urngd
+endef
+TARGET_DEVICES += friendlyarm_nanopi-r4s
+
 define Device/pine64_rockpro64
   DEVICE_VENDOR := Pine64
   DEVICE_MODEL := RockPro64
diff --git a/target/linux/rockchip/image/nanopi-r4s.bootscript b/target/linux/rockchip/image/nanopi-r4s.bootscript
new file mode 100644
index 0000000000..abe9c24ee3
--- /dev/null
+++ b/target/linux/rockchip/image/nanopi-r4s.bootscript
@@ -0,0 +1,8 @@
+part uuid mmc ${devnum}:2 uuid
+
+setenv bootargs "console=ttyS2,1500000 earlycon=uart8250,mmio32,0xff1a0000 root=PARTUUID=${uuid} rw rootwait"
+
+load mmc ${devnum}:1 ${fdt_addr_r} rockchip.dtb
+load mmc ${devnum}:1 ${kernel_addr_r} kernel.img
+
+booti ${kernel_addr_r} - ${fdt_addr_r}
diff --git a/target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch b/target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
new file mode 100644
index 0000000000..897a42fea2
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
@@ -0,0 +1,25 @@
+From bc6c96d850419e71dbc9b0094ccc9b668ba9be43 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+Date: Mon, 28 Sep 2020 22:54:52 +0200
+Subject: [PATCH] rockchip: rk3328: add compatible to NanoPi R2S ethernet PHY
+
+This adds the compatible property to the NanoPi R2S ethernet PHY node.
+Otherwise, the PHY might not be probed, as the PHY ID reads all 0xff
+when it is still in reset.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+---
+ arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
+@@ -134,6 +134,8 @@
+ 		#size-cells = <0>;
+ 
+ 		rtl8211e: ethernet-phy@1 {
++			compatible = "ethernet-phy-id001c.c915",
++				     "ethernet-phy-ieee802.3-c22";
+ 			reg = <1>;
+ 			pinctrl-0 = <&eth_phy_reset_pin>;
+ 			pinctrl-names = "default";
diff --git a/target/linux/rockchip/patches-5.10/105-mmc-core-set-initial-signal-voltage-on-power-off.patch b/target/linux/rockchip/patches-5.10/105-mmc-core-set-initial-signal-voltage-on-power-off.patch
new file mode 100644
index 0000000000..2a0f8d9bd0
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/105-mmc-core-set-initial-signal-voltage-on-power-off.patch
@@ -0,0 +1,35 @@
+From 0d329112c709d6cfedf0fffb19f0cc6b19043f6b Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Wed, 20 Feb 2019 07:38:34 +0000
+Subject: [PATCH] mmc: core: set initial signal voltage on power off
+
+Some boards have SD card connectors where the power rail cannot be switched
+off by the driver. If the card has not been power cycled, it may still be
+using 1.8V signaling after a warm re-boot. Bootroms expecting 3.3V signaling
+will fail to boot from a UHS card that continue to use 1.8V signaling.
+
+Set initial signal voltage in mmc_power_off() to allow re-boot to function.
+
+This fixes re-boot with UHS cards on Asus Tinker Board (Rockchip RK3288),
+same issue have been seen on some Rockchip RK3399 boards.
+
+I am sending this as a RFC because I have no insights into SD/MMC subsystem,
+this change fix a re-boot issue on my boards and does not break emmc/sdio.
+Is this an acceptable workaround? Any advice is appreciated.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+---
+ drivers/mmc/core/core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -1351,6 +1351,8 @@ void mmc_power_off(struct mmc_host *host
+ 
+ 	mmc_pwrseq_power_off(host);
+ 
++	mmc_set_initial_signal_voltage(host);
++
+ 	host->ios.clock = 0;
+ 	host->ios.vdd = 0;
+ 
diff --git a/target/linux/rockchip/patches-5.10/200-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch b/target/linux/rockchip/patches-5.10/200-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
new file mode 100644
index 0000000000..69c880db9f
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/200-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
@@ -0,0 +1,218 @@
+From 11c2b38cf0a04b0edb3eabae24fb1484489725e2 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Fri, 8 Jan 2021 07:12:30 +0000
+Subject: [PATCH] rockchip: rk3399: Add support for FriendlyARM NanoPi R4S
+
+This adds support for the NanoPi R4S from FriendlyArm.
+
+Rockchip RK3399 SoC
+1GB DDR3 or 4GB LPDDR4 RAM
+Gigabit Ethernet (WAN)
+Gigabit Ethernet (PCIe) (LAN)
+USB 3.0 Host Port x 2
+MicroSD slot
+Reset button
+WAN - LAN - SYS LED
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+Co-authored-by: Jensen Huang <jensenhuang@friendlyarm.com>
+Signed-off-by: Jensen Huang <jensenhuang@friendlyarm.com>
+Co-authored-by: Marty Jones <mj8263788@gmail.com>
+Signed-off-by: Marty Jones <mj8263788@gmail.com>
+---
+ arch/arm64/boot/dts/rockchip/Makefile         |   1 +
+ .../boot/dts/rockchip/rk3399-nanopi-r4s.dts   | 178 ++++++++++++++++++
+ 2 files changed, 179 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -30,6 +30,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-le
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopc-t4.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-m4.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-neo4.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-r4s.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-orangepi.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-pinebook-pro.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
+@@ -0,0 +1,178 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2020 Jensen Huang <jensenhuang@friendlyarm.com>
++ * Copyright (c) 2020 Marty Jones <mj8263788@gmail.com>
++ * Copyright (c) 2020 Tianling Shen <cnsztl@gmail.com>
++ */
++
++/dts-v1/;
++#include "rk3399-nanopi4.dtsi"
++
++/ {
++	model = "FriendlyElec NanoPi R4S";
++	compatible = "friendlyarm,nanopi-r4s", "rockchip,rk3399";
++
++	aliases {
++		led-boot = &sys_led;
++		led-failsafe = &sys_led;
++		led-running = &sys_led;
++		led-upgrade = &sys_led;
++	};
++
++	/delete-node/ gpio-leds;
++	gpio-leds {
++		compatible = "gpio-leds";
++		pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>;
++		pinctrl-names = "default";
++
++		lan_led: led-0 {
++			gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>;
++			label = "nanopi-r4s:green:lan";
++		};
++
++		sys_led: led-1 {
++			gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
++			label = "nanopi-r4s:red:sys";
++		};
++
++		wan_led: led-2 {
++			gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
++			label = "nanopi-r4s:green:wan";
++		};
++	};
++
++	/delete-node/ gpio-keys;
++	gpio-keys {
++		compatible = "gpio-keys";
++		pinctrl-names = "default";
++		pinctrl-0 = <&reset_button_pin>;
++
++		reset {
++			debounce-interval = <50>;
++			gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_LOW>;
++			label = "reset";
++			linux,code = <KEY_RESTART>;
++		};
++	};
++
++	vdd_5v: vdd-5v {
++		compatible = "regulator-fixed";
++		regulator-name = "vdd_5v";
++		regulator-always-on;
++		regulator-boot-on;
++	};
++
++	fan: pwm-fan {
++		compatible = "pwm-fan";
++		/*
++		 * With 20KHz PWM and an EVERCOOL EC4007H12SA fan, these levels
++		 * work out to 0, ~1200, ~3000, and 5000RPM respectively.
++		 */
++		cooling-levels = <0 12 18 255>;
++		#cooling-cells = <2>;
++		fan-supply = <&vdd_5v>;
++		pwms = <&pwm1 0 50000 0>;
++	};
++};
++
++&cpu_thermal {
++	trips {
++		cpu_warm: cpu_warm {
++			temperature = <55000>;
++			hysteresis = <2000>;
++			type = "active";
++		};
++
++		cpu_hot: cpu_hot {
++			temperature = <65000>;
++			hysteresis = <2000>;
++			type = "active";
++		};
++	};
++
++	cooling-maps {
++		map2 {
++			trip = <&cpu_warm>;
++			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
++		};
++
++		map3 {
++			trip = <&cpu_hot>;
++			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
++		};
++	};
++};
++
++&emmc_phy {
++	status = "disabled";
++};
++
++&fusb0 {
++	status = "disabled";
++};
++
++&pcie0 {
++	max-link-speed = <1>;
++	num-lanes = <1>;
++	vpcie3v3-supply = <&vcc3v3_sys>;
++
++	pcie@0 {
++		reg = <0x00000000 0 0 0 0>;
++		#address-cells = <3>;
++		#size-cells = <2>;
++	};
++};
++
++&pinctrl {
++	/delete-node/ gpio-leds;
++	gpio-leds {
++		lan_led_pin: lan-led-pin {
++			rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
++		};
++
++		sys_led_pin: sys-led-pin {
++			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
++		};
++
++		wan_led_pin: wan-led-pin {
++			rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
++		};
++	};
++
++	/delete-node/ rockchip-key;
++	rockchip-key {
++		reset_button_pin: reset-button-pin {
++			rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>;
++		};
++	};
++};
++
++&sdhci {
++	status = "disabled";
++};
++
++&sdio0 {
++	status = "disabled";
++};
++
++&sdmmc {
++	sd-uhs-sdr12;
++	sd-uhs-sdr25;
++	sd-uhs-sdr50;
++};
++
++&u2phy0_host {
++	phy-supply = <&vdd_5v>;
++};
++
++&u2phy1_host {
++	status = "disabled";
++};
++
++&usbdrd_dwc3_0 {
++	dr_mode = "host";
++};
++
++&vcc3v3_sys {
++	vin-supply = <&vcc5v0_sys>;
++};
diff --git a/target/linux/rockchip/patches-5.10/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch b/target/linux/rockchip/patches-5.10/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch
new file mode 100644
index 0000000000..28798047fd
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch
@@ -0,0 +1,22 @@
+From 3b7eb946b1d640d684a921e53e1e50985ab7eb89 Mon Sep 17 00:00:00 2001
+From: QiuSimons <45143996+QiuSimons@users.noreply.github.com>
+Date: Tue, 4 Aug 2020 20:17:53 +0800
+Subject: [PATCH] rockchip: rk3328: add i2c0 controller for nanopi r2s
+
+---
+ arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 4 ++++
+ 1 files changed, 4 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
+@@ -165,6 +165,10 @@
+ 	};
+ };
+ 
++&i2c0 {
++	status = "okay";
++};
++
+ &i2c1 {
+ 	status = "okay";
+ 
diff --git a/target/linux/rockchip/patches-5.10/801-char-add-support-for-rockchip-hardware-random-number.patch b/target/linux/rockchip/patches-5.10/801-char-add-support-for-rockchip-hardware-random-number.patch
new file mode 100644
index 0000000000..16ca6279e7
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/801-char-add-support-for-rockchip-hardware-random-number.patch
@@ -0,0 +1,45 @@
+From e5b5361651940ff5c0c1784dfd0130abec7ab535 Mon Sep 17 00:00:00 2001
+From: wevsty <ty@wevs.org>
+Date: Mon, 24 Aug 2020 02:27:11 +0800
+Subject: [PATCH] char: add support for rockchip hardware random number
+ generator
+
+This patch provides hardware random number generator support for all rockchip SOC.
+
+rockchip-rng.c from  https://github.com/rockchip-linux/kernel/blob/develop-4.4/drivers/char/hw_random/rockchip-rng.c
+
+Signed-off-by: wevsty <ty@wevs.org>
+---
+
+--- a/drivers/char/hw_random/Kconfig
++++ b/drivers/char/hw_random/Kconfig
+@@ -398,6 +398,19 @@ config HW_RANDOM_STM32
+ 
+ 	  If unsure, say N.
+ 
++config HW_RANDOM_ROCKCHIP
++	tristate "Rockchip Random Number Generator support"
++	depends on ARCH_ROCKCHIP
++	default HW_RANDOM
++	help
++	  This driver provides kernel-side support for the Random Number
++	  Generator hardware found on Rockchip cpus.
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called rockchip-rng.
++
++	  If unsure, say Y.
++
+ config HW_RANDOM_PIC32
+ 	tristate "Microchip PIC32 Random Number Generator support"
+ 	depends on HW_RANDOM && MACH_PIC32
+--- a/drivers/char/hw_random/Makefile
++++ b/drivers/char/hw_random/Makefile
+@@ -36,6 +36,7 @@ obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) +=
+ obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o
+ obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o
+ obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o
++obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o
+ obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o
+ obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o
+ obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o
diff --git a/target/linux/rockchip/patches-5.10/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch b/target/linux/rockchip/patches-5.10/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch
new file mode 100644
index 0000000000..1de560e33f
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch
@@ -0,0 +1,50 @@
+From e5b5361651940ff5c0c1784dfd0130abec7ab535 Mon Sep 17 00:00:00 2001
+From: wevsty <ty@wevs.org>
+Date: Mon, 24 Aug 2020 02:27:11 +0800
+Subject: [PATCH] arm64: dts: rockchip: add hardware random number generator
+ for RK3328 and RK3399
+
+Adding Hardware Random Number Generator Resources to the RK3328 and RK3399.
+
+Signed-off-by: wevsty <ty@wevs.org>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+@@ -297,6 +297,17 @@
+ 		status = "disabled";
+ 	};
+ 
++	rng: rng@ff060000 {
++		compatible = "rockchip,cryptov1-rng";
++		reg = <0x0 0xff060000 0x0 0x4000>;
++
++		clocks = <&cru SCLK_CRYPTO>, <&cru HCLK_CRYPTO_SLV>;
++		clock-names = "clk_crypto", "hclk_crypto";
++		assigned-clocks = <&cru SCLK_CRYPTO>, <&cru HCLK_CRYPTO_SLV>;
++		assigned-clock-rates = <150000000>, <100000000>;
++		status = "disabled";
++	};
++
+ 	grf: syscon@ff100000 {
+ 		compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd";
+ 		reg = <0x0 0xff100000 0x0 0x1000>;
+--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+@@ -1906,6 +1906,16 @@
+ 		};
+ 	};
+ 
++	rng: rng@ff8b8000 {
++		compatible = "rockchip,cryptov1-rng";
++		reg = <0x0 0xff8b8000 0x0 0x1000>;
++		clocks = <&cru SCLK_CRYPTO1>, <&cru HCLK_S_CRYPTO1>;
++		clock-names = "clk_crypto", "hclk_crypto";
++		assigned-clocks = <&cru SCLK_CRYPTO1>, <&cru HCLK_S_CRYPTO1>;
++		assigned-clock-rates = <150000000>, <100000000>;
++		status = "okay";
++	};
++
+ 	gpu: gpu@ff9a0000 {
+ 		compatible = "rockchip,rk3399-mali", "arm,mali-t860";
+ 		reg = <0x0 0xff9a0000 0x0 0x10000>;
diff --git a/target/linux/rockchip/patches-5.10/911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch b/target/linux/rockchip/patches-5.10/911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch
new file mode 100644
index 0000000000..f589ce2a7b
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch
@@ -0,0 +1,28 @@
+From 16bdf3e76fec6ddb44f1fcf221139fb39d225031 Mon Sep 17 00:00:00 2001
+From: Igor Pecovnik <igor.pecovnik@gmail.com>
+Date: Sat, 2 Jan 2021 05:23:55 +0000
+Subject: [PATCH] kernel: dma: adjust default coherent_pool to 2MiB
+
+---
+ kernel/dma/pool.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/kernel/dma/pool.c
++++ b/kernel/dma/pool.c
+@@ -192,13 +192,11 @@ static int __init dma_atomic_pool_init(v
+ 	int ret = 0;
+ 
+ 	/*
+-	 * If coherent_pool was not used on the command line, default the pool
+-	 * sizes to 128KB per 1GB of memory, min 128KB, max MAX_ORDER-1.
++	 * Always use 2MiB as default pool size.
++	 * See: https://forum.armbian.com/topic/4811-uas-mainline-kernel-coherent-pool-memory-size/
+ 	 */
+ 	if (!atomic_pool_size) {
+-		unsigned long pages = totalram_pages() / (SZ_1G / SZ_128K);
+-		pages = min_t(unsigned long, pages, MAX_ORDER_NR_PAGES);
+-		atomic_pool_size = max_t(size_t, pages << PAGE_SHIFT, SZ_128K);
++		atomic_pool_size = SZ_2M;
+ 	}
+ 	INIT_WORK(&atomic_pool_work, atomic_pool_work_fn);
+ 
diff --git a/target/linux/rockchip/patches-5.10/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch b/target/linux/rockchip/patches-5.10/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch
new file mode 100644
index 0000000000..c85da5fb07
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch
@@ -0,0 +1,44 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Leonidas P. Papadakos <papadakospan@gmail.com>
+Date: Fri, 1 Mar 2019 21:55:53 +0200
+Subject: [PATCH v2] arm64: dts: rockchip: add more cpu operating points for
+ RK3328
+
+This allows for greater max frequency on rk3328 boards,
+increasing performance.
+
+It has been included in Armbian (a linux distibution for ARM boards)
+for a while now without any reported issues
+
+https://github.com/armbian/build/blob/master/patch/kernel/rockchip64-default/enable-1392mhz-opp.patch
+https://github.com/armbian/build/blob/master/patch/kernel/rockchip64-default/enable-1512mhz-opp.patch
+
+Signed-off-by: Leonidas P. Papadakos <papadakospan@gmail.com>
+---
+ arch/arm64/boot/dts/rockchip/rk3328.dtsi | 15 +++++++++++++++
+ 1 files changed, 15 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+@@ -140,6 +140,21 @@
+ 			opp-microvolt = <1300000>;
+ 			clock-latency-ns = <40000>;
+ 		};
++		opp-1392000000 {
++			opp-hz = /bits/ 64 <1392000000>;
++			opp-microvolt = <1350000>;
++			clock-latency-ns = <40000>;
++		};
++		opp-1512000000 {
++			opp-hz = /bits/ 64 <1512000000>;
++			opp-microvolt = <1400000>;
++			clock-latency-ns = <40000>;
++		};
++		opp-1608000000 {
++			opp-hz = /bits/ 64 <1608000000>;
++			opp-microvolt = <1450000>;
++			clock-latency-ns = <40000>;
++		};
+ 	};
+ 
+ 	amba: bus {
diff --git a/target/linux/rockchip/patches-5.10/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch b/target/linux/rockchip/patches-5.10/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch
new file mode 100644
index 0000000000..9d393c5771
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch
@@ -0,0 +1,186 @@
+From 04202df5cb497b1934c95211cf43784ef62245a4 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Sat, 19 Dec 2020 12:42:27 +0000
+Subject: [PATCH] rockchip: rk3399: overclock to 2.2/1.8 GHz for NanoPi4 devices
+
+It's stable enough to overclock cpu frequency to 2.2/1.8 GHz,
+and for better performance.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+Co-authored-by: gzelvis <gzelvis@gmail.com>
+---
+ .../boot/dts/rockchip/rk3399-nanopi4-opp.dtsi | 156 ++++++++++++++++++
+ .../boot/dts/rockchip/rk3399-nanopi4.dtsi     |   2 +-
+ 2 files changed, 157 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-nanopi4-opp.dtsi
+
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-opp.dtsi
+@@ -0,0 +1,156 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2016-2017 Fuzhou Rockchip Electronics Co., Ltd
++ *
++ * Copyright (c) 2020 Tianling Shen <cnsztl@gmail.com>
++ * Copyright (c) 2020 gzelvis <gzelvis@gmail.com>
++ */
++
++/ {
++	cluster0_opp: opp-table0 {
++		compatible = "operating-points-v2";
++		opp-shared;
++
++		opp00 {
++			opp-hz = /bits/ 64 <408000000>;
++			opp-microvolt = <800000>;
++			clock-latency-ns = <40000>;
++		};
++		opp01 {
++			opp-hz = /bits/ 64 <600000000>;
++			opp-microvolt = <800000>;
++		};
++		opp02 {
++			opp-hz = /bits/ 64 <816000000>;
++			opp-microvolt = <850000>;
++		};
++		opp03 {
++			opp-hz = /bits/ 64 <1008000000>;
++			opp-microvolt = <925000>;
++		};
++		opp04 {
++			opp-hz = /bits/ 64 <1200000000>;
++			opp-microvolt = <1000000>;
++		};
++		opp05 {
++			opp-hz = /bits/ 64 <1416000000>;
++			opp-microvolt = <1150000>;
++		};
++		opp06 {
++			opp-hz = /bits/ 64 <1512000000>;
++			opp-microvolt = <1200000>;
++		};
++ 		opp07 {
++			opp-hz = /bits/ 64 <1608000000>;
++			opp-microvolt = <1250000>;
++		};
++		opp08 {
++			opp-hz = /bits/ 64 <1800000000>;
++			opp-microvolt = <1300000>;
++		};
++	};
++
++	cluster1_opp: opp-table1 {
++		compatible = "operating-points-v2";
++		opp-shared;
++
++		opp00 {
++			opp-hz = /bits/ 64 <408000000>;
++			opp-microvolt = <800000>;
++			clock-latency-ns = <40000>;
++		};
++		opp01 {
++			opp-hz = /bits/ 64 <600000000>;
++			opp-microvolt = <800000>;
++		};
++		opp02 {
++			opp-hz = /bits/ 64 <816000000>;
++			opp-microvolt = <825000>;
++		};
++		opp03 {
++			opp-hz = /bits/ 64 <1008000000>;
++			opp-microvolt = <875000>;
++		};
++		opp04 {
++			opp-hz = /bits/ 64 <1200000000>;
++			opp-microvolt = <950000>;
++		};
++		opp05 {
++			opp-hz = /bits/ 64 <1416000000>;
++			opp-microvolt = <1025000>;
++		};
++		opp06 {
++			opp-hz = /bits/ 64 <1608000000>;
++			opp-microvolt = <1100000>;
++		};
++		opp07 {
++			opp-hz = /bits/ 64 <1800000000>;
++			opp-microvolt = <1250000>;
++		};
++		opp08 {
++			opp-hz = /bits/ 64 <2016000000>;
++			opp-microvolt = <1350000>;
++		};
++		opp09 {
++			opp-hz = /bits/ 64 <2208000000>;
++			opp-microvolt = <1400000>;
++		};
++	};
++
++	gpu_opp_table: opp-table2 {
++		compatible = "operating-points-v2";
++
++		opp00 {
++			opp-hz = /bits/ 64 <200000000>;
++			opp-microvolt = <800000>;
++		};
++		opp01 {
++			opp-hz = /bits/ 64 <297000000>;
++			opp-microvolt = <800000>;
++		};
++		opp02 {
++			opp-hz = /bits/ 64 <400000000>;
++			opp-microvolt = <825000>;
++		};
++		opp03 {
++			opp-hz = /bits/ 64 <500000000>;
++			opp-microvolt = <875000>;
++		};
++		opp04 {
++			opp-hz = /bits/ 64 <600000000>;
++			opp-microvolt = <925000>;
++		};
++		opp05 {
++			opp-hz = /bits/ 64 <800000000>;
++			opp-microvolt = <1100000>;
++		};
++	};
++};
++
++&cpu_l0 {
++	operating-points-v2 = <&cluster0_opp>;
++};
++
++&cpu_l1 {
++	operating-points-v2 = <&cluster0_opp>;
++};
++
++&cpu_l2 {
++	operating-points-v2 = <&cluster0_opp>;
++};
++
++&cpu_l3 {
++	operating-points-v2 = <&cluster0_opp>;
++};
++
++&cpu_b0 {
++	operating-points-v2 = <&cluster1_opp>;
++};
++
++&cpu_b1 {
++	operating-points-v2 = <&cluster1_opp>;
++};
++
++&gpu {
++	operating-points-v2 = <&gpu_opp_table>;
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
+@@ -14,7 +14,7 @@
+ /dts-v1/;
+ #include <dt-bindings/input/linux-event-codes.h>
+ #include "rk3399.dtsi"
+-#include "rk3399-opp.dtsi"
++#include "rk3399-nanopi4-opp.dtsi"
+ 
+ / {
+ 	chosen {
-- 
2.25.1



================================================
FILE: not_use_file/0003-new_rk33xx_support_with_ARMv8_CE_k5.10.patch
================================================
From b569c89c51e21a9c4bc753e466e19aebde2b7b8b Mon Sep 17 00:00:00 2001
From: quintus-lab<noreply@github.com>
Date: Wed, 28 Apr 2021 02:59:14 +0800
Subject: [PATCH] new_rk33xx_support_with_ARMv8_CE_k5.10

 This introduces rockchip ddrloader firmware, which allows users to control the memory frequency
 runtime. This introduces rockchip ddrloader firmware, which allows users to control the memory frequency runtime.
 Signed-off-by: AmadeusGhost <amadeus@immortalwrt.org>
 Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>

 R4S support from:
 Signed-off-by: Tianling Shen <cnsztl@gmail.com>
 Co-authored-by: Jensen Huang <jensenhuang@friendlyarm.com>
 Signed-off-by: Jensen Huang <jensenhuang@friendlyarm.com>
 Co-authored-by: Marty Jones <mj8263788@gmail.com>
 Signed-off-by: Marty Jones <mj8263788@gmail.com>

 	new file:   package/boot/arm-trusted-firmware-rk3328/Makefile
 	new file:   package/boot/arm-trusted-firmware-rk3328/src/trust.ini 	
 	modified:   package/boot/uboot-rockchip/Makefile 	
 	new file:   package/boot/uboot-rockchip/patches/102-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
 	new file:   package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch
 	new file:   package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch
 	new file:   package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Kconfig 	
 	new file:   package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/MAINTAINERS
 	new file:   package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Makefile 	
 	new file:   package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.c  
 	new file:   package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.h
 	new file:   package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/nanopi4.c 	
 	new file:   package/boot/uboot-rockchip/src/include/configs/nanopi4.h 	
 	new file:   target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch
 	new file:   target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch
 	modified:   target/linux/rockchip/Makefile 	
 	modified:   target/linux/rockchip/armv8/base-files/etc/board.d/01_leds 	
 	modified:   target/linux/rockchip/armv8/base-files/etc/board.d/02_network 	
 	modified:   target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity  
 	modified:   target/linux/rockchip/armv8/config-5.10 	
 	new file:   target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-dram-nanopi2-timing.dtsi
 	new file:   target/linux/rockchip/files/drivers/devfreq/rk3328_dmc.c 
 	new file:   target/linux/rockchip/files/include/dt-bindings/clock/rockchip-ddr.h 	
 	new file:   target/linux/rockchip/files/include/dt-bindings/memory/rk3328-dram.h 
 	modified:   target/linux/rockchip/image/Makefile 	
 	modified:   target/linux/rockchip/image/armv8.mk 	
 	new file:   target/linux/rockchip/image/nanopi-r4s.bootscript 	
 	new file:   target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
 	new file:   target/linux/rockchip/patches-5.10/105-mmc-core-set-initial-signal-voltage-on-power-off.patch
 	new file:   target/linux/rockchip/patches-5.10/200-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
 	new file:   target/linux/rockchip/patches-5.10/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch
 	new file:   target/linux/rockchip/patches-5.10/801-char-add-support-for-rockchip-hardware-random-number.patch
 	new file:   target/linux/rockchip/patches-5.10/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch
 	new file:   target/linux/rockchip/patches-5.10/803-PM-devfreq-rockchip-add-devfreq-driver-for-rk3328-dmc.patch
 	new file:   target/linux/rockchip/patches-5.10/804-clk-rockchip-support-setting-ddr-clock-via-SIP-Version-2-.patch
 	new file:   target/linux/rockchip/patches-5.10/805-PM-devfreq-rockchip-dfi-add-more-soc-support.patch
 	new file:   target/linux/rockchip/patches-5.10/806-arm64-dts-rockchip-rk3328-add-dfi-node.patch
 	new file:   target/linux/rockchip/patches-5.10/807-arm64-dts-nanopi-r2s-add-rk3328-dmc-relate-node.patch
 	new file:   target/linux/rockchip/patches-5.10/911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch
 	new file:   target/linux/rockchip/patches-5.10/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch
 	new file:   target/linux/rockchip/patches-5.10/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch
---
 .../boot/arm-trusted-firmware-rk3328/Makefile |  55 ++
 .../arm-trusted-firmware-rk3328/src/trust.ini |  15 +
 package/boot/uboot-rockchip/Makefile          |  25 +-
 ...Add-support-for-FriendlyARM-NanoPi-R.patch | 257 ++++++
 ...split-nanopi-r4-rk3399-out-of-evb_rk.patch |  74 ++
 ...9-Add-support-for-multiple-DDR-types.patch | 256 ++++++
 .../src/board/friendlyarm/nanopi4/Kconfig     |  15 +
 .../src/board/friendlyarm/nanopi4/MAINTAINERS |   5 +
 .../src/board/friendlyarm/nanopi4/Makefile    |   8 +
 .../src/board/friendlyarm/nanopi4/hwrev.c     | 185 ++++
 .../src/board/friendlyarm/nanopi4/hwrev.h     |  27 +
 .../src/board/friendlyarm/nanopi4/nanopi4.c   | 148 +++
 .../src/include/configs/nanopi4.h             |  24 +
 ...el-name-in-proc-cpuinfo-for-64bit-ta.patch |  38 +
 ...k-events-support-multiple-registrant.patch | 291 ++++++
 target/linux/rockchip/Makefile                |   2 +-
 .../armv8/base-files/etc/board.d/01_leds      |   4 +
 .../armv8/base-files/etc/board.d/02_network   |   7 +-
 .../etc/hotplug.d/net/40-net-smp-affinity     |   4 +
 target/linux/rockchip/armv8/config-5.10       |  50 +
 .../rockchip/rk3328-dram-nanopi2-timing.dtsi  | 311 +++++++
 .../files/drivers/devfreq/rk3328_dmc.c        | 852 ++++++++++++++++++
 .../include/dt-bindings/clock/rockchip-ddr.h  |  63 ++
 .../include/dt-bindings/memory/rk3328-dram.h  | 159 ++++
 target/linux/rockchip/image/Makefile          |  20 +
 target/linux/rockchip/image/armv8.mk          |  12 +-
 .../rockchip/image/nanopi-r4s.bootscript      |   8 +
 ...add-compatible-to-NanoPi-R2S-etherne.patch |  25 +
 ...-initial-signal-voltage-on-power-off.patch |  35 +
 ...Add-support-for-FriendlyARM-NanoPi-R.patch | 218 +++++
 ...8-add-i2c0-controller-for-nanopi-r2s.patch |  22 +
 ...-for-rockchip-hardware-random-number.patch |  45 +
 ...ip-add-hardware-random-number-genera.patch |  50 +
 ...ip-add-devfreq-driver-for-rk3328-dmc.patch |  44 +
 ...setting-ddr-clock-via-SIP-Version-2-.patch | 218 +++++
 ...eq-rockchip-dfi-add-more-soc-support.patch | 662 ++++++++++++++
 ...m64-dts-rockchip-rk3328-add-dfi-node.patch |  27 +
 ...anopi-r2s-add-rk3328-dmc-relate-node.patch | 126 +++
 ...adjust-default-coherent_pool-to-2MiB.patch |  28 +
 ...ip-add-more-cpu-operating-points-for.patch |  44 +
 ...overclock-to-2.2-1.8-GHz-for-NanoPi4.patch | 182 ++++
 41 files changed, 4635 insertions(+), 6 deletions(-)
 create mode 100644 package/boot/arm-trusted-firmware-rk3328/Makefile
 create mode 100644 package/boot/arm-trusted-firmware-rk3328/src/trust.ini
 create mode 100644 package/boot/uboot-rockchip/patches/102-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
 create mode 100644 package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch
 create mode 100644 package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch
 create mode 100644 package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Kconfig
 create mode 100644 package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/MAINTAINERS
 create mode 100644 package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Makefile
 create mode 100644 package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.c
 create mode 100644 package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.h
 create mode 100644 package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/nanopi4.c
 create mode 100644 package/boot/uboot-rockchip/src/include/configs/nanopi4.h
 create mode 100644 target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch
 create mode 100644 target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch
 create mode 100644 target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-dram-nanopi2-timing.dtsi
 create mode 100644 target/linux/rockchip/files/drivers/devfreq/rk3328_dmc.c
 create mode 100644 target/linux/rockchip/files/include/dt-bindings/clock/rockchip-ddr.h
 create mode 100644 target/linux/rockchip/files/include/dt-bindings/memory/rk3328-dram.h
 create mode 100644 target/linux/rockchip/image/nanopi-r4s.bootscript
 create mode 100644 target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
 create mode 100644 target/linux/rockchip/patches-5.10/105-mmc-core-set-initial-signal-voltage-on-power-off.patch
 create mode 100644 target/linux/rockchip/patches-5.10/200-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
 create mode 100644 target/linux/rockchip/patches-5.10/201-rockchip-rk3328-add-i2c0-controller-for-nanopi-r2s.patch
 create mode 100644 target/linux/rockchip/patches-5.10/801-char-add-support-for-rockchip-hardware-random-number.patch
 create mode 100644 target/linux/rockchip/patches-5.10/802-arm64-dts-rockchip-add-hardware-random-number-genera.patch
 create mode 100644 target/linux/rockchip/patches-5.10/803-PM-devfreq-rockchip-add-devfreq-driver-for-rk3328-dmc.patch
 create mode 100644 target/linux/rockchip/patches-5.10/804-clk-rockchip-support-setting-ddr-clock-via-SIP-Version-2-.patch
 create mode 100644 target/linux/rockchip/patches-5.10/805-PM-devfreq-rockchip-dfi-add-more-soc-support.patch
 create mode 100644 target/linux/rockchip/patches-5.10/806-arm64-dts-rockchip-rk3328-add-dfi-node.patch
 create mode 100644 target/linux/rockchip/patches-5.10/807-arm64-dts-nanopi-r2s-add-rk3328-dmc-relate-node.patch
 create mode 100644 target/linux/rockchip/patches-5.10/911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch
 create mode 100644 target/linux/rockchip/patches-5.10/991-arm64-dts-rockchip-add-more-cpu-operating-points-for.patch
 create mode 100644 target/linux/rockchip/patches-5.10/992-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch

diff --git a/package/boot/arm-trusted-firmware-rk3328/Makefile b/package/boot/arm-trusted-firmware-rk3328/Makefile
new file mode 100644
index 0000000000..243fcac9c9
--- /dev/null
+++ b/package/boot/arm-trusted-firmware-rk3328/Makefile
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2021 ImmortalWrt
+# (https://immortalwrt.org)
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=arm-trusted-firmware-rk3328
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=https://github.com/rockchip-linux/rkbin.git
+PKG_SOURCE_DATE:=2020-10-30
+PKG_SOURCE_VERSION:=0bb1c512492386a72a3a0b5a0e18e49c636577b9
+PKG_MIRROR_HASH:=6dffe95b83f37a280f98c105fce529f45e39ce333b24709a9645aac1352457ce
+
+PKG_MAINTAINER:=AmadeusGhost <amadeus@immortalwrt.org>
+
+MAKE_PATH:=$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/arm-trusted-firmware-rk3328
+    SECTION:=boot
+    CATEGORY:=Boot Loaders
+    TITLE:=ARM Trusted Firmware for Rockchip
+    DEPENDS:=@TARGET_rockchip_armv8
+endef
+
+define Build/Configure
+	$(SED) 's,$$$$(PKG_BUILD_DIR),$(PKG_BUILD_DIR),g' $(PKG_BUILD_DIR)/trust.ini
+	$(call Build/Configure/Default)
+endef
+
+define Build/Compile
+	mkimage -n rk3328 -T rksd -d $(PKG_BUILD_DIR)/bin/rk33/rk3328_ddr_333MHz_v1.16.bin $(PKG_BUILD_DIR)/idbloader.bin
+	cat $(PKG_BUILD_DIR)/bin/rk33/rk322xh_miniloader_v2.50.bin >> $(PKG_BUILD_DIR)/idbloader.bin
+	$(PKG_BUILD_DIR)/tools/trust_merger --replace bl31.elf $(PKG_BUILD_DIR)/bin/rk33/rk322xh_bl31_v1.44.elf $(PKG_BUILD_DIR)/trust.ini
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) -p $(STAGING_DIR_IMAGE)
+	$(CP) $(PKG_BUILD_DIR)/bin/rk33/rk322xh_bl31_v1.44.elf $(STAGING_DIR_IMAGE)/
+	$(CP) $(PKG_BUILD_DIR)/tools/loaderimage $(STAGING_DIR_IMAGE)/
+	$(CP) $(PKG_BUILD_DIR)/idbloader.bin $(STAGING_DIR_IMAGE)/
+	$(CP) $(PKG_BUILD_DIR)/trust.bin $(STAGING_DIR_IMAGE)/
+endef
+
+define Package/arm-trusted-firmware-rk3328/install
+endef
+
+$(eval $(call BuildPackage,arm-trusted-firmware-rk3328))
diff --git a/package/boot/arm-trusted-firmware-rk3328/src/trust.ini b/package/boot/arm-trusted-firmware-rk3328/src/trust.ini
new file mode 100644
index 0000000000..b95797427e
--- /dev/null
+++ b/package/boot/arm-trusted-firmware-rk3328/src/trust.ini
@@ -0,0 +1,15 @@
+[VERSION]
+MAJOR=1
+MINOR=0
+[BL30_OPTION]
+SEC=0
+[BL31_OPTION]
+SEC=1
+PATH=bl31.elf
+ADDR=0x10000
+[BL32_OPTION]
+SEC=0
+[BL33_OPTION]
+SEC=0
+[OUTPUT]
+PATH=$(PKG_BUILD_DIR)/trust.bin
diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile
index 645422aca4..9d240e464c 100644
--- a/package/boot/uboot-rockchip/Makefile
+++ b/package/boot/uboot-rockchip/Makefile
@@ -29,15 +29,26 @@ define U-Boot/nanopi-r2s-rk3328
   NAME:=NanoPi R2S
   BUILD_DEVICES:= \
     friendlyarm_nanopi-r2s
-  DEPENDS:=+PACKAGE_u-boot-nanopi-r2s-rk3328:arm-trusted-firmware-rockchip
-  PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip
-  ATF:=rk3328_bl31.elf
+  DEPENDS:=+PACKAGE_u-boot-nanopi-r2s-rk3328:arm-trusted-firmware-rk3328
+  PKG_BUILD_DEPENDS:=arm-trusted-firmware-rk3328
+  ATF:=rk322xh_bl31_v1.44.elf
+  USE_RKBIN:=1
   OF_PLATDATA:=$(1)
 endef
 
 
 # RK3399 boards
 
+define U-Boot/nanopi-r4s-rk3399
+  BUILD_SUBTARGET:=armv8
+  NAME:=NanoPi R4S
+  BUILD_DEVICES:= \
+    friendlyarm_nanopi-r4s
+  DEPENDS:=+PACKAGE_u-boot-nanopi-r4s-rk3399:arm-trusted-firmware-rockchip
+  PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip
+  ATF:=rk3399_bl31.elf
+endef
+
 define U-Boot/rock-pi-4-rk3399
   BUILD_SUBTARGET:=armv8
   NAME:=Rock Pi 4
@@ -59,6 +70,7 @@ define U-Boot/rockpro64-rk3399
 endef
 
 UBOOT_TARGETS := \
+  nanopi-r4s-rk3399 \
   rock-pi-4-rk3399 \
   rockpro64-rk3399 \
   nanopi-r2s-rk3328
@@ -85,8 +97,15 @@ endef
 
 define Build/InstallDev
 	$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
+ifneq ($(USE_RKBIN),)
+	$(STAGING_DIR_IMAGE)/loaderimage --pack --uboot $(PKG_BUILD_DIR)/u-boot-dtb.bin $(PKG_BUILD_DIR)/uboot.img 0x200000
+	$(CP) $(PKG_BUILD_DIR)/uboot.img $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-uboot.img
+	$(CP) $(STAGING_DIR_IMAGE)/idbloader.bin $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-idbloader.bin
+	$(CP) $(STAGING_DIR_IMAGE)/trust.bin $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-trust.bin
+else
 	$(CP) $(PKG_BUILD_DIR)/idbloader.img $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-idbloader.img
 	$(CP) $(PKG_BUILD_DIR)/u-boot.itb $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot.itb
+endif
 endef
 
 define Package/u-boot/install/default
diff --git a/package/boot/uboot-rockchip/patches/102-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch b/package/boot/uboot-rockchip/patches/102-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
new file mode 100644
index 0000000000..2988ea2248
--- /dev/null
+++ b/package/boot/uboot-rockchip/patches/102-rockchip-rk3399-Add-support-for-FriendlyARM-NanoPi-R.patch
@@ -0,0 +1,257 @@
+From 2dd6b01ec665c376e6be7d37b513fb4d05df60db Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Fri, 8 Jan 2021 05:55:50 +0000
+Subject: [PATCH] rockchip: rk3399: Add support for FriendlyARM NanoPi R4S
+
+This adds support for the NanoPi R4S from FriendlyArm.
+
+Rockchip RK3399 SoC
+1GB DDR3 or 4GB LPDDR4 RAM
+Gigabit Ethernet (WAN)
+Gigabit Ethernet (PCIe) (LAN)
+USB 3.0 Host Port x 2
+MicroSD slot
+Reset button
+WAN - LAN - SYS LED
+
+Co-developed-by: Jensen Huang <jensenhuang@friendlyarm.com>
+Signed-off-by: Jensen Huang <jensenhuang@friendlyarm.com>
+[minor adjustments]
+Co-developed-by: Marty Jones <mj8263788@gmail.com>
+Signed-off-by: Marty Jones <mj8263788@gmail.com>
+[further adjustments, fixed format issues]
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+ arch/arm/dts/Makefile                      |   1 +
+ arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi |   9 ++
+ arch/arm/dts/rk3399-nanopi-r4s.dts         | 133 +++++++++++++++++++++
+ configs/nanopi-r4s-rk3399_defconfig        |  63 ++++++++++
+ 4 files changed, 206 insertions(+)
+ create mode 100644 arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
+ create mode 100644 arch/arm/dts/rk3399-nanopi-r4s.dts
+ create mode 100644 configs/nanopi-r4s-rk3399_defconfig
+
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -132,6 +132,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \
+ 	rk3399-nanopi-m4.dtb \
+ 	rk3399-nanopi-m4-2gb.dtb \
+ 	rk3399-nanopi-neo4.dtb \
++	rk3399-nanopi-r4s.dtb \
+ 	rk3399-orangepi.dtb \
+ 	rk3399-pinebook-pro.dtb \
+ 	rk3399-puma-haikou.dtb \
+--- /dev/null
++++ b/arch/arm/dts/rk3399-nanopi-r4s-u-boot.dtsi
+@@ -0,0 +1,9 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * (C) Copyright 2020 Jensen Huang <jensenhuang@friendlyarm.com>
++ */
++
++#include "rk3399-nanopi4-u-boot.dtsi"
++#include "rk3399-sdram-lpddr4-100.dtsi"
++#include "rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi"
++#include "rk3399-sdram-ddr3-1866.dtsi"
+--- /dev/null
++++ b/arch/arm/dts/rk3399-nanopi-r4s.dts
+@@ -0,0 +1,133 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * FriendlyElec NanoPC-T4 board device tree source
++ *
++ * Copyright (c) 2020 FriendlyElec Computer Tech. Co., Ltd.
++ * (http://www.friendlyarm.com)
++ *
++ * Copyright (c) 2018 Collabora Ltd.
++ *
++ * Copyright (c) 2020 Jensen Huang <jensenhuang@friendlyarm.com>
++ * Copyright (c) 2020 Marty Jones <mj8263788@gmail.com>
++ * Copyright (c) 2021 Tianling Shen <cnsztl@gmail.com>
++ */
++
++/dts-v1/;
++#include "rk3399-nanopi4.dtsi"
++
++/ {
++	model = "FriendlyElec NanoPi R4S";
++	compatible = "friendlyarm,nanopi-r4s", "rockchip,rk3399";
++
++	/delete-node/ display-subsystem;
++
++	gpio-leds {
++		pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>;
++
++		/delete-node/ status;
++
++		lan_led: led-lan {
++			gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>;
++			label = "green:lan";
++		};
++
++		sys_led: led-sys {
++			gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
++			label = "red:sys";
++			default-state = "on";
++		};
++
++		wan_led: led-wan {
++			gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
++			label = "green:wan";
++		};
++	};
++
++	gpio-keys {
++		pinctrl-0 = <&reset_button_pin>;
++
++		/delete-node/ power;
++
++		reset {
++			debounce-interval = <50>;
++			gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_LOW>;
++			label = "reset";
++			linux,code = <KEY_RESTART>;
++		};
++	};
++
++	vdd_5v: vdd-5v {
++		compatible = "regulator-fixed";
++		regulator-name = "vdd_5v";
++		regulator-always-on;
++		regulator-boot-on;
++	};
++};
++
++&emmc_phy {
++	status = "disabled";
++};
++
++&i2c4 {
++	status = "disabled";
++};
++
++&pcie0 {
++	max-link-speed = <1>;
++	num-lanes = <1>;
++	vpcie3v3-supply = <&vcc3v3_sys>;
++};
++
++&pinctrl {
++	gpio-leds {
++		/delete-node/ leds-gpio;
++
++		lan_led_pin: lan-led-pin {
++			rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
++		};
++
++		sys_led_pin: sys-led-pin {
++			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
++		};
++
++		wan_led_pin: wan-led-pin {
++			rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
++		};
++	};
++
++	rockchip-key {
++		/delete-node/ power-key;
++
++		reset_button_pin: reset-button-pin {
++			rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>;
++		};
++	};
++};
++
++&sdhci {
++	status = "disabled";
++};
++
++&sdio0 {
++	status = "disabled";
++};
++
++&u2phy0_host {
++	phy-supply = <&vdd_5v>;
++};
++
++&u2phy1_host {
++	status = "disabled";
++};
++
++&uart0 {
++	status = "disabled";
++};
++
++&usbdrd_dwc3_0 {
++	dr_mode = "host";
++};
++
++&vcc3v3_sys {
++	vin-supply = <&vcc5v0_sys>;
++};
+--- /dev/null
++++ b/configs/nanopi-r4s-rk3399_defconfig
+@@ -0,0 +1,63 @@
++CONFIG_ARM=y
++CONFIG_ARCH_ROCKCHIP=y
++CONFIG_SYS_TEXT_BASE=0x00200000
++CONFIG_NR_DRAM_BANKS=1
++CONFIG_ENV_OFFSET=0x3F8000
++CONFIG_ROCKCHIP_RK3399=y
++CONFIG_TARGET_NANOPI4_RK3399=y
++CONFIG_DEBUG_UART_BASE=0xFF1A0000
++CONFIG_DEBUG_UART_CLOCK=24000000
++CONFIG_DEFAULT_DEVICE_TREE="rk3399-nanopi-r4s"
++CONFIG_DEBUG_UART=y
++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-nanopi-r4s.dtb"
++CONFIG_MISC_INIT_R=y
++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
++CONFIG_SPL_STACK_R=y
++CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
++CONFIG_TPL=y
++CONFIG_CMD_BOOTZ=y
++CONFIG_CMD_GPT=y
++CONFIG_CMD_MMC=y
++CONFIG_CMD_USB=y
++# CONFIG_CMD_SETEXPR is not set
++CONFIG_CMD_TIME=y
++CONFIG_SPL_OF_CONTROL=y
++CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
++CONFIG_ENV_IS_IN_MMC=y
++CONFIG_SYS_RELOC_GD_ENV_ADDR=y
++CONFIG_SYS_MMC_ENV_DEV=1
++CONFIG_ROCKCHIP_GPIO=y
++CONFIG_SYS_I2C_ROCKCHIP=y
++CONFIG_MMC_DW=y
++CONFIG_MMC_DW_ROCKCHIP=y
++CONFIG_MMC_SDHCI=y
++CONFIG_MMC_SDHCI_ROCKCHIP=y
++CONFIG_DM_ETH=y
++CONFIG_ETH_DESIGNWARE=y
++CONFIG_GMAC_ROCKCHIP=y
++CONFIG_PMIC_RK8XX=y
++CONFIG_REGULATOR_PWM=y
++CONFIG_REGULATOR_RK8XX=y
++CONFIG_PWM_ROCKCHIP=y
++CONFIG_RAM_RK3399_LPDDR4=y
++CONFIG_BAUDRATE=1500000
++CONFIG_DEBUG_UART_SHIFT=2
++CONFIG_SYSRESET=y
++CONFIG_USB=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_XHCI_DWC3=y
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_GENERIC=y
++CONFIG_USB_KEYBOARD=y
++CONFIG_USB_HOST_ETHER=y
++CONFIG_USB_ETHER_ASIX=y
++CONFIG_USB_ETHER_ASIX88179=y
++CONFIG_USB_ETHER_MCS7830=y
++CONFIG_USB_ETHER_RTL8152=y
++CONFIG_USB_ETHER_SMSC95XX=y
++CONFIG_DM_VIDEO=y
++CONFIG_DISPLAY=y
++CONFIG_VIDEO_ROCKCHIP=y
++CONFIG_DISPLAY_ROCKCHIP_HDMI=y
++CONFIG_SPL_TINY_MEMSET=y
++CONFIG_ERRNO_STR=y
diff --git a/package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch b/package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch
new file mode 100644
index 0000000000..3580ade7b7
--- /dev/null
+++ b/package/boot/uboot-rockchip/patches/200-rockchip-rk3399-split-nanopi-r4-rk3399-out-of-evb_rk.patch
@@ -0,0 +1,74 @@
+From a765bb2678b6d1666caafef0fcf88fba88b5b26f Mon Sep 17 00:00:00 2001
+From: hmz007 <hmz007@gmail.com>
+Date: Fri, 18 Dec 2020 17:10:35 +0800
+Subject: [PATCH] rockchip: rk3399: split nanopi-r4-rk3399 out of evb_rk3399
+
+nanopi-r4-rk3399 board has multiple DDR types. Currently we don't have any code
+are compatible with these devices. Since multiple DDR types is specific to
+nanopi-r4-rk3399 board, split it into its own board file and add code
+support here.
+
+Signed-off-by: hmz007 <hmz007@gmail.com>
+[Improved commit message and Kconfig description]
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+ arch/arm/mach-rockchip/rk3399/Kconfig |  15 +++
+ board/friendlyarm/nanopi4/Kconfig     |  15 +++
+ board/friendlyarm/nanopi4/MAINTAINERS |   5 +
+ board/friendlyarm/nanopi4/Makefile    |   8 ++
+ board/friendlyarm/nanopi4/hwrev.c     | 185 ++++++++++++++++++++++++++
+ board/friendlyarm/nanopi4/hwrev.h     |  27 ++++
+ board/friendlyarm/nanopi4/nanopi4.c   | 148 +++++++++++++++++++++
+ drivers/clk/rockchip/clk_rk3399.c     |   2 +
+ include/configs/nanopi4.h             |  24 ++++
+ 9 files changed, 429 insertions(+)
+ create mode 100644 board/friendlyarm/nanopi4/Kconfig
+ create mode 100644 board/friendlyarm/nanopi4/MAINTAINERS
+ create mode 100644 board/friendlyarm/nanopi4/Makefile
+ create mode 100644 board/friendlyarm/nanopi4/hwrev.c
+ create mode 100644 board/friendlyarm/nanopi4/hwrev.h
+ create mode 100644 board/friendlyarm/nanopi4/nanopi4.c
+ create mode 100644 include/configs/nanopi4.h
+
+--- a/arch/arm/mach-rockchip/rk3399/Kconfig
++++ b/arch/arm/mach-rockchip/rk3399/Kconfig
+@@ -109,6 +109,20 @@ config TARGET_ROC_PC_RK3399
+ 	   * wide voltage input(5V-15V), dual cell battery
+ 	   * Wifi/BT accessible via expansion board M.2
+ 
++config TARGET_NANOPI4_RK3399
++	bool "FriendlyElec NanoPi4 board"
++	help
++	  NanoPi4 is SBC produced by FriendlyElec. Key features:
++
++	   * Rockchip RK3399
++	   * 1/2/4GB Dual-Channel DDR3/LPDDR4
++	   * SD card slot
++	   * Gigabit ethernet
++	   * PCIe
++	   * USB 3.0, 2.0
++	   * USB Type C power
++	   * GPIO expansion ports
++
+ endchoice
+ 
+ config ROCKCHIP_BOOT_MODE_REG
+@@ -152,6 +166,7 @@ config SYS_BOOTCOUNT_ADDR
+ endif # BOOTCOUNT_LIMIT
+ 
+ source "board/firefly/roc-pc-rk3399/Kconfig"
++source "board/friendlyarm/nanopi4/Kconfig"
+ source "board/google/gru/Kconfig"
+ source "board/pine64/pinebook-pro-rk3399/Kconfig"
+ source "board/pine64/rockpro64_rk3399/Kconfig"
+--- a/drivers/clk/rockchip/clk_rk3399.c
++++ b/drivers/clk/rockchip/clk_rk3399.c
+@@ -1372,6 +1372,8 @@ static void rkclk_init(struct rockchip_c
+ 		     pclk_div << PCLK_PERILP1_DIV_CON_SHIFT |
+ 		     hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
+ 		     HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
++
++	rk3399_saradc_set_clk(cru, 1000000);
+ }
+ 
+ static int rk3399_clk_probe(struct udevice *dev)
diff --git a/package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch b/package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch
new file mode 100644
index 0000000000..ba1a143268
--- /dev/null
+++ b/package/boot/uboot-rockchip/patches/201-ram-rk3399-Add-support-for-multiple-DDR-types.patch
@@ -0,0 +1,256 @@
+From a9447b7b60a3c5195d0fabbe5aa9c32d047ec997 Mon Sep 17 00:00:00 2001
+From: hmz007 <hmz007@gmail.com>
+Date: Sat, 19 Dec 2020 19:39:14 +0800
+Subject: [PATCH] ram: rk3399: Add support for multiple DDR types
+
+Move rockchip,sdram-params to named subnode to include
+multiple sdram parameters, and then read the parameters
+(by subnode name, first subnode or current node) before
+rk3399_dmc_init().
+
+Signed-off-by: hmz007 <hmz007@gmail.com>
+---
+ arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi      |  6 ++-
+ arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi      |  5 +-
+ arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi      |  6 ++-
+ .../arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi |  3 ++
+ .../arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi |  3 ++
+ .../rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi |  3 ++
+ arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi     |  3 ++
+ drivers/ram/rockchip/sdram_rk3399.c           | 49 +++++++++++++++----
+ 8 files changed, 64 insertions(+), 14 deletions(-)
+
+--- a/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
++++ b/arch/arm/dts/rk3399-sdram-ddr3-1333.dtsi
+@@ -4,7 +4,9 @@
+  */
+ 
+ &dmc {
+-        rockchip,sdram-params = <
++	ddr3-1333 {
++	u-boot,dm-pre-reloc;
++	rockchip,sdram-params = <
+ 		0x1
+ 		0xa
+ 		0x3
+@@ -1536,5 +1538,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+-
+--- a/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
++++ b/arch/arm/dts/rk3399-sdram-ddr3-1600.dtsi
+@@ -4,7 +4,9 @@
+  */
+ 
+ &dmc {
+-        rockchip,sdram-params = <
++	ddr3-1600 {
++	u-boot,dm-pre-reloc;
++	rockchip,sdram-params = <
+ 		0x1
+ 		0xa
+ 		0x3
+@@ -1536,4 +1538,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+--- a/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
++++ b/arch/arm/dts/rk3399-sdram-ddr3-1866.dtsi
+@@ -4,7 +4,9 @@
+  */
+ 
+ &dmc {
+-        rockchip,sdram-params = <
++	ddr3-1866 {
++	u-boot,dm-pre-reloc;
++	rockchip,sdram-params = <
+ 		0x1
+ 		0xa
+ 		0x3
+@@ -1536,5 +1538,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+-
+--- a/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
++++ b/arch/arm/dts/rk3399-sdram-lpddr3-2GB-1600.dtsi
+@@ -5,6 +5,8 @@
+  */
+ 
+ &dmc {
++	lpddr3-2GB-1600 {
++	u-boot,dm-pre-reloc;
+ 	rockchip,sdram-params = <
+ 		0x1
+ 		0xa
+@@ -1537,4 +1539,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+--- a/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
++++ b/arch/arm/dts/rk3399-sdram-lpddr3-4GB-1600.dtsi
+@@ -4,6 +4,8 @@
+  */
+ 
+ &dmc {
++	lpddr3-4GB-1600 {
++	u-boot,dm-pre-reloc;
+ 	rockchip,sdram-params = <
+ 		0x2
+ 		0xa
+@@ -1536,4 +1538,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+--- a/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
++++ b/arch/arm/dts/rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi
+@@ -4,6 +4,8 @@
+  */
+ 
+ &dmc {
++	lpddr3-samsung-4GB-1866 {
++	u-boot,dm-pre-reloc;
+ 	rockchip,sdram-params = <
+ 		0x2
+ 		0xa
+@@ -1543,4 +1545,5 @@
+ 		0x01010000	/* DENALI_PHY_957_DATA */
+ 		0x00000000	/* DENALI_PHY_958_DATA */
+ 	>;
++	};
+ };
+--- a/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
++++ b/arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi
+@@ -6,6 +6,8 @@
+  */
+ 
+ &dmc {
++	lpddr4-100 {
++	u-boot,dm-pre-reloc;
+ 	rockchip,sdram-params = <
+ 		0x2
+ 		0xa
+@@ -1538,4 +1540,5 @@
+ 		0x01010000
+ 		0x00000000
+ 	>;
++	};
+ };
+--- a/drivers/ram/rockchip/sdram_rk3399.c
++++ b/drivers/ram/rockchip/sdram_rk3399.c
+@@ -1625,7 +1625,6 @@ static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
+ 	rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
+ }
+ 
+-#if !defined(CONFIG_RAM_RK3399_LPDDR4)
+ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
+ 			       struct rk3399_sdram_params *params)
+ {
+@@ -1715,8 +1714,8 @@ void modify_param(const struct chan_info *chan,
+ 	clrsetbits_le32(&denali_pi_params[76], 0x1 << 24, 0x1 << 24);
+ 	clrsetbits_le32(&denali_pi_params[77], 0x1, 0x1);
+ }
+-#else
+ 
++#if defined(CONFIG_RAM_RK3399_LPDDR4)
+ struct rk3399_sdram_params dfs_cfgs_lpddr4[] = {
+ #include "sdram-rk3399-lpddr4-400.inc"
+ #include "sdram-rk3399-lpddr4-800.inc"
+@@ -3011,20 +3010,40 @@ static int sdram_init(struct dram_info *dram,
+ 	return 0;
+ }
+ 
++__weak const char *rk3399_get_ddrtype(void)
++{
++	return NULL;
++}
++
+ static int rk3399_dmc_of_to_plat(struct udevice *dev)
+ {
+ #if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ 	struct rockchip_dmc_plat *plat = dev_get_plat(dev);
++	ofnode node = { .np = NULL };
++	const char *name;
+ 	int ret;
+ 
+-	ret = dev_read_u32_array(dev, "rockchip,sdram-params",
+-				 (u32 *)&plat->sdram_params,
+-				 sizeof(plat->sdram_params) / sizeof(u32));
++	name = rk3399_get_ddrtype();
++	if (name)
++		node = dev_read_subnode(dev, name);
++	if (!ofnode_valid(node)) {
++		debug("Failed to read subnode %s\n", name);
++		node = dev_read_first_subnode(dev);
++	}
++
++	/* fallback to current node */
++	if (!ofnode_valid(node))
++		node = dev_ofnode(dev);
++
++	ret = ofnode_read_u32_array(node, "rockchip,sdram-params",
++				    (u32 *)&plat->sdram_params,
++				    sizeof(plat->sdram_params) / sizeof(u32));
+ 	if (ret) {
+ 		printf("%s: Cannot read rockchip,sdram-params %d\n",
+ 		       __func__, ret);
+ 		return ret;
+ 	}
++
+ 	ret = regmap_init_mem(dev_ofnode(dev), &plat->map);
+ 	if (ret)
+ 		printf("%s: regmap failed %d\n", __func__, ret);
+@@ -3050,18 +3069,20 @@ static int conv_of_plat(struct udevice *dev)
+ #endif
+ 
+ static const struct sdram_rk3399_ops rk3399_ops = {
+-#if !defined(CONFIG_RAM_RK3399_LPDDR4)
+ 	.data_training_first = data_training_first,
+ 	.set_rate_index = switch_to_phy_index1,
+ 	.modify_param = modify_param,
+ 	.get_phy_index_params = get_phy_index_params,
+-#else
++};
++
++#if defined(CONFIG_RAM_RK3399_LPDDR4)
++static const struct sdram_rk3399_ops lpddr4_ops = {
+ 	.data_training_first = lpddr4_mr_detect,
+ 	.set_rate_index = lpddr4_set_rate,
+ 	.modify_param = lpddr4_modify_param,
+ 	.get_phy_index_params = lpddr4_get_phy_index_params,
+-#endif
+ };
++#endif
+ 
+ static int rk3399_dmc_init(struct udevice *dev)
+ {
+@@ -3080,7 +3101,17 @@ static int rk3399_dmc_init(struct udevice *dev)
+ 		return ret;
+ #endif
+ 
+-	priv->ops = &rk3399_ops;
++	if (params->base.dramtype == LPDDR4) {
++#if defined(CONFIG_RAM_RK3399_LPDDR4)
++		priv->ops = &lpddr4_ops;
++#else
++		printf("LPDDR4 support is disable\n");
++		return -EINVAL;
++#endif
++	} else {
++		priv->ops = &rk3399_ops;
++	}
++
+ 	priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC);
+ 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ 	priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
diff --git a/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Kconfig b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Kconfig
new file mode 100644
index 0000000000..80a735d4c2
--- /dev/null
+++ b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_NANOPI4_RK3399
+
+config SYS_BOARD
+	default "nanopi4"
+
+config SYS_VENDOR
+	default "friendlyarm"
+
+config SYS_CONFIG_NAME
+	default "nanopi4"
+
+config BOARD_SPECIFIC_OPTIONS
+	def_bool y
+
+endif
diff --git a/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/MAINTAINERS b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/MAINTAINERS
new file mode 100644
index 0000000000..cbc4da4273
--- /dev/null
+++ b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/MAINTAINERS
@@ -0,0 +1,5 @@
+NanoPi 4 Series
+M:      FriendlyElec <support@friendlyarm.com>
+S:      Maintained
+F:      board/friendlyarm/nanopi4/
+F:      include/configs/nanopi4.h
diff --git a/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Makefile b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Makefile
new file mode 100644
index 0000000000..33a1466567
--- /dev/null
+++ b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (C) Guangzhou FriendlyELEC Computer Tech. Co., Ltd.
+# (http://www.friendlyarm.com)
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= nanopi4.o hwrev.o
diff --git a/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.c b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.c
new file mode 100644
index 0000000000..a3713ef18c
--- /dev/null
+++ b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 FriendlyElec Computer Tech. Co., Ltd.
+ * (http://www.friendlyarm.com)
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <log.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch-rockchip/gpio.h>
+
+/*
+ * ID info:
+ *  ID : Volts : ADC value :   Bucket
+ *  ==   =====   =========   ===========
+ *   0 : 0.102V:        58 :    0 -   81
+ *   1 : 0.211V:       120 :   82 -  150
+ *   2 : 0.319V:       181 :  151 -  211
+ *   3 : 0.427V:       242 :  212 -  274
+ *   4 : 0.542V:       307 :  275 -  342
+ *   5 : 0.666V:       378 :  343 -  411
+ *   6 : 0.781V:       444 :  412 -  477
+ *   7 : 0.900V:       511 :  478 -  545
+ *   8 : 1.023V:       581 :  546 -  613
+ *   9 : 1.137V:       646 :  614 -  675
+ *  10 : 1.240V:       704 :  676 -  733
+ *  11 : 1.343V:       763 :  734 -  795
+ *  12 : 1.457V:       828 :  796 -  861
+ *  13 : 1.576V:       895 :  862 -  925
+ *  14 : 1.684V:       956 :  926 -  989
+ *  15 : 1.800V:      1023 :  990 - 1023
+ */
+static const int id_readings[] = {
+	 81, 150, 211, 274, 342, 411, 477, 545,
+	613, 675, 733, 795, 861, 925, 989, 1023
+};
+
+static int cached_board_id = -1;
+
+#define SARADC_BASE		0xFF100000
+#define SARADC_DATA		(SARADC_BASE + 0)
+#define SARADC_CTRL		(SARADC_BASE + 8)
+
+static u32 get_saradc_value(int chn)
+{
+	int timeout = 0;
+	u32 adc_value = 0;
+
+	writel(0, SARADC_CTRL);
+	udelay(2);
+
+	writel(0x28 | chn, SARADC_CTRL);
+	udelay(50);
+
+	timeout = 0;
+	do {
+		if (readl(SARADC_CTRL) & 0x40) {
+			adc_value = readl(SARADC_DATA) & 0x3FF;
+			goto stop_adc;
+		}
+
+		udelay(10);
+	} while (timeout++ < 100);
+
+stop_adc:
+	writel(0, SARADC_CTRL);
+
+	return adc_value;
+}
+
+static uint32_t get_adc_index(int chn)
+{
+	int i;
+	int adc_reading;
+
+	if (cached_board_id != -1)
+		return cached_board_id;
+
+	adc_reading = get_saradc_value(chn);
+	for (i = 0; i < ARRAY_SIZE(id_readings); i++) {
+		if (adc_reading <= id_readings[i]) {
+			debug("ADC reading %d, ID %d\n", adc_reading, i);
+			cached_board_id = i;
+			return i;
+		}
+	}
+
+	/* should die for impossible value */
+	return 0;
+}
+
+/*
+ * Board revision list: <GPIO4_D1 | GPIO4_D0>
+ *  0b00 - NanoPC-T4
+ *  0b01 - NanoPi M4
+ *
+ * Extended by ADC_IN4
+ * Group A:
+ *  0x04 - NanoPi NEO4
+ *  0x06 - SOC-RK3399
+ *  0x07 - SOC-RK3399 V2
+ *  0x09 - NanoPi R4S 1GB
+ *  0x0A - NanoPi R4S 4GB
+ *
+ * Group B:
+ *  0x21 - NanoPi M4 Ver2.0
+ *  0x22 - NanoPi M4B
+ */
+static int pcb_rev = -1;
+
+void bd_hwrev_init(void)
+{
+#define GPIO4_BASE	0xff790000
+	struct rockchip_gpio_regs *regs = (void *)GPIO4_BASE;
+
+#ifdef CONFIG_SPL_BUILD
+	struct udevice *dev;
+
+	if (uclass_get_device_by_driver(UCLASS_CLK,
+				DM_DRIVER_GET(clk_rk3399), &dev))
+		return;
+#endif
+
+	if (pcb_rev >= 0)
+		return;
+
+	/* D1, D0: input mode */
+	clrbits_le32(&regs->swport_ddr, (0x3 << 24));
+	pcb_rev = (readl(&regs->ext_port) >> 24) & 0x3;
+
+	if (pcb_rev == 0x3) {
+		/* Revision group A: 0x04 ~ 0x13 */
+		pcb_rev = 0x4 + get_adc_index(4);
+
+	} else if (pcb_rev == 0x1) {
+		int idx = get_adc_index(4);
+
+		/* Revision group B: 0x21 ~ 0x2f */
+		if (idx > 0) {
+			pcb_rev = 0x20 + idx;
+		}
+	}
+}
+
+#ifdef CONFIG_SPL_BUILD
+static struct board_ddrtype {
+	int rev;
+	const char *type;
+} ddrtypes[] = {
+	{ 0x00, "lpddr3-samsung-4GB-1866" },
+	{ 0x01, "lpddr3-samsung-4GB-1866" },
+	{ 0x04,   "ddr3-1866" },
+	{ 0x06,   "ddr3-1866" },
+	{ 0x07, "lpddr4-100"  },
+	{ 0x09,   "ddr3-1866" },
+	{ 0x0a, "lpddr4-100"  },
+	{ 0x21, "lpddr4-100"  },
+	{ 0x22,   "ddr3-1866" },
+};
+
+const char *rk3399_get_ddrtype(void) {
+	int i;
+
+	bd_hwrev_init();
+	printf("Board: rev%02x\n", pcb_rev);
+
+	for (i = 0; i < ARRAY_SIZE(ddrtypes); i++) {
+		if (ddrtypes[i].rev == pcb_rev)
+			return ddrtypes[i].type;
+	}
+
+	/* fallback to first subnode (ie, first included dtsi) */
+	return NULL;
+}
+#endif
+
+/* To override __weak symbols */
+u32 get_board_rev(void)
+{
+	return pcb_rev;
+}
+
diff --git a/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.h b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.h
new file mode 100644
index 0000000000..23b3c7a557
--- /dev/null
+++ b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/hwrev.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd.
+ * (http://www.friendlyarm.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ */
+
+#ifndef __BD_HW_REV_H__
+#define __BD_HW_REV_H__
+
+extern void bd_hwrev_config_gpio(void);
+extern void bd_hwrev_init(void);
+extern u32 get_board_rev(void);
+
+#endif /* __BD_HW_REV_H__ */
diff --git a/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/nanopi4.c b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/nanopi4.c
new file mode 100644
index 0000000000..a140370ca2
--- /dev/null
+++ b/package/boot/uboot-rockchip/src/board/friendlyarm/nanopi4/nanopi4.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 FriendlyElec Computer Tech. Co., Ltd.
+ * (http://www.friendlyarm.com)
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <env.h>
+#include <hash.h>
+#include <linux/bitops.h>
+#include <i2c.h>
+#include <init.h>
+#include <net.h>
+#include <netdev.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/misc.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <u-boot/sha256.h>
+
+#ifdef CONFIG_MISC_INIT_R
+static void setup_iodomain(void)
+{
+	struct rk3399_grf_regs *grf =
+	    syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+	/* BT565 and AUDIO is in 1.8v domain */
+	rk_setreg(&grf->io_vsel, BIT(0) | BIT(1));
+}
+
+static int __maybe_unused mac_read_from_generic_eeprom(u8 *addr)
+{
+	struct udevice *i2c_dev;
+	int ret;
+
+	/* Microchip 24AA02xxx EEPROMs with EUI-48 Node Identity */
+	ret = i2c_get_chip_for_busnum(2, 0x51, 1, &i2c_dev);
+	if (!ret)
+		ret = dm_i2c_read(i2c_dev, 0xfa, addr, 6);
+
+	return ret;
+}
+
+static void setup_macaddr(void)
+{
+#if CONFIG_IS_ENABLED(CMD_NET)
+	int ret;
+	const char *cpuid = env_get("cpuid#");
+	u8 hash[SHA256_SUM_LEN];
+	int size = sizeof(hash);
+	u8 mac_addr[6];
+	int from_eeprom = 0;
+	int lockdown = 0;
+
+#ifndef CONFIG_ENV_IS_NOWHERE
+	lockdown = env_get_yesno("lockdown") == 1;
+#endif
+	if (lockdown && env_get("ethaddr"))
+		return;
+
+	ret = mac_read_from_generic_eeprom(mac_addr);
+	if (!ret && is_valid_ethaddr(mac_addr)) {
+		eth_env_set_enetaddr("ethaddr", mac_addr);
+		from_eeprom = 1;
+	}
+
+	if (!cpuid) {
+		debug("%s: could not retrieve 'cpuid#'\n", __func__);
+		return;
+	}
+
+	ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size);
+	if (ret) {
+		debug("%s: failed to calculate SHA256\n", __func__);
+		return;
+	}
+
+	/* Copy 6 bytes of the hash to base the MAC address on */
+	memcpy(mac_addr, hash, 6);
+
+	/* Make this a valid MAC address and set it */
+	mac_addr[0] &= 0xfe;  /* clear multicast bit */
+	mac_addr[0] |= 0x02;  /* set local assignment bit (IEEE802) */
+
+	if (from_eeprom) {
+		eth_env_set_enetaddr("eth1addr", mac_addr);
+	} else {
+		eth_env_set_enetaddr("ethaddr", mac_addr);
+
+		if (lockdown && env_get("eth1addr"))
+			return;
+
+		/* Ugly, copy another 4 bytes to generate a similar address */
+		memcpy(mac_addr + 2, hash + 8, 4);
+		if (!memcmp(hash + 2, hash + 8, 4))
+			mac_addr[5] ^= 0xff;
+
+		eth_env_set_enetaddr("eth1addr", mac_addr);
+	}
+#endif
+
+	return;
+}
+
+int misc_init_r(void)
+{
+	const u32 cpuid_offset = 0x7;
+	const u32 cpuid_length = 0x10;
+	u8 cpuid[cpuid_length];
+	int ret;
+
+	setup_iodomain();
+
+	ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
+	if (ret)
+		return ret;
+
+	ret = rockchip_cpuid_set(cpuid, cpuid_length);
+	if (ret)
+		return ret;
+
+	setup_macaddr();
+	bd_hwrev_init();
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SERIAL_TAG
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+	char *serial_string;
+	u64 serial = 0;
+
+	serial_string = env_get("serial#");
+
+	if (serial_string)
+		serial = simple_strtoull(serial_string, NULL, 16);
+
+	serialnr->high = (u32)(serial >> 32);
+	serialnr->low = (u32)(serial & 0xffffffff);
+}
+#endif
diff --git a/package/boot/uboot-rockchip/src/include/configs/nanopi4.h b/package/boot/uboot-rockchip/src/include/configs/nanopi4.h
new file mode 100644
index 0000000000..a86d38976a
--- /dev/null
+++ b/package/boot/uboot-rockchip/src/include/configs/nanopi4.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) Guangzhou FriendlyELEC Computer Tech. Co., Ltd.
+ * (http://www.friendlyarm.com)
+ *
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __CONFIG_NANOPI4_H__
+#define __CONFIG_NANOPI4_H__
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+		"stdin=serial,usbkbd\0" \
+		"stdout=serial,vidconsole\0" \
+		"stderr=serial,vidconsole\0"
+
+#include <configs/rk3399_common.h>
+
+#define SDRAM_BANK_SIZE			(2UL << 30)
+
+#define CONFIG_SERIAL_TAG
+#define CONFIG_REVISION_TAG
+
+#endif
diff --git a/target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch b/target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch
new file mode 100644
index 0000000000..70cfadca9c
--- /dev/null
+++ b/target/linux/generic/hack-5.10/310-arm64-cpuinfo-Add-model-name-in-proc-cpuinfo-for-64bit-ta.patch
@@ -0,0 +1,38 @@
+From: Sumit Gupta <sumitg@nvidia.com>
+To: <catalin.marinas@arm.com>, <linux-arm-kernel@lists.infradead.org>,
+	<linux-kernel@vger.kernel.org>
+Cc: <will.deacon@arm.com>, <suzuki.poulose@arm.com>,
+	<james.morse@arm.com>, <mark.rutland@arm.com>,
+	<yang.shi@linaro.org>, <julien.grall@arm.com>,
+	<steve.capper@linaro.org>, <bbasu@nvidia.com>,
+	<linux-tegra@vger.kernel.org>, Sumit Gupta <sumitg@nvidia.com>
+Subject: [PATCH] arm64: cpuinfo: Add "model name" in /proc/cpuinfo for 64bit tasks also
+Date: Mon, 29 Aug 2016 14:32:25 +0530
+Message-ID: <1472461345-28219-1-git-send-email-sumitg@nvidia.com> (raw)
+
+Removed restriction of displaying model name for 32 bit tasks only.
+Because of this Processor details were not displayed in
+"System setting -> Details" in Ubuntu model name display is generic
+and can be printed for 64 bit also.
+
+model name : ARMv8 Processor rev X (v8l)
+
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+---
+ arch/arm64/kernel/cpuinfo.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/arm64/kernel/cpuinfo.c
++++ b/arch/arm64/kernel/cpuinfo.c
+@@ -148,9 +148,8 @@ static int c_show(struct seq_file *m, vo
+ 		 * "processor".  Give glibc what it expects.
+ 		 */
+ 		seq_printf(m, "processor\t: %d\n", i);
+-		if (compat)
+-			seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
+-				   MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
++		seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
++			   MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
+ 
+ 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+ 			   loops_per_jiffy / (500000UL/HZ),
diff --git a/target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch b/target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch
new file mode 100644
index 0000000000..2981c3d906
--- /dev/null
+++ b/target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch
@@ -0,0 +1,291 @@
+--- a/include/net/netfilter/nf_conntrack_ecache.h
++++ b/include/net/netfilter/nf_conntrack_ecache.h
+@@ -72,6 +72,10 @@ struct nf_ct_event {
+ 	int report;
+ };
+ 
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
++extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
++#else
+ struct nf_ct_event_notifier {
+ 	int (*fcn)(unsigned int events, struct nf_ct_event *item);
+ };
+@@ -80,6 +84,7 @@ int nf_conntrack_register_notifier(struc
+ 				   struct nf_ct_event_notifier *nb);
+ void nf_conntrack_unregister_notifier(struct net *net,
+ 				      struct nf_ct_event_notifier *nb);
++#endif
+ 
+ void nf_ct_deliver_cached_events(struct nf_conn *ct);
+ int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
+@@ -105,11 +110,13 @@ static inline void
+ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
+ {
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
+-	struct net *net = nf_ct_net(ct);
+ 	struct nf_conntrack_ecache *e;
++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++	struct net *net = nf_ct_net(ct);
+ 
+ 	if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
+ 		return;
++#endif
+ 
+ 	e = nf_ct_ecache_find(ct);
+ 	if (e == NULL)
+@@ -124,10 +131,12 @@ nf_conntrack_event_report(enum ip_conntr
+ 			  u32 portid, int report)
+ {
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
+ 	const struct net *net = nf_ct_net(ct);
+ 
+ 	if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
+ 		return 0;
++#endif
+ 
+ 	return nf_conntrack_eventmask_report(1 << event, ct, portid, report);
+ #else
+@@ -139,10 +148,12 @@ static inline int
+ nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
+ {
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
++#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
+ 	const struct net *net = nf_ct_net(ct);
+ 
+ 	if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
+ 		return 0;
++#endif
+ 
+ 	return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
+ #else
+--- a/include/net/netns/conntrack.h
++++ b/include/net/netns/conntrack.h
+@@ -112,7 +112,11 @@ struct netns_ct {
+ 
+ 	struct ct_pcpu __percpu *pcpu_lists;
+ 	struct ip_conntrack_stat __percpu *stat;
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++	struct atomic_notifier_head nf_conntrack_chain;
++#else
+ 	struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
++#endif
+ 	struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
+ 	struct nf_ip_net	nf_ct_proto;
+ #if defined(CONFIG_NF_CONNTRACK_LABELS)
+--- a/net/netfilter/Kconfig
++++ b/net/netfilter/Kconfig
+@@ -136,6 +136,14 @@ config NF_CONNTRACK_EVENTS
+ 
+ 	  If unsure, say `N'.
+ 
++config NF_CONNTRACK_CHAIN_EVENTS
++	bool "Register multiple callbacks to ct events"
++	depends on NF_CONNTRACK_EVENTS
++	help
++	  Support multiple registrations.
++
++	  If unsure, say `N'.
++
+ config NF_CONNTRACK_TIMEOUT
+ 	bool  'Connection tracking timeout'
+ 	depends on NETFILTER_ADVANCED
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -2748,6 +2748,9 @@ int nf_conntrack_init_net(struct net *ne
+ 	nf_conntrack_helper_pernet_init(net);
+ 	nf_conntrack_proto_pernet_init(net);
+ 
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++	ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain);
++#endif
+ 	return 0;
+ 
+ err_expect:
+--- a/net/netfilter/nf_conntrack_ecache.c
++++ b/net/netfilter/nf_conntrack_ecache.c
+@@ -17,6 +17,9 @@
+ #include <linux/stddef.h>
+ #include <linux/err.h>
+ #include <linux/percpu.h>
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++#include <linux/notifier.h>
++#endif
+ #include <linux/kernel.h>
+ #include <linux/netdevice.h>
+ #include <linux/slab.h>
+@@ -129,7 +132,35 @@ static void ecache_work(struct work_stru
+ 	if (delay >= 0)
+ 		schedule_delayed_work(&ctnet->ecache_dwork, delay);
+ }
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
++				  u32 portid, int report)
++{
++	struct nf_conntrack_ecache *e;
++	struct net *net = nf_ct_net(ct);
++
++	e = nf_ct_ecache_find(ct);
++	if (e == NULL)
++		return 0;
++
++	if (nf_ct_is_confirmed(ct)) {
++		struct nf_ct_event item = {
++			.ct = ct,
++			.portid	= e->portid ? e->portid : portid,
++			.report = report
++		};
++		/* This is a resent of a destroy event? If so, skip missed */
++		unsigned long missed = e->portid ? 0 : e->missed;
++
++		if (!((eventmask | missed) & e->ctmask))
++			return 0;
+ 
++		atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item);
++	}
++
++	return 0;
++}
++#else
+ int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
+ 				  u32 portid, int report)
+ {
+@@ -184,10 +215,52 @@ out_unlock:
+ 	rcu_read_unlock();
+ 	return ret;
+ }
++#endif
+ EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report);
+ 
+ /* deliver cached events and clear cache entry - must be called with locally
+  * disabled softirqs */
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++void nf_ct_deliver_cached_events(struct nf_conn *ct)
++{
++	unsigned long events, missed;
++	struct nf_conntrack_ecache *e;
++	struct nf_ct_event item;
++	struct net *net = nf_ct_net(ct);
++
++	e = nf_ct_ecache_find(ct);
++	if (e == NULL)
++		return;
++
++	events = xchg(&e->cache, 0);
++
++	if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events)
++		return;
++
++	/* We make a copy of the missed event cache without taking
++	 * the lock, thus we may send missed events twice. However,
++	 * this does not harm and it happens very rarely. */
++	missed = e->missed;
++
++	if (!((events | missed) & e->ctmask))
++		return;
++
++	item.ct = ct;
++	item.portid = 0;
++	item.report = 0;
++
++	atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
++			events | missed,
++			&item);
++
++	if (likely(!missed))
++		return;
++
++	spin_lock_bh(&ct->lock);
++		e->missed &= ~missed;
++	spin_unlock_bh(&ct->lock);
++}
++#else
+ void nf_ct_deliver_cached_events(struct nf_conn *ct)
+ {
+ 	struct net *net = nf_ct_net(ct);
+@@ -238,6 +311,7 @@ void nf_ct_deliver_cached_events(struct
+ out_unlock:
+ 	rcu_read_unlock();
+ }
++#endif
+ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
+ 
+ void nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
+@@ -270,6 +344,13 @@ out_unlock:
+ 	rcu_read_unlock();
+ }
+ 
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++int nf_conntrack_register_notifier(struct net *net,
++				   struct notifier_block *nb)
++{
++        return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
++}
++#else
+ int nf_conntrack_register_notifier(struct net *net,
+ 				   struct nf_ct_event_notifier *new)
+ {
+@@ -290,8 +371,15 @@ out_unlock:
+ 	mutex_unlock(&nf_ct_ecache_mutex);
+ 	return ret;
+ }
++#endif
+ EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
+ 
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
++{
++	return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
++}
++#else
+ void nf_conntrack_unregister_notifier(struct net *net,
+ 				      struct nf_ct_event_notifier *new)
+ {
+@@ -305,6 +393,7 @@ void nf_conntrack_unregister_notifier(st
+ 	mutex_unlock(&nf_ct_ecache_mutex);
+ 	/* synchronize_rcu() is called from ctnetlink_exit. */
+ }
++#endif
+ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
+ 
+ int nf_ct_expect_register_notifier(struct net *net,
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -703,13 +703,20 @@ static size_t ctnetlink_nlmsg_size(const
+ }
+ 
+ static int
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++ctnetlink_conntrack_event(struct notifier_block *this, unsigned long events, void *ptr)
++#else
+ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
++#endif
+ {
+ 	const struct nf_conntrack_zone *zone;
+ 	struct net *net;
+ 	struct nlmsghdr *nlh;
+ 	struct nfgenmsg *nfmsg;
+ 	struct nlattr *nest_parms;
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++	struct nf_ct_event *item = (struct nf_ct_event *)ptr;
++#endif
+ 	struct nf_conn *ct = item->ct;
+ 	struct sk_buff *skb;
+ 	unsigned int type;
+@@ -3783,9 +3790,15 @@ static int ctnetlink_stat_exp_cpu(struct
+ }
+ 
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
++#ifdef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
++static struct notifier_block ctnl_notifier = {
++	.notifier_call = ctnetlink_conntrack_event,
++};
++#else
+ static struct nf_ct_event_notifier ctnl_notifier = {
+ 	.fcn = ctnetlink_conntrack_event,
+ };
++#endif
+ 
+ static struct nf_exp_event_notifier ctnl_notifier_exp = {
+ 	.fcn = ctnetlink_expect_event,
diff --git a/target/linux/rockchip/Makefile b/target/linux/rockchip/Makefile
index 7aeb0a3d55..f7b6995911 100644
--- a/target/linux/rockchip/Makefile
+++ b/target/linux/rockchip/Makefile
@@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
 
 BOARD:=rockchip
 BOARDNAME:=Rockchip
-FEATURES:=ext4 audio usb usbgadget display gpio fpu rootfs-part boot-part squashfs
+FEATURES:=ext4 audio usb usbgadget display gpio fpu pci pcie rootfs-part boot-part squashfs
 SUBTARGETS:=armv8
 
 KERNEL_PATCHVER=5.4
diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
index e97ea3312d..b10c43ba60 100644
--- a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
+++ b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
@@ -12,6 +12,10 @@ friendlyarm,nanopi-r2s)
 	ucidef_set_led_netdev "wan" "WAN" "$boardname:green:wan" "eth0"
 	ucidef_set_led_netdev "lan" "LAN" "$boardname:green:lan" "eth1"
 	;;
+friendlyarm,nanopi-r4s)
+	ucidef_set_led_netdev "wan" "WAN" "$boardname:green:wan" "eth0"
+	ucidef_set_led_netdev "lan" "LAN" "$boardname:green:lan" "eth1"
+	;;
 esac
 
 board_config_flush
diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
index f5e88cc148..b4e623532b 100644
--- a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
+++ b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
@@ -7,7 +7,8 @@ rockchip_setup_interfaces()
 	local board="$1"
 
 	case "$board" in
-	friendlyarm,nanopi-r2s)
+	friendlyarm,nanopi-r2s|\
+	friendlyarm,nanopi-r4s)
 		ucidef_set_interfaces_lan_wan 'eth1' 'eth0'
 		;;
 	*)
@@ -35,6 +36,10 @@ rockchip_setup_macs()
 		wan_mac=$(nanopi_r2s_generate_mac)
 		lan_mac=$(macaddr_add "$wan_mac" +1)
 		;;
+	friendlyarm,nanopi-r4s)
+		wan_mac=$(cat /sys/class/net/eth0/address)
+		lan_mac=$(macaddr_add "$wan_mac" +1)
+		;;
 	esac
 
 	[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
diff --git a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
index 44716258bf..9e4a4cf4fc 100644
--- a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
+++ b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
@@ -26,5 +26,9 @@ friendlyarm,nanopi-r2s)
 	set_interface_core 2 "eth0"
 	set_interface_core 4 "eth1" "xhci-hcd:usb3"
 	;;
+friendlyarm,nanopi-r4s)
+	set_interface_core 10 "eth0"
+	set_interface_core 20 "eth1"
+	;;
 esac
 
diff --git a/target/linux/rockchip/armv8/config-5.10 b/target/linux/rockchip/armv8/config-5.10
index c85984a982..c9a7887750 100644
--- a/target/linux/rockchip/armv8/config-5.10
+++ b/target/linux/rockchip/armv8/config-5.10
@@ -18,6 +18,7 @@ CONFIG_ARC_EMAC_CORE=y
 CONFIG_ARM64=y
 CONFIG_ARM64_4K_PAGES=y
 CONFIG_ARM64_CNP=y
+CONFIG_ARM64_CRYPTO=y
 # CONFIG_ARM64_ERRATUM_1165522 is not set
 # CONFIG_ARM64_ERRATUM_1286807 is not set
 # CONFIG_ARM64_ERRATUM_1418040 is not set
@@ -61,6 +62,7 @@ CONFIG_ARM_MHU=y
 CONFIG_ARM_PSCI_CPUIDLE=y
 CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
 CONFIG_ARM_PSCI_FW=y
+CONFIG_ARM_RK3328_DMC_DEVFREQ=y
 # CONFIG_ARM_RK3399_DMC_DEVFREQ is not set
 # CONFIG_ARM_SCMI_PROTOCOL is not set
 CONFIG_ARM_SCPI_CPUFREQ=y
@@ -158,18 +160,63 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CROSS_MEMORY_ATTACH=y
 CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_AES_ARM64=y
+CONFIG_CRYPTO_AES_ARM64_BS=y
+CONFIG_CRYPTO_AES_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y
+CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=y
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_CHACHA20_NEON=y
 CONFIG_CRYPTO_CRC32=y
 CONFIG_CRYPTO_CRC32C=y
 CONFIG_CRYPTO_CRCT10DIF=y
+CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_GHASH=y
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
 # CONFIG_CRYPTO_DEV_ROCKCHIP is not set
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y
+CONFIG_CRYPTO_LIB_POLY1305_GENERIC=y
+CONFIG_CRYPTO_LIB_SHA256=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_NHPOLY1305=y
+CONFIG_CRYPTO_NHPOLY1305_NEON=y
+CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_NULL2=y
+CONFIG_CRYPTO_POLY1305_NEON=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA256_ARM64=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA3_ARM64=y
+CONFIG_CRYPTO_SHA512_ARM64=y
+CONFIG_CRYPTO_SHA512_ARM64_CE=y
+CONFIG_CRYPTO_SIMD=y
+CONFIG_CRYPTO_SM3=y
+CONFIG_CRYPTO_SM3_ARM64_CE=y
+CONFIG_CRYPTO_SM4=y
+CONFIG_CRYPTO_SM4_ARM64_CE=y
 CONFIG_DCACHE_WORD_ACCESS=y
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y
 # CONFIG_DEVFREQ_GOV_PASSIVE is not set
 CONFIG_DEVFREQ_GOV_PERFORMANCE=y
 CONFIG_DEVFREQ_GOV_POWERSAVE=y
@@ -270,6 +317,8 @@ CONFIG_HUGETLB_PAGE=y
 CONFIG_HWMON=y
 CONFIG_HWSPINLOCK=y
 CONFIG_HW_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_ROCKCHIP=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
@@ -450,6 +499,7 @@ CONFIG_PM=y
 CONFIG_PM_CLK=y
 CONFIG_PM_DEVFREQ=y
 # CONFIG_PM_DEVFREQ_EVENT is not set
+CONFIG_PM_DEVFREQ_EVENT=y
 CONFIG_PM_GENERIC_DOMAINS=y
 CONFIG_PM_GENERIC_DOMAINS_OF=y
 CONFIG_PM_OPP=y
diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-dram-nanopi2-timing.dtsi b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-dram-nanopi2-timing.dtsi
new file mode 100644
index 0000000000..a3f5ff4bdc
--- /dev/null
+++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3328-dram-nanopi2-timing.dtsi
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <dt-bindings/clock/rockchip-ddr.h>
+#include <dt-bindings/memory/rk3328-dram.h>
+
+/ {
+	ddr_timing: ddr_timing {
+		compatible = "rockchip,ddr-timing";
+		ddr3_speed_bin = <DDR3_DEFAULT>;
+		ddr4_speed_bin = <DDR4_DEFAULT>;
+		pd_idle = <0>;
+		sr_idle = <0>;
+		sr_mc_gate_idle = <0>;
+		srpd_lite_idle	= <0>;
+		standby_idle = <0>;
+
+		auto_pd_dis_freq = <1066>;
+		auto_sr_dis_freq = <800>;
+		ddr3_dll_dis_freq = <300>;
+		ddr4_dll_dis_freq = <625>;
+		phy_dll_dis_freq = <400>;
+
+		ddr3_odt_dis_freq = <100>;
+		phy_ddr3_odt_dis_freq = <100>;
+		ddr3_drv = <DDR3_DS_40ohm>;
+		ddr3_odt = <DDR3_ODT_120ohm>;
+		phy_ddr3_ca_drv = <PHY_DDR3_RON_RTT_34ohm>;
+		phy_ddr3_ck_drv = <PHY_DDR3_RON_RTT_45ohm>;
+		phy_ddr3_dq_drv = <PHY_DDR3_RON_RTT_34ohm>;
+		phy_ddr3_odt = <PHY_DDR3_RON_RTT_225ohm>;
+
+		lpddr3_odt_dis_freq = <666>;
+		phy_lpddr3_odt_dis_freq = <666>;
+		lpddr3_drv = <LP3_DS_40ohm>;
+		lpddr3_odt = <LP3_ODT_240ohm>;
+		phy_lpddr3_ca_drv = <PHY_DDR4_LPDDR3_RON_RTT_34ohm>;
+		phy_lpddr3_ck_drv = <PHY_DDR4_LPDDR3_RON_RTT_43ohm>;
+		phy_lpddr3_dq_drv = <PHY_DDR4_LPDDR3_RON_RTT_34ohm>;
+		phy_lpddr3_odt = <PHY_DDR4_LPDDR3_RON_RTT_240ohm>;
+
+		lpddr4_odt_dis_freq = <800>;
+		phy_lpddr4_odt_dis_freq = <800>;
+		lpddr4_drv = <LP4_PDDS_60ohm>;
+		lpddr4_dq_odt = <LP4_DQ_ODT_40ohm>;
+		lpddr4_ca_odt = <LP4_CA_ODT_40ohm>;
+		phy_lpddr4_ca_drv = <PHY_DDR4_LPDDR3_RON_RTT_40ohm>;
+		phy_lpddr4_ck_cs_drv = <PHY_DDR4_LPDDR3_RON_RTT_80ohm>;
+		phy_lpddr4_dq_drv = <PHY_DDR4_LPDDR3_RON_RTT_80ohm>;
+		phy_lpddr4_odt = <PHY_DDR4_LPDDR3_RON_RTT_60ohm>;
+
+		ddr4_odt_dis_freq = <666>;
+		phy_ddr4_odt_dis_freq = <666>;
+		ddr4_drv = <DDR4_DS_34ohm>;
+		ddr4_odt = <DDR4_RTT_NOM_240ohm>;
+		phy_ddr4_ca_drv = <PHY_DDR4_LPDDR3_RON_RTT_34ohm>;
+		phy_ddr4_ck_drv = <PHY_DDR4_LPDDR3_RON_RTT_43ohm>;
+		phy_ddr4_dq_drv = <PHY_DDR4_LPDDR3_RON_RTT_34ohm>;
+		phy_ddr4_odt = <PHY_DDR4_LPDDR3_RON_RTT_240ohm>;
+
+		/* CA de-skew, one step is 47.8ps, range 0-15 */
+		ddr3a1_ddr4a9_de-skew = <7>;
+		ddr3a0_ddr4a10_de-skew = <7>;
+		ddr3a3_ddr4a6_de-skew = <8>;
+		ddr3a2_ddr4a4_de-skew = <8>;
+		ddr3a5_ddr4a8_de-skew = <7>;
+		ddr3a4_ddr4a5_de-skew = <9>;
+		ddr3a7_ddr4a11_de-skew = <7>;
+		ddr3a6_ddr4a7_de-skew = <9>;
+		ddr3a9_ddr4a0_de-skew = <8>;
+		ddr3a8_ddr4a13_de-skew = <7>;
+		ddr3a11_ddr4a3_de-skew = <9>;
+		ddr3a10_ddr4cs0_de-skew = <7>;
+		ddr3a13_ddr4a2_de-skew = <8>;
+		ddr3a12_ddr4ba1_de-skew = <7>;
+		ddr3a15_ddr4odt0_de-skew = <7>;
+		ddr3a14_ddr4a1_de-skew = <8>;
+		ddr3ba1_ddr4a15_de-skew = <7>;
+		ddr3ba0_ddr4bg0_de-skew = <7>;
+		ddr3ras_ddr4cke_de-skew = <7>;
+		ddr3ba2_ddr4ba0_de-skew = <8>;
+		ddr3we_ddr4bg1_de-skew = <8>;
+		ddr3cas_ddr4a12_de-skew = <7>;
+		ddr3ckn_ddr4ckn_de-skew = <8>;
+		ddr3ckp_ddr4ckp_de-skew = <8>;
+		ddr3cke_ddr4a16_de-skew = <8>;
+		ddr3odt0_ddr4a14_de-skew = <7>;
+		ddr3cs0_ddr4act_de-skew = <8>;
+		ddr3reset_ddr4reset_de-skew = <7>;
+		ddr3cs1_ddr4cs1_de-skew = <7>;
+		ddr3odt1_ddr4odt1_de-skew = <7>;
+
+		/* DATA de-skew
+		 * RX one step is 25.1ps, range 0-15
+		 * TX one step is 47.8ps, range 0-15
+		 */
+		cs0_dm0_rx_de-skew = <7>;
+		cs0_dm0_tx_de-skew = <8>;
+		cs0_dq0_rx_de-skew = <7>;
+		cs0_dq0_tx_de-skew = <8>;
+		cs0_dq1_rx_de-skew = <7>;
+		cs0_dq1_tx_de-skew = <8>;
+		cs0_dq2_rx_de-skew = <7>;
+		cs0_dq2_tx_de-skew = <8>;
+		cs0_dq3_rx_de-skew = <7>;
+		cs0_dq3_tx_de-skew = <8>;
+		cs0_dq4_rx_de-skew = <7>;
+		cs0_dq4_tx_de-skew = <8>;
+		cs0_dq5_rx_de-skew = <7>;
+		cs0_dq5_tx_de-skew = <8>;
+		cs0_dq6_rx_de-skew = <7>;
+		cs0_dq6_tx_de-skew = <8>;
+		cs0_dq7_rx_de-skew = <7>;
+		cs0_dq7_tx_de-skew = <8>;
+		cs0_dqs0_rx_de-skew = <6>;
+		cs0_dqs0p_tx_de-skew = <9>;
+		cs0_dqs0n_tx_de-skew = <9>;
+
+		cs0_dm1_rx_de-skew = <7>;
+		cs0_dm1_tx_de-skew = <7>;
+		cs0_dq8_rx_de-skew = <7>;
+		cs0_dq8_tx_de-skew = <8>;
+		cs0_dq9_rx_de-skew = <7>;
+		cs0_dq9_tx_de-skew = <7>;
+		cs0_dq10_rx_de-skew = <7>;
+		cs0_dq10_tx_de-skew = <8>;
+		cs0_dq11_rx_de-skew = <7>;
+		cs0_dq11_tx_de-skew = <7>;
+		cs0_dq12_rx_de-skew = <7>;
+		cs0_dq12_tx_de-skew = <8>;
+		cs0_dq13_rx_de-skew = <7>;
+		cs0_dq13_tx_de-skew = <7>;
+		cs0_dq14_rx_de-skew = <7>;
+		cs0_dq14_tx_de-skew = <8>;
+		cs0_dq15_rx_de-skew = <7>;
+		cs0_dq15_tx_de-skew = <7>;
+		cs0_dqs1_rx_de-skew = <7>;
+		cs0_dqs1p_tx_de-skew = <9>;
+		cs0_dqs1n_tx_de-skew = <9>;
+
+		cs0_dm2_rx_de-skew = <7>;
+		cs0_dm2_tx_de-skew = <8>;
+		cs0_dq16_rx_de-skew = <7>;
+		cs0_dq16_tx_de-skew = <8>;
+		cs0_dq17_rx_de-skew = <7>;
+		cs0_dq17_tx_de-skew = <8>;
+		cs0_dq18_rx_de-skew = <7>;
+		cs0_dq18_tx_de-skew = <8>;
+		cs0_dq19_rx_de-skew = <7>;
+		cs0_dq19_tx_de-skew = <8>;
+		cs0_dq20_rx_de-skew = <7>;
+		cs0_dq20_tx_de-skew = <8>;
+		cs0_dq21_rx_de-skew = <7>;
+		cs0_dq21_tx_de-skew = <8>;
+		cs0_dq22_rx_de-skew = <7>;
+		cs0_dq22_tx_de-skew = <8>;
+		cs0_dq23_rx_de-skew = <7>;
+		cs0_dq23_tx_de-skew = <8>;
+		cs0_dqs2_rx_de-skew = <6>;
+		cs0_dqs2p_tx_de-skew = <9>;
+		cs0_dqs2n_tx_de-skew = <9>;
+
+		cs0_dm3_rx_de-skew = <7>;
+		cs0_dm3_tx_de-skew = <7>;
+		cs0_dq24_rx_de-skew = <7>;
+		cs0_dq24_tx_de-skew = <8>;
+		cs0_dq25_rx_de-skew = <7>;
+		cs0_dq25_tx_de-skew = <7>;
+		cs0_dq26_rx_de-skew = <7>;
+		cs0_dq26_tx_de-skew = <7>;
+		cs0_dq27_rx_de-skew = <7>;
+		cs0_dq27_tx_de-skew = <7>;
+		cs0_dq28_rx_de-skew = <7>;
+		cs0_dq28_tx_de-skew = <7>;
+		cs0_dq29_rx_de-skew = <7>;
+		cs0_dq29_tx_de-skew = <7>;
+		cs0_dq30_rx_de-skew = <7>;
+		cs0_dq30_tx_de-skew = <7>;
+		cs0_dq31_rx_de-skew = <7>;
+		cs0_dq31_tx_de-skew = <7>;
+		cs0_dqs3_rx_de-skew = <7>;
+		cs0_dqs3p_tx_de-skew = <9>;
+		cs0_dqs3n_tx_de-skew = <9>;
+
+		cs1_dm0_rx_de-skew = <7>;
+		cs1_dm0_tx_de-skew = <8>;
+		cs1_dq0_rx_de-skew = <7>;
+		cs1_dq0_tx_de-skew = <8>;
+		cs1_dq1_rx_de-skew = <7>;
+		cs1_dq1_tx_de-skew = <8>;
+		cs1_dq2_rx_de-skew = <7>;
+		cs1_dq2_tx_de-skew = <8>;
+		cs1_dq3_rx_de-skew = <7>;
+		cs1_dq3_tx_de-skew = <8>;
+		cs1_dq4_rx_de-skew = <7>;
+		cs1_dq4_tx_de-skew = <8>;
+		cs1_dq5_rx_de-skew = <7>;
+		cs1_dq5_tx_de-skew = <8>;
+		cs1_dq6_rx_de-skew = <7>;
+		cs1_dq6_tx_de-skew = <8>;
+		cs1_dq7_rx_de-skew = <7>;
+		cs1_dq7_tx_de-skew = <8>;
+		cs1_dqs0_rx_de-skew = <6>;
+		cs1_dqs0p_tx_de-skew = <9>;
+		cs1_dqs0n_tx_de-skew = <9>;
+
+		cs1_dm1_rx_de-skew = <7>;
+		cs1_dm1_tx_de-skew = <7>;
+		cs1_dq8_rx_de-skew = <7>;
+		cs1_dq8_tx_de-skew = <8>;
+		cs1_dq9_rx_de-skew = <7>;
+		cs1_dq9_tx_de-skew = <7>;
+		cs1_dq10_rx_de-skew = <7>;
+		cs1_dq10_tx_de-skew = <8>;
+		cs1_dq11_rx_de-skew = <7>;
+		cs1_dq11_tx_de-skew = <7>;
+		cs1_dq12_rx_de-skew = <7>;
+		cs1_dq12_tx_de-skew = <8>;
+		cs1_dq13_rx_de-skew = <7>;
+		cs1_dq13_tx_de-skew = <7>;
+		cs1_dq14_rx_de-skew = <7>;
+		cs1_dq14_tx_de-skew = <8>;
+		cs1_dq15_rx_de-skew = <7>;
+		cs1_dq15_tx_de-skew = <7>;
+		cs1_dqs1_rx_de-skew = <7>;
+		cs1_dqs1p_tx_de-skew = <9>;
+		cs1_dqs1n_tx_de-skew = <9>;
+
+		cs1_dm2_rx_de-skew = <7>;
+		cs1_dm2_tx_de-skew = <8>;
+		cs1_dq16_rx_de-skew = <7>;
+		cs1_dq16_tx_de-skew = <8>;
+		cs1_dq17_rx_de-skew = <7>;
+		cs1_dq17_tx_de-skew = <8>;
+		cs1_dq18_rx_de-skew = <7>;
+		cs1_dq18_tx_de-skew = <8>;
+		cs1_dq19_rx_de-skew = <7>;
+		cs1_dq19_tx_de-skew = <8>;
+		cs1_dq20_rx_de-skew = <7>;
+		cs1_dq20_tx_de-skew = <8>;
+		cs1_dq21_rx_de-skew = <7>;
+		cs1_dq21_tx_de-skew = <8>;
+		cs1_dq22_rx_de-skew = <7>;
+		cs1_dq22_tx_de-skew = <8>;
+		cs1_dq23_rx_de-skew = <7>;
+		cs1_dq23_tx_de-skew = <8>;
+		cs1_dqs2_rx_de-skew = <6>;
+		cs1_dqs2p_tx_de-skew = <9>;
+		cs1_dqs2n_tx_de-skew = <9>;
+
+		cs1_dm3_rx_de-skew = <7>;
+		cs1_dm3_tx_de-skew = <7>;
+		cs1_dq24_rx_de-skew = <7>;
+		cs1_dq24_tx_de-skew = <8>;
+		cs1_dq25_rx_de-skew = <7>;
+		cs1_dq25_tx_de-skew = <7>;
+		cs1_dq26_rx_de-skew = <7>;
+		cs1_dq26_tx_de-skew = <7>;
+		cs1_dq27_rx_de-skew = <7>;
+		cs1_dq27_tx_de-skew = <7>;
+		cs1_dq28_rx_de-skew = <7>;
+		cs1_dq28_tx_de-skew = <7>;
+		cs1_dq29_rx_de-skew = <7>;
+		cs1_dq29_tx_de-skew = <7>;
+		cs1_dq30_rx_de-skew = <7>;
+		cs1_dq30_tx_de-skew = <7>;
+		cs1_dq31_rx_de-skew = <7>;
+		cs1_dq31_tx_de-skew = <7>;
+		cs1_dqs3_rx_de-skew = <7>;
+		cs1_dqs3p_tx_de-skew = <9>;
+		cs1_dqs3n_tx_de-skew = <9>;
+	};
+};
diff --git a/target/linux/rockchip/files/drivers/devfreq/rk3328_dmc.c b/target/linux/rockchip/files/drivers/devfreq/rk3328_dmc.c
new file mode 100644
index 0000000000..72601a0904
--- /dev/null
+++ b/target/linux/rockchip/files/drivers/devfreq/rk3328_dmc.c
@@ -0,0 +1,852 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd.
+ * Author: Lin Huang <hl@rock-chips.com>
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/devfreq.h>
+#include <linux/devfreq-event.h>
+#include <linux/interrupt.h>
+#include <linux/iversion.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/rwsem.h>
+#include <linux/suspend.h>
+#include <linux/version.h>
+
+#include <soc/rockchip/rockchip_sip.h>
+
+#define DTS_PAR_OFFSET		(4096)
+
+struct share_params {
+	u32 hz;
+	u32 lcdc_type;
+	u32 vop;
+	u32 vop_dclk_mode;
+	u32 sr_idle_en;
+	u32 addr_mcu_el3;
+	/*
+	 * 1: need to wait flag1
+	 * 0: never wait flag1
+	 */
+	u32 wait_flag1;
+	/*
+	 * 1: need to wait flag1
+	 * 0: never wait flag1
+	 */
+	u32 wait_flag0;
+	u32 complt_hwirq;
+	/* if need, add parameter after */
+};
+
+static struct share_params *ddr_psci_param;
+
+/* hope this define can adapt all future platform */
+static const char * const rk3328_dts_timing[] = {
+	"ddr3_speed_bin",
+	"ddr4_speed_bin",
+	"pd_idle",
+	"sr_idle",
+	"sr_mc_gate_idle",
+	"srpd_lite_idle",
+	"standby_idle",
+
+	"auto_pd_dis_freq",
+	"auto_sr_dis_freq",
+	"ddr3_dll_dis_freq",
+	"ddr4_dll_dis_freq",
+	"phy_dll_dis_freq",
+
+	"ddr3_odt_dis_freq",
+	"phy_ddr3_odt_dis_freq",
+	"ddr3_drv",
+	"ddr3_odt",
+	"phy_ddr3_ca_drv",
+	"phy_ddr3_ck_drv",
+	"phy_ddr3_dq_drv",
+	"phy_ddr3_odt",
+
+	"lpddr3_odt_dis_freq",
+	"phy_lpddr3_odt_dis_freq",
+	"lpddr3_drv",
+	"lpddr3_odt",
+	"phy_lpddr3_ca_drv",
+	"phy_lpddr3_ck_drv",
+	"phy_lpddr3_dq_drv",
+	"phy_lpddr3_odt",
+
+	"lpddr4_odt_dis_freq",
+	"phy_lpddr4_odt_dis_freq",
+	"lpddr4_drv",
+	"lpddr4_dq_odt",
+	"lpddr4_ca_odt",
+	"phy_lpddr4_ca_drv",
+	"phy_lpddr4_ck_cs_drv",
+	"phy_lpddr4_dq_drv",
+	"phy_lpddr4_odt",
+
+	"ddr4_odt_dis_freq",
+	"phy_ddr4_odt_dis_freq",
+	"ddr4_drv",
+	"ddr4_odt",
+	"phy_ddr4_ca_drv",
+	"phy_ddr4_ck_drv",
+	"phy_ddr4_dq_drv",
+	"phy_ddr4_odt",
+};
+
+static const char * const rk3328_dts_ca_timing[] = {
+	"ddr3a1_ddr4a9_de-skew",
+	"ddr3a0_ddr4a10_de-skew",
+	"ddr3a3_ddr4a6_de-skew",
+	"ddr3a2_ddr4a4_de-skew",
+	"ddr3a5_ddr4a8_de-skew",
+	"ddr3a4_ddr4a5_de-skew",
+	"ddr3a7_ddr4a11_de-skew",
+	"ddr3a6_ddr4a7_de-skew",
+	"ddr3a9_ddr4a0_de-skew",
+	"ddr3a8_ddr4a13_de-skew",
+	"ddr3a11_ddr4a3_de-skew",
+	"ddr3a10_ddr4cs0_de-skew",
+	"ddr3a13_ddr4a2_de-skew",
+	"ddr3a12_ddr4ba1_de-skew",
+	"ddr3a15_ddr4odt0_de-skew",
+	"ddr3a14_ddr4a1_de-skew",
+	"ddr3ba1_ddr4a15_de-skew",
+	"ddr3ba0_ddr4bg0_de-skew",
+	"ddr3ras_ddr4cke_de-skew",
+	"ddr3ba2_ddr4ba0_de-skew",
+	"ddr3we_ddr4bg1_de-skew",
+	"ddr3cas_ddr4a12_de-skew",
+	"ddr3ckn_ddr4ckn_de-skew",
+	"ddr3ckp_ddr4ckp_de-skew",
+	"ddr3cke_ddr4a16_de-skew",
+	"ddr3odt0_ddr4a14_de-skew",
+	"ddr3cs0_ddr4act_de-skew",
+	"ddr3reset_ddr4reset_de-skew",
+	"ddr3cs1_ddr4cs1_de-skew",
+	"ddr3odt1_ddr4odt1_de-skew",
+};
+
+static const char * const rk3328_dts_cs0_timing[] = {
+	"cs0_dm0_rx_de-skew",
+	"cs0_dm0_tx_de-skew",
+	"cs0_dq0_rx_de-skew",
+	"cs0_dq0_tx_de-skew",
+	"cs0_dq1_rx_de-skew",
+	"cs0_dq1_tx_de-skew",
+	"cs0_dq2_rx_de-skew",
+	"cs0_dq2_tx_de-skew",
+	"cs0_dq3_rx_de-skew",
+	"cs0_dq3_tx_de-skew",
+	"cs0_dq4_rx_de-skew",
+	"cs0_dq4_tx_de-skew",
+	"cs0_dq5_rx_de-skew",
+	"cs0_dq5_tx_de-skew",
+	"cs0_dq6_rx_de-skew",
+	"cs0_dq6_tx_de-skew",
+	"cs0_dq7_rx_de-skew",
+	"cs0_dq7_tx_de-skew",
+	"cs0_dqs0_rx_de-skew",
+	"cs0_dqs0p_tx_de-skew",
+	"cs0_dqs0n_tx_de-skew",
+
+	"cs0_dm1_rx_de-skew",
+	"cs0_dm1_tx_de-skew",
+	"cs0_dq8_rx_de-skew",
+	"cs0_dq8_tx_de-skew",
+	"cs0_dq9_rx_de-skew",
+	"cs0_dq9_tx_de-skew",
+	"cs0_dq10_rx_de-skew",
+	"cs0_dq10_tx_de-skew",
+	"cs0_dq11_rx_de-skew",
+	"cs0_dq11_tx_de-skew",
+	"cs0_dq12_rx_de-skew",
+	"cs0_dq12_tx_de-skew",
+	"cs0_dq13_rx_de-skew",
+	"cs0_dq13_tx_de-skew",
+	"cs0_dq14_rx_de-skew",
+	"cs0_dq14_tx_de-skew",
+	"cs0_dq15_rx_de-skew",
+	"cs0_dq15_tx_de-skew",
+	"cs0_dqs1_rx_de-skew",
+	"cs0_dqs1p_tx_de-skew",
+	"cs0_dqs1n_tx_de-skew",
+
+	"cs0_dm2_rx_de-skew",
+	"cs0_dm2_tx_de-skew",
+	"cs0_dq16_rx_de-skew",
+	"cs0_dq16_tx_de-skew",
+	"cs0_dq17_rx_de-skew",
+	"cs0_dq17_tx_de-skew",
+	"cs0_dq18_rx_de-skew",
+	"cs0_dq18_tx_de-skew",
+	"cs0_dq19_rx_de-skew",
+	"cs0_dq19_tx_de-skew",
+	"cs0_dq20_rx_de-skew",
+	"cs0_dq20_tx_de-skew",
+	"cs0_dq21_rx_de-skew",
+	"cs0_dq21_tx_de-skew",
+	"cs0_dq22_rx_de-skew",
+	"cs0_dq22_tx_de-skew",
+	"cs0_dq23_rx_de-skew",
+	"cs0_dq23_tx_de-skew",
+	"cs0_dqs2_rx_de-skew",
+	"cs0_dqs2p_tx_de-skew",
+	"cs0_dqs2n_tx_de-skew",
+
+	"cs0_dm3_rx_de-skew",
+	"cs0_dm3_tx_de-skew",
+	"cs0_dq24_rx_de-skew",
+	"cs0_dq24_tx_de-skew",
+	"cs0_dq25_rx_de-skew",
+	"cs0_dq25_tx_de-skew",
+	"cs0_dq26_rx_de-skew",
+	"cs0_dq26_tx_de-skew",
+	"cs0_dq27_rx_de-skew",
+	"cs0_dq27_tx_de-skew",
+	"cs0_dq28_rx_de-skew",
+	"cs0_dq28_tx_de-skew",
+	"cs0_dq29_rx_de-skew",
+	"cs0_dq29_tx_de-skew",
+	"cs0_dq30_rx_de-skew",
+	"cs0_dq30_tx_de-skew",
+	"cs0_dq31_rx_de-skew",
+	"cs0_dq31_tx_de-skew",
+	"cs0_dqs3_rx_de-skew",
+	"cs0_dqs3p_tx_de-skew",
+	"cs0_dqs3n_tx_de-skew",
+};
+
+static const char * const rk3328_dts_cs1_timing[] = {
+	"cs1_dm0_rx_de-skew",
+	"cs1_dm0_tx_de-skew",
+	"cs1_dq0_rx_de-skew",
+	"cs1_dq0_tx_de-skew",
+	"cs1_dq1_rx_de-skew",
+	"cs1_dq1_tx_de-skew",
+	"cs1_dq2_rx_de-skew",
+	"cs1_dq2_tx_de-skew",
+	"cs1_dq3_rx_de-skew",
+	"cs1_dq3_tx_de-skew",
+	"cs1_dq4_rx_de-skew",
+	"cs1_dq4_tx_de-skew",
+	"cs1_dq5_rx_de-skew",
+	"cs1_dq5_tx_de-skew",
+	"cs1_dq6_rx_de-skew",
+	"cs1_dq6_tx_de-skew",
+	"cs1_dq7_rx_de-skew",
+	"cs1_dq7_tx_de-skew",
+	"cs1_dqs0_rx_de-skew",
+	"cs1_dqs0p_tx_de-skew",
+	"cs1_dqs0n_tx_de-skew",
+
+	"cs1_dm1_rx_de-skew",
+	"cs1_dm1_tx_de-skew",
+	"cs1_dq8_rx_de-skew",
+	"cs1_dq8_tx_de-skew",
+	"cs1_dq9_rx_de-skew",
+	"cs1_dq9_tx_de-skew",
+	"cs1_dq10_rx_de-skew",
+	"cs1_dq10_tx_de-skew",
+	"cs1_dq11_rx_de-skew",
+	"cs1_dq11_tx_de-skew",
+	"cs1_dq12_rx_de-skew",
+	"cs1_dq12_tx_de-skew",
+	"cs1_dq13_rx_de-skew",
+	"cs1_dq13_tx_de-skew",
+	"cs1_dq14_rx_de-skew",
+	"cs1_dq14_tx_de-skew",
+	"cs1_dq15_rx_de-skew",
+	"cs1_dq15_tx_de-skew",
+	"cs1_dqs1_rx_de-skew",
+	"cs1_dqs1p_tx_de-skew",
+	"cs1_dqs1n_tx_de-skew",
+
+	"cs1_dm2_rx_de-skew",
+	"cs1_dm2_tx_de-skew",
+	"cs1_dq16_rx_de-skew",
+	"cs1_dq16_tx_de-skew",
+	"cs1_dq17_rx_de-skew",
+	"cs1_dq17_tx_de-skew",
+	"cs1_dq18_rx_de-skew",
+	"cs1_dq18_tx_de-skew",
+	"cs1_dq19_rx_de-skew",
+	"cs1_dq19_tx_de-skew",
+	"cs1_dq20_rx_de-skew",
+	"cs1_dq20_tx_de-skew",
+	"cs1_dq21_rx_de-skew",
+	"cs1_dq21_tx_de-skew",
+	"cs1_dq22_rx_de-skew",
+	"cs1_dq22_tx_de-skew",
+	"cs1_dq23_rx_de-skew",
+	"cs1_dq23_tx_de-skew",
+	"cs1_dqs2_rx_de-skew",
+	"cs1_dqs2p_tx_de-skew",
+	"cs1_dqs2n_tx_de-skew",
+
+	"cs1_dm3_rx_de-skew",
+	"cs1_dm3_tx_de-skew",
+	"cs1_dq24_rx_de-skew",
+	"cs1_dq24_tx_de-skew",
+	"cs1_dq25_rx_de-skew",
+	"cs1_dq25_tx_de-skew",
+	"cs1_dq26_rx_de-skew",
+	"cs1_dq26_tx_de-skew",
+	"cs1_dq27_rx_de-skew",
+	"cs1_dq27_tx_de-skew",
+	"cs1_dq28_rx_de-skew",
+	"cs1_dq28_tx_de-skew",
+	"cs1_dq29_rx_de-skew",
+	"cs1_dq29_tx_de-skew",
+	"cs1_dq30_rx_de-skew",
+	"cs1_dq30_tx_de-skew",
+	"cs1_dq31_rx_de-skew",
+	"cs1_dq31_tx_de-skew",
+	"cs1_dqs3_rx_de-skew",
+	"cs1_dqs3p_tx_de-skew",
+	"cs1_dqs3n_tx_de-skew",
+};
+
+struct rk3328_ddr_dts_config_timing {
+	unsigned int ddr3_speed_bin;
+	unsigned int ddr4_speed_bin;
+	unsigned int pd_idle;
+	unsigned int sr_idle;
+	unsigned int sr_mc_gate_idle;
+	unsigned int srpd_lite_idle;
+	unsigned int standby_idle;
+
+	unsigned int auto_pd_dis_freq;
+	unsigned int auto_sr_dis_freq;
+	/* for ddr3 only */
+	unsigned int ddr3_dll_dis_freq;
+	/* for ddr4 only */
+	unsigned int ddr4_dll_dis_freq;
+	unsigned int phy_dll_dis_freq;
+
+	unsigned int ddr3_odt_dis_freq;
+	unsigned int phy_ddr3_odt_dis_freq;
+	unsigned int ddr3_drv;
+	unsigned int ddr3_odt;
+	unsigned int phy_ddr3_ca_drv;
+	unsigned int phy_ddr3_ck_drv;
+	unsigned int phy_ddr3_dq_drv;
+	unsigned int phy_ddr3_odt;
+
+	unsigned int lpddr3_odt_dis_freq;
+	unsigned int phy_lpddr3_odt_dis_freq;
+	unsigned int lpddr3_drv;
+	unsigned int lpddr3_odt;
+	unsigned int phy_lpddr3_ca_drv;
+	unsigned int phy_lpddr3_ck_drv;
+	unsigned int phy_lpddr3_dq_drv;
+	unsigned int phy_lpddr3_odt;
+
+	unsigned int lpddr4_odt_dis_freq;
+	unsigned int phy_lpddr4_odt_dis_freq;
+	unsigned int lpddr4_drv;
+	unsigned int lpddr4_dq_odt;
+	unsigned int lpddr4_ca_odt;
+	unsigned int phy_lpddr4_ca_drv;
+	unsigned int phy_lpddr4_ck_cs_drv;
+	unsigned int phy_lpddr4_dq_drv;
+	unsigned int phy_lpddr4_odt;
+
+	unsigned int ddr4_odt_dis_freq;
+	unsigned int phy_ddr4_odt_dis_freq;
+	unsigned int ddr4_drv;
+	unsigned int ddr4_odt;
+	unsigned int phy_ddr4_ca_drv;
+	unsigned int phy_ddr4_ck_drv;
+	unsigned int phy_ddr4_dq_drv;
+	unsigned int phy_ddr4_odt;
+
+	unsigned int ca_skew[15];
+	unsigned int cs0_skew[44];
+	unsigned int cs1_skew[44];
+
+	unsigned int available;
+};
+
+struct rk3328_ddr_de_skew_setting {
+	unsigned int ca_de_skew[30];
+	unsigned int cs0_de_skew[84];
+	unsigned int cs1_de_skew[84];
+};
+
+struct rk3328_dmcfreq {
+	struct device *dev;
+	struct devfreq *devfreq;
+	struct devfreq_simple_ondemand_data ondemand_data;
+	struct clk *dmc_clk;
+	struct devfreq_event_dev *edev;
+	struct mutex lock;
+	struct regulator *vdd_center;
+	unsigned long rate, target_rate;
+	unsigned long volt, target_volt;
+
+	int (*set_auto_self_refresh)(u32 en);
+};
+
+static void
+rk3328_de_skew_setting_2_register(struct rk3328_ddr_de_skew_setting *de_skew,
+				  struct rk3328_ddr_dts_config_timing *tim)
+{
+	u32 n;
+	u32 offset;
+	u32 shift;
+
+	memset_io(tim->ca_skew, 0, sizeof(tim->ca_skew));
+	memset_io(tim->cs0_skew, 0, sizeof(tim->cs0_skew));
+	memset_io(tim->cs1_skew, 0, sizeof(tim->cs1_skew));
+
+	/* CA de-skew */
+	for (n = 0; n < ARRAY_SIZE(de_skew->ca_de_skew); n++) {
+		offset = n / 2;
+		shift = n % 2;
+		/* 0 => 4; 1 => 0 */
+		shift = (shift == 0) ? 4 : 0;
+		tim->ca_skew[offset] &= ~(0xf << shift);
+		tim->ca_skew[offset] |= (de_skew->ca_de_skew[n] << shift);
+	}
+
+	/* CS0 data de-skew */
+	for (n = 0; n < ARRAY_SIZE(de_skew->cs0_de_skew); n++) {
+		offset = ((n / 21) * 11) + ((n % 21) / 2);
+		shift = ((n % 21) % 2);
+		if ((n % 21) == 20)
+			shift = 0;
+		else
+			/* 0 => 4; 1 => 0 */
+			shift = (shift == 0) ? 4 : 0;
+		tim->cs0_skew[offset] &= ~(0xf << shift);
+		tim->cs0_skew[offset] |= (de_skew->cs0_de_skew[n] << shift);
+	}
+
+	/* CS1 data de-skew */
+	for (n = 0; n < ARRAY_SIZE(de_skew->cs1_de_skew); n++) {
+		offset = ((n / 21) * 11) + ((n % 21) / 2);
+		shift = ((n % 21) % 2);
+		if ((n % 21) == 20)
+			shift = 0;
+		else
+			/* 0 => 4; 1 => 0 */
+			shift = (shift == 0) ? 4 : 0;
+		tim->cs1_skew[offset] &= ~(0xf << shift);
+		tim->cs1_skew[offset] |= (de_skew->cs1_de_skew[n] << shift);
+	}
+}
+
+static void of_get_rk3328_timings(struct device *dev,
+				  struct device_node *np, uint32_t *timing)
+{
+	struct device_node *np_tim;
+	u32 *p;
+	struct rk3328_ddr_dts_config_timing *dts_timing;
+	struct rk3328_ddr_de_skew_setting *de_skew;
+	int ret = 0;
+	u32 i;
+
+	dts_timing =
+		(struct rk3328_ddr_dts_config_timing *)(timing +
+							DTS_PAR_OFFSET / 4);
+
+	np_tim = of_parse_phandle(np, "ddr_timing", 0);
+	if (!np_tim) {
+		ret = -EINVAL;
+		goto end;
+	}
+	de_skew = kmalloc(sizeof(*de_skew), GFP_KERNEL);
+	if (!de_skew) {
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	p = (u32 *)dts_timing;
+	for (i = 0; i < ARRAY_SIZE(rk3328_dts_timing); i++) {
+		ret |= of_property_read_u32(np_tim, rk3328_dts_timing[i],
+					p + i);
+	}
+	p = (u32 *)de_skew->ca_de_skew;
+	for (i = 0; i < ARRAY_SIZE(rk3328_dts_ca_timing); i++) {
+		ret |= of_property_read_u32(np_tim, rk3328_dts_ca_timing[i],
+					p + i);
+	}
+	p = (u32 *)de_skew->cs0_de_skew;
+	for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs0_timing); i++) {
+		ret |= of_property_read_u32(np_tim, rk3328_dts_cs0_timing[i],
+					p + i);
+	}
+	p = (u32 *)de_skew->cs1_de_skew;
+	for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs1_timing); i++) {
+		ret |= of_property_read_u32(np_tim, rk3328_dts_cs1_timing[i],
+					p + i);
+	}
+	if (!ret)
+		rk3328_de_skew_setting_2_register(de_skew, dts_timing);
+
+	kfree(de_skew);
+end:
+	if (!ret) {
+		dts_timing->available = 1;
+	} else {
+		dts_timing->available = 0;
+		dev_err(dev, "of_get_ddr_timings: fail\n");
+	}
+
+	of_node_put(np_tim);
+}
+
+static int rockchip_ddr_set_auto_self_refresh(uint32_t en)
+{
+	struct arm_smccc_res res;
+
+	ddr_psci_param->sr_idle_en = en;
+
+	arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ,
+		      SHARE_PAGE_TYPE_DDR, 0, ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR,
+		      0, 0, 0, 0, &res);
+
+	return res.a0;
+}
+
+static int rk3328_dmc_init(struct platform_device *pdev,
+			   struct rk3328_dmcfreq *dmcfreq)
+{
+	struct arm_smccc_res res;
+	u32 size, page_num;
+
+	arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ,
+		      0, 0, ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION,
+		      0, 0, 0, 0, &res);
+	if (res.a0 || (res.a1 < 0x101)) {
+		dev_err(&pdev->dev,
+			"trusted firmware need to update or is invalid\n");
+		return -ENXIO;
+	}
+
+	dev_notice(&pdev->dev, "current ATF version 0x%lx\n", res.a1);
+
+	/*
+	 * first 4KB is used for interface parameters
+	 * after 4KB * N is dts parameters
+	 */
+	size = sizeof(struct rk3328_ddr_dts_config_timing);
+	page_num = DIV_ROUND_UP(size, 4096) + 1;
+
+	arm_smccc_smc(ROCKCHIP_SIP_SHARE_MEM,
+		      page_num, SHARE_PAGE_TYPE_DDR, 0,
+		      0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		dev_err(&pdev->dev, "no ATF memory for init\n");
+		return -ENOMEM;
+	}
+
+	ddr_psci_param = ioremap(res.a1, page_num << 12);
+	of_get_rk3328_timings(&pdev->dev, pdev->dev.of_node,
+			      (uint32_t *)ddr_psci_param);
+
+	arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ,
+		      SHARE_PAGE_TYPE_DDR, 0, ROCKCHIP_SIP_CONFIG_DRAM_INIT,
+		      0, 0, 0, 0, &res);
+	if (res.a0) {
+		dev_err(&pdev->dev, "Rockchip dram init error %lx\n", res.a0);
+		return -ENOMEM;
+	}
+
+	dmcfreq->set_auto_self_refresh = rockchip_ddr_set_auto_self_refresh;
+
+	return 0;
+}
+
+static int rk3328_dmcfreq_target(struct device *dev, unsigned long *freq,
+				 u32 flags)
+{
+	struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev);
+	struct dev_pm_opp *opp;
+	unsigned long old_clk_rate = dmcfreq->rate;
+	unsigned long target_volt, target_rate;
+	int err;
+
+	opp = devfreq_recommended_opp(dev, freq, flags);
+	if (IS_ERR(opp))
+		return PTR_ERR(opp);
+
+	target_rate = dev_pm_opp_get_freq(opp);
+	target_volt = dev_pm_opp_get_voltage(opp);
+	dev_pm_opp_put(opp);
+
+	if (dmcfreq->rate == target_rate)
+		return 0;
+
+	mutex_lock(&dmcfreq->lock);
+
+	/*
+	 * If frequency scaling from low to high, adjust voltage first.
+	 * If frequency scaling from high to low, adjust frequency first.
+	 */
+	if (old_clk_rate < target_rate) {
+		err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,
+					    target_volt);
+		if (err) {
+			dev_err(dev, "Cannot set voltage %lu uV\n",
+				target_volt);
+			goto out;
+		}
+	}
+
+	err = clk_set_rate(dmcfreq->dmc_clk, target_rate);
+	if (err) {
+		dev_err(dev, "Cannot set frequency %lu (%d)\n", target_rate,
+			err);
+		regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,
+				      dmcfreq->volt);
+		goto out;
+	}
+
+	/*
+	 * Check the dpll rate,
+	 * There only two result we will get,
+	 * 1. Ddr frequency scaling fail, we still get the old rate.
+	 * 2. Ddr frequency scaling sucessful, we get the rate we set.
+	 */
+	dmcfreq->rate = clk_get_rate(dmcfreq->dmc_clk);
+
+	/* If get the incorrect rate, set voltage to old value. */
+	if (dmcfreq->rate != target_rate) {
+		dev_err(dev, "Got wrong frequency, Request %lu, Current %lu\n",
+			target_rate, dmcfreq->rate);
+		regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,
+				      dmcfreq->volt);
+		goto out;
+	} else if (old_clk_rate > target_rate)
+		err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,
+					    target_volt);
+	if (err)
+		dev_err(dev, "Cannot set voltage %lu uV\n", target_volt);
+
+	dmcfreq->rate = target_rate;
+	dmcfreq->volt = target_volt;
+
+out:
+	mutex_unlock(&dmcfreq->lock);
+	return err;
+}
+
+static int rk3328_dmcfreq_get_dev_status(struct device *dev,
+					 struct devfreq_dev_status *stat)
+{
+	struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev);
+	struct devfreq_event_data edata;
+	int ret = 0;
+
+	ret = devfreq_event_get_event(dmcfreq->edev, &edata);
+	if (ret < 0)
+		return ret;
+
+	stat->current_frequency = dmcfreq->rate;
+	stat->busy_time = edata.load_count;
+	stat->total_time = edata.total_count;
+
+	return ret;
+}
+
+static int rk3328_dmcfreq_get_cur_freq(struct device *dev, unsigned long *freq)
+{
+	struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev);
+
+	*freq = dmcfreq->rate;
+
+	return 0;
+}
+
+static struct devfreq_dev_profile rk3328_devfreq_dmc_profile = {
+	.polling_ms	= 200,
+	.target		= rk3328_dmcfreq_target,
+	.get_dev_status	= rk3328_dmcfreq_get_dev_status,
+	.get_cur_freq	= rk3328_dmcfreq_get_cur_freq,
+};
+
+static __maybe_unused int rk3328_dmcfreq_suspend(struct device *dev)
+{
+	struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev);
+	int ret = 0;
+
+	ret = devfreq_event_disable_edev(dmcfreq->edev);
+	if (ret < 0) {
+		dev_err(dev, "failed to disable the devfreq-event devices\n");
+		return ret;
+	}
+
+	ret = devfreq_suspend_device(dmcfreq->devfreq);
+	if (ret < 0) {
+		dev_err(dev, "failed to suspend the devfreq devices\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static __maybe_unused int rk3328_dmcfreq_resume(struct device *dev)
+{
+	struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev);
+	int ret = 0;
+
+	ret = devfreq_event_enable_edev(dmcfreq->edev);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable the devfreq-event devices\n");
+		return ret;
+	}
+
+	ret = devfreq_resume_device(dmcfreq->devfreq);
+	if (ret < 0) {
+		dev_err(dev, "failed to resume the devfreq devices\n");
+		return ret;
+	}
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(rk3328_dmcfreq_pm, rk3328_dmcfreq_suspend,
+			 rk3328_dmcfreq_resume);
+
+static int rk3328_dmcfreq_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = pdev->dev.of_node;
+	struct rk3328_dmcfreq *data;
+	struct dev_pm_opp *opp;
+	int ret;
+
+	data = devm_kzalloc(dev, sizeof(struct rk3328_dmcfreq), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	mutex_init(&data->lock);
+
+	data->vdd_center = devm_regulator_get(dev, "center");
+	if (IS_ERR(data->vdd_center)) {
+		if (PTR_ERR(data->vdd_center) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+
+		dev_err(dev, "Cannot get the regulator \"center\"\n");
+		return PTR_ERR(data->vdd_center);
+	}
+
+	data->dmc_clk = devm_clk_get(dev, "dmc_clk");
+	if (IS_ERR(data->dmc_clk)) {
+		if (PTR_ERR(data->dmc_clk) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+
+		dev_err(dev, "Cannot get the clk dmc_clk\n");
+		return PTR_ERR(data->dmc_clk);
+	}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
+	data->edev = devfreq_event_get_edev_by_phandle(dev, 0);
+#else
+	data->edev = devfreq_event_get_edev_by_phandle(dev, "devfreq-events", 0);
+#endif
+	if (IS_ERR(data->edev))
+		return -EPROBE_DEFER;
+
+	ret = devfreq_event_enable_edev(data->edev);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable devfreq-event devices\n");
+		return ret;
+	}
+
+	ret = rk3328_dmc_init(pdev, data);
+	if (ret)
+		return ret;
+
+	/*
+	 * We add a devfreq driver to our parent since it has a device tree node
+	 * with operating points.
+	 */
+	if (dev_pm_opp_of_add_table(dev)) {
+		dev_err(dev, "Invalid operating-points in device tree.\n");
+		return -EINVAL;
+	}
+
+	of_property_read_u32(np, "upthreshold",
+			     &data->ondemand_data.upthreshold);
+	of_property_read_u32(np, "downdifferential",
+			     &data->ondemand_data.downdifferential);
+
+	data->rate = clk_get_rate(data->dmc_clk);
+
+	opp = devfreq_recommended_opp(dev, &data->rate, 0);
+	if (IS_ERR(opp)) {
+		ret = PTR_ERR(opp);
+		goto err_free_opp;
+	}
+
+	data->rate = dev_pm_opp_get_freq(opp);
+	data->volt = dev_pm_opp_get_voltage(opp);
+	dev_pm_opp_put(opp);
+
+	rk3328_devfreq_dmc_profile.initial_freq = data->rate;
+
+	data->devfreq = devm_devfreq_add_device(dev,
+					   &rk3328_devfreq_dmc_profile,
+					   DEVFREQ_GOV_SIMPLE_ONDEMAND,
+					   &data->ondemand_data);
+	if (IS_ERR(data->devfreq)) {
+		ret = PTR_ERR(data->devfreq);
+		goto err_free_opp;
+	}
+
+	devm_devfreq_register_opp_notifier(dev, data->devfreq);
+
+	data->dev = dev;
+	platform_set_drvdata(pdev, data);
+
+	return 0;
+
+err_free_opp:
+	dev_pm_opp_of_remove_table(&pdev->dev);
+	return ret;
+}
+
+static int rk3328_dmcfreq_remove(struct platform_device *pdev)
+{
+	struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev);
+
+	/*
+	 * Before remove the opp table we need to unregister the opp notifier.
+	 */
+	devm_devfreq_unregister_opp_notifier(dmcfreq->dev, dmcfreq->devfreq);
+	dev_pm_opp_of_remove_table(dmcfreq->dev);
+
+	return 0;
+}
+
+static const struct of_device_id rk3328dmc_devfreq_of_match[] = {
+	{ .compatible = "rockchip,rk3328-dmc" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, rk3328dmc_devfreq_of_match);
+
+static struct platform_driver rk3328_dmcfreq_driver = {
+	.probe	= rk3328_dmcfreq_probe,
+	.remove = rk3328_dmcfreq_remove,
+	.driver = {
+		.name	= "rk3328-dmc-freq",
+		.pm	= &rk3328_dmcfreq_pm,
+		.of_match_table = rk3328dmc_devfreq_of_match,
+	},
+};
+module_platform_driver(rk3328_dmcfreq_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Lin Huang <hl@rock-chips.com>");
+MODULE_DESCRIPTION("RK3328 dmcfreq driver with devfreq framework");
diff --git a/target/linux/rockchip/files/include/dt-bindings/clock/rockchip-ddr.h b/target/linux/rockchip/files/include/dt-bindings/clock/rockchip-ddr.h
new file mode 100644
index 0000000000..b065432e77
--- /dev/null
+++ b/target/linux/rockchip/files/include/dt-bindings/clock/rockchip-ddr.h
@@ -0,0 +1,63 @@
+/*
+ *
+ * Copyright (C) 2017 ROCKCHIP, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H
+#define _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H
+
+#define DDR2_DEFAULT	(0)
+
+#define DDR3_800D	(0)	/* 5-5-5 */
+#define DDR3_800E	(1)	/* 6-6-6 */
+#define DDR3_1066E	(2)	/* 6-6-6 */
+#define DDR3_1066F	(3)	/* 7-7-7 */
+#define DDR3_1066G	(4)	/* 8-8-8 */
+#define DDR3_1333F	(5)	/* 7-7-7 */
+#define DDR3_1333G	(6)	/* 8-8-8 */
+#define DDR3_1333H	(7)	/* 9-9-9 */
+#define DDR3_1333J	(8)	/* 10-10-10 */
+#define DDR3_1600G	(9)	/* 8-8-8 */
+#define DDR3_1600H	(10)	/* 9-9-9 */
+#define DDR3_1600J	(11)	/* 10-10-10 */
+#define DDR3_1600K	(12)	/* 11-11-11 */
+#define DDR3_1866J	(13)	/* 10-10-10 */
+#define DDR3_1866K	(14)	/* 11-11-11 */
+#define DDR3_1866L	(15)	/* 12-12-12 */
+#define DDR3_1866M	(16)	/* 13-13-13 */
+#define DDR3_2133K	(17)	/* 11-11-11 */
+#define DDR3_2133L	(18)	/* 12-12-12 */
+#define DDR3_2133M	(19)	/* 13-13-13 */
+#define DDR3_2133N	(20)	/* 14-14-14 */
+#define DDR3_DEFAULT	(21)
+#define DDR_DDR2	(22)
+#define DDR_LPDDR	(23)
+#define DDR_LPDDR2	(24)
+
+#define DDR4_1600J	(0)	/* 10-10-10 */
+#define DDR4_1600K	(1)	/* 11-11-11 */
+#define DDR4_1600L	(2)	/* 12-12-12 */
+#define DDR4_1866L	(3)	/* 12-12-12 */
+#define DDR4_1866M	(4)	/* 13-13-13 */
+#define DDR4_1866N	(5)	/* 14-14-14 */
+#define DDR4_2133N	(6)	/* 14-14-14 */
+#define DDR4_2133P	(7)	/* 15-15-15 */
+#define DDR4_2133R	(8)	/* 16-16-16 */
+#define DDR4_2400P	(9)	/* 15-15-15 */
+#define DDR4_2400R	(10)	/* 16-16-16 */
+#define DDR4_2400U	(11)	/* 18-18-18 */
+#define DDR4_DEFAULT	(12)
+
+#define PAUSE_CPU_STACK_SIZE	16
+
+#endif
diff --git a/target/linux/rockchip/files/include/dt-bindings/memory/rk3328-dram.h b/target/linux/rockchip/files/include/dt-bindings/memory/rk3328-dram.h
new file mode 100644
index 0000000000..171f41c256
--- /dev/null
+++ b/target/linux/rockchip/files/include/dt-bindings/memory/rk3328-dram.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _DT_BINDINGS_DRAM_ROCKCHIP_RK3328_H
+#define _DT_BINDINGS_DRAM_ROCKCHIP_RK3328_H
+
+#define DDR3_DS_34ohm			(34)
+#define DDR3_DS_40ohm			(40)
+
+#define DDR3_ODT_DIS			(0)
+#define DDR3_ODT_40ohm			(40)
+#define DDR3_ODT_60ohm			(60)
+#define DDR3_ODT_120ohm			(120)
+
+#define LP2_DS_34ohm			(34)
+#define LP2_DS_40ohm			(40)
+#define LP2_DS_48ohm			(48)
+#define LP2_DS_60ohm			(60)
+#define LP2_DS_68_6ohm			(68)	/* optional */
+#define LP2_DS_80ohm			(80)
+#define LP2_DS_120ohm			(120)	/* optional */
+
+#define LP3_DS_34ohm			(34)
+#define LP3_DS_40ohm			(40)
+#define LP3_DS_48ohm			(48)
+#define LP3_DS_60ohm			(60)
+#define LP3_DS_80ohm			(80)
+#define LP3_DS_34D_40U			(3440)
+#define LP3_DS_40D_48U			(4048)
+#define LP3_DS_34D_48U			(3448)
+
+#define LP3_ODT_DIS			(0)
+#define LP3_ODT_60ohm			(60)
+#define LP3_ODT_120ohm			(120)
+#define LP3_ODT_240ohm			(240)
+
+#define LP4_PDDS_40ohm			(40)
+#define LP4_PDDS_48ohm			(48)
+#define LP4_PDDS_60ohm			(60)
+#define LP4_PDDS_80ohm			(80)
+#define LP4_PDDS_120ohm			(120)
+#define LP4_PDDS_240ohm			(240)
+
+#define LP4_DQ_ODT_40ohm		(40)
+#define LP4_DQ_ODT_48ohm		(48)
+#define LP4_DQ_ODT_60ohm		(60)
+#define LP4_DQ_ODT_80ohm		(80)
+#define LP4_DQ_ODT_120ohm		(120)
+#define LP4_DQ_ODT_240ohm		(240)
+#define LP4_DQ_ODT_DIS			(0)
+
+#define LP4_CA_ODT_40ohm		(40)
+#define LP4_CA_ODT_48ohm		(48)
+#define LP4_CA_ODT_60ohm		(60)
+#define LP4_CA_ODT_80ohm		(80)
+#define LP4_CA_ODT_120ohm		(120)
+#define LP4_CA_ODT_240ohm		(240)
+#define LP4_CA_ODT_DIS			(0)
+
+#define DDR4_DS_34ohm			(34)
+#define DDR4_DS_48ohm			(48)
+#define DDR4_RTT_NOM_DIS		(0)
+#define DDR4_RTT_NOM_60ohm		(60)
+#define DDR4_RTT_NOM_120ohm		(120)
+#define DDR4_RTT_NOM_40ohm		(40)
+#define DDR4_RTT_NOM_240ohm		(240)
+#define DDR4_RTT_NOM_48ohm		(48)
+#define DDR4_RTT_NOM_80ohm		(80)
+#define DDR4_RTT_NOM_34ohm		(34)
+
+#define PHY_DDR3_RON_RTT_DISABLE	(0)
+#define PHY_DDR3_RON_RTT_451ohm		(1)
+#define PHY_DDR3_RON_RTT_225ohm		(2)
+#define PHY_DDR3_RON_RTT_150ohm		(3)
+#define PHY_DDR3_RON_RTT_112ohm		(4)
+#define PHY_DDR3_RON_RTT_90ohm		(5)
+#define PHY_DDR3_RON_RTT_75ohm		(6)
+#define PHY_DDR3_RON_RTT_64ohm		(7)
+#define PHY_DDR3_RON_RTT_56ohm		(16)
+#define PHY_DDR3_RON_RTT_50ohm		(17)
+#define PHY_DDR3_RON_RTT_45ohm		(18)
+#define PHY_DDR3_RON_RTT_41ohm		(19)
+#define PHY_DDR3_RON_RTT_37ohm		(20)
+#define PHY_DDR3_RON_RTT_34ohm		(21)
+#define PHY_DDR3_RON_RTT_33ohm		(22)
+#define PHY_DDR3_RON_RTT_30ohm		(23)
+#define PHY_DDR3_RON_RTT_28ohm		(24)
+#define PHY_DDR3_RON_RTT_26ohm		(25)
+#define PHY_DDR3_RON_RTT_25ohm		(26)
+#define PHY_DDR3_RON_RTT_23ohm		(27)
+#define PHY_DDR3_RON_RTT_22ohm		(28)
+#define PHY_DDR3_RON_RTT_21ohm		(29)
+#define PHY_DDR3_RON_RTT_20ohm		(30)
+#define PHY_DDR3_RON_RTT_19ohm		(31)
+
+#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE (0)
+#define PHY_DDR4_LPDDR3_RON_RTT_480ohm	(1)
+#define PHY_DDR4_LPDDR3_RON_RTT_240ohm	(2)
+#define PHY_DDR4_LPDDR3_RON_RTT_160ohm	(3)
+#define PHY_DDR4_LPDDR3_RON_RTT_120ohm	(4)
+#define PHY_DDR4_LPDDR3_RON_RTT_96ohm	(5)
+#define PHY_DDR4_LPDDR3_RON_RTT_80ohm	(6)
+#define PHY_DDR4_LPDDR3_RON_RTT_68ohm	(7)
+#define PHY_DDR4_LPDDR3_RON_RTT_60ohm	(16)
+#define PHY_DDR4_LPDDR3_RON_RTT_53ohm	(17)
+#define PHY_DDR4_LPDDR3_RON_RTT_48ohm	(18)
+#define PHY_DDR4_LPDDR3_RON_RTT_43ohm	(19)
+#define PHY_DDR4_LPDDR3_RON_RTT_40ohm	(20)
+#define PHY_DDR4_LPDDR3_RON_RTT_37ohm	(21)
+#define PHY_DDR4_LPDDR3_RON_RTT_34ohm	(22)
+#define PHY_DDR4_LPDDR3_RON_RTT_32ohm	(23)
+#define PHY_DDR4_LPDDR3_RON_RTT_30ohm	(24)
+#define PHY_DDR4_LPDDR3_RON_RTT_28ohm	(25)
+#define PHY_DDR4_LPDDR3_RON_RTT_26ohm	(26)
+#define PHY_DDR4_LPDDR3_RON_RTT_25ohm	(27)
+#define PHY_DDR4_LPDDR3_RON_RTT_24ohm	(28)
+#define PHY_DDR4_LPDDR3_RON_RTT_22ohm	(29)
+#define PHY_DDR4_LPDDR3_RON_RTT_21ohm	(30)
+#define PHY_DDR4_LPDDR3_RON_RTT_20ohm	(31)
+
+#endif /*_DT_BINDINGS_DRAM_ROCKCHIP_RK3328_H*/
diff --git a/target/linux/rockchip/image/Makefile b/target/linux/rockchip/image/Makefile
index f5fdff637f..5791f5c064 100644
--- a/target/linux/rockchip/image/Makefile
+++ b/target/linux/rockchip/image/Makefile
@@ -45,6 +45,26 @@ define Build/pine64-img
 	dd if="$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-u-boot.itb of="$@" seek=16384 conv=notrunc
 endef
 
+define Build/pine64-bin
+	# Typical Rockchip boot flow with Rockchip miniloader
+	# Rockchp idbLoader which is combinded by Rockchip ddr init bin
+	# and miniloader bin from Rockchip rkbin project
+
+	# Generate a new partition table in $@ with 32 MiB of alignment
+	# padding for the idbloader, uboot and trust image to fit:
+	# http://opensource.rock-chips.com/wiki_Boot_option#Boot_flow
+	$(SCRIPT_DIR)/gen_image_generic.sh \
+		$@ \
+		$(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
+		$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
+		32768
+
+	# Copy the idbloader, uboot and trust image to the image at sector 0x40, 0x4000 and 0x6000
+	dd if="$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-idbloader.bin of="$@" seek=64 conv=notrunc
+	dd if="$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-uboot.img of="$@" seek=16384 conv=notrunc
+	dd if="$(STAGING_DIR_IMAGE)"/$(UBOOT_DEVICE_NAME)-trust.bin of="$@" seek=24576 conv=notrunc
+endef
+
 ### Devices ###
 define Device/Default
   PROFILES := Default
diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk
index 24b1c38137..b3ef5a28d4 100644
--- a/target/linux/rockchip/image/armv8.mk
+++ b/target/linux/rockchip/image/armv8.mk
@@ -7,11 +7,21 @@ define Device/friendlyarm_nanopi-r2s
   DEVICE_MODEL := NanoPi R2S
   SOC := rk3328
   UBOOT_DEVICE_NAME := nanopi-r2s-rk3328
-  IMAGE/sysupgrade.img.gz := boot-common | boot-script nanopi-r2s | pine64-img | gzip | append-metadata
+  IMAGE/sysupgrade.img.gz := boot-common | boot-script nanopi-r2s | pine64-bin | gzip | append-metadata
   DEVICE_PACKAGES := kmod-usb-net-rtl8152
 endef
 TARGET_DEVICES += friendlyarm_nanopi-r2s
 
+define Device/friendlyarm_nanopi-r4s
+  DEVICE_VENDOR := FriendlyARM
+  DEVICE_MODEL := NanoPi R4S
+  SOC := rk3399
+  UBOOT_DEVICE_NAME := nanopi-r4s-rk3399
+  IMAGE/sysupgrade.img.gz := boot-common | boot-script nanopi-r4s | pine64-img | gzip | append-metadata
+  DEVICE_PACKAGES := kmod-r8169 -urngd
+endef
+TARGET_DEVICES += friendlyarm_nanopi-r4s
+
 define Device/pine64_rockpro64
   DEVICE_VENDOR := Pine64
   DEVICE_MODEL := RockPro64
diff --git a/target/linux/rockchip/image/nanopi-r4s.bootscript b/target/linux/rockchip/image/nanopi-r4s.bootscript
new file mode 100644
index 0000000000..abe9c24ee3
--- /dev/null
+++ b/target/linux/rockchip/image/nanopi-r4s.bootscript
@@ -0,0 +1,8 @@
+part uuid mmc ${devnum}:2 uuid
+
+setenv bootargs "console=ttyS2,1500000 earlycon=uart8250,mmio32,0xff1a0000 root=PARTUUID=${uuid} rw rootwait"
+
+load mmc ${devnum}:1 ${fdt_addr_r} rockchip.dtb
+load mmc ${devnum}:1 ${kernel_addr_r} kernel.img
+
+booti ${kernel_addr_r} - ${fdt_addr_r}
diff --git a/target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch b/target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
new file mode 100644
index 0000000000..897a42fea2
--- /dev/null
+++ b/target/linux/rockchip/patches-5.10/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
@@ -0,0 +1,25 @@
+From bc6c96d850419e71dbc9b0094ccc9b668ba9be43 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+Date: Mon, 28 Sep 2020 22:54:52 +0200
+Subject: [PATCH] rockchip: rk3328: add compatible to NanoPi R2S ethernet PHY
+
+This adds the compatible property to the NanoPi R2S ethernet PHY node.
+Otherwise, the PHY might not be probed, as the PHY ID reads all 0xff
+when it is still in reset.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+---
+ arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
+@@ -134,6 +134,8
Download .txt
gitextract_5hrojddq/

├── .github/
│   └── workflows/
│       └── openwrt-rockchip.yml
├── .gitignore
├── LICENSE
├── README.md
├── body-origin.md
├── not_use_file/
│   ├── 0002-rockchip-rngd.patch
│   ├── 0003-add_rockchip_k510_support.patch
│   ├── 0003-new_rk33xx_support_with_ARMv8_CE_k5.10.patch
│   ├── 0003-new_rockchip_support_k510.patch
│   ├── 0003-rockchip-fixes-re-boot-with-UHS-cards.patch
│   ├── 0004-add-new-rk33xx-support.patch
│   ├── 0004-uboot-add-r4s-support.patch
│   ├── 0005-target-5.10-r4s-support.patch
│   ├── 0005-target-add-r4s-support.patch
│   ├── 0006-config54.patch
│   ├── 0006-target-5.10-rockchip-support.patch
│   ├── 0009-rockchip-add-support-for-OrangePi-R1-Plus.patch-old
│   ├── 0009-rockchip-introduce-vendor-USB3-inno-driver.patch
│   ├── 0010-rk3328_refresh_usb3_nodes_k5.10.patch
│   ├── 005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch
│   ├── 007-arm64-dts-rockchip-Add-RK3328-idle-state.patch
│   ├── 01-prepare_package.sh
│   ├── 02-convert_translation.sh
│   ├── 1002-add-fullconenat-and-shortcut-fe-support.patch
│   ├── 1002-luci-app-firewall_add_sfe_switch.patch
│   ├── 1003-shortcut-fe.patch
│   ├── 1004-fullconenat.patch
│   ├── 1004-netconntrack.patch
│   ├── 18.06.seed
│   ├── 18.06.sh
│   ├── 2000-zzz-default.patch
│   ├── 2001-ssr-plus-tls-181.patch
│   ├── 2001-ssr-plus-tls.patch
│   ├── 2002-luci-app-freq-r2s.patch
│   ├── 2002-luci-app-freq-r4s.patch
│   ├── 3829.patch
│   ├── 900-add-filter-aaaa-option.patch
│   ├── 911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch
│   ├── 991-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch
│   ├── 998-rockchip-enable-i2c0-on-NanoPi-R2S.patch
│   ├── 999-unlock-1608mhz-rk3328.patch
│   ├── Friendlywrt_archive/
│   │   ├── 000-fullconenat.patch
│   │   ├── 000-kernel-add-full_cone_nat.patch
│   │   ├── 001-cpu-enable_autocore.patch
│   │   ├── 002-enable-O3.patch
│   │   ├── base_rk3328.seed
│   │   ├── check
│   │   ├── check_inet.sh
│   │   ├── defconfig.override
│   │   ├── luci-app-r2sflasher_1.0-4_all.ipk
│   │   ├── opt.seed
│   │   ├── patch_kernel_5.4.sh
│   │   ├── r2s-mwan3.yml
│   │   ├── r2s-opt.yml
│   │   ├── r2s-slim-test.yml
│   │   ├── r2s-slim.yml
│   │   ├── r2s-tiny.yml
│   │   ├── r2s_step/
│   │   │   ├── 00_init_env.sh
│   │   │   ├── 01_friendlywrt.sh
│   │   │   ├── 02_rebase2lean.sh
│   │   │   ├── 03_kernel.sh
│   │   │   ├── 04_fullcone_1.5g.sh
│   │   │   ├── 06_mod_opt.sh
│   │   │   ├── 06_mod_slim.sh
│   │   │   ├── 09_load_config.sh
│   │   │   └── 10_fix_rootfs.sh
│   │   ├── slim.seed
│   │   ├── slim.seed copy
│   │   ├── test.seed
│   │   ├── tiny.seed
│   │   └── update.sh
│   ├── Remove old artifacts.yml
│   ├── Support-hardware-random-number-generator-for-RK3328.patch
│   ├── cleanup.yml
│   ├── cod.seed
│   ├── customization.yml
│   ├── dnsmasq-add-filter-aaaa-option.patch
│   ├── for_r2s_18.06.patch
│   ├── for_r2s_19.07_config-default.patch
│   ├── fullconenat/
│   │   ├── Makefile
│   │   ├── files/
│   │   │   └── Makefile
│   │   └── patches/
│   │       └── 000-printk.patch
│   ├── k5.10.20.patch
│   ├── kernel_crypto-add-rk3328-crypto-support.patch
│   ├── luci-add-filter-aaaa-option.patch
│   ├── luci-app-firewall_add_sfe_switch.patch
│   ├── luci-app-freq.patch
│   ├── luci_network-add-packet-steering.patch
│   ├── modules/
│   │   └── cryptodev-linux/
│   │       └── Makefile
│   ├── nanopi-openwrt copy.yml
│   ├── origin-full.seed
│   ├── origin-full.sh
│   ├── origin-full.yml
│   ├── origin-slim.seed
│   ├── purge-slim.seed
│   ├── purge-slim.yml
│   ├── purge_artifacts.sh
│   ├── r2s-18.06.yml
│   ├── shortcut-fe
│   ├── ssr-plus-tls.patch
│   ├── use_json_object_new_int64.patch
│   ├── zzz-default-settings-18.06
│   ├── zzz.patch
│   └── zzzzz.patch
├── patches/
│   ├── 0000-use_json_object_new_int64.patch
│   ├── 0001-tools-add-upx-ucl-support.patch
│   ├── 0003-rockchip-rk3328-dmc.patch
│   ├── 0004-add-new-rk33xx-support-k510.patch
│   ├── 0006-support-rk33xx-HWRNG.patch
│   ├── 0007-optimize_for_rk3399.patch
│   ├── 0008-mbedtls-Implements-AES-and-GCM-with-ARMv8-Crypto-Ext.patch
│   ├── 0009-rockchip-add-support-for-OrangePi-R1-Plus.patch
│   ├── 1001-dnsmasq_add_filter_aaaa_option.patch
│   ├── 1002-fw3_fullconenat.patch
│   ├── 1003-luci-app-firewall_add_fullcone.patch
│   ├── 2001-add-5.14-support.patch
│   ├── 2002-rockchip-add-5.14-support.patch
│   ├── 2003-mod-for-k514.patch
│   ├── 910-mini-ttl.patch
│   └── 911-dnsmasq-filter-aaaa.patch
├── script/
│   ├── free_disk_space.sh
│   ├── origin-slim.sh
│   ├── step.sh
│   └── zzz-default-settings
├── seed/
│   ├── k514.seed
│   ├── nanopi.seed
│   ├── r2s.seed
│   ├── r4s.seed
│   └── rockchip.seed
└── step/
    ├── 00-prepare_5.10.sh
    ├── 01-prepare_package.sh
    ├── 02-remove_upx.sh
    ├── 03-create_acl_for_luci.sh
    └── 04-k5.14.sh
Condensed preview — 134 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,334K chars).
[
  {
    "path": ".github/workflows/openwrt-rockchip.yml",
    "chars": 8028,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n\nnam"
  },
  {
    "path": ".gitignore",
    "chars": 24,
    "preview": "\n*/.DS_Store\n.DS_Store\n\n"
  },
  {
    "path": "LICENSE",
    "chars": 1064,
    "preview": "MIT License\n\nCopyright (c) 2020 quintus\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
  },
  {
    "path": "README.md",
    "chars": 2019,
    "preview": "## OpenWrt for Rockchip rk3328/rk3399, include Nanopi R2S/R4S and OrangePi R1 plus \n#### ⚠ WARNING: USE IT UNDER YOUR OW"
  },
  {
    "path": "body-origin.md",
    "chars": 98,
    "preview": "***OpenWRT master with Kernel 5.10 daily update***\nsupport: nanopi-r2s nanopi-r4s orangepi-r1-plus"
  },
  {
    "path": "not_use_file/0002-rockchip-rngd.patch",
    "chars": 9734,
    "preview": "From a13fecb3fdaf3ed707400d6950dd8934304ba563 Mon Sep 17 00:00:00 2001\nFrom: CN_SZTL <cnsztl@project-openwrt.eu.org>\nDat"
  },
  {
    "path": "not_use_file/0003-add_rockchip_k510_support.patch",
    "chars": 72828,
    "preview": "From 6ecff10072972d26d4b63c007516d4b8cd0cb07d Thu Mar 4 5:25:25 2021\nFrom: quintus-lab<noreply@github.com>\nDate: Thu, 4 "
  },
  {
    "path": "not_use_file/0003-new_rk33xx_support_with_ARMv8_CE_k5.10.patch",
    "chars": 159495,
    "preview": "From b569c89c51e21a9c4bc753e466e19aebde2b7b8b Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Wed, "
  },
  {
    "path": "not_use_file/0003-new_rockchip_support_k510.patch",
    "chars": 191973,
    "preview": "From 1f116553b6f685b0ab0303174e1d6ff73c85459f Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Fri, "
  },
  {
    "path": "not_use_file/0003-rockchip-fixes-re-boot-with-UHS-cards.patch",
    "chars": 3079,
    "preview": "From 390f2248dfa3a38dc33ee2219b4dcc581dadcf8d Mon Sep 17 00:00:00 2001\nFrom: Tianling Shen <cnsztl@gmail.com>\nDate: Fri,"
  },
  {
    "path": "not_use_file/0004-add-new-rk33xx-support.patch",
    "chars": 17855,
    "preview": "From f9a68930750e4b87888d6e20747a5438f3d3b1a3 Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Fri, "
  },
  {
    "path": "not_use_file/0004-uboot-add-r4s-support.patch",
    "chars": 30888,
    "preview": "From 2f05db8da23df42444ea353a012ae23ab4ddd4f2 Mon Sep 17 00:00:00 2001\nFrom: Tianling Shen <cnsztl@gmail.com>\nDate: Sat,"
  },
  {
    "path": "not_use_file/0005-target-5.10-r4s-support.patch",
    "chars": 4246,
    "preview": "diff --git a/target/linux/rockchip/Makefile b/target/linux/rockchip/Makefile\nindex bcc0cc3f8f..4996b434f0 100644\n--- a/t"
  },
  {
    "path": "not_use_file/0005-target-add-r4s-support.patch",
    "chars": 11786,
    "preview": "From 8c841a734925e412a343d6ddf21bc22b2c850c5a Mon Sep 17 00:00:00 2001\nFrom: Tianling Shen <cnsztl@gmail.com>\nDate: Fri,"
  },
  {
    "path": "not_use_file/0006-config54.patch",
    "chars": 4312,
    "preview": "diff --git a/target/linux/rockchip/armv8/config-5.4 b/target/linux/rockchip/armv8/config-5.4\nindex bea1dbc741..479cc53d0"
  },
  {
    "path": "not_use_file/0006-target-5.10-rockchip-support.patch",
    "chars": 22045,
    "preview": "diff --git a/target/linux/rockchip/armv8/config-5.10 b/target/linux/rockchip/armv8/config-5.10\nindex d7755ba3f5..ebb5ed3"
  },
  {
    "path": "not_use_file/0009-rockchip-add-support-for-OrangePi-R1-Plus.patch-old",
    "chars": 19806,
    "preview": "From dff6e56482e3e4af56f344e4ffe851ffe619852f Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Fri, "
  },
  {
    "path": "not_use_file/0009-rockchip-introduce-vendor-USB3-inno-driver.patch",
    "chars": 41139,
    "preview": "From dd3e76a173e3070b875b61186d363ba1097035df Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Mon, "
  },
  {
    "path": "not_use_file/0010-rk3328_refresh_usb3_nodes_k5.10.patch",
    "chars": 14887,
    "preview": "From fabf22f2188e53ab30d97ad90f6df6ba5e523cae Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Tue, "
  },
  {
    "path": "not_use_file/005-rockchip-rk3328-add-compatible-to-NanoPi-R2S-etherne.patch",
    "chars": 900,
    "preview": "From bc6c96d850419e71dbc9b0094ccc9b668ba9be43 Mon Sep 17 00:00:00 2001\nFrom: David Bauer <mail@david-bauer.net>\nDate: Mo"
  },
  {
    "path": "not_use_file/007-arm64-dts-rockchip-Add-RK3328-idle-state.patch",
    "chars": 2234,
    "preview": "From 4f279f9fbca54464173240f7e73b145a136dfa1e Mon Sep 17 00:00:00 2001\nFrom: Robin Murphy <robin.murphy@arm.com>\nDate: S"
  },
  {
    "path": "not_use_file/01-prepare_package.sh",
    "chars": 18099,
    "preview": "#!/bin/bash\nclear\n\n#Use 19.07 feed source\nrm -f ./feeds.conf.default\nwget https://raw.githubusercontent.com/openwrt/open"
  },
  {
    "path": "not_use_file/02-convert_translation.sh",
    "chars": 1679,
    "preview": "#!/bin/bash\n# [CTCGFW]Project-OpenWrt\n# Use it under GPLv3, please.\n# --------------------------------------------------"
  },
  {
    "path": "not_use_file/1002-add-fullconenat-and-shortcut-fe-support.patch",
    "chars": 20863,
    "preview": "From 1efde71dce5d30c64579afbfab265a4a3cf22cb3 Mon Sep 17 00:00:00 2001\nFrom: Quintus Chu <noreply@github.com>\nDate: Sat,"
  },
  {
    "path": "not_use_file/1002-luci-app-firewall_add_sfe_switch.patch",
    "chars": 3419,
    "preview": "From: QiuSimons\ndiff --git a/feeds/luci/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones."
  },
  {
    "path": "not_use_file/1003-shortcut-fe.patch",
    "chars": 2832,
    "preview": "From 3f2af23a85a931de429ddf632cbd64c470401d8b Mon Sep 17 00:00:00 2001\nFrom: Quintus Chu <ardanzhu@gmail.com>\nDate: Tue,"
  },
  {
    "path": "not_use_file/1004-fullconenat.patch",
    "chars": 4757,
    "preview": "From ad32f898937d6491eab35ef72b97f323e8fb256e Mon Sep 17 00:00:00 2001\nFrom: Quintus Chu <31897806+ardanzhu@users.norepl"
  },
  {
    "path": "not_use_file/1004-netconntrack.patch",
    "chars": 9028,
    "preview": "diff --git a/target/linux/generic/hack-5.10/952-net-conntrack-events-support-multiple-registrant.patch b/target/linux/ge"
  },
  {
    "path": "not_use_file/18.06.seed",
    "chars": 6806,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_rockchip_armv8_DEVICE_friendlyarm_nanopi-r2s=y\nCON"
  },
  {
    "path": "not_use_file/18.06.sh",
    "chars": 2320,
    "preview": "#!/bin/bash\nclear\n#生成时间\nVersionDate=$(git show -s --date=short --format=\"%cd\")\necho \"::set-env name=VersionDate::$Versio"
  },
  {
    "path": "not_use_file/2000-zzz-default.patch",
    "chars": 4762,
    "preview": "diff --git a/package/lean/default-settings/Makefile b/package/lean/default-settings/Makefile\nindex 9869b2511e..2e4696065"
  },
  {
    "path": "not_use_file/2001-ssr-plus-tls-181.patch",
    "chars": 1507,
    "preview": "diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gentrojanconfig.lua b/package/lean/luci-app-ssr-"
  },
  {
    "path": "not_use_file/2001-ssr-plus-tls.patch",
    "chars": 1489,
    "preview": "diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua b/package/lean/luci-app-ssr-plus/"
  },
  {
    "path": "not_use_file/2002-luci-app-freq-r2s.patch",
    "chars": 407,
    "preview": "diff --git a/package/lean/luci-app-cpufreq/root/etc/config/cpufreq b/package/lean/luci-app-cpufreq/root/etc/config/cpufr"
  },
  {
    "path": "not_use_file/2002-luci-app-freq-r4s.patch",
    "chars": 529,
    "preview": "diff --git a/package/lean/luci-app-cpufreq/root/etc/config/cpufreq b/package/lean/luci-app-cpufreq/root/etc/config/cpufr"
  },
  {
    "path": "not_use_file/3829.patch",
    "chars": 2804,
    "preview": "From d520ddaf0ad7243da7c95e638dff77e3c5496c54 Mon Sep 17 00:00:00 2001\nFrom: Tianling Shen <cnsztl@gmail.com>\nDate: Mon,"
  },
  {
    "path": "not_use_file/900-add-filter-aaaa-option.patch",
    "chars": 2100,
    "preview": "diff -rNEZbwBdu3 a/src/dnsmasq.h b/src/dnsmasq.h\n--- a/src/dnsmasq.h\t2020-04-09 00:32:53.000000000 +0800\n+++ b/src/dnsma"
  },
  {
    "path": "not_use_file/911-kernel-dma-adjust-default-coherent_pool-to-2MiB.patch",
    "chars": 722,
    "preview": "From 16bdf3e76fec6ddb44f1fcf221139fb39d225031 Mon Sep 17 00:00:00 2001\nFrom: Igor Pecovnik <igor.pecovnik@gmail.com>\nDat"
  },
  {
    "path": "not_use_file/991-rockchip-rk3399-overclock-to-2.2-1.8-GHz-for-NanoPi4.patch",
    "chars": 4016,
    "preview": "From 04202df5cb497b1934c95211cf43784ef62245a4 Mon Sep 17 00:00:00 2001\nFrom: Tianling Shen <cnsztl@gmail.com>\nDate: Sat,"
  },
  {
    "path": "not_use_file/998-rockchip-enable-i2c0-on-NanoPi-R2S.patch",
    "chars": 349,
    "preview": "From: QiuSimons\ndiff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts b/arch/arm64/boot/dts/rockchip/rk3328-na"
  },
  {
    "path": "not_use_file/999-unlock-1608mhz-rk3328.patch",
    "chars": 599,
    "preview": "From: QiuSimons\ndiff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi\nindex 8"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/000-fullconenat.patch",
    "chars": 10892,
    "preview": "diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig\nindex f17b402111ce..99f691a677a1 100644\n--- a/net/i"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/000-kernel-add-full_cone_nat.patch",
    "chars": 1927,
    "preview": "diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig\nindex f17b402111ce..99f691a677a1 100644\n--- a/net/i"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/001-cpu-enable_autocore.patch",
    "chars": 2547,
    "preview": "diff --git a/package/lean/autocore/Makefile b/package/lean/autocore/Makefile\nindex 5a3ea11..1f52537 100644\n--- a/package"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/002-enable-O3.patch",
    "chars": 726,
    "preview": "From 8e4c45742cfca87c0cc44e7969ab8826be9139be Mon Sep 17 00:00:00 2001\nFrom: \"Jan Alexander Steffens (heftig)\" <jan.stef"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/base_rk3328.seed",
    "chars": 1939,
    "preview": "CONFIG_AUTOREMOVE=y\nCONFIG_BRCMFMAC_SDIO=y\nCONFIG_DRIVER_11AC_SUPPORT=y\nCONFIG_DRIVER_11N_SUPPORT=y\nCONFIG_DRIVER_11W_SU"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/check",
    "chars": 108,
    "preview": "#!/bin/sh /etc/rc.common\n\nSTART=99\n \nstart() {\n    nohup /bin/sh /usr/bin/check_inet.sh 1>/dev/null 2>&1 &\n}"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/check_inet.sh",
    "chars": 1721,
    "preview": "#!/bin/sh\n# Copyright (c) 2020, Chuck <fanck0605@qq.com>\n#\n# this script is writing for openwrt\n# this script need the i"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/defconfig.override",
    "chars": 2106,
    "preview": "CONFIG_ATM_BR2684_IPFILTER=y\nCONFIG_ATM_CLIP_NO_ICMP=y\nCONFIG_ARM64_ERRATUM_826319=y\nCONFIG_ARM64_ERRATUM_827319=y\nCONFI"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/opt.seed",
    "chars": 3432,
    "preview": "CONFIG_LUCI_LANG_zh-cn=y\nCONFIG_LUCI_LANG_zh-tw=y\n\n#wireless card support\nCONFIG_PACKAGE_hostapd=y\nCONFIG_PACKAGE_hostap"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/patch_kernel_5.4.sh",
    "chars": 1141,
    "preview": "cd friendlywrt-rk3328\ncd kernel/\ngit apply ../../r2s/add_fullconenat.diff\nwget https://github.com/armbian/build/raw/mast"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s-mwan3.yml",
    "chars": 4520,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n# Au"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s-opt.yml",
    "chars": 3939,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n# Au"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s-slim-test.yml",
    "chars": 4351,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n# Au"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s-slim.yml",
    "chars": 3787,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n# Au"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s-tiny.yml",
    "chars": 3760,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n# Au"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s_step/00_init_env.sh",
    "chars": 963,
    "preview": "#!/bin/bash\nclear\nsudo rm -rf /etc/apt/sources.list.d\nsudo apt-get update\nsudo apt-get -y --no-install-recommends instal"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s_step/01_friendlywrt.sh",
    "chars": 486,
    "preview": "#!/bin/bash\nexport TERM=linux\ngit clone https://github.com/friendlyarm/repo\nsudo cp repo/repo /usr/bin/\nrm -rf friendlyw"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s_step/02_rebase2lean.sh",
    "chars": 641,
    "preview": "#!/bin/bash\nclear\ncd friendlywrt-rk3328/friendlywrt/\ngit config --local user.email \"action@github.com\" && git config --l"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s_step/03_kernel.sh",
    "chars": 962,
    "preview": "#!/bin/bash\nexport TERM=linux\ncd friendlywrt-rk3328/kernel\ngit config --local user.email \"action@github.com\" && git conf"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s_step/04_fullcone_1.5g.sh",
    "chars": 443,
    "preview": "#!/bin/bash\nclear\nexport TERM=linux\ncd friendlywrt-rk3328/kernel/\nwget -O net/netfilter/xt_FULLCONENAT.c https://raw.git"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s_step/06_mod_opt.sh",
    "chars": 4790,
    "preview": "#!/bin/bash\nclear\nexport TERM=linux\n#进入friendlywrt目录\ncd friendlywrt-rk3328/friendlywrt/\n#增加防掉线脚本\nmv ../../script/check_i"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s_step/06_mod_slim.sh",
    "chars": 3945,
    "preview": "#!/bin/bash\nclear\nexport TERM=linux\n#进入friendlywrt目录\ncd friendlywrt-rk3328/friendlywrt/\n#增加防掉线脚本\nmv ../../script/check_i"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s_step/09_load_config.sh",
    "chars": 686,
    "preview": "#!/bin/bash\nexport TERM=linux\ncd friendlywrt-rk3328\n#deconfig\n#wget https://github.com/fanck0605/nanopi-r2s/raw/lean/nan"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/r2s_step/10_fix_rootfs.sh",
    "chars": 374,
    "preview": "#!/bin/bash\nexport TERM=linux\nsudo df -lh\nlodev=$(sudo losetup -f)\necho \"found unused loop dev $lodev\"\nsudo losetup -P $"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/slim.seed",
    "chars": 2468,
    "preview": "CONFIG_LUCI_LANG_zh-cn=y\n#luci-app\nCONFIG_PACKAGE_luci-app-ddns=y\nCONFIG_PACKAGE_ddns-scripts_cloudflare.com-v4=y\nCONFIG"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/slim.seed copy",
    "chars": 2215,
    "preview": "CONFIG_LUCI_LANG_zh-cn=y\nCONFIG_LUCI_LANG_zh-tw=y\n#wireless card support\nCONFIG_PACKAGE_hostapd=y\nCONFIG_PACKAGE_hostapd"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/test.seed",
    "chars": 3970,
    "preview": "CONFIG_LUCI_LANG_zh-cn=y\n#wireless card support\nCONFIG_PACKAGE_kmod-usb-net=y\nCONFIG_PACKAGE_kmod-usb-net-rtl8150=y\nCONF"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/tiny.seed",
    "chars": 1109,
    "preview": "CONFIG_LUCI_LANG_zh-cn=y\n#luci-app\nCONFIG_PACKAGE_luci-app-ddns=y\nCONFIG_PACKAGE_ddns-scripts_cloudflare.com-v4=y\nCONFIG"
  },
  {
    "path": "not_use_file/Friendlywrt_archive/update.sh",
    "chars": 11272,
    "preview": "#!/bin/sh\n\nrom=0; \t#rom值若为0,则会出现可选菜单,也可手动改为1-3,将不会出现选项\nbackup=0; \t#backup值若为0,则会出现可选菜单,也可手动改为1-3,将不会出现选项\nmode=0; \t#mode值"
  },
  {
    "path": "not_use_file/Remove old artifacts.yml",
    "chars": 501,
    "preview": "name: Remove old artifacts\n\non:\n  push:\n    branches:\n      - master\n    paths:\n      - '.github/workflows/Remove old ar"
  },
  {
    "path": "not_use_file/Support-hardware-random-number-generator-for-RK3328.patch",
    "chars": 16185,
    "preview": "From e5b5361651940ff5c0c1784dfd0130abec7ab535 Mon Sep 17 00:00:00 2001\nFrom: wevsty <ty@wevs.org>\nDate: Mon, 24 Aug 2020"
  },
  {
    "path": "not_use_file/cleanup.yml",
    "chars": 922,
    "preview": "name: cleanup space\n\non:\n#  release:\n#    types: published\n  push:\n    paths:\n      - '.github/workflows/cleanup.yml'\n  "
  },
  {
    "path": "not_use_file/cod.seed",
    "chars": 8865,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_rockchip_armv8_DEVICE_friendlyelec_nanopi-r2-rev00"
  },
  {
    "path": "not_use_file/customization.yml",
    "chars": 4705,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n# Au"
  },
  {
    "path": "not_use_file/dnsmasq-add-filter-aaaa-option.patch",
    "chars": 1514,
    "preview": "From 23ddcf0e475059b9111d3f321a1a340cf1b48698 Mon Sep 17 00:00:00 2001\nFrom: Chuck <fanck0605@qq.com>\nDate: Thu, 28 May "
  },
  {
    "path": "not_use_file/for_r2s_18.06.patch",
    "chars": 6604,
    "preview": "diff --git a/package/lean/luci-app-cpufreq/root/etc/config/cpufreq b/package/lean/luci-app-cpufreq/root/etc/config/cpufr"
  },
  {
    "path": "not_use_file/for_r2s_19.07_config-default.patch",
    "chars": 5791,
    "preview": "diff --git a/target/linux/rockchip/armv8/config-5.4 b/target/linux/rockchip/armv8/config-5.4\nindex d7256a84a1..d09c03a1a"
  },
  {
    "path": "not_use_file/fullconenat/Makefile",
    "chars": 2130,
    "preview": "#\n# Copyright (C) 2018 Chion Tang <tech@chionlab.moe>\n#\n# This is free software, licensed under the GNU General Public L"
  },
  {
    "path": "not_use_file/fullconenat/files/Makefile",
    "chars": 428,
    "preview": "all: libipt_FULLCONENAT.so libip6t_FULLCONENAT.so\nlibipt_FULLCONENAT.so: libipt_FULLCONENAT.o\n\t$(CC) -shared -lxtables -"
  },
  {
    "path": "not_use_file/fullconenat/patches/000-printk.patch",
    "chars": 686,
    "preview": "diff --git a/xt_FULLCONENAT.c b/xt_FULLCONENAT.c\nindex 9e52eba..8658c5f 100644\n--- a/xt_FULLCONENAT.c\n+++ b/xt_FULLCONEN"
  },
  {
    "path": "not_use_file/k5.10.20.patch",
    "chars": 763,
    "preview": "diff --git a/include/kernel-version.mk b/include/kernel-version.mk\nindex 9fbd861440..33fe6b2d0e 100644\n--- a/include/ker"
  },
  {
    "path": "not_use_file/kernel_crypto-add-rk3328-crypto-support.patch",
    "chars": 1065,
    "preview": "From 7662626ba699090aa3ec98e9d406e7b056703438 Mon Sep 17 00:00:00 2001\nFrom: CN_SZTL <cnsztl@project-openwrt.eu.org>\nDat"
  },
  {
    "path": "not_use_file/luci-add-filter-aaaa-option.patch",
    "chars": 1254,
    "preview": "From d5714003b9ba288b45e6866472315a99230292f5 Mon Sep 17 00:00:00 2001\nFrom: Chuck <fanck0605@qq.com>\nDate: Wed, 3 Jun 2"
  },
  {
    "path": "not_use_file/luci-app-firewall_add_sfe_switch.patch",
    "chars": 3419,
    "preview": "From: QiuSimons\ndiff --git a/feeds/luci/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones."
  },
  {
    "path": "not_use_file/luci-app-freq.patch",
    "chars": 515,
    "preview": "diff --git a/package/lean/luci-app-cpufreq/root/etc/config/cpufreq b/package/lean/luci-app-cpufreq/root/etc/config/cpufr"
  },
  {
    "path": "not_use_file/luci_network-add-packet-steering.patch",
    "chars": 808,
    "preview": "diff -rNEZbwBdu3 a/feeds/luci/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js b/feeds/l"
  },
  {
    "path": "not_use_file/modules/cryptodev-linux/Makefile",
    "chars": 1642,
    "preview": "#\n# Copyright (C) 2014 OpenWrt.org\n#\n# This is free software, licensed under the GNU General Public License v2.\n# See /L"
  },
  {
    "path": "not_use_file/nanopi-openwrt copy.yml",
    "chars": 4763,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n\nnam"
  },
  {
    "path": "not_use_file/origin-full.seed",
    "chars": 8310,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_rockchip_armv8_DEVICE_friendlyelec_nanopi-r2-rev00"
  },
  {
    "path": "not_use_file/origin-full.sh",
    "chars": 1159,
    "preview": "#!/bin/bash\ngit clone https://git.openwrt.org/openwrt/openwrt.git\ncd openwrt\nwget https://github.com/quintus-lab/Openwrt"
  },
  {
    "path": "not_use_file/origin-full.yml",
    "chars": 4812,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n# Au"
  },
  {
    "path": "not_use_file/origin-slim.seed",
    "chars": 8981,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_rockchip_armv8_DEVICE_friendlyarm_nanopi-r2s=y\nCON"
  },
  {
    "path": "not_use_file/purge-slim.seed",
    "chars": 9003,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_rockchip_armv8_DEVICE_friendlyarm_nanopi-r2s=y\nCON"
  },
  {
    "path": "not_use_file/purge-slim.yml",
    "chars": 4974,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n# Au"
  },
  {
    "path": "not_use_file/purge_artifacts.sh",
    "chars": 1849,
    "preview": "#!/bin/bash\n\n# Customize those three lines with your repository and credentials:\nREPO=https://api.github.com/repos/${GIT"
  },
  {
    "path": "not_use_file/r2s-18.06.yml",
    "chars": 4738,
    "preview": "#=================================================\n# Description: Build OpenWrt using GitHub Actions\n# Lisence: MIT\n# Au"
  },
  {
    "path": "not_use_file/shortcut-fe",
    "chars": 1984,
    "preview": "#!/bin/sh /etc/rc.common\n#\n# Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.\n# Permission to use, cop"
  },
  {
    "path": "not_use_file/ssr-plus-tls.patch",
    "chars": 1489,
    "preview": "diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua b/package/lean/luci-app-ssr-plus/"
  },
  {
    "path": "not_use_file/use_json_object_new_int64.patch",
    "chars": 1055,
    "preview": "From f0972c84d9ed457ba9b430792c4809bc6207399a Mon Sep 17 00:00:00 2001\nFrom: lisaac <lisaac.cn@gmail.com>\nDate: Fri, 27 "
  },
  {
    "path": "not_use_file/zzz-default-settings-18.06",
    "chars": 2828,
    "preview": "#!/bin/sh\n\n#uci set luci.main.mediaurlbase='/luci-static/argon'\n#uci commit luci\n\nuci set system.@system[0].timezone=CST"
  },
  {
    "path": "not_use_file/zzz.patch",
    "chars": 4563,
    "preview": "diff --git a/package/lean/default-settings/Makefile b/package/lean/default-settings/Makefile\nindex 858587f71f..c7bb45ede"
  },
  {
    "path": "not_use_file/zzzzz.patch",
    "chars": 4802,
    "preview": "diff --git a/package/lean/default-settings/Makefile b/package/lean/default-settings/Makefile\nindex 858587f71f..c7bb45ede"
  },
  {
    "path": "patches/0000-use_json_object_new_int64.patch",
    "chars": 1055,
    "preview": "From f0972c84d9ed457ba9b430792c4809bc6207399a Mon Sep 17 00:00:00 2001\nFrom: lisaac <lisaac.cn@gmail.com>\nDate: Fri, 27 "
  },
  {
    "path": "patches/0001-tools-add-upx-ucl-support.patch",
    "chars": 3851,
    "preview": "From 70e08dad563e9520459faa0aef00a5e3645a796c Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Fri, "
  },
  {
    "path": "patches/0003-rockchip-rk3328-dmc.patch",
    "chars": 84272,
    "preview": "From 8d6cb03b0df27ce167d83f8b855a9621aaf9ee19 Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Fri, "
  },
  {
    "path": "patches/0004-add-new-rk33xx-support-k510.patch",
    "chars": 29733,
    "preview": "From 9a8da8467bb9d616cfc5fc26408ca6cf973271cf Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Fri, "
  },
  {
    "path": "patches/0006-support-rk33xx-HWRNG.patch",
    "chars": 14112,
    "preview": "From 20a000fb007a9b79bca43304689bd4813784ae78 Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Fri, "
  },
  {
    "path": "patches/0007-optimize_for_rk3399.patch",
    "chars": 793,
    "preview": "diff --git a/include/target.mk b/include/target.mk\nindex edc6a146de..e7217c6181 100644\n--- a/include/target.mk\n+++ b/inc"
  },
  {
    "path": "patches/0008-mbedtls-Implements-AES-and-GCM-with-ARMv8-Crypto-Ext.patch",
    "chars": 17709,
    "preview": "From 9fcf01be4e89e72887b58253ba5d2b2601bad7dc Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Tue, "
  },
  {
    "path": "patches/0009-rockchip-add-support-for-OrangePi-R1-Plus.patch",
    "chars": 21596,
    "preview": "From b677e175936397ffcc3592d4ef5af20343bd7b8f Mon Sep 17 00:00:00 2001\nFrom: Quintus Chu <ardanzhu@gmail.com>\nDate: Mon,"
  },
  {
    "path": "patches/1001-dnsmasq_add_filter_aaaa_option.patch",
    "chars": 3249,
    "preview": "From 2b6c77d13d06d2b316041af74b99c602a4e8256d Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Mon, "
  },
  {
    "path": "patches/1002-fw3_fullconenat.patch",
    "chars": 2799,
    "preview": "From b8be603976ff0ff22d60c873f6cb1b25db558250 Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Mon, "
  },
  {
    "path": "patches/1003-luci-app-firewall_add_fullcone.patch",
    "chars": 716,
    "preview": "From: QiuSimons\ndiff --git a/feeds/luci/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones."
  },
  {
    "path": "patches/2001-add-5.14-support.patch",
    "chars": 924894,
    "preview": "From 4dc54e1d98c74d1e7b770e3296edc7d8cd75a5d9 Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Wed, "
  },
  {
    "path": "patches/2002-rockchip-add-5.14-support.patch",
    "chars": 88933,
    "preview": "From f1d636e628e5b30517d07902d67410d532139e79 Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Thu, "
  },
  {
    "path": "patches/2003-mod-for-k514.patch",
    "chars": 5564,
    "preview": "From 612fec9271b6dcffe2ff2e6a60c5fbb3fbd9f7c4 Mon Sep 17 00:00:00 2001\nFrom: quintus-lab<noreply@github.com>\nDate: Tue, "
  },
  {
    "path": "patches/910-mini-ttl.patch",
    "chars": 4352,
    "preview": "--- a/src/dnsmasq.h\n+++ b/src/dnsmasq.h\n@@ -1116,7 +1116,7 @@ extern struct daemon {\n   int max_logs;  /* queue limit */"
  },
  {
    "path": "patches/911-dnsmasq-filter-aaaa.patch",
    "chars": 2267,
    "preview": "From 966471712184cfb3b067f2ae8dad9d8e2a896cae Mon Sep 17 00:00:00 2001\nFrom: Bearice Ren <bearice@icybear.net>\nDate: Tue"
  },
  {
    "path": "script/free_disk_space.sh",
    "chars": 1880,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE f"
  },
  {
    "path": "script/origin-slim.sh",
    "chars": 1160,
    "preview": "\n#!/bin/bash\ngit clone https://git.openwrt.org/openwrt/openwrt.git\ncd openwrt\nwget https://github.com/quintus-lab/Openwr"
  },
  {
    "path": "script/step.sh",
    "chars": 10105,
    "preview": "git clone https://git.openwrt.org/openwrt/openwrt.git\n\ncd openwrt\ngit config --local user.email \"action@github.com\" && g"
  },
  {
    "path": "script/zzz-default-settings",
    "chars": 2592,
    "preview": "#!/bin/sh\n\n#uci set luci.main.mediaurlbase='/luci-static/argon'\n#uci commit luci\n\nuci set system.@system[0].timezone=CST"
  },
  {
    "path": "seed/k514.seed",
    "chars": 13934,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_MULTI_PROFILE=y\nCONFIG_TARGET_DEVICE_rockchip_armv"
  },
  {
    "path": "seed/nanopi.seed",
    "chars": 13680,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_MULTI_PROFILE=y\nCONFIG_TARGET_DEVICE_rockchip_armv"
  },
  {
    "path": "seed/r2s.seed",
    "chars": 12515,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_rockchip_armv8_DEVICE_friendlyarm_nanopi-r2s=y\nCON"
  },
  {
    "path": "seed/r4s.seed",
    "chars": 12944,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_rockchip_armv8_DEVICE_friendlyarm_nanopi-r4s=y\nCON"
  },
  {
    "path": "seed/rockchip.seed",
    "chars": 13959,
    "preview": "CONFIG_TARGET_rockchip=y\nCONFIG_TARGET_rockchip_armv8=y\nCONFIG_TARGET_MULTI_PROFILE=y\nCONFIG_TARGET_DEVICE_rockchip_armv"
  },
  {
    "path": "step/00-prepare_5.10.sh",
    "chars": 1782,
    "preview": "#!/bin/bash\nclear\n#Update feed\n#sed -i '4s/src-git/#src-git/g' ./feeds.conf.default\n#sed -i '5s/src-git/#src-git/g' ./fe"
  },
  {
    "path": "step/01-prepare_package.sh",
    "chars": 2703,
    "preview": "#!/bin/bash\nclear\n\n# remove other coremark\nrm -rf feeds/packages/utils/coremark\nrm -rf package/feeds/packages/coremark\n."
  },
  {
    "path": "step/02-remove_upx.sh",
    "chars": 328,
    "preview": "#!/bin/bash\n# [CTCGFW]Project-OpenWrt\n# Use it under GPLv3, please.\n# --------------------------------------------------"
  },
  {
    "path": "step/03-create_acl_for_luci.sh",
    "chars": 3004,
    "preview": "#!/bin/bash\n# [CTCGFW]Project-OpenWrt\n# Use it under GPLv3, please.\n# --------------------------------------------------"
  },
  {
    "path": "step/04-k5.14.sh",
    "chars": 249,
    "preview": "#!/bin/bash\nclear\n#add kernel 5.14 support\npatch -p1 < ../patches/2001-add-5.14-support.patch\n#add rockchip 5.14 support"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the quintus-lab/openwrt-rockchip GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 134 files (2.1 MB), approximately 559.1k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!