From: Steven Feng <steven_f...@realsil.com.cn> The request should be resent when DMA transfer error occurred. For rts5227, the clock rate needs to be reduced when error occurred.
Signed-off-by: Steven Feng <steven_f...@realsil.com.cn> --- drivers/mfd/rtsx_pcr.c | 18 ++++++++++++++++-- include/linux/mfd/rtsx_pci.h | 5 +++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 98029ee..8e21fd6 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c @@ -30,6 +30,7 @@ #include <linux/platform_device.h> #include <linux/mfd/core.h> #include <linux/mfd/rtsx_pci.h> +#include <linux/mmc/card.h> #include <asm/unaligned.h> #include "rtsx_pcr.h" @@ -452,8 +453,12 @@ int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, } spin_lock_irqsave(&pcr->lock, flags); - if (pcr->trans_result == TRANS_RESULT_FAIL) - err = -EINVAL; + if (pcr->trans_result == TRANS_RESULT_FAIL) { + err = -EILSEQ; + if (pcr->dma_error_count < RTS_MAX_TIMES_FREQ_REDUCTION) + pcr->dma_error_count++; + } + else if (pcr->trans_result == TRANS_NO_DEVICE) err = -ENODEV; spin_unlock_irqrestore(&pcr->lock, flags); @@ -659,6 +664,14 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, if (err < 0) return err; + /* Reduce MMC card clock by 20MHz each time a DMA transfer error occurs + */ + if (card_clock == UHS_SDR104_MAX_DTR && + pcr->dma_error_count && + PCI_PID(pcr) == RTS5227_DEVICE_ID) + card_clock = UHS_SDR104_MAX_DTR - + (pcr->dma_error_count * 20000000); + card_clock /= 1000000; pcr_dbg(pcr, "Switch card clock to %dMHz\n", card_clock); @@ -894,6 +907,7 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) pcr->card_removed |= SD_EXIST; pcr->card_inserted &= ~SD_EXIST; } + pcr->dma_error_count = 0; } if (int_reg & MS_INT) { diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 7eb7cba..116816f 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h @@ -850,6 +850,9 @@ #define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0) +#define RTS5227_DEVICE_ID 0x5227 +#define RTS_MAX_TIMES_FREQ_REDUCTION 8 + struct rtsx_pcr; struct pcr_handle { @@ -957,6 +960,8 @@ struct rtsx_pcr { int num_slots; struct rtsx_slot *slots; + + u8 dma_error_count; }; #define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid)) -- 1.9.1