From patchwork Mon Oct 1 10:01:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [06/19] ARM: highbank: add coherent DMA setup Date: Mon, 01 Oct 2012 00:01:16 -0000 From: Ike Panhc X-Patchwork-Id: 188256 Message-Id: <1349085677-23285-1-git-send-email-ike.pan@canonical.com> To: kernel-team@lists.ubuntu.com From: Rob Herring BugLink: http://launchpad.net/bugs/1059432 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 Signed-off-by: Ike Panhc --- .../devicetree/bindings/ata/ahci-platform.txt | 3 ++ .../devicetree/bindings/dma/arm-pl330.txt | 3 ++ .../devicetree/bindings/net/calxeda-xgmac.txt | 3 ++ arch/arm/boot/dts/highbank.dts | 1 + arch/arm/mach-highbank/highbank.c | 53 ++++++++++++++++++++ 5 files changed, 63 insertions(+) diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index 8bb8a76..6c1ad01 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -8,6 +8,9 @@ Required properties: - interrupts : - reg : +Optional properties: +- dma-coherent : Present if dma operations are coherent + Example: sata@ffe08000 { compatible = "calxeda,hb-ahci"; diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt index a4cd273..36e27d5 100644 --- a/Documentation/devicetree/bindings/dma/arm-pl330.txt +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt @@ -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 { diff --git a/Documentation/devicetree/bindings/net/calxeda-xgmac.txt b/Documentation/devicetree/bindings/net/calxeda-xgmac.txt index 411727a..c8ae996 100644 --- a/Documentation/devicetree/bindings/net/calxeda-xgmac.txt +++ b/Documentation/devicetree/bindings/net/calxeda-xgmac.txt @@ -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 { diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts index d7c3e29..a3f9718 100644 --- a/arch/arm/boot/dts/highbank.dts +++ b/arch/arm/boot/dts/highbank.dts @@ -121,6 +121,7 @@ compatible = "calxeda,hb-ahci"; reg = <0xffe08000 0x10000>; interrupts = <0 83 4>; + dma-coherent; }; sdhci@ffe0e000 { diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index 4ed8211..c1760cf 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -15,6 +15,7 @@ */ #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include #include #include @@ -166,15 +168,66 @@ static int hb_keys_notifier(struct notifier_block *nb, unsigned long event, void return 0; } + static struct notifier_block hb_keys_nb = { .notifier_call = hb_keys_notifier, }; +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; pl320_ipc_register_notifier(&hb_keys_nb); + 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); }