Message ID | 20230715010407.1751715-8-fabrizio.castro.jz@renesas.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a6b2:0:b0:3e4:2afc:c1 with SMTP id c18csp2836800vqm; Fri, 14 Jul 2023 19:48:15 -0700 (PDT) X-Google-Smtp-Source: APBJJlGnETKX3czNz6KDBhQ2oA1IdENiHTgunbzyWWMJmc2INv1Tpu2PsJM+9wHVr/hD55wtQLxl X-Received: by 2002:a2e:924b:0:b0:2b6:d326:156d with SMTP id v11-20020a2e924b000000b002b6d326156dmr5059959ljg.19.1689389294767; Fri, 14 Jul 2023 19:48:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689389294; cv=none; d=google.com; s=arc-20160816; b=t3ll+hgo7Dt5nY1ez/qxUXBeIM80rh3pFlH4Y6wLdcQTKpJBDEgIuasW2dGNFhhUs0 mcnLqT4MCZHothqBmTvGY1lLvgO97S1VOf0/5xyAWB0F5ctHShjU/7MMYyRz7p7fqSNs NtbQSTH2t2/LVdKxVXZpn11rrjMyAE1wvx2yKrJG2L2yG3GKiivMMHwD5BQzdu298NOl o0SAcrcUPKRwl0WnKEp7gPDiTuY/inWEP4bP8vGU0eOf7qEbsvv1N9gFcELpd3q7DVWb Kv2KP6KpCVNEQPRqI9Z3EF85nOK8xDkBr7STKek4rCSD9NwM8ya7LlNNHHSuL3opRXB6 bqGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=oAk6hkdrBV9Bb/0GZTDXw88LMyiPxlb3FRPWnynrxl4=; fh=8SPOXdXcsbbrdLjCtKFrhdDDaSSTCLFzjvpt84tri9w=; b=YFPxvmYEClEfdX7hiDGSrV8R6sh8q1OsCarJFKbVilYl8+UU01ISFvf1a/PBztXbHD sO7nGyfh8vt4U6VuwIreG6OhffCgV1OZHJmhEW5XiF5K9BSz3NDP0hGm1OTXhLzuMBJs Zbtn8TYunIbbuJ2OOwlm7BIlCfC1QF6rUa67j2g4kZEsP/mMju1QiEsnSohRfKBKx887 RZJB/9mSes0qIElWBbpf6MlDjKdd5lZBs5m2VYlaDXlcSRQZESGUZ2DtVijmLLQjgb1t tPxFKVdipX4PxRsFVlHJiW7+L4GyWvp7sjjloTJKmPgNupgVfxH8FBGD2q79faa9Mk/A pWrw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=renesas.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k11-20020aa7d8cb000000b0051df47ad1f0si4116533eds.659.2023.07.14.19.47.51; Fri, 14 Jul 2023 19:48:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=renesas.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229745AbjGOBFI (ORCPT <rfc822;hadasmailinglist@gmail.com> + 99 others); Fri, 14 Jul 2023 21:05:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229986AbjGOBE7 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 14 Jul 2023 21:04:59 -0400 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id A12933C18; Fri, 14 Jul 2023 18:04:40 -0700 (PDT) X-IronPort-AV: E=Sophos;i="6.01,206,1684767600"; d="scan'208";a="172657855" Received: from unknown (HELO relmlir6.idc.renesas.com) ([10.200.68.152]) by relmlie6.idc.renesas.com with ESMTP; 15 Jul 2023 10:04:40 +0900 Received: from mulinux.home (unknown [10.226.92.194]) by relmlir6.idc.renesas.com (Postfix) with ESMTP id 59A9C40C4DBE; Sat, 15 Jul 2023 10:04:37 +0900 (JST) From: Fabrizio Castro <fabrizio.castro.jz@renesas.com> To: Mark Brown <broonie@kernel.org>, Geert Uytterhoeven <geert+renesas@glider.be> Cc: Fabrizio Castro <fabrizio.castro.jz@renesas.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, Chris Paterson <Chris.Paterson2@renesas.com>, Biju Das <biju.das@bp.renesas.com>, Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>, linux-renesas-soc@vger.kernel.org Subject: [PATCH 07/10] spi: rzv2m-csi: Switch to using {read,write}s{b,w} Date: Sat, 15 Jul 2023 02:04:04 +0100 Message-Id: <20230715010407.1751715-8-fabrizio.castro.jz@renesas.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230715010407.1751715-1-fabrizio.castro.jz@renesas.com> References: <20230715010407.1751715-1-fabrizio.castro.jz@renesas.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771453069155482088 X-GMAIL-MSGID: 1771453069155482088 |
Series |
spi: rzv2m-csi: Code refactoring
|
|
Commit Message
Fabrizio Castro
July 15, 2023, 1:04 a.m. UTC
The RX/TX FIFOs implemented by the CSI IP are accessed by
repeatedly reading/writing the same memory address, and
therefore they are the ideal candidate for {read,write}s{b,w}.
The RZ/V2M CSI driver currently implements loops to fill up
the TX FIFO and empty the RX FIFO, differentiating between
8-bit and 16-bit word size.
Switch to using {read,write}s{b,w} to get rid of the bespoke
loops.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
---
drivers/spi/spi-rzv2m-csi.c | 42 +++++++++++++------------------------
1 file changed, 14 insertions(+), 28 deletions(-)
Comments
Hi Fabrizio, On Sat, Jul 15, 2023 at 3:04 AM Fabrizio Castro <fabrizio.castro.jz@renesas.com> wrote: > The RX/TX FIFOs implemented by the CSI IP are accessed by > repeatedly reading/writing the same memory address, and > therefore they are the ideal candidate for {read,write}s{b,w}. > The RZ/V2M CSI driver currently implements loops to fill up > the TX FIFO and empty the RX FIFO, differentiating between > 8-bit and 16-bit word size. > Switch to using {read,write}s{b,w} to get rid of the bespoke > loops. > > Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com> Thanks for your patch! > --- a/drivers/spi/spi-rzv2m-csi.c > +++ b/drivers/spi/spi-rzv2m-csi.c > @@ -157,22 +157,15 @@ static int rzv2m_csi_start_stop_operation(const struct rzv2m_csi_priv *csi, > > static int rzv2m_csi_fill_txfifo(struct rzv2m_csi_priv *csi) > { > - int i; > - > if (readl(csi->base + CSI_OFIFOL)) > return -EIO; > > - if (csi->bytes_per_word == 2) { > - u16 *buf = (u16 *)csi->txbuf; > - > - for (i = 0; i < csi->words_to_transfer; i++) > - writel(buf[i], csi->base + CSI_OFIFO); > - } else { > - u8 *buf = (u8 *)csi->txbuf; > - > - for (i = 0; i < csi->words_to_transfer; i++) > - writel(buf[i], csi->base + CSI_OFIFO); > - } > + if (csi->bytes_per_word == 2) > + writesw(csi->base + CSI_OFIFO, csi->txbuf, > + csi->words_to_transfer); > + else > + writesb(csi->base + CSI_OFIFO, csi->txbuf, > + csi->words_to_transfer); According to the hardware documentation[1], the access size for both the CSI_OFIFO and CSI_IFIFO registers is 32 bits, so you must use writel() resp. readl(). So please check with the hardware people first. [1] RZ/V2M User's Manual Hardware, Rev. 1.30. Gr{oetje,eeting}s, Geert
Hi Geert, Thanks for your reply! > From: Geert Uytterhoeven <geert@linux-m68k.org> > Subject: Re: [PATCH 07/10] spi: rzv2m-csi: Switch to using > {read,write}s{b,w} > > Hi Fabrizio, > > On Sat, Jul 15, 2023 at 3:04 AM Fabrizio Castro > <fabrizio.castro.jz@renesas.com> wrote: > > The RX/TX FIFOs implemented by the CSI IP are accessed by > > repeatedly reading/writing the same memory address, and > > therefore they are the ideal candidate for {read,write}s{b,w}. > > The RZ/V2M CSI driver currently implements loops to fill up > > the TX FIFO and empty the RX FIFO, differentiating between > > 8-bit and 16-bit word size. > > Switch to using {read,write}s{b,w} to get rid of the bespoke > > loops. > > > > Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com> > > Thanks for your patch! > > > --- a/drivers/spi/spi-rzv2m-csi.c > > +++ b/drivers/spi/spi-rzv2m-csi.c > > > @@ -157,22 +157,15 @@ static int > rzv2m_csi_start_stop_operation(const struct rzv2m_csi_priv *csi, > > > > static int rzv2m_csi_fill_txfifo(struct rzv2m_csi_priv *csi) > > { > > - int i; > > - > > if (readl(csi->base + CSI_OFIFOL)) > > return -EIO; > > > > - if (csi->bytes_per_word == 2) { > > - u16 *buf = (u16 *)csi->txbuf; > > - > > - for (i = 0; i < csi->words_to_transfer; i++) > > - writel(buf[i], csi->base + CSI_OFIFO); > > - } else { > > - u8 *buf = (u8 *)csi->txbuf; > > - > > - for (i = 0; i < csi->words_to_transfer; i++) > > - writel(buf[i], csi->base + CSI_OFIFO); > > - } > > + if (csi->bytes_per_word == 2) > > + writesw(csi->base + CSI_OFIFO, csi->txbuf, > > + csi->words_to_transfer); > > + else > > + writesb(csi->base + CSI_OFIFO, csi->txbuf, > > + csi->words_to_transfer); > > According to the hardware documentation[1], the access size for both > the > CSI_OFIFO and CSI_IFIFO registers is 32 bits, so you must use writel() > resp. readl(). So please check with the hardware people first. > > [1] RZ/V2M User's Manual Hardware, Rev. 1.30. You are right, access is 32 bits (and although this patch works fine, we should avoid accessing those regs any other way). Now I remember why I decided to go for the bespoke loops in the first place, writesl and readsl provide the right register access, but the wrong pointer arithmetic for this use case. For this patch I ended up selecting writesw/writesb/readsw/readsb to get the right pointer arithmetic, but the register access is not as per manual. I can either fallback to using the bespoke loops (I can still remove the unnecessary u8* and u16* casting ;-) ), or I can add new APIs for this sort of access to io.h (e.g. writesbl, writeswl, readsbl, readswl, in order to get the pointer arithmetic right for the type of array handled, while keeping memory access as expected). What are your thoughts on that? Thanks, Fab > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- > geert@linux-m68k.org > > In personal conversations with technical people, I call myself a > hacker. But > when I'm talking to journalists I just say "programmer" or something > like that. > -- Linus Torvalds
On Mon, Jul 17, 2023 at 1:36 PM Fabrizio Castro <fabrizio.castro.jz@renesas.com> wrote: > > From: Geert Uytterhoeven <geert@linux-m68k.org> > > Subject: Re: [PATCH 07/10] spi: rzv2m-csi: Switch to using > > {read,write}s{b,w} > > On Sat, Jul 15, 2023 at 3:04 AM Fabrizio Castro > > <fabrizio.castro.jz@renesas.com> wrote: ... > > According to the hardware documentation[1], the access size for both > > the > > CSI_OFIFO and CSI_IFIFO registers is 32 bits, so you must use writel() > > resp. readl(). So please check with the hardware people first. > > > > [1] RZ/V2M User's Manual Hardware, Rev. 1.30. > > You are right, access is 32 bits (and although this patch works fine, > we should avoid accessing those regs any other way). Now I remember > why I decided to go for the bespoke loops in the first place, writesl > and readsl provide the right register access, but the wrong pointer > arithmetic for this use case. > For this patch I ended up selecting writesw/writesb/readsw/readsb to > get the right pointer arithmetic, but the register access is not as > per manual. > > I can either fallback to using the bespoke loops (I can still > remove the unnecessary u8* and u16* casting ;-) ), or I can add > new APIs for this sort of access to io.h (e.g. writesbl, writeswl, > readsbl, readswl, in order to get the pointer arithmetic right for > the type of array handled, while keeping memory access as expected). > > What are your thoughts on that? I think that you need to use readsl() / writesl() on the custom buffer with something like *_sparse() / *_condence() APIs added (perhaps locally to this driver) as they may be reused by others in the future. Having all flavours of read*()/write*() does not scale in my opinion.
Hi Andy, Thanks for your reply. > From: Andy Shevchenko <andy.shevchenko@gmail.com> > Subject: Re: [PATCH 07/10] spi: rzv2m-csi: Switch to using > {read,write}s{b,w} > > On Mon, Jul 17, 2023 at 1:36 PM Fabrizio Castro > <fabrizio.castro.jz@renesas.com> wrote: > > > From: Geert Uytterhoeven <geert@linux-m68k.org> > > > Subject: Re: [PATCH 07/10] spi: rzv2m-csi: Switch to using > > > {read,write}s{b,w} > > > On Sat, Jul 15, 2023 at 3:04 AM Fabrizio Castro > > > <fabrizio.castro.jz@renesas.com> wrote: > > ... > > > > According to the hardware documentation[1], the access size for > both > > > the > > > CSI_OFIFO and CSI_IFIFO registers is 32 bits, so you must use > writel() > > > resp. readl(). So please check with the hardware people first. > > > > > > [1] RZ/V2M User's Manual Hardware, Rev. 1.30. > > > > You are right, access is 32 bits (and although this patch works > fine, > > we should avoid accessing those regs any other way). Now I remember > > why I decided to go for the bespoke loops in the first place, > writesl > > and readsl provide the right register access, but the wrong pointer > > arithmetic for this use case. > > For this patch I ended up selecting writesw/writesb/readsw/readsb to > > get the right pointer arithmetic, but the register access is not as > > per manual. > > > > I can either fallback to using the bespoke loops (I can still > > remove the unnecessary u8* and u16* casting ;-) ), or I can add > > new APIs for this sort of access to io.h (e.g. writesbl, writeswl, > > readsbl, readswl, in order to get the pointer arithmetic right for > > the type of array handled, while keeping memory access as expected). > > > > What are your thoughts on that? > > I think that you need to use readsl() / writesl() on the custom buffer > with something like > > *_sparse() / *_condence() APIs added (perhaps locally to this driver) > as they may be reused by others in the future. > Having all flavours of read*()/write*() does not scale in my opinion. Maybe a "generic" macro then (one for reading and one for writing)? So that we can pass the data type (to get the pointer arithmetic right) and the function name to use for the read/write operations (to get the register operations right)? Maybe that would scale and cater for most needs (including the one from this patch)? Cheers, Fab > > -- > With Best Regards, > Andy Shevchenko
> From: Fabrizio Castro <fabrizio.castro.jz@renesas.com> > Subject: RE: [PATCH 07/10] spi: rzv2m-csi: Switch to using > {read,write}s{b,w} > > Hi Andy, > > Thanks for your reply. > > > From: Andy Shevchenko <andy.shevchenko@gmail.com> > > Subject: Re: [PATCH 07/10] spi: rzv2m-csi: Switch to using > > {read,write}s{b,w} > > > > On Mon, Jul 17, 2023 at 1:36 PM Fabrizio Castro > > <fabrizio.castro.jz@renesas.com> wrote: > > > > From: Geert Uytterhoeven <geert@linux-m68k.org> > > > > Subject: Re: [PATCH 07/10] spi: rzv2m-csi: Switch to using > > > > {read,write}s{b,w} > > > > On Sat, Jul 15, 2023 at 3:04 AM Fabrizio Castro > > > > <fabrizio.castro.jz@renesas.com> wrote: > > > > ... > > > > > > According to the hardware documentation[1], the access size for > > both > > > > the > > > > CSI_OFIFO and CSI_IFIFO registers is 32 bits, so you must use > > writel() > > > > resp. readl(). So please check with the hardware people first. > > > > > > > > [1] RZ/V2M User's Manual Hardware, Rev. 1.30. > > > > > > You are right, access is 32 bits (and although this patch works > > fine, > > > we should avoid accessing those regs any other way). Now I > remember > > > why I decided to go for the bespoke loops in the first place, > > writesl > > > and readsl provide the right register access, but the wrong > pointer > > > arithmetic for this use case. > > > For this patch I ended up selecting writesw/writesb/readsw/readsb > to > > > get the right pointer arithmetic, but the register access is not > as > > > per manual. > > > > > > I can either fallback to using the bespoke loops (I can still > > > remove the unnecessary u8* and u16* casting ;-) ), or I can add > > > new APIs for this sort of access to io.h (e.g. writesbl, writeswl, > > > readsbl, readswl, in order to get the pointer arithmetic right for > > > the type of array handled, while keeping memory access as > expected). > > > > > > What are your thoughts on that? > > > > I think that you need to use readsl() / writesl() on the custom > buffer > > with something like > > > > *_sparse() / *_condence() APIs added (perhaps locally to this > driver) > > as they may be reused by others in the future. > > Having all flavours of read*()/write*() does not scale in my > opinion. > > Maybe a "generic" macro then (one for reading and one for writing)? > So that we can pass the data type (to get the pointer arithmetic > right) and the function name to use for the read/write operations > (to get the register operations right)? > Maybe that would scale and cater for most needs (including the one > from this patch)? Something like the below perhaps: #ifndef readsx #define readsx(atype, readc, addr, buffer, count) \ ({ \ if (count) { \ unsigned int cnt = count; \ atype *buf = buffer; \ \ do { \ atype x = readc(addr); \ *buf++ = x; \ } while (--cnt); \ } \ }) #endif #ifndef writesx #define writesx(atype, writec, addr, buffer, count) \ ({ \ if (count) { \ unsigned int cnt = count; \ const atype *buf = buffer; \ \ do { \ writec(*buf++, addr); \ } while (--cnt); \ } \ }) #endif Cheers, Fab > > Cheers, > Fab > > > > > -- > > With Best Regards, > > Andy Shevchenko
diff --git a/drivers/spi/spi-rzv2m-csi.c b/drivers/spi/spi-rzv2m-csi.c index faf5898bc3e0..d0d6b183ffaf 100644 --- a/drivers/spi/spi-rzv2m-csi.c +++ b/drivers/spi/spi-rzv2m-csi.c @@ -86,8 +86,8 @@ struct rzv2m_csi_priv { struct clk *pclk; struct device *dev; struct spi_controller *controller; - const u8 *txbuf; - u8 *rxbuf; + const void *txbuf; + void *rxbuf; int buffer_len; int bytes_sent; int bytes_received; @@ -157,22 +157,15 @@ static int rzv2m_csi_start_stop_operation(const struct rzv2m_csi_priv *csi, static int rzv2m_csi_fill_txfifo(struct rzv2m_csi_priv *csi) { - int i; - if (readl(csi->base + CSI_OFIFOL)) return -EIO; - if (csi->bytes_per_word == 2) { - u16 *buf = (u16 *)csi->txbuf; - - for (i = 0; i < csi->words_to_transfer; i++) - writel(buf[i], csi->base + CSI_OFIFO); - } else { - u8 *buf = (u8 *)csi->txbuf; - - for (i = 0; i < csi->words_to_transfer; i++) - writel(buf[i], csi->base + CSI_OFIFO); - } + if (csi->bytes_per_word == 2) + writesw(csi->base + CSI_OFIFO, csi->txbuf, + csi->words_to_transfer); + else + writesb(csi->base + CSI_OFIFO, csi->txbuf, + csi->words_to_transfer); csi->txbuf += csi->bytes_to_transfer; csi->bytes_sent += csi->bytes_to_transfer; @@ -182,22 +175,15 @@ static int rzv2m_csi_fill_txfifo(struct rzv2m_csi_priv *csi) static int rzv2m_csi_read_rxfifo(struct rzv2m_csi_priv *csi) { - int i; - if (readl(csi->base + CSI_IFIFOL) != csi->bytes_to_transfer) return -EIO; - if (csi->bytes_per_word == 2) { - u16 *buf = (u16 *)csi->rxbuf; - - for (i = 0; i < csi->words_to_transfer; i++) - buf[i] = (u16)readl(csi->base + CSI_IFIFO); - } else { - u8 *buf = (u8 *)csi->rxbuf; - - for (i = 0; i < csi->words_to_transfer; i++) - buf[i] = (u8)readl(csi->base + CSI_IFIFO); - } + if (csi->bytes_per_word == 2) + readsw(csi->base + CSI_IFIFO, csi->rxbuf, + csi->words_to_transfer); + else + readsb(csi->base + CSI_IFIFO, csi->rxbuf, + csi->words_to_transfer); csi->rxbuf += csi->bytes_to_transfer; csi->bytes_received += csi->bytes_to_transfer;