Merge "[Bugfix][API-853][GNSS]init deinit Adds fault tolerance" into GSW3.0
diff --git a/meta-sdk/meta/meta-lynqSDK-T800/classes/md-fitimage.bbclass b/meta-sdk/meta/meta-lynqSDK-T800/classes/md-fitimage.bbclass
index 1a48a6e..782c417 100644
--- a/meta-sdk/meta/meta-lynqSDK-T800/classes/md-fitimage.bbclass
+++ b/meta-sdk/meta/meta-lynqSDK-T800/classes/md-fitimage.bbclass
@@ -69,7 +69,7 @@
                         type = "kernel";
                         arch = "arm";
                         os = "linux";
-                        compression = "none";
+                        compression = "${MODEM_COMPRESS}";
                         load = <${MD_LOADADDRESS}>;
                         entry = <${MD_ENTRYPOINT}>;
                         hash_1 {
@@ -119,7 +119,7 @@
                 fitimage_emit_section_maint imagestart
 
 
-                fitimage_emit_section_md ${WORKDIR}/modem-org.img
+                fitimage_emit_section_md ${WORKDIR}/modem.img
 
                 fitimage_emit_section_maint sectend
 
@@ -137,12 +137,11 @@
                 #
                 # Step 3: Assemble the image
                 #
-                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${MD_IMAGE}
-
+		uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${MD_DST_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_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_DST_IMAGE}
                 fi
 }
\ No newline at end of file
diff --git a/meta-sdk/meta/meta-lynqSDK-T800/classes/mddsp-fitimage.bbclass b/meta-sdk/meta/meta-lynqSDK-T800/classes/mddsp-fitimage.bbclass
index 593df1c..e32ada4 100644
--- a/meta-sdk/meta/meta-lynqSDK-T800/classes/mddsp-fitimage.bbclass
+++ b/meta-sdk/meta/meta-lynqSDK-T800/classes/mddsp-fitimage.bbclass
@@ -69,7 +69,7 @@
                         type = "kernel";
                         arch = "arm";
                         os = "linux";
-                        compression = "none";
+                        compression = "${DSP_COMPRESS}";
                         load = <${MDDSP_LOADADDRESS}>;
                         entry = <${MDDSP_ENTRYPOINT}>;
                         hash_1 {
@@ -118,7 +118,7 @@
                 fitimage_emit_section_maint imagestart
 
 
-                fitimage_emit_section_dsp ${WORKDIR}/dsp-org.bin
+                fitimage_emit_section_dsp ${WORKDIR}/dsp.bin
 
                 fitimage_emit_section_maint sectend
 
@@ -136,12 +136,12 @@
                 #
                 # Step 3: Assemble the image
                 #
-                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${MDDSP_IMAGE}
+                uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${DSP_DST_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}/${MDDSP_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}/${DSP_DST_IMAGE}
                 fi
 }
\ No newline at end of file
diff --git a/meta-sdk/meta/meta-lynqSDK-T800/conf/machine/auto2735evb-ivt-base.conf b/meta-sdk/meta/meta-lynqSDK-T800/conf/machine/auto2735evb-ivt-base.conf
index 4a131d4..2efcd7a 100755
--- a/meta-sdk/meta/meta-lynqSDK-T800/conf/machine/auto2735evb-ivt-base.conf
+++ b/meta-sdk/meta/meta-lynqSDK-T800/conf/machine/auto2735evb-ivt-base.conf
@@ -180,6 +180,8 @@
 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-sdk/meta/meta-lynqSDK-T800/recipes-modem/modem/modem_1.0.0.bb b/meta-sdk/meta/meta-lynqSDK-T800/recipes-modem/modem/modem_1.0.0.bb
index bcfec01..69a6031 100644
--- a/meta-sdk/meta/meta-lynqSDK-T800/recipes-modem/modem/modem_1.0.0.bb
+++ b/meta-sdk/meta/meta-lynqSDK-T800/recipes-modem/modem/modem_1.0.0.bb
@@ -3,39 +3,61 @@
 LIC_FILES_CHKSUM = "file://${MTK_LICENSE_DIR}/MediaTekProprietary;md5=c5d17c6905715d0948a3d6087602d12d"
 
 PACKAGE_ARCH = "${MACHINE_ARCH}"
-DEPENDS += "u-boot-mkimage-native bc-native dtc-native"
+DEPENDS += "u-boot-mkimage-native bc-native dtc-native flashtool"
 
 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_IMAGE = "md1img.img"
-MDDSP_IMAGE = "md1dsp.img"
+MD_SRC_IMAGE = "modem.img"
+MD_DST_IMAGE = "md1img.img"
+DSP_SRC_IMAGE = "dsp.bin"
+DSP_DST_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}/{} \;
 
-    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}
+    install ${MD_OUT}/${MD_DST_IMAGE} ${DEPLOYDIR}/${MD_DST_IMAGE}
+    install ${MD_OUT}/${DSP_DST_IMAGE} ${DEPLOYDIR}/${DSP_DST_IMAGE}
 }
 
-addtask deploy after do_configure
+addtask deploy after do_compile
diff --git a/meta/meta-mediatek-mt2735/classes/md-fitimage.bbclass b/meta/meta-mediatek-mt2735/classes/md-fitimage.bbclass
index 1a48a6e..782c417 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 = "none";
+                        compression = "${MODEM_COMPRESS}";
                         load = <${MD_LOADADDRESS}>;
                         entry = <${MD_ENTRYPOINT}>;
                         hash_1 {
@@ -119,7 +119,7 @@
                 fitimage_emit_section_maint imagestart
 
 
-                fitimage_emit_section_md ${WORKDIR}/modem-org.img
+                fitimage_emit_section_md ${WORKDIR}/modem.img
 
                 fitimage_emit_section_maint sectend
 
@@ -137,12 +137,11 @@
                 #
                 # Step 3: Assemble the image
                 #
-                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${MD_IMAGE}
-
+		uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${MD_DST_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_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_DST_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 593df1c..e32ada4 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 = "none";
+                        compression = "${DSP_COMPRESS}";
                         load = <${MDDSP_LOADADDRESS}>;
                         entry = <${MDDSP_ENTRYPOINT}>;
                         hash_1 {
@@ -118,7 +118,7 @@
                 fitimage_emit_section_maint imagestart
 
 
-                fitimage_emit_section_dsp ${WORKDIR}/dsp-org.bin
+                fitimage_emit_section_dsp ${WORKDIR}/dsp.bin
 
                 fitimage_emit_section_maint sectend
 
@@ -136,12 +136,12 @@
                 #
                 # Step 3: Assemble the image
                 #
-                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${MDDSP_IMAGE}
+                uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${DSP_DST_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}/${MDDSP_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}/${DSP_DST_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 4ea9a3d..8132c55 100755
--- a/meta/meta-mediatek-mt2735/conf/machine/auto2735evb-ivt-base.conf
+++ b/meta/meta-mediatek-mt2735/conf/machine/auto2735evb-ivt-base.conf
@@ -154,6 +154,8 @@
 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
new file mode 100644
index 0000000..45108b7
--- /dev/null
+++ b/meta/meta-mediatek-mt2735/recipes-core/initial/files/cpu_sched.service
@@ -0,0 +1,13 @@
+[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 100755
new mode 100644
index 23096c1..0e82cbd
--- 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,6 +11,7 @@
 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"
@@ -68,6 +69,7 @@
 SYSTEMD_PACKAGES = "${PN}"
 SYSTEMD_SERVICE_${PN} = "init_network.service \
                          init_mount.service \
+                         cpu_sched.service \
                          nvram_daemon.service \
                          ccci_fsd.service \
                          ccci_mdinit.service \
@@ -88,6 +90,7 @@
 #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 \
@@ -136,6 +139,7 @@
         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
new file mode 100644
index 0000000..b020174
--- /dev/null
+++ b/meta/meta-mediatek-mt2735/recipes-kernel/linux/files/boot_time.cfg
@@ -0,0 +1,2 @@
+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 826968f..28b0ce9 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=4
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=1
 # 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 2aa6a0a..0716be1 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,6 +28,7 @@
 
 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-lynq/lynq-at-test/lynq-at-test.bb b/meta/meta-mediatek-mt2735/recipes-lynq/lynq-at-test/lynq-at-test.bb
new file mode 100755
index 0000000..e660588
--- /dev/null
+++ b/meta/meta-mediatek-mt2735/recipes-lynq/lynq-at-test/lynq-at-test.bb
@@ -0,0 +1,27 @@
+DESCRIPTION = "at test"
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"
+
+inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/lynq/packages/apps/lynq-at-test/src"
+DEPENDS += "platform-libs mipc "
+
+LDFLAGS_append = " -lmipc_msg"
+
+
+FILES_${PN} = "/data/ ${bindir} "
+TARGET_CC_ARCH += "${LDFLAGS}"
+
+
+do_compile () {
+	if test "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" || test "${PACKAGE_ARCH}" = "cortexa7hf-neon-vfpv4"; then
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -mhard-float"
+	else
+		oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST}"
+	fi
+}
+
+do_install() {
+	install -d ${D}${bindir}/
+	install -m 0755 ${S}/lynq-at-test ${D}${bindir}/
+}
diff --git a/meta/meta-mediatek-mt2735/recipes-lynq/packagegroups/packagegroup-lync-mt2735.bb b/meta/meta-mediatek-mt2735/recipes-lynq/packagegroups/packagegroup-lync-mt2735.bb
index 06324be..6f4f5a1 100755
--- a/meta/meta-mediatek-mt2735/recipes-lynq/packagegroups/packagegroup-lync-mt2735.bb
+++ b/meta/meta-mediatek-mt2735/recipes-lynq/packagegroups/packagegroup-lync-mt2735.bb
@@ -33,6 +33,7 @@
     lynq-function-test \
     lynq-low-power \
     lynq-at-extension \
+    lynq-at-test \
     liblynq-logdata-handle \
     lynq-default \
     lynq-logrotate-service \
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 bcfec01..69a6031 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,39 +3,61 @@
 LIC_FILES_CHKSUM = "file://${MTK_LICENSE_DIR}/MediaTekProprietary;md5=c5d17c6905715d0948a3d6087602d12d"
 
 PACKAGE_ARCH = "${MACHINE_ARCH}"
-DEPENDS += "u-boot-mkimage-native bc-native dtc-native"
+DEPENDS += "u-boot-mkimage-native bc-native dtc-native flashtool"
 
 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_IMAGE = "md1img.img"
-MDDSP_IMAGE = "md1dsp.img"
+MD_SRC_IMAGE = "modem.img"
+MD_DST_IMAGE = "md1img.img"
+DSP_SRC_IMAGE = "dsp.bin"
+DSP_DST_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}/{} \;
 
-    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}
+    install ${MD_OUT}/${MD_DST_IMAGE} ${DEPLOYDIR}/${MD_DST_IMAGE}
+    install ${MD_OUT}/${DSP_DST_IMAGE} ${DEPLOYDIR}/${DSP_DST_IMAGE}
 }
 
-addtask deploy after do_configure
+addtask deploy after do_compile
diff --git a/src/bsp/lk/app/blxboot/blxboot.c b/src/bsp/lk/app/blxboot/blxboot.c
index 9a489f3..2b9352c 100644
--- a/src/bsp/lk/app/blxboot/blxboot.c
+++ b/src/bsp/lk/app/blxboot/blxboot.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2018 MediaTek Inc.
  *
@@ -24,6 +25,9 @@
 #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>
@@ -155,6 +159,7 @@
     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();
@@ -207,12 +212,15 @@
             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())
