aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sn/ioc4.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sn/ioc4.c')
-rw-r--r--drivers/sn/ioc4.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c
index 8562821e6498..83d2e90c581c 100644
--- a/drivers/sn/ioc4.c
+++ b/drivers/sn/ioc4.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (C) 2005-2006 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9/* This file contains the master driver module for use by SGI IOC4 subdrivers. 9/* This file contains the master driver module for use by SGI IOC4 subdrivers.
@@ -29,9 +29,9 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/ioc4.h> 31#include <linux/ioc4.h>
32#include <linux/mmtimer.h> 32#include <linux/ktime.h>
33#include <linux/rtc.h>
34#include <linux/mutex.h> 33#include <linux/mutex.h>
34#include <linux/time.h>
35#include <asm/sn/addrs.h> 35#include <asm/sn/addrs.h>
36#include <asm/sn/clksupport.h> 36#include <asm/sn/clksupport.h>
37#include <asm/sn/shub_mmr.h> 37#include <asm/sn/shub_mmr.h>
@@ -43,7 +43,7 @@
43/* Tweakable values */ 43/* Tweakable values */
44 44
45/* PCI bus speed detection/calibration */ 45/* PCI bus speed detection/calibration */
46#define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */ 46#define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */
47#define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */ 47#define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */
48#define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */ 48#define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */
49#define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */ 49#define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */
@@ -143,11 +143,11 @@ ioc4_unregister_submodule(struct ioc4_submodule *is)
143static void 143static void
144ioc4_clock_calibrate(struct ioc4_driver_data *idd) 144ioc4_clock_calibrate(struct ioc4_driver_data *idd)
145{ 145{
146 extern unsigned long sn_rtc_cycles_per_second;
147 union ioc4_int_out int_out; 146 union ioc4_int_out int_out;
148 union ioc4_gpcr gpcr; 147 union ioc4_gpcr gpcr;
149 unsigned int state, last_state = 1; 148 unsigned int state, last_state = 1;
150 uint64_t start = 0, end, period; 149 struct timespec start_ts, end_ts;
150 uint64_t start, end, period;
151 unsigned int count = 0; 151 unsigned int count = 0;
152 152
153 /* Enable output */ 153 /* Enable output */
@@ -175,30 +175,28 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
175 if (!last_state && state) { 175 if (!last_state && state) {
176 count++; 176 count++;
177 if (count == IOC4_CALIBRATE_END) { 177 if (count == IOC4_CALIBRATE_END) {
178 end = rtc_time(); 178 ktime_get_ts(&end_ts);
179 break; 179 break;
180 } else if (count == IOC4_CALIBRATE_DISCARD) 180 } else if (count == IOC4_CALIBRATE_DISCARD)
181 start = rtc_time(); 181 ktime_get_ts(&start_ts);
182 } 182 }
183 last_state = state; 183 last_state = state;
184 } while (1); 184 } while (1);
185 185
186 /* Calculation rearranged to preserve intermediate precision. 186 /* Calculation rearranged to preserve intermediate precision.
187 * Logically: 187 * Logically:
188 * 1. "end - start" gives us number of RTC cycles over all the 188 * 1. "end - start" gives us the measurement period over all
189 * square wave cycles measured. 189 * the square wave cycles.
190 * 2. Divide by number of square wave cycles to get number of 190 * 2. Divide by number of square wave cycles to get the period
191 * RTC cycles per square wave cycle. 191 * of a square wave cycle.
192 * 3. Divide by 2*(int_out.fields.count+1), which is the formula 192 * 3. Divide by 2*(int_out.fields.count+1), which is the formula
193 * by which the IOC4 generates the square wave, to get the 193 * by which the IOC4 generates the square wave, to get the
194 * number of RTC cycles per IOC4 INT_OUT count. 194 * period of an IOC4 INT_OUT count.
195 * 4. Divide by sn_rtc_cycles_per_second to get seconds per
196 * count.
197 * 5. Multiply by 1E9 to get nanoseconds per count.
198 */ 195 */
199 period = ((end - start) * 1000000000) / 196 end = end_ts.tv_sec * NSEC_PER_SEC + end_ts.tv_nsec;
200 (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1) 197 start = start_ts.tv_sec * NSEC_PER_SEC + start_ts.tv_nsec;
201 * sn_rtc_cycles_per_second); 198 period = (end - start) /
199 (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1));
202 200
203 /* Bounds check the result. */ 201 /* Bounds check the result. */
204 if (period > IOC4_CALIBRATE_LOW_LIMIT || 202 if (period > IOC4_CALIBRATE_LOW_LIMIT ||