diff options
author | Arnd Bergmann <arnd@arndb.de> | 2025-03-20 00:34:01 +0300 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2025-03-20 00:34:02 +0300 |
commit | 911a44cf6ddcb809ef5a5e0345986285a62ef462 (patch) | |
tree | 4d24655b2e541eb24003c36ef34b027ac7385d2e | |
parent | f7b352eb9575fb66cc8c90f25575ed6766d9737a (diff) | |
parent | 8bd10f002411c9ea947edc0af18ad81f789e28d5 (diff) | |
download | linux-911a44cf6ddcb809ef5a5e0345986285a62ef462.tar.xz |
Merge tag 'at91-soc-6.15' of https://git.kernel.org/pub/scm/linux/kernel/git/at91/linux into soc/arm
Microchip AT91 SoC updates for v6.15
This update includes:
- SoC driver support for Microchip SAMA7D65
- power management support for Microchip SAMA7D65
- power management fixes
- documentation fixes
* tag 'at91-soc-6.15' of https://git.kernel.org/pub/scm/linux/kernel/git/at91/linux:
ARM: at91: pm: Enable ULP0/ULP1 for SAMA7D65
ARM: at91: pm: Add Backup mode for SAMA7D65
ARM: at91: pm: add DT compatible support for sama7d65
ARM: at91: pm: fix at91_suspend_finish for ZQ calibration
dt-bindings: ARM: at91: add Calao USB boards
dt-bindings: ARM: at91: make separate entry for Olimex board
ARM: at91: Add Support in SoC driver for SAMA7D65
dt-bindings: atmel-sysreg: Add SAMA7D65 Chip ID
Link: https://lore.kernel.org/r/20250312173755.975074-2-claudiu.beznea@tuxon.dev
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r-- | Documentation/devicetree/bindings/arm/atmel-at91.yaml | 33 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/arm/atmel-sysregs.txt | 1 | ||||
-rw-r--r-- | arch/arm/mach-at91/pm.c | 47 | ||||
-rw-r--r-- | arch/arm/mach-at91/pm.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-at91/pm_data-offsets.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/pm_suspend.S | 101 | ||||
-rw-r--r-- | drivers/soc/atmel/soc.c | 5 | ||||
-rw-r--r-- | drivers/soc/atmel/soc.h | 3 |
8 files changed, 168 insertions, 25 deletions
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml index 0ec29366e6c2..3a34b7a2e8d4 100644 --- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml +++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml @@ -23,8 +23,6 @@ properties: - const: atmel,at91rm9200 - items: - enum: - - olimex,sam9-l9260 - - enum: - atmel,at91sam9260 - atmel,at91sam9261 - atmel,at91sam9263 @@ -36,6 +34,37 @@ properties: - atmel,at91sam9x60 - const: atmel,at91sam9 + - description: Olimex SAM9-L9260 + items: + - const: olimex,sam9-l9260 + - const: atmel,at91sam9260 + - const: atmel,at91sam9 + + - description: Calao USB A9260 + items: + - const: calao,usb-a9260 + - const: atmel,at91sam9260 + - const: atmel,at91sam9 + + - description: Calao USB A9263 + items: + - const: calao,usb-a9263 + - const: atmel,at91sam9263 + - const: atmel,at91sam9 + + - description: Calao USB A9G20 + items: + - const: calao,usb-a9g20 + - const: atmel,at91sam9g20 + - const: atmel,at91sam9 + + - description: Calao USB A9G20-LPW + items: + - const: calao,usb-a9g20-lpw + - const: calao,usb-a9g20 + - const: atmel,at91sam9g20 + - const: atmel,at91sam9 + - items: - enum: - overkiz,kizboxmini-base # Overkiz kizbox Mini Base Board diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt index 1a173e92bb13..d3821f651e72 100644 --- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt +++ b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt @@ -2,6 +2,7 @@ Atmel system registers Chipid required properties: - compatible: Should be "atmel,sama5d2-chipid" or "microchip,sama7g5-chipid" + "microchip,sama7d65-chipid" - reg : Should contain registers location and length PIT Timer required properties: diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 05a1547642b6..3aa20038ad93 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -222,13 +222,16 @@ static const struct of_device_id sam9x60_ws_ids[] = { { /* sentinel */ } }; -static const struct of_device_id sama7g5_ws_ids[] = { +static const struct of_device_id sama7_ws_ids[] = { + { .compatible = "microchip,sama7d65-rtc", .data = &ws_info[1] }, { .compatible = "microchip,sama7g5-rtc", .data = &ws_info[1] }, { .compatible = "microchip,sama7g5-ohci", .data = &ws_info[2] }, { .compatible = "usb-ohci", .data = &ws_info[2] }, { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] }, { .compatible = "usb-ehci", .data = &ws_info[2] }, + { .compatible = "microchip,sama7d65-sdhci", .data = &ws_info[3] }, { .compatible = "microchip,sama7g5-sdhci", .data = &ws_info[3] }, + { .compatible = "microchip,sama7d65-rtt", .data = &ws_info[4] }, { .compatible = "microchip,sama7g5-rtt", .data = &ws_info[4] }, { /* sentinel */ } }; @@ -545,11 +548,12 @@ extern u32 at91_pm_suspend_in_sram_sz; static int at91_suspend_finish(unsigned long val) { - unsigned char modified_gray_code[] = { - 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05, 0x0c, 0x0d, - 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09, 0x18, 0x19, 0x1a, 0x1b, - 0x1e, 0x1f, 0x1c, 0x1d, 0x14, 0x15, 0x16, 0x17, 0x12, 0x13, - 0x10, 0x11, + /* SYNOPSYS workaround to fix a bug in the calibration logic */ + unsigned char modified_fix_code[] = { + 0x00, 0x01, 0x01, 0x06, 0x07, 0x0c, 0x06, 0x07, 0x0b, 0x18, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0d, 0x0a, 0x13, 0x13, 0x12, 0x13, + 0x14, 0x15, 0x15, 0x12, 0x18, 0x19, 0x19, 0x1e, 0x1f, 0x14, + 0x1e, 0x1f, }; unsigned int tmp, index; int i; @@ -560,25 +564,25 @@ static int at91_suspend_finish(unsigned long val) * restore the ZQ0SR0 with the value saved here. But the * calibration is buggy and restoring some values from ZQ0SR0 * is forbidden and risky thus we need to provide processed - * values for these (modified gray code values). + * values for these. */ tmp = readl(soc_pm.data.ramc_phy + DDR3PHY_ZQ0SR0); /* Store pull-down output impedance select. */ index = (tmp >> DDR3PHY_ZQ0SR0_PDO_OFF) & 0x1f; - soc_pm.bu->ddr_phy_calibration[0] = modified_gray_code[index]; + soc_pm.bu->ddr_phy_calibration[0] = modified_fix_code[index] << DDR3PHY_ZQ0SR0_PDO_OFF; /* Store pull-up output impedance select. */ index = (tmp >> DDR3PHY_ZQ0SR0_PUO_OFF) & 0x1f; - soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index]; + soc_pm.bu->ddr_phy_calibration[0] |= modified_fix_code[index] << DDR3PHY_ZQ0SR0_PUO_OFF; /* Store pull-down on-die termination impedance select. */ index = (tmp >> DDR3PHY_ZQ0SR0_PDODT_OFF) & 0x1f; - soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index]; + soc_pm.bu->ddr_phy_calibration[0] |= modified_fix_code[index] << DDR3PHY_ZQ0SR0_PDODT_OFF; /* Store pull-up on-die termination impedance select. */ index = (tmp >> DDR3PHY_ZQ0SRO_PUODT_OFF) & 0x1f; - soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index]; + soc_pm.bu->ddr_phy_calibration[0] |= modified_fix_code[index] << DDR3PHY_ZQ0SRO_PUODT_OFF; /* * The 1st 8 words of memory might get corrupted in the process @@ -643,6 +647,11 @@ static void at91_pm_suspend(suspend_state_t state) at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn, &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); + + if (IS_ENABLED(CONFIG_SOC_SAMA7D65)) { + /* SHDWC.SR */ + readl(soc_pm.data.shdwc + 0x08); + } } else { at91_suspend_finish(0); } @@ -1061,7 +1070,8 @@ static int __init at91_pm_backup_init(void) int ret = -ENODEV, located = 0; if (!IS_ENABLED(CONFIG_SOC_SAMA5D2) && - !IS_ENABLED(CONFIG_SOC_SAMA7G5)) + !IS_ENABLED(CONFIG_SOC_SAMA7G5) && + !IS_ENABLED(CONFIG_SOC_SAMA7D65)) return -EPERM; if (!at91_is_pm_mode_active(AT91_PM_BACKUP)) @@ -1329,6 +1339,7 @@ struct pmc_info { unsigned long uhp_udp_mask; unsigned long mckr; unsigned long version; + unsigned long mcks; }; static const struct pmc_info pmc_infos[] __initconst = { @@ -1360,8 +1371,14 @@ static const struct pmc_info pmc_infos[] __initconst = { { .mckr = 0x28, .version = AT91_PMC_V2, + .mcks = 4, + }, + { + .uhp_udp_mask = AT91SAM926x_PMC_UHP, + .mckr = 0x28, + .version = AT91_PMC_V2, + .mcks = 9, }, - }; static const struct of_device_id atmel_pmc_ids[] __initconst = { @@ -1378,6 +1395,7 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = { { .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] }, { .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] }, { .compatible = "microchip,sam9x7-pmc", .data = &pmc_infos[4] }, + { .compatible = "microchip,sama7d65-pmc", .data = &pmc_infos[6] }, { .compatible = "microchip,sama7g5-pmc", .data = &pmc_infos[5] }, { /* sentinel */ }, }; @@ -1448,6 +1466,7 @@ static void __init at91_pm_init(void (*pm_idle)(void)) soc_pm.data.uhp_udp_mask = pmc->uhp_udp_mask; soc_pm.data.pmc_mckr_offset = pmc->mckr; soc_pm.data.pmc_version = pmc->version; + soc_pm.data.pmc_mcks = pmc->mcks; if (pm_idle) arm_pm_idle = pm_idle; @@ -1671,7 +1690,7 @@ void __init sama7_pm_init(void) at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps)); at91_pm_init(NULL); - soc_pm.ws_ids = sama7g5_ws_ids; + soc_pm.ws_ids = sama7_ws_ids; soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws; soc_pm.sfrbu_regs.pswbu.key = (0x4BD20C << 8); diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 53bdc9000e44..50c3a425d140 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -39,6 +39,7 @@ struct at91_pm_data { unsigned int suspend_mode; unsigned int pmc_mckr_offset; unsigned int pmc_version; + unsigned int pmc_mcks; }; #endif diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c index 40bd4e8fe40a..0ca5da66dc26 100644 --- a/arch/arm/mach-at91/pm_data-offsets.c +++ b/arch/arm/mach-at91/pm_data-offsets.c @@ -18,6 +18,8 @@ int main(void) pmc_mckr_offset)); DEFINE(PM_DATA_PMC_VERSION, offsetof(struct at91_pm_data, pmc_version)); + DEFINE(PM_DATA_PMC_MCKS, offsetof(struct at91_pm_data, + pmc_mcks)); return 0; } diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index e5869cca5e79..e23b86834096 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -814,18 +814,20 @@ sr_dis_exit: .endm /** - * at91_mckx_ps_enable: save MCK1..4 settings and switch it to main clock + * at91_mckx_ps_enable: save MCK settings and switch it to main clock * - * Side effects: overwrites tmp1, tmp2 + * Side effects: overwrites tmp1, tmp2, tmp3 */ .macro at91_mckx_ps_enable #ifdef CONFIG_SOC_SAMA7 ldr pmc, .pmc_base + ldr tmp3, .mcks - /* There are 4 MCKs we need to handle: MCK1..4 */ + /* Start at MCK1 and go until MCKs */ mov tmp1, #1 -e_loop: cmp tmp1, #5 - beq e_done +e_loop: + cmp tmp1, tmp3 + bgt e_done /* Write MCK ID to retrieve the settings. */ str tmp1, [pmc, #AT91_PMC_MCR_V2] @@ -850,7 +852,37 @@ e_save_mck3: b e_ps e_save_mck4: + cmp tmp1, #4 + bne e_save_mck5 str tmp2, .saved_mck4 + b e_ps + +e_save_mck5: + cmp tmp1, #5 + bne e_save_mck6 + str tmp2, .saved_mck5 + b e_ps + +e_save_mck6: + cmp tmp1, #6 + bne e_save_mck7 + str tmp2, .saved_mck6 + b e_ps + +e_save_mck7: + cmp tmp1, #7 + bne e_save_mck8 + str tmp2, .saved_mck7 + b e_ps + +e_save_mck8: + cmp tmp1, #8 + bne e_save_mck9 + str tmp2, .saved_mck8 + b e_ps + +e_save_mck9: + str tmp2, .saved_mck9 e_ps: /* Use CSS=MAINCK and DIV=1. */ @@ -870,18 +902,20 @@ e_done: .endm /** - * at91_mckx_ps_restore: restore MCK1..4 settings + * at91_mckx_ps_restore: restore MCKx settings * * Side effects: overwrites tmp1, tmp2 */ .macro at91_mckx_ps_restore #ifdef CONFIG_SOC_SAMA7 ldr pmc, .pmc_base + ldr tmp2, .mcks - /* There are 4 MCKs we need to handle: MCK1..4 */ + /* Start from MCK1 and go up to MCKs */ mov tmp1, #1 -r_loop: cmp tmp1, #5 - beq r_done +r_loop: + cmp tmp1, tmp2 + bgt r_done r_save_mck1: cmp tmp1, #1 @@ -902,7 +936,37 @@ r_save_mck3: b r_ps r_save_mck4: + cmp tmp1, #4 + bne r_save_mck5 ldr tmp2, .saved_mck4 + b r_ps + +r_save_mck5: + cmp tmp1, #5 + bne r_save_mck6 + ldr tmp2, .saved_mck5 + b r_ps + +r_save_mck6: + cmp tmp1, #6 + bne r_save_mck7 + ldr tmp2, .saved_mck6 + b r_ps + +r_save_mck7: + cmp tmp1, #7 + bne r_save_mck8 + ldr tmp2, .saved_mck7 + b r_ps + +r_save_mck8: + cmp tmp1, #8 + bne r_save_mck9 + ldr tmp2, .saved_mck8 + b r_ps + +r_save_mck9: + ldr tmp2, .saved_mck9 r_ps: /* Write MCK ID to retrieve the settings. */ @@ -921,6 +985,7 @@ r_ps: wait_mckrdy tmp1 add tmp1, tmp1, #1 + ldr tmp2, .mcks b r_loop r_done: #endif @@ -1045,6 +1110,10 @@ ENTRY(at91_pm_suspend_in_sram) str tmp1, .memtype ldr tmp1, [r0, #PM_DATA_MODE] str tmp1, .pm_mode +#ifdef CONFIG_SOC_SAMA7 + ldr tmp1, [r0, #PM_DATA_PMC_MCKS] + str tmp1, .mcks +#endif /* * ldrne below are here to preload their address in the TLB as access @@ -1132,6 +1201,10 @@ ENDPROC(at91_pm_suspend_in_sram) .word 0 .pmc_version: .word 0 +#ifdef CONFIG_SOC_SAMA7 +.mcks: + .word 0 +#endif .saved_mckr: .word 0 .saved_pllar: @@ -1155,6 +1228,16 @@ ENDPROC(at91_pm_suspend_in_sram) .word 0 .saved_mck4: .word 0 +.saved_mck5: + .word 0 +.saved_mck6: + .word 0 +.saved_mck7: + .word 0 +.saved_mck8: + .word 0 +.saved_mck9: + .word 0 #endif ENTRY(at91_pm_suspend_in_sram_sz) diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index 298b542dd1c0..09347bccdb1d 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -246,6 +246,9 @@ static const struct at91_soc socs[] __initconst = { "samv70q19", "samv7"), #endif #ifdef CONFIG_SOC_SAMA7 + AT91_SOC(SAMA7D65_CIDR_MATCH, AT91_CIDR_MASK_SAMA7G5, + AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7D65_EXID_MATCH, + "sama7d65", "sama7d6"), AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G51_EXID_MATCH, "sama7g51", "sama7g5"), @@ -305,6 +308,7 @@ static int __init at91_get_cidr_exid_from_chipid(u32 *cidr, u32 *exid) void __iomem *regs; static const struct of_device_id chipids[] = { { .compatible = "atmel,sama5d2-chipid" }, + { .compatible = "microchip,sama7d65-chipid" }, { .compatible = "microchip,sama7g5-chipid" }, { }, }; @@ -393,6 +397,7 @@ static const struct of_device_id at91_soc_allowed_list[] __initconst = { { .compatible = "atmel,at91sam9", }, { .compatible = "atmel,sama5", }, { .compatible = "atmel,samv7", }, + { .compatible = "microchip,sama7d65", }, { .compatible = "microchip,sama7g5", }, { } }; diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h index 2c78e54255f7..66a74017d9a3 100644 --- a/drivers/soc/atmel/soc.h +++ b/drivers/soc/atmel/soc.h @@ -45,6 +45,7 @@ at91_soc_init(const struct at91_soc *socs); #define AT91SAM9N12_CIDR_MATCH 0x019a07a0 #define SAM9X60_CIDR_MATCH 0x019b35a0 #define SAM9X7_CIDR_MATCH 0x09750020 +#define SAMA7D65_CIDR_MATCH 0x00262100 #define SAMA7G5_CIDR_MATCH 0x00162100 #define AT91SAM9M11_EXID_MATCH 0x00000001 @@ -75,6 +76,8 @@ at91_soc_init(const struct at91_soc *socs); #define SAM9X75_D5M_EXID_MATCH 0x00000010 #define SAM9X75_EXID_MATCH 0x00000000 +#define SAMA7D65_EXID_MATCH 0x00000080 + #define SAMA7G51_EXID_MATCH 0x3 #define SAMA7G52_EXID_MATCH 0x2 #define SAMA7G53_EXID_MATCH 0x1 |