Skip to content

Commit 49f75d7

Browse files
committed
Add NumBoostStates and NbPstate handling
1 parent 834e766 commit 49f75d7

1 file changed

Lines changed: 58 additions & 33 deletions

File tree

amdctl.c

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ static unsigned char COFVID_MAX_VID = 1;
114114
static unsigned char COFVID_MIN_VID = 128;
115115
static signed short MAIN_PLL_COFF = -1;
116116

117+
static char *CPU_NBPST_BITS = NULL;
118+
static char *CPBC_NUM_BOOST_STATES_BITS = NULL;
119+
static signed char nbPst = -1, maxNbPst = -1;
120+
117121
static uint64_t buffer;
118122
static unsigned char currentOnly = 0, debug = 0, DIDS = 5, quiet = 0, PSTATES = 8, pvi = 0, testMode = 0;
119123
static signed char cpuDid = -1, togglePs = -1;
@@ -259,6 +263,28 @@ void checkFamily() {
259263
fprintf(stderr, "Your CPU is not supported by amdctl (Family %xh ; Model %xh).\n", cpuFamily, cpuModel);
260264
exit(EXIT_FAILURE);
261265
}
266+
switch (cpuFamily) {
267+
case AMD10H:
268+
CPBC_NUM_BOOST_STATES_BITS = "2:2";
269+
break;
270+
case AMD12H:
271+
case AMD14H:
272+
case AMD15H:
273+
case AMD16H:
274+
CPBC_NUM_BOOST_STATES_BITS = "4:2";
275+
break;
276+
default:
277+
break;
278+
}
279+
switch (cpuFamily) {
280+
case AMD15H:
281+
case AMD16H:
282+
CPU_NBPST_BITS = "22:22";
283+
maxNbPst = 1;
284+
break;
285+
default:
286+
break;
287+
}
262288
}
263289

264290
/**
@@ -315,7 +341,15 @@ void parseOpts(const int argc, char **argv) {
315341
case 'm': // Kernel >= 5.9, check / set /sys/module/msr/parameters/allow_writes to on.
316342
allowWrites = 1;
317343
break;
318-
case 'n': // Northbridge vid to set.
344+
case 'n': // Northbridge vid/pstate to set.
345+
if (CPU_NBPST_BITS) {
346+
nbPst = atoi(optarg);
347+
if (nbPst < 0 || nbPst > maxNbPst) {
348+
fprintf(stderr, "ERROR: Option -n must be between 0 and %d.\n", maxNbPst);
349+
exit(EXIT_FAILURE);
350+
}
351+
break;
352+
}
319353
if (cpuFamily > AMD11H) {
320354
error("Currently amdctl can only change the NB vid on 10h and 11h CPU's.");
321355
}
@@ -414,6 +448,8 @@ void usage() {
414448
printf(" -v Set CPU voltage id (vid).\n");
415449
if (cpuFamily == AMD10H || cpuFamily == AMD11H) {
416450
printf(" -n Set north bridge voltage id (vid).\n");
451+
} else if (CPU_NBPST_BITS) {
452+
printf(" -n Set north bridge P-State.\n");
417453
}
418454
if (cpuFamily == AMD14H) {
419455
printf(" -d Set the CPU divisor ID most significant digit (CpuDidMSD).\n");
@@ -460,6 +496,7 @@ void fieldDescriptions() {
460496
printf("CpuVolt: Core voltage, in millivolts.\n");
461497
printf("NbVid: North bridge voltage ID.\n");
462498
printf("NbVolt: North bridge voltage, in millivolts.\n");
499+
printf("NbPst: North bridge P-State. (lower numbers mean higher performance).\n");
463500
printf("IddVal: Core current (intensity) ID. Used to calculate cpu current draw and power draw.\n");
464501
printf("IddDiv Core current (intensity) dividor.\n");
465502
printf("CpuCurr: The cpu current draw, in amps.\n");
@@ -522,8 +559,7 @@ void uwmsrCheck(const unsigned char allowWrites) {
522559
*/
523560
void wrCpuStates() {
524561
uint32_t tmp_pstates[PSTATES];
525-
unsigned char pstates_count = 0;
526-
unsigned char extra = 1;
562+
unsigned char pstates_count = 0, bstates = 0;
527563
if (pstate == -1) {
528564
for (; pstates_count < PSTATES; pstates_count++) {
529565
tmp_pstates[pstates_count] = (MSR_PSTATE_BASE + pstates_count);
@@ -532,49 +568,28 @@ void wrCpuStates() {
532568
tmp_pstates[0] = MSR_PSTATE_BASE + pstate;
533569
pstates_count = 1;
534570
}
571+
if (CPBC_NUM_BOOST_STATES_BITS) {
572+
rwPciReg("18.4", 0x15c, 1);
573+
bstates = getDec(CPBC_NUM_BOOST_STATES_BITS);
574+
}
535575

536576
for (; core < cores; core++) {
537577
rwMsrReg(MSR_PSTATE_CURRENT_LIMIT, 1);
538-
int i, curPstate = getDec(CUR_PSTATE_BITS), minPstate = getDec(PSTATE_MAX_VAL_BITS), maxPstate = getDec(CUR_PSTATE_LIMIT_BITS);
539-
switch (cpuFamily) {
540-
case AMD10H:
541-
if (cpuModel == 0x05) {
542-
extra = 0;
543-
}
544-
break;
545-
case AMD14H:
546-
if (cpuModel == 0x02) {
547-
extra = 0;
548-
}
549-
break;
550-
case AMD16H:
551-
if (cpuModel == 0x30) {
552-
extra = 2;
553-
}
554-
break;
555-
case AMD17H:
556-
case AMD19H:
557-
extra = 0;
558-
break;
559-
default:
560-
break;
561-
}
562-
curPstate += extra;
563-
minPstate += extra;
564-
maxPstate += extra;
578+
int i, curPstate, minPstate = bstates + getDec(PSTATE_MAX_VAL_BITS), maxPstate = bstates + getDec(CUR_PSTATE_LIMIT_BITS);
565579
rwMsrReg(MSR_PSTATE_STATUS, 1);
580+
curPstate = bstates + getDec(CUR_PSTATE_BITS);
566581
if (!quiet) {
567582
printf("\nCore %d | P-State Limits (non-turbo): Highest: %d ; Lowest %d | Current P-State: %d\n", core, maxPstate, minPstate, curPstate);
568583
printf(" Pstate Status CpuFid CpuDid CpuVid CpuMult CpuFreq CpuVolt IddVal IddDiv CpuCurr CpuPower");
569-
printf("%s\n", (cpuFamily == AMD10H || cpuFamily == AMD11H) ? " NbVid NbVolt" : "");
584+
printf("%s\n", (cpuFamily == AMD10H || cpuFamily == AMD11H) ? " NbVid NbVolt" : (CPU_NBPST_BITS ? " NbPst" : ""));
570585
}
571586
if (!currentOnly) {
572587
for (i = 0; i < pstates_count; i++) {
573588
if (!quiet) {
574589
printf("%7d", (pstate >= 0 ? pstate : i));
575590
}
576591
rwMsrReg(tmp_pstates[i], 1);
577-
if (nbVid > -1 || cpuVid > -1 || cpuFid > -1 || cpuDid > -1 || togglePs > -1) {
592+
if (nbVid > -1 || cpuVid > -1 || cpuFid > -1 || cpuDid > -1 || togglePs > -1 || nbPst > -1) {
578593
if (togglePs > -1) {
579594
updateBuffer(PSTATE_EN_BITS, togglePs);
580595
}
@@ -590,6 +605,9 @@ void wrCpuStates() {
590605
if (cpuDid > -1) {
591606
updateBuffer(CPU_DID_BITS, cpuDid);
592607
}
608+
if (nbPst > -1) {
609+
updateBuffer(CPU_NBPST_BITS, nbPst);
610+
}
593611
rwMsrReg(tmp_pstates[i], 0);
594612
}
595613
printCpuPstate(1);
@@ -662,6 +680,13 @@ void printCpuPstate(const unsigned char idd) {
662680
printf("%7s%7s%8s%9s", "", "", "", "");
663681
}
664682
printf("%6d%5dmV", NbVid, vidTomV(NbVid));
683+
} else if (CPU_NBPST_BITS) {
684+
if (!idd) {
685+
printf("%7s%7s%8s%9s%6s", "", "", "", "", "");
686+
} else {
687+
const int NbPst = getDec(CPU_NBPST_BITS);
688+
printf("%6d", NbPst);
689+
}
665690
}
666691
printf("\n");
667692
}
@@ -891,7 +916,7 @@ unsigned short vidTomV(const unsigned short vid) {
891916

892917
// https://github.com/mpollice/AmdMsrTweaker/blob/master/Info.cpp#L47
893918
if ((cpuFamily == AMD15H && ((cpuModel > 0x0f && cpuModel < 0x20) || (cpuModel > 0x2f && cpuModel < 0x40))) ||
894-
(cpuFamily == AMD16H && cpuModel == 0x30) ||
919+
cpuFamily == AMD16H ||
895920
cpuFamily == AMD17H ||
896921
cpuFamily == AMD19H) {
897922
return (MAX_VOLTAGE - (vid * VID_DIVIDOR3));

0 commit comments

Comments
 (0)