forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
....@@ -25,11 +25,16 @@
2525 *
2626 **************************************************************************/
2727
28
-#include "vmwgfx_kms.h"
29
-#include <drm/drm_plane_helper.h>
3028 #include <drm/drm_atomic.h>
3129 #include <drm/drm_atomic_helper.h>
30
+#include <drm/drm_damage_helper.h>
31
+#include <drm/drm_fourcc.h>
32
+#include <drm/drm_plane_helper.h>
3233 #include <drm/drm_rect.h>
34
+#include <drm/drm_sysfs.h>
35
+#include <drm/drm_vblank.h>
36
+
37
+#include "vmwgfx_kms.h"
3338
3439 /* Might need a hrtimer here? */
3540 #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
....@@ -63,11 +68,9 @@
6368 if (!image)
6469 return -EINVAL;
6570
66
- cmd = vmw_fifo_reserve(dev_priv, cmd_size);
67
- if (unlikely(cmd == NULL)) {
68
- DRM_ERROR("Fifo reserve failed.\n");
71
+ cmd = VMW_FIFO_RESERVE(dev_priv, cmd_size);
72
+ if (unlikely(cmd == NULL))
6973 return -ENOMEM;
70
- }
7174
7275 memset(cmd, 0, sizeof(*cmd));
7376
....@@ -179,11 +182,12 @@
179182 if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
180183 box->x != 0 || box->y != 0 || box->z != 0 ||
181184 box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
182
- box->d != 1 || box_count != 1) {
185
+ box->d != 1 || box_count != 1 ||
186
+ box->w > 64 || box->h > 64) {
183187 /* TODO handle none page aligned offsets */
184188 /* TODO handle more dst & src != 0 */
185189 /* TODO handle more then one copy */
186
- DRM_ERROR("Cant snoop dma request for cursor!\n");
190
+ DRM_ERROR("Can't snoop dma request for cursor!\n");
187191 DRM_ERROR("(%u, %u, %u) (%u, %u, %u) (%ux%ux%u) %u %u\n",
188192 box->srcx, box->srcy, box->srcz,
189193 box->x, box->y, box->z,
....@@ -456,21 +460,8 @@
456460 struct drm_crtc *crtc = state->crtc;
457461 struct vmw_connector_state *vcs;
458462 struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
459
- struct vmw_private *dev_priv = vmw_priv(crtc->dev);
460
- struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb);
461463
462464 vcs = vmw_connector_state_to_vcs(du->connector.state);
463
-
464
- /* Only one active implicit framebuffer at a time. */
465
- mutex_lock(&dev_priv->global_kms_state_mutex);
466
- if (vcs->is_implicit && dev_priv->implicit_fb &&
467
- !(dev_priv->num_implicit == 1 && du->active_implicit)
468
- && dev_priv->implicit_fb != vfb) {
469
- DRM_ERROR("Multiple implicit framebuffers "
470
- "not supported.\n");
471
- ret = -EINVAL;
472
- }
473
- mutex_unlock(&dev_priv->global_kms_state_mutex);
474465 }
475466
476467
....@@ -493,24 +484,24 @@
493484 struct drm_plane_state *new_state)
494485 {
495486 int ret = 0;
487
+ struct drm_crtc_state *crtc_state = NULL;
496488 struct vmw_surface *surface = NULL;
497489 struct drm_framebuffer *fb = new_state->fb;
498490
499
- struct drm_rect src = drm_plane_state_src(new_state);
500
- struct drm_rect dest = drm_plane_state_dest(new_state);
491
+ if (new_state->crtc)
492
+ crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
493
+ new_state->crtc);
494
+
495
+ ret = drm_atomic_helper_check_plane_state(new_state, crtc_state,
496
+ DRM_PLANE_HELPER_NO_SCALING,
497
+ DRM_PLANE_HELPER_NO_SCALING,
498
+ true, true);
499
+ if (ret)
500
+ return ret;
501501
502502 /* Turning off */
503503 if (!fb)
504
- return ret;
505
-
506
- ret = drm_plane_helper_check_update(plane, new_state->crtc, fb,
507
- &src, &dest,
508
- DRM_MODE_ROTATE_0,
509
- DRM_PLANE_HELPER_NO_SCALING,
510
- DRM_PLANE_HELPER_NO_SCALING,
511
- true, true, &new_state->visible);
512
- if (!ret)
513
- return ret;
504
+ return 0;
514505
515506 /* A lot of the code assumes this */
516507 if (new_state->crtc_w != 64 || new_state->crtc_h != 64) {
....@@ -639,8 +630,7 @@
639630 return;
640631 }
641632
642
- crtc->state = &vcs->base;
643
- crtc->state->crtc = crtc;
633
+ __drm_atomic_helper_crtc_reset(crtc, &vcs->base);
644634 }
645635
646636
....@@ -720,9 +710,7 @@
720710 return;
721711 }
722712
723
- plane->state = &vps->base;
724
- plane->state->plane = plane;
725
- plane->state->rotation = DRM_MODE_ROTATE_0;
713
+ __drm_atomic_helper_plane_reset(plane, &vps->base);
726714 }
727715
728716
....@@ -848,58 +836,6 @@
848836 kfree(vfbs);
849837 }
850838
851
-static int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
852
- struct drm_file *file_priv,
853
- unsigned flags, unsigned color,
854
- struct drm_clip_rect *clips,
855
- unsigned num_clips)
856
-{
857
- struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
858
- struct vmw_framebuffer_surface *vfbs =
859
- vmw_framebuffer_to_vfbs(framebuffer);
860
- struct drm_clip_rect norect;
861
- int ret, inc = 1;
862
-
863
- /* Legacy Display Unit does not support 3D */
864
- if (dev_priv->active_display_unit == vmw_du_legacy)
865
- return -EINVAL;
866
-
867
- drm_modeset_lock_all(dev_priv->dev);
868
-
869
- ret = ttm_read_lock(&dev_priv->reservation_sem, true);
870
- if (unlikely(ret != 0)) {
871
- drm_modeset_unlock_all(dev_priv->dev);
872
- return ret;
873
- }
874
-
875
- if (!num_clips) {
876
- num_clips = 1;
877
- clips = &norect;
878
- norect.x1 = norect.y1 = 0;
879
- norect.x2 = framebuffer->width;
880
- norect.y2 = framebuffer->height;
881
- } else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
882
- num_clips /= 2;
883
- inc = 2; /* skip source rects */
884
- }
885
-
886
- if (dev_priv->active_display_unit == vmw_du_screen_object)
887
- ret = vmw_kms_sou_do_surface_dirty(dev_priv, &vfbs->base,
888
- clips, NULL, NULL, 0, 0,
889
- num_clips, inc, NULL, NULL);
890
- else
891
- ret = vmw_kms_stdu_surface_dirty(dev_priv, &vfbs->base,
892
- clips, NULL, NULL, 0, 0,
893
- num_clips, inc, NULL, NULL);
894
-
895
- vmw_fifo_flush(dev_priv, false);
896
- ttm_read_unlock(&dev_priv->reservation_sem);
897
-
898
- drm_modeset_unlock_all(dev_priv->dev);
899
-
900
- return 0;
901
-}
902
-
903839 /**
904840 * vmw_kms_readback - Perform a readback from the screen system to
905841 * a buffer-object backed framebuffer.
....@@ -943,7 +879,7 @@
943879
944880 static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
945881 .destroy = vmw_framebuffer_surface_destroy,
946
- .dirty = vmw_framebuffer_surface_dirty,
882
+ .dirty = drm_atomic_helper_dirtyfb,
947883 };
948884
949885 static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
....@@ -969,14 +905,14 @@
969905 */
970906
971907 /* Surface must be marked as a scanout. */
972
- if (unlikely(!surface->scanout))
908
+ if (unlikely(!surface->metadata.scanout))
973909 return -EINVAL;
974910
975
- if (unlikely(surface->mip_levels[0] != 1 ||
976
- surface->num_sizes != 1 ||
977
- surface->base_size.width < mode_cmd->width ||
978
- surface->base_size.height < mode_cmd->height ||
979
- surface->base_size.depth != 1)) {
911
+ if (unlikely(surface->metadata.mip_levels[0] != 1 ||
912
+ surface->metadata.num_sizes != 1 ||
913
+ surface->metadata.base_size.width < mode_cmd->width ||
914
+ surface->metadata.base_size.height < mode_cmd->height ||
915
+ surface->metadata.base_size.depth != 1)) {
980916 DRM_ERROR("Incompatible surface dimensions "
981917 "for requested mode.\n");
982918 return -EINVAL;
....@@ -1005,7 +941,7 @@
1005941 * For DX, surface format validation is done when surface->scanout
1006942 * is set.
1007943 */
1008
- if (!dev_priv->has_dx && format != surface->format) {
944
+ if (!has_sm4_context(dev_priv) && format != surface->metadata.format) {
1009945 DRM_ERROR("Invalid surface format for requested mode.\n");
1010946 return -EINVAL;
1011947 }
....@@ -1086,16 +1022,6 @@
10861022 }
10871023
10881024 switch (dev_priv->active_display_unit) {
1089
- case vmw_du_screen_target:
1090
- ret = vmw_kms_stdu_dma(dev_priv, NULL, &vfbd->base, NULL,
1091
- clips, NULL, num_clips, increment,
1092
- true, true, NULL);
1093
- break;
1094
- case vmw_du_screen_object:
1095
- ret = vmw_kms_sou_do_bo_dirty(dev_priv, &vfbd->base,
1096
- clips, NULL, num_clips,
1097
- increment, true, NULL, NULL);
1098
- break;
10991025 case vmw_du_legacy:
11001026 ret = vmw_kms_ldu_do_bo_dirty(dev_priv, &vfbd->base, 0, 0,
11011027 clips, num_clips, increment);
....@@ -1114,9 +1040,25 @@
11141040 return ret;
11151041 }
11161042
1043
+static int vmw_framebuffer_bo_dirty_ext(struct drm_framebuffer *framebuffer,
1044
+ struct drm_file *file_priv,
1045
+ unsigned int flags, unsigned int color,
1046
+ struct drm_clip_rect *clips,
1047
+ unsigned int num_clips)
1048
+{
1049
+ struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
1050
+
1051
+ if (dev_priv->active_display_unit == vmw_du_legacy)
1052
+ return vmw_framebuffer_bo_dirty(framebuffer, file_priv, flags,
1053
+ color, clips, num_clips);
1054
+
1055
+ return drm_atomic_helper_dirtyfb(framebuffer, file_priv, flags, color,
1056
+ clips, num_clips);
1057
+}
1058
+
11171059 static const struct drm_framebuffer_funcs vmw_framebuffer_bo_funcs = {
11181060 .destroy = vmw_framebuffer_bo_destroy,
1119
- .dirty = vmw_framebuffer_bo_dirty,
1061
+ .dirty = vmw_framebuffer_bo_dirty_ext,
11201062 };
11211063
11221064 /**
....@@ -1202,8 +1144,8 @@
12021144 struct vmw_buffer_object *bo_mob,
12031145 struct vmw_surface **srf_out)
12041146 {
1147
+ struct vmw_surface_metadata metadata = {0};
12051148 uint32_t format;
1206
- struct drm_vmw_size content_base_size = {0};
12071149 struct vmw_resource *res;
12081150 unsigned int bytes_pp;
12091151 struct drm_format_name_buf format_name;
....@@ -1233,22 +1175,15 @@
12331175 return -EINVAL;
12341176 }
12351177
1236
- content_base_size.width = mode_cmd->pitches[0] / bytes_pp;
1237
- content_base_size.height = mode_cmd->height;
1238
- content_base_size.depth = 1;
1178
+ metadata.format = format;
1179
+ metadata.mip_levels[0] = 1;
1180
+ metadata.num_sizes = 1;
1181
+ metadata.base_size.width = mode_cmd->pitches[0] / bytes_pp;
1182
+ metadata.base_size.height = mode_cmd->height;
1183
+ metadata.base_size.depth = 1;
1184
+ metadata.scanout = true;
12391185
1240
- ret = vmw_surface_gb_priv_define(dev,
1241
- 0, /* kernel visible only */
1242
- 0, /* flags */
1243
- format,
1244
- true, /* can be a scanout buffer */
1245
- 1, /* num of mip levels */
1246
- 0,
1247
- 0,
1248
- content_base_size,
1249
- SVGA3D_MS_PATTERN_NONE,
1250
- SVGA3D_MS_QUALITY_NONE,
1251
- srf_out);
1186
+ ret = vmw_gb_surface_define(vmw_priv(dev), 0, &metadata, srf_out);
12521187 if (ret) {
12531188 DRM_ERROR("Failed to allocate proxy content buffer\n");
12541189 return ret;
....@@ -1262,7 +1197,7 @@
12621197 vmw_bo_unreference(&res->backup);
12631198 res->backup = vmw_bo_reference(bo_mob);
12641199 res->backup_offset = 0;
1265
- vmw_resource_unreserve(res, false, NULL, 0);
1200
+ vmw_resource_unreserve(res, false, false, false, NULL, 0);
12661201 mutex_unlock(&res->dev_priv->cmdbuf_mutex);
12671202
12681203 return 0;
....@@ -1524,7 +1459,7 @@
15241459 if (dev_priv->active_display_unit == vmw_du_screen_target &&
15251460 (drm_rect_width(&rects[i]) > dev_priv->stdu_max_width ||
15261461 drm_rect_height(&rects[i]) > dev_priv->stdu_max_height)) {
1527
- DRM_ERROR("Screen size not supported.\n");
1462
+ VMW_DEBUG_KMS("Screen size not supported.\n");
15281463 return -EINVAL;
15291464 }
15301465
....@@ -1548,7 +1483,7 @@
15481483 * limit on primary bounding box
15491484 */
15501485 if (pixel_mem > dev_priv->prim_bb_mem) {
1551
- DRM_ERROR("Combined output size too large.\n");
1486
+ VMW_DEBUG_KMS("Combined output size too large.\n");
15521487 return -EINVAL;
15531488 }
15541489
....@@ -1558,9 +1493,91 @@
15581493 bb_mem = (u64) bounding_box.x2 * bounding_box.y2 * 4;
15591494
15601495 if (bb_mem > dev_priv->prim_bb_mem) {
1561
- DRM_ERROR("Topology is beyond supported limits.\n");
1496
+ VMW_DEBUG_KMS("Topology is beyond supported limits.\n");
15621497 return -EINVAL;
15631498 }
1499
+ }
1500
+
1501
+ return 0;
1502
+}
1503
+
1504
+/**
1505
+ * vmw_crtc_state_and_lock - Return new or current crtc state with locked
1506
+ * crtc mutex
1507
+ * @state: The atomic state pointer containing the new atomic state
1508
+ * @crtc: The crtc
1509
+ *
1510
+ * This function returns the new crtc state if it's part of the state update.
1511
+ * Otherwise returns the current crtc state. It also makes sure that the
1512
+ * crtc mutex is locked.
1513
+ *
1514
+ * Returns: A valid crtc state pointer or NULL. It may also return a
1515
+ * pointer error, in particular -EDEADLK if locking needs to be rerun.
1516
+ */
1517
+static struct drm_crtc_state *
1518
+vmw_crtc_state_and_lock(struct drm_atomic_state *state, struct drm_crtc *crtc)
1519
+{
1520
+ struct drm_crtc_state *crtc_state;
1521
+
1522
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1523
+ if (crtc_state) {
1524
+ lockdep_assert_held(&crtc->mutex.mutex.base);
1525
+ } else {
1526
+ int ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
1527
+
1528
+ if (ret != 0 && ret != -EALREADY)
1529
+ return ERR_PTR(ret);
1530
+
1531
+ crtc_state = crtc->state;
1532
+ }
1533
+
1534
+ return crtc_state;
1535
+}
1536
+
1537
+/**
1538
+ * vmw_kms_check_implicit - Verify that all implicit display units scan out
1539
+ * from the same fb after the new state is committed.
1540
+ * @dev: The drm_device.
1541
+ * @state: The new state to be checked.
1542
+ *
1543
+ * Returns:
1544
+ * Zero on success,
1545
+ * -EINVAL on invalid state,
1546
+ * -EDEADLK if modeset locking needs to be rerun.
1547
+ */
1548
+static int vmw_kms_check_implicit(struct drm_device *dev,
1549
+ struct drm_atomic_state *state)
1550
+{
1551
+ struct drm_framebuffer *implicit_fb = NULL;
1552
+ struct drm_crtc *crtc;
1553
+ struct drm_crtc_state *crtc_state;
1554
+ struct drm_plane_state *plane_state;
1555
+
1556
+ drm_for_each_crtc(crtc, dev) {
1557
+ struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
1558
+
1559
+ if (!du->is_implicit)
1560
+ continue;
1561
+
1562
+ crtc_state = vmw_crtc_state_and_lock(state, crtc);
1563
+ if (IS_ERR(crtc_state))
1564
+ return PTR_ERR(crtc_state);
1565
+
1566
+ if (!crtc_state || !crtc_state->enable)
1567
+ continue;
1568
+
1569
+ /*
1570
+ * Can't move primary planes across crtcs, so this is OK.
1571
+ * It also means we don't need to take the plane mutex.
1572
+ */
1573
+ plane_state = du->primary.state;
1574
+ if (plane_state->crtc != crtc)
1575
+ continue;
1576
+
1577
+ if (!implicit_fb)
1578
+ implicit_fb = plane_state->fb;
1579
+ else if (implicit_fb != plane_state->fb)
1580
+ return -EINVAL;
15641581 }
15651582
15661583 return 0;
....@@ -1577,7 +1594,6 @@
15771594 static int vmw_kms_check_topology(struct drm_device *dev,
15781595 struct drm_atomic_state *state)
15791596 {
1580
- struct vmw_private *dev_priv = vmw_priv(dev);
15811597 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
15821598 struct drm_rect *rects;
15831599 struct drm_crtc *crtc;
....@@ -1589,19 +1605,31 @@
15891605 if (!rects)
15901606 return -ENOMEM;
15911607
1592
- mutex_lock(&dev_priv->requested_layout_mutex);
1593
-
15941608 drm_for_each_crtc(crtc, dev) {
15951609 struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
1596
- struct drm_crtc_state *crtc_state = crtc->state;
1610
+ struct drm_crtc_state *crtc_state;
15971611
15981612 i = drm_crtc_index(crtc);
15991613
1600
- if (crtc_state && crtc_state->enable) {
1614
+ crtc_state = vmw_crtc_state_and_lock(state, crtc);
1615
+ if (IS_ERR(crtc_state)) {
1616
+ ret = PTR_ERR(crtc_state);
1617
+ goto clean;
1618
+ }
1619
+
1620
+ if (!crtc_state)
1621
+ continue;
1622
+
1623
+ if (crtc_state->enable) {
16011624 rects[i].x1 = du->gui_x;
16021625 rects[i].y1 = du->gui_y;
16031626 rects[i].x2 = du->gui_x + crtc_state->mode.hdisplay;
16041627 rects[i].y2 = du->gui_y + crtc_state->mode.vdisplay;
1628
+ } else {
1629
+ rects[i].x1 = 0;
1630
+ rects[i].y1 = 0;
1631
+ rects[i].x2 = 0;
1632
+ rects[i].y2 = 0;
16051633 }
16061634 }
16071635
....@@ -1613,15 +1641,8 @@
16131641 struct drm_connector_state *conn_state;
16141642 struct vmw_connector_state *vmw_conn_state;
16151643
1616
- if (!new_crtc_state->enable) {
1617
- rects[i].x1 = 0;
1618
- rects[i].y1 = 0;
1619
- rects[i].x2 = 0;
1620
- rects[i].y2 = 0;
1621
- continue;
1622
- }
1623
-
1624
- if (!du->pref_active) {
1644
+ if (!du->pref_active && new_crtc_state->enable) {
1645
+ VMW_DEBUG_KMS("Enabling a disabled display unit\n");
16251646 ret = -EINVAL;
16261647 goto clean;
16271648 }
....@@ -1641,18 +1662,12 @@
16411662 vmw_conn_state = vmw_connector_state_to_vcs(conn_state);
16421663 vmw_conn_state->gui_x = du->gui_x;
16431664 vmw_conn_state->gui_y = du->gui_y;
1644
-
1645
- rects[i].x1 = du->gui_x;
1646
- rects[i].y1 = du->gui_y;
1647
- rects[i].x2 = du->gui_x + new_crtc_state->mode.hdisplay;
1648
- rects[i].y2 = du->gui_y + new_crtc_state->mode.vdisplay;
16491665 }
16501666
16511667 ret = vmw_kms_check_display_memory(dev, dev->mode_config.num_crtc,
16521668 rects);
16531669
16541670 clean:
1655
- mutex_unlock(&dev_priv->requested_layout_mutex);
16561671 kfree(rects);
16571672 return ret;
16581673 }
....@@ -1683,14 +1698,12 @@
16831698 if (ret)
16841699 return ret;
16851700
1686
- if (!state->allow_modeset)
1701
+ ret = vmw_kms_check_implicit(dev, state);
1702
+ if (ret) {
1703
+ VMW_DEBUG_KMS("Invalid implicit state\n");
16871704 return ret;
1705
+ }
16881706
1689
- /*
1690
- * Legacy path do not set allow_modeset properly like
1691
- * @drm_atomic_helper_update_plane, This will result in unnecessary call
1692
- * to vmw_kms_check_topology. So extra set of check.
1693
- */
16941707 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
16951708 if (drm_atomic_crtc_needs_modeset(crtc_state))
16961709 need_modeset = true;
....@@ -1877,87 +1890,6 @@
18771890 return 0;
18781891 }
18791892
1880
-int vmw_kms_save_vga(struct vmw_private *vmw_priv)
1881
-{
1882
- struct vmw_vga_topology_state *save;
1883
- uint32_t i;
1884
-
1885
- vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH);
1886
- vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT);
1887
- vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
1888
- if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
1889
- vmw_priv->vga_pitchlock =
1890
- vmw_read(vmw_priv, SVGA_REG_PITCHLOCK);
1891
- else if (vmw_fifo_have_pitchlock(vmw_priv))
1892
- vmw_priv->vga_pitchlock = vmw_mmio_read(vmw_priv->mmio_virt +
1893
- SVGA_FIFO_PITCHLOCK);
1894
-
1895
- if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
1896
- return 0;
1897
-
1898
- vmw_priv->num_displays = vmw_read(vmw_priv,
1899
- SVGA_REG_NUM_GUEST_DISPLAYS);
1900
-
1901
- if (vmw_priv->num_displays == 0)
1902
- vmw_priv->num_displays = 1;
1903
-
1904
- for (i = 0; i < vmw_priv->num_displays; ++i) {
1905
- save = &vmw_priv->vga_save[i];
1906
- vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
1907
- save->primary = vmw_read(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY);
1908
- save->pos_x = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_X);
1909
- save->pos_y = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y);
1910
- save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
1911
- save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
1912
- vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
1913
- if (i == 0 && vmw_priv->num_displays == 1 &&
1914
- save->width == 0 && save->height == 0) {
1915
-
1916
- /*
1917
- * It should be fairly safe to assume that these
1918
- * values are uninitialized.
1919
- */
1920
-
1921
- save->width = vmw_priv->vga_width - save->pos_x;
1922
- save->height = vmw_priv->vga_height - save->pos_y;
1923
- }
1924
- }
1925
-
1926
- return 0;
1927
-}
1928
-
1929
-int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
1930
-{
1931
- struct vmw_vga_topology_state *save;
1932
- uint32_t i;
1933
-
1934
- vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width);
1935
- vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height);
1936
- vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
1937
- if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
1938
- vmw_write(vmw_priv, SVGA_REG_PITCHLOCK,
1939
- vmw_priv->vga_pitchlock);
1940
- else if (vmw_fifo_have_pitchlock(vmw_priv))
1941
- vmw_mmio_write(vmw_priv->vga_pitchlock,
1942
- vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
1943
-
1944
- if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
1945
- return 0;
1946
-
1947
- for (i = 0; i < vmw_priv->num_displays; ++i) {
1948
- save = &vmw_priv->vga_save[i];
1949
- vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
1950
- vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, save->primary);
1951
- vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, save->pos_x);
1952
- vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, save->pos_y);
1953
- vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, save->width);
1954
- vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, save->height);
1955
- vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
1956
- }
1957
-
1958
- return 0;
1959
-}
1960
-
19611893 bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
19621894 uint32_t pitch,
19631895 uint32_t height)
....@@ -1971,7 +1903,7 @@
19711903 /**
19721904 * Function called by DRM code called with vbl_lock held.
19731905 */
1974
-u32 vmw_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
1906
+u32 vmw_get_vblank_counter(struct drm_crtc *crtc)
19751907 {
19761908 return 0;
19771909 }
....@@ -1979,7 +1911,7 @@
19791911 /**
19801912 * Function called by DRM code called with vbl_lock held.
19811913 */
1982
-int vmw_enable_vblank(struct drm_device *dev, unsigned int pipe)
1914
+int vmw_enable_vblank(struct drm_crtc *crtc)
19831915 {
19841916 return -EINVAL;
19851917 }
....@@ -1987,7 +1919,7 @@
19871919 /**
19881920 * Function called by DRM code called with vbl_lock held.
19891921 */
1990
-void vmw_disable_vblank(struct drm_device *dev, unsigned int pipe)
1922
+void vmw_disable_vblank(struct drm_crtc *crtc)
19911923 {
19921924 }
19931925
....@@ -2005,11 +1937,25 @@
20051937 struct vmw_display_unit *du;
20061938 struct drm_connector *con;
20071939 struct drm_connector_list_iter conn_iter;
1940
+ struct drm_modeset_acquire_ctx ctx;
1941
+ struct drm_crtc *crtc;
1942
+ int ret;
20081943
2009
- /*
2010
- * Currently only gui_x/y is protected with requested_layout_mutex.
2011
- */
2012
- mutex_lock(&dev_priv->requested_layout_mutex);
1944
+ /* Currently gui_x/y is protected with the crtc mutex */
1945
+ mutex_lock(&dev->mode_config.mutex);
1946
+ drm_modeset_acquire_init(&ctx, 0);
1947
+retry:
1948
+ drm_for_each_crtc(crtc, dev) {
1949
+ ret = drm_modeset_lock(&crtc->mutex, &ctx);
1950
+ if (ret < 0) {
1951
+ if (ret == -EDEADLK) {
1952
+ drm_modeset_backoff(&ctx);
1953
+ goto retry;
1954
+ }
1955
+ goto out_fini;
1956
+ }
1957
+ }
1958
+
20131959 drm_connector_list_iter_begin(dev, &conn_iter);
20141960 drm_for_each_connector_iter(con, &conn_iter) {
20151961 du = vmw_connector_to_du(con);
....@@ -2028,9 +1974,7 @@
20281974 }
20291975 }
20301976 drm_connector_list_iter_end(&conn_iter);
2031
- mutex_unlock(&dev_priv->requested_layout_mutex);
20321977
2033
- mutex_lock(&dev->mode_config.mutex);
20341978 list_for_each_entry(con, &dev->mode_config.connector_list, head) {
20351979 du = vmw_connector_to_du(con);
20361980 if (num_rects > du->unit) {
....@@ -2050,10 +1994,13 @@
20501994 }
20511995 con->status = vmw_du_connector_detect(con, true);
20521996 }
2053
- mutex_unlock(&dev->mode_config.mutex);
20541997
20551998 drm_sysfs_hotplug_event(dev);
2056
-
1999
+out_fini:
2000
+ drm_modeset_drop_locks(&ctx);
2001
+ drm_modeset_acquire_fini(&ctx);
2002
+ mutex_unlock(&dev->mode_config.mutex);
2003
+
20572004 return 0;
20582005 }
20592006
....@@ -2191,7 +2138,6 @@
21912138 mode->vtotal = mode->vsync_end + 50;
21922139
21932140 mode->clock = (u32)mode->htotal * (u32)mode->vtotal / 100 * 6;
2194
- mode->vrefresh = drm_mode_vrefresh(mode);
21952141 }
21962142
21972143
....@@ -2265,7 +2211,6 @@
22652211 mode = drm_mode_duplicate(dev, bmode);
22662212 if (!mode)
22672213 return 0;
2268
- mode->vrefresh = drm_mode_vrefresh(mode);
22692214
22702215 drm_mode_probed_add(connector, mode);
22712216 }
....@@ -2275,84 +2220,6 @@
22752220 drm_mode_sort(&connector->modes);
22762221
22772222 return 1;
2278
-}
2279
-
2280
-int vmw_du_connector_set_property(struct drm_connector *connector,
2281
- struct drm_property *property,
2282
- uint64_t val)
2283
-{
2284
- struct vmw_display_unit *du = vmw_connector_to_du(connector);
2285
- struct vmw_private *dev_priv = vmw_priv(connector->dev);
2286
-
2287
- if (property == dev_priv->implicit_placement_property)
2288
- du->is_implicit = val;
2289
-
2290
- return 0;
2291
-}
2292
-
2293
-
2294
-
2295
-/**
2296
- * vmw_du_connector_atomic_set_property - Atomic version of get property
2297
- *
2298
- * @crtc - crtc the property is associated with
2299
- *
2300
- * Returns:
2301
- * Zero on success, negative errno on failure.
2302
- */
2303
-int
2304
-vmw_du_connector_atomic_set_property(struct drm_connector *connector,
2305
- struct drm_connector_state *state,
2306
- struct drm_property *property,
2307
- uint64_t val)
2308
-{
2309
- struct vmw_private *dev_priv = vmw_priv(connector->dev);
2310
- struct vmw_connector_state *vcs = vmw_connector_state_to_vcs(state);
2311
- struct vmw_display_unit *du = vmw_connector_to_du(connector);
2312
-
2313
-
2314
- if (property == dev_priv->implicit_placement_property) {
2315
- vcs->is_implicit = val;
2316
-
2317
- /*
2318
- * We should really be doing a drm_atomic_commit() to
2319
- * commit the new state, but since this doesn't cause
2320
- * an immedate state change, this is probably ok
2321
- */
2322
- du->is_implicit = vcs->is_implicit;
2323
- } else {
2324
- return -EINVAL;
2325
- }
2326
-
2327
- return 0;
2328
-}
2329
-
2330
-
2331
-/**
2332
- * vmw_du_connector_atomic_get_property - Atomic version of get property
2333
- *
2334
- * @connector - connector the property is associated with
2335
- *
2336
- * Returns:
2337
- * Zero on success, negative errno on failure.
2338
- */
2339
-int
2340
-vmw_du_connector_atomic_get_property(struct drm_connector *connector,
2341
- const struct drm_connector_state *state,
2342
- struct drm_property *property,
2343
- uint64_t *val)
2344
-{
2345
- struct vmw_private *dev_priv = vmw_priv(connector->dev);
2346
- struct vmw_connector_state *vcs = vmw_connector_state_to_vcs(state);
2347
-
2348
- if (property == dev_priv->implicit_placement_property)
2349
- *val = vcs->is_implicit;
2350
- else {
2351
- DRM_ERROR("Invalid Property %s\n", property->name);
2352
- return -EINVAL;
2353
- }
2354
-
2355
- return 0;
23562223 }
23572224
23582225 /**
....@@ -2389,6 +2256,9 @@
23892256
23902257 if (!arg->num_outputs) {
23912258 struct drm_rect def_rect = {0, 0, 800, 600};
2259
+ VMW_DEBUG_KMS("Default layout x1 = %d y1 = %d x2 = %d y2 = %d\n",
2260
+ def_rect.x1, def_rect.y1,
2261
+ def_rect.x2, def_rect.y2);
23922262 vmw_du_update_layout(dev_priv, 1, &def_rect);
23932263 return 0;
23942264 }
....@@ -2409,6 +2279,7 @@
24092279
24102280 drm_rects = (struct drm_rect *)rects;
24112281
2282
+ VMW_DEBUG_KMS("Layout count = %u\n", arg->num_outputs);
24122283 for (i = 0; i < arg->num_outputs; i++) {
24132284 struct drm_vmw_rect curr_rect;
24142285
....@@ -2425,6 +2296,10 @@
24252296 drm_rects[i].x2 = curr_rect.x + curr_rect.w;
24262297 drm_rects[i].y2 = curr_rect.y + curr_rect.h;
24272298
2299
+ VMW_DEBUG_KMS(" x1 = %d y1 = %d x2 = %d y2 = %d\n",
2300
+ drm_rects[i].x1, drm_rects[i].y1,
2301
+ drm_rects[i].x2, drm_rects[i].y2);
2302
+
24282303 /*
24292304 * Currently this check is limiting the topology within
24302305 * mode_config->max (which actually is max texture size
....@@ -2435,7 +2310,9 @@
24352310 if (drm_rects[i].x1 < 0 || drm_rects[i].y1 < 0 ||
24362311 drm_rects[i].x2 > mode_config->max_width ||
24372312 drm_rects[i].y2 > mode_config->max_height) {
2438
- DRM_ERROR("Invalid GUI layout.\n");
2313
+ VMW_DEBUG_KMS("Invalid layout %d %d %d %d\n",
2314
+ drm_rects[i].x1, drm_rects[i].y1,
2315
+ drm_rects[i].x2, drm_rects[i].y2);
24392316 ret = -EINVAL;
24402317 goto out_free;
24412318 }
....@@ -2508,13 +2385,11 @@
25082385
25092386 dirty->unit = unit;
25102387 if (dirty->fifo_reserve_size > 0) {
2511
- dirty->cmd = vmw_fifo_reserve(dev_priv,
2388
+ dirty->cmd = VMW_FIFO_RESERVE(dev_priv,
25122389 dirty->fifo_reserve_size);
2513
- if (!dirty->cmd) {
2514
- DRM_ERROR("Couldn't reserve fifo space "
2515
- "for dirty blits.\n");
2390
+ if (!dirty->cmd)
25162391 return -ENOMEM;
2517
- }
2392
+
25182393 memset(dirty->cmd, 0, dirty->fifo_reserve_size);
25192394 }
25202395 dirty->num_hits = 0;
....@@ -2577,88 +2452,31 @@
25772452 }
25782453
25792454 /**
2580
- * vmw_kms_helper_buffer_prepare - Reserve and validate a buffer object before
2581
- * command submission.
2582
- *
2583
- * @dev_priv. Pointer to a device private structure.
2584
- * @buf: The buffer object
2585
- * @interruptible: Whether to perform waits as interruptible.
2586
- * @validate_as_mob: Whether the buffer should be validated as a MOB. If false,
2587
- * The buffer will be validated as a GMR. Already pinned buffers will not be
2588
- * validated.
2589
- *
2590
- * Returns 0 on success, negative error code on failure, -ERESTARTSYS if
2591
- * interrupted by a signal.
2455
+ * vmw_kms_helper_validation_finish - Helper for post KMS command submission
2456
+ * cleanup and fencing
2457
+ * @dev_priv: Pointer to the device-private struct
2458
+ * @file_priv: Pointer identifying the client when user-space fencing is used
2459
+ * @ctx: Pointer to the validation context
2460
+ * @out_fence: If non-NULL, returned refcounted fence-pointer
2461
+ * @user_fence_rep: If non-NULL, pointer to user-space address area
2462
+ * in which to copy user-space fence info
25922463 */
2593
-int vmw_kms_helper_buffer_prepare(struct vmw_private *dev_priv,
2594
- struct vmw_buffer_object *buf,
2595
- bool interruptible,
2596
- bool validate_as_mob,
2597
- bool for_cpu_blit)
2464
+void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv,
2465
+ struct drm_file *file_priv,
2466
+ struct vmw_validation_context *ctx,
2467
+ struct vmw_fence_obj **out_fence,
2468
+ struct drm_vmw_fence_rep __user *
2469
+ user_fence_rep)
25982470 {
2599
- struct ttm_operation_ctx ctx = {
2600
- .interruptible = interruptible,
2601
- .no_wait_gpu = false};
2602
- struct ttm_buffer_object *bo = &buf->base;
2603
- int ret;
2471
+ struct vmw_fence_obj *fence = NULL;
2472
+ uint32_t handle = 0;
2473
+ int ret = 0;
26042474
2605
- ttm_bo_reserve(bo, false, false, NULL);
2606
- if (for_cpu_blit)
2607
- ret = ttm_bo_validate(bo, &vmw_nonfixed_placement, &ctx);
2608
- else
2609
- ret = vmw_validate_single_buffer(dev_priv, bo, interruptible,
2610
- validate_as_mob);
2611
- if (ret)
2612
- ttm_bo_unreserve(bo);
2613
-
2614
- return ret;
2615
-}
2616
-
2617
-/**
2618
- * vmw_kms_helper_buffer_revert - Undo the actions of
2619
- * vmw_kms_helper_buffer_prepare.
2620
- *
2621
- * @res: Pointer to the buffer object.
2622
- *
2623
- * Helper to be used if an error forces the caller to undo the actions of
2624
- * vmw_kms_helper_buffer_prepare.
2625
- */
2626
-void vmw_kms_helper_buffer_revert(struct vmw_buffer_object *buf)
2627
-{
2628
- if (buf)
2629
- ttm_bo_unreserve(&buf->base);
2630
-}
2631
-
2632
-/**
2633
- * vmw_kms_helper_buffer_finish - Unreserve and fence a buffer object after
2634
- * kms command submission.
2635
- *
2636
- * @dev_priv: Pointer to a device private structure.
2637
- * @file_priv: Pointer to a struct drm_file representing the caller's
2638
- * connection. Must be set to NULL if @user_fence_rep is NULL, and conversely
2639
- * if non-NULL, @user_fence_rep must be non-NULL.
2640
- * @buf: The buffer object.
2641
- * @out_fence: Optional pointer to a fence pointer. If non-NULL, a
2642
- * ref-counted fence pointer is returned here.
2643
- * @user_fence_rep: Optional pointer to a user-space provided struct
2644
- * drm_vmw_fence_rep. If provided, @file_priv must also be provided and the
2645
- * function copies fence data to user-space in a fail-safe manner.
2646
- */
2647
-void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
2648
- struct drm_file *file_priv,
2649
- struct vmw_buffer_object *buf,
2650
- struct vmw_fence_obj **out_fence,
2651
- struct drm_vmw_fence_rep __user *
2652
- user_fence_rep)
2653
-{
2654
- struct vmw_fence_obj *fence;
2655
- uint32_t handle;
2656
- int ret;
2657
-
2658
- ret = vmw_execbuf_fence_commands(file_priv, dev_priv, &fence,
2659
- file_priv ? &handle : NULL);
2660
- if (buf)
2661
- vmw_bo_fence_single(&buf->base, fence);
2475
+ if (file_priv || user_fence_rep || vmw_validation_has_bos(ctx) ||
2476
+ out_fence)
2477
+ ret = vmw_execbuf_fence_commands(file_priv, dev_priv, &fence,
2478
+ file_priv ? &handle : NULL);
2479
+ vmw_validation_done(ctx, fence);
26622480 if (file_priv)
26632481 vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv),
26642482 ret, user_fence_rep, fence,
....@@ -2667,106 +2485,6 @@
26672485 *out_fence = fence;
26682486 else
26692487 vmw_fence_obj_unreference(&fence);
2670
-
2671
- vmw_kms_helper_buffer_revert(buf);
2672
-}
2673
-
2674
-
2675
-/**
2676
- * vmw_kms_helper_resource_revert - Undo the actions of
2677
- * vmw_kms_helper_resource_prepare.
2678
- *
2679
- * @res: Pointer to the resource. Typically a surface.
2680
- *
2681
- * Helper to be used if an error forces the caller to undo the actions of
2682
- * vmw_kms_helper_resource_prepare.
2683
- */
2684
-void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx)
2685
-{
2686
- struct vmw_resource *res = ctx->res;
2687
-
2688
- vmw_kms_helper_buffer_revert(ctx->buf);
2689
- vmw_bo_unreference(&ctx->buf);
2690
- vmw_resource_unreserve(res, false, NULL, 0);
2691
- mutex_unlock(&res->dev_priv->cmdbuf_mutex);
2692
-}
2693
-
2694
-/**
2695
- * vmw_kms_helper_resource_prepare - Reserve and validate a resource before
2696
- * command submission.
2697
- *
2698
- * @res: Pointer to the resource. Typically a surface.
2699
- * @interruptible: Whether to perform waits as interruptible.
2700
- *
2701
- * Reserves and validates also the backup buffer if a guest-backed resource.
2702
- * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
2703
- * interrupted by a signal.
2704
- */
2705
-int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
2706
- bool interruptible,
2707
- struct vmw_validation_ctx *ctx)
2708
-{
2709
- int ret = 0;
2710
-
2711
- ctx->buf = NULL;
2712
- ctx->res = res;
2713
-
2714
- if (interruptible)
2715
- ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex);
2716
- else
2717
- mutex_lock(&res->dev_priv->cmdbuf_mutex);
2718
-
2719
- if (unlikely(ret != 0))
2720
- return -ERESTARTSYS;
2721
-
2722
- ret = vmw_resource_reserve(res, interruptible, false);
2723
- if (ret)
2724
- goto out_unlock;
2725
-
2726
- if (res->backup) {
2727
- ret = vmw_kms_helper_buffer_prepare(res->dev_priv, res->backup,
2728
- interruptible,
2729
- res->dev_priv->has_mob,
2730
- false);
2731
- if (ret)
2732
- goto out_unreserve;
2733
-
2734
- ctx->buf = vmw_bo_reference(res->backup);
2735
- }
2736
- ret = vmw_resource_validate(res);
2737
- if (ret)
2738
- goto out_revert;
2739
- return 0;
2740
-
2741
-out_revert:
2742
- vmw_kms_helper_buffer_revert(ctx->buf);
2743
-out_unreserve:
2744
- vmw_resource_unreserve(res, false, NULL, 0);
2745
-out_unlock:
2746
- mutex_unlock(&res->dev_priv->cmdbuf_mutex);
2747
- return ret;
2748
-}
2749
-
2750
-/**
2751
- * vmw_kms_helper_resource_finish - Unreserve and fence a resource after
2752
- * kms command submission.
2753
- *
2754
- * @res: Pointer to the resource. Typically a surface.
2755
- * @out_fence: Optional pointer to a fence pointer. If non-NULL, a
2756
- * ref-counted fence pointer is returned here.
2757
- */
2758
-void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
2759
- struct vmw_fence_obj **out_fence)
2760
-{
2761
- struct vmw_resource *res = ctx->res;
2762
-
2763
- if (ctx->buf || out_fence)
2764
- vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf,
2765
- out_fence, NULL);
2766
-
2767
- vmw_bo_unreference(&ctx->buf);
2768
- vmw_resource_unreserve(res, false, NULL, 0);
2769
- mutex_unlock(&res->dev_priv->cmdbuf_mutex);
27702488 }
27712489
27722490 /**
....@@ -2789,7 +2507,7 @@
27892507 int increment)
27902508 {
27912509 struct vmw_private *dev_priv = res->dev_priv;
2792
- struct drm_vmw_size *size = &vmw_res_to_srf(res)->base_size;
2510
+ struct drm_vmw_size *size = &vmw_res_to_srf(res)->metadata.base_size;
27932511 struct {
27942512 SVGA3dCmdHeader header;
27952513 SVGA3dCmdUpdateGBImage body;
....@@ -2801,12 +2519,9 @@
28012519 if (!clips)
28022520 return 0;
28032521
2804
- cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) * num_clips);
2805
- if (!cmd) {
2806
- DRM_ERROR("Couldn't reserve fifo space for proxy surface "
2807
- "update.\n");
2522
+ cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd) * num_clips);
2523
+ if (!cmd)
28082524 return -ENOMEM;
2809
- }
28102525
28112526 for (i = 0; i < num_clips; ++i, clips += increment, ++cmd) {
28122527 box = &cmd->body.box;
....@@ -2901,142 +2616,24 @@
29012616 }
29022617
29032618 /**
2904
- * vmw_kms_del_active - unregister a crtc binding to the implicit framebuffer
2905
- *
2906
- * @dev_priv: Pointer to a device private struct.
2907
- * @du: The display unit of the crtc.
2908
- */
2909
-void vmw_kms_del_active(struct vmw_private *dev_priv,
2910
- struct vmw_display_unit *du)
2911
-{
2912
- mutex_lock(&dev_priv->global_kms_state_mutex);
2913
- if (du->active_implicit) {
2914
- if (--(dev_priv->num_implicit) == 0)
2915
- dev_priv->implicit_fb = NULL;
2916
- du->active_implicit = false;
2917
- }
2918
- mutex_unlock(&dev_priv->global_kms_state_mutex);
2919
-}
2920
-
2921
-/**
2922
- * vmw_kms_add_active - register a crtc binding to an implicit framebuffer
2923
- *
2924
- * @vmw_priv: Pointer to a device private struct.
2925
- * @du: The display unit of the crtc.
2926
- * @vfb: The implicit framebuffer
2927
- *
2928
- * Registers a binding to an implicit framebuffer.
2929
- */
2930
-void vmw_kms_add_active(struct vmw_private *dev_priv,
2931
- struct vmw_display_unit *du,
2932
- struct vmw_framebuffer *vfb)
2933
-{
2934
- mutex_lock(&dev_priv->global_kms_state_mutex);
2935
- WARN_ON_ONCE(!dev_priv->num_implicit && dev_priv->implicit_fb);
2936
-
2937
- if (!du->active_implicit && du->is_implicit) {
2938
- dev_priv->implicit_fb = vfb;
2939
- du->active_implicit = true;
2940
- dev_priv->num_implicit++;
2941
- }
2942
- mutex_unlock(&dev_priv->global_kms_state_mutex);
2943
-}
2944
-
2945
-/**
2946
- * vmw_kms_screen_object_flippable - Check whether we can page-flip a crtc.
2947
- *
2948
- * @dev_priv: Pointer to device-private struct.
2949
- * @crtc: The crtc we want to flip.
2950
- *
2951
- * Returns true or false depending whether it's OK to flip this crtc
2952
- * based on the criterion that we must not have more than one implicit
2953
- * frame-buffer at any one time.
2954
- */
2955
-bool vmw_kms_crtc_flippable(struct vmw_private *dev_priv,
2956
- struct drm_crtc *crtc)
2957
-{
2958
- struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
2959
- bool ret;
2960
-
2961
- mutex_lock(&dev_priv->global_kms_state_mutex);
2962
- ret = !du->is_implicit || dev_priv->num_implicit == 1;
2963
- mutex_unlock(&dev_priv->global_kms_state_mutex);
2964
-
2965
- return ret;
2966
-}
2967
-
2968
-/**
2969
- * vmw_kms_update_implicit_fb - Update the implicit fb.
2970
- *
2971
- * @dev_priv: Pointer to device-private struct.
2972
- * @crtc: The crtc the new implicit frame-buffer is bound to.
2973
- */
2974
-void vmw_kms_update_implicit_fb(struct vmw_private *dev_priv,
2975
- struct drm_crtc *crtc)
2976
-{
2977
- struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
2978
- struct drm_plane *plane = crtc->primary;
2979
- struct vmw_framebuffer *vfb;
2980
-
2981
- mutex_lock(&dev_priv->global_kms_state_mutex);
2982
-
2983
- if (!du->is_implicit)
2984
- goto out_unlock;
2985
-
2986
- vfb = vmw_framebuffer_to_vfb(plane->state->fb);
2987
- WARN_ON_ONCE(dev_priv->num_implicit != 1 &&
2988
- dev_priv->implicit_fb != vfb);
2989
-
2990
- dev_priv->implicit_fb = vfb;
2991
-out_unlock:
2992
- mutex_unlock(&dev_priv->global_kms_state_mutex);
2993
-}
2994
-
2995
-/**
29962619 * vmw_kms_create_implicit_placement_proparty - Set up the implicit placement
29972620 * property.
29982621 *
29992622 * @dev_priv: Pointer to a device private struct.
3000
- * @immutable: Whether the property is immutable.
30012623 *
30022624 * Sets up the implicit placement property unless it's already set up.
30032625 */
30042626 void
3005
-vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv,
3006
- bool immutable)
2627
+vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv)
30072628 {
30082629 if (dev_priv->implicit_placement_property)
30092630 return;
30102631
30112632 dev_priv->implicit_placement_property =
30122633 drm_property_create_range(dev_priv->dev,
3013
- immutable ?
3014
- DRM_MODE_PROP_IMMUTABLE : 0,
2634
+ DRM_MODE_PROP_IMMUTABLE,
30152635 "implicit_placement", 0, 1);
3016
-
30172636 }
3018
-
3019
-
3020
-/**
3021
- * vmw_kms_set_config - Wrapper around drm_atomic_helper_set_config
3022
- *
3023
- * @set: The configuration to set.
3024
- *
3025
- * The vmwgfx Xorg driver doesn't assign the mode::type member, which
3026
- * when drm_mode_set_crtcinfo is called as part of the configuration setting
3027
- * causes it to return incorrect crtc dimensions causing severe problems in
3028
- * the vmwgfx modesetting. So explicitly clear that member before calling
3029
- * into drm_atomic_helper_set_config.
3030
- */
3031
-int vmw_kms_set_config(struct drm_mode_set *set,
3032
- struct drm_modeset_acquire_ctx *ctx)
3033
-{
3034
- if (set && set->mode)
3035
- set->mode->type = 0;
3036
-
3037
- return drm_atomic_helper_set_config(set, ctx);
3038
-}
3039
-
30402637
30412638 /**
30422639 * vmw_kms_suspend - Save modesetting state and turn modesetting off.
....@@ -3094,3 +2691,125 @@
30942691 {
30952692 drm_atomic_helper_shutdown(dev);
30962693 }
2694
+
2695
+/**
2696
+ * vmw_du_helper_plane_update - Helper to do plane update on a display unit.
2697
+ * @update: The closure structure.
2698
+ *
2699
+ * Call this helper after setting callbacks in &vmw_du_update_plane to do plane
2700
+ * update on display unit.
2701
+ *
2702
+ * Return: 0 on success or a negative error code on failure.
2703
+ */
2704
+int vmw_du_helper_plane_update(struct vmw_du_update_plane *update)
2705
+{
2706
+ struct drm_plane_state *state = update->plane->state;
2707
+ struct drm_plane_state *old_state = update->old_state;
2708
+ struct drm_atomic_helper_damage_iter iter;
2709
+ struct drm_rect clip;
2710
+ struct drm_rect bb;
2711
+ DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
2712
+ uint32_t reserved_size = 0;
2713
+ uint32_t submit_size = 0;
2714
+ uint32_t curr_size = 0;
2715
+ uint32_t num_hits = 0;
2716
+ void *cmd_start;
2717
+ char *cmd_next;
2718
+ int ret;
2719
+
2720
+ /*
2721
+ * Iterate in advance to check if really need plane update and find the
2722
+ * number of clips that actually are in plane src for fifo allocation.
2723
+ */
2724
+ drm_atomic_helper_damage_iter_init(&iter, old_state, state);
2725
+ drm_atomic_for_each_plane_damage(&iter, &clip)
2726
+ num_hits++;
2727
+
2728
+ if (num_hits == 0)
2729
+ return 0;
2730
+
2731
+ if (update->vfb->bo) {
2732
+ struct vmw_framebuffer_bo *vfbbo =
2733
+ container_of(update->vfb, typeof(*vfbbo), base);
2734
+
2735
+ ret = vmw_validation_add_bo(&val_ctx, vfbbo->buffer, false,
2736
+ update->cpu_blit);
2737
+ } else {
2738
+ struct vmw_framebuffer_surface *vfbs =
2739
+ container_of(update->vfb, typeof(*vfbs), base);
2740
+
2741
+ ret = vmw_validation_add_resource(&val_ctx, &vfbs->surface->res,
2742
+ 0, VMW_RES_DIRTY_NONE, NULL,
2743
+ NULL);
2744
+ }
2745
+
2746
+ if (ret)
2747
+ return ret;
2748
+
2749
+ ret = vmw_validation_prepare(&val_ctx, update->mutex, update->intr);
2750
+ if (ret)
2751
+ goto out_unref;
2752
+
2753
+ reserved_size = update->calc_fifo_size(update, num_hits);
2754
+ cmd_start = VMW_FIFO_RESERVE(update->dev_priv, reserved_size);
2755
+ if (!cmd_start) {
2756
+ ret = -ENOMEM;
2757
+ goto out_revert;
2758
+ }
2759
+
2760
+ cmd_next = cmd_start;
2761
+
2762
+ if (update->post_prepare) {
2763
+ curr_size = update->post_prepare(update, cmd_next);
2764
+ cmd_next += curr_size;
2765
+ submit_size += curr_size;
2766
+ }
2767
+
2768
+ if (update->pre_clip) {
2769
+ curr_size = update->pre_clip(update, cmd_next, num_hits);
2770
+ cmd_next += curr_size;
2771
+ submit_size += curr_size;
2772
+ }
2773
+
2774
+ bb.x1 = INT_MAX;
2775
+ bb.y1 = INT_MAX;
2776
+ bb.x2 = INT_MIN;
2777
+ bb.y2 = INT_MIN;
2778
+
2779
+ drm_atomic_helper_damage_iter_init(&iter, old_state, state);
2780
+ drm_atomic_for_each_plane_damage(&iter, &clip) {
2781
+ uint32_t fb_x = clip.x1;
2782
+ uint32_t fb_y = clip.y1;
2783
+
2784
+ vmw_du_translate_to_crtc(state, &clip);
2785
+ if (update->clip) {
2786
+ curr_size = update->clip(update, cmd_next, &clip, fb_x,
2787
+ fb_y);
2788
+ cmd_next += curr_size;
2789
+ submit_size += curr_size;
2790
+ }
2791
+ bb.x1 = min_t(int, bb.x1, clip.x1);
2792
+ bb.y1 = min_t(int, bb.y1, clip.y1);
2793
+ bb.x2 = max_t(int, bb.x2, clip.x2);
2794
+ bb.y2 = max_t(int, bb.y2, clip.y2);
2795
+ }
2796
+
2797
+ curr_size = update->post_clip(update, cmd_next, &bb);
2798
+ submit_size += curr_size;
2799
+
2800
+ if (reserved_size < submit_size)
2801
+ submit_size = 0;
2802
+
2803
+ vmw_fifo_commit(update->dev_priv, submit_size);
2804
+
2805
+ vmw_kms_helper_validation_finish(update->dev_priv, NULL, &val_ctx,
2806
+ update->out_fence, NULL);
2807
+ return ret;
2808
+
2809
+out_revert:
2810
+ vmw_validation_revert(&val_ctx);
2811
+
2812
+out_unref:
2813
+ vmw_validation_unref_lists(&val_ctx);
2814
+ return ret;
2815
+}