[PATCH v2 2/7] tegra: change clocksource driver to be more lowlevel

Lucas Stach dev at lynxeye.de
Sun Jun 30 17:08:44 EDT 2013


In order to properly bring up the system PLLs we need a reliable
clocksource. To break the circular dependency between the clocksource
and the CAR driver, get the OSC frequency with a lowlevel function.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 arch/arm/mach-tegra/include/mach/lowlevel.h | 23 +++++++++++++++++++++++
 arch/arm/mach-tegra/tegra20-timer.c         | 16 +++-------------
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-tegra/include/mach/lowlevel.h b/arch/arm/mach-tegra/include/mach/lowlevel.h
index b7c01c0..071416f 100644
--- a/arch/arm/mach-tegra/include/mach/lowlevel.h
+++ b/arch/arm/mach-tegra/include/mach/lowlevel.h
@@ -142,5 +142,28 @@ static inline long tegra20_get_debuguart_base(void)
 	return uart_id_to_base[id];
 }
 
+#define CRC_OSC_CTRL			0x050
+#define CRC_OSC_CTRL_OSC_FREQ_SHIFT	30
+#define CRC_OSC_CTRL_OSC_FREQ_MASK	(0x3 << CRC_OSC_CTRL_OSC_FREQ_SHIFT)
+
+static inline unsigned int tegra_get_osc_clock(void)
+{
+	u32 osc_ctrl = readl(TEGRA_CLK_RESET_BASE + CRC_OSC_CTRL);
+
+	switch ((osc_ctrl & CRC_OSC_CTRL_OSC_FREQ_MASK) >>
+		CRC_OSC_CTRL_OSC_FREQ_SHIFT) {
+	case 0:
+		return 13000000;
+	case 1:
+		return 19200000;
+	case 2:
+		return 12000000;
+	case 3:
+		return 26000000;
+	default:
+		return 0;
+	}
+}
+
 /* reset vector for the main CPU complex */
 void tegra_maincomplex_entry(void);
diff --git a/arch/arm/mach-tegra/tegra20-timer.c b/arch/arm/mach-tegra/tegra20-timer.c
index aafbfd4..2b32647 100644
--- a/arch/arm/mach-tegra/tegra20-timer.c
+++ b/arch/arm/mach-tegra/tegra20-timer.c
@@ -24,6 +24,7 @@
 #include <init.h>
 #include <io.h>
 #include <linux/clk.h>
+#include <mach/lowlevel.h>
 
 /* register definitions */
 #define TIMERUS_CNTR_1US	0x10
@@ -43,8 +44,6 @@ static struct clocksource cs = {
 
 static int tegra20_timer_probe(struct device_d *dev)
 {
-	struct clk *timer_clk;
-	unsigned long rate;
 	u32 reg;
 
 	/* use only one timer */
@@ -57,22 +56,13 @@ static int tegra20_timer_probe(struct device_d *dev)
 		return -ENODEV;
 	}
 
-	timer_clk = clk_get(dev, NULL);
-	if (!timer_clk) {
-		dev_err(dev, "could not get clock\n");
-		return -ENODEV;
-	}
-
-	clk_enable(timer_clk);
-
 	/*
 	 * calibrate timer to run at 1MHz
 	 * TIMERUS_USEC_CFG selects the scale down factor with bits [0:7]
 	 * representing the divisor and bits [8:15] representing the dividend
 	 * each in n+1 form.
 	 */
-	rate = clk_get_rate(timer_clk);
-	switch (rate) {
+	switch (tegra_get_osc_clock()) {
 	case 12000000:
 		reg = 0x000b;
 		break;
@@ -116,4 +106,4 @@ static int tegra20_timer_init(void)
 {
 	return platform_driver_register(&tegra20_timer_driver);
 }
-coredevice_initcall(tegra20_timer_init);
+core_initcall(tegra20_timer_init);
-- 
1.8.3.1




More information about the barebox mailing list