BPI-R3 Mini eMMC Upgrade Project – Planning a 256 GB Upgrade

Hello everyone, I’m planning to upgrade the onboard eMMC of my Banana Pi BPI-R3 Mini from the factory chip to a 256 GB Samsung eMMC.

The eMMC I’m planning to use is: Samsung KLMEG8UERM-C041

From the information I have, it offers: Capacity: 256 GB Interface: eMMC 5.1 Package: BGA153 Manufacturer: Samsung

Higher storage capacity for Ubuntu, OpenWrt, Docker, containers, VMs, and development work. My goal is to make the BPI-R3 Mini a more capable router/NAS/server while keeping the onboard storage instead of relying entirely on an external SSD.

I’m also working on improving PCIe/NVMe support for my board, so increasing the onboard eMMC capacity will provide much more space for firmware development and testing.

I’d appreciate any advice from anyone who has: Successfully replaced the original eMMC. Verified compatibility of the Samsung KLMEG8UERM-C041 with the MT7986 platform. Found any bootloader (BL2/FIP), partitioning, or hardware issues after upgrading to a larger eMMC. Any experience or recommendations would be greatly appreciated.

Thank you!

Its original chip is an 8G eMMC, model number THGBMJG6C1LBAIL.

To replace it, I think we first need to compare their hardware power supply and software timings. If you are not familiar with this, you can try replacing it after comparing the voltage levels to see if it works.

You can find the datasheet for this chip online to view it.

Update: Samsung 256 GB eMMC Upgrade — Confirmed Findings and Open Questions

Hello everyone,

I have installed the Samsung KLMEG8UERM-C041 256 GB eMMC on my Banana Pi BPI-R3 Mini. I am currently investigating why Linux fails to switch the device to an eight-bit bus.

I have separated the observations confirmed by command output from possible explanations that have not yet been verified.

A. Confirmed facts

1. Test environment and storage

  • Board: Banana Pi BPI-R3 Mini, MediaTek MT7986.
  • Current OS: BananaWRT v25.12-linkup, booted from the board’s SPI-NAND for testing.
  • Replacement eMMC: Samsung KLMEG8UERM-C041, nominal 256 GB.
  • Linux-reported device name: EURM4S.
  • Detected capacity: 233 GiB.
  • eMMC revision: 5.1.
  • Boot partitions: boot0 and boot1, 4 MiB each.
  • RPMB: 4 MiB.

The replacement is detected by both U-Boot and Linux. Ubuntu has not yet been flashed to the replacement eMMC.

2. Linux initialization and current operating mode

The boot log contains:

mmc0: switch to bus width 8 failed
mmc0: new HS200 MMC card at address 0001
mmcblk0: mmc0:0001 EURM4S 233 GiB

The live controller state, read from /sys/kernel/debug/mmc0/ios, reports:

bus width:      2 (4 bits)
timing spec:    9 (mmc HS200)
signal voltage: 1.80 V
actual clock:   104000000 Hz

Therefore, Linux is currently operating the Samsung in four-bit HS200 mode, not HS400.

3. Samsung eMMC capabilities

The EXT_CSD data reports:

EXT_CSD_REV: 0x08
CARD_TYPE:   0x57
SEC_COUNT:   00c01e1d

The revision indicates eMMC 5.1. The CARD_TYPE value advertises HS200 and HS400 support at 1.8 V. SEC_COUNT is consistent with the detected capacity.

This confirms the advertised capabilities, but does not establish that the board can successfully initialize all those modes.

4. Active device-tree and pinctrl configuration

The live device tree contains:

bus-width          = 8
max-frequency      = 200000000
mmc-hs200-1_8v     = present
mmc-hs400-1_8v     = present
hs400-ds-delay     = 0x00014014

The clocks, assigned-clocks and assigned-clock-parents properties are also present.

Linux pinctrl reports all 12 eMMC signals assigned to the controller:

  • DAT0–DAT7
  • CMD
  • CLK
  • DS
  • RSTB

