示例#1
0
static int crosec_spi_io(size_t req_size, size_t resp_size, void *context)
{
	struct spi_slave *slave = (struct spi_slave *)context;
	int ret = 0;

	/* Wait minimum delay between CS assertions. */
	stopwatch_wait_until_expired(&cs_cooldown_sw);

	spi_claim_bus(slave);

	 /* Allow EC to ramp up clock after being awaken.
	  * See chrome-os-partner:32223 for more details. */
	udelay(CONFIG_EC_GOOGLE_CHROMEEC_SPI_WAKEUP_DELAY_US);

	if (spi_xfer(slave, req_buf, req_size, NULL, 0)) {
		printk(BIOS_ERR, "%s: Failed to send request.\n", __func__);
		ret = -1;
		goto out;
	}

	uint8_t byte;
	struct stopwatch sw;
	// Wait 1s for a framing byte.
	stopwatch_init_usecs_expire(&sw, USECS_PER_SEC);
	while (1) {
		if (spi_xfer(slave, NULL, 0, &byte, sizeof(byte))) {
			printk(BIOS_ERR, "%s: Failed to receive byte.\n",
			       __func__);
			ret = -1;
			goto out;
		}
		if (byte == EcFramingByte)
			break;

		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR,
			       "%s: Timeout waiting for framing byte.\n",
			       __func__);
			ret = -1;
			goto out;
		}
	}

	if (spi_xfer(slave, NULL, 0, resp_buf, resp_size)) {
		printk(BIOS_ERR, "%s: Failed to receive response.\n", __func__);
		ret = -1;
	}

out:
	spi_release_bus(slave);
	stopwatch_init_usecs_expire(&cs_cooldown_sw, cs_cooldown_us);
	return ret;
}
示例#2
0
static int tegra_spi_pio_finish(struct tegra_spi_channel *spi)
{
	u8 *p = spi->in_buf;
	struct stopwatch sw;

	clrbits_le32(&spi->regs->command1, SPI_CMD1_RX_EN | SPI_CMD1_TX_EN);

	/*
	 * Allow some time in case the Rx FIFO does not yet have
	 * all packets pushed into it. See chrome-os-partner:24215.
	 */
	stopwatch_init_usecs_expire(&sw, SPI_FIFO_XFER_TIMEOUT_US);
	do {
		if (rx_fifo_count(spi) == spi_byte_count(spi))
			break;
	} while (!stopwatch_expired(&sw));

	while (!(read32(&spi->regs->fifo_status) &
				SPI_FIFO_STATUS_RX_FIFO_EMPTY)) {
		*p = read8(&spi->regs->rx_fifo);
		p++;
	}

	if (fifo_error(spi)) {
		printk(BIOS_ERR, "%s: ERROR:\n", __func__);
		dump_spi_regs(spi);
		dump_fifo_status(spi);
		return -1;
	}

	return 0;
}
示例#3
0
static int dma_read(u32 addr, u8 *buf, u32 len, uintptr_t dma_buf,
		    size_t dma_buf_len)
{
	struct stopwatch sw;

	assert(IS_ALIGNED((uintptr_t)buf, SFLASH_DMA_ALIGN) &&
	       IS_ALIGNED(len, SFLASH_DMA_ALIGN) &&
	       len <= dma_buf_len);

	/* do dma reset */
	write32(&mt8173_nor->fdma_ctl, SFLASH_DMA_SW_RESET);
	write32(&mt8173_nor->fdma_ctl, SFLASH_DMA_WDLE_EN);
	/* flash source address and dram dest address */
	write32(&mt8173_nor->fdma_fadr, addr);
	write32(&mt8173_nor->fdma_dadr, dma_buf);
	write32(&mt8173_nor->fdma_end_dadr, (dma_buf + len));
	/* start dma */
	write32(&mt8173_nor->fdma_ctl, SFLASH_DMA_TRIGGER | SFLASH_DMA_WDLE_EN);

	stopwatch_init_usecs_expire(&sw, SFLASH_POLLINGREG_US);
	while ((read32(&mt8173_nor->fdma_ctl) & SFLASH_DMA_TRIGGER) != 0) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_WARNING, "dma read timeout!\n");
			return -1;
		}
	}

	memcpy(buf, (const void *)dma_buf, len);
	return 0;
}
示例#4
0
文件: usb.c 项目: AdriDlu/coreboot
static int check_ip_clk_status(void)
{
	int u3_port_num;
	u32 check_bits;
	u32 sts1, sts2;
	struct stopwatch sw;

	u3_port_num = CAP_U3_PORT_NUM(read32(&ippc_regs->ip_xhci_cap));

	check_bits = STS1_SYSPLL_STABLE | STS1_REF_RST | STS1_SYS125_RST;
	check_bits = (u3_port_num ? STS1_U3_MAC_RST : 0);

	stopwatch_init_usecs_expire(&sw, 50000);

	do {
		if (stopwatch_expired(&sw)) {
			u3p_err("usb clocks are not stable!!!\n");
			return -1;
		}

		sts1 = read32(&ippc_regs->ip_pw_sts1) & check_bits;
		sts2 = read32(&ippc_regs->ip_pw_sts2) & STS2_U2_MAC_RST;
	} while ((sts1 != check_bits) || !sts2);

	return 0;
}
示例#5
0
/*
 * Wait for the bit at the shift position to be set in reg
 * If the bit is not set in SPI_TIMEOUT_VALUE_US return with error
 */
static int wait_status(u32 reg, u32 shift)
{
	struct stopwatch sw;

	stopwatch_init_usecs_expire(&sw, SPI_TIMEOUT_VALUE_US);
	while (!(read32_x(reg) & (1 << shift))) {
		if (stopwatch_expired(&sw))
			return -SPIM_TIMEOUT;
	}
	return SPIM_OK;
}
示例#6
0
static int polling_cmd(u32 val)
{
	struct stopwatch sw;

	stopwatch_init_usecs_expire(&sw, SFLASH_POLLINGREG_US);

	while ((read32(&mt8173_nor->cmd) & val) != 0) {
		if (stopwatch_expired(&sw))
			return -1;
	}

	return 0;
}
示例#7
0
static int wait_for_write_done(void)
{
	struct stopwatch sw;
	u8 reg;

	stopwatch_init_usecs_expire(&sw, SFLASH_POLLINGREG_US);

	while (sflashhw_read_flash_status(&reg) == 0) {
		if (!(reg & SFLASH_WRITE_IN_PROGRESS))
			return 0;
		if (stopwatch_expired(&sw))
			return -1;
	}

	return -1;
}
示例#8
0
void udelay(unsigned int usec)
{
	struct stopwatch sw;

	/*
	 * As the timer granularity is in microseconds pad the
	 * requested delay by one to get at least >= requested usec delay.
	 */
	usec += 1;

	if (!thread_yield_microseconds(usec))
		return;

	stopwatch_init_usecs_expire(&sw, usec);

	while (!stopwatch_expired(&sw))
		;
}
示例#9
0
static int wait_for_status(uint32_t status_mask, uint32_t status_expected)
{
	uint32_t status;
	struct stopwatch sw;

	stopwatch_init_usecs_expire(&sw, MAX_STATUS_TIMEOUT * 1000 * 1000);
	do {
		udelay(1000);
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "failed to get expected status %x\n",
			       status_expected);
			return false;
		}
		read_tpm_sts(&status);
	} while ((status & status_mask) != status_expected);

	return 1;
}