mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-26 22:52:18 +00:00
tegra: Add functions to access low-level Osc/PLL details
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@chromium.org> Signed-off-by: Tom Warren <twarren@nvidia.com>
This commit is contained in:
parent
f9f3e1b8df
commit
ffc76482c2
3 changed files with 57 additions and 0 deletions
|
@ -410,6 +410,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)
|
||||
{
|
||||
|
@ -420,6 +430,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)
|
||||
{
|
||||
|
|
|
@ -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 - the mask here is normally 8 bits
|
||||
|
|
|
@ -210,6 +210,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
|
||||
*
|
||||
|
@ -368,6 +383,13 @@ void clock_ll_start_uart(enum periph_id periph_id);
|
|||
*/
|
||||
enum periph_id clock_decode_periph_id(const void *blob, int node);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue