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

icl.c (4348B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
      2//
      3// Copyright(c) 2020 Intel Corporation. All rights reserved.
      4//
      5// Author: Fred Oh <fred.oh@linux.intel.com>
      6//
      7
      8/*
      9 * Hardware interface for audio DSP on IceLake.
     10 */
     11
     12#include <linux/kernel.h>
     13#include <linux/kconfig.h>
     14#include <linux/export.h>
     15#include <linux/bits.h>
     16#include "../ops.h"
     17#include "hda.h"
     18#include "hda-ipc.h"
     19#include "../sof-audio.h"
     20
     21#define ICL_DSP_HPRO_CORE_ID 3
     22
     23static const struct snd_sof_debugfs_map icl_dsp_debugfs[] = {
     24	{"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
     25	{"pp", HDA_DSP_PP_BAR,  0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS},
     26	{"dsp", HDA_DSP_BAR,  0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
     27};
     28
     29static int icl_dsp_core_stall(struct snd_sof_dev *sdev, unsigned int core_mask)
     30{
     31	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
     32	const struct sof_intel_dsp_desc *chip = hda->desc;
     33
     34	/* make sure core_mask in host managed cores */
     35	core_mask &= chip->host_managed_cores_mask;
     36	if (!core_mask) {
     37		dev_err(sdev->dev, "error: core_mask is not in host managed cores\n");
     38		return -EINVAL;
     39	}
     40
     41	/* stall core */
     42	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS,
     43					 HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
     44					 HDA_DSP_ADSPCS_CSTALL_MASK(core_mask));
     45
     46	return 0;
     47}
     48
     49/*
     50 * post fw run operation for ICL.
     51 * Core 3 will be powered up and in stall when HPRO is enabled
     52 */
     53static int icl_dsp_post_fw_run(struct snd_sof_dev *sdev)
     54{
     55	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
     56	int ret;
     57
     58	if (sdev->first_boot) {
     59		struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
     60
     61		ret = hda_sdw_startup(sdev);
     62		if (ret < 0) {
     63			dev_err(sdev->dev, "error: could not startup SoundWire links\n");
     64			return ret;
     65		}
     66
     67		/* Check if IMR boot is usable */
     68		if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT) &&
     69		    sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT)
     70			hdev->imrboot_supported = true;
     71	}
     72
     73	hda_sdw_int_enable(sdev, true);
     74
     75	/*
     76	 * The recommended HW programming sequence for ICL is to
     77	 * power up core 3 and keep it in stall if HPRO is enabled.
     78	 */
     79	if (!hda->clk_config_lpro) {
     80		ret = hda_dsp_enable_core(sdev, BIT(ICL_DSP_HPRO_CORE_ID));
     81		if (ret < 0) {
     82			dev_err(sdev->dev, "error: dsp core power up failed on core %d\n",
     83				ICL_DSP_HPRO_CORE_ID);
     84			return ret;
     85		}
     86
     87		sdev->enabled_cores_mask |= BIT(ICL_DSP_HPRO_CORE_ID);
     88		sdev->dsp_core_ref_count[ICL_DSP_HPRO_CORE_ID]++;
     89
     90		snd_sof_dsp_stall(sdev, BIT(ICL_DSP_HPRO_CORE_ID));
     91	}
     92
     93	/* re-enable clock gating and power gating */
     94	return hda_dsp_ctrl_clock_power_gating(sdev, true);
     95}
     96
     97/* Icelake ops */
     98struct snd_sof_dsp_ops sof_icl_ops;
     99EXPORT_SYMBOL_NS(sof_icl_ops, SND_SOC_SOF_INTEL_HDA_COMMON);
    100
    101int sof_icl_ops_init(struct snd_sof_dev *sdev)
    102{
    103	/* common defaults */
    104	memcpy(&sof_icl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));
    105
    106	/* probe/remove/shutdown */
    107	sof_icl_ops.shutdown	= hda_dsp_shutdown;
    108
    109	/* doorbell */
    110	sof_icl_ops.irq_thread	= cnl_ipc_irq_thread;
    111
    112	/* ipc */
    113	sof_icl_ops.send_msg	= cnl_ipc_send_msg;
    114
    115	/* debug */
    116	sof_icl_ops.debug_map	= icl_dsp_debugfs;
    117	sof_icl_ops.debug_map_count	= ARRAY_SIZE(icl_dsp_debugfs);
    118	sof_icl_ops.ipc_dump	= cnl_ipc_dump;
    119
    120	/* pre/post fw run */
    121	sof_icl_ops.post_fw_run = icl_dsp_post_fw_run;
    122
    123	/* firmware run */
    124	sof_icl_ops.run = hda_dsp_cl_boot_firmware_iccmax;
    125	sof_icl_ops.stall = icl_dsp_core_stall;
    126
    127	/* dsp core get/put */
    128	sof_icl_ops.core_get = hda_dsp_core_get;
    129
    130	/* set DAI driver ops */
    131	hda_set_dai_drv_ops(sdev, &sof_icl_ops);
    132
    133	return 0;
    134};
    135EXPORT_SYMBOL_NS(sof_icl_ops_init, SND_SOC_SOF_INTEL_HDA_COMMON);
    136
    137const struct sof_intel_dsp_desc icl_chip_info = {
    138	/* Icelake */
    139	.cores_num = 4,
    140	.init_core_mask = 1,
    141	.host_managed_cores_mask = GENMASK(3, 0),
    142	.ipc_req = CNL_DSP_REG_HIPCIDR,
    143	.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
    144	.ipc_ack = CNL_DSP_REG_HIPCIDA,
    145	.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
    146	.ipc_ctl = CNL_DSP_REG_HIPCCTL,
    147	.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
    148	.rom_init_timeout	= 300,
    149	.ssp_count = ICL_SSP_COUNT,
    150	.ssp_base_offset = CNL_SSP_BASE_OFFSET,
    151	.sdw_shim_base = SDW_SHIM_BASE,
    152	.sdw_alh_base = SDW_ALH_BASE,
    153	.check_sdw_irq	= hda_common_check_sdw_irq,
    154	.check_ipc_irq	= hda_dsp_check_ipc_irq,
    155	.hw_ip_version = SOF_INTEL_CAVS_2_0,
    156};
    157EXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);