aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch
diff options
context:
space:
mode:
authorClaudiu Beznea <claudiu.beznea@microchip.com>2022-02-04 15:57:50 +0200
committerPetr Štetiar <ynezz@true.cz>2022-02-24 19:05:28 +0100
commite58cd453d58b20c6a6f34d3591640aa19aa14d25 (patch)
treea4fef5f5d79575a7a60b516482ee114c1dbc932e /target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch
parent3ed992a99630457f660761ce199e3d2a00f06168 (diff)
downloadupstream-e58cd453d58b20c6a6f34d3591640aa19aa14d25.tar.gz
upstream-e58cd453d58b20c6a6f34d3591640aa19aa14d25.tar.bz2
upstream-e58cd453d58b20c6a6f34d3591640aa19aa14d25.zip
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 <claudiu.beznea@microchip.com>
Diffstat (limited to 'target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch')
-rw-r--r--target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch283
1 files changed, 283 insertions, 0 deletions
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 <claudiu.beznea@microchip.com>
+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 <claudiu.beznea@microchip.com>
+Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
+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 <linux/mfd/syscon/atmel-mc.h>
+ #include <soc/at91/at91sam9_ddrsdr.h>
+ #include <soc/at91/at91sam9_sdramc.h>
++#include <soc/at91/sama7-ddr.h>
+
+ #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
+