Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2015 Red Hat Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: Ben Skeggs <bskeggs@redhat.com>
0023  */
0024 #include "priv.h"
0025 #include "agp.h"
0026 
0027 #include <core/option.h>
0028 #include <core/pci.h>
0029 #include <subdev/mc.h>
0030 
0031 u32
0032 nvkm_pci_rd32(struct nvkm_pci *pci, u16 addr)
0033 {
0034     return pci->func->rd32(pci, addr);
0035 }
0036 
0037 void
0038 nvkm_pci_wr08(struct nvkm_pci *pci, u16 addr, u8 data)
0039 {
0040     pci->func->wr08(pci, addr, data);
0041 }
0042 
0043 void
0044 nvkm_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data)
0045 {
0046     pci->func->wr32(pci, addr, data);
0047 }
0048 
0049 u32
0050 nvkm_pci_mask(struct nvkm_pci *pci, u16 addr, u32 mask, u32 value)
0051 {
0052     u32 data = pci->func->rd32(pci, addr);
0053     pci->func->wr32(pci, addr, (data & ~mask) | value);
0054     return data;
0055 }
0056 
0057 void
0058 nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow)
0059 {
0060     u32 data = nvkm_pci_rd32(pci, 0x0050);
0061     if (shadow)
0062         data |=  0x00000001;
0063     else
0064         data &= ~0x00000001;
0065     nvkm_pci_wr32(pci, 0x0050, data);
0066 }
0067 
0068 static irqreturn_t
0069 nvkm_pci_intr(int irq, void *arg)
0070 {
0071     struct nvkm_pci *pci = arg;
0072     struct nvkm_device *device = pci->subdev.device;
0073     bool handled = false;
0074 
0075     if (pci->irq < 0)
0076         return IRQ_HANDLED;
0077 
0078     nvkm_mc_intr_unarm(device);
0079     if (pci->msi)
0080         pci->func->msi_rearm(pci);
0081     nvkm_mc_intr(device, &handled);
0082     nvkm_mc_intr_rearm(device);
0083     return handled ? IRQ_HANDLED : IRQ_NONE;
0084 }
0085 
0086 static int
0087 nvkm_pci_fini(struct nvkm_subdev *subdev, bool suspend)
0088 {
0089     struct nvkm_pci *pci = nvkm_pci(subdev);
0090 
0091     if (pci->agp.bridge)
0092         nvkm_agp_fini(pci);
0093 
0094     return 0;
0095 }
0096 
0097 static int
0098 nvkm_pci_preinit(struct nvkm_subdev *subdev)
0099 {
0100     struct nvkm_pci *pci = nvkm_pci(subdev);
0101     if (pci->agp.bridge)
0102         nvkm_agp_preinit(pci);
0103     return 0;
0104 }
0105 
0106 static int
0107 nvkm_pci_oneinit(struct nvkm_subdev *subdev)
0108 {
0109     struct nvkm_pci *pci = nvkm_pci(subdev);
0110     struct pci_dev *pdev = pci->pdev;
0111     int ret;
0112 
0113     if (pci_is_pcie(pci->pdev)) {
0114         ret = nvkm_pcie_oneinit(pci);
0115         if (ret)
0116             return ret;
0117     }
0118 
0119     ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci);
0120     if (ret)
0121         return ret;
0122 
0123     pci->irq = pdev->irq;
0124     return 0;
0125 }
0126 
0127 static int
0128 nvkm_pci_init(struct nvkm_subdev *subdev)
0129 {
0130     struct nvkm_pci *pci = nvkm_pci(subdev);
0131     int ret;
0132 
0133     if (pci->agp.bridge) {
0134         ret = nvkm_agp_init(pci);
0135         if (ret)
0136             return ret;
0137     } else if (pci_is_pcie(pci->pdev)) {
0138         nvkm_pcie_init(pci);
0139     }
0140 
0141     if (pci->func->init)
0142         pci->func->init(pci);
0143 
0144     /* Ensure MSI interrupts are armed, for the case where there are
0145      * already interrupts pending (for whatever reason) at load time.
0146      */
0147     if (pci->msi)
0148         pci->func->msi_rearm(pci);
0149 
0150     return 0;
0151 }
0152 
0153 static void *
0154 nvkm_pci_dtor(struct nvkm_subdev *subdev)
0155 {
0156     struct nvkm_pci *pci = nvkm_pci(subdev);
0157 
0158     nvkm_agp_dtor(pci);
0159 
0160     if (pci->irq >= 0) {
0161         /* freq_irq() will call the handler, we use pci->irq == -1
0162          * to signal that it's been torn down and should be a noop.
0163          */
0164         int irq = pci->irq;
0165         pci->irq = -1;
0166         free_irq(irq, pci);
0167     }
0168 
0169     if (pci->msi)
0170         pci_disable_msi(pci->pdev);
0171 
0172     return nvkm_pci(subdev);
0173 }
0174 
0175 static const struct nvkm_subdev_func
0176 nvkm_pci_func = {
0177     .dtor = nvkm_pci_dtor,
0178     .oneinit = nvkm_pci_oneinit,
0179     .preinit = nvkm_pci_preinit,
0180     .init = nvkm_pci_init,
0181     .fini = nvkm_pci_fini,
0182 };
0183 
0184 int
0185 nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device,
0186           enum nvkm_subdev_type type, int inst, struct nvkm_pci **ppci)
0187 {
0188     struct nvkm_pci *pci;
0189 
0190     if (!(pci = *ppci = kzalloc(sizeof(**ppci), GFP_KERNEL)))
0191         return -ENOMEM;
0192     nvkm_subdev_ctor(&nvkm_pci_func, device, type, inst, &pci->subdev);
0193     pci->func = func;
0194     pci->pdev = device->func->pci(device)->pdev;
0195     pci->irq = -1;
0196     pci->pcie.speed = -1;
0197     pci->pcie.width = -1;
0198 
0199     if (device->type == NVKM_DEVICE_AGP)
0200         nvkm_agp_ctor(pci);
0201 
0202     switch (pci->pdev->device & 0x0ff0) {
0203     case 0x00f0:
0204     case 0x02e0:
0205         /* BR02? NFI how these would be handled yet exactly */
0206         break;
0207     default:
0208         switch (device->chipset) {
0209         case 0xaa:
0210             /* reported broken, nv also disable it */
0211             break;
0212         default:
0213             pci->msi = true;
0214             break;
0215         }
0216     }
0217 
0218 #ifdef __BIG_ENDIAN
0219     pci->msi = false;
0220 #endif
0221 
0222     pci->msi = nvkm_boolopt(device->cfgopt, "NvMSI", pci->msi);
0223     if (pci->msi && func->msi_rearm) {
0224         pci->msi = pci_enable_msi(pci->pdev) == 0;
0225         if (pci->msi)
0226             nvkm_debug(&pci->subdev, "MSI enabled\n");
0227     } else {
0228         pci->msi = false;
0229     }
0230 
0231     return 0;
0232 }