Commit e3c591c0 authored by Mark Brown's avatar Mark Brown

ASoC: SOF: Intel: update D0i3 registers for MTL

Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:

MeteorLake relies on a different register for D0i3 configuration, add
a platform-specific callback to abstract the differences.
parents 43b429f0 57f93492
...@@ -109,6 +109,7 @@ const struct sof_intel_dsp_desc apl_chip_info = { ...@@ -109,6 +109,7 @@ const struct sof_intel_dsp_desc apl_chip_info = {
.rom_init_timeout = 150, .rom_init_timeout = 150,
.ssp_count = APL_SSP_COUNT, .ssp_count = APL_SSP_COUNT,
.ssp_base_offset = APL_SSP_BASE_OFFSET, .ssp_base_offset = APL_SSP_BASE_OFFSET,
.d0i3_offset = SOF_HDA_VS_D0I3C,
.quirks = SOF_INTEL_PROCEN_FMT_QUIRK, .quirks = SOF_INTEL_PROCEN_FMT_QUIRK,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
......
...@@ -456,6 +456,7 @@ const struct sof_intel_dsp_desc cnl_chip_info = { ...@@ -456,6 +456,7 @@ const struct sof_intel_dsp_desc cnl_chip_info = {
.ssp_base_offset = CNL_SSP_BASE_OFFSET, .ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
...@@ -488,6 +489,7 @@ const struct sof_intel_dsp_desc jsl_chip_info = { ...@@ -488,6 +489,7 @@ const struct sof_intel_dsp_desc jsl_chip_info = {
.ssp_base_offset = CNL_SSP_BASE_OFFSET, .ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
......
...@@ -348,8 +348,12 @@ void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev) ...@@ -348,8 +348,12 @@ void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev)
static int hda_dsp_wait_d0i3c_done(struct snd_sof_dev *sdev) static int hda_dsp_wait_d0i3c_done(struct snd_sof_dev *sdev)
{ {
int retry = HDA_DSP_REG_POLL_RETRY_COUNT; int retry = HDA_DSP_REG_POLL_RETRY_COUNT;
struct snd_sof_pdata *pdata = sdev->pdata;
const struct sof_intel_dsp_desc *chip;
while (snd_sof_dsp_read8(sdev, HDA_DSP_HDA_BAR, SOF_HDA_VS_D0I3C) & SOF_HDA_VS_D0I3C_CIP) { chip = get_chip_info(pdata);
while (snd_sof_dsp_read8(sdev, HDA_DSP_HDA_BAR, chip->d0i3_offset) &
SOF_HDA_VS_D0I3C_CIP) {
if (!retry--) if (!retry--)
return -ETIMEDOUT; return -ETIMEDOUT;
usleep_range(10, 15); usleep_range(10, 15);
...@@ -377,29 +381,32 @@ static int hda_dsp_send_pm_gate_ipc(struct snd_sof_dev *sdev, u32 flags) ...@@ -377,29 +381,32 @@ static int hda_dsp_send_pm_gate_ipc(struct snd_sof_dev *sdev, u32 flags)
static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value) static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value)
{ {
struct hdac_bus *bus = sof_to_bus(sdev); struct snd_sof_pdata *pdata = sdev->pdata;
const struct sof_intel_dsp_desc *chip;
int ret; int ret;
u8 reg; u8 reg;
chip = get_chip_info(pdata);
/* Write to D0I3C after Command-In-Progress bit is cleared */ /* Write to D0I3C after Command-In-Progress bit is cleared */
ret = hda_dsp_wait_d0i3c_done(sdev); ret = hda_dsp_wait_d0i3c_done(sdev);
if (ret < 0) { if (ret < 0) {
dev_err(bus->dev, "CIP timeout before D0I3C update!\n"); dev_err(sdev->dev, "CIP timeout before D0I3C update!\n");
return ret; return ret;
} }
/* Update D0I3C register */ /* Update D0I3C register */
snd_sof_dsp_update8(sdev, HDA_DSP_HDA_BAR, snd_sof_dsp_update8(sdev, HDA_DSP_HDA_BAR, chip->d0i3_offset,
SOF_HDA_VS_D0I3C, SOF_HDA_VS_D0I3C_I3, value); SOF_HDA_VS_D0I3C_I3, value);
/* Wait for cmd in progress to be cleared before exiting the function */ /* Wait for cmd in progress to be cleared before exiting the function */
ret = hda_dsp_wait_d0i3c_done(sdev); ret = hda_dsp_wait_d0i3c_done(sdev);
if (ret < 0) { if (ret < 0) {
dev_err(bus->dev, "CIP timeout after D0I3C update!\n"); dev_err(sdev->dev, "CIP timeout after D0I3C update!\n");
return ret; return ret;
} }
reg = snd_sof_dsp_read8(sdev, HDA_DSP_HDA_BAR, SOF_HDA_VS_D0I3C); reg = snd_sof_dsp_read8(sdev, HDA_DSP_HDA_BAR, chip->d0i3_offset);
trace_sof_intel_D0I3C_updated(sdev, reg); trace_sof_intel_D0I3C_updated(sdev, reg);
return 0; return 0;
......
...@@ -180,6 +180,7 @@ const struct sof_intel_dsp_desc icl_chip_info = { ...@@ -180,6 +180,7 @@ const struct sof_intel_dsp_desc icl_chip_info = {
.ssp_base_offset = CNL_SSP_BASE_OFFSET, .ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
......
...@@ -684,6 +684,7 @@ const struct sof_intel_dsp_desc mtl_chip_info = { ...@@ -684,6 +684,7 @@ const struct sof_intel_dsp_desc mtl_chip_info = {
.ssp_base_offset = CNL_SSP_BASE_OFFSET, .ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE_ACE, .sdw_shim_base = SDW_SHIM_BASE_ACE,
.sdw_alh_base = SDW_ALH_BASE_ACE, .sdw_alh_base = SDW_ALH_BASE_ACE,
.d0i3_offset = MTL_HDA_VS_D0I3C,
.check_sdw_irq = mtl_dsp_check_sdw_irq, .check_sdw_irq = mtl_dsp_check_sdw_irq,
.check_ipc_irq = mtl_dsp_check_ipc_irq, .check_ipc_irq = mtl_dsp_check_ipc_irq,
.cl_init = mtl_dsp_cl_init, .cl_init = mtl_dsp_cl_init,
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#define MTL_IRQ_INTEN_L_SOUNDWIRE_MASK BIT(6) #define MTL_IRQ_INTEN_L_SOUNDWIRE_MASK BIT(6)
#define MTL_HFINTIPPTR_PTR_MASK GENMASK(20, 0) #define MTL_HFINTIPPTR_PTR_MASK GENMASK(20, 0)
#define MTL_HDA_VS_D0I3C 0x1D4A
#define MTL_DSP2CXCAP_PRIMARY_CORE 0x178D00 #define MTL_DSP2CXCAP_PRIMARY_CORE 0x178D00
#define MTL_DSP2CXCTL_PRIMARY_CORE 0x178D04 #define MTL_DSP2CXCTL_PRIMARY_CORE 0x178D04
#define MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK BIT(0) #define MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK BIT(0)
......
...@@ -182,6 +182,7 @@ struct sof_intel_dsp_desc { ...@@ -182,6 +182,7 @@ struct sof_intel_dsp_desc {
int ssp_base_offset; /* base address of the SSPs */ int ssp_base_offset; /* base address of the SSPs */
u32 sdw_shim_base; u32 sdw_shim_base;
u32 sdw_alh_base; u32 sdw_alh_base;
u32 d0i3_offset;
u32 quirks; u32 quirks;
enum sof_intel_hw_ip_version hw_ip_version; enum sof_intel_hw_ip_version hw_ip_version;
bool (*check_sdw_irq)(struct snd_sof_dev *sdev); bool (*check_sdw_irq)(struct snd_sof_dev *sdev);
......
...@@ -135,6 +135,7 @@ const struct sof_intel_dsp_desc tgl_chip_info = { ...@@ -135,6 +135,7 @@ const struct sof_intel_dsp_desc tgl_chip_info = {
.ssp_base_offset = CNL_SSP_BASE_OFFSET, .ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
...@@ -160,6 +161,7 @@ const struct sof_intel_dsp_desc tglh_chip_info = { ...@@ -160,6 +161,7 @@ const struct sof_intel_dsp_desc tglh_chip_info = {
.ssp_base_offset = CNL_SSP_BASE_OFFSET, .ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
...@@ -185,6 +187,7 @@ const struct sof_intel_dsp_desc ehl_chip_info = { ...@@ -185,6 +187,7 @@ const struct sof_intel_dsp_desc ehl_chip_info = {
.ssp_base_offset = CNL_SSP_BASE_OFFSET, .ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
...@@ -210,6 +213,7 @@ const struct sof_intel_dsp_desc adls_chip_info = { ...@@ -210,6 +213,7 @@ const struct sof_intel_dsp_desc adls_chip_info = {
.ssp_base_offset = CNL_SSP_BASE_OFFSET, .ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE, .sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE, .sdw_alh_base = SDW_ALH_BASE,
.d0i3_offset = SOF_HDA_VS_D0I3C,
.check_sdw_irq = hda_common_check_sdw_irq, .check_sdw_irq = hda_common_check_sdw_irq,
.check_ipc_irq = hda_dsp_check_ipc_irq, .check_ipc_irq = hda_dsp_check_ipc_irq,
.cl_init = cl_dsp_init, .cl_init = cl_dsp_init,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment