From patchwork Sat Apr 13 18:24:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 10899597 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 083AB1515 for ; Sat, 13 Apr 2019 18:25:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DE757285A7 for ; Sat, 13 Apr 2019 18:25:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D278628678; Sat, 13 Apr 2019 18:25:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7B3B2285A7 for ; Sat, 13 Apr 2019 18:25:15 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 54E5B89236; Sat, 13 Apr 2019 18:25:11 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4746789233 for ; Sat, 13 Apr 2019 18:25:08 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:48766 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84_2) (envelope-from ) id 1hFNKs-0005SF-CK; Sat, 13 Apr 2019 20:25:06 +0200 From: =?utf-8?q?Noralf_Tr=C3=B8nnes?= To: linux-spi@vger.kernel.org, dri-devel@lists.freedesktop.org Subject: [PATCH v5 3/4] spi/spi-bcm2835: Split transfers that exceed DLEN Date: Sat, 13 Apr 2019 20:24:14 +0200 Message-Id: <20190413182415.38543-4-noralf@tronnes.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190413182415.38543-1-noralf@tronnes.org> References: <20190413182415.38543-1-noralf@tronnes.org> MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tronnes.org; s=ds201810; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=1IjeNE+wWOLYmHhetqSE10NJZ4ye+fVTyppJIIbyng8=; b=Bqx2tPJoJNO8x9sHpRQvq6xCHxUG4JtV96erM6Auf2hDIFPF8am4KjY66q9ro8IooWgCpvVEKXI6Z3OgO+PA3jK3cWwJ8M1k6z+iT/ZfZe+lA6+8CdyUW2vflw6iZAOzGb7gWTN/7QZGlfkqQMlIiwv/w+dH/qsVP0tsp66kkExr9tK2Vs9/OB0uKjlVyQc0CekO3rg3FHHPcmvlpGMBJa+Ief1sAmHuJuk1tSWV+rhakShuMbP9MgZMTYdR3vyA+0wUz85NuB/MQOnJl9JbnE7015G+gPC2FhsCLurg0jsDiFWsFB1b6vbab5JEIhBGXeox4IzVMTCQlDAnF/S3kg==; X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: stefan.wahren@i2se.com, broonie@kernel.org, linux-rpi-kernel@lists.infradead.org, meghana.madhyastha@gmail.com, kernel@martin.sperl.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Meghana Madhyastha Split spi transfers into chunks of <=65532 to enable the driver to perform DMA transfer on big buffers. The DLEN register specifies the number of bytes to transfer in DMA mode. It is 16-bit wide and thus the maximum DMA transfer is 65535 bytes. Set the maximum to 65532 (4 byte aligned) since the FIFO in DMA mode is accessed in 4 byte chunks. ->max_dma_len is the value the spi core uses when splitting the buffer into scatter gather entries. The BCM2835 DMA block has 2 types of channels/engines: - Normal: Max length: 1G - Lite: Max length: 65535 Even when using a Lite channel we will not exceed the max length, so let's drop setting ->max_dma_len. Signed-off-by: Meghana Madhyastha Signed-off-by: Noralf Trønnes Reviewed-by: Lukas Wunner --- drivers/spi/spi-bcm2835.c | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 35aebdfd3b4e..8aa22713c483 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -335,20 +335,6 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master, return 1; } -/* - * DMA support - * - * this implementation has currently a few issues in so far as it does - * not work arrount limitations of the HW. - * - * the main one being that DMA transfers are limited to 16 bit - * (so 0 to 65535 bytes) by the SPI HW due to BCM2835_SPI_DLEN - * - * there may be a few more border-cases we may need to address as well - * but unfortunately this would mean splitting up the scatter-gather - * list making it slightly unpractical... - */ - /** * bcm2835_spi_transfer_prologue() - transfer first few bytes without DMA * @master: SPI master @@ -630,19 +616,6 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, if (tfr->len < BCM2835_SPI_DMA_MIN_LENGTH) return false; - /* BCM2835_SPI_DLEN has defined a max transfer size as - * 16 bit, so max is 65535 - * we can revisit this by using an alternative transfer - * method - ideally this would get done without any more - * interaction... - */ - if (tfr->len > 65535) { - dev_warn_once(&spi->dev, - "transfer size of %d too big for dma-transfer\n", - tfr->len); - return false; - } - /* return OK */ return true; } @@ -707,7 +680,6 @@ static void bcm2835_dma_init(struct spi_master *master, struct device *dev) /* all went well, so set can_dma */ master->can_dma = bcm2835_spi_can_dma; - master->max_dma_len = 65535; /* limitation by BCM2835_SPI_DLEN */ /* need to do TX AND RX DMA, so we need dummy buffers */ master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; @@ -844,6 +816,17 @@ static int bcm2835_spi_prepare_message(struct spi_master *master, struct spi_device *spi = msg->spi; struct bcm2835_spi *bs = spi_master_get_devdata(master); u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); + int ret; + + /* + * DMA transfers are limited to 16 bit (0 to 65535 bytes) by the SPI HW + * due to DLEN. Split up transfers (32-bit FIFO aligned) if the limit is + * exceeded. + */ + ret = spi_split_transfers_maxsize(master, msg, 65532, + GFP_KERNEL | GFP_DMA); + if (ret) + return ret; cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA);