[U-Boot] [PATCH v2 05/20] tegra: Add functions to access low-level Osc/PLL details

Simon Glass sjg at chromium.org
Fri Jan 13 22:35:20 CET 2012


Add clock_ll_read_pll() to read PLL parameters and clock_get_osc_bypass()
to find out if the Oscillator is bypassed. These are needed by warmboot.

Signed-off-by: Simon Glass <sjg at chromium.org>
---
Changes in v2:
- New patch to add low-level clock functions

 arch/arm/cpu/armv7/tegra2/clock.c          |   32 ++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/clk_rst.h |    3 ++
 arch/arm/include/asm/arch-tegra2/clock.h   |   22 +++++++++++++++++++
 3 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/armv7/tegra2/clock.c b/arch/arm/cpu/armv7/tegra2/clock.c
index 11d2346..82444dc 100644
--- a/arch/arm/cpu/armv7/tegra2/clock.c
+++ b/arch/arm/cpu/armv7/tegra2/clock.c
@@ -407,6 +407,16 @@ enum clock_osc_freq clock_get_osc_freq(void)
 	return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
 }
 
+int clock_get_osc_bypass(void)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 reg;
+
+	reg = readl(&clkrst->crc_osc_ctrl);
+	return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT;
+}
+
 /* Returns a pointer to the registers of the given pll */
 static struct clk_pll *get_pll(enum clock_id clkid)
 {
@@ -417,6 +427,28 @@ static struct clk_pll *get_pll(enum clock_id clkid)
 	return &clkrst->crc_pll[clkid];
 }
 
+int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
+		u32 *divp, u32 *cpcon, u32 *lfcon)
+{
+	struct clk_pll *pll = get_pll(clkid);
+	u32 data;
+
+	assert(clkid != CLOCK_ID_USB);
+
+	/* Safety check, adds to code size but is small */
+	if (!clock_id_isvalid(clkid) || clkid == CLOCK_ID_USB)
+		return -1;
+	data = readl(&pll->pll_base);
+	*divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
+	*divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT;
+	*divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
+	data = readl(&pll->pll_misc);
+	*cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT;
+	*lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT;
+
+	return 0;
+}
+
 unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
 		u32 divp, u32 cpcon, u32 lfcon)
 {
diff --git a/arch/arm/include/asm/arch-tegra2/clk_rst.h b/arch/arm/include/asm/arch-tegra2/clk_rst.h
index 0b6e004..e13b7f7 100644
--- a/arch/arm/include/asm/arch-tegra2/clk_rst.h
+++ b/arch/arm/include/asm/arch-tegra2/clk_rst.h
@@ -117,6 +117,7 @@ struct clk_rst_ctlr {
 #define PLL_CPCON_MASK		(15U << PLL_CPCON_SHIFT)
 
 #define PLL_LFCON_SHIFT		4
+#define PLL_LFCON_MASK		(15U << PLL_LFCON_SHIFT)
 
 #define PLLU_VCO_FREQ_SHIFT	20
 #define PLLU_VCO_FREQ_MASK	(1U << PLLU_VCO_FREQ_SHIFT)
@@ -124,6 +125,8 @@ struct clk_rst_ctlr {
 /* CLK_RST_CONTROLLER_OSC_CTRL_0 */
 #define OSC_FREQ_SHIFT		30
 #define OSC_FREQ_MASK		(3U << OSC_FREQ_SHIFT)
+#define OSC_XOBP_SHIFT		1
+#define OSC_XOBP_MASK		(1U << OSC_XOBP_SHIFT)
 
 /* CLK_RST_CONTROLLER_CLK_SOURCE_x_OUT_0 */
 #define OUT_CLK_DIVISOR_SHIFT	0
diff --git a/arch/arm/include/asm/arch-tegra2/clock.h b/arch/arm/include/asm/arch-tegra2/clock.h
index 080ef18..f5899a6 100644
--- a/arch/arm/include/asm/arch-tegra2/clock.h
+++ b/arch/arm/include/asm/arch-tegra2/clock.h
@@ -209,6 +209,21 @@ enum clock_osc_freq clock_get_osc_freq(void);
 unsigned long clock_start_pll(enum clock_id id, u32 divm, u32 divn,
 		u32 divp, u32 cpcon, u32 lfcon);
 
+/**
+ * Read low-level parameters of a PLL.
+ *
+ * @param id	clock id to read (note: USB is not supported)
+ * @param divm	returns input divider
+ * @param divn	returns feedback divider
+ * @param divp	returns post divider 2^n
+ * @param cpcon	returns charge pump setup control
+ * @param lfcon	returns loop filter setup control
+ *
+ * @returns 0 if ok, -1 on error (invalid clock id)
+ */
+int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
+		      u32 *divp, u32 *cpcon, u32 *lfcon);
+
 /*
  * Enable a clock
  *
@@ -355,6 +370,13 @@ unsigned clock_get_rate(enum clock_id clkid);
  */
 void clock_ll_start_uart(enum periph_id periph_id);
 
+/**
+ * Checks if the oscillator bypass is enabled (XOBP bit)
+ *
+ * @return 1 if bypass is enabled, 0 if not
+ */
+int clock_get_osc_bypass(void);
+
 /*
  * Checks that clocks are valid and prints a warning if not
  *
-- 
1.7.7.3



More information about the U-Boot mailing list