0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/firmware.h>
0013 #include <sound/sof/ipc4/header.h>
0014 #include "../ipc4-priv.h"
0015 #include "../ops.h"
0016 #include "hda.h"
0017 #include "hda-ipc.h"
0018 #include "../sof-audio.h"
0019 #include "mtl.h"
0020
0021 static const struct snd_sof_debugfs_map mtl_dsp_debugfs[] = {
0022 {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
0023 {"pp", HDA_DSP_PP_BAR, 0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS},
0024 {"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
0025 };
0026
0027 static void mtl_ipc_host_done(struct snd_sof_dev *sdev)
0028 {
0029
0030
0031
0032
0033 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR,
0034 MTL_DSP_REG_HFIPCXTDR_BUSY, MTL_DSP_REG_HFIPCXTDR_BUSY);
0035
0036
0037
0038 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDA,
0039 MTL_DSP_REG_HFIPCXTDA_BUSY, 0);
0040 }
0041
0042 static void mtl_ipc_dsp_done(struct snd_sof_dev *sdev)
0043 {
0044
0045
0046
0047
0048 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA,
0049 MTL_DSP_REG_HFIPCXIDA_DONE, MTL_DSP_REG_HFIPCXIDA_DONE);
0050
0051
0052 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL,
0053 MTL_DSP_REG_HFIPCXCTL_DONE, MTL_DSP_REG_HFIPCXCTL_DONE);
0054 }
0055
0056
0057 static bool mtl_dsp_check_ipc_irq(struct snd_sof_dev *sdev)
0058 {
0059 u32 irq_status;
0060 u32 hfintipptr;
0061
0062
0063 hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK;
0064 irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr + MTL_DSP_IRQSTS);
0065
0066 dev_vdbg(sdev->dev, "irq handler: irq_status:0x%x\n", irq_status);
0067
0068 if (irq_status != U32_MAX && (irq_status & MTL_DSP_IRQSTS_IPC))
0069 return true;
0070
0071 return false;
0072 }
0073
0074
0075 static bool mtl_dsp_check_sdw_irq(struct snd_sof_dev *sdev)
0076 {
0077 u32 irq_status;
0078 u32 hfintipptr;
0079
0080
0081 hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK;
0082 irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr + MTL_DSP_IRQSTS);
0083
0084 if (irq_status != U32_MAX && (irq_status & MTL_DSP_IRQSTS_SDW))
0085 return true;
0086
0087 return false;
0088 }
0089
0090 static int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
0091 {
0092 struct sof_ipc4_msg *msg_data = msg->msg_data;
0093
0094
0095 if (msg_data->data_size)
0096 sof_mailbox_write(sdev, sdev->host_box.offset, msg_data->data_ptr,
0097 msg_data->data_size);
0098
0099 snd_sof_dsp_write(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDDY,
0100 msg_data->extension);
0101 snd_sof_dsp_write(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDR,
0102 msg_data->primary | MTL_DSP_REG_HFIPCXIDR_BUSY);
0103
0104 return 0;
0105 }
0106
0107 static void mtl_enable_ipc_interrupts(struct snd_sof_dev *sdev)
0108 {
0109 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0110 const struct sof_intel_dsp_desc *chip = hda->desc;
0111
0112
0113 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
0114 MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE,
0115 MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE);
0116 }
0117
0118 static void mtl_disable_ipc_interrupts(struct snd_sof_dev *sdev)
0119 {
0120 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0121 const struct sof_intel_dsp_desc *chip = hda->desc;
0122
0123
0124 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
0125 MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE, 0);
0126 }
0127
0128 static int mtl_enable_interrupts(struct snd_sof_dev *sdev)
0129 {
0130 u32 hfintipptr;
0131 u32 irqinten;
0132 u32 host_ipc;
0133 u32 hipcie;
0134 int ret;
0135
0136
0137 hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK;
0138
0139
0140 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, hfintipptr,
0141 MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK,
0142 MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK);
0143
0144
0145 host_ipc = MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK;
0146 irqinten = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr);
0147 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, hfintipptr, irqinten,
0148 (irqinten & host_ipc) == host_ipc,
0149 HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US);
0150 if (ret < 0) {
0151 dev_err(sdev->dev, "failed to enable Host IPC and/or SOUNDWIRE\n");
0152 return ret;
0153 }
0154
0155
0156 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE,
0157 MTL_DSP_REG_HfHIPCIE_IE_MASK, MTL_DSP_REG_HfHIPCIE_IE_MASK);
0158
0159
0160 host_ipc = MTL_DSP_REG_HfHIPCIE_IE_MASK;
0161 hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE);
0162 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, hipcie,
0163 (hipcie & host_ipc) == host_ipc,
0164 HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US);
0165 if (ret < 0) {
0166 dev_err(sdev->dev, "failed to set Host IPC interrupt enable\n");
0167 return ret;
0168 }
0169
0170 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE,
0171 MTL_DSP_REG_HfSNDWIE_IE_MASK, MTL_DSP_REG_HfSNDWIE_IE_MASK);
0172 host_ipc = MTL_DSP_REG_HfSNDWIE_IE_MASK;
0173 hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE);
0174 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, hipcie,
0175 (hipcie & host_ipc) == host_ipc,
0176 HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US);
0177 if (ret < 0)
0178 dev_err(sdev->dev, "failed to set SoundWire IPC interrupt enable\n");
0179
0180 return ret;
0181 }
0182
0183 static int mtl_disable_interrupts(struct snd_sof_dev *sdev)
0184 {
0185 u32 hfintipptr;
0186 u32 irqinten;
0187 u32 host_ipc;
0188 u32 hipcie;
0189 int ret1;
0190 int ret;
0191
0192
0193 hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK;
0194
0195
0196 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, hfintipptr,
0197 MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK, 0);
0198
0199
0200 host_ipc = MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK;
0201 irqinten = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr);
0202 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, hfintipptr, irqinten,
0203 (irqinten & host_ipc) == 0,
0204 HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US);
0205
0206 if (ret < 0)
0207 dev_err(sdev->dev, "failed to disable Host IPC and SoundWire\n");
0208
0209
0210 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE,
0211 MTL_DSP_REG_HfHIPCIE_IE_MASK, 0);
0212
0213
0214 host_ipc = MTL_DSP_REG_HfHIPCIE_IE_MASK;
0215 hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE);
0216 ret1 = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, hipcie,
0217 (hipcie & host_ipc) == 0,
0218 HDA_DSP_REG_POLL_INTERVAL_US,
0219 HDA_DSP_RESET_TIMEOUT_US);
0220 if (ret1 < 0) {
0221 dev_err(sdev->dev, "failed to set Host IPC interrupt disable\n");
0222 if (!ret)
0223 ret = ret1;
0224 }
0225
0226
0227 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE,
0228 MTL_DSP_REG_HfSNDWIE_IE_MASK, 0);
0229 host_ipc = MTL_DSP_REG_HfSNDWIE_IE_MASK;
0230 hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE);
0231 ret1 = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, hipcie,
0232 (hipcie & host_ipc) == 0,
0233 HDA_DSP_REG_POLL_INTERVAL_US,
0234 HDA_DSP_RESET_TIMEOUT_US);
0235 if (ret1 < 0) {
0236 dev_err(sdev->dev, "failed to set SoundWire IPC interrupt disable\n");
0237 if (!ret)
0238 ret = ret1;
0239 }
0240
0241 return ret;
0242 }
0243
0244
0245 static int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev)
0246 {
0247 u32 dsphfpwrsts;
0248 u32 dsphfdsscs;
0249 u32 cpa;
0250 u32 pgs;
0251 int ret;
0252
0253
0254 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFDSSCS,
0255 MTL_HFDSSCS_SPA_MASK, MTL_HFDSSCS_SPA_MASK);
0256
0257
0258 usleep_range(1000, 1010);
0259
0260
0261 cpa = MTL_HFDSSCS_CPA_MASK;
0262 dsphfdsscs = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFDSSCS);
0263 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFDSSCS, dsphfdsscs,
0264 (dsphfdsscs & cpa) == cpa, HDA_DSP_REG_POLL_INTERVAL_US,
0265 HDA_DSP_RESET_TIMEOUT_US);
0266 if (ret < 0) {
0267 dev_err(sdev->dev, "failed to enable DSP subsystem\n");
0268 return ret;
0269 }
0270
0271
0272 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL,
0273 MTL_HFPWRCTL_WPDSPHPXPG, MTL_HFPWRCTL_WPDSPHPXPG);
0274
0275 usleep_range(1000, 1010);
0276
0277
0278 pgs = MTL_HFPWRSTS_DSPHPXPGS_MASK;
0279 dsphfpwrsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFPWRSTS);
0280 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFPWRSTS, dsphfpwrsts,
0281 (dsphfpwrsts & pgs) == pgs,
0282 HDA_DSP_REG_POLL_INTERVAL_US,
0283 HDA_DSP_RESET_TIMEOUT_US);
0284 if (ret < 0)
0285 dev_err(sdev->dev, "failed to power up gated DSP domain\n");
0286
0287
0288 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, MTL_HFPWRCTL,
0289 MTL_HfPWRCTL_WPIOXPG(1), MTL_HfPWRCTL_WPIOXPG(1));
0290 return ret;
0291 }
0292
0293 static int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev)
0294 {
0295 int ret;
0296
0297 if (sdev->first_boot) {
0298 struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
0299
0300 ret = hda_sdw_startup(sdev);
0301 if (ret < 0) {
0302 dev_err(sdev->dev, "could not startup SoundWire links\n");
0303 return ret;
0304 }
0305
0306
0307 if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT))
0308 hdev->imrboot_supported = true;
0309 }
0310
0311 hda_sdw_int_enable(sdev, true);
0312 return 0;
0313 }
0314
0315 static void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
0316 {
0317 char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR;
0318 u32 romdbgsts;
0319 u32 romdbgerr;
0320 u32 fwsts;
0321 u32 fwlec;
0322
0323 fwsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_ROM_STS);
0324 fwlec = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_ROM_ERROR);
0325 romdbgsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY);
0326 romdbgerr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY_ERROR);
0327
0328 dev_err(sdev->dev, "ROM status: %#x, ROM error: %#x\n", fwsts, fwlec);
0329 dev_err(sdev->dev, "ROM debug status: %#x, ROM debug error: %#x\n", romdbgsts,
0330 romdbgerr);
0331 romdbgsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY + 0x8 * 3);
0332 dev_printk(level, sdev->dev, "ROM feature bit%s enabled\n",
0333 romdbgsts & BIT(24) ? "" : " not");
0334 }
0335
0336 static bool mtl_dsp_primary_core_is_enabled(struct snd_sof_dev *sdev)
0337 {
0338 int val;
0339
0340 val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE);
0341 if (val != U32_MAX && val & MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK)
0342 return true;
0343
0344 return false;
0345 }
0346
0347 static int mtl_dsp_core_power_up(struct snd_sof_dev *sdev, int core)
0348 {
0349 unsigned int cpa;
0350 u32 dspcxctl;
0351 int ret;
0352
0353
0354 if (core != SOF_DSP_PRIMARY_CORE || mtl_dsp_primary_core_is_enabled(sdev))
0355 return 0;
0356
0357
0358 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE,
0359 MTL_DSP2CXCTL_PRIMARY_CORE_OSEL,
0360 0x2 << MTL_DSP2CXCTL_PRIMARY_CORE_OSEL_SHIFT);
0361
0362
0363 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE,
0364 MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK,
0365 MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK);
0366
0367
0368 usleep_range(1000, 1010);
0369
0370
0371 cpa = MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK;
0372 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, dspcxctl,
0373 (dspcxctl & cpa) == cpa, HDA_DSP_REG_POLL_INTERVAL_US,
0374 HDA_DSP_RESET_TIMEOUT_US);
0375 if (ret < 0)
0376 dev_err(sdev->dev, "%s: timeout on MTL_DSP2CXCTL_PRIMARY_CORE read\n",
0377 __func__);
0378
0379 return ret;
0380 }
0381
0382 static int mtl_dsp_core_power_down(struct snd_sof_dev *sdev, int core)
0383 {
0384 u32 dspcxctl;
0385 int ret;
0386
0387
0388 if (core != SOF_DSP_PRIMARY_CORE || !mtl_dsp_primary_core_is_enabled(sdev))
0389 return 0;
0390
0391
0392 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE,
0393 MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK, 0);
0394
0395
0396 usleep_range(1000, 1010);
0397
0398 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, dspcxctl,
0399 !(dspcxctl & MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK),
0400 HDA_DSP_REG_POLL_INTERVAL_US,
0401 HDA_DSP_PD_TIMEOUT * USEC_PER_MSEC);
0402 if (ret < 0)
0403 dev_err(sdev->dev, "failed to power down primary core\n");
0404
0405 return ret;
0406 }
0407
0408 static int mtl_dsp_cl_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot)
0409 {
0410 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0411 const struct sof_intel_dsp_desc *chip = hda->desc;
0412 unsigned int status;
0413 u32 ipc_hdr;
0414 int ret;
0415
0416
0417 ipc_hdr = chip->ipc_req_mask | HDA_DSP_ROM_IPC_CONTROL;
0418 if (!imr_boot)
0419 ipc_hdr |= HDA_DSP_ROM_IPC_PURGE_FW | ((stream_tag - 1) << 9);
0420
0421 snd_sof_dsp_write(sdev, HDA_DSP_BAR, chip->ipc_req, ipc_hdr);
0422
0423
0424 ret = mtl_dsp_core_power_up(sdev, SOF_DSP_PRIMARY_CORE);
0425 if (ret < 0) {
0426 if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
0427 dev_err(sdev->dev, "dsp core 0/1 power up failed\n");
0428 goto err;
0429 }
0430
0431 dev_dbg(sdev->dev, "Primary core power up successful\n");
0432
0433
0434 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, chip->ipc_ack, status,
0435 ((status & chip->ipc_ack_mask) == chip->ipc_ack_mask),
0436 HDA_DSP_REG_POLL_INTERVAL_US, MTL_DSP_PURGE_TIMEOUT_US);
0437 if (ret < 0) {
0438 if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
0439 dev_err(sdev->dev, "timeout waiting for purge IPC done\n");
0440 goto err;
0441 }
0442
0443
0444 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, chip->ipc_ack, chip->ipc_ack_mask,
0445 chip->ipc_ack_mask);
0446
0447
0448 ret = mtl_enable_interrupts(sdev);
0449 if (ret < 0) {
0450 if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
0451 dev_err(sdev->dev, "%s: failed to enable interrupts\n", __func__);
0452 goto err;
0453 }
0454
0455 mtl_enable_ipc_interrupts(sdev);
0456
0457
0458
0459
0460
0461
0462
0463 return 0;
0464
0465 err:
0466 snd_sof_dsp_dbg_dump(sdev, "MTL DSP init fail", 0);
0467 mtl_dsp_core_power_down(sdev, SOF_DSP_PRIMARY_CORE);
0468 return ret;
0469 }
0470
0471 static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
0472 {
0473 struct sof_ipc4_msg notification_data = {{ 0 }};
0474 struct snd_sof_dev *sdev = context;
0475 bool ipc_irq = false;
0476 u32 hipcida;
0477 u32 hipctdr;
0478
0479 hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA);
0480
0481
0482 if (hipcida & MTL_DSP_REG_HFIPCXIDA_DONE) {
0483
0484 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL,
0485 MTL_DSP_REG_HFIPCXCTL_DONE, 0);
0486
0487 mtl_ipc_dsp_done(sdev);
0488
0489 ipc_irq = true;
0490 }
0491
0492 hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR);
0493 if (hipctdr & MTL_DSP_REG_HFIPCXTDR_BUSY) {
0494
0495 u32 extension = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDDY);
0496 u32 primary = hipctdr & MTL_DSP_REG_HFIPCXTDR_MSG_MASK;
0497
0498
0499
0500
0501
0502 if (primary & SOF_IPC4_MSG_DIR_MASK) {
0503
0504 if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) {
0505 struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data;
0506
0507 data->primary = primary;
0508 data->extension = extension;
0509
0510 spin_lock_irq(&sdev->ipc_lock);
0511
0512 snd_sof_ipc_get_reply(sdev);
0513 snd_sof_ipc_reply(sdev, data->primary);
0514
0515 spin_unlock_irq(&sdev->ipc_lock);
0516 } else {
0517 dev_dbg_ratelimited(sdev->dev,
0518 "IPC reply before FW_READY: %#x|%#x\n",
0519 primary, extension);
0520 }
0521 } else {
0522
0523 notification_data.primary = primary;
0524 notification_data.extension = extension;
0525
0526 sdev->ipc->msg.rx_data = ¬ification_data;
0527 snd_sof_ipc_msgs_rx(sdev);
0528 sdev->ipc->msg.rx_data = NULL;
0529 }
0530
0531 mtl_ipc_host_done(sdev);
0532
0533 ipc_irq = true;
0534 }
0535
0536 if (!ipc_irq) {
0537
0538 dev_dbg_ratelimited(sdev->dev, "nothing to do in IPC IRQ thread\n");
0539 }
0540
0541 return IRQ_HANDLED;
0542 }
0543
0544 static int mtl_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev)
0545 {
0546 return MTL_DSP_MBOX_UPLINK_OFFSET;
0547 }
0548
0549 static int mtl_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id)
0550 {
0551 return MTL_SRAM_WINDOW_OFFSET(id);
0552 }
0553
0554 static int mtl_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
0555 {
0556 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0557 const struct sof_intel_dsp_desc *chip = hda->desc;
0558 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0559 struct hdac_bus *bus = sof_to_bus(sdev);
0560 #endif
0561 u32 dsphfdsscs;
0562 u32 cpa;
0563 int ret;
0564 int i;
0565
0566 mtl_disable_ipc_interrupts(sdev);
0567 ret = mtl_disable_interrupts(sdev);
0568 if (ret)
0569 return ret;
0570
0571 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0572 hda_codec_jack_wake_enable(sdev, runtime_suspend);
0573
0574 snd_hdac_ext_bus_link_power_down_all(bus);
0575 #endif
0576 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL,
0577 MTL_HFPWRCTL_WPDSPHPXPG, 0);
0578
0579
0580 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFDSSCS,
0581 MTL_HFDSSCS_SPA_MASK, 0);
0582
0583
0584 usleep_range(1000, 1010);
0585
0586
0587 cpa = MTL_HFDSSCS_CPA_MASK;
0588 dsphfdsscs = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFDSSCS);
0589 ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFDSSCS, dsphfdsscs,
0590 (dsphfdsscs & cpa) == 0, HDA_DSP_REG_POLL_INTERVAL_US,
0591 HDA_DSP_RESET_TIMEOUT_US);
0592 if (ret < 0)
0593 dev_err(sdev->dev, "failed to disable DSP subsystem\n");
0594
0595
0596 for (i = 0; i < chip->cores_num; i++)
0597 sdev->dsp_core_ref_count[i] = 0;
0598
0599
0600
0601
0602 hda_codec_i915_display_power(sdev, false);
0603
0604 return 0;
0605 }
0606
0607 static int mtl_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
0608 {
0609 const struct sof_dsp_power_state target_dsp_state = {
0610 .state = target_state,
0611 .substate = target_state == SOF_DSP_PM_D0 ?
0612 SOF_HDA_DSP_PM_D0I3 : 0,
0613 };
0614 int ret;
0615
0616 ret = mtl_suspend(sdev, false);
0617 if (ret < 0)
0618 return ret;
0619
0620 return snd_sof_dsp_set_power_state(sdev, &target_dsp_state);
0621 }
0622
0623 static int mtl_dsp_runtime_suspend(struct snd_sof_dev *sdev)
0624 {
0625 const struct sof_dsp_power_state target_state = {
0626 .state = SOF_DSP_PM_D3,
0627 };
0628 int ret;
0629
0630 ret = mtl_suspend(sdev, true);
0631 if (ret < 0)
0632 return ret;
0633
0634 return snd_sof_dsp_set_power_state(sdev, &target_state);
0635 }
0636
0637 static int mtl_resume(struct snd_sof_dev *sdev, bool runtime_resume)
0638 {
0639 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0640 struct hdac_bus *bus = sof_to_bus(sdev);
0641 struct hdac_ext_link *hlink = NULL;
0642 #endif
0643
0644
0645 hda_codec_i915_display_power(sdev, true);
0646
0647 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0648
0649 if (runtime_resume) {
0650 hda_codec_jack_wake_enable(sdev, false);
0651 if (sdev->system_suspend_target == SOF_SUSPEND_NONE)
0652 hda_codec_jack_check(sdev);
0653 }
0654
0655
0656 list_for_each_entry(hlink, &bus->hlink_list, list) {
0657 if (!hlink->ref_count)
0658 snd_hdac_ext_bus_link_power_down(hlink);
0659 }
0660
0661
0662 if (!bus->cmd_dma_state)
0663 snd_hdac_bus_stop_cmd_io(bus);
0664 #endif
0665
0666 return 0;
0667 }
0668
0669 static int mtl_dsp_resume(struct snd_sof_dev *sdev)
0670 {
0671 const struct sof_dsp_power_state target_state = {
0672 .state = SOF_DSP_PM_D0,
0673 .substate = SOF_HDA_DSP_PM_D0I0,
0674 };
0675 int ret;
0676
0677 ret = mtl_resume(sdev, false);
0678 if (ret < 0)
0679 return ret;
0680
0681 return snd_sof_dsp_set_power_state(sdev, &target_state);
0682 }
0683
0684 static int mtl_dsp_runtime_resume(struct snd_sof_dev *sdev)
0685 {
0686 const struct sof_dsp_power_state target_state = {
0687 .state = SOF_DSP_PM_D0,
0688 };
0689 int ret;
0690
0691 ret = mtl_resume(sdev, true);
0692 if (ret < 0)
0693 return ret;
0694
0695 return snd_sof_dsp_set_power_state(sdev, &target_state);
0696 }
0697
0698 static void mtl_ipc_dump(struct snd_sof_dev *sdev)
0699 {
0700 u32 hipcctl;
0701 u32 hipcida;
0702 u32 hipctdr;
0703
0704
0705 hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA);
0706 hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL);
0707 hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR);
0708
0709
0710
0711 dev_err(sdev->dev,
0712 "error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n",
0713 hipcida, hipctdr, hipcctl);
0714 }
0715
0716
0717 struct snd_sof_dsp_ops sof_mtl_ops;
0718 EXPORT_SYMBOL_NS(sof_mtl_ops, SND_SOC_SOF_INTEL_HDA_COMMON);
0719
0720 int sof_mtl_ops_init(struct snd_sof_dev *sdev)
0721 {
0722 struct sof_ipc4_fw_data *ipc4_data;
0723
0724
0725 memcpy(&sof_mtl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));
0726
0727
0728 sof_mtl_ops.shutdown = hda_dsp_shutdown;
0729
0730
0731 sof_mtl_ops.irq_thread = mtl_ipc_irq_thread;
0732
0733
0734 sof_mtl_ops.send_msg = mtl_ipc_send_msg;
0735 sof_mtl_ops.get_mailbox_offset = mtl_dsp_ipc_get_mailbox_offset;
0736 sof_mtl_ops.get_window_offset = mtl_dsp_ipc_get_window_offset;
0737
0738
0739 sof_mtl_ops.debug_map = mtl_dsp_debugfs;
0740 sof_mtl_ops.debug_map_count = ARRAY_SIZE(mtl_dsp_debugfs);
0741 sof_mtl_ops.dbg_dump = mtl_dsp_dump;
0742 sof_mtl_ops.ipc_dump = mtl_ipc_dump;
0743
0744
0745 sof_mtl_ops.pre_fw_run = mtl_dsp_pre_fw_run;
0746 sof_mtl_ops.post_fw_run = mtl_dsp_post_fw_run;
0747
0748
0749 sof_mtl_ops.parse_platform_ext_manifest = NULL;
0750
0751
0752
0753
0754
0755 sof_mtl_ops.suspend = mtl_dsp_suspend;
0756 sof_mtl_ops.resume = mtl_dsp_resume;
0757 sof_mtl_ops.runtime_suspend = mtl_dsp_runtime_suspend;
0758 sof_mtl_ops.runtime_resume = mtl_dsp_runtime_resume;
0759
0760 sdev->private = devm_kzalloc(sdev->dev, sizeof(struct sof_ipc4_fw_data), GFP_KERNEL);
0761 if (!sdev->private)
0762 return -ENOMEM;
0763
0764 ipc4_data = sdev->private;
0765 ipc4_data->manifest_fw_hdr_offset = SOF_MAN4_FW_HDR_OFFSET;
0766
0767
0768 hda_set_dai_drv_ops(sdev, &sof_mtl_ops);
0769
0770 return 0;
0771 };
0772 EXPORT_SYMBOL_NS(sof_mtl_ops_init, SND_SOC_SOF_INTEL_HDA_COMMON);
0773
0774 const struct sof_intel_dsp_desc mtl_chip_info = {
0775 .cores_num = 3,
0776 .init_core_mask = BIT(0),
0777 .host_managed_cores_mask = BIT(0),
0778 .ipc_req = MTL_DSP_REG_HFIPCXIDR,
0779 .ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY,
0780 .ipc_ack = MTL_DSP_REG_HFIPCXIDA,
0781 .ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE,
0782 .ipc_ctl = MTL_DSP_REG_HFIPCXCTL,
0783 .rom_status_reg = MTL_DSP_ROM_STS,
0784 .rom_init_timeout = 300,
0785 .ssp_count = ICL_SSP_COUNT,
0786 .ssp_base_offset = CNL_SSP_BASE_OFFSET,
0787 .sdw_shim_base = SDW_SHIM_BASE_ACE,
0788 .sdw_alh_base = SDW_ALH_BASE_ACE,
0789 .check_sdw_irq = mtl_dsp_check_sdw_irq,
0790 .check_ipc_irq = mtl_dsp_check_ipc_irq,
0791 .cl_init = mtl_dsp_cl_init,
0792 .hw_ip_version = SOF_INTEL_ACE_1_0,
0793 };
0794 EXPORT_SYMBOL_NS(mtl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);