Lines Matching +full:compound +full:- +full:device

1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright 2014-2015 Freescale
18 #include <linux/dma-mapping.h>
21 #include "virt-dma.h"
137 (((fsl_qdma_engine)->block_offset) * (x))
140 * struct fsl_qdma_format - This is the struct holding describing compound
144 * @addr_lo: Holding the compound descriptor of the lower
145 * 32-bits address in memory 40-bit address.
146 * @addr_hi: Same as above member, but point high 8-bits in
147 * memory 40-bit address.
149 * @cfg8b_w1: Compound descriptor command queue origin produced
151 * @data: Pointer to the memory 40-bit address, describes DMA
237 return le64_to_cpu(ccdf->data) & (U64_MAX >> 24); in qdma_ccdf_addr_get64()
243 ccdf->addr_hi = upper_32_bits(addr); in qdma_desc_addr_set64()
244 ccdf->addr_lo = cpu_to_le32(lower_32_bits(addr)); in qdma_desc_addr_set64()
250 return ccdf->cfg8b_w1 & U8_MAX; in qdma_ccdf_get_queue()
256 return (le32_to_cpu(ccdf->cfg) & QDMA_CCDF_MASK) >> QDMA_CCDF_OFFSET; in qdma_ccdf_get_offset()
262 ccdf->cfg = cpu_to_le32(QDMA_CCDF_FORMAT | in qdma_ccdf_set_format()
269 return (le32_to_cpu(ccdf->status) & QDMA_CCDF_STATUS_MASK); in qdma_ccdf_get_status()
275 ccdf->status = cpu_to_le32(QDMA_CCDF_SER | status); in qdma_ccdf_set_ser()
280 csgf->cfg = cpu_to_le32(len & QDMA_SG_LEN_MASK); in qdma_csgf_set_len()
285 csgf->cfg = cpu_to_le32(QDMA_SG_FIN | (len & QDMA_SG_LEN_MASK)); in qdma_csgf_set_f()
312 struct fsl_qdma_queue *fsl_queue = fsl_chan->queue; in fsl_qdma_free_chan_resources()
313 struct fsl_qdma_engine *fsl_qdma = fsl_chan->qdma; in fsl_qdma_free_chan_resources()
318 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); in fsl_qdma_free_chan_resources()
319 vchan_get_all_descriptors(&fsl_chan->vchan, &head); in fsl_qdma_free_chan_resources()
320 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); in fsl_qdma_free_chan_resources()
322 vchan_dma_desc_free_list(&fsl_chan->vchan, &head); in fsl_qdma_free_chan_resources()
324 if (!fsl_queue->comp_pool && !fsl_queue->desc_pool) in fsl_qdma_free_chan_resources()
328 &fsl_queue->comp_used, list) { in fsl_qdma_free_chan_resources()
329 dma_pool_free(fsl_queue->comp_pool, in fsl_qdma_free_chan_resources()
330 comp_temp->virt_addr, in fsl_qdma_free_chan_resources()
331 comp_temp->bus_addr); in fsl_qdma_free_chan_resources()
332 dma_pool_free(fsl_queue->desc_pool, in fsl_qdma_free_chan_resources()
333 comp_temp->desc_virt_addr, in fsl_qdma_free_chan_resources()
334 comp_temp->desc_bus_addr); in fsl_qdma_free_chan_resources()
335 list_del(&comp_temp->list); in fsl_qdma_free_chan_resources()
340 &fsl_queue->comp_free, list) { in fsl_qdma_free_chan_resources()
341 dma_pool_free(fsl_queue->comp_pool, in fsl_qdma_free_chan_resources()
342 comp_temp->virt_addr, in fsl_qdma_free_chan_resources()
343 comp_temp->bus_addr); in fsl_qdma_free_chan_resources()
344 dma_pool_free(fsl_queue->desc_pool, in fsl_qdma_free_chan_resources()
345 comp_temp->desc_virt_addr, in fsl_qdma_free_chan_resources()
346 comp_temp->desc_bus_addr); in fsl_qdma_free_chan_resources()
347 list_del(&comp_temp->list); in fsl_qdma_free_chan_resources()
351 dma_pool_destroy(fsl_queue->comp_pool); in fsl_qdma_free_chan_resources()
352 dma_pool_destroy(fsl_queue->desc_pool); in fsl_qdma_free_chan_resources()
354 fsl_qdma->desc_allocated--; in fsl_qdma_free_chan_resources()
355 fsl_queue->comp_pool = NULL; in fsl_qdma_free_chan_resources()
356 fsl_queue->desc_pool = NULL; in fsl_qdma_free_chan_resources()
365 ccdf = fsl_comp->virt_addr; in fsl_qdma_comp_fill_memcpy()
366 csgf_desc = fsl_comp->virt_addr + 1; in fsl_qdma_comp_fill_memcpy()
367 csgf_src = fsl_comp->virt_addr + 2; in fsl_qdma_comp_fill_memcpy()
368 csgf_dest = fsl_comp->virt_addr + 3; in fsl_qdma_comp_fill_memcpy()
369 sdf = fsl_comp->desc_virt_addr; in fsl_qdma_comp_fill_memcpy()
370 ddf = fsl_comp->desc_virt_addr + 1; in fsl_qdma_comp_fill_memcpy()
372 memset(fsl_comp->virt_addr, 0, FSL_QDMA_COMMAND_BUFFER_SIZE); in fsl_qdma_comp_fill_memcpy()
373 memset(fsl_comp->desc_virt_addr, 0, FSL_QDMA_DESCRIPTOR_BUFFER_SIZE); in fsl_qdma_comp_fill_memcpy()
375 qdma_desc_addr_set64(ccdf, fsl_comp->bus_addr + 16); in fsl_qdma_comp_fill_memcpy()
379 /* Compound Command Descriptor(Frame List Table) */ in fsl_qdma_comp_fill_memcpy()
380 qdma_desc_addr_set64(csgf_desc, fsl_comp->desc_bus_addr); in fsl_qdma_comp_fill_memcpy()
381 /* It must be 32 as Compound S/G Descriptor */ in fsl_qdma_comp_fill_memcpy()
390 sdf->cmd = cpu_to_le32((FSL_QDMA_CMD_RWTTYPE << FSL_QDMA_CMD_RWTTYPE_OFFSET) | in fsl_qdma_comp_fill_memcpy()
393 ddf->cmd = cpu_to_le32((FSL_QDMA_CMD_RWTTYPE << FSL_QDMA_CMD_RWTTYPE_OFFSET) | in fsl_qdma_comp_fill_memcpy()
398 * Pre-request full command descriptor for enqueue.
405 for (i = 0; i < queue->n_cq + FSL_COMMAND_QUEUE_OVERFLLOW; i++) { in fsl_qdma_pre_request_enqueue_desc()
409 comp_temp->virt_addr = in fsl_qdma_pre_request_enqueue_desc()
410 dma_pool_alloc(queue->comp_pool, GFP_KERNEL, in fsl_qdma_pre_request_enqueue_desc()
411 &comp_temp->bus_addr); in fsl_qdma_pre_request_enqueue_desc()
412 if (!comp_temp->virt_addr) in fsl_qdma_pre_request_enqueue_desc()
415 comp_temp->desc_virt_addr = in fsl_qdma_pre_request_enqueue_desc()
416 dma_pool_alloc(queue->desc_pool, GFP_KERNEL, in fsl_qdma_pre_request_enqueue_desc()
417 &comp_temp->desc_bus_addr); in fsl_qdma_pre_request_enqueue_desc()
418 if (!comp_temp->desc_virt_addr) in fsl_qdma_pre_request_enqueue_desc()
421 list_add_tail(&comp_temp->list, &queue->comp_free); in fsl_qdma_pre_request_enqueue_desc()
427 dma_pool_free(queue->comp_pool, comp_temp->virt_addr, in fsl_qdma_pre_request_enqueue_desc()
428 comp_temp->bus_addr); in fsl_qdma_pre_request_enqueue_desc()
435 &queue->comp_free, list) { in fsl_qdma_pre_request_enqueue_desc()
436 if (comp_temp->virt_addr) in fsl_qdma_pre_request_enqueue_desc()
437 dma_pool_free(queue->comp_pool, in fsl_qdma_pre_request_enqueue_desc()
438 comp_temp->virt_addr, in fsl_qdma_pre_request_enqueue_desc()
439 comp_temp->bus_addr); in fsl_qdma_pre_request_enqueue_desc()
440 if (comp_temp->desc_virt_addr) in fsl_qdma_pre_request_enqueue_desc()
441 dma_pool_free(queue->desc_pool, in fsl_qdma_pre_request_enqueue_desc()
442 comp_temp->desc_virt_addr, in fsl_qdma_pre_request_enqueue_desc()
443 comp_temp->desc_bus_addr); in fsl_qdma_pre_request_enqueue_desc()
445 list_del(&comp_temp->list); in fsl_qdma_pre_request_enqueue_desc()
449 return -ENOMEM; in fsl_qdma_pre_request_enqueue_desc()
461 struct fsl_qdma_queue *queue = fsl_chan->queue; in fsl_qdma_request_enqueue_desc()
463 while (timeout--) { in fsl_qdma_request_enqueue_desc()
464 spin_lock_irqsave(&queue->queue_lock, flags); in fsl_qdma_request_enqueue_desc()
465 if (!list_empty(&queue->comp_free)) { in fsl_qdma_request_enqueue_desc()
466 comp_temp = list_first_entry(&queue->comp_free, in fsl_qdma_request_enqueue_desc()
469 list_del(&comp_temp->list); in fsl_qdma_request_enqueue_desc()
471 spin_unlock_irqrestore(&queue->queue_lock, flags); in fsl_qdma_request_enqueue_desc()
472 comp_temp->qchan = fsl_chan; in fsl_qdma_request_enqueue_desc()
475 spin_unlock_irqrestore(&queue->queue_lock, flags); in fsl_qdma_request_enqueue_desc()
491 queue_num = fsl_qdma->n_queues; in fsl_qdma_alloc_queue_resources()
492 block_number = fsl_qdma->block_number; in fsl_qdma_alloc_queue_resources()
497 queue_head = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); in fsl_qdma_alloc_queue_resources()
501 ret = device_property_read_u32_array(&pdev->dev, "queue-sizes", in fsl_qdma_alloc_queue_resources()
504 dev_err(&pdev->dev, "Can't get queue-sizes.\n"); in fsl_qdma_alloc_queue_resources()
511 dev_err(&pdev->dev, in fsl_qdma_alloc_queue_resources()
512 "Get wrong queue-sizes.\n"); in fsl_qdma_alloc_queue_resources()
517 queue_temp->cq = in fsl_qdma_alloc_queue_resources()
518 dmam_alloc_coherent(&pdev->dev, in fsl_qdma_alloc_queue_resources()
521 &queue_temp->bus_addr, in fsl_qdma_alloc_queue_resources()
523 if (!queue_temp->cq) in fsl_qdma_alloc_queue_resources()
525 queue_temp->block_base = fsl_qdma->block_base + in fsl_qdma_alloc_queue_resources()
527 queue_temp->n_cq = queue_size[i]; in fsl_qdma_alloc_queue_resources()
528 queue_temp->id = i; in fsl_qdma_alloc_queue_resources()
529 queue_temp->virt_head = queue_temp->cq; in fsl_qdma_alloc_queue_resources()
530 queue_temp->virt_tail = queue_temp->cq; in fsl_qdma_alloc_queue_resources()
534 INIT_LIST_HEAD(&queue_temp->comp_used); in fsl_qdma_alloc_queue_resources()
535 spin_lock_init(&queue_temp->queue_lock); in fsl_qdma_alloc_queue_resources()
547 struct device_node *np = pdev->dev.of_node; in fsl_qdma_prep_status_queue()
549 ret = of_property_read_u32(np, "status-sizes", &status_size); in fsl_qdma_prep_status_queue()
551 dev_err(&pdev->dev, "Can't get status-sizes.\n"); in fsl_qdma_prep_status_queue()
556 dev_err(&pdev->dev, "Get wrong status_size.\n"); in fsl_qdma_prep_status_queue()
559 status_head = devm_kzalloc(&pdev->dev, in fsl_qdma_prep_status_queue()
567 status_head->cq = dmam_alloc_coherent(&pdev->dev, in fsl_qdma_prep_status_queue()
570 &status_head->bus_addr, in fsl_qdma_prep_status_queue()
572 if (!status_head->cq) in fsl_qdma_prep_status_queue()
575 status_head->n_cq = status_size; in fsl_qdma_prep_status_queue()
576 status_head->virt_head = status_head->cq; in fsl_qdma_prep_status_queue()
577 status_head->virt_tail = status_head->cq; in fsl_qdma_prep_status_queue()
578 status_head->comp_pool = NULL; in fsl_qdma_prep_status_queue()
587 void __iomem *block, *ctrl = fsl_qdma->ctrl_base; in fsl_qdma_halt()
593 for (j = 0; j < fsl_qdma->block_number; j++) { in fsl_qdma_halt()
594 block = fsl_qdma->block_base + in fsl_qdma_halt()
603 if (count-- < 0) in fsl_qdma_halt()
604 return -EBUSY; in fsl_qdma_halt()
608 for (j = 0; j < fsl_qdma->block_number; j++) { in fsl_qdma_halt()
609 block = fsl_qdma->block_base + in fsl_qdma_halt()
637 struct fsl_qdma_queue *fsl_queue = fsl_qdma->queue; in fsl_qdma_queue_transfer_complete()
638 struct fsl_qdma_queue *fsl_status = fsl_qdma->status[id]; in fsl_qdma_queue_transfer_complete()
642 while (count--) { in fsl_qdma_queue_transfer_complete()
648 status_addr = fsl_status->virt_head; in fsl_qdma_queue_transfer_complete()
656 id * fsl_qdma->n_queues; in fsl_qdma_queue_transfer_complete()
661 spin_lock(&temp_queue->queue_lock); in fsl_qdma_queue_transfer_complete()
662 if (list_empty(&temp_queue->comp_used)) { in fsl_qdma_queue_transfer_complete()
664 spin_unlock(&temp_queue->queue_lock); in fsl_qdma_queue_transfer_complete()
665 return -EAGAIN; in fsl_qdma_queue_transfer_complete()
668 fsl_comp = list_first_entry(&temp_queue->comp_used, in fsl_qdma_queue_transfer_complete()
670 if (fsl_comp->bus_addr + 16 != in fsl_qdma_queue_transfer_complete()
673 spin_unlock(&temp_queue->queue_lock); in fsl_qdma_queue_transfer_complete()
674 return -EAGAIN; in fsl_qdma_queue_transfer_complete()
683 fsl_status->virt_head++; in fsl_qdma_queue_transfer_complete()
684 if (fsl_status->virt_head == fsl_status->cq in fsl_qdma_queue_transfer_complete()
685 + fsl_status->n_cq) in fsl_qdma_queue_transfer_complete()
686 fsl_status->virt_head = fsl_status->cq; in fsl_qdma_queue_transfer_complete()
688 spin_unlock(&temp_queue->queue_lock); in fsl_qdma_queue_transfer_complete()
691 list_del(&fsl_comp->list); in fsl_qdma_queue_transfer_complete()
698 fsl_status->virt_head++; in fsl_qdma_queue_transfer_complete()
699 if (fsl_status->virt_head == fsl_status->cq + fsl_status->n_cq) in fsl_qdma_queue_transfer_complete()
700 fsl_status->virt_head = fsl_status->cq; in fsl_qdma_queue_transfer_complete()
702 spin_unlock(&temp_queue->queue_lock); in fsl_qdma_queue_transfer_complete()
711 fsl_comp->vdesc.tx_result.result = in fsl_qdma_queue_transfer_complete()
715 fsl_comp->vdesc.tx_result.result = in fsl_qdma_queue_transfer_complete()
721 fsl_comp->vdesc.tx_result.result = in fsl_qdma_queue_transfer_complete()
723 dev_err(fsl_qdma->dma_dev.dev, in fsl_qdma_queue_transfer_complete()
729 spin_lock(&fsl_comp->qchan->vchan.lock); in fsl_qdma_queue_transfer_complete()
730 vchan_cookie_complete(&fsl_comp->vdesc); in fsl_qdma_queue_transfer_complete()
731 fsl_comp->qchan->status = DMA_COMPLETE; in fsl_qdma_queue_transfer_complete()
732 spin_unlock(&fsl_comp->qchan->vchan.lock); in fsl_qdma_queue_transfer_complete()
742 void __iomem *status = fsl_qdma->status_base; in fsl_qdma_error_handler()
755 dev_err(fsl_qdma->dma_dev.dev, in fsl_qdma_error_handler()
756 "DMA transaction error! (%x: %x-%x-%x-%x)\n", in fsl_qdma_error_handler()
769 void __iomem *block, *ctrl = fsl_qdma->ctrl_base; in fsl_qdma_queue_handler()
771 id = irq - fsl_qdma->irq_base; in fsl_qdma_queue_handler()
772 if (id < 0 && id > fsl_qdma->block_number) { in fsl_qdma_queue_handler()
773 dev_err(fsl_qdma->dma_dev.dev, in fsl_qdma_queue_handler()
775 irq, fsl_qdma->irq_base); in fsl_qdma_queue_handler()
778 block = fsl_qdma->block_base + in fsl_qdma_queue_handler()
791 dev_err(fsl_qdma->dma_dev.dev, "QDMA: status err!\n"); in fsl_qdma_queue_handler()
810 fsl_qdma->error_irq = in fsl_qdma_irq_init()
811 platform_get_irq_byname(pdev, "qdma-error"); in fsl_qdma_irq_init()
812 if (fsl_qdma->error_irq < 0) in fsl_qdma_irq_init()
813 return fsl_qdma->error_irq; in fsl_qdma_irq_init()
815 ret = devm_request_irq(&pdev->dev, fsl_qdma->error_irq, in fsl_qdma_irq_init()
819 dev_err(&pdev->dev, "Can't register qDMA controller IRQ.\n"); in fsl_qdma_irq_init()
823 for (i = 0; i < fsl_qdma->block_number; i++) { in fsl_qdma_irq_init()
824 sprintf(irq_name, "qdma-queue%d", i); in fsl_qdma_irq_init()
825 fsl_qdma->queue_irq[i] = in fsl_qdma_irq_init()
828 if (fsl_qdma->queue_irq[i] < 0) in fsl_qdma_irq_init()
829 return fsl_qdma->queue_irq[i]; in fsl_qdma_irq_init()
831 ret = devm_request_irq(&pdev->dev, in fsl_qdma_irq_init()
832 fsl_qdma->queue_irq[i], in fsl_qdma_irq_init()
838 dev_err(&pdev->dev, in fsl_qdma_irq_init()
844 ret = irq_set_affinity_hint(fsl_qdma->queue_irq[i], in fsl_qdma_irq_init()
847 dev_err(&pdev->dev, in fsl_qdma_irq_init()
850 fsl_qdma->queue_irq[i]); in fsl_qdma_irq_init()
863 devm_free_irq(&pdev->dev, fsl_qdma->error_irq, fsl_qdma); in fsl_qdma_irq_exit()
864 for (i = 0; i < fsl_qdma->block_number; i++) in fsl_qdma_irq_exit()
865 devm_free_irq(&pdev->dev, fsl_qdma->queue_irq[i], fsl_qdma); in fsl_qdma_irq_exit()
873 void __iomem *status = fsl_qdma->status_base; in fsl_qdma_reg_init()
874 void __iomem *block, *ctrl = fsl_qdma->ctrl_base; in fsl_qdma_reg_init()
875 struct fsl_qdma_queue *fsl_queue = fsl_qdma->queue; in fsl_qdma_reg_init()
880 dev_err(fsl_qdma->dma_dev.dev, "DMA halt failed!"); in fsl_qdma_reg_init()
884 for (i = 0; i < fsl_qdma->block_number; i++) { in fsl_qdma_reg_init()
890 block = fsl_qdma->block_base + in fsl_qdma_reg_init()
896 for (j = 0; j < fsl_qdma->block_number; j++) { in fsl_qdma_reg_init()
897 block = fsl_qdma->block_base + in fsl_qdma_reg_init()
899 for (i = 0; i < fsl_qdma->n_queues; i++) { in fsl_qdma_reg_init()
900 temp = fsl_queue + i + (j * fsl_qdma->n_queues); in fsl_qdma_reg_init()
909 qdma_writel(fsl_qdma, temp->bus_addr, in fsl_qdma_reg_init()
911 qdma_writel(fsl_qdma, temp->bus_addr, in fsl_qdma_reg_init()
916 reg |= FSL_QDMA_BCQMR_CD_THLD(ilog2(temp->n_cq) - 4); in fsl_qdma_reg_init()
917 reg |= FSL_QDMA_BCQMR_CQ_SIZE(ilog2(temp->n_cq) - 6); in fsl_qdma_reg_init()
937 qdma_writel(fsl_qdma, fsl_qdma->status[j]->bus_addr, in fsl_qdma_reg_init()
939 qdma_writel(fsl_qdma, fsl_qdma->status[j]->bus_addr, in fsl_qdma_reg_init()
954 (fsl_qdma->status[j]->n_cq) - 6); in fsl_qdma_reg_init()
985 return vchan_tx_prep(&fsl_chan->vchan, &fsl_comp->vdesc, flags); in fsl_qdma_prep_memcpy()
993 struct fsl_qdma_queue *fsl_queue = fsl_chan->queue; in fsl_qdma_enqueue_desc()
994 void __iomem *block = fsl_queue->block_base; in fsl_qdma_enqueue_desc()
996 reg = qdma_readl(fsl_chan->qdma, block + FSL_QDMA_BCQSR(fsl_queue->id)); in fsl_qdma_enqueue_desc()
999 vdesc = vchan_next_desc(&fsl_chan->vchan); in fsl_qdma_enqueue_desc()
1002 list_del(&vdesc->node); in fsl_qdma_enqueue_desc()
1005 memcpy(fsl_queue->virt_head++, in fsl_qdma_enqueue_desc()
1006 fsl_comp->virt_addr, sizeof(struct fsl_qdma_format)); in fsl_qdma_enqueue_desc()
1007 if (fsl_queue->virt_head == fsl_queue->cq + fsl_queue->n_cq) in fsl_qdma_enqueue_desc()
1008 fsl_queue->virt_head = fsl_queue->cq; in fsl_qdma_enqueue_desc()
1010 list_add_tail(&fsl_comp->list, &fsl_queue->comp_used); in fsl_qdma_enqueue_desc()
1012 reg = qdma_readl(fsl_chan->qdma, block + FSL_QDMA_BCQMR(fsl_queue->id)); in fsl_qdma_enqueue_desc()
1014 qdma_writel(fsl_chan->qdma, reg, block + FSL_QDMA_BCQMR(fsl_queue->id)); in fsl_qdma_enqueue_desc()
1015 fsl_chan->status = DMA_IN_PROGRESS; in fsl_qdma_enqueue_desc()
1025 fsl_queue = fsl_comp->qchan->queue; in fsl_qdma_free_desc()
1027 spin_lock_irqsave(&fsl_queue->queue_lock, flags); in fsl_qdma_free_desc()
1028 list_add_tail(&fsl_comp->list, &fsl_queue->comp_free); in fsl_qdma_free_desc()
1029 spin_unlock_irqrestore(&fsl_queue->queue_lock, flags); in fsl_qdma_free_desc()
1036 struct fsl_qdma_queue *fsl_queue = fsl_chan->queue; in fsl_qdma_issue_pending()
1038 spin_lock_irqsave(&fsl_queue->queue_lock, flags); in fsl_qdma_issue_pending()
1039 spin_lock(&fsl_chan->vchan.lock); in fsl_qdma_issue_pending()
1040 if (vchan_issue_pending(&fsl_chan->vchan)) in fsl_qdma_issue_pending()
1042 spin_unlock(&fsl_chan->vchan.lock); in fsl_qdma_issue_pending()
1043 spin_unlock_irqrestore(&fsl_queue->queue_lock, flags); in fsl_qdma_issue_pending()
1050 vchan_synchronize(&fsl_chan->vchan); in fsl_qdma_synchronize()
1059 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); in fsl_qdma_terminate_all()
1060 vchan_get_all_descriptors(&fsl_chan->vchan, &head); in fsl_qdma_terminate_all()
1061 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); in fsl_qdma_terminate_all()
1062 vchan_dma_desc_free_list(&fsl_chan->vchan, &head); in fsl_qdma_terminate_all()
1070 struct fsl_qdma_engine *fsl_qdma = fsl_chan->qdma; in fsl_qdma_alloc_chan_resources()
1071 struct fsl_qdma_queue *fsl_queue = fsl_chan->queue; in fsl_qdma_alloc_chan_resources()
1073 if (fsl_queue->comp_pool && fsl_queue->desc_pool) in fsl_qdma_alloc_chan_resources()
1074 return fsl_qdma->desc_allocated; in fsl_qdma_alloc_chan_resources()
1076 INIT_LIST_HEAD(&fsl_queue->comp_free); in fsl_qdma_alloc_chan_resources()
1081 fsl_queue->comp_pool = in fsl_qdma_alloc_chan_resources()
1083 chan->device->dev, in fsl_qdma_alloc_chan_resources()
1086 if (!fsl_queue->comp_pool) in fsl_qdma_alloc_chan_resources()
1087 return -ENOMEM; in fsl_qdma_alloc_chan_resources()
1092 fsl_queue->desc_pool = in fsl_qdma_alloc_chan_resources()
1094 chan->device->dev, in fsl_qdma_alloc_chan_resources()
1097 if (!fsl_queue->desc_pool) in fsl_qdma_alloc_chan_resources()
1102 dev_err(chan->device->dev, in fsl_qdma_alloc_chan_resources()
1107 fsl_qdma->desc_allocated++; in fsl_qdma_alloc_chan_resources()
1108 return fsl_qdma->desc_allocated; in fsl_qdma_alloc_chan_resources()
1111 dma_pool_destroy(fsl_queue->desc_pool); in fsl_qdma_alloc_chan_resources()
1113 dma_pool_destroy(fsl_queue->comp_pool); in fsl_qdma_alloc_chan_resources()
1114 return -ENOMEM; in fsl_qdma_alloc_chan_resources()
1124 struct device_node *np = pdev->dev.of_node; in fsl_qdma_probe()
1126 ret = of_property_read_u32(np, "dma-channels", &chans); in fsl_qdma_probe()
1128 dev_err(&pdev->dev, "Can't get dma-channels.\n"); in fsl_qdma_probe()
1132 ret = of_property_read_u32(np, "block-offset", &blk_off); in fsl_qdma_probe()
1134 dev_err(&pdev->dev, "Can't get block-offset.\n"); in fsl_qdma_probe()
1138 ret = of_property_read_u32(np, "block-number", &blk_num); in fsl_qdma_probe()
1140 dev_err(&pdev->dev, "Can't get block-number.\n"); in fsl_qdma_probe()
1147 fsl_qdma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); in fsl_qdma_probe()
1149 return -ENOMEM; in fsl_qdma_probe()
1152 fsl_qdma->chans = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); in fsl_qdma_probe()
1153 if (!fsl_qdma->chans) in fsl_qdma_probe()
1154 return -ENOMEM; in fsl_qdma_probe()
1157 fsl_qdma->status = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); in fsl_qdma_probe()
1158 if (!fsl_qdma->status) in fsl_qdma_probe()
1159 return -ENOMEM; in fsl_qdma_probe()
1162 fsl_qdma->queue_irq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); in fsl_qdma_probe()
1163 if (!fsl_qdma->queue_irq) in fsl_qdma_probe()
1164 return -ENOMEM; in fsl_qdma_probe()
1166 ret = of_property_read_u32(np, "fsl,dma-queues", &queues); in fsl_qdma_probe()
1168 dev_err(&pdev->dev, "Can't get queues.\n"); in fsl_qdma_probe()
1172 fsl_qdma->desc_allocated = 0; in fsl_qdma_probe()
1173 fsl_qdma->n_chans = chans; in fsl_qdma_probe()
1174 fsl_qdma->n_queues = queues; in fsl_qdma_probe()
1175 fsl_qdma->block_number = blk_num; in fsl_qdma_probe()
1176 fsl_qdma->block_offset = blk_off; in fsl_qdma_probe()
1178 mutex_init(&fsl_qdma->fsl_qdma_mutex); in fsl_qdma_probe()
1180 for (i = 0; i < fsl_qdma->block_number; i++) { in fsl_qdma_probe()
1181 fsl_qdma->status[i] = fsl_qdma_prep_status_queue(pdev); in fsl_qdma_probe()
1182 if (!fsl_qdma->status[i]) in fsl_qdma_probe()
1183 return -ENOMEM; in fsl_qdma_probe()
1185 fsl_qdma->ctrl_base = devm_platform_ioremap_resource(pdev, 0); in fsl_qdma_probe()
1186 if (IS_ERR(fsl_qdma->ctrl_base)) in fsl_qdma_probe()
1187 return PTR_ERR(fsl_qdma->ctrl_base); in fsl_qdma_probe()
1189 fsl_qdma->status_base = devm_platform_ioremap_resource(pdev, 1); in fsl_qdma_probe()
1190 if (IS_ERR(fsl_qdma->status_base)) in fsl_qdma_probe()
1191 return PTR_ERR(fsl_qdma->status_base); in fsl_qdma_probe()
1193 fsl_qdma->block_base = devm_platform_ioremap_resource(pdev, 2); in fsl_qdma_probe()
1194 if (IS_ERR(fsl_qdma->block_base)) in fsl_qdma_probe()
1195 return PTR_ERR(fsl_qdma->block_base); in fsl_qdma_probe()
1196 fsl_qdma->queue = fsl_qdma_alloc_queue_resources(pdev, fsl_qdma); in fsl_qdma_probe()
1197 if (!fsl_qdma->queue) in fsl_qdma_probe()
1198 return -ENOMEM; in fsl_qdma_probe()
1200 fsl_qdma->irq_base = platform_get_irq_byname(pdev, "qdma-queue0"); in fsl_qdma_probe()
1201 if (fsl_qdma->irq_base < 0) in fsl_qdma_probe()
1202 return fsl_qdma->irq_base; in fsl_qdma_probe()
1204 fsl_qdma->feature = of_property_read_bool(np, "big-endian"); in fsl_qdma_probe()
1205 INIT_LIST_HEAD(&fsl_qdma->dma_dev.channels); in fsl_qdma_probe()
1207 for (i = 0; i < fsl_qdma->n_chans; i++) { in fsl_qdma_probe()
1208 struct fsl_qdma_chan *fsl_chan = &fsl_qdma->chans[i]; in fsl_qdma_probe()
1210 fsl_chan->qdma = fsl_qdma; in fsl_qdma_probe()
1211 fsl_chan->queue = fsl_qdma->queue + i % (fsl_qdma->n_queues * in fsl_qdma_probe()
1212 fsl_qdma->block_number); in fsl_qdma_probe()
1213 fsl_chan->vchan.desc_free = fsl_qdma_free_desc; in fsl_qdma_probe()
1214 vchan_init(&fsl_chan->vchan, &fsl_qdma->dma_dev); in fsl_qdma_probe()
1217 dma_cap_set(DMA_MEMCPY, fsl_qdma->dma_dev.cap_mask); in fsl_qdma_probe()
1219 fsl_qdma->dma_dev.dev = &pdev->dev; in fsl_qdma_probe()
1220 fsl_qdma->dma_dev.device_free_chan_resources = in fsl_qdma_probe()
1222 fsl_qdma->dma_dev.device_alloc_chan_resources = in fsl_qdma_probe()
1224 fsl_qdma->dma_dev.device_tx_status = dma_cookie_status; in fsl_qdma_probe()
1225 fsl_qdma->dma_dev.device_prep_dma_memcpy = fsl_qdma_prep_memcpy; in fsl_qdma_probe()
1226 fsl_qdma->dma_dev.device_issue_pending = fsl_qdma_issue_pending; in fsl_qdma_probe()
1227 fsl_qdma->dma_dev.device_synchronize = fsl_qdma_synchronize; in fsl_qdma_probe()
1228 fsl_qdma->dma_dev.device_terminate_all = fsl_qdma_terminate_all; in fsl_qdma_probe()
1230 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)); in fsl_qdma_probe()
1232 dev_err(&pdev->dev, "dma_set_mask failure.\n"); in fsl_qdma_probe()
1240 dev_err(&pdev->dev, "Can't Initialize the qDMA engine.\n"); in fsl_qdma_probe()
1248 ret = dma_async_device_register(&fsl_qdma->dma_dev); in fsl_qdma_probe()
1250 dev_err(&pdev->dev, "Can't register NXP Layerscape qDMA engine.\n"); in fsl_qdma_probe()
1262 &dmadev->channels, vchan.chan.device_node) { in fsl_qdma_cleanup_vchan()
1263 list_del(&chan->vchan.chan.device_node); in fsl_qdma_cleanup_vchan()
1264 tasklet_kill(&chan->vchan.task); in fsl_qdma_cleanup_vchan()
1270 struct device_node *np = pdev->dev.of_node; in fsl_qdma_remove()
1274 fsl_qdma_cleanup_vchan(&fsl_qdma->dma_dev); in fsl_qdma_remove()
1276 dma_async_device_unregister(&fsl_qdma->dma_dev); in fsl_qdma_remove()
1280 { .compatible = "fsl,ls1021a-qdma", },
1287 .name = "fsl-qdma",
1296 MODULE_ALIAS("platform:fsl-qdma");