]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
soundwire: pass sdw_bpt_section to cdns BPT helpers
authorBard Liao <yung-chuan.liao@linux.intel.com>
Tue, 21 Oct 2025 09:43:53 +0000 (17:43 +0800)
committerVinod Koul <vkoul@kernel.org>
Mon, 8 Dec 2025 07:07:27 +0000 (12:37 +0530)
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 <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Tested-by: Shuming Fan <shumingf@realtek.com>
Link: https://patch.msgid.link/20251021094355.132943-3-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/soundwire/cadence_master.c
drivers/soundwire/cadence_master.h
drivers/soundwire/intel_ace2x.c

index 4e94da28d8ad8c5f0a7cb566c683fd632c12af0a..a106e5e482c8e3dd00c7d703a064f2b051ffc103 100644 (file)
@@ -2324,17 +2324,20 @@ static int sdw_cdns_prepare_read_pd0_buffer(u8 *header, unsigned int header_size
 
 #define CDNS_BPT_ROLLING_COUNTER_START 1
 
-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 = 0;
        u8 *p_dma_buffer = dma_buffer;
        u8 header[SDW_CDNS_BRA_HDR];
+       unsigned int start_register;
+       unsigned int section_size;
        int dma_data_written;
-       u8 *p_data = data;
+       u8 *p_data;
        u8 counter;
        int ret;
+       int i;
 
        counter = CDNS_BPT_ROLLING_COUNTER_START;
 
@@ -2342,47 +2345,57 @@ int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, u32 start_register, u8 *data,
        header[0] |= GENMASK(7, 6);     /* header is active */
        header[0] |= (dev_num << 2);
 
-       while (data_size >= data_per_frame) {
-               header[1] = data_per_frame;
-               header[2] = start_register >> 24 & 0xFF;
-               header[3] = start_register >> 16 & 0xFF;
-               header[4] = start_register >> 8 & 0xFF;
-               header[5] = start_register >> 0 & 0xFF;
-
-               ret = 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;
+       for (i = 0; i < num_sec; i++) {
+               start_register = sec[i].addr;
+               section_size = sec[i].len;
+               p_data = sec[i].buf;
 
-               counter++;
+               while (section_size >= data_per_frame) {
+                       header[1] = data_per_frame;
+                       header[2] = start_register >> 24 & 0xFF;
+                       header[3] = start_register >> 16 & 0xFF;
+                       header[4] = start_register >> 8 & 0xFF;
+                       header[5] = start_register >> 0 & 0xFF;
 
-               p_data += data_per_frame;
-               data_size -= data_per_frame;
+                       ret = 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;
 
-               p_dma_buffer += dma_data_written;
-               dma_buffer_size -= dma_data_written;
-               total_dma_data_written += dma_data_written;
+                       counter++;
 
-               start_register += data_per_frame;
-       }
+                       p_data += data_per_frame;
+                       section_size -= data_per_frame;
 
-       if (data_size) {
-               header[1] = data_size;
-               header[2] = start_register >> 24 & 0xFF;
-               header[3] = start_register >> 16 & 0xFF;
-               header[4] = start_register >> 8 & 0xFF;
-               header[5] = start_register >> 0 & 0xFF;
+                       p_dma_buffer += dma_data_written;
+                       dma_buffer_size -= dma_data_written;
+                       total_dma_data_written += dma_data_written;
 
-               ret = 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;
+                       start_register += data_per_frame;
+               }
 
-               total_dma_data_written += dma_data_written;
+               if (section_size) {
+                       header[1] = section_size;
+                       header[2] = start_register >> 24 & 0xFF;
+                       header[3] = start_register >> 16 & 0xFF;
+                       header[4] = start_register >> 8 & 0xFF;
+                       header[5] = start_register >> 0 & 0xFF;
+
+                       ret = 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 += dma_data_written;
+                       dma_buffer_size -= dma_data_written;
+                       total_dma_data_written += dma_data_written;
+               }
        }
 
        *dma_buffer_total_bytes = total_dma_data_written;
@@ -2391,16 +2404,19 @@ int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, u32 start_register, u8 *data,
 }
 EXPORT_SYMBOL(sdw_cdns_prepare_write_dma_buffer);
 
-int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, u32 start_register, int data_size,
+int sdw_cdns_prepare_read_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, unsigned int fake_size)
 {
        int total_dma_data_written = 0;
        u8 *p_dma_buffer = 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;
 
        counter = CDNS_BPT_ROLLING_COUNTER_START;
 
@@ -2408,48 +2424,52 @@ int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, u32 start_register, int data_si
        header[0] |= GENMASK(7, 6);     /* header is active */
        header[0] |= (dev_num << 2);
 
-       while (data_size >= data_per_frame) {
-               header[1] = data_per_frame;
-               header[2] = start_register >> 24 & 0xFF;
-               header[3] = start_register >> 16 & 0xFF;
-               header[4] = start_register >> 8 & 0xFF;
-               header[5] = start_register >> 0 & 0xFF;
+       for (i = 0; i < num_sec; i++) {
+               start_register = sec[i].addr;
+               data_size = sec[i].len;
+               while (data_size >= data_per_frame) {
+                       header[1] = data_per_frame;
+                       header[2] = start_register >> 24 & 0xFF;
+                       header[3] = start_register >> 16 & 0xFF;
+                       header[4] = start_register >> 8 & 0xFF;
+                       header[5] = start_register >> 0 & 0xFF;
 
-               ret = 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;
+                       ret = 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++;
+                       counter++;
 
-               data_size -= data_per_frame;
+                       data_size -= data_per_frame;
 
-               p_dma_buffer += dma_data_written;
-               dma_buffer_size -= dma_data_written;
-               total_dma_data_written += dma_data_written;
+                       p_dma_buffer += dma_data_written;
+                       dma_buffer_size -= dma_data_written;
+                       total_dma_data_written += dma_data_written;
 
-               start_register += data_per_frame;
-       }
+                       start_register += data_per_frame;
+               }
 
-       if (data_size) {
-               header[1] = data_size;
-               header[2] = start_register >> 24 & 0xFF;
-               header[3] = start_register >> 16 & 0xFF;
-               header[4] = start_register >> 8 & 0xFF;
-               header[5] = start_register >> 0 & 0xFF;
+               if (data_size) {
+                       header[1] = data_size;
+                       header[2] = start_register >> 24 & 0xFF;
+                       header[3] = start_register >> 16 & 0xFF;
+                       header[4] = start_register >> 8 & 0xFF;
+                       header[5] = start_register >> 0 & 0xFF;
 
-               ret = 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;
+                       ret = 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++;
+                       counter++;
 
-               p_dma_buffer += dma_data_written;
-               dma_buffer_size -= dma_data_written;
-               total_dma_data_written += dma_data_written;
+                       p_dma_buffer += dma_data_written;
+                       dma_buffer_size -= dma_data_written;
+                       total_dma_data_written += dma_data_written;
+               }
        }
 
        /* Add fake frame */
@@ -2616,9 +2636,12 @@ static u8 extract_read_data(u32 *data, int num_bytes, u8 *buffer)
 }
 
 int sdw_cdns_check_read_response(struct device *dev, u8 *dma_buffer, int dma_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 = 0;
+       int buffer_size = 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
 
        counter = CDNS_BPT_ROLLING_COUNTER_START;
        p_data = (u32 *)dma_buffer;
-       p_buf = buffer;
+
+       sec_index = 0;
+       p_buf = sec[sec_index].buf;
+       buffer_size = sec[sec_index].len;
 
        for (i = 0; i < num_frames; i++) {
                header = *p_data++;
@@ -2672,6 +2698,18 @@ int sdw_cdns_check_read_response(struct device *dev, u8 *dma_buffer, int dma_buf
 
                counter++;
                counter &= GENMASK(3, 0);
+
+               if (buffer_size == total_num_bytes && (i + 1) < num_frames) {
+                       sec_index++;
+                       if (sec_index >= num_sec) {
+                               dev_err(dev, "%s: incorrect section index %d i %d\n",
+                                       __func__, sec_index, i);
+                               return -EINVAL;
+                       }
+                       p_buf = sec[sec_index].buf;
+                       buffer_size = sec[sec_index].len;
+                       total_num_bytes = 0;
+               }
        }
        return 0;
 }
index a269a87486fc6d5d506b3275f9035d012092c736..668f807cff4b239d242559558f2173aea279897b 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
 /* Copyright(c) 2015-17 Intel Corporation. */
 #include <sound/soc.h>
+#include "bus.h"
 
 #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);
 
-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 sdw_cdns_prepare_read_dma_buffer(u8 dev_num, u32 start_register, int data_size,
+int sdw_cdns_prepare_read_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, unsigned int fake_size);
 
@@ -232,5 +233,6 @@ int sdw_cdns_check_write_response(struct device *dev, u8 *dma_buffer,
                                  int dma_buffer_size, int num_frames);
 
 int sdw_cdns_check_read_response(struct device *dev, u8 *dma_buffer, int dma_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 */
index a0f708a7cdff00a9597482bfdbf889460073855b..300ede6bc7f132db14b362571c0f7758ab70ea4c 100644 (file)
@@ -220,14 +220,12 @@ 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->sec[0].addr,
-                                                       msg->sec[0].buf,
-                                                       msg->sec[0].len, data_per_frame,
+               ret = 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 = sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->sec[0].addr,
-                                                      msg->sec[0].len,
+               ret = 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 = 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);