DexOS wrote:@jnc100, Great work, are you testing each card and slowing clock down or up accordingly ? or just slow it down any way, as the mailbox has good easy to use functions, for getting max clock speed for sd card.
From what I'm learning deciding on the correct frequency for SD cards is tricky.
The specs define two SD clock frequencies - fOD and fPP used for initialization and data transfer respectively. The exact value for these is hidden away in the simplified specs and despite many days of re-reading and searching I've only just found out whilst in the process of writing the reply that the value fOD should probably be 400 kHz. fPP depends on the card - it can be 25 MHz (default), 50 MHz (high speed mode), or in UHS-I mode it can be 25, 50, 100 or 208 MHz.
The official way of setting the clock speed is to use the clock control register at offset 0x2c. The value you put in here can be determined in two ways. First, some controllers contain a set of 'preset' registers with values to read and put in the clock control register defined for each operating mode. Unfortunately the Arasan circuitry doesn't provide this. The second way is to use one of the clock control modes (either 10-bit divided clock mode or programmable clock mode) to divide the base clock up to an appropriate value.
To do this, you need to know both the base clock rate provided to the eMMC controller and the value of 'M' (if you are using programmable clock mode). On most host controllers, both of these are found in the capabilities register, which again is not present in the Arasan chip. Thus without knowledge of the magic 'M' value, it is impossible to calculate a divisor using the programmable clock mode (perhaps this knowledge could be gleaned from the linux module sources?). If the base clock rate is not found in the capabilities register, the SDHCI docs state it should be found 'by other means'. In the case of the Broadcom chip we can use the mailbox interface to query the clock rate supplied to the eMMC controller and then calculate our divisor from that.
The boot-up value of the base eMMC clock in the RPi is currently 100 MHz (as I have recently discovered). What I was previously doing (based upon code found somewhere in these forums) was using programmable clock mode to set the SD clock frequency to 'base clock * M / 2' which if we assume the value of 'M' is 1 equates to 50 MHz, for higher values of 'M' it is even quicker, which obviously wouldn't work with anything but the most modern cards. I think the reason the code was provided here was that that I think (based upon reading old code lying around) the base eMMC clock was 50 MHz in previous firmware versions (thus giving a valid SD clock of 25 MHz) but has since been increased.
The new version of my code does not change the base eMMC clock but simply reads its value and calculates an appropriate divisor for 10-bit programmable clock mode. To get things working I currently set all cards to run at 12.5 MHz (but enable 4-bit mode and UHS-I for quicker transfers if they are available) although I imagine what I should probably do is use 400 kHz for the identification phase and then switch up to 25 MHz for data transfers however as things seem to work for everyone now I'm reluctant to make this change.
I do not know what would happen if you change the clock frequency by using the mailbox interface intstead of the internal divider within the eMMC circuitry, as this would affect the clock rate at which the host interfaces with the rest of the ARM and Broadcom peripherals, as well as the SD clock rate (which is the rate the host interfaces with the card). Also, you are supposed to switch the SD card clock off when changing its rate and then re-enable it afterwards, so using the in-built divider may be easier anyway (as you can do it all with writing to the same register).