From nobody Sun Feb 8 11:40:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 609862F744C; Tue, 21 Oct 2025 09:44:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761039853; cv=none; b=USKmPOK+pd9QPjqPIfjAQNxWspQkXVPlm6gnlYcdShUHIQfoOtrH6zOuIPiZ5GJlaflYehuvT9Z8APXgA7XYr+EHWGDADtnJjrSrjmU69exFW6ZZdP59oCuBVuLa5MxCIdZxVWLhrGmH5cNa/81/jpfca0pnJpEu9r8CrVxk8pQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761039853; c=relaxed/simple; bh=GmShjL6FtP90Nh6uWEeIlkGwnSP52u115p0hkXvrcdc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pYG7IHHSSXYFQYAv0aspRVH43LTXyZw4wkG4SBNeGbwB+ZxPezVz43AXlf5ZjrFT07NOQJh6wC2P5/IU03nlijfOqc1r68Gx+xeuQZ+m+jA4KvCDvXYSoxKcXYj4C8EUvCufkFxvWftL+yfBOEthL+2L7e17m15sJOJAJJhmgDk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=SHDWPYdJ; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="SHDWPYdJ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1761039851; x=1792575851; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GmShjL6FtP90Nh6uWEeIlkGwnSP52u115p0hkXvrcdc=; b=SHDWPYdJvFKGTgfh83LlsyRlkCk/nqVY4lwlkBsE8LJRHgZ+PIMGS0rW cC3MV8HrcAkC20s01PNMXuK0TaYO2CrcP4xTBhBBDWzfHOCw9H94gqMjV XPwURLdOxBy/YS1NouE7AJkZAOXBrS2SnB0p6LFfz10npvResg3Qb42/a 7x3lShztJBGwP0yQXyqiyFcpx2KA780WqxroN0xhUxo2WO6hZ3dOV/rb9 ueepX2FAOg1CBWFujxoEy7dDiJgnBoAF2vzkna0mvBl+n8A9qZSv0LMZO 45RAvTmRpKqZo91ExlrDDjO66s8jzOtR+gBRUzhv9j+w60z68TrPAQwe6 A==; X-CSE-ConnectionGUID: xIn0SvrJTqqFQmtXRi1ptg== X-CSE-MsgGUID: R0hpvMZ5SiiPPUWX4txVjQ== X-IronPort-AV: E=McAfee;i="6800,10657,11586"; a="63259375" X-IronPort-AV: E=Sophos;i="6.19,244,1754982000"; d="scan'208";a="63259375" Received: from orviesa010.jf.intel.com ([10.64.159.150]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2025 02:44:08 -0700 X-CSE-ConnectionGUID: uwOhuCs/QU+PF9xZY6fw8g== X-CSE-MsgGUID: ZfxkHzxnRked0a4MSEsbRA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,244,1754982000"; d="scan'208";a="182753534" Received: from yungchua-desk.itwn.intel.com ([10.227.8.136]) by orviesa010-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2025 02:44:07 -0700 From: Bard Liao To: linux-sound@vger.kernel.org, vkoul@kernel.org Cc: vinod.koul@linaro.org, linux-kernel@vger.kernel.org, pierre-louis.bossart@linux.dev, bard.liao@intel.com Subject: [PATCH 1/3] soundwire: introduce BPT section Date: Tue, 21 Oct 2025 17:43:52 +0800 Message-ID: <20251021094355.132943-2-yung-chuan.liao@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251021094355.132943-1-yung-chuan.liao@linux.intel.com> References: <20251021094355.132943-1-yung-chuan.liao@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- drivers/soundwire/bus.c | 10 ++++++++-- drivers/soundwire/bus.h | 22 ++++++++++++++++------ drivers/soundwire/debugfs.c | 14 +++++++++++--- drivers/soundwire/intel_ace2x.c | 22 +++++++++++++--------- 4 files changed, 48 insertions(+), 20 deletions(-) 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); =20 int sdw_bpt_send_async(struct sdw_bus *bus, struct sdw_slave *slave, struc= t 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 =3D 0; + int i; + + for (i =3D 0; i < msg->sections; i++) + len +=3D msg->sec[i].len; + + if (len > SDW_BPT_MSG_MAX_BYTES) { + dev_err(bus->dev, "Invalid BPT message length %d\n", len); return -EINVAL; } =20 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 { }; =20 /** - * 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; }; =20 #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 =3D {0}; + struct sdw_bpt_section *sec; =20 - msg.addr =3D start_addr; - msg.len =3D num_bytes; + sec =3D kcalloc(1, sizeof(*sec), GFP_KERNEL); + if (!sec) + return -ENOMEM; + msg.sections =3D 1; + + sec[0].addr =3D start_addr; + sec[0].len =3D num_bytes; + + msg.sec =3D sec; msg.dev_num =3D slave->dev_num; if (write) msg.flags =3D SDW_MSG_FLAG_WRITE; else msg.flags =3D SDW_MSG_FLAG_READ; - msg.buf =3D buffer; + sec[0].buf =3D buffer; =20 return sdw_bpt_send_sync(slave->bus, slave, &msg); } diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2= x.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; =20 ret =3D sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row, cdn= s->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; =20 @@ -204,7 +205,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel= *sdw, struct sdw_slave * } =20 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); =20 @@ -219,12 +220,14 @@ static int intel_ace2x_bpt_open_stream(struct sdw_int= el *sdw, struct sdw_slave * } =20 if (!command) { - ret =3D sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->addr, msg->= buf, - msg->len, data_per_frame, + ret =3D 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 =3D sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->addr, msg->l= en, + ret =3D 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 =3D &sdw->cdns; int ret; =20 - 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; } =20 @@ -367,7 +370,8 @@ static int intel_ace2x_bpt_wait(struct sdw_intel *sdw, = struct sdw_slave *slave, } else { ret =3D 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); --=20 2.43.0 From nobody Sun Feb 8 11:40:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 609082EA158; Tue, 21 Oct 2025 09:44:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761039854; cv=none; b=Ka5khgegsXQ28iVImu4Gy+tkhOg9wdfVVPBOgqZ9gXz98qZbspr1yr4P44NNGV32W0P6aOgxn/eQlM5PGCMC525c0Hb3Q4s4o3opzkdMR0QzznIIAbtI2kP6ZA/PD+yJjdtj3bq5N/DxbE5aLOn7eoIGI1fFmQgV7q7rE15Mbj8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761039854; c=relaxed/simple; bh=HOhZsmTA3KldyGXWyx6woouKm3LnLGFrLzfFcBS04eQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZPTMFcdehK8D98FEwVX/AOR7S1PhuDV1jXl2y+S1cHZW/U/SHqQtAc6CWG1793zaW/kaDqcllJqznE76wS1ZYsJQV8p4aqKRG1PDxezRv7YkhXGPXNe4DZfl8ykYE3fQxF2R99zNh3jUdgAaWmrr1Lwmu7fuT/0odZqD7LMcuoM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=KNFVuax3; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="KNFVuax3" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1761039851; x=1792575851; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HOhZsmTA3KldyGXWyx6woouKm3LnLGFrLzfFcBS04eQ=; b=KNFVuax35i1WHQrlRfK2f/MrdDB5/F/S/RTowQcAnAbyE2pFsrf0JLsZ Zoy0j7/XEiSqgpC6PzHcir+2av4f35i8vdH693Txcy6MmDo/w49xRdITd NUBAiykU8+wUzszHLv/Jc5zr7DdjJr+7jfWBItH4+hWad1FL/Pn6MHVyk S48JriH/iWn+8EJIJCSRDI5sztobBi3q2+/hg4knJNxFo7to5ROwg/afL 8jwusgCUmwrL4gFl920Zc7Z4LNyPeWIvxdtcf8njAkWGRJc5MxjognkWT Lu/PCvNMU2PWNxpsI0mQ43dPmtcefJn83cuSVM9zmx2LqCgbi/5GrzrM+ w==; X-CSE-ConnectionGUID: 3Tw2HyhCRhOVkgDbtpHmEw== X-CSE-MsgGUID: IVhapV7ORNiYjrtuT+xF1g== X-IronPort-AV: E=McAfee;i="6800,10657,11586"; a="63259377" X-IronPort-AV: E=Sophos;i="6.19,244,1754982000"; d="scan'208";a="63259377" Received: from orviesa010.jf.intel.com ([10.64.159.150]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2025 02:44:10 -0700 X-CSE-ConnectionGUID: bGHNiItSSxmGtfkZZCaK5w== X-CSE-MsgGUID: pigsSyg5RGy5YPmspykbCg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,244,1754982000"; d="scan'208";a="182753541" Received: from yungchua-desk.itwn.intel.com ([10.227.8.136]) by orviesa010-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2025 02:44:09 -0700 From: Bard Liao To: linux-sound@vger.kernel.org, vkoul@kernel.org Cc: vinod.koul@linaro.org, linux-kernel@vger.kernel.org, pierre-louis.bossart@linux.dev, bard.liao@intel.com Subject: [PATCH 2/3] soundwire: pass sdw_bpt_section to cdns BPT helpers Date: Tue, 21 Oct 2025 17:43:53 +0800 Message-ID: <20251021094355.132943-3-yung-chuan.liao@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251021094355.132943-1-yung-chuan.liao@linux.intel.com> References: <20251021094355.132943-1-yung-chuan.liao@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" We can get start_register, data_size, and buffer data from the new sdw_bpt_section parameter. Also, handle all register sections in the cdns BRA helpers. No function changes as section number is 1. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Tested-by: Shuming Fan --- drivers/soundwire/cadence_master.c | 218 +++++++++++++++++------------ drivers/soundwire/cadence_master.h | 12 +- drivers/soundwire/intel_ace2x.c | 11 +- 3 files changed, 139 insertions(+), 102 deletions(-) diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence= _master.c index 4e94da28d8ad..a106e5e482c8 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -2324,17 +2324,20 @@ static int sdw_cdns_prepare_read_pd0_buffer(u8 *hea= der, unsigned int header_size =20 #define CDNS_BPT_ROLLING_COUNTER_START 1 =20 -int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, u32 start_register, u8 *= data, int data_size, - int data_per_frame, u8 *dma_buffer, int dma_buffer_size, - int *dma_buffer_total_bytes) +int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, struct sdw_bpt_section *= sec, int num_sec, + int data_per_frame, u8 *dma_buffer, + int dma_buffer_size, int *dma_buffer_total_bytes) { int total_dma_data_written =3D 0; u8 *p_dma_buffer =3D dma_buffer; u8 header[SDW_CDNS_BRA_HDR]; + unsigned int start_register; + unsigned int section_size; int dma_data_written; - u8 *p_data =3D data; + u8 *p_data; u8 counter; int ret; + int i; =20 counter =3D CDNS_BPT_ROLLING_COUNTER_START; =20 @@ -2342,47 +2345,57 @@ int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, u= 32 start_register, u8 *data, header[0] |=3D GENMASK(7, 6); /* header is active */ header[0] |=3D (dev_num << 2); =20 - while (data_size >=3D data_per_frame) { - header[1] =3D data_per_frame; - header[2] =3D start_register >> 24 & 0xFF; - header[3] =3D start_register >> 16 & 0xFF; - header[4] =3D start_register >> 8 & 0xFF; - header[5] =3D start_register >> 0 & 0xFF; - - ret =3D sdw_cdns_prepare_write_pd0_buffer(header, SDW_CDNS_BRA_HDR, - p_data, data_per_frame, - p_dma_buffer, dma_buffer_size, - &dma_data_written, counter); - if (ret < 0) - return ret; - - counter++; - - p_data +=3D data_per_frame; - data_size -=3D data_per_frame; - - p_dma_buffer +=3D dma_data_written; - dma_buffer_size -=3D dma_data_written; - total_dma_data_written +=3D dma_data_written; - - start_register +=3D data_per_frame; - } - - if (data_size) { - header[1] =3D data_size; - header[2] =3D start_register >> 24 & 0xFF; - header[3] =3D start_register >> 16 & 0xFF; - header[4] =3D start_register >> 8 & 0xFF; - header[5] =3D start_register >> 0 & 0xFF; - - ret =3D sdw_cdns_prepare_write_pd0_buffer(header, SDW_CDNS_BRA_HDR, - p_data, data_size, - p_dma_buffer, dma_buffer_size, - &dma_data_written, counter); - if (ret < 0) - return ret; - - total_dma_data_written +=3D dma_data_written; + for (i =3D 0; i < num_sec; i++) { + start_register =3D sec[i].addr; + section_size =3D sec[i].len; + p_data =3D sec[i].buf; + + while (section_size >=3D data_per_frame) { + header[1] =3D data_per_frame; + header[2] =3D start_register >> 24 & 0xFF; + header[3] =3D start_register >> 16 & 0xFF; + header[4] =3D start_register >> 8 & 0xFF; + header[5] =3D start_register >> 0 & 0xFF; + + ret =3D sdw_cdns_prepare_write_pd0_buffer(header, SDW_CDNS_BRA_HDR, + p_data, data_per_frame, + p_dma_buffer, dma_buffer_size, + &dma_data_written, counter); + if (ret < 0) + return ret; + + counter++; + + p_data +=3D data_per_frame; + section_size -=3D data_per_frame; + + p_dma_buffer +=3D dma_data_written; + dma_buffer_size -=3D dma_data_written; + total_dma_data_written +=3D dma_data_written; + + start_register +=3D data_per_frame; + } + + if (section_size) { + header[1] =3D section_size; + header[2] =3D start_register >> 24 & 0xFF; + header[3] =3D start_register >> 16 & 0xFF; + header[4] =3D start_register >> 8 & 0xFF; + header[5] =3D start_register >> 0 & 0xFF; + + ret =3D sdw_cdns_prepare_write_pd0_buffer(header, SDW_CDNS_BRA_HDR, + p_data, section_size, + p_dma_buffer, dma_buffer_size, + &dma_data_written, counter); + if (ret < 0) + return ret; + + counter++; + + p_dma_buffer +=3D dma_data_written; + dma_buffer_size -=3D dma_data_written; + total_dma_data_written +=3D dma_data_written; + } } =20 *dma_buffer_total_bytes =3D total_dma_data_written; @@ -2391,16 +2404,19 @@ int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, u= 32 start_register, u8 *data, } EXPORT_SYMBOL(sdw_cdns_prepare_write_dma_buffer); =20 -int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, u32 start_register, int d= ata_size, +int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, struct sdw_bpt_section *s= ec, int num_sec, int data_per_frame, u8 *dma_buffer, int dma_buffer_size, int *dma_buffer_total_bytes, unsigned int fake_size) { int total_dma_data_written =3D 0; u8 *p_dma_buffer =3D dma_buffer; u8 header[SDW_CDNS_BRA_HDR]; + unsigned int start_register; + unsigned int data_size; int dma_data_written; u8 counter; int ret; + int i; =20 counter =3D CDNS_BPT_ROLLING_COUNTER_START; =20 @@ -2408,48 +2424,52 @@ int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, u3= 2 start_register, int data_si header[0] |=3D GENMASK(7, 6); /* header is active */ header[0] |=3D (dev_num << 2); =20 - while (data_size >=3D data_per_frame) { - header[1] =3D data_per_frame; - header[2] =3D start_register >> 24 & 0xFF; - header[3] =3D start_register >> 16 & 0xFF; - header[4] =3D start_register >> 8 & 0xFF; - header[5] =3D start_register >> 0 & 0xFF; - - ret =3D sdw_cdns_prepare_read_pd0_buffer(header, SDW_CDNS_BRA_HDR, p_dma= _buffer, - dma_buffer_size, &dma_data_written, - counter); - if (ret < 0) - return ret; - - counter++; - - data_size -=3D data_per_frame; - - p_dma_buffer +=3D dma_data_written; - dma_buffer_size -=3D dma_data_written; - total_dma_data_written +=3D dma_data_written; - - start_register +=3D data_per_frame; - } - - if (data_size) { - header[1] =3D data_size; - header[2] =3D start_register >> 24 & 0xFF; - header[3] =3D start_register >> 16 & 0xFF; - header[4] =3D start_register >> 8 & 0xFF; - header[5] =3D start_register >> 0 & 0xFF; - - ret =3D sdw_cdns_prepare_read_pd0_buffer(header, SDW_CDNS_BRA_HDR, p_dma= _buffer, - dma_buffer_size, &dma_data_written, - counter); - if (ret < 0) - return ret; - - counter++; - - p_dma_buffer +=3D dma_data_written; - dma_buffer_size -=3D dma_data_written; - total_dma_data_written +=3D dma_data_written; + for (i =3D 0; i < num_sec; i++) { + start_register =3D sec[i].addr; + data_size =3D sec[i].len; + while (data_size >=3D data_per_frame) { + header[1] =3D data_per_frame; + header[2] =3D start_register >> 24 & 0xFF; + header[3] =3D start_register >> 16 & 0xFF; + header[4] =3D start_register >> 8 & 0xFF; + header[5] =3D start_register >> 0 & 0xFF; + + ret =3D sdw_cdns_prepare_read_pd0_buffer(header, SDW_CDNS_BRA_HDR, + p_dma_buffer, dma_buffer_size, + &dma_data_written, counter); + if (ret < 0) + return ret; + + counter++; + + data_size -=3D data_per_frame; + + p_dma_buffer +=3D dma_data_written; + dma_buffer_size -=3D dma_data_written; + total_dma_data_written +=3D dma_data_written; + + start_register +=3D data_per_frame; + } + + if (data_size) { + header[1] =3D data_size; + header[2] =3D start_register >> 24 & 0xFF; + header[3] =3D start_register >> 16 & 0xFF; + header[4] =3D start_register >> 8 & 0xFF; + header[5] =3D start_register >> 0 & 0xFF; + + ret =3D sdw_cdns_prepare_read_pd0_buffer(header, SDW_CDNS_BRA_HDR, + p_dma_buffer, dma_buffer_size, + &dma_data_written, counter); + if (ret < 0) + return ret; + + counter++; + + p_dma_buffer +=3D dma_data_written; + dma_buffer_size -=3D dma_data_written; + total_dma_data_written +=3D dma_data_written; + } } =20 /* Add fake frame */ @@ -2616,9 +2636,12 @@ static u8 extract_read_data(u32 *data, int num_bytes= , u8 *buffer) } =20 int sdw_cdns_check_read_response(struct device *dev, u8 *dma_buffer, int d= ma_buffer_size, - u8 *buffer, int buffer_size, int num_frames, int data_per_frame) + struct sdw_bpt_section *sec, int num_sec, int num_frames, + int data_per_frame) { int total_num_bytes =3D 0; + int buffer_size =3D 0; + int sec_index; u32 *p_data; u8 *p_buf; int counter; @@ -2632,7 +2655,10 @@ int sdw_cdns_check_read_response(struct device *dev,= u8 *dma_buffer, int dma_buf =20 counter =3D CDNS_BPT_ROLLING_COUNTER_START; p_data =3D (u32 *)dma_buffer; - p_buf =3D buffer; + + sec_index =3D 0; + p_buf =3D sec[sec_index].buf; + buffer_size =3D sec[sec_index].len; =20 for (i =3D 0; i < num_frames; i++) { header =3D *p_data++; @@ -2672,6 +2698,18 @@ int sdw_cdns_check_read_response(struct device *dev,= u8 *dma_buffer, int dma_buf =20 counter++; counter &=3D GENMASK(3, 0); + + if (buffer_size =3D=3D total_num_bytes && (i + 1) < num_frames) { + sec_index++; + if (sec_index >=3D num_sec) { + dev_err(dev, "%s: incorrect section index %d i %d\n", + __func__, sec_index, i); + return -EINVAL; + } + p_buf =3D sec[sec_index].buf; + buffer_size =3D sec[sec_index].len; + total_num_bytes =3D 0; + } } return 0; } diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence= _master.h index a269a87486fc..668f807cff4b 100644 --- a/drivers/soundwire/cadence_master.h +++ b/drivers/soundwire/cadence_master.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ /* Copyright(c) 2015-17 Intel Corporation. */ #include +#include "bus.h" =20 #ifndef __SDW_CADENCE_H #define __SDW_CADENCE_H @@ -220,11 +221,11 @@ int sdw_cdns_bpt_find_buffer_sizes(int command, /* 0:= write, 1: read */ unsigned int *data_per_frame, unsigned int *pdi0_buffer_size, unsigned int *pdi1_buffer_size, unsigned int *num_frames); =20 -int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, u32 start_register, u8 *= data, int data_size, - int data_per_frame, u8 *dma_buffer, int dma_buffer_size, - int *dma_buffer_total_bytes); +int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, struct sdw_bpt_section *= sec, int num_sec, + int data_per_frame, u8 *dma_buffer, + int dma_buffer_size, int *dma_buffer_total_bytes); =20 -int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, u32 start_register, int d= ata_size, +int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, struct sdw_bpt_section *s= ec, int num_sec, int data_per_frame, u8 *dma_buffer, int dma_buffer_size, int *dma_buffer_total_bytes, unsigned int fake_size); =20 @@ -232,5 +233,6 @@ int sdw_cdns_check_write_response(struct device *dev, u= 8 *dma_buffer, int dma_buffer_size, int num_frames); =20 int sdw_cdns_check_read_response(struct device *dev, u8 *dma_buffer, int d= ma_buffer_size, - u8 *buffer, int buffer_size, int num_frames, int data_per_frame); + struct sdw_bpt_section *sec, int num_sec, int num_frames, + int data_per_frame); #endif /* __SDW_CADENCE_H */ diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2= x.c index a0f708a7cdff..300ede6bc7f1 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -220,14 +220,12 @@ static int intel_ace2x_bpt_open_stream(struct sdw_int= el *sdw, struct sdw_slave * } =20 if (!command) { - ret =3D sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->sec[0].addr, - msg->sec[0].buf, - msg->sec[0].len, data_per_frame, + ret =3D sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->sec, 1, + data_per_frame, sdw->bpt_ctx.dmab_tx_bdl.area, pdi0_buffer_size, &tx_total_bytes); } else { - ret =3D sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->sec[0].addr, - msg->sec[0].len, + ret =3D sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->sec, 1, data_per_frame, sdw->bpt_ctx.dmab_tx_bdl.area, pdi0_buffer_size, &tx_total_bytes, @@ -370,8 +368,7 @@ static int intel_ace2x_bpt_wait(struct sdw_intel *sdw, = struct sdw_slave *slave, } else { ret =3D sdw_cdns_check_read_response(cdns->dev, sdw->bpt_ctx.dmab_rx_bdl= .area, sdw->bpt_ctx.pdi1_buffer_size, - msg->sec[0].buf, msg->sec[0].len, - sdw->bpt_ctx.num_frames, + msg->sec, 1, 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); --=20 2.43.0 From nobody Sun Feb 8 11:40:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC7E92F7477; Tue, 21 Oct 2025 09:44:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761039854; cv=none; b=uC4nMcpzLiAYSDSmmfaHS9CrKALN9Tf4/x7Y7xnLjHyYGAAvfRPFVtO7CZxBH0spF8z5aWEaequE5w+z4+LFr49LIGupe70B+DYHKV+fRo9vgvTWlxEibPfJ70Nq7IvRNKxZvakjk7yITTKs5lsb8NlDhB3qA4+6PkzOBf/b8fc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761039854; c=relaxed/simple; bh=OWlyyNOYBGSGibczZQ13ngOi8rR10xLww/Jd9naPUoo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p7i+/zvJ7S6RtjmcwTZGQzjIT0NIf4oBL2cKyb/baCD7BxnAMdXR7MnSo7NDIU8cGEThbGjuIdi0rsD4a+cSumQBD1kDwj5chNW4/g40dBwqvp0jLx3lm4wf/H+JQYNjGxClC4dEQjixjNjjjKvYBK2b+3gQa84EocxHTHjmDt0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=WJl3JGZf; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="WJl3JGZf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1761039853; x=1792575853; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OWlyyNOYBGSGibczZQ13ngOi8rR10xLww/Jd9naPUoo=; b=WJl3JGZfHMKvcUBDA8cS4xhkjyltRUQyAYXdQD0Py64ahn7K4OjbwbDW Zv4mju3A7kC7twQftPursTRyDaxWFmrm7eYT/3nORpBQs3/c/MePr1+Oh trch2f8d66rKWKN6UrxqBDasZTPVg3iCj/SVBUpyAOlNYVYYpZMCaOQv9 sURWLC33FZ7NRi3FiYLjPtR54DdpRZVLzuumpxF2kmqq0DW9AT4oJylYT RIHIPXXLDOZL4HitTRu0BW78H5gtKpTqUSoUeMFULv4ztTUWoGv/eeIoD BhrEIXv6wUq/Qx2ua1YUqJ5fjnLPZ3qN6ObRpYAPvKIxWxwNoCD0vHZTX A==; X-CSE-ConnectionGUID: t79QAjKNRR+ifY2H6cvTjA== X-CSE-MsgGUID: cL4Q2sMbSXirH2oDz91/GQ== X-IronPort-AV: E=McAfee;i="6800,10657,11586"; a="63259380" X-IronPort-AV: E=Sophos;i="6.19,244,1754982000"; d="scan'208";a="63259380" Received: from orviesa010.jf.intel.com ([10.64.159.150]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2025 02:44:12 -0700 X-CSE-ConnectionGUID: DG1ESi1VTtmCMxjPK2oflg== X-CSE-MsgGUID: mFiaFOHDTSaxVYzMzphcew== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,244,1754982000"; d="scan'208";a="182753545" Received: from yungchua-desk.itwn.intel.com ([10.227.8.136]) by orviesa010-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2025 02:44:11 -0700 From: Bard Liao To: linux-sound@vger.kernel.org, vkoul@kernel.org Cc: vinod.koul@linaro.org, linux-kernel@vger.kernel.org, pierre-louis.bossart@linux.dev, bard.liao@intel.com Subject: [PATCH 3/3] soundwire: intel_ace2x: handle multi BPT sections Date: Tue, 21 Oct 2025 17:43:54 +0800 Message-ID: <20251021094355.132943-4-yung-chuan.liao@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251021094355.132943-1-yung-chuan.liao@linux.intel.com> References: <20251021094355.132943-1-yung-chuan.liao@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Calculate required PDI buffer and pass the section number to the cdns BPT helpers. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Tested-by: Shuming Fan --- drivers/soundwire/intel_ace2x.c | 46 ++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2= x.c index 300ede6bc7f1..1ed0251d2592 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -57,6 +57,8 @@ 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 pdi0_buffer_size_; + unsigned int pdi1_buffer_size_; unsigned int pdi0_buffer_size; unsigned int tx_dma_bandwidth; unsigned int pdi1_buffer_size; @@ -68,6 +70,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *= sdw, struct sdw_slave * struct sdw_cdns_pdi *pdi1; unsigned int rx_alignment; unsigned int tx_alignment; + unsigned int num_frames_; unsigned int num_frames; unsigned int fake_size; unsigned int tx_pad; @@ -76,6 +79,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *= sdw, struct sdw_slave * int ret1; int ret; int dir; + int len; int i; =20 stream =3D sdw_alloc_stream("BPT", SDW_STREAM_BPT); @@ -155,12 +159,25 @@ static int intel_ace2x_bpt_open_stream(struct sdw_int= el *sdw, struct sdw_slave * if (ret < 0) goto deprepare_stream; =20 - ret =3D sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row, cdn= s->bus.params.col, - 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; + len =3D 0; + pdi0_buffer_size =3D 0; + pdi1_buffer_size =3D 0; + num_frames =3D 0; + /* Add up pdi buffer size and frame numbers of each BPT sections */ + for (i =3D 0; i < msg->sections; i++) { + ret =3D sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row, + cdns->bus.params.col, + msg->sec[i].len, SDW_BPT_MSG_MAX_BYTES, + &data_per_frame, &pdi0_buffer_size_, + &pdi1_buffer_size_, &num_frames_); + if (ret < 0) + goto deprepare_stream; + + len +=3D msg->sec[i].len; + pdi0_buffer_size +=3D pdi0_buffer_size_; + pdi1_buffer_size +=3D pdi1_buffer_size_; + num_frames +=3D num_frames_; + } =20 sdw->bpt_ctx.pdi0_buffer_size =3D pdi0_buffer_size; sdw->bpt_ctx.pdi1_buffer_size =3D pdi1_buffer_size; @@ -205,7 +222,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel= *sdw, struct sdw_slave * } =20 dev_dbg(cdns->dev, "Message len %d transferred in %d frames (%d per frame= )\n", - msg->sec[0].len, num_frames, data_per_frame); + 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); =20 @@ -220,12 +237,12 @@ static int intel_ace2x_bpt_open_stream(struct sdw_int= el *sdw, struct sdw_slave * } =20 if (!command) { - ret =3D sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->sec, 1, + ret =3D sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->sec, msg->s= ections, data_per_frame, sdw->bpt_ctx.dmab_tx_bdl.area, pdi0_buffer_size, &tx_total_bytes); } else { - ret =3D sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->sec, 1, + ret =3D sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->sec, msg->se= ctions, data_per_frame, sdw->bpt_ctx.dmab_tx_bdl.area, pdi0_buffer_size, &tx_total_bytes, @@ -304,11 +321,16 @@ static int intel_ace2x_bpt_send_async(struct sdw_inte= l *sdw, struct sdw_slave *s struct sdw_bpt_msg *msg) { struct sdw_cdns *cdns =3D &sdw->cdns; + int len =3D 0; int ret; + int i; =20 - if (msg->sec[0].len < INTEL_BPT_MSG_BYTE_MIN) { + for (i =3D 0; i < msg->sections; i++) + len +=3D msg->sec[i].len; + + if (len < INTEL_BPT_MSG_BYTE_MIN) { dev_err(cdns->dev, "BPT message length %d is less than the minimum bytes= %d\n", - msg->sec[0].len, INTEL_BPT_MSG_BYTE_MIN); + len, INTEL_BPT_MSG_BYTE_MIN); return -EINVAL; } =20 @@ -368,7 +390,7 @@ static int intel_ace2x_bpt_wait(struct sdw_intel *sdw, = struct sdw_slave *slave, } else { ret =3D sdw_cdns_check_read_response(cdns->dev, sdw->bpt_ctx.dmab_rx_bdl= .area, sdw->bpt_ctx.pdi1_buffer_size, - msg->sec, 1, sdw->bpt_ctx.num_frames, + msg->sec, msg->sections, 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); --=20 2.43.0