cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hda-dsp.c (26828B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
      2//
      3// This file is provided under a dual BSD/GPLv2 license.  When using or
      4// redistributing this file, you may do so under either license.
      5//
      6// Copyright(c) 2018 Intel Corporation. All rights reserved.
      7//
      8// Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com>
      9//	    Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
     10//	    Rander Wang <rander.wang@intel.com>
     11//          Keyon Jie <yang.jie@linux.intel.com>
     12//
     13
     14/*
     15 * Hardware interface for generic Intel audio DSP HDA IP
     16 */
     17
     18#include <linux/module.h>
     19#include <sound/hdaudio_ext.h>
     20#include <sound/hda_register.h>
     21#include "../sof-audio.h"
     22#include "../ops.h"
     23#include "hda.h"
     24#include "hda-ipc.h"
     25
     26static bool hda_enable_trace_D0I3_S0;
     27#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG)
     28module_param_named(enable_trace_D0I3_S0, hda_enable_trace_D0I3_S0, bool, 0444);
     29MODULE_PARM_DESC(enable_trace_D0I3_S0,
     30		 "SOF HDA enable trace when the DSP is in D0I3 in S0");
     31#endif
     32
     33/*
     34 * DSP Core control.
     35 */
     36
     37static int hda_dsp_core_reset_enter(struct snd_sof_dev *sdev, unsigned int core_mask)
     38{
     39	u32 adspcs;
     40	u32 reset;
     41	int ret;
     42
     43	/* set reset bits for cores */
     44	reset = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
     45	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
     46					 HDA_DSP_REG_ADSPCS,
     47					 reset, reset);
     48
     49	/* poll with timeout to check if operation successful */
     50	ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
     51					HDA_DSP_REG_ADSPCS, adspcs,
     52					((adspcs & reset) == reset),
     53					HDA_DSP_REG_POLL_INTERVAL_US,
     54					HDA_DSP_RESET_TIMEOUT_US);
     55	if (ret < 0) {
     56		dev_err(sdev->dev,
     57			"error: %s: timeout on HDA_DSP_REG_ADSPCS read\n",
     58			__func__);
     59		return ret;
     60	}
     61
     62	/* has core entered reset ? */
     63	adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
     64				  HDA_DSP_REG_ADSPCS);
     65	if ((adspcs & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) !=
     66		HDA_DSP_ADSPCS_CRST_MASK(core_mask)) {
     67		dev_err(sdev->dev,
     68			"error: reset enter failed: core_mask %x adspcs 0x%x\n",
     69			core_mask, adspcs);
     70		ret = -EIO;
     71	}
     72
     73	return ret;
     74}
     75
     76static int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_mask)
     77{
     78	unsigned int crst;
     79	u32 adspcs;
     80	int ret;
     81
     82	/* clear reset bits for cores */
     83	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
     84					 HDA_DSP_REG_ADSPCS,
     85					 HDA_DSP_ADSPCS_CRST_MASK(core_mask),
     86					 0);
     87
     88	/* poll with timeout to check if operation successful */
     89	crst = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
     90	ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
     91					    HDA_DSP_REG_ADSPCS, adspcs,
     92					    !(adspcs & crst),
     93					    HDA_DSP_REG_POLL_INTERVAL_US,
     94					    HDA_DSP_RESET_TIMEOUT_US);
     95
     96	if (ret < 0) {
     97		dev_err(sdev->dev,
     98			"error: %s: timeout on HDA_DSP_REG_ADSPCS read\n",
     99			__func__);
    100		return ret;
    101	}
    102
    103	/* has core left reset ? */
    104	adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
    105				  HDA_DSP_REG_ADSPCS);
    106	if ((adspcs & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) != 0) {
    107		dev_err(sdev->dev,
    108			"error: reset leave failed: core_mask %x adspcs 0x%x\n",
    109			core_mask, adspcs);
    110		ret = -EIO;
    111	}
    112
    113	return ret;
    114}
    115
    116static int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask)
    117{
    118	/* stall core */
    119	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
    120					 HDA_DSP_REG_ADSPCS,
    121					 HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
    122					 HDA_DSP_ADSPCS_CSTALL_MASK(core_mask));
    123
    124	/* set reset state */
    125	return hda_dsp_core_reset_enter(sdev, core_mask);
    126}
    127
    128static bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, unsigned int core_mask)
    129{
    130	int val;
    131	bool is_enable;
    132
    133	val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS);
    134
    135#define MASK_IS_EQUAL(v, m, field) ({	\
    136	u32 _m = field(m);		\
    137	((v) & _m) == _m;		\
    138})
    139
    140	is_enable = MASK_IS_EQUAL(val, core_mask, HDA_DSP_ADSPCS_CPA_MASK) &&
    141		MASK_IS_EQUAL(val, core_mask, HDA_DSP_ADSPCS_SPA_MASK) &&
    142		!(val & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) &&
    143		!(val & HDA_DSP_ADSPCS_CSTALL_MASK(core_mask));
    144
    145#undef MASK_IS_EQUAL
    146
    147	dev_dbg(sdev->dev, "DSP core(s) enabled? %d : core_mask %x\n",
    148		is_enable, core_mask);
    149
    150	return is_enable;
    151}
    152
    153int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask)
    154{
    155	int ret;
    156
    157	/* leave reset state */
    158	ret = hda_dsp_core_reset_leave(sdev, core_mask);
    159	if (ret < 0)
    160		return ret;
    161
    162	/* run core */
    163	dev_dbg(sdev->dev, "unstall/run core: core_mask = %x\n", core_mask);
    164	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
    165					 HDA_DSP_REG_ADSPCS,
    166					 HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
    167					 0);
    168
    169	/* is core now running ? */
    170	if (!hda_dsp_core_is_enabled(sdev, core_mask)) {
    171		hda_dsp_core_stall_reset(sdev, core_mask);
    172		dev_err(sdev->dev, "error: DSP start core failed: core_mask %x\n",
    173			core_mask);
    174		ret = -EIO;
    175	}
    176
    177	return ret;
    178}
    179
    180/*
    181 * Power Management.
    182 */
    183
    184int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask)
    185{
    186	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
    187	const struct sof_intel_dsp_desc *chip = hda->desc;
    188	unsigned int cpa;
    189	u32 adspcs;
    190	int ret;
    191
    192	/* restrict core_mask to host managed cores mask */
    193	core_mask &= chip->host_managed_cores_mask;
    194	/* return if core_mask is not valid */
    195	if (!core_mask)
    196		return 0;
    197
    198	/* update bits */
    199	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS,
    200				HDA_DSP_ADSPCS_SPA_MASK(core_mask),
    201				HDA_DSP_ADSPCS_SPA_MASK(core_mask));
    202
    203	/* poll with timeout to check if operation successful */
    204	cpa = HDA_DSP_ADSPCS_CPA_MASK(core_mask);
    205	ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
    206					    HDA_DSP_REG_ADSPCS, adspcs,
    207					    (adspcs & cpa) == cpa,
    208					    HDA_DSP_REG_POLL_INTERVAL_US,
    209					    HDA_DSP_RESET_TIMEOUT_US);
    210	if (ret < 0) {
    211		dev_err(sdev->dev,
    212			"error: %s: timeout on HDA_DSP_REG_ADSPCS read\n",
    213			__func__);
    214		return ret;
    215	}
    216
    217	/* did core power up ? */
    218	adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
    219				  HDA_DSP_REG_ADSPCS);
    220	if ((adspcs & HDA_DSP_ADSPCS_CPA_MASK(core_mask)) !=
    221		HDA_DSP_ADSPCS_CPA_MASK(core_mask)) {
    222		dev_err(sdev->dev,
    223			"error: power up core failed core_mask %xadspcs 0x%x\n",
    224			core_mask, adspcs);
    225		ret = -EIO;
    226	}
    227
    228	return ret;
    229}
    230
    231static int hda_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask)
    232{
    233	u32 adspcs;
    234	int ret;
    235
    236	/* update bits */
    237	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
    238					 HDA_DSP_REG_ADSPCS,
    239					 HDA_DSP_ADSPCS_SPA_MASK(core_mask), 0);
    240
    241	ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
    242				HDA_DSP_REG_ADSPCS, adspcs,
    243				!(adspcs & HDA_DSP_ADSPCS_CPA_MASK(core_mask)),
    244				HDA_DSP_REG_POLL_INTERVAL_US,
    245				HDA_DSP_PD_TIMEOUT * USEC_PER_MSEC);
    246	if (ret < 0)
    247		dev_err(sdev->dev,
    248			"error: %s: timeout on HDA_DSP_REG_ADSPCS read\n",
    249			__func__);
    250
    251	return ret;
    252}
    253
    254int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask)
    255{
    256	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
    257	const struct sof_intel_dsp_desc *chip = hda->desc;
    258	int ret;
    259
    260	/* restrict core_mask to host managed cores mask */
    261	core_mask &= chip->host_managed_cores_mask;
    262
    263	/* return if core_mask is not valid or cores are already enabled */
    264	if (!core_mask || hda_dsp_core_is_enabled(sdev, core_mask))
    265		return 0;
    266
    267	/* power up */
    268	ret = hda_dsp_core_power_up(sdev, core_mask);
    269	if (ret < 0) {
    270		dev_err(sdev->dev, "error: dsp core power up failed: core_mask %x\n",
    271			core_mask);
    272		return ret;
    273	}
    274
    275	return hda_dsp_core_run(sdev, core_mask);
    276}
    277
    278int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev,
    279				  unsigned int core_mask)
    280{
    281	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
    282	const struct sof_intel_dsp_desc *chip = hda->desc;
    283	int ret;
    284
    285	/* restrict core_mask to host managed cores mask */
    286	core_mask &= chip->host_managed_cores_mask;
    287
    288	/* return if core_mask is not valid */
    289	if (!core_mask)
    290		return 0;
    291
    292	/* place core in reset prior to power down */
    293	ret = hda_dsp_core_stall_reset(sdev, core_mask);
    294	if (ret < 0) {
    295		dev_err(sdev->dev, "error: dsp core reset failed: core_mask %x\n",
    296			core_mask);
    297		return ret;
    298	}
    299
    300	/* power down core */
    301	ret = hda_dsp_core_power_down(sdev, core_mask);
    302	if (ret < 0) {
    303		dev_err(sdev->dev, "error: dsp core power down fail mask %x: %d\n",
    304			core_mask, ret);
    305		return ret;
    306	}
    307
    308	/* make sure we are in OFF state */
    309	if (hda_dsp_core_is_enabled(sdev, core_mask)) {
    310		dev_err(sdev->dev, "error: dsp core disable fail mask %x: %d\n",
    311			core_mask, ret);
    312		ret = -EIO;
    313	}
    314
    315	return ret;
    316}
    317
    318void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev)
    319{
    320	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
    321	const struct sof_intel_dsp_desc *chip = hda->desc;
    322
    323	/* enable IPC DONE and BUSY interrupts */
    324	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
    325			HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY,
    326			HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY);
    327
    328	/* enable IPC interrupt */
    329	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
    330				HDA_DSP_ADSPIC_IPC, HDA_DSP_ADSPIC_IPC);
    331}
    332
    333void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev)
    334{
    335	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
    336	const struct sof_intel_dsp_desc *chip = hda->desc;
    337
    338	/* disable IPC interrupt */
    339	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
    340				HDA_DSP_ADSPIC_IPC, 0);
    341
    342	/* disable IPC BUSY and DONE interrupt */
    343	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
    344			HDA_DSP_REG_HIPCCTL_BUSY | HDA_DSP_REG_HIPCCTL_DONE, 0);
    345}
    346
    347static int hda_dsp_wait_d0i3c_done(struct snd_sof_dev *sdev)
    348{
    349	struct hdac_bus *bus = sof_to_bus(sdev);
    350	int retry = HDA_DSP_REG_POLL_RETRY_COUNT;
    351
    352	while (snd_hdac_chip_readb(bus, VS_D0I3C) & SOF_HDA_VS_D0I3C_CIP) {
    353		if (!retry--)
    354			return -ETIMEDOUT;
    355		usleep_range(10, 15);
    356	}
    357
    358	return 0;
    359}
    360
    361static int hda_dsp_send_pm_gate_ipc(struct snd_sof_dev *sdev, u32 flags)
    362{
    363	struct sof_ipc_pm_gate pm_gate;
    364	struct sof_ipc_reply reply;
    365
    366	memset(&pm_gate, 0, sizeof(pm_gate));
    367
    368	/* configure pm_gate ipc message */
    369	pm_gate.hdr.size = sizeof(pm_gate);
    370	pm_gate.hdr.cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_GATE;
    371	pm_gate.flags = flags;
    372
    373	/* send pm_gate ipc to dsp */
    374	return sof_ipc_tx_message_no_pm(sdev->ipc, &pm_gate, sizeof(pm_gate),
    375					&reply, sizeof(reply));
    376}
    377
    378static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value)
    379{
    380	struct hdac_bus *bus = sof_to_bus(sdev);
    381	int ret;
    382
    383	/* Write to D0I3C after Command-In-Progress bit is cleared */
    384	ret = hda_dsp_wait_d0i3c_done(sdev);
    385	if (ret < 0) {
    386		dev_err(bus->dev, "CIP timeout before D0I3C update!\n");
    387		return ret;
    388	}
    389
    390	/* Update D0I3C register */
    391	snd_hdac_chip_updateb(bus, VS_D0I3C, SOF_HDA_VS_D0I3C_I3, value);
    392
    393	/* Wait for cmd in progress to be cleared before exiting the function */
    394	ret = hda_dsp_wait_d0i3c_done(sdev);
    395	if (ret < 0) {
    396		dev_err(bus->dev, "CIP timeout after D0I3C update!\n");
    397		return ret;
    398	}
    399
    400	dev_vdbg(bus->dev, "D0I3C updated, register = 0x%x\n",
    401		 snd_hdac_chip_readb(bus, VS_D0I3C));
    402
    403	return 0;
    404}
    405
    406static int hda_dsp_set_D0_state(struct snd_sof_dev *sdev,
    407				const struct sof_dsp_power_state *target_state)
    408{
    409	u32 flags = 0;
    410	int ret;
    411	u8 value = 0;
    412
    413	/*
    414	 * Sanity check for illegal state transitions
    415	 * The only allowed transitions are:
    416	 * 1. D3 -> D0I0
    417	 * 2. D0I0 -> D0I3
    418	 * 3. D0I3 -> D0I0
    419	 */
    420	switch (sdev->dsp_power_state.state) {
    421	case SOF_DSP_PM_D0:
    422		/* Follow the sequence below for D0 substate transitions */
    423		break;
    424	case SOF_DSP_PM_D3:
    425		/* Follow regular flow for D3 -> D0 transition */
    426		return 0;
    427	default:
    428		dev_err(sdev->dev, "error: transition from %d to %d not allowed\n",
    429			sdev->dsp_power_state.state, target_state->state);
    430		return -EINVAL;
    431	}
    432
    433	/* Set flags and register value for D0 target substate */
    434	if (target_state->substate == SOF_HDA_DSP_PM_D0I3) {
    435		value = SOF_HDA_VS_D0I3C_I3;
    436
    437		/*
    438		 * Trace DMA need to be disabled when the DSP enters
    439		 * D0I3 for S0Ix suspend, but it can be kept enabled
    440		 * when the DSP enters D0I3 while the system is in S0
    441		 * for debug purpose.
    442		 */
    443		if (!sdev->fw_trace_is_supported ||
    444		    !hda_enable_trace_D0I3_S0 ||
    445		    sdev->system_suspend_target != SOF_SUSPEND_NONE)
    446			flags = HDA_PM_NO_DMA_TRACE;
    447	} else {
    448		/* prevent power gating in D0I0 */
    449		flags = HDA_PM_PPG;
    450	}
    451
    452	/* update D0I3C register */
    453	ret = hda_dsp_update_d0i3c_register(sdev, value);
    454	if (ret < 0)
    455		return ret;
    456
    457	/*
    458	 * Notify the DSP of the state change.
    459	 * If this IPC fails, revert the D0I3C register update in order
    460	 * to prevent partial state change.
    461	 */
    462	ret = hda_dsp_send_pm_gate_ipc(sdev, flags);
    463	if (ret < 0) {
    464		dev_err(sdev->dev,
    465			"error: PM_GATE ipc error %d\n", ret);
    466		goto revert;
    467	}
    468
    469	return ret;
    470
    471revert:
    472	/* fallback to the previous register value */
    473	value = value ? 0 : SOF_HDA_VS_D0I3C_I3;
    474
    475	/*
    476	 * This can fail but return the IPC error to signal that
    477	 * the state change failed.
    478	 */
    479	hda_dsp_update_d0i3c_register(sdev, value);
    480
    481	return ret;
    482}
    483
    484/* helper to log DSP state */
    485static void hda_dsp_state_log(struct snd_sof_dev *sdev)
    486{
    487	switch (sdev->dsp_power_state.state) {
    488	case SOF_DSP_PM_D0:
    489		switch (sdev->dsp_power_state.substate) {
    490		case SOF_HDA_DSP_PM_D0I0:
    491			dev_dbg(sdev->dev, "Current DSP power state: D0I0\n");
    492			break;
    493		case SOF_HDA_DSP_PM_D0I3:
    494			dev_dbg(sdev->dev, "Current DSP power state: D0I3\n");
    495			break;
    496		default:
    497			dev_dbg(sdev->dev, "Unknown DSP D0 substate: %d\n",
    498				sdev->dsp_power_state.substate);
    499			break;
    500		}
    501		break;
    502	case SOF_DSP_PM_D1:
    503		dev_dbg(sdev->dev, "Current DSP power state: D1\n");
    504		break;
    505	case SOF_DSP_PM_D2:
    506		dev_dbg(sdev->dev, "Current DSP power state: D2\n");
    507		break;
    508	case SOF_DSP_PM_D3:
    509		dev_dbg(sdev->dev, "Current DSP power state: D3\n");
    510		break;
    511	default:
    512		dev_dbg(sdev->dev, "Unknown DSP power state: %d\n",
    513			sdev->dsp_power_state.state);
    514		break;
    515	}
    516}
    517
    518/*
    519 * All DSP power state transitions are initiated by the driver.
    520 * If the requested state change fails, the error is simply returned.
    521 * Further state transitions are attempted only when the set_power_save() op
    522 * is called again either because of a new IPC sent to the DSP or
    523 * during system suspend/resume.
    524 */
    525int hda_dsp_set_power_state(struct snd_sof_dev *sdev,
    526			    const struct sof_dsp_power_state *target_state)
    527{
    528	int ret = 0;
    529
    530	/*
    531	 * When the DSP is already in D0I3 and the target state is D0I3,
    532	 * it could be the case that the DSP is in D0I3 during S0
    533	 * and the system is suspending to S0Ix. Therefore,
    534	 * hda_dsp_set_D0_state() must be called to disable trace DMA
    535	 * by sending the PM_GATE IPC to the FW.
    536	 */
    537	if (target_state->substate == SOF_HDA_DSP_PM_D0I3 &&
    538	    sdev->system_suspend_target == SOF_SUSPEND_S0IX)
    539		goto set_state;
    540
    541	/*
    542	 * For all other cases, return without doing anything if
    543	 * the DSP is already in the target state.
    544	 */
    545	if (target_state->state == sdev->dsp_power_state.state &&
    546	    target_state->substate == sdev->dsp_power_state.substate)
    547		return 0;
    548
    549set_state:
    550	switch (target_state->state) {
    551	case SOF_DSP_PM_D0:
    552		ret = hda_dsp_set_D0_state(sdev, target_state);
    553		break;
    554	case SOF_DSP_PM_D3:
    555		/* The only allowed transition is: D0I0 -> D3 */
    556		if (sdev->dsp_power_state.state == SOF_DSP_PM_D0 &&
    557		    sdev->dsp_power_state.substate == SOF_HDA_DSP_PM_D0I0)
    558			break;
    559
    560		dev_err(sdev->dev,
    561			"error: transition from %d to %d not allowed\n",
    562			sdev->dsp_power_state.state, target_state->state);
    563		return -EINVAL;
    564	default:
    565		dev_err(sdev->dev, "error: target state unsupported %d\n",
    566			target_state->state);
    567		return -EINVAL;
    568	}
    569	if (ret < 0) {
    570		dev_err(sdev->dev,
    571			"failed to set requested target DSP state %d substate %d\n",
    572			target_state->state, target_state->substate);
    573		return ret;
    574	}
    575
    576	sdev->dsp_power_state = *target_state;
    577	hda_dsp_state_log(sdev);
    578	return ret;
    579}
    580
    581/*
    582 * Audio DSP states may transform as below:-
    583 *
    584 *                                         Opportunistic D0I3 in S0
    585 *     Runtime    +---------------------+  Delayed D0i3 work timeout
    586 *     suspend    |                     +--------------------+
    587 *   +------------+       D0I0(active)  |                    |
    588 *   |            |                     <---------------+    |
    589 *   |   +-------->                     |    New IPC	|    |
    590 *   |   |Runtime +--^--+---------^--+--+ (via mailbox)	|    |
    591 *   |   |resume     |  |         |  |			|    |
    592 *   |   |           |  |         |  |			|    |
    593 *   |   |     System|  |         |  |			|    |
    594 *   |   |     resume|  | S3/S0IX |  |                  |    |
    595 *   |   |	     |  | suspend |  | S0IX             |    |
    596 *   |   |           |  |         |  |suspend           |    |
    597 *   |   |           |  |         |  |                  |    |
    598 *   |   |           |  |         |  |                  |    |
    599 * +-v---+-----------+--v-------+ |  |           +------+----v----+
    600 * |                            | |  +----------->                |
    601 * |       D3 (suspended)       | |              |      D0I3      |
    602 * |                            | +--------------+                |
    603 * |                            |  System resume |                |
    604 * +----------------------------+		 +----------------+
    605 *
    606 * S0IX suspend: The DSP is in D0I3 if any D0I3-compatible streams
    607 *		 ignored the suspend trigger. Otherwise the DSP
    608 *		 is in D3.
    609 */
    610
    611static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
    612{
    613	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
    614	const struct sof_intel_dsp_desc *chip = hda->desc;
    615#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
    616	struct hdac_bus *bus = sof_to_bus(sdev);
    617#endif
    618	int ret, j;
    619
    620	hda_sdw_int_enable(sdev, false);
    621
    622	/* disable IPC interrupts */
    623	hda_dsp_ipc_int_disable(sdev);
    624
    625#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
    626	hda_codec_jack_wake_enable(sdev, runtime_suspend);
    627
    628	/* power down all hda link */
    629	snd_hdac_ext_bus_link_power_down_all(bus);
    630#endif
    631
    632	/* power down DSP */
    633	ret = hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask);
    634	if (ret < 0) {
    635		dev_err(sdev->dev,
    636			"error: failed to power down core during suspend\n");
    637		return ret;
    638	}
    639
    640	/* reset ref counts for all cores */
    641	for (j = 0; j < chip->cores_num; j++)
    642		sdev->dsp_core_ref_count[j] = 0;
    643
    644	/* disable ppcap interrupt */
    645	hda_dsp_ctrl_ppcap_enable(sdev, false);
    646	hda_dsp_ctrl_ppcap_int_enable(sdev, false);
    647
    648	/* disable hda bus irq and streams */
    649	hda_dsp_ctrl_stop_chip(sdev);
    650
    651	/* disable LP retention mode */
    652	snd_sof_pci_update_bits(sdev, PCI_PGCTL,
    653				PCI_PGCTL_LSRMD_MASK, PCI_PGCTL_LSRMD_MASK);
    654
    655	/* reset controller */
    656	ret = hda_dsp_ctrl_link_reset(sdev, true);
    657	if (ret < 0) {
    658		dev_err(sdev->dev,
    659			"error: failed to reset controller during suspend\n");
    660		return ret;
    661	}
    662
    663	/* display codec can powered off after link reset */
    664	hda_codec_i915_display_power(sdev, false);
    665
    666	return 0;
    667}
    668
    669static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
    670{
    671#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
    672	struct hdac_bus *bus = sof_to_bus(sdev);
    673	struct hdac_ext_link *hlink = NULL;
    674#endif
    675	int ret;
    676
    677	/* display codec must be powered before link reset */
    678	hda_codec_i915_display_power(sdev, true);
    679
    680	/*
    681	 * clear TCSEL to clear playback on some HD Audio
    682	 * codecs. PCI TCSEL is defined in the Intel manuals.
    683	 */
    684	snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
    685
    686	/* reset and start hda controller */
    687	ret = hda_dsp_ctrl_init_chip(sdev, true);
    688	if (ret < 0) {
    689		dev_err(sdev->dev,
    690			"error: failed to start controller after resume\n");
    691		goto cleanup;
    692	}
    693
    694#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
    695	/* check jack status */
    696	if (runtime_resume) {
    697		hda_codec_jack_wake_enable(sdev, false);
    698		if (sdev->system_suspend_target == SOF_SUSPEND_NONE)
    699			hda_codec_jack_check(sdev);
    700	}
    701
    702	/* turn off the links that were off before suspend */
    703	list_for_each_entry(hlink, &bus->hlink_list, list) {
    704		if (!hlink->ref_count)
    705			snd_hdac_ext_bus_link_power_down(hlink);
    706	}
    707
    708	/* check dma status and clean up CORB/RIRB buffers */
    709	if (!bus->cmd_dma_state)
    710		snd_hdac_bus_stop_cmd_io(bus);
    711#endif
    712
    713	/* enable ppcap interrupt */
    714	hda_dsp_ctrl_ppcap_enable(sdev, true);
    715	hda_dsp_ctrl_ppcap_int_enable(sdev, true);
    716
    717cleanup:
    718	/* display codec can powered off after controller init */
    719	hda_codec_i915_display_power(sdev, false);
    720
    721	return 0;
    722}
    723
    724int hda_dsp_resume(struct snd_sof_dev *sdev)
    725{
    726	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
    727	struct pci_dev *pci = to_pci_dev(sdev->dev);
    728	const struct sof_dsp_power_state target_state = {
    729		.state = SOF_DSP_PM_D0,
    730		.substate = SOF_HDA_DSP_PM_D0I0,
    731	};
    732#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
    733	struct hdac_bus *bus = sof_to_bus(sdev);
    734	struct hdac_ext_link *hlink = NULL;
    735#endif
    736	int ret;
    737
    738	/* resume from D0I3 */
    739	if (sdev->dsp_power_state.state == SOF_DSP_PM_D0) {
    740#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
    741		/* power up links that were active before suspend */
    742		list_for_each_entry(hlink, &bus->hlink_list, list) {
    743			if (hlink->ref_count) {
    744				ret = snd_hdac_ext_bus_link_power_up(hlink);
    745				if (ret < 0) {
    746					dev_dbg(sdev->dev,
    747						"error %d in %s: failed to power up links",
    748						ret, __func__);
    749					return ret;
    750				}
    751			}
    752		}
    753
    754		/* set up CORB/RIRB buffers if was on before suspend */
    755		if (bus->cmd_dma_state)
    756			snd_hdac_bus_init_cmd_io(bus);
    757#endif
    758
    759		/* Set DSP power state */
    760		ret = snd_sof_dsp_set_power_state(sdev, &target_state);
    761		if (ret < 0) {
    762			dev_err(sdev->dev, "error: setting dsp state %d substate %d\n",
    763				target_state.state, target_state.substate);
    764			return ret;
    765		}
    766
    767		/* restore L1SEN bit */
    768		if (hda->l1_support_changed)
    769			snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
    770						HDA_VS_INTEL_EM2,
    771						HDA_VS_INTEL_EM2_L1SEN, 0);
    772
    773		/* restore and disable the system wakeup */
    774		pci_restore_state(pci);
    775		disable_irq_wake(pci->irq);
    776		return 0;
    777	}
    778
    779	/* init hda controller. DSP cores will be powered up during fw boot */
    780	ret = hda_resume(sdev, false);
    781	if (ret < 0)
    782		return ret;
    783
    784	return snd_sof_dsp_set_power_state(sdev, &target_state);
    785}
    786
    787int hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
    788{
    789	const struct sof_dsp_power_state target_state = {
    790		.state = SOF_DSP_PM_D0,
    791	};
    792	int ret;
    793
    794	/* init hda controller. DSP cores will be powered up during fw boot */
    795	ret = hda_resume(sdev, true);
    796	if (ret < 0)
    797		return ret;
    798
    799	return snd_sof_dsp_set_power_state(sdev, &target_state);
    800}
    801
    802int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
    803{
    804	struct hdac_bus *hbus = sof_to_bus(sdev);
    805
    806	if (hbus->codec_powered) {
    807		dev_dbg(sdev->dev, "some codecs still powered (%08X), not idle\n",
    808			(unsigned int)hbus->codec_powered);
    809		return -EBUSY;
    810	}
    811
    812	return 0;
    813}
    814
    815int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev)
    816{
    817	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
    818	const struct sof_dsp_power_state target_state = {
    819		.state = SOF_DSP_PM_D3,
    820	};
    821	int ret;
    822
    823	/* cancel any attempt for DSP D0I3 */
    824	cancel_delayed_work_sync(&hda->d0i3_work);
    825
    826	/* stop hda controller and power dsp off */
    827	ret = hda_suspend(sdev, true);
    828	if (ret < 0)
    829		return ret;
    830
    831	return snd_sof_dsp_set_power_state(sdev, &target_state);
    832}
    833
    834int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
    835{
    836	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
    837	struct hdac_bus *bus = sof_to_bus(sdev);
    838	struct pci_dev *pci = to_pci_dev(sdev->dev);
    839	const struct sof_dsp_power_state target_dsp_state = {
    840		.state = target_state,
    841		.substate = target_state == SOF_DSP_PM_D0 ?
    842				SOF_HDA_DSP_PM_D0I3 : 0,
    843	};
    844	int ret;
    845
    846	/* cancel any attempt for DSP D0I3 */
    847	cancel_delayed_work_sync(&hda->d0i3_work);
    848
    849	if (target_state == SOF_DSP_PM_D0) {
    850		/* Set DSP power state */
    851		ret = snd_sof_dsp_set_power_state(sdev, &target_dsp_state);
    852		if (ret < 0) {
    853			dev_err(sdev->dev, "error: setting dsp state %d substate %d\n",
    854				target_dsp_state.state,
    855				target_dsp_state.substate);
    856			return ret;
    857		}
    858
    859		/* enable L1SEN to make sure the system can enter S0Ix */
    860		hda->l1_support_changed =
    861			snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
    862						HDA_VS_INTEL_EM2,
    863						HDA_VS_INTEL_EM2_L1SEN,
    864						HDA_VS_INTEL_EM2_L1SEN);
    865
    866#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
    867		/* stop the CORB/RIRB DMA if it is On */
    868		if (bus->cmd_dma_state)
    869			snd_hdac_bus_stop_cmd_io(bus);
    870
    871		/* no link can be powered in s0ix state */
    872		ret = snd_hdac_ext_bus_link_power_down_all(bus);
    873		if (ret < 0) {
    874			dev_dbg(sdev->dev,
    875				"error %d in %s: failed to power down links",
    876				ret, __func__);
    877			return ret;
    878		}
    879#endif
    880
    881		/* enable the system waking up via IPC IRQ */
    882		enable_irq_wake(pci->irq);
    883		pci_save_state(pci);
    884		return 0;
    885	}
    886
    887	/* stop hda controller and power dsp off */
    888	ret = hda_suspend(sdev, false);
    889	if (ret < 0) {
    890		dev_err(bus->dev, "error: suspending dsp\n");
    891		return ret;
    892	}
    893
    894	return snd_sof_dsp_set_power_state(sdev, &target_dsp_state);
    895}
    896
    897int hda_dsp_shutdown(struct snd_sof_dev *sdev)
    898{
    899	sdev->system_suspend_target = SOF_SUSPEND_S3;
    900	return snd_sof_suspend(sdev->dev);
    901}
    902
    903int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
    904{
    905	int ret;
    906
    907	/* make sure all DAI resources are freed */
    908	ret = hda_dsp_dais_suspend(sdev);
    909	if (ret < 0)
    910		dev_warn(sdev->dev, "%s: failure in hda_dsp_dais_suspend\n", __func__);
    911
    912	return ret;
    913}
    914
    915void hda_dsp_d0i3_work(struct work_struct *work)
    916{
    917	struct sof_intel_hda_dev *hdev = container_of(work,
    918						      struct sof_intel_hda_dev,
    919						      d0i3_work.work);
    920	struct hdac_bus *bus = &hdev->hbus.core;
    921	struct snd_sof_dev *sdev = dev_get_drvdata(bus->dev);
    922	struct sof_dsp_power_state target_state = {
    923		.state = SOF_DSP_PM_D0,
    924		.substate = SOF_HDA_DSP_PM_D0I3,
    925	};
    926	int ret;
    927
    928	/* DSP can enter D0I3 iff only D0I3-compatible streams are active */
    929	if (!snd_sof_dsp_only_d0i3_compatible_stream_active(sdev))
    930		/* remain in D0I0 */
    931		return;
    932
    933	/* This can fail but error cannot be propagated */
    934	ret = snd_sof_dsp_set_power_state(sdev, &target_state);
    935	if (ret < 0)
    936		dev_err_ratelimited(sdev->dev,
    937				    "error: failed to set DSP state %d substate %d\n",
    938				    target_state.state, target_state.substate);
    939}
    940
    941int hda_dsp_core_get(struct snd_sof_dev *sdev, int core)
    942{
    943	struct sof_ipc_pm_core_config pm_core_config = {
    944		.hdr = {
    945			.cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE,
    946			.size = sizeof(pm_core_config),
    947		},
    948		.enable_mask = sdev->enabled_cores_mask | BIT(core),
    949	};
    950	int ret, ret1;
    951
    952	/* power up core */
    953	ret = hda_dsp_enable_core(sdev, BIT(core));
    954	if (ret < 0) {
    955		dev_err(sdev->dev, "failed to power up core %d with err: %d\n",
    956			core, ret);
    957		return ret;
    958	}
    959
    960	/* No need to send IPC for primary core or if FW boot is not complete */
    961	if (sdev->fw_state != SOF_FW_BOOT_COMPLETE || core == SOF_DSP_PRIMARY_CORE)
    962		return 0;
    963
    964	/* Now notify DSP for secondary cores */
    965	ret = sof_ipc_tx_message(sdev->ipc, &pm_core_config, sizeof(pm_core_config),
    966				 &pm_core_config, sizeof(pm_core_config));
    967	if (ret < 0) {
    968		dev_err(sdev->dev, "failed to enable secondary core '%d' failed with %d\n",
    969			core, ret);
    970		goto power_down;
    971	}
    972
    973	return ret;
    974
    975power_down:
    976	/* power down core if it is host managed and return the original error if this fails too */
    977	ret1 = hda_dsp_core_reset_power_down(sdev, BIT(core));
    978	if (ret1 < 0)
    979		dev_err(sdev->dev, "failed to power down core: %d with err: %d\n", core, ret1);
    980
    981	return ret;
    982}