Increasing (e)MMC clock for faster boot

I was just reading this post and wondering: what is the right way to increase the (e)MMC clock rate? I haven’t done a ton of digging on this just yet, but I’ve seen some interesting things in the am33xx-clocks dtsi and the am33xx-l4.dtsi. That seem to contain the nodes I want to modify; but I have a bit of uncertainty about this. Curious if anyone has done similar and is willing to share what they learned.

edit: did a bit of digging into the TRM for the AM335x, and the max clock frequency is 100MHz… which is what it is by default.

IIRC the BBB is in nitro mode, which is clocking beyond the normal multipliers, you keep the fundamental clocks at 100MHz though. Overclocking emmc you usually do through timings. When I’ve so it before I’ve modified the device tree at uboot time, crux is finding the thing to change, and the changing it in a safe way - e.g. If you have a script that modifies the device tree at built time, then when the machine refuses to boot, you can pull the sd card, and change things back. Also if you a uart attached, can just modify the change in uboot in real time. If I get time I’ll look into what to change, doing it via uboot may well be different, as I use arch rather than debian.

This is where I did this on an odroid Arch Linux ARM • View topic - odroid-c2 linux 4.15 and eMMC [SOLVED - well work arround]

OK found the two possible entries in the device tree for BBB:

ocp/interconnect@48000000/segment@100000/target-module@d8000/mmc@0 - this is the emmc
ocp/interconnect@48000000/segment@0/target-module@60000/mmc@0 - this is the sdcard

Neither has a speed, so will need to check from the compatible flag which kernel driver it uses, and if that kernel module can also take a speed setting from device tree.

This is where you can get the Device tree parameters for the kernel driver - it doesn’t obviously have a speed - so need to check if the kernel drive also uses the higher mmc kernel drive, which has speed settings.

This is where you can see the max-frequency, its not clear if this sets the running speed, or the maximum speed. Usually the speed is set by the card type, e.g. HS400 and so on, so I think max-frequency may only be to under clock devices …

So think maybe the way to do this is to force the emmc to be run in a different mode than is detected, this allows a higher multiplier. Then you set the max-frequency to down clock the speed to close to where you want it.

Btw - doing this is hairy as anything, it stands a good chance of breaking your system. So the real question has to be why do you want to increase the speed of the emmc beyond what is detected, boot speed isn’t a good reason …

Ohh yes this is wher you can see current settings: /sys/kernel/debug/mmc*/ios

The kernel module that does the emmc is:

omap_hsmmc.c

So you can see where the 5200000 comes from. It seems to inherit the maximum frequency - so it does suggest you can change the maximum frequency as above, this is under the assumption that it uses the main mmc code - which I think does take the maximum frequency.

If you do change these things, make sure you have a way of changing back. e.g. write it to a file system you can access independently (e.g. and sd card).

Thank you for the response!

What I found agrees with your comment: SD/eMMC speed is detected by the kernel module. I’m not 100% sure that the speed can be changed manually, and I sort of worry about doing it anyways.

Switching to the eMMC might be enough of a speed up given it has twice the data lanes.

The emmc on the bbb, although it has 8 lanes, it only runs at 52MHz, which is the 4.3 spec. Not sure what spec the sd slot is, it’s only 4 lanes, but think it can run at over 100MHz. So a fast sd card maybe faster than the emmc. I know @RobertCNelson has some info on this, and can say how fast the sd slot can go, e.g. Which card to buy to get the max speed.

Oh yes do use cat /sys/kernel/debug/mmc*/ios that means you can see how fast it is going, e.g. on my BBB my emmc used 8 bit @ 52MHz, and by sd uses 4 bits @ 50Mhz, but on pocketbeagle2 its on 200MHz using 4 bits (and the emmc is not on the board).

Oh yes you could try interrupting uboot (so you’ll need a uart cable connected). Then try:

fdt addr ${fdt_addr_r}
fdt resize 1024
fdt set /ocp/interconnect@48000000/segment@0/target-module@60000/mmc@0 max-frequency <0x30a32c0>
ftd resize

It may work and set it to 51MHz … and its easy enough to try if you have a uart cable. You’ll need to be at the right place in uboot - e.g. you’ve loaded the device tree at ${fdt_addr_r} - at least I assume the debian set up uses something like that - I’ve never dug into debians uboot in much detail …

And if the machine doesn’t boot - you just don’t set it next time …

1 Like

Woah - just tried max-frequency and it worked. So full uboot commands:

part uuid mmc 1:1 uuid
setenv bootargs “console=tty0 console=${console} root=PARTUUID=${uuid} rw rootwait”
load mmc 1:1 ${kernel_addr_r} /boot/zImage
load mmc 1:1 ${fdt_addr_r} /boot/dtbs/am335x-boneblack.dtb
fdt addr ${fdt_addr_r}
load mmc 1:1 0x88060000 /boot/dtbs/overlays/AM3359-PWM012.dtbo
fdt resize ${filesize}
fdt apply 0x88060000
fdt resize
fdt resize 1024
fdt set /ocp/interconnect@48000000/segment@0/target-module@60000/mmc@0 max-frequency
fdt set /ocp/interconnect@48000000/segment@0/target-module@60000/mmc@0 max-frequency <49000000>
load mmc 1:1 ${ramdisk_addr_r} /boot/initramfs-linux.img
bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}

Then it boots

sudo cat /sys/kernel/debug/mmc0/ios
clock:          49000000 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:      2 (4 bits)
timing spec:    2 (sd high-speed)
signal voltage: 0 (3.30 V)
driver type:    0 (driver type B)

I haven’t tried overclocking yet - but under clocking works. Probably easiest is to create your own overlay with the max-frequency, and then set uboot to load that overlay.

Oh yes its worth saying if you do type the commands in uboot - be very careful. Just one character wrong and uboot gives unhelpful errors - and some mistake and it just reboots the machine - uboot is a tad fussy and you’ll need to adapt it for the uboot that debian uses - which looks hacked to me. My uboot was mainline in 2017 ….

1 Like

What’s the resize for? Thanks for digging into the details here.

fdt resize is used for resizing the size of the memory allocated to the device tree - in uboot you have to do a resize when you are adding things, otherwise the device tree memory fills, and you get an error - so you’ll see the code before doing the overlays. In my case as I’m making a change to the device tree - I just make it larger by a small amount that will be enough. Afterwards I do a fdt resize with no size attached to shrink the memory allocated to the device tree down to the minim that is covers the device tree with patches. This used to be described in the uboot commands page - but I checked that this morning, although fdt resize is mentioned - it looks like the apply option also has this increase in size - and that seems the main one described. Hope that helps.