1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 // 3 // Copyright(c) 2022 Intel Corporation. All rights reserved. 4 // 5 // Authors: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> 6 // 7 8 /* 9 * Hardware interface for audio DSP on Meteorlake. 10 */ 11 12 #include <linux/debugfs.h> 13 #include <linux/firmware.h> 14 #include <sound/sof/ipc4/header.h> 15 #include <trace/events/sof_intel.h> 16 #include "../ipc4-priv.h" 17 #include "../ops.h" 18 #include "hda.h" 19 #include "hda-ipc.h" 20 #include "../sof-audio.h" 21 #include "mtl.h" 22 #include "telemetry.h" 23 24 static const struct snd_sof_debugfs_map mtl_dsp_debugfs[] = { 25 {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS}, 26 {"pp", HDA_DSP_PP_BAR, 0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS}, 27 {"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS}, 28 }; 29 30 static void mtl_ipc_host_done(struct snd_sof_dev *sdev) 31 { 32 /* 33 * clear busy interrupt to tell dsp controller this interrupt has been accepted, 34 * not trigger it again 35 */ 36 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR, 37 MTL_DSP_REG_HFIPCXTDR_BUSY, MTL_DSP_REG_HFIPCXTDR_BUSY); 38 /* 39 * clear busy bit to ack dsp the msg has been processed and send reply msg to dsp 40 */ 41 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDA, 42 MTL_DSP_REG_HFIPCXTDA_BUSY, 0); 43 } 44 45 static void mtl_ipc_dsp_done(struct snd_sof_dev *sdev) 46 { 47 /* 48 * set DONE bit - tell DSP we have received the reply msg from DSP, and processed it, 49 * don't send more reply to host 50 */ 51 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA, 52 MTL_DSP_REG_HFIPCXIDA_DONE, MTL_DSP_REG_HFIPCXIDA_DONE); 53 54 /* unmask Done interrupt */ 55 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL, 56 MTL_DSP_REG_HFIPCXCTL_DONE, MTL_DSP_REG_HFIPCXCTL_DONE); 57 } 58 59 /* Check if an IPC IRQ occurred */ 60 bool mtl_dsp_check_ipc_irq(struct snd_sof_dev *sdev) 61 { 62 u32 irq_status; 63 u32 hfintipptr; 64 65 if (sdev->dspless_mode_selected) 66 return false; 67 68 /* read Interrupt IP Pointer */ 69 hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK; 70 irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr + MTL_DSP_IRQSTS); 71 72 trace_sof_intel_hda_irq_ipc_check(sdev, irq_status); 73 74 if (irq_status != U32_MAX && (irq_status & MTL_DSP_IRQSTS_IPC)) 75 return true; 76 77 return false; 78 } 79 80 /* Check if an SDW IRQ occurred */ 81 static bool mtl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) 82 { 83 u32 irq_status; 84 u32 hfintipptr; 85 86 /* read Interrupt IP Pointer */ 87 hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK; 88 irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr + MTL_DSP_IRQSTS); 89 90 if (irq_status != U32_MAX && (irq_status & MTL_DSP_IRQSTS_SDW)) 91 return true; 92 93 return false; 94 } 95 96 int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) 97 { 98 struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; 99 struct sof_ipc4_msg *msg_data = msg->msg_data; 100 101 if (hda_ipc4_tx_is_busy(sdev)) { 102 hdev->delayed_ipc_tx_msg = msg; 103 return 0; 104 } 105 106 hdev->delayed_ipc_tx_msg = NULL; 107 108 /* send the message via mailbox */ 109 if (msg_data->data_size) 110 sof_mailbox_write(sdev, sdev->host_box.offset, msg_data->data_ptr, 111 msg_data->data_size); 112 113 snd_sof_dsp_write(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDDY, 114 msg_data->extension); 115 snd_sof_dsp_write(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDR, 116 msg_data->primary | MTL_DSP_REG_HFIPCXIDR_BUSY); 117 118 hda_dsp_ipc4_schedule_d0i3_work(hdev, msg); 119 120 return 0; 121 } 122 123 void mtl_enable_ipc_interrupts(struct snd_sof_dev *sdev) 124 { 125 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 126 const struct sof_intel_dsp_desc *chip = hda->desc; 127 128 if (sdev->dspless_mode_selected) 129 return; 130 131 /* enable IPC DONE and BUSY interrupts */ 132 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl, 133 MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE, 134 MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE); 135 } 136 137 void mtl_disable_ipc_interrupts(struct snd_sof_dev *sdev) 138 { 139 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 140 const struct sof_intel_dsp_desc *chip = hda->desc; 141 142 if (sdev->dspless_mode_selected) 143 return; 144 145 /* disable IPC DONE and BUSY interrupts */ 146 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl, 147 MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE, 0); 148 } 149 150 static void mtl_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable) 151 { 152 u32 hipcie; 153 u32 mask; 154 u32 val; 155 int ret; 156 157 if (sdev->dspless_mode_selected) 158 return; 159 160 /* Enable/Disable SoundWire interrupt */ 161 mask = MTL_DSP_REG_HfSNDWIE_IE_MASK; 162 if (enable) 163 val = mask; 164 else 165 val = 0; 166 167 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, mask, val); 168 169 /* check if operation was successful */ 170 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, hipcie, 171 (hipcie & mask) == val, 172 HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); 173 if (ret < 0) 174 dev_err(sdev->dev, "failed to set SoundWire IPC interrupt %s\n", 175 enable ? "enable" : "disable"); 176 } 177 178 int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable) 179 { 180 u32 hfintipptr; 181 u32 irqinten; 182 u32 hipcie; 183 u32 mask; 184 u32 val; 185 int ret; 186 187 if (sdev->dspless_mode_selected) 188 return 0; 189 190 /* read Interrupt IP Pointer */ 191 hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK; 192 193 /* Enable/Disable Host IPC and SOUNDWIRE */ 194 mask = MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK; 195 if (enable) 196 val = mask; 197 else 198 val = 0; 199 200 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, hfintipptr, mask, val); 201 202 /* check if operation was successful */ 203 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, hfintipptr, irqinten, 204 (irqinten & mask) == val, 205 HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); 206 if (ret < 0) { 207 dev_err(sdev->dev, "failed to %s Host IPC and/or SOUNDWIRE\n", 208 enable ? "enable" : "disable"); 209 return ret; 210 } 211 212 /* Enable/Disable Host IPC interrupt*/ 213 mask = MTL_DSP_REG_HfHIPCIE_IE_MASK; 214 if (enable) 215 val = mask; 216 else 217 val = 0; 218 219 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, mask, val); 220 221 /* check if operation was successful */ 222 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, hipcie, 223 (hipcie & mask) == val, 224 HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); 225 if (ret < 0) { 226 dev_err(sdev->dev, "failed to set Host IPC interrupt %s\n", 227 enable ? "enable" : "disable"); 228 return ret; 229 } 230 231 return ret; 232 } 233 234 /* pre fw run operations */ 235 int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) 236 { 237 struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; 238 u32 dsphfpwrsts; 239 u32 dsphfdsscs; 240 u32 cpa; 241 u32 pgs; 242 int ret; 243 244 /* Set the DSP subsystem power on */ 245 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFDSSCS, 246 MTL_HFDSSCS_SPA_MASK, MTL_HFDSSCS_SPA_MASK); 247 248 /* Wait for unstable CPA read (1 then 0 then 1) just after setting SPA bit */ 249 usleep_range(1000, 1010); 250 251 /* poll with timeout to check if operation successful */ 252 cpa = MTL_HFDSSCS_CPA_MASK; 253 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFDSSCS, dsphfdsscs, 254 (dsphfdsscs & cpa) == cpa, HDA_DSP_REG_POLL_INTERVAL_US, 255 HDA_DSP_RESET_TIMEOUT_US); 256 if (ret < 0) { 257 dev_err(sdev->dev, "failed to enable DSP subsystem\n"); 258 return ret; 259 } 260 261 /* Power up gated-DSP-0 domain in order to access the DSP shim register block. */ 262 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL, 263 MTL_HFPWRCTL_WPDSPHPXPG, MTL_HFPWRCTL_WPDSPHPXPG); 264 265 usleep_range(1000, 1010); 266 267 /* poll with timeout to check if operation successful */ 268 pgs = MTL_HFPWRSTS_DSPHPXPGS_MASK; 269 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFPWRSTS, dsphfpwrsts, 270 (dsphfpwrsts & pgs) == pgs, 271 HDA_DSP_REG_POLL_INTERVAL_US, 272 HDA_DSP_RESET_TIMEOUT_US); 273 if (ret < 0) 274 dev_err(sdev->dev, "failed to power up gated DSP domain\n"); 275 276 /* if SoundWire is used, make sure it is not power-gated */ 277 if (hdev->info.handle && hdev->info.link_mask > 0) 278 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL, 279 MTL_HfPWRCTL_WPIOXPG(1), MTL_HfPWRCTL_WPIOXPG(1)); 280 281 return ret; 282 } 283 284 int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev) 285 { 286 int ret; 287 288 if (sdev->first_boot) { 289 struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; 290 291 ret = hda_sdw_startup(sdev); 292 if (ret < 0) { 293 dev_err(sdev->dev, "could not startup SoundWire links\n"); 294 return ret; 295 } 296 297 /* Check if IMR boot is usable */ 298 if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT)) { 299 hdev->imrboot_supported = true; 300 debugfs_create_bool("skip_imr_boot", 301 0644, sdev->debugfs_root, 302 &hdev->skip_imr_boot); 303 } 304 } 305 306 hda_sdw_int_enable(sdev, true); 307 return 0; 308 } 309 310 void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags) 311 { 312 char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR; 313 u32 romdbgsts; 314 u32 romdbgerr; 315 u32 fwsts; 316 u32 fwlec; 317 318 fwsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_ROM_STS); 319 fwlec = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_ROM_ERROR); 320 romdbgsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY); 321 romdbgerr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY_ERROR); 322 323 dev_err(sdev->dev, "ROM status: %#x, ROM error: %#x\n", fwsts, fwlec); 324 dev_err(sdev->dev, "ROM debug status: %#x, ROM debug error: %#x\n", romdbgsts, 325 romdbgerr); 326 romdbgsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY + 0x8 * 3); 327 dev_printk(level, sdev->dev, "ROM feature bit%s enabled\n", 328 romdbgsts & BIT(24) ? "" : " not"); 329 330 sof_ipc4_intel_dump_telemetry_state(sdev, flags); 331 } 332 333 static bool mtl_dsp_primary_core_is_enabled(struct snd_sof_dev *sdev) 334 { 335 int val; 336 337 val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE); 338 if (val != U32_MAX && val & MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK) 339 return true; 340 341 return false; 342 } 343 344 static int mtl_dsp_core_power_up(struct snd_sof_dev *sdev, int core) 345 { 346 unsigned int cpa; 347 u32 dspcxctl; 348 int ret; 349 350 /* Only the primary core can be powered up by the host */ 351 if (core != SOF_DSP_PRIMARY_CORE || mtl_dsp_primary_core_is_enabled(sdev)) 352 return 0; 353 354 /* Program the owner of the IP & shim registers (10: Host CPU) */ 355 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, 356 MTL_DSP2CXCTL_PRIMARY_CORE_OSEL, 357 0x2 << MTL_DSP2CXCTL_PRIMARY_CORE_OSEL_SHIFT); 358 359 /* enable SPA bit */ 360 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, 361 MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK, 362 MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK); 363 364 /* Wait for unstable CPA read (1 then 0 then 1) just after setting SPA bit */ 365 usleep_range(1000, 1010); 366 367 /* poll with timeout to check if operation successful */ 368 cpa = MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK; 369 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, dspcxctl, 370 (dspcxctl & cpa) == cpa, HDA_DSP_REG_POLL_INTERVAL_US, 371 HDA_DSP_RESET_TIMEOUT_US); 372 if (ret < 0) { 373 dev_err(sdev->dev, "%s: timeout on MTL_DSP2CXCTL_PRIMARY_CORE read\n", 374 __func__); 375 return ret; 376 } 377 378 /* set primary core mask and refcount to 1 */ 379 sdev->enabled_cores_mask = BIT(SOF_DSP_PRIMARY_CORE); 380 sdev->dsp_core_ref_count[SOF_DSP_PRIMARY_CORE] = 1; 381 382 return 0; 383 } 384 385 static int mtl_dsp_core_power_down(struct snd_sof_dev *sdev, int core) 386 { 387 u32 dspcxctl; 388 int ret; 389 390 /* Only the primary core can be powered down by the host */ 391 if (core != SOF_DSP_PRIMARY_CORE || !mtl_dsp_primary_core_is_enabled(sdev)) 392 return 0; 393 394 /* disable SPA bit */ 395 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, 396 MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK, 0); 397 398 /* Wait for unstable CPA read (0 then 1 then 0) just after setting SPA bit */ 399 usleep_range(1000, 1010); 400 401 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, dspcxctl, 402 !(dspcxctl & MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK), 403 HDA_DSP_REG_POLL_INTERVAL_US, 404 HDA_DSP_PD_TIMEOUT * USEC_PER_MSEC); 405 if (ret < 0) { 406 dev_err(sdev->dev, "failed to power down primary core\n"); 407 return ret; 408 } 409 410 sdev->enabled_cores_mask = 0; 411 sdev->dsp_core_ref_count[SOF_DSP_PRIMARY_CORE] = 0; 412 413 return 0; 414 } 415 416 int mtl_power_down_dsp(struct snd_sof_dev *sdev) 417 { 418 u32 dsphfdsscs, cpa; 419 int ret; 420 421 /* first power down core */ 422 ret = mtl_dsp_core_power_down(sdev, SOF_DSP_PRIMARY_CORE); 423 if (ret) { 424 dev_err(sdev->dev, "mtl dsp power down error, %d\n", ret); 425 return ret; 426 } 427 428 /* Set the DSP subsystem power down */ 429 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFDSSCS, 430 MTL_HFDSSCS_SPA_MASK, 0); 431 432 /* Wait for unstable CPA read (0 then 1 then 0) just after setting SPA bit */ 433 usleep_range(1000, 1010); 434 435 /* poll with timeout to check if operation successful */ 436 cpa = MTL_HFDSSCS_CPA_MASK; 437 dsphfdsscs = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFDSSCS); 438 return snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFDSSCS, dsphfdsscs, 439 (dsphfdsscs & cpa) == 0, HDA_DSP_REG_POLL_INTERVAL_US, 440 HDA_DSP_RESET_TIMEOUT_US); 441 } 442 443 int mtl_dsp_cl_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) 444 { 445 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 446 const struct sof_intel_dsp_desc *chip = hda->desc; 447 unsigned int status; 448 u32 ipc_hdr, flags; 449 char *dump_msg; 450 int ret; 451 452 /* step 1: purge FW request */ 453 ipc_hdr = chip->ipc_req_mask | HDA_DSP_ROM_IPC_CONTROL; 454 if (!imr_boot) 455 ipc_hdr |= HDA_DSP_ROM_IPC_PURGE_FW | ((stream_tag - 1) << 9); 456 457 snd_sof_dsp_write(sdev, HDA_DSP_BAR, chip->ipc_req, ipc_hdr); 458 459 /* step 2: power up primary core */ 460 ret = mtl_dsp_core_power_up(sdev, SOF_DSP_PRIMARY_CORE); 461 if (ret < 0) { 462 if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) 463 dev_err(sdev->dev, "dsp core 0/1 power up failed\n"); 464 goto err; 465 } 466 467 dev_dbg(sdev->dev, "Primary core power up successful\n"); 468 469 /* step 3: wait for IPC DONE bit from ROM */ 470 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, chip->ipc_ack, status, 471 ((status & chip->ipc_ack_mask) == chip->ipc_ack_mask), 472 HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_INIT_TIMEOUT_US); 473 if (ret < 0) { 474 if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) 475 dev_err(sdev->dev, "timeout waiting for purge IPC done\n"); 476 goto err; 477 } 478 479 /* set DONE bit to clear the reply IPC message */ 480 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, chip->ipc_ack, chip->ipc_ack_mask, 481 chip->ipc_ack_mask); 482 483 /* step 4: enable interrupts */ 484 ret = mtl_enable_interrupts(sdev, true); 485 if (ret < 0) { 486 if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) 487 dev_err(sdev->dev, "%s: failed to enable interrupts\n", __func__); 488 goto err; 489 } 490 491 mtl_enable_ipc_interrupts(sdev); 492 493 /* 494 * ACE workaround: don't wait for ROM INIT. 495 * The platform cannot catch ROM_INIT_DONE because of a very short 496 * timing window. Follow the recommendations and skip this part. 497 */ 498 499 return 0; 500 501 err: 502 flags = SOF_DBG_DUMP_PCI | SOF_DBG_DUMP_MBOX | SOF_DBG_DUMP_OPTIONAL; 503 504 /* after max boot attempts make sure that the dump is printed */ 505 if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) 506 flags &= ~SOF_DBG_DUMP_OPTIONAL; 507 508 dump_msg = kasprintf(GFP_KERNEL, "Boot iteration failed: %d/%d", 509 hda->boot_iteration, HDA_FW_BOOT_ATTEMPTS); 510 snd_sof_dsp_dbg_dump(sdev, dump_msg, flags); 511 mtl_dsp_core_power_down(sdev, SOF_DSP_PRIMARY_CORE); 512 513 kfree(dump_msg); 514 return ret; 515 } 516 517 irqreturn_t mtl_ipc_irq_thread(int irq, void *context) 518 { 519 struct sof_ipc4_msg notification_data = {{ 0 }}; 520 struct snd_sof_dev *sdev = context; 521 bool ack_received = false; 522 bool ipc_irq = false; 523 u32 hipcida; 524 u32 hipctdr; 525 526 hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA); 527 hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR); 528 529 /* reply message from DSP */ 530 if (hipcida & MTL_DSP_REG_HFIPCXIDA_DONE) { 531 /* DSP received the message */ 532 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL, 533 MTL_DSP_REG_HFIPCXCTL_DONE, 0); 534 535 mtl_ipc_dsp_done(sdev); 536 537 ipc_irq = true; 538 ack_received = true; 539 } 540 541 if (hipctdr & MTL_DSP_REG_HFIPCXTDR_BUSY) { 542 /* Message from DSP (reply or notification) */ 543 u32 extension = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDDY); 544 u32 primary = hipctdr & MTL_DSP_REG_HFIPCXTDR_MSG_MASK; 545 546 /* 547 * ACE fw sends a new fw ipc message to host to 548 * notify the status of the last host ipc message 549 */ 550 if (primary & SOF_IPC4_MSG_DIR_MASK) { 551 /* Reply received */ 552 if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) { 553 struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data; 554 555 data->primary = primary; 556 data->extension = extension; 557 558 spin_lock_irq(&sdev->ipc_lock); 559 560 snd_sof_ipc_get_reply(sdev); 561 mtl_ipc_host_done(sdev); 562 snd_sof_ipc_reply(sdev, data->primary); 563 564 spin_unlock_irq(&sdev->ipc_lock); 565 } else { 566 dev_dbg_ratelimited(sdev->dev, 567 "IPC reply before FW_READY: %#x|%#x\n", 568 primary, extension); 569 } 570 } else { 571 /* Notification received */ 572 notification_data.primary = primary; 573 notification_data.extension = extension; 574 575 sdev->ipc->msg.rx_data = ¬ification_data; 576 snd_sof_ipc_msgs_rx(sdev); 577 sdev->ipc->msg.rx_data = NULL; 578 579 mtl_ipc_host_done(sdev); 580 } 581 582 ipc_irq = true; 583 } 584 585 if (!ipc_irq) { 586 /* This interrupt is not shared so no need to return IRQ_NONE. */ 587 dev_dbg_ratelimited(sdev->dev, "nothing to do in IPC IRQ thread\n"); 588 } 589 590 if (ack_received) { 591 struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; 592 593 if (hdev->delayed_ipc_tx_msg) 594 mtl_ipc_send_msg(sdev, hdev->delayed_ipc_tx_msg); 595 } 596 597 return IRQ_HANDLED; 598 } 599 600 int mtl_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) 601 { 602 return MTL_DSP_MBOX_UPLINK_OFFSET; 603 } 604 605 int mtl_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id) 606 { 607 return MTL_SRAM_WINDOW_OFFSET(id); 608 } 609 610 void mtl_ipc_dump(struct snd_sof_dev *sdev) 611 { 612 u32 hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl; 613 614 hipcidr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDR); 615 hipcidd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDDY); 616 hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA); 617 hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR); 618 hipctdd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDDY); 619 hipctda = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDA); 620 hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL); 621 622 dev_err(sdev->dev, 623 "Host IPC initiator: %#x|%#x|%#x, target: %#x|%#x|%#x, ctl: %#x\n", 624 hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl); 625 } 626 627 static int mtl_dsp_disable_interrupts(struct snd_sof_dev *sdev) 628 { 629 mtl_enable_sdw_irq(sdev, false); 630 mtl_disable_ipc_interrupts(sdev); 631 return mtl_enable_interrupts(sdev, false); 632 } 633 634 u64 mtl_dsp_get_stream_hda_link_position(struct snd_sof_dev *sdev, 635 struct snd_soc_component *component, 636 struct snd_pcm_substream *substream) 637 { 638 struct hdac_stream *hstream = substream->runtime->private_data; 639 u32 llp_l, llp_u; 640 641 llp_l = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, MTL_PPLCLLPL(hstream->index)); 642 llp_u = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, MTL_PPLCLLPU(hstream->index)); 643 return ((u64)llp_u << 32) | llp_l; 644 } 645 646 int mtl_dsp_core_get(struct snd_sof_dev *sdev, int core) 647 { 648 const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm; 649 650 if (core == SOF_DSP_PRIMARY_CORE) 651 return mtl_dsp_core_power_up(sdev, SOF_DSP_PRIMARY_CORE); 652 653 if (pm_ops->set_core_state) 654 return pm_ops->set_core_state(sdev, core, true); 655 656 return 0; 657 } 658 659 int mtl_dsp_core_put(struct snd_sof_dev *sdev, int core) 660 { 661 const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm; 662 int ret; 663 664 if (pm_ops->set_core_state) { 665 ret = pm_ops->set_core_state(sdev, core, false); 666 if (ret < 0) 667 return ret; 668 } 669 670 if (core == SOF_DSP_PRIMARY_CORE) 671 return mtl_dsp_core_power_down(sdev, SOF_DSP_PRIMARY_CORE); 672 673 return 0; 674 } 675 676 /* Meteorlake ops */ 677 struct snd_sof_dsp_ops sof_mtl_ops; 678 EXPORT_SYMBOL_NS(sof_mtl_ops, SND_SOC_SOF_INTEL_HDA_COMMON); 679 680 int sof_mtl_ops_init(struct snd_sof_dev *sdev) 681 { 682 struct sof_ipc4_fw_data *ipc4_data; 683 684 /* common defaults */ 685 memcpy(&sof_mtl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops)); 686 687 /* shutdown */ 688 sof_mtl_ops.shutdown = hda_dsp_shutdown; 689 690 /* doorbell */ 691 sof_mtl_ops.irq_thread = mtl_ipc_irq_thread; 692 693 /* ipc */ 694 sof_mtl_ops.send_msg = mtl_ipc_send_msg; 695 sof_mtl_ops.get_mailbox_offset = mtl_dsp_ipc_get_mailbox_offset; 696 sof_mtl_ops.get_window_offset = mtl_dsp_ipc_get_window_offset; 697 698 /* debug */ 699 sof_mtl_ops.debug_map = mtl_dsp_debugfs; 700 sof_mtl_ops.debug_map_count = ARRAY_SIZE(mtl_dsp_debugfs); 701 sof_mtl_ops.dbg_dump = mtl_dsp_dump; 702 sof_mtl_ops.ipc_dump = mtl_ipc_dump; 703 704 /* pre/post fw run */ 705 sof_mtl_ops.pre_fw_run = mtl_dsp_pre_fw_run; 706 sof_mtl_ops.post_fw_run = mtl_dsp_post_fw_run; 707 708 /* parse platform specific extended manifest */ 709 sof_mtl_ops.parse_platform_ext_manifest = NULL; 710 711 /* dsp core get/put */ 712 sof_mtl_ops.core_get = mtl_dsp_core_get; 713 sof_mtl_ops.core_put = mtl_dsp_core_put; 714 715 sof_mtl_ops.get_stream_position = mtl_dsp_get_stream_hda_link_position; 716 717 sdev->private = kzalloc(sizeof(struct sof_ipc4_fw_data), GFP_KERNEL); 718 if (!sdev->private) 719 return -ENOMEM; 720 721 ipc4_data = sdev->private; 722 ipc4_data->manifest_fw_hdr_offset = SOF_MAN4_FW_HDR_OFFSET; 723 724 ipc4_data->mtrace_type = SOF_IPC4_MTRACE_INTEL_CAVS_2; 725 726 ipc4_data->fw_context_save = true; 727 728 /* External library loading support */ 729 ipc4_data->load_library = hda_dsp_ipc4_load_library; 730 731 /* set DAI ops */ 732 hda_set_dai_drv_ops(sdev, &sof_mtl_ops); 733 734 sof_mtl_ops.set_power_state = hda_dsp_set_power_state_ipc4; 735 736 return 0; 737 }; 738 EXPORT_SYMBOL_NS(sof_mtl_ops_init, SND_SOC_SOF_INTEL_HDA_COMMON); 739 740 const struct sof_intel_dsp_desc mtl_chip_info = { 741 .cores_num = 3, 742 .init_core_mask = BIT(0), 743 .host_managed_cores_mask = BIT(0), 744 .ipc_req = MTL_DSP_REG_HFIPCXIDR, 745 .ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY, 746 .ipc_ack = MTL_DSP_REG_HFIPCXIDA, 747 .ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE, 748 .ipc_ctl = MTL_DSP_REG_HFIPCXCTL, 749 .rom_status_reg = MTL_DSP_ROM_STS, 750 .rom_init_timeout = 300, 751 .ssp_count = MTL_SSP_COUNT, 752 .ssp_base_offset = CNL_SSP_BASE_OFFSET, 753 .sdw_shim_base = SDW_SHIM_BASE_ACE, 754 .sdw_alh_base = SDW_ALH_BASE_ACE, 755 .d0i3_offset = MTL_HDA_VS_D0I3C, 756 .read_sdw_lcount = hda_sdw_check_lcount_common, 757 .enable_sdw_irq = mtl_enable_sdw_irq, 758 .check_sdw_irq = mtl_dsp_check_sdw_irq, 759 .check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common, 760 .check_ipc_irq = mtl_dsp_check_ipc_irq, 761 .cl_init = mtl_dsp_cl_init, 762 .power_down_dsp = mtl_power_down_dsp, 763 .disable_interrupts = mtl_dsp_disable_interrupts, 764 .hw_ip_version = SOF_INTEL_ACE_1_0, 765 }; 766 EXPORT_SYMBOL_NS(mtl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); 767 768 const struct sof_intel_dsp_desc arl_s_chip_info = { 769 .cores_num = 2, 770 .init_core_mask = BIT(0), 771 .host_managed_cores_mask = BIT(0), 772 .ipc_req = MTL_DSP_REG_HFIPCXIDR, 773 .ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY, 774 .ipc_ack = MTL_DSP_REG_HFIPCXIDA, 775 .ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE, 776 .ipc_ctl = MTL_DSP_REG_HFIPCXCTL, 777 .rom_status_reg = MTL_DSP_ROM_STS, 778 .rom_init_timeout = 300, 779 .ssp_count = MTL_SSP_COUNT, 780 .ssp_base_offset = CNL_SSP_BASE_OFFSET, 781 .sdw_shim_base = SDW_SHIM_BASE_ACE, 782 .sdw_alh_base = SDW_ALH_BASE_ACE, 783 .d0i3_offset = MTL_HDA_VS_D0I3C, 784 .read_sdw_lcount = hda_sdw_check_lcount_common, 785 .enable_sdw_irq = mtl_enable_sdw_irq, 786 .check_sdw_irq = mtl_dsp_check_sdw_irq, 787 .check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common, 788 .check_ipc_irq = mtl_dsp_check_ipc_irq, 789 .cl_init = mtl_dsp_cl_init, 790 .power_down_dsp = mtl_power_down_dsp, 791 .disable_interrupts = mtl_dsp_disable_interrupts, 792 .hw_ip_version = SOF_INTEL_ACE_1_0, 793 }; 794 EXPORT_SYMBOL_NS(arl_s_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); 795