diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index d9b4b6a23f6021..85750054a5c90c 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -87,6 +87,15 @@ config SND_SOC_SOF_SKYLAKE Say Y if you have such a device. If unsure select "N". +config SND_SOC_SOF_ICELAKE + tristate "SOF support for Icelake" + select SND_SOC_SOF_HDA_COMMON + help + This adds support for Sound Open Firmware for Intel(R) platforms + using the Icelake processors. + Say Y if you have such a device. + If unsure select "N". + config SND_SOC_SOF_HDA_COMMON tristate select SND_SOC_SOF_PCI diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 4d6b42028d1ed7..a3a814a74742b1 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -72,6 +72,7 @@ void hda_dsp_block_write(struct snd_sof_dev *sdev, u32 offset, void *src, u32 tmp = 0; int i, m, n; const u8 *src_byte = src; + u8 *dst_byte; m = size / 4; n = size % 4; @@ -80,8 +81,16 @@ void hda_dsp_block_write(struct snd_sof_dev *sdev, u32 offset, void *src, __iowrite32_copy(dest, src, m); if (n) { + /* first read the 32bit data of dest, then change affected + * bytes, and write back to dest. For unaffected bytes, it + * should not be changed + */ + __ioread32_copy(&tmp, dest + m * 4, 1); + + dst_byte = (u8 *)&tmp; for (i = 0; i < n; i++) - tmp |= (u32)*(src_byte + m * 4 + i) << (i * 8); + dst_byte[i] = src_byte[m * 4 + i]; + __iowrite32_copy(dest + m * 4, &tmp, 1); } } @@ -283,6 +292,21 @@ static const struct sof_intel_dsp_desc chip_info[] = { .ipc_ctl = CNL_DSP_REG_HIPCCTL, .ops = &sof_cnl_ops, }, +{ + /* Icelake */ + .id = 0x34c8, + .cores_num = 4, + .cores_mask = HDA_DSP_CORE_MASK(0) | + HDA_DSP_CORE_MASK(1) | + HDA_DSP_CORE_MASK(2) | + HDA_DSP_CORE_MASK(3), + .ipc_req = CNL_DSP_REG_HIPCIDR, + .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY, + .ipc_ack = CNL_DSP_REG_HIPCIDA, + .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE, + .ipc_ctl = CNL_DSP_REG_HIPCCTL, + .ops = &sof_cnl_ops, +}, }; static const struct sof_intel_dsp_desc *get_chip_info(int pci_id) diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 152a3d36b69ad3..5445d8007afb77 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -114,6 +114,19 @@ static struct sof_dev_desc kbl_desc = { }; #endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) +static const struct sof_dev_desc icl_desc = { + .machines = snd_soc_acpi_intel_icl_machines, + .resindex_lpe_base = 0, + .resindex_pcicfg_base = -1, + .resindex_imr_base = -1, + .irqindex_host_ipc = -1, + .resindex_dma_base = -1, + .nocodec_fw_filename = "intel/sof-icl.ri", + .nocodec_tplg_filename = "intel/sof-icl-nocodec.tplg" +}; +#endif + static void sof_pci_fw_cb(const struct firmware *fw, void *context) { struct sof_platform_priv *priv = context; @@ -164,6 +177,9 @@ static const struct sof_ops_table mach_ops[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_KABYLAKE) {&kbl_desc, &sof_apl_ops}, #endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) + {&icl_desc, &sof_cnl_ops}, +#endif }; static struct snd_sof_dsp_ops *sof_pci_get_ops(const struct sof_dev_desc *d) @@ -336,6 +352,10 @@ static const struct pci_device_id sof_pci_ids[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_SKYLAKE) { PCI_DEVICE(0x8086, 0x9d70), .driver_data = (unsigned long)&skl_desc}, +#endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) + { PCI_DEVICE(0x8086, 0x34C8), + .driver_data = (unsigned long)&icl_desc}, #endif { 0, } };