aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/atmel-mci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/atmel-mci.c')
-rw-r--r--drivers/mmc/host/atmel-mci.c92
1 files changed, 78 insertions, 14 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index e94476beca18..6f56ef025ab5 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -91,6 +91,11 @@ struct atmel_mci_dma {
91 * @regs: Pointer to MMIO registers. 91 * @regs: Pointer to MMIO registers.
92 * @sg: Scatterlist entry currently being processed by PIO or PDC code. 92 * @sg: Scatterlist entry currently being processed by PIO or PDC code.
93 * @pio_offset: Offset into the current scatterlist entry. 93 * @pio_offset: Offset into the current scatterlist entry.
94 * @buffer: Buffer used if we don't have the r/w proof capability. We
95 * don't have the time to switch pdc buffers so we have to use only
96 * one buffer for the full transaction.
97 * @buf_size: size of the buffer.
98 * @phys_buf_addr: buffer address needed for pdc.
94 * @cur_slot: The slot which is currently using the controller. 99 * @cur_slot: The slot which is currently using the controller.
95 * @mrq: The request currently being processed on @cur_slot, 100 * @mrq: The request currently being processed on @cur_slot,
96 * or NULL if the controller is idle. 101 * or NULL if the controller is idle.
@@ -166,6 +171,9 @@ struct atmel_mci {
166 171
167 struct scatterlist *sg; 172 struct scatterlist *sg;
168 unsigned int pio_offset; 173 unsigned int pio_offset;
174 unsigned int *buffer;
175 unsigned int buf_size;
176 dma_addr_t buf_phys_addr;
169 177
170 struct atmel_mci_slot *cur_slot; 178 struct atmel_mci_slot *cur_slot;
171 struct mmc_request *mrq; 179 struct mmc_request *mrq;
@@ -480,6 +488,11 @@ err:
480 dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n"); 488 dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n");
481} 489}
482 490
491static inline unsigned int atmci_get_version(struct atmel_mci *host)
492{
493 return atmci_readl(host, ATMCI_VERSION) & 0x00000fff;
494}
495
483static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host, 496static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host,
484 unsigned int ns) 497 unsigned int ns)
485{ 498{
@@ -603,6 +616,7 @@ static void atmci_pdc_set_single_buf(struct atmel_mci *host,
603 enum atmci_xfer_dir dir, enum atmci_pdc_buf buf_nb) 616 enum atmci_xfer_dir dir, enum atmci_pdc_buf buf_nb)
604{ 617{
605 u32 pointer_reg, counter_reg; 618 u32 pointer_reg, counter_reg;
619 unsigned int buf_size;
606 620
607 if (dir == XFER_RECEIVE) { 621 if (dir == XFER_RECEIVE) {
608 pointer_reg = ATMEL_PDC_RPR; 622 pointer_reg = ATMEL_PDC_RPR;
@@ -617,8 +631,15 @@ static void atmci_pdc_set_single_buf(struct atmel_mci *host,
617 counter_reg += ATMEL_PDC_SCND_BUF_OFF; 631 counter_reg += ATMEL_PDC_SCND_BUF_OFF;
618 } 632 }
619 633
620 atmci_writel(host, pointer_reg, sg_dma_address(host->sg)); 634 if (!host->caps.has_rwproof) {
621 if (host->data_size <= sg_dma_len(host->sg)) { 635 buf_size = host->buf_size;
636 atmci_writel(host, pointer_reg, host->buf_phys_addr);
637 } else {
638 buf_size = sg_dma_len(host->sg);
639 atmci_writel(host, pointer_reg, sg_dma_address(host->sg));
640 }
641
642 if (host->data_size <= buf_size) {
622 if (host->data_size & 0x3) { 643 if (host->data_size & 0x3) {
623 /* If size is different from modulo 4, transfer bytes */ 644 /* If size is different from modulo 4, transfer bytes */
624 atmci_writel(host, counter_reg, host->data_size); 645 atmci_writel(host, counter_reg, host->data_size);
@@ -670,7 +691,15 @@ static void atmci_pdc_cleanup(struct atmel_mci *host)
670 */ 691 */
671static void atmci_pdc_complete(struct atmel_mci *host) 692static void atmci_pdc_complete(struct atmel_mci *host)
672{ 693{
694 int transfer_size = host->data->blocks * host->data->blksz;
695
673 atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS); 696 atmci_writel(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
697
698 if ((!host->caps.has_rwproof)
699 && (host->data->flags & MMC_DATA_READ))
700 sg_copy_from_buffer(host->data->sg, host->data->sg_len,
701 host->buffer, transfer_size);
702
674 atmci_pdc_cleanup(host); 703 atmci_pdc_cleanup(host);
675 704
676 /* 705 /*
@@ -818,6 +847,12 @@ atmci_prepare_data_pdc(struct atmel_mci *host, struct mmc_data *data)
818 /* Configure PDC */ 847 /* Configure PDC */
819 host->data_size = data->blocks * data->blksz; 848 host->data_size = data->blocks * data->blksz;
820 sg_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, dir); 849 sg_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, dir);
850
851 if ((!host->caps.has_rwproof)
852 && (host->data->flags & MMC_DATA_WRITE))
853 sg_copy_to_buffer(host->data->sg, host->data->sg_len,
854 host->buffer, host->data_size);
855
821 if (host->data_size) 856 if (host->data_size)
822 atmci_pdc_set_both_buf(host, 857 atmci_pdc_set_both_buf(host,
823 ((dir == DMA_FROM_DEVICE) ? XFER_RECEIVE : XFER_TRANSMIT)); 858 ((dir == DMA_FROM_DEVICE) ? XFER_RECEIVE : XFER_TRANSMIT));
@@ -1877,13 +1912,26 @@ static int __init atmci_init_slot(struct atmel_mci *host,
1877 mmc->caps |= MMC_CAP_SDIO_IRQ; 1912 mmc->caps |= MMC_CAP_SDIO_IRQ;
1878 if (host->caps.has_highspeed) 1913 if (host->caps.has_highspeed)
1879 mmc->caps |= MMC_CAP_SD_HIGHSPEED; 1914 mmc->caps |= MMC_CAP_SD_HIGHSPEED;
1880 if (slot_data->bus_width >= 4) 1915 /*
1916 * Without the read/write proof capability, it is strongly suggested to
1917 * use only one bit for data to prevent fifo underruns and overruns
1918 * which will corrupt data.
1919 */
1920 if ((slot_data->bus_width >= 4) && host->caps.has_rwproof)
1881 mmc->caps |= MMC_CAP_4_BIT_DATA; 1921 mmc->caps |= MMC_CAP_4_BIT_DATA;
1882 1922
1883 mmc->max_segs = 64; 1923 if (atmci_get_version(host) < 0x200) {
1884 mmc->max_req_size = 32768 * 512; 1924 mmc->max_segs = 256;
1885 mmc->max_blk_size = 32768; 1925 mmc->max_blk_size = 4095;
1886 mmc->max_blk_count = 512; 1926 mmc->max_blk_count = 256;
1927 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
1928 mmc->max_seg_size = mmc->max_blk_size * mmc->max_segs;
1929 } else {
1930 mmc->max_segs = 64;
1931 mmc->max_req_size = 32768 * 512;
1932 mmc->max_blk_size = 32768;
1933 mmc->max_blk_count = 512;
1934 }
1887 1935
1888 /* Assume card is present initially */ 1936 /* Assume card is present initially */
1889 set_bit(ATMCI_CARD_PRESENT, &slot->flags); 1937 set_bit(ATMCI_CARD_PRESENT, &slot->flags);
@@ -2007,11 +2055,6 @@ static bool atmci_configure_dma(struct atmel_mci *host)
2007 } 2055 }
2008} 2056}
2009 2057
2010static inline unsigned int atmci_get_version(struct atmel_mci *host)
2011{
2012 return atmci_readl(host, ATMCI_VERSION) & 0x00000fff;
2013}
2014
2015/* 2058/*
2016 * HSMCI (High Speed MCI) module is not fully compatible with MCI module. 2059 * HSMCI (High Speed MCI) module is not fully compatible with MCI module.
2017 * HSMCI provides DMA support and a new config register but no more supports 2060 * HSMCI provides DMA support and a new config register but no more supports
@@ -2138,14 +2181,20 @@ static int __init atmci_probe(struct platform_device *pdev)
2138 if (pdata->slot[0].bus_width) { 2181 if (pdata->slot[0].bus_width) {
2139 ret = atmci_init_slot(host, &pdata->slot[0], 2182 ret = atmci_init_slot(host, &pdata->slot[0],
2140 0, ATMCI_SDCSEL_SLOT_A, ATMCI_SDIOIRQA); 2183 0, ATMCI_SDCSEL_SLOT_A, ATMCI_SDIOIRQA);
2141 if (!ret) 2184 if (!ret) {
2142 nr_slots++; 2185 nr_slots++;
2186 host->buf_size = host->slot[0]->mmc->max_req_size;
2187 }
2143 } 2188 }
2144 if (pdata->slot[1].bus_width) { 2189 if (pdata->slot[1].bus_width) {
2145 ret = atmci_init_slot(host, &pdata->slot[1], 2190 ret = atmci_init_slot(host, &pdata->slot[1],
2146 1, ATMCI_SDCSEL_SLOT_B, ATMCI_SDIOIRQB); 2191 1, ATMCI_SDCSEL_SLOT_B, ATMCI_SDIOIRQB);
2147 if (!ret) 2192 if (!ret) {
2148 nr_slots++; 2193 nr_slots++;
2194 if (host->slot[1]->mmc->max_req_size > host->buf_size)
2195 host->buf_size =
2196 host->slot[1]->mmc->max_req_size;
2197 }
2149 } 2198 }
2150 2199
2151 if (!nr_slots) { 2200 if (!nr_slots) {
@@ -2153,6 +2202,17 @@ static int __init atmci_probe(struct platform_device *pdev)
2153 goto err_init_slot; 2202 goto err_init_slot;
2154 } 2203 }
2155 2204
2205 if (!host->caps.has_rwproof) {
2206 host->buffer = dma_alloc_coherent(&pdev->dev, host->buf_size,
2207 &host->buf_phys_addr,
2208 GFP_KERNEL);
2209 if (!host->buffer) {
2210 ret = -ENOMEM;
2211 dev_err(&pdev->dev, "buffer allocation failed\n");
2212 goto err_init_slot;
2213 }
2214 }
2215
2156 dev_info(&pdev->dev, 2216 dev_info(&pdev->dev,
2157 "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", 2217 "Atmel MCI controller at 0x%08lx irq %d, %u slots\n",
2158 host->mapbase, irq, nr_slots); 2218 host->mapbase, irq, nr_slots);
@@ -2179,6 +2239,10 @@ static int __exit atmci_remove(struct platform_device *pdev)
2179 2239
2180 platform_set_drvdata(pdev, NULL); 2240 platform_set_drvdata(pdev, NULL);
2181 2241
2242 if (host->buffer)
2243 dma_free_coherent(&pdev->dev, host->buf_size,
2244 host->buffer, host->buf_phys_addr);
2245
2182 for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { 2246 for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
2183 if (host->slot[i]) 2247 if (host->slot[i])
2184 atmci_cleanup_slot(host->slot[i], i); 2248 atmci_cleanup_slot(host->slot[i], i);