示例#1
0
int sr_pll_clk_enable(struct clk *c)
{
	u32 mode;
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);

	spin_lock_irqsave(&pll_reg_lock, flags);
	mode = readl_relaxed(PLL_MODE_REG(pll));
	
	mode |= PLL_RESET_N;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	mb();
	udelay(10);

	
	mode |= PLL_BYPASSNL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	
	mb();
	udelay(60);

	
	mode |= PLL_OUTCTRL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	
	mb();

	spin_unlock_irqrestore(&pll_reg_lock, flags);

	return 0;
}
static int sr2_pll_clk_enable(struct clk *c)
{
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);
	int ret = 0, count;
	u32 mode = readl_relaxed(PLL_MODE_REG(pll));
	u32 lockmask = pll->masks.lock_mask ?: PLL_LOCKED_BIT;

	spin_lock_irqsave(&pll_reg_lock, flags);

	spm_event(pll->spm_ctrl.spm_base, pll->spm_ctrl.offset,
				pll->spm_ctrl.event_bit, false);

	/* Disable PLL bypass mode. */
	mode |= PLL_BYPASSNL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/*
	 * H/W requires a 5us delay between disabling the bypass and
	 * de-asserting the reset. Delay 10us just to be safe.
	 */
	mb();
	udelay(10);

	/* De-assert active-low PLL reset. */
	mode |= PLL_RESET_N;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Wait for pll to lock. */
	for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
		if (readl_relaxed(PLL_STATUS_REG(pll)) & lockmask)
			break;
		udelay(1);
	}

	if (!(readl_relaxed(PLL_STATUS_REG(pll)) & lockmask))
		pr_err("PLL %s didn't lock after enabling it!\n", c->dbg_name);

	/* Enable PLL output. */
	mode |= PLL_OUTCTRL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Ensure that the write above goes through before returning. */
	mb();

	spin_unlock_irqrestore(&pll_reg_lock, flags);
	return ret;
}
int msm8974_pll_clk_enable(struct clk *c)
{
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);
	u32 count, mode;
	int ret = 0;

	spin_lock_irqsave(&pll_reg_lock, flags);
	mode = readl_relaxed(PLL_MODE_REG(pll));
	/* Disable PLL bypass mode. */
	mode |= PLL_BYPASSNL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/*
	 * H/W requires a 5us delay between disabling the bypass and
	 * de-asserting the reset. Delay 10us just to be safe.
	 */
	mb();
	udelay(10);

	/* De-assert active-low PLL reset. */
	mode |= PLL_RESET_N;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Wait for pll to enable. */
	for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
		if (readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT)
			break;
		udelay(1);
	}

	if (!(readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT)) {
		WARN("PLL %s didn't lock after enabling it!\n", c->dbg_name);
		ret = -ETIMEDOUT;
		goto out;
	}

	/* Enable PLL output. */
	mode |= PLL_OUTCTRL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Ensure the write above goes through before returning. */
	mb();

out:
	spin_unlock_irqrestore(&pll_reg_lock, flags);
	return ret;
}
示例#4
0
static enum handoff pll_clk_handoff(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_lval;
	struct pll_rate *l;

	do {
		pll_lval = readl_relaxed(PLL_MODE_REG(pll) + 4) & 0x3ff;
		cpu_relax();
		udelay(50);
	} while (pll_lval == 0);

	
	for (l = pll_l_rate; l->rate != 0; l++) {
		if (l->lvalue == pll_lval) {
			c->rate = l->rate;
			break;
		}
	}

	if (!c->rate) {
		pr_crit("Unknown PLL's L value!\n");
		BUG();
	}

	return HANDOFF_ENABLED_CLK;
}
示例#5
0
static int local_pll_clk_set_rate(struct clk *c, unsigned long rate)
{
	struct pll_freq_tbl *nf;
	struct pll_clk *pll = to_pll_clk(c);
	u32 mode;

	mode = readl_relaxed(PLL_MODE_REG(pll));

	/* Don't change PLL's rate if it is enabled */
	if ((mode & PLL_MODE_MASK) == PLL_MODE_MASK)
		return -EBUSY;

	for (nf = pll->freq_tbl; nf->freq_hz != PLL_FREQ_END
			&& nf->freq_hz != rate; nf++)
		;

	if (nf->freq_hz == PLL_FREQ_END)
		return -EINVAL;

	writel_relaxed(nf->l_val, PLL_L_REG(pll));
	writel_relaxed(nf->m_val, PLL_M_REG(pll));
	writel_relaxed(nf->n_val, PLL_N_REG(pll));

	__pll_config_reg(PLL_CONFIG_REG(pll), nf, &pll->masks);

	return 0;
}
示例#6
0
static enum handoff pll_clk_handoff(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_lval;
	struct pll_rate *l;

	/*
	 * Wait for the PLLs to be initialized and then read their frequency.
	 */
	do {
		pll_lval = readl_relaxed(PLL_MODE_REG(pll) + 4) & 0x3ff;
		cpu_relax();
		udelay(50);
	} while (pll_lval == 0);

	/* Convert PLL L values to PLL Output rate */
	for (l = pll_l_rate; l->rate != 0; l++) {
		if (l->lvalue == pll_lval) {
			c->rate = l->rate;
			break;
		}
	}

	if (!c->rate) {
		pr_crit("Unknown PLL's L value!\n");
		BUG();
	}

	return HANDOFF_ENABLED_CLK;
}
示例#7
0
void __init configure_sr_hpm_lp_pll(struct pll_config *config,
		struct pll_config_regs *regs, u32 ena_fsm_mode)
{
	__configure_pll(config, regs, ena_fsm_mode);
	if (ena_fsm_mode)
		__set_fsm_mode(PLL_MODE_REG(regs), 0x1, 0x0);
}
static enum handoff local_pll_clk_handoff(struct clk *c)
{
	struct pll_clk *pll = to_pll_clk(c);
	u32 mode = readl_relaxed(PLL_MODE_REG(pll));
	u32 mask = PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL;
	unsigned long parent_rate;
	u32 lval, mval, nval, userval;

	if ((mode & mask) != mask)
		return HANDOFF_DISABLED_CLK;

	/* Assume bootloaders configure PLL to c->rate */
	if (c->rate)
		return HANDOFF_ENABLED_CLK;

	parent_rate = clk_get_rate(c->parent);
	lval = readl_relaxed(PLL_L_REG(pll));
	mval = readl_relaxed(PLL_M_REG(pll));
	nval = readl_relaxed(PLL_N_REG(pll));
	userval = readl_relaxed(PLL_CONFIG_REG(pll));

	c->rate = parent_rate * lval;

	if (pll->masks.mn_en_mask && userval) {
		if (!nval)
			nval = 1;
		c->rate += (parent_rate * mval) / nval;
	}

	return HANDOFF_ENABLED_CLK;
}
示例#9
0
static enum handoff pll_clk_handoff(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_lval;
	struct pll_rate *l;

	do {
		pll_lval = readl_relaxed(PLL_MODE_REG(pll) + 4) & 0x3ff;
		cpu_relax();
		udelay(50);
	} while (pll_lval == 0);

	
	for (l = pll_l_rate; l->rate != 0; l++) {
		if (l->lvalue == pll_lval) {
			c->rate = l->rate;
			break;
		}
	}

	if (!c->rate) {
		pr_crit("Unknown PLL's L value!\n");
		BUG();
	}

	if (!pll_clk_is_enabled(c))
		return HANDOFF_DISABLED_CLK;

	remote_spin_lock(&pll_lock);
	pll_control->pll[PLL_BASE + pll->id].votes |= BIT(1);
	pll_control->pll[PLL_BASE + pll->id].on = 1;
	remote_spin_unlock(&pll_lock);

	return HANDOFF_ENABLED_CLK;
}
static void __variable_rate_pll_init(struct clk *c)
{
	struct pll_clk *pll = to_pll_clk(c);
	u32 regval;

	regval = readl_relaxed(PLL_CONFIG_REG(pll));

	if (pll->masks.post_div_mask) {
		regval &= ~pll->masks.post_div_mask;
		regval |= pll->vals.post_div_masked;
	}

	if (pll->masks.pre_div_mask) {
		regval &= ~pll->masks.pre_div_mask;
		regval |= pll->vals.pre_div_masked;
	}

	if (pll->masks.main_output_mask)
		regval |= pll->masks.main_output_mask;

	if (pll->masks.early_output_mask)
		regval |= pll->masks.early_output_mask;

	if (pll->vals.enable_mn)
		regval |= pll->masks.mn_en_mask;
	else
		regval &= ~pll->masks.mn_en_mask;

	writel_relaxed(regval, PLL_CONFIG_REG(pll));

	regval = readl_relaxed(PLL_MODE_REG(pll));
	if (pll->masks.apc_pdn_mask)
		regval &= ~pll->masks.apc_pdn_mask;
	writel_relaxed(regval, PLL_MODE_REG(pll));

	writel_relaxed(pll->vals.alpha_val, PLL_ALPHA_REG(pll));
	writel_relaxed(pll->vals.config_ctl_val, PLL_CFG_CTL_REG(pll));
	if (pll->init_test_ctl) {
		writel_relaxed(pll->vals.test_ctl_lo_val,
				PLL_TEST_CTL_LO_REG(pll));
		writel_relaxed(pll->vals.test_ctl_hi_val,
				PLL_TEST_CTL_HI_REG(pll));
	}

	pll->inited = true;
}
示例#11
0
static void local_pll_clk_disable(struct clk *c)
{
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);

	spin_lock_irqsave(&pll_reg_lock, flags);
	__pll_clk_disable_reg(PLL_MODE_REG(pll));
	spin_unlock_irqrestore(&pll_reg_lock, flags);
}
示例#12
0
int msm8974_pll_clk_enable(struct clk *c)
{
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);
	u32 count, mode;
	int ret = 0;

	spin_lock_irqsave(&pll_reg_lock, flags);
	mode = readl_relaxed(PLL_MODE_REG(pll));
	
	mode |= PLL_BYPASSNL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	mb();
	udelay(10);

	
	mode |= PLL_RESET_N;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	
	for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
		if (readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT)
			break;
		udelay(1);
	}

	if (!(readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT)) {
		WARN("PLL %s didn't lock after enabling it!\n", c->dbg_name);
		ret = -ETIMEDOUT;
		goto out;
	}

	
	mode |= PLL_OUTCTRL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	
	mb();

out:
	spin_unlock_irqrestore(&pll_reg_lock, flags);
	return ret;
}
示例#13
0
static enum handoff local_pll_clk_handoff(struct clk *c)
{
	struct pll_clk *pll = to_pll_clk(c);
	u32 mode = readl_relaxed(PLL_MODE_REG(pll));
	u32 mask = PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL;

	if ((mode & mask) == mask)
		return HANDOFF_ENABLED_CLK;

	return HANDOFF_DISABLED_CLK;
}
示例#14
0
static int local_pll_clk_enable(struct clk *clk)
{
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(clk);

	spin_lock_irqsave(&pll_reg_lock, flags);
	__pll_clk_enable_reg(PLL_MODE_REG(pll));
	spin_unlock_irqrestore(&pll_reg_lock, flags);

	return 0;
}
static void local_pll_clk_disable(struct clk *c)
{
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);

	/*
	 * Disable the PLL output, disable test mode, enable
	 * the bypass mode, and assert the reset.
	 */
	spin_lock_irqsave(&pll_reg_lock, flags);
	__pll_clk_disable_reg(PLL_MODE_REG(pll));
	spin_unlock_irqrestore(&pll_reg_lock, flags);
}
int sr_pll_clk_enable(struct clk *c)
{
	u32 mode;
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);

	spin_lock_irqsave(&pll_reg_lock, flags);
	mode = readl_relaxed(PLL_MODE_REG(pll));
	/* De-assert active-low PLL reset. */
	mode |= PLL_RESET_N;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/*
	 * H/W requires a 5us delay between disabling the bypass and
	 * de-asserting the reset. Delay 10us just to be safe.
	 */
	mb();
	udelay(10);

	/* Disable PLL bypass mode. */
	mode |= PLL_BYPASSNL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Wait until PLL is locked. */
	mb();
	udelay(60);

	/* Enable PLL output. */
	mode |= PLL_OUTCTRL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Ensure that the write above goes through before returning. */
	mb();

	spin_unlock_irqrestore(&pll_reg_lock, flags);

	return 0;
}
示例#17
0
int sr_hpm_lp_pll_clk_enable(struct clk *c)
{
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);
	u32 count, mode;
	int ret = 0;

	spin_lock_irqsave(&pll_reg_lock, flags);

	/* Disable PLL bypass mode and de-assert reset. */
	mode = PLL_BYPASSNL | PLL_RESET_N;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Wait for pll to lock. */
	for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
		if (readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT)
			break;
		udelay(1);
	}

	if (!(readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT)) {
		WARN("PLL %s didn't lock after enabling it!\n", c->dbg_name);
		ret = -ETIMEDOUT;
		goto out;
	}

	/* Enable PLL output. */
	mode |= PLL_OUTCTRL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Ensure the write above goes through before returning. */
	mb();

