162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR MIT */
262306a36Sopenharmony_ci/**************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright © 2018 - 2022 VMware, Inc., Palo Alto, CA., USA
562306a36Sopenharmony_ci * All Rights Reserved.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
862306a36Sopenharmony_ci * copy of this software and associated documentation files (the
962306a36Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
1062306a36Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
1162306a36Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
1262306a36Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
1362306a36Sopenharmony_ci * the following conditions:
1462306a36Sopenharmony_ci *
1562306a36Sopenharmony_ci * The above copyright notice and this permission notice (including the
1662306a36Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
1762306a36Sopenharmony_ci * of the Software.
1862306a36Sopenharmony_ci *
1962306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2062306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2162306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
2262306a36Sopenharmony_ci * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
2362306a36Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2462306a36Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2562306a36Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
2662306a36Sopenharmony_ci *
2762306a36Sopenharmony_ci **************************************************************************/
2862306a36Sopenharmony_ci#ifndef _VMWGFX_VALIDATION_H_
2962306a36Sopenharmony_ci#define _VMWGFX_VALIDATION_H_
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#include <linux/list.h>
3262306a36Sopenharmony_ci#include <linux/hashtable.h>
3362306a36Sopenharmony_ci#include <linux/ww_mutex.h>
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#include <drm/ttm/ttm_execbuf_util.h>
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define VMW_RES_DIRTY_NONE 0
3862306a36Sopenharmony_ci#define VMW_RES_DIRTY_SET BIT(0)
3962306a36Sopenharmony_ci#define VMW_RES_DIRTY_CLEAR BIT(1)
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/**
4262306a36Sopenharmony_ci * struct vmw_validation_context - Per command submission validation context
4362306a36Sopenharmony_ci * @ht: Hash table used to find resource- or buffer object duplicates
4462306a36Sopenharmony_ci * @resource_list: List head for resource validation metadata
4562306a36Sopenharmony_ci * @resource_ctx_list: List head for resource validation metadata for
4662306a36Sopenharmony_ci * resources that need to be validated before those in @resource_list
4762306a36Sopenharmony_ci * @bo_list: List head for buffer objects
4862306a36Sopenharmony_ci * @page_list: List of pages used by the memory allocator
4962306a36Sopenharmony_ci * @ticket: Ticked used for ww mutex locking
5062306a36Sopenharmony_ci * @res_mutex: Pointer to mutex used for resource reserving
5162306a36Sopenharmony_ci * @merge_dups: Whether to merge metadata for duplicate resources or
5262306a36Sopenharmony_ci * buffer objects
5362306a36Sopenharmony_ci * @mem_size_left: Free memory left in the last page in @page_list
5462306a36Sopenharmony_ci * @page_address: Kernel virtual address of the last page in @page_list
5562306a36Sopenharmony_ci * @vm: A pointer to the memory reservation interface or NULL if no
5662306a36Sopenharmony_ci * memory reservation is needed.
5762306a36Sopenharmony_ci * @vm_size_left: Amount of reserved memory that so far has not been allocated.
5862306a36Sopenharmony_ci * @total_mem: Amount of reserved memory.
5962306a36Sopenharmony_ci */
6062306a36Sopenharmony_cistruct vmw_validation_context {
6162306a36Sopenharmony_ci	struct vmw_sw_context *sw_context;
6262306a36Sopenharmony_ci	struct list_head resource_list;
6362306a36Sopenharmony_ci	struct list_head resource_ctx_list;
6462306a36Sopenharmony_ci	struct list_head bo_list;
6562306a36Sopenharmony_ci	struct list_head page_list;
6662306a36Sopenharmony_ci	struct ww_acquire_ctx ticket;
6762306a36Sopenharmony_ci	struct mutex *res_mutex;
6862306a36Sopenharmony_ci	unsigned int merge_dups;
6962306a36Sopenharmony_ci	unsigned int mem_size_left;
7062306a36Sopenharmony_ci	u8 *page_address;
7162306a36Sopenharmony_ci	struct vmw_validation_mem *vm;
7262306a36Sopenharmony_ci	size_t vm_size_left;
7362306a36Sopenharmony_ci	size_t total_mem;
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_cistruct vmw_bo;
7762306a36Sopenharmony_cistruct vmw_resource;
7862306a36Sopenharmony_cistruct vmw_fence_obj;
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#if 0
8162306a36Sopenharmony_ci/**
8262306a36Sopenharmony_ci * DECLARE_VAL_CONTEXT - Declare a validation context with initialization
8362306a36Sopenharmony_ci * @_name: The name of the variable
8462306a36Sopenharmony_ci * @_sw_context: Contains the hash table used to find dups or NULL if none
8562306a36Sopenharmony_ci * @_merge_dups: Whether to merge duplicate buffer object- or resource
8662306a36Sopenharmony_ci * entries. If set to true, ideally a hash table pointer should be supplied
8762306a36Sopenharmony_ci * as well unless the number of resources and buffer objects per validation
8862306a36Sopenharmony_ci * is known to be very small
8962306a36Sopenharmony_ci */
9062306a36Sopenharmony_ci#endif
9162306a36Sopenharmony_ci#define DECLARE_VAL_CONTEXT(_name, _sw_context, _merge_dups)		\
9262306a36Sopenharmony_ci	struct vmw_validation_context _name =				\
9362306a36Sopenharmony_ci	{ .sw_context = _sw_context,					\
9462306a36Sopenharmony_ci	  .resource_list = LIST_HEAD_INIT((_name).resource_list),	\
9562306a36Sopenharmony_ci	  .resource_ctx_list = LIST_HEAD_INIT((_name).resource_ctx_list), \
9662306a36Sopenharmony_ci	  .bo_list = LIST_HEAD_INIT((_name).bo_list),			\
9762306a36Sopenharmony_ci	  .page_list = LIST_HEAD_INIT((_name).page_list),		\
9862306a36Sopenharmony_ci	  .res_mutex = NULL,						\
9962306a36Sopenharmony_ci	  .merge_dups = _merge_dups,					\
10062306a36Sopenharmony_ci	  .mem_size_left = 0,						\
10162306a36Sopenharmony_ci	}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/**
10462306a36Sopenharmony_ci * vmw_validation_has_bos - return whether the validation context has
10562306a36Sopenharmony_ci * any buffer objects registered.
10662306a36Sopenharmony_ci *
10762306a36Sopenharmony_ci * @ctx: The validation context
10862306a36Sopenharmony_ci * Returns: Whether any buffer objects are registered
10962306a36Sopenharmony_ci */
11062306a36Sopenharmony_cistatic inline bool
11162306a36Sopenharmony_civmw_validation_has_bos(struct vmw_validation_context *ctx)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	return !list_empty(&ctx->bo_list);
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci/**
11762306a36Sopenharmony_ci * vmw_validation_bo_reserve - Reserve buffer objects registered with a
11862306a36Sopenharmony_ci * validation context
11962306a36Sopenharmony_ci * @ctx: The validation context
12062306a36Sopenharmony_ci * @intr: Perform waits interruptible
12162306a36Sopenharmony_ci *
12262306a36Sopenharmony_ci * Return: Zero on success, -ERESTARTSYS when interrupted, negative error
12362306a36Sopenharmony_ci * code on failure
12462306a36Sopenharmony_ci */
12562306a36Sopenharmony_cistatic inline int
12662306a36Sopenharmony_civmw_validation_bo_reserve(struct vmw_validation_context *ctx,
12762306a36Sopenharmony_ci			  bool intr)
12862306a36Sopenharmony_ci{
12962306a36Sopenharmony_ci	return ttm_eu_reserve_buffers(&ctx->ticket, &ctx->bo_list, intr,
13062306a36Sopenharmony_ci				      NULL);
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci/**
13462306a36Sopenharmony_ci * vmw_validation_bo_fence - Unreserve and fence buffer objects registered
13562306a36Sopenharmony_ci * with a validation context
13662306a36Sopenharmony_ci * @ctx: The validation context
13762306a36Sopenharmony_ci *
13862306a36Sopenharmony_ci * This function unreserves the buffer objects previously reserved using
13962306a36Sopenharmony_ci * vmw_validation_bo_reserve, and fences them with a fence object.
14062306a36Sopenharmony_ci */
14162306a36Sopenharmony_cistatic inline void
14262306a36Sopenharmony_civmw_validation_bo_fence(struct vmw_validation_context *ctx,
14362306a36Sopenharmony_ci			struct vmw_fence_obj *fence)
14462306a36Sopenharmony_ci{
14562306a36Sopenharmony_ci	ttm_eu_fence_buffer_objects(&ctx->ticket, &ctx->bo_list,
14662306a36Sopenharmony_ci				    (void *) fence);
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci/**
15062306a36Sopenharmony_ci * vmw_validation_align - Align a validation memory allocation
15162306a36Sopenharmony_ci * @val: The size to be aligned
15262306a36Sopenharmony_ci *
15362306a36Sopenharmony_ci * Returns: @val aligned to the granularity used by the validation memory
15462306a36Sopenharmony_ci * allocator.
15562306a36Sopenharmony_ci */
15662306a36Sopenharmony_cistatic inline unsigned int vmw_validation_align(unsigned int val)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	return ALIGN(val, sizeof(long));
15962306a36Sopenharmony_ci}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ciint vmw_validation_add_bo(struct vmw_validation_context *ctx,
16262306a36Sopenharmony_ci			  struct vmw_bo *vbo);
16362306a36Sopenharmony_ciint vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr);
16462306a36Sopenharmony_civoid vmw_validation_unref_lists(struct vmw_validation_context *ctx);
16562306a36Sopenharmony_ciint vmw_validation_add_resource(struct vmw_validation_context *ctx,
16662306a36Sopenharmony_ci				struct vmw_resource *res,
16762306a36Sopenharmony_ci				size_t priv_size,
16862306a36Sopenharmony_ci				u32 dirty,
16962306a36Sopenharmony_ci				void **p_node,
17062306a36Sopenharmony_ci				bool *first_usage);
17162306a36Sopenharmony_civoid vmw_validation_drop_ht(struct vmw_validation_context *ctx);
17262306a36Sopenharmony_ciint vmw_validation_res_reserve(struct vmw_validation_context *ctx,
17362306a36Sopenharmony_ci			       bool intr);
17462306a36Sopenharmony_civoid vmw_validation_res_unreserve(struct vmw_validation_context *ctx,
17562306a36Sopenharmony_ci				  bool backoff);
17662306a36Sopenharmony_civoid vmw_validation_res_switch_backup(struct vmw_validation_context *ctx,
17762306a36Sopenharmony_ci				      void *val_private,
17862306a36Sopenharmony_ci				      struct vmw_bo *vbo,
17962306a36Sopenharmony_ci				      unsigned long backup_offset);
18062306a36Sopenharmony_ciint vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr);
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ciint vmw_validation_prepare(struct vmw_validation_context *ctx,
18362306a36Sopenharmony_ci			   struct mutex *mutex, bool intr);
18462306a36Sopenharmony_civoid vmw_validation_revert(struct vmw_validation_context *ctx);
18562306a36Sopenharmony_civoid vmw_validation_done(struct vmw_validation_context *ctx,
18662306a36Sopenharmony_ci			 struct vmw_fence_obj *fence);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_civoid *vmw_validation_mem_alloc(struct vmw_validation_context *ctx,
18962306a36Sopenharmony_ci			       unsigned int size);
19062306a36Sopenharmony_ciint vmw_validation_preload_bo(struct vmw_validation_context *ctx);
19162306a36Sopenharmony_ciint vmw_validation_preload_res(struct vmw_validation_context *ctx,
19262306a36Sopenharmony_ci			       unsigned int size);
19362306a36Sopenharmony_civoid vmw_validation_res_set_dirty(struct vmw_validation_context *ctx,
19462306a36Sopenharmony_ci				  void *val_private, u32 dirty);
19562306a36Sopenharmony_civoid vmw_validation_bo_backoff(struct vmw_validation_context *ctx);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci#endif
198