tegrakernel/kernel/nvidia/drivers/video/tegra/host/nvdla/nvdla.h

432 lines
12 KiB
C
Raw Permalink Normal View History

2022-02-16 09:13:02 -06:00
/*
* drivers/video/tegra/host/nvdla/nvdla.h
*
* Tegra Graphics Host NVDLA
*
* Copyright (c) 2016-2019 NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __NVHOST_NVDLA_H__
#define __NVHOST_NVDLA_H__
#include <linux/completion.h>
#include <linux/mutex.h>
#include <uapi/linux/nvdev_fence.h>
#include <uapi/linux/nvhost_nvdla_ioctl.h>
#include "nvdla_buffer.h"
#include "dla_os_interface.h"
#include "dla_t19x_fw_version.h"
/*
* macro to encode firmware version
*/
#define FIRMWARE_ENCODE_VERSION(chip) \
(((FIRMWARE_##chip##_VERSION_MAJOR & 0xffU) << 16) | \
((FIRMWARE_##chip##_VERSION_MINOR & 0xffU) << 8) | \
((FIRMWARE_##chip##_VERSION_SUBMINOR & 0xffU)))
#define ALIGNED_DMA(x) ((x >> 8) & 0xffffffff)
/*
* Max grid size
*/
#define MAX_GRID_SIZE SZ_256
/**
* DLA MCIF (Matrix Convolution Image Filter) outstanding AXI transactions
* count register offset
*/
#define NVDLA_MCIF_CFG_OUTSTANDING_CNT_0_OFFSET 0x00005014 /* RW-4R */
/**
* Method ID and Method data THI registers
*/
#define NV_DLA_THI_METHOD_ID 0x00000040 /* RW-4R */
#define NV_DLA_THI_METHOD_DATA 0x00000044 /* RW-4R */
#define NV_DLA_OS_VERSION 0x00001080 /* RW-4R */
#define MAX_NUM_ACTION_LIST 1
/**
* Maximum number of queue's per engine
*/
#define MAX_NVDLA_QUEUE_COUNT 16
/**
* Maximum number of tasks per queue
*/
#define MAX_NVDLA_TASK_COUNT 32
/**
* Maximum number of buffers per pin request
*/
#define MAX_NVDLA_PIN_BUFFERS 32
/**
* Maximum number of buffers per task
*/
#define MAX_NUM_NVDLA_BUFFERS_PER_TASK 6144
/**
* Trace Buffer Size
*/
#define TRACE_BUFFER_SIZE SZ_1M
/**
* Maximum buffer size for debug dump
*/
#define DEBUG_BUFFER_SIZE SZ_256
/**
* Firmware GCOV Buffer Size
*/
#define GCOV_BUFFER_SIZE SZ_64K
/*
* CMD submission timeout in msec
*/
#define CMD_TIMEOUT_MSEC (1000)
/**
* Max number of fences supported
*/
#define MAX_NUM_NVDLA_PREFENCES 32
#define MAX_NUM_NVDLA_POSTFENCES 32
#define MAX_NUM_NVDLA_EMU_PREFENCES 16
#define MAX_NUM_NVDLA_EMU_POSTFENCES 16
#define MAX_NUM_NVDLA_IN_TASK_STATUS MAX_NUM_NVDLA_PREFENCES
#define MAX_NUM_NVDLA_OUT_TASK_STATUS MAX_NUM_NVDLA_POSTFENCES
#define MAX_NUM_NVDLA_OUT_TIMESTAMP 32
#define NUM_PROFILING_POSTACTION 1
#define MAX_COMMANDS_PER_DEVICE 1
/*
* keep max cmd size multiple of 256 bytes.
*/
#define MAX_CMD_SIZE SZ_256
#define NVDLA_CMD_OFFSET(index) (MAX_CMD_SIZE * index)
/*
* Tegra/DLA Hardware version specific Quirks
*/
#define NVDLA_QUIRK_T194_A01_WAR BIT(0)
/**
* data structure to keep command memory
*
* @pa IOVA pointing to cmd memory with offset
* @va VA of cmd memory
* @index index pointing command in pool
*
*/
struct nvdla_cmd_mem_info {
dma_addr_t pa;
void *va;
int index;
};
/**
* data structure to keep command memory pool
*
* @pa IOVA pointing to cmd memory
* @va VA of cmd memory
* @lock mutex lock
* @alloc_table memory usage bitmap table
*/
struct nvdla_cmd_mem {
dma_addr_t pa;
void *va;
struct mutex lock;
unsigned long alloc_table;
};
/**
* data structure to keep command data
*
* @method_id method id with command and other info
* @method_data method data for command
* @wait If set to true then wait for command completion
*/
struct nvdla_cmd_data {
uint32_t method_id;
uint32_t method_data;
bool wait;
};
enum nvdla_submit_mode {
NVDLA_SUBMIT_MODE_MMIO = 0,
NVDLA_SUBMIT_MODE_CHANNEL = 1
};
/**
* data structure to keep per DLA engine device data
*
* @pdev pointer to platform device
* @pool pointer to queue table
* @dbg_mask debug mask for print level
* @en_trace flag to enable kernel tracing
* @submit_mode flag to enable task submit mode, default is
* NVDLA_SUBMIT_MODE_MMIO
* @fw_version saves current firmware version
* @cmd_mem structure to hold command memory pool
* @trace_enable to enable/disable the DLA firmware trace
* @events_mask mask to set/reset the different DLA firmware trace event
* @is_gos_enabled flag to check if GoS enabled
* @debug_dump_pa physical address of print buffer
* @debug_dump_va virtual address of print buffer
* @trace_dump_pa physical address of trace buffer
* @trace_dump_va virtual address of trace buffer
* @en_fw_gcov flag to enable firmware gcov
* @gcov_dump_pa physical address of fw gcov buffer
* @gcov_dump_va virtual address of fw gcovbuffer
* @quirks Tegra/DLA Hardware version specific settings
*/
struct nvdla_device {
struct platform_device *pdev;
struct nvdla_queue_pool *pool;
struct completion cmd_completion;
struct mutex cmd_lock;
int cmd_status;
int waiting;
u32 dbg_mask;
u32 en_trace;
u32 submit_mode;
u32 fw_version;
struct nvdla_cmd_mem cmd_mem;
u32 trace_enable;
u32 events_mask;
bool is_gos_enabled;
bool is_gos_fetched;
dma_addr_t debug_dump_pa;
u32 *debug_dump_va;
dma_addr_t trace_dump_pa;
u32 *trace_dump_va;
u32 en_fw_gcov;
dma_addr_t gcov_dump_pa;
u32 *gcov_dump_va;
u32 quirks;
struct work_struct reset_work;
};
/**
* struct nvdla_emu_task: structure for emulator task info
*
* @queue Queue in which task submitted
* @sp pointer to syncpt
* @prefences pointer to pre fences
* @postfences pointer to post fences
* @num_prefences Number of prefences in task
* @num_postfences Number of postfences in task
* @fence Fence tracking for current task
* @fence_counter Counter used to track fence value
*
*/
struct nvdla_emu_task {
struct nvdla_queue *queue;
struct nvhost_syncpt *sp;
struct nvdev_fence prefences[MAX_NUM_NVDLA_EMU_PREFENCES];
struct nvdev_fence postfences[MAX_NUM_NVDLA_EMU_POSTFENCES];
u32 num_prefences;
u32 num_postfences;
u32 fence;
u32 fence_counter;
};
/**
* struct nvdla_task: structure for task info
*
* @queue Queue in which task submitted
* @buffers nvhost buffers for priv/task
* @sp pointer to syncpt
* @prefences pointer to prefences
* @postfences pointer to post fences
* @fence fence tracking for current task
* @ref Reference count for task
* @list List entry
* @task_desc DLA task desc VA
* @task_desc_pa DLA task desc PA
* @buf_size Total size of task dma alloc
* @timeout max timeout to wait for task completion
* @op_handle pointer to handle list of operation descriptor
*
*/
struct nvdla_task {
struct nvdla_queue *queue;
struct nvdla_buffers *buffers;
struct nvhost_syncpt *sp;
struct nvdev_fence prefences[MAX_NUM_NVDLA_PREFENCES];
struct nvdev_fence postfences[MAX_NUM_NVDLA_POSTFENCES];
struct nvdla_status_notify in_task_status[MAX_NUM_NVDLA_IN_TASK_STATUS];
struct nvdla_status_notify sof_task_status[MAX_NUM_NVDLA_OUT_TASK_STATUS];
struct nvdla_status_notify eof_task_status[MAX_NUM_NVDLA_OUT_TASK_STATUS];
struct nvdla_mem_handle sof_timestamps[MAX_NUM_NVDLA_OUT_TIMESTAMP];
struct nvdla_mem_handle eof_timestamps[MAX_NUM_NVDLA_OUT_TIMESTAMP];
struct nvdla_mem_handle memory_handles[NVDLA_MAX_BUFFERS_PER_TASK];
u8 num_prefences;
u8 num_postfences;
u8 num_in_task_status;
u8 num_sof_task_status;
u8 num_eof_task_status;
u8 num_sof_timestamps;
u8 num_eof_timestamps;
u32 num_addresses;
u32 fence;
u32 fence_counter;
struct kref ref;
struct list_head list;
struct dla_task_descriptor *task_desc;
dma_addr_t task_desc_pa;
size_t buf_size;
int timeout;
int pool_index;
struct dma_buf *memory_dmabuf[NVDLA_MAX_BUFFERS_PER_TASK];
struct dma_buf *prefences_sem_dmabuf[MAX_NUM_NVDLA_PREFENCES];
struct dma_buf *in_task_status_dmabuf[MAX_NUM_NVDLA_IN_TASK_STATUS];
struct dma_buf *postfences_sem_dmabuf[MAX_NUM_NVDLA_POSTFENCES];
struct dma_buf *sof_task_status_dmabuf[MAX_NUM_NVDLA_OUT_TASK_STATUS];
struct dma_buf *eof_task_status_dmabuf[MAX_NUM_NVDLA_OUT_TASK_STATUS];
struct dma_buf *sof_timestamps_dmabuf[MAX_NUM_NVDLA_OUT_TIMESTAMP];
struct dma_buf *eof_timestamps_dmabuf[MAX_NUM_NVDLA_OUT_TIMESTAMP];
};
struct dla_mem_addr {
uint64_t val;
};
extern const struct file_operations tegra_nvdla_ctrl_ops;
extern struct nvdla_queue_ops nvdla_queue_ops;
/**
* nvhost_nvdla_finalize_poweron() finalize power on for DLA
*
* @pdev Pointer for platform device
*
* Return 0 on success otherwise negative
*
* This function called from nvhost ACM subsystem,
* to boot falcon and wait until falcon goes idle after initial setup
*/
int nvhost_nvdla_finalize_poweron(struct platform_device *pdev);
/**
* nvhost_nvdla_prepare_poweron() prepare to poweroff DLA
*
* @pdev Pointer for platform device
*
* Return 0 on success otherwise negative
*
* This function called from nvhost ACM subsystem,
* disables falcon interrupts and pass PM core to powergate and clockgate
*/
int nvhost_nvdla_prepare_poweroff(struct platform_device *pdev);
/**
* nvhost_nvdla_flcn_isr() falcon interrupt handler
*
* @pdev Pointer for platform device
*
* Return 0 on success otherwise negative
*
* This function called from nvhost falcon subsystem on recieving falcon
* interrupt, like INT_ON_COMPLETE, INT_ON_ERR, DLA_DEBUG etc.
*/
int nvhost_nvdla_flcn_isr(struct platform_device *pdev);
/**
* nvdla_send_cmd() send command to DLA
*
* @pdev Pointer for platform device
* @cmd_data Pointer command data
*
* Return 0 on success otherwise negative
*
* This function used to send method to falcon embedding different supporting
* command. This uses THI registers to send method id and method data
*/
int nvdla_send_cmd(struct platform_device *pdev,
struct nvdla_cmd_data *cmd_data);
/**
* nvdla_task_put() decrease task reference count
*
* @task Pointer to task in operation
*
* Return void
*
* This function puts task reference count and zero reference count
* invokes function to free task.
*/
void nvdla_task_put(struct nvdla_task *task);
/**
* nvdla_task_get() increase task reference count
*
* @task Pointer to task in operation
*
* Return void
*
* This function gets task reference count
*/
void nvdla_task_get(struct nvdla_task *task);
/**
* nvdla_task_alloc() allocate task for a give queue
*
* @task Pointer to nvdla_task
*
* Return allocated task in success, otherwise pointer to err
*
* This function allocates task desc and fills up initial task descriptor as
* task parameter detais
*/
int nvdla_fill_task_desc(struct nvdla_task *task);
/**
* nvdla_send_postfences() send back fences to UMD
*
* @task Pointer to nvhost queue
* @usr_task Pointer to user task to be updated
*
* Return 0 on success otherwise negative
*
* This function send post fences back to UMD after task submit
*/
int nvdla_send_postfences(struct nvdla_task *task,
struct nvdla_ioctl_submit_task *usr_task);
int nvdla_get_cmd_memory(struct platform_device *pdev,
struct nvdla_cmd_mem_info *cmd_mem_info);
int nvdla_put_cmd_memory(struct platform_device *pdev, int index);
int nvdla_set_queue_state(struct nvdla_queue *queue, int cmd);
int nvdla_get_task_mem(struct nvdla_queue *queue,
struct nvdla_task **task);
void nvdla_put_task_mem(struct nvdla_task *task);
size_t nvdla_get_max_task_size(void);
int nvdla_alloc_gcov_region(struct platform_device *pdev);
int nvdla_free_gcov_region(struct platform_device *pdev, bool update_region);
int nvdla_emulator_submit(struct nvdla_queue *queue,
struct nvdla_emu_task *task);
void task_free(struct kref *ref);
int nvdla_get_signal_fences(struct nvdla_queue *queue, void *in_task);
int nvdla_send_gos_region(struct platform_device *pdev);
#endif /* End of __NVHOST_NVDLA_H__ */