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
68946894 F: Documentation/accel/
68956895 F: drivers/accel/
68966896
6897+DRM ACCEL DRIVERS FOR INTEL VPU
6898+M: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
6899+M: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
6900+L: dri-devel@lists.freedesktop.org
6901+S: Supported
6902+T: git git://anongit.freedesktop.org/drm/drm-misc
6903+F: drivers/accel/ivpu/
6904+F: include/uapi/drm/ivpu_accel.h
6905+
68976906 DRM DRIVERS FOR ALLWINNER A10
68986907 M: Maxime Ripard <mripard@kernel.org>
68996908 M: Chen-Yu Tsai <wens@csie.org>
drivers/Makefile+1−0
@@ -189,3 +189,4 @@ obj-$(CONFIG_COUNTER) += counter/ · 188 unmodified lines
189189 obj-$(CONFIG_MOST) += most/
190190 obj-$(CONFIG_PECI) += peci/
191191 obj-$(CONFIG_HTE) += hte/
192+obj-$(CONFIG_DRM_ACCEL) += accel/
drivers/accel/Kconfig+2−0
@@ -22,3 +22,5 @@ menuconfig DRM_ACCEL · 21 unmodified lines
2222 major number than GPUs, and will be exposed to user-space using
2323 different device files, called accel/accel* (in /dev, sysfs
2424 and debugfs).
25+
26+source "drivers/accel/ivpu/Kconfig"
drivers/accel/Makefile+3−0
@@ -0,0 +1,3 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+
3+obj-y += ivpu/
drivers/accel/ivpu/Kconfig+15−0
@@ -0,0 +1,15 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+
3+config 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+
4+intel_vpu-y := \
5+ ivpu_drv.o \
6+ ivpu_hw_mtl.o
7+
8+obj-$(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+
24+static const struct drm_driver driver;
25+
26+int ivpu_dbg_mask;
27+module_param_named(dbg_mask, ivpu_dbg_mask, int, 0644);
28+MODULE_PARM_DESC(dbg_mask, "Driver debug mask. See IVPU_DBG_* macros.");
29+
30+u8 ivpu_pll_min_ratio;
31+module_param_named(pll_min_ratio, ivpu_pll_min_ratio, byte, 0644);
32+MODULE_PARM_DESC(pll_min_ratio, "Minimum PLL ratio used to set VPU frequency");
33+
34+u8 ivpu_pll_max_ratio = U8_MAX;
35+module_param_named(pll_max_ratio, ivpu_pll_max_ratio, byte, 0644);
36+MODULE_PARM_DESC(pll_max_ratio, "Maximum PLL ratio used to set VPU frequency");
37+
38+struct 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+
44+static 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+
51+void 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+
61+static 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+
99+static 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+
119+static 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+
136+static 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+
143+static 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+
148+int 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+
161+static const struct file_operations ivpu_fops = {
162+ .owner = THIS_MODULE,
163+ .mmap = drm_gem_mmap,
164+ DRM_ACCEL_FOPS,
165+};
166+
167+static 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+
184+static 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+
205+static 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+
246+static 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+
288+err_xa_destroy:
289+ xa_destroy(&vdev->context_xa);
290+ return ret;
291+}
292+
293+static 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+
301+static struct pci_device_id ivpu_pci_ids[] = {
302+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) },
303+ { }
304+};
305+MODULE_DEVICE_TABLE(pci, ivpu_pci_ids);
306+
307+static 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+
333+static 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+
341+static 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+
348+module_pci_driver(ivpu_pci_driver);
349+
350+MODULE_AUTHOR("Intel Corporation");
351+MODULE_DESCRIPTION(DRIVER_DESC);
352+MODULE_LICENSE("GPL and additional rights");
353+MODULE_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+
68+struct ivpu_wa_table {
69+ bool punit_disabled;
70+ bool clear_runtime_mem;
71+};
72+
73+struct ivpu_hw_info;
74+
75+struct 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+ */
100+struct ivpu_file_priv {
101+ struct kref ref;
102+ struct ivpu_device *vdev;
103+ u32 priority;
104+};
105+
106+extern int ivpu_dbg_mask;
107+extern u8 ivpu_pll_min_ratio;
108+extern u8 ivpu_pll_max_ratio;
109+
110+struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv);
111+void ivpu_file_priv_put(struct ivpu_file_priv **link);
112+int ivpu_shutdown(struct ivpu_device *vdev);
113+
114+static 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+
119+static inline u8 ivpu_revision(struct ivpu_device *vdev)
120+{
121+ return to_pci_dev(vdev->drm.dev)->revision;
122+}
123+
124+static inline u16 ivpu_device_id(struct ivpu_device *vdev)
125+{
126+ return to_pci_dev(vdev->drm.dev)->device;
127+}
128+
129+static inline struct ivpu_device *to_ivpu_device(struct drm_device *dev)
130+{
131+ return container_of(dev, struct ivpu_device, drm);
132+}
133+
134+static 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+
141+static 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+
147+static inline bool ivpu_is_silicon(struct ivpu_device *vdev)
148+{
149+ return ivpu_get_platform(vdev) == IVPU_PLATFORM_SILICON;
150+}
151+
152+static inline bool ivpu_is_simics(struct ivpu_device *vdev)
153+{
154+ return ivpu_get_platform(vdev) == IVPU_PLATFORM_SIMICS;
155+}
156+
157+static 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+
11+struct 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+
33+struct ivpu_addr_range {
34+ resource_size_t start;
35+ resource_size_t end;
36+};
37+
38+struct 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+
62+extern const struct ivpu_hw_ops ivpu_hw_mtl_ops;
63+
64+static inline int ivpu_hw_info_init(struct ivpu_device *vdev)
65+{
66+ return vdev->hw->ops->info_init(vdev);
67+};
68+
69+static 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+
76+static inline int ivpu_hw_boot_fw(struct ivpu_device *vdev)
77+{
78+ return vdev->hw->ops->boot_fw(vdev);
79+};
80+
81+static inline bool ivpu_hw_is_idle(struct ivpu_device *vdev)
82+{
83+ return vdev->hw->ops->is_idle(vdev);
84+};
85+
86+static 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+
93+static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev)
94+{
95+ vdev->hw->ops->wdt_disable(vdev);
96+};
97+
98+/* Register indirect accesses */
99+static 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+
104+static 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+
109+static 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+
114+static 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+
119+static 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+
124+static 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+
129+static 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+
134+static 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+
139+static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
140+{
141+ vdev->hw->ops->irq_clear(vdev);
142+};
143+
144+static inline void ivpu_hw_irq_enable(struct ivpu_device *vdev)
145+{
146+ vdev->hw->ops->irq_enable(vdev);
147+};
148+
149+static inline void ivpu_hw_irq_disable(struct ivpu_device *vdev)
150+{
151+ vdev->hw->ops->irq_disable(vdev);
152+};
153+
154+static 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+
160+static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range)
161+{
162+ return range->end - range->start;
163+}
164+
165+static 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+
68+static 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+
82+static 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+
96+static 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+
102+static 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+
117+static 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 */
123+static 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+
160+static 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+
170+static 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+
178+static 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+
196+static 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+
242+static int ivpu_pll_enable(struct ivpu_device *vdev)
243+{
244+ return ivpu_pll_drive(vdev, true);
245+}
246+
247+static int ivpu_pll_disable(struct ivpu_device *vdev)
248+{
249+ return ivpu_pll_drive(vdev, false);
250+}
251+
252+static 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+
263+static 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+
280+static 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+
297+static 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+
307+static 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+
317+static 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+
327+static 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+
338+static 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+
349+static 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+
360+static 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+
367+static 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+
372+static 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+
397+static int ivpu_boot_host_ss_axi_enable(struct ivpu_device *vdev)
398+{
399+ return ivpu_boot_host_ss_axi_drive(vdev, true);
400+}
401+
402+static int ivpu_boot_host_ss_axi_disable(struct ivpu_device *vdev)
403+{
404+ return ivpu_boot_host_ss_axi_drive(vdev, false);
405+}
406+
407+static 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+
435+static 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+
440+static 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+
445+static 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+
457+static 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+
469+static 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+
479+static 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+
491+static 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+
503+static 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+
513+static 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+
540+static 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+
551+static 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+
574+static 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+
591+static 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+
616+static 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+
659+static 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+
684+static 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+
697+static 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+
708+static 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+
762+static 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+
771+static 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+
783+static 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+
816+static 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 */
835+static 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+
848+static u32 ivpu_hw_mtl_reg_telemetry_offset_get(struct ivpu_device *vdev)
849+{
850+ return REGB_RD32(MTL_BUTTRESS_VPU_TELEMETRY_OFFSET);
851+}
852+
853+static u32 ivpu_hw_mtl_reg_telemetry_size_get(struct ivpu_device *vdev)
854+{
855+ return REGB_RD32(MTL_BUTTRESS_VPU_TELEMETRY_SIZE);
856+}
857+
858+static u32 ivpu_hw_mtl_reg_telemetry_enable_get(struct ivpu_device *vdev)
859+{
860+ return REGB_RD32(MTL_BUTTRESS_VPU_TELEMETRY_ENABLE);
861+}
862+
863+static 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+
871+static 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+
876+static 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+
883+static 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+
888+static 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+
893+static 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+
901+static 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+
909+static void ivpu_hw_mtl_irq_wdt_nce_handler(struct ivpu_device *vdev)
910+{
911+ ivpu_err_ratelimited(vdev, "WDT NCE irq\n");
912+}
913+
914+static 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+
921+static 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) */
927+static 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) */
946+static 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+
987+static 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+
998+static 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+
1028+const 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+
68+static inline u32
69+ivpu_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+
78+static inline u64
79+ivpu_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+
88+static inline void
89+ivpu_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+
96+static inline void
97+ivpu_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+
104+static inline void
105+ivpu_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)
12+extern "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+ */
52+struct 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