[U-Boot] [PATCH 3/8] tegra2: spi: Add SPI driver for SPIFLASH on Seaboard

Simon Glass sjg at chromium.org
Fri Oct 21 01:02:14 CEST 2011


Hi Mike,

On Thu, Oct 20, 2011 at 1:03 PM, Mike Frysinger <vapier at gentoo.org> wrote:
> On Thursday 20 October 2011 15:03:24 Simon Glass wrote:
>> This driver supports SPI on Tegra2, running at 48MHz.
>
> the summary says "SPIFLASH" and "Seaboard".  sounds like this is a tegra2 SoC
> issue, and so driver/board specific info shouldn't be in the summary.
>
> adding notes to the changelog as to what boards/setups have been tested is OK
> though ...
>
>> --- /dev/null
>> +++ b/arch/arm/include/asm/arch-tegra2/tegra2_spi.h
>>
>> +struct spi_tegra {
>> +     u32 command;    /* SPI_COMMAND_0 register  */
>> +     u32 status;     /* SPI_STATUS_0 register */
>> +     u32 rx_cmp;     /* SPI_RX_CMP_0 register  */
>> +     u32 dma_ctl;    /* SPI_DMA_CTL_0 register */
>> +     u32 tx_fifo;    /* SPI_TX_FIFO_0 register */
>> +     u32 rsvd[3];    /* offsets 0x14 to 0x1F reserved */
>> +     u32 rx_fifo;    /* SPI_RX_FIFO_0 register */
>> +
>> +};
>
> don't need that newline before the closing brace
>
>> --- /dev/null
>> +++ b/drivers/spi/tegra2_spi.c
>>
>> +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
>> +{
>> +     /* Tegra2 SPI-Flash - only 1 device ('bus/cs') */
>> +     if (bus > 0 && cs != 0)
>> +             return 0;
>> +     else
>> +             return 1;
>> +}
>> +
>> +
>
> only need one new line here
>
>> +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
>> +             unsigned int max_hz, unsigned int mode)
>> +{
>> +     struct spi_slave *slave;
>> +
>> +     if (!spi_cs_is_valid(bus, cs))
>> +             return NULL;
>> +
>> +     slave = malloc(sizeof(struct spi_slave));
>> +     if (!slave)
>> +             return NULL;
>> +
>> +     slave->bus = bus;
>> +     slave->cs = cs;
>> +
>> +     /*
>> +      * Currently, Tegra2 SFLASH uses mode 0 & a 24MHz clock.
>> +      * Use 'mode' and 'maz_hz' to change that here, if needed.
>> +      */
>> +
>> +     return slave;
>> +}
>
> this should be respecting hz/mode ...

Thanks for the comments.

OK I will need to implement this. There will be a short delay....

Regards,
Simon

>
>> +void spi_init(void)
>> +{
>> +     struct spi_tegra *spi = (struct spi_tegra *)TEGRA2_SPI_BASE;
>> +     u32 reg;
>> +
>> +     /* Change SPI clock to 48MHz, PLLP_OUT0 source */
>> +     clock_start_periph_pll(PERIPH_ID_SPI1, CLOCK_ID_PERIPH, 48000000);
>> +
>> +     /* Clear stale status here */
>> +     reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \
>> +             SPI_STAT_RXF_UNR | SPI_STAT_TXF_OVF;
>> +     writel(reg, &spi->status);
>> +     debug("spi_init: STATUS = %08x\n", readl(&spi->status));
>> +
>> +     /*
>> +      * Use sw-controlled CS, so we can clock in data after ReadID, etc.
>> +      */
>> +     reg = readl(&spi->command);
>> +     writel(reg | SPI_CMD_CS_SOFT, &spi->command);
>> +     debug("spi_init: COMMAND = %08x\n", readl(&spi->command));
>> +
>> +     /*
>> +      * SPI pins on Tegra2 are muxed - change pinmux later due to UART
>> +      * issue.
>> +      */
>> +}
>
> shouldn't this be in spi_claim_bus() ?  and configured using the values
> requested at spi_setup_slave() ?
>
>> +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void
>> +             *dout, void *din, unsigned long flags)
>> +{
>>
>> +     int num_bytes = (bitlen + 7) / 8;
>
> if you can only handle multiples of 8 bits, then return an error.  many (most)
> of the spi buses do just that.
>
>> +     reg = readl(&spi->command);
>> +     writel((reg |= (SPI_CMD_TXEN | SPI_CMD_RXEN)), &spi->command);
>
> ugh!  pull that "|=" operation out and move it up to the readl() line above.
>
>> +     debug("spi_xfer: COMMAND = %08x\n", readl(&spi->command));
>
> the debug() should use "reg" rather than readl().
>
>> +     debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
>> +           slave->bus, slave->cs, *(u8 *)dout, *(u8 *)din, bitlen);
>> ...
>> +                             tmpdout = (tmpdout << 8) | ((u8 *) dout)[i];
>> ...
>> +                                             ((u8 *)din)[i] =
>> +                                                     (tmpdin & 0xff);
>
> please setup local vars with u8* type and set din/dout to that to avoid all
> these inline casts
>
>> +             writel((reg |= SPI_CMD_GO), &spi->command);
>
> hoist that |= operation up and out
> -mike
>


More information about the U-Boot mailing list