cc77250ac8239f91f40223d768a8cbd7c5b8eb38
[platform/kernel/u-boot.git] / cmd / dcr.c
1 /*
2  * (C) Copyright 2001
3  * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * AMCC 4XX DCR Functions
10  */
11
12 #include <common.h>
13 #include <cli.h>
14 #include <config.h>
15 #include <command.h>
16 #include <console.h>
17
18 unsigned long get_dcr (unsigned short);
19 unsigned long set_dcr (unsigned short, unsigned long);
20
21 /* =======================================================================
22  * Interpreter command to retrieve an AMCC PPC 4xx Device Control Register
23  * =======================================================================
24  */
25 int do_getdcr ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] )
26 {
27         unsigned short dcrn;    /* Device Control Register Num */
28         unsigned long value;    /* DCR's value */
29
30         unsigned long get_dcr (unsigned short);
31
32         /* Validate arguments */
33         if (argc < 2)
34                 return CMD_RET_USAGE;
35
36         /* Get a DCR */
37         dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16);
38         value = get_dcr (dcrn);
39
40         printf ("%04x: %08lx\n", dcrn, value);
41
42         return 0;
43 }
44
45
46 /* ======================================================================
47  * Interpreter command to set an AMCC PPC 4xx Device Control Register
48  * ======================================================================
49 */
50 int do_setdcr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
51 {
52         unsigned short dcrn;    /* Device Control Register Num */
53         unsigned long value;
54
55         /* DCR's value */
56         int nbytes;
57
58         /* Validate arguments */
59         if (argc < 2)
60                 return CMD_RET_USAGE;
61
62         /* Set a DCR */
63         dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16);
64         do {
65                 value = get_dcr (dcrn);
66                 printf ("%04x: %08lx", dcrn, value);
67                 nbytes = cli_readline(" ? ");
68                 if (nbytes == 0) {
69                         /*
70                          * <CR> pressed as only input, don't modify current
71                          * location and exit command.
72                          */
73                         nbytes = 1;
74                         return 0;
75                 } else {
76                         unsigned long i;
77                         char *endp;
78
79                         i = simple_strtoul (console_buffer, &endp, 16);
80                         nbytes = endp - console_buffer;
81                         if (nbytes)
82                                 set_dcr (dcrn, i);
83                 }
84         } while (nbytes);
85
86         return 0;
87 }
88
89 /* =======================================================================
90  * Interpreter command to retrieve an register value through AMCC PPC 4xx
91  * Device Control Register inderect addressing.
92  * =======================================================================
93  */
94 int do_getidcr (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
95 {
96         unsigned short adr_dcrn;        /* Device Control Register Num for Address */
97         unsigned short dat_dcrn;        /* Device Control Register Num for Data */
98         unsigned short offset;          /* Register's offset */
99         unsigned long value;            /* Register's value */
100         char *ptr = NULL;
101         char buf[80];
102
103         /* Validate arguments */
104         if (argc < 3)
105                 return CMD_RET_USAGE;
106
107         /* Find out whether ther is '.' (dot) symbol in the first parameter. */
108         strncpy (buf, argv[1], sizeof(buf)-1);
109         buf[sizeof(buf)-1] = 0; /* will guarantee zero-end string */
110         ptr = strchr (buf, '.');
111
112         if (ptr != NULL) {
113                 /* First parameter has format adr_dcrn.dat_dcrn */
114                 *ptr++ = 0; /* erase '.', create zero-end string */
115                 adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16);
116                 dat_dcrn = (unsigned short) simple_strtoul (ptr, NULL, 16);
117         } else {
118                 /*
119                  * First parameter has format adr_dcrn; dat_dcrn will be
120                  * calculated as adr_dcrn+1.
121                  */
122                 adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16);
123                 dat_dcrn = adr_dcrn+1;
124         }
125
126         /* Register's offset */
127         offset = (unsigned short) simple_strtoul (argv[2], NULL, 16);
128
129         /* Disable interrupts */
130         disable_interrupts ();
131         /* Set offset */
132         set_dcr (adr_dcrn, offset);
133         /* get data */
134         value = get_dcr (dat_dcrn);
135         /* Enable interrupts */
136         enable_interrupts ();
137
138         printf ("%04x.%04x-%04x Read  %08lx\n", adr_dcrn, dat_dcrn, offset, value);
139
140         return 0;
141 }
142
143 /* =======================================================================
144  * Interpreter command to update an register value through AMCC PPC 4xx
145  * Device Control Register inderect addressing.
146  * =======================================================================
147  */
148 int do_setidcr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
149 {
150         unsigned short adr_dcrn;        /* Device Control Register Num for Address */
151         unsigned short dat_dcrn;        /* Device Control Register Num for Data */
152         unsigned short offset;          /* Register's offset */
153         unsigned long value;            /* Register's value */
154         char *ptr = NULL;
155         char buf[80];
156
157         /* Validate arguments */
158         if (argc < 4)
159                 return CMD_RET_USAGE;
160
161         /* Find out whether ther is '.' (dot) symbol in the first parameter. */
162         strncpy (buf, argv[1], sizeof(buf)-1);
163         buf[sizeof(buf)-1] = 0; /* will guarantee zero-end string */
164         ptr = strchr (buf, '.');
165
166         if (ptr != NULL) {
167                 /* First parameter has format adr_dcrn.dat_dcrn */
168                 *ptr++ = 0;     /* erase '.', create zero-end string */
169                 adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16);
170                 dat_dcrn = (unsigned short) simple_strtoul (ptr, NULL, 16);
171         } else {
172                 /*
173                  * First parameter has format adr_dcrn; dat_dcrn will be
174                  * calculated as adr_dcrn+1.
175                  */
176                 adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16);
177                 dat_dcrn = adr_dcrn+1;
178         }
179
180         /* Register's offset */
181         offset = (unsigned short) simple_strtoul (argv[2], NULL, 16);
182         /* New value */
183         value  = (unsigned  long) simple_strtoul (argv[3], NULL, 16);
184
185         /* Disable interrupts */
186         disable_interrupts ();
187         /* Set offset */
188         set_dcr (adr_dcrn, offset);
189         /* set data */
190         set_dcr (dat_dcrn, value);
191         /* Enable interrupts */
192         enable_interrupts ();
193
194         printf ("%04x.%04x-%04x Write %08lx\n", adr_dcrn, dat_dcrn, offset, value);
195
196         return 0;
197 }
198
199 /***************************************************/
200
201 U_BOOT_CMD(
202         getdcr, 2,      1,      do_getdcr,
203         "Get an AMCC PPC 4xx DCR's value",
204         "dcrn - return a DCR's value."
205 );
206 U_BOOT_CMD(
207         setdcr, 2,      1,      do_setdcr,
208         "Set an AMCC PPC 4xx DCR's value",
209         "dcrn - set a DCR's value."
210 );
211
212 U_BOOT_CMD(
213         getidcr,        3,      1,      do_getidcr,
214         "Get a register value via indirect DCR addressing",
215         "adr_dcrn[.dat_dcrn] offset - write offset to adr_dcrn, read value from dat_dcrn."
216 );
217
218 U_BOOT_CMD(
219         setidcr,        4,      1,      do_setidcr,
220         "Set a register value via indirect DCR addressing",
221         "adr_dcrn[.dat_dcrn] offset value - write offset to adr_dcrn, write value to dat_dcrn."
222 );