i2c.c 48.1 KB
Newer Older
wdenk's avatar
wdenk committed
1
/*
2 3 4 5 6
 * (C) Copyright 2009
 * Sergey Kubushyn, himself, ksi@koi8.net
 *
 * Changes for unified multibus/multiadapter I2C support.
 *
wdenk's avatar
wdenk committed
7 8 9
 * (C) Copyright 2001
 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
 *
10
 * SPDX-License-Identifier:	GPL-2.0+
wdenk's avatar
wdenk committed
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
 */

/*
 * I2C Functions similar to the standard memory functions.
 *
 * There are several parameters in many of the commands that bear further
 * explanations:
 *
 * {i2c_chip} is the I2C chip address (the first byte sent on the bus).
 *   Each I2C chip on the bus has a unique address.  On the I2C data bus,
 *   the address is the upper seven bits and the LSB is the "read/write"
 *   bit.  Note that the {i2c_chip} address specified on the command
 *   line is not shifted up: e.g. a typical EEPROM memory chip may have
 *   an I2C address of 0x50, but the data put on the bus will be 0xA0
 *   for write and 0xA1 for read.  This "non shifted" address notation
 *   matches at least half of the data sheets :-/.
 *
 * {addr} is the address (or offset) within the chip.  Small memory
 *   chips have 8 bit addresses.  Large memory chips have 16 bit
 *   addresses.  Other memory chips have 9, 10, or 11 bit addresses.
 *   Many non-memory chips have multiple registers and {addr} is used
 *   as the register index.  Some non-memory chips have only one register
 *   and therefore don't need any {addr} parameter.
 *
 *   The default {addr} parameter is one byte (.1) which works well for
 *   memories and registers with 8 bits of address space.
 *
 *   You can specify the length of the {addr} field with the optional .0,
 *   .1, or .2 modifier (similar to the .b, .w, .l modifier).  If you are
 *   manipulating a single register device which doesn't use an address
 *   field, use "0.0" for the address and the ".0" length field will
 *   suppress the address in the I2C data stream.  This also works for
 *   successive reads using the I2C auto-incrementing memory pointer.
 *
 *   If you are manipulating a large memory with 2-byte addresses, use
 *   the .2 address modifier, e.g. 210.2 addresses location 528 (decimal).
 *
 *   Then there are the unfortunate memory chips that spill the most
 *   significant 1, 2, or 3 bits of address into the chip address byte.
 *   This effectively makes one chip (logically) look like 2, 4, or
 *   8 chips.  This is handled (awkwardly) by #defining
52
 *   CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW and using the .1 modifier on the
wdenk's avatar
wdenk committed
53 54 55
 *   {addr} field (since .1 is the default, it doesn't actually have to
 *   be specified).  Examples: given a memory chip at I2C chip address
 *   0x50, the following would happen...
56
 *     i2c md 50 0 10   display 16 bytes starting at 0x000
wdenk's avatar
wdenk committed
57
 *                      On the bus: <S> A0 00 <E> <S> A1 <rd> ... <rd>
58
 *     i2c md 50 100 10 display 16 bytes starting at 0x100
wdenk's avatar
wdenk committed
59
 *                      On the bus: <S> A2 00 <E> <S> A3 <rd> ... <rd>
60
 *     i2c md 50 210 10 display 16 bytes starting at 0x210
wdenk's avatar
wdenk committed
61 62 63 64 65 66 67 68
 *                      On the bus: <S> A4 10 <E> <S> A5 <rd> ... <rd>
 *   This is awfully ugly.  It would be nice if someone would think up
 *   a better way of handling this.
 *
 * Adapted from cmd_mem.c which is copyright Wolfgang Denk (wd@denx.de).
 */

#include <common.h>
69
#include <bootretry.h>
70
#include <cli.h>
wdenk's avatar
wdenk committed
71
#include <command.h>
72
#include <console.h>
73
#include <dm.h>
74
#include <edid.h>
75
#include <environment.h>
76
#include <errno.h>
wdenk's avatar
wdenk committed
77
#include <i2c.h>
78
#include <malloc.h>
wdenk's avatar
wdenk committed
79
#include <asm/byteorder.h>
80
#include <linux/compiler.h>
wdenk's avatar
wdenk committed
81

82 83
DECLARE_GLOBAL_DATA_PTR;

wdenk's avatar
wdenk committed
84 85 86
/* Display values from last command.
 * Memory modify remembered values are different from display memory.
 */
87
static uint	i2c_dp_last_chip;
wdenk's avatar
wdenk committed
88 89 90 91
static uint	i2c_dp_last_addr;
static uint	i2c_dp_last_alen;
static uint	i2c_dp_last_length = 0x10;

92
static uint	i2c_mm_last_chip;
wdenk's avatar
wdenk committed
93 94 95
static uint	i2c_mm_last_addr;
static uint	i2c_mm_last_alen;

96 97 98 99 100
/* If only one I2C bus is present, the list of devices to ignore when
 * the probe command is issued is represented by a 1D array of addresses.
 * When multiple buses are present, the list is an array of bus-address
 * pairs.  The following macros take care of this */

101
#if defined(CONFIG_SYS_I2C_NOPROBES)
102
#if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS)
103 104 105 106
static struct
{
	uchar	bus;
	uchar	addr;
107
} i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
108 109 110 111 112
#define GET_BUS_NUM	i2c_get_bus_num()
#define COMPARE_BUS(b,i)	(i2c_no_probes[(i)].bus == (b))
#define COMPARE_ADDR(a,i)	(i2c_no_probes[(i)].addr == (a))
#define NO_PROBE_ADDR(i)	i2c_no_probes[(i)].addr
#else		/* single bus */
113
static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
114 115 116 117
#define GET_BUS_NUM	0
#define COMPARE_BUS(b,i)	((b) == 0)	/* Make compiler happy */
#define COMPARE_ADDR(a,i)	(i2c_no_probes[(i)] == (a))
#define NO_PROBE_ADDR(i)	i2c_no_probes[(i)]
118
#endif	/* defined(CONFIG_SYS_I2C) */
119 120
#endif

121 122
#define DISP_LINE_LEN	16

123 124 125 126 127 128 129 130 131 132 133 134 135 136
/*
 * Default for driver model is to use the chip's existing address length.
 * For legacy code, this is not stored, so we need to use a suitable
 * default.
 */
#ifdef CONFIG_DM_I2C
#define DEFAULT_ADDR_LEN	(-1)
#else
#define DEFAULT_ADDR_LEN	1
#endif

#ifdef CONFIG_DM_I2C
static struct udevice *i2c_cur_bus;

137
static int cmd_i2c_set_bus_num(unsigned int busnum)
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
{
	struct udevice *bus;
	int ret;

	ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus);
	if (ret) {
		debug("%s: No bus %d\n", __func__, busnum);
		return ret;
	}
	i2c_cur_bus = bus;

	return 0;
}

static int i2c_get_cur_bus(struct udevice **busp)
{
	if (!i2c_cur_bus) {
		puts("No I2C bus selected\n");
		return -ENODEV;
	}
	*busp = i2c_cur_bus;

	return 0;
}

static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp)
{
	struct udevice *bus;
	int ret;

	ret = i2c_get_cur_bus(&bus);
	if (ret)
		return ret;

172
	return i2c_get_chip(bus, chip_addr, 1, devp);
173 174 175 176
}

#endif

177 178 179 180 181 182 183
/**
 * i2c_init_board() - Board-specific I2C bus init
 *
 * This function is the default no-op implementation of I2C bus
 * initialization. This function can be overriden by board-specific
 * implementation if needed.
 */
184 185
__weak
void i2c_init_board(void)
186 187 188
{
}

189
/* TODO: Implement architecture-specific get/set functions */
190 191 192 193 194 195 196 197 198 199 200 201 202

/**
 * i2c_get_bus_speed() - Return I2C bus speed
 *
 * This function is the default implementation of function for retrieveing
 * the current I2C bus speed in Hz.
 *
 * A driver implementing runtime switching of I2C bus speed must override
 * this function to report the speed correctly. Simple or legacy drivers
 * can use this fallback.
 *
 * Returns I2C bus speed in Hz.
 */
203
#if !defined(CONFIG_SYS_I2C) && !defined(CONFIG_DM_I2C)
204 205 206 207
/*
 * TODO: Implement architecture-specific get/set functions
 * Should go away, if we switched completely to new multibus support
 */
208 209
__weak
unsigned int i2c_get_bus_speed(void)
210 211 212 213
{
	return CONFIG_SYS_I2C_SPEED;
}

214 215 216 217 218 219 220 221 222 223 224 225 226
/**
 * i2c_set_bus_speed() - Configure I2C bus speed
 * @speed:	Newly set speed of the I2C bus in Hz
 *
 * This function is the default implementation of function for setting
 * the I2C bus speed in Hz.
 *
 * A driver implementing runtime switching of I2C bus speed must override
 * this function to report the speed correctly. Simple or legacy drivers
 * can use this fallback.
 *
 * Returns zero on success, negative value on error.
 */
227 228
__weak
int i2c_set_bus_speed(unsigned int speed)
229 230 231 232 233 234
{
	if (speed != CONFIG_SYS_I2C_SPEED)
		return -1;

	return 0;
}
235
#endif
236

237 238 239 240
/**
 * get_alen() - Small parser helper function to get address length
 *
 * Returns the address length.
241
 */
242
static uint get_alen(char *arg, int default_len)
243 244 245 246
{
	int	j;
	int	alen;

247
	alen = default_len;
248 249 250 251 252 253 254 255 256 257
	for (j = 0; j < 8; j++) {
		if (arg[j] == '.') {
			alen = arg[j+1] - '0';
			break;
		} else if (arg[j] == '\0')
			break;
	}
	return alen;
}

258 259 260 261 262 263 264 265 266 267 268 269 270
enum i2c_err_op {
	I2C_ERR_READ,
	I2C_ERR_WRITE,
};

static int i2c_report_err(int ret, enum i2c_err_op op)
{
	printf("Error %s the chip: %d\n",
	       op == I2C_ERR_READ ? "reading" : "writing", ret);

	return CMD_RET_FAILURE;
}

271 272 273 274 275 276 277 278 279 280
/**
 * do_i2c_read() - Handle the "i2c read" command-line command
 * @cmdtp:	Command data struct pointer
 * @flag:	Command flag
 * @argc:	Command-line argument count
 * @argv:	Array of command-line arguments
 *
 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
 * on error.
 *
281 282 283
 * Syntax:
 *	i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr}
 */
284
static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
285
{
286
	uint	chip;
287 288
	uint	devaddr, length;
	int alen;
289
	u_char  *memaddr;
290 291 292 293
	int ret;
#ifdef CONFIG_DM_I2C
	struct udevice *dev;
#endif
294

295
	if (argc != 5)
296
		return CMD_RET_USAGE;
297 298 299 300 301 302 303 304 305 306 307

	/*
	 * I2C chip address
	 */
	chip = simple_strtoul(argv[1], NULL, 16);

	/*
	 * I2C data address within the chip.  This can be 1 or
	 * 2 bytes long.  Some day it might be 3 bytes long :-).
	 */
	devaddr = simple_strtoul(argv[2], NULL, 16);
308
	alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
Reinhard Meyer's avatar
Reinhard Meyer committed
309
	if (alen > 3)
310
		return CMD_RET_USAGE;
311 312 313 314 315 316 317 318 319 320 321

	/*
	 * Length is the number of objects, not number of bytes.
	 */
	length = simple_strtoul(argv[3], NULL, 16);

	/*
	 * memaddr is the address where to store things in memory
	 */
	memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16);

322 323 324 325 326
#ifdef CONFIG_DM_I2C
	ret = i2c_get_cur_bus_chip(chip, &dev);
	if (!ret && alen != -1)
		ret = i2c_set_chip_offset_len(dev, alen);
	if (!ret)
327
		ret = dm_i2c_read(dev, devaddr, memaddr, length);
328 329 330 331 332 333
#else
	ret = i2c_read(chip, devaddr, alen, memaddr, length);
#endif
	if (ret)
		return i2c_report_err(ret, I2C_ERR_READ);

334 335 336
	return 0;
}

York Sun's avatar
York Sun committed
337 338
static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
339
	uint	chip;
340 341
	uint	devaddr, length;
	int alen;
York Sun's avatar
York Sun committed
342
	u_char  *memaddr;
343 344 345
	int ret;
#ifdef CONFIG_DM_I2C
	struct udevice *dev;
346
	struct dm_i2c_chip *i2c_chip;
347
#endif
York Sun's avatar
York Sun committed
348

349
	if ((argc < 5) || (argc > 6))
York Sun's avatar
York Sun committed
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
		return cmd_usage(cmdtp);

	/*
	 * memaddr is the address where to store things in memory
	 */
	memaddr = (u_char *)simple_strtoul(argv[1], NULL, 16);

	/*
	 * I2C chip address
	 */
	chip = simple_strtoul(argv[2], NULL, 16);

	/*
	 * I2C data address within the chip.  This can be 1 or
	 * 2 bytes long.  Some day it might be 3 bytes long :-).
	 */
	devaddr = simple_strtoul(argv[3], NULL, 16);
367
	alen = get_alen(argv[3], DEFAULT_ADDR_LEN);
York Sun's avatar
York Sun committed
368 369 370 371
	if (alen > 3)
		return cmd_usage(cmdtp);

	/*
372
	 * Length is the number of bytes.
York Sun's avatar
York Sun committed
373 374 375
	 */
	length = simple_strtoul(argv[4], NULL, 16);

376 377 378 379 380 381
#ifdef CONFIG_DM_I2C
	ret = i2c_get_cur_bus_chip(chip, &dev);
	if (!ret && alen != -1)
		ret = i2c_set_chip_offset_len(dev, alen);
	if (ret)
		return i2c_report_err(ret, I2C_ERR_WRITE);
382 383 384
	i2c_chip = dev_get_parent_platdata(dev);
	if (!i2c_chip)
		return i2c_report_err(ret, I2C_ERR_WRITE);
385 386
#endif

387 388 389 390 391 392 393
	if (argc == 6 && !strcmp(argv[5], "-s")) {
		/*
		 * Write all bytes in a single I2C transaction. If the target
		 * device is an EEPROM, it is your responsibility to not cross
		 * a page boundary. No write delay upon completion, take this
		 * into account if linking commands.
		 */
394
#ifdef CONFIG_DM_I2C
395 396
		i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS;
		ret = dm_i2c_write(dev, devaddr, memaddr, length);
397
#else
398
		ret = i2c_write(chip, devaddr, alen, memaddr, length);
399 400 401
#endif
		if (ret)
			return i2c_report_err(ret, I2C_ERR_WRITE);
402 403 404 405 406 407 408 409 410 411 412 413 414 415
	} else {
		/*
		 * Repeated addressing - perform <length> separate
		 * write transactions of one byte each
		 */
		while (length-- > 0) {
#ifdef CONFIG_DM_I2C
			i2c_chip->flags |= DM_I2C_CHIP_WR_ADDRESS;
			ret = dm_i2c_write(dev, devaddr++, memaddr++, 1);
#else
			ret = i2c_write(chip, devaddr++, alen, memaddr++, 1);
#endif
			if (ret)
				return i2c_report_err(ret, I2C_ERR_WRITE);
York Sun's avatar
York Sun committed
416 417 418 419
/*
 * No write delay with FRAM devices.
 */
#if !defined(CONFIG_SYS_I2C_FRAM)
420
			udelay(11000);
York Sun's avatar
York Sun committed
421
#endif
422
		}
York Sun's avatar
York Sun committed
423 424 425 426
	}
	return 0;
}

427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
#ifdef CONFIG_DM_I2C
static int do_i2c_flags(cmd_tbl_t *cmdtp, int flag, int argc,
			char *const argv[])
{
	struct udevice *dev;
	uint flags;
	int chip;
	int ret;

	if (argc < 2)
		return CMD_RET_USAGE;

	chip = simple_strtoul(argv[1], NULL, 16);
	ret = i2c_get_cur_bus_chip(chip, &dev);
	if (ret)
		return i2c_report_err(ret, I2C_ERR_READ);

	if (argc > 2) {
		flags = simple_strtoul(argv[2], NULL, 16);
		ret = i2c_set_chip_flags(dev, flags);
	} else  {
		ret = i2c_get_chip_flags(dev, &flags);
		if (!ret)
			printf("%x\n", flags);
	}
	if (ret)
		return i2c_report_err(ret, I2C_ERR_READ);

	return 0;
}
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487

static int do_i2c_olen(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	struct udevice *dev;
	uint olen;
	int chip;
	int ret;

	if (argc < 2)
		return CMD_RET_USAGE;

	chip = simple_strtoul(argv[1], NULL, 16);
	ret = i2c_get_cur_bus_chip(chip, &dev);
	if (ret)
		return i2c_report_err(ret, I2C_ERR_READ);

	if (argc > 2) {
		olen = simple_strtoul(argv[2], NULL, 16);
		ret = i2c_set_chip_offset_len(dev, olen);
	} else  {
		ret = i2c_get_chip_offset_len(dev);
		if (ret >= 0) {
			printf("%x\n", ret);
			ret = 0;
		}
	}
	if (ret)
		return i2c_report_err(ret, I2C_ERR_READ);

	return 0;
}
488 489
#endif

490 491 492 493 494 495 496 497 498 499
/**
 * do_i2c_md() - Handle the "i2c md" command-line command
 * @cmdtp:	Command data struct pointer
 * @flag:	Command flag
 * @argc:	Command-line argument count
 * @argv:	Array of command-line arguments
 *
 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
 * on error.
 *
500 501 502
 * Syntax:
 *	i2c md {i2c_chip} {addr}{.0, .1, .2} {len}
 */
503
static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk's avatar
wdenk committed
504
{
505
	uint	chip;
506 507
	uint	addr, length;
	int alen;
wdenk's avatar
wdenk committed
508
	int	j, nbytes, linebytes;
509 510 511 512
	int ret;
#ifdef CONFIG_DM_I2C
	struct udevice *dev;
#endif
wdenk's avatar
wdenk committed
513 514 515 516 517 518 519 520 521

	/* We use the last specified parameters, unless new ones are
	 * entered.
	 */
	chip   = i2c_dp_last_chip;
	addr   = i2c_dp_last_addr;
	alen   = i2c_dp_last_alen;
	length = i2c_dp_last_length;

522
	if (argc < 3)
523
		return CMD_RET_USAGE;
wdenk's avatar
wdenk committed
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539

	if ((flag & CMD_FLAG_REPEAT) == 0) {
		/*
		 * New command specified.
		 */

		/*
		 * I2C chip address
		 */
		chip = simple_strtoul(argv[1], NULL, 16);

		/*
		 * I2C data address within the chip.  This can be 1 or
		 * 2 bytes long.  Some day it might be 3 bytes long :-).
		 */
		addr = simple_strtoul(argv[2], NULL, 16);
540
		alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
Reinhard Meyer's avatar
Reinhard Meyer committed
541
		if (alen > 3)
542
			return CMD_RET_USAGE;
wdenk's avatar
wdenk committed
543 544 545 546 547 548 549 550 551

		/*
		 * If another parameter, it is the length to display.
		 * Length is the number of objects, not number of bytes.
		 */
		if (argc > 3)
			length = simple_strtoul(argv[3], NULL, 16);
	}

552 553 554 555 556 557 558 559
#ifdef CONFIG_DM_I2C
	ret = i2c_get_cur_bus_chip(chip, &dev);
	if (!ret && alen != -1)
		ret = i2c_set_chip_offset_len(dev, alen);
	if (ret)
		return i2c_report_err(ret, I2C_ERR_READ);
#endif

wdenk's avatar
wdenk committed
560 561 562 563 564 565 566 567 568 569 570 571 572
	/*
	 * Print the lines.
	 *
	 * We buffer all read data, so we can make sure data is read only
	 * once.
	 */
	nbytes = length;
	do {
		unsigned char	linebuf[DISP_LINE_LEN];
		unsigned char	*cp;

		linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;

573
#ifdef CONFIG_DM_I2C
574
		ret = dm_i2c_read(dev, addr, linebuf, linebytes);
575 576 577 578
#else
		ret = i2c_read(chip, addr, alen, linebuf, linebytes);
#endif
		if (ret)
579
			return i2c_report_err(ret, I2C_ERR_READ);
580
		else {
wdenk's avatar
wdenk committed
581 582 583 584 585 586
			printf("%04x:", addr);
			cp = linebuf;
			for (j=0; j<linebytes; j++) {
				printf(" %02x", *cp++);
				addr++;
			}
587
			puts ("    ");
wdenk's avatar
wdenk committed
588 589 590
			cp = linebuf;
			for (j=0; j<linebytes; j++) {
				if ((*cp < 0x20) || (*cp > 0x7e))
591
					puts (".");
wdenk's avatar
wdenk committed
592 593 594 595
				else
					printf("%c", *cp);
				cp++;
			}
596
			putc ('\n');
wdenk's avatar
wdenk committed
597 598 599 600 601 602 603 604 605 606 607 608
		}
		nbytes -= linebytes;
	} while (nbytes > 0);

	i2c_dp_last_chip   = chip;
	i2c_dp_last_addr   = addr;
	i2c_dp_last_alen   = alen;
	i2c_dp_last_length = length;

	return 0;
}

609 610 611 612 613 614 615 616 617
/**
 * do_i2c_mw() - Handle the "i2c mw" command-line command
 * @cmdtp:	Command data struct pointer
 * @flag:	Command flag
 * @argc:	Command-line argument count
 * @argv:	Array of command-line arguments
 *
 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
 * on error.
wdenk's avatar
wdenk committed
618 619
 *
 * Syntax:
620
 *	i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}]
wdenk's avatar
wdenk committed
621
 */
622
static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk's avatar
wdenk committed
623
{
624
	uint	chip;
wdenk's avatar
wdenk committed
625
	ulong	addr;
626
	int	alen;
wdenk's avatar
wdenk committed
627 628
	uchar	byte;
	int	count;
629 630 631 632
	int ret;
#ifdef CONFIG_DM_I2C
	struct udevice *dev;
#endif
wdenk's avatar
wdenk committed
633

634
	if ((argc < 4) || (argc > 5))
635
		return CMD_RET_USAGE;
wdenk's avatar
wdenk committed
636 637

	/*
Wolfgang Denk's avatar
Wolfgang Denk committed
638 639
	 * Chip is always specified.
	 */
wdenk's avatar
wdenk committed
640 641 642 643 644 645
	chip = simple_strtoul(argv[1], NULL, 16);

	/*
	 * Address is always specified.
	 */
	addr = simple_strtoul(argv[2], NULL, 16);
646
	alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
Reinhard Meyer's avatar
Reinhard Meyer committed
647
	if (alen > 3)
648
		return CMD_RET_USAGE;
wdenk's avatar
wdenk committed
649

650 651 652 653 654 655 656
#ifdef CONFIG_DM_I2C
	ret = i2c_get_cur_bus_chip(chip, &dev);
	if (!ret && alen != -1)
		ret = i2c_set_chip_offset_len(dev, alen);
	if (ret)
		return i2c_report_err(ret, I2C_ERR_WRITE);
#endif
wdenk's avatar
wdenk committed
657 658 659 660 661 662 663 664
	/*
	 * Value to write is always specified.
	 */
	byte = simple_strtoul(argv[3], NULL, 16);

	/*
	 * Optional count
	 */
665
	if (argc == 5)
wdenk's avatar
wdenk committed
666
		count = simple_strtoul(argv[4], NULL, 16);
667
	else
wdenk's avatar
wdenk committed
668 669 670
		count = 1;

	while (count-- > 0) {
671
#ifdef CONFIG_DM_I2C
672
		ret = dm_i2c_write(dev, addr++, &byte, 1);
673 674 675 676
#else
		ret = i2c_write(chip, addr++, alen, &byte, 1);
#endif
		if (ret)
677
			return i2c_report_err(ret, I2C_ERR_WRITE);
wdenk's avatar
wdenk committed
678 679 680 681
		/*
		 * Wait for the write to complete.  The write can take
		 * up to 10mSec (we allow a little more time).
		 */
's avatar
committed
682 683 684
/*
 * No write delay with FRAM devices.
 */
685
#if !defined(CONFIG_SYS_I2C_FRAM)
wdenk's avatar
wdenk committed
686
		udelay(11000);
's avatar
committed
687
#endif
wdenk's avatar
wdenk committed
688 689
	}

690
	return 0;
wdenk's avatar
wdenk committed
691 692
}

693 694 695 696 697 698 699 700 701 702 703
/**
 * do_i2c_crc() - Handle the "i2c crc32" command-line command
 * @cmdtp:	Command data struct pointer
 * @flag:	Command flag
 * @argc:	Command-line argument count
 * @argv:	Array of command-line arguments
 *
 * Calculate a CRC on memory
 *
 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
 * on error.
wdenk's avatar
wdenk committed
704 705
 *
 * Syntax:
706
 *	i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count}
wdenk's avatar
wdenk committed
707
 */
708
static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk's avatar
wdenk committed
709
{
710
	uint	chip;
wdenk's avatar
wdenk committed
711
	ulong	addr;
712
	int	alen;
wdenk's avatar
wdenk committed
713 714 715 716
	int	count;
	uchar	byte;
	ulong	crc;
	ulong	err;
717 718 719 720
	int ret = 0;
#ifdef CONFIG_DM_I2C
	struct udevice *dev;
#endif
wdenk's avatar
wdenk committed
721

722
	if (argc < 4)
723
		return CMD_RET_USAGE;
wdenk's avatar
wdenk committed
724 725

	/*
Wolfgang Denk's avatar
Wolfgang Denk committed
726 727
	 * Chip is always specified.
	 */
wdenk's avatar
wdenk committed
728 729 730 731 732 733
	chip = simple_strtoul(argv[1], NULL, 16);

	/*
	 * Address is always specified.
	 */
	addr = simple_strtoul(argv[2], NULL, 16);
734
	alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
Reinhard Meyer's avatar
Reinhard Meyer committed
735
	if (alen > 3)
736
		return CMD_RET_USAGE;
wdenk's avatar
wdenk committed
737

738 739 740 741 742 743 744
#ifdef CONFIG_DM_I2C
	ret = i2c_get_cur_bus_chip(chip, &dev);
	if (!ret && alen != -1)
		ret = i2c_set_chip_offset_len(dev, alen);
	if (ret)
		return i2c_report_err(ret, I2C_ERR_READ);
#endif
wdenk's avatar
wdenk committed
745 746 747 748 749 750 751 752 753 754 755 756
	/*
	 * Count is always specified
	 */
	count = simple_strtoul(argv[3], NULL, 16);

	printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1);
	/*
	 * CRC a byte at a time.  This is going to be slooow, but hey, the
	 * memories are small and slow too so hopefully nobody notices.
	 */
	crc = 0;
	err = 0;
757
	while (count-- > 0) {
758
#ifdef CONFIG_DM_I2C
759
		ret = dm_i2c_read(dev, addr, &byte, 1);
760 761 762 763
#else
		ret = i2c_read(chip, addr, alen, &byte, 1);
#endif
		if (ret)
wdenk's avatar
wdenk committed
764 765 766 767
			err++;
		crc = crc32 (crc, &byte, 1);
		addr++;
	}
768
	if (err > 0)
769
		i2c_report_err(ret, I2C_ERR_READ);
770
	else
wdenk's avatar
wdenk committed
771 772 773 774 775
		printf ("%08lx\n", crc);

	return 0;
}

776 777 778 779 780 781 782 783 784 785 786
/**
 * mod_i2c_mem() - Handle the "i2c mm" and "i2c nm" command-line command
 * @cmdtp:	Command data struct pointer
 * @flag:	Command flag
 * @argc:	Command-line argument count
 * @argv:	Array of command-line arguments
 *
 * Modify memory.
 *
 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
 * on error.
wdenk's avatar
wdenk committed
787 788
 *
 * Syntax:
789 790
 *	i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
 *	i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2}
wdenk's avatar
wdenk committed
791 792
 */
static int
793
mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
wdenk's avatar
wdenk committed
794
{
795
	uint	chip;
wdenk's avatar
wdenk committed
796
	ulong	addr;
797
	int	alen;
wdenk's avatar
wdenk committed
798 799 800
	ulong	data;
	int	size = 1;
	int	nbytes;
801 802 803 804
	int ret;
#ifdef CONFIG_DM_I2C
	struct udevice *dev;
#endif
wdenk's avatar
wdenk committed
805

806
	if (argc != 3)
807
		return CMD_RET_USAGE;
wdenk's avatar
wdenk committed
808

809
	bootretry_reset_cmd_timeout();	/* got a good command to get here */
wdenk's avatar
wdenk committed
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
	/*
	 * We use the last specified parameters, unless new ones are
	 * entered.
	 */
	chip = i2c_mm_last_chip;
	addr = i2c_mm_last_addr;
	alen = i2c_mm_last_alen;

	if ((flag & CMD_FLAG_REPEAT) == 0) {
		/*
		 * New command specified.  Check for a size specification.
		 * Defaults to byte if no or incorrect specification.
		 */
		size = cmd_get_data_size(argv[0], 1);

		/*
Wolfgang Denk's avatar
Wolfgang Denk committed
826 827
		 * Chip is always specified.
		 */
wdenk's avatar
wdenk committed
828 829 830 831 832 833
		chip = simple_strtoul(argv[1], NULL, 16);

		/*
		 * Address is always specified.
		 */
		addr = simple_strtoul(argv[2], NULL, 16);
834
		alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
Reinhard Meyer's avatar
Reinhard Meyer committed
835
		if (alen > 3)
836
			return CMD_RET_USAGE;
wdenk's avatar
wdenk committed
837 838
	}

839 840 841 842 843 844 845 846
#ifdef CONFIG_DM_I2C
	ret = i2c_get_cur_bus_chip(chip, &dev);
	if (!ret && alen != -1)
		ret = i2c_set_chip_offset_len(dev, alen);
	if (ret)
		return i2c_report_err(ret, I2C_ERR_WRITE);
#endif

wdenk's avatar
wdenk committed
847 848 849 850 851 852
	/*
	 * Print the address, followed by value.  Then accept input for
	 * the next value.  A non-converted value exits.
	 */
	do {
		printf("%08lx:", addr);
853
#ifdef CONFIG_DM_I2C
854
		ret = dm_i2c_read(dev, addr, (uchar *)&data, size);
855 856 857 858
#else
		ret = i2c_read(chip, addr, alen, (uchar *)&data, size);
#endif
		if (ret)
859 860 861 862 863 864 865 866 867
			return i2c_report_err(ret, I2C_ERR_READ);

		data = cpu_to_be32(data);
		if (size == 1)
			printf(" %02lx", (data >> 24) & 0x000000FF);
		else if (size == 2)
			printf(" %04lx", (data >> 16) & 0x0000FFFF);
		else
			printf(" %08lx", data);
wdenk's avatar
wdenk committed
868

869
		nbytes = cli_readline(" ? ");
wdenk's avatar
wdenk committed
870 871 872 873 874 875 876 877
		if (nbytes == 0) {
			/*
			 * <CR> pressed as only input, don't modify current
			 * location and move to next.
			 */
			if (incrflag)
				addr += size;
			nbytes = size;
878 879
			/* good enough to not time out */
			bootretry_reset_cmd_timeout();
wdenk's avatar
wdenk committed
880 881
		}
#ifdef CONFIG_BOOT_RETRY_TIME
882
		else if (nbytes == -2)
wdenk's avatar
wdenk committed
883 884 885 886 887 888
			break;	/* timed out, exit the command	*/
#endif
		else {
			char *endp;

			data = simple_strtoul(console_buffer, &endp, 16);
889
			if (size == 1)
wdenk's avatar
wdenk committed
890
				data = data << 24;
891
			else if (size == 2)
wdenk's avatar
wdenk committed
892 893 894 895 896 897 898
				data = data << 16;
			data = be32_to_cpu(data);
			nbytes = endp - console_buffer;
			if (nbytes) {
				/*
				 * good enough to not time out
				 */
899
				bootretry_reset_cmd_timeout();
900
#ifdef CONFIG_DM_I2C
901 902
				ret = dm_i2c_write(dev, addr, (uchar *)&data,
						   size);
903 904 905 906 907
#else
				ret = i2c_write(chip, addr, alen,
						(uchar *)&data, size);
#endif
				if (ret)
908 909
					return i2c_report_err(ret,
							      I2C_ERR_WRITE);
910 911
#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS
				udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
912
#endif
wdenk's avatar
wdenk committed
913 914 915 916 917 918
				if (incrflag)
					addr += size;
			}
		}
	} while (nbytes);

Peter Tyser's avatar
Peter Tyser committed
919 920 921
	i2c_mm_last_chip = chip;
	i2c_mm_last_addr = addr;
	i2c_mm_last_alen = alen;
wdenk's avatar
wdenk committed
922 923 924 925

	return 0;
}

926 927 928 929 930 931 932 933 934 935
/**
 * do_i2c_probe() - Handle the "i2c probe" command-line command
 * @cmdtp:	Command data struct pointer
 * @flag:	Command flag
 * @argc:	Command-line argument count
 * @argv:	Array of command-line arguments
 *
 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
 * on error.
 *
wdenk's avatar
wdenk committed
936
 * Syntax:
937 938 939
 *	i2c probe {addr}
 *
 * Returns zero (success) if one or more I2C devices was found
wdenk's avatar
wdenk committed
940
 */
941
static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk's avatar
wdenk committed
942 943
{
	int j;
944 945
	int addr = -1;
	int found = 0;
946
#if defined(CONFIG_SYS_I2C_NOPROBES)
wdenk's avatar
wdenk committed
947
	int k, skip;
948
	unsigned int bus = GET_BUS_NUM;
949
#endif	/* NOPROBES */
950 951 952 953 954 955 956
	int ret;
#ifdef CONFIG_DM_I2C
	struct udevice *bus, *dev;

	if (i2c_get_cur_bus(&bus))
		return CMD_RET_FAILURE;
#endif
wdenk's avatar
wdenk committed
957

958 959 960
	if (argc == 2)
		addr = simple_strtol(argv[1], 0, 16);

961
	puts ("Valid chip addresses:");
962
	for (j = 0; j < 128; j++) {
963 964 965
		if ((0 <= addr) && (j != addr))
			continue;

966
#if defined(CONFIG_SYS_I2C_NOPROBES)
wdenk's avatar
wdenk committed
967
		skip = 0;
968
		for (k = 0; k < ARRAY_SIZE(i2c_no_probes); k++) {
969
			if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) {
wdenk's avatar
wdenk committed
970 971 972 973 974 975 976
				skip = 1;
				break;
			}
		}
		if (skip)
			continue;
#endif
977
#ifdef CONFIG_DM_I2C
978
		ret = dm_i2c_probe(bus, j, 0, &dev);
979 980 981 982
#else
		ret = i2c_probe(j);
#endif
		if (ret == 0) {
wdenk's avatar
wdenk committed
983
			printf(" %02X", j);
984 985
			found++;
		}
wdenk's avatar
wdenk committed
986
	}
987
	putc ('\n');
wdenk's avatar
wdenk committed
988

989
#if defined(CONFIG_SYS_I2C_NOPROBES)
wdenk's avatar
wdenk committed
990
	puts ("Excluded chip addresses:");
991
	for (k = 0; k < ARRAY_SIZE(i2c_no_probes); k++) {
992
		if (COMPARE_BUS(bus,k))
993 994
			printf(" %02X", NO_PROBE_ADDR(k));
	}
995
	putc ('\n');
wdenk's avatar
wdenk committed
996 997
#endif

998
	return (0 == found);
wdenk's avatar
wdenk committed
999 1000
}

1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
/**
 * do_i2c_loop() - Handle the "i2c loop" command-line command
 * @cmdtp:	Command data struct pointer
 * @flag:	Command flag
 * @argc:	Command-line argument count
 * @argv:	Array of command-line arguments
 *
 * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
 * on error.
 *
wdenk's avatar
wdenk committed
1011
 * Syntax:
1012
 *	i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}]
wdenk's avatar
wdenk committed
1013 1014 1015
 *	{length} - Number of bytes to read
 *	{delay}  - A DECIMAL number and defaults to 1000 uSec
 */
1016
static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenk's avatar
wdenk committed
1017
{
1018
	uint	chip;
1019
	int alen;
wdenk's avatar
wdenk committed
1020 1021 1022 1023
	uint	addr;
	uint	length;
	u_char	bytes[16];
	int	delay;
1024 1025 1026 1027
	int ret;
#ifdef CONFIG_DM_I2C
	struct udevice *dev;
#endif
wdenk's avatar
wdenk committed
1028

1029
	if (argc < 3)
1030
		return CMD_RET_USAGE;
wdenk's avatar
wdenk committed
1031 1032 1033 1034 1035 1036 1037 1038 1039 1040

	/*
	 * Chip is always specified.
	 */
	chip = simple_strtoul(argv[1], NULL, 16);

	/*
	 * Address is always specified.
	 */
	addr = simple_strtoul(argv[2], NULL, 16);
1041
	alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
Reinhard Meyer's avatar
Reinhard Meyer committed
1042
	if (alen > 3)
1043
		return CMD_RET_USAGE;
1044 1045 1046 1047 1048 1049 1050
#ifdef CONFIG_DM_I2C
	ret = i2c_get_cur_bus_chip(chip, &dev);
	if (!ret && alen != -1)
		ret = i2c_set_chip_offset_len(dev, alen);
	if (ret)
		return i2c_report_err(ret, I2C_ERR_WRITE);
#endif
wdenk's avatar
wdenk committed
1051 1052 1053 1054 1055 1056

	/*
	 * Length is the number of objects, not number of bytes.
	 */
	length = 1;
	length = simple_strtoul(argv[3], NULL, 16);
1057
	if (length > sizeof(bytes))
wdenk's avatar
wdenk committed
1058 1059 1060 1061 1062 1063
		length = sizeof(bytes);

	/*
	 * The delay time (uSec) is optional.
	 */
	delay = 1000;
1064
	if (argc > 3)
wdenk's avatar
wdenk committed
1065 1066 1067 1068
		delay = simple_strtoul(argv[4], NULL, 10);
	/*
	 * Run the loop...
	 */
1069
	while (1) {
1070
#ifdef CONFIG_DM_I2C
1071
		ret = dm_i2c_read(dev, addr, bytes, length);
1072 1073 1074 1075 1076
#else
		ret = i2c_read(chip, addr, alen, bytes, length);
#endif
		if (ret)
			i2c_report_err(ret, I2C_ERR_READ);
wdenk's avatar
wdenk committed
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
		udelay(delay);
	}

	/* NOTREACHED */
	return 0;
}

/*
 * The SDRAM command is separately configured because many
 * (most?) embedded boards don't use SDRAM DIMMs.
1087 1088
 *
 * FIXME: Document and probably move elsewhere!
wdenk's avatar
wdenk committed
1089
 */
1090
#if defined(CONFIG_CMD_SDRAM)
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
static void print_ddr2_tcyc (u_char const b)
{
	printf ("%d.", (b >> 4) & 0x0F);
	switch (b & 0x0F) {
	case 0x0:
	case 0x1:
	case 0x2:
	case 0x3:
	case 0x4:
	case 0x5:
	case 0x6:
	case 0x7:
	case 0x8:
	case 0x9:
		printf ("%d ns\n", b & 0x0F);
		break;
	case 0xA:
		puts ("25 ns\n");
		break;
	case 0xB:
		puts ("33 ns\n");
		break;
	case 0xC:
		puts ("66 ns\n");
		break;
	case 0xD:
		puts ("75 ns\n");
		break;
	default:
		puts ("?? ns\n");
		break;
	}
}

static void decode_bits (u_char const b, char const *str[], int const do_once)
{
	u_char mask;

	for (mask = 0x80; mask != 0x00; mask >>= 1, ++str) {
		if (b & mask) {
			puts (*str);
			if (do_once)
				return;
		}
	}
}
wdenk's avatar
wdenk committed
1137 1138 1139

/*
 * Syntax:
1140
 *	i2c sdram {i2c_chip}
wdenk's avatar
wdenk committed
1141
 */
1142
static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
wdenk's avatar
wdenk committed
1143
{
1144
	enum { unknown, EDO, SDRAM, DDR, DDR2, DDR3, DDR4 } type;
1145

1146
	uint	chip;
wdenk's avatar
wdenk committed
1147 1148 1149 1150
	u_char	data[128];
	u_char	cksum;
	int	j;

1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194
	static const char *decode_CAS_DDR2[] = {
		" TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD"
	};

	static const char *decode_CAS_default[] = {
		" TBD", " 7", " 6", " 5", " 4", " 3", " 2", " 1"
	};

	static const char *decode_CS_WE_default[] = {
		" TBD", " 6", " 5", " 4", " 3", " 2", " 1", " 0"
	};

	static const char *decode_byte21_default[] = {
		"  TBD (bit 7)\n",
		"  Redundant row address\n",
		"  Differential clock input\n",
		"  Registerd DQMB inputs\n",
		"  Buffered DQMB inputs\n",
		"  On-card PLL\n",
		"  Registered address/control lines\n",
		"  Buffered address/control lines\n"
	};

	static const char *decode_byte22_DDR2[] = {
		"  TBD (bit 7)\n",
		"  TBD (bit 6)\n",
		"  TBD (bit 5)\n",
		"  TBD (bit 4)\n",
		"  TBD (bit 3)\n",
		"  Supports partial array self refresh\n",
		"  Supports 50 ohm ODT\n",
		"  Supports weak driver\n"
	};

	static const char *decode_row_density_DDR2[] = {
		"512 MiB", "256 MiB", "128 MiB", "16 GiB",
		"8 GiB", "4 GiB", "2 GiB", "1 GiB"
	};

	static const char *decode_row_density_default[] = {
		"512 MiB", "256 MiB", "128 MiB", "64 MiB",
		"32 MiB", "16 MiB", "8 MiB", "4 MiB"
	};

1195
	if (argc < 2)
1196
		return CMD_RET_USAGE;
1197

wdenk's avatar
wdenk committed
1198 1199
	/*
	 * Chip is always specified.
1200 1201
	 */
	chip = simple_strtoul (argv[1], NULL, 16);
wdenk's avatar
wdenk committed
1202

1203
	if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) {
1204
		puts ("No SDRAM Serial Presence Detect found.\n");
wdenk's avatar
wdenk committed
1205 1206 1207 1208 1209 1210 1211
		return 1;
	}

	cksum = 0;
	for (j = 0; j < 63; j++) {
		cksum += data[j];
	}
1212
	if (cksum != data[63]) {
wdenk's avatar
wdenk committed
1213
		printf ("WARNING: Configuration data checksum failure:\n"
1214
			"  is 0x%02x, calculated 0x%02x\n", data[63], cksum);
wdenk's avatar
wdenk committed
1215
	}
1216
	printf ("SPD data revision            %d.%d\n",
wdenk's avatar
wdenk committed
1217
		(data[62] >> 4) & 0x0F, data[62] & 0x0F);
1218 1219 1220
	printf ("Bytes used                   0x%02X\n", data[0]);
	printf ("Serial memory size           0x%02X\n", 1 << data[1]);

1221
	puts ("Memory type                  ");
1222
	switch (data[2]) {
1223 1224 1225 1226 1227 1228 1229 1230
	case 2:
		type = EDO;
		puts ("EDO\n");
		break;
	case 4:
		type = SDRAM;
		puts ("SDRAM\n");
		break;
1231 1232 1233 1234
	case 7:
		type = DDR;
		puts("DDR\n");
		break;
1235 1236 1237 1238
	case 8:
		type = DDR2;
		puts ("DDR2\n");
		break;
1239 1240 1241 1242 1243 1244 1245 1246
	case 11:
		type = DDR3;
		puts("DDR3\n");
		break;
	case 12:
		type = DDR4;
		puts("DDR4\n");
		break;
1247 1248 1249 1250
	default:
		type = unknown;
		puts ("unknown\n");
		break;
wdenk's avatar
wdenk committed
1251
	}
1252

1253
	puts ("Row address bits             ");
1254
	if ((data[3] & 0x00F0) == 0)
1255
		printf ("%d\n", data[3] & 0x0F);
1256
	else
1257 1258
		printf ("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F);

1259
	puts ("Column address bits          ");
1260
	if ((data[4] & 0x00F0) == 0)
1261
		printf ("%d\n", data[4] & 0x0F);
1262
	else
1263
		printf ("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F);
1264 1265 1266

	switch (type) {
	case DDR2:
1267 1268
		printf ("Number of ranks              %d\n",
			(data[5] & 0x07) + 1);
1269 1270
		break;
	default:
1271
		printf ("Module rows                  %d\n", data[5]);
1272 1273 1274 1275 1276
		break;
	}

	switch (type) {
	case DDR2:
1277
		printf ("Module data width            %d bits\n", data[6]);
1278 1279
		break;
	default:
1280 1281
		printf ("Module data width            %d bits\n",
			(data[7] << 8) | data[6]);
1282 1283 1284
		break;
	}

1285
	puts ("Interface signal levels      ");
wdenk's avatar
wdenk committed
1286
	switch(data[8]) {
1287
		case 0:  puts ("TTL 5.0 V\n");	break;
1288
		case 1:  puts ("LVTTL\n");	break;
1289 1290 1291 1292
		case 2:  puts ("HSTL 1.5 V\n");	break;
		case 3:  puts ("SSTL 3.3 V\n");	break;
		case 4:  puts ("SSTL 2.5 V\n");	break;
		case 5:  puts ("SSTL 1.8 V\n");	break;
1293
		default: puts ("unknown\n");	break;
wdenk's avatar
wdenk committed
1294
	}
1295 1296 1297

	switch (type) {
	case DDR2:
1298 1299
		printf ("SDRAM cycle time             ");
		print_ddr2_tcyc (data[9]);
1300 1301
		break;
	default:
1302 1303
		printf ("SDRAM cycle time             %d.%d ns\n",
			(data[9] >> 4) & 0x0F, data[9] & 0x0F);
1304 1305 1306 1307 1308
		break;
	}

	switch (type) {
	case DDR2:
1309 1310
		printf ("SDRAM access time            0.%d%d ns\n",
			(data[10] >> 4) & 0x0F, data[10] & 0x0F);
1311 1312
		break;
	default:
1313 1314
		printf ("SDRAM access time            %d.%d ns\n",
			(data[10] >> 4) & 0x0F, data[10] & 0x0F);
1315 1316 1317
		break;
	}

1318
	puts ("EDC configuration            ");
1319
	switch (data[11]) {
1320 1321 1322 1323
		case 0:  puts ("None\n");	break;
		case 1:  puts ("Parity\n");	break;
		case 2:  puts ("ECC\n");	break;
		default: puts ("unknown\n");	break;
wdenk's avatar
wdenk committed
1324
	}
1325

1326
	if ((data[12] & 0x80) == 0)
1327
		puts ("No self refresh, rate        ");
1328
	else
1329
		puts ("Self refresh, rate           ");
1330

wdenk's avatar
wdenk committed
1331
	switch(data[12] & 0x7F) {
1332 1333 1334 1335 1336 1337
		case 0:  puts ("15.625 us\n");	break;
		case 1:  puts ("3.9 us\n");	break;
		case 2:  puts ("7.8 us\n");	break;
		case 3:  puts ("31.3 us\n");	break;
		case 4:  puts ("62.5 us\n");	break;
		case 5:  puts ("125 us\n");	break;
1338
		default: puts ("unknown\n");	break;
wdenk's avatar
wdenk committed
1339
	}
1340 1341 1342

	switch (type) {
	case DDR2:
1343
		printf ("SDRAM width (primary)        %d\n", data[13]);
1344 1345
		break;
	default:
1346
		printf ("SDRAM width (primary)        %d\n", data[13] & 0x7F);