From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750804AbdAWII0 convert rfc822-to-8bit (ORCPT ); Mon, 23 Jan 2017 03:08:26 -0500 Received: from mx6-09.smtp.antispamcloud.com ([95.211.2.200]:52793 "EHLO mx6-09.smtp.antispamcloud.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750708AbdAWIIX (ORCPT ); Mon, 23 Jan 2017 03:08:23 -0500 X-Greylist: delayed 2512 seconds by postgrey-1.27 at vger.kernel.org; Mon, 23 Jan 2017 03:08:23 EST Subject: Re: [PATCH v6 2/3] dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in vdma To: Kedareswara rao Appana , , , , , , , , , , , References: <1484372155-19423-1-git-send-email-appanad@xilinx.com> <1484372155-19423-3-git-send-email-appanad@xilinx.com> CC: , , , From: Mike Looijmans Organization: TOPIC Message-ID: <296cffff-3847-4217-bd94-ac72fe044f73@topic.nl> Date: Mon, 23 Jan 2017 08:26:09 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 In-Reply-To: <1484372155-19423-3-git-send-email-appanad@xilinx.com> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 8BIT X-Originating-IP: [192.168.80.121] X-EXCLAIMER-MD-CONFIG: 9833cda7-5b21-4d34-9a38-8d025ddc3664 X-EXCLAIMER-MD-BIFURCATION-INSTANCE: 0 X-Originating-IP: 37.74.225.130 X-SpamExperts-Domain: topic.nl X-SpamExperts-Username: 37.74.225.128/28 Authentication-Results: antispamcloud.com; auth=pass smtp.auth=37.74.225.128/28@topic.nl X-SpamExperts-Outgoing-Class: ham X-SpamExperts-Outgoing-Evidence: Combined (0.02) X-Filter-ID: s0sct1PQhAABKnZB5plbIbbvfIHzQjPVmPLZeVYSu3xU9luQrU+8/8qthi+0Jd/W/95+6ZE6dI+d FNTaLLKrTD4PkK8WOoKuw32u9iEtZmisSr42qUwvK7U11fJ5smF5bE7GwnNXTE7JFCR1ojdwNFvw 9gXKL4Xh8U6CStzWQpF96Jvx9r55L/xk23i+coF4k35ZdXDCwhY8tpwUKUeRkGbjO41FyBEqIaDu dcVplPGNaieKxw/vh63RdlaW2Zj1hcQD6Dxo9kokFZNwiacNPxeTCKssqlJePCDBHWfCYUvWOATT vnG+QUCcfrSs6FZc7tZ3vKwSN7Mv0HNteAusUZ8BuYwGqmI8Tx/Ism0pnCcmlWACu0WC7nIKSPYV aBAAdpU0oUDqng6Dyy2mQeofiU3ePCRQfq0TItPE84JXpQZ1el35jO+WJBgrWGjAavfuifnL+9wg oTj4ygNPw1XfN1IUJ2+rCMPpQhII5VkEVC//8GRISD+lYCwA5l6/Q4nfg8y63jKKBrO1BroJmvb9 eW6r2rlUSNsSKfXWKXbAnTtpwWXpE+sdjNmnXWjiNaLzpYbRm1I468S/yL0UV2VaFaHU7TvqT2so IjU4ke4l3yHonV+E7OMXRvgtdyMlnmWio7yflOSPePNf+xGd6n5xOT8FIprDRrySYpUp+LukEmTG N2UgrmErjtKlYAD94Y+HimJBmbX4ZwV05IcNNAgTWJlUOpwpEkpu90COvViIG1i2pq4ZmiLrUtAf M6WT3J4Pfkthd2LyVdAPfnUAFBPBekUASfSGhN2aoJTfS22cGXcRQas0Y+9lR0Wzsy3xsZoKhUN/ 7rmuhnJjwAyqkzxS1eEIlOfOdlM8xHogA0cW1m0vAAJ66iu+yjcnX4i+MdoGb9OI6N3hkf17OcM+ RjvufXLsu116vZB00h68Hr2DRJkY63S5XZsKlmYxMNpVjqjjzVhvs3eeY5/3ZK3UikoDgtaVKJuo 3Y4EyK5i+k44eh4XkB+eWXuUmVH/OveSUPQUmaFUsrb0xf82mwrJka9eHlnZeZkTpSWjdKDr98cJ Y3H+g45yvC8W92gyzsznFUmdhhIoFK2vs7u+GDFagW/56kJ8H0VNHJgnXWZbUSA5LvG3wL2Y4F04 12ezGCyTUPanavQ85opH/wqDz7VZA4byRBs40cmSL9tPfD9p0Q30Opqp1rt+p7rT4xEEhx6JOvPG idMlhCno/QsYaTlhyywkGd/tQspywW7uL6oK7DJaDKjbKrxSQm1e9uGJRbp+9k98s7ErhISbhMPq EOXICegc5yrU26zBKwLEanQ/0WtDtWqSD7Wsk3GC5bRcDSCQvo65XNaYwYGV7UmYQiKS8Xul9mGa vGtln7gcLZeAuKkf0VAuiQ/JZWGqk/7UQlpangQiFHi62c+876oxtBi6kxxY9w== X-Report-Abuse-To: spam@quarantine2.antispamcloud.com X-Recommended-Action: accept Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 14-01-17 06:35, Kedareswara rao Appana wrote: > When VDMA is configured for more than one frame in the h/w. > For example h/w is configured for n number of frames, user > Submits n number of frames and triggered the DMA using issue_pending API. > > In the current driver flow we are submitting one frame at a time, > But we should submit all the n number of frames at one time > As the h/w is configured for n number of frames. The hardware can always handle a single frame submission, by using the "park" bit. This would make a good "cyclic" implementation too (using vdma as framebuffer). It could also handle all cases for "k" frames where n%k==0 (n is a multiple of k) by simply replicating the frame pointers. > > This patch fixes this issue. > > Acked-by: Rob Herring > Reviewed-by: Jose Abreu > Signed-off-by: Kedareswara rao Appana > --- > Changes for v6: > ---> Added Rob Acked-by > ---> Updated commit message as suggested by Vinod. > Changes for v5: > ---> Updated xlnx,fstore-config property to xlnx,fstore-enable > and updated description as suggested by Rob. > Changes for v4: > ---> Add Check for framestore configuration on Transmit case as well > as suggested by Jose Abreu. > ---> Modified the dev_dbg checks to dev_warn checks as suggested > by Jose Abreu. > Changes for v3: > ---> Added Checks for frame store configuration. If frame store > Configuration is not present at the h/w level and user > Submits less frames added debug prints in the driver as relevant. > Changes for v2: > ---> Fixed race conditions in the driver as suggested by Jose Abreu > ---> Fixed unnecessray if else checks in the vdma_start_transfer > as suggested by Laurent Pinchart. > > .../devicetree/bindings/dma/xilinx/xilinx_dma.txt | 2 + > drivers/dma/xilinx/xilinx_dma.c | 78 +++++++++++++++------- > 2 files changed, 57 insertions(+), 23 deletions(-) > > diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt > index a2b8bfa..e951c09 100644 > --- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt > +++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt > @@ -66,6 +66,8 @@ Optional child node properties: > Optional child node properties for VDMA: > - xlnx,genlock-mode: Tells Genlock synchronization is > enabled/disabled in hardware. > +- xlnx,fstore-enable: boolean; if defined, it indicates that controller > + supports frame store configuration. > Optional child node properties for AXI DMA: > -dma-channels: Number of dma channels in child node. > > diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c > index 5eeea57..edb5b71 100644 > --- a/drivers/dma/xilinx/xilinx_dma.c > +++ b/drivers/dma/xilinx/xilinx_dma.c > @@ -322,6 +322,7 @@ struct xilinx_dma_tx_descriptor { > * @genlock: Support genlock mode > * @err: Channel has errors > * @idle: Check for channel idle > + * @has_fstoreen: Check for frame store configuration > * @tasklet: Cleanup work after irq > * @config: Device configuration info > * @flush_on_fsync: Flush on Frame sync > @@ -353,6 +354,7 @@ struct xilinx_dma_chan { > bool genlock; > bool err; > bool idle; > + bool has_fstoreen; > struct tasklet_struct tasklet; > struct xilinx_vdma_config config; > bool flush_on_fsync; > @@ -990,6 +992,27 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) > if (list_empty(&chan->pending_list)) > return; > > + /* > + * Note: When VDMA is built with default h/w configuration > + * User should submit frames upto H/W configured. > + * If users submits less than h/w configured > + * VDMA engine tries to write to a invalid location > + * Results undefined behaviour/memory corruption. > + * > + * If user would like to submit frames less than h/w capable > + * On S2MM side please enable debug info 13 at the h/w level > + * On MM2S side please enable debug info 6 at the h/w level > + * It will allows the frame buffers numbers to be modified at runtime. > + */ > + if (!chan->has_fstoreen && > + chan->desc_pendingcount < chan->num_frms) { > + dev_warn(chan->dev, "Frame Store Configuration is not enabled at the\n"); > + dev_warn(chan->dev, "H/w level enable Debug info 13 or 6 at the h/w level\n"); > + dev_warn(chan->dev, "OR Submit the frames upto h/w Capable\n\r"); > + > + return; > + } > + > desc = list_first_entry(&chan->pending_list, > struct xilinx_dma_tx_descriptor, node); > tail_desc = list_last_entry(&chan->pending_list, > @@ -1052,25 +1075,38 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) > if (chan->has_sg) { > dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC, > tail_segment->phys); > + list_splice_tail_init(&chan->pending_list, &chan->active_list); > + chan->desc_pendingcount = 0; > } else { > struct xilinx_vdma_tx_segment *segment, *last = NULL; > - int i = 0; > + int i = 0, j = 0; > > if (chan->desc_submitcount < chan->num_frms) > i = chan->desc_submitcount; > > - list_for_each_entry(segment, &desc->segments, node) { > - if (chan->ext_addr) > - vdma_desc_write_64(chan, > - XILINX_VDMA_REG_START_ADDRESS_64(i++), > - segment->hw.buf_addr, > - segment->hw.buf_addr_msb); > - else > - vdma_desc_write(chan, > - XILINX_VDMA_REG_START_ADDRESS(i++), > - segment->hw.buf_addr); > - > - last = segment; > + for (j = 0; j < chan->num_frms; ) { > + list_for_each_entry(segment, &desc->segments, node) { > + if (chan->ext_addr) > + vdma_desc_write_64(chan, > + XILINX_VDMA_REG_START_ADDRESS_64(i++), > + segment->hw.buf_addr, > + segment->hw.buf_addr_msb); > + else > + vdma_desc_write(chan, > + XILINX_VDMA_REG_START_ADDRESS(i++), > + segment->hw.buf_addr); > + > + last = segment; > + } > + list_del(&desc->node); > + list_add_tail(&desc->node, &chan->active_list); > + j++; > + if (list_empty(&chan->pending_list) || > + (i == chan->num_frms)) > + break; > + desc = list_first_entry(&chan->pending_list, > + struct xilinx_dma_tx_descriptor, > + node); > } > > if (!last) > @@ -1081,20 +1117,14 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) > vdma_desc_write(chan, XILINX_DMA_REG_FRMDLY_STRIDE, > last->hw.stride); > vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize); > - } > > - chan->idle = false; > - if (!chan->has_sg) { > - list_del(&desc->node); > - list_add_tail(&desc->node, &chan->active_list); > - chan->desc_submitcount++; > - chan->desc_pendingcount--; > + chan->desc_submitcount += j; > + chan->desc_pendingcount -= j; > if (chan->desc_submitcount == chan->num_frms) > chan->desc_submitcount = 0; > - } else { > - list_splice_tail_init(&chan->pending_list, &chan->active_list); > - chan->desc_pendingcount = 0; > } > + > + chan->idle = false; > } > > /** > @@ -1342,6 +1372,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan) > > chan->err = false; > chan->idle = true; > + chan->desc_submitcount = 0; > > return err; > } > @@ -2320,6 +2351,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, > has_dre = of_property_read_bool(node, "xlnx,include-dre"); > > chan->genlock = of_property_read_bool(node, "xlnx,genlock-mode"); > + chan->has_fstoreen = of_property_read_bool(node, "xlnx,fstore-enable"); > > err = of_property_read_u32(node, "xlnx,datawidth", &value); > if (err) { > Kind regards, Mike Looijmans System Expert TOPIC Products Materiaalweg 4, NL-5681 RJ Best Postbus 440, NL-5680 AK Best Telefoon: +31 (0) 499 33 69 79 E-mail: mike.looijmans@topicproducts.com Website: www.topicproducts.com Please consider the environment before printing this e-mail