This patch adds support for the SDHCI_CAN_DO_64BIT
capability, so that to allow 64-bit DMA operation
for the controllers which support this feature.
Details
- Reviewers
manu loos - Commits
- rG7d8700bc291b: sdhci: extend bus_dma_tag boundary to 64-bit space
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
Unfortunately, it looks bad.
Up until SDHCI v3.0, SDMA is strictly 32-bit, only ADMA mode (which we don't support yet, it is optionally 64-bit). As you can see at https://cgit.freebsd.org/src/tree/sys/dev/sdhci/sdhci.c#n1977, the driver ends up writing only the 32-part of buffer physical address to the DMA base register.
To enable 64-bit SDMA, the driver should check to see if the controller is SDHCI v4.0 compatible and supports 64-bit DMA.
If so, it should:
- switch the controller to v4.0 mode - bit "Host Version 4 Enable" in the Host Control 2 register.
- enable 64 bit DMA mode - bit "64-bit" addressing in in Host Control 2 register.
- select SDMA mode in Host Control 1 register.
- wrote physical address of DMA buffer to ADMA System address register (not to SDMA System Address).
In its current state, the driver can silently corrupt memory by ignoring the upper 32 bits of the DMA address.
Fortunately, the DMA buffer is allocated early enough in most systems to be in the lower 4G of memory.
@mmel Hi. I rechecked and you are right. Additional handling should be done in generic code. FYI, the SoC that needed the change had no < 4G physical address space at all, however it adds the upper 32-bit on HW level. Since current patch is incomplete, I'll revert for now.