From patchwork Mon Jul 6 21:14:36 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Hilman X-Patchwork-Id: 34320 Received: from arroyo.ext.ti.com (arroyo.ext.ti.com [192.94.94.40]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n66LIKcj016741 for ; Mon, 6 Jul 2009 21:18:21 GMT Received: from dlep36.itg.ti.com ([157.170.170.91]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id n66LGXYa013378; Mon, 6 Jul 2009 16:16:38 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep36.itg.ti.com (8.13.8/8.13.8) with ESMTP id n66LGWQl015295; Mon, 6 Jul 2009 16:16:32 -0500 (CDT) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 500638062B; Mon, 6 Jul 2009 16:16:29 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp51.itg.ti.com (dflp51.itg.ti.com [128.247.22.94]) by linux.omap.com (Postfix) with ESMTP id CB0F480627 for ; Mon, 6 Jul 2009 16:15:46 -0500 (CDT) Received: from red.ext.ti.com (localhost [127.0.0.1]) by dflp51.itg.ti.com (8.13.7/8.13.7) with ESMTP id n66LFkh9013532 for ; Mon, 6 Jul 2009 16:15:46 -0500 (CDT) Received: from mail90-tx2-R.bigfish.com (mail-tx2.bigfish.com [65.55.88.112]) by red.ext.ti.com (8.13.7/8.13.7) with ESMTP id n66LFffp009302 for ; Mon, 6 Jul 2009 16:15:46 -0500 Received: from mail90-tx2 (localhost.localdomain [127.0.0.1]) by mail90-tx2-R.bigfish.com (Postfix) with ESMTP id 13E97B68313 for ; Mon, 6 Jul 2009 21:15:41 +0000 (UTC) X-SpamScore: 0 X-BigFish: vps0(zzzz1202hzzz2dh61h) X-Spam-TCS-SCL: 0:0 X-FB-SS: 5, X-MS-Exchange-Organization-Antispam-Report: OrigIP: 209.85.216.201; Service: EHS Received: by mail90-tx2 (MessageSwitch) id 1246914924979006_9380; Mon, 6 Jul 2009 21:15:24 +0000 (UCT) Received: from mail-px0-f201.google.com (mail-px0-f201.google.com [209.85.216.201]) by mail90-tx2.bigfish.com (Postfix) with ESMTP id 8D25B50064 for ; Mon, 6 Jul 2009 21:15:24 +0000 (UTC) Received: by mail-px0-f201.google.com with SMTP id 39so1157876pxi.4 for ; Mon, 06 Jul 2009 14:15:24 -0700 (PDT) Received: by 10.114.137.16 with SMTP id k16mr8098197wad.189.1246914924347; Mon, 06 Jul 2009 14:15:24 -0700 (PDT) Received: from localhost ([216.254.16.51]) by mx.google.com with ESMTPS id n33sm11859859wag.56.2009.07.06.14.15.21 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 06 Jul 2009 14:15:23 -0700 (PDT) From: Kevin Hilman To: linux-arm-kernel@lists.arm.linux.org.uk Date: Mon, 6 Jul 2009 14:14:36 -0700 Message-Id: <1246914900-9034-3-git-send-email-khilman@deeprootsystems.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1246914900-9034-2-git-send-email-khilman@deeprootsystems.com> References: <1246914900-9034-1-git-send-email-khilman@deeprootsystems.com> <1246914900-9034-2-git-send-email-khilman@deeprootsystems.com> Cc: davinci-linux-open-source@linux.davincidsp.com Subject: [PATCH 02/26] davinci: EDMA: restructure to support multiple channel controllers X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.4 Precedence: list List-Id: davinci-linux-open-source.linux.davincidsp.com List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: davinci-linux-open-source-bounces@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com From: Sudhakar Rajashekhara Define a structure to store EDMA channel controller based information. Use platform_device.id to find out the instance being configured in probe function. Signed-off-by: Sudhakar Rajashekhara Reviewed-by: David Brownell Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dm355.c | 5 +- arch/arm/mach-davinci/dm644x.c | 5 +- arch/arm/mach-davinci/dma.c | 100 +++++++++++++++++++---------- arch/arm/mach-davinci/include/mach/edma.h | 1 + 4 files changed, 73 insertions(+), 38 deletions(-) diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index baaaf32..beda643 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -563,12 +563,13 @@ static struct edma_soc_info dm355_edma_info = { .n_region = 4, .n_slot = 128, .n_tc = 2, + .n_cc = 1, .noevent = dma_chan_dm355_no_event, }; static struct resource edma_resources[] = { { - .name = "edma_cc", + .name = "edma_cc0", .start = 0x01c00000, .end = 0x01c00000 + SZ_64K - 1, .flags = IORESOURCE_MEM, @@ -598,7 +599,7 @@ static struct resource edma_resources[] = { static struct platform_device dm355_edma_device = { .name = "edma", - .id = -1, + .id = 0, .dev.platform_data = &dm355_edma_info, .num_resources = ARRAY_SIZE(edma_resources), .resource = edma_resources, diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index fb5449b..ddc1d4f 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -489,12 +489,13 @@ static struct edma_soc_info dm644x_edma_info = { .n_region = 4, .n_slot = 128, .n_tc = 2, + .n_cc = 1, .noevent = dma_chan_dm644x_no_event, }; static struct resource edma_resources[] = { { - .name = "edma_cc", + .name = "edma_cc0", .start = 0x01c00000, .end = 0x01c00000 + SZ_64K - 1, .flags = IORESOURCE_MEM, @@ -524,7 +525,7 @@ static struct resource edma_resources[] = { static struct platform_device dm644x_edma_device = { .name = "edma", - .id = -1, + .id = 0, .dev.platform_data = &dm644x_edma_info, .num_resources = ARRAY_SIZE(edma_resources), .resource = edma_resources, diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index 15e9eb1..9afd55f 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -107,11 +107,12 @@ #define EDMA_MAX_DMACH 64 #define EDMA_MAX_PARAMENTRY 512 #define EDMA_MAX_EVQUE 2 /* FIXME too small */ +#define EDMA_MAX_CC 2 /*****************************************************************************/ -static void __iomem *edmacc_regs_base; +static void __iomem *edmacc_regs_base[EDMA_MAX_CC]; static inline unsigned int edma_read(int offset) { @@ -207,25 +208,39 @@ static inline void edma_parm_or(int offset, int param_no, unsigned or) /*****************************************************************************/ /* actual number of DMA channels and slots on this silicon */ -static unsigned num_channels; -static unsigned num_slots; +struct edma { + /* how many dma resources of each type */ + unsigned num_channels; + unsigned num_region; + unsigned num_slots; + unsigned num_tc; + unsigned num_cc; + + /* list of channels with no even trigger; terminated by "-1" */ + const s8 *noevent; + + /* The edma_inuse bit for each PaRAM slot is clear unless the + * channel is in use ... by ARM or DSP, for QDMA, or whatever. + */ + DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY); -static struct dma_interrupt_data { - void (*callback)(unsigned channel, unsigned short ch_status, - void *data); - void *data; -} intr_data[EDMA_MAX_DMACH]; + /* The edma_noevent bit for each channel is clear unless + * it doesn't trigger DMA events on this platform. It uses a + * bit of SOC-specific initialization code. + */ + DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH); -/* The edma_inuse bit for each PaRAM slot is clear unless the - * channel is in use ... by ARM or DSP, for QDMA, or whatever. - */ -static DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY); + unsigned irq_res_start; + unsigned irq_res_end; -/* The edma_noevent bit for each channel is clear unless - * it doesn't trigger DMA events on this platform. It uses a - * bit of SOC-specific initialization code. - */ -static DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH); + struct dma_interrupt_data { + void (*callback)(unsigned channel, unsigned short ch_status, + void *data); + void *data; + } intr_data[EDMA_MAX_DMACH]; +}; + +static struct edma *edma_info[EDMA_MAX_CC]; /* dummy param set used to (re)initialize parameter RAM slots */ static const struct edmacc_param dummy_paramset = { @@ -1018,11 +1033,13 @@ static int __init edma_probe(struct platform_device *pdev) int irq = 0, err_irq = 0; struct resource *r; resource_size_t len; + char name[10]; if (!info) return -ENODEV; - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "edma_cc"); + sprintf(name, "edma_cc%d", pdev->id); + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); if (!r) return -ENODEV; @@ -1032,28 +1049,41 @@ static int __init edma_probe(struct platform_device *pdev) if (!r) return -EBUSY; - edmacc_regs_base = ioremap(r->start, len); - if (!edmacc_regs_base) { + edmacc_regs_base[pdev->id] = ioremap(r->start, len); + if (!edmacc_regs_base[pdev->id]) { status = -EBUSY; goto fail1; } - num_channels = min_t(unsigned, info->n_channel, EDMA_MAX_DMACH); - num_slots = min_t(unsigned, info->n_slot, EDMA_MAX_PARAMENTRY); + edma_info[pdev->id] = kmalloc(sizeof(struct edma), GFP_KERNEL); + if (!edma_info[pdev->id]) { + status = -ENOMEM; + iounmap(edmacc_regs_base[pdev->id]); + goto fail1; + } + memset(edma_info[pdev->id], 0, sizeof(struct edma)); + + edma_info[pdev->id]->num_channels = min_t(unsigned, info->n_channel, + EDMA_MAX_DMACH); + edma_info[pdev->id]->num_slots = min_t(unsigned, info->n_slot, + EDMA_MAX_PARAMENTRY); + edma_info[pdev->id]->num_cc = min_t(unsigned, info->n_cc, EDMA_MAX_CC); - dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", edmacc_regs_base); + dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", + edmacc_regs_base[pdev->id]); - for (i = 0; i < num_slots; i++) - memcpy_toio(edmacc_regs_base + PARM_OFFSET(i), + for (i = 0; i < edma_info[pdev->id]->num_slots; i++) + memcpy_toio(edmacc_regs_base[pdev->id] + PARM_OFFSET(i), &dummy_paramset, PARM_SIZE); noevent = info->noevent; if (noevent) { while (*noevent != -1) - set_bit(*noevent++, edma_noevent); + set_bit(*noevent++, edma_info[pdev->id]->edma_noevent); } irq = platform_get_irq(pdev, 0); + edma_info[pdev->id]->irq_res_start = irq; status = request_irq(irq, dma_irq_handler, 0, "edma", &pdev->dev); if (status < 0) { dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", @@ -1062,6 +1092,7 @@ static int __init edma_probe(struct platform_device *pdev) } err_irq = platform_get_irq(pdev, 1); + edma_info[pdev->id]->irq_res_end = err_irq; status = request_irq(err_irq, dma_ccerr_handler, 0, "edma_error", &pdev->dev); if (status < 0) { @@ -1091,22 +1122,23 @@ static int __init edma_probe(struct platform_device *pdev) * This way, long transfers on the low priority queue * started by the codec engine will not cause audio defects. */ - for (i = 0; i < num_channels; i++) - map_dmach_queue(i, EVENTQ_1); + for (i = 0; i < edma_info[pdev->id]->num_channels; i++) + map_dmach_queue(pdev->id, i, EVENTQ_1); /* Event queue to TC mapping */ for (i = 0; queue_tc_mapping[i][0] != -1; i++) - map_queue_tc(queue_tc_mapping[i][0], queue_tc_mapping[i][1]); + map_queue_tc(pdev->id, queue_tc_mapping[i][0], + queue_tc_mapping[i][1]); /* Event queue priority mapping */ for (i = 0; queue_priority_mapping[i][0] != -1; i++) - assign_priority_to_queue(queue_priority_mapping[i][0], + assign_priority_to_queue(pdev->id, queue_priority_mapping[i][0], queue_priority_mapping[i][1]); for (i = 0; i < info->n_region; i++) { - edma_write_array2(EDMA_DRAE, i, 0, 0x0); - edma_write_array2(EDMA_DRAE, i, 1, 0x0); - edma_write_array(EDMA_QRAE, i, 0x0); + edma_write_array2(pdev->id, EDMA_DRAE, i, 0, 0x0); + edma_write_array2(pdev->id, EDMA_DRAE, i, 1, 0x0); + edma_write_array(pdev->id, EDMA_QRAE, i, 0x0); } return 0; @@ -1116,7 +1148,7 @@ fail: free_irq(err_irq, NULL); if (irq) free_irq(irq, NULL); - iounmap(edmacc_regs_base); + iounmap(edmacc_regs_base[pdev->id]); fail1: release_mem_region(r->start, len); return status; diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h index 24a3792..0780a4e 100644 --- a/arch/arm/mach-davinci/include/mach/edma.h +++ b/arch/arm/mach-davinci/include/mach/edma.h @@ -216,6 +216,7 @@ struct edma_soc_info { unsigned n_region; unsigned n_slot; unsigned n_tc; + unsigned n_cc; /* list of channels with no even trigger; terminated by "-1" */ const s8 *noevent;