Commit 81a8824f2e751f31249bc23e166c09d82e287887

Authored by wdenk
1 parent 1775979a28

Initial revision

Showing 2 changed files with 1041 additions and 0 deletions Side-by-side Diff

  1 +/*
  2 + * (C) Copyright 2001
  3 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
  4 + *
  5 + * See file CREDITS for list of people who contributed to this
  6 + * project.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + */
  23 +
  24 +/*
  25 + * I2C Functions similar to the standard memory functions.
  26 + *
  27 + * There are several parameters in many of the commands that bear further
  28 + * explanations:
  29 + *
  30 + * Two of the commands (imm and imw) take a byte/word/long modifier
  31 + * (e.g. imm.w specifies the word-length modifier). This was done to
  32 + * allow manipulating word-length registers. It was not done on any other
  33 + * commands because it was not deemed useful.
  34 + *
  35 + * {i2c_chip} is the I2C chip address (the first byte sent on the bus).
  36 + * Each I2C chip on the bus has a unique address. On the I2C data bus,
  37 + * the address is the upper seven bits and the LSB is the "read/write"
  38 + * bit. Note that the {i2c_chip} address specified on the command
  39 + * line is not shifted up: e.g. a typical EEPROM memory chip may have
  40 + * an I2C address of 0x50, but the data put on the bus will be 0xA0
  41 + * for write and 0xA1 for read. This "non shifted" address notation
  42 + * matches at least half of the data sheets :-/.
  43 + *
  44 + * {addr} is the address (or offset) within the chip. Small memory
  45 + * chips have 8 bit addresses. Large memory chips have 16 bit
  46 + * addresses. Other memory chips have 9, 10, or 11 bit addresses.
  47 + * Many non-memory chips have multiple registers and {addr} is used
  48 + * as the register index. Some non-memory chips have only one register
  49 + * and therefore don't need any {addr} parameter.
  50 + *
  51 + * The default {addr} parameter is one byte (.1) which works well for
  52 + * memories and registers with 8 bits of address space.
  53 + *
  54 + * You can specify the length of the {addr} field with the optional .0,
  55 + * .1, or .2 modifier (similar to the .b, .w, .l modifier). If you are
  56 + * manipulating a single register device which doesn't use an address
  57 + * field, use "0.0" for the address and the ".0" length field will
  58 + * suppress the address in the I2C data stream. This also works for
  59 + * successive reads using the I2C auto-incrementing memory pointer.
  60 + *
  61 + * If you are manipulating a large memory with 2-byte addresses, use
  62 + * the .2 address modifier, e.g. 210.2 addresses location 528 (decimal).
  63 + *
  64 + * Then there are the unfortunate memory chips that spill the most
  65 + * significant 1, 2, or 3 bits of address into the chip address byte.
  66 + * This effectively makes one chip (logically) look like 2, 4, or
  67 + * 8 chips. This is handled (awkwardly) by #defining
  68 + * CFG_I2C_EEPROM_ADDR_OVERFLOW and using the .1 modifier on the
  69 + * {addr} field (since .1 is the default, it doesn't actually have to
  70 + * be specified). Examples: given a memory chip at I2C chip address
  71 + * 0x50, the following would happen...
  72 + * imd 50 0 10 display 16 bytes starting at 0x000
  73 + * On the bus: <S> A0 00 <E> <S> A1 <rd> ... <rd>
  74 + * imd 50 100 10 display 16 bytes starting at 0x100
  75 + * On the bus: <S> A2 00 <E> <S> A3 <rd> ... <rd>
  76 + * imd 50 210 10 display 16 bytes starting at 0x210
  77 + * On the bus: <S> A4 10 <E> <S> A5 <rd> ... <rd>
  78 + * This is awfully ugly. It would be nice if someone would think up
  79 + * a better way of handling this.
  80 + *
  81 + * Adapted from cmd_mem.c which is copyright Wolfgang Denk (wd@denx.de).
  82 + */
  83 +
  84 +#include <common.h>
  85 +#include <command.h>
  86 +#include <cmd_i2c.h>
  87 +#include <i2c.h>
  88 +#include <asm/byteorder.h>
  89 +
  90 +#if (CONFIG_COMMANDS & CFG_CMD_I2C)
  91 +
  92 +
  93 +/* Display values from last command.
  94 + * Memory modify remembered values are different from display memory.
  95 + */
  96 +static uchar i2c_dp_last_chip;
  97 +static uint i2c_dp_last_addr;
  98 +static uint i2c_dp_last_alen;
  99 +static uint i2c_dp_last_length = 0x10;
  100 +
  101 +static uchar i2c_mm_last_chip;
  102 +static uint i2c_mm_last_addr;
  103 +static uint i2c_mm_last_alen;
  104 +
  105 +#if defined(CFG_I2C_NOPROBES)
  106 +static uchar i2c_no_probes[] = CFG_I2C_NOPROBES;
  107 +#endif
  108 +
  109 +static int
  110 +mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]);
  111 +extern int cmd_get_data_size(char* arg, int default_size);
  112 +
  113 +/*
  114 + * Syntax:
  115 + * imd {i2c_chip} {addr}{.0, .1, .2} {len}
  116 + */
  117 +#define DISP_LINE_LEN 16
  118 +
  119 +int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  120 +{
  121 + u_char chip;
  122 + uint addr, alen, length;
  123 + int j, nbytes, linebytes;
  124 +
  125 + /* We use the last specified parameters, unless new ones are
  126 + * entered.
  127 + */
  128 + chip = i2c_dp_last_chip;
  129 + addr = i2c_dp_last_addr;
  130 + alen = i2c_dp_last_alen;
  131 + length = i2c_dp_last_length;
  132 +
  133 + if (argc < 3) {
  134 + printf ("Usage:\n%s\n", cmdtp->usage);
  135 + return 1;
  136 + }
  137 +
  138 + if ((flag & CMD_FLAG_REPEAT) == 0) {
  139 + /*
  140 + * New command specified.
  141 + */
  142 + alen = 1;
  143 +
  144 + /*
  145 + * I2C chip address
  146 + */
  147 + chip = simple_strtoul(argv[1], NULL, 16);
  148 +
  149 + /*
  150 + * I2C data address within the chip. This can be 1 or
  151 + * 2 bytes long. Some day it might be 3 bytes long :-).
  152 + */
  153 + addr = simple_strtoul(argv[2], NULL, 16);
  154 + alen = 1;
  155 + for(j = 0; j < 8; j++) {
  156 + if (argv[2][j] == '.') {
  157 + alen = argv[2][j+1] - '0';
  158 + if (alen > 4) {
  159 + printf ("Usage:\n%s\n", cmdtp->usage);
  160 + return 1;
  161 + }
  162 + break;
  163 + } else if (argv[2][j] == '\0') {
  164 + break;
  165 + }
  166 + }
  167 +
  168 + /*
  169 + * If another parameter, it is the length to display.
  170 + * Length is the number of objects, not number of bytes.
  171 + */
  172 + if (argc > 3)
  173 + length = simple_strtoul(argv[3], NULL, 16);
  174 + }
  175 +
  176 + /*
  177 + * Print the lines.
  178 + *
  179 + * We buffer all read data, so we can make sure data is read only
  180 + * once.
  181 + */
  182 + nbytes = length;
  183 + do {
  184 + unsigned char linebuf[DISP_LINE_LEN];
  185 + unsigned char *cp;
  186 +
  187 + linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
  188 +
  189 + if(i2c_read(chip, addr, alen, linebuf, linebytes) != 0) {
  190 + printf("Error reading the chip.\n");
  191 + } else {
  192 + printf("%04x:", addr);
  193 + cp = linebuf;
  194 + for (j=0; j<linebytes; j++) {
  195 + printf(" %02x", *cp++);
  196 + addr++;
  197 + }
  198 + printf(" ");
  199 + cp = linebuf;
  200 + for (j=0; j<linebytes; j++) {
  201 + if ((*cp < 0x20) || (*cp > 0x7e))
  202 + printf(".");
  203 + else
  204 + printf("%c", *cp);
  205 + cp++;
  206 + }
  207 + printf("\n");
  208 + }
  209 + nbytes -= linebytes;
  210 + } while (nbytes > 0);
  211 +
  212 + i2c_dp_last_chip = chip;
  213 + i2c_dp_last_addr = addr;
  214 + i2c_dp_last_alen = alen;
  215 + i2c_dp_last_length = length;
  216 +
  217 + return 0;
  218 +}
  219 +
  220 +int do_i2c_mm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  221 +{
  222 + return mod_i2c_mem (cmdtp, 1, flag, argc, argv);
  223 +}
  224 +
  225 +
  226 +int do_i2c_nm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  227 +{
  228 + return mod_i2c_mem (cmdtp, 0, flag, argc, argv);
  229 +}
  230 +
  231 +/* Write (fill) memory
  232 + *
  233 + * Syntax:
  234 + * imw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}]
  235 + */
  236 +int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  237 +{
  238 + uchar chip;
  239 + ulong addr;
  240 + uint alen;
  241 + uchar byte;
  242 + int count;
  243 + int j;
  244 +
  245 + if ((argc < 4) || (argc > 5)) {
  246 + printf ("Usage:\n%s\n", cmdtp->usage);
  247 + return 1;
  248 + }
  249 +
  250 + /*
  251 + * Chip is always specified.
  252 + */
  253 + chip = simple_strtoul(argv[1], NULL, 16);
  254 +
  255 + /*
  256 + * Address is always specified.
  257 + */
  258 + addr = simple_strtoul(argv[2], NULL, 16);
  259 + alen = 1;
  260 + for(j = 0; j < 8; j++) {
  261 + if (argv[2][j] == '.') {
  262 + alen = argv[2][j+1] - '0';
  263 + if(alen > 4) {
  264 + printf ("Usage:\n%s\n", cmdtp->usage);
  265 + return 1;
  266 + }
  267 + break;
  268 + } else if (argv[2][j] == '\0') {
  269 + break;
  270 + }
  271 + }
  272 +
  273 + /*
  274 + * Value to write is always specified.
  275 + */
  276 + byte = simple_strtoul(argv[3], NULL, 16);
  277 +
  278 + /*
  279 + * Optional count
  280 + */
  281 + if(argc == 5) {
  282 + count = simple_strtoul(argv[4], NULL, 16);
  283 + } else {
  284 + count = 1;
  285 + }
  286 +
  287 + while (count-- > 0) {
  288 + if(i2c_write(chip, addr++, alen, &byte, 1) != 0) {
  289 + printf("Error writing the chip.\n");
  290 + }
  291 + /*
  292 + * Wait for the write to complete. The write can take
  293 + * up to 10mSec (we allow a little more time).
  294 + *
  295 + * On some chips, while the write is in progress, the
  296 + * chip doesn't respond. This apparently isn't a
  297 + * universal feature so we don't take advantage of it.
  298 + */
  299 + udelay(11000);
  300 +#if 0
  301 + for(timeout = 0; timeout < 10; timeout++) {
  302 + udelay(2000);
  303 + if(i2c_probe(chip) == 0)
  304 + break;
  305 + }
  306 +#endif
  307 + }
  308 +
  309 + return (0);
  310 +}
  311 +
  312 +
  313 +/* Calculate a CRC on memory
  314 + *
  315 + * Syntax:
  316 + * icrc32 {i2c_chip} {addr}{.0, .1, .2} {count}
  317 + */
  318 +int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  319 +{
  320 + uchar chip;
  321 + ulong addr;
  322 + uint alen;
  323 + int count;
  324 + uchar byte;
  325 + ulong crc;
  326 + ulong err;
  327 + int j;
  328 +
  329 + if (argc < 4) {
  330 + printf ("Usage:\n%s\n", cmdtp->usage);
  331 + return 1;
  332 + }
  333 +
  334 + /*
  335 + * Chip is always specified.
  336 + */
  337 + chip = simple_strtoul(argv[1], NULL, 16);
  338 +
  339 + /*
  340 + * Address is always specified.
  341 + */
  342 + addr = simple_strtoul(argv[2], NULL, 16);
  343 + alen = 1;
  344 + for(j = 0; j < 8; j++) {
  345 + if (argv[2][j] == '.') {
  346 + alen = argv[2][j+1] - '0';
  347 + if(alen > 4) {
  348 + printf ("Usage:\n%s\n", cmdtp->usage);
  349 + return 1;
  350 + }
  351 + break;
  352 + } else if (argv[2][j] == '\0') {
  353 + break;
  354 + }
  355 + }
  356 +
  357 + /*
  358 + * Count is always specified
  359 + */
  360 + count = simple_strtoul(argv[3], NULL, 16);
  361 +
  362 + printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1);
  363 + /*
  364 + * CRC a byte at a time. This is going to be slooow, but hey, the
  365 + * memories are small and slow too so hopefully nobody notices.
  366 + */
  367 + crc = 0;
  368 + err = 0;
  369 + while(count-- > 0) {
  370 + if(i2c_read(chip, addr, alen, &byte, 1) != 0) {
  371 + err++;
  372 + }
  373 + crc = crc32 (crc, &byte, 1);
  374 + addr++;
  375 + }
  376 + if(err > 0)
  377 + {
  378 + printf("Error reading the chip,\n");
  379 + } else {
  380 + printf ("%08lx\n", crc);
  381 + }
  382 +
  383 + return 0;
  384 +}
  385 +
  386 +
  387 +/* Modify memory.
  388 + *
  389 + * Syntax:
  390 + * imm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
  391 + * inm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
  392 + */
  393 +
  394 +static int
  395 +mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
  396 +{
  397 + uchar chip;
  398 + ulong addr;
  399 + uint alen;
  400 + ulong data;
  401 + int size = 1;
  402 + int nbytes;
  403 + int j;
  404 + extern char console_buffer[];
  405 +
  406 + if (argc != 3) {
  407 + printf ("Usage:\n%s\n", cmdtp->usage);
  408 + return 1;
  409 + }
  410 +
  411 +#ifdef CONFIG_BOOT_RETRY_TIME
  412 + reset_cmd_timeout(); /* got a good command to get here */
  413 +#endif
  414 + /*
  415 + * We use the last specified parameters, unless new ones are
  416 + * entered.
  417 + */
  418 + chip = i2c_mm_last_chip;
  419 + addr = i2c_mm_last_addr;
  420 + alen = i2c_mm_last_alen;
  421 +
  422 + if ((flag & CMD_FLAG_REPEAT) == 0) {
  423 + /*
  424 + * New command specified. Check for a size specification.
  425 + * Defaults to byte if no or incorrect specification.
  426 + */
  427 + size = cmd_get_data_size(argv[0], 1);
  428 +
  429 + /*
  430 + * Chip is always specified.
  431 + */
  432 + chip = simple_strtoul(argv[1], NULL, 16);
  433 +
  434 + /*
  435 + * Address is always specified.
  436 + */
  437 + addr = simple_strtoul(argv[2], NULL, 16);
  438 + alen = 1;
  439 + for(j = 0; j < 8; j++) {
  440 + if (argv[2][j] == '.') {
  441 + alen = argv[2][j+1] - '0';
  442 + if(alen > 4) {
  443 + printf ("Usage:\n%s\n", cmdtp->usage);
  444 + return 1;
  445 + }
  446 + break;
  447 + } else if (argv[2][j] == '\0') {
  448 + break;
  449 + }
  450 + }
  451 + }
  452 +
  453 + /*
  454 + * Print the address, followed by value. Then accept input for
  455 + * the next value. A non-converted value exits.
  456 + */
  457 + do {
  458 + printf("%08lx:", addr);
  459 + if(i2c_read(chip, addr, alen, (char *)&data, size) != 0) {
  460 + printf("\nError reading the chip,\n");
  461 + } else {
  462 + data = cpu_to_be32(data);
  463 + if(size == 1) {
  464 + printf(" %02lx", (data >> 24) & 0x000000FF);
  465 + } else if(size == 2) {
  466 + printf(" %04lx", (data >> 16) & 0x0000FFFF);
  467 + } else {
  468 + printf(" %08lx", data);
  469 + }
  470 + }
  471 +
  472 + nbytes = readline (" ? ");
  473 + if (nbytes == 0) {
  474 + /*
  475 + * <CR> pressed as only input, don't modify current
  476 + * location and move to next.
  477 + */
  478 + if (incrflag)
  479 + addr += size;
  480 + nbytes = size;
  481 +#ifdef CONFIG_BOOT_RETRY_TIME
  482 + reset_cmd_timeout(); /* good enough to not time out */
  483 +#endif
  484 + }
  485 +#ifdef CONFIG_BOOT_RETRY_TIME
  486 + else if (nbytes == -2) {
  487 + break; /* timed out, exit the command */
  488 + }
  489 +#endif
  490 + else {
  491 + char *endp;
  492 +
  493 + data = simple_strtoul(console_buffer, &endp, 16);
  494 + if(size == 1) {
  495 + data = data << 24;
  496 + } else if(size == 2) {
  497 + data = data << 16;
  498 + }
  499 + data = be32_to_cpu(data);
  500 + nbytes = endp - console_buffer;
  501 + if (nbytes) {
  502 +#ifdef CONFIG_BOOT_RETRY_TIME
  503 + /*
  504 + * good enough to not time out
  505 + */
  506 + reset_cmd_timeout();
  507 +#endif
  508 + if(i2c_write(chip, addr, alen, (char *)&data, size) != 0) {
  509 + printf("Error writing the chip.\n");
  510 + }
  511 + if (incrflag)
  512 + addr += size;
  513 + }
  514 + }
  515 + } while (nbytes);
  516 +
  517 + chip = i2c_mm_last_chip;
  518 + addr = i2c_mm_last_addr;
  519 + alen = i2c_mm_last_alen;
  520 +
  521 + return 0;
  522 +}
  523 +
  524 +/*
  525 + * Syntax:
  526 + * iprobe {addr}{.0, .1, .2}
  527 + */
  528 +int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  529 +{
  530 + int j;
  531 +#if defined(CFG_I2C_NOPROBES)
  532 + int k, skip;
  533 +#endif
  534 +
  535 + printf("Valid chip addresses:");
  536 + for(j = 0; j < 128; j++) {
  537 +#if defined(CFG_I2C_NOPROBES)
  538 + skip = 0;
  539 + for (k = 0; k < sizeof(i2c_no_probes); k++){
  540 + if (j == i2c_no_probes[k]){
  541 + skip = 1;
  542 + break;
  543 + }
  544 + }
  545 + if (skip)
  546 + continue;
  547 +#endif
  548 + if(i2c_probe(j) == 0) {
  549 + printf(" %02X", j);
  550 + }
  551 + }
  552 + printf("\n");
  553 +
  554 +#if defined(CFG_I2C_NOPROBES)
  555 + puts ("Excluded chip addresses:");
  556 + for( k = 0; k < sizeof(i2c_no_probes); k++ )
  557 + printf(" %02X", i2c_no_probes[k] );
  558 + puts ("\n");
  559 +#endif
  560 +
  561 + return 0;
  562 +}
  563 +
  564 +
  565 +/*
  566 + * Syntax:
  567 + * iloop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}]
  568 + * {length} - Number of bytes to read
  569 + * {delay} - A DECIMAL number and defaults to 1000 uSec
  570 + */
  571 +int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  572 +{
  573 + u_char chip;
  574 + ulong alen;
  575 + uint addr;
  576 + uint length;
  577 + u_char bytes[16];
  578 + int delay;
  579 + int j;
  580 +
  581 + if (argc < 3) {
  582 + printf ("Usage:\n%s\n", cmdtp->usage);
  583 + return 1;
  584 + }
  585 +
  586 + /*
  587 + * Chip is always specified.
  588 + */
  589 + chip = simple_strtoul(argv[1], NULL, 16);
  590 +
  591 + /*
  592 + * Address is always specified.
  593 + */
  594 + addr = simple_strtoul(argv[2], NULL, 16);
  595 + alen = 1;
  596 + for(j = 0; j < 8; j++) {
  597 + if (argv[2][j] == '.') {
  598 + alen = argv[2][j+1] - '0';
  599 + if (alen > 4) {
  600 + printf ("Usage:\n%s\n", cmdtp->usage);
  601 + return 1;
  602 + }
  603 + break;
  604 + } else if (argv[2][j] == '\0') {
  605 + break;
  606 + }
  607 + }
  608 +
  609 + /*
  610 + * Length is the number of objects, not number of bytes.
  611 + */
  612 + length = 1;
  613 + length = simple_strtoul(argv[3], NULL, 16);
  614 + if(length > sizeof(bytes)) {
  615 + length = sizeof(bytes);
  616 + }
  617 +
  618 + /*
  619 + * The delay time (uSec) is optional.
  620 + */
  621 + delay = 1000;
  622 + if (argc > 3) {
  623 + delay = simple_strtoul(argv[4], NULL, 10);
  624 + }
  625 + /*
  626 + * Run the loop...
  627 + */
  628 + while(1) {
  629 + if(i2c_read(chip, addr, alen, bytes, length) != 0) {
  630 + printf("Error reading the chip.\n");
  631 + }
  632 + udelay(delay);
  633 + }
  634 +
  635 + /* NOTREACHED */
  636 + return 0;
  637 +}
  638 +
  639 +
  640 +/*
  641 + * The SDRAM command is separately configured because many
  642 + * (most?) embedded boards don't use SDRAM DIMMs.
  643 + */
  644 +#if (CONFIG_COMMANDS & CFG_CMD_SDRAM)
  645 +
  646 +/*
  647 + * Syntax:
  648 + * sdram {i2c_chip}
  649 + */
  650 +int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  651 +{
  652 + u_char chip;
  653 + u_char data[128];
  654 + u_char cksum;
  655 + int j;
  656 +
  657 + if (argc < 2) {
  658 + printf ("Usage:\n%s\n", cmdtp->usage);
  659 + return 1;
  660 + }
  661 + /*
  662 + * Chip is always specified.
  663 + */
  664 + chip = simple_strtoul(argv[1], NULL, 16);
  665 +
  666 + if(i2c_read(chip, 0, 1, data, sizeof(data)) != 0) {
  667 + printf("No SDRAM Serial Presence Detect found.\n");
  668 + return 1;
  669 + }
  670 +
  671 + cksum = 0;
  672 + for (j = 0; j < 63; j++) {
  673 + cksum += data[j];
  674 + }
  675 + if(cksum != data[63]) {
  676 + printf ("WARNING: Configuration data checksum failure:\n"
  677 + " is 0x%02x, calculated 0x%02x\n",
  678 + data[63], cksum);
  679 + }
  680 + printf("SPD data revision %d.%d\n",
  681 + (data[62] >> 4) & 0x0F, data[62] & 0x0F);
  682 + printf("Bytes used 0x%02X\n", data[0]);
  683 + printf("Serial memory size 0x%02X\n", 1 << data[1]);
  684 + printf("Memory type ");
  685 + switch(data[2]) {
  686 + case 2: printf("EDO\n"); break;
  687 + case 4: printf("SDRAM\n"); break;
  688 + default: printf("unknown\n"); break;
  689 + }
  690 + printf("Row address bits ");
  691 + if((data[3] & 0x00F0) == 0) {
  692 + printf("%d\n", data[3] & 0x0F);
  693 + } else {
  694 + printf("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F);
  695 + }
  696 + printf("Column address bits ");
  697 + if((data[4] & 0x00F0) == 0) {
  698 + printf("%d\n", data[4] & 0x0F);
  699 + } else {
  700 + printf("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F);
  701 + }
  702 + printf("Module rows %d\n", data[5]);
  703 + printf("Module data width %d bits\n", (data[7] << 8) | data[6]);
  704 + printf("Interface signal levels ");
  705 + switch(data[8]) {
  706 + case 0: printf("5.0v/TTL\n"); break;
  707 + case 1: printf("LVTTL\n"); break;
  708 + case 2: printf("HSTL 1.5\n"); break;
  709 + case 3: printf("SSTL 3.3\n"); break;
  710 + case 4: printf("SSTL 2.5\n"); break;
  711 + default: printf("unknown\n"); break;
  712 + }
  713 + printf("SDRAM cycle time %d.%d nS\n",
  714 + (data[9] >> 4) & 0x0F, data[9] & 0x0F);
  715 + printf("SDRAM access time %d.%d nS\n",
  716 + (data[10] >> 4) & 0x0F, data[10] & 0x0F);
  717 + printf("EDC configuration ");
  718 + switch(data[11]) {
  719 + case 0: printf("None\n"); break;
  720 + case 1: printf("Parity\n"); break;
  721 + case 2: printf("ECC\n"); break;
  722 + default: printf("unknown\n"); break;
  723 + }
  724 + if((data[12] & 0x80) == 0) {
  725 + printf("No self refresh, rate ");
  726 + } else {
  727 + printf("Self refresh, rate ");
  728 + }
  729 + switch(data[12] & 0x7F) {
  730 + case 0: printf("15.625uS\n"); break;
  731 + case 1: printf("3.9uS\n"); break;
  732 + case 2: printf("7.8uS\n"); break;
  733 + case 3: printf("31.3uS\n"); break;
  734 + case 4: printf("62.5uS\n"); break;
  735 + case 5: printf("125uS\n"); break;
  736 + default: printf("unknown\n"); break;
  737 + }
  738 + printf("SDRAM width (primary) %d\n", data[13] & 0x7F);
  739 + if((data[13] & 0x80) != 0) {
  740 + printf(" (second bank) %d\n",
  741 + 2 * (data[13] & 0x7F));
  742 + }
  743 + if(data[14] != 0) {
  744 + printf("EDC width %d\n",
  745 + data[14] & 0x7F);
  746 + if((data[14] & 0x80) != 0) {
  747 + printf(" (second bank) %d\n",
  748 + 2 * (data[14] & 0x7F));
  749 + }
  750 + }
  751 + printf("Min clock delay, back-to-back random column addresses %d\n",
  752 + data[15]);
  753 + printf("Burst length(s) ");
  754 + if(data[16] & 0x80) printf(" Page");
  755 + if(data[16] & 0x08) printf(" 8");
  756 + if(data[16] & 0x04) printf(" 4");
  757 + if(data[16] & 0x02) printf(" 2");
  758 + if(data[16] & 0x01) printf(" 1");
  759 + printf("\n");
  760 + printf("Number of banks %d\n", data[17]);
  761 + printf("CAS latency(s) ");
  762 + if(data[18] & 0x80) printf(" TBD");
  763 + if(data[18] & 0x40) printf(" 7");
  764 + if(data[18] & 0x20) printf(" 6");
  765 + if(data[18] & 0x10) printf(" 5");
  766 + if(data[18] & 0x08) printf(" 4");
  767 + if(data[18] & 0x04) printf(" 3");
  768 + if(data[18] & 0x02) printf(" 2");
  769 + if(data[18] & 0x01) printf(" 1");
  770 + printf("\n");
  771 + printf("CS latency(s) ");
  772 + if(data[19] & 0x80) printf(" TBD");
  773 + if(data[19] & 0x40) printf(" 6");
  774 + if(data[19] & 0x20) printf(" 5");
  775 + if(data[19] & 0x10) printf(" 4");
  776 + if(data[19] & 0x08) printf(" 3");
  777 + if(data[19] & 0x04) printf(" 2");
  778 + if(data[19] & 0x02) printf(" 1");
  779 + if(data[19] & 0x01) printf(" 0");
  780 + printf("\n");
  781 + printf("WE latency(s) ");
  782 + if(data[20] & 0x80) printf(" TBD");
  783 + if(data[20] & 0x40) printf(" 6");
  784 + if(data[20] & 0x20) printf(" 5");
  785 + if(data[20] & 0x10) printf(" 4");
  786 + if(data[20] & 0x08) printf(" 3");
  787 + if(data[20] & 0x04) printf(" 2");
  788 + if(data[20] & 0x02) printf(" 1");
  789 + if(data[20] & 0x01) printf(" 0");
  790 + printf("\n");
  791 + printf("Module attributes:\n");
  792 + if(!data[21]) printf(" (none)\n");
  793 + if(data[21] & 0x80) printf(" TBD (bit 7)\n");
  794 + if(data[21] & 0x40) printf(" Redundant row address\n");
  795 + if(data[21] & 0x20) printf(" Differential clock input\n");
  796 + if(data[21] & 0x10) printf(" Registerd DQMB inputs\n");
  797 + if(data[21] & 0x08) printf(" Buffered DQMB inputs\n");
  798 + if(data[21] & 0x04) printf(" On-card PLL\n");
  799 + if(data[21] & 0x02) printf(" Registered address/control lines\n");
  800 + if(data[21] & 0x01) printf(" Buffered address/control lines\n");
  801 + printf("Device attributes:\n");
  802 + if(data[22] & 0x80) printf(" TBD (bit 7)\n");
  803 + if(data[22] & 0x40) printf(" TBD (bit 6)\n");
  804 + if(data[22] & 0x20) printf(" Upper Vcc tolerance 5%%\n");
  805 + else printf(" Upper Vcc tolerance 10%%\n");
  806 + if(data[22] & 0x10) printf(" Lower Vcc tolerance 5%%\n");
  807 + else printf(" Lower Vcc tolerance 10%%\n");
  808 + if(data[22] & 0x08) printf(" Supports write1/read burst\n");
  809 + if(data[22] & 0x04) printf(" Supports precharge all\n");
  810 + if(data[22] & 0x02) printf(" Supports auto precharge\n");
  811 + if(data[22] & 0x01) printf(" Supports early RAS# precharge\n");
  812 + printf("SDRAM cycle time (2nd highest CAS latency) %d.%d nS\n",
  813 + (data[23] >> 4) & 0x0F, data[23] & 0x0F);
  814 + printf("SDRAM access from clock (2nd highest CAS latency) %d.%d nS\n",
  815 + (data[24] >> 4) & 0x0F, data[24] & 0x0F);
  816 + printf("SDRAM cycle time (3rd highest CAS latency) %d.%d nS\n",
  817 + (data[25] >> 4) & 0x0F, data[25] & 0x0F);
  818 + printf("SDRAM access from clock (3rd highest CAS latency) %d.%d nS\n",
  819 + (data[26] >> 4) & 0x0F, data[26] & 0x0F);
  820 + printf("Minimum row precharge %d nS\n", data[27]);
  821 + printf("Row active to row active min %d nS\n", data[28]);
  822 + printf("RAS to CAS delay min %d nS\n", data[29]);
  823 + printf("Minimum RAS pulse width %d nS\n", data[30]);
  824 + printf("Density of each row ");
  825 + if(data[31] & 0x80) printf(" 512MByte");
  826 + if(data[31] & 0x40) printf(" 256MByte");
  827 + if(data[31] & 0x20) printf(" 128MByte");
  828 + if(data[31] & 0x10) printf(" 64MByte");
  829 + if(data[31] & 0x08) printf(" 32MByte");
  830 + if(data[31] & 0x04) printf(" 16MByte");
  831 + if(data[31] & 0x02) printf(" 8MByte");
  832 + if(data[31] & 0x01) printf(" 4MByte");
  833 + printf("\n");
  834 + printf("Command and Address setup %c%d.%d nS\n",
  835 + (data[32] & 0x80) ? '-' : '+',
  836 + (data[32] >> 4) & 0x07, data[32] & 0x0F);
  837 + printf("Command and Address hold %c%d.%d nS\n",
  838 + (data[33] & 0x80) ? '-' : '+',
  839 + (data[33] >> 4) & 0x07, data[33] & 0x0F);
  840 + printf("Data signal input setup %c%d.%d nS\n",
  841 + (data[34] & 0x80) ? '-' : '+',
  842 + (data[34] >> 4) & 0x07, data[34] & 0x0F);
  843 + printf("Data signal input hold %c%d.%d nS\n",
  844 + (data[35] & 0x80) ? '-' : '+',
  845 + (data[35] >> 4) & 0x07, data[35] & 0x0F);
  846 + printf("Manufacturer's JEDEC ID ");
  847 + for(j = 64; j <= 71; j++)
  848 + printf("%02X ", data[j]);
  849 + printf("\n");
  850 + printf("Manufacturing Location %02X\n", data[72]);
  851 + printf("Manufacturer's Part Number ");
  852 + for(j = 73; j <= 90; j++)
  853 + printf("%02X ", data[j]);
  854 + printf("\n");
  855 + printf("Revision Code %02X %02X\n", data[91], data[92]);
  856 + printf("Manufacturing Date %02X %02X\n", data[93], data[94]);
  857 + printf("Assembly Serial Number ");
  858 + for(j = 95; j <= 98; j++)
  859 + printf("%02X ", data[j]);
  860 + printf("\n");
  861 + printf("Speed rating PC%d\n",
  862 + data[126] == 0x66 ? 66 : data[126]);
  863 +
  864 + return 0;
  865 +}
  866 +#endif /* CFG_CMD_SDRAM */
  867 +
  868 +#endif /* CFG_CMD_I2C */
include/configs/smdk2410.h
  1 +/*
  2 + * (C) Copyright 2002
  3 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  4 + * Marius Groeger <mgroeger@sysgo.de>
  5 + * Gary Jennejohn <gj@denx.de>
  6 + * David Mueller <d.mueller@elsoft.ch>
  7 + *
  8 + * Configuation settings for the SAMSUNG SMDK2410 board.
  9 + *
  10 + * See file CREDITS for list of people who contributed to this
  11 + * project.
  12 + *
  13 + * This program is free software; you can redistribute it and/or
  14 + * modify it under the terms of the GNU General Public License as
  15 + * published by the Free Software Foundation; either version 2 of
  16 + * the License, or (at your option) any later version.
  17 + *
  18 + * This program is distributed in the hope that it will be useful,
  19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21 + * GNU General Public License for more details.
  22 + *
  23 + * You should have received a copy of the GNU General Public License
  24 + * along with this program; if not, write to the Free Software
  25 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  26 + * MA 02111-1307 USA
  27 + */
  28 +
  29 +#ifndef __CONFIG_H
  30 +#define __CONFIG_H
  31 +
  32 +/*
  33 + * If we are developing, we might want to start armboot from ram
  34 + * so we MUST NOT initialize critical regs like mem-timing ...
  35 + */
  36 +#define CONFIG_INIT_CRITICAL /* undef for developing */
  37 +
  38 +/*
  39 + * High Level Configuration Options
  40 + * (easy to change)
  41 + */
  42 +#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
  43 +#define CONFIG_S3C2410 1 /* in a SAMSUNG S3C2410 SoC */
  44 +#define CONFIG_SMDK2410 1 /* on a SAMSUNG SMDK2410 Board */
  45 +
  46 +/* input clock of PLL */
  47 +#define CONFIG_PLL_INPUT_FREQ 12000000/* the SMDK2410 has 12MHz input clock */
  48 +
  49 +
  50 +#define USE_920T_MMU 1
  51 +#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
  52 +
  53 +/*
  54 + * Size of malloc() pool
  55 + */
  56 +#define CONFIG_MALLOC_SIZE (CFG_ENV_SIZE + 128*1024)
  57 +
  58 +/*
  59 + * Hardware drivers
  60 + */
  61 +#define CONFIG_DRIVER_CS8900 1 /* we have a CS8900 on-board */
  62 +#define CS8900_BASE 0x19000300
  63 +#define CS8900_BUS16 1 /* the Linux driver does accesses as shorts */
  64 +
  65 +/*
  66 + * select serial console configuration
  67 + */
  68 +#define CONFIG_SERIAL1 1 /* we use SERIAL 1 on SMDK2410 */
  69 +
  70 +/* allow to overwrite serial and ethaddr */
  71 +#define CONFIG_ENV_OVERWRITE
  72 +
  73 +#define CONFIG_BAUDRATE 115200
  74 +
  75 +#ifndef USE_920T_MMU
  76 +#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_CACHE)
  77 +#else
  78 +#define CONFIG_COMMANDS (CONFIG_CMD_DFL)
  79 +#endif
  80 +
  81 +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
  82 +#include <cmd_confdefs.h>
  83 +
  84 +#define CONFIG_BOOTDELAY 3
  85 +/*#define CONFIG_BOOTARGS "root=ramfs devfs=mount console=ttySA0,9600" */
  86 +/*#define CONFIG_ETHADDR 08:00:3e:26:0a:5b */
  87 +#define CONFIG_NETMASK 255.255.255.0
  88 +#define CONFIG_IPADDR 10.0.0.110
  89 +#define CONFIG_SERVERIP 10.0.0.1
  90 +/*#define CONFIG_BOOTFILE "elinos-lart" */
  91 +/*#define CONFIG_BOOTCOMMAND "tftp; bootm" */
  92 +
  93 +#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
  94 +#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
  95 +/* what's this ? it's not used anywhere */
  96 +#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */
  97 +#endif
  98 +
  99 +/*
  100 + * Miscellaneous configurable options
  101 + */
  102 +#define CFG_LONGHELP /* undef to save memory */
  103 +#define CFG_PROMPT "SMDK2410 # " /* Monitor Command Prompt */
  104 +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
  105 +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
  106 +#define CFG_MAXARGS 16 /* max number of command args */
  107 +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
  108 +
  109 +#define CFG_MEMTEST_START 0x30000000 /* memtest works on */
  110 +#define CFG_MEMTEST_END 0x33F00000 /* 63 MB in DRAM */
  111 +
  112 +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
  113 +
  114 +#define CFG_LOAD_ADDR 0x33000000 /* default load address */
  115 +
  116 +/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */
  117 +/* it to wrap 100 times (total 1562500) to get 1 sec. */
  118 +#define CFG_HZ 1562500
  119 +
  120 +/* valid baudrates */
  121 +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
  122 +
  123 +/*-----------------------------------------------------------------------
  124 + * Stack sizes
  125 + *
  126 + * The stack sizes are set up in start.S using the settings below
  127 + */
  128 +#define CONFIG_STACKSIZE (128*1024) /* regular stack */
  129 +#ifdef CONFIG_USE_IRQ
  130 +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
  131 +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
  132 +#endif
  133 +
  134 +/*-----------------------------------------------------------------------
  135 + * Physical Memory Map
  136 + */
  137 +#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
  138 +#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */
  139 +#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */
  140 +
  141 +#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
  142 +
  143 +#define CFG_FLASH_BASE PHYS_FLASH_1
  144 +
  145 +/*-----------------------------------------------------------------------
  146 + * FLASH and environment organization
  147 + */
  148 +
  149 +#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
  150 +#if 0
  151 +#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
  152 +#endif
  153 +
  154 +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
  155 +#ifdef CONFIG_AMD_LV800
  156 +#define PHYS_FLASH_SIZE 0x00100000 /* 1MB */
  157 +#define CFG_MAX_FLASH_SECT (19) /* max number of sectors on one chip */
  158 +#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x0F0000) /* addr of environment */
  159 +#endif
  160 +#ifdef CONFIG_AMD_LV400
  161 +#define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
  162 +#define CFG_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
  163 +#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x070000) /* addr of environment */
  164 +#endif
  165 +
  166 +/* timeout values are in ticks */
  167 +#define CFG_FLASH_ERASE_TOUT (5*CFG_HZ) /* Timeout for Flash Erase */
  168 +#define CFG_FLASH_WRITE_TOUT (5*CFG_HZ) /* Timeout for Flash Write */
  169 +
  170 +#define CFG_ENV_IS_IN_FLASH 1
  171 +#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
  172 +
  173 +#endif /* __CONFIG_H */