xref: /linux/sound/soc/sof/intel/ptl.c (revision a9e6060bb2a6cae6d43a98ec0794844ad01273d3)
18aeb7d2cSPeter Ujfalusi // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
28aeb7d2cSPeter Ujfalusi //
38aeb7d2cSPeter Ujfalusi // Copyright(c) 2025 Intel Corporation
48aeb7d2cSPeter Ujfalusi 
58aeb7d2cSPeter Ujfalusi /*
68aeb7d2cSPeter Ujfalusi  * Hardware interface for audio DSP on PantherLake.
78aeb7d2cSPeter Ujfalusi  */
88aeb7d2cSPeter Ujfalusi 
98aeb7d2cSPeter Ujfalusi #include <sound/hda_register.h>
108aeb7d2cSPeter Ujfalusi #include <sound/hda-mlink.h>
118aeb7d2cSPeter Ujfalusi #include <sound/sof/ipc4/header.h>
128aeb7d2cSPeter Ujfalusi #include "../ipc4-priv.h"
138aeb7d2cSPeter Ujfalusi #include "../ops.h"
148aeb7d2cSPeter Ujfalusi #include "hda.h"
158aeb7d2cSPeter Ujfalusi #include "hda-ipc.h"
168aeb7d2cSPeter Ujfalusi #include "../sof-audio.h"
178aeb7d2cSPeter Ujfalusi #include "mtl.h"
188aeb7d2cSPeter Ujfalusi #include "lnl.h"
198aeb7d2cSPeter Ujfalusi #include "ptl.h"
208aeb7d2cSPeter Ujfalusi 
sof_ptl_check_mic_privacy_irq(struct snd_sof_dev * sdev,bool alt,int elid)214a43c324SPeter Ujfalusi static bool sof_ptl_check_mic_privacy_irq(struct snd_sof_dev *sdev, bool alt,
224a43c324SPeter Ujfalusi 					  int elid)
234a43c324SPeter Ujfalusi {
244a43c324SPeter Ujfalusi 	if (!alt || elid != AZX_REG_ML_LEPTR_ID_SDW)
254a43c324SPeter Ujfalusi 		return false;
264a43c324SPeter Ujfalusi 
274a43c324SPeter Ujfalusi 	return hdac_bus_eml_is_mic_privacy_changed(sof_to_bus(sdev), alt, elid);
284a43c324SPeter Ujfalusi }
294a43c324SPeter Ujfalusi 
sof_ptl_mic_privacy_work(struct work_struct * work)307d783d90SPeter Ujfalusi static void sof_ptl_mic_privacy_work(struct work_struct *work)
317d783d90SPeter Ujfalusi {
327d783d90SPeter Ujfalusi 	struct sof_intel_hda_dev *hdev = container_of(work,
337d783d90SPeter Ujfalusi 						      struct sof_intel_hda_dev,
347d783d90SPeter Ujfalusi 						      mic_privacy.work);
357d783d90SPeter Ujfalusi 	struct hdac_bus *bus = &hdev->hbus.core;
367d783d90SPeter Ujfalusi 	struct snd_sof_dev *sdev = dev_get_drvdata(bus->dev);
377d783d90SPeter Ujfalusi 	bool state;
387d783d90SPeter Ujfalusi 
397d783d90SPeter Ujfalusi 	/*
407d783d90SPeter Ujfalusi 	 * The microphone privacy state is only available via Soundwire shim
417d783d90SPeter Ujfalusi 	 * in PTL
427d783d90SPeter Ujfalusi 	 * The work is only scheduled on change.
437d783d90SPeter Ujfalusi 	 */
447d783d90SPeter Ujfalusi 	state = hdac_bus_eml_get_mic_privacy_state(bus, 1,
457d783d90SPeter Ujfalusi 						   AZX_REG_ML_LEPTR_ID_SDW);
467d783d90SPeter Ujfalusi 	sof_ipc4_mic_privacy_state_change(sdev, state);
477d783d90SPeter Ujfalusi }
487d783d90SPeter Ujfalusi 
sof_ptl_process_mic_privacy(struct snd_sof_dev * sdev,bool alt,int elid)494a43c324SPeter Ujfalusi static void sof_ptl_process_mic_privacy(struct snd_sof_dev *sdev, bool alt,
504a43c324SPeter Ujfalusi 					int elid)
514a43c324SPeter Ujfalusi {
527d783d90SPeter Ujfalusi 	struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
534a43c324SPeter Ujfalusi 
544a43c324SPeter Ujfalusi 	if (!alt || elid != AZX_REG_ML_LEPTR_ID_SDW)
554a43c324SPeter Ujfalusi 		return;
564a43c324SPeter Ujfalusi 
577d783d90SPeter Ujfalusi 	/*
587d783d90SPeter Ujfalusi 	 * Schedule the work to read the microphone privacy state and send IPC
597d783d90SPeter Ujfalusi 	 * message about the new state to the firmware
607d783d90SPeter Ujfalusi 	 */
617d783d90SPeter Ujfalusi 	schedule_work(&hdev->mic_privacy.work);
624a43c324SPeter Ujfalusi }
634a43c324SPeter Ujfalusi 
sof_ptl_set_mic_privacy(struct snd_sof_dev * sdev,struct sof_ipc4_intel_mic_privacy_cap * caps)644a43c324SPeter Ujfalusi static void sof_ptl_set_mic_privacy(struct snd_sof_dev *sdev,
654a43c324SPeter Ujfalusi 				    struct sof_ipc4_intel_mic_privacy_cap *caps)
664a43c324SPeter Ujfalusi {
677d783d90SPeter Ujfalusi 	struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
684a43c324SPeter Ujfalusi 	u32 micpvcp;
694a43c324SPeter Ujfalusi 
704a43c324SPeter Ujfalusi 	if (!caps || !caps->capabilities_length)
714a43c324SPeter Ujfalusi 		return;
724a43c324SPeter Ujfalusi 
734a43c324SPeter Ujfalusi 	micpvcp = caps->capabilities[0];
744a43c324SPeter Ujfalusi 
754a43c324SPeter Ujfalusi 	/* No need to set the mic privacy if it is not enabled or forced */
764a43c324SPeter Ujfalusi 	if (!(micpvcp & PTL_MICPVCP_DDZE_ENABLED) ||
774a43c324SPeter Ujfalusi 	    micpvcp & PTL_MICPVCP_DDZE_FORCED)
784a43c324SPeter Ujfalusi 		return;
794a43c324SPeter Ujfalusi 
804a43c324SPeter Ujfalusi 	hdac_bus_eml_set_mic_privacy_mask(sof_to_bus(sdev), true,
814a43c324SPeter Ujfalusi 					  AZX_REG_ML_LEPTR_ID_SDW,
824a43c324SPeter Ujfalusi 					  PTL_MICPVCP_GET_SDW_MASK(micpvcp));
837d783d90SPeter Ujfalusi 
847d783d90SPeter Ujfalusi 	INIT_WORK(&hdev->mic_privacy.work, sof_ptl_mic_privacy_work);
857d783d90SPeter Ujfalusi 	hdev->mic_privacy.active = true;
864a43c324SPeter Ujfalusi }
874a43c324SPeter Ujfalusi 
sof_ptl_set_ops(struct snd_sof_dev * sdev,struct snd_sof_dsp_ops * dsp_ops)888aeb7d2cSPeter Ujfalusi int sof_ptl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops)
898aeb7d2cSPeter Ujfalusi {
904a43c324SPeter Ujfalusi 	struct sof_ipc4_fw_data *ipc4_data;
914a43c324SPeter Ujfalusi 	int ret;
924a43c324SPeter Ujfalusi 
934a43c324SPeter Ujfalusi 	ret = sof_lnl_set_ops(sdev, dsp_ops);
944a43c324SPeter Ujfalusi 	if (ret)
954a43c324SPeter Ujfalusi 		return ret;
964a43c324SPeter Ujfalusi 
974a43c324SPeter Ujfalusi 	ipc4_data = sdev->private;
984a43c324SPeter Ujfalusi 	ipc4_data->intel_configure_mic_privacy = sof_ptl_set_mic_privacy;
994a43c324SPeter Ujfalusi 
1004a43c324SPeter Ujfalusi 	return 0;
1014a43c324SPeter Ujfalusi };
1028aeb7d2cSPeter Ujfalusi EXPORT_SYMBOL_NS(sof_ptl_set_ops, "SND_SOC_SOF_INTEL_PTL");
1038aeb7d2cSPeter Ujfalusi 
1048aeb7d2cSPeter Ujfalusi const struct sof_intel_dsp_desc ptl_chip_info = {
1058aeb7d2cSPeter Ujfalusi 	.cores_num = 5,
1068aeb7d2cSPeter Ujfalusi 	.init_core_mask = BIT(0),
1078aeb7d2cSPeter Ujfalusi 	.host_managed_cores_mask = BIT(0),
1088aeb7d2cSPeter Ujfalusi 	.ipc_req = MTL_DSP_REG_HFIPCXIDR,
1098aeb7d2cSPeter Ujfalusi 	.ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY,
1108aeb7d2cSPeter Ujfalusi 	.ipc_ack = MTL_DSP_REG_HFIPCXIDA,
1118aeb7d2cSPeter Ujfalusi 	.ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE,
1128aeb7d2cSPeter Ujfalusi 	.ipc_ctl = MTL_DSP_REG_HFIPCXCTL,
1138aeb7d2cSPeter Ujfalusi 	.rom_status_reg = LNL_DSP_REG_HFDSC,
1148aeb7d2cSPeter Ujfalusi 	.rom_init_timeout = 300,
1158aeb7d2cSPeter Ujfalusi 	.ssp_count = MTL_SSP_COUNT,
1168aeb7d2cSPeter Ujfalusi 	.d0i3_offset = MTL_HDA_VS_D0I3C,
1178aeb7d2cSPeter Ujfalusi 	.read_sdw_lcount =  hda_sdw_check_lcount_ext,
1188aeb7d2cSPeter Ujfalusi 	.check_sdw_irq = lnl_dsp_check_sdw_irq,
1198aeb7d2cSPeter Ujfalusi 	.check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq,
1208aeb7d2cSPeter Ujfalusi 	.check_ipc_irq = mtl_dsp_check_ipc_irq,
1214a43c324SPeter Ujfalusi 	.check_mic_privacy_irq = sof_ptl_check_mic_privacy_irq,
1224a43c324SPeter Ujfalusi 	.process_mic_privacy = sof_ptl_process_mic_privacy,
1238aeb7d2cSPeter Ujfalusi 	.cl_init = mtl_dsp_cl_init,
1248aeb7d2cSPeter Ujfalusi 	.power_down_dsp = mtl_power_down_dsp,
1258aeb7d2cSPeter Ujfalusi 	.disable_interrupts = lnl_dsp_disable_interrupts,
1268aeb7d2cSPeter Ujfalusi 	.hw_ip_version = SOF_INTEL_ACE_3_0,
1278aeb7d2cSPeter Ujfalusi };
1288aeb7d2cSPeter Ujfalusi 
129*6b04629aSPeter Ujfalusi const struct sof_intel_dsp_desc wcl_chip_info = {
130*6b04629aSPeter Ujfalusi 	.cores_num = 3,
131*6b04629aSPeter Ujfalusi 	.init_core_mask = BIT(0),
132*6b04629aSPeter Ujfalusi 	.host_managed_cores_mask = BIT(0),
133*6b04629aSPeter Ujfalusi 	.ipc_req = MTL_DSP_REG_HFIPCXIDR,
134*6b04629aSPeter Ujfalusi 	.ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY,
135*6b04629aSPeter Ujfalusi 	.ipc_ack = MTL_DSP_REG_HFIPCXIDA,
136*6b04629aSPeter Ujfalusi 	.ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE,
137*6b04629aSPeter Ujfalusi 	.ipc_ctl = MTL_DSP_REG_HFIPCXCTL,
138*6b04629aSPeter Ujfalusi 	.rom_status_reg = LNL_DSP_REG_HFDSC,
139*6b04629aSPeter Ujfalusi 	.rom_init_timeout = 300,
140*6b04629aSPeter Ujfalusi 	.ssp_count = MTL_SSP_COUNT,
141*6b04629aSPeter Ujfalusi 	.d0i3_offset = MTL_HDA_VS_D0I3C,
142*6b04629aSPeter Ujfalusi 	.read_sdw_lcount =  hda_sdw_check_lcount_ext,
143*6b04629aSPeter Ujfalusi 	.check_sdw_irq = lnl_dsp_check_sdw_irq,
144*6b04629aSPeter Ujfalusi 	.check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq,
145*6b04629aSPeter Ujfalusi 	.check_ipc_irq = mtl_dsp_check_ipc_irq,
146*6b04629aSPeter Ujfalusi 	.cl_init = mtl_dsp_cl_init,
147*6b04629aSPeter Ujfalusi 	.power_down_dsp = mtl_power_down_dsp,
148*6b04629aSPeter Ujfalusi 	.disable_interrupts = lnl_dsp_disable_interrupts,
149*6b04629aSPeter Ujfalusi 	.hw_ip_version = SOF_INTEL_ACE_3_0,
150*6b04629aSPeter Ujfalusi };
151*6b04629aSPeter Ujfalusi 
1528aeb7d2cSPeter Ujfalusi MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL");
1538aeb7d2cSPeter Ujfalusi MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_LNL");
1548aeb7d2cSPeter Ujfalusi MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK");
155