diff options
author | Dave Airlie <airlied@redhat.com> | 2018-09-26 21:06:46 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-09-26 21:06:46 -0400 |
commit | bf78296ab1cb215d0609ac6cff4e43e941e51265 (patch) | |
tree | a193615b327d9ee538e71ca5f13bbfb4f3db4e6b /drivers/gpu/drm/i915/intel_overlay.c | |
parent | 18eb2f6e19d77900695987e3a2b775cccbe5b84e (diff) | |
parent | 6bf4ca7fbc85d80446ac01c0d1d77db4d91a6d84 (diff) |
BackMerge v4.19-rc5 into drm-next
Sean Paul requested an -rc5 backmerge from some sun4i fixes.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_overlay.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 228 |
1 files changed, 75 insertions, 153 deletions
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index c2f10d899329..443dfaefd7a6 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -181,8 +181,9 @@ struct intel_overlay { | |||
181 | u32 brightness, contrast, saturation; | 181 | u32 brightness, contrast, saturation; |
182 | u32 old_xscale, old_yscale; | 182 | u32 old_xscale, old_yscale; |
183 | /* register access */ | 183 | /* register access */ |
184 | u32 flip_addr; | ||
185 | struct drm_i915_gem_object *reg_bo; | 184 | struct drm_i915_gem_object *reg_bo; |
185 | struct overlay_registers __iomem *regs; | ||
186 | u32 flip_addr; | ||
186 | /* flip handling */ | 187 | /* flip handling */ |
187 | struct i915_gem_active last_flip; | 188 | struct i915_gem_active last_flip; |
188 | }; | 189 | }; |
@@ -210,29 +211,6 @@ static void i830_overlay_clock_gating(struct drm_i915_private *dev_priv, | |||
210 | PCI_DEVFN(0, 0), I830_CLOCK_GATE, val); | 211 | PCI_DEVFN(0, 0), I830_CLOCK_GATE, val); |
211 | } | 212 | } |
212 | 213 | ||
213 | static struct overlay_registers __iomem * | ||
214 | intel_overlay_map_regs(struct intel_overlay *overlay) | ||
215 | { | ||
216 | struct drm_i915_private *dev_priv = overlay->i915; | ||
217 | struct overlay_registers __iomem *regs; | ||
218 | |||
219 | if (OVERLAY_NEEDS_PHYSICAL(dev_priv)) | ||
220 | regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr; | ||
221 | else | ||
222 | regs = io_mapping_map_wc(&dev_priv->ggtt.iomap, | ||
223 | overlay->flip_addr, | ||
224 | PAGE_SIZE); | ||
225 | |||
226 | return regs; | ||
227 | } | ||
228 | |||
229 | static void intel_overlay_unmap_regs(struct intel_overlay *overlay, | ||
230 | struct overlay_registers __iomem *regs) | ||
231 | { | ||
232 | if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915)) | ||
233 | io_mapping_unmap(regs); | ||
234 | } | ||
235 | |||
236 | static void intel_overlay_submit_request(struct intel_overlay *overlay, | 214 | static void intel_overlay_submit_request(struct intel_overlay *overlay, |
237 | struct i915_request *rq, | 215 | struct i915_request *rq, |
238 | i915_gem_retire_fn retire) | 216 | i915_gem_retire_fn retire) |
@@ -784,13 +762,13 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
784 | struct drm_i915_gem_object *new_bo, | 762 | struct drm_i915_gem_object *new_bo, |
785 | struct put_image_params *params) | 763 | struct put_image_params *params) |
786 | { | 764 | { |
787 | int ret, tmp_width; | 765 | struct overlay_registers __iomem *regs = overlay->regs; |
788 | struct overlay_registers __iomem *regs; | ||
789 | bool scale_changed = false; | ||
790 | struct drm_i915_private *dev_priv = overlay->i915; | 766 | struct drm_i915_private *dev_priv = overlay->i915; |
791 | u32 swidth, swidthsw, sheight, ostride; | 767 | u32 swidth, swidthsw, sheight, ostride; |
792 | enum pipe pipe = overlay->crtc->pipe; | 768 | enum pipe pipe = overlay->crtc->pipe; |
769 | bool scale_changed = false; | ||
793 | struct i915_vma *vma; | 770 | struct i915_vma *vma; |
771 | int ret, tmp_width; | ||
794 | 772 | ||
795 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | 773 | lockdep_assert_held(&dev_priv->drm.struct_mutex); |
796 | WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)); | 774 | WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)); |
@@ -815,30 +793,19 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
815 | 793 | ||
816 | if (!overlay->active) { | 794 | if (!overlay->active) { |
817 | u32 oconfig; | 795 | u32 oconfig; |
818 | regs = intel_overlay_map_regs(overlay); | 796 | |
819 | if (!regs) { | ||
820 | ret = -ENOMEM; | ||
821 | goto out_unpin; | ||
822 | } | ||
823 | oconfig = OCONF_CC_OUT_8BIT; | 797 | oconfig = OCONF_CC_OUT_8BIT; |
824 | if (IS_GEN4(dev_priv)) | 798 | if (IS_GEN4(dev_priv)) |
825 | oconfig |= OCONF_CSC_MODE_BT709; | 799 | oconfig |= OCONF_CSC_MODE_BT709; |
826 | oconfig |= pipe == 0 ? | 800 | oconfig |= pipe == 0 ? |
827 | OCONF_PIPE_A : OCONF_PIPE_B; | 801 | OCONF_PIPE_A : OCONF_PIPE_B; |
828 | iowrite32(oconfig, ®s->OCONFIG); | 802 | iowrite32(oconfig, ®s->OCONFIG); |
829 | intel_overlay_unmap_regs(overlay, regs); | ||
830 | 803 | ||
831 | ret = intel_overlay_on(overlay); | 804 | ret = intel_overlay_on(overlay); |
832 | if (ret != 0) | 805 | if (ret != 0) |
833 | goto out_unpin; | 806 | goto out_unpin; |
834 | } | 807 | } |
835 | 808 | ||
836 | regs = intel_overlay_map_regs(overlay); | ||
837 | if (!regs) { | ||
838 | ret = -ENOMEM; | ||
839 | goto out_unpin; | ||
840 | } | ||
841 | |||
842 | iowrite32((params->dst_y << 16) | params->dst_x, ®s->DWINPOS); | 809 | iowrite32((params->dst_y << 16) | params->dst_x, ®s->DWINPOS); |
843 | iowrite32((params->dst_h << 16) | params->dst_w, ®s->DWINSZ); | 810 | iowrite32((params->dst_h << 16) | params->dst_w, ®s->DWINSZ); |
844 | 811 | ||
@@ -882,8 +849,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
882 | 849 | ||
883 | iowrite32(overlay_cmd_reg(params), ®s->OCMD); | 850 | iowrite32(overlay_cmd_reg(params), ®s->OCMD); |
884 | 851 | ||
885 | intel_overlay_unmap_regs(overlay, regs); | ||
886 | |||
887 | ret = intel_overlay_continue(overlay, vma, scale_changed); | 852 | ret = intel_overlay_continue(overlay, vma, scale_changed); |
888 | if (ret) | 853 | if (ret) |
889 | goto out_unpin; | 854 | goto out_unpin; |
@@ -901,7 +866,6 @@ out_pin_section: | |||
901 | int intel_overlay_switch_off(struct intel_overlay *overlay) | 866 | int intel_overlay_switch_off(struct intel_overlay *overlay) |
902 | { | 867 | { |
903 | struct drm_i915_private *dev_priv = overlay->i915; | 868 | struct drm_i915_private *dev_priv = overlay->i915; |
904 | struct overlay_registers __iomem *regs; | ||
905 | int ret; | 869 | int ret; |
906 | 870 | ||
907 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | 871 | lockdep_assert_held(&dev_priv->drm.struct_mutex); |
@@ -918,9 +882,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay) | |||
918 | if (ret != 0) | 882 | if (ret != 0) |
919 | return ret; | 883 | return ret; |
920 | 884 | ||
921 | regs = intel_overlay_map_regs(overlay); | 885 | iowrite32(0, &overlay->regs->OCMD); |
922 | iowrite32(0, ®s->OCMD); | ||
923 | intel_overlay_unmap_regs(overlay, regs); | ||
924 | 886 | ||
925 | return intel_overlay_off(overlay); | 887 | return intel_overlay_off(overlay); |
926 | } | 888 | } |
@@ -1305,7 +1267,6 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data, | |||
1305 | struct drm_intel_overlay_attrs *attrs = data; | 1267 | struct drm_intel_overlay_attrs *attrs = data; |
1306 | struct drm_i915_private *dev_priv = to_i915(dev); | 1268 | struct drm_i915_private *dev_priv = to_i915(dev); |
1307 | struct intel_overlay *overlay; | 1269 | struct intel_overlay *overlay; |
1308 | struct overlay_registers __iomem *regs; | ||
1309 | int ret; | 1270 | int ret; |
1310 | 1271 | ||
1311 | overlay = dev_priv->overlay; | 1272 | overlay = dev_priv->overlay; |
@@ -1345,15 +1306,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data, | |||
1345 | overlay->contrast = attrs->contrast; | 1306 | overlay->contrast = attrs->contrast; |
1346 | overlay->saturation = attrs->saturation; | 1307 | overlay->saturation = attrs->saturation; |
1347 | 1308 | ||
1348 | regs = intel_overlay_map_regs(overlay); | 1309 | update_reg_attrs(overlay, overlay->regs); |
1349 | if (!regs) { | ||
1350 | ret = -ENOMEM; | ||
1351 | goto out_unlock; | ||
1352 | } | ||
1353 | |||
1354 | update_reg_attrs(overlay, regs); | ||
1355 | |||
1356 | intel_overlay_unmap_regs(overlay, regs); | ||
1357 | 1310 | ||
1358 | if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { | 1311 | if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { |
1359 | if (IS_GEN2(dev_priv)) | 1312 | if (IS_GEN2(dev_priv)) |
@@ -1386,12 +1339,47 @@ out_unlock: | |||
1386 | return ret; | 1339 | return ret; |
1387 | } | 1340 | } |
1388 | 1341 | ||
1342 | static int get_registers(struct intel_overlay *overlay, bool use_phys) | ||
1343 | { | ||
1344 | struct drm_i915_gem_object *obj; | ||
1345 | struct i915_vma *vma; | ||
1346 | int err; | ||
1347 | |||
1348 | obj = i915_gem_object_create_stolen(overlay->i915, PAGE_SIZE); | ||
1349 | if (obj == NULL) | ||
1350 | obj = i915_gem_object_create_internal(overlay->i915, PAGE_SIZE); | ||
1351 | if (IS_ERR(obj)) | ||
1352 | return PTR_ERR(obj); | ||
1353 | |||
1354 | vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE); | ||
1355 | if (IS_ERR(vma)) { | ||
1356 | err = PTR_ERR(vma); | ||
1357 | goto err_put_bo; | ||
1358 | } | ||
1359 | |||
1360 | if (use_phys) | ||
1361 | overlay->flip_addr = sg_dma_address(obj->mm.pages->sgl); | ||
1362 | else | ||
1363 | overlay->flip_addr = i915_ggtt_offset(vma); | ||
1364 | overlay->regs = i915_vma_pin_iomap(vma); | ||
1365 | i915_vma_unpin(vma); | ||
1366 | |||
1367 | if (IS_ERR(overlay->regs)) { | ||
1368 | err = PTR_ERR(overlay->regs); | ||
1369 | goto err_put_bo; | ||
1370 | } | ||
1371 | |||
1372 | overlay->reg_bo = obj; | ||
1373 | return 0; | ||
1374 | |||
1375 | err_put_bo: | ||
1376 | i915_gem_object_put(obj); | ||
1377 | return err; | ||
1378 | } | ||
1379 | |||
1389 | void intel_setup_overlay(struct drm_i915_private *dev_priv) | 1380 | void intel_setup_overlay(struct drm_i915_private *dev_priv) |
1390 | { | 1381 | { |
1391 | struct intel_overlay *overlay; | 1382 | struct intel_overlay *overlay; |
1392 | struct drm_i915_gem_object *reg_bo; | ||
1393 | struct overlay_registers __iomem *regs; | ||
1394 | struct i915_vma *vma = NULL; | ||
1395 | int ret; | 1383 | int ret; |
1396 | 1384 | ||
1397 | if (!HAS_OVERLAY(dev_priv)) | 1385 | if (!HAS_OVERLAY(dev_priv)) |
@@ -1401,46 +1389,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv) | |||
1401 | if (!overlay) | 1389 | if (!overlay) |
1402 | return; | 1390 | return; |
1403 | 1391 | ||
1404 | mutex_lock(&dev_priv->drm.struct_mutex); | ||
1405 | if (WARN_ON(dev_priv->overlay)) | ||
1406 | goto out_free; | ||
1407 | |||
1408 | overlay->i915 = dev_priv; | 1392 | overlay->i915 = dev_priv; |
1409 | 1393 | ||
1410 | reg_bo = NULL; | ||
1411 | if (!OVERLAY_NEEDS_PHYSICAL(dev_priv)) | ||
1412 | reg_bo = i915_gem_object_create_stolen(dev_priv, PAGE_SIZE); | ||
1413 | if (reg_bo == NULL) | ||
1414 | reg_bo = i915_gem_object_create(dev_priv, PAGE_SIZE); | ||
1415 | if (IS_ERR(reg_bo)) | ||
1416 | goto out_free; | ||
1417 | overlay->reg_bo = reg_bo; | ||
1418 | |||
1419 | if (OVERLAY_NEEDS_PHYSICAL(dev_priv)) { | ||
1420 | ret = i915_gem_object_attach_phys(reg_bo, PAGE_SIZE); | ||
1421 | if (ret) { | ||
1422 | DRM_ERROR("failed to attach phys overlay regs\n"); | ||
1423 | goto out_free_bo; | ||
1424 | } | ||
1425 | overlay->flip_addr = reg_bo->phys_handle->busaddr; | ||
1426 | } else { | ||
1427 | vma = i915_gem_object_ggtt_pin(reg_bo, NULL, | ||
1428 | 0, PAGE_SIZE, PIN_MAPPABLE); | ||
1429 | if (IS_ERR(vma)) { | ||
1430 | DRM_ERROR("failed to pin overlay register bo\n"); | ||
1431 | ret = PTR_ERR(vma); | ||
1432 | goto out_free_bo; | ||
1433 | } | ||
1434 | overlay->flip_addr = i915_ggtt_offset(vma); | ||
1435 | |||
1436 | ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); | ||
1437 | if (ret) { | ||
1438 | DRM_ERROR("failed to move overlay register bo into the GTT\n"); | ||
1439 | goto out_unpin_bo; | ||
1440 | } | ||
1441 | } | ||
1442 | |||
1443 | /* init all values */ | ||
1444 | overlay->color_key = 0x0101fe; | 1394 | overlay->color_key = 0x0101fe; |
1445 | overlay->color_key_enabled = true; | 1395 | overlay->color_key_enabled = true; |
1446 | overlay->brightness = -19; | 1396 | overlay->brightness = -19; |
@@ -1449,44 +1399,51 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv) | |||
1449 | 1399 | ||
1450 | init_request_active(&overlay->last_flip, NULL); | 1400 | init_request_active(&overlay->last_flip, NULL); |
1451 | 1401 | ||
1452 | regs = intel_overlay_map_regs(overlay); | 1402 | mutex_lock(&dev_priv->drm.struct_mutex); |
1453 | if (!regs) | 1403 | |
1454 | goto out_unpin_bo; | 1404 | ret = get_registers(overlay, OVERLAY_NEEDS_PHYSICAL(dev_priv)); |
1405 | if (ret) | ||
1406 | goto out_free; | ||
1407 | |||
1408 | ret = i915_gem_object_set_to_gtt_domain(overlay->reg_bo, true); | ||
1409 | if (ret) | ||
1410 | goto out_reg_bo; | ||
1455 | 1411 | ||
1456 | memset_io(regs, 0, sizeof(struct overlay_registers)); | 1412 | mutex_unlock(&dev_priv->drm.struct_mutex); |
1457 | update_polyphase_filter(regs); | ||
1458 | update_reg_attrs(overlay, regs); | ||
1459 | 1413 | ||
1460 | intel_overlay_unmap_regs(overlay, regs); | 1414 | memset_io(overlay->regs, 0, sizeof(struct overlay_registers)); |
1415 | update_polyphase_filter(overlay->regs); | ||
1416 | update_reg_attrs(overlay, overlay->regs); | ||
1461 | 1417 | ||
1462 | dev_priv->overlay = overlay; | 1418 | dev_priv->overlay = overlay; |
1463 | mutex_unlock(&dev_priv->drm.struct_mutex); | 1419 | DRM_INFO("Initialized overlay support.\n"); |
1464 | DRM_INFO("initialized overlay support\n"); | ||
1465 | return; | 1420 | return; |
1466 | 1421 | ||
1467 | out_unpin_bo: | 1422 | out_reg_bo: |
1468 | if (vma) | 1423 | i915_gem_object_put(overlay->reg_bo); |
1469 | i915_vma_unpin(vma); | ||
1470 | out_free_bo: | ||
1471 | i915_gem_object_put(reg_bo); | ||
1472 | out_free: | 1424 | out_free: |
1473 | mutex_unlock(&dev_priv->drm.struct_mutex); | 1425 | mutex_unlock(&dev_priv->drm.struct_mutex); |
1474 | kfree(overlay); | 1426 | kfree(overlay); |
1475 | return; | ||
1476 | } | 1427 | } |
1477 | 1428 | ||
1478 | void intel_cleanup_overlay(struct drm_i915_private *dev_priv) | 1429 | void intel_cleanup_overlay(struct drm_i915_private *dev_priv) |
1479 | { | 1430 | { |
1480 | if (!dev_priv->overlay) | 1431 | struct intel_overlay *overlay; |
1432 | |||
1433 | overlay = fetch_and_zero(&dev_priv->overlay); | ||
1434 | if (!overlay) | ||
1481 | return; | 1435 | return; |
1482 | 1436 | ||
1483 | /* The bo's should be free'd by the generic code already. | 1437 | /* |
1438 | * The bo's should be free'd by the generic code already. | ||
1484 | * Furthermore modesetting teardown happens beforehand so the | 1439 | * Furthermore modesetting teardown happens beforehand so the |
1485 | * hardware should be off already */ | 1440 | * hardware should be off already. |
1486 | WARN_ON(dev_priv->overlay->active); | 1441 | */ |
1442 | WARN_ON(overlay->active); | ||
1443 | |||
1444 | i915_gem_object_put(overlay->reg_bo); | ||
1487 | 1445 | ||
1488 | i915_gem_object_put(dev_priv->overlay->reg_bo); | 1446 | kfree(overlay); |
1489 | kfree(dev_priv->overlay); | ||
1490 | } | 1447 | } |
1491 | 1448 | ||
1492 | #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) | 1449 | #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) |
@@ -1498,37 +1455,11 @@ struct intel_overlay_error_state { | |||
1498 | u32 isr; | 1455 | u32 isr; |
1499 | }; | 1456 | }; |
1500 | 1457 | ||
1501 | static struct overlay_registers __iomem * | ||
1502 | intel_overlay_map_regs_atomic(struct intel_overlay *overlay) | ||
1503 | { | ||
1504 | struct drm_i915_private *dev_priv = overlay->i915; | ||
1505 | struct overlay_registers __iomem *regs; | ||
1506 | |||
1507 | if (OVERLAY_NEEDS_PHYSICAL(dev_priv)) | ||
1508 | /* Cast to make sparse happy, but it's wc memory anyway, so | ||
1509 | * equivalent to the wc io mapping on X86. */ | ||
1510 | regs = (struct overlay_registers __iomem *) | ||
1511 | overlay->reg_bo->phys_handle->vaddr; | ||
1512 | else | ||
1513 | regs = io_mapping_map_atomic_wc(&dev_priv->ggtt.iomap, | ||
1514 | overlay->flip_addr); | ||
1515 | |||
1516 | return regs; | ||
1517 | } | ||
1518 | |||
1519 | static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay, | ||
1520 | struct overlay_registers __iomem *regs) | ||
1521 | { | ||
1522 | if (!OVERLAY_NEEDS_PHYSICAL(overlay->i915)) | ||
1523 | io_mapping_unmap_atomic(regs); | ||
1524 | } | ||
1525 | |||
1526 | struct intel_overlay_error_state * | 1458 | struct intel_overlay_error_state * |
1527 | intel_overlay_capture_error_state(struct drm_i915_private *dev_priv) | 1459 | intel_overlay_capture_error_state(struct drm_i915_private *dev_priv) |
1528 | { | 1460 | { |
1529 | struct intel_overlay *overlay = dev_priv->overlay; | 1461 | struct intel_overlay *overlay = dev_priv->overlay; |
1530 | struct intel_overlay_error_state *error; | 1462 | struct intel_overlay_error_state *error; |
1531 | struct overlay_registers __iomem *regs; | ||
1532 | 1463 | ||
1533 | if (!overlay || !overlay->active) | 1464 | if (!overlay || !overlay->active) |
1534 | return NULL; | 1465 | return NULL; |
@@ -1541,18 +1472,9 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv) | |||
1541 | error->isr = I915_READ(ISR); | 1472 | error->isr = I915_READ(ISR); |
1542 | error->base = overlay->flip_addr; | 1473 | error->base = overlay->flip_addr; |
1543 | 1474 | ||
1544 | regs = intel_overlay_map_regs_atomic(overlay); | 1475 | memcpy_fromio(&error->regs, overlay->regs, sizeof(error->regs)); |
1545 | if (!regs) | ||
1546 | goto err; | ||
1547 | |||
1548 | memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); | ||
1549 | intel_overlay_unmap_regs_atomic(overlay, regs); | ||
1550 | 1476 | ||
1551 | return error; | 1477 | return error; |
1552 | |||
1553 | err: | ||
1554 | kfree(error); | ||
1555 | return NULL; | ||
1556 | } | 1478 | } |
1557 | 1479 | ||
1558 | void | 1480 | void |