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