Tegra: PLL: use per-SoC pllinfo table instead of PLL_DIVM/N/P, etc.
Added PLL variables (dividers mask/shift, lock enable/detect, etc.) to new pllinfo struct for each Soc/PLL. PLLA/C/D/E/M/P/U/X. Used pllinfo struct in all clock functions, validated on T210. Should be equivalent to prior code on T124/114/30/20. Thanks to Marcel Ziswiler for corrections to the T20/T30 values. Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com> Signed-off-by: Tom Warren <twarren@nvidia.com>
This commit is contained in:
		
							parent
							
								
									3e8650c0f9
								
							
						
					
					
						commit
						722e000ccd
					
				|  | @ -249,17 +249,6 @@ struct clk_rst_ctlr { | ||||||
| #define PLL_LOCK_SHIFT		27 | #define PLL_LOCK_SHIFT		27 | ||||||
| #define PLL_LOCK_MASK		(1U << PLL_LOCK_SHIFT) | #define PLL_LOCK_MASK		(1U << PLL_LOCK_SHIFT) | ||||||
| 
 | 
 | ||||||
| #define PLL_DIVP_SHIFT		20 |  | ||||||
| #define PLL_DIVP_MASK		(7U << PLL_DIVP_SHIFT) |  | ||||||
| /* Special case for T210 PLLU DIVP */ |  | ||||||
| #define PLLU_DIVP_SHIFT		16 |  | ||||||
| 
 |  | ||||||
| #define PLL_DIVN_SHIFT		8 |  | ||||||
| #define PLL_DIVN_MASK		(0x3ffU << PLL_DIVN_SHIFT) |  | ||||||
| 
 |  | ||||||
| #define PLL_DIVM_SHIFT		0 |  | ||||||
| #define PLL_DIVM_MASK		(0x1f << PLL_DIVM_SHIFT) |  | ||||||
| 
 |  | ||||||
| /* CLK_RST_CONTROLLER_PLLx_OUTx_0 */ | /* CLK_RST_CONTROLLER_PLLx_OUTx_0 */ | ||||||
| #define PLL_OUT_RSTN		(1 << 0) | #define PLL_OUT_RSTN		(1 << 0) | ||||||
| #define PLL_OUT_CLKEN		(1 << 1) | #define PLL_OUT_CLKEN		(1 << 1) | ||||||
|  | @ -272,24 +261,6 @@ struct clk_rst_ctlr { | ||||||
| #define PLL_DCCON_SHIFT		20 | #define PLL_DCCON_SHIFT		20 | ||||||
| #define PLL_DCCON_MASK		(1U << PLL_DCCON_SHIFT) | #define PLL_DCCON_MASK		(1U << PLL_DCCON_SHIFT) | ||||||
| 
 | 
 | ||||||
| #define PLL_LOCK_ENABLE_SHIFT	18 |  | ||||||
| #define PLL_LOCK_ENABLE_MASK	(1U << PLL_LOCK_ENABLE_SHIFT) |  | ||||||
| 
 |  | ||||||
| #define PLL_CPCON_SHIFT		8 |  | ||||||
| #define PLL_CPCON_MASK		(15U << PLL_CPCON_SHIFT) |  | ||||||
| 
 |  | ||||||
| #define PLL_LFCON_SHIFT		4 |  | ||||||
| #define PLL_LFCON_MASK		(15U << PLL_LFCON_SHIFT) |  | ||||||
| 
 |  | ||||||
| /* CPCON/LFCON replaced by KCP/KVCO in T210 PLLU */ |  | ||||||
| #define PLLU_KVCO_SHIFT		24 |  | ||||||
| #define PLLU_KVCO_MASK		(3U << PLLU_KVCO_SHIFT) |  | ||||||
| #define PLLU_KCP_SHIFT		25 |  | ||||||
| #define PLLU_KCP_MASK		(1U << PLLU_KCP_SHIFT) |  | ||||||
| 
 |  | ||||||
| #define PLLU_VCO_FREQ_SHIFT	20 |  | ||||||
| #define PLLU_VCO_FREQ_MASK	(1U << PLLU_VCO_FREQ_SHIFT) |  | ||||||
| 
 |  | ||||||
| #define PLLP_OUT1_OVR		(1 << 2) | #define PLLP_OUT1_OVR		(1 << 2) | ||||||
| #define PLLP_OUT2_OVR		(1 << 18) | #define PLLP_OUT2_OVR		(1 << 18) | ||||||
| #define PLLP_OUT3_OVR		(1 << 2) | #define PLLP_OUT3_OVR		(1 << 2) | ||||||
|  | @ -475,4 +446,7 @@ enum { | ||||||
| #define PLLDP_SS_CFG_UNDOCUMENTED	(1 << 24) | #define PLLDP_SS_CFG_UNDOCUMENTED	(1 << 24) | ||||||
| #define PLLDP_SS_CFG_DITHER		(1 << 28) | #define PLLDP_SS_CFG_DITHER		(1 << 28) | ||||||
| 
 | 
 | ||||||
|  | /* CLK_RST_PLLD_MISC */ | ||||||
|  | #define PLLD_CLKENABLE			30 | ||||||
|  | 
 | ||||||
| #endif	/* _TEGRA_CLK_RST_H_ */ | #endif	/* _TEGRA_CLK_RST_H_ */ | ||||||
|  |  | ||||||
|  | @ -338,6 +338,27 @@ void arch_timer_init(void); | ||||||
| 
 | 
 | ||||||
| void tegra30_set_up_pllp(void); | void tegra30_set_up_pllp(void); | ||||||
| 
 | 
 | ||||||
|  | /* Number of PLL-based clocks (i.e. not OSC or 32KHz) */ | ||||||
|  | #define CLOCK_ID_PLL_COUNT	(CLOCK_ID_COUNT - 2) | ||||||
|  | 
 | ||||||
|  | struct clk_pll_info { | ||||||
|  | 	u32	m_shift:5;	/* DIVM_SHIFT */ | ||||||
|  | 	u32	n_shift:5;	/* DIVN_SHIFT */ | ||||||
|  | 	u32	p_shift:5;	/* DIVP_SHIFT */ | ||||||
|  | 	u32	kcp_shift:5;	/* KCP/cpcon SHIFT */ | ||||||
|  | 	u32	kvco_shift:5;	/* KVCO/lfcon SHIFT */ | ||||||
|  | 	u32	lock_ena:6;	/* LOCK_ENABLE/EN_LOCKDET shift */ | ||||||
|  | 	u32	rsvd:1; | ||||||
|  | 	u32	m_mask:10;	/* DIVM_MASK */ | ||||||
|  | 	u32	n_mask:12;	/* DIVN_MASK */ | ||||||
|  | 	u32	p_mask:10;	/* DIVP_MASK or VCO_MASK */ | ||||||
|  | 	u32	kcp_mask:10;	/* KCP/CPCON MASK */ | ||||||
|  | 	u32	kvco_mask:10;	/* KVCO/LFCON MASK */ | ||||||
|  | 	u32	lock_det:6;	/* LOCK_DETECT/LOCKED shift */ | ||||||
|  | 	u32	rsvd2:6; | ||||||
|  | }; | ||||||
|  | extern struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT]; | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Enable output clock for external peripherals |  * Enable output clock for external peripherals | ||||||
|  * |  * | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ enum clock_id { | ||||||
| 	CLOCK_ID_XCPU = CLOCK_ID_FIRST_SIMPLE, | 	CLOCK_ID_XCPU = CLOCK_ID_FIRST_SIMPLE, | ||||||
| 	CLOCK_ID_EPCI, | 	CLOCK_ID_EPCI, | ||||||
| 	CLOCK_ID_SFROM32KHZ, | 	CLOCK_ID_SFROM32KHZ, | ||||||
|  | 	CLOCK_ID_DP, | ||||||
| 
 | 
 | ||||||
| 	/* These are the base clocks (inputs to the Tegra SoC) */ | 	/* These are the base clocks (inputs to the Tegra SoC) */ | ||||||
| 	CLOCK_ID_32KHZ, | 	CLOCK_ID_32KHZ, | ||||||
|  |  | ||||||
|  | @ -101,6 +101,7 @@ int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, | ||||||
| 		u32 *divp, u32 *cpcon, u32 *lfcon) | 		u32 *divp, u32 *cpcon, u32 *lfcon) | ||||||
| { | { | ||||||
| 	struct clk_pll *pll = get_pll(clkid); | 	struct clk_pll *pll = get_pll(clkid); | ||||||
|  | 	struct clk_pll_info *pllinfo = &tegra_pll_info_table[clkid]; | ||||||
| 	u32 data; | 	u32 data; | ||||||
| 
 | 
 | ||||||
| 	assert(clkid != CLOCK_ID_USB); | 	assert(clkid != CLOCK_ID_USB); | ||||||
|  | @ -109,17 +110,14 @@ int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, | ||||||
| 	if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB) | 	if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB) | ||||||
| 		return -1; | 		return -1; | ||||||
| 	data = readl(&pll->pll_base); | 	data = readl(&pll->pll_base); | ||||||
| 	*divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; | 	*divm = (data >> pllinfo->m_shift) & pllinfo->m_mask; | ||||||
| 	*divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT; | 	*divn = (data >> pllinfo->n_shift) & pllinfo->n_mask; | ||||||
| 	*divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; | 	*divp = (data >> pllinfo->p_shift) & pllinfo->p_mask; | ||||||
| 	data = readl(&pll->pll_misc); | 	data = readl(&pll->pll_misc); | ||||||
| 	*cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT; | 	/* NOTE: On T210, cpcon/lfcon no longer exist, moved to KCP/KVCO */ | ||||||
| 	*lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT; | 	*cpcon = (data >> pllinfo->kcp_shift) & pllinfo->kcp_mask; | ||||||
| #if defined(CONFIG_TEGRA210) | 	*lfcon = (data >> pllinfo->kvco_shift) & pllinfo->kvco_mask; | ||||||
| 	/* T210 PLLU uses KCP/KVCO instead of CPCON/LFCON */ | 
 | ||||||
| 	*cpcon = (data & PLLU_KCP_MASK) >> PLLU_KCP_SHIFT; |  | ||||||
| 	*lfcon = (data & PLLU_KVCO_MASK) >> PLLU_KVCO_SHIFT; |  | ||||||
| #endif |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -127,41 +125,25 @@ unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, | ||||||
| 		u32 divp, u32 cpcon, u32 lfcon) | 		u32 divp, u32 cpcon, u32 lfcon) | ||||||
| { | { | ||||||
| 	struct clk_pll *pll = NULL; | 	struct clk_pll *pll = NULL; | ||||||
|  | 	struct clk_pll_info *pllinfo = &tegra_pll_info_table[clkid]; | ||||||
| 	u32 misc_data, data; | 	u32 misc_data, data; | ||||||
| 
 | 
 | ||||||
| 	if (clkid < (enum clock_id)TEGRA_CLK_PLLS) | 	if (clkid < (enum clock_id)TEGRA_CLK_PLLS) | ||||||
| 		pll = get_pll(clkid); | 		pll = get_pll(clkid); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * We cheat by treating all PLL (except PLLU) in the same fashion. | 	 * pllinfo has the m/n/p and kcp/kvco mask and shift | ||||||
| 	 * This works only because: | 	 * values for all of the PLLs used in U-Boot, with any | ||||||
| 	 * - same fields are always mapped at same offsets, except DCCON | 	 * SoC differences accounted for. | ||||||
| 	 * - DCCON is always 0, doesn't conflict |  | ||||||
| 	 * - M,N, P of PLLP values are ignored for PLLP |  | ||||||
| 	 * NOTE: Above is no longer true with T210 - TBD: FIX THIS |  | ||||||
| 	 */ | 	 */ | ||||||
| 	misc_data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT); | 	misc_data = readl(&pll->pll_misc);	/* preserve EN_LOCKDET, etc. */ | ||||||
|  | 	misc_data &= ~(pllinfo->kcp_mask << pllinfo->kcp_shift) | (cpcon << pllinfo->kcp_shift); | ||||||
|  | 	misc_data &= ~(pllinfo->kvco_mask << pllinfo->kvco_shift) | (lfcon << pllinfo->kvco_shift); | ||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_TEGRA210) | 	data = (divm << pllinfo->m_shift) | (divn << pllinfo->n_shift); | ||||||
| 	/* T210 PLLU uses KCP/KVCO instead of cpcon/lfcon */ | 	data |= divp << pllinfo->p_shift; | ||||||
| 	if (clkid == CLOCK_ID_USB) { | 	data |= (1 << PLL_ENABLE_SHIFT);	/* BYPASS s/b 0 already */ | ||||||
| 		/* preserve EN_LOCKDET, set by default */ |  | ||||||
| 		misc_data = readl(&pll->pll_misc); |  | ||||||
| 		misc_data |= (cpcon << PLLU_KCP_SHIFT) | |  | ||||||
| 			(lfcon << PLLU_KVCO_SHIFT); |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
| 	data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) | |  | ||||||
| 			(0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT); |  | ||||||
| 
 | 
 | ||||||
| 	if (clkid == CLOCK_ID_USB) |  | ||||||
| #if defined(CONFIG_TEGRA210) |  | ||||||
| 		data |= divp << PLLU_DIVP_SHIFT; |  | ||||||
| #else |  | ||||||
| 		data |= divp << PLLU_VCO_FREQ_SHIFT; |  | ||||||
| #endif |  | ||||||
| 	else |  | ||||||
| 		data |= divp << PLL_DIVP_SHIFT; |  | ||||||
| 	if (pll) { | 	if (pll) { | ||||||
| 		writel(misc_data, &pll->pll_misc); | 		writel(misc_data, &pll->pll_misc); | ||||||
| 		writel(data, &pll->pll_base); | 		writel(data, &pll->pll_base); | ||||||
|  | @ -473,10 +455,9 @@ void reset_cmplx_set_enable(int cpu, int which, int reset) | ||||||
| unsigned clock_get_rate(enum clock_id clkid) | unsigned clock_get_rate(enum clock_id clkid) | ||||||
| { | { | ||||||
| 	struct clk_pll *pll; | 	struct clk_pll *pll; | ||||||
| 	u32 base; | 	u32 base, divm; | ||||||
| 	u32 divm; | 	u64 parent_rate, rate; | ||||||
| 	u64 parent_rate; | 	struct clk_pll_info *pllinfo = &tegra_pll_info_table[clkid]; | ||||||
| 	u64 rate; |  | ||||||
| 
 | 
 | ||||||
| 	parent_rate = osc_freq[clock_get_osc_freq()]; | 	parent_rate = osc_freq[clock_get_osc_freq()]; | ||||||
| 	if (clkid == CLOCK_ID_OSC) | 	if (clkid == CLOCK_ID_OSC) | ||||||
|  | @ -487,13 +468,13 @@ unsigned clock_get_rate(enum clock_id clkid) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	base = readl(&pll->pll_base); | 	base = readl(&pll->pll_base); | ||||||
| 
 | 
 | ||||||
| 	/* Oh for bf_unpack()... */ | 	rate = parent_rate * ((base >> pllinfo->n_shift) & pllinfo->n_mask); | ||||||
| 	rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT); | 	divm = (base >> pllinfo->m_shift) & pllinfo->m_mask; | ||||||
| 	divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; | 	/*
 | ||||||
| 	if (clkid == CLOCK_ID_USB) | 	 * PLLU uses p_mask/p_shift for VCO on all but T210, | ||||||
| 		divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT; | 	 * T210 uses normal DIVP. Handled in pllinfo table. | ||||||
| 	else | 	 */ | ||||||
| 		divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; | 	divm <<= (base >> pllinfo->p_shift) & pllinfo->p_mask; | ||||||
| 	do_div(rate, divm); | 	do_div(rate, divm); | ||||||
| 	return rate; | 	return rate; | ||||||
| } | } | ||||||
|  | @ -517,23 +498,23 @@ unsigned clock_get_rate(enum clock_id clkid) | ||||||
|  */ |  */ | ||||||
| int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) | int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) | ||||||
| { | { | ||||||
| 	u32 base_reg; | 	u32 base_reg, misc_reg; | ||||||
| 	u32 misc_reg; |  | ||||||
| 	struct clk_pll *pll; | 	struct clk_pll *pll; | ||||||
|  | 	struct clk_pll_info *pllinfo = &tegra_pll_info_table[clkid]; | ||||||
| 
 | 
 | ||||||
| 	pll = get_pll(clkid); | 	pll = get_pll(clkid); | ||||||
| 
 | 
 | ||||||
| 	base_reg = readl(&pll->pll_base); | 	base_reg = readl(&pll->pll_base); | ||||||
| 
 | 
 | ||||||
| 	/* Set BYPASS, m, n and p to PLL_BASE */ | 	/* Set BYPASS, m, n and p to PLL_BASE */ | ||||||
| 	base_reg &= ~PLL_DIVM_MASK; | 	base_reg &= ~(pllinfo->m_mask << pllinfo->m_shift); | ||||||
| 	base_reg |= m << PLL_DIVM_SHIFT; | 	base_reg |= m << pllinfo->m_shift; | ||||||
| 
 | 
 | ||||||
| 	base_reg &= ~PLL_DIVN_MASK; | 	base_reg &= ~(pllinfo->n_mask << pllinfo->n_shift); | ||||||
| 	base_reg |= n << PLL_DIVN_SHIFT; | 	base_reg |= n << pllinfo->n_shift; | ||||||
| 
 | 
 | ||||||
| 	base_reg &= ~PLL_DIVP_MASK; | 	base_reg &= ~(pllinfo->p_mask << pllinfo->p_shift); | ||||||
| 	base_reg |= p << PLL_DIVP_SHIFT; | 	base_reg |= p << pllinfo->p_shift; | ||||||
| 
 | 
 | ||||||
| 	if (clkid == CLOCK_ID_PERIPH) { | 	if (clkid == CLOCK_ID_PERIPH) { | ||||||
| 		/*
 | 		/*
 | ||||||
|  | @ -552,17 +533,10 @@ int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) | ||||||
| 	base_reg |= PLL_BYPASS_MASK; | 	base_reg |= PLL_BYPASS_MASK; | ||||||
| 	writel(base_reg, &pll->pll_base); | 	writel(base_reg, &pll->pll_base); | ||||||
| 
 | 
 | ||||||
| 	/* Set cpcon to PLL_MISC */ | 	/* Set cpcon (KCP) to PLL_MISC */ | ||||||
| 	misc_reg = readl(&pll->pll_misc); | 	misc_reg = readl(&pll->pll_misc); | ||||||
| #if !defined(CONFIG_TEGRA210) | 	misc_reg &= ~(pllinfo->kcp_mask << pllinfo->kcp_shift); | ||||||
| 	misc_reg &= ~PLL_CPCON_MASK; | 	misc_reg |= cpcon << pllinfo->kcp_shift; | ||||||
| 	misc_reg |= cpcon << PLL_CPCON_SHIFT; |  | ||||||
| #else |  | ||||||
| 	/* T210 uses KCP instead, use the most common bit shift (PLLA/U/D2) */ |  | ||||||
| 	misc_reg &= ~PLLU_KCP_MASK; |  | ||||||
| 	misc_reg |= cpcon << PLLU_KCP_SHIFT; |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 	writel(misc_reg, &pll->pll_misc); | 	writel(misc_reg, &pll->pll_misc); | ||||||
| 
 | 
 | ||||||
| 	/* Enable PLL */ | 	/* Enable PLL */ | ||||||
|  |  | ||||||
|  | @ -181,6 +181,7 @@ static inline void pllx_set_iddq(void) | ||||||
| int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, | int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, | ||||||
| 		u32 divp, u32 cpcon) | 		u32 divp, u32 cpcon) | ||||||
| { | { | ||||||
|  | 	struct clk_pll_info *pllinfo = &tegra_pll_info_table[CLOCK_ID_XCPU]; | ||||||
| 	int chip = tegra_get_chip(); | 	int chip = tegra_get_chip(); | ||||||
| 	u32 reg; | 	u32 reg; | ||||||
| 	debug("%s entry\n", __func__); | 	debug("%s entry\n", __func__); | ||||||
|  | @ -194,17 +195,21 @@ int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, | ||||||
| 	pllx_set_iddq(); | 	pllx_set_iddq(); | ||||||
| 
 | 
 | ||||||
| 	/* Set BYPASS, m, n and p to PLLX_BASE */ | 	/* Set BYPASS, m, n and p to PLLX_BASE */ | ||||||
| 	reg = PLL_BYPASS_MASK | (divm << PLL_DIVM_SHIFT); | 	reg = PLL_BYPASS_MASK | (divm << pllinfo->m_shift); | ||||||
| 	reg |= ((divn << PLL_DIVN_SHIFT) | (divp << PLL_DIVP_SHIFT)); | 	reg |= (divn << pllinfo->n_shift) | (divp << pllinfo->p_shift); | ||||||
| 	writel(reg, &pll->pll_base); | 	writel(reg, &pll->pll_base); | ||||||
| 
 | 
 | ||||||
| 	/* Set cpcon to PLLX_MISC */ | 	/* Set cpcon to PLLX_MISC */ | ||||||
| 	if (chip == CHIPID_TEGRA20 || chip == CHIPID_TEGRA30) | 	if (chip == CHIPID_TEGRA20 || chip == CHIPID_TEGRA30) | ||||||
| 		reg = (cpcon << PLL_CPCON_SHIFT); | 		reg = (cpcon << pllinfo->kcp_shift); | ||||||
| 	else | 	else | ||||||
| 		reg = 0; | 		reg = 0; | ||||||
| 
 | 
 | ||||||
| 	/* Set dccon to PLLX_MISC if freq > 600MHz */ | 	/*
 | ||||||
|  | 	 * TODO(twarren@nvidia.com) Check which SoCs use DCCON | ||||||
|  | 	 * and add to pllinfo table if needed! | ||||||
|  | 	 */ | ||||||
|  | 	 /* Set dccon to PLLX_MISC if freq > 600MHz */ | ||||||
| 	if (divn > 600) | 	if (divn > 600) | ||||||
| 		reg |= (1 << PLL_DCCON_SHIFT); | 		reg |= (1 << PLL_DCCON_SHIFT); | ||||||
| 	writel(reg, &pll->pll_misc); | 	writel(reg, &pll->pll_misc); | ||||||
|  | @ -215,9 +220,10 @@ int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, | ||||||
| 	writel(reg, &pll->pll_base); | 	writel(reg, &pll->pll_base); | ||||||
| 	debug("%s: base = 0x%08X\n", __func__, reg); | 	debug("%s: base = 0x%08X\n", __func__, reg); | ||||||
| 
 | 
 | ||||||
| 	/* Set lock_enable to PLLX_MISC */ | 	/* Set lock_enable to PLLX_MISC if lock_ena is valid (i.e. 0-31) */ | ||||||
| 	reg = readl(&pll->pll_misc); | 	reg = readl(&pll->pll_misc); | ||||||
| 	reg |= PLL_LOCK_ENABLE_MASK; | 	if (pllinfo->lock_ena < 32) | ||||||
|  | 		reg |= (1 << pllinfo->lock_ena); | ||||||
| 	writel(reg, &pll->pll_misc); | 	writel(reg, &pll->pll_misc); | ||||||
| 	debug("%s: misc = 0x%08X\n", __func__, reg); | 	debug("%s: misc = 0x%08X\n", __func__, reg); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,17 +1,8 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (c) 2010-2014, NVIDIA CORPORATION.  All rights reserved. |  * (C) Copyright 2010-2015 | ||||||
|  |  * NVIDIA Corporation <www.nvidia.com> | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify it |  * SPDX-License-Identifier:     GPL-2.0+ | ||||||
|  * under the terms and conditions of the GNU General Public License, |  | ||||||
|  * version 2, as published by the Free Software Foundation. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope it will be useful, but WITHOUT |  | ||||||
|  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |  | ||||||
|  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for |  | ||||||
|  * more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU General Public License |  | ||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 |  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /* Tegra114 Clock control functions */ | /* Tegra114 Clock control functions */ | ||||||
|  | @ -434,6 +425,36 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { | ||||||
| 	NONE(EMC1), | 	NONE(EMC1), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * PLL divider shift/mask tables for all PLL IDs. | ||||||
|  |  */ | ||||||
|  | struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { | ||||||
|  | 	/*
 | ||||||
|  | 	 * T114: some deviations from T2x/T30. | ||||||
|  | 	 * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLX, etc.) | ||||||
|  | 	 *       If lock_ena or lock_det are >31, they're not used in that PLL. | ||||||
|  | 	 */ | ||||||
|  | 
 | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 20, .p_mask = 0x0F, | ||||||
|  | 	  .lock_ena = 24, .lock_det = 27, .kcp_shift = 28, .kcp_mask = 3, .kvco_shift = 27, .kvco_mask = 1 },	/* PLLC */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 0,  .p_mask = 0, | ||||||
|  | 	  .lock_ena = 0,  .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLM */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLP */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLA */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x01, | ||||||
|  | 	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLU */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLD */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 20, .p_mask = 0x0F, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 0, .kcp_mask = 0, .kvco_shift = 0, .kvco_mask = 0 },	/* PLLX */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 0,  .p_mask = 0, | ||||||
|  | 	  .lock_ena = 9,  .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLE */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLS (RESERVED) */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Get the oscillator frequency, from the corresponding hardware configuration |  * Get the oscillator frequency, from the corresponding hardware configuration | ||||||
|  * field. Note that T30/T114 support 3 new higher freqs, but we map back |  * field. Note that T30/T114 support 3 new higher freqs, but we map back | ||||||
|  | @ -603,6 +624,8 @@ void clock_early_init(void) | ||||||
| { | { | ||||||
| 	struct clk_rst_ctlr *clkrst = | 	struct clk_rst_ctlr *clkrst = | ||||||
| 		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | ||||||
|  | 	struct clk_pll_info *pllinfo; | ||||||
|  | 	u32 data; | ||||||
| 
 | 
 | ||||||
| 	tegra30_set_up_pllp(); | 	tegra30_set_up_pllp(); | ||||||
| 
 | 
 | ||||||
|  | @ -639,11 +662,15 @@ void clock_early_init(void) | ||||||
| 	writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); | 	writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); | ||||||
| 
 | 
 | ||||||
| 	/* PLLC_MISC: Set LOCK_ENABLE */ | 	/* PLLC_MISC: Set LOCK_ENABLE */ | ||||||
| 	writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc); | 	pllinfo = &tegra_pll_info_table[CLOCK_ID_CGENERAL]; | ||||||
|  | 	setbits_le32(&clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc, (1 << pllinfo->lock_ena)); | ||||||
| 	udelay(2); | 	udelay(2); | ||||||
| 
 | 
 | ||||||
| 	/* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */ | 	/* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1, and enable lock */ | ||||||
| 	writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); | 	pllinfo = &tegra_pll_info_table[CLOCK_ID_DISPLAY]; | ||||||
|  | 	data = (12 << pllinfo->kcp_shift) | (1 << pllinfo->kvco_shift); | ||||||
|  | 	data |= (1 << PLLD_CLKENABLE) | (1 << pllinfo->lock_ena); | ||||||
|  | 	writel(data, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); | ||||||
| 	udelay(2); | 	udelay(2); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,17 +1,8 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (c) 2010-2014, NVIDIA CORPORATION.  All rights reserved. |  * (C) Copyright 2010-2014 | ||||||
|  |  * NVIDIA Corporation <www.nvidia.com> | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify it |  * SPDX-License-Identifier:     GPL-2.0+ | ||||||
|  * under the terms and conditions of the GNU General Public License, |  | ||||||
|  * version 2, as published by the Free Software Foundation. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope it will be useful, but WITHOUT |  | ||||||
|  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |  | ||||||
|  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for |  | ||||||
|  * more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU General Public License |  | ||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 |  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
|  | @ -31,7 +22,7 @@ static void enable_cpu_power_rail(void) | ||||||
| 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | ||||||
| 	u32 reg; | 	u32 reg; | ||||||
| 
 | 
 | ||||||
| 	debug("enable_cpu_power_rail entry\n"); | 	debug("%s entry\n", __func__); | ||||||
| 
 | 
 | ||||||
| 	/* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ | 	/* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ | ||||||
| 	pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6); | 	pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6); | ||||||
|  | @ -61,14 +52,15 @@ static void enable_cpu_power_rail(void) | ||||||
| static void enable_cpu_clocks(void) | static void enable_cpu_clocks(void) | ||||||
| { | { | ||||||
| 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | ||||||
|  | 	struct clk_pll_info *pllinfo = &tegra_pll_info_table[CLOCK_ID_XCPU]; | ||||||
| 	u32 reg; | 	u32 reg; | ||||||
| 
 | 
 | ||||||
| 	debug("enable_cpu_clocks entry\n"); | 	debug("%s entry\n", __func__); | ||||||
| 
 | 
 | ||||||
| 	/* Wait for PLL-X to lock */ | 	/* Wait for PLL-X to lock */ | ||||||
| 	do { | 	do { | ||||||
| 		reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); | 		reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); | ||||||
| 	} while ((reg & PLL_LOCK_MASK) == 0); | 	} while ((reg & (1 << pllinfo->lock_det)) == 0); | ||||||
| 
 | 
 | ||||||
| 	/* Wait until all clocks are stable */ | 	/* Wait until all clocks are stable */ | ||||||
| 	udelay(PLL_STABILIZATION_DELAY); | 	udelay(PLL_STABILIZATION_DELAY); | ||||||
|  | @ -87,7 +79,7 @@ static void remove_cpu_resets(void) | ||||||
| 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | ||||||
| 	u32 reg; | 	u32 reg; | ||||||
| 
 | 
 | ||||||
| 	debug("remove_cpu_resets entry\n"); | 	debug("%s entry\n", __func__); | ||||||
| 	/* Take the slow non-CPU partition out of reset */ | 	/* Take the slow non-CPU partition out of reset */ | ||||||
| 	reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr); | 	reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr); | ||||||
| 	writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpulp_cmplx_clr); | 	writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpulp_cmplx_clr); | ||||||
|  | @ -111,7 +103,7 @@ static void remove_cpu_resets(void) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * The T114 requires some special clock initialization, including setting up |  * Tegra114 requires some special clock initialization, including setting up | ||||||
|  * the DVC I2C, turning on MSELECT and selecting the G CPU cluster |  * the DVC I2C, turning on MSELECT and selecting the G CPU cluster | ||||||
|  */ |  */ | ||||||
| void t114_init_clocks(void) | void t114_init_clocks(void) | ||||||
|  | @ -121,7 +113,7 @@ void t114_init_clocks(void) | ||||||
| 	struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; | 	struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; | ||||||
| 	u32 val; | 	u32 val; | ||||||
| 
 | 
 | ||||||
