xref: /openbmc/linux/sound/soc/sof/amd/pci-rn.c (revision ec25a3b1)
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