1*af1c968dSCezary Rojewski // SPDX-License-Identifier: GPL-2.0-only
2*af1c968dSCezary Rojewski /*
3*af1c968dSCezary Rojewski * Copyright(c) 2024-2025 Intel Corporation
4*af1c968dSCezary Rojewski *
5*af1c968dSCezary Rojewski * Authors: Cezary Rojewski <cezary.rojewski@intel.com>
6*af1c968dSCezary Rojewski * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
7*af1c968dSCezary Rojewski */
8*af1c968dSCezary Rojewski
9*af1c968dSCezary Rojewski #include <sound/hdaudio_ext.h>
10*af1c968dSCezary Rojewski #include "avs.h"
11*af1c968dSCezary Rojewski #include "registers.h"
12*af1c968dSCezary Rojewski #include "trace.h"
13*af1c968dSCezary Rojewski
14*af1c968dSCezary Rojewski #define MTL_HfDSSGBL_BASE 0x1000
15*af1c968dSCezary Rojewski #define MTL_REG_HfDSSCS (MTL_HfDSSGBL_BASE + 0x0)
16*af1c968dSCezary Rojewski #define MTL_HfDSSCS_SPA BIT(16)
17*af1c968dSCezary Rojewski #define MTL_HfDSSCS_CPA BIT(24)
18*af1c968dSCezary Rojewski
19*af1c968dSCezary Rojewski #define MTL_DSPCS_BASE 0x178D00
20*af1c968dSCezary Rojewski #define MTL_REG_DSPCCTL (MTL_DSPCS_BASE + 0x4)
21*af1c968dSCezary Rojewski #define MTL_DSPCCTL_OSEL GENMASK(25, 24)
22*af1c968dSCezary Rojewski #define MTL_DSPCCTL_OSEL_HOST BIT(25)
23*af1c968dSCezary Rojewski
avs_ptl_core_power_on(struct avs_dev * adev)24*af1c968dSCezary Rojewski static int avs_ptl_core_power_on(struct avs_dev *adev)
25*af1c968dSCezary Rojewski {
26*af1c968dSCezary Rojewski u32 reg;
27*af1c968dSCezary Rojewski int ret;
28*af1c968dSCezary Rojewski
29*af1c968dSCezary Rojewski /* Power up DSP domain. */
30*af1c968dSCezary Rojewski snd_hdac_adsp_updatel(adev, MTL_REG_HfDSSCS, MTL_HfDSSCS_SPA, MTL_HfDSSCS_SPA);
31*af1c968dSCezary Rojewski trace_avs_dsp_core_op(1, AVS_MAIN_CORE_MASK, "power dsp", true);
32*af1c968dSCezary Rojewski
33*af1c968dSCezary Rojewski ret = snd_hdac_adsp_readl_poll(adev, MTL_REG_HfDSSCS, reg,
34*af1c968dSCezary Rojewski (reg & MTL_HfDSSCS_CPA) == MTL_HfDSSCS_CPA,
35*af1c968dSCezary Rojewski AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
36*af1c968dSCezary Rojewski if (ret) {
37*af1c968dSCezary Rojewski dev_err(adev->dev, "power on domain dsp failed: %d\n", ret);
38*af1c968dSCezary Rojewski return ret;
39*af1c968dSCezary Rojewski }
40*af1c968dSCezary Rojewski
41*af1c968dSCezary Rojewski /* Prevent power gating of DSP domain. */
42*af1c968dSCezary Rojewski snd_hdac_adsp_updatel(adev, MTL_REG_HfPWRCTL2, MTL_HfPWRCTL2_WPDSPHPxPG,
43*af1c968dSCezary Rojewski MTL_HfPWRCTL2_WPDSPHPxPG);
44*af1c968dSCezary Rojewski trace_avs_dsp_core_op(1, AVS_MAIN_CORE_MASK, "prevent dsp PG", true);
45*af1c968dSCezary Rojewski
46*af1c968dSCezary Rojewski ret = snd_hdac_adsp_readl_poll(adev, MTL_REG_HfPWRSTS2, reg,
47*af1c968dSCezary Rojewski (reg & MTL_HfPWRSTS2_DSPHPxPGS) == MTL_HfPWRSTS2_DSPHPxPGS,
48*af1c968dSCezary Rojewski AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
49*af1c968dSCezary Rojewski
50*af1c968dSCezary Rojewski /* Set ownership to HOST. */
51*af1c968dSCezary Rojewski snd_hdac_adsp_updatel(adev, MTL_REG_DSPCCTL, MTL_DSPCCTL_OSEL, MTL_DSPCCTL_OSEL_HOST);
52*af1c968dSCezary Rojewski return ret;
53*af1c968dSCezary Rojewski }
54*af1c968dSCezary Rojewski
avs_ptl_core_power_off(struct avs_dev * adev)55*af1c968dSCezary Rojewski static int avs_ptl_core_power_off(struct avs_dev *adev)
56*af1c968dSCezary Rojewski {
57*af1c968dSCezary Rojewski u32 reg;
58*af1c968dSCezary Rojewski
59*af1c968dSCezary Rojewski /* Allow power gating of DSP domain. No STS polling as HOST is only one of its users. */
60*af1c968dSCezary Rojewski snd_hdac_adsp_updatel(adev, MTL_REG_HfPWRCTL2, MTL_HfPWRCTL2_WPDSPHPxPG, 0);
61*af1c968dSCezary Rojewski trace_avs_dsp_core_op(0, AVS_MAIN_CORE_MASK, "allow dsp pg", false);
62*af1c968dSCezary Rojewski
63*af1c968dSCezary Rojewski /* Power down DSP domain. */
64*af1c968dSCezary Rojewski snd_hdac_adsp_updatel(adev, MTL_REG_HfDSSCS, MTL_HfDSSCS_SPA, 0);
65*af1c968dSCezary Rojewski trace_avs_dsp_core_op(0, AVS_MAIN_CORE_MASK, "power dsp", false);
66*af1c968dSCezary Rojewski
67*af1c968dSCezary Rojewski return snd_hdac_adsp_readl_poll(adev, MTL_REG_HfDSSCS, reg,
68*af1c968dSCezary Rojewski (reg & MTL_HfDSSCS_CPA) == 0,
69*af1c968dSCezary Rojewski AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US);
70*af1c968dSCezary Rojewski }
71*af1c968dSCezary Rojewski
avs_ptl_core_power(struct avs_dev * adev,u32 core_mask,bool power)72*af1c968dSCezary Rojewski static int avs_ptl_core_power(struct avs_dev *adev, u32 core_mask, bool power)
73*af1c968dSCezary Rojewski {
74*af1c968dSCezary Rojewski core_mask &= AVS_MAIN_CORE_MASK;
75*af1c968dSCezary Rojewski if (!core_mask)
76*af1c968dSCezary Rojewski return 0;
77*af1c968dSCezary Rojewski
78*af1c968dSCezary Rojewski if (power)
79*af1c968dSCezary Rojewski return avs_ptl_core_power_on(adev);
80*af1c968dSCezary Rojewski return avs_ptl_core_power_off(adev);
81*af1c968dSCezary Rojewski }
82*af1c968dSCezary Rojewski
83*af1c968dSCezary Rojewski const struct avs_dsp_ops avs_ptl_dsp_ops = {
84*af1c968dSCezary Rojewski .power = avs_ptl_core_power,
85*af1c968dSCezary Rojewski .reset = avs_mtl_core_reset,
86*af1c968dSCezary Rojewski .stall = avs_lnl_core_stall,
87*af1c968dSCezary Rojewski .dsp_interrupt = avs_mtl_dsp_interrupt,
88*af1c968dSCezary Rojewski .int_control = avs_mtl_interrupt_control,
89*af1c968dSCezary Rojewski .load_basefw = avs_hda_load_basefw,
90*af1c968dSCezary Rojewski .load_lib = avs_hda_load_library,
91*af1c968dSCezary Rojewski .transfer_mods = avs_hda_transfer_modules,
92*af1c968dSCezary Rojewski .log_buffer_offset = avs_icl_log_buffer_offset,
93*af1c968dSCezary Rojewski .log_buffer_status = avs_apl_log_buffer_status,
94*af1c968dSCezary Rojewski .coredump = avs_apl_coredump,
95*af1c968dSCezary Rojewski .d0ix_toggle = avs_icl_d0ix_toggle,
96*af1c968dSCezary Rojewski .set_d0ix = avs_icl_set_d0ix,
97*af1c968dSCezary Rojewski AVS_SET_ENABLE_LOGS_OP(icl)
98*af1c968dSCezary Rojewski };
99