1 /* SPDX-License-Identifier: BSD-3-Clause
5 #include <rte_dpaa_bus.h>
6 #include <rte_dmadev_pmd.h>
9 #include "dpaa_qdma_logs.h"
26 qdma_readl(void *addr)
32 qdma_writel(u32 val, void *addr)
38 *dma_pool_alloc(int size, int aligned, dma_addr_t *phy_addr)
42 virt_addr = rte_malloc("dma pool alloc", size, aligned);
46 *phy_addr = rte_mem_virt2iova(virt_addr);
52 dma_pool_free(void *addr)
58 fsl_qdma_free_chan_resources(struct fsl_qdma_chan *fsl_chan)
60 struct fsl_qdma_queue *fsl_queue = fsl_chan->queue;
61 struct fsl_qdma_engine *fsl_qdma = fsl_chan->qdma;
62 struct fsl_qdma_comp *comp_temp, *_comp_temp;
65 if (--fsl_queue->count)
68 id = (fsl_qdma->block_base - fsl_queue->block_base) /
69 fsl_qdma->block_offset;
71 while (rte_atomic32_read(&wait_task[id]) == 1)
72 rte_delay_us(QDMA_DELAY);
74 list_for_each_entry_safe(comp_temp, _comp_temp,
75 &fsl_queue->comp_used, list) {
76 list_del(&comp_temp->list);
77 dma_pool_free(comp_temp->virt_addr);
78 dma_pool_free(comp_temp->desc_virt_addr);
82 list_for_each_entry_safe(comp_temp, _comp_temp,
83 &fsl_queue->comp_free, list) {
84 list_del(&comp_temp->list);
85 dma_pool_free(comp_temp->virt_addr);
86 dma_pool_free(comp_temp->desc_virt_addr);
91 fsl_qdma->desc_allocated--;
94 static struct fsl_qdma_queue
95 *fsl_qdma_alloc_queue_resources(struct fsl_qdma_engine *fsl_qdma)
97 struct fsl_qdma_queue *queue_head, *queue_temp;
101 unsigned int queue_size[FSL_QDMA_QUEUE_MAX];
103 queue_num = fsl_qdma->n_queues;
104 blocks = fsl_qdma->num_blocks;
106 len = sizeof(*queue_head) * queue_num * blocks;
107 queue_head = rte_zmalloc("qdma: queue head", len, 0);
111 for (i = 0; i < FSL_QDMA_QUEUE_MAX; i++)
112 queue_size[i] = QDMA_QUEUE_SIZE;
114 for (j = 0; j < blocks; j++) {
115 for (i = 0; i < queue_num; i++) {
116 if (queue_size[i] > FSL_QDMA_CIRCULAR_DESC_SIZE_MAX ||
117 queue_size[i] < FSL_QDMA_CIRCULAR_DESC_SIZE_MIN) {
118 DPAA_QDMA_ERR("Get wrong queue-sizes.\n");
121 queue_temp = queue_head + i + (j * queue_num);
124 dma_pool_alloc(sizeof(struct fsl_qdma_format) *
126 sizeof(struct fsl_qdma_format) *
127 queue_size[i], &queue_temp->bus_addr);
132 memset(queue_temp->cq, 0x0, queue_size[i] *
133 sizeof(struct fsl_qdma_format));
135 queue_temp->block_base = fsl_qdma->block_base +
136 FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
137 queue_temp->n_cq = queue_size[i];
139 queue_temp->count = 0;
140 queue_temp->pending = 0;
141 queue_temp->virt_head = queue_temp->cq;
148 for (j = 0; j < blocks; j++) {
149 for (i = 0; i < queue_num; i++) {
150 queue_temp = queue_head + i + (j * queue_num);
151 dma_pool_free(queue_temp->cq);
154 rte_free(queue_head);
160 fsl_qdma_queue *fsl_qdma_prep_status_queue(void)
162 struct fsl_qdma_queue *status_head;
163 unsigned int status_size;
165 status_size = QDMA_STATUS_SIZE;
166 if (status_size > FSL_QDMA_CIRCULAR_DESC_SIZE_MAX ||
167 status_size < FSL_QDMA_CIRCULAR_DESC_SIZE_MIN) {
168 DPAA_QDMA_ERR("Get wrong status_size.\n");
172 status_head = rte_zmalloc("qdma: status head", sizeof(*status_head), 0);
177 * Buffer for queue command
179 status_head->cq = dma_pool_alloc(sizeof(struct fsl_qdma_format) *
181 sizeof(struct fsl_qdma_format) *
183 &status_head->bus_addr);
185 if (!status_head->cq) {
186 rte_free(status_head);
190 memset(status_head->cq, 0x0, status_size *
191 sizeof(struct fsl_qdma_format));
192 status_head->n_cq = status_size;
193 status_head->virt_head = status_head->cq;
199 fsl_qdma_halt(struct fsl_qdma_engine *fsl_qdma)
201 void *ctrl = fsl_qdma->ctrl_base;
203 int i, count = RETRIES;
207 /* Disable the command queue and wait for idle state. */
208 reg = qdma_readl(ctrl + FSL_QDMA_DMR);
209 reg |= FSL_QDMA_DMR_DQD;
210 qdma_writel(reg, ctrl + FSL_QDMA_DMR);
211 for (j = 0; j < fsl_qdma->num_blocks; j++) {
212 block = fsl_qdma->block_base +
213 FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
214 for (i = 0; i < FSL_QDMA_QUEUE_NUM_MAX; i++)
215 qdma_writel(0, block + FSL_QDMA_BCQMR(i));
218 reg = qdma_readl(ctrl + FSL_QDMA_DSR);
219 if (!(reg & FSL_QDMA_DSR_DB))
226 for (j = 0; j < fsl_qdma->num_blocks; j++) {
227 block = fsl_qdma->block_base +
228 FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
230 /* Disable status queue. */
231 qdma_writel(0, block + FSL_QDMA_BSQMR);
234 * clear the command queue interrupt detect register for
237 qdma_writel(0xffffffff, block + FSL_QDMA_BCQIDR(0));
244 fsl_qdma_reg_init(struct fsl_qdma_engine *fsl_qdma)
246 struct fsl_qdma_queue *fsl_queue = fsl_qdma->queue;
247 struct fsl_qdma_queue *temp;
248 void *ctrl = fsl_qdma->ctrl_base;
254 /* Try to halt the qDMA engine first. */
255 ret = fsl_qdma_halt(fsl_qdma);
257 DPAA_QDMA_ERR("DMA halt failed!");
261 for (j = 0; j < fsl_qdma->num_blocks; j++) {
262 block = fsl_qdma->block_base +
263 FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
264 for (i = 0; i < fsl_qdma->n_queues; i++) {
265 temp = fsl_queue + i + (j * fsl_qdma->n_queues);
267 * Initialize Command Queue registers to
269 * command descriptor in memory.
270 * Dequeue Pointer Address Registers
271 * Enqueue Pointer Address Registers
274 qdma_writel(lower_32_bits(temp->bus_addr),
275 block + FSL_QDMA_BCQDPA_SADDR(i));
276 qdma_writel(upper_32_bits(temp->bus_addr),
277 block + FSL_QDMA_BCQEDPA_SADDR(i));
278 qdma_writel(lower_32_bits(temp->bus_addr),
279 block + FSL_QDMA_BCQEPA_SADDR(i));
280 qdma_writel(upper_32_bits(temp->bus_addr),
281 block + FSL_QDMA_BCQEEPA_SADDR(i));
283 /* Initialize the queue mode. */
284 reg = FSL_QDMA_BCQMR_EN;
285 reg |= FSL_QDMA_BCQMR_CD_THLD(ilog2(temp->n_cq) - 4);
286 reg |= FSL_QDMA_BCQMR_CQ_SIZE(ilog2(temp->n_cq) - 6);
287 qdma_writel(reg, block + FSL_QDMA_BCQMR(i));
291 * Workaround for erratum: ERR010812.
292 * We must enable XOFF to avoid the enqueue rejection occurs.
293 * Setting SQCCMR ENTER_WM to 0x20.
296 qdma_writel(FSL_QDMA_SQCCMR_ENTER_WM,
297 block + FSL_QDMA_SQCCMR);
300 * Initialize status queue registers to point to the first
301 * command descriptor in memory.
302 * Dequeue Pointer Address Registers
303 * Enqueue Pointer Address Registers
307 upper_32_bits(fsl_qdma->status[j]->bus_addr),
308 block + FSL_QDMA_SQEEPAR);
310 lower_32_bits(fsl_qdma->status[j]->bus_addr),
311 block + FSL_QDMA_SQEPAR);
313 upper_32_bits(fsl_qdma->status[j]->bus_addr),
314 block + FSL_QDMA_SQEDPAR);
316 lower_32_bits(fsl_qdma->status[j]->bus_addr),
317 block + FSL_QDMA_SQDPAR);
318 /* Desiable status queue interrupt. */
320 qdma_writel(0x0, block + FSL_QDMA_BCQIER(0));
321 qdma_writel(0x0, block + FSL_QDMA_BSQICR);
322 qdma_writel(0x0, block + FSL_QDMA_CQIER);
324 /* Initialize the status queue mode. */
325 reg = FSL_QDMA_BSQMR_EN;
326 val = ilog2(fsl_qdma->status[j]->n_cq) - 6;
327 reg |= FSL_QDMA_BSQMR_CQ_SIZE(val);
328 qdma_writel(reg, block + FSL_QDMA_BSQMR);
331 reg = qdma_readl(ctrl + FSL_QDMA_DMR);
332 reg &= ~FSL_QDMA_DMR_DQD;
333 qdma_writel(reg, ctrl + FSL_QDMA_DMR);
339 dma_release(void *fsl_chan)
341 ((struct fsl_qdma_chan *)fsl_chan)->free = true;
342 fsl_qdma_free_chan_resources((struct fsl_qdma_chan *)fsl_chan);
346 dpaa_qdma_init(struct rte_dma_dev *dmadev)
348 struct fsl_qdma_engine *fsl_qdma = dmadev->data->dev_private;
349 struct fsl_qdma_chan *fsl_chan;
357 fsl_qdma->desc_allocated = 0;
358 fsl_qdma->n_chans = VIRT_CHANNELS;
359 fsl_qdma->n_queues = QDMA_QUEUES;
360 fsl_qdma->num_blocks = QDMA_BLOCKS;
361 fsl_qdma->block_offset = QDMA_BLOCK_OFFSET;
363 len = sizeof(*fsl_chan) * fsl_qdma->n_chans;
364 fsl_qdma->chans = rte_zmalloc("qdma: fsl chans", len, 0);
365 if (!fsl_qdma->chans)
368 len = sizeof(struct fsl_qdma_queue *) * fsl_qdma->num_blocks;
369 fsl_qdma->status = rte_zmalloc("qdma: fsl status", len, 0);
370 if (!fsl_qdma->status) {
371 rte_free(fsl_qdma->chans);
375 for (i = 0; i < fsl_qdma->num_blocks; i++) {
376 rte_atomic32_init(&wait_task[i]);
377 fsl_qdma->status[i] = fsl_qdma_prep_status_queue();
378 if (!fsl_qdma->status[i])
382 ccsr_qdma_fd = open("/dev/mem", O_RDWR);
383 if (unlikely(ccsr_qdma_fd < 0)) {
384 DPAA_QDMA_ERR("Can not open /dev/mem for qdma CCSR map");
388 regs_size = fsl_qdma->block_offset * (fsl_qdma->num_blocks + 2);
389 phys_addr = QDMA_CCSR_BASE;
390 fsl_qdma->ctrl_base = mmap(NULL, regs_size, PROT_READ |
391 PROT_WRITE, MAP_SHARED,
392 ccsr_qdma_fd, phys_addr);
395 if (fsl_qdma->ctrl_base == MAP_FAILED) {
396 DPAA_QDMA_ERR("Can not map CCSR base qdma: Phys: %08" PRIx64
397 "size %d\n", phys_addr, regs_size);
401 fsl_qdma->status_base = fsl_qdma->ctrl_base + QDMA_BLOCK_OFFSET;
402 fsl_qdma->block_base = fsl_qdma->status_base + QDMA_BLOCK_OFFSET;
404 fsl_qdma->queue = fsl_qdma_alloc_queue_resources(fsl_qdma);
405 if (!fsl_qdma->queue) {
406 munmap(fsl_qdma->ctrl_base, regs_size);
410 for (i = 0; i < fsl_qdma->n_chans; i++) {
411 struct fsl_qdma_chan *fsl_chan = &fsl_qdma->chans[i];
413 fsl_chan->qdma = fsl_qdma;
414 fsl_chan->queue = fsl_qdma->queue + i % (fsl_qdma->n_queues *
415 fsl_qdma->num_blocks);
416 fsl_chan->free = true;
419 ret = fsl_qdma_reg_init(fsl_qdma);
421 DPAA_QDMA_ERR("Can't Initialize the qDMA engine.\n");
422 munmap(fsl_qdma->ctrl_base, regs_size);
429 rte_free(fsl_qdma->chans);
430 rte_free(fsl_qdma->status);
436 dpaa_qdma_probe(__rte_unused struct rte_dpaa_driver *dpaa_drv,
437 struct rte_dpaa_device *dpaa_dev)
439 struct rte_dma_dev *dmadev;
442 dmadev = rte_dma_pmd_allocate(dpaa_dev->device.name,
444 sizeof(struct fsl_qdma_engine));
446 DPAA_QDMA_ERR("Unable to allocate dmadevice");
450 dpaa_dev->dmadev = dmadev;
452 /* Invoke PMD device initialization function */
453 ret = dpaa_qdma_init(dmadev);
455 (void)rte_dma_pmd_release(dpaa_dev->device.name);
459 dmadev->state = RTE_DMA_DEV_READY;
464 dpaa_qdma_remove(struct rte_dpaa_device *dpaa_dev)
466 struct rte_dma_dev *dmadev = dpaa_dev->dmadev;
467 struct fsl_qdma_engine *fsl_qdma = dmadev->data->dev_private;
468 int i = 0, max = QDMA_QUEUES * QDMA_BLOCKS;
470 for (i = 0; i < max; i++) {
471 struct fsl_qdma_chan *fsl_chan = &fsl_qdma->chans[i];
473 if (fsl_chan->free == false)
474 dma_release(fsl_chan);
477 rte_free(fsl_qdma->status);
478 rte_free(fsl_qdma->chans);
480 (void)rte_dma_pmd_release(dpaa_dev->device.name);
485 static struct rte_dpaa_driver rte_dpaa_qdma_pmd;
487 static struct rte_dpaa_driver rte_dpaa_qdma_pmd = {
488 .drv_type = FSL_DPAA_QDMA,
489 .probe = dpaa_qdma_probe,
490 .remove = dpaa_qdma_remove,
493 RTE_PMD_REGISTER_DPAA(dpaa_qdma, rte_dpaa_qdma_pmd);
494 RTE_LOG_REGISTER_DEFAULT(dpaa_qdma_logtype, INFO);