Skip to content

Commit

Permalink
MMC: added alternative MMC driver
Browse files Browse the repository at this point in the history
mmc: Disable CMD23 transfers on all cards

Pending wire-level investigation of these types of transfers
and associated errors on bcm2835-mmc, disable for now. Fallback of
CMD18/CMD25 transfers will be used automatically by the MMC layer.

Reported/Tested-by: Gellert Weisz <gellert@raspberrypi.org>

mmc: bcm2835-mmc: enable DT support for all architectures

Both ARCH_BCM2835 and ARCH_BCM270x are built with OF now.
Enable Device Tree support for all architectures.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>

mmc: bcm2835-mmc: fix probe error handling

Probe error handling is broken in several places.
Simplify error handling by using device managed functions.
Replace pr_{err,info} with dev_{err,info}.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>

bcm2835-mmc: Add locks when accessing sdhost registers

bcm2835-mmc: Add range of debug options for slowing things down

bcm2835-mmc: Add option to disable some delays

bcm2835-mmc: Add option to disable MMC_QUIRK_BLK_NO_CMD23

bcm2835-mmc: Default to disabling MMC_QUIRK_BLK_NO_CMD23

bcm2835-mmc: 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 mmc interface is restricted to EVEN integer divisions of
250MHz, and the highest sensible option is 63 (250/4 = 62.5), the
next being 125 (250/2) which is much too high.

Use at your own risk.

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

Also only warn once for each overclock setting.

mmc: bcm2835-mmc: Make available on ARCH_BCM2835

Make the bcm2835-mmc driver available for use on ARCH_BCM2835.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>

BCM270x_DT: add bcm2835-mmc entry

Add Device Tree entry for bcm2835-mmc.
In non-DT mode, don't add the device in the board file.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>

bcm2835-mmc: Don't overwrite MMC capabilities from DT

bcm2835-mmc: Don't override bus width capabilities from devicetree

Take out the force setting of the MMC_CAP_4_BIT_DATA host capability
so that the result read from devicetree via mmc_of_parse() is
preserved.

bcm2835-mmc: Only claim one DMA channel

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

See: #1327

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

bcm2835-mmc: New timer API

mmc: bcm2835-mmc: Support underclocking

Support underclocking of the SD bus using the max-frequency DT property
(which currently has no DT parameter). The sd_overclock parameter
already provides another way to achieve the same thing which should be
equivalent in end result, but it is a bug not to support max-frequency
as well.

See: #2350

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

mmc/bcm2835: 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: #2728

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

bcm2835-mmc: Fix DMA channel leak

The BCM2835 MMC host driver requests a DMA channel on probe but neglects
to release the channel in the probe error path and on driver unbind.

I'm seeing this happen on every boot of the Compute Module 3: On first
driver probe, DMA channel 2 is allocated and then leaked with a "could
not get clk, deferring probe" message. On second driver probe, channel 4
is allocated.

Fix it.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Cc: Frank Pavlic <f.pavlic@kunbus.de>

bcm2835-mmc: Fix struct mmc_host leak on probe

The BCM2835 MMC host driver requests the bus address of the host's
register map on probe.  If that fails, the driver leaks the struct
mmc_host allocated earlier.

Fix it.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Cc: Frank Pavlic <f.pavlic@kunbus.de>

bcm2835-mmc: Fix duplicate free_irq() on remove

The BCM2835 MMC host driver requests its interrupt as a device-managed
resource, so the interrupt is automatically freed after the driver is
unbound.

However on driver unbind, bcm2835_mmc_remove() frees the interrupt
explicitly to avoid invocation of the interrupt handler after driver
structures have been torn down.

The interrupt is thus freed twice, leading to a WARN splat in
__free_irq().  Fix by not requesting the interrupt as a device-managed
resource.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Cc: Frank Pavlic <f.pavlic@kunbus.de>

bcm2835-mmc: Handle mmc_add_host() errors

The BCM2835 MMC host driver calls mmc_add_host() but doesn't check its
return value.  Errors occurring in that function are therefore not
handled.  Fix it.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Cc: Frank Pavlic <f.pavlic@kunbus.de>

bcm2835-mmc: Deduplicate reset of driver data on remove

The BCM2835 MMC host driver sets the device's driver data pointer to
NULL on ->remove() even though the driver core subsequently does the
same in __device_release_driver().  Drop the duplicate assignment.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Cc: Frank Pavlic <f.pavlic@kunbus.de>

bcm2835_mmc: Remove vestigial threaded IRQ

With SDIO processing now managed by the MMC framework with a
workqueue, the bcm2835_mmc driver no longer needs a threaded
IRQ.

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

Add missing dma_unmap_sg calls to free relevant swiotlb bounce buffers.
This prevents DMA leaks.

Signed-off-by: Yaroslav Rosomakho <yaroslavros@gmail.com>

Limit max_req_size under arm64 (or any other platform that uses swiotlb) to prevent potential buffer overflow due to bouncing.

Signed-off-by: Yaroslav Rosomakho <yaroslavros@gmail.com>

mmc: sdhci: Silence MMC warnings

When the MMC isn't plugged in, the driver will spam the console which is
pretty annoying when using NFS.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>

mmc: sdhci-iproc: Fix vmmc regulators on iProc

The Linux support for controlling card power via regulators appears to
be contentious. I would argue that the default behaviour is contrary to
the SDHCI spec - turning off the power writes a reserved value to the
SD Bus Voltage Select field of the Power Control Register, which
seems to kill the Arasan/iProc controller - but fortunately there is a
hook in sdhci_ops to override the behaviour. Borrow the implementation
from sdhci_arasan_set_power.

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

bcm2835-mmc: uninitialized_var is no more

Revert "mmc: sdhci-iproc: Fix vmmc regulators on iProc"

This reverts commit aed1939.

Commit 6c92ae1 ("mmc: sdhci: Introduce sdhci_set_power_and_bus_voltage()")
introduced a generic helper that does the same thing so use that instead in
the following commit.

Signed-off-by: Juerg Haefliger <juergh@canonical.com>

mmc: sdhci-iproc: Fix vmmc regulators (pre-bcm2711)

The Linux support for controlling card power via regulators appears to
be contentious. I would argue that the default behaviour is contrary to
the SDHCI spec - turning off the power writes a reserved value to the
SD Bus Voltage Select field of the Power Control Register, which
seems to kill the Arasan/iProc controller - but fortunately there is a
hook in sdhci_ops to override the behaviour.

Signed-off-by: Juerg Haefliger <juergh@canonical.com>
Signed-off-by: Phil Elwell <phil@raspberrypi.com>

bcm2835-mmc: Honor return value of mmc_of_parse()

bcm2835_mmc_probe() ignores errors returned by mmc_of_parse() and in
particular ignores -EPROBE_DEFER, which may be returned if the power
sequencing driver configured in the devicetree is compiled as a module.

The user-visible result is that access to the SDIO device fails because
its power sequencing requirements have not been observed.  Fix it.

Signed-off-by: Lukas Wunner <lukas@wunner.de>

bcm2835-mmc: Use phys addresses for slave DMA config

Contrary to what struct snd_dmaengine_dai_dma_data suggests, the
configuration of addresses of DMA slave interfaces should be done in
CPU physical addresses.

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
  • Loading branch information
weiszg authored and popcornmix committed Apr 18, 2024
1 parent 96b0d70 commit 67e5fa5
Show file tree
Hide file tree
Showing 9 changed files with 1,637 additions and 5 deletions.
31 changes: 30 additions & 1 deletion drivers/mmc/core/block.c
Expand Up @@ -171,6 +171,13 @@ static DEFINE_MUTEX(open_lock);
module_param(perdev_minors, int, 0444);
MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");

/*
* Allow quirks to be overridden for the current card
*/
static char *card_quirks;
module_param(card_quirks, charp, 0644);
MODULE_PARM_DESC(card_quirks, "Force the use of the indicated quirks (a bitfield)");

static inline int mmc_blk_part_switch(struct mmc_card *card,
unsigned int part_type);
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
Expand Down Expand Up @@ -3008,14 +3015,25 @@ static int mmc_blk_probe(struct mmc_card *card)
{
struct mmc_blk_data *md;
int ret = 0;
char quirk_str[24];
char cap_str[10];

/*
* Check that the card supports the command class(es) we need.
*/
if (!(card->csd.cmdclass & CCC_BLOCK_READ))
return -ENODEV;

mmc_fixup_device(card, mmc_blk_fixups);
if (card_quirks) {
unsigned long quirks;
if (kstrtoul(card_quirks, 0, &quirks) == 0)
card->quirks = (unsigned int)quirks;
else
pr_err("mmc_block: Invalid card_quirks parameter '%s'\n",
card_quirks);
}
else
mmc_fixup_device(card, mmc_blk_fixups);

card->complete_wq = alloc_workqueue("mmc_complete",
WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
Expand All @@ -3030,6 +3048,17 @@ static int mmc_blk_probe(struct mmc_card *card)
goto out_free;
}

string_get_size((u64)get_capacity(md->disk), 512, STRING_UNITS_2,
cap_str, sizeof(cap_str));
if (card->quirks)
snprintf(quirk_str, sizeof(quirk_str),
" (quirks 0x%08x)", card->quirks);
else
quirk_str[0] = '\0';
pr_info("%s: %s %s %s%s%s\n",
md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
cap_str, md->read_only ? " (ro)" : "", quirk_str);

ret = mmc_blk_alloc_parts(card, md);
if (ret)
goto out;
Expand Down
3 changes: 2 additions & 1 deletion drivers/mmc/core/core.c
Expand Up @@ -1818,7 +1818,8 @@ EXPORT_SYMBOL(mmc_erase);

int mmc_can_erase(struct mmc_card *card)
{
if (card->csd.cmdclass & CCC_ERASE && card->erase_size)
if (card->csd.cmdclass & CCC_ERASE && card->erase_size &&
!(card->quirks & MMC_QUIRK_ERASE_BROKEN))
return 1;
return 0;
}
Expand Down
8 changes: 8 additions & 0 deletions drivers/mmc/core/quirks.h
Expand Up @@ -130,6 +130,14 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd,
MMC_QUIRK_BROKEN_SD_DISCARD),

/*
* On some Kingston SD cards, multiple erases of less than 64
* sectors can cause corruption.
*/
MMC_FIXUP("SD16G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),
MMC_FIXUP("SD32G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),
MMC_FIXUP("SD64G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),

END_FIXUP
};

Expand Down
29 changes: 29 additions & 0 deletions drivers/mmc/host/Kconfig
Expand Up @@ -5,6 +5,35 @@

comment "MMC/SD/SDIO Host Controller Drivers"

config MMC_BCM2835_MMC
tristate "MMC support on BCM2835"
depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835
help
This selects the MMC Interface on BCM2835.

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

If unsure, say N.

config MMC_BCM2835_DMA
bool "DMA support on BCM2835 Arasan controller"
depends on MMC_BCM2835_MMC
help
Enable DMA support on the Arasan SDHCI controller in Broadcom 2708
based chips.

If unsure, say N.

config MMC_BCM2835_PIO_DMA_BARRIER
int "Block count limit for PIO transfers"
depends on MMC_BCM2835_MMC && MMC_BCM2835_DMA
range 0 256
default 2
help
The inclusive limit in bytes under which PIO will be used instead of DMA

If unsure, say 2 here.

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 @@ -22,6 +22,7 @@ obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o
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_WBSD) += wbsd.o
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
obj-$(CONFIG_MMC_ALCOR) += alcor.o
Expand Down

0 comments on commit 67e5fa5

Please sign in to comment.