1 2 #include <sys/cdefs.h> 3 __FBSDID("$FreeBSD$"); 4 5 #include <dev/drm2/drmP.h> 6 7 #include <dev/agp/agpreg.h> 8 #include <dev/pci/pcireg.h> 9 10 devclass_t drm_devclass; 11 12 MALLOC_DEFINE(DRM_MEM_DMA, "drm_dma", "DRM DMA Data Structures"); 13 MALLOC_DEFINE(DRM_MEM_SAREA, "drm_sarea", "DRM SAREA Data Structures"); 14 MALLOC_DEFINE(DRM_MEM_DRIVER, "drm_driver", "DRM DRIVER Data Structures"); 15 MALLOC_DEFINE(DRM_MEM_MAGIC, "drm_magic", "DRM MAGIC Data Structures"); 16 MALLOC_DEFINE(DRM_MEM_MINOR, "drm_minor", "DRM MINOR Data Structures"); 17 MALLOC_DEFINE(DRM_MEM_IOCTLS, "drm_ioctls", "DRM IOCTL Data Structures"); 18 MALLOC_DEFINE(DRM_MEM_MAPS, "drm_maps", "DRM MAP Data Structures"); 19 MALLOC_DEFINE(DRM_MEM_BUFS, "drm_bufs", "DRM BUFFER Data Structures"); 20 MALLOC_DEFINE(DRM_MEM_SEGS, "drm_segs", "DRM SEGMENTS Data Structures"); 21 MALLOC_DEFINE(DRM_MEM_PAGES, "drm_pages", "DRM PAGES Data Structures"); 22 MALLOC_DEFINE(DRM_MEM_FILES, "drm_files", "DRM FILE Data Structures"); 23 MALLOC_DEFINE(DRM_MEM_QUEUES, "drm_queues", "DRM QUEUE Data Structures"); 24 MALLOC_DEFINE(DRM_MEM_CMDS, "drm_cmds", "DRM COMMAND Data Structures"); 25 MALLOC_DEFINE(DRM_MEM_MAPPINGS, "drm_mapping", "DRM MAPPING Data Structures"); 26 MALLOC_DEFINE(DRM_MEM_BUFLISTS, "drm_buflists", "DRM BUFLISTS Data Structures"); 27 MALLOC_DEFINE(DRM_MEM_AGPLISTS, "drm_agplists", "DRM AGPLISTS Data Structures"); 28 MALLOC_DEFINE(DRM_MEM_CTXBITMAP, "drm_ctxbitmap", 29 "DRM CTXBITMAP Data Structures"); 30 MALLOC_DEFINE(DRM_MEM_SGLISTS, "drm_sglists", "DRM SGLISTS Data Structures"); 31 MALLOC_DEFINE(DRM_MEM_MM, "drm_sman", "DRM MEMORY MANAGER Data Structures"); 32 MALLOC_DEFINE(DRM_MEM_HASHTAB, "drm_hashtab", "DRM HASHTABLE Data Structures"); 33 MALLOC_DEFINE(DRM_MEM_KMS, "drm_kms", "DRM KMS Data Structures"); 34 MALLOC_DEFINE(DRM_MEM_VBLANK, "drm_vblank", "DRM VBLANK Handling Data"); 35 36 const char *fb_mode_option = NULL; 37 38 #define NSEC_PER_USEC 1000L 39 #define NSEC_PER_SEC 1000000000L 40 41 int64_t 42 timeval_to_ns(const struct timeval *tv) 43 { 44 return ((int64_t)tv->tv_sec * NSEC_PER_SEC) + 45 tv->tv_usec * NSEC_PER_USEC; 46 } 47 48 struct timeval 49 ns_to_timeval(const int64_t nsec) 50 { 51 struct timeval tv; 52 long rem; 53 54 if (nsec == 0) { 55 tv.tv_sec = 0; 56 tv.tv_usec = 0; 57 return (tv); 58 } 59 60 tv.tv_sec = nsec / NSEC_PER_SEC; 61 rem = nsec % NSEC_PER_SEC; 62 if (rem < 0) { 63 tv.tv_sec--; 64 rem += NSEC_PER_SEC; 65 } 66 tv.tv_usec = rem / 1000; 67 return (tv); 68 } 69 70 /* Copied from OFED. */ 71 unsigned long drm_linux_timer_hz_mask; 72 73 static void 74 drm_linux_timer_init(void *arg) 75 { 76 77 /* 78 * Compute an internal HZ value which can divide 2**32 to 79 * avoid timer rounding problems when the tick value wraps 80 * around 2**32: 81 */ 82 drm_linux_timer_hz_mask = 1; 83 while (drm_linux_timer_hz_mask < (unsigned long)hz) 84 drm_linux_timer_hz_mask *= 2; 85 drm_linux_timer_hz_mask--; 86 } 87 SYSINIT(drm_linux_timer, SI_SUB_DRIVERS, SI_ORDER_FIRST, drm_linux_timer_init, NULL); 88 89 static const drm_pci_id_list_t * 90 drm_find_description(int vendor, int device, const drm_pci_id_list_t *idlist) 91 { 92 int i = 0; 93 94 for (i = 0; idlist[i].vendor != 0; i++) { 95 if ((idlist[i].vendor == vendor) && 96 ((idlist[i].device == device) || 97 (idlist[i].device == 0))) { 98 return (&idlist[i]); 99 } 100 } 101 return (NULL); 102 } 103 104 /* 105 * drm_probe_helper: called by a driver at the end of its probe 106 * method. 107 */ 108 int 109 drm_probe_helper(device_t kdev, const drm_pci_id_list_t *idlist) 110 { 111 const drm_pci_id_list_t *id_entry; 112 int vendor, device; 113 114 vendor = pci_get_vendor(kdev); 115 device = pci_get_device(kdev); 116 117 if (pci_get_class(kdev) != PCIC_DISPLAY || 118 (pci_get_subclass(kdev) != PCIS_DISPLAY_VGA && 119 pci_get_subclass(kdev) != PCIS_DISPLAY_OTHER)) 120 return (-ENXIO); 121 122 id_entry = drm_find_description(vendor, device, idlist); 123 if (id_entry != NULL) { 124 if (device_get_desc(kdev) == NULL) { 125 DRM_DEBUG("%s desc: %s\n", 126 device_get_nameunit(kdev), id_entry->name); 127 device_set_desc(kdev, id_entry->name); 128 } 129 return (0); 130 } 131 132 return (-ENXIO); 133 } 134 135 /* 136 * drm_attach_helper: called by a driver at the end of its attach 137 * method. 138 */ 139 int 140 drm_attach_helper(device_t kdev, const drm_pci_id_list_t *idlist, 141 struct drm_driver *driver) 142 { 143 struct drm_device *dev; 144 int vendor, device; 145 int ret; 146 147 dev = device_get_softc(kdev); 148 149 vendor = pci_get_vendor(kdev); 150 device = pci_get_device(kdev); 151 dev->id_entry = drm_find_description(vendor, device, idlist); 152 153 ret = drm_get_pci_dev(kdev, dev, driver); 154 155 return (ret); 156 } 157 158 int 159 drm_generic_suspend(device_t kdev) 160 { 161 struct drm_device *dev; 162 int error; 163 164 DRM_DEBUG_KMS("Starting suspend\n"); 165 166 dev = device_get_softc(kdev); 167 if (dev->driver->suspend) { 168 pm_message_t state; 169 170 state.event = PM_EVENT_SUSPEND; 171 error = -dev->driver->suspend(dev, state); 172 if (error) 173 goto out; 174 } 175 176 error = bus_generic_suspend(kdev); 177 178 out: 179 DRM_DEBUG_KMS("Finished suspend: %d\n", error); 180 181 return error; 182 } 183 184 int 185 drm_generic_resume(device_t kdev) 186 { 187 struct drm_device *dev; 188 int error; 189 190 DRM_DEBUG_KMS("Starting resume\n"); 191 192 dev = device_get_softc(kdev); 193 if (dev->driver->resume) { 194 error = -dev->driver->resume(dev); 195 if (error) 196 goto out; 197 } 198 199 error = bus_generic_resume(kdev); 200 201 out: 202 DRM_DEBUG_KMS("Finished resume: %d\n", error); 203 204 return error; 205 } 206 207 int 208 drm_generic_detach(device_t kdev) 209 { 210 struct drm_device *dev; 211 int i; 212 213 dev = device_get_softc(kdev); 214 215 drm_put_dev(dev); 216 217 /* Clean up PCI resources allocated by drm_bufs.c. We're not really 218 * worried about resource consumption while the DRM is inactive (between 219 * lastclose and firstopen or unload) because these aren't actually 220 * taking up KVA, just keeping the PCI resource allocated. 221 */ 222 for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) { 223 if (dev->pcir[i] == NULL) 224 continue; 225 bus_release_resource(dev->dev, SYS_RES_MEMORY, 226 dev->pcirid[i], dev->pcir[i]); 227 dev->pcir[i] = NULL; 228 } 229 230 if (pci_disable_busmaster(dev->dev)) 231 DRM_ERROR("Request to disable bus-master failed.\n"); 232 233 return (0); 234 } 235 236 int 237 drm_add_busid_modesetting(struct drm_device *dev, struct sysctl_ctx_list *ctx, 238 struct sysctl_oid *top) 239 { 240 struct sysctl_oid *oid; 241 242 snprintf(dev->busid_str, sizeof(dev->busid_str), 243 "pci:%04x:%02x:%02x.%d", dev->pci_domain, dev->pci_bus, 244 dev->pci_slot, dev->pci_func); 245 oid = SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(top), OID_AUTO, "busid", 246 CTLFLAG_RD, dev->busid_str, 0, NULL); 247 if (oid == NULL) 248 return (-ENOMEM); 249 dev->modesetting = (dev->driver->driver_features & DRIVER_MODESET) != 0; 250 oid = SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(top), OID_AUTO, 251 "modesetting", CTLFLAG_RD, &dev->modesetting, 0, NULL); 252 if (oid == NULL) 253 return (-ENOMEM); 254 255 return (0); 256 } 257 258 static int 259 drm_device_find_capability(struct drm_device *dev, int cap) 260 { 261 262 return (pci_find_cap(dev->dev, cap, NULL) == 0); 263 } 264 265 int 266 drm_pci_device_is_agp(struct drm_device *dev) 267 { 268 if (dev->driver->device_is_agp != NULL) { 269 int ret; 270 271 /* device_is_agp returns a tristate, 0 = not AGP, 1 = definitely 272 * AGP, 2 = fall back to PCI capability 273 */ 274 ret = (*dev->driver->device_is_agp)(dev); 275 if (ret != DRM_MIGHT_BE_AGP) 276 return ret; 277 } 278 279 return (drm_device_find_capability(dev, PCIY_AGP)); 280 } 281 282 int 283 drm_pci_device_is_pcie(struct drm_device *dev) 284 { 285 286 return (drm_device_find_capability(dev, PCIY_EXPRESS)); 287 } 288 289 static bool 290 dmi_found(const struct dmi_system_id *dsi) 291 { 292 char *hw_vendor, *hw_prod; 293 int i, slot; 294 bool res; 295 296 hw_vendor = kern_getenv("smbios.planar.maker"); 297 hw_prod = kern_getenv("smbios.planar.product"); 298 res = true; 299 for (i = 0; i < nitems(dsi->matches); i++) { 300 slot = dsi->matches[i].slot; 301 switch (slot) { 302 case DMI_NONE: 303 break; 304 case DMI_SYS_VENDOR: 305 case DMI_BOARD_VENDOR: 306 if (hw_vendor != NULL && 307 !strcmp(hw_vendor, dsi->matches[i].substr)) { 308 break; 309 } else { 310 res = false; 311 goto out; 312 } 313 case DMI_PRODUCT_NAME: 314 case DMI_BOARD_NAME: 315 if (hw_prod != NULL && 316 !strcmp(hw_prod, dsi->matches[i].substr)) { 317 break; 318 } else { 319 res = false; 320 goto out; 321 } 322 default: 323 res = false; 324 goto out; 325 } 326 } 327 out: 328 freeenv(hw_vendor); 329 freeenv(hw_prod); 330 331 return (res); 332 } 333 334 bool 335 dmi_check_system(const struct dmi_system_id *sysid) 336 { 337 const struct dmi_system_id *dsi; 338 bool res; 339 340 for (res = false, dsi = sysid; dsi->matches[0].slot != 0 ; dsi++) { 341 if (dmi_found(dsi)) { 342 res = true; 343 if (dsi->callback != NULL && dsi->callback(dsi)) 344 break; 345 } 346 } 347 return (res); 348 } 349 350 int 351 drm_mtrr_add(unsigned long offset, unsigned long size, unsigned int flags) 352 { 353 int act; 354 struct mem_range_desc mrdesc; 355 356 mrdesc.mr_base = offset; 357 mrdesc.mr_len = size; 358 mrdesc.mr_flags = flags; 359 act = MEMRANGE_SET_UPDATE; 360 strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); 361 return (-mem_range_attr_set(&mrdesc, &act)); 362 } 363 364 int 365 drm_mtrr_del(int handle __unused, unsigned long offset, unsigned long size, 366 unsigned int flags) 367 { 368 int act; 369 struct mem_range_desc mrdesc; 370 371 mrdesc.mr_base = offset; 372 mrdesc.mr_len = size; 373 mrdesc.mr_flags = flags; 374 act = MEMRANGE_SET_REMOVE; 375 strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); 376 return (-mem_range_attr_set(&mrdesc, &act)); 377 } 378 379 void 380 drm_clflush_pages(vm_page_t *pages, unsigned long num_pages) 381 { 382 383 #if defined(__i386__) || defined(__amd64__) 384 pmap_invalidate_cache_pages(pages, num_pages); 385 #else 386 DRM_ERROR("drm_clflush_pages not implemented on this architecture"); 387 #endif 388 } 389 390 void 391 drm_clflush_virt_range(char *addr, unsigned long length) 392 { 393 394 #if defined(__i386__) || defined(__amd64__) 395 pmap_invalidate_cache_range((vm_offset_t)addr, 396 (vm_offset_t)addr + length, TRUE); 397 #else 398 DRM_ERROR("drm_clflush_virt_range not implemented on this architecture"); 399 #endif 400 } 401 402 void 403 hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize, 404 char *linebuf, size_t linebuflen, bool ascii __unused) 405 { 406 int i, j, c; 407 408 i = j = 0; 409 410 while (i < len && j <= linebuflen) { 411 c = ((const char *)buf)[i]; 412 413 if (i != 0) { 414 if (i % rowsize == 0) { 415 /* Newline required. */ 416 sprintf(linebuf + j, "\n"); 417 ++j; 418 } else if (i % groupsize == 0) { 419 /* Space required. */ 420 sprintf(linebuf + j, " "); 421 ++j; 422 } 423 } 424 425 if (j > linebuflen - 1) 426 break; 427 428 sprintf(linebuf + j, "%02X", c); 429 j += 2; 430 431 ++i; 432 } 433 434 if (j <= linebuflen) 435 sprintf(linebuf + j, "\n"); 436 } 437 438 #if DRM_LINUX 439 440 #include <sys/sysproto.h> 441 442 MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1); 443 444 #define LINUX_IOCTL_DRM_MIN 0x6400 445 #define LINUX_IOCTL_DRM_MAX 0x64ff 446 447 static linux_ioctl_function_t drm_linux_ioctl; 448 static struct linux_ioctl_handler drm_handler = {drm_linux_ioctl, 449 LINUX_IOCTL_DRM_MIN, LINUX_IOCTL_DRM_MAX}; 450 451 /* The bits for in/out are switched on Linux */ 452 #define LINUX_IOC_IN IOC_OUT 453 #define LINUX_IOC_OUT IOC_IN 454 455 static int 456 drm_linux_ioctl(DRM_STRUCTPROC *p, struct linux_ioctl_args* args) 457 { 458 int error; 459 int cmd = args->cmd; 460 461 args->cmd &= ~(LINUX_IOC_IN | LINUX_IOC_OUT); 462 if (cmd & LINUX_IOC_IN) 463 args->cmd |= IOC_IN; 464 if (cmd & LINUX_IOC_OUT) 465 args->cmd |= IOC_OUT; 466 467 error = ioctl(p, (struct ioctl_args *)args); 468 469 return error; 470 } 471 #endif /* DRM_LINUX */ 472 473 static int 474 drm_modevent(module_t mod, int type, void *data) 475 { 476 477 switch (type) { 478 case MOD_LOAD: 479 TUNABLE_INT_FETCH("drm.debug", &drm_debug); 480 TUNABLE_INT_FETCH("drm.notyet", &drm_notyet); 481 break; 482 } 483 return (0); 484 } 485 486 static moduledata_t drm_mod = { 487 "drmn", 488 drm_modevent, 489 0 490 }; 491 492 DECLARE_MODULE(drmn, drm_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 493 MODULE_VERSION(drmn, 1); 494 MODULE_DEPEND(drmn, agp, 1, 1, 1); 495 MODULE_DEPEND(drmn, pci, 1, 1, 1); 496 MODULE_DEPEND(drmn, mem, 1, 1, 1); 497 MODULE_DEPEND(drmn, iicbus, 1, 1, 1); 498