Author: hailfinger
Date: Tue Sep 14 03:29:49 2010
New Revision: 1164
URL: http://flashrom.org/trac/flashrom/changeset/1164

Log:
Use caching for Nvidia MCP SPI GPIO accesses.
Reduce clock delay to zero.

Tests show more than 2x speedup.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2...@gmx.net>
Tested-by: Andrew Morgan <zil...@ziltro.com>
Acked-by: Uwe Hermann <u...@hermann-uwe.de>

Modified:
   trunk/mcp6x_spi.c

Modified: trunk/mcp6x_spi.c
==============================================================================
--- trunk/mcp6x_spi.c   Tue Sep 14 01:00:57 2010        (r1163)
+++ trunk/mcp6x_spi.c   Tue Sep 14 03:29:49 2010        (r1164)
@@ -42,41 +42,39 @@
 
 void *mcp6x_spibar = NULL;
 
+/* Cached value of last GPIO state. */
+static uint8_t mcp_gpiostate;
+
 static void mcp6x_request_spibus(void)
 {
-       uint8_t tmp;
-
-       tmp = mmio_readb(mcp6x_spibar + 0x530);
-       tmp |= 1 << MCP6X_SPI_REQUEST;
-       mmio_writeb(tmp, mcp6x_spibar + 0x530);
+       mcp_gpiostate = mmio_readb(mcp6x_spibar + 0x530);
+       mcp_gpiostate |= 1 << MCP6X_SPI_REQUEST;
+       mmio_writeb(mcp_gpiostate, mcp6x_spibar + 0x530);
 
        /* Wait until we are allowed to use the SPI bus. */
        while (!(mmio_readw(mcp6x_spibar + 0x530) & (1 << MCP6X_SPI_GRANT))) ;
+
+       /* Update the cache. */
+       mcp_gpiostate = mmio_readb(mcp6x_spibar + 0x530);
 }
 
 static void mcp6x_release_spibus(void)
 {
-       uint8_t tmp;
-
-       tmp = mmio_readb(mcp6x_spibar + 0x530);
-       tmp &= ~(1 << MCP6X_SPI_REQUEST);
-       mmio_writeb(tmp, mcp6x_spibar + 0x530);
+       mcp_gpiostate &= ~(1 << MCP6X_SPI_REQUEST);
+       mmio_writeb(mcp_gpiostate, mcp6x_spibar + 0x530);
 }
 
 static void mcp6x_bitbang_set_cs(int val)
 {
-       uint8_t tmp;
-
        /* Requesting and releasing the SPI bus is handled in here to allow the
         * chipset to use its own SPI engine for native reads.
         */
        if (val == 0)
                mcp6x_request_spibus();
 
-       tmp = mmio_readb(mcp6x_spibar + 0x530);
-       tmp &= ~(1 << MCP6X_SPI_CS);
-       tmp |= (val << MCP6X_SPI_CS);
-       mmio_writeb(tmp, mcp6x_spibar + 0x530);
+       mcp_gpiostate &= ~(1 << MCP6X_SPI_CS);
+       mcp_gpiostate |= (val << MCP6X_SPI_CS);
+       mmio_writeb(mcp_gpiostate, mcp6x_spibar + 0x530);
 
        if (val == 1)
                mcp6x_release_spibus();
@@ -84,31 +82,22 @@
 
 static void mcp6x_bitbang_set_sck(int val)
 {
-       uint8_t tmp;
-
-       tmp = mmio_readb(mcp6x_spibar + 0x530);
-       tmp &= ~(1 << MCP6X_SPI_SCK);
-       tmp |= (val << MCP6X_SPI_SCK);
-       mmio_writeb(tmp, mcp6x_spibar + 0x530);
+       mcp_gpiostate &= ~(1 << MCP6X_SPI_SCK);
+       mcp_gpiostate |= (val << MCP6X_SPI_SCK);
+       mmio_writeb(mcp_gpiostate, mcp6x_spibar + 0x530);
 }
 
 static void mcp6x_bitbang_set_mosi(int val)
 {
-       uint8_t tmp;
-
-       tmp = mmio_readb(mcp6x_spibar + 0x530);
-       tmp &= ~(1 << MCP6X_SPI_MOSI);
-       tmp |= (val << MCP6X_SPI_MOSI);
-       mmio_writeb(tmp, mcp6x_spibar + 0x530);
+       mcp_gpiostate &= ~(1 << MCP6X_SPI_MOSI);
+       mcp_gpiostate |= (val << MCP6X_SPI_MOSI);
+       mmio_writeb(mcp_gpiostate, mcp6x_spibar + 0x530);
 }
 
 static int mcp6x_bitbang_get_miso(void)
 {
-       uint8_t tmp;
-
-       tmp = mmio_readb(mcp6x_spibar + 0x530);
-       tmp = (tmp >> MCP6X_SPI_MISO) & 0x1;
-       return tmp;
+       mcp_gpiostate = mmio_readb(mcp6x_spibar + 0x530);
+       return (mcp_gpiostate >> MCP6X_SPI_MISO) & 0x1;
 }
 
 static const struct bitbang_spi_master bitbang_spi_master_mcp6x = {
@@ -176,9 +165,10 @@
        msg_pdbg("SPI control is 0x%04x, req=%i, gnt=%i\n",
                 status, (status >> MCP6X_SPI_REQUEST) & 0x1,
                 (status >> MCP6X_SPI_GRANT) & 0x1);
+       mcp_gpiostate = status & 0xff;
 
-       /* 1 usec halfperiod delay for now. */
-       if (bitbang_spi_init(&bitbang_spi_master_mcp6x, 1)) {
+       /* Zero halfperiod delay. */
+       if (bitbang_spi_init(&bitbang_spi_master_mcp6x, 0)) {
                /* This should never happen. */
                msg_perr("MCP6X bitbang SPI master init failed!\n");
                return 1;

_______________________________________________
flashrom mailing list
flashrom@flashrom.org
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to