Пример #1
0
/* Drain FDATAn FIFO after a read transaction populates data. */
static void drain_xfer_fifo(struct spi_ctx *ctx, void *dest, size_t len)
{
	len = min(len, SPIBAR_FDATA_FIFO_SIZE);

	/* YES! memcpy() works. FDATAn does not require 32-bit accesses. */
	memcpy(dest, (void*)(ctx->mmio_base + SPIBAR_FDATA(0)), len);
}
Пример #2
0
/*
 * Minimal set of commands to read WPSR from SPI.
 * Don't use this code outside romstage -- it trashes the opmenu table.
 * Returns 0 on success, < 0 on failure.
 */
int early_spi_read_wpsr(u8 *sr)
{
	int retry;

	/* No address associated with rdsr */
	SPIBAR8(SPIBAR_OPTYPE) = 0x0;
	/* Setup opcode[0] = read wpsr */
	SPIBAR8(SPIBAR_OPMENU_LOWER) = 0x5;

	/* Start transaction */
	SPIBAR16(SPIBAR_SSFC) = SPIBAR_SSFC_DATA | SPIBAR_SSFC_GO;

	/* Wait for error / complete status */
	for (retry = SPI_RETRY; retry; retry--) {
		u16 status = SPIBAR16(SPIBAR_SSFS);
		if (status & SPIBAR_SSFS_ERROR) {
			printk(BIOS_ERR, "SPI rdsr failed\n");
			return -1;
		} else if (status & SPIBAR_SSFS_DONE) {
			break;
		}

		udelay(SPI_DELAY);
	}

	*sr = SPIBAR32(SPIBAR_FDATA(0)) & 0xff;
	return 0;
}
Пример #3
0
/* Fill FDATAn FIFO in preparation for a write transaction. */
static void fill_xfer_fifo(struct spi_ctx *ctx, const void *data, size_t len)
{
	len = min(len, SPIBAR_FDATA_FIFO_SIZE);

	/* YES! memcpy() works. FDATAn does not require 32-bit accesses. */
	memcpy((void*)(ctx->mmio_base + SPIBAR_FDATA(0)), data, len);
}
Пример #4
0
static int early_spi_read_block(u32 offset, u8 size, u8 *buffer)
{
	u32 *ptr32 = (u32*)buffer;
	u32 i;

	/* Clear status bits */
	SPIBAR16(SPIBAR_HSFS) |= SPIBAR_HSFS_AEL | SPIBAR_HSFS_FCERR |
		SPIBAR_HSFS_FDONE;

	if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) {
		printk(BIOS_ERR, "SPI ERROR: transaction in progress\n");
		return -1;
	}

	/* Set flash address */
	SPIBAR32(SPIBAR_FADDR) = offset;

	/* Setup read transaction */
	SPIBAR16(SPIBAR_HSFC) = SPIBAR_HSFC_BYTE_COUNT(size) |
		SPIBAR_HSFC_CYCLE_READ;

	/* Start transaction */
	SPIBAR16(SPIBAR_HSFC) |= SPIBAR_HSFC_GO;

	/* Wait for completion */
	for (i = 0; i < SPI_RETRY; i++) {
		if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) {
			/* Cycle in progress, wait 1ms */
			udelay(SPI_DELAY);
			continue;
		}

		if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_AEL) {
			printk(BIOS_ERR, "SPI ERROR: Access Error\n");
			return -1;

		}

		if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_FCERR) {
			printk(BIOS_ERR, "SPI ERROR: Flash Cycle Error\n");
			return -1;
		}
		break;
	}

	if (i >= SPI_RETRY) {
		printk(BIOS_ERR, "SPI ERROR: Timeout\n");
		return -1;
	}

	/* Read the data */
	for (i = 0; i < size; i+=sizeof(u32)) {
		if (size-i >= 4) {
			/* reading >= dword */
			*ptr32++ = SPIBAR32(SPIBAR_FDATA(i/sizeof(u32)));
		} else {
			/* reading < dword */
			u8 j, *ptr8 = (u8*)ptr32;
			u32 temp = SPIBAR32(SPIBAR_FDATA(i/sizeof(u32)));
			for (j = 0; j < (size-i); j++) {
				*ptr8++ = temp & 0xff;
				temp >>= 8;
			}
		}
	}

	return size;
}