Linux-Clk Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/8] PM fixes and improvements for SAM9X60
@ 2020-01-20 12:10 Claudiu Beznea
  2020-01-20 12:10 ` [PATCH 1/8] ARM: at91: pm: use proper master clock register offset Claudiu Beznea
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Claudiu Beznea @ 2020-01-20 12:10 UTC (permalink / raw)
  To: nicolas.ferre, alexandre.belloni, ludovic.desroches, linux,
	mturquette, sboyd
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

Hi,

This series adds fixes and improvements for SAM9X60 as follows:
- fix master clock register offset in pm_suspend.S
- add support for disable/enable PLL for SAM9X60
- minor fix in pm_suspend.S: s/sfr/sfrbu
- move SAM9X60's macros for PLL in include/linux/clk/at91_pmc.h

Thank you,
Claudiu Beznea

Claudiu Beznea (8):
  ARM: at91: pm: use proper master clock register offset
  Revert "ARM: at91: pm: do not disable/enable PLLA for ULP modes"
  ARM: at91: pm: add macros for plla disable/enable
  ARM: at91: pm: add pmc_version member to at91_pm_data
  ARM: at91: pm: s/sfr/sfrbu in pm_suspend.S
  clk: at91: move sam9x60's PLL register offsets to PMC header
  ARM: at91: pm: add plla disable/enable support for sam9x60
  ARM: at91: pm: add quirk for sam9x60's ulp1

 arch/arm/mach-at91/pm.c              |  35 ++++++-
 arch/arm/mach-at91/pm.h              |   2 +
 arch/arm/mach-at91/pm_data-offsets.c |   4 +
 arch/arm/mach-at91/pm_suspend.S      | 189 ++++++++++++++++++++++++++++++++---
 drivers/clk/at91/clk-sam9x60-pll.c   |  91 +++++++----------
 include/linux/clk/at91_pmc.h         |  23 +++++
 6 files changed, 270 insertions(+), 74 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/8] ARM: at91: pm: use proper master clock register offset
  2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
@ 2020-01-20 12:10 ` Claudiu Beznea
  2020-01-20 12:10 ` [PATCH 2/8] Revert "ARM: at91: pm: do not disable/enable PLLA for ULP modes" Claudiu Beznea
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Claudiu Beznea @ 2020-01-20 12:10 UTC (permalink / raw)
  To: nicolas.ferre, alexandre.belloni, ludovic.desroches, linux,
	mturquette, sboyd
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

SAM9X60's PMC has different master clock register offset than the other
SoCs' PMC. Due to this, specify master clock register offset based
on PMC compatible and pass it to pm_suspend.S since it is also needed
in there. When PM part for SAM9X60 was published the SAM9X60's PMC
(commit f6deae46039c ("clk: at91: add sam9x60 pmc driver")) wasn't
integrated.

Fixes: fd2280a1829b ("ARM: at91: pm: initial PM support for SAM9X60")
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 arch/arm/mach-at91/pm.c              | 28 +++++++++++++++++++++++-----
 arch/arm/mach-at91/pm.h              |  1 +
 arch/arm/mach-at91/pm_data-offsets.c |  2 ++
 arch/arm/mach-at91/pm_suspend.S      | 32 ++++++++++++++++++++------------
 4 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 374b9d155558..ae7b148febd9 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -736,13 +736,30 @@ static void __init at91_pm_modes_init(void)
 
 struct pmc_info {
 	unsigned long uhp_udp_mask;
+	unsigned long mckr;
 };
 
 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,
+	},
+
+	{
+		.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
+		.mckr = 0x30,
+	},
+	{
+		.uhp_udp_mask = AT91SAM926x_PMC_UHP,
+		.mckr = 0x30,
+	},
+	{	.uhp_udp_mask = 0,
+		.mckr = 0x30,
+	},
+	{
+		.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP,
+		.mckr = 0x28,
+	},
 };
 
 static const struct of_device_id atmel_pmc_ids[] __initconst = {
@@ -757,7 +774,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 +796,7 @@ 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;
 
 	if (pm_idle)
 		arm_pm_idle = pm_idle;
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 9fa4f483f2b5..6f7f4236865a 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -33,6 +33,7 @@ struct at91_pm_data {
 	void __iomem *sfrbu;
 	unsigned int standby_mode;
 	unsigned int suspend_mode;
+	unsigned int pmc_mckr_offset;
 };
 #endif
 
diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c
index f2d893c03cd9..dfcbe626865c 100644
--- a/arch/arm/mach-at91/pm_data-offsets.c
+++ b/arch/arm/mach-at91/pm_data-offsets.c
@@ -12,6 +12,8 @@ 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));
 
 	return 0;
 }
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index ed57c879d4e1..52b262d56cfd 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -93,6 +93,8 @@ 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
 	/* Both ldrne below are here to preload their address in the TLB */
 	ldr	tmp1, [r0, #PM_DATA_SHDWC]
 	str	tmp1, .shdwc
@@ -138,9 +140,10 @@ 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
 
@@ -218,6 +221,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 +258,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
 
@@ -280,9 +284,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 +300,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
 
@@ -325,16 +329,17 @@ ENDPROC(at91_backup_mode)
 
 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
 
@@ -355,8 +360,9 @@ ulp_exit:
 	/*
 	 * 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
 
@@ -502,6 +508,8 @@ ENDPROC(at91_sramc_self_refresh)
 	.word 0
 .pm_mode:
 	.word 0
+.mckr_offset:
+	.word 0
 .saved_mckr:
 	.word 0
 .saved_sam9_lpr:
-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/8] Revert "ARM: at91: pm: do not disable/enable PLLA for ULP modes"
  2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
  2020-01-20 12:10 ` [PATCH 1/8] ARM: at91: pm: use proper master clock register offset Claudiu Beznea
@ 2020-01-20 12:10 ` Claudiu Beznea
  2020-01-20 12:10 ` [PATCH 3/8] ARM: at91: pm: add macros for plla disable/enable Claudiu Beznea
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Claudiu Beznea @ 2020-01-20 12:10 UTC (permalink / raw)
  To: nicolas.ferre, alexandre.belloni, ludovic.desroches, linux,
	mturquette, sboyd
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

This reverts commit 2725d70aa5138284ba2cebf0ef51dd23e0c9ea21
("ARM: at91: pm: do not disable/enable PLLA for ULP modes").
This is because PLLA is the clock source for CPU, PLLA should
be disabled/enabled in the final/first phase of suspend/resume
so that the power consumption in suspend/resume to be minimal
and suspend/resume time to be minimized.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 arch/arm/mach-at91/pm_suspend.S | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 52b262d56cfd..bfb3aab8859e 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -47,6 +47,15 @@ tmp2	.req	r5
 	.endm
 
 /*
+ * Wait until PLLA has locked.
+ */
+	.macro wait_pllalock
+1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
+	tst	tmp1, #AT91_PMC_LOCKA
+	beq	1b
+	.endm
+
+/*
  * Put the processor to enter the idle state
  */
 	.macro at91_cpu_idle
@@ -343,6 +352,14 @@ ENTRY(at91_ulp_mode)
 
 	wait_mckrdy
 
+	/* Save PLLA setting and disable it */
+	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
+	str	tmp1, .saved_pllar
+
+	mov	tmp1, #AT91_PMC_PLLCOUNT
+	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
 	ldr	r0, .pm_mode
 	cmp	r0, #AT91_PM_ULP1
 	beq	ulp1_mode
@@ -357,6 +374,18 @@ ulp1_mode:
 ulp_exit:
 	ldr	pmc, .pmc_base
 
+	/* Restore PLLA setting */
+	ldr	tmp1, .saved_pllar
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
+	bne	3f
+	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
+	beq	4f
+3:
+	wait_pllalock
+4:
+
 	/*
 	 * Restore master clock setting
 	 */
@@ -512,6 +541,8 @@ ENDPROC(at91_sramc_self_refresh)
 	.word 0
 .saved_mckr:
 	.word 0
+.saved_pllar:
+	.word 0
 .saved_sam9_lpr:
 	.word 0
 .saved_sam9_lpr1:
-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/8] ARM: at91: pm: add macros for plla disable/enable
  2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
  2020-01-20 12:10 ` [PATCH 1/8] ARM: at91: pm: use proper master clock register offset Claudiu Beznea
  2020-01-20 12:10 ` [PATCH 2/8] Revert "ARM: at91: pm: do not disable/enable PLLA for ULP modes" Claudiu Beznea
@ 2020-01-20 12:10 ` Claudiu Beznea
  2020-01-20 12:10 ` [PATCH 4/8] ARM: at91: pm: add pmc_version member to at91_pm_data Claudiu Beznea
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Claudiu Beznea @ 2020-01-20 12:10 UTC (permalink / raw)
  To: nicolas.ferre, alexandre.belloni, ludovic.desroches, linux,
	mturquette, sboyd
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

Add macros for PLLA disable and enable (in disable macro the PLLA
state will also be saved). This prepares the field for PLLA disable/enable
for suspend/resume on SAM9X60.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 arch/arm/mach-at91/pm_suspend.S | 57 ++++++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index bfb3aab8859e..64460b4e0fc1 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -47,15 +47,6 @@ tmp2	.req	r5
 	.endm
 
 /*
- * Wait until PLLA has locked.
- */
-	.macro wait_pllalock
-1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
-	tst	tmp1, #AT91_PMC_LOCKA
-	beq	1b
-	.endm
-
-/*
  * Put the processor to enter the idle state
  */
 	.macro at91_cpu_idle
@@ -336,6 +327,34 @@ ENDPROC(at91_backup_mode)
 3:
 .endm
 
+.macro at91_plla_disable
+	/* 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]
+.endm
+
+.macro at91_plla_enable
+	/* Restore PLLA setting */
+	ldr	tmp1, .saved_pllar
+	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+
+	/* Enable PLLA. */
+	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
+	bne	1f
+	tst	tmp1, #(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
@@ -352,13 +371,7 @@ ENTRY(at91_ulp_mode)
 
 	wait_mckrdy
 
-	/* Save PLLA setting and disable it */
-	ldr	tmp1, [pmc, #AT91_CKGR_PLLAR]
-	str	tmp1, .saved_pllar
-
-	mov	tmp1, #AT91_PMC_PLLCOUNT
-	orr	tmp1, tmp1, #(1 << 29)		/* bit 29 always set */
-	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+	at91_plla_disable
 
 	ldr	r0, .pm_mode
 	cmp	r0, #AT91_PM_ULP1
@@ -374,17 +387,7 @@ ulp1_mode:
 ulp_exit:
 	ldr	pmc, .pmc_base
 
-	/* Restore PLLA setting */
-	ldr	tmp1, .saved_pllar
-	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
-
-	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
-	bne	3f
-	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
-	beq	4f
-3:
-	wait_pllalock
-4:
+	at91_plla_enable
 
 	/*
 	 * Restore master clock setting
-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4/8] ARM: at91: pm: add pmc_version member to at91_pm_data
  2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
                   ` (2 preceding siblings ...)
  2020-01-20 12:10 ` [PATCH 3/8] ARM: at91: pm: add macros for plla disable/enable Claudiu Beznea
@ 2020-01-20 12:10 ` Claudiu Beznea
  2020-02-12 23:30   ` Stephen Boyd
  2020-01-20 12:10 ` [PATCH 5/8] ARM: at91: pm: s/sfr/sfrbu in pm_suspend.S Claudiu Beznea
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: Claudiu Beznea @ 2020-01-20 12:10 UTC (permalink / raw)
  To: nicolas.ferre, alexandre.belloni, ludovic.desroches, linux,
	mturquette, sboyd
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

This will be used to differentiate b/w different PLLs settings to be
applied in the final/first steps of the suspend/resume process by doing
PLL specific configurations.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 arch/arm/mach-at91/pm.c              | 7 +++++++
 arch/arm/mach-at91/pm.h              | 1 +
 arch/arm/mach-at91/pm_data-offsets.c | 2 ++
 arch/arm/mach-at91/pm_suspend.S      | 4 ++++
 include/linux/clk/at91_pmc.h         | 3 +++
 5 files changed, 17 insertions(+)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index ae7b148febd9..074bde64064e 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -737,28 +737,34 @@ static void __init at91_pm_modes_init(void)
 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,
 		.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,
 	},
 };
 
@@ -797,6 +803,7 @@ 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;
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 6f7f4236865a..218e8d1a30fb 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -34,6 +34,7 @@ struct at91_pm_data {
 	unsigned int standby_mode;
 	unsigned int suspend_mode;
 	unsigned int pmc_mckr_offset;
+	unsigned int pmc_version;
 };
 #endif
 
diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c
index dfcbe626865c..82089ff258c0 100644
--- a/arch/arm/mach-at91/pm_data-offsets.c
+++ b/arch/arm/mach-at91/pm_data-offsets.c
@@ -14,6 +14,8 @@ int main(void)
 	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;
 }
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 64460b4e0fc1..5fa0c2aa10f7 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -95,6 +95,8 @@ ENTRY(at91_pm_suspend_in_sram)
 	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
@@ -542,6 +544,8 @@ ENDPROC(at91_sramc_self_refresh)
 	.word 0
 .mckr_offset:
 	.word 0
+.pmc_version:
+	.word 0
 .saved_mckr:
 	.word 0
 .saved_pllar:
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 390437887b46..f3d691fc5f29 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -12,6 +12,9 @@
 #ifndef AT91_PMC_H
 #define AT91_PMC_H
 
+#define AT91_PMC_V1		(1)			/* PMC version 1 */
+#define AT91_PMC_V2		(2)			/* PMC version 2 [SAM9X60] */
+
 #define	AT91_PMC_SCER		0x00			/* System Clock Enable Register */
 #define	AT91_PMC_SCDR		0x04			/* System Clock Disable Register */
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 5/8] ARM: at91: pm: s/sfr/sfrbu in pm_suspend.S
  2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
                   ` (3 preceding siblings ...)
  2020-01-20 12:10 ` [PATCH 4/8] ARM: at91: pm: add pmc_version member to at91_pm_data Claudiu Beznea
