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 | |
| 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')
| -rw-r--r-- | drivers/mmc/host/mmci.c | 22 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.h | 7 |
2 files changed, 19 insertions, 10 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 | /* |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 68970cfb81e1..4e18f5403f48 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
| @@ -133,13 +133,6 @@ | |||
| 133 | MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ | 133 | MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ |
| 134 | MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK) | 134 | MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK) |
| 135 | 135 | ||
| 136 | /* | ||
| 137 | * The size of the FIFO in bytes. | ||
| 138 | */ | ||
| 139 | #define MCI_FIFOSIZE (16*4) | ||
| 140 | |||
| 141 | #define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2) | ||
| 142 | |||
| 143 | #define NR_SG 16 | 136 | #define NR_SG 16 |
| 144 | 137 | ||
| 145 | struct clk; | 138 | struct clk; |
