Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932138AbbFXR2T (ORCPT ); Wed, 24 Jun 2015 13:28:19 -0400 Received: from mail-bn1on0069.outbound.protection.outlook.com ([157.56.110.69]:35232 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932085AbbFXR2M convert rfc822-to-8bit (ORCPT ); Wed, 24 Jun 2015 13:28:12 -0400 Authentication-Results: spf=pass (sender IP is 149.199.60.83) smtp.mailfrom=xilinx.com; vger.kernel.org; dkim=none (message not signed) header.d=none; From: Appana Durga Kedareswara Rao To: Vinod Koul CC: "dan.j.williams@intel.com" , Michal Simek , Soren Brinkmann , Anirudha Sarangi , Punnaiah Choudary Kalluri , "dmaengine@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "linux-kernel@vger.kernel.org" , Srikanth Thokala Subject: RE: [PATCH v7] dma: Add Xilinx AXI Direct Memory Access Engine driver support Thread-Topic: [PATCH v7] dma: Add Xilinx AXI Direct Memory Access Engine driver support Thread-Index: AQHQon9A9kU/tLGXRkiyV8/V08t2PJ235yMAgAQMsPA= Date: Wed, 24 Jun 2015 17:12:13 +0000 Message-ID: References: <1433831736-18253-1-git-send-email-appanad@xilinx.com> <20150622104932.GC19530@localhost> In-Reply-To: <20150622104932.GC19530@localhost> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [172.23.231.165] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 X-RCIS-Action: ALLOW X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.0.0.1202-21630.005 X-TM-AS-User-Approved-Sender: Yes;Yes X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;BY2FFO11FD007;1:vP6Cg1XoxerxM/XnXenlVPph9w3huo5GsAW2JJSWaolEYw57+bFfuicxiCU9FU1wvSZl7AqRkioteEOD8GcvZumeH399p3Qpr12prifbYPG/I7pE2AyoyEMr1HO1rLoZc8LVALM1jWeGRpGc/Nf0g8nFx5xTcj8stZ1p1PTiMFjvm/JD3ClV9ru/0N6ur86OU8elt7wnoN/m0jSPTImlujbT4Wk/K5CqNI5T4S1/uZtqmJqXsrDuUOBtyaH7g7isrAfHm5OKeHA8FaHReXM+ZWZ4/7cxnGUfmN025W78EGKgFMiiomgFrb9T4vbfVj9/Ag+H+keMU3WDUoNRpsZq7w== X-Forefront-Antispam-Report: CIP:149.199.60.83;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(2980300002)(438002)(377454003)(43544003)(189002)(51704005)(51914003)(199003)(24454002)(13464003)(5250100002)(5001960100002)(107886002)(110136002)(50466002)(2950100001)(102836002)(6806004)(19580405001)(5890100001)(2900100001)(2920100001)(19580395003)(189998001)(5003600100002)(106116001)(46406003)(106466001)(46102003)(87936001)(86362001)(97756001)(54356999)(63266004)(55846006)(47776003)(551934003)(2656002)(33656002)(92566002)(62966003)(76176999)(77156002)(50986999)(23726002)(107986001)(4001430100001);DIR:OUT;SFP:1101;SCL:1;SRVR:BY2FFO11HUB039;H:xsj-pvapsmtpgw01;FPR:;SPF:Pass;MLV:sfv;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BY2FFO11HUB039;2:7RYUko2VG/SgaFhPWh8bvk3YiiVemrbf4UhQRhwrO9adAPkGWB2woSYxKoXeqNO4;2:h6bktorfUbh/qT27U95gW6YapSNAGfB9/E15wNMQXvfo6nkvUHXSdU+Cjrcp0VSDNvt/Yd4Zp4PrXLC1gExjK5nf+uU9efWSxRo2V7QMt0Iodw58SBgfEWos4qpE9k1DJUSiIr2IzaoUwWNdUIHKtSSTtEdUyt2L0UxA05mfksqOUOXEdRl/73aDWZNq98HgBoW6YmIeAu05XvQcPz2bDSiQT556OejMiKITNKFUk9s=;6:nV5kx9tCubT7rWtF5LULb5rzkyMiri5xDttQH/BEFNyBx6qAOK5353hodHIeJtUXYG9POMCEpoXMZsw3Y9YUBogp/xjLwoBDrobECJPN6bNkfZTPY3aPlH2kTzBQu5iKBYNbrA3QvcwrmpIbynmqmaCOGJomUJcuFDfjeHd2SxV283wmXHHoTn8oQZEvoX8ocUzfDXje8Yg5SxF9RRXS11HE7XNH3J2KEnKpmBELqUFglP5V5ANTtcqPWtucvlJB+pekMbYDivOyXRa3UChyRoDuyOG4kKVQO+PpM4L0QU8XwdxWkFDqeIe+H01jGfSA/XV7V1FDPQj6tnYvBXNeEtytFbxXwy98gZvLsxpN1I1ai6ZwRgmzF/MqWdWw0opkQss2JPfY/u3WzAUnFtEN7zj+9PgFhh4wVm3df+O8y9XVJDrfKWgBZF58MkbSew3aMjQQIYGpzC4s+rLuEB8yOIZIuctrfPAjBcjc2pBg0xy/tfmP2k48ey1WVNfQtyN/ X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY2FFO11HUB039; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(5005006)(3002001);SRVR:BY2FFO11HUB039;BCL:0;PCL:0;RULEID:;SRVR:BY2FFO11HUB039; X-Microsoft-Exchange-Diagnostics: 1;BY2FFO11HUB039;3:1u3imq92xLKk/LUG/d7ToaWw9qgkGzGB3vXpjK6gJNwDs8uxJkNnfYfl4IpVR9aoON2FbfNsTX/EMmUSH+0J8yM8znQrhakNuxUc4miVCPaKV4X4iHDePwSLkm1GV6PR0Gdd0weO9yrdEaTo0zf1QsQe7ZtVZelBA012P9Zu5m5Dhf/npJ4xrpO+KmpdsaF2QO7GN96wt120Cmrnf7X6BqhPeE94pH7jWB9eOAeJ7Hb8DMKfyPl8HttkPXxZqlFqa4P9sxriNgPnHgolcytQs6WlKfRcJZTcX2CrDB2mEcs= X-Forefront-PRVS: 061725F016 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BY2FFO11HUB039;9:r+2xMFra6fsTz45/Rrj4Zbxd9kA9oql2ZTHuW+/Hi?= =?us-ascii?Q?ZhL/sexTmjnht24uNYhaQv2Vj7IsJxmd7Qq/1QLNG+kyxtNRAYBMRKUG9u5P?= =?us-ascii?Q?3/vy5c2tYDKUHUTmaHRX9ZaqvYdLdfjM6PFNHFGi0MYArCt0omgwio6X1i9s?= =?us-ascii?Q?b+PZv2Ayzt145epUuolbHdqDnCQ+xpMslWY9T3XIG2q8E/0UWlqVyR/tf3/2?= =?us-ascii?Q?B0kv0EzrT+ByV4JkmxnL5uZYqhzptk2nPQzG3oUhRYPDYNvv+fYWH85k5V9x?= =?us-ascii?Q?51ljvH7qL984aDjPYVrUPFe//XnCNhyUwrrYJFEn5+MxXgUTC7yrlvHWwsWR?= =?us-ascii?Q?xl9VYRkmaCdAbqSeLgZx+OvwzkNeC0GlLcB6SsWQ5evSWUbpbBvwFiAfuBAJ?= =?us-ascii?Q?Pww6kNyJM0P8OokKpWpZiuUA/Sc33ki6RbKixN41KADuUHQDHH7IdaD/TRk+?= =?us-ascii?Q?byDn3OEEDwxxaeLPtRq6ZGZFkaBP7q/EMDuQbq3tYs2JgkSBVb8QopBH+Ipw?= =?us-ascii?Q?Rufc+mZyPvxs731oRY0HiQ2OdthAqkBfU6LnqaHeFKhui5Smyn63j9p7vdbY?= =?us-ascii?Q?h0RLyr6hDbULzlVV8nkhsGzxZRjlgxp/F9TZ/Ntfb1q60L7ejzmjRqDCukgz?= =?us-ascii?Q?PAOdmsRybYVl+BOiEgk7EuUz5FC/4HAQoxYkEdz1AoJiTXj0ZOIKpb4Y648i?= =?us-ascii?Q?JC0MSflFoTZizQdD4cvCKppOaVM4D3i5lSEI/W0fKBqiQgXLphryDhyLcvOd?= =?us-ascii?Q?qesMHuK6vQPcfk5LNmrLl9nLLcfRDx87mPIpfWbRYpbM91hSGIaGXmrVoiBF?= =?us-ascii?Q?C6btJvYS/WhBZaufE9SheA06h3uB/GEb8EGxkx++e17VOWYwgYRJUxVrS/xP?= =?us-ascii?Q?AonvNSKuGpE3+kearCYN/dNzYkW3uCmlU5J0FDDwj14Xh/v98i2v4B9l7pIR?= =?us-ascii?Q?Oi17lcyK1qUNOjeXJN0a3gvdgH5M1NnmOtnbF0E8mlgPviV0lqn8sBNvtCYm?= =?us-ascii?Q?IH+IiAkQ5bUFT2jfQs02xGgR0EhqU6rk5otalv/lPN/F8jiDWCQ2+VRpQFFz?= =?us-ascii?Q?h6aHyfyxeFd6b0YvUOH1w3uC+EcIWRPui2KLmhidNP0QNuYBlJ6IRkvTj1az?= =?us-ascii?Q?G1kqQzLZKy2QZY8VkP7rMp5Oi0UsvM3jTcADDZu+eVsrqv7WnIqHSP9uBiGR?= =?us-ascii?Q?abSBu6QjauNRDquCAd0X7O4FBoT0HKZC04e+BpCfcg4/dZvwJKv/07B3g=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1;BY2FFO11HUB039;3:WVV4HeMdgl895q1azJUx+TFqfAl5lpEt+g3rbVFAj5cHbMp4FuKFNzgO77By8k9CbI1dqETz18ankzCnTyuhJgXhjlF2NX5W+VbSDZZOnp+vAHMpoSyBtll5uvWh+yp/I3hVmVzN+3TjJFp+2VLQPA==;10:w/ZYJjV9F42/hFT7Cal5n/qbzcqLhi4ntM06Q9uX1zkYN/663gNbt1Aesw20BybmM3SVvpRb92EBILxF6K8XzzNUfvUgH06YnFAxGMz8m+0= X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Jun 2015 17:12:16.3839 (UTC) X-MS-Exchange-CrossTenant-Id: 657af505-d5df-48d0-8300-c31994686c5c X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=657af505-d5df-48d0-8300-c31994686c5c;Ip=[149.199.60.83];Helo=[xsj-pvapsmtpgw01] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2FFO11HUB039 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 9899 Lines: 248 Hi Vinod, > -----Original Message----- > From: Vinod Koul [mailto:vinod.koul@intel.com] > Sent: Monday, June 22, 2015 4:20 PM > To: Appana Durga Kedareswara Rao > Cc: dan.j.williams@intel.com; Michal Simek; Soren Brinkmann; Appana Durga > Kedareswara Rao; Anirudha Sarangi; Punnaiah Choudary Kalluri; > dmaengine@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux- > kernel@vger.kernel.org; Srikanth Thokala > Subject: Re: [PATCH v7] dma: Add Xilinx AXI Direct Memory Access Engine > driver support > > On Tue, Jun 09, 2015 at 12:05:36PM +0530, Kedareswara rao Appana wrote: > > This is the driver for the AXI Direct Memory Access (AXI DMA) core, > > which is a soft Xilinx IP core that provides high- bandwidth direct > > memory access between memory and AXI4-Stream type target > peripherals. > > > > Signed-off-by: Srikanth Thokala > > Signed-off-by: Kedareswara rao Appana > > --- > > The deivce tree doc got applied in the slave-dmaengine.git. > > > > This patch is rebased on the commit > > Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net > same stuff everywhere, sigh Ok will fix it in the next version of the patch. > > > +static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg( > > + struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len, > > + enum dma_transfer_direction direction, unsigned long flags, > > + void *context) > > +{ > > + struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); > > + struct xilinx_dma_tx_descriptor *desc; > > + struct xilinx_dma_tx_segment *segment; > > + struct xilinx_dma_desc_hw *hw; > > + u32 *app_w = (u32 *)context; > > + struct scatterlist *sg; > > + size_t copy, sg_used; > > + int i; > > + > > + if (!is_slave_direction(direction)) > > + return NULL; > > + > > + /* Allocate a transaction descriptor. */ > > + desc = xilinx_dma_alloc_tx_descriptor(chan); > > + if (!desc) > > + return NULL; > > + > > + desc->direction = direction; > > + dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); > > + desc->async_tx.tx_submit = xilinx_dma_tx_submit; > > + > > + /* Build transactions using information in the scatter gather list */ > > + for_each_sg(sgl, sg, sg_len, i) { > > + sg_used = 0; > > + > > + /* Loop until the entire scatterlist entry is used */ > > + while (sg_used < sg_dma_len(sg)) { > > + > > + /* Get a free segment */ > > + segment = xilinx_dma_alloc_tx_segment(chan); > > + if (!segment) > > + goto error; > > + > > + /* > > + * Calculate the maximum number of bytes to > transfer, > > + * making sure it is less than the hw limit > > + */ > > + copy = min_t(size_t, sg_dma_len(sg) - sg_used, > > + XILINX_DMA_MAX_TRANS_LEN); > > + hw = &segment->hw; > > + > > + /* Fill in the descriptor */ > > + hw->buf_addr = sg_dma_address(sg) + sg_used; > > + > > + hw->control = copy; > > + > > + if (direction == DMA_MEM_TO_DEV) { > > + if (app_w) > > + memcpy(hw->app, app_w, > sizeof(u32) * > > + > XILINX_DMA_NUM_APP_WORDS); > > + > > + /* > > + * For the first DMA_MEM_TO_DEV transfer, > > + * set SOP > > + */ > > + if (!i) > > + hw->control |= > XILINX_DMA_BD_SOP; > > + } > > + > > + sg_used += copy; > > + > > + /* > > + * Insert the segment into the descriptor segments > > + * list. > > + */ > > + list_add_tail(&segment->node, &desc->segments); > > + } > > + } > > + > > + /* For the last DMA_MEM_TO_DEV transfer, set EOP */ > > + if (direction == DMA_MEM_TO_DEV) { > > + segment = list_last_entry(&desc->segments, > > + struct xilinx_dma_tx_segment, > > + node); > > + segment->hw.control |= XILINX_DMA_BD_EOP; > > + } > where is the hardware addr programmed? I can see you are using sg list > passed for porgramming one side of a transfer where is other side > programmed? The actual programming happens in the start_transfer(I mean in issue_pending) API There are two modes All the h/w addresses are configured in the start_transfer API. In simple transfer Mode the below write triggers the transfer dma_ctrl_write(chan, XILINX_DMA_REG_BTT, hw->control & XILINX_DMA_MAX_TRANS_LEN); In SG Mode the below write triggers the transfer. dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC, tail->phys); There are two Channels MM2S (Memory to device) and S2MM (Device to Memory) channel. --> In MM2S case we need to configure the SOF (Start of frame) for the first BD and we need to set EOF(end of frame) for the last BD --> For S2MM case no need to configure SOF and EOF. Once we got the IOC interrupt will call mark the cookie as complete and will Call the user callback. There users checks for the data. Please let me know if you are not clear. > > > +int xilinx_dma_channel_set_config(struct dma_chan *dchan, > > + struct xilinx_dma_config *cfg) > > +{ > > + struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); > > + u32 reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL); > > + > > + if (!xilinx_dma_is_idle(chan)) > > + return -EBUSY; > > + > > + if (cfg->reset) > > + return xilinx_dma_chan_reset(chan); > > + > > + if (cfg->coalesc <= XILINX_DMA_CR_COALESCE_MAX) > > + reg |= cfg->coalesc << XILINX_DMA_CR_COALESCE_SHIFT; > > + > > + if (cfg->delay <= XILINX_DMA_CR_DELAY_MAX) > > + reg |= cfg->delay << XILINX_DMA_CR_DELAY_SHIFT; > > + > > + dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, reg); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL(xilinx_dma_channel_set_config); > Same question here as the other driver, why reset, why not _GPL here etc > etc. Ok will take care the comments in the next version of the patch. > > Also what is differenace betwene these two drivers, why cant we have one > driver for both? I agree with you and even initially we had a common driver with the similar implementation As you were mentioning. Later on, being soft IPs, new features were added and the IPs became diversified. As an example, this driver has a residue calculation whereas the other driver (DMA) is not applicable and the way interrupts are handled is completely different. Briefly, they are two complete different IPs with a different register set and descriptor format. Eventually, it became too complex to manage the common driver as the code became messy with lot of conditions around. Mainly the validation process is a big concern, as every change in the IP compels to test all the complete features of both IPs. So, we got convinced to the approach of separating the drivers to overcome this and it comes with few addition lines of common code. > > > +static int xilinx_dma_probe(struct platform_device *pdev) { > > + struct xilinx_dma_device *xdev; > > + struct device_node *child, *node; > > + struct resource *res; > > + int i, ret; > > + > > + xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL); > > + if (!xdev) > > + return -ENOMEM; > > + > > + xdev->dev = &(pdev->dev); > > + INIT_LIST_HEAD(&xdev->common.channels); > > + > > + node = pdev->dev.of_node; > > + > > + /* Map the registers */ > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > + xdev->regs = devm_ioremap_resource(&pdev->dev, res); > > + if (IS_ERR(xdev->regs)) > > + return PTR_ERR(xdev->regs); > > + > > + /* Check if SG is enabled */ > > + xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg"); > > + > > + /* Axi DMA only do slave transfers */ > > + dma_cap_set(DMA_SLAVE, xdev->common.cap_mask); > > + dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask); > > + xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg; > > + xdev->common.device_terminate_all = xilinx_dma_terminate_all; > > + xdev->common.device_issue_pending = xilinx_dma_issue_pending; > > + xdev->common.device_alloc_chan_resources = > > + xilinx_dma_alloc_chan_resources; > > + xdev->common.device_free_chan_resources = > > + xilinx_dma_free_chan_resources; > > + xdev->common.device_tx_status = xilinx_dma_tx_status; > > + xdev->common.directions = BIT(DMA_DEV_TO_MEM) | > BIT(DMA_MEM_TO_DEV); > > + xdev->common.residue_granularity = > DMA_RESIDUE_GRANULARITY_SEGMENT; > > + xdev->common.dev = &pdev->dev; > no dma_slave_config handler? No need of this callback earlier in the dma_slave_config we are doing terminate_all Now we have a separate API for that so no need to have this call back. Thanks for the comments. Regards, Kedar. > > > > -- > ~Vinod This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/