diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2010-08-09 07:57:30 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-26 14:54:29 -0400 |
commit | 8301bb68c6bb9836889641a47443aeb97b763f6c (patch) | |
tree | 4d65282eb5ad2cd6ec793483bc82e5e7ad5d9357 /drivers/mmc/host/mmci.c | |
parent | 2971944582ff43b7dedbb460777052243ac9915a (diff) |
ARM: 6310/1: mmci: support different FIFO sizes
The Ux500 variant has a 32-word FIFO (TXFIFOEMPTY is asserted when it
has 2 left) and TXFIFOHALFEMPTY is repurposed as TXFIFOBURSTWRITEABLE,
with a burst being defined as 8-words. Likewise for RX.
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r-- | drivers/mmc/host/mmci.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 9a9aeac50a6c..1932e9cc8f52 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -41,23 +41,35 @@ static unsigned int fmax = 515633; | |||
41 | * @clkreg: default value for MCICLOCK register | 41 | * @clkreg: default value for MCICLOCK register |
42 | * @clkreg_enable: enable value for MMCICLOCK register | 42 | * @clkreg_enable: enable value for MMCICLOCK register |
43 | * @datalength_bits: number of bits in the MMCIDATALENGTH register | 43 | * @datalength_bits: number of bits in the MMCIDATALENGTH register |
44 | * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY | ||
45 | * is asserted (likewise for RX) | ||
46 | * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY | ||
47 | * is asserted (likewise for RX) | ||
44 | */ | 48 | */ |
45 | struct variant_data { | 49 | struct variant_data { |
46 | unsigned int clkreg; | 50 | unsigned int clkreg; |
47 | unsigned int clkreg_enable; | 51 | unsigned int clkreg_enable; |
48 | unsigned int datalength_bits; | 52 | unsigned int datalength_bits; |
53 | unsigned int fifosize; | ||
54 | unsigned int fifohalfsize; | ||
49 | }; | 55 | }; |
50 | 56 | ||
51 | static struct variant_data variant_arm = { | 57 | static struct variant_data variant_arm = { |
58 | .fifosize = 16 * 4, | ||
59 | .fifohalfsize = 8 * 4, | ||
52 | .datalength_bits = 16, | 60 | .datalength_bits = 16, |
53 | }; | 61 | }; |
54 | 62 | ||
55 | static struct variant_data variant_u300 = { | 63 | static struct variant_data variant_u300 = { |
64 | .fifosize = 16 * 4, | ||
65 | .fifohalfsize = 8 * 4, | ||
56 | .clkreg_enable = 1 << 13, /* HWFCEN */ | 66 | .clkreg_enable = 1 << 13, /* HWFCEN */ |
57 | .datalength_bits = 16, | 67 | .datalength_bits = 16, |
58 | }; | 68 | }; |
59 | 69 | ||
60 | static struct variant_data variant_ux500 = { | 70 | static struct variant_data variant_ux500 = { |
71 | .fifosize = 30 * 4, | ||
72 | .fifohalfsize = 8 * 4, | ||
61 | .clkreg = MCI_CLK_ENABLE, | 73 | .clkreg = MCI_CLK_ENABLE, |
62 | .clkreg_enable = 1 << 14, /* HWFCEN */ | 74 | .clkreg_enable = 1 << 14, /* HWFCEN */ |
63 | .datalength_bits = 24, | 75 | .datalength_bits = 24, |
@@ -138,6 +150,7 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) | |||
138 | 150 | ||
139 | static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | 151 | static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) |
140 | { | 152 | { |
153 | struct variant_data *variant = host->variant; | ||
141 | unsigned int datactrl, timeout, irqmask; | 154 | unsigned int datactrl, timeout, irqmask; |
142 | unsigned long long clks; | 155 | unsigned long long clks; |
143 | void __iomem *base; | 156 | void __iomem *base; |
@@ -173,7 +186,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
173 | * If we have less than a FIFOSIZE of bytes to transfer, | 186 | * If we have less than a FIFOSIZE of bytes to transfer, |
174 | * trigger a PIO interrupt as soon as any data is available. | 187 | * trigger a PIO interrupt as soon as any data is available. |
175 | */ | 188 | */ |
176 | if (host->size < MCI_FIFOSIZE) | 189 | if (host->size < variant->fifosize) |
177 | irqmask |= MCI_RXDATAAVLBLMASK; | 190 | irqmask |= MCI_RXDATAAVLBLMASK; |
178 | } else { | 191 | } else { |
179 | /* | 192 | /* |
@@ -332,13 +345,15 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema | |||
332 | 345 | ||
333 | static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status) | 346 | static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status) |
334 | { | 347 | { |
348 | struct variant_data *variant = host->variant; | ||
335 | void __iomem *base = host->base; | 349 | void __iomem *base = host->base; |
336 | char *ptr = buffer; | 350 | char *ptr = buffer; |
337 | 351 | ||
338 | do { | 352 | do { |
339 | unsigned int count, maxcnt; | 353 | unsigned int count, maxcnt; |
340 | 354 | ||
341 | maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE : MCI_FIFOHALFSIZE; | 355 | maxcnt = status & MCI_TXFIFOEMPTY ? |
356 | variant->fifosize : variant->fifohalfsize; | ||
342 | count = min(remain, maxcnt); | 357 | count = min(remain, maxcnt); |
343 | 358 | ||
344 | writesl(base + MMCIFIFO, ptr, count >> 2); | 359 | writesl(base + MMCIFIFO, ptr, count >> 2); |
@@ -362,6 +377,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) | |||
362 | { | 377 | { |
363 | struct mmci_host *host = dev_id; | 378 | struct mmci_host *host = dev_id; |
364 | struct sg_mapping_iter *sg_miter = &host->sg_miter; | 379 | struct sg_mapping_iter *sg_miter = &host->sg_miter; |
380 | struct variant_data *variant = host->variant; | ||
365 | void __iomem *base = host->base; | 381 | void __iomem *base = host->base; |
366 | unsigned long flags; | 382 | unsigned long flags; |
367 | u32 status; | 383 | u32 status; |
@@ -420,7 +436,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) | |||
420 | * If we're nearing the end of the read, switch to | 436 | * If we're nearing the end of the read, switch to |
421 | * "any data available" mode. | 437 | * "any data available" mode. |
422 | */ | 438 | */ |
423 | if (status & MCI_RXACTIVE && host->size < MCI_FIFOSIZE) | 439 | if (status & MCI_RXACTIVE && host->size < variant->fifosize) |
424 | writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1); | 440 | writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1); |
425 | 441 | ||
426 | /* | 442 | /* |