int omap3530_init_sdma(omap3530_spi_t *omap3530) { /* * Map in DMA buffer */ if (omap3530->sdma) { omap3530->dmabuf = mmap(0, OMAP3530_SPI_MAXDMALEN, PROT_READ|PROT_WRITE|PROT_NOCACHE, MAP_ANON|MAP_PHYS|MAP_PRIVATE, NOFD, 0); if (omap3530->dmabuf != MAP_FAILED) { omap3530->pdmabuf = mphys(omap3530->dmabuf); if (omap3530->pdmabuf == -1) omap3530->sdma = 0; } else omap3530->sdma = 0; } if(omap3530_sdma_attach(omap3530)) return -1; omap3530_sdma_disablespi(omap3530); return 0; }
/****************************** * DMAC functions START *****************************/ static dmac_dev_t * dmac_init (hsmci_ext_t *hsmci) { rsrc_request_t req; dmac_dev_t *dmac_dev; int timeout; /* Allocated memory for channel */ dmac_dev = (dmac_dev_t*)calloc(1, sizeof (dmac_dev_t)); if (dmac_dev == NULL) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: DMAC calloc failed\n"); return NULL; } /* Map DMAC controller */ dmac_dev->dmac = (at91sam9xx_dmac_t *)mmap_device_memory(NULL,0x200, PROT_READ | PROT_WRITE | PROT_NOCACHE, MAP_SHARED, (uint32_t)(hsmci->dbase)); if (dmac_dev->dmac == MAP_FAILED) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: DMAC MAP_FAILED\n"); free (dmac_dev); return NULL; } /* Apply DMAC channel */ memset(&req, 0, sizeof(req)); req.length = 1; req.flags = RSRCDBMGR_DMA_CHANNEL; if (rsrcdbmgr_attach( &req, 1) == -1) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: Cannot acquire DMAC channel\n"); munmap_device_memory((void *)dmac_dev->dmac, sizeof(at91sam9xx_dmac_t)); free (dmac_dev); return NULL; } else { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: Use DMAC channel %lld\n", req.start); dmac_dev->chid = req.start; } /* Stop channel in case it is running */ dmac_dev->dmac->chdr = 1 << (dmac_dev->chid); timeout = 0; while (dmac_dev->dmac->chsr & (1 <<dmac_dev->chid)) { delay (1); if (timeout++ > 2000) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "%s: release DMAC channel time out\n", __func__); break; } } /* Reset HW LLI table*/ memset(&(dmac_dev->dmac->lli[dmac_dev->chid]), 0, sizeof(at91sam9xx_dmac_lli_t)); /* Alloc buffer link list memory */ dmac_dev->lli = mmap (0, (MAX_LLI_NUM) * sizeof(at91sam9xx_dmac_bd_t), PROT_READ | PROT_WRITE | PROT_NOCACHE, MAP_SHARED, NOFD, 0); if (dmac_dev->lli == MAP_FAILED) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: DMA setup_xfer map failed\n"); return NULL; } /* Initilize the link list */ memset(dmac_dev->lli, 0, MAX_LLI_NUM * sizeof(at91sam9xx_dmac_bd_t)); /* Get link list physical address here and assign them in setup_xfer to save CPU time */ lli_mphy = (uint32_t) mphys(&dmac_dev->lli[0]); lli_size = sizeof(at91sam9xx_dmac_bd_t); /* * Associate Channel chid Src/Dst Request peripheral identifier * SRC_PER/DST_PER handshaking interface */ dmac_dev->dmac->lli[dmac_dev->chid].cfg = DMAC_SOD_DISABLE | (hsmci->dintf << 0) | (hsmci->dintf << 4); dmac_dev->dmac->en = DMAC_ENABLE; return dmac_dev; }