From: Bard Liao Date: Tue, 21 Oct 2025 09:43:52 +0000 (+0800) Subject: soundwire: introduce BPT section X-Git-Tag: v6.19-rc1~19^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fdfa1960eee7591995cf877e9caf9cf5794ab91f;p=thirdparty%2Fkernel%2Flinux.git soundwire: introduce BPT section Currently we send a BRA message with a start address with continuous registers in a BPT stream. However, a codec may need to write different register sections shortly. Introduce a register section in struct sdw_btp_msg which contain register start address, length, and buffer. This commit uses only 1 section for each BPT message. And we need to add up all BPT section length and check if it reach maximum BPT bytes. No function changes. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Tested-by: Shuming Fan Link: https://patch.msgid.link/20251021094355.132943-2-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index 55c1db816534..fb68738dfb9b 100644 --- a/drivers/soundwire/bus.c +++ b/drivers/soundwire/bus.c @@ -2052,8 +2052,14 @@ EXPORT_SYMBOL(sdw_clear_slave_status); int sdw_bpt_send_async(struct sdw_bus *bus, struct sdw_slave *slave, struct sdw_bpt_msg *msg) { - if (msg->len > SDW_BPT_MSG_MAX_BYTES) { - dev_err(bus->dev, "Invalid BPT message length %d\n", msg->len); + int len = 0; + int i; + + for (i = 0; i < msg->sections; i++) + len += msg->sec[i].len; + + if (len > SDW_BPT_MSG_MAX_BYTES) { + dev_err(bus->dev, "Invalid BPT message length %d\n", len); return -EINVAL; } diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h index 02651fbb683a..8115c64dd48e 100644 --- a/drivers/soundwire/bus.h +++ b/drivers/soundwire/bus.h @@ -73,21 +73,31 @@ struct sdw_msg { }; /** - * struct sdw_btp_msg - Message structure + * struct sdw_btp_section - Message section structure * @addr: Start Register address accessed in the Slave * @len: number of bytes to transfer. More than 64Kb can be transferred * but a practical limit of SDW_BPT_MSG_MAX_BYTES is enforced. - * @dev_num: Slave device number - * @flags: transfer flags, indicate if xfer is read or write - * @buf: message data buffer (filled by host for write, filled + * @buf: section data buffer (filled by host for write, filled * by Peripheral hardware for reads) */ -struct sdw_bpt_msg { +struct sdw_bpt_section { u32 addr; u32 len; + u8 *buf; +}; + +/** + * struct sdw_btp_msg - Message structure + * @sec: Pointer to array of sections + * @sections: Number of sections in the array + * @dev_num: Slave device number + * @flags: transfer flags, indicate if xfer is read or write + */ +struct sdw_bpt_msg { + struct sdw_bpt_section *sec; + int sections; u8 dev_num; u8 flags; - u8 *buf; }; #define SDW_DOUBLE_RATE_FACTOR 2 diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c index 1e0f9318b616..6068011dd0d9 100644 --- a/drivers/soundwire/debugfs.c +++ b/drivers/soundwire/debugfs.c @@ -222,15 +222,23 @@ DEFINE_DEBUGFS_ATTRIBUTE(set_num_bytes_fops, NULL, static int do_bpt_sequence(struct sdw_slave *slave, bool write, u8 *buffer) { struct sdw_bpt_msg msg = {0}; + struct sdw_bpt_section *sec; - msg.addr = start_addr; - msg.len = num_bytes; + sec = kcalloc(1, sizeof(*sec), GFP_KERNEL); + if (!sec) + return -ENOMEM; + msg.sections = 1; + + sec[0].addr = start_addr; + sec[0].len = num_bytes; + + msg.sec = sec; msg.dev_num = slave->dev_num; if (write) msg.flags = SDW_MSG_FLAG_WRITE; else msg.flags = SDW_MSG_FLAG_READ; - msg.buf = buffer; + sec[0].buf = buffer; return sdw_bpt_send_sync(slave->bus, slave, &msg); } diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index e11a0cf77193..a0f708a7cdff 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -156,8 +156,9 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave * goto deprepare_stream; ret = sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row, cdns->bus.params.col, - msg->len, SDW_BPT_MSG_MAX_BYTES, &data_per_frame, - &pdi0_buffer_size, &pdi1_buffer_size, &num_frames); + msg->sec[0].len, SDW_BPT_MSG_MAX_BYTES, + &data_per_frame, &pdi0_buffer_size, &pdi1_buffer_size, + &num_frames); if (ret < 0) goto deprepare_stream; @@ -204,7 +205,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave * } dev_dbg(cdns->dev, "Message len %d transferred in %d frames (%d per frame)\n", - msg->len, num_frames, data_per_frame); + msg->sec[0].len, num_frames, data_per_frame); dev_dbg(cdns->dev, "sizes pdi0 %d pdi1 %d tx_bandwidth %d rx_bandwidth %d\n", pdi0_buffer_size, pdi1_buffer_size, tx_dma_bandwidth, rx_dma_bandwidth); @@ -219,12 +220,14 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave * } if (!command) { - ret = sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->addr, msg->buf, - msg->len, data_per_frame, + ret = sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->sec[0].addr, + msg->sec[0].buf, + msg->sec[0].len, data_per_frame, sdw->bpt_ctx.dmab_tx_bdl.area, pdi0_buffer_size, &tx_total_bytes); } else { - ret = sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->addr, msg->len, + ret = sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->sec[0].addr, + msg->sec[0].len, data_per_frame, sdw->bpt_ctx.dmab_tx_bdl.area, pdi0_buffer_size, &tx_total_bytes, @@ -305,9 +308,9 @@ static int intel_ace2x_bpt_send_async(struct sdw_intel *sdw, struct sdw_slave *s struct sdw_cdns *cdns = &sdw->cdns; int ret; - if (msg->len < INTEL_BPT_MSG_BYTE_MIN) { + if (msg->sec[0].len < INTEL_BPT_MSG_BYTE_MIN) { dev_err(cdns->dev, "BPT message length %d is less than the minimum bytes %d\n", - msg->len, INTEL_BPT_MSG_BYTE_MIN); + msg->sec[0].len, INTEL_BPT_MSG_BYTE_MIN); return -EINVAL; } @@ -367,7 +370,8 @@ static int intel_ace2x_bpt_wait(struct sdw_intel *sdw, struct sdw_slave *slave, } else { ret = sdw_cdns_check_read_response(cdns->dev, sdw->bpt_ctx.dmab_rx_bdl.area, sdw->bpt_ctx.pdi1_buffer_size, - msg->buf, msg->len, sdw->bpt_ctx.num_frames, + msg->sec[0].buf, msg->sec[0].len, + sdw->bpt_ctx.num_frames, sdw->bpt_ctx.data_per_frame); if (ret < 0) dev_err(cdns->dev, "%s: BPT Read failed %d\n", __func__, ret);