mirror of
https://github.com/qemu/qemu.git
synced 2025-08-08 08:05:17 +00:00
sdhci: implement the Host Control 2 register (tuning sequence)
[based on a patch from Alistair Francis <alistair.francis@xilinx.com> from qemu/xilinx tag xilinx-v2015.2] Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com> Message-Id: <20180208164818.7961-20-f4bug@amsat.org>
This commit is contained in:
parent
06c5120b09
commit
ea55a221bf
@ -188,6 +188,16 @@ FIELD(SDHC_ACMD12ERRSTS, TIMEOUT_ERR, 1, 1);
|
|||||||
FIELD(SDHC_ACMD12ERRSTS, CRC_ERR, 2, 1);
|
FIELD(SDHC_ACMD12ERRSTS, CRC_ERR, 2, 1);
|
||||||
FIELD(SDHC_ACMD12ERRSTS, INDEX_ERR, 4, 1);
|
FIELD(SDHC_ACMD12ERRSTS, INDEX_ERR, 4, 1);
|
||||||
|
|
||||||
|
/* Host Control Register 2 (since v3) */
|
||||||
|
#define SDHC_HOSTCTL2 0x3E
|
||||||
|
FIELD(SDHC_HOSTCTL2, UHS_MODE_SEL, 0, 3);
|
||||||
|
FIELD(SDHC_HOSTCTL2, V18_ENA, 3, 1); /* UHS-I only */
|
||||||
|
FIELD(SDHC_HOSTCTL2, DRIVER_STRENGTH, 4, 2); /* UHS-I only */
|
||||||
|
FIELD(SDHC_HOSTCTL2, EXECUTE_TUNING, 6, 1); /* UHS-I only */
|
||||||
|
FIELD(SDHC_HOSTCTL2, SAMPLING_CLKSEL, 7, 1); /* UHS-I only */
|
||||||
|
FIELD(SDHC_HOSTCTL2, ASYNC_INT, 14, 1);
|
||||||
|
FIELD(SDHC_HOSTCTL2, PRESET_ENA, 15, 1);
|
||||||
|
|
||||||
/* HWInit Capabilities Register 0x05E80080 */
|
/* HWInit Capabilities Register 0x05E80080 */
|
||||||
#define SDHC_CAPAB 0x40
|
#define SDHC_CAPAB 0x40
|
||||||
FIELD(SDHC_CAPAB, TOCLKFREQ, 0, 6);
|
FIELD(SDHC_CAPAB, TOCLKFREQ, 0, 6);
|
||||||
|
@ -408,14 +408,29 @@ static void sdhci_end_transfer(SDHCIState *s)
|
|||||||
static void sdhci_read_block_from_card(SDHCIState *s)
|
static void sdhci_read_block_from_card(SDHCIState *s)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
uint8_t data;
|
||||||
|
const uint16_t blk_size = s->blksize & BLOCK_SIZE_MASK;
|
||||||
|
|
||||||
if ((s->trnmod & SDHC_TRNS_MULTI) &&
|
if ((s->trnmod & SDHC_TRNS_MULTI) &&
|
||||||
(s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0)) {
|
(s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (index = 0; index < (s->blksize & BLOCK_SIZE_MASK); index++) {
|
for (index = 0; index < blk_size; index++) {
|
||||||
s->fifo_buffer[index] = sdbus_read_data(&s->sdbus);
|
data = sdbus_read_data(&s->sdbus);
|
||||||
|
if (!FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
|
||||||
|
/* Device is not in tunning */
|
||||||
|
s->fifo_buffer[index] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
|
||||||
|
/* Device is in tunning */
|
||||||
|
s->hostctl2 &= ~R_SDHC_HOSTCTL2_EXECUTE_TUNING_MASK;
|
||||||
|
s->hostctl2 |= R_SDHC_HOSTCTL2_SAMPLING_CLKSEL_MASK;
|
||||||
|
s->prnsts &= ~(SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ |
|
||||||
|
SDHC_DATA_INHIBIT);
|
||||||
|
goto read_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* New data now available for READ through Buffer Port Register */
|
/* New data now available for READ through Buffer Port Register */
|
||||||
@ -440,6 +455,7 @@ static void sdhci_read_block_from_card(SDHCIState *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read_done:
|
||||||
sdhci_update_irq(s);
|
sdhci_update_irq(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1005,7 +1021,7 @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
|
|||||||
ret = s->norintsigen | (s->errintsigen << 16);
|
ret = s->norintsigen | (s->errintsigen << 16);
|
||||||
break;
|
break;
|
||||||
case SDHC_ACMD12ERRSTS:
|
case SDHC_ACMD12ERRSTS:
|
||||||
ret = s->acmd12errsts;
|
ret = s->acmd12errsts | (s->hostctl2 << 16);
|
||||||
break;
|
break;
|
||||||
case SDHC_CAPAB:
|
case SDHC_CAPAB:
|
||||||
ret = (uint32_t)s->capareg;
|
ret = (uint32_t)s->capareg;
|
||||||
|
@ -73,6 +73,7 @@ typedef struct SDHCIState {
|
|||||||
uint16_t norintsigen; /* Normal Interrupt Signal Enable Register */
|
uint16_t norintsigen; /* Normal Interrupt Signal Enable Register */
|
||||||
uint16_t errintsigen; /* Error Interrupt Signal Enable Register */
|
uint16_t errintsigen; /* Error Interrupt Signal Enable Register */
|
||||||
uint16_t acmd12errsts; /* Auto CMD12 error status register */
|
uint16_t acmd12errsts; /* Auto CMD12 error status register */
|
||||||
|
uint16_t hostctl2; /* Host Control 2 */
|
||||||
uint64_t admasysaddr; /* ADMA System Address Register */
|
uint64_t admasysaddr; /* ADMA System Address Register */
|
||||||
|
|
||||||
/* Read-only registers */
|
/* Read-only registers */
|
||||||
|
Loading…
Reference in New Issue
Block a user