@@ -221,6 +229,10 @@
         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 e10aac7..cc86735 100644
--- a/src/bsp/lk/app/blxboot/imagelist.c
+++ b/src/bsp/lk/app/blxboot/imagelist.c
@@ -274,6 +274,14 @@
     },
 #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,
@@ -308,14 +316,6 @@
     },
 #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 4ddeb93..132f19e 100644
--- a/src/bsp/lk/lib/fit/fit.c
+++ b/src/bsp/lk/lib/fit/fit.c
@@ -105,7 +105,7 @@
  *    otherwise, on failure
  *
  */
-static int fit_get_img_subnode_offset(void *fit, const char *image_name)
+int fit_get_img_subnode_offset(void *fit, const char *image_name)
 {
     int noffset;
 
@@ -139,7 +139,7 @@
  *    otherwise, on failure
  *
  */
-static int fit_get_def_cfg_offset(void *fit, const char *conf)
+int fit_get_def_cfg_offset(void *fit, const char *conf)
 {
     int noffset, cfg_noffset, len;
 
@@ -528,7 +528,7 @@
     return 0;
 }
 
-static int fit_image_integrity_check_process(void *arg)
+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 258d75c..53419ea 100644
--- a/src/bsp/lk/platform/mt2735/bl2_bl33_options.mk
+++ b/src/bsp/lk/platform/mt2735/bl2_bl33_options.mk
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
 LOCAL_DIR := $(GET_LOCAL_DIR)
 
 ifeq ($(LK_AS_BL33),1)
@@ -29,6 +30,9 @@
 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
 
@@ -63,7 +67,8 @@
 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=$(ENABLE_MODEM_LOAD) \
+    ENABLE_MODEM_LOAD_MULTI_THREAD=$(ENABLE_MODEM_LOAD_MULTI_THREAD)
 
 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
new file mode 100644
index 0000000..4b3bb87
--- /dev/null
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_event.c
@@ -0,0 +1,30 @@
+// 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 719f143..db4b43a 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.c
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2016 MediaTek Inc.
  *
@@ -31,247 +32,60 @@
 #include <kernel/vm.h>
 #include <trace.h>
 
+#include "fit.h"
 #include "ccci_fit.h"
+
 #include "image.h"
 
-#define LOCAL_TRACE 0
+#define LOCAL_TRACE 1
 
-#define uswap_32(x) \
-    ((((x) & 0xff000000) >> 24) | \
-     (((x) & 0x00ff0000) >>  8) | \
-     (((x) & 0x0000ff00) <<  8) | \
-     (((x) & 0x000000ff) << 24))
+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);
 
-int ccci_fit_image_get_node(const void *fit, const char *image_uname)
+int ccci_fit_decompress_data(void *fit,
+                        void *decomp_addr, size_t *load_size)
 {
-    int noffset, images_noffset;
-
-    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;
-    }
-
-    noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
-    if (noffset < 0) {
-        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;
+    int len, ret;
     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;
+    int noffset = 0, cfg_noffset = 0;
+    const char *image_name;
+
+    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;
+    }
+
+    /* get this sub image node offset */
+    noffset = fit_get_img_subnode_offset(fit, image_name);
+    if (noffset < 0) {
+        dprintf(CRITICAL, "get sub image node (%s) failed\n", image_name);
+        return noffset;
+    }
 
     data = fdt_getprop(fit, noffset, "data", &len);
     if (!data) {
-        dprintf(CRITICAL, "%s can't get prop data\n", image_name);
+        dprintf(CRITICAL, "%s can't get prop data\n", __func__);
         return len;
     }
     size = len;
 
     compression = fdt_getprop(fit, noffset, "compression", &len);
     if (!compression) {
-        dprintf(CRITICAL, "%s compression is not specified\n", image_name);
+        dprintf(CRITICAL, "%s compression is not specified\n", __func__);
         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")) {
-        ret = unlz4(data, size - 4, (void *)(load_addr));
+        LTRACEF("[%s] start decompress\n", __func__);
+        ret = unlz4(data, size - 4, decomp_addr);
         if (ret != LZ4_OK) {
             dprintf(ALWAYS, "lz4 decompress failure\n");
             return -LZ4_FAIL;
@@ -280,117 +94,28 @@
          * kernel image size */
         size = *(u32 *)(data + size - 4);
     } else if (!strcmp((char *)compression, "none")) {
-        memmove((void *)(load_addr), data, size);
+        LTRACEF("[%s] copy image\n", __func__);
+        memmove(decomp_addr, data, size);
     } else {
-        dprintf(CRITICAL, "%s compression does not support\n", image_name);
+        dprintf(CRITICAL, "%s compression does not support\n", __func__);
         return -EINVAL;
     }
 
 #if WITH_KERNEL_VM
     /* always flush cache to PoC */
-    arch_clean_cache_range(load_addr, size);
+    arch_clean_cache_range(decomp_addr, size);
 #endif
 
-    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;
+    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);
 
     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)