| 	debug("t114_init_clocks entry\n"); | 	debug("%s entry\n", __func__); | ||||||
| 
 | 
 | ||||||
| 	/* Set active CPU cluster to G */ | 	/* Set active CPU cluster to G */ | ||||||
| 	clrbits_le32(&flow->cluster_control, 1); | 	clrbits_le32(&flow->cluster_control, 1); | ||||||
|  | @ -189,7 +181,7 @@ void t114_init_clocks(void) | ||||||
| 	reset_set_enable(PERIPH_ID_MC1, 0); | 	reset_set_enable(PERIPH_ID_MC1, 0); | ||||||
| 	reset_set_enable(PERIPH_ID_DVFS, 0); | 	reset_set_enable(PERIPH_ID_DVFS, 0); | ||||||
| 
 | 
 | ||||||
| 	debug("t114_init_clocks exit\n"); | 	debug("%s exit\n", __func__); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool is_partition_powered(u32 partid) | static bool is_partition_powered(u32 partid) | ||||||
|  | @ -238,10 +230,9 @@ static void power_partition(u32 partid) | ||||||
| 
 | 
 | ||||||
| void powerup_cpus(void) | void powerup_cpus(void) | ||||||
| { | { | ||||||
| 	debug("powerup_cpus entry\n"); |  | ||||||
| 
 |  | ||||||
| 	/* We boot to the fast cluster */ | 	/* We boot to the fast cluster */ | ||||||
| 	debug("powerup_cpus entry: G cluster\n"); | 	debug("%s entry: G cluster\n", __func__); | ||||||
|  | 
 | ||||||
| 	/* Power up the fast cluster rail partition */ | 	/* Power up the fast cluster rail partition */ | ||||||
| 	power_partition(CRAIL); | 	power_partition(CRAIL); | ||||||
| 
 | 
 | ||||||
|  | @ -256,7 +247,7 @@ void start_cpu(u32 reset_vector) | ||||||
| { | { | ||||||
| 	u32 imme, inst; | 	u32 imme, inst; | ||||||
| 
 | 
 | ||||||
| 	debug("start_cpu entry, reset_vector = %x\n", reset_vector); | 	debug("%s entry, reset_vector = %x\n", __func__, reset_vector); | ||||||
| 
 | 
 | ||||||
| 	t114_init_clocks(); | 	t114_init_clocks(); | ||||||
| 
 | 
 | ||||||
|  | @ -302,7 +293,7 @@ void start_cpu(u32 reset_vector) | ||||||
| 	inst |= 0xea000000; | 	inst |= 0xea000000; | ||||||
| 	writel(inst, 0x4003fffc); | 	writel(inst, 0x4003fffc); | ||||||
| 
 | 
 | ||||||
| 	/* Write to orignal location for compatibility */ | 	/* Write to original location for compatibility */ | ||||||
| 	writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); | 	writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); | ||||||
| 
 | 
 | ||||||
| 	/* If the CPU(s) don't already have power, power 'em up */ | 	/* If the CPU(s) don't already have power, power 'em up */ | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * (C) Copyright 2013 |  * (C) Copyright 2013-2015 | ||||||
|  * NVIDIA Corporation <www.nvidia.com> |  * NVIDIA Corporation <www.nvidia.com> | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier:     GPL-2.0+ |  * SPDX-License-Identifier:     GPL-2.0+ | ||||||
|  | @ -565,6 +565,36 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { | ||||||
| 	NONE(X_RESERVED31), | 	NONE(X_RESERVED31), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * PLL divider shift/mask tables for all PLL IDs. | ||||||
|  |  */ | ||||||
|  | struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { | ||||||
|  | 	/*
 | ||||||
|  | 	 * T124: same as T114, some deviations from T2x/T30. | ||||||
|  | 	 * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLX, etc.) | ||||||
|  | 	 *       If lock_ena or lock_det are >31, they're not used in that PLL. | ||||||
|  | 	 */ | ||||||
|  | 
 | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 20, .p_mask = 0x0F, | ||||||
|  | 	  .lock_ena = 24, .lock_det = 27, .kcp_shift = 28, .kcp_mask = 3, .kvco_shift = 27, .kvco_mask = 1 },	/* PLLC */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 0,  .p_mask = 0, | ||||||
|  | 	  .lock_ena = 0,  .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLM */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLP */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLA */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x01, | ||||||
|  | 	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLU */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLD */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 20, .p_mask = 0x0F, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 0, .kcp_mask = 0, .kvco_shift = 0, .kvco_mask = 0 },	/* PLLX */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 0,  .p_mask = 0, | ||||||
|  | 	  .lock_ena = 9,  .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLE */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLS (RESERVED) */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Get the oscillator frequency, from the corresponding hardware configuration |  * Get the oscillator frequency, from the corresponding hardware configuration | ||||||
|  * field. Note that Tegra30+ support 3 new higher freqs, but we map back |  * field. Note that Tegra30+ support 3 new higher freqs, but we map back | ||||||
|  | @ -772,6 +802,8 @@ void clock_early_init(void) | ||||||
| { | { | ||||||
| 	struct clk_rst_ctlr *clkrst = | 	struct clk_rst_ctlr *clkrst = | ||||||
| 		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | ||||||
|  | 	struct clk_pll_info *pllinfo; | ||||||
|  | 	u32 data; | ||||||
| 
 | 
 | ||||||
| 	tegra30_set_up_pllp(); | 	tegra30_set_up_pllp(); | ||||||
| 
 | 
 | ||||||
|  | @ -808,11 +840,15 @@ void clock_early_init(void) | ||||||
| 	writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); | 	writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); | ||||||
| 
 | 
 | ||||||
| 	/* PLLC_MISC: Set LOCK_ENABLE */ | 	/* PLLC_MISC: Set LOCK_ENABLE */ | ||||||
| 	writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc); | 	pllinfo = &tegra_pll_info_table[CLOCK_ID_CGENERAL]; | ||||||
|  | 	setbits_le32(&clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc, (1 << pllinfo->lock_ena)); | ||||||
| 	udelay(2); | 	udelay(2); | ||||||
| 
 | 
 | ||||||
| 	/* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */ | 	/* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1, and enable lock */ | ||||||
| 	writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); | 	pllinfo = &tegra_pll_info_table[CLOCK_ID_DISPLAY]; | ||||||
|  | 	data = (12 << pllinfo->kcp_shift) | (1 << pllinfo->kvco_shift); | ||||||
|  | 	data |= (1 << PLLD_CLKENABLE) | (1 << pllinfo->lock_ena); | ||||||
|  | 	writel(data, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); | ||||||
| 	udelay(2); | 	udelay(2); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ static void enable_cpu_power_rail(void) | ||||||
| { | { | ||||||
| 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; | 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; | ||||||
| 
 | 
 | ||||||
| 	debug("enable_cpu_power_rail entry\n"); | 	debug("%s entry\n", __func__); | ||||||
| 
 | 
 | ||||||
| 	/* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ | 	/* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ | ||||||
| 	pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6); | 	pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6); | ||||||
|  | @ -45,15 +45,16 @@ static void enable_cpu_power_rail(void) | ||||||
| static void enable_cpu_clocks(void) | static void enable_cpu_clocks(void) | ||||||
| { | { | ||||||
| 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | ||||||
|  | 	struct clk_pll_info *pllinfo = &tegra_pll_info_table[CLOCK_ID_XCPU]; | ||||||
| 	u32 reg; | 	u32 reg; | ||||||
| 
 | 
 | ||||||
| 	debug("enable_cpu_clocks entry\n"); | 	debug("%s entry\n", __func__); | ||||||
| 
 | 
 | ||||||
| 	/* Wait for PLL-X to lock */ | 	/* Wait for PLL-X to lock */ | ||||||
| 	do { | 	do { | ||||||
| 		reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); | 		reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); | ||||||
| 		debug("%s: PLLX base = 0x%08X\n", __func__, reg); | 		debug("%s: PLLX base = 0x%08X\n", __func__, reg); | ||||||
| 	} while ((reg & PLL_LOCK_MASK) == 0); | 	} while ((reg & (1 << pllinfo->lock_det)) == 0); | ||||||
| 
 | 
 | ||||||
| 	debug("%s: PLLX locked, delay for stable clocks\n", __func__); | 	debug("%s: PLLX locked, delay for stable clocks\n", __func__); | ||||||
| 	/* Wait until all clocks are stable */ | 	/* Wait until all clocks are stable */ | ||||||
|  | @ -83,7 +84,7 @@ static void remove_cpu_resets(void) | ||||||
| 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | ||||||
| 	u32 reg; | 	u32 reg; | ||||||
| 
 | 
 | ||||||
| 	debug("remove_cpu_resets entry\n"); | 	debug("%s entry\n", __func__); | ||||||
| 
 | 
 | ||||||
| 	/* Take the slow and fast partitions out of reset */ | 	/* Take the slow and fast partitions out of reset */ | ||||||
| 	reg = CLR_NONCPURESET; | 	reg = CLR_NONCPURESET; | ||||||
|  | @ -105,7 +106,7 @@ static void remove_cpu_resets(void) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * The Tegra124 requires some special clock initialization, including setting up |  * Tegra124 requires some special clock initialization, including setting up | ||||||
|  * the DVC I2C, turning on MSELECT and selecting the G CPU cluster |  * the DVC I2C, turning on MSELECT and selecting the G CPU cluster | ||||||
|  */ |  */ | ||||||
| void tegra124_init_clocks(void) | void tegra124_init_clocks(void) | ||||||
|  | @ -116,7 +117,7 @@ void tegra124_init_clocks(void) | ||||||
| 			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | ||||||
| 	u32 val; | 	u32 val; | ||||||
| 
 | 
 | ||||||
