* [PATCH 0/2] mmc: litex_mmc: Respect the bus width request from the core.
@ 2026-06-29 7:25 Inochi Amaoto
2026-06-29 7:25 ` [PATCH 1/2] mmc: litex_mmc: Set width from linux request Inochi Amaoto
2026-06-29 7:25 ` [PATCH 2/2] mmc: litex_mmc: Remove unused logic for the fixed bus width Inochi Amaoto
0 siblings, 2 replies; 3+ messages in thread
From: Inochi Amaoto @ 2026-06-29 7:25 UTC (permalink / raw)
To: Ulf Hansson, Karol Gugala, Mateusz Holenko, Gabriel Somlo,
Joel Stanley
Cc: Inochi Amaoto, linux-mmc, linux-kernel, Yixun Lan, Longbin Li
The litex_mmc only forces to use a 4-bits bus width for data transfer,
however, it does support setting bus width. Use this interface to simplify
the litex_mmc driver.
Inochi Amaoto (2):
mmc: litex_mmc: Set width from linux request
mmc: litex_mmc: Remove unused logic for the fixed bus width
drivers/mmc/host/litex_mmc.c | 131 +++++++++--------------------------
1 file changed, 32 insertions(+), 99 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] mmc: litex_mmc: Set width from linux request
2026-06-29 7:25 [PATCH 0/2] mmc: litex_mmc: Respect the bus width request from the core Inochi Amaoto
@ 2026-06-29 7:25 ` Inochi Amaoto
2026-06-29 7:25 ` [PATCH 2/2] mmc: litex_mmc: Remove unused logic for the fixed bus width Inochi Amaoto
1 sibling, 0 replies; 3+ messages in thread
From: Inochi Amaoto @ 2026-06-29 7:25 UTC (permalink / raw)
To: Ulf Hansson, Karol Gugala, Mateusz Holenko, Gabriel Somlo,
Joel Stanley
Cc: Inochi Amaoto, linux-mmc, linux-kernel, Yixun Lan, Longbin Li
Previously, the litex_mmc driver force the 4 bits bus width.
This means that the gateware with 1 bit bus width is not fit.
However, litesdcard does support setting bus width, which
make the 1 bit bus width gateware possible to be used.
Add logic for setting bus width in the set_ios() function.
Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
---
drivers/mmc/host/litex_mmc.c | 36 +++++++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/host/litex_mmc.c b/drivers/mmc/host/litex_mmc.c
index 3655542ca998..affdff8621bf 100644
--- a/drivers/mmc/host/litex_mmc.c
+++ b/drivers/mmc/host/litex_mmc.c
@@ -29,6 +29,7 @@
#define LITEX_PHY_CLOCKERDIV 0x04
#define LITEX_PHY_INITIALIZE 0x08
#define LITEX_PHY_WRITESTATUS 0x0C
+#define LITEX_PHY_SETTINGS 0x18
#define LITEX_CORE_CMDARG 0x00
#define LITEX_CORE_CMDCMD 0x04
#define LITEX_CORE_CMDSND 0x08
@@ -72,6 +73,10 @@
#define SD_INIT_DELAY_US 1000
#define SD_INIT_CLK_HZ 400000
+#define SD_PHY_SPEED_1X 0
+#define SD_PHY_SPEED_4X 1
+#define SD_PHY_SPEED_8X 2
+
#define SDIRQ_CARD_DETECT 1
#define SDIRQ_SD_TO_MEM_DONE 2
#define SDIRQ_MEM_TO_SD_DONE 4
@@ -96,6 +101,8 @@ struct litex_mmc_host {
unsigned int ref_clk;
unsigned int sd_clk;
+ u8 width;
+
u32 resp[4];
u16 rca;
@@ -451,6 +458,24 @@ static void litex_mmc_setclk(struct litex_mmc_host *host, unsigned int freq)
static void litex_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct litex_mmc_host *host = mmc_priv(mmc);
+ unsigned int bus_width = SD_PHY_SPEED_1X;
+
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_1:
+ bus_width = SD_PHY_SPEED_1X;
+ break;
+ case MMC_BUS_WIDTH_4:
+ bus_width = SD_PHY_SPEED_4X;
+ break;
+ case MMC_BUS_WIDTH_8:
+ bus_width = SD_PHY_SPEED_8X;
+ break;
+ }
+
+ if (host->width != ios->bus_width) {
+ litex_write8(host->sdphy + LITEX_PHY_SETTINGS, bus_width);
+ host->width = ios->bus_width;
+ }
/*
* The SD specification requires at least 74 idle clocks before CMD0.
@@ -463,13 +488,6 @@ static void litex_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
return;
}
- /*
- * NOTE: Ignore any ios->bus_width updates; they occur right after
- * the mmc core sends its own acmd6 bus-width change notification,
- * which is redundant since we snoop on the command flow and inject
- * an early acmd6 before the first data transfer command is sent!
- */
-
/* Update sd_clk */
if (ios->clock != host->sd_clk)
litex_mmc_setclk(host, ios->clock);
@@ -555,6 +573,7 @@ static int litex_mmc_probe(struct platform_device *pdev)
*/
host->is_bus_width_set = false;
host->app_cmd = false;
+ host->width = MMC_BUS_WIDTH_1;
/* LiteSDCard can support 64-bit DMA addressing */
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
@@ -587,6 +606,9 @@ static int litex_mmc_probe(struct platform_device *pdev)
litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0);
litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0);
+ /* Ensure the litex is at bus width x1 */
+ litex_write8(host->sdphy + LITEX_PHY_SETTINGS, SD_PHY_SPEED_1X);
+
init_completion(&host->cmd_done);
ret = litex_mmc_irq_init(pdev, host);
if (ret)
--
2.54.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] mmc: litex_mmc: Remove unused logic for the fixed bus width
2026-06-29 7:25 [PATCH 0/2] mmc: litex_mmc: Respect the bus width request from the core Inochi Amaoto
2026-06-29 7:25 ` [PATCH 1/2] mmc: litex_mmc: Set width from linux request Inochi Amaoto
@ 2026-06-29 7:25 ` Inochi Amaoto
1 sibling, 0 replies; 3+ messages in thread
From: Inochi Amaoto @ 2026-06-29 7:25 UTC (permalink / raw)
To: Ulf Hansson, Karol Gugala, Mateusz Holenko, Gabriel Somlo,
Joel Stanley
Cc: Inochi Amaoto, linux-mmc, linux-kernel, Yixun Lan, Longbin Li
As the set_ios() function in litex_mmc driver does support
setting bus width, it is not necessary to leave the logic
for fixed bus width. Clean up these unneeded code.
Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
---
drivers/mmc/host/litex_mmc.c | 95 ++----------------------------------
1 file changed, 3 insertions(+), 92 deletions(-)
diff --git a/drivers/mmc/host/litex_mmc.c b/drivers/mmc/host/litex_mmc.c
index affdff8621bf..1b5ac4b38f4c 100644
--- a/drivers/mmc/host/litex_mmc.c
+++ b/drivers/mmc/host/litex_mmc.c
@@ -104,10 +104,6 @@ struct litex_mmc_host {
u8 width;
u32 resp[4];
- u16 rca;
-
- bool is_bus_width_set;
- bool app_cmd;
};
static int litex_mmc_sdcard_wait_done(void __iomem *reg, struct device *dev)
@@ -172,11 +168,6 @@ static int litex_mmc_send_cmd(struct litex_mmc_host *host,
host->sdcore + LITEX_CORE_CMDRSP, 0x10);
}
- if (!host->app_cmd && cmd == SD_SEND_RELATIVE_ADDR)
- host->rca = (host->resp[3] >> 16);
-
- host->app_cmd = (cmd == MMC_APP_CMD);
-
if (transfer == SD_CTL_DATA_XFER_NONE)
return ret; /* OK from prior litex_mmc_sdcard_wait_done() */
@@ -198,51 +189,6 @@ static int litex_mmc_send_cmd(struct litex_mmc_host *host,
return ret;
}
-static int litex_mmc_send_app_cmd(struct litex_mmc_host *host)
-{
- return litex_mmc_send_cmd(host, MMC_APP_CMD, host->rca << 16,
- SD_CTL_RESP_SHORT, SD_CTL_DATA_XFER_NONE);
-}
-
-static int litex_mmc_send_set_bus_w_cmd(struct litex_mmc_host *host, u32 width)
-{
- return litex_mmc_send_cmd(host, SD_APP_SET_BUS_WIDTH, width,
- SD_CTL_RESP_SHORT, SD_CTL_DATA_XFER_NONE);
-}
-
-static int litex_mmc_set_bus_width(struct litex_mmc_host *host)
-{
- bool app_cmd_sent;
- int ret;
-
- if (host->is_bus_width_set)
- return 0;
-
- /* Ensure 'app_cmd' precedes 'app_set_bus_width_cmd' */
- app_cmd_sent = host->app_cmd; /* was preceding command app_cmd? */
- if (!app_cmd_sent) {
- ret = litex_mmc_send_app_cmd(host);
- if (ret)
- return ret;
- }
-
- /* LiteSDCard only supports 4-bit bus width */
- ret = litex_mmc_send_set_bus_w_cmd(host, MMC_BUS_WIDTH_4);
- if (ret)
- return ret;
-
- /* Re-send 'app_cmd' if necessary */
- if (app_cmd_sent) {
- ret = litex_mmc_send_app_cmd(host);
- if (ret)
- return ret;
- }
-
- host->is_bus_width_set = true;
-
- return 0;
-}
-
static int litex_mmc_get_cd(struct mmc_host *mmc)
{
struct litex_mmc_host *host = mmc_priv(mmc);
@@ -255,9 +201,6 @@ static int litex_mmc_get_cd(struct mmc_host *mmc)
if (ret)
return ret;
- /* Ensure bus width will be set (again) upon card (re)insertion */
- host->is_bus_width_set = false;
-
return 0;
}
@@ -373,39 +316,19 @@ static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
litex_mmc_response_len(sbc),
SD_CTL_DATA_XFER_NONE);
if (sbc->error) {
- host->is_bus_width_set = false;
mmc_request_done(mmc, mrq);
return;
}
}
- if (data) {
- /*
- * LiteSDCard only supports 4-bit bus width; therefore, we MUST
- * inject a SET_BUS_WIDTH (acmd6) before the very first data
- * transfer, earlier than when the mmc subsystem would normally
- * get around to it!
- */
- cmd->error = litex_mmc_set_bus_width(host);
- if (cmd->error) {
- dev_err(dev, "Can't set bus width!\n");
- mmc_request_done(mmc, mrq);
- return;
- }
-
+ if (data)
litex_mmc_do_dma(host, data, &len, &direct, &transfer);
- }
do {
cmd->error = litex_mmc_send_cmd(host, cmd->opcode, cmd->arg,
response_len, transfer);
} while (cmd->error && retries-- > 0);
- if (cmd->error) {
- /* Card may be gone; don't assume bus width is still set */
- host->is_bus_width_set = false;
- }
-
if (response_len == SD_CTL_RESP_SHORT) {
/* Pull short response fields from appropriate host registers */
cmd->resp[0] = host->resp[3];
@@ -418,13 +341,10 @@ static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
}
/* Send stop-transmission command if required */
- if (stop && (cmd->error || !sbc)) {
+ if (stop && (cmd->error || !sbc))
stop->error = litex_mmc_send_cmd(host, stop->opcode, stop->arg,
litex_mmc_response_len(stop),
SD_CTL_DATA_XFER_NONE);
- if (stop->error)
- host->is_bus_width_set = false;
- }
if (data) {
dma_unmap_sg(dev, data->sg, data->sg_len,
@@ -565,14 +485,6 @@ static int litex_mmc_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(clk), "can't get clock\n");
host->ref_clk = clk_get_rate(clk);
host->sd_clk = 0;
-
- /*
- * LiteSDCard only supports 4-bit bus width; therefore, we MUST inject
- * a SET_BUS_WIDTH (acmd6) before the very first data transfer, earlier
- * than when the mmc subsystem would normally get around to it!
- */
- host->is_bus_width_set = false;
- host->app_cmd = false;
host->width = MMC_BUS_WIDTH_1;
/* LiteSDCard can support 64-bit DMA addressing */
@@ -633,9 +545,8 @@ static int litex_mmc_probe(struct platform_device *pdev)
if (ret)
return ret;
- /* Force 4-bit bus_width (only width supported by hardware) */
+ /* Only drop 8-bit bus_width support */
mmc->caps &= ~MMC_CAP_8_BIT_DATA;
- mmc->caps |= MMC_CAP_4_BIT_DATA;
/* Set default capabilities */
mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY |
--
2.54.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-06-29 7:25 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-29 7:25 [PATCH 0/2] mmc: litex_mmc: Respect the bus width request from the core Inochi Amaoto
2026-06-29 7:25 ` [PATCH 1/2] mmc: litex_mmc: Set width from linux request Inochi Amaoto
2026-06-29 7:25 ` [PATCH 2/2] mmc: litex_mmc: Remove unused logic for the fixed bus width Inochi Amaoto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox