Page 1 of 1

SD Host Controller driver (on Raspberry Pi)

Posted: Fri Nov 19, 2021 6:07 am
by vhaudiquet
Hi,

As i'm trying to support the Raspberry Pi in my kernel, i need a way to read the SD Card.

I had never dealt with SD cards before, so i read the SD specifications (https://www.sdcard.org/downloads/pls/, Physical Layer Simplified Specification).
It was a little bit hard to understand everything, but i think i now understand the basics of the SD protocol, how to initialize and enter data transfer mode, ...
(side note: i could not find any information about SD Cards on the wiki, but maybe this is because of the license of this specification ? it seems we don't have any rights to reproduce parts of the specification, and other legal requirements that i did not understand well)

I then read the BCM2835 Arm Peripherals specification (Raspberry Pi soc), available here https://datasheets.raspberrypi.com/bcm2 ... herals.pdf, section 5 : External Mass Media Controller. This describes the Arasan controller, but only the modifications that Broadcom did to it. They refer to the original Arasan documentation, but a quick search on google shows that Arasan never published this documentation nor intended to, as it is supposed to be available for SoC manufacturers only.

Anyway, i read on the specifications, and using the MMIO addresses described, i got a response to an initialization command.
I don't understand how this is possible, and to my understanding Broadcom are completely crazy :
the SD protocol defines 48-bits communication channels to send commands, but Broadcom seems to have split this up in 2 32-bits MMIO registers, CMDTM and ARG1.
You would expect something like : low 32 bits are ARG1, and up 16 bits are the low or high 16 bits of CMDTM (CMDTM meaning Command AND Transfer Mode)

This is basically what my code assumes. It doesnt matter much for init commands as the arguments are pretty much ignored (like controller SDHC capacity/ ..., i will still get a response either way)
(EDIT : i just realized i sent two times CMD0 and not ACMD41, and i can't get a response on ACMD41 ; on double CMD0 i get 0x1 as a response, i think it brings the device in SPI mode, but i'm not intersted in that)

However, Broadcom layout describes fields on the CMDTM register that are not in the SD protocol standard (like CMD_ISDATA, to tell the controller if the command will involve a data transfer),
and these fields are taking place of the bits that would normally be used by other standard arguments. So : they seem to have randomized the 16 bits left over a 32 bits register, adding nonstandard bits in the way. How am i supposed to deal with this ?

I tried to read the linux driver code, but it isn't that easy : the RPI seems to have 2 different host controller (my guess is orginally one for the GPU to load the kernel and one for the ARM). The SD Host Controller that is not the Arasan one seems to be faster, so they have a specific driver for this one in linux (drivers/mmc/host/bcm2835.c). However this is NOT the one i'm interested in. If i understand correctly, for the Arasan one, they use the 'sdhci' driver. I did not understand what sdhci meant as first, but it seems to be 'SD Host Controller Interface', so a generic standard host controller driver.

Maybe i'm living in a fantasy world, but i was under the impression that SD Protocol was standardised enough so that there would be such an universal sd host controller driver, and it is what i'm trying to make (i would like to reuse my driver on other devices that are not the pi later if possible).
Is this real ? Or am i wrong and each SD host controller needs it's own driver ?

But then how does linux do it ? I've seen that they have sdhci over pci (drivers/mmc/host/sdhci-pci-core.c) and even arasan sdhci (drivers/mmc/host/sdhci-pci-arasan.c) specific drivers, but reading them it seems like they only fix some specific performance/bugs on the hardware, but still use the generic driver.

Is this possible to write a generic sdhci driver ? How am i supposed to get the BCM2835 Arasan SD controller to comply to the SD standard, where are the bits that are standard and why would i need to fill the bits that are not ?

I'm a little bit lost in this.
If someone already implemented an SD Card driver, for the PC (i think most of them are accessible through PCI or behind an USB interface ?), or even for the raspberry pi, i would love to hear from you.

(NB: i'm talking about an SD Protocol driver, not an SPI driver)

vhaudiquet

Re: SD Host Controller driver (on Raspberry Pi)

Posted: Wed Nov 24, 2021 3:45 pm
by vhaudiquet
Hi,

Little update if someone reading this is having the same issue i have understanding the arasan/broadcom rpi sd controller :
i've found this code : https://github.com/bztsrc/raspi3-tutori ... ector/sd.c
written by bzt, which is basically a driver for this controller, used on his raspi3-tutorial series.

i find it a little bit hard to read ; the init functions starts with stuff like this

Code: Select all

r=*GPFSEL4; r&=~(7<<(7*3)); *GPFSEL4=r;
and there are many short variable names that are confusing in lines like

Code: Select all

x=c-1; if(!x) s=0;
but it seems to be working so i'll try to dive into it this weekend to implement my driver.

however, this code seems to be really specialized at the rpi controller.

my question still holds : are there parts of this code that i could reuse on any other controller or will they be completely different ?

if anyone implemented an sd card driver for x86 pc, could you describe basically where do you send the commands and how are the 'registers' of the controller ?

Re: SD Host Controller driver (on Raspberry Pi)

Posted: Sun Jul 28, 2024 12:02 am
by digispin
Can you share your code that interacts with the SD Controller? asm or c