diff options
-rw-r--r-- | drivers/mmc/host/mmci.c | 30 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 1 |
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 | */ |
77 | struct variant_data { | 78 | struct 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 | ||
100 | static struct variant_data variant_arm = { | 102 | static 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 | ||
997 | static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain) | ||
998 | { | ||
999 | return remain - (readl(host->base + MMCIFIFOCNT) << 2); | ||
1000 | } | ||
1001 | |||
1002 | static 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 | |||
995 | static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) | 1016 | static 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 */ |