linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sekhar Nori <nsekhar-l0cyMroinI0@public.gmane.org>
To: Joel Fernandes <joelf-l0cyMroinI0@public.gmane.org>
Cc: Mark Brown <broonie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>,
	Grant Likely
	<grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>,
	Sricharan R <r.sricharan-l0cyMroinI0@public.gmane.org>,
	Russell King <linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org>,
	Vinod Koul <vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	Lokesh Vutla <lokeshvutla-l0cyMroinI0@public.gmane.org>,
	Chris Ball <cjb-2X9k7bc8m7Mdnm+yROfE0A@public.gmane.org>,
	Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>,
	Rajendra Nayak <rnayak-l0cyMroinI0@public.gmane.org>,
	Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>,
	Jason Kridner <jkridner-hcmAuCOw+vXj4SYmN/TMmA@public.gmane.org>,
	Linux OMAP List
	<linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	Linux ARM Kernel List
	<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>,
	Linux DaVinci Kernel List
	<davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org>,
	Balaji TK <balajitk-l0cyMroinI0@public.gmane.org>,
	Linux MMC List
	<linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	Linux Kernel Mailing List
	<linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	Santosh Shilimkar <santosh.shilim>
Subject: Re: [PATCH v3 09/12] dma: edma: Implement multiple linked sets for continuity
Date: Mon, 12 Aug 2013 18:56:55 +0000	[thread overview]
Message-ID: <52092FF7.7040508@ti.com> (raw)
In-Reply-To: <1375719297-12871-10-git-send-email-joelf-l0cyMroinI0@public.gmane.org>

On Monday 05 August 2013 04:14 PM, Joel Fernandes wrote:
> Here we implement splitting up of the total MAX number of slots
> available for a channel into 2 cyclically linked sets. Transfer
> completion Interrupts are enabled on both linked sets and respective
> handler recycles them on completion to process the next linked set.
> Both linked sets are cyclically linked to each other to ensure
> continuity of DMA operations. Interrupt handlers execute asynchronously
> to the EDMA events and recycles the linked sets at the right time,
> as a result EDMA is not blocked or dependent on interrupts and DMA
> continues till the end of the SG-lists without any interruption.
> 
> Suggested-by: Sekhar Nori <nsekhar-l0cyMroinI0@public.gmane.org>
> Signed-off-by: Joel Fernandes <joelf-l0cyMroinI0@public.gmane.org>
> ---
>  drivers/dma/edma.c |  157 +++++++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 118 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
> index df50a04..70923a2 100644
> --- a/drivers/dma/edma.c
> +++ b/drivers/dma/edma.c
> @@ -48,6 +48,7 @@
>  
>  /* Max of 16 segments per channel to conserve PaRAM slots */
>  #define MAX_NR_SG		16
> +#define MAX_NR_LS		(MAX_NR_SG >> 1)
>  #define EDMA_MAX_SLOTS		(MAX_NR_SG+1)
>  #define EDMA_DESCRIPTORS	16
>  
> @@ -57,6 +58,7 @@ struct edma_desc {
>  	int				absync;
>  	int				pset_nr;
>  	int				total_processed;
> +	int				next_setup_linkset;
>  	struct edmacc_param		pset[0];
>  };
>  
> @@ -140,7 +142,9 @@ static void edma_execute(struct edma_chan *echan)
>  	struct edma_desc *edesc;
>  	struct device *dev = echan->vchan.chan.device->dev;
>  
> -	int i, j, total_left, total_process;
> +	int i, total_left, total_link_set;
> +	int ls_cur_off, ls_next_off, slot_off;
> +	struct edmacc_param tmp_param;
>  
>  	/* If either we processed all psets or we're still not started */
>  	if (!echan->edesc ||
> @@ -159,48 +163,121 @@ static void edma_execute(struct edma_chan *echan)
>  
>  	/* Find out how many left */
>  	total_left = edesc->pset_nr - edesc->total_processed;
> -	total_process = total_left > MAX_NR_SG ? MAX_NR_SG : total_left;
> -
> -
> -	/* Write descriptor PaRAM set(s) */
> -	for (i = 0; i < total_process; i++) {
> -		j = i + edesc->total_processed;
> -		edma_write_slot(echan->slot[i], &edesc->pset[j]);
> -		dev_dbg(echan->vchan.chan.device->dev,
> -			"\n pset[%d]:\n"
> -			"  chnum\t%d\n"
> -			"  slot\t%d\n"
> -			"  opt\t%08x\n"
> -			"  src\t%08x\n"
> -			"  dst\t%08x\n"
> -			"  abcnt\t%08x\n"
> -			"  ccnt\t%08x\n"
> -			"  bidx\t%08x\n"
> -			"  cidx\t%08x\n"
> -			"  lkrld\t%08x\n",
> -			j, echan->ch_num, echan->slot[i],
> -			edesc->pset[j].opt,
> -			edesc->pset[j].src,
> -			edesc->pset[j].dst,
> -			edesc->pset[j].a_b_cnt,
> -			edesc->pset[j].ccnt,
> -			edesc->pset[j].src_dst_bidx,
> -			edesc->pset[j].src_dst_cidx,
> -			edesc->pset[j].link_bcntrld);
> -		/* Link to the previous slot if not the last set */
> -		if (i != (total_process - 1))

> +	total_link_set = total_left > MAX_NR_LS ? MAX_NR_LS : total_left;

The name you gave here sounds like this is defining total number of
linked PaRAM sets. Rather this is actually tracking the number of PaRAM
sets (slots) in current linked set, correct? Then may be just call it
'nslots' or even 'num_slots'? There are just too many variables with
"total" prefix to keep track of in this function!

> +
> +	/* First time, setup 2 cyclically linked sets, each containing half
> +	   the slots allocated for this channel */
> +	if (edesc->total_processed == 0) {

We dont need to check for this case for every DMA_COMPLETE interrupt.
May be move the initial setup to another function called from
edma_issue_pending()?

> +		for (i = 0; i < total_link_set; i++) {
> +			edma_write_slot(echan->slot[i+1], &edesc->pset[i]);
> +
> +			if (i != total_link_set - 1) {
> +				edma_link(echan->slot[i+1], echan->slot[i+2]);
> +				dump_pset(echan, echan->slot[i+1],
> +					  edesc->pset, i);
> +			}
> +		}
> +
> +		edesc->total_processed += total_link_set;
> +
> +		total_left = edesc->pset_nr - edesc->total_processed;
> +
> +		total_link_set = total_left > MAX_NR_LS ?
> +				 MAX_NR_LS : total_left;
> +
> +		if (total_link_set) {
> +			/* Don't setup interrupt for first linked set for cases
> +			   where total pset_nr is strictly within MAX_NR size */

See Documentation/CodingStyle for multi-line commenting style.

> +			if (total_left > total_link_set)
> +				edma_enable_interrupt(echan->slot[i]);
> +
> +			/* Setup link between linked set 0 to set 1 */
>  			edma_link(echan->slot[i], echan->slot[i+1]);
> -		/* Final pset links to the dummy pset */
> -		else
> +
> +			dump_pset(echan, echan->slot[i], edesc->pset, i-1);
> +
> +			/* Write out linked set 1 */
> +			for (; i < total_link_set + MAX_NR_LS; i++) {
> +				edma_write_slot(echan->slot[i+1],
> +						&edesc->pset[i]);
> +
> +				if (i != total_link_set + MAX_NR_LS - 1) {
> +					edma_link(echan->slot[i+1],
> +						  echan->slot[i+2]);
> +					dump_pset(echan, echan->slot[i+1],
> +						  edesc->pset, i);
> +				}
> +			}
> +
> +			edesc->total_processed += total_link_set;
> +			total_left = edesc->pset_nr - edesc->total_processed;

There is way too much duplication of code here mainly because you
decided not to loop twice in the course of setting up the two linked
sets. Can you use a loop instead?

> +
> +			if (total_left)
> +				/* Setup a link from linked set 1 to set 0 */
> +				edma_link(echan->slot[i], echan->slot[1]);

If you have more SGs to service at the end of setting up the two linked
sets, you should stop right there and wait for CPU to recycle the linked
sets. Right now you are setup for re-DMAing old data.

You wont hit this issue in testing because you have setup an interrupt
for LS0 and that will most likely service before LS1 completes but we
cannot rely on that timing.

Just link to dummy at end of LS1 to stall the DMA and wait for the
completion handler to come-in and restart the DMA after recycling LS0.

I haven't reviewed rest of the patch. Lets make sure we have a common
understanding here.

Thanks,
Sekhar

  parent reply	other threads:[~2013-08-12 18:56 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-05 16:14 [PATCH v3 00/12] edma: Add support for SG lists of any length Joel Fernandes
     [not found] ` <1375719297-12871-1-git-send-email-joelf-l0cyMroinI0@public.gmane.org>
2013-08-05 16:14   ` [PATCH v3 01/12] dma: edma: Setup parameters to DMA MAX_NR_SG at a time Joel Fernandes
     [not found]     ` <1375719297-12871-2-git-send-email-joelf-l0cyMroinI0@public.gmane.org>
2013-08-12  7:15       ` Sekhar Nori
     [not found]         ` <52088B8B.9040000-l0cyMroinI0@public.gmane.org>
2013-08-12 23:55           ` Joel Fernandes
     [not found]             ` <52097604.7010503-l0cyMroinI0@public.gmane.org>
2013-08-13  0:19               ` Joel Fernandes
2013-08-13  0:05           ` Joel Fernandes
2013-08-05 16:14   ` [PATCH v3 02/12] ARM: edma: Don't clear EMR of channel in edma_stop Joel Fernandes
     [not found]     ` <1375719297-12871-3-git-send-email-joelf-l0cyMroinI0@public.gmane.org>
2013-08-08 11:49       ` Sekhar Nori
     [not found]         ` <520385D3.1060408-l0cyMroinI0@public.gmane.org>
2013-08-12  4:25           ` Sekhar Nori
2013-08-12  4:29             ` Joel Fernandes
2013-08-12  6:24               ` Sekhar Nori
2013-08-16  5:57   ` [PATCH v3 00/12] edma: Add support for SG lists of any length Joel Fernandes
2013-08-05 16:14 ` [PATCH v3 03/12] dma: edma: remove limits on number of slots Joel Fernandes
     [not found]   ` <1375719297-12871-4-git-send-email-joelf-l0cyMroinI0@public.gmane.org>
2013-08-12  7:17     ` Sekhar Nori
2013-08-05 16:14 ` [PATCH v3 04/12] dma: edma: Write out and handle MAX_NR_SG at a given time Joel Fernandes
2013-08-05 16:14 ` [PATCH v3 05/12] ARM: edma: Add function to enable interrupt for a PaRAM slot Joel Fernandes
2013-08-05 16:14 ` [PATCH v3 06/12] ARM: edma: Add pr_debug in edma_link Joel Fernandes
2013-08-05 16:14 ` [PATCH v3 07/12] dma: edma: Add function to dump a PaRAM set from PaRAM Joel Fernandes
     [not found]   ` <1375719297-12871-8-git-send-email-joelf-l0cyMroinI0@public.gmane.org>
2013-08-12  5:52     ` Sekhar Nori
     [not found]       ` <52087824.60002-l0cyMroinI0@public.gmane.org>
2013-08-13  1:06         ` Joel Fernandes
2013-08-05 16:14 ` [PATCH v3 08/12] dma: edma: Add one more required slot to MAX slots Joel Fernandes
2013-08-12  5:56   ` Sekhar Nori
2013-08-12 13:31     ` Mark Brown
     [not found]       ` <20130812133111.GZ6427-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2013-08-12 18:19         ` Joel Fernandes
     [not found]     ` <52087921.8040101-l0cyMroinI0@public.gmane.org>
2013-08-13  1:08       ` Joel Fernandes
2013-08-05 16:14 ` [PATCH v3 09/12] dma: edma: Implement multiple linked sets for continuity Joel Fernandes
     [not found]   ` <1375719297-12871-10-git-send-email-joelf-l0cyMroinI0@public.gmane.org>
2013-08-12 18:56     ` Sekhar Nori [this message]
     [not found]       ` <52092FF7.7040508-l0cyMroinI0@public.gmane.org>
2013-08-13  1:00         ` Joel Fernandes
2013-08-05 16:14 ` [PATCH v3 10/12] dma: edma: Check if MAX_NR_SG is even in prep function Joel Fernandes
2013-08-05 16:14 ` [PATCH v3 11/12] dma: edma: Keep tracking of Pending interrupts (pending_acks) Joel Fernandes
2013-08-05 16:14 ` [PATCH v3 12/12] dma: edma: Return if nothing left todo in edma_execute Joel Fernandes

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=52092FF7.7040508@ti.com \
    --to=nsekhar-l0cymroini0@public.gmane.org \
    --cc=arnd-r2nGTMty4D4@public.gmane.org \
    --cc=balajitk-l0cyMroinI0@public.gmane.org \
    --cc=broonie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=cjb-2X9k7bc8m7Mdnm+yROfE0A@public.gmane.org \
    --cc=davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org \
    --cc=grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org \
    --cc=jkridner-hcmAuCOw+vXj4SYmN/TMmA@public.gmane.org \
    --cc=joelf-l0cyMroinI0@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org \
    --cc=linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=lokeshvutla-l0cyMroinI0@public.gmane.org \
    --cc=r.sricharan-l0cyMroinI0@public.gmane.org \
    --cc=rnayak-l0cyMroinI0@public.gmane.org \
    --cc=rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org \
    --cc=tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org \
    --cc=vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).