Micro SD card writes very slow

And it does make sense because the SDCARD organization says that you must pay royalties if you want to use the 4 bits mode

Until you realize the eMMC populated on the BeagleBone black doesn't
talk over SPI mode... Otherwise it too would be limited to 5Mb/s.

Obviously a driver problem..

Regards,

I believe that the pattern of activity on pin 3 and 7 would be swapped when changing from read to write if you were right. The pattern of activity is the same, suggesting 1 bit SD access.

It’s working !!!

I took a wild guess, and decompiled /boot/am335x-boneblack.dtb

I found the parts for the three mmc controllers. I figured that mmc@48060000 was the uSD slot and mmc@481d8000 was the eMMC part. The second one had this line: bus-width = <0x8>;

What if we took this hint, and added bus-width = <0x4>; to the first one?. I compiled the dts file and rebooted.

Read speed: 19.9 MB/s
Write speed 8.8 MB/s

Yeah! I just tripled the performance of the uSD card. :slight_smile:

This works both when booted from the eMMC and when booted from the uSD card.

This was done on Angstrom “Linux beaglebone 3.8.13 #1 SMP Wed Sep 4 09:09:32 CEST 2013 armv7l GNU/Linux”. Haven’t tested it on Debian yet.

I don’t know if this is the right way to do things or if it is just a dirty hack, and I don’t know who to notify of my findings. Please assist.

Jens,

Nice find ! Would you mind doing a mini writeup ? Not quite sure exactly what you’ve done, but I would be willing to test on my end too as well.

I found . . .

&mmc2 {
vmmc-supply = <&vmmcsd_fixed>;
bus-width = <8>;
ti,non-removable;
status = “okay”;

reset = <&rstctl 0 0>;
reset-names = “eMMC_RSTn-CONSUMER”;
};

but nothing else in ./arch/arm/boot/dts/am335x-boneblack.dts. Is this what I am looking for ?

Sure, no problem.

(Please make a backup first. This worked for me, there are no guarantees that it will work for you. I haven’t yet been able to confirm that this is the right way to solve the problem)

  1. decompile the device tree:

`
dtc -I dtb -O dts -o test.dts /boot/am335x-boneblack.dtb

`

  1. Edit the decompiled file:
    `
    nano test.dts

`

3.Search for the parts with the mmc controllers:
`
^w
mmc@48060000

`

  1. You will see three mmc controllers:

`
mmc@48060000 {
compatible = “ti,omap3-hsmmc”;
ti,hwmods = “mmc1”;
ti,dual-volt;
ti,needs-special-reset;
ti,needs-special-hs-handling;
dmas = <0x8 0x18 0x8 0x19>;
dma-names = “tx”, “rx”;
status = “okay”;
pinctrl-names = “default”;
pinctrl-0 = <0x9>;
cd-gpios = <0xa 0x6 0x0>;
cd-inverted;
vmmc-supply = <0xb>;
ti,vcc-aux-disable-is-sleep;
linux,phandle = <0x28>;
phandle = <0x28>;
};

mmc@481d8000 {
compatible = “ti,omap3-hsmmc”;
ti,hwmods = “mmc2”;
ti,needs-special-reset;
ti,needs-special-hs-handling;
dmas = <0x8 0x2 0x8 0x3>;
dma-names = “tx”, “rx”;
status = “disabled”;
vmmc-supply = <0xb>;
bus-width = <0x8>;
ti,non-removable;
reset = <0xc 0x0 0x0>;
reset-names = “eMMC_RSTn-CONSUMER”;
linux,phandle = <0x29>;
phandle = <0x29>;
};

mmc@47810000 {
compatible = “ti,omap3-hsmmc”;
ti,hwmods = “mmc3”;
ti,needs-special-reset;
ti,needs-special-hs-handling;
status = “disabled”;
linux,phandle = <0x2a>;
phandle = <0x2a>;
};

`

The first one is the uSD card (“mmc1”). The second one is the eMMC device and the third one is unused.

  1. Add this line to the first one:
    `
    bus-width = <0x4>;

`

I don’t know if the order of the lines is critical, but I added the line below the vmmc-supply line, just like the eMMC device.
The first device should now look like this:

mmc@48060000 { compatible = "ti,omap3-hsmmc"; ti,hwmods = "mmc1"; ti,dual-volt; ti,needs-special-reset; ti,needs-special-hs-handling; dmas = <0x8 0x18 0x8 0x19>; dma-names = "tx", "rx"; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <0x9>; cd-gpios = <0xa 0x6 0x0>; cd-inverted; vmmc-supply = <0xb>; bus-width = <0x4>; ti,vcc-aux-disable-is-sleep; linux,phandle = <0x28>; phandle = <0x28>; };

  1. Save the file
    `
    ^x
    y
    [enter]

`

  1. compile the dts file:

dtc -I dts -O dtb -o /boot/am335x-boneblack.dtb test.dts

  1. reboot

`
reboot

`

  1. Enjoy :slight_smile:

YMMV. I got about three times better performance with a Sandisk Ultra card. If you have a slower card, you will not see the same improvement.

oh, and the above writeup was done on Angstrom.

Awesome thanks Jens. Exact steps :wink:

Second post I just made was from a dts file I searched through using nano that came from instruction given by Robert Nelsons Linux on ARM ( debian 3.8.x ). Figured it was not right, but was about to search through a couple of includes . . .

Nice find..

/dev/mmcblk0:
Timing cached reads: 380 MB in 2.01 seconds = 189.30 MB/sec
Timing buffered disk reads: 56 MB in 3.00 seconds = 18.64 MB/sec

you can also just add the 4bit setting to the device dtb via:

diff --git a/arch/arm/boot/dts/am335x-bone.dts
b/arch/arm/boot/dts/am335x-bone.dts
index d5f43fe..aa1efb1 100644
--- a/arch/arm/boot/dts/am335x-bone.dts
+++ b/arch/arm/boot/dts/am335x-bone.dts
@@ -19,4 +19,5 @@
&mmc1 {
  status = "okay";
  vmmc-supply = <&ldo3_reg>;
+ bus-width = <0x4>;
};
diff --git a/arch/arm/boot/dts/am335x-boneblack.dts
b/arch/arm/boot/dts/am335x-boneblack.dts
index a6d7b0e..2a3f731 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -22,6 +22,7 @@

&mmc1 {
  vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <0x4>;
};

&mmc2 {

Regards,

Confirmed here too . .

william@arm:~$ lsb_release -a | grep Description
No LSB modules are available.
Description: Debian GNU/Linux 7.1 (wheezy)

william@arm:~$ uname -a
Linux arm 3.8.13-bone21 #1 SMP Sat Jun 15 19:36:33 MST 2013 armv7l GNU/Linux

william@arm:~$ sudo hdparm -tT /dev/mmcblk1

/dev/mmcblk1:
Timing cached reads: 456 MB in 2.00 seconds = 227.80 MB/sec
Timing buffered disk reads: 54 MB in 3.07 seconds = 17.56 MB/sec

However I did this slightly differently.

first I made a backup of the dtb on the beaglebone ( cp’d to ~/ on a reg user ) then on my cross system…

william@support:~$ nano ~/debian/linux-dev/KERNEL/arch/arm/boot/dts/am335x-boneblack.dts

^W added bus-width and found . . .
&mmc1 {
vmmc-supply = <&vmmcsd_fixed>;
bus-width = <0x4>; //<— added this
};

saved out of nano.

william@support:~/debian/linux-dev/KERNEL$ dtc -I dts -O dtb -o ~/am335x-boneblack.dtb ./arch/arm/boot/dts/am335x-boneblack.dts

And I boot tftp / nfs on my BBB from this cross system, so all i had to do was move the file into the nfsroot/boot, and bam done.

Thanks again jens awesome find.

If you wants something added to the kernel, send a pull request against https://github.com/beagleboard/kernel/

For people wanting to get this speed boost, just do:

  opkg update ; opkg install kernel-devicetrees ; reboot

That will install the new devicetree(s) and nothing else and reboot into the new, much faster system.

regards,

Koen

Thank you Koen. As far as I can tell, you did the pull request already, so no need for me to do it now, right? (sorry if it’s a total noob question)

And thanks to those of you brave enough to confirm my finding.

Thank you Koen. As far as I can tell, you did the pull request already, so no need for me to do it now, right? (sorry if it's a total noob question)

Right :slight_smile:

And for future reference, you can inspect the mmc parameters using debugfs as well:

root@beaglebone-cam:~# cat /sys/kernel/debug/mmc1/ios
clock: 52000000 Hz
vdd: 7 (1.65 - 1.95 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 3 (8 bits)
timing spec: 1 (mmc high-speed)
signal voltage: 0 (3.30 V)

root@beaglebone-cam:~# cat /sys/kernel/debug/mmc0/ios
clock: 50000000 Hz
vdd: 20 (3.2 ~ 3.3 V)
bus mode: 2 (push-pull)
chip select: 0 (don't care)
power mode: 2 (on)
bus width: 2 (4 bits)
timing spec: 2 (sd high-speed)
signal voltage: 0 (3.30 V)

I wonder if am335x can support the 100 and 200MHz modes in the UHS-I spec, that would be a neat speed boost.

regards,

Koen

That debugfs command could have saved me from a huge learning experience :wink:

According to the Technical Reference Manual for the MPU, 24 MB/s is the theoretical maximum speed for a 4-bit connection.

D’oh ! Silly me, I was editing the wrong file, or rather I was putting it into the wrong place. tftp gotcha !

william@arm:~$ sudo hdparm -tT /dev/mmcblk0

/dev/mmcblk0:
Timing cached reads: 482 MB in 2.00 seconds = 240.72 MB/sec
Timing buffered disk reads: 54 MB in 3.05 seconds = 17.68 MB/sec
william@arm:~$ sudo hdparm -tT /dev/mmcblk1

/dev/mmcblk1:
Timing cached reads: 402 MB in 2.00 seconds = 200.65 MB/sec
Timing buffered disk reads: 54 MB in 3.08 seconds = 17.56 MB/sec

Got it right now though ! mmcblk0 is the sdcard.

What would the equivalent package for Debian? There doesn’t seem to be any Debian package called “kernel-devicetrees”.

It's built into the linux-image-(uname -r) package..

Regards,