mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 18:50:54 +07:00
Merge remote-tracking branch 'scott/next' into next
Scott writes: Highlights include e6500 hardware threading support, an e6500 TLB erratum workaround, corenet error reporting, support for a new board, and some minor fixes.
This commit is contained in:
commit
9287b95ec9
@ -84,3 +84,19 @@ Example:
|
||||
compatible = "fsl,bsc9132qds-fpga", "fsl,fpga-qixis-i2c";
|
||||
reg = <0x66>;
|
||||
};
|
||||
|
||||
* Freescale on-board CPLD
|
||||
|
||||
Some Freescale boards like T1040RDB have an on board CPLD connected.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be a board-specific string like "fsl,<board>-cpld"
|
||||
Example:
|
||||
"fsl,t1040rdb-cpld", "fsl,t1042rdb-cpld", "fsl,t1042rdb_pi-cpld"
|
||||
- reg: should describe CPLD registers
|
||||
|
||||
Example:
|
||||
cpld@3,0 {
|
||||
compatible = "fsl,t1040rdb-cpld";
|
||||
reg = <3 0 0x300>;
|
||||
};
|
||||
|
57
arch/powerpc/boot/dts/t2080rdb.dts
Normal file
57
arch/powerpc/boot/dts/t2080rdb.dts
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* T2080PCIe-RDB Board Device Tree Source
|
||||
*
|
||||
* Copyright 2014 Freescale Semiconductor Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Freescale Semiconductor nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* ALTERNATIVELY, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") as published by the Free Software
|
||||
* Foundation, either version 2 of that License or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/include/ "fsl/t208xsi-pre.dtsi"
|
||||
/include/ "t208xrdb.dtsi"
|
||||
|
||||
/ {
|
||||
model = "fsl,T2080RDB";
|
||||
compatible = "fsl,T2080RDB";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
|
||||
rio: rapidio@ffe0c0000 {
|
||||
reg = <0xf 0xfe0c0000 0 0x11000>;
|
||||
|
||||
port1 {
|
||||
ranges = <0 0 0xc 0x20000000 0 0x10000000>;
|
||||
};
|
||||
port2 {
|
||||
ranges = <0 0 0xc 0x30000000 0 0x10000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/include/ "fsl/t2080si-post.dtsi"
|
184
arch/powerpc/boot/dts/t208xrdb.dtsi
Normal file
184
arch/powerpc/boot/dts/t208xrdb.dtsi
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* T2080PCIe-RDB Board Device Tree Source
|
||||
*
|
||||
* Copyright 2014 Freescale Semiconductor Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Freescale Semiconductor nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* ALTERNATIVELY, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") as published by the Free Software
|
||||
* Foundation, either version 2 of that License or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/ {
|
||||
model = "fsl,T2080RDB";
|
||||
compatible = "fsl,T2080RDB";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
|
||||
ifc: localbus@ffe124000 {
|
||||
reg = <0xf 0xfe124000 0 0x2000>;
|
||||
ranges = <0 0 0xf 0xe8000000 0x08000000
|
||||
2 0 0xf 0xff800000 0x00010000
|
||||
3 0 0xf 0xffdf0000 0x00008000>;
|
||||
|
||||
nor@0,0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x0 0x0 0x8000000>;
|
||||
|
||||
bank-width = <2>;
|
||||
device-width = <1>;
|
||||
};
|
||||
|
||||
nand@1,0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "fsl,ifc-nand";
|
||||
reg = <0x2 0x0 0x10000>;
|
||||
};
|
||||
|
||||
boardctrl: board-control@2,0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "fsl,t2080-cpld";
|
||||
reg = <3 0 0x300>;
|
||||
ranges = <0 3 0 0x300>;
|
||||
};
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
};
|
||||
|
||||
dcsr: dcsr@f00000000 {
|
||||
ranges = <0x00000000 0xf 0x00000000 0x01072000>;
|
||||
};
|
||||
|
||||
soc: soc@ffe000000 {
|
||||
ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
|
||||
reg = <0xf 0xfe000000 0 0x00001000>;
|
||||
spi@110000 {
|
||||
flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "micron,n25q512a";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>; /* input clock */
|
||||
};
|
||||
};
|
||||
|
||||
i2c@118000 {
|
||||
adt7481@4c {
|
||||
compatible = "adi,adt7481";
|
||||
reg = <0x4c>;
|
||||
};
|
||||
|
||||
rtc@68 {
|
||||
compatible = "dallas,ds1339";
|
||||
reg = <0x68>;
|
||||
interrupts = <0x1 0x1 0 0>;
|
||||
};
|
||||
|
||||
eeprom@50 {
|
||||
compatible = "atmel,24c256";
|
||||
reg = <0x50>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c@118100 {
|
||||
pca9546@77 {
|
||||
compatible = "nxp,pca9546";
|
||||
reg = <0x77>;
|
||||
};
|
||||
};
|
||||
|
||||
sdhc@114000 {
|
||||
voltage-ranges = <1800 1800 3300 3300>;
|
||||
};
|
||||
};
|
||||
|
||||
pci0: pcie@ffe240000 {
|
||||
reg = <0xf 0xfe240000 0 0x10000>;
|
||||
ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
|
||||
0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
|
||||
pcie@0 {
|
||||
ranges = <0x02000000 0 0xe0000000
|
||||
0x02000000 0 0xe0000000
|
||||
0 0x20000000
|
||||
|
||||
0x01000000 0 0x00000000
|
||||
0x01000000 0 0x00000000
|
||||
0 0x00010000>;
|
||||
};
|
||||
};
|
||||
|
||||
pci1: pcie@ffe250000 {
|
||||
reg = <0xf 0xfe250000 0 0x10000>;
|
||||
ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x10000000
|
||||
0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
|
||||
pcie@0 {
|
||||
ranges = <0x02000000 0 0xe0000000
|
||||
0x02000000 0 0xe0000000
|
||||
0 0x20000000
|
||||
|
||||
0x01000000 0 0x00000000
|
||||
0x01000000 0 0x00000000
|
||||
0 0x00010000>;
|
||||
};
|
||||
};
|
||||
|
||||
pci2: pcie@ffe260000 {
|
||||
reg = <0xf 0xfe260000 0 0x1000>;
|
||||
ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
|
||||
0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
|
||||
pcie@0 {
|
||||
ranges = <0x02000000 0 0xe0000000
|
||||
0x02000000 0 0xe0000000
|
||||
0 0x20000000
|
||||
|
||||
0x01000000 0 0x00000000
|
||||
0x01000000 0 0x00000000
|
||||
0 0x00010000>;
|
||||
};
|
||||
};
|
||||
|
||||
pci3: pcie@ffe270000 {
|
||||
reg = <0xf 0xfe270000 0 0x10000>;
|
||||
ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x10000000
|
||||
0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
|
||||
pcie@0 {
|
||||
ranges = <0x02000000 0 0xe0000000
|
||||
0x02000000 0 0xe0000000
|
||||
0 0x20000000
|
||||
|
||||
0x01000000 0 0x00000000
|
||||
0x01000000 0 0x00000000
|
||||
0 0x00010000>;
|
||||
};
|
||||
};
|
||||
};
|
@ -180,3 +180,4 @@ CONFIG_CRYPTO_SHA512=y
|
||||
CONFIG_CRYPTO_AES=y
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
CONFIG_CRYPTO_DEV_FSL_CAAM=y
|
||||
CONFIG_FSL_CORENET_CF=y
|
||||
|
@ -179,3 +179,4 @@ CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_CRYPTO_SHA512=y
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
CONFIG_CRYPTO_DEV_FSL_CAAM=y
|
||||
CONFIG_FSL_CORENET_CF=y
|
||||
|
@ -391,7 +391,7 @@ extern const char *powerpc_base_platform;
|
||||
CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
|
||||
CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
|
||||
CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \
|
||||
CPU_FTR_CELL_TB_BUG)
|
||||
CPU_FTR_CELL_TB_BUG | CPU_FTR_SMT)
|
||||
#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
|
||||
|
||||
/* 64-bit CPUs */
|
||||
|
@ -150,8 +150,10 @@
|
||||
#define PPC_INST_MCRXR_MASK 0xfc0007fe
|
||||
#define PPC_INST_MFSPR_PVR 0x7c1f42a6
|
||||
#define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff
|
||||
#define PPC_INST_MFTMR 0x7c0002dc
|
||||
#define PPC_INST_MSGSND 0x7c00019c
|
||||
#define PPC_INST_MSGSNDP 0x7c00011c
|
||||
#define PPC_INST_MTTMR 0x7c0003dc
|
||||
#define PPC_INST_NOP 0x60000000
|
||||
#define PPC_INST_POPCNTB 0x7c0000f4
|
||||
#define PPC_INST_POPCNTB_MASK 0xfc0007fe
|
||||
@ -369,4 +371,11 @@
|
||||
#define TABORT(r) stringify_in_c(.long PPC_INST_TABORT \
|
||||
| __PPC_RA(r))
|
||||
|
||||
/* book3e thread control instructions */
|
||||
#define TMRN(x) ((((x) & 0x1f) << 16) | (((x) & 0x3e0) << 6))
|
||||
#define MTTMR(tmr, r) stringify_in_c(.long PPC_INST_MTTMR | \
|
||||
TMRN(tmr) | ___PPC_RS(r))
|
||||
#define MFTMR(tmr, r) stringify_in_c(.long PPC_INST_MFTMR | \
|
||||
TMRN(tmr) | ___PPC_RT(r))
|
||||
|
||||
#endif /* _ASM_POWERPC_PPC_OPCODE_H */
|
||||
|
@ -15,16 +15,28 @@
|
||||
#ifndef __ASM_POWERPC_REG_BOOKE_H__
|
||||
#define __ASM_POWERPC_REG_BOOKE_H__
|
||||
|
||||
#include <asm/ppc-opcode.h>
|
||||
|
||||
/* Machine State Register (MSR) Fields */
|
||||
#define MSR_GS (1<<28) /* Guest state */
|
||||
#define MSR_UCLE (1<<26) /* User-mode cache lock enable */
|
||||
#define MSR_SPE (1<<25) /* Enable SPE */
|
||||
#define MSR_DWE (1<<10) /* Debug Wait Enable */
|
||||
#define MSR_UBLE (1<<10) /* BTB lock enable (e500) */
|
||||
#define MSR_IS MSR_IR /* Instruction Space */
|
||||
#define MSR_DS MSR_DR /* Data Space */
|
||||
#define MSR_PMM (1<<2) /* Performance monitor mark bit */
|
||||
#define MSR_CM (1<<31) /* Computation Mode (0=32-bit, 1=64-bit) */
|
||||
#define MSR_GS_LG 28 /* Guest state */
|
||||
#define MSR_UCLE_LG 26 /* User-mode cache lock enable */
|
||||
#define MSR_SPE_LG 25 /* Enable SPE */
|
||||
#define MSR_DWE_LG 10 /* Debug Wait Enable */
|
||||
#define MSR_UBLE_LG 10 /* BTB lock enable (e500) */
|
||||
#define MSR_IS_LG MSR_IR_LG /* Instruction Space */
|
||||
#define MSR_DS_LG MSR_DR_LG /* Data Space */
|
||||
#define MSR_PMM_LG 2 /* Performance monitor mark bit */
|
||||
#define MSR_CM_LG 31 /* Computation Mode (0=32-bit, 1=64-bit) */
|
||||
|
||||
#define MSR_GS __MASK(MSR_GS_LG)
|
||||
#define MSR_UCLE __MASK(MSR_UCLE_LG)
|
||||
#define MSR_SPE __MASK(MSR_SPE_LG)
|
||||
#define MSR_DWE __MASK(MSR_DWE_LG)
|
||||
#define MSR_UBLE __MASK(MSR_UBLE_LG)
|
||||
#define MSR_IS __MASK(MSR_IS_LG)
|
||||
#define MSR_DS __MASK(MSR_DS_LG)
|
||||
#define MSR_PMM __MASK(MSR_PMM_LG)
|
||||
#define MSR_CM __MASK(MSR_CM_LG)
|
||||
|
||||
#if defined(CONFIG_PPC_BOOK3E_64)
|
||||
#define MSR_64BIT MSR_CM
|
||||
@ -598,6 +610,13 @@
|
||||
/* Bit definitions for L1CSR2. */
|
||||
#define L1CSR2_DCWS 0x40000000 /* Data Cache write shadow */
|
||||
|
||||
/* Bit definitions for BUCSR. */
|
||||
#define BUCSR_STAC_EN 0x01000000 /* Segment Target Address Cache */
|
||||
#define BUCSR_LS_EN 0x00400000 /* Link Stack */
|
||||
#define BUCSR_BBFI 0x00000200 /* Branch Buffer flash invalidate */
|
||||
#define BUCSR_BPEN 0x00000001 /* Branch prediction enable */
|
||||
#define BUCSR_INIT (BUCSR_STAC_EN | BUCSR_LS_EN | BUCSR_BBFI | BUCSR_BPEN)
|
||||
|
||||
/* Bit definitions for L2CSR0. */
|
||||
#define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */
|
||||
#define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */
|
||||
@ -721,5 +740,23 @@
|
||||
#define MMUBE1_VBE4 0x00000002
|
||||
#define MMUBE1_VBE5 0x00000001
|
||||
|
||||
#define TMRN_IMSR0 0x120 /* Initial MSR Register 0 (e6500) */
|
||||
#define TMRN_IMSR1 0x121 /* Initial MSR Register 1 (e6500) */
|
||||
#define TMRN_INIA0 0x140 /* Next Instruction Address Register 0 */
|
||||
#define TMRN_INIA1 0x141 /* Next Instruction Address Register 1 */
|
||||
#define SPRN_TENSR 0x1b5 /* Thread Enable Status Register */
|
||||
#define SPRN_TENS 0x1b6 /* Thread Enable Set Register */
|
||||
#define SPRN_TENC 0x1b7 /* Thread Enable Clear Register */
|
||||
|
||||
#define TEN_THREAD(x) (1 << (x))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define mftmr(rn) ({unsigned long rval; \
|
||||
asm volatile(MFTMR(rn, %0) : "=r" (rval)); rval;})
|
||||
#define mttmr(rn, v) asm volatile(MTTMR(rn, %0) : \
|
||||
: "r" ((unsigned long)(v)) \
|
||||
: "memory")
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_POWERPC_REG_BOOKE_H__ */
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -180,6 +180,28 @@ exception_marker:
|
||||
#include "exceptions-64s.S"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3E
|
||||
_GLOBAL(fsl_secondary_thread_init)
|
||||
/* Enable branch prediction */
|
||||
lis r3,BUCSR_INIT@h
|
||||
ori r3,r3,BUCSR_INIT@l
|
||||
mtspr SPRN_BUCSR,r3
|
||||
isync
|
||||
|
||||
/*
|
||||
* Fix PIR to match the linear numbering in the device tree.
|
||||
*
|
||||
* On e6500, the reset value of PIR uses the low three bits for
|
||||
* the thread within a core, and the upper bits for the core
|
||||
* number. There are two threads per core, so shift everything
|
||||
* but the low bit right by two bits so that the cpu numbering is
|
||||
* continuous.
|
||||
*/
|
||||
mfspr r3, SPRN_PIR
|
||||
rlwimi r3, r3, 30, 2, 30
|
||||
mtspr SPRN_PIR, r3
|
||||
#endif
|
||||
|
||||
_GLOBAL(generic_secondary_thread_init)
|
||||
mr r24,r3
|
||||
|
||||
|
@ -308,12 +308,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
|
||||
|
||||
/* Get physical cpuid */
|
||||
intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
|
||||
if (intserv) {
|
||||
nthreads = len / sizeof(int);
|
||||
} else {
|
||||
intserv = of_get_flat_dt_prop(node, "reg", NULL);
|
||||
nthreads = 1;
|
||||
}
|
||||
if (!intserv)
|
||||
intserv = of_get_flat_dt_prop(node, "reg", &len);
|
||||
|
||||
nthreads = len / sizeof(int);
|
||||
|
||||
/*
|
||||
* Now see if any of these threads match our boot cpu.
|
||||
|
@ -456,18 +456,20 @@ void __init smp_setup_cpu_maps(void)
|
||||
intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s",
|
||||
&len);
|
||||
if (intserv) {
|
||||
nthreads = len / sizeof(int);
|
||||
DBG(" ibm,ppc-interrupt-server#s -> %d threads\n",
|
||||
nthreads);
|
||||
} else {
|
||||
DBG(" no ibm,ppc-interrupt-server#s -> 1 thread\n");
|
||||
intserv = of_get_property(dn, "reg", NULL);
|
||||
intserv = of_get_property(dn, "reg", &len);
|
||||
if (!intserv) {
|
||||
cpu_be = cpu_to_be32(cpu);
|
||||
intserv = &cpu_be; /* assume logical == phys */
|
||||
len = 4;
|
||||
}
|
||||
}
|
||||
|
||||
nthreads = len / sizeof(int);
|
||||
|
||||
for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
|
||||
bool avail;
|
||||
|
||||
|
@ -511,7 +511,11 @@ void __init setup_system(void)
|
||||
check_smt_enabled();
|
||||
setup_tlb_core_data();
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Freescale Book3e parts spin in a loop provided by firmware,
|
||||
* so smp_release_cpus() does nothing for them
|
||||
*/
|
||||
#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_FSL_BOOK3E)
|
||||
/* Release secondary cpus out of their spinloops at 0x60 now that
|
||||
* we can map physical -> logical CPU ids
|
||||
*/
|
||||
|
@ -299,7 +299,9 @@ itlb_miss_fault_bolted:
|
||||
* r10 = crap (free to use)
|
||||
*/
|
||||
tlb_miss_common_e6500:
|
||||
BEGIN_FTR_SECTION
|
||||
crmove cr2*4+2,cr0*4+2 /* cr2.eq != 0 if kernel address */
|
||||
|
||||
BEGIN_FTR_SECTION /* CPU_FTR_SMT */
|
||||
/*
|
||||
* Search if we already have an indirect entry for that virtual
|
||||
* address, and if we do, bail out.
|
||||
@ -324,17 +326,62 @@ BEGIN_FTR_SECTION
|
||||
b 1b
|
||||
.previous
|
||||
|
||||
/*
|
||||
* Erratum A-008139 says that we can't use tlbwe to change
|
||||
* an indirect entry in any way (including replacing or
|
||||
* invalidating) if the other thread could be in the process
|
||||
* of a lookup. The workaround is to invalidate the entry
|
||||
* with tlbilx before overwriting.
|
||||
*/
|
||||
|
||||
lbz r15,TCD_ESEL_NEXT(r11)
|
||||
rlwinm r10,r15,16,0xff0000
|
||||
oris r10,r10,MAS0_TLBSEL(1)@h
|
||||
mtspr SPRN_MAS0,r10
|
||||
isync
|
||||
tlbre
|
||||
mfspr r15,SPRN_MAS1
|
||||
mfspr r10,SPRN_MAS2
|
||||
andis. r15,r15,MAS1_VALID@h
|
||||
beq 5f
|
||||
|
||||
BEGIN_FTR_SECTION_NESTED(532)
|
||||
mfspr r10,SPRN_MAS8
|
||||
rlwinm r10,r10,0,0x80000fff /* tgs,tlpid -> sgs,slpid */
|
||||
mtspr SPRN_MAS5,r10
|
||||
END_FTR_SECTION_NESTED(CPU_FTR_EMB_HV,CPU_FTR_EMB_HV,532)
|
||||
|
||||
mfspr r10,SPRN_MAS1
|
||||
rlwinm r15,r10,0,0x3fff0000 /* tid -> spid */
|
||||
rlwimi r15,r10,20,0x00000003 /* ind,ts -> sind,sas */
|
||||
mfspr r10,SPRN_MAS6
|
||||
mtspr SPRN_MAS6,r15
|
||||
|
||||
mfspr r15,SPRN_MAS2
|
||||
isync
|
||||
tlbilxva 0,r15
|
||||
isync
|
||||
|
||||
mtspr SPRN_MAS6,r10
|
||||
|
||||
5:
|
||||
BEGIN_FTR_SECTION_NESTED(532)
|
||||
li r10,0
|
||||
mtspr SPRN_MAS8,r10
|
||||
mtspr SPRN_MAS5,r10
|
||||
END_FTR_SECTION_NESTED(CPU_FTR_EMB_HV,CPU_FTR_EMB_HV,532)
|
||||
|
||||
tlbsx 0,r16
|
||||
mtspr SPRN_MAS2,r10
|
||||
mfspr r10,SPRN_MAS1
|
||||
mtspr SPRN_MAS1,r15
|
||||
|
||||
andis. r10,r10,MAS1_VALID@h
|
||||
andis. r15,r10,MAS1_VALID@h
|
||||
bne tlb_miss_done_e6500
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_SMT)
|
||||
FTR_SECTION_ELSE
|
||||
mfspr r10,SPRN_MAS1
|
||||
ALT_FTR_SECTION_END_IFSET(CPU_FTR_SMT)
|
||||
|
||||
oris r10,r10,MAS1_VALID@h
|
||||
beq cr2,4f
|
||||
rlwinm r10,r10,0,16,1 /* Clear TID */
|
||||
4: mtspr SPRN_MAS1,r10
|
||||
|
||||
/* Now, we need to walk the page tables. First check if we are in
|
||||
* range.
|
||||
@ -410,12 +457,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_SMT)
|
||||
rfi
|
||||
|
||||
tlb_miss_kernel_e6500:
|
||||
mfspr r10,SPRN_MAS1
|
||||
ld r14,PACA_KERNELPGD(r13)
|
||||
cmpldi cr0,r15,8 /* Check for vmalloc region */
|
||||
rlwinm r10,r10,0,16,1 /* Clear TID */
|
||||
mtspr SPRN_MAS1,r10
|
||||
beq+ tlb_miss_common_e6500
|
||||
cmpldi cr1,r15,8 /* Check for vmalloc region */
|
||||
beq+ cr1,tlb_miss_common_e6500
|
||||
|
||||
tlb_miss_fault_e6500:
|
||||
tlb_unlock_e6500
|
||||
|
@ -274,7 +274,7 @@ config CORENET_GENERIC
|
||||
For 32bit kernel, the following boards are supported:
|
||||
P2041 RDB, P3041 DS, P4080 DS, kmcoge4, and OCA4080
|
||||
For 64bit kernel, the following boards are supported:
|
||||
T208x QDS, T4240 QDS/RDB and B4 QDS
|
||||
T208x QDS/RDB, T4240 QDS/RDB and B4 QDS
|
||||
The following boards are supported for both 32bit and 64bit kernel:
|
||||
P5020 DS, P5040 DS and T104xQDS
|
||||
|
||||
|
@ -120,6 +120,7 @@ static const char * const boards[] __initconst = {
|
||||
"fsl,P5020DS",
|
||||
"fsl,P5040DS",
|
||||
"fsl,T2080QDS",
|
||||
"fsl,T2080RDB",
|
||||
"fsl,T2081QDS",
|
||||
"fsl,T4240QDS",
|
||||
"fsl,T4240RDB",
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <asm/dbell.h>
|
||||
#include <asm/fsl_guts.h>
|
||||
#include <asm/code-patching.h>
|
||||
#include <asm/cputhreads.h>
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/mpic.h>
|
||||
@ -168,6 +169,24 @@ static inline u32 read_spin_table_addr_l(void *spin_table)
|
||||
return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
static void wake_hw_thread(void *info)
|
||||
{
|
||||
void fsl_secondary_thread_init(void);
|
||||
unsigned long imsr1, inia1;
|
||||
int nr = *(const int *)info;
|
||||
|
||||
imsr1 = MSR_KERNEL;
|
||||
inia1 = *(unsigned long *)fsl_secondary_thread_init;
|
||||
|
||||
mttmr(TMRN_IMSR1, imsr1);
|
||||
mttmr(TMRN_INIA1, inia1);
|
||||
mtspr(SPRN_TENS, TEN_THREAD(1));
|
||||
|
||||
smp_generic_kick_cpu(nr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int smp_85xx_kick_cpu(int nr)
|
||||
{
|
||||
unsigned long flags;
|
||||
@ -183,6 +202,31 @@ static int smp_85xx_kick_cpu(int nr)
|
||||
|
||||
pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
/* Threads don't use the spin table */
|
||||
if (cpu_thread_in_core(nr) != 0) {
|
||||
int primary = cpu_first_thread_sibling(nr);
|
||||
|
||||
if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
|
||||
return -ENOENT;
|
||||
|
||||
if (cpu_thread_in_core(nr) != 1) {
|
||||
pr_err("%s: cpu %d: invalid hw thread %d\n",
|
||||
__func__, nr, cpu_thread_in_core(nr));
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!cpu_online(primary)) {
|
||||
pr_err("%s: cpu %d: primary %d not online\n",
|
||||
__func__, nr, primary);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
smp_call_function_single(primary, wake_hw_thread, &nr, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
np = of_get_cpu_node(nr, NULL);
|
||||
cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
|
||||
|
||||
|
@ -853,8 +853,8 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
|
||||
in = pcie->cfg_type0 + PEX_RC_INWIN_BASE;
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* not enabled, skip */
|
||||
if (!in_le32(&in[i].ar) & PEX_RCIWARn_EN)
|
||||
continue;
|
||||
if (!(in_le32(&in[i].ar) & PEX_RCIWARn_EN))
|
||||
continue;
|
||||
|
||||
if (get_immrbase() == in_le32(&in[i].tar))
|
||||
return (u64)in_le32(&in[i].barh) << 32 |
|
||||
|
@ -184,7 +184,7 @@ static int mpic_msgr_probe(struct platform_device *dev)
|
||||
dev_info(&dev->dev, "Found %d message registers\n",
|
||||
mpic_msgr_count);
|
||||
|
||||
mpic_msgrs = kzalloc(sizeof(struct mpic_msgr) * mpic_msgr_count,
|
||||
mpic_msgrs = kcalloc(mpic_msgr_count, sizeof(*mpic_msgrs),
|
||||
GFP_KERNEL);
|
||||
if (!mpic_msgrs) {
|
||||
dev_err(&dev->dev,
|
||||
|
@ -61,6 +61,16 @@ config TEGRA30_MC
|
||||
analysis, especially for IOMMU/SMMU(System Memory Management
|
||||
Unit) module.
|
||||
|
||||
config FSL_CORENET_CF
|
||||
tristate "Freescale CoreNet Error Reporting"
|
||||
depends on FSL_SOC_BOOKE
|
||||
help
|
||||
Say Y for reporting of errors from the Freescale CoreNet
|
||||
Coherency Fabric. Errors reported include accesses to
|
||||
physical addresses that mapped by no local access window
|
||||
(LAW) or an invalid LAW, as well as bad cache state that
|
||||
represents a coherency violation.
|
||||
|
||||
config FSL_IFC
|
||||
bool
|
||||
depends on FSL_SOC
|
||||
|
@ -7,6 +7,7 @@ obj-$(CONFIG_OF) += of_memory.o
|
||||
endif
|
||||
obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
|
||||
obj-$(CONFIG_TI_EMIF) += emif.o
|
||||
obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o
|
||||
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
|
||||
obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
|
||||
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
|
||||
|
251
drivers/memory/fsl-corenet-cf.c
Normal file
251
drivers/memory/fsl-corenet-cf.c
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* CoreNet Coherency Fabric error reporting
|
||||
*
|
||||
* Copyright 2014 Freescale Semiconductor 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/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
enum ccf_version {
|
||||
CCF1,
|
||||
CCF2,
|
||||
};
|
||||
|
||||
struct ccf_info {
|
||||
enum ccf_version version;
|
||||
int err_reg_offs;
|
||||
};
|
||||
|
||||
static const struct ccf_info ccf1_info = {
|
||||
.version = CCF1,
|
||||
.err_reg_offs = 0xa00,
|
||||
};
|
||||
|
||||
static const struct ccf_info ccf2_info = {
|
||||
.version = CCF2,
|
||||
.err_reg_offs = 0xe40,
|
||||
};
|
||||
|
||||
static const struct of_device_id ccf_matches[] = {
|
||||
{
|
||||
.compatible = "fsl,corenet1-cf",
|
||||
.data = &ccf1_info,
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,corenet2-cf",
|
||||
.data = &ccf2_info,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
struct ccf_err_regs {
|
||||
u32 errdet; /* 0x00 Error Detect Register */
|
||||
/* 0x04 Error Enable (ccf1)/Disable (ccf2) Register */
|
||||
u32 errdis;
|
||||
/* 0x08 Error Interrupt Enable Register (ccf2 only) */
|
||||
u32 errinten;
|
||||
u32 cecar; /* 0x0c Error Capture Attribute Register */
|
||||
u32 cecaddrh; /* 0x10 Error Capture Address High */
|
||||
u32 cecaddrl; /* 0x14 Error Capture Address Low */
|
||||
u32 cecar2; /* 0x18 Error Capture Attribute Register 2 */
|
||||
};
|
||||
|
||||
/* LAE/CV also valid for errdis and errinten */
|
||||
#define ERRDET_LAE (1 << 0) /* Local Access Error */
|
||||
#define ERRDET_CV (1 << 1) /* Coherency Violation */
|
||||
#define ERRDET_CTYPE_SHIFT 26 /* Capture Type (ccf2 only) */
|
||||
#define ERRDET_CTYPE_MASK (0x1f << ERRDET_CTYPE_SHIFT)
|
||||
#define ERRDET_CAP (1 << 31) /* Capture Valid (ccf2 only) */
|
||||
|
||||
#define CECAR_VAL (1 << 0) /* Valid (ccf1 only) */
|
||||
#define CECAR_UVT (1 << 15) /* Unavailable target ID (ccf1) */
|
||||
#define CECAR_SRCID_SHIFT_CCF1 24
|
||||
#define CECAR_SRCID_MASK_CCF1 (0xff << CECAR_SRCID_SHIFT_CCF1)
|
||||
#define CECAR_SRCID_SHIFT_CCF2 18
|
||||
#define CECAR_SRCID_MASK_CCF2 (0xff << CECAR_SRCID_SHIFT_CCF2)
|
||||
|
||||
#define CECADDRH_ADDRH 0xff
|
||||
|
||||
struct ccf_private {
|
||||
const struct ccf_info *info;
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
struct ccf_err_regs __iomem *err_regs;
|
||||
};
|
||||
|
||||
static irqreturn_t ccf_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct ccf_private *ccf = dev_id;
|
||||
static DEFINE_RATELIMIT_STATE(ratelimit, DEFAULT_RATELIMIT_INTERVAL,
|
||||
DEFAULT_RATELIMIT_BURST);
|
||||
u32 errdet, cecar, cecar2;
|
||||
u64 addr;
|
||||
u32 src_id;
|
||||
bool uvt = false;
|
||||
bool cap_valid = false;
|
||||
|
||||
errdet = ioread32be(&ccf->err_regs->errdet);
|
||||
cecar = ioread32be(&ccf->err_regs->cecar);
|
||||
cecar2 = ioread32be(&ccf->err_regs->cecar2);
|
||||
addr = ioread32be(&ccf->err_regs->cecaddrl);
|
||||
addr |= ((u64)(ioread32be(&ccf->err_regs->cecaddrh) &
|
||||
CECADDRH_ADDRH)) << 32;
|
||||
|
||||
if (!__ratelimit(&ratelimit))
|
||||
goto out;
|
||||
|
||||
switch (ccf->info->version) {
|
||||
case CCF1:
|
||||
if (cecar & CECAR_VAL) {
|
||||
if (cecar & CECAR_UVT)
|
||||
uvt = true;
|
||||
|
||||
src_id = (cecar & CECAR_SRCID_MASK_CCF1) >>
|
||||
CECAR_SRCID_SHIFT_CCF1;
|
||||
cap_valid = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case CCF2:
|
||||
if (errdet & ERRDET_CAP) {
|
||||
src_id = (cecar & CECAR_SRCID_MASK_CCF2) >>
|
||||
CECAR_SRCID_SHIFT_CCF2;
|
||||
cap_valid = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
dev_crit(ccf->dev, "errdet 0x%08x cecar 0x%08x cecar2 0x%08x\n",
|
||||
errdet, cecar, cecar2);
|
||||
|
||||
if (errdet & ERRDET_LAE) {
|
||||
if (uvt)
|
||||
dev_crit(ccf->dev, "LAW Unavailable Target ID\n");
|
||||
else
|
||||
dev_crit(ccf->dev, "Local Access Window Error\n");
|
||||
}
|
||||
|
||||
if (errdet & ERRDET_CV)
|
||||
dev_crit(ccf->dev, "Coherency Violation\n");
|
||||
|
||||
if (cap_valid) {
|
||||
dev_crit(ccf->dev, "address 0x%09llx, src id 0x%x\n",
|
||||
addr, src_id);
|
||||
}
|
||||
|
||||
out:
|
||||
iowrite32be(errdet, &ccf->err_regs->errdet);
|
||||
return errdet ? IRQ_HANDLED : IRQ_NONE;
|
||||
}
|
||||
|
||||
static int ccf_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ccf_private *ccf;
|
||||
struct resource *r;
|
||||
const struct of_device_id *match;
|
||||
int ret, irq;
|
||||
|
||||
match = of_match_device(ccf_matches, &pdev->dev);
|
||||
if (WARN_ON(!match))
|
||||
return -ENODEV;
|
||||
|
||||
ccf = devm_kzalloc(&pdev->dev, sizeof(*ccf), GFP_KERNEL);
|
||||
if (!ccf)
|
||||
return -ENOMEM;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!r) {
|
||||
dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ccf->regs = devm_ioremap_resource(&pdev->dev, r);
|
||||
if (IS_ERR(ccf->regs)) {
|
||||
dev_err(&pdev->dev, "%s: can't map mem resource\n", __func__);
|
||||
return PTR_ERR(ccf->regs);
|
||||
}
|
||||
|
||||
ccf->dev = &pdev->dev;
|
||||
ccf->info = match->data;
|
||||
ccf->err_regs = ccf->regs + ccf->info->err_reg_offs;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, ccf);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (!irq) {
|
||||
dev_err(&pdev->dev, "%s: no irq\n", __func__);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, ccf_irq, 0, pdev->name, ccf);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: can't request irq\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (ccf->info->version) {
|
||||
case CCF1:
|
||||
/* On CCF1 this register enables rather than disables. */
|
||||
iowrite32be(ERRDET_LAE | ERRDET_CV, &ccf->err_regs->errdis);
|
||||
break;
|
||||
|
||||
case CCF2:
|
||||
iowrite32be(0, &ccf->err_regs->errdis);
|
||||
iowrite32be(ERRDET_LAE | ERRDET_CV, &ccf->err_regs->errinten);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ccf_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ccf_private *ccf = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
switch (ccf->info->version) {
|
||||
case CCF1:
|
||||
iowrite32be(0, &ccf->err_regs->errdis);
|
||||
break;
|
||||
|
||||
case CCF2:
|
||||
/*
|
||||
* We clear errdis on ccf1 because that's the only way to
|
||||
* disable interrupts, but on ccf2 there's no need to disable
|
||||
* detection.
|
||||
*/
|
||||
iowrite32be(0, &ccf->err_regs->errinten);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ccf_driver = {
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ccf_matches,
|
||||
},
|
||||
.probe = ccf_probe,
|
||||
.remove = ccf_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ccf_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Freescale Semiconductor");
|
||||
MODULE_DESCRIPTION("Freescale CoreNet Coherency Fabric error reporting");
|
Loading…
Reference in New Issue
Block a user