Skip to content

Commit

Permalink
Adding bcm2835-sdhost driver, and an overlay to enable it
Browse files Browse the repository at this point in the history
BCM2835 has two SD card interfaces. This driver uses the other one.

bcm2835-sdhost: Error handling fix, and code clarification

bcm2835-sdhost: Adding overclocking option

Allow a different clock speed to be substitued for a requested 50MHz.
This option is exposed using the "overclock_50" DT parameter.
Note that the sdhost interface is restricted to integer divisions of
core_freq, and the highest sensible option for a core_freq of 250MHz
is 84 (250/3 = 83.3MHz), the next being 125 (250/2) which is much too
high.

Use at your own risk.

bcm2835-sdhost: Round up the overclock, so 62 works for 62.5Mhz

Also only warn once for each overclock setting.

bcm2835-sdhost: Improve error handling and recovery

1) Expose the hw_reset method to the MMC framework, removing many
   internal calls by the driver.

2) Reduce overclock setting on error.

3) Increase timeout to cope with high capacity cards.

4) Add properties and parameters to control pio_limit and debug.

5) Reduce messages at probe time.

bcm2835-sdhost: Further improve overclock back-off

bcm2835-sdhost: Clear HBLC for PIO mode

Also update pio_limit default in overlay README.

bcm2835-sdhost: Add the ERASE capability

See: raspberrypi/linux#1076

bcm2835-sdhost: Ignore CRC7 for MMC CMD1

It seems that the sdhost interface returns CRC7 errors for CMD1,
which is the MMC-specific SEND_OP_COND. Returning these errors to
the MMC layer causes a downward spiral, but ignoring them seems
to be harmless.

bcm2835-mmc/sdhost: Remove ARCH_BCM2835 differences

The bcm2835-mmc driver (and -sdhost driver that copied from it)
contains code to handle SDIO interrupts in a threaded interrupt
handler rather than waking the MMC framework thread. The change
follows a patch from Russell King that adds the facility as the
preferred way of working.

However, the new code path is only present in ARCH_BCM2835
builds, which I have taken to be a way of testing the waters
rather than making the change across the board; I can't see
any technical reason why it wouldn't be enabled for MACH_BCM270X
builds. So this patch standardises on the ARCH_BCM2835 code,
removing the old code paths.

bcm2835-sdhost: Don't log timeout errors unless debug=1

The MMC card-discovery process generates timeouts. This is
expected behaviour, so reporting it to the user serves no purpose.
Suppress the reporting of timeout errors unless the debug flag
is on.

bcm2835-sdhost: Add workaround for odd behaviour on some cards

For reasons not understood, the sdhost driver fails when reading
sectors very near the end of some SD cards. The problem could
be related to the similar issue that reading the final sector
of any card as part of a multiple read never completes, and the
workaround is an extension of the mechanism introduced to solve
that problem which ensures those sectors are always read singly.

bcm2835-sdhost: Major revision

This is a significant revision of the bcm2835-sdhost driver. It
improves on the original in a number of ways:

1) Through the use of CMD23 for reads it appears to avoid problems
   reading some sectors on certain high speed cards.
2) Better atomicity to prevent crashes.
3) Higher performance.
4) Activity logging included, for easier diagnosis in the event
   of a problem.

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: Restore ATOMIC flag to PIO sg mapping

Allocation problems have been seen in a wireless driver, and
this is the only change which might have been responsible.

SQUASH: bcm2835-sdhost: Only claim one DMA channel

With both MMC controllers enabled there are few DMA channels left. The
bcm2835-sdhost driver only uses DMA in one direction at a time, so it
doesn't need to claim two channels.

See: raspberrypi/linux#1327

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: Workaround for "slow" sectors

Some cards have been seen to cause timeouts after certain sectors are
read. This workaround enforces a minimum delay between the stop after
reading one of those sectors and a subsequent data command.

Using CMD23 (SET_BLOCK_COUNT) avoids this problem, so good cards will
not be penalised by this workaround.

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: Firmware manages the clock divisor

The bcm2835-sdhost driver hands control of the CDIV clock divisor
register to matching firmware, allowing it to adjust to a changing
core clock. This removes the need to use the performance governor or
to enable io_is_busy on the on-demand governor in order to get the
best SD performance.

N.B. As SD clocks must be an integer divisor of the core clock, it is
possible that the SD clock for "turbo" mode can be different (even
lower) than "normal" mode.

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: Reset the clock in task context

