1 /* $NetBSD: ti_edma.c,v 1.11 2026/10/18 09:17:08 yurix 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.11 2026/10/18 09:17:08 yurix 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/errno.h> 36 #include <sys/intr.h> 37 #include <sys/kmem.h> 38 #include <sys/mutex.h> 39 #include <sys/bus.h> 40 #include <sys/bitops.h> 41 42 #include <dev/fdt/fdtvar.h> 43 44 #include <arm/ti/ti_prcm.h> 45 #include <arm/ti/ti_edma.h> 46 47 #define MAX_DMA_CHANNELS 64 48 #define MAX_PARAM_SETS 256 49 #define MAX_PARAM_PER_CHANNEL 32 50 51 #ifdef EDMA_DEBUG 52 int edmadebug = 1; 53 #define DPRINTF(n,s) do { if ((n) <= edmadebug) device_printf s; } while (0) 54 #else 55 #define DPRINTF(n,s) do {} while (0) 56 #endif 57 58 enum edma_type { 59 EDMA_TYPE_DMA, 60 EDMA_TYPE_QDMA 61 }; 62 63 struct edma_param { 64 uint32_t ep_opt; 65 uint32_t ep_src; 66 uint32_t ep_dst; 67 uint16_t ep_bcnt; 68 uint16_t ep_acnt; 69 uint16_t ep_dstbidx; 70 uint16_t ep_srcbidx; 71 uint16_t ep_bcntrld; 72 uint16_t ep_link; 73 uint16_t ep_dstcidx; 74 uint16_t ep_srccidx; 75 uint16_t ep_ccnt; 76 }; 77 78 struct edma_softc; 79 80 struct edma_channel { 81 struct edma_softc *ch_sc; 82 enum edma_type ch_type; 83 uint8_t ch_index; 84 void (*ch_callback)(void *); 85 void *ch_callbackarg; 86 unsigned int ch_nparams; 87 uint16_t ch_ownedparams[MAX_PARAM_PER_CHANNEL]; 88 }; 89 90 struct edma_softc { 91 device_t sc_dev; 92 bus_space_tag_t sc_iot; 93 bus_space_handle_t sc_ioh; 94 kmutex_t sc_lock; 95 struct edma_channel * sc_dma[MAX_DMA_CHANNELS]; 96 97 void *sc_ih; 98 99 uint32_t sc_dmamask[MAX_DMA_CHANNELS / 32]; 100 uint32_t sc_parammask[MAX_PARAM_SETS / 32]; 101 102 /* CCCFG settings */ 103 uint32_t sc_num_channels; 104 uint32_t sc_num_params; 105 bool sc_has_chmap; 106 }; 107 108 static int edma_match(device_t, cfdata_t, void *); 109 static void edma_attach(device_t, device_t, void *); 110 111 static void edma_init(struct edma_softc *); 112 static int edma_intr(void *); 113 static void edma_write_param(struct edma_softc *, 114 unsigned int, const struct edma_param *); 115 static void edma_channel_free_params(struct edma_channel *); 116 static bool edma_bit_isset(uint32_t *, unsigned int); 117 static void edma_bit_set(uint32_t *, unsigned int); 118 static void edma_bit_clr(uint32_t *, unsigned int); 119 static void * edma_fdt_acquire(device_t, const void *, size_t, 120 void (*)(void *), void *); 121 static void edma_fdt_release(device_t, void *); 122 static int edma_fdt_transfer(device_t, void *, struct fdtbus_dma_req *); 123 static void edma_fdt_halt(device_t, void *); 124 static struct edma_channel *edma_channel_alloc(struct edma_softc *, 125 enum edma_type, unsigned int, void (*)(void *), void *); 126 static void edma_channel_free(struct edma_channel *); 127 static int edma_channel_alloc_params(struct edma_channel *, int); 128 static int edma_param_alloc(struct edma_channel *, uint16_t); 129 static void edma_set_param(struct edma_channel *, uint16_t, 130 struct edma_param *); 131 static void edma_transfer_enable(struct edma_channel *, uint16_t); 132 #ifdef notyet 133 static void edma_transfer_start(struct edma_channel *); 134 static void edma_dump(struct edma_channel *); 135 static void edma_dump_param(struct edma_channel *, uint16_t); 136 #endif 137 138 CFATTACH_DECL_NEW(ti_edma, sizeof(struct edma_softc), 139 edma_match, edma_attach, NULL, NULL); 140 141 #define EDMA_READ(sc, reg) \ 142 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)) 143 #define EDMA_WRITE(sc, reg, val) \ 144 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 145 146 static const struct fdtbus_dma_controller_func edma_fdt_funcs = { 147 .acquire = edma_fdt_acquire, 148 .release = edma_fdt_release, 149 .transfer = edma_fdt_transfer, 150 .halt = edma_fdt_halt 151 }; 152 153 static const struct device_compatible_entry compat_data[] = { 154 { .compat = "ti,edma3-tpcc" }, 155 DEVICE_COMPAT_EOL 156 }; 157 158 static int 159 edma_match(device_t parent, cfdata_t match, void *aux) 160 { 161 struct fdt_attach_args * const faa = aux; 162 163 return of_compatible_match(faa->faa_phandle, compat_data); 164 } 165 166 static void 167 edma_attach(device_t parent, device_t self, void *aux) 168 { 169 struct edma_softc *sc = device_private(self); 170 struct fdt_attach_args * const faa = aux; 171 const int phandle = faa->faa_phandle; 172 const char *ccint_name = "edma3_ccint"; 173 char intrstr[128]; 174 bus_addr_t addr; 175 bus_size_t size; 176 int idx; 177 178 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 179 aprint_error(": couldn't get registers\n"); 180 return; 181 } 182 183 sc->sc_dev = self; 184 sc->sc_iot = faa->faa_bst; 185 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 186 if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) { 187 aprint_error(": couldn't map registers\n"); 188 return; 189 } 190 191 aprint_naive("\n"); 192 aprint_normal(": EDMA Channel Controller\n"); 193 194 for (idx = 0; idx < MAX_DMA_CHANNELS; idx++) { 195 sc->sc_dma[idx] = NULL; 196 } 197 198 if (of_hasprop(phandle, "power-domains")) { 199 /* clocks are configured through fdt_powerdomain */ 200 if (fdtbus_powerdomain_enable(phandle) != 0) { 201 aprint_error(": couldn't enable powerdomain\n"); 202 return; 203 } 204 } else { 205 /* clock are configured through the prcm system */ 206 if (ti_prcm_enable_hwmod(phandle, 0) != 0) { 207 aprint_error(": couldn't enable module\n"); 208 return; 209 } 210 } 211 212 edma_init(sc); 213 214 sc->sc_ih = fdtbus_intr_establish_byname(phandle, ccint_name, 215 IPL_VM, FDT_INTR_MPSAFE, edma_intr, sc, device_xname(self)); 216 if (sc->sc_ih == NULL) { 217 aprint_error_dev(self, "failed to establish interrupt\n"); 218 return; 219 } 220 if (!fdtbus_intr_str_byname(phandle, ccint_name, intrstr, sizeof(intrstr))) { 221 aprint_error(": failed to decode interrupt\n"); 222 return; 223 } 224 225 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 226 227 fdtbus_register_dma_controller(self, phandle, &edma_fdt_funcs); 228 } 229 230 /* 231 * Hardware initialization 232 */ 233 static void 234 edma_init(struct edma_softc *sc) 235 { 236 struct edma_param param; 237 uint32_t cccfg_val; 238 int idx; 239 240 cccfg_val = EDMA_READ(sc, EDMA_CCCFG_REG); 241 242 sc->sc_has_chmap = ISSET(cccfg_val, EDMA_CCCFG_CHMAP_EXIST); 243 sc->sc_num_channels = 2 << __SHIFTOUT(cccfg_val, EDMA_CCCFG_NUM_DMACH); 244 sc->sc_num_params = 16 << __SHIFTOUT(cccfg_val, EDMA_CCCFG_NUM_PAENTRY); 245 KASSERT(sc->sc_num_channels <= MAX_DMA_CHANNELS); 246 KASSERT(sc->sc_num_params <= MAX_PARAM_SETS); 247 248 if (sc->sc_has_chmap) { 249 for (idx = 0; idx < sc->sc_num_channels; idx++) { 250 EDMA_WRITE(sc, EDMA_DCHMAP_REG(idx), 251 __SHIFTIN(0, EDMA_DCHMAP_PAENTRY)); 252 } 253 } 254 255 /* fill the PaRAM with dummies */ 256 memset(¶m, 0, sizeof(param)); 257 param.ep_bcnt = 1; 258 for (idx = 0; idx < sc->sc_num_params; idx++) { 259 edma_write_param(sc, idx, ¶m); 260 } 261 262 /* reserve PaRAM entry 0 for dummy slot */ 263 edma_bit_set(sc->sc_parammask, 0); 264 } 265 266 /* 267 * Write a PaRAM entry 268 */ 269 static void 270 edma_write_param(struct edma_softc *sc, 271 unsigned int idx, const struct edma_param *ep) 272 { 273 EDMA_WRITE(sc, EDMA_PARAM_OPT_REG(idx), ep->ep_opt); 274 EDMA_WRITE(sc, EDMA_PARAM_SRC_REG(idx), ep->ep_src); 275 EDMA_WRITE(sc, EDMA_PARAM_CNT_REG(idx), 276 __SHIFTIN(ep->ep_bcnt, EDMA_PARAM_CNT_BCNT) | 277 __SHIFTIN(ep->ep_acnt, EDMA_PARAM_CNT_ACNT)); 278 EDMA_WRITE(sc, EDMA_PARAM_DST_REG(idx), ep->ep_dst); 279 EDMA_WRITE(sc, EDMA_PARAM_BIDX_REG(idx), 280 __SHIFTIN(ep->ep_dstbidx, EDMA_PARAM_BIDX_DSTBIDX) | 281 __SHIFTIN(ep->ep_srcbidx, EDMA_PARAM_BIDX_SRCBIDX)); 282 EDMA_WRITE(sc, EDMA_PARAM_LNK_REG(idx), 283 __SHIFTIN(ep->ep_bcntrld, EDMA_PARAM_LNK_BCNTRLD) | 284 __SHIFTIN(ep->ep_link, EDMA_PARAM_LNK_LINK)); 285 EDMA_WRITE(sc, EDMA_PARAM_CIDX_REG(idx), 286 __SHIFTIN(ep->ep_dstcidx, EDMA_PARAM_CIDX_DSTCIDX) | 287 __SHIFTIN(ep->ep_srccidx, EDMA_PARAM_CIDX_SRCCIDX)); 288 EDMA_WRITE(sc, EDMA_PARAM_CCNT_REG(idx), 289 __SHIFTIN(ep->ep_ccnt, EDMA_PARAM_CCNT_CCNT)); 290 } 291 292 static bool 293 edma_bit_isset(uint32_t *bits, unsigned int bit) 294 { 295 return !!(bits[bit >> 5] & (1 << (bit & 0x1f))); 296 } 297 298 static void 299 edma_bit_set(uint32_t *bits, unsigned int bit) 300 { 301 bits[bit >> 5] |= (1 << (bit & 0x1f)); 302 } 303 304 static void 305 edma_bit_clr(uint32_t *bits, unsigned int bit) 306 { 307 bits[bit >> 5] &= ~(1 << (bit & 0x1f)); 308 } 309 310 static int 311 edma_intr(void *priv) 312 { 313 struct edma_softc *sc = priv; 314 uint64_t ipr, ier; 315 int bit, idx; 316 317 ipr = EDMA_READ(sc, EDMA_IPR_REG); 318 ipr |= (uint64_t)EDMA_READ(sc, EDMA_IPRH_REG) << 32; 319 if (ipr == 0) 320 return 0; 321 322 ier = EDMA_READ(sc, EDMA_IER_REG); 323 ier |= (uint64_t)EDMA_READ(sc, EDMA_IERH_REG) << 32; 324 325 DPRINTF(2, (sc->sc_dev, "ipr = 0x%016llx ier 0x%016llx\n", ipr, ier)); 326 327 EDMA_WRITE(sc, EDMA_ICR_REG, ipr & 0xffffffff); 328 EDMA_WRITE(sc, EDMA_ICRH_REG, ipr >> 32); 329 330 while ((bit = ffs64(ipr)) != 0) { 331 idx = bit - 1; 332 ipr &= ~__BIT(idx); 333 if (!(ier & __BIT(idx))) 334 continue; 335 if (!edma_bit_isset(sc->sc_dmamask, idx)) 336 continue; 337 338 struct edma_channel *chan = sc->sc_dma[idx]; 339 if (chan == NULL) 340 continue; 341 342 edma_channel_free_params(chan); 343 344 chan->ch_callback(chan->ch_callbackarg); 345 } 346 347 EDMA_WRITE(sc, EDMA_IEVAL_REG, EDMA_IEVAL_EVAL); 348 349 return 1; 350 } 351 352 static void * 353 edma_fdt_acquire(device_t dev, const void *data, size_t len, void (*cb)(void *), 354 void *cbarg) 355 { 356 struct edma_softc *sc = device_private(dev); 357 const uint32_t *specifier = data; 358 359 /* get channel index */ 360 if (len != 8) { 361 return NULL; 362 } 363 const u_int chan_index = be32toh(specifier[0]); 364 365 return edma_channel_alloc(sc, EDMA_TYPE_DMA, chan_index, cb, 366 cbarg); 367 } 368 369 static void 370 edma_fdt_release(device_t dev, void *priv) 371 { 372 struct edma_channel *chan = priv; 373 374 edma_channel_free(chan); 375 } 376 377 static int 378 edma_fdt_transfer(device_t dev, void *priv, struct fdtbus_dma_req *req) 379 { 380 struct edma_channel *chan = priv; 381 struct edma_param transfer; 382 int acnt, bcnt, ccnt; 383 384 if (req->dreq_nsegs > MAX_PARAM_PER_CHANNEL) { 385 return ENOBUFS; 386 } 387 388 acnt = req->dreq_dev_opt.opt_bus_width; 389 KASSERT(acnt <= UINT16_MAX); 390 KASSERT(req->dreq_dev_opt.opt_burst_len % acnt == 0); 391 bcnt = req->dreq_dev_opt.opt_burst_len / acnt; 392 KASSERT(bcnt <= UINT16_MAX); 393 394 /* allocate param entries */ 395 int error = edma_channel_alloc_params(chan, req->dreq_nsegs); 396 if (error) { 397 return error; 398 } 399 400 /* fill param entries */ 401 for (int i = 0; i < req->dreq_nsegs; i++) { 402 bus_dma_segment_t seg = req->dreq_segs[i]; 403 404 /* calculate and validate ccnt */ 405 if (seg.ds_len > INT32_MAX){ 406 edma_channel_free_params(chan); 407 return EINVAL; 408 } 409 if (seg.ds_len % (acnt * bcnt) != 0 ) { 410 edma_channel_free_params(chan); 411 return EINVAL; 412 } 413 ccnt = seg.ds_len / (acnt * bcnt); 414 if (ccnt > UINT16_MAX) { 415 edma_channel_free_params(chan); 416 return EINVAL; 417 } 418 419 /* Do an AB-synchronized transfer */ 420 transfer.ep_opt = 421 __SHIFTIN(chan->ch_index, EDMA_PARAM_OPT_TCC) 422 | EDMA_PARAM_OPT_SYNCDIM; 423 transfer.ep_acnt = acnt; 424 transfer.ep_bcnt = bcnt; 425 transfer.ep_ccnt = ccnt; 426 transfer.ep_bcntrld = 0; 427 428 if (i == req->dreq_nsegs - 1) { 429 transfer.ep_opt |= EDMA_PARAM_OPT_TCINTEN; 430 transfer.ep_link = 0xffff; 431 } else { 432 transfer.ep_link = 433 EDMA_PARAM_BASE(chan->ch_ownedparams[i + 1]); 434 } 435 436 if (req->dreq_sel == 1) { 437 transfer.ep_opt |= __SHIFTIN(2, EDMA_PARAM_OPT_FWID); 438 transfer.ep_opt |= (req->dreq_dir == FDT_DMA_READ) 439 ? EDMA_PARAM_OPT_SAM 440 : EDMA_PARAM_OPT_DAM; 441 } 442 443 if (req->dreq_dir == FDT_DMA_READ) { 444 transfer.ep_src = req->dreq_dev_phys; 445 transfer.ep_dst = seg.ds_addr; 446 transfer.ep_dstbidx = acnt; 447 transfer.ep_dstcidx = acnt * bcnt; 448 transfer.ep_srcbidx = 0; 449 transfer.ep_srccidx = 0; 450 } else { 451 transfer.ep_src = seg.ds_addr; 452 transfer.ep_dst = req->dreq_dev_phys; 453 transfer.ep_dstbidx = 0; 454 transfer.ep_dstcidx = 0; 455 transfer.ep_srcbidx = acnt; 456 transfer.ep_srccidx = acnt * bcnt; 457 } 458 459 edma_set_param(chan, chan->ch_ownedparams[i], &transfer); 460 } 461 462 edma_transfer_enable(chan, chan->ch_ownedparams[0]); 463 464 return 0; 465 } 466 467 static void 468 edma_fdt_halt(device_t dev, void *priv) 469 { 470 struct edma_channel *ch = priv; 471 struct edma_softc *sc = ch->ch_sc; 472 bus_size_t off = (ch->ch_index < 32 ? 0 : 4); 473 uint32_t bit = __BIT( 474 ch->ch_index < 32 ? ch->ch_index : ch->ch_index - 32); 475 476 EDMA_WRITE(sc, EDMA_EECR_REG + off, bit); 477 EDMA_WRITE(sc, EDMA_ECR_REG + off, bit); 478 EDMA_WRITE(sc, EDMA_SECR_REG + off, bit); 479 EDMA_WRITE(sc, EDMA_EMCR_REG + off, bit); 480 481 if (sc->sc_has_chmap) { 482 EDMA_WRITE(sc, EDMA_DCHMAP_REG(ch->ch_index), 483 __SHIFTIN(0, EDMA_DCHMAP_PAENTRY)); 484 } 485 486 edma_channel_free_params(ch); 487 } 488 489 /* 490 * Allocate a DMA channel. Currently only DMA types are supported, not QDMA. 491 * Returns NULL on failure. 492 */ 493 static struct edma_channel * 494 edma_channel_alloc(struct edma_softc *sc, enum edma_type type, 495 unsigned int drq, void (*cb)(void *), void *cbarg) 496 { 497 struct edma_channel *ch = NULL; 498 499 KASSERT(type == EDMA_TYPE_DMA); /* QDMA not implemented */ 500 KASSERT(cb != NULL); 501 KASSERT(cbarg != NULL); 502 503 if (drq >= sc->sc_num_channels) return NULL; 504 505 /* allocate before the mutex since the mutex doesn't allow sleep */ 506 ch = kmem_alloc(sizeof(struct edma_channel), KM_SLEEP); 507 if (ch == NULL) return NULL; 508 509 mutex_enter(&sc->sc_lock); 510 511 if (sc->sc_dma[drq] != NULL) { 512 kmem_free(ch, sizeof(struct edma_channel)); 513 goto done; 514 } 515 516 ch->ch_sc = sc; 517 ch->ch_type = EDMA_TYPE_DMA; 518 ch->ch_index = drq; 519 ch->ch_callback = cb; 520 ch->ch_callbackarg = cbarg; 521 ch->ch_nparams = 0; 522 sc->sc_dma[drq] = ch; 523 524 edma_bit_set(sc->sc_dmamask, drq); 525 526 EDMA_WRITE(sc, EDMA_DRAE_REG(0), sc->sc_dmamask[0]); 527 EDMA_WRITE(sc, EDMA_DRAEH_REG(0), sc->sc_dmamask[1]); 528 529 if (ch->ch_index < 32) { 530 EDMA_WRITE(sc, EDMA_ICR_REG, __BIT(ch->ch_index)); 531 EDMA_WRITE(sc, EDMA_IESR_REG, __BIT(ch->ch_index)); 532 } else { 533 EDMA_WRITE(sc, EDMA_ICRH_REG, __BIT(ch->ch_index - 32)); 534 EDMA_WRITE(sc, EDMA_IESRH_REG, __BIT(ch->ch_index - 32)); 535 } 536 537 done: 538 mutex_exit(&sc->sc_lock); 539 540 return ch; 541 } 542 543 /* 544 * Free a DMA channel allocated with edma_channel_alloc 545 */ 546 static void 547 edma_channel_free(struct edma_channel *ch) 548 { 549 struct edma_softc *sc = ch->ch_sc; 550 551 KASSERT(ch->ch_nparams == 0); 552 553 mutex_enter(&sc->sc_lock); 554 if (ch->ch_index < 32) { 555 EDMA_WRITE(sc, EDMA_IECR_REG, __BIT(ch->ch_index)); 556 } else { 557 EDMA_WRITE(sc, EDMA_IECRH_REG, __BIT(ch->ch_index - 32)); 558 } 559 560 sc->sc_dma[ch->ch_index] = NULL; 561 kmem_free(ch, sizeof(struct edma_channel)); 562 563 edma_bit_clr(sc->sc_dmamask, ch->ch_index); 564 565 mutex_exit(&sc->sc_lock); 566 } 567 568 /* 569 * Allocate 'params' PaRAM entries for channel. The driver artificially 570 * restricts the number of PaRAM entries available for each channel to 571 * MAX_PARAM_PER_CHANNEL. If the number of entries for the channel has been 572 * exceeded, or there are no entries available, an error is returned. 573 */ 574 static int 575 edma_channel_alloc_params(struct edma_channel *chan, int params) 576 { 577 struct edma_softc *sc = chan->ch_sc; 578 int error = 0; 579 int reserved = 0; 580 581 KASSERT(chan->ch_nparams == 0); 582 KASSERT(params > 0); 583 KASSERT(params < MAX_PARAM_PER_CHANNEL); 584 585 mutex_enter(&sc->sc_lock); 586 587 /* 588 * Older revision without channel map need the first entry in the chain 589 * to be a specific entry. Try to allocate that first 590 */ 591 if (!sc->sc_has_chmap) { 592 uint16_t chan_param = chan->ch_index; 593 if (!edma_param_alloc(chan, chan_param)) { 594 goto out; 595 } 596 chan->ch_ownedparams[reserved++] = chan_param; 597 } 598 599 /* 600 * Try to allocate PaRAMs starting from after the PaRAMs reserved for 601 * events. 602 */ 603 for (int i = 32; reserved < params && i < sc->sc_num_params; i++) { 604 if (edma_param_alloc(chan, i)) { 605 chan->ch_ownedparams[reserved++] = i; 606 } 607 } 608 609 out: 610 mutex_exit(&sc->sc_lock); 611 612 if (reserved != params) { 613 edma_channel_free_params(chan); 614 error = EBUSY; 615 } 616 617 return error; 618 } 619 620 /* 621 * Check if PaRAM param is available and reserve it if so. Return 1 if 622 * successful, 0 if not. The caller should hold sc->sc_lock. 623 */ 624 static int 625 edma_param_alloc(struct edma_channel *chan, uint16_t param) 626 { 627 struct edma_softc *sc = chan->ch_sc; 628 629 KASSERT(param < sc->sc_num_params); 630 631 if (edma_bit_isset(sc->sc_parammask, param)) { 632 return 0; 633 } 634 635 edma_bit_set(sc->sc_parammask, param); 636 chan->ch_nparams++; 637 638 return 1; 639 } 640 641 /* 642 * Free a PaRAM entry allocated with edma_param_alloc 643 */ 644 static void 645 edma_channel_free_params(struct edma_channel *chan) 646 { 647 struct edma_softc *sc = chan->ch_sc; 648 649 mutex_enter(&sc->sc_lock); 650 int num_params = chan->ch_nparams; 651 for (int i = 0; i < num_params; i++) { 652 uint16_t param_entry = chan->ch_ownedparams[i]; 653 654 KASSERT(param_entry < sc->sc_num_params); 655 KASSERT(chan->ch_nparams > 0); 656 KASSERT(edma_bit_isset(sc->sc_parammask, param_entry)); 657 658 edma_bit_clr(sc->sc_parammask, param_entry); 659 chan->ch_nparams--; 660 } 661 mutex_exit(&sc->sc_lock); 662 } 663 664 /* 665 * Update a PaRAM entry register set with caller-provided values 666 */ 667 static void 668 edma_set_param(struct edma_channel *ch, uint16_t param_entry, 669 struct edma_param *ep) 670 { 671 struct edma_softc *sc = ch->ch_sc; 672 673 KASSERT(param_entry < sc->sc_num_params); 674 KASSERT(ch->ch_nparams > 0); 675 KASSERT(edma_bit_isset(sc->sc_parammask, param_entry)); 676 677 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)); 678 edma_write_param(sc, param_entry, ep); 679 } 680 681 /* 682 * Enable a DMA channel: Point channel to the PaRam entry, 683 * clear error if any, and only set the Event Enable bit. 684 * The Even will either be generated by hardware, or with 685 * edma_transfer_start() 686 */ 687 static void 688 edma_transfer_enable(struct edma_channel *ch, uint16_t param_entry) 689 { 690 struct edma_softc *sc = ch->ch_sc; 691 bus_size_t off = (ch->ch_index < 32 ? 0 : 4); 692 uint32_t bit = __BIT(ch->ch_index < 32 ? 693 ch->ch_index : ch->ch_index - 32); 694 695 DPRINTF(1, (sc->sc_dev, "enable transfer ch# %d off %d bit %x pe %d\n", ch->ch_index, (int)off, bit, param_entry)); 696 697 if (sc->sc_has_chmap) { 698 EDMA_WRITE(sc, EDMA_DCHMAP_REG(ch->ch_index), 699 __SHIFTIN(param_entry, EDMA_DCHMAP_PAENTRY)); 700 } 701 702 uint32_t ccerr = EDMA_READ(sc, EDMA_CCERR_REG); 703 if (ccerr) { 704 device_printf(sc->sc_dev, " !!! CCER %08x\n", ccerr); 705 EDMA_WRITE(sc, EDMA_CCERRCLR_REG, ccerr); 706 } 707 708 EDMA_WRITE(sc, EDMA_EESR_REG + off, bit); 709 } 710 711 #ifdef notyet 712 /* 713 * Software-start a DMA channel: Set the Event bit. Before calling this, prepare 714 * transfer with edma_transfer_enable(). 715 */ 716 static void 717 edma_transfer_start(struct edma_channel *ch) 718 { 719 struct edma_softc *sc = ch->ch_sc; 720 bus_size_t off = (ch->ch_index < 32 ? 0 : 4); 721 uint32_t bit = __BIT(ch->ch_index < 32 ? 722 ch->ch_index : ch->ch_index - 32); 723 724 DPRINTF(1, (sc->sc_dev, "start transfer ch# %d off %d bit %x pe %d\n", ch->ch_index, (int)off, bit)); 725 726 EDMA_WRITE(sc, EDMA_ESR_REG + off, bit); 727 } 728 729 static void 730 edma_dump(struct edma_channel *ch) 731 { 732 static const struct { 733 const char *name; 734 uint16_t off; 735 } regs[] = { 736 { "ER", EDMA_ER_REG }, 737 { "ERH", EDMA_ERH_REG }, 738 { "EER", EDMA_EER_REG }, 739 { "EERH", EDMA_EERH_REG }, 740 { "SER", EDMA_SER_REG }, 741 { "SERH", EDMA_SERH_REG }, 742 { "IER", EDMA_IER_REG }, 743 { "IERH", EDMA_IERH_REG }, 744 { "IPR", EDMA_IPR_REG }, 745 { "IPRH", EDMA_IPRH_REG }, 746 { "CCERR", EDMA_CCERR_REG }, 747 { "CCSTAT", EDMA_CCSTAT_REG }, 748 { "DRAE0", EDMA_DRAE_REG(0) }, 749 { "DRAEH0", EDMA_DRAEH_REG(0) }, 750 { NULL, 0 } 751 }; 752 struct edma_softc *sc = ch->ch_sc; 753 int i; 754 755 for (i = 0; regs[i].name; i++) { 756 device_printf(sc->sc_dev, "%s: %08x\n", 757 regs[i].name, EDMA_READ(sc, regs[i].off)); 758 } 759 device_printf(sc->sc_dev, "DCHMAP%d: %08x\n", ch->ch_index, 760 EDMA_READ(sc, EDMA_DCHMAP_REG(ch->ch_index))); 761 } 762 763 static void 764 edma_dump_param(struct edma_channel *ch, uint16_t param_entry) 765 { 766 struct { 767 const char *name; 768 uint16_t off; 769 } regs[] = { 770 { "OPT", EDMA_PARAM_OPT_REG(param_entry) }, 771 { "SRC", EDMA_PARAM_SRC_REG(param_entry) }, 772 { "CNT", EDMA_PARAM_CNT_REG(param_entry) }, 773 { "DST", EDMA_PARAM_DST_REG(param_entry) }, 774 { "BIDX", EDMA_PARAM_BIDX_REG(param_entry) }, 775 { "LNK", EDMA_PARAM_LNK_REG(param_entry) }, 776 { "CIDX", EDMA_PARAM_CIDX_REG(param_entry) }, 777 { "CCNT", EDMA_PARAM_CCNT_REG(param_entry) }, 778 { NULL, 0 } 779 }; 780 struct edma_softc *sc = ch->ch_sc; 781 int i; 782 783 for (i = 0; regs[i].name; i++) { 784 device_printf(sc->sc_dev, "%s%d: %08x\n", 785 regs[i].name, param_entry, EDMA_READ(sc, regs[i].off)); 786 } 787 } 788 #endif 789