forked from Minki/linux
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>
This commit is contained in:
parent
2971944582
commit
8301bb68c6
@ -41,23 +41,35 @@ static unsigned int fmax = 515633;
|
|||||||
* @clkreg: default value for MCICLOCK register
|
* @clkreg: default value for MCICLOCK register
|
||||||
* @clkreg_enable: enable value for MMCICLOCK register
|
* @clkreg_enable: enable value for MMCICLOCK register
|
||||||
* @datalength_bits: number of bits in the MMCIDATALENGTH register
|
* @datalength_bits: number of bits in the MMCIDATALENGTH register
|
||||||
|
* @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
|
||||||
|
* is asserted (likewise for RX)
|
||||||
|
* @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
|
||||||
|
* is asserted (likewise for RX)
|
||||||
*/
|
*/
|
||||||
struct variant_data {
|
struct variant_data {
|
||||||
unsigned int clkreg;
|
unsigned int clkreg;
|
||||||
unsigned int clkreg_enable;
|
unsigned int clkreg_enable;
|
||||||
unsigned int datalength_bits;
|
unsigned int datalength_bits;
|
||||||
|
unsigned int fifosize;
|
||||||
|
unsigned int fifohalfsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct variant_data variant_arm = {
|
static struct variant_data variant_arm = {
|
||||||
|
.fifosize = 16 * 4,
|
||||||
|
.fifohalfsize = 8 * 4,
|
||||||
.datalength_bits = 16,
|
.datalength_bits = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct variant_data variant_u300 = {
|
static struct variant_data variant_u300 = {
|
||||||
|
.fifosize = 16 * 4,
|
||||||
|
.fifohalfsize = 8 * 4,
|
||||||
.clkreg_enable = 1 << 13, /* HWFCEN */
|
.clkreg_enable = 1 << 13, /* HWFCEN */
|
||||||
.datalength_bits = 16,
|
.datalength_bits = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct variant_data variant_ux500 = {
|
static struct variant_data variant_ux500 = {
|
||||||
|
.fifosize = 30 * 4,
|
||||||
|
.fifohalfsize = 8 * 4,
|
||||||
.clkreg = MCI_CLK_ENABLE,
|
.clkreg = MCI_CLK_ENABLE,
|
||||||
.clkreg_enable = 1 << 14, /* HWFCEN */
|
.clkreg_enable = 1 << 14, /* HWFCEN */
|
||||||
.datalength_bits = 24,
|
.datalength_bits = 24,
|
||||||
@ -138,6 +150,7 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
|
|||||||
|
|
||||||
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
|
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
|
||||||
{
|
{
|
||||||
|
struct variant_data *variant = host->variant;
|
||||||
unsigned int datactrl, timeout, irqmask;
|
unsigned int datactrl, timeout, irqmask;
|
||||||
unsigned long long clks;
|
unsigned long long clks;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
@ -173,7 +186,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
|
|||||||
* If we have less than a FIFOSIZE of bytes to transfer,
|
* If we have less than a FIFOSIZE of bytes to transfer,
|
||||||
* trigger a PIO interrupt as soon as any data is available.
|
* trigger a PIO interrupt as soon as any data is available.
|
||||||
*/
|
*/
|
||||||
if (host->size < MCI_FIFOSIZE)
|
if (host->size < variant->fifosize)
|
||||||
irqmask |= MCI_RXDATAAVLBLMASK;
|
irqmask |= MCI_RXDATAAVLBLMASK;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -332,13 +345,15 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema
|
|||||||
|
|
||||||
static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status)
|
static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status)
|
||||||
{
|
{
|
||||||
|
struct variant_data *variant = host->variant;
|
||||||
void __iomem *base = host->base;
|
void __iomem *base = host->base;
|
||||||
char *ptr = buffer;
|
char *ptr = buffer;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
unsigned int count, maxcnt;
|
unsigned int count, maxcnt;
|
||||||
|
|
||||||
maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE : MCI_FIFOHALFSIZE;
|
maxcnt = status & MCI_TXFIFOEMPTY ?
|
||||||
|
variant->fifosize : variant->fifohalfsize;
|
||||||
count = min(remain, maxcnt);
|
count = min(remain, maxcnt);
|
||||||
|
|
||||||
writesl(base + MMCIFIFO, ptr, count >> 2);
|
writesl(base + MMCIFIFO, ptr, count >> 2);
|
||||||
@ -362,6 +377,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
|
|||||||
{
|
{
|
||||||
struct mmci_host *host = dev_id;
|
struct mmci_host *host = dev_id;
|
||||||
struct sg_mapping_iter *sg_miter = &host->sg_miter;
|
struct sg_mapping_iter *sg_miter = &host->sg_miter;
|
||||||
|
struct variant_data *variant = host->variant;
|
||||||
void __iomem *base = host->base;
|
void __iomem *base = host->base;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 status;
|
u32 status;
|
||||||
@ -420,7 +436,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
|
|||||||
* If we're nearing the end of the read, switch to
|
* If we're nearing the end of the read, switch to
|
||||||
* "any data available" mode.
|
* "any data available" mode.
|
||||||
*/
|
*/
|
||||||
if (status & MCI_RXACTIVE && host->size < MCI_FIFOSIZE)
|
if (status & MCI_RXACTIVE && host->size < variant->fifosize)
|
||||||
writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1);
|
writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -133,13 +133,6 @@
|
|||||||
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
|
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
|
||||||
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
|
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
|
||||||
|
|
||||||
/*
|
|
||||||
* The size of the FIFO in bytes.
|
|
||||||
*/
|
|
||||||
#define MCI_FIFOSIZE (16*4)
|
|
||||||
|
|
||||||
#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
|
|
||||||
|
|
||||||
#define NR_SG 16
|
#define NR_SG 16
|
||||||
|
|
||||||
struct clk;
|
struct clk;
|
||||||
|
Loading…
Reference in New Issue
Block a user