lib: utils/irqchip: plic: Common PM save/restore

Move the PLIC save/restore functions inside the driver, so they can be
reused on any platform that needs them. The memory needed to store the
PLIC context is also allocated by the driver. The PM data cannot be
completely encapsulated, as some platforms (including Allwinner D1) need
to program the IRQ enable status to a sideband interrupt controller for
wakeup capability.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Samuel Holland
2024-11-04 20:10:05 -08:00
committed by Anup Patel
parent 69448a0790
commit c6c22f00f4
5 changed files with 114 additions and 131 deletions

View File

@@ -60,31 +60,6 @@ static void sun20i_d1_csr_restore(void)
csr_write(THEAD_C9XX_CSR_MHINT, csr_mhint);
}
/*
* PLIC
*/
#define PLIC_SOURCES 175
#define PLIC_IE_WORDS (PLIC_SOURCES / 32 + 1)
static u8 plic_priority[1 + PLIC_SOURCES];
static u32 plic_sie[PLIC_IE_WORDS];
static u32 plic_threshold;
static void sun20i_d1_plic_save(void)
{
fdt_plic_context_save(true, plic_sie, &plic_threshold, PLIC_IE_WORDS);
fdt_plic_priority_save(plic_priority, PLIC_SOURCES);
}
static void sun20i_d1_plic_restore(void)
{
thead_plic_restore();
fdt_plic_priority_restore(plic_priority, PLIC_SOURCES);
fdt_plic_context_restore(true, plic_sie, plic_threshold,
PLIC_IE_WORDS);
}
/*
* PPU
*/
@@ -117,6 +92,9 @@ static void sun20i_d1_ppu_restore(void)
static void sun20i_d1_riscv_cfg_save(void)
{
struct plic_data *plic = fdt_plic_get();
u32 *plic_sie = plic->pm_data;
/* Enable MMIO access. Do not assume S-mode leaves the clock enabled. */
writel_relaxed(CCU_BGR_ENABLE, SUN20I_D1_CCU_BASE + RISCV_CFG_BGR_REG);
@@ -126,7 +104,7 @@ static void sun20i_d1_riscv_cfg_save(void)
* the wakeup mask registers (the offset is for GIC compatibility). So
* copying SIE to the wakeup mask needs some bit manipulation.
*/
for (int i = 0; i < PLIC_IE_WORDS - 1; i++)
for (int i = 0; i < PLIC_IE_WORDS(plic) - 1; i++)
writel_relaxed(plic_sie[i] >> 16 | plic_sie[i + 1] << 16,
SUN20I_D1_RISCV_CFG_BASE + WAKEUP_MASK_REG(i));
@@ -158,7 +136,7 @@ static int sun20i_d1_hart_suspend(u32 suspend_type)
if (!(suspend_type & SBI_HSM_SUSP_NON_RET_BIT))
return SBI_ENOTSUPP;
sun20i_d1_plic_save();
fdt_plic_suspend();
sun20i_d1_ppu_save();
sun20i_d1_riscv_cfg_save();
sun20i_d1_csr_save();
@@ -178,7 +156,7 @@ static void sun20i_d1_hart_resume(void)
sun20i_d1_csr_restore();
sun20i_d1_riscv_cfg_restore();
sun20i_d1_ppu_restore();
sun20i_d1_plic_restore();
fdt_plic_resume();
}
static const struct sbi_hsm_device sun20i_d1_ppu = {