1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * AMD ACP PCI driver callback routines for ACP6.3, ACP7.0 & ACP7.1 4 * platforms. 5 * 6 * Copyright 2025 Advanced Micro Devices, Inc. 7 * Authors: Vijendar Mukunda <Vijendar.Mukunda@amd.com> 8 */ 9 10 #include <linux/bitops.h> 11 #include <linux/delay.h> 12 #include <linux/export.h> 13 #include <linux/io.h> 14 #include <linux/iopoll.h> 15 #include <linux/pci.h> 16 #include <linux/platform_device.h> 17 #include <linux/pm_runtime.h> 18 #include <sound/pcm_params.h> 19 20 #include "acp63.h" 21 22 static int acp63_power_on(void __iomem *acp_base) 23 { 24 u32 val; 25 26 val = readl(acp_base + ACP_PGFSM_STATUS); 27 28 if (!val) 29 return val; 30 31 if ((val & ACP63_PGFSM_STATUS_MASK) != ACP63_POWER_ON_IN_PROGRESS) 32 writel(ACP63_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); 33 34 return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP63_TIMEOUT); 35 } 36 37 static int acp63_reset(void __iomem *acp_base) 38 { 39 u32 val; 40 int ret; 41 42 writel(1, acp_base + ACP_SOFT_RESET); 43 44 ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, 45 val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, 46 DELAY_US, ACP63_TIMEOUT); 47 if (ret) 48 return ret; 49 50 writel(0, acp_base + ACP_SOFT_RESET); 51 52 return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP63_TIMEOUT); 53 } 54 55 static void acp63_enable_interrupts(void __iomem *acp_base) 56 { 57 writel(1, acp_base + ACP_EXTERNAL_INTR_ENB); 58 writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL); 59 } 60 61 static void acp63_disable_interrupts(void __iomem *acp_base) 62 { 63 writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT); 64 writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL); 65 writel(0, acp_base + ACP_EXTERNAL_INTR_ENB); 66 } 67 68 static int acp63_init(void __iomem *acp_base, struct device *dev) 69 { 70 int ret; 71 72 ret = acp63_power_on(acp_base); 73 if (ret) { 74 dev_err(dev, "ACP power on failed\n"); 75 return ret; 76 } 77 writel(0x01, acp_base + ACP_CONTROL); 78 ret = acp63_reset(acp_base); 79 if (ret) { 80 dev_err(dev, "ACP reset failed\n"); 81 return ret; 82 } 83 acp63_enable_interrupts(acp_base); 84 writel(0, acp_base + ACP_ZSC_DSP_CTRL); 85 return 0; 86 } 87 88 static int acp63_deinit(void __iomem *acp_base, struct device *dev) 89 { 90 int ret; 91 92 acp63_disable_interrupts(acp_base); 93 ret = acp63_reset(acp_base); 94 if (ret) { 95 dev_err(dev, "ACP reset failed\n"); 96 return ret; 97 } 98 writel(0, acp_base + ACP_CONTROL); 99 writel(1, acp_base + ACP_ZSC_DSP_CTRL); 100 return 0; 101 } 102 103 static void acp63_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_data) 104 { 105 u32 config; 106 107 config = readl(acp_data->acp63_base + ACP_PIN_CONFIG); 108 dev_dbg(&pci->dev, "ACP config value: %d\n", config); 109 switch (config) { 110 case ACP_CONFIG_4: 111 case ACP_CONFIG_5: 112 case ACP_CONFIG_10: 113 case ACP_CONFIG_11: 114 acp_data->is_pdm_config = true; 115 break; 116 case ACP_CONFIG_2: 117 case ACP_CONFIG_3: 118 acp_data->is_sdw_config = true; 119 break; 120 case ACP_CONFIG_6: 121 case ACP_CONFIG_7: 122 case ACP_CONFIG_12: 123 case ACP_CONFIG_8: 124 case ACP_CONFIG_13: 125 case ACP_CONFIG_14: 126 acp_data->is_pdm_config = true; 127 acp_data->is_sdw_config = true; 128 break; 129 default: 130 break; 131 } 132 } 133 134 static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata) 135 { 136 u32 sdw0_en, sdw1_en; 137 138 sdw0_en = readl(adata->acp63_base + ACP_SW0_EN); 139 sdw1_en = readl(adata->acp63_base + ACP_SW1_EN); 140 return (sdw0_en || sdw1_en); 141 } 142 143 static void handle_acp63_sdw_pme_event(struct acp63_dev_data *adata) 144 { 145 u32 val; 146 147 val = readl(adata->acp63_base + ACP_SW0_WAKE_EN); 148 if (val && adata->sdw->pdev[0]) 149 pm_request_resume(&adata->sdw->pdev[0]->dev); 150 151 val = readl(adata->acp63_base + ACP_SW1_WAKE_EN); 152 if (val && adata->sdw->pdev[1]) 153 pm_request_resume(&adata->sdw->pdev[1]->dev); 154 } 155 156 static int __maybe_unused snd_acp63_suspend(struct device *dev) 157 { 158 struct acp63_dev_data *adata; 159 int ret; 160 161 adata = dev_get_drvdata(dev); 162 if (adata->is_sdw_dev) { 163 adata->acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); 164 adata->acp_pad_pulldown_ctrl = readl(adata->acp63_base + ACP_PAD_PULLDOWN_CTRL); 165 adata->sdw_en_stat = check_acp_sdw_enable_status(adata); 166 if (adata->sdw_en_stat) { 167 writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); 168 return 0; 169 } 170 } 171 ret = acp_hw_deinit(adata, dev); 172 if (ret) 173 dev_err(dev, "ACP de-init failed\n"); 174 175 return ret; 176 } 177 178 static int __maybe_unused snd_acp63_runtime_resume(struct device *dev) 179 { 180 struct acp63_dev_data *adata; 181 int ret; 182 183 adata = dev_get_drvdata(dev); 184 if (adata->sdw_en_stat) { 185 writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); 186 return 0; 187 } 188 ret = acp_hw_init(adata, dev); 189 if (ret) { 190 dev_err(dev, "ACP init failed\n"); 191 return ret; 192 } 193 194 if (!adata->sdw_en_stat) 195 handle_acp63_sdw_pme_event(adata); 196 return 0; 197 } 198 199 static int __maybe_unused snd_acp63_resume(struct device *dev) 200 { 201 struct acp63_dev_data *adata; 202 u32 acp_sw_pad_keeper_en; 203 int ret; 204 205 adata = dev_get_drvdata(dev); 206 if (adata->sdw_en_stat) { 207 writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); 208 return 0; 209 } 210 211 ret = acp_hw_init(adata, dev); 212 if (ret) 213 dev_err(dev, "ACP init failed\n"); 214 215 acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); 216 dev_dbg(dev, "ACP_SW0_PAD_KEEPER_EN:0x%x\n", acp_sw_pad_keeper_en); 217 if (!acp_sw_pad_keeper_en) { 218 writel(adata->acp_sw_pad_keeper_en, adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); 219 writel(adata->acp_pad_pulldown_ctrl, adata->acp63_base + ACP_PAD_PULLDOWN_CTRL); 220 } 221 return ret; 222 } 223 224 static void acp63_sdw_dma_irq_thread(struct acp63_dev_data *adata) 225 { 226 struct sdw_dma_dev_data *sdw_data; 227 u32 stream_id; 228 229 sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); 230 231 for (stream_id = 0; stream_id < ACP63_SDW0_DMA_MAX_STREAMS; stream_id++) { 232 if (adata->acp63_sdw0_dma_intr_stat[stream_id]) { 233 if (sdw_data->acp63_sdw0_dma_stream[stream_id]) 234 snd_pcm_period_elapsed(sdw_data->acp63_sdw0_dma_stream[stream_id]); 235 adata->acp63_sdw0_dma_intr_stat[stream_id] = 0; 236 } 237 } 238 for (stream_id = 0; stream_id < ACP63_SDW1_DMA_MAX_STREAMS; stream_id++) { 239 if (adata->acp63_sdw1_dma_intr_stat[stream_id]) { 240 if (sdw_data->acp63_sdw1_dma_stream[stream_id]) 241 snd_pcm_period_elapsed(sdw_data->acp63_sdw1_dma_stream[stream_id]); 242 adata->acp63_sdw1_dma_intr_stat[stream_id] = 0; 243 } 244 } 245 } 246 247 void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) 248 { 249 hw_ops->acp_init = acp63_init; 250 hw_ops->acp_deinit = acp63_deinit; 251 hw_ops->acp_get_config = acp63_get_config; 252 hw_ops->acp_sdw_dma_irq_thread = acp63_sdw_dma_irq_thread; 253 hw_ops->acp_suspend = snd_acp63_suspend; 254 hw_ops->acp_resume = snd_acp63_resume; 255 hw_ops->acp_suspend_runtime = snd_acp63_suspend; 256 hw_ops->acp_resume_runtime = snd_acp63_runtime_resume; 257 } 258 259 static int acp70_power_on(void __iomem *acp_base) 260 { 261 u32 val = 0; 262 263 val = readl(acp_base + ACP_PGFSM_STATUS); 264 265 if (!val) 266 return 0; 267 if (val & ACP70_PGFSM_STATUS_MASK) 268 writel(ACP70_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); 269 270 return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP70_TIMEOUT); 271 } 272 273 static int acp70_reset(void __iomem *acp_base) 274 { 275 u32 val; 276 int ret; 277 278 writel(1, acp_base + ACP_SOFT_RESET); 279 280 ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, 281 val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, 282 DELAY_US, ACP70_TIMEOUT); 283 if (ret) 284 return ret; 285 286 writel(0, acp_base + ACP_SOFT_RESET); 287 288 return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP70_TIMEOUT); 289 } 290 291 static void acp70_enable_sdw_host_wake_interrupts(void __iomem *acp_base) 292 { 293 u32 ext_intr_cntl1; 294 295 ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1); 296 ext_intr_cntl1 |= ACP70_SDW_HOST_WAKE_MASK; 297 writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1); 298 } 299 300 static void acp70_enable_interrupts(void __iomem *acp_base) 301 { 302 u32 sdw0_wake_en, sdw1_wake_en; 303 304 writel(1, acp_base + ACP_EXTERNAL_INTR_ENB); 305 writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL); 306 sdw0_wake_en = readl(acp_base + ACP_SW0_WAKE_EN); 307 sdw1_wake_en = readl(acp_base + ACP_SW1_WAKE_EN); 308 if (sdw0_wake_en || sdw1_wake_en) 309 acp70_enable_sdw_host_wake_interrupts(acp_base); 310 } 311 312 static void acp70_disable_interrupts(void __iomem *acp_base) 313 { 314 writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT); 315 writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL); 316 writel(0, acp_base + ACP_EXTERNAL_INTR_ENB); 317 } 318 319 static int acp70_init(void __iomem *acp_base, struct device *dev) 320 { 321 int ret; 322 323 ret = acp70_power_on(acp_base); 324 if (ret) { 325 dev_err(dev, "ACP power on failed\n"); 326 return ret; 327 } 328 writel(0x01, acp_base + ACP_CONTROL); 329 ret = acp70_reset(acp_base); 330 if (ret) { 331 dev_err(dev, "ACP reset failed\n"); 332 return ret; 333 } 334 writel(0, acp_base + ACP_ZSC_DSP_CTRL); 335 acp70_enable_interrupts(acp_base); 336 writel(0x1, acp_base + ACP_PME_EN); 337 return 0; 338 } 339 340 static int acp70_deinit(void __iomem *acp_base, struct device *dev) 341 { 342 int ret; 343 344 acp70_disable_interrupts(acp_base); 345 ret = acp70_reset(acp_base); 346 if (ret) { 347 dev_err(dev, "ACP reset failed\n"); 348 return ret; 349 } 350 writel(0x01, acp_base + ACP_ZSC_DSP_CTRL); 351 return 0; 352 } 353 354 static void acp70_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_data) 355 { 356 u32 config; 357 358 config = readl(acp_data->acp63_base + ACP_PIN_CONFIG); 359 dev_dbg(&pci->dev, "ACP config value: %d\n", config); 360 switch (config) { 361 case ACP_CONFIG_4: 362 case ACP_CONFIG_5: 363 case ACP_CONFIG_10: 364 case ACP_CONFIG_11: 365 case ACP_CONFIG_20: 366 acp_data->is_pdm_config = true; 367 break; 368 case ACP_CONFIG_2: 369 case ACP_CONFIG_3: 370 case ACP_CONFIG_16: 371 acp_data->is_sdw_config = true; 372 break; 373 case ACP_CONFIG_6: 374 case ACP_CONFIG_7: 375 case ACP_CONFIG_12: 376 case ACP_CONFIG_8: 377 case ACP_CONFIG_13: 378 case ACP_CONFIG_14: 379 case ACP_CONFIG_17: 380 case ACP_CONFIG_18: 381 case ACP_CONFIG_19: 382 acp_data->is_pdm_config = true; 383 acp_data->is_sdw_config = true; 384 break; 385 default: 386 break; 387 } 388 } 389 390 static void acp70_sdw_dma_irq_thread(struct acp63_dev_data *adata) 391 { 392 struct sdw_dma_dev_data *sdw_data; 393 u32 stream_id; 394 395 sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); 396 397 for (stream_id = 0; stream_id < ACP70_SDW0_DMA_MAX_STREAMS; stream_id++) { 398 if (adata->acp70_sdw0_dma_intr_stat[stream_id]) { 399 if (sdw_data->acp70_sdw0_dma_stream[stream_id]) 400 snd_pcm_period_elapsed(sdw_data->acp70_sdw0_dma_stream[stream_id]); 401 adata->acp70_sdw0_dma_intr_stat[stream_id] = 0; 402 } 403 } 404 for (stream_id = 0; stream_id < ACP70_SDW1_DMA_MAX_STREAMS; stream_id++) { 405 if (adata->acp70_sdw1_dma_intr_stat[stream_id]) { 406 if (sdw_data->acp70_sdw1_dma_stream[stream_id]) 407 snd_pcm_period_elapsed(sdw_data->acp70_sdw1_dma_stream[stream_id]); 408 adata->acp70_sdw1_dma_intr_stat[stream_id] = 0; 409 } 410 } 411 } 412 413 static int __maybe_unused snd_acp70_suspend(struct device *dev) 414 { 415 struct acp63_dev_data *adata; 416 int ret; 417 418 adata = dev_get_drvdata(dev); 419 if (adata->is_sdw_dev) { 420 adata->acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); 421 adata->acp_pad_pulldown_ctrl = readl(adata->acp63_base + ACP_PAD_PULLDOWN_CTRL); 422 adata->sdw_en_stat = check_acp_sdw_enable_status(adata); 423 if (adata->sdw_en_stat) { 424 writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); 425 return 0; 426 } 427 } 428 ret = acp_hw_deinit(adata, dev); 429 if (ret) 430 dev_err(dev, "ACP de-init failed\n"); 431 432 return ret; 433 } 434 435 static int __maybe_unused snd_acp70_runtime_resume(struct device *dev) 436 { 437 struct acp63_dev_data *adata; 438 int ret; 439 440 adata = dev_get_drvdata(dev); 441 442 if (adata->sdw_en_stat) { 443 writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); 444 writel(1, adata->acp63_base + ACP_PME_EN); 445 return 0; 446 } 447 448 ret = acp_hw_init(adata, dev); 449 if (ret) { 450 dev_err(dev, "ACP init failed\n"); 451 return ret; 452 } 453 return 0; 454 } 455 456 static int __maybe_unused snd_acp70_resume(struct device *dev) 457 { 458 struct acp63_dev_data *adata; 459 u32 acp_sw_pad_keeper_en; 460 int ret; 461 462 adata = dev_get_drvdata(dev); 463 464 if (adata->sdw_en_stat) { 465 writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); 466 writel(1, adata->acp63_base + ACP_PME_EN); 467 return 0; 468 } 469 470 ret = acp_hw_init(adata, dev); 471 if (ret) 472 dev_err(dev, "ACP init failed\n"); 473 474 acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); 475 dev_dbg(dev, "ACP_SW0_PAD_KEEPER_EN:0x%x\n", acp_sw_pad_keeper_en); 476 if (!acp_sw_pad_keeper_en) { 477 writel(adata->acp_sw_pad_keeper_en, adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); 478 writel(adata->acp_pad_pulldown_ctrl, adata->acp63_base + ACP_PAD_PULLDOWN_CTRL); 479 } 480 return ret; 481 } 482 483 void acp70_hw_init_ops(struct acp_hw_ops *hw_ops) 484 { 485 hw_ops->acp_init = acp70_init; 486 hw_ops->acp_deinit = acp70_deinit; 487 hw_ops->acp_get_config = acp70_get_config; 488 hw_ops->acp_sdw_dma_irq_thread = acp70_sdw_dma_irq_thread; 489 hw_ops->acp_suspend = snd_acp70_suspend; 490 hw_ops->acp_resume = snd_acp70_resume; 491 hw_ops->acp_suspend_runtime = snd_acp70_suspend; 492 hw_ops->acp_resume_runtime = snd_acp70_runtime_resume; 493 } 494