svn commit: r362394 - stable/12/sys/dev/mmc/host
Emmanuel Vadot
manu at FreeBSD.org
Fri Jun 19 17:52:49 UTC 2020
Author: manu
Date: Fri Jun 19 17:52:48 2020
New Revision: 362394
URL: https://svnweb.freebsd.org/changeset/base/362394
Log:
MFC r358450, r358635
r358450:
mmc: dwmmc: Fix off by one error
The IVAR_MAX_DATA is supposed to have the number of descriptor X the mmc
block size and desc_count contain all this information + 1.
Reported by: phk
r358635:
dwmmc: Rework the DMA engine
Each segment can be up to 4096 bytes in chain structure according to the
RK3399 TRM Part 2.
Set the buffers in full ring where the last one point to the first one.
Correctly reports the MMC_IVAR_MAX_DATA.
Use CACHE_LINE_SIZE for bus_dma alignment.
Modified:
stable/12/sys/dev/mmc/host/dwmmc.c
stable/12/sys/dev/mmc/host/dwmmc_hisi.c
stable/12/sys/dev/mmc/host/dwmmc_var.h
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/dev/mmc/host/dwmmc.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc.c Fri Jun 19 17:49:49 2020 (r362393)
+++ stable/12/sys/dev/mmc/host/dwmmc.c Fri Jun 19 17:52:48 2020 (r362394)
@@ -99,16 +99,15 @@ __FBSDID("$FreeBSD$");
#define DWMMC_ERR_FLAGS (DWMMC_DATA_ERR_FLAGS | DWMMC_CMD_ERR_FLAGS \
|SDMMC_INTMASK_HLE)
-#define DES0_DIC (1 << 1)
-#define DES0_LD (1 << 2)
-#define DES0_FS (1 << 3)
-#define DES0_CH (1 << 4)
-#define DES0_ER (1 << 5)
-#define DES0_CES (1 << 30)
-#define DES0_OWN (1 << 31)
+#define DES0_DIC (1 << 1) /* Disable Interrupt on Completion */
+#define DES0_LD (1 << 2) /* Last Descriptor */
+#define DES0_FS (1 << 3) /* First Descriptor */
+#define DES0_CH (1 << 4) /* second address CHained */
+#define DES0_ER (1 << 5) /* End of Ring */
+#define DES0_CES (1 << 30) /* Card Error Summary */
+#define DES0_OWN (1 << 31) /* OWN */
-#define DES1_BS1_MASK 0xfff
-#define DES1_BS1_SHIFT 0
+#define DES1_BS1_MASK 0x1fff
struct idmac_desc {
uint32_t des0; /* control */
@@ -117,9 +116,10 @@ struct idmac_desc {
uint32_t des3; /* buf2 phys addr or next descr */
};
-#define DESC_MAX 256
-#define DESC_SIZE (sizeof(struct idmac_desc) * DESC_MAX)
+#define IDMAC_DESC_SEGS (PAGE_SIZE / (sizeof(struct idmac_desc)))
+#define IDMAC_DESC_SIZE (sizeof(struct idmac_desc) * IDMAC_DESC_SEGS)
#define DEF_MSIZE 0x2 /* Burst size of multiple transaction */
+#define IDMAC_MAX_SIZE 4096
static void dwmmc_next_operation(struct dwmmc_softc *);
static int dwmmc_setup_bus(struct dwmmc_softc *, int);
@@ -162,7 +162,7 @@ dwmmc_ring_setup(void *arg, bus_dma_segment_t *segs, i
for (idx = 0; idx < nsegs; idx++) {
sc->desc_ring[idx].des0 = (DES0_OWN | DES0_DIC | DES0_CH);
- sc->desc_ring[idx].des1 = segs[idx].ds_len;
+ sc->desc_ring[idx].des1 = segs[idx].ds_len & DES1_BS1_MASK;
sc->desc_ring[idx].des2 = segs[idx].ds_addr;
if (idx == 0)
@@ -213,8 +213,8 @@ dma_setup(struct dwmmc_softc *sc)
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
- DESC_SIZE, 1, /* maxsize, nsegments */
- DESC_SIZE, /* maxsegsize */
+ IDMAC_DESC_SIZE, 1, /* maxsize, nsegments */
+ IDMAC_DESC_SIZE, /* maxsegsize */
0, /* flags */
NULL, NULL, /* lockfunc, lockarg */
&sc->desc_tag);
@@ -234,7 +234,7 @@ dma_setup(struct dwmmc_softc *sc)
}
error = bus_dmamap_load(sc->desc_tag, sc->desc_map,
- sc->desc_ring, DESC_SIZE, dwmmc_get1paddr,
+ sc->desc_ring, IDMAC_DESC_SIZE, dwmmc_get1paddr,
&sc->desc_ring_paddr, 0);
if (error != 0) {
device_printf(sc->dev,
@@ -242,23 +242,25 @@ dma_setup(struct dwmmc_softc *sc)
return (1);
}
- for (idx = 0; idx < sc->desc_count; idx++) {
+ for (idx = 0; idx < IDMAC_DESC_SEGS; idx++) {
sc->desc_ring[idx].des0 = DES0_CH;
sc->desc_ring[idx].des1 = 0;
- nidx = (idx + 1) % sc->desc_count;
+ nidx = (idx + 1) % IDMAC_DESC_SEGS;
sc->desc_ring[idx].des3 = sc->desc_ring_paddr + \
(nidx * sizeof(struct idmac_desc));
}
+ sc->desc_ring[idx - 1].des3 = sc->desc_ring_paddr;
+ sc->desc_ring[idx - 1].des0 |= DES0_ER;
error = bus_dma_tag_create(
bus_get_dma_tag(sc->dev), /* Parent tag. */
- 4096, 0, /* alignment, boundary */
+ CACHE_LINE_SIZE, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
- sc->desc_count * MMC_SECTOR_SIZE, /* maxsize */
- sc->desc_count, /* nsegments */
- MMC_SECTOR_SIZE, /* maxsegsize */
+ IDMAC_MAX_SIZE * IDMAC_DESC_SEGS, /* maxsize */
+ IDMAC_DESC_SEGS, /* nsegments */
+ IDMAC_MAX_SIZE, /* maxsegsize */
0, /* flags */
NULL, NULL, /* lockfunc, lockarg */
&sc->buf_tag);
@@ -664,9 +666,6 @@ dwmmc_attach(device_t dev)
device_printf(dev, "Hardware version ID is %04x\n",
READ4(sc, SDMMC_VERID) & 0xffff);
- if (sc->desc_count == 0)
- sc->desc_count = DESC_MAX;
-
/* XXX: we support operation for slot index 0 only */
slot = 0;
if (sc->pwren_inverted) {
@@ -1278,7 +1277,7 @@ dwmmc_read_ivar(device_t bus, device_t child, int whic
*(int *)result = sc->host.caps;
break;
case MMCBR_IVAR_MAX_DATA:
- *(int *)result = sc->desc_count;
+ *(int *)result = (IDMAC_MAX_SIZE * IDMAC_DESC_SEGS) / MMC_SECTOR_SIZE;
break;
case MMCBR_IVAR_TIMING:
*(int *)result = sc->host.ios.timing;
Modified: stable/12/sys/dev/mmc/host/dwmmc_hisi.c
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_hisi.c Fri Jun 19 17:49:49 2020 (r362393)
+++ stable/12/sys/dev/mmc/host/dwmmc_hisi.c Fri Jun 19 17:52:48 2020 (r362394)
@@ -79,7 +79,6 @@ hisi_dwmmc_attach(device_t dev)
* DMA when the controller is not cache-coherent on arm64.
*/
sc->use_pio = 1;
- sc->desc_count = 1;
return (dwmmc_attach(dev));
}
Modified: stable/12/sys/dev/mmc/host/dwmmc_var.h
==============================================================================
--- stable/12/sys/dev/mmc/host/dwmmc_var.h Fri Jun 19 17:49:49 2020 (r362393)
+++ stable/12/sys/dev/mmc/host/dwmmc_var.h Fri Jun 19 17:52:48 2020 (r362394)
@@ -60,7 +60,6 @@ struct dwmmc_softc {
uint32_t use_auto_stop;
uint32_t use_pio;
uint32_t pwren_inverted;
- u_int desc_count;
device_t child;
struct task card_task; /* Card presence check task */
struct timeout_task card_delayed_task;/* Card insert delayed task */
More information about the svn-src-stable-12
mailing list