* [PATCH v7 1/8] dmaengine: add DMA_PREP_LOCK and DMA_PREP_UNLOCK flag
2025-03-11 9:25 [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Bartosz Golaszewski
@ 2025-03-11 9:25 ` Bartosz Golaszewski
2025-03-11 15:59 ` Dmitry Baryshkov
2025-03-30 16:20 ` Vinod Koul
2025-03-11 9:25 ` [PATCH v7 2/8] dmaengine: qcom: bam_dma: extend the driver's device match data Bartosz Golaszewski
` (7 subsequent siblings)
8 siblings, 2 replies; 15+ messages in thread
From: Bartosz Golaszewski @ 2025-03-11 9:25 UTC (permalink / raw)
To: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla
Cc: linux-crypto, linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
From: Md Sadre Alam <quic_mdalam@quicinc.com>
Add lock and unlock flags for the command descriptor. With the former set
in the requester pipe, the bam controller will lock all other pipes and
process the request only from requester pipe. Unlocking can only be
performed from the same pipe.
Setting the DMA_PREP_LOCK/DMA_PREP_UNLOCK flags in the command
descriptor means, the caller requests the BAM controller to be locked
for the duration of the transaction. In this case the BAM driver must
set the LOCK/UNLOCK bits in the HW descriptor respectively.
Only BAM IPs version 1.4.0 and above support the LOCK/UNLOCK feature.
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
[Bartosz: reworked the commit message]
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
Documentation/driver-api/dmaengine/provider.rst | 15 +++++++++++++++
include/linux/dmaengine.h | 6 ++++++
2 files changed, 21 insertions(+)
diff --git a/Documentation/driver-api/dmaengine/provider.rst b/Documentation/driver-api/dmaengine/provider.rst
index 3085f8b460fa..a032e55d0a4f 100644
--- a/Documentation/driver-api/dmaengine/provider.rst
+++ b/Documentation/driver-api/dmaengine/provider.rst
@@ -628,6 +628,21 @@ DMA_CTRL_REUSE
- This flag is only supported if the channel reports the DMA_LOAD_EOT
capability.
+- DMA_PREP_LOCK
+
+ - If set, the DMA will lock all other pipes not related to the current
+ pipe group, and keep handling the current pipe only.
+
+ - All pipes not within this group will be locked by this pipe upon lock
+ event.
+
+ - only pipes which are in the same group and relate to the same Environment
+ Execution(EE) will not be locked by a certain pipe.
+
+- DMA_PREP_UNLOCK
+
+ - If set, DMA will release all locked pipes
+
General Design Notes
====================
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 346251bf1026..8ebd43a998a7 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -200,6 +200,10 @@ struct dma_vec {
* transaction is marked with DMA_PREP_REPEAT will cause the new transaction
* to never be processed and stay in the issued queue forever. The flag is
* ignored if the previous transaction is not a repeated transaction.
+ * @DMA_PREP_LOCK: tell the driver that there is a lock bit set on command
+ * descriptor.
+ * @DMA_PREP_UNLOCK: tell the driver that there is a un-lock bit set on command
+ * descriptor.
*/
enum dma_ctrl_flags {
DMA_PREP_INTERRUPT = (1 << 0),
@@ -212,6 +216,8 @@ enum dma_ctrl_flags {
DMA_PREP_CMD = (1 << 7),
DMA_PREP_REPEAT = (1 << 8),
DMA_PREP_LOAD_EOT = (1 << 9),
+ DMA_PREP_LOCK = (1 << 10),
+ DMA_PREP_UNLOCK = (1 << 11),
};
/**
--
2.45.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v7 1/8] dmaengine: add DMA_PREP_LOCK and DMA_PREP_UNLOCK flag
2025-03-11 9:25 ` [PATCH v7 1/8] dmaengine: add DMA_PREP_LOCK and DMA_PREP_UNLOCK flag Bartosz Golaszewski
@ 2025-03-11 15:59 ` Dmitry Baryshkov
2025-03-30 16:20 ` Vinod Koul
1 sibling, 0 replies; 15+ messages in thread
From: Dmitry Baryshkov @ 2025-03-11 15:59 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla, linux-crypto,
linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
On Tue, Mar 11, 2025 at 10:25:32AM +0100, Bartosz Golaszewski wrote:
> From: Md Sadre Alam <quic_mdalam@quicinc.com>
>
> Add lock and unlock flags for the command descriptor. With the former set
> in the requester pipe, the bam controller will lock all other pipes and
> process the request only from requester pipe. Unlocking can only be
> performed from the same pipe.
>
> Setting the DMA_PREP_LOCK/DMA_PREP_UNLOCK flags in the command
> descriptor means, the caller requests the BAM controller to be locked
> for the duration of the transaction. In this case the BAM driver must
> set the LOCK/UNLOCK bits in the HW descriptor respectively.
>
> Only BAM IPs version 1.4.0 and above support the LOCK/UNLOCK feature.
You are describing behaviour (and even versions) of a particular DMA
hardware (BAM) in the commit message for a generic flag. Please drop all
of that. Generic code should be described in generic terms.
>
> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
> [Bartosz: reworked the commit message]
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---
> Documentation/driver-api/dmaengine/provider.rst | 15 +++++++++++++++
> include/linux/dmaengine.h | 6 ++++++
> 2 files changed, 21 insertions(+)
>
> diff --git a/Documentation/driver-api/dmaengine/provider.rst b/Documentation/driver-api/dmaengine/provider.rst
> index 3085f8b460fa..a032e55d0a4f 100644
> --- a/Documentation/driver-api/dmaengine/provider.rst
> +++ b/Documentation/driver-api/dmaengine/provider.rst
> @@ -628,6 +628,21 @@ DMA_CTRL_REUSE
> - This flag is only supported if the channel reports the DMA_LOAD_EOT
> capability.
>
> +- DMA_PREP_LOCK
> +
> + - If set, the DMA will lock all other pipes not related to the current
> + pipe group, and keep handling the current pipe only.
> +
> + - All pipes not within this group will be locked by this pipe upon lock
> + event.
> +
> + - only pipes which are in the same group and relate to the same Environment
> + Execution(EE) will not be locked by a certain pipe.
> +
> +- DMA_PREP_UNLOCK
> +
> + - If set, DMA will release all locked pipes
> +
> General Design Notes
> ====================
>
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 346251bf1026..8ebd43a998a7 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -200,6 +200,10 @@ struct dma_vec {
> * transaction is marked with DMA_PREP_REPEAT will cause the new transaction
> * to never be processed and stay in the issued queue forever. The flag is
> * ignored if the previous transaction is not a repeated transaction.
> + * @DMA_PREP_LOCK: tell the driver that there is a lock bit set on command
> + * descriptor.
> + * @DMA_PREP_UNLOCK: tell the driver that there is a un-lock bit set on command
> + * descriptor.
> */
> enum dma_ctrl_flags {
> DMA_PREP_INTERRUPT = (1 << 0),
> @@ -212,6 +216,8 @@ enum dma_ctrl_flags {
> DMA_PREP_CMD = (1 << 7),
> DMA_PREP_REPEAT = (1 << 8),
> DMA_PREP_LOAD_EOT = (1 << 9),
> + DMA_PREP_LOCK = (1 << 10),
> + DMA_PREP_UNLOCK = (1 << 11),
> };
>
> /**
>
> --
> 2.45.2
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v7 1/8] dmaengine: add DMA_PREP_LOCK and DMA_PREP_UNLOCK flag
2025-03-11 9:25 ` [PATCH v7 1/8] dmaengine: add DMA_PREP_LOCK and DMA_PREP_UNLOCK flag Bartosz Golaszewski
2025-03-11 15:59 ` Dmitry Baryshkov
@ 2025-03-30 16:20 ` Vinod Koul
1 sibling, 0 replies; 15+ messages in thread
From: Vinod Koul @ 2025-03-30 16:20 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Thara Gopinath, Herbert Xu, David S. Miller, Jonathan Corbet,
Md Sadre Alam, Srinivas Kandagatla, linux-crypto, linux-arm-msm,
linux-kernel, dmaengine, linux-doc, Bartosz Golaszewski
On 11-03-25, 10:25, Bartosz Golaszewski wrote:
> From: Md Sadre Alam <quic_mdalam@quicinc.com>
>
> Add lock and unlock flags for the command descriptor. With the former set
> in the requester pipe, the bam controller will lock all other pipes and
> process the request only from requester pipe. Unlocking can only be
> performed from the same pipe.
>
> Setting the DMA_PREP_LOCK/DMA_PREP_UNLOCK flags in the command
> descriptor means, the caller requests the BAM controller to be locked
> for the duration of the transaction. In this case the BAM driver must
> set the LOCK/UNLOCK bits in the HW descriptor respectively.
>
> Only BAM IPs version 1.4.0 and above support the LOCK/UNLOCK feature.
>
> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
> [Bartosz: reworked the commit message]
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---
> Documentation/driver-api/dmaengine/provider.rst | 15 +++++++++++++++
> include/linux/dmaengine.h | 6 ++++++
> 2 files changed, 21 insertions(+)
>
> diff --git a/Documentation/driver-api/dmaengine/provider.rst b/Documentation/driver-api/dmaengine/provider.rst
> index 3085f8b460fa..a032e55d0a4f 100644
> --- a/Documentation/driver-api/dmaengine/provider.rst
> +++ b/Documentation/driver-api/dmaengine/provider.rst
> @@ -628,6 +628,21 @@ DMA_CTRL_REUSE
> - This flag is only supported if the channel reports the DMA_LOAD_EOT
> capability.
>
> +- DMA_PREP_LOCK
> +
> + - If set, the DMA will lock all other pipes not related to the current
> + pipe group, and keep handling the current pipe only.
> +
> + - All pipes not within this group will be locked by this pipe upon lock
> + event.
> +
> + - only pipes which are in the same group and relate to the same Environment
> + Execution(EE) will not be locked by a certain pipe.
This does not make sense for me in generic context... Pipes and EEs are
implementation details... Please generalise the description for a
dma controller...
--
~Vinod
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v7 2/8] dmaengine: qcom: bam_dma: extend the driver's device match data
2025-03-11 9:25 [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Bartosz Golaszewski
2025-03-11 9:25 ` [PATCH v7 1/8] dmaengine: add DMA_PREP_LOCK and DMA_PREP_UNLOCK flag Bartosz Golaszewski
@ 2025-03-11 9:25 ` Bartosz Golaszewski
2025-03-11 16:00 ` Dmitry Baryshkov
2025-03-11 9:25 ` [PATCH v7 3/8] dmaengine: qcom: bam_dma: add bam_pipe_lock flag support Bartosz Golaszewski
` (6 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Bartosz Golaszewski @ 2025-03-11 9:25 UTC (permalink / raw)
To: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla
Cc: linux-crypto, linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
In preparation for supporting the pipe locking feature flag, extend the
amount of information we can carry in device match data: create a
separate structure and make the register information one of its fields.
This way, in subsequent patches, it will be just a matter of adding a
new field to the device data.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/dma/qcom/bam_dma.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 2cf060174795..8861245314b1 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -111,6 +111,10 @@ struct reg_offset_data {
unsigned int pipe_mult, evnt_mult, ee_mult;
};
+struct bam_device_data {
+ const struct reg_offset_data *reg_info;
+};
+
static const struct reg_offset_data bam_v1_3_reg_info[] = {
[BAM_CTRL] = { 0x0F80, 0x00, 0x00, 0x00 },
[BAM_REVISION] = { 0x0F84, 0x00, 0x00, 0x00 },
@@ -140,6 +144,10 @@ static const struct reg_offset_data bam_v1_3_reg_info[] = {
[BAM_P_FIFO_SIZES] = { 0x1020, 0x00, 0x40, 0x00 },
};
+static const struct bam_device_data bam_v1_3_data = {
+ .reg_info = bam_v1_3_reg_info,
+};
+
static const struct reg_offset_data bam_v1_4_reg_info[] = {
[BAM_CTRL] = { 0x0000, 0x00, 0x00, 0x00 },
[BAM_REVISION] = { 0x0004, 0x00, 0x00, 0x00 },
@@ -169,6 +177,10 @@ static const struct reg_offset_data bam_v1_4_reg_info[] = {
[BAM_P_FIFO_SIZES] = { 0x1820, 0x00, 0x1000, 0x00 },
};
+static const struct bam_device_data bam_v1_4_data = {
+ .reg_info = bam_v1_4_reg_info,
+};
+
static const struct reg_offset_data bam_v1_7_reg_info[] = {
[BAM_CTRL] = { 0x00000, 0x00, 0x00, 0x00 },
[BAM_REVISION] = { 0x01000, 0x00, 0x00, 0x00 },
@@ -198,6 +210,10 @@ static const struct reg_offset_data bam_v1_7_reg_info[] = {
[BAM_P_FIFO_SIZES] = { 0x13820, 0x00, 0x1000, 0x00 },
};
+static const struct bam_device_data bam_v1_7_data = {
+ .reg_info = bam_v1_7_reg_info,
+};
+
/* BAM CTRL */
#define BAM_SW_RST BIT(0)
#define BAM_EN BIT(1)
@@ -391,7 +407,7 @@ struct bam_device {
bool powered_remotely;
u32 active_channels;
- const struct reg_offset_data *layout;
+ const struct bam_device_data *dev_data;
struct clk *bamclk;
int irq;
@@ -409,7 +425,7 @@ struct bam_device {
static inline void __iomem *bam_addr(struct bam_device *bdev, u32 pipe,
enum bam_reg reg)
{
- const struct reg_offset_data r = bdev->layout[reg];
+ const struct reg_offset_data r = bdev->dev_data->reg_info[reg];
return bdev->regs + r.base_offset +
r.pipe_mult * pipe +
@@ -1225,9 +1241,9 @@ static void bam_channel_init(struct bam_device *bdev, struct bam_chan *bchan,
}
static const struct of_device_id bam_of_match[] = {
- { .compatible = "qcom,bam-v1.3.0", .data = &bam_v1_3_reg_info },
- { .compatible = "qcom,bam-v1.4.0", .data = &bam_v1_4_reg_info },
- { .compatible = "qcom,bam-v1.7.0", .data = &bam_v1_7_reg_info },
+ { .compatible = "qcom,bam-v1.3.0", .data = &bam_v1_3_data },
+ { .compatible = "qcom,bam-v1.4.0", .data = &bam_v1_4_data },
+ { .compatible = "qcom,bam-v1.7.0", .data = &bam_v1_7_data },
{}
};
@@ -1251,7 +1267,7 @@ static int bam_dma_probe(struct platform_device *pdev)
return -ENODEV;
}
- bdev->layout = match->data;
+ bdev->dev_data = match->data;
bdev->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(bdev->regs))
--
2.45.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v7 2/8] dmaengine: qcom: bam_dma: extend the driver's device match data
2025-03-11 9:25 ` [PATCH v7 2/8] dmaengine: qcom: bam_dma: extend the driver's device match data Bartosz Golaszewski
@ 2025-03-11 16:00 ` Dmitry Baryshkov
0 siblings, 0 replies; 15+ messages in thread
From: Dmitry Baryshkov @ 2025-03-11 16:00 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla, linux-crypto,
linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
On Tue, Mar 11, 2025 at 10:25:33AM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> In preparation for supporting the pipe locking feature flag, extend the
> amount of information we can carry in device match data: create a
> separate structure and make the register information one of its fields.
> This way, in subsequent patches, it will be just a matter of adding a
> new field to the device data.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---
> drivers/dma/qcom/bam_dma.c | 28 ++++++++++++++++++++++------
> 1 file changed, 22 insertions(+), 6 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <lumag@kernel.org>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v7 3/8] dmaengine: qcom: bam_dma: add bam_pipe_lock flag support
2025-03-11 9:25 [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Bartosz Golaszewski
2025-03-11 9:25 ` [PATCH v7 1/8] dmaengine: add DMA_PREP_LOCK and DMA_PREP_UNLOCK flag Bartosz Golaszewski
2025-03-11 9:25 ` [PATCH v7 2/8] dmaengine: qcom: bam_dma: extend the driver's device match data Bartosz Golaszewski
@ 2025-03-11 9:25 ` Bartosz Golaszewski
2025-03-11 16:02 ` Dmitry Baryshkov
2025-03-30 16:22 ` Vinod Koul
2025-03-11 9:25 ` [PATCH v7 4/8] crypto: qce - use devres to allocate the result buffer Bartosz Golaszewski
` (5 subsequent siblings)
8 siblings, 2 replies; 15+ messages in thread
From: Bartosz Golaszewski @ 2025-03-11 9:25 UTC (permalink / raw)
To: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla
Cc: linux-crypto, linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Extend the device match data with a flag indicating whether the IP
supports the BAM lock/unlock feature. Set it to true on BAM IP versions
1.4.0 and above.
Co-developed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/dma/qcom/bam_dma.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 8861245314b1..737fce396c2e 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -58,6 +58,8 @@ struct bam_desc_hw {
#define DESC_FLAG_EOB BIT(13)
#define DESC_FLAG_NWD BIT(12)
#define DESC_FLAG_CMD BIT(11)
+#define DESC_FLAG_LOCK BIT(10)
+#define DESC_FLAG_UNLOCK BIT(9)
struct bam_async_desc {
struct virt_dma_desc vd;
@@ -113,6 +115,7 @@ struct reg_offset_data {
struct bam_device_data {
const struct reg_offset_data *reg_info;
+ bool bam_pipe_lock;
};
static const struct reg_offset_data bam_v1_3_reg_info[] = {
@@ -179,6 +182,7 @@ static const struct reg_offset_data bam_v1_4_reg_info[] = {
static const struct bam_device_data bam_v1_4_data = {
.reg_info = bam_v1_4_reg_info,
+ .bam_pipe_lock = true,
};
static const struct reg_offset_data bam_v1_7_reg_info[] = {
@@ -212,6 +216,7 @@ static const struct reg_offset_data bam_v1_7_reg_info[] = {
static const struct bam_device_data bam_v1_7_data = {
.reg_info = bam_v1_7_reg_info,
+ .bam_pipe_lock = true,
};
/* BAM CTRL */
@@ -707,8 +712,15 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
unsigned int curr_offset = 0;
do {
- if (flags & DMA_PREP_CMD)
+ if (flags & DMA_PREP_CMD) {
desc->flags |= cpu_to_le16(DESC_FLAG_CMD);
+ if (bdev->dev_data->bam_pipe_lock) {
+ if (flags & DMA_PREP_LOCK)
+ desc->flags |= cpu_to_le16(DESC_FLAG_LOCK);
+ else if (flags & DMA_PREP_UNLOCK)
+ desc->flags |= cpu_to_le16(DESC_FLAG_UNLOCK);
+ }
+ }
desc->addr = cpu_to_le32(sg_dma_address(sg) +
curr_offset);
--
2.45.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v7 3/8] dmaengine: qcom: bam_dma: add bam_pipe_lock flag support
2025-03-11 9:25 ` [PATCH v7 3/8] dmaengine: qcom: bam_dma: add bam_pipe_lock flag support Bartosz Golaszewski
@ 2025-03-11 16:02 ` Dmitry Baryshkov
2025-03-30 16:22 ` Vinod Koul
1 sibling, 0 replies; 15+ messages in thread
From: Dmitry Baryshkov @ 2025-03-11 16:02 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla, linux-crypto,
linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
On Tue, Mar 11, 2025 at 10:25:34AM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> Extend the device match data with a flag indicating whether the IP
> supports the BAM lock/unlock feature. Set it to true on BAM IP versions
> 1.4.0 and above.
This is obvious from the patch itself. I think this might be a good
place for the description that you had in patch 1.
>
> Co-developed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---
> drivers/dma/qcom/bam_dma.c | 14 +++++++++++++-
> 1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
> index 8861245314b1..737fce396c2e 100644
> --- a/drivers/dma/qcom/bam_dma.c
> +++ b/drivers/dma/qcom/bam_dma.c
> @@ -58,6 +58,8 @@ struct bam_desc_hw {
> #define DESC_FLAG_EOB BIT(13)
> #define DESC_FLAG_NWD BIT(12)
> #define DESC_FLAG_CMD BIT(11)
> +#define DESC_FLAG_LOCK BIT(10)
> +#define DESC_FLAG_UNLOCK BIT(9)
>
> struct bam_async_desc {
> struct virt_dma_desc vd;
> @@ -113,6 +115,7 @@ struct reg_offset_data {
>
> struct bam_device_data {
> const struct reg_offset_data *reg_info;
> + bool bam_pipe_lock;
> };
>
> static const struct reg_offset_data bam_v1_3_reg_info[] = {
> @@ -179,6 +182,7 @@ static const struct reg_offset_data bam_v1_4_reg_info[] = {
>
> static const struct bam_device_data bam_v1_4_data = {
> .reg_info = bam_v1_4_reg_info,
> + .bam_pipe_lock = true,
> };
>
> static const struct reg_offset_data bam_v1_7_reg_info[] = {
> @@ -212,6 +216,7 @@ static const struct reg_offset_data bam_v1_7_reg_info[] = {
>
> static const struct bam_device_data bam_v1_7_data = {
> .reg_info = bam_v1_7_reg_info,
> + .bam_pipe_lock = true,
> };
>
> /* BAM CTRL */
> @@ -707,8 +712,15 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
> unsigned int curr_offset = 0;
>
> do {
> - if (flags & DMA_PREP_CMD)
> + if (flags & DMA_PREP_CMD) {
> desc->flags |= cpu_to_le16(DESC_FLAG_CMD);
> + if (bdev->dev_data->bam_pipe_lock) {
> + if (flags & DMA_PREP_LOCK)
> + desc->flags |= cpu_to_le16(DESC_FLAG_LOCK);
> + else if (flags & DMA_PREP_UNLOCK)
> + desc->flags |= cpu_to_le16(DESC_FLAG_UNLOCK);
Should it fail if there is no support for those flags?
Is it an error to set the UNLOCK flag if there was no LOCK set
beforehand?
> + }
> + }
>
> desc->addr = cpu_to_le32(sg_dma_address(sg) +
> curr_offset);
>
> --
> 2.45.2
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v7 3/8] dmaengine: qcom: bam_dma: add bam_pipe_lock flag support
2025-03-11 9:25 ` [PATCH v7 3/8] dmaengine: qcom: bam_dma: add bam_pipe_lock flag support Bartosz Golaszewski
2025-03-11 16:02 ` Dmitry Baryshkov
@ 2025-03-30 16:22 ` Vinod Koul
1 sibling, 0 replies; 15+ messages in thread
From: Vinod Koul @ 2025-03-30 16:22 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Thara Gopinath, Herbert Xu, David S. Miller, Jonathan Corbet,
Md Sadre Alam, Srinivas Kandagatla, linux-crypto, linux-arm-msm,
linux-kernel, dmaengine, linux-doc, Bartosz Golaszewski
On 11-03-25, 10:25, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> Extend the device match data with a flag indicating whether the IP
> supports the BAM lock/unlock feature. Set it to true on BAM IP versions
> 1.4.0 and above.
>
> Co-developed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
> Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---
> drivers/dma/qcom/bam_dma.c | 14 +++++++++++++-
> 1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
> index 8861245314b1..737fce396c2e 100644
> --- a/drivers/dma/qcom/bam_dma.c
> +++ b/drivers/dma/qcom/bam_dma.c
> @@ -58,6 +58,8 @@ struct bam_desc_hw {
> #define DESC_FLAG_EOB BIT(13)
> #define DESC_FLAG_NWD BIT(12)
> #define DESC_FLAG_CMD BIT(11)
> +#define DESC_FLAG_LOCK BIT(10)
> +#define DESC_FLAG_UNLOCK BIT(9)
>
> struct bam_async_desc {
> struct virt_dma_desc vd;
> @@ -113,6 +115,7 @@ struct reg_offset_data {
>
> struct bam_device_data {
> const struct reg_offset_data *reg_info;
> + bool bam_pipe_lock;
> };
>
> static const struct reg_offset_data bam_v1_3_reg_info[] = {
> @@ -179,6 +182,7 @@ static const struct reg_offset_data bam_v1_4_reg_info[] = {
>
> static const struct bam_device_data bam_v1_4_data = {
> .reg_info = bam_v1_4_reg_info,
> + .bam_pipe_lock = true,
> };
>
> static const struct reg_offset_data bam_v1_7_reg_info[] = {
> @@ -212,6 +216,7 @@ static const struct reg_offset_data bam_v1_7_reg_info[] = {
>
> static const struct bam_device_data bam_v1_7_data = {
> .reg_info = bam_v1_7_reg_info,
> + .bam_pipe_lock = true,
> };
>
> /* BAM CTRL */
> @@ -707,8 +712,15 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
> unsigned int curr_offset = 0;
>
> do {
> - if (flags & DMA_PREP_CMD)
> + if (flags & DMA_PREP_CMD) {
> desc->flags |= cpu_to_le16(DESC_FLAG_CMD);
> + if (bdev->dev_data->bam_pipe_lock) {
> + if (flags & DMA_PREP_LOCK)
> + desc->flags |= cpu_to_le16(DESC_FLAG_LOCK);
> + else if (flags & DMA_PREP_UNLOCK)
> + desc->flags |= cpu_to_le16(DESC_FLAG_UNLOCK);
> + }
No else case? you are ignoring the flags passed by user...? This should
return an error...
--
~Vinod
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v7 4/8] crypto: qce - use devres to allocate the result buffer
2025-03-11 9:25 [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Bartosz Golaszewski
` (2 preceding siblings ...)
2025-03-11 9:25 ` [PATCH v7 3/8] dmaengine: qcom: bam_dma: add bam_pipe_lock flag support Bartosz Golaszewski
@ 2025-03-11 9:25 ` Bartosz Golaszewski
2025-03-11 9:25 ` [PATCH v7 5/8] crypto: qce - Map crypto memory for DMA Bartosz Golaszewski
` (4 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Bartosz Golaszewski @ 2025-03-11 9:25 UTC (permalink / raw)
To: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla
Cc: linux-crypto, linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Switch to devm_kmalloc for allocating the result_buf. This allows us to
drop two labels and make the devm action callback for DMA channels
smaller.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/crypto/qce/dma.c | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c
index 1dec7aea852d..6ac2efb7c2f7 100644
--- a/drivers/crypto/qce/dma.c
+++ b/drivers/crypto/qce/dma.c
@@ -15,7 +15,6 @@ static void qce_dma_release(void *data)
dma_release_channel(dma->txchan);
dma_release_channel(dma->rxchan);
- kfree(dma->result_buf);
}
int devm_qce_dma_request(struct device *dev, struct qce_dma_data *dma)
@@ -28,26 +27,23 @@ int devm_qce_dma_request(struct device *dev, struct qce_dma_data *dma)
dma->rxchan = dma_request_chan(dev, "rx");
if (IS_ERR(dma->rxchan)) {
- ret = PTR_ERR(dma->rxchan);
- goto error_rx;
+ dma_release_channel(dma->txchan);
+ return PTR_ERR(dma->rxchan);
}
- dma->result_buf = kmalloc(QCE_RESULT_BUF_SZ + QCE_IGNORE_BUF_SZ,
- GFP_KERNEL);
- if (!dma->result_buf) {
- ret = -ENOMEM;
- goto error_nomem;
- }
+ ret = devm_add_action_or_reset(dev, qce_dma_release, dma);
+ if (ret)
+ return ret;
+
+ dma->result_buf = devm_kmalloc(dev,
+ QCE_RESULT_BUF_SZ + QCE_IGNORE_BUF_SZ,
+ GFP_KERNEL);
+ if (!dma->result_buf)
+ return -ENOMEM;
dma->ignore_buf = dma->result_buf + QCE_RESULT_BUF_SZ;
- return devm_add_action_or_reset(dev, qce_dma_release, dma);
-
-error_nomem:
- dma_release_channel(dma->rxchan);
-error_rx:
- dma_release_channel(dma->txchan);
- return ret;
+ return 0;
}
struct scatterlist *
--
2.45.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v7 5/8] crypto: qce - Map crypto memory for DMA
2025-03-11 9:25 [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Bartosz Golaszewski
` (3 preceding siblings ...)
2025-03-11 9:25 ` [PATCH v7 4/8] crypto: qce - use devres to allocate the result buffer Bartosz Golaszewski
@ 2025-03-11 9:25 ` Bartosz Golaszewski
2025-03-11 9:25 ` [PATCH v7 6/8] crypto: qce - Add BAM DMA support for crypto register I/O Bartosz Golaszewski
` (3 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Bartosz Golaszewski @ 2025-03-11 9:25 UTC (permalink / raw)
To: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla
Cc: linux-crypto, linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
From: Md Sadre Alam <quic_mdalam@quicinc.com>
In preparation for supporting command descriptors, map the crypto memory
range for DMA.
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
[Bartosz: add kerneldocs, fix DMA mapping leak, rework commit message]
Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/crypto/qce/core.c | 24 ++++++++++++++++++++++--
drivers/crypto/qce/core.h | 4 ++++
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c
index e95e84486d9a..b21c4ecd2034 100644
--- a/drivers/crypto/qce/core.c
+++ b/drivers/crypto/qce/core.c
@@ -187,10 +187,19 @@ static int qce_check_version(struct qce_device *qce)
return 0;
}
+static void qce_crypto_unmap_dma(void *data)
+{
+ struct qce_device *qce = data;
+
+ dma_unmap_resource(qce->dev, qce->base_dma, qce->dma_size,
+ DMA_BIDIRECTIONAL, 0);
+}
+
static int qce_crypto_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct qce_device *qce;
+ struct resource *res;
int ret;
qce = devm_kzalloc(dev, sizeof(*qce), GFP_KERNEL);
@@ -200,7 +209,7 @@ static int qce_crypto_probe(struct platform_device *pdev)
qce->dev = dev;
platform_set_drvdata(pdev, qce);
- qce->base = devm_platform_ioremap_resource(pdev, 0);
+ qce->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(qce->base))
return PTR_ERR(qce->base);
@@ -246,7 +255,18 @@ static int qce_crypto_probe(struct platform_device *pdev)
qce->async_req_enqueue = qce_async_request_enqueue;
qce->async_req_done = qce_async_request_done;
- return devm_qce_register_algs(qce);
+ ret = devm_qce_register_algs(qce);
+ if (ret)
+ return ret;
+
+ qce->dma_size = resource_size(res);
+ qce->base_dma = dma_map_resource(dev, res->start, qce->dma_size,
+ DMA_BIDIRECTIONAL, 0);
+ ret = dma_mapping_error(dev, qce->base_dma);
+ if (ret)
+ return ret;
+
+ return devm_add_action_or_reset(qce->dev, qce_crypto_unmap_dma, qce);
}
static const struct of_device_id qce_crypto_of_match[] = {
diff --git a/drivers/crypto/qce/core.h b/drivers/crypto/qce/core.h
index eb6fa7a8b64a..b86caf8b926d 100644
--- a/drivers/crypto/qce/core.h
+++ b/drivers/crypto/qce/core.h
@@ -26,6 +26,8 @@
* @dma: pointer to dma data
* @burst_size: the crypto burst size
* @pipe_pair_id: which pipe pair id the device using
+ * @base_dma: base DMA address
+ * @dma_size: size of memory mapped for DMA
* @async_req_enqueue: invoked by every algorithm to enqueue a request
* @async_req_done: invoked by every algorithm to finish its request
*/
@@ -42,6 +44,8 @@ struct qce_device {
struct qce_dma_data dma;
int burst_size;
unsigned int pipe_pair_id;
+ dma_addr_t base_dma;
+ size_t dma_size;
int (*async_req_enqueue)(struct qce_device *qce,
struct crypto_async_request *req);
void (*async_req_done)(struct qce_device *qce, int ret);
--
2.45.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v7 6/8] crypto: qce - Add BAM DMA support for crypto register I/O
2025-03-11 9:25 [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Bartosz Golaszewski
` (4 preceding siblings ...)
2025-03-11 9:25 ` [PATCH v7 5/8] crypto: qce - Map crypto memory for DMA Bartosz Golaszewski
@ 2025-03-11 9:25 ` Bartosz Golaszewski
2025-03-11 9:25 ` [PATCH v7 7/8] crypto: qce - Switch to using DMA Bartosz Golaszewski
` (2 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Bartosz Golaszewski @ 2025-03-11 9:25 UTC (permalink / raw)
To: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla
Cc: linux-crypto, linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
From: Md Sadre Alam <quic_mdalam@quicinc.com>
Add BAM/DMA support infrastructure. These interfaces will allow us to
port the algorithm implementations to use DMA for transaction with BAM
locking.
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
[Bartosz: remove unused code, rework coding style, shuffle code around
for better readability, simplify resource management, many other tweaks]
Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/crypto/qce/dma.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++
drivers/crypto/qce/dma.h | 17 ++++++
2 files changed, 156 insertions(+)
diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c
index 6ac2efb7c2f7..71b191944e3f 100644
--- a/drivers/crypto/qce/dma.c
+++ b/drivers/crypto/qce/dma.c
@@ -5,10 +5,135 @@
#include <linux/device.h>
#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
#include <crypto/scatterwalk.h>
+#include "core.h"
#include "dma.h"
+struct qce_bam_transaction {
+ struct bam_cmd_element qce_bam_ce[QCE_BAM_CMD_ELEMENT_SIZE];
+ struct scatterlist qce_reg_write_sgl[QCE_BAM_CMD_SGL_SIZE];
+ struct qce_desc_info *qce_desc;
+ u32 qce_bam_ce_index;
+ u32 qce_pre_bam_ce_index;
+ u32 qce_write_sgl_cnt;
+};
+
+void qce_clear_bam_transaction(struct qce_device *qce)
+{
+ struct qce_bam_transaction *qce_bam_txn = qce->dma.qce_bam_txn;
+
+ memset(&qce_bam_txn->qce_bam_ce_index, 0, sizeof(u32) * 8);
+}
+
+static int qce_dma_prep_cmd_sg(struct qce_device *qce, struct dma_chan *chan,
+ struct scatterlist *qce_bam_sgl,
+ int qce_sgl_cnt, unsigned long flags,
+ enum dma_transfer_direction dir_eng,
+ dma_async_tx_callback cb, void *cb_param)
+{
+ struct dma_async_tx_descriptor *dma_desc;
+ struct qce_desc_info *desc;
+ dma_cookie_t cookie;
+
+ desc = qce->dma.qce_bam_txn->qce_desc;
+
+ if (dir_eng == DMA_MEM_TO_DEV)
+ desc->dir = DMA_TO_DEVICE;
+ if (dir_eng == DMA_DEV_TO_MEM)
+ desc->dir = DMA_FROM_DEVICE;
+
+ if (!qce_bam_sgl || !qce_sgl_cnt)
+ return -EINVAL;
+
+ if (!dma_map_sg(qce->dev, qce_bam_sgl,
+ qce_sgl_cnt, desc->dir)) {
+ dev_err(qce->dev, "failure in mapping sgl for cmd desc\n");
+ return -ENOMEM;
+ }
+
+ dma_desc = dmaengine_prep_slave_sg(chan, qce_bam_sgl, qce_sgl_cnt,
+ dir_eng, flags);
+ if (!dma_desc) {
+ dev_err(qce->dev, "failed to prepare the command descriptor\n");
+ dma_unmap_sg(qce->dev, qce_bam_sgl, qce_sgl_cnt, desc->dir);
+ kfree(desc);
+ return -EINVAL;
+ }
+
+ desc->dma_desc = dma_desc;
+ desc->dma_desc->callback = cb;
+ desc->dma_desc->callback_param = cb_param;
+
+ cookie = dmaengine_submit(desc->dma_desc);
+
+ return dma_submit_error(cookie);
+}
+
+int qce_submit_cmd_desc(struct qce_device *qce, unsigned long flags)
+{
+ struct qce_bam_transaction *qce_bam_txn = qce->dma.qce_bam_txn;
+ struct dma_chan *chan = qce->dma.rxchan;
+ unsigned long desc_flags;
+ int ret = 0;
+
+ desc_flags = DMA_PREP_CMD;
+
+ /*
+ * The HPG recommends always using the consumer pipe for command
+ * descriptors.
+ */
+ if (qce_bam_txn->qce_write_sgl_cnt)
+ ret = qce_dma_prep_cmd_sg(qce, chan, qce_bam_txn->qce_reg_write_sgl,
+ qce_bam_txn->qce_write_sgl_cnt,
+ desc_flags, DMA_MEM_TO_DEV,
+ NULL, NULL);
+ if (ret) {
+ dev_err(qce->dev,
+ "error while submitting the command descriptor for TX: %d\n",
+ ret);
+ return ret;
+ }
+
+ qce_dma_issue_pending(&qce->dma);
+
+ if (qce_bam_txn->qce_write_sgl_cnt)
+ dma_unmap_sg(qce->dev, qce_bam_txn->qce_reg_write_sgl,
+ qce_bam_txn->qce_write_sgl_cnt,
+ DMA_TO_DEVICE);
+
+ return ret;
+}
+
+static __maybe_unused void
+qce_prep_dma_command_desc(struct qce_device *qce, struct qce_dma_data *dma,
+ unsigned int addr, void *buff)
+{
+ struct qce_bam_transaction *qce_bam_txn = dma->qce_bam_txn;
+ struct bam_cmd_element *qce_bam_ce_buffer;
+ int qce_bam_ce_size, cnt, index;
+
+ index = qce_bam_txn->qce_bam_ce_index;
+ qce_bam_ce_buffer = &qce_bam_txn->qce_bam_ce[index];
+ bam_prep_ce_le32(qce_bam_ce_buffer, addr, BAM_WRITE_COMMAND,
+ *((__le32 *)buff));
+
+ cnt = qce_bam_txn->qce_write_sgl_cnt;
+ qce_bam_ce_buffer =
+ &qce_bam_txn->qce_bam_ce[qce_bam_txn->qce_pre_bam_ce_index];
+ ++qce_bam_txn->qce_bam_ce_index;
+ qce_bam_ce_size = (qce_bam_txn->qce_bam_ce_index -
+ qce_bam_txn->qce_pre_bam_ce_index) *
+ sizeof(struct bam_cmd_element);
+
+ sg_set_buf(&qce_bam_txn->qce_reg_write_sgl[cnt], qce_bam_ce_buffer,
+ qce_bam_ce_size);
+
+ ++qce_bam_txn->qce_write_sgl_cnt;
+ qce_bam_txn->qce_pre_bam_ce_index = qce_bam_txn->qce_bam_ce_index;
+}
+
static void qce_dma_release(void *data)
{
struct qce_dma_data *dma = data;
@@ -19,6 +144,7 @@ static void qce_dma_release(void *data)
int devm_qce_dma_request(struct device *dev, struct qce_dma_data *dma)
{
+ struct qce_bam_transaction *qce_bam_txn;
int ret;
dma->txchan = dma_request_chan(dev, "tx");
@@ -43,6 +169,19 @@ int devm_qce_dma_request(struct device *dev, struct qce_dma_data *dma)
dma->ignore_buf = dma->result_buf + QCE_RESULT_BUF_SZ;
+ dma->qce_bam_txn = devm_kmalloc(dev, sizeof(*qce_bam_txn), GFP_KERNEL);
+ if (!dma->qce_bam_txn)
+ return -ENOMEM;
+
+ dma->qce_bam_txn->qce_desc = devm_kzalloc(dev,
+ sizeof(*dma->qce_bam_txn->qce_desc),
+ GFP_KERNEL);
+ if (!dma->qce_bam_txn->qce_desc)
+ return -ENOMEM;
+
+ sg_init_table(dma->qce_bam_txn->qce_reg_write_sgl,
+ QCE_BAM_CMD_SGL_SIZE);
+
return 0;
}
diff --git a/drivers/crypto/qce/dma.h b/drivers/crypto/qce/dma.h
index 31629185000e..7d9d58b414ed 100644
--- a/drivers/crypto/qce/dma.h
+++ b/drivers/crypto/qce/dma.h
@@ -6,14 +6,22 @@
#ifndef _DMA_H_
#define _DMA_H_
+#include <linux/dma/qcom_bam_dma.h>
#include <linux/dmaengine.h>
+struct qce_device;
+
/* maximum data transfer block size between BAM and CE */
#define QCE_BAM_BURST_SIZE 64
#define QCE_AUTHIV_REGS_CNT 16
#define QCE_AUTH_BYTECOUNT_REGS_CNT 4
#define QCE_CNTRIV_REGS_CNT 4
+#define QCE_BAM_CMD_SGL_SIZE 64
+#define QCE_BAM_CMD_ELEMENT_SIZE 64
+#define QCE_DMA_DESC_FLAG_BAM_NWD (0x0004)
+#define QCE_MAX_REG_READ 8
+
struct qce_result_dump {
u32 auth_iv[QCE_AUTHIV_REGS_CNT];
@@ -31,9 +39,15 @@ struct qce_dma_data {
struct dma_chan *txchan;
struct dma_chan *rxchan;
struct qce_result_dump *result_buf;
+ struct qce_bam_transaction *qce_bam_txn;
void *ignore_buf;
};
+struct qce_desc_info {
+ struct dma_async_tx_descriptor *dma_desc;
+ enum dma_data_direction dir;
+};
+
int devm_qce_dma_request(struct device *dev, struct qce_dma_data *dma);
int qce_dma_prep_sgs(struct qce_dma_data *dma, struct scatterlist *sg_in,
int in_ents, struct scatterlist *sg_out, int out_ents,
@@ -44,4 +58,7 @@ struct scatterlist *
qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add,
unsigned int max_len);
+void qce_clear_bam_transaction(struct qce_device *qce);
+int qce_submit_cmd_desc(struct qce_device *qce, unsigned long flags);
+
#endif /* _DMA_H_ */
--
2.45.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v7 7/8] crypto: qce - Switch to using DMA
2025-03-11 9:25 [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Bartosz Golaszewski
` (5 preceding siblings ...)
2025-03-11 9:25 ` [PATCH v7 6/8] crypto: qce - Add BAM DMA support for crypto register I/O Bartosz Golaszewski
@ 2025-03-11 9:25 ` Bartosz Golaszewski
2025-03-11 9:25 ` [PATCH v7 8/8] crypto: qce - Add support for BAM locking Bartosz Golaszewski
2025-03-21 9:06 ` [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Herbert Xu
8 siblings, 0 replies; 15+ messages in thread
From: Bartosz Golaszewski @ 2025-03-11 9:25 UTC (permalink / raw)
To: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla
Cc: linux-crypto, linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Replace the qce_write() implementation with one that uses DMA. Convert
all algorithm implementations to use command descriptors. This makes the
driver use BAM DMA exclusively instead of register read/writes.
Co-developed-by: Md Sadre Alam <quic_mdalam@quicinc.com>
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/crypto/qce/common.c | 17 +++++++++--------
drivers/crypto/qce/common.h | 1 +
drivers/crypto/qce/dma.c | 13 ++++++++++---
3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/drivers/crypto/qce/common.c b/drivers/crypto/qce/common.c
index 04253a8d3340..80984e853454 100644
--- a/drivers/crypto/qce/common.c
+++ b/drivers/crypto/qce/common.c
@@ -23,11 +23,6 @@ static inline u32 qce_read(struct qce_device *qce, u32 offset)
return readl(qce->base + offset);
}
-static inline void qce_write(struct qce_device *qce, u32 offset, u32 val)
-{
- writel(val, qce->base + offset);
-}
-
static inline void qce_write_array(struct qce_device *qce, u32 offset,
const u32 *val, unsigned int len)
{
@@ -157,11 +152,13 @@ static int qce_setup_regs_ahash(struct crypto_async_request *async_req)
__be32 mackey[QCE_SHA_HMAC_KEY_SIZE / sizeof(__be32)] = {0};
u32 auth_cfg = 0, config;
unsigned int iv_words;
+ int ret;
/* if not the last, the size has to be on the block boundary */
if (!rctx->last_blk && req->nbytes % blocksize)
return -EINVAL;
+ qce_clear_bam_transaction(qce);
qce_setup_config(qce);
if (IS_CMAC(rctx->flags)) {
@@ -225,7 +222,7 @@ static int qce_setup_regs_ahash(struct crypto_async_request *async_req)
qce_crypto_go(qce, true);
- return 0;
+ return qce_submit_cmd_desc(qce, 0);
}
#endif
@@ -325,7 +322,9 @@ static int qce_setup_regs_skcipher(struct crypto_async_request *async_req)
u32 encr_cfg = 0, auth_cfg = 0, config;
unsigned int ivsize = rctx->ivsize;
unsigned long flags = rctx->flags;
+ int ret;
+ qce_clear_bam_transaction(qce);
qce_setup_config(qce);
if (IS_XTS(flags))
@@ -388,7 +387,7 @@ static int qce_setup_regs_skcipher(struct crypto_async_request *async_req)
qce_crypto_go(qce, true);
- return 0;
+ return qce_submit_cmd_desc(qce, 0);
}
#endif
@@ -438,7 +437,9 @@ static int qce_setup_regs_aead(struct crypto_async_request *async_req)
unsigned long flags = rctx->flags;
u32 encr_cfg, auth_cfg, config, totallen;
u32 iv_last_word;
+ int ret;
+ qce_clear_bam_transaction(qce);
qce_setup_config(qce);
/* Write encryption key */
@@ -537,7 +538,7 @@ static int qce_setup_regs_aead(struct crypto_async_request *async_req)
/* Start the process */
qce_crypto_go(qce, !IS_CCM(flags));
- return 0;
+ return qce_submit_cmd_desc(qce, 0);
}
#endif
diff --git a/drivers/crypto/qce/common.h b/drivers/crypto/qce/common.h
index 02e63ad9f245..ec58c1b6aa36 100644
--- a/drivers/crypto/qce/common.h
+++ b/drivers/crypto/qce/common.h
@@ -100,5 +100,6 @@ void qce_cpu_to_be32p_array(__be32 *dst, const u8 *src, unsigned int len);
int qce_check_status(struct qce_device *qce, u32 *status);
void qce_get_version(struct qce_device *qce, u32 *major, u32 *minor, u32 *step);
int qce_start(struct crypto_async_request *async_req, u32 type);
+void qce_write(struct qce_device *qce, unsigned int offset, u32 val);
#endif /* _COMMON_H_ */
diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c
index 71b191944e3f..b8b305fc1b6a 100644
--- a/drivers/crypto/qce/dma.c
+++ b/drivers/crypto/qce/dma.c
@@ -8,6 +8,7 @@
#include <linux/dma-mapping.h>
#include <crypto/scatterwalk.h>
+#include "common.h"
#include "core.h"
#include "dma.h"
@@ -106,9 +107,9 @@ int qce_submit_cmd_desc(struct qce_device *qce, unsigned long flags)
return ret;
}
-static __maybe_unused void
-qce_prep_dma_command_desc(struct qce_device *qce, struct qce_dma_data *dma,
- unsigned int addr, void *buff)
+static void qce_prep_dma_command_desc(struct qce_device *qce,
+ struct qce_dma_data *dma,
+ unsigned int addr, void *buff)
{
struct qce_bam_transaction *qce_bam_txn = dma->qce_bam_txn;
struct bam_cmd_element *qce_bam_ce_buffer;
@@ -134,6 +135,12 @@ qce_prep_dma_command_desc(struct qce_device *qce, struct qce_dma_data *dma,
qce_bam_txn->qce_pre_bam_ce_index = qce_bam_txn->qce_bam_ce_index;
}
+void qce_write(struct qce_device *qce, unsigned int offset, u32 val)
+{
+ qce_prep_dma_command_desc(qce, &qce->dma, (qce->base_dma + offset),
+ &val);
+}
+
static void qce_dma_release(void *data)
{
struct qce_dma_data *dma = data;
--
2.45.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v7 8/8] crypto: qce - Add support for BAM locking
2025-03-11 9:25 [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Bartosz Golaszewski
` (6 preceding siblings ...)
2025-03-11 9:25 ` [PATCH v7 7/8] crypto: qce - Switch to using DMA Bartosz Golaszewski
@ 2025-03-11 9:25 ` Bartosz Golaszewski
2025-03-21 9:06 ` [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Herbert Xu
8 siblings, 0 replies; 15+ messages in thread
From: Bartosz Golaszewski @ 2025-03-11 9:25 UTC (permalink / raw)
To: Thara Gopinath, Herbert Xu, David S. Miller, Vinod Koul,
Jonathan Corbet, Md Sadre Alam, Srinivas Kandagatla
Cc: linux-crypto, linux-arm-msm, linux-kernel, dmaengine, linux-doc,
Bartosz Golaszewski
From: Md Sadre Alam <quic_mdalam@quicinc.com>
The BAM driver now supports command descriptor locking. Add helper
functions that perform the dummy writes and acquire/release the lock and
use them across the supported algos. With this: if mutliple execution
environments (e.g.: a trusted app and linux) try to access the same
crypto engine, we can serialize their accesses.
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
[Bartosz: rework the coding style, naming convention, commit message and
ifdef logic]
Co-developed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/crypto/qce/aead.c | 4 ++++
drivers/crypto/qce/common.c | 30 ++++++++++++++++++++++++++++++
drivers/crypto/qce/core.h | 3 +++
drivers/crypto/qce/dma.c | 4 ++++
drivers/crypto/qce/dma.h | 2 ++
drivers/crypto/qce/sha.c | 4 ++++
drivers/crypto/qce/skcipher.c | 4 ++++
7 files changed, 51 insertions(+)
diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c
index 11cec08544c9..5d45841c029e 100644
--- a/drivers/crypto/qce/aead.c
+++ b/drivers/crypto/qce/aead.c
@@ -63,6 +63,8 @@ static void qce_aead_done(void *data)
sg_free_table(&rctx->dst_tbl);
}
+ qce_bam_unlock(qce);
+
error = qce_check_status(qce, &status);
if (error < 0 && (error != -EBADMSG))
dev_err(qce->dev, "aead operation error (%x)\n", status);
@@ -433,6 +435,8 @@ qce_aead_async_req_handle(struct crypto_async_request *async_req)
else
rctx->assoclen = req->assoclen;
+ qce_bam_lock(qce);
+
diff_dst = (req->src != req->dst) ? true : false;
dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL;
diff --git a/drivers/crypto/qce/common.c b/drivers/crypto/qce/common.c
index 80984e853454..251bf3cb1dd5 100644
--- a/drivers/crypto/qce/common.c
+++ b/drivers/crypto/qce/common.c
@@ -565,6 +565,36 @@ int qce_start(struct crypto_async_request *async_req, u32 type)
#define STATUS_ERRORS \
(BIT(SW_ERR_SHIFT) | BIT(AXI_ERR_SHIFT) | BIT(HSD_ERR_SHIFT))
+void qce_bam_lock(struct qce_device *qce)
+{
+ int ret;
+
+ qce_clear_bam_transaction(qce);
+
+ /* This is just a dummy write to acquire the lock on the BAM pipe. */
+ qce_write(qce, REG_AUTH_SEG_CFG, 0);
+
+ ret = qce_submit_cmd_desc(qce, QCE_DMA_DESC_FLAG_LOCK);
+ if (ret)
+ dev_err(qce->dev,
+ "Failed to lock the command descriptor: %d\n", ret);
+}
+
+void qce_bam_unlock(struct qce_device *qce)
+{
+ int ret;
+
+ qce_clear_bam_transaction(qce);
+
+ /* This just dummy write to release the lock on the BAM pipe. */
+ qce_write(qce, REG_AUTH_SEG_CFG, 0);
+
+ ret = qce_submit_cmd_desc(qce, QCE_DMA_DESC_FLAG_UNLOCK);
+ if (ret)
+ dev_err(qce->dev,
+ "Failed to unlock the command descriptor: %d\n", ret);
+}
+
int qce_check_status(struct qce_device *qce, u32 *status)
{
int ret = 0;
diff --git a/drivers/crypto/qce/core.h b/drivers/crypto/qce/core.h
index b86caf8b926d..3341571991a4 100644
--- a/drivers/crypto/qce/core.h
+++ b/drivers/crypto/qce/core.h
@@ -65,4 +65,7 @@ struct qce_algo_ops {
int (*async_req_handle)(struct crypto_async_request *async_req);
};
+void qce_bam_lock(struct qce_device *qce);
+void qce_bam_unlock(struct qce_device *qce);
+
#endif /* _CORE_H_ */
diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c
index b8b305fc1b6a..f3178144fa94 100644
--- a/drivers/crypto/qce/dma.c
+++ b/drivers/crypto/qce/dma.c
@@ -80,6 +80,10 @@ int qce_submit_cmd_desc(struct qce_device *qce, unsigned long flags)
int ret = 0;
desc_flags = DMA_PREP_CMD;
+ if (flags & QCE_DMA_DESC_FLAG_LOCK)
+ desc_flags |= DMA_PREP_LOCK;
+ else if (flags & QCE_DMA_DESC_FLAG_UNLOCK)
+ desc_flags |= DMA_PREP_UNLOCK;
/*
* The HPG recommends always using the consumer pipe for command
diff --git a/drivers/crypto/qce/dma.h b/drivers/crypto/qce/dma.h
index 7d9d58b414ed..c98dcab1dc62 100644
--- a/drivers/crypto/qce/dma.h
+++ b/drivers/crypto/qce/dma.h
@@ -21,6 +21,8 @@ struct qce_device;
#define QCE_BAM_CMD_ELEMENT_SIZE 64
#define QCE_DMA_DESC_FLAG_BAM_NWD (0x0004)
#define QCE_MAX_REG_READ 8
+#define QCE_DMA_DESC_FLAG_LOCK (0x0002)
+#define QCE_DMA_DESC_FLAG_UNLOCK (0x0001)
struct qce_result_dump {
diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c
index 0c7aab711b7b..4c701fca16f2 100644
--- a/drivers/crypto/qce/sha.c
+++ b/drivers/crypto/qce/sha.c
@@ -60,6 +60,8 @@ static void qce_ahash_done(void *data)
rctx->byte_count[0] = cpu_to_be32(result->auth_byte_count[0]);
rctx->byte_count[1] = cpu_to_be32(result->auth_byte_count[1]);
+ qce_bam_unlock(qce);
+
error = qce_check_status(qce, &status);
if (error < 0)
dev_dbg(qce->dev, "ahash operation error (%x)\n", status);
@@ -90,6 +92,8 @@ static int qce_ahash_async_req_handle(struct crypto_async_request *async_req)
rctx->authklen = AES_KEYSIZE_128;
}
+ qce_bam_lock(qce);
+
rctx->src_nents = sg_nents_for_len(req->src, req->nbytes);
if (rctx->src_nents < 0) {
dev_err(qce->dev, "Invalid numbers of src SG.\n");
diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
index cab796cd7e43..42414fe9b787 100644
--- a/drivers/crypto/qce/skcipher.c
+++ b/drivers/crypto/qce/skcipher.c
@@ -52,6 +52,8 @@ static void qce_skcipher_done(void *data)
sg_free_table(&rctx->dst_tbl);
+ qce_bam_unlock(qce);
+
error = qce_check_status(qce, &status);
if (error < 0)
dev_dbg(qce->dev, "skcipher operation error (%x)\n", status);
@@ -82,6 +84,8 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL;
+ qce_bam_lock(qce);
+
rctx->src_nents = sg_nents_for_len(req->src, req->cryptlen);
if (diff_dst)
rctx->dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
--
2.45.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support
2025-03-11 9:25 [PATCH v7 0/8] dmaengine: qcom: bam_dma: add command descriptor support Bartosz Golaszewski
` (7 preceding siblings ...)
2025-03-11 9:25 ` [PATCH v7 8/8] crypto: qce - Add support for BAM locking Bartosz Golaszewski
@ 2025-03-21 9:06 ` Herbert Xu
8 siblings, 0 replies; 15+ messages in thread
From: Herbert Xu @ 2025-03-21 9:06 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Thara Gopinath, David S. Miller, Vinod Koul, Jonathan Corbet,
Md Sadre Alam, Srinivas Kandagatla, linux-crypto, linux-arm-msm,
linux-kernel, dmaengine, linux-doc, Bartosz Golaszewski
On Tue, Mar 11, 2025 at 10:25:31AM +0100, Bartosz Golaszewski wrote:
>
> Testing:
>
> insmod tcrypt.ko mode=101
Please also enable CRYPTO_MANAGER_EXTRA_TESTS. Those tests are
a lot better than the fixed test vectors alone.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 15+ messages in thread