aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/mmci.c30
-rw-r--r--drivers/mmc/host/mmci.h1
2 files changed, 29 insertions, 2 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 2e6075fdce46..063136d89b42 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -73,6 +73,7 @@ static unsigned int fmax = 515633;
73 * @busy_detect: true if busy detection on dat0 is supported 73 * @busy_detect: true if busy detection on dat0 is supported
74 * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply 74 * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
75 * @explicit_mclk_control: enable explicit mclk control in driver. 75 * @explicit_mclk_control: enable explicit mclk control in driver.
76 * @qcom_fifo: enables qcom specific fifo pio read logic.
76 */ 77 */
77struct variant_data { 78struct variant_data {
78 unsigned int clkreg; 79 unsigned int clkreg;
@@ -95,6 +96,7 @@ struct variant_data {
95 bool busy_detect; 96 bool busy_detect;
96 bool pwrreg_nopower; 97 bool pwrreg_nopower;
97 bool explicit_mclk_control; 98 bool explicit_mclk_control;
99 bool qcom_fifo;
98}; 100};
99 101
100static struct variant_data variant_arm = { 102static struct variant_data variant_arm = {
@@ -992,15 +994,34 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
992 } 994 }
993} 995}
994 996
997static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain)
998{
999 return remain - (readl(host->base + MMCIFIFOCNT) << 2);
1000}
1001
1002static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r)
1003{
1004 /*
1005 * on qcom SDCC4 only 8 words are used in each burst so only 8 addresses
1006 * from the fifo range should be used
1007 */
1008 if (status & MCI_RXFIFOHALFFULL)
1009 return host->variant->fifohalfsize;
1010 else if (status & MCI_RXDATAAVLBL)
1011 return 4;
1012
1013 return 0;
1014}
1015
995static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) 1016static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain)
996{ 1017{
997 void __iomem *base = host->base; 1018 void __iomem *base = host->base;
998 char *ptr = buffer; 1019 char *ptr = buffer;
999 u32 status; 1020 u32 status = readl(host->base + MMCISTATUS);
1000 int host_remain = host->size; 1021 int host_remain = host->size;
1001 1022
1002 do { 1023 do {
1003 int count = host_remain - (readl(base + MMCIFIFOCNT) << 2); 1024 int count = host->get_rx_fifocnt(host, status, host_remain);
1004 1025
1005 if (count > remain) 1026 if (count > remain)
1006 count = remain; 1027 count = remain;
@@ -1489,6 +1510,11 @@ static int mmci_probe(struct amba_device *dev,
1489 if (ret) 1510 if (ret)
1490 goto host_free; 1511 goto host_free;
1491 1512
1513 if (variant->qcom_fifo)
1514 host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt;
1515 else
1516 host->get_rx_fifocnt = mmci_get_rx_fifocnt;
1517
1492 host->plat = plat; 1518 host->plat = plat;
1493 host->variant = variant; 1519 host->variant = variant;
1494 host->mclk = clk_get_rate(host->clk); 1520 host->mclk = clk_get_rate(host->clk);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index ef346170b241..a1f5e4f49e2a 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -229,6 +229,7 @@ struct mmci_host {
229 /* pio stuff */ 229 /* pio stuff */
230 struct sg_mapping_iter sg_miter; 230 struct sg_mapping_iter sg_miter;
231 unsigned int size; 231 unsigned int size;
232 int (*get_rx_fifocnt)(struct mmci_host *h, u32 status, int remain);
232 233
233#ifdef CONFIG_DMA_ENGINE 234#ifdef CONFIG_DMA_ENGINE
234 /* DMA stuff */ 235 /* DMA stuff */