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