int32_t omap3530_sdma_attach(omap3530_spi_t *omap3530) { int tx_idx = omap3530->sdma_tx_chid = -1; int rx_idx = omap3530->sdma_rx_chid = -1; rsrc_request_t req = { 0 }; /* Map in DMA registers */ if ((omap3530->dma4 = mmap_device_memory (0, sizeof (dma4_t), PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, DMA4_BASE_ADDR)) == MAP_FAILED) { fprintf(stderr, "Unable to mmap DMA (%s) \n", strerror (errno)); return (-1); } /* *********** SPI: transmit **************** */ req.length = 1; req.flags = RSRCDBMGR_DMA_CHANNEL; if (rsrcdbmgr_attach (&req, 1) == -1) { fprintf(stderr, "Unable to aquire DMA channels (%s) \n", strerror (errno)); munmap_device_memory (omap3530->dma4, sizeof (dma4_t)); return (-1); } tx_idx = omap3530->sdma_tx_chid = req.start; /* *********** SPI: receive **************** */ memset (&req, 0, sizeof (req)); req.length = 1; req.flags = RSRCDBMGR_DMA_CHANNEL; if (rsrcdbmgr_attach (&req, 1) == -1) { fprintf(stderr, "Unable to aquire DMA channels (%s) \n", strerror (errno)); omap3530_sdma_detach (omap3530); return (-1); } rx_idx = omap3530->sdma_rx_chid = req.start; // do some common initiailization omap3530->dma4->channel[tx_idx].cse = 1; omap3530->dma4->channel[tx_idx].cde = 1; omap3530->dma4->channel[rx_idx].cse = 1; omap3530->dma4->channel[rx_idx].cde = 1; omap3530->dma4->channel[tx_idx].cdf = 0; omap3530->dma4->channel[rx_idx].csf = 0; omap3530->dma4->channel[tx_idx].csdp = DMA4_CSDP_DATA_TYPE_8BIT; omap3530->dma4->channel[rx_idx].csdp = DMA4_CSDP_DATA_TYPE_8BIT; 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; }