Commit bb4b1e3f authored by Bjorn Andersson's avatar Bjorn Andersson
Browse files

Merge tag '20201013212531.428538-1-dianders@chromium.org' into drivers-for-5.11

parents 778279f4 80e8eaab
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -366,6 +366,7 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
		geni_se_select_mode(se, GENI_SE_FIFO);

	writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN);
	geni_se_setup_m_cmd(se, I2C_READ, m_param);

	if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, &rx_dma)) {
		geni_se_select_mode(se, GENI_SE_FIFO);
@@ -373,8 +374,6 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
		dma_buf = NULL;
	}

	geni_se_setup_m_cmd(se, I2C_READ, m_param);

	time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
	if (!time_left)
		geni_i2c_abort_xfer(gi2c);
@@ -408,6 +407,7 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
		geni_se_select_mode(se, GENI_SE_FIFO);

	writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN);
	geni_se_setup_m_cmd(se, I2C_WRITE, m_param);

	if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, &tx_dma)) {
		geni_se_select_mode(se, GENI_SE_FIFO);
@@ -415,8 +415,6 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
		dma_buf = NULL;
	}

	geni_se_setup_m_cmd(se, I2C_WRITE, m_param);

	if (!dma_buf) /* Get FIFO IRQ */
		writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG);

+41 −14
Original line number Diff line number Diff line
@@ -266,35 +266,62 @@ EXPORT_SYMBOL(geni_se_init);
static void geni_se_select_fifo_mode(struct geni_se *se)
{
	u32 proto = geni_se_read_proto(se);
	u32 val;
	u32 val, val_old;

	geni_se_irq_clear(se);

	val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
	/*
	 * The RX path for the UART is asynchronous and so needs more
	 * complex logic for enabling / disabling its interrupts.
	 *
	 * Specific notes:
	 * - The done and TX-related interrupts are managed manually.
	 * - We don't RX from the main sequencer (we use the secondary) so
	 *   we don't need the RX-related interrupts enabled in the main
	 *   sequencer for UART.
	 */
	if (proto != GENI_SE_UART) {
		val_old = val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
		val |= M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN;
		val |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
	}
		if (val != val_old)
			writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);

	val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
	if (proto != GENI_SE_UART)
		val_old = val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
		val |= S_CMD_DONE_EN;
		if (val != val_old)
			writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
	}

	val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
	val_old = val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
	val &= ~GENI_DMA_MODE_EN;
	if (val != val_old)
		writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
}

static void geni_se_select_dma_mode(struct geni_se *se)
{
	u32 val;
	u32 proto = geni_se_read_proto(se);
	u32 val, val_old;

	geni_se_irq_clear(se);

	val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
	if (proto != GENI_SE_UART) {
		val_old = val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
		val &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN);
		val &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
		if (val != val_old)
			writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);

		val_old = val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
		val &= ~S_CMD_DONE_EN;
		if (val != val_old)
			writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
	}

	val_old = val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
	val |= GENI_DMA_MODE_EN;
	if (val != val_old)
		writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
}

@@ -651,7 +678,7 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
	writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_TX_PTR_L);
	writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_TX_PTR_H);
	writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
	writel_relaxed(len, se->base + SE_DMA_TX_LEN);
	writel(len, se->base + SE_DMA_TX_LEN);
	return 0;
}
EXPORT_SYMBOL(geni_se_tx_dma_prep);
@@ -688,7 +715,7 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
	writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_RX_PTR_H);
	/* RX does not have EOT buffer type bit. So just reset RX_ATTR */
	writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
	writel_relaxed(len, se->base + SE_DMA_RX_LEN);
	writel(len, se->base + SE_DMA_RX_LEN);
	return 0;
}
EXPORT_SYMBOL(geni_se_rx_dma_prep);