Is it possible to Configure BLSP as SPI on DragonBoard820c?

Hi. I would like to configure a BLSP as SPI on the Dragonboard820c. Is this possible? What steps do I need to do?

Which one ?

BLSPs are configured in the device-tree (arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi), you can see that blsp1/spi0 and blsp2/spi5 are enabled. Note that each APQ8096 BLSP as zero or more QUP core (SPI/I2C block) which can be configured either as SPI or I2C.

Hi Loic,
I would like to configure either BLSP 10 or BLSP 11 as SPI. Which address do I use for either of these BLSPs?

BLSP10 is linked to GPIO 8,9,10,11, BLSP11 to GPIO 58,59,60,61, make sure these pins are not used/routed by any other subsystem before.

I don’t have the datasheet of the mapped register, so I don’t know their address, maybe you can deduct them from the ones described in the existing device tree (blsp1, blsp2).

Hi Loic,
Neither of the already configured BLSPs shows a /dev/spidevX device. I got /dev/spidev0.0 to show up for BLSP 10 with this:
blsp2_spi3: spi@075b8000{
compatible = “qcom,spi-qup-v2.2.1”;

device@0 {
compatible = “spidev”;
#address-cells = <1>;
#size-cells = <1>;
reg = <0>; /* Chip select 0 */
spi-max-frequency = <19200000>;
Do you know what the reg <0> Chip select comment means? I just found this in an example, but no explanation.

By default spi bus is not available to userspace. It is possible to expose them by creating a special ‘spidev’ device slave node. You can add spidev inside the spi you want to expose.

This is the chip select address/idx of device. Usually 0. CS pin is enabled when master sends data to the slave(s).

You can also follow the following guide to enable spidev at runtime on LS connector: Enabling SPI on Dragonboard 410c with SPIDEV - 96Boards

On DB820C:

git clone
cd dt-update
sudo scripts/db820c/
1 Like

Hi Loic,
Thank you for the information! Once I see the /dev/spidevX device I can open/read/write to the device, similar to the example program?

yes, you can use spidev uapi.

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>;
And in spidev test application:
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):

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): msm8996-pins.dtsi « qcom « dts « boot « arm64 « arch - working/qualcomm/kernel.git - Qualcomm Landing Team kernel

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.


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 ?


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 :