1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 // 3 // This file is provided under a dual BSD/GPLv2 license. When using or 4 // redistributing this file, you may do so under either license. 5 // 6 // Copyright(c) 2025 Intel Corporation. 7 // 8 9 /* 10 * Hardware interface for SoundWire BPT support with HDA DMA 11 */ 12 13 #include <linux/lcm.h> 14 #include <sound/hdaudio_ext.h> 15 #include <sound/hda-mlink.h> 16 #include <sound/hda-sdw-bpt.h> 17 #include <sound/sof.h> 18 #include <sound/sof/ipc4/header.h> 19 #include "../ops.h" 20 #include "../sof-priv.h" 21 #include "../ipc4-priv.h" 22 #include "hda.h" 23 24 #define BPT_FREQUENCY 192000 /* The max rate defined in rate_bits[] hdac_device.c */ 25 #define BPT_MULTIPLIER ((BPT_FREQUENCY / 48000) - 1) 26 #define BPT_CHAIN_DMA_FIFO_MS 10 27 /* 28 * This routine is directly inspired by sof_ipc4_chain_dma_trigger(), 29 * with major simplifications since there are no pipelines defined 30 * and no dependency on ALSA hw_params 31 */ 32 static int chain_dma_trigger(struct snd_sof_dev *sdev, unsigned int stream_tag, 33 int direction, int state) 34 { 35 struct sof_ipc4_fw_data *ipc4_data = sdev->private; 36 bool allocate, enable, set_fifo_size; 37 struct sof_ipc4_msg msg = {{ 0 }}; 38 int dma_id; 39 40 if (sdev->pdata->ipc_type != SOF_IPC_TYPE_4) 41 return -EOPNOTSUPP; 42 43 switch (state) { 44 case SOF_IPC4_PIPE_RUNNING: /* Allocate and start the chain */ 45 allocate = true; 46 enable = true; 47 set_fifo_size = true; 48 break; 49 case SOF_IPC4_PIPE_PAUSED: /* Stop the chain */ 50 allocate = true; 51 enable = false; 52 set_fifo_size = false; 53 break; 54 case SOF_IPC4_PIPE_RESET: /* Deallocate chain resources and remove the chain */ 55 allocate = false; 56 enable = false; 57 set_fifo_size = false; 58 break; 59 default: 60 dev_err(sdev->dev, "Unexpected state %d", state); 61 return -EINVAL; 62 } 63 64 msg.primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CHAIN_DMA); 65 msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 66 msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); 67 68 /* for BPT/BRA we can use the same stream tag for host and link */ 69 dma_id = stream_tag - 1; 70 if (direction == SNDRV_PCM_STREAM_CAPTURE) 71 dma_id += ipc4_data->num_playback_streams; 72 73 msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(dma_id); 74 msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(dma_id); 75 76 /* For BPT/BRA we use 32 bits so SCS is not set */ 77 78 /* CHAIN DMA needs at least 2ms */ 79 if (set_fifo_size) 80 msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(BPT_FREQUENCY / 1000 * 81 BPT_CHAIN_DMA_FIFO_MS * 82 sizeof(u32)); 83 84 if (allocate) 85 msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_ALLOCATE_MASK; 86 87 if (enable) 88 msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_ENABLE_MASK; 89 90 return sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); 91 } 92 93 static int hda_sdw_bpt_dma_prepare(struct device *dev, struct hdac_ext_stream **sdw_bpt_stream, 94 struct snd_dma_buffer *dmab_bdl, u32 bpt_num_bytes, 95 unsigned int num_channels, int direction) 96 { 97 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 98 struct hdac_ext_stream *bpt_stream; 99 unsigned int format = HDA_CL_STREAM_FORMAT; 100 101 if (!sdev->dspless_mode_selected) { 102 int ret; 103 104 /* 105 * Make sure that the DSP is booted up, which might not be the 106 * case if the on-demand DSP boot is used 107 */ 108 ret = snd_sof_boot_dsp_firmware(sdev); 109 if (ret) 110 return ret; 111 } 112 /* 113 * the baseline format needs to be adjusted to 114 * bandwidth requirements 115 */ 116 format |= (num_channels - 1); 117 format |= BPT_MULTIPLIER << AC_FMT_MULT_SHIFT; 118 119 dev_dbg(dev, "direction %d format_val %#x\n", direction, format); 120 121 bpt_stream = hda_cl_prepare(dev, format, bpt_num_bytes, dmab_bdl, false, direction, false); 122 if (IS_ERR(bpt_stream)) { 123 dev_err(sdev->dev, "%s: SDW BPT DMA prepare failed: dir %d\n", 124 __func__, direction); 125 return PTR_ERR(bpt_stream); 126 } 127 *sdw_bpt_stream = bpt_stream; 128 129 if (!sdev->dspless_mode_selected) { 130 struct hdac_stream *hstream; 131 u32 mask; 132 133 /* decouple host and link DMA if the DSP is used */ 134 hstream = &bpt_stream->hstream; 135 mask = BIT(hstream->index); 136 137 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, mask, mask); 138 139 snd_hdac_ext_stream_reset(bpt_stream); 140 141 snd_hdac_ext_stream_setup(bpt_stream, format); 142 } 143 144 if (hdac_stream(bpt_stream)->direction == SNDRV_PCM_STREAM_PLAYBACK) { 145 struct hdac_bus *bus = sof_to_bus(sdev); 146 struct hdac_ext_link *hlink; 147 int stream_tag; 148 149 stream_tag = hdac_stream(bpt_stream)->stream_tag; 150 hlink = hdac_bus_eml_sdw_get_hlink(bus); 151 152 snd_hdac_ext_bus_link_set_stream_id(hlink, stream_tag); 153 } 154 return 0; 155 } 156 157 static int hda_sdw_bpt_dma_deprepare(struct device *dev, struct hdac_ext_stream *sdw_bpt_stream, 158 struct snd_dma_buffer *dmab_bdl) 159 { 160 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 161 struct hdac_stream *hstream; 162 u32 mask; 163 int ret; 164 165 ret = hda_cl_cleanup(sdev->dev, dmab_bdl, false, sdw_bpt_stream); 166 if (ret < 0) { 167 dev_err(sdev->dev, "%s: SDW BPT DMA cleanup failed\n", 168 __func__); 169 return ret; 170 } 171 172 if (hdac_stream(sdw_bpt_stream)->direction == SNDRV_PCM_STREAM_PLAYBACK) { 173 struct hdac_bus *bus = sof_to_bus(sdev); 174 struct hdac_ext_link *hlink; 175 int stream_tag; 176 177 stream_tag = hdac_stream(sdw_bpt_stream)->stream_tag; 178 hlink = hdac_bus_eml_sdw_get_hlink(bus); 179 180 snd_hdac_ext_bus_link_clear_stream_id(hlink, stream_tag); 181 } 182 183 if (!sdev->dspless_mode_selected) { 184 /* Release CHAIN_DMA resources */ 185 ret = chain_dma_trigger(sdev, hdac_stream(sdw_bpt_stream)->stream_tag, 186 hdac_stream(sdw_bpt_stream)->direction, 187 SOF_IPC4_PIPE_RESET); 188 if (ret < 0) 189 dev_err(sdev->dev, "%s: chain_dma_trigger PIPE_RESET failed: %d\n", 190 __func__, ret); 191 192 /* couple host and link DMA */ 193 hstream = &sdw_bpt_stream->hstream; 194 mask = BIT(hstream->index); 195 196 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, mask, 0); 197 } 198 199 return 0; 200 } 201 202 static int hda_sdw_bpt_dma_enable(struct device *dev, struct hdac_ext_stream *sdw_bpt_stream) 203 { 204 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 205 int ret; 206 207 ret = hda_cl_trigger(sdev->dev, sdw_bpt_stream, SNDRV_PCM_TRIGGER_START); 208 if (ret < 0) 209 dev_err(sdev->dev, "%s: SDW BPT DMA trigger start failed\n", __func__); 210 211 if (!sdev->dspless_mode_selected) { 212 /* the chain DMA needs to be programmed before the DMAs */ 213 ret = chain_dma_trigger(sdev, hdac_stream(sdw_bpt_stream)->stream_tag, 214 hdac_stream(sdw_bpt_stream)->direction, 215 SOF_IPC4_PIPE_RUNNING); 216 if (ret < 0) { 217 dev_err(sdev->dev, "%s: chain_dma_trigger failed: %d\n", 218 __func__, ret); 219 hda_cl_trigger(sdev->dev, sdw_bpt_stream, SNDRV_PCM_TRIGGER_STOP); 220 return ret; 221 } 222 snd_hdac_ext_stream_start(sdw_bpt_stream); 223 } 224 225 return ret; 226 } 227 228 static int hda_sdw_bpt_dma_disable(struct device *dev, struct hdac_ext_stream *sdw_bpt_stream) 229 { 230 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 231 int ret; 232 233 if (!sdev->dspless_mode_selected) { 234 snd_hdac_ext_stream_clear(sdw_bpt_stream); 235 236 ret = chain_dma_trigger(sdev, hdac_stream(sdw_bpt_stream)->stream_tag, 237 hdac_stream(sdw_bpt_stream)->direction, 238 SOF_IPC4_PIPE_PAUSED); 239 if (ret < 0) 240 dev_err(sdev->dev, "%s: chain_dma_trigger PIPE_PAUSED failed: %d\n", 241 __func__, ret); 242 } 243 244 ret = hda_cl_trigger(sdev->dev, sdw_bpt_stream, SNDRV_PCM_TRIGGER_STOP); 245 if (ret < 0) 246 dev_err(sdev->dev, "%s: SDW BPT DMA trigger stop failed\n", __func__); 247 248 return ret; 249 } 250 251 #define FIFO_ALIGNMENT 64 252 253 unsigned int hda_sdw_bpt_get_buf_size_alignment(unsigned int dma_bandwidth) 254 { 255 unsigned int num_channels = DIV_ROUND_UP(dma_bandwidth, BPT_FREQUENCY * 32); 256 unsigned int data_block = num_channels * 4; 257 unsigned int alignment = lcm(data_block, FIFO_ALIGNMENT); 258 259 return alignment; 260 } 261 EXPORT_SYMBOL_NS(hda_sdw_bpt_get_buf_size_alignment, "SND_SOC_SOF_INTEL_HDA_SDW_BPT"); 262 263 int hda_sdw_bpt_open(struct device *dev, int link_id, struct hdac_ext_stream **bpt_tx_stream, 264 struct snd_dma_buffer *dmab_tx_bdl, u32 bpt_tx_num_bytes, 265 u32 tx_dma_bandwidth, struct hdac_ext_stream **bpt_rx_stream, 266 struct snd_dma_buffer *dmab_rx_bdl, u32 bpt_rx_num_bytes, 267 u32 rx_dma_bandwidth) 268 { 269 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 270 unsigned int num_channels_tx; 271 unsigned int num_channels_rx; 272 int ret1; 273 int ret; 274 275 num_channels_tx = DIV_ROUND_UP(tx_dma_bandwidth, BPT_FREQUENCY * 32); 276 277 ret = hda_sdw_bpt_dma_prepare(dev, bpt_tx_stream, dmab_tx_bdl, bpt_tx_num_bytes, 278 num_channels_tx, SNDRV_PCM_STREAM_PLAYBACK); 279 if (ret < 0) { 280 dev_err(dev, "%s: hda_sdw_bpt_dma_prepare failed for TX: %d\n", 281 __func__, ret); 282 return ret; 283 } 284 285 num_channels_rx = DIV_ROUND_UP(rx_dma_bandwidth, BPT_FREQUENCY * 32); 286 287 ret = hda_sdw_bpt_dma_prepare(dev, bpt_rx_stream, dmab_rx_bdl, bpt_rx_num_bytes, 288 num_channels_rx, SNDRV_PCM_STREAM_CAPTURE); 289 if (ret < 0) { 290 dev_err(dev, "%s: hda_sdw_bpt_dma_prepare failed for RX: %d\n", 291 __func__, ret); 292 293 ret1 = hda_sdw_bpt_dma_deprepare(dev, *bpt_tx_stream, dmab_tx_bdl); 294 if (ret1 < 0) 295 dev_err(dev, "%s: hda_sdw_bpt_dma_deprepare failed for TX: %d\n", 296 __func__, ret1); 297 return ret; 298 } 299 300 /* we need to map the channels in PCMSyCM registers */ 301 ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, 302 0, /* cpu_dai->id -> PDI0 */ 303 GENMASK(num_channels_tx - 1, 0), 304 hdac_stream(*bpt_tx_stream)->stream_tag, 305 SNDRV_PCM_STREAM_PLAYBACK); 306 if (ret < 0) { 307 dev_err(dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed for TX: %d\n", 308 __func__, ret); 309 goto close; 310 } 311 312 ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, 313 1, /* cpu_dai->id -> PDI1 */ 314 GENMASK(num_channels_rx - 1, 0), 315 hdac_stream(*bpt_rx_stream)->stream_tag, 316 SNDRV_PCM_STREAM_CAPTURE); 317 if (!ret) 318 return 0; 319 320 dev_err(dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed for RX: %d\n", 321 __func__, ret); 322 323 close: 324 ret1 = hda_sdw_bpt_close(dev, *bpt_tx_stream, dmab_tx_bdl, *bpt_rx_stream, dmab_rx_bdl); 325 if (ret1 < 0) 326 dev_err(dev, "%s: hda_sdw_bpt_close failed: %d\n", 327 __func__, ret1); 328 329 return ret; 330 } 331 EXPORT_SYMBOL_NS(hda_sdw_bpt_open, "SND_SOC_SOF_INTEL_HDA_SDW_BPT"); 332 333 int hda_sdw_bpt_send_async(struct device *dev, struct hdac_ext_stream *bpt_tx_stream, 334 struct hdac_ext_stream *bpt_rx_stream) 335 { 336 int ret1; 337 int ret; 338 339 ret = hda_sdw_bpt_dma_enable(dev, bpt_tx_stream); 340 if (ret < 0) { 341 dev_err(dev, "%s: hda_sdw_bpt_dma_enable failed for TX: %d\n", 342 __func__, ret); 343 return ret; 344 } 345 346 ret = hda_sdw_bpt_dma_enable(dev, bpt_rx_stream); 347 if (ret < 0) { 348 dev_err(dev, "%s: hda_sdw_bpt_dma_enable failed for RX: %d\n", 349 __func__, ret); 350 351 ret1 = hda_sdw_bpt_dma_disable(dev, bpt_tx_stream); 352 if (ret1 < 0) 353 dev_err(dev, "%s: hda_sdw_bpt_dma_disable failed for TX: %d\n", 354 __func__, ret1); 355 } 356 357 return ret; 358 } 359 EXPORT_SYMBOL_NS(hda_sdw_bpt_send_async, "SND_SOC_SOF_INTEL_HDA_SDW_BPT"); 360 361 /* 362 * 3s is several orders of magnitude larger than what is needed for a 363 * typical firmware download. 364 */ 365 #define HDA_BPT_IOC_TIMEOUT_MS 3000 366 367 int hda_sdw_bpt_wait(struct device *dev, struct hdac_ext_stream *bpt_tx_stream, 368 struct hdac_ext_stream *bpt_rx_stream) 369 { 370 struct sof_intel_hda_stream *hda_tx_stream; 371 struct sof_intel_hda_stream *hda_rx_stream; 372 snd_pcm_uframes_t tx_position; 373 snd_pcm_uframes_t rx_position; 374 unsigned long time_tx_left; 375 unsigned long time_rx_left; 376 int ret = 0; 377 int ret1; 378 int i; 379 380 hda_tx_stream = container_of(bpt_tx_stream, struct sof_intel_hda_stream, hext_stream); 381 hda_rx_stream = container_of(bpt_rx_stream, struct sof_intel_hda_stream, hext_stream); 382 383 time_tx_left = wait_for_completion_timeout(&hda_tx_stream->ioc, 384 msecs_to_jiffies(HDA_BPT_IOC_TIMEOUT_MS)); 385 if (!time_tx_left) { 386 tx_position = hda_dsp_stream_get_position(hdac_stream(bpt_tx_stream), 387 SNDRV_PCM_STREAM_PLAYBACK, false); 388 dev_err(dev, "%s: SDW BPT TX DMA did not complete: %ld\n", 389 __func__, tx_position); 390 ret = -ETIMEDOUT; 391 goto dma_disable; 392 } 393 394 /* Make sure the DMA is flushed */ 395 i = 0; 396 do { 397 tx_position = hda_dsp_stream_get_position(hdac_stream(bpt_tx_stream), 398 SNDRV_PCM_STREAM_PLAYBACK, false); 399 usleep_range(1000, 1010); 400 i++; 401 } while (tx_position && i < HDA_BPT_IOC_TIMEOUT_MS); 402 if (tx_position) { 403 dev_err(dev, "%s: SDW BPT TX DMA position %ld was not cleared\n", 404 __func__, tx_position); 405 ret = -ETIMEDOUT; 406 goto dma_disable; 407 } 408 409 /* the wait should be minimal here */ 410 time_rx_left = wait_for_completion_timeout(&hda_rx_stream->ioc, 411 msecs_to_jiffies(HDA_BPT_IOC_TIMEOUT_MS)); 412 if (!time_rx_left) { 413 rx_position = hda_dsp_stream_get_position(hdac_stream(bpt_rx_stream), 414 SNDRV_PCM_STREAM_CAPTURE, false); 415 dev_err(dev, "%s: SDW BPT RX DMA did not complete: %ld\n", 416 __func__, rx_position); 417 ret = -ETIMEDOUT; 418 goto dma_disable; 419 } 420 421 /* Make sure the DMA is flushed */ 422 i = 0; 423 do { 424 rx_position = hda_dsp_stream_get_position(hdac_stream(bpt_rx_stream), 425 SNDRV_PCM_STREAM_CAPTURE, false); 426 usleep_range(1000, 1010); 427 i++; 428 } while (rx_position && i < HDA_BPT_IOC_TIMEOUT_MS); 429 if (rx_position) { 430 dev_err(dev, "%s: SDW BPT RX DMA position %ld was not cleared\n", 431 __func__, rx_position); 432 ret = -ETIMEDOUT; 433 goto dma_disable; 434 } 435 436 dma_disable: 437 ret1 = hda_sdw_bpt_dma_disable(dev, bpt_rx_stream); 438 if (!ret) 439 ret = ret1; 440 441 ret1 = hda_sdw_bpt_dma_disable(dev, bpt_tx_stream); 442 if (!ret) 443 ret = ret1; 444 445 return ret; 446 } 447 EXPORT_SYMBOL_NS(hda_sdw_bpt_wait, "SND_SOC_SOF_INTEL_HDA_SDW_BPT"); 448 449 int hda_sdw_bpt_close(struct device *dev, struct hdac_ext_stream *bpt_tx_stream, 450 struct snd_dma_buffer *dmab_tx_bdl, struct hdac_ext_stream *bpt_rx_stream, 451 struct snd_dma_buffer *dmab_rx_bdl) 452 { 453 int ret; 454 int ret1; 455 456 ret = hda_sdw_bpt_dma_deprepare(dev, bpt_rx_stream, dmab_rx_bdl); 457 458 ret1 = hda_sdw_bpt_dma_deprepare(dev, bpt_tx_stream, dmab_tx_bdl); 459 if (!ret) 460 ret = ret1; 461 462 return ret; 463 } 464 EXPORT_SYMBOL_NS(hda_sdw_bpt_close, "SND_SOC_SOF_INTEL_HDA_SDW_BPT"); 465 466 MODULE_LICENSE("Dual BSD/GPL"); 467 MODULE_DESCRIPTION("SOF helpers for HDaudio SoundWire BPT"); 468 MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); 469 MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); 470