Merge "Revert "[Feature][T8TSK-124]Optimize the startup time of the LK stage"" into GSW3.0
diff --git a/meta/meta-mediatek-mt2735/classes/md-fitimage.bbclass b/meta/meta-mediatek-mt2735/classes/md-fitimage.bbclass
index 782c417..1a48a6e 100644
--- a/meta/meta-mediatek-mt2735/classes/md-fitimage.bbclass
+++ b/meta/meta-mediatek-mt2735/classes/md-fitimage.bbclass
@@ -69,7 +69,7 @@
                         type = "kernel";
                         arch = "arm";
                         os = "linux";
-                        compression = "${MODEM_COMPRESS}";
+                        compression = "none";
                         load = <${MD_LOADADDRESS}>;
                         entry = <${MD_ENTRYPOINT}>;
                         hash_1 {
@@ -119,7 +119,7 @@
                 fitimage_emit_section_maint imagestart
 
 
-                fitimage_emit_section_md ${WORKDIR}/modem.img
+                fitimage_emit_section_md ${WORKDIR}/modem-org.img
 
                 fitimage_emit_section_maint sectend
 
@@ -137,11 +137,12 @@
                 #
                 # Step 3: Assemble the image
                 #
-		uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${MD_DST_IMAGE}
+                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${MD_IMAGE}
+
                 if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
                         mkdir -p ${WORKDIR}/mykeys
                         cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ${WORKDIR}/mykeys/dev.crt
                         cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ${WORKDIR}/mykeys/dev.key
-                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ${WORKDIR}/mykeys -f ${WORKDIR}/fit-image.its -r ${WORKDIR}/${MD_DST_IMAGE}
+                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ${WORKDIR}/mykeys -f ${WORKDIR}/fit-image.its -r ${WORKDIR}/${MD_IMAGE}
                 fi
 }
\ No newline at end of file
diff --git a/meta/meta-mediatek-mt2735/classes/mddsp-fitimage.bbclass b/meta/meta-mediatek-mt2735/classes/mddsp-fitimage.bbclass
index e32ada4..593df1c 100644
--- a/meta/meta-mediatek-mt2735/classes/mddsp-fitimage.bbclass
+++ b/meta/meta-mediatek-mt2735/classes/mddsp-fitimage.bbclass
@@ -69,7 +69,7 @@
                         type = "kernel";
                         arch = "arm";
                         os = "linux";
-                        compression = "${DSP_COMPRESS}";
+                        compression = "none";
                         load = <${MDDSP_LOADADDRESS}>;
                         entry = <${MDDSP_ENTRYPOINT}>;
                         hash_1 {
@@ -118,7 +118,7 @@
                 fitimage_emit_section_maint imagestart
 
 
-                fitimage_emit_section_dsp ${WORKDIR}/dsp.bin
+                fitimage_emit_section_dsp ${WORKDIR}/dsp-org.bin
 
                 fitimage_emit_section_maint sectend
 
@@ -136,12 +136,12 @@
                 #
                 # Step 3: Assemble the image
                 #
-                uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${DSP_DST_IMAGE}
+                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${MDDSP_IMAGE}
 
                 if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
                         mkdir -p ${WORKDIR}/mykeys
                         cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ${WORKDIR}/mykeys/dev.crt
                         cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ${WORKDIR}/mykeys/dev.key
-                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ${WORKDIR}/mykeys -f ${WORKDIR}/fit-image.its -r ${WORKDIR}/${DSP_DST_IMAGE}
+                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ${WORKDIR}/mykeys -f ${WORKDIR}/fit-image.its -r ${WORKDIR}/${MDDSP_IMAGE}
                 fi
 }
\ No newline at end of file
diff --git a/meta/meta-mediatek-mt2735/conf/machine/auto2735evb-ivt-base.conf b/meta/meta-mediatek-mt2735/conf/machine/auto2735evb-ivt-base.conf
index 8132c55..4ea9a3d 100755
--- a/meta/meta-mediatek-mt2735/conf/machine/auto2735evb-ivt-base.conf
+++ b/meta/meta-mediatek-mt2735/conf/machine/auto2735evb-ivt-base.conf
@@ -154,8 +154,6 @@
 MODEM_CUSTOM_EXIST = "${@ os.path.exists('${MODEM_CUSTOM}')}"
 MODEM_DIR = "${@'${MODEM_INT}/${MODEM_PROJECT}' if ${MODEM_INT_EXIST} == True else '${MODEM_CUSTOM}/${MODEM_PROJECT}'}"
 EXTRA_IMAGEDEPENDS += "${@'modem' if ${MODEM_INT_EXIST} == True or ${MODEM_CUSTOM_EXIST} == True else ''}"
-MODEM_COMPRESS = "lz4"
-DSP_COMPRESS = "lz4"
 # MIPC
 MIPC_MODEM_PROJECT = "mt2735_ivt_nlwg_wide_temp"
 MIPC_INT = "${TOPDIR}/../src/telephonyware/3.0/mipc_internal"
diff --git a/meta/meta-mediatek-mt2735/recipes-core/initial/files/cpu_sched.service b/meta/meta-mediatek-mt2735/recipes-core/initial/files/cpu_sched.service
deleted file mode 100644
index 45108b7..0000000
--- a/meta/meta-mediatek-mt2735/recipes-core/initial/files/cpu_sched.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=CPU governor change to schedutil to avoid thermal issue
-Requires=init_mount.service
-After=init_mount.service
-
-[Service]
-Type=oneshot
-StandardOutput=kmsg+console
-RemainAfterExit=yes
-ExecStart=/bin/sh -c '/bin/echo schedutil > sys/devices/system/cpu/cpufreq/policy0/scaling_governor'
-
-[Install]
-WantedBy=sysinit.target
diff --git a/meta/meta-mediatek-mt2735/recipes-core/initial/init-2735_1.0.0.bb b/meta/meta-mediatek-mt2735/recipes-core/initial/init-2735_1.0.0.bb
old mode 100644
new mode 100755
index 0e82cbd..23096c1
--- a/meta/meta-mediatek-mt2735/recipes-core/initial/init-2735_1.0.0.bb
+++ b/meta/meta-mediatek-mt2735/recipes-core/initial/init-2735_1.0.0.bb
@@ -11,7 +11,6 @@
 SRC_URI += "file://usb_switch"
 SRC_URI += "file://init_network.service"
 SRC_URI += "file://init_mount.service"
-SRC_URI += "file://cpu_sched.service"
 SRC_URI += "file://nvram_daemon.service"
 SRC_URI += "file://ccci_fsd.service"
 SRC_URI += "file://ccci_mdinit.service"
@@ -69,7 +68,6 @@
 SYSTEMD_PACKAGES = "${PN}"
 SYSTEMD_SERVICE_${PN} = "init_network.service \
                          init_mount.service \
-                         cpu_sched.service \
                          nvram_daemon.service \
                          ccci_fsd.service \
                          ccci_mdinit.service \
@@ -90,7 +88,6 @@
 #xf.li 2022.11.17 modify for userdata recover start
 FILES_${PN} += "${systemd_unitdir}/system/init_network.service \
                 ${systemd_unitdir}/system/init_mount.service \
-                ${systemd_unitdir}/system/cpu_sched.service \
                 ${systemd_unitdir}/system/nvram_daemon.service \
                 ${systemd_unitdir}/system/ccci_fsd.service \
                 ${systemd_unitdir}/system/ccci_mdinit.service \
@@ -139,7 +136,6 @@
         install -d ${D}${systemd_unitdir}/system/
         install -m 0644 init_network.service ${D}${systemd_unitdir}/system
         install -m 0644 init_mount.service ${D}${systemd_unitdir}/system
-        install -m 0644 cpu_sched.service ${D}${systemd_unitdir}/system
         install -m 0644 nvram_daemon.service ${D}${systemd_unitdir}/system
         install -m 0644 ccci_fsd.service ${D}${systemd_unitdir}/system
         install -m 0644 ccci_mdinit.service ${D}${systemd_unitdir}/system
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/linux/files/boot_time.cfg b/meta/meta-mediatek-mt2735/recipes-kernel/linux/files/boot_time.cfg
deleted file mode 100644
index b020174..0000000
--- a/meta/meta-mediatek-mt2735/recipes-kernel/linux/files/boot_time.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/linux/files/user_build.cfg b/meta/meta-mediatek-mt2735/recipes-kernel/linux/files/user_build.cfg
index 28b0ce9..826968f 100644
--- a/meta/meta-mediatek-mt2735/recipes-kernel/linux/files/user_build.cfg
+++ b/meta/meta-mediatek-mt2735/recipes-kernel/linux/files/user_build.cfg
@@ -4,7 +4,7 @@
 # CONFIG_PSTORE_FTRACE is not set
 # CONFIG_PSTORE_RAM is not set
 # CONFIG_MTK_WATCHDOG is not set
-CONFIG_CONSOLE_LOGLEVEL_DEFAULT=1
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=4
 # CONFIG_PAGE_OWNER is not set
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_SLUB_DEBUG_ON is not set
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/linux/linux-mtk-extension_4.19.bbappend b/meta/meta-mediatek-mt2735/recipes-kernel/linux/linux-mtk-extension_4.19.bbappend
index 0716be1..2aa6a0a 100755
--- a/meta/meta-mediatek-mt2735/recipes-kernel/linux/linux-mtk-extension_4.19.bbappend
+++ b/meta/meta-mediatek-mt2735/recipes-kernel/linux/linux-mtk-extension_4.19.bbappend
@@ -28,7 +28,6 @@
 
 SRC_URI += "\
         ${@bb.utils.contains('BUILD_TYPE', 'user', ' file://user_build.cfg', '', d)} \
-        file://boot_time.cfg \
 "
 
 SRC_URI += "\
diff --git a/meta/meta-mediatek-mt2735/recipes-modem/modem/modem_1.0.0.bb b/meta/meta-mediatek-mt2735/recipes-modem/modem/modem_1.0.0.bb
index 69a6031..bcfec01 100644
--- a/meta/meta-mediatek-mt2735/recipes-modem/modem/modem_1.0.0.bb
+++ b/meta/meta-mediatek-mt2735/recipes-modem/modem/modem_1.0.0.bb
@@ -3,61 +3,39 @@
 LIC_FILES_CHKSUM = "file://${MTK_LICENSE_DIR}/MediaTekProprietary;md5=c5d17c6905715d0948a3d6087602d12d"
 
 PACKAGE_ARCH = "${MACHINE_ARCH}"
-DEPENDS += "u-boot-mkimage-native bc-native dtc-native flashtool"
+DEPENDS += "u-boot-mkimage-native bc-native dtc-native"
 
 inherit workonsrc deploy nopackages
 inherit md-fitimage mddsp-fitimage hsm-sign-env staging-copyfile
 
 WORKONSRC = "${MODEM_DIR}"
 
+do_compile[noexec] = "1"
 do_install[noexec] = "1"
 
-MD_SRC_IMAGE = "modem.img"
-MD_DST_IMAGE = "md1img.img"
-DSP_SRC_IMAGE = "dsp.bin"
-DSP_DST_IMAGE = "md1dsp.img"
+MD_IMAGE = "md1img.img"
+MDDSP_IMAGE = "md1dsp.img"
 
 MD_OUT = "${WORKDIR}"
 
-run_lz4_compression() {
-    dec_size=0
-    fsize=$(stat -c "%s" "${MD_OUT}/${1}")
-    dec_size=$(expr $dec_size + $fsize)
-    lz4 -l -c9 ${MD_OUT}/${1} > ${MD_OUT}/${1}.lz4
-    mv -f ${MD_OUT}/${1}.lz4 ${MD_OUT}/${1}
-    printf "%08x\n" $dec_size |
-    sed 's/\(..\)/\1 /g' | {
-        read ch0 ch1 ch2 ch3;
-        for ch in $ch3 $ch2 $ch1 $ch0; do
-            printf `printf '%s%03o' '\\' 0x$ch` >> ${MD_OUT}/${1};
-        done;
-    }
-}
-
-do_compile () {
-    #mkdir -p ${MD_OUT}
-
-    cp -f ${S}/${MD_SRC_IMAGE} ${MD_OUT}/${MD_SRC_IMAGE}
-    cp -f ${S}/${DSP_SRC_IMAGE} ${MD_OUT}/${DSP_SRC_IMAGE}
-
-    if [ "${MODEM_COMPRESS}" = "lz4" ]; then
-        run_lz4_compression "${MD_SRC_IMAGE}"
-    fi
-    if [ "${DSP_COMPRESS}" = "lz4" ]; then
-        run_lz4_compression "${DSP_SRC_IMAGE}"
-    fi
-
-    do_assemble_fitimage
-    do_assemble_mdfitimage
-}
-
 do_deploy () {
     install -d ${DEPLOYDIR}
     find . -type d -exec install -d ${DEPLOYDIR}/{} \;
     find . -type f -exec install -m 755 {} ${DEPLOYDIR}/{} \;
 
-    install ${MD_OUT}/${MD_DST_IMAGE} ${DEPLOYDIR}/${MD_DST_IMAGE}
-    install ${MD_OUT}/${DSP_DST_IMAGE} ${DEPLOYDIR}/${DSP_DST_IMAGE}
+    if [ "${SECURE_BOOT_ENABLE}" = "yes" ] ; then
+        cp ${DEPLOYDIR}/dsp.bin ${WORKDIR}/dsp-org.bin
+        cp ${DEPLOYDIR}/modem.img ${WORKDIR}/modem-org.img
+
+        do_assemble_fitimage
+        do_assemble_mdfitimage
+
+    else
+        cp ${DEPLOYDIR}/dsp.bin ${MD_OUT}/${MDDSP_IMAGE}
+        cp ${DEPLOYDIR}/modem.img ${MD_OUT}/${MD_IMAGE}
+    fi
+    install ${MD_OUT}/${MD_IMAGE} ${DEPLOYDIR}/${MD_IMAGE}
+    install ${MD_OUT}/${MDDSP_IMAGE} ${DEPLOYDIR}/${MDDSP_IMAGE}
 }
 
-addtask deploy after do_compile
+addtask deploy after do_configure
diff --git a/src/bsp/lk/app/blxboot/blxboot.c b/src/bsp/lk/app/blxboot/blxboot.c
index 2b9352c..9a489f3 100644
--- a/src/bsp/lk/app/blxboot/blxboot.c
+++ b/src/bsp/lk/app/blxboot/blxboot.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2018 MediaTek Inc.
  *
@@ -25,9 +24,6 @@
 #include <app.h>
 #include <assert.h>
 #include <boot_mode.h>
-#if ENABLE_MODEM_LOAD_MULTI_THREAD
-#include <ccci_event.h>
-#endif
 #include <err.h>
 #include <errno.h>
 #include <fit.h>
@@ -159,7 +155,6 @@
     uint32_t *boot_mode;
     void *fdt_dtb, *dtbo, *vpd;
     int rc;
-    lk_bigtime_t __timer;
 
 #if (defined AVB_ENABLE_ANTIROLLBACK) || (defined AVB_ENABLE_DEVICE_STATE_CHANGE)
     rpmb_init();
@@ -212,15 +207,12 @@
             fastboot_on_fail = false;
         }
 
-        __timer = current_time_hires();
         if ((rc = load_all_images(blxobj)) == 0)
             break;
 
         if (fastboot_on_fail)
             *boot_mode = FASTBOOT_BOOT;
     } while (fastboot_on_fail);
-    __timer = current_time_hires() - __timer;
-    dprintf(ALWAYS,"load_all_images execution time: %llu (us). \n", __timer);
 
     if (rc != 0) {
         if (is_enabled_ab_ota_updater())
@@ -229,10 +221,6 @@
         return;
     }
 
-#if ENABLE_MODEM_LOAD_MULTI_THREAD
-    wait_for_md_cpu_task();
-#endif
-
     /* dtbo may contains kernel bootargs, do overlay_fdt before fixup_image */
     blxobj->ops.get_overlay_image(blxobj, &fdt_dtb, &dtbo, &vpd);
     if (fdt_dtb && (dtbo || vpd)) {
diff --git a/src/bsp/lk/app/blxboot/imagelist.c b/src/bsp/lk/app/blxboot/imagelist.c
index cc86735..e10aac7 100644
--- a/src/bsp/lk/app/blxboot/imagelist.c
+++ b/src/bsp/lk/app/blxboot/imagelist.c
@@ -274,14 +274,6 @@
     },
 #endif /* ENABLE_DSP_LOAD */
 
-#if ENABLE_MODEM_LOAD
-    {
-        .type = IMGTYPE_MODEM,
-        .load = load_md_image,
-        .imgdata = &mdimg,
-    },
-#endif
-
 #if ENABLE_KERNEL_LOAD
     {
         .type = IMGTYPE_KERNEL,
@@ -316,6 +308,14 @@
     },
 #endif /* ENABLE_SPM_FW_LOAD */
 
