ARM: at91: pm: use proper master clock register offset
authorClaudiu Beznea <claudiu.beznea@microchip.com>
Mon, 20 Jan 2020 12:10:01 +0000 (14:10 +0200)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Tue, 18 Feb 2020 20:47:31 +0000 (21:47 +0100)
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: 01c7031cfa73 ("ARM: at91: pm: initial PM support for SAM9X60")
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/1579522208-19523-2-git-send-email-claudiu.beznea@microchip.com
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm.h
arch/arm/mach-at91/pm_data-offsets.c
arch/arm/mach-at91/pm_suspend.S

index 374b9d1..ae7b148 100644 (file)
@@ -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;
index 9fa4f48..6f7f423 100644 (file)
@@ -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
 
index f2d893c..dfcbe62 100644 (file)
@@ -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;
 }
index ed57c87..52b262d 100644 (file)
@@ -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: