Re: [PATCH] dmaengine: Add driver for Altera / Intel mSGDMA IP core

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 24, 2017 at 09:00:48AM +0200, Stefan Roese wrote:

> +#define MSGDMA_MAX_TRANS_LEN		0xffffffff

GENAMSK?

> +struct msgdma_extended_desc {
> +	u32 read_addr_lo;	/* data buffer source address low bits */
> +	u32 write_addr_lo;	/* data buffer destination address low bits */
> +	u32 len;		/* the number of bytes to transfer
> +				 * per descriptor
> +				 */
> +	u32 burst_seq_num;	/* bit 31:24 write burst
> +				 * bit 23:16 read burst
> +				 * bit 15:0  sequence number
> +				 */
> +	u32 stride;		/* bit 31:16 write stride
> +				 * bit 15:0  read stride
> +				 */
> +	u32 read_addr_hi;	/* data buffer source address high bits */
> +	u32 write_addr_hi;	/* data buffer destination address high bits */
> +	u32 control;		/* characteristics of the transfer */

nice comments but can be made kernel-doc style

> +#define MSGDMA_DESC_CTL_TR_ERR_IRQ	(0xff << 16)

GENMASK?

> +#define MSGDMA_CSR_STAT_MASK			0x3FF
> +#define MSGDMA_CSR_STAT_MASK_WITHOUT_IRQ	0x1FF

GENMASK for these two

> +
> +#define MSGDMA_CSR_STAT_BUSY_GET(v)			GET_BIT_VALUE(v, 0)

This is not defined globally and seems to be an altera define but I don't
see altera_tse.h included here ??

> +/* mSGDMA response register bit definitions */
> +#define MSGDMA_RESP_EARLY_TERM	BIT(8)
> +#define MSGDMA_RESP_ERR_MASK	0xFF

GENMASK

> +static dma_cookie_t msgdma_tx_submit(struct dma_async_tx_descriptor *tx)
> +{
> +	struct msgdma_device *mdev = to_mdev(tx->chan);
> +	struct msgdma_sw_desc *desc, *new;
> +	dma_cookie_t cookie;
> +
> +	new = tx_to_desc(tx);
> +	spin_lock_bh(&mdev->lock);
> +	cookie = dma_cookie_assign(tx);
> +
> +	if (!list_empty(&mdev->pending_list)) {
> +		desc = list_last_entry(&mdev->pending_list,
> +				       struct msgdma_sw_desc, node);
> +		if (!list_empty(&desc->tx_list))
> +			desc = list_last_entry(&desc->tx_list,
> +					       struct msgdma_sw_desc, node);
> +	}

desc is not used anywhere so not really seeing the point of this code..

> +static struct dma_async_tx_descriptor *msgdma_prep_memcpy(
> +	struct dma_chan *dchan, dma_addr_t dma_dst,
> +	dma_addr_t dma_src, size_t len, ulong flags)
> +{
> +	struct msgdma_device *mdev = to_mdev(dchan);
> +	struct msgdma_sw_desc *new, *first = NULL;
> +	struct msgdma_extended_desc *desc;
> +	size_t copy;
> +	u32 desc_cnt;
> +
> +	if (len > MSGDMA_MAX_TRANS_LEN)
> +		return NULL;


why :)

Nothing prevents you from splitting this to N descriptors of
MSGDMA_MAX_TRANS_LEN and one remaining one, though it would be great to have
this, but not a deal breaker

> +
> +	desc_cnt = DIV_ROUND_UP(len, MSGDMA_MAX_TRANS_LEN);

and in that case why would you need this??

> +static struct dma_async_tx_descriptor *msgdma_prep_sg(
> +	struct dma_chan *dchan, struct scatterlist *dst_sg,
> +	unsigned int dst_sg_len, struct scatterlist *src_sg,
> +	unsigned int src_sg_len, unsigned long flags)
> +{
> +	struct msgdma_device *mdev = to_mdev(dchan);
> +	struct msgdma_sw_desc *new, *first = NULL;
> +	void *desc = NULL;
> +	size_t len, dst_avail, src_avail;
> +	dma_addr_t dma_dst, dma_src;
> +	u32 desc_cnt = 0, i;
> +	struct scatterlist *sg;
> +
> +	for_each_sg(src_sg, sg, src_sg_len, i)
> +		desc_cnt += DIV_ROUND_UP(sg_dma_len(sg), MSGDMA_MAX_TRANS_LEN);
> +
> +	spin_lock_bh(&mdev->lock);
> +	if (desc_cnt > mdev->desc_free_cnt) {
> +		spin_unlock_bh(&mdev->lock);
> +		dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev);
> +		return NULL;
> +	}
> +	mdev->desc_free_cnt -= desc_cnt;
> +	spin_unlock_bh(&mdev->lock);
> +
> +	dst_avail = sg_dma_len(dst_sg);
> +	src_avail = sg_dma_len(src_sg);
> +
> +	/* Run until we are out of scatterlist entries */
> +	while (true) {
> +		/* Allocate and populate the descriptor */
> +		new = msgdma_get_descriptor(mdev);
> +
> +		desc = &new->hw_desc;
> +		len = min_t(size_t, src_avail, dst_avail);
> +		len = min_t(size_t, len, MSGDMA_MAX_TRANS_LEN);
> +		if (len == 0)
> +			goto fetch;
> +		dma_dst = sg_dma_address(dst_sg) + sg_dma_len(dst_sg) -
> +			dst_avail;

right justified pls

> +static struct dma_async_tx_descriptor *msgdma_prep_slave_sg(
> +	struct dma_chan *dchan, struct scatterlist *sgl,
> +	unsigned int sg_len, enum dma_transfer_direction dir,
> +	unsigned long flags, void *context)

these should be right justified as well, its quite hard to read

> +static void msgdma_copy_one(struct msgdma_device *mdev,
> +			    struct msgdma_sw_desc *desc)
> +{
> +	struct msgdma_extended_desc *hw_desc = mdev->desc;
> +
> +	/*
> +	 * Check if the DESC FIFO it not full. If its full, we need to wait
> +	 * for at least one entry to become free again
> +	 */
> +	while (ioread32(&mdev->csr->status) & MSGDMA_CSR_STAT_DESC_BUF_FULL)
> +		mdelay(1);
> +
> +	memcpy(hw_desc, &desc->hw_desc, sizeof(desc->hw_desc) - 4);

whats the magical 4 here?

> +static void msgdma_complete_descriptor(struct msgdma_device *mdev)
> +{
> +	struct msgdma_sw_desc *desc;
> +
> +	desc = list_first_entry_or_null(&mdev->active_list,
> +					struct msgdma_sw_desc, node);
> +	if (!desc)
> +		return;
> +	list_del(&desc->node);
> +	dma_cookie_complete(&desc->async_tx);
> +	list_add_tail(&desc->node, &mdev->done_list);

when do you move from done to free list

> +static void msgdma_free_descriptors(struct msgdma_device *mdev)
> +{
> +	msgdma_free_desc_list(mdev, &mdev->active_list);
> +	msgdma_free_desc_list(mdev, &mdev->pending_list);
> +	msgdma_free_desc_list(mdev, &mdev->done_list);

btw when are the descriptors in free list freedup

> +static int msgdma_alloc_chan_resources(struct dma_chan *dchan)
> +{
> +	struct msgdma_device *mdev = to_mdev(dchan);
> +	struct msgdma_sw_desc *desc;
> +	int i;
> +
> +	mdev->sw_desq = kzalloc(sizeof(*desc) * MSGDMA_DESC_NUM, GFP_KERNEL);

GFP_NOWAIT pls

> +static void msgdma_tasklet(unsigned long data)
> +{
> +	struct msgdma_device *mdev = (struct msgdma_device *)data;
> +	u32 count;
> +	u32 size;
> +	u32 status;
> +
> +	spin_lock(&mdev->lock);
> +
> +	/* Read number of responses that are available */
> +	count = ioread32(&mdev->csr->resp_fill_level);
> +	pr_debug("%s (%d): response count=%d\n", __func__, __LINE__, count);

dev_ variants please

> +static irqreturn_t msgdma_irq_handler(int irq, void *data)
> +{
> +	struct msgdma_device *mdev = data;
> +
> +	tasklet_schedule(&mdev->irq_tasklet);

not submitting next descriptor here..??

> +MODULE_DESCRIPTION("Altera mSGDMA driver");
> +MODULE_AUTHOR("Stefan Roese <sr@xxxxxxx>");
> +MODULE_LICENSE("GPL");

no alias?

-- 
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux