Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2011 Intel Corporation
  4.  * Copyright 2012 Francisco Jerez
  5.  * All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the
  9.  * "Software"), to deal in the Software without restriction, including
  10.  * without limitation the rights to use, copy, modify, merge, publish,
  11.  * distribute, sub license, and/or sell copies of the Software, and to
  12.  * permit persons to whom the Software is furnished to do so, subject to
  13.  * the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice (including the
  16.  * next paragraph) shall be included in all copies or substantial portions
  17.  * of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  22.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  23.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  24.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  25.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26.  *
  27.  * Authors:
  28.  *    Kristian Høgsberg <krh@bitplanet.net>
  29.  *    Benjamin Franzke <benjaminfranzke@googlemail.com>
  30.  *
  31.  **************************************************************************/
  32.  
  33. #include <fcntl.h>
  34. #include <stdio.h>
  35. //#include <libudev.h>
  36. #include <xf86drm.h>
  37.  
  38. #ifdef HAVE_PIPE_LOADER_XCB
  39.  
  40. #include <xcb/dri2.h>
  41.  
  42. #endif
  43.  
  44. #include "state_tracker/drm_driver.h"
  45. #include "pipe_loader_priv.h"
  46.  
  47. #include "util/u_memory.h"
  48. #include "util/u_dl.h"
  49. #include "util/u_debug.h"
  50.  
  51. #define DRIVER_MAP_GALLIUM_ONLY
  52. #include "pci_ids/pci_id_driver_map.h"
  53. #include <kos32sys.h>
  54.  
  55. struct pci_device {
  56.     uint16_t    domain;
  57.     uint8_t     bus;
  58.     uint8_t     dev;
  59.     uint8_t     func;
  60.     uint16_t    vendor_id;
  61.     uint16_t    device_id;
  62.     uint16_t    subvendor_id;
  63.     uint16_t    subdevice_id;
  64.     uint32_t    device_class;
  65.     uint8_t     revision;
  66. };
  67.  
  68. struct pipe_loader_drm_device {
  69.    struct pipe_loader_device base;
  70.    struct util_dl_library *lib;
  71.    int fd;
  72. };
  73.  
  74. #define pipe_loader_drm_device(dev) ((struct pipe_loader_drm_device *)dev)
  75.  
  76. static boolean
  77. find_drm_pci_id(struct pipe_loader_drm_device *ddev)
  78. {
  79.    struct pci_device device;
  80.    ioctl_t   io;
  81.  
  82.    io.handle   = ddev->fd;
  83.    io.io_code  = SRV_GET_PCI_INFO;
  84.    io.input    = &device;
  85.    io.inp_size = sizeof(device);
  86.    io.output   = NULL;
  87.    io.out_size = 0;
  88.  
  89.    if (call_service(&io)!=0)
  90.       return FALSE;
  91.  
  92.    ddev->base.u.pci.vendor_id = device.vendor_id;
  93.    ddev->base.u.pci.chip_id = device.device_id;
  94.  
  95.    return TRUE;
  96. }
  97.  
  98. static boolean
  99. find_drm_driver_name(struct pipe_loader_drm_device *ddev)
  100. {
  101.    struct pipe_loader_device *dev = &ddev->base;
  102.    int i, j;
  103.  
  104.    for (i = 0; driver_map[i].driver; i++) {
  105.       if (dev->u.pci.vendor_id != driver_map[i].vendor_id)
  106.          continue;
  107.  
  108.       if (driver_map[i].num_chips_ids == -1) {
  109.          dev->driver_name = driver_map[i].driver;
  110.          goto found;
  111.       }
  112.  
  113.       for (j = 0; j < driver_map[i].num_chips_ids; j++) {
  114.          if (dev->u.pci.chip_id == driver_map[i].chip_ids[j]) {
  115.             dev->driver_name = driver_map[i].driver;
  116.             goto found;
  117.          }
  118.       }
  119.    }
  120.  
  121.    return FALSE;
  122.  
  123.   found:
  124.    return TRUE;
  125. }
  126.  
  127. static struct pipe_loader_ops pipe_loader_drm_ops;
  128.  
  129.  
  130. boolean
  131. pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
  132. {
  133.    struct pipe_loader_drm_device *ddev = CALLOC_STRUCT(pipe_loader_drm_device);
  134.  
  135.    ddev->base.type = PIPE_LOADER_DEVICE_PCI;
  136.    ddev->base.ops = &pipe_loader_drm_ops;
  137.    ddev->fd = fd;
  138.  
  139.    if (!find_drm_pci_id(ddev))
  140.       goto fail;
  141.  
  142.    if (!find_drm_driver_name(ddev))
  143.       goto fail;
  144.  
  145.    *dev = &ddev->base;
  146.    return TRUE;
  147.  
  148.   fail:
  149.    FREE(ddev);
  150.    return FALSE;
  151. }
  152.  
  153.  
  154. int
  155. pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev)
  156. {
  157.    int i, j, fd;
  158.  
  159.    for (i = 0, j = 0; i < 1; i++) {
  160.       fd = get_service("DISPLAY");
  161.       if (fd == 0)
  162.          continue;
  163.  
  164.       if (j >= ndev || !pipe_loader_drm_probe_fd(&devs[j], fd))
  165.          ;
  166.  
  167.       j++;
  168.    }
  169.  
  170.    return j;
  171. }
  172.  
  173. static void
  174. pipe_loader_drm_release(struct pipe_loader_device **dev)
  175. {
  176.    struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(*dev);
  177.  
  178.    FREE(ddev);
  179.    *dev = NULL;
  180. }
  181.  
  182. static struct pipe_screen *
  183. pipe_loader_drm_create_screen(struct pipe_loader_device *dev,
  184.                               const char *library_paths)
  185. {
  186.    struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(dev);
  187.    const struct drm_driver_descriptor *dd;
  188.  
  189.    if (!ddev->lib)
  190.       ddev->lib = pipe_loader_find_module(dev, library_paths);
  191.    if (!ddev->lib)
  192.       return NULL;
  193.  
  194.    dd = (const struct drm_driver_descriptor *)
  195.       util_dl_get_proc_address(ddev->lib, "driver_descriptor");
  196.  
  197.    /* sanity check on the name */
  198.    if (!dd || strcmp(dd->name, ddev->base.driver_name) != 0)
  199.       return NULL;
  200.  
  201.    return dd->create_screen(ddev->fd);
  202. }
  203.  
  204. static struct pipe_loader_ops pipe_loader_drm_ops = {
  205.    .create_screen = pipe_loader_drm_create_screen,
  206.    .release = pipe_loader_drm_release
  207. };
  208.