Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Adjust all AMD audio drivers to use AMD_NODE

Merge series from Mario Limonciello <superm1@kernel.org>:

The various AMD audio drivers have self contained implementations
for SMN router communication that require hardcoding the bridge ID.

These implementations also don't prevent race conditions with other
drivers performing SMN communication.

A new centralized driver AMD_NODE is introduced and all drivers in
the kernel should use this instead. Adjust all AMD audio drivers to
use it.

+273 -165
+1 -1
arch/x86/entry/common.c
··· 142 142 #ifdef CONFIG_IA32_EMULATION 143 143 bool __ia32_enabled __ro_after_init = !IS_ENABLED(CONFIG_IA32_EMULATION_DEFAULT_DISABLED); 144 144 145 - static int ia32_emulation_override_cmdline(char *arg) 145 + static int __init ia32_emulation_override_cmdline(char *arg) 146 146 { 147 147 return kstrtobool(arg, &__ia32_enabled); 148 148 }
-1
arch/x86/include/asm/amd_nb.h
··· 27 27 }; 28 28 29 29 struct amd_northbridge { 30 - struct pci_dev *root; 31 30 struct pci_dev *misc; 32 31 struct pci_dev *link; 33 32 struct amd_l3_cache l3_cache;
+24
arch/x86/include/asm/amd_node.h
··· 30 30 return topology_amd_nodes_per_pkg() * topology_max_packages(); 31 31 } 32 32 33 + #ifdef CONFIG_AMD_NODE 33 34 int __must_check amd_smn_read(u16 node, u32 address, u32 *value); 34 35 int __must_check amd_smn_write(u16 node, u32 address, u32 value); 35 36 37 + /* Should only be used by the HSMP driver. */ 38 + int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write); 39 + #else 40 + static inline int __must_check amd_smn_read(u16 node, u32 address, u32 *value) { return -ENODEV; } 41 + static inline int __must_check amd_smn_write(u16 node, u32 address, u32 value) { return -ENODEV; } 42 + 43 + static inline int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write) 44 + { 45 + return -ENODEV; 46 + } 47 + #endif /* CONFIG_AMD_NODE */ 48 + 49 + /* helper for use with read_poll_timeout */ 50 + static inline int smn_read_register(u32 reg) 51 + { 52 + int data, rc; 53 + 54 + rc = amd_smn_read(0, reg, &data); 55 + if (rc) 56 + return rc; 57 + 58 + return data; 59 + } 36 60 #endif /*_ASM_X86_AMD_NODE_H_*/
-1
arch/x86/kernel/amd_nb.c
··· 73 73 amd_northbridges.nb = nb; 74 74 75 75 for (i = 0; i < amd_northbridges.num; i++) { 76 - node_to_amd_nb(i)->root = amd_node_get_root(i); 77 76 node_to_amd_nb(i)->misc = amd_node_get_func(i, 3); 78 77 79 78 /*
+149
arch/x86/kernel/amd_node.c
··· 8 8 * Author: Yazen Ghannam <Yazen.Ghannam@amd.com> 9 9 */ 10 10 11 + #include <linux/debugfs.h> 11 12 #include <asm/amd_node.h> 12 13 13 14 /* ··· 94 93 95 94 /* Protect the PCI config register pairs used for SMN. */ 96 95 static DEFINE_MUTEX(smn_mutex); 96 + static bool smn_exclusive; 97 97 98 98 #define SMN_INDEX_OFFSET 0x60 99 99 #define SMN_DATA_OFFSET 0x64 100 + 101 + #define HSMP_INDEX_OFFSET 0xc4 102 + #define HSMP_DATA_OFFSET 0xc8 100 103 101 104 /* 102 105 * SMN accesses may fail in ways that are difficult to detect here in the called ··· 151 146 if (!root) 152 147 return err; 153 148 149 + if (!smn_exclusive) 150 + return err; 151 + 154 152 guard(mutex)(&smn_mutex); 155 153 156 154 err = pci_write_config_dword(root, i_off, address); ··· 187 179 } 188 180 EXPORT_SYMBOL_GPL(amd_smn_write); 189 181 182 + int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write) 183 + { 184 + return __amd_smn_rw(HSMP_INDEX_OFFSET, HSMP_DATA_OFFSET, node, address, value, write); 185 + } 186 + EXPORT_SYMBOL_GPL(amd_smn_hsmp_rdwr); 187 + 188 + static struct dentry *debugfs_dir; 189 + static u16 debug_node; 190 + static u32 debug_address; 191 + 192 + static ssize_t smn_node_write(struct file *file, const char __user *userbuf, 193 + size_t count, loff_t *ppos) 194 + { 195 + u16 node; 196 + int ret; 197 + 198 + ret = kstrtou16_from_user(userbuf, count, 0, &node); 199 + if (ret) 200 + return ret; 201 + 202 + if (node >= amd_num_nodes()) 203 + return -ENODEV; 204 + 205 + debug_node = node; 206 + return count; 207 + } 208 + 209 + static int smn_node_show(struct seq_file *m, void *v) 210 + { 211 + seq_printf(m, "0x%08x\n", debug_node); 212 + return 0; 213 + } 214 + 215 + static ssize_t smn_address_write(struct file *file, const char __user *userbuf, 216 + size_t count, loff_t *ppos) 217 + { 218 + int ret; 219 + 220 + ret = kstrtouint_from_user(userbuf, count, 0, &debug_address); 221 + if (ret) 222 + return ret; 223 + 224 + return count; 225 + } 226 + 227 + static int smn_address_show(struct seq_file *m, void *v) 228 + { 229 + seq_printf(m, "0x%08x\n", debug_address); 230 + return 0; 231 + } 232 + 233 + static int smn_value_show(struct seq_file *m, void *v) 234 + { 235 + u32 val; 236 + int ret; 237 + 238 + ret = amd_smn_read(debug_node, debug_address, &val); 239 + if (ret) 240 + return ret; 241 + 242 + seq_printf(m, "0x%08x\n", val); 243 + return 0; 244 + } 245 + 246 + static ssize_t smn_value_write(struct file *file, const char __user *userbuf, 247 + size_t count, loff_t *ppos) 248 + { 249 + u32 val; 250 + int ret; 251 + 252 + ret = kstrtouint_from_user(userbuf, count, 0, &val); 253 + if (ret) 254 + return ret; 255 + 256 + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); 257 + 258 + ret = amd_smn_write(debug_node, debug_address, val); 259 + if (ret) 260 + return ret; 261 + 262 + return count; 263 + } 264 + 265 + DEFINE_SHOW_STORE_ATTRIBUTE(smn_node); 266 + DEFINE_SHOW_STORE_ATTRIBUTE(smn_address); 267 + DEFINE_SHOW_STORE_ATTRIBUTE(smn_value); 268 + 190 269 static int amd_cache_roots(void) 191 270 { 192 271 u16 node, num_nodes = amd_num_nodes(); ··· 287 192 288 193 return 0; 289 194 } 195 + 196 + static int reserve_root_config_spaces(void) 197 + { 198 + struct pci_dev *root = NULL; 199 + struct pci_bus *bus = NULL; 200 + 201 + while ((bus = pci_find_next_bus(bus))) { 202 + /* Root device is Device 0 Function 0 on each Primary Bus. */ 203 + root = pci_get_slot(bus, 0); 204 + if (!root) 205 + continue; 206 + 207 + if (root->vendor != PCI_VENDOR_ID_AMD && 208 + root->vendor != PCI_VENDOR_ID_HYGON) 209 + continue; 210 + 211 + pci_dbg(root, "Reserving PCI config space\n"); 212 + 213 + /* 214 + * There are a few SMN index/data pairs and other registers 215 + * that shouldn't be accessed by user space. 216 + * So reserve the entire PCI config space for simplicity rather 217 + * than covering specific registers piecemeal. 218 + */ 219 + if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) { 220 + pci_err(root, "Failed to reserve config space\n"); 221 + return -EEXIST; 222 + } 223 + } 224 + 225 + smn_exclusive = true; 226 + return 0; 227 + } 228 + 229 + static bool enable_dfs; 230 + 231 + static int __init amd_smn_enable_dfs(char *str) 232 + { 233 + enable_dfs = true; 234 + return 1; 235 + } 236 + __setup("amd_smn_debugfs_enable", amd_smn_enable_dfs); 290 237 291 238 static int __init amd_smn_init(void) 292 239 { ··· 345 208 err = amd_cache_roots(); 346 209 if (err) 347 210 return err; 211 + 212 + err = reserve_root_config_spaces(); 213 + if (err) 214 + return err; 215 + 216 + if (enable_dfs) { 217 + debugfs_dir = debugfs_create_dir("amd_smn", arch_debugfs_dir); 218 + 219 + debugfs_create_file("node", 0600, debugfs_dir, NULL, &smn_node_fops); 220 + debugfs_create_file("address", 0600, debugfs_dir, NULL, &smn_address_fops); 221 + debugfs_create_file("value", 0600, debugfs_dir, NULL, &smn_value_fops); 222 + } 348 223 349 224 return 0; 350 225 }
+7 -6
arch/x86/kernel/cpu/mtrr/generic.c
··· 9 9 #include <linux/io.h> 10 10 #include <linux/mm.h> 11 11 #include <linux/cc_platform.h> 12 + #include <linux/string_choices.h> 12 13 #include <asm/processor-flags.h> 13 14 #include <asm/cacheinfo.h> 14 15 #include <asm/cpufeature.h> ··· 647 646 pr_info("MTRR default type: %s\n", 648 647 mtrr_attrib_to_str(mtrr_state.def_type)); 649 648 if (mtrr_state.have_fixed) { 650 - pr_info("MTRR fixed ranges %sabled:\n", 651 - ((mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED) && 652 - (mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED)) ? 653 - "en" : "dis"); 649 + pr_info("MTRR fixed ranges %s:\n", 650 + str_enabled_disabled( 651 + (mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED) && 652 + (mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED))); 654 653 print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); 655 654 for (i = 0; i < 2; ++i) 656 655 print_fixed(0x80000 + i * 0x20000, 0x04000, ··· 662 661 /* tail */ 663 662 print_fixed_last(); 664 663 } 665 - pr_info("MTRR variable ranges %sabled:\n", 666 - mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED ? "en" : "dis"); 664 + pr_info("MTRR variable ranges %s:\n", 665 + str_enabled_disabled(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED)); 667 666 high_width = (boot_cpu_data.x86_phys_bits - (32 - PAGE_SHIFT) + 3) / 4; 668 667 669 668 for (i = 0; i < num_var_ranges; ++i) {
+1 -1
drivers/platform/x86/amd/hsmp/Kconfig
··· 7 7 tristate 8 8 9 9 menu "AMD HSMP Driver" 10 - depends on AMD_NB || COMPILE_TEST 10 + depends on AMD_NODE || COMPILE_TEST 11 11 12 12 config AMD_HSMP_ACPI 13 13 tristate "AMD HSMP ACPI device driver"
+4 -3
drivers/platform/x86/amd/hsmp/acpi.c
··· 10 10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 11 12 12 #include <asm/amd_hsmp.h> 13 - #include <asm/amd_nb.h> 14 13 15 14 #include <linux/acpi.h> 16 15 #include <linux/device.h> ··· 22 23 #include <linux/uuid.h> 23 24 24 25 #include <uapi/asm-generic/errno-base.h> 26 + 27 + #include <asm/amd_node.h> 25 28 26 29 #include "hsmp.h" 27 30 ··· 322 321 return -ENOMEM; 323 322 324 323 if (!hsmp_pdev->is_probed) { 325 - hsmp_pdev->num_sockets = amd_nb_num(); 326 - if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_SOCKETS) 324 + hsmp_pdev->num_sockets = amd_num_nodes(); 325 + if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_NUM_NODES) 327 326 return -ENODEV; 328 327 329 328 hsmp_pdev->sock = devm_kcalloc(&pdev->dev, hsmp_pdev->num_sockets,
-1
drivers/platform/x86/amd/hsmp/hsmp.c
··· 8 8 */ 9 9 10 10 #include <asm/amd_hsmp.h> 11 - #include <asm/amd_nb.h> 12 11 13 12 #include <linux/acpi.h> 14 13 #include <linux/delay.h>
-3
drivers/platform/x86/amd/hsmp/hsmp.h
··· 21 21 22 22 #define HSMP_ATTR_GRP_NAME_SIZE 10 23 23 24 - #define MAX_AMD_SOCKETS 8 25 - 26 24 #define HSMP_CDEV_NAME "hsmp_cdev" 27 25 #define HSMP_DEVNODE_NAME "hsmp" 28 26 ··· 39 41 void __iomem *virt_base_addr; 40 42 struct semaphore hsmp_sem; 41 43 char name[HSMP_ATTR_GRP_NAME_SIZE]; 42 - struct pci_dev *root; 43 44 struct device *dev; 44 45 u16 sock_ind; 45 46 int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool rw);
+12 -24
drivers/platform/x86/amd/hsmp/plat.c
··· 10 10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 11 12 12 #include <asm/amd_hsmp.h> 13 - #include <asm/amd_nb.h> 14 13 14 + #include <linux/build_bug.h> 15 15 #include <linux/device.h> 16 16 #include <linux/module.h> 17 17 #include <linux/pci.h> 18 18 #include <linux/platform_device.h> 19 19 #include <linux/sysfs.h> 20 + 21 + #include <asm/amd_node.h> 20 22 21 23 #include "hsmp.h" 22 24 ··· 36 34 #define SMN_HSMP_MSG_RESP 0x0010980 37 35 #define SMN_HSMP_MSG_DATA 0x00109E0 38 36 39 - #define HSMP_INDEX_REG 0xc4 40 - #define HSMP_DATA_REG 0xc8 41 - 42 37 static struct hsmp_plat_device *hsmp_pdev; 43 38 44 39 static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset, 45 40 u32 *value, bool write) 46 41 { 47 - int ret; 48 - 49 - if (!sock->root) 50 - return -ENODEV; 51 - 52 - ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG, 53 - sock->mbinfo.base_addr + offset); 54 - if (ret) 55 - return ret; 56 - 57 - ret = (write ? pci_write_config_dword(sock->root, HSMP_DATA_REG, *value) 58 - : pci_read_config_dword(sock->root, HSMP_DATA_REG, value)); 59 - 60 - return ret; 42 + return amd_smn_hsmp_rdwr(sock->sock_ind, sock->mbinfo.base_addr + offset, value, write); 61 43 } 62 44 63 45 static ssize_t hsmp_metric_tbl_plat_read(struct file *filp, struct kobject *kobj, ··· 81 95 * Static array of 8 + 1(for NULL) elements is created below 82 96 * to create sysfs groups for sockets. 83 97 * is_bin_visible function is used to show / hide the necessary groups. 98 + * 99 + * Validate the maximum number against MAX_AMD_NUM_NODES. If this changes, 100 + * then the attributes and groups below must be adjusted. 84 101 */ 102 + static_assert(MAX_AMD_NUM_NODES == 8); 103 + 85 104 #define HSMP_BIN_ATTR(index, _list) \ 86 105 static const struct bin_attribute attr##index = { \ 87 106 .attr = { .name = HSMP_METRICS_TABLE_NAME, .mode = 0444}, \ ··· 150 159 int ret, i; 151 160 152 161 for (i = 0; i < hsmp_pdev->num_sockets; i++) { 153 - if (!node_to_amd_nb(i)) 154 - return -ENODEV; 155 162 sock = &hsmp_pdev->sock[i]; 156 - sock->root = node_to_amd_nb(i)->root; 157 163 sock->sock_ind = i; 158 164 sock->dev = dev; 159 165 sock->mbinfo.base_addr = SMN_HSMP_BASE; ··· 293 305 return -ENOMEM; 294 306 295 307 /* 296 - * amd_nb_num() returns number of SMN/DF interfaces present in the system 308 + * amd_num_nodes() returns number of SMN/DF interfaces present in the system 297 309 * if we have N SMN/DF interfaces that ideally means N sockets 298 310 */ 299 - hsmp_pdev->num_sockets = amd_nb_num(); 300 - if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_SOCKETS) 311 + hsmp_pdev->num_sockets = amd_num_nodes(); 312 + if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_NUM_NODES) 301 313 return ret; 302 314 303 315 ret = platform_driver_register(&amd_hsmp_driver);
+3
sound/soc/amd/acp/Kconfig
··· 58 58 select SND_SOC_AMD_ACP_I2S 59 59 select SND_SOC_AMD_ACP_PDM 60 60 select SND_SOC_AMD_ACP_LEGACY_COMMON 61 + depends on AMD_NODE 61 62 depends on X86 && PCI 62 63 help 63 64 This option enables Rembrandt I2S support on AMD platform. ··· 69 68 tristate "AMD ACP ASOC ACP6.3 Support" 70 69 depends on X86 && PCI 71 70 depends on ACPI 71 + depends on AMD_NODE 72 72 select SND_SOC_AMD_ACP_PCM 73 73 select SND_SOC_AMD_ACP_I2S 74 74 select SND_SOC_AMD_ACP_PDM ··· 83 81 tristate "AMD ACP ASOC Acp7.0 Support" 84 82 depends on X86 && PCI 85 83 depends on ACPI 84 + depends on AMD_NODE 86 85 select SND_SOC_AMD_ACP_PCM 87 86 select SND_SOC_AMD_ACP_I2S 88 87 select SND_SOC_AMD_ACP_PDM
-18
sound/soc/amd/acp/acp-legacy-common.c
··· 345 345 } 346 346 EXPORT_SYMBOL_NS_GPL(acp_deinit, "SND_SOC_ACP_COMMON"); 347 347 348 - int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data) 349 - { 350 - pci_write_config_dword(dev, 0x60, smn_addr); 351 - pci_write_config_dword(dev, 0x64, data); 352 - return 0; 353 - } 354 - EXPORT_SYMBOL_NS_GPL(smn_write, "SND_SOC_ACP_COMMON"); 355 - 356 - int smn_read(struct pci_dev *dev, u32 smn_addr) 357 - { 358 - u32 data; 359 - 360 - pci_write_config_dword(dev, 0x60, smn_addr); 361 - pci_read_config_dword(dev, 0x64, &data); 362 - return data; 363 - } 364 - EXPORT_SYMBOL_NS_GPL(smn_read, "SND_SOC_ACP_COMMON"); 365 - 366 348 static void check_acp3x_config(struct acp_chip_info *chip) 367 349 { 368 350 u32 val;
+14 -14
sound/soc/amd/acp/acp-rembrandt.c
··· 22 22 #include <linux/pci.h> 23 23 #include <linux/pm_runtime.h> 24 24 25 + #include <asm/amd_node.h> 26 + 25 27 #include "amd.h" 26 28 #include "../mach-config.h" 27 29 #include "acp-mach.h" ··· 33 31 #define MP1_C2PMSG_69 0x3B10A14 34 32 #define MP1_C2PMSG_85 0x3B10A54 35 33 #define MP1_C2PMSG_93 0x3B10A74 36 - #define HOST_BRIDGE_ID 0x14B5 37 34 38 35 static struct acp_resource rsrc = { 39 36 .offset = 0, ··· 167 166 168 167 static int acp6x_master_clock_generate(struct device *dev) 169 168 { 170 - int data = 0; 171 - struct pci_dev *smn_dev; 169 + int data, rc; 172 170 173 - smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, HOST_BRIDGE_ID, NULL); 174 - if (!smn_dev) { 175 - dev_err(dev, "Failed to get host bridge device\n"); 176 - return -ENODEV; 177 - } 171 + rc = amd_smn_write(0, MP1_C2PMSG_93, 0); 172 + if (rc) 173 + return rc; 174 + rc = amd_smn_write(0, MP1_C2PMSG_85, 0xC4); 175 + if (rc) 176 + return rc; 177 + rc = amd_smn_write(0, MP1_C2PMSG_69, 0x4); 178 + if (rc) 179 + return rc; 178 180 179 - smn_write(smn_dev, MP1_C2PMSG_93, 0); 180 - smn_write(smn_dev, MP1_C2PMSG_85, 0xC4); 181 - smn_write(smn_dev, MP1_C2PMSG_69, 0x4); 182 - read_poll_timeout(smn_read, data, data, DELAY_US, 183 - ACP_TIMEOUT, false, smn_dev, MP1_C2PMSG_93); 184 - return 0; 181 + return read_poll_timeout(smn_read_register, data, data > 0, DELAY_US, 182 + ACP_TIMEOUT, false, MP1_C2PMSG_93); 185 183 } 186 184 187 185 static int rembrandt_audio_probe(struct platform_device *pdev)
+37 -18
sound/soc/amd/acp/acp63.c
··· 20 20 #include <linux/dma-mapping.h> 21 21 #include <linux/pm_runtime.h> 22 22 #include <linux/pci.h> 23 + 24 + #include <asm/amd_node.h> 25 + 23 26 #include "amd.h" 24 27 #include "acp-mach.h" 25 28 #include "../mach-config.h" ··· 163 160 164 161 static int acp63_i2s_master_clock_generate(struct acp_dev_data *adata) 165 162 { 163 + int rc; 166 164 u32 data; 167 165 union clk_pll_req_no clk_pll; 168 - struct pci_dev *smn_dev; 169 - 170 - smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x14E8, NULL); 171 - if (!smn_dev) 172 - return -ENODEV; 173 166 174 167 /* Clk5 pll register values to get mclk as 196.6MHz*/ 175 168 clk_pll.bits.fb_mult_int = 0x31; 176 169 clk_pll.bits.pll_spine_div = 0; 177 170 clk_pll.bits.gb_mult_frac = 0x26E9; 178 171 179 - data = smn_read(smn_dev, CLK_PLL_PWR_REQ_N0); 180 - smn_write(smn_dev, CLK_PLL_PWR_REQ_N0, data | PLL_AUTO_STOP_REQ); 172 + rc = amd_smn_read(0, CLK_PLL_PWR_REQ_N0, &data); 173 + if (rc) 174 + return rc; 175 + rc = amd_smn_write(0, CLK_PLL_PWR_REQ_N0, data | PLL_AUTO_STOP_REQ); 176 + if (rc) 177 + return rc; 181 178 182 - data = smn_read(smn_dev, CLK_SPLL_FIELD_2_N0); 183 - if (data & PLL_FRANCE_EN) 184 - smn_write(smn_dev, CLK_SPLL_FIELD_2_N0, data | PLL_FRANCE_EN); 179 + rc = amd_smn_read(0, CLK_SPLL_FIELD_2_N0, &data); 180 + if (rc) 181 + return rc; 182 + if (data & PLL_FRANCE_EN) { 183 + rc = amd_smn_write(0, CLK_SPLL_FIELD_2_N0, data | PLL_FRANCE_EN); 184 + if (rc) 185 + return rc; 186 + } 185 187 186 - smn_write(smn_dev, CLK_PLL_REQ_N0, clk_pll.clk_pll_req_no_reg); 188 + rc = amd_smn_write(0, CLK_PLL_REQ_N0, clk_pll.clk_pll_req_no_reg); 189 + if (rc) 190 + return rc; 187 191 188 - data = smn_read(smn_dev, CLK_PLL_PWR_REQ_N0); 189 - smn_write(smn_dev, CLK_PLL_PWR_REQ_N0, data | PLL_AUTO_START_REQ); 192 + rc = amd_smn_read(0, CLK_PLL_PWR_REQ_N0, &data); 193 + if (rc) 194 + return rc; 195 + rc = amd_smn_write(0, CLK_PLL_PWR_REQ_N0, data | PLL_AUTO_START_REQ); 196 + if (rc) 197 + return rc; 190 198 191 - data = smn_read(smn_dev, CLK_DFSBYPASS_CONTR); 192 - smn_write(smn_dev, CLK_DFSBYPASS_CONTR, data | EXIT_DPF_BYPASS_0); 193 - smn_write(smn_dev, CLK_DFSBYPASS_CONTR, data | EXIT_DPF_BYPASS_1); 199 + rc = amd_smn_read(0, CLK_DFSBYPASS_CONTR, &data); 200 + if (rc) 201 + return rc; 202 + rc = amd_smn_write(0, CLK_DFSBYPASS_CONTR, data | EXIT_DPF_BYPASS_0); 203 + if (rc) 204 + return rc; 205 + rc = amd_smn_write(0, CLK_DFSBYPASS_CONTR, data | EXIT_DPF_BYPASS_1); 206 + if (rc) 207 + return rc; 194 208 195 - smn_write(smn_dev, CLK_DFS_CNTL_N0, CLK0_DIVIDER); 196 - return 0; 209 + return amd_smn_write(0, CLK_DFS_CNTL_N0, CLK0_DIVIDER); 197 210 } 198 211 199 212 static int acp63_audio_probe(struct platform_device *pdev)
+4 -24
sound/soc/amd/acp/acp70.c
··· 23 23 #include "amd.h" 24 24 #include "acp-mach.h" 25 25 26 + #include <asm/amd_node.h> 27 + 26 28 #define DRV_NAME "acp_asoc_acp70" 27 29 28 30 #define CLK7_CLK0_DFS_CNTL_N1 0X0006C1A4 ··· 139 137 }, 140 138 }; 141 139 142 - static int acp70_i2s_master_clock_generate(struct acp_dev_data *adata) 143 - { 144 - struct pci_dev *smn_dev; 145 - u32 device_id; 146 - 147 - if (adata->acp_rev == ACP70_PCI_ID) 148 - device_id = 0x1507; 149 - else if (adata->acp_rev == ACP71_PCI_ID) 150 - device_id = 0x1122; 151 - else 152 - return -ENODEV; 153 - 154 - smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, device_id, NULL); 155 - 156 - if (!smn_dev) 157 - return -ENODEV; 158 - 159 - /* Set clk7 DFS clock divider register value to get mclk as 196.608MHz*/ 160 - smn_write(smn_dev, CLK7_CLK0_DFS_CNTL_N1, CLK0_DIVIDER); 161 - 162 - return 0; 163 - } 164 - 165 140 static int acp_acp70_audio_probe(struct platform_device *pdev) 166 141 { 167 142 struct device *dev = &pdev->dev; ··· 194 215 195 216 dev_set_drvdata(dev, adata); 196 217 197 - ret = acp70_i2s_master_clock_generate(adata); 218 + /* Set clk7 DFS clock divider register value to get mclk as 196.608MHz*/ 219 + ret = amd_smn_write(0, CLK7_CLK0_DFS_CNTL_N1, CLK0_DIVIDER); 198 220 if (ret) { 199 221 dev_err(&pdev->dev, "Failed to set I2S master clock as 196.608MHz\n"); 200 222 return ret;
-3
sound/soc/amd/acp/amd.h
··· 235 235 236 236 int acp_machine_select(struct acp_dev_data *adata); 237 237 238 - int smn_read(struct pci_dev *dev, u32 smn_addr); 239 - int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data); 240 - 241 238 int acp_init(struct acp_chip_info *chip); 242 239 int acp_deinit(struct acp_chip_info *chip); 243 240 void acp_enable_interrupts(struct acp_dev_data *adata);
+1
sound/soc/sof/amd/Kconfig
··· 25 25 select SND_SOC_SOF_ACP_PROBES 26 26 select SND_SOC_ACPI_AMD_MATCH 27 27 select SND_SOC_ACPI if ACPI 28 + depends on AMD_NODE 28 29 help 29 30 This option is not user-selectable but automatically handled by 30 31 'select' statements at a higher level
+16 -40
sound/soc/sof/amd/acp.c
··· 16 16 #include <linux/module.h> 17 17 #include <linux/pci.h> 18 18 19 + #include <asm/amd_node.h> 20 + 19 21 #include "../ops.h" 20 22 #include "acp.h" 21 23 #include "acp-dsp-offset.h" ··· 43 41 {} 44 42 }; 45 43 EXPORT_SYMBOL_GPL(acp_sof_quirk_table); 46 - 47 - static int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data) 48 - { 49 - pci_write_config_dword(dev, 0x60, smn_addr); 50 - pci_write_config_dword(dev, 0x64, data); 51 - 52 - return 0; 53 - } 54 - 55 - static int smn_read(struct pci_dev *dev, u32 smn_addr) 56 - { 57 - u32 data = 0; 58 - 59 - pci_write_config_dword(dev, 0x60, smn_addr); 60 - pci_read_config_dword(dev, 0x64, &data); 61 - 62 - return data; 63 - } 64 44 65 45 static void init_dma_descriptor(struct acp_dev_data *adata) 66 46 { ··· 192 208 static int psp_mbox_ready(struct acp_dev_data *adata, bool ack) 193 209 { 194 210 struct snd_sof_dev *sdev = adata->dev; 195 - int ret; 196 - u32 data; 211 + int ret, data; 197 212 198 - ret = read_poll_timeout(smn_read, data, data & MBOX_READY_MASK, MBOX_DELAY_US, 199 - ACP_PSP_TIMEOUT_US, false, adata->smn_dev, MP0_C2PMSG_114_REG); 213 + ret = read_poll_timeout(smn_read_register, data, data > 0 && data & MBOX_READY_MASK, 214 + MBOX_DELAY_US, ACP_PSP_TIMEOUT_US, false, MP0_C2PMSG_114_REG); 215 + 200 216 if (!ret) 201 217 return 0; 202 218 ··· 224 240 return -EINVAL; 225 241 226 242 /* Get a non-zero Doorbell value from PSP */ 227 - ret = read_poll_timeout(smn_read, data, data, MBOX_DELAY_US, ACP_PSP_TIMEOUT_US, false, 228 - adata->smn_dev, MP0_C2PMSG_73_REG); 243 + ret = read_poll_timeout(smn_read_register, data, data > 0, MBOX_DELAY_US, 244 + ACP_PSP_TIMEOUT_US, false, MP0_C2PMSG_73_REG); 229 245 230 246 if (ret) { 231 247 dev_err(sdev->dev, "Failed to get Doorbell from MBOX %x\n", MP0_C2PMSG_73_REG); ··· 237 253 if (ret) 238 254 return ret; 239 255 240 - smn_write(adata->smn_dev, MP0_C2PMSG_114_REG, cmd); 256 + ret = amd_smn_write(0, MP0_C2PMSG_114_REG, cmd); 257 + if (ret) 258 + return ret; 241 259 242 260 /* Ring the Doorbell for PSP */ 243 - smn_write(adata->smn_dev, MP0_C2PMSG_73_REG, data); 261 + ret = amd_smn_write(0, MP0_C2PMSG_73_REG, data); 262 + if (ret) 263 + return ret; 244 264 245 265 /* Check MBOX ready as PSP ack */ 246 266 ret = psp_mbox_ready(adata, 1); ··· 758 770 adata->pci_rev = pci->revision; 759 771 mutex_init(&adata->acp_lock); 760 772 sdev->pdata->hw_pdata = adata; 761 - adata->smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, chip->host_bridge_id, NULL); 762 - if (!adata->smn_dev) { 763 - dev_err(sdev->dev, "Failed to get host bridge device\n"); 764 - ret = -ENODEV; 765 - goto unregister_dev; 766 - } 767 773 768 774 ret = acp_init(sdev); 769 775 if (ret < 0) 770 - goto free_smn_dev; 776 + goto unregister_dev; 771 777 772 778 sdev->ipc_irq = pci->irq; 773 779 ret = request_threaded_irq(sdev->ipc_irq, acp_irq_handler, acp_irq_thread, ··· 769 787 if (ret < 0) { 770 788 dev_err(sdev->dev, "failed to register IRQ %d\n", 771 789 sdev->ipc_irq); 772 - goto free_smn_dev; 790 + goto unregister_dev; 773 791 } 774 792 775 793 /* scan SoundWire capabilities exposed by DSDT */ ··· 782 800 if (ret < 0) { 783 801 dev_err(sdev->dev, "error: SoundWire probe error\n"); 784 802 free_irq(sdev->ipc_irq, sdev); 785 - pci_dev_put(adata->smn_dev); 786 803 return ret; 787 804 } 788 805 ··· 827 846 828 847 free_ipc_irq: 829 848 free_irq(sdev->ipc_irq, sdev); 830 - free_smn_dev: 831 - pci_dev_put(adata->smn_dev); 832 849 unregister_dev: 833 850 platform_device_unregister(adata->dmic_dev); 834 851 return ret; ··· 836 857 void amd_sof_acp_remove(struct snd_sof_dev *sdev) 837 858 { 838 859 struct acp_dev_data *adata = sdev->pdata->hw_pdata; 839 - 840 - if (adata->smn_dev) 841 - pci_dev_put(adata->smn_dev); 842 860 843 861 if (adata->sdw) 844 862 amd_sof_sdw_exit(sdev);
-2
sound/soc/sof/amd/acp.h
··· 197 197 198 198 struct sof_amd_acp_desc { 199 199 const char *name; 200 - unsigned int host_bridge_id; 201 200 u32 pgfsm_base; 202 201 u32 ext_intr_enb; 203 202 u32 ext_intr_cntl; ··· 254 255 struct dma_descriptor dscr_info[ACP_MAX_DESC]; 255 256 struct acp_dsp_stream stream_buf[ACP_MAX_STREAM]; 256 257 struct acp_dsp_stream *dtrace_stream; 257 - struct pci_dev *smn_dev; 258 258 struct acp_dsp_stream *probe_stream; 259 259 bool enable_fw_debug; 260 260 bool is_dram_in_use;
-1
sound/soc/sof/amd/pci-acp63.c
··· 28 28 #define ACP6x_REG_END 0x125C000 29 29 30 30 static const struct sof_amd_acp_desc acp63_chip_info = { 31 - .host_bridge_id = HOST_BRIDGE_ACP63, 32 31 .pgfsm_base = ACP6X_PGFSM_BASE, 33 32 .ext_intr_enb = ACP6X_EXTERNAL_INTR_ENB, 34 33 .ext_intr_cntl = ACP6X_EXTERNAL_INTR_CNTL,
-1
sound/soc/sof/amd/pci-acp70.c
··· 28 28 #define ACP70_REG_END 0x125C000 29 29 30 30 static const struct sof_amd_acp_desc acp70_chip_info = { 31 - .host_bridge_id = HOST_BRIDGE_ACP70, 32 31 .pgfsm_base = ACP70_PGFSM_BASE, 33 32 .ext_intr_enb = ACP70_EXTERNAL_INTR_ENB, 34 33 .ext_intr_cntl = ACP70_EXTERNAL_INTR_CNTL,
-1
sound/soc/sof/amd/pci-rmb.c
··· 28 28 #define ACP6X_FUTURE_REG_ACLK_0 0x1854 29 29 30 30 static const struct sof_amd_acp_desc rembrandt_chip_info = { 31 - .host_bridge_id = HOST_BRIDGE_RMB, 32 31 .pgfsm_base = ACP6X_PGFSM_BASE, 33 32 .ext_intr_stat = ACP6X_EXT_INTR_STAT, 34 33 .dsp_intr_base = ACP6X_DSP_SW_INTR_BASE,
-1
sound/soc/sof/amd/pci-rn.c
··· 28 28 #define ACP3X_FUTURE_REG_ACLK_0 0x1860 29 29 30 30 static const struct sof_amd_acp_desc renoir_chip_info = { 31 - .host_bridge_id = HOST_BRIDGE_CZN, 32 31 .pgfsm_base = ACP3X_PGFSM_BASE, 33 32 .ext_intr_stat = ACP3X_EXT_INTR_STAT, 34 33 .dsp_intr_base = ACP3X_DSP_SW_INTR_BASE,
-1
sound/soc/sof/amd/pci-vangogh.c
··· 27 27 28 28 static const struct sof_amd_acp_desc vangogh_chip_info = { 29 29 .name = "vangogh", 30 - .host_bridge_id = HOST_BRIDGE_VGH, 31 30 .pgfsm_base = ACP5X_PGFSM_BASE, 32 31 .ext_intr_stat = ACP5X_EXT_INTR_STAT, 33 32 .dsp_intr_base = ACP5X_DSP_SW_INTR_BASE,