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

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
...@@ -736,13 +736,30 @@ static void __init at91_pm_modes_init(void) ...@@ -736,13 +736,30 @@ static void __init at91_pm_modes_init(void)
struct pmc_info { struct pmc_info {
unsigned long uhp_udp_mask; unsigned long uhp_udp_mask;
unsigned long mckr;
}; };
static const struct pmc_info pmc_infos[] __initconst = { 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 = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP,
{ .uhp_udp_mask = AT91SAM926x_PMC_UHP }, .mckr = 0x30,
{ .uhp_udp_mask = 0 }, },
{
.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 = { static const struct of_device_id atmel_pmc_ids[] __initconst = {
...@@ -757,7 +774,7 @@ 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,sama5d3-pmc", .data = &pmc_infos[1] },
{ .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] }, { .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
{ .compatible = "atmel,sama5d2-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 */ }, { /* sentinel */ },
}; };
...@@ -779,6 +796,7 @@ static void __init at91_pm_init(void (*pm_idle)(void)) ...@@ -779,6 +796,7 @@ static void __init at91_pm_init(void (*pm_idle)(void))
pmc = of_id->data; pmc = of_id->data;
soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask; soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask;
soc_pm.data.pmc_mckr_offset = pmc->mckr;
if (pm_idle) if (pm_idle)
arm_pm_idle = pm_idle; arm_pm_idle = pm_idle;
......
...@@ -33,6 +33,7 @@ struct at91_pm_data { ...@@ -33,6 +33,7 @@ struct at91_pm_data {
void __iomem *sfrbu; void __iomem *sfrbu;
unsigned int standby_mode; unsigned int standby_mode;
unsigned int suspend_mode; unsigned int suspend_mode;
unsigned int pmc_mckr_offset;
}; };
#endif #endif
......
...@@ -12,6 +12,8 @@ int main(void) ...@@ -12,6 +12,8 @@ int main(void)
DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode));
DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc)); DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc));
DEFINE(PM_DATA_SFRBU, offsetof(struct at91_pm_data, sfrbu)); 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; return 0;
} }
...@@ -93,6 +93,8 @@ ENTRY(at91_pm_suspend_in_sram) ...@@ -93,6 +93,8 @@ ENTRY(at91_pm_suspend_in_sram)
str tmp1, .memtype str tmp1, .memtype
ldr tmp1, [r0, #PM_DATA_MODE] ldr tmp1, [r0, #PM_DATA_MODE]
str tmp1, .pm_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 */ /* Both ldrne below are here to preload their address in the TLB */
ldr tmp1, [r0, #PM_DATA_SHDWC] ldr tmp1, [r0, #PM_DATA_SHDWC]
str tmp1, .shdwc str tmp1, .shdwc
...@@ -138,9 +140,10 @@ ENDPROC(at91_pm_suspend_in_sram) ...@@ -138,9 +140,10 @@ ENDPROC(at91_pm_suspend_in_sram)
ENTRY(at91_backup_mode) ENTRY(at91_backup_mode)
/* Switch the master clock source to slow clock. */ /* Switch the master clock source to slow clock. */
ldr pmc, .pmc_base ldr pmc, .pmc_base
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp2, .mckr_offset
ldr tmp1, [pmc, tmp2]
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
...@@ -218,6 +221,7 @@ ENDPROC(at91_backup_mode) ...@@ -218,6 +221,7 @@ ENDPROC(at91_backup_mode)
*/ */
.macro at91_pm_ulp1_mode .macro at91_pm_ulp1_mode
ldr pmc, .pmc_base ldr pmc, .pmc_base
ldr tmp2, .mckr_offset
/* Save RC oscillator state and check if it is enabled. */ /* Save RC oscillator state and check if it is enabled. */
ldr tmp1, [pmc, #AT91_PMC_SR] ldr tmp1, [pmc, #AT91_PMC_SR]
...@@ -254,10 +258,10 @@ ENDPROC(at91_backup_mode) ...@@ -254,10 +258,10 @@ ENDPROC(at91_backup_mode)
str tmp1, [pmc, #AT91_CKGR_MOR] str tmp1, [pmc, #AT91_CKGR_MOR]
/* Switch the master clock source to main clock */ /* Switch the master clock source to main clock */
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp1, [pmc, tmp2]
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
...@@ -280,9 +284,9 @@ ENDPROC(at91_backup_mode) ...@@ -280,9 +284,9 @@ ENDPROC(at91_backup_mode)
wait_moscrdy wait_moscrdy
/* Switch the master clock source to slow clock */ /* Switch the master clock source to slow clock */
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp1, [pmc, tmp2]
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
...@@ -296,10 +300,10 @@ ENDPROC(at91_backup_mode) ...@@ -296,10 +300,10 @@ ENDPROC(at91_backup_mode)
wait_moscsels wait_moscsels
/* Switch the master clock source to main clock */ /* Switch the master clock source to main clock */
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp1, [pmc, tmp2]
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
orr tmp1, tmp1, #AT91_PMC_CSS_MAIN orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
...@@ -325,16 +329,17 @@ ENDPROC(at91_backup_mode) ...@@ -325,16 +329,17 @@ ENDPROC(at91_backup_mode)
ENTRY(at91_ulp_mode) ENTRY(at91_ulp_mode)
ldr pmc, .pmc_base ldr pmc, .pmc_base
ldr tmp2, .mckr_offset
/* Save Master clock setting */ /* Save Master clock setting */
ldr tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp1, [pmc, tmp2]
str tmp1, .saved_mckr str tmp1, .saved_mckr
/* /*
* Set the Master clock source to slow clock * Set the Master clock source to slow clock
*/ */
bic tmp1, tmp1, #AT91_PMC_CSS bic tmp1, tmp1, #AT91_PMC_CSS
str tmp1, [pmc, #AT91_PMC_MCKR] str tmp1, [pmc, tmp2]
wait_mckrdy wait_mckrdy
...@@ -355,8 +360,9 @@ ulp_exit: ...@@ -355,8 +360,9 @@ ulp_exit:
/* /*
* Restore master clock setting * Restore master clock setting
*/ */
ldr tmp1, .saved_mckr ldr tmp1, .mckr_offset
str tmp1, [pmc, #AT91_PMC_MCKR] ldr tmp2, .saved_mckr
str tmp2, [pmc, tmp1]
wait_mckrdy wait_mckrdy
...@@ -502,6 +508,8 @@ ENDPROC(at91_sramc_self_refresh) ...@@ -502,6 +508,8 @@ ENDPROC(at91_sramc_self_refresh)
.word 0 .word 0
.pm_mode: .pm_mode:
.word 0 .word 0
.mckr_offset:
.word 0
.saved_mckr: .saved_mckr:
.word 0 .word 0
.saved_sam9_lpr: .saved_sam9_lpr:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment