1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * AMD Pink Sardine ACP PCI Driver 4 * 5 * Copyright 2022 Advanced Micro Devices, Inc. 6 */ 7 8 #include <linux/pci.h> 9 #include <linux/module.h> 10 #include <linux/io.h> 11 #include <linux/delay.h> 12 #include <linux/platform_device.h> 13 #include <linux/acpi.h> 14 #include <linux/interrupt.h> 15 #include <sound/pcm_params.h> 16 #include <linux/pm_runtime.h> 17 18 #include "acp63.h" 19 20 static int acp63_power_on(void __iomem *acp_base) 21 { 22 u32 val; 23 int timeout; 24 25 val = acp63_readl(acp_base + ACP_PGFSM_STATUS); 26 27 if (!val) 28 return val; 29 30 if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS) 31 acp63_writel(ACP_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); 32 timeout = 0; 33 while (++timeout < 500) { 34 val = acp63_readl(acp_base + ACP_PGFSM_STATUS); 35 if (!val) 36 return 0; 37 udelay(1); 38 } 39 return -ETIMEDOUT; 40 } 41 42 static int acp63_reset(void __iomem *acp_base) 43 { 44 u32 val; 45 int timeout; 46 47 acp63_writel(1, acp_base + ACP_SOFT_RESET); 48 timeout = 0; 49 while (++timeout < 500) { 50 val = acp63_readl(acp_base + ACP_SOFT_RESET); 51 if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK) 52 break; 53 cpu_relax(); 54 } 55 acp63_writel(0, acp_base + ACP_SOFT_RESET); 56 timeout = 0; 57 while (++timeout < 500) { 58 val = acp63_readl(acp_base + ACP_SOFT_RESET); 59 if (!val) 60 return 0; 61 cpu_relax(); 62 } 63 return -ETIMEDOUT; 64 } 65 66 static void acp63_enable_interrupts(void __iomem *acp_base) 67 { 68 acp63_writel(1, acp_base + ACP_EXTERNAL_INTR_ENB); 69 } 70 71 static void acp63_disable_interrupts(void __iomem *acp_base) 72 { 73 acp63_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + 74 ACP_EXTERNAL_INTR_STAT); 75 acp63_writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL); 76 acp63_writel(0, acp_base + ACP_EXTERNAL_INTR_ENB); 77 } 78 79 static int acp63_init(void __iomem *acp_base, struct device *dev) 80 { 81 int ret; 82 83 ret = acp63_power_on(acp_base); 84 if (ret) { 85 dev_err(dev, "ACP power on failed\n"); 86 return ret; 87 } 88 acp63_writel(0x01, acp_base + ACP_CONTROL); 89 ret = acp63_reset(acp_base); 90 if (ret) { 91 dev_err(dev, "ACP reset failed\n"); 92 return ret; 93 } 94 acp63_writel(0x03, acp_base + ACP_CLKMUX_SEL); 95 acp63_enable_interrupts(acp_base); 96 return 0; 97 } 98 99 static int acp63_deinit(void __iomem *acp_base, struct device *dev) 100 { 101 int ret; 102 103 acp63_disable_interrupts(acp_base); 104 ret = acp63_reset(acp_base); 105 if (ret) { 106 dev_err(dev, "ACP reset failed\n"); 107 return ret; 108 } 109 acp63_writel(0, acp_base + ACP_CLKMUX_SEL); 110 acp63_writel(0, acp_base + ACP_CONTROL); 111 return 0; 112 } 113 114 static irqreturn_t acp63_irq_handler(int irq, void *dev_id) 115 { 116 struct acp63_dev_data *adata; 117 struct pdm_dev_data *ps_pdm_data; 118 u32 val; 119 u16 pdev_index; 120 121 adata = dev_id; 122 if (!adata) 123 return IRQ_NONE; 124 125 val = acp63_readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT); 126 if (val & BIT(PDM_DMA_STAT)) { 127 pdev_index = adata->pdm_dev_index; 128 ps_pdm_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev); 129 acp63_writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); 130 if (ps_pdm_data->capture_stream) 131 snd_pcm_period_elapsed(ps_pdm_data->capture_stream); 132 return IRQ_HANDLED; 133 } 134 return IRQ_NONE; 135 } 136 137 static void get_acp63_device_config(u32 config, struct pci_dev *pci, 138 struct acp63_dev_data *acp_data) 139 { 140 struct acpi_device *dmic_dev; 141 const union acpi_object *obj; 142 bool is_dmic_dev = false; 143 144 dmic_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0); 145 if (dmic_dev) { 146 if (!acpi_dev_get_property(dmic_dev, "acp-audio-device-type", 147 ACPI_TYPE_INTEGER, &obj) && 148 obj->integer.value == ACP_DMIC_DEV) 149 is_dmic_dev = true; 150 } 151 152 switch (config) { 153 case ACP_CONFIG_0: 154 case ACP_CONFIG_1: 155 case ACP_CONFIG_2: 156 case ACP_CONFIG_3: 157 case ACP_CONFIG_9: 158 case ACP_CONFIG_15: 159 dev_dbg(&pci->dev, "Audio Mode %d\n", config); 160 break; 161 default: 162 if (is_dmic_dev) { 163 acp_data->pdev_mask = ACP63_PDM_DEV_MASK; 164 acp_data->pdev_count = ACP63_PDM_MODE_DEVS; 165 } 166 break; 167 } 168 } 169 170 static void acp63_fill_platform_dev_info(struct platform_device_info *pdevinfo, 171 struct device *parent, 172 struct fwnode_handle *fw_node, 173 char *name, unsigned int id, 174 const struct resource *res, 175 unsigned int num_res, 176 const void *data, 177 size_t size_data) 178 { 179 pdevinfo->name = name; 180 pdevinfo->id = id; 181 pdevinfo->parent = parent; 182 pdevinfo->num_res = num_res; 183 pdevinfo->res = res; 184 pdevinfo->data = data; 185 pdevinfo->size_data = size_data; 186 pdevinfo->fwnode = fw_node; 187 } 188 189 static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data *adata, u32 addr) 190 { 191 struct platform_device_info pdevinfo[ACP63_DEVS]; 192 struct device *parent; 193 int index; 194 int ret; 195 196 parent = &pci->dev; 197 dev_dbg(&pci->dev, 198 "%s pdev_mask:0x%x pdev_count:0x%x\n", __func__, adata->pdev_mask, 199 adata->pdev_count); 200 if (adata->pdev_mask) { 201 adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL); 202 if (!adata->res) { 203 ret = -ENOMEM; 204 goto de_init; 205 } 206 adata->res->flags = IORESOURCE_MEM; 207 adata->res->start = addr; 208 adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START); 209 memset(&pdevinfo, 0, sizeof(pdevinfo)); 210 } 211 212 switch (adata->pdev_mask) { 213 case ACP63_PDM_DEV_MASK: 214 adata->pdm_dev_index = 0; 215 acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma", 216 0, adata->res, 1, &adata->acp_lock, 217 sizeof(adata->acp_lock)); 218 acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "dmic-codec", 219 0, NULL, 0, NULL, 0); 220 acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "acp_ps_mach", 221 0, NULL, 0, NULL, 0); 222 break; 223 default: 224 dev_dbg(&pci->dev, "No PDM devices found\n"); 225 return 0; 226 } 227 228 for (index = 0; index < adata->pdev_count; index++) { 229 adata->pdev[index] = platform_device_register_full(&pdevinfo[index]); 230 if (IS_ERR(adata->pdev[index])) { 231 dev_err(&pci->dev, 232 "cannot register %s device\n", pdevinfo[index].name); 233 ret = PTR_ERR(adata->pdev[index]); 234 goto unregister_devs; 235 } 236 } 237 return 0; 238 unregister_devs: 239 for (--index; index >= 0; index--) 240 platform_device_unregister(adata->pdev[index]); 241 de_init: 242 if (acp63_deinit(adata->acp63_base, &pci->dev)) 243 dev_err(&pci->dev, "ACP de-init failed\n"); 244 return ret; 245 } 246 247 static int snd_acp63_probe(struct pci_dev *pci, 248 const struct pci_device_id *pci_id) 249 { 250 struct acp63_dev_data *adata; 251 u32 addr; 252 u32 irqflags; 253 int val; 254 int ret; 255 256 irqflags = IRQF_SHARED; 257 /* Pink Sardine device check */ 258 switch (pci->revision) { 259 case 0x63: 260 break; 261 default: 262 dev_dbg(&pci->dev, "acp63 pci device not found\n"); 263 return -ENODEV; 264 } 265 if (pci_enable_device(pci)) { 266 dev_err(&pci->dev, "pci_enable_device failed\n"); 267 return -ENODEV; 268 } 269 270 ret = pci_request_regions(pci, "AMD ACP6.2 audio"); 271 if (ret < 0) { 272 dev_err(&pci->dev, "pci_request_regions failed\n"); 273 goto disable_pci; 274 } 275 adata = devm_kzalloc(&pci->dev, sizeof(struct acp63_dev_data), 276 GFP_KERNEL); 277 if (!adata) { 278 ret = -ENOMEM; 279 goto release_regions; 280 } 281 282 addr = pci_resource_start(pci, 0); 283 adata->acp63_base = devm_ioremap(&pci->dev, addr, 284 pci_resource_len(pci, 0)); 285 if (!adata->acp63_base) { 286 ret = -ENOMEM; 287 goto release_regions; 288 } 289 pci_set_master(pci); 290 pci_set_drvdata(pci, adata); 291 mutex_init(&adata->acp_lock); 292 ret = acp63_init(adata->acp63_base, &pci->dev); 293 if (ret) 294 goto release_regions; 295 ret = devm_request_irq(&pci->dev, pci->irq, acp63_irq_handler, 296 irqflags, "ACP_PCI_IRQ", adata); 297 if (ret) { 298 dev_err(&pci->dev, "ACP PCI IRQ request failed\n"); 299 goto de_init; 300 } 301 val = acp63_readl(adata->acp63_base + ACP_PIN_CONFIG); 302 get_acp63_device_config(val, pci, adata); 303 ret = create_acp63_platform_devs(pci, adata, addr); 304 if (ret < 0) { 305 dev_err(&pci->dev, "ACP platform devices creation failed\n"); 306 goto de_init; 307 } 308 pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS); 309 pm_runtime_use_autosuspend(&pci->dev); 310 pm_runtime_put_noidle(&pci->dev); 311 pm_runtime_allow(&pci->dev); 312 return 0; 313 de_init: 314 if (acp63_deinit(adata->acp63_base, &pci->dev)) 315 dev_err(&pci->dev, "ACP de-init failed\n"); 316 release_regions: 317 pci_release_regions(pci); 318 disable_pci: 319 pci_disable_device(pci); 320 321 return ret; 322 } 323 324 static int __maybe_unused snd_acp63_suspend(struct device *dev) 325 { 326 struct acp63_dev_data *adata; 327 int ret; 328 329 adata = dev_get_drvdata(dev); 330 ret = acp63_deinit(adata->acp63_base, dev); 331 if (ret) 332 dev_err(dev, "ACP de-init failed\n"); 333 return ret; 334 } 335 336 static int __maybe_unused snd_acp63_resume(struct device *dev) 337 { 338 struct acp63_dev_data *adata; 339 int ret; 340 341 adata = dev_get_drvdata(dev); 342 ret = acp63_init(adata->acp63_base, dev); 343 if (ret) 344 dev_err(dev, "ACP init failed\n"); 345 return ret; 346 } 347 348 static const struct dev_pm_ops acp63_pm_ops = { 349 SET_RUNTIME_PM_OPS(snd_acp63_suspend, snd_acp63_resume, NULL) 350 SET_SYSTEM_SLEEP_PM_OPS(snd_acp63_suspend, snd_acp63_resume) 351 }; 352 353 static void snd_acp63_remove(struct pci_dev *pci) 354 { 355 struct acp63_dev_data *adata; 356 int ret, index; 357 358 adata = pci_get_drvdata(pci); 359 for (index = 0; index < adata->pdev_count; index++) 360 platform_device_unregister(adata->pdev[index]); 361 ret = acp63_deinit(adata->acp63_base, &pci->dev); 362 if (ret) 363 dev_err(&pci->dev, "ACP de-init failed\n"); 364 pm_runtime_forbid(&pci->dev); 365 pm_runtime_get_noresume(&pci->dev); 366 pci_release_regions(pci); 367 pci_disable_device(pci); 368 } 369 370 static const struct pci_device_id snd_acp63_ids[] = { 371 { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID), 372 .class = PCI_CLASS_MULTIMEDIA_OTHER << 8, 373 .class_mask = 0xffffff }, 374 { 0, }, 375 }; 376 MODULE_DEVICE_TABLE(pci, snd_acp63_ids); 377 378 static struct pci_driver ps_acp63_driver = { 379 .name = KBUILD_MODNAME, 380 .id_table = snd_acp63_ids, 381 .probe = snd_acp63_probe, 382 .remove = snd_acp63_remove, 383 .driver = { 384 .pm = &acp63_pm_ops, 385 } 386 }; 387 388 module_pci_driver(ps_acp63_driver); 389 390 MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); 391 MODULE_AUTHOR("Syed.SabaKareem@amd.com"); 392 MODULE_DESCRIPTION("AMD ACP Pink Sardine PCI driver"); 393 MODULE_LICENSE("GPL v2"); 394