spi.c 16.1 KB
Newer Older
1 2 3
/*
 * This file is part of the flashrom project.
 *
4 5
 * Copyright (C) 2007, 2008 Carl-Daniel Hailfinger
 * Copyright (C) 2008 Ronald Hoogenboom <ronald@zonnet.nl>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

/*
 * Contains the generic SPI framework
 */

#include <stdio.h>
#include <pci/pci.h>
#include <stdint.h>
#include <string.h>
#include "flash.h"

#define ITE_SUPERIO_PORT1	0x2e
#define ITE_SUPERIO_PORT2	0x4e

34
/* Read Electronic ID */
35
#define JEDEC_RDID	0x9f
36 37 38
#define JEDEC_RDID_OUTSIZE	0x01
#define JEDEC_RDID_INSIZE	0x03

39
/* Write Enable */
40
#define JEDEC_WREN	0x06
41 42 43 44
#define JEDEC_WREN_OUTSIZE	0x01
#define JEDEC_WREN_INSIZE	0x00

/* Write Disable */
45
#define JEDEC_WRDI	0x04
46 47 48
#define JEDEC_WRDI_OUTSIZE	0x01
#define JEDEC_WRDI_INSIZE	0x00

49
/* Chip Erase 0x60 is supported by Macronix/SST chips. */
50
#define JEDEC_CE_60	0x60
51 52
#define JEDEC_CE_60_OUTSIZE	0x01
#define JEDEC_CE_60_INSIZE	0x00
53

54
/* Chip Erase 0xc7 is supported by ST/EON/Macronix chips. */
55
#define JEDEC_CE_C7	0xc7
56 57
#define JEDEC_CE_C7_OUTSIZE	0x01
#define JEDEC_CE_C7_INSIZE	0x00
58

59
/* Block Erase 0x52 is supported by SST chips. */
60
#define JEDEC_BE_52	0x52
61 62
#define JEDEC_BE_52_OUTSIZE	0x04
#define JEDEC_BE_52_INSIZE	0x00
63 64

/* Block Erase 0xd8 is supported by EON/Macronix chips. */
65
#define JEDEC_BE_D8	0xd8
66 67
#define JEDEC_BE_D8_OUTSIZE	0x04
#define JEDEC_BE_D8_INSIZE	0x00
68 69

/* Sector Erase 0x20 is supported by Macronix/SST chips. */
70
#define JEDEC_SE	0x20
71 72 73
#define JEDEC_SE_OUTSIZE	0x04
#define JEDEC_SE_INSIZE	0x00

74
/* Read Status Register */
75
#define JEDEC_RDSR	0x05
76 77 78 79
#define JEDEC_RDSR_OUTSIZE	0x01
#define JEDEC_RDSR_INSIZE	0x01
#define JEDEC_RDSR_BIT_WIP	(0x01 << 0)

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
/* Write Status Register */
#define JEDEC_WRSR	0x01
#define JEDEC_WRSR_OUTSIZE	0x02
#define JEDEC_WRSR_INSIZE	0x00

/* Read the memory */
#define JEDEC_READ	0x03
#define JEDEC_READ_OUTSIZE	0x04
/*      JEDEC_READ_INSIZE : any length */

/* Write memory byte */
#define JEDEC_BYTE_PROGRAM 0x02
#define JEDEC_BYTE_PROGRAM_OUTSIZE 0x05
#define JEDEC_BYTE_PROGRAM_INSIZE 0x00

95
uint16_t it8716f_flashport = 0;
96
/* use fast 33MHz SPI (<>0) or slow 16MHz (0) */
97
int fast_spi = 1;
98

99 100
void spi_prettyprint_status_register(struct flashchip *flash);
void spi_disable_blockprotect(void);
101

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
/* Generic Super I/O helper functions */
uint8_t regval(uint16_t port, uint8_t reg)
{
	outb(reg, port);
	return inb(port + 1);
}

void regwrite(uint16_t port, uint8_t reg, uint8_t val)
{
	outb(reg, port);
	outb(val, port + 1);
}

/* Helper functions for most recent ITE IT87xx Super I/O chips */
#define CHIP_ID_BYTE1_REG	0x20
#define CHIP_ID_BYTE2_REG	0x21
static void enter_conf_mode_ite(uint16_t port)
{
	outb(0x87, port);
	outb(0x01, port);
	outb(0x55, port);
	if (port == ITE_SUPERIO_PORT1)
		outb(0x55, port);
	else
		outb(0xaa, port);
}

