Skip to content

Commit a421eb7

Browse files
committed
smu-tool: Add multiple SMU Support
Just found that we have another SMU interface called PwrSMU Signed-off-by: Jiaxun Yang <[email protected]>
1 parent 5f0b9cc commit a421eb7

File tree

5 files changed

+130
-29
lines changed

5 files changed

+130
-29
lines changed

smu-tool/inc/nb_smu_ops.h

+32-4
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,38 @@ typedef uint64_t u64;
2121

2222
#define AMD_VENDOR_ID 0x1022
2323
#define NB_DEVICE_ID 0x15d0
24-
#define NB_PCI_ID (AMD_VENDOR_ID << 16 | NB_DEVICE_ID)
2524

2625
#define NB_PCI_REG_ADDR_ADDR 0xB8
2726
#define NB_PCI_REG_DATA_ADDR 0xBC
2827

28+
#define C2PMSG_ARGx_ADDR(y, x) (y + 4 * x)
29+
30+
enum SMU_TYPE{
31+
TYPE_MP1,
32+
TYPE_PSMU,
33+
TYPE_COUNT,
34+
};
35+
2936
#define MP1_C2PMSG_MESSAGE_ADDR 0x3B10528
3037
#define MP1_C2PMSG_RESPONSE_ADDR 0x3B10564
3138
#define MP1_C2PMSG_ARG_BASE 0x3B10998
32-
#define MP1_C2PMSG_ARGx_ADDR(x) (MP1_C2PMSG_ARG_BASE + 4 * x)
3339

40+
#define PSMU_C2PMSG_MESSAGE_ADDR 0x3B10a20
41+
#define PSMU_C2PMSG_RESPONSE_ADDR 0x3B10a80
42+
#define PSMU_C2PMSG_ARG_BASE 0x3B10a88
3443

3544
#define REP_MSG_OK 0x1
3645
#define REP_MSG_Failed 0xFF
3746
#define REP_MSG_UnknownCmd 0xFE
3847
#define REP_MSG_CmdRejectedPrereq 0xFD
3948
#define REP_MSG_CmdRejectedBusy 0xFC
4049

