From: Serge Semin <fancer.lancer@gmail.com>
To: Viresh Kumar <vireshk@kernel.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Andy Shevchenko <andy@kernel.org>, Vinod Koul <vkoul@kernel.org>
Cc: "Serge Semin" <fancer.lancer@gmail.com>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Jiri Slaby" <jirislaby@kernel.org>,
dmaengine@vger.kernel.org, linux-serial@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH RESEND v4 5/6] dmaengine: dw: Simplify max-burst calculation procedure
Date: Fri, 2 Aug 2024 10:50:50 +0300 [thread overview]
Message-ID: <20240802075100.6475-6-fancer.lancer@gmail.com> (raw)
In-Reply-To: <20240802075100.6475-1-fancer.lancer@gmail.com>
In order to have a more coherent DW AHB DMA slave configuration method -
dwc_config() - let's simplify the source and destination channel max-burst
calculation procedure:
1. Create the max-burst verification method as it has been just done for
the memory and peripheral address widths. Thus the dwc_config() method
will turn to a set of the verification methods execution.
2. Since both the generic DW AHB DMA and Intel iDMA 32-bit engines support
the power-of-2 bursts only, then the specified by the client driver
max-burst values can be converted to being power-of-2 right in the
max-burst verification method.
3. Since max-burst encoded value is required on the CTL_LO fields
calculation stage, the encode_maxburst() callback can be easily dropped
from the dw_dma structure meanwhile the encoding procedure will be
executed right in the CTL_LO register value calculation.
Thus the update will provide the next positive effects: the internal
DMA-slave config structure will contain only the real DMA-transfer config
values, which will be encoded to the DMA-controller register fields only
when it's required on the buffer mapping; the redundant encode_maxburst()
callback will be dropped simplifying the internal HW-abstraction API;
dwc_config() will look more readable executing the verification functions
one-by-one.
Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
---
Changelog v2:
- Refer to dwc_config() in the commit message. (Andy)
- Convert dwc_verify_maxburst() to returning zero. (Andy)
- Add a comment regarding the values utilized in the
dwc_verify_p_buswidth() being verified before the method is called.
(Andy, see patch 2)
- Detach the dw_dma_encode_maxburst() and idma32_encode_maxburst()
movement to a preparatory patch. (Andy)
---
drivers/dma/dw/core.c | 30 +++++++++++++++++++++---------
drivers/dma/dw/dw.c | 9 ++++-----
drivers/dma/dw/idma32.c | 9 ++++-----
drivers/dma/dw/regs.h | 1 -
4 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index 4987bfa10461..c696d79b911a 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -779,6 +779,23 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
}
EXPORT_SYMBOL_GPL(dw_dma_filter);
+static int dwc_verify_maxburst(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+
+ dwc->dma_sconfig.src_maxburst =
+ clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst);
+ dwc->dma_sconfig.dst_maxburst =
+ clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst);
+
+ dwc->dma_sconfig.src_maxburst =
+ rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst);
+ dwc->dma_sconfig.dst_maxburst =
+ rounddown_pow_of_two(dwc->dma_sconfig.dst_maxburst);
+
+ return 0;
+}
+
static int dwc_verify_p_buswidth(struct dma_chan *chan)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
@@ -838,7 +855,7 @@ static int dwc_verify_m_buswidth(struct dma_chan *chan)
dwc->dma_sconfig.src_addr_width = mem_width;
} else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) {
reg_width = dwc->dma_sconfig.src_addr_width;
- reg_burst = rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst);
+ reg_burst = dwc->dma_sconfig.src_maxburst;
dwc->dma_sconfig.dst_addr_width = min(mem_width, reg_width * reg_burst);
}
@@ -849,15 +866,13 @@ static int dwc_verify_m_buswidth(struct dma_chan *chan)
static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
- struct dw_dma *dw = to_dw_dma(chan->device);
int ret;
memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
- dwc->dma_sconfig.src_maxburst =
- clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst);
- dwc->dma_sconfig.dst_maxburst =
- clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst);
+ ret = dwc_verify_maxburst(chan);
+ if (ret)
+ return ret;
ret = dwc_verify_p_buswidth(chan);
if (ret)
@@ -867,9 +882,6 @@ static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
if (ret)
return ret;
- dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst);
- dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst);
-
return 0;
}
diff --git a/drivers/dma/dw/dw.c b/drivers/dma/dw/dw.c
index 628ee1e77505..6766142884b6 100644
--- a/drivers/dma/dw/dw.c
+++ b/drivers/dma/dw/dw.c
@@ -64,13 +64,13 @@ static size_t dw_dma_block2bytes(struct dw_dma_chan *dwc, u32 block, u32 width)
return DWC_CTLH_BLOCK_TS(block) << width;
}
-static void dw_dma_encode_maxburst(struct dw_dma_chan *dwc, u32 *maxburst)
+static inline u8 dw_dma_encode_maxburst(u32 maxburst)
{
/*
* Fix burst size according to dw_dmac. We need to convert them as:
* 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
*/
- *maxburst = *maxburst > 1 ? fls(*maxburst) - 2 : 0;
+ return maxburst > 1 ? fls(maxburst) - 2 : 0;
}
static u32 dw_dma_prepare_ctllo(struct dw_dma_chan *dwc)
@@ -82,11 +82,11 @@ static u32 dw_dma_prepare_ctllo(struct dw_dma_chan *dwc)
if (dwc->direction == DMA_MEM_TO_DEV) {
sms = dwc->dws.m_master;
dms = dwc->dws.p_master;
- dmsize = sconfig->dst_maxburst;
+ dmsize = dw_dma_encode_maxburst(sconfig->dst_maxburst);
} else if (dwc->direction == DMA_DEV_TO_MEM) {
sms = dwc->dws.p_master;
dms = dwc->dws.m_master;
- smsize = sconfig->src_maxburst;
+ smsize = dw_dma_encode_maxburst(sconfig->src_maxburst);
} else /* DMA_MEM_TO_MEM */ {
sms = dwc->dws.m_master;
dms = dwc->dws.m_master;
@@ -125,7 +125,6 @@ int dw_dma_probe(struct dw_dma_chip *chip)
dw->suspend_chan = dw_dma_suspend_chan;
dw->resume_chan = dw_dma_resume_chan;
dw->prepare_ctllo = dw_dma_prepare_ctllo;
- dw->encode_maxburst = dw_dma_encode_maxburst;
dw->bytes2block = dw_dma_bytes2block;
dw->block2bytes = dw_dma_block2bytes;
diff --git a/drivers/dma/dw/idma32.c b/drivers/dma/dw/idma32.c
index 493fcbafa2b8..dac617c183e6 100644
--- a/drivers/dma/dw/idma32.c
+++ b/drivers/dma/dw/idma32.c
@@ -199,9 +199,9 @@ static size_t idma32_block2bytes(struct dw_dma_chan *dwc, u32 block, u32 width)
return IDMA32C_CTLH_BLOCK_TS(block);
}
-static void idma32_encode_maxburst(struct dw_dma_chan *dwc, u32 *maxburst)
+static inline u8 idma32_encode_maxburst(u32 maxburst)
{
- *maxburst = *maxburst > 1 ? fls(*maxburst) - 1 : 0;
+ return maxburst > 1 ? fls(maxburst) - 1 : 0;
}
static u32 idma32_prepare_ctllo(struct dw_dma_chan *dwc)
@@ -210,9 +210,9 @@ static u32 idma32_prepare_ctllo(struct dw_dma_chan *dwc)
u8 smsize = 0, dmsize = 0;
if (dwc->direction == DMA_MEM_TO_DEV)
- dmsize = sconfig->dst_maxburst;
+ dmsize = idma32_encode_maxburst(sconfig->dst_maxburst);
else if (dwc->direction == DMA_DEV_TO_MEM)
- smsize = sconfig->src_maxburst;
+ smsize = idma32_encode_maxburst(sconfig->src_maxburst);
return DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN |
DWC_CTLL_DST_MSIZE(dmsize) | DWC_CTLL_SRC_MSIZE(smsize);
@@ -274,7 +274,6 @@ int idma32_dma_probe(struct dw_dma_chip *chip)
dw->suspend_chan = idma32_suspend_chan;
dw->resume_chan = idma32_resume_chan;
dw->prepare_ctllo = idma32_prepare_ctllo;
- dw->encode_maxburst = idma32_encode_maxburst;
dw->bytes2block = idma32_bytes2block;
dw->block2bytes = idma32_block2bytes;
diff --git a/drivers/dma/dw/regs.h b/drivers/dma/dw/regs.h
index 76654bd13c1a..5969d9cc8d7a 100644
--- a/drivers/dma/dw/regs.h
+++ b/drivers/dma/dw/regs.h
@@ -327,7 +327,6 @@ struct dw_dma {
void (*suspend_chan)(struct dw_dma_chan *dwc, bool drain);
void (*resume_chan)(struct dw_dma_chan *dwc, bool drain);
u32 (*prepare_ctllo)(struct dw_dma_chan *dwc);
- void (*encode_maxburst)(struct dw_dma_chan *dwc, u32 *maxburst);
u32 (*bytes2block)(struct dw_dma_chan *dwc, size_t bytes,
unsigned int width, size_t *len);
size_t (*block2bytes)(struct dw_dma_chan *dwc, u32 block, u32 width);
--
2.43.0
next prev parent reply other threads:[~2024-08-02 7:51 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-02 7:50 [PATCH RESEND v4 0/6] dmaengine: dw: Fix src/dst addr width misconfig Serge Semin
2024-08-02 7:50 ` [PATCH RESEND v4 1/6] dmaengine: dw: Add peripheral bus width verification Serge Semin
2024-09-14 19:12 ` Andy Shevchenko
2024-09-14 19:22 ` Serge Semin
2024-09-15 21:06 ` Ferry Toth
2024-09-16 11:43 ` Andy Shevchenko
2024-09-16 11:45 ` Andy Shevchenko
2024-09-16 11:57 ` Andy Shevchenko
2024-09-16 12:46 ` Andy Shevchenko
2024-09-19 14:04 ` Serge Semin
2024-08-02 7:50 ` [PATCH RESEND v4 2/6] dmaengine: dw: Add memory " Serge Semin
2024-08-02 7:50 ` [PATCH RESEND v4 3/6] dmaengine: dw: Simplify prepare CTL_LO methods Serge Semin
2024-08-02 7:50 ` [PATCH RESEND v4 4/6] dmaengine: dw: Define encode_maxburst() above prepare_ctllo() callbacks Serge Semin
2024-08-02 7:50 ` Serge Semin [this message]
2024-08-02 7:50 ` [PATCH RESEND v4 6/6] dmaengine: dw: Unify ret-val local variables naming Serge Semin
2024-08-03 19:29 ` [PATCH RESEND v4 0/6] dmaengine: dw: Fix src/dst addr width misconfig Andy Shevchenko
2024-08-05 12:25 ` Serge Semin
2024-09-14 18:50 ` Andy Shevchenko
2024-09-14 19:06 ` Serge Semin
2024-09-14 19:08 ` Serge Semin
2024-09-15 11:43 ` Andy Shevchenko
2024-09-15 21:34 ` Serge Semin
2024-08-05 17:37 ` Vinod Koul
2024-08-29 17:30 ` Vinod Koul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240802075100.6475-6-fancer.lancer@gmail.com \
--to=fancer.lancer@gmail.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=andy@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=jirislaby@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=vireshk@kernel.org \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.