[PATCH 3/5] soundwire: intel: handle Peripheral bra_block_alignment

From: Bard Liao

Date: Tue Jun 30 2026 - 08:51:47 EST


The data pre frame size should be a multiple of bra_block_alignment.

Signed-off-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx>
---
drivers/soundwire/cadence_master.c | 11 +++++++++++
drivers/soundwire/cadence_master.h | 1 +
drivers/soundwire/intel_ace2x.c | 2 ++
3 files changed, 14 insertions(+)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 99414e71428b..6fa3739221ee 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -2135,6 +2135,7 @@ EXPORT_SYMBOL(sdw_cdns_bpt_find_bandwidth);
int sdw_cdns_bpt_find_buffer_sizes(int command, /* 0: write, 1: read */
int row, int col, unsigned int data_bytes,
unsigned int requested_bytes_per_frame,
+ unsigned int bra_block_alignment,
unsigned int *data_per_frame, unsigned int *pdi0_buffer_size,
unsigned int *pdi1_buffer_size, unsigned int *num_frames)
{
@@ -2159,6 +2160,16 @@ int sdw_cdns_bpt_find_buffer_sizes(int command, /* 0: write, 1: read */
if (requested_bytes_per_frame < actual_bpt_bytes)
actual_bpt_bytes = requested_bytes_per_frame;

+ if (bra_block_alignment) {
+ /* align to a multiple of bra_block_alignment */
+ if (actual_bpt_bytes < bra_block_alignment) {
+ pr_err("effective bytes per frame %u is smaller than block alignment %u\n",
+ actual_bpt_bytes, bra_block_alignment);
+ return -EINVAL;
+ }
+ actual_bpt_bytes -= (actual_bpt_bytes % bra_block_alignment);
+ }
+
*data_per_frame = actual_bpt_bytes;

if (data_bytes < actual_bpt_bytes)
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index 668f807cff4b..f4e41a9ab165 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -218,6 +218,7 @@ int sdw_cdns_bpt_find_bandwidth(int command, /* 0: write, 1: read */
int sdw_cdns_bpt_find_buffer_sizes(int command, /* 0: write, 1: read */
int row, int col, unsigned int data_bytes,
unsigned int requested_bytes_per_frame,
+ unsigned int bra_block_alignment,
unsigned int *data_per_frame, unsigned int *pdi0_buffer_size,
unsigned int *pdi1_buffer_size, unsigned int *num_frames);

diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c
index b37933efac5d..2fc5589bbd72 100644
--- a/drivers/soundwire/intel_ace2x.c
+++ b/drivers/soundwire/intel_ace2x.c
@@ -173,6 +173,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
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,
+ slave->prop.bra_block_alignment,
&data_per_frame, &pdi0_buffer_size_,
&pdi1_buffer_size_, &num_frames_);
if (ret < 0)
@@ -197,6 +198,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
ret = sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row,
cdns->bus.params.col,
data_per_frame, SDW_BPT_MSG_MAX_BYTES,
+ slave->prop.bra_block_alignment,
&data_per_frame, &pdi0_buf_size_pre_frame,
&pdi1_buf_size_pre_frame, &fake_num_frames);
if (ret < 0)
--
2.43.0