-/* $OpenBSD: sdhc.c,v 1.60 2018/05/30 13:32:40 patrick Exp $ */
+/* $OpenBSD: sdhc.c,v 1.61 2018/09/06 10:15:17 patrick Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
/* flag values */
#define SHF_USE_DMA 0x0001
+#define SHF_USE_DMA64 0x0002
#define HREAD1(hp, reg) \
(bus_space_read_1((hp)->iot, (hp)->ioh, (reg)))
caps = HREAD4(hp, SDHC_CAPABILITIES);
/* Use DMA if the host system and the controller support it. */
- if (usedma && ISSET(caps, SDHC_ADMA2_SUPP))
+ if (usedma && ISSET(caps, SDHC_ADMA2_SUPP)) {
SET(hp->flags, SHF_USE_DMA);
+ if (ISSET(caps, SDHC_64BIT_DMA_SUPP))
+ SET(hp->flags, SHF_USE_DMA64);
+ }
/*
* Determine the base clock frequency. (2.2.24)
int
sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
{
- struct sdhc_adma2_descriptor32 *desc = (void *)hp->adma2;
+ struct sdhc_adma2_descriptor32 *desc32 = (void *)hp->adma2;
+ struct sdhc_adma2_descriptor64 *desc64 = (void *)hp->adma2;
struct sdhc_softc *sc = hp->sc;
u_int16_t blksize = 0;
u_int16_t blkcount = 0;
if (seg == cmd->c_dmamap->dm_nsegs - 1)
attr |= SDHC_ADMA2_END;
- desc[seg].attribute = htole16(attr);
- desc[seg].length = htole16(len);
- desc[seg].address = htole32(paddr);
+ if (ISSET(hp->flags, SHF_USE_DMA64)) {
+ desc64[seg].attribute = htole16(attr);
+ desc64[seg].length = htole16(len);
+ desc64[seg].address_lo =
+ htole32((uint64_t)paddr & 0xffffffff);
+ desc64[seg].address_hi =
+ htole32((uint64_t)paddr >> 32);
+ } else {
+ desc32[seg].attribute = htole16(attr);
+ desc32[seg].length = htole16(len);
+ desc32[seg].address = htole32(paddr);
+ }
}
- desc[cmd->c_dmamap->dm_nsegs].attribute = htole16(0);
+ if (ISSET(hp->flags, SHF_USE_DMA64))
+ desc64[cmd->c_dmamap->dm_nsegs].attribute = htole16(0);
+ else
+ desc32[cmd->c_dmamap->dm_nsegs].attribute = htole16(0);
bus_dmamap_sync(sc->sc_dmat, hp->adma_map, 0, PAGE_SIZE,
BUS_DMASYNC_PREWRITE);
HCLR1(hp, SDHC_HOST_CTL, SDHC_DMA_SELECT);
- HSET1(hp, SDHC_HOST_CTL, SDHC_DMA_SELECT_ADMA2);
+ if (ISSET(hp->flags, SHF_USE_DMA64))
+ HSET1(hp, SDHC_HOST_CTL, SDHC_DMA_SELECT_ADMA64);
+ else
+ HSET1(hp, SDHC_HOST_CTL, SDHC_DMA_SELECT_ADMA32);
HWRITE4(hp, SDHC_ADMA_SYSTEM_ADDR,
hp->adma_map->dm_segs[0].ds_addr);
-/* $OpenBSD: sdhcreg.h,v 1.8 2018/03/19 21:40:32 kettenis Exp $ */
+/* $OpenBSD: sdhcreg.h,v 1.9 2018/09/06 10:15:17 patrick Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
#define SDHC_8BIT_MODE (1<<5)
#define SDHC_DMA_SELECT (3<<3)
#define SDHC_DMA_SELECT_SDMA (0<<3)
-#define SDHC_DMA_SELECT_ADMA2 (2<<3)
+#define SDHC_DMA_SELECT_ADMA32 (2<<3)
+#define SDHC_DMA_SELECT_ADMA64 (3<<3)
#define SDHC_HIGH_SPEED (1<<2)
#define SDHC_4BIT_MODE (1<<1)
#define SDHC_LED_ON (1<<0)
#define SDHC_UHS_MODE_SELECT_SDR104 3
#define SDHC_UHS_MODE_SELECT_DDR50 4
#define SDHC_CAPABILITIES 0x40
+#define SDHC_64BIT_DMA_SUPP (1<<28)
#define SDHC_VOLTAGE_SUPP_1_8V (1<<26)
#define SDHC_VOLTAGE_SUPP_3_0V (1<<25)
#define SDHC_VOLTAGE_SUPP_3_3V (1<<24)
uint32_t address;
} __packed;
+struct sdhc_adma2_descriptor64 {
+ uint16_t attribute;
+ uint16_t length;
+ uint32_t address_lo;
+ uint32_t address_hi;
+} __packed;
+
#endif