void sdhci_reset(struct sdhci_host *host, u8 mask)
{
unsigned long timeout;
+ u16 ctrl;
sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
timeout--;
mdelay(1);
}
+
+ if ((mask & SDHCI_RESET_ALL) && (host->version >= SDHCI_SPEC_400)) {
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ ctrl |= SDHCI_HOST_VERSION_4_EN;
+ if (host->quirks2 & SDHCI_QUIRK2_USE_64BIT_ADDR)
+ ctrl |= SDHCI_ADDRESSING_64BIT_EN;
+ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+ }
}
EXPORT_SYMBOL_GPL(sdhci_reset);
BUG_ON(len > 65536);
- /* tran, valid */
- sdhci_adma_write_desc(host, desc, addr, len, ADMA2_TRAN_VALID);
- desc += host->desc_sz;
+ if (len > 0) {
+ /* tran, valid */
+ sdhci_adma_write_desc(host, desc, addr, len,
+ ADMA2_TRAN_VALID);
+ desc += host->desc_sz;
+ }
/*
* If this triggers then we have a calculation bug
WARN_ON(1);
host->flags &= ~SDHCI_REQ_USE_DMA;
} else {
- sdhci_writel(host, host->adma_addr,
+ sdhci_writel(host,
+ (host->adma_addr & 0xFFFFFFFF),
SDHCI_ADMA_ADDRESS);
- if (host->flags & SDHCI_USE_64_BIT_DMA)
- sdhci_writel(host,
- (u64)host->adma_addr >> 32,
- SDHCI_ADMA_ADDRESS_HI);
+ if (host->flags & SDHCI_USE_64_BIT_DMA) {
+ if (host->quirks2 &
+ SDHCI_QUIRK2_USE_64BIT_ADDR) {
+ sdhci_writel(host,
+ ((u64)host->adma_addr >> 32)
+ & 0xFFFFFFFF,
+ SDHCI_ADMA_ADDRESS_HI);
+ } else {
+ sdhci_writel(host, 0,
+ SDHCI_ADMA_ADDRESS_HI);
+ }
+ }
}
} else {
int sg_cnt;
ctrl &= ~SDHCI_CTRL_DMA_MASK;
if ((host->flags & SDHCI_REQ_USE_DMA) &&
(host->flags & SDHCI_USE_ADMA)) {
- if (host->flags & SDHCI_USE_64_BIT_DMA)
- ctrl |= SDHCI_CTRL_ADMA64;
+ if ((host->flags & SDHCI_USE_64_BIT_DMA) &&
+ (host->version < SDHCI_SPEC_400))
+ ctrl |= SDHCI_CTRL_ADMA64;
else
ctrl |= SDHCI_CTRL_ADMA32;
} else {
* all multipled by the descriptor size.
*/
if (host->flags & SDHCI_USE_64_BIT_DMA) {
+ if (host->quirks2 & SDHCI_QUIRK2_USE_64BIT_ADDR)
+ host->desc_sz = SDHCI_ADMA2_64_ADDR_DESC_SZ;
+ else
+ host->desc_sz = SDHCI_ADMA2_64_DESC_SZ;
host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) *
- SDHCI_ADMA2_64_DESC_SZ;
+ host->desc_sz;
host->align_buffer_sz = SDHCI_MAX_SEGS *
SDHCI_ADMA2_64_ALIGN;
- host->desc_sz = SDHCI_ADMA2_64_DESC_SZ;
host->align_sz = SDHCI_ADMA2_64_ALIGN;
host->align_mask = SDHCI_ADMA2_64_ALIGN - 1;
} else {
mmc_add_host(mmc);
- pr_info("%s: SDHCI controller on %s [%s] using %s\n",
+ pr_info("%s: SDHCI controller on %s [%s] using %s with %s bit addr\n",
mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
(host->flags & SDHCI_USE_ADMA) ?
(host->flags & SDHCI_USE_64_BIT_DMA) ? "ADMA 64-bit" : "ADMA" :
- (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
+ (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO",
+ (host->quirks2 & SDHCI_QUIRK2_USE_64BIT_ADDR) ? "64" : "32");
sdhci_enable_card_detection(host);
#define SDHCI_CTRL_DRV_TYPE_D 0x0030
#define SDHCI_CTRL_EXEC_TUNING 0x0040
#define SDHCI_CTRL_TUNED_CLK 0x0080
+#define SDHCI_HOST_VERSION_4_EN 0x1000
+#define SDHCI_ADDRESSING_64BIT_EN 0x2000
#define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000
#define SDHCI_CAPABILITIES 0x40
#define SDHCI_SPEC_100 0
#define SDHCI_SPEC_200 1
#define SDHCI_SPEC_300 2
+#define SDHCI_SPEC_400 3
#define SDHCI_SPEC_410 4
/*
/* ADMA2 64-bit DMA descriptor size */
#define SDHCI_ADMA2_64_DESC_SZ 12
+/* ADMA2 64-bit Addressing DMA descriptor size */
+#define SDHCI_ADMA2_64_ADDR_DESC_SZ 16
+
/* ADMA2 64-bit DMA alignment */
#define SDHCI_ADMA2_64_ALIGN 8
#define SDHCI_QUIRK2_DDR_FIXED_DIVISOR (1<<17)
/* Turn off/on card clock before sending/after tuning command*/
#define SDHCI_QUIRK2_NON_STD_TUN_CARD_CLOCK (1<<18)
+#define SDHCI_QUIRK2_USE_64BIT_ADDR (1<<19)
int irq; /* Device IRQ */