From patchwork Thu Jul 30 21:49:52 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Brownell X-Patchwork-Id: 39259 Received: from devils.ext.ti.com (devils.ext.ti.com [198.47.26.153]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n750V9R7021135 for ; Wed, 5 Aug 2009 00:31:10 GMT Received: from dlep35.itg.ti.com ([157.170.170.118]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id n750TY6E031521; Tue, 4 Aug 2009 19:29:39 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep35.itg.ti.com (8.13.7/8.13.7) with ESMTP id n750TXES024317; Tue, 4 Aug 2009 19:29:33 -0500 (CDT) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id BBAC880631; Tue, 4 Aug 2009 19:29:19 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp53.itg.ti.com (dflp53.itg.ti.com [128.247.5.6]) by linux.omap.com (Postfix) with ESMTP id ABDF980627 for ; Tue, 4 Aug 2009 19:28:36 -0500 (CDT) Received: from neches.ext.ti.com (localhost [127.0.0.1]) by dflp53.itg.ti.com (8.13.8/8.13.8) with ESMTP id n750SYxN002551 for ; Tue, 4 Aug 2009 19:28:34 -0500 (CDT) Received: from mail71-va3-R.bigfish.com (mail-va3.bigfish.com [216.32.180.112]) by neches.ext.ti.com (8.13.7/8.13.7) with ESMTP id n750STAj021144 for ; Tue, 4 Aug 2009 19:28:34 -0500 Received: from mail71-va3 (localhost.localdomain [127.0.0.1]) by mail71-va3-R.bigfish.com (Postfix) with ESMTP id 6BB65D98171 for ; Wed, 5 Aug 2009 00:28:29 +0000 (UTC) X-SpamScore: -13 X-BigFish: vps-13(zcb8kz1432R9370K98dN19c2kzz1202hzzz2dh5eh6bh177h65h) X-Spam-TCS-SCL: 4:0 X-FB-SS: 5, X-MS-Exchange-Organization-Antispam-Report: OrigIP: 68.142.206.146; Service: EHS Received: by mail71-va3 (MessageSwitch) id 1249432107441429_11444; Wed, 5 Aug 2009 00:28:27 +0000 (UCT) Received: from n19.bullet.mail.mud.yahoo.com (n19.bullet.mail.mud.yahoo.com [68.142.206.146]) by mail71-va3.bigfish.com (Postfix) with SMTP id 46C921B50052 for ; Wed, 5 Aug 2009 00:28:27 +0000 (UTC) Received: from [68.142.200.224] by n19.bullet.mail.mud.yahoo.com with NNFMP; 05 Aug 2009 00:28:27 -0000 Received: from [68.142.201.68] by t5.bullet.mud.yahoo.com with NNFMP; 05 Aug 2009 00:28:26 -0000 Received: from [127.0.0.1] by omp420.mail.mud.yahoo.com with NNFMP; 05 Aug 2009 00:28:26 -0000 X-Yahoo-Newman-Id: 872539.57932.bm@omp420.mail.mud.yahoo.com Received: (qmail 75329 invoked from network); 5 Aug 2009 00:28:26 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=pacbell.net; h=Received:X-YMail-OSG:X-Yahoo-Newman-Property:From:To:Subject:Date:User-Agent:Cc:References:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-Disposition:Message-Id; b=kNOipx/Bd/tdFIhl08g0O7utpFjOqfhYUlGQcf4iYc5hPlmAoLzbVswdVTtVhpmQ5+GVqrkvKq3YqBDpnP+tNLEVkGcwRUqQQNwZevola2eX+w4ieEaEjSB/IHzUQCzUrvK+CuIBnr8Axm0fO/Ao06gxY8+JRbMIlq4lFXQSjJI= ; Received: from unknown (HELO albert) (david-b@69.226.245.56 with plain) by smtp109.sbc.mail.sp1.yahoo.com with SMTP; 5 Aug 2009 00:28:25 -0000 X-YMail-OSG: uS0UwoQVM1mbFngdITndYEo50rvX9BylAq_aScmCN_IAD87jBvFWUD3UlOiKoBJPrITeNq1V36eDFcOn7RqZkq6OeVIAZ3G7cV7CM1_3s_ndo2wU1LMabP0lcCPJM3We9LFdrD0aSxgPEcnr563xwTiLS04KiTH16Mdh2sSbNiNkYhZ2NMiP5d8G3AgVX3EeatY5sDSdci8.bi9UMsdCj6FyCMHVyApgh91Q9hQdpHpZwPPLwpMOXGrpsqQgL4Nh1X6519A3Z.1jKhm3t7t6CiooBd_rVEeyCUUHPRfeG9bsBZczX4xYrwXrsAJDbJ6xbGjw16eYLHKDe1rv X-Yahoo-Newman-Property: ymail-3 From: David Brownell To: s-paulraj@ti.com Date: Thu, 30 Jul 2009 14:49:52 -0700 User-Agent: KMail/1.9.10 References: <1247690282-995-1-git-send-email-s-paulraj@ti.com> <200907161528.42522.david-b@pacbell.net> In-Reply-To: <200907161528.42522.david-b@pacbell.net> MIME-Version: 1.0 Content-Disposition: inline Message-Id: <200907301449.52674.david-b@pacbell.net> Cc: davinci-linux-open-source@linux.davincidsp.com Subject: Re: [PATCH 1/6] DaVinci: SPI Driver for DaVinci and DA8xx SOC's X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.4 Precedence: list List-Id: davinci-linux-open-source.linux.davincidsp.com List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: davinci-linux-open-source-bounces@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com On Thursday 16 July 2009, David Brownell wrote: > On Wednesday 15 July 2009, s-paulraj@ti.com wrote: > >  arch/arm/mach-davinci/include/mach/spi.h |   45 ++ > >  drivers/spi/Kconfig                      |    7 + > >  drivers/spi/Makefile                     |    1 + > >  drivers/spi/davinci_spi.c                |  751 ++++++++++++++++++++++++++++++ > >  drivers/spi/davinci_spi.h                |  163 +++++++ > >  5 files changed, 967 insertions(+), 0 deletions(-) > > It's getting a lot closer.  See the appended ... the issues I > see remaining are partly performance (if you only set the FMT > register in the setup code the per-message overhead will be > a lot less) and partly functional (those per-device settings > that are treated as global, or wrongly held back on v1 parts). > > Let me know if you plan to address either of those. > > - Dave > I saw a followup from you that was incorrect (failed when spi_setup was called with an operation pending) ... so here's a second fixup, going on top of that 16-july patch, which moves almost everything out of per-message overhead. Verified on dm355evm and dm365evm Please let me know if there's a reason I shouldn't send your [1/6] patch upstream after combining it with the two fixup patches I've sent. - Dave ======== CUT HERE A few more fixes vs my previous patch: - Remove needless spi->bits_per_word default, now handled by the SPI core; - Move SPIFMTx setting to the spi_setup() code, out of the per-message overhead; - Move some never-change SPI settings to probe(), again out of the per-message overhead. This keeps a lot of setup code from being per-message overhead. --- drivers/spi/davinci_spi.c | 89 ++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 43 deletions(-) --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -198,10 +198,6 @@ static int davinci_spi_setup(struct spi_ davinci_spi = spi_master_get_devdata(spi->master); - /* if bits per word length is zero then set it default 8 */ - if (!spi->bits_per_word) - spi->bits_per_word = 8; - /* * SPI in DaVinci and DA8xx operate between * 600 KHz and 50 MHz @@ -209,23 +205,13 @@ static int davinci_spi_setup(struct spi_ if (spi->max_speed_hz < 600000 || spi->max_speed_hz > 50000000) return -EINVAL; - retval = davinci_spi_setup_transfer(spi, NULL); - - return retval; -} - -static int davinci_spi_bufs_prep(struct spi_device *spi, - struct davinci_spi *davinci_spi) -{ - int op_mode = 0; - /* - * Set up device-specific SPI configuration parameters. - * Most of these would normally be handled in spi_setup(), - * updating the per-chipselect FMT registers, but some of - * them use global controls like SPI_LOOP and SPI_READY. + * Set up SPIFMTn register, unique to this chipselect. + * + * NOTE: we could do all of these with one write. Also, some + * of the "version 2" features are found in chips that don't + * support all of them... */ - if (spi->mode & SPI_LSB_FIRST) set_fmt_bits(davinci_spi->base, SPIFMT_SHIFTDIR_MASK, spi->chip_select); @@ -247,6 +233,19 @@ static int davinci_spi_bufs_prep(struct clear_fmt_bits(davinci_spi->base, SPIFMT_PHASE_MASK, spi->chip_select); + /* + * Version 1 hardware supports two basic SPI modes: + * - Standard SPI mode uses 4 pins, with chipselect + * - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS) + * (distinct from SPI_3WIRE, with just one data wire; + * or similar variants without MOSI or without MISO) + * + * Version 2 hardware supports an optional handshaking signal, + * so it can support two more modes: + * - 5 pin SPI variant is standard SPI plus SPI_READY + * - 4 pin with enable is (SPI_READY | SPI_NO_CS) + */ + if (davinci_spi->version == SPI_VERSION_2) { clear_fmt_bits(davinci_spi->base, SPIFMT_WDELAY_MASK, spi->chip_select); @@ -293,33 +292,21 @@ static int davinci_spi_bufs_prep(struct spi->chip_select); } - /* Clock internal */ - if (davinci_spi->pdata->clk_internal) - set_io_bits(davinci_spi->base + SPIGCR1, - SPIGCR1_CLKMOD_MASK); - else - clear_io_bits(davinci_spi->base + SPIGCR1, - SPIGCR1_CLKMOD_MASK); + retval = davinci_spi_setup_transfer(spi, NULL); - /* master mode default */ - set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_MASTER_MASK); + return retval; +} - if (davinci_spi->pdata->intr_level) - iowrite32(SPI_INTLVL_1, davinci_spi->base + SPILVL); - else - iowrite32(SPI_INTLVL_0, davinci_spi->base + SPILVL); +static int davinci_spi_bufs_prep(struct spi_device *spi, + struct davinci_spi *davinci_spi) +{ + int op_mode = 0; /* - * Version 1 hardware supports two basic SPI modes: - * - Standard SPI mode uses 4 pins, with chipselect - * - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS) - * (distinct from SPI_3WIRE, with just one data wire; - * or similar variants without MOSI or without MISO) - * - * Version 2 hardware supports an optional handshaking signal, - * so it can support two more modes: - * - 5 pin SPI variant is standard SPI plus SPI_READY - * - 4 pin with enable is (SPI_READY | SPI_NO_CS) + * REVISIT unless devices disagree about SPI_LOOP or + * SPI_READY (SPI_NO_CS only allows one device!), this + * should not need to be done before each message... + * optimize for both flags staying cleared. */ op_mode = SPIPC0_DIFUN_MASK @@ -672,11 +659,27 @@ static int davinci_spi_probe(struct plat init_completion(&davinci_spi->done); - /* Reset In/OUT SPI modle */ + /* Reset In/OUT SPI module */ iowrite32(0, davinci_spi->base + SPIGCR0); udelay(100); iowrite32(1, davinci_spi->base + SPIGCR0); + /* Clock internal */ + if (davinci_spi->pdata->clk_internal) + set_io_bits(davinci_spi->base + SPIGCR1, + SPIGCR1_CLKMOD_MASK); + else + clear_io_bits(davinci_spi->base + SPIGCR1, + SPIGCR1_CLKMOD_MASK); + + /* master mode default */ + set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_MASTER_MASK); + + if (davinci_spi->pdata->intr_level) + iowrite32(SPI_INTLVL_1, davinci_spi->base + SPILVL); + else + iowrite32(SPI_INTLVL_0, davinci_spi->base + SPILVL); + ret = spi_bitbang_start(&davinci_spi->bitbang); if (ret != 0) goto free_clk;