@@ -165,6 +165,7 @@ struct meson_host {
165
165
166
166
unsigned int bounce_buf_size ;
167
167
void * bounce_buf ;
168
+ void __iomem * bounce_iomem_buf ;
168
169
dma_addr_t bounce_dma_addr ;
169
170
struct sd_emmc_desc * descs ;
170
171
dma_addr_t descs_dma_addr ;
@@ -745,6 +746,47 @@ static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg)
745
746
writel (start , host -> regs + SD_EMMC_START );
746
747
}
747
748
749
+ /* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */
750
+ static void meson_mmc_copy_buffer (struct meson_host * host , struct mmc_data * data ,
751
+ size_t buflen , bool to_buffer )
752
+ {
753
+ unsigned int sg_flags = SG_MITER_ATOMIC ;
754
+ struct scatterlist * sgl = data -> sg ;
755
+ unsigned int nents = data -> sg_len ;
756
+ struct sg_mapping_iter miter ;
757
+ unsigned int offset = 0 ;
758
+
759
+ if (to_buffer )
760
+ sg_flags |= SG_MITER_FROM_SG ;
761
+ else
762
+ sg_flags |= SG_MITER_TO_SG ;
763
+
764
+ sg_miter_start (& miter , sgl , nents , sg_flags );
765
+
766
+ while ((offset < buflen ) && sg_miter_next (& miter )) {
767
+ unsigned int len ;
768
+
769
+ len = min (miter .length , buflen - offset );
770
+
771
+ /* When dram_access_quirk, the bounce buffer is a iomem mapping */
772
+ if (host -> dram_access_quirk ) {
773
+ if (to_buffer )
774
+ memcpy_toio (host -> bounce_iomem_buf + offset , miter .addr , len );
775
+ else
776
+ memcpy_fromio (miter .addr , host -> bounce_iomem_buf + offset , len );
777
+ } else {
778
+ if (to_buffer )
779
+ memcpy (host -> bounce_buf + offset , miter .addr , len );
780
+ else
781
+ memcpy (miter .addr , host -> bounce_buf + offset , len );
782
+ }
783
+
784
+ offset += len ;
785
+ }
786
+
787
+ sg_miter_stop (& miter );
788
+ }
789
+
748
790
static void meson_mmc_start_cmd (struct mmc_host * mmc , struct mmc_command * cmd )
749
791
{
750
792
struct meson_host * host = mmc_priv (mmc );
@@ -788,8 +830,7 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
788
830
if (data -> flags & MMC_DATA_WRITE ) {
789
831
cmd_cfg |= CMD_CFG_DATA_WR ;
790
832
WARN_ON (xfer_bytes > host -> bounce_buf_size );
791
- sg_copy_to_buffer (data -> sg , data -> sg_len ,
792
- host -> bounce_buf , xfer_bytes );
833
+ meson_mmc_copy_buffer (host , data , xfer_bytes , true);
793
834
dma_wmb ();
794
835
}
795
836
@@ -958,8 +999,7 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
958
999
if (meson_mmc_bounce_buf_read (data )) {
959
1000
xfer_bytes = data -> blksz * data -> blocks ;
960
1001
WARN_ON (xfer_bytes > host -> bounce_buf_size );
961
- sg_copy_from_buffer (data -> sg , data -> sg_len ,
962
- host -> bounce_buf , xfer_bytes );
1002
+ meson_mmc_copy_buffer (host , data , xfer_bytes , false);
963
1003
}
964
1004
965
1005
next_cmd = meson_mmc_get_next_command (cmd );
@@ -1179,7 +1219,7 @@ static int meson_mmc_probe(struct platform_device *pdev)
1179
1219
* instead of the DDR memory
1180
1220
*/
1181
1221
host -> bounce_buf_size = SD_EMMC_SRAM_DATA_BUF_LEN ;
1182
- host -> bounce_buf = host -> regs + SD_EMMC_SRAM_DATA_BUF_OFF ;
1222
+ host -> bounce_iomem_buf = host -> regs + SD_EMMC_SRAM_DATA_BUF_OFF ;
1183
1223
host -> bounce_dma_addr = res -> start + SD_EMMC_SRAM_DATA_BUF_OFF ;
1184
1224
} else {
1185
1225
/* data bounce buffer */
0 commit comments