static void exit_conf_mode_ite(uint16_t port)
{
	regwrite(port, 0x02, 0x02);
}

134
static uint16_t find_ite_spi_flash_port(uint16_t port)
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
{
	uint8_t tmp = 0;
	uint16_t id, flashport = 0;

	enter_conf_mode_ite(port);

	id = regval(port, CHIP_ID_BYTE1_REG) << 8;
	id |= regval(port, CHIP_ID_BYTE2_REG);

	/* TODO: Handle more IT87xx if they support flash translation */
	if (id == 0x8716) {
		/* NOLDN, reg 0x24, mask out lowest bit (suspend) */
		tmp = regval(port, 0x24) & 0xFE;
		printf("Serial flash segment 0x%08x-0x%08x %sabled\n",
			0xFFFE0000, 0xFFFFFFFF, (tmp & 1 << 1) ? "en" : "dis");
		printf("Serial flash segment 0x%08x-0x%08x %sabled\n",
			0x000E0000, 0x000FFFFF, (tmp & 1 << 1) ? "en" : "dis");
		printf("Serial flash segment 0x%08x-0x%08x %sabled\n",
			0xFFEE0000, 0xFFEFFFFF, (tmp & 1 << 2) ? "en" : "dis");
		printf("Serial flash segment 0x%08x-0x%08x %sabled\n",
			0xFFF80000, 0xFFFEFFFF, (tmp & 1 << 3) ? "en" : "dis");
		printf("LPC write to serial flash %sabled\n",
			(tmp & 1 << 4) ? "en" : "dis");
158
		printf("serial flash pin %i\n", (tmp & 1 << 5) ? 87 : 29);
159 160 161 162 163 164 165 166 167
		/* LDN 0x7, reg 0x64/0x65 */
		regwrite(port, 0x07, 0x7);
		flashport = regval(port, 0x64) << 8;
		flashport |= regval(port, 0x65);
	}
	exit_conf_mode_ite(port);
	return flashport;
}

168 169 170 171 172 173 174 175
int it87xx_probe_spi_flash(const char *name)
{
	it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT1);
	if (!it8716f_flashport)
		it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT2);
	return (!it8716f_flashport);
}

176 177 178 179 180 181
/* The IT8716F only supports commands with length 1,2,4,5 bytes including
   command byte and can not read more than 3 bytes from the device.
   This function expects writearr[0] to be the first byte sent to the device,
   whereas the IT8716F splits commands internally into address and non-address
   commands with the address in inverse wire order. That's why the register
   ordering in case 4 and 5 may seem strange. */
182
static int it8716f_spi_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr)
183 184
{
	uint8_t busy, writeenc;
185 186
	int i;

187
	do {
188
		busy = inb(it8716f_flashport) & 0x80;
189 190
	} while (busy);
	if (readcnt > 3) {
191
		printf("%s called with unsupported readcnt %i.\n",
192 193 194 195 196
			__FUNCTION__, readcnt);
		return 1;
	}
	switch (writecnt) {
	case 1:
197
		outb(writearr[0], it8716f_flashport + 1);
198 199 200
		writeenc = 0x0;
		break;
	case 2:
201 202
		outb(writearr[0], it8716f_flashport + 1);
		outb(writearr[1], it8716f_flashport + 7);
203 204 205
		writeenc = 0x1;
		break;
	case 4:
206 207 208 209
		outb(writearr[0], it8716f_flashport + 1);
		outb(writearr[1], it8716f_flashport + 4);
		outb(writearr[2], it8716f_flashport + 3);
		outb(writearr[3], it8716f_flashport + 2);
210 211 212
		writeenc = 0x2;
		break;
	case 5:
213 214 215 216 217
		outb(writearr[0], it8716f_flashport + 1);
		outb(writearr[1], it8716f_flashport + 4);
		outb(writearr[2], it8716f_flashport + 3);
		outb(writearr[3], it8716f_flashport + 2);
		outb(writearr[4], it8716f_flashport + 7);
218 219 220
		writeenc = 0x3;
		break;
	default:
221
		printf("%s called with unsupported writecnt %i.\n",
222 223 224
			__FUNCTION__, writecnt);
		return 1;
	}
225 226
	/* Start IO, 33 or 16 MHz, readcnt input bytes, writecnt output bytes.
	 * Note:
227
	 * We can't use writecnt directly, but have to use a strange encoding.
228
	 */ 
229
	outb(((0x4 + (fast_spi ? 1 : 0)) << 4) | ((readcnt & 0x3) << 2) | (writeenc), it8716f_flashport);
230

231 232
	if (readcnt > 0) {
		do {
233
			busy = inb(it8716f_flashport) & 0x80;
234 235 236
		} while (busy);

		for (i = 0; i < readcnt; i++) {
237
			readarr[i] = inb(it8716f_flashport + 5 + i);
238
		}
239 240
	}

241 242 243
	return 0;
}

