From patchwork Fri Jun 21 10:14:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sekhar Nori X-Patchwork-Id: 2761331 Return-Path: X-Original-To: patchwork-davinci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 033FAC0AB1 for ; Fri, 21 Jun 2013 10:16:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 07858200F0 for ; Fri, 21 Jun 2013 10:16:22 +0000 (UTC) Received: from devils.ext.ti.com (devils.ext.ti.com [198.47.26.153]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B3084200ED for ; Fri, 21 Jun 2013 10:16:20 +0000 (UTC) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id r5LAEs8q032185; Fri, 21 Jun 2013 05:14:54 -0500 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r5LAEsAj008612; Fri, 21 Jun 2013 05:14:54 -0500 Received: from dlelxv23.itg.ti.com (172.17.1.198) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.2.342.3; Fri, 21 Jun 2013 05:14:53 -0500 Received: from linux.omap.com (dlelxs01.itg.ti.com [157.170.227.31]) by dlelxv23.itg.ti.com (8.13.8/8.13.8) with ESMTP id r5LAEr5V014035; Fri, 21 Jun 2013 05:14:53 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id DC1CA80627; Fri, 21 Jun 2013 05:14:53 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dbdlxv05.itg.ti.com (dbdlxv05.itg.ti.com [172.24.171.60]) by linux.omap.com (Postfix) with ESMTP id 8750980626 for ; Fri, 21 Jun 2013 05:14:51 -0500 (CDT) Received: from DBDE72.ent.ti.com (dbde72.ent.ti.com [172.24.171.97]) by dbdlxv05.itg.ti.com (8.14.3/8.13.8) with ESMTP id r5LAEfWK019994; Fri, 21 Jun 2013 05:14:42 -0500 Received: from dbdp33.itg.ti.com (172.24.170.252) by DBDE72.ent.ti.com (172.24.171.97) with Microsoft SMTP Server id 14.2.342.3; Fri, 21 Jun 2013 18:14:39 +0800 Received: from psplinux063.india.ti.com (smtpvbd.itg.ti.com [172.24.170.250]) by dbdp33.itg.ti.com (8.13.8/8.13.8) with ESMTP id r5LAEVtq016119; Fri, 21 Jun 2013 15:44:31 +0530 From: Sekhar Nori To: Joel A Fernandes Subject: [PATCH] ARM: edma: Add EDMA crossbar event mux support Date: Fri, 21 Jun 2013 15:44:31 +0530 Message-ID: <1371809671-24037-1-git-send-email-nsekhar@ti.com> X-Mailer: git-send-email 1.7.10.1 In-Reply-To: <51C42705.1060803@ti.com> References: <51C42705.1060803@ti.com> MIME-Version: 1.0 CC: Rob Landley , Linux DaVinci Kernel List , Russell King , Benoit Cousson , Arnd Bergmann , Linux Documentation List , Tony Lindgren , Devicetree Discuss , Linux MMC List , Koen Kooi , Rob Herring , Linux Kernel Mailing List , Grant Likely , Vinod Koul , Mark Brown , Jason Kridner , Linux SPI Devel List , Andrew Morton , Linux OMAP List , Linux ARM Kernel List X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Matt Porter EDMA supports a cross bar which provides ability to mux additional events into physical channels present in the channel controller. This is required when the number of events present in the system are more than number of available physical channels. Changes by Joel: * Split EDMA xbar support out of original EDMA DT parsing patch to keep it easier for review. * Rewrite shift and offset calculation. Suggested-by: Sekhar Nori Suggested by: Andy Shevchenko Signed-off-by: Joel A Fernandes Acked-by: Arnd Bergmann [nsekhar@ti.com: fix checkpatch errors and a minor coding improvement] Signed-off-by: Sekhar Nori --- arch/arm/common/edma.c | 78 ++++++++++++++++++++++++++++++++++++ include/linux/platform_data/edma.h | 1 + 2 files changed, 79 insertions(+) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index b3770ab..2b591b1 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -1378,12 +1378,76 @@ EXPORT_SYMBOL(edma_clear_event); #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DMADEVICES) +static int edma_of_read_u32_to_s16_array(const struct device_node *np, + const char *propname, s16 *out_values, + size_t sz) +{ + int ret; + + ret = of_property_read_u16_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret, i; + struct resource res; + void __iomem *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, &res); + if (ret) + return -EIO; + + xbar = devm_ioremap(dev, res.start, resource_size(&res)); + if (!xbar) + return -ENOMEM; + + ret = edma_of_read_u32_to_s16_array(node, + "ti,edma-xbar-event-map", + (s16 *)xbar_chans, + len/sizeof(u32)); + if (ret) + return -EIO; + + for (i = 0; xbar_chans[i][0] != -1; i++) { + shift = (xbar_chans[i][1] & 0x03) << 3; + offset = xbar_chans[i][1] & 0xfffffffc; + mux = readl(xbar + offset); + mux &= ~(0xff << shift); + mux |= xbar_chans[i][0] << shift; + writel(mux, (xbar + offset)); + } + + pdata->xbar_chans = xbar_chans; + + return 0; +} + static int edma_of_parse_dt(struct device *dev, struct device_node *node, struct edma_soc_info *pdata) { int ret = 0, i; u32 value; + struct property *prop; + size_t sz; struct edma_rsv_info *rsv_info; s8 (*queue_tc_map)[2], (*queue_priority_map)[2]; @@ -1439,6 +1503,10 @@ static int edma_of_parse_dt(struct device *dev, pdata->default_queue = 0; + prop = of_find_property(node, "ti,edma-xbar-event-map", &sz); + if (prop) + ret = edma_xbar_event_map(dev, node, pdata, sz); + return ret; } @@ -1492,6 +1560,7 @@ static int edma_probe(struct platform_device *pdev) int status = -1; const s16 (*rsv_chans)[2]; const s16 (*rsv_slots)[2]; + const s16 (*xbar_chans)[2]; int irq[EDMA_MAX_CC] = {0, 0}; int err_irq[EDMA_MAX_CC] = {0, 0}; struct resource *r[EDMA_MAX_CC] = {NULL}; @@ -1599,6 +1668,15 @@ static int edma_probe(struct platform_device *pdev) } } + /* Clear the xbar mapped channels in unused list */ + xbar_chans = info[j]->xbar_chans; + if (xbar_chans) { + for (i = 0; xbar_chans[i][1] != -1; i++) { + off = xbar_chans[i][1]; + clear_bits(off, 1, + edma_cc[j]->edma_unused); + } + } if (node) { irq[j] = irq_of_parse_and_map(node, 0); diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h index 317f2be..57300fd 100644 --- a/include/linux/platform_data/edma.h +++ b/include/linux/platform_data/edma.h @@ -177,6 +177,7 @@ struct edma_soc_info { s8 (*queue_tc_mapping)[2]; s8 (*queue_priority_mapping)[2]; + const s16 (*xbar_chans)[2]; }; #endif