On Tue, Feb 07, 2023 at 01:21:53AM +0800, Karny, Wyes wrote: > For some AMD shared memory based systems, the autonomous selection bit > needed to be set explicitly. Add autonomous selection register related > APIs to acpi driver, which amd_pstate driver uses later. > > Signed-off-by: Wyes Karny <wyes.karny@xxxxxxx> > Reviewed-by: Mario Limonciello <mario.limonciello@xxxxxxx> > --- > drivers/acpi/cppc_acpi.c | 97 ++++++++++++++++++++++++++++++++++++++++ > include/acpi/cppc_acpi.h | 11 +++++ > 2 files changed, 108 insertions(+) > > diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c > index 91f9ef75f7de..1806006a51af 100644 > --- a/drivers/acpi/cppc_acpi.c > +++ b/drivers/acpi/cppc_acpi.c > @@ -1432,6 +1432,103 @@ int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable) > } > EXPORT_SYMBOL_GPL(cppc_set_epp_perf); > > +/* > + * cppc_get_auto_sel_caps - Read autonomous selection register. > + * @cpunum : CPU from which to read register. > + * @perf_caps : struct where autonomous selection register value is updated. > + */ > +int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps) > +{ > + struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); > + struct cpc_register_resource *auto_sel_reg; > + u64 auto_sel; > + > + if (!cpc_desc) { > + pr_debug("No CPC descriptor for CPU:%d\n", cpunum); > + return -ENODEV; > + } > + > + auto_sel_reg = &cpc_desc->cpc_regs[AUTO_SEL_ENABLE]; > + > + if (!CPC_SUPPORTED(auto_sel_reg)) > + pr_warn_once("Autonomous mode is not unsupported!\n"); > + > + if (CPC_IN_PCC(auto_sel_reg)) { > + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); > + struct cppc_pcc_data *pcc_ss_data = NULL; > + int ret = 0; > + > + if (pcc_ss_id < 0) > + return -ENODEV; > + > + pcc_ss_data = pcc_data[pcc_ss_id]; > + > + down_write(&pcc_ss_data->pcc_lock); > + > + if (send_pcc_cmd(pcc_ss_id, CMD_READ) >= 0) { > + cpc_read(cpunum, auto_sel_reg, &auto_sel); > + perf_caps->auto_sel = (bool)auto_sel; > + } else { > + ret = -EIO; > + } > + > + up_write(&pcc_ss_data->pcc_lock); > + > + return ret; > + } > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(cppc_get_auto_sel_caps); > + > +/* > + * cppc_set_auto_sel - Write autonomous selection register. > + * @cpunum : CPU to which to write register. @cpu or you can align the name with above function as cpunum. > + * @enable : the desired value of autonomous selection resiter to be updated. > + */ > +int cppc_set_auto_sel(int cpu, bool enable) With above fixed, patch is Acked-by: Huang Rui <ray.huang@xxxxxxx> > +{ > + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); > + struct cpc_register_resource *auto_sel_reg; > + struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); > + struct cppc_pcc_data *pcc_ss_data = NULL; > + int ret = -EINVAL; > + > + if (!cpc_desc) { > + pr_debug("No CPC descriptor for CPU:%d\n", cpu); > + return -ENODEV; > + } > + > + auto_sel_reg = &cpc_desc->cpc_regs[AUTO_SEL_ENABLE]; > + > + if (CPC_IN_PCC(auto_sel_reg)) { > + if (pcc_ss_id < 0) { > + pr_debug("Invalid pcc_ss_id\n"); > + return -ENODEV; > + } > + > + if (CPC_SUPPORTED(auto_sel_reg)) { > + ret = cpc_write(cpu, auto_sel_reg, enable); > + if (ret) > + return ret; > + } > + > + pcc_ss_data = pcc_data[pcc_ss_id]; > + > + down_write(&pcc_ss_data->pcc_lock); > + /* after writing CPC, transfer the ownership of PCC to platform */ > + ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE); > + up_write(&pcc_ss_data->pcc_lock); > + } else { > + ret = -ENOTSUPP; > + pr_debug("_CPC in PCC is not supported\n"); > + } > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(cppc_set_auto_sel); > + > + > /** > * cppc_set_enable - Set to enable CPPC on the processor by writing the > * Continuous Performance Control package EnableRegister field. > diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h > index 6b487a5bd638..6126c977ece0 100644 > --- a/include/acpi/cppc_acpi.h > +++ b/include/acpi/cppc_acpi.h > @@ -109,6 +109,7 @@ struct cppc_perf_caps { > u32 lowest_freq; > u32 nominal_freq; > u32 energy_perf; > + bool auto_sel; > }; > > struct cppc_perf_ctrls { > @@ -153,6 +154,8 @@ extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val); > extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val); > extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf); > extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable); > +extern int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps); > +extern int cppc_set_auto_sel(int cpu, bool enable); > #else /* !CONFIG_ACPI_CPPC_LIB */ > static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf) > { > @@ -214,6 +217,14 @@ static inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf) > { > return -ENOTSUPP; > } > +static inline int cppc_set_auto_sel(int cpu, bool enable) > +{ > + return -ENOTSUPP; > +} > +static inline int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps) > +{ > + return -ENOTSUPP; > +} > #endif /* !CONFIG_ACPI_CPPC_LIB */ > > #endif /* _CPPC_ACPI_H*/ > -- > 2.34.1 >