50+
/*
51+
* All the SMU have the same TestMessage as for now
52+
* Correct me if they don't
53+
*/
54+
#define SMU_TEST_MSG 0x1
55+
4156
typedef struct {
4257
u32 arg0;
4358
u32 arg1;
@@ -61,17 +76,30 @@ typedef struct pci_dev *nb_t;
6176
typedef struct pci_access *pci_obj_t;
6277
#endif
6378

79+
typedef struct {
80+
nb_t nb;
81+
u32 msg;
82+
u32 rep;
83+
u32 arg_base;
84+
} smu_t;
85+
86+
6487
pci_obj_t init_pci_obj();
6588

66-
int free_pci_obj(pci_obj_t obj);
89+
void free_pci_obj(pci_obj_t obj);
6790

6891
nb_t get_nb(pci_obj_t obj);
6992

93+
void free_nb(nb_t nb);
94+
7095
u32 nb_reg_read(nb_t nb, u32 addr);
7196

7297
void nb_reg_write(nb_t nb, u32 addr, u32 data);
7398

74-
u32 smu_service_req(nb_t nb ,u32 id ,smu_service_args_t *args);
99+
100+
smu_t *get_smu(nb_t nb, int smu_type);
101+
void free_smu(smu_t *smu);
102+
u32 smu_service_req(smu_t *smu ,u32 id ,smu_service_args_t *args);
75103

76104

77105
#endif

smu-tool/libpci.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ nb_t get_nb(pci_obj_t obj){
1818
return nb;
1919
}
2020

21-
int free_pci_obj(pci_obj_t obj){
21+
void free_nb(nb_t nb){
22+
pci_free_dev(nb);
23+
}
24+
25+
26+
void free_pci_obj(pci_obj_t obj){
2227
pci_cleanup(obj);
23-
return 0;
2428
}
2529

2630
u32 nb_reg_read(nb_t nb, u32 addr)

smu-tool/main.cpp

+30-5
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,23 @@ static const char *const usage[] = {
1515

1616
int main(int argc, const char **argv)
1717
{
18-
pci_obj_t pci_obj;
19-
nb_t nb;
18+
/* Input args */
2019
uint32_t message = 0, iarg0 = 0, iarg1 = 0;
2120
uint32_t iarg2 = 0, iarg3 = 0, iarg4 = 0, iarg5 = 0;
21+
int mp1 = 0, psmu = 0;
22+
23+
/* Objects */
24+
pci_obj_t pci_obj;
25+
nb_t nb;
26+
smu_t *smu;
2227
smu_service_args_t *args;
2328
int err = 0;
2429

2530
struct argparse_option options[] = {
2631
OPT_HELP(),
32+
OPT_GROUP("SMU Type"),
33+
OPT_BOOLEAN('m',"mp1", &mp1, "MP1 SMU"),
34+
OPT_BOOLEAN('p',"psmu", &psmu, "Pwr SMU"),
2735
OPT_GROUP("Arguments"),
2836
OPT_U32('n', "message", &message, "The reqeust message"),
2937
OPT_U32('a', "arg0", &iarg0, "The first argument"),
@@ -42,18 +50,32 @@ int main(int argc, const char **argv)
4250
argc = argparse_parse(&argparse, argc, argv);
4351

4452
pci_obj = init_pci_obj();
45-
if(!pci_obj){
53+
if (!pci_obj){
4654
printf("Unable to get PCI Obj\n");
4755
return -1;
4856
}
4957

5058
nb = get_nb(pci_obj);
51-
if(!nb){
59+
if (!nb){
5260
printf("Unable to get NB Obj\n");
5361
err = -1;
5462
goto out_free_pci_obj;
5563
}
5664

65+
if (mp1){
66+
smu = get_smu(nb, TYPE_MP1);
67+
} else if (psmu){
68+
smu = get_smu(nb, TYPE_PSMU);
69+
} else {
70+
smu = get_smu(nb, TYPE_MP1);
71+
}
72+
73+
if(!smu){
74+
printf("Unable to get SMU\n");
75+
err = -1;
76+
goto out_free_nb;
77+
}
78+
5779
args = (smu_service_args_t *)malloc(sizeof(*args));
5880
memset(args, 0, sizeof(*args));
5981

@@ -64,7 +86,7 @@ int main(int argc, const char **argv)
6486
args->arg4 = iarg4;
6587
args->arg5 = iarg5;
6688

67-
switch(smu_service_req(nb, message, args)){
89+
switch(smu_service_req(smu, message, args)){
6890
case REP_MSG_OK:
6991
printf("Service Request OK\n");
7092
break;
@@ -95,6 +117,9 @@ int main(int argc, const char **argv)
95117
}
96118

97119
free(args);
120+
free_smu(smu);
121+
out_free_nb:
122+
free_nb(nb);
98123
out_free_pci_obj:
99124
free_pci_obj(pci_obj);
100125
return err;

smu-tool/nb_smu_ops.cpp

+57-16
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,79 @@
44

55
#include "nb_smu_ops.h"
66

7-
u32 smu_service_req(nb_t nb ,u32 id ,smu_service_args_t *args)
7+
u32 smu_service_req(smu_t *smu ,u32 id ,smu_service_args_t *args)
88
{
99
u32 response = 0x0;
1010
DBG("SMU_SERVICE REQ_ID:0x%x\n", id);
1111
DBG("SMU_SERVICE REQ: arg0: 0x%x, arg1:0x%x, arg2:0x%x, arg3:0x%x, arg4: 0x%x, arg5: 0x%x\n", \
1212
args->arg0, args->arg1, args->arg2, args->arg3, args->arg4, args->arg5);
1313

1414
/* Clear the response */
15-
nb_reg_write(nb, MP1_C2PMSG_RESPONSE_ADDR, 0x0);
15+
nb_reg_write(smu->nb, smu->rep, 0x0);
1616
/* Pass arguments */
17-
nb_reg_write(nb, MP1_C2PMSG_ARGx_ADDR(0), args->arg0);
18-
nb_reg_write(nb, MP1_C2PMSG_ARGx_ADDR(1), args->arg1);
19-
nb_reg_write(nb, MP1_C2PMSG_ARGx_ADDR(2), args->arg2);
20-
nb_reg_write(nb, MP1_C2PMSG_ARGx_ADDR(3), args->arg3);
21-
nb_reg_write(nb, MP1_C2PMSG_ARGx_ADDR(4), args->arg4);
22-
nb_reg_write(nb, MP1_C2PMSG_ARGx_ADDR(5), args->arg5);
17+
nb_reg_write(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 0), args->arg0);
18+
nb_reg_write(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 1), args->arg1);
19+
nb_reg_write(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 2), args->arg2);
20+
nb_reg_write(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 3), args->arg3);
21+
nb_reg_write(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 4), args->arg4);
22+
nb_reg_write(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 5), args->arg5);
2323
/* Send message ID */
24-
nb_reg_write(nb, MP1_C2PMSG_MESSAGE_ADDR, id);
24+
nb_reg_write(smu->nb, smu->msg, id);
2525
/* Wait until reponse changed */
2626
while(response == 0x0) {
27-
response = nb_reg_read(nb, MP1_C2PMSG_RESPONSE_ADDR);
27+
response = nb_reg_read(smu->nb, smu->rep);
2828
}
2929
/* Read back arguments */
30-
args->arg0 = nb_reg_read(nb, MP1_C2PMSG_ARGx_ADDR(0));
31-
args->arg1 = nb_reg_read(nb, MP1_C2PMSG_ARGx_ADDR(1));
32-
args->arg2 = nb_reg_read(nb, MP1_C2PMSG_ARGx_ADDR(2));
33-
args->arg3 = nb_reg_read(nb, MP1_C2PMSG_ARGx_ADDR(3));
34-
args->arg4 = nb_reg_read(nb, MP1_C2PMSG_ARGx_ADDR(4));
35-
args->arg5 = nb_reg_read(nb, MP1_C2PMSG_ARGx_ADDR(5));
30+
args->arg0 = nb_reg_read(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 0));
31+
args->arg1 = nb_reg_read(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 1));
32+
args->arg2 = nb_reg_read(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 2));
33+
args->arg3 = nb_reg_read(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 3));
34+
args->arg4 = nb_reg_read(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 4));
35+
args->arg5 = nb_reg_read(smu->nb, C2PMSG_ARGx_ADDR(smu->arg_base, 5));
3636

