From patchwork Tue Aug 24 10:40:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas tanure X-Patchwork-Id: 502088 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01CCAC432BE for ; Tue, 24 Aug 2021 10:41:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E318F60F11 for ; Tue, 24 Aug 2021 10:41:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236365AbhHXKls (ORCPT ); Tue, 24 Aug 2021 06:41:48 -0400 Received: from mx0b-001ae601.pphosted.com ([67.231.152.168]:27028 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236339AbhHXKlr (ORCPT ); Tue, 24 Aug 2021 06:41:47 -0400 Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 17O9oMhS012561; Tue, 24 Aug 2021 05:41:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=fuZSZI0E9hsp3UbqkpcQChizV3YjsSgucAX1LgLnmlk=; b=dV9JsRCmzgPMXCvQEtpqXzU92Lw5tPK45Xqqz/Gpv4OWo9zczZTH4STD+eWiRE5Ky+Uw cxEKlQz97IMi67CY7Fh3B3tQfvlztFsfaQ+ICQK1yLqaDau/gtWc01klDJtd1+FzMjcO DjpxyQmiuv48kd19Plcn/niOPZ3UoebfnRiKftdbsZ+8OvRFX2hn+y4SExaNSvdt8LSF Y6Zcdbj+8XUDHyFii/TFI8TdbWQTnLHhXnpWU9c0nsNH/hjZaQ2pirX942XdADG6h8qX VauVN4Cx4MF7pQjPBdb0sUzqLmTFl31O/vGoAfXRx6hBhEYEtnpiQzcoZGsVHazBFy6q 8Q== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3amxg601k1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Tue, 24 Aug 2021 05:41:00 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Tue, 24 Aug 2021 11:40:59 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.12 via Frontend Transport; Tue, 24 Aug 2021 11:40:59 +0100 Received: from aryzen.ad.cirrus.com (unknown [198.61.65.58]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 688622A9; Tue, 24 Aug 2021 10:40:55 +0000 (UTC) From: Lucas Tanure To: Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Sanjay R Mehta , Nehal Bakulchandra Shah CC: , , , Lucas Tanure Subject: [PATCH 2/9] spi: core: Add flag for controllers that can't hold cs between transfers Date: Tue, 24 Aug 2021 11:40:34 +0100 Message-ID: <20210824104041.708945-3-tanureal@opensource.cirrus.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210824104041.708945-1-tanureal@opensource.cirrus.com> References: <20210824104041.708945-1-tanureal@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: mSnUtxGavguZ3TD4NprwGcOxygIMaVnV X-Proofpoint-ORIG-GUID: mSnUtxGavguZ3TD4NprwGcOxygIMaVnV X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Create a flag for a controller that has an automatic cs selection and can't hold cs activated between transfers Some messages send address and data split between two transfers, see regmap-spi, and without the cs held the data loses it`s meaning Signed-off-by: Lucas Tanure --- include/linux/spi/spi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 8371bca13729..f5b55c237634 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -514,6 +514,7 @@ struct spi_controller { #define SPI_CONTROLLER_MUST_TX BIT(4) /* requires tx */ #define SPI_MASTER_GPIO_SS BIT(5) /* GPIO CS must select slave */ +#define SPI_CONTROLLER_CS_PER_TRANSFER BIT(6) /* SPI controller can not hold CS between transfers */ /* flag indicating if the allocation of this struct is devres-managed */ bool devm_allocated; From patchwork Tue Aug 24 10:40:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas tanure X-Patchwork-Id: 502087 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AC6BCC4320A for ; Tue, 24 Aug 2021 10:41:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 959E861262 for ; Tue, 24 Aug 2021 10:41:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236373AbhHXKlu (ORCPT ); Tue, 24 Aug 2021 06:41:50 -0400 Received: from mx0a-001ae601.pphosted.com ([67.231.149.25]:36010 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S236379AbhHXKls (ORCPT ); Tue, 24 Aug 2021 06:41:48 -0400 Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 17OA050R016652; Tue, 24 Aug 2021 05:41:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=wmJd13U/MiNXR0MpF3vqHT3p3GrmbatpUhQguV8vWF8=; b=ovOIWCkxW7yRmTHDYJc5kamF/EeyASI8hn+fQrRPmDZDP1y/X25XsTOpCHLaLqX+bVaA ixOO6cb+Fj9Ii5YxeEzEUxmWhGaolfFytfO8HCaia0S83GSxuOJWtOpDJ4BauV4P+3U9 Q8yz7UfC/H/JMs0uwMIMX8Kog/wmuP5TwxYxKMowiEggh4vjNJccg4KnCE8vGKVhbpE/ We51CI3UGaH2iZ5z/IfbbCFICRM9/bqSefbMdyd+/awvmR/LxEwNcbdG09+disygX4B7 yomFbZtTWchXG09FqEKeYuOF4UXytCyTNHRbpVhtqcvZxD663UeTG5wIOasnCF7ZvWJJ dQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3amjmq8wmh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Tue, 24 Aug 2021 05:41:01 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Tue, 24 Aug 2021 11:40:59 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.12 via Frontend Transport; Tue, 24 Aug 2021 11:40:59 +0100 Received: from aryzen.ad.cirrus.com (unknown [198.61.65.58]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 431BC2BA; Tue, 24 Aug 2021 10:40:59 +0000 (UTC) From: Lucas Tanure To: Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Sanjay R Mehta , Nehal Bakulchandra Shah CC: , , , Lucas Tanure Subject: [PATCH 3/9] regmap: spi: SPI_CONTROLLER_CS_PER_TRANSFER affects max read/write Date: Tue, 24 Aug 2021 11:40:35 +0100 Message-ID: <20210824104041.708945-4-tanureal@opensource.cirrus.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210824104041.708945-1-tanureal@opensource.cirrus.com> References: <20210824104041.708945-1-tanureal@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: pxnmr8H-9zsF7uLpZWYAKrXmKDKXbhu7 X-Proofpoint-GUID: pxnmr8H-9zsF7uLpZWYAKrXmKDKXbhu7 X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org regmap-spi will split data and address between two transfers in the same message so use addr_affects_max_raw_rw to flag that the number bytes to read or write should be a little less (address + padding size), so that the SPI controller can merge the entire message into a single CS period Signed-off-by: Lucas Tanure --- drivers/base/regmap/regmap-spi.c | 14 ++++++++++++-- drivers/base/regmap/regmap.c | 9 +++++++++ include/linux/regmap.h | 2 ++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 603a4c1c2066..0c1f2e51c0c7 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c @@ -115,12 +115,22 @@ static const struct regmap_bus *regmap_get_spi_bus(struct spi_device *spi, struct spi_master *master = spi->master; struct regmap_bus *bus = NULL; - if (master->max_transfer_size) { + if (master->max_transfer_size || (master->flags & SPI_CONTROLLER_CS_PER_TRANSFER)) { bus = kmemdup(®map_spi, sizeof(*bus), GFP_KERNEL); if (!bus) return ERR_PTR(-ENOMEM); bus->free_on_exit = true; - bus->max_raw_read = bus->max_raw_write = master->max_transfer_size(spi); + + /* regmap-spi will split data and address between two transfers in the same message + * so use addr_affects_max_raw_rw to flag that the number bytes to read or write + * should be a little less (address + padding size), so the controller can + * fit both transfers in a single CS period + */ + bus->addr_affects_max_raw_rw = master->flags & SPI_CONTROLLER_CS_PER_TRANSFER; + + if (master->max_transfer_size) + bus->max_raw_read = bus->max_raw_write = master->max_transfer_size(spi); + return bus; } diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 6ad41d0720ba..31d0949b6c2f 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -815,6 +815,15 @@ struct regmap *__regmap_init(struct device *dev, if (bus) { map->max_raw_read = bus->max_raw_read; map->max_raw_write = bus->max_raw_write; + if (bus->addr_affects_max_raw_rw) { + if (map->max_raw_read < map->format.buf_size || + map->max_raw_write < map->format.buf_size) { + ret = -EINVAL; + goto err_name; + } + map->max_raw_read -= (map->format.reg_bytes + map->format.pad_bytes); + map->max_raw_write -= (map->format.reg_bytes + map->format.pad_bytes); + } } map->dev = dev; map->bus = bus; diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 77755196277c..a90d1e270b1f 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -504,6 +504,7 @@ typedef void (*regmap_hw_free_context)(void *context); * @max_raw_read: Max raw read size that can be used on the bus. * @max_raw_write: Max raw write size that can be used on the bus. * @free_on_exit: kfree this on exit of regmap + * @addr_affects_max_raw_rw: max_raw_[read|write] must include the address and padding preamble */ struct regmap_bus { bool fast_io; @@ -522,6 +523,7 @@ struct regmap_bus { size_t max_raw_read; size_t max_raw_write; bool free_on_exit; + bool addr_affects_max_raw_rw; }; /* From patchwork Tue Aug 24 10:40:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas tanure X-Patchwork-Id: 502086 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4027CC4320E for ; Tue, 24 Aug 2021 10:41:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 21ADF61262 for ; Tue, 24 Aug 2021 10:41:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236359AbhHXKlv (ORCPT ); Tue, 24 Aug 2021 06:41:51 -0400 Received: from mx0b-001ae601.pphosted.com ([67.231.152.168]:59432 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236388AbhHXKlt (ORCPT ); Tue, 24 Aug 2021 06:41:49 -0400 Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 17O9oMhU012561; Tue, 24 Aug 2021 05:41:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=Y1dzi87RQSLOVgc1XSY6AIdI/7WVI0LjnVnxGx7qTbo=; b=d9MB0pdnOlz72yZbtV5+qLWlb1Cdu51SBr5bTq6VSTQUxcVI92l9cSUbWYSCYuaKguaP WjOTLHk87twmjlKIfd4E+X5VgTbrKiCYMUXCnvqBKDAT3wlZNcMhct9245Zi6xNhh827 xuBCPRkyd2DeQFR/bd2xSVo926UtLjyxADo9EAYejT/d5T/lIVtEdjHyk1kc17CkSsMA RvTYUjYvvkgDc/qMBg+Ya9RmB85mmtTEfPkaRlE2qSxMqIayH8U/njchntu4ie8o2DYf tPyzbhO+a3Dwu1+9B0MGc5GajR0sEiL/pHW7bxp8BnE3gD3eqMhnvjIEqxzyoekulk3q ig== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3amxg601k1-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Tue, 24 Aug 2021 05:41:01 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Tue, 24 Aug 2021 11:41:00 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.12 via Frontend Transport; Tue, 24 Aug 2021 11:41:00 +0100 Received: from aryzen.ad.cirrus.com (unknown [198.61.65.58]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 1AC082A9; Tue, 24 Aug 2021 10:41:00 +0000 (UTC) From: Lucas Tanure To: Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Sanjay R Mehta , Nehal Bakulchandra Shah CC: , , , Lucas Tanure Subject: [PATCH 6/9] spi: amd: Remove uneeded variable Date: Tue, 24 Aug 2021 11:40:38 +0100 Message-ID: <20210824104041.708945-7-tanureal@opensource.cirrus.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210824104041.708945-1-tanureal@opensource.cirrus.com> References: <20210824104041.708945-1-tanureal@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: MrbsGSsAFNFFq7jPDiZPQknEJAAaDpae X-Proofpoint-ORIG-GUID: MrbsGSsAFNFFq7jPDiZPQknEJAAaDpae X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Remove internal cs from amd_spi Signed-off-by: Lucas Tanure --- drivers/spi/spi-amd.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c index 9476b283840b..ebbc64a9fa7b 100644 --- a/drivers/spi/spi-amd.c +++ b/drivers/spi/spi-amd.c @@ -39,7 +39,6 @@ struct amd_spi { void __iomem *io_remap_addr; unsigned long io_base_addr; u32 rom_addr; - u8 chip_select; }; static inline u8 amd_spi_readreg8(struct amd_spi *amd_spi, int idx) @@ -78,10 +77,9 @@ static inline void amd_spi_setclear_reg32(struct amd_spi *amd_spi, int idx, u32 amd_spi_writereg32(amd_spi, idx, tmp); } -static void amd_spi_select_chip(struct amd_spi *amd_spi) +static void amd_spi_select_chip(struct amd_spi *amd_spi, u8 cs) { - amd_spi_setclear_reg8(amd_spi, AMD_SPI_ALT_CS_REG, amd_spi->chip_select, - AMD_SPI_ALT_CS_MASK); + amd_spi_setclear_reg8(amd_spi, AMD_SPI_ALT_CS_REG, cs, AMD_SPI_ALT_CS_MASK); } static void amd_spi_clear_fifo_ptr(struct amd_spi *amd_spi) @@ -196,8 +194,7 @@ static int amd_spi_master_transfer(struct spi_master *master, struct amd_spi *amd_spi = spi_master_get_devdata(master); struct spi_device *spi = msg->spi; - amd_spi->chip_select = spi->chip_select; - amd_spi_select_chip(amd_spi); + amd_spi_select_chip(amd_spi, spi->chip_select); /* * Extract spi_transfers from the spi message and From patchwork Tue Aug 24 10:40:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas tanure X-Patchwork-Id: 502085 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D105AC4320A for ; Tue, 24 Aug 2021 10:41:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B86BE61262 for ; Tue, 24 Aug 2021 10:41:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236455AbhHXKlx (ORCPT ); Tue, 24 Aug 2021 06:41:53 -0400 Received: from mx0a-001ae601.pphosted.com ([67.231.149.25]:23220 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S236398AbhHXKlu (ORCPT ); Tue, 24 Aug 2021 06:41:50 -0400 Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 17OA050T016652; Tue, 24 Aug 2021 05:41:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=bXPtQd8HEeyWR8X7GQzCqp25D8O8/msbik0SSpewS80=; b=eGSahquyMF4truea7sizxDcPXaCHGOTalqZxVraZgk8XwkpB7Sa8NFw09KmxP6QHA8lr UKZEwjfDltbBLTQznW5UH6TWSvxmJNLSHluxnrfVNU8DhfCl9I0LZpF7ZqefyJqv5fXW BTnekxDkJ2RvJ8jd17qcvXyenWTLiAjgSHgByEeeOhfqsMIiuFNvg4QioTT5U0NvBADX Zs7uOzrMJdcd9NoqWzJaxvYhRfe5hATFca8qZvumX33QCidvhXMWlQvyHmhTm38rxKbc 0Cn/inLB7FVC5F3ObFrzSg9PwK05ycJ7+WgjbFNkQDsbSCSNQdSZEKcF1iM6wrQk3Umm cw== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3amjmq8wmh-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Tue, 24 Aug 2021 05:41:03 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Tue, 24 Aug 2021 11:41:00 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.12 via Frontend Transport; Tue, 24 Aug 2021 11:41:00 +0100 Received: from aryzen.ad.cirrus.com (unknown [198.61.65.58]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id A5E262A9; Tue, 24 Aug 2021 10:41:00 +0000 (UTC) From: Lucas Tanure To: Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Sanjay R Mehta , Nehal Bakulchandra Shah CC: , , , Lucas Tanure Subject: [PATCH 8/9] spi: amd: Refactor to overcome 70 bytes per CS limitation Date: Tue, 24 Aug 2021 11:40:40 +0100 Message-ID: <20210824104041.708945-9-tanureal@opensource.cirrus.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210824104041.708945-1-tanureal@opensource.cirrus.com> References: <20210824104041.708945-1-tanureal@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: epGmpNXcnVKqNZ3X9hehhtdArML38hDr X-Proofpoint-GUID: epGmpNXcnVKqNZ3X9hehhtdArML38hDr X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org AMD SPI controller has 70 bytes for its FIFO and it has an automatic way of controlling it`s internal CS, which can only be activated during the time that the FIFO is being transfered. SPI_MASTER_HALF_DUPLEX here means that it can only read RX bytes after TX bytes were written, and RX+TX must be less than 70. If you write 4 bytes the first byte of read is in position 5 of the FIFO. All of that means that for devices that require an address for reads and writes, the 2 transfers must be put in the same FIFO so the CS can be hold for address and data, otherwise the data would lose it`s meaning. Signed-off-by: Lucas Tanure --- drivers/spi/spi-amd.c | 208 ++++++++++++++++++++++++++++-------------- 1 file changed, 140 insertions(+), 68 deletions(-) diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c index 75390fcb0481..b6308733265e 100644 --- a/drivers/spi/spi-amd.c +++ b/drivers/spi/spi-amd.c @@ -4,7 +4,8 @@ // // Copyright (c) 2020, Advanced Micro Devices, Inc. // -// Author: Sanjay R Mehta +// Authors: Sanjay R Mehta +// Lucas Tanure #include #include @@ -29,6 +30,7 @@ #define AMD_SPI_RX_COUNT_REG 0x4B #define AMD_SPI_STATUS_REG 0x4C +#define AMD_SPI_FIFO_SIZE 70 #define AMD_SPI_MEM_SIZE 200 /* M_CMD OP codes for SPI */ @@ -132,83 +134,152 @@ static int amd_spi_master_setup(struct spi_device *spi) return 0; } -static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, - struct spi_master *master, - struct spi_message *message) +static int amd_spi_double_write(struct spi_master *mst, u8 *tx1_buf, u8 tx1_len, u8 *tx2_buf, + u8 tx2_len) { - struct spi_transfer *xfer = NULL; - u8 cmd_opcode; - u8 *buf = NULL; - u32 m_cmd = 0; - u32 i = 0; - u32 tx_len = 0, rx_len = 0; - - list_for_each_entry(xfer, &message->transfers, - transfer_list) { - if (xfer->rx_buf) - m_cmd = AMD_SPI_XFER_RX; - if (xfer->tx_buf) - m_cmd = AMD_SPI_XFER_TX; - - if (m_cmd & AMD_SPI_XFER_TX) { - buf = (u8 *)xfer->tx_buf; - tx_len = xfer->len - 1; - cmd_opcode = *(u8 *)xfer->tx_buf; - buf++; - amd_spi_set_opcode(amd_spi, cmd_opcode); - - /* Write data into the FIFO. */ - for (i = 0; i < tx_len; i++) { - iowrite8(buf[i], ((u8 __iomem *)amd_spi->io_remap_addr + - AMD_SPI_FIFO_BASE + i)); - } + struct amd_spi *amd_spi = spi_master_get_devdata(mst); + int i, ret; - amd_spi_set_tx_count(amd_spi, tx_len); - amd_spi_clear_fifo_ptr(amd_spi); - /* Execute command */ - amd_spi_execute_opcode(amd_spi); - } - if (m_cmd & AMD_SPI_XFER_RX) { - /* - * Store no. of bytes to be received from - * FIFO - */ - rx_len = xfer->len; - buf = (u8 *)xfer->rx_buf; - amd_spi_set_rx_count(amd_spi, rx_len); - amd_spi_clear_fifo_ptr(amd_spi); - /* Execute command */ - amd_spi_execute_opcode(amd_spi); - /* Read data from FIFO to receive buffer */ - for (i = 0; i < rx_len; i++) - buf[i] = amd_spi_readreg8(amd_spi, AMD_SPI_FIFO_BASE + tx_len + i); - } - } + if (tx1_len + tx2_len > AMD_SPI_FIFO_SIZE) + return -EINVAL; - /* Update statistics */ - message->actual_length = tx_len + rx_len + 1; - /* complete the transaction */ - message->status = 0; - spi_finalize_current_message(master); + amd_spi_clear_fifo_ptr(amd_spi); + amd_spi_set_rx_count(amd_spi, 0); - return 0; + amd_spi_set_opcode(amd_spi, tx1_buf[0]); + tx1_len--; + tx1_buf++; + + for (i = 0; i < tx1_len; i++) + amd_spi_writereg8(amd_spi, (u8)(AMD_SPI_FIFO_BASE + i), tx1_buf[i]); + + for (i = 0; i < tx2_len; i++) + amd_spi_writereg8(amd_spi, (u8)(AMD_SPI_FIFO_BASE + tx1_len + i), tx2_buf[i]); + + amd_spi_set_tx_count(amd_spi, tx1_len + tx2_len); + ret = amd_spi_execute_opcode(amd_spi); + + return ret ? ret : tx1_len + 1 + tx2_len; } -static int amd_spi_master_transfer(struct spi_master *master, - struct spi_message *msg) +static int amd_spi_write_read(struct spi_master *mst, u8 *tx_buf, u8 tx_len, u8 *rx_buf, u8 rx_len) { - struct amd_spi *amd_spi = spi_master_get_devdata(master); - struct spi_device *spi = msg->spi; + struct amd_spi *amd_spi = spi_master_get_devdata(mst); + int i, ret; + + if (tx_len + rx_len > AMD_SPI_FIFO_SIZE) + return -EINVAL; + + amd_spi_clear_fifo_ptr(amd_spi); + + if (tx_buf) { + /* Take the first byte to be written and set as opcode */ + amd_spi_set_opcode(amd_spi, tx_buf[0]); + /* Set TX count as the number of bytes to be written less one (opcode byte) */ + tx_len--; + tx_buf++; - amd_spi_select_chip(amd_spi, spi->chip_select); + /* Copy to the FIFO the remaining bytes */ + for (i = 0; i < tx_len; i++) + amd_spi_writereg8(amd_spi, (AMD_SPI_FIFO_BASE + i), tx_buf[i]); - /* - * Extract spi_transfers from the spi message and - * program the controller. + amd_spi_set_tx_count(amd_spi, tx_len); + } + /* Set RX count as the number of bytes that will be read AFTER the TX bytes are sent + * Or set to zero to avoid extra bytes after the write cycle */ - amd_spi_fifo_xfer(amd_spi, master, msg); + amd_spi_set_rx_count(amd_spi, rx_buf ? rx_len : 0); - return 0; + /* Trigger the transfer by executing the opcode */ + ret = amd_spi_execute_opcode(amd_spi); + if (ret) + return ret; + + /* Wait for the SPI bus to be idle and copy the RX bytes from the FIFO from the starting + * position of TX bytes + */ + if (rx_buf) { + for (i = 0; i < rx_len; i++) + rx_buf[i] = amd_spi_readreg8(amd_spi, AMD_SPI_FIFO_BASE + tx_len + i); + } + + return tx_len + 1 + rx_len; +} + +/* amd_spi_master_transfer expects a spi_message with one or two transfers only + * Where a message with one transfer is a single write or read to a device + * And a message with two transfer is an address write followed by a read or + * write data into that address + */ +static int amd_spi_master_transfer(struct spi_master *mst, struct spi_message *msg) +{ + struct amd_spi *amd_spi = spi_master_get_devdata(mst); + struct spi_transfer *xfer, *xfer_n; + struct list_head *pos; + int ret, count = 0; + + list_for_each(pos, &msg->transfers) + count++; + + amd_spi_select_chip(amd_spi, msg->spi->chip_select); + + xfer = list_first_entry(&msg->transfers, struct spi_transfer, transfer_list); + switch (count) { + case 1: + /* This controller can't write and read simultaneously + * It can only write data first and read afterwards + */ + if (xfer->tx_buf && xfer->rx_buf) { + ret = -EINVAL; + dev_err(&mst->dev, "Error. Can't write and read simultaneously\n"); + goto complete; + } + + ret = amd_spi_write_read(mst, (u8 *)xfer->tx_buf, xfer->len, + (u8 *)xfer->rx_buf, xfer->len); + if (ret < 0) + goto complete; + break; + case 2: + xfer_n = list_last_entry(&msg->transfers, struct spi_transfer, transfer_list); + if (xfer->tx_buf && !xfer->rx_buf) { + if (xfer_n->rx_buf && !xfer_n->tx_buf) { + ret = amd_spi_write_read(mst, (u8 *)xfer->tx_buf, xfer->len, + (u8 *)xfer_n->rx_buf, xfer_n->len); + if (ret < 0) + goto complete; + break; + } else if (xfer_n->tx_buf && !xfer_n->rx_buf) { + ret = amd_spi_double_write(mst, (u8 *)xfer->tx_buf, xfer->len, + (u8 *)xfer_n->tx_buf, xfer_n->len); + if (ret < 0) + goto complete; + break; + } + } + ret = -EINVAL; + dev_err(&mst->dev, "Error. Message not supported\n"); + goto complete; + default: + ret = -EINVAL; + dev_err(&mst->dev, "Message with %d transfers is not supported\n", count); + goto complete; + } + + msg->actual_length += ret; + ret = 0; + +complete: + /* complete the transaction */ + msg->status = ret; + spi_finalize_current_message(mst); + + return ret; +} + +static size_t amd_spi_max_transfer_size(struct spi_device *spi) +{ + return AMD_SPI_FIFO_SIZE; } static int amd_spi_probe(struct platform_device *pdev) @@ -238,8 +309,9 @@ static int amd_spi_probe(struct platform_device *pdev) master->bus_num = 0; master->num_chipselect = 4; master->mode_bits = 0; - master->flags = SPI_MASTER_HALF_DUPLEX; + master->flags = SPI_MASTER_HALF_DUPLEX | SPI_CONTROLLER_CS_PER_TRANSFER; master->setup = amd_spi_master_setup; + master->max_transfer_size = amd_spi_max_transfer_size; master->transfer_one_message = amd_spi_master_transfer; /* Register the controller with SPI framework */