summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-02-03 09:13:43 -0600
committerTom Rini <[email protected]>2026-02-03 12:46:30 -0600
commit71f2564b178f3986dc89cdaa4558f0caa74fd88c (patch)
tree72425510b485afed47d9c78e5fcd31c3c08151e2
parentb3d5e06b4b1062b2966ac7fadd90ebec74fa5cac (diff)
parentb4f0479e076014f403319fdce53c5c1ac278f8ae (diff)
Merge tag 'mmc-for-2026.04-rc2' of https://source.denx.de/u-boot/custodians/u-boot-mmc
- Add DMA support for mediatek mmc - Cleanup mmc cmd - Fix typos in mmc [trini: Fix "quoted string split across lines" checkpatch warning] Signed-off-by: Tom Rini <[email protected]>
-rw-r--r--cmd/mmc.c55
-rw-r--r--drivers/mmc/mmc.c6
-rw-r--r--drivers/mmc/mtk-sd.c519
3 files changed, 336 insertions, 244 deletions
diff --git a/cmd/mmc.c b/cmd/mmc.c
index 5340a58be8e..6cb1ef5dc23 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -16,6 +16,7 @@
#include <sparse_format.h>
#include <image-sparse.h>
#include <vsprintf.h>
+#include <linux/compiler_attributes.h>
#include <linux/ctype.h>
static int curr_device = -1;
@@ -556,37 +557,45 @@ static int do_mmc_part(struct cmd_tbl *cmdtp, int flag,
static int do_mmc_dev(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
- int dev, part = 0, ret;
+ enum bus_mode speed_mode = MMC_MODES_END;
+ int dev = curr_device, part = 0, ret;
+ char *endp;
struct mmc *mmc;
- if (argc == 1) {
- dev = curr_device;
- mmc = init_mmc_device(dev, true);
- } else if (argc == 2) {
- dev = (int)dectoul(argv[1], NULL);
- mmc = init_mmc_device(dev, true);
- } else if (argc == 3) {
- dev = (int)dectoul(argv[1], NULL);
- part = (int)dectoul(argv[2], NULL);
- if (part > PART_ACCESS_MASK) {
- printf("#part_num shouldn't be larger than %d\n",
- PART_ACCESS_MASK);
- return CMD_RET_FAILURE;
+ switch (argc) {
+ case 4:
+ speed_mode = (int)dectoul(argv[3], &endp);
+ if (*endp) {
+ printf("Invalid speed mode index '%s', did you specify a mode name?\n",
+ argv[3]);
+ return CMD_RET_USAGE;
}
- mmc = init_mmc_device(dev, true);
- } else if (argc == 4) {
- enum bus_mode speed_mode;
- dev = (int)dectoul(argv[1], NULL);
- part = (int)dectoul(argv[2], NULL);
- if (part > PART_ACCESS_MASK) {
+ fallthrough;
+ case 3:
+ part = (int)dectoul(argv[2], &endp);
+ if (*endp) {
+ printf("Invalid part number '%s'\n", argv[2]);
+ return CMD_RET_USAGE;
+ } else if (part > PART_ACCESS_MASK) {
printf("#part_num shouldn't be larger than %d\n",
PART_ACCESS_MASK);
return CMD_RET_FAILURE;
}
- speed_mode = (int)dectoul(argv[3], NULL);
+
+ fallthrough;
+ case 2:
+ dev = (int)dectoul(argv[1], &endp);
+ if (*endp) {
+ printf("Invalid device number '%s'\n", argv[1]);
+ return CMD_RET_USAGE;
+ }
+
+ fallthrough;
+ case 1:
mmc = __init_mmc_device(dev, true, speed_mode);
- } else {
+ break;
+ default:
return CMD_RET_USAGE;
}
@@ -597,7 +606,7 @@ static int do_mmc_dev(struct cmd_tbl *cmdtp, int flag,
printf("switch to partitions #%d, %s\n",
part, (!ret) ? "OK" : "ERROR");
if (ret)
- return 1;
+ return CMD_RET_FAILURE;
curr_device = dev;
if (mmc->part_config == MMCPART_NOAVAILABLE)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 7dadff27abe..c5705f4f215 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -889,7 +889,7 @@ static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
return ret;
/*
- * In cases when neiter allowed to poll by using CMD13 nor we are
+ * In cases when neither allowed to poll by using CMD13 nor we are
* capable of polling by using mmc_wait_dat0, then rely on waiting the
* stated timeout to be sufficient.
*/
@@ -1663,7 +1663,7 @@ static inline int bus_width(uint cap)
return 4;
if (cap == MMC_MODE_1BIT)
return 1;
- pr_warn("invalid bus witdh capability 0x%x\n", cap);
+ pr_warn("invalid bus width capability 0x%x\n", cap);
return 0;
}
@@ -2200,7 +2200,7 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
return 0;
if (!mmc->ext_csd) {
- pr_debug("No ext_csd found!\n"); /* this should enver happen */
+ pr_debug("No ext_csd found!\n"); /* this should never happen */
return -ENOTSUPP;
}
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
index 2bc700b0d05..4928a880038 100644
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -7,6 +7,7 @@
*/
#include <clk.h>
+#include <cpu_func.h>
#include <dm.h>
#include <mmc.h>
#include <errno.h>
@@ -14,8 +15,10 @@
#include <mapmem.h>
#include <stdbool.h>
#include <asm/gpio.h>
+#include <asm/types.h>
#include <dm/device_compat.h>
#include <dm/pinctrl.h>
+#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/iopoll.h>
@@ -23,15 +26,11 @@
/* MSDC_CFG */
#define MSDC_CFG_HS400_CK_MODE_EXT BIT(22)
-#define MSDC_CFG_CKMOD_EXT_M 0x300000
-#define MSDC_CFG_CKMOD_EXT_S 20
-#define MSDC_CFG_CKDIV_EXT_M 0xfff00
-#define MSDC_CFG_CKDIV_EXT_S 8
+#define MSDC_CFG_CKMOD_EXT GENMASK(21, 20)
+#define MSDC_CFG_CKDIV_EXT GENMASK(19, 8)
#define MSDC_CFG_HS400_CK_MODE BIT(18)
-#define MSDC_CFG_CKMOD_M 0x30000
-#define MSDC_CFG_CKMOD_S 16
-#define MSDC_CFG_CKDIV_M 0xff00
-#define MSDC_CFG_CKDIV_S 8
+#define MSDC_CFG_CKMOD GENMASK(17, 16)
+#define MSDC_CFG_CKDIV GENMASK(15, 8)
#define MSDC_CFG_CKSTB BIT(7)
#define MSDC_CFG_PIO BIT(3)
#define MSDC_CFG_RST BIT(2)
@@ -45,8 +44,7 @@
/* MSDC_PS */
#define MSDC_PS_DAT0 BIT(16)
-#define MSDC_PS_CDDBCE_M 0xf000
-#define MSDC_PS_CDDBCE_S 12
+#define MSDC_PS_CDDBCE GENMASK(15, 12)
#define MSDC_PS_CDSTS BIT(1)
#define MSDC_PS_CDEN BIT(0)
@@ -60,33 +58,27 @@
#define MSDC_INT_XFER_COMPL BIT(12)
#define MSDC_INT_DATTMO BIT(14)
#define MSDC_INT_DATCRCERR BIT(15)
+#define MSDC_INT_BDCSERR BIT(17)
+#define MSDC_INT_GPDCSERR BIT(18)
/* MSDC_FIFOCS */
#define MSDC_FIFOCS_CLR BIT(31)
-#define MSDC_FIFOCS_TXCNT_M 0xff0000
-#define MSDC_FIFOCS_TXCNT_S 16
-#define MSDC_FIFOCS_RXCNT_M 0xff
-#define MSDC_FIFOCS_RXCNT_S 0
+#define MSDC_FIFOCS_TXCNT GENMASK(23, 16)
+#define MSDC_FIFOCS_RXCNT GENMASK(7, 0)
/* #define SDC_CFG */
-#define SDC_CFG_DTOC_M 0xff000000
-#define SDC_CFG_DTOC_S 24
+#define SDC_CFG_DTOC GENMASK(31, 24)
#define SDC_CFG_SDIOIDE BIT(20)
#define SDC_CFG_SDIO BIT(19)
-#define SDC_CFG_BUSWIDTH_M 0x30000
-#define SDC_CFG_BUSWIDTH_S 16
+#define SDC_CFG_BUSWIDTH GENMASK(17, 16)
/* SDC_CMD */
-#define SDC_CMD_BLK_LEN_M 0xfff0000
-#define SDC_CMD_BLK_LEN_S 16
+#define SDC_CMD_BLK_LEN GENMASK(27, 16)
#define SDC_CMD_STOP BIT(14)
#define SDC_CMD_WR BIT(13)
-#define SDC_CMD_DTYPE_M 0x1800
-#define SDC_CMD_DTYPE_S 11
-#define SDC_CMD_RSPTYP_M 0x380
-#define SDC_CMD_RSPTYP_S 7
-#define SDC_CMD_CMD_M 0x3f
-#define SDC_CMD_CMD_S 0
+#define SDC_CMD_DTYPE GENMASK(12, 11)
+#define SDC_CMD_RSPTYP GENMASK(9, 7)
+#define SDC_CMD_CMD GENMASK(5, 0)
/* SDC_STS */
#define SDC_STS_CMDBUSY BIT(1)
@@ -95,103 +87,84 @@
/* SDC_ADV_CFG0 */
#define SDC_RX_ENHANCE_EN BIT(20)
+/* MSDC_DMA_CTRL */
+#define MSDC_DMA_CTRL_BURSTSZ GENMASK(14, 12)
+#define MSDC_DMA_CTRL_LASTBUF BIT(10)
+#define MSDC_DMA_CTRL_MODE BIT(8)
+#define MSDC_DMA_CTRL_STOP BIT(1)
+#define MSDC_DMA_CTRL_START BIT(0)
+
+/* DMA_CFG */
+#define MSDC_DMA_CFG_STS BIT(0)
+
/* PATCH_BIT0 */
-#define MSDC_INT_DAT_LATCH_CK_SEL_M 0x380
-#define MSDC_INT_DAT_LATCH_CK_SEL_S 7
+#define MSDC_INT_DAT_LATCH_CK_SEL GENMASK(9, 7)
/* PATCH_BIT1 */
-#define MSDC_PB1_STOP_DLY_M 0xf00
-#define MSDC_PB1_STOP_DLY_S 8
+#define MSDC_PB1_STOP_DLY GENMASK(11, 8)
/* PATCH_BIT2 */
-#define MSDC_PB2_CRCSTSENSEL_M 0xe0000000
-#define MSDC_PB2_CRCSTSENSEL_S 29
+#define MSDC_PB2_CRCSTSENSEL GENMASK(31, 29)
#define MSDC_PB2_CFGCRCSTS BIT(28)
-#define MSDC_PB2_RESPSTSENSEL_M 0x70000
-#define MSDC_PB2_RESPSTSENSEL_S 16
+#define MSDC_PB2_RESPSTSENSEL GENMASK(18, 16)
#define MSDC_PB2_CFGRESP BIT(15)
-#define MSDC_PB2_RESPWAIT_M 0x0c
-#define MSDC_PB2_RESPWAIT_S 2
+#define MSDC_PB2_RESPWAIT GENMASK(3, 2)
/* MSDC_PAD_CTRL0 */
-#define MSDC_PAD_CTRL0_CLKRDSEL_M 0xff000000
-#define MSDC_PAD_CTRL0_CLKRDSEL_S 24
+#define MSDC_PAD_CTRL0_CLKRDSEL GENMASK(31, 24)
#define MSDC_PAD_CTRL0_CLKTDSEL BIT(20)
#define MSDC_PAD_CTRL0_CLKIES BIT(19)
#define MSDC_PAD_CTRL0_CLKSMT BIT(18)
#define MSDC_PAD_CTRL0_CLKPU BIT(17)
#define MSDC_PAD_CTRL0_CLKPD BIT(16)
#define MSDC_PAD_CTRL0_CLKSR BIT(8)
-#define MSDC_PAD_CTRL0_CLKDRVP_M 0x70
-#define MSDC_PAD_CTRL0_CLKDRVP_S 4
-#define MSDC_PAD_CTRL0_CLKDRVN_M 0x7
-#define MSDC_PAD_CTRL0_CLKDRVN_S 0
+#define MSDC_PAD_CTRL0_CLKDRVP GENMASK(6, 4)
+#define MSDC_PAD_CTRL0_CLKDRVN GENMASK(2, 0)
/* MSDC_PAD_CTRL1 */
-#define MSDC_PAD_CTRL1_CMDRDSEL_M 0xff000000
-#define MSDC_PAD_CTRL1_CMDRDSEL_S 24
+#define MSDC_PAD_CTRL1_CMDRDSEL GENMASK(31, 24)
#define MSDC_PAD_CTRL1_CMDTDSEL BIT(20)
#define MSDC_PAD_CTRL1_CMDIES BIT(19)
#define MSDC_PAD_CTRL1_CMDSMT BIT(18)
#define MSDC_PAD_CTRL1_CMDPU BIT(17)
#define MSDC_PAD_CTRL1_CMDPD BIT(16)
#define MSDC_PAD_CTRL1_CMDSR BIT(8)
-#define MSDC_PAD_CTRL1_CMDDRVP_M 0x70
-#define MSDC_PAD_CTRL1_CMDDRVP_S 4
-#define MSDC_PAD_CTRL1_CMDDRVN_M 0x7
-#define MSDC_PAD_CTRL1_CMDDRVN_S 0
-
+#define MSDC_PAD_CTRL1_CMDDRVP GENMASK(6, 4)
+#define MSDC_PAD_CTRL1_CMDDRVN GENMASK(2, 0)
/* MSDC_PAD_CTRL2 */
-#define MSDC_PAD_CTRL2_DATRDSEL_M 0xff000000
-#define MSDC_PAD_CTRL2_DATRDSEL_S 24
+#define MSDC_PAD_CTRL2_DATRDSEL GENMASK(31, 24)
#define MSDC_PAD_CTRL2_DATTDSEL BIT(20)
#define MSDC_PAD_CTRL2_DATIES BIT(19)
#define MSDC_PAD_CTRL2_DATSMT BIT(18)
#define MSDC_PAD_CTRL2_DATPU BIT(17)
#define MSDC_PAD_CTRL2_DATPD BIT(16)
#define MSDC_PAD_CTRL2_DATSR BIT(8)
-#define MSDC_PAD_CTRL2_DATDRVP_M 0x70
-#define MSDC_PAD_CTRL2_DATDRVP_S 4
-#define MSDC_PAD_CTRL2_DATDRVN_M 0x7
-#define MSDC_PAD_CTRL2_DATDRVN_S 0
+#define MSDC_PAD_CTRL2_DATDRVP GENMASK(6, 4)
+#define MSDC_PAD_CTRL2_DATDRVN GENMASK(2, 0)
/* PAD_TUNE */
-#define MSDC_PAD_TUNE_CLKTDLY_M 0xf8000000
-#define MSDC_PAD_TUNE_CLKTDLY_S 27
-#define MSDC_PAD_TUNE_CMDRRDLY_M 0x7c00000
-#define MSDC_PAD_TUNE_CMDRRDLY_S 22
+#define MSDC_PAD_TUNE_CLKTDLY GENMASK(31, 27)
+#define MSDC_PAD_TUNE_CMDRRDLY GENMASK(26, 22)
#define MSDC_PAD_TUNE_CMD_SEL BIT(21)
-#define MSDC_PAD_TUNE_CMDRDLY_M 0x1f0000
-#define MSDC_PAD_TUNE_CMDRDLY_S 16
+#define MSDC_PAD_TUNE_CMDRDLY GENMASK(20, 16)
#define MSDC_PAD_TUNE_RXDLYSEL BIT(15)
#define MSDC_PAD_TUNE_RD_SEL BIT(13)
-#define MSDC_PAD_TUNE_DATRRDLY_M 0x1f00
-#define MSDC_PAD_TUNE_DATRRDLY_S 8
-#define MSDC_PAD_TUNE_DATWRDLY_M 0x1f
-#define MSDC_PAD_TUNE_DATWRDLY_S 0
+#define MSDC_PAD_TUNE_DATRRDLY GENMASK(12, 8)
+#define MSDC_PAD_TUNE_DATWRDLY GENMASK(4, 0)
-#define PAD_CMD_TUNE_RX_DLY3 0x3E
-#define PAD_CMD_TUNE_RX_DLY3_S 1
+#define PAD_CMD_TUNE_RX_DLY3 GENMASK(5, 1)
/* PAD_TUNE0 */
-#define MSDC_PAD_TUNE0_DAT0RDDLY_M 0x1f000000
-#define MSDC_PAD_TUNE0_DAT0RDDLY_S 24
-#define MSDC_PAD_TUNE0_DAT1RDDLY_M 0x1f0000
-#define MSDC_PAD_TUNE0_DAT1RDDLY_S 16
-#define MSDC_PAD_TUNE0_DAT2RDDLY_M 0x1f00
-#define MSDC_PAD_TUNE0_DAT2RDDLY_S 8
-#define MSDC_PAD_TUNE0_DAT3RDDLY_M 0x1f
-#define MSDC_PAD_TUNE0_DAT3RDDLY_S 0
+#define MSDC_PAD_TUNE0_DAT0RDDLY GENMASK(28, 24)
+#define MSDC_PAD_TUNE0_DAT1RDDLY GENMASK(20, 16)
+#define MSDC_PAD_TUNE0_DAT2RDDLY GENMASK(12, 8)
+#define MSDC_PAD_TUNE0_DAT3RDDLY GENMASK(4, 0)
/* PAD_TUNE1 */
-#define MSDC_PAD_TUNE1_DAT4RDDLY_M 0x1f000000
-#define MSDC_PAD_TUNE1_DAT4RDDLY_S 24
-#define MSDC_PAD_TUNE1_DAT5RDDLY_M 0x1f0000
-#define MSDC_PAD_TUNE1_DAT5RDDLY_S 16
-#define MSDC_PAD_TUNE1_DAT6RDDLY_M 0x1f00
-#define MSDC_PAD_TUNE1_DAT6RDDLY_S 8
-#define MSDC_PAD_TUNE1_DAT7RDDLY_M 0x1f
-#define MSDC_PAD_TUNE1_DAT7RDDLY_S 0
+#define MSDC_PAD_TUNE1_DAT4RDDLY GENMASK(28, 24)
+#define MSDC_PAD_TUNE1_DAT5RDDLY GENMASK(20, 16)
+#define MSDC_PAD_TUNE1_DAT6RDDLY GENMASK(12, 8)
+#define MSDC_PAD_TUNE1_DAT7RDDLY GENMASK(4, 0)
/* EMMC50_CFG0 */
#define EMMC50_CFG_CFCSTS_SEL BIT(4)
@@ -203,21 +176,19 @@
/* EMMC_TOP_CONTROL mask */
#define PAD_RXDLY_SEL BIT(0)
#define DELAY_EN BIT(1)
-#define PAD_DAT_RD_RXDLY2 (0x1f << 2)
-#define PAD_DAT_RD_RXDLY (0x1f << 7)
-#define PAD_DAT_RD_RXDLY_S 7
+#define PAD_DAT_RD_RXDLY2 GENMASK(6, 2)
+#define PAD_DAT_RD_RXDLY GENMASK(11, 7)
#define PAD_DAT_RD_RXDLY2_SEL BIT(12)
#define PAD_DAT_RD_RXDLY_SEL BIT(13)
#define DATA_K_VALUE_SEL BIT(14)
#define SDC_RX_ENH_EN BIT(15)
/* EMMC_TOP_CMD mask */
-#define PAD_CMD_RXDLY2 (0x1f << 0)
-#define PAD_CMD_RXDLY (0x1f << 5)
-#define PAD_CMD_RXDLY_S 5
+#define PAD_CMD_RXDLY2 GENMASK(4, 0)
+#define PAD_CMD_RXDLY GENMASK(9, 5)
#define PAD_CMD_RD_RXDLY2_SEL BIT(10)
#define PAD_CMD_RD_RXDLY_SEL BIT(11)
-#define PAD_CMD_TX_DLY (0x1f << 12)
+#define PAD_CMD_TX_DLY GENMASK(16, 12)
/* SDC_CFG_BUSWIDTH */
#define MSDC_BUS_1BITS 0x0
@@ -238,7 +209,8 @@
(MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO)
#define DATA_INTS_MASK \
- (MSDC_INT_XFER_COMPL | MSDC_INT_DATTMO | MSDC_INT_DATCRCERR)
+ (MSDC_INT_XFER_COMPL | MSDC_INT_DATTMO | MSDC_INT_DATCRCERR | \
+ MSDC_INT_BDCSERR | MSDC_INT_GPDCSERR)
/* Register offset */
struct mtk_sd_regs {
@@ -337,6 +309,7 @@ struct msdc_compatible {
bool builtin_pad_ctrl;
bool default_pad_dly;
bool use_internal_cd;
+ bool use_dma_mode;
};
struct msdc_delay_phase {
@@ -428,14 +401,12 @@ static void msdc_fifo_clr(struct msdc_host *host)
static u32 msdc_fifo_rx_bytes(struct msdc_host *host)
{
- return (readl(&host->base->msdc_fifocs) &
- MSDC_FIFOCS_RXCNT_M) >> MSDC_FIFOCS_RXCNT_S;
+ return FIELD_GET(MSDC_FIFOCS_RXCNT, readl(&host->base->msdc_fifocs));
}
static u32 msdc_fifo_tx_bytes(struct msdc_host *host)
{
- return (readl(&host->base->msdc_fifocs) &
- MSDC_FIFOCS_TXCNT_M) >> MSDC_FIFOCS_TXCNT_S;
+ return FIELD_GET(MSDC_FIFOCS_TXCNT, readl(&host->base->msdc_fifocs));
}
static u32 msdc_cmd_find_resp(struct msdc_host *host, struct mmc_cmd *cmd)
@@ -504,10 +475,10 @@ static u32 msdc_cmd_prepare_raw_cmd(struct msdc_host *host,
blocksize = data->blocksize;
}
- rawcmd |= ((opcode << SDC_CMD_CMD_S) & SDC_CMD_CMD_M) |
- ((resp_type << SDC_CMD_RSPTYP_S) & SDC_CMD_RSPTYP_M) |
- ((blocksize << SDC_CMD_BLK_LEN_S) & SDC_CMD_BLK_LEN_M) |
- ((dtype << SDC_CMD_DTYPE_S) & SDC_CMD_DTYPE_M);
+ rawcmd |= FIELD_PREP(SDC_CMD_CMD, opcode) |
+ FIELD_PREP(SDC_CMD_RSPTYP, resp_type) |
+ FIELD_PREP(SDC_CMD_BLK_LEN, blocksize) |
+ FIELD_PREP(SDC_CMD_DTYPE, dtype);
if (opcode == MMC_CMD_STOP_TRANSMISSION)
rawcmd |= SDC_CMD_STOP;
@@ -547,6 +518,9 @@ static int msdc_cmd_done(struct msdc_host *host, int events,
ret = -EIO;
}
+ /* Clear CMD interrupt */
+ writel(events & CMD_INTS_MASK, &host->base->msdc_int);
+
return ret;
}
@@ -590,16 +564,13 @@ static int msdc_start_command(struct msdc_host *host, struct mmc_cmd *cmd,
if (!msdc_cmd_is_ready(host))
return -EIO;
- if ((readl(&host->base->msdc_fifocs) &
- MSDC_FIFOCS_TXCNT_M) >> MSDC_FIFOCS_TXCNT_S ||
- (readl(&host->base->msdc_fifocs) &
- MSDC_FIFOCS_RXCNT_M) >> MSDC_FIFOCS_RXCNT_S) {
+ if (FIELD_GET(MSDC_FIFOCS_TXCNT, readl(&host->base->msdc_fifocs)) ||
+ FIELD_GET(MSDC_FIFOCS_RXCNT, readl(&host->base->msdc_fifocs))) {
pr_err("TX/RX FIFO non-empty before start of IO. Reset\n");
msdc_reset_hw(host);
+ msdc_fifo_clr(host);
}
- msdc_fifo_clr(host);
-
host->last_resp_type = cmd->resp_type;
host->last_data_write = 0;
@@ -608,8 +579,6 @@ static int msdc_start_command(struct msdc_host *host, struct mmc_cmd *cmd,
if (data)
blocks = data->blocks;
- writel(CMD_INTS_MASK, &host->base->msdc_int);
- writel(DATA_INTS_MASK, &host->base->msdc_int);
writel(blocks, &host->base->sdc_blk_num);
writel(cmd->cmdarg, &host->base->sdc_arg);
writel(rawcmd, &host->base->sdc_cmd);
@@ -704,7 +673,7 @@ static int msdc_pio_read(struct msdc_host *host, u8 *ptr, u32 size)
break;
}
-}
+ }
return ret;
}
@@ -751,14 +720,11 @@ static int msdc_pio_write(struct msdc_host *host, const u8 *ptr, u32 size)
return ret;
}
-static int msdc_start_data(struct msdc_host *host, struct mmc_data *data)
+static int msdc_pio_transfer(struct msdc_host *host, struct mmc_data *data)
{
u32 size;
int ret;
- if (data->flags == MMC_DATA_WRITE)
- host->last_data_write = 1;
-
size = data->blocks * data->blocksize;
if (data->flags == MMC_DATA_WRITE)
@@ -766,6 +732,124 @@ static int msdc_start_data(struct msdc_host *host, struct mmc_data *data)
else
ret = msdc_pio_read(host, (u8 *)data->dest, size);
+ return ret;
+}
+
+static dma_addr_t msdc_flush_membuf(const void *ptr, size_t size, enum dma_data_direction dir)
+{
+ dma_addr_t addr = (dma_addr_t)ptr;
+
+ if (dir == DMA_FROM_DEVICE)
+ invalidate_dcache_range(addr, addr + size);
+ else
+ flush_dcache_range(addr, addr + size);
+
+ return addr;
+}
+
+static void msdc_dma_start(struct msdc_host *host, dma_addr_t addr, u32 size)
+{
+ writel((u32)addr, &host->base->dma_sa);
+ clrsetbits_le32(&host->base->dma_ctrl, MSDC_DMA_CTRL_BURSTSZ,
+ FIELD_PREP(MSDC_DMA_CTRL_BURSTSZ, 6));
+
+ /* BASIC_DMA mode */
+ clrbits_le32(&host->base->dma_ctrl, MSDC_DMA_CTRL_MODE);
+
+ /* This is the last buffer */
+ setbits_le32(&host->base->dma_ctrl, MSDC_DMA_CTRL_LASTBUF);
+
+ /* Total transfer size */
+ writel(size, &host->base->dma_length);
+
+ /* Trigger DMA start */
+ setbits_le32(&host->base->dma_ctrl, MSDC_DMA_CTRL_START);
+}
+
+static void msdc_dma_stop(struct msdc_host *host)
+{
+ u32 reg;
+
+ setbits_le32(&host->base->dma_ctrl, MSDC_DMA_CTRL_STOP);
+ readl_poll_timeout(&host->base->dma_cfg, reg,
+ !(reg & MSDC_DMA_CFG_STS), 1000000);
+}
+
+static int msdc_dma_done(struct msdc_host *host, int events)
+{
+ int ret = 0;
+ u32 rawcmd, arg;
+
+ if (!(events & MSDC_INT_XFER_COMPL)) {
+ rawcmd = readl(&host->base->sdc_cmd);
+ arg = readl(&host->base->sdc_arg);
+
+ if (events & MSDC_INT_DATTMO)
+ ret = -ETIMEDOUT;
+ else if (events & (MSDC_INT_DATCRCERR | MSDC_INT_GPDCSERR | MSDC_INT_BDCSERR))
+ ret = -EIO;
+ else
+ ret = -EBADRQC;
+
+ pr_err("MSDC: start data failure with %d, INT(0x%x), rawcmd=0x%x, arg=0x%x\n",
+ ret, events, rawcmd, arg);
+ }
+
+ /* Clear DAT interrupt */
+ writel(events & DATA_INTS_MASK, &host->base->msdc_int);
+
+ return ret;
+}
+
+static int msdc_dma_transfer(struct msdc_host *host, struct mmc_data *data)
+{
+ u32 size, status;
+ int ret;
+ const void *buf;
+ enum dma_data_direction dir;
+ dma_addr_t dma_addr;
+
+ size = data->blocks * data->blocksize;
+ if (data->flags == MMC_DATA_WRITE) {
+ buf = data->src;
+ dir = DMA_TO_DEVICE;
+ } else {
+ buf = data->dest;
+ dir = DMA_FROM_DEVICE;
+ }
+
+ dma_addr = msdc_flush_membuf(buf, size, dir);
+ msdc_dma_start(host, dma_addr, size);
+
+ ret = readl_poll_timeout(&host->base->msdc_int, status,
+ status & DATA_INTS_MASK, 5000000);
+ if (ret)
+ status = MSDC_INT_DATTMO;
+
+ msdc_dma_stop(host);
+
+ /*
+ * Need invalidate the dcache again to avoid any
+ * cache-refill during the DMA operations (pre-fetching)
+ */
+ if (data->flags & MMC_DATA_READ)
+ invalidate_dcache_range(dma_addr, dma_addr + size);
+
+ return msdc_dma_done(host, status);
+}
+
+static int msdc_start_data(struct msdc_host *host, struct mmc_data *data)
+{
+ int ret;
+
+ if (data->flags == MMC_DATA_WRITE)
+ host->last_data_write = 1;
+
+ if (host->dev_comp->use_dma_mode)
+ ret = msdc_dma_transfer(host, data);
+ else
+ ret = msdc_pio_transfer(host, data);
+
if (ret) {
msdc_reset_hw(host);
msdc_fifo_clr(host);
@@ -814,37 +898,35 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
/* unit is 1048576 sclk cycles */
timeout = (timeout + (0x1 << shift) - 1) >> shift;
if (host->dev_comp->clk_div_bits == 8)
- mode = (readl(&host->base->msdc_cfg) &
- MSDC_CFG_CKMOD_M) >> MSDC_CFG_CKMOD_S;
+ mode = FIELD_GET(MSDC_CFG_CKMOD, readl(&host->base->msdc_cfg));
else
- mode = (readl(&host->base->msdc_cfg) &
- MSDC_CFG_CKMOD_EXT_M) >> MSDC_CFG_CKMOD_EXT_S;
+ mode = FIELD_GET(MSDC_CFG_CKMOD_EXT, readl(&host->base->msdc_cfg));
/* DDR mode will double the clk cycles for data timeout */
timeout = mode >= 2 ? timeout * 2 : timeout;
timeout = timeout > 1 ? timeout - 1 : 0;
timeout = timeout > 255 ? 255 : timeout;
}
- clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M,
- timeout << SDC_CFG_DTOC_S);
+ clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC,
+ FIELD_PREP(SDC_CFG_DTOC, timeout));
}
static void msdc_set_buswidth(struct msdc_host *host, u32 width)
{
u32 val = readl(&host->base->sdc_cfg);
- val &= ~SDC_CFG_BUSWIDTH_M;
+ val &= ~SDC_CFG_BUSWIDTH;
switch (width) {
default:
case 1:
- val |= (MSDC_BUS_1BITS << SDC_CFG_BUSWIDTH_S);
+ val |= FIELD_PREP(SDC_CFG_BUSWIDTH, MSDC_BUS_1BITS);
break;
case 4:
- val |= (MSDC_BUS_4BITS << SDC_CFG_BUSWIDTH_S);
+ val |= FIELD_PREP(SDC_CFG_BUSWIDTH, MSDC_BUS_4BITS);
break;
case 8:
- val |= (MSDC_BUS_8BITS << SDC_CFG_BUSWIDTH_S);
+ val |= FIELD_PREP(SDC_CFG_BUSWIDTH, MSDC_BUS_8BITS);
break;
}
@@ -918,18 +1000,17 @@ static void msdc_set_mclk(struct udevice *dev,
clrbits_le32(&host->base->msdc_cfg, MSDC_CFG_CKPDN);
if (host->dev_comp->clk_div_bits == 8) {
- div = min(div, (u32)(MSDC_CFG_CKDIV_M >> MSDC_CFG_CKDIV_S));
+ div = min(div, (u32)FIELD_MAX(MSDC_CFG_CKDIV));
clrsetbits_le32(&host->base->msdc_cfg,
- MSDC_CFG_CKMOD_M | MSDC_CFG_CKDIV_M,
- (mode << MSDC_CFG_CKMOD_S) |
- (div << MSDC_CFG_CKDIV_S));
+ MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
+ FIELD_PREP(MSDC_CFG_CKMOD, mode) |
+ FIELD_PREP(MSDC_CFG_CKDIV, div));
} else {
- div = min(div, (u32)(MSDC_CFG_CKDIV_EXT_M >>
- MSDC_CFG_CKDIV_EXT_S));
+ div = min(div, (u32)FIELD_MAX(MSDC_CFG_CKDIV_EXT));
clrsetbits_le32(&host->base->msdc_cfg,
- MSDC_CFG_CKMOD_EXT_M | MSDC_CFG_CKDIV_EXT_M,
- (mode << MSDC_CFG_CKMOD_EXT_S) |
- (div << MSDC_CFG_CKDIV_EXT_S));
+ MSDC_CFG_CKMOD_EXT | MSDC_CFG_CKDIV_EXT,
+ FIELD_PREP(MSDC_CFG_CKMOD_EXT, mode) |
+ FIELD_PREP(MSDC_CFG_CKDIV_EXT, div));
}
readl_poll_timeout(&host->base->msdc_cfg, reg,
@@ -1085,10 +1166,10 @@ static inline void msdc_set_cmd_delay(struct msdc_host *host, u32 value)
if (host->top_base)
clrsetbits_le32(&host->top_base->emmc_top_cmd, PAD_CMD_RXDLY,
- value << PAD_CMD_RXDLY_S);
+ FIELD_PREP(PAD_CMD_RXDLY, value));
else
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
- value << MSDC_PAD_TUNE_CMDRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRDLY, value));
}
static inline void msdc_set_data_delay(struct msdc_host *host, u32 value)
@@ -1100,10 +1181,10 @@ static inline void msdc_set_data_delay(struct msdc_host *host, u32 value)
if (host->top_base)
clrsetbits_le32(&host->top_base->emmc_top_control,
- PAD_DAT_RD_RXDLY, value << PAD_DAT_RD_RXDLY_S);
+ PAD_DAT_RD_RXDLY, FIELD_PREP(PAD_DAT_RD_RXDLY, value));
else
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
- value << MSDC_PAD_TUNE_DATRRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_DATRRDLY, value));
}
static int hs400_tune_response(struct udevice *dev, u32 opcode)
@@ -1122,9 +1203,9 @@ static int hs400_tune_response(struct udevice *dev, u32 opcode)
if (mmc->selected_mode == MMC_HS_200 ||
mmc->selected_mode == UHS_SDR104)
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
- host->hs200_cmd_int_delay <<
- MSDC_PAD_TUNE_CMDRRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay));
if (host->r_smpl)
clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
@@ -1133,7 +1214,7 @@ static int hs400_tune_response(struct udevice *dev, u32 opcode)
for (i = 0; i < PAD_DELAY_MAX; i++) {
clrsetbits_le32(tune_reg, PAD_CMD_TUNE_RX_DLY3,
- i << PAD_CMD_TUNE_RX_DLY3_S);
+ FIELD_PREP(PAD_CMD_TUNE_RX_DLY3, i));
for (j = 0; j < 3; j++) {
cmd_err = mmc_send_tuning(mmc, opcode);
@@ -1148,8 +1229,7 @@ static int hs400_tune_response(struct udevice *dev, u32 opcode)
final_cmd_delay = get_best_delay(dev, host, cmd_delay);
clrsetbits_le32(tune_reg, PAD_CMD_TUNE_RX_DLY3,
- final_cmd_delay.final_phase <<
- PAD_CMD_TUNE_RX_DLY3_S);
+ FIELD_PREP(PAD_CMD_TUNE_RX_DLY3, final_cmd_delay.final_phase));
final_delay = final_cmd_delay.final_phase;
dev_info(dev, "Final cmd pad delay: %x\n", final_delay);
@@ -1175,15 +1255,15 @@ static int msdc_tune_response(struct udevice *dev, u32 opcode)
if (mmc->selected_mode == MMC_HS_200 ||
mmc->selected_mode == UHS_SDR104)
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
- host->hs200_cmd_int_delay <<
- MSDC_PAD_TUNE_CMDRRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay));
clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
for (i = 0; i < PAD_DELAY_MAX; i++) {
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
- i << MSDC_PAD_TUNE_CMDRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRDLY, i));
for (j = 0; j < 3; j++) {
cmd_err = mmc_send_tuning(mmc, opcode);
@@ -1204,8 +1284,8 @@ static int msdc_tune_response(struct udevice *dev, u32 opcode)
setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
for (i = 0; i < PAD_DELAY_MAX; i++) {
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
- i << MSDC_PAD_TUNE_CMDRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRDLY, i));
for (j = 0; j < 3; j++) {
cmd_err = mmc_send_tuning(mmc, opcode);
@@ -1224,15 +1304,15 @@ skip_fall:
final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
if (final_maxlen == final_rise_delay.maxlen) {
clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
- final_rise_delay.final_phase <<
- MSDC_PAD_TUNE_CMDRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRDLY,
+ final_rise_delay.final_phase));
final_delay = final_rise_delay.final_phase;
} else {
setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
- final_fall_delay.final_phase <<
- MSDC_PAD_TUNE_CMDRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRDLY,
+ final_fall_delay.final_phase));
final_delay = final_fall_delay.final_phase;
}
@@ -1240,9 +1320,8 @@ skip_fall:
goto skip_internal;
for (i = 0; i < PAD_DELAY_MAX; i++) {
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
- i << MSDC_PAD_TUNE_CMDRRDLY_S);
-
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRRDLY, i));
cmd_err = mmc_send_tuning(mmc, opcode);
if (!cmd_err)
internal_delay |= (1 << i);
@@ -1251,9 +1330,9 @@ skip_fall:
dev_dbg(dev, "Final internal delay: 0x%x\n", internal_delay);
internal_delay_phase = get_best_delay(dev, host, internal_delay);
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
- internal_delay_phase.final_phase <<
- MSDC_PAD_TUNE_CMDRRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRRDLY,
+ internal_delay_phase.final_phase));
skip_internal:
dev_dbg(dev, "Final cmd pad delay: %x\n", final_delay);
@@ -1278,8 +1357,8 @@ static int msdc_tune_data(struct udevice *dev, u32 opcode)
clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
for (i = 0; i < PAD_DELAY_MAX; i++) {
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
- i << MSDC_PAD_TUNE_DATRRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_DATRRDLY, i));
ret = mmc_send_tuning(mmc, opcode);
if (!ret) {
@@ -1301,8 +1380,8 @@ static int msdc_tune_data(struct udevice *dev, u32 opcode)
setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
for (i = 0; i < PAD_DELAY_MAX; i++) {
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
- i << MSDC_PAD_TUNE_DATRRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_DATRRDLY, i));
ret = mmc_send_tuning(mmc, opcode);
if (!ret) {
@@ -1322,24 +1401,24 @@ skip_fall:
if (final_maxlen == final_rise_delay.maxlen) {
clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
- final_rise_delay.final_phase <<
- MSDC_PAD_TUNE_DATRRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_DATRRDLY,
+ final_rise_delay.final_phase));
final_delay = final_rise_delay.final_phase;
} else {
setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
- final_fall_delay.final_phase <<
- MSDC_PAD_TUNE_DATRRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_DATRRDLY,
+ final_fall_delay.final_phase));
final_delay = final_fall_delay.final_phase;
}
if (mmc->selected_mode == MMC_HS_200 ||
mmc->selected_mode == UHS_SDR104)
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATWRDLY_M,
- host->hs200_write_int_delay <<
- MSDC_PAD_TUNE_DATWRDLY_S);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATWRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_DATWRDLY,
+ host->hs200_write_int_delay));
dev_dbg(dev, "Final data pad delay: %x\n", final_delay);
@@ -1426,7 +1505,7 @@ static int msdc_execute_tuning(struct udevice *dev, uint opcode)
clrbits_le32(&host->base->msdc_iocon,
MSDC_IOCON_DSPL | MSDC_IOCON_W_DSPL);
clrsetbits_le32(&host->base->pad_tune,
- MSDC_PAD_TUNE_DATRRDLY_M, 0);
+ MSDC_PAD_TUNE_DATRRDLY, 0);
writel(host->hs400_ds_delay, &host->base->pad_ds_tune);
/* for hs400 mode it must be set to 0 */
@@ -1479,8 +1558,11 @@ static void msdc_init_hw(struct msdc_host *host)
/* Configure to MMC/SD mode, clock free running */
setbits_le32(&host->base->msdc_cfg, MSDC_CFG_MODE);
- /* Use PIO mode */
- setbits_le32(&host->base->msdc_cfg, MSDC_CFG_PIO);
+ /* Data transfer mode */
+ if (host->dev_comp->use_dma_mode)
+ clrbits_le32(&host->base->msdc_cfg, MSDC_CFG_PIO);
+ else
+ setbits_le32(&host->base->msdc_cfg, MSDC_CFG_PIO);
/* Reset */
msdc_reset_hw(host);
@@ -1488,8 +1570,8 @@ static void msdc_init_hw(struct msdc_host *host)
/* Enable/disable hw card detection according to fdt option */
if (host->builtin_cd)
clrsetbits_le32(&host->base->msdc_ps,
- MSDC_PS_CDDBCE_M,
- (DEFAULT_CD_DEBOUNCE << MSDC_PS_CDDBCE_S) |
+ MSDC_PS_CDDBCE,
+ FIELD_PREP(MSDC_PS_CDDBCE, DEFAULT_CD_DEBOUNCE) |
MSDC_PS_CDEN);
else
clrbits_le32(&host->base->msdc_ps, MSDC_PS_CDEN);
@@ -1518,8 +1600,8 @@ static void msdc_init_hw(struct msdc_host *host)
writel(0xffff4089, &host->base->patch_bit1);
if (host->dev_comp->stop_clk_fix) {
- clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY_M,
- 3 << MSDC_PB1_STOP_DLY_S);
+ clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY,
+ FIELD_PREP(MSDC_PB1_STOP_DLY, 3));
clrbits_le32(&host->base->sdc_fifo_cfg,
SDC_FIFO_CFG_WRVALIDSEL);
clrbits_le32(&host->base->sdc_fifo_cfg,
@@ -1532,8 +1614,8 @@ static void msdc_init_hw(struct msdc_host *host)
setbits_le32(&host->base->emmc50_cfg0, EMMC50_CFG_CFCSTS_SEL);
if (host->dev_comp->async_fifo) {
- clrsetbits_le32(&host->base->patch_bit2, MSDC_PB2_RESPWAIT_M,
- 3 << MSDC_PB2_RESPWAIT_S);
+ clrsetbits_le32(&host->base->patch_bit2, MSDC_PB2_RESPWAIT,
+ FIELD_PREP(MSDC_PB2_RESPWAIT, 3));
if (host->dev_comp->enhance_rx) {
if (host->top_base)
@@ -1544,11 +1626,11 @@ static void msdc_init_hw(struct msdc_host *host)
SDC_RX_ENHANCE_EN);
} else {
clrsetbits_le32(&host->base->patch_bit2,
- MSDC_PB2_RESPSTSENSEL_M,
- 2 << MSDC_PB2_RESPSTSENSEL_S);
+ MSDC_PB2_RESPSTSENSEL,
+ FIELD_PREP(MSDC_PB2_RESPSTSENSEL, 2));
clrsetbits_le32(&host->base->patch_bit2,
- MSDC_PB2_CRCSTSENSEL_M,
- 2 << MSDC_PB2_CRCSTSENSEL_S);
+ MSDC_PB2_CRCSTSENSEL,
+ FIELD_PREP(MSDC_PB2_CRCSTSENSEL, 2));
}
/* use async fifo to avoid tune internal delay */
@@ -1574,9 +1656,9 @@ static void msdc_init_hw(struct msdc_host *host)
setbits_le32(tune_reg,
MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
clrsetbits_le32(&host->base->patch_bit0,
- MSDC_INT_DAT_LATCH_CK_SEL_M,
- host->latch_ck <<
- MSDC_INT_DAT_LATCH_CK_SEL_S);
+ MSDC_INT_DAT_LATCH_CK_SEL,
+ FIELD_PREP(MSDC_INT_DAT_LATCH_CK_SEL,
+ host->latch_ck));
}
} else {
/* choose clock tune */
@@ -1590,39 +1672,38 @@ static void msdc_init_hw(struct msdc_host *host)
if (host->dev_comp->builtin_pad_ctrl) {
/* Set pins driving strength */
writel(MSDC_PAD_CTRL0_CLKPD | MSDC_PAD_CTRL0_CLKSMT |
- MSDC_PAD_CTRL0_CLKIES | (4 << MSDC_PAD_CTRL0_CLKDRVN_S) |
- (4 << MSDC_PAD_CTRL0_CLKDRVP_S), &host->base->pad_ctrl0);
+ MSDC_PAD_CTRL0_CLKIES | FIELD_PREP(MSDC_PAD_CTRL0_CLKDRVN, 4) |
+ FIELD_PREP(MSDC_PAD_CTRL0_CLKDRVP, 4), &host->base->pad_ctrl0);
writel(MSDC_PAD_CTRL1_CMDPU | MSDC_PAD_CTRL1_CMDSMT |
- MSDC_PAD_CTRL1_CMDIES | (4 << MSDC_PAD_CTRL1_CMDDRVN_S) |
- (4 << MSDC_PAD_CTRL1_CMDDRVP_S), &host->base->pad_ctrl1);
+ MSDC_PAD_CTRL1_CMDIES | FIELD_PREP(MSDC_PAD_CTRL1_CMDDRVN, 4) |
+ FIELD_PREP(MSDC_PAD_CTRL1_CMDDRVP, 4), &host->base->pad_ctrl1);
writel(MSDC_PAD_CTRL2_DATPU | MSDC_PAD_CTRL2_DATSMT |
- MSDC_PAD_CTRL2_DATIES | (4 << MSDC_PAD_CTRL2_DATDRVN_S) |
- (4 << MSDC_PAD_CTRL2_DATDRVP_S), &host->base->pad_ctrl2);
+ MSDC_PAD_CTRL2_DATIES | FIELD_PREP(MSDC_PAD_CTRL2_DATDRVN, 4) |
+ FIELD_PREP(MSDC_PAD_CTRL2_DATDRVP, 4), &host->base->pad_ctrl2);
}
if (host->dev_comp->default_pad_dly) {
/* Default pad delay may be needed if tuning not enabled */
- clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CLKTDLY_M |
- MSDC_PAD_TUNE_CMDRRDLY_M |
- MSDC_PAD_TUNE_CMDRDLY_M |
- MSDC_PAD_TUNE_DATRRDLY_M |
- MSDC_PAD_TUNE_DATWRDLY_M,
- (0x10 << MSDC_PAD_TUNE_CLKTDLY_S) |
- (0x10 << MSDC_PAD_TUNE_CMDRRDLY_S) |
- (0x10 << MSDC_PAD_TUNE_CMDRDLY_S) |
- (0x10 << MSDC_PAD_TUNE_DATRRDLY_S) |
- (0x10 << MSDC_PAD_TUNE_DATWRDLY_S));
-
- writel((0x10 << MSDC_PAD_TUNE0_DAT0RDDLY_S) |
- (0x10 << MSDC_PAD_TUNE0_DAT1RDDLY_S) |
- (0x10 << MSDC_PAD_TUNE0_DAT2RDDLY_S) |
- (0x10 << MSDC_PAD_TUNE0_DAT3RDDLY_S),
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CLKTDLY |
+ MSDC_PAD_TUNE_CMDRRDLY |
+ MSDC_PAD_TUNE_CMDRDLY |
+ MSDC_PAD_TUNE_DATRRDLY |
+ MSDC_PAD_TUNE_DATWRDLY,
+ FIELD_PREP(MSDC_PAD_TUNE_CLKTDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRRDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE_CMDRDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE_DATRRDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE_DATWRDLY, 0x10));
+ writel(FIELD_PREP(MSDC_PAD_TUNE0_DAT0RDDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE0_DAT1RDDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE0_DAT2RDDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE0_DAT3RDDLY, 0x10),
rd_dly0_reg);
- writel((0x10 << MSDC_PAD_TUNE1_DAT4RDDLY_S) |
- (0x10 << MSDC_PAD_TUNE1_DAT5RDDLY_S) |
- (0x10 << MSDC_PAD_TUNE1_DAT6RDDLY_S) |
- (0x10 << MSDC_PAD_TUNE1_DAT7RDDLY_S),
+ writel(FIELD_PREP(MSDC_PAD_TUNE1_DAT4RDDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE1_DAT5RDDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE1_DAT6RDDLY, 0x10) |
+ FIELD_PREP(MSDC_PAD_TUNE1_DAT7RDDLY, 0x10),
rd_dly1_reg);
}
@@ -1633,8 +1714,8 @@ static void msdc_init_hw(struct msdc_host *host)
clrbits_le32(&host->base->sdc_cfg, SDC_CFG_SDIOIDE);
/* Configure to default data timeout */
- clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M,
- 3 << SDC_CFG_DTOC_S);
+ clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC,
+ FIELD_PREP(SDC_CFG_DTOC, 3));
host->def_tune_para.iocon = readl(&host->base->msdc_iocon);
host->def_tune_para.pad_tune = readl(&host->base->pad_tune);
@@ -1894,6 +1975,8 @@ static const struct msdc_compatible mt8183_compat = {
.data_tune = true,
.busy_check = true,
.stop_clk_fix = true,
+ .enhance_rx = true,
+ .use_dma_mode = true,
};
static const struct udevice_id msdc_ids[] = {