+#if ENABLE_MODEM_LOAD
+    {
+        .type = IMGTYPE_MODEM,
+        .load = load_md_image,
+        .imgdata = &mdimg,
+    },
+#endif
+
 #if ENABLE_MCUPM_LOAD
     {
         .type = IMGTYPE_MCUPM,
diff --git a/src/bsp/lk/lib/fit/fit.c b/src/bsp/lk/lib/fit/fit.c
index 132f19e..4ddeb93 100644
--- a/src/bsp/lk/lib/fit/fit.c
+++ b/src/bsp/lk/lib/fit/fit.c
@@ -105,7 +105,7 @@
  *    otherwise, on failure
  *
  */
-int fit_get_img_subnode_offset(void *fit, const char *image_name)
+static int fit_get_img_subnode_offset(void *fit, const char *image_name)
 {
     int noffset;
 
@@ -139,7 +139,7 @@
  *    otherwise, on failure
  *
  */
-int fit_get_def_cfg_offset(void *fit, const char *conf)
+static int fit_get_def_cfg_offset(void *fit, const char *conf)
 {
     int noffset, cfg_noffset, len;
 
@@ -528,7 +528,7 @@
     return 0;
 }
 
-int fit_image_integrity_check_process(void *arg)
+static int fit_image_integrity_check_process(void *arg)
 {
     int ret;
     struct verify_data *verify_info;
diff --git a/src/bsp/lk/platform/mt2735/bl2_bl33_options.mk b/src/bsp/lk/platform/mt2735/bl2_bl33_options.mk
index 53419ea..258d75c 100644
--- a/src/bsp/lk/platform/mt2735/bl2_bl33_options.mk
+++ b/src/bsp/lk/platform/mt2735/bl2_bl33_options.mk
@@ -1,4 +1,3 @@
-# SPDX-License-Identifier: MIT
 LOCAL_DIR := $(GET_LOCAL_DIR)
 
 ifeq ($(LK_AS_BL33),1)
@@ -30,9 +29,6 @@
 ENABLE_SSPM_LOAD := 0               # bl33 doesn't load sspm
 ENABLE_DPM_LOAD := 0                # bl33 doesn't load dpm
 
-# load modem image with multi-thread
-ENABLE_MODEM_LOAD_MULTI_THREAD := 1
-
 # bl33 boot options
 BL33_BOOT_NEXT_64BITS ?= 1          # boot stage after bl33 is 64 bits
 
@@ -67,8 +63,7 @@
 GLOBAL_DEFINES += \
     BL33_DRAM_SZ_MB=$(BL33_DRAM_SZ_MB) \
     BL33_BOOT_NEXT_64BITS=$(BL33_BOOT_NEXT_64BITS) \
-    ENABLE_MODEM_LOAD=$(ENABLE_MODEM_LOAD) \
-    ENABLE_MODEM_LOAD_MULTI_THREAD=$(ENABLE_MODEM_LOAD_MULTI_THREAD)
+    ENABLE_MODEM_LOAD=$(ENABLE_MODEM_LOAD)
 
 else
 
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/ccci_event.c b/src/bsp/lk/platform/mt2735/drivers/md/ccci_event.c
deleted file mode 100644
index 4b3bb87..0000000
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_event.c
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * 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>
-#include <kernel/event.h>
-#include <trace.h>
-
-#define LOCAL_TRACE 0
-
-event_t md_cpu_task_end_event = EVENT_INITIAL_VALUE(md_cpu_task_end_event, false, 0);
-
-void signal_md_cpu_end_event(void)
-{
-    LTRACEF_LEVEL(INFO, "Signal md cpu end event\n");
-    event_signal(&md_cpu_task_end_event, true);
-}
-
-void wait_for_md_cpu_task(void)
-{
-    LTRACEF_LEVEL(INFO, "Wait for md cpu task....\n");
-    event_wait(&md_cpu_task_end_event);
-    event_unsignal(&md_cpu_task_end_event);
-    LTRACEF_LEVEL(INFO, "md cpu task is done\n");
-}
\ No newline at end of file
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.c b/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.c
index db4b43a..719f143 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.c
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2016 MediaTek Inc.
  *
@@ -32,60 +31,247 @@
 #include <kernel/vm.h>
 #include <trace.h>
 
-#include "fit.h"
 #include "ccci_fit.h"
-
 #include "image.h"
 
-#define LOCAL_TRACE 1
+#define LOCAL_TRACE 0
 
-int fit_get_img_subnode_offset(void *fit, const char *image_name);
-int fit_get_def_cfg_offset(void *fit, const char *conf);
-int fit_image_integrity_check_process(void *arg);
+#define uswap_32(x) \
+    ((((x) & 0xff000000) >> 24) | \
+     (((x) & 0x00ff0000) >>  8) | \
+     (((x) & 0x0000ff00) <<  8) | \
+     (((x) & 0x000000ff) << 24))
 
-int ccci_fit_decompress_data(void *fit,
-                        void *decomp_addr, size_t *load_size)
+int ccci_fit_image_get_node(const void *fit, const char *image_uname)
 {
-    int len, ret;
-    size_t size;
-    const void *data, *compression;
-    int noffset = 0, cfg_noffset = 0;
-    const char *image_name;
+    int noffset, images_noffset;
 
-    cfg_noffset = fit_get_def_cfg_offset(fit, NULL);
-    if (cfg_noffset < 0)
-        return EINVAL;
-
-    /* unit name: fdt@1, kernel@2, ramdisk@3 and so on */
-    image_name = (char *)fdt_getprop(fit, cfg_noffset, "kernel", &len);
-    if (image_name == NULL) {
-        LTRACEF("%s get image name failed\n", "kernel");
-        return -ENOENT;
+    images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+    if (images_noffset < 0) {
+        dprintf(CRITICAL,"Can't find images parent node '%s' (%s)\n",
+                FIT_IMAGES_PATH, fdt_strerror(images_noffset));
+        return images_noffset;
     }
 
-    /* get this sub image node offset */
-    noffset = fit_get_img_subnode_offset(fit, image_name);
+    noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
     if (noffset < 0) {
-        dprintf(CRITICAL, "get sub image node (%s) failed\n", image_name);
+        dprintf(CRITICAL,"Can't get node offset for image name: '%s' (%s)\n",
+                image_uname, fdt_strerror(noffset));
+    }
+
+    return noffset;
+}
+
+int ccci_fit_image_get_data(const void *fit, int noffset,
+                       const void **data, uint32_t *size)
+{
+    int len;
+    *data = fdt_getprop(fit, noffset, FDT_DATA_NODE, &len);
+    if (*data == NULL)
+        return -1;
+
+    *size = len;
+
+    return 0;
+}
+
+int ccci_fit_conf_get_prop_node(const void *fit, int noffset,
+                           const char *prop_name)
+{
+    char *uname;
+    int len;
+
+    /* get kernel image unit name from configuration kernel property */
+    uname = (char *)fdt_getprop(fit, noffset, prop_name, &len);
+    if (uname == NULL)
+        return len;
+
+    return ccci_fit_image_get_node(fit, uname);
+}
+
+/**
+ * fit_get_img_subnode_offset() - get a subnode offset for a given image name
+ *
+ * This finds subnode offset using given image name within node "/images"
+ *
+ * @fit:    fit image start address
+ * @image_name: image name. "kernel", "fdt" or "ramdisk"...
+ *
+ * returns:
+ *    great than or equal 0, on success
+ *    otherwise, on failure
+ *
+ */
+static int ccci_fit_get_img_subnode_offset(void *fit, const char *image_name)
+{
+    int noffset;
+
+    /* get image node offset */
+    noffset = fdt_path_offset(fit, "/images");
+    if (noffset < 0) {
+        dprintf(CRITICAL, "Can't find image node(%s)\n", fdt_strerror(noffset));
         return noffset;
     }
 
+    /* get subnode offset */
+    noffset = fdt_subnode_offset(fit, noffset, image_name);
+    if (noffset < 0)
+        dprintf(CRITICAL, "Can't get node offset for image name: '%s' (%s)\n",
+                image_name, fdt_strerror(noffset));
+
+    return noffset;
+}
+
+/**
+ * fit_get_def_cfg_offset() - get a subnode offset from node "/configurations"
+ *
+ * This finds configuration subnode offset in node "configruations".
+ * If "conf" is not given, it will find property "default" for the case.
+ *
+ * @fit:    fit image start address
+ * @conf:   configuration name
+ *
+ * returns:
+ *    great than or equal 0, on success
+ *    otherwise, on failure
+ *
+ */
+static int ccci_fit_get_def_cfg_offset(void *fit, const char *conf)
+{
+    int noffset, cfg_noffset, len;
+
+    noffset = fdt_path_offset(fit, "/configurations");
+    if (noffset < 0) {
+        dprintf(CRITICAL, "can't find configuration node\n");
+        return noffset;
+    }
+
+    if (conf == NULL) {
+        conf = (char *)fdt_getprop(fit, noffset,
+                                   "default", &len);
+        if (conf == NULL) {
+            dprintf(CRITICAL, "Can't get default conf name\n");
+            return len;
+        }
+        dprintf(SPEW, "got default conf: %s\n", conf);
+    }
+
+    cfg_noffset = fdt_subnode_offset(fit, noffset, conf);
+    if (cfg_noffset < 0)
+        dprintf(CRITICAL, "Can't get conf subnode\n");
+    else
+        dprintf(SPEW, "got conf: %s subnode\n", conf);
+
+    return cfg_noffset;
+}
+
+int ccci_fit_get_image(const char *label,  void **load_buf)
+{
+    bdev_t *bdev = NULL;
+    struct fdt_header fdt = {0};
+    size_t totalsize = 0;
+    int fdt_len = 0, ret = 0;
+    void *fit_buf = NULL;
+
+    fdt_len = sizeof(struct fdt_header);
+    bdev = bio_open_by_label(label) ? : bio_open(label);
+    if (!bdev) {
+        dprintf(CRITICAL, "Partition [%s] is not exist.\n", label);
+        return -ENODEV;
+    }
+
+    if (bio_read(bdev, &fdt, 0, fdt_len) < fdt_len) {
+        ret = -EIO;
+        goto closebdev;
+    }
+
+    ret = fdt_check_header(&fdt);
+    if (ret) {
+        dprintf(CRITICAL, "[%s] check header failed\n", label);
+        goto closebdev;
+    }
+
+    totalsize = fdt_totalsize(&fdt);
+    fit_buf = mempool_alloc(totalsize, MEMPOOL_ANY);
+    if (!fit_buf) {
+        ret = -ENOMEM;
+        goto closebdev;
+    }
+
+    if (bio_read(bdev, fit_buf, 0, totalsize) < totalsize) {
+        ret = -EIO;
+        goto closebdev;
+    }
+    *load_buf = fit_buf;
+
+closebdev:
+    bio_close(bdev);
+    if ((ret != 0) && (fit_buf != NULL))
+        mempool_free(fit_buf);
+
+    return ret;
+}
+
+int ccci_fit_processing_data(void *fit, const char *image_name, int noffset,
+                        addr_t *load, size_t *load_size, paddr_t *entry)
+{
+    int len, ret, ac;
+    size_t size;
+    const char *type;
+    const void *data, *compression;
+    const uint32_t *load_prop, *entry_prop;
+    addr_t load_addr;
+    paddr_t entry_addr;
+
     data = fdt_getprop(fit, noffset, "data", &len);
     if (!data) {
-        dprintf(CRITICAL, "%s can't get prop data\n", __func__);
+        dprintf(CRITICAL, "%s can't get prop data\n", image_name);
         return len;
     }
     size = len;
 
     compression = fdt_getprop(fit, noffset, "compression", &len);
     if (!compression) {
-        dprintf(CRITICAL, "%s compression is not specified\n", __func__);
+        dprintf(CRITICAL, "%s compression is not specified\n", image_name);
         return -EINVAL;
     }
 
+    type = fdt_getprop(fit, noffset, "type", &len);
+    if (!type) {
+        dprintf(CRITICAL, "%s image type is not specified\n", image_name);
+        return -EINVAL;
+    }
+
+    /* read address-cells from root */
+    ac = fdt_address_cells(fit, 0);
+    if (ac <= 0 || (ac > sizeof(ulong) / sizeof(uint))) {
+        LTRACEF("%s #address-cells with a bad format or value\n", image_name);
+        return -EINVAL;
+    }
+
+    load_prop = fdt_getprop(fit, noffset, "load", &len);
+    if (!load_prop &&
+            (!strcmp(type, "kernel") || (!strcmp(type, "loadable")))) {
+        dprintf(CRITICAL, "%s need load addr\n", image_name);
+        return -EINVAL;
+    }
+
+    /* load address determination:
+     *   1. "load" property exist: use address in "load" property
+     *   2. "load" property not exist: use runtime address of "data" property
+     */
+    load_addr = (addr_t)data;
+    if (load_prop) {
+        load_addr = (addr_t)uswap_32(load_prop[0]);
+        if (ac == 2)
+            load_addr = (load_addr << 32) | (addr_t)uswap_32(load_prop[1]);
+#if WITH_KERNEL_VM
+        load_addr = (addr_t)paddr_to_kvaddr(load_addr);
+#endif
+    }
+
     if (!strcmp((char *)compression, "lz4")) {
-        LTRACEF("[%s] start decompress\n", __func__);
-        ret = unlz4(data, size - 4, decomp_addr);
+        ret = unlz4(data, size - 4, (void *)(load_addr));
         if (ret != LZ4_OK) {
             dprintf(ALWAYS, "lz4 decompress failure\n");
             return -LZ4_FAIL;
@@ -94,28 +280,117 @@
          * kernel image size */
         size = *(u32 *)(data + size - 4);
     } else if (!strcmp((char *)compression, "none")) {
-        LTRACEF("[%s] copy image\n", __func__);
-        memmove(decomp_addr, data, size);
+        memmove((void *)(load_addr), data, size);
     } else {
-        dprintf(CRITICAL, "%s compression does not support\n", __func__);
+        dprintf(CRITICAL, "%s compression does not support\n", image_name);
         return -EINVAL;
     }
 
 #if WITH_KERNEL_VM
     /* always flush cache to PoC */
-    arch_clean_cache_range(decomp_addr, size);
+    arch_clean_cache_range(load_addr, size);
 #endif
 
-    LTRACEF("[%s] load_addr %p\n", __func__, decomp_addr);
-    LTRACEF("[%s] fit = %p\n", __func__, fit);
-    LTRACEF("[%s] data = %p\n", __func__, data);
-    LTRACEF("[%s] size = %zu\n", __func__, size);
+    LTRACEF("[%s] load_addr 0x%lx\n", image_name, load_addr);
+    LTRACEF("[%s] fit = %p\n", image_name, fit);
+    LTRACEF("[%s] data = %p\n", image_name, data);
+    LTRACEF("[%s] size = %zu\n", image_name, size);
+
+    /* return load, load_size and entry address if caller spcified */
+    if (load)
+        *load = load_addr;
 
     if (load_size)
         *load_size = size;
 
+    if (entry) {
+        /*
+         * entry address determination:
+         *   1. "entry" property not exist: entry address = load address
+         *   2. "entry" & "load" properties both exist: "entry" property
+         *      contains the absolute address of entry, thus
+         *      entry address = "entry"
+         *   3. only "entry" property exist: "entry" property contains the
+         *      entry offset to load address, thus
+         *      entry address = "entry" + load address
+         */
+
+#if WITH_KERNEL_VM
+        load_addr = kvaddr_to_paddr((void *)load_addr);
+#endif
+        entry_addr = load_addr;
+        entry_prop = fdt_getprop(fit, noffset, "entry", &len);
+        if (entry_prop) {
+            entry_addr = (paddr_t)uswap_32(entry_prop[0]);
+            if (ac == 2) {
+                entry_addr = (entry_addr << 32) |
+                             (paddr_t)uswap_32(entry_prop[1]);
+            }
+            entry_addr += load_prop ? 0 : load_addr;
+        }
+        *entry = entry_addr;
+
+        LTRACEF("[%s] entry_addr 0x%lx\n", image_name, *entry);
+    }
+
     return 0;
 }
+
+int ccci_fit_load_loadable_image(void *fit, const char *sub_node_name, addr_t *load)
+{
+    int noffset;
+    int ret;
+
+    noffset = ccci_fit_get_img_subnode_offset(fit, sub_node_name);
+    if (noffset < 0) {
+        LTRACEF("%s: fit_get_img_subnode_offset fail\n", sub_node_name);
+        return noffset;
+    }
+
+    if (hash_check_enabled()) {
+        ret = fit_image_integrity_verify(fit, noffset);
+        LTRACEF("%s: integrity check %s\n",
+                sub_node_name, ret ? "fail" : "pass");
+        if (ret)
+            return -EACCES;
+    }
+
+    return ccci_fit_processing_data(fit, sub_node_name, noffset, load, NULL, NULL);
+}
+
+int ccci_fit_conf_verify_sig(const char *conf, void *fit)
+{
+    int ret;
+    int noffset;
+
+    /* get defualt configuration offset (conf@1, conf@2,...or confg@n) */
+    noffset = ccci_fit_get_def_cfg_offset(fit, conf);
+    if (noffset < 0)
+        return noffset;
+
+    /* verify config signature */
+    if (rsa_check_enabled()) {
+        ret = fit_verify_sign(fit, noffset);
+        dprintf(ALWAYS, "Verify sign: %s\n", ret ? "fail" : "pass");
+        if (ret)
+            return -EACCES;
+    }
+
+    return 0;
+}
+
+static int ccci_fit_image_integrity_check_process(void *arg)
+{
+    int ret;
+    struct verify_data *verify_info;
+
+    verify_info = (struct verify_data *)arg;
+    ret = fit_image_integrity_verify(verify_info->fit_image,
+            verify_info->noffset);
+
+    return ret;
+}
+
 int ccci_fit_load_image(const char *conf, const char *img_pro, void *fit,
                    addr_t *load, size_t *load_size, paddr_t *entry,
                    bool need_verified)
@@ -126,7 +401,7 @@
     thread_t *integrity_verify_t;
 
     /* get defualt configuration offset (conf@1, conf@2,...or confg@n) */
-    cfg_noffset = fit_get_def_cfg_offset(fit, conf);
+    cfg_noffset = ccci_fit_get_def_cfg_offset(fit, conf);
     if (cfg_noffset < 0)
         return cfg_noffset;
 
@@ -138,7 +413,7 @@
     }
 
     /* get this sub image node offset */
-    noffset = fit_get_img_subnode_offset(fit, image_name);
+    noffset = ccci_fit_get_img_subnode_offset(fit, image_name);
     if (noffset < 0) {
         dprintf(CRITICAL, "get sub image node (%s) failed\n", image_name);
         return noffset;
@@ -146,12 +421,39 @@
 
     /* verify integrity of this image */
     if (hash_check_enabled() && need_verified) {
+#if WITH_SMP
+        struct verify_data verify_info;
+        verify_info.fit_image = fit;
+        verify_info.noffset = noffset;
+
+        integrity_verify_t = thread_create("integrity_verify_t",
+            &ccci_fit_image_integrity_check_process, &verify_info,
+            DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
+
+        /* Assigned the thread to active cpu */
+        extern __WEAK void plat_mp_assign_workcpu(thread_t *t);
+        plat_mp_assign_workcpu(integrity_verify_t);
+        thread_resume(integrity_verify_t);
+#else
         ret = fit_image_integrity_verify(fit, noffset);
         LTRACEF_LEVEL(CRITICAL, "check %s integrity: %s\n",
                 image_name, ret ? "fail" : "pass");
         if (ret < 0)
             return -EACCES;
+#endif
     } /* verify end */
 
+    //rc = fit_processing_data(fit, image_name, noffset, load, load_size, entry);
+
+#if WITH_SMP
+    if (hash_check_enabled() && need_verified) {
+        thread_join(integrity_verify_t, &ret, INFINITE_TIME);
+        LTRACEF_LEVEL(CRITICAL, "check %s integrity: %s\n",
+                image_name, ret ? "fail" : "pass");
+        if (ret < 0)
+            return -EACCES;
+    }
+#endif
+
     return rc;
 }
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.h b/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.h
index 03dfd33..bbdee29 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.h
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.h
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2016 MediaTek Inc.
  *
@@ -26,10 +25,86 @@
 #include <stdbool.h>
 #include <sys/types.h>
 
+/**
+ * fit_get_image() - load fit image from a partition
+ *
+ * the function will use bio to access a partition from a storage and
+ * check fdt header. If pass, allocate memory buffer to read the fit image
+ * to load_buf
+ *
+ * @label:      partition name
+ * @load_buf:   pointer to buffer pointer, the address of allocated memory
+ *              buffer with fit image loaded was passing back to the caller
+ *              via this argument.
+ *
+ * returns:
+ *     0, on success
+ *     otherwise, on failure
+ *
+ */
+int ccci_fit_get_image(const char *label,  void **load_buf);
+
+/**
+ * fit_image_get_data() - get data property of a subimage node
+ * @fit:        fit image start address
+ * @noffset:    the offset to the subimage node
+ * @data:       return data pointer
+ * @size:       return data size
+ *
+ * returns:
+ *     0, on success
+ *     otherwise, on failure
+ */
+int ccci_fit_image_get_data(const void *fit, int noffset,
+                       const void **data, uint32_t *size);
+/**
+ * fit_conf_verify_sig() - verify fit configuration signature
+ *
+ * @conf:   configuration name
+ * @fit:    fit image start address
+ *
+ * returns:
+ *    0, on success
+ *    otherwise, on failure
+ */
+int ccci_fit_conf_verify_sig(const char *conf, void *fit);
+
+/**
+ * fit_load_image() - load fit image to proper address
+ *
+ * This checks FIT configuration to find sub-image nodes image
+ * and load the image to right address
+ *
+ * @conf:           configuration name
+ * @img_pro:        image property name
+ * @fit:            fit image start address
+ * @load:           returned load address
+ * @load_size:      returned loaded raw image size
+ * @entry:          returned entry address
+ * @need_verified:  whether to check image integrity
+ *
+ * returns:
+ *    0, on success
+ *    otherwise, on failure
+ *
+ */
 int ccci_fit_load_image(const char *conf, const char *img_pro, void *fit,
                    addr_t *load, size_t *load_size, paddr_t *entry,
                    bool need_verified);
 
-int ccci_fit_decompress_data(void *fit,
-                   void *decomp_addr, size_t *load_size);
-
+/**
+ * fit_load_loadable_image() - load "loadable" images to "load" address
+ *
+ * This function finds "sub_node_name" loadable image nodes, do integrity check
+ * per hash_check_enabled(), and load images to "load" address.
+ *
+ * @fit:            fit image start address
+ * @sub_node_name:  loadable image subnode name
+ * @load:           returned loadable image load address
+ *
+ * return:
+ *      0: success
+ *      otherwise: failure error code
+ *
+ */
+int ccci_fit_load_loadable_image(void *fit, const char *sub_node_name, addr_t *load);
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_api_wrapper.c b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_api_wrapper.c
index c4a8ce0..8c08720 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_api_wrapper.c
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_api_wrapper.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2020 MediaTek Inc.
  *
@@ -179,3 +178,38 @@
 
     return size;
 }
+
+int ccci_load_raw_data(const char *part_name, unsigned char *mem_addr,
+    unsigned int offset, int size)
+{
+    bdev_t *bdev;
+    int len;
+    LD_DBG_LOG("%s, name[%s], mem_addr[%p], offset[%x], size[%x]\n", __func__,
+        part_name, mem_addr, offset, size);
+    bdev = bio_open_by_label(part_name);
+    if (!bdev) {
+        ALWAYS_LOG("partition %s not exists\n", part_name);
+        return -LD_ERR_PT_NOT_FOUND;//return -ENODEV;
+    }
+    LD_DBG_LOG(" > to 0x%llx (at dram), size:0x%x\n", (u64)((unsigned long)mem_addr), size);
+    len = bio_read(bdev, mem_addr, offset, size);
+    if (len < 0) {
+        ALWAYS_LOG("[%s] %s boot image header read error. LINE: %d\n",
+            MODULE_NAME, part_name, __LINE__);
+        return -LD_ERR_PT_READ_RAW_FAIL;
+    }
+    bio_close(bdev);
+    arch_clean_cache_range((addr_t)mem_addr, size);
+    LD_DBG_LOG("%s clen cache done\n", __func__);
+    return len;
+}
+
+void ccci_ld_md_wrapper_api_init(void)
+{
+}
+
+
+/* This function should be called after ccci_tag_info function ready */
+void ccci_ld_md_add_wrapper_api_info(void)
+{
+}
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 e18e3dd..57ff400 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
@@ -37,14 +37,8 @@
 #include <stdint.h>
 #include <string.h>
 #include "ccci_fit.h"
-#include <fit.h>
-#include <lib/mempool.h>
 
 #include "mtk_ccci_ld_md.h"
-#if ENABLE_MODEM_LOAD_MULTI_THREAD
-#include <kernel/thread.h>
-#include "ccci_event.h"
-#endif
 #include "ccci_ld_md_core.h"
 #include "ccci_ld_md_errno.h"
 #include "ccci_ld_md_tel.h"
@@ -67,14 +61,10 @@
 {
     char *label;
     void *load_buf;
-    void *decompress_buf;
 };
 
 static struct fit_buf get_fit_buf[5] = {0};
-static struct download_info_s *image_list = NULL;
-static char part_name_buf[256] = {0};
-static int img_num = 0;
-
+static char part_name_buf[1024] ={0};
 
 static void add_hdr_info(struct modem_info_s tbl[], struct modem_info_s *hdr)
 {
@@ -156,12 +146,44 @@
     return ret_val;
 }
 
+static int find_offset_mdfit(void *fit)
+{
+    int load_size, hdr_offset = 0;
+    int buf_size = 512;
+    char *buf = malloc(buf_size);
+    unsigned int *tmp = NULL;
+
+    while(1)
+    {
+        load_size = (int)ccci_copy_raw_data(fit, (unsigned char*)buf, hdr_offset, buf_size);
+        if ((unsigned int)load_size != buf_size) {
+            ALWAYS_LOG("load hdr fail(%d)\n", load_size);
+            return -1;
+        }
+
+        for(tmp = (unsigned int *)buf ; tmp< buf + buf_size; tmp++)
+        {
+            if (*tmp == MKIMG_MAGIC) {
+                ALWAYS_LOG("find magic\n");
+                free(buf);
+                return hdr_offset;
+            }
+            if (hdr_offset > 50000) {
+                ALWAYS_LOG("can't find magic\n");
+                free(buf);
+                return -LD_ERR_PT_P_HDR_MAGIC_MIS_MATCH;
+            }
+            hdr_offset = hdr_offset + 4;
+         }
+    }
+}
+
 static int find_hdr_in_partition_mem(void *fit, const char *hdr_name,
     union mkimg_hdr *p_hdr, unsigned int p_hdr_size)
 {
     int load_size;
-    int hdr_offset = 0;
-
+    int hdr_offset = find_offset_mdfit(fit);
+    ALWAYS_LOG("hdr_offset(0x%x)\n", hdr_offset);
     while (1) {
         load_size = (int)ccci_copy_raw_data(fit,
             (unsigned char *)p_hdr, hdr_offset, p_hdr_size);
@@ -185,28 +207,28 @@
 }
 static int find_hdr_in_partiton(const char *partition_name, const char *hdr_name, union mkimg_hdr *p_hdr, unsigned int p_hdr_size)
 {
-    int load_size;
-    int hdr_offset = 0;
+	int load_size;
+	int hdr_offset = 0;
 
-    while (1) {
-        load_size = (int)ccci_load_raw_data(partition_name, (unsigned char*)p_hdr, hdr_offset, p_hdr_size);
-        if ((unsigned int)load_size != p_hdr_size) {
-            ALWAYS_LOG("load hdr fail(%d)\n", load_size);
-            return -1;
-        }
-        if (p_hdr->info.magic != MKIMG_MAGIC) {
-            ALWAYS_LOG("invalid magic(%x):(%x)ref\n", p_hdr->info.magic, MKIMG_MAGIC);
-            return -LD_ERR_PT_P_HDR_MAGIC_MIS_MATCH;
-        }
-        if (strcmp(p_hdr->info.name, hdr_name) == 0)
-            return hdr_offset;
+	while(1) {
+		load_size = (int)ccci_load_raw_data(partition_name, (unsigned char*)p_hdr, hdr_offset, p_hdr_size);
+		if ((unsigned int)load_size != p_hdr_size) {
+			ALWAYS_LOG("load hdr fail(%d)\n", load_size);
+			return -1;
+		}
+		if (p_hdr->info.magic != MKIMG_MAGIC) {
+			ALWAYS_LOG("invalid magic(%x):(%x)ref\n", p_hdr->info.magic, MKIMG_MAGIC);
+			return -LD_ERR_PT_P_HDR_MAGIC_MIS_MATCH;
+		}
+		if (strcmp(p_hdr->info.name, hdr_name) == 0)
+			return hdr_offset;
 
-        hdr_offset += p_hdr->info.hdr_sz;
-        hdr_offset += ((p_hdr->info.dsz + p_hdr->info.align_sz - 1) & (~(p_hdr->info.align_sz - 1)));
-    }
+		hdr_offset += p_hdr->info.hdr_sz;
+		hdr_offset += ((p_hdr->info.dsz + p_hdr->info.align_sz - 1) & (~(p_hdr->info.align_sz - 1)));
+	}
 }
 
-static int copy_image_by_name(void *image, const char *name,
+static int copy_image_by_name(void *fit, const char *name,
                 unsigned char *mem_addr, unsigned int max_size, unsigned int flags)
 {
     int i = 0;
@@ -224,7 +246,7 @@
         return -LD_ERR_PT_ALLOC_HDR_MEM_FAIL;
     }
 
-    hdr_offset = find_hdr_in_partition_mem(image, name, p_hdr, sizeof(union mkimg_hdr));
+    hdr_offset = find_hdr_in_partition_mem(fit, name, p_hdr, sizeof(union mkimg_hdr));
 
     if (hdr_offset < 0) {
         ALWAYS_LOG("load sub image %s fail\n", name);
@@ -246,7 +268,7 @@
     }
 
     /* load image raw data */
-    load_size = (int)ccci_copy_raw_data(image, mem_addr,
+    load_size = (int)ccci_copy_raw_data(fit, mem_addr,
         hdr_offset + p_hdr->info.hdr_sz, p_hdr->info.dsz);
     if ((unsigned int)load_size != p_hdr->info.dsz) {
         ALWAYS_LOG("load sub-image data fail(%d:%d)\n", load_size, p_hdr->info.dsz);
@@ -268,9 +290,76 @@
     return ret;
 }
 
+static int load_image_by_name(const char *partition_list[], const char *name,
+				unsigned char *mem_addr, unsigned int max_size, unsigned int flags)
+{
+	int i = 0;
+	int hdr_offset;
+	union mkimg_hdr *p_hdr;
+	int load_size;
+	int ret = -1;
+	int img_size_with_padding;
+	int partiton_idx = 0;
 
+	/* allocate partition header  memory first */
+	p_hdr = (union mkimg_hdr *)malloc(sizeof(union mkimg_hdr));
+	if (p_hdr==NULL) {
+		ALWAYS_LOG("alloc mem for hdr fail\n");
+		return -LD_ERR_PT_ALLOC_HDR_MEM_FAIL;
+	}
 
-static int load_main_image(struct download_info_s *main_img, void* image,
+	while (partition_list[i] != NULL) {
+		hdr_offset = find_hdr_in_partiton(partition_list[i], name, p_hdr, sizeof(union mkimg_hdr));
+		if (hdr_offset < 0) {
+			i++;
+			continue;
+		}
+		partiton_idx = i;
+		break;
+	}
+
+	if (hdr_offset < 0) {
+		ALWAYS_LOG("load sub image %s fail\n", name);
+		ret = -LD_ERR_GET_COM_CHK_HDR_FAIL;
+		goto _Exit;
+	}
+
+	LD_DBG_LOG("dump p_hdr info\n");
+	LD_DBG_LOG(" p_hdr->info.magic:%x\n", p_hdr->info.magic);
+	LD_DBG_LOG(" p_hdr->info.dsz:%x\n", p_hdr->info.dsz);
+	LD_DBG_LOG(" p_hdr->info.name:%s\n", p_hdr->info.name);
+	LD_DBG_LOG(" p_hdr->info.mode:%x\n", p_hdr->info.mode);
+	LD_DBG_LOG(" p_hdr->info.hdr_sz:%x\n", p_hdr->info.hdr_sz);
+
+	if (p_hdr->info.dsz > max_size) {
+		ALWAYS_LOG("load sub image %s fail\n", name);
+		ret = -LD_ERR_PT_IMG_TOO_LARGE;
+		goto _Exit;
+	}
+
+	/* load image raw data */
+	load_size = (int)ccci_load_raw_data(partition_list[i], mem_addr, hdr_offset + p_hdr->info.hdr_sz,
+						p_hdr->info.dsz);
+	if ((unsigned int)load_size != p_hdr->info.dsz) {
+		ALWAYS_LOG("load sub-image data fail(%d:%d)\n", load_size, p_hdr->info.dsz);
+		ret = -LD_ERR_PT_LD_IMG_DATA_FAIL;
+		goto _Exit;
+	}
+
+	/* Calcualte size that add padding */
+	img_size_with_padding = (load_size + p_hdr->info.align_sz - 1) & (~(p_hdr->info.align_sz -1));
+	/* Clear padding data to 0 */
+	for (i = 0; i < img_size_with_padding - (int)p_hdr->info.dsz; i++)
+		mem_addr[p_hdr->info.dsz + i] = 0;
+
+	ret = load_size;
+
+_Exit:
+	free(p_hdr);
+	return ret;
+}
+
+static int load_main_image(struct download_info_s *main_img,
     unsigned char **base_addr, int *resv_mem_size)
 {
     unsigned char *md_mem_base;
@@ -286,9 +375,34 @@
         load_size = ret;
         goto _Exit;
     }
+#ifdef MTK_SECURITY_SW_SUPPORT
+    get_fit_buf[0].label = main_img->partition_name;
 
-    load_size = copy_image_by_name(image, main_img->image_name, md_mem_base,
+    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);
+        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);
+        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");
+        goto _Exit;
+    }
+    load_size = copy_image_by_name(get_fit_buf[0].load_buf, main_img->image_name, md_mem_base,
         main_img->max_size, main_img->ext_flag);
+#else
+    partition_list[0] = main_img->partition_name;
+    partition_list[1] = NULL;
+    load_size = load_image_by_name(partition_list, main_img->image_name, md_mem_base,
+        main_img->max_size, main_img->ext_flag);
+#endif
     if (load_size < 0) {
         ret = load_size;
         /* If enter this function, it means we hope modem feature should be support,
@@ -346,20 +460,38 @@
     return 0;
 }
 
-/* --- load md raw data to DRAM that listed at table --- */
-static int ld_img_at_list(struct modem_info_s *info)
+/* --- 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;
     int md_mem_resv_size = 0;
     int md_mem_required_size = 0;
     unsigned char *md_resv_mem_addr = NULL;
     int ret = 0;
-    int i = 0;
+    int i = 0, j = 0;
+    struct download_info_s *curr;
     struct download_info_s *md_main_img;
-    md_main_img = image_list;
+    void *fit = NULL;
+    const char *partition_list[2];
+
+    if (img_list == NULL) {
+        ALWAYS_LOG("image list is NULL!\n");
+        return -LD_ERR_PT_IMG_LIST_NULL;
+    }
+    /* find main image at list */
+    curr = img_list;
+    while (curr->img_type != 0) {
+        if (curr->img_type == main_img)
+            break;
+        curr++;
+    }
+    if (curr->img_type != main_img)
+        return -LD_ERR_ASS_FIND_MAIN_INF_FAIL;
+
+    md_main_img = curr;
 
     /* alloc memory and load main image */
-    ret = load_main_image(md_main_img, get_fit_buf[0].decompress_buf, &md_resv_mem_addr, &md_mem_resv_size);
+    ret = load_main_image(md_main_img, &md_resv_mem_addr, &md_mem_resv_size);
     if (ret < 0)
         goto _MD_Exit;
     /* check header verify and sub image offset and size update */
@@ -367,13 +499,14 @@
     info->resv_mem_size = md_mem_resv_size;
     info->load_size = ret;
     ret = verify_main_img_check_header(info);
+
     if (ret < 0) {
         ALWAYS_LOG("md check header verify fail:%d\n", ret);
         goto _MD_Exit;
     }
 
     if (md_main_img->ass_func) {
-        ret = md_main_img->ass_func((void *)info, (void *)image_list);
+        ret = md_main_img->ass_func((void *)info, (void *)img_list);
         if (ret < 0) {
             ALWAYS_LOG("assistan func process fail:%d\n", ret);
             goto _MD_Exit;
@@ -382,31 +515,74 @@
     md_mem_required_size = info->resv_mem_size;
 
     /* load sub image one by one */
-    i = 1;
-    while (image_list[i].img_type != 0) {
+    curr = img_list;
+    i = 0;
+    while (curr[i].img_type != 0) {
+        get_fit_buf[i].label = curr[i].partition_name;
+
+        /* By pass main image */
+        if (curr[i].img_type == main_img) {
+            i++;
+            continue;
+        }
         /* By pass ext image that no need to load after query main image setting */
-        if ((image_list[i].mem_addr == NULL) || (image_list[i].img_size == 0)) {
+        if ((curr[i].mem_addr == NULL) || (curr[i].img_size == 0)) {
             i++;
             continue;
         }
 
+#ifdef MTK_SECURITY_SW_SUPPORT
+        //check part already load or not
+        for(j= 0; j < i; j++) {
+            if(strcmp(get_fit_buf[i].label, get_fit_buf[j].label) == 0) {
+                get_fit_buf[i].load_buf = get_fit_buf[j].load_buf;
+                break;
+            }
+        }
 
-        load_size = copy_image_by_name(get_fit_buf[i].decompress_buf, image_list[i].image_name, image_list[i].mem_addr,
-                        image_list[i].max_size, image_list[i].ext_flag);
-        if ((load_size >= 0) && (load_size > image_list[i].img_size)) {
+        //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);
+                goto _MD_Exit;
+            }
+
+            ret = ccci_fit_conf_verify_sig(NULL, get_fit_buf[i].load_buf);
+            if (ret < 0) {
+                ALWAYS_LOG("fit_conf_verify_sig failed: %s %d!\n", get_fit_buf[i].label, ret);
+                goto _MD_Exit;
+            }
+
+            ret = ccci_fit_load_image(NULL, "kernel", get_fit_buf[i].load_buf, NULL ,NULL, NULL, true);
+            if (ret < 0) {
+                ALWAYS_LOG("MD-fit image verify failed!\n");
+                goto _MD_Exit;
+            }
+        }
+
+        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
+        partition_list[0] = curr[i].partition_name;
+        partition_list[1] = NULL;
+        load_size = load_image_by_name(partition_list, curr[i].image_name, curr[i].mem_addr,
+                        curr[i].max_size, curr[i].ext_flag);
+#endif
+        if ((load_size >= 0) && (load_size > curr[i].img_size)) {
             ALWAYS_LOG("image size not sync to chk_hdr hdr:[0x%x]<>a:[0x%x]\n",
-                       image_list[i].img_size, load_size);
+                       curr[i].img_size, load_size);
             ret = -LD_ERR_PT_IMG_SIZE_NOT_SYNC_CHK_HDR;
             goto _MD_Exit;
         } else if (load_size < 0) {
             ALWAYS_LOG("load sub image: %s fail with ret info: %s\n",
-                       image_list[i].image_name, ld_md_errno_to_str(load_size));
+                       curr[i].image_name, ld_md_errno_to_str(load_size));
             ret = load_size;
             goto _MD_Exit;
         }
-        if (image_list[i].img_type == dsp_img) {
-            image_list[i].img_size = load_size;
-            ret = dsp_img_post_process(&image_list[i], info->md_id);
+        if (curr[i].img_type == dsp_img) {
+            curr[i].img_size = load_size;
+            ret = dsp_img_post_process(&curr[i], info->md_id);
             if (ret < 0)
                 goto _MD_Exit;
         }
@@ -434,72 +610,11 @@
     return ret;
 }
 
-
-/* --- load raw data to DRAM from storage --- */
-static int ld_list_img_from_storge(struct download_info_s img_list[])
-{
-    int i = 0, j = 0;
-    int ret = 0;
-
-    /* first image need main image */
-    if (img_list[i].img_type != main_img)
-        return -LD_ERR_ASS_FIND_MAIN_INF_FAIL;
-
-    while (img_list[i].img_type != 0) {
-        /* get partition name */
-        get_fit_buf[i].label = img_list[i].partition_name;
-
-        // check part already load or not
-        for (j = 0; j < i; j++) {
-            if (strcmp(get_fit_buf[i].label, get_fit_buf[j].label) == 0) {
-                get_fit_buf[i].load_buf = get_fit_buf[j].load_buf;
-                break;
-            }
-        }
-
-        // already load
-        if (j != i) {
-            i++;
-            continue;
-        }
-
-        ret = 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);
-            goto ERR_EXIT;
-        }
-#ifdef MTK_SECURITY_SW_SUPPORT
-        ret = fit_conf_verify_sig(NULL, get_fit_buf[i].load_buf);
-        if (ret < 0) {
-            ALWAYS_LOG("fit_conf_verify_sig failed: %s %d!\n", get_fit_buf[i].label, ret);
-            goto ERR_EXIT;
-        }
-        ret = ccci_fit_load_image(NULL, "kernel", get_fit_buf[i].load_buf, NULL, NULL, NULL, true);
-        if (ret < 0) {
-            ALWAYS_LOG("MD-fit image verify failed!\n");
-            goto ERR_EXIT;
-        }
-#else
-        ret = ccci_fit_load_image(NULL, "kernel", get_fit_buf[i].load_buf, NULL, NULL, NULL, false);
-        if (ret < 0) {
-            ALWAYS_LOG("MD-fit image verify failed!\n");
-            goto ERR_EXIT;
-        }
-#endif
-        i++;
-    }
-
-    return 0;
-
-ERR_EXIT:
-    return ret;
-}
-
 static int set_part_name_suffix(const char *part_name,
-    struct download_info_s *img_list, int img_num)
+    struct download_info_s *image_list, int img_num)
 {
     int name_len = 0;
-    int org_img_len = 0;
+	int org_img_len = 0;
     int i = 0;
     char *ptr = part_name_buf;
     char suffix[] = "_a";
@@ -511,158 +626,159 @@
 
     if(strcmp(suffix, "_a") == 0 || strcmp(suffix, "_b") == 0) {
         for(i = 0 ; i < img_num; i++) {
-            strcpy(ptr, img_list[i].partition_name);
-            strcpy(ptr + strlen(img_list[i].partition_name), suffix);
-            org_img_len = strlen(img_list[i].partition_name);
-            img_list[i].partition_name = ptr;
+            strcpy(ptr, image_list[i].partition_name);
+            strcpy(ptr + strlen(image_list[i].partition_name), suffix);
+			org_img_len = strlen(image_list[i].partition_name);
+            image_list[i].partition_name = ptr;
             ptr = ptr + org_img_len + 2;
-            *ptr = '\0';
-            ptr++;
+		    *ptr = '\0';
+			ptr++;
         }
     }
     else{
         ALWAYS_LOG("can't find a b update suffix string part name : %s\n", part_name);
-        return 0;
+		return 0;
     }
     for(i = 0 ; i < img_num; i++){
-        ALWAYS_LOG("MD load image: %s\n", img_list[i].partition_name);
+        ALWAYS_LOG("MD load image: %s\n", image_list[i].partition_name);
     }
-
     return 1;
 }
 
-static int decompress_img(void)
+/* --- Download list --------------------------------------- */
+/* --- This part is used for normal load ------------------- */
+static struct download_info_s md1_download_list_v50000[] = {/* for Gen97 FPGA */
+    /* img type | partition |image name | max size |img size |ext_flag  | mem addr | ass func p */
+    {main_img, "md1img", "md1rom", 0x10000000,   0,   0,     NULL,  ass_func_for_v6_normal_img},
+    {dsp_img,    "md1dsp",        "md1dsp",    0xA00000,    0,         0,   NULL,      NULL},
+    {drdi_img,   "md1img",   "md1drdi",   0x4000000,     0,   0,  NULL,      NULL},
+    {0,          NULL,       NULL,        0,           0,         0,     NULL,      NULL},
+};
+
+static struct download_info_s md1_download_list_v50001[] = {/* for 92 */
+    /* img type | partition | image name | max size  | img size | ext_flag         | mem addr */
+    {main_img, "md1img", "md1rom", 0x16000000, 0, DUMMY_AP_FLAG, NULL,
+        ass_func_for_97_md_only_img},
+    {dsp_img,    "md1dsp",    "md1dsp",    0xA00000,   0,   DUMMY_AP_FLAG,   NULL,  NULL},
+    {ramdisk_img, "USERDATA", "md1ramdisk", 0x2000000, 0,  DUMMY_AP_FLAG, NULL,   NULL},
+    {0,        NULL,        NULL,        0,           0,         0,     NULL,     NULL},
+};
+
+static char md1_version[65];
+static char md3_version[65];
+static int md1_version_rdy, md3_version_rdy;
+
+int load_modem_image(const char *part_name)
 {
+    struct modem_info_s info;
+    unsigned long long ld_img_ver;
+    long long plat_query_ret;
     int err_code = 0;
-    int ret = 0;
-    int smem_size = 0;
-    int size = 0;
-    int i = 0, j = 0;
-    int image_offset = 0;
-    void* image_temp_addr = NULL;
-
-    /* use md cache for temp buffer */
-    image_temp_addr = resv_named_memory("md_smem_cache", smem_size);
-    if (image_temp_addr == NULL) {
-        ALWAYS_LOG("allocate MD share memory fail\n");
-        err_code = -LD_ERR_PT_ALLOC_SMEM_FAIL;
-        goto exit;
-    }
-
-    while (i < img_num) {
-        // check part already decompress or not
-        for (j = 0; j < i; j++) {
-            if (strcmp(get_fit_buf[i].label, get_fit_buf[j].label) == 0) {
-                get_fit_buf[i].decompress_buf = get_fit_buf[j].decompress_buf;
-                break;
-            }
-        }
-
-        if (i != j) {
-            i++;
-            continue;
-        }
-
-        get_fit_buf[i].decompress_buf = image_offset + image_temp_addr;
-        if (get_fit_buf[i].decompress_buf == NULL) {
-            err_code = -LD_ERR_PT_MD1_LOAD_FAIL;
-            ALWAYS_LOG("decompress_buf mempool alloc failed \n", ret);
-            goto exit;
-        }
-
-        /* decompress image */
-        ret = ccci_fit_decompress_data(get_fit_buf[i].load_buf, get_fit_buf[i].decompress_buf, &size);
-        if (ret < 0 || size > 0x10000000) {
-            err_code = -LD_ERR_PT_MD1_LOAD_FAIL;
-            ALWAYS_LOG("md1 load fail:%d\n", ret);
-            goto exit;
-        }
-
-        // free load buff
-        if (get_fit_buf[i].load_buf != NULL)
-            mempool_free(get_fit_buf[i].load_buf);
-        get_fit_buf[i].load_buf = NULL;
-
-        image_offset += size;
-        i++;
-    }
-
-    /* check image size */
-    if (image_offset > 64 * 1024 * 1024) {
-        ALWAYS_LOG("need check temp buffer size, or change temp addr\n");
-        err_code = -LD_ERR_PT_MD1_LOAD_FAIL;
-        goto exit;
-    }
-
-exit:
-    return err_code;
-}
-
-static int md_main_thread(void)
-{
-    struct modem_info_s info = {0};
-    int err_code = 0;
-    int ret = 0;
+    int ret;
     unsigned char *smem_addr = NULL;
     int smem_size = 0;
     unsigned int md_load_status_flag = 0;
-    int i = 0;
-    char buf[65] = {0};
+    char buf[128];
+    struct download_info_s *image_list = NULL;
+    int img_num = 0;
+    int i = 0, j = 0;
 
-    ALWAYS_LOG("md_main_thread!\n");
+    //PROFILING_START("load_modem_image");
+    memset(md1_version, 0, sizeof(md1_version));
+    memset(md3_version, 0, sizeof(md3_version));
+    md1_version_rdy = 0;
+    md3_version_rdy = 0;
 
-    /* tag info init */
-    ret = ccci_lk_tag_info_init(0);
+    ccci_ld_md_wrapper_api_init();
+	ALWAYS_LOG("load_modem_image part_name: %s\n", part_name);
+
+    //check ld version
+    ld_img_ver = ccci_hal_get_ld_md_plat_setting("ld_version");
+    switch (ld_img_ver) {
+    case 0x50000:
+        image_list = md1_download_list_v50000;
+        img_num = sizeof(md1_download_list_v50000) / sizeof(struct download_info_s) - 1;
+        break;
+    case 0x50001:
+        image_list = md1_download_list_v50001;
+        img_num = sizeof(md1_download_list_v50001) / sizeof(struct download_info_s) - 1;
+        break;
+    default:
+        image_list = md1_download_list_v50000;
+        img_num = sizeof(md1_download_list_v50000) / sizeof(struct download_info_s) - 1;
+        break;
+    }
+
+    //check partition name by ab update
+    set_part_name_suffix(part_name, image_list, img_num);
+
+    /* --- 1. Get platform configure setting ---*/
+    if (ccci_hal_get_ld_md_plat_setting("support_detect") > 0) {
+        ALWAYS_LOG("Enter %s v2.0\n", __func__);
+    } else {
+        ALWAYS_LOG("Using %s v1.0\n", __func__);
+        err_code = -LD_ERR_PT_V2_PLAT_NOT_RDY;
+        goto _err_exit;
+    }
+    /* 2. tag info init */
+    ret = ccci_lk_tag_info_init((unsigned long long)((unsigned long)smem_addr));
     if (ret < 0) {
         ALWAYS_LOG("allocate tag memory fail\n");
         err_code = -LD_ERR_PT_ALLOC_CMD_BUF_FAIL;
-        goto exit;
+        goto _err_exit;
     }
+    /* 3. tel info init */
 
-    err_code = decompress_img();
-    if (err_code < 0) {
-            ALWAYS_LOG("decompress_img failed \n");
-        goto exit;
-    }
+    /* 4. security info init */
 
+    /* 5. Prepare done, begin to load MD one by one */
+    ALWAYS_LOG("-- MD1 --\n");
+    /* Load image */
     memset(&info, 0, sizeof(struct modem_info_s));
     info.md_id = MD_SYS1;
 
-    /* load modem image */
-    ret = ld_img_at_list(&info);
+    ret = ld_img_at_list(image_list, &info);
     if (ret < 0) {
         err_code = -LD_ERR_PT_MD1_LOAD_FAIL;
         update_md_err_to_lk_info(MD_SYS1, ret);
         ALWAYS_LOG("md1 load fail:%d\n", ret);
-        goto exit;
+        goto _load_md2;
     }
 
     /* Load success */
     update_md_load_flag_to_lk_info(MD_SYS1);
     add_hdr_info(s_g_md_ld_status, &info);
-    md_load_status_flag |= (1 << MD_SYS1);
+    md_load_status_flag |= (1<<MD_SYS1);
+_load_md2:
+    /* Do nothong currently */
+    goto _load_md3;
+_load_md3:
 
-    /* smem init: start */
-    smem_size = (int)ccci_hal_get_ld_md_plat_setting("share_memory_size");
-    if (smem_size <= 0) {
-        ALWAYS_LOG("Share memory size abnormal:%d\n", smem_size);
+_load_end:
+    if (s_g_md_ld_record_num == 0)
+        goto _err_exit;
+    /* 6. smem init: start */
+    plat_query_ret = ccci_hal_get_ld_md_plat_setting("share_memory_size");
+
+    if (plat_query_ret <= 0) {
+        ALWAYS_LOG("Share memory size abnormal:%d\n", (int)plat_query_ret);
         err_code = -LD_ERR_PT_SMEM_SIZE_ABNORMAL;
-        goto exit;
+        goto _err_exit;
     }
+    smem_size = (int)plat_query_ret;
 
     smem_addr = resv_named_memory("md_smem_ncache", smem_size);
     if (smem_addr == NULL) {
         ALWAYS_LOG("allocate MD share memory fail\n");
         err_code = -LD_ERR_PT_ALLOC_SMEM_FAIL;
-        goto exit;
+        goto _err_exit;
     }
 
     keep_md_ncache_memory((unsigned long long)smem_addr, smem_size);
     ccci_hal_apply_hw_remap_for_md_smem(smem_addr, smem_size);
     ccci_hal_amms_pos_notify_secure(smem_addr);
     /* smem init: end */
-
-    /* information settings. */
+    /* 7. information settings. */
     /* update hdr_count info */
     if (insert_ccci_tag_inf("hdr_count", (char *)&s_g_md_ld_record_num, sizeof(unsigned int)) < 0)
         ALWAYS_LOG("insert hdr_count fail\n");
@@ -680,12 +796,13 @@
         /* free all reserved share memory */
         ALWAYS_LOG("ccci_hal_apply_platform_setting ret %d\n", ret);
         err_code = -LD_ERR_PT_APPLY_PLAT_SETTING_FAIL;
-        goto exit;
+        update_common_err_to_lk_info(err_code);
+        goto _err_exit;
     } else if (ret == 0) {
         /* free all reserved share memory */
         ALWAYS_LOG("No MD Image enabled %d\n", ret);
         /* err_code = 0; */
-        goto exit;
+        goto _err_exit;
     } else if (ret < smem_size) {
         /* smem size returned from platform setting API, */
         /* resize share memory to final size */
@@ -696,109 +813,45 @@
     if (load_success_notify)
         load_success_notify(err_code);
 
-    ccci_lk_info_ctl_dump();
+    goto _OK_and_exit;
 
-    ret = ccci_get_md_version(MD_SYS1, buf, 65);
-    CRITICAL_LOG("[MD1 Baseband version] %s(%d)\r\n", buf, ret);
-exit:
-    for (i = 0; i < sizeof(get_fit_buf) / sizeof(struct fit_buf); i++) {
-        if (get_fit_buf[i].load_buf != NULL) {
-            mempool_free(get_fit_buf[i].load_buf);
-        }
-        get_fit_buf[i].load_buf = NULL;
-    }
-     update_common_err_to_lk_info(err_code);
-    ASSERT(err_code == 0);
-#if ENABLE_MODEM_LOAD_MULTI_THREAD
-    signal_md_cpu_end_event();
-#endif
-    return err_code;
-}
-
-/* --- Download list --------------------------------------- */
-/* --- This part is used for normal load ------------------- */
-static struct download_info_s md1_download_list_v50000[] = {/* for Gen97 FPGA */
-    /* img type | partition |image name | max size |img size |ext_flag  | mem addr | ass func p */
-    {main_img, "md1img", "md1rom", 0x10000000,   0,   0,     NULL,  ass_func_for_v6_normal_img},
-    {dsp_img,    "md1dsp",        "md1dsp",    0xA00000,    0,         0,   NULL,      NULL},
-    {drdi_img,   "md1img",   "md1drdi",   0x4000000,     0,   0,  NULL,      NULL},
-    {0,          NULL,       NULL,        0,           0,         0,     NULL,      NULL},
-};
- 
-static struct download_info_s md1_download_list_v50001[] = {/* for 92 */
-    /* img type | partition | image name | max size  | img size | ext_flag         | mem addr */
-    {main_img, "md1img", "md1rom", 0x16000000, 0, DUMMY_AP_FLAG, NULL,
-        ass_func_for_97_md_only_img},
-    {dsp_img,    "md1dsp",    "md1dsp",    0xA00000,   0,   DUMMY_AP_FLAG,   NULL,  NULL},
-    {ramdisk_img, "USERDATA", "md1ramdisk", 0x2000000, 0,  DUMMY_AP_FLAG, NULL,   NULL},
-    {0,        NULL,        NULL,        0,           0,         0,     NULL,     NULL},
-};
-
-static char md1_version[65] = {0};
-
-int load_modem_image(const char *part_name)
-{
-    unsigned long long ld_img_ver = {0};
-    int err_code = 0, ret = 0;
-
-    // PROFILING_START("load_modem_image");
-    ALWAYS_LOG("load_modem_image part_name: %s\n", part_name);
-
-    // check ld version
-    ld_img_ver = ccci_hal_get_ld_md_plat_setting("ld_version");
-    switch (ld_img_ver) {
-    case 0x50000:
-        image_list = md1_download_list_v50000;
-        img_num = sizeof(md1_download_list_v50000) / sizeof(struct download_info_s) - 1;
-        break;
-    case 0x50001:
-        image_list = md1_download_list_v50001;
-        img_num = sizeof(md1_download_list_v50001) / sizeof(struct download_info_s) - 1;
-        break;
-    default:
-        image_list = md1_download_list_v50000;
-        img_num = sizeof(md1_download_list_v50000) / sizeof(struct download_info_s) - 1;
-        break;
-    }
-
-    // check partition name by ab update
-    set_part_name_suffix(part_name, image_list, img_num);
-
-    /* Prepare done, load md image to dram */
-    ALWAYS_LOG("--Load MD1 --\n");
-
-    /* Load image to temp region */
-    ret = ld_list_img_from_storge(image_list);
-    if (ret < 0) {
-        err_code = -LD_ERR_PT_MD1_LOAD_FAIL;
-        ALWAYS_LOG("md1 load fail:%d\n", ret);
-        goto EXIT;
-    }
-
-    /* start md main thread */
-#if ENABLE_MODEM_LOAD_MULTI_THREAD
-    ALWAYS_LOG("create a thread for md cpu task\n");
-    thread_detach_and_resume(thread_create("md_cpu_task", &md_main_thread, NULL, DEFAULT_PRIORITY-1, DEFAULT_STACK_SIZE));
-#else
-    err_code = md_main_thread();
-#endif
-
-EXIT:
+_err_exit:
     update_common_err_to_lk_info(err_code);
-     return err_code;
- }
+
+_OK_and_exit:
+    ccci_ld_md_add_wrapper_api_info();
+    ccci_lk_info_ctl_dump();
+#ifdef mtk09077_temp_for_build
+   // ALWAYS_LOG("[PROFILE] ------- %s init cost %d ms ----\n", __func__,
+   //     (int)get_timer(time_lk_md_init));
+#else
+    //PROFILING_END();
+#endif
+    ret = ccci_get_md_version(MD_SYS1, buf, 128);
+    CRITICAL_LOG("[MD1 Baseband version] %s(%d)\r\n", buf, ret);
+    ret = ccci_get_md_version(MD_SYS3, buf, 128);
+    CRITICAL_LOG("[MD3 Baseband version] %s(%d)\r\n", buf, ret);
+    return 0;
+}
 
 void ccci_update_md_version(int md_id, unsigned char ver[])
 {
     if (md_id == MD_SYS1) {
+        md1_version_rdy = 1;
         snprintf(md1_version, 65, "%s", ver);
+    } else if (md_id == MD_SYS3) {
+        md3_version_rdy = 1;
+        snprintf(md3_version, 65, "%s", ver);
     }
 }
 
 int ccci_get_md_version(int md_id, char buf[], int size)
 {
-    if ((md_id == MD_SYS1))
+    if ((md_id == MD_SYS1) && md1_version_rdy)
         return snprintf(buf, size, "%s", md1_version);
+    else if ((md_id == MD_SYS3) && md3_version_rdy)
+        return snprintf(buf, size, "%s", md3_version);
+
     return -1;
 }
 
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_core.h b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_core.h
index 981c4d6..6603709 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_core.h
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_core.h
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2019 MediaTek Inc.
  *
@@ -403,6 +402,8 @@
 int ccci_resize_reserve_mem(unsigned char *addr, int old_size, int new_size);
 int ccci_free_not_used_reserved_memory(unsigned char *md_start_addr,
     int reserved, int required);
+void ccci_ld_md_wrapper_api_init(void);
+void ccci_ld_md_add_wrapper_api_info(void);
 
 /* --- sec api --- */
 void ccci_ld_md_sec_init(void);
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_hal.c b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_hal.c
index 5c60f4a..4de746d 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_hal.c
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_hal.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2019 MediaTek Inc.
  *
@@ -40,6 +39,12 @@
 {
     long long (*NULL_FP)(const char str[]) = 0;
 
+    if (strcmp(cfg_name, "support_detect") == 0) {
+        if (plat_ccci_get_ld_md_plat_setting == NULL_FP)
+            return 0LL;
+        return 1LL;
+    }
+
     if (plat_ccci_get_ld_md_plat_setting == NULL_FP)
         return 0LL;
 
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_tag_dt.c b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_tag_dt.c
index ca2c942..4010a40 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_tag_dt.c
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_ld_md_tag_dt.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2019 MediaTek Inc.
  *
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/ccci_lk_load_img_plat.c b/src/bsp/lk/platform/mt2735/drivers/md/ccci_lk_load_img_plat.c
index 0e3214f..9e9041b 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_lk_load_img_plat.c
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_lk_load_img_plat.c
@@ -1021,8 +1021,12 @@
 #endif
 
     /* Check loading validation */
-    if ((load_md_flag & (1 << MD_SYS1)) == 0) {
-        ALWAYS_LOG("md1 not enable\n");
+    if (((load_md_flag & (1<<MD_SYS1)) == 0) && (load_md_flag & (1<<MD_SYS3))) {
+        ALWAYS_LOG("md3 depends on md1,but md1 not loaded\n");
+        return -LD_ERR_PLAT_MD1_NOT_RDY;
+    }
+    if ((load_md_flag & ((1<<MD_SYS1)|(1<<MD_SYS3))) == 0) {
+        ALWAYS_LOG("both md1 and md3 not enable\n");
         return 0;
     }
     smem_final_size = cal_share_mem_layout(load_md_flag);
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/include/ccci_event.h b/src/bsp/lk/platform/mt2735/drivers/md/include/ccci_event.h
deleted file mode 100644
index a6b95c3..0000000
--- a/src/bsp/lk/platform/mt2735/drivers/md/include/ccci_event.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * 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
- */
-#pragma once
-
-void signal_md_cpu_end_event(void);
-void wait_for_md_cpu_task(void);
\ No newline at end of file
diff --git a/src/bsp/lk/platform/mt2735/drivers/md/rules.mk b/src/bsp/lk/platform/mt2735/drivers/md/rules.mk
index fcb905d..a80fd12 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/rules.mk
+++ b/src/bsp/lk/platform/mt2735/drivers/md/rules.mk
@@ -1,4 +1,3 @@
-# SPDX-License-Identifier: MIT
 LOCAL_DIR := $(GET_LOCAL_DIR)
 
 MODULE_SRCS += \
@@ -13,7 +12,6 @@
 	$(LOCAL_DIR)/load_md_wrapper.c \
 	$(LOCAL_DIR)/ccci_fit.c \
 	$(LOCAL_DIR)/cutils.c \
-	$(LOCAL_DIR)/ccci_event.c
 
 MODULE_DEPS += \
 	lib/fit \
diff --git a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand/nand_slc.c b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand/nand_slc.c
index b733af1..4e118a0 100644
--- a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand/nand_slc.c
+++ b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand/nand_slc.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -35,58 +34,53 @@
 static int nand_slc_cache_read_page(struct nand_chip *chip,
 				    struct nand_ops *ops, int count)
 {
-    struct nand_base *nand = chip->nand;
-    struct nand_device *dev = nand->dev;
-    int i, ret = 0;
-    int row = 0, col = 0, sectors;
-    u8 *data, *oob;
+	struct nand_base *nand = chip->nand;
+	struct nand_device *dev = nand->dev;
+	int i, ret = 0;
+	int row = 0, col = 0, sectors;
+	u8 *data, *oob;
 
-    for (i = 0; i < count; i++) {
-        row = ops[i].row;
-        col = ops[i].col;
+	for (i = 0; i <= count; i++) {
+		if (i < count) {
+			row = ops[i].row;
+			col = ops[i].col;
 
-        nand->addressing(nand, &row, &col);
+			nand->addressing(nand, &row, &col);
+		}
 
-        if (i == count - 1) {
-            ops[i].status = nand->read_cache(nand, true);
-        } else {
-            if (i == 0) {
-                ops[i].status = nand->read_page(nand, row);
-                if (ops[i].status < 0) {
-                    ret = ops[i].status;
-                    pr_err("%s %d failed i:%d count:%d ret:%d\n",
-                        __func__, __LINE__, i, count, ret);
-                    continue;
-                }
-            }
+		if (i == 0) {
+			ops[i].status = nand->read_page(nand, row);
+			continue;
+		}
 
-            ops[i].status = nand->read_cache(nand, false);
-        }
+		if (i == count - 1) {
+			ops[i].status = nand->read_last(nand);
+			continue;
+		}
 
-        if (ops[i].status < 0) {
-            ret = ops[i].status;
-            pr_err("%s %d read page failed i:%d ret:%d\n",
-                __func__, __LINE__, i, ret);
-            continue;
-        }
+		ops[i].status = nand->read_cache(nand, row);
+		if (ops[i - 1].status < 0) {
+			ret = ops[i - 1].status;
+			continue;
+		}
 
-        row = ops[i].row;
-        col = ops[i].col;
-        data = ops[i].data;
-        oob = ops[i].oob;
-        sectors = ops[i].len / chip->sector_size;
-        ops[i].status = nand->read_data(nand, row, col, sectors,
-            data, oob);
-        if (ops[i].status > 0) {
-            ops[i].status =
-            ops[i].status >=
-            dev->endurance->max_bitflips ? -ENANDFLIPS : 0;
-        }
+		row = ops[i - 1].row;
+		col = ops[i - 1].col;
+		data = ops[i - 1].data;
+		oob = ops[i - 1].oob;
+		sectors = ops[i - 1].len / chip->sector_size;
+		ops[i - 1].status = nand->read_data(nand, row, col, sectors,
+						    data, oob);
+		if (ops[i - 1].status > 0) {
+			ops[i - 1].status =
+				ops[i - 1].status >=
+				dev->endurance->max_bitflips ? -ENANDFLIPS : 0;
+		}
 
-        ret = i ? min_t(int, ret, ops[i - 1].status) : ops[i].status;
-    }
+		ret = min_t(int, ret, ops[i - 1].status);
+	}
 
-    return ret;
+	return ret;
 }
 
 static int nand_slc_read_multi(struct nand_base *nand, int row)
@@ -160,16 +154,16 @@
 				   struct nand_ops *ops,
 				   int count)
 {
-    struct nand_base *nand = chip->nand;
-    struct nand_slc *slc = base_to_slc(nand);
+	struct nand_base *nand = chip->nand;
+	struct nand_slc *slc = base_to_slc(nand);
 
-    if (slc->cache && (count >= (chip->block_pages >> 2)))
-        return slc->cache_read_page(chip, ops, count);
+	if (slc->cache)
+		return slc->cache_read_page(chip, ops, count);
 
-    if (slc->multi)
-        return slc->multi_read_page(chip, ops, count);
+	if (slc->multi)
+		return slc->multi_read_page(chip, ops, count);
 
-    return slc->read_page(chip, ops, count);
+	return slc->read_page(chip, ops, count);
 }
 
 static int nand_slc_cache_write_page(struct nand_chip *chip,
@@ -294,16 +288,16 @@
 static int nand_chip_slc_write_page(struct nand_chip *chip,
 				    struct nand_ops *ops, int count)
 {
-    struct nand_base *nand = chip->nand;
-    struct nand_slc *slc = base_to_slc(nand);
+	struct nand_base *nand = chip->nand;
+	struct nand_slc *slc = base_to_slc(nand);
 
-    if (slc->cache && (count >= (chip->block_pages >> 2)))
-        return slc->cache_write_page(chip, ops, count);
+	if (slc->cache)
+		return slc->cache_write_page(chip, ops, count);
 
-    if (slc->multi)
-        return slc->multi_write_page(chip, ops, count);
+	if (slc->multi)
+		return slc->multi_write_page(chip, ops, count);
 
-    return slc->write_page(chip, ops, count);
+	return slc->write_page(chip, ops, count);
 }
 
 static int nand_slc_erase_multi(struct nand_base *nand, int row)
@@ -536,8 +530,7 @@
 	nand = &slc->base;
 	memcpy(nand, slc->parent, sizeof(struct nand_base));
 
-    slc->multi = false;
-    slc->cache = true;
+	slc->cache = slc->multi = false;
 
 	slc->read_page = chip->read_page;
 	slc->write_page = chip->write_page;
diff --git a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand_base.c b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand_base.c
index a94948c..059c686 100644
--- a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand_base.c
+++ b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand_base.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -225,17 +224,28 @@
 			       dev->array_timing->tBERS);
 }
 
-static int nand_base_read_cache(struct nand_base *nand, bool last)
+static int nand_base_read_cache(struct nand_base *nand, int row)
 {
 	struct nfi *nfi = nand->nfi;
 	struct nand_device *dev = nand->dev;
-    short cmd;
-
-    cmd = (last == true) ?
-            dev->cmds->read_cache_last : dev->cmds->read_cache;
 
 	nfi->reset(nfi);
-    nfi->send_cmd(nfi, cmd);
+	nfi->send_cmd(nfi, dev->cmds->read_1st);
+	nfi->send_addr(nfi, 0, row, dev->col_cycle, dev->row_cycle);
+	nfi->send_cmd(nfi, dev->cmds->read_cache);
+	nfi->trigger(nfi);
+
+	return nfi->wait_ready(nfi, NAND_WAIT_BUSY,
+			       dev->array_timing->tRCBSY);
+}
+
+static int nand_base_read_last(struct nand_base *nand)
+{
+	struct nfi *nfi = nand->nfi;
+	struct nand_device *dev = nand->dev;
+
+	nfi->reset(nfi);
+	nfi->send_cmd(nfi, dev->cmds->read_cache_last);
 	nfi->trigger(nfi);
 
 	return nfi->wait_ready(nfi, NAND_WAIT_BUSY,
@@ -284,6 +294,7 @@
 	nand->read_page = nand_base_read_page;
 	nand->read_data = nand_base_read_data;
 	nand->read_cache = nand_base_read_cache;
+	nand->read_last = nand_base_read_last;
 	nand->write_enable = nand_base_write_enable;
 	nand->program_data = nand_base_program_data;
 	nand->program_page = nand_base_program_page;
diff --git a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand_base.h b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand_base.h
index c633624..a052f61 100644
--- a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand_base.h
+++ b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand_base.h
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -50,7 +49,8 @@
 	int (*read_page)(struct nand_base *nand, int row);
 	int (*read_data)(struct nand_base *nand, int row, int col, int sectors,
 			 u8 *data, u8 *oob);
-    int (*read_cache)(struct nand_base *nand, bool last);
+	int (*read_cache)(struct nand_base *nand, int row);
+	int (*read_last)(struct nand_base *nand);
 
 	int (*write_enable)(struct nand_base *nand);
 	int (*program_data)(struct nand_base *nand, int row, int col, u8 *data,
diff --git a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_base.c b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_base.c
index 37e8eb0..cf7f19d 100755
--- a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_base.c
+++ b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_base.c
@@ -120,7 +120,7 @@
 	u16 status, en;
 	int ret = 0;
 
-    nandx_irq_disable(nb->res.nfi_irq_id);
+	nandx_irq_disable(nb->res.nfi_irq_id);
 
 	status = readl(regs + NFI_INTR_STA);
 	en = readl(regs + NFI_INTR_EN);
@@ -140,8 +140,7 @@
 
 	nandx_irq_enable(nb->res.nfi_irq_id);
 
-    pr_debug("%s irq occur status:0x%x en:0x%x\n",
-        __func__, status, en);
+	pr_debug("%s irq occur status:0x%x en:0x%x\n", __func__, status, en);
 
 	/* Read clear irq status register */
 	status =  readl(regs + NFI_INTR_STA);
@@ -176,17 +175,14 @@
 	void *regs = nb->res.nfi_regs;
 	int ret, val;
 
-    /* Add IRQ Setting here, enable all slc/spi irq */
-    if (nb->nfi_irq_en) {
-        nandx_event_init(nb->done);
-        val  = readl(regs + NFI_INTR_EN);
-        val |= NFI_IRQ_INTR;
-        val |= nb->nfi_irq_all;
-        writel(val, regs + NFI_INTR_EN);
-        nb->nfi_irq_status = 0;
-        pr_debug("%s %d NFI_INTR_EN:0x%x\n",
-            __func__, __LINE__, readl(regs + NFI_INTR_EN));
-    }
+	/* Add IRQ Setting here, enable all slc/spi irq */
+	if (nb->nfi_irq_en) {
+		val  = readl(regs + NFI_INTR_EN);
+		val |= NFI_IRQ_INTR;
+		val |= nb->nfi_irq_all;
+		writel(val, regs + NFI_INTR_EN);
+		nb->nfi_irq_status = 0;
+	}
 
 	/* The NFI reset to reset all registers and force the NFI
 	 * master be early terminated
@@ -712,21 +708,28 @@
 	int ret = 0;
 	u32 val, i = 0;
 
-    val = readl(regs + NFI_INTR_EN);
-    writel(0xf1, regs + NFI_CNRNB);
-    nandx_event_init(nb->done);
+	val = readl(regs + NFI_INTR_EN);
+	writel(0xf1, regs + NFI_CNRNB);
+	nandx_event_init(nb->done);
 
-    /**
-     * check if nand already bean ready,
-     * avoid issue that casued by missing irq-event.
-     */
-    val = readl(regs + NFI_STA);
-    if (val & STA_BUSY2READY) {
-        readl(regs + NFI_INTR_STA);
-        writel(0, (void *)(regs + NFI_INTR_EN));
-        pr_debug("%s %d NFI_STA:%x\n", __func__, __LINE__, val);
-        return 0;
-    }
+	/**
+	 * check if nand already bean ready,
+	 * avoid issue that casued by missing irq-event.
+	 * AHB and Busy can not be valid at same time.
+	 */
+	while (i++ < timeout) {
+		if (nb->nfi_irq_status) {
+			pr_debug("%s IRQ done en:%x, status:%x time:%duS\n",
+				 __func__, val, nb->nfi_irq_status, i);
+			break;
+		}
+		udelay(10);
+	}
+
+	if (i > timeout) {
+		pr_err("IRQ timeout, irq_en: 0x%x\n", val);
+		ret = -EIO;
+	}
 
 	ret = nandx_event_wait_complete(nb->done, timeout);
 
@@ -1028,12 +1031,23 @@
 {
 	void *regs = nb->res.nfi_regs;
 	u32 len = nb->nfi.sector_size * sectors;
+	bool irq_en = nb->dma_en && nb->nfi_irq_en;
 	void *dma_addr;
 	u32 val;
 	int ret;
 
 	nb->rw_sectors = sectors;
 
+	/* IRQ setting, enable all slc/spi irq */
+	if (irq_en) {
+		nandx_event_init(nb->done);
+		val  = readl(regs + NFI_INTR_EN);
+		val |= NFI_IRQ_INTR;
+		val |= nb->nfi_irq_all;
+		writel(val, regs + NFI_INTR_EN);
+		nb->nfi_irq_status = 0;
+	}
+
 	val = readw(regs + NFI_CNFG);
 	if (read)
 		val |= CNFG_READ_EN;
@@ -1119,14 +1133,17 @@
 	int ret;
 	u32 val;
 
-    if (irq_en) {
-            ret = nandx_event_wait_complete(nb->done, NFI_TIMEOUT);
-            if (ret) {
-                pr_err("AHB IRQ error read:%d, sectors:%d\n",
-                    read, sectors);
-            writew(0, regs + NFI_INTR_EN);
-        }
-    }
+	if (irq_en) {
+		ret = wait_ready_irq(nb, NFI_TIMEOUT);
+		if (ret) {
+			pr_err("AHB IRQ error read:%d, sectors:%d\n",
+			       read, sectors);
+		}
+
+		ret = nandx_event_wait_complete(nb->done, NFI_TIMEOUT);
+		if (!ret)
+			writew(0, regs + NFI_INTR_EN);
+	}
 
 	if (read) {
 		ret = readl_poll_timeout_atomic(regs + NFI_BYTELEN, val,
@@ -1576,8 +1593,8 @@
 	nb->dma_en = true;
 	nb->dma_burst_en = true;
 
-    nb->nfi_irq_en = false;
-    nb->nfi_irq_all = INTR_AHB_DONE_EN | INTR_BUSY_RETURN_EN;
+	nb->nfi_irq_en = false;
+	nb->nfi_irq_all = NFI_IRQ_SLC;
 
 	nb->randomize_en = false;
 	nb->crc_en = false;
@@ -1654,24 +1671,24 @@
 	 */
 	nb->nfi.sector_size = 512;
 
-    /* give a default timing, and as discuss
-     * this is the only thing what we need do for nfi init
-     * if need do more, then we can add a function
-     */
-    writel(0x30C77FFF, nb->res.nfi_regs + NFI_ACCCON);
-    writel(0, nb->res.nfi_regs + NFI_INTR_EN);
+	/* give a default timing, and as discuss
+	 * this is the only thing what we need do for nfi init
+	 * if need do more, then we can add a function
+	 */
+	writel(0x30C77FFF, nb->res.nfi_regs + NFI_ACCCON);
 
-    nfi = nfi_extend_init(nb);
-    if (nfi) {
-        nandx_event_init(nb->done);
-        ret = nandx_irq_register(res->dev, res->nfi_irq_id,
-                nfi_irq_handler, "mtk_nfi", nfi);
-        if (ret) {
-            pr_err("nfi irq register failed!\n");
-            goto error;
-        }
-        return nfi;
-    }
+	nfi = nfi_extend_init(nb);
+	if (nfi) {
+		ret = nandx_irq_register(res->dev, res->nfi_irq_id,
+					 nfi_irq_handler,
+					 "mtk_nfi", nfi);
+		if (ret) {
+			pr_err("nfi irq register failed!\n");
+			goto error;
+		}
+
+		return nfi;
+	}
 
 error:
 	mem_free(nb);
diff --git a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_regs.h b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_regs.h
index c62a72e..16ae892 100644
--- a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_regs.h
+++ b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_regs.h
@@ -1,4 +1,3 @@
-/* SPDX-License-Identifier: MIT */
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -55,9 +54,6 @@
 #define NFI_INTR_EN             0x010
 #define NFI_INTR_STA            0x014
 #define         NFI_IRQ_INTR     BIT(31)
-#define         INTR_AHB_DONE_EN BIT(6)
-#define         INTR_BUSY_RETURN_EN BIT(4)
-
 #define         NFI_IRQ_SPI     GENMASK(11, 6)
 #define         NFI_IRQ_SLC     (GENMASK(13, 12) | GENMASK(6, 0))
 
diff --git a/src/bsp/lk/platform/mt2735/drivers/nandx/driver/lk/driver-nftl.c b/src/bsp/lk/platform/mt2735/drivers/nandx/driver/lk/driver-nftl.c
index ed09c75..668a9b1 100644
--- a/src/bsp/lk/platform/mt2735/drivers/nandx/driver/lk/driver-nftl.c
+++ b/src/bsp/lk/platform/mt2735/drivers/nandx/driver/lk/driver-nftl.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -89,7 +88,7 @@
 {
 	struct nandx_split64 split = {0};
 	func_nandx_operation operation;
-    int ret;
+	int ret, i, pages;
 	u8 *lbuf = (u8 *)buf;
 	u64 val;
 
@@ -102,10 +101,16 @@
 		lbuf += split.head_len;
 	}
 
-    if (split.body_len) {
-        operation(lbuf, NULL, split.body, split.body_len);
-        lbuf += split.body_len;
-    }
+	if (split.body_len) {
+		pages = div_down(split.body_len, nandxi.page_size);
+		for (i = 0; i < pages; i++) {
+			operation(lbuf + i * nandxi.page_size, NULL,
+				  split.body + i * nandxi.page_size,
+				  nandxi.page_size);
+		}
+
+		lbuf += split.body_len;
+	}
 
 	if (split.tail_len)
 		operation(lbuf, NULL, split.tail, split.tail_len);
@@ -250,12 +255,11 @@
 	arg = 0xf;
 	nandx_ioctl(NFI_CTRL_IOCON, &arg);
 
-    arg = 1;
-    nandx_ioctl(NFI_CTRL_NFI_IRQ, &arg);
-    nandx_ioctl(NFI_CTRL_DMA, &arg);
-    nandx_ioctl(NFI_CTRL_ECC, &arg);
-    nandx_ioctl(NFI_CTRL_BAD_MARK_SWAP, &arg);
-    nandx_ioctl(CORE_CTRL_NAND_INFO, &nandxi);
+	arg = 1;
+	nandx_ioctl(NFI_CTRL_DMA, &arg);
+	nandx_ioctl(NFI_CTRL_ECC, &arg);
+	nandx_ioctl(NFI_CTRL_BAD_MARK_SWAP, &arg);
+	nandx_ioctl(CORE_CTRL_NAND_INFO, &nandxi);
 
 #if NAND_UNIT_TEST
 	nand_unit_test();
diff --git a/src/bsp/lk/platform/mt2735/drivers/nandx/include/lk/nandx_os.h b/src/bsp/lk/platform/mt2735/drivers/nandx/include/lk/nandx_os.h
index 41cbbfb..d57e622 100644
--- a/src/bsp/lk/platform/mt2735/drivers/nandx/include/lk/nandx_os.h
+++ b/src/bsp/lk/platform/mt2735/drivers/nandx/include/lk/nandx_os.h
@@ -1,4 +1,3 @@
-/* SPDX-License-Identifier: MIT */
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -23,10 +22,6 @@
 #include <platform/mt_reg_base.h>
 #include <platform/pll.h>
 #include <lib/heap.h>
-#include <platform/interrupts.h>
-#include <platform/mt_irq.h>
-#include <kernel/event.h>
-
 
 #define NANDX_PERFORMANCE_TRACE 0
 #define NANDX_PAGE_PERFORMANCE_TRACE 0
@@ -108,9 +103,7 @@
 static inline int nandx_irq_register(void *dev, int irq,
 				     void *irq_handler, char *name, void *data)
 {
-    register_int_handler(irq, irq_handler, data);
-
-    return unmask_interrupt(irq);
+	return 0;
 }
 
 static inline int nandx_irq_unregister(int irq)
@@ -118,33 +111,21 @@
 	return 0;
 }
 
-/* No need to disable/enable, always enabled */
 static void nandx_irq_enable(int irq)
 {
-    /* unmask_interrupt(irq); */
+
 }
 
 static void nandx_irq_disable(int irq)
 {
-    /* mask_interrupt(irq); */
+
 }
 
-#define nandx_event_create() \
-    ({ \
-        event_t *__event = mem_alloc(1, sizeof(event_t)); \
-        event_init(__event, false, EVENT_FLAG_AUTOUNSIGNAL); \
-        (void *)__event; \
-    })
-
-#define nandx_event_destroy(event) \
-    ({ \
-        event_destroy(event); \
-        mem_free(event); \
-    })
-
-#define nandx_event_complete(event) event_signal(event, false)
-#define nandx_event_init(event) NULL
-#define nandx_event_wait_complete(event, timeout) event_wait_timeout(event, timeout)
+#define nandx_event_create()     NULL
+#define nandx_event_destroy(event)
+#define nandx_event_complete(event)
+#define nandx_event_init(event)
+#define nandx_event_wait_complete(event, timeout)        true
 
 static inline u64 get_current_time_us(void)
 {
diff --git a/src/bsp/lk/platform/mt2735/drivers/pll/pll.c b/src/bsp/lk/platform/mt2735/drivers/pll/pll.c
index af3cbbe..9653888 100755
--- a/src/bsp/lk/platform/mt2735/drivers/pll/pll.c
+++ b/src/bsp/lk/platform/mt2735/drivers/pll/pll.c
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -490,11 +489,7 @@
     DRV_WriteReg32(APLL2_CON0, 0x80000180);
 */
     //step 55: CPU SPEED*****
-#if MTK_CPU_MAX_IN_BL
-    DRV_WriteReg32(ARMPLL_LL_CON2, 0x811CD89D); // 1500 Mhz
-#else
     DRV_WriteReg32(ARMPLL_LL_CON2, 0x81133B13); // 1000 Mhz, need confirm with opp table
-#endif
     //DRV_WriteReg32(ARMPLL_LL_CON1, 0x81142762); // 1048Mhz
     //DRV_WriteReg32(ARMPLL_LL_CON2, 0x80133B13); // 2000Mhz
 /*
@@ -509,11 +504,8 @@
 */
     //step 60
     //DRV_WriteReg32(CCIPLL_CON2, 0x821EC4EC); // 800MHz, need confirm with opp table
-#if MTK_CPU_MAX_IN_BL
-    DRV_WriteReg32(CCIPLL_CON2, 0x81154EC4);
-#else
     DRV_WriteReg32(CCIPLL_CON2, 0x821AEC4E); // 700MHz, need confirm with opp table
-#endif
+
     /***********************
      * xPLL Frequency Enable
      ************************/
diff --git a/src/bsp/lk/platform/mt2735/drivers/rules.mk b/src/bsp/lk/platform/mt2735/drivers/rules.mk
index 760b0bb..46708a5 100644
--- a/src/bsp/lk/platform/mt2735/drivers/rules.mk
+++ b/src/bsp/lk/platform/mt2735/drivers/rules.mk
@@ -101,10 +101,6 @@
 ifeq ($(strip $(ENABLE_MODEM_LOAD)),1)
 MODULES += \
     $(LOCAL_DIR)/md
-
-GLOBAL_INCLUDES += \
-    $(LOCAL_DIR)/md/include
-
 endif
 
 ifeq ($(strip $(ENABLE_MEDMCU_LOAD)),1)
diff --git a/src/bsp/lk/platform/mt2735/rules.mk b/src/bsp/lk/platform/mt2735/rules.mk
index 40944be..a5f78f6 100644
--- a/src/bsp/lk/platform/mt2735/rules.mk
+++ b/src/bsp/lk/platform/mt2735/rules.mk
@@ -10,9 +10,6 @@
 WITH_KERNEL_VM ?= 1
 GICV3_SUPPORT_GIC600 ?= 1
 
-# enhance boot time
-MTK_CPU_MAX_IN_BL ?= 1
-
 LK_HEAP_IMPLEMENTATION ?= miniheap
 
 GLOBAL_INCLUDES += -I$(LK_TOP_DIR)/include \
diff --git a/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2735_hsm.txt b/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2735_hsm.txt
index b0184c8..e33edc6 100644
--- a/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2735_hsm.txt
+++ b/src/bsp/scatter/tools/nand-utils/nand_device_list_mt2735_hsm.txt
@@ -1,8 +1,8 @@
 Attention: use SPACE to input next parameter
 name vendor pagesize(B) sparesize(B) pageperblock blocks cycle config pll acccon strobe_sel latch_lat sam_dly
 MT29F8G08ABBCAH4  Micron 4096 224 64 4096 5 0x3 6 0x424094aa 0 0 0
-MT29F8G08ADBFA  Micron 4096 256 64 4096 5 0x3 6 0x10c06122 1 0 0
-JSFDDQ5QHAxGD  JSC 4096 256 64 4096 5 0x3 6 0x21406244 0 0 0
+MT29F8G08ADBFA  Micron 4096 256 64 4096 5 0x1 6 0 0 0 0
+JSFDDQ5QHAxGD  JSC 4096 256 64 4096 5 0x1 0 0 0 0 0
 MT29F4G08ABBFA  Micron 4096 256 64 2048 5 0x1 0 0 0 0 0
 MT29F4G01ABBFDWB  Micron 4096 256 64 2048 3 0x1 0 0 0 0 0
 NM4888KMPAXAI Nanya 2048 64 64 8192 3 0x1 0 0 0 0 0