diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-11-27 17:34:48 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-11-27 17:34:48 -0800 |
commit | 7dcbe3014ffc969629a250b4c614a43856a585ea (patch) | |
tree | bfdb161ea7f0a950183986f97471af25d4eb12b8 | |
parent | 1bd70281f247105c3b07d8a2453858605f943537 (diff) | |
download | ltsi-kernel-7dcbe3014ffc969629a250b4c614a43856a585ea.tar.gz |
Altera patches
40 files changed, 4653 insertions, 0 deletions
diff --git a/patches.altera/0001-ARM-socfpga-dts-add-cpu1-start-addr-for-Arria-10.patch b/patches.altera/0001-ARM-socfpga-dts-add-cpu1-start-addr-for-Arria-10.patch new file mode 100644 index 00000000000000..53b07a149c714b --- /dev/null +++ b/patches.altera/0001-ARM-socfpga-dts-add-cpu1-start-addr-for-Arria-10.patch @@ -0,0 +1,27 @@ +From f456a6f437ae935f3849ee21f4c522745cfb53f2 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Mon, 9 Mar 2015 22:41:17 -0500 +Subject: [PATCH 01/39] ARM: socfpga: dts: add cpu1-start-addr for Arria 10 + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 6770a255b7650d574c5050c11f08cfeab5dfc498) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga_arria10.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index 8a05c47fd57f..69d616a05b14 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -284,6 +284,7 @@ + sysmgr: sysmgr@ffd06000 { + compatible = "altr,sys-mgr", "syscon"; + reg = <0xffd06000 0x300>; ++ cpu1-start-addr = <0xffd06230>; + }; + + /* Local timer */ +-- +2.6.2 + diff --git a/patches.altera/0002-ARM-socfpga-dts-disable-the-sdmmc-and-uart-nodes-in-.patch b/patches.altera/0002-ARM-socfpga-dts-disable-the-sdmmc-and-uart-nodes-in-.patch new file mode 100644 index 00000000000000..c48258e83cd6ec --- /dev/null +++ b/patches.altera/0002-ARM-socfpga-dts-disable-the-sdmmc-and-uart-nodes-in-.patch @@ -0,0 +1,47 @@ +From 3f654bb5a6966029388184f489f5c531c5949971 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Mon, 9 Mar 2015 23:05:21 -0500 +Subject: [PATCH 02/39] ARM: socfpga: dts: disable the sdmmc, and uart nodes in + the base arria10 + +Add status = "disabled" in the base DTSI for Arria10. The SDMMC and uart +nodes should be enabled in the appropriate board file. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry-picked from commit 1dfb7d2fd6a8f9c69f0b434473637d88917c9ec7) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga_arria10.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index 69d616a05b14..d8436095b1dd 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -268,6 +268,7 @@ + reg = <0xff808000 0x1000>; + interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>; + fifo-depth = <0x400>; ++ status = "disabled"; + }; + + ocram: sram@ffe00000 { +@@ -324,6 +325,7 @@ + interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; ++ status = "disabled"; + }; + + uart1: serial1@ffc02100 { +@@ -332,6 +334,7 @@ + interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; ++ status = "disabled"; + }; + + usbphy0: usbphy@0 { +-- +2.6.2 + diff --git a/patches.altera/0003-ARM-socfpga-dts-enable-UART1-for-the-debug-uart.patch b/patches.altera/0003-ARM-socfpga-dts-enable-UART1-for-the-debug-uart.patch new file mode 100644 index 00000000000000..7c20a5f3d9b824 --- /dev/null +++ b/patches.altera/0003-ARM-socfpga-dts-enable-UART1-for-the-debug-uart.patch @@ -0,0 +1,60 @@ +From 258a4abb89b030c45d155a98bb7b4a58669c6fa9 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Thu, 2 Apr 2015 13:26:35 -0500 +Subject: [PATCH 03/39] ARM: socfpga: dts: enable UART1 for the debug uart + +Arria10 devkit is using UART1 for the debug uart port. Remove +unused aliases. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry-picked from commit 74568da48f69c21c8628090eaedb990369813a0b) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga_arria10.dtsi | 12 ------------ + arch/arm/boot/dts/socfpga_arria10_socdk.dts | 8 ++++---- + 2 files changed, 4 insertions(+), 16 deletions(-) + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index d8436095b1dd..6c3ad9220845 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -21,18 +21,6 @@ + #address-cells = <1>; + #size-cells = <1>; + +- aliases { +- ethernet0 = &gmac0; +- ethernet1 = &gmac1; +- ethernet2 = &gmac2; +- serial0 = &uart0; +- serial1 = &uart1; +- timer0 = &timer0; +- timer1 = &timer1; +- timer2 = &timer2; +- timer3 = &timer3; +- }; +- + cpus { + #address-cells = <1>; + #size-cells = <0>; +diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk.dts b/arch/arm/boot/dts/socfpga_arria10_socdk.dts +index 3015ce8d3057..811a61cd9dc7 100755 +--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dts ++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dts +@@ -40,9 +40,9 @@ + }; + }; + }; +- +- serial0@ffc02000 { +- status = "okay"; +- }; + }; + }; ++ ++&uart1 { ++ status = "okay"; ++}; +-- +2.6.2 + diff --git a/patches.altera/0004-ARM-socfpga-dts-rename-socdk-board-file-to-socdk_sdm.patch b/patches.altera/0004-ARM-socfpga-dts-rename-socdk-board-file-to-socdk_sdm.patch new file mode 100644 index 00000000000000..1b29cfd6599883 --- /dev/null +++ b/patches.altera/0004-ARM-socfpga-dts-rename-socdk-board-file-to-socdk_sdm.patch @@ -0,0 +1,167 @@ +From 93ecd79aece107b9d152a9e344362833ed530b92 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Mon, 9 Mar 2015 22:57:04 -0500 +Subject: [PATCH 04/39] ARM: socfpga: dts: rename socdk board file to + socdk_sdmmc + +Rename the socfpga_arria10_socdk board file to socfpga_arria10_socdk_sdmmc +as Arria 10 devkit cannot support SDMMC and QSPI at the same time. Thus +we will need to have 2 separate board files, one for SDMMC and one for +QSPI. We also add a new base board dtsi file, socfpga_arria10_socdk.dtsi +so that we use common peripherals for each flavor of the devkits. + +Add the sdmmc node to the socfpga_arria10_socdk_sdmmc.dts board file. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 88c8e4c2648c9daa18430a47e746a669254f00e5) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/Makefile | 2 + arch/arm/boot/dts/socfpga_arria10_socdk.dts | 48 ---------------------- + arch/arm/boot/dts/socfpga_arria10_socdk.dtsi | 46 +++++++++++++++++++++ + arch/arm/boot/dts/socfpga_arria10_socdk_sdmmc.dts | 26 +++++++++++ + 4 files changed, 73 insertions(+), 49 deletions(-) + rename arch/arm/boot/dts/{socfpga_arria10_socdk.dts => socfpga_arria10_socdk.dtsi} (94%) + mode change 100755 => 100644 + create mode 100644 arch/arm/boot/dts/socfpga_arria10_socdk_sdmmc.dts + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -495,7 +495,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \ + sh73a0-kzm9g.dtb + dtb-$(CONFIG_ARCH_SOCFPGA) += \ + socfpga_arria5_socdk.dtb \ +- socfpga_arria10_socdk.dtb \ ++ socfpga_arria10_socdk_sdmmc.dtb \ + socfpga_cyclone5_socdk.dtb \ + socfpga_cyclone5_sockit.dtb \ + socfpga_cyclone5_socrates.dtb \ +--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dts ++++ /dev/null +@@ -1,48 +0,0 @@ +-/* +- * Copyright (C) 2014 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_arria10.dtsi" +- +-/ { +- model = "Altera SOCFPGA Arria 10"; +- compatible = "altr,socfpga-arria10", "altr,socfpga"; +- +- chosen { +- bootargs = "console=ttyS0,115200 rootwait"; +- }; +- +- memory { +- name = "memory"; +- device_type = "memory"; +- reg = <0x0 0x40000000>; /* 1GB */ +- }; +- +- soc { +- clkmgr@ffd04000 { +- clocks { +- osc1 { +- clock-frequency = <25000000>; +- }; +- }; +- }; +- }; +-}; +- +-&uart1 { +- status = "okay"; +-}; +--- /dev/null ++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (C) 2015 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/>. ++ */ ++#include "socfpga_arria10.dtsi" ++ ++/ { ++ model = "Altera SOCFPGA Arria 10"; ++ compatible = "altr,socfpga-arria10", "altr,socfpga"; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200 rootwait"; ++ }; ++ ++ memory { ++ name = "memory"; ++ device_type = "memory"; ++ reg = <0x0 0x40000000>; /* 1GB */ ++ }; ++ ++ soc { ++ clkmgr@ffd04000 { ++ clocks { ++ osc1 { ++ clock-frequency = <25000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; +--- /dev/null ++++ b/arch/arm/boot/dts/socfpga_arria10_socdk_sdmmc.dts +@@ -0,0 +1,26 @@ ++/* ++ * Copyright (C) 2014-2015 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_arria10_socdk.dtsi" ++ ++&mmc { ++ status = "okay"; ++ num-slots = <1>; ++ broken-cd; ++ bus-width = <4>; ++}; diff --git a/patches.altera/0005-ARM-socfpga-dts-Add-a-clock-node-for-sdmmc-CIU.patch b/patches.altera/0005-ARM-socfpga-dts-Add-a-clock-node-for-sdmmc-CIU.patch new file mode 100644 index 00000000000000..da9d097b616a2b --- /dev/null +++ b/patches.altera/0005-ARM-socfpga-dts-Add-a-clock-node-for-sdmmc-CIU.patch @@ -0,0 +1,48 @@ +From c7a3d89527c63e5432f5597579849372cb891ad7 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 10 Apr 2015 15:40:42 -0500 +Subject: [PATCH 05/39] ARM: socfpga: dts: Add a clock node for sdmmc CIU + +The CIU(Card Interface Unit) get its clock from the sdmmc_clk_divided clock +which is used to clock the card. The sdmmc_clk_divided clock is the sdmmc_clk +passed through a fixed divider of 4. This patch adds the sdmmc_clk_divided +node and makes the sdmmc_clk it's parent. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 5459f9abe24c810e09d012519788747e97b3cdd7) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga.dtsi | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi +index d9176e606173..be4beda11d3d 100644 +--- a/arch/arm/boot/dts/socfpga.dtsi ++++ b/arch/arm/boot/dts/socfpga.dtsi +@@ -451,6 +451,14 @@ + clk-phase = <0 135>; + }; + ++ sdmmc_clk_divided: sdmmc_clk_divided { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-gate-clk"; ++ clocks = <&sdmmc_clk>; ++ clk-gate = <0xa0 8>; ++ fixed-divider = <4>; ++ }; ++ + nand_x_clk: nand_x_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; +@@ -635,7 +643,7 @@ + fifo-depth = <0x400>; + #address-cells = <1>; + #size-cells = <0>; +- clocks = <&l4_mp_clk>, <&sdmmc_clk>; ++ clocks = <&l4_mp_clk>, <&sdmmc_clk_divided>; + clock-names = "biu", "ciu"; + }; + +-- +2.6.2 + diff --git a/patches.altera/0006-ARM-socfpga-dts-Add-multicast-bins-and-unicast-filte.patch b/patches.altera/0006-ARM-socfpga-dts-Add-multicast-bins-and-unicast-filte.patch new file mode 100644 index 00000000000000..bb8464af9922f3 --- /dev/null +++ b/patches.altera/0006-ARM-socfpga-dts-Add-multicast-bins-and-unicast-filte.patch @@ -0,0 +1,51 @@ +From deed2b628a9784142de80611c0bd8bbee09eb845 Mon Sep 17 00:00:00 2001 +From: Vince Bridgers <vbridger@opensource.altera.com> +Date: Tue, 21 Apr 2015 14:15:40 -0500 +Subject: [PATCH 06/39] ARM: socfpga: dts: Add multicast bins and unicast + filter entries + +Add multicast-filter-bins and perfect-filter-entries configuration properties +to the socfpga devicetree for the Arria 10 socfpga. + +Signed-off-by: Vince Bridgers <vbridger@opensource.altera.com> +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit be9863cac24b53e826ded959ae4747a6f388885f) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga_arria10.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index 6c3ad9220845..38c643d620c4 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -116,6 +116,8 @@ + interrupt-names = "macirq"; + /* Filled in by bootloader */ + mac-address = [00 00 00 00 00 00]; ++ snps,multicast-filter-bins = <256>; ++ snps,perfect-filter-entries = <128>; + status = "disabled"; + }; + +@@ -126,6 +128,8 @@ + interrupt-names = "macirq"; + /* Filled in by bootloader */ + mac-address = [00 00 00 00 00 00]; ++ snps,multicast-filter-bins = <256>; ++ snps,perfect-filter-entries = <128>; + status = "disabled"; + }; + +@@ -136,6 +140,8 @@ + interrupt-names = "macirq"; + /* Filled in by bootloader */ + mac-address = [00 00 00 00 00 00]; ++ snps,multicast-filter-bins = <256>; ++ snps,perfect-filter-entries = <128>; + status = "disabled"; + }; + +-- +2.6.2 + diff --git a/patches.altera/0007-ARM-socfpga-dts-Add-tx-fifo-depth-and-rx-fifo-depth-.patch b/patches.altera/0007-ARM-socfpga-dts-Add-tx-fifo-depth-and-rx-fifo-depth-.patch new file mode 100644 index 00000000000000..7c47e45d3ba274 --- /dev/null +++ b/patches.altera/0007-ARM-socfpga-dts-Add-tx-fifo-depth-and-rx-fifo-depth-.patch @@ -0,0 +1,66 @@ +From 0e850b693fdfd03b4dde6dcc229ca4fb42abd402 Mon Sep 17 00:00:00 2001 +From: Vince Bridgers <vbridger@opensource.altera.com> +Date: Tue, 21 Apr 2015 14:19:24 -0500 +Subject: [PATCH 07/39] ARM: socfpga: dts: Add tx-fifo-depth and rx-fifo-depth + properties + +Add tx-fifo-depth and rx-fifo-depth devicetree properties for socfpga +stmmac. These devicetree properties will be used to configure certain +features of the stmmac on the socfpga. + +Signed-off-by: Vince Bridgers <vbridger@opensource.altera.com> +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit c01e8cdb7bf52681530d1a6ac3474c070468983b) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga.dtsi | 4 ++++ + arch/arm/boot/dts/socfpga_arria10.dtsi | 4 ++++ + 2 files changed, 8 insertions(+) + +diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi +index be4beda11d3d..2e9ed36df12e 100644 +--- a/arch/arm/boot/dts/socfpga.dtsi ++++ b/arch/arm/boot/dts/socfpga.dtsi +@@ -496,6 +496,8 @@ + reset-names = "stmmaceth"; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <128>; ++ tx-fifo-depth = <4096>; ++ rx-fifo-depth = <4096>; + status = "disabled"; + }; + +@@ -512,6 +514,8 @@ + reset-names = "stmmaceth"; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <128>; ++ tx-fifo-depth = <4096>; ++ rx-fifo-depth = <4096>; + status = "disabled"; + }; + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index 38c643d620c4..ab0af2afdcf7 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -130,6 +130,8 @@ + mac-address = [00 00 00 00 00 00]; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <128>; ++ tx-fifo-depth = <4096>; ++ rx-fifo-depth = <16384>; + status = "disabled"; + }; + +@@ -142,6 +144,8 @@ + mac-address = [00 00 00 00 00 00]; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <128>; ++ tx-fifo-depth = <4096>; ++ rx-fifo-depth = <16384>; + status = "disabled"; + }; + +-- +2.6.2 + diff --git a/patches.altera/0008-ARM-socfpga-dts-add-clocks-to-the-Arria10-platform.patch b/patches.altera/0008-ARM-socfpga-dts-add-clocks-to-the-Arria10-platform.patch new file mode 100644 index 00000000000000..58ecf78354bb52 --- /dev/null +++ b/patches.altera/0008-ARM-socfpga-dts-add-clocks-to-the-Arria10-platform.patch @@ -0,0 +1,417 @@ +From bee6d610400e4cdad642e08945ac12aae29d7547 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Thu, 2 Apr 2015 11:43:20 -0500 +Subject: [PATCH 08/39] ARM: socfpga: dts: add clocks to the Arria10 platform + +Add all the clock nodes for the Arria10 platform. At the same time, update +the peripherals with their respective clocks property. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit da29d824a6709116dd4dc50b82400547447a4f53) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga_arria10.dtsi | 309 ++++++++++++++++++++++++++++++++- + 1 file changed, 305 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index ab0af2afdcf7..abf97630c592 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -86,6 +86,21 @@ + #address-cells = <1>; + #size-cells = <0>; + ++ cb_intosc_hs_div2_clk: cb_intosc_hs_div2_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ }; ++ ++ cb_intosc_ls_clk: cb_intosc_ls_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ }; ++ ++ f2s_free_clk: f2s_free_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ }; ++ + osc1: osc1 { + #clock-cells = <0>; + compatible = "fixed-clock"; +@@ -95,16 +110,286 @@ + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <0>; +- compatible = "altr,socfpga-pll-clock"; +- clocks = <&osc1>; ++ compatible = "altr,socfpga-a10-pll-clock"; ++ clocks = <&osc1>, <&cb_intosc_ls_clk>, ++ <&f2s_free_clk>; ++ reg = <0x40>; ++ ++ main_mpu_base_clk: main_mpu_base_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ div-reg = <0x140 0 11>; ++ }; ++ ++ main_noc_base_clk: main_noc_base_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ div-reg = <0x144 0 11>; ++ }; ++ ++ main_emaca_clk: main_emaca_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ reg = <0x68>; ++ }; ++ ++ main_emacb_clk: main_emacb_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ reg = <0x6C>; ++ }; ++ ++ main_emac_ptp_clk: main_emac_ptp_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ reg = <0x70>; ++ }; ++ ++ main_gpio_db_clk: main_gpio_db_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ reg = <0x74>; ++ }; ++ ++ main_sdmmc_clk: main_sdmmc_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk" ++; ++ clocks = <&main_pll>; ++ reg = <0x78>; ++ }; ++ ++ main_s2f_usr0_clk: main_s2f_usr0_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ reg = <0x7C>; ++ }; ++ ++ main_s2f_usr1_clk: main_s2f_usr1_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ reg = <0x80>; ++ }; ++ ++ main_hmc_pll_ref_clk: main_hmc_pll_ref_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ reg = <0x84>; ++ }; ++ ++ main_periph_ref_clk: main_periph_ref_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_pll>; ++ reg = <0x9C>; ++ }; + }; + + periph_pll: periph_pll { + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <0>; +- compatible = "altr,socfpga-pll-clock"; +- clocks = <&osc1>; ++ compatible = "altr,socfpga-a10-pll-clock"; ++ clocks = <&osc1>, <&cb_intosc_ls_clk>, ++ <&f2s_free_clk>, <&main_periph_ref_clk>; ++ reg = <0xC0>; ++ ++ peri_mpu_base_clk: peri_mpu_base_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ div-reg = <0x140 16 11>; ++ }; ++ ++ peri_noc_base_clk: peri_noc_base_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ div-reg = <0x144 16 11>; ++ }; ++ ++ peri_emaca_clk: peri_emaca_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ reg = <0xE8>; ++ }; ++ ++ peri_emacb_clk: peri_emacb_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ reg = <0xEC>; ++ }; ++ ++ peri_emac_ptp_clk: peri_emac_ptp_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ reg = <0xF0>; ++ }; ++ ++ peri_gpio_db_clk: peri_gpio_db_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ reg = <0xF4>; ++ }; ++ ++ peri_sdmmc_clk: peri_sdmmc_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ reg = <0xF8>; ++ }; ++ ++ peri_s2f_usr0_clk: peri_s2f_usr0_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ reg = <0xFC>; ++ }; ++ ++ peri_s2f_usr1_clk: peri_s2f_usr1_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ reg = <0x100>; ++ }; ++ ++ peri_hmc_pll_ref_clk: peri_hmc_pll_ref_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&periph_pll>; ++ reg = <0x104>; ++ }; ++ }; ++ ++ mpu_free_clk: mpu_free_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_mpu_base_clk>, <&peri_mpu_base_clk>, ++ <&osc1>, <&cb_intosc_hs_div2_clk>, ++ <&f2s_free_clk>; ++ reg = <0x60>; ++ }; ++ ++ noc_free_clk: noc_free_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_noc_base_clk>, <&peri_noc_base_clk>, ++ <&osc1>, <&cb_intosc_hs_div2_clk>, ++ <&f2s_free_clk>; ++ reg = <0x64>; ++ }; ++ ++ s2f_user1_free_clk: s2f_user1_free_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_s2f_usr1_clk>, <&peri_s2f_usr1_clk>, ++ <&osc1>, <&cb_intosc_hs_div2_clk>, ++ <&f2s_free_clk>; ++ reg = <0x104>; ++ }; ++ ++ sdmmc_free_clk: sdmmc_free_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&main_sdmmc_clk>, <&peri_sdmmc_clk>, ++ <&osc1>, <&cb_intosc_hs_div2_clk>, ++ <&f2s_free_clk>; ++ fixed-divider = <4>; ++ reg = <0xF8>; ++ }; ++ ++ l4_sys_free_clk: l4_sys_free_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-perip-clk"; ++ clocks = <&noc_free_clk>; ++ fixed-divider = <4>; ++ }; ++ ++ l4_main_clk: l4_main_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&noc_free_clk>; ++ div-reg = <0xA8 0 2>; ++ clk-gate = <0x48 1>; ++ }; ++ ++ l4_mp_clk: l4_mp_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&noc_free_clk>; ++ div-reg = <0xA8 8 2>; ++ clk-gate = <0x48 2>; ++ }; ++ ++ l4_sp_clk: l4_sp_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&noc_free_clk>; ++ div-reg = <0xA8 16 2>; ++ clk-gate = <0x48 3>; ++ }; ++ ++ mpu_periph_clk: mpu_periph_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&mpu_free_clk>; ++ fixed-divider = <4>; ++ clk-gate = <0x48 0>; ++ }; ++ ++ sdmmc_clk: sdmmc_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&sdmmc_free_clk>; ++ clk-gate = <0xC8 5>; ++ }; ++ ++ qspi_clk: qspi_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&l4_main_clk>; ++ clk-gate = <0xC8 11>; ++ }; ++ ++ nand_clk: nand_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&l4_mp_clk>; ++ clk-gate = <0xC8 10>; ++ }; ++ ++ spi_m_clk: spi_m_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&l4_main_clk>; ++ clk-gate = <0xC8 9>; ++ }; ++ ++ usb_clk: usb_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&l4_mp_clk>; ++ clk-gate = <0xC8 8>; ++ }; ++ ++ s2f_usr1_clk: s2f_usr1_clk { ++ #clock-cells = <0>; ++ compatible = "altr,socfpga-a10-gate-clk"; ++ clocks = <&peri_s2f_usr1_clk>; ++ clk-gate = <0xC8 6>; + }; + }; + }; +@@ -266,6 +551,8 @@ + reg = <0xff808000 0x1000>; + interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>; + fifo-depth = <0x400>; ++ clocks = <&l4_mp_clk>, <&sdmmc_free_clk>; ++ clock-names = "biu", "ciu"; + status = "disabled"; + }; + +@@ -291,30 +578,39 @@ + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xffffc600 0x100>; + interrupts = <1 13 0xf04>; ++ clocks = <&mpu_periph_clk>; + }; + + timer0: timer0@ffc02700 { + compatible = "snps,dw-apb-timer"; + interrupts = <0 115 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xffc02700 0x100>; ++ clocks = <&l4_sp_clk>; ++ clock-names = "timer"; + }; + + timer1: timer1@ffc02800 { + compatible = "snps,dw-apb-timer"; + interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xffc02800 0x100>; ++ clocks = <&l4_sp_clk>; ++ clock-names = "timer"; + }; + + timer2: timer2@ffd00000 { + compatible = "snps,dw-apb-timer"; + interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xffd00000 0x100>; ++ clocks = <&l4_sys_free_clk>; ++ clock-names = "timer"; + }; + + timer3: timer3@ffd00100 { + compatible = "snps,dw-apb-timer"; + interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xffd01000 0x100>; ++ clocks = <&l4_sys_free_clk>; ++ clock-names = "timer"; + }; + + uart0: serial0@ffc02000 { +@@ -332,6 +628,7 @@ + interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; ++ clocks = <&l4_sp_clk>; + status = "disabled"; + }; + +@@ -345,6 +642,8 @@ + compatible = "snps,dwc2"; + reg = <0xffb00000 0xffff>; + interrupts = <0 95 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&usb_clk>; ++ clock-names = "otg"; + phys = <&usbphy0>; + phy-names = "usb2-phy"; + status = "disabled"; +@@ -363,6 +662,7 @@ + compatible = "snps,dw-wdt"; + reg = <0xffd00200 0x100>; + interrupts = <0 119 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&l4_sys_free_clk>; + status = "disabled"; + }; + +@@ -370,6 +670,7 @@ + compatible = "snps,dw-wdt"; + reg = <0xffd00300 0x100>; + interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&l4_sys_free_clk>; + status = "disabled"; + }; + }; +-- +2.6.2 + diff --git a/patches.altera/0009-ARM-socfpga-Add-support-for-UART1-debug-uart-for-ear.patch b/patches.altera/0009-ARM-socfpga-Add-support-for-UART1-debug-uart-for-ear.patch new file mode 100644 index 00000000000000..733fb745b94545 --- /dev/null +++ b/patches.altera/0009-ARM-socfpga-Add-support-for-UART1-debug-uart-for-ear.patch @@ -0,0 +1,80 @@ +From 9fb7d95533b91b8910f2db18fcf15b25a6a411e4 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Mon, 9 Mar 2015 15:48:31 -0500 +Subject: [PATCH 09/39] ARM: socfpga: Add support for UART1 debug uart for + earlyprintk + +Add support for hardware uart1 for earlyprintk support on Arria10 devkit. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit de73c162fc2e91e19b7716fc9c0150f759be2567) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/Kconfig.debug | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug +index 0c12ffb155a2..7ed976a719b3 100644 +--- a/arch/arm/Kconfig.debug ++++ b/arch/arm/Kconfig.debug +@@ -908,13 +908,22 @@ choice + on SA-11x0 UART ports. The kernel will check for the first + enabled UART in a sequence 3-1-2. + +- config DEBUG_SOCFPGA_UART ++ config DEBUG_SOCFPGA_UART0 + depends on ARCH_SOCFPGA +- bool "Use SOCFPGA UART for low-level debug" ++ bool "Use SOCFPGA UART0 for low-level debug" + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support +- on SOCFPGA based platforms. ++ on SOCFPGA(Cyclone 5 and Arria 5) based platforms. ++ ++ config DEBUG_SOCFPGA_UART1 ++ depends on ARCH_SOCFPGA ++ bool "Use SOCFPGA UART1 for low-level debug" ++ select DEBUG_UART_8250 ++ help ++ Say Y here if you want kernel low-level debugging support ++ on SOCFPGA(Arria 10) based platforms. ++ + + config DEBUG_SUN9I_UART0 + bool "Kernel low-level debugging messages via sun9i UART0" +@@ -1407,7 +1416,8 @@ config DEBUG_UART_PHYS + default 0xfd883000 if DEBUG_ALPINE_UART0 + default 0xfe800000 if ARCH_IOP32X + default 0xff690000 if DEBUG_RK32_UART2 +- default 0xffc02000 if DEBUG_SOCFPGA_UART ++ default 0xffc02000 if DEBUG_SOCFPGA_UART0 ++ default 0xffc02100 if DEBUG_SOCFPGA_UART1 + default 0xffd82340 if ARCH_IOP13XX + default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0 + default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2 +@@ -1485,7 +1495,8 @@ config DEBUG_UART_VIRT + default 0xfeb26000 if DEBUG_RK3X_UART1 + default 0xfeb30c00 if DEBUG_KEYSTONE_UART0 + default 0xfeb31000 if DEBUG_KEYSTONE_UART1 +- default 0xfec02000 if DEBUG_SOCFPGA_UART ++ default 0xfec02000 if DEBUG_SOCFPGA_UART0 ++ default 0xfec02100 if DEBUG_SOCFPGA_UART1 + default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE + default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE + default 0xfec10000 if DEBUG_SIRFATLAS7_UART0 +@@ -1530,8 +1541,9 @@ config DEBUG_UART_8250_WORD + bool "Use 32-bit accesses for 8250 UART" + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + depends on DEBUG_UART_8250_SHIFT >= 2 +- default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \ +- ARCH_KEYSTONE || DEBUG_ALPINE_UART0 || \ ++ default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART0 || \ ++ DEBUG_SOCFPGA_UART1 || ARCH_KEYSTONE || \ ++ DEBUG_ALPINE_UART0 || \ + DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ + DEBUG_DAVINCI_DA8XX_UART2 || \ + DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \ +-- +2.6.2 + diff --git a/patches.altera/0010-ARM-socfpga-remove-the-need-to-map-uart_io_desc.patch b/patches.altera/0010-ARM-socfpga-remove-the-need-to-map-uart_io_desc.patch new file mode 100644 index 00000000000000..5c3af2eecb7003 --- /dev/null +++ b/patches.altera/0010-ARM-socfpga-remove-the-need-to-map-uart_io_desc.patch @@ -0,0 +1,45 @@ +From a121e113b664c4eb6e11dd0fc5d562b5e892930f Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Mon, 9 Mar 2015 22:10:02 -0500 +Subject: [PATCH 10/39] ARM: socfpga: remove the need to map uart_io_desc + +All the necessary debug uart mapping is already being done in +debug_ll_io_init, there's no need for it here. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 65ce7a37ec23c9e7878bd77e2f75b1eb9d8926e3) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/mach-socfpga/socfpga.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c +index f5e597c207b9..358f2c712979 100644 +--- a/arch/arm/mach-socfpga/socfpga.c ++++ b/arch/arm/mach-socfpga/socfpga.c +@@ -39,13 +39,6 @@ static struct map_desc scu_io_desc __initdata = { + .type = MT_DEVICE, + }; + +-static struct map_desc uart_io_desc __initdata = { +- .virtual = 0xfec02000, +- .pfn = __phys_to_pfn(0xffc02000), +- .length = SZ_8K, +- .type = MT_DEVICE, +-}; +- + static void __init socfpga_scu_map_io(void) + { + unsigned long base; +@@ -60,8 +53,6 @@ static void __init socfpga_scu_map_io(void) + static void __init socfpga_map_io(void) + { + socfpga_scu_map_io(); +- iotable_init(&uart_io_desc, 1); +- early_printk("Early printk initialized\n"); + } + + void __init socfpga_sysmgr_init(void) +-- +2.6.2 + diff --git a/patches.altera/0011-ARM-socfpga-dts-add-the-a9-scu-node.patch b/patches.altera/0011-ARM-socfpga-dts-add-the-a9-scu-node.patch new file mode 100644 index 00000000000000..2b3e2290fdf6ea --- /dev/null +++ b/patches.altera/0011-ARM-socfpga-dts-add-the-a9-scu-node.patch @@ -0,0 +1,33 @@ +From 94947b77f52bf8b37621bf91123907c3cfaf4fa6 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Tue, 12 May 2015 15:48:13 -0500 +Subject: [PATCH 11/39] ARM: socfpga: dts: add the a9-scu node + +Add the dts node for the A9 SCU. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 8508452e57f7d50216338c28db6d42dfe585389a) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi +index 2e9ed36df12e..9b653edd003f 100644 +--- a/arch/arm/boot/dts/socfpga.dtsi ++++ b/arch/arm/boot/dts/socfpga.dtsi +@@ -667,6 +667,11 @@ + status = "disabled"; + }; + ++ scu: snoop-control-unit@fffec000 { ++ compatible = "arm,cortex-a9-scu"; ++ reg = <0xfffec000 0x100>; ++ }; ++ + spi1: spi@fff01000 { + compatible = "snps,dw-apb-ssi"; + #address-cells = <1>; +-- +2.6.2 + diff --git a/patches.altera/0012-ARM-socfpga-use-of_iomap-to-map-the-SCU.patch b/patches.altera/0012-ARM-socfpga-use-of_iomap-to-map-the-SCU.patch new file mode 100644 index 00000000000000..f23ab91db1fa2b --- /dev/null +++ b/patches.altera/0012-ARM-socfpga-use-of_iomap-to-map-the-SCU.patch @@ -0,0 +1,129 @@ +From 7d6b3c462a19dda153de86d2ccc5805ad7f47443 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Tue, 12 May 2015 16:49:21 -0500 +Subject: [PATCH 12/39] ARM: socfpga: use of_iomap to map the SCU + +Use of_iomap to map the "arm,cortex-a9-scu". By doing this, we can remove +map_io in socfpga.c. + +Also, we can remove socfpga_smp_init_cpus, as arm_dt_init_cpu_maps is +already doing the CPU mapping. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 122694a0c71281cf2b349af41309c3caf5f31d61) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/mach-socfpga/core.h | 2 -- + arch/arm/mach-socfpga/platsmp.c | 33 ++++++++++----------------------- + arch/arm/mach-socfpga/socfpga.c | 25 ------------------------- + 3 files changed, 10 insertions(+), 50 deletions(-) + +--- a/arch/arm/mach-socfpga/core.h ++++ b/arch/arm/mach-socfpga/core.h +@@ -31,8 +31,6 @@ + + #define RSTMGR_MPUMODRST_CPU1 0x2 /* CPU1 Reset */ + +-extern void __iomem *socfpga_scu_base_addr; +- + extern void socfpga_init_clocks(void); + extern void socfpga_sysmgr_init(void); + +--- a/arch/arm/mach-socfpga/platsmp.c ++++ b/arch/arm/mach-socfpga/platsmp.c +@@ -54,32 +54,20 @@ static int socfpga_boot_secondary(unsign + return 0; + } + +-/* +- * Initialise the CPU possible map early - this describes the CPUs +- * which may be present or become present in the system. +- */ +-static void __init socfpga_smp_init_cpus(void) ++static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) + { +- unsigned int i, ncores; +- +- ncores = scu_get_core_count(socfpga_scu_base_addr); +- +- for (i = 0; i < ncores; i++) +- set_cpu_possible(i, true); ++ struct device_node *np; ++ void __iomem *socfpga_scu_base_addr; + +- /* sanity check */ +- if (ncores > num_possible_cpus()) { +- pr_warn("socfpga: no. of cores (%d) greater than configured" +- "maximum of %d - clipping\n", ncores, num_possible_cpus()); +- ncores = num_possible_cpus(); ++ np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); ++ if (!np) { ++ pr_err("%s: missing scu\n", __func__); ++ return; + } + +- for (i = 0; i < ncores; i++) +- set_cpu_possible(i, true); +-} +- +-static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) +-{ ++ socfpga_scu_base_addr = of_iomap(np, 0); ++ if (!socfpga_scu_base_addr) ++ return; + scu_enable(socfpga_scu_base_addr); + } + +@@ -96,7 +84,6 @@ static void socfpga_cpu_die(unsigned int + } + + struct smp_operations socfpga_smp_ops __initdata = { +- .smp_init_cpus = socfpga_smp_init_cpus, + .smp_prepare_cpus = socfpga_smp_prepare_cpus, + .smp_boot_secondary = socfpga_boot_secondary, + #ifdef CONFIG_HOTPLUG_CPU +--- a/arch/arm/mach-socfpga/socfpga.c ++++ b/arch/arm/mach-socfpga/socfpga.c +@@ -27,34 +27,10 @@ + + #include "core.h" + +-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 socfpga_cpu1start_addr; + +-static struct map_desc scu_io_desc __initdata = { +- .virtual = SOCFPGA_SCU_VIRT_BASE, +- .pfn = 0, /* run-time */ +- .length = SZ_8K, +- .type = MT_DEVICE, +-}; +- +-static void __init socfpga_scu_map_io(void) +-{ +- unsigned long base; +- +- /* Get SCU base */ +- asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base)); +- +- scu_io_desc.pfn = __phys_to_pfn(base); +- iotable_init(&scu_io_desc, 1); +-} +- +-static void __init socfpga_map_io(void) +-{ +- socfpga_scu_map_io(); +-} +- + void __init socfpga_sysmgr_init(void) + { + struct device_node *np; +@@ -103,7 +79,6 @@ DT_MACHINE_START(SOCFPGA, "Altera SOCFPG + .l2c_aux_val = 0, + .l2c_aux_mask = ~0, + .smp = smp_ops(socfpga_smp_ops), +- .map_io = socfpga_map_io, + .init_irq = socfpga_init_irq, + .restart = socfpga_cyclone5_restart, + .dt_compat = altera_dt_match, diff --git a/patches.altera/0013-clk-socfpga-update-clk.h-so-for-Arria10-platform-to-.patch b/patches.altera/0013-clk-socfpga-update-clk.h-so-for-Arria10-platform-to-.patch new file mode 100644 index 00000000000000..e4337db46f111d --- /dev/null +++ b/patches.altera/0013-clk-socfpga-update-clk.h-so-for-Arria10-platform-to-.patch @@ -0,0 +1,60 @@ +From 802a04ce9dfe11e78a5aa6fb5389d7c5f935a33f Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Tue, 19 May 2015 22:22:41 -0500 +Subject: [PATCH 13/39] clk: socfpga: update clk.h so for Arria10 platform to + use + +There are 5 possible parent clocks for the SoCFPGA Arria10. Move the define +SYSMGR_SDMMC_CTRL_SET and streq() to clk.h so that the Arria clock driver +can use. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +(cherry picked from commit 5611a5ba8e5435740df99235b262b553f687b13b) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/clk/socfpga/clk-gate.c | 4 ---- + drivers/clk/socfpga/clk.h | 6 +++++- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c +index dd3a78c64795..607ab352f73c 100644 +--- a/drivers/clk/socfpga/clk-gate.c ++++ b/drivers/clk/socfpga/clk-gate.c +@@ -32,14 +32,10 @@ + #define SOCFPGA_MMC_CLK "sdmmc_clk" + #define SOCFPGA_GPIO_DB_CLK_OFFSET 0xA8 + +-#define streq(a, b) (strcmp((a), (b)) == 0) +- + #define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw) + + /* SDMMC Group for System Manager defines */ + #define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x108 +-#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ +- ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0)) + + static u8 socfpga_clk_get_parent(struct clk_hw *hwclk) + { +diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h +index d291f60c46e1..b09a5d50547e 100644 +--- a/drivers/clk/socfpga/clk.h ++++ b/drivers/clk/socfpga/clk.h +@@ -26,9 +26,13 @@ + #define CLKMGR_L4SRC 0x70 + #define CLKMGR_PERPLL_SRC 0xAC + +-#define SOCFPGA_MAX_PARENTS 3 ++#define SOCFPGA_MAX_PARENTS 5 + #define div_mask(width) ((1 << (width)) - 1) + ++#define streq(a, b) (strcmp((a), (b)) == 0) ++#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ ++ ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0)) ++ + extern void __iomem *clk_mgr_base_addr; + + void __init socfpga_pll_init(struct device_node *node); +-- +2.6.2 + diff --git a/patches.altera/0014-clk-socfpga-add-a-clock-driver-for-the-Arria-10-plat.patch b/patches.altera/0014-clk-socfpga-add-a-clock-driver-for-the-Arria-10-plat.patch new file mode 100644 index 00000000000000..ecafd3c91993d0 --- /dev/null +++ b/patches.altera/0014-clk-socfpga-add-a-clock-driver-for-the-Arria-10-plat.patch @@ -0,0 +1,555 @@ +From 908c56457c90fd483edd9ec76081415b10486711 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Tue, 19 May 2015 22:22:42 -0500 +Subject: [PATCH 14/39] clk: socfpga: add a clock driver for the Arria 10 + platform + +The clocks on the Arria 10 platform is a bit different than the +Cyclone/Arria 5 platform that it should just have it's own +driver. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +(cherry picked from commit 5343325ff3dd299f459fa9dacbd95dca5c9bf215) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/clk/socfpga/Makefile | 1 + + drivers/clk/socfpga/clk-gate-a10.c | 190 +++++++++++++++++++++++++++++++++++ + drivers/clk/socfpga/clk-periph-a10.c | 138 +++++++++++++++++++++++++ + drivers/clk/socfpga/clk-pll-a10.c | 129 ++++++++++++++++++++++++ + drivers/clk/socfpga/clk.c | 7 +- + drivers/clk/socfpga/clk.h | 5 + + 6 files changed, 469 insertions(+), 1 deletion(-) + create mode 100644 drivers/clk/socfpga/clk-gate-a10.c + create mode 100644 drivers/clk/socfpga/clk-periph-a10.c + create mode 100644 drivers/clk/socfpga/clk-pll-a10.c + +diff --git a/drivers/clk/socfpga/Makefile b/drivers/clk/socfpga/Makefile +index 7e2d15a0c7b8..d8bb239753a4 100644 +--- a/drivers/clk/socfpga/Makefile ++++ b/drivers/clk/socfpga/Makefile +@@ -2,3 +2,4 @@ obj-y += clk.o + obj-y += clk-gate.o + obj-y += clk-pll.o + obj-y += clk-periph.o ++obj-y += clk-pll-a10.o clk-periph-a10.o clk-gate-a10.o +diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c +new file mode 100644 +index 000000000000..be3e998b85d0 +--- /dev/null ++++ b/drivers/clk/socfpga/clk-gate-a10.c +@@ -0,0 +1,190 @@ ++/* ++ * Copyright (C) 2015 Altera Corporation. All rights reserved ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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/>. ++ */ ++#include <linux/clk-provider.h> ++#include <linux/io.h> ++#include <linux/mfd/syscon.h> ++#include <linux/of.h> ++#include <linux/regmap.h> ++ ++#include "clk.h" ++ ++#define streq(a, b) (strcmp((a), (b)) == 0) ++ ++#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw) ++ ++/* SDMMC Group for System Manager defines */ ++#define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x28 ++ ++static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk, ++ unsigned long parent_rate) ++{ ++ struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); ++ u32 div = 1, val; ++ ++ if (socfpgaclk->fixed_div) ++ div = socfpgaclk->fixed_div; ++ else if (socfpgaclk->div_reg) { ++ val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift; ++ val &= div_mask(socfpgaclk->width); ++ div = (1 << val); ++ } ++ ++ return parent_rate / div; ++} ++ ++static int socfpga_clk_prepare(struct clk_hw *hwclk) ++{ ++ struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); ++ int i; ++ u32 hs_timing; ++ u32 clk_phase[2]; ++ ++ if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) { ++ for (i = 0; i < ARRAY_SIZE(clk_phase); i++) { ++ switch (socfpgaclk->clk_phase[i]) { ++ case 0: ++ clk_phase[i] = 0; ++ break; ++ case 45: ++ clk_phase[i] = 1; ++ break; ++ case 90: ++ clk_phase[i] = 2; ++ break; ++ case 135: ++ clk_phase[i] = 3; ++ break; ++ case 180: ++ clk_phase[i] = 4; ++ break; ++ case 225: ++ clk_phase[i] = 5; ++ break; ++ case 270: ++ clk_phase[i] = 6; ++ break; ++ case 315: ++ clk_phase[i] = 7; ++ break; ++ default: ++ clk_phase[i] = 0; ++ break; ++ } ++ } ++ ++ hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1]); ++ if (!IS_ERR(socfpgaclk->sys_mgr_base_addr)) ++ regmap_write(socfpgaclk->sys_mgr_base_addr, ++ SYSMGR_SDMMCGRP_CTRL_OFFSET, hs_timing); ++ else ++ pr_err("%s: cannot set clk_phase because sys_mgr_base_addr is not available!\n", ++ __func__); ++ } ++ return 0; ++} ++ ++static struct clk_ops gateclk_ops = { ++ .prepare = socfpga_clk_prepare, ++ .recalc_rate = socfpga_gate_clk_recalc_rate, ++}; ++ ++static void __init __socfpga_gate_init(struct device_node *node, ++ const struct clk_ops *ops) ++{ ++ u32 clk_gate[2]; ++ u32 div_reg[3]; ++ u32 clk_phase[2]; ++ u32 fixed_div; ++ struct clk *clk; ++ struct socfpga_gate_clk *socfpga_clk; ++ const char *clk_name = node->name; ++ const char *parent_name[SOCFPGA_MAX_PARENTS]; ++ struct clk_init_data init; ++ int rc; ++ int i = 0; ++ ++ socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); ++ if (WARN_ON(!socfpga_clk)) ++ return; ++ ++ rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2); ++ if (rc) ++ clk_gate[0] = 0; ++ ++ if (clk_gate[0]) { ++ socfpga_clk->hw.reg = clk_mgr_a10_base_addr + clk_gate[0]; ++ socfpga_clk->hw.bit_idx = clk_gate[1]; ++ ++ gateclk_ops.enable = clk_gate_ops.enable; ++ gateclk_ops.disable = clk_gate_ops.disable; ++ } ++ ++ rc = of_property_read_u32(node, "fixed-divider", &fixed_div); ++ if (rc) ++ socfpga_clk->fixed_div = 0; ++ else ++ socfpga_clk->fixed_div = fixed_div; ++ ++ rc = of_property_read_u32_array(node, "div-reg", div_reg, 3); ++ if (!rc) { ++ socfpga_clk->div_reg = clk_mgr_a10_base_addr + div_reg[0]; ++ socfpga_clk->shift = div_reg[1]; ++ socfpga_clk->width = div_reg[2]; ++ } else { ++ socfpga_clk->div_reg = NULL; ++ } ++ ++ rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2); ++ if (!rc) { ++ socfpga_clk->clk_phase[0] = clk_phase[0]; ++ socfpga_clk->clk_phase[1] = clk_phase[1]; ++ ++ socfpga_clk->sys_mgr_base_addr = ++ syscon_regmap_lookup_by_compatible("altr,sys-mgr"); ++ if (IS_ERR(socfpga_clk->sys_mgr_base_addr)) { ++ pr_err("%s: failed to find altr,sys-mgr regmap!\n", ++ __func__); ++ return; ++ } ++ } ++ ++ of_property_read_string(node, "clock-output-names", &clk_name); ++ ++ init.name = clk_name; ++ init.ops = ops; ++ init.flags = 0; ++ while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] = ++ of_clk_get_parent_name(node, i)) != NULL) ++ i++; ++ ++ init.parent_names = parent_name; ++ init.num_parents = i; ++ socfpga_clk->hw.hw.init = &init; ++ ++ clk = clk_register(NULL, &socfpga_clk->hw.hw); ++ if (WARN_ON(IS_ERR(clk))) { ++ kfree(socfpga_clk); ++ return; ++ } ++ rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); ++ if (WARN_ON(rc)) ++ return; ++} ++ ++void __init socfpga_a10_gate_init(struct device_node *node) ++{ ++ __socfpga_gate_init(node, &gateclk_ops); ++} +diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c +new file mode 100644 +index 000000000000..9d0181b5a6a4 +--- /dev/null ++++ b/drivers/clk/socfpga/clk-periph-a10.c +@@ -0,0 +1,138 @@ ++/* ++ * Copyright (C) 2015 Altera Corporation. All rights reserved ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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/>. ++ */ ++#include <linux/clk-provider.h> ++#include <linux/io.h> ++#include <linux/of.h> ++ ++#include "clk.h" ++ ++#define CLK_MGR_FREE_SHIFT 16 ++#define CLK_MGR_FREE_MASK 0x7 ++ ++#define SOCFPGA_MPU_FREE_CLK "mpu_free_clk" ++#define SOCFPGA_NOC_FREE_CLK "noc_free_clk" ++#define SOCFPGA_SDMMC_FREE_CLK "sdmmc_free_clk" ++#define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw.hw) ++ ++static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk, ++ unsigned long parent_rate) ++{ ++ struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk); ++ u32 div; ++ ++ if (socfpgaclk->fixed_div) { ++ div = socfpgaclk->fixed_div; ++ } else if (socfpgaclk->div_reg) { ++ div = readl(socfpgaclk->div_reg) >> socfpgaclk->shift; ++ div &= div_mask(socfpgaclk->width); ++ div += 1; ++ } else { ++ div = ((readl(socfpgaclk->hw.reg) & 0x7ff) + 1); ++ } ++ ++ return parent_rate / div; ++} ++ ++static u8 clk_periclk_get_parent(struct clk_hw *hwclk) ++{ ++ struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk); ++ u32 clk_src; ++ ++ clk_src = readl(socfpgaclk->hw.reg); ++ if (streq(hwclk->init->name, SOCFPGA_MPU_FREE_CLK) || ++ streq(hwclk->init->name, SOCFPGA_NOC_FREE_CLK) || ++ streq(hwclk->init->name, SOCFPGA_SDMMC_FREE_CLK)) ++ return (clk_src >> CLK_MGR_FREE_SHIFT) & ++ CLK_MGR_FREE_MASK; ++ else ++ return 0; ++} ++ ++static const struct clk_ops periclk_ops = { ++ .recalc_rate = clk_periclk_recalc_rate, ++ .get_parent = clk_periclk_get_parent, ++}; ++ ++static __init void __socfpga_periph_init(struct device_node *node, ++ const struct clk_ops *ops) ++{ ++ u32 reg; ++ struct clk *clk; ++ struct socfpga_periph_clk *periph_clk; ++ const char *clk_name = node->name; ++ const char *parent_name; ++ struct clk_init_data init; ++ int rc; ++ u32 fixed_div; ++ u32 div_reg[3]; ++ ++ of_property_read_u32(node, "reg", ®); ++ ++ periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); ++ if (WARN_ON(!periph_clk)) ++ return; ++ ++ periph_clk->hw.reg = clk_mgr_a10_base_addr + reg; ++ ++ rc = of_property_read_u32_array(node, "div-reg", div_reg, 3); ++ if (!rc) { ++ periph_clk->div_reg = clk_mgr_a10_base_addr + div_reg[0]; ++ periph_clk->shift = div_reg[1]; ++ periph_clk->width = div_reg[2]; ++ } else { ++ periph_clk->div_reg = NULL; ++ } ++ ++ rc = of_property_read_u32(node, "fixed-divider", &fixed_div); ++ if (rc) ++ periph_clk->fixed_div = 0; ++ else ++ periph_clk->fixed_div = fixed_div; ++ ++ of_property_read_string(node, "clock-output-names", &clk_name); ++ ++ init.name = clk_name; ++ init.ops = ops; ++ init.flags = 0; ++ ++ parent_name = of_clk_get_parent_name(node, 0); ++ init.num_parents = 1; ++ init.parent_names = &parent_name; ++ ++ periph_clk->hw.hw.init = &init; ++ ++ clk = clk_register(NULL, &periph_clk->hw.hw); ++ if (WARN_ON(IS_ERR(clk))) { ++ kfree(periph_clk); ++ return; ++ } ++ rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); ++ if (rc < 0) { ++ pr_err("Could not register clock provider for node:%s\n", ++ clk_name); ++ goto err_clk; ++ } ++ ++ return; ++ ++err_clk: ++ clk_unregister(clk); ++} ++ ++void __init socfpga_a10_periph_init(struct device_node *node) ++{ ++ __socfpga_periph_init(node, &periclk_ops); ++} +diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c +new file mode 100644 +index 000000000000..1178b11babca +--- /dev/null ++++ b/drivers/clk/socfpga/clk-pll-a10.c +@@ -0,0 +1,129 @@ ++/* ++ * Copyright (C) 2015 Altera Corporation. All rights reserved ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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/>. ++ */ ++#include <linux/clk-provider.h> ++#include <linux/io.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++ ++#include "clk.h" ++ ++/* Clock Manager offsets */ ++#define CLK_MGR_PLL_CLK_SRC_SHIFT 8 ++#define CLK_MGR_PLL_CLK_SRC_MASK 0x3 ++ ++/* Clock bypass bits */ ++#define SOCFPGA_PLL_BG_PWRDWN 0 ++#define SOCFPGA_PLL_PWR_DOWN 1 ++#define SOCFPGA_PLL_EXT_ENA 2 ++#define SOCFPGA_PLL_DIVF_MASK 0x00001FFF ++#define SOCFPGA_PLL_DIVF_SHIFT 0 ++#define SOCFPGA_PLL_DIVQ_MASK 0x003F0000 ++#define SOCFPGA_PLL_DIVQ_SHIFT 16 ++#define SOCFGPA_MAX_PARENTS 5 ++ ++#define SOCFPGA_MAIN_PLL_CLK "main_pll" ++#define SOCFPGA_PERIP_PLL_CLK "periph_pll" ++ ++#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw) ++ ++void __iomem *clk_mgr_a10_base_addr; ++ ++static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk, ++ unsigned long parent_rate) ++{ ++ struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk); ++ unsigned long divf, divq, reg; ++ unsigned long long vco_freq; ++ ++ /* read VCO1 reg for numerator and denominator */ ++ reg = readl(socfpgaclk->hw.reg + 0x4); ++ divf = (reg & SOCFPGA_PLL_DIVF_MASK) >> SOCFPGA_PLL_DIVF_SHIFT; ++ divq = (reg & SOCFPGA_PLL_DIVQ_MASK) >> SOCFPGA_PLL_DIVQ_SHIFT; ++ vco_freq = (unsigned long long)parent_rate * (divf + 1); ++ do_div(vco_freq, (1 + divq)); ++ return (unsigned long)vco_freq; ++} ++ ++static u8 clk_pll_get_parent(struct clk_hw *hwclk) ++{ ++ struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk); ++ u32 pll_src; ++ ++ pll_src = readl(socfpgaclk->hw.reg); ++ ++ return (pll_src >> CLK_MGR_PLL_CLK_SRC_SHIFT) & ++ CLK_MGR_PLL_CLK_SRC_MASK; ++} ++ ++static struct clk_ops clk_pll_ops = { ++ .recalc_rate = clk_pll_recalc_rate, ++ .get_parent = clk_pll_get_parent, ++}; ++ ++static struct __init clk * __socfpga_pll_init(struct device_node *node, ++ const struct clk_ops *ops) ++{ ++ u32 reg; ++ struct clk *clk; ++ struct socfpga_pll *pll_clk; ++ const char *clk_name = node->name; ++ const char *parent_name[SOCFGPA_MAX_PARENTS]; ++ struct clk_init_data init; ++ struct device_node *clkmgr_np; ++ int rc; ++ int i = 0; ++ ++ of_property_read_u32(node, "reg", ®); ++ ++ pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); ++ if (WARN_ON(!pll_clk)) ++ return NULL; ++ ++ clkmgr_np = of_find_compatible_node(NULL, NULL, "altr,clk-mgr"); ++ clk_mgr_a10_base_addr = of_iomap(clkmgr_np, 0); ++ BUG_ON(!clk_mgr_a10_base_addr); ++ pll_clk->hw.reg = clk_mgr_a10_base_addr + reg; ++ ++ of_property_read_string(node, "clock-output-names", &clk_name); ++ ++ init.name = clk_name; ++ init.ops = ops; ++ init.flags = 0; ++ ++ while (i < SOCFGPA_MAX_PARENTS && (parent_name[i] = ++ of_clk_get_parent_name(node, i)) != NULL) ++ i++; ++ init.num_parents = i; ++ init.parent_names = parent_name; ++ pll_clk->hw.hw.init = &init; ++ ++ pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA; ++ clk_pll_ops.enable = clk_gate_ops.enable; ++ clk_pll_ops.disable = clk_gate_ops.disable; ++ ++ clk = clk_register(NULL, &pll_clk->hw.hw); ++ if (WARN_ON(IS_ERR(clk))) { ++ kfree(pll_clk); ++ return NULL; ++ } ++ rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); ++ return clk; ++} ++ ++void __init socfpga_a10_pll_init(struct device_node *node) ++{ ++ __socfpga_pll_init(node, &clk_pll_ops); ++} +diff --git a/drivers/clk/socfpga/clk.c b/drivers/clk/socfpga/clk.c +index 43db947e5f0e..7564d2e35f32 100644 +--- a/drivers/clk/socfpga/clk.c ++++ b/drivers/clk/socfpga/clk.c +@@ -24,4 +24,9 @@ + CLK_OF_DECLARE(socfpga_pll_clk, "altr,socfpga-pll-clock", socfpga_pll_init); + CLK_OF_DECLARE(socfpga_perip_clk, "altr,socfpga-perip-clk", socfpga_periph_init); + CLK_OF_DECLARE(socfpga_gate_clk, "altr,socfpga-gate-clk", socfpga_gate_init); +- ++CLK_OF_DECLARE(socfpga_a10_pll_clk, "altr,socfpga-a10-pll-clock", ++ socfpga_a10_pll_init); ++CLK_OF_DECLARE(socfpga_a10_perip_clk, "altr,socfpga-a10-perip-clk", ++ socfpga_a10_periph_init); ++CLK_OF_DECLARE(socfpga_a10_gate_clk, "altr,socfpga-a10-gate-clk", ++ socfpga_a10_gate_init); +diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h +index b09a5d50547e..603973ab7e29 100644 +--- a/drivers/clk/socfpga/clk.h ++++ b/drivers/clk/socfpga/clk.h +@@ -34,10 +34,14 @@ + ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0)) + + extern void __iomem *clk_mgr_base_addr; ++extern void __iomem *clk_mgr_a10_base_addr; + + void __init socfpga_pll_init(struct device_node *node); + void __init socfpga_periph_init(struct device_node *node); + void __init socfpga_gate_init(struct device_node *node); ++void socfpga_a10_pll_init(struct device_node *node); ++void socfpga_a10_periph_init(struct device_node *node); ++void socfpga_a10_gate_init(struct device_node *node); + + struct socfpga_pll { + struct clk_gate hw; +@@ -48,6 +52,7 @@ struct socfpga_gate_clk { + char *parent_name; + u32 fixed_div; + void __iomem *div_reg; ++ struct regmap *sys_mgr_base_addr; + u32 width; /* only valid if div_reg != 0 */ + u32 shift; /* only valid if div_reg != 0 */ + u32 clk_phase[2]; +-- +2.6.2 + diff --git a/patches.altera/0015-ARM-socfpga-dts-add-the-a9-scu-node-for-arria10.patch b/patches.altera/0015-ARM-socfpga-dts-add-the-a9-scu-node-for-arria10.patch new file mode 100644 index 00000000000000..4e4ff2c381bbf9 --- /dev/null +++ b/patches.altera/0015-ARM-socfpga-dts-add-the-a9-scu-node-for-arria10.patch @@ -0,0 +1,33 @@ +From 88e0b84faef41aaa768e9b2266b8b556b08343fa Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Thu, 14 May 2015 09:49:14 -0500 +Subject: [PATCH 15/39] ARM: socfpga: dts: add the a9-scu node for arria10 + +Add a dts node for the A9 SCU on the Arria10 platform. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 479f8df04c4b7b1dd53b8c2e5b157b678c8a319c) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga_arria10.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index abf97630c592..d025f77b11f2 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -567,6 +567,11 @@ + reg = <0xffd05000 0x100>; + }; + ++ scu: snoop-control-unit@ffffc000 { ++ compatible = "arm,cortex-a9-scu"; ++ reg = <0xffffc000 0x100>; ++ }; ++ + sysmgr: sysmgr@ffd06000 { + compatible = "altr,sys-mgr", "syscon"; + reg = <0xffd06000 0x300>; +-- +2.6.2 + diff --git a/patches.altera/0016-ARM-socfpga-dts-add-enable-method-property-for-cpu-n.patch b/patches.altera/0016-ARM-socfpga-dts-add-enable-method-property-for-cpu-n.patch new file mode 100644 index 00000000000000..c12f1e4f34720c --- /dev/null +++ b/patches.altera/0016-ARM-socfpga-dts-add-enable-method-property-for-cpu-n.patch @@ -0,0 +1,45 @@ +From e4d54548768143ed7840e75dbf3dc51883d3d89c Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 22 May 2015 23:00:10 -0500 +Subject: [PATCH 16/39] ARM: socfpga: dts: add enable-method property for cpu + nodes + +Add the enable-method property for the cpu node on socfpga.dtsi and +socfpga_arria10.dtsi. This is for CPU_METHOD_OF_DECLARE to use to enable +the secondary core. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit ebbce1bbc4f25c0ca68f66df54ea5e8eefa90da5) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga.dtsi | 1 + + arch/arm/boot/dts/socfpga_arria10.dtsi | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi +index 9b653edd003f..80f924deed37 100644 +--- a/arch/arm/boot/dts/socfpga.dtsi ++++ b/arch/arm/boot/dts/socfpga.dtsi +@@ -36,6 +36,7 @@ + cpus { + #address-cells = <1>; + #size-cells = <0>; ++ enable-method = "altr,socfpga-smp"; + + cpu@0 { + compatible = "arm,cortex-a9"; +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index d025f77b11f2..6ceb26e542ec 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -24,6 +24,7 @@ + cpus { + #address-cells = <1>; + #size-cells = <0>; ++ enable-method = "altr,socfpga-a10-smp"; + + cpu@0 { + compatible = "arm,cortex-a9"; +-- +2.6.2 + diff --git a/patches.altera/0017-clk-of-helper-for-filling-parent-clock-array-and-ret.patch b/patches.altera/0017-clk-of-helper-for-filling-parent-clock-array-and-ret.patch new file mode 100644 index 00000000000000..c635a754a2f4bd --- /dev/null +++ b/patches.altera/0017-clk-of-helper-for-filling-parent-clock-array-and-ret.patch @@ -0,0 +1,74 @@ +From 7d45a8582944d287a796ae846e88d41d5e3f02e1 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 5 Jun 2015 11:26:13 -0500 +Subject: [PATCH 17/39] clk: of: helper for filling parent clock array and + return num of parents + +Sprinkled all through the platform clock drivers are code like this to +fill the clock parent array: + +for (i = 0; i < num_parents; ++i) + parent_names[i] = of_clk_get_parent_name(np, i); + +The of_clk_parent_fill() will do the same as the code above, and while +at it, return the number of parents as well since the logic of the +function is to the walk the clock node to look for the parent. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +[sboyd@codeaurora.org: Fixed kernel-doc] +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +(cherry picked from commit 2e61dfb3602b904966491f260f62c01b9895936a) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/clk/clk.c | 21 +++++++++++++++++++++ + include/linux/clk-provider.h | 2 ++ + 2 files changed, 23 insertions(+) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 9f9cadd00bc8..80f3f38a2575 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -3069,6 +3069,27 @@ const char *of_clk_get_parent_name(struct device_node *np, int index) + } + EXPORT_SYMBOL_GPL(of_clk_get_parent_name); + ++/** ++ * of_clk_parent_fill() - Fill @parents with names of @np's parents and return ++ * number of parents ++ * @np: Device node pointer associated with clock provider ++ * @parents: pointer to char array that hold the parents' names ++ * @size: size of the @parents array ++ * ++ * Return: number of parents for the clock node. ++ */ ++int of_clk_parent_fill(struct device_node *np, const char **parents, ++ unsigned int size) ++{ ++ unsigned int i = 0; ++ ++ while (i < size && (parents[i] = of_clk_get_parent_name(np, i)) != NULL) ++ i++; ++ ++ return i; ++} ++EXPORT_SYMBOL_GPL(of_clk_parent_fill); ++ + struct clock_provider { + of_clk_init_cb_t clk_init_cb; + struct device_node *np; +diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h +index df695313f975..6068df19d08a 100644 +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -624,6 +624,8 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, + void *data); + struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data); + int of_clk_get_parent_count(struct device_node *np); ++int of_clk_parent_fill(struct device_node *np, const char **parents, ++ unsigned int size); + const char *of_clk_get_parent_name(struct device_node *np, int index); + + void of_clk_init(const struct of_device_id *matches); +-- +2.6.2 + diff --git a/patches.altera/0018-clk-socfpga-make-use-of-of_clk_parent_fill-helper-fu.patch b/patches.altera/0018-clk-socfpga-make-use-of-of_clk_parent_fill-helper-fu.patch new file mode 100644 index 00000000000000..d60f03010d7a98 --- /dev/null +++ b/patches.altera/0018-clk-socfpga-make-use-of-of_clk_parent_fill-helper-fu.patch @@ -0,0 +1,71 @@ +From 8affc952ff5eefdab643797d064f4557cc7ffb09 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 5 Jun 2015 11:26:14 -0500 +Subject: [PATCH 18/39] clk: socfpga: make use of of_clk_parent_fill helper + function + +Use of_clk_parent_fill to fill in the parent clock's array. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +(cherry picked from commit 761d3e328c503c8428cec54e33196e49f5c46e55) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/clk/socfpga/clk-gate.c | 6 +----- + drivers/clk/socfpga/clk-pll.c | 7 +------ + 2 files changed, 2 insertions(+), 11 deletions(-) + +diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c +index 607ab352f73c..b37f6c2fdd3b 100644 +--- a/drivers/clk/socfpga/clk-gate.c ++++ b/drivers/clk/socfpga/clk-gate.c +@@ -190,7 +190,6 @@ static void __init __socfpga_gate_init(struct device_node *node, + const char *parent_name[SOCFPGA_MAX_PARENTS]; + struct clk_init_data init; + int rc; +- int i = 0; + + socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); + if (WARN_ON(!socfpga_clk)) +@@ -234,12 +233,9 @@ static void __init __socfpga_gate_init(struct device_node *node, + init.name = clk_name; + init.ops = ops; + init.flags = 0; +- while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] = +- of_clk_get_parent_name(node, i)) != NULL) +- i++; + ++ init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS); + init.parent_names = parent_name; +- init.num_parents = i; + socfpga_clk->hw.hw.init = &init; + + clk = clk_register(NULL, &socfpga_clk->hw.hw); +diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c +index de6da957a09d..8f26b5234947 100644 +--- a/drivers/clk/socfpga/clk-pll.c ++++ b/drivers/clk/socfpga/clk-pll.c +@@ -92,7 +92,6 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node, + struct clk_init_data init; + struct device_node *clkmgr_np; + int rc; +- int i = 0; + + of_property_read_u32(node, "reg", ®); + +@@ -111,11 +110,7 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node, + init.ops = ops; + init.flags = 0; + +- while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] = +- of_clk_get_parent_name(node, i)) != NULL) +- i++; +- +- init.num_parents = i; ++ init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS); + init.parent_names = parent_name; + pll_clk->hw.hw.init = &init; + +-- +2.6.2 + diff --git a/patches.altera/0019-ARM-socfpga-use-CPU_METHOD_OF_DECLARE-for-socfpga_cy.patch b/patches.altera/0019-ARM-socfpga-use-CPU_METHOD_OF_DECLARE-for-socfpga_cy.patch new file mode 100644 index 00000000000000..290e3bfd5f5f65 --- /dev/null +++ b/patches.altera/0019-ARM-socfpga-use-CPU_METHOD_OF_DECLARE-for-socfpga_cy.patch @@ -0,0 +1,54 @@ +From 1fae7a42aeedf37fb99d9757afce4a080bbcae68 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Tue, 2 Jun 2015 21:14:01 -0500 +Subject: [PATCH 19/39] ARM: socfpga: use CPU_METHOD_OF_DECLARE for + socfpga_cyclone5 + +Convert cyclone5/arria5 to use CPU_METHOD_OF_DECLARE for smp operations. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +Signed-off-by: Kevin Hilman <khilman@linaro.org> +(cherry picked from commit 5f763ef80d4dff7f2aa519a31472b03499e2c2e1) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/mach-socfpga/core.h | 1 - + arch/arm/mach-socfpga/platsmp.c | 4 +++- + arch/arm/mach-socfpga/socfpga.c | 1 - + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/mach-socfpga/core.h ++++ b/arch/arm/mach-socfpga/core.h +@@ -37,7 +37,6 @@ extern void socfpga_sysmgr_init(void); + extern void __iomem *sys_manager_base_addr; + extern void __iomem *rst_manager_base_addr; + +-extern struct smp_operations socfpga_smp_ops; + extern char secondary_trampoline, secondary_trampoline_end; + + extern unsigned long socfpga_cpu1start_addr; +--- a/arch/arm/mach-socfpga/platsmp.c ++++ b/arch/arm/mach-socfpga/platsmp.c +@@ -83,10 +83,12 @@ static void socfpga_cpu_die(unsigned int + cpu_do_idle(); + } + +-struct smp_operations socfpga_smp_ops __initdata = { ++static struct smp_operations socfpga_smp_ops __initdata = { + .smp_prepare_cpus = socfpga_smp_prepare_cpus, + .smp_boot_secondary = socfpga_boot_secondary, + #ifdef CONFIG_HOTPLUG_CPU + .cpu_die = socfpga_cpu_die, + #endif + }; ++ ++CPU_METHOD_OF_DECLARE(socfpga_smp, "altr,socfpga-smp", &socfpga_smp_ops); +--- a/arch/arm/mach-socfpga/socfpga.c ++++ b/arch/arm/mach-socfpga/socfpga.c +@@ -78,7 +78,6 @@ static const char *altera_dt_match[] = { + DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA") + .l2c_aux_val = 0, + .l2c_aux_mask = ~0, +- .smp = smp_ops(socfpga_smp_ops), + .init_irq = socfpga_init_irq, + .restart = socfpga_cyclone5_restart, + .dt_compat = altera_dt_match, diff --git a/patches.altera/0020-ARM-socfpga-add-CPU_METHOD_OF_DECLARE-for-Arria-10.patch b/patches.altera/0020-ARM-socfpga-add-CPU_METHOD_OF_DECLARE-for-Arria-10.patch new file mode 100644 index 00000000000000..03e89bdbf7ba8b --- /dev/null +++ b/patches.altera/0020-ARM-socfpga-add-CPU_METHOD_OF_DECLARE-for-Arria-10.patch @@ -0,0 +1,85 @@ +From 24384bf8330823848560ee48ff30d2c6882a6284 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Tue, 2 Jun 2015 21:14:02 -0500 +Subject: [PATCH 20/39] ARM: socfpga: add CPU_METHOD_OF_DECLARE for Arria 10 + +Add boot_secondary implementation for the Arria10 platform. Bringing up +the secondary core on the Arria 10 platform is pretty similar to the +Cyclone/Arria 5 platform, with the exception of the following differences: + +- Register offset to bringup CPU1 out of reset is different. +- The cpu1-start-addr for Arria10 contains an additional nibble. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +Signed-off-by: Kevin Hilman <khilman@linaro.org> +(cherry picked from commit 45be0cdb5323d6f2b4005a4d9263a72eac2040cd) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/mach-socfpga/core.h | 2 ++ + arch/arm/mach-socfpga/platsmp.c | 32 ++++++++++++++++++++++++++++++++ + 2 files changed, 34 insertions(+) + +diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h +index 38e5cbf37f45..27e7c65093c0 100644 +--- a/arch/arm/mach-socfpga/core.h ++++ b/arch/arm/mach-socfpga/core.h +@@ -25,6 +25,8 @@ + #define SOCFPGA_RSTMGR_MODPERRST 0x14 + #define SOCFPGA_RSTMGR_BRGMODRST 0x1c + ++#define SOCFPGA_A10_RSTMGR_MODMPURST 0x20 ++ + /* System Manager bits */ + #define RSTMGR_CTRL_SWCOLDRSTREQ 0x1 /* Cold Reset */ + #define RSTMGR_CTRL_SWWARMRSTREQ 0x2 /* Warm Reset */ +diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c +index b84c1a12d3ae..5454e9ce31ea 100644 +--- a/arch/arm/mach-socfpga/platsmp.c ++++ b/arch/arm/mach-socfpga/platsmp.c +@@ -54,6 +54,29 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) + return 0; + } + ++static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; ++ ++ if (socfpga_cpu1start_addr) { ++ writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr + ++ SOCFPGA_A10_RSTMGR_MODMPURST); ++ memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); ++ ++ writel(virt_to_phys(socfpga_secondary_startup), ++ sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff)); ++ ++ flush_cache_all(); ++ smp_wmb(); ++ outer_clean_range(0, trampoline_size); ++ ++ /* This will release CPU #1 out of reset. */ ++ writel(0, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_MODMPURST); ++ } ++ ++ return 0; ++} ++ + static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) + { + struct device_node *np; +@@ -91,4 +114,13 @@ static struct smp_operations socfpga_smp_ops __initdata = { + #endif + }; + ++static struct smp_operations socfpga_a10_smp_ops __initdata = { ++ .smp_prepare_cpus = socfpga_smp_prepare_cpus, ++ .smp_boot_secondary = socfpga_a10_boot_secondary, ++#ifdef CONFIG_HOTPLUG_CPU ++ .cpu_die = socfpga_cpu_die, ++#endif ++}; ++ + CPU_METHOD_OF_DECLARE(socfpga_smp, "altr,socfpga-smp", &socfpga_smp_ops); ++CPU_METHOD_OF_DECLARE(socfpga_a10_smp, "altr,socfpga-a10-smp", &socfpga_a10_smp_ops); +-- +2.6.2 + diff --git a/patches.altera/0021-ARM-socfpga-dts-enable-ethernet-for-Arria10-devkit.patch b/patches.altera/0021-ARM-socfpga-dts-enable-ethernet-for-Arria10-devkit.patch new file mode 100644 index 00000000000000..cc2023bd3f835a --- /dev/null +++ b/patches.altera/0021-ARM-socfpga-dts-enable-ethernet-for-Arria10-devkit.patch @@ -0,0 +1,112 @@ +From 0599bf4506bc1d87a15e5883a86bb3dc8750a67a Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Tue, 2 Jun 2015 21:31:00 -0500 +Subject: [PATCH 21/39] ARM: socfpga: dts: enable ethernet for Arria10 devkit + +Update the arria10 gmac nodes with all the necessary properties for ethernet +to function on the Arria10 devkit. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +Signed-off-by: Kevin Hilman <khilman@linaro.org> +(cherry picked from commit 112cadfd4365b1949c7f13a2616f6b99990f5fd5) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga_arria10.dtsi | 11 +++++++++++ + arch/arm/boot/dts/socfpga_arria10_socdk.dtsi | 28 ++++++++++++++++++++++++++++ + 2 files changed, 39 insertions(+) + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index 6ceb26e542ec..f5bebdd6d1be 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -397,6 +397,7 @@ + + gmac0: ethernet@ff800000 { + compatible = "altr,socfpga-stmmac", "snps,dwmac-3.72a", "snps,dwmac"; ++ altr,sysmgr-syscon = <&sysmgr 0x44 0>; + reg = <0xff800000 0x2000>; + interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; +@@ -404,11 +405,16 @@ + mac-address = [00 00 00 00 00 00]; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <128>; ++ tx-fifo-depth = <4096>; ++ rx-fifo-depth = <16384>; ++ clocks = <&l4_mp_clk>; ++ clock-names = "stmmaceth"; + status = "disabled"; + }; + + gmac1: ethernet@ff802000 { + compatible = "altr,socfpga-stmmac", "snps,dwmac-3.72a", "snps,dwmac"; ++ altr,sysmgr-syscon = <&sysmgr 0x48 0>; + reg = <0xff802000 0x2000>; + interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; +@@ -418,11 +424,14 @@ + snps,perfect-filter-entries = <128>; + tx-fifo-depth = <4096>; + rx-fifo-depth = <16384>; ++ clocks = <&l4_mp_clk>; ++ clock-names = "stmmaceth"; + status = "disabled"; + }; + + gmac2: ethernet@ff804000 { + compatible = "altr,socfpga-stmmac", "snps,dwmac-3.72a", "snps,dwmac"; ++ altr,sysmgr-syscon = <&sysmgr 0x4C 0>; + reg = <0xff804000 0x2000>; + interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; +@@ -432,6 +441,8 @@ + snps,perfect-filter-entries = <128>; + tx-fifo-depth = <4096>; + rx-fifo-depth = <16384>; ++ clocks = <&l4_mp_clk>; ++ clock-names = "stmmaceth"; + status = "disabled"; + }; + +diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi +index 347ca4ef58f8..94a0709b2fe6 100644 +--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi +@@ -41,6 +41,34 @@ + }; + }; + ++&gmac0 { ++ phy-mode = "rgmii"; ++ phy-addr = <0xffffffff>; /* probe for phy addr */ ++ ++ /* ++ * These skews assume the user's FPGA design is adding 600ps of delay ++ * for TX_CLK on Arria 10. ++ * ++ * All skews are offset since hardware skew values for the ksz9031 ++ * range from a negative skew to a positive skew. ++ * See the micrel-ksz90x1.txt Documentation file for details. ++ */ ++ txd0-skew-ps = <0>; /* -420ps */ ++ txd1-skew-ps = <0>; /* -420ps */ ++ txd2-skew-ps = <0>; /* -420ps */ ++ txd3-skew-ps = <0>; /* -420ps */ ++ rxd0-skew-ps = <420>; /* 0ps */ ++ rxd1-skew-ps = <420>; /* 0ps */ ++ rxd2-skew-ps = <420>; /* 0ps */ ++ rxd3-skew-ps = <420>; /* 0ps */ ++ txen-skew-ps = <0>; /* -420ps */ ++ txc-skew-ps = <1860>; /* 960ps */ ++ rxdv-skew-ps = <420>; /* 0ps */ ++ rxc-skew-ps = <1680>; /* 780ps */ ++ max-frame-size = <3800>; ++ status = "okay"; ++}; ++ + &uart1 { + status = "okay"; + }; +-- +2.6.2 + diff --git a/patches.altera/0022-ARM-socfpga-support-suspend-to-ram.patch b/patches.altera/0022-ARM-socfpga-support-suspend-to-ram.patch new file mode 100644 index 00000000000000..509f3d165b377f --- /dev/null +++ b/patches.altera/0022-ARM-socfpga-support-suspend-to-ram.patch @@ -0,0 +1,400 @@ +From f37a045095f3b8dad974826d4ca38b1c54e4bd0f Mon Sep 17 00:00:00 2001 +From: Alan Tull <atull@opensource.altera.com> +Date: Fri, 5 Jun 2015 08:24:52 -0500 +Subject: [PATCH 22/39] ARM: socfpga: support suspend to ram + +Add code that requests that the sdr controller go into +self-refresh mode. This code is run from ocram. + +Suspend-to-RAM and EDAC support are mutually exclusive on +SOCFPGA. If the EDAC is enabled, it will prevent the +platform from going into suspend. + +Example of how to request to suspend to ram: + $ echo enabled > \ +/sys/devices/soc/ffc02000.serial0/tty/ttyS0/power/wakeup + + $ echo -n mem > /sys/power/state + +Signed-off-by: Alan Tull <atull@opensource.altera.com> +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +Signed-off-by: Kevin Hilman <khilman@linaro.org> +(cherry picked from commit 44fd8c7d4005f660f48679439f0a54225ba234a4) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/mach-socfpga/Kconfig | 10 ++ + arch/arm/mach-socfpga/Makefile | 1 + arch/arm/mach-socfpga/core.h | 6 + + arch/arm/mach-socfpga/pm.c | 149 +++++++++++++++++++++++++++++++++++ + arch/arm/mach-socfpga/self-refresh.S | 136 +++++++++++++++++++++++++++++++ + arch/arm/mach-socfpga/socfpga.c | 6 + + 6 files changed, 305 insertions(+), 3 deletions(-) + create mode 100644 arch/arm/mach-socfpga/pm.c + create mode 100644 arch/arm/mach-socfpga/self-refresh.S + +--- a/arch/arm/mach-socfpga/Kconfig ++++ b/arch/arm/mach-socfpga/Kconfig +@@ -1,4 +1,4 @@ +-config ARCH_SOCFPGA ++menuconfig ARCH_SOCFPGA + bool "Altera SOCFPGA family" if ARCH_MULTI_V7 + select ARM_AMBA + select ARM_GIC +@@ -8,3 +8,11 @@ config ARCH_SOCFPGA + select HAVE_ARM_SCU + select HAVE_ARM_TWD if SMP + select MFD_SYSCON ++ ++if ARCH_SOCFPGA ++config SOCFPGA_SUSPEND ++ bool "Suspend to RAM on SOCFPGA" ++ help ++ Select this if you want to enable Suspend-to-RAM on SOCFPGA ++ platforms. ++endif +--- a/arch/arm/mach-socfpga/Makefile ++++ b/arch/arm/mach-socfpga/Makefile +@@ -4,3 +4,4 @@ + + obj-y := socfpga.o + obj-$(CONFIG_SMP) += headsmp.o platsmp.o ++obj-$(CONFIG_SOCFPGA_SUSPEND) += pm.o self-refresh.o +--- a/arch/arm/mach-socfpga/core.h ++++ b/arch/arm/mach-socfpga/core.h +@@ -1,6 +1,6 @@ + /* + * Copyright 2012 Pavel Machek <pavel@denx.de> +- * Copyright (C) 2012 Altera Corporation ++ * Copyright (C) 2012-2015 Altera Corporation + * + * 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 +@@ -38,6 +38,10 @@ extern void socfpga_sysmgr_init(void); + + extern void __iomem *sys_manager_base_addr; + extern void __iomem *rst_manager_base_addr; ++extern void __iomem *sdr_ctl_base_addr; ++ ++u32 socfpga_sdram_self_refresh(u32 sdr_base); ++extern unsigned int socfpga_sdram_self_refresh_sz; + + extern char secondary_trampoline, secondary_trampoline_end; + +--- /dev/null ++++ b/arch/arm/mach-socfpga/pm.c +@@ -0,0 +1,149 @@ ++/* ++ * arch/arm/mach-socfpga/pm.c ++ * ++ * Copyright (C) 2014-2015 Altera Corporation. All rights reserved. ++ * ++ * with code from pm-imx6.c ++ * Copyright 2011-2014 Freescale Semiconductor, Inc. ++ * Copyright 2011 Linaro Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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/>. ++ */ ++ ++#include <linux/bitops.h> ++#include <linux/genalloc.h> ++#include <linux/init.h> ++#include <linux/io.h> ++#include <linux/of_platform.h> ++#include <linux/suspend.h> ++#include <asm/suspend.h> ++#include <asm/fncpy.h> ++#include "core.h" ++ ++/* Pointer to function copied to ocram */ ++static u32 (*socfpga_sdram_self_refresh_in_ocram)(u32 sdr_base); ++ ++static int socfpga_setup_ocram_self_refresh(void) ++{ ++ struct platform_device *pdev; ++ phys_addr_t ocram_pbase; ++ struct device_node *np; ++ struct gen_pool *ocram_pool; ++ unsigned long ocram_base; ++ void __iomem *suspend_ocram_base; ++ int ret = 0; ++ ++ np = of_find_compatible_node(NULL, NULL, "mmio-sram"); ++ if (!np) { ++ pr_err("%s: Unable to find mmio-sram in dtb\n", __func__); ++ return -ENODEV; ++ } ++ ++ pdev = of_find_device_by_node(np); ++ if (!pdev) { ++ pr_warn("%s: failed to find ocram device!\n", __func__); ++ ret = -ENODEV; ++ goto put_node; ++ } ++ ++ ocram_pool = dev_get_gen_pool(&pdev->dev); ++ if (!ocram_pool) { ++ pr_warn("%s: ocram pool unavailable!\n", __func__); ++ ret = -ENODEV; ++ goto put_node; ++ } ++ ++ ocram_base = gen_pool_alloc(ocram_pool, socfpga_sdram_self_refresh_sz); ++ if (!ocram_base) { ++ pr_warn("%s: unable to alloc ocram!\n", __func__); ++ ret = -ENOMEM; ++ goto put_node; ++ } ++ ++ ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base); ++ ++ suspend_ocram_base = __arm_ioremap_exec(ocram_pbase, ++ socfpga_sdram_self_refresh_sz, ++ false); ++ if (!suspend_ocram_base) { ++ pr_warn("%s: __arm_ioremap_exec failed!\n", __func__); ++ ret = -ENOMEM; ++ goto put_node; ++ } ++ ++ /* Copy the code that puts DDR in self refresh to ocram */ ++ socfpga_sdram_self_refresh_in_ocram = ++ (void *)fncpy(suspend_ocram_base, ++ &socfpga_sdram_self_refresh, ++ socfpga_sdram_self_refresh_sz); ++ ++ WARN(!socfpga_sdram_self_refresh_in_ocram, ++ "could not copy function to ocram"); ++ if (!socfpga_sdram_self_refresh_in_ocram) ++ ret = -EFAULT; ++ ++put_node: ++ of_node_put(np); ++ ++ return ret; ++} ++ ++static int socfpga_pm_suspend(unsigned long arg) ++{ ++ u32 ret; ++ ++ if (!sdr_ctl_base_addr) ++ return -EFAULT; ++ ++ ret = socfpga_sdram_self_refresh_in_ocram((u32)sdr_ctl_base_addr); ++ ++ pr_debug("%s self-refresh loops request=%d exit=%d\n", __func__, ++ ret & 0xffff, (ret >> 16) & 0xffff); ++ ++ return 0; ++} ++ ++static int socfpga_pm_enter(suspend_state_t state) ++{ ++ switch (state) { ++ case PM_SUSPEND_STANDBY: ++ case PM_SUSPEND_MEM: ++ outer_disable(); ++ cpu_suspend(0, socfpga_pm_suspend); ++ outer_resume(); ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static const struct platform_suspend_ops socfpga_pm_ops = { ++ .valid = suspend_valid_only_mem, ++ .enter = socfpga_pm_enter, ++}; ++ ++static int __init socfpga_pm_init(void) ++{ ++ int ret; ++ ++ ret = socfpga_setup_ocram_self_refresh(); ++ if (ret) ++ return ret; ++ ++ suspend_set_ops(&socfpga_pm_ops); ++ pr_info("SoCFPGA initialized for DDR self-refresh during suspend.\n"); ++ ++ return 0; ++} ++arch_initcall(socfpga_pm_init); +--- /dev/null ++++ b/arch/arm/mach-socfpga/self-refresh.S +@@ -0,0 +1,136 @@ ++/* ++ * Copyright (C) 2014-2015 Altera Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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/>. ++ */ ++#include <linux/linkage.h> ++#include <asm/assembler.h> ++ ++#define MAX_LOOP_COUNT 1000 ++ ++/* Register offset */ ++#define SDR_CTRLGRP_LOWPWREQ_ADDR 0x54 ++#define SDR_CTRLGRP_LOWPWRACK_ADDR 0x58 ++ ++/* Bitfield positions */ ++#define SELFRSHREQ_POS 3 ++#define SELFRSHREQ_MASK 0x8 ++ ++#define SELFRFSHACK_POS 1 ++#define SELFRFSHACK_MASK 0x2 ++ ++ /* ++ * This code assumes that when the bootloader configured ++ * the sdram controller for the DDR on the board it ++ * configured the following fields depending on the DDR ++ * vendor/configuration: ++ * ++ * sdr.ctrlcfg.lowpwreq.selfrfshmask ++ * sdr.ctrlcfg.lowpwrtiming.clkdisablecycles ++ * sdr.ctrlcfg.dramtiming4.selfrfshexit ++ */ ++ ++ .arch armv7-a ++ .text ++ .align 3 ++ ++ /* ++ * socfpga_sdram_self_refresh ++ * ++ * r0 : sdr_ctl_base_addr ++ * r1 : temp storage of return value ++ * r2 : temp storage of register values ++ * r3 : loop counter ++ * ++ * return value: lower 16 bits: loop count going into self refresh ++ * upper 16 bits: loop count exiting self refresh ++ */ ++ENTRY(socfpga_sdram_self_refresh) ++ /* Enable dynamic clock gating in the Power Control Register. */ ++ mrc p15, 0, r2, c15, c0, 0 ++ orr r2, r2, #1 ++ mcr p15, 0, r2, c15, c0, 0 ++ ++ /* Enable self refresh: set sdr.ctrlgrp.lowpwreq.selfrshreq = 1 */ ++ ldr r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR] ++ orr r2, r2, #SELFRSHREQ_MASK ++ str r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR] ++ ++ /* Poll until sdr.ctrlgrp.lowpwrack.selfrfshack == 1 or hit max loops */ ++ mov r3, #0 ++while_ack_0: ++ ldr r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR] ++ and r2, r2, #SELFRFSHACK_MASK ++ cmp r2, #SELFRFSHACK_MASK ++ beq ack_1 ++ ++ add r3, #1 ++ cmp r3, #MAX_LOOP_COUNT ++ bne while_ack_0 ++ ++ack_1: ++ mov r1, r3 ++ ++ /* ++ * Execute an ISB instruction to ensure that all of the ++ * CP15 register changes have been committed. ++ */ ++ isb ++ ++ /* ++ * Execute a barrier instruction to ensure that all cache, ++ * TLB and branch predictor maintenance operations issued ++ * by any CPU in the cluster have completed. ++ */ ++ dsb ++ dmb ++ ++ wfi ++ ++ /* Disable self-refresh: set sdr.ctrlgrp.lowpwreq.selfrshreq = 0 */ ++ ldr r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR] ++ bic r2, r2, #SELFRSHREQ_MASK ++ str r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR] ++ ++ /* Poll until sdr.ctrlgrp.lowpwrack.selfrfshack == 0 or hit max loops */ ++ mov r3, #0 ++while_ack_1: ++ ldr r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR] ++ and r2, r2, #SELFRFSHACK_MASK ++ cmp r2, #SELFRFSHACK_MASK ++ bne ack_0 ++ ++ add r3, #1 ++ cmp r3, #MAX_LOOP_COUNT ++ bne while_ack_1 ++ ++ack_0: ++ /* ++ * Prepare return value: ++ * Shift loop count for exiting self refresh into upper 16 bits. ++ * Leave loop count for requesting self refresh in lower 16 bits. ++ */ ++ mov r3, r3, lsl #16 ++ add r1, r1, r3 ++ ++ /* Disable dynamic clock gating in the Power Control Register. */ ++ mrc p15, 0, r2, c15, c0, 0 ++ bic r2, r2, #1 ++ mcr p15, 0, r2, c15, c0, 0 ++ ++ mov r0, r1 @ return value ++ bx lr @ return ++ ++ENDPROC(socfpga_sdram_self_refresh) ++ENTRY(socfpga_sdram_self_refresh_sz) ++ .word . - socfpga_sdram_self_refresh +--- a/arch/arm/mach-socfpga/socfpga.c ++++ b/arch/arm/mach-socfpga/socfpga.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (C) 2012 Altera Corporation ++ * Copyright (C) 2012-2015 Altera Corporation + * + * 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 +@@ -29,6 +29,7 @@ + + void __iomem *sys_manager_base_addr; + void __iomem *rst_manager_base_addr; ++void __iomem *sdr_ctl_base_addr; + unsigned long socfpga_cpu1start_addr; + + void __init socfpga_sysmgr_init(void) +@@ -49,6 +50,9 @@ void __init socfpga_sysmgr_init(void) + + np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); + rst_manager_base_addr = of_iomap(np, 0); ++ ++ np = of_find_compatible_node(NULL, NULL, "altr,sdr-ctl"); ++ sdr_ctl_base_addr = of_iomap(np, 0); + } + + static void __init socfpga_init_irq(void) diff --git a/patches.altera/0023-ARM-dts-socfpga-enable-the-data-and-instruction-pref.patch b/patches.altera/0023-ARM-dts-socfpga-enable-the-data-and-instruction-pref.patch new file mode 100644 index 00000000000000..9f887cab4b7618 --- /dev/null +++ b/patches.altera/0023-ARM-dts-socfpga-enable-the-data-and-instruction-pref.patch @@ -0,0 +1,32 @@ +From b1f0088dc002a07672fb6c862cc7c81a179abb1b Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Thu, 16 Jul 2015 15:48:50 -0500 +Subject: [PATCH 23/39] ARM: dts: socfpga: enable the data and instruction + prefetch for the l2 cache + +Just in case the firmware did not enable data and instruction prefetch in +the L2 cache controller, we enable it in the kernel. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 2211a658620a35f3b3eabdfa2587f46b7abf3ee7) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi +index 80f924deed37..1e3c833dfbd2 100644 +--- a/arch/arm/boot/dts/socfpga.dtsi ++++ b/arch/arm/boot/dts/socfpga.dtsi +@@ -639,6 +639,8 @@ + cache-level = <2>; + arm,tag-latency = <1 1 1>; + arm,data-latency = <2 1 1>; ++ prefetch-data = <1>; ++ prefetch-instr = <1>; + }; + + mmc: dwmmc0@ff704000 { +-- +2.6.2 + diff --git a/patches.altera/0024-ARM-dts-socfpga-use-stdout-path-for-chosen-node.patch b/patches.altera/0024-ARM-dts-socfpga-use-stdout-path-for-chosen-node.patch new file mode 100644 index 00000000000000..b14235a2d3db39 --- /dev/null +++ b/patches.altera/0024-ARM-dts-socfpga-use-stdout-path-for-chosen-node.patch @@ -0,0 +1,93 @@ +From 940016336f7e0cb0a64cf17aa0a0620597ace52f Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Tue, 14 Jul 2015 17:19:02 -0500 +Subject: [PATCH 24/39] ARM: dts: socfpga: use stdout-path for chosen node + +Use stdout-path dts property for kernel console. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit efc1985c8f79ee8259d19a9b6e3df6a07d063669) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga_arria10.dtsi | 5 +++++ + arch/arm/boot/dts/socfpga_arria10_socdk.dtsi | 3 ++- + arch/arm/boot/dts/socfpga_arria5_socdk.dts | 3 ++- + arch/arm/boot/dts/socfpga_cyclone5_socdk.dts | 3 ++- + arch/arm/boot/dts/socfpga_cyclone5_sockit.dts | 3 ++- + 5 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index f5bebdd6d1be..9f25a92a1e48 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -21,6 +21,11 @@ + #address-cells = <1>; + #size-cells = <1>; + ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ }; ++ + cpus { + #address-cells = <1>; + #size-cells = <0>; +diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi +index 94a0709b2fe6..99aa9a1c8af0 100644 +--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi +@@ -21,7 +21,8 @@ + compatible = "altr,socfpga-arria10", "altr,socfpga"; + + chosen { +- bootargs = "console=ttyS0,115200 rootwait"; ++ bootargs = "earlyprintk"; ++ stdout-path = "serial1:115200n8"; + }; + + memory { +diff --git a/arch/arm/boot/dts/socfpga_arria5_socdk.dts b/arch/arm/boot/dts/socfpga_arria5_socdk.dts +index ccaf41742fc3..a75a666032b2 100644 +--- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts ++++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts +@@ -22,7 +22,8 @@ + compatible = "altr,socfpga-arria5", "altr,socfpga"; + + chosen { +- bootargs = "console=ttyS0,115200"; ++ bootargs = "earlyprintk"; ++ stdout-path = "serial0:115200n8"; + }; + + memory { +diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts +index 258865da8f6a..d4d0a28fb331 100644 +--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts ++++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts +@@ -22,7 +22,8 @@ + compatible = "altr,socfpga-cyclone5", "altr,socfpga"; + + chosen { +- bootargs = "console=ttyS0,115200"; ++ bootargs = "earlyprintk"; ++ stdout-path = "serial0:115200n8"; + }; + + memory { +diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts +index 16ea6f5f2ab8..1ab1d6902504 100644 +--- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts ++++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts +@@ -22,7 +22,8 @@ + compatible = "altr,socfpga-cyclone5", "altr,socfpga"; + + chosen { +- bootargs = "console=ttyS0,115200"; ++ bootargs = "earlyprintk"; ++ stdout-path = "serial0:115200n8"; + }; + + memory { +-- +2.6.2 + diff --git a/patches.altera/0025-ARM-socfpga-add-reset-for-the-Arria-10-platform.patch b/patches.altera/0025-ARM-socfpga-add-reset-for-the-Arria-10-platform.patch new file mode 100644 index 00000000000000..de8496c282d659 --- /dev/null +++ b/patches.altera/0025-ARM-socfpga-add-reset-for-the-Arria-10-platform.patch @@ -0,0 +1,72 @@ +From e6929c08d62da19eb9860819f94d406b3b611329 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Mon, 20 Jul 2015 11:23:13 -0500 +Subject: [PATCH 25/39] ARM: socfpga: add reset for the Arria 10 platform + +Since the Arria10's reset register offset is different from the Cyclone/Arria 5, +it's best to add a new DT_MACHINE_START() for the Arria10. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit cd871d517d46f26943f3c8f61c0d2ac6665da6a2) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/mach-socfpga/core.h | 1 + + arch/arm/mach-socfpga/socfpga.c | 26 ++++++++++++++++++++++++++ + 2 files changed, 27 insertions(+) + +diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h +index 2484179c2b47..04d187434a6b 100644 +--- a/arch/arm/mach-socfpga/core.h ++++ b/arch/arm/mach-socfpga/core.h +@@ -25,6 +25,7 @@ + #define SOCFPGA_RSTMGR_MODPERRST 0x14 + #define SOCFPGA_RSTMGR_BRGMODRST 0x1c + ++#define SOCFPGA_A10_RSTMGR_CTRL 0xC + #define SOCFPGA_A10_RSTMGR_MODMPURST 0x20 + + /* System Manager bits */ +diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c +index 19643a756c48..a1c0efaa8794 100644 +--- a/arch/arm/mach-socfpga/socfpga.c ++++ b/arch/arm/mach-socfpga/socfpga.c +@@ -74,6 +74,19 @@ static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd) + writel(temp, rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL); + } + ++static void socfpga_arria10_restart(enum reboot_mode mode, const char *cmd) ++{ ++ u32 temp; ++ ++ temp = readl(rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL); ++ ++ if (mode == REBOOT_HARD) ++ temp |= RSTMGR_CTRL_SWCOLDRSTREQ; ++ else ++ temp |= RSTMGR_CTRL_SWWARMRSTREQ; ++ writel(temp, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL); ++} ++ + static const char *altera_dt_match[] = { + "altr,socfpga", + NULL +@@ -86,3 +99,16 @@ DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA") + .restart = socfpga_cyclone5_restart, + .dt_compat = altera_dt_match, + MACHINE_END ++ ++static const char *altera_a10_dt_match[] = { ++ "altr,socfpga-arria10", ++ NULL ++}; ++ ++DT_MACHINE_START(SOCFPGA_A10, "Altera SOCFPGA Arria10") ++ .l2c_aux_val = 0, ++ .l2c_aux_mask = ~0, ++ .init_irq = socfpga_init_irq, ++ .restart = socfpga_arria10_restart, ++ .dt_compat = altera_a10_dt_match, ++MACHINE_END +-- +2.6.2 + diff --git a/patches.altera/0026-ARM-socfpga-dts-Correct-the-parent-clock-for-l3_sp_c.patch b/patches.altera/0026-ARM-socfpga-dts-Correct-the-parent-clock-for-l3_sp_c.patch new file mode 100644 index 00000000000000..5535063cdd53c1 --- /dev/null +++ b/patches.altera/0026-ARM-socfpga-dts-Correct-the-parent-clock-for-l3_sp_c.patch @@ -0,0 +1,44 @@ +From dbc9e4f4f5fa52118578558cbfff17229103a2ed Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Wed, 20 Nov 2013 09:39:17 -0600 +Subject: [PATCH 26/39] ARM: socfpga: dts: Correct the parent clock for + l3_sp_clk and dbg_clk + +The l3_sp_clk's parent should be the l3_mp_clk. This will account for +the extra divider that is present for the l3_mp_clk. + +The dbg_clk's parent should be the dbg_at_clk. This will account for +the extra divider that is present for the dbg_at_clk. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit c5dab6e2c1f7bbf33ec855cebae92a1566ed6d04) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi +index 1e3c833dfbd2..7860935ae3a2 100644 +--- a/arch/arm/boot/dts/socfpga.dtsi ++++ b/arch/arm/boot/dts/socfpga.dtsi +@@ -318,7 +318,7 @@ + l3_sp_clk: l3_sp_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; +- clocks = <&mainclk>; ++ clocks = <&l3_mp_clk>; + div-reg = <0x64 2 2>; + }; + +@@ -349,7 +349,7 @@ + dbg_clk: dbg_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-gate-clk"; +- clocks = <&dbg_base_clk>; ++ clocks = <&dbg_at_clk>; + div-reg = <0x68 2 2>; + clk-gate = <0x60 5>; + }; +-- +2.6.2 + diff --git a/patches.altera/0027-ARM-socfpga-dts-Fix-gpio-dts-entry-for-the-correct-c.patch b/patches.altera/0027-ARM-socfpga-dts-Fix-gpio-dts-entry-for-the-correct-c.patch new file mode 100644 index 00000000000000..325f8b6ace2d1f --- /dev/null +++ b/patches.altera/0027-ARM-socfpga-dts-Fix-gpio-dts-entry-for-the-correct-c.patch @@ -0,0 +1,49 @@ +From 9b0cd899425c09a4b737c25a04c2ea6f63ec8e2c Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Wed, 28 May 2014 22:40:13 -0500 +Subject: [PATCH 27/39] ARM: socfpga: dts: Fix gpio dts entry for the correct + clock + +The correct clock for the HPS gpio(s) should be the l4_mp_clk. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit e9f9fe35f8940c9a4c5deba091d532e3a02bf78b) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi +index 7860935ae3a2..b0acaec3b81a 100644 +--- a/arch/arm/boot/dts/socfpga.dtsi ++++ b/arch/arm/boot/dts/socfpga.dtsi +@@ -565,7 +565,7 @@ + #size-cells = <0>; + compatible = "snps,dw-apb-gpio"; + reg = <0xff708000 0x1000>; +- clocks = <&per_base_clk>; ++ clocks = <&l4_mp_clk>; + status = "disabled"; + + porta: gpio-controller@0 { +@@ -585,7 +585,7 @@ + #size-cells = <0>; + compatible = "snps,dw-apb-gpio"; + reg = <0xff709000 0x1000>; +- clocks = <&per_base_clk>; ++ clocks = <&l4_mp_clk>; + status = "disabled"; + + portb: gpio-controller@0 { +@@ -605,7 +605,7 @@ + #size-cells = <0>; + compatible = "snps,dw-apb-gpio"; + reg = <0xff70a000 0x1000>; +- clocks = <&per_base_clk>; ++ clocks = <&l4_mp_clk>; + status = "disabled"; + + portc: gpio-controller@0 { +-- +2.6.2 + diff --git a/patches.altera/0028-ARM-socfpga-dts-add-osc1-as-a-possible-parent-for-db.patch b/patches.altera/0028-ARM-socfpga-dts-add-osc1-as-a-possible-parent-for-db.patch new file mode 100644 index 00000000000000..7c31785f8350c2 --- /dev/null +++ b/patches.altera/0028-ARM-socfpga-dts-add-osc1-as-a-possible-parent-for-db.patch @@ -0,0 +1,31 @@ +From 4de95d60860e167d40be1a68245075cc16a62ef7 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 24 Jul 2015 22:10:59 -0500 +Subject: [PATCH 28/39] ARM: socfpga: dts: add osc1 as a possible parent for + dbg_base_clk + +The dbg_base_clk can also have osc1 has a parent. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 2e4c7588f6c1d24ae991a85140e05139e953c9b5) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi +index b0acaec3b81a..9bb3b8ac0cb2 100644 +--- a/arch/arm/boot/dts/socfpga.dtsi ++++ b/arch/arm/boot/dts/socfpga.dtsi +@@ -164,7 +164,7 @@ + dbg_base_clk: dbg_base_clk { + #clock-cells = <0>; + compatible = "altr,socfpga-perip-clk"; +- clocks = <&main_pll>; ++ clocks = <&main_pll>, <&osc1>; + div-reg = <0xe8 0 9>; + reg = <0x50>; + }; +-- +2.6.2 + diff --git a/patches.altera/0029-reset-socfpga-Update-reset-socfpga-to-read-the-altr-.patch b/patches.altera/0029-reset-socfpga-Update-reset-socfpga-to-read-the-altr-.patch new file mode 100644 index 00000000000000..e58c714facde5b --- /dev/null +++ b/patches.altera/0029-reset-socfpga-Update-reset-socfpga-to-read-the-altr-.patch @@ -0,0 +1,93 @@ +From 946e3ffb70bff0ffaa5b47538c167fb32920f5ee Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 31 Jul 2015 16:03:10 -0500 +Subject: [PATCH 29/39] reset: socfpga: Update reset-socfpga to read the + altr,modrst-offset property + +In order for the Arria10 to be able to re-use the reset driver for SoCFPGA +Cyclone5/Arria5, we need to read the 'altr,modrst-offset' property from the +device tree entry. The 'altr,modrst-offset' property is the first register +into the reset manager that is used for bringing peripherals out of reset. + +The driver assumes a modrst-offset of 0x10 in order to support legacy +Cyclone5/Arria5 hardware. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 27e44646dc0083c931b71bbb8e179aeb38010d31) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/reset/reset-socfpga.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c +index 0a8def35ea2e..1a6c5d66c83b 100644 +--- a/drivers/reset/reset-socfpga.c ++++ b/drivers/reset/reset-socfpga.c +@@ -24,11 +24,11 @@ + #include <linux/types.h> + + #define NR_BANKS 4 +-#define OFFSET_MODRST 0x10 + + struct socfpga_reset_data { + spinlock_t lock; + void __iomem *membase; ++ u32 modrst_offset; + struct reset_controller_dev rcdev; + }; + +@@ -45,8 +45,8 @@ static int socfpga_reset_assert(struct reset_controller_dev *rcdev, + + spin_lock_irqsave(&data->lock, flags); + +- reg = readl(data->membase + OFFSET_MODRST + (bank * NR_BANKS)); +- writel(reg | BIT(offset), data->membase + OFFSET_MODRST + ++ reg = readl(data->membase + data->modrst_offset + (bank * NR_BANKS)); ++ writel(reg | BIT(offset), data->membase + data->modrst_offset + + (bank * NR_BANKS)); + spin_unlock_irqrestore(&data->lock, flags); + +@@ -67,8 +67,8 @@ static int socfpga_reset_deassert(struct reset_controller_dev *rcdev, + + spin_lock_irqsave(&data->lock, flags); + +- reg = readl(data->membase + OFFSET_MODRST + (bank * NR_BANKS)); +- writel(reg & ~BIT(offset), data->membase + OFFSET_MODRST + ++ reg = readl(data->membase + data->modrst_offset + (bank * NR_BANKS)); ++ writel(reg & ~BIT(offset), data->membase + data->modrst_offset + + (bank * NR_BANKS)); + + spin_unlock_irqrestore(&data->lock, flags); +@@ -85,7 +85,7 @@ static int socfpga_reset_status(struct reset_controller_dev *rcdev, + int offset = id % BITS_PER_LONG; + u32 reg; + +- reg = readl(data->membase + OFFSET_MODRST + (bank * NR_BANKS)); ++ reg = readl(data->membase + data->modrst_offset + (bank * NR_BANKS)); + + return !(reg & BIT(offset)); + } +@@ -100,6 +100,8 @@ static int socfpga_reset_probe(struct platform_device *pdev) + { + struct socfpga_reset_data *data; + struct resource *res; ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; + + /* + * The binding was mainlined without the required property. +@@ -120,6 +122,11 @@ static int socfpga_reset_probe(struct platform_device *pdev) + if (IS_ERR(data->membase)) + return PTR_ERR(data->membase); + ++ if (of_property_read_u32(np, "altr,modrst-offset", &data->modrst_offset)) { ++ dev_warn(dev, "missing altr,modrst-offset property, assuming 0x10!\n"); ++ data->modrst_offset = 0x10; ++ } ++ + spin_lock_init(&data->lock); + + data->rcdev.owner = THIS_MODULE; +-- +2.6.2 + diff --git a/patches.altera/0030-dt-bindings-Add-reset-manager-offsets-for-Arria10.patch b/patches.altera/0030-dt-bindings-Add-reset-manager-offsets-for-Arria10.patch new file mode 100644 index 00000000000000..bf8af3eea98eb0 --- /dev/null +++ b/patches.altera/0030-dt-bindings-Add-reset-manager-offsets-for-Arria10.patch @@ -0,0 +1,135 @@ +From 2105d44605f99793a624f1650b972efcf8ee554b Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 24 Jul 2015 00:01:55 -0500 +Subject: [PATCH 30/39] dt-bindings: Add reset manager offsets for Arria10 + +The reset manager for is pretty similar to the one for SoCFPGA +cyclone5/arria5 except for a few offsets. This patch adds those offsets. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 007bb689b3dbad83cdab0ad192bc6ed0162451e0) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + include/dt-bindings/reset/altr,rst-mgr-a10.h | 110 +++++++++++++++++++++++++++ + 1 file changed, 110 insertions(+) + create mode 100644 include/dt-bindings/reset/altr,rst-mgr-a10.h + +diff --git a/include/dt-bindings/reset/altr,rst-mgr-a10.h b/include/dt-bindings/reset/altr,rst-mgr-a10.h +new file mode 100644 +index 000000000000..acb0bbf4f9f5 +--- /dev/null ++++ b/include/dt-bindings/reset/altr,rst-mgr-a10.h +@@ -0,0 +1,110 @@ ++/* ++ * Copyright (c) 2014, Steffen Trumtrar <s.trumtrar@pengutronix.de> ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ */ ++ ++#ifndef _DT_BINDINGS_RESET_ALTR_RST_MGR_A10_H ++#define _DT_BINDINGS_RESET_ALTR_RST_MGR_A10_H ++ ++/* MPUMODRST */ ++#define CPU0_RESET 0 ++#define CPU1_RESET 1 ++#define WDS_RESET 2 ++#define SCUPER_RESET 3 ++ ++/* PER0MODRST */ ++#define EMAC0_RESET 32 ++#define EMAC1_RESET 33 ++#define EMAC2_RESET 34 ++#define USB0_RESET 35 ++#define USB1_RESET 36 ++#define NAND_RESET 37 ++#define QSPI_RESET 38 ++#define SDMMC_RESET 39 ++#define EMAC0_OCP_RESET 40 ++#define EMAC1_OCP_RESET 41 ++#define EMAC2_OCP_RESET 42 ++#define USB0_OCP_RESET 43 ++#define USB1_OCP_RESET 44 ++#define NAND_OCP_RESET 45 ++#define QSPI_OCP_RESET 46 ++#define SDMMC_OCP_RESET 47 ++#define DMA_RESET 48 ++#define SPIM0_RESET 49 ++#define SPIM1_RESET 50 ++#define SPIS0_RESET 51 ++#define SPIS1_RESET 52 ++#define DMA_OCP_RESET 53 ++#define EMAC_PTP_RESET 54 ++/* 55 is empty*/ ++#define DMAIF0_RESET 56 ++#define DMAIF1_RESET 57 ++#define DMAIF2_RESET 58 ++#define DMAIF3_RESET 59 ++#define DMAIF4_RESET 60 ++#define DMAIF5_RESET 61 ++#define DMAIF6_RESET 62 ++#define DMAIF7_RESET 63 ++ ++/* PER1MODRST */ ++#define L4WD0_RESET 64 ++#define L4WD1_RESET 65 ++#define L4SYSTIMER0_RESET 66 ++#define L4SYSTIMER1_RESET 67 ++#define SPTIMER0_RESET 68 ++#define SPTIMER1_RESET 69 ++/* 70-71 is reserved */ ++#define I2C0_RESET 72 ++#define I2C1_RESET 73 ++#define I2C2_RESET 74 ++#define I2C3_RESET 75 ++#define I2C4_RESET 76 ++/* 77-79 is reserved */ ++#define UART0_RESET 80 ++#define UART1_RESET 81 ++/* 82-87 is reserved */ ++#define GPIO0_RESET 88 ++#define GPIO1_RESET 89 ++#define GPIO2_RESET 90 ++ ++/* BRGMODRST */ ++#define HPS2FPGA_RESET 96 ++#define LWHPS2FPGA_RESET 97 ++#define FPGA2HPS_RESET 98 ++#define F2SSDRAM0_RESET 99 ++#define F2SSDRAM1_RESET 100 ++#define F2SSDRAM2_RESET 101 ++#define DDRSCH_RESET 102 ++ ++/* SYSMODRST*/ ++#define ROM_RESET 128 ++#define OCRAM_RESET 129 ++/* 130 is reserved */ ++#define FPGAMGR_RESET 131 ++#define S2F_RESET 132 ++#define SYSDBG_RESET 133 ++#define OCRAM_OCP_RESET 134 ++ ++/* COLDMODRST */ ++#define CLKMGRCOLD_RESET 160 ++/* 161-162 is reserved */ ++#define S2FCOLD_RESET 163 ++#define TIMESTAMPCOLD_RESET 164 ++#define TAPCOLD_RESET 165 ++#define HMCCOLD_RESET 166 ++#define IOMGRCOLD_RESET 167 ++ ++/* NRSTMODRST */ ++#define NRSTPINOE_RESET 192 ++ ++/* DBGMODRST */ ++#define DBG_RESET 224 ++#endif +-- +2.6.2 + diff --git a/patches.altera/0031-ARM-socfpga-dts-add-altr-modrst-offset-property.patch b/patches.altera/0031-ARM-socfpga-dts-add-altr-modrst-offset-property.patch new file mode 100644 index 00000000000000..0b3a9427c2eddb --- /dev/null +++ b/patches.altera/0031-ARM-socfpga-dts-add-altr-modrst-offset-property.patch @@ -0,0 +1,63 @@ +From 0553f0e52ee98abeb8904ee9621739be981c20ea Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 24 Jul 2015 14:05:06 -0500 +Subject: [PATCH 31/39] ARM: socfpga: dts: add "altr,modrst-offset" property + +The "altr,modrst-offset" property represents the offset into the reset manager +that is the first register to be used by the driver to bring peripherals out +of reset. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 1a94acf858000836d28b13942eebf5cbffc9ac34) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + Documentation/devicetree/bindings/reset/socfpga-reset.txt | 2 ++ + arch/arm/boot/dts/socfpga.dtsi | 1 + + arch/arm/boot/dts/socfpga_arria10.dtsi | 1 + + 3 files changed, 4 insertions(+) + +diff --git a/Documentation/devicetree/bindings/reset/socfpga-reset.txt b/Documentation/devicetree/bindings/reset/socfpga-reset.txt +index 32c1c8bfd5dc..98c9f560e5c5 100644 +--- a/Documentation/devicetree/bindings/reset/socfpga-reset.txt ++++ b/Documentation/devicetree/bindings/reset/socfpga-reset.txt +@@ -3,6 +3,7 @@ Altera SOCFPGA Reset Manager + Required properties: + - compatible : "altr,rst-mgr" + - reg : Should contain 1 register ranges(address and length) ++- altr,modrst-offset : Should contain the offset of the first modrst register. + - #reset-cells: 1 + + Example: +@@ -10,4 +11,5 @@ Example: + #reset-cells = <1>; + compatible = "altr,rst-mgr"; + reg = <0xffd05000 0x1000>; ++ altr,modrst-offset = <0x10>; + }; +diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi +index 9bb3b8ac0cb2..9e1563c39990 100644 +--- a/arch/arm/boot/dts/socfpga.dtsi ++++ b/arch/arm/boot/dts/socfpga.dtsi +@@ -754,6 +754,7 @@ + #reset-cells = <1>; + compatible = "altr,rst-mgr"; + reg = <0xffd05000 0x1000>; ++ altr,modrst-offset = <0x10>; + }; + + usbphy0: usbphy@0 { +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index 9f25a92a1e48..d80ca7a0cc7c 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -582,6 +582,7 @@ + #reset-cells = <1>; + compatible = "altr,rst-mgr"; + reg = <0xffd05000 0x100>; ++ altr,modrst-offset = <0x20>; + }; + + scu: snoop-control-unit@ffffc000 { +-- +2.6.2 + diff --git a/patches.altera/0032-ARM-socfpga-dts-Add-resets-for-EMACs-on-Arria10.patch b/patches.altera/0032-ARM-socfpga-dts-Add-resets-for-EMACs-on-Arria10.patch new file mode 100644 index 00000000000000..a974fe4300527f --- /dev/null +++ b/patches.altera/0032-ARM-socfpga-dts-Add-resets-for-EMACs-on-Arria10.patch @@ -0,0 +1,47 @@ +From 455d260b81cd4dd8d3c55da978ecea6c37695565 Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 24 Jul 2015 15:13:17 -0500 +Subject: [PATCH 32/39] ARM: socfpga: dts: Add resets for EMACs on Arria10 + +Add the reset property for the EMAC controllers on Arria10. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 6855e5b7090330add9521d8947017875d5f4f88e) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/socfpga_arria10.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index d80ca7a0cc7c..bcf3b781a9fc 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -16,6 +16,7 @@ + + #include "skeleton.dtsi" + #include <dt-bindings/interrupt-controller/arm-gic.h> ++#include <dt-bindings/reset/altr,rst-mgr-a10.h> + + / { + #address-cells = <1>; +@@ -414,6 +415,8 @@ + rx-fifo-depth = <16384>; + clocks = <&l4_mp_clk>; + clock-names = "stmmaceth"; ++ resets = <&rst EMAC0_RESET>; ++ reset-names = "stmmaceth"; + status = "disabled"; + }; + +@@ -431,6 +434,8 @@ + rx-fifo-depth = <16384>; + clocks = <&l4_mp_clk>; + clock-names = "stmmaceth"; ++ resets = <&rst EMAC1_RESET>; ++ reset-names = "stmmaceth"; + status = "disabled"; + }; + +-- +2.6.2 + diff --git a/patches.altera/0033-clk-socfpga-Add-a-second-parent-option-for-the-dbg_b.patch b/patches.altera/0033-clk-socfpga-Add-a-second-parent-option-for-the-dbg_b.patch new file mode 100644 index 00000000000000..6c05e33ba537d6 --- /dev/null +++ b/patches.altera/0033-clk-socfpga-Add-a-second-parent-option-for-the-dbg_b.patch @@ -0,0 +1,82 @@ +From 1551fee162675433aecccb9f26d03daa2760e42b Mon Sep 17 00:00:00 2001 +From: Dinh Nguyen <dinguyen@opensource.altera.com> +Date: Fri, 24 Jul 2015 22:30:18 -0500 +Subject: [PATCH 33/39] clk: socfpga: Add a second parent option for the + dbg_base_clk + +The debug base clock can be bypassed from the main PLL to the OSC1 clock. +The bypass register is the staysoc1(0x10) register that is in the clock +manager. + +This patch adds the option to get the correct parent for the debug base +clock. + +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> +(cherry picked from commit 34d5003bfba44a73fe9fbcf75e1d41d130d59bd1) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/clk/socfpga/clk-periph.c | 18 ++++++++++++++---- + drivers/clk/socfpga/clk.h | 1 + + 2 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/socfpga/clk-periph.c b/drivers/clk/socfpga/clk-periph.c +index 46531c34ec9b..8a4932fb83a8 100644 +--- a/drivers/clk/socfpga/clk-periph.c ++++ b/drivers/clk/socfpga/clk-periph.c +@@ -45,8 +45,17 @@ static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk, + return parent_rate / div; + } + ++static u8 clk_periclk_get_parent(struct clk_hw *hwclk) ++{ ++ u32 clk_src; ++ ++ clk_src = readl(clk_mgr_base_addr + CLKMGR_DBCTRL); ++ return clk_src & 0x1; ++} ++ + static const struct clk_ops periclk_ops = { + .recalc_rate = clk_periclk_recalc_rate, ++ .get_parent = clk_periclk_get_parent, + }; + + static __init void __socfpga_periph_init(struct device_node *node, +@@ -56,7 +65,7 @@ static __init void __socfpga_periph_init(struct device_node *node, + struct clk *clk; + struct socfpga_periph_clk *periph_clk; + const char *clk_name = node->name; +- const char *parent_name; ++ const char *parent_name[SOCFPGA_MAX_PARENTS]; + struct clk_init_data init; + int rc; + u32 fixed_div; +@@ -90,9 +99,10 @@ static __init void __socfpga_periph_init(struct device_node *node, + init.name = clk_name; + init.ops = ops; + init.flags = 0; +- parent_name = of_clk_get_parent_name(node, 0); +- init.parent_names = &parent_name; +- init.num_parents = 1; ++ ++ init.num_parents = of_clk_parent_fill(node, parent_name, ++ SOCFPGA_MAX_PARENTS); ++ init.parent_names = parent_name; + + periph_clk->hw.hw.init = &init; + +diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h +index 603973ab7e29..a75f0801a8bb 100644 +--- a/drivers/clk/socfpga/clk.h ++++ b/drivers/clk/socfpga/clk.h +@@ -23,6 +23,7 @@ + /* Clock Manager offsets */ + #define CLKMGR_CTRL 0x0 + #define CLKMGR_BYPASS 0x4 ++#define CLKMGR_DBCTRL 0x10 + #define CLKMGR_L4SRC 0x70 + #define CLKMGR_PERPLL_SRC 0xAC + +-- +2.6.2 + diff --git a/patches.altera/0034-EDAC-altera-Generalize-driver-to-use-DT-Memory-size.patch b/patches.altera/0034-EDAC-altera-Generalize-driver-to-use-DT-Memory-size.patch new file mode 100644 index 00000000000000..4fb3aa784a43d6 --- /dev/null +++ b/patches.altera/0034-EDAC-altera-Generalize-driver-to-use-DT-Memory-size.patch @@ -0,0 +1,114 @@ +From 18e01c2388a965f73b127ee8cc5a2ee8f23250b4 Mon Sep 17 00:00:00 2001 +From: Thor Thayer <tthayer@opensource.altera.com> +Date: Thu, 4 Jun 2015 09:28:45 -0500 +Subject: [PATCH 34/39] EDAC, altera: Generalize driver to use DT Memory size + +The Arria10 SOC uses a completely different SDRAM controller from the +earlier CycloneV and ArriaV SoCs. The memory size is calculated in the +bootloader and passed via the device tree. Using this device tree size +is more generic than using the register fields to calculate the memory +size for different SDRAM controllers. + +Signed-off-by: Thor Thayer <tthayer@opensource.altera.com> +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: devicetree@vger.kernel.org +Cc: dinguyen@opensource.altera.com +Cc: galak@codeaurora.org +Cc: grant.likely@linaro.org +Cc: ijc+devicetree@hellion.org.uk +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-edac <linux-edac@vger.kernel.org> +Cc: m.chehab@samsung.com +Cc: mark.rutland@arm.com +Cc: pawel.moll@arm.com +Cc: robh+dt@kernel.org +Cc: tthayer.linux@gmail.com +Link: http://lkml.kernel.org/r/1433428128-7292-2-git-send-email-tthayer@opensource.altera.com +Signed-off-by: Borislav Petkov <bp@suse.de> +(cherry picked from commit f9ae487e04370e229a96c83a8c86510299712192) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/edac/altera_edac.c | 58 +++++++++++++++++++++------------------------- + 1 file changed, 26 insertions(+), 32 deletions(-) + +diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c +index 3c4929fda9d5..1d55c5b98024 100644 +--- a/drivers/edac/altera_edac.c ++++ b/drivers/edac/altera_edac.c +@@ -219,36 +219,31 @@ static void altr_sdr_mc_create_debugfs_nodes(struct mem_ctl_info *mci) + {} + #endif + +-/* Get total memory size in bytes */ +-static u32 altr_sdram_get_total_mem_size(struct regmap *mc_vbase) ++/* Get total memory size from Open Firmware DTB */ ++static unsigned long get_total_mem(void) + { +- u32 size, read_reg, row, bank, col, cs, width; +- +- if (regmap_read(mc_vbase, DRAMADDRW_OFST, &read_reg) < 0) +- return 0; +- +- if (regmap_read(mc_vbase, DRAMIFWIDTH_OFST, &width) < 0) +- return 0; +- +- col = (read_reg & DRAMADDRW_COLBIT_MASK) >> +- DRAMADDRW_COLBIT_SHIFT; +- row = (read_reg & DRAMADDRW_ROWBIT_MASK) >> +- DRAMADDRW_ROWBIT_SHIFT; +- bank = (read_reg & DRAMADDRW_BANKBIT_MASK) >> +- DRAMADDRW_BANKBIT_SHIFT; +- cs = (read_reg & DRAMADDRW_CSBIT_MASK) >> +- DRAMADDRW_CSBIT_SHIFT; +- +- /* Correct for ECC as its not addressible */ +- if (width == DRAMIFWIDTH_32B_ECC) +- width = 32; +- if (width == DRAMIFWIDTH_16B_ECC) +- width = 16; +- +- /* calculate the SDRAM size base on this info */ +- size = 1 << (row + bank + col); +- size = size * cs * (width / 8); +- return size; ++ struct device_node *np = NULL; ++ const unsigned int *reg, *reg_end; ++ int len, sw, aw; ++ unsigned long start, size, total_mem = 0; ++ ++ for_each_node_by_type(np, "memory") { ++ aw = of_n_addr_cells(np); ++ sw = of_n_size_cells(np); ++ reg = (const unsigned int *)of_get_property(np, "reg", &len); ++ reg_end = reg + (len / sizeof(u32)); ++ ++ total_mem = 0; ++ do { ++ start = of_read_number(reg, aw); ++ reg += aw; ++ size = of_read_number(reg, sw); ++ reg += sw; ++ total_mem += size; ++ } while (reg < reg_end); ++ } ++ edac_dbg(0, "total_mem 0x%lx\n", total_mem); ++ return total_mem; + } + + static int altr_sdram_probe(struct platform_device *pdev) +@@ -280,10 +275,9 @@ static int altr_sdram_probe(struct platform_device *pdev) + } + + /* Grab memory size from device tree. */ +- mem_size = altr_sdram_get_total_mem_size(mc_vbase); ++ mem_size = get_total_mem(); + if (!mem_size) { +- edac_printk(KERN_ERR, EDAC_MC, +- "Unable to calculate memory size\n"); ++ edac_printk(KERN_ERR, EDAC_MC, "Unable to calculate memory size\n"); + return -ENODEV; + } + +-- +2.6.2 + diff --git a/patches.altera/0035-EDAC-altera-Refactor-for-Altera-CycloneV-SoC.patch b/patches.altera/0035-EDAC-altera-Refactor-for-Altera-CycloneV-SoC.patch new file mode 100644 index 00000000000000..c17a3f23702743 --- /dev/null +++ b/patches.altera/0035-EDAC-altera-Refactor-for-Altera-CycloneV-SoC.patch @@ -0,0 +1,478 @@ +From b677a87b67bb7f631e388cbb6e70b1fb75d86811 Mon Sep 17 00:00:00 2001 +From: Thor Thayer <tthayer@opensource.altera.com> +Date: Thu, 4 Jun 2015 09:28:46 -0500 +Subject: [PATCH 35/39] EDAC, altera: Refactor for Altera CycloneV SoC + +The Arria10 SoC uses a completely different SDRAM controller from the +earlier CycloneV and ArriaV SoCs. This patch abstracts the SDRAM bits +for the CycloneV/ArriaV SoCs in preparation for the Arria10 support. + +Signed-off-by: Thor Thayer <tthayer@opensource.altera.com> +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: devicetree@vger.kernel.org +Cc: dinguyen@opensource.altera.com +Cc: galak@codeaurora.org +Cc: grant.likely@linaro.org +Cc: ijc+devicetree@hellion.org.uk +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-edac <linux-edac@vger.kernel.org> +Cc: m.chehab@samsung.com +Cc: mark.rutland@arm.com +Cc: pawel.moll@arm.com +Cc: robh+dt@kernel.org +Cc: tthayer.linux@gmail.com +Link: http://lkml.kernel.org/r/1433428128-7292-3-git-send-email-tthayer@opensource.altera.com +Signed-off-by: Borislav Petkov <bp@suse.de> +(cherry picked from commit 143f4a5ac5af82a4055100c8f40b26187d5c20ba) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/edac/altera_edac.c | 194 +++++++++++++++++++++------------------------ + drivers/edac/altera_edac.h | 116 +++++++++++++++++++++++++++ + 2 files changed, 206 insertions(+), 104 deletions(-) + create mode 100644 drivers/edac/altera_edac.h + +diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c +index 1d55c5b98024..4ac4e6c11ece 100644 +--- a/drivers/edac/altera_edac.c ++++ b/drivers/edac/altera_edac.c +@@ -1,5 +1,5 @@ + /* +- * Copyright Altera Corporation (C) 2014. All rights reserved. ++ * Copyright Altera Corporation (C) 2014-2015. All rights reserved. + * Copyright 2011-2012 Calxeda, Inc. + * + * This program is free software; you can redistribute it and/or modify it +@@ -28,111 +28,64 @@ + #include <linux/types.h> + #include <linux/uaccess.h> + ++#include "altera_edac.h" + #include "edac_core.h" + #include "edac_module.h" + + #define EDAC_MOD_STR "altera_edac" + #define EDAC_VERSION "1" + +-/* SDRAM Controller CtrlCfg Register */ +-#define CTLCFG_OFST 0x00 +- +-/* SDRAM Controller CtrlCfg Register Bit Masks */ +-#define CTLCFG_ECC_EN 0x400 +-#define CTLCFG_ECC_CORR_EN 0x800 +-#define CTLCFG_GEN_SB_ERR 0x2000 +-#define CTLCFG_GEN_DB_ERR 0x4000 +- +-#define CTLCFG_ECC_AUTO_EN (CTLCFG_ECC_EN | \ +- CTLCFG_ECC_CORR_EN) +- +-/* SDRAM Controller Address Width Register */ +-#define DRAMADDRW_OFST 0x2C +- +-/* SDRAM Controller Address Widths Field Register */ +-#define DRAMADDRW_COLBIT_MASK 0x001F +-#define DRAMADDRW_COLBIT_SHIFT 0 +-#define DRAMADDRW_ROWBIT_MASK 0x03E0 +-#define DRAMADDRW_ROWBIT_SHIFT 5 +-#define DRAMADDRW_BANKBIT_MASK 0x1C00 +-#define DRAMADDRW_BANKBIT_SHIFT 10 +-#define DRAMADDRW_CSBIT_MASK 0xE000 +-#define DRAMADDRW_CSBIT_SHIFT 13 +- +-/* SDRAM Controller Interface Data Width Register */ +-#define DRAMIFWIDTH_OFST 0x30 +- +-/* SDRAM Controller Interface Data Width Defines */ +-#define DRAMIFWIDTH_16B_ECC 24 +-#define DRAMIFWIDTH_32B_ECC 40 +- +-/* SDRAM Controller DRAM Status Register */ +-#define DRAMSTS_OFST 0x38 +- +-/* SDRAM Controller DRAM Status Register Bit Masks */ +-#define DRAMSTS_SBEERR 0x04 +-#define DRAMSTS_DBEERR 0x08 +-#define DRAMSTS_CORR_DROP 0x10 +- +-/* SDRAM Controller DRAM IRQ Register */ +-#define DRAMINTR_OFST 0x3C +- +-/* SDRAM Controller DRAM IRQ Register Bit Masks */ +-#define DRAMINTR_INTREN 0x01 +-#define DRAMINTR_SBEMASK 0x02 +-#define DRAMINTR_DBEMASK 0x04 +-#define DRAMINTR_CORRDROPMASK 0x08 +-#define DRAMINTR_INTRCLR 0x10 +- +-/* SDRAM Controller Single Bit Error Count Register */ +-#define SBECOUNT_OFST 0x40 +- +-/* SDRAM Controller Single Bit Error Count Register Bit Masks */ +-#define SBECOUNT_MASK 0x0F +- +-/* SDRAM Controller Double Bit Error Count Register */ +-#define DBECOUNT_OFST 0x44 +- +-/* SDRAM Controller Double Bit Error Count Register Bit Masks */ +-#define DBECOUNT_MASK 0x0F +- +-/* SDRAM Controller ECC Error Address Register */ +-#define ERRADDR_OFST 0x48 +- +-/* SDRAM Controller ECC Error Address Register Bit Masks */ +-#define ERRADDR_MASK 0xFFFFFFFF +- +-/* Altera SDRAM Memory Controller data */ +-struct altr_sdram_mc_data { +- struct regmap *mc_vbase; ++static const struct altr_sdram_prv_data c5_data = { ++ .ecc_ctrl_offset = CV_CTLCFG_OFST, ++ .ecc_ctl_en_mask = CV_CTLCFG_ECC_AUTO_EN, ++ .ecc_stat_offset = CV_DRAMSTS_OFST, ++ .ecc_stat_ce_mask = CV_DRAMSTS_SBEERR, ++ .ecc_stat_ue_mask = CV_DRAMSTS_DBEERR, ++ .ecc_saddr_offset = CV_ERRADDR_OFST, ++ .ecc_cecnt_offset = CV_SBECOUNT_OFST, ++ .ecc_uecnt_offset = CV_DBECOUNT_OFST, ++ .ecc_irq_en_offset = CV_DRAMINTR_OFST, ++ .ecc_irq_en_mask = CV_DRAMINTR_INTREN, ++ .ecc_irq_clr_offset = CV_DRAMINTR_OFST, ++ .ecc_irq_clr_mask = (CV_DRAMINTR_INTRCLR | CV_DRAMINTR_INTREN), ++ .ecc_cnt_rst_offset = CV_DRAMINTR_OFST, ++ .ecc_cnt_rst_mask = CV_DRAMINTR_INTRCLR, ++#ifdef CONFIG_EDAC_DEBUG ++ .ce_ue_trgr_offset = CV_CTLCFG_OFST, ++ .ce_set_mask = CV_CTLCFG_GEN_SB_ERR, ++ .ue_set_mask = CV_CTLCFG_GEN_DB_ERR, ++#endif + }; + + static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id) + { + struct mem_ctl_info *mci = dev_id; + struct altr_sdram_mc_data *drvdata = mci->pvt_info; ++ const struct altr_sdram_prv_data *priv = drvdata->data; + u32 status, err_count, err_addr; + + /* Error Address is shared by both SBE & DBE */ +- regmap_read(drvdata->mc_vbase, ERRADDR_OFST, &err_addr); ++ regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset, &err_addr); + +- regmap_read(drvdata->mc_vbase, DRAMSTS_OFST, &status); ++ regmap_read(drvdata->mc_vbase, priv->ecc_stat_offset, &status); + +- if (status & DRAMSTS_DBEERR) { +- regmap_read(drvdata->mc_vbase, DBECOUNT_OFST, &err_count); ++ if (status & priv->ecc_stat_ue_mask) { ++ regmap_read(drvdata->mc_vbase, priv->ecc_uecnt_offset, ++ &err_count); + panic("\nEDAC: [%d Uncorrectable errors @ 0x%08X]\n", + err_count, err_addr); + } +- if (status & DRAMSTS_SBEERR) { +- regmap_read(drvdata->mc_vbase, SBECOUNT_OFST, &err_count); ++ if (status & priv->ecc_stat_ce_mask) { ++ regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset, ++ &err_count); + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, err_count, + err_addr >> PAGE_SHIFT, + err_addr & ~PAGE_MASK, 0, + 0, 0, -1, mci->ctl_name, ""); + } + +- regmap_write(drvdata->mc_vbase, DRAMINTR_OFST, +- (DRAMINTR_INTRCLR | DRAMINTR_INTREN)); ++ regmap_write(drvdata->mc_vbase, priv->ecc_irq_clr_offset, ++ priv->ecc_irq_clr_mask); + + return IRQ_HANDLED; + } +@@ -144,6 +97,7 @@ static ssize_t altr_sdr_mc_err_inject_write(struct file *file, + { + struct mem_ctl_info *mci = file->private_data; + struct altr_sdram_mc_data *drvdata = mci->pvt_info; ++ const struct altr_sdram_prv_data *priv = drvdata->data; + u32 *ptemp; + dma_addr_t dma_handle; + u32 reg, read_reg; +@@ -156,8 +110,9 @@ static ssize_t altr_sdr_mc_err_inject_write(struct file *file, + return -ENOMEM; + } + +- regmap_read(drvdata->mc_vbase, CTLCFG_OFST, &read_reg); +- read_reg &= ~(CTLCFG_GEN_SB_ERR | CTLCFG_GEN_DB_ERR); ++ regmap_read(drvdata->mc_vbase, priv->ce_ue_trgr_offset, ++ &read_reg); ++ read_reg &= ~(priv->ce_set_mask | priv->ue_set_mask); + + /* Error are injected by writing a word while the SBE or DBE + * bit in the CTLCFG register is set. Reading the word will +@@ -166,20 +121,20 @@ static ssize_t altr_sdr_mc_err_inject_write(struct file *file, + if (count == 3) { + edac_printk(KERN_ALERT, EDAC_MC, + "Inject Double bit error\n"); +- regmap_write(drvdata->mc_vbase, CTLCFG_OFST, +- (read_reg | CTLCFG_GEN_DB_ERR)); ++ regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset, ++ (read_reg | priv->ue_set_mask)); + } else { + edac_printk(KERN_ALERT, EDAC_MC, + "Inject Single bit error\n"); +- regmap_write(drvdata->mc_vbase, CTLCFG_OFST, +- (read_reg | CTLCFG_GEN_SB_ERR)); ++ regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset, ++ (read_reg | priv->ce_set_mask)); + } + + ptemp[0] = 0x5A5A5A5A; + ptemp[1] = 0xA5A5A5A5; + + /* Clear the error injection bits */ +- regmap_write(drvdata->mc_vbase, CTLCFG_OFST, read_reg); ++ regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset, read_reg); + /* Ensure it has been written out */ + wmb(); + +@@ -246,18 +201,29 @@ static unsigned long get_total_mem(void) + return total_mem; + } + ++static const struct of_device_id altr_sdram_ctrl_of_match[] = { ++ { .compatible = "altr,sdram-edac", .data = (void *)&c5_data}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match); ++ + static int altr_sdram_probe(struct platform_device *pdev) + { ++ const struct of_device_id *id; + struct edac_mc_layer layers[2]; + struct mem_ctl_info *mci; + struct altr_sdram_mc_data *drvdata; ++ const struct altr_sdram_prv_data *priv; + struct regmap *mc_vbase; + struct dimm_info *dimm; +- u32 read_reg, mem_size; +- int irq; +- int res = 0; ++ u32 read_reg; ++ int irq, res = 0; ++ unsigned long mem_size; ++ ++ id = of_match_device(altr_sdram_ctrl_of_match, &pdev->dev); ++ if (!id) ++ return -ENODEV; + +- /* Validate the SDRAM controller has ECC enabled */ + /* Grab the register range from the sdr controller in device tree */ + mc_vbase = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "altr,sdr-syscon"); +@@ -267,8 +233,13 @@ static int altr_sdram_probe(struct platform_device *pdev) + return -ENODEV; + } + +- if (regmap_read(mc_vbase, CTLCFG_OFST, &read_reg) || +- ((read_reg & CTLCFG_ECC_AUTO_EN) != CTLCFG_ECC_AUTO_EN)) { ++ /* Check specific dependencies for the module */ ++ priv = of_match_node(altr_sdram_ctrl_of_match, ++ pdev->dev.of_node)->data; ++ ++ /* Validate the SDRAM controller has ECC enabled */ ++ if (regmap_read(mc_vbase, priv->ecc_ctrl_offset, &read_reg) || ++ ((read_reg & priv->ecc_ctl_en_mask) != priv->ecc_ctl_en_mask)) { + edac_printk(KERN_ERR, EDAC_MC, + "No ECC/ECC disabled [0x%08X]\n", read_reg); + return -ENODEV; +@@ -281,10 +252,27 @@ static int altr_sdram_probe(struct platform_device *pdev) + return -ENODEV; + } + +- /* Ensure the SDRAM Interrupt is disabled and cleared */ +- if (regmap_write(mc_vbase, DRAMINTR_OFST, DRAMINTR_INTRCLR)) { ++ /* Ensure the SDRAM Interrupt is disabled */ ++ if (regmap_update_bits(mc_vbase, priv->ecc_irq_en_offset, ++ priv->ecc_irq_en_mask, 0)) { ++ edac_printk(KERN_ERR, EDAC_MC, ++ "Error disabling SDRAM ECC IRQ\n"); ++ return -ENODEV; ++ } ++ ++ /* Toggle to clear the SDRAM Error count */ ++ if (regmap_update_bits(mc_vbase, priv->ecc_cnt_rst_offset, ++ priv->ecc_cnt_rst_mask, ++ priv->ecc_cnt_rst_mask)) { ++ edac_printk(KERN_ERR, EDAC_MC, ++ "Error clearing SDRAM ECC count\n"); ++ return -ENODEV; ++ } ++ ++ if (regmap_update_bits(mc_vbase, priv->ecc_cnt_rst_offset, ++ priv->ecc_cnt_rst_mask, 0)) { + edac_printk(KERN_ERR, EDAC_MC, +- "Error clearing SDRAM ECC IRQ\n"); ++ "Error clearing SDRAM ECC count\n"); + return -ENODEV; + } + +@@ -309,9 +297,12 @@ static int altr_sdram_probe(struct platform_device *pdev) + mci->pdev = &pdev->dev; + drvdata = mci->pvt_info; + drvdata->mc_vbase = mc_vbase; ++ drvdata->data = priv; + platform_set_drvdata(pdev, mci); + + if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) { ++ edac_printk(KERN_ERR, EDAC_MC, ++ "Unable to get managed device resource\n"); + res = -ENOMEM; + goto free; + } +@@ -345,8 +336,9 @@ static int altr_sdram_probe(struct platform_device *pdev) + goto err2; + } + +- if (regmap_write(drvdata->mc_vbase, DRAMINTR_OFST, +- (DRAMINTR_INTRCLR | DRAMINTR_INTREN))) { ++ /* Infrastructure ready - enable the IRQ */ ++ if (regmap_update_bits(drvdata->mc_vbase, priv->ecc_irq_en_offset, ++ priv->ecc_irq_en_mask, priv->ecc_irq_en_mask)) { + edac_mc_printk(mci, KERN_ERR, + "Error enabling SDRAM ECC IRQ\n"); + res = -ENODEV; +@@ -382,12 +374,6 @@ static int altr_sdram_remove(struct platform_device *pdev) + return 0; + } + +-static const struct of_device_id altr_sdram_ctrl_of_match[] = { +- { .compatible = "altr,sdram-edac", }, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match); +- + static struct platform_driver altr_sdram_edac_driver = { + .probe = altr_sdram_probe, + .remove = altr_sdram_remove, +diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h +new file mode 100644 +index 000000000000..b744d914d976 +--- /dev/null ++++ b/drivers/edac/altera_edac.h +@@ -0,0 +1,116 @@ ++/* ++ * ++ * Copyright (C) 2015 Altera Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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/>. ++ */ ++ ++#ifndef _ALTERA_EDAC_H ++#define _ALTERA_EDAC_H ++ ++#include <linux/edac.h> ++#include <linux/types.h> ++ ++/* SDRAM Controller CtrlCfg Register */ ++#define CV_CTLCFG_OFST 0x00 ++ ++/* SDRAM Controller CtrlCfg Register Bit Masks */ ++#define CV_CTLCFG_ECC_EN 0x400 ++#define CV_CTLCFG_ECC_CORR_EN 0x800 ++#define CV_CTLCFG_GEN_SB_ERR 0x2000 ++#define CV_CTLCFG_GEN_DB_ERR 0x4000 ++ ++#define CV_CTLCFG_ECC_AUTO_EN (CV_CTLCFG_ECC_EN | \ ++ CV_CTLCFG_ECC_CORR_EN) ++ ++/* SDRAM Controller Address Width Register */ ++#define CV_DRAMADDRW_OFST 0x2C ++ ++/* SDRAM Controller Address Widths Field Register */ ++#define DRAMADDRW_COLBIT_MASK 0x001F ++#define DRAMADDRW_COLBIT_SHIFT 0 ++#define DRAMADDRW_ROWBIT_MASK 0x03E0 ++#define DRAMADDRW_ROWBIT_SHIFT 5 ++#define CV_DRAMADDRW_BANKBIT_MASK 0x1C00 ++#define CV_DRAMADDRW_BANKBIT_SHIFT 10 ++#define CV_DRAMADDRW_CSBIT_MASK 0xE000 ++#define CV_DRAMADDRW_CSBIT_SHIFT 13 ++ ++/* SDRAM Controller Interface Data Width Register */ ++#define CV_DRAMIFWIDTH_OFST 0x30 ++ ++/* SDRAM Controller Interface Data Width Defines */ ++#define CV_DRAMIFWIDTH_16B_ECC 24 ++#define CV_DRAMIFWIDTH_32B_ECC 40 ++ ++/* SDRAM Controller DRAM Status Register */ ++#define CV_DRAMSTS_OFST 0x38 ++ ++/* SDRAM Controller DRAM Status Register Bit Masks */ ++#define CV_DRAMSTS_SBEERR 0x04 ++#define CV_DRAMSTS_DBEERR 0x08 ++#define CV_DRAMSTS_CORR_DROP 0x10 ++ ++/* SDRAM Controller DRAM IRQ Register */ ++#define CV_DRAMINTR_OFST 0x3C ++ ++/* SDRAM Controller DRAM IRQ Register Bit Masks */ ++#define CV_DRAMINTR_INTREN 0x01 ++#define CV_DRAMINTR_SBEMASK 0x02 ++#define CV_DRAMINTR_DBEMASK 0x04 ++#define CV_DRAMINTR_CORRDROPMASK 0x08 ++#define CV_DRAMINTR_INTRCLR 0x10 ++ ++/* SDRAM Controller Single Bit Error Count Register */ ++#define CV_SBECOUNT_OFST 0x40 ++ ++/* SDRAM Controller Double Bit Error Count Register */ ++#define CV_DBECOUNT_OFST 0x44 ++ ++/* SDRAM Controller ECC Error Address Register */ ++#define CV_ERRADDR_OFST 0x48 ++ ++struct altr_sdram_prv_data { ++ int ecc_ctrl_offset; ++ int ecc_ctl_en_mask; ++ int ecc_cecnt_offset; ++ int ecc_uecnt_offset; ++ int ecc_stat_offset; ++ int ecc_stat_ce_mask; ++ int ecc_stat_ue_mask; ++ int ecc_saddr_offset; ++ int ecc_daddr_offset; ++ int ecc_irq_en_offset; ++ int ecc_irq_en_mask; ++ int ecc_irq_clr_offset; ++ int ecc_irq_clr_mask; ++ int ecc_cnt_rst_offset; ++ int ecc_cnt_rst_mask; ++#ifdef CONFIG_EDAC_DEBUG ++ struct edac_dev_sysfs_attribute *eccmgr_sysfs_attr; ++ int ecc_enable_mask; ++ int ce_set_mask; ++ int ue_set_mask; ++ int ce_ue_trgr_offset; ++#endif ++}; ++ ++/* Altera SDRAM Memory Controller data */ ++struct altr_sdram_mc_data { ++ struct regmap *mc_vbase; ++ int sb_irq; ++ int db_irq; ++ const struct altr_sdram_prv_data *data; ++}; ++ ++#endif /* #ifndef _ALTERA_EDAC_H */ +-- +2.6.2 + diff --git a/patches.altera/0036-EDAC-altera-Add-Arria10-EDAC-support.patch b/patches.altera/0036-EDAC-altera-Add-Arria10-EDAC-support.patch new file mode 100644 index 00000000000000..8b909cbafe40f1 --- /dev/null +++ b/patches.altera/0036-EDAC-altera-Add-Arria10-EDAC-support.patch @@ -0,0 +1,337 @@ +From 55a09d124336781839cfed610e18ea7945782d49 Mon Sep 17 00:00:00 2001 +From: Thor Thayer <tthayer@opensource.altera.com> +Date: Thu, 4 Jun 2015 09:28:47 -0500 +Subject: [PATCH 36/39] EDAC, altera: Add Arria10 EDAC support + +The Arria10 SDRAM and ECC system differs significantly from the +Cyclone5 and Arria5 SoCs. This patch adds support for the Arria10 +SoC. +1) IRQ handler needs to support SHARED IRQ +2) Support sberr and dberr address reporting. + +Signed-off-by: Thor Thayer <tthayer@opensource.altera.com> +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: devicetree@vger.kernel.org +Cc: dinguyen@opensource.altera.com +Cc: galak@codeaurora.org +Cc: grant.likely@linaro.org +Cc: ijc+devicetree@hellion.org.uk +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-edac <linux-edac@vger.kernel.org> +Cc: m.chehab@samsung.com +Cc: mark.rutland@arm.com +Cc: pawel.moll@arm.com +Cc: robh+dt@kernel.org +Cc: tthayer.linux@gmail.com +Link: http://lkml.kernel.org/r/1433428128-7292-4-git-send-email-tthayer@opensource.altera.com +Signed-off-by: Borislav Petkov <bp@suse.de> +(cherry picked from commit 73bcc942f4271fab2ea41e6a3992d3c2164faaa8) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/edac/altera_edac.c | 135 +++++++++++++++++++++++++++++++++++++++------ + drivers/edac/altera_edac.h | 85 ++++++++++++++++++++++++++++ + 2 files changed, 204 insertions(+), 16 deletions(-) + +diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c +index 4ac4e6c11ece..182c741adf3e 100644 +--- a/drivers/edac/altera_edac.c ++++ b/drivers/edac/altera_edac.c +@@ -42,6 +42,7 @@ static const struct altr_sdram_prv_data c5_data = { + .ecc_stat_ce_mask = CV_DRAMSTS_SBEERR, + .ecc_stat_ue_mask = CV_DRAMSTS_DBEERR, + .ecc_saddr_offset = CV_ERRADDR_OFST, ++ .ecc_daddr_offset = CV_ERRADDR_OFST, + .ecc_cecnt_offset = CV_SBECOUNT_OFST, + .ecc_uecnt_offset = CV_DBECOUNT_OFST, + .ecc_irq_en_offset = CV_DRAMINTR_OFST, +@@ -57,37 +58,62 @@ static const struct altr_sdram_prv_data c5_data = { + #endif + }; + ++static const struct altr_sdram_prv_data a10_data = { ++ .ecc_ctrl_offset = A10_ECCCTRL1_OFST, ++ .ecc_ctl_en_mask = A10_ECCCTRL1_ECC_EN, ++ .ecc_stat_offset = A10_INTSTAT_OFST, ++ .ecc_stat_ce_mask = A10_INTSTAT_SBEERR, ++ .ecc_stat_ue_mask = A10_INTSTAT_DBEERR, ++ .ecc_saddr_offset = A10_SERRADDR_OFST, ++ .ecc_daddr_offset = A10_DERRADDR_OFST, ++ .ecc_irq_en_offset = A10_ERRINTEN_OFST, ++ .ecc_irq_en_mask = A10_ECC_IRQ_EN_MASK, ++ .ecc_irq_clr_offset = A10_INTSTAT_OFST, ++ .ecc_irq_clr_mask = (A10_INTSTAT_SBEERR | A10_INTSTAT_DBEERR), ++ .ecc_cnt_rst_offset = A10_ECCCTRL1_OFST, ++ .ecc_cnt_rst_mask = A10_ECC_CNT_RESET_MASK, ++#ifdef CONFIG_EDAC_DEBUG ++ .ce_ue_trgr_offset = A10_DIAGINTTEST_OFST, ++ .ce_set_mask = A10_DIAGINT_TSERRA_MASK, ++ .ue_set_mask = A10_DIAGINT_TDERRA_MASK, ++#endif ++}; ++ + static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id) + { + struct mem_ctl_info *mci = dev_id; + struct altr_sdram_mc_data *drvdata = mci->pvt_info; + const struct altr_sdram_prv_data *priv = drvdata->data; +- u32 status, err_count, err_addr; +- +- /* Error Address is shared by both SBE & DBE */ +- regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset, &err_addr); ++ u32 status, err_count = 1, err_addr; + + regmap_read(drvdata->mc_vbase, priv->ecc_stat_offset, &status); + + if (status & priv->ecc_stat_ue_mask) { +- regmap_read(drvdata->mc_vbase, priv->ecc_uecnt_offset, +- &err_count); ++ regmap_read(drvdata->mc_vbase, priv->ecc_daddr_offset, ++ &err_addr); ++ if (priv->ecc_uecnt_offset) ++ regmap_read(drvdata->mc_vbase, priv->ecc_uecnt_offset, ++ &err_count); + panic("\nEDAC: [%d Uncorrectable errors @ 0x%08X]\n", + err_count, err_addr); + } + if (status & priv->ecc_stat_ce_mask) { +- regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset, +- &err_count); ++ regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset, ++ &err_addr); ++ if (priv->ecc_uecnt_offset) ++ regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset, ++ &err_count); + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, err_count, + err_addr >> PAGE_SHIFT, + err_addr & ~PAGE_MASK, 0, + 0, 0, -1, mci->ctl_name, ""); +- } +- +- regmap_write(drvdata->mc_vbase, priv->ecc_irq_clr_offset, +- priv->ecc_irq_clr_mask); ++ /* Clear IRQ to resume */ ++ regmap_write(drvdata->mc_vbase, priv->ecc_irq_clr_offset, ++ priv->ecc_irq_clr_mask); + +- return IRQ_HANDLED; ++ return IRQ_HANDLED; ++ } ++ return IRQ_NONE; + } + + #ifdef CONFIG_EDAC_DEBUG +@@ -203,10 +229,60 @@ static unsigned long get_total_mem(void) + + static const struct of_device_id altr_sdram_ctrl_of_match[] = { + { .compatible = "altr,sdram-edac", .data = (void *)&c5_data}, ++ { .compatible = "altr,sdram-edac-a10", .data = (void *)&a10_data}, + {}, + }; + MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match); + ++static int a10_init(struct regmap *mc_vbase) ++{ ++ if (regmap_update_bits(mc_vbase, A10_INTMODE_OFST, ++ A10_INTMODE_SB_INT, A10_INTMODE_SB_INT)) { ++ edac_printk(KERN_ERR, EDAC_MC, ++ "Error setting SB IRQ mode\n"); ++ return -ENODEV; ++ } ++ ++ if (regmap_write(mc_vbase, A10_SERRCNTREG_OFST, 1)) { ++ edac_printk(KERN_ERR, EDAC_MC, ++ "Error setting trigger count\n"); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static int a10_unmask_irq(struct platform_device *pdev, u32 mask) ++{ ++ void __iomem *sm_base; ++ int ret = 0; ++ ++ if (!request_mem_region(A10_SYMAN_INTMASK_CLR, sizeof(u32), ++ dev_name(&pdev->dev))) { ++ edac_printk(KERN_ERR, EDAC_MC, ++ "Unable to request mem region\n"); ++ return -EBUSY; ++ } ++ ++ sm_base = ioremap(A10_SYMAN_INTMASK_CLR, sizeof(u32)); ++ if (!sm_base) { ++ edac_printk(KERN_ERR, EDAC_MC, ++ "Unable to ioremap device\n"); ++ ++ ret = -ENOMEM; ++ goto release; ++ } ++ ++ iowrite32(mask, sm_base); ++ ++ iounmap(sm_base); ++ ++release: ++ release_mem_region(A10_SYMAN_INTMASK_CLR, sizeof(u32)); ++ ++ return ret; ++} ++ + static int altr_sdram_probe(struct platform_device *pdev) + { + const struct of_device_id *id; +@@ -217,8 +293,8 @@ static int altr_sdram_probe(struct platform_device *pdev) + struct regmap *mc_vbase; + struct dimm_info *dimm; + u32 read_reg; +- int irq, res = 0; +- unsigned long mem_size; ++ int irq, irq2, res = 0; ++ unsigned long mem_size, irqflags = 0; + + id = of_match_device(altr_sdram_ctrl_of_match, &pdev->dev); + if (!id) +@@ -283,6 +359,9 @@ static int altr_sdram_probe(struct platform_device *pdev) + return -ENODEV; + } + ++ /* Arria10 has a 2nd IRQ */ ++ irq2 = platform_get_irq(pdev, 1); ++ + layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; + layers[0].size = 1; + layers[0].is_virt_csrow = true; +@@ -327,8 +406,32 @@ static int altr_sdram_probe(struct platform_device *pdev) + if (res < 0) + goto err; + ++ /* Only the Arria10 has separate IRQs */ ++ if (irq2 > 0) { ++ /* Arria10 specific initialization */ ++ res = a10_init(mc_vbase); ++ if (res < 0) ++ goto err2; ++ ++ res = devm_request_irq(&pdev->dev, irq2, ++ altr_sdram_mc_err_handler, ++ IRQF_SHARED, dev_name(&pdev->dev), mci); ++ if (res < 0) { ++ edac_mc_printk(mci, KERN_ERR, ++ "Unable to request irq %d\n", irq2); ++ res = -ENODEV; ++ goto err2; ++ } ++ ++ res = a10_unmask_irq(pdev, A10_DDR0_IRQ_MASK); ++ if (res < 0) ++ goto err2; ++ ++ irqflags = IRQF_SHARED; ++ } ++ + res = devm_request_irq(&pdev->dev, irq, altr_sdram_mc_err_handler, +- 0, dev_name(&pdev->dev), mci); ++ irqflags, dev_name(&pdev->dev), mci); + if (res < 0) { + edac_mc_printk(mci, KERN_ERR, + "Unable to request irq %d\n", irq); +diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h +index b744d914d976..7b64dc7c4eb7 100644 +--- a/drivers/edac/altera_edac.h ++++ b/drivers/edac/altera_edac.h +@@ -80,6 +80,91 @@ + /* SDRAM Controller ECC Error Address Register */ + #define CV_ERRADDR_OFST 0x48 + ++/*-----------------------------------------*/ ++ ++/* SDRAM Controller EccCtrl Register */ ++#define A10_ECCCTRL1_OFST 0x00 ++ ++/* SDRAM Controller EccCtrl Register Bit Masks */ ++#define A10_ECCCTRL1_ECC_EN 0x001 ++#define A10_ECCCTRL1_CNT_RST 0x010 ++#define A10_ECCCTRL1_AWB_CNT_RST 0x100 ++#define A10_ECC_CNT_RESET_MASK (A10_ECCCTRL1_CNT_RST | \ ++ A10_ECCCTRL1_AWB_CNT_RST) ++ ++/* SDRAM Controller Address Width Register */ ++#define CV_DRAMADDRW 0xFFC2502C ++#define A10_DRAMADDRW 0xFFCFA0A8 ++ ++/* SDRAM Controller Address Widths Field Register */ ++#define DRAMADDRW_COLBIT_MASK 0x001F ++#define DRAMADDRW_COLBIT_SHIFT 0 ++#define DRAMADDRW_ROWBIT_MASK 0x03E0 ++#define DRAMADDRW_ROWBIT_SHIFT 5 ++#define CV_DRAMADDRW_BANKBIT_MASK 0x1C00 ++#define CV_DRAMADDRW_BANKBIT_SHIFT 10 ++#define CV_DRAMADDRW_CSBIT_MASK 0xE000 ++#define CV_DRAMADDRW_CSBIT_SHIFT 13 ++ ++#define A10_DRAMADDRW_BANKBIT_MASK 0x3C00 ++#define A10_DRAMADDRW_BANKBIT_SHIFT 10 ++#define A10_DRAMADDRW_GRPBIT_MASK 0xC000 ++#define A10_DRAMADDRW_GRPBIT_SHIFT 14 ++#define A10_DRAMADDRW_CSBIT_MASK 0x70000 ++#define A10_DRAMADDRW_CSBIT_SHIFT 16 ++ ++/* SDRAM Controller Interface Data Width Register */ ++#define CV_DRAMIFWIDTH 0xFFC25030 ++#define A10_DRAMIFWIDTH 0xFFCFB008 ++ ++/* SDRAM Controller Interface Data Width Defines */ ++#define CV_DRAMIFWIDTH_16B_ECC 24 ++#define CV_DRAMIFWIDTH_32B_ECC 40 ++ ++#define A10_DRAMIFWIDTH_16B 0x0 ++#define A10_DRAMIFWIDTH_32B 0x1 ++#define A10_DRAMIFWIDTH_64B 0x2 ++ ++/* SDRAM Controller DRAM IRQ Register */ ++#define A10_ERRINTEN_OFST 0x10 ++ ++/* SDRAM Controller DRAM IRQ Register Bit Masks */ ++#define A10_ERRINTEN_SERRINTEN 0x01 ++#define A10_ERRINTEN_DERRINTEN 0x02 ++#define A10_ECC_IRQ_EN_MASK (A10_ERRINTEN_SERRINTEN | \ ++ A10_ERRINTEN_DERRINTEN) ++ ++/* SDRAM Interrupt Mode Register */ ++#define A10_INTMODE_OFST 0x1C ++#define A10_INTMODE_SB_INT 1 ++ ++/* SDRAM Controller Error Status Register */ ++#define A10_INTSTAT_OFST 0x20 ++ ++/* SDRAM Controller Error Status Register Bit Masks */ ++#define A10_INTSTAT_SBEERR 0x01 ++#define A10_INTSTAT_DBEERR 0x02 ++ ++/* SDRAM Controller ECC Error Address Register */ ++#define A10_DERRADDR_OFST 0x2C ++#define A10_SERRADDR_OFST 0x30 ++ ++/* SDRAM Controller ECC Diagnostic Register */ ++#define A10_DIAGINTTEST_OFST 0x24 ++ ++#define A10_DIAGINT_TSERRA_MASK 0x0001 ++#define A10_DIAGINT_TDERRA_MASK 0x0100 ++ ++#define A10_SBERR_IRQ 34 ++#define A10_DBERR_IRQ 32 ++ ++/* SDRAM Single Bit Error Count Compare Set Register */ ++#define A10_SERRCNTREG_OFST 0x3C ++ ++#define A10_SYMAN_INTMASK_CLR 0xFFD06098 ++#define A10_INTMASK_CLR_OFST 0x10 ++#define A10_DDR0_IRQ_MASK BIT(17) ++ + struct altr_sdram_prv_data { + int ecc_ctrl_offset; + int ecc_ctl_en_mask; +-- +2.6.2 + diff --git a/patches.altera/0037-arm-socfpga-dts-Add-Arria10-SDRAM-EDAC-DTS-support.patch b/patches.altera/0037-arm-socfpga-dts-Add-Arria10-SDRAM-EDAC-DTS-support.patch new file mode 100644 index 00000000000000..c19640cb422b33 --- /dev/null +++ b/patches.altera/0037-arm-socfpga-dts-Add-Arria10-SDRAM-EDAC-DTS-support.patch @@ -0,0 +1,69 @@ +From 38ebd6db21176b14e4db3d7d782633f82c7dfbd9 Mon Sep 17 00:00:00 2001 +From: Thor Thayer <tthayer@opensource.altera.com> +Date: Thu, 4 Jun 2015 09:28:48 -0500 +Subject: [PATCH 37/39] arm: socfpga: dts: Add Arria10 SDRAM EDAC DTS support + +Add support for the Arria10 SDRAM EDAC. Update the bindings document for +the new match string. + +Signed-off-by: Thor Thayer <tthayer@opensource.altera.com> +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: devicetree@vger.kernel.org +Cc: dinguyen@opensource.altera.com +Cc: galak@codeaurora.org +Cc: grant.likely@linaro.org +Cc: ijc+devicetree@hellion.org.uk +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-edac <linux-edac@vger.kernel.org> +Cc: m.chehab@samsung.com +Cc: mark.rutland@arm.com +Cc: pawel.moll@arm.com +Cc: robh+dt@kernel.org +Cc: tthayer.linux@gmail.com +Link: http://lkml.kernel.org/r/1433428128-7292-5-git-send-email-tthayer@opensource.altera.com +Signed-off-by: Borislav Petkov <bp@suse.de> +(cherry picked from commit 54b4a8f57848bb08dcbdfba94b9b1ddef1c23358) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + .../devicetree/bindings/arm/altera/socfpga-sdram-edac.txt | 2 +- + arch/arm/boot/dts/socfpga_arria10.dtsi | 11 +++++++++++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-sdram-edac.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-sdram-edac.txt +index d0ce01da5c59..f5ad0ff69fae 100644 +--- a/Documentation/devicetree/bindings/arm/altera/socfpga-sdram-edac.txt ++++ b/Documentation/devicetree/bindings/arm/altera/socfpga-sdram-edac.txt +@@ -2,7 +2,7 @@ Altera SOCFPGA SDRAM Error Detection & Correction [EDAC] + The EDAC accesses a range of registers in the SDRAM controller. + + Required properties: +-- compatible : should contain "altr,sdram-edac"; ++- compatible : should contain "altr,sdram-edac" or "altr,sdram-edac-a10" + - altr,sdr-syscon : phandle of the sdr module + - interrupts : Should contain the SDRAM ECC IRQ in the + appropriate format for the IRQ controller. +diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi +index bcf3b781a9fc..2340fcb2b535 100644 +--- a/arch/arm/boot/dts/socfpga_arria10.dtsi ++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi +@@ -558,6 +558,17 @@ + status = "disabled"; + }; + ++ sdr: sdr@ffc25000 { ++ compatible = "syscon"; ++ reg = <0xffcfb100 0x80>; ++ }; ++ ++ sdramedac { ++ compatible = "altr,sdram-edac-a10"; ++ altr,sdr-syscon = <&sdr>; ++ interrupts = <0 2 4>, <0 0 4>; ++ }; ++ + L2: l2-cache@fffff000 { + compatible = "arm,pl310-cache"; + reg = <0xfffff000 0x1000>; +-- +2.6.2 + diff --git a/patches.altera/0038-EDAC-altera-Do-not-allow-suspend-when-EDAC-is-enable.patch b/patches.altera/0038-EDAC-altera-Do-not-allow-suspend-when-EDAC-is-enable.patch new file mode 100644 index 00000000000000..e7cd3c5499eae2 --- /dev/null +++ b/patches.altera/0038-EDAC-altera-Do-not-allow-suspend-when-EDAC-is-enable.patch @@ -0,0 +1,67 @@ +From d3e8a3bde5d6c4b9df0d7044a884422547a99937 Mon Sep 17 00:00:00 2001 +From: Alan Tull <atull@opensource.altera.com> +Date: Fri, 5 Jun 2015 08:49:15 -0500 +Subject: [PATCH 38/39] EDAC, altera: Do not allow suspend when EDAC is enabled + +Suspend-to-RAM and EDAC support are mutually exclusive on SOCFPGA. If +EDAC is enabled, it will prevent the platform from going into suspend. + +The reason is that the IRQ vectors for OCRAM reside on DDR and in +Suspend-to-RAM mode we're executing out of OCRAM. If an ECC error +occurs, we can't handle it so it was decided to make them mutually +exclusive. + +Signed-off-by: Alan Tull <atull@opensource.altera.com> +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +Cc: dinh.linux@gmail.com +Cc: dougthompson@xmission.com +Cc: linux-edac <linux-edac@vger.kernel.org> +Cc: mchehab@osg.samsung.com +Cc: tthayer@opensource.altera.com +Link: http://lkml.kernel.org/r/1433512155-9906-1-git-send-email-dinguyen@opensource.altera.com +Signed-off-by: Borislav Petkov <bp@suse.de> +(cherry picked from commit 6f2b6422d4787ffa72bd81abdc1b503dbf87a49a) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + drivers/edac/altera_edac.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c +index 182c741adf3e..23ef0917483c 100644 +--- a/drivers/edac/altera_edac.c ++++ b/drivers/edac/altera_edac.c +@@ -477,11 +477,31 @@ static int altr_sdram_remove(struct platform_device *pdev) + return 0; + } + ++/* ++ * If you want to suspend, need to disable EDAC by removing it ++ * from the device tree or defconfig. ++ */ ++#ifdef CONFIG_PM ++static int altr_sdram_prepare(struct device *dev) ++{ ++ pr_err("Suspend not allowed when EDAC is enabled.\n"); ++ ++ return -EPERM; ++} ++ ++static const struct dev_pm_ops altr_sdram_pm_ops = { ++ .prepare = altr_sdram_prepare, ++}; ++#endif ++ + static struct platform_driver altr_sdram_edac_driver = { + .probe = altr_sdram_probe, + .remove = altr_sdram_remove, + .driver = { + .name = "altr_sdram_edac", ++#ifdef CONFIG_PM ++ .pm = &altr_sdram_pm_ops, ++#endif + .of_match_table = altr_sdram_ctrl_of_match, + }, + }; +-- +2.6.2 + diff --git a/patches.altera/0039-ARM-dts-socfpga-Add-support-of-Terasic-DE0-Atlas-boa.patch b/patches.altera/0039-ARM-dts-socfpga-Add-support-of-Terasic-DE0-Atlas-boa.patch new file mode 100644 index 00000000000000..3359223d5f635c --- /dev/null +++ b/patches.altera/0039-ARM-dts-socfpga-Add-support-of-Terasic-DE0-Atlas-boa.patch @@ -0,0 +1,144 @@ +From 41d251e155fb401b459c88e58b0182f3b3a87ca5 Mon Sep 17 00:00:00 2001 +From: Dalon Westergreen <dwesterg@gmail.com> +Date: Wed, 8 Jul 2015 16:48:49 -0700 +Subject: [PATCH 39/39] ARM: dts: socfpga: Add support of Terasic DE0 Atlas + board + +The Terasic DE0 Atlas board is also known as the DE0-Nano board. +This patch adds the DTS board file for the DE0-Nano Sockit board, and not +the DE0 Nano "Development Board". + +Signed-off-by: Dalon Westergreen <dwesterg@gmail.com> +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +(cherry picked from commit 57c0f8c9c45365d167f8606dad7fde9565432b7a) +Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com> +--- + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts | 111 ++++++++++++++++++++++ + 2 files changed, 112 insertions(+) + create mode 100644 arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -497,6 +497,7 @@ dtb-$(CONFIG_ARCH_SOCFPGA) += \ + socfpga_arria5_socdk.dtb \ + socfpga_arria10_socdk_sdmmc.dtb \ + socfpga_cyclone5_socdk.dtb \ ++ socfpga_cyclone5_de0_sockit.dtb \ + socfpga_cyclone5_sockit.dtb \ + socfpga_cyclone5_socrates.dtb \ + socfpga_vt.dtb +--- /dev/null ++++ b/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts +@@ -0,0 +1,111 @@ ++/* ++ * Copyright Altera Corporation (C) 2015. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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/>. ++ */ ++ ++#include "socfpga_cyclone5.dtsi" ++ ++/ { ++ model = "Terasic DE-0(Atlas)"; ++ compatible = "altr,socfpga-cyclone5", "altr,socfpga"; ++ ++ chosen { ++ bootargs = "earlyprintk"; ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ memory { ++ name = "memory"; ++ device_type = "memory"; ++ reg = <0x0 0x40000000>; /* 1GB */ ++ }; ++ ++ aliases { ++ ethernet0 = &gmac1; ++ }; ++ ++ regulator_3_3v: 3-3-v-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ hps0 { ++ label = "hps_led0"; ++ gpios = <&portb 24 0>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++}; ++ ++&gmac1 { ++ status = "okay"; ++ phy-mode = "rgmii"; ++ ++ txd0-skew-ps = <0>; /* -420ps */ ++ txd1-skew-ps = <0>; /* -420ps */ ++ txd2-skew-ps = <0>; /* -420ps */ ++ txd3-skew-ps = <0>; /* -420ps */ ++ rxd0-skew-ps = <420>; /* 0ps */ ++ rxd1-skew-ps = <420>; /* 0ps */ ++ rxd2-skew-ps = <420>; /* 0ps */ ++ rxd3-skew-ps = <420>; /* 0ps */ ++ txen-skew-ps = <0>; /* -420ps */ ++ txc-skew-ps = <1860>; /* 960ps */ ++ rxdv-skew-ps = <420>; /* 0ps */ ++ rxc-skew-ps = <1680>; /* 780ps */ ++ ++ max-frame-size = <3800>; ++}; ++ ++&gpio0 { ++ status = "okay"; ++}; ++ ++&gpio1 { ++ status = "okay"; ++}; ++ ++&gpio2 { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ speed-mode = <0>; ++ ++ adxl345: adxl345@0 { ++ compatible = "adi,adxl345"; ++ reg = <0x53>; ++ ++ interrupt-parent = <&portc>; ++ interrupts = <3 2>; ++ }; ++}; ++ ++&mmc0 { ++ vmmc-supply = <®ulator_3_3v>; ++ vqmmc-supply = <®ulator_3_3v>; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&usb1 { ++ status = "okay"; ++}; @@ -365,8 +365,52 @@ patches.renesas/0336-staging-board-Migrate-away-from-__pm_genpd_name_add_.patch patches.renesas/0337-ARM-dts-fix-gpio-keys-wakeup-source-property.patch ############################################################################# +# Altera patches +# +patches.altera/0001-ARM-socfpga-dts-add-cpu1-start-addr-for-Arria-10.patch +patches.altera/0002-ARM-socfpga-dts-disable-the-sdmmc-and-uart-nodes-in-.patch +patches.altera/0003-ARM-socfpga-dts-enable-UART1-for-the-debug-uart.patch +patches.altera/0004-ARM-socfpga-dts-rename-socdk-board-file-to-socdk_sdm.patch +patches.altera/0005-ARM-socfpga-dts-Add-a-clock-node-for-sdmmc-CIU.patch +patches.altera/0006-ARM-socfpga-dts-Add-multicast-bins-and-unicast-filte.patch +patches.altera/0007-ARM-socfpga-dts-Add-tx-fifo-depth-and-rx-fifo-depth-.patch +patches.altera/0008-ARM-socfpga-dts-add-clocks-to-the-Arria10-platform.patch +patches.altera/0009-ARM-socfpga-Add-support-for-UART1-debug-uart-for-ear.patch +patches.altera/0010-ARM-socfpga-remove-the-need-to-map-uart_io_desc.patch +patches.altera/0011-ARM-socfpga-dts-add-the-a9-scu-node.patch +patches.altera/0012-ARM-socfpga-use-of_iomap-to-map-the-SCU.patch +patches.altera/0013-clk-socfpga-update-clk.h-so-for-Arria10-platform-to-.patch +patches.altera/0014-clk-socfpga-add-a-clock-driver-for-the-Arria-10-plat.patch +patches.altera/0015-ARM-socfpga-dts-add-the-a9-scu-node-for-arria10.patch +patches.altera/0016-ARM-socfpga-dts-add-enable-method-property-for-cpu-n.patch +patches.altera/0017-clk-of-helper-for-filling-parent-clock-array-and-ret.patch +patches.altera/0018-clk-socfpga-make-use-of-of_clk_parent_fill-helper-fu.patch +patches.altera/0019-ARM-socfpga-use-CPU_METHOD_OF_DECLARE-for-socfpga_cy.patch +patches.altera/0020-ARM-socfpga-add-CPU_METHOD_OF_DECLARE-for-Arria-10.patch +patches.altera/0021-ARM-socfpga-dts-enable-ethernet-for-Arria10-devkit.patch +patches.altera/0022-ARM-socfpga-support-suspend-to-ram.patch +patches.altera/0023-ARM-dts-socfpga-enable-the-data-and-instruction-pref.patch +patches.altera/0024-ARM-dts-socfpga-use-stdout-path-for-chosen-node.patch +patches.altera/0025-ARM-socfpga-add-reset-for-the-Arria-10-platform.patch +patches.altera/0026-ARM-socfpga-dts-Correct-the-parent-clock-for-l3_sp_c.patch +patches.altera/0027-ARM-socfpga-dts-Fix-gpio-dts-entry-for-the-correct-c.patch +patches.altera/0028-ARM-socfpga-dts-add-osc1-as-a-possible-parent-for-db.patch +patches.altera/0029-reset-socfpga-Update-reset-socfpga-to-read-the-altr-.patch +patches.altera/0030-dt-bindings-Add-reset-manager-offsets-for-Arria10.patch +patches.altera/0031-ARM-socfpga-dts-add-altr-modrst-offset-property.patch +patches.altera/0032-ARM-socfpga-dts-Add-resets-for-EMACs-on-Arria10.patch +patches.altera/0033-clk-socfpga-Add-a-second-parent-option-for-the-dbg_b.patch +patches.altera/0034-EDAC-altera-Generalize-driver-to-use-DT-Memory-size.patch +patches.altera/0035-EDAC-altera-Refactor-for-Altera-CycloneV-SoC.patch +patches.altera/0036-EDAC-altera-Add-Arria10-EDAC-support.patch +patches.altera/0037-arm-socfpga-dts-Add-Arria10-SDRAM-EDAC-DTS-support.patch +patches.altera/0038-EDAC-altera-Do-not-allow-suspend-when-EDAC-is-enable.patch +patches.altera/0039-ARM-dts-socfpga-Add-support-of-Terasic-DE0-Atlas-boa.patch + +############################################################################# # fixes that go after all of the above # + |