summaryrefslogtreecommitdiff
path: root/drivers/mmc
AgeCommit message (Collapse)Author
2025-09-30Merge tag 'u-boot-socfpga-next-20250930' of ↵Tom Rini
https://source.denx.de/u-boot/custodians/u-boot-socfpga into next SoCFPGA updates for v2025.10: CI: https://source.denx.de/u-boot/custodians/u-boot-socfpga/-/pipelines/27762 This pull request brings a set of updates across SoCFPGA platforms covering Agilex5, Agilex7, N5X, and Stratix10. The changes include: * Agilex5 enhancements: - USB3.1 enablement and DWC3 host driver support - System Manager register configuration for USB3 - Watchdog timeout increase and SDMMC clock API integration - dcache handling improvements in SMC mailbox path - Enable SPL_SYS_DCACHE_OFF in defconfig * Clock driver improvements: - Introduce dt-bindings header for Agilex clocks - Add enable/disable API and EMAC clock selection fixes - Replace manual shifts with FIELD_GET usage * DDR updates: - IOSSM mailbox compatibility check - Correct DDR calibration status handling * Device tree changes: - Agilex5: disable cache allocation for reads - Stratix10: add NAND IP node - Enable driver model watchdog - Enable USB3.1 node for Agilex5 * Config cleanups: - Simplify Agilex7 VAB defconfig - Remove obsolete SYS_BOOTM_LEN from N5X VAB config - Enable CRC32 support for SoCFPGA - Increase USB hub debounce timeout Overall this set improves reliability of DDR and cache flows, adds missing USB and MMC features for Agilex5, and refines clock and configuration handling across platforms. This patch set has been tested on Agilex 5 devkit, and Agilex devkit.
2025-09-30mmc: socfpga_dw_mmc: Enable/disable SDMMC clock via APIAlif Zakuan Yuslaimi
Update the driver to enable or disable the SDMMC clock via clock driver model API instead of doing it in the driver itself. This allows for scalability of the driver for various SoCFPGA devices. Signed-off-by: Alif Zakuan Yuslaimi <[email protected]> Reviewed-by: Tien Fong Chee <[email protected]>
2025-09-25mmc: core: style fixes in mmc.cBhimeswararao Matsa
Fix a couple of style issues reported by checkpatch.pl: - Replace `#ifdef CONFIG_MMC_TRACE` with `#if IS_ENABLED(CONFIG_MMC_TRACE)` to follow the preferred kernel style for config-dependent branches. - Drop explicit zero initialization of a static variable. No functional change intended. Signed-off-by: Bhimeswararao Matsa <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-09-16Merge patch series "Fix ADI driver header dependencies"Tom Rini
Greg Malysa <[email protected]> says: Between 2025.07 and 2025.10 many header dependency chains were improved, but this exposed implicit header usage in several of our drivers. This wasn't discovered before or included in the original fixes because our drivers are not yet used by any mainline-supported boards, so build tests did not find them. This series addresses the two build failures I've encountered while rebasing our work onto 2025.10 and continuing to prepare the next submission of our board files. Link: https://lore.kernel.org/r/[email protected]
2025-09-16mmc: adi_sdhci: Update headersGreg Malysa
As part of the header dependency cleanup between 2025.07 and 2025.10, an implicit route to obtain SZ_128M from linux/sizes.h was removed. This adds an explicit reference to linux/sizes.h to fix build failures for this driver. Signed-off-by: Greg Malysa <[email protected]> Reviewed-by: Peng Fan <[email protected]>
2025-09-08Merge tag 'v2025.10-rc4' into nextTom Rini
Prepare v2025.10-rc4
2025-09-01mmc: core: drop space before newline in trace printfBhimeswararao Matsa
Remove unnecessary whitespace before '\n' in trace printf format strings (checkpatch warning QUOTED_WHITESPACE_BEFORE_NEWLINE). No functional change intended. Signed-off-by: Bhimeswararao Matsa <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-09-01mmc: iproc_sdhci: Cannot test unsigned variable for negativeAndrew Goodbody
In sdhci_iproc_execute_tuning the variable tuning_loop_counter is unsigned and therefore will always fail the test for it being less than 0. Fix this by changing the variable type to be s8. This issue was found by Smatch. Signed-off-by: Andrew Goodbody <[email protected]> Reviewed-by: Peng Fan <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-08-30mmc: rockchip_sdhci: Do not test unsigned for being less than 0Andrew Goodbody
In rockchip_sdhci_execute_tuning the variable tuning_loop_counter is tested for being less than 0. Ensure that it is a signed type by declaring it as s8 instead of char. This issue was found by Smatch. Signed-off-by: Andrew Goodbody <[email protected]> Reviewed-by: Peng Fan <[email protected]> Reviewed-by: Kever Yang <[email protected]>
2025-08-26Merge tag 'u-boot-stm32-20250825' of ↵Tom Rini
https://source.denx.de/u-boot/custodians/u-boot-stm CI: https://source.denx.de/u-boot/custodians/u-boot-stm/-/pipelines/27466 - Enable OF_UPSTREAM_BUILD_VENDOR for stm32mp25_defconfig - Fix to avoid inifite loop in stm32_sdmmc2 driver - Populate oobavail field of nand_ecclayout in stm32_fmc2_nand driver
2025-08-25mmc: stm32_sdmmc2: avoid infinite while loopChristophe Kerello
Avoid unlimited while loop by adding a timeout. The timeout is calculated based on a minimal throughput of 256 KB/s. The timeout is set at least to 2 seconds. Signed-off-by: Christophe Kerello <[email protected]> Reviewed-by: Patrice Chotard <[email protected]>
2025-08-13mmc: gen_atmel_mci: NULL check variable before useAndrew Goodbody
In mci_send_cmd the pointer 'data' is optional so guard its use with a NULL check to prevent any attempt to dereference it when not provided. This issue was found by Smatch. Signed-off-by: Andrew Goodbody <[email protected]> Reviewed-by: Peng Fan <[email protected]>
2025-08-13mmc: gen_atmel_mci: Remove duplicate checksAndrew Goodbody
Remove duplicate checks on status from mci_data_read and mci_data_write which are guaranteed to be true as exiting the above do..while loop above requires that to be so. This issue was found by Smatch. Signed-off-by: Andrew Goodbody <[email protected]> Reviewed-by: Peng Fan <[email protected]>
2025-07-27sunxi: mmc: add support for Allwinner A523 MMC mod clockAndre Przywara
The Allwinner A523 SoC has a slightly changed mod clock, where the P factor, formerly a shift value, is now a second divider value. Also the input clock is not PLL_PERIPH0 (600MHz) anymore, but PLL_PERIPH0_400M (for MMC0/1), so adjust the input rate calculation accordingly. MMC2 has a different set of parents, so the input clock is 800 MHz there. Adjust for all of this. Signed-off-by: Andre Przywara <[email protected]>
2025-07-24Fix emmc error state after mmc write timeoutIulian Banaga
This is a fix for the sporadic mmc write failure: mmc write failed 0 blocks written: ERROR After this happens the emmc will remain in an error state where subsequent read/writes fail with a timeout. The mmc driver sends CMD25 - WRITE_MULTIPLE_BLOCK which can sporadically timeout. When this happens, the mmc driver aborts the transfer and returns the above error messages. But the emmc still remains in data transfer mode, since the timeout was decided by uboot, not by the emmc. Fix this by sending the STOP_TRANSMISSION command (CMD12) and waiting for the emmc to be in ready state again (CMD13). Transferring data blocks after a CMD25 can take anywhere between 5 and +15s on Samsung EMMCs and the current timeout is not enough. Increase the timeout by 2x to accommodate the long transfer times observed. Signed-off-by: Iulian Banaga <[email protected]> Acked-by: Jimmy Durand Wesolowski <[email protected]> Reviewed-by: Peng Fan <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-07-24mmc: exynos_dw_mmc: add exynos5420 compatiblesJaehoon Chung
The exynos5420 DTSes in linux kernel uses the compatibles samsung,exynos5420-dw-mshc{,-smu} instead of just samsung,exynos-dwmmc. Match the additional compatibles in the driver to make it possible to use it with DTSes from Linux kernel. Signed-off-by: Jaehoon Chung <[email protected]> [ grimler: rebase after clksel reg abstraction and re-write commit message ] Signed-off-by: Henrik Grimler <[email protected]> Reviewed-by: Sam Protsenko <[email protected]> Reviewed-by: Anand Moon <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-07-24mmc: s5p_sdhci: add samsung,exynos4210-sdhci compatibleHenrik Grimler
the Exynos4210 devices in u-boot uses samsung,exynos4412-sdhci as sdhci compatible in their DTSes, while the upstream DTSes uses samsung,exynos4210-sdhci. Add samsung,exynos4210-sdhci compatible string for s5p_sdhci driver as well so that it can be used with upstream DTSes. Signed-off-by: Henrik Grimler <[email protected]> Reviewed-by: Anand Moon <[email protected]> Reviewed-by: Sam Protsenko <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-07-24mmc: s5p_sdhci: remove duplicated card detect codeHenrik Grimler
The common sdhci infrastructure is already parsing the cd-gpios property, since commit 451931ea7002 ("mmc: sdhci: Read cd-gpio from devicetree"). The s5p code is therefore duplicated, and also broken since it assumes that the GPIO value is inverted, while the sdhci code correctly follows the ACTIVE_LOW/ACTIVE_HIGH flag specified in the device tree. This fix was originally authored by Simon Shields: https://github.com/fourkbomb/u-boot/commit/2eac9dea7903 The change has been tested on exynos4210-i9100, a device similar to exynos4210-trats. Signed-off-by: Henrik Grimler <[email protected]> Reviewed-by: Anand Moon <[email protected]> Reviewed-by: Sam Protsenko <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-07-17Merge tag 'u-boot-imx-master-20250717' of ↵Tom Rini
https://gitlab.denx.de/u-boot/custodians/u-boot-imx CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/27088 - Add support for the i.MX95 B0 version. - Enable standard boot for phycore-imx8mp. - Kconfig fixes for i.MX MMC and FSL_SEC_MON. - Support 4Gb single die variant of the i.MX8MM Venice board.
2025-07-17mmc: Remove unused kona_sdhci driverTom Rini
As no platforms use this driver anymore, remove it. Signed-off-by: Tom Rini <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-07-17mmc: Tighten some mmc driver dependenciesTom Rini
A large number of mmc drivers cannot build without access to some platform specific header files. Express those requirements in Kconfig as well. Signed-off-by: Tom Rini <[email protected]> Acked-by: Peng Fan <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-07-17mmc: Take cleanup path to free memory on error exitAndrew Goodbody
Instead of returning -EINVAL directly which will not call the cleanup path to free memory, fix the code to set the error and then goto the cleanup code. This issue found by Smatch. Signed-off-by: Andrew Goodbody <[email protected]> Reviewed-by: Peng Fan <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-07-17arm: imx: Remove unused mxcmmc driverTom Rini
As no platforms use this driver anymore, remove it. Signed-off-by: Tom Rini <[email protected]>
2025-07-08mmc: zynq_sdhci: Reset the host controllerVenkatesh Yadav Abbarapu
Reset the host controller at the early stage of probe so that the configuration will be done properly for reboot cases. Signed-off-by: Venkatesh Yadav Abbarapu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michal Simek <[email protected]>
2025-07-02mmc: socfpga_dw_mmc: Retrieve clock manager address via DTAlif Zakuan Yuslaimi
Update the MMC driver to retrieve the clock manager base address via probing the clock manager node in the device tree. Signed-off-by: Alif Zakuan Yuslaimi <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-07-02Revert "drivers: mmc: rpmb: Use R1 response"Jan Kiszka
This reverts commit ae93d8106bdb5926efef9222d553adb295ebce96. It is no longer needed since 24b1e0c7e2e3. Since the obsolete include pulled in byteorder.h which is needed by now, include this one directly. Signed-off-by: Jan Kiszka <[email protected]> Reviewed-by: Peng Fan <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-06-20Merge patch series "Consistent Kconfig environment options CONFIG_ENV_ prefix"Tom Rini
Marek Vasut <[email protected]> says: Rename the environment related variables and add ENV_ prefix, so that all configuration options which are related to environment would have an CONFIG_ENV_ prefix. No functional change. Link: https://lore.kernel.org/r/[email protected]
2025-06-20env: Rename SYS_MMC_ENV_DEV to ENV_MMC_DEVICE_INDEXMarek Vasut
Rename the variable and add ENV_ prefix, so that all configuration options which are related to environment would have an CONFIG_ENV_ prefix. No functional change. Use ENV_MMC_DEVICE_INDEX to clarify this is the SD/MMC device index, a number, as enumerated by U-Boot. Update the help text accordingly. Signed-off-by: Marek Vasut <[email protected]>
2025-06-16Merge tag 'u-boot-dfu-next-20250616' of ↵Tom Rini
https://source.denx.de/u-boot/custodians/u-boot-dfu into next u-boot-dfu-next-20250616 CI: https://source.denx.de/u-boot/custodians/u-boot-dfu/-/pipelines/26704 Usb gadget: - Fix ti_musb driver in gadget mode (with DM_USB_GADGET) DFU: - mmc/scsi backends when using 10 or more partitions
2025-06-14Merge patch series "Hex value prefix case cleanup"Tom Rini
E Shattow <[email protected]> says: Make consistent use of lowercase hexadecimal prefix '0x' throughout U-Boot. There are a few remaining uses of uppercase 'X' to denote hexadecimal prefix or placeholder in documentation and error messages. External devicetree-rebasing dts/upstream and the generated code of xilinx/zynq are ignored for the series. Link: https://lore.kernel.org/r/[email protected]
2025-06-14drivers: use lowercase hex prefix styleE Shattow
Use consistent lowercase hex prefix style in drivers/* Does not change hex prefix case in allcaps uppercase style error messages Signed-off-by: E Shattow <[email protected]>
2025-06-11mmc: Kconfig: Really correct dependencies SDHCI ADMA optionsTom Rini
When doing the investigation for commit 53bb8fdea12a ("mmc: Kconfig: Correct dependencies SDHCI ADMA options") I missed the implications of MMC_SDHCI_ADMA_HELPERS. The problem is that FSL_ESDHC via the FSL_ESDHC_SUPPORT_ADMA2 option will also enable these helper functions. This in turn means the correct dependency here is MMC_SDHCI_ADMA_HELPERS and not *MMC_SDHCI_ADMA. Reported-by: Heiko Thiery <[email protected]> Signed-off-by: Tom Rini <[email protected]>
2025-06-09Merge tag 'v2025.07-rc4' into nextTom Rini
Prepare v2025.07-rc4
2025-06-04mmc: am654_sdhci: Clear UHS_MODE_SELECT when <= MMC_HS_52Judith Mendez
This clears UHS_MODE_SELECT for timing modes <= MMC_HS_52. When initializing to HS400 mode, the host controller downgrades to non-uhs modes so clear UHS_MODE_SELECT at modes <= MMC_HS_52. This fixes eMMC writes on j7200 EVM. Fixes: 6067aa66b3bb ("mmc: am654_sdhci: Add am654_sdhci_set_control_reg") Signed-off-by: Judith Mendez <[email protected]> Reviewed-by: Peng Fan <[email protected]>
2025-06-02Merge patch series "Audit include list for include/[a-m]*.h"Tom Rini
Tom Rini <[email protected]> says: Hey all, Related to my other series I've posted recently on cleaning up some headers, this series here is the result of at least lightly auditing the #includes used in include/[a-m]*.h. This ignores subdirectories, as at least in part I think the top-level includes we've constructed are the most likely places to have some extra transitive include paths. I'm sure there's exceptions and I'll likely audit deeper once this first pass is done. This only gets as far as "include/m*.h" because I didn't want this to get too big. This also sets aside <miiphy.h> and <phy.h>. While miiphy.h does not directly need <phy.h> there are *so* many users and I think I had half of the tree just about not building when I first tried. It might be worth further investigation, but it might just be OK as-is. Link: https://lore.kernel.org/r/[email protected]
2025-06-02include/mmc.h: Audit include listTom Rini
This file does not need <linux/sizes.h> nor <linux/compiler.h> so remove them. This exposes however that a number of other files had been relying on this implicit include for <linux/sizes.h> so add that where needed. Signed-off-by: Tom Rini <[email protected]>
2025-05-20mmc: cv1800b: Fix build without MMC_SUPPORTS_TUNINGAlexander Sverdlin
That's how it looks like without CONFIG_MMC_SUPPORTS_TUNING before the patch: aarch64-buildroot-linux-gnu-ld.bfd: drivers/mmc/cv1800b_sdhci.o: in function `cv1800b_execute_tuning': drivers/mmc/cv1800b_sdhci.c:47:(.text.cv1800b_execute_tuning+0x50): undefined reference to `mmc_send_tuning' Signed-off-by: Alexander Sverdlin <[email protected]> Reviewed-by: Peng Fan <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-04-28sunxi: mmc: remove usage of struct sunxi_ccm_regAndre Przywara
The Allwinner MMC code uses a complex C struct, modelling the clock device's register frame. We rely on sharing the member names across all Allwinner SoCs, which is fragile. Drop the usage of the struct in the MMC code, by using #define'd register names and their offset, and then adding those names to the base pointer. This requires to define those offsets for all SoCs, but since we only use between four and six clock registers in the MMC code, this is easily done. This removes one common user of the clock register struct. Signed-off-by: Andre Przywara <[email protected]>
2025-04-24Merge patch series "More MMC fixes"Tom Rini
Judith Mendez <[email protected]> says: This patch series fixes MMC_HS_52 mode in am654_sdhci driver, as well as HIGH_SPEED_ENA and UHS_MODE_SELECT for HS modes. Also add TI_COMMON_CMD_OPTIONS to K3 Sitara board a53 defconfigs. Link: https://www.ti.com/lit/er/sprz574a/sprz574a.pdf Link: https://lore.kernel.org/r/[email protected]
2025-04-24mmc: am654_sdhci: Add am654_sdhci_set_control_regJudith Mendez
This patch adds am654_sdhci_set_control_reg to am654_sdhci. This is required to fix UHS_MODE_SELECT for TI K3 boards. If any of HIGH_SPEED_ENA, V1P8_SIGNAL_ENA, UHS_MODE_SELECT are set, then data will be launched on the pos-edge of the clock. Since K3 SoCs did not meet timing requirements for High Speed SDR mode at rising clock edge, none of these three should be set, therefore limit UHS_MODE_SELECT to only be set for modes above MMC_HS_52. This fixes MMC write issue on am64x evm at mode High Speed SDR. Signed-off-by: Judith Mendez <[email protected]> Reviewed-by: Bryan Brattlof <[email protected]>
2025-04-24mmc: am654_sdhci: Fix HIGH_SPEED_ENAJudith Mendez
High Speed enable bit switches data launch from the falling clock edge (half cycle timing) to the rising clock edge (full cycle timing). For all SD UHS modes, data launch must happen at the rising clock edge, so set HIGH_SPEED_ENA for SDR12 and SDR25 modes. For all HS modes, data launch must happen at the falling clock edge, so do not set HIGH_SPEED_ENA for MMC_HS_52. Signed-off-by: Judith Mendez <[email protected]> Reviewed-by: Bryan Brattlof <[email protected]>
2025-04-24mmc: am654_sdhci: Add MMC_HS_52 to timing dataJudith Mendez
This patch adds MMC_HS_52 to the timing data structure. Previously, this bus mode tap settings were not populated and were instead populated for MMC_HS which is a different bus mode up to 26MHz. Since we intended these settings according to the device data sheet[0] for MMC_HS_52 up to 52MHz, populate MMC_HS tap settings for MMC_HS_52. While we are here, fix typo in ti,itap-del-sel-mms-hs. [0] https://www.ti.com/lit/ds/symlink/am625.pdf Table 7-79 Signed-off-by: Judith Mendez <[email protected]> Reviewed-by: Bryan Brattlof <[email protected]>
2025-04-23Merge tag 'u-boot-rockchip-20250423' of ↵Tom Rini
https://source.denx.de/u-boot/custodians/u-boot-rockchip CI: https://source.denx.de/u-boot/custodians/u-boot-rockchip/-/pipelines/25909 Please pull the updates for rockchip platform: - New SoC support: RK3528, RK3576 - New Board support: rk3528 Radxa E20C, rk3576 Firefly ROC-RK3576-PC; - Add generic board for rk3288 and rk3399; - rng driver binding update; - misc updates on board level or header files;
2025-04-23mmc: rockchip_dw_mmc: Add support for rk3576Heiko Stuebner
The rk3576 uses a different base-compatible, as starting with this generation, the clock phase tuning is done via registers inside the mmc controller and not from inside the CRU. In U-Boot we do not tune at all, so no other code changes are necessary. Signed-off-by: Heiko Stuebner <[email protected]> Reviewed-by: Jaehoon Chung <[email protected]> Reviewed-by: Jonas Karlman <[email protected]> Reviewed-by: Kever Yang <[email protected]>
2025-04-23mmc: rockchip_sdhci: Add support for RK3576Heiko Stuebner
Add support for RK3576 to the rockchip sdhci driver. It's pretty similar to its cousins found in the RK3568 and RK3588 and the specific hs400-tx-tap number was taken from the vendor-u-boot. Signed-off-by: Heiko Stuebner <[email protected]> Reviewed-by: Jaehoon Chung <[email protected]> Reviewed-by: Jonas Karlman <[email protected]> Reviewed-by: Kever Yang <[email protected]>
2025-04-23mmc: rockchip_sdhci: Gate clock for glitch free phase switchingJonas Karlman
Enable clock stopping to gate clock during phase code change to ensure glitch free phase switching in auto-tuning circuit. Fixes HS200 mode on RK3528. POST_CHANGE_DLY Time taken for phase switching and stable clock output. - Less than 4-cycle latency PRE_CHANGE_DLY Maximum Latency specification between transmit clock and receive clock. - Less than 4-cycle latency TUNE_CLK_STOP_EN Clock stopping control for Tuning and auto-tuning circuit. When enabled, clock gate control output is pulled low before changing phase select codes. This effectively stops the receive clock. Changing phase code when clocks are stopped ensures glitch free phase switching. - Clocks stopped during phase code change Signed-off-by: Jonas Karlman <[email protected]> Reviewed-by: Kever Yang <[email protected]>
2025-04-23mmc: rockchip_sdhci: Add initial support for RK3528Jonas Karlman
Add initial support for SDHCI controller in RK3528. Only MMC Legacy and MMC High Speed (52MHz) mode is supported after this, more work is needed to get the faster HS200/HS400/HS400ES modes working. Variant tap and delay num is copied from vendor Linux tag linux-6.1-stan-rkr5. Signed-off-by: Jonas Karlman <[email protected]> Reviewed-by: Kever Yang <[email protected]>
2025-04-23mmc: rockchip_sdhci: Extend variant configurationJonas Karlman
RK3528 and RK3576 use different tap and delay num for cmdout and strbin. Move tap and delay num for cmdout and strbin to driver data to prepare for adding new SoCs. Signed-off-by: Jonas Karlman <[email protected]> Reviewed-by: Kever Yang <[email protected]>
2025-04-23mmc: omap_hsmmc: implement send_init_stream callbackMathieu Othacehe
This callback is used to send the 74 clock cycles after power up. Signed-off-by: Mathieu Othacehe <[email protected]> Reviewed-by: Peng Fan <[email protected]> Signed-off-by: Peng Fan <[email protected]>
2025-04-23mmc: Add a new callback function to perform the 74 clocks cycle sequenceJean-Jacques Hiblot
Add a new callback function *send_init_stream* which start a sequence of at least 74 clock cycles. The mmc core uses *mmc_send_init_stream* in order to invoke the callback function. This will be used during power cycle where the specification requires such a sequence after power up. Signed-off-by: Jean-Jacques Hiblot <[email protected]> Reviewed-by: Peng Fan <[email protected]> Signed-off-by: Peng Fan <[email protected]>