* [PATCHv3 for soc 0/4] Enabling socfpga on hardware
From: dinguyen at altera.com @ 2013-02-01 17:45 UTC (permalink / raw)
To: linux-arm-kernel
From: Dinh Nguyen <dinguyen@altera.com>
V3:
- Addressed comments from Olof Johansson and Russell King
- Received Acked-by and Tested-by Stephen Warren
- Received Signed-off-by Pavel Machek
V2:
- Remove patch that adds clock entries in the socfpga.dtsi as this
should accompany a rework in drivers/clk and will done in a different
patch series.
- Removed I-cache invalidate from v7_invalidate_l1
- Defined cpu1-start-addr as a device tree entry
- Removed the need to use CONFIG_VMSPLIT_2G
Dinh Nguyen (4):
arm: socfpga: Add new device tree source for actual socfpga HW
arm: socfpga: Add entries to enable make dtbs socfpga
arm: Add v7_invalidate_l1 to cache-v7.S
arm: socfpga: Add SMP support for actual socfpga harware
.../bindings/arm/altera/socfpga-system.txt | 2 +
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/socfpga.dtsi | 22 +++----
arch/arm/boot/dts/socfpga_cyclone5.dts | 34 ++++++++++-
arch/arm/boot/dts/socfpga_vt.dts | 64 ++++++++++++++++++++
arch/arm/mach-imx/headsmp.S | 47 --------------
arch/arm/mach-shmobile/headsmp.S | 48 ---------------
arch/arm/mach-socfpga/core.h | 4 +-
arch/arm/mach-socfpga/headsmp.S | 16 +++--
arch/arm/mach-socfpga/platsmp.c | 3 +-
arch/arm/mach-socfpga/socfpga.c | 7 ++-
arch/arm/mach-tegra/headsmp.S | 43 -------------
arch/arm/mm/cache-v7.S | 46 ++++++++++++++
13 files changed, 179 insertions(+), 159 deletions(-)
create mode 100644 arch/arm/boot/dts/socfpga_vt.dts
--
1.7.9.5
^ permalink raw reply
* [PATCHv3 for soc 1/4] arm: socfpga: Add new device tree source for actual socfpga HW
From: dinguyen at altera.com @ 2013-02-01 17:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359740758-29703-1-git-send-email-dinguyen@altera.com>
From: Dinh Nguyen <dinguyen@altera.com>
Up to this point, support for socfpga has only been on a virtual
platform. Now that actual hardware is available, we add the appropriate
device tree source files.
Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
Tested-by: Pavel Machek <pavel@denx.de>
Reviewed-by: Pavel Machek <pavel@denx.de>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
---
arch/arm/boot/dts/socfpga.dtsi | 22 ++++++------
arch/arm/boot/dts/socfpga_cyclone5.dts | 30 ++++++++++++++--
arch/arm/boot/dts/socfpga_vt.dts | 60 ++++++++++++++++++++++++++++++++
arch/arm/mach-socfpga/socfpga.c | 1 -
4 files changed, 98 insertions(+), 15 deletions(-)
create mode 100644 arch/arm/boot/dts/socfpga_vt.dts
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 19aec42..936d230 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -25,6 +25,10 @@
ethernet0 = &gmac0;
serial0 = &uart0;
serial1 = &uart1;
+ timer0 = &timer0;
+ timer1 = &timer1;
+ timer2 = &timer2;
+ timer3 = &timer3;
};
cpus {
@@ -98,47 +102,41 @@
interrupts = <1 13 0xf04>;
};
- timer0: timer at ffc08000 {
+ timer0: timer0 at ffc08000 {
compatible = "snps,dw-apb-timer-sp";
interrupts = <0 167 4>;
- clock-frequency = <200000000>;
reg = <0xffc08000 0x1000>;
};
- timer1: timer at ffc09000 {
+ timer1: timer1 at ffc09000 {
compatible = "snps,dw-apb-timer-sp";
interrupts = <0 168 4>;
- clock-frequency = <200000000>;
reg = <0xffc09000 0x1000>;
};
- timer2: timer at ffd00000 {
+ timer2: timer2 at ffd00000 {
compatible = "snps,dw-apb-timer-osc";
interrupts = <0 169 4>;
- clock-frequency = <200000000>;
reg = <0xffd00000 0x1000>;
};
- timer3: timer at ffd01000 {
+ timer3: timer3 at ffd01000 {
compatible = "snps,dw-apb-timer-osc";
interrupts = <0 170 4>;
- clock-frequency = <200000000>;
reg = <0xffd01000 0x1000>;
};
- uart0: uart at ffc02000 {
+ uart0: serial0 at ffc02000 {
compatible = "snps,dw-apb-uart";
reg = <0xffc02000 0x1000>;
- clock-frequency = <7372800>;
interrupts = <0 162 4>;
reg-shift = <2>;
reg-io-width = <4>;
};
- uart1: uart at ffc03000 {
+ uart1: serial1 at ffc03000 {
compatible = "snps,dw-apb-uart";
reg = <0xffc03000 0x1000>;
- clock-frequency = <7372800>;
interrupts = <0 163 4>;
reg-shift = <2>;
reg-io-width = <4>;
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dts b/arch/arm/boot/dts/socfpga_cyclone5.dts
index ab7e4a9..7ad3cc6 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5.dts
@@ -20,7 +20,7 @@
/ {
model = "Altera SOCFPGA Cyclone V";
- compatible = "altr,socfpga-cyclone5";
+ compatible = "altr,socfpga-cyclone5", "altr,socfpga";
chosen {
bootargs = "console=ttyS0,57600";
@@ -29,6 +29,32 @@
memory {
name = "memory";
device_type = "memory";
- reg = <0x0 0x10000000>; /* 256MB */
+ reg = <0x0 0x40000000>; /* 1GB */
+ };
+
+ soc {
+ timer0 at ffc08000 {
+ clock-frequency = <100000000>;
+ };
+
+ timer1 at ffc09000 {
+ clock-frequency = <100000000>;
+ };
+
+ timer2 at ffd00000 {
+ clock-frequency = <25000000>;
+ };
+
+ timer3 at ffd01000 {
+ clock-frequency = <25000000>;
+ };
+
+ serial0 at ffc02000 {
+ clock-frequency = <100000000>;
+ };
+
+ serial1 at ffc03000 {
+ clock-frequency = <100000000>;
+ };
};
};
diff --git a/arch/arm/boot/dts/socfpga_vt.dts b/arch/arm/boot/dts/socfpga_vt.dts
new file mode 100644
index 0000000..a0c6c65
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_vt.dts
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Altera Corporation <www.altera.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+/include/ "socfpga.dtsi"
+
+/ {
+ model = "Altera SOCFPGA VT";
+ compatible = "altr,socfpga-vt", "altr,socfpga";
+
+ chosen {
+ bootargs = "console=ttyS0,57600";
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0x0 0x40000000>; /* 1 GB */
+ };
+
+ soc {
+ timer0 at ffc08000 {
+ clock-frequency = <7000000>;
+ };
+
+ timer1 at ffc09000 {
+ clock-frequency = <7000000>;
+ };
+
+ timer2 at ffd00000 {
+ clock-frequency = <7000000>;
+ };
+
+ timer3 at ffd01000 {
+ clock-frequency = <7000000>;
+ };
+
+ serial0 at ffc02000 {
+ clock-frequency = <7372800>;
+ };
+
+ serial1 at ffc03000 {
+ clock-frequency = <7372800>;
+ };
+ };
+};
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
index 6732924..94aa6ad 100644
--- a/arch/arm/mach-socfpga/socfpga.c
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -98,7 +98,6 @@ static void __init socfpga_cyclone5_init(void)
static const char *altera_dt_match[] = {
"altr,socfpga",
- "altr,socfpga-cyclone5",
NULL
};
--
1.7.9.5
^ permalink raw reply related
* [PATCHv3 for soc 2/4] arm: socfpga: Add entries to enable make dtbs socfpga
From: dinguyen at altera.com @ 2013-02-01 17:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359740758-29703-1-git-send-email-dinguyen@altera.com>
From: Dinh Nguyen <dinguyen@altera.com>
Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
Tested-by: Pavel Machek <pavel@denx.de>
Reviewed-by: Pavel Machek <pavel@denx.de>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: Pavel Machek <pavel@denx.de>
---
arch/arm/boot/dts/Makefile | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 5ebb44f..1b8276c 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -124,6 +124,8 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
r8a7740-armadillo800eva.dtb \
sh73a0-kzm9g.dtb \
sh7372-mackerel.dtb
+dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb \
+ socfpga_vt.dtb
dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \
spear1340-evb.dtb
dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
--
1.7.9.5
^ permalink raw reply related
* [PATCHv3 for soc 3/4] arm: Add v7_invalidate_l1 to cache-v7.S
From: dinguyen at altera.com @ 2013-02-01 17:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359740758-29703-1-git-send-email-dinguyen@altera.com>
From: Dinh Nguyen <dinguyen@altera.com>
mach-socfpga is another platform that needs to use
v7_invalidate_l1 to bringup additional cores. There was a comment that
the ideal place for v7_invalidate_l1 should be in arm/mm/cache-v7.S
Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
Acked-by: Simon Horman <horms+renesas@verge.net.au>
Acked-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Pavel Machek <pavel@denx.de>
Tested-by: Pavel Machek <pavel@denx.de>
Tested-by: Stephen Warren <swarren@nvidia.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Olof Johansson <olof@lixom.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Magnus Damm <magnus.damm@gmail.com>
---
arch/arm/mach-imx/headsmp.S | 47 -------------------------------------
arch/arm/mach-shmobile/headsmp.S | 48 --------------------------------------
arch/arm/mach-tegra/headsmp.S | 43 ----------------------------------
arch/arm/mm/cache-v7.S | 46 ++++++++++++++++++++++++++++++++++++
4 files changed, 46 insertions(+), 138 deletions(-)
diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S
index 7e49deb..921fc15 100644
--- a/arch/arm/mach-imx/headsmp.S
+++ b/arch/arm/mach-imx/headsmp.S
@@ -17,53 +17,6 @@
.section ".text.head", "ax"
-/*
- * The secondary kernel init calls v7_flush_dcache_all before it enables
- * the L1; however, the L1 comes out of reset in an undefined state, so
- * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
- * of cache lines with uninitialized data and uninitialized tags to get
- * written out to memory, which does really unpleasant things to the main
- * processor. We fix this by performing an invalidate, rather than a
- * clean + invalidate, before jumping into the kernel.
- *
- * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
- * to be called for both secondary cores startup and primary core resume
- * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
- */
-ENTRY(v7_invalidate_l1)
- mov r0, #0
- mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
- mcr p15, 2, r0, c0, c0, 0
- mrc p15, 1, r0, c0, c0, 0
-
- ldr r1, =0x7fff
- and r2, r1, r0, lsr #13
-
- ldr r1, =0x3ff
-
- and r3, r1, r0, lsr #3 @ NumWays - 1
- add r2, r2, #1 @ NumSets
-
- and r0, r0, #0x7
- add r0, r0, #4 @ SetShift
-
- clz r1, r3 @ WayShift
- add r4, r3, #1 @ NumWays
-1: sub r2, r2, #1 @ NumSets--
- mov r3, r4 @ Temp = NumWays
-2: subs r3, r3, #1 @ Temp--
- mov r5, r3, lsl r1
- mov r6, r2, lsl r0
- orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
- mcr p15, 0, r5, c7, c6, 2
- bgt 2b
- cmp r2, #0
- bgt 1b
- dsb
- isb
- mov pc, lr
-ENDPROC(v7_invalidate_l1)
-
#ifdef CONFIG_SMP
ENTRY(v7_secondary_startup)
bl v7_invalidate_l1
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
index b202c12..96001fd 100644
--- a/arch/arm/mach-shmobile/headsmp.S
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -16,54 +16,6 @@
__CPUINIT
-/* Cache invalidation nicked from arch/arm/mach-imx/head-v7.S, thanks!
- *
- * The secondary kernel init calls v7_flush_dcache_all before it enables
- * the L1; however, the L1 comes out of reset in an undefined state, so
- * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
- * of cache lines with uninitialized data and uninitialized tags to get
- * written out to memory, which does really unpleasant things to the main
- * processor. We fix this by performing an invalidate, rather than a
- * clean + invalidate, before jumping into the kernel.
- *
- * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
- * to be called for both secondary cores startup and primary core resume
- * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
- */
-ENTRY(v7_invalidate_l1)
- mov r0, #0
- mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
- mcr p15, 2, r0, c0, c0, 0
- mrc p15, 1, r0, c0, c0, 0
-
- ldr r1, =0x7fff
- and r2, r1, r0, lsr #13
-
- ldr r1, =0x3ff
-
- and r3, r1, r0, lsr #3 @ NumWays - 1
- add r2, r2, #1 @ NumSets
-
- and r0, r0, #0x7
- add r0, r0, #4 @ SetShift
-
- clz r1, r3 @ WayShift
- add r4, r3, #1 @ NumWays
-1: sub r2, r2, #1 @ NumSets--
- mov r3, r4 @ Temp = NumWays
-2: subs r3, r3, #1 @ Temp--
- mov r5, r3, lsl r1
- mov r6, r2, lsl r0
- orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
- mcr p15, 0, r5, c7, c6, 2
- bgt 2b
- cmp r2, #0
- bgt 1b
- dsb
- isb
- mov pc, lr
-ENDPROC(v7_invalidate_l1)
-
ENTRY(shmobile_invalidate_start)
bl v7_invalidate_l1
b secondary_startup
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
index 4a317fa..fb082c4 100644
--- a/arch/arm/mach-tegra/headsmp.S
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -18,49 +18,6 @@
.section ".text.head", "ax"
__CPUINIT
-/*
- * Tegra specific entry point for secondary CPUs.
- * The secondary kernel init calls v7_flush_dcache_all before it enables
- * the L1; however, the L1 comes out of reset in an undefined state, so
- * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
- * of cache lines with uninitialized data and uninitialized tags to get
- * written out to memory, which does really unpleasant things to the main
- * processor. We fix this by performing an invalidate, rather than a
- * clean + invalidate, before jumping into the kernel.
- */
-ENTRY(v7_invalidate_l1)
- mov r0, #0
- mcr p15, 2, r0, c0, c0, 0
- mrc p15, 1, r0, c0, c0, 0
-
- ldr r1, =0x7fff
- and r2, r1, r0, lsr #13
-
- ldr r1, =0x3ff
-
- and r3, r1, r0, lsr #3 @ NumWays - 1
- add r2, r2, #1 @ NumSets
-
- and r0, r0, #0x7
- add r0, r0, #4 @ SetShift
-
- clz r1, r3 @ WayShift
- add r4, r3, #1 @ NumWays
-1: sub r2, r2, #1 @ NumSets--
- mov r3, r4 @ Temp = NumWays
-2: subs r3, r3, #1 @ Temp--
- mov r5, r3, lsl r1
- mov r6, r2, lsl r0
- orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
- mcr p15, 0, r5, c7, c6, 2
- bgt 2b
- cmp r2, #0
- bgt 1b
- dsb
- isb
- mov pc, lr
-ENDPROC(v7_invalidate_l1)
-
ENTRY(tegra_secondary_startup)
bl v7_invalidate_l1
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 7539ec2..15451ee 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -19,6 +19,52 @@
#include "proc-macros.S"
/*
+ * The secondary kernel init calls v7_flush_dcache_all before it enables
+ * the L1; however, the L1 comes out of reset in an undefined state, so
+ * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
+ * of cache lines with uninitialized data and uninitialized tags to get
+ * written out to memory, which does really unpleasant things to the main
+ * processor. We fix this by performing an invalidate, rather than a
+ * clean + invalidate, before jumping into the kernel.
+ *
+ * This function is cloned from arch/arm/mach-tegra/headsmp.S, and needs
+ * to be called for both secondary cores startup and primary core resume
+ * procedures.
+ */
+ENTRY(v7_invalidate_l1)
+ mov r0, #0
+ mcr p15, 2, r0, c0, c0, 0
+ mrc p15, 1, r0, c0, c0, 0
+
+ ldr r1, =0x7fff
+ and r2, r1, r0, lsr #13
+
+ ldr r1, =0x3ff
+
+ and r3, r1, r0, lsr #3 @ NumWays - 1
+ add r2, r2, #1 @ NumSets
+
+ and r0, r0, #0x7
+ add r0, r0, #4 @ SetShift
+
+ clz r1, r3 @ WayShift
+ add r4, r3, #1 @ NumWays
+1: sub r2, r2, #1 @ NumSets--
+ mov r3, r4 @ Temp = NumWays
+2: subs r3, r3, #1 @ Temp--
+ mov r5, r3, lsl r1
+ mov r6, r2, lsl r0
+ orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
+ mcr p15, 0, r5, c7, c6, 2
+ bgt 2b
+ cmp r2, #0
+ bgt 1b
+ dsb
+ isb
+ mov pc, lr
+ENDPROC(v7_invalidate_l1)
+
+/*
* v7_flush_icache_all()
*
* Flush the whole I-cache.
--
1.7.9.5
^ permalink raw reply related
* [PATCHv3 for soc 4/4] arm: socfpga: Add SMP support for actual socfpga harware
From: dinguyen at altera.com @ 2013-02-01 17:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359740758-29703-1-git-send-email-dinguyen@altera.com>
From: Dinh Nguyen <dinguyen@altera.com>
Because the CPU1 start address is different for socfpga-vt and
socfpga-cyclone5, we add code to use the correct CPU1 start addr.
Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
Signed-off-by: Pavel Machek <pavel@denx.de>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Pavel Machek <pavel@denx.de>
---
.../bindings/arm/altera/socfpga-system.txt | 2 ++
arch/arm/boot/dts/socfpga_cyclone5.dts | 4 ++++
arch/arm/boot/dts/socfpga_vt.dts | 4 ++++
arch/arm/mach-socfpga/core.h | 4 +++-
arch/arm/mach-socfpga/headsmp.S | 16 ++++++++++++----
arch/arm/mach-socfpga/platsmp.c | 3 ++-
arch/arm/mach-socfpga/socfpga.c | 6 ++++++
7 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
index 07c65e3..f4d04a0 100644
--- a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
+++ b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
@@ -3,9 +3,11 @@ Altera SOCFPGA System Manager
Required properties:
- compatible : "altr,sys-mgr"
- reg : Should contain 1 register ranges(address and length)
+- cpu1-start-addr : CPU1 start address in hex.
Example:
sysmgr at ffd08000 {
compatible = "altr,sys-mgr";
reg = <0xffd08000 0x1000>;
+ cpu1-start-addr = <0xffd080c4>;
};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dts b/arch/arm/boot/dts/socfpga_cyclone5.dts
index 7ad3cc6..3ae8a83 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5.dts
@@ -56,5 +56,9 @@
serial1 at ffc03000 {
clock-frequency = <100000000>;
};
+
+ sysmgr at ffd08000 {
+ cpu1-start-addr = <0xffd080c4>;
+ };
};
};
diff --git a/arch/arm/boot/dts/socfpga_vt.dts b/arch/arm/boot/dts/socfpga_vt.dts
index a0c6c65..1036eba 100644
--- a/arch/arm/boot/dts/socfpga_vt.dts
+++ b/arch/arm/boot/dts/socfpga_vt.dts
@@ -56,5 +56,9 @@
serial1 at ffc03000 {
clock-frequency = <7372800>;
};
+
+ sysmgr at ffd08000 {
+ cpu1-start-addr = <0xffd08010>;
+ };
};
};
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
index 9941caa..5b76dd4 100644
--- a/arch/arm/mach-socfpga/core.h
+++ b/arch/arm/mach-socfpga/core.h
@@ -20,7 +20,7 @@
#ifndef __MACH_CORE_H
#define __MACH_CORE_H
-extern void secondary_startup(void);
+extern void v7_secondary_startup(void);
extern void __iomem *socfpga_scu_base_addr;
extern void socfpga_init_clocks(void);
@@ -29,6 +29,8 @@ extern void socfpga_sysmgr_init(void);
extern struct smp_operations socfpga_smp_ops;
extern char secondary_trampoline, secondary_trampoline_end;
+extern unsigned long cpu1start_addr;
+
#define SOCFPGA_SCU_VIRT_BASE 0xfffec000
#endif
diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S
index f09b128..3c83582 100644
--- a/arch/arm/mach-socfpga/headsmp.S
+++ b/arch/arm/mach-socfpga/headsmp.S
@@ -13,13 +13,21 @@
__CPUINIT
.arch armv7-a
-#define CPU1_START_ADDR 0xffd08010
-
ENTRY(secondary_trampoline)
- movw r0, #:lower16:CPU1_START_ADDR
- movt r0, #:upper16:CPU1_START_ADDR
+ movw r2, #:lower16:cpu1start_addr
+ movt r2, #:upper16:cpu1start_addr
+
+ /* The socfpga VT cannot handle a 0xC0000000 page offset when loading
+ the cpu1start_addr, we bit clear it. Tested on HW and VT. */
+ bic r2, r2, #0x40000000
+ ldr r0, [r2]
ldr r1, [r0]
bx r1
ENTRY(secondary_trampoline_end)
+
+ENTRY(v7_secondary_startup)
+ bl v7_invalidate_l1
+ b secondary_startup
+ENDPROC(v7_secondary_startup)
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
index 68dd1b6..c428519 100644
--- a/arch/arm/mach-socfpga/platsmp.c
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -49,7 +49,8 @@ static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct
memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
- __raw_writel(virt_to_phys(secondary_startup), (sys_manager_base_addr+0x10));
+ __raw_writel(virt_to_phys(v7_secondary_startup),
+ (sys_manager_base_addr + (cpu1start_addr & 0x000000ff)));
flush_cache_all();
smp_wmb();
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
index 94aa6ad..cec1266 100644
--- a/arch/arm/mach-socfpga/socfpga.c
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -29,6 +29,7 @@
void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE));
void __iomem *sys_manager_base_addr;
void __iomem *rst_manager_base_addr;
+unsigned long cpu1start_addr;
static struct map_desc scu_io_desc __initdata = {
.virtual = SOCFPGA_SCU_VIRT_BASE,
@@ -72,6 +73,11 @@ void __init socfpga_sysmgr_init(void)
struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
+
+ if (of_property_read_u32(np, "cpu1-start-addr",
+ (u32 *) &cpu1start_addr))
+ pr_err("SMP: Need cpu1-start-addr in device tree.\n");
+
sys_manager_base_addr = of_iomap(np, 0);
np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3] USB: add devicetree helpers for determining dr_mode and phy_type
From: Sascha Hauer @ 2013-02-01 17:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359705132-9434-1-git-send-email-s.hauer@pengutronix.de>
Apparantly I was not fully awake while sending this series :(
On Fri, Feb 01, 2013 at 08:52:03AM +0100, Sascha Hauer wrote:
> (resend because I got the linux-usb address wrong)
>
> Here's another round of the dr_mode/phy_type patches. I think they should
> be ready for merging now. Greg, will you apply them should there be no
> problems anymore?
>
> Sascha
>
> changes since v2:
>
> - fix adding of GPL Header was in wrong patch
> - add missing hunk for new file of.c
>
> changes since v1:
> - move phy specific of helper to drivers/usb/phy/of.c
> - use strcmp instead of strcasecmp for matching property values
> - change usb_phy_dr_mode to usb_dr_mode
> - change USBPHY_INTERFACE_MODE_NA to USBPHY_INTERFACE_MODE_UNKNOWN
> - add copyright header to new files
> - chipidea: drop mdelay at end of PTS/PTW setup
> - chipidea: implement lpm core type handling for PTS/PTW
>
> The following changes since commit 7b8bc3aad0deabf3bc50cd2fe29bce29be5681fe:
>
> USB: chipidea: ci13xxx_imx: Remove sparse warning (2013-01-30 00:17:39 -0500)
>
> are available in the git repository at:
>
> git://git.pengutronix.de/git/imx/linux-2.6.git tags/usb-chipidea-for-next
>
> for you to fetch changes up to b82b92ba281add3e4d67bf6704052c0fd8c5c7f0:
>
> USB chipidea i.MX: use devm_usb_get_phy_by_phandle to get phy (2013-01-31 12:27:36 +0100)
>
> ----------------------------------------------------------------
> USB Chipidea patches for v3.9
>
> These add OF helpers for handling the dr_mode and phy_type property
> and makes use of them in the chipidea driver.
>
> ----------------------------------------------------------------
> Michael Grzeschik (3):
> USB: add devicetree helpers for determining dr_mode and phy_type
> USB: chipidea: ci13xxx-imx: create dynamic platformdata
> USB: chipidea: add PTW and PTS handling
>
> Sascha Hauer (6):
> USB: move bulk of otg/otg.c to phy/phy.c
> USB chipidea: introduce dual role mode pdata flags
> USB chipidea i.MX: introduce dr_mode property
> como fec wip
> USB mxs-phy: Register phy with framework
> USB chipidea i.MX: use devm_usb_get_phy_by_phandle to get phy
>
> Documentation/devicetree/bindings/net/fsl-fec.txt | 20 +
> .../devicetree/bindings/usb/ci13xxx-imx.txt | 6 +
> drivers/net/ethernet/freescale/fec.c | 77 ++--
> drivers/net/ethernet/freescale/fec.h | 1 +
> drivers/usb/chipidea/bits.h | 14 +-
> drivers/usb/chipidea/ci13xxx_imx.c | 60 ++-
> drivers/usb/chipidea/core.c | 60 ++-
> drivers/usb/otg/mxs-phy.c | 9 +
> drivers/usb/otg/otg.c | 423 -------------------
> drivers/usb/phy/Makefile | 2 +
> drivers/usb/phy/of.c | 47 +++
> drivers/usb/phy/phy.c | 434 ++++++++++++++++++++
> drivers/usb/usb-common.c | 36 ++
> include/linux/usb/chipidea.h | 3 +-
> include/linux/usb/of.h | 27 ++
> include/linux/usb/otg.h | 7 +
> include/linux/usb/phy.h | 9 +
> 17 files changed, 742 insertions(+), 493 deletions(-)
> create mode 100644 drivers/usb/phy/of.c
> create mode 100644 drivers/usb/phy/phy.c
> create mode 100644 include/linux/usb/of.h
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH] ARM: OMAP2+: dpll: Add missing soc_is_am33xx() check
From: Mike Turquette @ 2013-02-01 17:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359714424-21167-1-git-send-email-anilkumar@ti.com>
Quoting AnilKumar Ch (2013-02-01 02:27:04)
> Add missing soc_is_am33xx() check in noncore DPLL set rate function.
> Without this, dpll set_rate function throughs warnings for am33xx
> family of devices.
>
> Signed-off-by: AnilKumar Ch <anilkumar@ti.com>
I think that only 3430 needs the freqsel calculation. If this is true,
then I think it would be better to just have a check for cpu_is_3430()
instead of appending new SoCs to the list that do not care about the
freqsel calculation.
Regards,
Mike
> ---
> arch/arm/mach-omap2/dpll3xxx.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
> index 0a02aab5..4bb3f78 100644
> --- a/arch/arm/mach-omap2/dpll3xxx.c
> +++ b/arch/arm/mach-omap2/dpll3xxx.c
> @@ -501,7 +501,8 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
> return -EINVAL;
>
> /* No freqsel on OMAP4 and OMAP3630 */
> - if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
> + if (!cpu_is_omap44xx() && !cpu_is_omap3630() &&
> + !soc_is_am33xx()) {
> freqsel = _omap3_dpll_compute_freqsel(clk,
> dd->last_rounded_n);
> WARN_ON(!freqsel);
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [RFC PATCH] ARM: mm: Fix alloc_init_section bug on LPAE
From: Catalin Marinas @ 2013-02-01 17:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359160318-27068-1-git-send-email-chris@cloudcar.com>
On Sat, Jan 26, 2013 at 12:31:58AM +0000, Christoffer Dall wrote:
> When using LPAE the call to alloc_init_pte is passed then end address
> for the entire 1st level page table region, and the code unluckily ends
> up going over the bounds of the single allocated PTE, which is sad.
>
> This caused LPAE boot on omap5 to crash.
>
> There may be some hidden mystery in the boot code that I'm unaware of
> or it may be assumed that all mappings are always mappable as sections
> on LPAE and therefore omap5 just does something bad, in which case this
> patch isn't the right fix, but I'd be happy to be told the reason.
>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Jeremy C. Andrus <jeremya@cs.columbia.edu>
> Signed-off-by: Christoffer Dall <chris@cloudcar.com>
> ---
> arch/arm/mm/mmu.c | 12 +++++++-----
> 1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index ce328c7..1cecc99 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -603,11 +603,13 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
>
> flush_pmd_entry(p);
> } else {
> - /*
> - * No need to loop; pte's aren't interested in the
> - * individual L1 entries.
> - */
> - alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
> + unsigned long next;
> +
> + do {
> + next = pmd_addr_end(addr, end);
> + alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), type);
> + phys += next - addr;
> + } while (pmd++, addr = next, addr != end);
I now noticed your patch (I'm a bit behind with the list). It looks to
me like it should work since next == end with the classic MMU, so we
only go through the loop once.
--
Catalin
^ permalink raw reply
* [PATCH v4 00/13] ARM LPAE Fixes - Part 1
From: Nicolas Pitre @ 2013-02-01 17:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <510BE9BC.9090701@ti.com>
On Fri, 1 Feb 2013, Cyril Chemparathy wrote:
> On 02/01/2013 10:14 AM, Russell King - ARM Linux wrote:
> > On Fri, Feb 01, 2013 at 10:10:37AM -0500, Cyril Chemparathy wrote:
> > > With this, I ran simple network and filesystem performance tests to
> > > compare the code-patching vs. non-code-patching variants. These tests
> > > didn't yield any significant performance difference between the two on
> > > an ARMv7 (Cortex-A8) platform.
> >
> > It's not network and fs activity that this kind of stuff is likely to
> > show up in, but more to do with walking pages tables and the like -
> > remember that page tables are stored using physical addresses, and any
> > walks of them have to convert those physical addresses to virtual
> > addresses and back again.
> >
> > So, things like page scanning for eviction (eg, page aging, page
> > faults even those which just re-use a page from the page cache) have
> > to use the v:p / p:v translation macros.
> >
>
> Thanks, Russell. Any recommendations on how to best benchmark this?
Well, the benchmark issue can be side-stepped altogether. We know that
the assembly patching is the best thing that can be done, and we do have
most of it already.
As previously stated, the p2v patching may remain essentially identical
to what we have right now. Since the result is a 32-bit value, the
current code should just work.
On the v2p side, it's just a matter of adding two instructions around
the existing one (which should be turned into an adds). The first is a
mov to load the high bits of PHYS_OFFSET which are likely to be
representable with a simple immediate operand, and the third one would
be a simple adc with #0 which doesn't need any patching.
Nicolas
^ permalink raw reply
* [PATCH v4 02/13] ARM: LPAE: use phys_addr_t in alloc_init_pud()
From: Cyril Chemparathy @ 2013-02-01 17:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <510BFC84.2030902@gmail.com>
On 02/01/2013 12:33 PM, Subash Patel wrote:
> Hi Nicolas,
>
> On Thursday 31 January 2013 07:35 PM, Nicolas Pitre wrote:
>> On Fri, 1 Feb 2013, Hui Wang wrote:
>>
>>> Cyril Chemparathy wrote:
>>>> From: Vitaly Andrianov <vitalya@ti.com>
>>>>
>>>> This patch fixes the alloc_init_pud() function to use phys_addr_t
>>>> instead of
>>>> unsigned long when passing in the phys argument.
>>>>
>>>> This is an extension to commit 97092e0c56830457af0639f6bd904537a150ea4a
>>>> (ARM:
>>>> pgtable: use phys_addr_t for physical addresses), which applied similar
>>>> changes
>>>> elsewhere in the ARM memory management code.
>>>>
>>>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>>>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>>>> Acked-by: Nicolas Pitre <nico@linaro.org>
>>>> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
>>>> ---
>>>> arch/arm/mm/mmu.c | 3 ++-
>>>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
>>>> index 9f06102..ef43689 100644
>>>> --- a/arch/arm/mm/mmu.c
>>>> +++ b/arch/arm/mm/mmu.c
>>>> @@ -612,7 +612,8 @@ static void __init alloc_init_section(pud_t *pud,
>>>> unsigned long addr,
>>>> }
>>>> static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
>>>> - unsigned long end, unsigned long phys, const struct mem_type
>>>> *type)
>>>> + unsigned long end, phys_addr_t phys,
>>>> + const struct mem_type *type)
>>>>
>>> The change is correct but seems useless so far. This function only be
>>> called
>>> from map_lowmem and devicemaps_init, from i know neither lowmem nor
>>> device io
>>> registers of existing platforms exceed 32bit address.
>>
>> It is not because you are not aware of any existing platforms with RAM
>> or device IO above the 4GB mark that they don't exist.
>>
>> For example, some LPAE systems have all their RAM located above the 4G
>> physical address mark. A simple (potentially non DMA capable) alias
>> exists in the low 32-bit address space to allow the system to boot and
>> switch to the real physical RAM addresses once the MMU is turned on.
>> Some of that RAM is still qualified as "low mem" i.e. the portion of RAM
>> that the kernel keeps permanently mapped in the 32-bit virtual space
>> even if all of it is above the 4G mark in physical space.
>
> I think he is right. You cannot have low_mem and devices in 36-bit
> areas. Atleast this is what I saw in one of the platforms on which I
> tested these patches. I am not sure what you mean by hardware address
> aliasing(as I have real RAM), but we need 32-bit areas to boot the CPU
> and I have mapped them for the LOW_MEM. But, I have used 36-bit areas
> for the HIGH_MEM. Since you said about aliasing DDR area in 32-bits, and
> then switching to 36-bit RAM, does the dma of the devices still use
> 32-bit aliased addresses?
>
> I haven't tested a configuration where LOW_MEM can have both 32-bit and
> 36-bit DDR PA though. I think its not possible too.
>
On the KeyStone platform, memory is located at 08:0000:0000, i.e.,
outside the 32-bit addressable range. The hardware provides a limited
aliased map of the very same memory at 8000:0000, but this alias is
limited and intended only for boot time usage.
We boot the system while running out of this 32-bit physical address
range. We then switch over to the high physical address range fairly
early in the kernel boot, by rewriting boot-time page tables and the
TTBRs. Once this switch over has happened, lowmem is indeed outside the
32-bit physical address space.
Thanks
-- Cyril.
^ permalink raw reply
* [PATCH v2 19/27] pci: PCIe driver for Marvell Armada 370/XP systems
From: Stephen Warren @ 2013-02-01 17:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130201094613.38fa2ad0@skate>
On 02/01/2013 01:46 AM, Thomas Petazzoni wrote:
> Dear Stephen Warren,
>
> Thanks for this great discussion. I see that Jason has already answered
> most of the questions on the why we need this "dynamicity" in the window
> configuration. A few comments below.
>
> On Thu, 31 Jan 2013 19:21:02 -0700, Stephen Warren wrote:
>
>> So, the dynamic programming of the windows on Marvell HW is the exact
>> logical equivalent of programming a standard PCIe root port's BAR
>> registers. It makes perfect sense that should be dynamic. Presumably
>> this is something you can make work inside your emulated PCIe/PCIe
>> bridge module, simply by capturing writes to the BAR registers, and
>> translating them into writes to the Marvell window registers.
>
> That's what I'm doing. In the PATCHv2, my PCIe host driver was reading
> back the BARs in the PCI-to-PCI bridges configuration space, and was
> setting up the windows according to the addresses that had been
> assigned to each bridge.
>
> I am currently working in making this more dynamic: it is directly when
> the BAR is being written to in the PCI-to-PCI bridge configuration
> space that a window will be setup.
>
>> Now, I do have one follow-on question: You said you don't have 30
>> windows, but how many do you have free after allocating windows to any
>> other peripherals that need them, relative to (3 *
>> number-of-root-ports-in-the-SoC)? (3 being IO+Mem+PrefetchableMem.)
>
> We have 20 windows on Armada XP if I remember correctly, and they are
> not only used for PCIe, but also to map the BootROM (needed to boot
> secondary CPUs), to map SPI flashes or NOR flashes, for example. So
> they are really shared between many uses. In terms of PCIe, there are
> only two types of windows: I/O and Memory, there is no notion of
> Prefetchable Memory window as far as I could see.
In Tegra, we end up having separate MMIO vs. Prefetchable MMIO chunks of
our overall PCIe aperture. However, the HW setup appears the same for
both of those. I'm not sure if it's a bug in the driver, or if it's just
to separate the two address spaces so that the page tables can be
configured for those two regions with large rather than small
granularity. I need to go investigate that.
> We have up to 10 PCIe interfaces, and only 20 windows. It means that
> you basically can't use all PCIe interfaces, there will necessarily be
> some limit, due to the limited number of windows.
So there are 10 PCIe interfaces (root ports). That's on the SoC itself
right. Are all 10 (or a large number of them) actually used at once on
any given board design? I suppose this must be the case, or Marvell
wouldn't have wasted the silicon space on 10 root ports... Still, that's
a rather large number of ports!
If only a few PCIe ports are ever in use at once on a design and/or the
PCIe ports generally contain soldered-down devices rather than
user-accessible ports, the statically assigning window *IDs* to
individual ports would make for easier code in the driver, since the BAR
register emulation would never have to allocate/de-allocate windows, but
rather only ever have to enable/disable/configure them.
However, if many PCIe ports are in use at once and there are
user-accessible ports, you can't know ahead of time which ports will
need MMIO vs. MMIO prefetch vs. IO, so you'd have to dynamically
allocate window IDs to ports, in addition to dynamically setting up the
address/size of windows.
> Also, I'd like to point out that the dynamic configuration is needed
> for two reasons:
>
> * The number of windows, as we are discussing now.
OK.
> * The amount of physical address space available. If you don't
> dynamically configure those windows, then you have to account the
> "worst case", i.e the PCIe devices that require very large memory
> areas. So you end up creating static windows that reserve 32M or 64M
> or 128M *per* PCIe link. You can see that it "consumes" pretty
> quickly a large part of the 4G physical address space that we have.
> Thanks to the dynamic window configuration that we do with the
> PCI-to-PCI bridge, we can size the windows exactly the size needed
> by the downstream device on each PCIe interface.
That aspect is applicable to any PCIe system; there's always some chunk
of physical address space that maps to PCIe, and which must be divided
into per-root-port chunks.
I think the only difference on the Marvell HW is:
* The overall total size of the physical address space is dynamic rather
than fixed, because it's programmed through windows rather than
hard-coded into HW.
* Hence, the windows /both/ define the physical address space layout
/and/ define the routing of transactions to individual root ports. On
regular PCIe, the root port BARs only divide up the overall physical
(PCIe bus 0 really) address space and hence perform routing; they have
no influence over the CPU physical address space.
So I think the crux of the problem is that you really have 10 PCIe root
ports, each of which is a nominally a separate PCIe domain (since the
windows connect CPU physical address space to an individual/specific
root port's PCIe address space, rather than having separate connections
from CPU -> PCIe bus 0 address space, then BARs/windows connecting PCIe
bus 0 address space to individual root port/subordinate bus address
space), but you're attempting to treat all 10 ports as a single PCIe
domain so that you don't have to dedicate separate physical CPU address
space to each port, which you would have to do if they were actually
treated as separate domains.
>> The thing here is that when the PCIe core writes to a root port BAR
>> window to configure/enable it the first time, you'll need to capture
>> that transaction and dynamically allocate a window and program it in a
>> way equivalent to what the BAR register write would have achieved on
>> standard HW. Later, the window might need resizing, or even to be
>> completely disabled, if the PCIe core were to change the standard BAR
>> register. Dynamically allocating a window when the BAR is written
>> seems a little heavy-weight.
>
> Why?
Well, it's just a bunch more code; much more than a simple writel().
^ permalink raw reply
* [RFC PATCH] arm: decompressor: initialize PIC offset base register for uClinux tools
From: Nicolas Pitre @ 2013-02-01 18:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <510BF0B3.3030608@arm.com>
On Fri, 1 Feb 2013, Jonathan Austin wrote:
> Hi Nicolas, thanks for the comments,
>
> On 29/01/13 20:13, Nicolas Pitre wrote:
> > On Tue, 29 Jan 2013, Jonathan Austin wrote:
> >
> >> Before jumping to (position independent) C-code from the decompressor's
> >> assembler world we set-up the C environment. This setup currently does not
> >> set r9, which for arm-none-uclinux-uclibceabi should be the PIC offset base
> >> register (IE should point to the beginning of the GOT).
> >>
> >> Currently, therefore, in order to build working kernels that use the
> >> decompressor it is necessary to use an arm-linux-gnueabi toolchain, or
> >> similar. uClinux toolchains cause a Prefetch Abort to occur at the beginning
> >> of the decompress_kernel function.
> >>
> >> This patch allows uClinux toolchains to build bootable zImages by setting r9
> >> to the beginning of the GOT when __uClinux__ is defined, allowing the
> >> decompressor's C functions to work correctly.
> >>
> >> Signed-off-by: Jonathan Austin <jonathan.austin@arm.com>
> >> ---
> >>
> >> One other possibility would be to specify -mno-single-pic-base when building
> >> the decompressor. This works around the problem, but forces the compiler to
> >> generate less optimal code.
> >
> > How "less optimal"? How much bigger/slower is it?
> > If not significant enough then going with -mno-single-pic-base might be
> > fine.
>
> Code that needs to access anything global will need to derive the location
> of the GOT for itself, but there's a possible upside there that there's an
> extra free register (r9 can be used as a general purpose register...)
We try to minimize those in order to perform the easy relocation trick
which requires no reference to global initialized data. Hence this in
the linker script:
/DISCARD/ : {
*(.ARM.exidx*)
*(.ARM.extab*)
/*
* Discard any r/w data - this produces a link error if we have any,
* which is required for PIC decompression. Local data generates
* GOTOFF relocations, which prevents it being relocated independently
* of the text/got segments.
*/
*(.data)
}
> The patch would look like:
> -----8<-------
> diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
> index 5cad8a6..afed28e 100644
> --- a/arch/arm/boot/compressed/Makefile
> +++ b/arch/arm/boot/compressed/Makefile
> @@ -120,7 +120,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
> KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
> endif
> -ccflags-y := -fpic -fno-builtin -I$(obj)
> +ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
> asflags-y := -Wa,-march=all -DZIMAGE
> # Supply kernel BSS size to the decompressor via a linker symbol.
> ------>8---------
>
>
> I did a fairly crude benchmark - count how many instructions we need in
> order to finish decompressing the kernel...
>
> Setup r9 correctly: 129,976,282
> Use -mno-single-pic-base: 124,826,778
>
> (this was done using an R-class model and a magic semi-hosting call to pause
> the model at the end of the decompress_kernel function)
>
> So, it seems like the extra register means there's actually a 4% *win*
> in instruction terms from using -mno-single-pic-base
Looks like you have a winner.
Acked-by: Nicolas Pitre <nico@linaro.org>
> That said, I've still made some comments/amendments below...
>
> >
> >> arch/arm/boot/compressed/head.S | 4 ++++
> >> 1 file changed, 4 insertions(+)
> >>
> >> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> >> index fe4d9c3..4491e75 100644
> >> --- a/arch/arm/boot/compressed/head.S
> >> +++ b/arch/arm/boot/compressed/head.S
> >> @@ -410,6 +410,10 @@ wont_overwrite:
> >> * sp = stack pointer
> >> */
> >> orrs r1, r0, r5
> >> +#ifdef __uClinux__
> >> + mov r9, r11 @ PIC offset base register
> >> + addne r9, r9, r0 @ Also needs relocating
> >> +#endif
> >> beq not_relocated
> >
> > Please don't insert your code between the orrs and the beq as those two
> > go logically together.
>
> I'd initially done this in order to change only one site - as we need to
> set r9 and then add the offset I was using the condition code to test r0...
>
> However, this was silly - I think I can just do it in one instruction:
>
> add r9, r11, r0
>
> In the case that we're not relocated, r0 should be 0 anyway...
>
> >
> > In fact, the best location for this would probably be between the
> > wont_overwrite label and the comment that immediately follows it. And
> > then, those comments that follow until the branch into C code should be
> > updated accordingly.
>
>
> Okay, assuming I've understood you correctly, you're suggesting something
> like this:
>
> -----8<-------
>
> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index fe4d9c3..d81efbd 100644
> --- a/arch/arm/boot/compressed/head.S
> +++ b/arch/arm/boot/compressed/head.S
> @@ -396,6 +396,9 @@ dtb_check_done:
> mov pc, r0
> wont_overwrite:
> +#ifdef __uClinux__
> + add r9, r11, r0 @ uClinux PIC offset base register
> +#endif
> /*
> * If delta is zero, we are running at the address we were linked at.
> * r0 = delta
> @@ -405,6 +408,7 @@ wont_overwrite:
> * r5 = appended dtb size (0 if not present)
> * r7 = architecture ID
> * r8 = atags pointer
> + * r9 = GOT start (for uClinux ABI), relocated
> * r11 = GOT start
> * r12 = GOT end
> * sp = stack pointer
> @@ -470,6 +474,7 @@ not_relocated: mov r0, #0
> * r4 = kernel execution address
> * r7 = architecture ID
> * r8 = atags pointer
> + * r9 = GOT start (for uClinux ABI)
> */
> mov r0, r4
> mov r1, sp @ malloc space above stack
> ------->8-----------
Yes, that's what I was suggesting.
> The question that now occurs is whether we should just set r9 whether or not
> we're using a uClinux toolchain - I don't think it is going to hurt as the
> arm-linux-gnueabi world can happily clobber it with no bad consequences...
>
> But after all this, it seems that just using -mno-single-pic base as in the patch
> above is best...
Indeed. As longas this option is compatible with all toolchains.
Nicolas
^ permalink raw reply
* [PATCHv5 15/16] ARM: hyp: initialize CNTVOFF to zero
From: Dave Martin @ 2013-02-01 18:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130201114641.GB2094@e106331-lin.cambridge.arm.com>
On Fri, Feb 01, 2013 at 11:46:41AM +0000, Mark Rutland wrote:
> On Fri, Feb 01, 2013 at 11:13:50AM +0000, Dave Martin wrote:
> > On Thu, Jan 31, 2013 at 12:15:38PM +0000, Mark Rutland wrote:
> > > From: Marc Zyngier <Marc.Zyngier@arm.com>
> > >
> > > In order to be able to use the virtual counter in a safe way,
> > > make sure it is initialized to zero before dropping to SVC.
> > >
> > > Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> > > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > > Cc: Dave Martin <dave.martin@arm.com>
> > > ---
> > > arch/arm/kernel/hyp-stub.S | 3 +++
> > > 1 file changed, 3 insertions(+)
> > >
> > > diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
> > > index 65b2417..455603a 100644
> > > --- a/arch/arm/kernel/hyp-stub.S
> > > +++ b/arch/arm/kernel/hyp-stub.S
> > > @@ -152,6 +152,9 @@ THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE
> > > mrc p15, 4, r7, c14, c1, 0 @ CNTHCTL
> > > orr r7, r7, #3 @ PL1PCEN | PL1PCTEN
> > > mcr p15, 4, r7, c14, c1, 0 @ CNTHCTL
> > > + mov r6, #0
> > > + mov r7, #0
> > > + mcrr p15, 4, r6, r7, c14 @ CNTVOFF
> >
> > Is this required for safety, or is it more a sanity feature?
>
> This makes more sense with the next patch, which makes the arch_timer
> driver always use the virtual counters (to avoid indirection in the fast
> path and messy races with the setup of function pointers otherwise).
>
> It's required for safety when hyp mode is enabled, and the arch_timer
> driver uses the physical timers in combination with the virtual
> counters. Either the driver has to apply CNTVOFF manually when setting
> the physical timers, or the physical timers and virtual counters need
> the same view of time (i.e. CNTVOFF == 0).
>
> It also brings us in line with arm64, which always uses the virtual
> counter for its vDSO.
OK. This definitely sounds like the correct model.
>
> >
> > The architected timer counters are supposed to be monotonic time sources
> > only, so applying a random offset shouldn't really change anything.
>
> This is true except when we want to use the physical timers as described above.
>
> >
> > The main thing I can think of is that it is easier for the host to
> > manage guests' virtual counter offsets if the host's offset is 0 (and
> > we don't really want to be changing the host offset after the host kernel
> > boots).
>
> That's pretty much it. We don't want to have to further separate the handling
> of the timer for host and guest. By having CNTVOFF as zero for the host, we
> don't need to duplicate reading of the timers and/or incur an additional
> overhead on reading them.
That all sounds sensible. FWIW:
Reviewed-by: Dave Martin <dave.martin@linaro.org>
Cheers
---Dave
^ permalink raw reply
* [PATCH] arm: omap: Remove apollon board support
From: Tony Lindgren @ 2013-02-01 18:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50DDE0B2.60006@ti.com>
* Santosh Shilimkar <santosh.shilimkar@ti.com> [121228 10:12]:
> On Wednesday 26 December 2012 10:51 AM, Kyungmin Park wrote:
> >From: Kyungmin Park <kyungmin.park@samsung.com>
> >
> >As apollon board doesn't used anymore, remove it.
> >
> >Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> >---
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Thanks applying into omap-for-v3.9/board.
Regards,
Tony
^ permalink raw reply
* [PATCH v2] ARM: OMAP3: cm-t3517: add MMC support
From: Tony Lindgren @ 2013-02-01 18:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50FE845A.8090309@compulab.co.il>
* Igor Grinberg <grinberg@compulab.co.il> [130122 04:25]:
> ping!
>
> It has been 1.5 month and we are at rc4 already...
Sorry for the delay, applying finally into omap-for-v3.9/board.
Regards,
Tony
^ permalink raw reply
* [PATCH v4 02/13] ARM: LPAE: use phys_addr_t in alloc_init_pud()
From: Nicolas Pitre @ 2013-02-01 18:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <510BFC84.2030902@gmail.com>
On Fri, 1 Feb 2013, Subash Patel wrote:
> Hi Nicolas,
>
> On Thursday 31 January 2013 07:35 PM, Nicolas Pitre wrote:
> > On Fri, 1 Feb 2013, Hui Wang wrote:
> >
> > > Cyril Chemparathy wrote:
> > > > From: Vitaly Andrianov <vitalya@ti.com>
> > > >
> > > > This patch fixes the alloc_init_pud() function to use phys_addr_t
> > > > instead of
> > > > unsigned long when passing in the phys argument.
> > > >
> > > > This is an extension to commit 97092e0c56830457af0639f6bd904537a150ea4a
> > > > (ARM:
> > > > pgtable: use phys_addr_t for physical addresses), which applied similar
> > > > changes
> > > > elsewhere in the ARM memory management code.
> > > >
> > > > Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> > > > Signed-off-by: Cyril Chemparathy <cyril@ti.com>
> > > > Acked-by: Nicolas Pitre <nico@linaro.org>
> > > > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> > > > ---
> > > > arch/arm/mm/mmu.c | 3 ++-
> > > > 1 file changed, 2 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> > > > index 9f06102..ef43689 100644
> > > > --- a/arch/arm/mm/mmu.c
> > > > +++ b/arch/arm/mm/mmu.c
> > > > @@ -612,7 +612,8 @@ static void __init alloc_init_section(pud_t *pud,
> > > > unsigned long addr,
> > > > }
> > > > static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
> > > > - unsigned long end, unsigned long phys, const struct mem_type *type)
> > > > + unsigned long end, phys_addr_t phys,
> > > > + const struct mem_type *type)
> > > >
> > > The change is correct but seems useless so far. This function only be
> > > called
> > > from map_lowmem and devicemaps_init, from i know neither lowmem nor device
> > > io
> > > registers of existing platforms exceed 32bit address.
> >
> > It is not because you are not aware of any existing platforms with RAM
> > or device IO above the 4GB mark that they don't exist.
> >
> > For example, some LPAE systems have all their RAM located above the 4G
> > physical address mark. A simple (potentially non DMA capable) alias
> > exists in the low 32-bit address space to allow the system to boot and
> > switch to the real physical RAM addresses once the MMU is turned on.
> > Some of that RAM is still qualified as "low mem" i.e. the portion of RAM
> > that the kernel keeps permanently mapped in the 32-bit virtual space
> > even if all of it is above the 4G mark in physical space.
>
> I think he is right. You cannot have low_mem and devices in 36-bit areas.
> Atleast this is what I saw in one of the platforms on which I tested these
> patches. I am not sure what you mean by hardware address aliasing(as I have
> real RAM), but we need 32-bit areas to boot the CPU and I have mapped them for
> the LOW_MEM. But, I have used 36-bit areas for the HIGH_MEM. Since you said
> about aliasing DDR area in 32-bits, and then switching to 36-bit RAM, does the
> dma of the devices still use 32-bit aliased addresses?
>
> I haven't tested a configuration where LOW_MEM can have both 32-bit and 36-bit
> DDR PA though. I think its not possible too.
Don't get confused by the 36-bit supersections introduced with ARMv6.
This patch series is about LPAE capable systems using a completely
different page table format providing physical addressing beyond 36
bits.
Nicolas
^ permalink raw reply
* [RFC PATCH] arm: decompressor: initialize PIC offset base register for uClinux tools
From: Russell King - ARM Linux @ 2013-02-01 18:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <510BF0B3.3030608@arm.com>
On Fri, Feb 01, 2013 at 04:43:31PM +0000, Jonathan Austin wrote:
> Code that needs to access anything global will need to derive the location
> of the GOT for itself, but there's a possible upside there that there's an
> extra free register (r9 can be used as a general purpose register...)
>
> The patch would look like:
> -----8<-------
> diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
> index 5cad8a6..afed28e 100644
> --- a/arch/arm/boot/compressed/Makefile
> +++ b/arch/arm/boot/compressed/Makefile
> @@ -120,7 +120,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
> KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
> endif
> -ccflags-y := -fpic -fno-builtin -I$(obj)
> +ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
> asflags-y := -Wa,-march=all -DZIMAGE
> # Supply kernel BSS size to the decompressor via a linker symbol.
> ------>8---------
>
>
> I did a fairly crude benchmark - count how many instructions we need in
> order to finish decompressing the kernel...
>
> Setup r9 correctly: 129,976,282
> Use -mno-single-pic-base: 124,826,778
>
> (this was done using an R-class model and a magic semi-hosting call to pause
> the model at the end of the decompress_kernel function)
>
> So, it seems like the extra register means there's actually a 4% *win*
> in instruction terms from using -mno-single-pic-base
Hmm. This is the opposite of what I'd expect. -msingle-pic-base says:
Treat the register used for PIC addressing as read-only, rather
than loading it in the prologue for each function. The run-time
system is responsible for initializing this register with an
appropriate value before execution begins.
which implies that we should be able to load it before calling the C
code (as you're doing) and then the compiler won't issue instructions
to reload that register.
Giving -mno-single-pic-base suggests that it would turn _off_ this
behaviour (which afaik - sensibly - is not by default enabled.)
So, I'm not sure I fully understand what's going on here.
^ permalink raw reply
* [PATCH v7 00/10] DMA Engine support for AM33XX
From: Matt Porter @ 2013-02-01 18:22 UTC (permalink / raw)
To: linux-arm-kernel
Changes since v6:
- Converted edma_of_read_*() to wrappers around of_property_read_*()
- Fixed wording on the omap-spi generic DMA properties
- Added comment/check to clarify that the driver only supports
a single EDMA instance when booting from DT
Changes since v5:
- Dropped mmc portion and moved it to a separate series
- Incorporate corrected version of dma_request_slave_channel_compat()
- Fix #defines and enablement of TI_PRIV_EDMA option
Changes since v4:
- Fixed debug section mismatch in private edma api [01/14]
- Respun format-patch to catch the platform_data/edma.h rename [01/14]
- Removed address/size-cells from the EDMA binding [05/14]
Changes since v3:
- Rebased on 3.8-rc3
- No longer an RFC
- Fixed bugs in DT/pdata parsing reported by Vaibhav Bedia
- Restored all the Davinci pdata to const
- Removed max_segs hack in favor of using dma_get_channel_caps()
- Fixed extra parens, __raw_* accessors and, ioremap error checks
in xbar handling
- Removed excess license info in platform_data/edma.h
- Removed unneeded reserved channels data for AM33xx
- Removed test-specific pinmuxing from dts files
- Adjusted mmc1 node to be disabled by default in the dtsi
Changes since v2:
- Rebased on 3.7-rc1
- Fixed bug in DT/pdata parsing first found by Gururaja
that turned out to be masked by some toolchains
- Dropped unused mach-omap2/devices.c hsmmc patch
- Added AM33XX crossbar DMA event mux support
- Added am335x-evm support
Changes since v1:
- Rebased on top of mainline from 12250d8
- Dropped the feature removal schedule patch
- Implemented dma_request_slave_channel_compat() and
converted the mmc and spi drivers to use it
- Dropped unneeded #address-cells and #size-cells from
EDMA DT support
- Moved private EDMA header to linux/platform_data/ and
removed some unneeded definitions
- Fixed parsing of optional properties
This series adds DMA Engine support for AM33xx, which uses
an EDMA DMAC. The EDMA DMAC has been previously supported by only
a private API implementation (much like the situation with OMAP
DMA) found on the DaVinci family of SoCs.
The series applies on top of 3.8-rc5 and the following patches:
- dmaengine DT support and edma dmaengine driver fix from
the git://git.infradead.org/users/vkoul/slave-dma.git next
branch
The approach taken is similar to how OMAP DMA is being converted to
DMA Engine support. With the functional EDMA private API already
existing in mach-davinci/dma.c, we first move that to an ARM common
area so it can be shared. Adding DT and runtime PM support to the
private EDMA API implementation allows it to run on AM33xx. AM33xx
*only* boots using DT so we leverage Jon's generic DT DMA helpers to
register EDMA DMAC with the of_dma framework and then add support
for calling the dma_request_slave_channel() API to both the mmc
and spi drivers.
With this series both BeagleBone and the AM335x EVM have working
SPI DMA support (and MMC support with the separate MMC series).
This is tested on BeagleBone with a SPI framebuffer driver and MMC
rootfs. A trivial gpio DMA event misc driver was used to test the
crossbar DMA event support. It is also tested on the AM335x EVM
with the onboard SPI flash and MMC rootfs. The branch at
https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v7
has the complete series, dependencies, and some test
drivers/defconfigs. Note that MMC can only be tested with a
separate MMC dmaengine/DT series applied.
Regression testing was done on AM180x-EVM (which also makes use
of the EDMA dmaengine driver and the EDMA private API) using SD,
SPI flash, and the onboard audio supported by the ASoC Davinci
driver. Regression testing was also done on a BeagleBoard xM
booting from the legacy board file using MMC rootfs.
Matt Porter (10):
ARM: davinci: move private EDMA API to arm/common
ARM: edma: remove unused transfer controller handlers
ARM: edma: add AM33XX support to the private EDMA API
dmaengine: edma: enable build for AM33XX
dmaengine: edma: Add TI EDMA device tree binding
ARM: dts: add AM33XX EDMA support
dmaengine: add dma_request_slave_channel_compat()
spi: omap2-mcspi: convert to dma_request_slave_channel_compat()
spi: omap2-mcspi: add generic DMA request support to the DT binding
ARM: dts: add AM33XX SPI DMA support
Documentation/devicetree/bindings/dma/ti-edma.txt | 49 +++
Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +-
arch/arm/Kconfig | 1 +
arch/arm/boot/dts/am33xx.dtsi | 30 ++
arch/arm/common/Kconfig | 3 +
arch/arm/common/Makefile | 1 +
arch/arm/{mach-davinci/dma.c => common/edma.c} | 342 +++++++++++++++++---
arch/arm/mach-davinci/Makefile | 2 +-
arch/arm/mach-davinci/board-tnetv107x-evm.c | 2 +-
arch/arm/mach-davinci/davinci.h | 2 +-
arch/arm/mach-davinci/devices-tnetv107x.c | 2 +-
arch/arm/mach-davinci/devices.c | 6 +-
arch/arm/mach-davinci/dm355.c | 2 +-
arch/arm/mach-davinci/dm365.c | 2 +-
arch/arm/mach-davinci/dm644x.c | 2 +-
arch/arm/mach-davinci/dm646x.c | 2 +-
arch/arm/mach-davinci/include/mach/da8xx.h | 2 +-
arch/arm/plat-omap/Kconfig | 1 +
drivers/dma/Kconfig | 2 +-
drivers/dma/edma.c | 2 +-
drivers/mmc/host/davinci_mmc.c | 1 +
drivers/spi/spi-omap2-mcspi.c | 65 ++--
include/linux/dmaengine.h | 16 +
include/linux/mfd/davinci_voicecodec.h | 3 +-
.../mach => include/linux/platform_data}/edma.h | 90 +-----
include/linux/platform_data/spi-davinci.h | 2 +-
sound/soc/davinci/davinci-evm.c | 1 +
sound/soc/davinci/davinci-pcm.c | 1 +
sound/soc/davinci/davinci-pcm.h | 2 +-
sound/soc/davinci/davinci-sffsdr.c | 7 +-
30 files changed, 496 insertions(+), 174 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt
rename arch/arm/{mach-davinci/dma.c => common/edma.c} (86%)
rename {arch/arm/mach-davinci/include/mach => include/linux/platform_data}/edma.h (59%)
--
1.7.9.5
^ permalink raw reply
* [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
From: Matt Porter @ 2013-02-01 18:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359742975-10421-1-git-send-email-mporter@ti.com>
Move mach-davinci/dma.c to common/edma.c so it can be used
by OMAP (specifically AM33xx) as well.
Signed-off-by: Matt Porter <mporter@ti.com>
Acked-by: Sekhar Nori <nsekhar@ti.com>
---
arch/arm/Kconfig | 1 +
arch/arm/common/Kconfig | 3 +
arch/arm/common/Makefile | 1 +
arch/arm/{mach-davinci/dma.c => common/edma.c} | 209 +++++++++++++++++++-
arch/arm/mach-davinci/Makefile | 2 +-
arch/arm/mach-davinci/board-tnetv107x-evm.c | 2 +-
arch/arm/mach-davinci/davinci.h | 2 +-
arch/arm/mach-davinci/devices-tnetv107x.c | 2 +-
arch/arm/mach-davinci/devices.c | 6 +-
arch/arm/mach-davinci/dm355.c | 2 +-
arch/arm/mach-davinci/dm365.c | 2 +-
arch/arm/mach-davinci/dm644x.c | 2 +-
arch/arm/mach-davinci/dm646x.c | 2 +-
arch/arm/mach-davinci/include/mach/da8xx.h | 2 +-
drivers/dma/edma.c | 2 +-
drivers/mmc/host/davinci_mmc.c | 1 +
include/linux/mfd/davinci_voicecodec.h | 3 +-
.../mach => include/linux/platform_data}/edma.h | 89 +--------
include/linux/platform_data/spi-davinci.h | 2 +-
sound/soc/davinci/davinci-evm.c | 1 +
sound/soc/davinci/davinci-pcm.c | 1 +
sound/soc/davinci/davinci-pcm.h | 2 +-
sound/soc/davinci/davinci-sffsdr.c | 7 +-
23 files changed, 240 insertions(+), 106 deletions(-)
rename arch/arm/{mach-davinci/dma.c => common/edma.c} (90%)
rename {arch/arm/mach-davinci/include/mach => include/linux/platform_data}/edma.h (59%)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 67874b8..7637d31 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -932,6 +932,7 @@ config ARCH_DAVINCI
select GENERIC_IRQ_CHIP
select HAVE_IDE
select NEED_MACH_GPIO_H
+ select TI_PRIV_EDMA
select USE_OF
select ZONE_DMA
help
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 45ceeb0..9e32d0d 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -40,3 +40,6 @@ config SHARP_PARAM
config SHARP_SCOOP
bool
+
+config TI_PRIV_EDMA
+ bool
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index e8a4e58..d09a39b 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o
obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
+obj-$(CONFIG_TI_PRIV_EDMA) += edma.o
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/common/edma.c
similarity index 90%
rename from arch/arm/mach-davinci/dma.c
rename to arch/arm/common/edma.c
index a685e97..aa4a49a 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/common/edma.c
@@ -25,7 +25,7 @@
#include <linux/io.h>
#include <linux/slab.h>
-#include <mach/edma.h>
+#include <linux/platform_data/edma.h>
/* Offsets matching "struct edmacc_param" */
#define PARM_OPT 0x00
@@ -1386,8 +1386,213 @@ void edma_clear_event(unsigned channel)
EXPORT_SYMBOL(edma_clear_event);
/*-----------------------------------------------------------------------*/
+static int edma_of_read_u32_to_s8_array(const struct device_node *np,
+ const char *propname, s8 *out_values,
+ size_t sz)
+{
+ int ret;
+
+ ret = of_property_read_u8_array(np, propname, out_values, sz);
+ if (ret)
+ return ret;
+
+ /* Terminate it */
+ *out_values++ = -1;
+ *out_values++ = -1;
+
+ return 0;
+}
+
+static int edma_of_read_u32_to_s16_array(const struct device_node *np,
+ const char *propname, s16 *out_values,
+ size_t sz)
+{
+ int ret;
+
+ ret = of_property_read_u16_array(np, propname, out_values, sz);
+ if (ret)
+ return ret;
+
+ /* Terminate it */
+ *out_values++ = -1;
+ *out_values++ = -1;
+
+ return 0;
+}
+
+static int edma_xbar_event_map(struct device *dev,
+ struct device_node *node,
+ struct edma_soc_info *pdata, int len)
+{
+ int ret = 0;
+ int i;
+ struct resource res;
+ void *xbar;
+ const s16 (*xbar_chans)[2];
+ u32 shift, offset, mux;
+
+ xbar_chans = devm_kzalloc(dev,
+ len/sizeof(s16) + 2*sizeof(s16),
+ GFP_KERNEL);
+ if (!xbar_chans)
+ return -ENOMEM;
+
+ ret = of_address_to_resource(node, 1, &res);
+ if (IS_ERR_VALUE(ret))
+ return -EIO;
+
+ xbar = devm_ioremap(dev, res.start, resource_size(&res));
+ if (!xbar)
+ return -ENOMEM;
+
+ ret = edma_of_read_u32_to_s16_array(node,
+ "ti,edma-xbar-event-map",
+ (s16 *)xbar_chans,
+ len/sizeof(u32));
+ if (IS_ERR_VALUE(ret))
+ return -EIO;
+
+ for (i = 0; xbar_chans[i][0] != -1; i++) {
+ shift = (xbar_chans[i][1] % 4) * 8;
+ offset = xbar_chans[i][1] >> 2;
+ offset <<= 2;
+ mux = readl((void *)((u32)xbar + offset));
+ mux &= ~(0xff << shift);
+ mux |= xbar_chans[i][0] << shift;
+ writel(mux, (void *)((u32)xbar + offset));
+ }
+
+ pdata->xbar_chans = xbar_chans;
+
+ return 0;
+}
+
+static int edma_of_parse_dt(struct device *dev,
+ struct device_node *node,
+ struct edma_soc_info *pdata)
+{
+ int ret = 0;
+ u32 value;
+ struct property *prop;
+ size_t sz;
+ struct edma_rsv_info *rsv_info;
+ const s16 (*rsv_chans)[2], (*rsv_slots)[2];
+ const s8 (*queue_tc_map)[2], (*queue_priority_map)[2];
+
+ memset(pdata, 0, sizeof(struct edma_soc_info));
+
+ ret = of_property_read_u32(node, "dma-channels", &value);
+ if (ret < 0)
+ return ret;
+ pdata->n_channel = value;
+
+ ret = of_property_read_u32(node, "ti,edma-regions", &value);
+ if (ret < 0)
+ return ret;
+ pdata->n_region = value;
+
+ ret = of_property_read_u32(node, "ti,edma-slots", &value);
+ if (ret < 0)
+ return ret;
+ pdata->n_slot = value;
+
+ pdata->n_cc = 1;
+ pdata->n_tc = 3;
+
+ rsv_info =
+ devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL);
+ if (!rsv_info)
+ return -ENOMEM;
+ pdata->rsv = rsv_info;
+
+ /* Build the reserved channel/slots arrays */
+ prop = of_find_property(node, "ti,edma-reserved-channels", &sz);
+ if (prop) {
+ rsv_chans = devm_kzalloc(dev,
+ sz/sizeof(s16) + 2*sizeof(s16),
+ GFP_KERNEL);
+ if (!rsv_chans)
+ return -ENOMEM;
+ pdata->rsv->rsv_chans = rsv_chans;
+
+ ret = edma_of_read_u32_to_s16_array(node,
+ "ti,edma-reserved-channels",
+ (s16 *)rsv_chans,
+ sz/sizeof(u32));
+ if (ret < 0)
+ return ret;
+ }
+
+ prop = of_find_property(node, "ti,edma-reserved-slots", &sz);
+ if (prop) {
+ rsv_slots = devm_kzalloc(dev,
+ sz/sizeof(s16) + 2*sizeof(s16),
+ GFP_KERNEL);
+ if (!rsv_slots)
+ return -ENOMEM;
+ pdata->rsv->rsv_slots = rsv_slots;
+
+ ret = edma_of_read_u32_to_s16_array(node,
+ "ti,edma-reserved-slots",
+ (s16 *)rsv_slots,
+ sz/sizeof(u32));
+ if (ret < 0)
+ return ret;
+ }
+
+ prop = of_find_property(node, "ti,edma-queue-tc-map", &sz);
+ if (!prop)
+ return -EINVAL;
+
+ queue_tc_map = devm_kzalloc(dev,
+ sz/sizeof(s8) + 2*sizeof(s8),
+ GFP_KERNEL);
+ if (!queue_tc_map)
+ return -ENOMEM;
+ pdata->queue_tc_mapping = queue_tc_map;
+
+ ret = edma_of_read_u32_to_s8_array(node,
+ "ti,edma-queue-tc-map",
+ (s8 *)queue_tc_map,
+ sz/sizeof(u32));
+ if (ret < 0)
+ return ret;
+
+ prop = of_find_property(node, "ti,edma-queue-priority-map", &sz);
+ if (!prop)
+ return -EINVAL;
+
+ queue_priority_map = devm_kzalloc(dev,
+ sz/sizeof(s8) + 2*sizeof(s8),
+ GFP_KERNEL);
+ if (!queue_priority_map)
+ return -ENOMEM;
+ pdata->queue_priority_mapping = queue_priority_map;
+
+ ret = edma_of_read_u32_to_s8_array(node,
+ "ti,edma-queue-tc-map",
+ (s8 *)queue_priority_map,
+ sz/sizeof(u32));
+ if (ret < 0)
+ return ret;
+
+ ret = of_property_read_u32(node, "ti,edma-default-queue", &value);
+ if (ret < 0)
+ return ret;
+ pdata->default_queue = value;
+
+ prop = of_find_property(node, "ti,edma-xbar-event-map", &sz);
+ if (prop)
+ ret = edma_xbar_event_map(dev, node, pdata, sz);
+
+ return ret;
+}
+
+static struct of_dma_filter_info edma_filter_info = {
+ .filter_fn = edma_filter_fn,
+};
-static int __init edma_probe(struct platform_device *pdev)
+static int edma_probe(struct platform_device *pdev)
{
struct edma_soc_info **info = pdev->dev.platform_data;
const s8 (*queue_priority_mapping)[2];
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index fb5c1aa..493a36b 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -5,7 +5,7 @@
# Common objects
obj-y := time.o clock.o serial.o psc.o \
- dma.o usb.o common.o sram.o aemif.o
+ usb.o common.o sram.o aemif.o
obj-$(CONFIG_DAVINCI_MUX) += mux.o
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c
index be30997..86f55ba 100644
--- a/arch/arm/mach-davinci/board-tnetv107x-evm.c
+++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c
@@ -26,12 +26,12 @@
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
+#include <linux/platform_data/edma.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
#include <mach/irqs.h>
-#include <mach/edma.h>
#include <mach/mux.h>
#include <mach/cp_intc.h>
#include <mach/tnetv107x.h>
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index 12d544b..d26a6bc 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -23,9 +23,9 @@
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/davinci_asp.h>
+#include <linux/platform_data/edma.h>
#include <linux/platform_data/keyscan-davinci.h>
#include <mach/hardware.h>
-#include <mach/edma.h>
#include <media/davinci/vpfe_capture.h>
#include <media/davinci/vpif_types.h>
diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c
index 773ab07..ba37760 100644
--- a/arch/arm/mach-davinci/devices-tnetv107x.c
+++ b/arch/arm/mach-davinci/devices-tnetv107x.c
@@ -18,10 +18,10 @@
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/slab.h>
+#include <linux/platform_data/edma.h>
#include <mach/common.h>
#include <mach/irqs.h>
-#include <mach/edma.h>
#include <mach/tnetv107x.h>
#include "clock.h"
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 4c48a36..ca0c7b3 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -19,9 +19,10 @@
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/mux.h>
-#include <mach/edma.h>
#include <linux/platform_data/mmc-davinci.h>
#include <mach/time.h>
+#include <linux/platform_data/edma.h>
+
#include "davinci.h"
#include "clock.h"
@@ -34,6 +35,9 @@
#define DM365_MMCSD0_BASE 0x01D11000
#define DM365_MMCSD1_BASE 0x01D00000
+#define DAVINCI_DMA_MMCRXEVT 26
+#define DAVINCI_DMA_MMCTXEVT 27
+
void __iomem *davinci_sysmod_base;
void davinci_map_sysmod(void)
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index b49c3b7..53998d8 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -19,7 +19,6 @@
#include <asm/mach/map.h>
#include <mach/cputype.h>
-#include <mach/edma.h>
#include <mach/psc.h>
#include <mach/mux.h>
#include <mach/irqs.h>
@@ -28,6 +27,7 @@
#include <mach/common.h>
#include <linux/platform_data/spi-davinci.h>
#include <mach/gpio-davinci.h>
+#include <linux/platform_data/edma.h>
#include "davinci.h"
#include "clock.h"
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 6c39805..9b41d33 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -18,11 +18,11 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
+#include <linux/platform_data/edma.h>
#include <asm/mach/map.h>
#include <mach/cputype.h>
-#include <mach/edma.h>
#include <mach/psc.h>
#include <mach/mux.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 11c79a3..a08910e 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -12,11 +12,11 @@
#include <linux/clk.h>
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/edma.h>
#include <asm/mach/map.h>
#include <mach/cputype.h>
-#include <mach/edma.h>
#include <mach/irqs.h>
#include <mach/psc.h>
#include <mach/mux.h>
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index ac7b431..6d52a32 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -13,11 +13,11 @@
#include <linux/clk.h>
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/edma.h>
#include <asm/mach/map.h>
#include <mach/cputype.h>
-#include <mach/edma.h>
#include <mach/irqs.h>
#include <mach/psc.h>
#include <mach/mux.h>
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 700d311..9d77f9b 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -20,8 +20,8 @@
#include <linux/videodev2.h>
#include <mach/serial.h>
-#include <mach/edma.h>
#include <mach/pm.h>
+#include <linux/platform_data/edma.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 06ea4b8..9c7d16b 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <mach/edma.h>
+#include <linux/platform_data/edma.h>
#include "dmaengine.h"
#include "virt-dma.h"
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 2063677..f5d46ea 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -35,6 +35,7 @@
#include <linux/edma.h>
#include <linux/mmc/mmc.h>
+#include <linux/platform_data/edma.h>
#include <linux/platform_data/mmc-davinci.h>
/*
diff --git a/include/linux/mfd/davinci_voicecodec.h b/include/linux/mfd/davinci_voicecodec.h
index 0ab6132..7dd6524 100644
--- a/include/linux/mfd/davinci_voicecodec.h
+++ b/include/linux/mfd/davinci_voicecodec.h
@@ -26,8 +26,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/mfd/core.h>
-
-#include <mach/edma.h>
+#include <linux/platform_data/edma.h>
/*
* Register values.
diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/include/linux/platform_data/edma.h
similarity index 59%
rename from arch/arm/mach-davinci/include/mach/edma.h
rename to include/linux/platform_data/edma.h
index 7e84c90..2344ea2 100644
--- a/arch/arm/mach-davinci/include/mach/edma.h
+++ b/include/linux/platform_data/edma.h
@@ -1,28 +1,12 @@
/*
- * TI DAVINCI dma definitions
+ * TI EDMA definitions
*
- * Copyright (C) 2006-2009 Texas Instruments.
+ * Copyright (C) 2006-2013 Texas Instruments.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
*/
/*
@@ -69,11 +53,6 @@ struct edmacc_param {
unsigned int ccnt;
};
-#define CCINT0_INTERRUPT 16
-#define CCERRINT_INTERRUPT 17
-#define TCERRINT0_INTERRUPT 18
-#define TCERRINT1_INTERRUPT 19
-
/* fields in edmacc_param.opt */
#define SAM BIT(0)
#define DAM BIT(1)
@@ -87,70 +66,6 @@ struct edmacc_param {
#define TCCHEN BIT(22)
#define ITCCHEN BIT(23)
-#define TRWORD (0x7<<2)
-#define PAENTRY (0x1ff<<5)
-
-/* Drivers should avoid using these symbolic names for dm644x
- * channels, and use platform_device IORESOURCE_DMA resources
- * instead. (Other DaVinci chips have different peripherals
- * and thus have different DMA channel mappings.)
- */
-#define DAVINCI_DMA_MCBSP_TX 2
-#define DAVINCI_DMA_MCBSP_RX 3
-#define DAVINCI_DMA_VPSS_HIST 4
-#define DAVINCI_DMA_VPSS_H3A 5
-#define DAVINCI_DMA_VPSS_PRVU 6
-#define DAVINCI_DMA_VPSS_RSZ 7
-#define DAVINCI_DMA_IMCOP_IMXINT 8
-#define DAVINCI_DMA_IMCOP_VLCDINT 9
-#define DAVINCI_DMA_IMCO_PASQINT 10
-#define DAVINCI_DMA_IMCOP_DSQINT 11
-#define DAVINCI_DMA_SPI_SPIX 16
-#define DAVINCI_DMA_SPI_SPIR 17
-#define DAVINCI_DMA_UART0_URXEVT0 18
-#define DAVINCI_DMA_UART0_UTXEVT0 19
-#define DAVINCI_DMA_UART1_URXEVT1 20
-#define DAVINCI_DMA_UART1_UTXEVT1 21
-#define DAVINCI_DMA_UART2_URXEVT2 22
-#define DAVINCI_DMA_UART2_UTXEVT2 23
-#define DAVINCI_DMA_MEMSTK_MSEVT 24
-#define DAVINCI_DMA_MMCRXEVT 26
-#define DAVINCI_DMA_MMCTXEVT 27
-#define DAVINCI_DMA_I2C_ICREVT 28
-#define DAVINCI_DMA_I2C_ICXEVT 29
-#define DAVINCI_DMA_GPIO_GPINT0 32
-#define DAVINCI_DMA_GPIO_GPINT1 33
-#define DAVINCI_DMA_GPIO_GPINT2 34
-#define DAVINCI_DMA_GPIO_GPINT3 35
-#define DAVINCI_DMA_GPIO_GPINT4 36
-#define DAVINCI_DMA_GPIO_GPINT5 37
-#define DAVINCI_DMA_GPIO_GPINT6 38
-#define DAVINCI_DMA_GPIO_GPINT7 39
-#define DAVINCI_DMA_GPIO_GPBNKINT0 40
-#define DAVINCI_DMA_GPIO_GPBNKINT1 41
-#define DAVINCI_DMA_GPIO_GPBNKINT2 42
-#define DAVINCI_DMA_GPIO_GPBNKINT3 43
-#define DAVINCI_DMA_GPIO_GPBNKINT4 44
-#define DAVINCI_DMA_TIMER0_TINT0 48
-#define DAVINCI_DMA_TIMER1_TINT1 49
-#define DAVINCI_DMA_TIMER2_TINT2 50
-#define DAVINCI_DMA_TIMER3_TINT3 51
-#define DAVINCI_DMA_PWM0 52
-#define DAVINCI_DMA_PWM1 53
-#define DAVINCI_DMA_PWM2 54
-
-/* DA830 specific EDMA3 information */
-#define EDMA_DA830_NUM_DMACH 32
-#define EDMA_DA830_NUM_TCC 32
-#define EDMA_DA830_NUM_PARAMENTRY 128
-#define EDMA_DA830_NUM_EVQUE 2
-#define EDMA_DA830_NUM_TC 2
-#define EDMA_DA830_CHMAP_EXIST 0
-#define EDMA_DA830_NUM_REGIONS 4
-#define DA830_DMACH2EVENT_MAP0 0x000FC03Fu
-#define DA830_DMACH2EVENT_MAP1 0x00000000u
-#define DA830_EDMA_ARM_OWN 0x30FFCCFFu
-
/*ch_status paramater of callback function possible values*/
#define DMA_COMPLETE 1
#define DMA_CC_ERROR 2
diff --git a/include/linux/platform_data/spi-davinci.h b/include/linux/platform_data/spi-davinci.h
index 7af305b..8dc2fa47 100644
--- a/include/linux/platform_data/spi-davinci.h
+++ b/include/linux/platform_data/spi-davinci.h
@@ -19,7 +19,7 @@
#ifndef __ARCH_ARM_DAVINCI_SPI_H
#define __ARCH_ARM_DAVINCI_SPI_H
-#include <mach/edma.h>
+#include <linux/platform_data/edma.h>
#define SPI_INTERN_CS 0xFF
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index d55e647..591f547 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -14,6 +14,7 @@
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/edma.h>
#include <linux/i2c.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index afab81f..9bdd71b 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -17,6 +17,7 @@
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/genalloc.h>
+#include <linux/platform_data/edma.h>
#include <sound/core.h>
#include <sound/pcm.h>
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index b6ef703..fbb710c 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -14,7 +14,7 @@
#include <linux/genalloc.h>
#include <linux/platform_data/davinci_asp.h>
-#include <mach/edma.h>
+#include <linux/platform_data/edma.h>
struct davinci_pcm_dma_params {
int channel; /* sync dma channel ID */
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 5be65aa..a45af64 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -17,6 +17,7 @@
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/edma.h>
#include <linux/gpio.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -28,12 +29,14 @@
#include <asm/plat-sffsdr/sffsdr-fpga.h>
#endif
-#include <mach/edma.h>
#include "../codecs/pcm3008.h"
#include "davinci-pcm.h"
#include "davinci-i2s.h"
+#define DAVINCI_DMA_MCBSP_TX 2
+#define DAVINCI_DMA_MCBSP_RX 3
+
/*
* CLKX and CLKR are the inputs for the Sample Rate Generator.
* FSX and FSR are outputs, driven by the sample Rate Generator.
@@ -124,7 +127,7 @@ static struct resource sffsdr_snd_resources[] = {
static struct evm_snd_platform_data sffsdr_snd_data = {
.tx_dma_ch = DAVINCI_DMA_MCBSP_TX,
- .rx_dma_ch = DAVINCI_DMA_MCBSP_RX,
+ .rx_dma_ch = DAVINCI_DMA_MCBAP_RX,
};
static struct platform_device *sffsdr_snd_device;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v7 02/10] ARM: edma: remove unused transfer controller handlers
From: Matt Porter @ 2013-02-01 18:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359742975-10421-1-git-send-email-mporter@ti.com>
Fix build on OMAP, the irqs are undefined on AM33xx.
These error interrupt handlers were hardcoded as disabled
so since they are unused code, simply remove them.
Signed-off-by: Matt Porter <mporter@ti.com>
Acked-by: Sekhar Nori <nsekhar@ti.com>
---
arch/arm/common/edma.c | 37 -------------------------------------
1 file changed, 37 deletions(-)
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index aa4a49a..3440d16 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -494,26 +494,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
return IRQ_HANDLED;
}
-/******************************************************************************
- *
- * Transfer controller error interrupt handlers
- *
- *****************************************************************************/
-
-#define tc_errs_handled false /* disabled as long as they're NOPs */
-
-static irqreturn_t dma_tc0err_handler(int irq, void *data)
-{
- dev_dbg(data, "dma_tc0err_handler\n");
- return IRQ_HANDLED;
-}
-
-static irqreturn_t dma_tc1err_handler(int irq, void *data)
-{
- dev_dbg(data, "dma_tc1err_handler\n");
- return IRQ_HANDLED;
-}
-
static int reserve_contiguous_slots(int ctlr, unsigned int id,
unsigned int num_slots,
unsigned int start_slot)
@@ -1743,23 +1723,6 @@ static int edma_probe(struct platform_device *pdev)
arch_num_cc++;
}
- if (tc_errs_handled) {
- status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0,
- "edma_tc0", &pdev->dev);
- if (status < 0) {
- dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
- IRQ_TCERRINT0, status);
- return status;
- }
- status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0,
- "edma_tc1", &pdev->dev);
- if (status < 0) {
- dev_dbg(&pdev->dev, "request_irq %d --> %d\n",
- IRQ_TCERRINT, status);
- return status;
- }
- }
-
return 0;
fail:
--
1.7.9.5
^ permalink raw reply related
* [PATCH v7 03/10] ARM: edma: add AM33XX support to the private EDMA API
From: Matt Porter @ 2013-02-01 18:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359742975-10421-1-git-send-email-mporter@ti.com>
Adds support for parsing the TI EDMA DT data into the
required EDMA private API platform data. Enables runtime
PM support to initialize the EDMA hwmod. Adds AM33XX EDMA
crossbar event mux support. Enables build on OMAP.
Signed-off-by: Matt Porter <mporter@ti.com>
Acked-by: Sekhar Nori <nsekhar@ti.com>
---
arch/arm/common/edma.c | 96 ++++++++++++++++++++++++++++++++----
arch/arm/plat-omap/Kconfig | 1 +
include/linux/platform_data/edma.h | 1 +
3 files changed, 89 insertions(+), 9 deletions(-)
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 3440d16..bd2416a 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -24,6 +24,13 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/edma.h>
+#include <linux/err.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/pm_runtime.h>
#include <linux/platform_data/edma.h>
@@ -723,6 +730,9 @@ EXPORT_SYMBOL(edma_free_channel);
*/
int edma_alloc_slot(unsigned ctlr, int slot)
{
+ if (!edma_cc[ctlr])
+ return -EINVAL;
+
if (slot >= 0)
slot = EDMA_CHAN_SLOT(slot);
@@ -1575,27 +1585,69 @@ static struct of_dma_filter_info edma_filter_info = {
static int edma_probe(struct platform_device *pdev)
{
struct edma_soc_info **info = pdev->dev.platform_data;
+ struct edma_soc_info *ninfo[EDMA_MAX_CC] = {NULL, NULL};
+ struct edma_soc_info tmpinfo;
const s8 (*queue_priority_mapping)[2];
const s8 (*queue_tc_mapping)[2];
int i, j, off, ln, found = 0;
int status = -1;
const s16 (*rsv_chans)[2];
const s16 (*rsv_slots)[2];
+ const s16 (*xbar_chans)[2];
int irq[EDMA_MAX_CC] = {0, 0};
int err_irq[EDMA_MAX_CC] = {0, 0};
- struct resource *r[EDMA_MAX_CC] = {NULL};
+ struct resource *r[EDMA_MAX_CC] = {NULL, NULL};
+ struct resource res[EDMA_MAX_CC];
resource_size_t len[EDMA_MAX_CC];
char res_name[10];
char irq_name[10];
+ struct device_node *node = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ if (node) {
+ /* Check if this is a second instance registered */
+ if (arch_num_cc) {
+ dev_err(dev, "only one EDMA instance is supported via DT\n");
+ return -ENODEV;
+ }
+ info = ninfo;
+ edma_of_parse_dt(dev, node, &tmpinfo);
+ info[0] = &tmpinfo;
+
+ dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
+ of_dma_controller_register(dev->of_node,
+ of_dma_simple_xlate,
+ &edma_filter_info);
+ }
if (!info)
return -ENODEV;
+ pm_runtime_enable(dev);
+ ret = pm_runtime_get_sync(dev);
+ if (IS_ERR_VALUE(ret)) {
+ dev_err(dev, "pm_runtime_get_sync() failed\n");
+ return ret;
+ }
+
for (j = 0; j < EDMA_MAX_CC; j++) {
- sprintf(res_name, "edma_cc%d", j);
- r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ if (!info[j]) {
+ if (!found)
+ return -ENODEV;
+ break;
+ }
+ if (node) {
+ ret = of_address_to_resource(node, j, &res[j]);
+ if (!IS_ERR_VALUE(ret))
+ r[j] = &res[j];
+ } else {
+ sprintf(res_name, "edma_cc%d", j);
+ r[j] = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM,
res_name);
- if (!r[j] || !info[j]) {
+ }
+ if (!r[j]) {
if (found)
break;
else
@@ -1670,8 +1722,22 @@ static int edma_probe(struct platform_device *pdev)
}
}
- sprintf(irq_name, "edma%d", j);
- irq[j] = platform_get_irq_byname(pdev, irq_name);
+ /* Clear the xbar mapped channels in unused list */
+ xbar_chans = info[j]->xbar_chans;
+ if (xbar_chans) {
+ for (i = 0; xbar_chans[i][1] != -1; i++) {
+ off = xbar_chans[i][1];
+ clear_bits(off, 1,
+ edma_cc[j]->edma_unused);
+ }
+ }
+
+ if (node)
+ irq[j] = irq_of_parse_and_map(node, 0);
+ else {
+ sprintf(irq_name, "edma%d", j);
+ irq[j] = platform_get_irq_byname(pdev, irq_name);
+ }
edma_cc[j]->irq_res_start = irq[j];
status = request_irq(irq[j], dma_irq_handler, 0, "edma",
&pdev->dev);
@@ -1681,8 +1747,12 @@ static int edma_probe(struct platform_device *pdev)
goto fail;
}
- sprintf(irq_name, "edma%d_err", j);
- err_irq[j] = platform_get_irq_byname(pdev, irq_name);
+ if (node)
+ err_irq[j] = irq_of_parse_and_map(node, 2);
+ else {
+ sprintf(irq_name, "edma%d_err", j);
+ err_irq[j] = platform_get_irq_byname(pdev, irq_name);
+ }
edma_cc[j]->irq_res_end = err_irq[j];
status = request_irq(err_irq[j], dma_ccerr_handler, 0,
"edma_error", &pdev->dev);
@@ -1743,9 +1813,17 @@ fail1:
return status;
}
+static const struct of_device_id edma_of_ids[] = {
+ { .compatible = "ti,edma3", },
+ {}
+};
static struct platform_driver edma_driver = {
- .driver.name = "edma",
+ .driver = {
+ .name = "edma",
+ .of_match_table = edma_of_ids,
+ },
+ .probe = edma_probe,
};
static int __init edma_init(void)
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 665870d..0b81d6c 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -29,6 +29,7 @@ config ARCH_OMAP2PLUS
select PINCTRL
select PROC_DEVICETREE if PROC_FS
select SPARSE_IRQ
+ select TI_PRIV_EDMA
select USE_OF
help
"Systems based on OMAP2, OMAP3, OMAP4 or OMAP5"
diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h
index 2344ea2..ffc1fb2 100644
--- a/include/linux/platform_data/edma.h
+++ b/include/linux/platform_data/edma.h
@@ -177,6 +177,7 @@ struct edma_soc_info {
const s8 (*queue_tc_mapping)[2];
const s8 (*queue_priority_mapping)[2];
+ const s16 (*xbar_chans)[2];
};
#endif
--
1.7.9.5
^ permalink raw reply related
* [PATCH v7 04/10] dmaengine: edma: enable build for AM33XX
From: Matt Porter @ 2013-02-01 18:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359742975-10421-1-git-send-email-mporter@ti.com>
Enable TI EDMA option on OMAP.
Signed-off-by: Matt Porter <mporter@ti.com>
---
drivers/dma/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 0b408bb..239020b 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -220,7 +220,7 @@ config SIRF_DMA
config TI_EDMA
tristate "TI EDMA support"
- depends on ARCH_DAVINCI
+ depends on ARCH_DAVINCI || ARCH_OMAP
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
default n
--
1.7.9.5
^ permalink raw reply related
* [PATCH v7 05/10] dmaengine: edma: Add TI EDMA device tree binding
From: Matt Porter @ 2013-02-01 18:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359742975-10421-1-git-send-email-mporter@ti.com>
The binding definition is based on the generic DMA controller
binding.
Signed-off-by: Matt Porter <mporter@ti.com>
---
Documentation/devicetree/bindings/dma/ti-edma.txt | 49 +++++++++++++++++++++
1 file changed, 49 insertions(+)
create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt
diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt
new file mode 100644
index 0000000..075a60e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/ti-edma.txt
@@ -0,0 +1,49 @@
+TI EDMA
+
+Required properties:
+- compatible : "ti,edma3"
+- ti,hwmods: Name of the hwmods associated to the EDMA
+- ti,edma-regions: Number of regions
+- ti,edma-slots: Number of slots
+- ti,edma-queue-tc-map: List of transfer control to queue mappings
+- ti,edma-queue-priority-map: List of queue priority mappings
+- ti,edma-default-queue: Default queue value
+
+Optional properties:
+- ti,edma-reserved-channels: List of reserved channel regions
+- ti,edma-reserved-slots: List of reserved slot regions
+- ti,edma-xbar-event-map: Crossbar event to channel map
+
+Example:
+
+edma: edma at 49000000 {
+ reg = <0x49000000 0x10000>;
+ interrupt-parent = <&intc>;
+ interrupts = <12 13 14>;
+ compatible = "ti,edma3";
+ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
+ #dma-cells = <1>;
+ dma-channels = <64>;
+ ti,edma-regions = <4>;
+ ti,edma-slots = <256>;
+ ti,edma-reserved-channels = <0 2
+ 14 2
+ 26 6
+ 48 4
+ 56 8>;
+ ti,edma-reserved-slots = <0 2
+ 14 2
+ 26 6
+ 48 4
+ 56 8
+ 64 127>;
+ ti,edma-queue-tc-map = <0 0
+ 1 1
+ 2 2>;
+ ti,edma-queue-priority-map = <0 0
+ 1 1
+ 2 2>;
+ ti,edma-default-queue = <0>;
+ ti,edma-xbar-event-map = <1 12
+ 2 13>;
+};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v7 06/10] ARM: dts: add AM33XX EDMA support
From: Matt Porter @ 2013-02-01 18:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359742975-10421-1-git-send-email-mporter@ti.com>
Adds AM33XX EDMA support to the am33xx.dtsi as documented in
Documentation/devicetree/bindings/dma/ti-edma.txt
Signed-off-by: Matt Porter <mporter@ti.com>
---
arch/arm/boot/dts/am33xx.dtsi | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index c2f14e8..e711ffb 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -87,6 +87,26 @@
reg = <0x48200000 0x1000>;
};
+ edma: edma at 49000000 {
+ compatible = "ti,edma3";
+ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
+ reg = <0x49000000 0x10000>,
+ <0x44e10f90 0x10>;
+ interrupt-parent = <&intc>;
+ interrupts = <12 13 14>;
+ #dma-cells = <1>;
+ dma-channels = <64>;
+ ti,edma-regions = <4>;
+ ti,edma-slots = <256>;
+ ti,edma-queue-tc-map = <0 0
+ 1 1
+ 2 2>;
+ ti,edma-queue-priority-map = <0 0
+ 1 1
+ 2 2>;
+ ti,edma-default-queue = <0>;
+ };
+
gpio1: gpio at 44e07000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio1";
--
1.7.9.5
^ permalink raw reply related
* [PATCH v7 07/10] dmaengine: add dma_request_slave_channel_compat()
From: Matt Porter @ 2013-02-01 18:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359742975-10421-1-git-send-email-mporter@ti.com>
Adds a dma_request_slave_channel_compat() wrapper which accepts
both the arguments from dma_request_channel() and
dma_request_slave_channel(). Based on whether the driver is
instantiated via DT, the appropriate channel request call will be
made.
This allows for a much cleaner migration of drivers to the
dmaengine DT API as platforms continue to be mixed between those
that boot using DT and those that do not.
Suggested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Matt Porter <mporter@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
include/linux/dmaengine.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index bfcdecb..17d8ffd 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1001,6 +1001,22 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
struct dma_chan *net_dma_find_channel(void);
#define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
+#define dma_request_slave_channel_compat(mask, x, y, dev, name) \
+ __dma_request_slave_channel_compat(&(mask), x, y, dev, name)
+
+static inline struct dma_chan
+*__dma_request_slave_channel_compat(dma_cap_mask_t *mask, dma_filter_fn fn,
+ void *fn_param, struct device *dev,
+ char *name)
+{
+ struct dma_chan *chan;
+
+ chan = dma_request_slave_channel(dev, name);
+ if (chan)
+ return chan;
+
+ return __dma_request_channel(mask, fn, fn_param);
+}
/* --- Helper iov-locking functions --- */
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox