@@ -44,6 +44,8 @@ static int sdw_slave_bpt_stream_add(struct sdw_slave *slave, struct sdw_stream_r
4444 return ret ;
4545}
4646
47+ #define READ_PDI1_MIN_SIZE 12
48+
4749static int intel_ace2x_bpt_open_stream (struct sdw_intel * sdw , struct sdw_slave * slave ,
4850 struct sdw_bpt_msg * msg )
4951{
@@ -53,15 +55,23 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
5355 struct sdw_stream_runtime * stream ;
5456 struct sdw_stream_config sconfig ;
5557 struct sdw_port_config * pconfig ;
58+ unsigned int pdi0_buf_size_pre_frame ;
59+ unsigned int pdi1_buf_size_pre_frame ;
5660 unsigned int pdi0_buffer_size ;
5761 unsigned int tx_dma_bandwidth ;
5862 unsigned int pdi1_buffer_size ;
5963 unsigned int rx_dma_bandwidth ;
64+ unsigned int fake_num_frames ;
6065 unsigned int data_per_frame ;
6166 unsigned int tx_total_bytes ;
6267 struct sdw_cdns_pdi * pdi0 ;
6368 struct sdw_cdns_pdi * pdi1 ;
69+ unsigned int rx_alignment ;
70+ unsigned int tx_alignment ;
6471 unsigned int num_frames ;
72+ unsigned int fake_size ;
73+ unsigned int tx_pad ;
74+ unsigned int rx_pad ;
6575 int command ;
6676 int ret1 ;
6777 int ret ;
@@ -138,6 +148,13 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
138148
139149 command = (msg -> flags & SDW_MSG_FLAG_WRITE ) ? 0 : 1 ;
140150
151+ ret = sdw_cdns_bpt_find_bandwidth (command , cdns -> bus .params .row ,
152+ cdns -> bus .params .col ,
153+ prop -> default_frame_rate ,
154+ & tx_dma_bandwidth , & rx_dma_bandwidth );
155+ if (ret < 0 )
156+ goto deprepare_stream ;
157+
141158 ret = sdw_cdns_bpt_find_buffer_sizes (command , cdns -> bus .params .row , cdns -> bus .params .col ,
142159 msg -> len , SDW_BPT_MSG_MAX_BYTES , & data_per_frame ,
143160 & pdi0_buffer_size , & pdi1_buffer_size , & num_frames );
@@ -148,10 +165,44 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
148165 sdw -> bpt_ctx .pdi1_buffer_size = pdi1_buffer_size ;
149166 sdw -> bpt_ctx .num_frames = num_frames ;
150167 sdw -> bpt_ctx .data_per_frame = data_per_frame ;
151- tx_dma_bandwidth = div_u64 ((u64 )pdi0_buffer_size * 8 * (u64 )prop -> default_frame_rate ,
152- num_frames );
153- rx_dma_bandwidth = div_u64 ((u64 )pdi1_buffer_size * 8 * (u64 )prop -> default_frame_rate ,
154- num_frames );
168+
169+ rx_alignment = hda_sdw_bpt_get_buf_size_alignment (rx_dma_bandwidth );
170+ tx_alignment = hda_sdw_bpt_get_buf_size_alignment (tx_dma_bandwidth );
171+
172+ if (command ) { /* read */
173+ /* Get buffer size of a full frame */
174+ ret = sdw_cdns_bpt_find_buffer_sizes (command , cdns -> bus .params .row ,
175+ cdns -> bus .params .col ,
176+ data_per_frame , SDW_BPT_MSG_MAX_BYTES ,
177+ & data_per_frame , & pdi0_buf_size_pre_frame ,
178+ & pdi1_buf_size_pre_frame , & fake_num_frames );
179+ if (ret < 0 )
180+ goto deprepare_stream ;
181+
182+ /* find fake pdi1 buffer size */
183+ rx_pad = rx_alignment - (pdi1_buffer_size % rx_alignment );
184+ while (rx_pad <= READ_PDI1_MIN_SIZE ) {
185+ rx_pad += rx_alignment ;
186+ }
187+ pdi1_buffer_size += rx_pad ;
188+ /* It is fine if we request more than enough byte to read */
189+ fake_num_frames = DIV_ROUND_UP (rx_pad , pdi1_buf_size_pre_frame );
190+ fake_size = fake_num_frames * data_per_frame ;
191+
192+ /* find fake pdi0 buffer size */
193+ pdi0_buffer_size += (fake_num_frames * pdi0_buf_size_pre_frame );
194+ tx_pad = tx_alignment - (pdi0_buffer_size % tx_alignment );
195+ pdi0_buffer_size += tx_pad ;
196+ } else { /* write */
197+ /*
198+ * For the write command, the rx data block is 4, and the rx buffer size of a frame
199+ * is 8. So the rx buffer size (pdi0_buffer_size) is always a mutiple of rx
200+ * alignment.
201+ */
202+ tx_pad = tx_alignment - (pdi0_buffer_size % tx_alignment );
203+ pdi0_buffer_size += tx_pad ;
204+
205+ }
155206
156207 dev_dbg (cdns -> dev , "Message len %d transferred in %d frames (%d per frame)\n" ,
157208 msg -> len , num_frames , data_per_frame );
@@ -177,7 +228,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
177228 ret = sdw_cdns_prepare_read_dma_buffer (msg -> dev_num , msg -> addr , msg -> len ,
178229 data_per_frame ,
179230 sdw -> bpt_ctx .dmab_tx_bdl .area ,
180- pdi0_buffer_size , & tx_total_bytes , 0 );
231+ pdi0_buffer_size , & tx_total_bytes , fake_size );
181232 }
182233
183234 if (!ret )
0 commit comments