Commit e13208ab authored by Claudiu Beznea's avatar Claudiu Beznea Committed by Alexandre Belloni
Browse files

clk: at91: move sam9x60's PLL register offsets to PMC header



Move SAM9X60's PLL register offsets to PMC header so that the
definitions would also be available from arch/arm/mach-at91/pm_suspend.S.
This is necessary to disable/enable PLLA for SAM9X60 on suspend/resume.

Signed-off-by: default avatarClaudiu Beznea <claudiu.beznea@microchip.com>
Acked-by: default avatarStephen Boyd <sboyd@kernel.org>
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/1579522208-19523-7-git-send-email-claudiu.beznea@microchip.com
parent 4a877560
Loading
Loading
Loading
Loading
+37 −54
Original line number Diff line number Diff line
@@ -14,28 +14,9 @@

#include "pmc.h"

#define PMC_PLL_CTRL0	0xc
#define	PMC_PLL_CTRL0_DIV_MSK	GENMASK(7, 0)
#define		PMC_PLL_CTRL0_ENPLL		BIT(28)
#define		PMC_PLL_CTRL0_ENPLLCK		BIT(29)
#define		PMC_PLL_CTRL0_ENLOCK		BIT(31)

#define PMC_PLL_CTRL1	0x10
#define		PMC_PLL_CTRL1_FRACR_MSK		GENMASK(21, 0)
#define	PMC_PLL_CTRL1_MUL_MSK	GENMASK(30, 24)

#define PMC_PLL_ACR	0x18
#define		PMC_PLL_ACR_DEFAULT_UPLL	0x12020010UL
#define		PMC_PLL_ACR_DEFAULT_PLLA	0x00020010UL
#define		PMC_PLL_ACR_UTMIVR		BIT(12)
#define		PMC_PLL_ACR_UTMIBG		BIT(13)
#define		PMC_PLL_ACR_LOOP_FILTER_MSK	GENMASK(31, 24)

#define PMC_PLL_UPDT	0x1c
#define		PMC_PLL_UPDT_UPDATE		BIT(8)

#define PMC_PLL_ISR0	0xec

#define PLL_DIV_MAX		(FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
#define UPLL_DIV		2
#define PLL_MUL_MAX		(FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
@@ -59,7 +40,7 @@ static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
{
	unsigned int status;

	regmap_read(regmap, PMC_PLL_ISR0, &status);
	regmap_read(regmap, AT91_PMC_PLL_ISR0, &status);

	return !!(status & BIT(id));
}
@@ -74,12 +55,12 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
	u32 val;

	spin_lock_irqsave(pll->lock, flags);
	regmap_write(regmap, PMC_PLL_UPDT, pll->id);
	regmap_write(regmap, AT91_PMC_PLL_UPDT, pll->id);

	regmap_read(regmap, PMC_PLL_CTRL0, &val);
	regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
	div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);

	regmap_read(regmap, PMC_PLL_CTRL1, &val);
	regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
	mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);

	if (sam9x60_pll_ready(regmap, pll->id) &&
@@ -88,39 +69,39 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
		return 0;
	}

	/* Recommended value for PMC_PLL_ACR */
	/* Recommended value for AT91_PMC_PLL_ACR */
	if (pll->characteristics->upll)
		val = PMC_PLL_ACR_DEFAULT_UPLL;
		val = AT91_PMC_PLL_ACR_DEFAULT_UPLL;
	else
		val = PMC_PLL_ACR_DEFAULT_PLLA;
	regmap_write(regmap, PMC_PLL_ACR, val);
		val = AT91_PMC_PLL_ACR_DEFAULT_PLLA;
	regmap_write(regmap, AT91_PMC_PLL_ACR, val);

	regmap_write(regmap, PMC_PLL_CTRL1,
	regmap_write(regmap, AT91_PMC_PLL_CTRL1,
		     FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul));

	if (pll->characteristics->upll) {
		/* Enable the UTMI internal bandgap */
		val |= PMC_PLL_ACR_UTMIBG;
		regmap_write(regmap, PMC_PLL_ACR, val);
		val |= AT91_PMC_PLL_ACR_UTMIBG;
		regmap_write(regmap, AT91_PMC_PLL_ACR, val);

		udelay(10);

		/* Enable the UTMI internal regulator */
		val |= PMC_PLL_ACR_UTMIVR;
		regmap_write(regmap, PMC_PLL_ACR, val);
		val |= AT91_PMC_PLL_ACR_UTMIVR;
		regmap_write(regmap, AT91_PMC_PLL_ACR, val);

		udelay(10);
	}

	regmap_update_bits(regmap, PMC_PLL_UPDT,
			   PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
	regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
			   AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);

	regmap_write(regmap, PMC_PLL_CTRL0,
		     PMC_PLL_CTRL0_ENLOCK | PMC_PLL_CTRL0_ENPLL |
		     PMC_PLL_CTRL0_ENPLLCK | pll->div);
	regmap_write(regmap, AT91_PMC_PLL_CTRL0,
		     AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL |
		     AT91_PMC_PLL_CTRL0_ENPLLCK | pll->div);

	regmap_update_bits(regmap, PMC_PLL_UPDT,
			   PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
	regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
			   AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);

	while (!sam9x60_pll_ready(regmap, pll->id))
		cpu_relax();
@@ -144,22 +125,24 @@ static void sam9x60_pll_unprepare(struct clk_hw *hw)

	spin_lock_irqsave(pll->lock, flags);

	regmap_write(pll->regmap, PMC_PLL_UPDT, pll->id);
	regmap_write(pll->regmap, AT91_PMC_PLL_UPDT, pll->id);

	regmap_update_bits(pll->regmap, PMC_PLL_CTRL0,
			   PMC_PLL_CTRL0_ENPLLCK, 0);
	regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0,
			   AT91_PMC_PLL_CTRL0_ENPLLCK, 0);

	regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
			   PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
	regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
			   AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);

	regmap_update_bits(pll->regmap, PMC_PLL_CTRL0, PMC_PLL_CTRL0_ENPLL, 0);
	regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0,
			   AT91_PMC_PLL_CTRL0_ENPLL, 0);

	if (pll->characteristics->upll)
		regmap_update_bits(pll->regmap, PMC_PLL_ACR,
				   PMC_PLL_ACR_UTMIBG | PMC_PLL_ACR_UTMIVR, 0);
		regmap_update_bits(pll->regmap, AT91_PMC_PLL_ACR,
				   AT91_PMC_PLL_ACR_UTMIBG |
				   AT91_PMC_PLL_ACR_UTMIVR, 0);

	regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
			   PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
	regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT,
			   AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE);

	spin_unlock_irqrestore(pll->lock, flags);
}
@@ -316,10 +299,10 @@ sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
	pll->regmap = regmap;
	pll->lock = lock;

	regmap_write(regmap, PMC_PLL_UPDT, id);
	regmap_read(regmap, PMC_PLL_CTRL0, &pllr);
	regmap_write(regmap, AT91_PMC_PLL_UPDT, id);
	regmap_read(regmap, AT91_PMC_PLL_CTRL0, &pllr);
	pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr);
	regmap_read(regmap, PMC_PLL_CTRL1, &pllr);
	regmap_read(regmap, AT91_PMC_PLL_CTRL1, &pllr);
	pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr);

	hw = &pll->hw;
+20 −0
Original line number Diff line number Diff line
@@ -33,16 +33,34 @@
#define		AT91_PMC_HCK0		(1 << 16)		/* AHB Clock (USB host) [AT91SAM9261 only] */
#define		AT91_PMC_HCK1		(1 << 17)		/* AHB Clock (LCD) [AT91SAM9261 only] */

#define AT91_PMC_PLL_CTRL0		0x0C		/* PLL Control Register 0 [for SAM9X60] */
#define		AT91_PMC_PLL_CTRL0_ENPLL	(1 << 28)	/* Enable PLL */
#define		AT91_PMC_PLL_CTRL0_ENPLLCK	(1 << 29)	/* Enable PLL clock for PMC */
#define		AT91_PMC_PLL_CTRL0_ENLOCK	(1 << 31)	/* Enable PLL lock */

#define AT91_PMC_PLL_CTRL1		0x10		/* PLL Control Register 1 [for SAM9X60] */

#define	AT91_PMC_PCER		0x10			/* Peripheral Clock Enable Register */
#define	AT91_PMC_PCDR		0x14			/* Peripheral Clock Disable Register */
#define	AT91_PMC_PCSR		0x18			/* Peripheral Clock Status Register */

#define AT91_PMC_PLL_ACR	0x18			/* PLL Analog Control Register [for SAM9X60] */
#define		AT91_PMC_PLL_ACR_DEFAULT_UPLL	0x12020010UL	/* Default PLL ACR value for UPLL */
#define		AT91_PMC_PLL_ACR_DEFAULT_PLLA	0x00020010UL	/* Default PLL ACR value for PLLA */
#define		AT91_PMC_PLL_ACR_UTMIVR		(1 << 12)	/* UPLL Voltage regulator Control */
#define		AT91_PMC_PLL_ACR_UTMIBG		(1 << 13)	/* UPLL Bandgap Control */

#define	AT91_CKGR_UCKR		0x1C			/* UTMI Clock Register [some SAM9] */
#define		AT91_PMC_UPLLEN		(1   << 16)		/* UTMI PLL Enable */
#define		AT91_PMC_UPLLCOUNT	(0xf << 20)		/* UTMI PLL Start-up Time */
#define		AT91_PMC_BIASEN		(1   << 24)		/* UTMI BIAS Enable */
#define		AT91_PMC_BIASCOUNT	(0xf << 28)		/* UTMI BIAS Start-up Time */

#define AT91_PMC_PLL_UPDT		0x1C		/* PMC PLL update register [for SAM9X60] */
#define		AT91_PMC_PLL_UPDT_UPDATE	(1 << 8)	/* Update PLL settings */
#define		AT91_PMC_PLL_UPDT_ID		(1 << 0)	/* PLL ID */
#define		AT91_PMC_PLL_UPDT_STUPTIM	(0xff << 16)	/* Startup time */

#define	AT91_CKGR_MOR		0x20			/* Main Oscillator Register [not on SAM9RL] */
#define		AT91_PMC_MOSCEN		(1    <<  0)		/* Main Oscillator Enable */
#define		AT91_PMC_OSCBYPASS	(1    <<  1)		/* Oscillator Bypass */
@@ -183,6 +201,8 @@
#define		AT91_PMC_WPVS		(0x1  <<  0)		/* Write Protect Violation Status */
#define		AT91_PMC_WPVSRC		(0xffff  <<  8)		/* Write Protect Violation Source */

#define AT91_PMC_PLL_ISR0	0xEC			/* PLL Interrupt Status Register 0 [SAM9X60 only] */

#define AT91_PMC_PCER1		0x100			/* Peripheral Clock Enable Register 1 [SAMA5 only]*/
#define AT91_PMC_PCDR1		0x104			/* Peripheral Clock Enable Register 1 */
#define AT91_PMC_PCSR1		0x108			/* Peripheral Clock Enable Register 1 */