1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright(c) 2021-2024 Intel Corporation. All rights reserved.
4//
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
13irqreturn_t avs_cnl_irq_thread(struct avs_dev *adev)
14{
15	union avs_reply_msg msg;
16	u32 hipctdr, hipctdd, hipctda;
17
18	hipctdr = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDR);
19	hipctdd = snd_hdac_adsp_readl(adev, CNL_ADSP_REG_HIPCTDD);
20
21	/* Ensure DSP sent new response to process. */
22	if (!(hipctdr & CNL_ADSP_HIPCTDR_BUSY))
23		return IRQ_NONE;
24
25	msg.primary = hipctdr;
26	msg.ext.val = hipctdd;
27	avs_dsp_process_response(adev, msg.val);
28
29	/* Tell DSP we accepted its message. */
30	snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDR,
31			      CNL_ADSP_HIPCTDR_BUSY, CNL_ADSP_HIPCTDR_BUSY);
32	/* Ack this response. */
33	snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCTDA,
34			      CNL_ADSP_HIPCTDA_DONE, CNL_ADSP_HIPCTDA_DONE);
35	/* HW might have been clock gated, give some time for change to propagate. */
36	snd_hdac_adsp_readl_poll(adev, CNL_ADSP_REG_HIPCTDA, hipctda,
37				 !(hipctda & CNL_ADSP_HIPCTDA_DONE), 10, 1000);
38	/* Unmask busy interrupt. */
39	snd_hdac_adsp_updatel(adev, CNL_ADSP_REG_HIPCCTL,
40			      AVS_ADSP_HIPCCTL_BUSY, AVS_ADSP_HIPCCTL_BUSY);
41
42	return IRQ_HANDLED;
43}
44
45const struct avs_dsp_ops avs_cnl_dsp_ops = {
46	.power = avs_dsp_core_power,
47	.reset = avs_dsp_core_reset,
48	.stall = avs_dsp_core_stall,
49	.irq_handler = avs_irq_handler,
50	.irq_thread = avs_cnl_irq_thread,
51	.int_control = avs_dsp_interrupt_control,
52	.load_basefw = avs_hda_load_basefw,
53	.load_lib = avs_hda_load_library,
54	.transfer_mods = avs_hda_transfer_modules,
55	.log_buffer_offset = avs_skl_log_buffer_offset,
56	.log_buffer_status = avs_apl_log_buffer_status,
57	.coredump = avs_apl_coredump,
58	.d0ix_toggle = avs_apl_d0ix_toggle,
59	.set_d0ix = avs_apl_set_d0ix,
60	AVS_SET_ENABLE_LOGS_OP(apl)
61};
62