1 #include <common.h>
2 #include <command.h>
3 #include <aspeed_fsi.h>
4 #include <dm/device.h>
5 #include <dm/uclass.h>
6
7 struct fsi_master_aspeed *fsi;
8
do_break(void)9 static void do_break(void)
10 {
11 debug("%s\n", __func__);
12 aspeed_fsi_break(fsi, 0);
13 }
14
do_status(void)15 static void do_status(void)
16 {
17 debug("%s\n", __func__);
18 aspeed_fsi_status(fsi);
19 }
20
do_getcfam(int argc,char * const argv[])21 static void do_getcfam(int argc, char *const argv[])
22 {
23 int rc;
24 uint32_t addr, val;
25
26 if (argc != 3) {
27 printf("invalid arguments to getcfam\n");
28 return;
29 }
30
31 addr = simple_strtoul(argv[2], NULL, 16);
32
33 debug("%s %08x\n", __func__, addr);
34 rc = aspeed_fsi_read(fsi, 0, addr, &val, 4);
35 if (rc) {
36 printf("error reading: %d\n", rc);
37 return;
38 }
39
40 printf("0x%08x\n", be32_to_cpu(val));
41 }
42
do_putcfam(int argc,char * const argv[])43 static void do_putcfam(int argc, char *const argv[])
44 {
45 int rc;
46 uint32_t addr, val;
47
48 if (argc != 4) {
49 printf("invalid arguments to putcfam\n");
50 return;
51 }
52
53 addr = simple_strtoul(argv[2], NULL, 16);
54 val = simple_strtoul(argv[3], NULL, 16);
55
56 debug("%s %08x %08x\n", __func__, addr, val);
57 rc = aspeed_fsi_write(fsi, 0, addr, &val, 4);
58 if (rc)
59 printf("error writing: %d\n", rc);
60 }
61
do_divisor(int argc,char * const argv[])62 static void do_divisor(int argc, char *const argv[])
63 {
64 int rc;
65 uint32_t val;
66
67 if (argc == 2) {
68 rc = aspeed_fsi_divisor(fsi, 0);
69 if (rc > 0)
70 printf("divsior: %d\n", rc);
71 } else if (argc == 3) {
72 val = simple_strtoul(argv[2], NULL, 0);
73 rc = aspeed_fsi_divisor(fsi, val);
74 } else {
75 printf("invalid arguments to divisor\n");
76 return;
77 }
78
79 if (rc < 0)
80 printf("divisor error: %d\n", rc);
81 }
82
do_probe(int argc,char * const argv[])83 static struct fsi_master_aspeed *do_probe(int argc, char *const argv[])
84 {
85 struct udevice *dev;
86 const char *devices[] = {"fsi@1e79b000", "fsi@1e79b100"};
87 int rc, id;
88
89 if (argc > 3) {
90 printf("invalid arguments to probe\n");
91 return NULL;
92 }
93
94 if (argc == 2)
95 id = 0;
96 else
97 id = simple_strtoul(argv[2], NULL, 10);
98
99 if (id > 1) {
100 printf("valid devices: 0, 1\n");
101 return NULL;
102 }
103
104 rc = uclass_get_device_by_name(UCLASS_MISC, devices[id], &dev);
105 if (rc) {
106 printf("fsi device %s not found\n", devices[id]);
107 return NULL;
108 }
109 return dev_get_priv(dev);
110 }
111
112
do_fsi(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])113 static int do_fsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
114 {
115
116 if (!strcmp(argv[1], "probe")) {
117 fsi = do_probe(argc, argv);
118 return 0;
119 }
120
121 if (fsi == NULL) {
122 printf("Run probe first\n");
123 return -EINVAL;
124 }
125
126 if (!strcmp(argv[1], "break"))
127 do_break();
128 else if (!strcmp(argv[1], "status"))
129 do_status();
130 else if (!strncmp(argv[1], "put", 3))
131 do_putcfam(argc, argv);
132 else if (!strncmp(argv[1], "get", 3))
133 do_getcfam(argc, argv);
134 else if (!strncmp(argv[1], "div", 3))
135 do_divisor(argc, argv);
136
137 return 0;
138 }
139
140 static char fsi_help_text[] =
141 "fsi probe [<n>]\n"
142 "fsi break\n"
143 "fsi getcfam <addr>\n"
144 "fsi putcfam <addr> <value>\n"
145 "fsi divisor [<divisor>]\n"
146 "fsi status\n";
147
148 U_BOOT_CMD(
149 fsi, 4, 1, do_fsi,
150 "IBM FSI commands",
151 fsi_help_text
152 );
153
154