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; }
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; }
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; }
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; }
/* * 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; }
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; }
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(®) == 0) { if (!(reg & SFLASH_WRITE_IN_PROGRESS)) return 0; if (stopwatch_expired(&sw)) return -1; } return -1; }
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)) ; }
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; }