1 // 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 11 #include "mt7915.h" 12 #include "mac.h" 13 #include "../trace.h" 14 15 static LIST_HEAD(hif_list); 16 static DEFINE_SPINLOCK(hif_lock); 17 static u32 hif_idx; 18 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) }, 22 { }, 23 }; 24 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) }, 28 { }, 29 }; 30 31 static struct mt7915_hif *mt7915_pci_get_hif2(u32 idx) 32 { 33 struct mt7915_hif *hif; 34 u32 val; 35 36 spin_lock_bh(&hif_lock); 37 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; 41 if (val != idx) 42 continue; 43 44 get_device(hif->dev); 45 goto out; 46 } 47 hif = NULL; 48 49 out: 50 spin_unlock_bh(&hif_lock); 51 52 return hif; 53 } 54 55 static void mt7915_put_hif2(struct mt7915_hif *hif) 56 { 57 if (!hif) 58 return; 59 60 put_device(hif->dev); 61 } 62 63 static struct mt7915_hif *mt7915_pci_init_hif2(struct pci_dev *pdev) 64 { 65 hif_idx++; 66 if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL) && 67 !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, 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 mt7915_pci_get_hif2(hif_idx); 74 } 75 76 static int mt7915_pci_hif2_probe(struct pci_dev *pdev) 77 { 78 struct mt7915_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 mt7915_pci_probe(struct pci_dev *pdev, 96 const struct pci_device_id *id) 97 { 98 struct mt7915_dev *dev; 99 struct mt76_dev *mdev; 100 struct mt7915_hif *hif2; 101 int irq; 102 int 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 == 0x7916 || id->device == 0x790a) 121 return mt7915_pci_hif2_probe(pdev); 122 123 dev = mt7915_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 hif2 = mt7915_pci_init_hif2(pdev); 130 131 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 132 if (ret < 0) 133 goto free_device; 134 135 irq = pdev->irq; 136 ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler, 137 IRQF_SHARED, KBUILD_MODNAME, dev); 138 if (ret) 139 goto free_irq_vector; 140 141 mt76_wr(dev, MT_INT_MASK_CSR, 0); 142 143 /* master switch of PCIe tnterrupt enable */ 144 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); 145 146 if (hif2) { 147 dev->hif2 = hif2; 148 149 mt76_wr(dev, MT_INT1_MASK_CSR, 0); 150 /* master switch of PCIe tnterrupt enable */ 151 if (is_mt7915(mdev)) 152 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); 153 else 154 mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0xff); 155 156 ret = devm_request_irq(mdev->dev, dev->hif2->irq, 157 mt7915_irq_handler, IRQF_SHARED, 158 KBUILD_MODNAME "-hif", dev); 159 if (ret) 160 goto free_hif2; 161 } 162 163 ret = mt7915_register_device(dev); 164 if (ret) 165 goto free_hif2_irq; 166 167 return 0; 168 169 free_hif2_irq: 170 if (dev->hif2) 171 devm_free_irq(mdev->dev, dev->hif2->irq, dev); 172 free_hif2: 173 if (dev->hif2) 174 put_device(dev->hif2->dev); 175 devm_free_irq(mdev->dev, irq, dev); 176 free_irq_vector: 177 pci_free_irq_vectors(pdev); 178 free_device: 179 mt76_free_device(&dev->mt76); 180 181 return ret; 182 } 183 184 static void mt7915_hif_remove(struct pci_dev *pdev) 185 { 186 struct mt7915_hif *hif = pci_get_drvdata(pdev); 187 188 list_del(&hif->list); 189 } 190 191 static void mt7915_pci_remove(struct pci_dev *pdev) 192 { 193 struct mt76_dev *mdev; 194 struct mt7915_dev *dev; 195 196 mdev = pci_get_drvdata(pdev); 197 dev = container_of(mdev, struct mt7915_dev, mt76); 198 mt7915_put_hif2(dev->hif2); 199 mt7915_unregister_device(dev); 200 } 201 202 struct pci_driver mt7915_hif_driver = { 203 .name = KBUILD_MODNAME "_hif", 204 .id_table = mt7915_hif_device_table, 205 .probe = mt7915_pci_probe, 206 .remove = mt7915_hif_remove, 207 }; 208 209 struct pci_driver mt7915_pci_driver = { 210 .name = KBUILD_MODNAME, 211 .id_table = mt7915_pci_device_table, 212 .probe = mt7915_pci_probe, 213 .remove = mt7915_pci_remove, 214 }; 215 216 MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table); 217 MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table); 218 MODULE_FIRMWARE(MT7915_FIRMWARE_WA); 219 MODULE_FIRMWARE(MT7915_FIRMWARE_WM); 220 MODULE_FIRMWARE(MT7915_ROM_PATCH); 221 MODULE_FIRMWARE(MT7916_FIRMWARE_WA); 222 MODULE_FIRMWARE(MT7916_FIRMWARE_WM); 223 MODULE_FIRMWARE(MT7916_ROM_PATCH); 224