History

accel/ivpu: Introduce a new DRM driver for Intel VPU

VPU stands for Versatile Processing Unit and it's a CPU-integrated inference accelerator for Computer Vision and Deep Learning applications. The VPU device consist of following components: - Buttress - provides CPU to VPU integration, interrupt, frequency and power management. - Memory Management Unit (based on ARM MMU-600) - translates VPU to host DMA addresses, isolates user workloads. - RISC based microcontroller - executes firmware that provides job execution API for the kernel-mode driver - Neural Compute Subsystem (NCS) - does the actual work, provides Compute and Copy engines. - Network on Chip (NoC) - network fabric connecting all the components This driver supports VPU IP v2.7 integrated into Intel Meteor Lake client CPUs (14th generation). Module sources are at drivers/accel/ivpu and module name is "intel_vpu.ko". This patch includes only very besic functionality: - module, PCI device and IRQ initialization - register definitions and low level register manipulation functions - SET/GET_PARAM ioctls - power up without firmware

Jacek Lawrynowicz committed 3 years ago

Commit 35b13761 parent 6f8498114 files · +2272 −0Browse files

Unified · Split

14 files
  1. MAINTAINERS +9 −0
  2. drivers/Makefile +1 −0
  3. drivers/accel/Kconfig +2 −0
  4. drivers/accel/Makefile +3 −0
  5. drivers/accel/ivpu/Kconfig +15 −0
  6. drivers/accel/ivpu/Makefile +8 −0
  7. drivers/accel/ivpu/TODO +11 −0
  8. drivers/accel/ivpu/ivpu_drv.c +353 −0
  9. drivers/accel/ivpu/ivpu_drv.h +162 −0
  10. drivers/accel/ivpu/ivpu_hw.h +170 −0
  11. drivers/accel/ivpu/ivpu_hw_mtl.c +1048 −0
  12. drivers/accel/ivpu/ivpu_hw_mtl_reg.h +280 −0
  13. drivers/accel/ivpu/ivpu_hw_reg_io.h +115 −0
  14. include/uapi/drm/ivpu_accel.h +95 −0
MAINTAINERS+9−0
@@ -6894,6 +6894,15 @@ T: git https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/accel.git · 6893 unmodified lines
6894F: Documentation/accel/6894F: Documentation/accel/
6895F: drivers/accel/6895F: drivers/accel/
6896 6896
6897DRM ACCEL DRIVERS FOR INTEL VPU
6898M: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
6899M: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
6900L: dri-devel@lists.freedesktop.org
6901S: Supported
6902T: git git://anongit.freedesktop.org/drm/drm-misc
6903F: drivers/accel/ivpu/
6904F: include/uapi/drm/ivpu_accel.h
6905
6897DRM DRIVERS FOR ALLWINNER A106906DRM DRIVERS FOR ALLWINNER A10
6898M: Maxime Ripard <mripard@kernel.org>6907M: Maxime Ripard <mripard@kernel.org>
6899M: Chen-Yu Tsai <wens@csie.org>6908M: Chen-Yu Tsai <wens@csie.org>
drivers/Makefile+1−0
@@ -189,3 +189,4 @@ obj-$(CONFIG_COUNTER) += counter/ · 188 unmodified lines
189obj-$(CONFIG_MOST) += most/189obj-$(CONFIG_MOST) += most/
190obj-$(CONFIG_PECI) += peci/190obj-$(CONFIG_PECI) += peci/
191obj-$(CONFIG_HTE) += hte/191obj-$(CONFIG_HTE) += hte/
192obj-$(CONFIG_DRM_ACCEL) += accel/
drivers/accel/Kconfig+2−0
@@ -22,3 +22,5 @@ menuconfig DRM_ACCEL · 21 unmodified lines
22 major number than GPUs, and will be exposed to user-space using22 major number than GPUs, and will be exposed to user-space using
23 different device files, called accel/accel* (in /dev, sysfs23 different device files, called accel/accel* (in /dev, sysfs
24 and debugfs).24 and debugfs).
25
26source "drivers/accel/ivpu/Kconfig"
drivers/accel/Makefile+3−0
@@ -0,0 +1,3 @@
1# SPDX-License-Identifier: GPL-2.0-only
2
3obj-y += ivpu/
drivers/accel/ivpu/Kconfig+15−0
@@ -0,0 +1,15 @@
1# SPDX-License-Identifier: GPL-2.0-only
2
3config DRM_ACCEL_IVPU
4 tristate "Intel VPU for Meteor Lake and newer"
5 depends on DRM_ACCEL
6 depends on X86_64 && !UML
7 depends on PCI && PCI_MSI
8 select FW_LOADER
9 select SHMEM
10 help
11 Choose this option if you have a system that has an 14th generation Intel CPU
12 or newer. VPU stands for Versatile Processing Unit and it's a CPU-integrated
13 inference accelerator for Computer Vision and Deep Learning applications.
14
15 If "M" is selected, the module will be called intel_vpu.
drivers/accel/ivpu/Makefile+8−0
@@ -0,0 +1,8 @@
1# SPDX-License-Identifier: GPL-2.0-only
2# Copyright (C) 2023 Intel Corporation
3
4intel_vpu-y := \
5 ivpu_drv.o \
6 ivpu_hw_mtl.o
7
8obj-$(CONFIG_DRM_ACCEL_IVPU) += intel_vpu.o
drivers/accel/ivpu/TODO+11−0
@@ -0,0 +1,11 @@
1- Move to threaded_irqs to mitigate potential infinite loop in ivpu_ipc_irq_handler()
2- Implement support for BLOB IDs
3- Add debugfs support to improve debugging and testing
4- Add tracing events for performance debugging
5- Implement HW based scheduling support
6- Use syncobjs for submit/sync
7- Refactor IPC protocol to improve message latency
8- Implement BO cache and MADVISE IOCTL
9- Add support for user allocated buffers using prime import and dma-buf heaps
10- Refactor struct ivpu_bo to use struct drm_gem_shmem_object
11- Add driver/device documentation
drivers/accel/ivpu/ivpu_drv.c+353−0
@@ -0,0 +1,353 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2020-2023 Intel Corporation
4 */
5
6#include <linux/firmware.h>
7#include <linux/module.h>
8#include <linux/pci.h>
9
10#include <drm/drm_accel.h>
11#include <drm/drm_drv.h>
12#include <drm/drm_file.h>
13#include <drm/drm_gem.h>
14#include <drm/drm_ioctl.h>
15
16#include "ivpu_drv.h"
17#include "ivpu_hw.h"
18
19#ifndef DRIVER_VERSION_STR
20#define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \
21 __stringify(DRM_IVPU_DRIVER_MINOR) "."
22#endif
23
24static const struct drm_driver driver;
25
26int ivpu_dbg_mask;
27module_param_named(dbg_mask, ivpu_dbg_mask, int, 0644);
28MODULE_PARM_DESC(dbg_mask, "Driver debug mask. See IVPU_DBG_* macros.");
29
30u8 ivpu_pll_min_ratio;
31module_param_named(pll_min_ratio, ivpu_pll_min_ratio, byte, 0644);
32MODULE_PARM_DESC(pll_min_ratio, "Minimum PLL ratio used to set VPU frequency");
33
34u8 ivpu_pll_max_ratio = U8_MAX;
35module_param_named(pll_max_ratio, ivpu_pll_max_ratio, byte, 0644);
36MODULE_PARM_DESC(pll_max_ratio, "Maximum PLL ratio used to set VPU frequency");
37
38struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv)
39{
40 kref_get(&file_priv->ref);
41 return file_priv;
42}
43
44static void file_priv_release(struct kref *ref)
45{
46 struct ivpu_file_priv *file_priv = container_of(ref, struct ivpu_file_priv, ref);
47
48 kfree(file_priv);
49}
50
51void ivpu_file_priv_put(struct ivpu_file_priv **link)
52{
53 struct ivpu_file_priv *file_priv = *link;
54
55 WARN_ON(!file_priv);
56
57 *link = NULL;
58 kref_put(&file_priv->ref, file_priv_release);
59}
60
61static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
62{
63 struct ivpu_file_priv *file_priv = file->driver_priv;
64 struct ivpu_device *vdev = file_priv->vdev;
65 struct pci_dev *pdev = to_pci_dev(vdev->drm.dev);
66 struct drm_ivpu_param *args = data;
67 int ret = 0;
68
69 switch (args->param) {
70 case DRM_IVPU_PARAM_DEVICE_ID:
71 args->value = pdev->device;
72 break;
73 case DRM_IVPU_PARAM_DEVICE_REVISION:
74 args->value = pdev->revision;
75 break;
76 case DRM_IVPU_PARAM_PLATFORM_TYPE:
77 args->value = vdev->platform;
78 break;
79 case DRM_IVPU_PARAM_CORE_CLOCK_RATE:
80 args->value = ivpu_hw_reg_pll_freq_get(vdev);
81 break;
82 case DRM_IVPU_PARAM_NUM_CONTEXTS:
83 args->value = ivpu_get_context_count(vdev);
84 break;
85 case DRM_IVPU_PARAM_CONTEXT_BASE_ADDRESS:
86 args->value = vdev->hw->ranges.user_low.start;
87 break;
88 case DRM_IVPU_PARAM_CONTEXT_PRIORITY:
89 args->value = file_priv->priority;
90 break;
91 default:
92 ret = -EINVAL;
93 break;
94 }
95
96 return ret;
97}
98
99static int ivpu_set_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
100{
101 struct ivpu_file_priv *file_priv = file->driver_priv;
102 struct drm_ivpu_param *args = data;
103 int ret = 0;
104
105 switch (args->param) {
106 case DRM_IVPU_PARAM_CONTEXT_PRIORITY:
107 if (args->value <= DRM_IVPU_CONTEXT_PRIORITY_REALTIME)
108 file_priv->priority = args->value;
109 else
110 ret = -EINVAL;
111 break;
112 default:
113 ret = -EINVAL;
114 }
115
116 return ret;
117}
118
119static int ivpu_open(struct drm_device *dev, struct drm_file *file)
120{
121 struct ivpu_device *vdev = to_ivpu_device(dev);
122 struct ivpu_file_priv *file_priv;
123
124 file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
125 if (!file_priv)
126 return -ENOMEM;
127
128 file_priv->vdev = vdev;
129 file_priv->priority = DRM_IVPU_CONTEXT_PRIORITY_NORMAL;
130 kref_init(&file_priv->ref);
131
132 file->driver_priv = file_priv;
133 return 0;
134}
135
136static void ivpu_postclose(struct drm_device *dev, struct drm_file *file)
137{
138 struct ivpu_file_priv *file_priv = file->driver_priv;
139
140 ivpu_file_priv_put(&file_priv);
141}
142
143static const struct drm_ioctl_desc ivpu_drm_ioctls[] = {
144 DRM_IOCTL_DEF_DRV(IVPU_GET_PARAM, ivpu_get_param_ioctl, 0),
145 DRM_IOCTL_DEF_DRV(IVPU_SET_PARAM, ivpu_set_param_ioctl, 0),
146};
147
148int ivpu_shutdown(struct ivpu_device *vdev)
149{
150 int ret;
151
152 ivpu_hw_irq_disable(vdev);
153
154 ret = ivpu_hw_power_down(vdev);
155 if (ret)
156 ivpu_warn(vdev, "Failed to power down HW: %d\n", ret);
157
158 return ret;
159}
160
161static const struct file_operations ivpu_fops = {
162 .owner = THIS_MODULE,
163 .mmap = drm_gem_mmap,
164 DRM_ACCEL_FOPS,
165};
166
167static const struct drm_driver driver = {
168 .driver_features = DRIVER_GEM | DRIVER_COMPUTE_ACCEL,
169
170 .open = ivpu_open,
171 .postclose = ivpu_postclose,
172
173 .ioctls = ivpu_drm_ioctls,
174 .num_ioctls = ARRAY_SIZE(ivpu_drm_ioctls),
175 .fops = &ivpu_fops,
176
177 .name = DRIVER_NAME,
178 .desc = DRIVER_DESC,
179 .date = DRIVER_DATE,
180 .major = DRM_IVPU_DRIVER_MAJOR,
181 .minor = DRM_IVPU_DRIVER_MINOR,
182};
183
184static int ivpu_irq_init(struct ivpu_device *vdev)
185{
186 struct pci_dev *pdev = to_pci_dev(vdev->drm.dev);
187 int ret;
188
189 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI | PCI_IRQ_MSIX);
190 if (ret < 0) {
191 ivpu_err(vdev, "Failed to allocate a MSI IRQ: %d\n", ret);
192 return ret;
193 }
194
195 vdev->irq = pci_irq_vector(pdev, 0);
196
197 ret = devm_request_irq(vdev->drm.dev, vdev->irq, vdev->hw->ops->irq_handler,
198 IRQF_NO_AUTOEN, DRIVER_NAME, vdev);
199 if (ret)
200 ivpu_err(vdev, "Failed to request an IRQ %d\n", ret);
201
202 return ret;
203}
204
205static int ivpu_pci_init(struct ivpu_device *vdev)
206{
207 struct pci_dev *pdev = to_pci_dev(vdev->drm.dev);
208 struct resource *bar0 = &pdev->resource[0];
209 struct resource *bar4 = &pdev->resource[4];
210 int ret;
211
212 ivpu_dbg(vdev, MISC, "Mapping BAR0 (RegV) %pR\n", bar0);
213 vdev->regv = devm_ioremap_resource(vdev->drm.dev, bar0);
214 if (IS_ERR(vdev->regv)) {
215 ivpu_err(vdev, "Failed to map bar 0: %pe\n", vdev->regv);
216 return PTR_ERR(vdev->regv);
217 }
218
219 ivpu_dbg(vdev, MISC, "Mapping BAR4 (RegB) %pR\n", bar4);
220 vdev->regb = devm_ioremap_resource(vdev->drm.dev, bar4);
221 if (IS_ERR(vdev->regb)) {
222 ivpu_err(vdev, "Failed to map bar 4: %pe\n", vdev->regb);
223 return PTR_ERR(vdev->regb);
224 }
225
226 ret = dma_set_mask_and_coherent(vdev->drm.dev, DMA_BIT_MASK(38));
227 if (ret) {
228 ivpu_err(vdev, "Failed to set DMA mask: %d\n", ret);
229 return ret;
230 }
231
232 /* Clear any pending errors */
233 pcie_capability_clear_word(pdev, PCI_EXP_DEVSTA, 0x3f);
234
235 ret = pcim_enable_device(pdev);
236 if (ret) {
237 ivpu_err(vdev, "Failed to enable PCI device: %d\n", ret);
238 return ret;
239 }
240
241 pci_set_master(pdev);
242
243 return 0;
244}
245
246static int ivpu_dev_init(struct ivpu_device *vdev)
247{
248 int ret;
249
250 vdev->hw = drmm_kzalloc(&vdev->drm, sizeof(*vdev->hw), GFP_KERNEL);
251 if (!vdev->hw)
252 return -ENOMEM;
253
254 vdev->hw->ops = &ivpu_hw_mtl_ops;
255 vdev->platform = IVPU_PLATFORM_INVALID;
256 vdev->context_xa_limit.min = IVPU_GLOBAL_CONTEXT_MMU_SSID + 1;
257 vdev->context_xa_limit.max = IVPU_CONTEXT_LIMIT;
258 xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC);
259
260 ret = ivpu_pci_init(vdev);
261 if (ret) {
262 ivpu_err(vdev, "Failed to initialize PCI device: %d\n", ret);
263 goto err_xa_destroy;
264 }
265
266 ret = ivpu_irq_init(vdev);
267 if (ret) {
268 ivpu_err(vdev, "Failed to initialize IRQs: %d\n", ret);
269 goto err_xa_destroy;
270 }
271
272 /* Init basic HW info based on buttress registers which are accessible before power up */
273 ret = ivpu_hw_info_init(vdev);
274 if (ret) {
275 ivpu_err(vdev, "Failed to initialize HW info: %d\n", ret);
276 goto err_xa_destroy;
277 }
278
279 /* Power up early so the rest of init code can access VPU registers */
280 ret = ivpu_hw_power_up(vdev);
281 if (ret) {
282 ivpu_err(vdev, "Failed to power up HW: %d\n", ret);
283 goto err_xa_destroy;
284 }
285
286 return 0;
287
288err_xa_destroy:
289 xa_destroy(&vdev->context_xa);
290 return ret;
291}
292
293static void ivpu_dev_fini(struct ivpu_device *vdev)
294{
295 ivpu_shutdown(vdev);
296
297 drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->context_xa));
298 xa_destroy(&vdev->context_xa);
299}
300
301static struct pci_device_id ivpu_pci_ids[] = {
302 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) },
303 { }
304};
305MODULE_DEVICE_TABLE(pci, ivpu_pci_ids);
306
307static int ivpu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
308{
309 struct ivpu_device *vdev;
310 int ret;
311
312 vdev = devm_drm_dev_alloc(&pdev->dev, &driver, struct ivpu_device, drm);
313 if (IS_ERR(vdev))
314 return PTR_ERR(vdev);
315
316 pci_set_drvdata(pdev, vdev);
317
318 ret = ivpu_dev_init(vdev);
319 if (ret) {
320 dev_err(&pdev->dev, "Failed to initialize VPU device: %d\n", ret);
321 return ret;
322 }
323
324 ret = drm_dev_register(&vdev->drm, 0);
325 if (ret) {
326 dev_err(&pdev->dev, "Failed to register DRM device: %d\n", ret);
327 ivpu_dev_fini(vdev);
328 }
329
330 return ret;
331}
332
333static void ivpu_remove(struct pci_dev *pdev)
334{
335 struct ivpu_device *vdev = pci_get_drvdata(pdev);
336
337 drm_dev_unregister(&vdev->drm);
338 ivpu_dev_fini(vdev);
339}
340
341static struct pci_driver ivpu_pci_driver = {
342 .name = KBUILD_MODNAME,
343 .id_table = ivpu_pci_ids,
344 .probe = ivpu_probe,
345 .remove = ivpu_remove,
346};
347
348module_pci_driver(ivpu_pci_driver);
349
350MODULE_AUTHOR("Intel Corporation");
351MODULE_DESCRIPTION(DRIVER_DESC);
352MODULE_LICENSE("GPL and additional rights");
353MODULE_VERSION(DRIVER_VERSION_STR);
drivers/accel/ivpu/ivpu_drv.h+162−0
@@ -0,0 +1,162 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2020-2023 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_managed.h>
11#include <drm/drm_mm.h>
12#include <drm/drm_print.h>
13
14#include <linux/pci.h>
15#include <linux/xarray.h>
16#include <uapi/drm/ivpu_accel.h>
17
18#define DRIVER_NAME "intel_vpu"
19#define DRIVER_DESC "Driver for Intel Versatile Processing Unit (VPU)"
20#define DRIVER_DATE "20230117"
21
22#define PCI_DEVICE_ID_MTL 0x7d1d
23
24#define IVPU_GLOBAL_CONTEXT_MMU_SSID 0
25#define IVPU_CONTEXT_LIMIT 64
26#define IVPU_NUM_ENGINES 2
27
28#define IVPU_PLATFORM_SILICON 0
29#define IVPU_PLATFORM_SIMICS 2
30#define IVPU_PLATFORM_FPGA 3
31#define IVPU_PLATFORM_INVALID 8
32
33#define IVPU_DBG_REG BIT(0)
34#define IVPU_DBG_IRQ BIT(1)
35#define IVPU_DBG_MMU BIT(2)
36#define IVPU_DBG_FILE BIT(3)
37#define IVPU_DBG_MISC BIT(4)
38#define IVPU_DBG_FW_BOOT BIT(5)
39#define IVPU_DBG_PM BIT(6)
40#define IVPU_DBG_IPC BIT(7)
41#define IVPU_DBG_BO BIT(8)
42#define IVPU_DBG_JOB BIT(9)
43#define IVPU_DBG_JSM BIT(10)
44#define IVPU_DBG_KREF BIT(11)
45#define IVPU_DBG_RPM BIT(12)
46
47#define ivpu_err(vdev, fmt, ...) \
48 drm_err(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__)
49
50#define ivpu_err_ratelimited(vdev, fmt, ...) \
51 drm_err_ratelimited(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__)
52
53#define ivpu_warn(vdev, fmt, ...) \
54 drm_warn(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__)
55
56#define ivpu_warn_ratelimited(vdev, fmt, ...) \
57 drm_err_ratelimited(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__)
58
59#define ivpu_info(vdev, fmt, ...) drm_info(&(vdev)->drm, fmt, ##__VA_ARGS__)
60
61#define ivpu_dbg(vdev, type, fmt, args...) do { \
62 if (unlikely(IVPU_DBG_##type & ivpu_dbg_mask)) \
63 dev_dbg((vdev)->drm.dev, "[%s] " fmt, #type, ##args); \
64} while (0)
65
66#define IVPU_WA(wa_name) (vdev->wa.wa_name)
67
68struct ivpu_wa_table {
69 bool punit_disabled;
70 bool clear_runtime_mem;
71};
72
73struct ivpu_hw_info;
74
75struct ivpu_device {
76 struct drm_device drm;
77 void __iomem *regb;
78 void __iomem *regv;
79 u32 platform;
80 u32 irq;
81
82 struct ivpu_wa_table wa;
83 struct ivpu_hw_info *hw;
84
85 struct xarray context_xa;
86 struct xa_limit context_xa_limit;
87
88 struct {
89 int boot;
90 int jsm;
91 int tdr;
92 int reschedule_suspend;
93 } timeout;
94};
95
96/*
97 * file_priv has its own refcount (ref) that allows user space to close the fd
98 * without blocking even if VPU is still processing some jobs.
99 */
100struct ivpu_file_priv {
101 struct kref ref;
102 struct ivpu_device *vdev;
103 u32 priority;
104};
105
106extern int ivpu_dbg_mask;
107extern u8 ivpu_pll_min_ratio;
108extern u8 ivpu_pll_max_ratio;
109
110struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv);
111void ivpu_file_priv_put(struct ivpu_file_priv **link);
112int ivpu_shutdown(struct ivpu_device *vdev);
113
114static inline bool ivpu_is_mtl(struct ivpu_device *vdev)
115{
116 return to_pci_dev(vdev->drm.dev)->device == PCI_DEVICE_ID_MTL;
117}
118
119static inline u8 ivpu_revision(struct ivpu_device *vdev)
120{
121 return to_pci_dev(vdev->drm.dev)->revision;
122}
123
124static inline u16 ivpu_device_id(struct ivpu_device *vdev)
125{
126 return to_pci_dev(vdev->drm.dev)->device;
127}
128
129static inline struct ivpu_device *to_ivpu_device(struct drm_device *dev)
130{
131 return container_of(dev, struct ivpu_device, drm);
132}
133
134static inline u32 ivpu_get_context_count(struct ivpu_device *vdev)
135{
136 struct xa_limit ctx_limit = vdev->context_xa_limit;
137
138 return (ctx_limit.max - ctx_limit.min + 1);
139}
140
141static inline u32 ivpu_get_platform(struct ivpu_device *vdev)
142{
143 WARN_ON_ONCE(vdev->platform == IVPU_PLATFORM_INVALID);
144 return vdev->platform;
145}
146
147static inline bool ivpu_is_silicon(struct ivpu_device *vdev)
148{
149 return ivpu_get_platform(vdev) == IVPU_PLATFORM_SILICON;
150}
151
152static inline bool ivpu_is_simics(struct ivpu_device *vdev)
153{
154 return ivpu_get_platform(vdev) == IVPU_PLATFORM_SIMICS;
155}
156
157static inline bool ivpu_is_fpga(struct ivpu_device *vdev)
158{
159 return ivpu_get_platform(vdev) == IVPU_PLATFORM_FPGA;
160}
161
162#endif /* __IVPU_DRV_H__ */
drivers/accel/ivpu/ivpu_hw.h+170−0
@@ -0,0 +1,170 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2020-2023 Intel Corporation
4 */
5
6#ifndef __IVPU_HW_H__
7#define __IVPU_HW_H__
8
9#include "ivpu_drv.h"
10
11struct ivpu_hw_ops {
12 int (*info_init)(struct ivpu_device *vdev);
13 int (*power_up)(struct ivpu_device *vdev);
14 int (*boot_fw)(struct ivpu_device *vdev);
15 int (*power_down)(struct ivpu_device *vdev);
16 bool (*is_idle)(struct ivpu_device *vdev);
17 void (*wdt_disable)(struct ivpu_device *vdev);
18 void (*diagnose_failure)(struct ivpu_device *vdev);
19 u32 (*reg_pll_freq_get)(struct ivpu_device *vdev);
20 u32 (*reg_telemetry_offset_get)(struct ivpu_device *vdev);
21 u32 (*reg_telemetry_size_get)(struct ivpu_device *vdev);
22 u32 (*reg_telemetry_enable_get)(struct ivpu_device *vdev);
23 void (*reg_db_set)(struct ivpu_device *vdev, u32 db_id);
24 u32 (*reg_ipc_rx_addr_get)(struct ivpu_device *vdev);
25 u32 (*reg_ipc_rx_count_get)(struct ivpu_device *vdev);
26 void (*reg_ipc_tx_set)(struct ivpu_device *vdev, u32 vpu_addr);
27 void (*irq_clear)(struct ivpu_device *vdev);
28 void (*irq_enable)(struct ivpu_device *vdev);
29 void (*irq_disable)(struct ivpu_device *vdev);
30 irqreturn_t (*irq_handler)(int irq, void *ptr);
31};
32
33struct ivpu_addr_range {
34 resource_size_t start;
35 resource_size_t end;
36};
37
38struct ivpu_hw_info {
39 const struct ivpu_hw_ops *ops;
40 struct {
41 struct ivpu_addr_range global_low;
42 struct ivpu_addr_range global_high;
43 struct ivpu_addr_range user_low;
44 struct ivpu_addr_range user_high;
45 struct ivpu_addr_range global_aliased_pio;
46 } ranges;
47 struct {
48 u8 min_ratio;
49 u8 max_ratio;
50 /*
51 * Pll ratio for the efficiency frequency. The VPU has optimum
52 * performance to power ratio at this frequency.
53 */
54 u8 pn_ratio;
55 u32 profiling_freq;
56 } pll;
57 u32 tile_fuse;
58 u32 sku;
59 u16 config;
60};
61
62extern const struct ivpu_hw_ops ivpu_hw_mtl_ops;
63
64static inline int ivpu_hw_info_init(struct ivpu_device *vdev)
65{
66 return vdev->hw->ops->info_init(vdev);
67};
68
69static inline int ivpu_hw_power_up(struct ivpu_device *vdev)
70{
71 ivpu_dbg(vdev, PM, "HW power up\n");
72
73 return vdev->hw->ops->power_up(vdev);
74};
75
76static inline int ivpu_hw_boot_fw(struct ivpu_device *vdev)
77{
78 return vdev->hw->ops->boot_fw(vdev);
79};
80
81static inline bool ivpu_hw_is_idle(struct ivpu_device *vdev)
82{
83 return vdev->hw->ops->is_idle(vdev);
84};
85
86static inline int ivpu_hw_power_down(struct ivpu_device *vdev)
87{
88 ivpu_dbg(vdev, PM, "HW power down\n");
89
90 return vdev->hw->ops->power_down(vdev);
91};
92
93static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev)
94{
95 vdev->hw->ops->wdt_disable(vdev);
96};
97
98/* Register indirect accesses */
99static inline u32 ivpu_hw_reg_pll_freq_get(struct ivpu_device *vdev)
100{
101 return vdev->hw->ops->reg_pll_freq_get(vdev);
102};
103
104static inline u32 ivpu_hw_reg_telemetry_offset_get(struct ivpu_device *vdev)
105{
106 return vdev->hw->ops->reg_telemetry_offset_get(vdev);
107};
108
109static inline u32 ivpu_hw_reg_telemetry_size_get(struct ivpu_device *vdev)
110{
111 return vdev->hw->ops->reg_telemetry_size_get(vdev);
112};
113
114static inline u32 ivpu_hw_reg_telemetry_enable_get(struct ivpu_device *vdev)
115{
116 return vdev->hw->ops->reg_telemetry_enable_get(vdev);
117};
118
119static inline void ivpu_hw_reg_db_set(struct ivpu_device *vdev, u32 db_id)
120{
121 vdev->hw->ops->reg_db_set(vdev, db_id);
122};
123
124static inline u32 ivpu_hw_reg_ipc_rx_addr_get(struct ivpu_device *vdev)
125{
126 return vdev->hw->ops->reg_ipc_rx_addr_get(vdev);
127};
128
129static inline u32 ivpu_hw_reg_ipc_rx_count_get(struct ivpu_device *vdev)
130{
131 return vdev->hw->ops->reg_ipc_rx_count_get(vdev);
132};
133
134static inline void ivpu_hw_reg_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
135{
136 vdev->hw->ops->reg_ipc_tx_set(vdev, vpu_addr);
137};
138
139static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
140{
141 vdev->hw->ops->irq_clear(vdev);
142};
143
144static inline void ivpu_hw_irq_enable(struct ivpu_device *vdev)
145{
146 vdev->hw->ops->irq_enable(vdev);
147};
148
149static inline void ivpu_hw_irq_disable(struct ivpu_device *vdev)
150{
151 vdev->hw->ops->irq_disable(vdev);
152};
153
154static inline void ivpu_hw_init_range(struct ivpu_addr_range *range, u64 start, u64 size)
155{
156 range->start = start;
157 range->end = start + size;
158}
159
160static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range)
161{
162 return range->end - range->start;
163}
164
165static inline void ivpu_hw_diagnose_failure(struct ivpu_device *vdev)
166{
167 vdev->hw->ops->diagnose_failure(vdev);
168}
169
170#endif /* __IVPU_HW_H__ */
drivers/accel/ivpu/ivpu_hw_mtl.c+1048−0
@@ -0,0 +1,1048 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2020-2023 Intel Corporation
4 */
5
6#include "ivpu_drv.h"
7#include "ivpu_hw_mtl_reg.h"
8#include "ivpu_hw_reg_io.h"
9#include "ivpu_hw.h"
10
11#define TILE_FUSE_ENABLE_BOTH 0x0
12#define TILE_FUSE_ENABLE_UPPER 0x1
13#define TILE_FUSE_ENABLE_LOWER 0x2
14
15#define TILE_SKU_BOTH_MTL 0x3630
16#define TILE_SKU_LOWER_MTL 0x3631
17#define TILE_SKU_UPPER_MTL 0x3632
18
19/* Work point configuration values */
20#define WP_CONFIG_1_TILE_5_3_RATIO 0x0101
21#define WP_CONFIG_1_TILE_4_3_RATIO 0x0102
22#define WP_CONFIG_2_TILE_5_3_RATIO 0x0201
23#define WP_CONFIG_2_TILE_4_3_RATIO 0x0202
24#define WP_CONFIG_0_TILE_PLL_OFF 0x0000
25
26#define PLL_REF_CLK_FREQ (50 * 1000000)
27#define PLL_SIMULATION_FREQ (10 * 1000000)
28#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ)
29#define PLL_DEFAULT_EPP_VALUE 0x80
30
31#define TIM_SAFE_ENABLE 0xf1d0dead
32#define TIM_WATCHDOG_RESET_VALUE 0xffffffff
33
34#define TIMEOUT_US (150 * USEC_PER_MSEC)
35#define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC)
36#define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC)
37#define IDLE_TIMEOUT_US (500 * USEC_PER_MSEC)
38
39#define ICB_0_IRQ_MASK ((REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
40 (REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
41 (REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \
42 (REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \
43 (REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \
44 (REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \
45 (REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))
46
47#define ICB_1_IRQ_MASK ((REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \
48 (REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \
49 (REG_FLD(MTL_VPU_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))
50
51#define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK)
52
53#define BUTTRESS_IRQ_MASK ((REG_FLD(MTL_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE)) | \
54 (REG_FLD(MTL_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
55 (REG_FLD(MTL_BUTTRESS_INTERRUPT_STAT, UFI_ERR)))
56
57#define BUTTRESS_IRQ_ENABLE_MASK ((u32)~BUTTRESS_IRQ_MASK)
58#define BUTTRESS_IRQ_DISABLE_MASK ((u32)-1)
59
60#define ITF_FIREWALL_VIOLATION_MASK ((REG_FLD(MTL_VPU_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \
61 (REG_FLD(MTL_VPU_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \
62 (REG_FLD(MTL_VPU_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \
63 (REG_FLD(MTL_VPU_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \
64 (REG_FLD(MTL_VPU_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \
65 (REG_FLD(MTL_VPU_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \
66 (REG_FLD(MTL_VPU_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))
67
68static char *ivpu_platform_to_str(u32 platform)
69{
70 switch (platform) {
71 case IVPU_PLATFORM_SILICON:
72 return "IVPU_PLATFORM_SILICON";
73 case IVPU_PLATFORM_SIMICS:
74 return "IVPU_PLATFORM_SIMICS";
75 case IVPU_PLATFORM_FPGA:
76 return "IVPU_PLATFORM_FPGA";
77 default:
78 return "Invalid platform";
79 }
80}
81
82static void ivpu_hw_read_platform(struct ivpu_device *vdev)
83{
84 u32 gen_ctrl = REGV_RD32(MTL_VPU_HOST_SS_GEN_CTRL);
85 u32 platform = REG_GET_FLD(MTL_VPU_HOST_SS_GEN_CTRL, PS, gen_ctrl);
86
87 if (platform == IVPU_PLATFORM_SIMICS || platform == IVPU_PLATFORM_FPGA)
88 vdev->platform = platform;
89 else
90 vdev->platform = IVPU_PLATFORM_SILICON;
91
92 ivpu_dbg(vdev, MISC, "Platform type: %s (%d)\n",
93 ivpu_platform_to_str(vdev->platform), vdev->platform);
94}
95
96static void ivpu_hw_wa_init(struct ivpu_device *vdev)
97{
98 vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
99 vdev->wa.clear_runtime_mem = false;
100}
101
102static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)
103{
104 if (ivpu_is_simics(vdev) || ivpu_is_fpga(vdev)) {
105 vdev->timeout.boot = 100000;
106 vdev->timeout.jsm = 50000;
107 vdev->timeout.tdr = 2000000;
108 vdev->timeout.reschedule_suspend = 1000;
109 } else {
110 vdev->timeout.boot = 1000;
111 vdev->timeout.jsm = 500;
112 vdev->timeout.tdr = 2000;
113 vdev->timeout.reschedule_suspend = 10;
114 }
115}
116
117static int ivpu_pll_wait_for_cmd_send(struct ivpu_device *vdev)
118{
119 return REGB_POLL_FLD(MTL_BUTTRESS_WP_REQ_CMD, SEND, 0, PLL_TIMEOUT_US);
120}
121
122/* Send KMD initiated workpoint change */
123static int ivpu_pll_cmd_send(struct ivpu_device *vdev, u16 min_ratio, u16 max_ratio,
124 u16 target_ratio, u16 config)
125{
126 int ret;
127 u32 val;
128
129 ret = ivpu_pll_wait_for_cmd_send(vdev);
130 if (ret) {
131 ivpu_err(vdev, "Failed to sync before WP request: %d\n", ret);
132 return ret;
133 }
134
135 val = REGB_RD32(MTL_BUTTRESS_WP_REQ_PAYLOAD0);
136 val = REG_SET_FLD_NUM(MTL_BUTTRESS_WP_REQ_PAYLOAD0, MIN_RATIO, min_ratio, val);
137 val = REG_SET_FLD_NUM(MTL_BUTTRESS_WP_REQ_PAYLOAD0, MAX_RATIO, max_ratio, val);
138 REGB_WR32(MTL_BUTTRESS_WP_REQ_PAYLOAD0, val);
139
140 val = REGB_RD32(MTL_BUTTRESS_WP_REQ_PAYLOAD1);
141 val = REG_SET_FLD_NUM(MTL_BUTTRESS_WP_REQ_PAYLOAD1, TARGET_RATIO, target_ratio, val);
142 val = REG_SET_FLD_NUM(MTL_BUTTRESS_WP_REQ_PAYLOAD1, EPP, PLL_DEFAULT_EPP_VALUE, val);
143 REGB_WR32(MTL_BUTTRESS_WP_REQ_PAYLOAD1, val);
144
145 val = REGB_RD32(MTL_BUTTRESS_WP_REQ_PAYLOAD2);
146 val = REG_SET_FLD_NUM(MTL_BUTTRESS_WP_REQ_PAYLOAD2, CONFIG, config, val);
147 REGB_WR32(MTL_BUTTRESS_WP_REQ_PAYLOAD2, val);
148
149 val = REGB_RD32(MTL_BUTTRESS_WP_REQ_CMD);
150 val = REG_SET_FLD(MTL_BUTTRESS_WP_REQ_CMD, SEND, val);
151 REGB_WR32(MTL_BUTTRESS_WP_REQ_CMD, val);
152
153 ret = ivpu_pll_wait_for_cmd_send(vdev);
154 if (ret)
155 ivpu_err(vdev, "Failed to sync after WP request: %d\n", ret);
156
157 return ret;
158}
159
160static int ivpu_pll_wait_for_lock(struct ivpu_device *vdev, bool enable)
161{
162 u32 exp_val = enable ? 0x1 : 0x0;
163
164 if (IVPU_WA(punit_disabled))
165 return 0;
166
167 return REGB_POLL_FLD(MTL_BUTTRESS_PLL_STATUS, LOCK, exp_val, PLL_TIMEOUT_US);
168}
169
170static int ivpu_pll_wait_for_status_ready(struct ivpu_device *vdev)
171{
172 if (IVPU_WA(punit_disabled))
173 return 0;
174
175 return REGB_POLL_FLD(MTL_BUTTRESS_VPU_STATUS, READY, 1, PLL_TIMEOUT_US);
176}
177
178static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev)
179{
180 struct ivpu_hw_info *hw = vdev->hw;
181 u8 fuse_min_ratio, fuse_max_ratio, fuse_pn_ratio;
182 u32 fmin_fuse, fmax_fuse;
183
184 fmin_fuse = REGB_RD32(MTL_BUTTRESS_FMIN_FUSE);
185 fuse_min_ratio = REG_GET_FLD(MTL_BUTTRESS_FMIN_FUSE, MIN_RATIO, fmin_fuse);
186 fuse_pn_ratio = REG_GET_FLD(MTL_BUTTRESS_FMIN_FUSE, PN_RATIO, fmin_fuse);
187
188 fmax_fuse = REGB_RD32(MTL_BUTTRESS_FMAX_FUSE);
189 fuse_max_ratio = REG_GET_FLD(MTL_BUTTRESS_FMAX_FUSE, MAX_RATIO, fmax_fuse);
190
191 hw->pll.min_ratio = clamp_t(u8, ivpu_pll_min_ratio, fuse_min_ratio, fuse_max_ratio);
192 hw->pll.max_ratio = clamp_t(u8, ivpu_pll_max_ratio, hw->pll.min_ratio, fuse_max_ratio);
193 hw->pll.pn_ratio = clamp_t(u8, fuse_pn_ratio, hw->pll.min_ratio, hw->pll.max_ratio);
194}
195
196static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
197{
198 struct ivpu_hw_info *hw = vdev->hw;
199 u16 target_ratio;
200 u16 config;
201 int ret;
202
203 if (IVPU_WA(punit_disabled)) {
204 ivpu_dbg(vdev, PM, "Skipping PLL request on %s\n",
205 ivpu_platform_to_str(vdev->platform));
206 return 0;
207 }
208
209 if (enable) {
210 target_ratio = hw->pll.pn_ratio;
211 config = hw->config;
212 } else {
213 target_ratio = 0;
214 config = 0;
215 }
216
217 ivpu_dbg(vdev, PM, "PLL workpoint request: %d Hz\n", PLL_RATIO_TO_FREQ(target_ratio));
218
219 ret = ivpu_pll_cmd_send(vdev, hw->pll.min_ratio, hw->pll.max_ratio, target_ratio, config);
220 if (ret) {
221 ivpu_err(vdev, "Failed to send PLL workpoint request: %d\n", ret);
222 return ret;
223 }
224
225 ret = ivpu_pll_wait_for_lock(vdev, enable);
226 if (ret) {
227 ivpu_err(vdev, "Timed out waiting for PLL lock\n");
228 return ret;
229 }
230
231 if (enable) {
232 ret = ivpu_pll_wait_for_status_ready(vdev);
233 if (ret) {
234 ivpu_err(vdev, "Timed out waiting for PLL ready status\n");
235 return ret;
236 }
237 }
238
239 return 0;
240}
241
242static int ivpu_pll_enable(struct ivpu_device *vdev)
243{
244 return ivpu_pll_drive(vdev, true);
245}
246
247static int ivpu_pll_disable(struct ivpu_device *vdev)
248{
249 return ivpu_pll_drive(vdev, false);
250}
251
252static void ivpu_boot_host_ss_rst_clr_assert(struct ivpu_device *vdev)
253{
254 u32 val = REGV_RD32(MTL_VPU_HOST_SS_CPR_RST_CLR);
255
256 val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, TOP_NOC, val);
257 val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, DSS_MAS, val);
258 val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, MSS_MAS, val);
259
260 REGV_WR32(MTL_VPU_HOST_SS_CPR_RST_CLR, val);
261}
262
263static void ivpu_boot_host_ss_rst_drive(struct ivpu_device *vdev, bool enable)
264{
265 u32 val = REGV_RD32(MTL_VPU_HOST_SS_CPR_RST_SET);
266
267 if (enable) {
268 val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_SET, TOP_NOC, val);
269 val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_SET, DSS_MAS, val);
270 val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_SET, MSS_MAS, val);
271 } else {
272 val = REG_CLR_FLD(MTL_VPU_HOST_SS_CPR_RST_SET, TOP_NOC, val);
273 val = REG_CLR_FLD(MTL_VPU_HOST_SS_CPR_RST_SET, DSS_MAS, val);
274 val = REG_CLR_FLD(MTL_VPU_HOST_SS_CPR_RST_SET, MSS_MAS, val);
275 }
276
277 REGV_WR32(MTL_VPU_HOST_SS_CPR_RST_SET, val);
278}
279
280static void ivpu_boot_host_ss_clk_drive(struct ivpu_device *vdev, bool enable)
281{
282 u32 val = REGV_RD32(MTL_VPU_HOST_SS_CPR_CLK_SET);
283
284 if (enable) {
285 val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
286 val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
287 val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
288 } else {
289 val = REG_CLR_FLD(MTL_VPU_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
290 val = REG_CLR_FLD(MTL_VPU_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
291 val = REG_CLR_FLD(MTL_VPU_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
292 }
293
294 REGV_WR32(MTL_VPU_HOST_SS_CPR_CLK_SET, val);
295}
296
297static int ivpu_boot_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)
298{
299 u32 val = REGV_RD32(MTL_VPU_HOST_SS_NOC_QREQN);
300
301 if (!REG_TEST_FLD_NUM(MTL_VPU_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))
302 return -EIO;
303
304 return 0;
305}
306
307static int ivpu_boot_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
308{
309 u32 val = REGV_RD32(MTL_VPU_HOST_SS_NOC_QACCEPTN);
310
311 if (!REG_TEST_FLD_NUM(MTL_VPU_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))
312 return -EIO;
313
314 return 0;
315}
316
317static int ivpu_boot_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
318{
319 u32 val = REGV_RD32(MTL_VPU_HOST_SS_NOC_QDENY);
320
321 if (!REG_TEST_FLD_NUM(MTL_VPU_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))
322 return -EIO;
323
324 return 0;
325}
326
327static int ivpu_boot_top_noc_qrenqn_check(struct ivpu_device *vdev, u32 exp_val)
328{
329 u32 val = REGV_RD32(MTL_VPU_TOP_NOC_QREQN);
330
331 if (!REG_TEST_FLD_NUM(MTL_VPU_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||
332 !REG_TEST_FLD_NUM(MTL_VPU_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))
333 return -EIO;
334
335 return 0;
336}
337
338static int ivpu_boot_top_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
339{
340 u32 val = REGV_RD32(MTL_VPU_TOP_NOC_QACCEPTN);
341
342 if (!REG_TEST_FLD_NUM(MTL_VPU_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||
343 !REG_TEST_FLD_NUM(MTL_VPU_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))
344 return -EIO;
345
346 return 0;
347}
348
349static int ivpu_boot_top_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
350{
351 u32 val = REGV_RD32(MTL_VPU_TOP_NOC_QDENY);
352
353 if (!REG_TEST_FLD_NUM(MTL_VPU_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||
354 !REG_TEST_FLD_NUM(MTL_VPU_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))
355 return -EIO;
356
357 return 0;
358}
359
360static int ivpu_boot_host_ss_configure(struct ivpu_device *vdev)
361{
362 ivpu_boot_host_ss_rst_clr_assert(vdev);
363
364 return ivpu_boot_noc_qreqn_check(vdev, 0x0);
365}
366
367static void ivpu_boot_vpu_idle_gen_disable(struct ivpu_device *vdev)
368{
369 REGV_WR32(MTL_VPU_HOST_SS_AON_VPU_IDLE_GEN, 0x0);
370}
371
372static int ivpu_boot_host_ss_axi_drive(struct ivpu_device *vdev, bool enable)
373{
374 int ret;
375 u32 val;
376
377 val = REGV_RD32(MTL_VPU_HOST_SS_NOC_QREQN);
378 if (enable)
379 val = REG_SET_FLD(MTL_VPU_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
380 else
381 val = REG_CLR_FLD(MTL_VPU_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
382 REGV_WR32(MTL_VPU_HOST_SS_NOC_QREQN, val);
383
384 ret = ivpu_boot_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
385 if (ret) {
386 ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
387 return ret;
388 }
389
390 ret = ivpu_boot_noc_qdeny_check(vdev, 0x0);
391 if (ret)
392 ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
393
394 return ret;
395}
396
397static int ivpu_boot_host_ss_axi_enable(struct ivpu_device *vdev)
398{
399 return ivpu_boot_host_ss_axi_drive(vdev, true);
400}
401
402static int ivpu_boot_host_ss_axi_disable(struct ivpu_device *vdev)
403{
404 return ivpu_boot_host_ss_axi_drive(vdev, false);
405}
406
407static int ivpu_boot_host_ss_top_noc_drive(struct ivpu_device *vdev, bool enable)
408{
409 int ret;
410 u32 val;
411
412 val = REGV_RD32(MTL_VPU_TOP_NOC_QREQN);
413 if (enable) {
414 val = REG_SET_FLD(MTL_VPU_TOP_NOC_QREQN, CPU_CTRL, val);
415 val = REG_SET_FLD(MTL_VPU_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
416 } else {
417 val = REG_CLR_FLD(MTL_VPU_TOP_NOC_QREQN, CPU_CTRL, val);
418 val = REG_CLR_FLD(MTL_VPU_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
419 }
420 REGV_WR32(MTL_VPU_TOP_NOC_QREQN, val);
421
422 ret = ivpu_boot_top_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
423 if (ret) {
424 ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
425 return ret;
426 }
427
428 ret = ivpu_boot_top_noc_qdeny_check(vdev, 0x0);
429 if (ret)
430 ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
431
432 return ret;
433}
434
435static int ivpu_boot_host_ss_top_noc_enable(struct ivpu_device *vdev)
436{
437 return ivpu_boot_host_ss_top_noc_drive(vdev, true);
438}
439
440static int ivpu_boot_host_ss_top_noc_disable(struct ivpu_device *vdev)
441{
442 return ivpu_boot_host_ss_top_noc_drive(vdev, false);
443}
444
445static void ivpu_boot_pwr_island_trickle_drive(struct ivpu_device *vdev, bool enable)
446{
447 u32 val = REGV_RD32(MTL_VPU_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
448
449 if (enable)
450 val = REG_SET_FLD(MTL_VPU_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
451 else
452 val = REG_CLR_FLD(MTL_VPU_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
453
454 REGV_WR32(MTL_VPU_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);
455}
456
457static void ivpu_boot_pwr_island_drive(struct ivpu_device *vdev, bool enable)
458{
459 u32 val = REGV_RD32(MTL_VPU_HOST_SS_AON_PWR_ISLAND_EN0);
460
461 if (enable)
462 val = REG_SET_FLD(MTL_VPU_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
463 else
464 val = REG_CLR_FLD(MTL_VPU_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
465
466 REGV_WR32(MTL_VPU_HOST_SS_AON_PWR_ISLAND_EN0, val);
467}
468
469static int ivpu_boot_wait_for_pwr_island_status(struct ivpu_device *vdev, u32 exp_val)
470{
471 /* FPGA model (UPF) is not power aware, skipped Power Island polling */
472 if (ivpu_is_fpga(vdev))
473 return 0;
474
475 return REGV_POLL_FLD(MTL_VPU_HOST_SS_AON_PWR_ISLAND_STATUS0, MSS_CPU,
476 exp_val, PWR_ISLAND_STATUS_TIMEOUT_US);
477}
478
479static void ivpu_boot_pwr_island_isolation_drive(struct ivpu_device *vdev, bool enable)
480{
481 u32 val = REGV_RD32(MTL_VPU_HOST_SS_AON_PWR_ISO_EN0);
482
483 if (enable)
484 val = REG_SET_FLD(MTL_VPU_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
485 else
486 val = REG_CLR_FLD(MTL_VPU_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
487
488 REGV_WR32(MTL_VPU_HOST_SS_AON_PWR_ISO_EN0, val);
489}
490
491static void ivpu_boot_dpu_active_drive(struct ivpu_device *vdev, bool enable)
492{
493 u32 val = REGV_RD32(MTL_VPU_HOST_SS_AON_DPU_ACTIVE);
494
495 if (enable)
496 val = REG_SET_FLD(MTL_VPU_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
497 else
498 val = REG_CLR_FLD(MTL_VPU_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
499
500 REGV_WR32(MTL_VPU_HOST_SS_AON_DPU_ACTIVE, val);
501}
502
503static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev)
504{
505 ivpu_boot_dpu_active_drive(vdev, false);
506 ivpu_boot_pwr_island_isolation_drive(vdev, true);
507 ivpu_boot_pwr_island_trickle_drive(vdev, false);
508 ivpu_boot_pwr_island_drive(vdev, false);
509
510 return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0);
511}
512
513static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
514{
515 int ret;
516
517 ivpu_boot_pwr_island_trickle_drive(vdev, true);
518 ivpu_boot_pwr_island_drive(vdev, true);
519
520 ret = ivpu_boot_wait_for_pwr_island_status(vdev, 0x1);
521 if (ret) {
522 ivpu_err(vdev, "Timed out waiting for power island status\n");
523 return ret;
524 }
525
526 ret = ivpu_boot_top_noc_qrenqn_check(vdev, 0x0);
527 if (ret) {
528 ivpu_err(vdev, "Failed qrenqn check %d\n", ret);
529 return ret;
530 }
531
532 ivpu_boot_host_ss_clk_drive(vdev, true);
533 ivpu_boot_pwr_island_isolation_drive(vdev, false);
534 ivpu_boot_host_ss_rst_drive(vdev, true);
535 ivpu_boot_dpu_active_drive(vdev, true);
536
537 return ret;
538}
539
540static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
541{
542 u32 val = REGV_RD32(MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES);
543
544 val = REG_SET_FLD(MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES, NOSNOOP_OVERRIDE_EN, val);
545 val = REG_SET_FLD(MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES, AW_NOSNOOP_OVERRIDE, val);
546 val = REG_SET_FLD(MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
547
548 REGV_WR32(MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES, val);
549}
550
551static void ivpu_boot_tbu_mmu_enable(struct ivpu_device *vdev)
552{
553 u32 val = REGV_RD32(MTL_VPU_HOST_IF_TBU_MMUSSIDV);
554
555 if (ivpu_is_fpga(vdev)) {
556 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
557 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
558 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
559 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
560 } else {
561 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
562 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
563 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU1_AWMMUSSIDV, val);
564 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU1_ARMMUSSIDV, val);
565 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
566 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
567 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU3_AWMMUSSIDV, val);
568 val = REG_SET_FLD(MTL_VPU_HOST_IF_TBU_MMUSSIDV, TBU3_ARMMUSSIDV, val);
569 }
570
571 REGV_WR32(MTL_VPU_HOST_IF_TBU_MMUSSIDV, val);
572}
573
574static void ivpu_boot_soc_cpu_boot(struct ivpu_device *vdev)
575{
576 u32 val;
577
578 val = REGV_RD32(MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC);
579 val = REG_SET_FLD(MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTRUN0, val);
580
581 val = REG_CLR_FLD(MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTVEC, val);
582 REGV_WR32(MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
583
584 val = REG_SET_FLD(MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
585 REGV_WR32(MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
586
587 val = REG_CLR_FLD(MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
588 REGV_WR32(MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
589}
590
591static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)
592{
593 int ret;
594 u32 val;
595
596 ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
597 if (ret) {
598 ivpu_err(vdev, "Failed to sync before D0i3 tansition: %d\n", ret);
599 return ret;
600 }
601
602 val = REGB_RD32(MTL_BUTTRESS_VPU_D0I3_CONTROL);
603 if (enable)
604 val = REG_SET_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, I3, val);
605 else
606 val = REG_CLR_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, I3, val);
607 REGB_WR32(MTL_BUTTRESS_VPU_D0I3_CONTROL, val);
608
609 ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
610 if (ret)
611 ivpu_err(vdev, "Failed to sync after D0i3 tansition: %d\n", ret);
612
613 return ret;
614}
615
616static int ivpu_hw_mtl_info_init(struct ivpu_device *vdev)
617{
618 struct ivpu_hw_info *hw = vdev->hw;
619 u32 tile_fuse;
620
621 tile_fuse = REGB_RD32(MTL_BUTTRESS_TILE_FUSE);
622 if (!REG_TEST_FLD(MTL_BUTTRESS_TILE_FUSE, VALID, tile_fuse))
623 ivpu_warn(vdev, "Tile Fuse: Invalid (0x%x)\n", tile_fuse);
624
625 hw->tile_fuse = REG_GET_FLD(MTL_BUTTRESS_TILE_FUSE, SKU, tile_fuse);
626 switch (hw->tile_fuse) {
627 case TILE_FUSE_ENABLE_LOWER:
628 hw->sku = TILE_SKU_LOWER_MTL;
629 hw->config = WP_CONFIG_1_TILE_5_3_RATIO;
630 ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Lower\n");
631 break;
632 case TILE_FUSE_ENABLE_UPPER:
633 hw->sku = TILE_SKU_UPPER_MTL;
634 hw->config = WP_CONFIG_1_TILE_4_3_RATIO;
635 ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Upper\n");
636 break;
637 case TILE_FUSE_ENABLE_BOTH:
638 hw->sku = TILE_SKU_BOTH_MTL;
639 hw->config = WP_CONFIG_2_TILE_5_3_RATIO;
640 ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Both\n");
641 break;
642 default:
643 hw->config = WP_CONFIG_0_TILE_PLL_OFF;
644 ivpu_dbg(vdev, MISC, "Tile Fuse: Disable\n");
645 break;
646 }
647
648 ivpu_pll_init_frequency_ratios(vdev);
649
650 ivpu_hw_init_range(&hw->ranges.global_low, 0x80000000, SZ_512M);
651 ivpu_hw_init_range(&hw->ranges.global_high, 0x180000000, SZ_2M);
652 ivpu_hw_init_range(&hw->ranges.user_low, 0xc0000000, 255 * SZ_1M);
653 ivpu_hw_init_range(&hw->ranges.user_high, 0x180000000, SZ_2G);
654 hw->ranges.global_aliased_pio = hw->ranges.user_low;
655
656 return 0;
657}
658
659static int ivpu_hw_mtl_reset(struct ivpu_device *vdev)
660{
661 int ret;
662 u32 val;
663
664 if (IVPU_WA(punit_disabled))
665 return 0;
666
667 ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
668 if (ret) {
669 ivpu_err(vdev, "Timed out waiting for TRIGGER bit\n");
670 return ret;
671 }
672
673 val = REGB_RD32(MTL_BUTTRESS_VPU_IP_RESET);
674 val = REG_SET_FLD(MTL_BUTTRESS_VPU_IP_RESET, TRIGGER, val);
675 REGB_WR32(MTL_BUTTRESS_VPU_IP_RESET, val);
676
677 ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
678 if (ret)
679 ivpu_err(vdev, "Timed out waiting for RESET completion\n");
680
681 return ret;
682}
683
684static int ivpu_hw_mtl_d0i3_enable(struct ivpu_device *vdev)
685{
686 int ret;
687
688 ret = ivpu_boot_d0i3_drive(vdev, true);
689 if (ret)
690 ivpu_err(vdev, "Failed to enable D0i3: %d\n", ret);
691
692 udelay(5); /* VPU requires 5 us to complete the transition */
693
694 return ret;
695}
696
697static int ivpu_hw_mtl_d0i3_disable(struct ivpu_device *vdev)
698{
699 int ret;
700
701 ret = ivpu_boot_d0i3_drive(vdev, false);
702 if (ret)
703 ivpu_err(vdev, "Failed to disable D0i3: %d\n", ret);
704
705 return ret;
706}
707
708static int ivpu_hw_mtl_power_up(struct ivpu_device *vdev)
709{
710 int ret;
711
712 ivpu_hw_read_platform(vdev);
713 ivpu_hw_wa_init(vdev);
714 ivpu_hw_timeouts_init(vdev);
715
716 ret = ivpu_hw_mtl_reset(vdev);
717 if (ret)
718 ivpu_warn(vdev, "Failed to reset HW: %d\n", ret);
719
720 ret = ivpu_hw_mtl_d0i3_disable(vdev);
721 if (ret)
722 ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
723
724 ret = ivpu_pll_enable(vdev);
725 if (ret) {
726 ivpu_err(vdev, "Failed to enable PLL: %d\n", ret);
727 return ret;
728 }
729
730 ret = ivpu_boot_host_ss_configure(vdev);
731 if (ret) {
732 ivpu_err(vdev, "Failed to configure host SS: %d\n", ret);
733 return ret;
734 }
735
736 /*
737 * The control circuitry for vpu_idle indication logic powers up active.
738 * To ensure unnecessary low power mode signal from LRT during bring up,
739 * KMD disables the circuitry prior to bringing up the Main Power island.
740 */
741 ivpu_boot_vpu_idle_gen_disable(vdev);
742
743 ret = ivpu_boot_pwr_domain_enable(vdev);
744 if (ret) {
745 ivpu_err(vdev, "Failed to enable power domain: %d\n", ret);
746 return ret;
747 }
748
749 ret = ivpu_boot_host_ss_axi_enable(vdev);
750 if (ret) {
751 ivpu_err(vdev, "Failed to enable AXI: %d\n", ret);
752 return ret;
753 }
754
755 ret = ivpu_boot_host_ss_top_noc_enable(vdev);
756 if (ret)
757 ivpu_err(vdev, "Failed to enable TOP NOC: %d\n", ret);
758
759 return ret;
760}
761
762static int ivpu_hw_mtl_boot_fw(struct ivpu_device *vdev)
763{
764 ivpu_boot_no_snoop_enable(vdev);
765 ivpu_boot_tbu_mmu_enable(vdev);
766 ivpu_boot_soc_cpu_boot(vdev);
767
768 return 0;
769}
770
771static bool ivpu_hw_mtl_is_idle(struct ivpu_device *vdev)
772{
773 u32 val;
774
775 if (IVPU_WA(punit_disabled))
776 return true;
777
778 val = REGB_RD32(MTL_BUTTRESS_VPU_STATUS);
779 return REG_TEST_FLD(MTL_BUTTRESS_VPU_STATUS, READY, val) &&
780 REG_TEST_FLD(MTL_BUTTRESS_VPU_STATUS, IDLE, val);
781}
782
783static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev)
784{
785 int ret = 0;
786
787 /* FPGA requires manual clearing of IP_Reset bit by enabling quiescent state */
788 if (ivpu_is_fpga(vdev)) {
789 if (ivpu_boot_host_ss_top_noc_disable(vdev)) {
790 ivpu_err(vdev, "Failed to disable TOP NOC\n");
791 ret = -EIO;
792 }
793
794 if (ivpu_boot_host_ss_axi_disable(vdev)) {
795 ivpu_err(vdev, "Failed to disable AXI\n");
796 ret = -EIO;
797 }
798 }
799
800 if (ivpu_boot_pwr_domain_disable(vdev)) {
801 ivpu_err(vdev, "Failed to disable power domain\n");
802 ret = -EIO;
803 }
804
805 if (ivpu_pll_disable(vdev)) {
806 ivpu_err(vdev, "Failed to disable PLL\n");
807 ret = -EIO;
808 }
809
810 if (ivpu_hw_mtl_d0i3_enable(vdev))
811 ivpu_warn(vdev, "Failed to enable D0I3\n");
812
813 return ret;
814}
815
816static void ivpu_hw_mtl_wdt_disable(struct ivpu_device *vdev)
817{
818 u32 val;
819
820 /* Enable writing and set non-zero WDT value */
821 REGV_WR32(MTL_VPU_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
822 REGV_WR32(MTL_VPU_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);
823
824 /* Enable writing and disable watchdog timer */
825 REGV_WR32(MTL_VPU_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
826 REGV_WR32(MTL_VPU_CPU_SS_TIM_WDOG_EN, 0);
827
828 /* Now clear the timeout interrupt */
829 val = REGV_RD32(MTL_VPU_CPU_SS_TIM_GEN_CONFIG);
830 val = REG_CLR_FLD(MTL_VPU_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);
831 REGV_WR32(MTL_VPU_CPU_SS_TIM_GEN_CONFIG, val);
832}
833
834/* Register indirect accesses */
835static u32 ivpu_hw_mtl_reg_pll_freq_get(struct ivpu_device *vdev)
836{
837 u32 pll_curr_ratio;
838
839 pll_curr_ratio = REGB_RD32(MTL_BUTTRESS_CURRENT_PLL);
840 pll_curr_ratio &= MTL_BUTTRESS_CURRENT_PLL_RATIO_MASK;
841
842 if (!ivpu_is_silicon(vdev))
843 return PLL_SIMULATION_FREQ;
844
845 return PLL_RATIO_TO_FREQ(pll_curr_ratio);
846}
847
848static u32 ivpu_hw_mtl_reg_telemetry_offset_get(struct ivpu_device *vdev)
849{
850 return REGB_RD32(MTL_BUTTRESS_VPU_TELEMETRY_OFFSET);
851}
852
853static u32 ivpu_hw_mtl_reg_telemetry_size_get(struct ivpu_device *vdev)
854{
855 return REGB_RD32(MTL_BUTTRESS_VPU_TELEMETRY_SIZE);
856}
857
858static u32 ivpu_hw_mtl_reg_telemetry_enable_get(struct ivpu_device *vdev)
859{
860 return REGB_RD32(MTL_BUTTRESS_VPU_TELEMETRY_ENABLE);
861}
862
863static void ivpu_hw_mtl_reg_db_set(struct ivpu_device *vdev, u32 db_id)
864{
865 u32 reg_stride = MTL_VPU_CPU_SS_DOORBELL_1 - MTL_VPU_CPU_SS_DOORBELL_0;
866 u32 val = REG_FLD(MTL_VPU_CPU_SS_DOORBELL_0, SET);
867
868 REGV_WR32I(MTL_VPU_CPU_SS_DOORBELL_0, reg_stride, db_id, val);
869}
870
871static u32 ivpu_hw_mtl_reg_ipc_rx_addr_get(struct ivpu_device *vdev)
872{
873 return REGV_RD32(MTL_VPU_HOST_SS_TIM_IPC_FIFO_ATM);
874}
875
876static u32 ivpu_hw_mtl_reg_ipc_rx_count_get(struct ivpu_device *vdev)
877{
878 u32 count = REGV_RD32_SILENT(MTL_VPU_HOST_SS_TIM_IPC_FIFO_STAT);
879
880 return REG_GET_FLD(MTL_VPU_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);
881}
882
883static void ivpu_hw_mtl_reg_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
884{
885 REGV_WR32(MTL_VPU_CPU_SS_TIM_IPC_FIFO, vpu_addr);
886}
887
888static void ivpu_hw_mtl_irq_clear(struct ivpu_device *vdev)
889{
890 REGV_WR64(MTL_VPU_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK);
891}
892
893static void ivpu_hw_mtl_irq_enable(struct ivpu_device *vdev)
894{
895 REGV_WR32(MTL_VPU_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK);
896 REGV_WR64(MTL_VPU_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK);
897 REGB_WR32(MTL_BUTTRESS_LOCAL_INT_MASK, BUTTRESS_IRQ_ENABLE_MASK);
898 REGB_WR32(MTL_BUTTRESS_GLOBAL_INT_MASK, 0x0);
899}
900
901static void ivpu_hw_mtl_irq_disable(struct ivpu_device *vdev)
902{
903 REGB_WR32(MTL_BUTTRESS_GLOBAL_INT_MASK, 0x1);
904 REGB_WR32(MTL_BUTTRESS_LOCAL_INT_MASK, BUTTRESS_IRQ_DISABLE_MASK);
905 REGV_WR64(MTL_VPU_HOST_SS_ICB_ENABLE_0, 0x0ull);
906 REGB_WR32(MTL_VPU_HOST_SS_FW_SOC_IRQ_EN, 0x0);
907}
908
909static void ivpu_hw_mtl_irq_wdt_nce_handler(struct ivpu_device *vdev)
910{
911 ivpu_err_ratelimited(vdev, "WDT NCE irq\n");
912}
913
914static void ivpu_hw_mtl_irq_wdt_mss_handler(struct ivpu_device *vdev)
915{
916 ivpu_err_ratelimited(vdev, "WDT MSS irq\n");
917
918 ivpu_hw_wdt_disable(vdev);
919}
920
921static void ivpu_hw_mtl_irq_noc_firewall_handler(struct ivpu_device *vdev)
922{
923 ivpu_err_ratelimited(vdev, "NOC Firewall irq\n");
924}
925
926/* Handler for IRQs from VPU core (irqV) */
927static u32 ivpu_hw_mtl_irqv_handler(struct ivpu_device *vdev, int irq)
928{
929 u32 status = REGV_RD32(MTL_VPU_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
930
931 REGV_WR32(MTL_VPU_HOST_SS_ICB_CLEAR_0, status);
932
933 if (REG_TEST_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))
934 ivpu_hw_mtl_irq_wdt_mss_handler(vdev);
935
936 if (REG_TEST_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))
937 ivpu_hw_mtl_irq_wdt_nce_handler(vdev);
938
939 if (REG_TEST_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
940 ivpu_hw_mtl_irq_noc_firewall_handler(vdev);
941
942 return status;
943}
944
945/* Handler for IRQs from Buttress core (irqB) */
946static u32 ivpu_hw_mtl_irqb_handler(struct ivpu_device *vdev, int irq)
947{
948 u32 status = REGB_RD32(MTL_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
949
950 if (status == 0)
951 return 0;
952
953 /* Disable global interrupt before handling local buttress interrupts */
954 REGB_WR32(MTL_BUTTRESS_GLOBAL_INT_MASK, 0x1);
955
956 if (REG_TEST_FLD(MTL_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
957 ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", REGB_RD32(MTL_BUTTRESS_CURRENT_PLL));
958
959 if (REG_TEST_FLD(MTL_BUTTRESS_INTERRUPT_STAT, ATS_ERR, status)) {
960 ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(MTL_BUTTRESS_ATS_ERR_LOG_0));
961 REGB_WR32(MTL_BUTTRESS_ATS_ERR_CLEAR, 0x1);
962 }
963
964 if (REG_TEST_FLD(MTL_BUTTRESS_INTERRUPT_STAT, UFI_ERR, status)) {
965 u32 ufi_log = REGB_RD32(MTL_BUTTRESS_UFI_ERR_LOG);
966
967 ivpu_err(vdev, "UFI_ERR irq (0x%08x) opcode: 0x%02lx axi_id: 0x%02lx cq_id: 0x%03lx",
968 ufi_log, REG_GET_FLD(MTL_BUTTRESS_UFI_ERR_LOG, OPCODE, ufi_log),
969 REG_GET_FLD(MTL_BUTTRESS_UFI_ERR_LOG, AXI_ID, ufi_log),
970 REG_GET_FLD(MTL_BUTTRESS_UFI_ERR_LOG, CQ_ID, ufi_log));
971 REGB_WR32(MTL_BUTTRESS_UFI_ERR_CLEAR, 0x1);
972 }
973
974 /*
975 * Clear local interrupt status by writing 0 to all bits.
976 * This must be done after interrupts are cleared at the source.
977 * Writing 1 triggers an interrupt, so we can't perform read update write.
978 */
979 REGB_WR32(MTL_BUTTRESS_INTERRUPT_STAT, 0x0);
980
981 /* Re-enable global interrupt */
982 REGB_WR32(MTL_BUTTRESS_GLOBAL_INT_MASK, 0x0);
983
984 return status;
985}
986
987static irqreturn_t ivpu_hw_mtl_irq_handler(int irq, void *ptr)
988{
989 struct ivpu_device *vdev = ptr;
990 u32 ret_irqv, ret_irqb;
991
992 ret_irqv = ivpu_hw_mtl_irqv_handler(vdev, irq);
993 ret_irqb = ivpu_hw_mtl_irqb_handler(vdev, irq);
994
995 return IRQ_RETVAL(ret_irqb | ret_irqv);
996}
997
998static void ivpu_hw_mtl_diagnose_failure(struct ivpu_device *vdev)
999{
1000 u32 irqv = REGV_RD32(MTL_VPU_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
1001 u32 irqb = REGB_RD32(MTL_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
1002
1003 if (ivpu_hw_mtl_reg_ipc_rx_count_get(vdev))
1004 ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");
1005
1006 if (REG_TEST_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, irqv))
1007 ivpu_err(vdev, "WDT MSS timeout detected\n");
1008
1009 if (REG_TEST_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, irqv))
1010 ivpu_err(vdev, "WDT NCE timeout detected\n");
1011
1012 if (REG_TEST_FLD(MTL_VPU_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, irqv))
1013 ivpu_err(vdev, "NOC Firewall irq detected\n");
1014
1015 if (REG_TEST_FLD(MTL_BUTTRESS_INTERRUPT_STAT, ATS_ERR, irqb))
1016 ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(MTL_BUTTRESS_ATS_ERR_LOG_0));
1017
1018 if (REG_TEST_FLD(MTL_BUTTRESS_INTERRUPT_STAT, UFI_ERR, irqb)) {
1019 u32 ufi_log = REGB_RD32(MTL_BUTTRESS_UFI_ERR_LOG);
1020
1021 ivpu_err(vdev, "UFI_ERR irq (0x%08x) opcode: 0x%02lx axi_id: 0x%02lx cq_id: 0x%03lx",
1022 ufi_log, REG_GET_FLD(MTL_BUTTRESS_UFI_ERR_LOG, OPCODE, ufi_log),
1023 REG_GET_FLD(MTL_BUTTRESS_UFI_ERR_LOG, AXI_ID, ufi_log),
1024 REG_GET_FLD(MTL_BUTTRESS_UFI_ERR_LOG, CQ_ID, ufi_log));
1025 }
1026}
1027
1028const struct ivpu_hw_ops ivpu_hw_mtl_ops = {
1029 .info_init = ivpu_hw_mtl_info_init,
1030 .power_up = ivpu_hw_mtl_power_up,
1031 .is_idle = ivpu_hw_mtl_is_idle,
1032 .power_down = ivpu_hw_mtl_power_down,
1033 .boot_fw = ivpu_hw_mtl_boot_fw,
1034 .wdt_disable = ivpu_hw_mtl_wdt_disable,
1035 .diagnose_failure = ivpu_hw_mtl_diagnose_failure,
1036 .reg_pll_freq_get = ivpu_hw_mtl_reg_pll_freq_get,
1037 .reg_telemetry_offset_get = ivpu_hw_mtl_reg_telemetry_offset_get,
1038 .reg_telemetry_size_get = ivpu_hw_mtl_reg_telemetry_size_get,
1039 .reg_telemetry_enable_get = ivpu_hw_mtl_reg_telemetry_enable_get,
1040 .reg_db_set = ivpu_hw_mtl_reg_db_set,
1041 .reg_ipc_rx_addr_get = ivpu_hw_mtl_reg_ipc_rx_addr_get,
1042 .reg_ipc_rx_count_get = ivpu_hw_mtl_reg_ipc_rx_count_get,
1043 .reg_ipc_tx_set = ivpu_hw_mtl_reg_ipc_tx_set,
1044 .irq_clear = ivpu_hw_mtl_irq_clear,
1045 .irq_enable = ivpu_hw_mtl_irq_enable,
1046 .irq_disable = ivpu_hw_mtl_irq_disable,
1047 .irq_handler = ivpu_hw_mtl_irq_handler,
1048};
drivers/accel/ivpu/ivpu_hw_mtl_reg.h+280−0
@@ -0,0 +1,280 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2020-2023 Intel Corporation
4 */
5
6#ifndef __IVPU_HW_MTL_REG_H__
7#define __IVPU_HW_MTL_REG_H__
8
9#include <linux/bits.h>
10
11#define MTL_BUTTRESS_INTERRUPT_TYPE 0x00000000u
12
13#define MTL_BUTTRESS_INTERRUPT_STAT 0x00000004u
14#define MTL_BUTTRESS_INTERRUPT_STAT_FREQ_CHANGE_MASK BIT_MASK(0)
15#define MTL_BUTTRESS_INTERRUPT_STAT_ATS_ERR_MASK BIT_MASK(1)
16#define MTL_BUTTRESS_INTERRUPT_STAT_UFI_ERR_MASK BIT_MASK(2)
17
18#define MTL_BUTTRESS_WP_REQ_PAYLOAD0 0x00000008u
19#define MTL_BUTTRESS_WP_REQ_PAYLOAD0_MIN_RATIO_MASK GENMASK(15, 0)
20#define MTL_BUTTRESS_WP_REQ_PAYLOAD0_MAX_RATIO_MASK GENMASK(31, 16)
21
22#define MTL_BUTTRESS_WP_REQ_PAYLOAD1 0x0000000cu
23#define MTL_BUTTRESS_WP_REQ_PAYLOAD1_TARGET_RATIO_MASK GENMASK(15, 0)
24#define MTL_BUTTRESS_WP_REQ_PAYLOAD1_EPP_MASK GENMASK(31, 16)
25
26#define MTL_BUTTRESS_WP_REQ_PAYLOAD2 0x00000010u
27#define MTL_BUTTRESS_WP_REQ_PAYLOAD2_CONFIG_MASK GENMASK(15, 0)
28
29#define MTL_BUTTRESS_WP_REQ_CMD 0x00000014u
30#define MTL_BUTTRESS_WP_REQ_CMD_SEND_MASK BIT_MASK(0)
31
32#define MTL_BUTTRESS_WP_DOWNLOAD 0x00000018u
33#define MTL_BUTTRESS_WP_DOWNLOAD_TARGET_RATIO_MASK GENMASK(15, 0)
34
35#define MTL_BUTTRESS_CURRENT_PLL 0x0000001cu
36#define MTL_BUTTRESS_CURRENT_PLL_RATIO_MASK GENMASK(15, 0)
37
38#define MTL_BUTTRESS_PLL_ENABLE 0x00000020u
39
40#define MTL_BUTTRESS_FMIN_FUSE 0x00000024u
41#define MTL_BUTTRESS_FMIN_FUSE_MIN_RATIO_MASK GENMASK(7, 0)
42#define MTL_BUTTRESS_FMIN_FUSE_PN_RATIO_MASK GENMASK(15, 8)
43
44#define MTL_BUTTRESS_FMAX_FUSE 0x00000028u
45#define MTL_BUTTRESS_FMAX_FUSE_MAX_RATIO_MASK GENMASK(7, 0)
46
47#define MTL_BUTTRESS_TILE_FUSE 0x0000002cu
48#define MTL_BUTTRESS_TILE_FUSE_VALID_MASK BIT_MASK(0)
49#define MTL_BUTTRESS_TILE_FUSE_SKU_MASK GENMASK(3, 2)
50
51#define MTL_BUTTRESS_LOCAL_INT_MASK 0x00000030u
52#define MTL_BUTTRESS_GLOBAL_INT_MASK 0x00000034u
53
54#define MTL_BUTTRESS_PLL_STATUS 0x00000040u
55#define MTL_BUTTRESS_PLL_STATUS_LOCK_MASK BIT_MASK(1)
56
57#define MTL_BUTTRESS_VPU_STATUS 0x00000044u
58#define MTL_BUTTRESS_VPU_STATUS_READY_MASK BIT_MASK(0)
59#define MTL_BUTTRESS_VPU_STATUS_IDLE_MASK BIT_MASK(1)
60
61#define MTL_BUTTRESS_VPU_D0I3_CONTROL 0x00000060u
62#define MTL_BUTTRESS_VPU_D0I3_CONTROL_INPROGRESS_MASK BIT_MASK(0)
63#define MTL_BUTTRESS_VPU_D0I3_CONTROL_I3_MASK BIT_MASK(2)
64
65#define MTL_BUTTRESS_VPU_IP_RESET 0x00000050u
66#define MTL_BUTTRESS_VPU_IP_RESET_TRIGGER_MASK BIT_MASK(0)
67
68#define MTL_BUTTRESS_VPU_TELEMETRY_OFFSET 0x00000080u
69#define MTL_BUTTRESS_VPU_TELEMETRY_SIZE 0x00000084u
70#define MTL_BUTTRESS_VPU_TELEMETRY_ENABLE 0x00000088u
71
72#define MTL_BUTTRESS_ATS_ERR_LOG_0 0x000000a0u
73#define MTL_BUTTRESS_ATS_ERR_LOG_1 0x000000a4u
74#define MTL_BUTTRESS_ATS_ERR_CLEAR 0x000000a8u
75
76#define MTL_BUTTRESS_UFI_ERR_LOG 0x000000b0u
77#define MTL_BUTTRESS_UFI_ERR_LOG_CQ_ID_MASK GENMASK(11, 0)
78#define MTL_BUTTRESS_UFI_ERR_LOG_AXI_ID_MASK GENMASK(19, 12)
79#define MTL_BUTTRESS_UFI_ERR_LOG_OPCODE_MASK GENMASK(24, 20)
80
81#define MTL_BUTTRESS_UFI_ERR_CLEAR 0x000000b4u
82
83#define MTL_VPU_HOST_SS_CPR_CLK_SET 0x00000084u
84#define MTL_VPU_HOST_SS_CPR_CLK_SET_TOP_NOC_MASK BIT_MASK(1)
85#define MTL_VPU_HOST_SS_CPR_CLK_SET_DSS_MAS_MASK BIT_MASK(10)
86#define MTL_VPU_HOST_SS_CPR_CLK_SET_MSS_MAS_MASK BIT_MASK(11)
87
88#define MTL_VPU_HOST_SS_CPR_RST_SET 0x00000094u
89#define MTL_VPU_HOST_SS_CPR_RST_SET_TOP_NOC_MASK BIT_MASK(1)
90#define MTL_VPU_HOST_SS_CPR_RST_SET_DSS_MAS_MASK BIT_MASK(10)
91#define MTL_VPU_HOST_SS_CPR_RST_SET_MSS_MAS_MASK BIT_MASK(11)
92
93#define MTL_VPU_HOST_SS_CPR_RST_CLR 0x00000098u
94#define MTL_VPU_HOST_SS_CPR_RST_CLR_TOP_NOC_MASK BIT_MASK(1)
95#define MTL_VPU_HOST_SS_CPR_RST_CLR_DSS_MAS_MASK BIT_MASK(10)
96#define MTL_VPU_HOST_SS_CPR_RST_CLR_MSS_MAS_MASK BIT_MASK(11)
97
98#define MTL_VPU_HOST_SS_HW_VERSION 0x00000108u
99#define MTL_VPU_HOST_SS_HW_VERSION_SOC_REVISION_MASK GENMASK(7, 0)
100#define MTL_VPU_HOST_SS_HW_VERSION_SOC_NUMBER_MASK GENMASK(15, 8)
101#define MTL_VPU_HOST_SS_HW_VERSION_VPU_GENERATION_MASK GENMASK(23, 16)
102
103#define MTL_VPU_HOST_SS_GEN_CTRL 0x00000118u
104#define MTL_VPU_HOST_SS_GEN_CTRL_PS_MASK GENMASK(31, 29)
105
106#define MTL_VPU_HOST_SS_NOC_QREQN 0x00000154u
107#define MTL_VPU_HOST_SS_NOC_QREQN_TOP_SOCMMIO_MASK BIT_MASK(0)
108
109#define MTL_VPU_HOST_SS_NOC_QACCEPTN 0x00000158u
110#define MTL_VPU_HOST_SS_NOC_QACCEPTN_TOP_SOCMMIO_MASK BIT_MASK(0)
111
112#define MTL_VPU_HOST_SS_NOC_QDENY 0x0000015cu
113#define MTL_VPU_HOST_SS_NOC_QDENY_TOP_SOCMMIO_MASK BIT_MASK(0)
114
115#define MTL_VPU_TOP_NOC_QREQN 0x00000160u
116#define MTL_VPU_TOP_NOC_QREQN_CPU_CTRL_MASK BIT_MASK(0)
117#define MTL_VPU_TOP_NOC_QREQN_HOSTIF_L2CACHE_MASK BIT_MASK(1)
118
119#define MTL_VPU_TOP_NOC_QACCEPTN 0x00000164u
120#define MTL_VPU_TOP_NOC_QACCEPTN_CPU_CTRL_MASK BIT_MASK(0)
121#define MTL_VPU_TOP_NOC_QACCEPTN_HOSTIF_L2CACHE_MASK BIT_MASK(1)
122
123#define MTL_VPU_TOP_NOC_QDENY 0x00000168u
124#define MTL_VPU_TOP_NOC_QDENY_CPU_CTRL_MASK BIT_MASK(0)
125#define MTL_VPU_TOP_NOC_QDENY_HOSTIF_L2CACHE_MASK BIT_MASK(1)
126
127#define MTL_VPU_HOST_SS_FW_SOC_IRQ_EN 0x00000170u
128#define MTL_VPU_HOST_SS_FW_SOC_IRQ_EN_CSS_ROM_CMX_MASK BIT_MASK(0)
129#define MTL_VPU_HOST_SS_FW_SOC_IRQ_EN_CSS_DBG_MASK BIT_MASK(1)
130#define MTL_VPU_HOST_SS_FW_SOC_IRQ_EN_CSS_CTRL_MASK BIT_MASK(2)
131#define MTL_VPU_HOST_SS_FW_SOC_IRQ_EN_DEC400_MASK BIT_MASK(3)
132#define MTL_VPU_HOST_SS_FW_SOC_IRQ_EN_MSS_NCE_MASK BIT_MASK(4)
133#define MTL_VPU_HOST_SS_FW_SOC_IRQ_EN_MSS_MBI_MASK BIT_MASK(5)
134#define MTL_VPU_HOST_SS_FW_SOC_IRQ_EN_MSS_MBI_CMX_MASK BIT_MASK(6)
135
136#define MTL_VPU_HOST_SS_ICB_STATUS_0 0x00010210u
137#define MTL_VPU_HOST_SS_ICB_STATUS_0_TIMER_0_INT_MASK BIT_MASK(0)
138#define MTL_VPU_HOST_SS_ICB_STATUS_0_TIMER_1_INT_MASK BIT_MASK(1)
139#define MTL_VPU_HOST_SS_ICB_STATUS_0_TIMER_2_INT_MASK BIT_MASK(2)
140#define MTL_VPU_HOST_SS_ICB_STATUS_0_TIMER_3_INT_MASK BIT_MASK(3)
141#define MTL_VPU_HOST_SS_ICB_STATUS_0_HOST_IPC_FIFO_INT_MASK BIT_MASK(4)
142#define MTL_VPU_HOST_SS_ICB_STATUS_0_MMU_IRQ_0_INT_MASK BIT_MASK(5)
143#define MTL_VPU_HOST_SS_ICB_STATUS_0_MMU_IRQ_1_INT_MASK BIT_MASK(6)
144#define MTL_VPU_HOST_SS_ICB_STATUS_0_MMU_IRQ_2_INT_MASK BIT_MASK(7)
145#define MTL_VPU_HOST_SS_ICB_STATUS_0_NOC_FIREWALL_INT_MASK BIT_MASK(8)
146#define MTL_VPU_HOST_SS_ICB_STATUS_0_CPU_INT_REDIRECT_0_INT_MASK BIT_MASK(30)
147#define MTL_VPU_HOST_SS_ICB_STATUS_0_CPU_INT_REDIRECT_1_INT_MASK BIT_MASK(31)
148
149#define MTL_VPU_HOST_SS_ICB_STATUS_1 0x00010214u
150#define MTL_VPU_HOST_SS_ICB_STATUS_1_CPU_INT_REDIRECT_2_INT_MASK BIT_MASK(0)
151#define MTL_VPU_HOST_SS_ICB_STATUS_1_CPU_INT_REDIRECT_3_INT_MASK BIT_MASK(1)
152#define MTL_VPU_HOST_SS_ICB_STATUS_1_CPU_INT_REDIRECT_4_INT_MASK BIT_MASK(2)
153
154#define MTL_VPU_HOST_SS_ICB_CLEAR_0 0x00010220u
155#define MTL_VPU_HOST_SS_ICB_CLEAR_1 0x00010224u
156#define MTL_VPU_HOST_SS_ICB_ENABLE_0 0x00010240u
157
158#define MTL_VPU_HOST_SS_TIM_IPC_FIFO_ATM 0x000200f4u
159
160#define MTL_VPU_HOST_SS_TIM_IPC_FIFO_STAT 0x000200fcu
161#define MTL_VPU_HOST_SS_TIM_IPC_FIFO_STAT_READ_POINTER_MASK GENMASK(7, 0)
162#define MTL_VPU_HOST_SS_TIM_IPC_FIFO_STAT_WRITE_POINTER_MASK GENMASK(15, 8)
163#define MTL_VPU_HOST_SS_TIM_IPC_FIFO_STAT_FILL_LEVEL_MASK GENMASK(23, 16)
164#define MTL_VPU_HOST_SS_TIM_IPC_FIFO_STAT_RSVD0_MASK GENMASK(31, 24)
165
166#define MTL_VPU_HOST_SS_AON_PWR_ISO_EN0 0x00030020u
167#define MTL_VPU_HOST_SS_AON_PWR_ISO_EN0_MSS_CPU_MASK BIT_MASK(3)
168
169#define MTL_VPU_HOST_SS_AON_PWR_ISLAND_EN0 0x00030024u
170#define MTL_VPU_HOST_SS_AON_PWR_ISLAND_EN0_MSS_CPU_MASK BIT_MASK(3)
171
172#define MTL_VPU_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0 0x00030028u
173#define MTL_VPU_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0_MSS_CPU_MASK BIT_MASK(3)
174
175#define MTL_VPU_HOST_SS_AON_PWR_ISLAND_STATUS0 0x0003002cu
176#define MTL_VPU_HOST_SS_AON_PWR_ISLAND_STATUS0_MSS_CPU_MASK BIT_MASK(3)
177
178#define MTL_VPU_HOST_SS_AON_VPU_IDLE_GEN 0x00030200u
179#define MTL_VPU_HOST_SS_AON_VPU_IDLE_GEN_EN_MASK BIT_MASK(0)
180
181#define MTL_VPU_HOST_SS_AON_DPU_ACTIVE 0x00030204u
182#define MTL_VPU_HOST_SS_AON_DPU_ACTIVE_DPU_ACTIVE_MASK BIT_MASK(0)
183
184#define MTL_VPU_HOST_SS_LOADING_ADDRESS_LO 0x00041040u
185#define MTL_VPU_HOST_SS_LOADING_ADDRESS_LO_DONE_MASK BIT_MASK(0)
186#define MTL_VPU_HOST_SS_LOADING_ADDRESS_LO_IOSF_RS_ID_MASK GENMASK(2, 1)
187#define MTL_VPU_HOST_SS_LOADING_ADDRESS_LO_IMAGE_LOCATION_MASK GENMASK(31, 3)
188
189#define MTL_VPU_HOST_SS_WORKPOINT_CONFIG_MIRROR 0x00082020u
190#define MTL_VPU_HOST_SS_WORKPOINT_CONFIG_MIRROR_FINAL_PLL_FREQ_MASK GENMASK(15, 0)
191#define MTL_VPU_HOST_SS_WORKPOINT_CONFIG_MIRROR_CONFIG_ID_MASK GENMASK(31, 16)
192
193#define MTL_VPU_HOST_MMU_IDR0 0x00200000u
194#define MTL_VPU_HOST_MMU_IDR1 0x00200004u
195#define MTL_VPU_HOST_MMU_IDR3 0x0020000cu
196#define MTL_VPU_HOST_MMU_IDR5 0x00200014u
197#define MTL_VPU_HOST_MMU_CR0 0x00200020u
198#define MTL_VPU_HOST_MMU_CR0ACK 0x00200024u
199#define MTL_VPU_HOST_MMU_CR1 0x00200028u
200#define MTL_VPU_HOST_MMU_CR2 0x0020002cu
201#define MTL_VPU_HOST_MMU_IRQ_CTRL 0x00200050u
202#define MTL_VPU_HOST_MMU_IRQ_CTRLACK 0x00200054u
203
204#define MTL_VPU_HOST_MMU_GERROR 0x00200060u
205#define MTL_VPU_HOST_MMU_GERROR_CMDQ_MASK BIT_MASK(0)
206#define MTL_VPU_HOST_MMU_GERROR_EVTQ_ABT_MASK BIT_MASK(2)
207#define MTL_VPU_HOST_MMU_GERROR_PRIQ_ABT_MASK BIT_MASK(3)
208#define MTL_VPU_HOST_MMU_GERROR_MSI_CMDQ_ABT_MASK BIT_MASK(4)
209#define MTL_VPU_HOST_MMU_GERROR_MSI_EVTQ_ABT_MASK BIT_MASK(5)
210#define MTL_VPU_HOST_MMU_GERROR_MSI_PRIQ_ABT_MASK BIT_MASK(6)
211#define MTL_VPU_HOST_MMU_GERROR_MSI_ABT_MASK BIT_MASK(7)
212
213#define MTL_VPU_HOST_MMU_GERRORN 0x00200064u
214
215#define MTL_VPU_HOST_MMU_STRTAB_BASE 0x00200080u
216#define MTL_VPU_HOST_MMU_STRTAB_BASE_CFG 0x00200088u
217#define MTL_VPU_HOST_MMU_CMDQ_BASE 0x00200090u
218#define MTL_VPU_HOST_MMU_CMDQ_PROD 0x00200098u
219#define MTL_VPU_HOST_MMU_CMDQ_CONS 0x0020009cu
220#define MTL_VPU_HOST_MMU_EVTQ_BASE 0x002000a0u
221#define MTL_VPU_HOST_MMU_EVTQ_PROD 0x002000a8u
222#define MTL_VPU_HOST_MMU_EVTQ_CONS 0x002000acu
223#define MTL_VPU_HOST_MMU_EVTQ_PROD_SEC (0x002000a8u + SZ_64K)
224#define MTL_VPU_HOST_MMU_EVTQ_CONS_SEC (0x002000acu + SZ_64K)
225
226#define MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES 0x00360000u
227#define MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES_CACHE_OVERRIDE_EN_MASK BIT_MASK(0)
228#define MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES_AWCACHE_OVERRIDE_MASK BIT_MASK(1)
229#define MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES_ARCACHE_OVERRIDE_MASK BIT_MASK(2)
230#define MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES_NOSNOOP_OVERRIDE_EN_MASK BIT_MASK(3)
231#define MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES_AW_NOSNOOP_OVERRIDE_MASK BIT_MASK(4)
232#define MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES_AR_NOSNOOP_OVERRIDE_MASK BIT_MASK(5)
233#define MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES_PTW_AW_CONTEXT_FLAG_MASK GENMASK(10, 6)
234#define MTL_VPU_HOST_IF_TCU_PTW_OVERRIDES_PTW_AR_CONTEXT_FLAG_MASK GENMASK(15, 11)
235
236#define MTL_VPU_HOST_IF_TBU_MMUSSIDV 0x00360004u
237#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU0_AWMMUSSIDV_MASK BIT_MASK(0)
238#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU0_ARMMUSSIDV_MASK BIT_MASK(1)
239#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU1_AWMMUSSIDV_MASK BIT_MASK(2)
240#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU1_ARMMUSSIDV_MASK BIT_MASK(3)
241#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU2_AWMMUSSIDV_MASK BIT_MASK(4)
242#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU2_ARMMUSSIDV_MASK BIT_MASK(5)
243#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU3_AWMMUSSIDV_MASK BIT_MASK(6)
244#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU3_ARMMUSSIDV_MASK BIT_MASK(7)
245#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU4_AWMMUSSIDV_MASK BIT_MASK(8)
246#define MTL_VPU_HOST_IF_TBU_MMUSSIDV_TBU4_ARMMUSSIDV_MASK BIT_MASK(9)
247
248#define MTL_VPU_CPU_SS_DSU_LEON_RT_BASE 0x04000000u
249#define MTL_VPU_CPU_SS_DSU_LEON_RT_DSU_CTRL 0x04000000u
250#define MTL_VPU_CPU_SS_DSU_LEON_RT_PC_REG 0x04400010u
251#define MTL_VPU_CPU_SS_DSU_LEON_RT_NPC_REG 0x04400014u
252#define MTL_VPU_CPU_SS_DSU_LEON_RT_DSU_TRAP_REG 0x04400020u
253
254#define MTL_VPU_CPU_SS_MSSCPU_CPR_CLK_SET 0x06010004u
255#define MTL_VPU_CPU_SS_MSSCPU_CPR_CLK_SET_CPU_DSU_MASK BIT_MASK(1)
256
257#define MTL_VPU_CPU_SS_MSSCPU_CPR_RST_CLR 0x06010018u
258#define MTL_VPU_CPU_SS_MSSCPU_CPR_RST_CLR_CPU_DSU_MASK BIT_MASK(1)
259
260#define MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC 0x06010040u
261#define MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC_IRQI_RSTRUN0_MASK BIT_MASK(0)
262#define MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC_IRQI_RESUME0_MASK BIT_MASK(1)
263#define MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC_IRQI_RSTRUN1_MASK BIT_MASK(2)
264#define MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC_IRQI_RESUME1_MASK BIT_MASK(3)
265#define MTL_VPU_CPU_SS_MSSCPU_CPR_LEON_RT_VEC_IRQI_RSTVEC_MASK GENMASK(31, 4)
266
267#define MTL_VPU_CPU_SS_TIM_WATCHDOG 0x0602009cu
268#define MTL_VPU_CPU_SS_TIM_WDOG_EN 0x060200a4u
269#define MTL_VPU_CPU_SS_TIM_SAFE 0x060200a8u
270#define MTL_VPU_CPU_SS_TIM_IPC_FIFO 0x060200f0u
271
272#define MTL_VPU_CPU_SS_TIM_GEN_CONFIG 0x06021008u
273#define MTL_VPU_CPU_SS_TIM_GEN_CONFIG_WDOG_TO_INT_CLR_MASK BIT_MASK(9)
274
275#define MTL_VPU_CPU_SS_DOORBELL_0 0x06300000u
276#define MTL_VPU_CPU_SS_DOORBELL_0_SET_MASK BIT_MASK(0)
277
278#define MTL_VPU_CPU_SS_DOORBELL_1 0x06301000u
279
280#endif /* __IVPU_HW_MTL_REG_H__ */
drivers/accel/ivpu/ivpu_hw_reg_io.h+115−0
@@ -0,0 +1,115 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2020-2023 Intel Corporation
4 */
5
6#ifndef __IVPU_HW_REG_IO_H__
7#define __IVPU_HW_REG_IO_H__
8
9#include <linux/bitfield.h>
10#include <linux/io.h>
11#include <linux/iopoll.h>
12
13#include "ivpu_drv.h"
14
15#define REG_POLL_SLEEP_US 50
16#define REG_IO_ERROR 0xffffffff
17
18#define REGB_RD32(reg) ivpu_hw_reg_rd32(vdev, vdev->regb, (reg), #reg, __func__)
19#define REGB_RD32_SILENT(reg) readl(vdev->regb + (reg))
20#define REGB_RD64(reg) ivpu_hw_reg_rd64(vdev, vdev->regb, (reg), #reg, __func__)
21#define REGB_WR32(reg, val) ivpu_hw_reg_wr32(vdev, vdev->regb, (reg), (val), #reg, __func__)
22#define REGB_WR64(reg, val) ivpu_hw_reg_wr64(vdev, vdev->regb, (reg), (val), #reg, __func__)
23
24#define REGV_RD32(reg) ivpu_hw_reg_rd32(vdev, vdev->regv, (reg), #reg, __func__)
25#define REGV_RD32_SILENT(reg) readl(vdev->regv + (reg))
26#define REGV_RD64(reg) ivpu_hw_reg_rd64(vdev, vdev->regv, (reg), #reg, __func__)
27#define REGV_WR32(reg, val) ivpu_hw_reg_wr32(vdev, vdev->regv, (reg), (val), #reg, __func__)
28#define REGV_WR64(reg, val) ivpu_hw_reg_wr64(vdev, vdev->regv, (reg), (val), #reg, __func__)
29
30#define REGV_WR32I(reg, stride, index, val) \
31 ivpu_hw_reg_wr32_index(vdev, vdev->regv, (reg), (stride), (index), (val), #reg, __func__)
32
33#define REG_FLD(REG, FLD) \
34 (REG##_##FLD##_MASK)
35#define REG_FLD_NUM(REG, FLD, num) \
36 FIELD_PREP(REG##_##FLD##_MASK, num)
37#define REG_GET_FLD(REG, FLD, val) \
38 FIELD_GET(REG##_##FLD##_MASK, val)
39#define REG_CLR_FLD(REG, FLD, val) \
40 ((val) & ~(REG##_##FLD##_MASK))
41#define REG_SET_FLD(REG, FLD, val) \
42 ((val) | (REG##_##FLD##_MASK))
43#define REG_SET_FLD_NUM(REG, FLD, num, val) \
44 (((val) & ~(REG##_##FLD##_MASK)) | FIELD_PREP(REG##_##FLD##_MASK, num))
45#define REG_TEST_FLD(REG, FLD, val) \
46 ((REG##_##FLD##_MASK) == ((val) & (REG##_##FLD##_MASK)))
47#define REG_TEST_FLD_NUM(REG, FLD, num, val) \
48 ((num) == FIELD_GET(REG##_##FLD##_MASK, val))
49
50#define REGB_POLL(reg, var, cond, timeout_us) \
51 read_poll_timeout(REGB_RD32_SILENT, var, cond, REG_POLL_SLEEP_US, timeout_us, false, reg)
52
53#define REGV_POLL(reg, var, cond, timeout_us) \
54 read_poll_timeout(REGV_RD32_SILENT, var, cond, REG_POLL_SLEEP_US, timeout_us, false, reg)
55
56#define REGB_POLL_FLD(reg, fld, val, timeout_us) \
57({ \
58 u32 var; \
59 REGB_POLL(reg, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)), timeout_us); \
60})
61
62#define REGV_POLL_FLD(reg, fld, val, timeout_us) \
63({ \
64 u32 var; \
65 REGV_POLL(reg, var, (FIELD_GET(reg##_##fld##_MASK, var) == (val)), timeout_us); \
66})
67
68static inline u32
69ivpu_hw_reg_rd32(struct ivpu_device *vdev, void __iomem *base, u32 reg,
70 const char *name, const char *func)
71{
72 u32 val = readl(base + reg);
73
74 ivpu_dbg(vdev, REG, "%s RD: %s (0x%08x) => 0x%08x\n", func, name, reg, val);
75 return val;
76}
77
78static inline u64
79ivpu_hw_reg_rd64(struct ivpu_device *vdev, void __iomem *base, u32 reg,
80 const char *name, const char *func)
81{
82 u64 val = readq(base + reg);
83
84 ivpu_dbg(vdev, REG, "%s RD: %s (0x%08x) => 0x%016llx\n", func, name, reg, val);
85 return val;
86}
87
88static inline void
89ivpu_hw_reg_wr32(struct ivpu_device *vdev, void __iomem *base, u32 reg, u32 val,
90 const char *name, const char *func)
91{
92 ivpu_dbg(vdev, REG, "%s WR: %s (0x%08x) <= 0x%08x\n", func, name, reg, val);
93 writel(val, base + reg);
94}
95
96static inline void
97ivpu_hw_reg_wr64(struct ivpu_device *vdev, void __iomem *base, u32 reg, u64 val,
98 const char *name, const char *func)
99{
100 ivpu_dbg(vdev, REG, "%s WR: %s (0x%08x) <= 0x%016llx\n", func, name, reg, val);
101 writeq(val, base + reg);
102}
103
104static inline void
105ivpu_hw_reg_wr32_index(struct ivpu_device *vdev, void __iomem *base, u32 reg,
106 u32 stride, u32 index, u32 val, const char *name,
107 const char *func)
108{
109 reg += index * stride;
110
111 ivpu_dbg(vdev, REG, "%s WR: %s_%d (0x%08x) <= 0x%08x\n", func, name, index, reg, val);
112 writel(val, base + reg);
113}
114
115#endif /* __IVPU_HW_REG_IO_H__ */
include/uapi/drm/ivpu_accel.h+95−0
@@ -0,0 +1,95 @@
1/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
2/*
3 * Copyright (C) 2020-2023 Intel Corporation
4 */
5
6#ifndef __UAPI_IVPU_DRM_H__
7#define __UAPI_IVPU_DRM_H__
8
9#include "drm.h"
10
11#if defined(__cplusplus)
12extern "C" {
13#endif
14
15#define DRM_IVPU_DRIVER_MAJOR 1
16#define DRM_IVPU_DRIVER_MINOR 0
17
18#define DRM_IVPU_GET_PARAM 0x00
19#define DRM_IVPU_SET_PARAM 0x01
20
21#define DRM_IOCTL_IVPU_GET_PARAM \
22 DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_GET_PARAM, struct drm_ivpu_param)
23
24#define DRM_IOCTL_IVPU_SET_PARAM \
25 DRM_IOW(DRM_COMMAND_BASE + DRM_IVPU_SET_PARAM, struct drm_ivpu_param)
26
27/**
28 * DOC: contexts
29 *
30 * VPU contexts have private virtual address space, job queues and priority.
31 * Each context is identified by an unique ID. Context is created on open().
32 */
33
34#define DRM_IVPU_PARAM_DEVICE_ID 0
35#define DRM_IVPU_PARAM_DEVICE_REVISION 1
36#define DRM_IVPU_PARAM_PLATFORM_TYPE 2
37#define DRM_IVPU_PARAM_CORE_CLOCK_RATE 3
38#define DRM_IVPU_PARAM_NUM_CONTEXTS 4
39#define DRM_IVPU_PARAM_CONTEXT_BASE_ADDRESS 5
40#define DRM_IVPU_PARAM_CONTEXT_PRIORITY 6
41
42#define DRM_IVPU_PLATFORM_TYPE_SILICON 0
43
44#define DRM_IVPU_CONTEXT_PRIORITY_IDLE 0
45#define DRM_IVPU_CONTEXT_PRIORITY_NORMAL 1
46#define DRM_IVPU_CONTEXT_PRIORITY_FOCUS 2
47#define DRM_IVPU_CONTEXT_PRIORITY_REALTIME 3
48
49/**
50 * struct drm_ivpu_param - Get/Set VPU parameters
51 */
52struct drm_ivpu_param {
53 /**
54 * @param:
55 *
56 * Supported params:
57 *
58 * %DRM_IVPU_PARAM_DEVICE_ID:
59 * PCI Device ID of the VPU device (read-only)
60 *
61 * %DRM_IVPU_PARAM_DEVICE_REVISION:
62 * VPU device revision (read-only)
63 *
64 * %DRM_IVPU_PARAM_PLATFORM_TYPE:
65 * Returns %DRM_IVPU_PLATFORM_TYPE_SILICON on real hardware or device specific
66 * platform type when executing on a simulator or emulator (read-only)
67 *
68 * %DRM_IVPU_PARAM_CORE_CLOCK_RATE:
69 * Current PLL frequency (read-only)
70 *
71 * %DRM_IVPU_PARAM_NUM_CONTEXTS:
72 * Maximum number of simultaneously existing contexts (read-only)
73 *
74 * %DRM_IVPU_PARAM_CONTEXT_BASE_ADDRESS:
75 * Lowest VPU virtual address available in the current context (read-only)
76 *
77 * %DRM_IVPU_PARAM_CONTEXT_PRIORITY:
78 * Value of current context scheduling priority (read-write).
79 * See DRM_IVPU_CONTEXT_PRIORITY_* for possible values.
80 *
81 */
82 __u32 param;
83
84 /** @index: Index for params that have multiple instances */
85 __u32 index;
86
87 /** @value: Param value */
88 __u64 value;
89};
90
91#if defined(__cplusplus)
92}
93#endif
94
95#endif /* __UAPI_IVPU_DRM_H__ */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t