aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2010-06-01 16:18:15 -0400
committerRalf Baechle <ralf@linux-mips.org>2010-08-05 08:26:20 -0400
commitca148125e6134de334b61822539d220794d8da18 (patch)
treee31af5840a8873ec6613bf9b09fe0f9ad3e6a9c7 /arch/mips
parente6b78c4f224925c71cce57033b1e6e30dd56add7 (diff)
MIPS: Octeon: Implement delays with cycle counter.
Power throttling make deterministic delay loops impossible. Re-implement delays using the cycle counter. This also allows us to get rid of the code that calculates loops per jiffy. Signed-off-by: David Daney <ddaney@caviumnetworks.com> To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/1317/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/cavium-octeon/csrc-octeon.c55
-rw-r--r--arch/mips/cavium-octeon/setup.c4
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h11
-rw-r--r--arch/mips/include/asm/octeon/octeon.h1
4 files changed, 58 insertions, 13 deletions
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c
index 36400d23ff59..b6847c8e0ddd 100644
--- a/arch/mips/cavium-octeon/csrc-octeon.c
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -80,3 +80,58 @@ void __init plat_time_init(void)
80 clocksource_set_clock(&clocksource_mips, mips_hpt_frequency); 80 clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
81 clocksource_register(&clocksource_mips); 81 clocksource_register(&clocksource_mips);
82} 82}
83
84static u64 octeon_udelay_factor;
85static u64 octeon_ndelay_factor;
86
87void __init octeon_setup_delays(void)
88{
89 octeon_udelay_factor = octeon_get_clock_rate() / 1000000;
90 /*
91 * For __ndelay we divide by 2^16, so the factor is multiplied
92 * by the same amount.
93 */
94 octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull;
95
96 preset_lpj = octeon_get_clock_rate() / HZ;
97}
98
99void __udelay(unsigned long us)
100{
101 u64 cur, end, inc;
102
103 cur = read_c0_cvmcount();
104
105 inc = us * octeon_udelay_factor;
106 end = cur + inc;
107
108 while (end > cur)
109 cur = read_c0_cvmcount();
110}
111EXPORT_SYMBOL(__udelay);
112
113void __ndelay(unsigned long ns)
114{
115 u64 cur, end, inc;
116
117 cur = read_c0_cvmcount();
118
119 inc = ((ns * octeon_ndelay_factor) >> 16);
120 end = cur + inc;
121
122 while (end > cur)
123 cur = read_c0_cvmcount();
124}
125EXPORT_SYMBOL(__ndelay);
126
127void __delay(unsigned long loops)
128{
129 u64 cur, end;
130
131 cur = read_c0_cvmcount();
132 end = cur + loops;
133
134 while (end > cur)
135 cur = read_c0_cvmcount();
136}
137EXPORT_SYMBOL(__delay);
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 8c81a5c5bbab..7216fbd5d79d 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -594,13 +594,13 @@ void __init prom_init(void)
594 * the filesystem. Also specify the calibration delay 594 * the filesystem. Also specify the calibration delay
595 * to avoid calculating it every time. 595 * to avoid calculating it every time.
596 */ 596 */
597 strcat(arcs_cmdline, " rw root=1f00" 597 strcat(arcs_cmdline, " rw root=1f00 slram=root,0x40000000,+1073741824");
598 " lpj=60176 slram=root,0x40000000,+1073741824");
599 } 598 }
600 599
601 mips_hpt_frequency = octeon_get_clock_rate(); 600 mips_hpt_frequency = octeon_get_clock_rate();
602 601
603 octeon_init_cvmcount(); 602 octeon_init_cvmcount();
603 octeon_setup_delays();
604 604
605 _machine_restart = octeon_restart; 605 _machine_restart = octeon_restart;
606 _machine_halt = octeon_halt; 606 _machine_halt = octeon_halt;
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index 2a7ea90fee2a..b952fc7215e2 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -61,22 +61,11 @@
61 61
62#define kernel_uses_smartmips_rixi (cpu_data[0].cputype == CPU_CAVIUM_OCTEON_PLUS) 62#define kernel_uses_smartmips_rixi (cpu_data[0].cputype == CPU_CAVIUM_OCTEON_PLUS)
63 63
64#define ARCH_HAS_READ_CURRENT_TIMER 1
65#define ARCH_HAS_IRQ_PER_CPU 1 64#define ARCH_HAS_IRQ_PER_CPU 1
66#define ARCH_HAS_SPINLOCK_PREFETCH 1 65#define ARCH_HAS_SPINLOCK_PREFETCH 1
67#define spin_lock_prefetch(x) prefetch(x) 66#define spin_lock_prefetch(x) prefetch(x)
68#define PREFETCH_STRIDE 128 67#define PREFETCH_STRIDE 128
69 68
70static inline int read_current_timer(unsigned long *result)
71{
72 asm volatile ("rdhwr %0,$31\n"
73#ifndef CONFIG_64BIT
74 "\tsll %0, 0"
75#endif
76 : "=r" (*result));
77 return 0;
78}
79
80#ifdef __OCTEON__ 69#ifdef __OCTEON__
81/* 70/*
82 * All gcc versions that have OCTEON support define __OCTEON__ and have the 71 * All gcc versions that have OCTEON support define __OCTEON__ and have the
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index c29debe7a8ad..917a6c413b1a 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -50,6 +50,7 @@ extern void octeon_crypto_disable(struct octeon_cop2_state *state,
50extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task); 50extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task);
51 51
52extern void octeon_init_cvmcount(void); 52extern void octeon_init_cvmcount(void);
53extern void octeon_setup_delays(void);
53 54
54#define OCTEON_ARGV_MAX_ARGS 64 55#define OCTEON_ARGV_MAX_ARGS 64
55#define OCTOEN_SERIAL_LEN 20 56#define OCTOEN_SERIAL_LEN 20