| /* |
| * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
| * All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sub license, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the |
| * next paragraph) shall be included in all copies or substantial portions |
| * of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
| * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR |
| * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| * |
| * |
| * Author: Alan Hourihane <alanh@tungstengraphics.com> |
| * Author: Jakob Bornecrantz <wallbraker@gmail.com> |
| * |
| */ |
| |
| #include "../../state_trackers/xorg/xorg_winsys.h" |
| #include <nouveau.h> |
| #include <xorg/dri.h> |
| #include <xf86drmMode.h> |
| |
| static void nouveau_xorg_identify(int flags); |
| static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num, |
| struct pci_device *device, |
| intptr_t match_data); |
| |
| static const struct pci_id_match nouveau_xorg_device_match[] = { |
| { 0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, |
| 0x00030000, 0x00ffffff, 0 }, |
| {0, 0, 0}, |
| }; |
| |
| static PciChipsets nouveau_xorg_pci_devices[] = { |
| {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL}, |
| {-1, -1, NULL} |
| }; |
| |
| static XF86ModuleVersionInfo nouveau_xorg_version = { |
| "nouveau2", |
| MODULEVENDORSTRING, |
| MODINFOSTRING1, |
| MODINFOSTRING2, |
| XORG_VERSION_CURRENT, |
| 0, 1, 0, /* major, minor, patch */ |
| ABI_CLASS_VIDEODRV, |
| ABI_VIDEODRV_VERSION, |
| MOD_CLASS_VIDEODRV, |
| {0, 0, 0, 0} |
| }; |
| |
| /* |
| * Xorg driver exported structures |
| */ |
| |
| _X_EXPORT DriverRec nouveau2 = { |
| 1, |
| "nouveau2", |
| nouveau_xorg_identify, |
| NULL, |
| xorg_tracker_available_options, |
| NULL, |
| 0, |
| NULL, |
| nouveau_xorg_device_match, |
| nouveau_xorg_pci_probe |
| }; |
| |
| static MODULESETUPPROTO(nouveau_xorg_setup); |
| |
| _X_EXPORT XF86ModuleData nouveau2ModuleData = { |
| &nouveau_xorg_version, |
| nouveau_xorg_setup, |
| NULL |
| }; |
| |
| /* |
| * Xorg driver functions |
| */ |
| |
| static pointer |
| nouveau_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin) |
| { |
| static Bool setupDone = 0; |
| |
| /* This module should be loaded only once, but check to be sure. |
| */ |
| if (!setupDone) { |
| setupDone = 1; |
| xf86AddDriver(&nouveau2, module, HaveDriverFuncs); |
| |
| /* |
| * The return value must be non-NULL on success even though there |
| * is no TearDownProc. |
| */ |
| return (pointer) 1; |
| } else { |
| if (errmaj) |
| *errmaj = LDR_ONCEONLY; |
| return NULL; |
| } |
| } |
| |
| static void |
| nouveau_xorg_identify(int flags) |
| { |
| xf86DrvMsg(0, X_INFO, "nouveau2: Gallium3D based 2D driver for NV30+ NVIDIA chipsets\n"); |
| } |
| |
| static Bool |
| nouveau_xorg_pci_probe(DriverPtr driver, |
| int entity_num, struct pci_device *device, intptr_t match_data) |
| { |
| ScrnInfoPtr scrn = NULL; |
| EntityInfoPtr entity; |
| struct nouveau_device *dev = NULL; |
| char *busid; |
| int chipset, ret; |
| |
| if (device->vendor_id != 0x10DE) |
| return FALSE; |
| |
| if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) { |
| xf86DrvMsg(-1, X_ERROR, "[drm] No DRICreatePCIBusID symbol\n"); |
| return FALSE; |
| } |
| busid = DRICreatePCIBusID(device); |
| |
| ret = nouveau_device_open(busid, &dev); |
| if (ret) { |
| xf86DrvMsg(-1, X_ERROR, "[drm] failed to open device\n"); |
| free(busid); |
| return FALSE; |
| } |
| |
| chipset = dev->chipset; |
| nouveau_device_del(&dev); |
| |
| ret = drmCheckModesettingSupported(busid); |
| free(busid); |
| if (ret) { |
| xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n"); |
| return FALSE; |
| } |
| |
| switch (chipset & 0xf0) { |
| case 0x00: |
| case 0x10: |
| case 0x20: |
| xf86DrvMsg(-1, X_NOTICE, "Too old chipset: NV%02x\n", chipset); |
| return FALSE; |
| case 0x30: |
| case 0x40: |
| case 0x60: |
| case 0x50: |
| case 0x80: |
| case 0x90: |
| case 0xa0: |
| case 0xc0: |
| xf86DrvMsg(-1, X_INFO, "Detected chipset: NV%02x\n", chipset); |
| break; |
| default: |
| xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02x\n", chipset); |
| return FALSE; |
| } |
| |
| scrn = xf86ConfigPciEntity(scrn, 0, entity_num, nouveau_xorg_pci_devices, |
| NULL, NULL, NULL, NULL, NULL); |
| if (scrn != NULL) { |
| scrn->driverVersion = 1; |
| scrn->driverName = "nouveau"; |
| scrn->name = "nouveau2"; |
| scrn->Probe = NULL; |
| |
| entity = xf86GetEntityInfo(entity_num); |
| |
| /* Use all the functions from the xorg tracker */ |
| xorg_tracker_set_functions(scrn); |
| } |
| return scrn != NULL; |
| } |