diff options
Diffstat (limited to 'arch/mips/cavium-octeon/csrc-octeon.c')
| -rw-r--r-- | arch/mips/cavium-octeon/csrc-octeon.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c index 02193953eb9e..af62a210a40b 100644 --- a/arch/mips/cavium-octeon/csrc-octeon.c +++ b/arch/mips/cavium-octeon/csrc-octeon.c @@ -7,17 +7,20 @@ * Copyright (C) 2009, 2012 Cavium, Inc. */ #include <linux/clocksource.h> +#include <linux/sched/clock.h> #include <linux/export.h> #include <linux/init.h> #include <linux/smp.h> #include <asm/cpu-info.h> +#include <asm/cpu-type.h> #include <asm/time.h> #include <asm/octeon/octeon.h> #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; @@ -38,11 +41,20 @@ void __init octeon_setup_delays(void) if (current_cpu_type() == CPU_CAVIUM_OCTEON2) { union cvmx_mio_rst_boot rst_boot; + rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT); rdiv = rst_boot.s.c_mul; /* CPU clock */ sdiv = rst_boot.s.pnr_mul; /* I/O clock */ f = (0x8000000000000000ull / sdiv) * 2; + } else if (current_cpu_type() == CPU_CAVIUM_OCTEON3) { + union cvmx_rst_boot rst_boot; + + rst_boot.u64 = cvmx_read_csr(CVMX_RST_BOOT); + rdiv = rst_boot.s.c_mul; /* CPU clock */ + sdiv = rst_boot.s.pnr_mul; /* I/O clock */ + f = (0x8000000000000000ull / sdiv) * 2; } + } /* @@ -55,9 +67,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)); @@ -67,23 +83,23 @@ 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); } -static cycle_t octeon_cvmcount_read(struct clocksource *cs) +static u64 octeon_cvmcount_read(struct clocksource *cs) { return read_c0_cvmcount(); } @@ -97,7 +113,7 @@ static struct clocksource clocksource_mips = { unsigned long long notrace sched_clock(void) { - /* 64-bit arithmatic can overflow, so use 128-bit. */ + /* 64-bit arithmetic can overflow, so use 128-bit. */ u64 t1, t2, t3; unsigned long long rv; u64 mult = clocksource_mips.mult; |
