From b60bffefc510f0602c8ec52ce31c62cc432bc48d Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 6 Sep 2018 10:15:17 +0000 Subject: [PATCH] Implement 64-bit DMA support in sdhc(4). tested in snaps ok kettenis@ --- sys/dev/sdmmc/sdhc.c | 36 ++++++++++++++++++++++++++++-------- sys/dev/sdmmc/sdhcreg.h | 13 +++++++++++-- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/sys/dev/sdmmc/sdhc.c b/sys/dev/sdmmc/sdhc.c index c2d149c8a90..248878293e3 100644 --- a/sys/dev/sdmmc/sdhc.c +++ b/sys/dev/sdmmc/sdhc.c @@ -1,4 +1,4 @@ -/* $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 @@ -61,6 +61,7 @@ struct sdhc_host { /* 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))) @@ -190,8 +191,11 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, 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) @@ -804,7 +808,8 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 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; @@ -903,18 +908,33 @@ sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd) 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); diff --git a/sys/dev/sdmmc/sdhcreg.h b/sys/dev/sdmmc/sdhcreg.h index 97b3e748bff..9a891688695 100644 --- a/sys/dev/sdmmc/sdhcreg.h +++ b/sys/dev/sdmmc/sdhcreg.h @@ -1,4 +1,4 @@ -/* $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 @@ -83,7 +83,8 @@ #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) @@ -155,6 +156,7 @@ #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) @@ -257,4 +259,11 @@ struct sdhc_adma2_descriptor32 { uint32_t address; } __packed; +struct sdhc_adma2_descriptor64 { + uint16_t attribute; + uint16_t length; + uint32_t address_lo; + uint32_t address_hi; +} __packed; + #endif -- 2.20.1