summaryrefslogtreecommitdiff
path: root/arch/arm/common/edma.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/common/edma.c')
-rw-r--r--arch/arm/common/edma.c76
1 files changed, 28 insertions, 48 deletions
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 41bca32409fc..3ef06c4ada4b 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -994,29 +994,23 @@ void edma_set_dest(unsigned slot, dma_addr_t dest_port,
EXPORT_SYMBOL(edma_set_dest);
/**
- * edma_get_position - returns the current transfer points
+ * edma_get_position - returns the current transfer point
* @slot: parameter RAM slot being examined
- * @src: pointer to source port position
- * @dst: pointer to destination port position
+ * @dst: true selects the dest position, false the source
*
- * Returns current source and destination addresses for a particular
- * parameter RAM slot. Its channel should not be active when this is called.
+ * Returns the position of the current active slot
*/
-void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst)
+dma_addr_t edma_get_position(unsigned slot, bool dst)
{
- struct edmacc_param temp;
- unsigned ctlr;
+ u32 offs, ctlr = EDMA_CTLR(slot);
- ctlr = EDMA_CTLR(slot);
slot = EDMA_CHAN_SLOT(slot);
- edma_read_slot(EDMA_CTLR_CHAN(ctlr, slot), &temp);
- if (src != NULL)
- *src = temp.src;
- if (dst != NULL)
- *dst = temp.dst;
+ offs = PARM_OFFSET(slot);
+ offs += dst ? PARM_DST : PARM_SRC;
+
+ return edma_read(ctlr, offs);
}
-EXPORT_SYMBOL(edma_get_position);
/**
* edma_set_src_index - configure DMA source address indexing
@@ -1423,55 +1417,38 @@ 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)
+static int edma_xbar_event_map(struct device *dev, struct device_node *node,
+ struct edma_soc_info *pdata, size_t sz)
{
- int ret, i;
+ const char pname[] = "ti,edma-xbar-event-map";
struct resource res;
void __iomem *xbar;
- const s16 (*xbar_chans)[2];
+ s16 (*xbar_chans)[2];
+ size_t nelm = sz / sizeof(s16);
u32 shift, offset, mux;
+ int ret, i;
- xbar_chans = devm_kzalloc(dev,
- len/sizeof(s16) + 2*sizeof(s16),
- GFP_KERNEL);
+ xbar_chans = devm_kzalloc(dev, (nelm + 2) * sizeof(s16), GFP_KERNEL);
if (!xbar_chans)
return -ENOMEM;
ret = of_address_to_resource(node, 1, &res);
if (ret)
- return -EIO;
+ return -ENOMEM;
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));
+ ret = of_property_read_u16_array(node, pname, (u16 *)xbar_chans, nelm);
if (ret)
return -EIO;
- for (i = 0; xbar_chans[i][0] != -1; i++) {
+ /* Invalidate last entry for the other user of this mess */
+ nelm >>= 1;
+ xbar_chans[nelm][0] = xbar_chans[nelm][1] = -1;
+
+ for (i = 0; i < nelm; i++) {
shift = (xbar_chans[i][1] & 0x03) << 3;
offset = xbar_chans[i][1] & 0xfffffffc;
mux = readl(xbar + offset);
@@ -1480,8 +1457,7 @@ static int edma_xbar_event_map(struct device *dev,
writel(mux, (xbar + offset));
}
- pdata->xbar_chans = xbar_chans;
-
+ pdata->xbar_chans = (const s16 (*)[2]) xbar_chans;
return 0;
}
@@ -1574,6 +1550,7 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
return ERR_PTR(ret);
dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
+ dma_cap_set(DMA_CYCLIC, edma_filter_info.dma_cap);
of_dma_controller_register(dev->of_node, of_dma_simple_xlate,
&edma_filter_info);
@@ -1768,6 +1745,9 @@ static int edma_probe(struct platform_device *pdev)
map_queue_tc(j, queue_tc_mapping[i][0],
queue_tc_mapping[i][1]);
+ /* Save the number of TCs */
+ edma_cc[j]->num_tc = i;
+
/* Event queue priority mapping */
for (i = 0; queue_priority_mapping[i][0] != -1; i++)
assign_priority_to_queue(j,