244
int spi_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr)
245 246
{
	if (it8716f_flashport)
247
		return it8716f_spi_command(writecnt, readcnt, writearr, readarr);
248
	printf_debug("%s called, but no SPI chipset detected\n", __FUNCTION__);
249 250 251
	return 1;
}

252
static int spi_rdid(unsigned char *readarr)
253
{
254
	const unsigned char cmd[JEDEC_RDID_OUTSIZE] = {JEDEC_RDID};
255

256
	if (spi_command(JEDEC_RDID_OUTSIZE, JEDEC_RDID_INSIZE, cmd, readarr))
257
		return 1;
258
	printf_debug("RDID returned %02x %02x %02x.\n", readarr[0], readarr[1], readarr[2]);
259 260 261
	return 0;
}

262
void spi_write_enable()
263
{
264
	const unsigned char cmd[JEDEC_WREN_OUTSIZE] = {JEDEC_WREN};
265 266

	/* Send WREN (Write Enable) */
267
	spi_command(JEDEC_WREN_OUTSIZE, JEDEC_WREN_INSIZE, cmd, NULL);
268 269
}

270
void spi_write_disable()
271
{
272
	const unsigned char cmd[JEDEC_WRDI_OUTSIZE] = {JEDEC_WRDI};
273 274

	/* Send WRDI (Write Disable) */
275
	spi_command(JEDEC_WRDI_OUTSIZE, JEDEC_WRDI_INSIZE, cmd, NULL);
276 277
}

278 279 280
int probe_spi(struct flashchip *flash)
{
	unsigned char readarr[3];
281 282
	uint32_t manuf_id;
	uint32_t model_id;
283
	if (!spi_rdid(readarr)) {
284 285 286 287 288 289 290 291
		/* Check if this is a continuation vendor ID */
		if (readarr[0] == 0x7f) {
			manuf_id = (readarr[0] << 8) | readarr[1];
			model_id = readarr[2];
		} else {
			manuf_id = readarr[0];
			model_id = (readarr[1] << 8) | readarr[2];
		}
292
		printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, manuf_id, model_id);
293 294 295
		if (manuf_id == flash->manufacture_id &&
		    model_id == flash->model_id) {
			/* Print the status register to tell the
296 297
			 * user about possible write protection.
			 */
298
			spi_prettyprint_status_register(flash);
299

300
			return 1;
301
		}
302 303 304 305
		/* Test if this is a pure vendor match. */
		if (manuf_id == flash->manufacture_id &&
		    GENERIC_DEVICE_ID == flash->model_id)
			return 1;
306 307 308 309 310
	}

	return 0;
}

311
uint8_t spi_read_status_register()
312
{
313
	const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = {JEDEC_RDSR};
314 315 316
	unsigned char readarr[1];

	/* Read Status Register */
317
	spi_command(JEDEC_RDSR_OUTSIZE, JEDEC_RDSR_INSIZE, cmd, readarr);
318 319 320
	return readarr[0];
}

321
/* Prettyprint the status register. Common definitions.
322
 */
323
void spi_prettyprint_status_register_common(uint8_t status)
324
{
325
	printf_debug("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
326
		"%sset\n", (status & (1 << 5)) ? "" : "not ");
327
	printf_debug("Chip status register: Bit 4 / Block Protect 2 (BP2) is "
328
		"%sset\n", (status & (1 << 4)) ? "" : "not ");
329
	printf_debug("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
330
		"%sset\n", (status & (1 << 3)) ? "" : "not ");
331
	printf_debug("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
332 333 334
		"%sset\n", (status & (1 << 2)) ? "" : "not ");
	printf_debug("Chip status register: Write Enable Latch (WEL) is "
		"%sset\n", (status & (1 << 1)) ? "" : "not ");
335
	printf_debug("Chip status register: Write In Progress (WIP/BUSY) is "
336 337 338
		"%sset\n", (status & (1 << 0)) ? "" : "not ");
}

339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
/* Prettyprint the status register. Works for
 * ST M25P series
 * MX MX25L series
 */
