diff --git a/corefreq-cli.c b/corefreq-cli.c index eb281f17..15492798 100644 --- a/corefreq-cli.c +++ b/corefreq-cli.c @@ -3674,8 +3674,8 @@ REASON_CODE SysInfoPerfMon(Window *win, CUINT width, CELL_FUNC OutFunc) { if (RO(Shm)->Proc.Features.ACPI_CPPC == 1) { - GridHover( PUT( SCANKEY_NULL, attrib[bix], width, 2, - "%s%.*s%s [%3s]", RSC(PERF_MON_CPPC).CODE(), + GridHover( PUT( BOXKEY_HWP, attrib[bix], width, 2, + "%s%.*s%s <%3s>", RSC(PERF_MON_CPPC).CODE(), width - 19 - RSZ(PERF_MON_CPPC), hSpace, RSC(PERF_LABEL_CPPC).CODE(), RSC(FMW).CODE() ), (char *) RSC(PERF_MON_CPPC_COMM).CODE() ); @@ -9165,19 +9165,23 @@ void CPU_Target_Freq_Update(TGrid *grid, DATA_TYPE data[]) void Pkg_Item_HWP_Target_Freq(ASCII *item) { unsigned int top = Ruler.Top[BOOST(HWP_TGT)]; + const unsigned int isEnable = (RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1); Pkg_Fmt_Freq( item, RSC(CREATE_SELECT_FREQ_HWP_TGT).CODE(), &RO(Shm)->Cpu[top].FlipFlop[ !RO(Shm)->Cpu[top].Toggle ].Clock, RO(Shm)->Cpu[top].Boost[BOOST(HWP_TGT)], - RO(Shm)->Proc.Features.HWP_Enable ); + isEnable ); } void Pkg_HWP_Target_Freq_Update(TGrid *grid, DATA_TYPE data[]) { ASCII item[RSZ(CREATE_SELECT_FREQ_OFFLINE)+9+10+1]; unsigned int top = Ruler.Top[BOOST(HWP_TGT)]; + const unsigned int isEnable = (RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1); UNUSED(data); Pkg_Fmt_Freq( item, RSC(CREATE_SELECT_FREQ_HWP_TGT).CODE(), @@ -9185,7 +9189,7 @@ void Pkg_HWP_Target_Freq_Update(TGrid *grid, DATA_TYPE data[]) !RO(Shm)->Cpu[top].Toggle ].Clock, RO(Shm)->Cpu[top].Boost[BOOST(HWP_TGT)], - RO(Shm)->Proc.Features.HWP_Enable ); + isEnable ); memcpy(grid->cell.item, item, grid->cell.length); } @@ -9194,11 +9198,13 @@ void CPU_Item_HWP_Target_Freq(unsigned int cpu, ASCII *item) { struct FLIP_FLOP *CFlop; CFlop = &RO(Shm)->Cpu[cpu].FlipFlop[ !RO(Shm)->Cpu[cpu].Toggle ]; + const unsigned int isEnable = (RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1); if (RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Desired_Perf == 0) { CPU_Item_Auto_Freq( cpu, RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Desired_Perf, - RO(Shm)->Proc.Features.HWP_Enable, item ); + isEnable, item ); } else { StrFormat(item, RSZ(CREATE_SELECT_FREQ_OFFLINE)+10+11+11+11+8+10+1, @@ -9211,9 +9217,9 @@ void CPU_Item_HWP_Target_Freq(unsigned int cpu, ASCII *item) RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Desired_Perf, CFlop->Clock ), - RO(Shm)->Proc.Features.HWP_Enable ? '<' : '[', + isEnable ? '<' : '[', RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Desired_Perf, - RO(Shm)->Proc.Features.HWP_Enable ? '>' : ']'); + isEnable ? '>' : ']'); } } @@ -9260,19 +9266,23 @@ void CPU_HWP_Target_Freq_Update(TGrid *grid, DATA_TYPE data[]) void Pkg_Item_HWP_Max_Freq(ASCII *item) { unsigned int top = Ruler.Top[BOOST(HWP_MAX)]; + const unsigned int isEnable = (RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1); Pkg_Fmt_Freq( item, RSC(CREATE_SELECT_FREQ_HWP_MAX).CODE(), &RO(Shm)->Cpu[top].FlipFlop[ !RO(Shm)->Cpu[top].Toggle ].Clock, RO(Shm)->Cpu[top].Boost[BOOST(HWP_MAX)], - RO(Shm)->Proc.Features.HWP_Enable ); + isEnable ); } void Pkg_HWP_Max_Freq_Update(TGrid *grid, DATA_TYPE data[]) { ASCII item[RSZ(CREATE_SELECT_FREQ_OFFLINE)+9+10+1]; unsigned int top = Ruler.Top[BOOST(HWP_MAX)]; + const unsigned int isEnable = (RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1); UNUSED(data); Pkg_Fmt_Freq( item, RSC(CREATE_SELECT_FREQ_HWP_MAX).CODE(), @@ -9280,7 +9290,7 @@ void Pkg_HWP_Max_Freq_Update(TGrid *grid, DATA_TYPE data[]) !RO(Shm)->Cpu[top].Toggle ].Clock, RO(Shm)->Cpu[top].Boost[BOOST(HWP_MAX)], - RO(Shm)->Proc.Features.HWP_Enable ); + isEnable ); memcpy(grid->cell.item, item, grid->cell.length); } @@ -9289,11 +9299,13 @@ void CPU_Item_HWP_Max_Freq(unsigned int cpu, ASCII *item) { struct FLIP_FLOP *CFlop; CFlop = &RO(Shm)->Cpu[cpu].FlipFlop[ !RO(Shm)->Cpu[cpu].Toggle ]; + const unsigned int isEnable = (RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1); if (RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Maximum_Perf == 0) { CPU_Item_Auto_Freq( cpu, RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Maximum_Perf, - RO(Shm)->Proc.Features.HWP_Enable, item ); + isEnable, item ); } else { StrFormat(item, RSZ(CREATE_SELECT_FREQ_OFFLINE)+10+11+11+11+8+10+1, @@ -9306,9 +9318,9 @@ void CPU_Item_HWP_Max_Freq(unsigned int cpu, ASCII *item) RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Maximum_Perf, CFlop->Clock ), - RO(Shm)->Proc.Features.HWP_Enable ? '<' : '[', + isEnable ? '<' : '[', RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Maximum_Perf, - RO(Shm)->Proc.Features.HWP_Enable ? '>' : ']'); + isEnable ? '>' : ']'); } } @@ -9355,19 +9367,23 @@ void CPU_HWP_Max_Freq_Update(TGrid *grid, DATA_TYPE data[]) void Pkg_Item_HWP_Min_Freq(ASCII *item) { unsigned int top = Ruler.Top[BOOST(HWP_MIN)]; + const unsigned int isEnable = (RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1); Pkg_Fmt_Freq( item, RSC(CREATE_SELECT_FREQ_HWP_MIN).CODE(), &RO(Shm)->Cpu[top].FlipFlop[ !RO(Shm)->Cpu[top].Toggle ].Clock, RO(Shm)->Cpu[top].Boost[BOOST(HWP_MIN)], - RO(Shm)->Proc.Features.HWP_Enable ); + isEnable ); } void Pkg_HWP_Min_Freq_Update(TGrid *grid, DATA_TYPE data[]) { ASCII item[RSZ(CREATE_SELECT_FREQ_OFFLINE)+9+10+1]; unsigned int top = Ruler.Top[BOOST(HWP_MIN)]; + const unsigned int isEnable = (RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1); UNUSED(data); Pkg_Fmt_Freq( item, RSC(CREATE_SELECT_FREQ_HWP_MIN).CODE(), @@ -9375,7 +9391,7 @@ void Pkg_HWP_Min_Freq_Update(TGrid *grid, DATA_TYPE data[]) !RO(Shm)->Cpu[top].Toggle ].Clock, RO(Shm)->Cpu[top].Boost[BOOST(HWP_MIN)], - RO(Shm)->Proc.Features.HWP_Enable ); + isEnable ); memcpy(grid->cell.item, item, grid->cell.length); } @@ -9384,11 +9400,13 @@ void CPU_Item_HWP_Min_Freq(unsigned int cpu, ASCII *item) { struct FLIP_FLOP *CFlop; CFlop = &RO(Shm)->Cpu[cpu].FlipFlop[ !RO(Shm)->Cpu[cpu].Toggle ]; + const unsigned int isEnable = (RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1); if (RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Minimum_Perf == 0) { CPU_Item_Auto_Freq( cpu, RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Minimum_Perf, - RO(Shm)->Proc.Features.HWP_Enable, item ); + isEnable, item ); } else { StrFormat(item, RSZ(CREATE_SELECT_FREQ_OFFLINE)+10+11+11+11+8+10+1, @@ -9401,9 +9419,9 @@ void CPU_Item_HWP_Min_Freq(unsigned int cpu, ASCII *item) RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Minimum_Perf, CFlop->Clock ), - RO(Shm)->Proc.Features.HWP_Enable ? '<' : '[', + isEnable ? '<' : '[', RO(Shm)->Cpu[cpu].PowerThermal.HWP.Request.Minimum_Perf, - RO(Shm)->Proc.Features.HWP_Enable ? '>' : ']'); + isEnable ? '>' : ']'); } } @@ -14805,7 +14823,8 @@ int Shortcut(SCANKEY *scan) break; case BOXKEY_RATIO_CLOCK_HWP_TGT: - if (RO(Shm)->Proc.Features.HWP_Enable == 1) + if ((RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1)) { Window *win = SearchWinListById(scan->key, &winList); if (win == NULL) @@ -14857,7 +14876,8 @@ int Shortcut(SCANKEY *scan) break; case BOXKEY_RATIO_CLOCK_HWP_MAX: - if (RO(Shm)->Proc.Features.HWP_Enable == 1) + if ((RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1)) { Window *win = SearchWinListById(scan->key, &winList); if (win == NULL) @@ -14909,7 +14929,8 @@ int Shortcut(SCANKEY *scan) break; case BOXKEY_RATIO_CLOCK_HWP_MIN: - if (RO(Shm)->Proc.Features.HWP_Enable == 1) + if ((RO(Shm)->Proc.Features.HWP_Enable == 1) + || (RO(Shm)->Proc.Features.ACPI_CPPC == 1)) { Window *win = SearchWinListById(scan->key, &winList); if (win == NULL) diff --git a/corefreqk.c b/corefreqk.c index 29914b90..eb8cd8e9 100644 --- a/corefreqk.c +++ b/corefreqk.c @@ -3663,7 +3663,16 @@ long AMD_F17h_CPPC(void) return -ENODEV; } -signed int Read_ACPI_CPPC_Registers(unsigned int cpu) +inline signed int Enable_ACPI_CPPC(unsigned int cpu, void *arg) +{ +#ifdef CONFIG_ACPI_CPPC_LIB + return cppc_set_enable((signed int) cpu, true); +#else + return -ENODEV; +#endif /* CONFIG_ACPI_CPPC_LIB */ +} + +signed int Read_ACPI_CPPC_Registers(unsigned int cpu, void *arg) { #ifdef CONFIG_ACPI_CPPC_LIB struct cppc_perf_fb_ctrs CPPC_Perf; @@ -3684,22 +3693,22 @@ signed int Read_ACPI_CPPC_Registers(unsigned int cpu) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) .Efficient = CPPC_Caps.nominal_freq, .Lowest = CPPC_Caps.lowest_freq, + .Minimum = CPPC_Caps.lowest_freq, #else .Efficient = CPPC_Caps.nominal_perf, .Lowest = CPPC_Caps.lowest_perf, + .Minimum = CPPC_Caps.lowest_perf, #endif - .Minimum = CPPC_Perf.reference_perf, - .Maximum = CPPC_Perf.reference_perf, + .Maximum = CPPC_Caps.highest_perf, .Desired = CPPC_Perf.reference_perf, .Energy = 0 }; #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) rc = cppc_get_desired_perf(Core->Bind, &desired_perf); - #endif if (rc == 0) { - Core->PowerThermal.ACPI_CPPC.Maximum = \ Core->PowerThermal.ACPI_CPPC.Desired = desired_perf; } + #endif } return rc; #else @@ -3707,7 +3716,7 @@ signed int Read_ACPI_CPPC_Registers(unsigned int cpu) #endif /* CONFIG_ACPI_CPPC_LIB */ } -void For_All_ACPI_CPPC_Read(void) +void For_All_ACPI_CPPC(signed int(*CPPC_Func)(unsigned int, void*), void *arg) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) signed int rc = acpi_cpc_valid() == false; @@ -3718,7 +3727,7 @@ void For_All_ACPI_CPPC_Read(void) unsigned int cpu; for (cpu = 0; (cpu < PUBLIC(RO(Proc))->CPU.Count) && (rc == 0); cpu++) { - rc = Read_ACPI_CPPC_Registers(cpu); + rc = CPPC_Func(cpu, arg); } PUBLIC(RO(Proc))->Features.ACPI_CPPC = (rc == 0); } @@ -6965,6 +6974,108 @@ inline unsigned int CPPC_AMD_Zen_ScaleHint( CORE_RO *Core, return flag; } +signed int Write_ACPI_CPPC_Registers(unsigned int cpu, void *arg) +{ +#ifdef CONFIG_ACPI_CPPC_LIB + CLOCK_ZEN_ARG *pClockZen = (CLOCK_ZEN_ARG *) arg; + + struct cppc_perf_fb_ctrs CPPC_Perf; + struct cppc_perf_caps CPPC_Caps; + + CORE_RO *Core = (CORE_RO *) PUBLIC(RO(Core, AT(cpu))); + + if ((cppc_get_perf_ctrs(Core->Bind, &CPPC_Perf) == 0) + && (cppc_get_perf_caps(Core->Bind, &CPPC_Caps) == 0)) + { + HWCR HwCfgRegister = {.value = 0}; + unsigned short WrRdCPPC = 0; + + struct cppc_perf_ctrls perf_ctrls = { + .max_perf = CPPC_Caps.highest_perf, + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + .min_perf = CPPC_AMD_Zen_ScaleHint(Core, + CPPC_Caps.lowest_freq / PRECISION, + !HwCfgRegister.Family_17h.CpbDis), + #else + .min_perf = CPPC_Caps.lowest_perf, + #endif + .desired_perf = CPPC_Perf.reference_perf + }; + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) + unsigned long long desired_perf = 0; + if (cppc_get_desired_perf(Core->Bind, &desired_perf) == 0) { + perf_ctrls.desired_perf = desired_perf; + } + #endif + + RDMSR(HwCfgRegister, MSR_K7_HWCR); + + switch (pClockZen->pClockMod->NC) { + case CLOCK_MOD_HWP_MIN: + pClockZen->rc = -RC_UNIMPLEMENTED; + break; + case CLOCK_MOD_HWP_MAX: + pClockZen->rc = -RC_UNIMPLEMENTED; + break; + case CLOCK_MOD_HWP_TGT: + { + unsigned int hint; + if (pClockZen->pClockMod->cpu == -1) { + hint = CPPC_AMD_Zen_ScaleHint( Core, + pClockZen->pClockMod->Ratio, + !HwCfgRegister.Family_17h.CpbDis ); + + perf_ctrls.desired_perf = hint & 0xff; + WrRdCPPC = 1; + } else if (pClockZen->pClockMod->cpu == cpu) { + hint = CPPC_AMD_Zen_ScaleHint( Core, + Core->Boost[BOOST(HWP_TGT)] + + pClockZen->pClockMod->Offset, + !HwCfgRegister.Family_17h.CpbDis ); + + perf_ctrls.desired_perf = hint & 0xff; + WrRdCPPC = 1; + } + } + break; + default: + pClockZen->rc = -RC_UNIMPLEMENTED; + break; + } + if (WrRdCPPC == 1) + { + cppc_set_perf(cpu, &perf_ctrls); + + if (cppc_get_perf_caps(cpu, &CPPC_Caps) == 0) + { + perf_ctrls.max_perf = CPPC_Caps.highest_perf; + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + perf_ctrls.min_perf = CPPC_AMD_Zen_ScaleHint(Core, + CPPC_Caps.lowest_freq / PRECISION, + !HwCfgRegister.Family_17h.CpbDis); + #else + perf_ctrls.min_perf = CPPC_Caps.lowest_perf; + #endif + + Core->PowerThermal.ACPI_CPPC.Minimum = CPPC_Caps.lowest_freq; + Core->PowerThermal.ACPI_CPPC.Maximum = CPPC_Caps.highest_perf; + } + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) + if (cppc_get_desired_perf(cpu, &desired_perf) == 0) { + perf_ctrls.desired_perf = desired_perf; + + Core->PowerThermal.ACPI_CPPC.Desired = desired_perf; + } + #endif + pClockZen->rc = RC_OK_COMPUTE; + } + } + return 0; +#else + return -ENODEV; +#endif /* CONFIG_ACPI_CPPC_LIB */ +} + static void CPPC_AMD_Zen_PerCore(void *arg) { CLOCK_ZEN_ARG *pClockZen = (CLOCK_ZEN_ARG *) arg; @@ -7217,9 +7328,16 @@ static long ClockMod_AMD_Zen(CLOCK_ARG *pClockMod) .pClockMod = pClockMod, .rc = RC_SUCCESS }; - return PUBLIC(RO(Proc))->Features.HWP_Enable == 1 ? - For_All_AMD_Zen_Clock(&ClockZen, CPPC_AMD_Zen_PerCore) - : -RC_UNIMPLEMENTED; + if (PUBLIC(RO(Proc))->Features.HWP_Enable == 1) { + return For_All_AMD_Zen_Clock(&ClockZen, CPPC_AMD_Zen_PerCore); + } + else if (PUBLIC(RO(Proc))->Features.ACPI_CPPC == 1) + { + For_All_ACPI_CPPC(Write_ACPI_CPPC_Registers, &ClockZen); + return ClockZen.rc; + } else { + return -RC_UNIMPLEMENTED; + } } default: return -RC_UNIMPLEMENTED; @@ -7459,7 +7577,7 @@ static void Query_AMD_F17h_PerSocket(unsigned int cpu) if (cpu == PUBLIC(RO(Proc))->Service.Core) { Query_AMD_F17h_Power_Limits(PUBLIC(RO(Proc))); if (AMD_F17h_CPPC() == -ENODEV) { - For_All_ACPI_CPPC_Read(); + For_All_ACPI_CPPC(Read_ACPI_CPPC_Registers, NULL); } } } @@ -7475,7 +7593,7 @@ static void Query_AMD_F17h_PerCluster(unsigned int cpu) if (cpu == PUBLIC(RO(Proc))->Service.Core) { Query_AMD_F17h_Power_Limits(PUBLIC(RO(Proc))); if (AMD_F17h_CPPC() == -ENODEV) { - For_All_ACPI_CPPC_Read(); + For_All_ACPI_CPPC(Read_ACPI_CPPC_Registers, NULL); } } } @@ -11798,6 +11916,9 @@ static void PerCore_AMD_Family_17h_Query(void *arg) Core->PowerThermal.HWP_Capabilities.Lowest = \ Core->PowerThermal.ACPI_CPPC.Lowest / PRECISION; + + Core->PowerThermal.HWP_Request.Minimum_Perf = \ + Core->PowerThermal.ACPI_CPPC.Minimum / PRECISION; #else Core->PowerThermal.HWP_Capabilities.Most_Efficient = \ CPPC_AMD_Zen_ScaleRatio( Core, @@ -11809,12 +11930,12 @@ static void PerCore_AMD_Family_17h_Query(void *arg) Core->PowerThermal.ACPI_CPPC.Lowest, !HwCfgRegister.Family_17h.CpbDis ); - #endif Core->PowerThermal.HWP_Request.Minimum_Perf = \ CPPC_AMD_Zen_ScaleRatio( Core, Core->PowerThermal.ACPI_CPPC.Minimum, !HwCfgRegister.Family_17h.CpbDis ); + #endif Core->PowerThermal.HWP_Request.Maximum_Perf = \ CPPC_AMD_Zen_ScaleRatio( Core, Core->PowerThermal.ACPI_CPPC.Maximum, @@ -20136,7 +20257,11 @@ static long CoreFreqK_ioctl( struct file *filp, } else if ((PUBLIC(RO(Proc))->Features.Info.Vendor.CRC == CRC_AMD) || (PUBLIC(RO(Proc))->Features.Info.Vendor.CRC == CRC_HYGON)) { - AMD_F17h_CPPC(); + if (PUBLIC(RO(Proc))->Features.ACPI_CPPC) { + For_All_ACPI_CPPC(Enable_ACPI_CPPC, NULL); + } else { + AMD_F17h_CPPC(); + } } Controller_Start(1); HWP_Enable = -1; diff --git a/coretypes.h b/coretypes.h index d38e25a3..15f02703 100644 --- a/coretypes.h +++ b/coretypes.h @@ -5,8 +5,8 @@ */ #define COREFREQ_MAJOR 1 -#define COREFREQ_MINOR 91 -#define COREFREQ_REV 6 +#define COREFREQ_MINOR 92 +#define COREFREQ_REV 0 #if !defined(CORE_COUNT) #define CORE_COUNT 256 diff --git a/dkms.conf b/dkms.conf index a9af8f62..d1468d0d 100644 --- a/dkms.conf +++ b/dkms.conf @@ -5,7 +5,7 @@ AUTOINSTALL="yes" REMAKE_INITRD="no" DRV_PATH=/kernel/drivers/misc -DRV_VERSION=1.91 +DRV_VERSION=1.92 PACKAGE_NAME="corefreqk" PACKAGE_VERSION="$DRV_VERSION" BUILT_MODULE_NAME[0]="corefreqk"