Hi Oleksij, On 08/10/2017 09:09 AM, Oleksij Rempel wrote: > Hi Greg, > > On 09.08.2017 15:00, Greg Ungerer wrote: >> Hi Qleksij, >> >> On 24/07/17 16:21, Oleksij Rempel wrote: >>> On Thu, Jul 20, 2017 at 11:00:49PM +1000, Greg Ungerer wrote: >>>> Hi Oleksij, >>>> >>>> On 20/07/17 16:34, Oleksij Rempel wrote: >>>>> Hi Greg, >>>>> >>>>> On Tue, Jul 18, 2017 at 09:53:58PM -0300, Fabio Estevam wrote: >>>>>> Adding Pengutronix folks on Cc. >>>>>> >>>>>> On Tue, Jul 11, 2017 at 1:22 AM, Greg Ungerer <gerg@xxxxxxxxxxxxxx> >>>>>> wrote: >>>>>>> The commonly used mechanism of specifying the hardware or native >>>>>>> chip-select on an SPI device in devicetree (that is "cs-gpios = <0>") >>>>>>> does not result in the native chip-select being configured for use. >>>>>>> So external SPI devices that require use of the native chip-select >>>>>>> will not work. >>>>>>> >>>>>>> You can successfully specify native chip-selects if using a platform >>>>>>> setup by specifying the cs-gpio as negative offset by 32. And that >>>>>>> works correctly. You cannot use the same method in devicetree. >>>>>>> >>>>>>> The logic in the spi-imx.c driver during probe uses core spi function >>>>>>> of_spi_register_master() in spi.c to parse the "cs-gpios" >>>>>>> devicetree tag. >>>>>>> For valid GPIO values that will be recorded for use, all other >>>>>>> entries in >>>>>>> the cs_gpios list will be set to -ENOENT. So entries like "<0>" >>>>>>> will be >>>>>>> set to -ENOENT in the cs_gpios list. >>>>>>> >>>>>>> When the SPI device registers are setup the code will use the GPIO >>>>>>> listed in the cs_gpios list for the desired chip-select. If the >>>>>>> cs_gpio >>>>>>> is less then 0 then it is intended to be for a native chip-select, >>>>>>> and >>>>>>> its cs_gpio value is added to 32 to get the chipselect number to use. >>>>>>> Problem is that with devicetree this can only ever be -ENOENT (which >>>>>>> is -2), and that alone results in an invalid chip-select number. >>>>>>> But also >>>>>>> doesn't allow selection of the native chip-select at all. >>>>>>> >>>>>>> To fix, if the cs_gpio specified for this spi device is not a >>>>>>> valid GPIO then use the "chip_select" (that is the native chip-select >>>>>>> number) for hardware setup. >>>>>>> >>>>>>> Signed-off-by: Greg Ungerer <gerg@xxxxxxxxxxxxxx> >>>>>>> --- >>>>>>> drivers/spi/spi-imx.c | 8 ++++---- >>>>>>> 1 file changed, 4 insertions(+), 4 deletions(-) >>>>>>> >>>>>>> diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c >>>>>>> index b402530..f4fe66c 100644 >>>>>>> --- a/drivers/spi/spi-imx.c >>>>>>> +++ b/drivers/spi/spi-imx.c >>>>>>> @@ -524,8 +524,8 @@ static int mx31_config(struct spi_device *spi, >>>>>>> struct spi_imx_config *config) >>>>>>> reg |= MX31_CSPICTRL_POL; >>>>>>> if (spi->mode & SPI_CS_HIGH) >>>>>>> reg |= MX31_CSPICTRL_SSPOL; >>>>>>> - if (spi->cs_gpio < 0) >>>>>>> - reg |= (spi->cs_gpio + 32) << >>>>>>> + if (!gpio_is_valid(spi->cs_gpio)) >>>>>>> + reg |= (spi->chip_select) << >>>>>>> (is_imx35_cspi(spi_imx) ? >>>>>>> MX35_CSPICTRL_CS_SHIFT : >>>>>>> >>>>>>> MX31_CSPICTRL_CS_SHIFT); >>>>>>> >>>>>>> @@ -616,8 +616,8 @@ static int mx21_config(struct spi_device *spi, >>>>>>> struct spi_imx_config *config) >>>>>>> reg |= MX21_CSPICTRL_POL; >>>>>>> if (spi->mode & SPI_CS_HIGH) >>>>>>> reg |= MX21_CSPICTRL_SSPOL; >>>>>>> - if (spi->cs_gpio < 0) >>>>>>> - reg |= (spi->cs_gpio + 32) << MX21_CSPICTRL_CS_SHIFT; >>>>>>> + if (!gpio_is_valid(spi->cs_gpio)) >>>>>>> + reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT; >>>>>>> >>>>>>> writel(reg, spi_imx->base + MXC_CSPICTRL); >>>>>>> >>>>> >>>>> hm... do I see this correctly, all native chip_selects should >>>>> be registered before gpio based CS? >>>> >>>> I don't follow. The "<0>" must be in the position in the list where >>>> you want to use the native chip select. You can't arbitrarily change >>>> the order. >>>> >>>> >>>>> For example like this? >>>>> cs-gpios = <0>, <&gpio1 1 0>, <&gpio1 2 0>; >>>>> >>>>> Looks like we don't have any sanity checks for this kind of >>>>> configuration: >>>>> cs-gpios = <&gpio1 1 0>, <&gpio1 2 0>, <0>; >>>> >>>> The chip_select is sanity checked in spi_add_device(). >>>> >>>> >>>>> We may shift some wired numbers here: >>>>> reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT; >>>> >>>> I am not sure I see how that can be the case? >>> >>> old and new version of iMX have different amount of native CS. >>> I can't find the code which is actually checking if we use right native >>> CS-index. >>> May be i'm blind :) >> >> I don't think I entirely understand what you are saying. The code at the >> top of spi_add_device() [drivers/spi/spi.c] looks like this: >> >> /* Chipselects are numbered 0..max; validate. */ >> if (spi->chip_select >= ctlr->num_chipselect) { >> dev_err(dev, "cs%d >= max %d\n", spi->chip_select, >> ctlr->num_chipselect); >> return -EINVAL; >> } >> >> So it will range check the spi device (spi->chip_select) to be within >> the range valid for this SPI controller. That is the very same >> spi->chip_select that is used in spi-imx.c to set the register bits >> when using a native chip select. > > Correct. This is how ctlr->num_chipselect initialized: > > nb = of_gpio_named_count(np, "cs-gpios"); > ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect); > > it will take the count of cs-gpios. > > The i.MX233 has 3 native CSs (SSn) and i.MX6D/Q has 4 CSs - controlled > by 2 bits. Lets assume in both cases we wish to use 5CSs, some of them > are GPIOs. > > We will use same line for devicetree on i.MX233 and i.MX6D/Q: > cs-gpios = <&gpio1 0 0>, <&gpio1 1 0>, <&gpio1 2 0>, <0>, <&gpio1 4 0>; > > If i see it correctly, spi.c and imx-spi.c will just take it. But in > case of i.MX6 it should work and on i.MX233 it should silently fail. Errors in DTB (or platform data) may confuse a driver and lead to runtime misbehaviour. You describe an error in a board DTB, which is definitely better to handle in the SPI driver, but I don't think it is strictly mandatory to do it, because DTB errors are supposed to be fixed in DTB. May be one day a formal check of DTBs against Documentation/devicetree descriptions will be added and such DTB errors could be captured on DTB compilation stage. > And in this case: > cs-gpios = <&gpio1 0 0>, <&gpio1 1 0>, <&gpio1 2 0>, <&gpio1 3 0>, <0>; > > we should produce a 3 bit value b100 which will be shifted left and > "or"-ed with other ctrl bits. Same is here. -- With best wishes, Vladimir -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html