All of lore.kernel.org
 help / color / mirror / Atom feed
From: fengchengwen <fengchengwen@huawei.com>
To: Gagandeep Singh <g.singh@nxp.com>, <thomas@monjalon.net>, <dev@dpdk.org>
Cc: <nipun.gupta@nxp.com>
Subject: Re: [dpdk-dev] [PATCH v2 2/6] dma/dpaa: add device probe and remove functionality
Date: Tue, 2 Nov 2021 17:07:17 +0800	[thread overview]
Message-ID: <2243c59d-fbcf-eb3c-f24e-d6b943a82d73@huawei.com> (raw)
In-Reply-To: <20211101085143.2472241-3-g.singh@nxp.com>

On 2021/11/1 16:51, Gagandeep Singh wrote:
> This patch add device initialisation functionality.
> 
> Signed-off-by: Gagandeep Singh <g.singh@nxp.com>

[snip]

> +
> +static void fsl_qdma_free_chan_resources(struct fsl_qdma_chan *fsl_chan)
> +{
> +	struct fsl_qdma_queue *fsl_queue = fsl_chan->queue;
> +	struct fsl_qdma_engine *fsl_qdma = fsl_chan->qdma;
> +	struct fsl_qdma_comp *comp_temp, *_comp_temp;
> +	int id;
> +
> +	if (--fsl_queue->count)
> +		goto finally;
> +
> +	id = (fsl_qdma->block_base - fsl_queue->block_base) /
> +	      fsl_qdma->block_offset;
> +
> +	while (rte_atomic32_read(&wait_task[id]) == 1)
> +		rte_delay_us(QDMA_DELAY);
> +
> +	list_for_each_entry_safe(comp_temp, _comp_temp,
> +				 &fsl_queue->comp_used,	list) {
> +		list_del(&comp_temp->list);
> +		dma_pool_free(comp_temp->virt_addr);
> +		dma_pool_free(comp_temp->desc_virt_addr);
> +		rte_free(comp_temp);
> +	}
> +
> +	list_for_each_entry_safe(comp_temp, _comp_temp,
> +				 &fsl_queue->comp_free, list) {
> +		list_del(&comp_temp->list);
> +		dma_pool_free(comp_temp->virt_addr);
> +		dma_pool_free(comp_temp->desc_virt_addr);
> +		rte_free(comp_temp);
> +	}
> +
> +finally:
> +	fsl_qdma->desc_allocated--;
> +}

add a blank line