Since reprogramming the clock can now involve a round-trip to the
firmware it must not be done at atomic context, and a tasklet
is not a task.

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: Don't exit cmd wait loop on error

The FAIL flag can be set in the CMD register before command processing
is complete, leading to spurious "failed to complete" errors. This has
the effect of promoting harmless CRC7 errors during CMD1 processing
into errors that can delay and even prevent booting.

Also:
1) Convert the last KERN_ERROR message in the register dumping to
   KERN_INFO.
2) Remove an unnecessary reset call from  bcm2835_sdhost_add_host.

See: raspberrypi/linux#1492

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: mmc_card_blockaddr fix

Get the definition of mmc_card_blockaddr from drivers/mmc/core/card.h.

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: New timer API

mmc: bcm2835-sdhost: Support underclocking

Support underclocking of the SD bus in two ways:
1. using the max-frequency DT property (which currently has no DT
   parameter), and
2. using the exiting sd_overclock parameter.

The two methods differ slightly - in the former the MMC subsystem is
aware of the underclocking, while in the latter it isn't - but the
end results should be the same.

See: raspberrypi/linux#2350

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

mmc: bcm2835-sdhost: Add include

highmem.h (needed for kmap_atomic) is pulled in by one of the other
include files, but only with some CONFIG settings. Make the inclusion
explicit to cater for cases where the CONFIG setting is absent.

See: raspberrypi/linux#2366

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

mmc/bcm2835-sdhost: Recover from MMC_SEND_EXT_CSD

If the user issues an "mmc extcsd read", the SD controller receives
what it thinks is a SEND_IF_COND command with an unexpected data block.
The resulting operations leave the FSM stuck in READWAIT, a state which
persists until the MMC framework resets the controller, by which point
the root filesystem is likely to have been unmounted.

A less heavyweight solution is to detect the condition and nudge the
FSM by asserting the (self-clearing) FORCE_DATA_MODE bit.

N.B. This workaround was essentially discovered by accident and without
a full understanding the inner workings of the controller, so it is
fortunate that the "fix" only modifies error paths.

See: raspberrypi/linux#2728

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

mmc: bcm2835-sdhost: Fix warnings on arm64

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: Allow for sg entries that cross pages

The dma_complete handling code calculates a virtual address for a page
then adds an offset, but if the offset is more than a page and HIGHMEM
is in use then the summed address could be in an unmapped (or just
incorrect) page.

The upstream SDHOST driver allows for this possibility - copy the code
that does so.

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: Fix DMA channel leak on error/remove

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

mmc: bcm2835-sdhost: Support 64-bit physical addresses

Signed-off-by: Phil Elwell <phil@raspberrypi.org>

bcm2835-sdhost: Replace obsolete struct timeval

struct timeval has been retired due to the impending linux 32-bit tv_sec
rollover (only 18 years to go) - timespec64 is the obvious replacement.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>

mmc: sdhost: Pass DT pointer to rpi_firmware_get

Using the rpi_firmware API as intended allows proper reference counting
of the firmware device and means we can remove a downstream patch to
the firmware driver.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
  • Loading branch information
Phil Elwell authored and popcornmix committed Mar 21, 2022
1 parent 07021b7 commit b4327d1
Show file tree
Hide file tree
Showing 3 changed files with 2,218 additions and 0 deletions.
10 changes: 10 additions & 0 deletions drivers/mmc/host/Kconfig
Expand Up @@ -34,6 +34,16 @@ config MMC_BCM2835_PIO_DMA_BARRIER

If unsure, say 2 here.

config MMC_BCM2835_SDHOST
tristate "Support for the SDHost controller on BCM2708/9"
depends on ARCH_BCM2835
help
This selects the SDHost controller on BCM2835/6.

If you have a controller with this interface, say Y or M here.

If unsure, say N.

config MMC_DEBUG
bool "MMC host drivers debugging"
depends on MMC != n
Expand Down
1 change: 1 addition & 0 deletions drivers/mmc/host/Makefile
Expand Up @@ -23,6 +23,7 @@ obj-$(CONFIG_MMC_SDHCI_MILBEAUT) += sdhci-milbeaut.o
obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o
obj-$(CONFIG_MMC_SDHCI_AM654) += sdhci_am654.o
obj-$(CONFIG_MMC_BCM2835_MMC) += bcm2835-mmc.o
obj-$(CONFIG_MMC_BCM2835_SDHOST) += bcm2835-sdhost.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
obj-$(CONFIG_MMC_ALCOR) += alcor.o
Expand Down

0 comments on commit b4327d1

Please sign in to comment.