From patchwork Mon Apr 18 12:39:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 8872021 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5C2B9BF29F for ; Mon, 18 Apr 2016 12:39:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C2AF62034B for ; Mon, 18 Apr 2016 12:39:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9D99020220 for ; Mon, 18 Apr 2016 12:39:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751892AbcDRMjk (ORCPT ); Mon, 18 Apr 2016 08:39:40 -0400 Received: from mail-lf0-f43.google.com ([209.85.215.43]:35856 "EHLO mail-lf0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751780AbcDRMjj (ORCPT ); Mon, 18 Apr 2016 08:39:39 -0400 Received: by mail-lf0-f43.google.com with SMTP id g184so214852533lfb.3; Mon, 18 Apr 2016 05:39:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=r7TI+l30JyAV7Py6tn+nzyeb9QPzCNzDcNUVFXMqAyE=; b=Zgbjg2DSl5gtbywPVdx8qSB0XYn0G+Tkz0KlUtiw11Zp1IkI2DuXZmmbF00BSrecgL ZXZkizIivnEeFBcnOD0uHRMNfzrgqKTRpyLG4uDFgPYJOCr7rVIXkQVmlG6p0kjPFGJO I2C2C4IUM8l23IQP2fUG+izwuZ4ncmDu9Tmn9LCvl8c46pG+fCGysoRGt3q4Dqn+TAph J/UmjfJ3coDIl8GWR3BytxPKvxsOWB2G9G0AD+xaIC5DnlL+/NGnpScfdmlD9Javwd2p FJpoTabBm4w/tJuFChuBmkVX0wTk4BxW38xgw5jrqH1qaTwvVYSnega/sM8P7UZ0crv4 6hpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=r7TI+l30JyAV7Py6tn+nzyeb9QPzCNzDcNUVFXMqAyE=; b=XtENjFEewRc71b25tHaVvrL1zmQ2qryPiiPvZCEdyZ2JTjS6d6AUvfYhqUQ4roPmFy 6Nl5hUMTj+j6T+29TMCh72K9kCh3Z20+wjl3TgxB/kYZTp5JkZ/UzRvojtJ8Ev7iJnS1 p0al/9JxJejBKhYfNaSOTnO7RD7i8PuxiC7PBANB8u4OK5KMPxaZwZcr8xRUOfTy+PC3 TirGN7C6NNK6HzJrHR6hG+qCs7P+aCLDEl8w4kBr2BIh6keAj3hzBpm8yOVSLhiETPHh cIxKFcw+T9wbu59x26PdbP1K1LjS58GTlJndf3/VymUUvRGUYevx/HXBCvryJa8VoIrg ZtfA== X-Gm-Message-State: AOPr4FWP81ljn44Hynp/KmEdjusmZDoERFdNCm3W2CHigSiFUbHVeavayMy0K7ENoeju9w== X-Received: by 10.112.124.197 with SMTP id mk5mr1474906lbb.60.1460983177509; Mon, 18 Apr 2016 05:39:37 -0700 (PDT) Received: from linux-samsung.lan (ip-194-187-74-233.konfederacka.maverick.com.pl. [194.187.74.233]) by smtp.gmail.com with ESMTPSA id b195sm10407015lfb.5.2016.04.18.05.39.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Apr 2016 05:39:36 -0700 (PDT) From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= To: Mark Brown Cc: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= , linux-spi@vger.kernel.org (open list:SPI SUBSYSTEM), linux-kernel@vger.kernel.org (open list) Subject: [PATCH V2 for-next] spi: bcm53xx: add spi_flash_read callback for MMIO-based reads Date: Mon, 18 Apr 2016 14:39:30 +0200 Message-Id: <1460983170-7390-1-git-send-email-zajec5@gmail.com> X-Mailer: git-send-email 1.8.4.5 In-Reply-To: <1460977843-9426-1-git-send-email-zajec5@gmail.com> References: <1460977843-9426-1-git-send-email-zajec5@gmail.com> MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This implements more efficient reads of SPI-attached flash content. Signed-off-by: Rafa? Mi?ecki --- V2: Add BCM53XXSPI_FLASH_WINDOW and check it in bcm53xxspi_flash_read. --- drivers/spi/spi-bcm53xx.c | 78 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-bcm53xx.c b/drivers/spi/spi-bcm53xx.c index cc3f938..afb5169 100644 --- a/drivers/spi/spi-bcm53xx.c +++ b/drivers/spi/spi-bcm53xx.c @@ -10,6 +10,7 @@ #include "spi-bcm53xx.h" #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */ +#define BCM53XXSPI_FLASH_WINDOW SZ_32M /* The longest observed required wait was 19 ms */ #define BCM53XXSPI_SPE_TIMEOUT_MS 80 @@ -17,8 +18,10 @@ struct bcm53xxspi { struct bcma_device *core; struct spi_master *master; + void __iomem *mmio_base; size_t read_offset; + bool bspi; /* Boot SPI mode with memory mapping */ }; static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset) @@ -32,6 +35,50 @@ static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset, bcma_write32(b53spi->core, offset, value); } +static void bcm53xxspi_disable_bspi(struct bcm53xxspi *b53spi) +{ + struct device *dev = &b53spi->core->dev; + unsigned long deadline; + u32 tmp; + + if (!b53spi->bspi) + return; + + tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL); + if (tmp & 0x1) + return; + + deadline = jiffies + usecs_to_jiffies(200); + do { + tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_BUSY_STATUS); + if (!(tmp & 0x1)) { + bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, + 0x1); + ndelay(200); + b53spi->bspi = false; + return; + } + udelay(1); + } while (!time_after_eq(jiffies, deadline)); + + dev_warn(dev, "Timeout disabling BSPI\n"); +} + +static void bcm53xxspi_enable_bspi(struct bcm53xxspi *b53spi) +{ + u32 tmp; + + if (b53spi->bspi) + return; + + tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL); + if (!(tmp & 0x1)) + return; + + bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x0); + b53spi->bspi = true; +} + static inline unsigned int bcm53xxspi_calc_timeout(size_t len) { /* Do some magic calculation based on length and buad. Add 10% and 1. */ @@ -176,6 +223,8 @@ static int bcm53xxspi_transfer_one(struct spi_master *master, u8 *buf; size_t left; + bcm53xxspi_disable_bspi(b53spi); + if (t->tx_buf) { buf = (u8 *)t->tx_buf; left = t->len; @@ -206,6 +255,22 @@ static int bcm53xxspi_transfer_one(struct spi_master *master, return 0; } +static int bcm53xxspi_flash_read(struct spi_device *spi, + struct spi_flash_read_message *msg) +{ + struct bcm53xxspi *b53spi = spi_master_get_devdata(spi->master); + int ret = 0; + + if (msg->from + msg->len > BCM53XXSPI_FLASH_WINDOW) + return -EINVAL; + + bcm53xxspi_enable_bspi(b53spi); + memcpy_fromio(msg->buf, b53spi->mmio_base + msg->from, msg->len); + msg->retlen = msg->len; + + return ret; +} + /************************************************** * BCMA **************************************************/ @@ -222,6 +287,7 @@ MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl); static int bcm53xxspi_bcma_probe(struct bcma_device *core) { + struct device *dev = &core->dev; struct bcm53xxspi *b53spi; struct spi_master *master; int err; @@ -231,7 +297,7 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) return -ENOTSUPP; } - master = spi_alloc_master(&core->dev, sizeof(*b53spi)); + master = spi_alloc_master(dev, sizeof(*b53spi)); if (!master) return -ENOMEM; @@ -239,11 +305,19 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) b53spi->master = master; b53spi->core = core; + if (core->addr_s[0]) + b53spi->mmio_base = devm_ioremap(dev, core->addr_s[0], + BCM53XXSPI_FLASH_WINDOW); + b53spi->bspi = true; + bcm53xxspi_disable_bspi(b53spi); + master->transfer_one = bcm53xxspi_transfer_one; + if (b53spi->mmio_base) + master->spi_flash_read = bcm53xxspi_flash_read; bcma_set_drvdata(core, b53spi); - err = devm_spi_register_master(&core->dev, master); + err = devm_spi_register_master(dev, master); if (err) { spi_master_put(master); bcma_set_drvdata(core, NULL);