18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * loongson-specific suspend support 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Author: Huacai Chen <chenhuacai@loongson.cn> 68c2ecf20Sopenharmony_ci * Copyright (C) 2020 Loongson Technology Co., Ltd. 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci#include <linux/acpi.h> 98c2ecf20Sopenharmony_ci#include <linux/pm.h> 108c2ecf20Sopenharmony_ci#include <linux/suspend.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <asm/loongarchregs.h> 138c2ecf20Sopenharmony_ci#include <asm/setup.h> 148c2ecf20Sopenharmony_ci#include <asm/time.h> 158c2ecf20Sopenharmony_ci#include <asm/tlbflush.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <loongson.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ciu64 loongarch_suspend_addr; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistruct saved_registers { 228c2ecf20Sopenharmony_ci u32 ecfg; 238c2ecf20Sopenharmony_ci u32 euen; 248c2ecf20Sopenharmony_ci u64 pgd; 258c2ecf20Sopenharmony_ci u64 kpgd; 268c2ecf20Sopenharmony_ci u32 pwctl0; 278c2ecf20Sopenharmony_ci u32 pwctl1; 288c2ecf20Sopenharmony_ci}; 298c2ecf20Sopenharmony_cistatic struct saved_registers saved_regs; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistatic void arch_common_suspend(void) 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci save_counter(); 348c2ecf20Sopenharmony_ci saved_regs.pgd = csr_read64(LOONGARCH_CSR_PGDL); 358c2ecf20Sopenharmony_ci saved_regs.kpgd = csr_read64(LOONGARCH_CSR_PGDH); 368c2ecf20Sopenharmony_ci saved_regs.pwctl0 = csr_read32(LOONGARCH_CSR_PWCTL0); 378c2ecf20Sopenharmony_ci saved_regs.pwctl1 = csr_read32(LOONGARCH_CSR_PWCTL1); 388c2ecf20Sopenharmony_ci saved_regs.ecfg = csr_read32(LOONGARCH_CSR_ECFG); 398c2ecf20Sopenharmony_ci saved_regs.euen = csr_read32(LOONGARCH_CSR_EUEN); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci loongarch_suspend_addr = loongson_sysconf.suspend_addr; 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic void arch_common_resume(void) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci sync_counter(); 478c2ecf20Sopenharmony_ci local_flush_tlb_all(); 488c2ecf20Sopenharmony_ci csr_write64(per_cpu_offset(0), PERCPU_BASE_KS); 498c2ecf20Sopenharmony_ci csr_write64(eentry, LOONGARCH_CSR_EENTRY); 508c2ecf20Sopenharmony_ci csr_write64(eentry, LOONGARCH_CSR_MERRENTRY); 518c2ecf20Sopenharmony_ci csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci csr_write64(saved_regs.pgd, LOONGARCH_CSR_PGDL); 548c2ecf20Sopenharmony_ci csr_write64(saved_regs.kpgd, LOONGARCH_CSR_PGDH); 558c2ecf20Sopenharmony_ci csr_write32(saved_regs.pwctl0, LOONGARCH_CSR_PWCTL0); 568c2ecf20Sopenharmony_ci csr_write32(saved_regs.pwctl1, LOONGARCH_CSR_PWCTL1); 578c2ecf20Sopenharmony_ci csr_write32(saved_regs.ecfg, LOONGARCH_CSR_ECFG); 588c2ecf20Sopenharmony_ci csr_write32(saved_regs.euen, LOONGARCH_CSR_EUEN); 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ciint loongarch_acpi_suspend(void) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci enable_gpe_wakeup(); 648c2ecf20Sopenharmony_ci enable_pci_wakeup(); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci arch_common_suspend(); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci /* processor specific suspend */ 698c2ecf20Sopenharmony_ci loongarch_suspend_enter(); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci arch_common_resume(); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci return 0; 748c2ecf20Sopenharmony_ci} 75