Commit d078cd1b authored by Zidan Wang's avatar Zidan Wang Committed by Vinod Koul

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: default avatarZidan Wang <zidan.wang@freescale.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
parent e900c30d
......@@ -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 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
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)
......
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