256 lines
5.7 KiB
C
256 lines
5.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2020 MediaTek Inc.
|
|
*/
|
|
|
|
#ifndef __VPU_CMN_H__
|
|
#define __VPU_CMN_H__
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/cdev.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/wait.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/scatterlist.h>
|
|
#include <linux/workqueue.h>
|
|
|
|
#include "apusys_device.h"
|
|
#include "vpu_cfg.h"
|
|
#include "vpu_cmd.h"
|
|
#include "vpu_mem.h"
|
|
#include "vpu_met.h"
|
|
#include "vpu_dump.h"
|
|
#include "vpu_algo.h"
|
|
#include "vpu_ioctl.h"
|
|
#include "apu_tags.h"
|
|
|
|
#include <aee.h>
|
|
|
|
#ifdef CONFIG_MTK_AEE_FEATURE
|
|
/**
|
|
* vpu_aee_excp_locked() - VPU exception handler
|
|
*
|
|
* @vd: vpu device
|
|
* @req: vpu reqeuest that caused exception, can be NULL (optional)
|
|
* @key: dispatch keyword passed to AEE db
|
|
* @format: exception message format string
|
|
* @args: exception message arguments
|
|
*
|
|
* Note: device lock (vd->lock) must be acquired when calling
|
|
* vpu_aee_excp_locked()
|
|
*/
|
|
#define vpu_aee_excp_locked(vd, req, key, format, args...) \
|
|
do { \
|
|
if (vd->state <= VS_DOWN) { \
|
|
pr_info(format ", crashed by other thread", ##args); \
|
|
break; \
|
|
} \
|
|
pr_info(format, ##args); \
|
|
vpu_dmp_create_locked(vd, req, format, ##args); \
|
|
aee_kernel_exception("VPU", \
|
|
"\nCRDISPATCH_KEY:" key "\n" format, ##args); \
|
|
vpu_pwr_down_locked(vd); \
|
|
vpu_cmd_wake_all(vd); \
|
|
} while (0)
|
|
|
|
#define vpu_aee_excp(vd, req, key, format, args...) \
|
|
do { \
|
|
mutex_lock_nested(&vd->lock, VPU_MUTEX_DEV); \
|
|
vpu_aee_excp_locked(vd, req, key, format, ##args); \
|
|
mutex_unlock(&vd->lock); \
|
|
} while (0)
|
|
|
|
#define vpu_aee_warn(key, format, args...) \
|
|
do { \
|
|
pr_info(format, ##args); \
|
|
aee_kernel_warning("VPU", \
|
|
"\nCRDISPATCH_KEY:" key "\n" format, ##args); \
|
|
} while (0)
|
|
#else
|
|
#define vpu_aee_excp_locked(vd, req, key, format, args...)
|
|
#define vpu_aee_excp(vd, req, key, format, args...)
|
|
#define vpu_aee_warn(key, format, args...)
|
|
#endif
|
|
|
|
/*
|
|
* mutex lock order
|
|
* 1. driver lock (vpu_drv->lock)
|
|
* - protects driver's data (vpu_drv)
|
|
* 2. command lock (vd->cmd[i].lock)
|
|
* - protects device's command execution of priority "i"
|
|
* 3. device lock (vd->lock)
|
|
* - protects device's power control, and boot sequence
|
|
**/
|
|
|
|
enum vpu_mutex_class {
|
|
VPU_MUTEX_DRV = 0,
|
|
VPU_MUTEX_CMD = 1,
|
|
VPU_MUTEX_DEV = (VPU_MAX_PRIORITY + VPU_MUTEX_CMD),
|
|
};
|
|
|
|
struct vpu_met_hrt {
|
|
spinlock_t lock;
|
|
struct hrtimer t;
|
|
struct kref ref;
|
|
uint64_t latency;
|
|
};
|
|
|
|
// driver data
|
|
struct vpu_driver {
|
|
void *bin_va;
|
|
unsigned long bin_pa;
|
|
unsigned int bin_size;
|
|
unsigned int bin_head_ofs;
|
|
unsigned int bin_preload_ofs;
|
|
|
|
/* power work queue */
|
|
struct workqueue_struct *wq;
|
|
|
|
/* iova settings */
|
|
struct kref iova_ref;
|
|
struct device *iova_dev;
|
|
struct vpu_iova iova_algo;
|
|
struct vpu_iova iova_share;
|
|
|
|
/* shared */
|
|
uint64_t mva_algo;
|
|
|
|
/* list of devices */
|
|
struct list_head devs;
|
|
struct mutex lock;
|
|
|
|
/* debugfs entry */
|
|
struct dentry *droot;
|
|
|
|
/* procfs entry */
|
|
struct proc_dir_entry *proc_root;
|
|
|
|
/* device references */
|
|
struct kref ref;
|
|
|
|
/* met */
|
|
uint32_t ilog;
|
|
uint32_t met;
|
|
struct vpu_met_hrt met_hrt;
|
|
|
|
/* tags */
|
|
struct apu_tags *tags;
|
|
};
|
|
|
|
enum vpu_state {
|
|
VS_UNKNOWN = 0,
|
|
VS_DISALBED, // disabled by e-fuse
|
|
VS_DOWN, // power down
|
|
VS_UP, // power up
|
|
VS_BOOT, // booting
|
|
VS_IDLE, // power on, idle
|
|
VS_CMD_ALG,
|
|
VS_CMD_D2D,
|
|
VS_CMD_D2D_EXT,
|
|
VS_REMOVING,
|
|
VS_TOTAL
|
|
};
|
|
|
|
struct vpu_iomem {
|
|
void __iomem *m;
|
|
struct resource *res;
|
|
};
|
|
|
|
// device data
|
|
struct vpu_device {
|
|
int id;
|
|
char name[8];
|
|
struct list_head list; // link in vpu driver
|
|
enum vpu_state state;
|
|
struct mutex lock;
|
|
struct apusys_device adev;
|
|
struct apusys_device adev_rt;
|
|
struct device *dev; // platform device
|
|
struct rproc *rproc;
|
|
|
|
/* xos */
|
|
atomic_t xos_state;
|
|
|
|
/* iomem */
|
|
spinlock_t reg_lock;
|
|
struct vpu_iomem reg;
|
|
struct vpu_iomem dmem;
|
|
struct vpu_iomem imem;
|
|
struct vpu_iomem dbg;
|
|
|
|
/* power */
|
|
struct kref pw_ref;
|
|
struct delayed_work pw_off_work;
|
|
wait_queue_head_t pw_wait;
|
|
uint64_t pw_off_latency; /* ms, 0 = always on */
|
|
atomic_t pw_boost; /* current boost */
|
|
#ifdef CONFIG_PM_SLEEP
|
|
//struct wakeup_source pw_wake_lock;
|
|
struct wakeup_source *pw_wake_lock;
|
|
#endif
|
|
|
|
/* iova settings */
|
|
struct vpu_iova iova_reset;
|
|
struct vpu_iova iova_main;
|
|
struct vpu_iova iova_kernel;
|
|
struct vpu_iova iova_iram;
|
|
struct vpu_iova iova_work;
|
|
|
|
/* work buffer */
|
|
uint32_t wb_log_size;
|
|
uint32_t wb_log_data;
|
|
|
|
/* algorithm */
|
|
struct vpu_algo_list aln; /* normal */
|
|
struct vpu_algo_list alp; /* preload */
|
|
|
|
/* irq */
|
|
unsigned int irq_num;
|
|
|
|
/* command */
|
|
atomic_t cmd_prio; /* current running command's priority */
|
|
int cmd_prio_max; /* eq. VPU_MAX_PRIORITY */
|
|
struct vpu_cmd_ctl cmd[VPU_MAX_PRIORITY];
|
|
atomic_t cmd_active; /* number of active command controls */
|
|
uint32_t dev_state; /* last known device state */
|
|
uint64_t cmd_timeout; /* ms */
|
|
|
|
/* memory */
|
|
uint64_t mva_iram;
|
|
|
|
/* debug */
|
|
struct dentry *droot; /* debugfs entry */
|
|
struct proc_dir_entry *proc_root; /* procfs entry */
|
|
bool ftrace_avail; /* trace */
|
|
bool jtag_enabled; /* jtag */
|
|
struct vpu_dmp *dmp; /* dump */
|
|
|
|
/* MET */
|
|
struct vpu_met_work met;
|
|
struct vpu_met_pm pm;
|
|
};
|
|
|
|
|
|
extern struct vpu_driver *vpu_drv;
|
|
|
|
int vpu_init_dev_hw(struct platform_device *pdev, struct vpu_device *vd);
|
|
int vpu_init_drv_hw(void);
|
|
|
|
int vpu_exit_dev_hw(struct platform_device *pdev, struct vpu_device *vd);
|
|
int vpu_exit_drv_hw(void);
|
|
|
|
int vpu_alloc_request(struct vpu_request **rreq);
|
|
int vpu_free_request(struct vpu_request *req);
|
|
|
|
int vpu_alloc_algo(struct __vpu_algo **ralgo);
|
|
int vpu_free_algo(struct __vpu_algo *algo);
|
|
|
|
int vpu_execute(struct vpu_device *vd, struct vpu_request *req);
|
|
int vpu_preempt(struct vpu_device *vd, struct vpu_request *req);
|
|
|
|
int vpu_kbuf_alloc(struct vpu_device *vd);
|
|
int vpu_kbuf_free(struct vpu_device *vd);
|
|
#endif
|
|
|