diff options
author | Soby Mathew <soby.mathew@arm.com> | 2019-03-13 15:25:54 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-13 15:25:54 +0000 |
commit | 77913d446cc2dca5c801ab9e52716e501872ae81 (patch) | |
tree | 46c84487dadd8b444b6f52c1700a878ea71b8c2b | |
parent | eb9da9e182e0499b2c684f3829df687bee4782c8 (diff) | |
parent | 3d0f30bb544a6b4a0c4766a6c31169419db4090e (diff) | |
download | trusted-firmware-a-77913d446cc2dca5c801ab9e52716e501872ae81.tar.gz |
Merge pull request #1858 from thloh85-intel/dwmmc_fixes
drivers: synopsys: Fix synopsys MMC driver
-rw-r--r-- | drivers/synopsys/emmc/dw_mmc.c | 29 | ||||
-rw-r--r-- | include/drivers/synopsys/dw_mmc.h | 1 |
2 files changed, 29 insertions, 1 deletions
diff --git a/drivers/synopsys/emmc/dw_mmc.c b/drivers/synopsys/emmc/dw_mmc.c index 0c5c645701..4cd1226aa5 100644 --- a/drivers/synopsys/emmc/dw_mmc.c +++ b/drivers/synopsys/emmc/dw_mmc.c @@ -243,6 +243,11 @@ static int dw_send_cmd(struct mmc_cmd *cmd) op = CMD_WAIT_PRVDATA_COMPLETE; break; case 8: + if (dw_params.mmc_dev_type == MMC_IS_EMMC) + op = CMD_DATA_TRANS_EXPECT | CMD_WAIT_PRVDATA_COMPLETE; + else + op = CMD_WAIT_PRVDATA_COMPLETE; + break; case 17: case 18: op = CMD_DATA_TRANS_EXPECT | CMD_WAIT_PRVDATA_COMPLETE; @@ -252,6 +257,9 @@ static int dw_send_cmd(struct mmc_cmd *cmd) op = CMD_WRITE | CMD_DATA_TRANS_EXPECT | CMD_WAIT_PRVDATA_COMPLETE; break; + case 51: + op = CMD_DATA_TRANS_EXPECT; + break; default: op = 0; break; @@ -337,7 +345,6 @@ static int dw_prepare(int lba, uintptr_t buf, size_t size) uintptr_t base; assert(((buf & DWMMC_ADDRESS_MASK) == 0) && - ((size % MMC_BLOCK_SIZE) == 0) && (dw_params.desc_size > 0) && ((dw_params.reg_base & MMC_BLOCK_MASK) == 0) && ((dw_params.desc_base & MMC_BLOCK_MASK) == 0) && @@ -352,6 +359,12 @@ static int dw_prepare(int lba, uintptr_t buf, size_t size) base = dw_params.reg_base; desc = (struct dw_idmac_desc *)dw_params.desc_base; mmio_write_32(base + DWMMC_BYTCNT, size); + + if (size < MMC_BLOCK_SIZE) + mmio_write_32(base + DWMMC_BLKSIZ, size); + else + mmio_write_32(base + DWMMC_BLKSIZ, MMC_BLOCK_SIZE); + mmio_write_32(base + DWMMC_RINTSTS, ~0); for (i = 0; i < desc_cnt; i++) { desc[i].des0 = IDMAC_DES0_OWN | IDMAC_DES0_CH | IDMAC_DES0_DIC; @@ -375,11 +388,22 @@ static int dw_prepare(int lba, uintptr_t buf, size_t size) flush_dcache_range(dw_params.desc_base, desc_cnt * DWMMC_DMA_MAX_BUFFER_SIZE); + return 0; } static int dw_read(int lba, uintptr_t buf, size_t size) { + uint32_t data = 0; + int timeout = TIMEOUT; + + do { + data = mmio_read_32(dw_params.reg_base + DWMMC_RINTSTS); + udelay(50); + } while (!(data & INT_DTO) && timeout-- > 0); + + inv_dcache_range(buf, size); + return 0; } @@ -401,6 +425,9 @@ void dw_mmc_init(dw_mmc_params_t *params, struct mmc_device_info *info) (params->bus_width == MMC_BUS_WIDTH_8))); memcpy(&dw_params, params, sizeof(dw_mmc_params_t)); + mmio_write_32(dw_params.reg_base + DWMMC_FIFOTH, 0x103ff); mmc_init(&dw_mmc_ops, params->clk_rate, params->bus_width, params->flags, info); + + dw_params.mmc_dev_type = info->mmc_dev_type; } diff --git a/include/drivers/synopsys/dw_mmc.h b/include/drivers/synopsys/dw_mmc.h index 7031e0f46f..2004355259 100644 --- a/include/drivers/synopsys/dw_mmc.h +++ b/include/drivers/synopsys/dw_mmc.h @@ -16,6 +16,7 @@ typedef struct dw_mmc_params { int clk_rate; int bus_width; unsigned int flags; + enum mmc_device_type mmc_dev_type; } dw_mmc_params_t; void dw_mmc_init(dw_mmc_params_t *params, struct mmc_device_info *info); |