In the test, 190MHz noise was found in the EMMC attachment, so we want to switch the working mode of HS400 200MHz to HS200 or lower to verify whether it is the noise effect of EMMC.
Refer to the NXP Official Forum: eMMC configuration to operate in HS200 mode But no answer was given, so let's explore it yourself.
legacy mode Unilateral sampling ( SDR),Support 3 V/1.8V/1.2V Signal voltage, bus width support 1, 4, 8 bit Mode. Maximum frequency support up to 26 Mhz. Corresponding kernel in host Of MMC_TIMING_LEGACY Time Series. HS mode Unilateral sampling ( SDR),Support 3 V/1.8V/1.2V Signal voltage, bus width support 1, 4, 8 bit Mode. Maximum frequency support to 52 Mhz Corresponding kernel in host Of MMC_TIMING_MMC_HS Time Series. HSDDR mode Bilateral sampling ( DDR),Support 3 V/1.8V/1.2V Signal voltage, bus width support 4, 8 bit Mode. Maximum frequency support to 52 Mhz Corresponding kernel in host Of MMC_TIMING_UHS_DDR50 Time Series. HS200 mode Unilateral sampling ( SDR),Support 1.8V/1.2V Signal voltage, bus width support 4, 8 bit Mode. Maximum frequency up to 200 Mhz Corresponding kernel in host Of MMC_TIMING_MMC_HS200 Time Series. HS400 mode Bilateral sampling ( DDR),Support 1.8V/1.2V Signal voltage, bus width support 8 bit Mode. Maximum frequency up to 200 Mhz. Corresponding kernel in host Of MMC_TIMING_MMC_HS400 Time Series.
Hardware Design Diagram
EMMC chip model: MTFC8GAKAJCN-4M IT, supports four modes: SDR/DDR/HS200/HS400
Check the IMX8QXP data manual to support multiple data transfer modes, although HS200 is not mentioned here, it is supported.
DTS Device Tree
Additionally, it is known that EMMC-supported mode types are probed at system startup and will generally be configured up to HS400. However, to enforce a specified working data mode, you can switch to HS200 mode by adding mmc-hs200-1_8v information to the usdhc1 node of the dts device tree, but the modified mode does not take effect, or HS400 mode:
&usdhc1 { pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc1>; pinctrl-1 = <&pinctrl_usdhc1_100mhz>; pinctrl-2 = <&pinctrl_usdhc1_200mhz>; bus-width = <8>; non-removable; mmc-hs200-1_8v; status = "okay"; };
root@genvict_imx8qxp:~# cat /sys/kernel/debug/mmc0/ios clock: 200000000 Hz actual clock: 166666666 Hz vdd: 21 (3.3 ~ 3.4 V) bus mode: 2 (push-pull) chip select: 0 (don't care) power mode: 2 (on) bus width: 3 (8 bits) timing spec: 10 (mmc HS400) signal voltage: 1 (1.80 V) driver type: 0 (driver type B)
The modification is not valid, you can only see how the source code is detected and set up. View the kernel code by viewing the EMMC kernel print.
[ 3.972667] mmc0: CQHCI version 5.10 [ 4.020868] mmc0: SDHCI controller on 5b010000.usdhc [5b010000.usdhc] using ADMA [ 4.148498] mmc0: new HS400 MMC card at address 0001 [ 4.158688] mmcblk0: mmc0:0001 Q2J55L 7.09 GiB [ 4.169308] mmcblk0boot0: mmc0:0001 Q2J55L partition 1 16.0 MiB [ 4.179797] mmcblk0boot1: mmc0:0001 Q2J55L partition 2 16.0 MiB [ 4.190834] mmcblk0rpmb: mmc0:0001 Q2J55L partition 3 4.00 MiB [ 4.204782] mmcblk0: p1 p2
Code Flow
Overall, H200 was chosen to be supported, but HS400 was detected after H200 was chosen, coded as follows:
/* * Activate High Speed, HS200 or HS400ES mode if supported. */ static int mmc_select_timing(struct mmc_card *card) { int err = 0; if (!mmc_can_ext_csd(card)) goto bus_speed; if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES) err = mmc_select_hs400es(card); else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) err = mmc_select_hs200(card); else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS) err = mmc_select_hs(card); if (err && err != -EBADMSG) return err; bus_speed: /* * Set the bus speed to the selected bus timing. * If timing is not selected, backward compatible is the default. */ mmc_set_bus_speed(card); return 0; } /* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { ...... /* * Select timing interface */ err = mmc_select_timing(card); if (err) goto free_card; if (mmc_card_hs200(card)) { err = mmc_hs200_tuning(card); if (err) goto free_card; err = mmc_select_hs400(card); if (err) goto free_card; } else if (!mmc_card_hs400es(card)) { /* Select the desired bus width optionally */ err = mmc_select_bus_width(card); if (err > 0 && mmc_card_hs(card)) { err = mmc_select_hs_ddr(card); if (err) goto free_card; } } ...... return 0; free_card: if (!oldcard) mmc_remove_card(card); err: return err; }
Therefore, as long as the hardware design and EMMC itself support HS400, the data transfer mode of HS400 can be achieved, but then the HS200 mode cannot be forcibly switched in the device tree, only the following code can be modified:
--- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1725,7 +1725,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if (err) goto free_card; - err = mmc_select_hs400(card); + //err = mmc_select_hs400(card); if (err) goto free_card; } else if (!mmc_card_hs400es(card)) {
root@genvict_imx8qxp:~# cat /sys/kernel/debug/mmc0/ios clock: 200000000 Hz actual clock: 166666666 Hz vdd: 21 (3.3 ~ 3.4 V) bus mode: 2 (push-pull) chip select: 0 (don't care) power mode: 2 (on) bus width: 3 (8 bits) timing spec: 9 (mmc HS200) signal voltage: 1 (1.80 V) driver type: 0 (driver type B)
If the detection codes of H200 and HS400 are commented out, the system starts at 400KHz in legacy mode, and the speed of system start-up and read-write is only about 100K:
root@genvict_imx8qxp:~# cat /sys/kernel/debug/mmc0/ios clock: 400000 Hz actual clock: 372023 Hz vdd: 21 (3.3 ~ 3.4 V) bus mode: 2 (push-pull) chip select: 0 (don't care) power mode: 2 (on) bus width: 3 (8 bits) timing spec: 0 (legacy) signal voltage: 0 (3.30 V) driver type: 0 (driver type B)
In the code you want to force a switch to SDR or DDR mode, but both failed to start with errors:
HS mode: [ 5.191830] mmcblk0: error -84 transferring data, sector 0, nr 8, cmd response 0x900, card status 0xb00 [ 5.201245] mmcblk0: retrying using single block read [ 5.214907] print_req_error: I/O error, dev mmcblk0, sector 0 HSDDR mode [ 4.495078] eason....mmc_init_card,1747-select_hs faild!
Help inform if you have information on how to modify the code to support HS/HSDDR mode.
summary
Switching to HS200 or legacy mode does not change the 190MHz noise of EMMC, and as long as the EMMC reads and writes, the noise of 8G EMMC is the same, so it is not possible to find out why at this time. Ask your RF and hardware engineer again later.