1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2020 MediaTek Inc.
4 * Author: Ryder Lee <ryder.lee@mediatek.com>
7 #include <linux/kernel.h>
8 #include <linux/module.h>
15 static LIST_HEAD(hif_list
);
16 static DEFINE_SPINLOCK(hif_lock
);
19 static const struct pci_device_id mt7915_pci_device_table
[] = {
20 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK
, 0x7915) },
21 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK
, 0x7906) },
25 static const struct pci_device_id mt7915_hif_device_table
[] = {
26 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK
, 0x7916) },
27 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK
, 0x790a) },
31 static struct mt7915_hif
*mt7915_pci_get_hif2(u32 idx
)
33 struct mt7915_hif
*hif
;
36 spin_lock_bh(&hif_lock
);
38 list_for_each_entry(hif
, &hif_list
, list
) {
39 val
= readl(hif
->regs
+ MT_PCIE_RECOG_ID
);
40 val
&= MT_PCIE_RECOG_ID_MASK
;
50 spin_unlock_bh(&hif_lock
);
55 static void mt7915_put_hif2(struct mt7915_hif
*hif
)
63 static struct mt7915_hif
*mt7915_pci_init_hif2(struct pci_dev
*pdev
)
65 struct pci_dev
*tmp_pdev
;
69 tmp_pdev
= pci_get_device(PCI_VENDOR_ID_MEDIATEK
, 0x7916, NULL
);
71 tmp_pdev
= pci_get_device(PCI_VENDOR_ID_MEDIATEK
, 0x790a, NULL
);
75 pci_dev_put(tmp_pdev
);
77 writel(hif_idx
| MT_PCIE_RECOG_ID_SEM
,
78 pcim_iomap_table(pdev
)[0] + MT_PCIE_RECOG_ID
);
80 return mt7915_pci_get_hif2(hif_idx
);
83 static int mt7915_pci_hif2_probe(struct pci_dev
*pdev
)
85 struct mt7915_hif
*hif
;
87 hif
= devm_kzalloc(&pdev
->dev
, sizeof(*hif
), GFP_KERNEL
);
91 hif
->dev
= &pdev
->dev
;
92 hif
->regs
= pcim_iomap_table(pdev
)[0];
94 spin_lock_bh(&hif_lock
);
95 list_add(&hif
->list
, &hif_list
);
96 spin_unlock_bh(&hif_lock
);
97 pci_set_drvdata(pdev
, hif
);
102 static int mt7915_pci_probe(struct pci_dev
*pdev
,
103 const struct pci_device_id
*id
)
105 struct mt7915_hif
*hif2
= NULL
;
106 struct mt7915_dev
*dev
;
107 struct mt76_dev
*mdev
;
111 ret
= pcim_enable_device(pdev
);
115 ret
= pcim_iomap_regions(pdev
, BIT(0), pci_name(pdev
));
119 pci_set_master(pdev
);
121 ret
= dma_set_mask(&pdev
->dev
, DMA_BIT_MASK(32));
125 mt76_pci_disable_aspm(pdev
);
127 if (id
->device
== 0x7916 || id
->device
== 0x790a)
128 return mt7915_pci_hif2_probe(pdev
);
130 dev
= mt7915_mmio_probe(&pdev
->dev
, pcim_iomap_table(pdev
)[0],
136 mt7915_wfsys_reset(dev
);
137 hif2
= mt7915_pci_init_hif2(pdev
);
139 ret
= mt7915_mmio_wed_init(dev
, pdev
, true, &irq
);
141 goto free_wed_or_irq_vector
;
144 hif2
= mt7915_pci_init_hif2(pdev
);
146 ret
= pci_alloc_irq_vectors(pdev
, 1, 1, PCI_IRQ_ALL_TYPES
);
153 ret
= devm_request_irq(mdev
->dev
, irq
, mt7915_irq_handler
,
154 IRQF_SHARED
, KBUILD_MODNAME
, dev
);
156 goto free_wed_or_irq_vector
;
158 /* master switch of PCIe tnterrupt enable */
159 mt76_wr(dev
, MT_PCIE_MAC_INT_ENABLE
, 0xff);
164 mt76_wr(dev
, MT_INT1_MASK_CSR
, 0);
165 /* master switch of PCIe tnterrupt enable */
167 mt76_wr(dev
, MT_PCIE1_MAC_INT_ENABLE
, 0xff);
169 mt76_wr(dev
, MT_PCIE1_MAC_INT_ENABLE_MT7916
, 0xff);
171 ret
= devm_request_irq(mdev
->dev
, dev
->hif2
->irq
,
172 mt7915_irq_handler
, IRQF_SHARED
,
173 KBUILD_MODNAME
"-hif", dev
);
178 ret
= mt7915_register_device(dev
);
186 devm_free_irq(mdev
->dev
, dev
->hif2
->irq
, dev
);
189 put_device(dev
->hif2
->dev
);
190 devm_free_irq(mdev
->dev
, irq
, dev
);
191 free_wed_or_irq_vector
:
192 if (mtk_wed_device_active(&mdev
->mmio
.wed
))
193 mtk_wed_device_detach(&mdev
->mmio
.wed
);
195 pci_free_irq_vectors(pdev
);
197 mt76_free_device(&dev
->mt76
);
202 static void mt7915_hif_remove(struct pci_dev
*pdev
)
204 struct mt7915_hif
*hif
= pci_get_drvdata(pdev
);
206 list_del(&hif
->list
);
209 static void mt7915_pci_remove(struct pci_dev
*pdev
)
211 struct mt76_dev
*mdev
;
212 struct mt7915_dev
*dev
;
214 mdev
= pci_get_drvdata(pdev
);
215 dev
= container_of(mdev
, struct mt7915_dev
, mt76
);
216 mt7915_put_hif2(dev
->hif2
);
217 mt7915_unregister_device(dev
);
220 struct pci_driver mt7915_hif_driver
= {
221 .name
= KBUILD_MODNAME
"_hif",
222 .id_table
= mt7915_hif_device_table
,
223 .probe
= mt7915_pci_probe
,
224 .remove
= mt7915_hif_remove
,
227 struct pci_driver mt7915_pci_driver
= {
228 .name
= KBUILD_MODNAME
,
229 .id_table
= mt7915_pci_device_table
,
230 .probe
= mt7915_pci_probe
,
231 .remove
= mt7915_pci_remove
,
234 MODULE_DEVICE_TABLE(pci
, mt7915_pci_device_table
);
235 MODULE_DEVICE_TABLE(pci
, mt7915_hif_device_table
);
236 MODULE_FIRMWARE(MT7915_FIRMWARE_WA
);
237 MODULE_FIRMWARE(MT7915_FIRMWARE_WM
);
238 MODULE_FIRMWARE(MT7915_ROM_PATCH
);
239 MODULE_FIRMWARE(MT7916_FIRMWARE_WA
);
240 MODULE_FIRMWARE(MT7916_FIRMWARE_WM
);
241 MODULE_FIRMWARE(MT7916_ROM_PATCH
);