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

ARM: at91: pm: use proper master clock register offset



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: 01c7031c ("ARM: at91: pm: initial PM support for SAM9X60")
Signed-off-by: default avatarClaudiu Beznea <claudiu.beznea@microchip.com>
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/1579522208-19523-2-git-send-email-claudiu.beznea@microchip.com
parent e77a63a7
Loading
Loading
Loading
Loading
+23 −5
Original line number Diff line number Diff line
@@ -736,13 +736,30 @@ backup_default:

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;
+1 −0
Original line number Diff line number Diff line
@@ -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

+2 −0
Original line number Diff line number Diff line
@@ -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;
}
+20 −12
Original line number Diff line number Diff line
@@ -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: