Home | History | Annotate | Line # | Download | only in ti
      1 /* $NetBSD: ti_edma.c,v 1.5 2022/05/21 19:07:23 andvar Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2014 Jared D. McNeill <jmcneill (at) invisible.ca>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. The name of the author may not be used to endorse or promote products
     13  *    derived from this software without specific prior written permission.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     22  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25  * SUCH DAMAGE.
     26  */
     27 
     28 #include <sys/cdefs.h>
     29 __KERNEL_RCSID(0, "$NetBSD: ti_edma.c,v 1.5 2022/05/21 19:07:23 andvar Exp $");
     30 
     31 #include <sys/param.h>
     32 #include <sys/systm.h>
     33 #include <sys/device.h>
     34 #include <sys/conf.h>
     35 #include <sys/intr.h>
     36 #include <sys/mutex.h>
     37 #include <sys/bus.h>
     38 #include <sys/bitops.h>
     39 
     40 #include <dev/fdt/fdtvar.h>
     41 
     42 #include <arm/ti/ti_prcm.h>
     43 #include <arm/ti/ti_edma.h>
     44 
     45 #define NUM_DMA_CHANNELS	64
     46 #define NUM_PARAM_SETS		256
     47 #define MAX_PARAM_PER_CHANNEL	32
     48 
     49 #ifdef EDMA_DEBUG
     50 int edmadebug = 1;
     51 #define DPRINTF(n,s)    do { if ((n) <= edmadebug) device_printf s; } while (0)
     52 #else
     53 #define DPRINTF(n,s)    do {} while (0)
     54 #endif
     55 
     56 struct edma_softc;
     57 
     58 struct edma_channel {
     59 	struct edma_softc *ch_sc;
     60 	enum edma_type ch_type;
     61 	uint8_t ch_index;
     62 	void (*ch_callback)(void *);
     63 	void *ch_callbackarg;
     64 	unsigned int ch_nparams;
     65 };
     66 
     67 struct edma_softc {
     68 	device_t sc_dev;
     69 	bus_space_tag_t sc_iot;
     70 	bus_space_handle_t sc_ioh;
     71 	kmutex_t sc_lock;
     72 	struct edma_channel sc_dma[NUM_DMA_CHANNELS];
     73 
     74 	void *sc_ih;
     75 
     76 	uint32_t sc_dmamask[NUM_DMA_CHANNELS / 32];
     77 	uint32_t sc_parammask[NUM_PARAM_SETS / 32];
     78 };
     79 
     80 static int edma_match(device_t, cfdata_t, void *);
     81 static void edma_attach(device_t, device_t, void *);
     82 
     83 static void edma_init(struct edma_softc *);
     84 static int edma_intr(void *);
     85 static void edma_write_param(struct edma_softc *,
     86 				  unsigned int, const struct edma_param *);
     87 static bool edma_bit_isset(uint32_t *, unsigned int);
     88 static void edma_bit_set(uint32_t *, unsigned int);
     89 static void edma_bit_clr(uint32_t *, unsigned int);
     90 
     91 CFATTACH_DECL_NEW(ti_edma, sizeof(struct edma_softc),
     92     edma_match, edma_attach, NULL, NULL);
     93 
     94 #define EDMA_READ(sc, reg) \
     95 	bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
     96 #define EDMA_WRITE(sc, reg, val) \
     97 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
     98 
     99 static const struct device_compatible_entry compat_data[] = {
    100 	{ .compat = "ti,edma3-tpcc" },
    101 	DEVICE_COMPAT_EOL
    102 };
    103 
    104 static int
    105 edma_match(device_t parent, cfdata_t match, void *aux)
    106 {
    107 	struct fdt_attach_args * const faa = aux;
    108 
    109 	return of_compatible_match(faa->faa_phandle, compat_data);
    110 }
    111 
    112 static void
    113 edma_attach(device_t parent, device_t self, void *aux)
    114 {
    115 	struct edma_softc *sc = device_private(self);
    116 	struct fdt_attach_args * const faa = aux;
    117 	const int phandle = faa->faa_phandle;
    118 	char intrstr[128];
    119 	bus_addr_t addr;
    120 	bus_size_t size;
    121 	int idx;
    122 
    123 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
    124 		aprint_error(": couldn't get registers\n");
    125 		return;
    126 	}
    127 
    128 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
    129 		aprint_error(": failed to decode interrupt\n");
    130 		return;
    131 	}
    132 
    133 	sc->sc_dev = self;
    134 	sc->sc_iot = faa->faa_bst;
    135 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
    136 	if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) {
    137 		aprint_error(": couldn't map registers\n");
    138 		return;
    139 	}
    140 
    141 	aprint_naive("\n");
    142 	aprint_normal(": EDMA Channel Controller\n");
    143 
    144 	for (idx = 0; idx < NUM_DMA_CHANNELS; idx++) {
    145 		struct edma_channel *ch = &sc->sc_dma[idx];
    146 		ch->ch_sc = sc;
    147 		ch->ch_type = EDMA_TYPE_DMA;
    148 		ch->ch_index = idx;
    149 		ch->ch_callback = NULL;
    150 		ch->ch_callbackarg = NULL;
    151 		ch->ch_nparams = 0;
    152 	}
    153 
    154 	if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
    155 		aprint_error_dev(self, "couldn't enable module\n");
    156 		return;
    157 	}
    158 
    159 	edma_init(sc);
    160 
    161 	sc->sc_ih = fdtbus_intr_establish_byname(phandle, "edma3_ccint",
    162 	    IPL_VM, FDT_INTR_MPSAFE, edma_intr, sc, device_xname(self));
    163 	if (sc->sc_ih == NULL) {
    164 		aprint_error_dev(self, "failed to establish interrupt\n");
    165 		return;
    166 	}
    167 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
    168 }
    169 
    170 /*
    171  * Hardware initialization
    172  */
    173 static void
    174 edma_init(struct edma_softc *sc)
    175 {
    176 	struct edma_param param;
    177 	uint32_t val;
    178 	int idx;
    179 
    180 	val = EDMA_READ(sc, EDMA_CCCFG_REG);
    181 	if (val & EDMA_CCCFG_CHMAP_EXIST) {
    182 		for (idx = 0; idx < NUM_DMA_CHANNELS; idx++) {
    183 			EDMA_WRITE(sc, EDMA_DCHMAP_REG(idx),
    184 			    __SHIFTIN(0, EDMA_DCHMAP_PAENTRY));
    185 		}
    186 	}
    187 
    188 	memset(&param, 0, sizeof(param));
    189 	param.ep_bcnt = 1;
    190 	for (idx = 0; idx < NUM_PARAM_SETS; idx++) {
    191 		edma_write_param(sc, idx, &param);
    192 	}
    193 
    194 	/* reserve PaRAM entry 0 for dummy slot */
    195 	edma_bit_set(sc->sc_parammask, 0);
    196 	for (idx = 1; idx <= 32; idx++) {
    197 		edma_bit_set(sc->sc_parammask, idx);
    198 	}
    199 }
    200 
    201 /*
    202  * Write a PaRAM entry
    203  */
    204 static void
    205 edma_write_param(struct edma_softc *sc,
    206     unsigned int idx, const struct edma_param *ep)
    207 {
    208 	EDMA_WRITE(sc, EDMA_PARAM_OPT_REG(idx), ep->ep_opt);
    209 	EDMA_WRITE(sc, EDMA_PARAM_SRC_REG(idx), ep->ep_src);
    210 	EDMA_WRITE(sc, EDMA_PARAM_CNT_REG(idx),
    211 	    __SHIFTIN(ep->ep_bcnt, EDMA_PARAM_CNT_BCNT) |
    212 	    __SHIFTIN(ep->ep_acnt, EDMA_PARAM_CNT_ACNT));
    213 	EDMA_WRITE(sc, EDMA_PARAM_DST_REG(idx), ep->ep_dst);
    214 	EDMA_WRITE(sc, EDMA_PARAM_BIDX_REG(idx),
    215 	    __SHIFTIN(ep->ep_dstbidx, EDMA_PARAM_BIDX_DSTBIDX) |
    216 	    __SHIFTIN(ep->ep_srcbidx, EDMA_PARAM_BIDX_SRCBIDX));
    217 	EDMA_WRITE(sc, EDMA_PARAM_LNK_REG(idx),
    218 	    __SHIFTIN(ep->ep_bcntrld, EDMA_PARAM_LNK_BCNTRLD) |
    219 	    __SHIFTIN(ep->ep_link, EDMA_PARAM_LNK_LINK));
    220 	EDMA_WRITE(sc, EDMA_PARAM_CIDX_REG(idx),
    221 	    __SHIFTIN(ep->ep_dstcidx, EDMA_PARAM_CIDX_DSTCIDX) |
    222 	    __SHIFTIN(ep->ep_srccidx, EDMA_PARAM_CIDX_SRCCIDX));
    223 	EDMA_WRITE(sc, EDMA_PARAM_CCNT_REG(idx),
    224 	    __SHIFTIN(ep->ep_ccnt, EDMA_PARAM_CCNT_CCNT));
    225 }
    226 
    227 static bool
    228 edma_bit_isset(uint32_t *bits, unsigned int bit)
    229 {
    230 	return !!(bits[bit >> 5] & (1 << (bit & 0x1f)));
    231 }
    232 
    233 static void
    234 edma_bit_set(uint32_t *bits, unsigned int bit)
    235 {
    236 	bits[bit >> 5] |= (1 << (bit & 0x1f));
    237 }
    238 
    239 static void
    240 edma_bit_clr(uint32_t *bits, unsigned int bit)
    241 {
    242 	bits[bit >> 5] &= ~(1 << (bit & 0x1f));
    243 }
    244 
    245 static int
    246 edma_intr(void *priv)
    247 {
    248 	struct edma_softc *sc = priv;
    249 	uint64_t ipr, ier;
    250 	int bit, idx;
    251 
    252 	ipr = EDMA_READ(sc, EDMA_IPR_REG);
    253 	ipr |= (uint64_t)EDMA_READ(sc, EDMA_IPRH_REG) << 32;
    254 	if (ipr == 0)
    255 		return 0;
    256 
    257 	ier = EDMA_READ(sc, EDMA_IER_REG);
    258 	ier |= (uint64_t)EDMA_READ(sc, EDMA_IERH_REG) << 32;
    259 
    260 	DPRINTF(2, (sc->sc_dev, "ipr = 0x%016llx ier 0x%016llx\n", ipr, ier));
    261 
    262 	EDMA_WRITE(sc, EDMA_ICR_REG, ipr & 0xffffffff);
    263 	EDMA_WRITE(sc, EDMA_ICRH_REG, ipr >> 32);
    264 
    265 	while ((bit = ffs64(ipr)) != 0) {
    266 		idx = bit - 1;
    267 		ipr &= ~__BIT(idx);
    268 		if (!(ier & __BIT(idx)))
    269 			continue;
    270 		if (!edma_bit_isset(sc->sc_dmamask, idx))
    271 			continue;
    272 
    273 		sc->sc_dma[idx].ch_callback(sc->sc_dma[idx].ch_callbackarg);
    274 	}
    275 
    276 	EDMA_WRITE(sc, EDMA_IEVAL_REG, EDMA_IEVAL_EVAL);
    277 
    278 	return 1;
    279 }
    280 
    281 /*
    282  * Allocate a DMA channel. Currently only DMA types are supported, not QDMA.
    283  * Returns NULL on failure.
    284  */
    285 struct edma_channel *
    286 edma_channel_alloc(enum edma_type type, unsigned int drq,
    287     void (*cb)(void *), void *cbarg)
    288 {
    289 	struct edma_softc *sc;
    290 	device_t dev;
    291 	struct edma_channel *ch = NULL;
    292 
    293 	KASSERT(drq < __arraycount(sc->sc_dma));
    294 	KASSERT(type == EDMA_TYPE_DMA);	/* QDMA not implemented */
    295 	KASSERT(cb != NULL);
    296 	KASSERT(cbarg != NULL);
    297 
    298 	dev = device_find_by_driver_unit("tiedma", 0);
    299 	if (dev == NULL)
    300 		return NULL;
    301 	sc = device_private(dev);
    302 
    303 	mutex_enter(&sc->sc_lock);
    304 	if (!edma_bit_isset(sc->sc_dmamask, drq)) {
    305 		ch = &sc->sc_dma[drq];
    306 		KASSERT(ch->ch_callback == NULL);
    307 		KASSERT(ch->ch_index == drq);
    308 		ch->ch_callback = cb;
    309 		ch->ch_callbackarg = cbarg;
    310 		edma_bit_set(sc->sc_dmamask, drq);
    311 	}
    312 
    313 	if (ch == NULL)
    314 		goto done;
    315 
    316 	EDMA_WRITE(sc, EDMA_DRAE_REG(0), sc->sc_dmamask[0]);
    317 	EDMA_WRITE(sc, EDMA_DRAEH_REG(0), sc->sc_dmamask[1]);
    318 
    319 	if (ch->ch_index < 32) {
    320 		EDMA_WRITE(sc, EDMA_ICR_REG, __BIT(ch->ch_index));
    321 		EDMA_WRITE(sc, EDMA_IESR_REG, __BIT(ch->ch_index));
    322 	} else {
    323 		EDMA_WRITE(sc, EDMA_ICRH_REG, __BIT(ch->ch_index - 32));
    324 		EDMA_WRITE(sc, EDMA_IESRH_REG, __BIT(ch->ch_index - 32));
    325 	}
    326 
    327 done:
    328 	mutex_exit(&sc->sc_lock);
    329 
    330 	return ch;
    331 }
    332 
    333 /*
    334  * Free a DMA channel allocated with edma_channel_alloc
    335  */
    336 void
    337 edma_channel_free(struct edma_channel *ch)
    338 {
    339 	struct edma_softc *sc = ch->ch_sc;
    340 
    341 	KASSERT(ch->ch_nparams == 0);
    342 
    343 	mutex_enter(&sc->sc_lock);
    344 	if (ch->ch_index < 32) {
    345 		EDMA_WRITE(sc, EDMA_IECR_REG, __BIT(ch->ch_index));
    346 	} else {
    347 		EDMA_WRITE(sc, EDMA_IECRH_REG, __BIT(ch->ch_index - 32));
    348 	}
    349 	ch->ch_callback = NULL;
    350 	ch->ch_callbackarg = NULL;
    351 	edma_bit_clr(sc->sc_dmamask, ch->ch_index);
    352 	mutex_exit(&sc->sc_lock);
    353 }
    354 
    355 /*
    356  * Allocate a PaRAM entry. The driver artificially restricts the number
    357  * of PaRAM entries available for each channel to MAX_PARAM_PER_CHANNEL.
    358  * If the number of entries for the channel has been exceeded, or there
    359  * are no entries available, 0xffff is returned.
    360  */
    361 uint16_t
    362 edma_param_alloc(struct edma_channel *ch)
    363 {
    364 	struct edma_softc *sc = ch->ch_sc;
    365 	uint16_t param_entry = 0xffff;
    366 	int idx;
    367 
    368 	if (ch->ch_nparams == MAX_PARAM_PER_CHANNEL)
    369 		return param_entry;
    370 
    371 	mutex_enter(&sc->sc_lock);
    372 	for (idx = 0; idx < NUM_PARAM_SETS; idx++) {
    373 		if (!edma_bit_isset(sc->sc_parammask, idx)) {
    374 			param_entry = idx;
    375 			edma_bit_set(sc->sc_parammask, idx);
    376 			ch->ch_nparams++;
    377 			break;
    378 		}
    379 	}
    380 	mutex_exit(&sc->sc_lock);
    381 
    382 	return param_entry;
    383 }
    384 
    385 /*
    386  * Free a PaRAM entry allocated with edma_param_alloc
    387  */
    388 void
    389 edma_param_free(struct edma_channel *ch, uint16_t param_entry)
    390 {
    391 	struct edma_softc *sc = ch->ch_sc;
    392 
    393 	KASSERT(param_entry < NUM_PARAM_SETS);
    394 	KASSERT(ch->ch_nparams > 0);
    395 	KASSERT(edma_bit_isset(sc->sc_parammask, param_entry));
    396 
    397 	mutex_enter(&sc->sc_lock);
    398 	edma_bit_clr(sc->sc_parammask, param_entry);
    399 	ch->ch_nparams--;
    400 	mutex_exit(&sc->sc_lock);
    401 }
    402 
    403 /*
    404  * Update a PaRAM entry register set with caller-provided values
    405  */
    406 void
    407 edma_set_param(struct edma_channel *ch, uint16_t param_entry,
    408     struct edma_param *ep)
    409 {
    410 	struct edma_softc *sc = ch->ch_sc;
    411 
    412 	KASSERT(param_entry < NUM_PARAM_SETS);
    413 	KASSERT(ch->ch_nparams > 0);
    414 	KASSERT(edma_bit_isset(sc->sc_parammask, param_entry));
    415 
    416 	DPRINTF(1, (sc->sc_dev, "write param entry ch# %d pe %d: 0x%08x -> 0x%08x (%u, %u, %u)\n", ch->ch_index, param_entry, ep->ep_src, ep->ep_dst, ep->ep_acnt, ep->ep_bcnt, ep->ep_ccnt));
    417 	edma_write_param(sc, param_entry, ep);
    418 }
    419 
    420 /*
    421  * Enable a DMA channel: Point channel to the PaRam entry,
    422  * clear error if any, and only set the Event Enable bit.
    423  * The Even will either be generated by hardware, or with
    424  * edma_transfer_start()
    425  */
    426 int
    427 edma_transfer_enable(struct edma_channel *ch, uint16_t param_entry)
    428 {
    429 	struct edma_softc *sc = ch->ch_sc;
    430 	bus_size_t off = (ch->ch_index < 32 ? 0 : 4);
    431 	uint32_t bit = __BIT(ch->ch_index < 32 ?
    432 			     ch->ch_index : ch->ch_index - 32);
    433 
    434 	DPRINTF(1, (sc->sc_dev, "enable transfer ch# %d off %d bit %x pe %d\n", ch->ch_index, (int)off, bit, param_entry));
    435 
    436 	EDMA_WRITE(sc, EDMA_DCHMAP_REG(ch->ch_index),
    437 	    __SHIFTIN(param_entry, EDMA_DCHMAP_PAENTRY));
    438 
    439 	uint32_t ccerr = EDMA_READ(sc, EDMA_CCERR_REG);
    440 	if (ccerr) {
    441 		device_printf(sc->sc_dev, " !!! CCER %08x\n", ccerr);
    442 		EDMA_WRITE(sc, EDMA_CCERRCLR_REG, ccerr);
    443 	}
    444 
    445 	EDMA_WRITE(sc, EDMA_EESR_REG + off, bit);
    446 	return 0;
    447 }
    448 
    449 /*
    450  * Software-start a DMA channel: Set the Event bit.
    451  */
    452 int
    453 edma_transfer_start(struct edma_channel *ch)
    454 {
    455 	struct edma_softc *sc = ch->ch_sc;
    456 	bus_size_t off = (ch->ch_index < 32 ? 0 : 4);
    457 	uint32_t bit = __BIT(ch->ch_index < 32 ?
    458 			     ch->ch_index : ch->ch_index - 32);
    459 
    460 	DPRINTF(1, (sc->sc_dev, "start transfer ch# %d off %d bit %x pe %d\n", ch->ch_index, (int)off, bit));
    461 
    462 	EDMA_WRITE(sc, EDMA_ESR_REG + off, bit);
    463 	return 0;
    464 }
    465 
    466 /*
    467  * Halt a DMA transfer. Called after successful transfer, or to abort
    468  * a transfer.
    469  */
    470 void
    471 edma_halt(struct edma_channel *ch)
    472 {
    473 	struct edma_softc *sc = ch->ch_sc;
    474 	bus_size_t off = (ch->ch_index < 32 ? 0 : 4);
    475 	uint32_t bit = __BIT(ch->ch_index < 32 ?
    476 			     ch->ch_index : ch->ch_index - 32);
    477 
    478 	EDMA_WRITE(sc, EDMA_EECR_REG + off, bit);
    479 	EDMA_WRITE(sc, EDMA_ECR_REG + off, bit);
    480 	EDMA_WRITE(sc, EDMA_SECR_REG + off, bit);
    481 	EDMA_WRITE(sc, EDMA_EMCR_REG + off, bit);
    482 
    483 	EDMA_WRITE(sc, EDMA_DCHMAP_REG(ch->ch_index),
    484 	    __SHIFTIN(0, EDMA_DCHMAP_PAENTRY));
    485 }
    486 
    487 uint8_t
    488 edma_channel_index(struct edma_channel *ch)
    489 {
    490 	return ch->ch_index;
    491 }
    492 
    493 void
    494 edma_dump(struct edma_channel *ch)
    495 {
    496 	static const struct {
    497 		const char *name;
    498 		uint16_t off;
    499 	} regs[] = {
    500 		{ "ER", EDMA_ER_REG },
    501 		{ "ERH", EDMA_ERH_REG },
    502 		{ "EER", EDMA_EER_REG },
    503 		{ "EERH", EDMA_EERH_REG },
    504 		{ "SER", EDMA_SER_REG },
    505 		{ "SERH", EDMA_SERH_REG },
    506 		{ "IER", EDMA_IER_REG },
    507 		{ "IERH", EDMA_IERH_REG },
    508 		{ "IPR", EDMA_IPR_REG },
    509 		{ "IPRH", EDMA_IPRH_REG },
    510 		{ "CCERR", EDMA_CCERR_REG },
    511 		{ "CCSTAT", EDMA_CCSTAT_REG },
    512 		{ "DRAE0", EDMA_DRAE_REG(0) },
    513 		{ "DRAEH0", EDMA_DRAEH_REG(0) },
    514 		{ NULL, 0 }
    515 	};
    516 	struct edma_softc *sc = ch->ch_sc;
    517 	int i;
    518 
    519 	for (i = 0; regs[i].name; i++) {
    520 		device_printf(sc->sc_dev, "%s: %08x\n",
    521 		    regs[i].name, EDMA_READ(sc, regs[i].off));
    522 	}
    523 	device_printf(sc->sc_dev, "DCHMAP%d: %08x\n", ch->ch_index,
    524 	    EDMA_READ(sc, EDMA_DCHMAP_REG(ch->ch_index)));
    525 }
    526 
    527 void
    528 edma_dump_param(struct edma_channel *ch, uint16_t param_entry)
    529 {
    530 	struct {
    531 		const char *name;
    532 		uint16_t off;
    533 	} regs[] = {
    534 		{ "OPT", EDMA_PARAM_OPT_REG(param_entry) },
    535 		{ "CNT", EDMA_PARAM_CNT_REG(param_entry) },
    536 		{ "DST", EDMA_PARAM_DST_REG(param_entry) },
    537 		{ "BIDX", EDMA_PARAM_BIDX_REG(param_entry) },
    538 		{ "LNK", EDMA_PARAM_LNK_REG(param_entry) },
    539 		{ "CIDX", EDMA_PARAM_CIDX_REG(param_entry) },
    540 		{ "CCNT", EDMA_PARAM_CCNT_REG(param_entry) },
    541 		{ NULL, 0 }
    542 	};
    543 	struct edma_softc *sc = ch->ch_sc;
    544 	int i;
    545 
    546 	for (i = 0; regs[i].name; i++) {
    547 		device_printf(sc->sc_dev, "%s%d: %08x\n",
    548 		    regs[i].name, param_entry, EDMA_READ(sc, regs[i].off));
    549 	}
    550 }
    551