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