The pin configuration is present for all 12 signals. These checks establish the software assignments, not physical continuity of the PCB traces or BGA solder joints.

5. U-Boot result

U-Boot reports:

Mode: MMC High Speed (52MHz)
Bus Width: 4-bit

Requesting MMC mode index 10 did not change the reported mode. The capabilities of this particular U-Boot build have not been independently established, so this result alone does not prove a hardware problem.

In my earlier logs, the original Kioxia THGBMJG6C1LBAIL 8 GB eMMC successfully reached HS400 on this board.

B. Hypotheses—not yet confirmed

The cause of the failed eight-bit switch remains unresolved.

Hypothesis 1: Physical connection issue

A poor BGA solder joint or PCB connection affecting DAT4–DAT7 could prevent eight-bit operation while allowing the device to work in four-bit mode. This is plausible but has not been demonstrated by continuity measurements or BGA inspection.

Hypothesis 2: Controller or driver initialization issue

The MediaTek MSDC driver, the firmware version, or a chip-specific initialization difference could explain the failure. The presence of the expected device-tree properties does not prove that every initialization step is correct.

Hypothesis 3: Clock or timing configuration

The clock-parent configuration or HS400 timing parameters might require further investigation. However, the current clock-tree information has not established that these are the cause.

The hs400-ds-delay setting may matter when tuning HS400, but the eight-bit switch fails before HS400 is activated. I therefore do not want to change the data-strobe delay prematurely.

No evidence currently proves that the Samsung chip itself is defective or that its soldering is faulty.

C. Questions for the community

  1. Are there known initialization quirks or MediaTek MSDC patches for the Samsung KLMEG8UERM-C041 on MT7986?
  2. What is the recommended way to debug switch to bus width 8 failed in the Linux MMC core and MediaTek MSDC driver?
  3. Can anyone confirm HS400 operation with this Samsung part on the BPI-R3 Mini or another MT7986 platform?
  4. What is the most reliable procedure for separating a driver/configuration issue from a physical DAT4–DAT7 connection problem?

My objective is to diagnose the eight-bit initialization failure before changing the device tree or performing further BGA rework.

Thank you for your technical advice.

Have you ever tried to add fixed-emmc-driver-type = <1>; in your dts? Like this:

&mmc0 {
	pinctrl-names = "default", "state_uhs";
	pinctrl-0 = <&mmc0_pins_default>;
	pinctrl-1 = <&mmc0_pins_uhs>;
	bus-width = <8>;
	max-frequency = <208000000>;
	cap-mmc-highspeed;
	mmc-hs200-1_8v;
	mmc-hs400-1_8v;
	hs400-ds-delay = <0x12814>;
	vqmmc-supply = <&reg_1p8v>;
	vmmc-supply = <&reg_3p3v>;
	fixed-emmc-driver-type = <1>;
	non-removable;
	no-sd;
	no-sdio;
	status = "okay";
};

If possible, please dump cat /sys/kernel/debug/mmc0/mmc0:0001/ext_csd result for me. I would like to help with this if you can tell us more about EXT_CSD registers value.

1 Like

We recently added support for R3 mini, covering 6.18 and 7.3 kernel. Still WIP, but worth checking Banana Pi R3 Mini | Armbian

2 Likes

A technically precise reply would acknowledge the suggestion, provide the current evidence, and avoid claiming the driver-type setting is already proven.

Thanks for the suggestion. I have not tried fixed-emmc-driver-type = <1>; yet, so I will test that separately rather than changing the HS400 delay at the same time.

My current findings are:

  • The Samsung KLMEG8UERM-C041 is detected correctly by Linux.
  • bus-width = <8> , max-frequency = <200000000> , mmc-hs200-1_8v , and mmc-hs400-1_8v are all present in the live device tree.
  • The card identifies as Samsung (manfid = 0x000015 ) and reports EURM4S , 233 GiB.
  • The card reaches READY_FOR_DATA with CMD13.
  • However, the initialization does not reliably progress to the intended 8-bit mode. In my latest low-level test the controller was still showing 1-bit legacy operation, and a direct read from /dev/mmcblk0 failed with an I/O error.
  • The kernel MMC error counters currently show zero command/data CRC and timeout errors, so I am still trying to determine exactly where the data-transfer failure occurs.

