ARM: highbank: add coherent DMA setup

Some highbank DMA masters can support coherent (ACP) or non-coherent DMA.
This sets up dma_map_ops for masters which are configured for coherent DMA.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
This commit is contained in:
Rob Herring 2012-08-21 12:31:06 +02:00 committed by Marek Szyprowski
parent 48aa820f1e
commit 1dc737c44a
5 changed files with 62 additions and 0 deletions

View File

@ -8,6 +8,9 @@ Required properties:
- interrupts : <interrupt mapping for SATA IRQ>
- reg : <registers mapping>
Optional properties:
- dma-coherent : Present if dma operations are coherent
Example:
sata@ffe08000 {
compatible = "calxeda,hb-ahci";

View File

@ -9,6 +9,9 @@ Required properties:
region.
- interrupts: interrupt number to the cpu.
Optional properties:
- dma-coherent : Present if dma operations are coherent
Example:
pdma0: pdma@12680000 {

View File

@ -6,6 +6,9 @@ Required properties:
- interrupts : Should contain 3 xgmac interrupts. The 1st is main interrupt.
The 2nd is pwr mgt interrupt. The 3rd is low power state interrupt.
Optional properties:
- dma-coherent : Present if dma operations are coherent
Example:
ethernet@fff50000 {

View File

@ -121,6 +121,7 @@ sata@ffe08000 {
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x10000>;
interrupts = <0 83 4>;
dma-coherent;
};
sdhci@ffe0e000 {

View File

@ -15,6 +15,7 @@
*/
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
@ -23,6 +24,7 @@
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/smp.h>
#include <linux/amba/bus.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
@ -149,10 +151,60 @@ static void highbank_power_off(void)
cpu_do_idle();
}
static int highbank_platform_notifier(struct notifier_block *nb,
unsigned long event, void *__dev)
{
struct resource *res;
int reg = -1;
struct device *dev = __dev;
if (event != BUS_NOTIFY_ADD_DEVICE)
return NOTIFY_DONE;
if (of_device_is_compatible(dev->of_node, "calxeda,hb-ahci"))
reg = 0xc;
else if (of_device_is_compatible(dev->of_node, "calxeda,hb-sdhci"))
reg = 0x18;
else if (of_device_is_compatible(dev->of_node, "arm,pl330"))
reg = 0x20;
else if (of_device_is_compatible(dev->of_node, "calxeda,hb-xgmac")) {
res = platform_get_resource(to_platform_device(dev),
IORESOURCE_MEM, 0);
if (res) {
if (res->start == 0xfff50000)
reg = 0;
else if (res->start == 0xfff51000)
reg = 4;
}
}
if (reg < 0)
return NOTIFY_DONE;
if (of_property_read_bool(dev->of_node, "dma-coherent")) {
writel(0xff31, sregs_base + reg);
set_dma_ops(dev, &arm_coherent_dma_ops);
} else
writel(0, sregs_base + reg);
return NOTIFY_OK;
}
static struct notifier_block highbank_amba_nb = {
.notifier_call = highbank_platform_notifier,
};
static struct notifier_block highbank_platform_nb = {
.notifier_call = highbank_platform_notifier,
};
static void __init highbank_init(void)
{
pm_power_off = highbank_power_off;
bus_register_notifier(&platform_bus_type, &highbank_platform_nb);
bus_register_notifier(&amba_bustype, &highbank_amba_nb);
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}