brintos

brintos / linux-shallow public Read only

0
0
Text · 2.7 KiB · bd3c4bb Raw
91 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// Copyright(c) 2021-2024 Intel Corporation4//5// Authors: Cezary Rojewski <cezary.rojewski@intel.com>6//          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>7//8 9#include <sound/hdaudio_ext.h>10#include "avs.h"11#include "messages.h"12 13static void avs_cnl_ipc_interrupt(struct avs_dev *adev)14{15	const struct avs_spec *spec = adev->spec;16	u32 hipc_ack, hipc_rsp;17 18	snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,19			      AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY, 0);20 21	hipc_ack = snd_hdac_adsp_readl(adev, spec->hipc->ack_offset);22	hipc_rsp = snd_hdac_adsp_readl(adev, spec->hipc->rsp_offset);23 24	/* DSP acked host's request. */25	if (hipc_ack & spec->hipc->ack_done_mask) {26		complete(&adev->ipc->done_completion);27 28		/* Tell DSP it has our attention. */29		snd_hdac_adsp_updatel(adev, spec->hipc->ack_offset, spec->hipc->ack_done_mask,30				      spec->hipc->ack_done_mask);31	}32 33	/* DSP sent new response to process. */34	if (hipc_rsp & spec->hipc->rsp_busy_mask) {35		union avs_reply_msg msg;36		u32 hipctda;37 38		msg.primary = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDR);39		msg.ext.val = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDD);40 41		avs_dsp_process_response(adev, msg.val);42 43		/* Tell DSP we accepted its message. */44		snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDR,45				      CNL_ADSP_HIPCTDR_BUSY, CNL_ADSP_HIPCTDR_BUSY);46		/* Ack this response. */47		snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDA,48				      CNL_ADSP_HIPCTDA_DONE, CNL_ADSP_HIPCTDA_DONE);49		/* HW might have been clock gated, give some time for change to propagate. */50		snd_hdac_adsp_readl_poll(adev, CNL_ADSP_REG_HIPCTDA, hipctda,51					 !(hipctda & CNL_ADSP_HIPCTDA_DONE), 10, 1000);52	}53 54	snd_hdac_adsp_updatel(adev, spec->hipc->ctl_offset,55			      AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY,56			      AVS_ADSP_HIPCCTL_DONE | AVS_ADSP_HIPCCTL_BUSY);57}58 59irqreturn_t avs_cnl_dsp_interrupt(struct avs_dev *adev)60{61	u32 adspis = snd_hdac_adsp_readl(adev, AVS_ADSP_REG_ADSPIS);62	irqreturn_t ret = IRQ_NONE;63 64	if (adspis == UINT_MAX)65		return ret;66 67	if (adspis & AVS_ADSP_ADSPIS_IPC) {68		avs_cnl_ipc_interrupt(adev);69		ret = IRQ_HANDLED;70	}71 72	return ret;73}74 75const struct avs_dsp_ops avs_cnl_dsp_ops = {76	.power = avs_dsp_core_power,77	.reset = avs_dsp_core_reset,78	.stall = avs_dsp_core_stall,79	.dsp_interrupt = avs_cnl_dsp_interrupt,80	.int_control = avs_dsp_interrupt_control,81	.load_basefw = avs_hda_load_basefw,82	.load_lib = avs_hda_load_library,83	.transfer_mods = avs_hda_transfer_modules,84	.log_buffer_offset = avs_skl_log_buffer_offset,85	.log_buffer_status = avs_apl_log_buffer_status,86	.coredump = avs_apl_coredump,87	.d0ix_toggle = avs_apl_d0ix_toggle,88	.set_d0ix = avs_apl_set_d0ix,89	AVS_SET_ENABLE_LOGS_OP(apl)90};91