Deleted Added
full compact
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 ---