Huacai Chen | 366bb35 | 2022-12-10 22:40:15 +0800 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* |
| 3 | * loongson-specific suspend support |
| 4 | * |
| 5 | * Author: Huacai Chen <chenhuacai@loongson.cn> |
| 6 | * Copyright (C) 2020-2022 Loongson Technology Corporation Limited |
| 7 | */ |
| 8 | #include <linux/acpi.h> |
| 9 | #include <linux/pm.h> |
| 10 | #include <linux/suspend.h> |
| 11 | |
| 12 | #include <asm/loongarch.h> |
| 13 | #include <asm/loongson.h> |
| 14 | #include <asm/setup.h> |
| 15 | #include <asm/time.h> |
| 16 | #include <asm/tlbflush.h> |
| 17 | |
| 18 | u64 loongarch_suspend_addr; |
| 19 | |
| 20 | struct saved_registers { |
| 21 | u32 ecfg; |
| 22 | u32 euen; |
| 23 | u64 pgd; |
| 24 | u64 kpgd; |
| 25 | u32 pwctl0; |
| 26 | u32 pwctl1; |
Tiezhu Yang | 5685d7f | 2024-05-14 12:24:18 +0800 | [diff] [blame] | 27 | u64 pcpu_base; |
Huacai Chen | 366bb35 | 2022-12-10 22:40:15 +0800 | [diff] [blame] | 28 | }; |
| 29 | static struct saved_registers saved_regs; |
| 30 | |
Yinbo Zhu | 31f1a8b | 2023-06-29 20:58:44 +0800 | [diff] [blame] | 31 | void loongarch_common_suspend(void) |
Huacai Chen | 366bb35 | 2022-12-10 22:40:15 +0800 | [diff] [blame] | 32 | { |
| 33 | save_counter(); |
| 34 | saved_regs.pgd = csr_read64(LOONGARCH_CSR_PGDL); |
| 35 | saved_regs.kpgd = csr_read64(LOONGARCH_CSR_PGDH); |
| 36 | saved_regs.pwctl0 = csr_read32(LOONGARCH_CSR_PWCTL0); |
| 37 | saved_regs.pwctl1 = csr_read32(LOONGARCH_CSR_PWCTL1); |
| 38 | saved_regs.ecfg = csr_read32(LOONGARCH_CSR_ECFG); |
| 39 | saved_regs.euen = csr_read32(LOONGARCH_CSR_EUEN); |
Tiezhu Yang | 5685d7f | 2024-05-14 12:24:18 +0800 | [diff] [blame] | 40 | saved_regs.pcpu_base = csr_read64(PERCPU_BASE_KS); |
Huacai Chen | 366bb35 | 2022-12-10 22:40:15 +0800 | [diff] [blame] | 41 | |
| 42 | loongarch_suspend_addr = loongson_sysconf.suspend_addr; |
| 43 | } |
| 44 | |
Yinbo Zhu | 31f1a8b | 2023-06-29 20:58:44 +0800 | [diff] [blame] | 45 | void loongarch_common_resume(void) |
Huacai Chen | 366bb35 | 2022-12-10 22:40:15 +0800 | [diff] [blame] | 46 | { |
| 47 | sync_counter(); |
| 48 | local_flush_tlb_all(); |
Huacai Chen | 366bb35 | 2022-12-10 22:40:15 +0800 | [diff] [blame] | 49 | csr_write64(eentry, LOONGARCH_CSR_EENTRY); |
| 50 | csr_write64(eentry, LOONGARCH_CSR_MERRENTRY); |
| 51 | csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY); |
| 52 | |
| 53 | csr_write64(saved_regs.pgd, LOONGARCH_CSR_PGDL); |
| 54 | csr_write64(saved_regs.kpgd, LOONGARCH_CSR_PGDH); |
| 55 | csr_write32(saved_regs.pwctl0, LOONGARCH_CSR_PWCTL0); |
| 56 | csr_write32(saved_regs.pwctl1, LOONGARCH_CSR_PWCTL1); |
| 57 | csr_write32(saved_regs.ecfg, LOONGARCH_CSR_ECFG); |
| 58 | csr_write32(saved_regs.euen, LOONGARCH_CSR_EUEN); |
Tiezhu Yang | 5685d7f | 2024-05-14 12:24:18 +0800 | [diff] [blame] | 59 | csr_write64(saved_regs.pcpu_base, PERCPU_BASE_KS); |
Huacai Chen | 366bb35 | 2022-12-10 22:40:15 +0800 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | int loongarch_acpi_suspend(void) |
| 63 | { |
| 64 | enable_gpe_wakeup(); |
| 65 | enable_pci_wakeup(); |
| 66 | |
Yinbo Zhu | 31f1a8b | 2023-06-29 20:58:44 +0800 | [diff] [blame] | 67 | loongarch_common_suspend(); |
Huacai Chen | 366bb35 | 2022-12-10 22:40:15 +0800 | [diff] [blame] | 68 | |
| 69 | /* processor specific suspend */ |
| 70 | loongarch_suspend_enter(); |
| 71 | |
Yinbo Zhu | 31f1a8b | 2023-06-29 20:58:44 +0800 | [diff] [blame] | 72 | loongarch_common_resume(); |
Huacai Chen | 366bb35 | 2022-12-10 22:40:15 +0800 | [diff] [blame] | 73 | |
| 74 | return 0; |
| 75 | } |