Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp1218835pxk; Sat, 12 Sep 2020 16:10:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwkfbMnUc7xWpi/y5AWzzeiUoB6BgXEQxUaoP3opC+G0mzZQKOPlZ2nK86Y1RRiX/b/7BHP X-Received: by 2002:a17:906:4e82:: with SMTP id v2mr7635538eju.218.1599952253859; Sat, 12 Sep 2020 16:10:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599952253; cv=none; d=google.com; s=arc-20160816; b=DDBPNcSPMbVTWndCn+sTMBgtVsoRZAH9G+UIsGgpP6Fpxh301wTVvRrizfrYVXXbfi QuhpnizM3u0rkdFhTcQJroyYZhfCLmb9M2Es4H0wxs/xx6fywSRz/OpvEJyrVwU/6QZI geWuB//cS1e2OKl3S2fkOXZPlq3XUCXFU7C31KqkyuniYoylrKWAkiAV1q2aTlc5oHcT 3A6/gDReAajDiXzud1iXGrRzOn+VczZ3usBIsPllyXiu4nZCvQBB2hK7pjqMKfsgi4xX 0Rb48w8F2tW26U7PTRAxyP5Kfa6Qr2Nvm6WYWZJEriYXb/GqQ6f/IXj2+X25UO2VF2Y7 TAlQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :dkim-signature; bh=YEj25auNRfoFs7fGBIclA3iB7k0sYk51VrLB+0yDItQ=; b=w7nlPZXPTE1J/pZwzq8UUPPQsY0jqp3ebUnWxiLlZyujmdMHIGVtOs9WMeuUANz6f2 N/P8WGbamPvf8lMCOgXveYXdXeD0eH8O3CXllji705aRWhBTPBUmmGWXF+Ief5MUx+2J omNHA8c5UfEPMgLqFS/EXVpCLoBxr+jBLwjC2JdGkGerhg3NcXXTtR15ErmqVp9xWzUY U/HvLTP6C23J9L4a38G3XtPTWnn+HHAgNs2zTFY5Ys3km26Q4DGg9ufeRRkfMWheBZKk LBv2id3ICIf9WTr62339flj3Ga+fN+SxOipZHqnoNYT9bwJnZ5YXqyff4OZSpuFh7cjz M14A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=zFiZPyOH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id lu5si3884832ejb.377.2020.09.12.16.10.28; Sat, 12 Sep 2020 16:10:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=zFiZPyOH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725903AbgILXJ6 (ORCPT + 99 others); Sat, 12 Sep 2020 19:09:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725893AbgILXJz (ORCPT ); Sat, 12 Sep 2020 19:09:55 -0400 Received: from mail-ot1-x344.google.com (mail-ot1-x344.google.com [IPv6:2607:f8b0:4864:20::344]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65544C061574 for ; Sat, 12 Sep 2020 16:09:54 -0700 (PDT) Received: by mail-ot1-x344.google.com with SMTP id o6so11580600ota.2 for ; Sat, 12 Sep 2020 16:09:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=YEj25auNRfoFs7fGBIclA3iB7k0sYk51VrLB+0yDItQ=; b=zFiZPyOHU6K9fCyvzETj/V58HgaEc/7wTNUFlNllONtwgCArpJkW0yzLCmTfQf/mgx n0nNCW1I4aCXkXC9oy7JhAv124+wTeIH0uQsKH5Yg7FCPAJ/jexB93WgQU4o0b1idWWz fWAoO1X+ElA3xylI5IRoKuNDMEEJfERoV+afQDE4ShNZuNkiigtMCegv/Dj2wpqat8kU D36KzLGA0oarBc2q+ws9+jjIiNF1rueTSzmGCXeqEi34/bWJFqd8m/W8dskdGDoud3uE syhLIEcxQs2PRgQ/5z/ToKSDnZ7IeeJ+CMJN7B2Dw8hSLX0hwqQel3QWWozjiJuxqTNv b6/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=YEj25auNRfoFs7fGBIclA3iB7k0sYk51VrLB+0yDItQ=; b=twwzh1rkpQY6uBZDxQrohDtE+tY/hmT5CAAVPsT1MrjYLJliLHgrGJHtcoAI6EyghN DPSOrzlZIpAPlEqJB/pPlyETszlzTC9Rn+NfDMMWG58orCIUH1hXr3i8kPTDjS8zDJ6B 5b7XeGFJR9ceANAsVmURAUHDs8zI5PTI+KceUGJe7iRrPIZJGRpnApd3O5DuTyiBY3cd 0fx8YWf7pLuRqC2NwtGBfy5iti0KdSTwagjXlAiDU3R8M8KYNYYAZdfEIOF3MCcq6+Gn M4DE2yW6E0Oi5oBnH7NdGMUshnaDzknTqUI2Qwgg1gGzCP8Xg9OoEgGGOy61tgb8VJ3i FbCQ== X-Gm-Message-State: AOAM530Zt//omUit4dZpZ2uPegHaN0diH6Kq98ODAverV2Fea2N3jlSB vK9QiYYtXR00srYVS7oabWiGsQ== X-Received: by 2002:a05:6830:c3:: with SMTP id x3mr4862450oto.235.1599952193178; Sat, 12 Sep 2020 16:09:53 -0700 (PDT) Received: from yoga ([2605:6000:e5cb:c100:8898:14ff:fe6d:34e]) by smtp.gmail.com with ESMTPSA id t84sm994652oif.32.2020.09.12.16.09.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Sep 2020 16:09:52 -0700 (PDT) Date: Sat, 12 Sep 2020 18:09:50 -0500 From: Bjorn Andersson To: Douglas Anderson Cc: Mark Brown , swboyd@chromium.org, Akash Asthana , Andy Gross , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org Subject: Re: [PATCH] spi: spi-geni-qcom: Don't wait to start 1st transfer if transmitting Message-ID: <20200912230950.GD3715@yoga> References: <20200912111716.1.Ied5e843fad0d6b733a1fb8bcfb364dd2fa889eb3@changeid> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200912111716.1.Ied5e843fad0d6b733a1fb8bcfb364dd2fa889eb3@changeid> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat 12 Sep 13:17 CDT 2020, Douglas Anderson wrote: > If we're sending bytes over SPI, we know the FIFO is empty at the > start of the transfer. There's no reason to wait for the interrupt > telling us to start--we can just start right away. Then if we > transmit everything in one swell foop we don't even need to bother > listening for TX interrupts. > > In a test of "flashrom -p ec -r /tmp/foo.bin" interrupts were reduced > from ~30560 to ~29730, about a 3% savings. > > This patch looks bigger than it is because I moved a few functions > rather than adding a forward declaration. The only actual change to > geni_spi_handle_tx() was to make it return a bool indicating if there > is more to tx. > Reviewed-by: Bjorn Andersson Regards, Bjorn > Signed-off-by: Douglas Anderson > --- > > drivers/spi/spi-geni-qcom.c | 167 +++++++++++++++++++----------------- > 1 file changed, 86 insertions(+), 81 deletions(-) > > diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c > index 0dc3f4c55b0b..49c9eb870755 100644 > --- a/drivers/spi/spi-geni-qcom.c > +++ b/drivers/spi/spi-geni-qcom.c > @@ -326,6 +326,88 @@ static int spi_geni_init(struct spi_geni_master *mas) > return 0; > } > > +static unsigned int geni_byte_per_fifo_word(struct spi_geni_master *mas) > +{ > + /* > + * Calculate how many bytes we'll put in each FIFO word. If the > + * transfer words don't pack cleanly into a FIFO word we'll just put > + * one transfer word in each FIFO word. If they do pack we'll pack 'em. > + */ > + if (mas->fifo_width_bits % mas->cur_bits_per_word) > + return roundup_pow_of_two(DIV_ROUND_UP(mas->cur_bits_per_word, > + BITS_PER_BYTE)); > + > + return mas->fifo_width_bits / BITS_PER_BYTE; > +} > + > +static bool geni_spi_handle_tx(struct spi_geni_master *mas) > +{ > + struct geni_se *se = &mas->se; > + unsigned int max_bytes; > + const u8 *tx_buf; > + unsigned int bytes_per_fifo_word = geni_byte_per_fifo_word(mas); > + unsigned int i = 0; > + > + max_bytes = (mas->tx_fifo_depth - mas->tx_wm) * bytes_per_fifo_word; > + if (mas->tx_rem_bytes < max_bytes) > + max_bytes = mas->tx_rem_bytes; > + > + tx_buf = mas->cur_xfer->tx_buf + mas->cur_xfer->len - mas->tx_rem_bytes; > + while (i < max_bytes) { > + unsigned int j; > + unsigned int bytes_to_write; > + u32 fifo_word = 0; > + u8 *fifo_byte = (u8 *)&fifo_word; > + > + bytes_to_write = min(bytes_per_fifo_word, max_bytes - i); > + for (j = 0; j < bytes_to_write; j++) > + fifo_byte[j] = tx_buf[i++]; > + iowrite32_rep(se->base + SE_GENI_TX_FIFOn, &fifo_word, 1); > + } > + mas->tx_rem_bytes -= max_bytes; > + if (!mas->tx_rem_bytes) { > + writel(0, se->base + SE_GENI_TX_WATERMARK_REG); > + return false; > + } > + return true; > +} > + > +static void geni_spi_handle_rx(struct spi_geni_master *mas) > +{ > + struct geni_se *se = &mas->se; > + u32 rx_fifo_status; > + unsigned int rx_bytes; > + unsigned int rx_last_byte_valid; > + u8 *rx_buf; > + unsigned int bytes_per_fifo_word = geni_byte_per_fifo_word(mas); > + unsigned int i = 0; > + > + rx_fifo_status = readl(se->base + SE_GENI_RX_FIFO_STATUS); > + rx_bytes = (rx_fifo_status & RX_FIFO_WC_MSK) * bytes_per_fifo_word; > + if (rx_fifo_status & RX_LAST) { > + rx_last_byte_valid = rx_fifo_status & RX_LAST_BYTE_VALID_MSK; > + rx_last_byte_valid >>= RX_LAST_BYTE_VALID_SHFT; > + if (rx_last_byte_valid && rx_last_byte_valid < 4) > + rx_bytes -= bytes_per_fifo_word - rx_last_byte_valid; > + } > + if (mas->rx_rem_bytes < rx_bytes) > + rx_bytes = mas->rx_rem_bytes; > + > + rx_buf = mas->cur_xfer->rx_buf + mas->cur_xfer->len - mas->rx_rem_bytes; > + while (i < rx_bytes) { > + u32 fifo_word = 0; > + u8 *fifo_byte = (u8 *)&fifo_word; > + unsigned int bytes_to_read; > + unsigned int j; > + > + bytes_to_read = min(bytes_per_fifo_word, rx_bytes - i); > + ioread32_rep(se->base + SE_GENI_RX_FIFOn, &fifo_word, 1); > + for (j = 0; j < bytes_to_read; j++) > + rx_buf[i++] = fifo_byte[j]; > + } > + mas->rx_rem_bytes -= rx_bytes; > +} > + > static void setup_fifo_xfer(struct spi_transfer *xfer, > struct spi_geni_master *mas, > u16 mode, struct spi_master *spi) > @@ -398,8 +480,10 @@ static void setup_fifo_xfer(struct spi_transfer *xfer, > * setting up GENI SE engine, as driver starts data transfer > * for the watermark interrupt. > */ > - if (m_cmd & SPI_TX_ONLY) > - writel(mas->tx_wm, se->base + SE_GENI_TX_WATERMARK_REG); > + if (m_cmd & SPI_TX_ONLY) { > + if (geni_spi_handle_tx(mas)) > + writel(mas->tx_wm, se->base + SE_GENI_TX_WATERMARK_REG); > + } > spin_unlock_irq(&mas->lock); > } > > @@ -417,85 +501,6 @@ static int spi_geni_transfer_one(struct spi_master *spi, > return 1; > } > > -static unsigned int geni_byte_per_fifo_word(struct spi_geni_master *mas) > -{ > - /* > - * Calculate how many bytes we'll put in each FIFO word. If the > - * transfer words don't pack cleanly into a FIFO word we'll just put > - * one transfer word in each FIFO word. If they do pack we'll pack 'em. > - */ > - if (mas->fifo_width_bits % mas->cur_bits_per_word) > - return roundup_pow_of_two(DIV_ROUND_UP(mas->cur_bits_per_word, > - BITS_PER_BYTE)); > - > - return mas->fifo_width_bits / BITS_PER_BYTE; > -} > - > -static void geni_spi_handle_tx(struct spi_geni_master *mas) > -{ > - struct geni_se *se = &mas->se; > - unsigned int max_bytes; > - const u8 *tx_buf; > - unsigned int bytes_per_fifo_word = geni_byte_per_fifo_word(mas); > - unsigned int i = 0; > - > - max_bytes = (mas->tx_fifo_depth - mas->tx_wm) * bytes_per_fifo_word; > - if (mas->tx_rem_bytes < max_bytes) > - max_bytes = mas->tx_rem_bytes; > - > - tx_buf = mas->cur_xfer->tx_buf + mas->cur_xfer->len - mas->tx_rem_bytes; > - while (i < max_bytes) { > - unsigned int j; > - unsigned int bytes_to_write; > - u32 fifo_word = 0; > - u8 *fifo_byte = (u8 *)&fifo_word; > - > - bytes_to_write = min(bytes_per_fifo_word, max_bytes - i); > - for (j = 0; j < bytes_to_write; j++) > - fifo_byte[j] = tx_buf[i++]; > - iowrite32_rep(se->base + SE_GENI_TX_FIFOn, &fifo_word, 1); > - } > - mas->tx_rem_bytes -= max_bytes; > - if (!mas->tx_rem_bytes) > - writel(0, se->base + SE_GENI_TX_WATERMARK_REG); > -} > - > -static void geni_spi_handle_rx(struct spi_geni_master *mas) > -{ > - struct geni_se *se = &mas->se; > - u32 rx_fifo_status; > - unsigned int rx_bytes; > - unsigned int rx_last_byte_valid; > - u8 *rx_buf; > - unsigned int bytes_per_fifo_word = geni_byte_per_fifo_word(mas); > - unsigned int i = 0; > - > - rx_fifo_status = readl(se->base + SE_GENI_RX_FIFO_STATUS); > - rx_bytes = (rx_fifo_status & RX_FIFO_WC_MSK) * bytes_per_fifo_word; > - if (rx_fifo_status & RX_LAST) { > - rx_last_byte_valid = rx_fifo_status & RX_LAST_BYTE_VALID_MSK; > - rx_last_byte_valid >>= RX_LAST_BYTE_VALID_SHFT; > - if (rx_last_byte_valid && rx_last_byte_valid < 4) > - rx_bytes -= bytes_per_fifo_word - rx_last_byte_valid; > - } > - if (mas->rx_rem_bytes < rx_bytes) > - rx_bytes = mas->rx_rem_bytes; > - > - rx_buf = mas->cur_xfer->rx_buf + mas->cur_xfer->len - mas->rx_rem_bytes; > - while (i < rx_bytes) { > - u32 fifo_word = 0; > - u8 *fifo_byte = (u8 *)&fifo_word; > - unsigned int bytes_to_read; > - unsigned int j; > - > - bytes_to_read = min(bytes_per_fifo_word, rx_bytes - i); > - ioread32_rep(se->base + SE_GENI_RX_FIFOn, &fifo_word, 1); > - for (j = 0; j < bytes_to_read; j++) > - rx_buf[i++] = fifo_byte[j]; > - } > - mas->rx_rem_bytes -= rx_bytes; > -} > - > static irqreturn_t geni_spi_isr(int irq, void *data) > { > struct spi_master *spi = data; > -- > 2.28.0.618.gf4bc123cb7-goog >