1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (C) 2022 MediaTek Inc. 4 */ 5 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/pci.h> 9 10 #include "mt7996.h" 11 #include "mac.h" 12 #include "../trace.h" 13 14 static LIST_HEAD(hif_list); 15 static DEFINE_SPINLOCK(hif_lock); 16 static u32 hif_idx; 17 18 static const struct pci_device_id mt7996_pci_device_table[] = { 19 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7990) }, 20 { }, 21 }; 22 23 static const struct pci_device_id mt7996_hif_device_table[] = { 24 { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7991) }, 25 { }, 26 }; 27 28 static struct mt7996_hif *mt7996_pci_get_hif2(u32 idx) 29 { 30 struct mt7996_hif *hif; 31 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 46 out: 47 spin_unlock_bh(&hif_lock); 48 49 return hif; 50 } 51 52 static void mt7996_put_hif2(struct mt7996_hif *hif) 53 { 54 if (!hif) 55 return; 56 57 put_device(hif->dev); 58 } 59 60 static struct mt7996_hif *mt7996_pci_init_hif2(struct pci_dev *pdev) 61 { 62 hif_idx++; 63 if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL)) 64 return NULL; 65 66 writel(hif_idx | MT_PCIE_RECOG_ID_SEM, 67 pcim_iomap_table(pdev)[0] + MT_PCIE_RECOG_ID); 68 69 return mt7996_pci_get_hif2(hif_idx); 70 } 71 72 static int mt7996_pci_hif2_probe(struct pci_dev *pdev) 73 { 74 struct mt7996_hif *hif; 75 76 hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL); 77 if (!hif) 78 return -ENOMEM; 79 80 hif->dev = &pdev->dev; 81 hif->regs = pcim_iomap_table(pdev)[0]; 82 hif->irq = pdev->irq; 83 spin_lock_bh(&hif_lock); 84 list_add(&hif->list, &hif_list); 85 spin_unlock_bh(&hif_lock); 86 pci_set_drvdata(pdev, hif); 87 88 return 0; 89 } 90 91 static int mt7996_pci_probe(struct pci_dev *pdev, 92 const struct pci_device_id *id) 93 { 94 struct pci_dev *hif2_dev; 95 struct mt7996_dev *dev; 96 struct mt76_dev *mdev; 97 struct mt7996_hif *hif2; 98 int irq, ret; 99 100 ret = pcim_enable_device(pdev); 101 if (ret) 102 return ret; 103 104 ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev)); 105 if (ret) 106 return ret; 107 108 pci_set_master(pdev); 109 110 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); 111 if (ret) 112 return ret; 113 114 mt76_pci_disable_aspm(pdev); 115 116 if (id->device == 0x7991) 117 return mt7996_pci_hif2_probe(pdev); 118 119 dev = mt7996_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0], 120 id->device); 121 if (IS_ERR(dev)) 122 return PTR_ERR(dev); 123 124 mdev = &dev->mt76; 125 mt7996_wfsys_reset(dev); 126 hif2 = mt7996_pci_init_hif2(pdev); 127 128 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 129 if (ret < 0) 130 goto free_device; 131 132 irq = pdev->irq; 133 ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler, 134 IRQF_SHARED, KBUILD_MODNAME, dev); 135 if (ret) 136 goto free_irq_vector; 137 138 mt76_wr(dev, MT_INT_MASK_CSR, 0); 139 /* master switch of PCIe tnterrupt enable */ 140 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); 141 142 if (hif2) { 143 hif2_dev = container_of(hif2->dev, struct pci_dev, dev); 144 dev->hif2 = hif2; 145 146 ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES); 147 if (ret < 0) 148 goto free_hif2; 149 150 dev->hif2->irq = hif2_dev->irq; 151 ret = devm_request_irq(mdev->dev, dev->hif2->irq, 152 mt7996_irq_handler, IRQF_SHARED, 153 KBUILD_MODNAME "-hif", dev); 154 if (ret) 155 goto free_hif2_irq_vector; 156 157 mt76_wr(dev, MT_INT1_MASK_CSR, 0); 158 /* master switch of PCIe tnterrupt enable */ 159 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); 160 } 161 162 ret = mt7996_register_device(dev); 163 if (ret) 164 goto free_hif2_irq; 165 166 return 0; 167 168 free_hif2_irq: 169 if (dev->hif2) 170 devm_free_irq(mdev->dev, dev->hif2->irq, dev); 171 free_hif2_irq_vector: 172 if (dev->hif2) 173 pci_free_irq_vectors(hif2_dev); 174 free_hif2: 175 if (dev->hif2) 176 put_device(dev->hif2->dev); 177 devm_free_irq(mdev->dev, irq, dev); 178 free_irq_vector: 179 pci_free_irq_vectors(pdev); 180 free_device: 181 mt76_free_device(&dev->mt76); 182 183 return ret; 184 } 185 186 static void mt7996_hif_remove(struct pci_dev *pdev) 187 { 188 struct mt7996_hif *hif = pci_get_drvdata(pdev); 189 190 list_del(&hif->list); 191 } 192 193 static void mt7996_pci_remove(struct pci_dev *pdev) 194 { 195 struct mt76_dev *mdev; 196 struct mt7996_dev *dev; 197 198 mdev = pci_get_drvdata(pdev); 199 dev = container_of(mdev, struct mt7996_dev, mt76); 200 mt7996_put_hif2(dev->hif2); 201 mt7996_unregister_device(dev); 202 } 203 204 struct pci_driver mt7996_hif_driver = { 205 .name = KBUILD_MODNAME "_hif", 206 .id_table = mt7996_hif_device_table, 207 .probe = mt7996_pci_probe, 208 .remove = mt7996_hif_remove, 209 }; 210 211 struct pci_driver mt7996_pci_driver = { 212 .name = KBUILD_MODNAME, 213 .id_table = mt7996_pci_device_table, 214 .probe = mt7996_pci_probe, 215 .remove = mt7996_pci_remove, 216 }; 217 218 MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table); 219 MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table); 220 MODULE_FIRMWARE(MT7996_FIRMWARE_WA); 221 MODULE_FIRMWARE(MT7996_FIRMWARE_WM); 222 MODULE_FIRMWARE(MT7996_ROM_PATCH); 223