Is it possible to Configure BLSP as SPI on DragonBoard820c?

yes, you can use spidev uapi.
https://www.kernel.org/doc/Documentation/spi/spidev

I have enabled spi device using blsp5_spi0: spi@07579000;
When I set max frequency as 50Mhz as:
spidev@0x00 {
compatible = “spidev”;
spi-max-frequency = <50000000>;
reg = <0>;
spi-cpol;
spi-cpha;
};
And in spidev test application: https://github.com/KnCMiner/spi-test/blob/master/spi-test.c
on giving speed_hz = 28000000; (28Mhz)
I found output as 50Mhz, any value above 25Mhz was giving o/p 50Mhz;

Any delay being added ?? Any suggestions are welcome…

Which board/kernel is it?

The clock feeding SPI has a limited set of operating frequencies, e.g (blsp1):
https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/tree/drivers/clk/qcom/gcc-msm8996.c?h=release/qcomlt-4.14#n584

That why you see a jump from 25MHz to 50MHz, this is not a hertz-grained configuration. You can, however, add a new line to the frequency table with your custom clock divider/multiplier config to target another frequency.

Firstly, thanks for pointing to right file : gcc-msm8996.c
I am using custom board designed from DB820c
Kernel version being operated is : 4.14.0-qcomlt-arm64

Is there a provision of handling ChipSelect transitions from devicetree ?? Since in my case for 10microsec data transfer I got 400microsec CS high to low transition :thinking:

Do you have a logic analyzer capture of the behavior? CS is managed in hardware on 820c (contrary to 410c), so not sure If we can improve that.

I hav uploaded probed results for 15Mhz & 25 Mhz.
yellow = CS
blue = clk
magenta = data

I observed that clock pulses at higher frequencies(40Mhz or so) are not square waves any more. Any suggestions on improving the drive strength and sinusoidal kind of behaviour in clock pulses?? @Loic

Thanks in advance…

I can not really comment since I don’t see the full CS cycle in your capture.

You can configure drive strength in the device tree (drive-strength property): https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/tree/arch/arm64/boot/dts/qcom/msm8996-pins.dtsi?h=release/qcomlt-4.14#n62

AFAIK, maximum is <16> . Also it could be due extra capacitance on the clock pin, e.g. is the wire too long?

CSissue CStransitissue

Note: 1st pic is just the enlarged version of 2nd.

This was my observation when data (in yellow) vs CS (in blue) was probed.
The data passed was hex values 0x01 to 0x0E, output was as expected:
01 02 03 04 05 06
07 08 09 0A 0B 0C
0D 0E

But CS is low for 100microsec for data transfer of 5microsec…

I tried 16mA but now the data recieved is FF (hex value) always, I feel 16mA has let the BLSP MISO & MOSI pin go bad(still debugging what went wrong).

Thanks in advance…

This looks like what I saw on the 410c. How is your CS pin defined in the device tree? There are 3 ways to drive CS 1) user land SW toggling the GPIO, 2) device driver toggling the GPIO, and 3) HW toggling the GPIO. From the scope pictures it looks like you are in state 2). Change to state 3) and the CS will be 1 clock before and after data.

Take a look at this thread, I think that it should apply to the 820c since the BLSP didn’t get many changes between 410c and 820c.

-Lawrence-

I tried that driver change @
index 974a8ce…2969d59 100644
— a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -754,6 +754,7 @@
config |= SPI_IO_C_MX_CS_MODE;
writel_relaxed(control, controller->base + SPI_IO_CONTROL);

@@ -1113,7 +1114,7 @@
– writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
++ writel_relaxed(SPI_IO_C_NO_TRI_STATE|SPI_IO_C_MX_CS_MODE, base + SPI_IO_CONTROL);

Also in msm8996-pins.dtsi:
pinmux_cs {
function = “blsp_spi5”;
pins = “gpio83”;
};

It didn’t change the CS pulse in any ways… @ljking
Any help in understanding how to use Hardware CS ?? Thanks in advance

Any ideas to solve this issue (CS being in low state for longer duration) ?
I’m finding same behaviour with both SW & HW means of driving Chip Select.
Also why does the Chip Select shift low for one clock before & after the Data transfer ?

Thanks,
Yash

Change looks good.

What about the clock? is the clock only active during data activity or as long CS is asserted?

For debugging purpose, can you print values written to QUP_MX_INPUT_CNT and QUP_MX_OUTPUT_CNT in spi_qup_io_config function.

Yes, the clock is in exact sync with the SPI data transfers.

And the values are same as defined in spi-qup.c :
QUP_MX_INPUT_CNT = 0x0200
QUP_MX_OUTPUT_CNT = 0x0100

Thanks,
Yash

QUP_MX_INPUT_CNT and OUTPUT are registers, 0x0200 and 0x0100 are their addresses not their values. They contain the number of word to read and write, and according to apq8016 technical manual (which has similar spi controller), the chip select is supposed to be asserted for a period derived from these values. So it would worth to write the values according to the expected word counts.

Also I notice that DMA mode is not enabled on MSM8996 (no dma channel associated), which can also be the cause of this limitation (FIFO mode is used).

Sorry, I meant the same :
512 words to read & 256 words to write

I also tried with : QUP_MX_OUTPUT_CNT = 0x0010
to write 16 words of 8 bits, the results observed were at 1Mhz:

As frequency of operation increases the performance is much degraded.

Any further insights on how to add support for this ??

Thanks in advance…

I don’t really know what happens, maybe it’s just a limitation of what can be achieved in FIFO mode, which is anyway used for small transfers. So it would require deeper investigation. One last thing to try would be maybe to replace any usleep_range() with udelay() in the driver in order to prevent context switching for SPI QUP state change.

Sure @Loic, will try to debug and update if any.

Hi @ljking

Is there any reason why CS is driven low one clock before & after ?

Thanks ,
Yash

Hi @ymj

Like almost any other interface, the chip select must be active before the data starts to arrive. If the chip select was to go active slightly after the data (say by 1ns), then the device receiving the information would have no idea that the information is intended for that device. if the chip select was to go active at exactly the same time as the data, then the receiving device might still miss it, due to delays in the wiring or in the transmitting and receiving circuitry.

In order to ensure that the receiving device knows that information is intended for that device the chip select must go active well in advance of the data. In this case (and with every SPI chip I have ever used) “well in advance” is one clock time.

Same problem at the end of the data, if the chip select goes inactive too soon the receiving device might miss the data.

Here is a fragment from a typical SPI device datasheet.

As you can see the chip select must go active tcssc = 100nS before the the clock. The clock period tsclk is 250ns, this means that the chip select must go active about 1/2 clock time before the data, and every controller rounds this up to a full clock cycle. Same thing with tsccs at the end of the cycle.

Without the one clock before and after the data the SPI bus wouldn’t work.

@ljking thanks for the detailing on how to stop data loss.

Can you suggest ways to check if H/W CS is enabled and how it runs in accordance with CLK:

If it looks like this https://discuss-96boards-org.s3.amazonaws.com/original/1X/e07d0b61c5d53d27bda0746c9166db341de059c1.jpg then you have HW chip select. If it looks like your scope trace above you have user SW or driver SW chip select.