1b5a2fdc5SVijendar Mukunda // SPDX-License-Identifier: GPL-2.0-only 2b5a2fdc5SVijendar Mukunda /* 3b5a2fdc5SVijendar Mukunda * AMD ACP PCI driver callback routines for ACP7.x 4b5a2fdc5SVijendar Mukunda * platforms. 5b5a2fdc5SVijendar Mukunda * 6b5a2fdc5SVijendar Mukunda * Copyright 2026 Advanced Micro Devices, Inc. 7b5a2fdc5SVijendar Mukunda */ 8b5a2fdc5SVijendar Mukunda 9b5a2fdc5SVijendar Mukunda #include <linux/device.h> 10b5a2fdc5SVijendar Mukunda #include <linux/io.h> 11b5a2fdc5SVijendar Mukunda #include <linux/iopoll.h> 12b5a2fdc5SVijendar Mukunda #include <linux/types.h> 13b5a2fdc5SVijendar Mukunda 14b5a2fdc5SVijendar Mukunda #include "acp7x.h" 15b5a2fdc5SVijendar Mukunda 16b5a2fdc5SVijendar Mukunda static int acp7x_power_on(void __iomem *acp_base) 17b5a2fdc5SVijendar Mukunda { 18b5a2fdc5SVijendar Mukunda u32 val = 0; 19b5a2fdc5SVijendar Mukunda 20b5a2fdc5SVijendar Mukunda val = readl(acp_base + ACP_PGFSM_STATUS); 21b5a2fdc5SVijendar Mukunda if (!(val & ACP7X_PGFSM_STATUS_MASK)) 22b5a2fdc5SVijendar Mukunda return 0; 23b5a2fdc5SVijendar Mukunda 24b5a2fdc5SVijendar Mukunda writel(ACP7X_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); 25b5a2fdc5SVijendar Mukunda val = readl(acp_base + ACP_PGFSM_CONTROL); 26b5a2fdc5SVijendar Mukunda return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, 27b5a2fdc5SVijendar Mukunda ((val & ACP7X_PGFSM_STATUS_MASK) == 0), DELAY_US, ACP7X_TIMEOUT); 28b5a2fdc5SVijendar Mukunda } 29b5a2fdc5SVijendar Mukunda 30b5a2fdc5SVijendar Mukunda static int acp7x_reset(void __iomem *acp_base) 31b5a2fdc5SVijendar Mukunda { 32b5a2fdc5SVijendar Mukunda u32 val; 33b5a2fdc5SVijendar Mukunda int ret; 34b5a2fdc5SVijendar Mukunda 35b5a2fdc5SVijendar Mukunda writel(1, acp_base + ACP_SOFT_RESET); 36b5a2fdc5SVijendar Mukunda ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, 37b5a2fdc5SVijendar Mukunda val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, 38b5a2fdc5SVijendar Mukunda DELAY_US, ACP7X_TIMEOUT); 39b5a2fdc5SVijendar Mukunda if (ret) 40b5a2fdc5SVijendar Mukunda return ret; 41b5a2fdc5SVijendar Mukunda 42b5a2fdc5SVijendar Mukunda writel(0, acp_base + ACP_SOFT_RESET); 43b5a2fdc5SVijendar Mukunda return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP7X_TIMEOUT); 44b5a2fdc5SVijendar Mukunda } 45b5a2fdc5SVijendar Mukunda 46b5a2fdc5SVijendar Mukunda static int acp7x_init(void __iomem *acp_base, struct device *dev) 47b5a2fdc5SVijendar Mukunda { 48b5a2fdc5SVijendar Mukunda int ret; 49b5a2fdc5SVijendar Mukunda 50b5a2fdc5SVijendar Mukunda ret = acp7x_power_on(acp_base); 51b5a2fdc5SVijendar Mukunda if (ret) { 52b5a2fdc5SVijendar Mukunda dev_err(dev, "ACP power on failed\n"); 53b5a2fdc5SVijendar Mukunda return ret; 54b5a2fdc5SVijendar Mukunda } 55b5a2fdc5SVijendar Mukunda writel(0x01, acp_base + ACP_CONTROL); 56b5a2fdc5SVijendar Mukunda ret = acp7x_reset(acp_base); 57b5a2fdc5SVijendar Mukunda if (ret) { 58b5a2fdc5SVijendar Mukunda dev_err(dev, "ACP reset failed\n"); 59b5a2fdc5SVijendar Mukunda return ret; 60b5a2fdc5SVijendar Mukunda } 61b5a2fdc5SVijendar Mukunda writel(0, acp_base + ACP_ZSC_DSP_CTRL); 62b5a2fdc5SVijendar Mukunda return 0; 63b5a2fdc5SVijendar Mukunda } 64b5a2fdc5SVijendar Mukunda 65b5a2fdc5SVijendar Mukunda static int acp7x_deinit(void __iomem *acp_base, struct device *dev) 66b5a2fdc5SVijendar Mukunda { 67b5a2fdc5SVijendar Mukunda int ret; 68b5a2fdc5SVijendar Mukunda 69b5a2fdc5SVijendar Mukunda ret = acp7x_reset(acp_base); 70b5a2fdc5SVijendar Mukunda if (ret) { 71b5a2fdc5SVijendar Mukunda dev_err(dev, "ACP reset failed\n"); 72b5a2fdc5SVijendar Mukunda return ret; 73b5a2fdc5SVijendar Mukunda } 74b5a2fdc5SVijendar Mukunda writel(0x01, acp_base + ACP_ZSC_DSP_CTRL); 75b5a2fdc5SVijendar Mukunda return 0; 76b5a2fdc5SVijendar Mukunda } 77b5a2fdc5SVijendar Mukunda 78*07d56a83SVijendar Mukunda static int __maybe_unused snd_acp7x_suspend(struct device *dev) 79*07d56a83SVijendar Mukunda { 80*07d56a83SVijendar Mukunda struct acp7x_dev_data *adata; 81*07d56a83SVijendar Mukunda int ret; 82*07d56a83SVijendar Mukunda 83*07d56a83SVijendar Mukunda adata = dev_get_drvdata(dev); 84*07d56a83SVijendar Mukunda ret = acp_hw_deinit(adata, dev); 85*07d56a83SVijendar Mukunda if (ret) 86*07d56a83SVijendar Mukunda dev_err(dev, "ACP de-init failed\n"); 87*07d56a83SVijendar Mukunda return ret; 88*07d56a83SVijendar Mukunda } 89*07d56a83SVijendar Mukunda 90*07d56a83SVijendar Mukunda static int __maybe_unused snd_acp7x_runtime_resume(struct device *dev) 91*07d56a83SVijendar Mukunda { 92*07d56a83SVijendar Mukunda struct acp7x_dev_data *adata; 93*07d56a83SVijendar Mukunda int ret; 94*07d56a83SVijendar Mukunda 95*07d56a83SVijendar Mukunda adata = dev_get_drvdata(dev); 96*07d56a83SVijendar Mukunda ret = acp_hw_init(adata, dev); 97*07d56a83SVijendar Mukunda if (ret) { 98*07d56a83SVijendar Mukunda dev_err(dev, "ACP init failed\n"); 99*07d56a83SVijendar Mukunda return ret; 100*07d56a83SVijendar Mukunda } 101*07d56a83SVijendar Mukunda return 0; 102*07d56a83SVijendar Mukunda } 103*07d56a83SVijendar Mukunda 104*07d56a83SVijendar Mukunda static int __maybe_unused snd_acp7x_resume(struct device *dev) 105*07d56a83SVijendar Mukunda { 106*07d56a83SVijendar Mukunda struct acp7x_dev_data *adata; 107*07d56a83SVijendar Mukunda int ret; 108*07d56a83SVijendar Mukunda 109*07d56a83SVijendar Mukunda adata = dev_get_drvdata(dev); 110*07d56a83SVijendar Mukunda ret = acp_hw_init(adata, dev); 111*07d56a83SVijendar Mukunda if (ret) 112*07d56a83SVijendar Mukunda dev_err(dev, "ACP init failed\n"); 113*07d56a83SVijendar Mukunda 114*07d56a83SVijendar Mukunda return ret; 115*07d56a83SVijendar Mukunda } 116*07d56a83SVijendar Mukunda 117b5a2fdc5SVijendar Mukunda void acp7x_hw_init_ops(struct acp_hw_ops *hw_ops) 118b5a2fdc5SVijendar Mukunda { 119b5a2fdc5SVijendar Mukunda hw_ops->acp_init = acp7x_init; 120b5a2fdc5SVijendar Mukunda hw_ops->acp_deinit = acp7x_deinit; 121*07d56a83SVijendar Mukunda hw_ops->acp_suspend = snd_acp7x_suspend; 122*07d56a83SVijendar Mukunda hw_ops->acp_resume = snd_acp7x_resume; 123*07d56a83SVijendar Mukunda hw_ops->acp_suspend_runtime = snd_acp7x_suspend; 124*07d56a83SVijendar Mukunda hw_ops->acp_resume_runtime = snd_acp7x_runtime_resume; 125b5a2fdc5SVijendar Mukunda } 126