diff options
author | David Daney <ddaney@caviumnetworks.com> | 2010-06-01 16:18:15 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-08-05 08:26:20 -0400 |
commit | ca148125e6134de334b61822539d220794d8da18 (patch) | |
tree | e31af5840a8873ec6613bf9b09fe0f9ad3e6a9c7 /arch | |
parent | e6b78c4f224925c71cce57033b1e6e30dd56add7 (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')
-rw-r--r-- | arch/mips/cavium-octeon/csrc-octeon.c | 55 | ||||
-rw-r--r-- | arch/mips/cavium-octeon/setup.c | 4 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h | 11 | ||||
-rw-r--r-- | arch/mips/include/asm/octeon/octeon.h | 1 |
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 | |||
84 | static u64 octeon_udelay_factor; | ||
85 | static u64 octeon_ndelay_factor; | ||
86 | |||
87 | void __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 | |||
99 | void __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 | } | ||
111 | EXPORT_SYMBOL(__udelay); | ||
112 | |||
113 | void __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 | } | ||
125 | EXPORT_SYMBOL(__ndelay); | ||
126 | |||
127 | void __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 | } | ||
137 | EXPORT_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 | ||
70 | static 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, | |||
50 | extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task); | 50 | extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task); |
51 | 51 | ||
52 | extern void octeon_init_cvmcount(void); | 52 | extern void octeon_init_cvmcount(void); |
53 | extern 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 |