Subversion Repositories Kolibri OS

Rev

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