xref: /openbmc/linux/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h (revision 65674218)
109881d29SZack Rusin /* SPDX-License-Identifier: GPL-2.0 OR MIT */
209881d29SZack Rusin /**************************************************************************
309881d29SZack Rusin  *
409881d29SZack Rusin  * Copyright 2023 VMware, Inc., Palo Alto, CA., USA
509881d29SZack Rusin  *
609881d29SZack Rusin  * Permission is hereby granted, free of charge, to any person obtaining a
709881d29SZack Rusin  * copy of this software and associated documentation files (the
809881d29SZack Rusin  * "Software"), to deal in the Software without restriction, including
909881d29SZack Rusin  * without limitation the rights to use, copy, modify, merge, publish,
1009881d29SZack Rusin  * distribute, sub license, and/or sell copies of the Software, and to
1109881d29SZack Rusin  * permit persons to whom the Software is furnished to do so, subject to
1209881d29SZack Rusin  * the following conditions:
1309881d29SZack Rusin  *
1409881d29SZack Rusin  * The above copyright notice and this permission notice (including the
1509881d29SZack Rusin  * next paragraph) shall be included in all copies or substantial portions
1609881d29SZack Rusin  * of the Software.
1709881d29SZack Rusin  *
1809881d29SZack Rusin  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1909881d29SZack Rusin  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2009881d29SZack Rusin  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
2109881d29SZack Rusin  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
2209881d29SZack Rusin  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2309881d29SZack Rusin  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2409881d29SZack Rusin  * USE OR OTHER DEALINGS IN THE SOFTWARE.
2509881d29SZack Rusin  *
2609881d29SZack Rusin  **************************************************************************/
2709881d29SZack Rusin 
2809881d29SZack Rusin #ifndef VMWGFX_BO_H
2909881d29SZack Rusin #define VMWGFX_BO_H
3009881d29SZack Rusin 
3109881d29SZack Rusin #include "device_include/svga_reg.h"
3209881d29SZack Rusin 
3309881d29SZack Rusin #include <drm/ttm/ttm_bo.h>
3439985eeaSZack Rusin #include <drm/ttm/ttm_placement.h>
3509881d29SZack Rusin 
3609881d29SZack Rusin #include <linux/rbtree_types.h>
3709881d29SZack Rusin #include <linux/types.h>
3809881d29SZack Rusin 
3909881d29SZack Rusin struct vmw_bo_dirty;
4009881d29SZack Rusin struct vmw_fence_obj;
4109881d29SZack Rusin struct vmw_private;
4209881d29SZack Rusin struct vmw_resource;
4309881d29SZack Rusin 
4439985eeaSZack Rusin enum vmw_bo_domain {
4539985eeaSZack Rusin 	VMW_BO_DOMAIN_SYS           = BIT(0),
4639985eeaSZack Rusin 	VMW_BO_DOMAIN_WAITABLE_SYS  = BIT(1),
4739985eeaSZack Rusin 	VMW_BO_DOMAIN_VRAM          = BIT(2),
4839985eeaSZack Rusin 	VMW_BO_DOMAIN_GMR           = BIT(3),
4939985eeaSZack Rusin 	VMW_BO_DOMAIN_MOB           = BIT(4),
5039985eeaSZack Rusin };
5139985eeaSZack Rusin 
52668b2066SZack Rusin struct vmw_bo_params {
53668b2066SZack Rusin 	u32 domain;
54668b2066SZack Rusin 	u32 busy_domain;
55668b2066SZack Rusin 	enum ttm_bo_type bo_type;
56668b2066SZack Rusin 	size_t size;
57668b2066SZack Rusin 	bool pin;
5865674218SZack Rusin 	struct dma_resv *resv;
5965674218SZack Rusin 	struct sg_table *sg;
60668b2066SZack Rusin };
61668b2066SZack Rusin 
6209881d29SZack Rusin /**
6309881d29SZack Rusin  * struct vmw_bo - TTM buffer object with vmwgfx additions
64668b2066SZack Rusin  * @tbo: The TTM buffer object
65668b2066SZack Rusin  * @placement: The preferred placement for this buffer object
66668b2066SZack Rusin  * @places: The chosen places for the preferred placement.
67668b2066SZack Rusin  * @busy_places: Chosen busy places for the preferred placement
68668b2066SZack Rusin  * @map: Kmap object for semi-persistent mappings
6909881d29SZack Rusin  * @res_tree: RB tree of resources using this buffer object as a backing MOB
70668b2066SZack Rusin  * @res_prios: Eviction priority counts for attached resources
7109881d29SZack Rusin  * @cpu_writers: Number of synccpu write grabs. Protected by reservation when
7209881d29SZack Rusin  * increased. May be decreased without reservation.
7309881d29SZack Rusin  * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB
7409881d29SZack Rusin  * @dirty: structure for user-space dirty-tracking
7509881d29SZack Rusin  */
7609881d29SZack Rusin struct vmw_bo {
77668b2066SZack Rusin 	struct ttm_buffer_object tbo;
7839985eeaSZack Rusin 
7939985eeaSZack Rusin 	struct ttm_placement placement;
8039985eeaSZack Rusin 	struct ttm_place places[5];
8139985eeaSZack Rusin 	struct ttm_place busy_places[5];
8239985eeaSZack Rusin 
83668b2066SZack Rusin 	/* Protected by reservation */
84668b2066SZack Rusin 	struct ttm_bo_kmap_obj map;
85668b2066SZack Rusin 
8609881d29SZack Rusin 	struct rb_root res_tree;
87668b2066SZack Rusin 	u32 res_prios[TTM_MAX_BO_PRIORITY];
8809881d29SZack Rusin 
8909881d29SZack Rusin 	atomic_t cpu_writers;
9009881d29SZack Rusin 	/* Not ref-counted.  Protected by binding_mutex */
9109881d29SZack Rusin 	struct vmw_resource *dx_query_ctx;
9209881d29SZack Rusin 	struct vmw_bo_dirty *dirty;
9309881d29SZack Rusin };
9409881d29SZack Rusin 
9539985eeaSZack Rusin void vmw_bo_placement_set(struct vmw_bo *bo, u32 domain, u32 busy_domain);
9639985eeaSZack Rusin void vmw_bo_placement_set_default_accelerated(struct vmw_bo *bo);
9739985eeaSZack Rusin 
9809881d29SZack Rusin int vmw_bo_create(struct vmw_private *dev_priv,
99668b2066SZack Rusin 		  struct vmw_bo_params *params,
10009881d29SZack Rusin 		  struct vmw_bo **p_bo);
101668b2066SZack Rusin 
10209881d29SZack Rusin int vmw_bo_unref_ioctl(struct drm_device *dev, void *data,
10309881d29SZack Rusin 		       struct drm_file *file_priv);
10409881d29SZack Rusin 
10509881d29SZack Rusin int vmw_bo_pin_in_vram(struct vmw_private *dev_priv,
10609881d29SZack Rusin 		       struct vmw_bo *buf,
10709881d29SZack Rusin 		       bool interruptible);
10809881d29SZack Rusin int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
10909881d29SZack Rusin 			      struct vmw_bo *buf,
11009881d29SZack Rusin 			      bool interruptible);
11109881d29SZack Rusin int vmw_bo_pin_in_start_of_vram(struct vmw_private *vmw_priv,
11209881d29SZack Rusin 				struct vmw_bo *bo,
11309881d29SZack Rusin 				bool interruptible);
11409881d29SZack Rusin void vmw_bo_pin_reserved(struct vmw_bo *bo, bool pin);
11509881d29SZack Rusin int vmw_bo_unpin(struct vmw_private *vmw_priv,
11609881d29SZack Rusin 		 struct vmw_bo *bo,
11709881d29SZack Rusin 		 bool interruptible);
11809881d29SZack Rusin 
11909881d29SZack Rusin void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *buf,
12009881d29SZack Rusin 			  SVGAGuestPtr *ptr);
12109881d29SZack Rusin int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data,
12209881d29SZack Rusin 			      struct drm_file *file_priv);
12309881d29SZack Rusin void vmw_bo_fence_single(struct ttm_buffer_object *bo,
12409881d29SZack Rusin 			 struct vmw_fence_obj *fence);
12509881d29SZack Rusin 
12609881d29SZack Rusin void *vmw_bo_map_and_cache(struct vmw_bo *vbo);
12709881d29SZack Rusin void vmw_bo_unmap(struct vmw_bo *vbo);
12809881d29SZack Rusin 
12909881d29SZack Rusin void vmw_bo_move_notify(struct ttm_buffer_object *bo,
13009881d29SZack Rusin 			struct ttm_resource *mem);
13109881d29SZack Rusin void vmw_bo_swap_notify(struct ttm_buffer_object *bo);
13209881d29SZack Rusin 
133668b2066SZack Rusin int vmw_user_bo_lookup(struct drm_file *filp,
134668b2066SZack Rusin 		       u32 handle,
135668b2066SZack Rusin 		       struct vmw_bo **out);
13609881d29SZack Rusin /**
13709881d29SZack Rusin  * vmw_bo_adjust_prio - Adjust the buffer object eviction priority
13809881d29SZack Rusin  * according to attached resources
13909881d29SZack Rusin  * @vbo: The struct vmw_bo
14009881d29SZack Rusin  */
vmw_bo_prio_adjust(struct vmw_bo * vbo)14109881d29SZack Rusin static inline void vmw_bo_prio_adjust(struct vmw_bo *vbo)
14209881d29SZack Rusin {
14309881d29SZack Rusin 	int i = ARRAY_SIZE(vbo->res_prios);
14409881d29SZack Rusin 
14509881d29SZack Rusin 	while (i--) {
14609881d29SZack Rusin 		if (vbo->res_prios[i]) {
147668b2066SZack Rusin 			vbo->tbo.priority = i;
14809881d29SZack Rusin 			return;
14909881d29SZack Rusin 		}
15009881d29SZack Rusin 	}
15109881d29SZack Rusin 
152668b2066SZack Rusin 	vbo->tbo.priority = 3;
15309881d29SZack Rusin }
15409881d29SZack Rusin 
15509881d29SZack Rusin /**
15609881d29SZack Rusin  * vmw_bo_prio_add - Notify a buffer object of a newly attached resource
15709881d29SZack Rusin  * eviction priority
15809881d29SZack Rusin  * @vbo: The struct vmw_bo
15909881d29SZack Rusin  * @prio: The resource priority
16009881d29SZack Rusin  *
16109881d29SZack Rusin  * After being notified, the code assigns the highest resource eviction priority
16209881d29SZack Rusin  * to the backing buffer object (mob).
16309881d29SZack Rusin  */
vmw_bo_prio_add(struct vmw_bo * vbo,int prio)16409881d29SZack Rusin static inline void vmw_bo_prio_add(struct vmw_bo *vbo, int prio)
16509881d29SZack Rusin {
16609881d29SZack Rusin 	if (vbo->res_prios[prio]++ == 0)
16709881d29SZack Rusin 		vmw_bo_prio_adjust(vbo);
16809881d29SZack Rusin }
16909881d29SZack Rusin 
17009881d29SZack Rusin /**
171668b2066SZack Rusin  * vmw_bo_used_prio_del - Notify a buffer object of a resource with a certain
17209881d29SZack Rusin  * priority being removed
17309881d29SZack Rusin  * @vbo: The struct vmw_bo
17409881d29SZack Rusin  * @prio: The resource priority
17509881d29SZack Rusin  *
17609881d29SZack Rusin  * After being notified, the code assigns the highest resource eviction priority
17709881d29SZack Rusin  * to the backing buffer object (mob).
17809881d29SZack Rusin  */
vmw_bo_prio_del(struct vmw_bo * vbo,int prio)17909881d29SZack Rusin static inline void vmw_bo_prio_del(struct vmw_bo *vbo, int prio)
18009881d29SZack Rusin {
18109881d29SZack Rusin 	if (--vbo->res_prios[prio] == 0)
18209881d29SZack Rusin 		vmw_bo_prio_adjust(vbo);
18309881d29SZack Rusin }
18409881d29SZack Rusin 
vmw_bo_unreference(struct vmw_bo ** buf)18509881d29SZack Rusin static inline void vmw_bo_unreference(struct vmw_bo **buf)
18609881d29SZack Rusin {
18709881d29SZack Rusin 	struct vmw_bo *tmp_buf = *buf;
18809881d29SZack Rusin 
18909881d29SZack Rusin 	*buf = NULL;
19009881d29SZack Rusin 	if (tmp_buf)
191668b2066SZack Rusin 		ttm_bo_put(&tmp_buf->tbo);
19209881d29SZack Rusin }
19309881d29SZack Rusin 
vmw_bo_reference(struct vmw_bo * buf)19409881d29SZack Rusin static inline struct vmw_bo *vmw_bo_reference(struct vmw_bo *buf)
19509881d29SZack Rusin {
196668b2066SZack Rusin 	ttm_bo_get(&buf->tbo);
19709881d29SZack Rusin 	return buf;
19809881d29SZack Rusin }
19909881d29SZack Rusin 
vmw_user_bo_ref(struct vmw_bo * vbo)20091398b41SZack Rusin static inline struct vmw_bo *vmw_user_bo_ref(struct vmw_bo *vbo)
201f9e96bf1SZack Rusin {
20291398b41SZack Rusin 	drm_gem_object_get(&vbo->tbo.base);
20391398b41SZack Rusin 	return vbo;
204f9e96bf1SZack Rusin }
20591398b41SZack Rusin 
vmw_user_bo_unref(struct vmw_bo ** buf)20691398b41SZack Rusin static inline void vmw_user_bo_unref(struct vmw_bo **buf)
20791398b41SZack Rusin {
20891398b41SZack Rusin 	struct vmw_bo *tmp_buf = *buf;
20991398b41SZack Rusin 
21091398b41SZack Rusin 	*buf = NULL;
21191398b41SZack Rusin 	if (tmp_buf)
21291398b41SZack Rusin 		drm_gem_object_put(&tmp_buf->tbo.base);
213f9e96bf1SZack Rusin }
214f9e96bf1SZack Rusin 
to_vmw_bo(struct drm_gem_object * gobj)21509881d29SZack Rusin static inline struct vmw_bo *to_vmw_bo(struct drm_gem_object *gobj)
21609881d29SZack Rusin {
217668b2066SZack Rusin 	return container_of((gobj), struct vmw_bo, tbo.base);
21809881d29SZack Rusin }
21909881d29SZack Rusin 
22009881d29SZack Rusin #endif // VMWGFX_BO_H
221