Home | History | Annotate | Line # | Download | only in pci
drm_pci.c revision 1.13.2.1
      1  1.13.2.1  pgoyette /*	$NetBSD: drm_pci.c,v 1.13.2.1 2017/03/20 06:57:45 pgoyette Exp $	*/
      2       1.2  riastrad 
      3       1.2  riastrad /*-
      4       1.2  riastrad  * Copyright (c) 2013 The NetBSD Foundation, Inc.
      5       1.2  riastrad  * All rights reserved.
      6       1.2  riastrad  *
      7       1.2  riastrad  * This code is derived from software contributed to The NetBSD Foundation
      8       1.2  riastrad  * by Taylor R. Campbell.
      9       1.2  riastrad  *
     10       1.2  riastrad  * Redistribution and use in source and binary forms, with or without
     11       1.2  riastrad  * modification, are permitted provided that the following conditions
     12       1.2  riastrad  * are met:
     13       1.2  riastrad  * 1. Redistributions of source code must retain the above copyright
     14       1.2  riastrad  *    notice, this list of conditions and the following disclaimer.
     15       1.2  riastrad  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.2  riastrad  *    notice, this list of conditions and the following disclaimer in the
     17       1.2  riastrad  *    documentation and/or other materials provided with the distribution.
     18       1.2  riastrad  *
     19       1.2  riastrad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20       1.2  riastrad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21       1.2  riastrad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22       1.2  riastrad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23       1.2  riastrad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24       1.2  riastrad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25       1.2  riastrad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26       1.2  riastrad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27       1.2  riastrad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28       1.2  riastrad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29       1.2  riastrad  * POSSIBILITY OF SUCH DAMAGE.
     30       1.2  riastrad  */
     31       1.2  riastrad 
     32       1.2  riastrad #include <sys/cdefs.h>
     33  1.13.2.1  pgoyette __KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.13.2.1 2017/03/20 06:57:45 pgoyette Exp $");
     34       1.2  riastrad 
     35       1.2  riastrad #include <sys/types.h>
     36       1.2  riastrad #include <sys/errno.h>
     37       1.2  riastrad #include <sys/systm.h>
     38       1.2  riastrad 
     39       1.2  riastrad #include <dev/pci/pcivar.h>
     40       1.2  riastrad 
     41       1.2  riastrad #include <drm/drmP.h>
     42       1.2  riastrad 
     43  1.13.2.1  pgoyette struct drm_bus_irq_cookie {
     44  1.13.2.1  pgoyette 	pci_intr_handle_t *intr_handles;
     45  1.13.2.1  pgoyette 	void *ih_cookie;
     46  1.13.2.1  pgoyette };
     47  1.13.2.1  pgoyette 
     48       1.2  riastrad static int	drm_pci_get_irq(struct drm_device *);
     49       1.2  riastrad static int	drm_pci_irq_install(struct drm_device *,
     50       1.2  riastrad 		    irqreturn_t (*)(void *), int, const char *, void *,
     51       1.2  riastrad 		    struct drm_bus_irq_cookie **);
     52       1.2  riastrad static void	drm_pci_irq_uninstall(struct drm_device *,
     53       1.2  riastrad 		    struct drm_bus_irq_cookie *);
     54       1.2  riastrad static const char *
     55       1.2  riastrad 		drm_pci_get_name(struct drm_device *);
     56       1.2  riastrad static int	drm_pci_set_busid(struct drm_device *, struct drm_master *);
     57       1.2  riastrad static int	drm_pci_set_unique(struct drm_device *, struct drm_master *,
     58       1.2  riastrad 		    struct drm_unique *);
     59       1.2  riastrad static int	drm_pci_irq_by_busid(struct drm_device *,
     60       1.2  riastrad 		    struct drm_irq_busid *);
     61       1.2  riastrad 
     62       1.2  riastrad const struct drm_bus drm_pci_bus = {
     63       1.2  riastrad 	.bus_type = DRIVER_BUS_PCI,
     64       1.2  riastrad 	.get_irq = drm_pci_get_irq,
     65       1.2  riastrad 	.irq_install = drm_pci_irq_install,
     66       1.2  riastrad 	.irq_uninstall = drm_pci_irq_uninstall,
     67       1.2  riastrad 	.get_name = drm_pci_get_name,
     68       1.2  riastrad 	.set_busid = drm_pci_set_busid,
     69       1.2  riastrad 	.set_unique = drm_pci_set_unique,
     70       1.2  riastrad 	.irq_by_busid = drm_pci_irq_by_busid,
     71       1.2  riastrad };
     72       1.2  riastrad 
     73       1.2  riastrad static const struct pci_attach_args *
     74       1.2  riastrad drm_pci_attach_args(struct drm_device *dev)
     75       1.2  riastrad {
     76       1.2  riastrad 	return &dev->pdev->pd_pa;
     77       1.2  riastrad }
     78       1.2  riastrad 
     79       1.2  riastrad int
     80       1.2  riastrad drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver __unused)
     81       1.2  riastrad {
     82       1.2  riastrad 
     83       1.2  riastrad 	driver->bus = &drm_pci_bus;
     84       1.2  riastrad 	return 0;
     85       1.2  riastrad }
     86       1.2  riastrad 
     87       1.2  riastrad void
     88       1.2  riastrad drm_pci_exit(struct drm_driver *driver __unused,
     89       1.2  riastrad     struct pci_driver *pdriver __unused)
     90       1.2  riastrad {
     91       1.2  riastrad }
     92       1.2  riastrad 
     93       1.4  riastrad int
     94       1.2  riastrad drm_pci_attach(device_t self, const struct pci_attach_args *pa,
     95       1.4  riastrad     struct pci_dev *pdev, struct drm_driver *driver, unsigned long cookie,
     96       1.4  riastrad     struct drm_device **devp)
     97       1.2  riastrad {
     98       1.4  riastrad 	struct drm_device *dev;
     99       1.2  riastrad 	unsigned int unit;
    100       1.4  riastrad 	int ret;
    101       1.2  riastrad 
    102      1.10  riastrad 	/* Ensure the drm agp hooks are installed.  */
    103      1.10  riastrad 	/* XXX errno NetBSD->Linux */
    104      1.10  riastrad 	ret = -drmkms_pci_agp_guarantee_initialized();
    105      1.10  riastrad 	if (ret)
    106      1.10  riastrad 		goto fail0;
    107      1.10  riastrad 
    108       1.4  riastrad 	/* Initialize the Linux PCI device descriptor.  */
    109       1.2  riastrad 	linux_pci_dev_init(pdev, self, pa, 0);
    110       1.2  riastrad 
    111       1.4  riastrad 	/* Create a DRM device.  */
    112       1.4  riastrad 	dev = drm_dev_alloc(driver, self);
    113       1.4  riastrad 	if (dev == NULL) {
    114       1.4  riastrad 		ret = -ENOMEM;
    115       1.4  riastrad 		goto fail0;
    116       1.4  riastrad 	}
    117       1.4  riastrad 
    118       1.2  riastrad 	dev->pdev = pdev;
    119      1.11  riastrad 	pdev->pd_drm_dev = dev;	/* XXX Nouveau kludge.  */
    120       1.2  riastrad 
    121       1.2  riastrad 	/* XXX Set the power state to D0?  */
    122       1.2  riastrad 
    123       1.4  riastrad 	/* Set up the bus space and bus DMA tags.  */
    124       1.2  riastrad 	dev->bst = pa->pa_memt;
    125       1.2  riastrad 	/* XXX Let the driver say something about 32-bit vs 64-bit DMA?  */
    126       1.2  riastrad 	dev->bus_dmat = (pci_dma64_available(pa)? pa->pa_dmat64 : pa->pa_dmat);
    127       1.2  riastrad 	dev->dmat = dev->bus_dmat;
    128       1.2  riastrad 	dev->dmat_subregion_p = false;
    129       1.2  riastrad 
    130       1.4  riastrad 	/* Find all the memory maps.  */
    131       1.4  riastrad 	CTASSERT(PCI_NUM_RESOURCES < (SIZE_MAX / sizeof(dev->bus_maps[0])));
    132       1.4  riastrad 	dev->bus_maps = kmem_zalloc(PCI_NUM_RESOURCES *
    133       1.4  riastrad 	    sizeof(dev->bus_maps[0]), KM_SLEEP);
    134       1.4  riastrad 	dev->bus_nmaps = PCI_NUM_RESOURCES;
    135       1.4  riastrad 	for (unit = 0; unit < PCI_NUM_RESOURCES; unit++) {
    136       1.2  riastrad 		struct drm_bus_map *const bm = &dev->bus_maps[unit];
    137       1.2  riastrad 		const int reg = PCI_BAR(unit);
    138       1.2  riastrad 		const pcireg_t type =
    139       1.2  riastrad 		    pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg);
    140       1.2  riastrad 
    141       1.2  riastrad 		/* Reject non-memory mappings.  */
    142       1.2  riastrad 		if ((type & PCI_MAPREG_TYPE_MEM) != PCI_MAPREG_TYPE_MEM) {
    143       1.2  riastrad 			aprint_debug_dev(self, "map %u has non-memory type:"
    144       1.2  riastrad 			    " 0x%"PRIxMAX"\n", unit, (uintmax_t)type);
    145       1.2  riastrad 			continue;
    146       1.2  riastrad 		}
    147       1.2  riastrad 
    148      1.13  riastrad 		/* Inquire about it.  We'll map it in drm_core_ioremap.  */
    149       1.2  riastrad 		if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, reg, type,
    150       1.2  riastrad 			&bm->bm_base, &bm->bm_size, &bm->bm_flags) != 0) {
    151       1.2  riastrad 			aprint_debug_dev(self, "map %u failed\n", unit);
    152       1.2  riastrad 			continue;
    153       1.2  riastrad 		}
    154       1.2  riastrad 
    155       1.2  riastrad 		/* Assume since it is a memory mapping it can be linear.  */
    156       1.2  riastrad 		bm->bm_flags |= BUS_SPACE_MAP_LINEAR;
    157       1.2  riastrad 	}
    158       1.2  riastrad 
    159       1.4  riastrad 	/* Set up AGP stuff if requested.  */
    160       1.4  riastrad 	if (drm_core_check_feature(dev, DRIVER_USE_AGP)) {
    161       1.4  riastrad 		if (drm_pci_device_is_agp(dev))
    162       1.4  riastrad 			dev->agp = drm_agp_init(dev);
    163       1.4  riastrad 		if (dev->agp)
    164       1.4  riastrad 			dev->agp->agp_mtrr = arch_phys_wc_add(dev->agp->base,
    165       1.4  riastrad 				dev->agp->agp_info.aki_info.ai_aperture_size);
    166       1.4  riastrad 	}
    167       1.4  riastrad 
    168       1.4  riastrad 	/* Register the DRM device and do driver-specific initialization.  */
    169       1.4  riastrad 	ret = drm_dev_register(dev, cookie);
    170       1.4  riastrad 	if (ret)
    171       1.4  riastrad 		goto fail1;
    172       1.4  riastrad 
    173       1.4  riastrad 	/* Success!  */
    174       1.4  riastrad 	*devp = dev;
    175       1.4  riastrad 	return 0;
    176       1.4  riastrad 
    177       1.4  riastrad fail2: __unused
    178       1.4  riastrad 	drm_dev_unregister(dev);
    179       1.4  riastrad fail1:	drm_pci_agp_destroy(dev);
    180       1.4  riastrad 	dev->bus_nmaps = 0;
    181       1.4  riastrad 	kmem_free(dev->bus_maps, PCI_NUM_RESOURCES * sizeof(dev->bus_maps[0]));
    182       1.5  riastrad 	if (dev->dmat_subregion_p)
    183       1.5  riastrad 		bus_dmatag_destroy(dev->dmat);
    184       1.4  riastrad 	drm_dev_unref(dev);
    185       1.4  riastrad fail0:	return ret;
    186       1.2  riastrad }
    187       1.2  riastrad 
    188       1.2  riastrad int
    189       1.4  riastrad drm_pci_detach(struct drm_device *dev, int flags __unused)
    190       1.2  riastrad {
    191       1.2  riastrad 
    192       1.4  riastrad 	/* Do driver-specific detachment and unregister the device.  */
    193       1.4  riastrad 	drm_dev_unregister(dev);
    194       1.4  riastrad 
    195       1.4  riastrad 	/* Tear down AGP stuff if necessary.  */
    196       1.8  riastrad 	drm_pci_agp_destroy(dev);
    197       1.4  riastrad 
    198       1.4  riastrad 	/* Free the record of available bus space mappings.  */
    199       1.4  riastrad 	dev->bus_nmaps = 0;
    200       1.4  riastrad 	kmem_free(dev->bus_maps, PCI_NUM_RESOURCES * sizeof(dev->bus_maps[0]));
    201       1.2  riastrad 
    202       1.4  riastrad 	/* Tear down bus space and bus DMA tags.  */
    203       1.2  riastrad 	if (dev->dmat_subregion_p)
    204       1.2  riastrad 		bus_dmatag_destroy(dev->dmat);
    205       1.2  riastrad 
    206       1.4  riastrad 	drm_dev_unref(dev);
    207       1.4  riastrad 
    208       1.2  riastrad 	return 0;
    209       1.2  riastrad }
    210       1.2  riastrad 
    211       1.4  riastrad void
    212       1.4  riastrad drm_pci_agp_destroy(struct drm_device *dev)
    213       1.4  riastrad {
    214       1.4  riastrad 
    215       1.4  riastrad 	if (dev->agp) {
    216       1.4  riastrad 		arch_phys_wc_del(dev->agp->agp_mtrr);
    217       1.4  riastrad 		drm_agp_clear(dev);
    218       1.4  riastrad 		kfree(dev->agp); /* XXX Should go in drm_agp_clear...  */
    219       1.4  riastrad 		dev->agp = NULL;
    220       1.4  riastrad 	}
    221       1.4  riastrad }
    222       1.4  riastrad 
    223       1.2  riastrad static int
    224       1.2  riastrad drm_pci_get_irq(struct drm_device *dev)
    225       1.2  riastrad {
    226       1.2  riastrad 
    227       1.2  riastrad 	/*
    228      1.12  riastrad 	 * Caller expects a nonzero int, and doesn't really use it for
    229      1.12  riastrad 	 * anything, so no need to pci_intr_map here.
    230       1.2  riastrad 	 */
    231      1.12  riastrad 	return dev->pdev->pd_pa.pa_intrpin;
    232       1.2  riastrad }
    233       1.2  riastrad 
    234       1.2  riastrad static int
    235       1.2  riastrad drm_pci_irq_install(struct drm_device *dev, irqreturn_t (*handler)(void *),
    236  1.13.2.1  pgoyette     int flags, const char *name, void *arg, struct drm_bus_irq_cookie **cookiep)
    237       1.2  riastrad {
    238       1.2  riastrad 	const struct pci_attach_args *const pa = drm_pci_attach_args(dev);
    239       1.2  riastrad 	const char *intrstr;
    240       1.3  christos 	char intrbuf[PCI_INTRSTR_LEN];
    241  1.13.2.1  pgoyette 	struct drm_bus_irq_cookie *irq_cookie;
    242       1.2  riastrad 
    243  1.13.2.1  pgoyette 	irq_cookie = kmem_alloc(sizeof(*irq_cookie), KM_SLEEP);
    244  1.13.2.1  pgoyette 	if (irq_cookie == NULL)
    245  1.13.2.1  pgoyette 		return -ENOMEM;
    246  1.13.2.1  pgoyette 
    247  1.13.2.1  pgoyette 	if (dev->pdev->msi_enabled) {
    248  1.13.2.1  pgoyette 		irq_cookie->intr_handles = dev->pdev->intr_handles;
    249  1.13.2.1  pgoyette 		dev->pdev->intr_handles = NULL;
    250  1.13.2.1  pgoyette 	} else {
    251  1.13.2.1  pgoyette 		if (pci_intx_alloc(pa, &irq_cookie->intr_handles))
    252  1.13.2.1  pgoyette 			return -ENOENT;
    253  1.13.2.1  pgoyette 	}
    254       1.2  riastrad 
    255  1.13.2.1  pgoyette 	intrstr = pci_intr_string(pa->pa_pc, irq_cookie->intr_handles[0],
    256  1.13.2.1  pgoyette 	    intrbuf, sizeof(intrbuf));
    257  1.13.2.1  pgoyette 	irq_cookie->ih_cookie = pci_intr_establish_xname(pa->pa_pc,
    258  1.13.2.1  pgoyette 	    irq_cookie->intr_handles[0], IPL_DRM, handler, arg, name);
    259  1.13.2.1  pgoyette 	if (irq_cookie->ih_cookie == NULL) {
    260       1.2  riastrad 		aprint_error_dev(dev->dev,
    261  1.13.2.1  pgoyette 		    "couldn't establish interrupt at %s (%s)\n", intrstr, name);
    262       1.2  riastrad 		return -ENOENT;
    263       1.2  riastrad 	}
    264       1.2  riastrad 
    265  1.13.2.1  pgoyette 	aprint_normal_dev(dev->dev, "interrupting at %s (%s)\n", intrstr, name);
    266  1.13.2.1  pgoyette 	*cookiep = irq_cookie;
    267       1.2  riastrad 	return 0;
    268       1.2  riastrad }
    269       1.2  riastrad 
    270       1.2  riastrad static void
    271  1.13.2.1  pgoyette drm_pci_irq_uninstall(struct drm_device *dev, struct drm_bus_irq_cookie *cookie)
    272       1.2  riastrad {
    273       1.2  riastrad 	const struct pci_attach_args *pa = drm_pci_attach_args(dev);
    274       1.2  riastrad 
    275  1.13.2.1  pgoyette 	pci_intr_disestablish(pa->pa_pc, cookie->ih_cookie);
    276  1.13.2.1  pgoyette 	pci_intr_release(pa->pa_pc, cookie->intr_handles, 1);
    277  1.13.2.1  pgoyette 	kmem_free(cookie, sizeof(*cookie));
    278       1.2  riastrad }
    279       1.2  riastrad 
    280       1.2  riastrad static const char *
    281       1.2  riastrad drm_pci_get_name(struct drm_device *dev)
    282       1.2  riastrad {
    283       1.2  riastrad 	return "pci";		/* XXX PCI bus names?  */
    284       1.2  riastrad }
    285       1.2  riastrad 
    286       1.2  riastrad static int
    287       1.2  riastrad drm_pci_format_unique(struct drm_device *dev, char *buf, size_t size)
    288       1.2  riastrad {
    289       1.6  riastrad 	const unsigned int domain = device_unit(device_parent(dev->dev));
    290       1.2  riastrad 	const unsigned int bus = dev->pdev->pd_pa.pa_bus;
    291       1.2  riastrad 	const unsigned int device = dev->pdev->pd_pa.pa_device;
    292       1.2  riastrad 	const unsigned int function = dev->pdev->pd_pa.pa_function;
    293       1.2  riastrad 
    294       1.2  riastrad 	return snprintf(buf, size, "pci:%04x:%02x:%02x.%d",
    295       1.2  riastrad 	    domain, bus, device, function);
    296       1.2  riastrad }
    297       1.2  riastrad 
    298       1.2  riastrad static int
    299       1.2  riastrad drm_pci_format_devname(struct drm_device *dev, const char *unique,
    300       1.2  riastrad     char *buf, size_t size)
    301       1.2  riastrad {
    302       1.2  riastrad 
    303       1.2  riastrad 	return snprintf(buf, size, "%s@%s",
    304       1.2  riastrad 	    device_xname(device_parent(dev->dev)),
    305       1.2  riastrad 	    unique);
    306       1.2  riastrad }
    307       1.2  riastrad 
    308       1.2  riastrad static int
    309       1.2  riastrad drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
    310       1.2  riastrad {
    311       1.2  riastrad 	int n;
    312       1.2  riastrad 	char *buf;
    313       1.2  riastrad 
    314       1.2  riastrad 	n = drm_pci_format_unique(dev, NULL, 0);
    315       1.2  riastrad 	if (n < 0)
    316       1.2  riastrad 		return -ENOSPC;	/* XXX */
    317       1.2  riastrad 	if (0xff < n)
    318       1.2  riastrad 		n = 0xff;
    319       1.2  riastrad 
    320       1.2  riastrad 	buf = kzalloc(n + 1, GFP_KERNEL);
    321       1.2  riastrad 	(void)drm_pci_format_unique(dev, buf, n + 1);
    322       1.2  riastrad 
    323       1.2  riastrad 	if (master->unique)
    324       1.2  riastrad 		kfree(master->unique);
    325       1.2  riastrad 	master->unique = buf;
    326       1.2  riastrad 	master->unique_len = n;
    327       1.2  riastrad 	master->unique_size = n + 1;
    328       1.2  riastrad 
    329       1.2  riastrad 	n = drm_pci_format_devname(dev, master->unique, NULL, 0);
    330       1.2  riastrad 	if (n < 0)
    331       1.2  riastrad 		return -ENOSPC;	/* XXX back out? */
    332       1.2  riastrad 	if (0xff < n)
    333       1.2  riastrad 		n = 0xff;
    334       1.2  riastrad 
    335       1.2  riastrad 	buf = kzalloc(n + 1, GFP_KERNEL);
    336       1.2  riastrad 	(void)drm_pci_format_devname(dev, master->unique, buf, n + 1);
    337       1.2  riastrad 
    338       1.2  riastrad 	if (dev->devname)
    339       1.2  riastrad 		kfree(dev->devname);
    340       1.2  riastrad 	dev->devname = buf;
    341       1.2  riastrad 
    342       1.2  riastrad 	return 0;
    343       1.2  riastrad }
    344       1.2  riastrad 
    345       1.2  riastrad static int
    346       1.2  riastrad drm_pci_set_unique(struct drm_device *dev, struct drm_master *master,
    347       1.2  riastrad     struct drm_unique *unique __unused)
    348       1.2  riastrad {
    349       1.2  riastrad 
    350       1.2  riastrad 	/*
    351       1.2  riastrad 	 * XXX This is silly.  We're supposed to reject unique names
    352       1.2  riastrad 	 * that don't match the ones we would generate anyway.  For
    353       1.2  riastrad 	 * expedience, we'll just generate the one we would and ignore
    354       1.2  riastrad 	 * whatever userland threw at us...
    355       1.2  riastrad 	 */
    356       1.2  riastrad 	return drm_pci_set_busid(dev, master);
    357       1.2  riastrad }
    358       1.2  riastrad 
    359       1.2  riastrad static int
    360       1.2  riastrad drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *busid)
    361       1.2  riastrad {
    362       1.2  riastrad 	return -ENOSYS;		/* XXX */
    363       1.2  riastrad }
    364