Commit 0cdc79a2 authored by Sudhakar Rajashekhara's avatar Sudhakar Rajashekhara Committed by Kevin Hilman

ARM: DaVinci: Internal restructuring of EDMA driver

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: default avatarSudhakar Rajashekhara <sudhakar.raj@ti.com>
Reviewed-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 20b84f61
...@@ -563,12 +563,13 @@ static struct edma_soc_info dm355_edma_info = { ...@@ -563,12 +563,13 @@ static struct edma_soc_info dm355_edma_info = {
.n_region = 4, .n_region = 4,
.n_slot = 128, .n_slot = 128,
.n_tc = 2, .n_tc = 2,
.n_cc = 1,
.noevent = dma_chan_dm355_no_event, .noevent = dma_chan_dm355_no_event,
}; };
static struct resource edma_resources[] = { static struct resource edma_resources[] = {
{ {
.name = "edma_cc", .name = "edma_cc0",
.start = 0x01c00000, .start = 0x01c00000,
.end = 0x01c00000 + SZ_64K - 1, .end = 0x01c00000 + SZ_64K - 1,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
...@@ -598,7 +599,7 @@ static struct resource edma_resources[] = { ...@@ -598,7 +599,7 @@ static struct resource edma_resources[] = {
static struct platform_device dm355_edma_device = { static struct platform_device dm355_edma_device = {
.name = "edma", .name = "edma",
.id = -1, .id = 0,
.dev.platform_data = &dm355_edma_info, .dev.platform_data = &dm355_edma_info,
.num_resources = ARRAY_SIZE(edma_resources), .num_resources = ARRAY_SIZE(edma_resources),
.resource = edma_resources, .resource = edma_resources,
......
...@@ -489,12 +489,13 @@ static struct edma_soc_info dm644x_edma_info = { ...@@ -489,12 +489,13 @@ static struct edma_soc_info dm644x_edma_info = {
.n_region = 4, .n_region = 4,
.n_slot = 128, .n_slot = 128,
.n_tc = 2, .n_tc = 2,
.n_cc = 1,
.noevent = dma_chan_dm644x_no_event, .noevent = dma_chan_dm644x_no_event,
}; };
static struct resource edma_resources[] = { static struct resource edma_resources[] = {
{ {
.name = "edma_cc", .name = "edma_cc0",
.start = 0x01c00000, .start = 0x01c00000,
.end = 0x01c00000 + SZ_64K - 1, .end = 0x01c00000 + SZ_64K - 1,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
...@@ -524,7 +525,7 @@ static struct resource edma_resources[] = { ...@@ -524,7 +525,7 @@ static struct resource edma_resources[] = {
static struct platform_device dm644x_edma_device = { static struct platform_device dm644x_edma_device = {
.name = "edma", .name = "edma",
.id = -1, .id = 0,
.dev.platform_data = &dm644x_edma_info, .dev.platform_data = &dm644x_edma_info,
.num_resources = ARRAY_SIZE(edma_resources), .num_resources = ARRAY_SIZE(edma_resources),
.resource = edma_resources, .resource = edma_resources,
......
...@@ -107,11 +107,12 @@ ...@@ -107,11 +107,12 @@
#define EDMA_MAX_DMACH 64 #define EDMA_MAX_DMACH 64
#define EDMA_MAX_PARAMENTRY 512 #define EDMA_MAX_PARAMENTRY 512
#define EDMA_MAX_EVQUE 2 /* FIXME too small */ #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) 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) ...@@ -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 */ /* actual number of DMA channels and slots on this silicon */
static unsigned num_channels; struct edma {
static unsigned num_slots; /* 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 { /* The edma_noevent bit for each channel is clear unless
void (*callback)(unsigned channel, unsigned short ch_status, * it doesn't trigger DMA events on this platform. It uses a
void *data); * bit of SOC-specific initialization code.
void *data; */
} intr_data[EDMA_MAX_DMACH]; DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH);
/* The edma_inuse bit for each PaRAM slot is clear unless the unsigned irq_res_start;
* channel is in use ... by ARM or DSP, for QDMA, or whatever. unsigned irq_res_end;
*/
static DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
/* The edma_noevent bit for each channel is clear unless struct dma_interrupt_data {
* it doesn't trigger DMA events on this platform. It uses a void (*callback)(unsigned channel, unsigned short ch_status,
* bit of SOC-specific initialization code. void *data);
*/ void *data;
static DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH); } intr_data[EDMA_MAX_DMACH];
};
static struct edma *edma_info[EDMA_MAX_CC];
/* dummy param set used to (re)initialize parameter RAM slots */ /* dummy param set used to (re)initialize parameter RAM slots */
static const struct edmacc_param dummy_paramset = { static const struct edmacc_param dummy_paramset = {
...@@ -1018,11 +1033,13 @@ static int __init edma_probe(struct platform_device *pdev) ...@@ -1018,11 +1033,13 @@ static int __init edma_probe(struct platform_device *pdev)
int irq = 0, err_irq = 0; int irq = 0, err_irq = 0;
struct resource *r; struct resource *r;
resource_size_t len; resource_size_t len;
char name[10];
if (!info) if (!info)
return -ENODEV; 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) if (!r)
return -ENODEV; return -ENODEV;
...@@ -1032,28 +1049,41 @@ static int __init edma_probe(struct platform_device *pdev) ...@@ -1032,28 +1049,41 @@ static int __init edma_probe(struct platform_device *pdev)
if (!r) if (!r)
return -EBUSY; return -EBUSY;
edmacc_regs_base = ioremap(r->start, len); edmacc_regs_base[pdev->id] = ioremap(r->start, len);
if (!edmacc_regs_base) { if (!edmacc_regs_base[pdev->id]) {
status = -EBUSY; status = -EBUSY;
goto fail1; goto fail1;
} }
num_channels = min_t(unsigned, info->n_channel, EDMA_MAX_DMACH); edma_info[pdev->id] = kmalloc(sizeof(struct edma), GFP_KERNEL);
num_slots = min_t(unsigned, info->n_slot, EDMA_MAX_PARAMENTRY); 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++) for (i = 0; i < edma_info[pdev->id]->num_slots; i++)
memcpy_toio(edmacc_regs_base + PARM_OFFSET(i), memcpy_toio(edmacc_regs_base[pdev->id] + PARM_OFFSET(i),
&dummy_paramset, PARM_SIZE); &dummy_paramset, PARM_SIZE);
noevent = info->noevent; noevent = info->noevent;
if (noevent) { if (noevent) {
while (*noevent != -1) while (*noevent != -1)
set_bit(*noevent++, edma_noevent); set_bit(*noevent++, edma_info[pdev->id]->edma_noevent);
} }
irq = platform_get_irq(pdev, 0); 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); status = request_irq(irq, dma_irq_handler, 0, "edma", &pdev->dev);
if (status < 0) { if (status < 0) {
dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n", dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
...@@ -1062,6 +1092,7 @@ static int __init edma_probe(struct platform_device *pdev) ...@@ -1062,6 +1092,7 @@ static int __init edma_probe(struct platform_device *pdev)
} }
err_irq = platform_get_irq(pdev, 1); 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, status = request_irq(err_irq, dma_ccerr_handler, 0,
"edma_error", &pdev->dev); "edma_error", &pdev->dev);
if (status < 0) { if (status < 0) {
...@@ -1091,22 +1122,23 @@ static int __init edma_probe(struct platform_device *pdev) ...@@ -1091,22 +1122,23 @@ static int __init edma_probe(struct platform_device *pdev)
* This way, long transfers on the low priority queue * This way, long transfers on the low priority queue
* started by the codec engine will not cause audio defects. * started by the codec engine will not cause audio defects.
*/ */
for (i = 0; i < num_channels; i++) for (i = 0; i < edma_info[pdev->id]->num_channels; i++)
map_dmach_queue(i, EVENTQ_1); map_dmach_queue(pdev->id, i, EVENTQ_1);
/* Event queue to TC mapping */ /* Event queue to TC mapping */
for (i = 0; queue_tc_mapping[i][0] != -1; i++) 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 */ /* Event queue priority mapping */
for (i = 0; queue_priority_mapping[i][0] != -1; i++) 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]); queue_priority_mapping[i][1]);
for (i = 0; i < info->n_region; i++) { for (i = 0; i < info->n_region; i++) {
edma_write_array2(EDMA_DRAE, i, 0, 0x0); edma_write_array2(pdev->id, EDMA_DRAE, i, 0, 0x0);
edma_write_array2(EDMA_DRAE, i, 1, 0x0); edma_write_array2(pdev->id, EDMA_DRAE, i, 1, 0x0);
edma_write_array(EDMA_QRAE, i, 0x0); edma_write_array(pdev->id, EDMA_QRAE, i, 0x0);
} }
return 0; return 0;
...@@ -1116,7 +1148,7 @@ fail: ...@@ -1116,7 +1148,7 @@ fail:
free_irq(err_irq, NULL); free_irq(err_irq, NULL);
if (irq) if (irq)
free_irq(irq, NULL); free_irq(irq, NULL);
iounmap(edmacc_regs_base); iounmap(edmacc_regs_base[pdev->id]);
fail1: fail1:
release_mem_region(r->start, len); release_mem_region(r->start, len);
return status; return status;
......
...@@ -216,6 +216,7 @@ struct edma_soc_info { ...@@ -216,6 +216,7 @@ struct edma_soc_info {
unsigned n_region; unsigned n_region;
unsigned n_slot; unsigned n_slot;
unsigned n_tc; unsigned n_tc;
unsigned n_cc;
/* list of channels with no even trigger; terminated by "-1" */ /* list of channels with no even trigger; terminated by "-1" */
const s8 *noevent; const s8 *noevent;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment