Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: SOF: amd: Add Renoir PCI driver interface

Add PCI driver module to enable sof pci device support for Renoir.
If machine flag set to FLAG_SOF_ONLY_DMIC this pci driver register
platform device for non dsp based I2S platform device. If machine
flag is not enabled for SOF pci probe will return without invoking
sof device probe and registration

Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
Reviewed-by: Bard Liao <bard.liao@intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Link: https://lore.kernel.org/r/20211117093734.17407-10-daniel.baluta@oss.nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Ajit Kumar Pandey and committed by
Mark Brown
ec25a3b1 11ddd4e3

+168 -2
+4 -1
sound/soc/sof/amd/Kconfig
··· 17 17 config SND_SOC_SOF_AMD_COMMON 18 18 tristate 19 19 select SND_SOC_SOF 20 + select SND_SOC_SOF_PCI_DEV 21 + select SND_AMD_ACP_CONFIG 22 + select SND_SOC_ACPI if ACPI 20 23 help 21 24 This option is not user-selectable but automatically handled by 22 25 'select' statements at a higher level 23 26 24 27 config SND_SOC_SOF_AMD_RENOIR 25 28 tristate "SOF support for RENOIR" 29 + depends on SND_SOC_SOF_PCI 26 30 select SND_SOC_SOF_AMD_COMMON 27 31 help 28 32 Select this option for SOF support on AMD Renoir platform 29 - 30 33 endif
+1 -1
sound/soc/sof/amd/Makefile
··· 5 5 # Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved. 6 6 7 7 snd-sof-amd-acp-objs := acp.o acp-loader.o acp-ipc.o acp-pcm.o acp-stream.o 8 - snd-sof-amd-renoir-objs := renoir.o 8 + snd-sof-amd-renoir-objs := pci-rn.o renoir.o 9 9 10 10 obj-$(CONFIG_SND_SOC_SOF_AMD_COMMON) += snd-sof-amd-acp.o 11 11 obj-$(CONFIG_SND_SOC_SOF_AMD_RENOIR) +=snd-sof-amd-renoir.o
+3
sound/soc/sof/amd/acp.h
··· 194 194 struct snd_pcm_hw_params *params, struct sof_ipc_stream_params *ipc_params); 195 195 196 196 extern const struct snd_sof_dsp_ops sof_renoir_ops; 197 + 198 + /* Machine configuration */ 199 + int snd_amd_acp_find_config(struct pci_dev *pci); 197 200 #endif
+160
sound/soc/sof/amd/pci-rn.c
··· 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) 2021 Advanced Micro Devices, Inc. All rights reserved. 7 + // 8 + // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> 9 + 10 + /* 11 + * PCI interface for Renoir ACP device 12 + */ 13 + 14 + #include <linux/module.h> 15 + #include <linux/pci.h> 16 + #include <linux/platform_device.h> 17 + #include <sound/sof.h> 18 + #include <sound/soc-acpi.h> 19 + 20 + #include "../ops.h" 21 + #include "../sof-pci-dev.h" 22 + #include "../../amd/mach-config.h" 23 + #include "acp.h" 24 + 25 + #define ACP3x_REG_START 0x1240000 26 + #define ACP3x_REG_END 0x125C000 27 + 28 + static struct platform_device *dmic_dev; 29 + static struct platform_device *pdev; 30 + 31 + static const struct resource renoir_res[] = { 32 + { 33 + .start = 0, 34 + .end = ACP3x_REG_END - ACP3x_REG_START, 35 + .name = "acp_mem", 36 + .flags = IORESOURCE_MEM, 37 + }, 38 + { 39 + .start = 0, 40 + .end = 0, 41 + .name = "acp_dai_irq", 42 + .flags = IORESOURCE_IRQ, 43 + }, 44 + }; 45 + 46 + static const struct sof_dev_desc renoir_desc = { 47 + .machines = snd_soc_acpi_amd_sof_machines, 48 + .resindex_lpe_base = 0, 49 + .resindex_pcicfg_base = -1, 50 + .resindex_imr_base = -1, 51 + .irqindex_host_ipc = -1, 52 + .default_fw_path = "amd/sof", 53 + .default_tplg_path = "amd/sof-tplg", 54 + .default_fw_filename = "sof-rn.ri", 55 + .nocodec_tplg_filename = "sof-acp.tplg", 56 + .ops = &sof_renoir_ops, 57 + }; 58 + 59 + static int acp_pci_rn_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) 60 + { 61 + struct platform_device_info pdevinfo; 62 + struct device *dev = &pci->dev; 63 + const struct resource *res_i2s; 64 + struct resource *res; 65 + unsigned int flag, i, addr; 66 + int ret; 67 + 68 + flag = snd_amd_acp_find_config(pci); 69 + if (flag != FLAG_AMD_SOF && flag != FLAG_AMD_SOF_ONLY_DMIC) 70 + return -ENODEV; 71 + 72 + ret = sof_pci_probe(pci, pci_id); 73 + if (ret != 0) 74 + return ret; 75 + 76 + dmic_dev = platform_device_register_data(dev, "dmic-codec", PLATFORM_DEVID_NONE, NULL, 0); 77 + if (IS_ERR(dmic_dev)) { 78 + dev_err(dev, "failed to create DMIC device\n"); 79 + sof_pci_remove(pci); 80 + return PTR_ERR(dmic_dev); 81 + } 82 + 83 + /* Register platform device only if flag set to FLAG_AMD_SOF_ONLY_DMIC */ 84 + if (flag != FLAG_AMD_SOF_ONLY_DMIC) 85 + return 0; 86 + 87 + addr = pci_resource_start(pci, 0); 88 + res = devm_kzalloc(&pci->dev, sizeof(struct resource) * ARRAY_SIZE(renoir_res), GFP_KERNEL); 89 + if (!res) { 90 + sof_pci_remove(pci); 91 + return -ENOMEM; 92 + } 93 + 94 + res_i2s = renoir_res; 95 + for (i = 0; i < ARRAY_SIZE(renoir_res); i++, res_i2s++) { 96 + res[i].name = res_i2s->name; 97 + res[i].flags = res_i2s->flags; 98 + res[i].start = addr + res_i2s->start; 99 + res[i].end = addr + res_i2s->end; 100 + if (res_i2s->flags == IORESOURCE_IRQ) { 101 + res[i].start = pci->irq; 102 + res[i].end = res[i].start; 103 + } 104 + } 105 + 106 + memset(&pdevinfo, 0, sizeof(pdevinfo)); 107 + 108 + /* 109 + * We have common PCI driver probe for ACP device but we have to support I2S without SOF 110 + * for some distributions. Register platform device that will be used to support non dsp 111 + * ACP's audio ends points on some machines. 112 + */ 113 + 114 + pdevinfo.name = "acp_asoc_renoir"; 115 + pdevinfo.id = 0; 116 + pdevinfo.parent = &pci->dev; 117 + pdevinfo.num_res = ARRAY_SIZE(renoir_res); 118 + pdevinfo.res = &res[0]; 119 + 120 + pdev = platform_device_register_full(&pdevinfo); 121 + if (IS_ERR(pdev)) { 122 + dev_err(&pci->dev, "cannot register %s device\n", pdevinfo.name); 123 + sof_pci_remove(pci); 124 + platform_device_unregister(dmic_dev); 125 + ret = PTR_ERR(pdev); 126 + } 127 + 128 + return ret; 129 + }; 130 + 131 + static void acp_pci_rn_remove(struct pci_dev *pci) 132 + { 133 + if (dmic_dev) 134 + platform_device_unregister(dmic_dev); 135 + if (pdev) 136 + platform_device_unregister(pdev); 137 + 138 + return sof_pci_remove(pci); 139 + } 140 + 141 + /* PCI IDs */ 142 + static const struct pci_device_id rn_pci_ids[] = { 143 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_PCI_DEV_ID), 144 + .driver_data = (unsigned long)&renoir_desc}, 145 + { 0, } 146 + }; 147 + MODULE_DEVICE_TABLE(pci, rn_pci_ids); 148 + 149 + /* pci_driver definition */ 150 + static struct pci_driver snd_sof_pci_amd_rn_driver = { 151 + .name = KBUILD_MODNAME, 152 + .id_table = rn_pci_ids, 153 + .probe = acp_pci_rn_probe, 154 + .remove = acp_pci_rn_remove, 155 + }; 156 + module_pci_driver(snd_sof_pci_amd_rn_driver); 157 + 158 + MODULE_LICENSE("Dual BSD/GPL"); 159 + MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON); 160 + MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV);