-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable Low Power Idle (LPI) based cpuidle driver for RISC-V platforms. It depends on SBI HSM calls for idle state transitions. Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://lore.kernel.org/r/20240118062930.245937-3-sunilvl@ventanamicro.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
- Loading branch information
Sunil V L
authored and
Palmer Dabbelt
committed
Mar 20, 2024
1 parent
6649182
commit 4877fc9
Showing
2 changed files
with
83 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
obj-y += rhct.o | ||
obj-y += rhct.o | ||
obj-$(CONFIG_ACPI_PROCESSOR_IDLE) += cpuidle.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Copyright (C) 2024, Ventana Micro Systems Inc | ||
* Author: Sunil V L <sunilvl@ventanamicro.com> | ||
* | ||
*/ | ||
|
||
#include <linux/acpi.h> | ||
#include <acpi/processor.h> | ||
#include <linux/cpu_pm.h> | ||
#include <linux/cpuidle.h> | ||
#include <linux/suspend.h> | ||
#include <asm/cpuidle.h> | ||
#include <asm/sbi.h> | ||
#include <asm/suspend.h> | ||
|
||
#define RISCV_FFH_LPI_TYPE_MASK GENMASK_ULL(63, 60) | ||
#define RISCV_FFH_LPI_RSVD_MASK GENMASK_ULL(59, 32) | ||
|
||
#define RISCV_FFH_LPI_TYPE_SBI BIT_ULL(60) | ||
|
||
static int acpi_cpu_init_idle(unsigned int cpu) | ||
{ | ||
int i; | ||
struct acpi_lpi_state *lpi; | ||
struct acpi_processor *pr = per_cpu(processors, cpu); | ||
|
||
if (unlikely(!pr || !pr->flags.has_lpi)) | ||
return -EINVAL; | ||
|
||
if (!riscv_sbi_hsm_is_supported()) | ||
return -ENODEV; | ||
|
||
if (pr->power.count <= 1) | ||
return -ENODEV; | ||
|
||
for (i = 1; i < pr->power.count; i++) { | ||
u32 state; | ||
|
||
lpi = &pr->power.lpi_states[i]; | ||
|
||
/* | ||
* Validate Entry Method as per FFH spec. | ||
* bits[63:60] should be 0x1 | ||
* bits[59:32] should be 0x0 | ||
* bits[31:0] represent a SBI power_state | ||
*/ | ||
if (((lpi->address & RISCV_FFH_LPI_TYPE_MASK) != RISCV_FFH_LPI_TYPE_SBI) || | ||
(lpi->address & RISCV_FFH_LPI_RSVD_MASK)) { | ||
pr_warn("Invalid LPI entry method %#llx\n", lpi->address); | ||
return -EINVAL; | ||
} | ||
|
||
state = lpi->address; | ||
if (!riscv_sbi_suspend_state_is_valid(state)) { | ||
pr_warn("Invalid SBI power state %#x\n", state); | ||
return -EINVAL; | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int acpi_processor_ffh_lpi_probe(unsigned int cpu) | ||
{ | ||
return acpi_cpu_init_idle(cpu); | ||
} | ||
|
||
int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi) | ||
{ | ||
u32 state = lpi->address; | ||
|
||
if (state & SBI_HSM_SUSP_NON_RET_BIT) | ||
return CPU_PM_CPU_IDLE_ENTER_PARAM(riscv_sbi_hart_suspend, | ||
lpi->index, | ||
state); | ||
else | ||
return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(riscv_sbi_hart_suspend, | ||
lpi->index, | ||
state); | ||
} |