]> git.ipfire.org Git - thirdparty/qemu.git/blame - hw/sd/sdhci.c
sdhci: rename the hostctl1 register
[thirdparty/qemu.git] / hw / sd / sdhci.c
CommitLineData
d7dfca08
IM
1/*
2 * SD Association Host Standard Specification v2.0 controller emulation
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * Mitsyanko Igor <i.mitsyanko@samsung.com>
6 * Peter A.G. Crosthwaite <peter.crosthwaite@petalogix.com>
7 *
8 * Based on MMC controller for Samsung S5PC1xx-based board emulation
9 * by Alexey Merkulov and Vladimir Monakhov.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 * See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, see <http://www.gnu.org/licenses/>.
23 */
24
0430891c 25#include "qemu/osdep.h"
6ff37c3d 26#include "qemu/error-report.h"
b635d98c 27#include "qapi/error.h"
83c9f4ca 28#include "hw/hw.h"
fa1d36df 29#include "sysemu/block-backend.h"
d7dfca08
IM
30#include "sysemu/blockdev.h"
31#include "sysemu/dma.h"
32#include "qemu/timer.h"
d7dfca08 33#include "qemu/bitops.h"
f82a0f44 34#include "hw/sd/sdhci.h"
637d23be 35#include "sdhci-internal.h"
03dd024f 36#include "qemu/log.h"
bf8ec38e 37#include "qemu/cutils.h"
8be487d8 38#include "trace.h"
d7dfca08 39
40bbc194
PM
40#define TYPE_SDHCI_BUS "sdhci-bus"
41#define SDHCI_BUS(obj) OBJECT_CHECK(SDBus, (obj), TYPE_SDHCI_BUS)
42
aa164fbf
PMD
43#define MASKED_WRITE(reg, mask, val) (reg = (reg & (mask)) | (val))
44
d7dfca08
IM
45/* Default SD/MMC host controller features information, which will be
46 * presented in CAPABILITIES register of generic SD host controller at reset.
aa164fbf
PMD
47 *
48 * support:
49 * - 3.3v and 1.8v voltages
50 * - SDMA/ADMA1/ADMA2
51 * - high-speed
52 * max host controller R/W buffers size: 512B
53 * max clock frequency for SDclock: 52 MHz
54 * timeout clock frequency: 52 MHz
55 *
56 * does not support:
57 * - 3.0v voltage
58 * - 64-bit system bus
59 * - suspend/resume
d7dfca08 60 */
aa164fbf 61#define SDHC_CAPAB_REG_DEFAULT 0x057834b4
d7dfca08 62
09b738ff
PMD
63static inline unsigned int sdhci_get_fifolen(SDHCIState *s)
64{
65 return 1 << (9 + FIELD_EX32(s->capareg, SDHC_CAPAB, MAXBLOCKLENGTH));
66}
67
6ff37c3d
PMD
68/* return true on error */
69static bool sdhci_check_capab_freq_range(SDHCIState *s, const char *desc,
70 uint8_t freq, Error **errp)
71{
4d67852d
PMD
72 if (s->sd_spec_version >= 3) {
73 return false;
74 }
6ff37c3d
PMD
75 switch (freq) {
76 case 0:
77 case 10 ... 63:
78 break;
79 default:
80 error_setg(errp, "SD %s clock frequency can have value"
81 "in range 0-63 only", desc);
82 return true;
83 }
84 return false;
85}
86
87static void sdhci_check_capareg(SDHCIState *s, Error **errp)
88{
89 uint64_t msk = s->capareg;
90 uint32_t val;
91 bool y;
92
93 switch (s->sd_spec_version) {
4d67852d
PMD
94 case 3:
95 val = FIELD_EX64(s->capareg, SDHC_CAPAB, ASYNC_INT);
96 trace_sdhci_capareg("async interrupt", val);
97 msk = FIELD_DP64(msk, SDHC_CAPAB, ASYNC_INT, 0);
98
99 val = FIELD_EX64(s->capareg, SDHC_CAPAB, SLOT_TYPE);
100 if (val) {
101 error_setg(errp, "slot-type not supported");
102 return;
103 }
104 trace_sdhci_capareg("slot type", val);
105 msk = FIELD_DP64(msk, SDHC_CAPAB, SLOT_TYPE, 0);
106
107 if (val != 2) {
108 val = FIELD_EX64(s->capareg, SDHC_CAPAB, EMBEDDED_8BIT);
109 trace_sdhci_capareg("8-bit bus", val);
110 }
111 msk = FIELD_DP64(msk, SDHC_CAPAB, EMBEDDED_8BIT, 0);
112
113 val = FIELD_EX64(s->capareg, SDHC_CAPAB, BUS_SPEED);
114 trace_sdhci_capareg("bus speed mask", val);
115 msk = FIELD_DP64(msk, SDHC_CAPAB, BUS_SPEED, 0);
116
117 val = FIELD_EX64(s->capareg, SDHC_CAPAB, DRIVER_STRENGTH);
118 trace_sdhci_capareg("driver strength mask", val);
119 msk = FIELD_DP64(msk, SDHC_CAPAB, DRIVER_STRENGTH, 0);
120
121 val = FIELD_EX64(s->capareg, SDHC_CAPAB, TIMER_RETUNING);
122 trace_sdhci_capareg("timer re-tuning", val);
123 msk = FIELD_DP64(msk, SDHC_CAPAB, TIMER_RETUNING, 0);
124
125 val = FIELD_EX64(s->capareg, SDHC_CAPAB, SDR50_TUNING);
126 trace_sdhci_capareg("use SDR50 tuning", val);
127 msk = FIELD_DP64(msk, SDHC_CAPAB, SDR50_TUNING, 0);
128
129 val = FIELD_EX64(s->capareg, SDHC_CAPAB, RETUNING_MODE);
130 trace_sdhci_capareg("re-tuning mode", val);
131 msk = FIELD_DP64(msk, SDHC_CAPAB, RETUNING_MODE, 0);
132
133 val = FIELD_EX64(s->capareg, SDHC_CAPAB, CLOCK_MULT);
134 trace_sdhci_capareg("clock multiplier", val);
135 msk = FIELD_DP64(msk, SDHC_CAPAB, CLOCK_MULT, 0);
136
137 /* fallthrough */
6ff37c3d 138 case 2: /* default version */
0540fba9
PMD
139 val = FIELD_EX64(s->capareg, SDHC_CAPAB, ADMA2);
140 trace_sdhci_capareg("ADMA2", val);
141 msk = FIELD_DP64(msk, SDHC_CAPAB, ADMA2, 0);
142
143 val = FIELD_EX64(s->capareg, SDHC_CAPAB, ADMA1);
144 trace_sdhci_capareg("ADMA1", val);
145 msk = FIELD_DP64(msk, SDHC_CAPAB, ADMA1, 0);
146
147 val = FIELD_EX64(s->capareg, SDHC_CAPAB, BUS64BIT);
148 trace_sdhci_capareg("64-bit system bus", val);
149 msk = FIELD_DP64(msk, SDHC_CAPAB, BUS64BIT, 0);
6ff37c3d
PMD
150
151 /* fallthrough */
152 case 1:
153 y = FIELD_EX64(s->capareg, SDHC_CAPAB, TOUNIT);
154 msk = FIELD_DP64(msk, SDHC_CAPAB, TOUNIT, 0);
155
156 val = FIELD_EX64(s->capareg, SDHC_CAPAB, TOCLKFREQ);
157 trace_sdhci_capareg(y ? "timeout (MHz)" : "Timeout (KHz)", val);
158 if (sdhci_check_capab_freq_range(s, "timeout", val, errp)) {
159 return;
160 }
161 msk = FIELD_DP64(msk, SDHC_CAPAB, TOCLKFREQ, 0);
162
163 val = FIELD_EX64(s->capareg, SDHC_CAPAB, BASECLKFREQ);
164 trace_sdhci_capareg(y ? "base (MHz)" : "Base (KHz)", val);
165 if (sdhci_check_capab_freq_range(s, "base", val, errp)) {
166 return;
167 }
168 msk = FIELD_DP64(msk, SDHC_CAPAB, BASECLKFREQ, 0);
169
170 val = FIELD_EX64(s->capareg, SDHC_CAPAB, MAXBLOCKLENGTH);
171 if (val >= 3) {
172 error_setg(errp, "block size can be 512, 1024 or 2048 only");
173 return;
174 }
175 trace_sdhci_capareg("max block length", sdhci_get_fifolen(s));
176 msk = FIELD_DP64(msk, SDHC_CAPAB, MAXBLOCKLENGTH, 0);
177
178 val = FIELD_EX64(s->capareg, SDHC_CAPAB, HIGHSPEED);
179 trace_sdhci_capareg("high speed", val);
180 msk = FIELD_DP64(msk, SDHC_CAPAB, HIGHSPEED, 0);
181
182 val = FIELD_EX64(s->capareg, SDHC_CAPAB, SDMA);
183 trace_sdhci_capareg("SDMA", val);
184 msk = FIELD_DP64(msk, SDHC_CAPAB, SDMA, 0);
185
186 val = FIELD_EX64(s->capareg, SDHC_CAPAB, SUSPRESUME);
187 trace_sdhci_capareg("suspend/resume", val);
188 msk = FIELD_DP64(msk, SDHC_CAPAB, SUSPRESUME, 0);
189
190 val = FIELD_EX64(s->capareg, SDHC_CAPAB, V33);
191 trace_sdhci_capareg("3.3v", val);
192 msk = FIELD_DP64(msk, SDHC_CAPAB, V33, 0);
193
194 val = FIELD_EX64(s->capareg, SDHC_CAPAB, V30);
195 trace_sdhci_capareg("3.0v", val);
196 msk = FIELD_DP64(msk, SDHC_CAPAB, V30, 0);
197
198 val = FIELD_EX64(s->capareg, SDHC_CAPAB, V18);
199 trace_sdhci_capareg("1.8v", val);
200 msk = FIELD_DP64(msk, SDHC_CAPAB, V18, 0);
201 break;
202
203 default:
204 error_setg(errp, "Unsupported spec version: %u", s->sd_spec_version);
205 }
206 if (msk) {
207 qemu_log_mask(LOG_UNIMP,
208 "SDHCI: unknown CAPAB mask: 0x%016" PRIx64 "\n", msk);
209 }
210}
211
d7dfca08
IM
212static uint8_t sdhci_slotint(SDHCIState *s)
213{
214 return (s->norintsts & s->norintsigen) || (s->errintsts & s->errintsigen) ||
215 ((s->norintsts & SDHC_NIS_INSERT) && (s->wakcon & SDHC_WKUP_ON_INS)) ||
216 ((s->norintsts & SDHC_NIS_REMOVE) && (s->wakcon & SDHC_WKUP_ON_RMV));
217}
218
219static inline void sdhci_update_irq(SDHCIState *s)
220{
221 qemu_set_irq(s->irq, sdhci_slotint(s));
222}
223
224static void sdhci_raise_insertion_irq(void *opaque)
225{
226 SDHCIState *s = (SDHCIState *)opaque;
227
228 if (s->norintsts & SDHC_NIS_REMOVE) {
bc72ad67
AB
229 timer_mod(s->insert_timer,
230 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_INSERTION_DELAY);
d7dfca08
IM
231 } else {
232 s->prnsts = 0x1ff0000;
233 if (s->norintstsen & SDHC_NISEN_INSERT) {
234 s->norintsts |= SDHC_NIS_INSERT;
235 }
236 sdhci_update_irq(s);
237 }
238}
239
40bbc194 240static void sdhci_set_inserted(DeviceState *dev, bool level)
d7dfca08 241{
40bbc194 242 SDHCIState *s = (SDHCIState *)dev;
d7dfca08 243
8be487d8 244 trace_sdhci_set_inserted(level ? "insert" : "eject");
d7dfca08
IM
245 if ((s->norintsts & SDHC_NIS_REMOVE) && level) {
246 /* Give target some time to notice card ejection */
bc72ad67
AB
247 timer_mod(s->insert_timer,
248 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_INSERTION_DELAY);
d7dfca08
IM
249 } else {
250 if (level) {
251 s->prnsts = 0x1ff0000;
252 if (s->norintstsen & SDHC_NISEN_INSERT) {
253 s->norintsts |= SDHC_NIS_INSERT;
254 }
255 } else {
256 s->prnsts = 0x1fa0000;
257 s->pwrcon &= ~SDHC_POWER_ON;
258 s->clkcon &= ~SDHC_CLOCK_SDCLK_EN;
259 if (s->norintstsen & SDHC_NISEN_REMOVE) {
260 s->norintsts |= SDHC_NIS_REMOVE;
261 }
262 }
263 sdhci_update_irq(s);
264 }
265}
266
40bbc194 267static void sdhci_set_readonly(DeviceState *dev, bool level)
d7dfca08 268{
40bbc194 269 SDHCIState *s = (SDHCIState *)dev;
d7dfca08
IM
270
271 if (level) {
272 s->prnsts &= ~SDHC_WRITE_PROTECT;
273 } else {
274 /* Write enabled */
275 s->prnsts |= SDHC_WRITE_PROTECT;
276 }
277}
278
279static void sdhci_reset(SDHCIState *s)
280{
40bbc194
PM
281 DeviceState *dev = DEVICE(s);
282
bc72ad67
AB
283 timer_del(s->insert_timer);
284 timer_del(s->transfer_timer);
aceb5b06
PMD
285
286 /* Set all registers to 0. Capabilities/Version registers are not cleared
d7dfca08
IM
287 * and assumed to always preserve their value, given to them during
288 * initialization */
289 memset(&s->sdmasysad, 0, (uintptr_t)&s->capareg - (uintptr_t)&s->sdmasysad);
290
5c1bc9a2
AB
291 /* Reset other state based on current card insertion/readonly status */
292 sdhci_set_inserted(dev, sdbus_get_inserted(&s->sdbus));
293 sdhci_set_readonly(dev, sdbus_get_readonly(&s->sdbus));
40bbc194 294
d7dfca08
IM
295 s->data_count = 0;
296 s->stopped_state = sdhc_not_stopped;
0a7ac9f9 297 s->pending_insert_state = false;
d7dfca08
IM
298}
299
8b41c305
PM
300static void sdhci_poweron_reset(DeviceState *dev)
301{
302 /* QOM (ie power-on) reset. This is identical to reset
303 * commanded via device register apart from handling of the
304 * 'pending insert on powerup' quirk.
305 */
306 SDHCIState *s = (SDHCIState *)dev;
307
308 sdhci_reset(s);
309
310 if (s->pending_insert_quirk) {
311 s->pending_insert_state = true;
312 }
313}
314
d368ba43 315static void sdhci_data_transfer(void *opaque);
d7dfca08
IM
316
317static void sdhci_send_command(SDHCIState *s)
318{
319 SDRequest request;
320 uint8_t response[16];
321 int rlen;
322
323 s->errintsts = 0;
324 s->acmd12errsts = 0;
325 request.cmd = s->cmdreg >> 8;
326 request.arg = s->argument;
8be487d8
PMD
327
328 trace_sdhci_send_command(request.cmd, request.arg);
40bbc194 329 rlen = sdbus_do_command(&s->sdbus, &request, response);
d7dfca08
IM
330
331 if (s->cmdreg & SDHC_CMD_RESPONSE) {
332 if (rlen == 4) {
333 s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |
334 (response[2] << 8) | response[3];
335 s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
8be487d8 336 trace_sdhci_response4(s->rspreg[0]);
d7dfca08
IM
337 } else if (rlen == 16) {
338 s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |
339 (response[13] << 8) | response[14];
340 s->rspreg[1] = (response[7] << 24) | (response[8] << 16) |
341 (response[9] << 8) | response[10];
342 s->rspreg[2] = (response[3] << 24) | (response[4] << 16) |
343 (response[5] << 8) | response[6];
344 s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
345 response[2];
8be487d8
PMD
346 trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
347 s->rspreg[1], s->rspreg[0]);
d7dfca08 348 } else {
8be487d8 349 trace_sdhci_error("timeout waiting for command response");
d7dfca08
IM
350 if (s->errintstsen & SDHC_EISEN_CMDTIMEOUT) {
351 s->errintsts |= SDHC_EIS_CMDTIMEOUT;
352 s->norintsts |= SDHC_NIS_ERR;
353 }
354 }
355
fd1e5c81
AS
356 if (!(s->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
357 (s->norintstsen & SDHC_NISEN_TRSCMP) &&
d7dfca08
IM
358 (s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {
359 s->norintsts |= SDHC_NIS_TRSCMP;
360 }
d7dfca08
IM
361 }
362
363 if (s->norintstsen & SDHC_NISEN_CMDCMP) {
364 s->norintsts |= SDHC_NIS_CMDCMP;
365 }
366
367 sdhci_update_irq(s);
368
369 if (s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) {
656f416c 370 s->data_count = 0;
d368ba43 371 sdhci_data_transfer(s);
d7dfca08
IM
372 }
373}
374
375static void sdhci_end_transfer(SDHCIState *s)
376{
377 /* Automatically send CMD12 to stop transfer if AutoCMD12 enabled */
378 if ((s->trnmod & SDHC_TRNS_ACMD12) != 0) {
379 SDRequest request;
380 uint8_t response[16];
381
382 request.cmd = 0x0C;
383 request.arg = 0;
8be487d8 384 trace_sdhci_end_transfer(request.cmd, request.arg);
40bbc194 385 sdbus_do_command(&s->sdbus, &request, response);
d7dfca08
IM
386 /* Auto CMD12 response goes to the upper Response register */
387 s->rspreg[3] = (response[0] << 24) | (response[1] << 16) |
388 (response[2] << 8) | response[3];
389 }
390
391 s->prnsts &= ~(SDHC_DOING_READ | SDHC_DOING_WRITE |
392 SDHC_DAT_LINE_ACTIVE | SDHC_DATA_INHIBIT |
393 SDHC_SPACE_AVAILABLE | SDHC_DATA_AVAILABLE);
394
395 if (s->norintstsen & SDHC_NISEN_TRSCMP) {
396 s->norintsts |= SDHC_NIS_TRSCMP;
397 }
398
399 sdhci_update_irq(s);
400}
401
402/*
403 * Programmed i/o data transfer
404 */
bf8ec38e 405#define BLOCK_SIZE_MASK (4 * K_BYTE - 1)
d7dfca08
IM
406
407/* Fill host controller's read buffer with BLKSIZE bytes of data from card */
408static void sdhci_read_block_from_card(SDHCIState *s)
409{
410 int index = 0;
411
412 if ((s->trnmod & SDHC_TRNS_MULTI) &&
413 (s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0)) {
414 return;
415 }
416
bf8ec38e 417 for (index = 0; index < (s->blksize & BLOCK_SIZE_MASK); index++) {
40bbc194 418 s->fifo_buffer[index] = sdbus_read_data(&s->sdbus);
d7dfca08
IM
419 }
420
421 /* New data now available for READ through Buffer Port Register */
422 s->prnsts |= SDHC_DATA_AVAILABLE;
423 if (s->norintstsen & SDHC_NISEN_RBUFRDY) {
424 s->norintsts |= SDHC_NIS_RBUFRDY;
425 }
426
427 /* Clear DAT line active status if that was the last block */
428 if ((s->trnmod & SDHC_TRNS_MULTI) == 0 ||
429 ((s->trnmod & SDHC_TRNS_MULTI) && s->blkcnt == 1)) {
430 s->prnsts &= ~SDHC_DAT_LINE_ACTIVE;
431 }
432
433 /* If stop at block gap request was set and it's not the last block of
434 * data - generate Block Event interrupt */
435 if (s->stopped_state == sdhc_gap_read && (s->trnmod & SDHC_TRNS_MULTI) &&
436 s->blkcnt != 1) {
437 s->prnsts &= ~SDHC_DAT_LINE_ACTIVE;
438 if (s->norintstsen & SDHC_EISEN_BLKGAP) {
439 s->norintsts |= SDHC_EIS_BLKGAP;
440 }
441 }
442
443 sdhci_update_irq(s);
444}
445
446/* Read @size byte of data from host controller @s BUFFER DATA PORT register */
447static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
448{
449 uint32_t value = 0;
450 int i;
451
452 /* first check that a valid data exists in host controller input buffer */
453 if ((s->prnsts & SDHC_DATA_AVAILABLE) == 0) {
8be487d8 454 trace_sdhci_error("read from empty buffer");
d7dfca08
IM
455 return 0;
456 }
457
458 for (i = 0; i < size; i++) {
459 value |= s->fifo_buffer[s->data_count] << i * 8;
460 s->data_count++;
461 /* check if we've read all valid data (blksize bytes) from buffer */
bf8ec38e 462 if ((s->data_count) >= (s->blksize & BLOCK_SIZE_MASK)) {
8be487d8 463 trace_sdhci_read_dataport(s->data_count);
d7dfca08
IM
464 s->prnsts &= ~SDHC_DATA_AVAILABLE; /* no more data in a buffer */
465 s->data_count = 0; /* next buff read must start at position [0] */
466
467 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
468 s->blkcnt--;
469 }
470
471 /* if that was the last block of data */
472 if ((s->trnmod & SDHC_TRNS_MULTI) == 0 ||
473 ((s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0)) ||
474 /* stop at gap request */
475 (s->stopped_state == sdhc_gap_read &&
476 !(s->prnsts & SDHC_DAT_LINE_ACTIVE))) {
d368ba43 477 sdhci_end_transfer(s);
d7dfca08 478 } else { /* if there are more data, read next block from card */
d368ba43 479 sdhci_read_block_from_card(s);
d7dfca08
IM
480 }
481 break;
482 }
483 }
484
485 return value;
486}
487
488/* Write data from host controller FIFO to card */
489static void sdhci_write_block_to_card(SDHCIState *s)
490{
491 int index = 0;
492
493 if (s->prnsts & SDHC_SPACE_AVAILABLE) {
494 if (s->norintstsen & SDHC_NISEN_WBUFRDY) {
495 s->norintsts |= SDHC_NIS_WBUFRDY;
496 }
497 sdhci_update_irq(s);
498 return;
499 }
500
501 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
502 if (s->blkcnt == 0) {
503 return;
504 } else {
505 s->blkcnt--;
506 }
507 }
508
bf8ec38e 509 for (index = 0; index < (s->blksize & BLOCK_SIZE_MASK); index++) {
40bbc194 510 sdbus_write_data(&s->sdbus, s->fifo_buffer[index]);
d7dfca08
IM
511 }
512
513 /* Next data can be written through BUFFER DATORT register */
514 s->prnsts |= SDHC_SPACE_AVAILABLE;
d7dfca08
IM
515
516 /* Finish transfer if that was the last block of data */
517 if ((s->trnmod & SDHC_TRNS_MULTI) == 0 ||
518 ((s->trnmod & SDHC_TRNS_MULTI) &&
519 (s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0))) {
d368ba43 520 sdhci_end_transfer(s);
dcdb4cd8
PC
521 } else if (s->norintstsen & SDHC_NISEN_WBUFRDY) {
522 s->norintsts |= SDHC_NIS_WBUFRDY;
d7dfca08
IM
523 }
524
525 /* Generate Block Gap Event if requested and if not the last block */
526 if (s->stopped_state == sdhc_gap_write && (s->trnmod & SDHC_TRNS_MULTI) &&
527 s->blkcnt > 0) {
528 s->prnsts &= ~SDHC_DOING_WRITE;
529 if (s->norintstsen & SDHC_EISEN_BLKGAP) {
530 s->norintsts |= SDHC_EIS_BLKGAP;
531 }
d368ba43 532 sdhci_end_transfer(s);
d7dfca08
IM
533 }
534
535 sdhci_update_irq(s);
536}
537
538/* Write @size bytes of @value data to host controller @s Buffer Data Port
539 * register */
540static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
541{
542 unsigned i;
543
544 /* Check that there is free space left in a buffer */
545 if (!(s->prnsts & SDHC_SPACE_AVAILABLE)) {
8be487d8 546 trace_sdhci_error("Can't write to data buffer: buffer full");
d7dfca08
IM
547 return;
548 }
549
550 for (i = 0; i < size; i++) {
551 s->fifo_buffer[s->data_count] = value & 0xFF;
552 s->data_count++;
553 value >>= 8;
bf8ec38e 554 if (s->data_count >= (s->blksize & BLOCK_SIZE_MASK)) {
8be487d8 555 trace_sdhci_write_dataport(s->data_count);
d7dfca08
IM
556 s->data_count = 0;
557 s->prnsts &= ~SDHC_SPACE_AVAILABLE;
558 if (s->prnsts & SDHC_DOING_WRITE) {
d368ba43 559 sdhci_write_block_to_card(s);
d7dfca08
IM
560 }
561 }
562 }
563}
564
565/*
566 * Single DMA data transfer
567 */
568
569/* Multi block SDMA transfer */
570static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
571{
572 bool page_aligned = false;
573 unsigned int n, begin;
bf8ec38e
PMD
574 const uint16_t block_size = s->blksize & BLOCK_SIZE_MASK;
575 uint32_t boundary_chk = 1 << (((s->blksize & ~BLOCK_SIZE_MASK) >> 12) + 12);
d7dfca08
IM
576 uint32_t boundary_count = boundary_chk - (s->sdmasysad % boundary_chk);
577
6e86d903
PP
578 if (!(s->trnmod & SDHC_TRNS_BLK_CNT_EN) || !s->blkcnt) {
579 qemu_log_mask(LOG_UNIMP, "infinite transfer is not supported\n");
580 return;
581 }
582
d7dfca08
IM
583 /* XXX: Some sd/mmc drivers (for example, u-boot-slp) do not account for
584 * possible stop at page boundary if initial address is not page aligned,
585 * allow them to work properly */
586 if ((s->sdmasysad % boundary_chk) == 0) {
587 page_aligned = true;
588 }
589
590 if (s->trnmod & SDHC_TRNS_READ) {
591 s->prnsts |= SDHC_DOING_READ | SDHC_DATA_INHIBIT |
592 SDHC_DAT_LINE_ACTIVE;
593 while (s->blkcnt) {
594 if (s->data_count == 0) {
595 for (n = 0; n < block_size; n++) {
40bbc194 596 s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);
d7dfca08
IM
597 }
598 }
599 begin = s->data_count;
600 if (((boundary_count + begin) < block_size) && page_aligned) {
601 s->data_count = boundary_count + begin;
602 boundary_count = 0;
603 } else {
604 s->data_count = block_size;
605 boundary_count -= block_size - begin;
606 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
607 s->blkcnt--;
608 }
609 }
dd55c485 610 dma_memory_write(s->dma_as, s->sdmasysad,
d7dfca08
IM
611 &s->fifo_buffer[begin], s->data_count - begin);
612 s->sdmasysad += s->data_count - begin;
613 if (s->data_count == block_size) {
614 s->data_count = 0;
615 }
616 if (page_aligned && boundary_count == 0) {
617 break;
618 }
619 }
620 } else {
621 s->prnsts |= SDHC_DOING_WRITE | SDHC_DATA_INHIBIT |
622 SDHC_DAT_LINE_ACTIVE;
623 while (s->blkcnt) {
624 begin = s->data_count;
625 if (((boundary_count + begin) < block_size) && page_aligned) {
626 s->data_count = boundary_count + begin;
627 boundary_count = 0;
628 } else {
629 s->data_count = block_size;
630 boundary_count -= block_size - begin;
631 }
dd55c485 632 dma_memory_read(s->dma_as, s->sdmasysad,
42922105 633 &s->fifo_buffer[begin], s->data_count - begin);
d7dfca08
IM
634 s->sdmasysad += s->data_count - begin;
635 if (s->data_count == block_size) {
636 for (n = 0; n < block_size; n++) {
40bbc194 637 sdbus_write_data(&s->sdbus, s->fifo_buffer[n]);
d7dfca08
IM
638 }
639 s->data_count = 0;
640 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
641 s->blkcnt--;
642 }
643 }
644 if (page_aligned && boundary_count == 0) {
645 break;
646 }
647 }
648 }
649
650 if (s->blkcnt == 0) {
d368ba43 651 sdhci_end_transfer(s);
d7dfca08
IM
652 } else {
653 if (s->norintstsen & SDHC_NISEN_DMA) {
654 s->norintsts |= SDHC_NIS_DMA;
655 }
656 sdhci_update_irq(s);
657 }
658}
659
660/* single block SDMA transfer */
d7dfca08
IM
661static void sdhci_sdma_transfer_single_block(SDHCIState *s)
662{
663 int n;
bf8ec38e 664 uint32_t datacnt = s->blksize & BLOCK_SIZE_MASK;
d7dfca08
IM
665
666 if (s->trnmod & SDHC_TRNS_READ) {
667 for (n = 0; n < datacnt; n++) {
40bbc194 668 s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);
d7dfca08 669 }
dd55c485 670 dma_memory_write(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
d7dfca08 671 } else {
dd55c485 672 dma_memory_read(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
d7dfca08 673 for (n = 0; n < datacnt; n++) {
40bbc194 674 sdbus_write_data(&s->sdbus, s->fifo_buffer[n]);
d7dfca08
IM
675 }
676 }
241999bf 677 s->blkcnt--;
d7dfca08 678
d368ba43 679 sdhci_end_transfer(s);
d7dfca08
IM
680}
681
682typedef struct ADMADescr {
683 hwaddr addr;
684 uint16_t length;
685 uint8_t attr;
686 uint8_t incr;
687} ADMADescr;
688
689static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
690{
691 uint32_t adma1 = 0;
692 uint64_t adma2 = 0;
693 hwaddr entry_addr = (hwaddr)s->admasysaddr;
06c5120b 694 switch (SDHC_DMA_TYPE(s->hostctl1)) {
d7dfca08 695 case SDHC_CTRL_ADMA2_32:
dd55c485 696 dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma2,
d7dfca08
IM
697 sizeof(adma2));
698 adma2 = le64_to_cpu(adma2);
699 /* The spec does not specify endianness of descriptor table.
700 * We currently assume that it is LE.
701 */
702 dscr->addr = (hwaddr)extract64(adma2, 32, 32) & ~0x3ull;
703 dscr->length = (uint16_t)extract64(adma2, 16, 16);
704 dscr->attr = (uint8_t)extract64(adma2, 0, 7);
705 dscr->incr = 8;
706 break;
707 case SDHC_CTRL_ADMA1_32:
dd55c485 708 dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma1,
d7dfca08
IM
709 sizeof(adma1));
710 adma1 = le32_to_cpu(adma1);
711 dscr->addr = (hwaddr)(adma1 & 0xFFFFF000);
712 dscr->attr = (uint8_t)extract32(adma1, 0, 7);
713 dscr->incr = 4;
714 if ((dscr->attr & SDHC_ADMA_ATTR_ACT_MASK) == SDHC_ADMA_ATTR_SET_LEN) {
715 dscr->length = (uint16_t)extract32(adma1, 12, 16);
716 } else {
717 dscr->length = 4096;
718 }
719 break;
720 case SDHC_CTRL_ADMA2_64:
dd55c485 721 dma_memory_read(s->dma_as, entry_addr,
d7dfca08 722 (uint8_t *)(&dscr->attr), 1);
dd55c485 723 dma_memory_read(s->dma_as, entry_addr + 2,
d7dfca08
IM
724 (uint8_t *)(&dscr->length), 2);
725 dscr->length = le16_to_cpu(dscr->length);
dd55c485 726 dma_memory_read(s->dma_as, entry_addr + 4,
d7dfca08 727 (uint8_t *)(&dscr->addr), 8);
04654b5a
SPB
728 dscr->addr = le64_to_cpu(dscr->addr);
729 dscr->attr &= (uint8_t) ~0xC0;
d7dfca08
IM
730 dscr->incr = 12;
731 break;
732 }
733}
734
735/* Advanced DMA data transfer */
736
737static void sdhci_do_adma(SDHCIState *s)
738{
739 unsigned int n, begin, length;
bf8ec38e 740 const uint16_t block_size = s->blksize & BLOCK_SIZE_MASK;
8be487d8 741 ADMADescr dscr = {};
d7dfca08
IM
742 int i;
743
744 for (i = 0; i < SDHC_ADMA_DESCS_PER_DELAY; ++i) {
745 s->admaerr &= ~SDHC_ADMAERR_LENGTH_MISMATCH;
746
747 get_adma_description(s, &dscr);
8be487d8 748 trace_sdhci_adma_loop(dscr.addr, dscr.length, dscr.attr);
d7dfca08
IM
749
750 if ((dscr.attr & SDHC_ADMA_ATTR_VALID) == 0) {
751 /* Indicate that error occurred in ST_FDS state */
752 s->admaerr &= ~SDHC_ADMAERR_STATE_MASK;
753 s->admaerr |= SDHC_ADMAERR_STATE_ST_FDS;
754
755 /* Generate ADMA error interrupt */
756 if (s->errintstsen & SDHC_EISEN_ADMAERR) {
757 s->errintsts |= SDHC_EIS_ADMAERR;
758 s->norintsts |= SDHC_NIS_ERR;
759 }
760
761 sdhci_update_irq(s);
762 return;
763 }
764
765 length = dscr.length ? dscr.length : 65536;
766
767 switch (dscr.attr & SDHC_ADMA_ATTR_ACT_MASK) {
768 case SDHC_ADMA_ATTR_ACT_TRAN: /* data transfer */
769
770 if (s->trnmod & SDHC_TRNS_READ) {
771 while (length) {
772 if (s->data_count == 0) {
773 for (n = 0; n < block_size; n++) {
40bbc194 774 s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);
d7dfca08
IM
775 }
776 }
777 begin = s->data_count;
778 if ((length + begin) < block_size) {
779 s->data_count = length + begin;
780 length = 0;
781 } else {
782 s->data_count = block_size;
783 length -= block_size - begin;
784 }
dd55c485 785 dma_memory_write(s->dma_as, dscr.addr,
d7dfca08
IM
786 &s->fifo_buffer[begin],
787 s->data_count - begin);
788 dscr.addr += s->data_count - begin;
789 if (s->data_count == block_size) {
790 s->data_count = 0;
791 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
792 s->blkcnt--;
793 if (s->blkcnt == 0) {
794 break;
795 }
796 }
797 }
798 }
799 } else {
800 while (length) {
801 begin = s->data_count;
802 if ((length + begin) < block_size) {
803 s->data_count = length + begin;
804 length = 0;
805 } else {
806 s->data_count = block_size;
807 length -= block_size - begin;
808 }
dd55c485 809 dma_memory_read(s->dma_as, dscr.addr,
9db11cef
PC
810 &s->fifo_buffer[begin],
811 s->data_count - begin);
d7dfca08
IM
812 dscr.addr += s->data_count - begin;
813 if (s->data_count == block_size) {
814 for (n = 0; n < block_size; n++) {
40bbc194 815 sdbus_write_data(&s->sdbus, s->fifo_buffer[n]);
d7dfca08
IM
816 }
817 s->data_count = 0;
818 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
819 s->blkcnt--;
820 if (s->blkcnt == 0) {
821 break;
822 }
823 }
824 }
825 }
826 }
827 s->admasysaddr += dscr.incr;
828 break;
829 case SDHC_ADMA_ATTR_ACT_LINK: /* link to next descriptor table */
830 s->admasysaddr = dscr.addr;
8be487d8 831 trace_sdhci_adma("link", s->admasysaddr);
d7dfca08
IM
832 break;
833 default:
834 s->admasysaddr += dscr.incr;
835 break;
836 }
837
1d32c26f 838 if (dscr.attr & SDHC_ADMA_ATTR_INT) {
8be487d8 839 trace_sdhci_adma("interrupt", s->admasysaddr);
1d32c26f
PC
840 if (s->norintstsen & SDHC_NISEN_DMA) {
841 s->norintsts |= SDHC_NIS_DMA;
842 }
843
844 sdhci_update_irq(s);
845 }
846
d7dfca08
IM
847 /* ADMA transfer terminates if blkcnt == 0 or by END attribute */
848 if (((s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
849 (s->blkcnt == 0)) || (dscr.attr & SDHC_ADMA_ATTR_END)) {
8be487d8 850 trace_sdhci_adma_transfer_completed();
d7dfca08
IM
851 if (length || ((dscr.attr & SDHC_ADMA_ATTR_END) &&
852 (s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
853 s->blkcnt != 0)) {
8be487d8 854 trace_sdhci_error("SD/MMC host ADMA length mismatch");
d7dfca08
IM
855 s->admaerr |= SDHC_ADMAERR_LENGTH_MISMATCH |
856 SDHC_ADMAERR_STATE_ST_TFR;
857 if (s->errintstsen & SDHC_EISEN_ADMAERR) {
8be487d8 858 trace_sdhci_error("Set ADMA error flag");
d7dfca08
IM
859 s->errintsts |= SDHC_EIS_ADMAERR;
860 s->norintsts |= SDHC_NIS_ERR;
861 }
862
863 sdhci_update_irq(s);
864 }
d368ba43 865 sdhci_end_transfer(s);
d7dfca08
IM
866 return;
867 }
868
d7dfca08
IM
869 }
870
085d8134 871 /* we have unfinished business - reschedule to continue ADMA */
bc72ad67
AB
872 timer_mod(s->transfer_timer,
873 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_TRANSFER_DELAY);
d7dfca08
IM
874}
875
876/* Perform data transfer according to controller configuration */
877
d368ba43 878static void sdhci_data_transfer(void *opaque)
d7dfca08 879{
d368ba43 880 SDHCIState *s = (SDHCIState *)opaque;
d7dfca08
IM
881
882 if (s->trnmod & SDHC_TRNS_DMA) {
06c5120b 883 switch (SDHC_DMA_TYPE(s->hostctl1)) {
d7dfca08 884 case SDHC_CTRL_SDMA:
d7dfca08 885 if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) {
d368ba43 886 sdhci_sdma_transfer_single_block(s);
d7dfca08 887 } else {
d368ba43 888 sdhci_sdma_transfer_multi_blocks(s);
d7dfca08
IM
889 }
890
891 break;
892 case SDHC_CTRL_ADMA1_32:
0540fba9 893 if (!(s->capareg & R_SDHC_CAPAB_ADMA1_MASK)) {
8be487d8 894 trace_sdhci_error("ADMA1 not supported");
d7dfca08
IM
895 break;
896 }
897
d368ba43 898 sdhci_do_adma(s);
d7dfca08
IM
899 break;
900 case SDHC_CTRL_ADMA2_32:
0540fba9 901 if (!(s->capareg & R_SDHC_CAPAB_ADMA2_MASK)) {
8be487d8 902 trace_sdhci_error("ADMA2 not supported");
d7dfca08
IM
903 break;
904 }
905
d368ba43 906 sdhci_do_adma(s);
d7dfca08
IM
907 break;
908 case SDHC_CTRL_ADMA2_64:
0540fba9
PMD
909 if (!(s->capareg & R_SDHC_CAPAB_ADMA2_MASK) ||
910 !(s->capareg & R_SDHC_CAPAB_BUS64BIT_MASK)) {
8be487d8 911 trace_sdhci_error("64 bit ADMA not supported");
d7dfca08
IM
912 break;
913 }
914
d368ba43 915 sdhci_do_adma(s);
d7dfca08
IM
916 break;
917 default:
8be487d8 918 trace_sdhci_error("Unsupported DMA type");
d7dfca08
IM
919 break;
920 }
921 } else {
40bbc194 922 if ((s->trnmod & SDHC_TRNS_READ) && sdbus_data_ready(&s->sdbus)) {
d7dfca08
IM
923 s->prnsts |= SDHC_DOING_READ | SDHC_DATA_INHIBIT |
924 SDHC_DAT_LINE_ACTIVE;
d368ba43 925 sdhci_read_block_from_card(s);
d7dfca08
IM
926 } else {
927 s->prnsts |= SDHC_DOING_WRITE | SDHC_DAT_LINE_ACTIVE |
928 SDHC_SPACE_AVAILABLE | SDHC_DATA_INHIBIT;
d368ba43 929 sdhci_write_block_to_card(s);
d7dfca08
IM
930 }
931 }
932}
933
934static bool sdhci_can_issue_command(SDHCIState *s)
935{
6890a695 936 if (!SDHC_CLOCK_IS_ON(s->clkcon) ||
d7dfca08
IM
937 (((s->prnsts & SDHC_DATA_INHIBIT) || s->stopped_state) &&
938 ((s->cmdreg & SDHC_CMD_DATA_PRESENT) ||
939 ((s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY &&
940 !(SDHC_COMMAND_TYPE(s->cmdreg) == SDHC_CMD_ABORT))))) {
941 return false;
942 }
943
944 return true;
945}
946
947/* The Buffer Data Port register must be accessed in sequential and
948 * continuous manner */
949static inline bool
950sdhci_buff_access_is_sequential(SDHCIState *s, unsigned byte_num)
951{
952 if ((s->data_count & 0x3) != byte_num) {
8be487d8
PMD
953 trace_sdhci_error("Non-sequential access to Buffer Data Port register"
954 "is prohibited\n");
d7dfca08
IM
955 return false;
956 }
957 return true;
958}
959
d368ba43 960static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
d7dfca08 961{
d368ba43 962 SDHCIState *s = (SDHCIState *)opaque;
d7dfca08
IM
963 uint32_t ret = 0;
964
965 switch (offset & ~0x3) {
966 case SDHC_SYSAD:
967 ret = s->sdmasysad;
968 break;
969 case SDHC_BLKSIZE:
970 ret = s->blksize | (s->blkcnt << 16);
971 break;
972 case SDHC_ARGUMENT:
973 ret = s->argument;
974 break;
975 case SDHC_TRNMOD:
976 ret = s->trnmod | (s->cmdreg << 16);
977 break;
978 case SDHC_RSPREG0 ... SDHC_RSPREG3:
979 ret = s->rspreg[((offset & ~0x3) - SDHC_RSPREG0) >> 2];
980 break;
981 case SDHC_BDATA:
982 if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
d368ba43 983 ret = sdhci_read_dataport(s, size);
8be487d8 984 trace_sdhci_access("rd", size << 3, offset, "->", ret, ret);
d7dfca08
IM
985 return ret;
986 }
987 break;
988 case SDHC_PRNSTS:
989 ret = s->prnsts;
990 break;
991 case SDHC_HOSTCTL:
06c5120b 992 ret = s->hostctl1 | (s->pwrcon << 8) | (s->blkgap << 16) |
d7dfca08
IM
993 (s->wakcon << 24);
994 break;
995 case SDHC_CLKCON:
996 ret = s->clkcon | (s->timeoutcon << 16);
997 break;
998 case SDHC_NORINTSTS:
999 ret = s->norintsts | (s->errintsts << 16);
1000 break;
1001 case SDHC_NORINTSTSEN:
1002 ret = s->norintstsen | (s->errintstsen << 16);
1003 break;
1004 case SDHC_NORINTSIGEN:
1005 ret = s->norintsigen | (s->errintsigen << 16);
1006 break;
1007 case SDHC_ACMD12ERRSTS:
1008 ret = s->acmd12errsts;
1009 break;
cd209421 1010 case SDHC_CAPAB:
5efc9016
PMD
1011 ret = (uint32_t)s->capareg;
1012 break;
1013 case SDHC_CAPAB + 4:
1014 ret = (uint32_t)(s->capareg >> 32);
d7dfca08
IM
1015 break;
1016 case SDHC_MAXCURR:
5efc9016
PMD
1017 ret = (uint32_t)s->maxcurr;
1018 break;
1019 case SDHC_MAXCURR + 4:
1020 ret = (uint32_t)(s->maxcurr >> 32);
d7dfca08
IM
1021 break;
1022 case SDHC_ADMAERR:
1023 ret = s->admaerr;
1024 break;
1025 case SDHC_ADMASYSADDR:
1026 ret = (uint32_t)s->admasysaddr;
1027 break;
1028 case SDHC_ADMASYSADDR + 4:
1029 ret = (uint32_t)(s->admasysaddr >> 32);
1030 break;
1031 case SDHC_SLOT_INT_STATUS:
aceb5b06 1032 ret = (s->version << 16) | sdhci_slotint(s);
d7dfca08
IM
1033 break;
1034 default:
00b004b3
PMD
1035 qemu_log_mask(LOG_UNIMP, "SDHC rd_%ub @0x%02" HWADDR_PRIx " "
1036 "not implemented\n", size, offset);
d7dfca08
IM
1037 break;
1038 }
1039
1040 ret >>= (offset & 0x3) * 8;
1041 ret &= (1ULL << (size * 8)) - 1;
8be487d8 1042 trace_sdhci_access("rd", size << 3, offset, "->", ret, ret);
d7dfca08
IM
1043 return ret;
1044}
1045
1046static inline void sdhci_blkgap_write(SDHCIState *s, uint8_t value)
1047{
1048 if ((value & SDHC_STOP_AT_GAP_REQ) && (s->blkgap & SDHC_STOP_AT_GAP_REQ)) {
1049 return;
1050 }
1051 s->blkgap = value & SDHC_STOP_AT_GAP_REQ;
1052
1053 if ((value & SDHC_CONTINUE_REQ) && s->stopped_state &&
1054 (s->blkgap & SDHC_STOP_AT_GAP_REQ) == 0) {
1055 if (s->stopped_state == sdhc_gap_read) {
1056 s->prnsts |= SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ;
d368ba43 1057 sdhci_read_block_from_card(s);
d7dfca08
IM
1058 } else {
1059 s->prnsts |= SDHC_DAT_LINE_ACTIVE | SDHC_DOING_WRITE;
d368ba43 1060 sdhci_write_block_to_card(s);
d7dfca08
IM
1061 }
1062 s->stopped_state = sdhc_not_stopped;
1063 } else if (!s->stopped_state && (value & SDHC_STOP_AT_GAP_REQ)) {
1064 if (s->prnsts & SDHC_DOING_READ) {
1065 s->stopped_state = sdhc_gap_read;
1066 } else if (s->prnsts & SDHC_DOING_WRITE) {
1067 s->stopped_state = sdhc_gap_write;
1068 }
1069 }
1070}
1071
1072static inline void sdhci_reset_write(SDHCIState *s, uint8_t value)
1073{
1074 switch (value) {
1075 case SDHC_RESET_ALL:
d368ba43 1076 sdhci_reset(s);
d7dfca08
IM
1077 break;
1078 case SDHC_RESET_CMD:
1079 s->prnsts &= ~SDHC_CMD_INHIBIT;
1080 s->norintsts &= ~SDHC_NIS_CMDCMP;
1081 break;
1082 case SDHC_RESET_DATA:
1083 s->data_count = 0;
1084 s->prnsts &= ~(SDHC_SPACE_AVAILABLE | SDHC_DATA_AVAILABLE |
1085 SDHC_DOING_READ | SDHC_DOING_WRITE |
1086 SDHC_DATA_INHIBIT | SDHC_DAT_LINE_ACTIVE);
1087 s->blkgap &= ~(SDHC_STOP_AT_GAP_REQ | SDHC_CONTINUE_REQ);
1088 s->stopped_state = sdhc_not_stopped;
1089 s->norintsts &= ~(SDHC_NIS_WBUFRDY | SDHC_NIS_RBUFRDY |
1090 SDHC_NIS_DMA | SDHC_NIS_TRSCMP | SDHC_NIS_BLKGAP);
1091 break;
1092 }
1093}
1094
1095static void
d368ba43 1096sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
d7dfca08 1097{
d368ba43 1098 SDHCIState *s = (SDHCIState *)opaque;
d7dfca08
IM
1099 unsigned shift = 8 * (offset & 0x3);
1100 uint32_t mask = ~(((1ULL << (size * 8)) - 1) << shift);
d368ba43 1101 uint32_t value = val;
d7dfca08
IM
1102 value <<= shift;
1103
1104 switch (offset & ~0x3) {
1105 case SDHC_SYSAD:
1106 s->sdmasysad = (s->sdmasysad & mask) | value;
1107 MASKED_WRITE(s->sdmasysad, mask, value);
1108 /* Writing to last byte of sdmasysad might trigger transfer */
1109 if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt &&
06c5120b 1110 s->blksize && SDHC_DMA_TYPE(s->hostctl1) == SDHC_CTRL_SDMA) {
45ba9f76
PP
1111 if (s->trnmod & SDHC_TRNS_MULTI) {
1112 sdhci_sdma_transfer_multi_blocks(s);
1113 } else {
1114 sdhci_sdma_transfer_single_block(s);
1115 }
d7dfca08
IM
1116 }
1117 break;
1118 case SDHC_BLKSIZE:
1119 if (!TRANSFERRING_DATA(s->prnsts)) {
1120 MASKED_WRITE(s->blksize, mask, value);
1121 MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16);
1122 }
9201bb9a
AF
1123
1124 /* Limit block size to the maximum buffer size */
1125 if (extract32(s->blksize, 0, 12) > s->buf_maxsz) {
1126 qemu_log_mask(LOG_GUEST_ERROR, "%s: Size 0x%x is larger than " \
1127 "the maximum buffer 0x%x", __func__, s->blksize,
1128 s->buf_maxsz);
1129
1130 s->blksize = deposit32(s->blksize, 0, 12, s->buf_maxsz);
1131 }
1132
d7dfca08
IM
1133 break;
1134 case SDHC_ARGUMENT:
1135 MASKED_WRITE(s->argument, mask, value);
1136 break;
1137 case SDHC_TRNMOD:
1138 /* DMA can be enabled only if it is supported as indicated by
1139 * capabilities register */
6ff37c3d 1140 if (!(s->capareg & R_SDHC_CAPAB_SDMA_MASK)) {
d7dfca08
IM
1141 value &= ~SDHC_TRNS_DMA;
1142 }
24bddf9d 1143 MASKED_WRITE(s->trnmod, mask, value & SDHC_TRNMOD_MASK);
d7dfca08
IM
1144 MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);
1145
1146 /* Writing to the upper byte of CMDREG triggers SD command generation */
d368ba43 1147 if ((mask & 0xFF000000) || !sdhci_can_issue_command(s)) {
d7dfca08
IM
1148 break;
1149 }
1150
d368ba43 1151 sdhci_send_command(s);
d7dfca08
IM
1152 break;
1153 case SDHC_BDATA:
1154 if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
d368ba43 1155 sdhci_write_dataport(s, value >> shift, size);
d7dfca08
IM
1156 }
1157 break;
1158 case SDHC_HOSTCTL:
1159 if (!(mask & 0xFF0000)) {
1160 sdhci_blkgap_write(s, value >> 16);
1161 }
06c5120b 1162 MASKED_WRITE(s->hostctl1, mask, value);
d7dfca08
IM
1163 MASKED_WRITE(s->pwrcon, mask >> 8, value >> 8);
1164 MASKED_WRITE(s->wakcon, mask >> 24, value >> 24);
1165 if (!(s->prnsts & SDHC_CARD_PRESENT) || ((s->pwrcon >> 1) & 0x7) < 5 ||
1166 !(s->capareg & (1 << (31 - ((s->pwrcon >> 1) & 0x7))))) {
1167 s->pwrcon &= ~SDHC_POWER_ON;
1168 }
1169 break;
1170 case SDHC_CLKCON:
1171 if (!(mask & 0xFF000000)) {
1172 sdhci_reset_write(s, value >> 24);
1173 }
1174 MASKED_WRITE(s->clkcon, mask, value);
1175 MASKED_WRITE(s->timeoutcon, mask >> 16, value >> 16);
1176 if (s->clkcon & SDHC_CLOCK_INT_EN) {
1177 s->clkcon |= SDHC_CLOCK_INT_STABLE;
1178 } else {
1179 s->clkcon &= ~SDHC_CLOCK_INT_STABLE;
1180 }
1181 break;
1182 case SDHC_NORINTSTS:
1183 if (s->norintstsen & SDHC_NISEN_CARDINT) {
1184 value &= ~SDHC_NIS_CARDINT;
1185 }
1186 s->norintsts &= mask | ~value;
1187 s->errintsts &= (mask >> 16) | ~(value >> 16);
1188 if (s->errintsts) {
1189 s->norintsts |= SDHC_NIS_ERR;
1190 } else {
1191 s->norintsts &= ~SDHC_NIS_ERR;
1192 }
1193 sdhci_update_irq(s);
1194 break;
1195 case SDHC_NORINTSTSEN:
1196 MASKED_WRITE(s->norintstsen, mask, value);
1197 MASKED_WRITE(s->errintstsen, mask >> 16, value >> 16);
1198 s->norintsts &= s->norintstsen;
1199 s->errintsts &= s->errintstsen;
1200 if (s->errintsts) {
1201 s->norintsts |= SDHC_NIS_ERR;
1202 } else {
1203 s->norintsts &= ~SDHC_NIS_ERR;
1204 }
0a7ac9f9
AB
1205 /* Quirk for Raspberry Pi: pending card insert interrupt
1206 * appears when first enabled after power on */
1207 if ((s->norintstsen & SDHC_NISEN_INSERT) && s->pending_insert_state) {
1208 assert(s->pending_insert_quirk);
1209 s->norintsts |= SDHC_NIS_INSERT;
1210 s->pending_insert_state = false;
1211 }
d7dfca08
IM
1212 sdhci_update_irq(s);
1213 break;
1214 case SDHC_NORINTSIGEN:
1215 MASKED_WRITE(s->norintsigen, mask, value);
1216 MASKED_WRITE(s->errintsigen, mask >> 16, value >> 16);
1217 sdhci_update_irq(s);
1218 break;
1219 case SDHC_ADMAERR:
1220 MASKED_WRITE(s->admaerr, mask, value);
1221 break;
1222 case SDHC_ADMASYSADDR:
1223 s->admasysaddr = (s->admasysaddr & (0xFFFFFFFF00000000ULL |
1224 (uint64_t)mask)) | (uint64_t)value;
1225 break;
1226 case SDHC_ADMASYSADDR + 4:
1227 s->admasysaddr = (s->admasysaddr & (0x00000000FFFFFFFFULL |
1228 ((uint64_t)mask << 32))) | ((uint64_t)value << 32);
1229 break;
1230 case SDHC_FEAER:
1231 s->acmd12errsts |= value;
1232 s->errintsts |= (value >> 16) & s->errintstsen;
1233 if (s->acmd12errsts) {
1234 s->errintsts |= SDHC_EIS_CMD12ERR;
1235 }
1236 if (s->errintsts) {
1237 s->norintsts |= SDHC_NIS_ERR;
1238 }
1239 sdhci_update_irq(s);
1240 break;
5d2c0464
AS
1241 case SDHC_ACMD12ERRSTS:
1242 MASKED_WRITE(s->acmd12errsts, mask, value);
1243 break;
5efc9016
PMD
1244
1245 case SDHC_CAPAB:
1246 case SDHC_CAPAB + 4:
1247 case SDHC_MAXCURR:
1248 case SDHC_MAXCURR + 4:
1249 qemu_log_mask(LOG_GUEST_ERROR, "SDHC wr_%ub @0x%02" HWADDR_PRIx
1250 " <- 0x%08x read-only\n", size, offset, value >> shift);
1251 break;
1252
d7dfca08 1253 default:
00b004b3
PMD
1254 qemu_log_mask(LOG_UNIMP, "SDHC wr_%ub @0x%02" HWADDR_PRIx " <- 0x%08x "
1255 "not implemented\n", size, offset, value >> shift);
d7dfca08
IM
1256 break;
1257 }
8be487d8
PMD
1258 trace_sdhci_access("wr", size << 3, offset, "<-",
1259 value >> shift, value >> shift);
d7dfca08
IM
1260}
1261
1262static const MemoryRegionOps sdhci_mmio_ops = {
d368ba43
KC
1263 .read = sdhci_read,
1264 .write = sdhci_write,
d7dfca08
IM
1265 .valid = {
1266 .min_access_size = 1,
1267 .max_access_size = 4,
1268 .unaligned = false
1269 },
1270 .endianness = DEVICE_LITTLE_ENDIAN,
1271};
1272
aceb5b06
PMD
1273static void sdhci_init_readonly_registers(SDHCIState *s, Error **errp)
1274{
6ff37c3d
PMD
1275 Error *local_err = NULL;
1276
4d67852d
PMD
1277 switch (s->sd_spec_version) {
1278 case 2 ... 3:
1279 break;
1280 default:
1281 error_setg(errp, "Only Spec v2/v3 are supported");
aceb5b06
PMD
1282 return;
1283 }
1284 s->version = (SDHC_HCVER_VENDOR << 8) | (s->sd_spec_version - 1);
6ff37c3d
PMD
1285
1286 sdhci_check_capareg(s, &local_err);
1287 if (local_err) {
1288 error_propagate(errp, local_err);
1289 return;
1290 }
aceb5b06
PMD
1291}
1292
b635d98c
PMD
1293/* --- qdev common --- */
1294
1295#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \
aceb5b06
PMD
1296 DEFINE_PROP_UINT8("sd-spec-version", _state, sd_spec_version, 2), \
1297 \
1298 /* Capabilities registers provide information on supported
1299 * features of this specific host controller implementation */ \
5efc9016
PMD
1300 DEFINE_PROP_UINT64("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \
1301 DEFINE_PROP_UINT64("maxcurr", _state, maxcurr, 0)
b635d98c 1302
40bbc194 1303static void sdhci_initfn(SDHCIState *s)
d7dfca08 1304{
40bbc194
PM
1305 qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
1306 TYPE_SDHCI_BUS, DEVICE(s), "sd-bus");
d7dfca08 1307
bc72ad67 1308 s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
d368ba43 1309 s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
fd1e5c81
AS
1310
1311 s->io_ops = &sdhci_mmio_ops;
d7dfca08
IM
1312}
1313
7302dcd6 1314static void sdhci_uninitfn(SDHCIState *s)
d7dfca08 1315{
bc72ad67
AB
1316 timer_del(s->insert_timer);
1317 timer_free(s->insert_timer);
1318 timer_del(s->transfer_timer);
1319 timer_free(s->transfer_timer);
d7dfca08 1320
012aef07
MA
1321 g_free(s->fifo_buffer);
1322 s->fifo_buffer = NULL;
d7dfca08
IM
1323}
1324
25367498
PMD
1325static void sdhci_common_realize(SDHCIState *s, Error **errp)
1326{
aceb5b06
PMD
1327 Error *local_err = NULL;
1328
1329 sdhci_init_readonly_registers(s, &local_err);
1330 if (local_err) {
1331 error_propagate(errp, local_err);
1332 return;
1333 }
25367498
PMD
1334 s->buf_maxsz = sdhci_get_fifolen(s);
1335 s->fifo_buffer = g_malloc0(s->buf_maxsz);
1336
1337 memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
1338 SDHC_REGISTERS_MAP_SIZE);
1339}
1340
8b7455c7
PMD
1341static void sdhci_common_unrealize(SDHCIState *s, Error **errp)
1342{
1343 /* This function is expected to be called only once for each class:
1344 * - SysBus: via DeviceClass->unrealize(),
1345 * - PCI: via PCIDeviceClass->exit().
1346 * However to avoid double-free and/or use-after-free we still nullify
1347 * this variable (better safe than sorry!). */
1348 g_free(s->fifo_buffer);
1349 s->fifo_buffer = NULL;
1350}
1351
0a7ac9f9
AB
1352static bool sdhci_pending_insert_vmstate_needed(void *opaque)
1353{
1354 SDHCIState *s = opaque;
1355
1356 return s->pending_insert_state;
1357}
1358
1359static const VMStateDescription sdhci_pending_insert_vmstate = {
1360 .name = "sdhci/pending-insert",
1361 .version_id = 1,
1362 .minimum_version_id = 1,
1363 .needed = sdhci_pending_insert_vmstate_needed,
1364 .fields = (VMStateField[]) {
1365 VMSTATE_BOOL(pending_insert_state, SDHCIState),
1366 VMSTATE_END_OF_LIST()
1367 },
1368};
1369
d7dfca08
IM
1370const VMStateDescription sdhci_vmstate = {
1371 .name = "sdhci",
1372 .version_id = 1,
1373 .minimum_version_id = 1,
35d08458 1374 .fields = (VMStateField[]) {
d7dfca08
IM
1375 VMSTATE_UINT32(sdmasysad, SDHCIState),
1376 VMSTATE_UINT16(blksize, SDHCIState),
1377 VMSTATE_UINT16(blkcnt, SDHCIState),
1378 VMSTATE_UINT32(argument, SDHCIState),
1379 VMSTATE_UINT16(trnmod, SDHCIState),
1380 VMSTATE_UINT16(cmdreg, SDHCIState),
1381 VMSTATE_UINT32_ARRAY(rspreg, SDHCIState, 4),
1382 VMSTATE_UINT32(prnsts, SDHCIState),
06c5120b 1383 VMSTATE_UINT8(hostctl1, SDHCIState),
d7dfca08
IM
1384 VMSTATE_UINT8(pwrcon, SDHCIState),
1385 VMSTATE_UINT8(blkgap, SDHCIState),
1386 VMSTATE_UINT8(wakcon, SDHCIState),
1387 VMSTATE_UINT16(clkcon, SDHCIState),
1388 VMSTATE_UINT8(timeoutcon, SDHCIState),
1389 VMSTATE_UINT8(admaerr, SDHCIState),
1390 VMSTATE_UINT16(norintsts, SDHCIState),
1391 VMSTATE_UINT16(errintsts, SDHCIState),
1392 VMSTATE_UINT16(norintstsen, SDHCIState),
1393 VMSTATE_UINT16(errintstsen, SDHCIState),
1394 VMSTATE_UINT16(norintsigen, SDHCIState),
1395 VMSTATE_UINT16(errintsigen, SDHCIState),
1396 VMSTATE_UINT16(acmd12errsts, SDHCIState),
1397 VMSTATE_UINT16(data_count, SDHCIState),
1398 VMSTATE_UINT64(admasysaddr, SDHCIState),
1399 VMSTATE_UINT8(stopped_state, SDHCIState),
59046ec2 1400 VMSTATE_VBUFFER_UINT32(fifo_buffer, SDHCIState, 1, NULL, buf_maxsz),
e720677e
PB
1401 VMSTATE_TIMER_PTR(insert_timer, SDHCIState),
1402 VMSTATE_TIMER_PTR(transfer_timer, SDHCIState),
d7dfca08 1403 VMSTATE_END_OF_LIST()
0a7ac9f9
AB
1404 },
1405 .subsections = (const VMStateDescription*[]) {
1406 &sdhci_pending_insert_vmstate,
1407 NULL
1408 },
d7dfca08
IM
1409};
1410
1c92c505
PMD
1411static void sdhci_common_class_init(ObjectClass *klass, void *data)
1412{
1413 DeviceClass *dc = DEVICE_CLASS(klass);
1414
1415 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1416 dc->vmsd = &sdhci_vmstate;
1417 dc->reset = sdhci_poweron_reset;
1418}
1419
b635d98c
PMD
1420/* --- qdev PCI --- */
1421
5ec911c3 1422static Property sdhci_pci_properties[] = {
b635d98c 1423 DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
d7dfca08
IM
1424 DEFINE_PROP_END_OF_LIST(),
1425};
1426
9af21dbe 1427static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
224d10ff
KC
1428{
1429 SDHCIState *s = PCI_SDHCI(dev);
ab958e38 1430 Error *local_err = NULL;
25367498
PMD
1431
1432 sdhci_initfn(s);
1433 sdhci_common_realize(s, errp);
ab958e38
PMD
1434 if (local_err) {
1435 error_propagate(errp, local_err);
25367498
PMD
1436 return;
1437 }
1438
224d10ff
KC
1439 dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */
1440 dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
224d10ff 1441 s->irq = pci_allocate_irq(dev);
dd55c485
PMD
1442 s->dma_as = pci_get_address_space(dev);
1443 pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->iomem);
224d10ff
KC
1444}
1445
1446static void sdhci_pci_exit(PCIDevice *dev)
1447{
1448 SDHCIState *s = PCI_SDHCI(dev);
8b7455c7
PMD
1449
1450 sdhci_common_unrealize(s, &error_abort);
224d10ff
KC
1451 sdhci_uninitfn(s);
1452}
1453
1454static void sdhci_pci_class_init(ObjectClass *klass, void *data)
1455{
1456 DeviceClass *dc = DEVICE_CLASS(klass);
1457 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1458
9af21dbe 1459 k->realize = sdhci_pci_realize;
224d10ff
KC
1460 k->exit = sdhci_pci_exit;
1461 k->vendor_id = PCI_VENDOR_ID_REDHAT;
1462 k->device_id = PCI_DEVICE_ID_REDHAT_SDHCI;
1463 k->class_id = PCI_CLASS_SYSTEM_SDHCI;
5ec911c3 1464 dc->props = sdhci_pci_properties;
1c92c505
PMD
1465
1466 sdhci_common_class_init(klass, data);
224d10ff
KC
1467}
1468
1469static const TypeInfo sdhci_pci_info = {
1470 .name = TYPE_PCI_SDHCI,
1471 .parent = TYPE_PCI_DEVICE,
1472 .instance_size = sizeof(SDHCIState),
1473 .class_init = sdhci_pci_class_init,
fd3b02c8
EH
1474 .interfaces = (InterfaceInfo[]) {
1475 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
1476 { },
1477 },
224d10ff
KC
1478};
1479
b635d98c
PMD
1480/* --- qdev SysBus --- */
1481
5ec911c3 1482static Property sdhci_sysbus_properties[] = {
b635d98c 1483 DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
0a7ac9f9
AB
1484 DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk,
1485 false),
60765b6c
PMD
1486 DEFINE_PROP_LINK("dma", SDHCIState,
1487 dma_mr, TYPE_MEMORY_REGION, MemoryRegion *),
5ec911c3
KC
1488 DEFINE_PROP_END_OF_LIST(),
1489};
1490
7302dcd6
KC
1491static void sdhci_sysbus_init(Object *obj)
1492{
1493 SDHCIState *s = SYSBUS_SDHCI(obj);
5ec911c3 1494
40bbc194 1495 sdhci_initfn(s);
7302dcd6
KC
1496}
1497
1498static void sdhci_sysbus_finalize(Object *obj)
1499{
1500 SDHCIState *s = SYSBUS_SDHCI(obj);
60765b6c
PMD
1501
1502 if (s->dma_mr) {
1503 object_unparent(OBJECT(s->dma_mr));
1504 }
1505
7302dcd6
KC
1506 sdhci_uninitfn(s);
1507}
1508
1509static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
d7dfca08 1510{
7302dcd6 1511 SDHCIState *s = SYSBUS_SDHCI(dev);
d7dfca08 1512 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
ab958e38 1513 Error *local_err = NULL;
d7dfca08 1514
25367498 1515 sdhci_common_realize(s, errp);
ab958e38
PMD
1516 if (local_err) {
1517 error_propagate(errp, local_err);
25367498
PMD
1518 return;
1519 }
1520
60765b6c 1521 if (s->dma_mr) {
02e57e1c 1522 s->dma_as = &s->sysbus_dma_as;
60765b6c
PMD
1523 address_space_init(s->dma_as, s->dma_mr, "sdhci-dma");
1524 } else {
1525 /* use system_memory() if property "dma" not set */
1526 s->dma_as = &address_space_memory;
1527 }
dd55c485 1528
d7dfca08 1529 sysbus_init_irq(sbd, &s->irq);
fd1e5c81
AS
1530
1531 memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s, "sdhci",
1532 SDHC_REGISTERS_MAP_SIZE);
1533
d7dfca08
IM
1534 sysbus_init_mmio(sbd, &s->iomem);
1535}
1536
8b7455c7
PMD
1537static void sdhci_sysbus_unrealize(DeviceState *dev, Error **errp)
1538{
1539 SDHCIState *s = SYSBUS_SDHCI(dev);
1540
1541 sdhci_common_unrealize(s, &error_abort);
60765b6c
PMD
1542
1543 if (s->dma_mr) {
1544 address_space_destroy(s->dma_as);
1545 }
8b7455c7
PMD
1546}
1547
7302dcd6 1548static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
d7dfca08
IM
1549{
1550 DeviceClass *dc = DEVICE_CLASS(klass);
d7dfca08 1551
5ec911c3 1552 dc->props = sdhci_sysbus_properties;
7302dcd6 1553 dc->realize = sdhci_sysbus_realize;
8b7455c7 1554 dc->unrealize = sdhci_sysbus_unrealize;
1c92c505
PMD
1555
1556 sdhci_common_class_init(klass, data);
d7dfca08
IM
1557}
1558
7302dcd6
KC
1559static const TypeInfo sdhci_sysbus_info = {
1560 .name = TYPE_SYSBUS_SDHCI,
d7dfca08
IM
1561 .parent = TYPE_SYS_BUS_DEVICE,
1562 .instance_size = sizeof(SDHCIState),
7302dcd6
KC
1563 .instance_init = sdhci_sysbus_init,
1564 .instance_finalize = sdhci_sysbus_finalize,
1565 .class_init = sdhci_sysbus_class_init,
d7dfca08
IM
1566};
1567
b635d98c
PMD
1568/* --- qdev bus master --- */
1569
40bbc194
PM
1570static void sdhci_bus_class_init(ObjectClass *klass, void *data)
1571{
1572 SDBusClass *sbc = SD_BUS_CLASS(klass);
1573
1574 sbc->set_inserted = sdhci_set_inserted;
1575 sbc->set_readonly = sdhci_set_readonly;
1576}
1577
1578static const TypeInfo sdhci_bus_info = {
1579 .name = TYPE_SDHCI_BUS,
1580 .parent = TYPE_SD_BUS,
1581 .instance_size = sizeof(SDBus),
1582 .class_init = sdhci_bus_class_init,
1583};
1584
fd1e5c81
AS
1585static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
1586{
1587 SDHCIState *s = SYSBUS_SDHCI(opaque);
1588 uint32_t ret;
06c5120b 1589 uint16_t hostctl1;
fd1e5c81
AS
1590
1591 switch (offset) {
1592 default:
1593 return sdhci_read(opaque, offset, size);
1594
1595 case SDHC_HOSTCTL:
1596 /*
1597 * For a detailed explanation on the following bit
1598 * manipulation code see comments in a similar part of
1599 * usdhc_write()
1600 */
06c5120b 1601 hostctl1 = SDHC_DMA_TYPE(s->hostctl1) << (8 - 3);
fd1e5c81 1602
06c5120b
PMD
1603 if (s->hostctl1 & SDHC_CTRL_8BITBUS) {
1604 hostctl1 |= ESDHC_CTRL_8BITBUS;
fd1e5c81
AS
1605 }
1606
06c5120b
PMD
1607 if (s->hostctl1 & SDHC_CTRL_4BITBUS) {
1608 hostctl1 |= ESDHC_CTRL_4BITBUS;
fd1e5c81
AS
1609 }
1610
06c5120b 1611 ret = hostctl1;
fd1e5c81
AS
1612 ret |= (uint32_t)s->blkgap << 16;
1613 ret |= (uint32_t)s->wakcon << 24;
1614
1615 break;
1616
1617 case ESDHC_DLL_CTRL:
1618 case ESDHC_TUNE_CTRL_STATUS:
1619 case ESDHC_UNDOCUMENTED_REG27:
1620 case ESDHC_TUNING_CTRL:
1621 case ESDHC_VENDOR_SPEC:
1622 case ESDHC_MIX_CTRL:
1623 case ESDHC_WTMK_LVL:
1624 ret = 0;
1625 break;
1626 }
1627
1628 return ret;
1629}
1630
1631static void
1632usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
1633{
1634 SDHCIState *s = SYSBUS_SDHCI(opaque);
06c5120b 1635 uint8_t hostctl1;
fd1e5c81
AS
1636 uint32_t value = (uint32_t)val;
1637
1638 switch (offset) {
1639 case ESDHC_DLL_CTRL:
1640 case ESDHC_TUNE_CTRL_STATUS:
1641 case ESDHC_UNDOCUMENTED_REG27:
1642 case ESDHC_TUNING_CTRL:
1643 case ESDHC_WTMK_LVL:
1644 case ESDHC_VENDOR_SPEC:
1645 break;
1646
1647 case SDHC_HOSTCTL:
1648 /*
1649 * Here's What ESDHCI has at offset 0x28 (SDHC_HOSTCTL)
1650 *
1651 * 7 6 5 4 3 2 1 0
1652 * |-----------+--------+--------+-----------+----------+---------|
1653 * | Card | Card | Endian | DATA3 | Data | Led |
1654 * | Detect | Detect | Mode | as Card | Transfer | Control |
1655 * | Signal | Test | | Detection | Width | |
1656 * | Selection | Level | | Pin | | |
1657 * |-----------+--------+--------+-----------+----------+---------|
1658 *
1659 * and 0x29
1660 *
1661 * 15 10 9 8
1662 * |----------+------|
1663 * | Reserved | DMA |
1664 * | | Sel. |
1665 * | | |
1666 * |----------+------|
1667 *
1668 * and here's what SDCHI spec expects those offsets to be:
1669 *
1670 * 0x28 (Host Control Register)
1671 *
1672 * 7 6 5 4 3 2 1 0
1673 * |--------+--------+----------+------+--------+----------+---------|
1674 * | Card | Card | Extended | DMA | High | Data | LED |
1675 * | Detect | Detect | Data | Sel. | Speed | Transfer | Control |
1676 * | Signal | Test | Transfer | | Enable | Width | |
1677 * | Sel. | Level | Width | | | | |
1678 * |--------+--------+----------+------+--------+----------+---------|
1679 *
1680 * and 0x29 (Power Control Register)
1681 *
1682 * |----------------------------------|
1683 * | Power Control Register |
1684 * | |
1685 * | Description omitted, |
1686 * | since it has no analog in ESDHCI |
1687 * | |
1688 * |----------------------------------|
1689 *
1690 * Since offsets 0x2A and 0x2B should be compatible between
1691 * both IP specs we only need to reconcile least 16-bit of the
1692 * word we've been given.
1693 */
1694
1695 /*
1696 * First, save bits 7 6 and 0 since they are identical
1697 */
06c5120b
PMD
1698 hostctl1 = value & (SDHC_CTRL_LED |
1699 SDHC_CTRL_CDTEST_INS |
1700 SDHC_CTRL_CDTEST_EN);
fd1e5c81
AS
1701 /*
1702 * Second, split "Data Transfer Width" from bits 2 and 1 in to
1703 * bits 5 and 1
1704 */
1705 if (value & ESDHC_CTRL_8BITBUS) {
06c5120b 1706 hostctl1 |= SDHC_CTRL_8BITBUS;
fd1e5c81
AS
1707 }
1708
1709 if (value & ESDHC_CTRL_4BITBUS) {
06c5120b 1710 hostctl1 |= ESDHC_CTRL_4BITBUS;
fd1e5c81
AS
1711 }
1712
1713 /*
1714 * Third, move DMA select from bits 9 and 8 to bits 4 and 3
1715 */
06c5120b 1716 hostctl1 |= SDHC_DMA_TYPE(value >> (8 - 3));
fd1e5c81
AS
1717
1718 /*
1719 * Now place the corrected value into low 16-bit of the value
1720 * we are going to give standard SDHCI write function
1721 *
1722 * NOTE: This transformation should be the inverse of what can
1723 * be found in drivers/mmc/host/sdhci-esdhc-imx.c in Linux
1724 * kernel
1725 */
1726 value &= ~UINT16_MAX;
06c5120b 1727 value |= hostctl1;
fd1e5c81
AS
1728 value |= (uint16_t)s->pwrcon << 8;
1729
1730 sdhci_write(opaque, offset, value, size);
1731 break;
1732
1733 case ESDHC_MIX_CTRL:
1734 /*
1735 * So, when SD/MMC stack in Linux tries to write to "Transfer
1736 * Mode Register", ESDHC i.MX quirk code will translate it
1737 * into a write to ESDHC_MIX_CTRL, so we do the opposite in
1738 * order to get where we started
1739 *
1740 * Note that Auto CMD23 Enable bit is located in a wrong place
1741 * on i.MX, but since it is not used by QEMU we do not care.
1742 *
1743 * We don't want to call sdhci_write(.., SDHC_TRNMOD, ...)
1744 * here becuase it will result in a call to
1745 * sdhci_send_command(s) which we don't want.
1746 *
1747 */
1748 s->trnmod = value & UINT16_MAX;
1749 break;
1750 case SDHC_TRNMOD:
1751 /*
1752 * Similar to above, but this time a write to "Command
1753 * Register" will be translated into a 4-byte write to
1754 * "Transfer Mode register" where lower 16-bit of value would
1755 * be set to zero. So what we do is fill those bits with
1756 * cached value from s->trnmod and let the SDHCI
1757 * infrastructure handle the rest
1758 */
1759 sdhci_write(opaque, offset, val | s->trnmod, size);
1760 break;
1761 case SDHC_BLKSIZE:
1762 /*
1763 * ESDHCI does not implement "Host SDMA Buffer Boundary", and
1764 * Linux driver will try to zero this field out which will
1765 * break the rest of SDHCI emulation.
1766 *
1767 * Linux defaults to maximum possible setting (512K boundary)
1768 * and it seems to be the only option that i.MX IP implements,
1769 * so we artificially set it to that value.
1770 */
1771 val |= 0x7 << 12;
1772 /* FALLTHROUGH */
1773 default:
1774 sdhci_write(opaque, offset, val, size);
1775 break;
1776 }
1777}
1778
1779
1780static const MemoryRegionOps usdhc_mmio_ops = {
1781 .read = usdhc_read,
1782 .write = usdhc_write,
1783 .valid = {
1784 .min_access_size = 1,
1785 .max_access_size = 4,
1786 .unaligned = false
1787 },
1788 .endianness = DEVICE_LITTLE_ENDIAN,
1789};
1790
1791static void imx_usdhc_init(Object *obj)
1792{
1793 SDHCIState *s = SYSBUS_SDHCI(obj);
1794
1795 s->io_ops = &usdhc_mmio_ops;
1796 s->quirks = SDHCI_QUIRK_NO_BUSY_IRQ;
1797}
1798
1799static const TypeInfo imx_usdhc_info = {
1800 .name = TYPE_IMX_USDHC,
1801 .parent = TYPE_SYSBUS_SDHCI,
1802 .instance_init = imx_usdhc_init,
1803};
1804
d7dfca08
IM
1805static void sdhci_register_types(void)
1806{
224d10ff 1807 type_register_static(&sdhci_pci_info);
7302dcd6 1808 type_register_static(&sdhci_sysbus_info);
40bbc194 1809 type_register_static(&sdhci_bus_info);
fd1e5c81 1810 type_register_static(&imx_usdhc_info);
d7dfca08
IM
1811}
1812
1813type_init(sdhci_register_types)