diff mbox series

[v6,03/12] dmaengine: qcom: bam_dma: add bam_pipe_lock flag support

Message ID 20250115103004.3350561-4-quic_mdalam@quicinc.com (mailing list archive)
State New
Headers show
Series dmaengine: qcom: bam_dma: add cmd descriptor support | expand

Commit Message

Md Sadre Alam Jan. 15, 2025, 10:29 a.m. UTC
BAM IP version 1.4.0 and above only supports this LOCK/UNLOCK
feature. So adding check for the same and setting bam_pipe_lock
based on BAM SW Version.

Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
---

Change in [v6]

* No change

Change in [v5]

* Removed DMA_PREP_LOCK & DMA_PREP_UNLOCK flag

* Added FIELD_GET and GENMASK macro to extract major
  and minor version

Change in [v4]

* Added BAM_SW_VERSION read for major & minor
  version

* Added bam_pipe_lock flag 

Change in [v3]

* Moved lock/unlock bit set inside loop

Change in [v2]

* No change
 
Change in [v1]

* Added initial support for BAM pipe lock/unlock

 drivers/dma/qcom/bam_dma.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index daeacd5cb8e9..f50d88ad4f6d 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -53,11 +53,18 @@  struct bam_desc_hw {
 
 #define BAM_DMA_AUTOSUSPEND_DELAY 100
 
+#define SW_VERSION_MAJOR_MASK	GENMASK(31, 28)
+#define SW_VERSION_MINOR_MASK	GENMASK(27, 16)
+#define SW_MAJOR_1	0x1
+#define SW_VERSION_4	0x4
+
 #define DESC_FLAG_INT BIT(15)
 #define DESC_FLAG_EOT BIT(14)
 #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)
 
 #define BAM_NDP_REVISION_START	0x20
 #define BAM_NDP_REVISION_END	0x27
@@ -396,6 +403,7 @@  struct bam_device {
 	u32 ee;
 	bool controlled_remotely;
 	bool powered_remotely;
+	bool bam_pipe_lock;
 	u32 active_channels;
 	u32 bam_sw_version;
 
@@ -702,8 +710,13 @@  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->bam_pipe_lock && flags & DMA_PREP_LOCK)
+					desc->flags |= cpu_to_le16(DESC_FLAG_LOCK);
+				else if (bdev->bam_pipe_lock && flags & DMA_PREP_UNLOCK)
+					desc->flags |= cpu_to_le16(DESC_FLAG_UNLOCK);
+			}
 
 			desc->addr = cpu_to_le32(sg_dma_address(sg) +
 						 curr_offset);
@@ -1250,6 +1263,7 @@  static int bam_dma_probe(struct platform_device *pdev)
 {
 	struct bam_device *bdev;
 	const struct of_device_id *match;
+	u32 sw_major, sw_minor;
 	int ret, i;
 
 	bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
@@ -1313,6 +1327,11 @@  static int bam_dma_probe(struct platform_device *pdev)
 
 	bdev->bam_sw_version = readl_relaxed(bam_addr(bdev, 0, BAM_SW_VERSION));
 	dev_info(bdev->dev, "BAM software version:0x%08x\n", bdev->bam_sw_version);
+	sw_major = FIELD_GET(SW_VERSION_MAJOR_MASK, bdev->bam_sw_version);
+	sw_minor = FIELD_GET(SW_VERSION_MINOR_MASK, bdev->bam_sw_version);
+
+	if (sw_major == SW_MAJOR_1 && sw_minor >= SW_VERSION_4)
+		bdev->bam_pipe_lock = true;
 
 	ret = bam_init(bdev);
 	if (ret)