The original KIOXIA THGBMJG6C1LBAIL on the same board was able to reach HS400, so the host hardware and basic MMC controller configuration are known to work with the original device.

I will also dump the EXT_CSD information you requested. mmc extcsd read /dev/mmcblk0 currently times out, so I will check whether the kernel debugfs card entry exposes the EXT_CSD data directly.

I agree that testing fixed-emmc-driver-type = <1> is worthwhile. I would like to test that independently first, while keeping hs400-ds-delay unchanged, because the 8-bit initialization problem appears to occur before HS400/DS timing becomes relevant.

If you know which MediaTek MSDC driver setting corresponds to fixed-emmc-driver-type , or what driver type <1> represents on MT7986, that would also help interpret the result.

this seems to be a core-setting and nothing mtk specific one:

drivers/mmc/core/host.c:412:	if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
drivers/mmc/core/host.c-413-		if (host->caps & MMC_CAP_NONREMOVABLE)
drivers/mmc/core/host.c-414-			host->fixed_drv_type = drv_type;
drivers/mmc/core/host.c-415-		else
drivers/mmc/core/host.c-416-			dev_err(host->parent,
drivers/mmc/core/host.c-417-				"can't use fixed driver type, media is removable\n");
drivers/mmc/core/host.c-418-	}

it looks like it is a configuration if eMMC supports type in EXT_CSD (“A” =>drv_type=1) or not (“B”,0 or “C”=2 or “D”=3)…include/linux/mmc/host.h, check in mmc_select_driver_type()

it looks like some kind of electrical strength for fast modes of emmc…nothing linux specific and nothing for host-controller itself

mmc@11230000 {

                    compatible = "mediatek,mt7986-mmc";
                    reg = <0x00 0x11230000 0x00 0x1000 0x00 0x11c20000 0x00 0x1000>;
                    interrupts = <0x00 0x8f 0x04>;
                    assigned-clocks = <0x03 0x23 0x03 0x22>;
                    assigned-clock-parents = <0x06 0x06 0x03 0x12>;
                    clocks = <0x03 0x23 0x05 0x29 0x05 0x28 0x05 0x2a 0x05 0x2b>;
                    clock-names = "source", "hclk", "source_cg", "bus_clk", "sys_cg";
                    status = "okay";
                    #address-cells = <0x01>;
                    #size-cells = <0x00>;
                    pinctrl-names = "default", "state_uhs";
                    pinctrl-0 = <0x14>;
                    pinctrl-1 = <0x15>;
                    bus-width = <0x08>
                    max-frequency = <0x0c65d400>;
                    cap-mmc-highspeed;
                    mmc-hs200-1_8v;
                    mmc-hs400-1_8v;
                    hs400-ds-delay = <0x12814>;
                    vmmc-supply = <0x12>;
                    vqmmc-supply = <0x16>;
                    fixed-emmc-driver-type = <0x01>;
                    non-removable;
                    no-sd;
                    no-sdio;
                    phandle = <0x42>;

                    card@0 {
                            compatible = "mmc-card";
                            reg = <0x00>;

                            block {
                                    compatible = "block-device";

                                    partitions {

                                            block-partition-production {
                                                    partname = "production";
                                                    phandle = <0x2c>;
                                            };
                                    };
                            };
                    };
            };

Setting fixed-emmc-driver-type = <1> actually overrides EXT_CSD[185]'s bit4~7. You can see the definition in eMMC’s spec. Basically, setting emmc’s driver type as 0x1 will increase its driving cap. I observed that some Samsung eMMC devices require this option to achieve HS400 probe and transmission.