diff options
Diffstat (limited to 'arch/arm/mach-at91/pm.c')
-rw-r--r-- | arch/arm/mach-at91/pm.c | 47 |
1 files changed, 33 insertions, 14 deletions
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); |