| 	debug("tegra124_init_clocks entry\n"); | 	debug("%s entry\n", __func__); | ||||||
| 
 | 
 | ||||||
| 	/* Set active CPU cluster to G */ | 	/* Set active CPU cluster to G */ | ||||||
| 	clrbits_le32(&flow->cluster_control, 1); | 	clrbits_le32(&flow->cluster_control, 1); | ||||||
|  | @ -188,7 +189,7 @@ void tegra124_init_clocks(void) | ||||||
| 	reset_set_enable(PERIPH_ID_MSELECT, 0); | 	reset_set_enable(PERIPH_ID_MSELECT, 0); | ||||||
| 	reset_set_enable(PERIPH_ID_DVFS, 0); | 	reset_set_enable(PERIPH_ID_DVFS, 0); | ||||||
| 
 | 
 | ||||||
| 	debug("tegra124_init_clocks exit\n"); | 	debug("%s exit\n", __func__); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool is_partition_powered(u32 partid) | static bool is_partition_powered(u32 partid) | ||||||
|  | @ -223,31 +224,29 @@ static void power_partition(u32 partid) | ||||||
| 
 | 
 | ||||||
| void powerup_cpus(void) | void powerup_cpus(void) | ||||||
| { | { | ||||||
| 	debug("powerup_cpus entry\n"); |  | ||||||
| 
 |  | ||||||
| 	/* We boot to the fast cluster */ | 	/* We boot to the fast cluster */ | ||||||
| 	debug("powerup_cpus entry: G cluster\n"); | 	debug("%s entry: G cluster\n", __func__); | ||||||
| 
 | 
 | ||||||
| 	/* Power up the fast cluster rail partition */ | 	/* Power up the fast cluster rail partition */ | ||||||
| 	debug("powerup_cpus: CRAIL\n"); | 	debug("%s: CRAIL\n", __func__); | ||||||
| 	power_partition(CRAIL); | 	power_partition(CRAIL); | ||||||
| 
 | 
 | ||||||
| 	/* Power up the fast cluster non-CPU partition */ | 	/* Power up the fast cluster non-CPU partition */ | ||||||
| 	debug("powerup_cpus: C0NC\n"); | 	debug("%s: C0NC\n", __func__); | ||||||
| 	power_partition(C0NC); | 	power_partition(C0NC); | ||||||
| 
 | 
 | ||||||
| 	/* Power up the fast cluster CPU0 partition */ | 	/* Power up the fast cluster CPU0 partition */ | ||||||
| 	debug("powerup_cpus: CE0\n"); | 	debug("%s: CE0\n", __func__); | ||||||
| 	power_partition(CE0); | 	power_partition(CE0); | ||||||
| 
 | 
 | ||||||
| 	debug("powerup_cpus: done\n"); | 	debug("%s: done\n", __func__); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void start_cpu(u32 reset_vector) | void start_cpu(u32 reset_vector) | ||||||
| { | { | ||||||
| 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; | 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; | ||||||
| 
 | 
 | ||||||
| 	debug("start_cpu entry, reset_vector = %x\n", reset_vector); | 	debug("%s entry, reset_vector = %x\n", __func__, reset_vector); | ||||||
| 
 | 
 | ||||||
| 	tegra124_init_clocks(); | 	tegra124_init_clocks(); | ||||||
| 
 | 
 | ||||||
|  | @ -261,5 +260,5 @@ void start_cpu(u32 reset_vector) | ||||||
| 	remove_cpu_resets(); | 	remove_cpu_resets(); | ||||||
| 	writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); | 	writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); | ||||||
| 	powerup_cpus(); | 	powerup_cpus(); | ||||||
| 	debug("start_cpu exit, should continue @ reset_vector\n"); | 	debug("%s exit, should continue @ reset_vector\n", __func__); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (c) 2011 The Chromium OS Authors. |  * Copyright (c) 2011 The Chromium OS Authors. | ||||||
|  |  * (C) Copyright 2010-2015 | ||||||
|  |  * NVIDIA Corporation <www.nvidia.com> | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier:	GPL-2.0+ |  * SPDX-License-Identifier:	GPL-2.0+ | ||||||
|  */ |  */ | ||||||
|  | @ -354,6 +356,36 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { | ||||||
| 	NONE(CRAM2), | 	NONE(CRAM2), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * PLL divider shift/mask tables for all PLL IDs. | ||||||
|  |  */ | ||||||
|  | struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { | ||||||
|  | 	/*
 | ||||||
|  | 	 * T20 and T25 | ||||||
|  | 	 * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLX, etc.) | ||||||
|  | 	 *       If lock_ena or lock_det are >31, they're not used in that PLL. | ||||||
|  | 	 */ | ||||||
|  | 
 | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF,  .p_shift = 20, .p_mask = 0x0F, | ||||||
|  | 	  .lock_ena = 24, .lock_det = 27, .kcp_shift = 28, .kcp_mask = 3, .kvco_shift = 27, .kvco_mask = 1 },	/* PLLC */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF,  .p_shift = 0,  .p_mask = 0, | ||||||
|  | 	  .lock_ena = 0,  .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLM */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLP */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLA */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x01, | ||||||
|  | 	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLU */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLD */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF,  .p_shift = 20, .p_mask = 0x0F, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 0, .kvco_mask = 0 },	/* PLLX */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 0,  .p_mask = 0, | ||||||
|  | 	  .lock_ena = 9,  .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLE */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 0, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLS */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Get the oscillator frequency, from the corresponding hardware configuration |  * Get the oscillator frequency, from the corresponding hardware configuration | ||||||
|  * field. T20 has 4 frequencies that it supports. |  * field. T20 has 4 frequencies that it supports. | ||||||
|  |  | ||||||
|  | @ -630,6 +630,34 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { | ||||||
| 	NONE(Y_RESERVED31), | 	NONE(Y_RESERVED31), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * PLL divider shift/mask tables for all PLL IDs. | ||||||
|  |  */ | ||||||
|  | struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { | ||||||
|  | 	/*
 | ||||||
|  | 	 * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLC, etc.) | ||||||
|  | 	 *       If lock_ena or lock_det are >31, they're not used in that PLL (PLLC, etc.) | ||||||
|  | 	 */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 10, .n_mask = 0xFF, .p_shift = 20, .p_mask = 0x1F, | ||||||
|  | 	  .lock_ena = 32,  .lock_det = 27, .kcp_shift = 0, .kcp_mask = 0, .kvco_shift = 0, .kvco_mask = 0 },	/* PLLC */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8,  .n_mask = 0xFF, .p_shift = 20, .p_mask = 0x1F, | ||||||
|  | 	  .lock_ena = 4,  .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLM */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 10, .n_mask = 0xFF, .p_shift = 20, .p_mask = 0x1F, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 0, .kcp_mask = 3, .kvco_shift = 2, .kvco_mask = 1 },	/* PLLP */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8,  .n_mask = 0xFF, .p_shift = 20, .p_mask = 0x1F, | ||||||
|  | 	  .lock_ena = 28, .lock_det = 27, .kcp_shift = 25, .kcp_mask = 3, .kvco_shift = 24, .kvco_mask = 1 },	/* PLLA */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8,  .n_mask = 0xFF, .p_shift = 16, .p_mask = 0x1F, | ||||||
|  | 	  .lock_ena = 29, .lock_det = 27, .kcp_shift = 25, .kcp_mask = 3, .kvco_shift = 24, .kvco_mask = 1 },	/* PLLU */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 11, .n_mask = 0xFF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 23, .kcp_mask = 3, .kvco_shift = 22, .kvco_mask = 1 },	/* PLLD */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8,  .n_mask = 0xFF, .p_shift = 20, .p_mask = 0x1F, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLX */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8,  .n_mask = 0xFF, .p_shift = 0,  .p_mask = 0, | ||||||
|  | 	  .lock_ena = 9,  .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLE */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0, .n_shift = 0, .n_mask = 0, .p_shift = 0, .p_mask = 0, | ||||||
|  | 	  .lock_ena = 0, .lock_det = 0, .kcp_shift = 0, .kcp_mask = 0, .kvco_shift = 0, .kvco_mask = 0 },	/* PLLS (gone)*/ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Get the oscillator frequency, from the corresponding hardware configuration |  * Get the oscillator frequency, from the corresponding hardware configuration | ||||||
|  * field. Note that Tegra30+ support 3 new higher freqs, but we map back |  * field. Note that Tegra30+ support 3 new higher freqs, but we map back | ||||||
|  | @ -903,6 +931,7 @@ void clock_early_init(void) | ||||||
| { | { | ||||||
| 	struct clk_rst_ctlr *clkrst = | 	struct clk_rst_ctlr *clkrst = | ||||||
| 		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | ||||||
|  | 	struct clk_pll_info *pllinfo = &tegra_pll_info_table[CLOCK_ID_DISPLAY]; | ||||||
| 	u32 data; | 	u32 data; | ||||||
| 
 | 
 | ||||||
| 	tegra210_setup_pllp(); | 	tegra210_setup_pllp(); | ||||||
|  | @ -957,7 +986,7 @@ void clock_early_init(void) | ||||||
| 	udelay(2); | 	udelay(2); | ||||||
| 
 | 
 | ||||||
| 	/* PLLD_MISC: Set CLKENABLE and LOCK_DETECT bits */ | 	/* PLLD_MISC: Set CLKENABLE and LOCK_DETECT bits */ | ||||||
| 	data = (1 << PLLD_ENABLE_CLK) | (1 << PLLD_EN_LCKDET); | 	data = (1 << PLLD_ENABLE_CLK) | (1 << pllinfo->lock_ena); | ||||||
| 	writel(data, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); | 	writel(data, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); | ||||||
| 	udelay(2); | 	udelay(2); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,17 +1,8 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (c) 2010-2014, NVIDIA CORPORATION.  All rights reserved. |  * (C) Copyright 2010-2015 | ||||||
|  |  * NVIDIA Corporation <www.nvidia.com> | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify it |  * SPDX-License-Identifier:     GPL-2.0+ | ||||||
|  * under the terms and conditions of the GNU General Public License, |  | ||||||
|  * version 2, as published by the Free Software Foundation. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope it will be useful, but WITHOUT |  | ||||||
|  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |  | ||||||
|  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for |  | ||||||
|  * more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU General Public License |  | ||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 |  | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /* Tegra30 Clock control functions */ | /* Tegra30 Clock control functions */ | ||||||
|  | @ -414,6 +405,36 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { | ||||||
| 	NONE(EX_RESERVED47), | 	NONE(EX_RESERVED47), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * PLL divider shift/mask tables for all PLL IDs. | ||||||
|  |  */ | ||||||
|  | struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { | ||||||
|  | 	/*
 | ||||||
|  | 	 * T30: some deviations from T2x. | ||||||
|  | 	 * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLX, etc.) | ||||||
|  | 	 *       If lock_ena or lock_det are >31, they're not used in that PLL. | ||||||
|  | 	 */ | ||||||
|  | 
 | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF,  .p_shift = 20, .p_mask = 0x0F, | ||||||
|  | 	  .lock_ena = 24, .lock_det = 27, .kcp_shift = 28, .kcp_mask = 3, .kvco_shift = 27, .kvco_mask = 1 },	/* PLLC */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF,  .p_shift = 0,  .p_mask = 0, | ||||||
|  | 	  .lock_ena = 0,  .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLM */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLP */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLA */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x01, | ||||||
|  | 	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLU */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLD */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 20, .p_mask = 0x0F, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 0, .kvco_mask = 0 },	/* PLLX */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 0,  .p_mask = 0, | ||||||
|  | 	  .lock_ena = 9,  .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLE */ | ||||||
|  | 	{ .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | ||||||
|  | 	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLS (RESERVED) */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Get the oscillator frequency, from the corresponding hardware configuration |  * Get the oscillator frequency, from the corresponding hardware configuration | ||||||
|  * field. Note that T30 supports 3 new higher freqs, but we map back |  * field. Note that T30 supports 3 new higher freqs, but we map back | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue