Commit bb4b1e3f authored by Bjorn Andersson's avatar Bjorn Andersson

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

parents 778279f4 80e8eaab
...@@ -366,6 +366,7 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, ...@@ -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); geni_se_select_mode(se, GENI_SE_FIFO);
writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN); 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)) { if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, &rx_dma)) {
geni_se_select_mode(se, GENI_SE_FIFO); 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, ...@@ -373,8 +374,6 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
dma_buf = NULL; dma_buf = NULL;
} }
geni_se_setup_m_cmd(se, I2C_READ, m_param);
time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
if (!time_left) if (!time_left)
geni_i2c_abort_xfer(gi2c); 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, ...@@ -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); geni_se_select_mode(se, GENI_SE_FIFO);
writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN); 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)) { if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, &tx_dma)) {
geni_se_select_mode(se, GENI_SE_FIFO); 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, ...@@ -415,8 +415,6 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
dma_buf = NULL; dma_buf = NULL;
} }
geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
if (!dma_buf) /* Get FIFO IRQ */ if (!dma_buf) /* Get FIFO IRQ */
writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG); writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG);
......
...@@ -266,36 +266,63 @@ EXPORT_SYMBOL(geni_se_init); ...@@ -266,36 +266,63 @@ EXPORT_SYMBOL(geni_se_init);
static void geni_se_select_fifo_mode(struct geni_se *se) static void geni_se_select_fifo_mode(struct geni_se *se)
{ {
u32 proto = geni_se_read_proto(se); u32 proto = geni_se_read_proto(se);
u32 val; u32 val, val_old;
geni_se_irq_clear(se); 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) { 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_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN;
val |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_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); writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN); val_old = val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
if (proto != GENI_SE_UART)
val |= S_CMD_DONE_EN; val |= S_CMD_DONE_EN;
writel_relaxed(val, se->base + SE_GENI_S_IRQ_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; val &= ~GENI_DMA_MODE_EN;
writel_relaxed(val, se->base + SE_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) 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); 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; val |= GENI_DMA_MODE_EN;
writel_relaxed(val, se->base + SE_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, ...@@ -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(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(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(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; return 0;
} }
EXPORT_SYMBOL(geni_se_tx_dma_prep); 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, ...@@ -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); 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 */ /* RX does not have EOT buffer type bit. So just reset RX_ATTR */
writel_relaxed(0, se->base + SE_DMA_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; return 0;
} }
EXPORT_SYMBOL(geni_se_rx_dma_prep); EXPORT_SYMBOL(geni_se_rx_dma_prep);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment