[Feature][T8TSK-304] merge mtk official patch 5th AP patch release
--bsp,kernel part

Only Configure: No
Affected branch: N/A
Affected module: N/A
Is it affected on both ZXIC and MTK: only MTK
Self-test: Yes
Doc Update: No

Change-Id: I178a62705346db5188af3159e31f660d27c6df35
diff --git a/prebuilt/bsp/hsm/private/crypto/mt2735/hsm-crypto-dev-1.0.0-r0.aarch64.rpm b/prebuilt/bsp/hsm/private/crypto/mt2735/hsm-crypto-dev-1.0.0-r0.aarch64.rpm
index 444786d..1a3e15b 100644
--- a/prebuilt/bsp/hsm/private/crypto/mt2735/hsm-crypto-dev-1.0.0-r0.aarch64.rpm
+++ b/prebuilt/bsp/hsm/private/crypto/mt2735/hsm-crypto-dev-1.0.0-r0.aarch64.rpm
Binary files differ
diff --git a/prebuilt/bsp/hsm/private/crypto/mt2735/hsm-crypto-staticdev-1.0.0-r0.aarch64.rpm b/prebuilt/bsp/hsm/private/crypto/mt2735/hsm-crypto-staticdev-1.0.0-r0.aarch64.rpm
index 5bac365..0975e50 100644
--- a/prebuilt/bsp/hsm/private/crypto/mt2735/hsm-crypto-staticdev-1.0.0-r0.aarch64.rpm
+++ b/prebuilt/bsp/hsm/private/crypto/mt2735/hsm-crypto-staticdev-1.0.0-r0.aarch64.rpm
Binary files differ
diff --git a/prebuilt/devtools/aee/aee-1.0-r0.aarch64_prop_gcc_glibc_2.28.rpm b/prebuilt/devtools/aee/aee-1.0-r0.aarch64_prop_gcc_glibc_2.28.rpm
index fd5ad8f..27dfb2e 100644
--- a/prebuilt/devtools/aee/aee-1.0-r0.aarch64_prop_gcc_glibc_2.28.rpm
+++ b/prebuilt/devtools/aee/aee-1.0-r0.aarch64_prop_gcc_glibc_2.28.rpm
Binary files differ
diff --git a/src/bsp/lk/app/blxboot/avb.c b/src/bsp/lk/app/blxboot/avb.c
index 008794b..0ff1873 100755
--- a/src/bsp/lk/app/blxboot/avb.c
+++ b/src/bsp/lk/app/blxboot/avb.c
@@ -26,11 +26,6 @@
 #include <libavb/libavb.h>
 #include <libavb_ab/libavb_ab.h>
 
-
-//xf.li@2023410 add for ab rooback start
-//#include <lib/bootctrl.h>
-//#include <platform.h>
-//xf.li@2023410 add for ab rooback end
 #include <platform/mmc_rpmb.h>
 #include <sys/types.h>
 #include <string.h>
@@ -413,21 +408,9 @@
     AvbSlotVerifyResult verify_result;
     const char *requested_partitions[] = { part_name, NULL };
     const char *ab_suffix = get_suffix() ? : "";
-    int current_slot = -1;
 
     verify_result = avb_slot_verify(&avbops,requested_partitions,ab_suffix,is_device_unlocked(),AVB_HASHTREE_ERROR_MODE_RESTART,verifyData);
     dprintf(CRITICAL, "avb boot verification result is %s\n",avb_slot_verify_result_to_string(verify_result));
-/*
-//xf.li@20230313 modify for ab_rollback start
-    if(verify_result == AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION && avb_strcmp(part_name,"boot") == 0)
-    {
-        dprintf(ALWAYS, "BOOTCTRL: hash verification is error\n");
-        current_slot = get_current_slot();
-        dprintf(ALWAYS, "BOOTCTRL: current_slot: %d. reboot\n" ,current_slot);
-        mark_slot_unsuccessful(current_slot);
-    }
-//xf.li@20230313 modify for ab_rollback end
-*/
     if (verify_result == AVB_SLOT_VERIFY_RESULT_OK) {
         verify_result = avb_update_rollback_indexes(&avbops,*verifyData);
         dprintf(CRITICAL, "avb boot rollback indexes result is %s\n",avb_slot_verify_result_to_string(verify_result));
diff --git a/src/bsp/lk/app/blxboot/imagelist.c b/src/bsp/lk/app/blxboot/imagelist.c
index fdda944..2ff41e9 100755
--- a/src/bsp/lk/app/blxboot/imagelist.c
+++ b/src/bsp/lk/app/blxboot/imagelist.c
@@ -32,7 +32,6 @@
 #include <string.h>
 #include <sys/types.h>
 #include <trace.h>
-//#include <lib/bootctrl.h>
 
 #include "avb.h"
 #include "blxboot_ab.h"
@@ -617,21 +616,11 @@
 static int load_fit_image(const char *part_name, struct imageinfo_t *img)
 {
     int err;
-    /*
-    int current_slot = -1;
 
-    dprintf(CRITICAL, "LYNQ: load_fit_image part_name %s\n",part_name);*/
     if ((err = fit_get_image(part_name, &img->imgdata->buf)) == 0) {
         err = fit_load_images(img->imgdata->buf, img->imgdata, true);
     }
-    /*
-    if(err != 0 && ((strcmp(part_name,"bl33_a") == 0) || (strcmp(part_name,"bl33_b") == 0)))
-    {
-        dprintf(ALWAYS, "BL33_load: hash verification is error\n");
-        current_slot = get_current_slot();
-        dprintf(ALWAYS, "BL33_load: current_slot: %d. reboot\n" ,current_slot);
-        mark_slot_unsuccessful(current_slot);
-    }*/
+
     return err;
 }
 
diff --git a/src/bsp/lk/lib/aee/mrdump_aee.c b/src/bsp/lk/lib/aee/mrdump_aee.c
index ddc57f2..2cd8938 100644
--- a/src/bsp/lk/lib/aee/mrdump_aee.c
+++ b/src/bsp/lk/lib/aee/mrdump_aee.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2018 MediaTek Inc.
  *
@@ -41,8 +42,8 @@
 #include <string.h>
 #ifdef MTK_PMIC_FULL_RESET
 #include <platform/pmic.h>
-#include <platform/spmi/pmif.h> //jb.qi change for reboot when sleep on 20230309
-#include <platform/spmi/spmi.h> //jb.qi change for reboot when sleep on 20230309
+#include <platform/spmi/pmif.h>
+#include <platform/spmi/spmi.h>
 #endif
 
 #include "aee.h"
@@ -441,8 +442,8 @@
     voprintf_debug("Ready for full pmic reset\n");
     mrdump_write_result();
     pmif_spmi_init(SPMI_MASTER_1);
-    pmic_reinit();         //jb.qi change for reboot when sleep on 20230309
-    pmic_cold_reset();     //jb.qi change for reboot when sleep on 20230309
+    pmic_reinit();
+    pmic_cold_reset();
 #else
     voprintf_debug("Ready for reset\n");
     mrdump_write_result();
diff --git a/src/bsp/lk/lib/aee/mrdump_setup.c b/src/bsp/lk/lib/aee/mrdump_setup.c
index 649812a..60a87a2 100755
--- a/src/bsp/lk/lib/aee/mrdump_setup.c
+++ b/src/bsp/lk/lib/aee/mrdump_setup.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2018 MediaTek Inc.
  *
diff --git a/src/bsp/lk/platform/mediatek/common/arch/arm/mp.c b/src/bsp/lk/platform/mediatek/common/arch/arm/mp.c
deleted file mode 120000
index a2426e7..0000000
--- a/src/bsp/lk/platform/mediatek/common/arch/arm/mp.c
+++ /dev/null
@@ -1 +0,0 @@
-../arm64/mp.c
\ No newline at end of file
diff --git a/src/bsp/lk/platform/mediatek/common/arch/arm/mp.c b/src/bsp/lk/platform/mediatek/common/arch/arm/mp.c
new file mode 100644
index 0000000..03b134b
--- /dev/null
+++ b/src/bsp/lk/platform/mediatek/common/arch/arm/mp.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ *
+ * Use of this source code is governed by a MIT-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/MIT
+ */
+
+#include <arch/arch_ops.h>
+#include <arch/mp.h>
+#include <arch/mp_mediatek.h>
+#include <arch/ops.h>
+#include <assert.h>
+#include <compiler.h>
+#include <debug.h>
+#include <dev/interrupt/arm_gic.h>
+#include <err.h>
+#include <kernel/event.h>
+#include <kernel/mp.h>
+#include <kernel/thread.h>
+#include <lk/init.h>
+#include <platform/interrupts.h>
+#include <platform/psci.h>
+#include <sys/types.h>
+#include <trace.h>
+
+#if LK_AS_BL33 == 0
+#error "MTK BL2 does not support SMP yet!"
+#endif
+
+#define LOCAL_TRACE 0
+
+/*
+ * [platform smp note]
+ * Platform should add platform specific stuff to support smp:
+ * 1. define following SMP constants in platform specific makefile,
+ *      SMP_MAX_CPUS:
+ *          Max number of cpus to be used
+ *      SMP_CPU_CLUSTER_SHIFT:
+ *          Bits to shift for cluster to form linear cpu id.
+ *          For example, if at most 4 cores in a cluster, set this to 2.
+ * 2. add "struct smp_cpu_info smp_cpu" in platform code.
+ * 3. implement void platform_quiesce(void) to call plat_mp_off().
+ * 4. optional: add PLAT_GIC_IPI_BASE to GLOBAL_DEFINES constant in makefile
+ *    if platform required IPI base other than 0.
+ */
+
+/* set PLAT_GIC_IPI_BASE to non-secure interrupt base */
+#if !defined(PLAT_GIC_IPI_BASE)
+#define PLAT_GIC_IPI_BASE   0
+#endif
+
+#define MAX_IPI_NUM 15
+enum {
+    MTK_PLAT_MP_IPI_GENERIC = MP_IPI_GENERIC,
+    MTK_PLAT_MP_IPI_RESCHEDULE = MP_IPI_RESCHEDULE,
+    MTK_PLAT_MP_IPI_CUSTOM_START,
+};
+
+STATIC_ASSERT(MTK_PLAT_MP_IPI_CUSTOM_START <= MAX_IPI_NUM);
+
+
+status_t plat_mp_send_ipi(mp_cpu_mask_t target, uint ipi)
+{
+    LTRACEF_LEVEL(2, "target 0x%x, ipi %u\n", target, ipi);
+
+    uint gic_ipi_num = ipi + PLAT_GIC_IPI_BASE;
+
+    /* filter out targets outside of the range of cpus we care about */
+    target &= ((1UL << SMP_MAX_CPUS) - 1);
+    if (target != 0) {
+        LTRACEF_LEVEL(2, "target 0x%x, gic_ipi %u\n", target, gic_ipi_num);
+        arm_gic_sgi(gic_ipi_num, ARM_GIC_SGI_FLAG_NS, target);
+    }
+
+    return NO_ERROR;
+}
+
+status_t arch_mp_send_ipi(mp_cpu_mask_t target, mp_ipi_t ipi)
+{
+    return plat_mp_send_ipi(target, ipi);
+}
+
+void arch_mp_init_percpu(void)
+{
+    extern enum handler_return arm_ipi_generic_handler(void *arg);
+    extern enum handler_return arm_ipi_reschedule_handler(void *arg);
+
+    register_int_handler(MTK_PLAT_MP_IPI_GENERIC + PLAT_GIC_IPI_BASE,
+            &arm_ipi_generic_handler, 0);
+    register_int_handler(MTK_PLAT_MP_IPI_RESCHEDULE + PLAT_GIC_IPI_BASE,
+            &arm_ipi_reschedule_handler, 0);
+
+    unmask_interrupt(MTK_PLAT_MP_IPI_GENERIC + PLAT_GIC_IPI_BASE);
+    unmask_interrupt(MTK_PLAT_MP_IPI_RESCHEDULE + PLAT_GIC_IPI_BASE);
+}
+
+static int cpu_off_thread(void *arg)
+{
+    int ret;
+
+    arch_disable_ints();
+
+    THREAD_LOCK(state);
+    mp_set_curr_cpu_active(false);
+    THREAD_UNLOCK(state);
+
+    /* executed by the to-be-off cpu */
+    ret = psci_cpu_off(); /* should never return */
+    DEBUG_ASSERT(ret && 0);
+
+    return -1;
+}
+
+__WEAK void plat_pre_cpu_on(void)
+{
+}
+
+static void plat_mp_on(uint level)
+{
+    extern struct smp_cpu_info smp_cpu;
+    int i, ret;
+    uint32_t local_cpu = arch_curr_cpu_num();
+    uint32_t cpu_on_mask = smp_cpu.cpu_on_mask & ~(1U << local_cpu);
+
+    plat_pre_cpu_on(); /* preprocess cpu if necessary */
+
+    for (i = 0; i < SMP_MAX_CPUS; i++) {
+        if (cpu_on_mask & (1 << i)) {
+            ret = psci_cpu_on(smp_cpu.id[i], MEMBASE + KERNEL_LOAD_OFFSET, 0);
+            LTRACEF("plat_mp_on cpu=0x%x, ret=%d, entry=%x\n",
+                    smp_cpu.id[i], ret, MEMBASE + KERNEL_LOAD_OFFSET);
+        }
+    }
+}
+
+void plat_mp_off(void)
+{
+    mp_cpu_mask_t target = 0;
+    uint32_t local_cpu = arch_curr_cpu_num();
+    thread_t *t;
+    uint32_t cpu;
+
+    for (cpu = 0; cpu < SMP_MAX_CPUS; cpu++) {
+        if (mp_is_cpu_active(cpu) && (cpu != local_cpu)) {
+            t = thread_create("cpu_off_thread", &cpu_off_thread, NULL,
+                              DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
+            thread_set_pinned_cpu(t, cpu);
+            thread_detach_and_resume(t);
+            target |= (1 << cpu);
+        }
+    }
+
+    plat_mp_send_ipi(target, MTK_PLAT_MP_IPI_RESCHEDULE);
+}
+
+struct handover_struct {
+    event_t *ev;
+    uint32_t cpu;
+};
+
+static int handover_worker(void *arg)
+{
+    struct handover_struct *handover = (struct handover_struct *)arg;
+    event_t *ev;
+    uint32_t cpu;
+
+    LTRACEF("cpu=%u\n", arch_curr_cpu_num());
+
+    DEBUG_ASSERT(handover != NULL);
+
+    /* handover worker send reschedule ipi to designated cpu if necessary */
+    cpu = handover->cpu;
+    ev = handover->ev;
+    while (event_wait_timeout(ev, 1) != NO_ERROR)
+        plat_mp_send_ipi((1 << cpu), MTK_PLAT_MP_IPI_RESCHEDULE);
+
+    return 0;
+}
+
+void plat_mp_bootcpu_handover(uint32_t cpu)
+{
+    struct handover_struct handover;
+    thread_t *curr_thread;
+    thread_t *handover_thread;
+    event_t handover_ev;
+
+    DEBUG_ASSERT(!arch_ints_disabled());
+
+    curr_thread = get_current_thread();
+    LTRACEF("handover %s from cpu %u to cpu %u\n",
+            curr_thread->name, arch_curr_cpu_num(), cpu);
+
+    if (arch_curr_cpu_num() == cpu)
+        return;
+
+    if (!mp_is_cpu_active(cpu)) {
+        LTRACEF("handover cpu=%u is not active.\n", cpu);
+        return;
+    }
+
+    event_init(&handover_ev, false, EVENT_FLAG_AUTOUNSIGNAL);
+    handover.cpu = cpu;
+    handover.ev = &handover_ev;
+
+    /* let current cpu executes handover thread, so designated cpu could
+     * have chance to execute blxboot_task thread */
+    handover_thread = thread_create("handover_thread",
+                                    &handover_worker, &handover,
+                                    DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
+    DEBUG_ASSERT(handover_thread != NULL);
+    if (handover_thread == NULL)
+        return;
+
+    thread_set_pinned_cpu(handover_thread, arch_curr_cpu_num());
+    thread_resume(handover_thread);
+
+    /* pin blxboot_task thread to the designated cpu */
+    thread_set_pinned_cpu(curr_thread, cpu);
+
+    /* if the current cpu is not the designated cpu, yield */
+    if (arch_curr_cpu_num() != cpu)
+        thread_yield();
+
+    /* program reaches here must be executed by the designated cpu */
+    event_signal(&handover_ev, false);
+    thread_join(handover_thread, NULL, INFINITE_TIME);
+    event_destroy(&handover_ev);
+
+    LTRACEF("new cpu=%u\n", arch_curr_cpu_num());
+}
+
+LK_INIT_HOOK(plat_mp_on, &plat_mp_on, LK_INIT_LEVEL_THREADING);
diff --git a/src/bsp/lk/platform/mt2735/drivers/dpm/dpm.h b/src/bsp/lk/platform/mt2735/drivers/dpm/dpm.h
index 37cc34f..9a97572 100644
--- a/src/bsp/lk/platform/mt2735/drivers/dpm/dpm.h
+++ b/src/bsp/lk/platform/mt2735/drivers/dpm/dpm.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2020 MediaTek Inc.
  *
@@ -13,35 +14,35 @@
 #include <platform/mt_typedefs.h>
 #include <string.h>
 #include <stdlib.h>
-/*jb.qi change for reboot when sleep on 20230309 start*/
-#if 0 
+
+#if 0
 #define DPM_CFG_CH0_BASE         (0x10940000)
 #define DRAMC_CH0_TOP5_BASE      (0x10238000)
 #define DPM_PM_SRAM_BASE         (0x10900000)
 #define DPM_DM_SRAM_BASE         (0x10920000)
 #endif
-/*jb.qi change for reboot when sleep on 20230309 end*/
-#define DPM_VERSION              (0x00000001)  // DPM version     jb.qi change for reboot when sleep on 20230309
-#define DPM_HWID                 (0x00002735)  // DPM HWID        jb.qi change for reboot when sleep on 20230309
+
+#define DPM_VERSION              (0x00000001)  // DPM version
+#define DPM_HWID                 (0x00002735)  // DPM HWID
 #define DPM_NUM                  (0x00000001)  // DPM number
-#define DPM_HEAD_SIZE            (0x00000024)  // DPM header size jb.qi change for reboot when sleep on 20230309
+#define DPM_HEAD_SIZE            (0x00000024)  // DPM header size
 #define DPM_DBG_LEN              (0x48)        // dpm dbg latch
 #define DPM_CFG1_LEN             (0x14)        // dpm cfg1 latch
 #define DPM_CFG2_LEN             (0x8)         // dpm cfg2 latch
 #define DRAM_CHANNEL             (0x2)         // dramc AO latch
 #define DDRPHY_LATCH_LEN         (0x20)        // ddrphy AO latch
-#define LATCH_PC_NUM             0x10    // dpm last 16 pc        jb.qi change for reboot when sleep on 20230309
+#define LATCH_PC_NUM             0x10    // dpm last 16 pc
 
 #define DPM_CFG_CH0              DPM_CFG_CH0_BASE
 #define DPM_DBG_LATCH_CH0_OFST   (0x7380)
 #define DPM_CFG1_CH0_OFST        (0x0064)
 #define DPM_CFG2_CH0_OFST        (0x014C)
-/*jb.qi change for reboot when sleep on 20230309 start*/
+
 #define SSPM_CFGREG_TBUF_SEL     ((DPM_CFG_CH0_BASE) + 0x178)
 #define SSPM_CFGREG_TBUFL        ((DPM_CFG_CH0_BASE) + 0x17C)
 #define SSPM_CFGREG_TBUFH        ((DPM_CFG_CH0_BASE) + 0x180)
 #define SSPM_CFGREG_TBUF_WPTR    ((DPM_CFG_CH0_BASE) + 0x4C)
-/*jb.qi change for reboot when sleep on 20230309 end*/
+
 #define DDRPHY_AO_CH0            DRAMC_CH0_TOP5_BASE
 #define DDRPHY_LATCH_OFFSET      (0x1600)
 #define CHANNEL_OFFSET           (0x10000)
diff --git a/src/bsp/lk/platform/mt2735/drivers/dpm/dpm_aee.h b/src/bsp/lk/platform/mt2735/drivers/dpm/dpm_aee.h
index e9e4d44..c7a382f 100644
--- a/src/bsp/lk/platform/mt2735/drivers/dpm/dpm_aee.h
+++ b/src/bsp/lk/platform/mt2735/drivers/dpm/dpm_aee.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2020 MediaTek Inc.
  *
@@ -14,11 +15,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-//#define DPM_CFG_CH0_BASE         (0x10940000+KERNEL_ASPACE_BASE)
-//#define DRAMC_CH0_TOP5_BASE      (0x10238000+KERNEL_ASPACE_BASE)
-//#define DPM_PM_SRAM_BASE         (0x10900000+KERNEL_ASPACE_BASE)
-//#define DPM_DM_SRAM_BASE         (0x10920000+KERNEL_ASPACE_BASE)
-
 #define DPM_VERSION              (0x00000001)  // DPM version
 #define DPM_HWID                 (0x00002735)  // DPM HWID
 #define DPM_NUM                  (0x00000001)  // DPM number
diff --git a/src/bsp/lk/platform/mt2735/drivers/dpm/dpm_aee_dump.c b/src/bsp/lk/platform/mt2735/drivers/dpm/dpm_aee_dump.c
index 3b0864e..56552fd 100644
--- a/src/bsp/lk/platform/mt2735/drivers/dpm/dpm_aee_dump.c
+++ b/src/bsp/lk/platform/mt2735/drivers/dpm/dpm_aee_dump.c
@@ -17,18 +17,17 @@
 #include <platform/mtk_wdt.h>
 #include <stdbool.h>
 #define DPM_DBG_MODE           (1)
-#define LOCAL_TRACE 1
+#define LOCAL_TRACE 0
 #if DPM_DBG_MODE
 #define dpm_dbg(f, ...)        dprintf(ALWAYS, "[DPM][DBG] " f, ##__VA_ARGS__)
 #else
-#define dpm_dbg(f, ...)        do{}while(0)
+#define dpm_dbg(f, ...)        do{ }while(0)
 #endif
 #define dpm_error(f, ...)      dprintf(CRITICAL, "[DPM][ERROR] " f, ##__VA_ARGS__)
 #define DOWNLOAD_KEY           "download:"
 #define MAX_SIZE               (20)
 
-static void wake_dpm_sram_up(void)
-{
+static void wake_dpm_sram_up(void) {
     addr_t reg = SPM_BASE + DRAMC_MCU_SPM_CON_OFST;
 
     DRV_WriteReg32(reg, DRV_Reg32(reg) | DRAMC_MCU_SRAM_SLEEP_B_LSB);
@@ -38,8 +37,7 @@
     DRV_WriteReg32(reg, DRV_Reg32(reg) | DRAMC_MCU_SRAM_ISOINT_B_LSB);
 }
 
-static unsigned int set_dpm_header(unsigned char *buf)
-{
+static unsigned int set_dpm_header(unsigned char *buf) {
     unsigned int version = DPM_VERSION;
     unsigned int hw_id = DPM_HWID;
     unsigned int nr_dpm = DPM_NUM;
@@ -67,17 +65,17 @@
                       version, hw_id, nr_dpm, nr_channel,
                       coredump_sz, lpif_sz, cfg_sz,
 #if DPM_VERSION >= 1
-						last_pc_sz,
+                      last_pc_sz,
 #endif
-						dram_sz);
+                      dram_sz);
     return length;
 }
-static void save_dpm_reg(AEE_DUMP_CALLBACK dev_write)
-{
+
+static void save_dpm_reg(AEE_DUMP_CALLBACK dev_write) {
     unsigned char *buf = malloc(DPM_REG_DUMP_SIZE);
 #if DPM_VERSION >= 1
     unsigned int *pc_latch = NULL;
-	int j = 0;
+    int j = 0;
 #endif
     unsigned int addr = 0;
     unsigned int channel_index = 0;
@@ -90,54 +88,48 @@
     }
     datasize += set_dpm_header(buf);
     dpm_dbg("[dpm] set_dpm_header datasize: 0x%x\n", datasize);
-	dpm_dbg("[dpm]1 : 0x%x\n",DPM_CFG_CH0_BASE + DPM_DBG_LATCH_CH0_OFST);
-	dpm_dbg("[dpm]  read:0x%x\n", readl(DPM_CFG_CH0_BASE + DPM_DBG_LATCH_CH0_OFST));
+
     addr = DPM_CFG_CH0_BASE + DPM_DBG_LATCH_CH0_OFST;
-    dpm_dbg("[dpm] DPM_DBG_LATCH_CH0_OFST[0]: 0x%x\n", readl(DPM_CFG_CH0_BASE + DPM_DBG_LATCH_CH0_OFST));
     for (int i = 0; i < DPM_DBG_LEN; i += sizeof(unsigned int))
         datasize += sprintf(buf+datasize, "0x%08x: 0x%08x\n", addr + i,
                             readl(DPM_CFG_CH0_BASE + DPM_DBG_LATCH_CH0_OFST + i));
     addr = DPM_CFG_CH0_BASE + DPM_CFG1_CH0_OFST;
-    dpm_dbg("[dpm] DPM_CFG1_CH0_OFST[0]: 0x%x\n", readl(DPM_CFG_CH0_BASE + DPM_CFG1_CH0_OFST));
     for (int i = 0; i < DPM_CFG1_LEN; i += sizeof(unsigned int))
         datasize += sprintf(buf+datasize, "0x%08x: 0x%08x\n", addr + i,
                             readl(DPM_CFG_CH0_BASE + DPM_CFG1_CH0_OFST + i));
     addr = DPM_CFG_CH0_BASE + DPM_CFG2_CH0_OFST;
-    dpm_dbg("[dpm] DPM_CFG2_CH0_OFST[0]: 0x%x\n", readl(DPM_CFG_CH0_BASE + DPM_CFG2_CH0_OFST));
     for (int i = 0; i < DPM_CFG2_LEN; i += sizeof(unsigned int))
         datasize += sprintf(buf+datasize, "0x%08x: 0x%08x\n", addr + i,
                             readl(DPM_CFG_CH0_BASE + DPM_CFG2_CH0_OFST + i));
     for (channel_index = 0; channel_index < DRAM_CHANNEL; channel_index++) {
-        //ddrphy RG
+        // ddrphy RG
         addr = DDRPHY_AO_CH0 + channel_index * CHANNEL_OFFSET + DDRPHY_LATCH_OFFSET;
-        dpm_dbg("[dpm] DDRPHY_LATCH_OFFSET[0]: 0x%x\n", readl(DDRPHY_AO_CH0 + channel_index * CHANNEL_OFFSET + DDRPHY_LATCH_OFFSET));
         for (int i = 0; i < DDRPHY_LATCH_LEN; i += sizeof(unsigned int))
             datasize += sprintf(buf+datasize, "0x%08x: 0x%08x\n", DDRPHY_AO_CH0 + channel_index * CHANNEL_OFFSET + DDRPHY_LATCH_OFFSET + i,
                                 readl(DDRPHY_AO_CH0 + channel_index * CHANNEL_OFFSET + DDRPHY_LATCH_OFFSET + i));
     }
 
 #if DPM_VERSION >= 1
-	dprintf(CRITICAL, "DPM last 16 pc dump !\n");
-	for (j = 0; j < LATCH_PC_NUM; j++) {
-		writel(j, SSPM_CFGREG_TBUF_SEL);
+    dprintf(CRITICAL, "DPM last 16 pc dump !\n");
+    for (j = 0; j < LATCH_PC_NUM; j++) {
+        writel(j, SSPM_CFGREG_TBUF_SEL);
         datasize += sprintf(buf+datasize, "SSPM_CFGREG_TBUFL_%d: 0x%08x\n", j, readl(SSPM_CFGREG_TBUFL));
         datasize += sprintf(buf+datasize, "SSPM_CFGREG_TBUFH_%d: 0x%08x\n", j, readl(SSPM_CFGREG_TBUFH));
     }
     datasize += sprintf(buf+datasize, "SSPM_CFGREG_TBUF_WPTR: 0x%08x\n", j, readl(SSPM_CFGREG_TBUF_WPTR));
-	dprintf(CRITICAL, "DPM last 16 pc dump done!\n");
+    dprintf(CRITICAL, "DPM last 16 pc dump done!\n");
 #endif
 
-    //if (!dev_write(paddr_to_kvaddr(buf), datasize))
     if (!dev_write((buf), datasize))
         dprintf(CRITICAL, "[dpm] dev_write failed\n");
-    dpm_dbg("[dpm] %s total size: %u\n", __func__, datasize);
+
+    // dpm_dbg("[dpm] %s total size: %u\n", __func__, datasize);
     free(buf);
     return;
 }
 AEE_EXPDB_INIT_HOOK(SYS_DPM_REG_DUMP, DPM_REG_DUMP_SIZE, save_dpm_reg);
 
-static void save_dpm_data(AEE_DUMP_CALLBACK dev_write)
-{
+static void save_dpm_data(AEE_DUMP_CALLBACK dev_write) {
     unsigned int addr = 0;
     unsigned int channel_index = 0;
     unsigned int datasize = 0;
@@ -148,20 +140,13 @@
         dprintf(CRITICAL, "[dpm] -ENOMEM\n");
         return;
     }
-	dpm_dbg("[dpm] DPM_DM1_SRAM_BASE1: 0x%x\n",DPM_DM1_SRAM_BASE);
-	dpm_dbg("[dpm] DPM_DM1_SRAM_BASE read:0x%x\n", readl(DPM_DM1_SRAM_BASE));
-	//dpm_dbg("[dpm] DPM_DM1_SRAM_BASE+kernel:0x%x\n",DPM_DM1_SRAM_BASE+KERNEL_ASPACE_BASE);
-	//dpm_dbg("[dpm] DPM_DM1_SRAM_BASE read:0x%x\n", readl(DPM_DM1_SRAM_BASE+KERNEL_ASPACE_BASE));
-	
+
     addr = DPM_DM1_SRAM_BASE;
-    for (int i = 0; i < DPM_CORE_DUMP_SIZE; i += sizeof(unsigned int)) {
-		
-		//dpm_dbg("[dpm] DPM_DM1_SRAM_BASE + i:0x%x\n", readl((DPM_DM1_SRAM_BASE + i)));
+    for (int i = 0; i < DPM_CORE_DUMP_SIZE; i += sizeof(unsigned int))
         buf[datasize + i/sizeof(unsigned int)] = readl((DPM_DM1_SRAM_BASE + i));
-		//dpm_dbg("[dpm] buf[datasize + i]:0x%x\n", buf[datasize + i]);
-	}
+
     datasize += DPM_DM_OFST;
-    //if (!dev_write(paddr_to_kvaddr(buf), datasize))
+
     if (!dev_write((buf), datasize))
         dprintf(CRITICAL, "[dpm] dev_write failed\n");
     dpm_dbg("[dpm] %s total size: %u\n", __func__, datasize);
diff --git a/src/bsp/lk/platform/mt2735/drivers/gpio/mt_gpio.c b/src/bsp/lk/platform/mt2735/drivers/gpio/mt_gpio.c
index 5276983..e566ac4 100755
--- a/src/bsp/lk/platform/mt2735/drivers/gpio/mt_gpio.c
+++ b/src/bsp/lk/platform/mt2735/drivers/gpio/mt_gpio.c
@@ -1,24 +1,10 @@
+// SPDX-License-Identifier: MIT
 /*
- * Copyright (c) 2018 MediaTek Inc.
- *
- * 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.
+* Copyright (c) 2021 MediaTek Inc.
+*
+* Use of this source code is governed by a MIT-style
+* license that can be found in the LICENSE file or at
+* https://opensource.org/licenses/MIT
 */
 
 #include <debug.h>
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_core.c b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_core.c
index dafb84d..e5140c9 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_core.c
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_core.c
@@ -36,7 +36,7 @@
 #include <sys/types.h>
 #include <stdint.h>
 #include <string.h>
-#include <lib/mempool.h>
+#include <lib/mempool.h> //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken
 #include "ccci_fit.h"
 
 #include "mtk_ccci_ld_md.h"
@@ -365,7 +365,7 @@
 {
     unsigned char *md_mem_base;
     const char *partition_list[2];
-    int ret = 0, load_size = 0;
+    int ret = 0, load_size = 0; //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken
     void *fit = NULL;
 
     /* reserve memory for modem with max requirement */
@@ -382,21 +382,21 @@
     ret = ccci_fit_get_image(get_fit_buf[0].label, &get_fit_buf[0].load_buf);
     if (ret < 0) {
         ALWAYS_LOG("fit_get_image failed: %s %d!\n", get_fit_buf[0].label, ret);
-        load_size = ret;
+        load_size = ret; //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken
         goto _Exit;
     }
 
     ret = ccci_fit_conf_verify_sig(NULL, get_fit_buf[0].load_buf);
     if (ret < 0) {
         ALWAYS_LOG("fit_conf_verify_sig failed: %s %d!\n", get_fit_buf[0].label, ret);
-        load_size = ret;
+        load_size = ret; //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken
         goto _Exit;
     }
 
     ret = ccci_fit_load_image(NULL, "kernel", get_fit_buf[0].load_buf, NULL ,NULL, NULL, true);
     if (ret < 0) {
         ALWAYS_LOG("MD-fit image verify failed!\n");
-        load_size = ret;
+        load_size = ret; //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken
         goto _Exit;
     }
     load_size = copy_image_by_name(get_fit_buf[0].load_buf, main_img->image_name, md_mem_base,
@@ -467,7 +467,7 @@
 /* --- load raw data to DRAM that listed at table --- */
 static int ld_img_at_list(struct download_info_s img_list[], struct modem_info_s *info)
 {
-    int load_size = 0;
+    int load_size = 0; //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken
     int md_mem_resv_size = 0;
     int md_mem_required_size = 0;
     unsigned char *md_resv_mem_addr = NULL;
@@ -544,10 +544,8 @@
             }
         }
 
-        // load partition and verify in first time
-        // different images may share the same partitation
-        // skip loading partition if it is loaded before
-        if(j == i) { // the partition isn't loaded before
+        //need load partition and verify in first time
+        if(j == i) {
             ret = ccci_fit_get_image(get_fit_buf[i].label, &get_fit_buf[i].load_buf);
             if (ret < 0) {
                 ALWAYS_LOG("fit_get_image failed: %s %d!\n", get_fit_buf[i].label, ret);
@@ -567,7 +565,6 @@
             }
         }
 
-        // load image
         load_size = copy_image_by_name(get_fit_buf[i].load_buf, curr[i].image_name, curr[i].mem_addr,
                         curr[i].max_size, curr[i].ext_flag);
 #else
@@ -600,15 +597,16 @@
     ALWAYS_LOG("arch_sync_cache_range: addr[%p], size[0x%08x]\n",
         md_resv_mem_addr, md_mem_resv_size);
     info->errno = 0;
-    ret = 0;
+    ret = 0;  //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken
 
     /* Retrieve not used memory if needed*/
     if (md_mem_resv_size != md_mem_required_size)
         ccci_free_not_used_reserved_memory(md_resv_mem_addr, md_mem_resv_size,
             md_mem_required_size);
 
+    //return 0; //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken
 _MD_Exit:
-#ifdef MTK_SECURITY_SW_SUPPORT
+#ifdef MTK_SECURITY_SW_SUPPORT  //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken --start
     ALWAYS_LOG("Free buf memory\n");
     for (j = 0; j < (sizeof(get_fit_buf) / sizeof(get_fit_buf[0])); j++) {
         if (get_fit_buf[j].load_buf) {
@@ -618,7 +616,7 @@
     }
 #endif
 
-    if (ret && md_resv_mem_addr) {
+    if (ret && md_resv_mem_addr) { //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken -- end
         ALWAYS_LOG("Free reserved memory\n");
         ccci_free_not_used_reserved_memory(md_resv_mem_addr, md_mem_resv_size, 0);
     }
@@ -848,7 +846,7 @@
     ret = ccci_get_md_version(MD_SYS3, buf, 128);
     CRITICAL_LOG("[MD3 Baseband version] %s(%d)\r\n", buf, ret);
 
-    return err_code;
+    return err_code; //XF.LI [Feature][T8TSK-265]add rollback after medmcu and md1img broken
 }
 
 void ccci_update_md_version(int md_id, unsigned char ver[])
diff --git a/src/bsp/lk/platform/mt2735/drivers/pll/pll.c b/src/bsp/lk/platform/mt2735/drivers/pll/pll.c
index 9653888..32a312d 100755
--- a/src/bsp/lk/platform/mt2735/drivers/pll/pll.c
+++ b/src/bsp/lk/platform/mt2735/drivers/pll/pll.c
@@ -768,8 +768,6 @@
     DRV_WriteReg32(INFRA_PDN_CLR1, 0xE79DBFD6);// bit 28 27 22 21 17 5 3 0 are empty 10 14 gating, add bit 6
     DRV_WriteReg32(INFRA_PDN_SET1, 0x00004000);// bit 14: auxadc_md_cg clk gating. bit 27, 28: dxcc clk gating. ask
     DRV_WriteReg32(INFRA_PDN_CLR2, 0x8FFFFEFE);// bit 30 29 28 26 25 8 0 is empty, add bit 1
-     //DRV_WriteReg32(INFRA_PDN_CLR2, 0x8FFFFAFE);// bit 30 29 28 26 25 8 0 is empty, add bit 1
-    // DRV_WriteReg32(INFRA_PDN_SET2, 0x00000400);// bit 10 set to off
     DRV_WriteReg32(INFRA_PDN_CLR3, 0x3FFFCFDF);// bit 31 30 13 12 5 is empty
 #ifdef SLT
     DRV_WriteReg32(INFRA_PDN_CLR4, 0xCFFFFBFF);// bit 29 28 10 is empty 16 15 14 en
diff --git a/src/bsp/lk/platform/mt2735/drivers/pmic/pmic.c b/src/bsp/lk/platform/mt2735/drivers/pmic/pmic.c
index d36e99e..c183aab 100644
--- a/src/bsp/lk/platform/mt2735/drivers/pmic/pmic.c
+++ b/src/bsp/lk/platform/mt2735/drivers/pmic/pmic.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MIT
+
 #include <debug.h>
 #include <platform/mt_typedefs.h>
 #include <platform/spmi/spmi.h>
@@ -6,7 +8,7 @@
 #include <platform/regulator/mtk_regulator_errno.h>
 #include <platform/pmic/pmic.h>
 #include <platform/pmic/mt6330.h>
-#include <platform/pmic/upmu_hw.h> //jb.qi change for reboot when sleep on 20230309
+#include <platform/pmic/upmu_hw.h>
 
 #ifdef EXT_BUCK_MT6315
 #include <platform/pmic/mt6315-spmi.h>
@@ -21,7 +23,7 @@
 
 void pmic_cold_reset(void)
 {
-	pmic_config_interface(MT6330_PPCCTL1, 0x1, 0x1, 0x0); //jb.qi change for reboot when sleep on 20230309
+    pmic_config_interface(MT6330_PPCCTL1, 0x1, 0x1, 0x0);
 }
 
 /* show vcore for MD before MD boot up */
diff --git a/src/bsp/lk/platform/mt2735/drivers/rtc/rtc.c b/src/bsp/lk/platform/mt2735/drivers/rtc/rtc.c
index 3620798..1f8f728 100644
--- a/src/bsp/lk/platform/mt2735/drivers/rtc/rtc.c
+++ b/src/bsp/lk/platform/mt2735/drivers/rtc/rtc.c
@@ -890,7 +890,7 @@
 
 	/*
     RTC_LOG("%s#1 powerkey1 = 0x%x, powerkey2 = 0x%x, %s LPD\n", __func__, RTC_Read(RTC_POWERKEY1), RTC_Read(RTC_POWERKEY2)
-             , (RTC_Read(RTC_CON) & RTC_CON_LPSTA_RAW) ? "with" : "without" );
+             , (RTC_Read(RTC_CON) & RTC_CON_LPSTA_RAW) ? "with" : "without" );   // you.chen [Feature][API-1305] remove lk log contains key|port on Oct 31 2023
 			 */
 
     RTC_LOG("bbpu = 0x%x, con = 0x%x, osc32con = 0x%x, sec = 0x%x, yea = 0x%x\n", RTC_Read(RTC_BBPU), RTC_Read(RTC_CON), RTC_Read(RTC_OSC32CON)
@@ -902,7 +902,7 @@
         }
     } else {
         /* normally HW reload is done in BROM but check again here */
-        //RTC_LOG("%s#2 powerkey1 = 0x%x, powerkey2 = 0x%x\n", __func__, RTC_Read(RTC_POWERKEY1), RTC_Read(RTC_POWERKEY2));
+        //RTC_LOG("%s#2 powerkey1 = 0x%x, powerkey2 = 0x%x\n", __func__, RTC_Read(RTC_POWERKEY1), RTC_Read(RTC_POWERKEY2));  //you.chen [Feature][API-1305] remove lk log contains key|port -- on Oct 31 2023
         RTC_Write(RTC_BBPU, RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
         if (!Write_trigger()) {
             rtc_recovery_flow();
@@ -912,7 +912,7 @@
             } else {
                 RTC_LOG("%s Writeif_unlock\n", __func__);
                 if (RTC_Read(RTC_POWERKEY1) != RTC_POWERKEY1_KEY || RTC_Read(RTC_POWERKEY2) != RTC_POWERKEY2_KEY) {
-                    //RTC_LOG("%s#3 powerkey1 = 0x%x, powerkey2 = 0x%x\n", __func__, RTC_Read(RTC_POWERKEY1), RTC_Read(RTC_POWERKEY2));
+                    //RTC_LOG("%s#3 powerkey1 = 0x%x, powerkey2 = 0x%x\n", __func__, RTC_Read(RTC_POWERKEY1), RTC_Read(RTC_POWERKEY2));  //you.chen [Feature][API-1305] remove lk log contains key|port -- on Oct 31 2023
                     if (!rtc_first_boot_init(result)) {
                         rtc_recovery_flow();
                     }
@@ -1060,9 +1060,11 @@
                 Write_trigger();
                 RTC_LOG("Expired alarm\n");
             }
-        } else {
-		RTC_LOG("Not power on alarm\n");
-	}
+        } //XJ [Feature] add poweralarm /wakup-alarm lib --start on May 26 2022
+        else
+        {  
+            RTC_LOG("Not power on alarm\n"); //XJ [Feature] add poweralarm /wakup-alarm lib --end on May 26 2022
+        }
     }
 
     if ((pdn1 & RTC_PDN1_RECOVERY_MASK) == RTC_PDN1_FAC_RESET) {    /* factory data reset */
diff --git a/src/bsp/lk/platform/mt2735/drivers/rules.mk b/src/bsp/lk/platform/mt2735/drivers/rules.mk
index 74703cc..bd773be 100755
--- a/src/bsp/lk/platform/mt2735/drivers/rules.mk
+++ b/src/bsp/lk/platform/mt2735/drivers/rules.mk
@@ -79,7 +79,8 @@
 
 ifeq ($(LK_AS_BL33),0)
 MODULE_SRCS += \
-    $(LOCAL_DIR)/bgr/bgr.c
+    $(LOCAL_DIR)/bgr/bgr.c \
+    $(LOCAL_DIR)/sda/init.c
 
 # KH TBD: need DRAM owner to create dramk_2735
 MODULE_DEPS += \
diff --git a/src/bsp/lk/platform/mt2735/include/platform/mt_reg_base.h b/src/bsp/lk/platform/mt2735/include/platform/mt_reg_base.h
index 711dd0c..0bb7ed9 100755
--- a/src/bsp/lk/platform/mt2735/include/platform/mt_reg_base.h
+++ b/src/bsp/lk/platform/mt2735/include/platform/mt_reg_base.h
@@ -75,11 +75,11 @@
 #define PERI_TRACKER_BASE   (IO_PHYS + 0x00218000)
 #define INFRA_TRACKER_BASE  (IO_PHYS + 0x00314000)
 #define BUS_DBG_BASE        (IO_PHYS + 0x00208000)
+
 #define DRAMC_CH0_TOP5_BASE      (IO_PHYS + 0x00238000)
 #define DPM_PM_SRAM_BASE         (IO_PHYS + 0x00900000)
 #define DPM_DM_SRAM_BASE         (IO_PHYS + 0x00920000)
 #define DPM_CFG_CH0_BASE         (IO_PHYS + 0x00940000)
-/*jb.qi change for reboot when sleep on 20230309 end*/
 
 /* GPIO register definitions */
 #define GPIO_BASE          (IO_PHYS + 0x00005000)
diff --git a/src/bsp/lk/platform/mt2735/include/platform/mtk_wdt.h b/src/bsp/lk/platform/mt2735/include/platform/mtk_wdt.h
index 219b6cd..c3d14ba 100755
--- a/src/bsp/lk/platform/mt2735/include/platform/mtk_wdt.h
+++ b/src/bsp/lk/platform/mt2735/include/platform/mtk_wdt.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
diff --git a/src/bsp/lk/platform/mt2735/include/platform/pmic/pmic.h b/src/bsp/lk/platform/mt2735/include/platform/pmic/pmic.h
index de40db2..78ba8f4 100644
--- a/src/bsp/lk/platform/mt2735/include/platform/pmic/pmic.h
+++ b/src/bsp/lk/platform/mt2735/include/platform/pmic/pmic.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 #ifndef _PMIC_H_
 #define _PMIC_H_
 
@@ -121,7 +122,7 @@
 extern void pl_hw_ulc_det(void);
 extern void mt6330_dump_record_reg(struct spmi_device *dev);
 extern U32 pmic_init (void);
-extern U32 pmic_reinit(void); //jb.qi change for reboot when sleep on 20230309
+extern U32 pmic_reinit(void);
 extern int pmic_get_auxadc_value(unsigned short channel);
 extern U32 is_pmic_rtc_alarm(void);
 extern U32 is_pmic_spar(void);
diff --git a/src/bsp/lk/platform/mt2735/platform_bl2.c b/src/bsp/lk/platform/mt2735/platform_bl2.c
index cd21cbe..d298949 100644
--- a/src/bsp/lk/platform/mt2735/platform_bl2.c
+++ b/src/bsp/lk/platform/mt2735/platform_bl2.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2018 MediaTek Inc.
  *
@@ -62,6 +63,10 @@
 extern emi_info_t emi_info_arg;
 
 
+// lastpc, systracker init
+extern void lastpc_init(void);
+extern void systracker_init(void);
+
 #if WITH_KERNEL_VM
 #define PROG_MEM_MAPPING_IDX    0
 #define GIC_PERIPHERAL_MAPPING_IDX     1
@@ -305,6 +310,10 @@
 
     bgr_init();
 
+    // init tracker / lastpc
+    lastpc_init();
+    systracker_init();
+
     dprintf(CRITICAL, "BL2 Build Time: %s %s\n", __DATE__, __TIME__);
 }
 
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/Makefile b/src/bsp/trustzone/atf/v1.6/mt2xxx/Makefile
index 3ca4bf3..f599540 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/Makefile
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/Makefile
@@ -681,6 +681,7 @@
 $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
 $(eval $(call add_define,BL2_AT_EL3))
 $(eval $(call add_define,BL2_IN_XIP_MEM))
+$(eval $(call add_define,MTK_PLAT_PORTING_LAYER))
 
 # Define the EL3_PAYLOAD_BASE flag only if it is provided.
 ifdef EL3_PAYLOAD_BASE
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/common/tf_log.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/common/tf_log.c
index e8d93d0..0702185 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/common/tf_log.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/common/tf_log.c
@@ -8,7 +8,6 @@
 #include <debug.h>
 #include <platform.h>
 
-
 /* Set the default maximum log level to the `LOG_LEVEL` build flag */
 static unsigned int max_log_level = LOG_LEVEL;
 
@@ -19,82 +18,12 @@
  * expects the first character in the format string to be one of the
  * LOG_MARKER_* macros defined in debug.h.
  */
-
-
-//Add for timestamp print
-#include <string.h>
-#include <arch.h>
-#include <arch_helpers.h>
-#include <mt_cpuxgpt.h>
-
-#define ATF_SCHED_CLOCK_UNIT 1000000000 //ns
-#define TIMESTAMP_BUFFER_SIZE 48
-int (*log_lock_acquire)();
-int (*log_write)(unsigned char);
-int (*log_lock_release)();
-static char timestamp_buf[TIMESTAMP_BUFFER_SIZE] __attribute__((aligned(8)));
-
-/* reverse:  reverse string s in place */
-static void reverse(char s[])
-{
-	int c, i, j;
-
-	for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
-		c = s[i];
-		s[i] = s[j];
-		s[j] = c;
-	}
-}
-/* itoa:  convert n to characters in s */
-static int utoa(unsigned int n, char s[])
-{
-	int i;
-
-	i = 0;
-	do {       /* generate digits in reverse order */
-		s[i++] = n % 10 + '0';   /* get next digit */
-	} while ((n /= 10) > 0);     /* delete it */
-	s[i] = '\0';
-	reverse(s);
-	return i;
-}
-static int ltoa(unsigned long long n, char s[], unsigned add_zero)
-{
-	int i = 0;
-
-	do {       /* generate digits in reverse order */
-		s[i++] = n % 10 + '0';   /* get next digit */
-	} while ((n /= 10) > 0);     /* delete it */
-
-	while(add_zero && i < 6){
-		s[i++] = '0'; /* add '0' for log readability */
-	}
-	s[i] = '\0';
-
-	reverse(s);
-
-	return i;
-}
-
-#define dcache_check()	\
-	unsigned long sec_sctlr_el3 = read_sctlr_el3();	\
-	if ((sec_sctlr_el3 & 0x4) == 0) {	\
-		/* Data Cache is disable in secure world */	\
-		panic(); \
-		return;	\
-	}
-
 void tf_log(const char *fmt, ...)
 {
 	unsigned int log_level;
 	va_list args;
 	const char *prefix_str;
-//add for print time
-	unsigned long long cur_time;
-	unsigned long long sec_time;
-	unsigned long long ns_time;
-	int 	count;
-	char	*timestamp_bufptr = timestamp_buf;
+
 	/* We expect the LOG_MARKER_* macro as the first character */
 	log_level = fmt[0];
 
@@ -105,59 +34,10 @@
 	if (log_level > max_log_level)
 		return;
 
-	/* try get buffer lock */
-	if (log_lock_acquire){
-		(*log_lock_acquire)();
-	}
-
-	/* in ATF boot time, tiemr for cntpct_el0 is not initialized
-	 * so it will not count now.
-	 */
-	cur_time = atf_sched_clock();
-	sec_time = cur_time / ATF_SCHED_CLOCK_UNIT;
-	ns_time = (cur_time % ATF_SCHED_CLOCK_UNIT)/1000;
-	*timestamp_bufptr++ = '[';
-	*timestamp_bufptr++ = 'A';
-	*timestamp_bufptr++ = 'T';
-	*timestamp_bufptr++ = 'F';
-	*timestamp_bufptr++ = ']';
-	*timestamp_bufptr++ = '(';
-	count = utoa(platform_get_core_pos(read_mpidr()), timestamp_bufptr);
-	timestamp_bufptr += count;
-	*timestamp_bufptr++ = ')';
-
-	*timestamp_bufptr++ = '[';
-	count = ltoa(sec_time, timestamp_bufptr, 0);
-	timestamp_bufptr += count;
-	*timestamp_bufptr++ = '.';
-	count = ltoa(ns_time, timestamp_bufptr, 1);
-	timestamp_bufptr += count;
-	*timestamp_bufptr++ = ']';
-	*timestamp_bufptr++ = '\0';
-
-	timestamp_buf[TIMESTAMP_BUFFER_SIZE - 1] = '\0';
-	count = 0;
-	while (timestamp_buf[count])
-	{
-		/* output char to ATF log buffer */
-		if (log_write)
-			(*log_write)(timestamp_buf[count]);
-		putchar(timestamp_buf[count]);
-		count++;
-	}
-	/* release buffer lock */
-	if (log_lock_release)
-		(*log_lock_release)();
-
-	//end for print time
-
-
 	prefix_str = plat_log_get_prefix(log_level);
 
 	while (*prefix_str != '\0') {
 		(void)putchar(*prefix_str);
-		if (log_write)
-                        (*log_write)(*prefix_str);
 		prefix_str++;
 	}
 
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/drivers/console/aarch64/deprecated_console.S b/src/bsp/trustzone/atf/v1.6/mt2xxx/drivers/console/aarch64/deprecated_console.S
index d6ecc4d..68c53f5 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/drivers/console/aarch64/deprecated_console.S
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/drivers/console/aarch64/deprecated_console.S
@@ -9,7 +9,7 @@
  * This is the common console core code for the deprecated single-console API.
  * New platforms should set MULTI_CONSOLE_API=1 and not use this file.
  */
-#warning "Using deprecated console implementation. Please migrate to MULTI_CONSOLE_API"
+/*#warning "Using deprecated console implementation. Please migrate to MULTI_CONSOLE_API"*/
 
 	.globl	console_init
 	.globl	console_uninit
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/include/plat/mediatek/mt2735/platform.h b/src/bsp/trustzone/atf/v1.6/mt2xxx/include/plat/mediatek/mt2735/platform.h
index 5826e6a..fb8d4a7 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/include/plat/mediatek/mt2735/platform.h
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/include/plat/mediatek/mt2735/platform.h
@@ -28,6 +28,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+// SPDX-License-Identifier: BSD-3-Clause
+
 #ifndef __PLATFORM_H__
 #define __PLATFORM_H__
 
@@ -314,7 +316,7 @@
  * haven't migrated to the new platform API to compile on platforms which
  * have the compatibility layer disabled.
  */
-unsigned int platform_get_core_pos(unsigned long mpidr) __deprecated;
+unsigned int platform_get_core_pos(unsigned long mpidr);
 
 #endif /* __ENABLE_PLAT_COMPAT__ */
 #endif /* __PLATFORM_H__ */
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/lib/libc/printf.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/lib/libc/printf.c
index 27fd7f8..3821a37 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/lib/libc/printf.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/lib/libc/printf.c
@@ -9,6 +9,24 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#if defined(MTK_PLAT_PORTING_LAYER)
+#include <arch_helpers.h>	/* for read_mpidr() */
+#include <log.h>
+#include <mt_cpuxgpt.h>
+#include <platform.h>
+#include <string.h>
+
+#define ATF_SCHED_CLOCK_UNIT 1000000000 /* ns */
+#define TIMESTAMP_BUFFER_SIZE 32
+int (*log_lock_acquire)();
+int (*log_write)(unsigned char);
+int (*log_lock_release)();
+extern uint64_t normal_time_base;
+static char timestamp_buf[TIMESTAMP_BUFFER_SIZE] __attribute__((aligned(8)));
+
+#endif
+
+
 #define get_num_va_args(_args, _lcount)				\
 	(((_lcount) > 1)  ? va_arg(_args, long long int) :	\
 	(((_lcount) == 1) ? va_arg(_args, long int) :		\
@@ -19,8 +37,6 @@
 	(((_lcount) == 1) ? va_arg(_args, unsigned long int) :		\
 			    va_arg(_args, unsigned int)))
 
-extern int (*log_write)(unsigned char);
-
 static int string_print(const char *str)
 {
 	int count = 0;
@@ -99,6 +115,18 @@
 	int padn; /* Number of characters to pad */
 	int count = 0; /* Number of printed characters */
 
+#if defined(MTK_PLAT_PORTING_LAYER)
+	/* try get buffer lock */
+	if (log_lock_acquire){
+		/* use bakery lock instead of spinlock */
+		/* we do not need to check if Dcache is enabled */
+		(*log_lock_acquire)();
+	}
+	/* print overwritten msg if it is overwritten */
+	print_overwritten_msg();
+	print_log_timestamp();
+#endif
+
 	while (*fmt != '\0') {
 		l_count = 0;
 		padn = 0;
@@ -169,6 +197,11 @@
 					fmt++;
 				}
 			default:
+#if defined(MTK_PLAT_PORTING_LAYER)
+				/* release buffer lock */
+				if (log_lock_release)
+					(*log_lock_release)();
+#endif
 				/* Exit on any other format specifier */
 				return -1;
 			}
@@ -176,12 +209,16 @@
 			continue;
 		}
 		(void)putchar(*fmt);
-		if (log_write)
-			(*log_write)(*fmt);
 		fmt++;
 		count++;
 	}
 
+#if defined(MTK_PLAT_PORTING_LAYER)
+	/* release buffer lock */
+	if (log_lock_release)
+		(*log_lock_release)();
+#endif
+
 	return count;
 }
 
@@ -196,3 +233,123 @@
 
 	return count;
 }
+
+#if defined(MTK_PLAT_PORTING_LAYER)
+void bl31_log_service_register(int (*lock_get)(),
+    int (*log_putc)(unsigned char),
+    int (*lock_release)())
+{
+    log_lock_acquire = lock_get;
+    log_write = log_putc;
+    log_lock_release = lock_release;
+}
+
+/* reverse:  reverse string s in place */
+static void reverse(char s[])
+{
+	int c, i, j;
+
+	for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
+		c = s[i];
+		s[i] = s[j];
+		s[j] = c;
+	}
+}
+
+/* itoa:  convert n to characters in s */
+static int utoa(unsigned int n, char s[])
+{
+	int i;
+
+	i = 0;
+	do {       /* generate digits in reverse order */
+		s[i++] = n % 10 + '0';   /* get next digit */
+	} while ((n /= 10) > 0);     /* delete it */
+	s[i] = '\0';
+	reverse(s);
+	return i;
+}
+static int ltoa(unsigned long long n, char s[], unsigned add_zero)
+{
+	int i = 0;
+
+	do {       /* generate digits in reverse order */
+		s[i++] = n % 10 + '0';   /* get next digit */
+	} while ((n /= 10) > 0);     /* delete it */
+
+	while(add_zero && i < 6){
+		s[i++] = '0'; /* add '0' for log readability */
+	}
+	s[i] = '\0';
+
+	reverse(s);
+
+	return i;
+}
+
+void print_log_timestamp(void)
+{
+	unsigned long long cur_time;
+	unsigned long long sec_time;
+	unsigned long long ns_time;
+	int 	count;
+	char	*timestamp_bufptr = timestamp_buf;
+
+	/* in ATF boot time, tiemr for cntpct_el0 is not initialized
+	 * so it will not count now.
+	 */
+#if !defined(ATF_BYPASS_DRAM)
+	cur_time = atf_sched_clock();
+#else
+    cur_time = 0;
+#endif
+	sec_time = cur_time / ATF_SCHED_CLOCK_UNIT;
+	ns_time = (cur_time % ATF_SCHED_CLOCK_UNIT)/1000;
+
+	*timestamp_bufptr++ = '[';
+	*timestamp_bufptr++ = 'A';
+	*timestamp_bufptr++ = 'T';
+	*timestamp_bufptr++ = 'F';
+	*timestamp_bufptr++ = ']';
+	*timestamp_bufptr++ = '(';
+	count = utoa(platform_get_core_pos(read_mpidr()), timestamp_bufptr);
+	timestamp_bufptr += count;
+	*timestamp_bufptr++ = ')';
+	if (MT_LOG_KTIME) {
+		*timestamp_bufptr++ = 'K';
+		*timestamp_bufptr++ = ':';
+	}
+	*timestamp_bufptr++ = '[';
+	count = ltoa(sec_time, timestamp_bufptr, 0);
+	timestamp_bufptr += count;
+	*timestamp_bufptr++ = '.';
+	count = ltoa(ns_time, timestamp_bufptr, 1);
+	timestamp_bufptr += count;
+	*timestamp_bufptr++ = ']';
+	*timestamp_bufptr++ = '\0';
+
+	timestamp_buf[TIMESTAMP_BUFFER_SIZE - 1] = '\0';
+	count = 0;
+	while (timestamp_buf[count]) {
+		putchar(timestamp_buf[count]);
+		count++;
+	}
+}
+
+void print_overwritten_msg(void)
+{
+	const char	*log_overwritten_msg = "===Log is overwritten===";
+	int	count;
+	/* write_pos cross read_pos */
+	/* clear flag and print out overwritten message */
+	if (get_is_log_overwritten() == 1) {
+		clr_is_log_overwritten();
+		count = 0;
+		while (log_overwritten_msg[count] != '\0') {
+			putchar(log_overwritten_msg[count]);
+			count++;
+		}
+	}
+}
+#endif
+
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/lib/libc/putchar.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/lib/libc/putchar.c
index 0beb625..aa66a51 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/lib/libc/putchar.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/lib/libc/putchar.c
@@ -6,10 +6,18 @@
 
 #include <stdio.h>
 #include <console.h>
+#if defined(MTK_PLAT_PORTING_LAYER)
+#include <log.h>	/* for log_write() */
+#endif
 
 int putchar(int c)
 {
 	int res;
+
+#if defined(MTK_PLAT_PORTING_LAYER)
+	if (log_write)
+		(*log_write)((unsigned char)c);
+#endif
 	if (console_putc((unsigned char)c) >= 0)
 		res = c;
 	else
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/common/fiq_smp_call.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/common/fiq_smp_call.c
index a2a1913..2ee448b 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/common/fiq_smp_call.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/common/fiq_smp_call.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: BSD-3-Clause
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -100,8 +101,6 @@
 	int lockval, tmp;
 	uint64_t mpidr;
 
-	INFO("inter-cpu-call interrupt is triggered\n");
-
 	mpidr = read_mpidr();
 	cpu = platform_get_core_pos(mpidr);
 
@@ -123,5 +122,4 @@
 		INFO("cfd[%d] is invalid (func = 0x%lx, lock = %d)\n", cpu,    \
 			(unsigned long) cfd[cpu].func, cfd[cpu].lock);
 	}
-	INFO("CPU_%d cfd lock = %d\n", cpu, cfd[cpu].lock);
 }
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/common/mtk_aee_mrdump.h b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/common/mtk_aee_mrdump.h
new file mode 100644
index 0000000..41aaff7
--- /dev/null
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/common/mtk_aee_mrdump.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ *
+ * 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.
+ */
+
+// SPDX-License-Identifier: BSD-3-Clause
+
+#if !defined(__MRDUMP_H__)
+#define __MRDUMP_H__
+
+#include <platform.h>
+
+static inline void cpu_relax(void)
+{
+	asm volatile("yield" ::: "memory");
+}
+
+enum MRDUMP_REBOOT_MODE {
+	MRDUMP_REBOOT_MODE_NORMAL = 0,
+	MRDUMP_REBOOT_MODE_KERNEL_OOPS,
+	MRDUMP_REBOOT_MODE_KERNEL_PANIC,
+	MRDUMP_REBOOT_MODE_NESTED_EXCEPTION,
+	MRDUMP_REBOOT_MODE_WDT,
+	MRDUMP_REBOOT_MODE_MANUAL_KDUMP,
+	MRDUMP_REBOOT_MODE_MRDUMP_KEY,
+	MRDUMP_REBOOT_MODE_GZ_KE,
+	MRDUMP_REBOOT_MODE_GZ_WDT,
+	MRDUMP_REBOOT_MODE_HANG_DETECT,
+};
+
+
+#ifndef __aarch64__
+struct pt_regs {
+	long uregs[18];
+};
+#define ARM_cpsr        uregs[16]
+#define ARM_pc          uregs[15]
+#define ARM_lr          uregs[14]
+#define ARM_sp          uregs[13]
+#define ARM_ip          uregs[12]
+#define ARM_fp          uregs[11]
+#define ARM_r10         uregs[10]
+#define ARM_r9          uregs[9]
+#define ARM_r8          uregs[8]
+#define ARM_r7          uregs[7]
+#define ARM_r6          uregs[6]
+#define ARM_r5          uregs[5]
+#define ARM_r4          uregs[4]
+#define ARM_r3          uregs[3]
+#define ARM_r2          uregs[2]
+#define ARM_r1          uregs[1]
+#define ARM_r0          uregs[0]
+#define ARM_ORIG_r0     uregs[17]
+#endif
+
+#ifdef __aarch64__
+#define reg_pc	pc
+#define reg_lr	regs[30]
+#define reg_sp	sp
+#define reg_fp	regs[29]
+#else
+#define reg_pc	ARM_pc
+#define reg_lr	ARM_lr
+#define reg_sp	ARM_sp
+#define reg_ip	ARM_ip
+#define reg_fp	ARM_fp
+#endif
+
+#define MRDUMP_CPU_MAX 12
+
+#define MRDUMP_ENABLE_COOKIE 0x590d2ba3
+
+#define MRDUMP_GO_DUMP "MRDUMP10"
+
+#define KSYM_32        1
+#define KSYM_64        2
+
+typedef uint32_t arm32_gregset_t[18];
+typedef uint64_t aarch64_gregset_t[34];
+
+struct arm32_ctrl_regs {
+	uint32_t sctlr;
+	uint64_t ttbcr;
+	uint64_t ttbr0;
+	uint64_t ttbr1;
+};
+
+struct aarch64_ctrl_regs {
+	uint64_t sctlr_el1;
+	uint64_t sctlr_el2;
+	uint64_t sctlr_el3;
+
+	uint64_t tcr_el1;
+	uint64_t tcr_el2;
+	uint64_t tcr_el3;
+
+	uint64_t ttbr0_el1;
+	uint64_t ttbr0_el2;
+	uint64_t ttbr0_el3;
+
+	uint64_t ttbr1_el1;
+
+	uint64_t sp_el[4];
+};
+
+struct mrdump_arm32_reg {
+	arm32_gregset_t arm32_regs;
+	struct arm32_ctrl_regs arm32_creg;
+};
+
+struct mrdump_arm64_reg {
+	aarch64_gregset_t aarch64_regs;
+	struct aarch64_ctrl_regs aarch64_creg;
+};
+
+struct mrdump_crash_record {
+	int reboot_mode;
+
+	char msg[128];
+
+	uint32_t fault_cpu;
+
+	union {
+		arm32_gregset_t arm32_regs;
+		aarch64_gregset_t aarch64_regs;
+	} cpu_regs[MRDUMP_CPU_MAX];
+
+	union {
+		struct arm32_ctrl_regs arm32_creg;
+		struct aarch64_ctrl_regs aarch64_creg;
+	} cpu_creg[MRDUMP_CPU_MAX];
+};
+
+struct mrdump_ksyms_param {
+	char     tag[4];
+	uint32_t flag;
+	uint32_t crc;
+	uint64_t start_addr;
+	uint32_t size;
+	uint32_t addresses_off;
+	uint32_t num_syms_off;
+	uint32_t names_off;
+	uint32_t markers_off;
+	uint32_t token_table_off;
+	uint32_t token_index_off;
+} __packed;
+
+struct mrdump_machdesc {
+	uint32_t nr_cpus;
+
+	uint64_t page_offset;
+	uint64_t high_memory;
+
+	uint64_t kimage_vaddr;
+	uint64_t dram_start;
+	uint64_t dram_end;
+	uint64_t kimage_stext;
+	uint64_t kimage_etext;
+	uint64_t kimage_stext_real;
+	uint64_t kimage_voffset;
+	uint64_t kimage_sdata;
+	uint64_t kimage_edata;
+
+	uint64_t vmalloc_start;
+	uint64_t vmalloc_end;
+
+	uint64_t modules_start;
+	uint64_t modules_end;
+
+	uint64_t phys_offset;
+	uint64_t master_page_table;
+
+	uint64_t memmap;
+	uint64_t pageflags;
+	uint32_t struct_page_size;
+
+	uint64_t dfdmem_pa;
+
+	struct mrdump_ksyms_param kallsyms;
+};
+
+struct mrdump_control_block {
+	char sig[8];
+
+	struct mrdump_machdesc machdesc;
+	uint32_t machdesc_crc;
+
+	uint32_t enabled;
+	uint32_t output_fs_lbaooo;
+
+	struct mrdump_crash_record crash_record;
+};
+#endif
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/aarch64/platform_common.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/aarch64/platform_common.c
index 9ea42ba..d1b4486 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/aarch64/platform_common.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/aarch64/platform_common.c
@@ -40,9 +40,8 @@
 			MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(DBGSYS_DEM_BASE, DBGSYS_DEM_SIZE,
 			MT_DEVICE | MT_RW | MT_SECURE),
-// FIXME: RAM_CONSOLE doesn't support DRAM base
-//	MAP_REGION_FLAT(RAM_CONSOLE_BASE, RAM_CONSOLE_MAPPING_SIZE,
-//			MT_MEMORY | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(RAM_CONSOLE_BASE, RAM_CONSOLE_MAPPING_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(MTK_WDT_BASE, MTK_WDT_SIZE,
 			MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(MTK_MCDI_SRAM_BASE, MTK_MCDI_SRAM_MAP_SIZE,
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/bl31_plat_setup.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/bl31_plat_setup.c
index afc144d..7fa73e9 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/bl31_plat_setup.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/bl31_plat_setup.c
@@ -27,6 +27,9 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+
+// SPDX-License-Identifier: BSD-3-Clause
+
 #include <arch_helpers.h>
 #include <arm_gic.h>
 #include <assert.h>
@@ -66,6 +69,77 @@
 IMPORT_SYM(unsigned long, __COHERENT_RAM_START__, BL31_COHERENT_RAM_START);
 IMPORT_SYM(unsigned long, __COHERENT_RAM_END__, BL31_COHERENT_RAM_END);
 
+#define RAM_CONSOLE_DEF_ADDR (0x4351a000)
+#define RAM_CONSOLE_DEF_SIZE (0x10000)
+#define RAM_CONSOLE_LK_SIZE 16
+#define RAM_CONSOLE_EXP_TYPE_MAGIC 0xaeedead0
+
+#define RAM_CONSOLE_EXP_TYPE_DEC(exp_type) \
+    ((exp_type ^ RAM_CONSOLE_EXP_TYPE_MAGIC) < 16 ? exp_type ^ RAM_CONSOLE_EXP_TYPE_MAGIC : exp_type)
+
+/* Reboot reason */
+#define RE_BOOT_REASON_UNKNOW           (0x00)
+#define RE_BOOT_BY_WDT_HW               (0x01)
+#define RE_BOOT_BY_WDT_SW               (0x02)
+#define RE_BOOT_WITH_INTTERUPT          (0x04)
+#define RE_BOOT_BY_SPM_THERMAL          (0x08)
+#define RE_BOOT_BY_SPM                  (0x10)
+#define RE_BOOT_BY_THERMAL_DIRECT       (0x20)
+#define RE_BOOT_BY_DEBUG                (0x40)
+#define RE_BOOT_BY_SECURITY             (0x80)
+#define RE_BOOT_BY_PMIC_FULL_RST        (0x800)    /* PMIC full (cold) reset */
+#define RE_BOOT_ABNORMAL                (0xF0)
+#define RE_BOOT_FULL_PMIC 0x800
+#define RE_BOOT_NORMAL_BOOT 0
+
+#define RAM_CONSOLE_PL_SIZE 3
+#define RAM_CONSOLE_SIG (0x43474244) /* DBGC */
+
+typedef struct {
+    uint32_t maggic_number;
+    uint32_t boot_mode;
+    uint32_t boot_reason;
+    uint32_t cold_reset;
+    uint32_t rgu_mode;
+    uint32_t ddr_reserve_enable;
+    uint32_t ddr_reserve_success;
+    uint32_t ddr_reserve_ready;
+    uint64_t dram_size;
+} BOOT_ARGUMENT;
+
+struct ram_console_buffer {
+    uint32_t sig;
+    /* for size comptible */
+    uint32_t off_pl;
+    uint32_t off_lpl;
+    uint32_t sz_pl;
+    uint32_t off_lk;
+    uint32_t off_llk; /* last lk */
+    uint32_t sz_lk;
+    uint32_t padding[2]; /* size = 2 * 16 = 32 byte */
+    uint32_t dump_step;
+    uint32_t sz_buffer;
+    uint32_t off_linux;
+    uint32_t off_console;
+    uint32_t padding2[3];
+};
+
+struct reboot_reason_pl {
+    uint32_t wdt_status;
+    uint32_t last_func[RAM_CONSOLE_PL_SIZE];
+};
+
+struct reboot_reason_lk {
+    uint32_t last_func[RAM_CONSOLE_LK_SIZE];
+};
+
+struct reboot_reason_kernel {
+    uint32_t fiq_step;
+    /* 0xaeedeadX: X=1 (HWT), X=2 (KE), X=3 (nested panic) */
+    /* details see enum AEE_EXP_TYPE_NUM in ram_console_common.h */
+    uint32_t exp_type;
+    uint32_t others[0];
+};
 /*
  * Placeholder variables for copying the arguments that have been passed to
  * BL3-1 from BL2.
@@ -74,9 +148,28 @@
 static entry_point_info_t bl33_image_ep_info;
 static struct kernel_info k_info;
 static unsigned int gis_abnormal_boot;
+static struct ram_console_buffer *ram_console = NULL;
+static uint32_t ram_console_size;
 
 atf_arg_t gteearg;
 
+#define U_VAR(type) rc_##type
+static unsigned int U_VAR(wdt_status), U_VAR(fiq_step), U_VAR(exp_type);
+static bool U_VAR(set_flag) = false;
+
+static void ram_console_ptr_init(void)
+{
+    if (ram_console && ram_console_size) {
+        INFO("%s. already init start: 0x%zx, size: 0x%x, sig: 0x%x\n",
+             "RAM CONSOLE", (size_t)ram_console, ram_console_size, ram_console->sig);
+        return;
+    }
+
+    ram_console = (struct ram_console_buffer *)(RAM_CONSOLE_DEF_ADDR);
+    ram_console_size = RAM_CONSOLE_DEF_SIZE;
+    INFO("%s. pa start: 0x%zx, size: 0x%x\n", "RAM CONSOLE", (size_t)RAM_CONSOLE_DEF_ADDR, RAM_CONSOLE_DEF_SIZE);
+}
+
 static void platform_setup_cpu(void)
 {
 	INFO("%s()\n", __func__);
@@ -93,6 +186,112 @@
 	spmc_init();
 }
 
+void pl_ram_console_init(void)
+{
+    int i;
+    struct reboot_reason_pl *rr_pl;
+    ram_console = (struct ram_console_buffer *)(RAM_CONSOLE_DEF_ADDR);
+    ram_console_size = RAM_CONSOLE_DEF_SIZE;
+    INFO("pl_ram_console_init ram_console pa: 0x%zx, va:0x%zx, size: 0x%x\n",
+         (size_t)RAM_CONSOLE_DEF_ADDR, (size_t)ram_console, RAM_CONSOLE_DEF_SIZE);
+
+    if (ram_console->sig == RAM_CONSOLE_SIG && ram_console->sz_pl == sizeof(struct reboot_reason_pl)
+        && ram_console->off_pl + ALIGN(ram_console->sz_pl, 64) == ram_console->off_lpl) {
+        rr_pl = (void *)ram_console + ram_console->off_pl;
+        for (i = 0; i < RAM_CONSOLE_PL_SIZE; i++) {
+            INFO("0x%x ", rr_pl->last_func[i]);
+        }
+        INFO("\n");
+        memcpy((void *)ram_console + ram_console->off_lpl, (void *)ram_console + ram_console->off_pl,
+            ram_console->sz_pl);
+    } else {
+        memset(ram_console, 0, ram_console_size);
+        ram_console->sig = RAM_CONSOLE_SIG;
+        ram_console->off_pl = sizeof(struct ram_console_buffer);
+        ram_console->sz_pl = sizeof(struct reboot_reason_pl);
+        ram_console->off_lpl = ram_console->off_pl + ALIGN(ram_console->sz_pl, 64);
+        INFO("pl_ram_console_init first init\n");
+    }
+}
+
+void ram_console_init(void)
+{
+    //int i;
+    //struct reboot_reason_lk *rr_lk;
+    pl_ram_console_init();
+    ram_console_ptr_init();
+    if (ram_console) {
+        INFO("%s. start: 0x%lx, size: 0x%x\n", "RAM CONSOLE", (long unsigned int)ram_console, ram_console_size);
+    } else {
+        INFO("%s. sig not match\n", "RAM CONSOLE");
+        return;
+    }
+
+    ram_console->off_lk = ram_console->off_lpl + ALIGN(ram_console->sz_pl, 64);;
+    ram_console->off_llk = ram_console->off_lk + ALIGN(sizeof(struct reboot_reason_lk), 64);
+    ram_console->sz_lk = sizeof(struct reboot_reason_lk);
+    if (ram_console->sz_lk == sizeof(struct reboot_reason_lk) && (ram_console->off_lk +
+        ram_console->sz_lk == ram_console->off_llk)) {
+        INFO("%s. lk last status: ", "RAM CONSOLE");
+        /*rr_lk = (void *)ram_console + ram_console->off_lk;
+        for (i = 0; i < RAM_CONSOLE_LK_SIZE; i++) {
+            INFO("0x%x ", rr_lk->last_func[i]);
+        }
+        INFO("\n");*/
+        memcpy((void *)ram_console + ram_console->off_llk, (void *)ram_console +
+            ram_console->off_lk, ram_console->sz_lk);
+    } else {
+        INFO("%s. lk size mismatch %x + %x != %x\n", "RAM CONSOLE", ram_console->sz_lk,
+            ram_console->off_lk, ram_console->off_llk);
+        ram_console->sz_lk = sizeof(struct reboot_reason_lk);
+    }
+    ram_console->off_linux = ram_console->off_llk + ALIGN(ram_console->sz_lk, 64);
+}
+
+int ram_console_is_abnormal_boot(unsigned int wdt_status)
+{
+    unsigned int fiq_step, exp_type;
+    int reinit_flag = 0;
+
+    if (!ram_console) {
+        ram_console_init();
+        reinit_flag = 1;
+    }
+
+    if (wdt_status == 0x40000000) wdt_status = RE_BOOT_BY_WDT_SW;
+    if (ram_console && ram_console->off_linux &&
+            (ram_console->off_linux == (ram_console->off_llk + ALIGN(ram_console->sz_lk, 64))) &&
+            (ram_console->off_pl == sizeof(struct ram_console_buffer))) {
+        //wdt_status = ((struct reboot_reason_pl *)((void *)ram_console + ram_console->off_pl))->wdt_status;
+        fiq_step = ((struct reboot_reason_kernel *)((void *)ram_console + ram_console->off_linux))->fiq_step;
+        exp_type = ((struct reboot_reason_kernel *)((void *)ram_console + ram_console->off_linux))->exp_type;
+        INFO("%s. wdt_status 0x%x, fiq_step 0x%x, exp_type 0x%x\n", "RAM CONSOLE", wdt_status, fiq_step, RAM_CONSOLE_EXP_TYPE_DEC(exp_type));
+        if (fiq_step != 0 && (exp_type ^ RAM_CONSOLE_EXP_TYPE_MAGIC) >= 16) {
+            fiq_step = 0;
+            ((struct reboot_reason_kernel *)((void *)ram_console + ram_console->off_linux))->fiq_step = fiq_step;
+        }
+        U_VAR(wdt_status) = wdt_status;
+        U_VAR(fiq_step) = fiq_step;
+        U_VAR(exp_type) = RAM_CONSOLE_EXP_TYPE_DEC(exp_type);
+        U_VAR(set_flag) = true;
+        INFO("%s. set reboot reason info done\n", "RAM CONSOLE");
+
+        if ((wdt_status == RE_BOOT_BY_WDT_SW && fiq_step == 0 && U_VAR(exp_type) == 0) /* adb reboot */
+            || (wdt_status == RE_BOOT_FULL_PMIC && fiq_step == 0) /* full pmic reset */
+            || (wdt_status == RE_BOOT_NORMAL_BOOT))  /* power off->on */
+            return false;
+        else
+            return true;
+    } else {
+        if (ram_console) {
+            INFO("%s. set reboot reason info failed: off_linux:0x%x, off_llk:0x%x, off_pl:0x%x, reinit flag:%d\n",
+                "RAM CONSOLE", ram_console->off_linux, ram_console->off_llk, ram_console->off_pl, reinit_flag);
+        } else {
+            INFO("%s. ram console buffer NULL\n", "RAM CONSOLE");
+        }
+    }
+    return false;
+}
 /*******************************************************************************
  * Return a pointer to the 'entry_point_info' structure of the next image for
  * the security state specified. BL33 corresponds to the non-secure image type
@@ -132,7 +331,7 @@
 	 * registers are UNKNOWN if CPU change to 64 bit state.
 	 * So we need to clear high 32bit, which may be random value. */
 	pmtk_bl_param_t = (mtk_bl_param_t *)((uint64_t)pmtk_bl_param_t & 0x00000000ffffffff);
-	gis_abnormal_boot = (unsigned int)((uint64_t)plat_params_from_bl2 & 0x00000000ffffffff);
+	//gis_abnormal_boot = (unsigned int)((uint64_t)plat_params_from_bl2 & 0x00000000ffffffff);
 	teearg = (atf_arg_t_ptr)pmtk_bl_param_t->tee_info_addr;
 
 	console_init(teearg->atf_log_port, MT2735_UART_CLOCK, teearg->atf_log_baudrate);
@@ -263,8 +462,8 @@
 		INFO("mmap atf buffer (force 2MB aligned): 0x%llx, 0x%x\n\r",
 			(teearg->atf_log_buf_start & ~(PAGE_SIZE_2MB_MASK)), PAGE_SIZE_2MB);
 	}
-
-       configure_mmu_el3();
+	gis_abnormal_boot = ram_console_is_abnormal_boot(((BOOT_ARGUMENT *)(bl33_image_ep_info.args.arg0))->boot_reason);
+	configure_mmu_el3();
 
 	/* Initialize for ATF log buffer */
 	if(teearg->atf_log_buf_size != 0)
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/common/plat_aee_debug.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/common/plat_aee_debug.c
index dc65287..ba32eef 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/common/plat_aee_debug.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/common/plat_aee_debug.c
@@ -5,16 +5,22 @@
  */
 
 #include <arch_helpers.h>
-#include <debug.h>
+#include <bl_common.h>
 #include <console.h>
-#include <mtk_plat_common.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <debug.h>
 #include <delay_timer.h>
 #include <fiq_smp_call.h>
+#include <mtk_aee_mrdump.h>
 #include <mtk_gic.h>
+#include <mtk_plat_common.h>
 #include <mtk_rgu.h>
 #include <plat_private.h>  //for atf_arg_t_ptr
-#include <platform.h>
 #include <platform_def.h>
+#include <platform.h>
+#include <spinlock.h>
+#include <smccc_helpers.h>
 
 #define RAM_CONSOLE_SIG_ATF (0x43474244) /* DBGC */
 #define RAM_CONSOLE_EXP_TYPE_MAGIC_ATF 0xaeedead0
@@ -23,6 +29,11 @@
 #define HWT_EXP_TYPE 1
 #define MRDUMP_KEY_EXP_TYPE 4
 
+static int8_t first_cpu;
+
+/* locker for log printing */
+static spinlock_t aee_wdt_dump_lock;
+
 struct ram_console_buffer_atf {
 	unsigned int sig;
 	unsigned int others1[9];
@@ -33,7 +44,6 @@
 
 unsigned char ram_console_set_exp_type_atf(unsigned int exp_type)
 {
-#if 0
 	unsigned char ret = false;
 	struct ram_console_buffer_atf *ram_console =
 			(struct ram_console_buffer_atf *)RAM_CONSOLE_BASE;
@@ -59,19 +69,187 @@
 			__func__, "FATAL", ram_console->off_linux, ram_console->sig, ram_console->sz_buffer);
 	}
 	return ret;
-#else
-	NOTICE("ram_console non-sram type NOT supported\n");
-	return 0;
-#endif
+}
+
+void aee_wdt_legacy_dump()
+{
+	struct atf_aee_regs *regs;
+	cpu_context_t *ns_cpu_context;
+	uint64_t mpidr = read_mpidr();
+	uint32_t linear_id = plat_core_pos_by_mpidr(mpidr);
+	uint64_t spsr;
+	int i;
+
+	/* save context if from non-secure */
+	if (read_scr_el3() & SCR_NS_BIT)
+		cm_el1_sysregs_context_save(NON_SECURE);
+	ns_cpu_context = (cpu_context_t *)cm_get_context_by_index(linear_id, NON_SECURE);
+	spsr = SMC_GET_EL3(ns_cpu_context, CTX_SPSR_EL3);
+
+	/* Always print dump info on console in LK stage */
+	console_init(gteearg.atf_log_port, MT2735_UART_CLOCK, MT2735_BAUDRATE);
+	/* Log starts here... */
+	INFO("%s: on cpu%d\n", __func__, (int)linear_id);
+	atf_arg_t_ptr teearg = &gteearg;
+	regs = (void *)(teearg->atf_aee_debug_buf_start + (linear_id * sizeof(struct atf_aee_regs)));
+	/* save debug infos */
+	regs->pstate = SMC_GET_EL3(ns_cpu_context, CTX_SPSR_EL3);
+	regs->pc = SMC_GET_EL3(ns_cpu_context, CTX_ELR_EL3);
+	for (i = 0; i < 31; i++)
+		regs->regs[i] = SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (i<<3)));
+	if (GET_RW(spsr) == MODE_RW_32)
+		regs->sp = regs->regs[19]; /* SVC SP */
+	else
+		regs->sp = read_ctx_reg(get_sysregs_ctx(ns_cpu_context), CTX_SP_EL1);
+	/* dump debug infos in pretty print */
+	INFO("(%d) pc:<%016llx> lr:<%016llx> sp:<%016llx> pstate=%llx\n",
+		(int)linear_id, regs->pc, regs->regs[30], regs->sp, regs->pstate);
+	for (i = 29; i >= 0; i -= 3) {
+		INFO("(%d) x%02d: %016llx x%02d: %016llx x%02d: %016llx\n",
+			(int)linear_id, i, regs->regs[i], (i-1), regs->regs[i-1], (i-2), regs->regs[i-2]);
+	}
 }
 
 void aee_wdt_dump(void __unused *cookie)
 {
-	unsigned int cpuid = plat_my_core_pos();
+	spin_lock(&aee_wdt_dump_lock);
 
-	INFO("%s: CPU(%u) in ATF by IPI.\n", __func__, cpuid);
+#if defined(MRDUMP_CB_ADDR)
+	struct mrdump_control_block *mrdump_cblock = NULL;
+#endif
+	cpu_context_t *ns_cpu_context;
+	uint64_t spsr;
+	int i, j;
+	char exception_mode[16] = {0};
+	int8_t cpuid = plat_my_core_pos();
+
+	aee_wdt_legacy_dump();
+	if (cpuid < 0) {
+		ERROR("%s: invalid cpuid(%d)\n", __func__, cpuid);
+		spin_unlock(&aee_wdt_dump_lock);
+		return;
+	}
+
+	/* save context if from non-secure */
+	if (read_scr_el3() & SCR_NS_BIT)
+		cm_el1_sysregs_context_save(NON_SECURE);
+
+	ns_cpu_context = (cpu_context_t *)cm_get_context_by_index(cpuid, NON_SECURE);
+
+	/* Log starts here... */
+#if defined(MRDUMP_CB_ADDR)
+	mrdump_cblock = (struct mrdump_control_block *)(uintptr_t)MRDUMP_CB_ADDR;
+	if (strncmp(mrdump_cblock->sig, MRDUMP_GO_DUMP, strlen(MRDUMP_GO_DUMP)) != 0) {
+		NOTICE("%s: signature mismatched, cpu(%d).\n", __func__, cpuid);
+		spin_unlock(&aee_wdt_dump_lock);
+		return;
+	}
+#else
+	spin_unlock(&aee_wdt_dump_lock);
+	return;
+#endif
+
+	spsr = SMC_GET_EL3(ns_cpu_context, CTX_SPSR_EL3);
+	if (GET_RW(spsr) == MODE_RW_32) {
+		/* USR: r0 ~ r14 */
+		for (i = 0; i < 15; i++) {
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[i] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (i<<3)));
+		}
+
+		switch (GET_M32(spsr)) {
+		case MODE32_hyp:
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[13] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (15 << 3)));
+			snprintf(exception_mode, 10, "%s", "MODE32_hyp");
+			break;
+		case MODE32_irq:
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[14] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (16 << 3)));
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[13] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (17 << 3)));
+			snprintf(exception_mode, 10, "%s", "MODE32_irq");
+			break;
+		case MODE32_svc:
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[14] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (18 << 3)));
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[13] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (19 << 3)));
+			snprintf(exception_mode, 10, "%s", "MODE32_svc");
+			break;
+		case MODE32_abt:
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[14] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (20 << 3)));
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[13] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (21 << 3)));
+			snprintf(exception_mode, 10, "%s", "MODE32_abt");
+			break;
+		case MODE32_und:
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[14] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (22 << 3)));
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[13] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (23 << 3)));
+			snprintf(exception_mode, 10, "%s", "MODE32_und");
+			break;
+		case MODE32_fiq:
+			for (i = 8, j = 0; i < 15; i++, j++) {
+				mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[i] =
+					SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + ((24 + j)<<3)));
+			}
+			snprintf(exception_mode, 10, "%s", "MODE32_fiq");
+			break;
+		default:
+			snprintf(exception_mode, 10, "%s", "MODE32_usr");
+			break;
+		}
+
+		/* pc r15 */
+		mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[15] =
+			SMC_GET_EL3(ns_cpu_context, CTX_ELR_EL3);
+
+		/* dump debug infos in pretty print */
+		INFO("cpu(%d) pc:<%08x> lr:<%08x> sp:<%08x> pstate=%llx (%s)\n",
+			cpuid,
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[15],
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[14],
+			mrdump_cblock->crash_record.cpu_regs[cpuid].arm32_regs[13],
+			spsr, exception_mode);
+	} else {  // TODO: remove? identical to legacy(). Bollinger also has this part
+		/* x0 ~ x30 */
+		for (i = 0; i < 31; i++) {
+			mrdump_cblock->crash_record.cpu_regs[cpuid].aarch64_regs[i] =
+				SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (i<<3)));
+		}
+
+		/* x31: sp */
+		mrdump_cblock->crash_record.cpu_regs[cpuid].aarch64_regs[31] =
+			read_ctx_reg(get_sysregs_ctx(ns_cpu_context), CTX_SP_EL1);
+		/* x32: pc */
+		mrdump_cblock->crash_record.cpu_regs[cpuid].aarch64_regs[32] =
+			SMC_GET_EL3(ns_cpu_context, CTX_ELR_EL3);
+		/* x33: pstate */
+		mrdump_cblock->crash_record.cpu_regs[cpuid].aarch64_regs[33] =
+			spsr;
+
+		/* dump debug infos in pretty print */
+		INFO("cpu(%d) pc:<%016llx> lr:<%016llx> sp:<%016llx> pstate=%llx\n",
+			cpuid,
+			mrdump_cblock->crash_record.cpu_regs[cpuid].aarch64_regs[32],
+			mrdump_cblock->crash_record.cpu_regs[cpuid].aarch64_regs[30],
+			mrdump_cblock->crash_record.cpu_regs[cpuid].aarch64_regs[31],
+			spsr);
+	}
+
+	spin_unlock(&aee_wdt_dump_lock);
+
+	/* flush cache */
+	disable_mmu_el3();
 	dcsw_op_all(DCCISW);
-	while(1);
+
+	if (cpuid != first_cpu) {
+		while (1)
+			cpu_relax();
+	}
 }
 
 #define PLATFORM_MAX_CPU_BIT_MASK ((1 << PLATFORM_CORE_COUNT) - 1)
@@ -84,10 +262,14 @@
 
 void aee_wdt_dump_all_core(void __unused *cookie)
 {
+	first_cpu = plat_core_pos_by_mpidr(read_mpidr());
 	unsigned int cpuid = plat_my_core_pos();
 	console_init(gteearg.atf_log_port, MT2735_UART_CLOCK, MT2735_BAUDRATE);
 	INFO("%s: CPU(%u) in ATF by WDT.\n", __func__, cpuid);
 	wdt_notify_other_cores(aee_wdt_dump, 0, 0);
+
+	/* aee_wdt_dump and delay 1000ms for other cores trapped into ATF */
+	aee_wdt_dump(NULL);
 	mdelay(1000);
 
 	mask_wdt_fiq();
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/atf_control.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/atf_control.c
new file mode 100644
index 0000000..6a36361
--- /dev/null
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/atf_control.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <atf_control.h>
+#include <footprint.h>
+#include <atf_log.h>
+#include <mtk_sip_svc.h>
+#include <platform_def.h>
+
+int64_t atf_control(uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4,
+	void *cookie, void *handle, uint64_t flags, struct smc_retval *pret_val)
+{
+	int64_t ret = ATF_RET_SUCCESS;
+
+	switch (x1) {
+	case ATF_OP_ID_GET_FOOTPRINT_BUF_INFO:
+		get_footprint_info(pret_val);
+		break;
+	default:
+		ret = ATF_RET_UNKNOWN;
+		break;
+	}
+	return ret;
+}
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/atf_control.h b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/atf_control.h
new file mode 100644
index 0000000..52e3577
--- /dev/null
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/atf_control.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ATF_CONTROL_H__
+#define __ATF_CONTROL_H__
+
+#include <mtk_sip_svc.h>
+
+#define ATF_OP_ID_GET_FOOTPRINT_BUF_INFO	(0x0)
+
+
+#define ATF_RET_SUCCESS 0
+#define ATF_RET_UNKNOWN -1
+/*
+ * ATF CO wrapper to set tee_sanity intr pending.
+ *
+ * For op_id: TEE_OP_ID_SET_PENDING used
+ */
+int64_t atf_control(uint64_t x1, uint64_t x2, uint64_t x3,
+	uint64_t x4, void *cookie, void *handle, uint64_t flags,
+	struct smc_retval *ret_val);
+#endif /* __ATF_CONTROL_H__ */
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/atf_log.h b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/atf_log.h
new file mode 100644
index 0000000..182619d
--- /dev/null
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/atf_log.h
@@ -0,0 +1,179 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+
+// SPDX-License-Identifier: BSD-3-Clause
+
+/******************************************************************************
+*
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+#ifndef ATF_LOG_DRV_H
+#define ATF_LOG_DRV_H
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <spinlock.h>
+#include <stdint.h>
+#include <platform_def.h>
+#endif
+#define ATF_LOG_CTRL_BUF_SIZE 512
+#define ATF_CRASH_MAGIC_NO	0xdead1abf
+#define ATF_LAST_LOG_MAGIC_NO	0x41544641
+#define ATF_BAD_PTR		0xffffffff
+#define ATF_DUMP_DONE_MAGIC_NO	0xd07ed07e
+
+#define LOG_USE_SPIN_LOCK	0
+#define MT_LOG_KTIME_FLAG_SHIFT 31
+
+/*
+ *  ___________________________
+ * |                           |
+ * | ATF crash reserved buffer |
+ * |___________________________|
+ *
+ *
+ * Total reserved buffer size = ATF_CRASH_LAST_LOG_SIZE + ATF_EXCEPT_BUF_SIZE
+ *
+ * +--------------------------------+--------------------------------------------------------+
+ * |    ATF_CRASH_LAST_LOG_SIZE     |    ATF_EXCEPT_BUF_SIZE_PER_CPU * PLATFORM_CORE_COUNT   |
+ * +--------------------------------+--------------------------------------------------------+
+ * |    Last ATF log for crash      | CPU-0 | CPU-1| CPU-2 | CPU-3 |...PLATFORM_CORE_COUNT-1 |
+ * +--------------------------------+--------------------------------------------------------+
+ */
+#define ATF_CRASH_LAST_LOG_SIZE (64*1024)
+#define ATF_EXCEPT_BUF_SIZE_PER_CPU (4*1024)
+#define ATF_EXCEPT_BUF_SIZE (ATF_EXCEPT_BUF_SIZE_PER_CPU * PLATFORM_CORE_COUNT)
+
+/* footprint part define */
+#define ATF_FOOTPRINT_BUF_SIZE 2048
+#define MAX_FOOTPRINT_TYPE_STRING_SIZE 8	  /* 4 byte alignment */
+#define MAX_SUPPORTED_FOOTPRINT_TYPE 16
+#define ADDR_32_BITS_MASK 0xFFFFFFFF
+#define WORD_SHIFT_BITS 32
+#define FOOTPRINT_MAGIC_NUM 0xCA7FF007
+
+#define PER_CPU_FOOTPRINT_SIZE 4
+#define SIZE_OF_HEADER_AND_NAME (8 + MAX_FOOTPRINT_TYPE_STRING_SIZE)
+/* footprint end */
+
+/* if struct is modified, please update the offset*/
+#define FOOTPRINT_PACKAGE_OFFSET	48
+
+#ifndef __ASSEMBLY__
+
+extern unsigned int mt_log_ktime_sync;
+
+#define MT_LOG_KTIME_CLEAR() { mt_log_ktime_sync = 0; }
+#define MT_LOG_KTIME_SET() { mt_log_ktime_sync = 1; }
+#define MT_LOG_KTIME mt_log_ktime_sync
+
+struct footprint_header {
+	uint32_t size;
+	uint32_t magic;
+};
+
+struct footprint_package {
+	struct footprint_header header;
+	/* 4 bytes alignment */
+	uint8_t name_string[MAX_FOOTPRINT_TYPE_STRING_SIZE];	/* 8 */
+	uint32_t footprint[PLATFORM_CORE_COUNT];				/* 16*/
+};
+
+
+union atf_log_ctrl {
+	struct {
+	uint64_t atf_log_addr;			/* 0 */
+	uint64_t atf_log_size;
+	uint32_t atf_write_offset;
+	uint32_t atf_read_offset;
+
+	/* must keep value after reboot */
+	uint64_t atf_crash_log_addr;	/* 24 */
+	uint64_t atf_crash_log_size;
+	uint32_t atf_total_write_count;
+	uint32_t atf_crash_flag;
+	struct footprint_package *ptr_fp_pkg_start;	/* 48 */
+
+	/* for FIQ/IRQ footprint, print in crash log*/
+	uint64_t fiq_irq_enter_timestamp[PLATFORM_CORE_COUNT];
+	uint64_t fiq_irq_quit_timestamp[PLATFORM_CORE_COUNT];
+	uint32_t enter_atf_fiq_irq_num[PLATFORM_CORE_COUNT];
+	} info;
+	unsigned char data[ATF_LOG_CTRL_BUF_SIZE];
+};
+
+/* Check union atf_log_ctrl size */
+CASSERT(sizeof(union atf_log_ctrl) <= ATF_LOG_CTRL_BUF_SIZE,
+		atf_log_ctrl_t_is_larger_than_ATF_LOG_CTRL_BUF_SIZE);
+
+void mt_log_setup(uint64_t start, unsigned int size, unsigned int aee_buf_size, unsigned int is_abnormal_boot);
+int mt_log_lock_acquire(void);
+int mt_log_write(unsigned char c);
+int mt_log_lock_release(void);
+void bl31_log_service_register(int (*lock_get)(),
+	int (*log_putc)(unsigned char),
+	int (*lock_release)());
+void print_log_timestamp(void);
+void print_overwritten_msg(void);
+
+int (*log_write)(unsigned char);
+
+void mt_log_suspend_flush(void);
+void mt_log_secure_os_print(int c);
+
+uint64_t mt_log_get_crash_log_addr(void);
+uint64_t mt_log_get_crash_log_size(void);
+unsigned int *mt_log_get_crash_flag_addr(void);
+
+void atf_enter_timestamp(unsigned int irq);
+void atf_exit_timestamp(void);
+unsigned int get_is_log_overwritten(void);
+void clr_is_log_overwritten(void);
+
+#ifdef MTK_ATF_RAM_DUMP
+extern uint64_t	atf_ram_dump_base;
+extern uint64_t	atf_ram_dump_size;
+#endif
+#endif
+#endif
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/footprint.S b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/footprint.S
new file mode 100644
index 0000000..aa9c2b5
--- /dev/null
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/footprint.S
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_macros.S>
+#include <footprint.h>
+#include <log.h>
+#include <platform_def.h>
+.globl	footprint_set
+.globl	footprint_clear
+.globl	footprint_bit_set
+.globl	footprint_clear_by_cpuid
+
+	/*
+	 * -----------------------------------------------------------------
+	 * void footprint_set(enum footprint_type fp_type, uint32_t value)
+	 *
+	 * This function set footprint value of specific type and current CPU
+	 * For low level debug
+	 *
+	 * In: X0 = footprint_type, X1 = value
+	 * Out: N/A
+	 * Clobber: X30, X0, X1, X2, X3, X13, X14, X15,
+	 * -----------------------------------------------------------------
+	 */
+func footprint_set
+	/* no sp, keep x0, x1 and x30 */
+	mov x13, x0	/* footprint_type */
+	mov x14, x1	/* value */
+	mov x15, x30	/* LR */
+
+	/*
+	 * uint32_t my_cpuid = plat_my_core_pos();
+	 * plat_my_core_pos
+	 * Clobbers: x0 - x1 and x30
+	 */
+	bl plat_my_core_pos
+
+	/*
+	 * p_atf_log_ctrl->info.ptr_fp_pkg_start[fp_type].footprint[my_cpuid]
+	 * ptr_fp_pkg_start[fp_type].footprint[my_cpuid] = value;
+	 */
+
+	/*
+	 * Caculate offset from start address of footpring buffer
+	 * CPU# (x1=PLATFORM_CORE_COUNT) * fp size((x2=4))
+	 * (header (8) + fp_type_name (8)) (X3 =16)
+	 */
+	mov x1, #PLATFORM_CORE_COUNT
+	mov x2, #PER_CPU_FOOTPRINT_SIZE
+	mov x3, #SIZE_OF_HEADER_AND_NAME/* size of heaer(8) + name_string(8) */
+
+	/* package size(x1) = PLATFORM_CORE_COUNT(x1) * 4(x2) + header&string (x3) */
+	madd x1, x1, x2, x3
+	/* footprint_type(x13) * package size (x1) */
+	mul x1, x13, x1
+	/* footprint start address of corresponding package (x1) = package start address + header */
+	add x1, x1, x3
+	/* footprint offset from start address of footprint buffer */
+	/* cpuid(x0) * 4(x2) + (footprint start address of corresponding package)(x1) */
+	madd x1, x0, x2, x1
+
+	/* load & p_atf_log_ctrl->info.ptr_fp_pkg_start[0].footprint[0] */
+	adr x0, p_atf_log_ctrl
+	ldr x0, [x0]
+	ldr x0, [x0, #FOOTPRINT_PACKAGE_OFFSET]
+
+	/* package start address(x0) + offset(x1) */
+	str w14, [x0, x1]
+	mov x30, x15
+	ret
+endfunc footprint_set
+
+	/*
+	 * -----------------------------------------------------------------
+	 * void footprint_bit_set(enum footprint_type fp_type, uint32_t bit_index)
+	 *
+	 * This function set footprint bit of specific type and current CPU
+	 * For low level debug
+	 *
+	 * In: X0 = footprint_type, X1 = bit_index
+	 * Out: N/A
+	 * Clobber: X30, X0, X1, X2, X3, X13, X14, X15
+	 * -----------------------------------------------------------------
+	 */
+func footprint_bit_set
+	/* no sp, keep x0, x1 and x30 */
+	mov x13, x0	/* footprint_type */
+	mov x14, x1	/* bit_index */
+	mov x15, x30	/* LR */
+
+	/*
+	 * uint32_t my_cpuid = plat_my_core_pos();
+	 * plat_my_core_pos
+	 * Clobbers: x0 - x1 and x30
+	 */
+	bl plat_my_core_pos
+	/*
+	 * p_atf_log_ctrl->info.ptr_fp_pkg_start[fp_type].footprint[my_cpuid]
+	 * ptr_fp_pkg_start[fp_type].footprint[my_cpuid] = value;
+	 * Caculate offset from start address of footpring buffer
+	 * CPU# (x1=PLATFORM_CORE_COUNT) * fp size((x2=4))
+	 * (header (8) + fp_type_name (8)) (X3 =16)
+	 */
+	mov x1, #PLATFORM_CORE_COUNT
+	mov x2, #PER_CPU_FOOTPRINT_SIZE
+	mov x3, #SIZE_OF_HEADER_AND_NAME	/* size of heaer(8) + name_string(8) */
+
+	/* package size(x1) = PLATFORM_CORE_COUNT(x1) * 4(x2) + header&string (x3) */
+	madd x1, x1, x2, x3
+	/* footprint_type(x13) * package size (x1) */
+	mul x1, x13, x1
+	/* footprint start address of corresponding package (x1) = package start address + header */
+	add x1, x1, x3
+	/* footprint offset from start address of footprint buffer */
+	/* cpuid(x0) * 4(x2) + (footprint start address of corresponding package)(x1) */
+	madd x1, x0, x2, x1
+
+	/* load & p_atf_log_ctrl->info.ptr_fp_pkg_start[0].footprint[0] */
+	adr x0, p_atf_log_ctrl
+	ldr x0, [x0]
+	ldr x0, [x0, #FOOTPRINT_PACKAGE_OFFSET]
+
+	/* w2 = 1 << bit_index(w14) */
+	mov w2, #0x1
+	lsl w2, w2, w14
+
+	/* package start address(x0) + offset(x1) */
+	ldr w14, [x0, x1]
+
+	/* footprint(w14) = footprint(w14) | bit(w2) */
+	orr w14, w14, w2
+
+	/* package start address(x0) + offset(x1) */
+	str w14, [x0, x1]
+
+	mov x30, x15
+	ret
+endfunc footprint_bit_set
+
+	/*
+	 * -----------------------------------------------------------------
+	 * void footprint_clear(enum footprint_type fp_type)
+	 *
+	 * This function clear footprint of specific type and current CPU
+	 * For low level debug
+	 *
+	 * In: X0 = footprint_type
+	 * Out: N/A
+ 	 * Clobber: X30, X0, X1, X2, X3, X13, X15
+	 * -----------------------------------------------------------------
+	 */
+func footprint_clear
+	/* no sp, keep x0 and x30 */
+	mov x13, x0	/* footprint_type */
+	mov x15, x30	/* LR */
+
+	/*
+	 * uint32_t my_cpuid = plat_my_core_pos();
+	 * plat_my_core_pos
+	 * Clobbers: x0 - x1 and x30
+	 */
+	bl plat_my_core_pos
+
+	/*
+	 * p_atf_log_ctrl->info.ptr_fp_pkg_start[fp_type].footprint[my_cpuid]
+	 * ptr_fp_pkg_start[fp_type].footprint[my_cpuid] = value;
+	 * Caculate offset from start address of footpring buffer
+	 * CPU# (x1=PLATFORM_CORE_COUNT) * fp size((x2=4))
+	 * (header (8) + fp_type_name (8)) (X3 =16)
+	 */
+	mov x1, #PLATFORM_CORE_COUNT
+	mov x2, #PER_CPU_FOOTPRINT_SIZE
+	mov x3, #SIZE_OF_HEADER_AND_NAME	/* size of heaer(8) + name_string(8) */
+
+	/* package size(x1) = PLATFORM_CORE_COUNT(x1) * 4(x2) + header&string (x3) */
+	madd x1, x1, x2, x3
+	/* footprint_type(x13) * package size (x1) */
+	mul x1, x13, x1
+	/* footprint start address of corresponding package (x1) = package start address + header */
+	add x1, x1, x3
+
+	/*
+	 * footprint offset from start address of footprint buffer
+	 * cpuid(x0) * 4(x2) + (footprint start address of corresponding package)(x1)
+	 */
+	madd x1, x0, x2, x1
+
+	/* load & p_atf_log_ctrl->info.ptr_fp_pkg_start[0].footprint[0] */
+	adr x0, p_atf_log_ctrl
+	ldr x0, [x0]
+	ldr x0, [x0, #FOOTPRINT_PACKAGE_OFFSET]
+
+	/* package start address(x0) + offset(x1) */
+	str wzr, [x0, x1]
+	mov x30, x15
+	ret
+endfunc footprint_clear
+
+	/*
+	 * -----------------------------------------------------------------
+	 * void footprint_clear_by_cpuid(enum footprint_type fp_type, uint32_t cpuid)
+	 *
+	 * This function clear footprint of specific type and specific CPU
+	 * For low level debug
+	 *
+	 * In: X0 = footprint_type, X1 = cpuid
+	 * Out: N/A
+	 * Clobber: X0, X1, X2, X3, X13, X14
+	 * -----------------------------------------------------------------
+	 */
+func footprint_clear_by_cpuid
+	/* no sp, keep x0, x1 and x30 */
+	mov x13, x0	/* footprint_type */
+	mov x14, x1	/* cpuid */
+
+	/*
+	 * p_atf_log_ctrl->info.ptr_fp_pkg_start[fp_type].footprint[my_cpuid]
+	 * ptr_fp_pkg_start[fp_type].footprint[my_cpuid] = value;
+	 * Caculate offset from start address of footpring buffer
+	 * CPU# (x1=PLATFORM_CORE_COUNT) * fp size((x2=4))
+	 * (header (8) + fp_type_name (8)) (X3 =16)
+	 */
+	mov x1, #PLATFORM_CORE_COUNT
+	mov x2, #PER_CPU_FOOTPRINT_SIZE
+	mov x3, #SIZE_OF_HEADER_AND_NAME	/* size of heaer(8) + name_string(8) */
+
+	/* package size(x1) = PLATFORM_CORE_COUNT(x1) * 4(x2) + header&string (x3) */
+	madd x1, x1, x2, x3
+	/* footprint_type(x13) * package size (x1) */
+	mul x1, x13, x1
+	/* footprint start address of corresponding package (x1) = package start address + header */
+	add x1, x1, x3
+	/*
+	 * footprint offset from start address of footprint buffer
+	 * cpuid(x14) * 4 + (footprint start address of corresponding package)
+	 */
+	madd x1, x14, x2, x1
+
+	/* load & p_atf_log_ctrl->info.ptr_fp_pkg_start[0].footprint[0] */
+	adr x0, p_atf_log_ctrl
+	ldr x0, [x0]
+	ldr x0, [x0, #FOOTPRINT_PACKAGE_OFFSET]
+
+	/* package start address(x0) + offset(x1) */
+	str wzr, [x0, x1]
+	ret
+endfunc footprint_clear_by_cpuid
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/footprint.h b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/footprint.h
new file mode 100644
index 0000000..60e2197
--- /dev/null
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/footprint.h
@@ -0,0 +1,85 @@
+/*****************************************************************************
+ *
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Except as
+ * otherwise provided in  the applicable licensing terms with MediaTek Inc.
+ * and/or its licensors, any reproduction, modification, use or disclosure of
+ * MediaTek Software, and information contained herein, in whole or in part,
+ * shall be strictly prohibited.
+ *
+ *****************************************************************************/
+
+// SPDX-License-Identifier: BSD-3-Clause
+
+#ifndef FOOTPRINT_H
+#define FOOTPRINT_H
+
+#ifndef __ASSEMBLY__
+#include <cassert.h>
+#include <mtk_sip_svc.h>
+#include <platform_def.h>
+#endif
+
+#define ATF_FOOTPRINT_BUF_SIZE 2048
+#define MAX_FOOTPRINT_TYPE_STRING_SIZE 8	  /* 4 byte alignment */
+#define MAX_SUPPORTED_FOOTPRINT_TYPE 16
+#define ADDR_32_BITS_MASK 0xFFFFFFFF
+#define WORD_SHIFT_BITS 32
+#define FOOTPRINT_MAGIC_NUM 0xCA7FF007
+
+#define PER_CPU_FOOTPRINT_SIZE 4
+#define SIZE_OF_HEADER_AND_NAME (8 + MAX_FOOTPRINT_TYPE_STRING_SIZE)
+
+#ifndef __ASSEMBLY__
+
+#ifdef FOOTPRINT_DEF
+#undef FOOTPRINT_DEF
+#endif
+/* X macro, expend the defination */
+#define FOOTPRINT_DEF(a) a,
+
+enum footprint_type {
+#include <footprint_def.h>
+	FOOTPRINT_TYPE_MAX
+	};
+#undef FOOTPRINT_DEF
+
+/*
+ * each footprint package would look like
+  _________________________________
+ |        |      |                 |
+ | header   name   footprint arrah |
+ |________|______|_________________|
+
+*/
+
+struct footprint_header {
+	uint32_t size;
+	uint32_t magic;
+};
+
+struct footprint_package {
+	struct footprint_header header;
+	/* 4 bytes alignment */
+	uint8_t name_string[MAX_FOOTPRINT_TYPE_STRING_SIZE];	/* 8 */
+	uint32_t footprint[PLATFORM_CORE_COUNT];				/* 16*/
+};
+
+CASSERT(FOOTPRINT_TYPE_MAX < MAX_SUPPORTED_FOOTPRINT_TYPE,
+	footprint_type_are_more_than_16);
+
+CASSERT(MAX_SUPPORTED_FOOTPRINT_TYPE <=
+	(ATF_FOOTPRINT_BUF_SIZE/sizeof(struct footprint_package)),
+	ATF_FOOTPRINT_BUF_SIZE_is_too_small);
+
+
+void get_footprint_info(struct smc_retval *ret_val);
+void footprint_set(enum footprint_type fp_type, uint32_t value);
+void footprint_bit_set(enum footprint_type fp_type, uint32_t bit_index);
+void footprint_clear(enum footprint_type fp_type);
+void footprint_clear_by_cpuid(enum footprint_type fp_type, uint32_t cpuid);
+#endif
+
+#endif /* ifndef FOOTPRINT_H */
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/footprint_def.h b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/footprint_def.h
new file mode 100644
index 0000000..23a4ac5
--- /dev/null
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/footprint_def.h
@@ -0,0 +1,17 @@
+/*****************************************************************************
+ *
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Except as
+ * otherwise provided in  the applicable licensing terms with MediaTek Inc.
+ * and/or its licensors, any reproduction, modification, use or disclosure of
+ * MediaTek Software, and information contained herein, in whole or in part,
+ * shall be strictly prohibited.
+ *
+ *****************************************************************************/
+
+// SPDX-License-Identifier: BSD-3-Clause
+
+/* define your footprint with (YOURNAME) */
+FOOTPRINT_DEF(DRCC)
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/log.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/log.c
new file mode 100644
index 0000000..64f4e9a
--- /dev/null
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/log.c
@@ -0,0 +1,616 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+
+// SPDX-License-Identifier: BSD-3-Clause
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <debug.h>
+//#include <footprint.h>
+#include <gic_common.h>
+#include <gicv3.h>
+#include <log.h>
+#include <mmio.h>
+#include <mt_cpuxgpt.h>	/* sched_clock() */
+#include <mtk_plat_common.h>
+#include <mtk_sip_svc.h>
+#include <plat_private.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include <stdint.h>
+
+#define DEBUG_LOG_SERVICE 1
+#if DEBUG_LOG_SERVICE
+#define debug_print(...) NOTICE(__VA_ARGS__)
+#else
+#define debug_print(...) ((void)0)
+#endif
+
+static spinlock_t atf_buf_lock;
+static unsigned int atf_crash_write_offset;
+static unsigned int mt_log_buf_start;
+static unsigned int mt_log_buf_size;
+static unsigned int mt_log_buf_end;
+static unsigned int mt_log_sanity;
+
+/* X macro, expend the defination */
+#ifdef FOOTPRINT_DEF
+#undef FOOTPRINT_DEF
+#endif
+
+/*#define FOOTPRINT_DEF(a) #a,
+static const char *const_fp_name_list[MAX_SUPPORTED_FOOTPRINT_TYPE] = {
+#include <footprint_def.h>
+};
+#undef FOOTPRINT_DEF*/
+
+/* Record if the ATF log overwritten, if yes, print overwrtten log */
+static unsigned int is_log_overwritten;
+static uint64_t except_write_pos_per_cpu[PLATFORM_CORE_COUNT];
+
+unsigned int *mt_exception_buf_end;
+union atf_log_ctrl *p_atf_log_ctrl;
+unsigned int mt_log_ktime_sync;
+
+/*
+ * Set ptr_atf_crash_flg to ATF_BAD_PTR instead of NULL pointer, this
+ * could prevent any unexpect access before .bss initialization.
+ */
+unsigned int *ptr_atf_crash_flag = (unsigned int *)ATF_BAD_PTR;
+unsigned long *ptr_except_write_pos_per_cpu;
+uintptr_t atf_crash_buf_upper_bound_addr;
+
+#ifdef MTK_ATF_RAM_DUMP
+uint64_t	atf_ram_dump_base;
+uint64_t	atf_ram_dump_size;
+spinlock_t	atf_ram_dump_lock;
+#endif
+
+#if !LOG_USE_SPIN_LOCK
+DEFINE_BAKERY_LOCK(log_lock);
+#endif
+
+unsigned int get_is_log_overwritten(void)
+{
+	return is_log_overwritten;
+}
+
+void clr_is_log_overwritten(void)
+{
+	is_log_overwritten = 0;
+}
+
+void mt_log_suspend_flush(void)
+{
+	if (mt_log_buf_size != 0)
+		flush_dcache_range((uint64_t)mt_log_buf_start, (uint64_t)mt_log_buf_size);
+}
+
+/* don't use any print function here in this function */
+int mt_log_lock_acquire(void)
+{
+#if LOG_USE_SPIN_LOCK
+	spin_lock(&atf_buf_lock);
+#else
+	bakery_lock_get(&log_lock);
+#endif
+	return 0;
+}
+
+/* don't use any print function here in this function */
+int mt_log_write(unsigned char c)
+{
+	/* p_atf_log_ctrl->info.atf_log_addr = start + ATF_LOG_CTRL_BUF_SIZE; */
+	*(unsigned char *)(uintptr_t)(p_atf_log_ctrl->info.atf_log_addr +
+								p_atf_log_ctrl->info.atf_write_offset) = c;
+
+	if (p_atf_log_ctrl->info.atf_total_write_count <= ATF_CRASH_LAST_LOG_SIZE)
+		p_atf_log_ctrl->info.atf_total_write_count++;
+
+	/*
+	 * |--- Ctrl  ---|--- Ring Buffer ---|--- Crash Log -|-Except-|--- AEE buffer --|
+	 * clean		  clean			  keep			keep		clean
+	 *
+	 *	p_atf_log_ctrl->info.atf_log_size = size -
+	 *		ATF_LOG_CTRL_BUF_SIZE - aee_buf_size -
+	 *		ATF_CRASH_LAST_LOG_SIZE - ATF_EXCEPT_BUF_SIZE;
+	 */
+
+	p_atf_log_ctrl->info.atf_write_offset++;
+	p_atf_log_ctrl->info.atf_write_offset = p_atf_log_ctrl->info.atf_write_offset %
+										p_atf_log_ctrl->info.atf_log_size;
+
+	if (p_atf_log_ctrl->info.atf_write_offset == p_atf_log_ctrl->info.atf_read_offset) {
+		/* write_pos cross read_pos */
+		is_log_overwritten = 1;
+	}
+
+	return 0;
+}
+
+static int mt_crash_log_write(unsigned char c)
+{
+	/* p_atf_log_ctrl->info.atf_log_addr = start + ATF_LOG_CTRL_BUF_SIZE; */
+	*(unsigned char *)(uintptr_t)(p_atf_log_ctrl->info.atf_crash_log_addr + atf_crash_write_offset) = c;
+
+	/*
+	 * |- Ctrl -|- Ring Buffer -|- Crash Log -|-Except-|- AEE buffer -|
+	 *    clean       clean           keep       keep       clean
+	 *
+	 *	p_atf_log_ctrl->info.atf_log_size = size -
+	 *	ATF_LOG_CTRL_BUF_SIZE - aee_buf_size -
+	 *	ATF_CRASH_LAST_LOG_SIZE - ATF_EXCEPT_BUF_SIZE;
+	 */
+
+	atf_crash_write_offset++;
+	atf_crash_write_offset = atf_crash_write_offset % p_atf_log_ctrl->info.atf_crash_log_size;
+
+	return 0;
+}
+
+static void show_atf_wdt_timestamp(void)
+{
+	int cpu;
+
+	atf_crash_write_offset = 0;
+	/* direct atf log write crash_log_write() */
+	bl31_log_service_register(NULL, &mt_crash_log_write, NULL);
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
+		/* cannot merge in a line, */
+		/* it will caused the print buffer overflow */
+		NOTICE("[%s] CPU[%d] IRQ[%u]",
+			/* check it timestamp sync with kernel wall time */
+		((p_atf_log_ctrl->info.enter_atf_fiq_irq_num[cpu] >>
+			MT_LOG_KTIME_FLAG_SHIFT) & 0x1)?"K":"'A",
+			cpu,
+			/* keep IRQ numeber only, remove MT_LOG_KTIME flag */
+			(p_atf_log_ctrl->info.enter_atf_fiq_irq_num[cpu] & IAR0_EL1_INTID_MASK));
+
+		NOTICE("enter(%llu)", p_atf_log_ctrl->info.fiq_irq_enter_timestamp[cpu]);
+		NOTICE("quit(%llu)\n", p_atf_log_ctrl->info.fiq_irq_quit_timestamp[cpu]);
+	}
+	/* unregister crash_log_write() */
+	bl31_log_service_register(NULL, NULL, NULL);
+}
+
+int mt_crash_log_dump_sanity(union atf_log_ctrl *ctrl, uint64_t start,
+	uint32_t size, uint32_t aee_buf_size)
+{
+	uint32_t ring_buf_size = (size - ATF_LOG_CTRL_BUF_SIZE -
+		ATF_FOOTPRINT_BUF_SIZE - ATF_CRASH_LAST_LOG_SIZE -
+		ATF_EXCEPT_BUF_SIZE - aee_buf_size);
+
+	uint64_t atf_log_addr_sanity = start + ATF_LOG_CTRL_BUF_SIZE;
+
+	if (ATF_LAST_LOG_MAGIC_NO != ctrl->info.atf_crash_flag && ATF_CRASH_MAGIC_NO != ctrl->info.atf_crash_flag)
+		goto FAIL;
+
+	if (ctrl->info.atf_log_addr != atf_log_addr_sanity)
+		goto FAIL;
+	if (ctrl->info.atf_log_size != ring_buf_size)
+		goto FAIL;
+	if (ctrl->info.atf_crash_log_addr != (start + ATF_LOG_CTRL_BUF_SIZE) +
+				ring_buf_size + ATF_FOOTPRINT_BUF_SIZE)
+		goto FAIL;
+	if (ctrl->info.atf_write_offset > ring_buf_size)
+		goto FAIL;
+	if (ctrl->info.atf_read_offset > ring_buf_size)
+		goto FAIL;
+
+	return 1;
+FAIL:
+	INFO("atf RAW dump\n");
+	return 0;
+
+}
+
+int mt_crash_log_dump(uint8_t *crash_log_addr, uint32_t crash_log_size,
+uint64_t start, uint32_t size, uint32_t aee_buf_size)
+{
+	uint64_t ret = 0;
+	uint64_t read_count;
+	uint64_t offset;
+	uint64_t write_count = p_atf_log_ctrl->info.atf_total_write_count;
+	uint8_t *r_ptr = NULL;
+	uint8_t *w_ptr = NULL;
+	uint8_t *start_ptr = (uint8_t *)p_atf_log_ctrl->info.atf_log_addr;
+
+	/* Sanity check */
+	if (!mt_crash_log_dump_sanity(p_atf_log_ctrl, start, size, aee_buf_size))
+		return 0;
+	if (write_count == 0)
+		return 0;
+	if (write_count > crash_log_size) {
+		offset = crash_log_size-1;
+		read_count = crash_log_size;
+	} else {
+		offset = write_count-1;
+		read_count = write_count;
+	}
+
+	/* p_atf_log_ctrl->info.atf_log_addr = start + ATF_LOG_CTRL_BUF_SIZE; */
+	r_ptr = (uint8_t *)((uintptr_t)p_atf_log_ctrl->info.atf_log_addr +
+						(uintptr_t)p_atf_log_ctrl->info.atf_write_offset);/*offset*/
+
+	w_ptr = crash_log_addr + offset;
+	while (read_count) {
+		*(w_ptr--) = *(r_ptr--);
+		if (r_ptr < start_ptr)
+			r_ptr = (uint8_t *)(uintptr_t)mt_log_buf_end;
+		read_count--;
+		ret++;
+	}
+
+	return ret;
+}
+
+
+/* don't use any print function here in this function */
+int mt_log_lock_release(void)
+{
+	/* release the lock */
+#if LOG_USE_SPIN_LOCK
+	spin_unlock(&atf_buf_lock);
+#else
+	bakery_lock_release(&log_lock);
+#endif
+	return 0;
+}
+
+/*
+ * uint32_t is_power_on_boot(void)
+ * {
+ *	uint32_t wdt_sta, wdt_interval;
+ *	wdt_sta = mmio_read_32(MTK_WDT_STATUS);
+ *	wdt_interval = mmio_read_32(MTK_WDT_INTERVAL);
+ *	NOTICE("sta=0x%x int=0x%x\r\n", wdt_sta, wdt_interval);
+ *
+ *	Bit 2: IS_POWER_ON_RESET.
+ *	(bit2 will be set in preloader when reboot_from power on)
+ *	if(wdt_interval & (1<<2))
+ *		return 1;
+ *	return 0;
+ * }
+ */
+
+void mt_log_set_crash_flag(void)
+{
+	p_atf_log_ctrl->info.atf_crash_flag = ATF_CRASH_MAGIC_NO;
+}
+
+uint64_t mt_log_get_crash_log_addr(void)
+{
+	if (!mt_log_sanity)
+		return (uint64_t) gteearg.atf_log_buf_start;
+	else
+		return p_atf_log_ctrl->info.atf_crash_log_addr;
+}
+
+uint64_t mt_log_get_crash_log_size(void)
+{
+	if (!mt_log_sanity)
+		return (uint64_t) gteearg.atf_log_buf_size;
+	else
+		return p_atf_log_ctrl->info.atf_crash_log_size;
+}
+
+unsigned int *mt_log_get_crash_flag_addr(void)
+{
+	return ptr_atf_crash_flag;
+}
+
+/*void footprint_init(uint64_t footprint_buf_addr, uint32_t clear_footprint)
+{
+	uint32_t i;
+	size_t string_len;
+
+	
+	p_atf_log_ctrl->info.ptr_fp_pkg_start =
+		(struct footprint_package *) footprint_buf_addr;
+
+	INFO("FOOTPRINT_TYPE_MAX: 0x%x\n", FOOTPRINT_TYPE_MAX);
+
+	if (clear_footprint == 1) {
+		
+		memset((void *)(uintptr_t)footprint_buf_addr, 0x0, ATF_FOOTPRINT_BUF_SIZE);
+
+		for (i = 0; i < FOOTPRINT_TYPE_MAX; i++) {
+			
+			p_atf_log_ctrl->info.ptr_fp_pkg_start[i].header.size =
+				sizeof(struct footprint_package);
+			p_atf_log_ctrl->info.ptr_fp_pkg_start[i].header.magic =
+				FOOTPRINT_MAGIC_NUM;
+
+			
+			string_len = strlen(const_fp_name_list[i]);
+			if (string_len > 0) {
+				memcpy(&p_atf_log_ctrl->info.ptr_fp_pkg_start[i].name_string[0],
+					const_fp_name_list[i],
+					string_len > MAX_FOOTPRINT_TYPE_STRING_SIZE ?
+						MAX_FOOTPRINT_TYPE_STRING_SIZE : string_len);
+				
+				p_atf_log_ctrl->info.ptr_fp_pkg_start[i].
+					name_string[MAX_FOOTPRINT_TYPE_STRING_SIZE-1] = '\0';
+			}
+		}
+	}
+}
+
+void get_footprint_info(struct smc_retval *pret_val)
+{
+	
+	pret_val->ret0 = (uint64_t)(((uint64_t)p_atf_log_ctrl->info.ptr_fp_pkg_start >> WORD_SHIFT_BITS) &
+						ADDR_32_BITS_MASK);
+	
+	pret_val->ret1 = (uint64_t)((uint64_t)p_atf_log_ctrl->info.ptr_fp_pkg_start & ADDR_32_BITS_MASK);
+	
+	pret_val->ret2 = ATF_FOOTPRINT_BUF_SIZE;
+}*/
+
+void mt_log_setup(uint64_t start, unsigned int size,
+	unsigned int aee_buf_size, unsigned int is_abnormal_boot)
+{
+	uint32_t dump_ret = 0;
+	int i;
+	uint32_t local_flag = 0;
+	uint64_t ring_buf_size = (size - ATF_LOG_CTRL_BUF_SIZE -
+		ATF_FOOTPRINT_BUF_SIZE - ATF_CRASH_LAST_LOG_SIZE -
+		ATF_EXCEPT_BUF_SIZE - aee_buf_size);
+
+	mt_log_buf_start = start;
+	mt_log_buf_size = size;
+	mt_log_buf_end = start + ATF_LOG_CTRL_BUF_SIZE + ring_buf_size - 1;
+	mt_exception_buf_end =
+		(unsigned int *)(uintptr_t)(start + size - 1 - aee_buf_size);
+
+	p_atf_log_ctrl = (union atf_log_ctrl *)(uintptr_t)start;
+#if !LOG_USE_SPIN_LOCK
+	bakery_lock_init(&log_lock);
+#endif
+	/* Initialize those two pointers for mt_console_core_putc */
+	ptr_except_write_pos_per_cpu =
+		(unsigned long *) &except_write_pos_per_cpu[0];
+	INFO("abnormal_boot: 0x%x, cflag: 0x%x\n",
+		is_abnormal_boot, p_atf_log_ctrl->info.atf_crash_flag);
+
+	if (!is_abnormal_boot || ATF_DUMP_DONE_MAGIC_NO ==
+					p_atf_log_ctrl->info.atf_crash_flag) {
+		memset((void *)(uintptr_t)start, 0x0, size);
+		p_atf_log_ctrl->info.atf_crash_flag = ATF_LAST_LOG_MAGIC_NO;
+		p_atf_log_ctrl->info.atf_crash_log_size = ATF_CRASH_LAST_LOG_SIZE;
+		/* footprint==1 for clear footprint fields */
+		//footprint_init(start + ATF_LOG_CTRL_BUF_SIZE + ring_buf_size, 1);
+	} else {
+		dump_ret = mt_crash_log_dump(
+		(uint8_t *)(uintptr_t)p_atf_log_ctrl->info.atf_crash_log_addr,
+		ATF_CRASH_LAST_LOG_SIZE, start, size, aee_buf_size);
+
+		if (dump_ret) {
+			/* dump ATF timestamp, when atf_log_ctrl_buf correct */
+			show_atf_wdt_timestamp();
+
+			local_flag = p_atf_log_ctrl->info.atf_crash_flag;
+
+			/*
+			 * |--- Ctrl ---|--- Ring Buffer ---|--- footprint Buffer ---|
+			 *      clean         clean			    keep
+			 *
+			 * |--- Crash Log -|-Except-|--- AEE buffer --|
+			 *       keep          keep        clean
+			 */
+
+			memset((void *)(uintptr_t)start, 0x0,
+					(ATF_LOG_CTRL_BUF_SIZE + ring_buf_size));
+			memset((void *)(uintptr_t)(start+(size-aee_buf_size)), 0x0, aee_buf_size);
+
+			/* write crash info back to control buffer */
+			if (local_flag == ATF_LAST_LOG_MAGIC_NO) {
+				p_atf_log_ctrl->info.atf_crash_log_size = ATF_CRASH_LAST_LOG_SIZE;
+				p_atf_log_ctrl->info.atf_crash_flag = ATF_LAST_LOG_MAGIC_NO;
+			} else if (local_flag == ATF_CRASH_MAGIC_NO) {
+				p_atf_log_ctrl->info.atf_crash_log_size = ATF_CRASH_LAST_LOG_SIZE + ATF_EXCEPT_BUF_SIZE;
+				p_atf_log_ctrl->info.atf_crash_flag = ATF_CRASH_MAGIC_NO;
+				INFO("atf_crash_flag = ATF_CRASH_MAGIC_NO\n");
+			}
+			/* footprint==0 for keep footprint fields */
+			//footprint_init(start + ATF_LOG_CTRL_BUF_SIZE + ring_buf_size, 0);
+		} else{
+			/* Can't pass ATF log sanity, dump entire atf log buffer */
+			mt_log_sanity = 0;
+			ptr_atf_crash_flag = &p_atf_log_ctrl->info.atf_crash_flag;
+			flush_dcache_range(start, size);
+
+			/* Don't modify Buffer and register information, just dump */
+			return;
+		}
+	}
+
+	atf_buf_lock.lock = 0;
+
+	p_atf_log_ctrl->info.atf_crash_log_addr = (start + ATF_LOG_CTRL_BUF_SIZE) +
+			ring_buf_size + ATF_FOOTPRINT_BUF_SIZE;
+
+	p_atf_log_ctrl->info.atf_log_addr = start + ATF_LOG_CTRL_BUF_SIZE;
+	p_atf_log_ctrl->info.atf_log_size = ring_buf_size;
+	p_atf_log_ctrl->info.atf_write_offset = 0;
+	p_atf_log_ctrl->info.atf_read_offset = 0;
+
+	INFO("mt_log_setup\n");
+	INFO(" -atf_buf_lock: 0x%x\n", atf_buf_lock.lock);
+	INFO(" -mt_log_buf_start: 0x%x\n", mt_log_buf_start);
+	INFO(" -mt_log_buf_size: 0x%x\n", mt_log_buf_size);
+	INFO(" -log_addr: 0x%llx\n", p_atf_log_ctrl->info.atf_log_addr);
+	INFO(" -log_size: 0x%llx\n", p_atf_log_ctrl->info.atf_log_size);
+	INFO(" -write_offset: 0x%x\n", p_atf_log_ctrl->info.atf_write_offset);
+	INFO(" -read_offset: 0x%x\n", p_atf_log_ctrl->info.atf_read_offset);
+	INFO(" -log_buf_end : 0x%x\n", mt_log_buf_end);
+	INFO(" -ATF_EXCEPT_BUF_SIZE_PER_CPU : 0x%x\n", ATF_EXCEPT_BUF_SIZE_PER_CPU);
+	INFO(" -ATF_EXCEPT_BUF_SIZE : 0x%x\n", ATF_EXCEPT_BUF_SIZE);
+	INFO(" -PLATFORM_CORE_COUNT : 0x%x\n", PLATFORM_CORE_COUNT);
+	atf_crash_buf_upper_bound_addr = start + (size - aee_buf_size) - 1;
+
+	/*	*/
+	/* |--- Ctrl ---|--- Ring Buffer ---|--- footprint Buffer ---| */
+	/*		clean		  clean				keep	*/
+	/*													*/
+	/* |--- Crash Log -|-Except-|--- AEE buffer --|	*/
+	/*		 keep		   keep	   clean			*/
+	/*	*/
+
+	for (i = 0; i < PLATFORM_CORE_COUNT; i++) {
+		except_write_pos_per_cpu[i] =
+			(start + ATF_LOG_CTRL_BUF_SIZE + ring_buf_size +
+			ATF_FOOTPRINT_BUF_SIZE + ATF_CRASH_LAST_LOG_SIZE) +
+			(i * ATF_EXCEPT_BUF_SIZE_PER_CPU);
+		INFO(" -except_write_pos_per_cpu[%d]: 0x%llx\n", i,
+			except_write_pos_per_cpu[i]);
+	}
+
+	INFO(" -crash_flag : 0x%x\n", p_atf_log_ctrl->info.atf_crash_flag);
+	INFO(" -crash_log_addr : 0x%llx\n", p_atf_log_ctrl->info.atf_crash_log_addr);
+	INFO(" -crash_log_size : 0x%llx\n", p_atf_log_ctrl->info.atf_crash_log_size);
+
+	bl31_log_service_register(&mt_log_lock_acquire, &mt_log_write,
+		&mt_log_lock_release);
+
+	mt_log_sanity = 1;
+	/* Record if the ATF log overwritten */
+	is_log_overwritten = 0;
+	ptr_atf_crash_flag = &p_atf_log_ctrl->info.atf_crash_flag;
+
+	flush_dcache_range(start, size);
+}
+
+#define MT_LOG_SECURE_OS_BUFFER_MAX_LENGTH 120
+#define TBASE_TAG "TBASE"
+static unsigned char mt_log_secure_os_buf[MT_LOG_SECURE_OS_BUFFER_MAX_LENGTH+1] = {0};
+static unsigned int mt_log_secure_os_pos;
+
+void mt_log_secure_os_print(int c)
+{
+	mt_log_secure_os_buf[mt_log_secure_os_pos] = c;
+
+	/* Force to flush the buffer if find end of line */
+	if (c == '\n') {
+		mt_log_secure_os_buf[mt_log_secure_os_pos+1] = '\0';
+#if CFG_MICROTRUST_TEE_SUPPORT
+	NOTICE("[%s]%s", "uTos", mt_log_secure_os_buf);
+#elif CFG_TRUSTKERNEL_TEE_SUPPORT
+	NOTICE("[%s]%s", "TKCore", mt_log_secure_os_buf);
+#else
+	NOTICE("[%s]%s", TBASE_TAG, mt_log_secure_os_buf);
+#endif
+		mt_log_secure_os_pos = 0;
+		return;
+	}
+
+	mt_log_secure_os_pos++;
+
+	/* Already reach the end of buffer, force to flush the buffer */
+	if (mt_log_secure_os_pos == MT_LOG_SECURE_OS_BUFFER_MAX_LENGTH)	{
+		mt_log_secure_os_buf[mt_log_secure_os_pos] = '\0';
+#if CFG_MICROTRUST_TEE_SUPPORT
+	NOTICE("[%s]%s", "uTos", mt_log_secure_os_buf);
+#elif CFG_TRUSTKERNEL_TEE_SUPPORT
+	NOTICE("[%s]%s", "TKCore", mt_log_secure_os_buf);
+#else
+	NOTICE("[%s]%s", TBASE_TAG, mt_log_secure_os_buf);
+#endif
+		mt_log_secure_os_pos = 0;
+	}
+}
+
+static void flush_log_ctrl_cache(void)
+{
+	flush_dcache_range((unsigned long)p_atf_log_ctrl,
+			ATF_LOG_CTRL_BUF_SIZE);
+}
+
+void atf_enter_timestamp(unsigned int irq)
+{
+	uint64_t mpidr = 0;
+	uint32_t cpu = 0;
+	unsigned long long cur_time;
+
+	mpidr = read_mpidr();
+	cpu = plat_core_pos_by_mpidr(mpidr);
+
+	/* in ATF boot time, tiemr for cntpct_el0 is not initialized
+	 * so it will not count now.
+	 */
+#if !defined(ATF_BYPASS_DRAM)
+	cur_time = atf_sched_clock();
+#else
+	cur_time = 0;
+#endif
+
+	p_atf_log_ctrl->info.fiq_irq_enter_timestamp[cpu] = cur_time;
+	p_atf_log_ctrl->info.enter_atf_fiq_irq_num[cpu] = irq;
+
+	/* if timestamp is not sync. to kernel, or a bit 31 as flag */
+	if (MT_LOG_KTIME) {
+		p_atf_log_ctrl->info.enter_atf_fiq_irq_num[cpu] = p_atf_log_ctrl->info.enter_atf_fiq_irq_num[cpu] |
+						(1 << MT_LOG_KTIME_FLAG_SHIFT);
+	}
+}
+
+void atf_exit_timestamp(void)
+{
+	uint64_t mpidr = 0;
+	uint32_t cpu = 0;
+	unsigned long long cur_time;
+
+	mpidr = read_mpidr();
+	cpu = plat_core_pos_by_mpidr(mpidr);
+
+#if !defined(ATF_BYPASS_DRAM)
+	cur_time = atf_sched_clock();
+#else
+	cur_time = 0;
+#endif
+
+	/* only WDT or SGI will record the exit timestamp */
+	if ((p_atf_log_ctrl->info.enter_atf_fiq_irq_num[cpu] & IAR0_EL1_INTID_MASK)
+			== WDT_IRQ_BIT_ID ||
+		(p_atf_log_ctrl->info.enter_atf_fiq_irq_num[cpu] & IAR0_EL1_INTID_MASK)
+			== FIQ_SMP_CALL_SGI) {
+		p_atf_log_ctrl->info.fiq_irq_quit_timestamp[cpu] = cur_time;
+		flush_log_ctrl_cache();
+	}
+}
+
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/log.h b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/log.h
new file mode 100644
index 0000000..1b2eb27
--- /dev/null
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/debug/log.h
@@ -0,0 +1,181 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+
+// SPDX-License-Identifier: BSD-3-Clause
+
+/******************************************************************************
+*
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+#ifndef ATF_LOG_DRV_H
+#define ATF_LOG_DRV_H
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <spinlock.h>
+#include <stdint.h>
+#include <platform_def.h>
+#endif
+#define ATF_LOG_CTRL_BUF_SIZE 512
+#define ATF_CRASH_MAGIC_NO	0xdead1abf
+#define ATF_LAST_LOG_MAGIC_NO	0x41544641
+#define ATF_BAD_PTR		0xffffffff
+#define ATF_DUMP_DONE_MAGIC_NO	0xd07ed07e
+
+#define LOG_USE_SPIN_LOCK	0
+#define MT_LOG_KTIME_FLAG_SHIFT 31
+
+/*
+ *  ___________________________
+ * |                           |
+ * | ATF crash reserved buffer |
+ * |___________________________|
+ *
+ *
+ * Total reserved buffer size = ATF_CRASH_LAST_LOG_SIZE + ATF_EXCEPT_BUF_SIZE
+ *
+ * +--------------------------------+--------------------------------------------------------+
+ * |    ATF_CRASH_LAST_LOG_SIZE     |    ATF_EXCEPT_BUF_SIZE_PER_CPU * PLATFORM_CORE_COUNT   |
+ * +--------------------------------+--------------------------------------------------------+
+ * |    Last ATF log for crash      | CPU-0 | CPU-1| CPU-2 | CPU-3 |...PLATFORM_CORE_COUNT-1 |
+ * +--------------------------------+--------------------------------------------------------+
+ */
+#define ATF_CRASH_LAST_LOG_SIZE (64*1024)
+#define ATF_EXCEPT_BUF_SIZE_PER_CPU (4*1024)
+#define ATF_EXCEPT_BUF_SIZE (ATF_EXCEPT_BUF_SIZE_PER_CPU * PLATFORM_CORE_COUNT)
+
+/* footprint part define */
+#define ATF_FOOTPRINT_BUF_SIZE 2048
+#define MAX_FOOTPRINT_TYPE_STRING_SIZE 8	  /* 4 byte alignment */
+#define MAX_SUPPORTED_FOOTPRINT_TYPE 16
+#define ADDR_32_BITS_MASK 0xFFFFFFFF
+#define WORD_SHIFT_BITS 32
+#define FOOTPRINT_MAGIC_NUM 0xCA7FF007
+
+#define PER_CPU_FOOTPRINT_SIZE 4
+#define SIZE_OF_HEADER_AND_NAME (8 + MAX_FOOTPRINT_TYPE_STRING_SIZE)
+/* footprint end */
+
+/* if struct is modified, please update the offset*/
+#define FOOTPRINT_PACKAGE_OFFSET	48
+
+#ifndef __ASSEMBLY__
+
+extern unsigned int mt_log_ktime_sync;
+
+#define MT_LOG_KTIME_CLEAR() { mt_log_ktime_sync = 0; }
+#define MT_LOG_KTIME_SET() { mt_log_ktime_sync = 1; }
+#define MT_LOG_KTIME mt_log_ktime_sync
+
+struct footprint_header {
+	uint32_t size;
+	uint32_t magic;
+};
+
+struct footprint_package {
+	struct footprint_header header;
+	/* 4 bytes alignment */
+	uint8_t name_string[MAX_FOOTPRINT_TYPE_STRING_SIZE];	/* 8 */
+	uint32_t footprint[PLATFORM_CORE_COUNT];				/* 16*/
+};
+
+
+union atf_log_ctrl {
+	struct {
+	uint64_t atf_log_addr;			/* 0 */
+	uint64_t atf_log_size;
+	uint32_t atf_write_offset;
+	uint32_t atf_read_offset;
+
+	/* must keep value after reboot */
+	uint64_t atf_crash_log_addr;	/* 24 */
+	uint64_t atf_crash_log_size;
+	uint32_t atf_total_write_count;
+	uint32_t atf_crash_flag;
+	struct footprint_package *ptr_fp_pkg_start;	/* 48 */
+
+	/* for FIQ/IRQ footprint, print in crash log*/
+	uint64_t fiq_irq_enter_timestamp[PLATFORM_CORE_COUNT];
+	uint64_t fiq_irq_quit_timestamp[PLATFORM_CORE_COUNT];
+	uint32_t enter_atf_fiq_irq_num[PLATFORM_CORE_COUNT];
+	} info;
+	unsigned char data[ATF_LOG_CTRL_BUF_SIZE];
+};
+
+/* Check union atf_log_ctrl size */
+CASSERT(sizeof(union atf_log_ctrl) <= ATF_LOG_CTRL_BUF_SIZE,
+		atf_log_ctrl_t_is_larger_than_ATF_LOG_CTRL_BUF_SIZE);
+
+void mt_log_setup(uint64_t start, unsigned int size, unsigned int aee_buf_size, unsigned int is_abnormal_boot);
+int mt_log_lock_acquire(void);
+int mt_log_write(unsigned char c);
+int mt_log_lock_release(void);
+void bl31_log_service_register(int (*lock_get)(),
+	int (*log_putc)(unsigned char),
+	int (*lock_release)());
+void print_log_timestamp(void);
+void print_overwritten_msg(void);
+
+extern int (*log_write)(unsigned char);
+extern int (*log_lock_acquire)();
+extern int (*log_lock_release)();
+
+void mt_log_suspend_flush(void);
+void mt_log_secure_os_print(int c);
+
+uint64_t mt_log_get_crash_log_addr(void);
+uint64_t mt_log_get_crash_log_size(void);
+unsigned int *mt_log_get_crash_flag_addr(void);
+
+void atf_enter_timestamp(unsigned int irq);
+void atf_exit_timestamp(void);
+unsigned int get_is_log_overwritten(void);
+void clr_is_log_overwritten(void);
+
+#ifdef MTK_ATF_RAM_DUMP
+extern uint64_t	atf_ram_dump_base;
+extern uint64_t	atf_ram_dump_size;
+#endif
+#endif
+#endif
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/spm/mt_spm_suspend.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/spm/mt_spm_suspend.c
index e969d1b..4ff1430 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/spm/mt_spm_suspend.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/spm/mt_spm_suspend.c
@@ -33,7 +33,8 @@
 	(SPM_FLAG_ENABLE_MD_MUMTAS) | \
 	(SPM_FLAG_USE_SRCCLKENO2) | \
 	(SPM_FLAG_NETSYS_DVFS_ENABLE))
-//jb.qi change for abnormal resume on 20230328
+
+    /*jb.qi add SPM_FLAG_ENABLE_MD_MUMTAS for abnormal resume on 20230328*/
 #define SPM_SUSPEND_SLEEP_PCM_FLAG1		(0)
 
 #define SPM_SUSPEND_PCM_FLAG	( \
@@ -43,7 +44,9 @@
 	(SPM_FLAG_ENABLE_PCIE_0P6V_WORKAROUND) | \
 	(SPM_FLAG_ENABLE_MD_MUMTAS) | \
 	(SPM_FLAG_NETSYS_DVFS_ENABLE))
-//jb.qi change for abnormal resume on 20230328
+
+    /*jb.qi add SPM_FLAG_ENABLE_MD_MUMTAS for abnormal resume on 20230328*/
+
 #define SPM_SUSPEND_PCM_FLAG1		(0)
 
 /* Suspend spm power control */
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/include/platform_def.h b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/include/platform_def.h
index 15bb062..edf1ada 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/include/platform_def.h
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/include/platform_def.h
@@ -241,8 +241,8 @@
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
 #define ADDR_SPACE_SIZE		(1ull << 32)
-#define MAX_XLAT_TABLES		16
-#define MAX_MMAP_REGIONS	50
+#define MAX_XLAT_TABLES		32
+#define MAX_MMAP_REGIONS	128
 
 /*******************************************************************************
  * Declarations and constants to access the mailboxes safely. Each mailbox is
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/mpu_ctrl/plat_mpu_feats.h b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/mpu_ctrl/plat_mpu_feats.h
index cdc6f76..d0df868 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/mpu_ctrl/plat_mpu_feats.h
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/mpu_ctrl/plat_mpu_feats.h
@@ -68,7 +68,7 @@
 			.d11 = FORBIDDEN, .d10 = FORBIDDEN,
 			.d9  = NO_PROTECTION, .d8  = NO_PROTECTION,
 			.d7  = SEC_R_NSEC_R, .d6  = SEC_R_NSEC_RW,
-			.d5  = NO_PROTECTION, .d4  = NO_PROTECTION,
+			.d5  = NO_PROTECTION, .d4  = NO_PROTECTION,   /*[API-1244][wifi]when insmod wifi driver access dramin 5 cuse system reboot --on Sep 1 2023*/
 			.d3  = FORBIDDEN, .d2  = FORBIDDEN,
 			.d1  = SEC_R_NSEC_R, .d0  = NO_PROTECTION,
 		}, },
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/plat_sip_svc.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/plat_sip_svc.c
index f70dd6d..cc2a997 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/plat_sip_svc.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/plat_sip_svc.c
@@ -124,6 +124,11 @@
 	uint64_t rc = 0;
 	uint32_t ns;
 	atf_arg_t_ptr teearg = &gteearg;
+  	uint64_t atf_crash_log_addr;
+ 	uint64_t atf_crash_log_size;
+ 	uint64_t atf_crash_flag_high_addr;
+ 	uint64_t atf_crash_flag_low_addr;
+ 	uint32_t *atf_crash_flag_addr_ptr;
 
 	/* Determine which security state this SMC originated from */
 	ns = is_caller_non_secure(flags);
@@ -428,6 +433,26 @@
 		case MTK_SIP_HSM_CLOCK_OFF_AARCH64:
 			hsm_clock_off();
 			break;
+		case MTK_SIP_LK_DUMP_ATF_LOG_INFO_AARCH32:
+		case MTK_SIP_LK_DUMP_ATF_LOG_INFO_AARCH64:
+		{
+			console_init(teearg->atf_log_port, MT2735_UART_CLOCK, MT2735_BAUDRATE);
+			atf_crash_log_addr = mt_log_get_crash_log_addr();
+			atf_crash_log_size = mt_log_get_crash_log_size();
+			atf_crash_flag_addr_ptr = mt_log_get_crash_flag_addr();
+			atf_crash_flag_low_addr = (uint64_t)atf_crash_flag_addr_ptr & 0xffffffff;
+			atf_crash_flag_high_addr = ((uint64_t)atf_crash_flag_addr_ptr >> 32) & 0xffffffff;
+
+			INFO("Get ATF log buffer info. for AEE dump in LK.\n");
+			INFO("Buf addr:0x%llx, buf size:%llu, flag addr:0x%llx, flag value:0x%x\n",
+				atf_crash_log_addr, atf_crash_log_size,
+				atf_crash_flag_low_addr, *atf_crash_flag_addr_ptr);
+
+			console_uninit();
+			SMC_RET4(handle, atf_crash_log_addr, atf_crash_log_size,
+				atf_crash_flag_low_addr, atf_crash_flag_high_addr);
+			break;
+		}
 		default:
 			rc = SMC_UNK;
 			console_init(gteearg.atf_log_port, MT2735_UART_CLOCK, MT2735_BAUDRATE);
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/platform.mk b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/platform.mk
index 4e6b92a..eb36566 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/platform.mk
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/platform.mk
@@ -39,7 +39,8 @@
 
 include lib/xlat_tables_v2/xlat_tables.mk
 
-PLAT_INCLUDES		:=	-I${MTK_PLAT_SOC}/common/				\
+PLAT_INCLUDES		:=	-I${MTK_PLAT_SOC}/drivers/debug/		\
+				-I${MTK_PLAT_SOC}/common/				\
 				-I${MTK_PLAT}/common/ 	                      \
 				-I${MTK_PLAT_SOC}/				\
 				-I${MTK_PLAT_SOC}/drivers/			\
@@ -73,7 +74,8 @@
 PLAT_BL_COMMON_SOURCES	:=	${XLAT_TABLES_LIB_SRCS}  			\
 				plat/common/plat_gicv2.c
 
-BL31_SOURCES		+=	${MTK_PLAT_SOC}/drivers/arm/cci/cci.c				\
+BL31_SOURCES		+=	${MTK_PLAT_SOC}/drivers/debug/log.c				\
+                ${MTK_PLAT_SOC}/drivers/arm/cci/cci.c				\
 				${MTK_PLAT_SOC}/drivers/arm/gic/common/gic_common.c		\
 				${MTK_PLAT_SOC}/drivers/arm/gic/v3/gicv3_main.c			\
 				${MTK_PLAT_SOC}/drivers/arm/gic/v3/gicv3_helpers.c		\
@@ -87,7 +89,6 @@
 				${MTK_PLAT_SOC}/common/mtk_rgu.c		\
 				${MTK_PLAT}/common/fiq_smp_call.c		\
 				${MTK_PLAT_SOC}/common/plat_aee_debug.c		\
-				${MTK_PLAT}/common/log.c			\
 				${MTK_PLAT_SOC}/aarch64/plat_helpers.S		\
 				${MTK_PLAT_SOC}/aarch64/platform_common.c	\
 				${MTK_PLAT_SOC}/bl31_plat_setup.c		\
diff --git a/src/bsp/trustzone/teeloader/mt2735/default.mak b/src/bsp/trustzone/teeloader/mt2735/default.mak
index 5dc9038..5003be6 100644
--- a/src/bsp/trustzone/teeloader/mt2735/default.mak
+++ b/src/bsp/trustzone/teeloader/mt2735/default.mak
@@ -2,7 +2,7 @@
 # Default Project Feautre
 ###################################################################
 MACH_TYPE := MT2735
-CFG_ATF_LOG_SUPPORT := 0
+CFG_ATF_LOG_SUPPORT := 1
 CFG_TEE_SUPPORT := 0
 CFG_TRUSTONIC_TEE_SUPPORT := 0
 CFG_TEE_SECURE_MEM_PROTECTED := 0
@@ -10,6 +10,6 @@
 CFG_TZ_UART_APDMA_SUPPORT := 1
 CFG_DEVAPC_SET_PROTECT := 1
 
-CFG_ATF_LOG_BUFFER_ADDR := 0x4FFC0000
+CFG_ATF_LOG_BUFFER_ADDR := 0x61000000
 CFG_TEE_SECMEM_SIZE = 0x3000000
 CFG_TEE_HWUID_DEBUG := 0
diff --git a/src/kernel/linux/v4.19/Documentation/Changes b/src/kernel/linux/v4.19/Documentation/Changes
deleted file mode 120000
index 7564ae1..0000000
--- a/src/kernel/linux/v4.19/Documentation/Changes
+++ /dev/null
@@ -1 +0,0 @@
-process/changes.rst
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/Documentation/Changes b/src/kernel/linux/v4.19/Documentation/Changes
new file mode 100644
index 0000000..d1bf143
--- /dev/null
+++ b/src/kernel/linux/v4.19/Documentation/Changes
@@ -0,0 +1,487 @@
+.. _changes:
+
+Minimal requirements to compile the Kernel
+++++++++++++++++++++++++++++++++++++++++++
+
+Intro
+=====
+
+This document is designed to provide a list of the minimum levels of
+software necessary to run the 4.x kernels.
+
+This document is originally based on my "Changes" file for 2.0.x kernels
+and therefore owes credit to the same people as that file (Jared Mauch,
+Axel Boldt, Alessandro Sigala, and countless other users all over the
+'net).
+
+Current Minimal Requirements
+****************************
+
+Upgrade to at **least** these software revisions before thinking you've
+encountered a bug!  If you're unsure what version you're currently
+running, the suggested command should tell you.
+
+Again, keep in mind that this list assumes you are already functionally
+running a Linux kernel.  Also, not all tools are necessary on all
+systems; obviously, if you don't have any ISDN hardware, for example,
+you probably needn't concern yourself with isdn4k-utils.
+
+====================== ===============  ========================================
+        Program        Minimal version       Command to check the version
+====================== ===============  ========================================
+GNU C                  4.6              gcc --version
+GNU make               3.81             make --version
+binutils               2.20             ld -v
+flex                   2.5.35           flex --version
+bison                  2.0              bison --version
+util-linux             2.10o            fdformat --version
+kmod                   13               depmod -V
+e2fsprogs              1.41.4           e2fsck -V
+jfsutils               1.1.3            fsck.jfs -V
+reiserfsprogs          3.6.3            reiserfsck -V
+xfsprogs               2.6.0            xfs_db -V
+squashfs-tools         4.0              mksquashfs -version
+btrfs-progs            0.18             btrfsck
+pcmciautils            004              pccardctl -V
+quota-tools            3.09             quota -V
+PPP                    2.4.0            pppd --version
+isdn4k-utils           3.1pre1          isdnctrl 2>&1|grep version
+nfs-utils              1.0.5            showmount --version
+procps                 3.2.0            ps --version
+oprofile               0.9              oprofiled --version
+udev                   081              udevd --version
+grub                   0.93             grub --version || grub-install --version
+mcelog                 0.6              mcelog --version
+iptables               1.4.2            iptables -V
+openssl & libcrypto    1.0.0            openssl version
+bc                     1.06.95          bc --version
+Sphinx\ [#f1]_	       1.3		sphinx-build --version
+====================== ===============  ========================================
+
+.. [#f1] Sphinx is needed only to build the Kernel documentation
+
+Kernel compilation
+******************
+
+GCC
+---
+
+The gcc version requirements may vary depending on the type of CPU in your
+computer.
+
+Make
+----
+
+You will need GNU make 3.81 or later to build the kernel.
+
+Binutils
+--------
+
+The build system has, as of 4.13, switched to using thin archives (`ar T`)
+rather than incremental linking (`ld -r`) for built-in.a intermediate steps.
+This requires binutils 2.20 or newer.
+
+pkg-config
+----------
+
+The build system, as of 4.18, requires pkg-config to check for installed
+kconfig tools and to determine flags settings for use in
+'make {g,x}config'.  Previously pkg-config was being used but not
+verified or documented.
+
+Flex
+----
+
+Since Linux 4.16, the build system generates lexical analyzers
+during build.  This requires flex 2.5.35 or later.
+
+
+Bison
+-----
+
+Since Linux 4.16, the build system generates parsers
+during build.  This requires bison 2.0 or later.
+
+Perl
+----
+
+You will need perl 5 and the following modules: ``Getopt::Long``,
+``Getopt::Std``, ``File::Basename``, and ``File::Find`` to build the kernel.
+
+BC
+--
+
+You will need bc to build kernels 3.10 and higher
+
+
+OpenSSL
+-------
+
+Module signing and external certificate handling use the OpenSSL program and
+crypto library to do key creation and signature generation.
+
+You will need openssl to build kernels 3.7 and higher if module signing is
+enabled.  You will also need openssl development packages to build kernels 4.3
+and higher.
+
+
+System utilities
+****************
+
+Architectural changes
+---------------------
+
+DevFS has been obsoleted in favour of udev
+(http://www.kernel.org/pub/linux/utils/kernel/hotplug/)
+
+32-bit UID support is now in place.  Have fun!
+
+Linux documentation for functions is transitioning to inline
+documentation via specially-formatted comments near their
+definitions in the source.  These comments can be combined with ReST
+files the Documentation/ directory to make enriched documentation, which can
+then be converted to PostScript, HTML, LaTex, ePUB and PDF files.
+In order to convert from ReST format to a format of your choice, you'll need
+Sphinx.
+
+Util-linux
+----------
+
+New versions of util-linux provide ``fdisk`` support for larger disks,
+support new options to mount, recognize more supported partition
+types, have a fdformat which works with 2.4 kernels, and similar goodies.
+You'll probably want to upgrade.
+
+Ksymoops
+--------
+
+If the unthinkable happens and your kernel oopses, you may need the
+ksymoops tool to decode it, but in most cases you don't.
+It is generally preferred to build the kernel with ``CONFIG_KALLSYMS`` so
+that it produces readable dumps that can be used as-is (this also
+produces better output than ksymoops).  If for some reason your kernel
+is not build with ``CONFIG_KALLSYMS`` and you have no way to rebuild and
+reproduce the Oops with that option, then you can still decode that Oops
+with ksymoops.
+
+Mkinitrd
+--------
+
+These changes to the ``/lib/modules`` file tree layout also require that
+mkinitrd be upgraded.
+
+E2fsprogs
+---------
+
+The latest version of ``e2fsprogs`` fixes several bugs in fsck and
+debugfs.  Obviously, it's a good idea to upgrade.
+
+JFSutils
+--------
+
+The ``jfsutils`` package contains the utilities for the file system.
+The following utilities are available:
+
+- ``fsck.jfs`` - initiate replay of the transaction log, and check
+  and repair a JFS formatted partition.
+
+- ``mkfs.jfs`` - create a JFS formatted partition.
+
+- other file system utilities are also available in this package.
+
+Reiserfsprogs
+-------------
+
+The reiserfsprogs package should be used for reiserfs-3.6.x
+(Linux kernels 2.4.x). It is a combined package and contains working
+versions of ``mkreiserfs``, ``resize_reiserfs``, ``debugreiserfs`` and
+``reiserfsck``. These utils work on both i386 and alpha platforms.
+
+Xfsprogs
+--------
+
+The latest version of ``xfsprogs`` contains ``mkfs.xfs``, ``xfs_db``, and the
+``xfs_repair`` utilities, among others, for the XFS filesystem.  It is
+architecture independent and any version from 2.0.0 onward should
+work correctly with this version of the XFS kernel code (2.6.0 or
+later is recommended, due to some significant improvements).
+
+PCMCIAutils
+-----------
+
+PCMCIAutils replaces ``pcmcia-cs``. It properly sets up
+PCMCIA sockets at system startup and loads the appropriate modules
+for 16-bit PCMCIA devices if the kernel is modularized and the hotplug
+subsystem is used.
+
+Quota-tools
+-----------
+
+Support for 32 bit uid's and gid's is required if you want to use
+the newer version 2 quota format.  Quota-tools version 3.07 and
+newer has this support.  Use the recommended version or newer
+from the table above.
+
+Intel IA32 microcode
+--------------------
+
+A driver has been added to allow updating of Intel IA32 microcode,
+accessible as a normal (misc) character device.  If you are not using
+udev you may need to::
+
+  mkdir /dev/cpu
+  mknod /dev/cpu/microcode c 10 184
+  chmod 0644 /dev/cpu/microcode
+
+as root before you can use this.  You'll probably also want to
+get the user-space microcode_ctl utility to use with this.
+
+udev
+----
+
+``udev`` is a userspace application for populating ``/dev`` dynamically with
+only entries for devices actually present. ``udev`` replaces the basic
+functionality of devfs, while allowing persistent device naming for
+devices.
+
+FUSE
+----
+
+Needs libfuse 2.4.0 or later.  Absolute minimum is 2.3.0 but mount
+options ``direct_io`` and ``kernel_cache`` won't work.
+
+Networking
+**********
+
+General changes
+---------------
+
+If you have advanced network configuration needs, you should probably
+consider using the network tools from ip-route2.
+
+Packet Filter / NAT
+-------------------
+The packet filtering and NAT code uses the same tools like the previous 2.4.x
+kernel series (iptables).  It still includes backwards-compatibility modules
+for 2.2.x-style ipchains and 2.0.x-style ipfwadm.
+
+PPP
+---
+
+The PPP driver has been restructured to support multilink and to
+enable it to operate over diverse media layers.  If you use PPP,
+upgrade pppd to at least 2.4.0.
+
+If you are not using udev, you must have the device file /dev/ppp
+which can be made by::
+
+  mknod /dev/ppp c 108 0
+
+as root.
+
+Isdn4k-utils
+------------
+
+Due to changes in the length of the phone number field, isdn4k-utils
+needs to be recompiled or (preferably) upgraded.
+
+NFS-utils
+---------
+
+In ancient (2.4 and earlier) kernels, the nfs server needed to know
+about any client that expected to be able to access files via NFS.  This
+information would be given to the kernel by ``mountd`` when the client
+mounted the filesystem, or by ``exportfs`` at system startup.  exportfs
+would take information about active clients from ``/var/lib/nfs/rmtab``.
+
+This approach is quite fragile as it depends on rmtab being correct
+which is not always easy, particularly when trying to implement
+fail-over.  Even when the system is working well, ``rmtab`` suffers from
+getting lots of old entries that never get removed.
+
+With modern kernels we have the option of having the kernel tell mountd
+when it gets a request from an unknown host, and mountd can give
+appropriate export information to the kernel.  This removes the
+dependency on ``rmtab`` and means that the kernel only needs to know about
+currently active clients.
+
+To enable this new functionality, you need to::
+
+  mount -t nfsd nfsd /proc/fs/nfsd
+
+before running exportfs or mountd.  It is recommended that all NFS
+services be protected from the internet-at-large by a firewall where
+that is possible.
+
+mcelog
+------
+
+On x86 kernels the mcelog utility is needed to process and log machine check
+events when ``CONFIG_X86_MCE`` is enabled. Machine check events are errors
+reported by the CPU. Processing them is strongly encouraged.
+
+Kernel documentation
+********************
+
+Sphinx
+------
+
+Please see :ref:`sphinx_install` in ``Documentation/doc-guide/sphinx.rst``
+for details about Sphinx requirements.
+
+Getting updated software
+========================
+
+Kernel compilation
+******************
+
+gcc
+---
+
+- <ftp://ftp.gnu.org/gnu/gcc/>
+
+Make
+----
+
+- <ftp://ftp.gnu.org/gnu/make/>
+
+Binutils
+--------
+
+- <https://www.kernel.org/pub/linux/devel/binutils/>
+
+Flex
+----
+
+- <https://github.com/westes/flex/releases>
+
+Bison
+-----
+
+- <ftp://ftp.gnu.org/gnu/bison/>
+
+OpenSSL
+-------
+
+- <https://www.openssl.org/>
+
+System utilities
+****************
+
+Util-linux
+----------
+
+- <https://www.kernel.org/pub/linux/utils/util-linux/>
+
+Kmod
+----
+
+- <https://www.kernel.org/pub/linux/utils/kernel/kmod/>
+- <https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git>
+
+Ksymoops
+--------
+
+- <https://www.kernel.org/pub/linux/utils/kernel/ksymoops/v2.4/>
+
+Mkinitrd
+--------
+
+- <https://code.launchpad.net/initrd-tools/main>
+
+E2fsprogs
+---------
+
+- <http://prdownloads.sourceforge.net/e2fsprogs/e2fsprogs-1.29.tar.gz>
+
+JFSutils
+--------
+
+- <http://jfs.sourceforge.net/>
+
+Reiserfsprogs
+-------------
+
+- <http://www.kernel.org/pub/linux/utils/fs/reiserfs/>
+
+Xfsprogs
+--------
+
+- <ftp://oss.sgi.com/projects/xfs/>
+
+Pcmciautils
+-----------
+
+- <https://www.kernel.org/pub/linux/utils/kernel/pcmcia/>
+
+Quota-tools
+-----------
+
+- <http://sourceforge.net/projects/linuxquota/>
+
+
+Intel P6 microcode
+------------------
+
+- <https://downloadcenter.intel.com/>
+
+udev
+----
+
+- <http://www.freedesktop.org/software/systemd/man/udev.html>
+
+FUSE
+----
+
+- <https://github.com/libfuse/libfuse/releases>
+
+mcelog
+------
+
+- <http://www.mcelog.org/>
+
+Networking
+**********
+
+PPP
+---
+
+- <ftp://ftp.samba.org/pub/ppp/>
+
+Isdn4k-utils
+------------
+
+- <ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/>
+
+NFS-utils
+---------
+
+- <http://sourceforge.net/project/showfiles.php?group_id=14>
+
+Iptables
+--------
+
+- <http://www.iptables.org/downloads.html>
+
+Ip-route2
+---------
+
+- <https://www.kernel.org/pub/linux/utils/net/iproute2/>
+
+OProfile
+--------
+
+- <http://oprofile.sf.net/download/>
+
+NFS-Utils
+---------
+
+- <http://nfs.sourceforge.net/>
+
+Kernel documentation
+********************
+
+Sphinx
+------
+
+- <http://www.sphinx-doc.org/>
diff --git a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
deleted file mode 120000
index c2f22fc..0000000
--- a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
+++ /dev/null
@@ -1 +0,0 @@
-sun8i-a23-q8-tablet.dts
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
new file mode 100644
index 0000000..b6958e8
--- /dev/null
+++ b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v1.2.dts
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * 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 file 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 file 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.
+ */
+
+/dts-v1/;
+#include "sun8i-a23.dtsi"
+#include "sun8i-q8-common.dtsi"
+
+/ {
+	model = "Q8 A23 Tablet";
+	compatible = "allwinner,q8-a23", "allwinner,sun8i-a23";
+};
+
+&codec {
+	allwinner,pa-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
+	allwinner,audio-routing =
+		"Headphone", "HP",
+		"Headphone", "HPCOM",
+		"Speaker", "HP",
+		"MIC1", "Mic",
+		"MIC2", "Headset Mic",
+		"Mic",  "MBIAS",
+		"Headset Mic", "HBIAS";
+	status = "okay";
+};
diff --git a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
deleted file mode 120000
index c2f22fc..0000000
--- a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
+++ /dev/null
@@ -1 +0,0 @@
-sun8i-a23-q8-tablet.dts
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
new file mode 100644
index 0000000..b6958e8
--- /dev/null
+++ b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * 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 file 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 file 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.
+ */
+
+/dts-v1/;
+#include "sun8i-a23.dtsi"
+#include "sun8i-q8-common.dtsi"
+
+/ {
+	model = "Q8 A23 Tablet";
+	compatible = "allwinner,q8-a23", "allwinner,sun8i-a23";
+};
+
+&codec {
+	allwinner,pa-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
+	allwinner,audio-routing =
+		"Headphone", "HP",
+		"Headphone", "HPCOM",
+		"Speaker", "HP",
+		"MIC1", "Mic",
+		"MIC2", "Headset Mic",
+		"Mic",  "MBIAS",
+		"Headset Mic", "HBIAS";
+	status = "okay";
+};
diff --git a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts
deleted file mode 120000
index 4519fd7..0000000
--- a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts
+++ /dev/null
@@ -1 +0,0 @@
-sun8i-a33-q8-tablet.dts
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts
new file mode 100644
index 0000000..b0bc236
--- /dev/null
+++ b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-et-q8-v1.6.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * 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 file 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 file 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.
+ */
+
+/dts-v1/;
+#include "sun8i-a33.dtsi"
+#include "sun8i-q8-common.dtsi"
+
+/ {
+	model = "Q8 A33 Tablet";
+	compatible = "allwinner,q8-a33", "allwinner,sun8i-a33";
+};
diff --git a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts
deleted file mode 120000
index 4519fd7..0000000
--- a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts
+++ /dev/null
@@ -1 +0,0 @@
-sun8i-a33-q8-tablet.dts
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts
new file mode 100644
index 0000000..b0bc236
--- /dev/null
+++ b/src/kernel/linux/v4.19/arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * 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 file 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 file 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.
+ */
+
+/dts-v1/;
+#include "sun8i-a33.dtsi"
+#include "sun8i-q8-common.dtsi"
+
+/ {
+	model = "Q8 A33 Tablet";
+	compatible = "allwinner,q8-a33", "allwinner,sun8i-a33";
+};
diff --git a/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/auto2735evb.dts b/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/auto2735evb.dts
index f631a60..f7bc787 100755
--- a/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/auto2735evb.dts
+++ b/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/auto2735evb.dts
@@ -49,8 +49,10 @@
 		atag,videolfb-vramSize= <0x1be0000>;
 		atag,videolfb-lcmname=
 			"nt35595_fhd_dsi_cmd_truly_nt50358_drv";
+#if defined(CONFIG_MTK_AEE_FEATURE)
 		aee,enable = "mini";
 		mrdump,cblock = <0x12e000 0x2000>;
+#endif
 		atag,boot = <0x03000000 0x02080041 0x0>;
 	};
 
diff --git a/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/mt2735.dtsi b/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/mt2735.dtsi
index aab8034..9ec6011 100644
--- a/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/mt2735.dtsi
+++ b/src/kernel/linux/v4.19/arch/arm64/boot/dts/mediatek/mt2735.dtsi
@@ -219,36 +219,6 @@
 			};
 		};
 
-#if 0
-		idle-states {
-			entry-method = "arm,psci";
-			cpuoff_l: cpuoff_l {
-					compatible = "mediatek,idle-state";
-					arm,psci-suspend-param = <0x00010001>;
-					local-timer-stop;
-					entry-latency-us = <50>;
-					exit-latency-us = <100>;
-					min-residency-us = <1600>;
-			};
-			clusteroff_l: clusteroff_l {
-					compatible = "mediatek,idle-state";
-					arm,psci-suspend-param = <0x01010001>;
-					local-timer-stop;
-					entry-latency-us = <100>;
-					exit-latency-us = <250>;
-					min-residency-us = <2100>;
-			};
-			mcusysoff: mcusysoff {
-					compatible = "mediatek,idle-state";
-					arm,psci-suspend-param = <0x01010002>;
-					local-timer-stop;
-					entry-latency-us = <300>;
-					exit-latency-us = <1200>;
-					min-residency-us = <2600>;
-			};
-		};
-#endif
-
 	};
 
 	pmu {
@@ -368,6 +338,13 @@
 			reg = <0 0x42FB0000 0 0x1FA000>;
 		};
 
+		reserve-memory-atf_log {
+			compatible = "mediatek,atf-log-reserved";
+			no-map;
+			reg = <0 0x61000000 0 0x40000>;
+		};
+
+
 		reserve-memory-mcupm_share {
 			compatible = "mediatek,reserve-memory-mcupm_share";
 			no-map;
@@ -411,7 +388,7 @@
 			ftrace-size = <0x1000>;
 			pmsg-size = <0x10000>;
 		};
-		
+
 #if defined(CONFIG_MTK_AEE_FEATURE)
 		reserve-memory-emi_isu_buf {
 			compatible = "mediatek,emi_isu_buf";
@@ -3207,7 +3184,7 @@
 		compatible = "mediatek,leopard-ethsys", "syscon", "simple-mfd";
                 reg = <0 0x15195000 0 0x1000>;
         };
-	/*jb.qi change for reboot after sleep on 20230417 start*/
+
         wed: wed@15010000 {
                 compatible = "mediatek,leopard-ethsys", "syscon", "simple-mfd";
                 reg = <0 0x15010000 0 0x1000>;
@@ -3217,7 +3194,7 @@
                 compatible = "mediatek,leopard-ethsys", "syscon", "simple-mfd";
                 reg = <0 0x15011000 0 0x1000>;
         };
-	/*jb.qi change for reboot after sleep on 20230417 end*/
+
 	hnat: hnat@15100e00 {
 		compatible = "mediatek,hnat", "syscon";
 		reg = <0 0x15100e00 0 0x1000>;
@@ -3267,8 +3244,8 @@
 		power-domains = <&scpsys MT6890_POWER_DOMAIN_NETSYS>;
 		mediatek,ethsys = <&ethsys>;
 		mediatek,wo = <&wo>;
-		mediatek,wed = <&wed>; //jb.qi change for reboot after sleep on 20230417
-		mediatek,wed2 = <&wed2>; //jb.qi change for reboot after sleep on 20230417
+		mediatek,wed = <&wed>;
+		mediatek,wed2 = <&wed2>;
 #if defined(CONFIG_MTK_SGMII_NETSYS)
 		mediatek,sgmiisys = <&sgmiisys_0>,<&sgmiisys_1>;
 		mediatek,sgmiisys_phy = <&sgmiisys_phy_0>,<&sgmiisys_phy_1>;
diff --git a/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_defconfig b/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_defconfig
index 3c3b39b..cb9c6ed 100644
--- a/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_defconfig
+++ b/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_defconfig
@@ -392,6 +392,7 @@
 CONFIG_MTK_AEE_FEATURE=y
 CONFIG_MTK_AEE_AED=y
 CONFIG_MTK_AEE_IPANIC=y
+CONFIG_MTK_AEE_HANGDET=y
 CONFIG_MTK_DBGTOP=y
 CONFIG_MTK_HANG_DETECT=y
 CONFIG_MTK_HANG_DETECT_DB=y
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/fsm/ccci_fsm.c b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/fsm/ccci_fsm.c
index 26b9810..c5a5c51 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/fsm/ccci_fsm.c
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/fsm/ccci_fsm.c
@@ -40,13 +40,13 @@
 
 static int needforcestop;
 static bool sForceWakeup;
-/*jb.qi change for medmcu sleep fail on 20230418 start*/
+
 int ccci_fsm_get_md_force_stop_state(void)
 {
        return needforcestop;
 }
 EXPORT_SYMBOL_GPL(ccci_fsm_get_md_force_stop_state);
-/*jb.qi change for medmcu sleep fail on 20230418 end*/
+
 int force_md_stop(struct ccci_fsm_monitor *monitor_ctl)
 {
 	int ret = -1;
@@ -458,7 +458,7 @@
 	ctl->curr_state = CCCI_FSM_GATED;
 	fsm_broadcast_state(ctl, GATED);
 	fsm_finish_command(ctl, cmd, 1);
-	needforcestop = 0;//jb.qi change for medmcu sleep fail on 20230418
+	needforcestop = 0;
 }
 
 static void fsm_routine_wdt(struct ccci_fsm_ctl *ctl,
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.c b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.c
index 3f638f1..c8df8aa 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.c
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.c
@@ -65,6 +65,7 @@
 	0 * 1024, 0 * 1024, 0 * 1024, 0 * 1024, 0 * 1024, 0 * 1024,
 	0 * 1024, 0 * 1024,
 };
+
 static void md_ccif_dump(unsigned char *title, unsigned char hif_id)
 {
 	int idx;
@@ -201,7 +202,7 @@
 		i += 4;
 	}
 
-	if (test_and_clear_bit((D2H_SRAM), &md_ctrl->wakeup_ch)) { //jb.qi change for abnormal resume on 20230328
+	if (test_and_clear_bit((D2H_SRAM), &md_ctrl->wakeup_ch)) {
 		CCCI_NOTICE_LOG(md_ctrl->md_id, TAG,
 			"CCIF_MD wakeup source:(SRX_IDX/%d)(%u)\n",
 			ccci_h->channel, md_ctrl->wakeup_count);
@@ -373,15 +374,13 @@
 		}
 		ccci_h = (struct ccci_header *)skb->data;
 
-		if (test_and_clear_bit(queue->index, &md_ctrl->wakeup_ch)) { //jb.qi change for abnormal resume on 20230328
+		if (test_and_clear_bit(queue->index, &md_ctrl->wakeup_ch)) {
 			CCCI_NOTICE_LOG(md_ctrl->md_id, TAG,
 				"CCIF_MD wakeup source:(%d/%d/%x)(%u)\n",
 				queue->index, ccci_h->channel,
 				ccci_h->reserved, md_ctrl->wakeup_count);
-			/*jb.qi change for abnormal resume start on 20230328*/
 			if (ccci_h->channel == CCCI_FS_RX)
 				ccci_h->data[0] |= CCCI_FS_AP_CCCI_WAKEUP;
-			/*jb.qi change for abnormal resume end on 20230328*/
 		}
 
 		ccci_hdr = *ccci_h;
@@ -714,7 +713,7 @@
 	if (md_ctrl->channel_id & (1 << AP_MD_CCB_WAKEUP)) {
 		clear_bit(AP_MD_CCB_WAKEUP, &md_ctrl->channel_id);
 		CCCI_DEBUG_LOG(md_ctrl->md_id, TAG, "CCB wakeup\n");
-		if (test_and_clear_bit(AP_MD_CCB_WAKEUP, &md_ctrl->wakeup_ch)) { //jb.qi change for abnormal resume on 20230328
+		if (test_and_clear_bit(AP_MD_CCB_WAKEUP, &md_ctrl->wakeup_ch)) {
 			CCCI_NOTICE_LOG(md_ctrl->md_id, TAG,
 			"CCIF_MD wakeup source:(CCB)(%u)\n",
 			md_ctrl->wakeup_count);
@@ -1259,7 +1258,7 @@
 	md_ctrl->md_id = md_id;
 	md_ctrl->hif_id = hif_id;
 	atomic_set(&md_ctrl->reset_on_going, 1);
-	md_ctrl->wakeup_ch = 0; //jb.qi change for abnormal resume on 20230328
+	md_ctrl->wakeup_ch = 0;
 	ccci_reset_seq_num(&md_ctrl->traffic_info);
 
 	/*init queue */
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.h b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.h
index 29b2286..90b8bfc 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.h
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.h
@@ -21,11 +21,11 @@
 #else
 #define QUEUE_NUM   8
 #endif
-/*jb.qi change for abnormal resume start on 20230328*/
+
 /* speciall for user: ccci_fsd data[0] */
 #define CCCI_FS_AP_CCCI_WAKEUP (0x40000000)
 #define CCCI_FS_REQ_SEND_AGAIN 0x80000000
-/*jb.qi change for abnormal resume end on 20230328*/
+
 /*#define FLOW_CTRL_ENABLE*/
 #define FLOW_CTRL_HEAD		0x464C4F57	/*FLOW*/
 #define FLOW_CTRL_TAIL		0x4354524C	/*CTRL*/
@@ -95,7 +95,7 @@
 	struct timer_list bus_timeout_timer;
 	void __iomem *ccif_ap_base;
 	void __iomem *ccif_md_base;
-	unsigned long wakeup_ch; //jb.qi change for abnormal resume on 20230328
+	unsigned long wakeup_ch;
 	unsigned int wakeup_count;
 
 	struct work_struct wdt_work;
@@ -233,8 +233,8 @@
 {
 	struct md_ccif_ctrl *md_ctrl =
 		(struct md_ccif_ctrl *)ccci_hif_get_by_id(hif_id);
-	unsigned int ccif_ch = 0; //jb.qi change for abnormal resume on 20230328
-	/*jb.qi change for abnormal resume start on 20230328 */
+	unsigned int ccif_ch = 0;
+
 	if (md_ctrl) {
 		ccif_ch = ccif_read32(md_ctrl->ccif_ap_base, APCCIF_RCHNUM);
 		pr_notice("[ccci1/cif] CCIF wakeup channel: 0x%x\n", ccif_ch);
@@ -244,7 +244,6 @@
 		}
 		return value;
 	}
-	/*jb.qi change for abnormal resume end on 20230328 */
 	else
 		return -1;
 }
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_dpmaif.c b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_dpmaif.c
index a0e9fa6..dc65976 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_dpmaif.c
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_dpmaif.c
@@ -355,7 +355,7 @@
 
 	}
 }
-
+//xy.he [Bugfix][API-1384] add debug patch for command ping fail (tx_busy) -- start on Nov 25 2023 
 void* getDRBtableAddress(int qid)
 {
 	struct dpmaif_tx_queue *txq;
@@ -366,7 +366,7 @@
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(getDRBtableAddress);
-
+//xy.he [Bugfix][API-1384] add debug patch for command ping fail (tx_busy) -- end on Nov 25 2023
 static void dpmaif_dump_txq_remain(struct hif_dpmaif_ctrl *hif_ctrl,
 	unsigned int qno, int dump_multi)
 {
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/inc/ccci_fsm.h b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/inc/ccci_fsm.h
index 59656ed..70dc76a 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/inc/ccci_fsm.h
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/inc/ccci_fsm.h
@@ -21,6 +21,6 @@
 
 extern void mdee_set_ex_time_str(unsigned char md_id, unsigned int type,
 	char *str);
-int ccci_fsm_get_md_force_stop_state(void); //jb.qi change for medmcu sleep fail on 20230418
+int ccci_fsm_get_md_force_stop_state(void);
 #endif /* __CCCI_FSM_H__ */
 
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/mt6880/modem_secure_base.h b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/mt6880/modem_secure_base.h
index 4e28fa7..0f66f48 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/mt6880/modem_secure_base.h
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/mt6880/modem_secure_base.h
@@ -38,9 +38,8 @@
 #define mdreg_write32(reg_id, value)								\
 	{																\
 		struct arm_smccc_res res;									\
-		arm_smccc_smc(MTK_SIP_KERNEL_CCCI_CONTROL, MD_POWER_CONFIG,	\
-				MD_DBGSYS_REG_DUMP,									\
-				reg_id, value, 0, 0, 0, &res);						\
+		arm_smccc_smc(MTK_SIP_KERNEL_CCCI_CONTROL, MD_DBGSYS_REG_DUMP,	\
+				reg_id, value, 0, 0, 0, 0, &res);						\
 	}
 
 #endif				/* __MODEM_SECURE_BASE_H__ */
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/mt6890/modem_secure_base.h b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/mt6890/modem_secure_base.h
index 19f0182..4897b56 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/mt6890/modem_secure_base.h
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/mt6890/modem_secure_base.h
@@ -39,9 +39,8 @@
 #define mdreg_write32(reg_id, value)								\
 	{																\
 		struct arm_smccc_res res;									\
-		arm_smccc_smc(MTK_SIP_KERNEL_CCCI_CONTROL, MD_POWER_CONFIG,	\
-				MD_DBGSYS_REG_DUMP,									\
-				reg_id, value, 0, 0, 0, &res);						\
+		arm_smccc_smc(MTK_SIP_KERNEL_CCCI_CONTROL, MD_DBGSYS_REG_DUMP,	\
+				reg_id, value, 0, 0, 0, 0, &res);						\
 	}
 
 #endif				/* __MODEM_SECURE_BASE_H__ */
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/lpm/modules/debug/mt6880/mtk_logger.c b/src/kernel/linux/v4.19/drivers/misc/mediatek/lpm/modules/debug/mt6880/mtk_logger.c
index 0e2fd79..5fb0294 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/lpm/modules/debug/mt6880/mtk_logger.c
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/lpm/modules/debug/mt6880/mtk_logger.c
@@ -834,10 +834,6 @@
 					"MCUSYSOFF", NULL);
 		mtk_logger_help.prev = mtk_logger_help.cur;
 	}
-	/*
-   	else
-		pr_info("[name:spm&][SPM] MCUSYSOFF Didn't enter low power scenario\n");
-	*/
 
 	timer->fired = info->fired;
 	return 0;
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/Makefile b/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/Makefile
index e20c3c2..e525ad2 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/Makefile
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/Makefile
@@ -28,7 +28,7 @@
 # include mtk_spm_resource_req
 ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/
 
-# include ccci_fsm.h jb.qi change for medmcu sleep fail on 202304018
+# include ccci_fsm.h
 ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/inc
 
 #ifeq ($(CONFIG_MTK_ENG_BUILD),y)
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/medmcu_helper.h b/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/medmcu_helper.h
index 2fda41b..ee46f48 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/medmcu_helper.h
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/medmcu_helper.h
@@ -88,8 +88,8 @@
 	RESET_TYPE_CMD = 2,
 	RESET_TYPE_TIMEOUT = 3,
 	RESET_TYPE_MD_EXCEP = 4,
-	RESET_TYPE_MD_FORCE_STOP = 5, //jb.qi change for medmcu sleep fail on 20230418
-	RESET_TYPE_RESUME = 6, //jb.qi change for medmcu sleep fail on 20230418
+	RESET_TYPE_MD_FORCE_STOP = 5,
+	RESET_TYPE_RESUME = 6,
 };
 
 struct scp_regs {
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/v02/medmcu_helper.c b/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/v02/medmcu_helper.c
old mode 100755
new mode 100644
index 892dc0f..a6275e2
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/v02/medmcu_helper.c
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/v02/medmcu_helper.c
@@ -30,7 +30,7 @@
 #include <mt-plat/sync_write.h>
 //#include <mt-plat/aee.h>
 #include <linux/delay.h>
-#include <linux/pm_wakeup.h> //jb.qi change for medmcu sleep fail on 20230418
+#include <linux/pm_wakeup.h>
 #include <linux/syscore_ops.h>
 #include "medmcu_helper.h"
 #include "medmcu_ipi_pin.h"
@@ -39,15 +39,17 @@
 #include "medmcu_excep.h"
 #include "medmcu_scpctl.h"
 #include "medmcu_dvfs.h"
-#include "ccci_fsm.h" //jb.qi change for medmcu sleep fail on 20230418
+#include "ccci_fsm.h"
+
 void __iomem *medhw_base;
 EXPORT_SYMBOL_GPL(medhw_base);
 
 #define MEDHW_BASE           medhw_base
 #define MEDHW_INT_MNG_BASE          (MEDHW_BASE + 0x3000)
-#define MEDHW_INT_EXCEP_W1C         (MEDHW_INT_MNG_BASE + 0x00) //jb.qi change for medmcu sleep fail on 20230418
+#define MEDHW_INT_EXCEP_W1C         (MEDHW_INT_MNG_BASE + 0x00)
 #define MEDHW_INT_EXCEP_SET         (MEDHW_INT_MNG_BASE + 0x08)
-#define MEDHW_INT_NOTIF_W1C         (MEDHW_INT_MNG_BASE + 0x20) //jb.qi change for medmcu sleep fail on 20230418
+#define MEDHW_INT_NOTIF_W1C         (MEDHW_INT_MNG_BASE + 0x20)
+
 void __iomem *fe_base;
 #define FE_BASE           fe_base
 
@@ -230,7 +232,8 @@
 static unsigned int scp_timeout_times;
 #endif
 static struct scp_work_struct scp_A_notify_work;
-static unsigned int g_ignore_stop_ipi_flag = 0; //jb.qi change for medmcu sleep fail on 20230418
+static unsigned int g_ignore_stop_ipi_flag = 0;
+
 //represent the suspend response from medmcu, 0: no response, 1: idle, -1: can't suspend
 atomic_t medmcu_suspend_response;
 //represent the medmcu is ready for suspend query or not
@@ -247,10 +250,10 @@
 
 char *core_ids[SCP_CORE_TOTAL] = {"SCP A"};
 DEFINE_SPINLOCK(scp_awake_spinlock);
-DEFINE_SPINLOCK(medmcu_resume_spinlock);//jb.qi change for medmcu sleep fail on 20230418
+DEFINE_SPINLOCK(medmcu_resume_spinlock);
 /* set flag after driver initial done */
 static bool driver_init_done;
-static struct wakeup_source *medmcu_dl_wakelock;//jb.qi change for medmcu sleep fail on 20230418
+static struct wakeup_source *medmcu_dl_wakelock;
 
 struct scp_ipi_irq {
 	const char *name;
@@ -281,7 +284,7 @@
 	}
 	return 0;
 }
-/*jb.qi change for medmcu sleep fail on 20230418 start*/
+
 static void medmcu_set_ignore_stop_ipi_flag(unsigned int flag)
 {
 	g_ignore_stop_ipi_flag = flag;
@@ -291,7 +294,6 @@
 {
 	return (g_ignore_stop_ipi_flag == 1);
 }
-/*jb.qi change for medmcu sleep fail on 20230418 end*/
 
 void fdma_init(struct net_device *dev)
 {
@@ -438,7 +440,7 @@
 	//Enable DMA check WDONE bit by 0x15104204[28]=1
 	//Disable 2-byte offset by 0x15104204[31]=0
 	//Disable TX_DMA writing back DDONE into TXD: 0x15104204[6]=0
-	reg_write(MDMA_GLO_CFG, 0x10404825);//jb.qi change for medmcu sleep fail on 20230803
+	reg_write(MDMA_GLO_CFG, 0x10404825);
 }
 
 int mdma_init(struct net_device *dev, struct MDMA_END_DEVICE *ei_local)
@@ -772,14 +774,12 @@
 			if (!is_scp_ready(SCP_A_ID)) {
 				pr_notice("[MEDMCU] %s(): scp_extern_notify SCP_EVENT_STOP_ACK\n", __func__);
 				scp_extern_notify(SCP_EVENT_STOP_ACK);
-			/*jb.qi change for medmcu sleep fail on 20230417 start*/
 			} else if (medmcu_ignore_stop_ipi()) {
 				medmcu_set_ignore_stop_ipi_flag(0);
 				pr_notice("[MEDMCU] %s(): scp_extern_notify SCP_EVENT_STOP_ACK\n", __func__);
 				scp_extern_notify(SCP_EVENT_STOP_ACK);
 			} else
 				handle_dpmaif_stop();
-			/*jb.qi change for medmcu sleep fail on 20230417 start*/
 			break;
 		case CCCI_DPMAIF_EVENT_READY:
 			if (!is_scp_ready(SCP_A_ID)) {
@@ -876,7 +876,7 @@
 	unsigned long spin_flags;
 	struct scp_work_struct *sws =
 		container_of(ws, struct scp_work_struct, work);
-	unsigned int scp_notify_flag = sws->flags; //jb.qi change for medmcu sleep fail on20230417
+	unsigned int scp_notify_flag = sws->flags;
 
 
 	if (scp_notify_flag) {
@@ -897,13 +897,13 @@
 			, SCP_EVENT_READY, NULL);
 		mutex_unlock(&scp_A_notify_mutex);
 		//for resume medmcu, need dpamif ready event.
-		spin_lock_irqsave(&medmcu_resume_spinlock, spin_flags); //jb.qi change for medmcu sleep fail on20230417
+		spin_lock_irqsave(&medmcu_resume_spinlock, spin_flags);
 		if (atomic_read(&medmcu_resume_need_dpmaif_ready) == 1) {
 			//ask ccci to send dpmaif ready, since dpmaif hw/sw is still alive after resume
 			ccci_dpmaif_resend_ready();
 			atomic_set(&medmcu_resume_need_dpmaif_ready, 0);
 		}
-		spin_unlock_irqrestore(&medmcu_resume_spinlock, spin_flags); //jb.qi change for medmcu sleep fail on20230417
+		spin_unlock_irqrestore(&medmcu_resume_spinlock, spin_flags);
 	}
 
 	/* register scp dvfs*/
@@ -1102,9 +1102,9 @@
 static int med_stop_ack_ipi_handler(unsigned int id, void *prdata, void *data,
 				    unsigned int len)
 {
-	int md_force_stop;//jb.qi change for medmcu sleep fail on 20230418
+	int md_force_stop;
 	scp_reset_counts = 9999;
-	/*jb.qi change for medmcu sleep fail on 20230418 start*/
+
 	md_force_stop = ccci_fsm_get_md_force_stop_state();
 
 	if (md_force_stop == 1) {
@@ -1115,7 +1115,7 @@
 		   scp_reset_by_md_excep = 1;
 		   scp_send_reset_wq(RESET_TYPE_MD_EXCEP);
 	}
-	/*jb.qi change for medmcu sleep fail on 20230418 end*/
+
 	return 0;
 }
 
@@ -2211,7 +2211,6 @@
 
 /******************************************************************************
  *****************************************************************************/
-/*jb.qi change for medmcu sleep fail on 20230418 start */
 void print_med_registers(void)
 {
 	uint32_t medhw_int_exp_w1c, medhw_int_notif_w1c;
@@ -2221,7 +2220,7 @@
 	pr_notice("MEDHW_INT_EXCEP_W1C = 0x%08x\n", medhw_int_exp_w1c);
 	pr_notice("MEDHW_INT_NOTIFY_W1C = 0x%08x\n", medhw_int_notif_w1c);
 }
-/*jb.qi change for medmcu sleep fail on 20230418 end */
+
 void print_clk_registers(void)
 {
 	void __iomem *cfg = scpreg.cfg;
@@ -2264,7 +2263,7 @@
 
 	while (timeout--) {
 		core0_halt = readl(R_CORE0_STATUS) & B_CORE_HALT;
-		if (core0_halt) { //jb.qi change for medmcu sleep fail on 20230418
+		if (core0_halt) {
 			/* SCP stops any activities
 			 * and parks at wfi
 			 */
@@ -2311,15 +2310,12 @@
 		 * reset type scp WDT, CMD or MD_EXCEP
 		 * make sure scp is in idle state
 		 */
-		/*jb.qi change for medmcu sleep fail on 20230418 start*/
 		if (scp_reset_type == RESET_TYPE_WDT)
 			medmcu_set_ignore_stop_ipi_flag(1);
-		/*jb.qi change for medmcu sleep fail on 20230418 end*/
 		scp_reset_wait_timeout();
 		writel(1, R_CORE0_SW_RSTN_SET);
 		writel(1, R_CORE1_SW_RSTN_SET);
 		writel(CORE_REBOOT_OK, SCP_GPR_CORE0_REBOOT);
-		writel(CORE_REBOOT_OK, SCP_GPR_CORE1_REBOOT);
 		dsb(SY); /* may take lot of time */
 		pr_notice("[MEDMCU] rstn core0 %x core1 %x\n",
 		readl(R_CORE0_SW_RSTN_SET), readl(R_CORE1_SW_RSTN_SET));
@@ -2334,35 +2330,32 @@
 
 	/* start scp */
 	pr_notice("[MEDMCU] start scp\n");
-	/*jb.qi change for medmcu sleep fail on 20230418 start*/
+
 	if (scp_reset_type == RESET_TYPE_RESUME) {
 		pr_notice("[MEDMCU] get spinlock for atomic medmcu resume rstn sequence\n");
 		spin_lock_irqsave(&medmcu_resume_spinlock, spin_flags);
 	}
-	/*jb.qi change for medmcu sleep fail on 20230418 end*/
 	writel(1, R_CORE0_SW_RSTN_CLR);
 	dsb(SY); /* may take lot of time */
 
 	atomic_set(&medmcu_resume_need_dpmaif_ready, 0);
 
 	if (scp_reset_type == RESET_TYPE_MD_EXCEP) {
-		/*notify scp functions stop*/
+		/* notify scp functions stop */
 		pr_notice("[MEDMCU] %s(): scp_extern_notify SCP_EVENT_STOP_ACK\n", __func__);
 		scp_extern_notify(SCP_EVENT_STOP_ACK);
 	} else if (scp_reset_type == RESET_TYPE_WDT) {
-		/*notify scp functions stop*/
+		/* notify scp functions stop */
 		pr_notice("[MEDMCU] %s(): scp_extern_notify SCP_EVENT_STOP_BY_WDT\n", __func__);
 		scp_extern_notify(SCP_EVENT_STOP_BY_WDT);
 	} else if (scp_reset_type == RESET_TYPE_RESUME) {
-		//wait scp ready and ask for dpmaif_ready_event
+		/* wait scp ready and ask for dpmaif_ready_event */
 		atomic_set(&medmcu_resume_need_dpmaif_ready, 1);
-		/*jb.qi change for medmcu sleep fail on 20230418 start*/
 		spin_unlock_irqrestore(&medmcu_resume_spinlock, spin_flags);
 		pr_notice("[MEDMCU] %s(): need dpmaif ready flag set in RESET_TYPE_RESUME\n", __func__);
-		/*jb.qi change for medmcu sleep fail on 20230418 end*/
-
 	}
-	pr_notice("[MEDMCU] rstn core0 %x\n", readl(R_CORE0_SW_RSTN_CLR)); //jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("[MEDMCU] rstn core0 %x\n", readl(R_CORE0_SW_RSTN_CLR));
+
 #if SCP_BOOT_TIME_OUT_MONITOR
 	mod_timer(&scp_ready_timer[SCP_A_ID], jiffies + SCP_READY_TIMEOUT);
 #endif
@@ -2399,13 +2392,13 @@
 	unsigned int scp_reset_type = sws->flags;
 
 	pr_notice("[MEDMCU] %s(): remain %d times\n", __func__, scp_reset_counts);
-	/*jb.qi change for medmcu sleep fail on 20230418 start */
+
 	if (scp_reset_type == RESET_TYPE_MD_FORCE_STOP) {
 		scp_extern_notify(SCP_EVENT_STOP_ACK);
 		return;
 	}
-	/*jb.qi change for medmcu sleep fail on 20230418 end*/
-	/*notify scp functions stop*/
+
+	/* notify scp functions stop */
 	pr_debug("[MEDMCU] %s(): scp_extern_notify SCP_EVENT_STOP\n", __func__);
 	scp_extern_notify(SCP_EVENT_STOP);
 	/*
@@ -2423,7 +2416,7 @@
 	}
 
 	/* print_clk and scp_aed before pll enable to keep ori CLK_SEL */
-	print_med_registers();//jb.qi change for medmcu sleep fail on 20230803
+	print_med_registers();
 	print_clk_registers();
 	/*workqueue for scp ee, scp reset by cmd will not trigger scp ee*/
 	if (scp_reset_by_cmd == 0 && scp_reset_by_md_excep == 0) {
@@ -2562,13 +2555,13 @@
 	struct net_device *netdev;
 
 	struct MDMA_END_DEVICE *ei_local = &mdma_device;
-	/*jb.qi change for medmcu sleep fail on20230418 start*/
+
 	medmcu_dl_wakelock = wakeup_source_register(NULL, "medmcu_dl_wakelock");
 	if (!medmcu_dl_wakelock) {
 		pr_err("%s %d: init dl wakeup source fail!", __func__, __LINE__);
 		return -1;
 	}
-	/*jb.qi change for medmcu sleep fail on20230418 end*/
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	scpreg.sram = devm_ioremap_resource(dev, res);
 	if (IS_ERR((void const *) scpreg.sram)) {
@@ -2749,7 +2742,7 @@
 int medmcu_pm_suspend(struct device *device)
 {
 	if (sync_medmcu_can_suspend() == -1) {
-		__pm_wakeup_event(medmcu_dl_wakelock, jiffies_to_msecs(HZ)); //jb.qi change for medmcu sleep fail on 20230418
+		__pm_wakeup_event(medmcu_dl_wakelock, jiffies_to_msecs(HZ));
 		return -1;
 	}
 	writel(V_DISABLE_WDT, R_CORE0_WDT_CFG);
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/v02/medmcu_logger.c b/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/v02/medmcu_logger.c
index b933751..e240df7 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/v02/medmcu_logger.c
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/medmcu/rv33/v02/medmcu_logger.c
@@ -799,13 +799,14 @@
 extern phys_addr_t gMedmcuDrb0PhyBase;
 extern phys_addr_t gMedmcuDrb1PhyBase;
 
-extern void* getDRBtableAddress(int qid);
+extern void* getDRBtableAddress(int qid);  //xy.he [Bugfix][API-1384] add debug patch for command ping fail (tx_busy) -- on Nov 25 2023 
 
 int print_medhw_dram(struct seq_file *seq) {
 	u32 i;
 	u32 *p;
 	char buf[100];
-	pr_notice("Dump TX_DESC...\n"); //jb.qi change for medmcu sleep fail on 20230418
+
+	pr_notice("Dump TX_DESC...\n");
 	p = (u32 *)medmcu_tx_desc_base_virt;
 	if (seq != NULL) {
 		seq_puts(seq, "        <<TX_DESC DUMP>>\n");
@@ -829,7 +830,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump RX_DESC...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump RX_DESC...\n");
 	p = (u32 *)medmcu_rx_desc_base_virt;
 	if (seq != NULL) {
 		seq_puts(seq, "        <<RX_DESC DUMP>>\n");
@@ -853,7 +854,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump HNAT_INFO...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump HNAT_INFO...\n");
 	p = (u32 *)medmcu_hnat_info_base_virt;
 	if (seq != NULL) {
 		seq_puts(seq, "        <<HNAT_INFO DUMP>>\n");
@@ -877,7 +878,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump HNAT_INFO_HOST...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump HNAT_INFO_HOST...\n");
 	p = (u32 *)medmcu_hnat_info_host_base_virt;
 	if (seq != NULL) {
 		seq_puts(seq, "        <<HNAT_INFO_HOST DUMP>>\n");
@@ -901,7 +902,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump PIT_NAT...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump PIT_NAT...\n");
 	p = (u32 *)medmcu_pit_nat_base_virt;
 	if (seq != NULL) {
 		seq_puts(seq, "        <<PIT_NAT DUMP>>\n");
@@ -925,7 +926,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump PIT...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump PIT...\n");
 	p = (u32 *)medmcu_pit_base_virt;
 	if (seq != NULL) {
 		seq_puts(seq, "        <<PIT DUMP>>\n");
@@ -949,7 +950,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump DRB0...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump DRB0...\n");
 	p = (u32 *)medmcu_drb0_base_virt;
 	if (seq != NULL) {
 		seq_puts(seq, "        <<DRB0 DUMP>>\n");
@@ -973,7 +974,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump DRB1...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump DRB1...\n");
 	p = (u32 *)medmcu_drb1_base_virt;
 	if (seq != NULL) {
 		seq_puts(seq, "        <<DRB1 DUMP>>\n");
@@ -996,7 +997,7 @@
 	} else {
 		pr_notice("+-----------------------------------------------+\n");
 	}
-	
+    //xy.he [Bugfix][API-1384] add debug patch for command ping fail (tx_busy) -- start on Nov 25 2023 
 	pr_notice("Dump DRB2...\n");
 	p = (u32 *)getDRBtableAddress(2);
 	if (seq != NULL) {
@@ -1048,7 +1049,7 @@
 	} else {
 		pr_notice("+-----------------------------------------------+\n");
 	}
-
+    //xy.he [Bugfix][API-1384] add debug patch for command ping fail (tx_busy) -- end on Nov 25 2023 
 	medhw_dram_logged = 1;//jb.qi change for medmcu sleep fail on 20230418
 	pr_notice("[MEDHW] read dram end\n");//jb.qi change for medmcu sleep fail on 20230418
 
@@ -1087,8 +1088,8 @@
 
 	unsigned char *medhw_bat_sw_map_buf = (unsigned char *)(SCP_TCM + bat_addr);
 	unsigned char *medhw_fbat_sw_map_buf = (unsigned char *)(SCP_TCM + fbat_addr);
-	
-	pr_notice("Dump MEDHW_INT_MNG...\n");//jb.qi change for medmcu sleep fail on 20230418
+
+	pr_notice("Dump MEDHW_INT_MNG...\n");
 	if (seq != NULL) {
 		seq_puts(seq, "       <<MEDHW_INT_MNG CR DUMP>>\n");
 	} else {
@@ -1111,7 +1112,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump MEDHW_BMP...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump MEDHW_BMP...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<MEDHW_BMP CR DUMP>>\n");
 	} else {
@@ -1134,7 +1135,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump MEDHW_SSR0...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump MEDHW_SSR0...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<MEDHW_SSR0 CR DUMP>>\n");
 	} else {
@@ -1157,7 +1158,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump MEDHW_SSR1...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump MEDHW_SSR1...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<MEDHW_SSR1 CR DUMP>>\n");
 	} else {
@@ -1180,7 +1181,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump MEDHW_SSR2...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump MEDHW_SSR2...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<MEDHW_SSR2 CR DUMP>>\n");
 	} else {
@@ -1203,7 +1204,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump DPMAIF_INT...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump DPMAIF_INT...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<DPMAIF_INT CR DUMP>>\n");
 	} else {
@@ -1226,7 +1227,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump DPMAIF_DL...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump DPMAIF_DL...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<DPMAIF_DL CR DUMP>>\n");
 	} else {
@@ -1249,7 +1250,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump DPMAIF_UL...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump DPMAIF_UL...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<DPMAIF_UL CR DUMP>>\n");
 	} else {
@@ -1343,7 +1344,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump MDMA_RX_DESC...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump MDMA_RX_DESC...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<MDMA_RX_DESC CR DUMP>>\n");
 	} else {
@@ -1366,7 +1367,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump MDMA_TXRX_DESC_INFO...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump MDMA_TXRX_DESC_INFO...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<MDMA_TXRX_DESC_INFO CR DUMP>>\n");
 	} else {
@@ -1389,7 +1390,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump FDMA_HNAT_INFO...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump FDMA_HNAT_INFO...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<FDMA_HNAT_INFO CR DUMP>>\n");
 	} else {
@@ -1412,7 +1413,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump FDMA_HNAT_INFO_INFO...\n");//jb.qi change for medmcu sleep fail on 20230418
+	pr_notice("Dump FDMA_HNAT_INFO_INFO...\n");
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<FDMA_HNAT_INFO_INFO CR DUMP>>\n");
 	} else {
@@ -1435,7 +1436,7 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	pr_notice("Dump BAT_SW_MAP...\n");//jb.qi change for medmcu sleep fail on 20230418
+
 	if (!sw_map_flush(false)) {
 		seq_puts(seq, "BAT_SW_MAP flush error\n");
 		return 0;
@@ -1445,6 +1446,7 @@
 		return 0;
 	}
 
+	pr_notice("Dump BAT_SW_MAP...\n");
 	p = (u32 *)medhw_bat_sw_map_buf;
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<BAT_SW_MAP DUMP>>\n");
@@ -1461,7 +1463,8 @@
 			pr_notice("[MEDHW] %s", buf);
 		}
 	}
-	pr_notice("Dump FBAT_SW_MAP...\n");//jb.qi change for medmcu sleep fail on 20230418
+
+	pr_notice("Dump FBAT_SW_MAP...\n");
 	p = (u32 *)medhw_fbat_sw_map_buf;
 	if (seq != NULL) {
 		seq_puts(seq, " 	  <<FBAT_SW_MAP DUMP>>\n");
@@ -1486,22 +1489,21 @@
 		pr_notice("+-----------------------------------------------+\n");
 	}
 
-	medhw_cr_dump_logged = 1;//jb.qi change for medmcu sleep fail on 20230418
-	pr_notice("[MEDHW] read cr_dump end\n");//jb.qi change for medmcu sleep fail on 20230418
+	medhw_cr_dump_logged = 1;
+	pr_notice("[MEDHW] read cr_dump end\n");
 
-	return 0;//jb.qi change for medmcu sleep fail on 20230418
+	return 0;
 }
 
 static int dram_seq_show(struct seq_file *seq, void *v)
 {
-	return print_medhw_dram(seq);//jb.qi change for medmcu sleep fail on 20230418
+    return print_medhw_dram(seq);
 }
 
-
 static int dram_seq_open(struct inode *inode, struct file *file)
 {
 	pr_notice("[MEDHW] read dram start\n");
-	return single_open_size(file, dram_seq_show, NULL, (PAGE_SIZE << 11));//jb.qi change for medmcu sleep fail on 20230418
+	return single_open_size(file, dram_seq_show, NULL, (PAGE_SIZE << 11));
 }
 
 static const struct file_operations dram_fops = {
@@ -1513,15 +1515,13 @@
 
 static int cr_dump_seq_show(struct seq_file *seq, void *v)
 {
-
-	return print_medhw_cr_dump(seq);//jb.qi change for medmcu sleep fail on 20230418
+	return print_medhw_cr_dump(seq);
 }
 
 static int cr_dump_seq_open(struct inode *inode, struct file *file)
 {
-	
 	pr_notice("[MEDHW] read cr_dump start\n");
-	return single_open_size(file, cr_dump_seq_show, NULL, (PAGE_SIZE << 4));//jb.qi change for medmcu sleep fail on 20230418
+	return single_open_size(file, cr_dump_seq_show, NULL, (PAGE_SIZE << 4));
 }
 
 static const struct file_operations cr_dump_fops = {
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand/device_slc.c b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand/device_slc.c
index 0963660..b309b34 100755
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand/device_slc.c
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand/device_slc.c
@@ -297,9 +297,9 @@
 				&slc_endurance, &slc_array_timing),
 		SLC_DRIVE_STRENGTH(0x80, 0x00, 0x01, 0x02, 0x03),
 		&onfi_extend_cmds,
-		CHIP_TIMING_MODE2, //jb.qi change for ubi problem on 20221129
+		CHIP_TIMING_MODE2,
 		&timing_mode[0],
-		sdr_timing_micron_slc //zhengzhou for MT29GZ6A6BPIET-046AAT.112 
+		sdr_timing_micron_slc
 	},
 	/* Winbond */
 	{
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.c b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.c
index 81f8755..d038970 100755
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.c
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.c
@@ -63,6 +63,7 @@
 		}
 		nand->performance->read_data_time = (int)time_cons;
 #endif
+
 		ret_max = max_t(int, ret_max, ops[i].status);
 		ret_min = min_t(int, ret_min, ops[i].status);
 #if NANDX_PAGE_PERFORMANCE_TRACE
@@ -160,7 +161,6 @@
 	return ret;
 }
 
-/*jb.qi change for ubi problem on 20221129 start*/
 static inline void nand_bit_invert(u8 *buf, int len)
 {
 	int i;
@@ -259,7 +259,6 @@
 restore_ecc:
 	nandx_ioctl(NFI_CTRL_ECC, &nfi_ecc_en_old);
 }
-/*jb.qi change for ubi problem on 20221129 end*/
 
 static int nand_chip_erase_block(struct nand_chip *chip,
 				 struct nand_ops *ops,
@@ -276,12 +275,11 @@
 
 		nand->addressing(nand, &row, &col);
 
-		/*jb.qi change for ubi problem on 20221129 start*/
 		/* void type to avoid mis-judging this block as bad in ubi,
 		 * nand block erase operation can continue
 		 */
 		nand_chip_erase_prepare(chip, row, col);
-		/*jb.qi change for ubi problem on 20221129 end*/
+
 		ops[i].status = nand->write_enable(nand);
 		if (ops[i].status) {
 			pr_debug("Write Protect at %x!\n", row);
@@ -435,6 +433,6 @@
 		nand_spi_exit(chip->nand);
 	else
 		nand_exit(chip->nand);
-	mem_free(chip->raw_buf); //jb.qi change for ubi problem on 20221129
+	mem_free(chip->raw_buf);
 	mem_free(chip);
 }
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.h b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.h
index 997fad0..cdcfaa3 100755
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.h
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.h
@@ -75,7 +75,8 @@
 	u32 fdm_reg_size;
 
 	void *nand;
-	u8 *raw_buf; //jb.qi add for ubi problem on 20221129
+	u8 *raw_buf;
+
 	int (*read_page)(struct nand_chip *chip, struct nand_ops *ops,
 			 int count);
 	int (*write_page)(struct nand_chip *chip, struct nand_ops *ops,
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nfi/nfi_base.c b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nfi/nfi_base.c
index e6528f5..69e499d 100755
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nfi/nfi_base.c
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nfi/nfi_base.c
@@ -558,7 +558,7 @@
 	case NFI_CTRL_BAD_MARK_SWAP:
 		nb->bad_mark_swap_en = *(bool *)args;
 		break;
-	/*jb.qi change for ubi problem on 20221129 start*/
+
 	case NFI_CTRL_BAD_MARK_SWAP_GET_SWAP_EN:
 		*(bool *)args = nb->bad_mark_swap_en;
 		break;
@@ -566,7 +566,7 @@
 	case NFI_CTRL_ECC_GET_ECC_EN:
 		*(bool *)args = nb->ecc_en;
 		break;
-	/*jb.qi change for ubi problem on 20221129 end*/
+
 #ifdef NANDX_TEST_BUF_ALIGN
 	case NFI_ADDR_ALIGNMENT_EN:
 		if (*(u8 *)args)
@@ -1146,15 +1146,14 @@
 	if (read) {
 		is_empty = nb->is_page_empty(nb, data, fdm, nb->rw_sectors);
 		if (is_empty) {
- 			nb->read_status = 0;
+			nb->read_status = 0;
 
 			/* try to memset 0xff for empty page */
 			if (data)
 				memset(data, 0xff, nb->access_len);
 			if (nb->ecc_en && fdm)
 				memset(fdm, 0xff, nb->nfi.fdm_size * nb->rw_sectors);
-		}/*jb.qi change for ubi1_0 problem on 20220921 end*/
-
+		}
 	}
 
 	/* whether it's reading or writing, we all check if nee swap
@@ -1343,7 +1342,7 @@
 	void *regs = nb->res.nfi_regs;
 	u32 tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt, tstrobe;
 	u32 rate, val;
-	u16 thold; //jb.qi change for ubi problem on 20221129
+	u16 thold;
 	int ret;
 
 	ret = wait_flash_macro_idle(regs);
@@ -1353,13 +1352,14 @@
 	}
 
 	/* turn clock rate into KHZ */
-	rate = div_down(nb->res.clock_1x, 1000);  //jb.qi change for ubi problem on 20221129
-	tpoecs = max(sdr->tALH, sdr->tCLH);    
+	rate = div_down(nb->res.clock_1x, 1000);
+
+	tpoecs = max(sdr->tALH, sdr->tCLH);
 	tpoecs = div_up(tpoecs * rate, 1000000);
 	tpoecs &= 0xf;
 
 	tprecs = max(sdr->tCLS, sdr->tALS);
-	tprecs = div_up(tprecs * rate, 1000000) + 1;  //jb.qi change for ubi problem on 20221129
+	tprecs = div_up(tprecs * rate, 1000000) + 1;
 	tprecs &= 0x3f;
 
 	/* tc2r is in unit of 2T */
@@ -1375,32 +1375,26 @@
 	twh = div_up(twh * rate, 1000000) - 1;
 	twh &= 0xf;
 
-	/*jb.qi change for ubi problem on 20221129 start*/
 	twst = 0;
 	thold = div_down((twh + 1) * 1000000, rate);
 	if (thold < sdr->tWC)
 		twst = sdr->tWC - thold;
 	twst = max((u32)sdr->tWP, twst);
 	twst = div_up(twst * rate, 1000000) - 1;
-	/*jb.qi change for ubi problem on 20221129 end*/
 	twst &= 0xf;
 
-	/*jb.qi change for ubi problem on 20221129 start*/
 	trlt = 0;
 	if (thold < sdr->tRC)
 		trlt = sdr->tRC - thold;
 	trlt = max((u32)sdr->tRP, trlt);
 	trlt = div_up(trlt * rate, 1000000) - 1;
-	/*jb.qi change for ubi problem on 20221129 end*/
 	trlt &= 0xf;
 
-	tstrobe = 0; //jb.qi change for ubi problem on 20221129
+	tstrobe = 0;
 	/* If tREA is bigger than tRP, setup strobe sel here */
-	/*jb.qi change for ubi problem on 20221129 start*/
 	if (div_down((trlt + 1) * 1000000, rate) < sdr->tREA) {
 		tstrobe = div_up(sdr->tREA * rate, 1000000);
 		tstrobe -= trlt + 1;
-	/*jb.qi change for ubi problem on 20221129 end*/
 		val = readl(regs + NFI_DEBUG_CON1);
 		val &= ~STROBE_MASK;
 		val |= tstrobe << STROBE_SHIFT;
@@ -1421,7 +1415,7 @@
 	 * 03:00: trlt, read wait states
 	 */
 	val = ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt);
-	pr_debug("NAND acctiming: 0x%x, strobe_sel:0x%x\n", val, tstrobe); //jb.qi change for ubi problem on 20221129
+	pr_debug("NAND acctiming: 0x%x, strobe_sel:0x%x\n", val, tstrobe);
 	writel(val, regs + NFI_ACCCON);
 
 	/* set NAND type */
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/include/internal/nandx_core.h b/src/kernel/linux/v4.19/drivers/mtd/nandx/include/internal/nandx_core.h
index 61d1288..4e45bd7 100755
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/include/internal/nandx_core.h
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/include/internal/nandx_core.h
@@ -67,11 +67,10 @@
 	NFI_CTRL_ECC_DECODE_MODE,
 	NFI_CTRL_ECC_ERRNUM0,
 	NFI_CTRL_ECC_GET_STATUS, /*20*/
-	NFI_CTRL_ECC_GET_ECC_EN, //jb.qi change for ubi problem on 20221129
-
+	NFI_CTRL_ECC_GET_ECC_EN,
 
 	NFI_CTRL_BAD_MARK_SWAP,
-	NFI_CTRL_BAD_MARK_SWAP_GET_SWAP_EN, //jb.qi change for ubi problem on 20221129
+	NFI_CTRL_BAD_MARK_SWAP_GET_SWAP_EN,
 	NFI_CTRL_IOCON,
 
 	SNFI_CTRL_OP_MODE,
diff --git a/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_edma.c b/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_edma.c
index 86123c0..29d23de 100644
--- a/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_edma.c
+++ b/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_edma.c
@@ -569,11 +569,10 @@
 	//EDMA_GLO_CFG: TX_WB_DDONE | RX_DMA_EN |
 	//   PDMA_BT_SIZE_16DWORDS | PDMA_DESC_32B_E |
 	//   MULTI_EN | ADMA_RX_BT_SIZE_32DWORDS  RX_2B_OFFSET
-	/*jb.qi change for reboot after sleep on 20230417 start*/
+
 	/* Set EDMA0_GLO_CFG and EDMA1_GLO_CFG [23:16] to 0x80 since CDM FIFO overrun issue */
 	mtk_w32(eth, 0x80801C64, MTK_EDMA0_GLO_CFG);
 	mtk_w32(eth, 0x80801C64, MTK_EDMA1_GLO_CFG);
-	/*jb.qi change for reboot after sleep on 20230417 end*/
 }
 
 void mtk_stop_dma_edma(struct mtk_eth *eth, u32 glo_cfg)
diff --git a/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
index 3e92205..b0f0f68 100644
--- a/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
+++ b/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
@@ -695,7 +695,7 @@
 
 	cr_max = 5000 * 4;
 	seq_puts(seq, "       <<FE CR DUMP>>\n");
-	for (i = 0x0; i < cr_max; i = i + 0x10) { //jb.qi change for reboot after sleep on20230417
+	for (i = 0x0; i < cr_max; i = i + 0x10) {
 		seq_printf(seq, "0x%08x : 0x%08x 0x%08x 0x%08x 0x%08x\n", cr_base + i,
 			mtk_r32(eth, i), mtk_r32(eth, i + 4),
 			mtk_r32(eth, i + 8), mtk_r32(eth, i + 0xc));
diff --git a/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 709b7c9..42510fa 100755
--- a/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -831,10 +831,10 @@
 				  DMA_FROM_DEVICE);
 	if (unlikely(dma_mapping_error(eth->dev, dma_addr)))
 		return -ENOMEM;
-	/*jb.qi change for reboot after sleep on 20230417 start*/
+
 	eth->phy_scratch_head = dma_addr;
 	eth->scratch_head_size = cnt * MTK_QDMA_PAGE_SIZE;
-	/*jb.qi change for reboot after sleep on 20230417 end*/
+
 	memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
 	phy_ring_tail = eth->phy_scratch_ring +
 			(sizeof(struct mtk_tx_dma) * (cnt - 1));
@@ -2932,7 +2932,7 @@
 		for (i = 1; i < MTK_MAX_RX_RING_NUM; i++)
 			mtk_rx_clean(eth, &eth->rx_ring[i]);
 	}
-	/*jb.qi change for reboot after sleep on 20230417 start*/
+
 	if (eth->phy_scratch_head) {
 		dma_unmap_single(eth->dev, eth->phy_scratch_head,
 			eth->scratch_head_size,	DMA_FROM_DEVICE);
@@ -2944,7 +2944,7 @@
 		kfree(eth->scratch_head);
 		eth->scratch_head = NULL;
 	}
-	/*jb.qi change for reboot after sleep on 20230417 end*/
+
 	if (eth->hwedmarx) {
 		for (i = 0; i < MTK_MAX_EDMA_RX_RING_NUM; i++) {
 			mtk_rx_clean_edma(eth, &eth->rx_ring_edma0[i]);
@@ -3238,10 +3238,10 @@
 		} else {
 			napi_enable(&eth->rx_napi);
 		}
-		/*jb.qi change for reboot after sleep on 20230417 start*/
+
 		if (eth->hwedmarx)
 			napi_enable_edma(eth);
-		/*jb.qi change for reboot after sleep on 20230417 end*/
+
 		/* enable IRQ Top */
 		mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
 		if (eth->hwrss) {
@@ -3253,7 +3253,7 @@
 			mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
 		}
 
-		if (eth->hwedmarx) //jb.qi change for reboot after sleep on 20230417
+		if (eth->hwedmarx)
 			mtk_rx_irq_enable_edma_all(eth);
 
 #if defined(CONFIG_HW_NAT)
@@ -3301,7 +3301,7 @@
 	struct mtk_mac *mac = netdev_priv(dev);
 	struct mtk_eth *eth = mac->hw;
 
-	pr_info("%s in mac[%d]\n", __func__, mac->id); //jb.qi change for reboot after sleep on 20230417
+	pr_info("%s in mac[%d]\n", __func__, mac->id);
 
 	netif_tx_disable(dev);
 
@@ -3311,11 +3311,11 @@
 	/* only shutdown DMA if this is the last user */
 	if (!refcount_dec_and_test(&eth->dma_refcnt))
 		return 0;
-/*jb.qi change for reboot after sleep on 20230417 start*/
+
 #if defined(CONFIG_HW_NAT)
 	mtk_unregister_fast_path();
 #endif
-/*jb.qi change for reboot after sleep on 20230417 end*/
+
 	mtk_gdma_config(eth, MTK_GDMA_DROP_ALL);
 
 	/* disable IRQ Top */
@@ -3329,13 +3329,13 @@
 	} else {
 		mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
 	}
-	/*jb.qi change for reboot after sleep on 20230417 start*/
+
 	if (eth->hwedmarx)
 		mtk_rx_irq_disable_edma_all(eth);
 
 	if (eth->int_ext)
 		disable_irq_nosync(eth->irq[8]);
-	/*jb.qi change for reboot after sleep on 20230417 end*/
+
 	/* disable IRQ Bottom */
 	napi_disable(&eth->tx_napi);
 
@@ -3347,12 +3347,12 @@
 	} else {
 		napi_disable(&eth->rx_napi);
 	}
-	/*jb.qi change for reboot after sleep on 20230417 start*/
+
 	if (eth->hwedmarx) {
 		napi_disable(&eth->rx_napi_edma0);
 		napi_disable(&eth->rx_napi_edma1);
 	}
-	/*jb.qi change for reboot after sleep on 20230417 end*/
+
 	mtk_stop_dma(eth, MTK_QDMA_GLO_CFG);
 	mtk_stop_dma(eth, MTK_PDMA_GLO_CFG);
 
@@ -3744,10 +3744,9 @@
 
 static int mtk_hw_deinit(struct mtk_eth *eth)
 {
-	/*jb.qi change for reboot after sleep on 20230417 start*/
 	//if (!test_and_clear_bit(MTK_HW_INIT, &eth->state))
 	//	return 0;
-	/*jb.qi change for reboot after sleep on 20230417 end*/
+
 	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_FPGA_CLK)) {
 		mtk_clk_disable(eth);
 		pm_runtime_put_sync(eth->dev);
@@ -4281,7 +4280,6 @@
 		dev_err(&pdev->dev, "no wo regmap found\n");
 		return PTR_ERR(eth->wo);
 	}
-	/*jb.qi change for reboot after sleep on 20230417 start*/
 	regmap_write(eth->wo, 0x0070, 0x1);
 	regmap_write(eth->wo, 0x0074, 0x1);
 	pr_notice("%s reset wo\n", __func__);
@@ -4301,7 +4299,7 @@
 	}
 	regmap_write(eth->wed2, 0x057c, 0x0);
 	pr_notice("%s reset wed2\n", __func__);
-	/*jb.qi change for reboot after sleep on 20230417 end*/
+
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_INFRA)) {
 		eth->infra = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
 							"mediatek,infracfg");
@@ -4573,7 +4571,7 @@
 
 	return 0;
 }
-/*jb.qi change for reboot after sleep on 20230417 start*/
+
 int netsys_pm_check_status(struct mtk_eth *eth, u32 idle)
 {
 	u32 val = 0, tmp = 0, cnt = 0, pass = 0;
@@ -4667,7 +4665,7 @@
 void netsys_pm_recovery(struct mtk_eth *eth)
 {
 }
-/*jb.qi change for reboot after sleep on 20230417 end*/
+
 int netsys_pm_suspend(struct device *device)
 {
 	struct platform_device *pdev = to_platform_device(device);
@@ -4677,12 +4675,12 @@
 	pr_notice("ethernet suspend time start = %lx\n", jiffies);
 
 	if (pdev == NULL) {
-		pr_notice("%s pdev == NULL\n", __func__); //jb.qi change for reboot after sleep on 20230417
+		pr_notice("%s pdev == NULL\n", __func__);
 		return -1;
 	}
 
 	eth = platform_get_drvdata(pdev);
-	/*jb.qi change for reboot after sleep on 20230417 start*/
+
 	regmap_write(eth->ethsys, 0x10, 0xb6000000);
 	regmap_write(eth->ethsys, 0x58, 0x20000000);
 	regmap_write(eth->ethsys, 0xf0, 0x007f0000);
@@ -4711,7 +4709,7 @@
 		}
 	}
 	pr_notice("ethernet suspend time phy stop = %lx\n", jiffies);
-	/*jb.qi change for reboot after sleep on 20230417 end*/
+
 #if 0
 	regmap_update_bits(eth->ethsys, MTK_PPE_TB_CFG,
 			   SCAN_MODE_MASK,
@@ -4726,10 +4724,10 @@
 	if (eth->soc->sgmii_pm)
 		regulator_set_voltage(eth->dvfsrc_vcore_power,
 				      SGMII_VCORE_NON_OPS, INT_MAX);
-	pr_notice("ethernet suspend time set vcore 0.55V = %lx\n", jiffies);//jb.qi change for reboot after sleep on 20230417
+	pr_notice("ethernet suspend time set vcore 0.55V = %lx\n", jiffies);
 
 	mtk_gdma_config(eth, MTK_GDMA_DROP_ALL);
-	pr_notice("ethernet suspend time set GDM ingress pkt drop = %lx\n", jiffies);//jb.qi change for reboot after sleep on 20230417
+	pr_notice("ethernet suspend time set GDM ingress pkt drop = %lx\n", jiffies);
 
 	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
 	if (eth->hwrss) {
@@ -4744,15 +4742,15 @@
 	if (eth->int_ext)
 		disable_irq_nosync(eth->irq[8]);
 
-	pr_notice("ethernet suspend time disable irq = %lx\n", jiffies);//jb.qi change for reboot after sleep on 20230417
+	pr_notice("ethernet suspend time disable irq = %lx\n", jiffies);
 
 	if (eth->hwedmarx) {
 		mtk_rx_irq_disable_edma_all(eth);
 		mtk_stop_dma_edma(eth, MTK_EDMA0_GLO_CFG);
 		mtk_stop_dma_edma(eth, MTK_EDMA1_GLO_CFG);
 	}
-	pr_notice("ethernet suspend time stop EDMA = %lx\n", jiffies);//jb.qi change for reboot after sleep on 20230417
-	/*jb.qi change for reboot after sleep on 20230417 start*/
+	pr_notice("ethernet suspend time stop EDMA = %lx\n", jiffies);
+
 	//napi_disable(&eth->tx_napi);
 	//napi_disable(&eth->rx_napi);
 	/*disable ADMA*/
@@ -4775,7 +4773,7 @@
 	mtk_clk_disable(eth);
 	pr_notice("ethernet suspend time clk disable = %lx\n", jiffies);
 	pr_notice("ethernet suspend time end = %lx\n", jiffies);
-	/*jb.qi change for reboot after sleep on 20230417 end*/
+
 	return 0;
 }
 
@@ -4790,7 +4788,7 @@
 	pr_notice("ethernet resume time start = %lx\n", jiffies);
 
 	if (pdev == NULL) {
-		pr_notice("%s pdev == NULL\n", __func__); //jb.qi change for reboot after sleep on 20230417
+		pr_notice("%s pdev == NULL\n", __func__);
 		return -1;
 	}
 
@@ -4805,9 +4803,9 @@
 			   SCAN_MODE);
 #endif
 
-	mtk_clk_enable(eth);//jb.qi change for reboot after sleep on 20230417
+	mtk_clk_enable(eth);
 	mtk_hw_init_resume(eth);
-	pr_notice("ethernet resume time clk enable = %lx\n", jiffies);//jb.qi change for reboot after sleep on 20230417
+	pr_notice("ethernet resume time clk enable = %lx\n", jiffies);
 
 	//mtk_w32(eth, 0x27fb5, MTK_PPE_TB_CFG);
 	//mtk_w32(eth, 0x27fb5, MTK_PPE1_TB_CFG);
@@ -4890,7 +4888,7 @@
 	for (i = 0; i < MTK_MAC_COUNT; i++) {
 		if (!eth->netdev[i])
 			continue;
-		/*jb.qi change for reboot after sleep on 20230417 start*/
+
 		pr_notice("restore %s state=%d mac%d=0x%x",
 			eth->netdev[i]->name,
 			eth->suspend_data.eth_state[i],
@@ -4901,14 +4899,14 @@
 				phy_start(eth->netdev[i]->phydev);
 			netif_start_queue(eth->netdev[i]);
 		}
-		/*jb.qi change for reboot after sleep on 20230417 end*/
 	}
 
-	pr_notice("ethernet resume time eth up = %lx\n", jiffies);//jb.qi change for reboot after sleep on 20230417
+	pr_notice("ethernet resume time eth up = %lx\n", jiffies);
 	pr_notice("ethernet resume time end = %lx\n", jiffies);
 
 	return 0;
 }
+
 static const struct dev_pm_ops netsys_pm_ops = {
 	.suspend_noirq = netsys_pm_suspend,
 	.resume_noirq = netsys_pm_resume,
diff --git a/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index bcfe59c..8b1c23e 100644
--- a/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/src/kernel/linux/v4.19/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1026,12 +1026,12 @@
 	u32             flags[MTK_MAX_DEVS];
 	u32             ana_rgc3;
 };
-/*jb.qi change for reboot after sleep on 20230417 start*/
+
 struct mtk_suspend_data {
 	int		eth_state[MTK_MAX_DEVS];
 	u32		mcr[MTK_MAX_DEVS];
 };
-/*jb.qi change for reboot after sleep on 20230417 end*/
+
 /* struct mtk_eth -	This is the main datasructure for holding the state
  *			of the driver
  * @dev:		The device pointer
@@ -1083,8 +1083,8 @@
 	struct regmap			*ethsys;
 	struct regmap                   *infra;
 	struct regmap                   *wo;
-	struct regmap                   *wed;//jb.qi change for reboot after sleep on 20230417
-	struct regmap                   *wed2;//jb.qi change for reboot after sleep on 20230417
+	struct regmap                   *wed;
+	struct regmap                   *wed2;
 	struct mtk_sgmii                *sgmii;
 	struct regmap			*pctl;
 	u32				hwlro;
@@ -1136,7 +1136,7 @@
 	unsigned int			irq_work;
 	struct work_struct		link_work;
 
-	struct mtk_suspend_data		suspend_data;//jb.qi change for reboot after sleep on 20230417
+	struct mtk_suspend_data		suspend_data;
 };
 
 /* struct mtk_mac -	the structure that holds the info about the MACs of the
diff --git a/src/kernel/linux/v4.19/drivers/rtc/rtc-mt6330.c b/src/kernel/linux/v4.19/drivers/rtc/rtc-mt6330.c
index 7783c74..404fc55 100644
--- a/src/kernel/linux/v4.19/drivers/rtc/rtc-mt6330.c
+++ b/src/kernel/linux/v4.19/drivers/rtc/rtc-mt6330.c
@@ -180,10 +180,10 @@
 	struct regmap_field	*spare[SPARE_RG_MAX];
 	struct regmap_field	*cali[CALI_FILED_MAX];
 	bool			cali_is_supported;
-	ktime_t		wakeup_time; //jb.qi change for rtc resume API on 2022.11.18 start
+	ktime_t		wakeup_time;
 };
 
-bool wakeup_by_rtc; //jb.qi change for rtc resume API on 2022.11.18 start
+bool wakeup_by_rtc;
 #define RTC_WAKEUP_THRESHOLD	1500000000 // 1500ms jb.qi change for rtc resume API on 20230802
 
 static int mtk_rtc_write_trigger(struct mt6330_rtc *rtc);
@@ -534,9 +534,9 @@
 		if (i == RTC_OFFSET_DOW)
 			continue;
 		ret = rtc_update_bits(rtc,
-					 rtc->addr_base + rtc_pwron_reg[i][RTC_REG],
-					 rtc_pwron_reg[i][RTC_MASK],
-					 data[i]);
+				rtc->addr_base + rtc_pwron_reg[i][RTC_REG],
+				rtc_pwron_reg[i][RTC_MASK],
+				data[i]);
 
 		if (ret < 0)
 			goto exit;
@@ -577,8 +577,6 @@
 	if (ret < 0)
 		goto exit;
 
-//	mtk_rtc_write_trigger(rtc);
-
 	return;
 
 exit:
@@ -1033,10 +1031,9 @@
 	if (rtc->dev_comp->cali_reg_fields)
 		if (mtk_rtc_config_eosc_cali(&pdev->dev))
 			dev_err(&pdev->dev, "config eosc cali failed\n");
-	/*jb.qi change for rtc resume API on 2022.11.18 start*/
+
 	rtc->wakeup_time = ktime_get();
 	wakeup_by_rtc = false;
-	/*jb.qi change for rtc resume API on 2022.11.18 end*/
 
 	return 0;
 
@@ -1058,12 +1055,11 @@
 }
 
 #ifdef CONFIG_PM_SLEEP
-/*jb.qi change for rtc resume API on 2022.11.18 start*/
 bool isWakeupByRTC(void)
 {
 	return wakeup_by_rtc;
 }
-/*jb.qi change for rtc resume API on 2022.11.18 start*/
+
 static int mt6330_rtc_suspend(struct device *dev)
 {
 	struct mt6330_rtc *rtc = dev_get_drvdata(dev);
@@ -1071,7 +1067,7 @@
 	if (device_may_wakeup(dev))
 		enable_irq_wake(rtc->irq);
 
-	wakeup_by_rtc = false; //jb.qi change for rtc resume API on 2022.11.18 
+	wakeup_by_rtc = false;
 
 	return 0;
 }
@@ -1079,11 +1075,11 @@
 static int mt6330_rtc_resume(struct device *dev)
 {
 	struct mt6330_rtc *rtc = dev_get_drvdata(dev);
-	ktime_t temp; //jb.qi change for rtc resume API on 2022.11.18 
- 
+	ktime_t temp;
+
 	if (device_may_wakeup(dev))
 		disable_irq_wake(rtc->irq);
-	/*jb.qi change for rtc resume API on 2022.11.18 start*/
+
 	temp = ktime_get();
 
 	wakeup_by_rtc = false;
@@ -1091,7 +1087,6 @@
 		wakeup_by_rtc = true;
 
 	dev_info(dev, "%s: wakeup time:%lld, resume_time %lld wakeup_by_rtc %d\n", __func__, rtc->wakeup_time, temp, wakeup_by_rtc);
-	/*jb.qi change for rtc resume API on 2022.11.18 end*/
 	return 0;
 }
 #endif
diff --git a/src/kernel/linux/v4.19/drivers/rtc/rtc-proc.c b/src/kernel/linux/v4.19/drivers/rtc/rtc-proc.c
index 9256596..dfd09b9 100644
--- a/src/kernel/linux/v4.19/drivers/rtc/rtc-proc.c
+++ b/src/kernel/linux/v4.19/drivers/rtc/rtc-proc.c
@@ -106,7 +106,7 @@
 
 	return 0;
 }
-/*jb.qi change for rtc resume API on 2022.11.18 start*/
+
 #ifdef CONFIG_PM_SLEEP
 extern bool isWakeupByRTC(void);
 #endif
@@ -118,14 +118,14 @@
 #endif
 	return 0;
 }
-/*jb.qi change for rtc resume API on 2022.11.18 end*/
+
 void rtc_proc_add_device(struct rtc_device *rtc)
 {
 	if (is_rtc_hctosys(rtc)) {
- 		proc_create_single_data("driver/rtc", 0, NULL, rtc_proc_show,
- 				rtc);
+		proc_create_single_data("driver/rtc", 0, NULL, rtc_proc_show,
+				rtc);
 		proc_create_single_data("driver/rtc_wakeup", 0, NULL, rtc_wakeup_proc_show,
-				rtc); //jb.qi change for rtc resume API on 2022.11.18
+				rtc);
 	}
 }
 
diff --git a/src/kernel/linux/v4.19/drivers/soc/mediatek/Kconfig b/src/kernel/linux/v4.19/drivers/soc/mediatek/Kconfig
index 7945f5c..c82a4f4 100755
--- a/src/kernel/linux/v4.19/drivers/soc/mediatek/Kconfig
+++ b/src/kernel/linux/v4.19/drivers/soc/mediatek/Kconfig
@@ -83,10 +83,6 @@
 	  platform could enter deeper sleep mode when cpu preparing to
 	  power down if it have sufficient time between warmboot.
 
-#Typethree@2023.2.01 modify for TCXO hw version start
-
-#Typethree@2023.2.01 modify for TCXO hw version end
-
 config MTK_IPI
 	tristate "MediaTek IPI Support"
 	depends on RPMSG_MTK
diff --git a/src/kernel/linux/v4.19/drivers/soc/mediatek/mtk-scpsys.c b/src/kernel/linux/v4.19/drivers/soc/mediatek/mtk-scpsys.c
index 6846443..92ead56 100755
--- a/src/kernel/linux/v4.19/drivers/soc/mediatek/mtk-scpsys.c
+++ b/src/kernel/linux/v4.19/drivers/soc/mediatek/mtk-scpsys.c
@@ -1398,7 +1398,7 @@
 	for (i = 0; i < num; i++) {
 		struct scp_domain *scpd = &scp->domains[i];
 		struct generic_pm_domain *genpd = &scpd->genpd;
-		bool on;//jb.qi change for reboot after sleep on 20230417
+		bool on;
 		/*
 		 * Initially turn on the domains to make the domains usable
 		 * with !CONFIG_PM and to get the hardware in sync with the
@@ -1407,7 +1407,6 @@
 		 * Power on the ssusb/netsys/connectivity by default to let each driver
 		 * disable the clock in case of no usage.
 		 */
-		/*jb.qi change for reboot after sleep on 20230417 start*/
 		if (strcmp(genpd->name, "ssusb_phy") == 0 ||
 		    strcmp(genpd->name, "netsys") == 0 ||
 		    strcmp(genpd->name, "conn") == 0) {
@@ -1424,7 +1423,6 @@
 		}
 
 		pm_genpd_init(genpd, NULL, !on);
-		/*jb.qi change for reboot after sleep on 20230417 end*/
 	}
 
 	/*
@@ -1727,12 +1725,10 @@
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.basic_clk_name = {"audio"},
 		.caps = MTK_SCPD_STRICT_BUSP,
-		/*jb.qi change for reboot after sleep on 20230417 start*/
 		.bp_table = {
 			BUS_PROT(IFR_TYPE, MT6779_IFR_SET, MT6779_IFR_CLR,
 				0, MT6779_IFR_STA1, BIT(31), BIT(31), 0),
 		},
-		/*jb.qi change for reboot after sleep on 20230417 end*/
 	},
 
 	[MT6779_POWER_DOMAIN_MM] = {
diff --git a/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_mutt.c b/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_mutt.c
index 60f2f2a..fff906e 100644
--- a/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_mutt.c
+++ b/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_mutt.c
@@ -131,6 +131,7 @@
 	struct md_cooling_device *md_cdev = cdev->devdata;
 	struct mutt_driver_data *drv_data;
 	struct device *dev;
+	struct thermal_instance *instance;
 	enum md_status status, new_status;
 	unsigned int msg;
 	unsigned long target_lv, final_lv;
@@ -161,6 +162,10 @@
 		mutex_lock(&drv_data->lock);
 		drv_data->current_level = MD_COOLING_UNLIMITED_LV;
 		mutex_unlock(&drv_data->lock);
+		list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
+			if (instance->cdev->type == cdev->type)
+				instance->target = MD_COOLING_UNLIMITED_LV;
+		}
 		return 0;
 	}
 
diff --git a/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_scg_off.c b/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_scg_off.c
index a4e244b..93e77ac 100644
--- a/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_scg_off.c
+++ b/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_scg_off.c
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <md_cooling.h>
 #include <mtk_thermal_trace.h>
+#include "../thermal_core.h"
 
 #define SCG_OFF_MAX_LEVEL	(1)
 
@@ -39,6 +40,7 @@
 {
 	struct md_cooling_device *md_cdev = cdev->devdata;
 	struct device *dev = (struct device *)md_cdev->dev_data;
+	struct thermal_instance *instance;
 	enum md_status status;
 	unsigned int msg;
 	int ret = 0;
@@ -53,8 +55,13 @@
 	status = get_md_status();
 	if (is_mutt_enabled(status)) {
 		dev_info(dev, "skip SCG control due to MUTT is enabled\n");
-		if (is_md_off(status))
+		if (is_md_off(status)) {
 			md_cdev->target_level = MD_COOLING_UNLIMITED_LV;
+			list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
+				if (instance->cdev->type == cdev->type)
+					instance->target = MD_COOLING_UNLIMITED_LV;
+			}
+		}
 		trace_md_scg_off(md_cdev, status);
 		return -EACCES;
 	}
diff --git a/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_tx_pwr.c b/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_tx_pwr.c
index 3f1e29f..b509f0c 100644
--- a/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_tx_pwr.c
+++ b/src/kernel/linux/v4.19/drivers/thermal/mediatek/md_cooling_tx_pwr.c
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <md_cooling.h>
 #include <mtk_thermal_trace.h>
+#include "../thermal_core.h"
 
 #define DEFAULT_THROTTLE_TX_PWR_LV1	(4)
 #define DEFAULT_THROTTLE_TX_PWR_LV2	(6)
@@ -43,6 +44,7 @@
 	struct device *dev = (struct device *)md_cdev->dev_data;
 	enum md_status status;
 	unsigned int msg, pwr;
+	struct thermal_instance *instance;
 	int ret = 0;
 
 	/* Request state should be less than max_level */
@@ -55,8 +57,13 @@
 	status = get_md_status();
 	if (is_md_inactive(status)) {
 		dev_info(dev, "skip tx pwr control due to MD is inactive\n");
-		if (is_md_off(status))
+		if (is_md_off(status)) {
 			md_cdev->target_level = MD_COOLING_UNLIMITED_LV;
+			list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
+				if (instance->cdev->type == cdev->type)
+					instance->target = MD_COOLING_UNLIMITED_LV;
+			}
+		}
 		trace_md_tx_pwr_limit(md_cdev, status);
 		return -EACCES;
 	}
diff --git a/src/kernel/linux/v4.19/include/dt-bindings/input/linux-event-codes.h b/src/kernel/linux/v4.19/include/dt-bindings/input/linux-event-codes.h
deleted file mode 120000
index 693bbcd..0000000
--- a/src/kernel/linux/v4.19/include/dt-bindings/input/linux-event-codes.h
+++ /dev/null
@@ -1 +0,0 @@
-../../uapi/linux/input-event-codes.h
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/include/dt-bindings/input/linux-event-codes.h b/src/kernel/linux/v4.19/include/dt-bindings/input/linux-event-codes.h
new file mode 100644
index 0000000..61a5799
--- /dev/null
+++ b/src/kernel/linux/v4.19/include/dt-bindings/input/linux-event-codes.h
@@ -0,0 +1,851 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Input event codes
+ *
+ *    *** IMPORTANT ***
+ * This file is not only included from C-code but also from devicetree source
+ * files. As such this file MUST only contain comments and defines.
+ *
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef _UAPI_INPUT_EVENT_CODES_H
+#define _UAPI_INPUT_EVENT_CODES_H
+
+/*
+ * Device properties and quirks
+ */
+
+#define INPUT_PROP_POINTER		0x00	/* needs a pointer */
+#define INPUT_PROP_DIRECT		0x01	/* direct input devices */
+#define INPUT_PROP_BUTTONPAD		0x02	/* has button(s) under pad */
+#define INPUT_PROP_SEMI_MT		0x03	/* touch rectangle only */
+#define INPUT_PROP_TOPBUTTONPAD		0x04	/* softbuttons at top of pad */
+#define INPUT_PROP_POINTING_STICK	0x05	/* is a pointing stick */
+#define INPUT_PROP_ACCELEROMETER	0x06	/* has accelerometer */
+
+#define INPUT_PROP_MAX			0x1f
+#define INPUT_PROP_CNT			(INPUT_PROP_MAX + 1)
+
+/*
+ * Event types
+ */
+
+#define EV_SYN			0x00
+#define EV_KEY			0x01
+#define EV_REL			0x02
+#define EV_ABS			0x03
+#define EV_MSC			0x04
+#define EV_SW			0x05
+#define EV_LED			0x11
+#define EV_SND			0x12
+#define EV_REP			0x14
+#define EV_FF			0x15
+#define EV_PWR			0x16
+#define EV_FF_STATUS		0x17
+#define EV_MAX			0x1f
+#define EV_CNT			(EV_MAX+1)
+
+/*
+ * Synchronization events.
+ */
+
+#define SYN_REPORT		0
+#define SYN_CONFIG		1
+#define SYN_MT_REPORT		2
+#define SYN_DROPPED		3
+#define SYN_MAX			0xf
+#define SYN_CNT			(SYN_MAX+1)
+
+/*
+ * Keys and buttons
+ *
+ * Most of the keys/buttons are modeled after USB HUT 1.12
+ * (see http://www.usb.org/developers/hidpage).
+ * Abbreviations in the comments:
+ * AC - Application Control
+ * AL - Application Launch Button
+ * SC - System Control
+ */
+
+#define KEY_RESERVED		0
+#define KEY_ESC			1
+#define KEY_1			2
+#define KEY_2			3
+#define KEY_3			4
+#define KEY_4			5
+#define KEY_5			6
+#define KEY_6			7
+#define KEY_7			8
+#define KEY_8			9
+#define KEY_9			10
+#define KEY_0			11
+#define KEY_MINUS		12
+#define KEY_EQUAL		13
+#define KEY_BACKSPACE		14
+#define KEY_TAB			15
+#define KEY_Q			16
+#define KEY_W			17
+#define KEY_E			18
+#define KEY_R			19
+#define KEY_T			20
+#define KEY_Y			21
+#define KEY_U			22
+#define KEY_I			23
+#define KEY_O			24
+#define KEY_P			25
+#define KEY_LEFTBRACE		26
+#define KEY_RIGHTBRACE		27
+#define KEY_ENTER		28
+#define KEY_LEFTCTRL		29
+#define KEY_A			30
+#define KEY_S			31
+#define KEY_D			32
+#define KEY_F			33
+#define KEY_G			34
+#define KEY_H			35
+#define KEY_J			36
+#define KEY_K			37
+#define KEY_L			38
+#define KEY_SEMICOLON		39
+#define KEY_APOSTROPHE		40
+#define KEY_GRAVE		41
+#define KEY_LEFTSHIFT		42
+#define KEY_BACKSLASH		43
+#define KEY_Z			44
+#define KEY_X			45
+#define KEY_C			46
+#define KEY_V			47
+#define KEY_B			48
+#define KEY_N			49
+#define KEY_M			50
+#define KEY_COMMA		51
+#define KEY_DOT			52
+#define KEY_SLASH		53
+#define KEY_RIGHTSHIFT		54
+#define KEY_KPASTERISK		55
+#define KEY_LEFTALT		56
+#define KEY_SPACE		57
+#define KEY_CAPSLOCK		58
+#define KEY_F1			59
+#define KEY_F2			60
+#define KEY_F3			61
+#define KEY_F4			62
+#define KEY_F5			63
+#define KEY_F6			64
+#define KEY_F7			65
+#define KEY_F8			66
+#define KEY_F9			67
+#define KEY_F10			68
+#define KEY_NUMLOCK		69
+#define KEY_SCROLLLOCK		70
+#define KEY_KP7			71
+#define KEY_KP8			72
+#define KEY_KP9			73
+#define KEY_KPMINUS		74
+#define KEY_KP4			75
+#define KEY_KP5			76
+#define KEY_KP6			77
+#define KEY_KPPLUS		78
+#define KEY_KP1			79
+#define KEY_KP2			80
+#define KEY_KP3			81
+#define KEY_KP0			82
+#define KEY_KPDOT		83
+
+#define KEY_ZENKAKUHANKAKU	85
+#define KEY_102ND		86
+#define KEY_F11			87
+#define KEY_F12			88
+#define KEY_RO			89
+#define KEY_KATAKANA		90
+#define KEY_HIRAGANA		91
+#define KEY_HENKAN		92
+#define KEY_KATAKANAHIRAGANA	93
+#define KEY_MUHENKAN		94
+#define KEY_KPJPCOMMA		95
+#define KEY_KPENTER		96
+#define KEY_RIGHTCTRL		97
+#define KEY_KPSLASH		98
+#define KEY_SYSRQ		99
+#define KEY_RIGHTALT		100
+#define KEY_LINEFEED		101
+#define KEY_HOME		102
+#define KEY_UP			103
+#define KEY_PAGEUP		104
+#define KEY_LEFT		105
+#define KEY_RIGHT		106
+#define KEY_END			107
+#define KEY_DOWN		108
+#define KEY_PAGEDOWN		109
+#define KEY_INSERT		110
+#define KEY_DELETE		111
+#define KEY_MACRO		112
+#define KEY_MUTE		113
+#define KEY_VOLUMEDOWN		114
+#define KEY_VOLUMEUP		115
+#define KEY_POWER		116	/* SC System Power Down */
+#define KEY_KPEQUAL		117
+#define KEY_KPPLUSMINUS		118
+#define KEY_PAUSE		119
+#define KEY_SCALE		120	/* AL Compiz Scale (Expose) */
+
+#define KEY_KPCOMMA		121
+#define KEY_HANGEUL		122
+#define KEY_HANGUEL		KEY_HANGEUL
+#define KEY_HANJA		123
+#define KEY_YEN			124
+#define KEY_LEFTMETA		125
+#define KEY_RIGHTMETA		126
+#define KEY_COMPOSE		127
+
+#define KEY_STOP		128	/* AC Stop */
+#define KEY_AGAIN		129
+#define KEY_PROPS		130	/* AC Properties */
+#define KEY_UNDO		131	/* AC Undo */
+#define KEY_FRONT		132
+#define KEY_COPY		133	/* AC Copy */
+#define KEY_OPEN		134	/* AC Open */
+#define KEY_PASTE		135	/* AC Paste */
+#define KEY_FIND		136	/* AC Search */
+#define KEY_CUT			137	/* AC Cut */
+#define KEY_HELP		138	/* AL Integrated Help Center */
+#define KEY_MENU		139	/* Menu (show menu) */
+#define KEY_CALC		140	/* AL Calculator */
+#define KEY_SETUP		141
+#define KEY_SLEEP		142	/* SC System Sleep */
+#define KEY_WAKEUP		143	/* System Wake Up */
+#define KEY_FILE		144	/* AL Local Machine Browser */
+#define KEY_SENDFILE		145
+#define KEY_DELETEFILE		146
+#define KEY_XFER		147
+#define KEY_PROG1		148
+#define KEY_PROG2		149
+#define KEY_WWW			150	/* AL Internet Browser */
+#define KEY_MSDOS		151
+#define KEY_COFFEE		152	/* AL Terminal Lock/Screensaver */
+#define KEY_SCREENLOCK		KEY_COFFEE
+#define KEY_ROTATE_DISPLAY	153	/* Display orientation for e.g. tablets */
+#define KEY_DIRECTION		KEY_ROTATE_DISPLAY
+#define KEY_CYCLEWINDOWS	154
+#define KEY_MAIL		155
+#define KEY_BOOKMARKS		156	/* AC Bookmarks */
+#define KEY_COMPUTER		157
+#define KEY_BACK		158	/* AC Back */
+#define KEY_FORWARD		159	/* AC Forward */
+#define KEY_CLOSECD		160
+#define KEY_EJECTCD		161
+#define KEY_EJECTCLOSECD	162
+#define KEY_NEXTSONG		163
+#define KEY_PLAYPAUSE		164
+#define KEY_PREVIOUSSONG	165
+#define KEY_STOPCD		166
+#define KEY_RECORD		167
+#define KEY_REWIND		168
+#define KEY_PHONE		169	/* Media Select Telephone */
+#define KEY_ISO			170
+#define KEY_CONFIG		171	/* AL Consumer Control Configuration */
+#define KEY_HOMEPAGE		172	/* AC Home */
+#define KEY_REFRESH		173	/* AC Refresh */
+#define KEY_EXIT		174	/* AC Exit */
+#define KEY_MOVE		175
+#define KEY_EDIT		176
+#define KEY_SCROLLUP		177
+#define KEY_SCROLLDOWN		178
+#define KEY_KPLEFTPAREN		179
+#define KEY_KPRIGHTPAREN	180
+#define KEY_NEW			181	/* AC New */
+#define KEY_REDO		182	/* AC Redo/Repeat */
+
+#define KEY_F13			183
+#define KEY_F14			184
+#define KEY_F15			185
+#define KEY_F16			186
+#define KEY_F17			187
+#define KEY_F18			188
+#define KEY_F19			189
+#define KEY_F20			190
+#define KEY_F21			191
+#define KEY_F22			192
+#define KEY_F23			193
+#define KEY_F24			194
+
+#define KEY_PLAYCD		200
+#define KEY_PAUSECD		201
+#define KEY_PROG3		202
+#define KEY_PROG4		203
+#define KEY_DASHBOARD		204	/* AL Dashboard */
+#define KEY_SUSPEND		205
+#define KEY_CLOSE		206	/* AC Close */
+#define KEY_PLAY		207
+#define KEY_FASTFORWARD		208
+#define KEY_BASSBOOST		209
+#define KEY_PRINT		210	/* AC Print */
+#define KEY_HP			211
+#define KEY_CAMERA		212
+#define KEY_SOUND		213
+#define KEY_QUESTION		214
+#define KEY_EMAIL		215
+#define KEY_CHAT		216
+#define KEY_SEARCH		217
+#define KEY_CONNECT		218
+#define KEY_FINANCE		219	/* AL Checkbook/Finance */
+#define KEY_SPORT		220
+#define KEY_SHOP		221
+#define KEY_ALTERASE		222
+#define KEY_CANCEL		223	/* AC Cancel */
+#define KEY_BRIGHTNESSDOWN	224
+#define KEY_BRIGHTNESSUP	225
+#define KEY_MEDIA		226
+
+#define KEY_SWITCHVIDEOMODE	227	/* Cycle between available video
+					   outputs (Monitor/LCD/TV-out/etc) */
+#define KEY_KBDILLUMTOGGLE	228
+#define KEY_KBDILLUMDOWN	229
+#define KEY_KBDILLUMUP		230
+
+#define KEY_SEND		231	/* AC Send */
+#define KEY_REPLY		232	/* AC Reply */
+#define KEY_FORWARDMAIL		233	/* AC Forward Msg */
+#define KEY_SAVE		234	/* AC Save */
+#define KEY_DOCUMENTS		235
+
+#define KEY_BATTERY		236
+
+#define KEY_BLUETOOTH		237
+#define KEY_WLAN		238
+#define KEY_UWB			239
+
+#define KEY_UNKNOWN		240
+
+#define KEY_VIDEO_NEXT		241	/* drive next video source */
+#define KEY_VIDEO_PREV		242	/* drive previous video source */
+#define KEY_BRIGHTNESS_CYCLE	243	/* brightness up, after max is min */
+#define KEY_BRIGHTNESS_AUTO	244	/* Set Auto Brightness: manual
+					  brightness control is off,
+					  rely on ambient */
+#define KEY_BRIGHTNESS_ZERO	KEY_BRIGHTNESS_AUTO
+#define KEY_DISPLAY_OFF		245	/* display device to off state */
+
+#define KEY_WWAN		246	/* Wireless WAN (LTE, UMTS, GSM, etc.) */
+#define KEY_WIMAX		KEY_WWAN
+#define KEY_RFKILL		247	/* Key that controls all radios */
+
+#define KEY_MICMUTE		248	/* Mute / unmute the microphone */
+
+/* Code 255 is reserved for special needs of AT keyboard driver */
+
+#define BTN_MISC		0x100
+#define BTN_0			0x100
+#define BTN_1			0x101
+#define BTN_2			0x102
+#define BTN_3			0x103
+#define BTN_4			0x104
+#define BTN_5			0x105
+#define BTN_6			0x106
+#define BTN_7			0x107
+#define BTN_8			0x108
+#define BTN_9			0x109
+
+#define BTN_MOUSE		0x110
+#define BTN_LEFT		0x110
+#define BTN_RIGHT		0x111
+#define BTN_MIDDLE		0x112
+#define BTN_SIDE		0x113
+#define BTN_EXTRA		0x114
+#define BTN_FORWARD		0x115
+#define BTN_BACK		0x116
+#define BTN_TASK		0x117
+
+#define BTN_JOYSTICK		0x120
+#define BTN_TRIGGER		0x120
+#define BTN_THUMB		0x121
+#define BTN_THUMB2		0x122
+#define BTN_TOP			0x123
+#define BTN_TOP2		0x124
+#define BTN_PINKIE		0x125
+#define BTN_BASE		0x126
+#define BTN_BASE2		0x127
+#define BTN_BASE3		0x128
+#define BTN_BASE4		0x129
+#define BTN_BASE5		0x12a
+#define BTN_BASE6		0x12b
+#define BTN_DEAD		0x12f
+
+#define BTN_GAMEPAD		0x130
+#define BTN_SOUTH		0x130
+#define BTN_A			BTN_SOUTH
+#define BTN_EAST		0x131
+#define BTN_B			BTN_EAST
+#define BTN_C			0x132
+#define BTN_NORTH		0x133
+#define BTN_X			BTN_NORTH
+#define BTN_WEST		0x134
+#define BTN_Y			BTN_WEST
+#define BTN_Z			0x135
+#define BTN_TL			0x136
+#define BTN_TR			0x137
+#define BTN_TL2			0x138
+#define BTN_TR2			0x139
+#define BTN_SELECT		0x13a
+#define BTN_START		0x13b
+#define BTN_MODE		0x13c
+#define BTN_THUMBL		0x13d
+#define BTN_THUMBR		0x13e
+
+#define BTN_DIGI		0x140
+#define BTN_TOOL_PEN		0x140
+#define BTN_TOOL_RUBBER		0x141
+#define BTN_TOOL_BRUSH		0x142
+#define BTN_TOOL_PENCIL		0x143
+#define BTN_TOOL_AIRBRUSH	0x144
+#define BTN_TOOL_FINGER		0x145
+#define BTN_TOOL_MOUSE		0x146
+#define BTN_TOOL_LENS		0x147
+#define BTN_TOOL_QUINTTAP	0x148	/* Five fingers on trackpad */
+#define BTN_STYLUS3		0x149
+#define BTN_TOUCH		0x14a
+#define BTN_STYLUS		0x14b
+#define BTN_STYLUS2		0x14c
+#define BTN_TOOL_DOUBLETAP	0x14d
+#define BTN_TOOL_TRIPLETAP	0x14e
+#define BTN_TOOL_QUADTAP	0x14f	/* Four fingers on trackpad */
+
+#define BTN_WHEEL		0x150
+#define BTN_GEAR_DOWN		0x150
+#define BTN_GEAR_UP		0x151
+
+#define KEY_OK			0x160
+#define KEY_SELECT		0x161
+#define KEY_GOTO		0x162
+#define KEY_CLEAR		0x163
+#define KEY_POWER2		0x164
+#define KEY_OPTION		0x165
+#define KEY_INFO		0x166	/* AL OEM Features/Tips/Tutorial */
+#define KEY_TIME		0x167
+#define KEY_VENDOR		0x168
+#define KEY_ARCHIVE		0x169
+#define KEY_PROGRAM		0x16a	/* Media Select Program Guide */
+#define KEY_CHANNEL		0x16b
+#define KEY_FAVORITES		0x16c
+#define KEY_EPG			0x16d
+#define KEY_PVR			0x16e	/* Media Select Home */
+#define KEY_MHP			0x16f
+#define KEY_LANGUAGE		0x170
+#define KEY_TITLE		0x171
+#define KEY_SUBTITLE		0x172
+#define KEY_ANGLE		0x173
+#define KEY_ZOOM		0x174
+#define KEY_MODE		0x175
+#define KEY_KEYBOARD		0x176
+#define KEY_SCREEN		0x177
+#define KEY_PC			0x178	/* Media Select Computer */
+#define KEY_TV			0x179	/* Media Select TV */
+#define KEY_TV2			0x17a	/* Media Select Cable */
+#define KEY_VCR			0x17b	/* Media Select VCR */
+#define KEY_VCR2		0x17c	/* VCR Plus */
+#define KEY_SAT			0x17d	/* Media Select Satellite */
+#define KEY_SAT2		0x17e
+#define KEY_CD			0x17f	/* Media Select CD */
+#define KEY_TAPE		0x180	/* Media Select Tape */
+#define KEY_RADIO		0x181
+#define KEY_TUNER		0x182	/* Media Select Tuner */
+#define KEY_PLAYER		0x183
+#define KEY_TEXT		0x184
+#define KEY_DVD			0x185	/* Media Select DVD */
+#define KEY_AUX			0x186
+#define KEY_MP3			0x187
+#define KEY_AUDIO		0x188	/* AL Audio Browser */
+#define KEY_VIDEO		0x189	/* AL Movie Browser */
+#define KEY_DIRECTORY		0x18a
+#define KEY_LIST		0x18b
+#define KEY_MEMO		0x18c	/* Media Select Messages */
+#define KEY_CALENDAR		0x18d
+#define KEY_RED			0x18e
+#define KEY_GREEN		0x18f
+#define KEY_YELLOW		0x190
+#define KEY_BLUE		0x191
+#define KEY_CHANNELUP		0x192	/* Channel Increment */
+#define KEY_CHANNELDOWN		0x193	/* Channel Decrement */
+#define KEY_FIRST		0x194
+#define KEY_LAST		0x195	/* Recall Last */
+#define KEY_AB			0x196
+#define KEY_NEXT		0x197
+#define KEY_RESTART		0x198
+#define KEY_SLOW		0x199
+#define KEY_SHUFFLE		0x19a
+#define KEY_BREAK		0x19b
+#define KEY_PREVIOUS		0x19c
+#define KEY_DIGITS		0x19d
+#define KEY_TEEN		0x19e
+#define KEY_TWEN		0x19f
+#define KEY_VIDEOPHONE		0x1a0	/* Media Select Video Phone */
+#define KEY_GAMES		0x1a1	/* Media Select Games */
+#define KEY_ZOOMIN		0x1a2	/* AC Zoom In */
+#define KEY_ZOOMOUT		0x1a3	/* AC Zoom Out */
+#define KEY_ZOOMRESET		0x1a4	/* AC Zoom */
+#define KEY_WORDPROCESSOR	0x1a5	/* AL Word Processor */
+#define KEY_EDITOR		0x1a6	/* AL Text Editor */
+#define KEY_SPREADSHEET		0x1a7	/* AL Spreadsheet */
+#define KEY_GRAPHICSEDITOR	0x1a8	/* AL Graphics Editor */
+#define KEY_PRESENTATION	0x1a9	/* AL Presentation App */
+#define KEY_DATABASE		0x1aa	/* AL Database App */
+#define KEY_NEWS		0x1ab	/* AL Newsreader */
+#define KEY_VOICEMAIL		0x1ac	/* AL Voicemail */
+#define KEY_ADDRESSBOOK		0x1ad	/* AL Contacts/Address Book */
+#define KEY_MESSENGER		0x1ae	/* AL Instant Messaging */
+#define KEY_DISPLAYTOGGLE	0x1af	/* Turn display (LCD) on and off */
+#define KEY_BRIGHTNESS_TOGGLE	KEY_DISPLAYTOGGLE
+#define KEY_SPELLCHECK		0x1b0   /* AL Spell Check */
+#define KEY_LOGOFF		0x1b1   /* AL Logoff */
+
+#define KEY_DOLLAR		0x1b2
+#define KEY_EURO		0x1b3
+
+#define KEY_FRAMEBACK		0x1b4	/* Consumer - transport controls */
+#define KEY_FRAMEFORWARD	0x1b5
+#define KEY_CONTEXT_MENU	0x1b6	/* GenDesc - system context menu */
+#define KEY_MEDIA_REPEAT	0x1b7	/* Consumer - transport control */
+#define KEY_10CHANNELSUP	0x1b8	/* 10 channels up (10+) */
+#define KEY_10CHANNELSDOWN	0x1b9	/* 10 channels down (10-) */
+#define KEY_IMAGES		0x1ba	/* AL Image Browser */
+
+#define KEY_DEL_EOL		0x1c0
+#define KEY_DEL_EOS		0x1c1
+#define KEY_INS_LINE		0x1c2
+#define KEY_DEL_LINE		0x1c3
+
+#define KEY_FN			0x1d0
+#define KEY_FN_ESC		0x1d1
+#define KEY_FN_F1		0x1d2
+#define KEY_FN_F2		0x1d3
+#define KEY_FN_F3		0x1d4
+#define KEY_FN_F4		0x1d5
+#define KEY_FN_F5		0x1d6
+#define KEY_FN_F6		0x1d7
+#define KEY_FN_F7		0x1d8
+#define KEY_FN_F8		0x1d9
+#define KEY_FN_F9		0x1da
+#define KEY_FN_F10		0x1db
+#define KEY_FN_F11		0x1dc
+#define KEY_FN_F12		0x1dd
+#define KEY_FN_1		0x1de
+#define KEY_FN_2		0x1df
+#define KEY_FN_D		0x1e0
+#define KEY_FN_E		0x1e1
+#define KEY_FN_F		0x1e2
+#define KEY_FN_S		0x1e3
+#define KEY_FN_B		0x1e4
+
+#define KEY_BRL_DOT1		0x1f1
+#define KEY_BRL_DOT2		0x1f2
+#define KEY_BRL_DOT3		0x1f3
+#define KEY_BRL_DOT4		0x1f4
+#define KEY_BRL_DOT5		0x1f5
+#define KEY_BRL_DOT6		0x1f6
+#define KEY_BRL_DOT7		0x1f7
+#define KEY_BRL_DOT8		0x1f8
+#define KEY_BRL_DOT9		0x1f9
+#define KEY_BRL_DOT10		0x1fa
+
+#define KEY_NUMERIC_0		0x200	/* used by phones, remote controls, */
+#define KEY_NUMERIC_1		0x201	/* and other keypads */
+#define KEY_NUMERIC_2		0x202
+#define KEY_NUMERIC_3		0x203
+#define KEY_NUMERIC_4		0x204
+#define KEY_NUMERIC_5		0x205
+#define KEY_NUMERIC_6		0x206
+#define KEY_NUMERIC_7		0x207
+#define KEY_NUMERIC_8		0x208
+#define KEY_NUMERIC_9		0x209
+#define KEY_NUMERIC_STAR	0x20a
+#define KEY_NUMERIC_POUND	0x20b
+#define KEY_NUMERIC_A		0x20c	/* Phone key A - HUT Telephony 0xb9 */
+#define KEY_NUMERIC_B		0x20d
+#define KEY_NUMERIC_C		0x20e
+#define KEY_NUMERIC_D		0x20f
+
+#define KEY_CAMERA_FOCUS	0x210
+#define KEY_WPS_BUTTON		0x211	/* WiFi Protected Setup key */
+
+#define KEY_TOUCHPAD_TOGGLE	0x212	/* Request switch touchpad on or off */
+#define KEY_TOUCHPAD_ON		0x213
+#define KEY_TOUCHPAD_OFF	0x214
+
+#define KEY_CAMERA_ZOOMIN	0x215
+#define KEY_CAMERA_ZOOMOUT	0x216
+#define KEY_CAMERA_UP		0x217
+#define KEY_CAMERA_DOWN		0x218
+#define KEY_CAMERA_LEFT		0x219
+#define KEY_CAMERA_RIGHT	0x21a
+
+#define KEY_ATTENDANT_ON	0x21b
+#define KEY_ATTENDANT_OFF	0x21c
+#define KEY_ATTENDANT_TOGGLE	0x21d	/* Attendant call on or off */
+#define KEY_LIGHTS_TOGGLE	0x21e	/* Reading light on or off */
+
+#define BTN_DPAD_UP		0x220
+#define BTN_DPAD_DOWN		0x221
+#define BTN_DPAD_LEFT		0x222
+#define BTN_DPAD_RIGHT		0x223
+
+#define KEY_ALS_TOGGLE		0x230	/* Ambient light sensor */
+#define KEY_ROTATE_LOCK_TOGGLE	0x231	/* Display rotation lock */
+
+#define KEY_BUTTONCONFIG		0x240	/* AL Button Configuration */
+#define KEY_TASKMANAGER		0x241	/* AL Task/Project Manager */
+#define KEY_JOURNAL		0x242	/* AL Log/Journal/Timecard */
+#define KEY_CONTROLPANEL		0x243	/* AL Control Panel */
+#define KEY_APPSELECT		0x244	/* AL Select Task/Application */
+#define KEY_SCREENSAVER		0x245	/* AL Screen Saver */
+#define KEY_VOICECOMMAND		0x246	/* Listening Voice Command */
+#define KEY_ASSISTANT		0x247	/* AL Context-aware desktop assistant */
+
+#define KEY_BRIGHTNESS_MIN		0x250	/* Set Brightness to Minimum */
+#define KEY_BRIGHTNESS_MAX		0x251	/* Set Brightness to Maximum */
+
+#define KEY_KBDINPUTASSIST_PREV		0x260
+#define KEY_KBDINPUTASSIST_NEXT		0x261
+#define KEY_KBDINPUTASSIST_PREVGROUP		0x262
+#define KEY_KBDINPUTASSIST_NEXTGROUP		0x263
+#define KEY_KBDINPUTASSIST_ACCEPT		0x264
+#define KEY_KBDINPUTASSIST_CANCEL		0x265
+
+/* Diagonal movement keys */
+#define KEY_RIGHT_UP			0x266
+#define KEY_RIGHT_DOWN			0x267
+#define KEY_LEFT_UP			0x268
+#define KEY_LEFT_DOWN			0x269
+
+#define KEY_ROOT_MENU			0x26a /* Show Device's Root Menu */
+/* Show Top Menu of the Media (e.g. DVD) */
+#define KEY_MEDIA_TOP_MENU		0x26b
+#define KEY_NUMERIC_11			0x26c
+#define KEY_NUMERIC_12			0x26d
+/*
+ * Toggle Audio Description: refers to an audio service that helps blind and
+ * visually impaired consumers understand the action in a program. Note: in
+ * some countries this is referred to as "Video Description".
+ */
+#define KEY_AUDIO_DESC			0x26e
+#define KEY_3D_MODE			0x26f
+#define KEY_NEXT_FAVORITE		0x270
+#define KEY_STOP_RECORD			0x271
+#define KEY_PAUSE_RECORD		0x272
+#define KEY_VOD				0x273 /* Video on Demand */
+#define KEY_UNMUTE			0x274
+#define KEY_FASTREVERSE			0x275
+#define KEY_SLOWREVERSE			0x276
+/*
+ * Control a data application associated with the currently viewed channel,
+ * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
+ */
+#define KEY_DATA			0x277
+#define KEY_ONSCREEN_KEYBOARD		0x278
+
+#define BTN_TRIGGER_HAPPY		0x2c0
+#define BTN_TRIGGER_HAPPY1		0x2c0
+#define BTN_TRIGGER_HAPPY2		0x2c1
+#define BTN_TRIGGER_HAPPY3		0x2c2
+#define BTN_TRIGGER_HAPPY4		0x2c3
+#define BTN_TRIGGER_HAPPY5		0x2c4
+#define BTN_TRIGGER_HAPPY6		0x2c5
+#define BTN_TRIGGER_HAPPY7		0x2c6
+#define BTN_TRIGGER_HAPPY8		0x2c7
+#define BTN_TRIGGER_HAPPY9		0x2c8
+#define BTN_TRIGGER_HAPPY10		0x2c9
+#define BTN_TRIGGER_HAPPY11		0x2ca
+#define BTN_TRIGGER_HAPPY12		0x2cb
+#define BTN_TRIGGER_HAPPY13		0x2cc
+#define BTN_TRIGGER_HAPPY14		0x2cd
+#define BTN_TRIGGER_HAPPY15		0x2ce
+#define BTN_TRIGGER_HAPPY16		0x2cf
+#define BTN_TRIGGER_HAPPY17		0x2d0
+#define BTN_TRIGGER_HAPPY18		0x2d1
+#define BTN_TRIGGER_HAPPY19		0x2d2
+#define BTN_TRIGGER_HAPPY20		0x2d3
+#define BTN_TRIGGER_HAPPY21		0x2d4
+#define BTN_TRIGGER_HAPPY22		0x2d5
+#define BTN_TRIGGER_HAPPY23		0x2d6
+#define BTN_TRIGGER_HAPPY24		0x2d7
+#define BTN_TRIGGER_HAPPY25		0x2d8
+#define BTN_TRIGGER_HAPPY26		0x2d9
+#define BTN_TRIGGER_HAPPY27		0x2da
+#define BTN_TRIGGER_HAPPY28		0x2db
+#define BTN_TRIGGER_HAPPY29		0x2dc
+#define BTN_TRIGGER_HAPPY30		0x2dd
+#define BTN_TRIGGER_HAPPY31		0x2de
+#define BTN_TRIGGER_HAPPY32		0x2df
+#define BTN_TRIGGER_HAPPY33		0x2e0
+#define BTN_TRIGGER_HAPPY34		0x2e1
+#define BTN_TRIGGER_HAPPY35		0x2e2
+#define BTN_TRIGGER_HAPPY36		0x2e3
+#define BTN_TRIGGER_HAPPY37		0x2e4
+#define BTN_TRIGGER_HAPPY38		0x2e5
+#define BTN_TRIGGER_HAPPY39		0x2e6
+#define BTN_TRIGGER_HAPPY40		0x2e7
+
+/* We avoid low common keys in module aliases so they don't get huge. */
+#define KEY_MIN_INTERESTING	KEY_MUTE
+#define KEY_MAX			0x2ff
+#define KEY_CNT			(KEY_MAX+1)
+
+/*
+ * Relative axes
+ */
+
+#define REL_X			0x00
+#define REL_Y			0x01
+#define REL_Z			0x02
+#define REL_RX			0x03
+#define REL_RY			0x04
+#define REL_RZ			0x05
+#define REL_HWHEEL		0x06
+#define REL_DIAL		0x07
+#define REL_WHEEL		0x08
+#define REL_MISC		0x09
+#define REL_MAX			0x0f
+#define REL_CNT			(REL_MAX+1)
+
+/*
+ * Absolute axes
+ */
+
+#define ABS_X			0x00
+#define ABS_Y			0x01
+#define ABS_Z			0x02
+#define ABS_RX			0x03
+#define ABS_RY			0x04
+#define ABS_RZ			0x05
+#define ABS_THROTTLE		0x06
+#define ABS_RUDDER		0x07
+#define ABS_WHEEL		0x08
+#define ABS_GAS			0x09
+#define ABS_BRAKE		0x0a
+#define ABS_HAT0X		0x10
+#define ABS_HAT0Y		0x11
+#define ABS_HAT1X		0x12
+#define ABS_HAT1Y		0x13
+#define ABS_HAT2X		0x14
+#define ABS_HAT2Y		0x15
+#define ABS_HAT3X		0x16
+#define ABS_HAT3Y		0x17
+#define ABS_PRESSURE		0x18
+#define ABS_DISTANCE		0x19
+#define ABS_TILT_X		0x1a
+#define ABS_TILT_Y		0x1b
+#define ABS_TOOL_WIDTH		0x1c
+
+#define ABS_VOLUME		0x20
+
+#define ABS_MISC		0x28
+
+/*
+ * 0x2e is reserved and should not be used in input drivers.
+ * It was used by HID as ABS_MISC+6 and userspace needs to detect if
+ * the next ABS_* event is correct or is just ABS_MISC + n.
+ * We define here ABS_RESERVED so userspace can rely on it and detect
+ * the situation described above.
+ */
+#define ABS_RESERVED		0x2e
+
+#define ABS_MT_SLOT		0x2f	/* MT slot being modified */
+#define ABS_MT_TOUCH_MAJOR	0x30	/* Major axis of touching ellipse */
+#define ABS_MT_TOUCH_MINOR	0x31	/* Minor axis (omit if circular) */
+#define ABS_MT_WIDTH_MAJOR	0x32	/* Major axis of approaching ellipse */
+#define ABS_MT_WIDTH_MINOR	0x33	/* Minor axis (omit if circular) */
+#define ABS_MT_ORIENTATION	0x34	/* Ellipse orientation */
+#define ABS_MT_POSITION_X	0x35	/* Center X touch position */
+#define ABS_MT_POSITION_Y	0x36	/* Center Y touch position */
+#define ABS_MT_TOOL_TYPE	0x37	/* Type of touching device */
+#define ABS_MT_BLOB_ID		0x38	/* Group a set of packets as a blob */
+#define ABS_MT_TRACKING_ID	0x39	/* Unique ID of initiated contact */
+#define ABS_MT_PRESSURE		0x3a	/* Pressure on contact area */
+#define ABS_MT_DISTANCE		0x3b	/* Contact hover distance */
+#define ABS_MT_TOOL_X		0x3c	/* Center X tool position */
+#define ABS_MT_TOOL_Y		0x3d	/* Center Y tool position */
+
+
+#define ABS_MAX			0x3f
+#define ABS_CNT			(ABS_MAX+1)
+
+/*
+ * Switch events
+ */
+
+#define SW_LID			0x00  /* set = lid shut */
+#define SW_TABLET_MODE		0x01  /* set = tablet mode */
+#define SW_HEADPHONE_INSERT	0x02  /* set = inserted */
+#define SW_RFKILL_ALL		0x03  /* rfkill master switch, type "any"
+					 set = radio enabled */
+#define SW_RADIO		SW_RFKILL_ALL	/* deprecated */
+#define SW_MICROPHONE_INSERT	0x04  /* set = inserted */
+#define SW_DOCK			0x05  /* set = plugged into dock */
+#define SW_LINEOUT_INSERT	0x06  /* set = inserted */
+#define SW_JACK_PHYSICAL_INSERT 0x07  /* set = mechanical switch set */
+#define SW_VIDEOOUT_INSERT	0x08  /* set = inserted */
+#define SW_CAMERA_LENS_COVER	0x09  /* set = lens covered */
+#define SW_KEYPAD_SLIDE		0x0a  /* set = keypad slide out */
+#define SW_FRONT_PROXIMITY	0x0b  /* set = front proximity sensor active */
+#define SW_ROTATE_LOCK		0x0c  /* set = rotate locked/disabled */
+#define SW_LINEIN_INSERT	0x0d  /* set = inserted */
+#define SW_MUTE_DEVICE		0x0e  /* set = device disabled */
+#define SW_PEN_INSERTED		0x0f  /* set = pen inserted */
+#define SW_MAX			0x0f
+#define SW_CNT			(SW_MAX+1)
+
+/*
+ * Misc events
+ */
+
+#define MSC_SERIAL		0x00
+#define MSC_PULSELED		0x01
+#define MSC_GESTURE		0x02
+#define MSC_RAW			0x03
+#define MSC_SCAN		0x04
+#define MSC_TIMESTAMP		0x05
+#define MSC_MAX			0x07
+#define MSC_CNT			(MSC_MAX+1)
+
+/*
+ * LEDs
+ */
+
+#define LED_NUML		0x00
+#define LED_CAPSL		0x01
+#define LED_SCROLLL		0x02
+#define LED_COMPOSE		0x03
+#define LED_KANA		0x04
+#define LED_SLEEP		0x05
+#define LED_SUSPEND		0x06
+#define LED_MUTE		0x07
+#define LED_MISC		0x08
+#define LED_MAIL		0x09
+#define LED_CHARGING		0x0a
+#define LED_MAX			0x0f
+#define LED_CNT			(LED_MAX+1)
+
+/*
+ * Autorepeat values
+ */
+
+#define REP_DELAY		0x00
+#define REP_PERIOD		0x01
+#define REP_MAX			0x01
+#define REP_CNT			(REP_MAX+1)
+
+/*
+ * Sounds
+ */
+
+#define SND_CLICK		0x00
+#define SND_BELL		0x01
+#define SND_TONE		0x02
+#define SND_MAX			0x07
+#define SND_CNT			(SND_MAX+1)
+
+#endif
diff --git a/src/kernel/linux/v4.19/init/do_mounts_dm.c b/src/kernel/linux/v4.19/init/do_mounts_dm.c
index 6df0b4c..5041a9a 100644
--- a/src/kernel/linux/v4.19/init/do_mounts_dm.c
+++ b/src/kernel/linux/v4.19/init/do_mounts_dm.c
@@ -397,7 +397,6 @@
 	fmode_t fmode = FMODE_READ;
 	struct dm_device *devices;
 	int ret;
-
 	devices = dm_parse_args();
 
 	for (dev = devices; dev; dev = dev->next) {
diff --git a/src/kernel/linux/v4.19/net/wireless/rdev-ops.h b/src/kernel/linux/v4.19/net/wireless/rdev-ops.h
index 33999c4..4cff76f 100644
--- a/src/kernel/linux/v4.19/net/wireless/rdev-ops.h
+++ b/src/kernel/linux/v4.19/net/wireless/rdev-ops.h
@@ -1222,7 +1222,7 @@
 	return ret;
 }
 
-static inline int 
+static inline int
 rdev_external_auth(struct cfg80211_registered_device *rdev,
 		   struct net_device *dev,
 		   struct cfg80211_external_auth_params *params)
diff --git a/src/kernel/linux/v4.19/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/src/kernel/linux/v4.19/sound/soc/mediatek/common/mtk-afe-platform-driver.c
index cca4bf2..a784ee5 100755
--- a/src/kernel/linux/v4.19/sound/soc/mediatek/common/mtk-afe-platform-driver.c
+++ b/src/kernel/linux/v4.19/sound/soc/mediatek/common/mtk-afe-platform-driver.c
@@ -93,75 +93,45 @@
 static snd_pcm_uframes_t mtk_afe_pcm_pointer
 			 (struct snd_pcm_substream *substream)
 {
-	struct snd_soc_pcm_runtime *rtd;
-	struct snd_soc_component *component;
-    struct mtk_base_afe *afe;
-    struct mtk_base_afe_memif *memif;
-    const struct mtk_base_memif_data *memif_data;
-    struct regmap *regmap;
-    struct device *dev;
-    int reg_ofs_base;
-    int reg_ofs_cur;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct mtk_base_afe *afe;
+	struct mtk_base_afe_memif *memif = NULL;
+	const struct mtk_base_memif_data *memif_data;
+	struct regmap *regmap;
+	struct device *dev;
+	int reg_ofs_base;
+	int reg_ofs_cur;
 	unsigned int hw_ptr = 0, hw_base = 0;
 	int ret, pcm_ptr_bytes;
 
-    if(substream == NULL)
-    {
-        dev_err(NULL, "%s substream is NULL\n", __func__);
-        return -EINVAL;
-    }
+	if (component == NULL)
+		return -EINVAL;
+	afe = snd_soc_component_get_drvdata(component);
+	if (afe == NULL)
+		return -EINVAL;
+	dev = afe->dev;
 
-    rtd = substream->private_data;
+	if (rtd->cpu_dai->id >= 0 && rtd->cpu_dai->id < afe->memif_size) {
+		memif = &afe->memif[rtd->cpu_dai->id];
+	}
+	if (memif == NULL) {
+		dev_err(dev, "%s memif NULL\n", __func__);
+		return -EINVAL;
+	}
+	memif_data = memif->data;
+	if (memif_data == NULL) {
+		dev_err(dev, "%s memif_data NULL\n", __func__);
+		return -EINVAL;
+	}
+	regmap = afe->regmap;
+	if (regmap == NULL) {
+		dev_err(dev, "%s regmap NULL\n", __func__);
+		return -EINVAL;
+	}
 
-    if(rtd == NULL)
-    {
-        dev_err(NULL, "%s rtd is NULL\n", __func__);
-        return -EINVAL;
-    }
-
-    component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
-
-    if (component == NULL) {
-      dev_err(NULL, "%s component NULL\n", __func__);
-      return -EINVAL;
-    }
-    afe = snd_soc_component_get_drvdata(component);
-    if (afe == NULL) {
-        dev_err(NULL, "%s afe NULL\n", __func__);
-        return -EINVAL;
-    }
-
-    dev = afe->dev;
-    if(dev == NULL){
-        dev_err(NULL, "%s dev is NULL\n", __func__);
-      //  return -EINVAL;
-    }
-
-    if (rtd->cpu_dai->id >= 0 && rtd->cpu_dai->id < afe->memif_size) {
-        memif = &afe->memif[rtd->cpu_dai->id];
-    }
-    else {
-       dev_err(dev, "%s rtd->cpu_dai->id %d is error\n", __func__ , rtd->cpu_dai->id);
-       return -EINVAL;
-    }
-    memif = &afe->memif[rtd->cpu_dai->id];
-    if (memif == NULL) {
-        dev_err(dev, "%s memif NULL\n", __func__);
-        return -EINVAL;
-    }
-    memif_data = memif->data;
-    if (memif_data == NULL) {
-        dev_err(dev, "%s memif_data NULL\n", __func__);
-        return -EINVAL;
-    }
-    regmap = afe->regmap;
-    if (regmap == NULL) {
-        dev_err(dev, "%s regmap 2 NULL\n", __func__);
-        return -EINVAL;
-    }
-   
-    reg_ofs_base = memif_data->reg_ofs_base;
-    reg_ofs_cur = memif_data->reg_ofs_cur;
+	reg_ofs_base = memif_data->reg_ofs_base;
+	reg_ofs_cur = memif_data->reg_ofs_cur;
 
 	ret = regmap_read(regmap, reg_ofs_cur, &hw_ptr);
 	if (ret || hw_ptr == 0) {
@@ -179,11 +149,6 @@
 
 	pcm_ptr_bytes = hw_ptr - hw_base;
 
-    if(pcm_ptr_bytes <0)
-    {
-        dev_err(dev, "%s pcm_ptr_bytes < 0 hw_ptr is %d, hw_base is %d \n", __func__ , hw_ptr, hw_base);
-    }
-
 POINTER_RETURN_FRAMES:
 	pcm_ptr_bytes = word_size_align(pcm_ptr_bytes);
 	return bytes_to_frames(substream->runtime, pcm_ptr_bytes);
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_64.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_64.S
deleted file mode 120000
index f1c418a..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_64.S
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/lib/copyuser_64.S
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_64.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_64.S
new file mode 100644
index 0000000..96c514b
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_64.S
@@ -0,0 +1,568 @@
+/*
+ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+ *
+ * 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.
+ */
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/export.h>
+#include <asm/asm-compat.h>
+#include <asm/feature-fixups.h>
+
+#ifndef SELFTEST_CASE
+/* 0 == most CPUs, 1 == POWER6, 2 == Cell */
+#define SELFTEST_CASE	0
+#endif
+
+#ifdef __BIG_ENDIAN__
+#define sLd sld		/* Shift towards low-numbered address. */
+#define sHd srd		/* Shift towards high-numbered address. */
+#else
+#define sLd srd		/* Shift towards low-numbered address. */
+#define sHd sld		/* Shift towards high-numbered address. */
+#endif
+
+/*
+ * These macros are used to generate exception table entries.
+ * The exception handlers below use the original arguments
+ * (stored on the stack) and the point where we're up to in
+ * the destination buffer, i.e. the address of the first
+ * unmodified byte.  Generally r3 points into the destination
+ * buffer, but the first unmodified byte is at a variable
+ * offset from r3.  In the code below, the symbol r3_offset
+ * is set to indicate the current offset at each point in
+ * the code.  This offset is then used as a negative offset
+ * from the exception handler code, and those instructions
+ * before the exception handlers are addi instructions that
+ * adjust r3 to point to the correct place.
+ */
+	.macro	lex		/* exception handler for load */
+100:	EX_TABLE(100b, .Lld_exc - r3_offset)
+	.endm
+
+	.macro	stex		/* exception handler for store */
+100:	EX_TABLE(100b, .Lst_exc - r3_offset)
+	.endm
+
+	.align	7
+_GLOBAL_TOC(__copy_tofrom_user)
+#ifdef CONFIG_PPC_BOOK3S_64
+BEGIN_FTR_SECTION
+	nop
+FTR_SECTION_ELSE
+	b	__copy_tofrom_user_power7
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
+#endif
+_GLOBAL(__copy_tofrom_user_base)
+	/* first check for a 4kB copy on a 4kB boundary */
+	cmpldi	cr1,r5,16
+	cmpdi	cr6,r5,4096
+	or	r0,r3,r4
+	neg	r6,r3		/* LS 3 bits = # bytes to 8-byte dest bdry */
+	andi.	r0,r0,4095
+	std	r3,-24(r1)
+	crand	cr0*4+2,cr0*4+2,cr6*4+2
+	std	r4,-16(r1)
+	std	r5,-8(r1)
+	dcbt	0,r4
+	beq	.Lcopy_page_4K
+	andi.	r6,r6,7
+	PPC_MTOCRF(0x01,r5)
+	blt	cr1,.Lshort_copy
+/* Below we want to nop out the bne if we're on a CPU that has the
+ * CPU_FTR_UNALIGNED_LD_STD bit set and the CPU_FTR_CP_USE_DCBTZ bit
+ * cleared.
+ * At the time of writing the only CPU that has this combination of bits
+ * set is Power6.
+ */
+test_feature = (SELFTEST_CASE == 1)
+BEGIN_FTR_SECTION
+	nop
+FTR_SECTION_ELSE
+	bne	.Ldst_unaligned
+ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \
+		    CPU_FTR_UNALIGNED_LD_STD)
+.Ldst_aligned:
+	addi	r3,r3,-16
+r3_offset = 16
+test_feature = (SELFTEST_CASE == 0)
+BEGIN_FTR_SECTION
+	andi.	r0,r4,7
+	bne	.Lsrc_unaligned
+END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
+	blt	cr1,.Ldo_tail		/* if < 16 bytes to copy */
+	srdi	r0,r5,5
+	cmpdi	cr1,r0,0
+lex;	ld	r7,0(r4)
+lex;	ld	r6,8(r4)
+	addi	r4,r4,16
+	mtctr	r0
+	andi.	r0,r5,0x10
+	beq	22f
+	addi	r3,r3,16
+r3_offset = 0
+	addi	r4,r4,-16
+	mr	r9,r7
+	mr	r8,r6
+	beq	cr1,72f
+21:
+lex;	ld	r7,16(r4)
+lex;	ld	r6,24(r4)
+	addi	r4,r4,32
+stex;	std	r9,0(r3)
+r3_offset = 8
+stex;	std	r8,8(r3)
+r3_offset = 16
+22:
+lex;	ld	r9,0(r4)
+lex;	ld	r8,8(r4)
+stex;	std	r7,16(r3)
+r3_offset = 24
+stex;	std	r6,24(r3)
+	addi	r3,r3,32
+r3_offset = 0
+	bdnz	21b
+72:
+stex;	std	r9,0(r3)
+r3_offset = 8
+stex;	std	r8,8(r3)
+r3_offset = 16
+	andi.	r5,r5,0xf
+	beq+	3f
+	addi	r4,r4,16
+.Ldo_tail:
+	addi	r3,r3,16
+r3_offset = 0
+	bf	cr7*4+0,246f
+lex;	ld	r9,0(r4)
+	addi	r4,r4,8
+stex;	std	r9,0(r3)
+	addi	r3,r3,8
+246:	bf	cr7*4+1,1f
+lex;	lwz	r9,0(r4)
+	addi	r4,r4,4
+stex;	stw	r9,0(r3)
+	addi	r3,r3,4
+1:	bf	cr7*4+2,2f
+lex;	lhz	r9,0(r4)
+	addi	r4,r4,2
+stex;	sth	r9,0(r3)
+	addi	r3,r3,2
+2:	bf	cr7*4+3,3f
+lex;	lbz	r9,0(r4)
+stex;	stb	r9,0(r3)
+3:	li	r3,0
+	blr
+
+.Lsrc_unaligned:
+r3_offset = 16
+	srdi	r6,r5,3
+	addi	r5,r5,-16
+	subf	r4,r0,r4
+	srdi	r7,r5,4
+	sldi	r10,r0,3
+	cmpldi	cr6,r6,3
+	andi.	r5,r5,7
+	mtctr	r7
+	subfic	r11,r10,64
+	add	r5,r5,r0
+	bt	cr7*4+0,28f
+
+lex;	ld	r9,0(r4)	/* 3+2n loads, 2+2n stores */
+lex;	ld	r0,8(r4)
+	sLd	r6,r9,r10
+lex;	ldu	r9,16(r4)
+	sHd	r7,r0,r11
+	sLd	r8,r0,r10
+	or	r7,r7,r6
+	blt	cr6,79f
+lex;	ld	r0,8(r4)
+	b	2f
+
+28:
+lex;	ld	r0,0(r4)	/* 4+2n loads, 3+2n stores */
+lex;	ldu	r9,8(r4)
+	sLd	r8,r0,r10
+	addi	r3,r3,-8
+r3_offset = 24
+	blt	cr6,5f
+lex;	ld	r0,8(r4)
+	sHd	r12,r9,r11
+	sLd	r6,r9,r10
+lex;	ldu	r9,16(r4)
+	or	r12,r8,r12
+	sHd	r7,r0,r11
+	sLd	r8,r0,r10
+	addi	r3,r3,16
+r3_offset = 8
+	beq	cr6,78f
+
+1:	or	r7,r7,r6
+lex;	ld	r0,8(r4)
+stex;	std	r12,8(r3)
+r3_offset = 16
+2:	sHd	r12,r9,r11
+	sLd	r6,r9,r10
+lex;	ldu	r9,16(r4)
+	or	r12,r8,r12
+stex;	stdu	r7,16(r3)
+r3_offset = 8
+	sHd	r7,r0,r11
+	sLd	r8,r0,r10
+	bdnz	1b
+
+78:
+stex;	std	r12,8(r3)
+r3_offset = 16
+	or	r7,r7,r6
+79:
+stex;	std	r7,16(r3)
+r3_offset = 24
+5:	sHd	r12,r9,r11
+	or	r12,r8,r12
+stex;	std	r12,24(r3)
+r3_offset = 32
+	bne	6f
+	li	r3,0
+	blr
+6:	cmpwi	cr1,r5,8
+	addi	r3,r3,32
+r3_offset = 0
+	sLd	r9,r9,r10
+	ble	cr1,7f
+lex;	ld	r0,8(r4)
+	sHd	r7,r0,r11
+	or	r9,r7,r9
+7:
+	bf	cr7*4+1,1f
+#ifdef __BIG_ENDIAN__
+	rotldi	r9,r9,32
+#endif
+stex;	stw	r9,0(r3)
+#ifdef __LITTLE_ENDIAN__
+	rotrdi	r9,r9,32
+#endif
+	addi	r3,r3,4
+1:	bf	cr7*4+2,2f
+#ifdef __BIG_ENDIAN__
+	rotldi	r9,r9,16
+#endif
+stex;	sth	r9,0(r3)
+#ifdef __LITTLE_ENDIAN__
+	rotrdi	r9,r9,16
+#endif
+	addi	r3,r3,2
+2:	bf	cr7*4+3,3f
+#ifdef __BIG_ENDIAN__
+	rotldi	r9,r9,8
+#endif
+stex;	stb	r9,0(r3)
+#ifdef __LITTLE_ENDIAN__
+	rotrdi	r9,r9,8
+#endif
+3:	li	r3,0
+	blr
+
+.Ldst_unaligned:
+r3_offset = 0
+	PPC_MTOCRF(0x01,r6)		/* put #bytes to 8B bdry into cr7 */
+	subf	r5,r6,r5
+	li	r7,0
+	cmpldi	cr1,r5,16
+	bf	cr7*4+3,1f
+100:	EX_TABLE(100b, .Lld_exc_r7)
+	lbz	r0,0(r4)
+100:	EX_TABLE(100b, .Lst_exc_r7)
+	stb	r0,0(r3)
+	addi	r7,r7,1
+1:	bf	cr7*4+2,2f
+100:	EX_TABLE(100b, .Lld_exc_r7)
+	lhzx	r0,r7,r4
+100:	EX_TABLE(100b, .Lst_exc_r7)
+	sthx	r0,r7,r3
+	addi	r7,r7,2
+2:	bf	cr7*4+1,3f
+100:	EX_TABLE(100b, .Lld_exc_r7)
+	lwzx	r0,r7,r4
+100:	EX_TABLE(100b, .Lst_exc_r7)
+	stwx	r0,r7,r3
+3:	PPC_MTOCRF(0x01,r5)
+	add	r4,r6,r4
+	add	r3,r6,r3
+	b	.Ldst_aligned
+
+.Lshort_copy:
+r3_offset = 0
+	bf	cr7*4+0,1f
+lex;	lwz	r0,0(r4)
+lex;	lwz	r9,4(r4)
+	addi	r4,r4,8
+stex;	stw	r0,0(r3)
+stex;	stw	r9,4(r3)
+	addi	r3,r3,8
+1:	bf	cr7*4+1,2f
+lex;	lwz	r0,0(r4)
+	addi	r4,r4,4
+stex;	stw	r0,0(r3)
+	addi	r3,r3,4
+2:	bf	cr7*4+2,3f
+lex;	lhz	r0,0(r4)
+	addi	r4,r4,2
+stex;	sth	r0,0(r3)
+	addi	r3,r3,2
+3:	bf	cr7*4+3,4f
+lex;	lbz	r0,0(r4)
+stex;	stb	r0,0(r3)
+4:	li	r3,0
+	blr
+
+/*
+ * exception handlers follow
+ * we have to return the number of bytes not copied
+ * for an exception on a load, we set the rest of the destination to 0
+ * Note that the number of bytes of instructions for adjusting r3 needs
+ * to equal the amount of the adjustment, due to the trick of using
+ * .Lld_exc - r3_offset as the handler address.
+ */
+
+.Lld_exc_r7:
+	add	r3,r3,r7
+	b	.Lld_exc
+
+	/* adjust by 24 */
+	addi	r3,r3,8
+	nop
+	/* adjust by 16 */
+	addi	r3,r3,8
+	nop
+	/* adjust by 8 */
+	addi	r3,r3,8
+	nop
+
+/*
+ * Here we have had a fault on a load and r3 points to the first
+ * unmodified byte of the destination.  We use the original arguments
+ * and r3 to work out how much wasn't copied.  Since we load some
+ * distance ahead of the stores, we continue copying byte-by-byte until
+ * we hit the load fault again in order to copy as much as possible.
+ */
+.Lld_exc:
+	ld	r6,-24(r1)
+	ld	r4,-16(r1)
+	ld	r5,-8(r1)
+	subf	r6,r6,r3
+	add	r4,r4,r6
+	subf	r5,r6,r5	/* #bytes left to go */
+
+/*
+ * first see if we can copy any more bytes before hitting another exception
+ */
+	mtctr	r5
+r3_offset = 0
+100:	EX_TABLE(100b, .Ldone)
+43:	lbz	r0,0(r4)
+	addi	r4,r4,1
+stex;	stb	r0,0(r3)
+	addi	r3,r3,1
+	bdnz	43b
+	li	r3,0		/* huh? all copied successfully this time? */
+	blr
+
+/*
+ * here we have trapped again, amount remaining is in ctr.
+ */
+.Ldone:
+	mfctr	r3
+	blr
+
+/*
+ * exception handlers for stores: we need to work out how many bytes
+ * weren't copied, and we may need to copy some more.
+ * Note that the number of bytes of instructions for adjusting r3 needs
+ * to equal the amount of the adjustment, due to the trick of using
+ * .Lst_exc - r3_offset as the handler address.
+ */
+.Lst_exc_r7:
+	add	r3,r3,r7
+	b	.Lst_exc
+
+	/* adjust by 24 */
+	addi	r3,r3,8
+	nop
+	/* adjust by 16 */
+	addi	r3,r3,8
+	nop
+	/* adjust by 8 */
+	addi	r3,r3,4
+	/* adjust by 4 */
+	addi	r3,r3,4
+.Lst_exc:
+	ld	r6,-24(r1)	/* original destination pointer */
+	ld	r4,-16(r1)	/* original source pointer */
+	ld	r5,-8(r1)	/* original number of bytes */
+	add	r7,r6,r5
+	/*
+	 * If the destination pointer isn't 8-byte aligned,
+	 * we may have got the exception as a result of a
+	 * store that overlapped a page boundary, so we may be
+	 * able to copy a few more bytes.
+	 */
+17:	andi.	r0,r3,7
+	beq	19f
+	subf	r8,r6,r3	/* #bytes copied */
+100:	EX_TABLE(100b,19f)
+	lbzx	r0,r8,r4
+100:	EX_TABLE(100b,19f)
+	stb	r0,0(r3)
+	addi	r3,r3,1
+	cmpld	r3,r7
+	blt	17b
+19:	subf	r3,r3,r7	/* #bytes not copied in r3 */
+	blr
+
+/*
+ * Routine to copy a whole page of data, optimized for POWER4.
+ * On POWER4 it is more than 50% faster than the simple loop
+ * above (following the .Ldst_aligned label).
+ */
+	.macro	exc
+100:	EX_TABLE(100b, .Labort)
+	.endm
+.Lcopy_page_4K:
+	std	r31,-32(1)
+	std	r30,-40(1)
+	std	r29,-48(1)
+	std	r28,-56(1)
+	std	r27,-64(1)
+	std	r26,-72(1)
+	std	r25,-80(1)
+	std	r24,-88(1)
+	std	r23,-96(1)
+	std	r22,-104(1)
+	std	r21,-112(1)
+	std	r20,-120(1)
+	li	r5,4096/32 - 1
+	addi	r3,r3,-8
+	li	r0,5
+0:	addi	r5,r5,-24
+	mtctr	r0
+exc;	ld	r22,640(4)
+exc;	ld	r21,512(4)
+exc;	ld	r20,384(4)
+exc;	ld	r11,256(4)
+exc;	ld	r9,128(4)
+exc;	ld	r7,0(4)
+exc;	ld	r25,648(4)
+exc;	ld	r24,520(4)
+exc;	ld	r23,392(4)
+exc;	ld	r10,264(4)
+exc;	ld	r8,136(4)
+exc;	ldu	r6,8(4)
+	cmpwi	r5,24
+1:
+exc;	std	r22,648(3)
+exc;	std	r21,520(3)
+exc;	std	r20,392(3)
+exc;	std	r11,264(3)
+exc;	std	r9,136(3)
+exc;	std	r7,8(3)
+exc;	ld	r28,648(4)
+exc;	ld	r27,520(4)
+exc;	ld	r26,392(4)
+exc;	ld	r31,264(4)
+exc;	ld	r30,136(4)
+exc;	ld	r29,8(4)
+exc;	std	r25,656(3)
+exc;	std	r24,528(3)
+exc;	std	r23,400(3)
+exc;	std	r10,272(3)
+exc;	std	r8,144(3)
+exc;	std	r6,16(3)
+exc;	ld	r22,656(4)
+exc;	ld	r21,528(4)
+exc;	ld	r20,400(4)
+exc;	ld	r11,272(4)
+exc;	ld	r9,144(4)
+exc;	ld	r7,16(4)
+exc;	std	r28,664(3)
+exc;	std	r27,536(3)
+exc;	std	r26,408(3)
+exc;	std	r31,280(3)
+exc;	std	r30,152(3)
+exc;	stdu	r29,24(3)
+exc;	ld	r25,664(4)
+exc;	ld	r24,536(4)
+exc;	ld	r23,408(4)
+exc;	ld	r10,280(4)
+exc;	ld	r8,152(4)
+exc;	ldu	r6,24(4)
+	bdnz	1b
+exc;	std	r22,648(3)
+exc;	std	r21,520(3)
+exc;	std	r20,392(3)
+exc;	std	r11,264(3)
+exc;	std	r9,136(3)
+exc;	std	r7,8(3)
+	addi	r4,r4,640
+	addi	r3,r3,648
+	bge	0b
+	mtctr	r5
+exc;	ld	r7,0(4)
+exc;	ld	r8,8(4)
+exc;	ldu	r9,16(4)
+3:
+exc;	ld	r10,8(4)
+exc;	std	r7,8(3)
+exc;	ld	r7,16(4)
+exc;	std	r8,16(3)
+exc;	ld	r8,24(4)
+exc;	std	r9,24(3)
+exc;	ldu	r9,32(4)
+exc;	stdu	r10,32(3)
+	bdnz	3b
+4:
+exc;	ld	r10,8(4)
+exc;	std	r7,8(3)
+exc;	std	r8,16(3)
+exc;	std	r9,24(3)
+exc;	std	r10,32(3)
+9:	ld	r20,-120(1)
+	ld	r21,-112(1)
+	ld	r22,-104(1)
+	ld	r23,-96(1)
+	ld	r24,-88(1)
+	ld	r25,-80(1)
+	ld	r26,-72(1)
+	ld	r27,-64(1)
+	ld	r28,-56(1)
+	ld	r29,-48(1)
+	ld	r30,-40(1)
+	ld	r31,-32(1)
+	li	r3,0
+	blr
+
+/*
+ * on an exception, reset to the beginning and jump back into the
+ * standard __copy_tofrom_user
+ */
+.Labort:
+	ld	r20,-120(1)
+	ld	r21,-112(1)
+	ld	r22,-104(1)
+	ld	r23,-96(1)
+	ld	r24,-88(1)
+	ld	r25,-80(1)
+	ld	r26,-72(1)
+	ld	r27,-64(1)
+	ld	r28,-56(1)
+	ld	r29,-48(1)
+	ld	r30,-40(1)
+	ld	r31,-32(1)
+	ld	r3,-24(r1)
+	ld	r4,-16(r1)
+	li	r5,4096
+	b	.Ldst_aligned
+EXPORT_SYMBOL(__copy_tofrom_user)
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S
deleted file mode 120000
index 4786895..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/lib/copyuser_power7.S
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S
new file mode 100644
index 0000000..1a1fe18
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S
@@ -0,0 +1,707 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2011
+ *
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ */
+#include <asm/ppc_asm.h>
+
+#ifndef SELFTEST_CASE
+/* 0 == don't use VMX, 1 == use VMX */
+#define SELFTEST_CASE	0
+#endif
+
+#ifdef __BIG_ENDIAN__
+#define LVS(VRT,RA,RB)		lvsl	VRT,RA,RB
+#define VPERM(VRT,VRA,VRB,VRC)	vperm	VRT,VRA,VRB,VRC
+#else
+#define LVS(VRT,RA,RB)		lvsr	VRT,RA,RB
+#define VPERM(VRT,VRA,VRB,VRC)	vperm	VRT,VRB,VRA,VRC
+#endif
+
+	.macro err1
+100:
+	EX_TABLE(100b,.Ldo_err1)
+	.endm
+
+	.macro err2
+200:
+	EX_TABLE(200b,.Ldo_err2)
+	.endm
+
+#ifdef CONFIG_ALTIVEC
+	.macro err3
+300:
+	EX_TABLE(300b,.Ldo_err3)
+	.endm
+
+	.macro err4
+400:
+	EX_TABLE(400b,.Ldo_err4)
+	.endm
+
+
+.Ldo_err4:
+	ld	r16,STK_REG(R16)(r1)
+	ld	r15,STK_REG(R15)(r1)
+	ld	r14,STK_REG(R14)(r1)
+.Ldo_err3:
+	bl	exit_vmx_usercopy
+	ld	r0,STACKFRAMESIZE+16(r1)
+	mtlr	r0
+	b	.Lexit
+#endif /* CONFIG_ALTIVEC */
+
+.Ldo_err2:
+	ld	r22,STK_REG(R22)(r1)
+	ld	r21,STK_REG(R21)(r1)
+	ld	r20,STK_REG(R20)(r1)
+	ld	r19,STK_REG(R19)(r1)
+	ld	r18,STK_REG(R18)(r1)
+	ld	r17,STK_REG(R17)(r1)
+	ld	r16,STK_REG(R16)(r1)
+	ld	r15,STK_REG(R15)(r1)
+	ld	r14,STK_REG(R14)(r1)
+.Lexit:
+	addi	r1,r1,STACKFRAMESIZE
+.Ldo_err1:
+	ld	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
+	ld	r4,-STACKFRAMESIZE+STK_REG(R30)(r1)
+	ld	r5,-STACKFRAMESIZE+STK_REG(R29)(r1)
+	b	__copy_tofrom_user_base
+
+
+_GLOBAL(__copy_tofrom_user_power7)
+	cmpldi	r5,16
+	cmpldi	cr1,r5,3328
+
+	std	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
+	std	r4,-STACKFRAMESIZE+STK_REG(R30)(r1)
+	std	r5,-STACKFRAMESIZE+STK_REG(R29)(r1)
+
+	blt	.Lshort_copy
+
+#ifdef CONFIG_ALTIVEC
+test_feature = SELFTEST_CASE
+BEGIN_FTR_SECTION
+	bgt	cr1,.Lvmx_copy
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
+
+.Lnonvmx_copy:
+	/* Get the source 8B aligned */
+	neg	r6,r4
+	mtocrf	0x01,r6
+	clrldi	r6,r6,(64-3)
+
+	bf	cr7*4+3,1f
+err1;	lbz	r0,0(r4)
+	addi	r4,r4,1
+err1;	stb	r0,0(r3)
+	addi	r3,r3,1
+
+1:	bf	cr7*4+2,2f
+err1;	lhz	r0,0(r4)
+	addi	r4,r4,2
+err1;	sth	r0,0(r3)
+	addi	r3,r3,2
+
+2:	bf	cr7*4+1,3f
+err1;	lwz	r0,0(r4)
+	addi	r4,r4,4
+err1;	stw	r0,0(r3)
+	addi	r3,r3,4
+
+3:	sub	r5,r5,r6
+	cmpldi	r5,128
+	blt	5f
+
+	mflr	r0
+	stdu	r1,-STACKFRAMESIZE(r1)
+	std	r14,STK_REG(R14)(r1)
+	std	r15,STK_REG(R15)(r1)
+	std	r16,STK_REG(R16)(r1)
+	std	r17,STK_REG(R17)(r1)
+	std	r18,STK_REG(R18)(r1)
+	std	r19,STK_REG(R19)(r1)
+	std	r20,STK_REG(R20)(r1)
+	std	r21,STK_REG(R21)(r1)
+	std	r22,STK_REG(R22)(r1)
+	std	r0,STACKFRAMESIZE+16(r1)
+
+	srdi	r6,r5,7
+	mtctr	r6
+
+	/* Now do cacheline (128B) sized loads and stores. */
+	.align	5
+4:
+err2;	ld	r0,0(r4)
+err2;	ld	r6,8(r4)
+err2;	ld	r7,16(r4)
+err2;	ld	r8,24(r4)
+err2;	ld	r9,32(r4)
+err2;	ld	r10,40(r4)
+err2;	ld	r11,48(r4)
+err2;	ld	r12,56(r4)
+err2;	ld	r14,64(r4)
+err2;	ld	r15,72(r4)
+err2;	ld	r16,80(r4)
+err2;	ld	r17,88(r4)
+err2;	ld	r18,96(r4)
+err2;	ld	r19,104(r4)
+err2;	ld	r20,112(r4)
+err2;	ld	r21,120(r4)
+	addi	r4,r4,128
+err2;	std	r0,0(r3)
+err2;	std	r6,8(r3)
+err2;	std	r7,16(r3)
+err2;	std	r8,24(r3)
+err2;	std	r9,32(r3)
+err2;	std	r10,40(r3)
+err2;	std	r11,48(r3)
+err2;	std	r12,56(r3)
+err2;	std	r14,64(r3)
+err2;	std	r15,72(r3)
+err2;	std	r16,80(r3)
+err2;	std	r17,88(r3)
+err2;	std	r18,96(r3)
+err2;	std	r19,104(r3)
+err2;	std	r20,112(r3)
+err2;	std	r21,120(r3)
+	addi	r3,r3,128
+	bdnz	4b
+
+	clrldi	r5,r5,(64-7)
+
+	ld	r14,STK_REG(R14)(r1)
+	ld	r15,STK_REG(R15)(r1)
+	ld	r16,STK_REG(R16)(r1)
+	ld	r17,STK_REG(R17)(r1)
+	ld	r18,STK_REG(R18)(r1)
+	ld	r19,STK_REG(R19)(r1)
+	ld	r20,STK_REG(R20)(r1)
+	ld	r21,STK_REG(R21)(r1)
+	ld	r22,STK_REG(R22)(r1)
+	addi	r1,r1,STACKFRAMESIZE
+
+	/* Up to 127B to go */
+5:	srdi	r6,r5,4
+	mtocrf	0x01,r6
+
+6:	bf	cr7*4+1,7f
+err1;	ld	r0,0(r4)
+err1;	ld	r6,8(r4)
+err1;	ld	r7,16(r4)
+err1;	ld	r8,24(r4)
+err1;	ld	r9,32(r4)
+err1;	ld	r10,40(r4)
+err1;	ld	r11,48(r4)
+err1;	ld	r12,56(r4)
+	addi	r4,r4,64
+err1;	std	r0,0(r3)
+err1;	std	r6,8(r3)
+err1;	std	r7,16(r3)
+err1;	std	r8,24(r3)
+err1;	std	r9,32(r3)
+err1;	std	r10,40(r3)
+err1;	std	r11,48(r3)
+err1;	std	r12,56(r3)
+	addi	r3,r3,64
+
+	/* Up to 63B to go */
+7:	bf	cr7*4+2,8f
+err1;	ld	r0,0(r4)
+err1;	ld	r6,8(r4)
+err1;	ld	r7,16(r4)
+err1;	ld	r8,24(r4)
+	addi	r4,r4,32
+err1;	std	r0,0(r3)
+err1;	std	r6,8(r3)
+err1;	std	r7,16(r3)
+err1;	std	r8,24(r3)
+	addi	r3,r3,32
+
+	/* Up to 31B to go */
+8:	bf	cr7*4+3,9f
+err1;	ld	r0,0(r4)
+err1;	ld	r6,8(r4)
+	addi	r4,r4,16
+err1;	std	r0,0(r3)
+err1;	std	r6,8(r3)
+	addi	r3,r3,16
+
+9:	clrldi	r5,r5,(64-4)
+
+	/* Up to 15B to go */
+.Lshort_copy:
+	mtocrf	0x01,r5
+	bf	cr7*4+0,12f
+err1;	lwz	r0,0(r4)	/* Less chance of a reject with word ops */
+err1;	lwz	r6,4(r4)
+	addi	r4,r4,8
+err1;	stw	r0,0(r3)
+err1;	stw	r6,4(r3)
+	addi	r3,r3,8
+
+12:	bf	cr7*4+1,13f
+err1;	lwz	r0,0(r4)
+	addi	r4,r4,4
+err1;	stw	r0,0(r3)
+	addi	r3,r3,4
+
+13:	bf	cr7*4+2,14f
+err1;	lhz	r0,0(r4)
+	addi	r4,r4,2
+err1;	sth	r0,0(r3)
+	addi	r3,r3,2
+
+14:	bf	cr7*4+3,15f
+err1;	lbz	r0,0(r4)
+err1;	stb	r0,0(r3)
+
+15:	li	r3,0
+	blr
+
+.Lunwind_stack_nonvmx_copy:
+	addi	r1,r1,STACKFRAMESIZE
+	b	.Lnonvmx_copy
+
+.Lvmx_copy:
+#ifdef CONFIG_ALTIVEC
+	mflr	r0
+	std	r0,16(r1)
+	stdu	r1,-STACKFRAMESIZE(r1)
+	bl	enter_vmx_usercopy
+	cmpwi	cr1,r3,0
+	ld	r0,STACKFRAMESIZE+16(r1)
+	ld	r3,STK_REG(R31)(r1)
+	ld	r4,STK_REG(R30)(r1)
+	ld	r5,STK_REG(R29)(r1)
+	mtlr	r0
+
+	/*
+	 * We prefetch both the source and destination using enhanced touch
+	 * instructions. We use a stream ID of 0 for the load side and
+	 * 1 for the store side.
+	 */
+	clrrdi	r6,r4,7
+	clrrdi	r9,r3,7
+	ori	r9,r9,1		/* stream=1 */
+
+	srdi	r7,r5,7		/* length in cachelines, capped at 0x3FF */
+	cmpldi	r7,0x3FF
+	ble	1f
+	li	r7,0x3FF
+1:	lis	r0,0x0E00	/* depth=7 */
+	sldi	r7,r7,7
+	or	r7,r7,r0
+	ori	r10,r7,1	/* stream=1 */
+
+	lis	r8,0x8000	/* GO=1 */
+	clrldi	r8,r8,32
+
+	/* setup read stream 0 */
+	dcbt	0,r6,0b01000   /* addr from */
+	dcbt	0,r7,0b01010   /* length and depth from */
+	/* setup write stream 1 */
+	dcbtst	0,r9,0b01000   /* addr to */
+	dcbtst	0,r10,0b01010  /* length and depth to */
+	eieio
+	dcbt	0,r8,0b01010	/* all streams GO */
+
+	beq	cr1,.Lunwind_stack_nonvmx_copy
+
+	/*
+	 * If source and destination are not relatively aligned we use a
+	 * slower permute loop.
+	 */
+	xor	r6,r4,r3
+	rldicl.	r6,r6,0,(64-4)
+	bne	.Lvmx_unaligned_copy
+
+	/* Get the destination 16B aligned */
+	neg	r6,r3
+	mtocrf	0x01,r6
+	clrldi	r6,r6,(64-4)
+
+	bf	cr7*4+3,1f
+err3;	lbz	r0,0(r4)
+	addi	r4,r4,1
+err3;	stb	r0,0(r3)
+	addi	r3,r3,1
+
+1:	bf	cr7*4+2,2f
+err3;	lhz	r0,0(r4)
+	addi	r4,r4,2
+err3;	sth	r0,0(r3)
+	addi	r3,r3,2
+
+2:	bf	cr7*4+1,3f
+err3;	lwz	r0,0(r4)
+	addi	r4,r4,4
+err3;	stw	r0,0(r3)
+	addi	r3,r3,4
+
+3:	bf	cr7*4+0,4f
+err3;	ld	r0,0(r4)
+	addi	r4,r4,8
+err3;	std	r0,0(r3)
+	addi	r3,r3,8
+
+4:	sub	r5,r5,r6
+
+	/* Get the desination 128B aligned */
+	neg	r6,r3
+	srdi	r7,r6,4
+	mtocrf	0x01,r7
+	clrldi	r6,r6,(64-7)
+
+	li	r9,16
+	li	r10,32
+	li	r11,48
+
+	bf	cr7*4+3,5f
+err3;	lvx	v1,0,r4
+	addi	r4,r4,16
+err3;	stvx	v1,0,r3
+	addi	r3,r3,16
+
+5:	bf	cr7*4+2,6f
+err3;	lvx	v1,0,r4
+err3;	lvx	v0,r4,r9
+	addi	r4,r4,32
+err3;	stvx	v1,0,r3
+err3;	stvx	v0,r3,r9
+	addi	r3,r3,32
+
+6:	bf	cr7*4+1,7f
+err3;	lvx	v3,0,r4
+err3;	lvx	v2,r4,r9
+err3;	lvx	v1,r4,r10
+err3;	lvx	v0,r4,r11
+	addi	r4,r4,64
+err3;	stvx	v3,0,r3
+err3;	stvx	v2,r3,r9
+err3;	stvx	v1,r3,r10
+err3;	stvx	v0,r3,r11
+	addi	r3,r3,64
+
+7:	sub	r5,r5,r6
+	srdi	r6,r5,7
+
+	std	r14,STK_REG(R14)(r1)
+	std	r15,STK_REG(R15)(r1)
+	std	r16,STK_REG(R16)(r1)
+
+	li	r12,64
+	li	r14,80
+	li	r15,96
+	li	r16,112
+
+	mtctr	r6
+
+	/*
+	 * Now do cacheline sized loads and stores. By this stage the
+	 * cacheline stores are also cacheline aligned.
+	 */
+	.align	5
+8:
+err4;	lvx	v7,0,r4
+err4;	lvx	v6,r4,r9
+err4;	lvx	v5,r4,r10
+err4;	lvx	v4,r4,r11
+err4;	lvx	v3,r4,r12
+err4;	lvx	v2,r4,r14
+err4;	lvx	v1,r4,r15
+err4;	lvx	v0,r4,r16
+	addi	r4,r4,128
+err4;	stvx	v7,0,r3
+err4;	stvx	v6,r3,r9
+err4;	stvx	v5,r3,r10
+err4;	stvx	v4,r3,r11
+err4;	stvx	v3,r3,r12
+err4;	stvx	v2,r3,r14
+err4;	stvx	v1,r3,r15
+err4;	stvx	v0,r3,r16
+	addi	r3,r3,128
+	bdnz	8b
+
+	ld	r14,STK_REG(R14)(r1)
+	ld	r15,STK_REG(R15)(r1)
+	ld	r16,STK_REG(R16)(r1)
+
+	/* Up to 127B to go */
+	clrldi	r5,r5,(64-7)
+	srdi	r6,r5,4
+	mtocrf	0x01,r6
+
+	bf	cr7*4+1,9f
+err3;	lvx	v3,0,r4
+err3;	lvx	v2,r4,r9
+err3;	lvx	v1,r4,r10
+err3;	lvx	v0,r4,r11
+	addi	r4,r4,64
+err3;	stvx	v3,0,r3
+err3;	stvx	v2,r3,r9
+err3;	stvx	v1,r3,r10
+err3;	stvx	v0,r3,r11
+	addi	r3,r3,64
+
+9:	bf	cr7*4+2,10f
+err3;	lvx	v1,0,r4
+err3;	lvx	v0,r4,r9
+	addi	r4,r4,32
+err3;	stvx	v1,0,r3
+err3;	stvx	v0,r3,r9
+	addi	r3,r3,32
+
+10:	bf	cr7*4+3,11f
+err3;	lvx	v1,0,r4
+	addi	r4,r4,16
+err3;	stvx	v1,0,r3
+	addi	r3,r3,16
+
+	/* Up to 15B to go */
+11:	clrldi	r5,r5,(64-4)
+	mtocrf	0x01,r5
+	bf	cr7*4+0,12f
+err3;	ld	r0,0(r4)
+	addi	r4,r4,8
+err3;	std	r0,0(r3)
+	addi	r3,r3,8
+
+12:	bf	cr7*4+1,13f
+err3;	lwz	r0,0(r4)
+	addi	r4,r4,4
+err3;	stw	r0,0(r3)
+	addi	r3,r3,4
+
+13:	bf	cr7*4+2,14f
+err3;	lhz	r0,0(r4)
+	addi	r4,r4,2
+err3;	sth	r0,0(r3)
+	addi	r3,r3,2
+
+14:	bf	cr7*4+3,15f
+err3;	lbz	r0,0(r4)
+err3;	stb	r0,0(r3)
+
+15:	addi	r1,r1,STACKFRAMESIZE
+	b	exit_vmx_usercopy	/* tail call optimise */
+
+.Lvmx_unaligned_copy:
+	/* Get the destination 16B aligned */
+	neg	r6,r3
+	mtocrf	0x01,r6
+	clrldi	r6,r6,(64-4)
+
+	bf	cr7*4+3,1f
+err3;	lbz	r0,0(r4)
+	addi	r4,r4,1
+err3;	stb	r0,0(r3)
+	addi	r3,r3,1
+
+1:	bf	cr7*4+2,2f
+err3;	lhz	r0,0(r4)
+	addi	r4,r4,2
+err3;	sth	r0,0(r3)
+	addi	r3,r3,2
+
+2:	bf	cr7*4+1,3f
+err3;	lwz	r0,0(r4)
+	addi	r4,r4,4
+err3;	stw	r0,0(r3)
+	addi	r3,r3,4
+
+3:	bf	cr7*4+0,4f
+err3;	lwz	r0,0(r4)	/* Less chance of a reject with word ops */
+err3;	lwz	r7,4(r4)
+	addi	r4,r4,8
+err3;	stw	r0,0(r3)
+err3;	stw	r7,4(r3)
+	addi	r3,r3,8
+
+4:	sub	r5,r5,r6
+
+	/* Get the desination 128B aligned */
+	neg	r6,r3
+	srdi	r7,r6,4
+	mtocrf	0x01,r7
+	clrldi	r6,r6,(64-7)
+
+	li	r9,16
+	li	r10,32
+	li	r11,48
+
+	LVS(v16,0,r4)		/* Setup permute control vector */
+err3;	lvx	v0,0,r4
+	addi	r4,r4,16
+
+	bf	cr7*4+3,5f
+err3;	lvx	v1,0,r4
+	VPERM(v8,v0,v1,v16)
+	addi	r4,r4,16
+err3;	stvx	v8,0,r3
+	addi	r3,r3,16
+	vor	v0,v1,v1
+
+5:	bf	cr7*4+2,6f
+err3;	lvx	v1,0,r4
+	VPERM(v8,v0,v1,v16)
+err3;	lvx	v0,r4,r9
+	VPERM(v9,v1,v0,v16)
+	addi	r4,r4,32
+err3;	stvx	v8,0,r3
+err3;	stvx	v9,r3,r9
+	addi	r3,r3,32
+
+6:	bf	cr7*4+1,7f
+err3;	lvx	v3,0,r4
+	VPERM(v8,v0,v3,v16)
+err3;	lvx	v2,r4,r9
+	VPERM(v9,v3,v2,v16)
+err3;	lvx	v1,r4,r10
+	VPERM(v10,v2,v1,v16)
+err3;	lvx	v0,r4,r11
+	VPERM(v11,v1,v0,v16)
+	addi	r4,r4,64
+err3;	stvx	v8,0,r3
+err3;	stvx	v9,r3,r9
+err3;	stvx	v10,r3,r10
+err3;	stvx	v11,r3,r11
+	addi	r3,r3,64
+
+7:	sub	r5,r5,r6
+	srdi	r6,r5,7
+
+	std	r14,STK_REG(R14)(r1)
+	std	r15,STK_REG(R15)(r1)
+	std	r16,STK_REG(R16)(r1)
+
+	li	r12,64
+	li	r14,80
+	li	r15,96
+	li	r16,112
+
+	mtctr	r6
+
+	/*
+	 * Now do cacheline sized loads and stores. By this stage the
+	 * cacheline stores are also cacheline aligned.
+	 */
+	.align	5
+8:
+err4;	lvx	v7,0,r4
+	VPERM(v8,v0,v7,v16)
+err4;	lvx	v6,r4,r9
+	VPERM(v9,v7,v6,v16)
+err4;	lvx	v5,r4,r10
+	VPERM(v10,v6,v5,v16)
+err4;	lvx	v4,r4,r11
+	VPERM(v11,v5,v4,v16)
+err4;	lvx	v3,r4,r12
+	VPERM(v12,v4,v3,v16)
+err4;	lvx	v2,r4,r14
+	VPERM(v13,v3,v2,v16)
+err4;	lvx	v1,r4,r15
+	VPERM(v14,v2,v1,v16)
+err4;	lvx	v0,r4,r16
+	VPERM(v15,v1,v0,v16)
+	addi	r4,r4,128
+err4;	stvx	v8,0,r3
+err4;	stvx	v9,r3,r9
+err4;	stvx	v10,r3,r10
+err4;	stvx	v11,r3,r11
+err4;	stvx	v12,r3,r12
+err4;	stvx	v13,r3,r14
+err4;	stvx	v14,r3,r15
+err4;	stvx	v15,r3,r16
+	addi	r3,r3,128
+	bdnz	8b
+
+	ld	r14,STK_REG(R14)(r1)
+	ld	r15,STK_REG(R15)(r1)
+	ld	r16,STK_REG(R16)(r1)
+
+	/* Up to 127B to go */
+	clrldi	r5,r5,(64-7)
+	srdi	r6,r5,4
+	mtocrf	0x01,r6
+
+	bf	cr7*4+1,9f
+err3;	lvx	v3,0,r4
+	VPERM(v8,v0,v3,v16)
+err3;	lvx	v2,r4,r9
+	VPERM(v9,v3,v2,v16)
+err3;	lvx	v1,r4,r10
+	VPERM(v10,v2,v1,v16)
+err3;	lvx	v0,r4,r11
+	VPERM(v11,v1,v0,v16)
+	addi	r4,r4,64
+err3;	stvx	v8,0,r3
+err3;	stvx	v9,r3,r9
+err3;	stvx	v10,r3,r10
+err3;	stvx	v11,r3,r11
+	addi	r3,r3,64
+
+9:	bf	cr7*4+2,10f
+err3;	lvx	v1,0,r4
+	VPERM(v8,v0,v1,v16)
+err3;	lvx	v0,r4,r9
+	VPERM(v9,v1,v0,v16)
+	addi	r4,r4,32
+err3;	stvx	v8,0,r3
+err3;	stvx	v9,r3,r9
+	addi	r3,r3,32
+
+10:	bf	cr7*4+3,11f
+err3;	lvx	v1,0,r4
+	VPERM(v8,v0,v1,v16)
+	addi	r4,r4,16
+err3;	stvx	v8,0,r3
+	addi	r3,r3,16
+
+	/* Up to 15B to go */
+11:	clrldi	r5,r5,(64-4)
+	addi	r4,r4,-16	/* Unwind the +16 load offset */
+	mtocrf	0x01,r5
+	bf	cr7*4+0,12f
+err3;	lwz	r0,0(r4)	/* Less chance of a reject with word ops */
+err3;	lwz	r6,4(r4)
+	addi	r4,r4,8
+err3;	stw	r0,0(r3)
+err3;	stw	r6,4(r3)
+	addi	r3,r3,8
+
+12:	bf	cr7*4+1,13f
+err3;	lwz	r0,0(r4)
+	addi	r4,r4,4
+err3;	stw	r0,0(r3)
+	addi	r3,r3,4
+
+13:	bf	cr7*4+2,14f
+err3;	lhz	r0,0(r4)
+	addi	r4,r4,2
+err3;	sth	r0,0(r3)
+	addi	r3,r3,2
+
+14:	bf	cr7*4+3,15f
+err3;	lbz	r0,0(r4)
+err3;	stb	r0,0(r3)
+
+15:	addi	r1,r1,STACKFRAMESIZE
+	b	exit_vmx_usercopy	/* tail call optimise */
+#endif /* CONFIG_ALTIVEC */
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_64.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_64.S
deleted file mode 120000
index cce33fb..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_64.S
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/lib/memcpy_64.S
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_64.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_64.S
new file mode 100644
index 0000000..273ea67
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_64.S
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+ *
+ * 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.
+ */
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/export.h>
+#include <asm/asm-compat.h>
+#include <asm/feature-fixups.h>
+
+#ifndef SELFTEST_CASE
+/* For big-endian, 0 == most CPUs, 1 == POWER6, 2 == Cell */
+#define SELFTEST_CASE	0
+#endif
+
+	.align	7
+_GLOBAL_TOC(memcpy)
+BEGIN_FTR_SECTION
+#ifdef __LITTLE_ENDIAN__
+	cmpdi	cr7,r5,0
+#else
+	std	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)	/* save destination pointer for return value */
+#endif
+FTR_SECTION_ELSE
+#ifdef CONFIG_PPC_BOOK3S_64
+	b	memcpy_power7
+#endif
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
+#ifdef __LITTLE_ENDIAN__
+	/* dumb little-endian memcpy that will get replaced at runtime */
+	addi r9,r3,-1
+	addi r4,r4,-1
+	beqlr cr7
+	mtctr r5
+1:	lbzu r10,1(r4)
+	stbu r10,1(r9)
+	bdnz 1b
+	blr
+#else
+	PPC_MTOCRF(0x01,r5)
+	cmpldi	cr1,r5,16
+	neg	r6,r3		# LS 3 bits = # bytes to 8-byte dest bdry
+	andi.	r6,r6,7
+	dcbt	0,r4
+	blt	cr1,.Lshort_copy
+/* Below we want to nop out the bne if we're on a CPU that has the
+   CPU_FTR_UNALIGNED_LD_STD bit set and the CPU_FTR_CP_USE_DCBTZ bit
+   cleared.
+   At the time of writing the only CPU that has this combination of bits
+   set is Power6. */
+test_feature = (SELFTEST_CASE == 1)
+BEGIN_FTR_SECTION
+	nop
+FTR_SECTION_ELSE
+	bne	.Ldst_unaligned
+ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \
+                    CPU_FTR_UNALIGNED_LD_STD)
+.Ldst_aligned:
+	addi	r3,r3,-16
+test_feature = (SELFTEST_CASE == 0)
+BEGIN_FTR_SECTION
+	andi.	r0,r4,7
+	bne	.Lsrc_unaligned
+END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
+	srdi	r7,r5,4
+	ld	r9,0(r4)
+	addi	r4,r4,-8
+	mtctr	r7
+	andi.	r5,r5,7
+	bf	cr7*4+0,2f
+	addi	r3,r3,8
+	addi	r4,r4,8
+	mr	r8,r9
+	blt	cr1,3f
+1:	ld	r9,8(r4)
+	std	r8,8(r3)
+2:	ldu	r8,16(r4)
+	stdu	r9,16(r3)
+	bdnz	1b
+3:	std	r8,8(r3)
+	beq	3f
+	addi	r3,r3,16
+.Ldo_tail:
+	bf	cr7*4+1,1f
+	lwz	r9,8(r4)
+	addi	r4,r4,4
+	stw	r9,0(r3)
+	addi	r3,r3,4
+1:	bf	cr7*4+2,2f
+	lhz	r9,8(r4)
+	addi	r4,r4,2
+	sth	r9,0(r3)
+	addi	r3,r3,2
+2:	bf	cr7*4+3,3f
+	lbz	r9,8(r4)
+	stb	r9,0(r3)
+3:	ld	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)	/* return dest pointer */
+	blr
+
+.Lsrc_unaligned:
+	srdi	r6,r5,3
+	addi	r5,r5,-16
+	subf	r4,r0,r4
+	srdi	r7,r5,4
+	sldi	r10,r0,3
+	cmpdi	cr6,r6,3
+	andi.	r5,r5,7
+	mtctr	r7
+	subfic	r11,r10,64
+	add	r5,r5,r0
+
+	bt	cr7*4+0,0f
+
+	ld	r9,0(r4)	# 3+2n loads, 2+2n stores
+	ld	r0,8(r4)
+	sld	r6,r9,r10
+	ldu	r9,16(r4)
+	srd	r7,r0,r11
+	sld	r8,r0,r10
+	or	r7,r7,r6
+	blt	cr6,4f
+	ld	r0,8(r4)
+	# s1<< in r8, d0=(s0<<|s1>>) in r7, s3 in r0, s2 in r9, nix in r6 & r12
+	b	2f
+
+0:	ld	r0,0(r4)	# 4+2n loads, 3+2n stores
+	ldu	r9,8(r4)
+	sld	r8,r0,r10
+	addi	r3,r3,-8
+	blt	cr6,5f
+	ld	r0,8(r4)
+	srd	r12,r9,r11
+	sld	r6,r9,r10
+	ldu	r9,16(r4)
+	or	r12,r8,r12
+	srd	r7,r0,r11
+	sld	r8,r0,r10
+	addi	r3,r3,16
+	beq	cr6,3f
+
+	# d0=(s0<<|s1>>) in r12, s1<< in r6, s2>> in r7, s2<< in r8, s3 in r9
+1:	or	r7,r7,r6
+	ld	r0,8(r4)
+	std	r12,8(r3)
+2:	srd	r12,r9,r11
+	sld	r6,r9,r10
+	ldu	r9,16(r4)
+	or	r12,r8,r12
+	stdu	r7,16(r3)
+	srd	r7,r0,r11
+	sld	r8,r0,r10
+	bdnz	1b
+
+3:	std	r12,8(r3)
+	or	r7,r7,r6
+4:	std	r7,16(r3)
+5:	srd	r12,r9,r11
+	or	r12,r8,r12
+	std	r12,24(r3)
+	beq	4f
+	cmpwi	cr1,r5,8
+	addi	r3,r3,32
+	sld	r9,r9,r10
+	ble	cr1,6f
+	ld	r0,8(r4)
+	srd	r7,r0,r11
+	or	r9,r7,r9
+6:
+	bf	cr7*4+1,1f
+	rotldi	r9,r9,32
+	stw	r9,0(r3)
+	addi	r3,r3,4
+1:	bf	cr7*4+2,2f
+	rotldi	r9,r9,16
+	sth	r9,0(r3)
+	addi	r3,r3,2
+2:	bf	cr7*4+3,3f
+	rotldi	r9,r9,8
+	stb	r9,0(r3)
+3:	ld	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)	/* return dest pointer */
+	blr
+
+.Ldst_unaligned:
+	PPC_MTOCRF(0x01,r6)		# put #bytes to 8B bdry into cr7
+	subf	r5,r6,r5
+	li	r7,0
+	cmpldi	cr1,r5,16
+	bf	cr7*4+3,1f
+	lbz	r0,0(r4)
+	stb	r0,0(r3)
+	addi	r7,r7,1
+1:	bf	cr7*4+2,2f
+	lhzx	r0,r7,r4
+	sthx	r0,r7,r3
+	addi	r7,r7,2
+2:	bf	cr7*4+1,3f
+	lwzx	r0,r7,r4
+	stwx	r0,r7,r3
+3:	PPC_MTOCRF(0x01,r5)
+	add	r4,r6,r4
+	add	r3,r6,r3
+	b	.Ldst_aligned
+
+.Lshort_copy:
+	bf	cr7*4+0,1f
+	lwz	r0,0(r4)
+	lwz	r9,4(r4)
+	addi	r4,r4,8
+	stw	r0,0(r3)
+	stw	r9,4(r3)
+	addi	r3,r3,8
+1:	bf	cr7*4+1,2f
+	lwz	r0,0(r4)
+	addi	r4,r4,4
+	stw	r0,0(r3)
+	addi	r3,r3,4
+2:	bf	cr7*4+2,3f
+	lhz	r0,0(r4)
+	addi	r4,r4,2
+	sth	r0,0(r3)
+	addi	r3,r3,2
+3:	bf	cr7*4+3,4f
+	lbz	r0,0(r4)
+	stb	r0,0(r3)
+4:	ld	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)	/* return dest pointer */
+	blr
+#endif
+EXPORT_SYMBOL(memcpy)
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S
deleted file mode 120000
index 0d6fbfa..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/lib/memcpy_power7.S
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S
new file mode 100644
index 0000000..89bfefc
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S
@@ -0,0 +1,653 @@
+/*
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2012
+ *
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ */
+#include <asm/ppc_asm.h>
+
+#ifndef SELFTEST_CASE
+/* 0 == don't use VMX, 1 == use VMX */
+#define SELFTEST_CASE	0
+#endif
+
+#ifdef __BIG_ENDIAN__
+#define LVS(VRT,RA,RB)		lvsl	VRT,RA,RB
+#define VPERM(VRT,VRA,VRB,VRC)	vperm	VRT,VRA,VRB,VRC
+#else
+#define LVS(VRT,RA,RB)		lvsr	VRT,RA,RB
+#define VPERM(VRT,VRA,VRB,VRC)	vperm	VRT,VRB,VRA,VRC
+#endif
+
+_GLOBAL(memcpy_power7)
+	cmpldi	r5,16
+	cmpldi	cr1,r5,4096
+	std	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
+	blt	.Lshort_copy
+
+#ifdef CONFIG_ALTIVEC
+test_feature = SELFTEST_CASE
+BEGIN_FTR_SECTION
+	bgt	cr1, .Lvmx_copy
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
+
+.Lnonvmx_copy:
+	/* Get the source 8B aligned */
+	neg	r6,r4
+	mtocrf	0x01,r6
+	clrldi	r6,r6,(64-3)
+
+	bf	cr7*4+3,1f
+	lbz	r0,0(r4)
+	addi	r4,r4,1
+	stb	r0,0(r3)
+	addi	r3,r3,1
+
+1:	bf	cr7*4+2,2f
+	lhz	r0,0(r4)
+	addi	r4,r4,2
+	sth	r0,0(r3)
+	addi	r3,r3,2
+
+2:	bf	cr7*4+1,3f
+	lwz	r0,0(r4)
+	addi	r4,r4,4
+	stw	r0,0(r3)
+	addi	r3,r3,4
+
+3:	sub	r5,r5,r6
+	cmpldi	r5,128
+	blt	5f
+
+	mflr	r0
+	stdu	r1,-STACKFRAMESIZE(r1)
+	std	r14,STK_REG(R14)(r1)
+	std	r15,STK_REG(R15)(r1)
+	std	r16,STK_REG(R16)(r1)
+	std	r17,STK_REG(R17)(r1)
+	std	r18,STK_REG(R18)(r1)
+	std	r19,STK_REG(R19)(r1)
+	std	r20,STK_REG(R20)(r1)
+	std	r21,STK_REG(R21)(r1)
+	std	r22,STK_REG(R22)(r1)
+	std	r0,STACKFRAMESIZE+16(r1)
+
+	srdi	r6,r5,7
+	mtctr	r6
+
+	/* Now do cacheline (128B) sized loads and stores. */
+	.align	5
+4:
+	ld	r0,0(r4)
+	ld	r6,8(r4)
+	ld	r7,16(r4)
+	ld	r8,24(r4)
+	ld	r9,32(r4)
+	ld	r10,40(r4)
+	ld	r11,48(r4)
+	ld	r12,56(r4)
+	ld	r14,64(r4)
+	ld	r15,72(r4)
+	ld	r16,80(r4)
+	ld	r17,88(r4)
+	ld	r18,96(r4)
+	ld	r19,104(r4)
+	ld	r20,112(r4)
+	ld	r21,120(r4)
+	addi	r4,r4,128
+	std	r0,0(r3)
+	std	r6,8(r3)
+	std	r7,16(r3)
+	std	r8,24(r3)
+	std	r9,32(r3)
+	std	r10,40(r3)
+	std	r11,48(r3)
+	std	r12,56(r3)
+	std	r14,64(r3)
+	std	r15,72(r3)
+	std	r16,80(r3)
+	std	r17,88(r3)
+	std	r18,96(r3)
+	std	r19,104(r3)
+	std	r20,112(r3)
+	std	r21,120(r3)
+	addi	r3,r3,128
+	bdnz	4b
+
+	clrldi	r5,r5,(64-7)
+
+	ld	r14,STK_REG(R14)(r1)
+	ld	r15,STK_REG(R15)(r1)
+	ld	r16,STK_REG(R16)(r1)
+	ld	r17,STK_REG(R17)(r1)
+	ld	r18,STK_REG(R18)(r1)
+	ld	r19,STK_REG(R19)(r1)
+	ld	r20,STK_REG(R20)(r1)
+	ld	r21,STK_REG(R21)(r1)
+	ld	r22,STK_REG(R22)(r1)
+	addi	r1,r1,STACKFRAMESIZE
+
+	/* Up to 127B to go */
+5:	srdi	r6,r5,4
+	mtocrf	0x01,r6
+
+6:	bf	cr7*4+1,7f
+	ld	r0,0(r4)
+	ld	r6,8(r4)
+	ld	r7,16(r4)
+	ld	r8,24(r4)
+	ld	r9,32(r4)
+	ld	r10,40(r4)
+	ld	r11,48(r4)
+	ld	r12,56(r4)
+	addi	r4,r4,64
+	std	r0,0(r3)
+	std	r6,8(r3)
+	std	r7,16(r3)
+	std	r8,24(r3)
+	std	r9,32(r3)
+	std	r10,40(r3)
+	std	r11,48(r3)
+	std	r12,56(r3)
+	addi	r3,r3,64
+
+	/* Up to 63B to go */
+7:	bf	cr7*4+2,8f
+	ld	r0,0(r4)
+	ld	r6,8(r4)
+	ld	r7,16(r4)
+	ld	r8,24(r4)
+	addi	r4,r4,32
+	std	r0,0(r3)
+	std	r6,8(r3)
+	std	r7,16(r3)
+	std	r8,24(r3)
+	addi	r3,r3,32
+
+	/* Up to 31B to go */
+8:	bf	cr7*4+3,9f
+	ld	r0,0(r4)
+	ld	r6,8(r4)
+	addi	r4,r4,16
+	std	r0,0(r3)
+	std	r6,8(r3)
+	addi	r3,r3,16
+
+9:	clrldi	r5,r5,(64-4)
+
+	/* Up to 15B to go */
+.Lshort_copy:
+	mtocrf	0x01,r5
+	bf	cr7*4+0,12f
+	lwz	r0,0(r4)	/* Less chance of a reject with word ops */
+	lwz	r6,4(r4)
+	addi	r4,r4,8
+	stw	r0,0(r3)
+	stw	r6,4(r3)
+	addi	r3,r3,8
+
+12:	bf	cr7*4+1,13f
+	lwz	r0,0(r4)
+	addi	r4,r4,4
+	stw	r0,0(r3)
+	addi	r3,r3,4
+
+13:	bf	cr7*4+2,14f
+	lhz	r0,0(r4)
+	addi	r4,r4,2
+	sth	r0,0(r3)
+	addi	r3,r3,2
+
+14:	bf	cr7*4+3,15f
+	lbz	r0,0(r4)
+	stb	r0,0(r3)
+
+15:	ld	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
+	blr
+
+.Lunwind_stack_nonvmx_copy:
+	addi	r1,r1,STACKFRAMESIZE
+	b	.Lnonvmx_copy
+
+.Lvmx_copy:
+#ifdef CONFIG_ALTIVEC
+	mflr	r0
+	std	r4,-STACKFRAMESIZE+STK_REG(R30)(r1)
+	std	r5,-STACKFRAMESIZE+STK_REG(R29)(r1)
+	std	r0,16(r1)
+	stdu	r1,-STACKFRAMESIZE(r1)
+	bl	enter_vmx_ops
+	cmpwi	cr1,r3,0
+	ld	r0,STACKFRAMESIZE+16(r1)
+	ld	r3,STK_REG(R31)(r1)
+	ld	r4,STK_REG(R30)(r1)
+	ld	r5,STK_REG(R29)(r1)
+	mtlr	r0
+
+	/*
+	 * We prefetch both the source and destination using enhanced touch
+	 * instructions. We use a stream ID of 0 for the load side and
+	 * 1 for the store side.
+	 */
+	clrrdi	r6,r4,7
+	clrrdi	r9,r3,7
+	ori	r9,r9,1		/* stream=1 */
+
+	srdi	r7,r5,7		/* length in cachelines, capped at 0x3FF */
+	cmpldi	r7,0x3FF
+	ble	1f
+	li	r7,0x3FF
+1:	lis	r0,0x0E00	/* depth=7 */
+	sldi	r7,r7,7
+	or	r7,r7,r0
+	ori	r10,r7,1	/* stream=1 */
+
+	lis	r8,0x8000	/* GO=1 */
+	clrldi	r8,r8,32
+
+	dcbt	0,r6,0b01000
+	dcbt	0,r7,0b01010
+	dcbtst	0,r9,0b01000
+	dcbtst	0,r10,0b01010
+	eieio
+	dcbt	0,r8,0b01010	/* GO */
+
+	beq	cr1,.Lunwind_stack_nonvmx_copy
+
+	/*
+	 * If source and destination are not relatively aligned we use a
+	 * slower permute loop.
+	 */
+	xor	r6,r4,r3
+	rldicl.	r6,r6,0,(64-4)
+	bne	.Lvmx_unaligned_copy
+
+	/* Get the destination 16B aligned */
+	neg	r6,r3
+	mtocrf	0x01,r6
+	clrldi	r6,r6,(64-4)
+
+	bf	cr7*4+3,1f
+	lbz	r0,0(r4)
+	addi	r4,r4,1
+	stb	r0,0(r3)
+	addi	r3,r3,1
+
+1:	bf	cr7*4+2,2f
+	lhz	r0,0(r4)
+	addi	r4,r4,2
+	sth	r0,0(r3)
+	addi	r3,r3,2
+
+2:	bf	cr7*4+1,3f
+	lwz	r0,0(r4)
+	addi	r4,r4,4
+	stw	r0,0(r3)
+	addi	r3,r3,4
+
+3:	bf	cr7*4+0,4f
+	ld	r0,0(r4)
+	addi	r4,r4,8
+	std	r0,0(r3)
+	addi	r3,r3,8
+
+4:	sub	r5,r5,r6
+
+	/* Get the desination 128B aligned */
+	neg	r6,r3
+	srdi	r7,r6,4
+	mtocrf	0x01,r7
+	clrldi	r6,r6,(64-7)
+
+	li	r9,16
+	li	r10,32
+	li	r11,48
+
+	bf	cr7*4+3,5f
+	lvx	v1,0,r4
+	addi	r4,r4,16
+	stvx	v1,0,r3
+	addi	r3,r3,16
+
+5:	bf	cr7*4+2,6f
+	lvx	v1,0,r4
+	lvx	v0,r4,r9
+	addi	r4,r4,32
+	stvx	v1,0,r3
+	stvx	v0,r3,r9
+	addi	r3,r3,32
+
+6:	bf	cr7*4+1,7f
+	lvx	v3,0,r4
+	lvx	v2,r4,r9
+	lvx	v1,r4,r10
+	lvx	v0,r4,r11
+	addi	r4,r4,64
+	stvx	v3,0,r3
+	stvx	v2,r3,r9
+	stvx	v1,r3,r10
+	stvx	v0,r3,r11
+	addi	r3,r3,64
+
+7:	sub	r5,r5,r6
+	srdi	r6,r5,7
+
+	std	r14,STK_REG(R14)(r1)
+	std	r15,STK_REG(R15)(r1)
+	std	r16,STK_REG(R16)(r1)
+
+	li	r12,64
+	li	r14,80
+	li	r15,96
+	li	r16,112
+
+	mtctr	r6
+
+	/*
+	 * Now do cacheline sized loads and stores. By this stage the
+	 * cacheline stores are also cacheline aligned.
+	 */
+	.align	5
+8:
+	lvx	v7,0,r4
+	lvx	v6,r4,r9
+	lvx	v5,r4,r10
+	lvx	v4,r4,r11
+	lvx	v3,r4,r12
+	lvx	v2,r4,r14
+	lvx	v1,r4,r15
+	lvx	v0,r4,r16
+	addi	r4,r4,128
+	stvx	v7,0,r3
+	stvx	v6,r3,r9
+	stvx	v5,r3,r10
+	stvx	v4,r3,r11
+	stvx	v3,r3,r12
+	stvx	v2,r3,r14
+	stvx	v1,r3,r15
+	stvx	v0,r3,r16
+	addi	r3,r3,128
+	bdnz	8b
+
+	ld	r14,STK_REG(R14)(r1)
+	ld	r15,STK_REG(R15)(r1)
+	ld	r16,STK_REG(R16)(r1)
+
+	/* Up to 127B to go */
+	clrldi	r5,r5,(64-7)
+	srdi	r6,r5,4
+	mtocrf	0x01,r6
+
+	bf	cr7*4+1,9f
+	lvx	v3,0,r4
+	lvx	v2,r4,r9
+	lvx	v1,r4,r10
+	lvx	v0,r4,r11
+	addi	r4,r4,64
+	stvx	v3,0,r3
+	stvx	v2,r3,r9
+	stvx	v1,r3,r10
+	stvx	v0,r3,r11
+	addi	r3,r3,64
+
+9:	bf	cr7*4+2,10f
+	lvx	v1,0,r4
+	lvx	v0,r4,r9
+	addi	r4,r4,32
+	stvx	v1,0,r3
+	stvx	v0,r3,r9
+	addi	r3,r3,32
+
+10:	bf	cr7*4+3,11f
+	lvx	v1,0,r4
+	addi	r4,r4,16
+	stvx	v1,0,r3
+	addi	r3,r3,16
+
+	/* Up to 15B to go */
+11:	clrldi	r5,r5,(64-4)
+	mtocrf	0x01,r5
+	bf	cr7*4+0,12f
+	ld	r0,0(r4)
+	addi	r4,r4,8
+	std	r0,0(r3)
+	addi	r3,r3,8
+
+12:	bf	cr7*4+1,13f
+	lwz	r0,0(r4)
+	addi	r4,r4,4
+	stw	r0,0(r3)
+	addi	r3,r3,4
+
+13:	bf	cr7*4+2,14f
+	lhz	r0,0(r4)
+	addi	r4,r4,2
+	sth	r0,0(r3)
+	addi	r3,r3,2
+
+14:	bf	cr7*4+3,15f
+	lbz	r0,0(r4)
+	stb	r0,0(r3)
+
+15:	addi	r1,r1,STACKFRAMESIZE
+	ld	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
+	b	exit_vmx_ops		/* tail call optimise */
+
+.Lvmx_unaligned_copy:
+	/* Get the destination 16B aligned */
+	neg	r6,r3
+	mtocrf	0x01,r6
+	clrldi	r6,r6,(64-4)
+
+	bf	cr7*4+3,1f
+	lbz	r0,0(r4)
+	addi	r4,r4,1
+	stb	r0,0(r3)
+	addi	r3,r3,1
+
+1:	bf	cr7*4+2,2f
+	lhz	r0,0(r4)
+	addi	r4,r4,2
+	sth	r0,0(r3)
+	addi	r3,r3,2
+
+2:	bf	cr7*4+1,3f
+	lwz	r0,0(r4)
+	addi	r4,r4,4
+	stw	r0,0(r3)
+	addi	r3,r3,4
+
+3:	bf	cr7*4+0,4f
+	lwz	r0,0(r4)	/* Less chance of a reject with word ops */
+	lwz	r7,4(r4)
+	addi	r4,r4,8
+	stw	r0,0(r3)
+	stw	r7,4(r3)
+	addi	r3,r3,8
+
+4:	sub	r5,r5,r6
+
+	/* Get the desination 128B aligned */
+	neg	r6,r3
+	srdi	r7,r6,4
+	mtocrf	0x01,r7
+	clrldi	r6,r6,(64-7)
+
+	li	r9,16
+	li	r10,32
+	li	r11,48
+
+	LVS(v16,0,r4)		/* Setup permute control vector */
+	lvx	v0,0,r4
+	addi	r4,r4,16
+
+	bf	cr7*4+3,5f
+	lvx	v1,0,r4
+	VPERM(v8,v0,v1,v16)
+	addi	r4,r4,16
+	stvx	v8,0,r3
+	addi	r3,r3,16
+	vor	v0,v1,v1
+
+5:	bf	cr7*4+2,6f
+	lvx	v1,0,r4
+	VPERM(v8,v0,v1,v16)
+	lvx	v0,r4,r9
+	VPERM(v9,v1,v0,v16)
+	addi	r4,r4,32
+	stvx	v8,0,r3
+	stvx	v9,r3,r9
+	addi	r3,r3,32
+
+6:	bf	cr7*4+1,7f
+	lvx	v3,0,r4
+	VPERM(v8,v0,v3,v16)
+	lvx	v2,r4,r9
+	VPERM(v9,v3,v2,v16)
+	lvx	v1,r4,r10
+	VPERM(v10,v2,v1,v16)
+	lvx	v0,r4,r11
+	VPERM(v11,v1,v0,v16)
+	addi	r4,r4,64
+	stvx	v8,0,r3
+	stvx	v9,r3,r9
+	stvx	v10,r3,r10
+	stvx	v11,r3,r11
+	addi	r3,r3,64
+
+7:	sub	r5,r5,r6
+	srdi	r6,r5,7
+
+	std	r14,STK_REG(R14)(r1)
+	std	r15,STK_REG(R15)(r1)
+	std	r16,STK_REG(R16)(r1)
+
+	li	r12,64
+	li	r14,80
+	li	r15,96
+	li	r16,112
+
+	mtctr	r6
+
+	/*
+	 * Now do cacheline sized loads and stores. By this stage the
+	 * cacheline stores are also cacheline aligned.
+	 */
+	.align	5
+8:
+	lvx	v7,0,r4
+	VPERM(v8,v0,v7,v16)
+	lvx	v6,r4,r9
+	VPERM(v9,v7,v6,v16)
+	lvx	v5,r4,r10
+	VPERM(v10,v6,v5,v16)
+	lvx	v4,r4,r11
+	VPERM(v11,v5,v4,v16)
+	lvx	v3,r4,r12
+	VPERM(v12,v4,v3,v16)
+	lvx	v2,r4,r14
+	VPERM(v13,v3,v2,v16)
+	lvx	v1,r4,r15
+	VPERM(v14,v2,v1,v16)
+	lvx	v0,r4,r16
+	VPERM(v15,v1,v0,v16)
+	addi	r4,r4,128
+	stvx	v8,0,r3
+	stvx	v9,r3,r9
+	stvx	v10,r3,r10
+	stvx	v11,r3,r11
+	stvx	v12,r3,r12
+	stvx	v13,r3,r14
+	stvx	v14,r3,r15
+	stvx	v15,r3,r16
+	addi	r3,r3,128
+	bdnz	8b
+
+	ld	r14,STK_REG(R14)(r1)
+	ld	r15,STK_REG(R15)(r1)
+	ld	r16,STK_REG(R16)(r1)
+
+	/* Up to 127B to go */
+	clrldi	r5,r5,(64-7)
+	srdi	r6,r5,4
+	mtocrf	0x01,r6
+
+	bf	cr7*4+1,9f
+	lvx	v3,0,r4
+	VPERM(v8,v0,v3,v16)
+	lvx	v2,r4,r9
+	VPERM(v9,v3,v2,v16)
+	lvx	v1,r4,r10
+	VPERM(v10,v2,v1,v16)
+	lvx	v0,r4,r11
+	VPERM(v11,v1,v0,v16)
+	addi	r4,r4,64
+	stvx	v8,0,r3
+	stvx	v9,r3,r9
+	stvx	v10,r3,r10
+	stvx	v11,r3,r11
+	addi	r3,r3,64
+
+9:	bf	cr7*4+2,10f
+	lvx	v1,0,r4
+	VPERM(v8,v0,v1,v16)
+	lvx	v0,r4,r9
+	VPERM(v9,v1,v0,v16)
+	addi	r4,r4,32
+	stvx	v8,0,r3
+	stvx	v9,r3,r9
+	addi	r3,r3,32
+
+10:	bf	cr7*4+3,11f
+	lvx	v1,0,r4
+	VPERM(v8,v0,v1,v16)
+	addi	r4,r4,16
+	stvx	v8,0,r3
+	addi	r3,r3,16
+
+	/* Up to 15B to go */
+11:	clrldi	r5,r5,(64-4)
+	addi	r4,r4,-16	/* Unwind the +16 load offset */
+	mtocrf	0x01,r5
+	bf	cr7*4+0,12f
+	lwz	r0,0(r4)	/* Less chance of a reject with word ops */
+	lwz	r6,4(r4)
+	addi	r4,r4,8
+	stw	r0,0(r3)
+	stw	r6,4(r3)
+	addi	r3,r3,8
+
+12:	bf	cr7*4+1,13f
+	lwz	r0,0(r4)
+	addi	r4,r4,4
+	stw	r0,0(r3)
+	addi	r3,r3,4
+
+13:	bf	cr7*4+2,14f
+	lhz	r0,0(r4)
+	addi	r4,r4,2
+	sth	r0,0(r3)
+	addi	r3,r3,2
+
+14:	bf	cr7*4+3,15f
+	lbz	r0,0(r4)
+	stb	r0,0(r3)
+
+15:	addi	r1,r1,STACKFRAMESIZE
+	ld	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
+	b	exit_vmx_ops		/* tail call optimise */
+#endif /* CONFIG_ALTIVEC */
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-compat.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-compat.h
deleted file mode 120000
index b14255e..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-compat.h
+++ /dev/null
@@ -1 +0,0 @@
-../.././../../../../arch/powerpc/include/asm/asm-compat.h
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-compat.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-compat.h
new file mode 100644
index 0000000..19b70c5
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-compat.h
@@ -0,0 +1,62 @@
+#ifndef _ASM_POWERPC_ASM_COMPAT_H
+#define _ASM_POWERPC_ASM_COMPAT_H
+
+#include <asm/asm-const.h>
+#include <asm/types.h>
+#include <asm/ppc-opcode.h>
+
+#ifdef __powerpc64__
+
+/* operations for longs and pointers */
+#define PPC_LL		stringify_in_c(ld)
+#define PPC_STL		stringify_in_c(std)
+#define PPC_STLU	stringify_in_c(stdu)
+#define PPC_LCMPI	stringify_in_c(cmpdi)
+#define PPC_LCMPLI	stringify_in_c(cmpldi)
+#define PPC_LCMP	stringify_in_c(cmpd)
+#define PPC_LONG	stringify_in_c(.8byte)
+#define PPC_LONG_ALIGN	stringify_in_c(.balign 8)
+#define PPC_TLNEI	stringify_in_c(tdnei)
+#define PPC_LLARX(t, a, b, eh)	PPC_LDARX(t, a, b, eh)
+#define PPC_STLCX	stringify_in_c(stdcx.)
+#define PPC_CNTLZL	stringify_in_c(cntlzd)
+#define PPC_MTOCRF(FXM, RS) MTOCRF((FXM), RS)
+#define PPC_LR_STKOFF	16
+#define PPC_MIN_STKFRM	112
+
+#ifdef __BIG_ENDIAN__
+#define LHZX_BE	stringify_in_c(lhzx)
+#define LWZX_BE	stringify_in_c(lwzx)
+#define LDX_BE	stringify_in_c(ldx)
+#define STWX_BE	stringify_in_c(stwx)
+#define STDX_BE	stringify_in_c(stdx)
+#else
+#define LHZX_BE	stringify_in_c(lhbrx)
+#define LWZX_BE	stringify_in_c(lwbrx)
+#define LDX_BE	stringify_in_c(ldbrx)
+#define STWX_BE	stringify_in_c(stwbrx)
+#define STDX_BE	stringify_in_c(stdbrx)
+#endif
+
+#else /* 32-bit */
+
+/* operations for longs and pointers */
+#define PPC_LL		stringify_in_c(lwz)
+#define PPC_STL		stringify_in_c(stw)
+#define PPC_STLU	stringify_in_c(stwu)
+#define PPC_LCMPI	stringify_in_c(cmpwi)
+#define PPC_LCMPLI	stringify_in_c(cmplwi)
+#define PPC_LCMP	stringify_in_c(cmpw)
+#define PPC_LONG	stringify_in_c(.long)
+#define PPC_LONG_ALIGN	stringify_in_c(.balign 4)
+#define PPC_TLNEI	stringify_in_c(twnei)
+#define PPC_LLARX(t, a, b, eh)	PPC_LWARX(t, a, b, eh)
+#define PPC_STLCX	stringify_in_c(stwcx.)
+#define PPC_CNTLZL	stringify_in_c(cntlzw)
+#define PPC_MTOCRF	stringify_in_c(mtcrf)
+#define PPC_LR_STKOFF	4
+#define PPC_MIN_STKFRM	16
+
+#endif
+
+#endif /* _ASM_POWERPC_ASM_COMPAT_H */
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-const.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-const.h
deleted file mode 120000
index 18d8be1..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-const.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../arch/powerpc/include/asm/asm-const.h
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-const.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-const.h
new file mode 100644
index 0000000..082c153
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/asm-const.h
@@ -0,0 +1,14 @@
+#ifndef _ASM_POWERPC_ASM_CONST_H
+#define _ASM_POWERPC_ASM_CONST_H
+
+#ifdef __ASSEMBLY__
+#  define stringify_in_c(...)	__VA_ARGS__
+#  define ASM_CONST(x)		x
+#else
+/* This version of stringify will deal with commas... */
+#  define __stringify_in_c(...)	#__VA_ARGS__
+#  define stringify_in_c(...)	__stringify_in_c(__VA_ARGS__) " "
+#  define __ASM_CONST(x)	x##UL
+#  define ASM_CONST(x)		__ASM_CONST(x)
+#endif
+#endif /* _ASM_POWERPC_ASM_CONST_H */
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/feature-fixups.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/feature-fixups.h
deleted file mode 120000
index 8dc6d4d..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/feature-fixups.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../arch/powerpc/include/asm/feature-fixups.h
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/feature-fixups.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/feature-fixups.h
new file mode 100644
index 0000000..40a6c92
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/feature-fixups.h
@@ -0,0 +1,250 @@
+#ifndef __ASM_POWERPC_FEATURE_FIXUPS_H
+#define __ASM_POWERPC_FEATURE_FIXUPS_H
+
+#include <asm/asm-const.h>
+
+/*
+ * 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.
+ */
+
+/*
+ * Feature section common macros
+ *
+ * Note that the entries now contain offsets between the table entry
+ * and the code rather than absolute code pointers in order to be
+ * useable with the vdso shared library. There is also an assumption
+ * that values will be negative, that is, the fixup table has to be
+ * located after the code it fixes up.
+ */
+#if defined(CONFIG_PPC64) && !defined(__powerpc64__)
+/* 64 bits kernel, 32 bits code (ie. vdso32) */
+#define FTR_ENTRY_LONG		.8byte
+#define FTR_ENTRY_OFFSET	.long 0xffffffff; .long
+#elif defined(CONFIG_PPC64)
+#define FTR_ENTRY_LONG		.8byte
+#define FTR_ENTRY_OFFSET	.8byte
+#else
+#define FTR_ENTRY_LONG		.long
+#define FTR_ENTRY_OFFSET	.long
+#endif
+
+#define START_FTR_SECTION(label)	label##1:
+
+#define FTR_SECTION_ELSE_NESTED(label)			\
+label##2:						\
+	.pushsection __ftr_alt_##label,"a";		\
+	.align 2;					\
+label##3:
+
+#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect)		\
+label##4:							\
+	.popsection;						\
+	.pushsection sect,"a";					\
+	.align 3;						\
+label##5:							\
+	FTR_ENTRY_LONG msk;					\
+	FTR_ENTRY_LONG val;					\
+	FTR_ENTRY_OFFSET label##1b-label##5b;			\
+	FTR_ENTRY_OFFSET label##2b-label##5b;			\
+	FTR_ENTRY_OFFSET label##3b-label##5b;			\
+	FTR_ENTRY_OFFSET label##4b-label##5b;			\
+	.ifgt (label##4b- label##3b)-(label##2b- label##1b);	\
+	.error "Feature section else case larger than body";	\
+	.endif;							\
+	.popsection;
+
+
+/* CPU feature dependent sections */
+#define BEGIN_FTR_SECTION_NESTED(label)	START_FTR_SECTION(label)
+#define BEGIN_FTR_SECTION		START_FTR_SECTION(97)
+
+#define END_FTR_SECTION_NESTED(msk, val, label) 		\
+	FTR_SECTION_ELSE_NESTED(label)				\
+	MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup)
+
+#define END_FTR_SECTION(msk, val)		\
+	END_FTR_SECTION_NESTED(msk, val, 97)
+
+#define END_FTR_SECTION_NESTED_IFSET(msk, label)	\
+	END_FTR_SECTION_NESTED((msk), (msk), label)
+
+#define END_FTR_SECTION_IFSET(msk)	END_FTR_SECTION((msk), (msk))
+#define END_FTR_SECTION_IFCLR(msk)	END_FTR_SECTION((msk), 0)
+
+/* CPU feature sections with alternatives, use BEGIN_FTR_SECTION to start */
+#define FTR_SECTION_ELSE	FTR_SECTION_ELSE_NESTED(97)
+#define ALT_FTR_SECTION_END_NESTED(msk, val, label)	\
+	MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup)
+#define ALT_FTR_SECTION_END_NESTED_IFSET(msk, label)	\
+	ALT_FTR_SECTION_END_NESTED(msk, msk, label)
+#define ALT_FTR_SECTION_END_NESTED_IFCLR(msk, label)	\
+	ALT_FTR_SECTION_END_NESTED(msk, 0, label)
+#define ALT_FTR_SECTION_END(msk, val)	\
+	ALT_FTR_SECTION_END_NESTED(msk, val, 97)
+#define ALT_FTR_SECTION_END_IFSET(msk)	\
+	ALT_FTR_SECTION_END_NESTED_IFSET(msk, 97)
+#define ALT_FTR_SECTION_END_IFCLR(msk)	\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(msk, 97)
+
+/* MMU feature dependent sections */
+#define BEGIN_MMU_FTR_SECTION_NESTED(label)	START_FTR_SECTION(label)
+#define BEGIN_MMU_FTR_SECTION			START_FTR_SECTION(97)
+
+#define END_MMU_FTR_SECTION_NESTED(msk, val, label) 		\
+	FTR_SECTION_ELSE_NESTED(label)				\
+	MAKE_FTR_SECTION_ENTRY(msk, val, label, __mmu_ftr_fixup)
+
+#define END_MMU_FTR_SECTION(msk, val)		\
+	END_MMU_FTR_SECTION_NESTED(msk, val, 97)
+
+#define END_MMU_FTR_SECTION_IFSET(msk)	END_MMU_FTR_SECTION((msk), (msk))
+#define END_MMU_FTR_SECTION_IFCLR(msk)	END_MMU_FTR_SECTION((msk), 0)
+
+/* MMU feature sections with alternatives, use BEGIN_FTR_SECTION to start */
+#define MMU_FTR_SECTION_ELSE_NESTED(label)	FTR_SECTION_ELSE_NESTED(label)
+#define MMU_FTR_SECTION_ELSE	MMU_FTR_SECTION_ELSE_NESTED(97)
+#define ALT_MMU_FTR_SECTION_END_NESTED(msk, val, label)	\
+	MAKE_FTR_SECTION_ENTRY(msk, val, label, __mmu_ftr_fixup)
+#define ALT_MMU_FTR_SECTION_END_NESTED_IFSET(msk, label)	\
+	ALT_MMU_FTR_SECTION_END_NESTED(msk, msk, label)
+#define ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(msk, label)	\
+	ALT_MMU_FTR_SECTION_END_NESTED(msk, 0, label)
+#define ALT_MMU_FTR_SECTION_END(msk, val)	\
+	ALT_MMU_FTR_SECTION_END_NESTED(msk, val, 97)
+#define ALT_MMU_FTR_SECTION_END_IFSET(msk)	\
+	ALT_MMU_FTR_SECTION_END_NESTED_IFSET(msk, 97)
+#define ALT_MMU_FTR_SECTION_END_IFCLR(msk)	\
+	ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(msk, 97)
+
+/* Firmware feature dependent sections */
+#define BEGIN_FW_FTR_SECTION_NESTED(label)	START_FTR_SECTION(label)
+#define BEGIN_FW_FTR_SECTION			START_FTR_SECTION(97)
+
+#define END_FW_FTR_SECTION_NESTED(msk, val, label) 		\
+	FTR_SECTION_ELSE_NESTED(label)				\
+	MAKE_FTR_SECTION_ENTRY(msk, val, label, __fw_ftr_fixup)
+
+#define END_FW_FTR_SECTION(msk, val)		\
+	END_FW_FTR_SECTION_NESTED(msk, val, 97)
+
+#define END_FW_FTR_SECTION_IFSET(msk)	END_FW_FTR_SECTION((msk), (msk))
+#define END_FW_FTR_SECTION_IFCLR(msk)	END_FW_FTR_SECTION((msk), 0)
+
+/* Firmware feature sections with alternatives */
+#define FW_FTR_SECTION_ELSE_NESTED(label)	FTR_SECTION_ELSE_NESTED(label)
+#define FW_FTR_SECTION_ELSE	FTR_SECTION_ELSE_NESTED(97)
+#define ALT_FW_FTR_SECTION_END_NESTED(msk, val, label)	\
+	MAKE_FTR_SECTION_ENTRY(msk, val, label, __fw_ftr_fixup)
+#define ALT_FW_FTR_SECTION_END_NESTED_IFSET(msk, label)	\
+	ALT_FW_FTR_SECTION_END_NESTED(msk, msk, label)
+#define ALT_FW_FTR_SECTION_END_NESTED_IFCLR(msk, label)	\
+	ALT_FW_FTR_SECTION_END_NESTED(msk, 0, label)
+#define ALT_FW_FTR_SECTION_END(msk, val)	\
+	ALT_FW_FTR_SECTION_END_NESTED(msk, val, 97)
+#define ALT_FW_FTR_SECTION_END_IFSET(msk)	\
+	ALT_FW_FTR_SECTION_END_NESTED_IFSET(msk, 97)
+#define ALT_FW_FTR_SECTION_END_IFCLR(msk)	\
+	ALT_FW_FTR_SECTION_END_NESTED_IFCLR(msk, 97)
+
+#ifndef __ASSEMBLY__
+
+#define ASM_FTR_IF(section_if, section_else, msk, val)	\
+	stringify_in_c(BEGIN_FTR_SECTION)			\
+	section_if "; "						\
+	stringify_in_c(FTR_SECTION_ELSE)			\
+	section_else "; "					\
+	stringify_in_c(ALT_FTR_SECTION_END((msk), (val)))
+
+#define ASM_FTR_IFSET(section_if, section_else, msk)	\
+	ASM_FTR_IF(section_if, section_else, (msk), (msk))
+
+#define ASM_FTR_IFCLR(section_if, section_else, msk)	\
+	ASM_FTR_IF(section_if, section_else, (msk), 0)
+
+#define ASM_MMU_FTR_IF(section_if, section_else, msk, val)	\
+	stringify_in_c(BEGIN_MMU_FTR_SECTION)			\
+	section_if "; "						\
+	stringify_in_c(MMU_FTR_SECTION_ELSE)			\
+	section_else "; "					\
+	stringify_in_c(ALT_MMU_FTR_SECTION_END((msk), (val)))
+
+#define ASM_MMU_FTR_IFSET(section_if, section_else, msk)	\
+	ASM_MMU_FTR_IF(section_if, section_else, (msk), (msk))
+
+#define ASM_MMU_FTR_IFCLR(section_if, section_else, msk)	\
+	ASM_MMU_FTR_IF(section_if, section_else, (msk), 0)
+
+#endif /* __ASSEMBLY__ */
+
+/* LWSYNC feature sections */
+#define START_LWSYNC_SECTION(label)	label##1:
+#define MAKE_LWSYNC_SECTION_ENTRY(label, sect)		\
+label##2:						\
+	.pushsection sect,"a";				\
+	.align 2;					\
+label##3:					       	\
+	FTR_ENTRY_OFFSET label##1b-label##3b;		\
+	.popsection;
+
+#define STF_ENTRY_BARRIER_FIXUP_SECTION			\
+953:							\
+	.pushsection __stf_entry_barrier_fixup,"a";	\
+	.align 2;					\
+954:							\
+	FTR_ENTRY_OFFSET 953b-954b;			\
+	.popsection;
+
+#define STF_EXIT_BARRIER_FIXUP_SECTION			\
+955:							\
+	.pushsection __stf_exit_barrier_fixup,"a";	\
+	.align 2;					\
+956:							\
+	FTR_ENTRY_OFFSET 955b-956b;			\
+	.popsection;
+
+#define RFI_FLUSH_FIXUP_SECTION				\
+951:							\
+	.pushsection __rfi_flush_fixup,"a";		\
+	.align 2;					\
+952:							\
+	FTR_ENTRY_OFFSET 951b-952b;			\
+	.popsection;
+
+#define NOSPEC_BARRIER_FIXUP_SECTION			\
+953:							\
+	.pushsection __barrier_nospec_fixup,"a";	\
+	.align 2;					\
+954:							\
+	FTR_ENTRY_OFFSET 953b-954b;			\
+	.popsection;
+
+#define START_BTB_FLUSH_SECTION			\
+955:							\
+
+#define END_BTB_FLUSH_SECTION			\
+956:							\
+	.pushsection __btb_flush_fixup,"a";	\
+	.align 2;							\
+957:						\
+	FTR_ENTRY_OFFSET 955b-957b;			\
+	FTR_ENTRY_OFFSET 956b-957b;			\
+	.popsection;
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+extern long stf_barrier_fallback;
+extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup;
+extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
+extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
+extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup;
+extern long __start__btb_flush_fixup, __stop__btb_flush_fixup;
+
+void apply_feature_fixups(void);
+void setup_feature_keys(void);
+#endif
+
+#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/ppc_asm.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/ppc_asm.h
deleted file mode 120000
index 66c8193..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/ppc_asm.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../arch/powerpc/include/asm/ppc_asm.h
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/ppc_asm.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/ppc_asm.h
new file mode 100644
index 0000000..5c901bf
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/asm/ppc_asm.h
@@ -0,0 +1,834 @@
+/*
+ * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
+ */
+#ifndef _ASM_POWERPC_PPC_ASM_H
+#define _ASM_POWERPC_PPC_ASM_H
+
+#include <linux/stringify.h>
+#include <asm/asm-compat.h>
+#include <asm/processor.h>
+#include <asm/ppc-opcode.h>
+#include <asm/firmware.h>
+#include <asm/feature-fixups.h>
+
+#ifdef __ASSEMBLY__
+
+#define SZL			(BITS_PER_LONG/8)
+
+/*
+ * Stuff for accurate CPU time accounting.
+ * These macros handle transitions between user and system state
+ * in exception entry and exit and accumulate time to the
+ * user_time and system_time fields in the paca.
+ */
+
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb)
+#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb)
+#define ACCOUNT_STOLEN_TIME
+#else
+#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb)				\
+	MFTB(ra);			/* get timebase */		\
+	PPC_LL	rb, ACCOUNT_STARTTIME_USER(ptr);			\
+	PPC_STL	ra, ACCOUNT_STARTTIME(ptr);				\
+	subf	rb,rb,ra;		/* subtract start value */	\
+	PPC_LL	ra, ACCOUNT_USER_TIME(ptr);				\
+	add	ra,ra,rb;		/* add on to user time */	\
+	PPC_STL	ra, ACCOUNT_USER_TIME(ptr);				\
+
+#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb)				\
+	MFTB(ra);			/* get timebase */		\
+	PPC_LL	rb, ACCOUNT_STARTTIME(ptr);				\
+	PPC_STL	ra, ACCOUNT_STARTTIME_USER(ptr);			\
+	subf	rb,rb,ra;		/* subtract start value */	\
+	PPC_LL	ra, ACCOUNT_SYSTEM_TIME(ptr);				\
+	add	ra,ra,rb;		/* add on to system time */	\
+	PPC_STL	ra, ACCOUNT_SYSTEM_TIME(ptr)
+
+#ifdef CONFIG_PPC_SPLPAR
+#define ACCOUNT_STOLEN_TIME						\
+BEGIN_FW_FTR_SECTION;							\
+	beq	33f;							\
+	/* from user - see if there are any DTL entries to process */	\
+	ld	r10,PACALPPACAPTR(r13);	/* get ptr to VPA */		\
+	ld	r11,PACA_DTL_RIDX(r13);	/* get log read index */	\
+	addi	r10,r10,LPPACA_DTLIDX;					\
+	LDX_BE	r10,0,r10;		/* get log write index */	\
+	cmpd	cr1,r11,r10;						\
+	beq+	cr1,33f;						\
+	bl	accumulate_stolen_time;				\
+	ld	r12,_MSR(r1);						\
+	andi.	r10,r12,MSR_PR;		/* Restore cr0 (coming from user) */ \
+33:									\
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
+
+#else  /* CONFIG_PPC_SPLPAR */
+#define ACCOUNT_STOLEN_TIME
+
+#endif /* CONFIG_PPC_SPLPAR */
+
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+
+/*
+ * Macros for storing registers into and loading registers from
+ * exception frames.
+ */
+#ifdef __powerpc64__
+#define SAVE_GPR(n, base)	std	n,GPR0+8*(n)(base)
+#define REST_GPR(n, base)	ld	n,GPR0+8*(n)(base)
+#define SAVE_NVGPRS(base)	SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
+#define REST_NVGPRS(base)	REST_8GPRS(14, base); REST_10GPRS(22, base)
+#else
+#define SAVE_GPR(n, base)	stw	n,GPR0+4*(n)(base)
+#define REST_GPR(n, base)	lwz	n,GPR0+4*(n)(base)
+#define SAVE_NVGPRS(base)	stmw	13, GPR0+4*13(base)
+#define REST_NVGPRS(base)	lmw	13, GPR0+4*13(base)
+#endif
+
+#define SAVE_2GPRS(n, base)	SAVE_GPR(n, base); SAVE_GPR(n+1, base)
+#define SAVE_4GPRS(n, base)	SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
+#define SAVE_8GPRS(n, base)	SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
+#define SAVE_10GPRS(n, base)	SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
+#define REST_2GPRS(n, base)	REST_GPR(n, base); REST_GPR(n+1, base)
+#define REST_4GPRS(n, base)	REST_2GPRS(n, base); REST_2GPRS(n+2, base)
+#define REST_8GPRS(n, base)	REST_4GPRS(n, base); REST_4GPRS(n+4, base)
+#define REST_10GPRS(n, base)	REST_8GPRS(n, base); REST_2GPRS(n+8, base)
+
+#define SAVE_FPR(n, base)	stfd	n,8*TS_FPRWIDTH*(n)(base)
+#define SAVE_2FPRS(n, base)	SAVE_FPR(n, base); SAVE_FPR(n+1, base)
+#define SAVE_4FPRS(n, base)	SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
+#define SAVE_8FPRS(n, base)	SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
+#define SAVE_16FPRS(n, base)	SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
+#define SAVE_32FPRS(n, base)	SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
+#define REST_FPR(n, base)	lfd	n,8*TS_FPRWIDTH*(n)(base)
+#define REST_2FPRS(n, base)	REST_FPR(n, base); REST_FPR(n+1, base)
+#define REST_4FPRS(n, base)	REST_2FPRS(n, base); REST_2FPRS(n+2, base)
+#define REST_8FPRS(n, base)	REST_4FPRS(n, base); REST_4FPRS(n+4, base)
+#define REST_16FPRS(n, base)	REST_8FPRS(n, base); REST_8FPRS(n+8, base)
+#define REST_32FPRS(n, base)	REST_16FPRS(n, base); REST_16FPRS(n+16, base)
+
+#define SAVE_VR(n,b,base)	li b,16*(n);  stvx n,base,b
+#define SAVE_2VRS(n,b,base)	SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
+#define SAVE_4VRS(n,b,base)	SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
+#define SAVE_8VRS(n,b,base)	SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
+#define SAVE_16VRS(n,b,base)	SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
+#define SAVE_32VRS(n,b,base)	SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
+#define REST_VR(n,b,base)	li b,16*(n); lvx n,base,b
+#define REST_2VRS(n,b,base)	REST_VR(n,b,base); REST_VR(n+1,b,base)
+#define REST_4VRS(n,b,base)	REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
+#define REST_8VRS(n,b,base)	REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
+#define REST_16VRS(n,b,base)	REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
+#define REST_32VRS(n,b,base)	REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
+
+#ifdef __BIG_ENDIAN__
+#define STXVD2X_ROT(n,b,base)		STXVD2X(n,b,base)
+#define LXVD2X_ROT(n,b,base)		LXVD2X(n,b,base)
+#else
+#define STXVD2X_ROT(n,b,base)		XXSWAPD(n,n);		\
+					STXVD2X(n,b,base);	\
+					XXSWAPD(n,n)
+
+#define LXVD2X_ROT(n,b,base)		LXVD2X(n,b,base);	\
+					XXSWAPD(n,n)
+#endif
+/* Save the lower 32 VSRs in the thread VSR region */
+#define SAVE_VSR(n,b,base)	li b,16*(n);  STXVD2X_ROT(n,R##base,R##b)
+#define SAVE_2VSRS(n,b,base)	SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base)
+#define SAVE_4VSRS(n,b,base)	SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base)
+#define SAVE_8VSRS(n,b,base)	SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base)
+#define SAVE_16VSRS(n,b,base)	SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base)
+#define SAVE_32VSRS(n,b,base)	SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base)
+#define REST_VSR(n,b,base)	li b,16*(n); LXVD2X_ROT(n,R##base,R##b)
+#define REST_2VSRS(n,b,base)	REST_VSR(n,b,base); REST_VSR(n+1,b,base)
+#define REST_4VSRS(n,b,base)	REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base)
+#define REST_8VSRS(n,b,base)	REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base)
+#define REST_16VSRS(n,b,base)	REST_8VSRS(n,b,base); REST_8VSRS(n+8,b,base)
+#define REST_32VSRS(n,b,base)	REST_16VSRS(n,b,base); REST_16VSRS(n+16,b,base)
+
+/*
+ * b = base register for addressing, o = base offset from register of 1st EVR
+ * n = first EVR, s = scratch
+ */
+#define SAVE_EVR(n,s,b,o)	evmergehi s,s,n; stw s,o+4*(n)(b)
+#define SAVE_2EVRS(n,s,b,o)	SAVE_EVR(n,s,b,o); SAVE_EVR(n+1,s,b,o)
+#define SAVE_4EVRS(n,s,b,o)	SAVE_2EVRS(n,s,b,o); SAVE_2EVRS(n+2,s,b,o)
+#define SAVE_8EVRS(n,s,b,o)	SAVE_4EVRS(n,s,b,o); SAVE_4EVRS(n+4,s,b,o)
+#define SAVE_16EVRS(n,s,b,o)	SAVE_8EVRS(n,s,b,o); SAVE_8EVRS(n+8,s,b,o)
+#define SAVE_32EVRS(n,s,b,o)	SAVE_16EVRS(n,s,b,o); SAVE_16EVRS(n+16,s,b,o)
+#define REST_EVR(n,s,b,o)	lwz s,o+4*(n)(b); evmergelo n,s,n
+#define REST_2EVRS(n,s,b,o)	REST_EVR(n,s,b,o); REST_EVR(n+1,s,b,o)
+#define REST_4EVRS(n,s,b,o)	REST_2EVRS(n,s,b,o); REST_2EVRS(n+2,s,b,o)
+#define REST_8EVRS(n,s,b,o)	REST_4EVRS(n,s,b,o); REST_4EVRS(n+4,s,b,o)
+#define REST_16EVRS(n,s,b,o)	REST_8EVRS(n,s,b,o); REST_8EVRS(n+8,s,b,o)
+#define REST_32EVRS(n,s,b,o)	REST_16EVRS(n,s,b,o); REST_16EVRS(n+16,s,b,o)
+
+/* Macros to adjust thread priority for hardware multithreading */
+#define HMT_VERY_LOW	or	31,31,31	# very low priority
+#define HMT_LOW		or	1,1,1
+#define HMT_MEDIUM_LOW  or	6,6,6		# medium low priority
+#define HMT_MEDIUM	or	2,2,2
+#define HMT_MEDIUM_HIGH or	5,5,5		# medium high priority
+#define HMT_HIGH	or	3,3,3
+#define HMT_EXTRA_HIGH	or	7,7,7		# power7 only
+
+#ifdef CONFIG_PPC64
+#define ULONG_SIZE 	8
+#else
+#define ULONG_SIZE	4
+#endif
+#define __VCPU_GPR(n)	(VCPU_GPRS + (n * ULONG_SIZE))
+#define VCPU_GPR(n)	__VCPU_GPR(__REG_##n)
+
+#ifdef __KERNEL__
+#ifdef CONFIG_PPC64
+
+#define STACKFRAMESIZE 256
+#define __STK_REG(i)   (112 + ((i)-14)*8)
+#define STK_REG(i)     __STK_REG(__REG_##i)
+
+#ifdef PPC64_ELF_ABI_v2
+#define STK_GOT		24
+#define __STK_PARAM(i)	(32 + ((i)-3)*8)
+#else
+#define STK_GOT		40
+#define __STK_PARAM(i)	(48 + ((i)-3)*8)
+#endif
+#define STK_PARAM(i)	__STK_PARAM(__REG_##i)
+
+#ifdef PPC64_ELF_ABI_v2
+
+#define _GLOBAL(name) \
+	.align 2 ; \
+	.type name,@function; \
+	.globl name; \
+name:
+
+#define _GLOBAL_TOC(name) \
+	.align 2 ; \
+	.type name,@function; \
+	.globl name; \
+name: \
+0:	addis r2,r12,(.TOC.-0b)@ha; \
+	addi r2,r2,(.TOC.-0b)@l; \
+	.localentry name,.-name
+
+#define DOTSYM(a)	a
+
+#else
+
+#define XGLUE(a,b) a##b
+#define GLUE(a,b) XGLUE(a,b)
+
+#define _GLOBAL(name) \
+	.align 2 ; \
+	.globl name; \
+	.globl GLUE(.,name); \
+	.pushsection ".opd","aw"; \
+name: \
+	.quad GLUE(.,name); \
+	.quad .TOC.@tocbase; \
+	.quad 0; \
+	.popsection; \
+	.type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _GLOBAL_TOC(name) _GLOBAL(name)
+
+#define DOTSYM(a)	GLUE(.,a)
+
+#endif
+
+#else /* 32-bit */
+
+#define _ENTRY(n)	\
+	.globl n;	\
+n:
+
+#define _GLOBAL(n)	\
+	.stabs __stringify(n:F-1),N_FUN,0,0,n;\
+	.globl n;	\
+n:
+
+#define _GLOBAL_TOC(name) _GLOBAL(name)
+
+#endif
+
+/*
+ * __kprobes (the C annotation) puts the symbol into the .kprobes.text
+ * section, which gets emitted at the end of regular text.
+ *
+ * _ASM_NOKPROBE_SYMBOL and NOKPROBE_SYMBOL just adds the symbol to
+ * a blacklist. The former is for core kprobe functions/data, the
+ * latter is for those that incdentially must be excluded from probing
+ * and allows them to be linked at more optimal location within text.
+ */
+#ifdef CONFIG_KPROBES
+#define _ASM_NOKPROBE_SYMBOL(entry)			\
+	.pushsection "_kprobe_blacklist","aw";		\
+	PPC_LONG (entry) ;				\
+	.popsection
+#else
+#define _ASM_NOKPROBE_SYMBOL(entry)
+#endif
+
+#define FUNC_START(name)	_GLOBAL(name)
+#define FUNC_END(name)
+
+/* 
+ * LOAD_REG_IMMEDIATE(rn, expr)
+ *   Loads the value of the constant expression 'expr' into register 'rn'
+ *   using immediate instructions only.  Use this when it's important not
+ *   to reference other data (i.e. on ppc64 when the TOC pointer is not
+ *   valid) and when 'expr' is a constant or absolute address.
+ *
+ * LOAD_REG_ADDR(rn, name)
+ *   Loads the address of label 'name' into register 'rn'.  Use this when
+ *   you don't particularly need immediate instructions only, but you need
+ *   the whole address in one register (e.g. it's a structure address and
+ *   you want to access various offsets within it).  On ppc32 this is
+ *   identical to LOAD_REG_IMMEDIATE.
+ *
+ * LOAD_REG_ADDR_PIC(rn, name)
+ *   Loads the address of label 'name' into register 'run'. Use this when
+ *   the kernel doesn't run at the linked or relocated address. Please
+ *   note that this macro will clobber the lr register.
+ *
+ * LOAD_REG_ADDRBASE(rn, name)
+ * ADDROFF(name)
+ *   LOAD_REG_ADDRBASE loads part of the address of label 'name' into
+ *   register 'rn'.  ADDROFF(name) returns the remainder of the address as
+ *   a constant expression.  ADDROFF(name) is a signed expression < 16 bits
+ *   in size, so is suitable for use directly as an offset in load and store
+ *   instructions.  Use this when loading/storing a single word or less as:
+ *      LOAD_REG_ADDRBASE(rX, name)
+ *      ld	rY,ADDROFF(name)(rX)
+ */
+
+/* Be careful, this will clobber the lr register. */
+#define LOAD_REG_ADDR_PIC(reg, name)		\
+	bl	0f;				\
+0:	mflr	reg;				\
+	addis	reg,reg,(name - 0b)@ha;		\
+	addi	reg,reg,(name - 0b)@l;
+
+#ifdef __powerpc64__
+#ifdef HAVE_AS_ATHIGH
+#define __AS_ATHIGH high
+#else
+#define __AS_ATHIGH h
+#endif
+#define LOAD_REG_IMMEDIATE(reg,expr)		\
+	lis     reg,(expr)@highest;		\
+	ori     reg,reg,(expr)@higher;	\
+	rldicr  reg,reg,32,31;		\
+	oris    reg,reg,(expr)@__AS_ATHIGH;	\
+	ori     reg,reg,(expr)@l;
+
+#define LOAD_REG_ADDR(reg,name)			\
+	ld	reg,name@got(r2)
+
+#define LOAD_REG_ADDRBASE(reg,name)	LOAD_REG_ADDR(reg,name)
+#define ADDROFF(name)			0
+
+/* offsets for stack frame layout */
+#define LRSAVE	16
+
+#else /* 32-bit */
+
+#define LOAD_REG_IMMEDIATE(reg,expr)		\
+	lis	reg,(expr)@ha;		\
+	addi	reg,reg,(expr)@l;
+
+#define LOAD_REG_ADDR(reg,name)		LOAD_REG_IMMEDIATE(reg, name)
+
+#define LOAD_REG_ADDRBASE(reg, name)	lis	reg,name@ha
+#define ADDROFF(name)			name@l
+
+/* offsets for stack frame layout */
+#define LRSAVE	4
+
+#endif
+
+/* various errata or part fixups */
+#ifdef CONFIG_PPC601_SYNC_FIX
+#define SYNC				\
+BEGIN_FTR_SECTION			\
+	sync;				\
+	isync;				\
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+#define SYNC_601			\
+BEGIN_FTR_SECTION			\
+	sync;				\
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+#define ISYNC_601			\
+BEGIN_FTR_SECTION			\
+	isync;				\
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+#else
+#define	SYNC
+#define SYNC_601
+#define ISYNC_601
+#endif
+
+#if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E)
+#define MFTB(dest)			\
+90:	mfspr dest, SPRN_TBRL;		\
+BEGIN_FTR_SECTION_NESTED(96);		\
+	cmpwi dest,0;			\
+	beq-  90b;			\
+END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
+#else
+#define MFTB(dest)			MFTBL(dest)
+#endif
+
+#ifdef CONFIG_PPC_8xx
+#define MFTBL(dest)			mftb dest
+#define MFTBU(dest)			mftbu dest
+#else
+#define MFTBL(dest)			mfspr dest, SPRN_TBRL
+#define MFTBU(dest)			mfspr dest, SPRN_TBRU
+#endif
+
+#ifndef CONFIG_SMP
+#define TLBSYNC
+#else /* CONFIG_SMP */
+/* tlbsync is not implemented on 601 */
+#define TLBSYNC				\
+BEGIN_FTR_SECTION			\
+	tlbsync;			\
+	sync;				\
+END_FTR_SECTION_IFCLR(CPU_FTR_601)
+#endif
+
+#ifdef CONFIG_PPC64
+#define MTOCRF(FXM, RS)			\
+	BEGIN_FTR_SECTION_NESTED(848);	\
+	mtcrf	(FXM), RS;		\
+	FTR_SECTION_ELSE_NESTED(848);	\
+	mtocrf (FXM), RS;		\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_NOEXECUTE, 848)
+#endif
+
+/*
+ * This instruction is not implemented on the PPC 603 or 601; however, on
+ * the 403GCX and 405GP tlbia IS defined and tlbie is not.
+ * All of these instructions exist in the 8xx, they have magical powers,
+ * and they must be used.
+ */
+
+#if !defined(CONFIG_4xx) && !defined(CONFIG_PPC_8xx)
+#define tlbia					\
+	li	r4,1024;			\
+	mtctr	r4;				\
+	lis	r4,KERNELBASE@h;		\
+	.machine push;				\
+	.machine "power4";			\
+0:	tlbie	r4;				\
+	.machine pop;				\
+	addi	r4,r4,0x1000;			\
+	bdnz	0b
+#endif
+
+
+#ifdef CONFIG_IBM440EP_ERR42
+#define PPC440EP_ERR42 isync
+#else
+#define PPC440EP_ERR42
+#endif
+
+/* The following stops all load and store data streams associated with stream
+ * ID (ie. streams created explicitly).  The embedded and server mnemonics for
+ * dcbt are different so this must only be used for server.
+ */
+#define DCBT_BOOK3S_STOP_ALL_STREAM_IDS(scratch)	\
+       lis     scratch,0x60000000@h;			\
+       dcbt    0,scratch,0b01010
+
+/*
+ * toreal/fromreal/tophys/tovirt macros. 32-bit BookE makes them
+ * keep the address intact to be compatible with code shared with
+ * 32-bit classic.
+ *
+ * On the other hand, I find it useful to have them behave as expected
+ * by their name (ie always do the addition) on 64-bit BookE
+ */
+#if defined(CONFIG_BOOKE) && !defined(CONFIG_PPC64)
+#define toreal(rd)
+#define fromreal(rd)
+
+/*
+ * We use addis to ensure compatibility with the "classic" ppc versions of
+ * these macros, which use rs = 0 to get the tophys offset in rd, rather than
+ * converting the address in r0, and so this version has to do that too
+ * (i.e. set register rd to 0 when rs == 0).
+ */
+#define tophys(rd,rs)				\
+	addis	rd,rs,0
+
+#define tovirt(rd,rs)				\
+	addis	rd,rs,0
+
+#elif defined(CONFIG_PPC64)
+#define toreal(rd)		/* we can access c000... in real mode */
+#define fromreal(rd)
+
+#define tophys(rd,rs)                           \
+	clrldi	rd,rs,2
+
+#define tovirt(rd,rs)                           \
+	rotldi	rd,rs,16;			\
+	ori	rd,rd,((KERNELBASE>>48)&0xFFFF);\
+	rotldi	rd,rd,48
+#else
+/*
+ * On APUS (Amiga PowerPC cpu upgrade board), we don't know the
+ * physical base address of RAM at compile time.
+ */
+#define toreal(rd)	tophys(rd,rd)
+#define fromreal(rd)	tovirt(rd,rd)
+
+#define tophys(rd,rs)				\
+0:	addis	rd,rs,-PAGE_OFFSET@h;		\
+	.section ".vtop_fixup","aw";		\
+	.align  1;				\
+	.long   0b;				\
+	.previous
+
+#define tovirt(rd,rs)				\
+0:	addis	rd,rs,PAGE_OFFSET@h;		\
+	.section ".ptov_fixup","aw";		\
+	.align  1;				\
+	.long   0b;				\
+	.previous
+#endif
+
+#ifdef CONFIG_PPC_BOOK3S_64
+#define RFI		rfid
+#define MTMSRD(r)	mtmsrd	r
+#define MTMSR_EERI(reg)	mtmsrd	reg,1
+#else
+#ifndef CONFIG_40x
+#define	RFI		rfi
+#else
+#define RFI		rfi; b .	/* Prevent prefetch past rfi */
+#endif
+#define MTMSRD(r)	mtmsr	r
+#define MTMSR_EERI(reg)	mtmsr	reg
+#endif
+
+#endif /* __KERNEL__ */
+
+/* The boring bits... */
+
+/* Condition Register Bit Fields */
+
+#define	cr0	0
+#define	cr1	1
+#define	cr2	2
+#define	cr3	3
+#define	cr4	4
+#define	cr5	5
+#define	cr6	6
+#define	cr7	7
+
+
+/*
+ * General Purpose Registers (GPRs)
+ *
+ * The lower case r0-r31 should be used in preference to the upper
+ * case R0-R31 as they provide more error checking in the assembler.
+ * Use R0-31 only when really nessesary.
+ */
+
+#define	r0	%r0
+#define	r1	%r1
+#define	r2	%r2
+#define	r3	%r3
+#define	r4	%r4
+#define	r5	%r5
+#define	r6	%r6
+#define	r7	%r7
+#define	r8	%r8
+#define	r9	%r9
+#define	r10	%r10
+#define	r11	%r11
+#define	r12	%r12
+#define	r13	%r13
+#define	r14	%r14
+#define	r15	%r15
+#define	r16	%r16
+#define	r17	%r17
+#define	r18	%r18
+#define	r19	%r19
+#define	r20	%r20
+#define	r21	%r21
+#define	r22	%r22
+#define	r23	%r23
+#define	r24	%r24
+#define	r25	%r25
+#define	r26	%r26
+#define	r27	%r27
+#define	r28	%r28
+#define	r29	%r29
+#define	r30	%r30
+#define	r31	%r31
+
+
+/* Floating Point Registers (FPRs) */
+
+#define	fr0	0
+#define	fr1	1
+#define	fr2	2
+#define	fr3	3
+#define	fr4	4
+#define	fr5	5
+#define	fr6	6
+#define	fr7	7
+#define	fr8	8
+#define	fr9	9
+#define	fr10	10
+#define	fr11	11
+#define	fr12	12
+#define	fr13	13
+#define	fr14	14
+#define	fr15	15
+#define	fr16	16
+#define	fr17	17
+#define	fr18	18
+#define	fr19	19
+#define	fr20	20
+#define	fr21	21
+#define	fr22	22
+#define	fr23	23
+#define	fr24	24
+#define	fr25	25
+#define	fr26	26
+#define	fr27	27
+#define	fr28	28
+#define	fr29	29
+#define	fr30	30
+#define	fr31	31
+
+/* AltiVec Registers (VPRs) */
+
+#define	v0	0
+#define	v1	1
+#define	v2	2
+#define	v3	3
+#define	v4	4
+#define	v5	5
+#define	v6	6
+#define	v7	7
+#define	v8	8
+#define	v9	9
+#define	v10	10
+#define	v11	11
+#define	v12	12
+#define	v13	13
+#define	v14	14
+#define	v15	15
+#define	v16	16
+#define	v17	17
+#define	v18	18
+#define	v19	19
+#define	v20	20
+#define	v21	21
+#define	v22	22
+#define	v23	23
+#define	v24	24
+#define	v25	25
+#define	v26	26
+#define	v27	27
+#define	v28	28
+#define	v29	29
+#define	v30	30
+#define	v31	31
+
+/* VSX Registers (VSRs) */
+
+#define	vs0	0
+#define	vs1	1
+#define	vs2	2
+#define	vs3	3
+#define	vs4	4
+#define	vs5	5
+#define	vs6	6
+#define	vs7	7
+#define	vs8	8
+#define	vs9	9
+#define	vs10	10
+#define	vs11	11
+#define	vs12	12
+#define	vs13	13
+#define	vs14	14
+#define	vs15	15
+#define	vs16	16
+#define	vs17	17
+#define	vs18	18
+#define	vs19	19
+#define	vs20	20
+#define	vs21	21
+#define	vs22	22
+#define	vs23	23
+#define	vs24	24
+#define	vs25	25
+#define	vs26	26
+#define	vs27	27
+#define	vs28	28
+#define	vs29	29
+#define	vs30	30
+#define	vs31	31
+#define	vs32	32
+#define	vs33	33
+#define	vs34	34
+#define	vs35	35
+#define	vs36	36
+#define	vs37	37
+#define	vs38	38
+#define	vs39	39
+#define	vs40	40
+#define	vs41	41
+#define	vs42	42
+#define	vs43	43
+#define	vs44	44
+#define	vs45	45
+#define	vs46	46
+#define	vs47	47
+#define	vs48	48
+#define	vs49	49
+#define	vs50	50
+#define	vs51	51
+#define	vs52	52
+#define	vs53	53
+#define	vs54	54
+#define	vs55	55
+#define	vs56	56
+#define	vs57	57
+#define	vs58	58
+#define	vs59	59
+#define	vs60	60
+#define	vs61	61
+#define	vs62	62
+#define	vs63	63
+
+/* SPE Registers (EVPRs) */
+
+#define	evr0	0
+#define	evr1	1
+#define	evr2	2
+#define	evr3	3
+#define	evr4	4
+#define	evr5	5
+#define	evr6	6
+#define	evr7	7
+#define	evr8	8
+#define	evr9	9
+#define	evr10	10
+#define	evr11	11
+#define	evr12	12
+#define	evr13	13
+#define	evr14	14
+#define	evr15	15
+#define	evr16	16
+#define	evr17	17
+#define	evr18	18
+#define	evr19	19
+#define	evr20	20
+#define	evr21	21
+#define	evr22	22
+#define	evr23	23
+#define	evr24	24
+#define	evr25	25
+#define	evr26	26
+#define	evr27	27
+#define	evr28	28
+#define	evr29	29
+#define	evr30	30
+#define	evr31	31
+
+/* some stab codes */
+#define N_FUN	36
+#define N_RSYM	64
+#define N_SLINE	68
+#define N_SO	100
+
+/*
+ * Create an endian fixup trampoline
+ *
+ * This starts with a "tdi 0,0,0x48" instruction which is
+ * essentially a "trap never", and thus akin to a nop.
+ *
+ * The opcode for this instruction read with the wrong endian
+ * however results in a b . + 8
+ *
+ * So essentially we use that trick to execute the following
+ * trampoline in "reverse endian" if we are running with the
+ * MSR_LE bit set the "wrong" way for whatever endianness the
+ * kernel is built for.
+ */
+
+#ifdef CONFIG_PPC_BOOK3E
+#define FIXUP_ENDIAN
+#else
+/*
+ * This version may be used in in HV or non-HV context.
+ * MSR[EE] must be disabled.
+ */
+#define FIXUP_ENDIAN						   \
+	tdi   0,0,0x48;	  /* Reverse endian of b . + 8		*/ \
+	b     191f;	  /* Skip trampoline if endian is good	*/ \
+	.long 0xa600607d; /* mfmsr r11				*/ \
+	.long 0x01006b69; /* xori r11,r11,1			*/ \
+	.long 0x00004039; /* li r10,0				*/ \
+	.long 0x6401417d; /* mtmsrd r10,1			*/ \
+	.long 0x05009f42; /* bcl 20,31,$+4			*/ \
+	.long 0xa602487d; /* mflr r10				*/ \
+	.long 0x14004a39; /* addi r10,r10,20			*/ \
+	.long 0xa6035a7d; /* mtsrr0 r10				*/ \
+	.long 0xa6037b7d; /* mtsrr1 r11				*/ \
+	.long 0x2400004c; /* rfid				*/ \
+191:
+
+/*
+ * This version that may only be used with MSR[HV]=1
+ * - Does not clear MSR[RI], so more robust.
+ * - Slightly smaller and faster.
+ */
+#define FIXUP_ENDIAN_HV						   \
+	tdi   0,0,0x48;	  /* Reverse endian of b . + 8		*/ \
+	b     191f;	  /* Skip trampoline if endian is good	*/ \
+	.long 0xa600607d; /* mfmsr r11				*/ \
+	.long 0x01006b69; /* xori r11,r11,1			*/ \
+	.long 0x05009f42; /* bcl 20,31,$+4			*/ \
+	.long 0xa602487d; /* mflr r10				*/ \
+	.long 0x14004a39; /* addi r10,r10,20			*/ \
+	.long 0xa64b5a7d; /* mthsrr0 r10			*/ \
+	.long 0xa64b7b7d; /* mthsrr1 r11			*/ \
+	.long 0x2402004c; /* hrfid				*/ \
+191:
+
+#endif /* !CONFIG_PPC_BOOK3E */
+
+#endif /*  __ASSEMBLY__ */
+
+/*
+ * Helper macro for exception table entries
+ */
+#define EX_TABLE(_fault, _target)		\
+	stringify_in_c(.section __ex_table,"a";)\
+	stringify_in_c(.balign 4;)		\
+	stringify_in_c(.long (_fault) - . ;)	\
+	stringify_in_c(.long (_target) - . ;)	\
+	stringify_in_c(.previous)
+
+#ifdef CONFIG_PPC_FSL_BOOK3E
+#define BTB_FLUSH(reg)			\
+	lis reg,BUCSR_INIT@h;		\
+	ori reg,reg,BUCSR_INIT@l;	\
+	mtspr SPRN_BUCSR,reg;		\
+	isync;
+#else
+#define BTB_FLUSH(reg)
+#endif /* CONFIG_PPC_FSL_BOOK3E */
+
+#endif /* _ASM_POWERPC_PPC_ASM_H */
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/word-at-a-time.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/word-at-a-time.h
deleted file mode 120000
index eb74401..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/word-at-a-time.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/include/asm/word-at-a-time.h
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/word-at-a-time.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/word-at-a-time.h
new file mode 100644
index 0000000..f3f4710
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/primitives/word-at-a-time.h
@@ -0,0 +1,206 @@
+#ifndef _ASM_WORD_AT_A_TIME_H
+#define _ASM_WORD_AT_A_TIME_H
+
+/*
+ * Word-at-a-time interfaces for PowerPC.
+ */
+
+#include <linux/kernel.h>
+#include <asm/asm-compat.h>
+#include <asm/ppc_asm.h>
+
+#ifdef __BIG_ENDIAN__
+
+struct word_at_a_time {
+	const unsigned long high_bits, low_bits;
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0xfe) + 1, REPEAT_BYTE(0x7f) }
+
+/* Bit set in the bytes that have a zero */
+static inline long prep_zero_mask(unsigned long val, unsigned long rhs, const struct word_at_a_time *c)
+{
+	unsigned long mask = (val & c->low_bits) + c->low_bits;
+	return ~(mask | rhs);
+}
+
+#define create_zero_mask(mask) (mask)
+
+static inline long find_zero(unsigned long mask)
+{
+	long leading_zero_bits;
+
+	asm (PPC_CNTLZL "%0,%1" : "=r" (leading_zero_bits) : "r" (mask));
+	return leading_zero_bits >> 3;
+}
+
+static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
+{
+	unsigned long rhs = val | c->low_bits;
+	*data = rhs;
+	return (val + c->high_bits) & ~rhs;
+}
+
+static inline unsigned long zero_bytemask(unsigned long mask)
+{
+	return ~1ul << __fls(mask);
+}
+
+#else
+
+#ifdef CONFIG_64BIT
+
+/* unused */
+struct word_at_a_time {
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { }
+
+/* This will give us 0xff for a NULL char and 0x00 elsewhere */
+static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c)
+{
+	unsigned long ret;
+	unsigned long zero = 0;
+
+	asm("cmpb %0,%1,%2" : "=r" (ret) : "r" (a), "r" (zero));
+	*bits = ret;
+
+	return ret;
+}
+
+static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c)
+{
+	return bits;
+}
+
+/* Alan Modra's little-endian strlen tail for 64-bit */
+static inline unsigned long create_zero_mask(unsigned long bits)
+{
+	unsigned long leading_zero_bits;
+	long trailing_zero_bit_mask;
+
+	asm("addi	%1,%2,-1\n\t"
+	    "andc	%1,%1,%2\n\t"
+	    "popcntd	%0,%1"
+		: "=r" (leading_zero_bits), "=&r" (trailing_zero_bit_mask)
+		: "b" (bits));
+
+	return leading_zero_bits;
+}
+
+static inline unsigned long find_zero(unsigned long mask)
+{
+	return mask >> 3;
+}
+
+/* This assumes that we never ask for an all 1s bitmask */
+static inline unsigned long zero_bytemask(unsigned long mask)
+{
+	return (1UL << mask) - 1;
+}
+
+#else	/* 32-bit case */
+
+struct word_at_a_time {
+	const unsigned long one_bits, high_bits;
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
+
+/*
+ * This is largely generic for little-endian machines, but the
+ * optimal byte mask counting is probably going to be something
+ * that is architecture-specific. If you have a reliably fast
+ * bit count instruction, that might be better than the multiply
+ * and shift, for example.
+ */
+
+/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */
+static inline long count_masked_bytes(long mask)
+{
+	/* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
+	long a = (0x0ff0001+mask) >> 23;
+	/* Fix the 1 for 00 case */
+	return a & mask;
+}
+
+static inline unsigned long create_zero_mask(unsigned long bits)
+{
+	bits = (bits - 1) & ~bits;
+	return bits >> 7;
+}
+
+static inline unsigned long find_zero(unsigned long mask)
+{
+	return count_masked_bytes(mask);
+}
+
+/* Return nonzero if it has a zero */
+static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c)
+{
+	unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
+	*bits = mask;
+	return mask;
+}
+
+static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c)
+{
+	return bits;
+}
+
+/* The mask we created is directly usable as a bytemask */
+#define zero_bytemask(mask) (mask)
+
+#endif /* CONFIG_64BIT */
+
+#endif /* __BIG_ENDIAN__ */
+
+/*
+ * We use load_unaligned_zero() in a selftest, which builds a userspace
+ * program. Some linker scripts seem to discard the .fixup section, so allow
+ * the test code to use a different section name.
+ */
+#ifndef FIXUP_SECTION
+#define FIXUP_SECTION ".fixup"
+#endif
+
+static inline unsigned long load_unaligned_zeropad(const void *addr)
+{
+	unsigned long ret, offset, tmp;
+
+	asm(
+	"1:	" PPC_LL "%[ret], 0(%[addr])\n"
+	"2:\n"
+	".section " FIXUP_SECTION ",\"ax\"\n"
+	"3:	"
+#ifdef __powerpc64__
+	"clrrdi		%[tmp], %[addr], 3\n\t"
+	"clrlsldi	%[offset], %[addr], 61, 3\n\t"
+	"ld		%[ret], 0(%[tmp])\n\t"
+#ifdef __BIG_ENDIAN__
+	"sld		%[ret], %[ret], %[offset]\n\t"
+#else
+	"srd		%[ret], %[ret], %[offset]\n\t"
+#endif
+#else
+	"clrrwi		%[tmp], %[addr], 2\n\t"
+	"clrlslwi	%[offset], %[addr], 30, 3\n\t"
+	"lwz		%[ret], 0(%[tmp])\n\t"
+#ifdef __BIG_ENDIAN__
+	"slw		%[ret], %[ret], %[offset]\n\t"
+#else
+	"srw		%[ret], %[ret], %[offset]\n\t"
+#endif
+#endif
+	"b	2b\n"
+	".previous\n"
+	EX_TABLE(1b, 3b)
+	: [tmp] "=&b" (tmp), [offset] "=&r" (offset), [ret] "=&r" (ret)
+	: [addr] "b" (addr), "m" (*(unsigned long *)addr));
+
+	return ret;
+}
+
+#undef FIXUP_SECTION
+
+#endif /* _ASM_WORD_AT_A_TIME_H */
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_32.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_32.S
deleted file mode 120000
index 056f2b3..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_32.S
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/lib/memcmp_32.S
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_32.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_32.S
new file mode 100644
index 0000000..5010e37
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_32.S
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * memcmp for PowerPC32
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/export.h>
+
+	.text
+
+_GLOBAL(memcmp)
+	srawi.	r7, r5, 2		/* Divide len by 4 */
+	mr	r6, r3
+	beq-	3f
+	mtctr	r7
+	li	r7, 0
+1:	lwzx	r3, r6, r7
+	lwzx	r0, r4, r7
+	addi	r7, r7, 4
+	cmplw	cr0, r3, r0
+	bdnzt	eq, 1b
+	bne	5f
+3:	andi.	r3, r5, 3
+	beqlr
+	cmplwi	cr1, r3, 2
+	blt-	cr1, 4f
+	lhzx	r3, r6, r7
+	lhzx	r0, r4, r7
+	addi	r7, r7, 2
+	subf.	r3, r0, r3
+	beqlr	cr1
+	bnelr
+4:	lbzx	r3, r6, r7
+	lbzx	r0, r4, r7
+	subf.	r3, r0, r3
+	blr
+5:	li	r3, 1
+	bgtlr
+	li	r3, -1
+	blr
+EXPORT_SYMBOL(memcmp)
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_64.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_64.S
deleted file mode 120000
index 9bc87e4..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_64.S
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/lib/memcmp_64.S
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_64.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_64.S
new file mode 100644
index 0000000..b7f6f6e
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/memcmp_64.S
@@ -0,0 +1,642 @@
+/*
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ * Copyright 2015 IBM Corporation.
+ *
+ * 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.
+ */
+#include <asm/ppc_asm.h>
+#include <asm/export.h>
+#include <asm/ppc-opcode.h>
+
+#define off8	r6
+#define off16	r7
+#define off24	r8
+
+#define rA	r9
+#define rB	r10
+#define rC	r11
+#define rD	r27
+#define rE	r28
+#define rF	r29
+#define rG	r30
+#define rH	r31
+
+#ifdef __LITTLE_ENDIAN__
+#define LH	lhbrx
+#define LW	lwbrx
+#define LD	ldbrx
+#define LVS	lvsr
+#define VPERM(_VRT,_VRA,_VRB,_VRC) \
+	vperm _VRT,_VRB,_VRA,_VRC
+#else
+#define LH	lhzx
+#define LW	lwzx
+#define LD	ldx
+#define LVS	lvsl
+#define VPERM(_VRT,_VRA,_VRB,_VRC) \
+	vperm _VRT,_VRA,_VRB,_VRC
+#endif
+
+#define VMX_THRESH 4096
+#define ENTER_VMX_OPS	\
+	mflr    r0;	\
+	std     r3,-STACKFRAMESIZE+STK_REG(R31)(r1); \
+	std     r4,-STACKFRAMESIZE+STK_REG(R30)(r1); \
+	std     r5,-STACKFRAMESIZE+STK_REG(R29)(r1); \
+	std     r0,16(r1); \
+	stdu    r1,-STACKFRAMESIZE(r1); \
+	bl      enter_vmx_ops; \
+	cmpwi   cr1,r3,0; \
+	ld      r0,STACKFRAMESIZE+16(r1); \
+	ld      r3,STK_REG(R31)(r1); \
+	ld      r4,STK_REG(R30)(r1); \
+	ld      r5,STK_REG(R29)(r1); \
+	addi	r1,r1,STACKFRAMESIZE; \
+	mtlr    r0
+
+#define EXIT_VMX_OPS \
+	mflr    r0; \
+	std     r3,-STACKFRAMESIZE+STK_REG(R31)(r1); \
+	std     r4,-STACKFRAMESIZE+STK_REG(R30)(r1); \
+	std     r5,-STACKFRAMESIZE+STK_REG(R29)(r1); \
+	std     r0,16(r1); \
+	stdu    r1,-STACKFRAMESIZE(r1); \
+	bl      exit_vmx_ops; \
+	ld      r0,STACKFRAMESIZE+16(r1); \
+	ld      r3,STK_REG(R31)(r1); \
+	ld      r4,STK_REG(R30)(r1); \
+	ld      r5,STK_REG(R29)(r1); \
+	addi	r1,r1,STACKFRAMESIZE; \
+	mtlr    r0
+
+/*
+ * LD_VSR_CROSS16B load the 2nd 16 bytes for _vaddr which is unaligned with
+ * 16 bytes boundary and permute the result with the 1st 16 bytes.
+
+ *    |  y y y y y y y y y y y y y 0 1 2 | 3 4 5 6 7 8 9 a b c d e f z z z |
+ *    ^                                  ^                                 ^
+ * 0xbbbb10                          0xbbbb20                          0xbbb30
+ *                                 ^
+ *                                _vaddr
+ *
+ *
+ * _vmask is the mask generated by LVS
+ * _v1st_qw is the 1st aligned QW of current addr which is already loaded.
+ *   for example: 0xyyyyyyyyyyyyy012 for big endian
+ * _v2nd_qw is the 2nd aligned QW of cur _vaddr to be loaded.
+ *   for example: 0x3456789abcdefzzz for big endian
+ * The permute result is saved in _v_res.
+ *   for example: 0x0123456789abcdef for big endian.
+ */
+#define LD_VSR_CROSS16B(_vaddr,_vmask,_v1st_qw,_v2nd_qw,_v_res) \
+        lvx     _v2nd_qw,_vaddr,off16; \
+        VPERM(_v_res,_v1st_qw,_v2nd_qw,_vmask)
+
+/*
+ * There are 2 categories for memcmp:
+ * 1) src/dst has the same offset to the 8 bytes boundary. The handlers
+ * are named like .Lsameoffset_xxxx
+ * 2) src/dst has different offset to the 8 bytes boundary. The handlers
+ * are named like .Ldiffoffset_xxxx
+ */
+_GLOBAL_TOC(memcmp)
+	cmpdi	cr1,r5,0
+
+	/* Use the short loop if the src/dst addresses are not
+	 * with the same offset of 8 bytes align boundary.
+	 */
+	xor	r6,r3,r4
+	andi.	r6,r6,7
+
+	/* Fall back to short loop if compare at aligned addrs
+	 * with less than 8 bytes.
+	 */
+	cmpdi   cr6,r5,7
+
+	beq	cr1,.Lzero
+	bgt	cr6,.Lno_short
+
+.Lshort:
+	mtctr	r5
+1:	lbz	rA,0(r3)
+	lbz	rB,0(r4)
+	subf.	rC,rB,rA
+	bne	.Lnon_zero
+	bdz	.Lzero
+
+	lbz	rA,1(r3)
+	lbz	rB,1(r4)
+	subf.	rC,rB,rA
+	bne	.Lnon_zero
+	bdz	.Lzero
+
+	lbz	rA,2(r3)
+	lbz	rB,2(r4)
+	subf.	rC,rB,rA
+	bne	.Lnon_zero
+	bdz	.Lzero
+
+	lbz	rA,3(r3)
+	lbz	rB,3(r4)
+	subf.	rC,rB,rA
+	bne	.Lnon_zero
+
+	addi	r3,r3,4
+	addi	r4,r4,4
+
+	bdnz	1b
+
+.Lzero:
+	li	r3,0
+	blr
+
+.Lno_short:
+	dcbt	0,r3
+	dcbt	0,r4
+	bne	.Ldiffoffset_8bytes_make_align_start
+
+
+.Lsameoffset_8bytes_make_align_start:
+	/* attempt to compare bytes not aligned with 8 bytes so that
+	 * rest comparison can run based on 8 bytes alignment.
+	 */
+	andi.   r6,r3,7
+
+	/* Try to compare the first double word which is not 8 bytes aligned:
+	 * load the first double word at (src & ~7UL) and shift left appropriate
+	 * bits before comparision.
+	 */
+	rlwinm  r6,r3,3,26,28
+	beq     .Lsameoffset_8bytes_aligned
+	clrrdi	r3,r3,3
+	clrrdi	r4,r4,3
+	LD	rA,0,r3
+	LD	rB,0,r4
+	sld	rA,rA,r6
+	sld	rB,rB,r6
+	cmpld	cr0,rA,rB
+	srwi	r6,r6,3
+	bne	cr0,.LcmpAB_lightweight
+	subfic  r6,r6,8
+	subf.	r5,r6,r5
+	addi	r3,r3,8
+	addi	r4,r4,8
+	beq	.Lzero
+
+.Lsameoffset_8bytes_aligned:
+	/* now we are aligned with 8 bytes.
+	 * Use .Llong loop if left cmp bytes are equal or greater than 32B.
+	 */
+	cmpdi   cr6,r5,31
+	bgt	cr6,.Llong
+
+.Lcmp_lt32bytes:
+	/* compare 1 ~ 31 bytes, at least r3 addr is 8 bytes aligned now */
+	cmpdi   cr5,r5,7
+	srdi    r0,r5,3
+	ble	cr5,.Lcmp_rest_lt8bytes
+
+	/* handle 8 ~ 31 bytes */
+	clrldi  r5,r5,61
+	mtctr   r0
+2:
+	LD	rA,0,r3
+	LD	rB,0,r4
+	cmpld	cr0,rA,rB
+	addi	r3,r3,8
+	addi	r4,r4,8
+	bne	cr0,.LcmpAB_lightweight
+	bdnz	2b
+
+	cmpwi   r5,0
+	beq	.Lzero
+
+.Lcmp_rest_lt8bytes:
+	/*
+	 * Here we have less than 8 bytes to compare. At least s1 is aligned to
+	 * 8 bytes, but s2 may not be. We must make sure s2 + 7 doesn't cross a
+	 * page boundary, otherwise we might read past the end of the buffer and
+	 * trigger a page fault. We use 4K as the conservative minimum page
+	 * size. If we detect that case we go to the byte-by-byte loop.
+	 *
+	 * Otherwise the next double word is loaded from s1 and s2, and shifted
+	 * right to compare the appropriate bits.
+	 */
+	clrldi	r6,r4,(64-12)	// r6 = r4 & 0xfff
+	cmpdi	r6,0xff8
+	bgt	.Lshort
+
+	subfic  r6,r5,8
+	slwi	r6,r6,3
+	LD	rA,0,r3
+	LD	rB,0,r4
+	srd	rA,rA,r6
+	srd	rB,rB,r6
+	cmpld	cr0,rA,rB
+	bne	cr0,.LcmpAB_lightweight
+	b	.Lzero
+
+.Lnon_zero:
+	mr	r3,rC
+	blr
+
+.Llong:
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+	/* Try to use vmx loop if length is equal or greater than 4K */
+	cmpldi  cr6,r5,VMX_THRESH
+	bge	cr6,.Lsameoffset_vmx_cmp
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+
+.Llong_novmx_cmp:
+#endif
+	/* At least s1 addr is aligned with 8 bytes */
+	li	off8,8
+	li	off16,16
+	li	off24,24
+
+	std	r31,-8(r1)
+	std	r30,-16(r1)
+	std	r29,-24(r1)
+	std	r28,-32(r1)
+	std	r27,-40(r1)
+
+	srdi	r0,r5,5
+	mtctr	r0
+	andi.	r5,r5,31
+
+	LD	rA,0,r3
+	LD	rB,0,r4
+
+	LD	rC,off8,r3
+	LD	rD,off8,r4
+
+	LD	rE,off16,r3
+	LD	rF,off16,r4
+
+	LD	rG,off24,r3
+	LD	rH,off24,r4
+	cmpld	cr0,rA,rB
+
+	addi	r3,r3,32
+	addi	r4,r4,32
+
+	bdz	.Lfirst32
+
+	LD	rA,0,r3
+	LD	rB,0,r4
+	cmpld	cr1,rC,rD
+
+	LD	rC,off8,r3
+	LD	rD,off8,r4
+	cmpld	cr6,rE,rF
+
+	LD	rE,off16,r3
+	LD	rF,off16,r4
+	cmpld	cr7,rG,rH
+	bne	cr0,.LcmpAB
+
+	LD	rG,off24,r3
+	LD	rH,off24,r4
+	cmpld	cr0,rA,rB
+	bne	cr1,.LcmpCD
+
+	addi	r3,r3,32
+	addi	r4,r4,32
+
+	bdz	.Lsecond32
+
+	.balign	16
+
+1:	LD	rA,0,r3
+	LD	rB,0,r4
+	cmpld	cr1,rC,rD
+	bne	cr6,.LcmpEF
+
+	LD	rC,off8,r3
+	LD	rD,off8,r4
+	cmpld	cr6,rE,rF
+	bne	cr7,.LcmpGH
+
+	LD	rE,off16,r3
+	LD	rF,off16,r4
+	cmpld	cr7,rG,rH
+	bne	cr0,.LcmpAB
+
+	LD	rG,off24,r3
+	LD	rH,off24,r4
+	cmpld	cr0,rA,rB
+	bne	cr1,.LcmpCD
+
+	addi	r3,r3,32
+	addi	r4,r4,32
+
+	bdnz	1b
+
+.Lsecond32:
+	cmpld	cr1,rC,rD
+	bne	cr6,.LcmpEF
+
+	cmpld	cr6,rE,rF
+	bne	cr7,.LcmpGH
+
+	cmpld	cr7,rG,rH
+	bne	cr0,.LcmpAB
+
+	bne	cr1,.LcmpCD
+	bne	cr6,.LcmpEF
+	bne	cr7,.LcmpGH
+
+.Ltail:
+	ld	r31,-8(r1)
+	ld	r30,-16(r1)
+	ld	r29,-24(r1)
+	ld	r28,-32(r1)
+	ld	r27,-40(r1)
+
+	cmpdi	r5,0
+	beq	.Lzero
+	b	.Lshort
+
+.Lfirst32:
+	cmpld	cr1,rC,rD
+	cmpld	cr6,rE,rF
+	cmpld	cr7,rG,rH
+
+	bne	cr0,.LcmpAB
+	bne	cr1,.LcmpCD
+	bne	cr6,.LcmpEF
+	bne	cr7,.LcmpGH
+
+	b	.Ltail
+
+.LcmpAB:
+	li	r3,1
+	bgt	cr0,.Lout
+	li	r3,-1
+	b	.Lout
+
+.LcmpCD:
+	li	r3,1
+	bgt	cr1,.Lout
+	li	r3,-1
+	b	.Lout
+
+.LcmpEF:
+	li	r3,1
+	bgt	cr6,.Lout
+	li	r3,-1
+	b	.Lout
+
+.LcmpGH:
+	li	r3,1
+	bgt	cr7,.Lout
+	li	r3,-1
+
+.Lout:
+	ld	r31,-8(r1)
+	ld	r30,-16(r1)
+	ld	r29,-24(r1)
+	ld	r28,-32(r1)
+	ld	r27,-40(r1)
+	blr
+
+.LcmpAB_lightweight:   /* skip NV GPRS restore */
+	li	r3,1
+	bgtlr
+	li	r3,-1
+	blr
+
+#ifdef CONFIG_ALTIVEC
+.Lsameoffset_vmx_cmp:
+	/* Enter with src/dst addrs has the same offset with 8 bytes
+	 * align boundary.
+	 *
+	 * There is an optimization based on following fact: memcmp()
+	 * prones to fail early at the first 32 bytes.
+	 * Before applying VMX instructions which will lead to 32x128bits
+	 * VMX regs load/restore penalty, we compare the first 32 bytes
+	 * so that we can catch the ~80% fail cases.
+	 */
+
+	li	r0,4
+	mtctr	r0
+.Lsameoffset_prechk_32B_loop:
+	LD	rA,0,r3
+	LD	rB,0,r4
+	cmpld	cr0,rA,rB
+	addi	r3,r3,8
+	addi	r4,r4,8
+	bne     cr0,.LcmpAB_lightweight
+	addi	r5,r5,-8
+	bdnz	.Lsameoffset_prechk_32B_loop
+
+	ENTER_VMX_OPS
+	beq     cr1,.Llong_novmx_cmp
+
+3:
+	/* need to check whether r4 has the same offset with r3
+	 * for 16 bytes boundary.
+	 */
+	xor	r0,r3,r4
+	andi.	r0,r0,0xf
+	bne	.Ldiffoffset_vmx_cmp_start
+
+	/* len is no less than 4KB. Need to align with 16 bytes further.
+	 */
+	andi.	rA,r3,8
+	LD	rA,0,r3
+	beq	4f
+	LD	rB,0,r4
+	cmpld	cr0,rA,rB
+	addi	r3,r3,8
+	addi	r4,r4,8
+	addi	r5,r5,-8
+
+	beq	cr0,4f
+	/* save and restore cr0 */
+	mfocrf  r5,128
+	EXIT_VMX_OPS
+	mtocrf  128,r5
+	b	.LcmpAB_lightweight
+
+4:
+	/* compare 32 bytes for each loop */
+	srdi	r0,r5,5
+	mtctr	r0
+	clrldi  r5,r5,59
+	li	off16,16
+
+.balign 16
+5:
+	lvx 	v0,0,r3
+	lvx 	v1,0,r4
+	VCMPEQUD_RC(v0,v0,v1)
+	bnl	cr6,7f
+	lvx 	v0,off16,r3
+	lvx 	v1,off16,r4
+	VCMPEQUD_RC(v0,v0,v1)
+	bnl	cr6,6f
+	addi	r3,r3,32
+	addi	r4,r4,32
+	bdnz	5b
+
+	EXIT_VMX_OPS
+	cmpdi	r5,0
+	beq	.Lzero
+	b	.Lcmp_lt32bytes
+
+6:
+	addi	r3,r3,16
+	addi	r4,r4,16
+
+7:
+	/* diff the last 16 bytes */
+	EXIT_VMX_OPS
+	LD	rA,0,r3
+	LD	rB,0,r4
+	cmpld	cr0,rA,rB
+	li	off8,8
+	bne	cr0,.LcmpAB_lightweight
+
+	LD	rA,off8,r3
+	LD	rB,off8,r4
+	cmpld	cr0,rA,rB
+	bne	cr0,.LcmpAB_lightweight
+	b	.Lzero
+#endif
+
+.Ldiffoffset_8bytes_make_align_start:
+	/* now try to align s1 with 8 bytes */
+	rlwinm  r6,r3,3,26,28
+	beq     .Ldiffoffset_align_s1_8bytes
+
+	clrrdi	r3,r3,3
+	LD	rA,0,r3
+	LD	rB,0,r4  /* unaligned load */
+	sld	rA,rA,r6
+	srd	rA,rA,r6
+	srd	rB,rB,r6
+	cmpld	cr0,rA,rB
+	srwi	r6,r6,3
+	bne	cr0,.LcmpAB_lightweight
+
+	subfic  r6,r6,8
+	subf.	r5,r6,r5
+	addi	r3,r3,8
+	add	r4,r4,r6
+
+	beq	.Lzero
+
+.Ldiffoffset_align_s1_8bytes:
+	/* now s1 is aligned with 8 bytes. */
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+	/* only do vmx ops when the size equal or greater than 4K bytes */
+	cmpdi	cr5,r5,VMX_THRESH
+	bge	cr5,.Ldiffoffset_vmx_cmp
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+
+.Ldiffoffset_novmx_cmp:
+#endif
+
+
+	cmpdi   cr5,r5,31
+	ble	cr5,.Lcmp_lt32bytes
+
+#ifdef CONFIG_ALTIVEC
+	b	.Llong_novmx_cmp
+#else
+	b	.Llong
+#endif
+
+#ifdef CONFIG_ALTIVEC
+.Ldiffoffset_vmx_cmp:
+	/* perform a 32 bytes pre-checking before
+	 * enable VMX operations.
+	 */
+	li	r0,4
+	mtctr	r0
+.Ldiffoffset_prechk_32B_loop:
+	LD	rA,0,r3
+	LD	rB,0,r4
+	cmpld	cr0,rA,rB
+	addi	r3,r3,8
+	addi	r4,r4,8
+	bne     cr0,.LcmpAB_lightweight
+	addi	r5,r5,-8
+	bdnz	.Ldiffoffset_prechk_32B_loop
+
+	ENTER_VMX_OPS
+	beq     cr1,.Ldiffoffset_novmx_cmp
+
+.Ldiffoffset_vmx_cmp_start:
+	/* Firstly try to align r3 with 16 bytes */
+	andi.   r6,r3,0xf
+	li	off16,16
+	beq     .Ldiffoffset_vmx_s1_16bytes_align
+
+	LVS	v3,0,r3
+	LVS	v4,0,r4
+
+	lvx     v5,0,r3
+	lvx     v6,0,r4
+	LD_VSR_CROSS16B(r3,v3,v5,v7,v9)
+	LD_VSR_CROSS16B(r4,v4,v6,v8,v10)
+
+	VCMPEQUB_RC(v7,v9,v10)
+	bnl	cr6,.Ldiffoffset_vmx_diff_found
+
+	subfic  r6,r6,16
+	subf    r5,r6,r5
+	add     r3,r3,r6
+	add     r4,r4,r6
+
+.Ldiffoffset_vmx_s1_16bytes_align:
+	/* now s1 is aligned with 16 bytes */
+	lvx     v6,0,r4
+	LVS	v4,0,r4
+	srdi	r6,r5,5  /* loop for 32 bytes each */
+	clrldi  r5,r5,59
+	mtctr	r6
+
+.balign	16
+.Ldiffoffset_vmx_32bytesloop:
+	/* the first qw of r4 was saved in v6 */
+	lvx	v9,0,r3
+	LD_VSR_CROSS16B(r4,v4,v6,v8,v10)
+	VCMPEQUB_RC(v7,v9,v10)
+	vor	v6,v8,v8
+	bnl	cr6,.Ldiffoffset_vmx_diff_found
+
+	addi	r3,r3,16
+	addi	r4,r4,16
+
+	lvx	v9,0,r3
+	LD_VSR_CROSS16B(r4,v4,v6,v8,v10)
+	VCMPEQUB_RC(v7,v9,v10)
+	vor	v6,v8,v8
+	bnl	cr6,.Ldiffoffset_vmx_diff_found
+
+	addi	r3,r3,16
+	addi	r4,r4,16
+
+	bdnz	.Ldiffoffset_vmx_32bytesloop
+
+	EXIT_VMX_OPS
+
+	cmpdi	r5,0
+	beq	.Lzero
+	b	.Lcmp_lt32bytes
+
+.Ldiffoffset_vmx_diff_found:
+	EXIT_VMX_OPS
+	/* anyway, the diff will appear in next 16 bytes */
+	li	r5,16
+	b	.Lcmp_lt32bytes
+
+#endif
+EXPORT_SYMBOL(memcmp)
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/strlen_32.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/strlen_32.S
deleted file mode 120000
index 72b1373..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/strlen_32.S
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/lib/strlen_32.S
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/strlen_32.S b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/strlen_32.S
new file mode 100644
index 0000000..0a8d3f6
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/stringloops/strlen_32.S
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * strlen() for PPC32
+ *
+ * Copyright (C) 2018 Christophe Leroy CS Systemes d'Information.
+ *
+ * Inspired from glibc implementation
+ */
+#include <asm/ppc_asm.h>
+#include <asm/export.h>
+#include <asm/cache.h>
+
+	.text
+
+/*
+ * Algorithm:
+ *
+ * 1) Given a word 'x', we can test to see if it contains any 0 bytes
+ *    by subtracting 0x01010101, and seeing if any of the high bits of each
+ *    byte changed from 0 to 1. This works because the least significant
+ *    0 byte must have had no incoming carry (otherwise it's not the least
+ *    significant), so it is 0x00 - 0x01 == 0xff. For all other
+ *    byte values, either they have the high bit set initially, or when
+ *    1 is subtracted you get a value in the range 0x00-0x7f, none of which
+ *    have their high bit set. The expression here is
+ *    (x - 0x01010101) & ~x & 0x80808080), which gives 0x00000000 when
+ *    there were no 0x00 bytes in the word.  You get 0x80 in bytes that
+ *    match, but possibly false 0x80 matches in the next more significant
+ *    byte to a true match due to carries.  For little-endian this is
+ *    of no consequence since the least significant match is the one
+ *    we're interested in, but big-endian needs method 2 to find which
+ *    byte matches.
+ * 2) Given a word 'x', we can test to see _which_ byte was zero by
+ *    calculating ~(((x & ~0x80808080) - 0x80808080 - 1) | x | ~0x80808080).
+ *    This produces 0x80 in each byte that was zero, and 0x00 in all
+ *    the other bytes. The '| ~0x80808080' clears the low 7 bits in each
+ *    byte, and the '| x' part ensures that bytes with the high bit set
+ *    produce 0x00. The addition will carry into the high bit of each byte
+ *    iff that byte had one of its low 7 bits set. We can then just see
+ *    which was the most significant bit set and divide by 8 to find how
+ *    many to add to the index.
+ *    This is from the book 'The PowerPC Compiler Writer's Guide',
+ *    by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
+ */
+
+_GLOBAL(strlen)
+	andi.   r0, r3, 3
+	lis	r7, 0x0101
+	addi	r10, r3, -4
+	addic	r7, r7, 0x0101	/* r7 = 0x01010101 (lomagic) & clear XER[CA] */
+	rotlwi	r6, r7, 31 	/* r6 = 0x80808080 (himagic) */
+	bne-	3f
+	.balign IFETCH_ALIGN_BYTES
+1:	lwzu	r9, 4(r10)
+2:	subf	r8, r7, r9
+	and.	r8, r8, r6
+	beq+	1b
+	andc.	r8, r8, r9
+	beq+	1b
+	andc	r8, r9, r6
+	orc	r9, r9, r6
+	subfe	r8, r6, r8
+	nor	r8, r8, r9
+	cntlzw	r8, r8
+	subf	r3, r3, r10
+	srwi	r8, r8, 3
+	add	r3, r3, r8
+	blr
+
+	/* Missaligned string: make sure bytes before string are seen not 0 */
+3:	xor	r10, r10, r0
+	orc	r8, r8, r8
+	lwzu	r9, 4(r10)
+	slwi	r0, r0, 3
+	srw	r8, r8, r0
+	orc	r9, r9, r8
+	b	2b
+EXPORT_SYMBOL(strlen)
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.c b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.c
deleted file mode 120000
index 186b906..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.c
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/mm/vphn.c
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.c b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.c
new file mode 100644
index 0000000..f83044f
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <asm/byteorder.h>
+#include "vphn.h"
+
+/*
+ * The associativity domain numbers are returned from the hypervisor as a
+ * stream of mixed 16-bit and 32-bit fields. The stream is terminated by the
+ * special value of "all ones" (aka. 0xffff) and its size may not exceed 48
+ * bytes.
+ *
+ *    --- 16-bit fields -->
+ *  _________________________
+ *  |  0  |  1  |  2  |  3  |   be_packed[0]
+ *  ------+-----+-----+------
+ *  _________________________
+ *  |  4  |  5  |  6  |  7  |   be_packed[1]
+ *  -------------------------
+ *            ...
+ *  _________________________
+ *  | 20  | 21  | 22  | 23  |   be_packed[5]
+ *  -------------------------
+ *
+ * Convert to the sequence they would appear in the ibm,associativity property.
+ */
+int vphn_unpack_associativity(const long *packed, __be32 *unpacked)
+{
+	__be64 be_packed[VPHN_REGISTER_COUNT];
+	int i, nr_assoc_doms = 0;
+	const __be16 *field = (const __be16 *) be_packed;
+	u16 last = 0;
+	bool is_32bit = false;
+
+#define VPHN_FIELD_UNUSED	(0xffff)
+#define VPHN_FIELD_MSB		(0x8000)
+#define VPHN_FIELD_MASK		(~VPHN_FIELD_MSB)
+
+	/* Let's fix the values returned by plpar_hcall9() */
+	for (i = 0; i < VPHN_REGISTER_COUNT; i++)
+		be_packed[i] = cpu_to_be64(packed[i]);
+
+	for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) {
+		u16 new = be16_to_cpup(field++);
+
+		if (is_32bit) {
+			/* Let's concatenate the 16 bits of this field to the
+			 * 15 lower bits of the previous field
+			 */
+			unpacked[++nr_assoc_doms] =
+				cpu_to_be32(last << 16 | new);
+			is_32bit = false;
+		} else if (new == VPHN_FIELD_UNUSED)
+			/* This is the list terminator */
+			break;
+		else if (new & VPHN_FIELD_MSB) {
+			/* Data is in the lower 15 bits of this field */
+			unpacked[++nr_assoc_doms] =
+				cpu_to_be32(new & VPHN_FIELD_MASK);
+		} else {
+			/* Data is in the lower 15 bits of this field
+			 * concatenated with the next 16 bit field
+			 */
+			last = new;
+			is_32bit = true;
+		}
+	}
+
+	/* The first cell contains the length of the property */
+	unpacked[0] = cpu_to_be32(nr_assoc_doms);
+
+	return nr_assoc_doms;
+}
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.h
deleted file mode 120000
index 7131efe..0000000
--- a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../arch/powerpc/mm/vphn.h
\ No newline at end of file
diff --git a/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.h b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.h
new file mode 100644
index 0000000..f9ffdb3
--- /dev/null
+++ b/src/kernel/linux/v4.19/tools/testing/selftests/powerpc/vphn/vphn.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ARCH_POWERPC_MM_VPHN_H_
+#define _ARCH_POWERPC_MM_VPHN_H_
+
+/* The H_HOME_NODE_ASSOCIATIVITY h_call returns 6 64-bit registers.
+ */
+#define VPHN_REGISTER_COUNT 6
+
+/*
+ * 6 64-bit registers unpacked into up to 24 be32 associativity values. To
+ * form the complete property we have to add the length in the first cell.
+ */
+#define VPHN_ASSOC_BUFSIZE (VPHN_REGISTER_COUNT*sizeof(u64)/sizeof(u16) + 1)
+
+extern int vphn_unpack_associativity(const long *packed, __be32 *unpacked);
+
+#endif