aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/renesas-sdhi.c46
-rw-r--r--drivers/mmc/tmio-common.h1
2 files changed, 37 insertions, 10 deletions
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 231a78178cf..88a7160b0a0 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -692,28 +692,26 @@ static int renesas_sdhi_wait_dat0(struct udevice *dev, int state,
#define RENESAS_SDHI_DMA_ALIGNMENT 128
-static int renesas_sdhi_addr_aligned(struct bounce_buffer *state)
+static int renesas_sdhi_addr_aligned_gen(uintptr_t ubuf,
+ size_t len, size_t len_aligned)
{
- uintptr_t ubuf = (uintptr_t)state->user_buffer;
-
/* Check if start is aligned */
if (!IS_ALIGNED(ubuf, RENESAS_SDHI_DMA_ALIGNMENT)) {
- debug("Unaligned buffer address %p\n", state->user_buffer);
+ debug("Unaligned buffer address %lx\n", ubuf);
return 0;
}
/* Check if length is aligned */
- if (state->len != state->len_aligned) {
- debug("Unaligned buffer length %zu\n", state->len);
+ if (len != len_aligned) {
+ debug("Unaligned buffer length %zu\n", len);
return 0;
}
#ifdef CONFIG_PHYS_64BIT
/* Check if below 32bit boundary */
- if ((ubuf >> 32) || (ubuf + state->len_aligned) >> 32) {
- debug("Buffer above 32bit boundary %p-%p\n",
- state->user_buffer,
- state->user_buffer + state->len_aligned);
+ if ((ubuf >> 32) || (ubuf + len_aligned) >> 32) {
+ debug("Buffer above 32bit boundary %lx-%lx\n",
+ ubuf, ubuf + len_aligned);
return 0;
}
#endif
@@ -722,6 +720,14 @@ static int renesas_sdhi_addr_aligned(struct bounce_buffer *state)
return 1;
}
+static int renesas_sdhi_addr_aligned(struct bounce_buffer *state)
+{
+ uintptr_t ubuf = (uintptr_t)state->user_buffer;
+
+ return renesas_sdhi_addr_aligned_gen(ubuf, state->len,
+ state->len_aligned);
+}
+
static int renesas_sdhi_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
{
@@ -789,6 +795,24 @@ static int renesas_sdhi_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
return 0;
}
+int renesas_sdhi_get_b_max(struct udevice *dev, void *dst, lbaint_t blkcnt)
+{
+ struct tmio_sd_priv *priv = dev_get_priv(dev);
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct mmc *mmc = upriv->mmc;
+ size_t len = blkcnt * mmc->read_bl_len;
+ size_t len_align = roundup(len, RENESAS_SDHI_DMA_ALIGNMENT);
+
+ if (renesas_sdhi_addr_aligned_gen((uintptr_t)dst, len, len_align)) {
+ if (priv->quirks & TMIO_SD_CAP_16BIT)
+ return U16_MAX;
+ else
+ return U32_MAX;
+ } else {
+ return (CONFIG_SYS_MALLOC_LEN / 4) / mmc->read_bl_len;
+ }
+}
+
static const struct dm_mmc_ops renesas_sdhi_ops = {
.send_cmd = renesas_sdhi_send_cmd,
.set_ios = renesas_sdhi_set_ios,
@@ -801,6 +825,7 @@ static const struct dm_mmc_ops renesas_sdhi_ops = {
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
.wait_dat0 = renesas_sdhi_wait_dat0,
#endif
+ .get_b_max = renesas_sdhi_get_b_max,
};
#define RENESAS_GEN2_QUIRKS TMIO_SD_CAP_RCAR_GEN2
@@ -966,6 +991,7 @@ static int renesas_sdhi_probe(struct udevice *dev)
return ret;
}
+ priv->quirks = quirks;
ret = tmio_sd_probe(dev, quirks);
renesas_sdhi_filter_caps(dev);
diff --git a/drivers/mmc/tmio-common.h b/drivers/mmc/tmio-common.h
index 047458849bd..2f671df4bc9 100644
--- a/drivers/mmc/tmio-common.h
+++ b/drivers/mmc/tmio-common.h
@@ -147,6 +147,7 @@ struct tmio_sd_priv {
u8 adjust_hs400_calibrate;
u8 hs400_bad_tap;
const u8 *adjust_hs400_calib_table;
+ u32 quirks;
#endif
ulong (*clk_get_rate)(struct tmio_sd_priv *);
};