MIPS: OCTEON: Don't attempt to use nonexistent registers on OCTEON III models.
authorDavid Daney <david.daney@cavium.com>
Tue, 9 Feb 2016 19:00:10 +0000 (11:00 -0800)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 13 May 2016 12:01:40 +0000 (14:01 +0200)
Attempts to read the nonexistent registers results in bus errors.
Either use registers that exist, or don't do the access as appropriate.

Signed-off-by: David Daney <david.daney@cavium.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/12502/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/cavium-octeon/csrc-octeon.c
arch/mips/cavium-octeon/setup.c

index 1882e64..23c2344 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/octeon/cvmx-ipd-defs.h>
 #include <asm/octeon/cvmx-mio-defs.h>
 #include <asm/octeon/cvmx-rst-defs.h>
+#include <asm/octeon/cvmx-fpa-defs.h>
 
 static u64 f;
 static u64 rdiv;
@@ -65,9 +66,13 @@ void __init octeon_setup_delays(void)
  */
 void octeon_init_cvmcount(void)
 {
+       u64 clk_reg;
        unsigned long flags;
        unsigned loops = 2;
 
+       clk_reg = octeon_has_feature(OCTEON_FEATURE_FPA3) ?
+               CVMX_FPA_CLK_COUNT : CVMX_IPD_CLK_COUNT;
+
        /* Clobber loops so GCC will not unroll the following while loop. */
        asm("" : "+r" (loops));
 
@@ -77,18 +82,18 @@ void octeon_init_cvmcount(void)
         * which should give more deterministic timing.
         */
        while (loops--) {
-               u64 ipd_clk_count = cvmx_read_csr(CVMX_IPD_CLK_COUNT);
+               u64 clk_count = cvmx_read_csr(clk_reg);
                if (rdiv != 0) {
-                       ipd_clk_count *= rdiv;
+                       clk_count *= rdiv;
                        if (f != 0) {
                                asm("dmultu\t%[cnt],%[f]\n\t"
                                    "mfhi\t%[cnt]"
-                                   : [cnt] "+r" (ipd_clk_count)
+                                   : [cnt] "+r" (clk_count)
                                    : [f] "r" (f)
                                    : "hi", "lo");
                        }
                }
-               write_c0_cvmcount(ipd_clk_count);
+               write_c0_cvmcount(clk_count);
        }
        local_irq_restore(flags);
 }
index 9c6ad2f..54a214e 100644 (file)
@@ -492,8 +492,6 @@ const char *get_system_type(void)
 void octeon_user_io_init(void)
 {
        union octeon_cvmemctl cvmmemctl;
-       union cvmx_iob_fau_timeout fau_timeout;
-       union cvmx_pow_nw_tim nm_tim;
 
        /* Get the current settings for CP0_CVMMEMCTL_REG */
        cvmmemctl.u64 = read_c0_cvmmemctl();
@@ -595,17 +593,27 @@ void octeon_user_io_init(void)
                          CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
                          CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
 
-       /* Set a default for the hardware timeouts */
-       fau_timeout.u64 = 0;
-       fau_timeout.s.tout_val = 0xfff;
-       /* Disable tagwait FAU timeout */
-       fau_timeout.s.tout_enb = 0;
-       cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64);
-
-       nm_tim.u64 = 0;
-       /* 4096 cycles */
-       nm_tim.s.nw_tim = 3;
-       cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64);
+       if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+               union cvmx_iob_fau_timeout fau_timeout;
+
+               /* Set a default for the hardware timeouts */
+               fau_timeout.u64 = 0;
+               fau_timeout.s.tout_val = 0xfff;
+               /* Disable tagwait FAU timeout */
+               fau_timeout.s.tout_enb = 0;
+               cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64);
+       }
+
+       if ((!OCTEON_IS_MODEL(OCTEON_CN68XX) &&
+            !OCTEON_IS_MODEL(OCTEON_CN7XXX)) ||
+           OCTEON_IS_MODEL(OCTEON_CN70XX)) {
+               union cvmx_pow_nw_tim nm_tim;
+
+               nm_tim.u64 = 0;
+               /* 4096 cycles */
+               nm_tim.s.nw_tim = 3;
+               cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64);
+       }
 
        write_octeon_c0_icacheerr(0);
        write_c0_derraddr1(0);