mmci: Add support for ST Micro derivate
This patch adds support for the ST Microelectronics version of the PL180 PrimeCell. They use designer ID 0x80 and have a few alterations/bugfixes related to open drain and HW flow control. They also add some SDIO registers, I am unsure if these are in ST HW only or if this is things also added in later ARM revisions, but they are included in the mmci.h file for completeness. Signed-off-by: Linus Walleij <linus.walleij@ericsson.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
This commit is contained in:
Родитель
d96be879ff
Коммит
cc30d60e4c
|
@ -430,6 +430,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|||
clk = 255;
|
||||
host->cclk = host->mclk / (2 * (clk + 1));
|
||||
}
|
||||
if (host->hw_designer == 0x80)
|
||||
clk |= MCI_FCEN; /* Bug fix in ST IP block */
|
||||
clk |= MCI_CLK_ENABLE;
|
||||
}
|
||||
|
||||
|
@ -440,15 +442,27 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|||
case MMC_POWER_OFF:
|
||||
break;
|
||||
case MMC_POWER_UP:
|
||||
pwr |= MCI_PWR_UP;
|
||||
break;
|
||||
/* The ST version does not have this, fall through to POWER_ON */
|
||||
if (host->hw_designer != 0x80) {
|
||||
pwr |= MCI_PWR_UP;
|
||||
break;
|
||||
}
|
||||
case MMC_POWER_ON:
|
||||
pwr |= MCI_PWR_ON;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
|
||||
pwr |= MCI_ROD;
|
||||
if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
|
||||
if (host->hw_designer != 0x80)
|
||||
pwr |= MCI_ROD;
|
||||
else {
|
||||
/*
|
||||
* The ST Micro variant use the ROD bit for something
|
||||
* else and only has OD (Open Drain).
|
||||
*/
|
||||
pwr |= MCI_OD;
|
||||
}
|
||||
}
|
||||
|
||||
writel(clk, host->base + MMCICLOCK);
|
||||
|
||||
|
@ -500,6 +514,12 @@ static int mmci_probe(struct amba_device *dev, void *id)
|
|||
}
|
||||
|
||||
host = mmc_priv(mmc);
|
||||
/* Bits 12 thru 19 is the designer */
|
||||
host->hw_designer = (dev->periphid >> 12) & 0xff;
|
||||
/* Bits 20 thru 23 is the revison */
|
||||
host->hw_revision = (dev->periphid >> 20) & 0xf;
|
||||
DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
|
||||
DBG(host, "revision = 0x%01x\n", host->hw_revision);
|
||||
host->clk = clk_get(&dev->dev, NULL);
|
||||
if (IS_ERR(host->clk)) {
|
||||
ret = PTR_ERR(host->clk);
|
||||
|
@ -693,6 +713,15 @@ static struct amba_id mmci_ids[] = {
|
|||
.id = 0x00041181,
|
||||
.mask = 0x000fffff,
|
||||
},
|
||||
/* ST Micro variants */
|
||||
{
|
||||
.id = 0x00180180,
|
||||
.mask = 0x00ffffff,
|
||||
},
|
||||
{
|
||||
.id = 0x00280180,
|
||||
.mask = 0x00ffffff,
|
||||
},
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
|
|
|
@ -11,13 +11,23 @@
|
|||
#define MCI_PWR_OFF 0x00
|
||||
#define MCI_PWR_UP 0x02
|
||||
#define MCI_PWR_ON 0x03
|
||||
#define MCI_DATA2DIREN (1 << 2)
|
||||
#define MCI_CMDDIREN (1 << 3)
|
||||
#define MCI_DATA0DIREN (1 << 4)
|
||||
#define MCI_DATA31DIREN (1 << 5)
|
||||
#define MCI_OD (1 << 6)
|
||||
#define MCI_ROD (1 << 7)
|
||||
/* The ST Micro version does not have ROD */
|
||||
#define MCI_FBCLKEN (1 << 7)
|
||||
#define MCI_DATA74DIREN (1 << 8)
|
||||
|
||||
#define MMCICLOCK 0x004
|
||||
#define MCI_CLK_ENABLE (1 << 8)
|
||||
#define MCI_CLK_PWRSAVE (1 << 9)
|
||||
#define MCI_CLK_BYPASS (1 << 10)
|
||||
#define MCI_WIDE_BUS (1 << 11)
|
||||
/* HW flow control on the ST Micro version */
|
||||
#define MCI_FCEN (1 << 13)
|
||||
|
||||
#define MMCIARGUMENT 0x008
|
||||
#define MMCICOMMAND 0x00c
|
||||
|
@ -26,6 +36,10 @@
|
|||
#define MCI_CPSM_INTERRUPT (1 << 8)
|
||||
#define MCI_CPSM_PENDING (1 << 9)
|
||||
#define MCI_CPSM_ENABLE (1 << 10)
|
||||
#define MCI_SDIO_SUSP (1 << 11)
|
||||
#define MCI_ENCMD_COMPL (1 << 12)
|
||||
#define MCI_NIEN (1 << 13)
|
||||
#define MCI_CE_ATACMD (1 << 14)
|
||||
|
||||
#define MMCIRESPCMD 0x010
|
||||
#define MMCIRESPONSE0 0x014
|
||||
|
@ -39,6 +53,11 @@
|
|||
#define MCI_DPSM_DIRECTION (1 << 1)
|
||||
#define MCI_DPSM_MODE (1 << 2)
|
||||
#define MCI_DPSM_DMAENABLE (1 << 3)
|
||||
#define MCI_DPSM_BLOCKSIZE (1 << 4)
|
||||
#define MCI_DPSM_RWSTART (1 << 8)
|
||||
#define MCI_DPSM_RWSTOP (1 << 9)
|
||||
#define MCI_DPSM_RWMOD (1 << 10)
|
||||
#define MCI_DPSM_SDIOEN (1 << 11)
|
||||
|
||||
#define MMCIDATACNT 0x030
|
||||
#define MMCISTATUS 0x034
|
||||
|
@ -63,6 +82,8 @@
|
|||
#define MCI_RXFIFOEMPTY (1 << 19)
|
||||
#define MCI_TXDATAAVLBL (1 << 20)
|
||||
#define MCI_RXDATAAVLBL (1 << 21)
|
||||
#define MCI_SDIOIT (1 << 22)
|
||||
#define MCI_CEATAEND (1 << 23)
|
||||
|
||||
#define MMCICLEAR 0x038
|
||||
#define MCI_CMDCRCFAILCLR (1 << 0)
|
||||
|
@ -75,6 +96,8 @@
|
|||
#define MCI_CMDSENTCLR (1 << 7)
|
||||
#define MCI_DATAENDCLR (1 << 8)
|
||||
#define MCI_DATABLOCKENDCLR (1 << 10)
|
||||
#define MCI_SDIOITC (1 << 22)
|
||||
#define MCI_CEATAENDC (1 << 23)
|
||||
|
||||
#define MMCIMASK0 0x03c
|
||||
#define MCI_CMDCRCFAILMASK (1 << 0)
|
||||
|
@ -98,6 +121,8 @@
|
|||
#define MCI_RXFIFOEMPTYMASK (1 << 19)
|
||||
#define MCI_TXDATAAVLBLMASK (1 << 20)
|
||||
#define MCI_RXDATAAVLBLMASK (1 << 21)
|
||||
#define MCI_SDIOITMASK (1 << 22)
|
||||
#define MCI_CEATAENDMASK (1 << 23)
|
||||
|
||||
#define MMCIMASK1 0x040
|
||||
#define MMCIFIFOCNT 0x048
|
||||
|
@ -136,6 +161,9 @@ struct mmci_host {
|
|||
u32 pwr;
|
||||
struct mmc_platform_data *plat;
|
||||
|
||||
u8 hw_designer;
|
||||
u8 hw_revision:4;
|
||||
|
||||
struct timer_list timer;
|
||||
unsigned int oldstat;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче