Commit ec18b456 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'at91-5.7-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux into arm/soc

AT91 SoC for 5.7

 - Rework PM to support sam9x60

* tag 'at91-5.7-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux:
  ARM: at91: pm: add quirk for sam9x60's ulp1
  ARM: at91: pm: add plla disable/enable support for sam9x60
  clk: at91: move sam9x60's PLL register offsets to PMC header
  ARM: at91: pm: s/sfr/sfrbu in pm_suspend.S
  ARM: at91: pm: add pmc_version member to at91_pm_data
  ARM: at91: pm: add macros for plla disable/enable
  ARM: at91: pm: revert do not disable/enable PLLA for ULP modes
  ARM: at91: pm: use proper master clock register offset
  ARM: at91: Drop unneeded select of COMMON_CLK

Link: https://lore.kernel.org/r/20200322090116.GA208895@piout.net


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents fd91e03e bb1a0e87
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -153,7 +153,6 @@ config HAVE_AT91_USB_CLK

config COMMON_CLK_AT91
	bool
	select COMMON_CLK
	select MFD_SYSCON

config HAVE_AT91_SMD
+30 −5
Original line number Diff line number Diff line
@@ -736,13 +736,36 @@ backup_default:

struct pmc_info {
	unsigned long uhp_udp_mask;
	unsigned long mckr;
	unsigned long version;
};

static const struct pmc_info pmc_infos[] __initconst = {
	{ .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP },
	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP },
	{ .uhp_udp_mask = AT91SAM926x_PMC_UHP },
	{ .uhp_udp_mask = 0 },
	{
		.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP,
		.mckr = 0x30,
		.version = AT91_PMC_V1,
	},

	{
		.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
		.mckr = 0x30,
		.version = AT91_PMC_V1,
	},
	{
		.uhp_udp_mask = AT91SAM926x_PMC_UHP,
		.mckr = 0x30,
		.version = AT91_PMC_V1,
	},
	{	.uhp_udp_mask = 0,
		.mckr = 0x30,
		.version = AT91_PMC_V1,
	},
	{
		.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
		.mckr = 0x28,
		.version = AT91_PMC_V2,
	},
};

static const struct of_device_id atmel_pmc_ids[] __initconst = {
@@ -757,7 +780,7 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = {
	{ .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
	{ .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
	{ .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
	{ .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[1] },
	{ .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] },
	{ /* sentinel */ },
};

@@ -779,6 +802,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))

	pmc = of_id->data;
	soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask;
	soc_pm.data.pmc_mckr_offset = pmc->mckr;
	soc_pm.data.pmc_version = pmc->version;

	if (pm_idle)
		arm_pm_idle = pm_idle;
+2 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ struct at91_pm_data {
	void __iomem *sfrbu;
	unsigned int standby_mode;
	unsigned int suspend_mode;
	unsigned int pmc_mckr_offset;
	unsigned int pmc_version;
};
#endif

+4 −0
Original line number Diff line number Diff line
@@ -12,6 +12,10 @@ int main(void)
	DEFINE(PM_DATA_MODE,		offsetof(struct at91_pm_data, mode));
	DEFINE(PM_DATA_SHDWC,		offsetof(struct at91_pm_data, shdwc));
	DEFINE(PM_DATA_SFRBU,		offsetof(struct at91_pm_data, sfrbu));
	DEFINE(PM_DATA_PMC_MCKR_OFFSET,	offsetof(struct at91_pm_data,
						 pmc_mckr_offset));
	DEFINE(PM_DATA_PMC_VERSION,	offsetof(struct at91_pm_data,
						 pmc_version));

	return 0;
}
+174 −15
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
pmc	.req	r0
tmp1	.req	r4
tmp2	.req	r5
tmp3	.req	r6

/*
 * Wait until master clock is ready (after switching master clock source)
@@ -93,13 +94,17 @@ ENTRY(at91_pm_suspend_in_sram)
	str	tmp1, .memtype
	ldr	tmp1, [r0, #PM_DATA_MODE]
	str	tmp1, .pm_mode
	ldr	tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
	str	tmp1, .mckr_offset
	ldr	tmp1, [r0, #PM_DATA_PMC_VERSION]
	str	tmp1, .pmc_version
	/* Both ldrne below are here to preload their address in the TLB */
	ldr	tmp1, [r0, #PM_DATA_SHDWC]
	str	tmp1, .shdwc
	cmp	tmp1, #0
	ldrne	tmp2, [tmp1, #0]
	ldr	tmp1, [r0, #PM_DATA_SFRBU]
	str	tmp1, .sfr
	str	tmp1, .sfrbu
	cmp	tmp1, #0
	ldrne	tmp2, [tmp1, #0x10]

@@ -138,14 +143,15 @@ ENDPROC(at91_pm_suspend_in_sram)
ENTRY(at91_backup_mode)
	/* Switch the master clock source to slow clock. */
	ldr	pmc, .pmc_base
	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
	ldr	tmp2, .mckr_offset
	ldr	tmp1, [pmc, tmp2]
	bic	tmp1, tmp1, #AT91_PMC_CSS
	str	tmp1, [pmc, #AT91_PMC_MCKR]
	str	tmp1, [pmc, tmp2]

	wait_mckrdy

	/*BUMEN*/
	ldr	r0, .sfr
	ldr	r0, .sfrbu
	mov	tmp1, #0x1
	str	tmp1, [r0, #0x10]

@@ -218,6 +224,7 @@ ENDPROC(at91_backup_mode)
 */
.macro at91_pm_ulp1_mode
	ldr	pmc, .pmc_base
	ldr	tmp2, .mckr_offset

	/* Save RC oscillator state and check if it is enabled. */
	ldr	tmp1, [pmc, #AT91_PMC_SR]
@@ -254,10 +261,10 @@ ENDPROC(at91_backup_mode)
	str	tmp1, [pmc, #AT91_CKGR_MOR]

	/* Switch the master clock source to main clock */
	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
	ldr	tmp1, [pmc, tmp2]
	bic	tmp1, tmp1, #AT91_PMC_CSS
	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
	str	tmp1, [pmc, #AT91_PMC_MCKR]
	str	tmp1, [pmc, tmp2]

	wait_mckrdy

@@ -268,6 +275,10 @@ ENDPROC(at91_backup_mode)
	orr	tmp1, tmp1, #AT91_PMC_KEY
	str	tmp1, [pmc, #AT91_CKGR_MOR]

	/* Quirk for SAM9X60's PMC */
	nop
	nop

	wait_mckrdy

	/* Enable the crystal oscillator */
@@ -280,9 +291,9 @@ ENDPROC(at91_backup_mode)
	wait_moscrdy

	/* Switch the master clock source to slow clock */
	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
	ldr	tmp1, [pmc, tmp2]
	bic	tmp1, tmp1, #AT91_PMC_CSS
	str	tmp1, [pmc, #AT91_PMC_MCKR]
	str	tmp1, [pmc, tmp2]

	wait_mckrdy

@@ -296,10 +307,10 @@ ENDPROC(at91_backup_mode)
	wait_moscsels

	/* Switch the master clock source to main clock */
	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
	ldr	tmp1, [pmc, tmp2]
	bic	tmp1, tmp1, #AT91_PMC_CSS
	orr	tmp1, tmp1, #AT91_PMC_CSS_MAIN
	str	tmp1, [pmc, #AT91_PMC_MCKR]
	str	tmp1, [pmc, tmp2]

	wait_mckrdy

@@ -323,21 +334,160 @@ ENDPROC(at91_backup_mode)
3:
.endm

.macro at91_plla_disable
	/* Save PLLA setting and disable it */
	ldr	tmp1, .pmc_version
	cmp	tmp1, #AT91_PMC_V1
	beq	1f

#ifdef CONFIG_SOC_SAM9X60
	/* Save PLLA settings. */
	ldr	tmp2, [pmc, #AT91_PMC_PLL_UPDT]
	bic	tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID
	str	tmp2, [pmc, #AT91_PMC_PLL_UPDT]

	/* save div. */
	mov	tmp1, #0
	ldr	tmp2, [pmc, #AT91_PMC_PLL_CTRL0]
	bic	tmp2, tmp2, #0xffffff00
	orr	tmp1, tmp1, tmp2

	/* save mul. */
	ldr	tmp2, [pmc, #AT91_PMC_PLL_CTRL1]
	bic	tmp2, tmp2, #0xffffff
	orr	tmp1, tmp1, tmp2
	str	tmp1, .saved_pllar

	/* step 2. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]

	/* step 3. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
	bic	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]

	/* step 4. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]

	/* step 5. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
	bic	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]

	/* step 7. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]

	b	2f
#endif

1:	/* Save PLLA setting and disable it */
	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
	str	tmp1, .saved_pllar

	/* Disable PLLA. */
	mov	tmp1, #AT91_PMC_PLLCOUNT
	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
2:
.endm

.macro at91_plla_enable
	ldr	tmp2, .saved_pllar
	ldr	tmp3, .pmc_version
	cmp	tmp3, #AT91_PMC_V1
	beq	4f

#ifdef CONFIG_SOC_SAM9X60
	/* step 1. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]

	/* step 2. */
	ldr	tmp1, =#AT91_PMC_PLL_ACR_DEFAULT_PLLA
	str	tmp1, [pmc, #AT91_PMC_PLL_ACR]

	/* step 3. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL1]
	mov	tmp3, tmp2
	bic	tmp3, tmp3, #0xffffff
	orr	tmp1, tmp1, tmp3
	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL1]

	/* step 8. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]

	/* step 9. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]
	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK
	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL
	orr	tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK
	bic	tmp1, tmp1, #0xff
	mov	tmp3, tmp2
	bic	tmp3, tmp3, #0xffffff00
	orr	tmp1, tmp1, tmp3
	str	tmp1, [pmc, #AT91_PMC_PLL_CTRL0]

	/* step 10. */
	ldr	tmp1, [pmc, #AT91_PMC_PLL_UPDT]
	orr	tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE
	bic	tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID
	str	tmp1, [pmc, #AT91_PMC_PLL_UPDT]

	/* step 11. */
3:	ldr	tmp1, [pmc, #AT91_PMC_PLL_ISR0]
	tst	tmp1, #0x1
	beq	3b
	b	2f
#endif

	/* Restore PLLA setting */
4:	str	tmp2, [pmc, #AT91_CKGR_PLLAR]

	/* Enable PLLA. */
	tst	tmp2, #(AT91_PMC_MUL &  0xff0000)
	bne	1f
	tst	tmp2, #(AT91_PMC_MUL & ~0xff0000)
	beq	2f

1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
	tst	tmp1, #AT91_PMC_LOCKA
	beq	1b
2:
.endm

ENTRY(at91_ulp_mode)
	ldr	pmc, .pmc_base
	ldr	tmp2, .mckr_offset

	/* Save Master clock setting */
	ldr	tmp1, [pmc, #AT91_PMC_MCKR]
	ldr	tmp1, [pmc, tmp2]
	str	tmp1, .saved_mckr

	/*
	 * Set the Master clock source to slow clock
	 */
	bic	tmp1, tmp1, #AT91_PMC_CSS
	str	tmp1, [pmc, #AT91_PMC_MCKR]
	str	tmp1, [pmc, tmp2]

	wait_mckrdy

	at91_plla_disable

	ldr	r0, .pm_mode
	cmp	r0, #AT91_PM_ULP1
	beq	ulp1_mode
@@ -352,11 +502,14 @@ ulp1_mode:
ulp_exit:
	ldr	pmc, .pmc_base

	at91_plla_enable

	/*
	 * Restore master clock setting
	 */
	ldr	tmp1, .saved_mckr
	str	tmp1, [pmc, #AT91_PMC_MCKR]
	ldr	tmp1, .mckr_offset
	ldr	tmp2, .saved_mckr
	str	tmp2, [pmc, tmp1]

	wait_mckrdy

@@ -496,14 +649,20 @@ ENDPROC(at91_sramc_self_refresh)
	.word 0
.shdwc:
	.word 0
.sfr:
.sfrbu:
	.word 0
.memtype:
	.word 0
.pm_mode:
	.word 0
.mckr_offset:
	.word 0
.pmc_version:
	.word 0
.saved_mckr:
	.word 0
.saved_pllar:
	.word 0
.saved_sam9_lpr:
	.word 0
.saved_sam9_lpr1:
Loading