summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2016-07-30 03:43:19 (GMT)
committerMichael Ellerman <mpe@ellerman.id.au>2016-07-30 03:43:19 (GMT)
commit719dbb2df78fc9a40e28392b07cd715bfc5a665c (patch)
tree0bbc3b84b74178d18164f5522ee3715623f94bbe /arch
parentfbef66f0adcddf4475e19f3d09df22fb34e633f6 (diff)
parent9f595fd8b54809fed13fc30906ef1e90a3fcfbc9 (diff)
downloadlinux-719dbb2df78fc9a40e28392b07cd715bfc5a665c.tar.xz
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux into next
Freescale updates from Scott: "Highlights include more 8xx optimizations, device tree updates, and MVME7100 support."
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/Kconfig6
-rw-r--r--arch/powerpc/Kconfig.debug1
-rw-r--r--arch/powerpc/boot/Makefile4
-rw-r--r--arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi1
-rw-r--r--arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi1
-rw-r--r--arch/powerpc/boot/dts/fsl/kmcoge4.dts37
-rw-r--r--arch/powerpc/boot/dts/fsl/mvme7100.dts153
-rw-r--r--arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi2
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040si-post.dtsi49
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi38
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xqds.dtsi38
-rw-r--r--arch/powerpc/boot/dts/fsl/t104xrdb.dtsi38
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi2
-rw-r--r--arch/powerpc/boot/motload-head.S11
-rw-r--r--arch/powerpc/boot/mvme7100.c59
-rw-r--r--arch/powerpc/boot/ppcboot.h2
-rwxr-xr-xarch/powerpc/boot/wrapper5
-rw-r--r--arch/powerpc/configs/86xx-hw.config4
-rw-r--r--arch/powerpc/configs/mpc86xx_basic_defconfig1
-rw-r--r--arch/powerpc/configs/pq2fads_defconfig1
-rw-r--r--arch/powerpc/include/asm/accounting.h24
-rw-r--r--arch/powerpc/include/asm/cputime.h14
-rw-r--r--arch/powerpc/include/asm/exception-64s.h2
-rw-r--r--arch/powerpc/include/asm/fixmap.h7
-rw-r--r--arch/powerpc/include/asm/mmu-8xx.h3
-rw-r--r--arch/powerpc/include/asm/paca.h9
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h24
-rw-r--r--arch/powerpc/include/asm/reg.h1
-rw-r--r--arch/powerpc/include/asm/thread_info.h4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c31
-rw-r--r--arch/powerpc/kernel/entry_32.S17
-rw-r--r--arch/powerpc/kernel/entry_64.S6
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S4
-rw-r--r--arch/powerpc/kernel/head_8xx.S159
-rw-r--r--arch/powerpc/kernel/time.c81
-rw-r--r--arch/powerpc/mm/8xx_mmu.c131
-rw-r--r--arch/powerpc/mm/mmu_decl.h3
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig8
-rw-r--r--arch/powerpc/platforms/86xx/Makefile1
-rw-r--r--arch/powerpc/platforms/86xx/mvme7100.c121
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype1
-rw-r--r--arch/powerpc/sysdev/cpm_common.c22
-rw-r--r--arch/powerpc/sysdev/fsl_85xx_l2ctlr.c8
-rw-r--r--arch/powerpc/xmon/xmon.c14
44 files changed, 940 insertions, 208 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a5e0b47..6a656f8 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -166,6 +166,7 @@ config PPC
select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT
select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
select GENERIC_CPU_AUTOPROBE
+ select HAVE_VIRT_CPU_ACCOUNTING
config GENERIC_CSUM
def_bool CPU_LITTLE_ENDIAN
@@ -1056,6 +1057,11 @@ config CONSISTENT_SIZE
config PIN_TLB
bool "Pinned Kernel TLBs (860 ONLY)"
depends on ADVANCED_OPTIONS && 8xx
+
+config PIN_TLB_IMMR
+ bool "Pinned TLB for IMMR"
+ depends on PIN_TLB
+ default y
endmenu
if PPC64
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index cfe08ea..1710478 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -212,7 +212,6 @@ config PPC_EARLY_DEBUG_40x
config PPC_EARLY_DEBUG_CPM
bool "Early serial debugging for Freescale CPM-based serial ports"
depends on SERIAL_CPM
- select PIN_TLB if PPC_8xx
help
Select this to enable early debugging for Freescale chips
using a CPM-based serial port. This assumes that the bootwrapper
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 00cf88a..4cd612a 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -113,6 +113,7 @@ src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c
src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S
src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
+src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
src-wlib := $(sort $(src-wlib-y))
src-plat := $(sort $(src-plat-y))
@@ -296,6 +297,9 @@ image-$(CONFIG_TQM8560) += cuImage.tqm8560
image-$(CONFIG_SBC8548) += cuImage.sbc8548
image-$(CONFIG_KSI8560) += cuImage.ksi8560
+# Board ports in arch/powerpc/platform/86xx/Kconfig
+image-$(CONFIG_MVME7100) += dtbImage.mvme7100
+
# Board ports in arch/powerpc/platform/embedded6xx/Kconfig
image-$(CONFIG_STORCENTER) += cuImage.storcenter
image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2
diff --git a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
index bc3bf93..88d8423 100644
--- a/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
@@ -51,6 +51,7 @@
serial2 = &serial2;
serial3 = &serial3;
pci0 = &pci0;
+ usb0 = &usb0;
dma0 = &dma0;
dma1 = &dma1;
sdhc = &sdhc;
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
index 8797ce1..f3f968c 100644
--- a/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
@@ -51,6 +51,7 @@
serial2 = &serial2;
serial3 = &serial3;
pci0 = &pci0;
+ usb0 = &usb0;
dma0 = &dma0;
dma1 = &dma1;
sdhc = &sdhc;
diff --git a/arch/powerpc/boot/dts/fsl/kmcoge4.dts b/arch/powerpc/boot/dts/fsl/kmcoge4.dts
index 2d4b64f..ae70a24 100644
--- a/arch/powerpc/boot/dts/fsl/kmcoge4.dts
+++ b/arch/powerpc/boot/dts/fsl/kmcoge4.dts
@@ -106,6 +106,43 @@
sata@221000 {
status = "disabled";
};
+
+ fman0: fman@400000 {
+ enet0: ethernet@e0000 {
+ phy-connection-type = "sgmii";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ mdio0: mdio@e1120 {
+ front_phy: ethernet-phy@11 {
+ reg = <0x11>;
+ };
+ };
+
+ enet1: ethernet@e2000 {
+ phy-connection-type = "sgmii";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ enet2: ethernet@e4000 {
+ status = "disabled";
+ };
+
+ enet3: ethernet@e6000 {
+ status = "disabled";
+ };
+ enet4: ethernet@e8000 {
+ phy-handle = <&front_phy>;
+ phy-connection-type = "rgmii";
+ };
+ enet5: ethernet@f0000 {
+ status = "disabled";
+ };
+ };
};
rio: rapidio@ffe0c0000 {
diff --git a/arch/powerpc/boot/dts/fsl/mvme7100.dts b/arch/powerpc/boot/dts/fsl/mvme7100.dts
new file mode 100644
index 0000000..e2d306a
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/mvme7100.dts
@@ -0,0 +1,153 @@
+/*
+ * Device tree source for the Emerson/Artesyn MVME7100
+ *
+ * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
+ *
+ * Author: Alessio Igor Bogani <alessio.bogani@elettra.eu>
+ *
+ * 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.
+ *
+ */
+
+/include/ "mpc8641si-pre.dtsi"
+
+/ {
+ model = "MVME7100";
+ compatible = "artesyn,MVME7100";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>;
+ };
+
+ soc: soc@f1000000 {
+ ranges = <0x00000000 0xf1000000 0x00100000>;
+
+ i2c@3000 {
+ hwmon@4c {
+ compatible = "dallas,max6649";
+ reg = <0x4c>;
+ };
+
+ rtc@68 {
+ status = "disabled";
+ };
+ };
+
+
+ enet0: ethernet@24000 {
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@24520 {
+ phy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+ phy1: ethernet-phy@2 {
+ reg = <2>;
+ };
+ phy2: ethernet-phy@3 {
+ reg = <3>;
+ };
+ phy3: ethernet-phy@4 {
+ reg = <4>;
+ };
+ };
+
+ enet1: ethernet@25000 {
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@25520 {
+ status = "disabled";
+ };
+
+ enet2: ethernet@26000 {
+ phy-handle = <&phy2>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@26520 {
+ status = "disabled";
+ };
+
+ enet3: ethernet@27000 {
+ phy-handle = <&phy3>;
+ phy-connection-type = "rgmii-id";
+ };
+
+ mdio@27520 {
+ status = "disabled";
+ };
+
+ serial1: serial@4600 {
+ status = "disabled";
+ };
+ };
+
+ lbc: localbus@f1005000 {
+ reg = <0xf1005000 0x1000>;
+
+ ranges = <0 0 0xf8000000 0x08000000 // NOR Flash (128MB)
+ 2 0 0xf2030000 0x00010000 // NAND Flash (8GB)
+ 3 0 0xf2400000 0x00080000 // MRAM (512KB)
+ 4 0 0xf2000000 0x00010000 // BCSR
+ 5 0 0xf2010000 0x00010000>; // QUART
+
+ bcsr@4,0 {
+ compatible = "artesyn,mvme7100-bcsr";
+ reg = <4 0 0x10000>;
+ };
+
+ serial@5,1000 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <5 0x1000 0x100>;
+ clock-frequency = <1843200>;
+ interrupts = <11 1 0 0>;
+ };
+
+ serial@5,2000 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <5 0x2000 0x100>;
+ clock-frequency = <1843200>;
+ interrupts = <11 1 0 0>;
+ };
+
+ serial@5,3000 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <5 0x3000 0x100>;
+ clock-frequency = <1843200>;
+ interrupts = <11 1 0 0>;
+ };
+
+ serial@5,4000 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <5 0x4000 0x100>;
+ clock-frequency = <1843200>;
+ interrupts = <11 1 0 0>;
+ };
+ };
+
+ pci0: pcie@f1008000 {
+ status = "disabled";
+ };
+
+ pci1: pcie@f1009000 {
+ status = "disabled";
+ };
+
+ chosen {
+ linux,stdout-path = &serial0;
+ };
+};
+
+/include/ "mpc8641si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi b/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi
index 29dad72..fcc7e5b 100644
--- a/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi
@@ -32,7 +32,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-usb@210000 {
+usb0: usb@210000 {
compatible = "fsl-usb2-dr";
reg = <0x210000 0x1000>;
#address-cells = <1>;
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index 507649e..44e399b 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -607,7 +607,7 @@
/include/ "qoriq-gpio-3.dtsi"
/include/ "qoriq-usb2-mph-0.dtsi"
usb0: usb@210000 {
- compatible = "fsl-usb2-mph-v2.4", "fsl-usb2-mph";
+ compatible = "fsl-usb2-mph-v2.5", "fsl-usb2-mph";
fsl,iommu-parent = <&pamu0>;
fsl,liodn-reg = <&guts 0x520>; /* USB1LIODNR */
phy_type = "utmi";
@@ -615,7 +615,7 @@
};
/include/ "qoriq-usb2-dr-0.dtsi"
usb1: usb@211000 {
- compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr";
+ compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr";
fsl,iommu-parent = <&pamu0>;
fsl,liodn-reg = <&guts 0x524>; /* USB2LIODNR */
dr_mode = "host";
@@ -673,3 +673,48 @@
};
};
};
+
+&qe {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "qe";
+ compatible = "fsl,qe";
+ fsl,qe-num-riscs = <1>;
+ fsl,qe-num-snums = <28>;
+
+ qeic: interrupt-controller@80 {
+ interrupt-controller;
+ compatible = "fsl,qe-ic";
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x80 0x80>;
+ interrupts = <95 2 0 0 94 2 0 0>; //high:79 low:78
+ };
+
+ ucc@2000 {
+ cell-index = <1>;
+ reg = <0x2000 0x200>;
+ interrupts = <32>;
+ interrupt-parent = <&qeic>;
+ };
+
+ ucc@2200 {
+ cell-index = <3>;
+ reg = <0x2200 0x200>;
+ interrupts = <34>;
+ interrupt-parent = <&qeic>;
+ };
+
+ muram@10000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,qe-muram", "fsl,cpm-muram";
+ ranges = <0x0 0x10000 0x6000>;
+
+ data-only@0 {
+ compatible = "fsl,qe-muram-data",
+ "fsl,cpm-muram-data";
+ reg = <0x0 0x6000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi
index 8c7ea6c..863f943 100644
--- a/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi
@@ -212,4 +212,42 @@
0 0x00010000>;
};
};
+
+ qe: qe@ffe140000 {
+ ranges = <0x0 0xf 0xfe140000 0x40000>;
+ reg = <0xf 0xfe140000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+
+ si1: si@700 {
+ compatible = "fsl,t1040-qe-si";
+ reg = <0x700 0x80>;
+ };
+
+ siram1: siram@1000 {
+ compatible = "fsl,t1040-qe-siram";
+ reg = <0x1000 0x800>;
+ };
+
+ ucc_hdlc: ucc@2000 {
+ compatible = "fsl,ucc-hdlc";
+ rx-clock-name = "clk8";
+ tx-clock-name = "clk9";
+ fsl,rx-sync-clock = "rsync_pin";
+ fsl,tx-sync-clock = "tsync_pin";
+ fsl,tx-timeslot-mask = <0xfffffffe>;
+ fsl,rx-timeslot-mask = <0xfffffffe>;
+ fsl,tdm-framer-type = "e1";
+ fsl,tdm-id = <0>;
+ fsl,siram-entry-id = <0>;
+ fsl,tdm-interface;
+ };
+
+ ucc_serial: ucc@2200 {
+ compatible = "fsl,t1040-ucc-uart";
+ port-number = <0>;
+ rx-clock-name = "brg2";
+ tx-clock-name = "brg2";
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/t104xqds.dtsi b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi
index 977af35..2fd4cbe 100644
--- a/arch/powerpc/boot/dts/fsl/t104xqds.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi
@@ -366,4 +366,42 @@
0 0x00010000>;
};
};
+
+ qe: qe@ffe140000 {
+ ranges = <0x0 0xf 0xfe140000 0x40000>;
+ reg = <0xf 0xfe140000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+
+ si1: si@700 {
+ compatible = "fsl,t1040-qe-si";
+ reg = <0x700 0x80>;
+ };
+
+ siram1: siram@1000 {
+ compatible = "fsl,t1040-qe-siram";
+ reg = <0x1000 0x800>;
+ };
+
+ ucc_hdlc: ucc@2000 {
+ compatible = "fsl,ucc-hdlc";
+ rx-clock-name = "clk8";
+ tx-clock-name = "clk9";
+ fsl,rx-sync-clock = "rsync_pin";
+ fsl,tx-sync-clock = "tsync_pin";
+ fsl,tx-timeslot-mask = <0xfffffffe>;
+ fsl,rx-timeslot-mask = <0xfffffffe>;
+ fsl,tdm-framer-type = "e1";
+ fsl,tdm-id = <0>;
+ fsl,siram-entry-id = <0>;
+ fsl,tdm-interface;
+ };
+
+ ucc_serial: ucc@2200 {
+ compatible = "fsl,t1040-ucc-uart";
+ port-number = <0>;
+ rx-clock-name = "brg2";
+ tx-clock-name = "brg2";
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
index 7c4afdb..5fdddbd 100644
--- a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi
@@ -222,4 +222,42 @@
0 0x00010000>;
};
};
+
+ qe: qe@ffe140000 {
+ ranges = <0x0 0xf 0xfe140000 0x40000>;
+ reg = <0xf 0xfe140000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+
+ si1: si@700 {
+ compatible = "fsl,t1040-qe-si";
+ reg = <0x700 0x80>;
+ };
+
+ siram1: siram@1000 {
+ compatible = "fsl,t1040-qe-siram";
+ reg = <0x1000 0x800>;
+ };
+
+ ucc_hdlc: ucc@2000 {
+ compatible = "fsl,ucc-hdlc";
+ rx-clock-name = "clk8";
+ tx-clock-name = "clk9";
+ fsl,rx-sync-clock = "rsync_pin";
+ fsl,tx-sync-clock = "tsync_pin";
+ fsl,tx-timeslot-mask = <0xfffffffe>;
+ fsl,rx-timeslot-mask = <0xfffffffe>;
+ fsl,tdm-framer-type = "e1";
+ fsl,tdm-id = <0>;
+ fsl,siram-entry-id = <0>;
+ fsl,tdm-interface;
+ };
+
+ ucc_serial: ucc@2200 {
+ compatible = "fsl,t1040-ucc-uart";
+ port-number = <0>;
+ rx-clock-name = "brg2";
+ tx-clock-name = "brg2";
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
index 1184a74..038cf8f 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
@@ -56,6 +56,8 @@
pci1 = &pci1;
pci2 = &pci2;
pci3 = &pci3;
+ usb0 = &usb0;
+ usb1 = &usb1;
dma0 = &dma0;
dma1 = &dma1;
dma2 = &dma2;
diff --git a/arch/powerpc/boot/motload-head.S b/arch/powerpc/boot/motload-head.S
new file mode 100644
index 0000000..41cabb4
--- /dev/null
+++ b/arch/powerpc/boot/motload-head.S
@@ -0,0 +1,11 @@
+#include "ppc_asm.h"
+
+ .text
+ .globl _zimage_start
+_zimage_start:
+ mfmsr r10
+ rlwinm r10,r10,0,~(1<<15) /* Clear MSR_EE */
+ sync
+ mtmsr r10
+ isync
+ b _zimage_start_lib
diff --git a/arch/powerpc/boot/mvme7100.c b/arch/powerpc/boot/mvme7100.c
new file mode 100644
index 0000000..8b0a932
--- /dev/null
+++ b/arch/powerpc/boot/mvme7100.c
@@ -0,0 +1,59 @@
+/*
+ * Motload compatibility for the Emerson/Artesyn MVME7100
+ *
+ * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
+ *
+ * Author: Alessio Igor Bogani <alessio.bogani@elettra.eu>
+ *
+ * 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.
+ *
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "cuboot.h"
+
+#define TARGET_86xx
+#define TARGET_HAS_ETH1
+#define TARGET_HAS_ETH2
+#define TARGET_HAS_ETH3
+#include "ppcboot.h"
+
+static bd_t bd;
+
+BSS_STACK(16384);
+
+static void mvme7100_fixups(void)
+{
+ void *devp;
+ unsigned long busfreq = bd.bi_busfreq * 1000000;
+
+ dt_fixup_cpu_clocks(bd.bi_intfreq * 1000000, busfreq / 4, busfreq);
+
+ devp = finddevice("/soc@f1000000");
+ if (devp)
+ setprop(devp, "bus-frequency", &busfreq, sizeof(busfreq));
+
+ devp = finddevice("/soc/serial@4500");
+ if (devp)
+ setprop(devp, "clock-frequency", &busfreq, sizeof(busfreq));
+
+ dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
+
+ dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
+ dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
+ dt_fixup_mac_address_by_alias("ethernet2", bd.bi_enet2addr);
+ dt_fixup_mac_address_by_alias("ethernet3", bd.bi_enet3addr);
+}
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ CUBOOT_INIT();
+ fdt_init(_dtb_start);
+ serial_console_init();
+ platform_ops.fixups = mvme7100_fixups;
+}
diff --git a/arch/powerpc/boot/ppcboot.h b/arch/powerpc/boot/ppcboot.h
index 6ae6f90..453df42 100644
--- a/arch/powerpc/boot/ppcboot.h
+++ b/arch/powerpc/boot/ppcboot.h
@@ -43,7 +43,7 @@ typedef struct bd_info {
unsigned long bi_sramstart; /* start of SRAM memory */
unsigned long bi_sramsize; /* size of SRAM memory */
#if defined(TARGET_8xx) || defined(TARGET_CPM2) || defined(TARGET_85xx) ||\
- defined(TARGET_83xx)
+ defined(TARGET_83xx) || defined(TARGET_86xx)
unsigned long bi_immr_base; /* base of IMMR register */
#endif
#if defined(TARGET_PPC_MPC52xx)
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 6a19fce..6681ec3 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -302,6 +302,11 @@ mvme5100)
platformo="$object/fixed-head.o $object/mvme5100.o"
binary=y
;;
+mvme7100)
+ platformo="$object/motload-head.o $object/mvme7100.o"
+ link_address='0x4000000'
+ binary=y
+ ;;
esac
vmz="$tmpdir/`basename \"$kernel\"`.$ext"
diff --git a/arch/powerpc/configs/86xx-hw.config b/arch/powerpc/configs/86xx-hw.config
index f91f889..d3dd6b8 100644
--- a/arch/powerpc/configs/86xx-hw.config
+++ b/arch/powerpc/configs/86xx-hw.config
@@ -74,9 +74,9 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_NR_UARTS=5
CONFIG_SERIAL_8250_RSA=y
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=5
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250=y
CONFIG_SERIO_LIBPS2=y
diff --git a/arch/powerpc/configs/mpc86xx_basic_defconfig b/arch/powerpc/configs/mpc86xx_basic_defconfig
index 33af5c5..3283f05 100644
--- a/arch/powerpc/configs/mpc86xx_basic_defconfig
+++ b/arch/powerpc/configs/mpc86xx_basic_defconfig
@@ -8,3 +8,4 @@ CONFIG_GEF_SBC610=y
CONFIG_MPC8610_HPCD=y
CONFIG_MPC8641_HPCN=y
CONFIG_SBC8641D=y
+CONFIG_MVME7100=y
diff --git a/arch/powerpc/configs/pq2fads_defconfig b/arch/powerpc/configs/pq2fads_defconfig
index 5432c7a..50b2bad 100644
--- a/arch/powerpc/configs/pq2fads_defconfig
+++ b/arch/powerpc/configs/pq2fads_defconfig
@@ -39,7 +39,6 @@ CONFIG_MTD_CFI_I4=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_BLK_DEV_LOOP=y
-CONFIG_IDE=y
CONFIG_NETDEVICES=y
CONFIG_TUN=y
CONFIG_FS_ENET=y
diff --git a/arch/powerpc/include/asm/accounting.h b/arch/powerpc/include/asm/accounting.h
new file mode 100644
index 0000000..c133246
--- /dev/null
+++ b/arch/powerpc/include/asm/accounting.h
@@ -0,0 +1,24 @@
+/*
+ * Common time accounting prototypes and such for all ppc machines.
+ *
+ * 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.
+ */
+
+#ifndef __POWERPC_ACCOUNTING_H
+#define __POWERPC_ACCOUNTING_H
+
+/* Stuff for accurate time accounting */
+struct cpu_accounting_data {
+ unsigned long user_time; /* accumulated usermode TB ticks */
+ unsigned long system_time; /* accumulated system TB ticks */
+ unsigned long user_time_scaled; /* accumulated usermode SPURR ticks */
+ unsigned long starttime; /* TB value snapshot */
+ unsigned long starttime_user; /* TB value on exit to usermode */
+ unsigned long startspurr; /* SPURR value snapshot */
+ unsigned long utime_sspurr; /* ->user_time when ->startspurr set */
+};
+
+#endif
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h
index e245255..2dfd4fc 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -90,11 +90,10 @@ static inline void setup_cputime_one_jiffy(void)
static inline cputime64_t jiffies64_to_cputime64(const u64 jif)
{
u64 ct;
- u64 sec;
+ u64 sec = jif;
/* have to be a little careful about overflow */
- ct = jif % HZ;
- sec = jif / HZ;
+ ct = do_div(sec, HZ);
if (ct) {
ct *= tb_ticks_per_sec;
do_div(ct, HZ);
@@ -230,7 +229,16 @@ static inline cputime_t clock_t_to_cputime(const unsigned long clk)
#define cputime64_to_clock_t(ct) cputime_to_clock_t((cputime_t)(ct))
+/*
+ * PPC64 uses PACA which is task independent for storing accounting data while
+ * PPC32 uses struct thread_info, therefore at task switch the accounting data
+ * has to be populated in the new task
+ */
+#ifdef CONFIG_PPC64
static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
+#else
+void arch_vtime_task_switch(struct task_struct *tsk);
+#endif
#endif /* __KERNEL__ */
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index c7d2773..bed66e5 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -287,7 +287,7 @@ do_kvm_##n: \
std r0,GPR0(r1); /* save r0 in stackframe */ \
std r10,GPR1(r1); /* save r1 in stackframe */ \
beq 4f; /* if from kernel mode */ \
- ACCOUNT_CPU_USER_ENTRY(r9, r10); \
+ ACCOUNT_CPU_USER_ENTRY(r13, r9, r10); \
SAVE_PPR(area, r9, r10); \
4: EXCEPTION_PROLOG_COMMON_2(area) \
EXCEPTION_PROLOG_COMMON_3(n) \
diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h
index 90f604b..4508b32 100644
--- a/arch/powerpc/include/asm/fixmap.h
+++ b/arch/powerpc/include/asm/fixmap.h
@@ -51,6 +51,13 @@ enum fixed_addresses {
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
+#ifdef CONFIG_PPC_8xx
+ /* For IMMR we need an aligned 512K area */
+#define FIX_IMMR_SIZE (512 * 1024 / PAGE_SIZE)
+ FIX_IMMR_START,
+ FIX_IMMR_BASE = __ALIGN_MASK(FIX_IMMR_START, FIX_IMMR_SIZE - 1) - 1 +
+ FIX_IMMR_SIZE,
+#endif
/* FIX_PCIE_MCFG, */
__end_of_fixed_addresses
};
diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h
index 0a566f1..3e0e492 100644
--- a/arch/powerpc/include/asm/mmu-8xx.h
+++ b/arch/powerpc/include/asm/mmu-8xx.h
@@ -169,6 +169,9 @@ typedef struct {
unsigned int active;
unsigned long vdso_base;
} mm_context_t;
+
+#define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff80000)
+#define VIRT_IMMR_BASE (__fix_to_virt(FIX_IMMR_BASE))
#endif /* !__ASSEMBLY__ */
#if defined(CONFIG_PPC_4K_PAGES)
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 546540b..ad171e9 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -25,6 +25,7 @@
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
#include <asm/kvm_book3s_asm.h>
#endif
+#include <asm/accounting.h>
register struct paca_struct *local_paca asm("r13");
@@ -184,13 +185,7 @@ struct paca_struct {
#endif
/* Stuff for accurate time accounting */
- u64 user_time; /* accumulated usermode TB ticks */
- u64 system_time; /* accumulated system TB ticks */
- u64 user_time_scaled; /* accumulated usermode SPURR ticks */
- u64 starttime; /* TB value snapshot */
- u64 starttime_user; /* TB value on exit to usermode */
- u64 startspurr; /* SPURR value snapshot */
- u64 utime_sspurr; /* ->user_time when ->startspurr set */
+ struct cpu_accounting_data accounting;
u64 stolen_time; /* TB ticks taken by hypervisor */
u64 dtl_ridx; /* read index in dispatch log */
struct dtl_entry *dtl_curr; /* pointer corresponding to dtl_ridx */
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 7b591f9..96b06dc 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -24,27 +24,27 @@
*/
#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-#define ACCOUNT_CPU_USER_ENTRY(ra, rb)
-#define ACCOUNT_CPU_USER_EXIT(ra, rb)
+#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb)
+#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb)
#define ACCOUNT_STOLEN_TIME
#else
-#define ACCOUNT_CPU_USER_ENTRY(ra, rb) \
+#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb) \
MFTB(ra); /* get timebase */ \
- ld rb,PACA_STARTTIME_USER(r13); \
- std ra,PACA_STARTTIME(r13); \
+ PPC_LL rb, ACCOUNT_STARTTIME_USER(ptr); \
+ PPC_STL ra, ACCOUNT_STARTTIME(ptr); \
subf rb,rb,ra; /* subtract start value */ \
- ld ra,PACA_USER_TIME(r13); \
+ PPC_LL ra, ACCOUNT_USER_TIME(ptr); \
add ra,ra,rb; /* add on to user time */ \
- std ra,PACA_USER_TIME(r13); \
+ PPC_STL ra, ACCOUNT_USER_TIME(ptr); \
-#define ACCOUNT_CPU_USER_EXIT(ra, rb) \
+#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb) \
MFTB(ra); /* get timebase */ \
- ld rb,PACA_STARTTIME(r13); \
- std ra,PACA_STARTTIME_USER(r13); \
+ PPC_LL rb, ACCOUNT_STARTTIME(ptr); \
+ PPC_STL ra, ACCOUNT_STARTTIME_USER(ptr); \
subf rb,rb,ra; /* subtract start value */ \
- ld ra,PACA_SYSTEM_TIME(r13); \
+ PPC_LL ra, ACCOUNT_SYSTEM_TIME(ptr); \
add ra,ra,rb; /* add on to system time */ \
- std ra,PACA_SYSTEM_TIME(r13)
+ PPC_STL ra, ACCOUNT_SYSTEM_TIME(ptr)
#ifdef CONFIG_PPC_SPLPAR
#define ACCOUNT_STOLEN_TIME \
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index d7e9ab5..40f3615 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1307,6 +1307,7 @@ static inline unsigned long mfvtb (void)
asm volatile("mfspr %0, %1" : "=r" (rval) : \
"i" (SPRN_TBRU)); rval;})
#endif
+#define mftb() mftbl()
#endif /* !__powerpc64__ */
#define mttbl(v) asm volatile("mttbl %0":: "r"(v))
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 8febc3f..b21bb1f 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -33,6 +33,7 @@
#include <asm/processor.h>
#include <asm/page.h>
#include <linux/stringify.h>
+#include <asm/accounting.h>
/*
* low level task data.
@@ -46,6 +47,9 @@ struct thread_info {
#ifdef CONFIG_LIVEPATCH
unsigned long *livepatch_sp;
#endif
+#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC32)
+ struct cpu_accounting_data accounting;
+#endif
/* low level flags - has atomic operations done on it */
unsigned long flags ____cacheline_aligned_in_smp;
};
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 5b99f95..b89d14c 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -68,6 +68,10 @@
#include "../mm/mmu_decl.h"
#endif
+#ifdef CONFIG_PPC_8xx
+#include <asm/fixmap.h>
+#endif
+
int main(void)
{
DEFINE(THREAD, offsetof(struct task_struct, thread));
@@ -240,13 +244,28 @@ int main(void)
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
DEFINE(PACA_DSCR_DEFAULT, offsetof(struct paca_struct, dscr_default));
- DEFINE(PACA_STARTTIME, offsetof(struct paca_struct, starttime));
- DEFINE(PACA_STARTTIME_USER, offsetof(struct paca_struct, starttime_user));
- DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
- DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
+ DEFINE(ACCOUNT_STARTTIME,
+ offsetof(struct paca_struct, accounting.starttime));
+ DEFINE(ACCOUNT_STARTTIME_USER,
+ offsetof(struct paca_struct, accounting.starttime_user));
+ DEFINE(ACCOUNT_USER_TIME,
+ offsetof(struct paca_struct, accounting.user_time));
+ DEFINE(ACCOUNT_SYSTEM_TIME,
+ offsetof(struct paca_struct, accounting.system_time));
DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost));
DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso));
+#else /* CONFIG_PPC64 */
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+ DEFINE(ACCOUNT_STARTTIME,
+ offsetof(struct thread_info, accounting.starttime));
+ DEFINE(ACCOUNT_STARTTIME_USER,
+ offsetof(struct thread_info, accounting.starttime_user));
+ DEFINE(ACCOUNT_USER_TIME,
+ offsetof(struct thread_info, accounting.user_time));
+ DEFINE(ACCOUNT_SYSTEM_TIME,
+ offsetof(struct thread_info, accounting.system_time));
+#endif
#endif /* CONFIG_PPC64 */
/* RTAS */
@@ -734,5 +753,9 @@ int main(void)
DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER);
+#ifdef CONFIG_PPC_8xx
+ DEFINE(VIRT_IMMR_BASE, (u64)__fix_to_virt(FIX_IMMR_BASE));
+#endif
+
return 0;
}
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 2405631..9899032 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -175,6 +175,12 @@ transfer_to_handler:
addi r12,r12,-1
stw r12,4(r11)
#endif
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+ CURRENT_THREAD_INFO(r9, r1)
+ tophys(r9, r9)
+ ACCOUNT_CPU_USER_ENTRY(r9, r11, r12)
+#endif
+
b 3f
2: /* if from kernel, check interrupted DOZE/NAP mode and
@@ -398,6 +404,13 @@ BEGIN_FTR_SECTION
lwarx r7,0,r1
END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
stwcx. r0,0,r1 /* to clear the reservation */
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+ andi. r4,r8,MSR_PR
+ beq 3f
+ CURRENT_THREAD_INFO(r4, r1)
+ ACCOUNT_CPU_USER_EXIT(r4, r5, r7)
+3:
+#endif
lwz r4,_LINK(r1)
lwz r5,_CCR(r1)
mtlr r4
@@ -769,6 +782,10 @@ restore_user:
andis. r10,r0,DBCR0_IDM@h
bnel- load_dbcr0
#endif
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+ CURRENT_THREAD_INFO(r9, r1)
+ ACCOUNT_CPU_USER_EXIT(r9, r10, r11)
+#endif
b restore
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2e0c565..fcb2887 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -72,7 +72,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
std r0,GPR0(r1)
std r10,GPR1(r1)
beq 2f /* if from kernel mode */
- ACCOUNT_CPU_USER_ENTRY(r10, r11)
+ ACCOUNT_CPU_USER_ENTRY(r13, r10, r11)
2: std r2,GPR2(r1)
std r3,GPR3(r1)
mfcr r2
@@ -246,7 +246,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
ld r4,_LINK(r1)
beq- 1f
- ACCOUNT_CPU_USER_EXIT(r11, r12)
+ ACCOUNT_CPU_USER_EXIT(r13, r11, r12)
BEGIN_FTR_SECTION
HMT_MEDIUM_LOW
@@ -859,7 +859,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
BEGIN_FTR_SECTION
mtspr SPRN_PPR,r2 /* Restore PPR */
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
- ACCOUNT_CPU_USER_EXIT(r2, r4)
+ ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
REST_GPR(13, r1)
1:
mtspr SPRN_SRR1,r3
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 2d3b40f..38a1f96 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -386,7 +386,7 @@ exc_##n##_common: \
std r10,_NIP(r1); /* save SRR0 to stackframe */ \
std r11,_MSR(r1); /* save SRR1 to stackframe */ \
beq 2f; /* if from kernel mode */ \
- ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */ \
+ ACCOUNT_CPU_USER_ENTRY(r13,r10,r11);/* accounting (uses cr0+eq) */ \
2: ld r3,excf+EX_R10(r13); /* get back r10 */ \
ld r4,excf+EX_R11(r13); /* get back r11 */ \
mfspr r5,scratch; /* get back r13 */ \
@@ -1059,7 +1059,7 @@ fast_exception_return:
andi. r6,r10,MSR_PR
REST_2GPRS(6, r1)
beq 1f
- ACCOUNT_CPU_USER_EXIT(r10, r11)
+ ACCOUNT_CPU_USER_EXIT(r13, r10, r11)
ld r0,GPR13(r1)
1: stdcx. r0,0,r1 /* to clear the reservation */
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 80c6947..43ddaae 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -30,6 +30,7 @@
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/ptrace.h>
+#include <asm/fixmap.h>
/* Macro to make the code more readable. */
#ifdef CONFIG_8xx_CPU6
@@ -383,28 +384,57 @@ InstructionTLBMiss:
EXCEPTION_EPILOG_0
rfi
+/*
+ * Bottom part of DataStoreTLBMiss handler for IMMR area
+ * not enough space in the DataStoreTLBMiss area
+ */
+DTLBMissIMMR:
+ mtcr r10
+ /* Set 512k byte guarded page and mark it valid */
+ li r10, MD_PS512K | MD_GUARDED | MD_SVALID
+ MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
+ mfspr r10, SPRN_IMMR /* Get current IMMR */
+ rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */
+ ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
+ _PAGE_PRESENT | _PAGE_NO_CACHE
+ MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
+
+ li r11, RPN_PATTERN
+ mtspr SPRN_DAR, r11 /* Tag DAR */
+ EXCEPTION_EPILOG_0
+ rfi
+
. = 0x1200
DataStoreTLBMiss:
- mtspr SPRN_SPRG_SCRATCH2, r3
EXCEPTION_PROLOG_0
- mfcr r3
+ mfcr r10
/* If we are faulting a kernel address, we have to use the
* kernel page tables.
*/
- mfspr r10, SPRN_MD_EPN
- IS_KERNEL(r11, r10)
+ mfspr r11, SPRN_MD_EPN
+ rlwinm r11, r11, 16, 0xfff8
+#ifndef CONFIG_PIN_TLB_IMMR
+ cmpli cr0, r11, VIRT_IMMR_BASE@h
+#endif
+ cmpli cr7, r11, PAGE_OFFSET@h
+#ifndef CONFIG_PIN_TLB_IMMR
+_ENTRY(DTLBMiss_jmp)
+ beq- DTLBMissIMMR
+#endif
+ bge- cr7, 4f
+
mfspr r11, SPRN_M_TW /* Get level 1 table */
- BRANCH_UNLESS_KERNEL(3f)
- lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
3:
+ mtcr r10
+#ifdef CONFIG_8xx_CPU6
+ mtspr SPRN_SPRG_SCRATCH2, r3
+#endif
+ mfspr r10, SPRN_MD_EPN
/* Insert level 1 index */
rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
- mtcr r11
- bt- 28,DTLBMiss8M /* bit 28 = Large page (8M) */
- mtcr r3
/* We have a pte table, so load fetch the pte from the table.
*/
@@ -452,29 +482,30 @@ DataStoreTLBMiss:
MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
/* Restore registers */
+#ifdef CONFIG_8xx_CPU6
mfspr r3, SPRN_SPRG_SCRATCH2
+#endif
mtspr SPRN_DAR, r11 /* Tag DAR */
EXCEPTION_EPILOG_0
rfi
-DTLBMiss8M:
- mtcr r3
- ori r11, r11, MD_SVALID
- MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
-#ifdef CONFIG_PPC_16K_PAGES
- /*
- * In 16k pages mode, each PGD entry defines a 64M block.
- * Here we select the 8M page within the block.
- */
- rlwimi r11, r10, 0, 0x03800000
-#endif
- rlwinm r10, r11, 0, 0xff800000
+4:
+_ENTRY(DTLBMiss_cmp)
+ cmpli cr0, r11, (PAGE_OFFSET + 0x1800000)@h
+ lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
+ bge- 3b
+
+ mtcr r10
+ /* Set 8M byte page and mark it valid */
+ li r10, MD_PS8MEG | MD_SVALID
+ MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
+ mfspr r10, SPRN_MD_EPN
+ rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
_PAGE_PRESENT
- MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
+ MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
li r11, RPN_PATTERN
- mfspr r3, SPRN_SPRG_SCRATCH2
mtspr SPRN_DAR, r11 /* Tag DAR */
EXCEPTION_EPILOG_0
rfi
@@ -553,12 +584,14 @@ FixupDAR:/* Entry point for dcbx workaround. */
IS_KERNEL(r11, r10)
mfspr r11, SPRN_M_TW /* Get level 1 table */
BRANCH_UNLESS_KERNEL(3f)
+ rlwinm r11, r10, 16, 0xfff8
+_ENTRY(FixupDAR_cmp)
+ cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h
+ blt- cr7, 200f
lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
/* Insert level 1 index */
3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
- mtcr r11
- bt 28,200f /* bit 28 = Large page (8M) */
rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */
/* Insert level 2 index */
rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
@@ -584,8 +617,8 @@ FixupDAR:/* Entry point for dcbx workaround. */
141: mfspr r10,SPRN_SPRG_SCRATCH2
b DARFixed /* Nope, go back to normal TLB processing */
- /* concat physical page address(r11) and page offset(r10) */
-200: rlwimi r11, r10, 0, 32 - (PAGE_SHIFT << 1), 31
+ /* create physical page address from effective address */
+200: tophys(r11, r10)
b 201b
144: mfspr r10, SPRN_DSISR
@@ -763,10 +796,18 @@ start_here:
* virtual to physical. Also, set the cache mode since that is defined
* by TLB entries and perform any additional mapping (like of the IMMR).
* If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
- * 24 Mbytes of data, and the 8M IMMR space. Anything not covered by
+ * 24 Mbytes of data, and the 512k IMMR space. Anything not covered by
* these mappings is mapped by page tables.
*/
initial_mmu:
+ li r8, 0
+ mtspr SPRN_MI_CTR, r8 /* remove PINNED ITLB entries */
+ lis r10, MD_RESETVAL@h
+#ifndef CONFIG_8xx_COPYBACK
+ oris r10, r10, MD_WTDEF@h
+#endif
+ mtspr SPRN_MD_CTR, r10 /* remove PINNED DTLB entries */
+
tlbia /* Invalidate all TLB entries */
/* Always pin the first 8 MB ITLB to prevent ITLB
misses while mucking around with SRR0/SRR1 in asm
@@ -777,34 +818,20 @@ initial_mmu:
mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
#ifdef CONFIG_PIN_TLB
- lis r10, (MD_RSV4I | MD_RESETVAL)@h
- ori r10, r10, 0x1c00
- mr r8, r10
-#else
- lis r10, MD_RESETVAL@h
-#endif
-#ifndef CONFIG_8xx_COPYBACK
- oris r10, r10, MD_WTDEF@h
-#endif
+ oris r10, r10, MD_RSV4I@h
mtspr SPRN_MD_CTR, r10 /* Set data TLB control */
+#endif
- /* Now map the lower 8 Meg into the TLBs. For this quick hack,
- * we can load the instruction and data TLB registers with the
- * same values.
- */
+ /* Now map the lower 8 Meg into the ITLB. */
lis r8, KERNELBASE@h /* Create vaddr for TLB */
ori r8, r8, MI_EVALID /* Mark it valid */
mtspr SPRN_MI_EPN, r8
- mtspr SPRN_MD_EPN, r8
li r8, MI_PS8MEG | (2 << 5) /* Set 8M byte page, APG 2 */
ori r8, r8, MI_SVALID /* Make it valid */
mtspr SPRN_MI_TWC, r8
- li r8, MI_PS8MEG /* Set 8M byte page, APG 0 */
- ori r8, r8, MI_SVALID /* Make it valid */
- mtspr SPRN_MD_TWC, r8
li r8, MI_BOOTINIT /* Create RPN for address 0 */
mtspr SPRN_MI_RPN, r8 /* Store TLB entry */
- mtspr SPRN_MD_RPN, r8
+
lis r8, MI_APG_INIT@h /* Set protection modes */
ori r8, r8, MI_APG_INIT@l
mtspr SPRN_MI_AP, r8
@@ -812,51 +839,25 @@ initial_mmu:
ori r8, r8, MD_APG_INIT@l
mtspr SPRN_MD_AP, r8
- /* Map another 8 MByte at the IMMR to get the processor
+ /* Map a 512k page for the IMMR to get the processor
* internal registers (among other things).
*/
-#ifdef CONFIG_PIN_TLB
- addi r10, r10, 0x0100
+#ifdef CONFIG_PIN_TLB_IMMR
+ ori r10, r10, 0x1c00
mtspr SPRN_MD_CTR, r10
-#endif
+
mfspr r9, 638 /* Get current IMMR */
- andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */
+ andis. r9, r9, 0xfff8 /* Get 512 kbytes boundary */
- mr r8, r9 /* Create vaddr for TLB */
+ lis r8, VIRT_IMMR_BASE@h /* Create vaddr for TLB */
ori r8, r8, MD_EVALID /* Mark it valid */
mtspr SPRN_MD_EPN, r8
- li r8, MD_PS8MEG /* Set 8M byte page */
+ li r8, MD_PS512K | MD_GUARDED /* Set 512k byte page */
ori r8, r8, MD_SVALID /* Make it valid */
mtspr SPRN_MD_TWC, r8
mr r8, r9 /* Create paddr for TLB */
ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
mtspr SPRN_MD_RPN, r8
-
-#ifdef CONFIG_PIN_TLB
- /* Map two more 8M kernel data pages.
- */
- addi r10, r10, 0x0100
- mtspr SPRN_MD_CTR, r10
-
- lis r8, KERNELBASE@h /* Create vaddr for TLB */
- addis r8, r8, 0x0080 /* Add 8M */
- ori r8, r8, MI_EVALID /* Mark it valid */
- mtspr SPRN_MD_EPN, r8
- li r9, MI_PS8MEG /* Set 8M byte page */
- ori r9, r9, MI_SVALID /* Make it valid */
- mtspr SPRN_MD_TWC, r9
- li r11, MI_BOOTINIT /* Create RPN for address 0 */
- addis r11, r11, 0x0080 /* Add 8M */
- mtspr SPRN_MD_RPN, r11
-
- addi r10, r10, 0x0100
- mtspr SPRN_MD_CTR, r10
-
- addis r8, r8, 0x0080 /* Add 8M */
- mtspr SPRN_MD_EPN, r8
- mtspr SPRN_MD_TWC, r9
- addis r11, r11, 0x0080 /* Add 8M */
- mtspr SPRN_MD_RPN, r11
#endif
/* Since the cache is enabled according to the information we
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 6b4d01d..4e7759c 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -167,7 +167,15 @@ DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
cputime_t cputime_one_jiffy;
+#ifdef CONFIG_PPC_SPLPAR
void (*dtl_consumer)(struct dtl_entry *, u64);
+#endif
+
+#ifdef CONFIG_PPC64
+#define get_accounting(tsk) (&get_paca()->accounting)
+#else
+#define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
+#endif
static void calc_cputime_factors(void)
{
@@ -187,7 +195,7 @@ static void calc_cputime_factors(void)
* Read the SPURR on systems that have it, otherwise the PURR,
* or if that doesn't exist return the timebase value passed in.
*/
-static u64 read_spurr(u64 tb)
+static unsigned long read_spurr(unsigned long tb)
{
if (cpu_has_feature(CPU_FTR_SPURR))
return mfspr(SPRN_SPURR);
@@ -250,8 +258,8 @@ static u64 scan_dispatch_log(u64 stop_tb)
void accumulate_stolen_time(void)
{
u64 sst, ust;
-
u8 save_soft_enabled = local_paca->soft_enabled;
+ struct cpu_accounting_data *acct = &local_paca->accounting;
/* We are called early in the exception entry, before
* soft/hard_enabled are sync'ed to the expected state
@@ -261,10 +269,10 @@ void accumulate_stolen_time(void)
*/
local_paca->soft_enabled = 0;
- sst = scan_dispatch_log(local_paca->starttime_user);
- ust = scan_dispatch_log(local_paca->starttime);
- local_paca->system_time -= sst;
- local_paca->user_time -= ust;
+ sst = scan_dispatch_log(acct->starttime_user);
+ ust = scan_dispatch_log(acct->starttime);
+ acct->system_time -= sst;
+ acct->user_time -= ust;
local_paca->stolen_time += ust + sst;
local_paca->soft_enabled = save_soft_enabled;
@@ -276,7 +284,7 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) {
stolen = scan_dispatch_log(stop_tb);
- get_paca()->system_time -= stolen;
+ get_paca()->accounting.system_time -= stolen;
}
stolen += get_paca()->stolen_time;
@@ -296,27 +304,29 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
* Account time for a transition between system, hard irq
* or soft irq state.
*/
-static u64 vtime_delta(struct task_struct *tsk,
- u64 *sys_scaled, u64 *stolen)
+static unsigned long vtime_delta(struct task_struct *tsk,
+ unsigned long *sys_scaled,
+ unsigned long *stolen)
{
- u64 now, nowscaled, deltascaled;
- u64 udelta, delta, user_scaled;
+ unsigned long now, nowscaled, deltascaled;
+ unsigned long udelta, delta, user_scaled;
+ struct cpu_accounting_data *acct = get_accounting(tsk);
WARN_ON_ONCE(!irqs_disabled());
now = mftb();
nowscaled = read_spurr(now);
- get_paca()->system_time += now - get_paca()->starttime;
- get_paca()->starttime = now;
- deltascaled = nowscaled - get_paca()->startspurr;
- get_paca()->startspurr = nowscaled;
+ acct->system_time += now - acct->starttime;
+ acct->starttime = now;
+ deltascaled = nowscaled - acct->startspurr;
+ acct->startspurr = nowscaled;
*stolen = calculate_stolen_time(now);
- delta = get_paca()->system_time;
- get_paca()->system_time = 0;
- udelta = get_paca()->user_time - get_paca()->utime_sspurr;
- get_paca()->utime_sspurr = get_paca()->user_time;
+ delta = acct->system_time;
+ acct->system_time = 0;
+ udelta = acct->user_time - acct->utime_sspurr;
+ acct->utime_sspurr = acct->user_time;
/*
* Because we don't read the SPURR on every kernel entry/exit,
@@ -338,14 +348,14 @@ static u64 vtime_delta(struct task_struct *tsk,
*sys_scaled = deltascaled;
}
}
- get_paca()->user_time_scaled += user_scaled;
+ acct->user_time_scaled += user_scaled;
return delta;
}
void vtime_account_system(struct task_struct *tsk)
{
- u64 delta, sys_scaled, stolen;
+ unsigned long delta, sys_scaled, stolen;
delta = vtime_delta(tsk, &sys_scaled, &stolen);
account_system_time(tsk, 0, delta, sys_scaled);
@@ -356,7 +366,7 @@ EXPORT_SYMBOL_GPL(vtime_account_system);
void vtime_account_idle(struct task_struct *tsk)
{
- u64 delta, sys_scaled, stolen;
+ unsigned long delta, sys_scaled, stolen;
delta = vtime_delta(tsk, &sys_scaled, &stolen);
account_idle_time(delta + stolen);
@@ -374,15 +384,32 @@ void vtime_account_idle(struct task_struct *tsk)
void vtime_account_user(struct task_struct *tsk)
{
cputime_t utime, utimescaled;
+ struct cpu_accounting_data *acct = get_accounting(tsk);
- utime = get_paca()->user_time;
- utimescaled = get_paca()->user_time_scaled;
- get_paca()->user_time = 0;
- get_paca()->user_time_scaled = 0;
- get_paca()->utime_sspurr = 0;
+ utime = acct->user_time;
+ utimescaled = acct->user_time_scaled;
+ acct->user_time = 0;
+ acct->user_time_scaled = 0;
+ acct->utime_sspurr = 0;
account_user_time(tsk, utime, utimescaled);
}
+#ifdef CONFIG_PPC32
+/*
+ * Called from the context switch with interrupts disabled, to charge all
+ * accumulated times to the current process, and to prepare accounting on
+ * the next process.
+ */
+void arch_vtime_task_switch(struct task_struct *prev)
+{
+ struct cpu_accounting_data *acct = get_accounting(current);
+
+ acct->starttime = get_accounting(prev)->starttime;
+ acct->system_time = 0;
+ acct->user_time = 0;
+}
+#endif /* CONFIG_PPC32 */
+
#else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
#define calc_cputime_factors()
#endif
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
index 9491005..6c5025e 100644
--- a/arch/powerpc/mm/8xx_mmu.c
+++ b/arch/powerpc/mm/8xx_mmu.c
@@ -13,62 +13,115 @@
*/
#include <linux/memblock.h>
+#include <asm/fixmap.h>
+#include <asm/code-patching.h>
#include "mmu_decl.h"
+#define IMMR_SIZE (FIX_IMMR_SIZE << PAGE_SHIFT)
+
extern int __map_without_ltlbs;
+
/*
- * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ * Return PA for this VA if it is in IMMR area, or 0
*/
-void __init MMU_init_hw(void)
+phys_addr_t v_block_mapped(unsigned long va)
{
- /* Nothing to do for the time being but keep it similar to other PPC */
+ unsigned long p = PHYS_IMMR_BASE;
+
+ if (__map_without_ltlbs)
+ return 0;
+ if (va >= VIRT_IMMR_BASE && va < VIRT_IMMR_BASE + IMMR_SIZE)
+ return p + va - VIRT_IMMR_BASE;
+ return 0;
+}
+
+/*
+ * Return VA for a given PA or 0 if not mapped
+ */
+unsigned long p_block_mapped(phys_addr_t pa)
+{
+ unsigned long p = PHYS_IMMR_BASE;
+
+ if (__map_without_ltlbs)
+ return 0;
+ if (pa >= p && pa < p + IMMR_SIZE)
+ return VIRT_IMMR_BASE + pa - p;
+ return 0;
}
-#define LARGE_PAGE_SIZE_4M (1<<22)
#define LARGE_PAGE_SIZE_8M (1<<23)
-#define LARGE_PAGE_SIZE_64M (1<<26)
-unsigned long __init mmu_mapin_ram(unsigned long top)
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
{
- unsigned long v, s, mapped;
- phys_addr_t p;
+ /* PIN up to the 3 first 8Mb after IMMR in DTLB table */
+#ifdef CONFIG_PIN_TLB
+ unsigned long ctr = mfspr(SPRN_MD_CTR) & 0xfe000000;
+ unsigned long flags = 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY;
+#ifdef CONFIG_PIN_TLB_IMMR
+ int i = 29;
+#else
+ int i = 28;
+#endif
+ unsigned long addr = 0;
+ unsigned long mem = total_lowmem;
+
+ for (; i < 32 && mem >= LARGE_PAGE_SIZE_8M; i++) {
+ mtspr(SPRN_MD_CTR, ctr | (i << 8));
+ mtspr(SPRN_MD_EPN, (unsigned long)__va(addr) | MD_EVALID);
+ mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID);
+ mtspr(SPRN_MD_RPN, addr | flags | _PAGE_PRESENT);
+ addr += LARGE_PAGE_SIZE_8M;
+ mem -= LARGE_PAGE_SIZE_8M;
+ }
+#endif
+}
- v = KERNELBASE;
- p = 0;
- s = top;
+static void mmu_mapin_immr(void)
+{
+ unsigned long p = PHYS_IMMR_BASE;
+ unsigned long v = VIRT_IMMR_BASE;
+ unsigned long f = pgprot_val(PAGE_KERNEL_NCG);
+ int offset;
- if (__map_without_ltlbs)
- return 0;
+ for (offset = 0; offset < IMMR_SIZE; offset += PAGE_SIZE)
+ map_page(v + offset, p + offset, f);
+}
-#ifdef CONFIG_PPC_4K_PAGES
- while (s >= LARGE_PAGE_SIZE_8M) {
- pmd_t *pmdp;
- unsigned long val = p | MD_PS8MEG;
+/* Address of instructions to patch */
+#ifndef CONFIG_PIN_TLB_IMMR
+extern unsigned int DTLBMiss_jmp;
+#endif
+extern unsigned int DTLBMiss_cmp, FixupDAR_cmp;
- pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
- *pmdp++ = __pmd(val);
- *pmdp++ = __pmd(val + LARGE_PAGE_SIZE_4M);
+void mmu_patch_cmp_limit(unsigned int *addr, unsigned long mapped)
+{
+ unsigned int instr = *addr;
- v += LARGE_PAGE_SIZE_8M;
- p += LARGE_PAGE_SIZE_8M;
- s -= LARGE_PAGE_SIZE_8M;
- }
-#else /* CONFIG_PPC_16K_PAGES */
- while (s >= LARGE_PAGE_SIZE_64M) {
- pmd_t *pmdp;
- unsigned long val = p | MD_PS8MEG;
+ instr &= 0xffff0000;
+ instr |= (unsigned long)__va(mapped) >> 16;
+ patch_instruction(addr, instr);
+}
- pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
- *pmdp++ = __pmd(val);
+unsigned long __init mmu_mapin_ram(unsigned long top)
+{
+ unsigned long mapped;
- v += LARGE_PAGE_SIZE_64M;
- p += LARGE_PAGE_SIZE_64M;
- s -= LARGE_PAGE_SIZE_64M;
- }
+ if (__map_without_ltlbs) {
+ mapped = 0;
+ mmu_mapin_immr();
+#ifndef CONFIG_PIN_TLB_IMMR
+ patch_instruction(&DTLBMiss_jmp, PPC_INST_NOP);
#endif
+ } else {
+ mapped = top & ~(LARGE_PAGE_SIZE_8M - 1);
+ }
- mapped = top - s;
+ mmu_patch_cmp_limit(&DTLBMiss_cmp, mapped);
+ mmu_patch_cmp_limit(&FixupDAR_cmp, mapped);
/* If the size of RAM is not an exact power of two, we may not
* have covered RAM in its entirety with 8 MiB
@@ -77,7 +130,8 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
* coverage with normal-sized pages (or other reasons) do not
* attempt to allocate outside the allowed range.
*/
- memblock_set_current_limit(mapped);
+ if (mapped)
+ memblock_set_current_limit(mapped);
return mapped;
}
@@ -90,13 +144,8 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
*/
BUG_ON(first_memblock_base != 0);
-#ifdef CONFIG_PIN_TLB
/* 8xx can only access 24MB at the moment */
memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000));
-#else
- /* 8xx can only access 8MB at the moment */
- memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
-#endif
}
/*
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 6af6532..f988db6 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -154,9 +154,10 @@ struct tlbcam {
};
#endif
-#if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE)
+#if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE) || defined(CONFIG_PPC_8xx)
/* 6xx have BATS */
/* FSL_BOOKE have TLBCAM */
+/* 8xx have LTLB */
phys_addr_t v_block_mapped(unsigned long va);
unsigned long p_block_mapped(phys_addr_t pa);
#else
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 1afd1e4..37b166e 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -61,6 +61,11 @@ config GEF_SBC610
help
This option enables support for the GE SBC610.
+config MVME7100
+ bool "Artesyn MVME7100"
+ help
+ This option enables support for the Emerson/Artesyn MVME7100 board.
+
endif
config MPC8641
@@ -69,7 +74,8 @@ config MPC8641
select FSL_PCI if PCI
select PPC_UDBG_16550
select MPIC
- default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 || GEF_SBC310 || GEF_PPC9A
+ default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 || GEF_SBC310 || GEF_PPC9A \
+ || MVME7100
config MPC8610
bool
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile
index 2d889ad..01958fe 100644
--- a/arch/powerpc/platforms/86xx/Makefile
+++ b/arch/powerpc/platforms/86xx/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o
obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o
obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o
obj-$(CONFIG_GEF_PPC9A) += gef_ppc9a.o
+obj-$(CONFIG_MVME7100) += mvme7100.o
diff --git a/arch/powerpc/platforms/86xx/mvme7100.c b/arch/powerpc/platforms/86xx/mvme7100.c
new file mode 100644
index 0000000..addb41e
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/mvme7100.c
@@ -0,0 +1,121 @@
+/*
+ * Board setup routines for the Emerson/Artesyn MVME7100
+ *
+ * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A.
+ *
+ * Author: Alessio Igor Bogani <alessio.bogani@elettra.eu>
+ *
+ * Based on earlier code by:
+ *
+ * Ajit Prem <ajit.prem@emerson.com>
+ * Copyright 2008 Emerson
+ *
+ * USB host fixup is borrowed by:
+ *
+ * Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+#include "mpc86xx.h"
+
+#define MVME7100_INTERRUPT_REG_2_OFFSET 0x05
+#define MVME7100_DS1375_MASK 0x40
+#define MVME7100_MAX6649_MASK 0x20
+#define MVME7100_ABORT_MASK 0x10
+
+/*
+ * Setup the architecture
+ */
+static void __init mvme7100_setup_arch(void)
+{
+ struct device_node *bcsr_node;
+ void __iomem *mvme7100_regs = NULL;
+ u8 reg;
+
+ if (ppc_md.progress)
+ ppc_md.progress("mvme7100_setup_arch()", 0);
+
+#ifdef CONFIG_SMP
+ mpc86xx_smp_init();
+#endif
+
+ fsl_pci_assign_primary();
+
+ /* Remap BCSR registers */
+ bcsr_node = of_find_compatible_node(NULL, NULL,
+ "artesyn,mvme7100-bcsr");
+ if (bcsr_node) {
+ mvme7100_regs = of_iomap(bcsr_node, 0);
+ of_node_put(bcsr_node);
+ }
+
+ if (mvme7100_regs) {
+ /* Disable ds1375, max6649, and abort interrupts */
+ reg = readb(mvme7100_regs + MVME7100_INTERRUPT_REG_2_OFFSET);
+ reg |= MVME7100_DS1375_MASK | MVME7100_MAX6649_MASK
+ | MVME7100_ABORT_MASK;
+ writeb(reg, mvme7100_regs + MVME7100_INTERRUPT_REG_2_OFFSET);
+ } else
+ pr_warn("Unable to map board registers\n");
+
+ pr_info("MVME7100 board from Artesyn\n");
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init mvme7100_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "artesyn,MVME7100");
+}
+
+static void mvme7100_usb_host_fixup(struct pci_dev *pdev)
+{
+ unsigned int val;
+
+ if (!machine_is(mvme7100))
+ return;
+
+ /* Ensure only ports 1 & 2 are enabled */
+ pci_read_config_dword(pdev, 0xe0, &val);
+ pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x2);
+
+ /* System clock is 48-MHz Oscillator and EHCI Enabled. */
+ pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+ mvme7100_usb_host_fixup);
+
+machine_arch_initcall(mvme7100, mpc86xx_common_publish_devices);
+
+define_machine(mvme7100) {
+ .name = "MVME7100",
+ .probe = mvme7100_probe,
+ .setup_arch = mvme7100_setup_arch,
+ .init_IRQ = mpc86xx_init_irq,
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .time_init = mpc86xx_time_init,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+};
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 77e9b8d..f32edec 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -1,7 +1,6 @@
config PPC64
bool "64-bit kernel"
default n
- select HAVE_VIRT_CPU_ACCOUNTING
select ZLIB_DEFLATE
help
This option selects whether a 32-bit or a 64-bit kernel
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index 0ac12e5..911456d 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -28,6 +28,7 @@
#include <asm/udbg.h>
#include <asm/io.h>
#include <asm/cpm.h>
+#include <asm/fixmap.h>
#include <soc/fsl/qe/qe.h>
#include <mm/mmu_decl.h>
@@ -37,25 +38,36 @@
#endif
#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
-static u32 __iomem *cpm_udbg_txdesc =
- (u32 __iomem __force *)CONFIG_PPC_EARLY_DEBUG_CPM_ADDR;
+static u32 __iomem *cpm_udbg_txdesc;
+static u8 __iomem *cpm_udbg_txbuf;
static void udbg_putc_cpm(char c)
{
- u8 __iomem *txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
-
if (c == '\n')
udbg_putc_cpm('\r');
while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
;
- out_8(txbuf, c);
+ out_8(cpm_udbg_txbuf, c);
out_be32(&cpm_udbg_txdesc[0], 0xa0000001);
}
void __init udbg_init_cpm(void)
{
+#ifdef CONFIG_PPC_8xx
+ cpm_udbg_txdesc = (u32 __iomem __force *)
+ (CONFIG_PPC_EARLY_DEBUG_CPM_ADDR - PHYS_IMMR_BASE +
+ VIRT_IMMR_BASE);
+ cpm_udbg_txbuf = (u8 __iomem __force *)
+ (in_be32(&cpm_udbg_txdesc[1]) - PHYS_IMMR_BASE +
+ VIRT_IMMR_BASE);
+#else
+ cpm_udbg_txdesc = (u32 __iomem __force *)
+ CONFIG_PPC_EARLY_DEBUG_CPM_ADDR;
+ cpm_udbg_txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
+#endif
+
if (cpm_udbg_txdesc) {
#ifdef CONFIG_CPM2
setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
index 861cebf..c27058e 100644
--- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
@@ -90,12 +90,8 @@ static int mpc85xx_l2ctlr_of_probe(struct platform_device *dev)
}
l2cache_size = *prop;
- if (get_cache_sram_params(&sram_params)) {
- dev_err(&dev->dev,
- "Entire L2 as cache, provide valid sram offset and size\n");
- return -EINVAL;
- }
-
+ if (get_cache_sram_params(&sram_params))
+ return 0; /* fall back to L2 cache only */
rem = l2cache_size % sram_params.sram_size;
ways = LOCK_WAYS_FULL * sram_params.sram_size / l2cache_size;
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 2555233..7605455 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2284,13 +2284,13 @@ static void dump_one_paca(int cpu)
DUMP(p, subcore_sibling_mask, "x");
#endif
- DUMP(p, user_time, "llx");
- DUMP(p, system_time, "llx");
- DUMP(p, user_time_scaled, "llx");
- DUMP(p, starttime, "llx");
- DUMP(p, starttime_user, "llx");
- DUMP(p, startspurr, "llx");
- DUMP(p, utime_sspurr, "llx");
+ DUMP(p, accounting.user_time, "llx");
+ DUMP(p, accounting.system_time, "llx");
+ DUMP(p, accounting.user_time_scaled, "llx");
+ DUMP(p, accounting.starttime, "llx");
+ DUMP(p, accounting.starttime_user, "llx");
+ DUMP(p, accounting.startspurr, "llx");
+ DUMP(p, accounting.utime_sspurr, "llx");
DUMP(p, stolen_time, "llx");
#undef DUMP