@ 2020-01-20 12:10 ` Claudiu Beznea
  2020-01-20 12:10 ` [PATCH 6/8] clk: at91: move sam9x60's PLL register offsets to PMC header Claudiu Beznea
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Claudiu Beznea @ 2020-01-20 12:10 UTC (permalink / raw)
  To: nicolas.ferre, alexandre.belloni, ludovic.desroches, linux,
	mturquette, sboyd
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

s/sfr/sfrbu in pm_suspend.S.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 arch/arm/mach-at91/pm_suspend.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 5fa0c2aa10f7..c898071e0c0b 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -103,7 +103,7 @@ ENTRY(at91_pm_suspend_in_sram)
 	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]
 
@@ -150,7 +150,7 @@ ENTRY(at91_backup_mode)
 	wait_mckrdy
 
 	/*BUMEN*/
-	ldr	r0, .sfr
+	ldr	r0, .sfrbu
 	mov	tmp1, #0x1
 	str	tmp1, [r0, #0x10]
 
@@ -536,7 +536,7 @@ ENDPROC(at91_sramc_self_refresh)
 	.word 0
 .shdwc:
 	.word 0
-.sfr:
+.sfrbu:
 	.word 0
 .memtype:
 	.word 0
-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 6/8] clk: at91: move sam9x60's PLL register offsets to PMC header
  2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
                   ` (4 preceding siblings ...)
  2020-01-20 12:10 ` [PATCH 5/8] ARM: at91: pm: s/sfr/sfrbu in pm_suspend.S Claudiu Beznea
@ 2020-01-20 12:10 ` Claudiu Beznea
  2020-02-12 23:31   ` Stephen Boyd
  2020-01-20 12:10 ` [PATCH 7/8] ARM: at91: pm: add plla disable/enable support for sam9x60 Claudiu Beznea
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: Claudiu Beznea @ 2020-01-20 12:10 UTC (permalink / raw)
  To: nicolas.ferre, alexandre.belloni, ludovic.desroches, linux,
	mturquette, sboyd
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

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: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/clk/at91/clk-sam9x60-pll.c | 91 ++++++++++++++++----------------------
 include/linux/clk/at91_pmc.h       | 20 +++++++++
 2 files changed, 57 insertions(+), 54 deletions(-)

diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index dfb354a5ff18..e699803986e5 100644
--- a/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -14,27 +14,8 @@
 
 #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	PMC_PLL_CTRL0_DIV_MSK	GENMASK(7, 0)
+#define	PMC_PLL_CTRL1_MUL_MSK	GENMASK(30, 24)
 
 #define PLL_DIV_MAX		(FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
 #define UPLL_DIV		2
@@ -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;
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index f3d691fc5f29..49a53a137610 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -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 */
-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 7/8] ARM: at91: pm: add plla disable/enable support for sam9x60
  2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
                   ` (5 preceding siblings ...)
  2020-01-20 12:10 ` [PATCH 6/8] clk: at91: move sam9x60's PLL register offsets to PMC header Claudiu Beznea
@ 2020-01-20 12:10 ` Claudiu Beznea
  2020-01-20 12:10 ` [PATCH 8/8] ARM: at91: pm: add quirk for sam9x60's ulp1 Claudiu Beznea
  2020-02-14 11:04 ` [PATCH 0/8] PM fixes and improvements for SAM9X60 Alexandre Belloni
  8 siblings, 0 replies; 12+ messages in thread
From: Claudiu Beznea @ 2020-01-20 12:10 UTC (permalink / raw)
  To: nicolas.ferre, alexandre.belloni, ludovic.desroches, linux,
	mturquette, sboyd
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

Add PLLA enable/disable support for SAM9X60.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 arch/arm/mach-at91/pm_suspend.S | 117 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 113 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index c898071e0c0b..4e9eb4f57f16 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -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)
@@ -331,6 +332,61 @@ ENDPROC(at91_backup_mode)
 
 .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
 
@@ -338,17 +394,70 @@ ENDPROC(at91_backup_mode)
 	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 */
-	ldr	tmp1, .saved_pllar
-	str	tmp1, [pmc, #AT91_CKGR_PLLAR]
+4:	str	tmp2, [pmc, #AT91_CKGR_PLLAR]
 
 	/* Enable PLLA. */
-	tst	tmp1, #(AT91_PMC_MUL &  0xff0000)
+	tst	tmp2, #(AT91_PMC_MUL &  0xff0000)
 	bne	1f
-	tst	tmp1, #(AT91_PMC_MUL & ~0xff0000)
+	tst	tmp2, #(AT91_PMC_MUL & ~0xff0000)
 	beq	2f
 
 1:	ldr	tmp1, [pmc, #AT91_PMC_SR]
-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 8/8] ARM: at91: pm: add quirk for sam9x60's ulp1
  2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
                   ` (6 preceding siblings ...)
  2020-01-20 12:10 ` [PATCH 7/8] ARM: at91: pm: add plla disable/enable support for sam9x60 Claudiu Beznea
@ 2020-01-20 12:10 ` Claudiu Beznea
  2020-02-14 11:04 ` [PATCH 0/8] PM fixes and improvements for SAM9X60 Alexandre Belloni
  8 siblings, 0 replies; 12+ messages in thread
From: Claudiu Beznea @ 2020-01-20 12:10 UTC (permalink / raw)
  To: nicolas.ferre, alexandre.belloni, ludovic.desroches, linux,
	mturquette, sboyd
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

On SAM9X60 2 nop operations has to be introduced after setting
WAITMODE bit in CKGR_MOR.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 arch/arm/mach-at91/pm_suspend.S | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index 4e9eb4f57f16..be9764e8d3fa 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -275,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 */
-- 
2.7.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/8] ARM: at91: pm: add pmc_version member to at91_pm_data
  2020-01-20 12:10 ` [PATCH 4/8] ARM: at91: pm: add pmc_version member to at91_pm_data Claudiu Beznea
@ 2020-02-12 23:30   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2020-02-12 23:30 UTC (permalink / raw)
  To: Claudiu Beznea, alexandre.belloni, linux, ludovic.desroches,
	mturquette, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

Quoting Claudiu Beznea (2020-01-20 04:10:04)
> This will be used to differentiate b/w different PLLs settings to be
> applied in the final/first steps of the suspend/resume process by doing
> PLL specific configurations.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
> ---

Acked-by: Stephen Boyd <sboyd@kernel.org>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 6/8] clk: at91: move sam9x60's PLL register offsets to PMC header
  2020-01-20 12:10 ` [PATCH 6/8] clk: at91: move sam9x60's PLL register offsets to PMC header Claudiu Beznea
@ 2020-02-12 23:31   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2020-02-12 23:31 UTC (permalink / raw)
  To: Claudiu Beznea, alexandre.belloni, linux, ludovic.desroches,
	mturquette, nicolas.ferre
  Cc: linux-arm-kernel, linux-kernel, linux-clk, Claudiu Beznea

Quoting Claudiu Beznea (2020-01-20 04:10:06)
> 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: Claudiu Beznea <claudiu.beznea@microchip.com>
> ---

Acked-by: Stephen Boyd <sboyd@kernel.org>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/8] PM fixes and improvements for SAM9X60
  2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
                   ` (7 preceding siblings ...)
  2020-01-20 12:10 ` [PATCH 8/8] ARM: at91: pm: add quirk for sam9x60's ulp1 Claudiu Beznea
@ 2020-02-14 11:04 ` Alexandre Belloni
  8 siblings, 0 replies; 12+ messages in thread
From: Alexandre Belloni @ 2020-02-14 11:04 UTC (permalink / raw)
  To: Claudiu Beznea
  Cc: nicolas.ferre, ludovic.desroches, linux, mturquette, sboyd,
	linux-arm-kernel, linux-kernel, linux-clk

On 20/01/2020 14:10:00+0200, Claudiu Beznea wrote:
> Hi,
> 
> This series adds fixes and improvements for SAM9X60 as follows:
> - fix master clock register offset in pm_suspend.S
> - add support for disable/enable PLL for SAM9X60
> - minor fix in pm_suspend.S: s/sfr/sfrbu
> - move SAM9X60's macros for PLL in include/linux/clk/at91_pmc.h
> 
> Thank you,
> Claudiu Beznea
> 
> Claudiu Beznea (8):
>   ARM: at91: pm: use proper master clock register offset
>   Revert "ARM: at91: pm: do not disable/enable PLLA for ULP modes"
>   ARM: at91: pm: add macros for plla disable/enable
>   ARM: at91: pm: add pmc_version member to at91_pm_data
>   ARM: at91: pm: s/sfr/sfrbu in pm_suspend.S
>   clk: at91: move sam9x60's PLL register offsets to PMC header
>   ARM: at91: pm: add plla disable/enable support for sam9x60
>   ARM: at91: pm: add quirk for sam9x60's ulp1
> 
>  arch/arm/mach-at91/pm.c              |  35 ++++++-
>  arch/arm/mach-at91/pm.h              |   2 +
>  arch/arm/mach-at91/pm_data-offsets.c |   4 +
>  arch/arm/mach-at91/pm_suspend.S      | 189 ++++++++++++++++++++++++++++++++---
>  drivers/clk/at91/clk-sam9x60-pll.c   |  91 +++++++----------
>  include/linux/clk/at91_pmc.h         |  23 +++++
>  6 files changed, 270 insertions(+), 74 deletions(-)
> 
Applied, thanks.

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, back to index

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-20 12:10 [PATCH 0/8] PM fixes and improvements for SAM9X60 Claudiu Beznea
2020-01-20 12:10 ` [PATCH 1/8] ARM: at91: pm: use proper master clock register offset Claudiu Beznea
2020-01-20 12:10 ` [PATCH 2/8] Revert "ARM: at91: pm: do not disable/enable PLLA for ULP modes" Claudiu Beznea
2020-01-20 12:10 ` [PATCH 3/8] ARM: at91: pm: add macros for plla disable/enable Claudiu Beznea
2020-01-20 12:10 ` [PATCH 4/8] ARM: at91: pm: add pmc_version member to at91_pm_data Claudiu Beznea
2020-02-12 23:30   ` Stephen Boyd
2020-01-20 12:10 ` [PATCH 5/8] ARM: at91: pm: s/sfr/sfrbu in pm_suspend.S Claudiu Beznea
2020-01-20 12:10 ` [PATCH 6/8] clk: at91: move sam9x60's PLL register offsets to PMC header Claudiu Beznea
2020-02-12 23:31   ` Stephen Boyd
2020-01-20 12:10 ` [PATCH 7/8] ARM: at91: pm: add plla disable/enable support for sam9x60 Claudiu Beznea
2020-01-20 12:10 ` [PATCH 8/8] ARM: at91: pm: add quirk for sam9x60's ulp1 Claudiu Beznea
2020-02-14 11:04 ` [PATCH 0/8] PM fixes and improvements for SAM9X60 Alexandre Belloni

Linux-Clk Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-clk/0 linux-clk/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-clk linux-clk/ https://lore.kernel.org/linux-clk \
		linux-clk@vger.kernel.org
	public-inbox-index linux-clk

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-clk


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git