void spi_prettyprint_status_register_st_m25p(uint8_t status)
{
	printf_debug("Chip status register: Status Register Write Disable "
		"(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not ");
	printf_debug("Chip status register: Bit 6 is "
		"%sset\n", (status & (1 << 6)) ? "" : "not ");
	spi_prettyprint_status_register_common(status);
}

/* Prettyprint the status register. Works for
 * SST 25VF016
 */
void spi_prettyprint_status_register_sst25vf016(uint8_t status)
{
357
	const char *bpt[] = {
358 359 360 361 362 363
		"none",
		"1F0000H-1FFFFFH",
		"1E0000H-1FFFFFH",
		"1C0000H-1FFFFFH",
		"180000H-1FFFFFH",
		"100000H-1FFFFFH",
364
		"all", "all"
365 366 367 368 369 370 371 372 373 374 375
	};
	printf_debug("Chip status register: Block Protect Write Disable "
		"(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not ");
	printf_debug("Chip status register: Auto Address Increment Programming "
		"(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not ");
	spi_prettyprint_status_register_common(status);
	printf_debug("Resulting block protection : %s\n",
		bpt[(status & 0x1c) >> 2]);
}

void spi_prettyprint_status_register(struct flashchip *flash)
376 377 378
{
	uint8_t status;

379
	status = spi_read_status_register();
380 381 382 383 384
	printf_debug("Chip status register is %02x\n", status);
	switch (flash->manufacture_id) {
	case ST_ID:
	case MX_ID:
		if ((flash->model_id & 0xff00) == 0x2000)
385 386 387 388 389
			spi_prettyprint_status_register_st_m25p(status);
		break;
	case SST_ID:
		if (flash->model_id == SST_25VF016B)
			spi_prettyprint_status_register_sst25vf016(status);
390 391 392 393
		break;
	}
}
	
394
int spi_chip_erase_c7(struct flashchip *flash)
395
{
396
	const unsigned char cmd[JEDEC_CE_C7_OUTSIZE] = {JEDEC_CE_C7};
397
	
398
	spi_disable_blockprotect();
399
	spi_write_enable();
400
	/* Send CE (Chip Erase) */
401
	spi_command(JEDEC_CE_C7_OUTSIZE, JEDEC_CE_C7_INSIZE, cmd, NULL);
402 403 404
	/* Wait until the Write-In-Progress bit is cleared.
	 * This usually takes 1-85 s, so wait in 1 s steps.
	 */
405
	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
406 407 408 409
		sleep(1);
	return 0;
}

410 411 412 413 414
/* Block size is usually
 * 64k for Macronix
 * 32k for SST
 * 4-32k non-uniform for EON
 */
415
int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr)
416
{
417
	unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = {JEDEC_BE_D8};
418 419 420 421

	cmd[1] = (addr & 0x00ff0000) >> 16;
	cmd[2] = (addr & 0x0000ff00) >> 8;
	cmd[3] = (addr & 0x000000ff);
422
	spi_write_enable();
423
	/* Send BE (Block Erase) */
424
	spi_command(JEDEC_BE_D8_OUTSIZE, JEDEC_BE_D8_INSIZE, cmd, NULL);
425 426 427
	/* Wait until the Write-In-Progress bit is cleared.
	 * This usually takes 100-4000 ms, so wait in 100 ms steps.
	 */
428
	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
429 430 431 432 433
		usleep(100 * 1000);
	return 0;
}

/* Sector size is usually 4k, though Macronix eliteflash has 64k */
434
int spi_sector_erase(const struct flashchip *flash, unsigned long addr)
435
{
436
	unsigned char cmd[JEDEC_SE_OUTSIZE] = {JEDEC_SE};
437 438 439 440
	cmd[1] = (addr & 0x00ff0000) >> 16;
	cmd[2] = (addr & 0x0000ff00) >> 8;
	cmd[3] = (addr & 0x000000ff);

441
	spi_write_enable();
442
	/* Send SE (Sector Erase) */
443
	spi_command(JEDEC_SE_OUTSIZE, JEDEC_SE_INSIZE, cmd, NULL);
444 445 446
	/* Wait until the Write-In-Progress bit is cleared.
	 * This usually takes 15-800 ms, so wait in 10 ms steps.
	 */
447
	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
448 449 450 451 452
		usleep(10 * 1000);
	return 0;
}

/* Page size is usually 256 bytes */
453 454 455
void it8716f_spi_page_program(int block, uint8_t *buf, uint8_t *bios) {
	int i;

456
	spi_write_enable();
457
	outb(0x06 , it8716f_flashport + 1);
458
	outb(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport);
459 460 461 462
	for (i = 0; i < 256; i++) {
		bios[256 * block + i] = buf[256 * block + i];
	}
	outb(0, it8716f_flashport);
463 464 465
	/* Wait until the Write-In-Progress bit is cleared.
	 * This usually takes 1-10 ms, so wait in 1 ms steps.
	 */
466
	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
467 468 469
		usleep(1000);
}

470
void spi_page_program(int block, uint8_t *buf, uint8_t *bios)
471 472 473 474 475
{
	if (it8716f_flashport)
		it8716f_spi_page_program(block, buf, bios);
}

476 477 478 479 480 481
/*
 * This is according the SST25VF016 datasheet, who knows it is more
 * generic that this...
 */
void spi_write_status_register(int status)
{
482
	const unsigned char cmd[JEDEC_WRSR_OUTSIZE] = {JEDEC_WRSR, (unsigned char)status};
483 484

	/* Send WRSR (Write Status Register) */
485
	spi_command(JEDEC_WRSR_OUTSIZE, JEDEC_WRSR_INSIZE, cmd, NULL);
486 487 488 489 490 491 492 493 494 495 496 497
}

void spi_byte_program(int address, uint8_t byte)
{
	const unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE] = {JEDEC_BYTE_PROGRAM,
		(address>>16)&0xff,
		(address>>8)&0xff,
		(address>>0)&0xff,
		byte
	};

	/* Send Byte-Program */
498
	spi_command(JEDEC_BYTE_PROGRAM_OUTSIZE, JEDEC_BYTE_PROGRAM_INSIZE, cmd, NULL);
499 500 501 502 503 504
}

void spi_disable_blockprotect(void)
{
	uint8_t status;

505
	status = spi_read_status_register();
506 507 508
	/* If there is block protection in effect, unprotect it first. */
	if ((status & 0x3c) != 0) {
		printf_debug("Some block protection in effect, disabling\n");
509
		spi_write_enable();
510 511 512 513 514 515 516 517 518 519 520 521
		spi_write_status_register(status & ~0x3c);
	}
}

/*
 * IT8716F only allows maximum of 512 kb SPI mapped to LPC memory cycles
 * Program chip using firmware cycle byte programming. (SLOW!)
 */
int it8716f_over512k_spi_chip_write(struct flashchip *flash, uint8_t *buf)
{
	int total_size = 1024 * flash->total_size;
	int i;
522
	fast_spi = 0;
523 524

	spi_disable_blockprotect();
525
	for (i = 0; i < total_size; i++) {
526
		spi_write_enable();
527
		spi_byte_program(i, buf[i]);
528
		while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
529
			myusec_delay(10);
530 531 532 533 534 535 536 537 538
	}
	/* resume normal ops... */
	outb(0x20, it8716f_flashport);
	return 0;
}

void spi_3byte_read(int address, uint8_t *bytes, int len)
{
	const unsigned char cmd[JEDEC_READ_OUTSIZE] = {JEDEC_READ,
539 540 541
		(address >> 16) & 0xff,
		(address >> 8) & 0xff,
		(address >> 0) & 0xff,
542 543 544
	};

	/* Send Read */
545
	spi_command(JEDEC_READ_OUTSIZE, len, cmd, bytes);
546 547 548 549 550 551
}

/*
 * IT8716F only allows maximum of 512 kb SPI mapped to LPC memory cycles
 * Need to read this big flash using firmware cycles 3 byte at a time.
 */
552
int spi_chip_read(struct flashchip *flash, uint8_t *buf)
553 554 555
{
	int total_size = 1024 * flash->total_size;
	int i;
556
	fast_spi = 0;
557 558

	if (total_size > 512 * 1024) {
559 560 561 562 563
		for (i = 0; i < total_size; i += 3) {
			int toread = 3;
			if (total_size - i < toread)
				toread = total_size - i;
			spi_3byte_read(i, buf + i, toread);
564 565 566 567 568 569 570
		}
	} else {
		memcpy(buf, (const char *)flash->virtual_memory, total_size);
	}
	return 0;
}

571
int spi_chip_write(struct flashchip *flash, uint8_t *buf) {
572 573
	int total_size = 1024 * flash->total_size;
	int i;
574 575 576 577
	if (total_size > 512 * 1024) {
		it8716f_over512k_spi_chip_write(flash, buf);
	} else {
		for (i = 0; i < total_size / 256; i++) {
578
			spi_page_program(i, buf, (uint8_t *)flash->virtual_memory);
579
		}
580 581 582 583
	}
	return 0;
}