|
@@ -51,6 +51,7 @@
|
|
#include <asm/idle.h>
|
|
#include <asm/idle.h>
|
|
#include <asm/mips-cm.h>
|
|
#include <asm/mips-cm.h>
|
|
#include <asm/mips-r2-to-r6-emul.h>
|
|
#include <asm/mips-r2-to-r6-emul.h>
|
|
|
|
+#include <asm/mips-cm.h>
|
|
#include <asm/mipsregs.h>
|
|
#include <asm/mipsregs.h>
|
|
#include <asm/mipsmtregs.h>
|
|
#include <asm/mipsmtregs.h>
|
|
#include <asm/module.h>
|
|
#include <asm/module.h>
|
|
@@ -1644,6 +1645,65 @@ __setup("nol2par", nol2parity);
|
|
*/
|
|
*/
|
|
static inline void parity_protection_init(void)
|
|
static inline void parity_protection_init(void)
|
|
{
|
|
{
|
|
|
|
+#define ERRCTL_PE 0x80000000
|
|
|
|
+#define ERRCTL_L2P 0x00800000
|
|
|
|
+
|
|
|
|
+ if (mips_cm_revision() >= CM_REV_CM3) {
|
|
|
|
+ ulong gcr_ectl, cp0_ectl;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * With CM3 systems we need to ensure that the L1 & L2
|
|
|
|
+ * parity enables are set to the same value, since this
|
|
|
|
+ * is presumed by the hardware engineers.
|
|
|
|
+ *
|
|
|
|
+ * If the user disabled either of L1 or L2 ECC checking,
|
|
|
|
+ * disable both.
|
|
|
|
+ */
|
|
|
|
+ l1parity &= l2parity;
|
|
|
|
+ l2parity &= l1parity;
|
|
|
|
+
|
|
|
|
+ /* Probe L1 ECC support */
|
|
|
|
+ cp0_ectl = read_c0_ecc();
|
|
|
|
+ write_c0_ecc(cp0_ectl | ERRCTL_PE);
|
|
|
|
+ back_to_back_c0_hazard();
|
|
|
|
+ cp0_ectl = read_c0_ecc();
|
|
|
|
+
|
|
|
|
+ /* Probe L2 ECC support */
|
|
|
|
+ gcr_ectl = read_gcr_err_control();
|
|
|
|
+
|
|
|
|
+ if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK) ||
|
|
|
|
+ !(cp0_ectl & ERRCTL_PE)) {
|
|
|
|
+ /*
|
|
|
|
+ * One of L1 or L2 ECC checking isn't supported,
|
|
|
|
+ * so we cannot enable either.
|
|
|
|
+ */
|
|
|
|
+ l1parity = l2parity = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Configure L1 ECC checking */
|
|
|
|
+ if (l1parity)
|
|
|
|
+ cp0_ectl |= ERRCTL_PE;
|
|
|
|
+ else
|
|
|
|
+ cp0_ectl &= ~ERRCTL_PE;
|
|
|
|
+ write_c0_ecc(cp0_ectl);
|
|
|
|
+ back_to_back_c0_hazard();
|
|
|
|
+ WARN_ON(!!(read_c0_ecc() & ERRCTL_PE) != l1parity);
|
|
|
|
+
|
|
|
|
+ /* Configure L2 ECC checking */
|
|
|
|
+ if (l2parity)
|
|
|
|
+ gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK;
|
|
|
|
+ else
|
|
|
|
+ gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK;
|
|
|
|
+ write_gcr_err_control(gcr_ectl);
|
|
|
|
+ gcr_ectl = read_gcr_err_control();
|
|
|
|
+ gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK;
|
|
|
|
+ WARN_ON(!!gcr_ectl != l2parity);
|
|
|
|
+
|
|
|
|
+ pr_info("Cache parity protection %sabled\n",
|
|
|
|
+ l1parity ? "en" : "dis");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
switch (current_cpu_type()) {
|
|
switch (current_cpu_type()) {
|
|
case CPU_24K:
|
|
case CPU_24K:
|
|
case CPU_34K:
|
|
case CPU_34K:
|
|
@@ -1654,11 +1714,8 @@ static inline void parity_protection_init(void)
|
|
case CPU_PROAPTIV:
|
|
case CPU_PROAPTIV:
|
|
case CPU_P5600:
|
|
case CPU_P5600:
|
|
case CPU_QEMU_GENERIC:
|
|
case CPU_QEMU_GENERIC:
|
|
- case CPU_I6400:
|
|
|
|
case CPU_P6600:
|
|
case CPU_P6600:
|
|
{
|
|
{
|
|
-#define ERRCTL_PE 0x80000000
|
|
|
|
-#define ERRCTL_L2P 0x00800000
|
|
|
|
unsigned long errctl;
|
|
unsigned long errctl;
|
|
unsigned int l1parity_present, l2parity_present;
|
|
unsigned int l1parity_present, l2parity_present;
|
|
|
|
|