1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright (C) 2020-2024 Intel Corporation |
4 | */ |
5 | |
6 | #ifndef __IVPU_DRV_H__ |
7 | #define __IVPU_DRV_H__ |
8 | |
9 | #include <drm/drm_device.h> |
10 | #include <drm/drm_drv.h> |
11 | #include <drm/drm_managed.h> |
12 | #include <drm/drm_mm.h> |
13 | #include <drm/drm_print.h> |
14 | |
15 | #include <linux/pci.h> |
16 | #include <linux/xarray.h> |
17 | #include <uapi/drm/ivpu_accel.h> |
18 | |
19 | #include "ivpu_mmu_context.h" |
20 | #include "ivpu_ipc.h" |
21 | |
22 | #define DRIVER_NAME "intel_vpu" |
23 | #define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)" |
24 | #define DRIVER_DATE "20230117" |
25 | |
26 | #define PCI_DEVICE_ID_MTL 0x7d1d |
27 | #define PCI_DEVICE_ID_ARL 0xad1d |
28 | #define PCI_DEVICE_ID_LNL 0x643e |
29 | |
30 | #define IVPU_HW_37XX 37 |
31 | #define IVPU_HW_40XX 40 |
32 | |
33 | #define IVPU_GLOBAL_CONTEXT_MMU_SSID 0 |
34 | /* SSID 1 is used by the VPU to represent reserved context */ |
35 | #define IVPU_RESERVED_CONTEXT_MMU_SSID 1 |
36 | #define IVPU_USER_CONTEXT_MIN_SSID 2 |
37 | #define IVPU_USER_CONTEXT_MAX_SSID (IVPU_USER_CONTEXT_MIN_SSID + 63) |
38 | |
39 | #define IVPU_MIN_DB 1 |
40 | #define IVPU_MAX_DB 255 |
41 | |
42 | #define IVPU_NUM_ENGINES 2 |
43 | |
44 | #define IVPU_PLATFORM_SILICON 0 |
45 | #define IVPU_PLATFORM_SIMICS 2 |
46 | #define IVPU_PLATFORM_FPGA 3 |
47 | #define IVPU_PLATFORM_INVALID 8 |
48 | |
49 | #define IVPU_DBG_REG BIT(0) |
50 | #define IVPU_DBG_IRQ BIT(1) |
51 | #define IVPU_DBG_MMU BIT(2) |
52 | #define IVPU_DBG_FILE BIT(3) |
53 | #define IVPU_DBG_MISC BIT(4) |
54 | #define IVPU_DBG_FW_BOOT BIT(5) |
55 | #define IVPU_DBG_PM BIT(6) |
56 | #define IVPU_DBG_IPC BIT(7) |
57 | #define IVPU_DBG_BO BIT(8) |
58 | #define IVPU_DBG_JOB BIT(9) |
59 | #define IVPU_DBG_JSM BIT(10) |
60 | #define IVPU_DBG_KREF BIT(11) |
61 | #define IVPU_DBG_RPM BIT(12) |
62 | #define IVPU_DBG_MMU_MAP BIT(13) |
63 | |
64 | #define ivpu_err(vdev, fmt, ...) \ |
65 | drm_err(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) |
66 | |
67 | #define ivpu_err_ratelimited(vdev, fmt, ...) \ |
68 | drm_err_ratelimited(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) |
69 | |
70 | #define ivpu_warn(vdev, fmt, ...) \ |
71 | drm_warn(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) |
72 | |
73 | #define ivpu_warn_ratelimited(vdev, fmt, ...) \ |
74 | drm_err_ratelimited(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) |
75 | |
76 | #define ivpu_info(vdev, fmt, ...) drm_info(&(vdev)->drm, fmt, ##__VA_ARGS__) |
77 | |
78 | #define ivpu_dbg(vdev, type, fmt, args...) do { \ |
79 | if (unlikely(IVPU_DBG_##type & ivpu_dbg_mask)) \ |
80 | dev_dbg((vdev)->drm.dev, "[%s] " fmt, #type, ##args); \ |
81 | } while (0) |
82 | |
83 | #define IVPU_WA(wa_name) (vdev->wa.wa_name) |
84 | |
85 | #define IVPU_PRINT_WA(wa_name) do { \ |
86 | if (IVPU_WA(wa_name)) \ |
87 | ivpu_dbg(vdev, MISC, "Using WA: " #wa_name "\n"); \ |
88 | } while (0) |
89 | |
90 | struct ivpu_wa_table { |
91 | bool punit_disabled; |
92 | bool clear_runtime_mem; |
93 | bool interrupt_clear_with_0; |
94 | bool disable_clock_relinquish; |
95 | bool disable_d0i3_msg; |
96 | }; |
97 | |
98 | struct ivpu_hw_info; |
99 | struct ivpu_mmu_info; |
100 | struct ivpu_fw_info; |
101 | struct ivpu_ipc_info; |
102 | struct ivpu_pm_info; |
103 | |
104 | struct ivpu_device { |
105 | struct drm_device drm; |
106 | void __iomem *regb; |
107 | void __iomem *regv; |
108 | u32 platform; |
109 | u32 irq; |
110 | |
111 | struct ivpu_wa_table wa; |
112 | struct ivpu_hw_info *hw; |
113 | struct ivpu_mmu_info *mmu; |
114 | struct ivpu_fw_info *fw; |
115 | struct ivpu_ipc_info *ipc; |
116 | struct ivpu_pm_info *pm; |
117 | |
118 | struct ivpu_mmu_context gctx; |
119 | struct ivpu_mmu_context rctx; |
120 | struct mutex context_list_lock; /* Protects user context addition/removal */ |
121 | struct xarray context_xa; |
122 | struct xa_limit context_xa_limit; |
123 | |
124 | struct xarray db_xa; |
125 | |
126 | struct mutex bo_list_lock; /* Protects bo_list */ |
127 | struct list_head bo_list; |
128 | |
129 | struct xarray submitted_jobs_xa; |
130 | struct ivpu_ipc_consumer job_done_consumer; |
131 | |
132 | atomic64_t unique_id_counter; |
133 | |
134 | struct { |
135 | int boot; |
136 | int jsm; |
137 | int tdr; |
138 | int reschedule_suspend; |
139 | int autosuspend; |
140 | int d0i3_entry_msg; |
141 | } timeout; |
142 | }; |
143 | |
144 | /* |
145 | * file_priv has its own refcount (ref) that allows user space to close the fd |
146 | * without blocking even if VPU is still processing some jobs. |
147 | */ |
148 | struct ivpu_file_priv { |
149 | struct kref ref; |
150 | struct ivpu_device *vdev; |
151 | struct mutex lock; /* Protects cmdq */ |
152 | struct ivpu_cmdq *cmdq[IVPU_NUM_ENGINES]; |
153 | struct ivpu_mmu_context ctx; |
154 | bool has_mmu_faults; |
155 | bool bound; |
156 | }; |
157 | |
158 | extern int ivpu_dbg_mask; |
159 | extern u8 ivpu_pll_min_ratio; |
160 | extern u8 ivpu_pll_max_ratio; |
161 | extern bool ivpu_disable_mmu_cont_pages; |
162 | |
163 | #define IVPU_TEST_MODE_FW_TEST BIT(0) |
164 | #define IVPU_TEST_MODE_NULL_HW BIT(1) |
165 | #define IVPU_TEST_MODE_NULL_SUBMISSION BIT(2) |
166 | #define IVPU_TEST_MODE_D0I3_MSG_DISABLE BIT(4) |
167 | #define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5) |
168 | extern int ivpu_test_mode; |
169 | |
170 | struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv); |
171 | void ivpu_file_priv_put(struct ivpu_file_priv **link); |
172 | |
173 | int ivpu_boot(struct ivpu_device *vdev); |
174 | int ivpu_shutdown(struct ivpu_device *vdev); |
175 | void ivpu_prepare_for_reset(struct ivpu_device *vdev); |
176 | |
177 | static inline u8 ivpu_revision(struct ivpu_device *vdev) |
178 | { |
179 | return to_pci_dev(vdev->drm.dev)->revision; |
180 | } |
181 | |
182 | static inline u16 ivpu_device_id(struct ivpu_device *vdev) |
183 | { |
184 | return to_pci_dev(vdev->drm.dev)->device; |
185 | } |
186 | |
187 | static inline int ivpu_hw_gen(struct ivpu_device *vdev) |
188 | { |
189 | switch (ivpu_device_id(vdev)) { |
190 | case PCI_DEVICE_ID_MTL: |
191 | case PCI_DEVICE_ID_ARL: |
192 | return IVPU_HW_37XX; |
193 | case PCI_DEVICE_ID_LNL: |
194 | return IVPU_HW_40XX; |
195 | default: |
196 | ivpu_err(vdev, "Unknown NPU device\n" ); |
197 | return 0; |
198 | } |
199 | } |
200 | |
201 | static inline struct ivpu_device *to_ivpu_device(struct drm_device *dev) |
202 | { |
203 | return container_of(dev, struct ivpu_device, drm); |
204 | } |
205 | |
206 | static inline u32 ivpu_get_context_count(struct ivpu_device *vdev) |
207 | { |
208 | struct xa_limit ctx_limit = vdev->context_xa_limit; |
209 | |
210 | return (ctx_limit.max - ctx_limit.min + 1); |
211 | } |
212 | |
213 | static inline u32 ivpu_get_platform(struct ivpu_device *vdev) |
214 | { |
215 | WARN_ON_ONCE(vdev->platform == IVPU_PLATFORM_INVALID); |
216 | return vdev->platform; |
217 | } |
218 | |
219 | static inline bool ivpu_is_silicon(struct ivpu_device *vdev) |
220 | { |
221 | return ivpu_get_platform(vdev) == IVPU_PLATFORM_SILICON; |
222 | } |
223 | |
224 | static inline bool ivpu_is_simics(struct ivpu_device *vdev) |
225 | { |
226 | return ivpu_get_platform(vdev) == IVPU_PLATFORM_SIMICS; |
227 | } |
228 | |
229 | static inline bool ivpu_is_fpga(struct ivpu_device *vdev) |
230 | { |
231 | return ivpu_get_platform(vdev) == IVPU_PLATFORM_FPGA; |
232 | } |
233 | |
234 | #endif /* __IVPU_DRV_H__ */ |
235 | |