ivpu_drv.h 5.58 KB
Newer Older
1 2 3 4 5 6 7 8 9
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2020-2023 Intel Corporation
 */

#ifndef __IVPU_DRV_H__
#define __IVPU_DRV_H__

#include <drm/drm_device.h>
10
#include <drm/drm_drv.h>
11 12 13 14 15 16 17 18
#include <drm/drm_managed.h>
#include <drm/drm_mm.h>
#include <drm/drm_print.h>

#include <linux/pci.h>
#include <linux/xarray.h>
#include <uapi/drm/ivpu_accel.h>

19 20
#include "ivpu_mmu_context.h"

21 22 23 24 25
#define DRIVER_NAME "intel_vpu"
#define DRIVER_DESC "Driver for Intel Versatile Processing Unit (VPU)"
#define DRIVER_DATE "20230117"

#define PCI_DEVICE_ID_MTL   0x7d1d
26
#define PCI_DEVICE_ID_LNL   0x643e
27

28
#define IVPU_HW_37XX	37
29
#define IVPU_HW_40XX	40
30

31 32 33 34 35
#define IVPU_GLOBAL_CONTEXT_MMU_SSID   0
/* SSID 1 is used by the VPU to represent reserved context */
#define IVPU_RESERVED_CONTEXT_MMU_SSID 1
#define IVPU_USER_CONTEXT_MIN_SSID     2
#define IVPU_USER_CONTEXT_MAX_SSID     (IVPU_USER_CONTEXT_MIN_SSID + 63)
36

37
#define IVPU_NUM_ENGINES 2
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

#define IVPU_PLATFORM_SILICON 0
#define IVPU_PLATFORM_SIMICS  2
#define IVPU_PLATFORM_FPGA    3
#define IVPU_PLATFORM_INVALID 8

#define IVPU_DBG_REG	 BIT(0)
#define IVPU_DBG_IRQ	 BIT(1)
#define IVPU_DBG_MMU	 BIT(2)
#define IVPU_DBG_FILE	 BIT(3)
#define IVPU_DBG_MISC	 BIT(4)
#define IVPU_DBG_FW_BOOT BIT(5)
#define IVPU_DBG_PM	 BIT(6)
#define IVPU_DBG_IPC	 BIT(7)
#define IVPU_DBG_BO	 BIT(8)
#define IVPU_DBG_JOB	 BIT(9)
#define IVPU_DBG_JSM	 BIT(10)
#define IVPU_DBG_KREF	 BIT(11)
#define IVPU_DBG_RPM	 BIT(12)

#define ivpu_err(vdev, fmt, ...) \
	drm_err(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__)

#define ivpu_err_ratelimited(vdev, fmt, ...) \
	drm_err_ratelimited(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__)

#define ivpu_warn(vdev, fmt, ...) \
	drm_warn(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__)

#define ivpu_warn_ratelimited(vdev, fmt, ...) \
	drm_err_ratelimited(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__)

#define ivpu_info(vdev, fmt, ...) drm_info(&(vdev)->drm, fmt, ##__VA_ARGS__)

#define ivpu_dbg(vdev, type, fmt, args...) do {                                \
	if (unlikely(IVPU_DBG_##type & ivpu_dbg_mask))                         \
		dev_dbg((vdev)->drm.dev, "[%s] " fmt, #type, ##args);          \
} while (0)

#define IVPU_WA(wa_name) (vdev->wa.wa_name)

79 80 81 82 83
#define IVPU_PRINT_WA(wa_name) do {					\
	if (IVPU_WA(wa_name))						\
		ivpu_dbg(vdev, MISC, "Using WA: " #wa_name "\n");	\
} while (0)

84 85 86
struct ivpu_wa_table {
	bool punit_disabled;
	bool clear_runtime_mem;
87
	bool d3hot_after_power_off;
88
	bool interrupt_clear_with_0;
89
	bool disable_clock_relinquish;
90
	bool disable_d0i3_msg;
91 92 93
};

struct ivpu_hw_info;
94
struct ivpu_mmu_info;
95
struct ivpu_fw_info;
96
struct ivpu_ipc_info;
97
struct ivpu_pm_info;
98 99 100 101 102 103 104 105 106 107

struct ivpu_device {
	struct drm_device drm;
	void __iomem *regb;
	void __iomem *regv;
	u32 platform;
	u32 irq;

	struct ivpu_wa_table wa;
	struct ivpu_hw_info *hw;
108
	struct ivpu_mmu_info *mmu;
109
	struct ivpu_fw_info *fw;
110
	struct ivpu_ipc_info *ipc;
111
	struct ivpu_pm_info *pm;
112

113
	struct ivpu_mmu_context gctx;
114
	struct ivpu_mmu_context rctx;
115 116 117
	struct xarray context_xa;
	struct xa_limit context_xa_limit;

118 119 120
	struct xarray submitted_jobs_xa;
	struct task_struct *job_done_thread;

121 122
	atomic64_t unique_id_counter;

123 124 125 126 127
	struct {
		int boot;
		int jsm;
		int tdr;
		int reschedule_suspend;
128
		int autosuspend;
129
		int d0i3_entry_msg;
130 131 132 133 134 135 136 137 138 139
	} timeout;
};

/*
 * file_priv has its own refcount (ref) that allows user space to close the fd
 * without blocking even if VPU is still processing some jobs.
 */
struct ivpu_file_priv {
	struct kref ref;
	struct ivpu_device *vdev;
140 141
	struct mutex lock; /* Protects cmdq */
	struct ivpu_cmdq *cmdq[IVPU_NUM_ENGINES];
142
	struct ivpu_mmu_context ctx;
143
	u32 priority;
144
	bool has_mmu_faults;
145 146 147 148 149
};

extern int ivpu_dbg_mask;
extern u8 ivpu_pll_min_ratio;
extern u8 ivpu_pll_max_ratio;
150
extern bool ivpu_disable_mmu_cont_pages;
151

152 153 154 155 156
#define IVPU_TEST_MODE_FW_TEST            BIT(0)
#define IVPU_TEST_MODE_NULL_HW            BIT(1)
#define IVPU_TEST_MODE_NULL_SUBMISSION    BIT(2)
#define IVPU_TEST_MODE_D0I3_MSG_DISABLE   BIT(4)
#define IVPU_TEST_MODE_D0I3_MSG_ENABLE    BIT(5)
157 158
extern int ivpu_test_mode;

159
struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv);
160
struct ivpu_file_priv *ivpu_file_priv_get_by_ctx_id(struct ivpu_device *vdev, unsigned long id);
161
void ivpu_file_priv_put(struct ivpu_file_priv **link);
162 163

int ivpu_boot(struct ivpu_device *vdev);
164 165 166 167 168 169 170 171 172 173 174 175
int ivpu_shutdown(struct ivpu_device *vdev);

static inline u8 ivpu_revision(struct ivpu_device *vdev)
{
	return to_pci_dev(vdev->drm.dev)->revision;
}

static inline u16 ivpu_device_id(struct ivpu_device *vdev)
{
	return to_pci_dev(vdev->drm.dev)->device;
}

176 177 178 179 180
static inline int ivpu_hw_gen(struct ivpu_device *vdev)
{
	switch (ivpu_device_id(vdev)) {
	case PCI_DEVICE_ID_MTL:
		return IVPU_HW_37XX;
181 182
	case PCI_DEVICE_ID_LNL:
		return IVPU_HW_40XX;
183 184 185 186 187 188
	default:
		ivpu_err(vdev, "Unknown VPU device\n");
		return 0;
	}
}

189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
static inline struct ivpu_device *to_ivpu_device(struct drm_device *dev)
{
	return container_of(dev, struct ivpu_device, drm);
}

static inline u32 ivpu_get_context_count(struct ivpu_device *vdev)
{
	struct xa_limit ctx_limit = vdev->context_xa_limit;

	return (ctx_limit.max - ctx_limit.min + 1);
}

static inline u32 ivpu_get_platform(struct ivpu_device *vdev)
{
	WARN_ON_ONCE(vdev->platform == IVPU_PLATFORM_INVALID);
	return vdev->platform;
}

static inline bool ivpu_is_silicon(struct ivpu_device *vdev)
{
	return ivpu_get_platform(vdev) == IVPU_PLATFORM_SILICON;
}

static inline bool ivpu_is_simics(struct ivpu_device *vdev)
{
	return ivpu_get_platform(vdev) == IVPU_PLATFORM_SIMICS;
}

static inline bool ivpu_is_fpga(struct ivpu_device *vdev)
{
	return ivpu_get_platform(vdev) == IVPU_PLATFORM_FPGA;
}

#endif /* __IVPU_DRV_H__ */