diff mbox series

[2/4] spi: intel: Implement adjust_op_size()

Message ID 20221025064623.22808-3-mika.westerberg@linux.intel.com (mailing list archive)
State Accepted
Commit 8a9a784fb337cfd07f305faf5358335d4c12a788
Headers show
Series spi: intel: Add support for SFDP opcode | expand

Commit Message

Mika Westerberg Oct. 25, 2022, 6:46 a.m. UTC
This allows us to get rid of the checks in the intel_spi_[sh]w_cycle()
and makes it possible for the SPI-NOR core to split the transaction into
smaller chunks as needed.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/spi/spi-intel.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

Comments

Dhruva Gole Oct. 28, 2022, 6:12 a.m. UTC | #1
Hi Mika,

On 10/25/2022 12:16 PM, Mika Westerberg wrote:
> This allows us to get rid of the checks in the intel_spi_[sh]w_cycle()
> and makes it possible for the SPI-NOR core to split the transaction into
> smaller chunks as needed.

If I understand correctly, the controller ops are called from spi-mem.c, 
and

spi_mem_adjust_op does exist and on it's own does "split a data transfer
  operation into multiple ones"

So is this really something that you require the controller to do and

can we not rely on spi-mem.c to do it's thing instead?

I would like to point you to another controller spi-cadence-quadspi.c

that also doesn't have it's own adjust_op_size but I haven't seen any 
issues as such

inspite. This is because everything first goes through spi-mem.c then 
onto the controllers drivers.

This atleast is my understanding, please correct me if I am mistaken.

>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>   drivers/spi/spi-intel.c | 14 +++++++-------
>   1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c
> index b3685460d848..13a3a61239d2 100644
> --- a/drivers/spi/spi-intel.c
> +++ b/drivers/spi/spi-intel.c
> @@ -363,10 +363,6 @@ static int intel_spi_hw_cycle(struct intel_spi *ispi,
>   
>   	val = readl(ispi->base + HSFSTS_CTL);
>   	val &= ~(HSFSTS_CTL_FCYCLE_MASK | HSFSTS_CTL_FDBC_MASK);
> -
> -	if (len > INTEL_SPI_FIFO_SZ)
> -		return -EINVAL;
> -
>   	val |= (len - 1) << HSFSTS_CTL_FDBC_SHIFT;
>   	val |= HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE;
>   	val |= HSFSTS_CTL_FGO;
> @@ -397,9 +393,6 @@ static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len,
>   	if (ret < 0)
>   		return ret;
>   
> -	if (len > INTEL_SPI_FIFO_SZ)
> -		return -EINVAL;
> -
>   	/*
>   	 * Always clear it after each SW sequencer operation regardless
>   	 * of whether it is successful or not.
> @@ -704,6 +697,12 @@ static int intel_spi_erase(struct intel_spi *ispi, const struct spi_mem *mem,
>   	return 0;
>   }
>   
> +static int intel_spi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
> +{
> +	op->data.nbytes = clamp_val(op->data.nbytes, 0, INTEL_SPI_FIFO_SZ);
> +	return 0;
> +}
> +
>   static bool intel_spi_cmp_mem_op(const struct intel_spi_mem_op *iop,
>   				 const struct spi_mem_op *op)
>   {
> @@ -844,6 +843,7 @@ static ssize_t intel_spi_dirmap_write(struct spi_mem_dirmap_desc *desc, u64 offs
>   }
>   
>   static const struct spi_controller_mem_ops intel_spi_mem_ops = {
> +	.adjust_op_size = intel_spi_adjust_op_size,
>   	.supports_op = intel_spi_supports_mem_op,
>   	.exec_op = intel_spi_exec_mem_op,
>   	.get_name = intel_spi_get_name,
Mika Westerberg Oct. 28, 2022, 6:25 a.m. UTC | #2
Hi,

On Fri, Oct 28, 2022 at 11:42:09AM +0530, Gole, Dhruva wrote:
> Hi Mika,
> 
> On 10/25/2022 12:16 PM, Mika Westerberg wrote:
> > This allows us to get rid of the checks in the intel_spi_[sh]w_cycle()
> > and makes it possible for the SPI-NOR core to split the transaction into
> > smaller chunks as needed.
> 
> If I understand correctly, the controller ops are called from spi-mem.c, and
> 
> spi_mem_adjust_op does exist and on it's own does "split a data transfer
>  operation into multiple ones"
> 
> So is this really something that you require the controller to do and
> 
> can we not rely on spi-mem.c to do it's thing instead?

How does it know the size supported by the hardware? I think this is the
reason spi_mem_adjust_op was introduced but I may be mistaken.

> I would like to point you to another controller spi-cadence-quadspi.c
> 
> that also doesn't have it's own adjust_op_size but I haven't seen any issues
> as such
> 
> inspite. This is because everything first goes through spi-mem.c then onto
> the controllers drivers.

Well Intel SPI driver did not not have any issues previously either
because it handled the read/write split internally but SFDP read is done
through "register read side" which only supported max 64-byte read until
now :-)
Dhruva Gole Oct. 28, 2022, 6:46 a.m. UTC | #3
On 10/28/2022 11:55 AM, Mika Westerberg wrote:
> Hi,
>
> On Fri, Oct 28, 2022 at 11:42:09AM +0530, Gole, Dhruva wrote:
>> Hi Mika,
>>
>> On 10/25/2022 12:16 PM, Mika Westerberg wrote:
>>> This allows us to get rid of the checks in the intel_spi_[sh]w_cycle()
>>> and makes it possible for the SPI-NOR core to split the transaction into
>>> smaller chunks as needed.
>> If I understand correctly, the controller ops are called from spi-mem.c, and
>>
>> spi_mem_adjust_op does exist and on it's own does "split a data transfer
>>   operation into multiple ones"
>>
>> So is this really something that you require the controller to do and
>>
>> can we not rely on spi-mem.c to do it's thing instead?
> How does it know the size supported by the hardware? I think this is the
> reason spi_mem_adjust_op was introduced but I may be mistaken.'

The following piece of code might help:

         op->data.nbytes = min3((size_t)op->data.nbytes,
                        spi_max_transfer_size(mem->spi),
                        spi_max_message_size(mem->spi)

I believe this will help it know the size supported by the hardware.

and on the controller side:

in case of cadence I have seen it pickup the fifo depth from DTSI, for eg.

arch/arm64/boot/dts/ti/k3-am62-main.dtsi: cdns,fifo-depth = <256>;

>
>> I would like to point you to another controller spi-cadence-quadspi.c
>>
>> that also doesn't have it's own adjust_op_size but I haven't seen any issues
>> as such
>>
>> inspite. This is because everything first goes through spi-mem.c then onto
>> the controllers drivers.
> Well Intel SPI driver did not not have any issues previously either
> because it handled the read/write split internally but SFDP read is done
> through "register read side" which only supported max 64-byte read until
> now :-)
Mika Westerberg Oct. 28, 2022, 7:05 a.m. UTC | #4
Hi,

On Fri, Oct 28, 2022 at 12:16:43PM +0530, Gole, Dhruva wrote:
> 
> On 10/28/2022 11:55 AM, Mika Westerberg wrote:
> > Hi,
> > 
> > On Fri, Oct 28, 2022 at 11:42:09AM +0530, Gole, Dhruva wrote:
> > > Hi Mika,
> > > 
> > > On 10/25/2022 12:16 PM, Mika Westerberg wrote:
> > > > This allows us to get rid of the checks in the intel_spi_[sh]w_cycle()
> > > > and makes it possible for the SPI-NOR core to split the transaction into
> > > > smaller chunks as needed.
> > > If I understand correctly, the controller ops are called from spi-mem.c, and
> > > 
> > > spi_mem_adjust_op does exist and on it's own does "split a data transfer
> > >   operation into multiple ones"
> > > 
> > > So is this really something that you require the controller to do and
> > > 
> > > can we not rely on spi-mem.c to do it's thing instead?
> > How does it know the size supported by the hardware? I think this is the
> > reason spi_mem_adjust_op was introduced but I may be mistaken.'
> 
> The following piece of code might help:
> 
>         op->data.nbytes = min3((size_t)op->data.nbytes,
>                        spi_max_transfer_size(mem->spi),
>                        spi_max_message_size(mem->spi)
> 
> I believe this will help it know the size supported by the hardware.
> 
> and on the controller side:
> 
> in case of cadence I have seen it pickup the fifo depth from DTSI, for eg.
> 
> arch/arm64/boot/dts/ti/k3-am62-main.dtsi: cdns,fifo-depth = <256>;

I'm not entirely sure I understand what you are suggesting to be honest? ;-)

For example the Intel SPI controller does not have any sort of device
tree description, it does not really understand anything about SPI
either (internally yes but the operations it exposes to software are
higher level), and it has fixed 64 byte FIFO.

Can I get the SFDP opcode supported with that without implementing
custom spi_mem_adjust_op() and if yes, how? Thanks!
diff mbox series

Patch

diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c
index b3685460d848..13a3a61239d2 100644
--- a/drivers/spi/spi-intel.c
+++ b/drivers/spi/spi-intel.c
@@ -363,10 +363,6 @@  static int intel_spi_hw_cycle(struct intel_spi *ispi,
 
 	val = readl(ispi->base + HSFSTS_CTL);
 	val &= ~(HSFSTS_CTL_FCYCLE_MASK | HSFSTS_CTL_FDBC_MASK);
-
-	if (len > INTEL_SPI_FIFO_SZ)
-		return -EINVAL;
-
 	val |= (len - 1) << HSFSTS_CTL_FDBC_SHIFT;
 	val |= HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE;
 	val |= HSFSTS_CTL_FGO;
@@ -397,9 +393,6 @@  static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len,
 	if (ret < 0)
 		return ret;
 
-	if (len > INTEL_SPI_FIFO_SZ)
-		return -EINVAL;
-
 	/*
 	 * Always clear it after each SW sequencer operation regardless
 	 * of whether it is successful or not.
@@ -704,6 +697,12 @@  static int intel_spi_erase(struct intel_spi *ispi, const struct spi_mem *mem,
 	return 0;
 }
 
+static int intel_spi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+{
+	op->data.nbytes = clamp_val(op->data.nbytes, 0, INTEL_SPI_FIFO_SZ);
+	return 0;
+}
+
 static bool intel_spi_cmp_mem_op(const struct intel_spi_mem_op *iop,
 				 const struct spi_mem_op *op)
 {
@@ -844,6 +843,7 @@  static ssize_t intel_spi_dirmap_write(struct spi_mem_dirmap_desc *desc, u64 offs
 }
 
 static const struct spi_controller_mem_ops intel_spi_mem_ops = {
+	.adjust_op_size = intel_spi_adjust_op_size,
 	.supports_op = intel_spi_supports_mem_op,
 	.exec_op = intel_spi_exec_mem_op,
 	.get_name = intel_spi_get_name,