Hi,

I am working on getting u-boot (circa 2009.08) to program an SPI flash (STMicro 
M25P40)
that contains the equations for our board's fpga.

While looking at mpc8xxx_spi I realized it is coded for a non-QUICC-Engine 
based SPI flavor of 8xxx.

I worked up this patch that compiles for mpc8360e. I'd like to share to get 
some sanity check if this is
a good approach that have a hope of being mainlined. The idea is to use the 
MPC8360e SPI controller
in cpu-mode, in which case SOME bits are different, but none are being used at 
the moment.

Another approach I looked at is the /cpu/mpc8260/spi.c but I think this will 
eventually be superseded by mpc_8xxx.spi, no?

Right now I'm stuck in the transfer timing out. With a slight head-scratching 
at this comment:

/*
  * Wait for SPI transmit to get out
  * or time out (1 second = 1000 ms)
  * The NE event must be read and cleared first
  */

Yet in the loop I don't see any udelay(1000) to get us to 1second (based on 
SPI_TIMEOUT = 1000)
am I missing something here?


This is what I've done so far to compile with mpc8360
-----------------------------------------------------

diff --git a/drivers/spi/mpc8xxx_spi.c b/drivers/spi/mpc8xxx_spi.c
index c4b36f0..ff4b44e 100644
--- a/drivers/spi/mpc8xxx_spi.c
+++ b/drivers/spi/mpc8xxx_spi.c
@@ -27,14 +27,27 @@
  #include <spi.h>
  #include <asm/mpc8xxx_spi.h>

+#if defined (CONFIG_MPC8360)
+#include <asm/immap_qe.h>
+#endif
+
+#if defined (CONFIG_MPC8360)
+#define SPI_EV_NE      (0x80 >> 6)     /* Receiver Not Empty */
+#define SPI_EV_NF      (0x80 >> 7)     /* Transmitter Not Full */
+#else
  #define SPI_EV_NE     (0x80000000 >> 22)      /* Receiver Not Empty */
  #define SPI_EV_NF     (0x80000000 >> 23)      /* Transmitter Not Full */
+#endif

  #define SPI_MODE_LOOP (0x80000000 >> 1)       /* Loopback mode */
  #define SPI_MODE_REV  (0x80000000 >> 5)       /* Reverse mode - MSB first */
  #define SPI_MODE_MS   (0x80000000 >> 6)       /* Always master */
  #define SPI_MODE_EN   (0x80000000 >> 7)       /* Enable interface */

+#if defined (CONFIG_MPC8360)
+#define SPI_MODE_OP    (0x80000000 >> 17)      /* CPU mode */
+#endif
+
  #define SPI_TIMEOUT   1000

  struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
@@ -67,6 +80,22 @@ void spi_free_slave(struct spi_slave *slave)

  void spi_init(void)
  {
+#if defined (CONFIG_MPC8360)
+       volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR;
+       volatile qe_map_t *qe = (volatile qe_map_t *)&im->qe;
+       volatile spi_t *spi = (volatile spi_t *)&qe->spi;
+
+       /*
+        * SPI pins on the MPC83xx are not muxed, so all we do is initialize
+        * some registers (mode must be CPU mode to use this driver)
+        */
+       spi->mode = SPI_MODE_REV | SPI_MODE_MS | SPI_MODE_EN | SPI_MODE_OP;
+       spi->mode = (spi->mode & 0xfff0ffff) | (1 << 16); /* Use QE_CLK / 16
+                                                            (12.5 MHz typ.) */
+       spi->event = 0xff;      /* Clear all SPI events */
+       spi->mask = 0x00;       /* Mask  all SPI interrupts */
+       spi->com = 0;           /* LST bit doesn't do anything, so disregard */
+#else
        volatile spi8xxx_t *spi = &((immap_t *) (CONFIG_SYS_IMMR))->spi;

        /*
@@ -79,6 +108,8 @@ void spi_init(void)
        spi->event = 0xffffffff;        /* Clear all SPI events */
        spi->mask = 0x00000000; /* Mask  all SPI interrupts */
        spi->com = 0;           /* LST bit doesn't do anything, so disregard */
+#endif
+
  }

  int spi_claim_bus(struct spi_slave *slave)
@@ -94,19 +125,32 @@ void spi_release_bus(struct spi_slave *slave)
  int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
                void *din, unsigned long flags)
  {
+#if defined (CONFIG_MPC8360)
+       volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR;
+       volatile qe_map_t *qe = (volatile qe_map_t *)&im->qe;
+       volatile spi_t *spi = (volatile spi_t *)&qe->spi;
+       unsigned short event;
+#else
        volatile spi8xxx_t *spi = &((immap_t *) (CONFIG_SYS_IMMR))->spi;
-       unsigned int tmpdout, tmpdin, event;
+       unsigned int event;
+#endif
+
+       unsigned int tmpdout, tmpdin;
        int numBlks = bitlen / 32 + (bitlen % 32 ? 1 : 0);
        int tm, isRead = 0;
        unsigned char charSize = 32;

-       debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
+       printf("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
              slave->bus, slave->cs, *(uint *) dout, *(uint *) din, bitlen);

        if (flags & SPI_XFER_BEGIN)
                spi_cs_activate(slave);

+#if defined (CONFIG_MPC8360)
+       spi->event = 0xff;      /* Clear all SPI events */
+#else
        spi->event = 0xffffffff;        /* Clear all SPI events */
+#endif

        /* handle data in 32-bit chunks */
        while (numBlks--) {
@@ -139,7 +183,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, 
const void *dout,
                }

                spi->tx = tmpdout;      /* Write the data out */
-               debug("*** spi_xfer: ... %08x written\n", tmpdout);
+               printf("*** spi_xfer: ... %08x written\n", tmpdout);

                /*
                 * Wait for SPI transmit to get out
diff --git a/include/asm-ppc/immap_qe.h b/include/asm-ppc/immap_qe.h
index 531cfc8..4f11e04 100644
--- a/include/asm-ppc/immap_qe.h
+++ b/include/asm-ppc/immap_qe.h
@@ -159,18 +159,18 @@ typedef struct qe_brg {
  */
  typedef struct spi {
        u8 res0[0x20];
-       u32 spmode;             /* SPI mode register */
+       u32 mode;               /* SPI mode register */
        u8 res1[0x2];
-       u8 spie;                /* SPI event register */
+       u8 event;               /* SPI event register */
        u8 res2[0x1];
        u8 res3[0x2];
-       u8 spim;                /* SPI mask register */
+       u8 mask;                /* SPI mask register */
        u8 res4[0x1];
        u8 res5[0x1];
-       u8 spcom;               /* SPI command register  */
+       u8 com;                 /* SPI command register  */
        u8 res6[0x2];
-       u32 spitd;              /* SPI transmit data register (cpu mode) */
-       u32 spird;              /* SPI receive data register (cpu mode) */
+       u32 tx;                 /* SPI transmit data register (cpu mode) */
+       u32 rx;                 /* SPI receive data register (cpu mode) */
        u8 res7[0x8];
  } __attribute__ ((packed)) spi_t;


_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to