> +static struct fsl_qdma_queue
> +*fsl_qdma_alloc_queue_resources(struct fsl_qdma_engine *fsl_qdma)
> +{
> +	struct fsl_qdma_queue *queue_head, *queue_temp;
> +	int len, i, j;
> +	int queue_num;
> +	int blocks;
> +	unsigned int queue_size[FSL_QDMA_QUEUE_MAX];
> +
> +	queue_num = fsl_qdma->n_queues;
> +	blocks = fsl_qdma->num_blocks;
> +
> +	len = sizeof(*queue_head) * queue_num * blocks;
> +	queue_head = rte_zmalloc("qdma: queue head", len, 0);
> +	if (!queue_head)
> +		return NULL;
> +
> +	for (i = 0; i < FSL_QDMA_QUEUE_MAX; i++)
> +		queue_size[i] = QDMA_QUEUE_SIZE;
> +
> +	for (j = 0; j < blocks; j++) {
> +		for (i = 0; i < queue_num; i++) {
> +			if (queue_size[i] > FSL_QDMA_CIRCULAR_DESC_SIZE_MAX ||
> +			    queue_size[i] < FSL_QDMA_CIRCULAR_DESC_SIZE_MIN) {
> +				return NULL;
> +			}
> +			queue_temp = queue_head + i + (j * queue_num);
> +
> +			queue_temp->cq =
> +			dma_pool_alloc(sizeof(struct fsl_qdma_format) *
> +				       queue_size[i],
> +				       sizeof(struct fsl_qdma_format) *
> +				       queue_size[i], &queue_temp->bus_addr);
> +
> +			memset(queue_temp->cq, 0x0, queue_size[i] *
> +			       sizeof(struct fsl_qdma_format));
> +

move memset after check queue_temp->cq validity.

> +			if (!queue_temp->cq)

queue_head and previous queue_temp->cq need also freed.

> +				return NULL;
> +
> +			queue_temp->block_base = fsl_qdma->block_base +
> +				FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
> +			queue_temp->n_cq = queue_size[i];
> +			queue_temp->id = i;
> +			queue_temp->count = 0;
> +			queue_temp->virt_head = queue_temp->cq;
> +
> +		}
> +	}
> +	return queue_head;
> +}
> +
> +static struct fsl_qdma_queue *fsl_qdma_prep_status_queue(void)
> +{
> +	struct fsl_qdma_queue *status_head;
> +	unsigned int status_size;
> +
> +	status_size = QDMA_STATUS_SIZE;
> +	if (status_size > FSL_QDMA_CIRCULAR_DESC_SIZE_MAX ||
> +	    status_size < FSL_QDMA_CIRCULAR_DESC_SIZE_MIN) {
> +		return NULL;
> +	}
> +
> +	status_head = rte_zmalloc("qdma: status head", sizeof(*status_head), 0);
> +	if (!status_head)
> +		return NULL;
> +
> +	/*
> +	 * Buffer for queue command
> +	 */
> +	status_head->cq = dma_pool_alloc(sizeof(struct fsl_qdma_format) *
> +					 status_size,
> +					 sizeof(struct fsl_qdma_format) *
> +					 status_size,
> +					 &status_head->bus_addr);
> +
> +	memset(status_head->cq, 0x0, status_size *
> +	       sizeof(struct fsl_qdma_format));

move memset after check queue_temp->cq validity.

> +	if (!status_head->cq)

status_head also need free

> +		return NULL;
> +
> +	status_head->n_cq = status_size;
> +	status_head->virt_head = status_head->cq;
> +
> +	return status_head;
> +}
> +
> +static int fsl_qdma_halt(struct fsl_qdma_engine *fsl_qdma)
> +{
> +	void *ctrl = fsl_qdma->ctrl_base;
> +	void *block;
> +	int i, count = RETRIES;
> +	unsigned int j;
> +	u32 reg;
> +
> +	/* Disable the command queue and wait for idle state. */
> +	reg = qdma_readl(ctrl + FSL_QDMA_DMR);
> +	reg |= FSL_QDMA_DMR_DQD;
> +	qdma_writel(reg, ctrl + FSL_QDMA_DMR);
> +	for (j = 0; j < fsl_qdma->num_blocks; j++) {
> +		block = fsl_qdma->block_base +
> +			FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
> +		for (i = 0; i < FSL_QDMA_QUEUE_NUM_MAX; i++)
> +			qdma_writel(0, block + FSL_QDMA_BCQMR(i));
> +	}
> +	while (true) {
> +		reg = qdma_readl(ctrl + FSL_QDMA_DSR);
> +		if (!(reg & FSL_QDMA_DSR_DB))
> +			break;
> +		if (count-- < 0)
> +			return -EBUSY;
> +		rte_delay_us(100);
> +	}
> +
> +	for (j = 0; j < fsl_qdma->num_blocks; j++) {
> +		block = fsl_qdma->block_base +
> +			FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
> +
> +		/* Disable status queue. */
> +		qdma_writel(0, block + FSL_QDMA_BSQMR);
> +
> +		/*
> +		 * clear the command queue interrupt detect register for
> +		 * all queues.
> +		 */
> +		qdma_writel(0xffffffff, block + FSL_QDMA_BCQIDR(0));
> +	}
> +
> +	return 0;
> +}
> +
> +static int fsl_qdma_reg_init(struct fsl_qdma_engine *fsl_qdma)
> +{
> +	struct fsl_qdma_queue *fsl_queue = fsl_qdma->queue;
> +	struct fsl_qdma_queue *temp;
> +	void *ctrl = fsl_qdma->ctrl_base;
> +	void *block;
> +	u32 i, j;
> +	u32 reg;
> +	int ret, val;
> +
> +	/* Try to halt the qDMA engine first. */
> +	ret = fsl_qdma_halt(fsl_qdma);
> +	if (ret) {
> +		return ret;
> +	}
> +
> +	for (j = 0; j < fsl_qdma->num_blocks; j++) {
> +		block = fsl_qdma->block_base +
> +			FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
> +		for (i = 0; i < fsl_qdma->n_queues; i++) {
> +			temp = fsl_queue + i + (j * fsl_qdma->n_queues);
> +			/*
> +			 * Initialize Command Queue registers to
> +			 * point to the first
> +			 * command descriptor in memory.
> +			 * Dequeue Pointer Address Registers
> +			 * Enqueue Pointer Address Registers
> +			 */
> +
> +			qdma_writel(lower_32_bits(temp->bus_addr),
> +				    block + FSL_QDMA_BCQDPA_SADDR(i));
> +			qdma_writel(upper_32_bits(temp->bus_addr),
> +				    block + FSL_QDMA_BCQEDPA_SADDR(i));
> +			qdma_writel(lower_32_bits(temp->bus_addr),
> +				    block + FSL_QDMA_BCQEPA_SADDR(i));
> +			qdma_writel(upper_32_bits(temp->bus_addr),
> +				    block + FSL_QDMA_BCQEEPA_SADDR(i));
> +
> +			/* Initialize the queue mode. */
> +			reg = FSL_QDMA_BCQMR_EN;
> +			reg |= FSL_QDMA_BCQMR_CD_THLD(ilog2(temp->n_cq) - 4);
> +			reg |= FSL_QDMA_BCQMR_CQ_SIZE(ilog2(temp->n_cq) - 6);
> +			qdma_writel(reg, block + FSL_QDMA_BCQMR(i));
> +		}
> +
> +		/*
> +		 * Workaround for erratum: ERR010812.
> +		 * We must enable XOFF to avoid the enqueue rejection occurs.
> +		 * Setting SQCCMR ENTER_WM to 0x20.
> +		 */
> +
> +		qdma_writel(FSL_QDMA_SQCCMR_ENTER_WM,
> +			    block + FSL_QDMA_SQCCMR);
> +
> +		/*
> +		 * Initialize status queue registers to point to the first
> +		 * command descriptor in memory.
> +		 * Dequeue Pointer Address Registers
> +		 * Enqueue Pointer Address Registers
> +		 */
> +
> +		qdma_writel(
> +			    upper_32_bits(fsl_qdma->status[j]->bus_addr),
> +			    block + FSL_QDMA_SQEEPAR);
> +		qdma_writel(
> +			    lower_32_bits(fsl_qdma->status[j]->bus_addr),
> +			    block + FSL_QDMA_SQEPAR);
> +		qdma_writel(
> +			    upper_32_bits(fsl_qdma->status[j]->bus_addr),
> +			    block + FSL_QDMA_SQEDPAR);
> +		qdma_writel(
> +			    lower_32_bits(fsl_qdma->status[j]->bus_addr),
> +			    block + FSL_QDMA_SQDPAR);
> +		/* Desiable status queue interrupt. */
> +
> +		qdma_writel(0x0, block + FSL_QDMA_BCQIER(0));
> +		qdma_writel(0x0, block + FSL_QDMA_BSQICR);
> +		qdma_writel(0x0, block + FSL_QDMA_CQIER);
> +
> +		/* Initialize the status queue mode. */
> +		reg = FSL_QDMA_BSQMR_EN;
> +		val = ilog2(fsl_qdma->status[j]->n_cq) - 6;
> +		reg |= FSL_QDMA_BSQMR_CQ_SIZE(val);
> +		qdma_writel(reg, block + FSL_QDMA_BSQMR);
> +	}
> +
> +	reg = qdma_readl(ctrl + FSL_QDMA_DMR);
> +	reg &= ~FSL_QDMA_DMR_DQD;
> +	qdma_writel(reg, ctrl + FSL_QDMA_DMR);
> +
> +	return 0;
> +}
> +
> +static void
> +dma_release(void *fsl_chan)
> +{
> +	((struct fsl_qdma_chan *)fsl_chan)->free = true;
> +	fsl_qdma_free_chan_resources((struct fsl_qdma_chan *)fsl_chan);
> +}
> +
> +static int
> +dpaa_qdma_init(struct rte_dma_dev *dmadev)
> +{
> +	struct fsl_qdma_engine *fsl_qdma = dmadev->data->dev_private;
> +	struct fsl_qdma_chan *fsl_chan;
> +	uint64_t phys_addr;
> +	unsigned int len;
> +	int ccsr_qdma_fd;
> +	int regs_size;
> +	int ret;
> +	u32 i;
> +
> +	fsl_qdma->desc_allocated = 0;
> +	fsl_qdma->n_chans = VIRT_CHANNELS;
> +	fsl_qdma->n_queues = QDMA_QUEUES;
> +	fsl_qdma->num_blocks = QDMA_BLOCKS;
> +	fsl_qdma->block_offset = QDMA_BLOCK_OFFSET;
> +
> +	len = sizeof(*fsl_chan) * fsl_qdma->n_chans;
> +	fsl_qdma->chans = rte_zmalloc("qdma: fsl chans", len, 0);
> +	if (!fsl_qdma->chans)
> +		return -1;
> +
> +	len = sizeof(struct fsl_qdma_queue *) * fsl_qdma->num_blocks;
> +	fsl_qdma->status = rte_zmalloc("qdma: fsl status", len, 0);
> +	if (!fsl_qdma->status) {
> +		rte_free(fsl_qdma->chans);
> +		return -1;
> +	}
> +
> +	for (i = 0; i < fsl_qdma->num_blocks; i++) {
> +		rte_atomic32_init(&wait_task[i]);
> +		fsl_qdma->status[i] = fsl_qdma_prep_status_queue();
> +		if (!fsl_qdma->status[i])
> +			goto err;
> +	}
> +
> +	ccsr_qdma_fd = open("/dev/mem", O_RDWR);
> +	if (unlikely(ccsr_qdma_fd < 0)) {
> +		goto err;
> +	}
> +
> +	regs_size = fsl_qdma->block_offset * (fsl_qdma->num_blocks + 2);
> +	phys_addr = QDMA_CCSR_BASE;
> +	fsl_qdma->ctrl_base = mmap(NULL, regs_size, PROT_READ |
> +					 PROT_WRITE, MAP_SHARED,
> +					 ccsr_qdma_fd, phys_addr);
> +
> +	close(ccsr_qdma_fd);
> +	if (fsl_qdma->ctrl_base == MAP_FAILED) {
> +		goto err;
> +	}
> +
> +	fsl_qdma->status_base = fsl_qdma->ctrl_base + QDMA_BLOCK_OFFSET;
> +	fsl_qdma->block_base = fsl_qdma->status_base + QDMA_BLOCK_OFFSET;
> +
> +	fsl_qdma->queue = fsl_qdma_alloc_queue_resources(fsl_qdma);
> +	if (!fsl_qdma->queue) {
> +		munmap(fsl_qdma->ctrl_base, regs_size);
> +		goto err;
> +	}
> +
> +	for (i = 0; i < fsl_qdma->n_chans; i++) {
> +		struct fsl_qdma_chan *fsl_chan = &fsl_qdma->chans[i];
> +
> +		fsl_chan->qdma = fsl_qdma;
> +		fsl_chan->queue = fsl_qdma->queue + i % (fsl_qdma->n_queues *
> +							fsl_qdma->num_blocks);
> +		fsl_chan->free = true;
> +	}
> +
> +	ret = fsl_qdma_reg_init(fsl_qdma);
> +	if (ret) {
> +		munmap(fsl_qdma->ctrl_base, regs_size);
> +		goto err;
> +	}
> +
> +	return 0;
> +
> +err:
> +	rte_free(fsl_qdma->chans);
> +	rte_free(fsl_qdma->status);
> +
> +	return -1;
> +}
>  
>  static int
>  dpaa_qdma_probe(__rte_unused struct rte_dpaa_driver *dpaa_drv,
> -		__rte_unused struct rte_dpaa_device *dpaa_dev)
> +		struct rte_dpaa_device *dpaa_dev)
>  {
> +	struct rte_dma_dev *dmadev;
> +	int ret;
> +
> +	dmadev = rte_dma_pmd_allocate(dpaa_dev->device.name,
> +				      rte_socket_id(),
> +				      sizeof(struct fsl_qdma_engine));
> +	if (!dmadev) {
> +		return -EINVAL;
> +	}

no need {}

> +
> +	dpaa_dev->dmadev = dmadev;
> +
> +	/* Invoke PMD device initialization function */
> +	ret = dpaa_qdma_init(dmadev);
> +	if (ret) {
> +		(void)rte_dma_pmd_release(dpaa_dev->device.name);
> +		return ret;
> +	}
> +
> +	dmadev->state = RTE_DMA_DEV_READY;
>  	return 0;
>  }
>  
>  static int
> -dpaa_qdma_remove(__rte_unused struct rte_dpaa_device *dpaa_dev)
> +dpaa_qdma_remove(struct rte_dpaa_device *dpaa_dev)
>  {
> +	struct rte_dma_dev *dmadev = dpaa_dev->dmadev;
> +	struct fsl_qdma_engine *fsl_qdma = dmadev->data->dev_private;
> +	int i = 0, max = QDMA_QUEUES * QDMA_BLOCKS;
> +
> +	for (i = 0; i < max; i++) {
> +		struct fsl_qdma_chan *fsl_chan = &fsl_qdma->chans[i];
> +
> +		if (fsl_chan->free == false)
> +			dma_release(fsl_chan);

where to release rte_dma_dev ?

> +	}
> +
> +	rte_free(fsl_qdma->status);
> +	rte_free(fsl_qdma->chans);
> +
>  	return 0;
>  }
>  

