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