GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / arch / mips / cpu / sb1250 / src / ui_spdcmds.c
blob6174e59c42952abcaf77805bea8263699dddfb03
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * SPD (memory serial presence detect) File: ui_spdcmds.c
5 *
6 * Commands to display contents of memory SPD ROMs
7 *
8 * Author: Mitch Lichtenberg (mpl@broadcom.com)
9 *
10 *********************************************************************
12 * Copyright 2000,2001,2002,2003
13 * Broadcom Corporation. All rights reserved.
15 * This software is furnished under license and may be used and
16 * copied only in accordance with the following terms and
17 * conditions. Subject to these conditions, you may download,
18 * copy, install, use, modify and distribute modified or unmodified
19 * copies of this software in source and/or binary form. No title
20 * or ownership is transferred hereby.
22 * 1) Any source code used, modified or distributed must reproduce
23 * and retain this copyright notice and list of conditions
24 * as they appear in the source file.
26 * 2) No right is granted to use any trade name, trademark, or
27 * logo of Broadcom Corporation. The "Broadcom Corporation"
28 * name may not be used to endorse or promote products derived
29 * from this software without the prior written permission of
30 * Broadcom Corporation.
32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44 * THE POSSIBILITY OF SUCH DAMAGE.
45 ********************************************************************* */
48 #include "lib_types.h"
49 #include "lib_string.h"
50 #include "lib_queue.h"
51 #include "lib_malloc.h"
52 #include "lib_printf.h"
54 #include "cfe_error.h"
55 #include "cfe_timer.h"
57 #include "ui_command.h"
58 #include "cfe.h"
60 #include "bsp_config.h"
62 #include "sbmips.h"
63 #include "sb1250_regs.h"
64 #include "sb1250_smbus.h"
65 #include "sb1250_draminit.h"
67 /*#define _PROGRAM_SPD_*/
69 /* *********************************************************************
70 * Configuration
71 ********************************************************************* */
74 /* *********************************************************************
75 * prototypes
76 ********************************************************************* */
78 int ui_init_spdcmds(void);
79 static int ui_cmd_showspd(ui_cmdline_t *cmd,int argc,char *argv[]);
81 #ifdef _PROGRAM_SPD_
82 static int ui_cmd_programspd(ui_cmdline_t *cmd,int argc,char *argv[]);
83 #endif
85 /* *********************************************************************
86 * Data
87 ********************************************************************* */
90 #define SPD_DEC_BCD 1
91 #define SPD_DEC_QTR 2
92 #define SPD_ENCODED 3
93 #define SPD_ENCODED2 4
95 typedef struct spdbyte_s {
96 char *name;
97 int spdidx;
98 int decimal;
99 char *description;
100 } spdbyte_t;
102 static spdbyte_t spdinfo[] = {
103 {"memtype",JEDEC_SPD_MEMTYPE, 0,"[2 ] Memory type"},
104 {"rows", JEDEC_SPD_ROWS, 0,"[3 ] Number of row bits"},
105 {"cols", JEDEC_SPD_COLS, 0,"[4 ] Number of column bits"},
106 {"sides", JEDEC_SPD_SIDES, 0,"[5 ] Number of sides"},
107 {"width", JEDEC_SPD_WIDTH, 0,"[6 ] Module width"},
108 {"banks", JEDEC_SPD_BANKS, 0,"[17] Number of banks"},
109 {"tCK25", JEDEC_SPD_tCK25, SPD_DEC_BCD,"[9 ] tCK value for CAS Latency 2.5"},
110 {"tCK20", JEDEC_SPD_tCK20, SPD_DEC_BCD,"[23] tCK value for CAS Latency 2.0"},
111 {"tCK10", JEDEC_SPD_tCK10, SPD_DEC_BCD,"[25] tCK value for CAS Latency 1.0"},
112 {"rfsh", JEDEC_SPD_RFSH, SPD_ENCODED,"[12] Refresh rate (KHz)"},
113 {"caslat",JEDEC_SPD_CASLATENCIES,SPD_ENCODED,"[18] CAS Latencies supported"},
114 {"attrib",JEDEC_SPD_ATTRIBUTES, SPD_ENCODED,"[21] Module attributes"},
115 {"tRAS", JEDEC_SPD_tRAS, 0,"[30]"},
116 {"tRP", JEDEC_SPD_tRP, SPD_DEC_QTR,"[27]"},
117 {"tRRD", JEDEC_SPD_tRRD, SPD_DEC_QTR,"[28]"},
118 {"tRCD", JEDEC_SPD_tRCD, SPD_DEC_QTR,"[29]"},
119 {"tRFC", JEDEC_SPD_tRFC, 0,"[42]"},
120 {"tRC", JEDEC_SPD_tRC, 0,"[41]"},
121 {NULL, 0, 0, NULL}};
124 /* *********************************************************************
125 * ui_init_spdcmds()
127 * Add SPD-specific commands to the command table
129 * Input parameters:
130 * nothing
132 * Return value:
134 ********************************************************************* */
136 int ui_init_spdcmds(void)
139 cmd_addcmd("show spd",
140 ui_cmd_showspd,
141 NULL,
142 "Display contents of memory SPD",
143 "show spd chan device",
144 "-v;Display entire SPD content in hex");
146 #ifdef _PROGRAM_SPD_
147 cmd_addcmd("program spd",
148 ui_cmd_programspd,
149 NULL,
150 "DANGER Program SPD with memory parameters DANGER",
151 "program spd chan device [ {-offset=* -byte=*} | [MEMORY_PARAMETERS] ]\n\n"
152 "This commands first reads from SPD, then change only the specified parameter.",
153 "-offset=*;Dev addr within SPD(deflt=0)|"
154 "-byte=*;Byte value if -offset used|"
155 "-memtype=*;Memory type|"
156 "-rows=*;Number of row bits|"
157 "-cols=*;Number of column bits|"
158 "-sides=*;Number of sides|"
159 "-width=*;Module width|"
160 "-banks=*;Number of banks|"
161 "-tck25=*;tCK value for CAS Latency 2.5|"
162 "-tck20=*;tCK value for CAS Latency 2.0|"
163 "-tck10=*;tCK value for CAS Latency 1.0|"
164 "-rfsh=*;Refresh rate setting|"
165 "-caslat=*;CAS Latencies supported|"
166 "-attrib=*;Module Attributes|"
167 "-tras=*;tRAS|"
168 "-trp=*;tRP|"
169 "-trrd=*;tRRD|"
170 "-trcd=*;tRCD|"
171 "-trfc=*;tRFC|"
172 "-trc=*;tRC"
174 #endif // _PROGRAM_SPD_
176 return 0;
180 /* *********************************************************************
181 * spd_smbus_init(chan)
183 * Initialize the specified SMBus channel for the temp sensor
185 * Input parameters:
186 * chan - channel # (0 or 1)
188 * Return value:
189 * nothing
190 ********************************************************************* */
192 static void spd_smbus_init(int chan)
194 uintptr_t reg;
196 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_FREQ));
198 SBWRITECSR(reg,K_SMB_FREQ_100KHZ); /* 100Khz clock */
200 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CONTROL));
202 SBWRITECSR(reg,0); /* not in direct mode, no interrupts, will poll */
206 /* *********************************************************************
207 * spd_smbus_waitready(chan)
209 * Wait until the SMBus channel is ready. We simply poll
210 * the busy bit until it clears.
212 * Input parameters:
213 * chan - channel (0 or 1)
215 * Return value:
216 * nothing
217 ********************************************************************* */
218 static int spd_smbus_waitready(int chan)
220 uintptr_t reg;
221 uint64_t status;
223 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_STATUS));
225 for (;;) {
226 status = SBREADCSR(reg);
227 if (status & M_SMB_BUSY) continue;
228 break;
231 if (status & M_SMB_ERROR) {
232 SBWRITECSR(reg,(status & M_SMB_ERROR));
233 return -1;
235 return 0;
238 /* *********************************************************************
239 * spd_smbus_read(chan,slaveaddr,devaddr)
241 * Read a byte from the chip
243 * Input parameters:
244 * chan - SMBus channel
245 * slaveaddr - SMBus slave address
246 * devaddr - byte with in the sensor device to read
248 * Return value:
249 * 0 if ok
250 * else -1
251 ********************************************************************* */
253 static int spd_smbus_read(int chan,int slaveaddr,int devaddr)
255 uintptr_t reg;
256 int err;
259 * Make sure the bus is idle (probably should
260 * ignore error here)
263 if (spd_smbus_waitready(chan) < 0) return -1;
266 * Write the device address to the controller. There are two
267 * parts, the high part goes in the "CMD" field, and the
268 * low part is the data field.
271 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CMD));
272 SBWRITECSR(reg,devaddr);
275 * Read the data byte
278 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_START));
279 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_CMD_RD1BYTE) | slaveaddr);
281 err = spd_smbus_waitready(chan);
282 if (err < 0) return err;
284 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA));
285 err = SBREADCSR(reg);
287 return (err & 0xFF);
290 /* *********************************************************************
291 * spd_smbus_write(chan,slaveaddr,devaddr,b)
293 * write a byte to the chip.
295 * Input parameters:
296 * chan - SMBus channel
297 * slaveaddr - SMBus slave address
298 * devaddr - byte within the at24c02 device to read
299 * b - byte to write
301 * Return value:
302 * 0 if ok
303 * else -1
304 ********************************************************************* */
306 #ifdef _PROGRAM_SPD_
308 static int spd_smbus_write(int chan,int slaveaddr,int devaddr,int b)
310 uintptr_t reg;
311 int err;
312 int64_t timer;
315 * Make sure the bus is idle (probably should
316 * ignore error here)
319 if (spd_smbus_waitready(chan) < 0) return -1;
322 * Write the device address to the controller. There are two
323 * parts, the high part goes in the "CMD" field, and the
324 * low part is the data field.
327 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CMD));
328 SBWRITECSR(reg,devaddr);
331 * Write the data to the controller
334 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA));
335 SBWRITECSR(reg,b);
338 * Start the command. Keep pounding on the device until it
339 * submits or the timer expires, whichever comes first. The
340 * datasheet says writes can take up to 10ms, so we'll give it 500.
343 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_START));
344 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_WR2BYTE) | slaveaddr);
347 * Wait till the SMBus interface is done
350 err = spd_smbus_waitready(chan);
351 if (err < 0) return err;
354 * Pound on the device with a current address read
355 * to poll for the write complete
358 TIMER_SET(timer,50);
359 err = -1;
361 while (!TIMER_EXPIRED(timer)) {
362 POLL();
364 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_RD1BYTE) | slaveaddr);
366 err = spd_smbus_waitready(chan);
367 if (err == 0) break;
370 return err;
373 #endif // _PROGRAM_SPD_
375 /* *********************************************************************
376 * ui_cmd_showspd(cmd,argc,argv)
378 * Show SPD contents.
380 * Input parameters:
381 * cmd - command structure
382 * argc,argv - parameters
384 * Return value:
385 * -1 if error occured.
386 ********************************************************************* */
388 static int ui_cmd_showspd(ui_cmdline_t *cmd,int argc,char *argv[])
390 int chan,dev;
391 char *x;
392 int idx;
393 int b;
395 x = cmd_getarg(cmd,0);
396 if (!x) return ui_showusage(cmd);
397 chan = lib_atoi(x);
398 if ((chan < 0) || (chan > 1)) return ui_showusage(cmd);
400 x = cmd_getarg(cmd,1);
401 if (!x) return ui_showusage(cmd);
402 dev = lib_atoi(x);
404 spd_smbus_init(chan);
406 if (cmd_sw_isset(cmd,"-v")) {
407 for (idx = 0; idx < 32; idx++) {
408 b = spd_smbus_read(chan,dev,idx);
409 if (b < 0) {
410 printf("Could not read SPD at %d/0x%02X\n",chan,dev);
411 return -1;
413 printf("SPD[%2d] = %02X\n",idx,b);
416 else {
417 spdbyte_t *s = spdinfo;
418 char buf[20];
420 while (s->name) {
421 b = spd_smbus_read(chan,dev,s->spdidx);
422 if (b < 0) {
423 printf("Could not read SPD at %d/0x%02X\n",chan,dev);
424 return -1;
427 switch (s->decimal) {
428 case 0:
429 sprintf(buf,"%02X (%u)",b,b);
430 break;
431 case SPD_DEC_BCD:
432 sprintf(buf,"%d.%d",(b >> 4), b & 0x0F);
433 break;
434 case SPD_ENCODED:
435 sprintf(buf,"0x%02X",b);
436 break;
437 case SPD_DEC_QTR:
438 sprintf(buf,"%d.%02d",(b >> 2), (b & 0x03) *25);;
439 break;
442 printf("%8s = %15s | %30s\n",s->name,buf,s->description);
443 s++;
448 return 0;
451 /* *********************************************************************
452 * ui_cmd_programspd(cmd,argc,argv)
454 * Program SPD with memory parameters.
456 * Input parameters:
457 * cmd - command structure
458 * argc,argv - parameters
460 * Return value:
461 * -1 if error occured.
462 ********************************************************************* */
464 #ifdef _PROGRAM_SPD_
466 static int ui_cmd_programspd(ui_cmdline_t *cmd,int argc,char *argv[])
468 int chan,dev;
469 char *x;
470 unsigned char spd[JEDEC_SPD_MAX+1];
471 int res;
472 int idx=0;
473 int offset=0;
475 x = cmd_getarg(cmd,0);
476 if (!x) return ui_showusage(cmd);
477 chan = lib_atoi(x);
478 if ((chan < 0) || (chan > 1)) return ui_showusage(cmd);
480 x = cmd_getarg(cmd,1);
481 if (!x) return ui_showusage(cmd);
482 dev = lib_atoi(x);
484 spd_smbus_init(chan);
486 /* Save what's on the SPD */
487 idx = 0;
488 while (idx <= JEDEC_SPD_MAX) {
489 res = spd_smbus_read(chan,dev,idx);
490 if (res < 0) {
491 printf("Could not read byte %d at %d/0x%02X\n",idx,chan,dev);
492 return -1;
494 spd[idx] = res;
495 idx++;
498 /* Get user values */
500 x = NULL;
501 cmd_sw_value(cmd,"-offset",&x);
502 if (x != NULL) offset = lib_atoi(x);
504 x = NULL;
505 cmd_sw_value(cmd,"-byte",&x);
506 if (x != NULL) spd[offset] = lib_atoi(x);
508 x = NULL;
509 cmd_sw_value(cmd,"-memtype",&x);
510 if (x != NULL) spd[JEDEC_SPD_MEMTYPE] = lib_atoi(x);
512 x = NULL;
513 cmd_sw_value(cmd,"-rows",&x);
514 if (x != NULL) spd[JEDEC_SPD_ROWS] = lib_atoi(x);
516 x = NULL;
517 cmd_sw_value(cmd,"-cols",&x);
518 if (x != NULL) spd[JEDEC_SPD_COLS] = lib_atoi(x);
520 x = NULL;
521 cmd_sw_value(cmd,"-sides",&x);
522 if (x != NULL) spd[JEDEC_SPD_SIDES] = lib_atoi(x);
524 x = NULL;
525 cmd_sw_value(cmd,"-width",&x);
526 if (x != NULL) spd[JEDEC_SPD_WIDTH] = lib_atoi(x);
528 x = NULL;
529 cmd_sw_value(cmd,"-banks",&x);
530 if (x != NULL) spd[JEDEC_SPD_BANKS] = lib_atoi(x);
532 x = NULL;
533 cmd_sw_value(cmd,"-tck25",&x);
534 if (x != NULL) spd[JEDEC_SPD_tCK25] = lib_atoi(x);
536 x = NULL;
537 cmd_sw_value(cmd,"-tck20",&x);
538 if (x != NULL) spd[JEDEC_SPD_tCK20] = lib_atoi(x);
540 x = NULL;
541 cmd_sw_value(cmd,"-tck10",&x);
542 if (x != NULL) spd[JEDEC_SPD_tCK10] = lib_atoi(x);
544 x = NULL;
545 cmd_sw_value(cmd,"-rfsh",&x);
546 if (x != NULL) spd[JEDEC_SPD_RFSH] = lib_atoi(x);
548 x = NULL;
549 cmd_sw_value(cmd,"-caslat",&x);
550 if (x != NULL) spd[JEDEC_SPD_CASLATENCIES] = lib_atoi(x);
552 x = NULL;
553 cmd_sw_value(cmd,"-attrib",&x);
554 if (x != NULL) spd[JEDEC_SPD_ATTRIBUTES] = lib_atoi(x);
556 x = NULL;
557 cmd_sw_value(cmd,"-tras",&x);
558 if (x != NULL) spd[JEDEC_SPD_tRAS] = lib_atoi(x);
560 x = NULL;
561 cmd_sw_value(cmd,"-trp",&x);
562 if (x != NULL) spd[JEDEC_SPD_tRP] = lib_atoi(x);
564 x = NULL;
565 cmd_sw_value(cmd,"-trrd",&x);
566 if (x != NULL) spd[JEDEC_SPD_tRRD] = lib_atoi(x);
568 x = NULL;
569 cmd_sw_value(cmd,"-trcd",&x);
570 if (x != NULL) spd[JEDEC_SPD_tRCD] = lib_atoi(x);
572 x = NULL;
573 cmd_sw_value(cmd,"-trfc",&x);
574 if (x != NULL) spd[JEDEC_SPD_tRFC] = lib_atoi(x);
576 x = NULL;
577 cmd_sw_value(cmd,"-trc",&x);
578 if (x != NULL) spd[JEDEC_SPD_tRC] = lib_atoi(x);
580 /* Program SPD */
581 idx = 0;
582 while (idx <= JEDEC_SPD_MAX) {
583 res = spd_smbus_write(chan,dev,idx,spd[idx]);
584 if (res < 0) {
585 printf("Could not write byte %d at %d/0x%02X\n",idx,chan,dev);
586 return -1;
588 idx++;
591 return 0;
594 #endif // _PROGRAM_SPD_