[flashrom] [PATCH] Nvidia MCP SPI speedup

Andrew Morgan ziltro at ziltro.com
Tue Aug 3 16:55:19 CEST 2010


  Read times before patch:
real    1m47.500s
user    1m47.190s
sys     0m0.130s

Read times after patch:
real    0m51.714s
user    0m51.370s
sys     0m0.150s

The data read before and after the patch was identical.
Log attached.

Tested-by: Andrew Morgan <ziltro at ziltro.com>

-- 

Andrew.


On 03/08/2010 15:27, Carl-Daniel Hailfinger wrote:
> Use caching for Nvidia MCP SPI GPIO accesses.
> Reduce clock delay to zero.
>
> Should result in a 2x speedup, maybe more.
>
> Signed-off-by: Carl-Daniel Hailfinger<c-d.hailfinger.devel.2006 at gmx.net>
>
> Index: flashrom-bitbang_spi_nvidia_mcp_faster/mcp6x_spi.c
> ===================================================================
> --- flashrom-bitbang_spi_nvidia_mcp_faster/mcp6x_spi.c	(Revision 1130)
> +++ flashrom-bitbang_spi_nvidia_mcp_faster/mcp6x_spi.c	(Arbeitskopie)
> @@ -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;
> +	mcp_gpiostate = mmio_readb(mcp6x_spibar + 0x530);
> +	mcp_gpiostate |= 1<<  MCP6X_SPI_REQUEST;
> +	mmio_writeb(mcp_gpiostate, mcp6x_spibar + 0x530);
>
> -	tmp = mmio_readb(mcp6x_spibar + 0x530);
> -	tmp |= 1<<  MCP6X_SPI_REQUEST;
> -	mmio_writeb(tmp, 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;
>
>

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: flashrom-Vr-SPI-speedup.txt
URL: <http://www.flashrom.org/pipermail/flashrom/attachments/20100803/4d4cceee/attachment.txt>


More information about the flashrom mailing list