diff options
| author | Linus Walleij <linus.walleij@ericsson.com> | 2009-01-04 09:18:54 -0500 |
|---|---|---|
| committer | Pierre Ossman <drzeus@drzeus.cx> | 2009-02-02 14:57:06 -0500 |
| commit | cc30d60e4ca0b68e7e3f906eddd1e5b995d349f8 (patch) | |
| tree | d5de29f232617cc7ce92cca77dd0b2f7f8024f66 | |
| parent | d96be879ff469759af6d7fcebdb66237c18da6f8 (diff) | |
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>
| -rw-r--r-- | drivers/mmc/host/mmci.c | 37 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.h | 28 |
2 files changed, 61 insertions, 4 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 1bcbdd6763ac..2909bbc8ad00 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
| @@ -430,6 +430,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 430 | clk = 255; | 430 | clk = 255; |
| 431 | host->cclk = host->mclk / (2 * (clk + 1)); | 431 | host->cclk = host->mclk / (2 * (clk + 1)); |
| 432 | } | 432 | } |
| 433 | if (host->hw_designer == 0x80) | ||
| 434 | clk |= MCI_FCEN; /* Bug fix in ST IP block */ | ||
| 433 | clk |= MCI_CLK_ENABLE; | 435 | clk |= MCI_CLK_ENABLE; |
| 434 | } | 436 | } |
| 435 | 437 | ||
| @@ -440,15 +442,27 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 440 | case MMC_POWER_OFF: | 442 | case MMC_POWER_OFF: |
| 441 | break; | 443 | break; |
| 442 | case MMC_POWER_UP: | 444 | case MMC_POWER_UP: |
| 443 | pwr |= MCI_PWR_UP; | 445 | /* The ST version does not have this, fall through to POWER_ON */ |
| 444 | break; | 446 | if (host->hw_designer != 0x80) { |
| 447 | pwr |= MCI_PWR_UP; | ||
| 448 | break; | ||
| 449 | } | ||
| 445 | case MMC_POWER_ON: | 450 | case MMC_POWER_ON: |
| 446 | pwr |= MCI_PWR_ON; | 451 | pwr |= MCI_PWR_ON; |
| 447 | break; | 452 | break; |
| 448 | } | 453 | } |
| 449 | 454 | ||
| 450 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) | 455 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { |
| 451 | pwr |= MCI_ROD; | 456 | if (host->hw_designer != 0x80) |
| 457 | pwr |= MCI_ROD; | ||
| 458 | else { | ||
| 459 | /* | ||
| 460 | * The ST Micro variant use the ROD bit for something | ||
| 461 | * else and only has OD (Open Drain). | ||
| 462 | */ | ||
| 463 | pwr |= MCI_OD; | ||
| 464 | } | ||
| 465 | } | ||
| 452 | 466 | ||
| 453 | writel(clk, host->base + MMCICLOCK); | 467 | writel(clk, host->base + MMCICLOCK); |
| 454 | 468 | ||
| @@ -500,6 +514,12 @@ static int mmci_probe(struct amba_device *dev, void *id) | |||
| 500 | } | 514 | } |
| 501 | 515 | ||
| 502 | host = mmc_priv(mmc); | 516 | host = mmc_priv(mmc); |
| 517 | /* Bits 12 thru 19 is the designer */ | ||
| 518 | host->hw_designer = (dev->periphid >> 12) & 0xff; | ||
| 519 | /* Bits 20 thru 23 is the revison */ | ||
| 520 | host->hw_revision = (dev->periphid >> 20) & 0xf; | ||
| 521 | DBG(host, "designer ID = 0x%02x\n", host->hw_designer); | ||
| 522 | DBG(host, "revision = 0x%01x\n", host->hw_revision); | ||
| 503 | host->clk = clk_get(&dev->dev, NULL); | 523 | host->clk = clk_get(&dev->dev, NULL); |
| 504 | if (IS_ERR(host->clk)) { | 524 | if (IS_ERR(host->clk)) { |
| 505 | ret = PTR_ERR(host->clk); | 525 | ret = PTR_ERR(host->clk); |
| @@ -693,6 +713,15 @@ static struct amba_id mmci_ids[] = { | |||
| 693 | .id = 0x00041181, | 713 | .id = 0x00041181, |
| 694 | .mask = 0x000fffff, | 714 | .mask = 0x000fffff, |
| 695 | }, | 715 | }, |
| 716 | /* ST Micro variants */ | ||
| 717 | { | ||
| 718 | .id = 0x00180180, | ||
| 719 | .mask = 0x00ffffff, | ||
| 720 | }, | ||
| 721 | { | ||
| 722 | .id = 0x00280180, | ||
| 723 | .mask = 0x00ffffff, | ||
| 724 | }, | ||
| 696 | { 0, 0 }, | 725 | { 0, 0 }, |
| 697 | }; | 726 | }; |
| 698 | 727 | ||
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 0f39c490f022..0441bac1c0ec 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
| @@ -11,13 +11,23 @@ | |||
| 11 | #define MCI_PWR_OFF 0x00 | 11 | #define MCI_PWR_OFF 0x00 |
| 12 | #define MCI_PWR_UP 0x02 | 12 | #define MCI_PWR_UP 0x02 |
| 13 | #define MCI_PWR_ON 0x03 | 13 | #define MCI_PWR_ON 0x03 |
| 14 | #define MCI_DATA2DIREN (1 << 2) | ||
| 15 | #define MCI_CMDDIREN (1 << 3) | ||
| 16 | #define MCI_DATA0DIREN (1 << 4) | ||
| 17 | #define MCI_DATA31DIREN (1 << 5) | ||
| 14 | #define MCI_OD (1 << 6) | 18 | #define MCI_OD (1 << 6) |
| 15 | #define MCI_ROD (1 << 7) | 19 | #define MCI_ROD (1 << 7) |
| 20 | /* The ST Micro version does not have ROD */ | ||
| 21 | #define MCI_FBCLKEN (1 << 7) | ||
| 22 | #define MCI_DATA74DIREN (1 << 8) | ||
| 16 | 23 | ||
| 17 | #define MMCICLOCK 0x004 | 24 | #define MMCICLOCK 0x004 |
| 18 | #define MCI_CLK_ENABLE (1 << 8) | 25 | #define MCI_CLK_ENABLE (1 << 8) |
| 19 | #define MCI_CLK_PWRSAVE (1 << 9) | 26 | #define MCI_CLK_PWRSAVE (1 << 9) |
| 20 | #define MCI_CLK_BYPASS (1 << 10) | 27 | #define MCI_CLK_BYPASS (1 << 10) |
| 28 | #define MCI_WIDE_BUS (1 << 11) | ||
| 29 | /* HW flow control on the ST Micro version */ | ||
| 30 | #define MCI_FCEN (1 << 13) | ||
| 21 | 31 | ||
| 22 | #define MMCIARGUMENT 0x008 | 32 | #define MMCIARGUMENT 0x008 |
| 23 | #define MMCICOMMAND 0x00c | 33 | #define MMCICOMMAND 0x00c |
| @@ -26,6 +36,10 @@ | |||
| 26 | #define MCI_CPSM_INTERRUPT (1 << 8) | 36 | #define MCI_CPSM_INTERRUPT (1 << 8) |
| 27 | #define MCI_CPSM_PENDING (1 << 9) | 37 | #define MCI_CPSM_PENDING (1 << 9) |
| 28 | #define MCI_CPSM_ENABLE (1 << 10) | 38 | #define MCI_CPSM_ENABLE (1 << 10) |
| 39 | #define MCI_SDIO_SUSP (1 << 11) | ||
| 40 | #define MCI_ENCMD_COMPL (1 << 12) | ||
| 41 | #define MCI_NIEN (1 << 13) | ||
| 42 | #define MCI_CE_ATACMD (1 << 14) | ||
| 29 | 43 | ||
| 30 | #define MMCIRESPCMD 0x010 | 44 | #define MMCIRESPCMD 0x010 |
| 31 | #define MMCIRESPONSE0 0x014 | 45 | #define MMCIRESPONSE0 0x014 |
| @@ -39,6 +53,11 @@ | |||
| 39 | #define MCI_DPSM_DIRECTION (1 << 1) | 53 | #define MCI_DPSM_DIRECTION (1 << 1) |
| 40 | #define MCI_DPSM_MODE (1 << 2) | 54 | #define MCI_DPSM_MODE (1 << 2) |
| 41 | #define MCI_DPSM_DMAENABLE (1 << 3) | 55 | #define MCI_DPSM_DMAENABLE (1 << 3) |
| 56 | #define MCI_DPSM_BLOCKSIZE (1 << 4) | ||
| 57 | #define MCI_DPSM_RWSTART (1 << 8) | ||
| 58 | #define MCI_DPSM_RWSTOP (1 << 9) | ||
| 59 | #define MCI_DPSM_RWMOD (1 << 10) | ||
| 60 | #define MCI_DPSM_SDIOEN (1 << 11) | ||
| 42 | 61 | ||
| 43 | #define MMCIDATACNT 0x030 | 62 | #define MMCIDATACNT 0x030 |
| 44 | #define MMCISTATUS 0x034 | 63 | #define MMCISTATUS 0x034 |
| @@ -63,6 +82,8 @@ | |||
| 63 | #define MCI_RXFIFOEMPTY (1 << 19) | 82 | #define MCI_RXFIFOEMPTY (1 << 19) |
| 64 | #define MCI_TXDATAAVLBL (1 << 20) | 83 | #define MCI_TXDATAAVLBL (1 << 20) |
| 65 | #define MCI_RXDATAAVLBL (1 << 21) | 84 | #define MCI_RXDATAAVLBL (1 << 21) |
| 85 | #define MCI_SDIOIT (1 << 22) | ||
| 86 | #define MCI_CEATAEND (1 << 23) | ||
| 66 | 87 | ||
| 67 | #define MMCICLEAR 0x038 | 88 | #define MMCICLEAR 0x038 |
| 68 | #define MCI_CMDCRCFAILCLR (1 << 0) | 89 | #define MCI_CMDCRCFAILCLR (1 << 0) |
| @@ -75,6 +96,8 @@ | |||
| 75 | #define MCI_CMDSENTCLR (1 << 7) | 96 | #define MCI_CMDSENTCLR (1 << 7) |
| 76 | #define MCI_DATAENDCLR (1 << 8) | 97 | #define MCI_DATAENDCLR (1 << 8) |
| 77 | #define MCI_DATABLOCKENDCLR (1 << 10) | 98 | #define MCI_DATABLOCKENDCLR (1 << 10) |
| 99 | #define MCI_SDIOITC (1 << 22) | ||
| 100 | #define MCI_CEATAENDC (1 << 23) | ||
| 78 | 101 | ||
| 79 | #define MMCIMASK0 0x03c | 102 | #define MMCIMASK0 0x03c |
| 80 | #define MCI_CMDCRCFAILMASK (1 << 0) | 103 | #define MCI_CMDCRCFAILMASK (1 << 0) |
| @@ -98,6 +121,8 @@ | |||
| 98 | #define MCI_RXFIFOEMPTYMASK (1 << 19) | 121 | #define MCI_RXFIFOEMPTYMASK (1 << 19) |
| 99 | #define MCI_TXDATAAVLBLMASK (1 << 20) | 122 | #define MCI_TXDATAAVLBLMASK (1 << 20) |
| 100 | #define MCI_RXDATAAVLBLMASK (1 << 21) | 123 | #define MCI_RXDATAAVLBLMASK (1 << 21) |
| 124 | #define MCI_SDIOITMASK (1 << 22) | ||
| 125 | #define MCI_CEATAENDMASK (1 << 23) | ||
| 101 | 126 | ||
| 102 | #define MMCIMASK1 0x040 | 127 | #define MMCIMASK1 0x040 |
| 103 | #define MMCIFIFOCNT 0x048 | 128 | #define MMCIFIFOCNT 0x048 |
| @@ -136,6 +161,9 @@ struct mmci_host { | |||
| 136 | u32 pwr; | 161 | u32 pwr; |
| 137 | struct mmc_platform_data *plat; | 162 | struct mmc_platform_data *plat; |
| 138 | 163 | ||
| 164 | u8 hw_designer; | ||
| 165 | u8 hw_revision:4; | ||
| 166 | |||
| 139 | struct timer_list timer; | 167 | struct timer_list timer; |
| 140 | unsigned int oldstat; | 168 | unsigned int oldstat; |
| 141 | 169 | ||
