1 // SPDX-License-Identifier: ISC
3 * Copyright (C) 2022 MediaTek Inc.
6 #include <linux/kernel.h>
7 #include <linux/module.h>
14 static LIST_HEAD(hif_list
);
15 static DEFINE_SPINLOCK(hif_lock
);
18 static const struct pci_device_id mt7996_pci_device_table
[] = {
19 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK
, 0x7990) },
20 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK
, 0x7992) },
24 static const struct pci_device_id mt7996_hif_device_table
[] = {
25 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK
, 0x7991) },
26 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK
, 0x799a) },
30 static struct mt7996_hif
*mt7996_pci_get_hif2(u32 idx
)
32 struct mt7996_hif
*hif
;
35 spin_lock_bh(&hif_lock
);
37 list_for_each_entry(hif
, &hif_list
, list
) {
38 val
= readl(hif
->regs
+ MT_PCIE_RECOG_ID
);
39 val
&= MT_PCIE_RECOG_ID_MASK
;
49 spin_unlock_bh(&hif_lock
);
54 static void mt7996_put_hif2(struct mt7996_hif
*hif
)
62 static struct mt7996_hif
*mt7996_pci_init_hif2(struct pci_dev
*pdev
)
66 if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK
, 0x7991, NULL
) &&
67 !pci_get_device(PCI_VENDOR_ID_MEDIATEK
, 0x799a, NULL
))
70 writel(hif_idx
| MT_PCIE_RECOG_ID_SEM
,
71 pcim_iomap_table(pdev
)[0] + MT_PCIE_RECOG_ID
);
73 return mt7996_pci_get_hif2(hif_idx
);
76 static int mt7996_pci_hif2_probe(struct pci_dev
*pdev
)
78 struct mt7996_hif
*hif
;
80 hif
= devm_kzalloc(&pdev
->dev
, sizeof(*hif
), GFP_KERNEL
);
84 hif
->dev
= &pdev
->dev
;
85 hif
->regs
= pcim_iomap_table(pdev
)[0];
87 spin_lock_bh(&hif_lock
);
88 list_add(&hif
->list
, &hif_list
);
89 spin_unlock_bh(&hif_lock
);
90 pci_set_drvdata(pdev
, hif
);
95 static int mt7996_pci_probe(struct pci_dev
*pdev
,
96 const struct pci_device_id
*id
)
98 struct pci_dev
*hif2_dev
;
99 struct mt7996_hif
*hif2
;
100 struct mt7996_dev
*dev
;
101 int irq
, hif2_irq
, ret
;
102 struct mt76_dev
*mdev
;
104 ret
= pcim_enable_device(pdev
);
108 ret
= pcim_iomap_regions(pdev
, BIT(0), pci_name(pdev
));
112 pci_set_master(pdev
);
114 ret
= dma_set_mask(&pdev
->dev
, DMA_BIT_MASK(36));
118 ret
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
122 mt76_pci_disable_aspm(pdev
);
124 if (id
->device
== 0x7991 || id
->device
== 0x799a)
125 return mt7996_pci_hif2_probe(pdev
);
127 dev
= mt7996_mmio_probe(&pdev
->dev
, pcim_iomap_table(pdev
)[0],
133 mt7996_wfsys_reset(dev
);
134 hif2
= mt7996_pci_init_hif2(pdev
);
136 ret
= mt7996_mmio_wed_init(dev
, pdev
, false, &irq
);
138 goto free_wed_or_irq_vector
;
141 ret
= pci_alloc_irq_vectors(pdev
, 1, 1, PCI_IRQ_ALL_TYPES
);
148 ret
= devm_request_irq(mdev
->dev
, irq
, mt7996_irq_handler
,
149 IRQF_SHARED
, KBUILD_MODNAME
, dev
);
151 goto free_wed_or_irq_vector
;
153 mt76_wr(dev
, MT_INT_MASK_CSR
, 0);
154 /* master switch of PCIe tnterrupt enable */
155 mt76_wr(dev
, MT_PCIE_MAC_INT_ENABLE
, 0xff);
158 hif2_dev
= container_of(hif2
->dev
, struct pci_dev
, dev
);
161 ret
= mt7996_mmio_wed_init(dev
, hif2_dev
, true, &hif2_irq
);
163 goto free_hif2_wed_irq_vector
;
166 ret
= pci_alloc_irq_vectors(hif2_dev
, 1, 1,
171 dev
->hif2
->irq
= hif2_dev
->irq
;
172 hif2_irq
= dev
->hif2
->irq
;
175 ret
= devm_request_irq(mdev
->dev
, hif2_irq
, mt7996_irq_handler
,
176 IRQF_SHARED
, KBUILD_MODNAME
"-hif",
179 goto free_hif2_wed_irq_vector
;
181 mt76_wr(dev
, MT_INT1_MASK_CSR
, 0);
182 /* master switch of PCIe tnterrupt enable */
183 mt76_wr(dev
, MT_PCIE1_MAC_INT_ENABLE
, 0xff);
186 ret
= mt7996_register_device(dev
);
194 devm_free_irq(mdev
->dev
, hif2_irq
, dev
);
195 free_hif2_wed_irq_vector
:
197 if (mtk_wed_device_active(&dev
->mt76
.mmio
.wed_hif2
))
198 mtk_wed_device_detach(&dev
->mt76
.mmio
.wed_hif2
);
200 pci_free_irq_vectors(hif2_dev
);
204 put_device(dev
->hif2
->dev
);
205 devm_free_irq(mdev
->dev
, irq
, dev
);
206 free_wed_or_irq_vector
:
207 if (mtk_wed_device_active(&dev
->mt76
.mmio
.wed
))
208 mtk_wed_device_detach(&dev
->mt76
.mmio
.wed
);
210 pci_free_irq_vectors(pdev
);
212 mt76_free_device(&dev
->mt76
);
217 static void mt7996_hif_remove(struct pci_dev
*pdev
)
219 struct mt7996_hif
*hif
= pci_get_drvdata(pdev
);
221 list_del(&hif
->list
);
224 static void mt7996_pci_remove(struct pci_dev
*pdev
)
226 struct mt76_dev
*mdev
;
227 struct mt7996_dev
*dev
;
229 mdev
= pci_get_drvdata(pdev
);
230 dev
= container_of(mdev
, struct mt7996_dev
, mt76
);
231 mt7996_put_hif2(dev
->hif2
);
232 mt7996_unregister_device(dev
);
235 struct pci_driver mt7996_hif_driver
= {
236 .name
= KBUILD_MODNAME
"_hif",
237 .id_table
= mt7996_hif_device_table
,
238 .probe
= mt7996_pci_probe
,
239 .remove
= mt7996_hif_remove
,
242 struct pci_driver mt7996_pci_driver
= {
243 .name
= KBUILD_MODNAME
,
244 .id_table
= mt7996_pci_device_table
,
245 .probe
= mt7996_pci_probe
,
246 .remove
= mt7996_pci_remove
,
249 MODULE_DEVICE_TABLE(pci
, mt7996_pci_device_table
);
250 MODULE_DEVICE_TABLE(pci
, mt7996_hif_device_table
);
251 MODULE_FIRMWARE(MT7996_FIRMWARE_WA
);
252 MODULE_FIRMWARE(MT7996_FIRMWARE_WM
);
253 MODULE_FIRMWARE(MT7996_FIRMWARE_DSP
);
254 MODULE_FIRMWARE(MT7996_ROM_PATCH
);
255 MODULE_FIRMWARE(MT7992_FIRMWARE_WA
);
256 MODULE_FIRMWARE(MT7992_FIRMWARE_WM
);
257 MODULE_FIRMWARE(MT7992_FIRMWARE_DSP
);
258 MODULE_FIRMWARE(MT7992_ROM_PATCH
);