3737
DBG("SMU_SERVICE REP: REP: 0x%x, arg0: 0x%x, arg1:0x%x, arg2:0x%x, arg3:0x%x, arg4: 0x%x, arg5: 0x%x\n", \
3838
response, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4, args->arg5);
3939

4040
return response;
41+
}
42+
43+
smu_t *get_smu(nb_t nb, int smu_type) {
44+
smu_t *smu;
45+
uint32_t rep; /* REP of test message */
46+
smu_service_args_t arg = {0, 0, 0, 0, 0, 0}; /* Test message shuld have no arguments */
47+
48+
smu = (smu_t *)malloc((sizeof(smu_t)));
49+
smu->nb = nb;
50+
/* Fill SMU information */
51+
switch(smu_type){
52+
case TYPE_MP1:
53+
smu->msg = MP1_C2PMSG_MESSAGE_ADDR;
54+
smu->rep = MP1_C2PMSG_RESPONSE_ADDR;
55+
smu->arg_base = MP1_C2PMSG_ARG_BASE;
56+
break;
57+
case TYPE_PSMU:
58+
smu->msg = PSMU_C2PMSG_MESSAGE_ADDR;
59+
smu->rep = PSMU_C2PMSG_RESPONSE_ADDR;
60+
smu->arg_base = PSMU_C2PMSG_ARG_BASE;
61+
break;
62+
default:
63+
DBG("Failed to get SMU, unknown SMU_TYPE: %s\n", smu_type);
64+
goto err;
65+
break;
66+
}
67+
/* Try to send a test message*/
68+
rep = smu_service_req(smu, SMU_TEST_MSG, &arg);
69+
if(rep == REP_MSG_OK){
70+
return smu;
71+
} else {
72+
DBG("Faild to get SMU: %s, test message REP: %x\n", smu_type, rep);
73+
goto err;
74+
}
75+
err:
76+
free_smu(smu);
77+
return NULL;
78+
}
79+
80+
void free_smu(smu_t *smu) {
81+
free((void *)smu);
4182
}

smu-tool/winring0.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@ nb_t get_nb(pci_obj_t obj){
2323
return &nb_pci_address;
2424
}
2525

26-
int free_pci_obj(pci_obj_t obj){
26+
void free_nb(nb_t){
27+
return;
28+
}
29+
30+
void free_pci_obj(pci_obj_t obj){
2731
DeinitializeOls();
28-
return 0;
2932
}
3033

3134
u32 nb_reg_read(nb_t nb, u32 addr)

0 commit comments

Comments
 (0)