* [PATCH 0/5] soundwire: add BRA properties
@ 2026-06-30 12:48 Bard Liao
2026-06-30 12:48 ` [PATCH 1/5] soundwire: cadence_master: add BRA_NumBytes[8] support Bard Liao
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Bard Liao @ 2026-06-30 12:48 UTC (permalink / raw)
To: linux-sound, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, peter.ujfalusi,
bard.liao
This series adds mipi-sdw-bra-mode-max-data-per-frame and
mipi-sdw-bra-mode-block-alignment properties support and fixes the
BRA_NumBytes[8] support in cadence_master driver.
Bard Liao (4):
soundwire: cadence_master: add BRA_NumBytes[8] support
soundwire: intel: handle Peripheral bra_block_alignment
soundwire: get mipi-sdw-bra-mode-max-data-per-frame property
soundwire: intel_ace2x: handle the max_data_per_frame property
Richard Fitzgerald (1):
soundwire: Add bra_block_alignment property support
drivers/soundwire/cadence_master.c | 35 +++++++++++++++++++++++++-----
drivers/soundwire/cadence_master.h | 1 +
drivers/soundwire/intel_ace2x.c | 20 +++++++++++++++--
drivers/soundwire/mipi_disco.c | 6 +++++
include/linux/soundwire/sdw.h | 14 ++++++++++++
5 files changed, 68 insertions(+), 8 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/5] soundwire: cadence_master: add BRA_NumBytes[8] support
2026-06-30 12:48 [PATCH 0/5] soundwire: add BRA properties Bard Liao
@ 2026-06-30 12:48 ` Bard Liao
2026-06-30 12:48 ` [PATCH 2/5] soundwire: Add bra_block_alignment property support Bard Liao
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Bard Liao @ 2026-06-30 12:48 UTC (permalink / raw)
To: linux-sound, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, peter.ujfalusi,
bard.liao
The header[0] bit definitions are:
Header[0] bits 7 – 6: BRA_HeaderType
Header[0] bits 5 – 2: BRA_DeviceAddress[3:0]
Header[0] bit 1 BRA_Opcode 1 => Write, 0 => Read
Header[0] bit 0 BRA_NumBytes[8]
And the header[1] indicates the BRA_NumBytes[7:0]. The existing code
doesn't handle BRA_NumBytes[8] therefore the maximum BRA number of a
frame is limited to 255.
Fixes: fe8a9cf75c1e ("soundwire: pass sdw_bpt_section to cdns BPT helpers")
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
drivers/soundwire/cadence_master.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index b8b62735c893..99414e71428b 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -2359,7 +2359,9 @@ int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, struct sdw_bpt_section *sec, i
p_data = sec[i].buf;
while (section_size >= data_per_frame) {
- header[1] = data_per_frame;
+ header[0] &= ~BIT(0);
+ header[0] |= (data_per_frame >> 8) & BIT(0);
+ header[1] = data_per_frame & 0xFF;
header[2] = start_register >> 24 & 0xFF;
header[3] = start_register >> 16 & 0xFF;
header[4] = start_register >> 8 & 0xFF;
@@ -2385,7 +2387,9 @@ int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, struct sdw_bpt_section *sec, i
}
if (section_size) {
- header[1] = section_size;
+ header[0] &= ~BIT(0);
+ header[0] |= (section_size >> 8) & BIT(0);
+ header[1] = section_size & 0xFF;
header[2] = start_register >> 24 & 0xFF;
header[3] = start_register >> 16 & 0xFF;
header[4] = start_register >> 8 & 0xFF;
@@ -2436,7 +2440,9 @@ int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, struct sdw_bpt_section *sec, in
start_register = sec[i].addr;
data_size = sec[i].len;
while (data_size >= data_per_frame) {
- header[1] = data_per_frame;
+ header[0] &= ~BIT(0);
+ header[0] |= (data_per_frame >> 8) & BIT(0);
+ header[1] = data_per_frame & 0xFF;
header[2] = start_register >> 24 & 0xFF;
header[3] = start_register >> 16 & 0xFF;
header[4] = start_register >> 8 & 0xFF;
@@ -2460,7 +2466,9 @@ int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, struct sdw_bpt_section *sec, in
}
if (data_size) {
- header[1] = data_size;
+ header[0] &= ~BIT(0);
+ header[0] |= (data_size >> 8) & BIT(0);
+ header[1] = data_size & 0xFF;
header[2] = start_register >> 24 & 0xFF;
header[3] = start_register >> 16 & 0xFF;
header[4] = start_register >> 8 & 0xFF;
@@ -2483,7 +2491,9 @@ int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, struct sdw_bpt_section *sec, in
/* Add fake frame */
header[0] &= ~GENMASK(7, 6); /* Set inactive flag in BPT/BRA frame heade */
while (fake_size >= data_per_frame) {
- header[1] = data_per_frame;
+ header[0] &= ~BIT(0);
+ header[0] |= (data_per_frame >> 8) & BIT(0);
+ header[1] = data_per_frame & 0xFF;
ret = sdw_cdns_prepare_read_pd0_buffer(header, SDW_CDNS_BRA_HDR, p_dma_buffer,
dma_buffer_size, &dma_data_written,
counter);
@@ -2499,7 +2509,9 @@ int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, struct sdw_bpt_section *sec, in
}
if (fake_size) {
- header[1] = fake_size;
+ header[0] &= ~BIT(0);
+ header[0] |= (fake_size >> 8) & BIT(0);
+ header[1] = fake_size & 0xFF;
ret = sdw_cdns_prepare_read_pd0_buffer(header, SDW_CDNS_BRA_HDR, p_dma_buffer,
dma_buffer_size, &dma_data_written,
counter);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/5] soundwire: Add bra_block_alignment property support
2026-06-30 12:48 [PATCH 0/5] soundwire: add BRA properties Bard Liao
2026-06-30 12:48 ` [PATCH 1/5] soundwire: cadence_master: add BRA_NumBytes[8] support Bard Liao
@ 2026-06-30 12:48 ` Bard Liao
2026-06-30 12:48 ` [PATCH 3/5] soundwire: intel: handle Peripheral bra_block_alignment Bard Liao
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Bard Liao @ 2026-06-30 12:48 UTC (permalink / raw)
To: linux-sound, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, peter.ujfalusi,
bard.liao
From: Richard Fitzgerald <rf@opensource.cirrus.com>
Add a property to struct sdw_slave_prop equivalent to the Disco
property "mipi-sdw-bra-mode-block-alignment".
The SoundWire Disco specification defines this as:
"The data payload size for this BRA Mode shall be an integer
multiple of the value of this Property."
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Co-developed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
drivers/soundwire/mipi_disco.c | 3 +++
include/linux/soundwire/sdw.h | 3 +++
2 files changed, 6 insertions(+)
diff --git a/drivers/soundwire/mipi_disco.c b/drivers/soundwire/mipi_disco.c
index c69b78cd0b62..b122bd1e7321 100644
--- a/drivers/soundwire/mipi_disco.c
+++ b/drivers/soundwire/mipi_disco.c
@@ -471,6 +471,9 @@ int sdw_slave_read_prop(struct sdw_slave *slave)
device_property_read_u32(dev, "mipi-sdw-sdca-interrupt-register-list",
&prop->sdca_interrupt_register_list);
+ device_property_read_u32(dev, "mipi-sdw-bra-mode-block-alignment",
+ &prop->bra_block_alignment);
+
prop->commit_register_supported = mipi_device_property_read_bool(dev,
"mipi-sdw-commit-register-supported");
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index b484784e2690..7e27e8bdb64a 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -365,6 +365,8 @@ struct sdw_dpn_prop {
* @commit_register_supported: is PCP_Commit register supported
* @scp_int1_mask: SCP_INT1_MASK desired settings
* @lane_maps: Lane mapping for the slave, only valid if lane_control_support is set
+ * @bra_block_alignment: If non-zero the length of data in a BRA frame must be
+ * a multiple of this number of bytes.
* @clock_reg_supported: the Peripheral implements the clock base and scale
* registers introduced with the SoundWire 1.2 specification. SDCA devices
* do not need to set this boolean property as the registers are required.
@@ -395,6 +397,7 @@ struct sdw_slave_prop {
u8 commit_register_supported;
u8 scp_int1_mask;
u8 lane_maps[SDW_MAX_LANES];
+ u32 bra_block_alignment;
bool clock_reg_supported;
bool use_domain_irq;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/5] soundwire: intel: handle Peripheral bra_block_alignment
2026-06-30 12:48 [PATCH 0/5] soundwire: add BRA properties Bard Liao
2026-06-30 12:48 ` [PATCH 1/5] soundwire: cadence_master: add BRA_NumBytes[8] support Bard Liao
2026-06-30 12:48 ` [PATCH 2/5] soundwire: Add bra_block_alignment property support Bard Liao
@ 2026-06-30 12:48 ` Bard Liao
2026-06-30 12:48 ` [PATCH 4/5] soundwire: get mipi-sdw-bra-mode-max-data-per-frame property Bard Liao
2026-06-30 12:48 ` [PATCH 5/5] soundwire: intel_ace2x: handle the max_data_per_frame property Bard Liao
4 siblings, 0 replies; 6+ messages in thread
From: Bard Liao @ 2026-06-30 12:48 UTC (permalink / raw)
To: linux-sound, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, peter.ujfalusi,
bard.liao
The data pre frame size should be a multiple of bra_block_alignment.
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
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
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/5] soundwire: get mipi-sdw-bra-mode-max-data-per-frame property
2026-06-30 12:48 [PATCH 0/5] soundwire: add BRA properties Bard Liao
` (2 preceding siblings ...)
2026-06-30 12:48 ` [PATCH 3/5] soundwire: intel: handle Peripheral bra_block_alignment Bard Liao
@ 2026-06-30 12:48 ` Bard Liao
2026-06-30 12:48 ` [PATCH 5/5] soundwire: intel_ace2x: handle the max_data_per_frame property Bard Liao
4 siblings, 0 replies; 6+ messages in thread
From: Bard Liao @ 2026-06-30 12:48 UTC (permalink / raw)
To: linux-sound, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, peter.ujfalusi,
bard.liao
Get the mipi-sdw-bra-mode-max-data-per-frame property which indicates
the maximum data payload size (in bytes per frame excluding header,
CRC, and footer) for the BRA Mode.
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
drivers/soundwire/mipi_disco.c | 3 +++
include/linux/soundwire/sdw.h | 3 +++
2 files changed, 6 insertions(+)
diff --git a/drivers/soundwire/mipi_disco.c b/drivers/soundwire/mipi_disco.c
index b122bd1e7321..cfccaa33f438 100644
--- a/drivers/soundwire/mipi_disco.c
+++ b/drivers/soundwire/mipi_disco.c
@@ -474,6 +474,9 @@ int sdw_slave_read_prop(struct sdw_slave *slave)
device_property_read_u32(dev, "mipi-sdw-bra-mode-block-alignment",
&prop->bra_block_alignment);
+ device_property_read_u32(dev, "mipi-sdw-bra-mode-max-data-per-frame",
+ &prop->bra_max_data_per_frame);
+
prop->commit_register_supported = mipi_device_property_read_bool(dev,
"mipi-sdw-commit-register-supported");
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index 7e27e8bdb64a..89009a2c321d 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -367,6 +367,8 @@ struct sdw_dpn_prop {
* @lane_maps: Lane mapping for the slave, only valid if lane_control_support is set
* @bra_block_alignment: If non-zero the length of data in a BRA frame must be
* a multiple of this number of bytes.
+ * @bra_max_data_per_frame: If non-zero the maximum data payload size (in bytes per
+ * frame excluding header, CRC, and footer) for this BRA Mode
* @clock_reg_supported: the Peripheral implements the clock base and scale
* registers introduced with the SoundWire 1.2 specification. SDCA devices
* do not need to set this boolean property as the registers are required.
@@ -398,6 +400,7 @@ struct sdw_slave_prop {
u8 scp_int1_mask;
u8 lane_maps[SDW_MAX_LANES];
u32 bra_block_alignment;
+ u32 bra_max_data_per_frame;
bool clock_reg_supported;
bool use_domain_irq;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5/5] soundwire: intel_ace2x: handle the max_data_per_frame property
2026-06-30 12:48 [PATCH 0/5] soundwire: add BRA properties Bard Liao
` (3 preceding siblings ...)
2026-06-30 12:48 ` [PATCH 4/5] soundwire: get mipi-sdw-bra-mode-max-data-per-frame property Bard Liao
@ 2026-06-30 12:48 ` Bard Liao
4 siblings, 0 replies; 6+ messages in thread
From: Bard Liao @ 2026-06-30 12:48 UTC (permalink / raw)
To: linux-sound, vkoul
Cc: vinod.koul, linux-kernel, pierre-louis.bossart, peter.ujfalusi,
bard.liao
The optional property indicates the maximum data payload size for the
BRA mode.
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
---
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
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-30 12:48 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-30 12:48 [PATCH 0/5] soundwire: add BRA properties Bard Liao
2026-06-30 12:48 ` [PATCH 1/5] soundwire: cadence_master: add BRA_NumBytes[8] support Bard Liao
2026-06-30 12:48 ` [PATCH 2/5] soundwire: Add bra_block_alignment property support Bard Liao
2026-06-30 12:48 ` [PATCH 3/5] soundwire: intel: handle Peripheral bra_block_alignment Bard Liao
2026-06-30 12:48 ` [PATCH 4/5] soundwire: get mipi-sdw-bra-mode-max-data-per-frame property Bard Liao
2026-06-30 12:48 ` [PATCH 5/5] soundwire: intel_ace2x: handle the max_data_per_frame property Bard Liao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox