[U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip select

Karicheri, Muralidharan m-karicheri2 at ti.com
Tue Apr 1 20:40:52 CEST 2014


>-----Original Message-----
>From: u-boot-bounces at lists.denx.de [mailto:u-boot-bounces at lists.denx.de] On Behalf Of
>Karicheri, Muralidharan
>Sent: Monday, March 31, 2014 4:10 PM
>To: Jagan Teki
>Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
>Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip
>select
>
>>-----Original Message-----
>>From: Jagan Teki [mailto:jagannadh.teki at gmail.com]
>>Sent: Thursday, March 27, 2014 1:47 PM
>>To: Karicheri, Muralidharan
>>Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
>>Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for
>>multiple bus and chip select
>>
>>On Thu, Mar 27, 2014 at 1:19 AM, Karicheri, Muralidharan <m-karicheri2 at ti.com>
>wrote:
>>>>-----Original Message-----
>>>>From: Jagan Teki [mailto:jagannadh.teki at gmail.com]
>>>>Sent: Sunday, March 23, 2014 7:07 AM
>>>>To: Karicheri, Muralidharan
>>>>Cc: Rini, Tom; u-boot at lists.denx.de; Chang, Rex
>>>>Subject: Re: [U-Boot] [PATCH v3 8/9] spi: davinci: add support for
>>>>multiple bus and chip select
>>>>
>>>>Hi,
>>>>
>>>>On Sat, Mar 22, 2014 at 2:21 AM, Murali Karicheri <m-karicheri2 at ti.com> wrote:
>>>>> Currently davinci spi driver supports only bus 0 cs 0.
>>>>> This patch allows driver to support bus 1 and bus 2 with
>>>>> configurable number of chip selects. Also defaults are selected in
>>>>> a way to avoid regression on other platforms that uses davinci spi
>>>>> driver and has only one spi bus.
>>>>>
>>>>> Signed-off-by: Rex Chang <rchang at ti.com>
>>>>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>>>>> Acked-by: Tom Rini <trini at ti.com>
>>>>> ---
>>>>>  drivers/spi/davinci_spi.c |   60
>>>>++++++++++++++++++++++++++++++++++++++++++---
>>>>>  drivers/spi/davinci_spi.h |   33 +++++++++++++++++++++++++
>>>>>  2 files changed, 90 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
>>>>> index e3fb321..b682bc4 100644
>>>>> --- a/drivers/spi/davinci_spi.c
>>>>> +++ b/drivers/spi/davinci_spi.c
>>>>> @@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int
>>>>> bus, unsigned int
>>>>cs,
>>>>>         if (!ds)
>>>>>                 return NULL;
>>>>>
>>>>> -       ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
>>>>> +       ds->slave.bus = bus;
>>>>> +       ds->slave.cs = cs;
>>>>> +
>>>>> +       switch (bus) {
>>>>> +       case SPI0_BUS:
>>>>> +               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
>>>>> +               break;
>>>>> +#ifdef CONFIG_SYS_SPI1
>>>>> +       case SPI1_BUS:
>>>>> +               ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
>>>>> +               break;
>>>>> +#endif
>>>>> +#ifdef CONFIG_SYS_SPI2
>>>>> +       case SPI2_BUS:
>>>>> +               ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
>>>>> +               break;
>>>>> +#endif
>>>>> +       default: /* Invalid bus number */
>>>>> +               return NULL;
>>>>> +       }
>>>>> +
>>>>>         ds->freq = max_hz;
>>>>>
>>>>>         return &ds->slave;
>>>>> @@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
>>>>>         writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK,
>>>>> &ds->regs->gcr1);
>>>>>
>>>>>         /* CS, CLK, SIMO and SOMI are functional pins */
>>>>> -       writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
>>>>> +       writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
>>>>>                 SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK),
>>>>> &ds->regs->pc0);
>>>>>
>>>>>         /* setup format */
>>>>> @@ -262,9 +282,43 @@ out:
>>>>>         return 0;
>>>>>  }
>>>>>
>>>>> +#ifdef CONFIG_SYS_SPI1
>>>>> +static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
>>>>> +       if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
>>>>> +               return 1;
>>>>> +       return 0;
>>>>> +}
>>>>> +#else
>>>>> +static int bus1_cs_valid(unsigned int bus, unsigned int cs) {
>>>>> +       return 0;
>>>>> +}
>>>>> +#endif
>>>>> +
>>>>> +#ifdef CONFIG_SYS_SPI2
>>>>> +static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
>>>>> +       if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
>>>>> +               return 1;
>>>>> +       return 0;
>>>>> +}
>>>>> +#else
>>>>> +static int bus2_cs_valid(unsigned int bus, unsigned int cs) {
>>>>> +       return 0;
>>>>> +}
>>>>> +#endif
>>>>> +
>>>>>  int spi_cs_is_valid(unsigned int bus, unsigned int cs)  {
>>>>> -       return bus == 0 && cs == 0;
>>>>> +       if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
>>>>> +               return 1;
>>>>> +       else if (bus1_cs_valid(bus, cs))
>>>>> +               return 1;
>>>>> +       else if (bus2_cs_valid(bus, cs))
>>>>> +               return 1;
>>>>> +       return 0;
>>>>>  }
>>>>>
>>>>>  void spi_cs_activate(struct spi_slave *slave) diff --git
>>>>> a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h index
>>>>> 33f69b5..d4612d3 100644
>>>>> --- a/drivers/spi/davinci_spi.h
>>>>> +++ b/drivers/spi/davinci_spi.h
>>>>> @@ -74,6 +74,39 @@ struct davinci_spi_regs {
>>>>>  /* SPIDEF */
>>>>>  #define SPIDEF_CSDEF0_MASK     BIT(0)
>>>>>
>>>>> +#define SPI0_BUS               0
>>>>> +#define SPI0_BASE              CONFIG_SYS_SPI_BASE
>>>>> +/*
>>>>> + * Define default SPI0_NUM_CS as 1 for existing platforms that
>>>>> +uses this
>>>>> + * driver. Platform can configure number of CS using
>>>>> +CONFIG_SYS_SPI0_NUM_CS
>>>>> + * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
>>>>> + */
>>>>> +#ifndef CONFIG_SYS_SPI0
>>>>> +#define SPI0_NUM_CS            1
>>>>> +#else
>>>>> +#define SPI0_NUM_CS            CONFIG_SYS_SPI0_NUM_CS
>>>>> +#endif
>>>>> +
>>>>> +/*
>>>>> + * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1)
>>>>> +and
>>>>> + * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus  */
>>>>> +#ifdef
>>>>> +CONFIG_SYS_SPI1
>>>>> +#define SPI1_BUS               1
>>>>> +#define SPI1_NUM_CS            CONFIG_SYS_SPI1_NUM_CS
>>>>> +#define SPI1_BASE              CONFIG_SYS_SPI1_BASE
>>>>> +#endif
>>>>> +
>>>>> +/*
>>>>> + * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2)
>>>>> +and
>>>>> + * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus  */
>>>>> +#ifdef
>>>>> +CONFIG_SYS_SPI2
>>>>> +#define SPI2_BUS               2
>>>>> +#define SPI2_NUM_CS            CONFIG_SYS_SPI2_NUM_CS
>>>>> +#define SPI2_BASE              CONFIG_SYS_SPI2_BASE
>>>>> +#endif
>>>>> +
>>>>>  struct davinci_spi_slave {
>>>>>         struct spi_slave slave;
>>>>>         struct davinci_spi_regs *regs;
>>>>> --
>>>>> 1.7.9.5
>>>>
>>>>This code looks more static, can you try get the bus and cs from sf
>>>>probe and according assign the reg_base.
>>>>
>>>>fyi: look at drivers/spi/zynq_spi.c where based on the bus number we
>>>>assign the reg_base and prior to that we can do the same for bus and cs.
>>>>
>>>
>>> Jagan,
>>>
>>> Thanks for your comments.
>>>
>>> I looked at the driver code. In the example driver you provided the
>>> reg_base is chosen based on device number and the hardware.h define
>>> the base0 and base1 address and assign it based on device number.
>>> davinci_spi is re-used on many devices. All of the DaVinci devices
>>> such as dm644x, dm355, dm365 etc that mostly has one SPI device vs
>>> keystone devices such k2h/k that has 3 devices.
>>> If I follow this approach, I need to define BASE1 and BASE2 in the
>>> hardware.h of all devices that this software must run.
>>> This is not right since DaVinci devices has only one SPI device
>>>
>>> I think this is what best we can do given that the driver needs to be
>>> re-used across multiple devices and static is the way to go unless
>>> you have better suggestion to handle this scenario.
>>
>>Agree with your comments as reg_base is not possible to define at one
>>place due to this you may not try as I suggested.
>>
>>OK, atleast can you aviod using busx_cs_valid() calls, try to manage
>>spi_cs_is_valid() itself.
>>
>Jagan,
>
>Thanks again. But to me it is just a personal opinion. I would let it go ASIS unless you can
>give me a strong reason to change the code and provide a sample as well. The if else
>statement with #ifdef interleaved will make it really messy. I will make it static inline as
>the function call is unnecessary.
>

Jagan,

Ok. I found my original code will add additional return statements on platforms
that doesn't have more than one SPI device. So reworked the patch as you have
suggested. Please see the v5 for the change and I will be sending the same today.

Murali

>Murali
>>thanks!
>>--
>>Jagan.
>_______________________________________________
>U-Boot mailing list
>U-Boot at lists.denx.de
>http://lists.denx.de/mailman/listinfo/u-boot


More information about the U-Boot mailing list