[snip]

> 


  reply	other threads:[~2021-11-02  9:07 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-09 11:14 [dpdk-dev] [PATCH 0/6] Introduce DPAA DMA driver Gagandeep Singh
2021-09-09 11:14 ` [dpdk-dev] [PATCH 1/6] dma/dpaa: introduce " Gagandeep Singh
2021-09-09 11:14 ` [dpdk-dev] [PATCH 2/6] dma/dpaa: add device probe and remove functionality Gagandeep Singh
2021-09-09 11:14 ` [dpdk-dev] [PATCH 3/6] dma/dpaa: add driver logs Gagandeep Singh
2021-09-09 11:14 ` [dpdk-dev] [PATCH 4/6] dma/dpaa: support basic operations Gagandeep Singh
2021-09-09 11:14 ` [dpdk-dev] [PATCH 5/6] dma/dpaa: support DMA operations Gagandeep Singh
2021-09-09 11:15 ` [dpdk-dev] [PATCH 6/6] doc: add user guide of DPAA DMA driver Gagandeep Singh
2021-10-27 14:57 ` [dpdk-dev] [PATCH 0/6] Introduce " Thomas Monjalon
2021-10-28  4:34   ` Gagandeep Singh
2021-11-01  8:51 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh
2021-11-01  8:51   ` [dpdk-dev] [PATCH v2 1/6] dma/dpaa: introduce " Gagandeep Singh
2021-11-02  8:51     ` fengchengwen
2021-11-02 15:27       ` Thomas Monjalon
2021-11-08  9:06     ` [dpdk-dev] [PATCH v3 0/7] Introduce " Gagandeep Singh
2021-11-08  9:06       ` [dpdk-dev] [PATCH v3 1/7] dma/dpaa: introduce " Gagandeep Singh
2021-11-09  4:39         ` [dpdk-dev] [PATCH v4 0/5] Introduce " Gagandeep Singh
2021-11-09  4:39           ` [dpdk-dev] [PATCH v4 1/5] dma/dpaa: introduce " Gagandeep Singh
2021-11-09 14:44             ` Thomas Monjalon
2021-11-10  5:17               ` Gagandeep Singh
2021-11-09  4:39           ` [dpdk-dev] [PATCH v4 2/5] dma/dpaa: add device probe and remove functionality Gagandeep Singh
2021-11-09  4:39           ` [dpdk-dev] [PATCH v4 3/5] dma/dpaa: support basic operations Gagandeep Singh
2021-11-09  4:39           ` [dpdk-dev] [PATCH v4 4/5] dma/dpaa: support DMA operations Gagandeep Singh
2021-11-09  4:39           ` [dpdk-dev] [PATCH v4 5/5] dma/dpaa: support statistics Gagandeep Singh
2021-11-10 12:48           ` [dpdk-dev] [PATCH v4 0/5] Introduce DPAA DMA driver Thomas Monjalon
2021-11-08  9:06       ` [dpdk-dev] [PATCH v3 2/7] dma/dpaa: add device probe and remove functionality Gagandeep Singh
2021-11-08  9:07       ` [dpdk-dev] [PATCH v3 3/7] dma/dpaa: add driver logs Gagandeep Singh
2021-11-08  9:38         ` Thomas Monjalon
2021-11-08  9:07       ` [dpdk-dev] [PATCH v3 4/7] dma/dpaa: support basic operations Gagandeep Singh
2021-11-08  9:07       ` [dpdk-dev] [PATCH v3 5/7] dma/dpaa: support DMA operations Gagandeep Singh
2021-11-08  9:07       ` [dpdk-dev] [PATCH v3 6/7] dma/dpaa: support statistics Gagandeep Singh
2021-11-08  9:07       ` [dpdk-dev] [PATCH v3 7/7] doc: add user guide of DPAA DMA driver Gagandeep Singh
2021-11-08  9:37         ` Thomas Monjalon
2021-11-08  9:39         ` Thomas Monjalon
2021-11-01  8:51   ` [dpdk-dev] [PATCH v2 2/6] dma/dpaa: add device probe and remove functionality Gagandeep Singh
2021-11-02  9:07     ` fengchengwen [this message]
2021-11-01  8:51   ` [dpdk-dev] [PATCH v2 3/6] dma/dpaa: add driver logs Gagandeep Singh
2021-11-01  8:51   ` [dpdk-dev] [PATCH v2 4/6] dma/dpaa: support basic operations Gagandeep Singh
2021-11-02  9:21     ` fengchengwen
2021-11-01  8:51   ` [dpdk-dev] [PATCH v2 5/6] dma/dpaa: support DMA operations Gagandeep Singh
2021-11-02  9:31     ` fengchengwen
2021-11-08  9:06       ` Gagandeep Singh
2021-11-01  8:51   ` [dpdk-dev] [PATCH v2 6/6] doc: add user guide of DPAA DMA driver Gagandeep Singh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2243c59d-fbcf-eb3c-f24e-d6b943a82d73@huawei.com \
    --to=fengchengwen@huawei.com \
    --cc=dev@dpdk.org \
    --cc=g.singh@nxp.com \
    --cc=nipun.gupta@nxp.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.