Subversion Repositories Kolibri OS

Rev

Rev 5271 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2003 José Fonseca.
  3.  * Copyright 2003 Leif Delgass.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the next
  14.  * paragraph) shall be included in all copies or substantial portions of the
  15.  * Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  20.  * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  21.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  22.  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include <linux/pci.h>
  26. #include <linux/slab.h>
  27. #include <linux/dma-mapping.h>
  28. #include <linux/export.h>
  29. #include <drm/drmP.h>
  30. #include "drm_internal.h"
  31. #include "drm_legacy.h"
  32.  
  33. #include <syscall.h>
  34. /**
  35.  * drm_pci_alloc - Allocate a PCI consistent memory block, for DMA.
  36.  * @dev: DRM device
  37.  * @size: size of block to allocate
  38.  * @align: alignment of block
  39.  *
  40.  * Return: A handle to the allocated memory block on success or NULL on
  41.  * failure.
  42.  */
  43. drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align)
  44. {
  45.         drm_dma_handle_t *dmah;
  46.         unsigned long addr;
  47.         size_t sz;
  48.  
  49.         /* pci_alloc_consistent only guarantees alignment to the smallest
  50.          * PAGE_SIZE order which is greater than or equal to the requested size.
  51.          * Return NULL here for now to make sure nobody tries for larger alignment
  52.          */
  53.         if (align > size)
  54.                 return NULL;
  55.  
  56.         dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
  57.         if (!dmah)
  58.                 return NULL;
  59.  
  60.         dmah->size = size;
  61.     dmah->vaddr = (void*)KernelAlloc(size);
  62.     dmah->busaddr = GetPgAddr(dmah->vaddr);
  63.  
  64.         if (dmah->vaddr == NULL) {
  65.                 kfree(dmah);
  66.                 return NULL;
  67.         }
  68.  
  69.         memset(dmah->vaddr, 0, size);
  70.  
  71.         return dmah;
  72. }
  73.  
  74. EXPORT_SYMBOL(drm_pci_alloc);
  75.  
  76. #if 0
  77. /**
  78.  * \brief Free a PCI consistent memory block without freeing its descriptor.
  79.  *
  80.  * This function is for internal use in the Linux-specific DRM core code.
  81.  */
  82. void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
  83. {
  84.         unsigned long addr;
  85.         size_t sz;
  86.  
  87.         if (dmah->vaddr) {
  88.                 /* XXX - Is virt_to_page() legal for consistent mem? */
  89.                 /* Unreserve */
  90.                 for (addr = (unsigned long)dmah->vaddr, sz = dmah->size;
  91.                      sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
  92.                         ClearPageReserved(virt_to_page((void *)addr));
  93.                 }
  94.                 dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr,
  95.                                   dmah->busaddr);
  96.         }
  97. }
  98.  
  99. /**
  100.  * drm_pci_free - Free a PCI consistent memory block
  101.  * @dev: DRM device
  102.  * @dmah: handle to memory block
  103.  */
  104. void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
  105. {
  106.         __drm_pci_free(dev, dmah);
  107.         kfree(dmah);
  108. }
  109.  
  110. EXPORT_SYMBOL(drm_pci_free);
  111.  
  112.  
  113. static int drm_get_pci_domain(struct drm_device *dev)
  114. {
  115. #ifndef __alpha__
  116.         /* For historical reasons, drm_get_pci_domain() is busticated
  117.          * on most archs and has to remain so for userspace interface
  118.          * < 1.4, except on alpha which was right from the beginning
  119.          */
  120.         if (dev->if_version < 0x10004)
  121.                 return 0;
  122. #endif /* __alpha__ */
  123.  
  124.         return pci_domain_nr(dev->pdev->bus);
  125. }
  126.  
  127. static int drm_pci_get_irq(struct drm_device *dev)
  128. {
  129.         return dev->pdev->irq;
  130. }
  131.  
  132. static const char *drm_pci_get_name(struct drm_device *dev)
  133. {
  134.         struct pci_driver *pdriver = dev->driver->kdriver.pci;
  135.         return pdriver->name;
  136. }
  137.  
  138. static int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
  139. {
  140.         int len, ret;
  141.         struct pci_driver *pdriver = dev->driver->kdriver.pci;
  142.         master->unique_len = 40;
  143.         master->unique_size = master->unique_len;
  144.         master->unique = kmalloc(master->unique_size, GFP_KERNEL);
  145.         if (master->unique == NULL)
  146.                 return -ENOMEM;
  147.  
  148.  
  149.         len = snprintf(master->unique, master->unique_len,
  150.                        "pci:%04x:%02x:%02x.%d",
  151.                        drm_get_pci_domain(dev),
  152.                        dev->pdev->bus->number,
  153.                        PCI_SLOT(dev->pdev->devfn),
  154.                        PCI_FUNC(dev->pdev->devfn));
  155.  
  156.         if (len >= master->unique_len) {
  157.                 DRM_ERROR("buffer overflow");
  158.                 ret = -EINVAL;
  159.                 goto err;
  160.         } else
  161.                 master->unique_len = len;
  162.  
  163.         dev->devname =
  164.                 kmalloc(strlen(pdriver->name) +
  165.                         master->unique_len + 2, GFP_KERNEL);
  166.  
  167.         if (dev->devname == NULL) {
  168.                 ret = -ENOMEM;
  169.                 goto err;
  170.         }
  171.  
  172.         sprintf(dev->devname, "%s@%s", pdriver->name,
  173.                 master->unique);
  174.  
  175.         return 0;
  176. err:
  177.         return ret;
  178. }
  179.  
  180. static int drm_pci_set_unique(struct drm_device *dev,
  181.                               struct drm_master *master,
  182.                               struct drm_unique *u)
  183. {
  184.         int domain, bus, slot, func, ret;
  185.         const char *bus_name;
  186.  
  187.         master->unique_len = u->unique_len;
  188.         master->unique_size = u->unique_len + 1;
  189.         master->unique = kmalloc(master->unique_size, GFP_KERNEL);
  190.         if (!master->unique) {
  191.                 ret = -ENOMEM;
  192.                 goto err;
  193.         }
  194.  
  195.         if (copy_from_user(master->unique, u->unique, master->unique_len)) {
  196.                 ret = -EFAULT;
  197.                 goto err;
  198.         }
  199.  
  200.         master->unique[master->unique_len] = '\0';
  201.  
  202.         bus_name = dev->driver->bus->get_name(dev);
  203.         dev->devname = kmalloc(strlen(bus_name) +
  204.                                strlen(master->unique) + 2, GFP_KERNEL);
  205.         if (!dev->devname) {
  206.                 ret = -ENOMEM;
  207.                 goto err;
  208.         }
  209.  
  210.         sprintf(dev->devname, "%s@%s", bus_name,
  211.                 master->unique);
  212.  
  213.         /* Return error if the busid submitted doesn't match the device's actual
  214.          * busid.
  215.          */
  216.         ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
  217.         if (ret != 3) {
  218.                 ret = -EINVAL;
  219.                 goto err;
  220.         }
  221.  
  222.         domain = bus >> 8;
  223.         bus &= 0xff;
  224.  
  225.         if ((domain != drm_get_pci_domain(dev)) ||
  226.             (bus != dev->pdev->bus->number) ||
  227.             (slot != PCI_SLOT(dev->pdev->devfn)) ||
  228.             (func != PCI_FUNC(dev->pdev->devfn))) {
  229.                 ret = -EINVAL;
  230.                 goto err;
  231.         }
  232.         return 0;
  233. err:
  234.         return ret;
  235. }
  236.  
  237. static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
  238. {
  239.         if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
  240.             (p->busnum & 0xff) != dev->pdev->bus->number ||
  241.             p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
  242.                 return -EINVAL;
  243.  
  244.         p->irq = dev->pdev->irq;
  245.  
  246.         DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
  247.                   p->irq);
  248.         return 0;
  249. }
  250.  
  251. static void drm_pci_agp_init(struct drm_device *dev)
  252. {
  253.         if (drm_core_check_feature(dev, DRIVER_USE_AGP)) {
  254.                 if (drm_pci_device_is_agp(dev))
  255.                         dev->agp = drm_agp_init(dev);
  256.                 if (dev->agp) {
  257.                         dev->agp->agp_mtrr = arch_phys_wc_add(
  258.                                 dev->agp->agp_info.aper_base,
  259.                                 dev->agp->agp_info.aper_size *
  260.                                 1024 * 1024);
  261.                 }
  262.         }
  263. }
  264.  
  265. void drm_pci_agp_destroy(struct drm_device *dev)
  266. {
  267.         if (dev->agp) {
  268.                 arch_phys_wc_del(dev->agp->agp_mtrr);
  269.                 drm_agp_clear(dev);
  270.                 kfree(dev->agp);
  271.                 dev->agp = NULL;
  272.         }
  273. }
  274.  
  275. static struct drm_bus drm_pci_bus = {
  276.         .bus_type = DRIVER_BUS_PCI,
  277.         .get_irq = drm_pci_get_irq,
  278.         .get_name = drm_pci_get_name,
  279.         .set_busid = drm_pci_set_busid,
  280.         .set_unique = drm_pci_set_unique,
  281.         .irq_by_busid = drm_pci_irq_by_busid,
  282. };
  283. #endif
  284.  
  285. /**
  286.  * Register.
  287.  *
  288.  * \param pdev - PCI device structure
  289.  * \param ent entry from the PCI ID table with device type flags
  290.  * \return zero on success or a negative number on failure.
  291.  *
  292.  * Attempt to gets inter module "drm" information. If we are first
  293.  * then register the character device and inter module information.
  294.  * Try and register, if we fail to register, backout previous work.
  295.  *
  296.  * Return: 0 on success or a negative error code on failure.
  297.  */
  298. int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
  299.                     struct drm_driver *driver)
  300. {
  301.     static struct drm_device drm_dev;
  302.     static struct drm_file   drm_file;
  303.  
  304.         struct drm_device *dev;
  305.     struct drm_file   *priv;
  306.  
  307.         int ret;
  308.  
  309.     dev  = &drm_dev;
  310.     priv = &drm_file;
  311.  
  312.     drm_file_handlers[0] = priv;
  313.  
  314.  //   ret = pci_enable_device(pdev);
  315.  //   if (ret)
  316.  //       goto err_g1;
  317.  
  318.     pci_set_master(pdev);
  319.  
  320.     if ((ret = drm_fill_in_dev(dev, ent, driver))) {
  321.         printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
  322.         goto err_g2;
  323.     }
  324.  
  325.         DRM_DEBUG("\n");
  326.  
  327.  
  328.         dev->pdev = pdev;
  329. #ifdef __alpha__
  330.         dev->hose = pdev->sysdata;
  331. #endif
  332.  
  333.  
  334.         if ((ret = drm_fill_in_dev(dev, ent, driver))) {
  335.                 printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
  336.                 goto err_g2;
  337.         }
  338.  
  339. #if 0
  340.         if (drm_core_check_feature(dev, DRIVER_MODESET)) {
  341.                 pci_set_drvdata(pdev, dev);
  342.                 ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
  343.                 if (ret)
  344.                         goto err_g2;
  345.         }
  346.  
  347.         if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
  348.                 ret = drm_get_minor(dev, &dev->render, DRM_MINOR_RENDER);
  349.                 if (ret)
  350.                         goto err_g21;
  351.         }
  352.  
  353.         if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
  354.                 goto err_g3;
  355. #endif
  356.  
  357.         if (dev->driver->load) {
  358.                 ret = dev->driver->load(dev, ent->driver_data);
  359.                 if (ret)
  360.                         goto err_g4;
  361.         }
  362.  
  363.     if (dev->driver->open) {
  364.         ret = dev->driver->open(dev, priv);
  365.         if (ret < 0)
  366.             goto err_g4;
  367.     }
  368.  
  369.  
  370. //   mutex_unlock(&drm_global_mutex);
  371.         return 0;
  372.  
  373. err_g4:
  374. //   drm_put_minor(&dev->primary);
  375. err_g3:
  376. //   if (dev->render)
  377. //       drm_put_minor(&dev->render);
  378. err_g21:
  379. //   if (drm_core_check_feature(dev, DRIVER_MODESET))
  380. //       drm_put_minor(&dev->control);
  381. err_g2:
  382. //   pci_disable_device(pdev);
  383. err_g1:
  384. //   kfree(dev);
  385. //   mutex_unlock(&drm_global_mutex);
  386.         return ret;
  387. }
  388. EXPORT_SYMBOL(drm_get_pci_dev);
  389.  
  390. int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask)
  391. {
  392.         struct pci_dev *root;
  393.         u32 lnkcap, lnkcap2;
  394.  
  395.         *mask = 0;
  396.         if (!dev->pdev)
  397.                 return -EINVAL;
  398.  
  399.  
  400.     return -EINVAL;
  401.  
  402. #if 0
  403.         root = dev->pdev->bus->self;
  404.  
  405.         /* we've been informed via and serverworks don't make the cut */
  406.         if (root->vendor == PCI_VENDOR_ID_VIA ||
  407.             root->vendor == PCI_VENDOR_ID_SERVERWORKS)
  408.                 return -EINVAL;
  409.  
  410.         pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
  411.         pcie_capability_read_dword(root, PCI_EXP_LNKCAP2, &lnkcap2);
  412.  
  413.         if (lnkcap2) {  /* PCIe r3.0-compliant */
  414.                 if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB)
  415.                         *mask |= DRM_PCIE_SPEED_25;
  416.                 if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
  417.                         *mask |= DRM_PCIE_SPEED_50;
  418.                 if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
  419.                         *mask |= DRM_PCIE_SPEED_80;
  420.         } else {        /* pre-r3.0 */
  421.                 if (lnkcap & PCI_EXP_LNKCAP_SLS_2_5GB)
  422.                         *mask |= DRM_PCIE_SPEED_25;
  423.                 if (lnkcap & PCI_EXP_LNKCAP_SLS_5_0GB)
  424.                         *mask |= (DRM_PCIE_SPEED_25 | DRM_PCIE_SPEED_50);
  425.         }
  426.  
  427.         DRM_INFO("probing gen 2 caps for device %x:%x = %x/%x\n", root->vendor, root->device, lnkcap, lnkcap2);
  428.         return 0;
  429. #endif
  430.  
  431. }
  432. EXPORT_SYMBOL(drm_pcie_get_speed_cap_mask);
  433.