diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 71 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_tiling.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 15 |
4 files changed, 56 insertions, 39 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f245c588ae95..ce7914c4c044 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -262,6 +262,7 @@ enum intel_pch { | |||
| 262 | }; | 262 | }; |
| 263 | 263 | ||
| 264 | #define QUIRK_PIPEA_FORCE (1<<0) | 264 | #define QUIRK_PIPEA_FORCE (1<<0) |
| 265 | #define QUIRK_LVDS_SSC_DISABLE (1<<1) | ||
| 265 | 266 | ||
| 266 | struct intel_fbdev; | 267 | struct intel_fbdev; |
| 267 | 268 | ||
| @@ -1194,7 +1195,9 @@ void i915_gem_free_all_phys_object(struct drm_device *dev); | |||
| 1194 | void i915_gem_release(struct drm_device *dev, struct drm_file *file); | 1195 | void i915_gem_release(struct drm_device *dev, struct drm_file *file); |
| 1195 | 1196 | ||
| 1196 | uint32_t | 1197 | uint32_t |
| 1197 | i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj); | 1198 | i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev, |
| 1199 | uint32_t size, | ||
| 1200 | int tiling_mode); | ||
| 1198 | 1201 | ||
| 1199 | /* i915_gem_gtt.c */ | 1202 | /* i915_gem_gtt.c */ |
| 1200 | void i915_gem_restore_gtt_mappings(struct drm_device *dev); | 1203 | void i915_gem_restore_gtt_mappings(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5c0d1247f453..a087e1bf0c2f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -1374,25 +1374,24 @@ i915_gem_free_mmap_offset(struct drm_i915_gem_object *obj) | |||
| 1374 | } | 1374 | } |
| 1375 | 1375 | ||
| 1376 | static uint32_t | 1376 | static uint32_t |
| 1377 | i915_gem_get_gtt_size(struct drm_i915_gem_object *obj) | 1377 | i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode) |
| 1378 | { | 1378 | { |
| 1379 | struct drm_device *dev = obj->base.dev; | 1379 | uint32_t gtt_size; |
| 1380 | uint32_t size; | ||
| 1381 | 1380 | ||
| 1382 | if (INTEL_INFO(dev)->gen >= 4 || | 1381 | if (INTEL_INFO(dev)->gen >= 4 || |
| 1383 | obj->tiling_mode == I915_TILING_NONE) | 1382 | tiling_mode == I915_TILING_NONE) |
| 1384 | return obj->base.size; | 1383 | return size; |
| 1385 | 1384 | ||
| 1386 | /* Previous chips need a power-of-two fence region when tiling */ | 1385 | /* Previous chips need a power-of-two fence region when tiling */ |
| 1387 | if (INTEL_INFO(dev)->gen == 3) | 1386 | if (INTEL_INFO(dev)->gen == 3) |
| 1388 | size = 1024*1024; | 1387 | gtt_size = 1024*1024; |
| 1389 | else | 1388 | else |
| 1390 | size = 512*1024; | 1389 | gtt_size = 512*1024; |
| 1391 | 1390 | ||
| 1392 | while (size < obj->base.size) | 1391 | while (gtt_size < size) |
| 1393 | size <<= 1; | 1392 | gtt_size <<= 1; |
| 1394 | 1393 | ||
| 1395 | return size; | 1394 | return gtt_size; |
| 1396 | } | 1395 | } |
| 1397 | 1396 | ||
| 1398 | /** | 1397 | /** |
| @@ -1403,59 +1402,52 @@ i915_gem_get_gtt_size(struct drm_i915_gem_object *obj) | |||
| 1403 | * potential fence register mapping. | 1402 | * potential fence register mapping. |
| 1404 | */ | 1403 | */ |
| 1405 | static uint32_t | 1404 | static uint32_t |
| 1406 | i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj) | 1405 | i915_gem_get_gtt_alignment(struct drm_device *dev, |
| 1406 | uint32_t size, | ||
| 1407 | int tiling_mode) | ||
| 1407 | { | 1408 | { |
| 1408 | struct drm_device *dev = obj->base.dev; | ||
| 1409 | |||
| 1410 | /* | 1409 | /* |
| 1411 | * Minimum alignment is 4k (GTT page size), but might be greater | 1410 | * Minimum alignment is 4k (GTT page size), but might be greater |
| 1412 | * if a fence register is needed for the object. | 1411 | * if a fence register is needed for the object. |
| 1413 | */ | 1412 | */ |
| 1414 | if (INTEL_INFO(dev)->gen >= 4 || | 1413 | if (INTEL_INFO(dev)->gen >= 4 || |
| 1415 | obj->tiling_mode == I915_TILING_NONE) | 1414 | tiling_mode == I915_TILING_NONE) |
| 1416 | return 4096; | 1415 | return 4096; |
| 1417 | 1416 | ||
| 1418 | /* | 1417 | /* |
| 1419 | * Previous chips need to be aligned to the size of the smallest | 1418 | * Previous chips need to be aligned to the size of the smallest |
| 1420 | * fence register that can contain the object. | 1419 | * fence register that can contain the object. |
| 1421 | */ | 1420 | */ |
| 1422 | return i915_gem_get_gtt_size(obj); | 1421 | return i915_gem_get_gtt_size(dev, size, tiling_mode); |
| 1423 | } | 1422 | } |
| 1424 | 1423 | ||
| 1425 | /** | 1424 | /** |
| 1426 | * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an | 1425 | * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an |
| 1427 | * unfenced object | 1426 | * unfenced object |
| 1428 | * @obj: object to check | 1427 | * @dev: the device |
| 1428 | * @size: size of the object | ||
| 1429 | * @tiling_mode: tiling mode of the object | ||
| 1429 | * | 1430 | * |
| 1430 | * Return the required GTT alignment for an object, only taking into account | 1431 | * Return the required GTT alignment for an object, only taking into account |
| 1431 | * unfenced tiled surface requirements. | 1432 | * unfenced tiled surface requirements. |
| 1432 | */ | 1433 | */ |
| 1433 | uint32_t | 1434 | uint32_t |
| 1434 | i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) | 1435 | i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev, |
| 1436 | uint32_t size, | ||
| 1437 | int tiling_mode) | ||
| 1435 | { | 1438 | { |
| 1436 | struct drm_device *dev = obj->base.dev; | ||
| 1437 | int tile_height; | ||
| 1438 | |||
| 1439 | /* | 1439 | /* |
| 1440 | * Minimum alignment is 4k (GTT page size) for sane hw. | 1440 | * Minimum alignment is 4k (GTT page size) for sane hw. |
| 1441 | */ | 1441 | */ |
| 1442 | if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) || | 1442 | if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) || |
| 1443 | obj->tiling_mode == I915_TILING_NONE) | 1443 | tiling_mode == I915_TILING_NONE) |
| 1444 | return 4096; | 1444 | return 4096; |
| 1445 | 1445 | ||
| 1446 | /* | 1446 | /* Previous hardware however needs to be aligned to a power-of-two |
| 1447 | * Older chips need unfenced tiled buffers to be aligned to the left | 1447 | * tile height. The simplest method for determining this is to reuse |
| 1448 | * edge of an even tile row (where tile rows are counted as if the bo is | 1448 | * the power-of-tile object size. |
| 1449 | * placed in a fenced gtt region). | ||
| 1450 | */ | 1449 | */ |
| 1451 | if (IS_GEN2(dev)) | 1450 | return i915_gem_get_gtt_size(dev, size, tiling_mode); |
| 1452 | tile_height = 16; | ||
| 1453 | else if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) | ||
| 1454 | tile_height = 32; | ||
| 1455 | else | ||
| 1456 | tile_height = 8; | ||
| 1457 | |||
| 1458 | return tile_height * obj->stride * 2; | ||
| 1459 | } | 1451 | } |
| 1460 | 1452 | ||
| 1461 | int | 1453 | int |
| @@ -2744,9 +2736,16 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
| 2744 | return -EINVAL; | 2736 | return -EINVAL; |
| 2745 | } | 2737 | } |
| 2746 | 2738 | ||
| 2747 | fence_size = i915_gem_get_gtt_size(obj); | 2739 | fence_size = i915_gem_get_gtt_size(dev, |
| 2748 | fence_alignment = i915_gem_get_gtt_alignment(obj); | 2740 | obj->base.size, |
| 2749 | unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj); | 2741 | obj->tiling_mode); |
| 2742 | fence_alignment = i915_gem_get_gtt_alignment(dev, | ||
| 2743 | obj->base.size, | ||
| 2744 | obj->tiling_mode); | ||
| 2745 | unfenced_alignment = | ||
| 2746 | i915_gem_get_unfenced_gtt_alignment(dev, | ||
| 2747 | obj->base.size, | ||
| 2748 | obj->tiling_mode); | ||
| 2750 | 2749 | ||
| 2751 | if (alignment == 0) | 2750 | if (alignment == 0) |
| 2752 | alignment = map_and_fenceable ? fence_alignment : | 2751 | alignment = map_and_fenceable ? fence_alignment : |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 82d70fd9e933..99c4faa59d8f 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
| @@ -348,7 +348,9 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
| 348 | /* Rebind if we need a change of alignment */ | 348 | /* Rebind if we need a change of alignment */ |
| 349 | if (!obj->map_and_fenceable) { | 349 | if (!obj->map_and_fenceable) { |
| 350 | u32 unfenced_alignment = | 350 | u32 unfenced_alignment = |
| 351 | i915_gem_get_unfenced_gtt_alignment(obj); | 351 | i915_gem_get_unfenced_gtt_alignment(dev, |
| 352 | obj->base.size, | ||
| 353 | args->tiling_mode); | ||
| 352 | if (obj->gtt_offset & (unfenced_alignment - 1)) | 354 | if (obj->gtt_offset & (unfenced_alignment - 1)) |
| 353 | ret = i915_gem_object_unbind(obj); | 355 | ret = i915_gem_object_unbind(obj); |
| 354 | } | 356 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 21b6f93fe919..0f1c799afea1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -4305,7 +4305,8 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
| 4305 | 4305 | ||
| 4306 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) | 4306 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) |
| 4307 | { | 4307 | { |
| 4308 | return dev_priv->lvds_use_ssc && i915_panel_use_ssc; | 4308 | return dev_priv->lvds_use_ssc && i915_panel_use_ssc |
| 4309 | && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); | ||
| 4309 | } | 4310 | } |
| 4310 | 4311 | ||
| 4311 | static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | 4312 | static int i9xx_crtc_mode_set(struct drm_crtc *crtc, |
| @@ -7810,6 +7811,15 @@ static void quirk_pipea_force (struct drm_device *dev) | |||
| 7810 | DRM_DEBUG_DRIVER("applying pipe a force quirk\n"); | 7811 | DRM_DEBUG_DRIVER("applying pipe a force quirk\n"); |
| 7811 | } | 7812 | } |
| 7812 | 7813 | ||
| 7814 | /* | ||
| 7815 | * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason | ||
| 7816 | */ | ||
| 7817 | static void quirk_ssc_force_disable(struct drm_device *dev) | ||
| 7818 | { | ||
| 7819 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 7820 | dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE; | ||
| 7821 | } | ||
| 7822 | |||
| 7813 | struct intel_quirk { | 7823 | struct intel_quirk { |
| 7814 | int device; | 7824 | int device; |
| 7815 | int subsystem_vendor; | 7825 | int subsystem_vendor; |
| @@ -7838,6 +7848,9 @@ struct intel_quirk intel_quirks[] = { | |||
| 7838 | /* 855 & before need to leave pipe A & dpll A up */ | 7848 | /* 855 & before need to leave pipe A & dpll A up */ |
| 7839 | { 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | 7849 | { 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
| 7840 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | 7850 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
| 7851 | |||
| 7852 | /* Lenovo U160 cannot use SSC on LVDS */ | ||
| 7853 | { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, | ||
| 7841 | }; | 7854 | }; |
| 7842 | 7855 | ||
| 7843 | static void intel_init_quirks(struct drm_device *dev) | 7856 | static void intel_init_quirks(struct drm_device *dev) |
