mbox series

[v2,0/2] spi-geni-qcom: Add new interfaces and utilise them to do map/unmap in framework for SE DMA

Message ID 1684325894-30252-1-git-send-email-quic_vnivarth@quicinc.com
Headers show
Series spi-geni-qcom: Add new interfaces and utilise them to do map/unmap in framework for SE DMA | expand

Message

Vijaya Krishna Nivarthi May 17, 2023, 12:18 p.m. UTC
A "known issue" during implementation of SE DMA for spi geni driver was
that it does DMA map/unmap internally instead of in spi framework.
Current patches remove this hiccup and also clean up code a bit.

Testing revealed no regressions and results with 1000 iterations of
reading from EC showed no loss of performance.
Results
=======
Before - Iteration 999, min=5.10, max=5.17, avg=5.14, ints=25129
After  - Iteration 999, min=5.10, max=5.20, avg=5.15, ints=25153

Vijaya Krishna Nivarthi (2):
  soc: qcom: geni-se: Add interfaces geni_se_tx_init_dma() and
    geni_se_rx_init_dma()
  spi: spi-geni-qcom: Do not do DMA map/unmap inside driver, use
    framework instead
---
v1 -> v2:
- Modified interfaces arguments and accordingly calls to them
- Added dma_max_len to driver

 drivers/soc/qcom/qcom-geni-se.c  |  67 ++++++++++++++++++-------
 drivers/spi/spi-geni-qcom.c      | 103 +++++++++++++++++++--------------------
 include/linux/soc/qcom/geni-se.h |   4 ++
 3 files changed, 103 insertions(+), 71 deletions(-)

Comments

Mark Brown June 6, 2023, 3:53 p.m. UTC | #1
On Wed, May 17, 2023 at 07:18:17AM -0700, Doug Anderson wrote:
> On Wed, May 17, 2023 at 5:18 AM Vijaya Krishna Nivarthi

> > The geni_se_xx_dma_prep() interfaces necessarily do DMA mapping before
> > initiating DMA transfers. This is not suitable for spi where framework
> > is expected to handle map/unmap.

> Mark and Bjorn will have to coordinate how they want to land this,
> since normally patch #1 would go through the Qualcomm tree and patch
> #2 through the SPI tree. In any case:

Bjorn?
Konrad Dybcio June 6, 2023, 4:53 p.m. UTC | #2
On 17.05.2023 14:18, Vijaya Krishna Nivarthi wrote:
> The geni_se_xx_dma_prep() interfaces necessarily do DMA mapping before
> initiating DMA transfers. This is not suitable for spi where framework
> is expected to handle map/unmap.
> 
> Expose new interfaces geni_se_xx_init_dma() which do only DMA transfer.
> 
> Signed-off-by: Vijaya Krishna Nivarthi <quic_vnivarth@quicinc.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>

Konrad
> v1 -> v2:
> - interfaces to take dma address as argument instead of its pointer
> ---
>  drivers/soc/qcom/qcom-geni-se.c  | 67 +++++++++++++++++++++++++++++-----------
>  include/linux/soc/qcom/geni-se.h |  4 +++
>  2 files changed, 53 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
> index 795a2e1..dd50a25 100644
> --- a/drivers/soc/qcom/qcom-geni-se.c
> +++ b/drivers/soc/qcom/qcom-geni-se.c
> @@ -682,6 +682,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 +721,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 +729,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 +773,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 +781,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);
> diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h
> index c55a0bc..821a191 100644
> --- a/include/linux/soc/qcom/geni-se.h
> +++ b/include/linux/soc/qcom/geni-se.h
> @@ -490,9 +490,13 @@ int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq,
>  			   unsigned int *index, unsigned long *res_freq,
>  			   bool exact);
>  
> +void geni_se_tx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len);
> +
>  int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
>  			dma_addr_t *iova);
>  
> +void geni_se_rx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len);
> +
>  int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
>  			dma_addr_t *iova);
>
Mark Brown June 6, 2023, 5:49 p.m. UTC | #3
On Wed, May 17, 2023 at 05:48:12PM +0530, Vijaya Krishna Nivarthi wrote:
> A "known issue" during implementation of SE DMA for spi geni driver was
> that it does DMA map/unmap internally instead of in spi framework.
> Current patches remove this hiccup and also clean up code a bit.

Given Konrad's review I'll go ahead and apply these on a branch
(assuming my CI is happy), if there's a need to merge them into the qcom
tree I can sign a pull request (or revert the commits).  Hopefully
that's OK with everyone.
Vijaya Krishna Nivarthi June 7, 2023, 1:14 a.m. UTC | #4
On 6/6/2023 11:19 PM, Mark Brown wrote:
> On Wed, May 17, 2023 at 05:48:12PM +0530, Vijaya Krishna Nivarthi wrote:
>> A "known issue" during implementation of SE DMA for spi geni driver was
>> that it does DMA map/unmap internally instead of in spi framework.
>> Current patches remove this hiccup and also clean up code a bit.
> Given Konrad's review I'll go ahead and apply these on a branch
> (assuming my CI is happy), if there's a need to merge them into the qcom
> tree I can sign a pull request (or revert the commits).  Hopefully
> that's OK with everyone.


Sounds ok to me given Bjorn seems not available until 9th.

Thank you everyone for review and time.

-Vijay/
Mark Brown June 7, 2023, 12:28 p.m. UTC | #5
On Wed, 17 May 2023 17:48:12 +0530, Vijaya Krishna Nivarthi wrote:
> A "known issue" during implementation of SE DMA for spi geni driver was
> that it does DMA map/unmap internally instead of in spi framework.
> Current patches remove this hiccup and also clean up code a bit.
> 
> Testing revealed no regressions and results with 1000 iterations of
> reading from EC showed no loss of performance.
> Results
> =======
> Before - Iteration 999, min=5.10, max=5.17, avg=5.14, ints=25129
> After  - Iteration 999, min=5.10, max=5.20, avg=5.15, ints=25153
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[1/2] soc: qcom: geni-se: Add interfaces geni_se_tx_init_dma() and geni_se_rx_init_dma()
      commit: 6d6e57594957ee9131bc3802dfc8657ca6f78fee
[2/2] spi: spi-geni-qcom: Do not do DMA map/unmap inside driver, use framework instead
      commit: 3a76c7ca9e77269dd10cf21465a055274cfa40c6

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark