sdhci: add support for v3 capabilities
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com> Message-Id: <20180208164818.7961-18-f4bug@amsat.org>
This commit is contained in:
parent
27a49d3be6
commit
4d67852d9c
@ -43,6 +43,7 @@
|
|||||||
#define SDHC_TRNS_DMA 0x0001
|
#define SDHC_TRNS_DMA 0x0001
|
||||||
#define SDHC_TRNS_BLK_CNT_EN 0x0002
|
#define SDHC_TRNS_BLK_CNT_EN 0x0002
|
||||||
#define SDHC_TRNS_ACMD12 0x0004
|
#define SDHC_TRNS_ACMD12 0x0004
|
||||||
|
#define SDHC_TRNS_ACMD23 0x0008 /* since v3 */
|
||||||
#define SDHC_TRNS_READ 0x0010
|
#define SDHC_TRNS_READ 0x0010
|
||||||
#define SDHC_TRNS_MULTI 0x0020
|
#define SDHC_TRNS_MULTI 0x0020
|
||||||
#define SDHC_TRNMOD_MASK 0x0037
|
#define SDHC_TRNMOD_MASK 0x0037
|
||||||
@ -193,6 +194,7 @@ FIELD(SDHC_CAPAB, TOCLKFREQ, 0, 6);
|
|||||||
FIELD(SDHC_CAPAB, TOUNIT, 7, 1);
|
FIELD(SDHC_CAPAB, TOUNIT, 7, 1);
|
||||||
FIELD(SDHC_CAPAB, BASECLKFREQ, 8, 8);
|
FIELD(SDHC_CAPAB, BASECLKFREQ, 8, 8);
|
||||||
FIELD(SDHC_CAPAB, MAXBLOCKLENGTH, 16, 2);
|
FIELD(SDHC_CAPAB, MAXBLOCKLENGTH, 16, 2);
|
||||||
|
FIELD(SDHC_CAPAB, EMBEDDED_8BIT, 18, 1); /* since v3 */
|
||||||
FIELD(SDHC_CAPAB, ADMA2, 19, 1); /* since v2 */
|
FIELD(SDHC_CAPAB, ADMA2, 19, 1); /* since v2 */
|
||||||
FIELD(SDHC_CAPAB, ADMA1, 20, 1); /* v1 only? */
|
FIELD(SDHC_CAPAB, ADMA1, 20, 1); /* v1 only? */
|
||||||
FIELD(SDHC_CAPAB, HIGHSPEED, 21, 1);
|
FIELD(SDHC_CAPAB, HIGHSPEED, 21, 1);
|
||||||
@ -202,6 +204,17 @@ FIELD(SDHC_CAPAB, V33, 24, 1);
|
|||||||
FIELD(SDHC_CAPAB, V30, 25, 1);
|
FIELD(SDHC_CAPAB, V30, 25, 1);
|
||||||
FIELD(SDHC_CAPAB, V18, 26, 1);
|
FIELD(SDHC_CAPAB, V18, 26, 1);
|
||||||
FIELD(SDHC_CAPAB, BUS64BIT, 28, 1); /* since v2 */
|
FIELD(SDHC_CAPAB, BUS64BIT, 28, 1); /* since v2 */
|
||||||
|
FIELD(SDHC_CAPAB, ASYNC_INT, 29, 1); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, SLOT_TYPE, 30, 2); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, BUS_SPEED, 32, 3); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, DRIVER_STRENGTH, 36, 3); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, DRIVER_TYPE_A, 36, 1); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, DRIVER_TYPE_C, 37, 1); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, DRIVER_TYPE_D, 38, 1); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, TIMER_RETUNING, 40, 4); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, SDR50_TUNING, 45, 1); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, RETUNING_MODE, 46, 2); /* since v3 */
|
||||||
|
FIELD(SDHC_CAPAB, CLOCK_MULT, 48, 8); /* since v3 */
|
||||||
|
|
||||||
/* HWInit Maximum Current Capabilities Register 0x0 */
|
/* HWInit Maximum Current Capabilities Register 0x0 */
|
||||||
#define SDHC_MAXCURR 0x48
|
#define SDHC_MAXCURR 0x48
|
||||||
|
@ -69,6 +69,9 @@ static inline unsigned int sdhci_get_fifolen(SDHCIState *s)
|
|||||||
static bool sdhci_check_capab_freq_range(SDHCIState *s, const char *desc,
|
static bool sdhci_check_capab_freq_range(SDHCIState *s, const char *desc,
|
||||||
uint8_t freq, Error **errp)
|
uint8_t freq, Error **errp)
|
||||||
{
|
{
|
||||||
|
if (s->sd_spec_version >= 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
switch (freq) {
|
switch (freq) {
|
||||||
case 0:
|
case 0:
|
||||||
case 10 ... 63:
|
case 10 ... 63:
|
||||||
@ -88,6 +91,50 @@ static void sdhci_check_capareg(SDHCIState *s, Error **errp)
|
|||||||
bool y;
|
bool y;
|
||||||
|
|
||||||
switch (s->sd_spec_version) {
|
switch (s->sd_spec_version) {
|
||||||
|
case 3:
|
||||||
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, ASYNC_INT);
|
||||||
|
trace_sdhci_capareg("async interrupt", val);
|
||||||
|
msk = FIELD_DP64(msk, SDHC_CAPAB, ASYNC_INT, 0);
|
||||||
|
|
||||||
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, SLOT_TYPE);
|
||||||
|
if (val) {
|
||||||
|
error_setg(errp, "slot-type not supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trace_sdhci_capareg("slot type", val);
|
||||||
|
msk = FIELD_DP64(msk, SDHC_CAPAB, SLOT_TYPE, 0);
|
||||||
|
|
||||||
|
if (val != 2) {
|
||||||
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, EMBEDDED_8BIT);
|
||||||
|
trace_sdhci_capareg("8-bit bus", val);
|
||||||
|
}
|
||||||
|
msk = FIELD_DP64(msk, SDHC_CAPAB, EMBEDDED_8BIT, 0);
|
||||||
|
|
||||||
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, BUS_SPEED);
|
||||||
|
trace_sdhci_capareg("bus speed mask", val);
|
||||||
|
msk = FIELD_DP64(msk, SDHC_CAPAB, BUS_SPEED, 0);
|
||||||
|
|
||||||
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, DRIVER_STRENGTH);
|
||||||
|
trace_sdhci_capareg("driver strength mask", val);
|
||||||
|
msk = FIELD_DP64(msk, SDHC_CAPAB, DRIVER_STRENGTH, 0);
|
||||||
|
|
||||||
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, TIMER_RETUNING);
|
||||||
|
trace_sdhci_capareg("timer re-tuning", val);
|
||||||
|
msk = FIELD_DP64(msk, SDHC_CAPAB, TIMER_RETUNING, 0);
|
||||||
|
|
||||||
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, SDR50_TUNING);
|
||||||
|
trace_sdhci_capareg("use SDR50 tuning", val);
|
||||||
|
msk = FIELD_DP64(msk, SDHC_CAPAB, SDR50_TUNING, 0);
|
||||||
|
|
||||||
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, RETUNING_MODE);
|
||||||
|
trace_sdhci_capareg("re-tuning mode", val);
|
||||||
|
msk = FIELD_DP64(msk, SDHC_CAPAB, RETUNING_MODE, 0);
|
||||||
|
|
||||||
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, CLOCK_MULT);
|
||||||
|
trace_sdhci_capareg("clock multiplier", val);
|
||||||
|
msk = FIELD_DP64(msk, SDHC_CAPAB, CLOCK_MULT, 0);
|
||||||
|
|
||||||
|
/* fallthrough */
|
||||||
case 2: /* default version */
|
case 2: /* default version */
|
||||||
val = FIELD_EX64(s->capareg, SDHC_CAPAB, ADMA2);
|
val = FIELD_EX64(s->capareg, SDHC_CAPAB, ADMA2);
|
||||||
trace_sdhci_capareg("ADMA2", val);
|
trace_sdhci_capareg("ADMA2", val);
|
||||||
@ -1227,8 +1274,11 @@ static void sdhci_init_readonly_registers(SDHCIState *s, Error **errp)
|
|||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
if (s->sd_spec_version != 2) {
|
switch (s->sd_spec_version) {
|
||||||
error_setg(errp, "Only Spec v2 is supported");
|
case 2 ... 3:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error_setg(errp, "Only Spec v2/v3 are supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s->version = (SDHC_HCVER_VENDOR << 8) | (s->sd_spec_version - 1);
|
s->version = (SDHC_HCVER_VENDOR << 8) | (s->sd_spec_version - 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user