xref: /linux/drivers/net/wireless/ath/ath12k/wifi7/pci.c (revision 37a93dd5c49b5fda807fd204edf2547c3493319c)
1a7202704SKiran Venkatappa // SPDX-License-Identifier: BSD-3-Clause-Clear
2a7202704SKiran Venkatappa /*
3a7202704SKiran Venkatappa  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
4a7202704SKiran Venkatappa  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
5a7202704SKiran Venkatappa  */
6a7202704SKiran Venkatappa 
7a7202704SKiran Venkatappa #include <linux/pci.h>
8a7202704SKiran Venkatappa 
9a7202704SKiran Venkatappa #include "../pci.h"
10a7202704SKiran Venkatappa #include "pci.h"
11a7202704SKiran Venkatappa #include "../core.h"
12a7202704SKiran Venkatappa #include "../hif.h"
13a7202704SKiran Venkatappa #include "../mhi.h"
14a7202704SKiran Venkatappa #include "hw.h"
15bce3b73dSKiran Venkatappa #include "../hal.h"
16614c23e2SRipan Deuri #include "dp.h"
17614c23e2SRipan Deuri #include "core.h"
182bb41934SPavankumar Nandeshwar #include "hal.h"
19a7202704SKiran Venkatappa 
20a7202704SKiran Venkatappa #define QCN9274_DEVICE_ID		0x1109
21a7202704SKiran Venkatappa #define WCN7850_DEVICE_ID		0x1107
22*d8e1f4a1SBaochen Qiang #define QCC2072_DEVICE_ID		0x1112
23a7202704SKiran Venkatappa 
24a7202704SKiran Venkatappa #define ATH12K_PCI_W7_SOC_HW_VERSION_1	1
25a7202704SKiran Venkatappa #define ATH12K_PCI_W7_SOC_HW_VERSION_2	2
26a7202704SKiran Venkatappa 
27a7202704SKiran Venkatappa #define TCSR_SOC_HW_VERSION		0x1B00000
28a7202704SKiran Venkatappa #define TCSR_SOC_HW_VERSION_MAJOR_MASK	GENMASK(11, 8)
29a7202704SKiran Venkatappa #define TCSR_SOC_HW_VERSION_MINOR_MASK	GENMASK(7, 4)
30a7202704SKiran Venkatappa 
317a6b6386SBaochen Qiang #define WINDOW_REG_ADDRESS		0x310c
32*d8e1f4a1SBaochen Qiang #define WINDOW_REG_ADDRESS_QCC2072	0x3278
337a6b6386SBaochen Qiang 
34a7202704SKiran Venkatappa static const struct pci_device_id ath12k_wifi7_pci_id_table[] = {
35a7202704SKiran Venkatappa 	{ PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) },
36a7202704SKiran Venkatappa 	{ PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) },
37*d8e1f4a1SBaochen Qiang 	{ PCI_VDEVICE(QCOM, QCC2072_DEVICE_ID) },
38a7202704SKiran Venkatappa 	{}
39a7202704SKiran Venkatappa };
40a7202704SKiran Venkatappa 
41a7202704SKiran Venkatappa MODULE_DEVICE_TABLE(pci, ath12k_wifi7_pci_id_table);
42a7202704SKiran Venkatappa 
43a7202704SKiran Venkatappa /* TODO: revisit IRQ mapping for new SRNG's */
44a7202704SKiran Venkatappa static const struct ath12k_msi_config ath12k_wifi7_msi_config[] = {
45a7202704SKiran Venkatappa 	{
46a7202704SKiran Venkatappa 		.total_vectors = 16,
47a7202704SKiran Venkatappa 		.total_users = 3,
48a7202704SKiran Venkatappa 		.users = (struct ath12k_msi_user[]) {
49a7202704SKiran Venkatappa 			{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
50a7202704SKiran Venkatappa 			{ .name = "CE", .num_vectors = 5, .base_vector = 3 },
51a7202704SKiran Venkatappa 			{ .name = "DP", .num_vectors = 8, .base_vector = 8 },
52a7202704SKiran Venkatappa 		},
53a7202704SKiran Venkatappa 	},
54a7202704SKiran Venkatappa };
55a7202704SKiran Venkatappa 
56bce3b73dSKiran Venkatappa static const struct ath12k_pci_ops ath12k_wifi7_pci_ops_qcn9274 = {
57a7202704SKiran Venkatappa 	.wakeup = NULL,
58a7202704SKiran Venkatappa 	.release = NULL,
59a7202704SKiran Venkatappa };
60a7202704SKiran Venkatappa 
61a7202704SKiran Venkatappa static int ath12k_wifi7_pci_bus_wake_up(struct ath12k_base *ab)
62a7202704SKiran Venkatappa {
63a7202704SKiran Venkatappa 	struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
64a7202704SKiran Venkatappa 
65a7202704SKiran Venkatappa 	return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
66a7202704SKiran Venkatappa }
67a7202704SKiran Venkatappa 
68a7202704SKiran Venkatappa static void ath12k_wifi7_pci_bus_release(struct ath12k_base *ab)
69a7202704SKiran Venkatappa {
70a7202704SKiran Venkatappa 	struct ath12k_pci *ab_pci = ath12k_pci_priv(ab);
71a7202704SKiran Venkatappa 
72a7202704SKiran Venkatappa 	mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
73a7202704SKiran Venkatappa }
74a7202704SKiran Venkatappa 
75bce3b73dSKiran Venkatappa static const struct ath12k_pci_ops ath12k_wifi7_pci_ops_wcn7850 = {
76a7202704SKiran Venkatappa 	.wakeup = ath12k_wifi7_pci_bus_wake_up,
77a7202704SKiran Venkatappa 	.release = ath12k_wifi7_pci_bus_release,
78a7202704SKiran Venkatappa };
79a7202704SKiran Venkatappa 
80a7202704SKiran Venkatappa static
81a7202704SKiran Venkatappa void ath12k_wifi7_pci_read_hw_version(struct ath12k_base *ab,
82a7202704SKiran Venkatappa 				      u32 *major, u32 *minor)
83a7202704SKiran Venkatappa {
84a7202704SKiran Venkatappa 	u32 soc_hw_version;
85a7202704SKiran Venkatappa 
86a7202704SKiran Venkatappa 	soc_hw_version = ath12k_pci_read32(ab, TCSR_SOC_HW_VERSION);
87a7202704SKiran Venkatappa 	*major = u32_get_bits(soc_hw_version, TCSR_SOC_HW_VERSION_MAJOR_MASK);
88a7202704SKiran Venkatappa 	*minor = u32_get_bits(soc_hw_version, TCSR_SOC_HW_VERSION_MINOR_MASK);
89a7202704SKiran Venkatappa }
90a7202704SKiran Venkatappa 
91a7202704SKiran Venkatappa static int ath12k_wifi7_pci_probe(struct pci_dev *pdev,
92a7202704SKiran Venkatappa 				  const struct pci_device_id *pci_dev)
93a7202704SKiran Venkatappa {
94a7202704SKiran Venkatappa 	u32 soc_hw_version_major, soc_hw_version_minor;
95a7202704SKiran Venkatappa 	struct ath12k_pci *ab_pci;
96a7202704SKiran Venkatappa 	struct ath12k_base *ab;
97a7202704SKiran Venkatappa 	int ret;
98a7202704SKiran Venkatappa 
99a7202704SKiran Venkatappa 	ab = pci_get_drvdata(pdev);
100a7202704SKiran Venkatappa 	if (!ab)
101a7202704SKiran Venkatappa 		return -EINVAL;
102a7202704SKiran Venkatappa 
103a7202704SKiran Venkatappa 	ab_pci = ath12k_pci_priv(ab);
104a7202704SKiran Venkatappa 	if (!ab_pci)
105a7202704SKiran Venkatappa 		return -EINVAL;
106a7202704SKiran Venkatappa 
107a7202704SKiran Venkatappa 	switch (pci_dev->device) {
108a7202704SKiran Venkatappa 	case QCN9274_DEVICE_ID:
109a7202704SKiran Venkatappa 		ab_pci->msi_config = &ath12k_wifi7_msi_config[0];
110a7202704SKiran Venkatappa 		ab->static_window_map = true;
111bce3b73dSKiran Venkatappa 		ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274;
1127a6b6386SBaochen Qiang 		/*
1137a6b6386SBaochen Qiang 		 * init window reg addr before reading hardware version
1147a6b6386SBaochen Qiang 		 * as it will be used there
1157a6b6386SBaochen Qiang 		 */
1167a6b6386SBaochen Qiang 		ab_pci->window_reg_addr = WINDOW_REG_ADDRESS;
117a7202704SKiran Venkatappa 		ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major,
118a7202704SKiran Venkatappa 						 &soc_hw_version_minor);
119a7202704SKiran Venkatappa 		ab->target_mem_mode = ath12k_core_get_memory_mode(ab);
120a7202704SKiran Venkatappa 		switch (soc_hw_version_major) {
121a7202704SKiran Venkatappa 		case ATH12K_PCI_W7_SOC_HW_VERSION_2:
122a7202704SKiran Venkatappa 			ab->hw_rev = ATH12K_HW_QCN9274_HW20;
123a7202704SKiran Venkatappa 			break;
124a7202704SKiran Venkatappa 		case ATH12K_PCI_W7_SOC_HW_VERSION_1:
125a7202704SKiran Venkatappa 			ab->hw_rev = ATH12K_HW_QCN9274_HW10;
126a7202704SKiran Venkatappa 			break;
127a7202704SKiran Venkatappa 		default:
128a7202704SKiran Venkatappa 			dev_err(&pdev->dev,
129a7202704SKiran Venkatappa 				"Unknown hardware version found for QCN9274: 0x%x\n",
130a7202704SKiran Venkatappa 				soc_hw_version_major);
131a7202704SKiran Venkatappa 			return -EOPNOTSUPP;
132a7202704SKiran Venkatappa 		}
133a7202704SKiran Venkatappa 		break;
134a7202704SKiran Venkatappa 	case WCN7850_DEVICE_ID:
135a7202704SKiran Venkatappa 		ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD;
136a7202704SKiran Venkatappa 		ab_pci->msi_config = &ath12k_wifi7_msi_config[0];
137a7202704SKiran Venkatappa 		ab->static_window_map = false;
138bce3b73dSKiran Venkatappa 		ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850;
1397a6b6386SBaochen Qiang 		/*
1407a6b6386SBaochen Qiang 		 * init window reg addr before reading hardware version
1417a6b6386SBaochen Qiang 		 * as it will be used there
1427a6b6386SBaochen Qiang 		 */
1437a6b6386SBaochen Qiang 		ab_pci->window_reg_addr = WINDOW_REG_ADDRESS;
144a7202704SKiran Venkatappa 		ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major,
145a7202704SKiran Venkatappa 						 &soc_hw_version_minor);
146a7202704SKiran Venkatappa 		ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT;
147a7202704SKiran Venkatappa 		switch (soc_hw_version_major) {
148a7202704SKiran Venkatappa 		case ATH12K_PCI_W7_SOC_HW_VERSION_2:
149a7202704SKiran Venkatappa 			ab->hw_rev = ATH12K_HW_WCN7850_HW20;
150a7202704SKiran Venkatappa 			break;
151a7202704SKiran Venkatappa 		default:
152a7202704SKiran Venkatappa 			dev_err(&pdev->dev,
153a7202704SKiran Venkatappa 				"Unknown hardware version found for WCN7850: 0x%x\n",
154a7202704SKiran Venkatappa 				soc_hw_version_major);
155a7202704SKiran Venkatappa 			return -EOPNOTSUPP;
156a7202704SKiran Venkatappa 		}
157a7202704SKiran Venkatappa 		break;
158*d8e1f4a1SBaochen Qiang 	case QCC2072_DEVICE_ID:
159*d8e1f4a1SBaochen Qiang 		ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD;
160*d8e1f4a1SBaochen Qiang 		ab_pci->msi_config = &ath12k_wifi7_msi_config[0];
161*d8e1f4a1SBaochen Qiang 		ab->static_window_map = false;
162*d8e1f4a1SBaochen Qiang 		ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850;
163*d8e1f4a1SBaochen Qiang 		ab_pci->window_reg_addr = WINDOW_REG_ADDRESS_QCC2072;
164*d8e1f4a1SBaochen Qiang 		ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT;
165*d8e1f4a1SBaochen Qiang 		/* there is only one version till now */
166*d8e1f4a1SBaochen Qiang 		ab->hw_rev = ATH12K_HW_QCC2072_HW10;
167*d8e1f4a1SBaochen Qiang 		break;
168a7202704SKiran Venkatappa 	default:
169a7202704SKiran Venkatappa 		dev_err(&pdev->dev, "Unknown Wi-Fi 7 PCI device found: 0x%x\n",
170a7202704SKiran Venkatappa 			pci_dev->device);
171a7202704SKiran Venkatappa 		return -EOPNOTSUPP;
172a7202704SKiran Venkatappa 	}
173a7202704SKiran Venkatappa 
174a7202704SKiran Venkatappa 	ret = ath12k_wifi7_hw_init(ab);
175a7202704SKiran Venkatappa 	if (ret) {
176a7202704SKiran Venkatappa 		dev_err(&pdev->dev, "WiFi-7 hw_init for PCI failed: %d\n", ret);
177a7202704SKiran Venkatappa 		return ret;
178a7202704SKiran Venkatappa 	}
179a7202704SKiran Venkatappa 
180a7202704SKiran Venkatappa 	return 0;
181a7202704SKiran Venkatappa }
182a7202704SKiran Venkatappa 
1836cbd1718SKiran Venkatappa static const struct ath12k_pci_reg_base ath12k_wifi7_reg_base = {
1846cbd1718SKiran Venkatappa 	.umac_base = HAL_SEQ_WCSS_UMAC_OFFSET,
1856cbd1718SKiran Venkatappa 	.ce_reg_base = HAL_CE_WFSS_CE_REG_BASE,
1866cbd1718SKiran Venkatappa };
1876cbd1718SKiran Venkatappa 
188bce3b73dSKiran Venkatappa static struct ath12k_pci_driver ath12k_wifi7_pci_driver = {
189a7202704SKiran Venkatappa 	.name = "ath12k_wifi7_pci",
190a7202704SKiran Venkatappa 	.id_table = ath12k_wifi7_pci_id_table,
191a7202704SKiran Venkatappa 	.ops.probe = ath12k_wifi7_pci_probe,
1926cbd1718SKiran Venkatappa 	.reg_base = &ath12k_wifi7_reg_base,
193614c23e2SRipan Deuri 	.ops.arch_init = ath12k_wifi7_arch_init,
194614c23e2SRipan Deuri 	.ops.arch_deinit = ath12k_wifi7_arch_deinit,
195a7202704SKiran Venkatappa };
196a7202704SKiran Venkatappa 
197a7202704SKiran Venkatappa int ath12k_wifi7_pci_init(void)
198a7202704SKiran Venkatappa {
199a7202704SKiran Venkatappa 	int ret;
200a7202704SKiran Venkatappa 
201a7202704SKiran Venkatappa 	ret = ath12k_pci_register_driver(ATH12K_DEVICE_FAMILY_WIFI7,
202bce3b73dSKiran Venkatappa 					 &ath12k_wifi7_pci_driver);
203a7202704SKiran Venkatappa 	if (ret) {
204a7202704SKiran Venkatappa 		pr_err("Failed to register ath12k Wi-Fi 7 driver: %d\n",
205a7202704SKiran Venkatappa 		       ret);
206a7202704SKiran Venkatappa 		return ret;
207a7202704SKiran Venkatappa 	}
208a7202704SKiran Venkatappa 
209a7202704SKiran Venkatappa 	return 0;
210a7202704SKiran Venkatappa }
211a7202704SKiran Venkatappa 
212a7202704SKiran Venkatappa void ath12k_wifi7_pci_exit(void)
213a7202704SKiran Venkatappa {
214a7202704SKiran Venkatappa 	ath12k_pci_unregister_driver(ATH12K_DEVICE_FAMILY_WIFI7);
215a7202704SKiran Venkatappa }
216