示例#1
0
void flash_wren(void) {
	uint8_t tx[8] = { FLASH_CMD_WREN,
		FLASH_CMD_WRDI };
	struct spi_transfer td[] = { {NULL, &tx[0], 1 },
		{NULL, &tx[1], 1} };
//	spi_exchange(&td[1], 1);
	spi_exchange(&td[0], 1);
	flash_poll(FLASH_MOD_POLLWREN);
}
示例#2
0
static int
flash_eraseblk(unsigned long addr)
{
	unsigned long a;
	uint16 st;

	a = (unsigned long)addr;
	if (a >= flashutl_desc->size)
		return 1;

	a = block(a, BLOCK_BASE);

	/* Ensure blocks are unlocked (for intel chips) */
	if (flashutl_cmd->type == BSC) {
		scmd((unsigned char)INTEL_UNLOCK1, a);
		scmd((unsigned char)INTEL_UNLOCK2, a);
	}

	if (flashutl_cmd->pre_erase)
		cmd(flashutl_cmd->pre_erase, CMD_ADDR);
	if (flashutl_cmd->erase_block)
		cmd(flashutl_cmd->erase_block, a);
	if (flashutl_cmd->confirm)
		scmd(flashutl_cmd->confirm, a);

	if (flashutl_wsz == sizeof(uint8))
		st = flash_poll(a, 0xff);
	else
		st = flash_poll(a, 0xffff);

	flash_reset();

	if (st) {
		DPRINT(("Erase of block 0x%08lx-0x%08lx failed\n",
			a, block((unsigned long)addr, BLOCK_LIM)));
		return st;
	}

	DPRINT(("Erase of block 0x%08lx-0x%08lx done\n", a, block((unsigned long)addr, BLOCK_LIM)));

	return 0;
}
示例#3
0
static int
flash_write(unsigned long off, uint8 *src, uint nbytes)
{
	uint8 *dest;
	uint16 st, data;
	uint i, len;

	ASSERT(flashutl_desc != NULL);

	if (off >= flashutl_desc->size)
		return 1;

	ASSERT(!(off & (flashutl_wsz - 1)));

	dest = (uint8*)FLASH_ADDR(off);
	st = 0;

	while (nbytes) {
		if ((flashutl_desc->type == SCS) &&
		    flashutl_cmd->write_buf &&
		    ((off & (WBUFSIZE - 1)) == 0)) {
			/* issue write command */
			if (flashutl_cmd->write_buf)
				cmd(flashutl_cmd->write_buf, off);
			if ((st = flash_poll(off, DONE)))
				continue;

			len = MIN(nbytes, WBUFSIZE);

#ifndef MIPSEB
			/* write (length - 1) */
			cmd(len / sizeof(uint16) - 1, off);

			/* write data */
			for (i = 0; i < len; i += sizeof(uint16),
			             dest += sizeof(uint16), src += sizeof(uint16))
				*(uint16 *)dest = *(uint16 *)src;
#else
			/*
			 * BCM4710 endianness is word consistent but
			 * byte/short scrambled. This write buffer
			 * mechanism appears to be sensitive to the
			 * order of the addresses hence we need to
			 * unscramble them. We may also need to pad
			 * the source with two bytes of 0xffff in case
			 * an odd number of shorts are presented.
			 */

			/* write (padded length - 1) */
			cmd((ROUNDUP(len, sizeof(uint32)) / sizeof(uint16)) - 1, off);

			/* write data (plus pad if necessary) */
			for (i = 0; i < ROUNDUP(len, sizeof(uint32)); i += sizeof(uint32),
			             dest += sizeof(uint32), src += sizeof(uint32)) {
				*((uint16 *)dest + 1) = ((i + sizeof(uint16)) < len) ?
				        *((uint16 *)src + 1) : 0xffff;
				*(uint16 *)dest = *(uint16 *)src;
			}
#endif /* MIPSEB */

			/* write confirm */
			if (flashutl_cmd->confirm)
				cmd(flashutl_cmd->confirm, off);

			if ((st = flash_poll(off, DONE)))
				break;
		} else {
			/* issue write command */
			if (flashutl_cmd->write_word)
				cmd(flashutl_cmd->write_word, CMD_ADDR);

			/* write data */
			data = flash_readword((unsigned long)src);
			flash_writeword((unsigned long)dest, data);

			/* poll for done */
			if ((st = flash_poll(off, data)))
				break;

			len = MIN(nbytes, flashutl_wsz);
			dest += len;
			src += len;
		}

		nbytes -= len;
		off += len;
	}

	flash_reset();

	return st;
}