@@ -401,7 +126,7 @@
     thread_t *integrity_verify_t;
 
     /* get defualt configuration offset (conf@1, conf@2,...or confg@n) */
-    cfg_noffset = ccci_fit_get_def_cfg_offset(fit, conf);
+    cfg_noffset = fit_get_def_cfg_offset(fit, conf);
     if (cfg_noffset < 0)
         return cfg_noffset;
 
@@ -413,7 +138,7 @@
     }
 
     /* get this sub image node offset */
-    noffset = ccci_fit_get_img_subnode_offset(fit, image_name);
+    noffset = fit_get_img_subnode_offset(fit, image_name);
     if (noffset < 0) {
         dprintf(CRITICAL, "get sub image node (%s) failed\n", image_name);
         return noffset;
@@ -421,39 +146,12 @@
 
     /* 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 bbdee29..03dfd33 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.h
+++ b/src/bsp/lk/platform/mt2735/drivers/md/ccci_fit.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2016 MediaTek Inc.
  *
@@ -25,86 +26,10 @@
 #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);
 
-/**
- * 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);
+int ccci_fit_decompress_data(void *fit,
+                   void *decomp_addr, size_t *load_size);
+
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 8c08720..c4a8ce0 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,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2020 MediaTek Inc.
  *
@@ -178,38 +179,3 @@
 
     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 57ff400..e18e3dd 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,8 +37,14 @@
 #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"
@@ -61,10 +67,14 @@
 {
     char *label;
     void *load_buf;
+    void *decompress_buf;
 };
 
 static struct fit_buf get_fit_buf[5] = {0};
-static char part_name_buf[1024] ={0};
+static struct download_info_s *image_list = NULL;
+static char part_name_buf[256] = {0};
+static int img_num = 0;
+
 
 static void add_hdr_info(struct modem_info_s tbl[], struct modem_info_s *hdr)
 {
@@ -146,44 +156,12 @@
     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 = find_offset_mdfit(fit);
-    ALWAYS_LOG("hdr_offset(0x%x)\n", hdr_offset);
+    int hdr_offset = 0;
+
     while (1) {
         load_size = (int)ccci_copy_raw_data(fit,
             (unsigned char *)p_hdr, hdr_offset, p_hdr_size);
@@ -207,28 +185,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 *fit, const char *name,
+static int copy_image_by_name(void *image, const char *name,
                 unsigned char *mem_addr, unsigned int max_size, unsigned int flags)
 {
     int i = 0;
@@ -246,7 +224,7 @@
         return -LD_ERR_PT_ALLOC_HDR_MEM_FAIL;
     }
 
-    hdr_offset = find_hdr_in_partition_mem(fit, name, p_hdr, sizeof(union mkimg_hdr));
+    hdr_offset = find_hdr_in_partition_mem(image, name, p_hdr, sizeof(union mkimg_hdr));
 
     if (hdr_offset < 0) {
         ALWAYS_LOG("load sub image %s fail\n", name);
@@ -268,7 +246,7 @@
     }
 
     /* load image raw data */
-    load_size = (int)ccci_copy_raw_data(fit, mem_addr,
+    load_size = (int)ccci_copy_raw_data(image, 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);
@@ -290,76 +268,9 @@
     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;
-	}
 
-	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,
+static int load_main_image(struct download_info_s *main_img, void* image,
     unsigned char **base_addr, int *resv_mem_size)
 {
     unsigned char *md_mem_base;
@@ -375,34 +286,9 @@
         load_size = ret;
         goto _Exit;
     }
-#ifdef MTK_SECURITY_SW_SUPPORT
-    get_fit_buf[0].label = main_img->partition_name;
 
-    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,
+    load_size = copy_image_by_name(image, 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,
@@ -460,38 +346,20 @@
     return 0;
 }
 
-/* --- 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)
+/* --- load md raw data to DRAM that listed at table --- */
+static int ld_img_at_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, j = 0;
-    struct download_info_s *curr;
+    int i = 0;
     struct download_info_s *md_main_img;
-    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;
+    md_main_img = image_list;
 
     /* alloc memory and load main image */
-    ret = load_main_image(md_main_img, &md_resv_mem_addr, &md_mem_resv_size);
+    ret = load_main_image(md_main_img, get_fit_buf[0].decompress_buf, &md_resv_mem_addr, &md_mem_resv_size);
     if (ret < 0)
         goto _MD_Exit;
     /* check header verify and sub image offset and size update */
@@ -499,14 +367,13 @@
     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 *)img_list);
+        ret = md_main_img->ass_func((void *)info, (void *)image_list);
         if (ret < 0) {
             ALWAYS_LOG("assistan func process fail:%d\n", ret);
             goto _MD_Exit;
@@ -515,74 +382,31 @@
     md_mem_required_size = info->resv_mem_size;
 
     /* load sub image one by one */
-    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;
-        }
+    i = 1;
+    while (image_list[i].img_type != 0) {
         /* By pass ext image that no need to load after query main image setting */
-        if ((curr[i].mem_addr == NULL) || (curr[i].img_size == 0)) {
+        if ((image_list[i].mem_addr == NULL) || (image_list[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;
-            }
-        }
 
-        //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)) {
+        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)) {
             ALWAYS_LOG("image size not sync to chk_hdr hdr:[0x%x]<>a:[0x%x]\n",
-                       curr[i].img_size, load_size);
+                       image_list[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",
-                       curr[i].image_name, ld_md_errno_to_str(load_size));
+                       image_list[i].image_name, ld_md_errno_to_str(load_size));
             ret = load_size;
             goto _MD_Exit;
         }
-        if (curr[i].img_type == dsp_img) {
-            curr[i].img_size = load_size;
-            ret = dsp_img_post_process(&curr[i], info->md_id);
+        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 (ret < 0)
                 goto _MD_Exit;
         }
@@ -610,11 +434,72 @@
     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 *image_list, int img_num)
+    struct download_info_s *img_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";
@@ -626,159 +511,158 @@
 
     if(strcmp(suffix, "_a") == 0 || strcmp(suffix, "_b") == 0) {
         for(i = 0 ; i < img_num; i++) {
-            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;
+            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;
             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", image_list[i].partition_name);
+        ALWAYS_LOG("MD load image: %s\n", img_list[i].partition_name);
     }
+
     return 1;
 }
 
-/* --- 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)
+static int decompress_img(void)
 {
-    struct modem_info_s info;
-    unsigned long long ld_img_ver;
-    long long plat_query_ret;
     int err_code = 0;
-    int ret;
+    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;
     unsigned char *smem_addr = NULL;
     int smem_size = 0;
     unsigned int md_load_status_flag = 0;
-    char buf[128];
-    struct download_info_s *image_list = NULL;
-    int img_num = 0;
-    int i = 0, j = 0;
+    int i = 0;
+    char buf[65] = {0};
 
-    //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;
+    ALWAYS_LOG("md_main_thread!\n");
 
-    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));
+    /* tag info init */
+    ret = ccci_lk_tag_info_init(0);
     if (ret < 0) {
         ALWAYS_LOG("allocate tag memory fail\n");
         err_code = -LD_ERR_PT_ALLOC_CMD_BUF_FAIL;
-        goto _err_exit;
+        goto exit;
     }
-    /* 3. tel info init */
 
-    /* 4. security info init */
+    err_code = decompress_img();
+    if (err_code < 0) {
+            ALWAYS_LOG("decompress_img failed \n");
+        goto exit;
+    }
 
-    /* 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;
 
-    ret = ld_img_at_list(image_list, &info);
+    /* load modem image */
+    ret = ld_img_at_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 _load_md2;
+        goto exit;
     }
 
     /* 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);
-_load_md2:
-    /* Do nothong currently */
-    goto _load_md3;
-_load_md3:
+    md_load_status_flag |= (1 << MD_SYS1);
 
-_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);
+    /* 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);
         err_code = -LD_ERR_PT_SMEM_SIZE_ABNORMAL;
-        goto _err_exit;
+        goto 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 _err_exit;
+        goto 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 */
-    /* 7. information settings. */
+
+    /* 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");
@@ -796,13 +680,12 @@
         /* 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;
-        update_common_err_to_lk_info(err_code);
-        goto _err_exit;
+        goto exit;
     } else if (ret == 0) {
         /* free all reserved share memory */
         ALWAYS_LOG("No MD Image enabled %d\n", ret);
         /* err_code = 0; */
-        goto _err_exit;
+        goto exit;
     } else if (ret < smem_size) {
         /* smem size returned from platform setting API, */
         /* resize share memory to final size */
@@ -813,45 +696,109 @@
     if (load_success_notify)
         load_success_notify(err_code);
 
-    goto _OK_and_exit;
-
-_err_exit:
-    update_common_err_to_lk_info(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);
+
+    ret = ccci_get_md_version(MD_SYS1, buf, 65);
     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;
+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:
+    update_common_err_to_lk_info(err_code);
+     return err_code;
+ }
+
 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) && md1_version_rdy)
+    if ((md_id == MD_SYS1))
         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 6603709..981c4d6 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,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2019 MediaTek Inc.
  *
@@ -402,8 +403,6 @@
 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 4de746d..5c60f4a 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,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (c) 2019 MediaTek Inc.
  *
@@ -39,12 +40,6 @@
 {
     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 4010a40..ca2c942 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,3 +1,4 @@
+// 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 9e9041b..0e3214f 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,12 +1021,8 @@
 #endif
 
     /* Check loading validation */
-    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");
+    if ((load_md_flag & (1 << MD_SYS1)) == 0) {
+        ALWAYS_LOG("md1 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
new file mode 100644
index 0000000..a6b95c3
--- /dev/null
+++ b/src/bsp/lk/platform/mt2735/drivers/md/include/ccci_event.h
@@ -0,0 +1,12 @@
+// 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 a80fd12..fcb905d 100644
--- a/src/bsp/lk/platform/mt2735/drivers/md/rules.mk
+++ b/src/bsp/lk/platform/mt2735/drivers/md/rules.mk
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
 LOCAL_DIR := $(GET_LOCAL_DIR)
 
 MODULE_SRCS += \
@@ -12,6 +13,7 @@
 	$(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 4e118a0..b733af1 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,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -34,53 +35,58 @@
 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++) {
-		if (i < count) {
-			row = ops[i].row;
-			col = ops[i].col;
+    for (i = 0; i < count; i++) {
+        row = ops[i].row;
+        col = ops[i].col;
 
-			nand->addressing(nand, &row, &col);
-		}
+        nand->addressing(nand, &row, &col);
 
-		if (i == 0) {
-			ops[i].status = nand->read_page(nand, row);
-			continue;
-		}
+        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 == count - 1) {
-			ops[i].status = nand->read_last(nand);
-			continue;
-		}
+            ops[i].status = nand->read_cache(nand, false);
+        }
 
-		ops[i].status = nand->read_cache(nand, row);
-		if (ops[i - 1].status < 0) {
-			ret = ops[i - 1].status;
-			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;
+        }
 
-		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;
-		}
+        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;
+        }
 
-		ret = min_t(int, ret, ops[i - 1].status);
-	}
+        ret = i ? min_t(int, ret, ops[i - 1].status) : ops[i].status;
+    }
 
-	return ret;
+    return ret;
 }
 
 static int nand_slc_read_multi(struct nand_base *nand, int row)
@@ -154,16 +160,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)
-		return slc->cache_read_page(chip, ops, count);
+    if (slc->cache && (count >= (chip->block_pages >> 2)))
+        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,
@@ -288,16 +294,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)
-		return slc->cache_write_page(chip, ops, count);
+    if (slc->cache && (count >= (chip->block_pages >> 2)))
+        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)
@@ -530,7 +536,8 @@
 	nand = &slc->base;
 	memcpy(nand, slc->parent, sizeof(struct nand_base));
 
-	slc->cache = slc->multi = false;
+    slc->multi = false;
+    slc->cache = true;
 
 	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 059c686..a94948c 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,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -224,28 +225,17 @@
 			       dev->array_timing->tBERS);
 }
 
-static int nand_base_read_cache(struct nand_base *nand, int row)
+static int nand_base_read_cache(struct nand_base *nand, bool last)
 {
 	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, 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->send_cmd(nfi, cmd);
 	nfi->trigger(nfi);
 
 	return nfi->wait_ready(nfi, NAND_WAIT_BUSY,
@@ -294,7 +284,6 @@
 	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 a052f61..c633624 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,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -49,8 +50,7 @@
 	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, int row);
-	int (*read_last)(struct nand_base *nand);
+    int (*read_cache)(struct nand_base *nand, bool last);
 
 	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 cf7f19d..37e8eb0 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,7 +140,8 @@
 
 	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);
@@ -175,14 +176,17 @@
 	void *regs = nb->res.nfi_regs;
 	int ret, val;
 
-	/* 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;
-	}
+    /* 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));
+    }
 
 	/* The NFI reset to reset all registers and force the NFI
 	 * master be early terminated
@@ -708,28 +712,21 @@
 	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.
-	 * 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;
-	}
+    /**
+     * 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;
+    }
 
 	ret = nandx_event_wait_complete(nb->done, timeout);
 
@@ -1031,23 +1028,12 @@
 {
 	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;
@@ -1133,17 +1119,14 @@
 	int ret;
 	u32 val;
 
-	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 (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 (read) {
 		ret = readl_poll_timeout_atomic(regs + NFI_BYTELEN, val,
@@ -1593,8 +1576,8 @@
 	nb->dma_en = true;
 	nb->dma_burst_en = true;
 
-	nb->nfi_irq_en = false;
-	nb->nfi_irq_all = NFI_IRQ_SLC;
+    nb->nfi_irq_en = false;
+    nb->nfi_irq_all = INTR_AHB_DONE_EN | INTR_BUSY_RETURN_EN;
 
 	nb->randomize_en = false;
 	nb->crc_en = false;
@@ -1671,24 +1654,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);
+    /* 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);
 
-	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;
-	}
+    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;
+    }
 
 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 16ae892..c62a72e 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,3 +1,4 @@
+/* SPDX-License-Identifier: MIT */
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -54,6 +55,9 @@
 #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 668a9b1..ed09c75 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,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -88,7 +89,7 @@
 {
 	struct nandx_split64 split = {0};
 	func_nandx_operation operation;
-	int ret, i, pages;
+    int ret;
 	u8 *lbuf = (u8 *)buf;
 	u64 val;
 
@@ -101,16 +102,10 @@
 		lbuf += split.head_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.body_len) {
+        operation(lbuf, NULL, split.body, split.body_len);
+        lbuf += split.body_len;
+    }
 
 	if (split.tail_len)
 		operation(lbuf, NULL, split.tail, split.tail_len);
@@ -255,11 +250,12 @@
 	arg = 0xf;
 	nandx_ioctl(NFI_CTRL_IOCON, &arg);
 
-	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);
+    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);
 
 #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 d57e622..41cbbfb 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,3 +1,4 @@
+/* SPDX-License-Identifier: MIT */
 /*
  * Copyright (C) 2017 MediaTek Inc.
  * Licensed under either
@@ -22,6 +23,10 @@
 #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
@@ -103,7 +108,9 @@
 static inline int nandx_irq_register(void *dev, int irq,
 				     void *irq_handler, char *name, void *data)
 {
-	return 0;
+    register_int_handler(irq, irq_handler, data);
+
+    return unmask_interrupt(irq);
 }
 
 static inline int nandx_irq_unregister(int irq)
@@ -111,21 +118,33 @@
 	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()     NULL
-#define nandx_event_destroy(event)
-#define nandx_event_complete(event)
-#define nandx_event_init(event)
-#define nandx_event_wait_complete(event, timeout)        true
+#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)
 
 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 9653888..af3cbbe 100755
--- a/src/bsp/lk/platform/mt2735/drivers/pll/pll.c
+++ b/src/bsp/lk/platform/mt2735/drivers/pll/pll.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 /* Copyright Statement:
  *
  * This software/firmware and related documentation ("MediaTek Software") are
@@ -489,7 +490,11 @@
     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
 /*
@@ -504,8 +509,11 @@
 */
     //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 46708a5..760b0bb 100644
--- a/src/bsp/lk/platform/mt2735/drivers/rules.mk
+++ b/src/bsp/lk/platform/mt2735/drivers/rules.mk
@@ -101,6 +101,10 @@
 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 a5f78f6..40944be 100644
--- a/src/bsp/lk/platform/mt2735/rules.mk
+++ b/src/bsp/lk/platform/mt2735/rules.mk
@@ -10,6 +10,9 @@
 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 e33edc6..b0184c8 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 0x1 6 0 0 0 0
-JSFDDQ5QHAxGD  JSC 4096 256 64 4096 5 0x1 0 0 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
 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
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 724193d..6dd83e1 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
@@ -1237,13 +1237,8 @@
 
 #if defined(CONFIG_HW_NAT)
 		/* fast path FP is QDMA. default uses mac1(eth0) */
-		/*Lxf modify for api-604 20220930 start*/
-		if (mac > 1) {
-			netdev = eth->netdev[1];
-			mac = (netdev && netif_running(netdev)) ?
-			       eth->mac[1]->id : eth->mac[0]->id;
-		}
-		/*Lxf modify for api-604 20220930 end*/
+		if (mac > 1)
+			mac = netif_running(eth->netdev[1]) ? 1 : 0;
 #endif
 		if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
 			     !eth->netdev[mac]))
diff --git a/src/kernel/modules/netsys_driver/nat/hw_nat/hnat_common.c b/src/kernel/modules/netsys_driver/nat/hw_nat/hnat_common.c
index c4e9b0e..09360ce 100755
--- a/src/kernel/modules/netsys_driver/nat/hw_nat/hnat_common.c
+++ b/src/kernel/modules/netsys_driver/nat/hw_nat/hnat_common.c
@@ -1026,13 +1026,10 @@
 	}
 
 	if (debug_level >= 10)
-/*Lxf modify for api-604 20220930 start*/
-		pr_notice("%s, send to ppe via %s tx\n", __func__, skb->dev->name);
-		
+		pr_notice("%s, send to ppe via ETH tx\n", __func__);
 
-	//dev_queue_xmit(skb);
-	skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev);
-/*Lxf modify for api-604 20220930 end*/
+	dev_queue_xmit(skb);
+
 	return 0;
 }
 
@@ -1303,10 +1300,8 @@
 
 	if (debug_level >= 7)
 		pr_notice("%s, bind to cpu done if name = %s\n",  __func__, skb->dev->name);
-/*Lxf modify for api-604 20220930 start*/
-	//dev_queue_xmit(skb);
-	skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev);
-/*Lxf modify for api-604 20220930 end*/
+
+	dev_queue_xmit(skb);
 
 	return 0;
 }
diff --git a/src/lynq/framework/lynq-sdk-ready/src/main.cpp b/src/lynq/framework/lynq-sdk-ready/src/main.cpp
index 0ff285c..9c8ee18 100755
--- a/src/lynq/framework/lynq-sdk-ready/src/main.cpp
+++ b/src/lynq/framework/lynq-sdk-ready/src/main.cpp
@@ -15,9 +15,6 @@
 
 int main(void){
     RLOGD("lynq-sdk-ready begin");
-    //xf.li add in 2023.01.04 for API-696 start
-    system("hwnat -O 5");
-    //xf.li add in 2023.01.04 for API-696 end
     start_timer_request();
     while (1)
     {
diff --git a/src/lynq/packages/apps/lynq-at-test/src/main.cpp b/src/lynq/packages/apps/lynq-at-test/src/main.cpp
new file mode 100755
index 0000000..367a6bb
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-at-test/src/main.cpp
@@ -0,0 +1,121 @@
+
+/*============================================================================= 
+#     FileName: lynq-at-test
+#     Desc: about SIMAPI
+#     Author: lei 
+#     Version: V1.0
+#     LastChange: 2023-03-09 
+#     History: 
+# 
+=============================================================================*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "mipc_msg.h"
+#include "mipc_msg_tlv_api.h"
+#include "mipc_msg_tlv_const.h"
+#include "mipc_msg_host.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char str[] = "AT;AT+CSQ;AT+ECSQ;AT+CREG;AT+CEREG;AT+C5GREG;AT+COPS;AT+CFUN;AT+ERAT";
+
+int check_buf(char *str,char *cmd)
+{
+    char *q = (char *)calloc(64,sizeof(char));
+    strcpy(q, str);
+    char *name;
+    char cmp[16] = {0};
+    while(q != NULL)
+    {
+        name = strsep(&q,";");
+        //printf("name %s\n", name);
+        strcpy(cmp, name);
+        //printf("cmp %s\n", cmp);
+        if(!strncmp(cmp, cmd, strlen(cmp)))
+        {
+            //printf("equal\n");
+            return 1;
+        }
+        // if(name != NULL)
+        // {
+        //     printf("%s\n", name);
+        //     if(!strncmp(name, cmd, strlen(name)))
+        //     {
+        //         return 1;
+        //     }
+        // }
+    }
+    free(q);
+    return 0;
+}
+
+void uper_char(char *cmd)
+{
+    char *p = cmd;
+    while (*p != '\0')
+    {
+        if((*p >= 'a') && (*p <= 'z'))
+        {
+            *p = *p-32;
+        }
+        *p++;
+    }
+}
+
+void sendcmd(char *cmd)
+{
+    mipc_msg_t *msg_req_ptr = mipc_msg_init(MIPC_SYS_AT_REQ, (mipc_msg_sim_ps_id_enum)MIPC_PS0);
+    mipc_msg_t *msg_cnf_ptr = NULL;
+    mipc_result_enum result;
+    char *atcmd_res_ptr = NULL;//, *atci_res = NULL;
+    uint16_t atcmd_res_len;
+    mipc_msg_add_tlv(msg_req_ptr, MIPC_SYS_AT_REQ_T_ATCMD, strlen(cmd), cmd);
+    msg_cnf_ptr = mipc_msg_sync_timeout(msg_req_ptr);
+    mipc_msg_deinit(msg_req_ptr);
+    result = mipc_get_result(msg_cnf_ptr);
+    if (result == MIPC_RESULT_SUCCESS) {
+        atcmd_res_ptr = (char *)mipc_msg_get_val_ptr(msg_cnf_ptr, MIPC_SYS_AT_CNF_T_ATCMD, &atcmd_res_len);
+        //int res_len = strlen(atcmd_res_ptr);
+        //printf( "res_len is:%d, atcmd_res_len is %d\n", res_len, atcmd_res_len);
+        //strncpy(response, atcmd_res_ptr, res_len);
+        //response[res_len] = '\0';
+        //atcmd_res_ptr[atcmd_res_len] = '\0';
+        printf( "%s\n", atcmd_res_ptr);
+    } else {
+        printf( "Failed to execute:%d\n", result);
+    }
+    mipc_msg_deinit(msg_cnf_ptr);
+}
+
+int main(void)
+{
+    SETCOM("/dev/ttyCMIPC2");
+    mipc_init("atci");
+    printf( "set mipc_inited true (UANT)\n");
+    char cmd[256] = {0};
+    while (1)
+    {
+        printf("please input at cmd:\n");
+        fgets(cmd, 256, stdin);
+        cmd[strlen(cmd)-1]='\0';
+        uper_char(cmd);
+        if(check_buf(str, cmd))
+        {
+            sendcmd(cmd);
+        }
+        else
+        {
+            printf("we just support AT+CSQ AT+ECSQ AT+CREG AT+CEREG AT+C5GREG AT+COPS AT+CFUN AT+ERAT\n");
+        }
+        
+    }
+}
+#ifdef __cplusplus
+}
+#endif 
diff --git a/src/lynq/packages/apps/lynq-at-test/src/makefile b/src/lynq/packages/apps/lynq-at-test/src/makefile
new file mode 100755
index 0000000..bf048d7
--- /dev/null
+++ b/src/lynq/packages/apps/lynq-at-test/src/makefile
@@ -0,0 +1,64 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -g -Os \
+                -flto \
+                -DRIL_SHLIB \
+                -D_LINUX \
+
+$(warning ################# TARGET_PLATFORM: $(TARGET_PLATFORM))
+ifeq ($(strip $(TARGET_PLATFORM)), mt2731)
+#$(warning #################add for debug $(ROOT), $(includedir))
+$(warning ################# TARGET_PLATFORM_MT2731)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2731 \
+                    -DMD_93_SUPPORT
+else ifeq ($(strip $(TARGET_PLATFORM)), mt2635)
+$(warning ################# TARGET_PLATFORM_MT2635)
+    LOCAL_CFLAGS += -DTARGET_PLATFORM_MT2635 \
+                    -DMD_90_SUPPORT
+endif
+
+
+LOCAL_PATH   = .
+
+$(warning ################# ZHOUQUNCHAO ROOT: $(ROOT),includedir:$(includedir),LOCAL_PATH:$(LOCAL_PATH))
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH) \
+  -I$(ROOT)$(includedir)/ \
+  -I$(ROOT)$(includedir)/mipc/api  \
+  -I$(ROOT)$(includedir)/mipc/common  \
+  -I$(ROOT)$(includedir)/mipc/msg  \
+  -I$(ROOT)$(includedir)/mipc/external  \
+  -DLIB_GNSS_HAL_DIR='"$(libdir)"'
+
+LOCAL_C_INCLUDES+=$(DNS_FLAGS)
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lstdc++ \
+    -llog \
+    -pthread \
+    -lmipc_msg \
+
+LOCAL_SRC_FILES_CPP = $(wildcard *.cpp gpio/*.cpp ril/*.cpp)
+LOCAL_SRC_FILES_C = $(wildcard *.c gps/*.c)
+EXECUTABLE = lynq-at-test
+
+OBJECTS=$(LOCAL_SRC_FILES_CPP:.cpp=.o) $(LOCAL_SRC_FILES_C:.c=.o)
+all: $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o: %.c
+	$(warning ----->build $<)
+	$(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+%.o : %.cpp
+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+.PHONY: clean
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)