linux/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c

/*
 * Copyright 2008 Jerome Glisse.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *    Jerome Glisse <[email protected]>
 */

#include <linux/file.h>
#include <linux/pagemap.h>
#include <linux/sync_file.h>
#include <linux/dma-buf.h>

#include <drm/amdgpu_drm.h>
#include <drm/drm_syncobj.h>
#include <drm/ttm/ttm_tt.h>

#include "amdgpu_cs.h"
#include "amdgpu.h"
#include "amdgpu_trace.h"
#include "amdgpu_gmc.h"
#include "amdgpu_gem.h"
#include "amdgpu_ras.h"

static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,
				 struct amdgpu_device *adev,
				 struct drm_file *filp,
				 union drm_amdgpu_cs *cs)
{}

static int amdgpu_cs_job_idx(struct amdgpu_cs_parser *p,
			     struct drm_amdgpu_cs_chunk_ib *chunk_ib)
{}

static int amdgpu_cs_p1_ib(struct amdgpu_cs_parser *p,
			   struct drm_amdgpu_cs_chunk_ib *chunk_ib,
			   unsigned int *num_ibs)
{}

static int amdgpu_cs_p1_user_fence(struct amdgpu_cs_parser *p,
				   struct drm_amdgpu_cs_chunk_fence *data,
				   uint32_t *offset)
{}

static int amdgpu_cs_p1_bo_handles(struct amdgpu_cs_parser *p,
				   struct drm_amdgpu_bo_list_in *data)
{}

/* Copy the data from userspace and go over it the first time */
static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
			   union drm_amdgpu_cs *cs)
{}

static int amdgpu_cs_p2_ib(struct amdgpu_cs_parser *p,
			   struct amdgpu_cs_chunk *chunk,
			   unsigned int *ce_preempt,
			   unsigned int *de_preempt)
{}

static int amdgpu_cs_p2_dependencies(struct amdgpu_cs_parser *p,
				     struct amdgpu_cs_chunk *chunk)
{}

static int amdgpu_syncobj_lookup_and_add(struct amdgpu_cs_parser *p,
					 uint32_t handle, u64 point,
					 u64 flags)
{}

static int amdgpu_cs_p2_syncobj_in(struct amdgpu_cs_parser *p,
				   struct amdgpu_cs_chunk *chunk)
{}

static int amdgpu_cs_p2_syncobj_timeline_wait(struct amdgpu_cs_parser *p,
					      struct amdgpu_cs_chunk *chunk)
{}

static int amdgpu_cs_p2_syncobj_out(struct amdgpu_cs_parser *p,
				    struct amdgpu_cs_chunk *chunk)
{}

static int amdgpu_cs_p2_syncobj_timeline_signal(struct amdgpu_cs_parser *p,
						struct amdgpu_cs_chunk *chunk)
{}

static int amdgpu_cs_p2_shadow(struct amdgpu_cs_parser *p,
			       struct amdgpu_cs_chunk *chunk)
{}

static int amdgpu_cs_pass2(struct amdgpu_cs_parser *p)
{}

/* Convert microseconds to bytes. */
static u64 us_to_bytes(struct amdgpu_device *adev, s64 us)
{}

static s64 bytes_to_us(struct amdgpu_device *adev, u64 bytes)
{}

/* Returns how many bytes TTM can move right now. If no bytes can be moved,
 * it returns 0. If it returns non-zero, it's OK to move at least one buffer,
 * which means it can go over the threshold once. If that happens, the driver
 * will be in debt and no other buffer migrations can be done until that debt
 * is repaid.
 *
 * This approach allows moving a buffer of any size (it's important to allow
 * that).
 *
 * The currency is simply time in microseconds and it increases as the clock
 * ticks. The accumulated microseconds (us) are converted to bytes and
 * returned.
 */
static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
					      u64 *max_bytes,
					      u64 *max_vis_bytes)
{}

/* Report how many bytes have really been moved for the last command
 * submission. This can result in a debt that can stop buffer migrations
 * temporarily.
 */
void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
				  u64 num_vis_bytes)
{}

static int amdgpu_cs_bo_validate(void *param, struct amdgpu_bo *bo)
{}

static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
				union drm_amdgpu_cs *cs)
{}

static void trace_amdgpu_cs_ibs(struct amdgpu_cs_parser *p)
{}

static int amdgpu_cs_patch_ibs(struct amdgpu_cs_parser *p,
			       struct amdgpu_job *job)
{}

static int amdgpu_cs_patch_jobs(struct amdgpu_cs_parser *p)
{}

static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
{}

static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
{}

static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
{}

static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
			    union drm_amdgpu_cs *cs)
{}

/* Cleanup the parser structure */
static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser)
{}

int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
{}

/**
 * amdgpu_cs_wait_ioctl - wait for a command submission to finish
 *
 * @dev: drm device
 * @data: data from userspace
 * @filp: file private
 *
 * Wait for the command submission identified by handle to finish.
 */
int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data,
			 struct drm_file *filp)
{}

/**
 * amdgpu_cs_get_fence - helper to get fence from drm_amdgpu_fence
 *
 * @adev: amdgpu device
 * @filp: file private
 * @user: drm_amdgpu_fence copied from user space
 */
static struct dma_fence *amdgpu_cs_get_fence(struct amdgpu_device *adev,
					     struct drm_file *filp,
					     struct drm_amdgpu_fence *user)
{}

int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data,
				    struct drm_file *filp)
{}

/**
 * amdgpu_cs_wait_all_fences - wait on all fences to signal
 *
 * @adev: amdgpu device
 * @filp: file private
 * @wait: wait parameters
 * @fences: array of drm_amdgpu_fence
 */
static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev,
				     struct drm_file *filp,
				     union drm_amdgpu_wait_fences *wait,
				     struct drm_amdgpu_fence *fences)
{}

/**
 * amdgpu_cs_wait_any_fence - wait on any fence to signal
 *
 * @adev: amdgpu device
 * @filp: file private
 * @wait: wait parameters
 * @fences: array of drm_amdgpu_fence
 */
static int amdgpu_cs_wait_any_fence(struct amdgpu_device *adev,
				    struct drm_file *filp,
				    union drm_amdgpu_wait_fences *wait,
				    struct drm_amdgpu_fence *fences)
{}

/**
 * amdgpu_cs_wait_fences_ioctl - wait for multiple command submissions to finish
 *
 * @dev: drm device
 * @data: data from userspace
 * @filp: file private
 */
int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
				struct drm_file *filp)
{}

/**
 * amdgpu_cs_find_mapping - find bo_va for VM address
 *
 * @parser: command submission parser context
 * @addr: VM address
 * @bo: resulting BO of the mapping found
 * @map: Placeholder to return found BO mapping
 *
 * Search the buffer objects in the command submission context for a certain
 * virtual memory address. Returns allocation structure when found, NULL
 * otherwise.
 */
int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
			   uint64_t addr, struct amdgpu_bo **bo,
			   struct amdgpu_bo_va_mapping **map)
{}