From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ben Warren Date: Mon, 08 Dec 2008 10:33:42 -0800 Subject: [U-Boot] [PATCH 1/2][RESEND] Add an SPI driver for PPC440EPx In-Reply-To: <493D5B65.6020305@harris.com> References: <493D5B65.6020305@harris.com> Message-ID: <493D6886.9080803@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Steven, Steven A. Falco wrote: > This patch adds a SPI driver for the PPC440EPx processor. > > Signed-off-by: Steven A. Falco > --- > Sorry - forgot the subject line, the first time. > > cpu/ppc4xx/Makefile | 1 + > cpu/ppc4xx/spi.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++ > include/4xx_spi.h | 50 ++++++++++++++++++++ > 3 files changed, 179 insertions(+), 0 deletions(-) > create mode 100644 cpu/ppc4xx/spi.c > create mode 100644 include/4xx_spi.h > > diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile > index 96ab5c6..bdebfb6 100644 > --- a/cpu/ppc4xx/Makefile > +++ b/cpu/ppc4xx/Makefile > @@ -54,6 +54,7 @@ COBJS += iop480_uart.o > COBJS += ndfc.o > COBJS += sdram.o > COBJS += speed.o > +COBJS += spi.o > COBJS += tlb.o > COBJS += traps.o > COBJS += usb.o > diff --git a/cpu/ppc4xx/spi.c b/cpu/ppc4xx/spi.c > Please put this in drivers/spi, and create a CONFIG for it that is appropriate. For example, CONFIG_PPC4xx_SPI if this controller is found on 405, 440 and 460 SOCs, CONFIG_PPC44x_SPI if only on 440 and CONFIG_PPC440EPX_SPI if only on 440EPX. Then follow the format found in drivers/spi/Makefile for conditionally compiling it in. > new file mode 100644 > index 0000000..572244b > --- /dev/null > +++ b/cpu/ppc4xx/spi.c > @@ -0,0 +1,128 @@ > +/* > + * Copyright (C) 2008 Harris Corporation > + * Author: Steven A. Falco > + * > + * See file CREDITS for list of people who contributed to this > + * project. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, > + * MA 02111-1307 USA > + */ > + > +#include > +#include > +#include > + > +#include > + > +#include <4xx_spi.h> > + > +#if defined(CONFIG_HARD_SPI) > This shouldn't be necessary if you use the driver-specific CONFIG as I mentioned above. > + > +void spi_init (void ) > +{ > + volatile u8 *cd = (volatile u8 *) SPI_CDM; > + volatile u8 *md = (volatile u8 *) SPI_MODE; > + > Please use the built-in accessors found in include/asm-ppc/io.h instead (in_8 etc.). This will force some pretty big changes to your patch, so I won't mention them all. > + *cd = 0; /* Default to "go fast" */ > + *md = SPI_MODE_SPE; /* Enable port */ > +} > + > +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, > + unsigned int max_hz, unsigned int mode) > +{ > + volatile u8 *md = (volatile u8 *) SPI_MODE; > + volatile u8 *cd = (volatile u8 *) SPI_CDM; > + ulong opb = get_OPB_freq(); > + ulong divisor; > + struct spi_slave *s; > + > + if(!spi_cs_is_valid(bus, cs)) > + return NULL; > + > + divisor = ((opb + (max_hz * 4) - 1) / (max_hz * 4)) - 1; > + if(divisor > 255) > + return NULL; > + > + *cd = divisor; > + > + if (!(s = malloc(sizeof(struct spi_slave)))) > + return NULL; > + > + if (mode & SPI_CPHA) > + *md &= ~SPI_MODE_SCP; > + else > + *md |= SPI_MODE_SCP; > + > + if (mode & SPI_CPOL) > + *md |= SPI_MODE_CI; > + else > + *md &= ~SPI_MODE_CI; > + > + s->bus = bus; > + s->cs = cs; > + > + return s; > +} > + > +void spi_free_slave(struct spi_slave *slave) > +{ > + free(slave); > +} > + > +int spi_claim_bus(struct spi_slave *slave) > +{ > + return 0; > +} > + > +void spi_release_bus(struct spi_slave *slave) > +{ > +} > + > +#define GO *cr = SPI_CR_STR > +#define TXWAIT while(*sr & SPI_SR_BSY) > +#define RXWAIT while(!(*sr & SPI_SR_RBR)) > + > +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, > + const void *dout, void *din, unsigned long flags) > +{ > + volatile u8 *cr = (volatile u8 *) SPI_CR; > + volatile u8 *sr = (volatile u8 *) SPI_SR; > + volatile u8 *tx = (volatile u8 *) SPI_TXD; > + volatile u8 *rx = (volatile u8 *) SPI_RXD; > + > + const u8 *txd = dout; > + u8 *rxd = din; > + int ii; > + > + if (flags & SPI_XFER_BEGIN) > + spi_cs_activate(slave); > + > + /* Do a byte at a time */ > + for (ii = 0; ii < ((bitlen + 7) / 8); ii++) { > + TXWAIT; > + *tx = *txd++; > + GO; > + RXWAIT; > + *rxd++ = *rx; > + } > + > + if (flags & SPI_XFER_END) > + spi_cs_deactivate(slave); > + > + return 0; > +} > + > +#endif /* CONFIG_HARD_SPI */ > diff --git a/include/4xx_spi.h b/include/4xx_spi.h > Probably put this file in include/asm-ppc/ > new file mode 100644 > index 0000000..331de20 > --- /dev/null > +++ b/include/4xx_spi.h > @@ -0,0 +1,50 @@ > +/* > + * Copyright (C) 2008 Harris Corporation > + * Author: Steven A. Falco > + * > + * See file CREDITS for list of people who contributed to this > + * project. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, > + * MA 02111-1307 USA > + */ > + > +#ifndef _4xx_spi_h_ > +#define _4xx_spi_h_ > + > +#if defined(CONFIG_440EPX) > +#define SPI_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x00000900) > +#endif > + > +#define SPI_REGISTERS_BASE_ADDRESS SPI_BASE_ADDR > +#define SPI_MODE (SPI_REGISTERS_BASE_ADDRESS + 0x00) > +#define SPI_RXD (SPI_REGISTERS_BASE_ADDRESS + 0x01) > +#define SPI_TXD (SPI_REGISTERS_BASE_ADDRESS + 0x02) > +#define SPI_CR (SPI_REGISTERS_BASE_ADDRESS + 0x03) > +#define SPI_SR (SPI_REGISTERS_BASE_ADDRESS + 0x04) > +#define SPI_CDM (SPI_REGISTERS_BASE_ADDRESS + 0x06) > + > If the controller is common to different chips and the register layout is similar, it's much cleaner to define a struct somewhere and reference a pointer to it rather than using macros like this. For example, please see include/asm-ppc/mpc8xxx_spi.h > +#define SPI_CR_STR (0x01) > + > +#define SPI_SR_RBR (0x01) > +#define SPI_SR_BSY (0x02) > + > +#define SPI_MODE_IL (0x01) > +#define SPI_MODE_CI (0x02) > +#define SPI_MODE_RD (0x04) > +#define SPI_MODE_SPE (0x08) > +#define SPI_MODE_SCP (0x10) > + > Some will argue that the brackets aren't needed around constants. > +#endif /* _4xx_spi_h_ */ > regards, Ben