From e58cd453d58b20c6a6f34d3591640aa19aa14d25 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 4 Feb 2022 15:57:50 +0200 Subject: at91: add kernel support for sama7g5 soc Add kernel support for SAMA7G5 by back-porting mainline kernel patches. Among SAMA7G5 features could be remembered: - ARM Cortex-A7 - double data rate multi-port dynamic RAM controller supporting DDR2, DDR3, DDR3L, LPDDR2, LPDDR3 up to 533MHz - peripherals for audio, video processing - 1 gigabit + 1 megabit Ethernet controllers - 6 CAN controllers - trust zone support - DVFS for CPU - criptography IPs Signed-off-by: Claudiu Beznea --- ...1-pm-add-self-refresh-support-for-sama7g5.patch | 283 +++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch (limited to 'target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch') diff --git a/target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch b/target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch new file mode 100644 index 0000000000..344b14c4d9 --- /dev/null +++ b/target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch @@ -0,0 +1,283 @@ +From 1bfd85d71703f80392a71043caf74f159bec97b8 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea +Date: Thu, 15 Apr 2021 13:49:58 +0300 +Subject: [PATCH 208/247] ARM: at91: pm: add self-refresh support for sama7g5 + +Add self-refresh support for SAMA7G5. + +Signed-off-by: Claudiu Beznea +Signed-off-by: Nicolas Ferre +Link: https://lore.kernel.org/r/20210415105010.569620-13-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.h | 2 + + arch/arm/mach-at91/pm_data-offsets.c | 2 + + arch/arm/mach-at91/pm_suspend.S | 199 +++++++++++++++++++++++++++ + 3 files changed, 203 insertions(+) + +diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h +index bfb260be371e..666474088d55 100644 +--- a/arch/arm/mach-at91/pm.h ++++ b/arch/arm/mach-at91/pm.h +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #define AT91_MEMCTRL_MC 0 + #define AT91_MEMCTRL_SDRAMC 1 +@@ -27,6 +28,7 @@ + struct at91_pm_data { + void __iomem *pmc; + void __iomem *ramc[2]; ++ void __iomem *ramc_phy; + unsigned long uhp_udp_mask; + unsigned int memctrl; + unsigned int mode; +diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c +index 82089ff258c0..40bd4e8fe40a 100644 +--- a/arch/arm/mach-at91/pm_data-offsets.c ++++ b/arch/arm/mach-at91/pm_data-offsets.c +@@ -8,6 +8,8 @@ int main(void) + DEFINE(PM_DATA_PMC, offsetof(struct at91_pm_data, pmc)); + DEFINE(PM_DATA_RAMC0, offsetof(struct at91_pm_data, ramc[0])); + DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1])); ++ DEFINE(PM_DATA_RAMC_PHY, offsetof(struct at91_pm_data, ++ ramc_phy)); + DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl)); + DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); + DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc)); +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 7669b32d5257..84418120ba67 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -87,6 +87,200 @@ tmp3 .req r6 + + .arm + ++#ifdef CONFIG_SOC_SAMA7 ++/** ++ * Enable self-refresh ++ * ++ * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3, r7 ++ */ ++.macro at91_sramc_self_refresh_ena ++ ldr r2, .sramc_base ++ ldr r3, .sramc_phy_base ++ ldr r7, .pm_mode ++ ++ dsb ++ ++ /* Disable all AXI ports. */ ++ ldr tmp1, [r2, #UDDRC_PCTRL_0] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_0] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_1] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_1] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_2] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_2] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_3] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_3] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_4] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_4] ++ ++sr_ena_1: ++ /* Wait for all ports to disable. */ ++ ldr tmp1, [r2, #UDDRC_PSTAT] ++ ldr tmp2, =UDDRC_PSTAT_ALL_PORTS ++ tst tmp1, tmp2 ++ bne sr_ena_1 ++ ++ /* Switch to self-refresh. */ ++ ldr tmp1, [r2, #UDDRC_PWRCTL] ++ orr tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW ++ str tmp1, [r2, #UDDRC_PWRCTL] ++ ++sr_ena_2: ++ /* Wait for self-refresh enter. */ ++ ldr tmp1, [r2, #UDDRC_STAT] ++ bic tmp1, tmp1, #~UDDRC_STAT_SELFREF_TYPE_MSK ++ cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW ++ bne sr_ena_2 ++ ++ /* Put DDR PHY's DLL in bypass mode for non-backup modes. */ ++ cmp r7, #AT91_PM_BACKUP ++ beq sr_ena_3 ++ ldr tmp1, [r3, #DDR3PHY_PIR] ++ orr tmp1, tmp1, #DDR3PHY_PIR_DLLBYP ++ str tmp1, [r3, #DDR3PHY_PIR] ++ ++sr_ena_3: ++ /* Power down DDR PHY data receivers. */ ++ ldr tmp1, [r3, #DDR3PHY_DXCCR] ++ orr tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR ++ str tmp1, [r3, #DDR3PHY_DXCCR] ++ ++ /* Power down ADDR/CMD IO. */ ++ ldr tmp1, [r3, #DDR3PHY_ACIOCR] ++ orr tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD ++ orr tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0 ++ orr tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0 ++ str tmp1, [r3, #DDR3PHY_ACIOCR] ++ ++ /* Power down ODT. */ ++ ldr tmp1, [r3, #DDR3PHY_DSGCR] ++ orr tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0 ++ str tmp1, [r3, #DDR3PHY_DSGCR] ++.endm ++ ++/** ++ * Disable self-refresh ++ * ++ * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3 ++ */ ++.macro at91_sramc_self_refresh_dis ++ ldr r2, .sramc_base ++ ldr r3, .sramc_phy_base ++ ++ /* Power up DDR PHY data receivers. */ ++ ldr tmp1, [r3, #DDR3PHY_DXCCR] ++ bic tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR ++ str tmp1, [r3, #DDR3PHY_DXCCR] ++ ++ /* Power up the output of CK and CS pins. */ ++ ldr tmp1, [r3, #DDR3PHY_ACIOCR] ++ bic tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD ++ bic tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0 ++ bic tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0 ++ str tmp1, [r3, #DDR3PHY_ACIOCR] ++ ++ /* Power up ODT. */ ++ ldr tmp1, [r3, #DDR3PHY_DSGCR] ++ bic tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0 ++ str tmp1, [r3, #DDR3PHY_DSGCR] ++ ++ /* Take DDR PHY's DLL out of bypass mode. */ ++ ldr tmp1, [r3, #DDR3PHY_PIR] ++ bic tmp1, tmp1, #DDR3PHY_PIR_DLLBYP ++ str tmp1, [r3, #DDR3PHY_PIR] ++ ++ /* Enable quasi-dynamic programming. */ ++ mov tmp1, #0 ++ str tmp1, [r2, #UDDRC_SWCTRL] ++ ++ /* De-assert SDRAM initialization. */ ++ ldr tmp1, [r2, #UDDRC_DFIMISC] ++ bic tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN ++ str tmp1, [r2, #UDDRC_DFIMISC] ++ ++ /* Quasi-dynamic programming done. */ ++ mov tmp1, #UDDRC_SWCTRL_SW_DONE ++ str tmp1, [r2, #UDDRC_SWCTRL] ++ ++sr_dis_1: ++ ldr tmp1, [r2, #UDDRC_SWSTAT] ++ tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK ++ beq sr_dis_1 ++ ++ /* DLL soft-reset + DLL lock wait + ITM reset */ ++ mov tmp1, #(DDR3PHY_PIR_INIT | DDR3PHY_PIR_DLLSRST | \ ++ DDR3PHY_PIR_DLLLOCK | DDR3PHY_PIR_ITMSRST) ++ str tmp1, [r3, #DDR3PHY_PIR] ++ ++sr_dis_4: ++ /* Wait for it. */ ++ ldr tmp1, [r3, #DDR3PHY_PGSR] ++ tst tmp1, #DDR3PHY_PGSR_IDONE ++ beq sr_dis_4 ++ ++ /* Enable quasi-dynamic programming. */ ++ mov tmp1, #0 ++ str tmp1, [r2, #UDDRC_SWCTRL] ++ ++ /* Assert PHY init complete enable signal. */ ++ ldr tmp1, [r2, #UDDRC_DFIMISC] ++ orr tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN ++ str tmp1, [r2, #UDDRC_DFIMISC] ++ ++ /* Programming is done. Set sw_done. */ ++ mov tmp1, #UDDRC_SWCTRL_SW_DONE ++ str tmp1, [r2, #UDDRC_SWCTRL] ++ ++sr_dis_5: ++ /* Wait for it. */ ++ ldr tmp1, [r2, #UDDRC_SWSTAT] ++ tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK ++ beq sr_dis_5 ++ ++ /* Trigger self-refresh exit. */ ++ ldr tmp1, [r2, #UDDRC_PWRCTL] ++ bic tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW ++ str tmp1, [r2, #UDDRC_PWRCTL] ++ ++sr_dis_6: ++ /* Wait for self-refresh exit done. */ ++ ldr tmp1, [r2, #UDDRC_STAT] ++ bic tmp1, tmp1, #~UDDRC_STAT_OPMODE_MSK ++ cmp tmp1, #UDDRC_STAT_OPMODE_NORMAL ++ bne sr_dis_6 ++ ++ /* Enable all AXI ports. */ ++ ldr tmp1, [r2, #UDDRC_PCTRL_0] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_0] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_1] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_1] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_2] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_2] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_3] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_3] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_4] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_4] ++ ++ dsb ++.endm ++#else + /** + * Enable self-refresh + * +@@ -228,6 +422,7 @@ sdramc_exit_sf: + + sr_dis_exit: + .endm ++#endif + + .macro at91_pm_ulp0_mode + ldr pmc, .pmc_base +@@ -668,6 +863,8 @@ ENTRY(at91_pm_suspend_in_sram) + str tmp1, .sramc_base + ldr tmp1, [r0, #PM_DATA_RAMC1] + str tmp1, .sramc1_base ++ ldr tmp1, [r0, #PM_DATA_RAMC_PHY] ++ str tmp1, .sramc_phy_base + ldr tmp1, [r0, #PM_DATA_MEMCTRL] + str tmp1, .memtype + ldr tmp1, [r0, #PM_DATA_MODE] +@@ -721,6 +918,8 @@ ENDPROC(at91_pm_suspend_in_sram) + .word 0 + .sramc1_base: + .word 0 ++.sramc_phy_base: ++ .word 0 + .shdwc: + .word 0 + .sfrbu: +-- +2.32.0 + -- cgit v1.2.3