162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2020-2023 Intel Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __IVPU_DRV_H__ 762306a36Sopenharmony_ci#define __IVPU_DRV_H__ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <drm/drm_device.h> 1062306a36Sopenharmony_ci#include <drm/drm_drv.h> 1162306a36Sopenharmony_ci#include <drm/drm_managed.h> 1262306a36Sopenharmony_ci#include <drm/drm_mm.h> 1362306a36Sopenharmony_ci#include <drm/drm_print.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/pci.h> 1662306a36Sopenharmony_ci#include <linux/xarray.h> 1762306a36Sopenharmony_ci#include <uapi/drm/ivpu_accel.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "ivpu_mmu_context.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define DRIVER_NAME "intel_vpu" 2262306a36Sopenharmony_ci#define DRIVER_DESC "Driver for Intel Versatile Processing Unit (VPU)" 2362306a36Sopenharmony_ci#define DRIVER_DATE "20230117" 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define PCI_DEVICE_ID_MTL 0x7d1d 2662306a36Sopenharmony_ci#define PCI_DEVICE_ID_ARL 0xad1d 2762306a36Sopenharmony_ci#define PCI_DEVICE_ID_LNL 0x643e 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define IVPU_HW_37XX 37 3062306a36Sopenharmony_ci#define IVPU_HW_40XX 40 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define IVPU_GLOBAL_CONTEXT_MMU_SSID 0 3362306a36Sopenharmony_ci/* SSID 1 is used by the VPU to represent invalid context */ 3462306a36Sopenharmony_ci#define IVPU_USER_CONTEXT_MIN_SSID 2 3562306a36Sopenharmony_ci#define IVPU_USER_CONTEXT_MAX_SSID (IVPU_USER_CONTEXT_MIN_SSID + 63) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#define IVPU_NUM_ENGINES 2 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#define IVPU_PLATFORM_SILICON 0 4062306a36Sopenharmony_ci#define IVPU_PLATFORM_SIMICS 2 4162306a36Sopenharmony_ci#define IVPU_PLATFORM_FPGA 3 4262306a36Sopenharmony_ci#define IVPU_PLATFORM_INVALID 8 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#define IVPU_DBG_REG BIT(0) 4562306a36Sopenharmony_ci#define IVPU_DBG_IRQ BIT(1) 4662306a36Sopenharmony_ci#define IVPU_DBG_MMU BIT(2) 4762306a36Sopenharmony_ci#define IVPU_DBG_FILE BIT(3) 4862306a36Sopenharmony_ci#define IVPU_DBG_MISC BIT(4) 4962306a36Sopenharmony_ci#define IVPU_DBG_FW_BOOT BIT(5) 5062306a36Sopenharmony_ci#define IVPU_DBG_PM BIT(6) 5162306a36Sopenharmony_ci#define IVPU_DBG_IPC BIT(7) 5262306a36Sopenharmony_ci#define IVPU_DBG_BO BIT(8) 5362306a36Sopenharmony_ci#define IVPU_DBG_JOB BIT(9) 5462306a36Sopenharmony_ci#define IVPU_DBG_JSM BIT(10) 5562306a36Sopenharmony_ci#define IVPU_DBG_KREF BIT(11) 5662306a36Sopenharmony_ci#define IVPU_DBG_RPM BIT(12) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci#define ivpu_err(vdev, fmt, ...) \ 5962306a36Sopenharmony_ci drm_err(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define ivpu_err_ratelimited(vdev, fmt, ...) \ 6262306a36Sopenharmony_ci drm_err_ratelimited(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci#define ivpu_warn(vdev, fmt, ...) \ 6562306a36Sopenharmony_ci drm_warn(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci#define ivpu_warn_ratelimited(vdev, fmt, ...) \ 6862306a36Sopenharmony_ci drm_err_ratelimited(&(vdev)->drm, "%s(): " fmt, __func__, ##__VA_ARGS__) 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci#define ivpu_info(vdev, fmt, ...) drm_info(&(vdev)->drm, fmt, ##__VA_ARGS__) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#define ivpu_dbg(vdev, type, fmt, args...) do { \ 7362306a36Sopenharmony_ci if (unlikely(IVPU_DBG_##type & ivpu_dbg_mask)) \ 7462306a36Sopenharmony_ci dev_dbg((vdev)->drm.dev, "[%s] " fmt, #type, ##args); \ 7562306a36Sopenharmony_ci} while (0) 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci#define IVPU_WA(wa_name) (vdev->wa.wa_name) 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci#define IVPU_PRINT_WA(wa_name) do { \ 8062306a36Sopenharmony_ci if (IVPU_WA(wa_name)) \ 8162306a36Sopenharmony_ci ivpu_dbg(vdev, MISC, "Using WA: " #wa_name "\n"); \ 8262306a36Sopenharmony_ci} while (0) 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistruct ivpu_wa_table { 8562306a36Sopenharmony_ci bool punit_disabled; 8662306a36Sopenharmony_ci bool clear_runtime_mem; 8762306a36Sopenharmony_ci bool d3hot_after_power_off; 8862306a36Sopenharmony_ci bool interrupt_clear_with_0; 8962306a36Sopenharmony_ci bool disable_clock_relinquish; 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistruct ivpu_hw_info; 9362306a36Sopenharmony_cistruct ivpu_mmu_info; 9462306a36Sopenharmony_cistruct ivpu_fw_info; 9562306a36Sopenharmony_cistruct ivpu_ipc_info; 9662306a36Sopenharmony_cistruct ivpu_pm_info; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistruct ivpu_device { 9962306a36Sopenharmony_ci struct drm_device drm; 10062306a36Sopenharmony_ci void __iomem *regb; 10162306a36Sopenharmony_ci void __iomem *regv; 10262306a36Sopenharmony_ci u32 platform; 10362306a36Sopenharmony_ci u32 irq; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci struct ivpu_wa_table wa; 10662306a36Sopenharmony_ci struct ivpu_hw_info *hw; 10762306a36Sopenharmony_ci struct ivpu_mmu_info *mmu; 10862306a36Sopenharmony_ci struct ivpu_fw_info *fw; 10962306a36Sopenharmony_ci struct ivpu_ipc_info *ipc; 11062306a36Sopenharmony_ci struct ivpu_pm_info *pm; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci struct ivpu_mmu_context gctx; 11362306a36Sopenharmony_ci struct xarray context_xa; 11462306a36Sopenharmony_ci struct xa_limit context_xa_limit; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci struct xarray submitted_jobs_xa; 11762306a36Sopenharmony_ci struct task_struct *job_done_thread; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci atomic64_t unique_id_counter; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci struct { 12262306a36Sopenharmony_ci int boot; 12362306a36Sopenharmony_ci int jsm; 12462306a36Sopenharmony_ci int tdr; 12562306a36Sopenharmony_ci int reschedule_suspend; 12662306a36Sopenharmony_ci } timeout; 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci/* 13062306a36Sopenharmony_ci * file_priv has its own refcount (ref) that allows user space to close the fd 13162306a36Sopenharmony_ci * without blocking even if VPU is still processing some jobs. 13262306a36Sopenharmony_ci */ 13362306a36Sopenharmony_cistruct ivpu_file_priv { 13462306a36Sopenharmony_ci struct kref ref; 13562306a36Sopenharmony_ci struct ivpu_device *vdev; 13662306a36Sopenharmony_ci struct mutex lock; /* Protects cmdq */ 13762306a36Sopenharmony_ci struct ivpu_cmdq *cmdq[IVPU_NUM_ENGINES]; 13862306a36Sopenharmony_ci struct ivpu_mmu_context ctx; 13962306a36Sopenharmony_ci u32 priority; 14062306a36Sopenharmony_ci bool has_mmu_faults; 14162306a36Sopenharmony_ci}; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ciextern int ivpu_dbg_mask; 14462306a36Sopenharmony_ciextern u8 ivpu_pll_min_ratio; 14562306a36Sopenharmony_ciextern u8 ivpu_pll_max_ratio; 14662306a36Sopenharmony_ciextern bool ivpu_disable_mmu_cont_pages; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci#define IVPU_TEST_MODE_DISABLED 0 14962306a36Sopenharmony_ci#define IVPU_TEST_MODE_FW_TEST 1 15062306a36Sopenharmony_ci#define IVPU_TEST_MODE_NULL_HW 2 15162306a36Sopenharmony_ciextern int ivpu_test_mode; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistruct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv); 15462306a36Sopenharmony_cistruct ivpu_file_priv *ivpu_file_priv_get_by_ctx_id(struct ivpu_device *vdev, unsigned long id); 15562306a36Sopenharmony_civoid ivpu_file_priv_put(struct ivpu_file_priv **link); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ciint ivpu_boot(struct ivpu_device *vdev); 15862306a36Sopenharmony_ciint ivpu_shutdown(struct ivpu_device *vdev); 15962306a36Sopenharmony_civoid ivpu_prepare_for_reset(struct ivpu_device *vdev); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic inline u8 ivpu_revision(struct ivpu_device *vdev) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci return to_pci_dev(vdev->drm.dev)->revision; 16462306a36Sopenharmony_ci} 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistatic inline u16 ivpu_device_id(struct ivpu_device *vdev) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci return to_pci_dev(vdev->drm.dev)->device; 16962306a36Sopenharmony_ci} 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_cistatic inline int ivpu_hw_gen(struct ivpu_device *vdev) 17262306a36Sopenharmony_ci{ 17362306a36Sopenharmony_ci switch (ivpu_device_id(vdev)) { 17462306a36Sopenharmony_ci case PCI_DEVICE_ID_MTL: 17562306a36Sopenharmony_ci case PCI_DEVICE_ID_ARL: 17662306a36Sopenharmony_ci return IVPU_HW_37XX; 17762306a36Sopenharmony_ci case PCI_DEVICE_ID_LNL: 17862306a36Sopenharmony_ci return IVPU_HW_40XX; 17962306a36Sopenharmony_ci default: 18062306a36Sopenharmony_ci ivpu_err(vdev, "Unknown VPU device\n"); 18162306a36Sopenharmony_ci return 0; 18262306a36Sopenharmony_ci } 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cistatic inline struct ivpu_device *to_ivpu_device(struct drm_device *dev) 18662306a36Sopenharmony_ci{ 18762306a36Sopenharmony_ci return container_of(dev, struct ivpu_device, drm); 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistatic inline u32 ivpu_get_context_count(struct ivpu_device *vdev) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci struct xa_limit ctx_limit = vdev->context_xa_limit; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci return (ctx_limit.max - ctx_limit.min + 1); 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic inline u32 ivpu_get_platform(struct ivpu_device *vdev) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci WARN_ON_ONCE(vdev->platform == IVPU_PLATFORM_INVALID); 20062306a36Sopenharmony_ci return vdev->platform; 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistatic inline bool ivpu_is_silicon(struct ivpu_device *vdev) 20462306a36Sopenharmony_ci{ 20562306a36Sopenharmony_ci return ivpu_get_platform(vdev) == IVPU_PLATFORM_SILICON; 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistatic inline bool ivpu_is_simics(struct ivpu_device *vdev) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci return ivpu_get_platform(vdev) == IVPU_PLATFORM_SIMICS; 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cistatic inline bool ivpu_is_fpga(struct ivpu_device *vdev) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci return ivpu_get_platform(vdev) == IVPU_PLATFORM_FPGA; 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci#endif /* __IVPU_DRV_H__ */ 219