aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/include/asm/timex.h65
-rw-r--r--arch/mips/kernel/cpu-probe.c1
2 files changed, 48 insertions, 18 deletions
diff --git a/arch/mips/include/asm/timex.h b/arch/mips/include/asm/timex.h
index c5424757da65..b05bb70a2e46 100644
--- a/arch/mips/include/asm/timex.h
+++ b/arch/mips/include/asm/timex.h
@@ -4,12 +4,16 @@
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1998, 1999, 2003 by Ralf Baechle 6 * Copyright (C) 1998, 1999, 2003 by Ralf Baechle
7 * Copyright (C) 2014 by Maciej W. Rozycki
7 */ 8 */
8#ifndef _ASM_TIMEX_H 9#ifndef _ASM_TIMEX_H
9#define _ASM_TIMEX_H 10#define _ASM_TIMEX_H
10 11
11#ifdef __KERNEL__ 12#ifdef __KERNEL__
12 13
14#include <linux/compiler.h>
15
16#include <asm/cpu.h>
13#include <asm/cpu-features.h> 17#include <asm/cpu-features.h>
14#include <asm/mipsregs.h> 18#include <asm/mipsregs.h>
15#include <asm/cpu-type.h> 19#include <asm/cpu-type.h>
@@ -45,29 +49,54 @@ typedef unsigned int cycles_t;
45 * However for now the implementaton of this function doesn't get these 49 * However for now the implementaton of this function doesn't get these
46 * fine details right. 50 * fine details right.
47 */ 51 */
48static inline cycles_t get_cycles(void) 52static inline int can_use_mips_counter(unsigned int prid)
49{ 53{
50 switch (boot_cpu_type()) { 54 int comp = (prid & PRID_COMP_MASK) != PRID_COMP_LEGACY;
51 case CPU_R4400PC:
52 case CPU_R4400SC:
53 case CPU_R4400MC:
54 if ((read_c0_prid() & 0xff) >= 0x0050)
55 return read_c0_count();
56 break;
57 55
58 case CPU_R4000PC: 56 if (__builtin_constant_p(cpu_has_counter) && !cpu_has_counter)
59 case CPU_R4000SC: 57 return 0;
60 case CPU_R4000MC: 58 else if (__builtin_constant_p(cpu_has_mips_r) && cpu_has_mips_r)
61 break; 59 return 1;
60 else if (likely(!__builtin_constant_p(cpu_has_mips_r) && comp))
61 return 1;
62 /* Make sure we don't peek at cpu_data[0].options in the fast path! */
63 if (!__builtin_constant_p(cpu_has_counter))
64 asm volatile("" : "=m" (cpu_data[0].options));
65 if (likely(cpu_has_counter &&
66 prid >= (PRID_IMP_R4000 | PRID_REV_ENCODE_44(5, 0))))
67 return 1;
68 else
69 return 0;
70}
62 71
63 default: 72static inline cycles_t get_cycles(void)
64 if (cpu_has_counter) 73{
65 return read_c0_count(); 74 if (can_use_mips_counter(read_c0_prid()))
66 break; 75 return read_c0_count();
67 } 76 else
77 return 0; /* no usable counter */
78}
79
80/*
81 * Like get_cycles - but where c0_count is not available we desperately
82 * use c0_random in an attempt to get at least a little bit of entropy.
83 *
84 * R6000 and R6000A neither have a count register nor a random register.
85 * That leaves no entropy source in the CPU itself.
86 */
87static inline unsigned long random_get_entropy(void)
88{
89 unsigned int prid = read_c0_prid();
90 unsigned int imp = prid & PRID_IMP_MASK;
68 91
69 return 0; /* no usable counter */ 92 if (can_use_mips_counter(prid))
93 return read_c0_count();
94 else if (likely(imp != PRID_IMP_R6000 && imp != PRID_IMP_R6000A))
95 return read_c0_random();
96 else
97 return 0; /* no usable register */
70} 98}
99#define random_get_entropy random_get_entropy
71 100
72#endif /* __KERNEL__ */ 101#endif /* __KERNEL__ */
73 102
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index f34000b27bf1..b1b580d69db0 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -1026,6 +1026,7 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
1026 decode_configs(c); 1026 decode_configs(c);
1027 /* JZRISC does not implement the CP0 counter. */ 1027 /* JZRISC does not implement the CP0 counter. */
1028 c->options &= ~MIPS_CPU_COUNTER; 1028 c->options &= ~MIPS_CPU_COUNTER;
1029 BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
1029 switch (c->processor_id & PRID_IMP_MASK) { 1030 switch (c->processor_id & PRID_IMP_MASK) {
1030 case PRID_IMP_JZRISC: 1031 case PRID_IMP_JZRISC:
1031 c->cputype = CPU_JZRISC; 1032 c->cputype = CPU_JZRISC;