Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1dc737c4 authored by Rob Herring's avatar Rob Herring Committed by Marek Szyprowski
Browse files

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: default avatarRob Herring <rob.herring@calxeda.com>
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
parent 48aa820f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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";
+3 −0
Original line number Diff line number Diff line
@@ -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 {
+3 −0
Original line number Diff line number Diff line
@@ -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 {
+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@
			compatible = "calxeda,hb-ahci";
			reg = <0xffe08000 0x10000>;
			interrupts = <0 83 4>;
			dma-coherent;
		};

		sdhci@ffe0e000 {
+52 −0
Original line number Diff line number Diff line
@@ -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);
}