Home | History | Annotate | Download | only in xorg-nouveau
      1 /*
      2  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sub license, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial portions
     15  * of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     20  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
     21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  *
     26  * Author: Alan Hourihane <alanh (at) tungstengraphics.com>
     27  * Author: Jakob Bornecrantz <wallbraker (at) gmail.com>
     28  *
     29  */
     30 
     31 #include "../../state_trackers/xorg/xorg_winsys.h"
     32 #include <nouveau.h>
     33 #include <xorg/dri.h>
     34 #include <xf86drmMode.h>
     35 
     36 static void nouveau_xorg_identify(int flags);
     37 static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num,
     38 				   struct pci_device *device,
     39 				   intptr_t match_data);
     40 
     41 static const struct pci_id_match nouveau_xorg_device_match[] = {
     42     { 0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
     43       0x00030000, 0x00ffffff, 0 },
     44     {0, 0, 0},
     45 };
     46 
     47 static PciChipsets nouveau_xorg_pci_devices[] = {
     48     {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
     49     {-1, -1, NULL}
     50 };
     51 
     52 static XF86ModuleVersionInfo nouveau_xorg_version = {
     53     "nouveau2",
     54     MODULEVENDORSTRING,
     55     MODINFOSTRING1,
     56     MODINFOSTRING2,
     57     XORG_VERSION_CURRENT,
     58     0, 1, 0, /* major, minor, patch */
     59     ABI_CLASS_VIDEODRV,
     60     ABI_VIDEODRV_VERSION,
     61     MOD_CLASS_VIDEODRV,
     62     {0, 0, 0, 0}
     63 };
     64 
     65 /*
     66  * Xorg driver exported structures
     67  */
     68 
     69 _X_EXPORT DriverRec nouveau2 = {
     70     1,
     71     "nouveau2",
     72     nouveau_xorg_identify,
     73     NULL,
     74     xorg_tracker_available_options,
     75     NULL,
     76     0,
     77     NULL,
     78     nouveau_xorg_device_match,
     79     nouveau_xorg_pci_probe
     80 };
     81 
     82 static MODULESETUPPROTO(nouveau_xorg_setup);
     83 
     84 _X_EXPORT XF86ModuleData nouveau2ModuleData = {
     85     &nouveau_xorg_version,
     86     nouveau_xorg_setup,
     87     NULL
     88 };
     89 
     90 /*
     91  * Xorg driver functions
     92  */
     93 
     94 static pointer
     95 nouveau_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
     96 {
     97     static Bool setupDone = 0;
     98 
     99     /* This module should be loaded only once, but check to be sure.
    100      */
    101     if (!setupDone) {
    102 	setupDone = 1;
    103 	xf86AddDriver(&nouveau2, module, HaveDriverFuncs);
    104 
    105 	/*
    106 	 * The return value must be non-NULL on success even though there
    107 	 * is no TearDownProc.
    108 	 */
    109 	return (pointer) 1;
    110     } else {
    111 	if (errmaj)
    112 	    *errmaj = LDR_ONCEONLY;
    113 	return NULL;
    114     }
    115 }
    116 
    117 static void
    118 nouveau_xorg_identify(int flags)
    119 {
    120     xf86DrvMsg(0, X_INFO, "nouveau2: Gallium3D based 2D driver for NV30+ NVIDIA chipsets\n");
    121 }
    122 
    123 static Bool
    124 nouveau_xorg_pci_probe(DriverPtr driver,
    125 	  int entity_num, struct pci_device *device, intptr_t match_data)
    126 {
    127     ScrnInfoPtr scrn = NULL;
    128     EntityInfoPtr entity;
    129     struct nouveau_device *dev = NULL;
    130     char *busid;
    131     int chipset, ret;
    132 
    133     if (device->vendor_id != 0x10DE)
    134 	return FALSE;
    135 
    136     if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
    137 	xf86DrvMsg(-1, X_ERROR, "[drm] No DRICreatePCIBusID symbol\n");
    138 	return FALSE;
    139     }
    140     busid = DRICreatePCIBusID(device);
    141 
    142     ret = nouveau_device_open(busid, &dev);
    143     if (ret) {
    144 	xf86DrvMsg(-1, X_ERROR, "[drm] failed to open device\n");
    145 	free(busid);
    146 	return FALSE;
    147     }
    148 
    149     chipset = dev->chipset;
    150     nouveau_device_del(&dev);
    151 
    152     ret = drmCheckModesettingSupported(busid);
    153     free(busid);
    154     if (ret) {
    155 	xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n");
    156 	return FALSE;
    157     }
    158 
    159     switch (chipset & 0xf0) {
    160     case 0x00:
    161     case 0x10:
    162     case 0x20:
    163 	xf86DrvMsg(-1, X_NOTICE, "Too old chipset: NV%02x\n", chipset);
    164 	return FALSE;
    165     case 0x30:
    166     case 0x40:
    167     case 0x60:
    168     case 0x50:
    169     case 0x80:
    170     case 0x90:
    171     case 0xa0:
    172     case 0xc0:
    173 	xf86DrvMsg(-1, X_INFO, "Detected chipset: NV%02x\n", chipset);
    174 	break;
    175     default:
    176 	xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02x\n", chipset);
    177 	return FALSE;
    178     }
    179 
    180     scrn = xf86ConfigPciEntity(scrn, 0, entity_num, nouveau_xorg_pci_devices,
    181 			       NULL, NULL, NULL, NULL, NULL);
    182     if (scrn != NULL) {
    183 	scrn->driverVersion = 1;
    184 	scrn->driverName = "nouveau";
    185 	scrn->name = "nouveau2";
    186 	scrn->Probe = NULL;
    187 
    188 	entity = xf86GetEntityInfo(entity_num);
    189 
    190 	/* Use all the functions from the xorg tracker */
    191 	xorg_tracker_set_functions(scrn);
    192     }
    193     return scrn != NULL;
    194 }
    195