Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/sunxi Validate burst and width arguments.
details: https://anonhg.NetBSD.org/src/rev/34cea6670428
branches: trunk
changeset: 449296:34cea6670428
user: jakllsch <jakllsch%NetBSD.org@localhost>
date: Sat Mar 02 16:55:13 2019 +0000
description:
Validate burst and width arguments.
Also add some more register definitions, and a (disabled) example of
how to set the DMA flow control mode.
diffstat:
sys/arch/arm/sunxi/sun6i_dma.c | 53 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 51 insertions(+), 2 deletions(-)
diffs (145 lines):
diff -r 74382916d450 -r 34cea6670428 sys/arch/arm/sunxi/sun6i_dma.c
--- a/sys/arch/arm/sunxi/sun6i_dma.c Sat Mar 02 14:21:19 2019 +0000
+++ b/sys/arch/arm/sunxi/sun6i_dma.c Sat Mar 02 16:55:13 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sun6i_dma.c,v 1.7 2019/03/02 03:21:17 jakllsch Exp $ */
+/* $NetBSD: sun6i_dma.c,v 1.8 2019/03/02 16:55:13 jakllsch Exp $ */
/*-
* Copyright (c) 2014-2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "opt_ddb.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sun6i_dma.c,v 1.7 2019/03/02 03:21:17 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sun6i_dma.c,v 1.8 2019/03/02 16:55:13 jakllsch Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -79,6 +79,13 @@
#define DMA_PARA_REG(n) (0x0100 + (n) * 0x40 + 0x1C)
#define DMA_PARA_DATA_BLK_SIZE __BITS(15,8)
#define DMA_PARA_WAIT_CYC __BITS(7,0)
+#define DMA_MODE_REG(n) (0x0100 + (n) * 0x40 + 0x28)
+#define MODE_WAIT 0b0
+#define MODE_HANDSHAKE 0b1
+#define DMA_MODE_DST(m) __SHIFTIN((m), __BIT(3))
+#define DMA_MODE_SRC(m) __SHIFTIN((m), __BIT(2))
+#define DMA_FDESC_ADDR_REG(n) (0x0100 + (n) * 0x40 + 0x2C)
+#define DMA_PKG_NUM_REG(n) (0x0100 + (n) * 0x40 + 0x30)
struct sun6idma_desc {
uint32_t dma_config;
@@ -93,14 +100,25 @@
struct sun6idma_config {
u_int num_channels;
bool autogate;
+ uint8_t bursts;
+ uint8_t widths;
bus_size_t autogate_reg;
uint32_t autogate_mask;
uint32_t burst_mask;
};
+#define IL2B(x) __BIT(ilog2(x))
+#define IL2B_RANGE(x, y) __BITS(ilog2(x), ilog2(y))
+#define WIDTHS_1_2_4 IL2B_RANGE(4, 1)
+#define WIDTHS_1_2_4_8 IL2B_RANGE(8, 1)
+#define BURSTS_1_8 (IL2B(8)|IL2B(1))
+#define BURSTS_1_4_8_16 (IL2B(16)|IL2B(8)|IL2B(4)|IL2B(1))
+
static const struct sun6idma_config sun6i_a31_dma_config = {
.num_channels = 16,
.burst_mask = __BITS(8,7),
+ .bursts = BURSTS_1_8,
+ .widths = WIDTHS_1_2_4,
};
static const struct sun6idma_config sun8i_a83t_dma_config = {
@@ -109,6 +127,8 @@
.autogate_reg = 0x20,
.autogate_mask = 0x4,
.burst_mask = __BITS(8,7),
+ .bursts = BURSTS_1_8,
+ .widths = WIDTHS_1_2_4,
};
static const struct sun6idma_config sun8i_h3_dma_config = {
@@ -117,6 +137,8 @@
.autogate_reg = 0x28,
.autogate_mask = 0x4,
.burst_mask = __BITS(7,6),
+ .bursts = BURSTS_1_4_8_16,
+ .widths = WIDTHS_1_2_4_8,
};
static const struct sun6idma_config sun50i_a64_dma_config = {
@@ -125,6 +147,8 @@
.autogate_reg = 0x28,
.autogate_mask = 0x4,
.burst_mask = __BITS(7,6),
+ .bursts = BURSTS_1_4_8_16,
+ .widths = WIDTHS_1_2_4_8,
};
static const struct of_compat_data compat_data[] = {
@@ -158,6 +182,8 @@
struct sun6idma_channel *sc_chan;
u_int sc_nchan;
u_int sc_ndesc_ch;
+ uint8_t sc_widths;
+ uint8_t sc_bursts;
bus_dma_segment_t sc_dmasegs[1];
bus_dmamap_t sc_dmamap;
@@ -259,6 +285,19 @@
if (req->dreq_nsegs > sc->sc_ndesc_ch)
return EINVAL;
+ if ((sc->sc_widths &
+ IL2B(req->dreq_mem_opt.opt_bus_width/NBBY)) == 0)
+ return EINVAL;
+ if ((sc->sc_widths &
+ IL2B(req->dreq_dev_opt.opt_bus_width/NBBY)) == 0)
+ return EINVAL;
+ if ((sc->sc_bursts &
+ IL2B(req->dreq_mem_opt.opt_burst_len)) == 0)
+ return EINVAL;
+ if ((sc->sc_bursts &
+ IL2B(req->dreq_dev_opt.opt_burst_len)) == 0)
+ return EINVAL;
+
mem_width = DMA_CFG_DATA_WIDTH(req->dreq_mem_opt.opt_bus_width);
dev_width = DMA_CFG_DATA_WIDTH(req->dreq_dev_opt.opt_bus_width);
mem_burst = DMA_CFG_BST_LEN(req->dreq_mem_opt.opt_burst_len);
@@ -296,6 +335,11 @@
desc[j].dma_next = htole32(DMA_NULL);
}
+#if maybenever
+ DMA_WRITE(sc, DMA_MODE_REG(ch->ch_index),
+ DMA_MODE_DST(MODE_HANDSHAKE)|DMA_MODE_SRC(MODE_HANDSHAKE));
+#endif
+
bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, DESC_OFFS(ch->ch_index, 0),
DESC_LEN(req->dreq_nsegs), BUS_DMASYNC_PREWRITE);
@@ -419,6 +463,8 @@
sc->sc_burst_mask = conf->burst_mask;
sc->sc_nchan = conf->num_channels;
+ sc->sc_widths = conf->widths;
+ sc->sc_bursts = conf->bursts;
sc->sc_chan = kmem_alloc(sizeof(*sc->sc_chan) * sc->sc_nchan, KM_SLEEP);
desclen = DESC_OFFS(sc->sc_nchan, 0);
sc->sc_ndesc_ch = DESC_OFFS(1, 0) / sizeof(struct sun6idma_desc);
@@ -509,6 +555,9 @@
device_printf(dev, " %2d: DMA_CUR_DEST_REG: %08x\n", index, DMA_READ(sc, DMA_CUR_DEST_REG(index)));
device_printf(dev, " %2d: DMA_BCNT_LEFT_REG: %08x\n", index, DMA_READ(sc, DMA_BCNT_LEFT_REG(index)));
device_printf(dev, " %2d: DMA_PARA_REG: %08x\n", index, DMA_READ(sc, DMA_PARA_REG(index)));
+ device_printf(dev, " %2d: DMA_MODE_REG: %08x\n", index, DMA_READ(sc, DMA_MODE_REG(index)));
+ device_printf(dev, " %2d: DMA_FDESC_ADDR_REG: %08x\n", index, DMA_READ(sc, DMA_FDESC_ADDR_REG(index)));
+ device_printf(dev, " %2d: DMA_PKG_NUM_REG: %08x\n", index, DMA_READ(sc, DMA_PKG_NUM_REG(index)));
}
}
#endif
Home |
Main Index |
Thread Index |
Old Index