Home | History | Annotate | Line # | Download | only in vmwgfx
      1  1.7  riastrad /*	$NetBSD: vmwgfx_kms.c,v 1.7 2021/12/18 23:45:45 riastradh Exp $	*/
      2  1.4  riastrad 
      3  1.7  riastrad // SPDX-License-Identifier: GPL-2.0 OR MIT
      4  1.1  riastrad /**************************************************************************
      5  1.1  riastrad  *
      6  1.7  riastrad  * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
      7  1.1  riastrad  *
      8  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      9  1.1  riastrad  * copy of this software and associated documentation files (the
     10  1.1  riastrad  * "Software"), to deal in the Software without restriction, including
     11  1.1  riastrad  * without limitation the rights to use, copy, modify, merge, publish,
     12  1.1  riastrad  * distribute, sub license, and/or sell copies of the Software, and to
     13  1.1  riastrad  * permit persons to whom the Software is furnished to do so, subject to
     14  1.1  riastrad  * the following conditions:
     15  1.1  riastrad  *
     16  1.1  riastrad  * The above copyright notice and this permission notice (including the
     17  1.1  riastrad  * next paragraph) shall be included in all copies or substantial portions
     18  1.1  riastrad  * of the Software.
     19  1.1  riastrad  *
     20  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     21  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     22  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     23  1.1  riastrad  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     24  1.1  riastrad  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     25  1.1  riastrad  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     26  1.1  riastrad  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     27  1.1  riastrad  *
     28  1.1  riastrad  **************************************************************************/
     29  1.1  riastrad 
     30  1.4  riastrad #include <sys/cdefs.h>
     31  1.7  riastrad __KERNEL_RCSID(0, "$NetBSD: vmwgfx_kms.c,v 1.7 2021/12/18 23:45:45 riastradh Exp $");
     32  1.7  riastrad 
     33  1.7  riastrad #include <drm/drm_atomic.h>
     34  1.7  riastrad #include <drm/drm_atomic_helper.h>
     35  1.7  riastrad #include <drm/drm_damage_helper.h>
     36  1.7  riastrad #include <drm/drm_fourcc.h>
     37  1.7  riastrad #include <drm/drm_plane_helper.h>
     38  1.7  riastrad #include <drm/drm_rect.h>
     39  1.7  riastrad #include <drm/drm_sysfs.h>
     40  1.7  riastrad #include <drm/drm_vblank.h>
     41  1.4  riastrad 
     42  1.1  riastrad #include "vmwgfx_kms.h"
     43  1.1  riastrad 
     44  1.1  riastrad /* Might need a hrtimer here? */
     45  1.1  riastrad #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
     46  1.1  riastrad 
     47  1.4  riastrad void vmw_du_cleanup(struct vmw_display_unit *du)
     48  1.1  riastrad {
     49  1.7  riastrad 	drm_plane_cleanup(&du->primary);
     50  1.7  riastrad 	drm_plane_cleanup(&du->cursor);
     51  1.7  riastrad 
     52  1.4  riastrad 	drm_connector_unregister(&du->connector);
     53  1.1  riastrad 	drm_crtc_cleanup(&du->crtc);
     54  1.1  riastrad 	drm_encoder_cleanup(&du->encoder);
     55  1.1  riastrad 	drm_connector_cleanup(&du->connector);
     56  1.1  riastrad }
     57  1.1  riastrad 
     58  1.1  riastrad /*
     59  1.1  riastrad  * Display Unit Cursor functions
     60  1.1  riastrad  */
     61  1.1  riastrad 
     62  1.7  riastrad static int vmw_cursor_update_image(struct vmw_private *dev_priv,
     63  1.7  riastrad 				   u32 *image, u32 width, u32 height,
     64  1.7  riastrad 				   u32 hotspotX, u32 hotspotY)
     65  1.1  riastrad {
     66  1.1  riastrad 	struct {
     67  1.1  riastrad 		u32 cmd;
     68  1.1  riastrad 		SVGAFifoCmdDefineAlphaCursor cursor;
     69  1.1  riastrad 	} *cmd;
     70  1.1  riastrad 	u32 image_size = width * height * 4;
     71  1.1  riastrad 	u32 cmd_size = sizeof(*cmd) + image_size;
     72  1.1  riastrad 
     73  1.1  riastrad 	if (!image)
     74  1.1  riastrad 		return -EINVAL;
     75  1.1  riastrad 
     76  1.7  riastrad 	cmd = VMW_FIFO_RESERVE(dev_priv, cmd_size);
     77  1.7  riastrad 	if (unlikely(cmd == NULL))
     78  1.1  riastrad 		return -ENOMEM;
     79  1.1  riastrad 
     80  1.1  riastrad 	memset(cmd, 0, sizeof(*cmd));
     81  1.1  riastrad 
     82  1.1  riastrad 	memcpy(&cmd[1], image, image_size);
     83  1.1  riastrad 
     84  1.4  riastrad 	cmd->cmd = SVGA_CMD_DEFINE_ALPHA_CURSOR;
     85  1.4  riastrad 	cmd->cursor.id = 0;
     86  1.4  riastrad 	cmd->cursor.width = width;
     87  1.4  riastrad 	cmd->cursor.height = height;
     88  1.4  riastrad 	cmd->cursor.hotspotX = hotspotX;
     89  1.4  riastrad 	cmd->cursor.hotspotY = hotspotY;
     90  1.1  riastrad 
     91  1.4  riastrad 	vmw_fifo_commit_flush(dev_priv, cmd_size);
     92  1.1  riastrad 
     93  1.1  riastrad 	return 0;
     94  1.1  riastrad }
     95  1.1  riastrad 
     96  1.7  riastrad static int vmw_cursor_update_bo(struct vmw_private *dev_priv,
     97  1.7  riastrad 				struct vmw_buffer_object *bo,
     98  1.7  riastrad 				u32 width, u32 height,
     99  1.7  riastrad 				u32 hotspotX, u32 hotspotY)
    100  1.1  riastrad {
    101  1.1  riastrad 	struct ttm_bo_kmap_obj map;
    102  1.1  riastrad 	unsigned long kmap_offset;
    103  1.1  riastrad 	unsigned long kmap_num;
    104  1.1  riastrad 	void *virtual;
    105  1.1  riastrad 	bool dummy;
    106  1.1  riastrad 	int ret;
    107  1.1  riastrad 
    108  1.1  riastrad 	kmap_offset = 0;
    109  1.1  riastrad 	kmap_num = (width*height*4 + PAGE_SIZE - 1) >> PAGE_SHIFT;
    110  1.1  riastrad 
    111  1.7  riastrad 	ret = ttm_bo_reserve(&bo->base, true, false, NULL);
    112  1.1  riastrad 	if (unlikely(ret != 0)) {
    113  1.1  riastrad 		DRM_ERROR("reserve failed\n");
    114  1.1  riastrad 		return -EINVAL;
    115  1.1  riastrad 	}
    116  1.1  riastrad 
    117  1.7  riastrad 	ret = ttm_bo_kmap(&bo->base, kmap_offset, kmap_num, &map);
    118  1.1  riastrad 	if (unlikely(ret != 0))
    119  1.1  riastrad 		goto err_unreserve;
    120  1.1  riastrad 
    121  1.1  riastrad 	virtual = ttm_kmap_obj_virtual(&map, &dummy);
    122  1.1  riastrad 	ret = vmw_cursor_update_image(dev_priv, virtual, width, height,
    123  1.1  riastrad 				      hotspotX, hotspotY);
    124  1.1  riastrad 
    125  1.1  riastrad 	ttm_bo_kunmap(&map);
    126  1.1  riastrad err_unreserve:
    127  1.7  riastrad 	ttm_bo_unreserve(&bo->base);
    128  1.1  riastrad 
    129  1.1  riastrad 	return ret;
    130  1.1  riastrad }
    131  1.1  riastrad 
    132  1.1  riastrad 
    133  1.7  riastrad static void vmw_cursor_update_position(struct vmw_private *dev_priv,
    134  1.7  riastrad 				       bool show, int x, int y)
    135  1.1  riastrad {
    136  1.4  riastrad 	u32 *fifo_mem = dev_priv->mmio_virt;
    137  1.1  riastrad 	uint32_t count;
    138  1.1  riastrad 
    139  1.7  riastrad 	spin_lock(&dev_priv->cursor_lock);
    140  1.4  riastrad 	vmw_mmio_write(show ? 1 : 0, fifo_mem + SVGA_FIFO_CURSOR_ON);
    141  1.4  riastrad 	vmw_mmio_write(x, fifo_mem + SVGA_FIFO_CURSOR_X);
    142  1.4  riastrad 	vmw_mmio_write(y, fifo_mem + SVGA_FIFO_CURSOR_Y);
    143  1.4  riastrad 	count = vmw_mmio_read(fifo_mem + SVGA_FIFO_CURSOR_COUNT);
    144  1.4  riastrad 	vmw_mmio_write(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT);
    145  1.7  riastrad 	spin_unlock(&dev_priv->cursor_lock);
    146  1.1  riastrad }
    147  1.1  riastrad 
    148  1.4  riastrad 
    149  1.1  riastrad void vmw_kms_cursor_snoop(struct vmw_surface *srf,
    150  1.1  riastrad 			  struct ttm_object_file *tfile,
    151  1.1  riastrad 			  struct ttm_buffer_object *bo,
    152  1.1  riastrad 			  SVGA3dCmdHeader *header)
    153  1.1  riastrad {
    154  1.1  riastrad 	struct ttm_bo_kmap_obj map;
    155  1.1  riastrad 	unsigned long kmap_offset;
    156  1.1  riastrad 	unsigned long kmap_num;
    157  1.1  riastrad 	SVGA3dCopyBox *box;
    158  1.1  riastrad 	unsigned box_count;
    159  1.1  riastrad 	void *virtual;
    160  1.1  riastrad 	bool dummy;
    161  1.1  riastrad 	struct vmw_dma_cmd {
    162  1.1  riastrad 		SVGA3dCmdHeader header;
    163  1.1  riastrad 		SVGA3dCmdSurfaceDMA dma;
    164  1.1  riastrad 	} *cmd;
    165  1.1  riastrad 	int i, ret;
    166  1.1  riastrad 
    167  1.1  riastrad 	cmd = container_of(header, struct vmw_dma_cmd, header);
    168  1.1  riastrad 
    169  1.1  riastrad 	/* No snooper installed */
    170  1.1  riastrad 	if (!srf->snooper.image)
    171  1.1  riastrad 		return;
    172  1.1  riastrad 
    173  1.1  riastrad 	if (cmd->dma.host.face != 0 || cmd->dma.host.mipmap != 0) {
    174  1.1  riastrad 		DRM_ERROR("face and mipmap for cursors should never != 0\n");
    175  1.1  riastrad 		return;
    176  1.1  riastrad 	}
    177  1.1  riastrad 
    178  1.1  riastrad 	if (cmd->header.size < 64) {
    179  1.1  riastrad 		DRM_ERROR("at least one full copy box must be given\n");
    180  1.1  riastrad 		return;
    181  1.1  riastrad 	}
    182  1.1  riastrad 
    183  1.1  riastrad 	box = (SVGA3dCopyBox *)&cmd[1];
    184  1.1  riastrad 	box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) /
    185  1.1  riastrad 			sizeof(SVGA3dCopyBox);
    186  1.1  riastrad 
    187  1.1  riastrad 	if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
    188  1.1  riastrad 	    box->x != 0    || box->y != 0    || box->z != 0    ||
    189  1.1  riastrad 	    box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
    190  1.1  riastrad 	    box->d != 1    || box_count != 1) {
    191  1.1  riastrad 		/* TODO handle none page aligned offsets */
    192  1.1  riastrad 		/* TODO handle more dst & src != 0 */
    193  1.6  riastrad 		/* TODO handle more then one copy */
    194  1.1  riastrad 		DRM_ERROR("Cant snoop dma request for cursor!\n");
    195  1.1  riastrad 		DRM_ERROR("(%u, %u, %u) (%u, %u, %u) (%ux%ux%u) %u %u\n",
    196  1.1  riastrad 			  box->srcx, box->srcy, box->srcz,
    197  1.1  riastrad 			  box->x, box->y, box->z,
    198  1.1  riastrad 			  box->w, box->h, box->d, box_count,
    199  1.1  riastrad 			  cmd->dma.guest.ptr.offset);
    200  1.1  riastrad 		return;
    201  1.1  riastrad 	}
    202  1.1  riastrad 
    203  1.1  riastrad 	kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
    204  1.1  riastrad 	kmap_num = (64*64*4) >> PAGE_SHIFT;
    205  1.1  riastrad 
    206  1.7  riastrad 	ret = ttm_bo_reserve(bo, true, false, NULL);
    207  1.1  riastrad 	if (unlikely(ret != 0)) {
    208  1.1  riastrad 		DRM_ERROR("reserve failed\n");
    209  1.1  riastrad 		return;
    210  1.1  riastrad 	}
    211  1.1  riastrad 
    212  1.1  riastrad 	ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
    213  1.1  riastrad 	if (unlikely(ret != 0))
    214  1.1  riastrad 		goto err_unreserve;
    215  1.1  riastrad 
    216  1.1  riastrad 	virtual = ttm_kmap_obj_virtual(&map, &dummy);
    217  1.1  riastrad 
    218  1.1  riastrad 	if (box->w == 64 && cmd->dma.guest.pitch == 64*4) {
    219  1.1  riastrad 		memcpy(srf->snooper.image, virtual, 64*64*4);
    220  1.1  riastrad 	} else {
    221  1.1  riastrad 		/* Image is unsigned pointer. */
    222  1.1  riastrad 		for (i = 0; i < box->h; i++)
    223  1.7  riastrad 			memcpy(srf->snooper.image + i * 64,
    224  1.7  riastrad 			       virtual + i * cmd->dma.guest.pitch,
    225  1.7  riastrad 			       box->w * 4);
    226  1.7  riastrad 	}
    227  1.7  riastrad 
    228  1.7  riastrad 	srf->snooper.age++;
    229  1.7  riastrad 
    230  1.7  riastrad 	ttm_bo_kunmap(&map);
    231  1.7  riastrad err_unreserve:
    232  1.7  riastrad 	ttm_bo_unreserve(bo);
    233  1.7  riastrad }
    234  1.7  riastrad 
    235  1.7  riastrad /**
    236  1.7  riastrad  * vmw_kms_legacy_hotspot_clear - Clear legacy hotspots
    237  1.7  riastrad  *
    238  1.7  riastrad  * @dev_priv: Pointer to the device private struct.
    239  1.7  riastrad  *
    240  1.7  riastrad  * Clears all legacy hotspots.
    241  1.7  riastrad  */
    242  1.7  riastrad void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv)
    243  1.7  riastrad {
    244  1.7  riastrad 	struct drm_device *dev = dev_priv->dev;
    245  1.7  riastrad 	struct vmw_display_unit *du;
    246  1.7  riastrad 	struct drm_crtc *crtc;
    247  1.7  riastrad 
    248  1.7  riastrad 	drm_modeset_lock_all(dev);
    249  1.7  riastrad 	drm_for_each_crtc(crtc, dev) {
    250  1.7  riastrad 		du = vmw_crtc_to_du(crtc);
    251  1.7  riastrad 
    252  1.7  riastrad 		du->hotspot_x = 0;
    253  1.7  riastrad 		du->hotspot_y = 0;
    254  1.7  riastrad 	}
    255  1.7  riastrad 	drm_modeset_unlock_all(dev);
    256  1.7  riastrad }
    257  1.7  riastrad 
    258  1.7  riastrad void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
    259  1.7  riastrad {
    260  1.7  riastrad 	struct drm_device *dev = dev_priv->dev;
    261  1.7  riastrad 	struct vmw_display_unit *du;
    262  1.7  riastrad 	struct drm_crtc *crtc;
    263  1.7  riastrad 
    264  1.7  riastrad 	mutex_lock(&dev->mode_config.mutex);
    265  1.7  riastrad 
    266  1.7  riastrad 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
    267  1.7  riastrad 		du = vmw_crtc_to_du(crtc);
    268  1.7  riastrad 		if (!du->cursor_surface ||
    269  1.7  riastrad 		    du->cursor_age == du->cursor_surface->snooper.age)
    270  1.7  riastrad 			continue;
    271  1.7  riastrad 
    272  1.7  riastrad 		du->cursor_age = du->cursor_surface->snooper.age;
    273  1.7  riastrad 		vmw_cursor_update_image(dev_priv,
    274  1.7  riastrad 					du->cursor_surface->snooper.image,
    275  1.7  riastrad 					64, 64,
    276  1.7  riastrad 					du->hotspot_x + du->core_hotspot_x,
    277  1.7  riastrad 					du->hotspot_y + du->core_hotspot_y);
    278  1.7  riastrad 	}
    279  1.7  riastrad 
    280  1.7  riastrad 	mutex_unlock(&dev->mode_config.mutex);
    281  1.7  riastrad }
    282  1.7  riastrad 
    283  1.7  riastrad 
    284  1.7  riastrad void vmw_du_cursor_plane_destroy(struct drm_plane *plane)
    285  1.7  riastrad {
    286  1.7  riastrad 	vmw_cursor_update_position(plane->dev->dev_private, false, 0, 0);
    287  1.7  riastrad 
    288  1.7  riastrad 	drm_plane_cleanup(plane);
    289  1.7  riastrad }
    290  1.7  riastrad 
    291  1.7  riastrad 
    292  1.7  riastrad void vmw_du_primary_plane_destroy(struct drm_plane *plane)
    293  1.7  riastrad {
    294  1.7  riastrad 	drm_plane_cleanup(plane);
    295  1.7  riastrad 
    296  1.7  riastrad 	/* Planes are static in our case so we don't free it */
    297  1.7  riastrad }
    298  1.7  riastrad 
    299  1.7  riastrad 
    300  1.7  riastrad /**
    301  1.7  riastrad  * vmw_du_vps_unpin_surf - unpins resource associated with a framebuffer surface
    302  1.7  riastrad  *
    303  1.7  riastrad  * @vps: plane state associated with the display surface
    304  1.7  riastrad  * @unreference: true if we also want to unreference the display.
    305  1.7  riastrad  */
    306  1.7  riastrad void vmw_du_plane_unpin_surf(struct vmw_plane_state *vps,
    307  1.7  riastrad 			     bool unreference)
    308  1.7  riastrad {
    309  1.7  riastrad 	if (vps->surf) {
    310  1.7  riastrad 		if (vps->pinned) {
    311  1.7  riastrad 			vmw_resource_unpin(&vps->surf->res);
    312  1.7  riastrad 			vps->pinned--;
    313  1.7  riastrad 		}
    314  1.7  riastrad 
    315  1.7  riastrad 		if (unreference) {
    316  1.7  riastrad 			if (vps->pinned)
    317  1.7  riastrad 				DRM_ERROR("Surface still pinned\n");
    318  1.7  riastrad 			vmw_surface_unreference(&vps->surf);
    319  1.7  riastrad 		}
    320  1.7  riastrad 	}
    321  1.7  riastrad }
    322  1.7  riastrad 
    323  1.7  riastrad 
    324  1.7  riastrad /**
    325  1.7  riastrad  * vmw_du_plane_cleanup_fb - Unpins the cursor
    326  1.7  riastrad  *
    327  1.7  riastrad  * @plane:  display plane
    328  1.7  riastrad  * @old_state: Contains the FB to clean up
    329  1.7  riastrad  *
    330  1.7  riastrad  * Unpins the framebuffer surface
    331  1.7  riastrad  *
    332  1.7  riastrad  * Returns 0 on success
    333  1.7  riastrad  */
    334  1.7  riastrad void
    335  1.7  riastrad vmw_du_plane_cleanup_fb(struct drm_plane *plane,
    336  1.7  riastrad 			struct drm_plane_state *old_state)
    337  1.7  riastrad {
    338  1.7  riastrad 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
    339  1.7  riastrad 
    340  1.7  riastrad 	vmw_du_plane_unpin_surf(vps, false);
    341  1.7  riastrad }
    342  1.7  riastrad 
    343  1.7  riastrad 
    344  1.7  riastrad /**
    345  1.7  riastrad  * vmw_du_cursor_plane_prepare_fb - Readies the cursor by referencing it
    346  1.7  riastrad  *
    347  1.7  riastrad  * @plane:  display plane
    348  1.7  riastrad  * @new_state: info on the new plane state, including the FB
    349  1.7  riastrad  *
    350  1.7  riastrad  * Returns 0 on success
    351  1.7  riastrad  */
    352  1.7  riastrad int
    353  1.7  riastrad vmw_du_cursor_plane_prepare_fb(struct drm_plane *plane,
    354  1.7  riastrad 			       struct drm_plane_state *new_state)
    355  1.7  riastrad {
    356  1.7  riastrad 	struct drm_framebuffer *fb = new_state->fb;
    357  1.7  riastrad 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
    358  1.7  riastrad 
    359  1.7  riastrad 
    360  1.7  riastrad 	if (vps->surf)
    361  1.7  riastrad 		vmw_surface_unreference(&vps->surf);
    362  1.7  riastrad 
    363  1.7  riastrad 	if (vps->bo)
    364  1.7  riastrad 		vmw_bo_unreference(&vps->bo);
    365  1.7  riastrad 
    366  1.7  riastrad 	if (fb) {
    367  1.7  riastrad 		if (vmw_framebuffer_to_vfb(fb)->bo) {
    368  1.7  riastrad 			vps->bo = vmw_framebuffer_to_vfbd(fb)->buffer;
    369  1.7  riastrad 			vmw_bo_reference(vps->bo);
    370  1.7  riastrad 		} else {
    371  1.7  riastrad 			vps->surf = vmw_framebuffer_to_vfbs(fb)->surface;
    372  1.7  riastrad 			vmw_surface_reference(vps->surf);
    373  1.7  riastrad 		}
    374  1.7  riastrad 	}
    375  1.7  riastrad 
    376  1.7  riastrad 	return 0;
    377  1.7  riastrad }
    378  1.7  riastrad 
    379  1.7  riastrad 
    380  1.7  riastrad void
    381  1.7  riastrad vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
    382  1.7  riastrad 				  struct drm_plane_state *old_state)
    383  1.7  riastrad {
    384  1.7  riastrad 	struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc;
    385  1.7  riastrad 	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
    386  1.7  riastrad 	struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
    387  1.7  riastrad 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(plane->state);
    388  1.7  riastrad 	s32 hotspot_x, hotspot_y;
    389  1.7  riastrad 	int ret = 0;
    390  1.7  riastrad 
    391  1.7  riastrad 
    392  1.7  riastrad 	hotspot_x = du->hotspot_x;
    393  1.7  riastrad 	hotspot_y = du->hotspot_y;
    394  1.7  riastrad 
    395  1.7  riastrad 	if (plane->state->fb) {
    396  1.7  riastrad 		hotspot_x += plane->state->fb->hot_x;
    397  1.7  riastrad 		hotspot_y += plane->state->fb->hot_y;
    398  1.7  riastrad 	}
    399  1.7  riastrad 
    400  1.7  riastrad 	du->cursor_surface = vps->surf;
    401  1.7  riastrad 	du->cursor_bo = vps->bo;
    402  1.7  riastrad 
    403  1.7  riastrad 	if (vps->surf) {
    404  1.7  riastrad 		du->cursor_age = du->cursor_surface->snooper.age;
    405  1.7  riastrad 
    406  1.7  riastrad 		ret = vmw_cursor_update_image(dev_priv,
    407  1.7  riastrad 					      vps->surf->snooper.image,
    408  1.7  riastrad 					      64, 64, hotspot_x,
    409  1.7  riastrad 					      hotspot_y);
    410  1.7  riastrad 	} else if (vps->bo) {
    411  1.7  riastrad 		ret = vmw_cursor_update_bo(dev_priv, vps->bo,
    412  1.7  riastrad 					   plane->state->crtc_w,
    413  1.7  riastrad 					   plane->state->crtc_h,
    414  1.7  riastrad 					   hotspot_x, hotspot_y);
    415  1.7  riastrad 	} else {
    416  1.7  riastrad 		vmw_cursor_update_position(dev_priv, false, 0, 0);
    417  1.7  riastrad 		return;
    418  1.7  riastrad 	}
    419  1.7  riastrad 
    420  1.7  riastrad 	if (!ret) {
    421  1.7  riastrad 		du->cursor_x = plane->state->crtc_x + du->set_gui_x;
    422  1.7  riastrad 		du->cursor_y = plane->state->crtc_y + du->set_gui_y;
    423  1.7  riastrad 
    424  1.7  riastrad 		vmw_cursor_update_position(dev_priv, true,
    425  1.7  riastrad 					   du->cursor_x + hotspot_x,
    426  1.7  riastrad 					   du->cursor_y + hotspot_y);
    427  1.7  riastrad 
    428  1.7  riastrad 		du->core_hotspot_x = hotspot_x - du->hotspot_x;
    429  1.7  riastrad 		du->core_hotspot_y = hotspot_y - du->hotspot_y;
    430  1.7  riastrad 	} else {
    431  1.7  riastrad 		DRM_ERROR("Failed to update cursor image\n");
    432  1.7  riastrad 	}
    433  1.7  riastrad }
    434  1.7  riastrad 
    435  1.7  riastrad 
    436  1.7  riastrad /**
    437  1.7  riastrad  * vmw_du_primary_plane_atomic_check - check if the new state is okay
    438  1.7  riastrad  *
    439  1.7  riastrad  * @plane: display plane
    440  1.7  riastrad  * @state: info on the new plane state, including the FB
    441  1.7  riastrad  *
    442  1.7  riastrad  * Check if the new state is settable given the current state.  Other
    443  1.7  riastrad  * than what the atomic helper checks, we care about crtc fitting
    444  1.7  riastrad  * the FB and maintaining one active framebuffer.
    445  1.7  riastrad  *
    446  1.7  riastrad  * Returns 0 on success
    447  1.7  riastrad  */
    448  1.7  riastrad int vmw_du_primary_plane_atomic_check(struct drm_plane *plane,
    449  1.7  riastrad 				      struct drm_plane_state *state)
    450  1.7  riastrad {
    451  1.7  riastrad 	struct drm_crtc_state *crtc_state = NULL;
    452  1.7  riastrad 	struct drm_framebuffer *new_fb = state->fb;
    453  1.7  riastrad 	int ret;
    454  1.7  riastrad 
    455  1.7  riastrad 	if (state->crtc)
    456  1.7  riastrad 		crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
    457  1.7  riastrad 
    458  1.7  riastrad 	ret = drm_atomic_helper_check_plane_state(state, crtc_state,
    459  1.7  riastrad 						  DRM_PLANE_HELPER_NO_SCALING,
    460  1.7  riastrad 						  DRM_PLANE_HELPER_NO_SCALING,
    461  1.7  riastrad 						  false, true);
    462  1.7  riastrad 
    463  1.7  riastrad 	if (!ret && new_fb) {
    464  1.7  riastrad 		struct drm_crtc *crtc = state->crtc;
    465  1.7  riastrad 		struct vmw_connector_state *vcs;
    466  1.7  riastrad 		struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
    467  1.7  riastrad 
    468  1.7  riastrad 		vcs = vmw_connector_state_to_vcs(du->connector.state);
    469  1.7  riastrad 	}
    470  1.7  riastrad 
    471  1.7  riastrad 
    472  1.7  riastrad 	return ret;
    473  1.7  riastrad }
    474  1.7  riastrad 
    475  1.7  riastrad 
    476  1.7  riastrad /**
    477  1.7  riastrad  * vmw_du_cursor_plane_atomic_check - check if the new state is okay
    478  1.7  riastrad  *
    479  1.7  riastrad  * @plane: cursor plane
    480  1.7  riastrad  * @state: info on the new plane state
    481  1.7  riastrad  *
    482  1.7  riastrad  * This is a chance to fail if the new cursor state does not fit
    483  1.7  riastrad  * our requirements.
    484  1.7  riastrad  *
    485  1.7  riastrad  * Returns 0 on success
    486  1.7  riastrad  */
    487  1.7  riastrad int vmw_du_cursor_plane_atomic_check(struct drm_plane *plane,
    488  1.7  riastrad 				     struct drm_plane_state *new_state)
    489  1.7  riastrad {
    490  1.7  riastrad 	int ret = 0;
    491  1.7  riastrad 	struct drm_crtc_state *crtc_state = NULL;
    492  1.7  riastrad 	struct vmw_surface *surface = NULL;
    493  1.7  riastrad 	struct drm_framebuffer *fb = new_state->fb;
    494  1.7  riastrad 
    495  1.7  riastrad 	if (new_state->crtc)
    496  1.7  riastrad 		crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
    497  1.7  riastrad 							   new_state->crtc);
    498  1.7  riastrad 
    499  1.7  riastrad 	ret = drm_atomic_helper_check_plane_state(new_state, crtc_state,
    500  1.7  riastrad 						  DRM_PLANE_HELPER_NO_SCALING,
    501  1.7  riastrad 						  DRM_PLANE_HELPER_NO_SCALING,
    502  1.7  riastrad 						  true, true);
    503  1.7  riastrad 	if (ret)
    504  1.7  riastrad 		return ret;
    505  1.7  riastrad 
    506  1.7  riastrad 	/* Turning off */
    507  1.7  riastrad 	if (!fb)
    508  1.7  riastrad 		return 0;
    509  1.7  riastrad 
    510  1.7  riastrad 	/* A lot of the code assumes this */
    511  1.7  riastrad 	if (new_state->crtc_w != 64 || new_state->crtc_h != 64) {
    512  1.7  riastrad 		DRM_ERROR("Invalid cursor dimensions (%d, %d)\n",
    513  1.7  riastrad 			  new_state->crtc_w, new_state->crtc_h);
    514  1.7  riastrad 		ret = -EINVAL;
    515  1.7  riastrad 	}
    516  1.7  riastrad 
    517  1.7  riastrad 	if (!vmw_framebuffer_to_vfb(fb)->bo)
    518  1.7  riastrad 		surface = vmw_framebuffer_to_vfbs(fb)->surface;
    519  1.7  riastrad 
    520  1.7  riastrad 	if (surface && !surface->snooper.image) {
    521  1.7  riastrad 		DRM_ERROR("surface not suitable for cursor\n");
    522  1.7  riastrad 		ret = -EINVAL;
    523  1.7  riastrad 	}
    524  1.7  riastrad 
    525  1.7  riastrad 	return ret;
    526  1.7  riastrad }
    527  1.7  riastrad 
    528  1.7  riastrad 
    529  1.7  riastrad int vmw_du_crtc_atomic_check(struct drm_crtc *crtc,
    530  1.7  riastrad 			     struct drm_crtc_state *new_state)
    531  1.7  riastrad {
    532  1.7  riastrad 	struct vmw_display_unit *du = vmw_crtc_to_du(new_state->crtc);
    533  1.7  riastrad 	int connector_mask = drm_connector_mask(&du->connector);
    534  1.7  riastrad 	bool has_primary = new_state->plane_mask &
    535  1.7  riastrad 			   drm_plane_mask(crtc->primary);
    536  1.7  riastrad 
    537  1.7  riastrad 	/* We always want to have an active plane with an active CRTC */
    538  1.7  riastrad 	if (has_primary != new_state->enable)
    539  1.7  riastrad 		return -EINVAL;
    540  1.7  riastrad 
    541  1.7  riastrad 
    542  1.7  riastrad 	if (new_state->connector_mask != connector_mask &&
    543  1.7  riastrad 	    new_state->connector_mask != 0) {
    544  1.7  riastrad 		DRM_ERROR("Invalid connectors configuration\n");
    545  1.7  riastrad 		return -EINVAL;
    546  1.7  riastrad 	}
    547  1.7  riastrad 
    548  1.7  riastrad 	/*
    549  1.7  riastrad 	 * Our virtual device does not have a dot clock, so use the logical
    550  1.7  riastrad 	 * clock value as the dot clock.
    551  1.7  riastrad 	 */
    552  1.7  riastrad 	if (new_state->mode.crtc_clock == 0)
    553  1.7  riastrad 		new_state->adjusted_mode.crtc_clock = new_state->mode.clock;
    554  1.7  riastrad 
    555  1.7  riastrad 	return 0;
    556  1.7  riastrad }
    557  1.7  riastrad 
    558  1.7  riastrad 
    559  1.7  riastrad void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc,
    560  1.7  riastrad 			      struct drm_crtc_state *old_crtc_state)
    561  1.7  riastrad {
    562  1.7  riastrad }
    563  1.7  riastrad 
    564  1.7  riastrad 
    565  1.7  riastrad void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc,
    566  1.7  riastrad 			      struct drm_crtc_state *old_crtc_state)
    567  1.7  riastrad {
    568  1.7  riastrad 	struct drm_pending_vblank_event *event = crtc->state->event;
    569  1.7  riastrad 
    570  1.7  riastrad 	if (event) {
    571  1.7  riastrad 		crtc->state->event = NULL;
    572  1.7  riastrad 
    573  1.7  riastrad 		spin_lock_irq(&crtc->dev->event_lock);
    574  1.7  riastrad 		drm_crtc_send_vblank_event(crtc, event);
    575  1.7  riastrad 		spin_unlock_irq(&crtc->dev->event_lock);
    576  1.7  riastrad 	}
    577  1.7  riastrad }
    578  1.7  riastrad 
    579  1.7  riastrad 
    580  1.7  riastrad /**
    581  1.7  riastrad  * vmw_du_crtc_duplicate_state - duplicate crtc state
    582  1.7  riastrad  * @crtc: DRM crtc
    583  1.7  riastrad  *
    584  1.7  riastrad  * Allocates and returns a copy of the crtc state (both common and
    585  1.7  riastrad  * vmw-specific) for the specified crtc.
    586  1.7  riastrad  *
    587  1.7  riastrad  * Returns: The newly allocated crtc state, or NULL on failure.
    588  1.7  riastrad  */
    589  1.7  riastrad struct drm_crtc_state *
    590  1.7  riastrad vmw_du_crtc_duplicate_state(struct drm_crtc *crtc)
    591  1.7  riastrad {
    592  1.7  riastrad 	struct drm_crtc_state *state;
    593  1.7  riastrad 	struct vmw_crtc_state *vcs;
    594  1.7  riastrad 
    595  1.7  riastrad 	if (WARN_ON(!crtc->state))
    596  1.7  riastrad 		return NULL;
    597  1.7  riastrad 
    598  1.7  riastrad 	vcs = kmemdup(crtc->state, sizeof(*vcs), GFP_KERNEL);
    599  1.7  riastrad 
    600  1.7  riastrad 	if (!vcs)
    601  1.7  riastrad 		return NULL;
    602  1.7  riastrad 
    603  1.7  riastrad 	state = &vcs->base;
    604  1.7  riastrad 
    605  1.7  riastrad 	__drm_atomic_helper_crtc_duplicate_state(crtc, state);
    606  1.7  riastrad 
    607  1.7  riastrad 	return state;
    608  1.7  riastrad }
    609  1.7  riastrad 
    610  1.7  riastrad 
    611  1.7  riastrad /**
    612  1.7  riastrad  * vmw_du_crtc_reset - creates a blank vmw crtc state
    613  1.7  riastrad  * @crtc: DRM crtc
    614  1.7  riastrad  *
    615  1.7  riastrad  * Resets the atomic state for @crtc by freeing the state pointer (which
    616  1.7  riastrad  * might be NULL, e.g. at driver load time) and allocating a new empty state
    617  1.7  riastrad  * object.
    618  1.7  riastrad  */
    619  1.7  riastrad void vmw_du_crtc_reset(struct drm_crtc *crtc)
    620  1.7  riastrad {
    621  1.7  riastrad 	struct vmw_crtc_state *vcs;
    622  1.7  riastrad 
    623  1.7  riastrad 
    624  1.7  riastrad 	if (crtc->state) {
    625  1.7  riastrad 		__drm_atomic_helper_crtc_destroy_state(crtc->state);
    626  1.7  riastrad 
    627  1.7  riastrad 		kfree(vmw_crtc_state_to_vcs(crtc->state));
    628  1.7  riastrad 	}
    629  1.7  riastrad 
    630  1.7  riastrad 	vcs = kzalloc(sizeof(*vcs), GFP_KERNEL);
    631  1.7  riastrad 
    632  1.7  riastrad 	if (!vcs) {
    633  1.7  riastrad 		DRM_ERROR("Cannot allocate vmw_crtc_state\n");
    634  1.7  riastrad 		return;
    635  1.7  riastrad 	}
    636  1.7  riastrad 
    637  1.7  riastrad 	crtc->state = &vcs->base;
    638  1.7  riastrad 	crtc->state->crtc = crtc;
    639  1.7  riastrad }
    640  1.7  riastrad 
    641  1.7  riastrad 
    642  1.7  riastrad /**
    643  1.7  riastrad  * vmw_du_crtc_destroy_state - destroy crtc state
    644  1.7  riastrad  * @crtc: DRM crtc
    645  1.7  riastrad  * @state: state object to destroy
    646  1.7  riastrad  *
    647  1.7  riastrad  * Destroys the crtc state (both common and vmw-specific) for the
    648  1.7  riastrad  * specified plane.
    649  1.7  riastrad  */
    650  1.7  riastrad void
    651  1.7  riastrad vmw_du_crtc_destroy_state(struct drm_crtc *crtc,
    652  1.7  riastrad 			  struct drm_crtc_state *state)
    653  1.7  riastrad {
    654  1.7  riastrad 	drm_atomic_helper_crtc_destroy_state(crtc, state);
    655  1.7  riastrad }
    656  1.7  riastrad 
    657  1.7  riastrad 
    658  1.7  riastrad /**
    659  1.7  riastrad  * vmw_du_plane_duplicate_state - duplicate plane state
    660  1.7  riastrad  * @plane: drm plane
    661  1.7  riastrad  *
    662  1.7  riastrad  * Allocates and returns a copy of the plane state (both common and
    663  1.7  riastrad  * vmw-specific) for the specified plane.
    664  1.7  riastrad  *
    665  1.7  riastrad  * Returns: The newly allocated plane state, or NULL on failure.
    666  1.7  riastrad  */
    667  1.7  riastrad struct drm_plane_state *
    668  1.7  riastrad vmw_du_plane_duplicate_state(struct drm_plane *plane)
    669  1.7  riastrad {
    670  1.7  riastrad 	struct drm_plane_state *state;
    671  1.7  riastrad 	struct vmw_plane_state *vps;
    672  1.7  riastrad 
    673  1.7  riastrad 	vps = kmemdup(plane->state, sizeof(*vps), GFP_KERNEL);
    674  1.7  riastrad 
    675  1.7  riastrad 	if (!vps)
    676  1.7  riastrad 		return NULL;
    677  1.7  riastrad 
    678  1.7  riastrad 	vps->pinned = 0;
    679  1.7  riastrad 	vps->cpp = 0;
    680  1.7  riastrad 
    681  1.7  riastrad 	/* Each ref counted resource needs to be acquired again */
    682  1.7  riastrad 	if (vps->surf)
    683  1.7  riastrad 		(void) vmw_surface_reference(vps->surf);
    684  1.7  riastrad 
    685  1.7  riastrad 	if (vps->bo)
    686  1.7  riastrad 		(void) vmw_bo_reference(vps->bo);
    687  1.7  riastrad 
    688  1.7  riastrad 	state = &vps->base;
    689  1.7  riastrad 
    690  1.7  riastrad 	__drm_atomic_helper_plane_duplicate_state(plane, state);
    691  1.7  riastrad 
    692  1.7  riastrad 	return state;
    693  1.7  riastrad }
    694  1.7  riastrad 
    695  1.7  riastrad 
    696  1.7  riastrad /**
    697  1.7  riastrad  * vmw_du_plane_reset - creates a blank vmw plane state
    698  1.7  riastrad  * @plane: drm plane
    699  1.7  riastrad  *
    700  1.7  riastrad  * Resets the atomic state for @plane by freeing the state pointer (which might
    701  1.7  riastrad  * be NULL, e.g. at driver load time) and allocating a new empty state object.
    702  1.7  riastrad  */
    703  1.7  riastrad void vmw_du_plane_reset(struct drm_plane *plane)
    704  1.7  riastrad {
    705  1.7  riastrad 	struct vmw_plane_state *vps;
    706  1.7  riastrad 
    707  1.7  riastrad 
    708  1.7  riastrad 	if (plane->state)
    709  1.7  riastrad 		vmw_du_plane_destroy_state(plane, plane->state);
    710  1.7  riastrad 
    711  1.7  riastrad 	vps = kzalloc(sizeof(*vps), GFP_KERNEL);
    712  1.7  riastrad 
    713  1.7  riastrad 	if (!vps) {
    714  1.7  riastrad 		DRM_ERROR("Cannot allocate vmw_plane_state\n");
    715  1.7  riastrad 		return;
    716  1.7  riastrad 	}
    717  1.7  riastrad 
    718  1.7  riastrad 	__drm_atomic_helper_plane_reset(plane, &vps->base);
    719  1.7  riastrad }
    720  1.7  riastrad 
    721  1.7  riastrad 
    722  1.7  riastrad /**
    723  1.7  riastrad  * vmw_du_plane_destroy_state - destroy plane state
    724  1.7  riastrad  * @plane: DRM plane
    725  1.7  riastrad  * @state: state object to destroy
    726  1.7  riastrad  *
    727  1.7  riastrad  * Destroys the plane state (both common and vmw-specific) for the
    728  1.7  riastrad  * specified plane.
    729  1.7  riastrad  */
    730  1.7  riastrad void
    731  1.7  riastrad vmw_du_plane_destroy_state(struct drm_plane *plane,
    732  1.7  riastrad 			   struct drm_plane_state *state)
    733  1.7  riastrad {
    734  1.7  riastrad 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(state);
    735  1.7  riastrad 
    736  1.7  riastrad 
    737  1.7  riastrad 	/* Should have been freed by cleanup_fb */
    738  1.7  riastrad 	if (vps->surf)
    739  1.7  riastrad 		vmw_surface_unreference(&vps->surf);
    740  1.1  riastrad 
    741  1.7  riastrad 	if (vps->bo)
    742  1.7  riastrad 		vmw_bo_unreference(&vps->bo);
    743  1.1  riastrad 
    744  1.7  riastrad 	drm_atomic_helper_plane_destroy_state(plane, state);
    745  1.1  riastrad }
    746  1.1  riastrad 
    747  1.7  riastrad 
    748  1.4  riastrad /**
    749  1.7  riastrad  * vmw_du_connector_duplicate_state - duplicate connector state
    750  1.7  riastrad  * @connector: DRM connector
    751  1.4  riastrad  *
    752  1.7  riastrad  * Allocates and returns a copy of the connector state (both common and
    753  1.7  riastrad  * vmw-specific) for the specified connector.
    754  1.4  riastrad  *
    755  1.7  riastrad  * Returns: The newly allocated connector state, or NULL on failure.
    756  1.4  riastrad  */
    757  1.7  riastrad struct drm_connector_state *
    758  1.7  riastrad vmw_du_connector_duplicate_state(struct drm_connector *connector)
    759  1.4  riastrad {
    760  1.7  riastrad 	struct drm_connector_state *state;
    761  1.7  riastrad 	struct vmw_connector_state *vcs;
    762  1.7  riastrad 
    763  1.7  riastrad 	if (WARN_ON(!connector->state))
    764  1.7  riastrad 		return NULL;
    765  1.7  riastrad 
    766  1.7  riastrad 	vcs = kmemdup(connector->state, sizeof(*vcs), GFP_KERNEL);
    767  1.7  riastrad 
    768  1.7  riastrad 	if (!vcs)
    769  1.7  riastrad 		return NULL;
    770  1.7  riastrad 
    771  1.7  riastrad 	state = &vcs->base;
    772  1.4  riastrad 
    773  1.7  riastrad 	__drm_atomic_helper_connector_duplicate_state(connector, state);
    774  1.4  riastrad 
    775  1.7  riastrad 	return state;
    776  1.4  riastrad }
    777  1.4  riastrad 
    778  1.7  riastrad 
    779  1.7  riastrad /**
    780  1.7  riastrad  * vmw_du_connector_reset - creates a blank vmw connector state
    781  1.7  riastrad  * @connector: DRM connector
    782  1.7  riastrad  *
    783  1.7  riastrad  * Resets the atomic state for @connector by freeing the state pointer (which
    784  1.7  riastrad  * might be NULL, e.g. at driver load time) and allocating a new empty state
    785  1.7  riastrad  * object.
    786  1.7  riastrad  */
    787  1.7  riastrad void vmw_du_connector_reset(struct drm_connector *connector)
    788  1.1  riastrad {
    789  1.7  riastrad 	struct vmw_connector_state *vcs;
    790  1.7  riastrad 
    791  1.7  riastrad 
    792  1.7  riastrad 	if (connector->state) {
    793  1.7  riastrad 		__drm_atomic_helper_connector_destroy_state(connector->state);
    794  1.1  riastrad 
    795  1.7  riastrad 		kfree(vmw_connector_state_to_vcs(connector->state));
    796  1.7  riastrad 	}
    797  1.1  riastrad 
    798  1.7  riastrad 	vcs = kzalloc(sizeof(*vcs), GFP_KERNEL);
    799  1.1  riastrad 
    800  1.7  riastrad 	if (!vcs) {
    801  1.7  riastrad 		DRM_ERROR("Cannot allocate vmw_connector_state\n");
    802  1.7  riastrad 		return;
    803  1.1  riastrad 	}
    804  1.1  riastrad 
    805  1.7  riastrad 	__drm_atomic_helper_connector_reset(connector, &vcs->base);
    806  1.1  riastrad }
    807  1.1  riastrad 
    808  1.7  riastrad 
    809  1.7  riastrad /**
    810  1.7  riastrad  * vmw_du_connector_destroy_state - destroy connector state
    811  1.7  riastrad  * @connector: DRM connector
    812  1.7  riastrad  * @state: state object to destroy
    813  1.7  riastrad  *
    814  1.7  riastrad  * Destroys the connector state (both common and vmw-specific) for the
    815  1.7  riastrad  * specified plane.
    816  1.7  riastrad  */
    817  1.7  riastrad void
    818  1.7  riastrad vmw_du_connector_destroy_state(struct drm_connector *connector,
    819  1.7  riastrad 			  struct drm_connector_state *state)
    820  1.7  riastrad {
    821  1.7  riastrad 	drm_atomic_helper_connector_destroy_state(connector, state);
    822  1.7  riastrad }
    823  1.1  riastrad /*
    824  1.1  riastrad  * Generic framebuffer code
    825  1.1  riastrad  */
    826  1.1  riastrad 
    827  1.1  riastrad /*
    828  1.1  riastrad  * Surface framebuffer code
    829  1.1  riastrad  */
    830  1.1  riastrad 
    831  1.3  riastrad static void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
    832  1.1  riastrad {
    833  1.1  riastrad 	struct vmw_framebuffer_surface *vfbs =
    834  1.1  riastrad 		vmw_framebuffer_to_vfbs(framebuffer);
    835  1.1  riastrad 
    836  1.1  riastrad 	drm_framebuffer_cleanup(framebuffer);
    837  1.1  riastrad 	vmw_surface_unreference(&vfbs->surface);
    838  1.4  riastrad 	if (vfbs->base.user_obj)
    839  1.4  riastrad 		ttm_base_object_unref(&vfbs->base.user_obj);
    840  1.1  riastrad 
    841  1.1  riastrad 	kfree(vfbs);
    842  1.1  riastrad }
    843  1.1  riastrad 
    844  1.4  riastrad /**
    845  1.4  riastrad  * vmw_kms_readback - Perform a readback from the screen system to
    846  1.7  riastrad  * a buffer-object backed framebuffer.
    847  1.4  riastrad  *
    848  1.4  riastrad  * @dev_priv: Pointer to the device private structure.
    849  1.4  riastrad  * @file_priv: Pointer to a struct drm_file identifying the caller.
    850  1.4  riastrad  * Must be set to NULL if @user_fence_rep is NULL.
    851  1.7  riastrad  * @vfb: Pointer to the buffer-object backed framebuffer.
    852  1.4  riastrad  * @user_fence_rep: User-space provided structure for fence information.
    853  1.4  riastrad  * Must be set to non-NULL if @file_priv is non-NULL.
    854  1.4  riastrad  * @vclips: Array of clip rects.
    855  1.4  riastrad  * @num_clips: Number of clip rects in @vclips.
    856  1.4  riastrad  *
    857  1.4  riastrad  * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
    858  1.4  riastrad  * interrupted.
    859  1.4  riastrad  */
    860  1.4  riastrad int vmw_kms_readback(struct vmw_private *dev_priv,
    861  1.4  riastrad 		     struct drm_file *file_priv,
    862  1.4  riastrad 		     struct vmw_framebuffer *vfb,
    863  1.4  riastrad 		     struct drm_vmw_fence_rep __user *user_fence_rep,
    864  1.4  riastrad 		     struct drm_vmw_rect *vclips,
    865  1.4  riastrad 		     uint32_t num_clips)
    866  1.4  riastrad {
    867  1.4  riastrad 	switch (dev_priv->active_display_unit) {
    868  1.4  riastrad 	case vmw_du_screen_object:
    869  1.4  riastrad 		return vmw_kms_sou_readback(dev_priv, file_priv, vfb,
    870  1.7  riastrad 					    user_fence_rep, vclips, num_clips,
    871  1.7  riastrad 					    NULL);
    872  1.4  riastrad 	case vmw_du_screen_target:
    873  1.4  riastrad 		return vmw_kms_stdu_dma(dev_priv, file_priv, vfb,
    874  1.4  riastrad 					user_fence_rep, NULL, vclips, num_clips,
    875  1.7  riastrad 					1, false, true, NULL);
    876  1.4  riastrad 	default:
    877  1.4  riastrad 		WARN_ONCE(true,
    878  1.4  riastrad 			  "Readback called with invalid display system.\n");
    879  1.4  riastrad }
    880  1.4  riastrad 
    881  1.4  riastrad 	return -ENOSYS;
    882  1.4  riastrad }
    883  1.4  riastrad 
    884  1.4  riastrad 
    885  1.7  riastrad static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
    886  1.1  riastrad 	.destroy = vmw_framebuffer_surface_destroy,
    887  1.7  riastrad 	.dirty = drm_atomic_helper_dirtyfb,
    888  1.1  riastrad };
    889  1.1  riastrad 
    890  1.1  riastrad static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
    891  1.1  riastrad 					   struct vmw_surface *surface,
    892  1.1  riastrad 					   struct vmw_framebuffer **out,
    893  1.7  riastrad 					   const struct drm_mode_fb_cmd2
    894  1.4  riastrad 					   *mode_cmd,
    895  1.7  riastrad 					   bool is_bo_proxy)
    896  1.1  riastrad 
    897  1.1  riastrad {
    898  1.1  riastrad 	struct drm_device *dev = dev_priv->dev;
    899  1.1  riastrad 	struct vmw_framebuffer_surface *vfbs;
    900  1.1  riastrad 	enum SVGA3dSurfaceFormat format;
    901  1.1  riastrad 	int ret;
    902  1.7  riastrad 	struct drm_format_name_buf format_name;
    903  1.1  riastrad 
    904  1.4  riastrad 	/* 3D is only supported on HWv8 and newer hosts */
    905  1.4  riastrad 	if (dev_priv->active_display_unit == vmw_du_legacy)
    906  1.1  riastrad 		return -ENOSYS;
    907  1.1  riastrad 
    908  1.1  riastrad 	/*
    909  1.1  riastrad 	 * Sanity checks.
    910  1.1  riastrad 	 */
    911  1.1  riastrad 
    912  1.1  riastrad 	/* Surface must be marked as a scanout. */
    913  1.1  riastrad 	if (unlikely(!surface->scanout))
    914  1.1  riastrad 		return -EINVAL;
    915  1.1  riastrad 
    916  1.1  riastrad 	if (unlikely(surface->mip_levels[0] != 1 ||
    917  1.1  riastrad 		     surface->num_sizes != 1 ||
    918  1.3  riastrad 		     surface->base_size.width < mode_cmd->width ||
    919  1.3  riastrad 		     surface->base_size.height < mode_cmd->height ||
    920  1.3  riastrad 		     surface->base_size.depth != 1)) {
    921  1.1  riastrad 		DRM_ERROR("Incompatible surface dimensions "
    922  1.1  riastrad 			  "for requested mode.\n");
    923  1.1  riastrad 		return -EINVAL;
    924  1.1  riastrad 	}
    925  1.1  riastrad 
    926  1.7  riastrad 	switch (mode_cmd->pixel_format) {
    927  1.7  riastrad 	case DRM_FORMAT_ARGB8888:
    928  1.1  riastrad 		format = SVGA3D_A8R8G8B8;
    929  1.1  riastrad 		break;
    930  1.7  riastrad 	case DRM_FORMAT_XRGB8888:
    931  1.1  riastrad 		format = SVGA3D_X8R8G8B8;
    932  1.1  riastrad 		break;
    933  1.7  riastrad 	case DRM_FORMAT_RGB565:
    934  1.1  riastrad 		format = SVGA3D_R5G6B5;
    935  1.1  riastrad 		break;
    936  1.7  riastrad 	case DRM_FORMAT_XRGB1555:
    937  1.1  riastrad 		format = SVGA3D_A1R5G5B5;
    938  1.1  riastrad 		break;
    939  1.1  riastrad 	default:
    940  1.7  riastrad 		DRM_ERROR("Invalid pixel format: %s\n",
    941  1.7  riastrad 			  drm_get_format_name(mode_cmd->pixel_format, &format_name));
    942  1.1  riastrad 		return -EINVAL;
    943  1.1  riastrad 	}
    944  1.1  riastrad 
    945  1.4  riastrad 	/*
    946  1.4  riastrad 	 * For DX, surface format validation is done when surface->scanout
    947  1.4  riastrad 	 * is set.
    948  1.4  riastrad 	 */
    949  1.4  riastrad 	if (!dev_priv->has_dx && format != surface->format) {
    950  1.1  riastrad 		DRM_ERROR("Invalid surface format for requested mode.\n");
    951  1.1  riastrad 		return -EINVAL;
    952  1.1  riastrad 	}
    953  1.1  riastrad 
    954  1.1  riastrad 	vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL);
    955  1.1  riastrad 	if (!vfbs) {
    956  1.1  riastrad 		ret = -ENOMEM;
    957  1.1  riastrad 		goto out_err1;
    958  1.1  riastrad 	}
    959  1.1  riastrad 
    960  1.7  riastrad 	drm_helper_mode_fill_fb_struct(dev, &vfbs->base.base, mode_cmd);
    961  1.4  riastrad 	vfbs->surface = vmw_surface_reference(surface);
    962  1.7  riastrad 	vfbs->base.user_handle = mode_cmd->handles[0];
    963  1.7  riastrad 	vfbs->is_bo_proxy = is_bo_proxy;
    964  1.1  riastrad 
    965  1.1  riastrad 	*out = &vfbs->base;
    966  1.1  riastrad 
    967  1.3  riastrad 	ret = drm_framebuffer_init(dev, &vfbs->base.base,
    968  1.3  riastrad 				   &vmw_framebuffer_surface_funcs);
    969  1.3  riastrad 	if (ret)
    970  1.4  riastrad 		goto out_err2;
    971  1.3  riastrad 
    972  1.1  riastrad 	return 0;
    973  1.1  riastrad 
    974  1.4  riastrad out_err2:
    975  1.3  riastrad 	vmw_surface_unreference(&surface);
    976  1.1  riastrad 	kfree(vfbs);
    977  1.1  riastrad out_err1:
    978  1.1  riastrad 	return ret;
    979  1.1  riastrad }
    980  1.1  riastrad 
    981  1.1  riastrad /*
    982  1.7  riastrad  * Buffer-object framebuffer code
    983  1.1  riastrad  */
    984  1.1  riastrad 
    985  1.7  riastrad static void vmw_framebuffer_bo_destroy(struct drm_framebuffer *framebuffer)
    986  1.1  riastrad {
    987  1.7  riastrad 	struct vmw_framebuffer_bo *vfbd =
    988  1.1  riastrad 		vmw_framebuffer_to_vfbd(framebuffer);
    989  1.1  riastrad 
    990  1.1  riastrad 	drm_framebuffer_cleanup(framebuffer);
    991  1.7  riastrad 	vmw_bo_unreference(&vfbd->buffer);
    992  1.4  riastrad 	if (vfbd->base.user_obj)
    993  1.4  riastrad 		ttm_base_object_unref(&vfbd->base.user_obj);
    994  1.1  riastrad 
    995  1.1  riastrad 	kfree(vfbd);
    996  1.1  riastrad }
    997  1.1  riastrad 
    998  1.7  riastrad static int vmw_framebuffer_bo_dirty(struct drm_framebuffer *framebuffer,
    999  1.7  riastrad 				    struct drm_file *file_priv,
   1000  1.7  riastrad 				    unsigned int flags, unsigned int color,
   1001  1.7  riastrad 				    struct drm_clip_rect *clips,
   1002  1.7  riastrad 				    unsigned int num_clips)
   1003  1.1  riastrad {
   1004  1.1  riastrad 	struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
   1005  1.7  riastrad 	struct vmw_framebuffer_bo *vfbd =
   1006  1.1  riastrad 		vmw_framebuffer_to_vfbd(framebuffer);
   1007  1.1  riastrad 	struct drm_clip_rect norect;
   1008  1.1  riastrad 	int ret, increment = 1;
   1009  1.1  riastrad 
   1010  1.3  riastrad 	drm_modeset_lock_all(dev_priv->dev);
   1011  1.3  riastrad 
   1012  1.3  riastrad 	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
   1013  1.3  riastrad 	if (unlikely(ret != 0)) {
   1014  1.3  riastrad 		drm_modeset_unlock_all(dev_priv->dev);
   1015  1.1  riastrad 		return ret;
   1016  1.3  riastrad 	}
   1017  1.1  riastrad 
   1018  1.1  riastrad 	if (!num_clips) {
   1019  1.1  riastrad 		num_clips = 1;
   1020  1.1  riastrad 		clips = &norect;
   1021  1.1  riastrad 		norect.x1 = norect.y1 = 0;
   1022  1.1  riastrad 		norect.x2 = framebuffer->width;
   1023  1.1  riastrad 		norect.y2 = framebuffer->height;
   1024  1.1  riastrad 	} else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
   1025  1.1  riastrad 		num_clips /= 2;
   1026  1.1  riastrad 		increment = 2;
   1027  1.1  riastrad 	}
   1028  1.1  riastrad 
   1029  1.4  riastrad 	switch (dev_priv->active_display_unit) {
   1030  1.4  riastrad 	case vmw_du_legacy:
   1031  1.7  riastrad 		ret = vmw_kms_ldu_do_bo_dirty(dev_priv, &vfbd->base, 0, 0,
   1032  1.7  riastrad 					      clips, num_clips, increment);
   1033  1.4  riastrad 		break;
   1034  1.4  riastrad 	default:
   1035  1.4  riastrad 		ret = -EINVAL;
   1036  1.4  riastrad 		WARN_ONCE(true, "Dirty called with invalid display system.\n");
   1037  1.4  riastrad 		break;
   1038  1.1  riastrad 	}
   1039  1.1  riastrad 
   1040  1.4  riastrad 	vmw_fifo_flush(dev_priv, false);
   1041  1.3  riastrad 	ttm_read_unlock(&dev_priv->reservation_sem);
   1042  1.3  riastrad 
   1043  1.3  riastrad 	drm_modeset_unlock_all(dev_priv->dev);
   1044  1.3  riastrad 
   1045  1.1  riastrad 	return ret;
   1046  1.1  riastrad }
   1047  1.1  riastrad 
   1048  1.7  riastrad static int vmw_framebuffer_bo_dirty_ext(struct drm_framebuffer *framebuffer,
   1049  1.7  riastrad 					struct drm_file *file_priv,
   1050  1.7  riastrad 					unsigned int flags, unsigned int color,
   1051  1.7  riastrad 					struct drm_clip_rect *clips,
   1052  1.7  riastrad 					unsigned int num_clips)
   1053  1.7  riastrad {
   1054  1.7  riastrad 	struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
   1055  1.7  riastrad 
   1056  1.7  riastrad 	if (dev_priv->active_display_unit == vmw_du_legacy)
   1057  1.7  riastrad 		return vmw_framebuffer_bo_dirty(framebuffer, file_priv, flags,
   1058  1.7  riastrad 						color, clips, num_clips);
   1059  1.7  riastrad 
   1060  1.7  riastrad 	return drm_atomic_helper_dirtyfb(framebuffer, file_priv, flags, color,
   1061  1.7  riastrad 					 clips, num_clips);
   1062  1.7  riastrad }
   1063  1.7  riastrad 
   1064  1.7  riastrad static const struct drm_framebuffer_funcs vmw_framebuffer_bo_funcs = {
   1065  1.7  riastrad 	.destroy = vmw_framebuffer_bo_destroy,
   1066  1.7  riastrad 	.dirty = vmw_framebuffer_bo_dirty_ext,
   1067  1.1  riastrad };
   1068  1.1  riastrad 
   1069  1.1  riastrad /**
   1070  1.7  riastrad  * Pin the bofer in a location suitable for access by the
   1071  1.7  riastrad  * display system.
   1072  1.1  riastrad  */
   1073  1.4  riastrad static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb)
   1074  1.1  riastrad {
   1075  1.1  riastrad 	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
   1076  1.7  riastrad 	struct vmw_buffer_object *buf;
   1077  1.7  riastrad 	struct ttm_placement *placement;
   1078  1.1  riastrad 	int ret;
   1079  1.1  riastrad 
   1080  1.7  riastrad 	buf = vfb->bo ?  vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
   1081  1.4  riastrad 		vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup;
   1082  1.1  riastrad 
   1083  1.4  riastrad 	if (!buf)
   1084  1.4  riastrad 		return 0;
   1085  1.1  riastrad 
   1086  1.4  riastrad 	switch (dev_priv->active_display_unit) {
   1087  1.4  riastrad 	case vmw_du_legacy:
   1088  1.4  riastrad 		vmw_overlay_pause_all(dev_priv);
   1089  1.7  riastrad 		ret = vmw_bo_pin_in_start_of_vram(dev_priv, buf, false);
   1090  1.4  riastrad 		vmw_overlay_resume_all(dev_priv);
   1091  1.4  riastrad 		break;
   1092  1.4  riastrad 	case vmw_du_screen_object:
   1093  1.4  riastrad 	case vmw_du_screen_target:
   1094  1.7  riastrad 		if (vfb->bo) {
   1095  1.7  riastrad 			if (dev_priv->capabilities & SVGA_CAP_3D) {
   1096  1.7  riastrad 				/*
   1097  1.7  riastrad 				 * Use surface DMA to get content to
   1098  1.7  riastrad 				 * sreen target surface.
   1099  1.7  riastrad 				 */
   1100  1.7  riastrad 				placement = &vmw_vram_gmr_placement;
   1101  1.7  riastrad 			} else {
   1102  1.7  riastrad 				/* Use CPU blit. */
   1103  1.7  riastrad 				placement = &vmw_sys_placement;
   1104  1.7  riastrad 			}
   1105  1.7  riastrad 		} else {
   1106  1.7  riastrad 			/* Use surface / image update */
   1107  1.7  riastrad 			placement = &vmw_mob_placement;
   1108  1.7  riastrad 		}
   1109  1.1  riastrad 
   1110  1.7  riastrad 		return vmw_bo_pin_in_placement(dev_priv, buf, placement, false);
   1111  1.4  riastrad 	default:
   1112  1.4  riastrad 		return -EINVAL;
   1113  1.4  riastrad 	}
   1114  1.1  riastrad 
   1115  1.4  riastrad 	return ret;
   1116  1.1  riastrad }
   1117  1.1  riastrad 
   1118  1.4  riastrad static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb)
   1119  1.1  riastrad {
   1120  1.1  riastrad 	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
   1121  1.7  riastrad 	struct vmw_buffer_object *buf;
   1122  1.4  riastrad 
   1123  1.7  riastrad 	buf = vfb->bo ?  vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
   1124  1.4  riastrad 		vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup;
   1125  1.1  riastrad 
   1126  1.4  riastrad 	if (WARN_ON(!buf))
   1127  1.1  riastrad 		return 0;
   1128  1.4  riastrad 
   1129  1.7  riastrad 	return vmw_bo_unpin(dev_priv, buf, false);
   1130  1.4  riastrad }
   1131  1.4  riastrad 
   1132  1.4  riastrad /**
   1133  1.7  riastrad  * vmw_create_bo_proxy - create a proxy surface for the buffer object
   1134  1.4  riastrad  *
   1135  1.4  riastrad  * @dev: DRM device
   1136  1.4  riastrad  * @mode_cmd: parameters for the new surface
   1137  1.7  riastrad  * @bo_mob: MOB backing the buffer object
   1138  1.4  riastrad  * @srf_out: newly created surface
   1139  1.4  riastrad  *
   1140  1.7  riastrad  * When the content FB is a buffer object, we create a surface as a proxy to the
   1141  1.4  riastrad  * same buffer.  This way we can do a surface copy rather than a surface DMA.
   1142  1.4  riastrad  * This is a more efficient approach
   1143  1.4  riastrad  *
   1144  1.4  riastrad  * RETURNS:
   1145  1.4  riastrad  * 0 on success, error code otherwise
   1146  1.4  riastrad  */
   1147  1.7  riastrad static int vmw_create_bo_proxy(struct drm_device *dev,
   1148  1.7  riastrad 			       const struct drm_mode_fb_cmd2 *mode_cmd,
   1149  1.7  riastrad 			       struct vmw_buffer_object *bo_mob,
   1150  1.7  riastrad 			       struct vmw_surface **srf_out)
   1151  1.4  riastrad {
   1152  1.4  riastrad 	uint32_t format;
   1153  1.7  riastrad 	struct drm_vmw_size content_base_size = {0};
   1154  1.4  riastrad 	struct vmw_resource *res;
   1155  1.4  riastrad 	unsigned int bytes_pp;
   1156  1.7  riastrad 	struct drm_format_name_buf format_name;
   1157  1.4  riastrad 	int ret;
   1158  1.4  riastrad 
   1159  1.7  riastrad 	switch (mode_cmd->pixel_format) {
   1160  1.7  riastrad 	case DRM_FORMAT_ARGB8888:
   1161  1.7  riastrad 	case DRM_FORMAT_XRGB8888:
   1162  1.4  riastrad 		format = SVGA3D_X8R8G8B8;
   1163  1.4  riastrad 		bytes_pp = 4;
   1164  1.4  riastrad 		break;
   1165  1.4  riastrad 
   1166  1.7  riastrad 	case DRM_FORMAT_RGB565:
   1167  1.7  riastrad 	case DRM_FORMAT_XRGB1555:
   1168  1.4  riastrad 		format = SVGA3D_R5G6B5;
   1169  1.4  riastrad 		bytes_pp = 2;
   1170  1.4  riastrad 		break;
   1171  1.4  riastrad 
   1172  1.4  riastrad 	case 8:
   1173  1.4  riastrad 		format = SVGA3D_P8;
   1174  1.4  riastrad 		bytes_pp = 1;
   1175  1.4  riastrad 		break;
   1176  1.4  riastrad 
   1177  1.4  riastrad 	default:
   1178  1.7  riastrad 		DRM_ERROR("Invalid framebuffer format %s\n",
   1179  1.7  riastrad 			  drm_get_format_name(mode_cmd->pixel_format, &format_name));
   1180  1.4  riastrad 		return -EINVAL;
   1181  1.4  riastrad 	}
   1182  1.4  riastrad 
   1183  1.7  riastrad 	content_base_size.width  = mode_cmd->pitches[0] / bytes_pp;
   1184  1.4  riastrad 	content_base_size.height = mode_cmd->height;
   1185  1.4  riastrad 	content_base_size.depth  = 1;
   1186  1.4  riastrad 
   1187  1.4  riastrad 	ret = vmw_surface_gb_priv_define(dev,
   1188  1.7  riastrad 					 0, /* kernel visible only */
   1189  1.7  riastrad 					 0, /* flags */
   1190  1.7  riastrad 					 format,
   1191  1.7  riastrad 					 true, /* can be a scanout buffer */
   1192  1.7  riastrad 					 1, /* num of mip levels */
   1193  1.7  riastrad 					 0,
   1194  1.7  riastrad 					 0,
   1195  1.7  riastrad 					 content_base_size,
   1196  1.7  riastrad 					 SVGA3D_MS_PATTERN_NONE,
   1197  1.7  riastrad 					 SVGA3D_MS_QUALITY_NONE,
   1198  1.7  riastrad 					 srf_out);
   1199  1.4  riastrad 	if (ret) {
   1200  1.4  riastrad 		DRM_ERROR("Failed to allocate proxy content buffer\n");
   1201  1.4  riastrad 		return ret;
   1202  1.1  riastrad 	}
   1203  1.1  riastrad 
   1204  1.4  riastrad 	res = &(*srf_out)->res;
   1205  1.4  riastrad 
   1206  1.4  riastrad 	/* Reserve and switch the backing mob. */
   1207  1.4  riastrad 	mutex_lock(&res->dev_priv->cmdbuf_mutex);
   1208  1.4  riastrad 	(void) vmw_resource_reserve(res, false, true);
   1209  1.7  riastrad 	vmw_bo_unreference(&res->backup);
   1210  1.7  riastrad 	res->backup = vmw_bo_reference(bo_mob);
   1211  1.4  riastrad 	res->backup_offset = 0;
   1212  1.7  riastrad 	vmw_resource_unreserve(res, false, false, false, NULL, 0);
   1213  1.4  riastrad 	mutex_unlock(&res->dev_priv->cmdbuf_mutex);
   1214  1.4  riastrad 
   1215  1.4  riastrad 	return 0;
   1216  1.1  riastrad }
   1217  1.1  riastrad 
   1218  1.4  riastrad 
   1219  1.4  riastrad 
   1220  1.7  riastrad static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv,
   1221  1.7  riastrad 				      struct vmw_buffer_object *bo,
   1222  1.7  riastrad 				      struct vmw_framebuffer **out,
   1223  1.7  riastrad 				      const struct drm_mode_fb_cmd2
   1224  1.7  riastrad 				      *mode_cmd)
   1225  1.1  riastrad 
   1226  1.1  riastrad {
   1227  1.1  riastrad 	struct drm_device *dev = dev_priv->dev;
   1228  1.7  riastrad 	struct vmw_framebuffer_bo *vfbd;
   1229  1.1  riastrad 	unsigned int requested_size;
   1230  1.7  riastrad 	struct drm_format_name_buf format_name;
   1231  1.1  riastrad 	int ret;
   1232  1.1  riastrad 
   1233  1.7  riastrad 	requested_size = mode_cmd->height * mode_cmd->pitches[0];
   1234  1.7  riastrad 	if (unlikely(requested_size > bo->base.num_pages * PAGE_SIZE)) {
   1235  1.1  riastrad 		DRM_ERROR("Screen buffer object size is too small "
   1236  1.1  riastrad 			  "for requested mode.\n");
   1237  1.1  riastrad 		return -EINVAL;
   1238  1.1  riastrad 	}
   1239  1.1  riastrad 
   1240  1.1  riastrad 	/* Limited framebuffer color depth support for screen objects */
   1241  1.4  riastrad 	if (dev_priv->active_display_unit == vmw_du_screen_object) {
   1242  1.7  riastrad 		switch (mode_cmd->pixel_format) {
   1243  1.7  riastrad 		case DRM_FORMAT_XRGB8888:
   1244  1.7  riastrad 		case DRM_FORMAT_ARGB8888:
   1245  1.7  riastrad 			break;
   1246  1.7  riastrad 		case DRM_FORMAT_XRGB1555:
   1247  1.7  riastrad 		case DRM_FORMAT_RGB565:
   1248  1.7  riastrad 			break;
   1249  1.1  riastrad 		default:
   1250  1.7  riastrad 			DRM_ERROR("Invalid pixel format: %s\n",
   1251  1.7  riastrad 				  drm_get_format_name(mode_cmd->pixel_format, &format_name));
   1252  1.1  riastrad 			return -EINVAL;
   1253  1.1  riastrad 		}
   1254  1.1  riastrad 	}
   1255  1.1  riastrad 
   1256  1.1  riastrad 	vfbd = kzalloc(sizeof(*vfbd), GFP_KERNEL);
   1257  1.1  riastrad 	if (!vfbd) {
   1258  1.1  riastrad 		ret = -ENOMEM;
   1259  1.1  riastrad 		goto out_err1;
   1260  1.1  riastrad 	}
   1261  1.1  riastrad 
   1262  1.7  riastrad 	drm_helper_mode_fill_fb_struct(dev, &vfbd->base.base, mode_cmd);
   1263  1.7  riastrad 	vfbd->base.bo = true;
   1264  1.7  riastrad 	vfbd->buffer = vmw_bo_reference(bo);
   1265  1.7  riastrad 	vfbd->base.user_handle = mode_cmd->handles[0];
   1266  1.1  riastrad 	*out = &vfbd->base;
   1267  1.1  riastrad 
   1268  1.3  riastrad 	ret = drm_framebuffer_init(dev, &vfbd->base.base,
   1269  1.7  riastrad 				   &vmw_framebuffer_bo_funcs);
   1270  1.3  riastrad 	if (ret)
   1271  1.4  riastrad 		goto out_err2;
   1272  1.3  riastrad 
   1273  1.1  riastrad 	return 0;
   1274  1.1  riastrad 
   1275  1.4  riastrad out_err2:
   1276  1.7  riastrad 	vmw_bo_unreference(&bo);
   1277  1.1  riastrad 	kfree(vfbd);
   1278  1.1  riastrad out_err1:
   1279  1.1  riastrad 	return ret;
   1280  1.1  riastrad }
   1281  1.1  riastrad 
   1282  1.7  riastrad 
   1283  1.7  riastrad /**
   1284  1.7  riastrad  * vmw_kms_srf_ok - check if a surface can be created
   1285  1.7  riastrad  *
   1286  1.7  riastrad  * @width: requested width
   1287  1.7  riastrad  * @height: requested height
   1288  1.7  riastrad  *
   1289  1.7  riastrad  * Surfaces need to be less than texture size
   1290  1.7  riastrad  */
   1291  1.7  riastrad static bool
   1292  1.7  riastrad vmw_kms_srf_ok(struct vmw_private *dev_priv, uint32_t width, uint32_t height)
   1293  1.7  riastrad {
   1294  1.7  riastrad 	if (width  > dev_priv->texture_max_width ||
   1295  1.7  riastrad 	    height > dev_priv->texture_max_height)
   1296  1.7  riastrad 		return false;
   1297  1.7  riastrad 
   1298  1.7  riastrad 	return true;
   1299  1.7  riastrad }
   1300  1.7  riastrad 
   1301  1.4  riastrad /**
   1302  1.4  riastrad  * vmw_kms_new_framebuffer - Create a new framebuffer.
   1303  1.4  riastrad  *
   1304  1.4  riastrad  * @dev_priv: Pointer to device private struct.
   1305  1.7  riastrad  * @bo: Pointer to buffer object to wrap the kms framebuffer around.
   1306  1.7  riastrad  * Either @bo or @surface must be NULL.
   1307  1.4  riastrad  * @surface: Pointer to a surface to wrap the kms framebuffer around.
   1308  1.7  riastrad  * Either @bo or @surface must be NULL.
   1309  1.7  riastrad  * @only_2d: No presents will occur to this buffer object based framebuffer.
   1310  1.7  riastrad  * This helps the code to do some important optimizations.
   1311  1.4  riastrad  * @mode_cmd: Frame-buffer metadata.
   1312  1.4  riastrad  */
   1313  1.4  riastrad struct vmw_framebuffer *
   1314  1.4  riastrad vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
   1315  1.7  riastrad 			struct vmw_buffer_object *bo,
   1316  1.4  riastrad 			struct vmw_surface *surface,
   1317  1.4  riastrad 			bool only_2d,
   1318  1.7  riastrad 			const struct drm_mode_fb_cmd2 *mode_cmd)
   1319  1.4  riastrad {
   1320  1.4  riastrad 	struct vmw_framebuffer *vfb = NULL;
   1321  1.7  riastrad 	bool is_bo_proxy = false;
   1322  1.4  riastrad 	int ret;
   1323  1.4  riastrad 
   1324  1.4  riastrad 	/*
   1325  1.4  riastrad 	 * We cannot use the SurfaceDMA command in an non-accelerated VM,
   1326  1.7  riastrad 	 * therefore, wrap the buffer object in a surface so we can use the
   1327  1.4  riastrad 	 * SurfaceCopy command.
   1328  1.4  riastrad 	 */
   1329  1.7  riastrad 	if (vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)  &&
   1330  1.7  riastrad 	    bo && only_2d &&
   1331  1.7  riastrad 	    mode_cmd->width > 64 &&  /* Don't create a proxy for cursor */
   1332  1.4  riastrad 	    dev_priv->active_display_unit == vmw_du_screen_target) {
   1333  1.7  riastrad 		ret = vmw_create_bo_proxy(dev_priv->dev, mode_cmd,
   1334  1.7  riastrad 					  bo, &surface);
   1335  1.4  riastrad 		if (ret)
   1336  1.4  riastrad 			return ERR_PTR(ret);
   1337  1.4  riastrad 
   1338  1.7  riastrad 		is_bo_proxy = true;
   1339  1.4  riastrad 	}
   1340  1.4  riastrad 
   1341  1.4  riastrad 	/* Create the new framebuffer depending one what we have */
   1342  1.4  riastrad 	if (surface) {
   1343  1.4  riastrad 		ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
   1344  1.4  riastrad 						      mode_cmd,
   1345  1.7  riastrad 						      is_bo_proxy);
   1346  1.4  riastrad 
   1347  1.4  riastrad 		/*
   1348  1.7  riastrad 		 * vmw_create_bo_proxy() adds a reference that is no longer
   1349  1.4  riastrad 		 * needed
   1350  1.4  riastrad 		 */
   1351  1.7  riastrad 		if (is_bo_proxy)
   1352  1.4  riastrad 			vmw_surface_unreference(&surface);
   1353  1.7  riastrad 	} else if (bo) {
   1354  1.7  riastrad 		ret = vmw_kms_new_framebuffer_bo(dev_priv, bo, &vfb,
   1355  1.7  riastrad 						 mode_cmd);
   1356  1.4  riastrad 	} else {
   1357  1.4  riastrad 		BUG();
   1358  1.4  riastrad 	}
   1359  1.4  riastrad 
   1360  1.4  riastrad 	if (ret)
   1361  1.4  riastrad 		return ERR_PTR(ret);
   1362  1.4  riastrad 
   1363  1.4  riastrad 	vfb->pin = vmw_framebuffer_pin;
   1364  1.4  riastrad 	vfb->unpin = vmw_framebuffer_unpin;
   1365  1.4  riastrad 
   1366  1.4  riastrad 	return vfb;
   1367  1.4  riastrad }
   1368  1.4  riastrad 
   1369  1.4  riastrad /*
   1370  1.4  riastrad  * Generic Kernel modesetting functions
   1371  1.1  riastrad  */
   1372  1.1  riastrad 
   1373  1.1  riastrad static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
   1374  1.1  riastrad 						 struct drm_file *file_priv,
   1375  1.7  riastrad 						 const struct drm_mode_fb_cmd2 *mode_cmd)
   1376  1.1  riastrad {
   1377  1.1  riastrad 	struct vmw_private *dev_priv = vmw_priv(dev);
   1378  1.1  riastrad 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
   1379  1.1  riastrad 	struct vmw_framebuffer *vfb = NULL;
   1380  1.1  riastrad 	struct vmw_surface *surface = NULL;
   1381  1.7  riastrad 	struct vmw_buffer_object *bo = NULL;
   1382  1.1  riastrad 	struct ttm_base_object *user_obj;
   1383  1.1  riastrad 	int ret;
   1384  1.1  riastrad 
   1385  1.1  riastrad 	/*
   1386  1.1  riastrad 	 * Take a reference on the user object of the resource
   1387  1.1  riastrad 	 * backing the kms fb. This ensures that user-space handle
   1388  1.1  riastrad 	 * lookups on that resource will always work as long as
   1389  1.1  riastrad 	 * it's registered with a kms framebuffer. This is important,
   1390  1.1  riastrad 	 * since vmw_execbuf_process identifies resources in the
   1391  1.1  riastrad 	 * command stream using user-space handles.
   1392  1.1  riastrad 	 */
   1393  1.1  riastrad 
   1394  1.7  riastrad 	user_obj = ttm_base_object_lookup(tfile, mode_cmd->handles[0]);
   1395  1.1  riastrad 	if (unlikely(user_obj == NULL)) {
   1396  1.1  riastrad 		DRM_ERROR("Could not locate requested kms frame buffer.\n");
   1397  1.1  riastrad 		return ERR_PTR(-ENOENT);
   1398  1.1  riastrad 	}
   1399  1.1  riastrad 
   1400  1.1  riastrad 	/**
   1401  1.1  riastrad 	 * End conditioned code.
   1402  1.1  riastrad 	 */
   1403  1.1  riastrad 
   1404  1.7  riastrad 	/* returns either a bo or surface */
   1405  1.1  riastrad 	ret = vmw_user_lookup_handle(dev_priv, tfile,
   1406  1.7  riastrad 				     mode_cmd->handles[0],
   1407  1.1  riastrad 				     &surface, &bo);
   1408  1.1  riastrad 	if (ret)
   1409  1.1  riastrad 		goto err_out;
   1410  1.1  riastrad 
   1411  1.7  riastrad 
   1412  1.7  riastrad 	if (!bo &&
   1413  1.7  riastrad 	    !vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) {
   1414  1.7  riastrad 		DRM_ERROR("Surface size cannot exceed %dx%d",
   1415  1.7  riastrad 			dev_priv->texture_max_width,
   1416  1.7  riastrad 			dev_priv->texture_max_height);
   1417  1.7  riastrad 		goto err_out;
   1418  1.7  riastrad 	}
   1419  1.7  riastrad 
   1420  1.7  riastrad 
   1421  1.4  riastrad 	vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
   1422  1.4  riastrad 				      !(dev_priv->capabilities & SVGA_CAP_3D),
   1423  1.7  riastrad 				      mode_cmd);
   1424  1.4  riastrad 	if (IS_ERR(vfb)) {
   1425  1.4  riastrad 		ret = PTR_ERR(vfb);
   1426  1.4  riastrad 		goto err_out;
   1427  1.4  riastrad  	}
   1428  1.1  riastrad 
   1429  1.1  riastrad err_out:
   1430  1.1  riastrad 	/* vmw_user_lookup_handle takes one ref so does new_fb */
   1431  1.1  riastrad 	if (bo)
   1432  1.7  riastrad 		vmw_bo_unreference(&bo);
   1433  1.1  riastrad 	if (surface)
   1434  1.7  riastrad 		vmw_surface_unreference(&surface);
   1435  1.7  riastrad 
   1436  1.7  riastrad 	if (ret) {
   1437  1.7  riastrad 		DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
   1438  1.7  riastrad 		ttm_base_object_unref(&user_obj);
   1439  1.7  riastrad 		return ERR_PTR(ret);
   1440  1.7  riastrad 	} else
   1441  1.7  riastrad 		vfb->user_obj = user_obj;
   1442  1.7  riastrad 
   1443  1.7  riastrad 	return &vfb->base;
   1444  1.7  riastrad }
   1445  1.7  riastrad 
   1446  1.7  riastrad /**
   1447  1.7  riastrad  * vmw_kms_check_display_memory - Validates display memory required for a
   1448  1.7  riastrad  * topology
   1449  1.7  riastrad  * @dev: DRM device
   1450  1.7  riastrad  * @num_rects: number of drm_rect in rects
   1451  1.7  riastrad  * @rects: array of drm_rect representing the topology to validate indexed by
   1452  1.7  riastrad  * crtc index.
   1453  1.7  riastrad  *
   1454  1.7  riastrad  * Returns:
   1455  1.7  riastrad  * 0 on success otherwise negative error code
   1456  1.7  riastrad  */
   1457  1.7  riastrad static int vmw_kms_check_display_memory(struct drm_device *dev,
   1458  1.7  riastrad 					uint32_t num_rects,
   1459  1.7  riastrad 					struct drm_rect *rects)
   1460  1.7  riastrad {
   1461  1.7  riastrad 	struct vmw_private *dev_priv = vmw_priv(dev);
   1462  1.7  riastrad 	struct drm_rect bounding_box = {0};
   1463  1.7  riastrad 	u64 total_pixels = 0, pixel_mem, bb_mem;
   1464  1.7  riastrad 	int i;
   1465  1.7  riastrad 
   1466  1.7  riastrad 	for (i = 0; i < num_rects; i++) {
   1467  1.7  riastrad 		/*
   1468  1.7  riastrad 		 * For STDU only individual screen (screen target) is limited by
   1469  1.7  riastrad 		 * SCREENTARGET_MAX_WIDTH/HEIGHT registers.
   1470  1.7  riastrad 		 */
   1471  1.7  riastrad 		if (dev_priv->active_display_unit == vmw_du_screen_target &&
   1472  1.7  riastrad 		    (drm_rect_width(&rects[i]) > dev_priv->stdu_max_width ||
   1473  1.7  riastrad 		     drm_rect_height(&rects[i]) > dev_priv->stdu_max_height)) {
   1474  1.7  riastrad 			VMW_DEBUG_KMS("Screen size not supported.\n");
   1475  1.7  riastrad 			return -EINVAL;
   1476  1.7  riastrad 		}
   1477  1.7  riastrad 
   1478  1.7  riastrad 		/* Bounding box upper left is at (0,0). */
   1479  1.7  riastrad 		if (rects[i].x2 > bounding_box.x2)
   1480  1.7  riastrad 			bounding_box.x2 = rects[i].x2;
   1481  1.7  riastrad 
   1482  1.7  riastrad 		if (rects[i].y2 > bounding_box.y2)
   1483  1.7  riastrad 			bounding_box.y2 = rects[i].y2;
   1484  1.7  riastrad 
   1485  1.7  riastrad 		total_pixels += (u64) drm_rect_width(&rects[i]) *
   1486  1.7  riastrad 			(u64) drm_rect_height(&rects[i]);
   1487  1.7  riastrad 	}
   1488  1.7  riastrad 
   1489  1.7  riastrad 	/* Virtual svga device primary limits are always in 32-bpp. */
   1490  1.7  riastrad 	pixel_mem = total_pixels * 4;
   1491  1.7  riastrad 
   1492  1.7  riastrad 	/*
   1493  1.7  riastrad 	 * For HV10 and below prim_bb_mem is vram size. When
   1494  1.7  riastrad 	 * SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM is not present vram size is
   1495  1.7  riastrad 	 * limit on primary bounding box
   1496  1.7  riastrad 	 */
   1497  1.7  riastrad 	if (pixel_mem > dev_priv->prim_bb_mem) {
   1498  1.7  riastrad 		VMW_DEBUG_KMS("Combined output size too large.\n");
   1499  1.7  riastrad 		return -EINVAL;
   1500  1.7  riastrad 	}
   1501  1.7  riastrad 
   1502  1.7  riastrad 	/* SVGA_CAP_NO_BB_RESTRICTION is available for STDU only. */
   1503  1.7  riastrad 	if (dev_priv->active_display_unit != vmw_du_screen_target ||
   1504  1.7  riastrad 	    !(dev_priv->capabilities & SVGA_CAP_NO_BB_RESTRICTION)) {
   1505  1.7  riastrad 		bb_mem = (u64) bounding_box.x2 * bounding_box.y2 * 4;
   1506  1.7  riastrad 
   1507  1.7  riastrad 		if (bb_mem > dev_priv->prim_bb_mem) {
   1508  1.7  riastrad 			VMW_DEBUG_KMS("Topology is beyond supported limits.\n");
   1509  1.7  riastrad 			return -EINVAL;
   1510  1.7  riastrad 		}
   1511  1.7  riastrad 	}
   1512  1.7  riastrad 
   1513  1.7  riastrad 	return 0;
   1514  1.7  riastrad }
   1515  1.7  riastrad 
   1516  1.7  riastrad /**
   1517  1.7  riastrad  * vmw_crtc_state_and_lock - Return new or current crtc state with locked
   1518  1.7  riastrad  * crtc mutex
   1519  1.7  riastrad  * @state: The atomic state pointer containing the new atomic state
   1520  1.7  riastrad  * @crtc: The crtc
   1521  1.7  riastrad  *
   1522  1.7  riastrad  * This function returns the new crtc state if it's part of the state update.
   1523  1.7  riastrad  * Otherwise returns the current crtc state. It also makes sure that the
   1524  1.7  riastrad  * crtc mutex is locked.
   1525  1.7  riastrad  *
   1526  1.7  riastrad  * Returns: A valid crtc state pointer or NULL. It may also return a
   1527  1.7  riastrad  * pointer error, in particular -EDEADLK if locking needs to be rerun.
   1528  1.7  riastrad  */
   1529  1.7  riastrad static struct drm_crtc_state *
   1530  1.7  riastrad vmw_crtc_state_and_lock(struct drm_atomic_state *state, struct drm_crtc *crtc)
   1531  1.7  riastrad {
   1532  1.7  riastrad 	struct drm_crtc_state *crtc_state;
   1533  1.7  riastrad 
   1534  1.7  riastrad 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
   1535  1.7  riastrad 	if (crtc_state) {
   1536  1.7  riastrad 		lockdep_assert_held(&crtc->mutex.mutex.base);
   1537  1.7  riastrad 	} else {
   1538  1.7  riastrad 		int ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
   1539  1.7  riastrad 
   1540  1.7  riastrad 		if (ret != 0 && ret != -EALREADY)
   1541  1.7  riastrad 			return ERR_PTR(ret);
   1542  1.7  riastrad 
   1543  1.7  riastrad 		crtc_state = crtc->state;
   1544  1.7  riastrad 	}
   1545  1.7  riastrad 
   1546  1.7  riastrad 	return crtc_state;
   1547  1.7  riastrad }
   1548  1.7  riastrad 
   1549  1.7  riastrad /**
   1550  1.7  riastrad  * vmw_kms_check_implicit - Verify that all implicit display units scan out
   1551  1.7  riastrad  * from the same fb after the new state is committed.
   1552  1.7  riastrad  * @dev: The drm_device.
   1553  1.7  riastrad  * @state: The new state to be checked.
   1554  1.7  riastrad  *
   1555  1.7  riastrad  * Returns:
   1556  1.7  riastrad  *   Zero on success,
   1557  1.7  riastrad  *   -EINVAL on invalid state,
   1558  1.7  riastrad  *   -EDEADLK if modeset locking needs to be rerun.
   1559  1.7  riastrad  */
   1560  1.7  riastrad static int vmw_kms_check_implicit(struct drm_device *dev,
   1561  1.7  riastrad 				  struct drm_atomic_state *state)
   1562  1.7  riastrad {
   1563  1.7  riastrad 	struct drm_framebuffer *implicit_fb = NULL;
   1564  1.7  riastrad 	struct drm_crtc *crtc;
   1565  1.7  riastrad 	struct drm_crtc_state *crtc_state;
   1566  1.7  riastrad 	struct drm_plane_state *plane_state;
   1567  1.7  riastrad 
   1568  1.7  riastrad 	drm_for_each_crtc(crtc, dev) {
   1569  1.7  riastrad 		struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
   1570  1.7  riastrad 
   1571  1.7  riastrad 		if (!du->is_implicit)
   1572  1.7  riastrad 			continue;
   1573  1.7  riastrad 
   1574  1.7  riastrad 		crtc_state = vmw_crtc_state_and_lock(state, crtc);
   1575  1.7  riastrad 		if (IS_ERR(crtc_state))
   1576  1.7  riastrad 			return PTR_ERR(crtc_state);
   1577  1.7  riastrad 
   1578  1.7  riastrad 		if (!crtc_state || !crtc_state->enable)
   1579  1.7  riastrad 			continue;
   1580  1.7  riastrad 
   1581  1.7  riastrad 		/*
   1582  1.7  riastrad 		 * Can't move primary planes across crtcs, so this is OK.
   1583  1.7  riastrad 		 * It also means we don't need to take the plane mutex.
   1584  1.7  riastrad 		 */
   1585  1.7  riastrad 		plane_state = du->primary.state;
   1586  1.7  riastrad 		if (plane_state->crtc != crtc)
   1587  1.7  riastrad 			continue;
   1588  1.7  riastrad 
   1589  1.7  riastrad 		if (!implicit_fb)
   1590  1.7  riastrad 			implicit_fb = plane_state->fb;
   1591  1.7  riastrad 		else if (implicit_fb != plane_state->fb)
   1592  1.7  riastrad 			return -EINVAL;
   1593  1.7  riastrad 	}
   1594  1.7  riastrad 
   1595  1.7  riastrad 	return 0;
   1596  1.7  riastrad }
   1597  1.7  riastrad 
   1598  1.7  riastrad /**
   1599  1.7  riastrad  * vmw_kms_check_topology - Validates topology in drm_atomic_state
   1600  1.7  riastrad  * @dev: DRM device
   1601  1.7  riastrad  * @state: the driver state object
   1602  1.7  riastrad  *
   1603  1.7  riastrad  * Returns:
   1604  1.7  riastrad  * 0 on success otherwise negative error code
   1605  1.7  riastrad  */
   1606  1.7  riastrad static int vmw_kms_check_topology(struct drm_device *dev,
   1607  1.7  riastrad 				  struct drm_atomic_state *state)
   1608  1.7  riastrad {
   1609  1.7  riastrad 	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
   1610  1.7  riastrad 	struct drm_rect *rects;
   1611  1.7  riastrad 	struct drm_crtc *crtc;
   1612  1.7  riastrad 	uint32_t i;
   1613  1.7  riastrad 	int ret = 0;
   1614  1.7  riastrad 
   1615  1.7  riastrad 	rects = kcalloc(dev->mode_config.num_crtc, sizeof(struct drm_rect),
   1616  1.7  riastrad 			GFP_KERNEL);
   1617  1.7  riastrad 	if (!rects)
   1618  1.7  riastrad 		return -ENOMEM;
   1619  1.7  riastrad 
   1620  1.7  riastrad 	drm_for_each_crtc(crtc, dev) {
   1621  1.7  riastrad 		struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
   1622  1.7  riastrad 		struct drm_crtc_state *crtc_state;
   1623  1.7  riastrad 
   1624  1.7  riastrad 		i = drm_crtc_index(crtc);
   1625  1.7  riastrad 
   1626  1.7  riastrad 		crtc_state = vmw_crtc_state_and_lock(state, crtc);
   1627  1.7  riastrad 		if (IS_ERR(crtc_state)) {
   1628  1.7  riastrad 			ret = PTR_ERR(crtc_state);
   1629  1.7  riastrad 			goto clean;
   1630  1.7  riastrad 		}
   1631  1.7  riastrad 
   1632  1.7  riastrad 		if (!crtc_state)
   1633  1.7  riastrad 			continue;
   1634  1.7  riastrad 
   1635  1.7  riastrad 		if (crtc_state->enable) {
   1636  1.7  riastrad 			rects[i].x1 = du->gui_x;
   1637  1.7  riastrad 			rects[i].y1 = du->gui_y;
   1638  1.7  riastrad 			rects[i].x2 = du->gui_x + crtc_state->mode.hdisplay;
   1639  1.7  riastrad 			rects[i].y2 = du->gui_y + crtc_state->mode.vdisplay;
   1640  1.7  riastrad 		} else {
   1641  1.7  riastrad 			rects[i].x1 = 0;
   1642  1.7  riastrad 			rects[i].y1 = 0;
   1643  1.7  riastrad 			rects[i].x2 = 0;
   1644  1.7  riastrad 			rects[i].y2 = 0;
   1645  1.7  riastrad 		}
   1646  1.7  riastrad 	}
   1647  1.7  riastrad 
   1648  1.7  riastrad 	/* Determine change to topology due to new atomic state */
   1649  1.7  riastrad 	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
   1650  1.7  riastrad 				      new_crtc_state, i) {
   1651  1.7  riastrad 		struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
   1652  1.7  riastrad 		struct drm_connector *connector;
   1653  1.7  riastrad 		struct drm_connector_state *conn_state;
   1654  1.7  riastrad 		struct vmw_connector_state *vmw_conn_state;
   1655  1.7  riastrad 
   1656  1.7  riastrad 		if (!du->pref_active && new_crtc_state->enable) {
   1657  1.7  riastrad 			VMW_DEBUG_KMS("Enabling a disabled display unit\n");
   1658  1.7  riastrad 			ret = -EINVAL;
   1659  1.7  riastrad 			goto clean;
   1660  1.7  riastrad 		}
   1661  1.7  riastrad 
   1662  1.7  riastrad 		/*
   1663  1.7  riastrad 		 * For vmwgfx each crtc has only one connector attached and it
   1664  1.7  riastrad 		 * is not changed so don't really need to check the
   1665  1.7  riastrad 		 * crtc->connector_mask and iterate over it.
   1666  1.7  riastrad 		 */
   1667  1.7  riastrad 		connector = &du->connector;
   1668  1.7  riastrad 		conn_state = drm_atomic_get_connector_state(state, connector);
   1669  1.7  riastrad 		if (IS_ERR(conn_state)) {
   1670  1.7  riastrad 			ret = PTR_ERR(conn_state);
   1671  1.7  riastrad 			goto clean;
   1672  1.7  riastrad 		}
   1673  1.7  riastrad 
   1674  1.7  riastrad 		vmw_conn_state = vmw_connector_state_to_vcs(conn_state);
   1675  1.7  riastrad 		vmw_conn_state->gui_x = du->gui_x;
   1676  1.7  riastrad 		vmw_conn_state->gui_y = du->gui_y;
   1677  1.7  riastrad 	}
   1678  1.7  riastrad 
   1679  1.7  riastrad 	ret = vmw_kms_check_display_memory(dev, dev->mode_config.num_crtc,
   1680  1.7  riastrad 					   rects);
   1681  1.7  riastrad 
   1682  1.7  riastrad clean:
   1683  1.7  riastrad 	kfree(rects);
   1684  1.7  riastrad 	return ret;
   1685  1.7  riastrad }
   1686  1.7  riastrad 
   1687  1.7  riastrad /**
   1688  1.7  riastrad  * vmw_kms_atomic_check_modeset- validate state object for modeset changes
   1689  1.7  riastrad  *
   1690  1.7  riastrad  * @dev: DRM device
   1691  1.7  riastrad  * @state: the driver state object
   1692  1.7  riastrad  *
   1693  1.7  riastrad  * This is a simple wrapper around drm_atomic_helper_check_modeset() for
   1694  1.7  riastrad  * us to assign a value to mode->crtc_clock so that
   1695  1.7  riastrad  * drm_calc_timestamping_constants() won't throw an error message
   1696  1.7  riastrad  *
   1697  1.7  riastrad  * Returns:
   1698  1.7  riastrad  * Zero for success or -errno
   1699  1.7  riastrad  */
   1700  1.7  riastrad static int
   1701  1.7  riastrad vmw_kms_atomic_check_modeset(struct drm_device *dev,
   1702  1.7  riastrad 			     struct drm_atomic_state *state)
   1703  1.7  riastrad {
   1704  1.7  riastrad 	struct drm_crtc *crtc;
   1705  1.7  riastrad 	struct drm_crtc_state *crtc_state;
   1706  1.7  riastrad 	bool need_modeset = false;
   1707  1.7  riastrad 	int i, ret;
   1708  1.7  riastrad 
   1709  1.7  riastrad 	ret = drm_atomic_helper_check(dev, state);
   1710  1.7  riastrad 	if (ret)
   1711  1.7  riastrad 		return ret;
   1712  1.1  riastrad 
   1713  1.7  riastrad 	ret = vmw_kms_check_implicit(dev, state);
   1714  1.1  riastrad 	if (ret) {
   1715  1.7  riastrad 		VMW_DEBUG_KMS("Invalid implicit state\n");
   1716  1.7  riastrad 		return ret;
   1717  1.7  riastrad 	}
   1718  1.7  riastrad 
   1719  1.7  riastrad 	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
   1720  1.7  riastrad 		if (drm_atomic_crtc_needs_modeset(crtc_state))
   1721  1.7  riastrad 			need_modeset = true;
   1722  1.7  riastrad 	}
   1723  1.7  riastrad 
   1724  1.7  riastrad 	if (need_modeset)
   1725  1.7  riastrad 		return vmw_kms_check_topology(dev, state);
   1726  1.1  riastrad 
   1727  1.7  riastrad 	return ret;
   1728  1.1  riastrad }
   1729  1.1  riastrad 
   1730  1.1  riastrad static const struct drm_mode_config_funcs vmw_kms_funcs = {
   1731  1.1  riastrad 	.fb_create = vmw_kms_fb_create,
   1732  1.7  riastrad 	.atomic_check = vmw_kms_atomic_check_modeset,
   1733  1.7  riastrad 	.atomic_commit = drm_atomic_helper_commit,
   1734  1.1  riastrad };
   1735  1.1  riastrad 
   1736  1.4  riastrad static int vmw_kms_generic_present(struct vmw_private *dev_priv,
   1737  1.4  riastrad 				   struct drm_file *file_priv,
   1738  1.4  riastrad 				   struct vmw_framebuffer *vfb,
   1739  1.4  riastrad 				   struct vmw_surface *surface,
   1740  1.4  riastrad 				   uint32_t sid,
   1741  1.4  riastrad 				   int32_t destX, int32_t destY,
   1742  1.4  riastrad 				   struct drm_vmw_rect *clips,
   1743  1.4  riastrad 				   uint32_t num_clips)
   1744  1.4  riastrad {
   1745  1.4  riastrad 	return vmw_kms_sou_do_surface_dirty(dev_priv, vfb, NULL, clips,
   1746  1.4  riastrad 					    &surface->res, destX, destY,
   1747  1.7  riastrad 					    num_clips, 1, NULL, NULL);
   1748  1.4  riastrad }
   1749  1.4  riastrad 
   1750  1.4  riastrad 
   1751  1.1  riastrad int vmw_kms_present(struct vmw_private *dev_priv,
   1752  1.1  riastrad 		    struct drm_file *file_priv,
   1753  1.1  riastrad 		    struct vmw_framebuffer *vfb,
   1754  1.1  riastrad 		    struct vmw_surface *surface,
   1755  1.1  riastrad 		    uint32_t sid,
   1756  1.1  riastrad 		    int32_t destX, int32_t destY,
   1757  1.1  riastrad 		    struct drm_vmw_rect *clips,
   1758  1.1  riastrad 		    uint32_t num_clips)
   1759  1.1  riastrad {
   1760  1.4  riastrad 	int ret;
   1761  1.1  riastrad 
   1762  1.4  riastrad 	switch (dev_priv->active_display_unit) {
   1763  1.4  riastrad 	case vmw_du_screen_target:
   1764  1.4  riastrad 		ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, clips,
   1765  1.4  riastrad 						 &surface->res, destX, destY,
   1766  1.7  riastrad 						 num_clips, 1, NULL, NULL);
   1767  1.4  riastrad 		break;
   1768  1.4  riastrad 	case vmw_du_screen_object:
   1769  1.4  riastrad 		ret = vmw_kms_generic_present(dev_priv, file_priv, vfb, surface,
   1770  1.4  riastrad 					      sid, destX, destY, clips,
   1771  1.4  riastrad 					      num_clips);
   1772  1.4  riastrad 		break;
   1773  1.4  riastrad 	default:
   1774  1.4  riastrad 		WARN_ONCE(true,
   1775  1.4  riastrad 			  "Present called with invalid display system.\n");
   1776  1.4  riastrad 		ret = -ENOSYS;
   1777  1.4  riastrad 		break;
   1778  1.1  riastrad 	}
   1779  1.4  riastrad 	if (ret)
   1780  1.4  riastrad 		return ret;
   1781  1.1  riastrad 
   1782  1.4  riastrad 	vmw_fifo_flush(dev_priv, false);
   1783  1.1  riastrad 
   1784  1.4  riastrad 	return 0;
   1785  1.1  riastrad }
   1786  1.1  riastrad 
   1787  1.7  riastrad static void
   1788  1.7  riastrad vmw_kms_create_hotplug_mode_update_property(struct vmw_private *dev_priv)
   1789  1.7  riastrad {
   1790  1.7  riastrad 	if (dev_priv->hotplug_mode_update_property)
   1791  1.7  riastrad 		return;
   1792  1.7  riastrad 
   1793  1.7  riastrad 	dev_priv->hotplug_mode_update_property =
   1794  1.7  riastrad 		drm_property_create_range(dev_priv->dev,
   1795  1.7  riastrad 					  DRM_MODE_PROP_IMMUTABLE,
   1796  1.7  riastrad 					  "hotplug_mode_update", 0, 1);
   1797  1.7  riastrad 
   1798  1.7  riastrad 	if (!dev_priv->hotplug_mode_update_property)
   1799  1.7  riastrad 		return;
   1800  1.7  riastrad 
   1801  1.7  riastrad }
   1802  1.7  riastrad 
   1803  1.1  riastrad int vmw_kms_init(struct vmw_private *dev_priv)
   1804  1.1  riastrad {
   1805  1.1  riastrad 	struct drm_device *dev = dev_priv->dev;
   1806  1.1  riastrad 	int ret;
   1807  1.1  riastrad 
   1808  1.1  riastrad 	drm_mode_config_init(dev);
   1809  1.1  riastrad 	dev->mode_config.funcs = &vmw_kms_funcs;
   1810  1.1  riastrad 	dev->mode_config.min_width = 1;
   1811  1.1  riastrad 	dev->mode_config.min_height = 1;
   1812  1.4  riastrad 	dev->mode_config.max_width = dev_priv->texture_max_width;
   1813  1.4  riastrad 	dev->mode_config.max_height = dev_priv->texture_max_height;
   1814  1.1  riastrad 
   1815  1.7  riastrad 	drm_mode_create_suggested_offset_properties(dev);
   1816  1.7  riastrad 	vmw_kms_create_hotplug_mode_update_property(dev_priv);
   1817  1.7  riastrad 
   1818  1.4  riastrad 	ret = vmw_kms_stdu_init_display(dev_priv);
   1819  1.4  riastrad 	if (ret) {
   1820  1.4  riastrad 		ret = vmw_kms_sou_init_display(dev_priv);
   1821  1.4  riastrad 		if (ret) /* Fallback */
   1822  1.4  riastrad 			ret = vmw_kms_ldu_init_display(dev_priv);
   1823  1.4  riastrad 	}
   1824  1.4  riastrad 
   1825  1.4  riastrad 	return ret;
   1826  1.1  riastrad }
   1827  1.1  riastrad 
   1828  1.1  riastrad int vmw_kms_close(struct vmw_private *dev_priv)
   1829  1.1  riastrad {
   1830  1.7  riastrad 	int ret = 0;
   1831  1.4  riastrad 
   1832  1.1  riastrad 	/*
   1833  1.1  riastrad 	 * Docs says we should take the lock before calling this function
   1834  1.1  riastrad 	 * but since it destroys encoders and our destructor calls
   1835  1.1  riastrad 	 * drm_encoder_cleanup which takes the lock we deadlock.
   1836  1.1  riastrad 	 */
   1837  1.1  riastrad 	drm_mode_config_cleanup(dev_priv->dev);
   1838  1.7  riastrad 	if (dev_priv->active_display_unit == vmw_du_legacy)
   1839  1.4  riastrad 		ret = vmw_kms_ldu_close_display(dev_priv);
   1840  1.4  riastrad 
   1841  1.4  riastrad 	return ret;
   1842  1.1  riastrad }
   1843  1.1  riastrad 
   1844  1.1  riastrad int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
   1845  1.1  riastrad 				struct drm_file *file_priv)
   1846  1.1  riastrad {
   1847  1.1  riastrad 	struct drm_vmw_cursor_bypass_arg *arg = data;
   1848  1.1  riastrad 	struct vmw_display_unit *du;
   1849  1.1  riastrad 	struct drm_crtc *crtc;
   1850  1.1  riastrad 	int ret = 0;
   1851  1.1  riastrad 
   1852  1.1  riastrad 
   1853  1.1  riastrad 	mutex_lock(&dev->mode_config.mutex);
   1854  1.1  riastrad 	if (arg->flags & DRM_VMW_CURSOR_BYPASS_ALL) {
   1855  1.1  riastrad 
   1856  1.1  riastrad 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
   1857  1.1  riastrad 			du = vmw_crtc_to_du(crtc);
   1858  1.1  riastrad 			du->hotspot_x = arg->xhot;
   1859  1.1  riastrad 			du->hotspot_y = arg->yhot;
   1860  1.1  riastrad 		}
   1861  1.1  riastrad 
   1862  1.1  riastrad 		mutex_unlock(&dev->mode_config.mutex);
   1863  1.1  riastrad 		return 0;
   1864  1.1  riastrad 	}
   1865  1.1  riastrad 
   1866  1.7  riastrad 	crtc = drm_crtc_find(dev, file_priv, arg->crtc_id);
   1867  1.4  riastrad 	if (!crtc) {
   1868  1.3  riastrad 		ret = -ENOENT;
   1869  1.1  riastrad 		goto out;
   1870  1.1  riastrad 	}
   1871  1.1  riastrad 
   1872  1.1  riastrad 	du = vmw_crtc_to_du(crtc);
   1873  1.1  riastrad 
   1874  1.1  riastrad 	du->hotspot_x = arg->xhot;
   1875  1.1  riastrad 	du->hotspot_y = arg->yhot;
   1876  1.1  riastrad 
   1877  1.1  riastrad out:
   1878  1.1  riastrad 	mutex_unlock(&dev->mode_config.mutex);
   1879  1.1  riastrad 
   1880  1.1  riastrad 	return ret;
   1881  1.1  riastrad }
   1882  1.1  riastrad 
   1883  1.1  riastrad int vmw_kms_write_svga(struct vmw_private *vmw_priv,
   1884  1.1  riastrad 			unsigned width, unsigned height, unsigned pitch,
   1885  1.1  riastrad 			unsigned bpp, unsigned depth)
   1886  1.1  riastrad {
   1887  1.1  riastrad 	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
   1888  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, pitch);
   1889  1.1  riastrad 	else if (vmw_fifo_have_pitchlock(vmw_priv))
   1890  1.4  riastrad 		vmw_mmio_write(pitch, vmw_priv->mmio_virt +
   1891  1.4  riastrad 			       SVGA_FIFO_PITCHLOCK);
   1892  1.1  riastrad 	vmw_write(vmw_priv, SVGA_REG_WIDTH, width);
   1893  1.1  riastrad 	vmw_write(vmw_priv, SVGA_REG_HEIGHT, height);
   1894  1.1  riastrad 	vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, bpp);
   1895  1.1  riastrad 
   1896  1.1  riastrad 	if (vmw_read(vmw_priv, SVGA_REG_DEPTH) != depth) {
   1897  1.1  riastrad 		DRM_ERROR("Invalid depth %u for %u bpp, host expects %u\n",
   1898  1.1  riastrad 			  depth, bpp, vmw_read(vmw_priv, SVGA_REG_DEPTH));
   1899  1.1  riastrad 		return -EINVAL;
   1900  1.1  riastrad 	}
   1901  1.1  riastrad 
   1902  1.1  riastrad 	return 0;
   1903  1.1  riastrad }
   1904  1.1  riastrad 
   1905  1.1  riastrad int vmw_kms_save_vga(struct vmw_private *vmw_priv)
   1906  1.1  riastrad {
   1907  1.1  riastrad 	struct vmw_vga_topology_state *save;
   1908  1.1  riastrad 	uint32_t i;
   1909  1.1  riastrad 
   1910  1.1  riastrad 	vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH);
   1911  1.1  riastrad 	vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT);
   1912  1.1  riastrad 	vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
   1913  1.1  riastrad 	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
   1914  1.1  riastrad 		vmw_priv->vga_pitchlock =
   1915  1.1  riastrad 		  vmw_read(vmw_priv, SVGA_REG_PITCHLOCK);
   1916  1.1  riastrad 	else if (vmw_fifo_have_pitchlock(vmw_priv))
   1917  1.4  riastrad 		vmw_priv->vga_pitchlock = vmw_mmio_read(vmw_priv->mmio_virt +
   1918  1.4  riastrad 							SVGA_FIFO_PITCHLOCK);
   1919  1.1  riastrad 
   1920  1.1  riastrad 	if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
   1921  1.1  riastrad 		return 0;
   1922  1.1  riastrad 
   1923  1.1  riastrad 	vmw_priv->num_displays = vmw_read(vmw_priv,
   1924  1.1  riastrad 					  SVGA_REG_NUM_GUEST_DISPLAYS);
   1925  1.1  riastrad 
   1926  1.1  riastrad 	if (vmw_priv->num_displays == 0)
   1927  1.1  riastrad 		vmw_priv->num_displays = 1;
   1928  1.1  riastrad 
   1929  1.1  riastrad 	for (i = 0; i < vmw_priv->num_displays; ++i) {
   1930  1.1  riastrad 		save = &vmw_priv->vga_save[i];
   1931  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
   1932  1.1  riastrad 		save->primary = vmw_read(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY);
   1933  1.1  riastrad 		save->pos_x = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_X);
   1934  1.1  riastrad 		save->pos_y = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y);
   1935  1.1  riastrad 		save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
   1936  1.1  riastrad 		save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
   1937  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
   1938  1.1  riastrad 		if (i == 0 && vmw_priv->num_displays == 1 &&
   1939  1.1  riastrad 		    save->width == 0 && save->height == 0) {
   1940  1.1  riastrad 
   1941  1.1  riastrad 			/*
   1942  1.1  riastrad 			 * It should be fairly safe to assume that these
   1943  1.1  riastrad 			 * values are uninitialized.
   1944  1.1  riastrad 			 */
   1945  1.1  riastrad 
   1946  1.1  riastrad 			save->width = vmw_priv->vga_width - save->pos_x;
   1947  1.1  riastrad 			save->height = vmw_priv->vga_height - save->pos_y;
   1948  1.1  riastrad 		}
   1949  1.1  riastrad 	}
   1950  1.1  riastrad 
   1951  1.1  riastrad 	return 0;
   1952  1.1  riastrad }
   1953  1.1  riastrad 
   1954  1.1  riastrad int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
   1955  1.1  riastrad {
   1956  1.1  riastrad 	struct vmw_vga_topology_state *save;
   1957  1.1  riastrad 	uint32_t i;
   1958  1.1  riastrad 
   1959  1.1  riastrad 	vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width);
   1960  1.1  riastrad 	vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height);
   1961  1.1  riastrad 	vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
   1962  1.1  riastrad 	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
   1963  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_PITCHLOCK,
   1964  1.1  riastrad 			  vmw_priv->vga_pitchlock);
   1965  1.1  riastrad 	else if (vmw_fifo_have_pitchlock(vmw_priv))
   1966  1.4  riastrad 		vmw_mmio_write(vmw_priv->vga_pitchlock,
   1967  1.4  riastrad 			       vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
   1968  1.1  riastrad 
   1969  1.1  riastrad 	if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
   1970  1.1  riastrad 		return 0;
   1971  1.1  riastrad 
   1972  1.1  riastrad 	for (i = 0; i < vmw_priv->num_displays; ++i) {
   1973  1.1  riastrad 		save = &vmw_priv->vga_save[i];
   1974  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
   1975  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, save->primary);
   1976  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, save->pos_x);
   1977  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, save->pos_y);
   1978  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, save->width);
   1979  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, save->height);
   1980  1.1  riastrad 		vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
   1981  1.1  riastrad 	}
   1982  1.1  riastrad 
   1983  1.1  riastrad 	return 0;
   1984  1.1  riastrad }
   1985  1.1  riastrad 
   1986  1.1  riastrad bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
   1987  1.1  riastrad 				uint32_t pitch,
   1988  1.1  riastrad 				uint32_t height)
   1989  1.1  riastrad {
   1990  1.4  riastrad 	return ((u64) pitch * (u64) height) < (u64)
   1991  1.4  riastrad 		((dev_priv->active_display_unit == vmw_du_screen_target) ?
   1992  1.4  riastrad 		 dev_priv->prim_bb_mem : dev_priv->vram_size);
   1993  1.1  riastrad }
   1994  1.1  riastrad 
   1995  1.1  riastrad 
   1996  1.1  riastrad /**
   1997  1.1  riastrad  * Function called by DRM code called with vbl_lock held.
   1998  1.1  riastrad  */
   1999  1.4  riastrad u32 vmw_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
   2000  1.1  riastrad {
   2001  1.1  riastrad 	return 0;
   2002  1.1  riastrad }
   2003  1.1  riastrad 
   2004  1.1  riastrad /**
   2005  1.1  riastrad  * Function called by DRM code called with vbl_lock held.
   2006  1.1  riastrad  */
   2007  1.4  riastrad int vmw_enable_vblank(struct drm_device *dev, unsigned int pipe)
   2008  1.1  riastrad {
   2009  1.7  riastrad 	return -EINVAL;
   2010  1.1  riastrad }
   2011  1.1  riastrad 
   2012  1.1  riastrad /**
   2013  1.1  riastrad  * Function called by DRM code called with vbl_lock held.
   2014  1.1  riastrad  */
   2015  1.4  riastrad void vmw_disable_vblank(struct drm_device *dev, unsigned int pipe)
   2016  1.1  riastrad {
   2017  1.1  riastrad }
   2018  1.1  riastrad 
   2019  1.7  riastrad /**
   2020  1.7  riastrad  * vmw_du_update_layout - Update the display unit with topology from resolution
   2021  1.7  riastrad  * plugin and generate DRM uevent
   2022  1.7  riastrad  * @dev_priv: device private
   2023  1.7  riastrad  * @num_rects: number of drm_rect in rects
   2024  1.7  riastrad  * @rects: toplogy to update
   2025  1.1  riastrad  */
   2026  1.7  riastrad static int vmw_du_update_layout(struct vmw_private *dev_priv,
   2027  1.7  riastrad 				unsigned int num_rects, struct drm_rect *rects)
   2028  1.1  riastrad {
   2029  1.1  riastrad 	struct drm_device *dev = dev_priv->dev;
   2030  1.1  riastrad 	struct vmw_display_unit *du;
   2031  1.1  riastrad 	struct drm_connector *con;
   2032  1.7  riastrad 	struct drm_connector_list_iter conn_iter;
   2033  1.7  riastrad 	struct drm_modeset_acquire_ctx ctx;
   2034  1.7  riastrad 	struct drm_crtc *crtc;
   2035  1.7  riastrad 	int ret;
   2036  1.1  riastrad 
   2037  1.7  riastrad 	/* Currently gui_x/y is protected with the crtc mutex */
   2038  1.1  riastrad 	mutex_lock(&dev->mode_config.mutex);
   2039  1.7  riastrad 	drm_modeset_acquire_init(&ctx, 0);
   2040  1.7  riastrad retry:
   2041  1.7  riastrad 	drm_for_each_crtc(crtc, dev) {
   2042  1.7  riastrad 		ret = drm_modeset_lock(&crtc->mutex, &ctx);
   2043  1.7  riastrad 		if (ret < 0) {
   2044  1.7  riastrad 			if (ret == -EDEADLK) {
   2045  1.7  riastrad 				drm_modeset_backoff(&ctx);
   2046  1.7  riastrad 				goto retry;
   2047  1.7  riastrad       		}
   2048  1.7  riastrad 			goto out_fini;
   2049  1.7  riastrad 		}
   2050  1.1  riastrad 	}
   2051  1.1  riastrad 
   2052  1.7  riastrad 	drm_connector_list_iter_begin(dev, &conn_iter);
   2053  1.7  riastrad 	drm_for_each_connector_iter(con, &conn_iter) {
   2054  1.1  riastrad 		du = vmw_connector_to_du(con);
   2055  1.7  riastrad 		if (num_rects > du->unit) {
   2056  1.7  riastrad 			du->pref_width = drm_rect_width(&rects[du->unit]);
   2057  1.7  riastrad 			du->pref_height = drm_rect_height(&rects[du->unit]);
   2058  1.1  riastrad 			du->pref_active = true;
   2059  1.7  riastrad 			du->gui_x = rects[du->unit].x1;
   2060  1.7  riastrad 			du->gui_y = rects[du->unit].y1;
   2061  1.1  riastrad 		} else {
   2062  1.1  riastrad 			du->pref_width = 800;
   2063  1.1  riastrad 			du->pref_height = 600;
   2064  1.1  riastrad 			du->pref_active = false;
   2065  1.7  riastrad 			du->gui_x = 0;
   2066  1.7  riastrad 			du->gui_y = 0;
   2067  1.7  riastrad 		}
   2068  1.7  riastrad 	}
   2069  1.7  riastrad 	drm_connector_list_iter_end(&conn_iter);
   2070  1.7  riastrad 
   2071  1.7  riastrad 	list_for_each_entry(con, &dev->mode_config.connector_list, head) {
   2072  1.7  riastrad 		du = vmw_connector_to_du(con);
   2073  1.7  riastrad 		if (num_rects > du->unit) {
   2074  1.7  riastrad 			drm_object_property_set_value
   2075  1.7  riastrad 			  (&con->base, dev->mode_config.suggested_x_property,
   2076  1.7  riastrad 			   du->gui_x);
   2077  1.7  riastrad 			drm_object_property_set_value
   2078  1.7  riastrad 			  (&con->base, dev->mode_config.suggested_y_property,
   2079  1.7  riastrad 			   du->gui_y);
   2080  1.7  riastrad 		} else {
   2081  1.7  riastrad 			drm_object_property_set_value
   2082  1.7  riastrad 			  (&con->base, dev->mode_config.suggested_x_property,
   2083  1.7  riastrad 			   0);
   2084  1.7  riastrad 			drm_object_property_set_value
   2085  1.7  riastrad 			  (&con->base, dev->mode_config.suggested_y_property,
   2086  1.7  riastrad 			   0);
   2087  1.1  riastrad 		}
   2088  1.1  riastrad 		con->status = vmw_du_connector_detect(con, true);
   2089  1.1  riastrad 	}
   2090  1.1  riastrad 
   2091  1.7  riastrad 	drm_sysfs_hotplug_event(dev);
   2092  1.7  riastrad out_fini:
   2093  1.7  riastrad 	drm_modeset_drop_locks(&ctx);
   2094  1.7  riastrad 	drm_modeset_acquire_fini(&ctx);
   2095  1.1  riastrad 	mutex_unlock(&dev->mode_config.mutex);
   2096  1.7  riastrad 
   2097  1.1  riastrad 	return 0;
   2098  1.1  riastrad }
   2099  1.1  riastrad 
   2100  1.7  riastrad int vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
   2101  1.7  riastrad 			  u16 *r, u16 *g, u16 *b,
   2102  1.7  riastrad 			  uint32_t size,
   2103  1.7  riastrad 			  struct drm_modeset_acquire_ctx *ctx)
   2104  1.1  riastrad {
   2105  1.1  riastrad 	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
   2106  1.1  riastrad 	int i;
   2107  1.1  riastrad 
   2108  1.1  riastrad 	for (i = 0; i < size; i++) {
   2109  1.1  riastrad 		DRM_DEBUG("%d r/g/b = 0x%04x / 0x%04x / 0x%04x\n", i,
   2110  1.1  riastrad 			  r[i], g[i], b[i]);
   2111  1.1  riastrad 		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 0, r[i] >> 8);
   2112  1.1  riastrad 		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8);
   2113  1.1  riastrad 		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8);
   2114  1.1  riastrad 	}
   2115  1.7  riastrad 
   2116  1.7  riastrad 	return 0;
   2117  1.1  riastrad }
   2118  1.1  riastrad 
   2119  1.4  riastrad int vmw_du_connector_dpms(struct drm_connector *connector, int mode)
   2120  1.1  riastrad {
   2121  1.4  riastrad 	return 0;
   2122  1.1  riastrad }
   2123  1.1  riastrad 
   2124  1.1  riastrad enum drm_connector_status
   2125  1.1  riastrad vmw_du_connector_detect(struct drm_connector *connector, bool force)
   2126  1.1  riastrad {
   2127  1.1  riastrad 	uint32_t num_displays;
   2128  1.1  riastrad 	struct drm_device *dev = connector->dev;
   2129  1.1  riastrad 	struct vmw_private *dev_priv = vmw_priv(dev);
   2130  1.1  riastrad 	struct vmw_display_unit *du = vmw_connector_to_du(connector);
   2131  1.1  riastrad 
   2132  1.1  riastrad 	num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS);
   2133  1.1  riastrad 
   2134  1.1  riastrad 	return ((vmw_connector_to_du(connector)->unit < num_displays &&
   2135  1.1  riastrad 		 du->pref_active) ?
   2136  1.1  riastrad 		connector_status_connected : connector_status_disconnected);
   2137  1.1  riastrad }
   2138  1.1  riastrad 
   2139  1.1  riastrad static struct drm_display_mode vmw_kms_connector_builtin[] = {
   2140  1.1  riastrad 	/* 640x480@60Hz */
   2141  1.1  riastrad 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
   2142  1.1  riastrad 		   752, 800, 0, 480, 489, 492, 525, 0,
   2143  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
   2144  1.1  riastrad 	/* 800x600@60Hz */
   2145  1.1  riastrad 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
   2146  1.1  riastrad 		   968, 1056, 0, 600, 601, 605, 628, 0,
   2147  1.1  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2148  1.1  riastrad 	/* 1024x768@60Hz */
   2149  1.1  riastrad 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
   2150  1.1  riastrad 		   1184, 1344, 0, 768, 771, 777, 806, 0,
   2151  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
   2152  1.1  riastrad 	/* 1152x864@75Hz */
   2153  1.1  riastrad 	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
   2154  1.1  riastrad 		   1344, 1600, 0, 864, 865, 868, 900, 0,
   2155  1.1  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2156  1.1  riastrad 	/* 1280x768@60Hz */
   2157  1.1  riastrad 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
   2158  1.1  riastrad 		   1472, 1664, 0, 768, 771, 778, 798, 0,
   2159  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2160  1.1  riastrad 	/* 1280x800@60Hz */
   2161  1.1  riastrad 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
   2162  1.1  riastrad 		   1480, 1680, 0, 800, 803, 809, 831, 0,
   2163  1.1  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
   2164  1.1  riastrad 	/* 1280x960@60Hz */
   2165  1.1  riastrad 	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
   2166  1.1  riastrad 		   1488, 1800, 0, 960, 961, 964, 1000, 0,
   2167  1.1  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2168  1.1  riastrad 	/* 1280x1024@60Hz */
   2169  1.1  riastrad 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
   2170  1.1  riastrad 		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
   2171  1.1  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2172  1.1  riastrad 	/* 1360x768@60Hz */
   2173  1.1  riastrad 	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
   2174  1.1  riastrad 		   1536, 1792, 0, 768, 771, 777, 795, 0,
   2175  1.1  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2176  1.1  riastrad 	/* 1440x1050@60Hz */
   2177  1.1  riastrad 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
   2178  1.1  riastrad 		   1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
   2179  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2180  1.1  riastrad 	/* 1440x900@60Hz */
   2181  1.1  riastrad 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
   2182  1.1  riastrad 		   1672, 1904, 0, 900, 903, 909, 934, 0,
   2183  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2184  1.1  riastrad 	/* 1600x1200@60Hz */
   2185  1.1  riastrad 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
   2186  1.1  riastrad 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
   2187  1.1  riastrad 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2188  1.1  riastrad 	/* 1680x1050@60Hz */
   2189  1.1  riastrad 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
   2190  1.1  riastrad 		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
   2191  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2192  1.1  riastrad 	/* 1792x1344@60Hz */
   2193  1.1  riastrad 	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
   2194  1.1  riastrad 		   2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
   2195  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2196  1.1  riastrad 	/* 1853x1392@60Hz */
   2197  1.1  riastrad 	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
   2198  1.1  riastrad 		   2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
   2199  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2200  1.1  riastrad 	/* 1920x1200@60Hz */
   2201  1.1  riastrad 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
   2202  1.1  riastrad 		   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
   2203  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2204  1.1  riastrad 	/* 1920x1440@60Hz */
   2205  1.1  riastrad 	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
   2206  1.1  riastrad 		   2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
   2207  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2208  1.1  riastrad 	/* 2560x1600@60Hz */
   2209  1.1  riastrad 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
   2210  1.1  riastrad 		   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
   2211  1.1  riastrad 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
   2212  1.1  riastrad 	/* Terminate */
   2213  1.1  riastrad 	{ DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) },
   2214  1.1  riastrad };
   2215  1.1  riastrad 
   2216  1.1  riastrad /**
   2217  1.1  riastrad  * vmw_guess_mode_timing - Provide fake timings for a
   2218  1.1  riastrad  * 60Hz vrefresh mode.
   2219  1.1  riastrad  *
   2220  1.1  riastrad  * @mode - Pointer to a struct drm_display_mode with hdisplay and vdisplay
   2221  1.1  riastrad  * members filled in.
   2222  1.1  riastrad  */
   2223  1.4  riastrad void vmw_guess_mode_timing(struct drm_display_mode *mode)
   2224  1.1  riastrad {
   2225  1.1  riastrad 	mode->hsync_start = mode->hdisplay + 50;
   2226  1.1  riastrad 	mode->hsync_end = mode->hsync_start + 50;
   2227  1.1  riastrad 	mode->htotal = mode->hsync_end + 50;
   2228  1.1  riastrad 
   2229  1.1  riastrad 	mode->vsync_start = mode->vdisplay + 50;
   2230  1.1  riastrad 	mode->vsync_end = mode->vsync_start + 50;
   2231  1.1  riastrad 	mode->vtotal = mode->vsync_end + 50;
   2232  1.1  riastrad 
   2233  1.1  riastrad 	mode->clock = (u32)mode->htotal * (u32)mode->vtotal / 100 * 6;
   2234  1.1  riastrad 	mode->vrefresh = drm_mode_vrefresh(mode);
   2235  1.1  riastrad }
   2236  1.1  riastrad 
   2237  1.1  riastrad 
   2238  1.1  riastrad int vmw_du_connector_fill_modes(struct drm_connector *connector,
   2239  1.1  riastrad 				uint32_t max_width, uint32_t max_height)
   2240  1.1  riastrad {
   2241  1.1  riastrad 	struct vmw_display_unit *du = vmw_connector_to_du(connector);
   2242  1.1  riastrad 	struct drm_device *dev = connector->dev;
   2243  1.1  riastrad 	struct vmw_private *dev_priv = vmw_priv(dev);
   2244  1.1  riastrad 	struct drm_display_mode *mode = NULL;
   2245  1.1  riastrad 	struct drm_display_mode *bmode;
   2246  1.1  riastrad 	struct drm_display_mode prefmode = { DRM_MODE("preferred",
   2247  1.1  riastrad 		DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
   2248  1.1  riastrad 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2249  1.1  riastrad 		DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
   2250  1.1  riastrad 	};
   2251  1.1  riastrad 	int i;
   2252  1.4  riastrad 	u32 assumed_bpp = 4;
   2253  1.4  riastrad 
   2254  1.4  riastrad 	if (dev_priv->assume_16bpp)
   2255  1.4  riastrad 		assumed_bpp = 2;
   2256  1.4  riastrad 
   2257  1.7  riastrad 	max_width  = min(max_width,  dev_priv->texture_max_width);
   2258  1.7  riastrad 	max_height = min(max_height, dev_priv->texture_max_height);
   2259  1.7  riastrad 
   2260  1.7  riastrad 	/*
   2261  1.7  riastrad 	 * For STDU extra limit for a mode on SVGA_REG_SCREENTARGET_MAX_WIDTH/
   2262  1.7  riastrad 	 * HEIGHT registers.
   2263  1.7  riastrad 	 */
   2264  1.4  riastrad 	if (dev_priv->active_display_unit == vmw_du_screen_target) {
   2265  1.4  riastrad 		max_width  = min(max_width,  dev_priv->stdu_max_width);
   2266  1.4  riastrad 		max_height = min(max_height, dev_priv->stdu_max_height);
   2267  1.4  riastrad 	}
   2268  1.1  riastrad 
   2269  1.1  riastrad 	/* Add preferred mode */
   2270  1.4  riastrad 	mode = drm_mode_duplicate(dev, &prefmode);
   2271  1.4  riastrad 	if (!mode)
   2272  1.4  riastrad 		return 0;
   2273  1.4  riastrad 	mode->hdisplay = du->pref_width;
   2274  1.4  riastrad 	mode->vdisplay = du->pref_height;
   2275  1.4  riastrad 	vmw_guess_mode_timing(mode);
   2276  1.4  riastrad 
   2277  1.4  riastrad 	if (vmw_kms_validate_mode_vram(dev_priv,
   2278  1.4  riastrad 					mode->hdisplay * assumed_bpp,
   2279  1.4  riastrad 					mode->vdisplay)) {
   2280  1.4  riastrad 		drm_mode_probed_add(connector, mode);
   2281  1.4  riastrad 	} else {
   2282  1.4  riastrad 		drm_mode_destroy(dev, mode);
   2283  1.4  riastrad 		mode = NULL;
   2284  1.4  riastrad 	}
   2285  1.1  riastrad 
   2286  1.4  riastrad 	if (du->pref_mode) {
   2287  1.4  riastrad 		list_del_init(&du->pref_mode->head);
   2288  1.4  riastrad 		drm_mode_destroy(dev, du->pref_mode);
   2289  1.4  riastrad 	}
   2290  1.1  riastrad 
   2291  1.4  riastrad 	/* mode might be null here, this is intended */
   2292  1.4  riastrad 	du->pref_mode = mode;
   2293  1.1  riastrad 
   2294  1.1  riastrad 	for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) {
   2295  1.1  riastrad 		bmode = &vmw_kms_connector_builtin[i];
   2296  1.1  riastrad 		if (bmode->hdisplay > max_width ||
   2297  1.1  riastrad 		    bmode->vdisplay > max_height)
   2298  1.1  riastrad 			continue;
   2299  1.1  riastrad 
   2300  1.4  riastrad 		if (!vmw_kms_validate_mode_vram(dev_priv,
   2301  1.4  riastrad 						bmode->hdisplay * assumed_bpp,
   2302  1.1  riastrad 						bmode->vdisplay))
   2303  1.1  riastrad 			continue;
   2304  1.1  riastrad 
   2305  1.1  riastrad 		mode = drm_mode_duplicate(dev, bmode);
   2306  1.1  riastrad 		if (!mode)
   2307  1.1  riastrad 			return 0;
   2308  1.1  riastrad 		mode->vrefresh = drm_mode_vrefresh(mode);
   2309  1.1  riastrad 
   2310  1.1  riastrad 		drm_mode_probed_add(connector, mode);
   2311  1.1  riastrad 	}
   2312  1.1  riastrad 
   2313  1.7  riastrad 	drm_connector_list_update(connector);
   2314  1.1  riastrad 	/* Move the prefered mode first, help apps pick the right mode. */
   2315  1.4  riastrad 	drm_mode_sort(&connector->modes);
   2316  1.1  riastrad 
   2317  1.1  riastrad 	return 1;
   2318  1.1  riastrad }
   2319  1.1  riastrad 
   2320  1.7  riastrad /**
   2321  1.7  riastrad  * vmw_kms_update_layout_ioctl - Handler for DRM_VMW_UPDATE_LAYOUT ioctl
   2322  1.7  riastrad  * @dev: drm device for the ioctl
   2323  1.7  riastrad  * @data: data pointer for the ioctl
   2324  1.7  riastrad  * @file_priv: drm file for the ioctl call
   2325  1.7  riastrad  *
   2326  1.7  riastrad  * Update preferred topology of display unit as per ioctl request. The topology
   2327  1.7  riastrad  * is expressed as array of drm_vmw_rect.
   2328  1.7  riastrad  * e.g.
   2329  1.7  riastrad  * [0 0 640 480] [640 0 800 600] [0 480 640 480]
   2330  1.7  riastrad  *
   2331  1.7  riastrad  * NOTE:
   2332  1.7  riastrad  * The x and y offset (upper left) in drm_vmw_rect cannot be less than 0. Beside
   2333  1.7  riastrad  * device limit on topology, x + w and y + h (lower right) cannot be greater
   2334  1.7  riastrad  * than INT_MAX. So topology beyond these limits will return with error.
   2335  1.7  riastrad  *
   2336  1.7  riastrad  * Returns:
   2337  1.7  riastrad  * Zero on success, negative errno on failure.
   2338  1.7  riastrad  */
   2339  1.1  riastrad int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
   2340  1.1  riastrad 				struct drm_file *file_priv)
   2341  1.1  riastrad {
   2342  1.1  riastrad 	struct vmw_private *dev_priv = vmw_priv(dev);
   2343  1.7  riastrad 	struct drm_mode_config *mode_config = &dev->mode_config;
   2344  1.1  riastrad 	struct drm_vmw_update_layout_arg *arg =
   2345  1.1  riastrad 		(struct drm_vmw_update_layout_arg *)data;
   2346  1.1  riastrad 	void __user *user_rects;
   2347  1.1  riastrad 	struct drm_vmw_rect *rects;
   2348  1.7  riastrad 	struct drm_rect *drm_rects;
   2349  1.1  riastrad 	unsigned rects_size;
   2350  1.7  riastrad 	int ret, i;
   2351  1.1  riastrad 
   2352  1.1  riastrad 	if (!arg->num_outputs) {
   2353  1.7  riastrad 		struct drm_rect def_rect = {0, 0, 800, 600};
   2354  1.7  riastrad 		VMW_DEBUG_KMS("Default layout x1 = %d y1 = %d x2 = %d y2 = %d\n",
   2355  1.7  riastrad 			      def_rect.x1, def_rect.y1,
   2356  1.7  riastrad 			      def_rect.x2, def_rect.y2);
   2357  1.1  riastrad 		vmw_du_update_layout(dev_priv, 1, &def_rect);
   2358  1.4  riastrad 		return 0;
   2359  1.1  riastrad 	}
   2360  1.1  riastrad 
   2361  1.1  riastrad 	rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
   2362  1.1  riastrad 	rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
   2363  1.1  riastrad 			GFP_KERNEL);
   2364  1.4  riastrad 	if (unlikely(!rects))
   2365  1.4  riastrad 		return -ENOMEM;
   2366  1.1  riastrad 
   2367  1.1  riastrad 	user_rects = (void __user *)(unsigned long)arg->rects;
   2368  1.1  riastrad 	ret = copy_from_user(rects, user_rects, rects_size);
   2369  1.1  riastrad 	if (unlikely(ret != 0)) {
   2370  1.1  riastrad 		DRM_ERROR("Failed to get rects.\n");
   2371  1.1  riastrad 		ret = -EFAULT;
   2372  1.1  riastrad 		goto out_free;
   2373  1.1  riastrad 	}
   2374  1.1  riastrad 
   2375  1.7  riastrad 	drm_rects = (struct drm_rect *)rects;
   2376  1.7  riastrad 
   2377  1.7  riastrad 	VMW_DEBUG_KMS("Layout count = %u\n", arg->num_outputs);
   2378  1.7  riastrad 	for (i = 0; i < arg->num_outputs; i++) {
   2379  1.7  riastrad 		struct drm_vmw_rect curr_rect;
   2380  1.7  riastrad 
   2381  1.7  riastrad 		/* Verify user-space for overflow as kernel use drm_rect */
   2382  1.7  riastrad 		if ((rects[i].x + rects[i].w > INT_MAX) ||
   2383  1.7  riastrad 		    (rects[i].y + rects[i].h > INT_MAX)) {
   2384  1.7  riastrad 			ret = -ERANGE;
   2385  1.1  riastrad 			goto out_free;
   2386  1.1  riastrad 		}
   2387  1.4  riastrad 
   2388  1.7  riastrad 		curr_rect = rects[i];
   2389  1.7  riastrad 		drm_rects[i].x1 = curr_rect.x;
   2390  1.7  riastrad 		drm_rects[i].y1 = curr_rect.y;
   2391  1.7  riastrad 		drm_rects[i].x2 = curr_rect.x + curr_rect.w;
   2392  1.7  riastrad 		drm_rects[i].y2 = curr_rect.y + curr_rect.h;
   2393  1.7  riastrad 
   2394  1.7  riastrad 		VMW_DEBUG_KMS("  x1 = %d y1 = %d x2 = %d y2 = %d\n",
   2395  1.7  riastrad 			      drm_rects[i].x1, drm_rects[i].y1,
   2396  1.7  riastrad 			      drm_rects[i].x2, drm_rects[i].y2);
   2397  1.4  riastrad 
   2398  1.4  riastrad 		/*
   2399  1.7  riastrad 		 * Currently this check is limiting the topology within
   2400  1.7  riastrad 		 * mode_config->max (which actually is max texture size
   2401  1.7  riastrad 		 * supported by virtual device). This limit is here to address
   2402  1.7  riastrad 		 * window managers that create a big framebuffer for whole
   2403  1.7  riastrad 		 * topology.
   2404  1.4  riastrad 		 */
   2405  1.7  riastrad 		if (drm_rects[i].x1 < 0 ||  drm_rects[i].y1 < 0 ||
   2406  1.7  riastrad 		    drm_rects[i].x2 > mode_config->max_width ||
   2407  1.7  riastrad 		    drm_rects[i].y2 > mode_config->max_height) {
   2408  1.7  riastrad 			VMW_DEBUG_KMS("Invalid layout %d %d %d %d\n",
   2409  1.7  riastrad 				      drm_rects[i].x1, drm_rects[i].y1,
   2410  1.7  riastrad 				      drm_rects[i].x2, drm_rects[i].y2);
   2411  1.4  riastrad 			ret = -EINVAL;
   2412  1.4  riastrad 			goto out_free;
   2413  1.4  riastrad 		}
   2414  1.7  riastrad 	}
   2415  1.4  riastrad 
   2416  1.7  riastrad 	ret = vmw_kms_check_display_memory(dev, arg->num_outputs, drm_rects);
   2417  1.1  riastrad 
   2418  1.7  riastrad 	if (ret == 0)
   2419  1.7  riastrad 		vmw_du_update_layout(dev_priv, arg->num_outputs, drm_rects);
   2420  1.1  riastrad 
   2421  1.1  riastrad out_free:
   2422  1.1  riastrad 	kfree(rects);
   2423  1.4  riastrad 	return ret;
   2424  1.4  riastrad }
   2425  1.4  riastrad 
   2426  1.4  riastrad /**
   2427  1.4  riastrad  * vmw_kms_helper_dirty - Helper to build commands and perform actions based
   2428  1.4  riastrad  * on a set of cliprects and a set of display units.
   2429  1.4  riastrad  *
   2430  1.4  riastrad  * @dev_priv: Pointer to a device private structure.
   2431  1.4  riastrad  * @framebuffer: Pointer to the framebuffer on which to perform the actions.
   2432  1.4  riastrad  * @clips: A set of struct drm_clip_rect. Either this os @vclips must be NULL.
   2433  1.4  riastrad  * Cliprects are given in framebuffer coordinates.
   2434  1.4  riastrad  * @vclips: A set of struct drm_vmw_rect cliprects. Either this or @clips must
   2435  1.4  riastrad  * be NULL. Cliprects are given in source coordinates.
   2436  1.4  riastrad  * @dest_x: X coordinate offset for the crtc / destination clip rects.
   2437  1.4  riastrad  * @dest_y: Y coordinate offset for the crtc / destination clip rects.
   2438  1.4  riastrad  * @num_clips: Number of cliprects in the @clips or @vclips array.
   2439  1.4  riastrad  * @increment: Integer with which to increment the clip counter when looping.
   2440  1.4  riastrad  * Used to skip a predetermined number of clip rects.
   2441  1.4  riastrad  * @dirty: Closure structure. See the description of struct vmw_kms_dirty.
   2442  1.4  riastrad  */
   2443  1.4  riastrad int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
   2444  1.4  riastrad 			 struct vmw_framebuffer *framebuffer,
   2445  1.4  riastrad 			 const struct drm_clip_rect *clips,
   2446  1.4  riastrad 			 const struct drm_vmw_rect *vclips,
   2447  1.4  riastrad 			 s32 dest_x, s32 dest_y,
   2448  1.4  riastrad 			 int num_clips,
   2449  1.4  riastrad 			 int increment,
   2450  1.4  riastrad 			 struct vmw_kms_dirty *dirty)
   2451  1.4  riastrad {
   2452  1.4  riastrad 	struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
   2453  1.4  riastrad 	struct drm_crtc *crtc;
   2454  1.4  riastrad 	u32 num_units = 0;
   2455  1.4  riastrad 	u32 i, k;
   2456  1.4  riastrad 
   2457  1.4  riastrad 	dirty->dev_priv = dev_priv;
   2458  1.4  riastrad 
   2459  1.7  riastrad 	/* If crtc is passed, no need to iterate over other display units */
   2460  1.7  riastrad 	if (dirty->crtc) {
   2461  1.7  riastrad 		units[num_units++] = vmw_crtc_to_du(dirty->crtc);
   2462  1.7  riastrad 	} else {
   2463  1.7  riastrad 		list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list,
   2464  1.7  riastrad 				    head) {
   2465  1.7  riastrad 			struct drm_plane *plane = crtc->primary;
   2466  1.7  riastrad 
   2467  1.7  riastrad 			if (plane->state->fb == &framebuffer->base)
   2468  1.7  riastrad 				units[num_units++] = vmw_crtc_to_du(crtc);
   2469  1.7  riastrad 		}
   2470  1.4  riastrad 	}
   2471  1.4  riastrad 
   2472  1.4  riastrad 	for (k = 0; k < num_units; k++) {
   2473  1.4  riastrad 		struct vmw_display_unit *unit = units[k];
   2474  1.4  riastrad 		s32 crtc_x = unit->crtc.x;
   2475  1.4  riastrad 		s32 crtc_y = unit->crtc.y;
   2476  1.4  riastrad 		s32 crtc_width = unit->crtc.mode.hdisplay;
   2477  1.4  riastrad 		s32 crtc_height = unit->crtc.mode.vdisplay;
   2478  1.4  riastrad 		const struct drm_clip_rect *clips_ptr = clips;
   2479  1.4  riastrad 		const struct drm_vmw_rect *vclips_ptr = vclips;
   2480  1.4  riastrad 
   2481  1.4  riastrad 		dirty->unit = unit;
   2482  1.4  riastrad 		if (dirty->fifo_reserve_size > 0) {
   2483  1.7  riastrad 			dirty->cmd = VMW_FIFO_RESERVE(dev_priv,
   2484  1.4  riastrad 						      dirty->fifo_reserve_size);
   2485  1.7  riastrad 			if (!dirty->cmd)
   2486  1.4  riastrad 				return -ENOMEM;
   2487  1.7  riastrad 
   2488  1.4  riastrad 			memset(dirty->cmd, 0, dirty->fifo_reserve_size);
   2489  1.4  riastrad 		}
   2490  1.4  riastrad 		dirty->num_hits = 0;
   2491  1.4  riastrad 		for (i = 0; i < num_clips; i++, clips_ptr += increment,
   2492  1.4  riastrad 		       vclips_ptr += increment) {
   2493  1.4  riastrad 			s32 clip_left;
   2494  1.4  riastrad 			s32 clip_top;
   2495  1.4  riastrad 
   2496  1.4  riastrad 			/*
   2497  1.4  riastrad 			 * Select clip array type. Note that integer type
   2498  1.4  riastrad 			 * in @clips is unsigned short, whereas in @vclips
   2499  1.4  riastrad 			 * it's 32-bit.
   2500  1.4  riastrad 			 */
   2501  1.4  riastrad 			if (clips) {
   2502  1.4  riastrad 				dirty->fb_x = (s32) clips_ptr->x1;
   2503  1.4  riastrad 				dirty->fb_y = (s32) clips_ptr->y1;
   2504  1.4  riastrad 				dirty->unit_x2 = (s32) clips_ptr->x2 + dest_x -
   2505  1.4  riastrad 					crtc_x;
   2506  1.4  riastrad 				dirty->unit_y2 = (s32) clips_ptr->y2 + dest_y -
   2507  1.4  riastrad 					crtc_y;
   2508  1.4  riastrad 			} else {
   2509  1.4  riastrad 				dirty->fb_x = vclips_ptr->x;
   2510  1.4  riastrad 				dirty->fb_y = vclips_ptr->y;
   2511  1.4  riastrad 				dirty->unit_x2 = dirty->fb_x + vclips_ptr->w +
   2512  1.4  riastrad 					dest_x - crtc_x;
   2513  1.4  riastrad 				dirty->unit_y2 = dirty->fb_y + vclips_ptr->h +
   2514  1.4  riastrad 					dest_y - crtc_y;
   2515  1.4  riastrad 			}
   2516  1.4  riastrad 
   2517  1.4  riastrad 			dirty->unit_x1 = dirty->fb_x + dest_x - crtc_x;
   2518  1.4  riastrad 			dirty->unit_y1 = dirty->fb_y + dest_y - crtc_y;
   2519  1.4  riastrad 
   2520  1.4  riastrad 			/* Skip this clip if it's outside the crtc region */
   2521  1.4  riastrad 			if (dirty->unit_x1 >= crtc_width ||
   2522  1.4  riastrad 			    dirty->unit_y1 >= crtc_height ||
   2523  1.4  riastrad 			    dirty->unit_x2 <= 0 || dirty->unit_y2 <= 0)
   2524  1.4  riastrad 				continue;
   2525  1.4  riastrad 
   2526  1.4  riastrad 			/* Clip right and bottom to crtc limits */
   2527  1.4  riastrad 			dirty->unit_x2 = min_t(s32, dirty->unit_x2,
   2528  1.4  riastrad 					       crtc_width);
   2529  1.4  riastrad 			dirty->unit_y2 = min_t(s32, dirty->unit_y2,
   2530  1.4  riastrad 					       crtc_height);
   2531  1.4  riastrad 
   2532  1.4  riastrad 			/* Clip left and top to crtc limits */
   2533  1.4  riastrad 			clip_left = min_t(s32, dirty->unit_x1, 0);
   2534  1.4  riastrad 			clip_top = min_t(s32, dirty->unit_y1, 0);
   2535  1.4  riastrad 			dirty->unit_x1 -= clip_left;
   2536  1.4  riastrad 			dirty->unit_y1 -= clip_top;
   2537  1.4  riastrad 			dirty->fb_x -= clip_left;
   2538  1.4  riastrad 			dirty->fb_y -= clip_top;
   2539  1.4  riastrad 
   2540  1.4  riastrad 			dirty->clip(dirty);
   2541  1.4  riastrad 		}
   2542  1.4  riastrad 
   2543  1.4  riastrad 		dirty->fifo_commit(dirty);
   2544  1.4  riastrad 	}
   2545  1.4  riastrad 
   2546  1.4  riastrad 	return 0;
   2547  1.4  riastrad }
   2548  1.4  riastrad 
   2549  1.4  riastrad /**
   2550  1.7  riastrad  * vmw_kms_helper_validation_finish - Helper for post KMS command submission
   2551  1.7  riastrad  * cleanup and fencing
   2552  1.7  riastrad  * @dev_priv: Pointer to the device-private struct
   2553  1.7  riastrad  * @file_priv: Pointer identifying the client when user-space fencing is used
   2554  1.7  riastrad  * @ctx: Pointer to the validation context
   2555  1.7  riastrad  * @out_fence: If non-NULL, returned refcounted fence-pointer
   2556  1.7  riastrad  * @user_fence_rep: If non-NULL, pointer to user-space address area
   2557  1.7  riastrad  * in which to copy user-space fence info
   2558  1.7  riastrad  */
   2559  1.7  riastrad void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv,
   2560  1.7  riastrad 				      struct drm_file *file_priv,
   2561  1.7  riastrad 				      struct vmw_validation_context *ctx,
   2562  1.7  riastrad 				      struct vmw_fence_obj **out_fence,
   2563  1.7  riastrad 				      struct drm_vmw_fence_rep __user *
   2564  1.7  riastrad 				      user_fence_rep)
   2565  1.4  riastrad {
   2566  1.7  riastrad 	struct vmw_fence_obj *fence = NULL;
   2567  1.7  riastrad 	uint32_t handle = 0;
   2568  1.7  riastrad 	int ret = 0;
   2569  1.4  riastrad 
   2570  1.7  riastrad 	if (file_priv || user_fence_rep || vmw_validation_has_bos(ctx) ||
   2571  1.7  riastrad 	    out_fence)
   2572  1.7  riastrad 		ret = vmw_execbuf_fence_commands(file_priv, dev_priv, &fence,
   2573  1.7  riastrad 						 file_priv ? &handle : NULL);
   2574  1.7  riastrad 	vmw_validation_done(ctx, fence);
   2575  1.4  riastrad 	if (file_priv)
   2576  1.4  riastrad 		vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv),
   2577  1.4  riastrad 					    ret, user_fence_rep, fence,
   2578  1.7  riastrad 					    handle, -1, NULL);
   2579  1.4  riastrad 	if (out_fence)
   2580  1.4  riastrad 		*out_fence = fence;
   2581  1.4  riastrad 	else
   2582  1.4  riastrad 		vmw_fence_obj_unreference(&fence);
   2583  1.4  riastrad }
   2584  1.4  riastrad 
   2585  1.4  riastrad /**
   2586  1.4  riastrad  * vmw_kms_update_proxy - Helper function to update a proxy surface from
   2587  1.4  riastrad  * its backing MOB.
   2588  1.4  riastrad  *
   2589  1.4  riastrad  * @res: Pointer to the surface resource
   2590  1.4  riastrad  * @clips: Clip rects in framebuffer (surface) space.
   2591  1.4  riastrad  * @num_clips: Number of clips in @clips.
   2592  1.4  riastrad  * @increment: Integer with which to increment the clip counter when looping.
   2593  1.4  riastrad  * Used to skip a predetermined number of clip rects.
   2594  1.4  riastrad  *
   2595  1.4  riastrad  * This function makes sure the proxy surface is updated from its backing MOB
   2596  1.4  riastrad  * using the region given by @clips. The surface resource @res and its backing
   2597  1.4  riastrad  * MOB needs to be reserved and validated on call.
   2598  1.4  riastrad  */
   2599  1.4  riastrad int vmw_kms_update_proxy(struct vmw_resource *res,
   2600  1.4  riastrad 			 const struct drm_clip_rect *clips,
   2601  1.4  riastrad 			 unsigned num_clips,
   2602  1.4  riastrad 			 int increment)
   2603  1.4  riastrad {
   2604  1.4  riastrad 	struct vmw_private *dev_priv = res->dev_priv;
   2605  1.4  riastrad 	struct drm_vmw_size *size = &vmw_res_to_srf(res)->base_size;
   2606  1.4  riastrad 	struct {
   2607  1.4  riastrad 		SVGA3dCmdHeader header;
   2608  1.4  riastrad 		SVGA3dCmdUpdateGBImage body;
   2609  1.4  riastrad 	} *cmd;
   2610  1.4  riastrad 	SVGA3dBox *box;
   2611  1.4  riastrad 	size_t copy_size = 0;
   2612  1.4  riastrad 	int i;
   2613  1.4  riastrad 
   2614  1.4  riastrad 	if (!clips)
   2615  1.4  riastrad 		return 0;
   2616  1.4  riastrad 
   2617  1.7  riastrad 	cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd) * num_clips);
   2618  1.7  riastrad 	if (!cmd)
   2619  1.4  riastrad 		return -ENOMEM;
   2620  1.4  riastrad 
   2621  1.4  riastrad 	for (i = 0; i < num_clips; ++i, clips += increment, ++cmd) {
   2622  1.4  riastrad 		box = &cmd->body.box;
   2623  1.4  riastrad 
   2624  1.4  riastrad 		cmd->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
   2625  1.4  riastrad 		cmd->header.size = sizeof(cmd->body);
   2626  1.4  riastrad 		cmd->body.image.sid = res->id;
   2627  1.4  riastrad 		cmd->body.image.face = 0;
   2628  1.4  riastrad 		cmd->body.image.mipmap = 0;
   2629  1.4  riastrad 
   2630  1.4  riastrad 		if (clips->x1 > size->width || clips->x2 > size->width ||
   2631  1.4  riastrad 		    clips->y1 > size->height || clips->y2 > size->height) {
   2632  1.4  riastrad 			DRM_ERROR("Invalid clips outsize of framebuffer.\n");
   2633  1.4  riastrad 			return -EINVAL;
   2634  1.4  riastrad 		}
   2635  1.4  riastrad 
   2636  1.4  riastrad 		box->x = clips->x1;
   2637  1.4  riastrad 		box->y = clips->y1;
   2638  1.4  riastrad 		box->z = 0;
   2639  1.4  riastrad 		box->w = clips->x2 - clips->x1;
   2640  1.4  riastrad 		box->h = clips->y2 - clips->y1;
   2641  1.4  riastrad 		box->d = 1;
   2642  1.4  riastrad 
   2643  1.4  riastrad 		copy_size += sizeof(*cmd);
   2644  1.4  riastrad 	}
   2645  1.4  riastrad 
   2646  1.4  riastrad 	vmw_fifo_commit(dev_priv, copy_size);
   2647  1.4  riastrad 
   2648  1.4  riastrad 	return 0;
   2649  1.4  riastrad }
   2650  1.4  riastrad 
   2651  1.4  riastrad int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
   2652  1.4  riastrad 			    unsigned unit,
   2653  1.4  riastrad 			    u32 max_width,
   2654  1.4  riastrad 			    u32 max_height,
   2655  1.4  riastrad 			    struct drm_connector **p_con,
   2656  1.4  riastrad 			    struct drm_crtc **p_crtc,
   2657  1.4  riastrad 			    struct drm_display_mode **p_mode)
   2658  1.4  riastrad {
   2659  1.4  riastrad 	struct drm_connector *con;
   2660  1.4  riastrad 	struct vmw_display_unit *du;
   2661  1.4  riastrad 	struct drm_display_mode *mode;
   2662  1.4  riastrad 	int i = 0;
   2663  1.7  riastrad 	int ret = 0;
   2664  1.4  riastrad 
   2665  1.7  riastrad 	mutex_lock(&dev_priv->dev->mode_config.mutex);
   2666  1.4  riastrad 	list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list,
   2667  1.4  riastrad 			    head) {
   2668  1.4  riastrad 		if (i == unit)
   2669  1.4  riastrad 			break;
   2670  1.4  riastrad 
   2671  1.4  riastrad 		++i;
   2672  1.4  riastrad 	}
   2673  1.4  riastrad 
   2674  1.4  riastrad 	if (i != unit) {
   2675  1.4  riastrad 		DRM_ERROR("Could not find initial display unit.\n");
   2676  1.7  riastrad 		ret = -EINVAL;
   2677  1.7  riastrad 		goto out_unlock;
   2678  1.4  riastrad 	}
   2679  1.4  riastrad 
   2680  1.4  riastrad 	if (list_empty(&con->modes))
   2681  1.4  riastrad 		(void) vmw_du_connector_fill_modes(con, max_width, max_height);
   2682  1.4  riastrad 
   2683  1.4  riastrad 	if (list_empty(&con->modes)) {
   2684  1.4  riastrad 		DRM_ERROR("Could not find initial display mode.\n");
   2685  1.7  riastrad 		ret = -EINVAL;
   2686  1.7  riastrad 		goto out_unlock;
   2687  1.4  riastrad 	}
   2688  1.4  riastrad 
   2689  1.4  riastrad 	du = vmw_connector_to_du(con);
   2690  1.4  riastrad 	*p_con = con;
   2691  1.4  riastrad 	*p_crtc = &du->crtc;
   2692  1.4  riastrad 
   2693  1.4  riastrad 	list_for_each_entry(mode, &con->modes, head) {
   2694  1.4  riastrad 		if (mode->type & DRM_MODE_TYPE_PREFERRED)
   2695  1.4  riastrad 			break;
   2696  1.4  riastrad 	}
   2697  1.4  riastrad 
   2698  1.4  riastrad 	if (mode->type & DRM_MODE_TYPE_PREFERRED)
   2699  1.4  riastrad 		*p_mode = mode;
   2700  1.4  riastrad 	else {
   2701  1.4  riastrad 		WARN_ONCE(true, "Could not find initial preferred mode.\n");
   2702  1.4  riastrad 		*p_mode = list_first_entry(&con->modes,
   2703  1.4  riastrad 					   struct drm_display_mode,
   2704  1.4  riastrad 					   head);
   2705  1.4  riastrad 	}
   2706  1.4  riastrad 
   2707  1.7  riastrad  out_unlock:
   2708  1.7  riastrad 	mutex_unlock(&dev_priv->dev->mode_config.mutex);
   2709  1.7  riastrad 
   2710  1.7  riastrad 	return ret;
   2711  1.7  riastrad }
   2712  1.7  riastrad 
   2713  1.7  riastrad /**
   2714  1.7  riastrad  * vmw_kms_create_implicit_placement_proparty - Set up the implicit placement
   2715  1.7  riastrad  * property.
   2716  1.7  riastrad  *
   2717  1.7  riastrad  * @dev_priv: Pointer to a device private struct.
   2718  1.7  riastrad  *
   2719  1.7  riastrad  * Sets up the implicit placement property unless it's already set up.
   2720  1.7  riastrad  */
   2721  1.7  riastrad void
   2722  1.7  riastrad vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv)
   2723  1.7  riastrad {
   2724  1.7  riastrad 	if (dev_priv->implicit_placement_property)
   2725  1.7  riastrad 		return;
   2726  1.7  riastrad 
   2727  1.7  riastrad 	dev_priv->implicit_placement_property =
   2728  1.7  riastrad 		drm_property_create_range(dev_priv->dev,
   2729  1.7  riastrad 					  DRM_MODE_PROP_IMMUTABLE,
   2730  1.7  riastrad 					  "implicit_placement", 0, 1);
   2731  1.7  riastrad }
   2732  1.7  riastrad 
   2733  1.7  riastrad /**
   2734  1.7  riastrad  * vmw_kms_suspend - Save modesetting state and turn modesetting off.
   2735  1.7  riastrad  *
   2736  1.7  riastrad  * @dev: Pointer to the drm device
   2737  1.7  riastrad  * Return: 0 on success. Negative error code on failure.
   2738  1.7  riastrad  */
   2739  1.7  riastrad int vmw_kms_suspend(struct drm_device *dev)
   2740  1.7  riastrad {
   2741  1.7  riastrad 	struct vmw_private *dev_priv = vmw_priv(dev);
   2742  1.7  riastrad 
   2743  1.7  riastrad 	dev_priv->suspend_state = drm_atomic_helper_suspend(dev);
   2744  1.7  riastrad 	if (IS_ERR(dev_priv->suspend_state)) {
   2745  1.7  riastrad 		int ret = PTR_ERR(dev_priv->suspend_state);
   2746  1.7  riastrad 
   2747  1.7  riastrad 		DRM_ERROR("Failed kms suspend: %d\n", ret);
   2748  1.7  riastrad 		dev_priv->suspend_state = NULL;
   2749  1.7  riastrad 
   2750  1.7  riastrad 		return ret;
   2751  1.7  riastrad 	}
   2752  1.7  riastrad 
   2753  1.4  riastrad 	return 0;
   2754  1.4  riastrad }
   2755  1.7  riastrad 
   2756  1.7  riastrad 
   2757  1.7  riastrad /**
   2758  1.7  riastrad  * vmw_kms_resume - Re-enable modesetting and restore state
   2759  1.7  riastrad  *
   2760  1.7  riastrad  * @dev: Pointer to the drm device
   2761  1.7  riastrad  * Return: 0 on success. Negative error code on failure.
   2762  1.7  riastrad  *
   2763  1.7  riastrad  * State is resumed from a previous vmw_kms_suspend(). It's illegal
   2764  1.7  riastrad  * to call this function without a previous vmw_kms_suspend().
   2765  1.7  riastrad  */
   2766  1.7  riastrad int vmw_kms_resume(struct drm_device *dev)
   2767  1.7  riastrad {
   2768  1.7  riastrad 	struct vmw_private *dev_priv = vmw_priv(dev);
   2769  1.7  riastrad 	int ret;
   2770  1.7  riastrad 
   2771  1.7  riastrad 	if (WARN_ON(!dev_priv->suspend_state))
   2772  1.7  riastrad 		return 0;
   2773  1.7  riastrad 
   2774  1.7  riastrad 	ret = drm_atomic_helper_resume(dev, dev_priv->suspend_state);
   2775  1.7  riastrad 	dev_priv->suspend_state = NULL;
   2776  1.7  riastrad 
   2777  1.7  riastrad 	return ret;
   2778  1.7  riastrad }
   2779  1.7  riastrad 
   2780  1.7  riastrad /**
   2781  1.7  riastrad  * vmw_kms_lost_device - Notify kms that modesetting capabilities will be lost
   2782  1.7  riastrad  *
   2783  1.7  riastrad  * @dev: Pointer to the drm device
   2784  1.7  riastrad  */
   2785  1.7  riastrad void vmw_kms_lost_device(struct drm_device *dev)
   2786  1.7  riastrad {
   2787  1.7  riastrad 	drm_atomic_helper_shutdown(dev);
   2788  1.7  riastrad }
   2789  1.7  riastrad 
   2790  1.7  riastrad /**
   2791  1.7  riastrad  * vmw_du_helper_plane_update - Helper to do plane update on a display unit.
   2792  1.7  riastrad  * @update: The closure structure.
   2793  1.7  riastrad  *
   2794  1.7  riastrad  * Call this helper after setting callbacks in &vmw_du_update_plane to do plane
   2795  1.7  riastrad  * update on display unit.
   2796  1.7  riastrad  *
   2797  1.7  riastrad  * Return: 0 on success or a negative error code on failure.
   2798  1.7  riastrad  */
   2799  1.7  riastrad int vmw_du_helper_plane_update(struct vmw_du_update_plane *update)
   2800  1.7  riastrad {
   2801  1.7  riastrad 	struct drm_plane_state *state = update->plane->state;
   2802  1.7  riastrad 	struct drm_plane_state *old_state = update->old_state;
   2803  1.7  riastrad 	struct drm_atomic_helper_damage_iter iter;
   2804  1.7  riastrad 	struct drm_rect clip;
   2805  1.7  riastrad 	struct drm_rect bb;
   2806  1.7  riastrad 	DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
   2807  1.7  riastrad 	uint32_t reserved_size = 0;
   2808  1.7  riastrad 	uint32_t submit_size = 0;
   2809  1.7  riastrad 	uint32_t curr_size = 0;
   2810  1.7  riastrad 	uint32_t num_hits = 0;
   2811  1.7  riastrad 	void *cmd_start;
   2812  1.7  riastrad 	char *cmd_next;
   2813  1.7  riastrad 	int ret;
   2814  1.7  riastrad 
   2815  1.7  riastrad 	/*
   2816  1.7  riastrad 	 * Iterate in advance to check if really need plane update and find the
   2817  1.7  riastrad 	 * number of clips that actually are in plane src for fifo allocation.
   2818  1.7  riastrad 	 */
   2819  1.7  riastrad 	drm_atomic_helper_damage_iter_init(&iter, old_state, state);
   2820  1.7  riastrad 	drm_atomic_for_each_plane_damage(&iter, &clip)
   2821  1.7  riastrad 		num_hits++;
   2822  1.7  riastrad 
   2823  1.7  riastrad 	if (num_hits == 0)
   2824  1.7  riastrad 		return 0;
   2825  1.7  riastrad 
   2826  1.7  riastrad 	if (update->vfb->bo) {
   2827  1.7  riastrad 		struct vmw_framebuffer_bo *vfbbo =
   2828  1.7  riastrad 			container_of(update->vfb, typeof(*vfbbo), base);
   2829  1.7  riastrad 
   2830  1.7  riastrad 		ret = vmw_validation_add_bo(&val_ctx, vfbbo->buffer, false,
   2831  1.7  riastrad 					    update->cpu_blit);
   2832  1.7  riastrad 	} else {
   2833  1.7  riastrad 		struct vmw_framebuffer_surface *vfbs =
   2834  1.7  riastrad 			container_of(update->vfb, typeof(*vfbs), base);
   2835  1.7  riastrad 
   2836  1.7  riastrad 		ret = vmw_validation_add_resource(&val_ctx, &vfbs->surface->res,
   2837  1.7  riastrad 						  0, VMW_RES_DIRTY_NONE, NULL,
   2838  1.7  riastrad 						  NULL);
   2839  1.7  riastrad 	}
   2840  1.7  riastrad 
   2841  1.7  riastrad 	if (ret)
   2842  1.7  riastrad 		return ret;
   2843  1.7  riastrad 
   2844  1.7  riastrad 	ret = vmw_validation_prepare(&val_ctx, update->mutex, update->intr);
   2845  1.7  riastrad 	if (ret)
   2846  1.7  riastrad 		goto out_unref;
   2847  1.7  riastrad 
   2848  1.7  riastrad 	reserved_size = update->calc_fifo_size(update, num_hits);
   2849  1.7  riastrad 	cmd_start = VMW_FIFO_RESERVE(update->dev_priv, reserved_size);
   2850  1.7  riastrad 	if (!cmd_start) {
   2851  1.7  riastrad 		ret = -ENOMEM;
   2852  1.7  riastrad 		goto out_revert;
   2853  1.7  riastrad 	}
   2854  1.7  riastrad 
   2855  1.7  riastrad 	cmd_next = cmd_start;
   2856  1.7  riastrad 
   2857  1.7  riastrad 	if (update->post_prepare) {
   2858  1.7  riastrad 		curr_size = update->post_prepare(update, cmd_next);
   2859  1.7  riastrad 		cmd_next += curr_size;
   2860  1.7  riastrad 		submit_size += curr_size;
   2861  1.7  riastrad 	}
   2862  1.7  riastrad 
   2863  1.7  riastrad 	if (update->pre_clip) {
   2864  1.7  riastrad 		curr_size = update->pre_clip(update, cmd_next, num_hits);
   2865  1.7  riastrad 		cmd_next += curr_size;
   2866  1.7  riastrad 		submit_size += curr_size;
   2867  1.7  riastrad 	}
   2868  1.7  riastrad 
   2869  1.7  riastrad 	bb.x1 = INT_MAX;
   2870  1.7  riastrad 	bb.y1 = INT_MAX;
   2871  1.7  riastrad 	bb.x2 = INT_MIN;
   2872  1.7  riastrad 	bb.y2 = INT_MIN;
   2873  1.7  riastrad 
   2874  1.7  riastrad 	drm_atomic_helper_damage_iter_init(&iter, old_state, state);
   2875  1.7  riastrad 	drm_atomic_for_each_plane_damage(&iter, &clip) {
   2876  1.7  riastrad 		uint32_t fb_x = clip.x1;
   2877  1.7  riastrad 		uint32_t fb_y = clip.y1;
   2878  1.7  riastrad 
   2879  1.7  riastrad 		vmw_du_translate_to_crtc(state, &clip);
   2880  1.7  riastrad 		if (update->clip) {
   2881  1.7  riastrad 			curr_size = update->clip(update, cmd_next, &clip, fb_x,
   2882  1.7  riastrad 						 fb_y);
   2883  1.7  riastrad 			cmd_next += curr_size;
   2884  1.7  riastrad 			submit_size += curr_size;
   2885  1.7  riastrad 		}
   2886  1.7  riastrad 		bb.x1 = min_t(int, bb.x1, clip.x1);
   2887  1.7  riastrad 		bb.y1 = min_t(int, bb.y1, clip.y1);
   2888  1.7  riastrad 		bb.x2 = max_t(int, bb.x2, clip.x2);
   2889  1.7  riastrad 		bb.y2 = max_t(int, bb.y2, clip.y2);
   2890  1.7  riastrad 	}
   2891  1.7  riastrad 
   2892  1.7  riastrad 	curr_size = update->post_clip(update, cmd_next, &bb);
   2893  1.7  riastrad 	submit_size += curr_size;
   2894  1.7  riastrad 
   2895  1.7  riastrad 	if (reserved_size < submit_size)
   2896  1.7  riastrad 		submit_size = 0;
   2897  1.7  riastrad 
   2898  1.7  riastrad 	vmw_fifo_commit(update->dev_priv, submit_size);
   2899  1.7  riastrad 
   2900  1.7  riastrad 	vmw_kms_helper_validation_finish(update->dev_priv, NULL, &val_ctx,
   2901  1.7  riastrad 					 update->out_fence, NULL);
   2902  1.7  riastrad 	return ret;
   2903  1.7  riastrad 
   2904  1.7  riastrad out_revert:
   2905  1.7  riastrad 	vmw_validation_revert(&val_ctx);
   2906  1.7  riastrad 
   2907  1.7  riastrad out_unref:
   2908  1.7  riastrad 	vmw_validation_unref_lists(&val_ctx);
   2909  1.7  riastrad 	return ret;
   2910  1.7  riastrad }
   2911