diff options
Diffstat (limited to 'drivers/soc/qcom/qcom-geni-se.c')
-rw-r--r-- | drivers/soc/qcom/qcom-geni-se.c | 95 |
1 files changed, 53 insertions, 42 deletions
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c index 795a2e1d59b3..ba788762835f 100644 --- a/drivers/soc/qcom/qcom-geni-se.c +++ b/drivers/soc/qcom/qcom-geni-se.c @@ -281,27 +281,14 @@ static void geni_se_select_fifo_mode(struct geni_se *se) geni_se_irq_clear(se); - /* - * 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. - */ + /* UART driver manages enabling / disabling interrupts internally */ if (proto != GENI_SE_UART) { + /* Non-UART use only primary sequencer so dont bother about S_IRQ */ 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); @@ -317,17 +304,14 @@ static void geni_se_select_dma_mode(struct geni_se *se) geni_se_irq_clear(se); + /* UART driver manages enabling / disabling interrupts internally */ if (proto != GENI_SE_UART) { + /* Non-UART use only primary sequencer so dont bother about S_IRQ */ 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); @@ -344,10 +328,6 @@ static void geni_se_select_gpi_mode(struct geni_se *se) writel(0, se->base + SE_IRQ_EN); - val = readl(se->base + SE_GENI_S_IRQ_EN); - val &= ~S_CMD_DONE_EN; - writel(val, se->base + SE_GENI_S_IRQ_EN); - val = readl(se->base + SE_GENI_M_IRQ_EN); val &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN | M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN); @@ -682,6 +662,30 @@ EXPORT_SYMBOL(geni_se_clk_freq_match); #define GENI_SE_DMA_EOT_EN BIT(1) #define GENI_SE_DMA_AHB_ERR_EN BIT(2) #define GENI_SE_DMA_EOT_BUF BIT(0) + +/** + * geni_se_tx_init_dma() - Initiate TX DMA transfer on the serial engine + * @se: Pointer to the concerned serial engine. + * @iova: Mapped DMA address. + * @len: Length of the TX buffer. + * + * This function is used to initiate DMA TX transfer. + */ +void geni_se_tx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len) +{ + u32 val; + + val = GENI_SE_DMA_DONE_EN; + val |= GENI_SE_DMA_EOT_EN; + val |= GENI_SE_DMA_AHB_ERR_EN; + writel_relaxed(val, se->base + SE_DMA_TX_IRQ_EN_SET); + 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(len, se->base + SE_DMA_TX_LEN); +} +EXPORT_SYMBOL(geni_se_tx_init_dma); + /** * geni_se_tx_dma_prep() - Prepare the serial engine for TX DMA transfer * @se: Pointer to the concerned serial engine. @@ -697,7 +701,6 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len, dma_addr_t *iova) { struct geni_wrapper *wrapper = se->wrapper; - u32 val; if (!wrapper) return -EINVAL; @@ -706,17 +709,34 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len, if (dma_mapping_error(wrapper->dev, *iova)) return -EIO; + geni_se_tx_init_dma(se, *iova, len); + return 0; +} +EXPORT_SYMBOL(geni_se_tx_dma_prep); + +/** + * geni_se_rx_init_dma() - Initiate RX DMA transfer on the serial engine + * @se: Pointer to the concerned serial engine. + * @iova: Mapped DMA address. + * @len: Length of the RX buffer. + * + * This function is used to initiate DMA RX transfer. + */ +void geni_se_rx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len) +{ + u32 val; + val = GENI_SE_DMA_DONE_EN; val |= GENI_SE_DMA_EOT_EN; val |= GENI_SE_DMA_AHB_ERR_EN; - writel_relaxed(val, se->base + SE_DMA_TX_IRQ_EN_SET); - 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(len, se->base + SE_DMA_TX_LEN); - return 0; + writel_relaxed(val, se->base + SE_DMA_RX_IRQ_EN_SET); + writel_relaxed(lower_32_bits(iova), se->base + SE_DMA_RX_PTR_L); + 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(len, se->base + SE_DMA_RX_LEN); } -EXPORT_SYMBOL(geni_se_tx_dma_prep); +EXPORT_SYMBOL(geni_se_rx_init_dma); /** * geni_se_rx_dma_prep() - Prepare the serial engine for RX DMA transfer @@ -733,7 +753,6 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len, dma_addr_t *iova) { struct geni_wrapper *wrapper = se->wrapper; - u32 val; if (!wrapper) return -EINVAL; @@ -742,15 +761,7 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len, if (dma_mapping_error(wrapper->dev, *iova)) return -EIO; - val = GENI_SE_DMA_DONE_EN; - val |= GENI_SE_DMA_EOT_EN; - val |= GENI_SE_DMA_AHB_ERR_EN; - writel_relaxed(val, se->base + SE_DMA_RX_IRQ_EN_SET); - writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_RX_PTR_L); - 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(len, se->base + SE_DMA_RX_LEN); + geni_se_rx_init_dma(se, *iova, len); return 0; } EXPORT_SYMBOL(geni_se_rx_dma_prep); |