[RFC PATCH v1 14/20] arch/x86: Add ART nanosecond to ART conversion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Christopher Hall <christopher.s.hall@xxxxxxxxx>

The PWM 'apply' interface uses units of nominal nanoseconds for period and
the Intel(R) PMC Timed I/O hardware requires a period in terms of ART
cycles. Add a function using ART conversion coefficients determined at boot
time by the TSC initialization code to convert from ART in nominal
nanoseconds to ART cycles.

Signed-off-by: Christopher Hall <christopher.s.hall@xxxxxxxxx>
Signed-off-by: Tamal Saha <tamal.saha@xxxxxxxxx>
Signed-off-by: Lakshmi Sowjanya D <lakshmi.sowjanya.d@xxxxxxxxx>
Reviewed-by: Mark Gross <mgross@xxxxxxxxxxxxxxx>
---
 arch/x86/include/asm/tsc.h |  1 +
 arch/x86/kernel/tsc.c      | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index f1de7ede3ec9..e53507df92e1 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -34,6 +34,7 @@ extern u64 read_art_time(void);
 extern int convert_tsc_to_art(const struct system_counterval_t *tsc, u64 *art);
 extern struct system_counterval_t convert_art_to_tsc(u64 art);
 extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns);
+extern u64 convert_art_ns_to_art(u64 art_ns);
 
 extern void tsc_early_init(void);
 extern void tsc_init(void);
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 040109228100..381d15894dd2 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1329,6 +1329,38 @@ struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns)
 }
 EXPORT_SYMBOL(convert_art_ns_to_tsc);
 
+/*
+ * convert_art_ns_to_art() - Convert ART in nanoseconds to ART
+ * @art_ns: ART (Always Running Timer) in nominal nanoseconds
+ *
+ * Computes the ART cycles given the duration in nominal nanoseconds
+ *
+ * This is valid when CPU feature flag X86_FEATURE_TSC_KNOWN_FREQ is set
+ * indicating the tsc_khz is derived from CPUID[15H]. Drivers should check
+ * that this flag is set before conversion to ART is attempted.
+ *
+ * Return:
+ *	u64 ART value rounded to nearest cycle corresponding to nanosecond
+ *	duration input
+ */
+u64 convert_art_ns_to_art(u64 art_ns)
+{
+	u64 tmp, res, rem;
+	u32 crystal_khz;
+
+	crystal_khz = (tsc_khz * art_to_tsc_denominator) /
+		art_to_tsc_numerator;
+
+	rem = do_div(art_ns, USEC_PER_SEC);
+	res = art_ns * crystal_khz;
+	tmp = rem * crystal_khz;
+
+	rem = do_div(tmp, USEC_PER_SEC);
+	res += rem < USEC_PER_SEC / 2 ? tmp : tmp + 1;
+
+	return res;
+}
+EXPORT_SYMBOL(convert_art_ns_to_art);
 
 static void tsc_refine_calibration_work(struct work_struct *work);
 static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
-- 
2.17.1




[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux