| From 9ec691f48b5ef741a48af8932ccaec859c67e8f1 Mon Sep 17 00:00:00 2001 |
| From: Sameer Pujar <spujar@nvidia.com> |
| Date: Mon, 16 Sep 2019 15:05:13 +0530 |
| Subject: dmaengine: tegra210-adma: fix transfer failure |
| |
| From: Sameer Pujar <spujar@nvidia.com> |
| |
| commit 9ec691f48b5ef741a48af8932ccaec859c67e8f1 upstream. |
| |
| >From Tegra186 onwards OUTSTANDING_REQUESTS field is added in channel |
| configuration register(bits 7:4) which defines the maximum number of reads |
| from the source and writes to the destination that may be outstanding at |
| any given point of time. This field must be programmed with a value |
| between 1 and 8. A value of 0 will prevent any transfers from happening. |
| |
| Thus added 'has_outstanding_reqs' bool member in chip data structure and is |
| set to false for Tegra210, since the field is not applicable. For Tegra186 |
| it is set to true and channel configuration is updated with maximum |
| outstanding requests. |
| |
| Fixes: 433de642a76c ("dmaengine: tegra210-adma: add support for Tegra186/Tegra194") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Sameer Pujar <spujar@nvidia.com> |
| Acked-by: Jon Hunter <jonathanh@nvidia.com> |
| Link: https://lore.kernel.org/r/1568626513-16541-1-git-send-email-spujar@nvidia.com |
| Signed-off-by: Vinod Koul <vkoul@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/dma/tegra210-adma.c | 7 +++++++ |
| 1 file changed, 7 insertions(+) |
| |
| --- a/drivers/dma/tegra210-adma.c |
| +++ b/drivers/dma/tegra210-adma.c |
| @@ -40,6 +40,7 @@ |
| #define ADMA_CH_CONFIG_MAX_BURST_SIZE 16 |
| #define ADMA_CH_CONFIG_WEIGHT_FOR_WRR(val) ((val) & 0xf) |
| #define ADMA_CH_CONFIG_MAX_BUFS 8 |
| +#define TEGRA186_ADMA_CH_CONFIG_OUTSTANDING_REQS(reqs) (reqs << 4) |
| |
| #define ADMA_CH_FIFO_CTRL 0x2c |
| #define TEGRA210_ADMA_CH_FIFO_CTRL_OFLWTHRES(val) (((val) & 0xf) << 24) |
| @@ -85,6 +86,7 @@ struct tegra_adma; |
| * @ch_req_tx_shift: Register offset for AHUB transmit channel select. |
| * @ch_req_rx_shift: Register offset for AHUB receive channel select. |
| * @ch_base_offset: Register offset of DMA channel registers. |
| + * @has_outstanding_reqs: If DMA channel can have outstanding requests. |
| * @ch_fifo_ctrl: Default value for channel FIFO CTRL register. |
| * @ch_req_mask: Mask for Tx or Rx channel select. |
| * @ch_req_max: Maximum number of Tx or Rx channels available. |
| @@ -103,6 +105,7 @@ struct tegra_adma_chip_data { |
| unsigned int ch_req_max; |
| unsigned int ch_reg_size; |
| unsigned int nr_channels; |
| + bool has_outstanding_reqs; |
| }; |
| |
| /* |
| @@ -602,6 +605,8 @@ static int tegra_adma_set_xfer_params(st |
| ADMA_CH_CTRL_FLOWCTRL_EN; |
| ch_regs->config |= cdata->adma_get_burst_config(burst_size); |
| ch_regs->config |= ADMA_CH_CONFIG_WEIGHT_FOR_WRR(1); |
| + if (cdata->has_outstanding_reqs) |
| + ch_regs->config |= TEGRA186_ADMA_CH_CONFIG_OUTSTANDING_REQS(8); |
| ch_regs->fifo_ctrl = cdata->ch_fifo_ctrl; |
| ch_regs->tc = desc->period_len & ADMA_CH_TC_COUNT_MASK; |
| |
| @@ -786,6 +791,7 @@ static const struct tegra_adma_chip_data |
| .ch_req_tx_shift = 28, |
| .ch_req_rx_shift = 24, |
| .ch_base_offset = 0, |
| + .has_outstanding_reqs = false, |
| .ch_fifo_ctrl = TEGRA210_FIFO_CTRL_DEFAULT, |
| .ch_req_mask = 0xf, |
| .ch_req_max = 10, |
| @@ -800,6 +806,7 @@ static const struct tegra_adma_chip_data |
| .ch_req_tx_shift = 27, |
| .ch_req_rx_shift = 22, |
| .ch_base_offset = 0x10000, |
| + .has_outstanding_reqs = true, |
| .ch_fifo_ctrl = TEGRA186_FIFO_CTRL_DEFAULT, |
| .ch_req_mask = 0x1f, |
| .ch_req_max = 20, |