1
0
Fork 0

dmaengine: imx-sdma: Add imx6sx platform support

The new Solo X has more requirements for SDMA events. So it creates
a event mux to remap most of event numbers in GPR (General Purpose
Register). If we want to use SDMA support for those module who do
not get the even number as default, we need to configure GPR first.

Thus this patch adds this support of GPR event remapping configuration
to the SDMA driver.

Signed-off-by: Zidan Wang <zidan.wang@freescale.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
hifive-unleashed-5.1
Zidan Wang 2015-07-23 11:40:49 +08:00 committed by Vinod Koul
parent e900c30dc1
commit d078cd1b41
1 changed files with 73 additions and 0 deletions

View File

@ -42,6 +42,9 @@
#include <asm/irq.h>
#include <linux/platform_data/dma-imx-sdma.h>
#include <linux/platform_data/dma-imx.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include "dmaengine.h"
@ -1447,6 +1450,72 @@ err_firmware:
release_firmware(fw);
}
#define EVENT_REMAP_CELLS 3
static int __init sdma_event_remap(struct sdma_engine *sdma)
{
struct device_node *np = sdma->dev->of_node;
struct device_node *gpr_np = of_parse_phandle(np, "gpr", 0);
struct property *event_remap;
struct regmap *gpr;
char propname[] = "fsl,sdma-event-remap";
u32 reg, val, shift, num_map, i;
int ret = 0;
if (IS_ERR(np) || IS_ERR(gpr_np))
goto out;
event_remap = of_find_property(np, propname, NULL);
num_map = event_remap ? (event_remap->length / sizeof(u32)) : 0;
if (!num_map) {
dev_warn(sdma->dev, "no event needs to be remapped\n");
goto out;
} else if (num_map % EVENT_REMAP_CELLS) {
dev_err(sdma->dev, "the property %s must modulo %d\n",
propname, EVENT_REMAP_CELLS);
ret = -EINVAL;
goto out;
}
gpr = syscon_node_to_regmap(gpr_np);
if (IS_ERR(gpr)) {
dev_err(sdma->dev, "failed to get gpr regmap\n");
ret = PTR_ERR(gpr);
goto out;
}
for (i = 0; i < num_map; i += EVENT_REMAP_CELLS) {
ret = of_property_read_u32_index(np, propname, i, &reg);
if (ret) {
dev_err(sdma->dev, "failed to read property %s index %d\n",
propname, i);
goto out;
}
ret = of_property_read_u32_index(np, propname, i + 1, &shift);
if (ret) {
dev_err(sdma->dev, "failed to read property %s index %d\n",
propname, i + 1);
goto out;
}
ret = of_property_read_u32_index(np, propname, i + 2, &val);
if (ret) {
dev_err(sdma->dev, "failed to read property %s index %d\n",
propname, i + 2);
goto out;
}
regmap_update_bits(gpr, reg, BIT(shift), val << shift);
}
out:
if (!IS_ERR(gpr_np))
of_node_put(gpr_np);
return ret;
}
static int sdma_get_firmware(struct sdma_engine *sdma,
const char *fw_name)
{
@ -1671,6 +1740,10 @@ static int sdma_probe(struct platform_device *pdev)
if (ret)
goto err_init;
ret = sdma_event_remap(sdma);
if (ret)
goto err_init;
if (sdma->drvdata->script_addrs)
sdma_add_scripts(sdma, sdma->drvdata->script_addrs);
if (pdata && pdata->script_addrs)