diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-03-23 20:10:36 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-03-23 20:10:36 -0400 |
| commit | bba1594d348b59d6172e02bf74fba837c8273989 (patch) | |
| tree | 223e67a4ad043d4ec9361e89c59592ea60e7ddff | |
| parent | 9e5ed094c89e55fbf11d2e81d60be98eb12346c0 (diff) | |
| parent | 7437cfa532842ce75189826742bddf1ba137f58e (diff) | |
Merge branch 'mmci' into amba
| -rw-r--r-- | arch/arm/mach-ux500/board-mop500-sdi.c | 21 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.c | 166 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.h | 15 | ||||
| -rw-r--r-- | include/linux/amba/mmci.h | 22 |
4 files changed, 151 insertions, 73 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 23be34b3bb6e..4049bd7f061f 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c | |||
| @@ -31,21 +31,13 @@ | |||
| 31 | * SDI 0 (MicroSD slot) | 31 | * SDI 0 (MicroSD slot) |
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | /* MMCIPOWER bits */ | ||
| 35 | #define MCI_DATA2DIREN (1 << 2) | ||
| 36 | #define MCI_CMDDIREN (1 << 3) | ||
| 37 | #define MCI_DATA0DIREN (1 << 4) | ||
| 38 | #define MCI_DATA31DIREN (1 << 5) | ||
| 39 | #define MCI_FBCLKEN (1 << 7) | ||
| 40 | |||
| 41 | /* GPIO pins used by the sdi0 level shifter */ | 34 | /* GPIO pins used by the sdi0 level shifter */ |
| 42 | static int sdi0_en = -1; | 35 | static int sdi0_en = -1; |
| 43 | static int sdi0_vsel = -1; | 36 | static int sdi0_vsel = -1; |
| 44 | 37 | ||
| 45 | static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, | 38 | static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) |
| 46 | unsigned char power_mode) | ||
| 47 | { | 39 | { |
| 48 | switch (power_mode) { | 40 | switch (ios->power_mode) { |
| 49 | case MMC_POWER_UP: | 41 | case MMC_POWER_UP: |
| 50 | case MMC_POWER_ON: | 42 | case MMC_POWER_ON: |
| 51 | /* | 43 | /* |
| @@ -65,8 +57,7 @@ static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, | |||
| 65 | break; | 57 | break; |
| 66 | } | 58 | } |
| 67 | 59 | ||
| 68 | return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | | 60 | return 0; |
| 69 | MCI_DATA2DIREN | MCI_DATA31DIREN; | ||
| 70 | } | 61 | } |
| 71 | 62 | ||
| 72 | #ifdef CONFIG_STE_DMA40 | 63 | #ifdef CONFIG_STE_DMA40 |
| @@ -90,13 +81,17 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { | |||
| 90 | #endif | 81 | #endif |
| 91 | 82 | ||
| 92 | static struct mmci_platform_data mop500_sdi0_data = { | 83 | static struct mmci_platform_data mop500_sdi0_data = { |
| 93 | .vdd_handler = mop500_sdi0_vdd_handler, | 84 | .ios_handler = mop500_sdi0_ios_handler, |
| 94 | .ocr_mask = MMC_VDD_29_30, | 85 | .ocr_mask = MMC_VDD_29_30, |
| 95 | .f_max = 50000000, | 86 | .f_max = 50000000, |
| 96 | .capabilities = MMC_CAP_4_BIT_DATA | | 87 | .capabilities = MMC_CAP_4_BIT_DATA | |
| 97 | MMC_CAP_SD_HIGHSPEED | | 88 | MMC_CAP_SD_HIGHSPEED | |
| 98 | MMC_CAP_MMC_HIGHSPEED, | 89 | MMC_CAP_MMC_HIGHSPEED, |
| 99 | .gpio_wp = -1, | 90 | .gpio_wp = -1, |
| 91 | .sigdir = MCI_ST_FBCLKEN | | ||
| 92 | MCI_ST_CMDDIREN | | ||
| 93 | MCI_ST_DATA0DIREN | | ||
| 94 | MCI_ST_DATA2DIREN, | ||
| 100 | #ifdef CONFIG_STE_DMA40 | 95 | #ifdef CONFIG_STE_DMA40 |
| 101 | .dma_filter = stedma40_filter, | 96 | .dma_filter = stedma40_filter, |
| 102 | .dma_rx_param = &mop500_sdi0_dma_cfg_rx, | 97 | .dma_rx_param = &mop500_sdi0_dma_cfg_rx, |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 6692392c05dd..deb73e2b7460 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
| @@ -53,6 +53,8 @@ static unsigned int fmax = 515633; | |||
| 53 | * @sdio: variant supports SDIO | 53 | * @sdio: variant supports SDIO |
| 54 | * @st_clkdiv: true if using a ST-specific clock divider algorithm | 54 | * @st_clkdiv: true if using a ST-specific clock divider algorithm |
| 55 | * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register | 55 | * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register |
| 56 | * @pwrreg_powerup: power up value for MMCIPOWER register | ||
| 57 | * @signal_direction: input/out direction of bus signals can be indicated | ||
| 56 | */ | 58 | */ |
| 57 | struct variant_data { | 59 | struct variant_data { |
| 58 | unsigned int clkreg; | 60 | unsigned int clkreg; |
| @@ -63,18 +65,22 @@ struct variant_data { | |||
| 63 | bool sdio; | 65 | bool sdio; |
| 64 | bool st_clkdiv; | 66 | bool st_clkdiv; |
| 65 | bool blksz_datactrl16; | 67 | bool blksz_datactrl16; |
| 68 | u32 pwrreg_powerup; | ||
| 69 | bool signal_direction; | ||
| 66 | }; | 70 | }; |
| 67 | 71 | ||
| 68 | static struct variant_data variant_arm = { | 72 | static struct variant_data variant_arm = { |
| 69 | .fifosize = 16 * 4, | 73 | .fifosize = 16 * 4, |
| 70 | .fifohalfsize = 8 * 4, | 74 | .fifohalfsize = 8 * 4, |
| 71 | .datalength_bits = 16, | 75 | .datalength_bits = 16, |
| 76 | .pwrreg_powerup = MCI_PWR_UP, | ||
| 72 | }; | 77 | }; |
| 73 | 78 | ||
| 74 | static struct variant_data variant_arm_extended_fifo = { | 79 | static struct variant_data variant_arm_extended_fifo = { |
| 75 | .fifosize = 128 * 4, | 80 | .fifosize = 128 * 4, |
| 76 | .fifohalfsize = 64 * 4, | 81 | .fifohalfsize = 64 * 4, |
| 77 | .datalength_bits = 16, | 82 | .datalength_bits = 16, |
| 83 | .pwrreg_powerup = MCI_PWR_UP, | ||
| 78 | }; | 84 | }; |
| 79 | 85 | ||
| 80 | static struct variant_data variant_u300 = { | 86 | static struct variant_data variant_u300 = { |
| @@ -83,6 +89,8 @@ static struct variant_data variant_u300 = { | |||
| 83 | .clkreg_enable = MCI_ST_U300_HWFCEN, | 89 | .clkreg_enable = MCI_ST_U300_HWFCEN, |
| 84 | .datalength_bits = 16, | 90 | .datalength_bits = 16, |
| 85 | .sdio = true, | 91 | .sdio = true, |
| 92 | .pwrreg_powerup = MCI_PWR_ON, | ||
| 93 | .signal_direction = true, | ||
| 86 | }; | 94 | }; |
| 87 | 95 | ||
| 88 | static struct variant_data variant_ux500 = { | 96 | static struct variant_data variant_ux500 = { |
| @@ -93,6 +101,8 @@ static struct variant_data variant_ux500 = { | |||
| 93 | .datalength_bits = 24, | 101 | .datalength_bits = 24, |
| 94 | .sdio = true, | 102 | .sdio = true, |
| 95 | .st_clkdiv = true, | 103 | .st_clkdiv = true, |
| 104 | .pwrreg_powerup = MCI_PWR_ON, | ||
| 105 | .signal_direction = true, | ||
| 96 | }; | 106 | }; |
| 97 | 107 | ||
| 98 | static struct variant_data variant_ux500v2 = { | 108 | static struct variant_data variant_ux500v2 = { |
| @@ -104,11 +114,35 @@ static struct variant_data variant_ux500v2 = { | |||
| 104 | .sdio = true, | 114 | .sdio = true, |
| 105 | .st_clkdiv = true, | 115 | .st_clkdiv = true, |
| 106 | .blksz_datactrl16 = true, | 116 | .blksz_datactrl16 = true, |
| 117 | .pwrreg_powerup = MCI_PWR_ON, | ||
| 118 | .signal_direction = true, | ||
| 107 | }; | 119 | }; |
| 108 | 120 | ||
| 109 | /* | 121 | /* |
| 110 | * This must be called with host->lock held | 122 | * This must be called with host->lock held |
| 111 | */ | 123 | */ |
| 124 | static void mmci_write_clkreg(struct mmci_host *host, u32 clk) | ||
| 125 | { | ||
| 126 | if (host->clk_reg != clk) { | ||
| 127 | host->clk_reg = clk; | ||
| 128 | writel(clk, host->base + MMCICLOCK); | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | /* | ||
| 133 | * This must be called with host->lock held | ||
| 134 | */ | ||
| 135 | static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) | ||
| 136 | { | ||
| 137 | if (host->pwr_reg != pwr) { | ||
| 138 | host->pwr_reg = pwr; | ||
| 139 | writel(pwr, host->base + MMCIPOWER); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | ||
| 144 | * This must be called with host->lock held | ||
| 145 | */ | ||
| 112 | static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) | 146 | static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) |
| 113 | { | 147 | { |
| 114 | struct variant_data *variant = host->variant; | 148 | struct variant_data *variant = host->variant; |
| @@ -153,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) | |||
| 153 | if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) | 187 | if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) |
| 154 | clk |= MCI_ST_8BIT_BUS; | 188 | clk |= MCI_ST_8BIT_BUS; |
| 155 | 189 | ||
| 156 | writel(clk, host->base + MMCICLOCK); | 190 | mmci_write_clkreg(host, clk); |
| 157 | } | 191 | } |
| 158 | 192 | ||
| 159 | static void | 193 | static void |
| @@ -166,14 +200,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) | |||
| 166 | host->mrq = NULL; | 200 | host->mrq = NULL; |
