sdhci.c (271051) | sdhci.c (276287) |
---|---|
1/*- 2 * Copyright (c) 2008 Alexander Motin <mav@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2008 Alexander Motin <mav@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> |
27__FBSDID("$FreeBSD: stable/10/sys/dev/sdhci/sdhci.c 271051 2014-09-03 20:07:26Z marius $"); | 27__FBSDID("$FreeBSD: stable/10/sys/dev/sdhci/sdhci.c 276287 2014-12-27 04:54:36Z ian $"); |
28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/bus.h> 32#include <sys/callout.h> 33#include <sys/conf.h> 34#include <sys/kernel.h> 35#include <sys/lock.h> --- 109 unchanged lines hidden (view full) --- 145 slot_printf(slot, 146 "===========================================\n"); 147} 148 149static void 150sdhci_reset(struct sdhci_slot *slot, uint8_t mask) 151{ 152 int timeout; | 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/bus.h> 32#include <sys/callout.h> 33#include <sys/conf.h> 34#include <sys/kernel.h> 35#include <sys/lock.h> --- 109 unchanged lines hidden (view full) --- 145 slot_printf(slot, 146 "===========================================\n"); 147} 148 149static void 150sdhci_reset(struct sdhci_slot *slot, uint8_t mask) 151{ 152 int timeout; |
153 uint8_t res; | |
154 155 if (slot->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { 156 if (!(RD4(slot, SDHCI_PRESENT_STATE) & 157 SDHCI_CARD_PRESENT)) 158 return; 159 } 160 161 /* Some controllers need this kick or reset won't work. */ 162 if ((mask & SDHCI_RESET_ALL) == 0 && 163 (slot->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)) { 164 uint32_t clock; 165 166 /* This is to force an update */ 167 clock = slot->clock; 168 slot->clock = 0; 169 sdhci_set_clock(slot, clock); 170 } 171 | 153 154 if (slot->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { 155 if (!(RD4(slot, SDHCI_PRESENT_STATE) & 156 SDHCI_CARD_PRESENT)) 157 return; 158 } 159 160 /* Some controllers need this kick or reset won't work. */ 161 if ((mask & SDHCI_RESET_ALL) == 0 && 162 (slot->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)) { 163 uint32_t clock; 164 165 /* This is to force an update */ 166 clock = slot->clock; 167 slot->clock = 0; 168 sdhci_set_clock(slot, clock); 169 } 170 |
172 WR1(slot, SDHCI_SOFTWARE_RESET, mask); 173 | |
174 if (mask & SDHCI_RESET_ALL) { 175 slot->clock = 0; 176 slot->power = 0; 177 } 178 | 171 if (mask & SDHCI_RESET_ALL) { 172 slot->clock = 0; 173 slot->power = 0; 174 } 175 |
176 WR1(slot, SDHCI_SOFTWARE_RESET, mask); 177 178 if (slot->quirks & SDHCI_QUIRK_WAITFOR_RESET_ASSERTED) { 179 /* 180 * Resets on TI OMAPs and AM335x are incompatible with SDHCI 181 * specification. The reset bit has internal propagation delay, 182 * so a fast read after write returns 0 even if reset process is 183 * in progress. The workaround is to poll for 1 before polling 184 * for 0. In the worst case, if we miss seeing it asserted the 185 * time we spent waiting is enough to ensure the reset finishes. 186 */ 187 timeout = 10000; 188 while ((RD1(slot, SDHCI_SOFTWARE_RESET) & mask) != mask) { 189 if (timeout <= 0) 190 break; 191 timeout--; 192 DELAY(1); 193 } 194 } 195 |
|
179 /* Wait max 100 ms */ | 196 /* Wait max 100 ms */ |
180 timeout = 100; | 197 timeout = 10000; |
181 /* Controller clears the bits when it's done */ | 198 /* Controller clears the bits when it's done */ |
182 while ((res = RD1(slot, SDHCI_SOFTWARE_RESET)) & mask) { 183 if (timeout == 0) { 184 slot_printf(slot, 185 "Reset 0x%x never completed - 0x%x.\n", 186 (int)mask, (int)res); | 199 while (RD1(slot, SDHCI_SOFTWARE_RESET) & mask) { 200 if (timeout <= 0) { 201 slot_printf(slot, "Reset 0x%x never completed.\n", 202 mask); |
187 sdhci_dumpregs(slot); 188 return; 189 } 190 timeout--; | 203 sdhci_dumpregs(slot); 204 return; 205 } 206 timeout--; |
191 DELAY(1000); | 207 DELAY(10); |
192 } 193} 194 195static void 196sdhci_init(struct sdhci_slot *slot) 197{ 198 199 sdhci_reset(slot, SDHCI_RESET_ALL); --- 509 unchanged lines hidden (view full) --- 709} 710 711static void 712sdhci_timeout(void *arg) 713{ 714 struct sdhci_slot *slot = arg; 715 716 if (slot->curcmd != NULL) { | 208 } 209} 210 211static void 212sdhci_init(struct sdhci_slot *slot) 213{ 214 215 sdhci_reset(slot, SDHCI_RESET_ALL); --- 509 unchanged lines hidden (view full) --- 725} 726 727static void 728sdhci_timeout(void *arg) 729{ 730 struct sdhci_slot *slot = arg; 731 732 if (slot->curcmd != NULL) { |
733 slot_printf(slot, " Controller timeout\n"); 734 sdhci_dumpregs(slot); |
|
717 sdhci_reset(slot, SDHCI_RESET_CMD|SDHCI_RESET_DATA); 718 slot->curcmd->error = MMC_ERR_TIMEOUT; 719 sdhci_req_done(slot); | 735 sdhci_reset(slot, SDHCI_RESET_CMD|SDHCI_RESET_DATA); 736 slot->curcmd->error = MMC_ERR_TIMEOUT; 737 sdhci_req_done(slot); |
738 } else { 739 slot_printf(slot, " Spurious timeout - no active command\n"); |
|
720 } 721} 722 723static void 724sdhci_set_transfer_mode(struct sdhci_slot *slot, 725 struct mmc_data *data) 726{ 727 uint16_t mode; --- 542 unchanged lines hidden (view full) --- 1270 /* Handle command interrupts. */ 1271 if (intmask & SDHCI_INT_CMD_MASK) { 1272 WR4(slot, SDHCI_INT_STATUS, intmask & SDHCI_INT_CMD_MASK); 1273 sdhci_cmd_irq(slot, intmask & SDHCI_INT_CMD_MASK); 1274 } 1275 /* Handle data interrupts. */ 1276 if (intmask & SDHCI_INT_DATA_MASK) { 1277 WR4(slot, SDHCI_INT_STATUS, intmask & SDHCI_INT_DATA_MASK); | 740 } 741} 742 743static void 744sdhci_set_transfer_mode(struct sdhci_slot *slot, 745 struct mmc_data *data) 746{ 747 uint16_t mode; --- 542 unchanged lines hidden (view full) --- 1290 /* Handle command interrupts. */ 1291 if (intmask & SDHCI_INT_CMD_MASK) { 1292 WR4(slot, SDHCI_INT_STATUS, intmask & SDHCI_INT_CMD_MASK); 1293 sdhci_cmd_irq(slot, intmask & SDHCI_INT_CMD_MASK); 1294 } 1295 /* Handle data interrupts. */ 1296 if (intmask & SDHCI_INT_DATA_MASK) { 1297 WR4(slot, SDHCI_INT_STATUS, intmask & SDHCI_INT_DATA_MASK); |
1278 sdhci_data_irq(slot, intmask & SDHCI_INT_DATA_MASK); | 1298 /* Dont call data_irq in case of errored command */ 1299 if ((intmask & SDHCI_INT_CMD_ERROR_MASK) == 0) 1300 sdhci_data_irq(slot, intmask & SDHCI_INT_DATA_MASK); |
1279 } 1280 /* Handle AutoCMD12 error interrupt. */ 1281 if (intmask & SDHCI_INT_ACMD12ERR) { 1282 WR4(slot, SDHCI_INT_STATUS, SDHCI_INT_ACMD12ERR); 1283 sdhci_acmd_irq(slot); 1284 } 1285 intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK); 1286 intmask &= ~SDHCI_INT_ACMD12ERR; --- 146 unchanged lines hidden --- | 1301 } 1302 /* Handle AutoCMD12 error interrupt. */ 1303 if (intmask & SDHCI_INT_ACMD12ERR) { 1304 WR4(slot, SDHCI_INT_STATUS, SDHCI_INT_ACMD12ERR); 1305 sdhci_acmd_irq(slot); 1306 } 1307 intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK); 1308 intmask &= ~SDHCI_INT_ACMD12ERR; --- 146 unchanged lines hidden --- |