Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2a141a4 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: clock-pll: Panic if a variable rate PLL fails to lock"

parents 5e9d5032 4a1caaa8
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ static struct pll_clk a57_pll0 = {
	.config_reg = (void __iomem *)C1_PLL_USER_CTL,
	.config_ctl_reg = (void __iomem *)C1_PLL_CONFIG_CTL,
	.status_reg = (void __iomem *)C1_PLL_MODE,
	.alt_status_reg = (void __iomem *)C1_PLL_STATUS,
	.test_ctl_lo_reg = (void __iomem *)C1_PLL_TEST_CTL_LO,
	.test_ctl_hi_reg = (void __iomem *)C1_PLL_TEST_CTL_HI,
	.pgm_test_ctl_enable = true,
@@ -208,6 +209,7 @@ static struct pll_clk a57_pll1 = {
	.config_reg = (void __iomem *)C1_PLLA_USER_CTL,
	.config_ctl_reg = (void __iomem *)C1_PLLA_CONFIG_CTL,
	.status_reg = (void __iomem *)C1_PLLA_MODE,
	.alt_status_reg = (void __iomem *)C1_PLLA_STATUS,
	.test_ctl_lo_reg = (void __iomem *)C1_PLLA_TEST_CTL_LO,
	.test_ctl_hi_reg = (void __iomem *)C1_PLLA_TEST_CTL_HI,
	.pgm_test_ctl_enable = true,
@@ -245,6 +247,7 @@ static struct pll_clk a53_pll0 = {
	.config_reg = (void __iomem *)C0_PLL_USER_CTL,
	.config_ctl_reg = (void __iomem *)C0_PLL_CONFIG_CTL,
	.status_reg = (void __iomem *)C0_PLL_MODE,
	.alt_status_reg = (void __iomem *)C0_PLL_STATUS,
	.test_ctl_lo_reg = (void __iomem *)C0_PLL_TEST_CTL_LO,
	.test_ctl_hi_reg = (void __iomem *)C0_PLL_TEST_CTL_HI,
	.pgm_test_ctl_enable = true,
@@ -280,6 +283,7 @@ static struct pll_clk a53_pll1 = {
	.config_reg = (void __iomem *)C0_PLLA_USER_CTL,
	.config_ctl_reg = (void __iomem *)C0_PLLA_CONFIG_CTL,
	.status_reg = (void __iomem *)C0_PLLA_MODE,
	.alt_status_reg = (void __iomem *)C0_PLLA_STATUS,
	.test_ctl_lo_reg = (void __iomem *)C0_PLLA_TEST_CTL_LO,
	.test_ctl_hi_reg = (void __iomem *)C0_PLLA_TEST_CTL_HI,
	.pgm_test_ctl_enable = true,
+85 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/sched.h>
#include <soc/qcom/clock-pll.h>
#include <soc/qcom/msm-clock-controller.h>

@@ -31,6 +32,8 @@

#define PLL_EN_REG(x)		(*(x)->base + (unsigned long) (x)->en_reg)
#define PLL_STATUS_REG(x)	(*(x)->base + (unsigned long) (x)->status_reg)
#define PLL_ALT_STATUS_REG(x)	(*(x)->base + (unsigned long) \
							(x)->alt_status_reg)
#define PLL_MODE_REG(x)		(*(x)->base + (unsigned long) (x)->mode_reg)
#define PLL_L_REG(x)		(*(x)->base + (unsigned long) (x)->l_reg)
#define PLL_M_REG(x)		(*(x)->base + (unsigned long) (x)->m_reg)
@@ -258,8 +261,11 @@ 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;
	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);

@@ -274,6 +280,17 @@ static int variable_rate_pll_clk_enable(struct clk *c)
		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));
@@ -303,6 +320,8 @@ static int variable_rate_pll_clk_enable(struct clk *c)
		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) {
@@ -314,12 +333,74 @@ static int variable_rate_pll_clk_enable(struct clk *c)
			 */
			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();

	if (!(readl_relaxed(PLL_STATUS_REG(pll)) & lockmask))
		pr_err("PLL %s didn't lock after enabling it!\n", c->dbg_name);
		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;
+1 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ struct pll_clk {
	void __iomem *const config_reg;
	void __iomem *const config_ctl_reg;
	void __iomem *const status_reg;
	void __iomem *const alt_status_reg;
	void __iomem *const test_ctl_lo_reg;
	void __iomem *const test_ctl_hi_reg;