[PATCH RESEND 5/5] soundwire: intel_ace2x: handle the max_data_per_frame property

Bard Liao <[email protected]>
Newsgroups org.kernel.vger.linux-sound,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The optional property indicates the maximum data payload size for the
BRA mode.

Signed-off-by: Bard Liao <[email protected]>
Reviewed-by: Péter Ujfalusi <[email protected]>
---
 drivers/soundwire/intel_ace2x.c | 18 ++++++++++++++++--
 include/linux/soundwire/sdw.h   |  8 ++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c
index 2fc5589bbd72..ad83811037d2 100644
--- a/drivers/soundwire/intel_ace2x.c
+++ b/drivers/soundwire/intel_ace2x.c
@@ -57,6 +57,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
 	struct sdw_port_config *pconfig;
 	unsigned int pdi0_buf_size_pre_frame;
 	unsigned int pdi1_buf_size_pre_frame;
+	unsigned int max_data_per_frame;
 	unsigned int pdi0_buffer_size_;
 	unsigned int pdi1_buffer_size_;
 	unsigned int pdi0_buffer_size;
@@ -168,11 +169,24 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
 	pdi0_buffer_size = 0;
 	pdi1_buffer_size = 0;
 	num_frames = 0;
+
+	if (slave->prop.bra_max_data_per_frame) {
+		max_data_per_frame = slave->prop.bra_max_data_per_frame;
+		if (max_data_per_frame > SDW_BRA_MAX_BYTES_PER_FRAME) {
+			dev_warn(&slave->dev,
+				 "BRA max_data_per_frame %u exceeds limit %u, clamping\n",
+				 max_data_per_frame, SDW_BRA_MAX_BYTES_PER_FRAME);
+			max_data_per_frame = SDW_BRA_MAX_BYTES_PER_FRAME;
+		}
+	} else {
+		max_data_per_frame = SDW_BRA_MAX_BYTES_PER_FRAME;
+	}
+
 	/* Add up pdi buffer size and frame numbers of each BPT sections */
 	for (i = 0; i < msg->sections; i++) {
 		ret = sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row,
 						     cdns->bus.params.col,
-						     msg->sec[i].len, SDW_BPT_MSG_MAX_BYTES,
+						     msg->sec[i].len, max_data_per_frame,
 						     slave->prop.bra_block_alignment,
 						     &data_per_frame, &pdi0_buffer_size_,
 						     &pdi1_buffer_size_, &num_frames_);
@@ -197,7 +211,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
 		/* Get buffer size of a full frame */
 		ret = sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row,
 						     cdns->bus.params.col,
-						     data_per_frame, SDW_BPT_MSG_MAX_BYTES,
+						     data_per_frame, max_data_per_frame,
 						     slave->prop.bra_block_alignment,
 						     &data_per_frame, &pdi0_buf_size_pre_frame,
 						     &pdi1_buf_size_pre_frame, &fake_num_frames);
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index 89009a2c321d..769a8ba5b5c6 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -843,6 +843,14 @@ struct sdw_defer {
  */
 #define SDW_BPT_MSG_MAX_BYTES  (1024 * 1024)
 
+/*
+ * According to mipi SoundWire DisCo Specification_v2-1,
+ * this maximum value shall not exceed 470.
+ * Note that the largest number of bytes accessible by a single BRA operation is limited to 470
+ * bytes when using lane 0, but goes up to 502 bytes when using one of the optional extra lanes.
+ */
+#define SDW_BRA_MAX_BYTES_PER_FRAME  470
+
 struct sdw_bpt_msg;
 
 /**
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.