brintos

brintos / linux-shallow public Read only

0
0
Text · 5.6 KiB · 0405618 Raw
259 lines · c
1// SPDX-License-Identifier: ISC2/*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 14static LIST_HEAD(hif_list);15static DEFINE_SPINLOCK(hif_lock);16static u32 hif_idx;17 18static 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 24static 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 30static 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 48out:49	spin_unlock_bh(&hif_lock);50 51	return hif;52}53 54static void mt7996_put_hif2(struct mt7996_hif *hif)55{56	if (!hif)57		return;58 59	put_device(hif->dev);60}61 62static 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 76static 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 95static 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_hif *hif2;100	struct mt7996_dev *dev;101	int irq, hif2_irq, ret;102	struct mt76_dev *mdev;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(36));115	if (ret)116		return ret;117 118	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));119	if (ret)120		return ret;121 122	mt76_pci_disable_aspm(pdev);123 124	if (id->device == 0x7991 || id->device == 0x799a)125		return mt7996_pci_hif2_probe(pdev);126 127	dev = mt7996_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],128				id->device);129	if (IS_ERR(dev))130		return PTR_ERR(dev);131 132	mdev = &dev->mt76;133	mt7996_wfsys_reset(dev);134	hif2 = mt7996_pci_init_hif2(pdev);135 136	ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);137	if (ret < 0)138		goto free_wed_or_irq_vector;139 140	if (!ret) {141		ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);142		if (ret < 0)143			goto free_device;144 145		irq = pdev->irq;146	}147 148	ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,149			       IRQF_SHARED, KBUILD_MODNAME, dev);150	if (ret)151		goto free_wed_or_irq_vector;152 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);156 157	if (hif2) {158		hif2_dev = container_of(hif2->dev, struct pci_dev, dev);159		dev->hif2 = hif2;160 161		ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &hif2_irq);162		if (ret < 0)163			goto free_hif2_wed_irq_vector;164 165		if (!ret) {166			ret = pci_alloc_irq_vectors(hif2_dev, 1, 1,167						    PCI_IRQ_ALL_TYPES);168			if (ret < 0)169				goto free_hif2;170 171			dev->hif2->irq = hif2_dev->irq;172			hif2_irq = dev->hif2->irq;173		}174 175		ret = devm_request_irq(mdev->dev, hif2_irq, mt7996_irq_handler,176				       IRQF_SHARED, KBUILD_MODNAME "-hif",177				       dev);178		if (ret)179			goto free_hif2_wed_irq_vector;180 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);184	}185 186	ret = mt7996_register_device(dev);187	if (ret)188		goto free_hif2_irq;189 190	return 0;191 192free_hif2_irq:193	if (dev->hif2)194		devm_free_irq(mdev->dev, hif2_irq, dev);195free_hif2_wed_irq_vector:196	if (dev->hif2) {197		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))198			mtk_wed_device_detach(&dev->mt76.mmio.wed_hif2);199		else200			pci_free_irq_vectors(hif2_dev);201	}202free_hif2:203	if (dev->hif2)204		put_device(dev->hif2->dev);205	devm_free_irq(mdev->dev, irq, dev);206free_wed_or_irq_vector:207	if (mtk_wed_device_active(&dev->mt76.mmio.wed))208		mtk_wed_device_detach(&dev->mt76.mmio.wed);209	else210		pci_free_irq_vectors(pdev);211free_device:212	mt76_free_device(&dev->mt76);213 214	return ret;215}216 217static void mt7996_hif_remove(struct pci_dev *pdev)218{219	struct mt7996_hif *hif = pci_get_drvdata(pdev);220 221	list_del(&hif->list);222}223 224static void mt7996_pci_remove(struct pci_dev *pdev)225{226	struct mt76_dev *mdev;227	struct mt7996_dev *dev;228 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);233}234 235struct 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,240};241 242struct 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,247};248 249MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table);250MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table);251MODULE_FIRMWARE(MT7996_FIRMWARE_WA);252MODULE_FIRMWARE(MT7996_FIRMWARE_WM);253MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);254MODULE_FIRMWARE(MT7996_ROM_PATCH);255MODULE_FIRMWARE(MT7992_FIRMWARE_WA);256MODULE_FIRMWARE(MT7992_FIRMWARE_WM);257MODULE_FIRMWARE(MT7992_FIRMWARE_DSP);258MODULE_FIRMWARE(MT7992_ROM_PATCH);259