162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright 2008 Advanced Micro Devices, Inc.
362306a36Sopenharmony_ci * Copyright 2008 Red Hat Inc.
462306a36Sopenharmony_ci * Copyright 2009 Jerome Glisse.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
762306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
862306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation
962306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1062306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
1162306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
1462306a36Sopenharmony_ci * all copies or substantial portions of the Software.
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1762306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1862306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1962306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2062306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2162306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2262306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * Authors: Dave Airlie
2562306a36Sopenharmony_ci *          Alex Deucher
2662306a36Sopenharmony_ci *          Jerome Glisse
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_ci#ifndef __RADEON_OBJECT_H__
2962306a36Sopenharmony_ci#define __RADEON_OBJECT_H__
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#include <drm/radeon_drm.h>
3262306a36Sopenharmony_ci#include "radeon.h"
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/**
3562306a36Sopenharmony_ci * radeon_mem_type_to_domain - return domain corresponding to mem_type
3662306a36Sopenharmony_ci * @mem_type:	ttm memory type
3762306a36Sopenharmony_ci *
3862306a36Sopenharmony_ci * Returns corresponding domain of the ttm mem_type
3962306a36Sopenharmony_ci */
4062306a36Sopenharmony_cistatic inline unsigned radeon_mem_type_to_domain(u32 mem_type)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	switch (mem_type) {
4362306a36Sopenharmony_ci	case TTM_PL_VRAM:
4462306a36Sopenharmony_ci		return RADEON_GEM_DOMAIN_VRAM;
4562306a36Sopenharmony_ci	case TTM_PL_TT:
4662306a36Sopenharmony_ci		return RADEON_GEM_DOMAIN_GTT;
4762306a36Sopenharmony_ci	case TTM_PL_SYSTEM:
4862306a36Sopenharmony_ci		return RADEON_GEM_DOMAIN_CPU;
4962306a36Sopenharmony_ci	default:
5062306a36Sopenharmony_ci		break;
5162306a36Sopenharmony_ci	}
5262306a36Sopenharmony_ci	return 0;
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/**
5662306a36Sopenharmony_ci * radeon_bo_reserve - reserve bo
5762306a36Sopenharmony_ci * @bo:		bo structure
5862306a36Sopenharmony_ci * @no_intr:	don't return -ERESTARTSYS on pending signal
5962306a36Sopenharmony_ci *
6062306a36Sopenharmony_ci * Returns:
6162306a36Sopenharmony_ci * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
6262306a36Sopenharmony_ci * a signal. Release all buffer reservations and return to user-space.
6362306a36Sopenharmony_ci */
6462306a36Sopenharmony_cistatic inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_intr)
6562306a36Sopenharmony_ci{
6662306a36Sopenharmony_ci	int r;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	r = ttm_bo_reserve(&bo->tbo, !no_intr, false, NULL);
6962306a36Sopenharmony_ci	if (unlikely(r != 0)) {
7062306a36Sopenharmony_ci		if (r != -ERESTARTSYS)
7162306a36Sopenharmony_ci			dev_err(bo->rdev->dev, "%p reserve failed\n", bo);
7262306a36Sopenharmony_ci		return r;
7362306a36Sopenharmony_ci	}
7462306a36Sopenharmony_ci	return 0;
7562306a36Sopenharmony_ci}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistatic inline void radeon_bo_unreserve(struct radeon_bo *bo)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci	ttm_bo_unreserve(&bo->tbo);
8062306a36Sopenharmony_ci}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci/**
8362306a36Sopenharmony_ci * radeon_bo_gpu_offset - return GPU offset of bo
8462306a36Sopenharmony_ci * @bo:	radeon object for which we query the offset
8562306a36Sopenharmony_ci *
8662306a36Sopenharmony_ci * Returns current GPU offset of the object.
8762306a36Sopenharmony_ci *
8862306a36Sopenharmony_ci * Note: object should either be pinned or reserved when calling this
8962306a36Sopenharmony_ci * function, it might be useful to add check for this for debugging.
9062306a36Sopenharmony_ci */
9162306a36Sopenharmony_cistatic inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo)
9262306a36Sopenharmony_ci{
9362306a36Sopenharmony_ci	struct radeon_device *rdev;
9462306a36Sopenharmony_ci	u64 start = 0;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	rdev = radeon_get_rdev(bo->tbo.bdev);
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	switch (bo->tbo.resource->mem_type) {
9962306a36Sopenharmony_ci	case TTM_PL_TT:
10062306a36Sopenharmony_ci		start = rdev->mc.gtt_start;
10162306a36Sopenharmony_ci		break;
10262306a36Sopenharmony_ci	case TTM_PL_VRAM:
10362306a36Sopenharmony_ci		start = rdev->mc.vram_start;
10462306a36Sopenharmony_ci		break;
10562306a36Sopenharmony_ci	}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	return (bo->tbo.resource->start << PAGE_SHIFT) + start;
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cistatic inline unsigned long radeon_bo_size(struct radeon_bo *bo)
11162306a36Sopenharmony_ci{
11262306a36Sopenharmony_ci	return bo->tbo.base.size;
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistatic inline unsigned radeon_bo_ngpu_pages(struct radeon_bo *bo)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	return bo->tbo.base.size / RADEON_GPU_PAGE_SIZE;
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cistatic inline unsigned radeon_bo_gpu_page_alignment(struct radeon_bo *bo)
12162306a36Sopenharmony_ci{
12262306a36Sopenharmony_ci	return (bo->tbo.page_alignment << PAGE_SHIFT) / RADEON_GPU_PAGE_SIZE;
12362306a36Sopenharmony_ci}
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci/**
12662306a36Sopenharmony_ci * radeon_bo_mmap_offset - return mmap offset of bo
12762306a36Sopenharmony_ci * @bo:	radeon object for which we query the offset
12862306a36Sopenharmony_ci *
12962306a36Sopenharmony_ci * Returns mmap offset of the object.
13062306a36Sopenharmony_ci */
13162306a36Sopenharmony_cistatic inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo)
13262306a36Sopenharmony_ci{
13362306a36Sopenharmony_ci	return drm_vma_node_offset_addr(&bo->tbo.base.vma_node);
13462306a36Sopenharmony_ci}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ciextern int radeon_bo_create(struct radeon_device *rdev,
13762306a36Sopenharmony_ci			    unsigned long size, int byte_align,
13862306a36Sopenharmony_ci			    bool kernel, u32 domain, u32 flags,
13962306a36Sopenharmony_ci			    struct sg_table *sg,
14062306a36Sopenharmony_ci			    struct dma_resv *resv,
14162306a36Sopenharmony_ci			    struct radeon_bo **bo_ptr);
14262306a36Sopenharmony_ciextern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
14362306a36Sopenharmony_ciextern void radeon_bo_kunmap(struct radeon_bo *bo);
14462306a36Sopenharmony_ciextern struct radeon_bo *radeon_bo_ref(struct radeon_bo *bo);
14562306a36Sopenharmony_ciextern void radeon_bo_unref(struct radeon_bo **bo);
14662306a36Sopenharmony_ciextern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr);
14762306a36Sopenharmony_ciextern int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain,
14862306a36Sopenharmony_ci				    u64 max_offset, u64 *gpu_addr);
14962306a36Sopenharmony_ciextern void radeon_bo_unpin(struct radeon_bo *bo);
15062306a36Sopenharmony_ciextern int radeon_bo_evict_vram(struct radeon_device *rdev);
15162306a36Sopenharmony_ciextern void radeon_bo_force_delete(struct radeon_device *rdev);
15262306a36Sopenharmony_ciextern int radeon_bo_init(struct radeon_device *rdev);
15362306a36Sopenharmony_ciextern void radeon_bo_fini(struct radeon_device *rdev);
15462306a36Sopenharmony_ciextern int radeon_bo_list_validate(struct radeon_device *rdev,
15562306a36Sopenharmony_ci				   struct ww_acquire_ctx *ticket,
15662306a36Sopenharmony_ci				   struct list_head *head, int ring);
15762306a36Sopenharmony_ciextern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
15862306a36Sopenharmony_ci				u32 tiling_flags, u32 pitch);
15962306a36Sopenharmony_ciextern void radeon_bo_get_tiling_flags(struct radeon_bo *bo,
16062306a36Sopenharmony_ci				u32 *tiling_flags, u32 *pitch);
16162306a36Sopenharmony_ciextern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
16262306a36Sopenharmony_ci				bool force_drop);
16362306a36Sopenharmony_ciextern void radeon_bo_move_notify(struct ttm_buffer_object *bo);
16462306a36Sopenharmony_ciextern vm_fault_t radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
16562306a36Sopenharmony_ciextern int radeon_bo_get_surface_reg(struct radeon_bo *bo);
16662306a36Sopenharmony_ciextern void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence,
16762306a36Sopenharmony_ci			    bool shared);
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/*
17062306a36Sopenharmony_ci * sub allocation
17162306a36Sopenharmony_ci */
17262306a36Sopenharmony_cistatic inline struct radeon_sa_manager *
17362306a36Sopenharmony_cito_radeon_sa_manager(struct drm_suballoc_manager *manager)
17462306a36Sopenharmony_ci{
17562306a36Sopenharmony_ci	return container_of(manager, struct radeon_sa_manager, base);
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cistatic inline uint64_t radeon_sa_bo_gpu_addr(struct drm_suballoc *sa_bo)
17962306a36Sopenharmony_ci{
18062306a36Sopenharmony_ci	return to_radeon_sa_manager(sa_bo->manager)->gpu_addr +
18162306a36Sopenharmony_ci		drm_suballoc_soffset(sa_bo);
18262306a36Sopenharmony_ci}
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_cistatic inline void *radeon_sa_bo_cpu_addr(struct drm_suballoc *sa_bo)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	return to_radeon_sa_manager(sa_bo->manager)->cpu_ptr +
18762306a36Sopenharmony_ci		drm_suballoc_soffset(sa_bo);
18862306a36Sopenharmony_ci}
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciextern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
19162306a36Sopenharmony_ci				     struct radeon_sa_manager *sa_manager,
19262306a36Sopenharmony_ci				     unsigned size, u32 align, u32 domain,
19362306a36Sopenharmony_ci				     u32 flags);
19462306a36Sopenharmony_ciextern void radeon_sa_bo_manager_fini(struct radeon_device *rdev,
19562306a36Sopenharmony_ci				      struct radeon_sa_manager *sa_manager);
19662306a36Sopenharmony_ciextern int radeon_sa_bo_manager_start(struct radeon_device *rdev,
19762306a36Sopenharmony_ci				      struct radeon_sa_manager *sa_manager);
19862306a36Sopenharmony_ciextern int radeon_sa_bo_manager_suspend(struct radeon_device *rdev,
19962306a36Sopenharmony_ci					struct radeon_sa_manager *sa_manager);
20062306a36Sopenharmony_ciextern int radeon_sa_bo_new(struct radeon_sa_manager *sa_manager,
20162306a36Sopenharmony_ci			    struct drm_suballoc **sa_bo,
20262306a36Sopenharmony_ci			    unsigned int size, unsigned int align);
20362306a36Sopenharmony_ciextern void radeon_sa_bo_free(struct drm_suballoc **sa_bo,
20462306a36Sopenharmony_ci			      struct radeon_fence *fence);
20562306a36Sopenharmony_ci#if defined(CONFIG_DEBUG_FS)
20662306a36Sopenharmony_ciextern void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
20762306a36Sopenharmony_ci					 struct seq_file *m);
20862306a36Sopenharmony_ci#endif
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci#endif
212