Loading drivers/mmc/host/meson-gx-mmc.c +45 −5 Original line number Diff line number Diff line Loading @@ -165,6 +165,7 @@ struct meson_host { unsigned int bounce_buf_size; void *bounce_buf; void __iomem *bounce_iomem_buf; dma_addr_t bounce_dma_addr; struct sd_emmc_desc *descs; dma_addr_t descs_dma_addr; Loading Loading @@ -745,6 +746,47 @@ static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg) writel(start, host->regs + SD_EMMC_START); } /* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */ static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data, size_t buflen, bool to_buffer) { unsigned int sg_flags = SG_MITER_ATOMIC; struct scatterlist *sgl = data->sg; unsigned int nents = data->sg_len; struct sg_mapping_iter miter; unsigned int offset = 0; if (to_buffer) sg_flags |= SG_MITER_FROM_SG; else sg_flags |= SG_MITER_TO_SG; sg_miter_start(&miter, sgl, nents, sg_flags); while ((offset < buflen) && sg_miter_next(&miter)) { unsigned int len; len = min(miter.length, buflen - offset); /* When dram_access_quirk, the bounce buffer is a iomem mapping */ if (host->dram_access_quirk) { if (to_buffer) memcpy_toio(host->bounce_iomem_buf + offset, miter.addr, len); else memcpy_fromio(miter.addr, host->bounce_iomem_buf + offset, len); } else { if (to_buffer) memcpy(host->bounce_buf + offset, miter.addr, len); else memcpy(miter.addr, host->bounce_buf + offset, len); } offset += len; } sg_miter_stop(&miter); } static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) { struct meson_host *host = mmc_priv(mmc); Loading Loading @@ -788,8 +830,7 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) if (data->flags & MMC_DATA_WRITE) { cmd_cfg |= CMD_CFG_DATA_WR; WARN_ON(xfer_bytes > host->bounce_buf_size); sg_copy_to_buffer(data->sg, data->sg_len, host->bounce_buf, xfer_bytes); meson_mmc_copy_buffer(host, data, xfer_bytes, true); dma_wmb(); } Loading Loading @@ -958,8 +999,7 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) if (meson_mmc_bounce_buf_read(data)) { xfer_bytes = data->blksz * data->blocks; WARN_ON(xfer_bytes > host->bounce_buf_size); sg_copy_from_buffer(data->sg, data->sg_len, host->bounce_buf, xfer_bytes); meson_mmc_copy_buffer(host, data, xfer_bytes, false); } next_cmd = meson_mmc_get_next_command(cmd); Loading Loading @@ -1179,7 +1219,7 @@ static int meson_mmc_probe(struct platform_device *pdev) * instead of the DDR memory */ host->bounce_buf_size = SD_EMMC_SRAM_DATA_BUF_LEN; host->bounce_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; host->bounce_iomem_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; host->bounce_dma_addr = res->start + SD_EMMC_SRAM_DATA_BUF_OFF; } else { /* data bounce buffer */ Loading Loading
drivers/mmc/host/meson-gx-mmc.c +45 −5 Original line number Diff line number Diff line Loading @@ -165,6 +165,7 @@ struct meson_host { unsigned int bounce_buf_size; void *bounce_buf; void __iomem *bounce_iomem_buf; dma_addr_t bounce_dma_addr; struct sd_emmc_desc *descs; dma_addr_t descs_dma_addr; Loading Loading @@ -745,6 +746,47 @@ static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg) writel(start, host->regs + SD_EMMC_START); } /* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */ static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data, size_t buflen, bool to_buffer) { unsigned int sg_flags = SG_MITER_ATOMIC; struct scatterlist *sgl = data->sg; unsigned int nents = data->sg_len; struct sg_mapping_iter miter; unsigned int offset = 0; if (to_buffer) sg_flags |= SG_MITER_FROM_SG; else sg_flags |= SG_MITER_TO_SG; sg_miter_start(&miter, sgl, nents, sg_flags); while ((offset < buflen) && sg_miter_next(&miter)) { unsigned int len; len = min(miter.length, buflen - offset); /* When dram_access_quirk, the bounce buffer is a iomem mapping */ if (host->dram_access_quirk) { if (to_buffer) memcpy_toio(host->bounce_iomem_buf + offset, miter.addr, len); else memcpy_fromio(miter.addr, host->bounce_iomem_buf + offset, len); } else { if (to_buffer) memcpy(host->bounce_buf + offset, miter.addr, len); else memcpy(miter.addr, host->bounce_buf + offset, len); } offset += len; } sg_miter_stop(&miter); } static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) { struct meson_host *host = mmc_priv(mmc); Loading Loading @@ -788,8 +830,7 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) if (data->flags & MMC_DATA_WRITE) { cmd_cfg |= CMD_CFG_DATA_WR; WARN_ON(xfer_bytes > host->bounce_buf_size); sg_copy_to_buffer(data->sg, data->sg_len, host->bounce_buf, xfer_bytes); meson_mmc_copy_buffer(host, data, xfer_bytes, true); dma_wmb(); } Loading Loading @@ -958,8 +999,7 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) if (meson_mmc_bounce_buf_read(data)) { xfer_bytes = data->blksz * data->blocks; WARN_ON(xfer_bytes > host->bounce_buf_size); sg_copy_from_buffer(data->sg, data->sg_len, host->bounce_buf, xfer_bytes); meson_mmc_copy_buffer(host, data, xfer_bytes, false); } next_cmd = meson_mmc_get_next_command(cmd); Loading Loading @@ -1179,7 +1219,7 @@ static int meson_mmc_probe(struct platform_device *pdev) * instead of the DDR memory */ host->bounce_buf_size = SD_EMMC_SRAM_DATA_BUF_LEN; host->bounce_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; host->bounce_iomem_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; host->bounce_dma_addr = res->start + SD_EMMC_SRAM_DATA_BUF_OFF; } else { /* data bounce buffer */ Loading