diff options
| -rw-r--r-- | drivers/gpu/drm/drm_edid.c | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 37 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_gart.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/si.c | 4 |
5 files changed, 73 insertions, 18 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 5873e481e5d2..a8743c399e83 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
| @@ -1039,6 +1039,24 @@ mode_in_range(const struct drm_display_mode *mode, struct edid *edid, | |||
| 1039 | return true; | 1039 | return true; |
| 1040 | } | 1040 | } |
| 1041 | 1041 | ||
| 1042 | static bool valid_inferred_mode(const struct drm_connector *connector, | ||
| 1043 | const struct drm_display_mode *mode) | ||
| 1044 | { | ||
| 1045 | struct drm_display_mode *m; | ||
| 1046 | bool ok = false; | ||
| 1047 | |||
| 1048 | list_for_each_entry(m, &connector->probed_modes, head) { | ||
| 1049 | if (mode->hdisplay == m->hdisplay && | ||
| 1050 | mode->vdisplay == m->vdisplay && | ||
| 1051 | drm_mode_vrefresh(mode) == drm_mode_vrefresh(m)) | ||
| 1052 | return false; /* duplicated */ | ||
| 1053 | if (mode->hdisplay <= m->hdisplay && | ||
| 1054 | mode->vdisplay <= m->vdisplay) | ||
| 1055 | ok = true; | ||
| 1056 | } | ||
| 1057 | return ok; | ||
| 1058 | } | ||
| 1059 | |||
| 1042 | static int | 1060 | static int |
| 1043 | drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, | 1061 | drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, |
| 1044 | struct detailed_timing *timing) | 1062 | struct detailed_timing *timing) |
| @@ -1048,7 +1066,8 @@ drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, | |||
| 1048 | struct drm_device *dev = connector->dev; | 1066 | struct drm_device *dev = connector->dev; |
| 1049 | 1067 | ||
| 1050 | for (i = 0; i < drm_num_dmt_modes; i++) { | 1068 | for (i = 0; i < drm_num_dmt_modes; i++) { |
| 1051 | if (mode_in_range(drm_dmt_modes + i, edid, timing)) { | 1069 | if (mode_in_range(drm_dmt_modes + i, edid, timing) && |
| 1070 | valid_inferred_mode(connector, drm_dmt_modes + i)) { | ||
| 1052 | newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]); | 1071 | newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]); |
| 1053 | if (newmode) { | 1072 | if (newmode) { |
| 1054 | drm_mode_probed_add(connector, newmode); | 1073 | drm_mode_probed_add(connector, newmode); |
| @@ -1088,7 +1107,8 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, | |||
| 1088 | return modes; | 1107 | return modes; |
| 1089 | 1108 | ||
| 1090 | fixup_mode_1366x768(newmode); | 1109 | fixup_mode_1366x768(newmode); |
| 1091 | if (!mode_in_range(newmode, edid, timing)) { | 1110 | if (!mode_in_range(newmode, edid, timing) || |
| 1111 | !valid_inferred_mode(connector, newmode)) { | ||
| 1092 | drm_mode_destroy(dev, newmode); | 1112 | drm_mode_destroy(dev, newmode); |
| 1093 | continue; | 1113 | continue; |
| 1094 | } | 1114 | } |
| @@ -1116,7 +1136,8 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid, | |||
| 1116 | return modes; | 1136 | return modes; |
| 1117 | 1137 | ||
| 1118 | fixup_mode_1366x768(newmode); | 1138 | fixup_mode_1366x768(newmode); |
| 1119 | if (!mode_in_range(newmode, edid, timing)) { | 1139 | if (!mode_in_range(newmode, edid, timing) || |
| 1140 | !valid_inferred_mode(connector, newmode)) { | ||
| 1120 | drm_mode_destroy(dev, newmode); | 1141 | drm_mode_destroy(dev, newmode); |
| 1121 | continue; | 1142 | continue; |
| 1122 | } | 1143 | } |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f94792626b94..36822b924eb1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -1401,6 +1401,27 @@ i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base, | |||
| 1401 | } | 1401 | } |
| 1402 | } | 1402 | } |
| 1403 | 1403 | ||
| 1404 | static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) | ||
| 1405 | { | ||
| 1406 | struct apertures_struct *ap; | ||
| 1407 | struct pci_dev *pdev = dev_priv->dev->pdev; | ||
| 1408 | bool primary; | ||
| 1409 | |||
| 1410 | ap = alloc_apertures(1); | ||
| 1411 | if (!ap) | ||
| 1412 | return; | ||
| 1413 | |||
| 1414 | ap->ranges[0].base = dev_priv->dev->agp->base; | ||
| 1415 | ap->ranges[0].size = | ||
| 1416 | dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
| 1417 | primary = | ||
| 1418 | pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; | ||
| 1419 | |||
| 1420 | remove_conflicting_framebuffers(ap, "inteldrmfb", primary); | ||
| 1421 | |||
| 1422 | kfree(ap); | ||
| 1423 | } | ||
| 1424 | |||
| 1404 | /** | 1425 | /** |
| 1405 | * i915_driver_load - setup chip and create an initial config | 1426 | * i915_driver_load - setup chip and create an initial config |
| 1406 | * @dev: DRM device | 1427 | * @dev: DRM device |
| @@ -1446,6 +1467,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 1446 | goto free_priv; | 1467 | goto free_priv; |
| 1447 | } | 1468 | } |
| 1448 | 1469 | ||
| 1470 | dev_priv->mm.gtt = intel_gtt_get(); | ||
| 1471 | if (!dev_priv->mm.gtt) { | ||
| 1472 | DRM_ERROR("Failed to initialize GTT\n"); | ||
| 1473 | ret = -ENODEV; | ||
| 1474 | goto put_bridge; | ||
| 1475 | } | ||
| 1476 | |||
| 1477 | i915_kick_out_firmware_fb(dev_priv); | ||
| 1478 | |||
| 1449 | pci_set_master(dev->pdev); | 1479 | pci_set_master(dev->pdev); |
| 1450 | 1480 | ||
| 1451 | /* overlay on gen2 is broken and can't address above 1G */ | 1481 | /* overlay on gen2 is broken and can't address above 1G */ |
| @@ -1471,13 +1501,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 1471 | goto put_bridge; | 1501 | goto put_bridge; |
| 1472 | } | 1502 | } |
| 1473 | 1503 | ||
| 1474 | dev_priv->mm.gtt = intel_gtt_get(); | ||
| 1475 | if (!dev_priv->mm.gtt) { | ||
| 1476 | DRM_ERROR("Failed to initialize GTT\n"); | ||
| 1477 | ret = -ENODEV; | ||
| 1478 | goto out_rmmap; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | aperture_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | 1504 | aperture_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; |
| 1482 | 1505 | ||
| 1483 | dev_priv->mm.gtt_mapping = | 1506 | dev_priv->mm.gtt_mapping = |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 59d44937dd9f..84b648a7ddd8 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
| @@ -289,8 +289,9 @@ int radeon_vm_manager_init(struct radeon_device *rdev) | |||
| 289 | rdev->vm_manager.enabled = false; | 289 | rdev->vm_manager.enabled = false; |
| 290 | 290 | ||
| 291 | /* mark first vm as always in use, it's the system one */ | 291 | /* mark first vm as always in use, it's the system one */ |
| 292 | /* allocate enough for 2 full VM pts */ | ||
| 292 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, | 293 | r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, |
| 293 | rdev->vm_manager.max_pfn * 8, | 294 | rdev->vm_manager.max_pfn * 8 * 2, |
| 294 | RADEON_GEM_DOMAIN_VRAM); | 295 | RADEON_GEM_DOMAIN_VRAM); |
| 295 | if (r) { | 296 | if (r) { |
| 296 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", | 297 | dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", |
| @@ -633,7 +634,15 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 633 | mutex_init(&vm->mutex); | 634 | mutex_init(&vm->mutex); |
| 634 | INIT_LIST_HEAD(&vm->list); | 635 | INIT_LIST_HEAD(&vm->list); |
| 635 | INIT_LIST_HEAD(&vm->va); | 636 | INIT_LIST_HEAD(&vm->va); |
| 636 | vm->last_pfn = 0; | 637 | /* SI requires equal sized PTs for all VMs, so always set |
| 638 | * last_pfn to max_pfn. cayman allows variable sized | ||
| 639 | * pts so we can grow then as needed. Once we switch | ||
| 640 | * to two level pts we can unify this again. | ||
| 641 | */ | ||
| 642 | if (rdev->family >= CHIP_TAHITI) | ||
| 643 | vm->last_pfn = rdev->vm_manager.max_pfn; | ||
| 644 | else | ||
| 645 | vm->last_pfn = 0; | ||
| 637 | /* map the ib pool buffer at 0 in virtual address space, set | 646 | /* map the ib pool buffer at 0 in virtual address space, set |
| 638 | * read only | 647 | * read only |
| 639 | */ | 648 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index f28bd4b7ef98..21ec9f5653ce 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -292,6 +292,7 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
| 292 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | 292 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, |
| 293 | struct drm_file *filp) | 293 | struct drm_file *filp) |
| 294 | { | 294 | { |
| 295 | struct radeon_device *rdev = dev->dev_private; | ||
| 295 | struct drm_radeon_gem_busy *args = data; | 296 | struct drm_radeon_gem_busy *args = data; |
| 296 | struct drm_gem_object *gobj; | 297 | struct drm_gem_object *gobj; |
| 297 | struct radeon_bo *robj; | 298 | struct radeon_bo *robj; |
| @@ -317,13 +318,14 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
| 317 | break; | 318 | break; |
| 318 | } | 319 | } |
| 319 | drm_gem_object_unreference_unlocked(gobj); | 320 | drm_gem_object_unreference_unlocked(gobj); |
| 320 | r = radeon_gem_handle_lockup(robj->rdev, r); | 321 | r = radeon_gem_handle_lockup(rdev, r); |
| 321 | return r; | 322 | return r; |
| 322 | } | 323 | } |
| 323 | 324 | ||
| 324 | int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | 325 | int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, |
| 325 | struct drm_file *filp) | 326 | struct drm_file *filp) |
| 326 | { | 327 | { |
| 328 | struct radeon_device *rdev = dev->dev_private; | ||
| 327 | struct drm_radeon_gem_wait_idle *args = data; | 329 | struct drm_radeon_gem_wait_idle *args = data; |
| 328 | struct drm_gem_object *gobj; | 330 | struct drm_gem_object *gobj; |
| 329 | struct radeon_bo *robj; | 331 | struct radeon_bo *robj; |
| @@ -336,10 +338,10 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
| 336 | robj = gem_to_radeon_bo(gobj); | 338 | robj = gem_to_radeon_bo(gobj); |
| 337 | r = radeon_bo_wait(robj, NULL, false); | 339 | r = radeon_bo_wait(robj, NULL, false); |
| 338 | /* callback hw specific functions if any */ | 340 | /* callback hw specific functions if any */ |
| 339 | if (robj->rdev->asic->ioctl_wait_idle) | 341 | if (rdev->asic->ioctl_wait_idle) |
| 340 | robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); | 342 | robj->rdev->asic->ioctl_wait_idle(rdev, robj); |
| 341 | drm_gem_object_unreference_unlocked(gobj); | 343 | drm_gem_object_unreference_unlocked(gobj); |
| 342 | r = radeon_gem_handle_lockup(robj->rdev, r); | 344 | r = radeon_gem_handle_lockup(rdev, r); |
| 343 | return r; | 345 | return r; |
| 344 | } | 346 | } |
| 345 | 347 | ||
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c7b61f16ecfd..0b0279291a73 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -2365,12 +2365,12 @@ int si_pcie_gart_enable(struct radeon_device *rdev) | |||
| 2365 | WREG32(0x15DC, 0); | 2365 | WREG32(0x15DC, 0); |
| 2366 | 2366 | ||
| 2367 | /* empty context1-15 */ | 2367 | /* empty context1-15 */ |
| 2368 | /* FIXME start with 1G, once using 2 level pt switch to full | 2368 | /* FIXME start with 4G, once using 2 level pt switch to full |
| 2369 | * vm size space | 2369 | * vm size space |
| 2370 | */ | 2370 | */ |
| 2371 | /* set vm size, must be a multiple of 4 */ | 2371 | /* set vm size, must be a multiple of 4 */ |
| 2372 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); | 2372 | WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); |
| 2373 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, (1 << 30) / RADEON_GPU_PAGE_SIZE); | 2373 | WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); |
| 2374 | for (i = 1; i < 16; i++) { | 2374 | for (i = 1; i < 16; i++) { |
| 2375 | if (i < 8) | 2375 | if (i < 8) |
| 2376 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), | 2376 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), |
