Re: [PATCH] spi: set right CS polarity depend on gpiolib

From: 乱石
Date: Fri May 07 2021 - 21:01:53 EST


Hi,
在 2021/5/7 23:30, Mark Brown 写道:
On Fri, May 07, 2021 at 10:51:17PM +0800, Liguang Zhang wrote:
After a kernel upgrade from 4.19 to 5.10, we found that tpm flow control
always causes TIMEOUT which caused by wrong CS polarity setting depend
on gpiolib.
if (spi->cs_gpiod)
/* polarity handled by gpiolib */
- gpiod_set_value_cansleep(spi->cs_gpiod, activate);
+ gpiod_set_value_cansleep(spi->cs_gpiod, !enable);
Whatever is going on here it doesn't seem likely that this is a problem
in the SPI core given the widespread use of gpiod based chip selects -
can you provide more explanation of what you're seeing here, how is the
chip select configured, what is the hardware expectation and what
actually ends up happening?

The arm platform is  kunpeng-920, detail dsdt information here:

        Device (SPI0)
        {
            Name (_HID, "HISI0173")  // _HID: Hardware ID
            Name (_ADR, Zero)  // _ADR: Address
            Name (_UID, Zero)  // _UID: Unique ID
            Name (RBUF, ResourceTemplate ()
            {
                GpioIo (Exclusive, PullUp, 0x0000, 0x0000, IoRestrictionNone,
                    "\\_SB.GPO1", 0x00, ResourceConsumer, ,
                    )
                    {   // Pin list
                        0x0006
                    }
                QWordMemory (ResourceConsumer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
                    0x0000000000000000, // Granularity
                    0x00000002011A0000, // Range Minimum
                    0x00000002011AFFFF, // Range Maximum
                    0x0000000000000000, // Translation Offset
                    0x0000000000010000, // Length
                    ,, , AddressRangeMemory, TypeStatic)
                Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
                {
                    0x000001EB,
                }
            })
            Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
            {
                Return (RBUF) /* \_SB_.SPI0.RBUF */
            }

            Name (_DSD, Package (0x02)  // _DSD: Device-Specific Data
            {
                ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */,
                Package (0x03)
                {
                    Package (0x02)
                    {
                        "reg-io-width",
                        0x04
                    },

                    Package (0x02)
                    {
                        "num-cs",
                        One
                    },

                    Package (0x02)
                    {
                        "cs-gpios",
                        Package (0x04)
                        {
                            SPI0,
                            Zero,
                            Zero,
                            Zero
                        }
                    }
                }
            })
        }

        Scope (SPI0)
        {
            Device (TPM)
            {
                Name (_ADR, Zero)  // _ADR: Address
                Name (_CID, Package (0x01)  // _CID: Compatible ID
                {
                    "SMO0768"
                })
                Name (_UID, Zero)  // _UID: Unique ID
                Name (_DSD, Package (0x02)  // _DSD: Device-Specific Data
                {
                    ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */,
                    Package (0x00){}
                })
                Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                {
                    Name (RBUF, ResourceTemplate ()
                    {
                        SpiSerialBusV2 (0x0000, PolarityLow, FourWireMode, 0x08,
                            ControllerInitiated, 0x000F4240, ClockPolarityLow,
                            ClockPhaseFirst, "\\_SB.SPI0",
                            0x00, ResourceConsumer, , Exclusive,
                            )
                    })
                    Return (RBUF) /* \_SB_.SPI0.TPM_._CRS.RBUF */
                }

                Method (_STA, 0, NotSerialized)  // _STA: Status
                {
                    If ((TPEN == One))
                    {
                        Return (0x0F)
                    }
                    Else
                    {
                        Return (Zero)
                    }
                }
            }
        }
    }


The problem I meet is:

   tpm_tis_spi_init

       tpm_tis_core_init

            wait_startup     // Timeout is occured, appear every time.

If the modification below done, probe succeed.

gpiod_set_value_cansleep(spi->cs_gpiod, !enable)