blob: 90c8709181d190cfc5a9197003ea72836ee96777 [file] [log] [blame]
developerb11a5392022-03-31 00:34:47 +08001// SPDX-License-Identifier: ISC
2/* Copyright (C) 2020 MediaTek Inc.
3 *
4 * Author: Ryder Lee <ryder.lee@mediatek.com>
5 */
6
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/pci.h>
10
developer7800b8d2022-06-23 22:15:56 +080011#include "besra.h"
developerb11a5392022-03-31 00:34:47 +080012#include "mac.h"
13#include "../trace.h"
14
15static LIST_HEAD(hif_list);
16static DEFINE_SPINLOCK(hif_lock);
17static u32 hif_idx;
18
developer7800b8d2022-06-23 22:15:56 +080019static const struct pci_device_id besra_pci_device_table[] = {
developerb11a5392022-03-31 00:34:47 +080020 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7902) }, //bellwether
21 { },
22};
23
developer7800b8d2022-06-23 22:15:56 +080024static const struct pci_device_id besra_hif_device_table[] = {
developerb11a5392022-03-31 00:34:47 +080025 { },
26};
27
developer7800b8d2022-06-23 22:15:56 +080028static struct besra_hif *besra_pci_get_hif2(u32 idx)
developerb11a5392022-03-31 00:34:47 +080029{
developer7800b8d2022-06-23 22:15:56 +080030 struct besra_hif *hif;
developerb11a5392022-03-31 00:34:47 +080031 u32 val;
32
33 spin_lock_bh(&hif_lock);
34
35 list_for_each_entry(hif, &hif_list, list) {
36 val = readl(hif->regs + MT_PCIE_RECOG_ID);
37 val &= MT_PCIE_RECOG_ID_MASK;
38 if (val != idx)
39 continue;
40
41 get_device(hif->dev);
42 goto out;
43 }
44 hif = NULL;
45
46out:
47 spin_unlock_bh(&hif_lock);
48
49 return hif;
50}
51
developer7800b8d2022-06-23 22:15:56 +080052static void besra_put_hif2(struct besra_hif *hif)
developerb11a5392022-03-31 00:34:47 +080053{
54 if (!hif)
55 return;
56
57 put_device(hif->dev);
58}
59
developer7800b8d2022-06-23 22:15:56 +080060static struct besra_hif *besra_pci_init_hif2(struct pci_dev *pdev)
developerb11a5392022-03-31 00:34:47 +080061{
62 hif_idx++;
63 if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL) &&
64 !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, NULL))
65 return NULL;
66
67 writel(hif_idx | MT_PCIE_RECOG_ID_SEM,
68 pcim_iomap_table(pdev)[0] + MT_PCIE_RECOG_ID);
69
developer7800b8d2022-06-23 22:15:56 +080070 return besra_pci_get_hif2(hif_idx);
developerb11a5392022-03-31 00:34:47 +080071}
72
developer7800b8d2022-06-23 22:15:56 +080073static int besra_pci_hif2_probe(struct pci_dev *pdev)
developerb11a5392022-03-31 00:34:47 +080074{
developer7800b8d2022-06-23 22:15:56 +080075 struct besra_hif *hif;
developerb11a5392022-03-31 00:34:47 +080076
77 hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL);
78 if (!hif)
79 return -ENOMEM;
80
81 hif->dev = &pdev->dev;
82 hif->regs = pcim_iomap_table(pdev)[0];
83 hif->irq = pdev->irq;
84 spin_lock_bh(&hif_lock);
85 list_add(&hif->list, &hif_list);
86 spin_unlock_bh(&hif_lock);
87 pci_set_drvdata(pdev, hif);
88
89 return 0;
90}
91
developer7800b8d2022-06-23 22:15:56 +080092static int besra_pci_probe(struct pci_dev *pdev,
developerb11a5392022-03-31 00:34:47 +080093 const struct pci_device_id *id)
94{
developer7800b8d2022-06-23 22:15:56 +080095 struct besra_dev *dev;
developerb11a5392022-03-31 00:34:47 +080096 struct mt76_dev *mdev;
developer7800b8d2022-06-23 22:15:56 +080097 struct besra_hif *hif2;
developerb11a5392022-03-31 00:34:47 +080098 int irq;
99 int ret;
100
101 ret = pcim_enable_device(pdev);
102 if (ret)
103 return ret;
104
105 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
106 if (ret)
107 return ret;
108
109 pci_set_master(pdev);
110
111 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
112 if (ret)
113 return ret;
114
115 mt76_pci_disable_aspm(pdev);
116
117 if (id->device == 0x790a)
developer7800b8d2022-06-23 22:15:56 +0800118 return besra_pci_hif2_probe(pdev);
developerb11a5392022-03-31 00:34:47 +0800119
developer7800b8d2022-06-23 22:15:56 +0800120 dev = besra_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],
developerb11a5392022-03-31 00:34:47 +0800121 id->device);
122 if (IS_ERR(dev))
123 return PTR_ERR(dev);
124
125 mdev = &dev->mt76;
developer7800b8d2022-06-23 22:15:56 +0800126 besra_wfsys_reset(dev);
127 hif2 = besra_pci_init_hif2(pdev);
developerb11a5392022-03-31 00:34:47 +0800128
129 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
130 if (ret < 0)
131 goto free_device;
132
133 irq = pdev->irq;
developer7800b8d2022-06-23 22:15:56 +0800134 ret = devm_request_irq(mdev->dev, irq, besra_irq_handler,
developerb11a5392022-03-31 00:34:47 +0800135 IRQF_SHARED, KBUILD_MODNAME, dev);
136 if (ret)
137 goto free_irq_vector;
138
139 mt76_wr(dev, MT_INT_MASK_CSR, 0);
140
141 /* master switch of PCIe tnterrupt enable */
142 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
143
144 if (hif2) {
145 dev->hif2 = hif2;
146
147 mt76_wr(dev, MT_INT1_MASK_CSR, 0);
148 /* master switch of PCIe tnterrupt enable */
149 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
150
151 ret = devm_request_irq(mdev->dev, dev->hif2->irq,
developer7800b8d2022-06-23 22:15:56 +0800152 besra_irq_handler, IRQF_SHARED,
developerb11a5392022-03-31 00:34:47 +0800153 KBUILD_MODNAME "-hif", dev);
154 if (ret)
155 goto free_hif2;
156 }
157
developer7800b8d2022-06-23 22:15:56 +0800158 ret = besra_register_device(dev);
developerb11a5392022-03-31 00:34:47 +0800159 if (ret)
160 goto free_hif2_irq;
161
162 return 0;
163
164free_hif2_irq:
165 if (dev->hif2)
166 devm_free_irq(mdev->dev, dev->hif2->irq, dev);
167free_hif2:
168 if (dev->hif2)
169 put_device(dev->hif2->dev);
170 devm_free_irq(mdev->dev, irq, dev);
171free_irq_vector:
172 pci_free_irq_vectors(pdev);
173free_device:
174 mt76_free_device(&dev->mt76);
175
176 return ret;
177}
178
developer7800b8d2022-06-23 22:15:56 +0800179static void besra_hif_remove(struct pci_dev *pdev)
developerb11a5392022-03-31 00:34:47 +0800180{
developer7800b8d2022-06-23 22:15:56 +0800181 struct besra_hif *hif = pci_get_drvdata(pdev);
developerb11a5392022-03-31 00:34:47 +0800182
183 list_del(&hif->list);
184}
185
developer7800b8d2022-06-23 22:15:56 +0800186static void besra_pci_remove(struct pci_dev *pdev)
developerb11a5392022-03-31 00:34:47 +0800187{
188 struct mt76_dev *mdev;
developer7800b8d2022-06-23 22:15:56 +0800189 struct besra_dev *dev;
developerb11a5392022-03-31 00:34:47 +0800190
191 mdev = pci_get_drvdata(pdev);
developer7800b8d2022-06-23 22:15:56 +0800192 dev = container_of(mdev, struct besra_dev, mt76);
193 besra_put_hif2(dev->hif2);
194 besra_unregister_device(dev);
developerb11a5392022-03-31 00:34:47 +0800195}
196
developer7800b8d2022-06-23 22:15:56 +0800197struct pci_driver besra_hif_driver = {
developerb11a5392022-03-31 00:34:47 +0800198 .name = KBUILD_MODNAME "_hif",
developer7800b8d2022-06-23 22:15:56 +0800199 .id_table = besra_hif_device_table,
200 .probe = besra_pci_probe,
201 .remove = besra_hif_remove,
developerb11a5392022-03-31 00:34:47 +0800202};
203
developer7800b8d2022-06-23 22:15:56 +0800204struct pci_driver besra_pci_driver = {
developerb11a5392022-03-31 00:34:47 +0800205 .name = KBUILD_MODNAME,
developer7800b8d2022-06-23 22:15:56 +0800206 .id_table = besra_pci_device_table,
207 .probe = besra_pci_probe,
208 .remove = besra_pci_remove,
developerb11a5392022-03-31 00:34:47 +0800209};
210
developer7800b8d2022-06-23 22:15:56 +0800211MODULE_DEVICE_TABLE(pci, besra_pci_device_table);
212MODULE_DEVICE_TABLE(pci, besra_hif_device_table);
developerb11a5392022-03-31 00:34:47 +0800213MODULE_FIRMWARE(MT7902_FIRMWARE_WA);
214MODULE_FIRMWARE(MT7902_FIRMWARE_WM);
215MODULE_FIRMWARE(MT7902_ROM_PATCH);
216MODULE_FIRMWARE(MT7902_FIRMWARE_ROM);
217MODULE_FIRMWARE(MT7902_FIRMWARE_ROM_SRAM);