From: Greg Malysa <greg.malysa@timesys.com>
To: u-boot@lists.denx.de, Peng Fan <peng.fan@nxp.com>,
Jaehoon Chung <jh80.chung@samsung.com>
Cc: Ian Roberts <ian.roberts@timesys.com>,
Nathan Barrett-Morrison <nathan.morrison@timesys.com>,
Greg Malysa <greg.malysa@timesys.com>,
Sean Anderson <sean.anderson@seco.com>,
Simon Glass <sjg@chromium.org>, Tom Rini <trini@konsulko.com>
Subject: [PATCH v2] mmc: sdhci: introduce adma_write_desc() hook to struct sdhci_ops
Date: Mon, 22 Apr 2024 15:00:02 -0400 [thread overview]
Message-ID: <20240422190035.25852-1-greg.malysa@timesys.com> (raw)
From: Ian Roberts <ian.roberts@timesys.com>
Add this hook so that it can be overridden with driver specific
implementations. We also let the original sdhci_adma_write_desc()
accept &desc so that the function can set its new value. Then export
the function so that it could be reused by driver's specific
implementations.
The above is a port of Linux kernel commit 54552e4948cbf
In addition, allow drivers to allocate their own ADMA descriptor
tables if additional space is required.
Finally, fix the assignment of adma_addr to fix compiler warning
on 64-bit platforms that still use 32-bit DMA addressing.
Co-developed-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
Signed-off-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
Co-developed-by: Greg Malysa <greg.malysa@timesys.com>
Signed-off-by: Greg Malysa <greg.malysa@timesys.com>
Signed-off-by: Ian Roberts <ian.roberts@timesys.com>
---
Changes in v2:
- Switch from #if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA) to #ifdef
CONFIG_MMC_SDHCI_ADMA_HELPERS, as CONFIG_IS_ENABLED() causes a build
failure during SPL builds when CONFIG_SPL_MMC is set.
- Passed CI before submitting this time
---
drivers/mmc/fsl_esdhc.c | 2 +-
drivers/mmc/sdhci-adma.c | 41 +++++++++++++++++++++++++++-------------
drivers/mmc/sdhci.c | 8 +++++---
include/sdhci.h | 12 ++++++++++--
4 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index d506666669..bd0671cc52 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -252,7 +252,7 @@ static void esdhc_setup_dma(struct fsl_esdhc_priv *priv, struct mmc_data *data)
priv->adma_desc_table) {
debug("Using ADMA2\n");
/* prefer ADMA2 if it is available */
- sdhci_prepare_adma_table(priv->adma_desc_table, data,
+ sdhci_prepare_adma_table(NULL, priv->adma_desc_table, data,
priv->dma_addr);
adma_addr = virt_to_phys(priv->adma_desc_table);
diff --git a/drivers/mmc/sdhci-adma.c b/drivers/mmc/sdhci-adma.c
index 8213223d3f..8c38448b6a 100644
--- a/drivers/mmc/sdhci-adma.c
+++ b/drivers/mmc/sdhci-adma.c
@@ -9,9 +9,10 @@
#include <malloc.h>
#include <asm/cache.h>
-static void sdhci_adma_desc(struct sdhci_adma_desc *desc,
- dma_addr_t addr, u16 len, bool end)
+void sdhci_adma_write_desc(struct sdhci_host *host, void **next_desc,
+ dma_addr_t addr, int len, bool end)
{
+ struct sdhci_adma_desc *desc = *next_desc;
u8 attr;
attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;
@@ -19,17 +20,30 @@ static void sdhci_adma_desc(struct sdhci_adma_desc *desc,
attr |= ADMA_DESC_ATTR_END;
desc->attr = attr;
- desc->len = len;
+ desc->len = len & 0xffff;
desc->reserved = 0;
desc->addr_lo = lower_32_bits(addr);
#ifdef CONFIG_DMA_ADDR_T_64BIT
desc->addr_hi = upper_32_bits(addr);
#endif
+
+ *next_desc += ADMA_DESC_LEN;
+}
+
+static inline void __sdhci_adma_write_desc(struct sdhci_host *host,
+ void **desc, dma_addr_t addr,
+ int len, bool end)
+{
+ if (host && host->ops && host->ops->adma_write_desc)
+ host->ops->adma_write_desc(host, desc, addr, len, end);
+ else
+ sdhci_adma_write_desc(host, desc, addr, len, end);
}
/**
* sdhci_prepare_adma_table() - Populate the ADMA table
*
+ * @host: Pointer to the sdhci_host
* @table: Pointer to the ADMA table
* @data: Pointer to MMC data
* @addr: DMA address to write to or read from
@@ -39,25 +53,26 @@ static void sdhci_adma_desc(struct sdhci_adma_desc *desc,
* Please note, that the table size depends on CONFIG_SYS_MMC_MAX_BLK_COUNT and
* we don't have to check for overflow.
*/
-void sdhci_prepare_adma_table(struct sdhci_adma_desc *table,
- struct mmc_data *data, dma_addr_t addr)
+void sdhci_prepare_adma_table(struct sdhci_host *host,
+ struct sdhci_adma_desc *table,
+ struct mmc_data *data, dma_addr_t start_addr)
{
+ dma_addr_t addr = start_addr;
uint trans_bytes = data->blocksize * data->blocks;
- uint desc_count = DIV_ROUND_UP(trans_bytes, ADMA_MAX_LEN);
- struct sdhci_adma_desc *desc = table;
- int i = desc_count;
+ void *next_desc = table;
+ int i = DIV_ROUND_UP(trans_bytes, ADMA_MAX_LEN);
while (--i) {
- sdhci_adma_desc(desc, addr, ADMA_MAX_LEN, false);
+ __sdhci_adma_write_desc(host, &next_desc, addr,
+ ADMA_MAX_LEN, false);
addr += ADMA_MAX_LEN;
trans_bytes -= ADMA_MAX_LEN;
- desc++;
}
- sdhci_adma_desc(desc, addr, trans_bytes, true);
+ __sdhci_adma_write_desc(host, &next_desc, addr, trans_bytes, true);
- flush_cache((dma_addr_t)table,
- ROUND(desc_count * sizeof(struct sdhci_adma_desc),
+ flush_cache((phys_addr_t)table,
+ ROUND(next_desc - (void *)table,
ARCH_DMA_MINALIGN));
}
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 0178ed8a11..65090348ae 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -111,7 +111,7 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
}
#if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
else if (host->flags & (USE_ADMA | USE_ADMA64)) {
- sdhci_prepare_adma_table(host->adma_desc_table, data,
+ sdhci_prepare_adma_table(host, host->adma_desc_table, data,
host->start_addr);
sdhci_writel(host, lower_32_bits(host->adma_addr),
@@ -897,8 +897,10 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
__func__);
return -EINVAL;
}
- host->adma_desc_table = sdhci_adma_init();
- host->adma_addr = (dma_addr_t)host->adma_desc_table;
+ if (!host->adma_desc_table) {
+ host->adma_desc_table = sdhci_adma_init();
+ host->adma_addr = virt_to_phys(host->adma_desc_table);
+ }
#ifdef CONFIG_DMA_ADDR_T_64BIT
host->flags |= USE_ADMA64;
diff --git a/include/sdhci.h b/include/sdhci.h
index a1b74e3bd7..d73a725609 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -291,6 +291,11 @@ struct sdhci_ops {
* Return: 0 if successful, -ve on error
*/
int (*set_enhanced_strobe)(struct sdhci_host *host);
+
+#ifdef CONFIG_MMC_SDHCI_ADMA_HELPERS
+ void (*adma_write_desc)(struct sdhci_host *host, void **desc,
+ dma_addr_t addr, int len, bool end);
+#endif
};
#define ADMA_MAX_LEN 65532
@@ -526,8 +531,11 @@ extern const struct dm_mmc_ops sdhci_ops;
#else
#endif
+void sdhci_adma_write_desc(struct sdhci_host *host, void **next_desc,
+ dma_addr_t addr, int len, bool end);
struct sdhci_adma_desc *sdhci_adma_init(void);
-void sdhci_prepare_adma_table(struct sdhci_adma_desc *table,
- struct mmc_data *data, dma_addr_t addr);
+void sdhci_prepare_adma_table(struct sdhci_host *host,
+ struct sdhci_adma_desc *table,
+ struct mmc_data *data, dma_addr_t start_addr);
#endif /* __SDHCI_HW_H */
--
2.43.2
next reply other threads:[~2024-04-22 19:01 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-22 19:00 Greg Malysa [this message]
2024-05-01 15:43 ` [PATCH v2] mmc: sdhci: introduce adma_write_desc() hook to struct sdhci_ops Sverdlin, Alexander
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240422190035.25852-1-greg.malysa@timesys.com \
--to=greg.malysa@timesys.com \
--cc=ian.roberts@timesys.com \
--cc=jh80.chung@samsung.com \
--cc=nathan.morrison@timesys.com \
--cc=peng.fan@nxp.com \
--cc=sean.anderson@seco.com \
--cc=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).