out:
	spin_unlock_irqrestore(&pll_reg_lock, flags);
	return ret;
}
static void pll_clk_disable(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_id = pll->id;

	remote_spin_lock(&pll_lock);

	pll_control->pll[PLL_BASE + pll_id].votes &= ~BIT(1);
	if (pll_control->pll[PLL_BASE + pll_id].on
	    && !pll_control->pll[PLL_BASE + pll_id].votes) {
		__pll_clk_disable_reg(PLL_MODE_REG(pll));
		pll_control->pll[PLL_BASE + pll_id].on = 0;
	}

	remote_spin_unlock(&pll_lock);
}
static int pll_clk_enable(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_id = pll->id;

	remote_spin_lock(&pll_lock);

	pll_control->pll[PLL_BASE + pll_id].votes |= BIT(1);
	if (!pll_control->pll[PLL_BASE + pll_id].on) {
		__pll_clk_enable_reg(PLL_MODE_REG(pll));
		pll_control->pll[PLL_BASE + pll_id].on = 1;
	}

	remote_spin_unlock(&pll_lock);
	return 0;
}
static void __iomem *variable_rate_pll_list_registers(struct clk *c, int n,
				struct clk_register_data **regs, u32 *size)
{
	struct pll_clk *pll = to_pll_clk(c);
	static struct clk_register_data data[] = {
		{"MODE", 0x0},
		{"L", 0x4},
		{"ALPHA", 0x8},
		{"USER_CTL", 0x10},
		{"CONFIG_CTL", 0x14},
		{"STATUS", 0x1C},
	};
	if (n)
		return ERR_PTR(-EINVAL);

	*regs = data;
	*size = ARRAY_SIZE(data);
	return PLL_MODE_REG(pll);
}
static enum handoff pll_clk_handoff(struct clk *c)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(c);
	unsigned int pll_lval;
	struct pll_rate *l;

	/*
	 * Wait for the PLLs to be initialized and then read their frequency.
	 */
	do {
		pll_lval = readl_relaxed(PLL_MODE_REG(pll) + 4) & 0x3ff;
		cpu_relax();
		udelay(50);
	} while (pll_lval == 0);

	/* Convert PLL L values to PLL Output rate */
	for (l = pll_l_rate; l->rate != 0; l++) {
		if (l->lvalue == pll_lval) {
			c->rate = l->rate;
			break;
		}
	}

	if (!c->rate) {
		pr_crit("Unknown PLL's L value!\n");
		BUG();
	}

	if (!pll_clk_is_enabled(c))
		return HANDOFF_DISABLED_CLK;

	/*
	 * Do not call pll_clk_enable() since that function can assume
	 * the PLL is not in use when it's called.
	 */
	remote_spin_lock(&pll_lock);
	pll_control->pll[PLL_BASE + pll->id].votes |= BIT(1);
	pll_control->pll[PLL_BASE + pll->id].on = 1;
	remote_spin_unlock(&pll_lock);

	return HANDOFF_ENABLED_CLK;
}
static void __iomem *local_pll_clk_list_registers(struct clk *c, int n,
				struct clk_register_data **regs, u32 *size)
{
	/* Not compatible with 8960 & friends */
	struct pll_clk *pll = to_pll_clk(c);
	static struct clk_register_data data[] = {
		{"MODE", 0x0},
		{"L", 0x4},
		{"M", 0x8},
		{"N", 0xC},
		{"USER", 0x10},
		{"CONFIG", 0x14},
		{"STATUS", 0x1C},
	};
	if (n)
		return ERR_PTR(-EINVAL);

	*regs = data;
	*size = ARRAY_SIZE(data);
	return PLL_MODE_REG(pll);
}
void configure_pll(struct pll_config *config,
		struct pll_config_regs *regs, u32 ena_fsm_mode)
{
	u32 regval;

	writel_relaxed(config->l, PLL_L_REG(regs));
	writel_relaxed(config->m, PLL_M_REG(regs));
	writel_relaxed(config->n, PLL_N_REG(regs));

	regval = readl_relaxed(PLL_CONFIG_REG(regs));

	/* Enable the MN accumulator  */
	if (config->mn_ena_mask) {
		regval &= ~config->mn_ena_mask;
		regval |= config->mn_ena_val;
	}

	/* Enable the main output */
	if (config->main_output_mask) {
		regval &= ~config->main_output_mask;
		regval |= config->main_output_val;
	}

	/* Set pre-divider and post-divider values */
	regval &= ~config->pre_div_mask;
	regval |= config->pre_div_val;
	regval &= ~config->post_div_mask;
	regval |= config->post_div_val;

	/* Select VCO setting */
	regval &= ~config->vco_mask;
	regval |= config->vco_val;
	writel_relaxed(regval, PLL_CONFIG_REG(regs));

	/* Configure in FSM mode if necessary */
	if (ena_fsm_mode)
		__set_fsm_mode(PLL_MODE_REG(regs));
}
示例#24
0
void __init configure_pll(struct pll_config *config,
		struct pll_config_regs *regs, u32 ena_fsm_mode)
{
	u32 regval;

	writel_relaxed(config->l, PLL_L_REG(regs));
	writel_relaxed(config->m, PLL_M_REG(regs));
	writel_relaxed(config->n, PLL_N_REG(regs));

	regval = readl_relaxed(PLL_CONFIG_REG(regs));

	
	if (config->mn_ena_mask) {
		regval &= ~config->mn_ena_mask;
		regval |= config->mn_ena_val;
	}

	
	if (config->main_output_mask) {
		regval &= ~config->main_output_mask;
		regval |= config->main_output_val;
	}

	
	regval &= ~config->pre_div_mask;
	regval |= config->pre_div_val;
	regval &= ~config->post_div_mask;
	regval |= config->post_div_val;

	
	regval &= ~config->vco_mask;
	regval |= config->vco_val;
	writel_relaxed(regval, PLL_CONFIG_REG(regs));

	
	if (ena_fsm_mode)
		__set_fsm_mode(PLL_MODE_REG(regs));
}
static enum handoff variable_rate_pll_handoff(struct clk *c)
{
	struct pll_clk *pll = to_pll_clk(c);
	u32 mode = readl_relaxed(PLL_MODE_REG(pll));
	u32 mask = PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL;
	u32 lval;

	pll->src_rate = clk_get_rate(c->parent);

	if ((mode & mask) != mask)
		return HANDOFF_DISABLED_CLK;

	lval = readl_relaxed(PLL_L_REG(pll));

	c->rate = pll->src_rate * lval;

	if (c->rate > pll->max_rate || c->rate < pll->min_rate) {
		WARN(1, "%s: Out of spec PLL", c->dbg_name);
		return HANDOFF_DISABLED_CLK;
	}

	return HANDOFF_ENABLED_CLK;
}
static int hf_pll_clk_enable(struct clk *c)
{
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);
	int ret = 0, count;
	u32 mode;
	u32 lockmask = pll->masks.lock_mask ?: PLL_LOCKED_BIT;
	u32 status_reg, user_reg, l_reg, m_reg, n_reg, config_reg;

	spin_lock_irqsave(&pll_reg_lock, flags);

	if (unlikely(!to_pll_clk(c)->inited))
		__hf_pll_init(c);

	/* Remove SPM HW event */
	spm_event(pll->spm_ctrl.spm_base, pll->spm_ctrl.offset,
				pll->spm_ctrl.event_bit, false);

	mode = readl_relaxed(PLL_MODE_REG(pll));

	/* Disable PLL bypass mode. */
	mode |= PLL_BYPASSNL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/*
	 * H/W requires a 5us delay between disabling the bypass and
	 * de-asserting the reset. Use 10us to be sure.
	 */
	mb();
	udelay(10);

	/* De-assert active-low PLL reset. */
	mode |= PLL_RESET_N;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* A 50us delay required before locking the PLL. */
	mb();
	udelay(50);
	/* Wait for pll to lock. */
	for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
		if (readl_relaxed(PLL_STATUS_REG(pll)) & lockmask) {
			udelay(1);
			/*
			 * Check again to be sure. This is to avoid
			 * breaking too early if there is a "transient"
			 * lock.
			 */
			if ((readl_relaxed(PLL_STATUS_REG(pll)) & lockmask))
				break;
		}
		udelay(1);
	}

	if (!(readl_relaxed(PLL_STATUS_REG(pll)) & lockmask)) {
		mode = readl_relaxed(PLL_MODE_REG(pll));
		status_reg = readl_relaxed(PLL_STATUS_REG(pll));
		user_reg = readl_relaxed(PLL_CONFIG_REG(pll));
		config_reg = readl_relaxed(PLL_CFG_CTL_REG(pll));
		l_reg = readl_relaxed(PLL_L_REG(pll));
		m_reg = readl_relaxed(PLL_M_REG(pll));
		n_reg = readl_relaxed(PLL_N_REG(pll));

		pr_err("PLL %s didn't lock after enabling for L value 0x%x!\n",
				c->dbg_name, l_reg);
		pr_err("mode register is 0x%x\n", mode);
		pr_err("status register is 0x%x\n", status_reg);
		pr_err("user control register is 0x%x\n", user_reg);
		pr_err("config control register is 0x%x\n", config_reg);
		pr_err("L value register is 0x%x\n", l_reg);
		pr_err("M value register is 0x%x\n", m_reg);
		pr_err("N value control register is 0x%x\n", n_reg);
		if (pll->spm_ctrl.spm_base)
			pr_err("L2 spm_force_event_en 0x%x\n",
			readl_relaxed(pll->spm_ctrl.spm_base +
						SPM_FORCE_EVENT));
		panic("PLL %s didn't lock after enabling it!\n", c->dbg_name);
	}

	/* Enable PLL output. */
	mode |= PLL_OUTCTRL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Ensure that the write above goes through before returning. */
	mb();

	spin_unlock_irqrestore(&pll_reg_lock, flags);

	return ret;
}
static int pll_clk_is_enabled(struct clk *c)
{
	return readl_relaxed(PLL_MODE_REG(to_pll_shared_clk(c))) & BIT(0);
}
static int variable_rate_pll_clk_enable(struct clk *c)
{
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);
	int ret = 0, count;
	u32 mode, testlo;
	u32 lockmask = pll->masks.lock_mask ?: PLL_LOCKED_BIT;
	u32 mode_lock;
	u64 time;
	bool early_lock = false;

	spin_lock_irqsave(&pll_reg_lock, flags);

	if (unlikely(!to_pll_clk(c)->inited))
		__variable_rate_pll_init(c);

	mode = readl_relaxed(PLL_MODE_REG(pll));

	/* Set test control bits as required by HW doc */
	if (pll->test_ctl_lo_reg && pll->vals.test_ctl_lo_val &&
		pll->pgm_test_ctl_enable)
		writel_relaxed(pll->vals.test_ctl_lo_val,
				PLL_TEST_CTL_LO_REG(pll));

	/* Enable test_ctl debug */
	mode |= BIT(3);
	writel_relaxed(mode, PLL_MODE_REG(pll));

	testlo = readl_relaxed(PLL_TEST_CTL_LO_REG(pll));
	testlo &= ~BM(7, 6);
	testlo |= 0xC0;
	writel_relaxed(testlo, PLL_TEST_CTL_LO_REG(pll));
	/* Wait for the write to complete */
	mb();

	/* Disable PLL bypass mode. */
	mode |= PLL_BYPASSNL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/*
	 * H/W requires a 5us delay between disabling the bypass and
	 * de-asserting the reset. Use 10us to be sure.
	 */
	mb();
	udelay(10);

	/* De-assert active-low PLL reset. */
	mode |= PLL_RESET_N;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/*
	 * 5us delay mandated by HPG. However, put in a 200us delay here.
	 * This is to address possible locking issues with the PLL exhibit
	 * early "transient" locks about 16us from this point. With this
	 * higher delay, we avoid running into those transients.
	 */
	mb();
	udelay(200);

	/* Clear test control bits */
	if (pll->test_ctl_lo_reg && pll->vals.test_ctl_lo_val &&
		pll->pgm_test_ctl_enable)
		writel_relaxed(0x0, PLL_TEST_CTL_LO_REG(pll));


	time = sched_clock();
	/* Wait for pll to lock. */
	for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
		if (readl_relaxed(PLL_STATUS_REG(pll)) & lockmask) {
			udelay(1);
			/*
			 * Check again to be sure. This is to avoid
			 * breaking too early if there is a "transient"
			 * lock.
			 */
			if ((readl_relaxed(PLL_STATUS_REG(pll)) & lockmask))
				break;
			else
				early_lock = true;
		}
		udelay(1);
	}
	time = sched_clock() - time;

	mode_lock = readl_relaxed(PLL_STATUS_REG(pll));

	if (!(mode_lock & lockmask)) {
		pr_err("PLL lock bit detection total wait time: %lld ns", time);
		pr_err("PLL %s didn't lock after enabling for L value 0x%x!\n",
			c->dbg_name, readl_relaxed(PLL_L_REG(pll)));
		pr_err("mode register is 0x%x\n",
			readl_relaxed(PLL_STATUS_REG(pll)));
		pr_err("user control register is 0x%x\n",
			readl_relaxed(PLL_CONFIG_REG(pll)));
		pr_err("config control register is 0x%x\n",
			readl_relaxed(PLL_CFG_CTL_REG(pll)));
		pr_err("test control high register is 0x%x\n",
			readl_relaxed(PLL_TEST_CTL_HI_REG(pll)));
		pr_err("test control low register is 0x%x\n",
			readl_relaxed(PLL_TEST_CTL_LO_REG(pll)));
		pr_err("early lock? %s\n", early_lock ? "yes" : "no");

		testlo = readl_relaxed(PLL_TEST_CTL_LO_REG(pll));
		testlo &= ~BM(7, 6);
		writel_relaxed(testlo, PLL_TEST_CTL_LO_REG(pll));
		/* Wait for the write to complete */
		mb();

		pr_err("test_ctl_lo = 0x%x, pll status is: 0x%x\n",
			readl_relaxed(PLL_TEST_CTL_LO_REG(pll)),
			readl_relaxed(PLL_ALT_STATUS_REG(pll)));

		testlo = readl_relaxed(PLL_TEST_CTL_LO_REG(pll));
		testlo &= ~BM(7, 6);
		testlo |= 0x40;
		writel_relaxed(testlo, PLL_TEST_CTL_LO_REG(pll));
		/* Wait for the write to complete */
		mb();
		pr_err("test_ctl_lo = 0x%x, pll status is: 0x%x\n",
			readl_relaxed(PLL_TEST_CTL_LO_REG(pll)),
			readl_relaxed(PLL_ALT_STATUS_REG(pll)));

		testlo = readl_relaxed(PLL_TEST_CTL_LO_REG(pll));
		testlo &= ~BM(7, 6);
		testlo |= 0x80;
		writel_relaxed(testlo, PLL_TEST_CTL_LO_REG(pll));
		/* Wait for the write to complete */
		mb();

		pr_err("test_ctl_lo = 0x%x, pll status is: 0x%x\n",
			readl_relaxed(PLL_TEST_CTL_LO_REG(pll)),
			readl_relaxed(PLL_ALT_STATUS_REG(pll)));

		testlo = readl_relaxed(PLL_TEST_CTL_LO_REG(pll));
		testlo &= ~BM(7, 6);
		testlo |= 0xC0;
		writel_relaxed(testlo, PLL_TEST_CTL_LO_REG(pll));
		/* Wait for the write to complete */
		mb();

		pr_err("test_ctl_lo = 0x%x, pll status is: 0x%x\n",
			readl_relaxed(PLL_TEST_CTL_LO_REG(pll)),
			readl_relaxed(PLL_ALT_STATUS_REG(pll)));
		panic("failed to lock %s PLL\n", c->dbg_name);
	}

	/* Enable PLL output. */
	mode |= PLL_OUTCTRL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Ensure that the write above goes through before returning. */
	mb();

	spin_unlock_irqrestore(&pll_reg_lock, flags);

	return ret;
}
int sr_pll_clk_enable(struct clk *c)
{
	u32 mode;
	int count;
	unsigned long flags;
	struct pll_clk *pll = to_pll_clk(c);
	u32 lockmask = pll->masks.lock_mask ?: PLL_LOCKED_BIT;
	u32 status_reg, user_reg, l_reg, m_reg, n_reg, config_reg;

	spin_lock_irqsave(&pll_reg_lock, flags);

	if (unlikely(!to_pll_clk(c)->inited))
		/* PLL initilazation is similar to HF PLL */
		__hf_pll_init(c);

	/* Remove SPM HW event */
	spm_event(pll->spm_ctrl.spm_base, pll->spm_ctrl.offset,
				pll->spm_ctrl.event_bit, false);

	mode = readl_relaxed(PLL_MODE_REG(pll));
	/* De-assert active-low PLL reset. */
	mode |= PLL_RESET_N | PLL_BYPASSNL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* A 100us delay required before locking the PLL */
	mb();
	udelay(100);

	/* Wait for the PLL to lock */
	for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
		if (readl_relaxed(PLL_STATUS_REG(pll)) & lockmask)
			break;
		udelay(1);
	}


	if (!(readl_relaxed(PLL_STATUS_REG(pll)) & lockmask)) {
		mode = readl_relaxed(PLL_MODE_REG(pll));
		status_reg = readl_relaxed(PLL_STATUS_REG(pll));
		user_reg = readl_relaxed(PLL_CONFIG_REG(pll));
		config_reg = readl_relaxed(PLL_CFG_CTL_REG(pll));
		l_reg = readl_relaxed(PLL_L_REG(pll));
		m_reg = readl_relaxed(PLL_M_REG(pll));
		n_reg = readl_relaxed(PLL_N_REG(pll));

		pr_err("PLL %s didn't lock after enabling for L value 0x%x!\n",
				c->dbg_name, l_reg);
		pr_err("mode register is 0x%x\n", mode);
		pr_err("status register is 0x%x\n", status_reg);
		pr_err("user control register is 0x%x\n", user_reg);
		pr_err("config control register is 0x%x\n", config_reg);
		pr_err("L value register is 0x%x\n", l_reg);
		pr_err("M value register is 0x%x\n", m_reg);
		pr_err("N value control register is 0x%x\n", n_reg);
		if (pll->spm_ctrl.spm_base)
			pr_err("L2 spm_force_event_en 0x%x\n",
			readl_relaxed(pll->spm_ctrl.spm_base +
						SPM_FORCE_EVENT));
		panic("PLL %s didn't lock after enabling it!\n", c->dbg_name);
	}

	/* Enable PLL output. */
	mode |= PLL_OUTCTRL;
	writel_relaxed(mode, PLL_MODE_REG(pll));

	/* Ensure that the write above goes through before returning. */
	mb();

	spin_unlock_irqrestore(&pll_reg_lock, flags);

	return 0;
}
示例#30
0
static int pll_clk_is_enabled(struct clk *clk)
{
	struct pll_shared_clk *pll = to_pll_shared_clk(clk);

	return readl_relaxed(PLL_MODE_REG(pll)) & BIT(0);
}