Skip to content

Commit 89ba739

Browse files
committed
[AArch64] Get the voltage core of CPUs from OPP
1 parent 43b96ae commit 89ba739

File tree

4 files changed

+304
-5
lines changed

4 files changed

+304
-5
lines changed

aarch64/corefreqd.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,50 @@ static void (*ComputeVoltage_None_Matrix[4])( struct FLIP_FLOP*,
158158
[FORMULA_SCOPE_PKG ] = ComputeVoltage_None_PerPkg
159159
};
160160

161+
static void ComputeVoltage_OPP( struct FLIP_FLOP *CFlip,
162+
RO(SHM_STRUCT) *RO(Shm),
163+
unsigned int cpu )
164+
{
165+
COMPUTE_VOLTAGE(OPP,
166+
CFlip->Voltage.Vcore,
167+
CFlip->Voltage.VID);
168+
169+
Core_ComputeVoltageLimits(&RO(Shm)->Cpu[cpu], CFlip);
170+
}
171+
172+
#define ComputeVoltage_OPP_PerSMT ComputeVoltage_OPP
173+
174+
static void ComputeVoltage_OPP_PerCore( struct FLIP_FLOP *CFlip,
175+
RO(SHM_STRUCT) *RO(Shm),
176+
unsigned int cpu )
177+
{
178+
if ((RO(Shm)->Cpu[cpu].Topology.ThreadID == 0)
179+
|| (RO(Shm)->Cpu[cpu].Topology.ThreadID == -1))
180+
{
181+
ComputeVoltage_OPP(CFlip, RO(Shm), cpu);
182+
}
183+
}
184+
185+
static void ComputeVoltage_OPP_PerPkg( struct FLIP_FLOP *CFlip,
186+
RO(SHM_STRUCT) *RO(Shm),
187+
unsigned int cpu )
188+
{
189+
if (cpu == RO(Shm)->Proc.Service.Core)
190+
{
191+
ComputeVoltage_OPP(CFlip, RO(Shm), cpu);
192+
}
193+
}
194+
195+
static void (*ComputeVoltage_OPP_Matrix[4])( struct FLIP_FLOP*,
196+
RO(SHM_STRUCT)*,
197+
unsigned int ) = \
198+
{
199+
[FORMULA_SCOPE_NONE] = ComputeVoltage_None,
200+
[FORMULA_SCOPE_SMT ] = ComputeVoltage_OPP_PerSMT,
201+
[FORMULA_SCOPE_CORE] = ComputeVoltage_OPP_PerCore,
202+
[FORMULA_SCOPE_PKG ] = ComputeVoltage_OPP_PerPkg
203+
};
204+
161205
void Core_ComputePowerLimits(CPU_STRUCT *Cpu, struct FLIP_FLOP *CFlip)
162206
{ /* Per Core, computes the Min CPU Energy consumed. */
163207
TEST_AND_SET_SENSOR( ENERGY, LOWEST, CFlip->State.Energy,
@@ -245,6 +289,9 @@ static void *Core_Cycle(void *arg)
245289
}
246290

247291
switch (KIND_OF_FORMULA(RO(Shm)->Proc.voltageFormula)) {
292+
case VOLTAGE_KIND_OPP:
293+
ComputeVoltageFormula = ComputeVoltage_OPP_Matrix;
294+
break;
248295
case VOLTAGE_KIND_NONE:
249296
default:
250297
ComputeVoltageFormula = ComputeVoltage_None_Matrix;
@@ -1520,6 +1567,13 @@ static void Pkg_ComputeVoltage_None(struct PKG_FLIP_FLOP *PFlip)
15201567
UNUSED(PFlip);
15211568
}
15221569

1570+
static void Pkg_ComputeVoltage_OPP(struct PKG_FLIP_FLOP *PFlip)
1571+
{
1572+
COMPUTE_VOLTAGE(OPP,
1573+
PFlip->Voltage.CPU,
1574+
PFlip->Voltage.VID.CPU);
1575+
}
1576+
15231577
static void Pkg_ComputePower_None(RW(PROC) *RW(Proc), struct FLIP_FLOP *CFlop)
15241578
{
15251579
UNUSED(RW(Proc));
@@ -1591,6 +1645,9 @@ REASON_CODE Core_Manager(REF *Ref)
15911645
}
15921646

15931647
switch (KIND_OF_FORMULA(RO(Shm)->Proc.voltageFormula)) {
1648+
case VOLTAGE_KIND_OPP:
1649+
Pkg_ComputeVoltageFormula = Pkg_ComputeVoltage_OPP;
1650+
break;
15941651
case VOLTAGE_KIND_NONE:
15951652
default:
15961653
Pkg_ComputeVoltageFormula = Pkg_ComputeVoltage_None;

aarch64/corefreqk.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
#ifdef CONFIG_CPU_FREQ
2626
#include <linux/cpufreq.h>
2727
#endif /* CONFIG_CPU_FREQ */
28+
#ifdef CONFIG_PM_OPP
29+
#include <linux/pm_opp.h>
30+
#endif /* CONFIG_PM_OPP */
2831
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
2932
#include <linux/sched/signal.h>
3033
#endif /* KERNEL_VERSION(4, 11, 0) */
@@ -2021,6 +2024,62 @@ static void Query_DeviceTree(unsigned int cpu)
20212024
Core->Boost[BOOST(TGT)] = cur_freq / UNIT_KHz(PRECISION);
20222025
}
20232026

2027+
#ifdef CONFIG_PM_OPP
2028+
static unsigned long GetVoltage_From_OPP(unsigned int cpu,
2029+
unsigned long freq_hz)
2030+
{
2031+
unsigned long u_volt = 0;
2032+
struct device *cpu_dev = get_cpu_device(cpu);
2033+
if (cpu_dev != NULL) {
2034+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
2035+
struct dev_pm_opp *opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
2036+
#else
2037+
struct opp *opp_find_freq_ceil(cpu_dev, &freq_hz);
2038+
#endif
2039+
if (!IS_ERR(opp)) {
2040+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
2041+
u_volt = dev_pm_opp_get_voltage(opp);
2042+
dev_pm_opp_put(opp);
2043+
#else
2044+
u_volt = opp_get_voltage(opp);
2045+
#endif
2046+
}
2047+
}
2048+
return u_volt;
2049+
}
2050+
2051+
static void Query_Voltage_From_OPP(void)
2052+
{
2053+
unsigned int cpu;
2054+
for (cpu = 0; cpu < PUBLIC(RO(Proc))->CPU.Count; cpu++) {
2055+
enum RATIO_BOOST boost;
2056+
for (boost = BOOST(MIN); boost < BOOST(SIZE) - BOOST(18C); boost++)
2057+
{
2058+
unsigned long freq_hz = PUBLIC(RO(Proc))->Features.Factory.Clock.Hz
2059+
* PUBLIC(RO(Core, AT(cpu)))->Boost[BOOST(18C) + boost],
2060+
2061+
u_volt = GetVoltage_From_OPP(cpu, freq_hz);
2062+
u_volt = u_volt >> 5;
2063+
2064+
PRIVATE(OF(Core, AT(cpu)))->OPP[boost].VID = (signed int) u_volt;
2065+
}
2066+
}
2067+
}
2068+
2069+
inline enum RATIO_BOOST Find_OPP_From_Ratio(CORE_RO *Core, unsigned int ratio)
2070+
{
2071+
enum RATIO_BOOST boost, last = BOOST(MIN);
2072+
for (boost = BOOST(MIN); boost < BOOST(SIZE) - BOOST(18C); boost++) {
2073+
if (Core->Boost[BOOST(18C) + boost] <= ratio) {
2074+
last = boost;
2075+
continue;
2076+
}
2077+
break;
2078+
}
2079+
return last;
2080+
}
2081+
#endif /* CONFIG_PM_OPP */
2082+
20242083
static void Compute_ACPI_CPPC_Bounds(unsigned int cpu)
20252084
{
20262085
CORE_RO *Core = (CORE_RO *) PUBLIC(RO(Core, AT(cpu)));
@@ -3307,6 +3366,39 @@ static enum hrtimer_restart Cycle_GenericMachine(struct hrtimer *pTimer)
33073366
#endif
33083367
PUBLIC(RO(Core, AT(cpu)))->Boost[BOOST(TGT)] = Core->Ratio.COF.Q;
33093368

3369+
#ifdef CONFIG_PM_OPP
3370+
{
3371+
enum RATIO_BOOST index = Find_OPP_From_Ratio(Core, Core->Ratio.COF.Q);
3372+
3373+
switch (SCOPE_OF_FORMULA(PUBLIC(RO(Proc))->voltageFormula)) {
3374+
case FORMULA_SCOPE_CORE:
3375+
if (!((Core->T.ThreadID == 0) || (Core->T.ThreadID == -1)))
3376+
{
3377+
break;
3378+
}
3379+
fallthrough;
3380+
case FORMULA_SCOPE_SMT:
3381+
Core->PowerThermal.VID = \
3382+
PRIVATE(OF(Core, AT(Core->Bind)))->OPP[index].VID;
3383+
break;
3384+
case FORMULA_SCOPE_PKG:
3385+
if (Core->Bind == PUBLIC(RO(Proc))->Service.Core) {
3386+
Core->PowerThermal.VID = \
3387+
PRIVATE(OF(Core, AT(Core->Bind)))->OPP[index].VID;
3388+
}
3389+
break;
3390+
case FORMULA_SCOPE_NONE:
3391+
break;
3392+
}
3393+
if (((PUBLIC(RO(Proc))->Features.Hybrid)
3394+
&& (Core->Bind == PUBLIC(RO(Proc))->Service.Hybrid))
3395+
|| (Core->Bind == PUBLIC(RO(Proc))->Service.Core))
3396+
{
3397+
PUBLIC(RO(Proc))->PowerThermal.VID.CPU = \
3398+
PRIVATE(OF(Core, AT(Core->Bind)))->OPP[index].VID;
3399+
}
3400+
}
3401+
#endif /* CONFIG_PM_OPP */
33103402
BITSET(LOCKLESS, PUBLIC(RW(Core, AT(cpu)))->Sync.V, NTFY);
33113403

33123404
return HRTIMER_RESTART;
@@ -5922,6 +6014,10 @@ static int CoreFreqK_Ignition_Level_Up(INIT_ARG *pArg)
59226014

59236015
Controller_Start(0);
59246016

6017+
#ifdef CONFIG_PM_OPP
6018+
Query_Voltage_From_OPP();
6019+
#endif /* CONFIG_PM_OPP */
6020+
59256021
#ifdef CONFIG_HOTPLUG_CPU
59266022
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
59276023
/* Always returns zero (kernel/notifier.c) */

0 commit comments

Comments
 (0)