162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2020-2023 Intel Corporation
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci#ifndef __IVPU_GEM_H__
662306a36Sopenharmony_ci#define __IVPU_GEM_H__
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <drm/drm_gem.h>
962306a36Sopenharmony_ci#include <drm/drm_mm.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistruct dma_buf;
1262306a36Sopenharmony_cistruct ivpu_bo_ops;
1362306a36Sopenharmony_cistruct ivpu_file_priv;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistruct ivpu_bo {
1662306a36Sopenharmony_ci	struct drm_gem_object base;
1762306a36Sopenharmony_ci	const struct ivpu_bo_ops *ops;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	struct ivpu_mmu_context *ctx;
2062306a36Sopenharmony_ci	struct list_head ctx_node;
2162306a36Sopenharmony_ci	struct drm_mm_node mm_node;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	struct mutex lock; /* Protects: pages, sgt, mmu_mapped */
2462306a36Sopenharmony_ci	struct sg_table *sgt;
2562306a36Sopenharmony_ci	struct page **pages;
2662306a36Sopenharmony_ci	bool mmu_mapped;
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	void *kvaddr;
2962306a36Sopenharmony_ci	u64 vpu_addr;
3062306a36Sopenharmony_ci	u32 handle;
3162306a36Sopenharmony_ci	u32 flags;
3262306a36Sopenharmony_ci	uintptr_t user_ptr;
3362306a36Sopenharmony_ci	u32 job_status;
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cienum ivpu_bo_type {
3762306a36Sopenharmony_ci	IVPU_BO_TYPE_SHMEM = 1,
3862306a36Sopenharmony_ci	IVPU_BO_TYPE_INTERNAL,
3962306a36Sopenharmony_ci	IVPU_BO_TYPE_PRIME,
4062306a36Sopenharmony_ci};
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistruct ivpu_bo_ops {
4362306a36Sopenharmony_ci	enum ivpu_bo_type type;
4462306a36Sopenharmony_ci	const char *name;
4562306a36Sopenharmony_ci	int (*alloc_pages)(struct ivpu_bo *bo);
4662306a36Sopenharmony_ci	void (*free_pages)(struct ivpu_bo *bo);
4762306a36Sopenharmony_ci	int (*map_pages)(struct ivpu_bo *bo);
4862306a36Sopenharmony_ci	void (*unmap_pages)(struct ivpu_bo *bo);
4962306a36Sopenharmony_ci};
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ciint ivpu_bo_pin(struct ivpu_bo *bo);
5262306a36Sopenharmony_civoid ivpu_bo_remove_all_bos_from_context(struct ivpu_mmu_context *ctx);
5362306a36Sopenharmony_civoid ivpu_bo_list(struct drm_device *dev, struct drm_printer *p);
5462306a36Sopenharmony_civoid ivpu_bo_list_print(struct drm_device *dev);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistruct ivpu_bo *
5762306a36Sopenharmony_ciivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 flags);
5862306a36Sopenharmony_civoid ivpu_bo_free_internal(struct ivpu_bo *bo);
5962306a36Sopenharmony_cistruct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf);
6062306a36Sopenharmony_civoid ivpu_bo_unmap_sgt_and_remove_from_context(struct ivpu_bo *bo);
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ciint ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
6362306a36Sopenharmony_ciint ivpu_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
6462306a36Sopenharmony_ciint ivpu_bo_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic inline struct ivpu_bo *to_ivpu_bo(struct drm_gem_object *obj)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	return container_of(obj, struct ivpu_bo, base);
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic inline struct page *ivpu_bo_get_page(struct ivpu_bo *bo, u64 offset)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	if (offset > bo->base.size || !bo->pages)
7462306a36Sopenharmony_ci		return NULL;
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	return bo->pages[offset / PAGE_SIZE];
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistatic inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	return bo->flags & DRM_IVPU_BO_CACHE_MASK;
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cistatic inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic inline pgprot_t ivpu_bo_pgprot(struct ivpu_bo *bo, pgprot_t prot)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	if (bo->flags & DRM_IVPU_BO_WC)
9262306a36Sopenharmony_ci		return pgprot_writecombine(prot);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	if (bo->flags & DRM_IVPU_BO_UNCACHED)
9562306a36Sopenharmony_ci		return pgprot_noncached(prot);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	return prot;
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic inline struct ivpu_device *ivpu_bo_to_vdev(struct ivpu_bo *bo)
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	return to_ivpu_device(bo->base.dev);
10362306a36Sopenharmony_ci}
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cistatic inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr)
10662306a36Sopenharmony_ci{
10762306a36Sopenharmony_ci	if (vpu_addr < bo->vpu_addr)
10862306a36Sopenharmony_ci		return NULL;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	if (vpu_addr >= (bo->vpu_addr + bo->base.size))
11162306a36Sopenharmony_ci		return NULL;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	return bo->kvaddr + (vpu_addr - bo->vpu_addr);
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic inline u32 cpu_to_vpu_addr(struct ivpu_bo *bo, void *cpu_addr)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	if (cpu_addr < bo->kvaddr)
11962306a36Sopenharmony_ci		return 0;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	if (cpu_addr >= (bo->kvaddr + bo->base.size))
12262306a36Sopenharmony_ci		return 0;
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci	return bo->vpu_addr + (cpu_addr - bo->kvaddr);
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#endif /* __IVPU_GEM_H__ */
128