mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
Short summary of fixes pull:
dma-buf: - Correctly decrement refcounter on errors gem: - Fix test for imported buffers ivpu: - Fix debugging - Fixes to frequency - Support firmware API 3.28.3 - Flush jobs upon reset mgag200: - Set vblank start to correct values v3d: - Fix Indirect Dispatch -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmgAviQACgkQaA3BHVML eiPysQf/fjWwUAWs00ANi9ERtRN4doWNLeDB3vNrIsPB2NEwfc/RwmQvT06Ar7Zb /rwudFgGsw7cRK2d7LqjJtfmE/5/qILCTSsRWWgVCtP8bxLmew3WtyurYczvpAc4 nAAkctNdj9uLl/btc2HimhxGaJzxHv3Wt64GL2ROldqhf8sjs9x0uxMed58UUYsQ t/6EqmVyjfigwvIFHj0o5iv7AnFKbWeg3tENyeQMaxOwh+TQyWvAGsJzqhhFLxQV JGeU/ARu+ZeKdDkYArDzDUTW0BCetC3lmeg7PMX1Paf4876VAHRaVx5y8xn+LJiA xz5BOehz/yJpqvtDd7/J/taw6o4OKw== =tU6K -----END PGP SIGNATURE----- Merge tag 'drm-misc-fixes-2025-04-17' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes Short summary of fixes pull: dma-buf: - Correctly decrement refcounter on errors gem: - Fix test for imported buffers ivpu: - Fix debugging - Fixes to frequency - Support firmware API 3.28.3 - Flush jobs upon reset mgag200: - Set vblank start to correct values v3d: - Fix Indirect Dispatch Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://lore.kernel.org/r/20250417084043.GA365738@linux.fritz.box
This commit is contained in:
commit
9bca5bcdeb
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
@ -164,7 +164,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
|
||||
args->value = vdev->platform;
|
||||
break;
|
||||
case DRM_IVPU_PARAM_CORE_CLOCK_RATE:
|
||||
args->value = ivpu_hw_ratio_to_freq(vdev, vdev->hw->pll.max_ratio);
|
||||
args->value = ivpu_hw_dpu_max_freq_get(vdev);
|
||||
break;
|
||||
case DRM_IVPU_PARAM_NUM_CONTEXTS:
|
||||
args->value = ivpu_get_context_count(vdev);
|
||||
@ -421,9 +421,9 @@ void ivpu_prepare_for_reset(struct ivpu_device *vdev)
|
||||
{
|
||||
ivpu_hw_irq_disable(vdev);
|
||||
disable_irq(vdev->irq);
|
||||
cancel_work_sync(&vdev->irq_ipc_work);
|
||||
cancel_work_sync(&vdev->irq_dct_work);
|
||||
cancel_work_sync(&vdev->context_abort_work);
|
||||
flush_work(&vdev->irq_ipc_work);
|
||||
flush_work(&vdev->irq_dct_work);
|
||||
flush_work(&vdev->context_abort_work);
|
||||
ivpu_ipc_disable(vdev);
|
||||
ivpu_mmu_disable(vdev);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/firmware.h>
|
||||
@ -233,10 +233,20 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
|
||||
fw->dvfs_mode = 0;
|
||||
|
||||
fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr);
|
||||
fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size;
|
||||
fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size;
|
||||
ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS");
|
||||
|
||||
if (fw_hdr->preemption_buffer_1_max_size)
|
||||
fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_max_size;
|
||||
else
|
||||
fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size;
|
||||
|
||||
if (fw_hdr->preemption_buffer_2_max_size)
|
||||
fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_max_size;
|
||||
else
|
||||
fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size;
|
||||
ivpu_dbg(vdev, FW_BOOT, "Preemption buffer sizes: primary %u, secondary %u\n",
|
||||
fw->primary_preempt_buf_size, fw->secondary_preempt_buf_size);
|
||||
|
||||
if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address,
|
||||
fw_hdr->ro_section_size,
|
||||
fw_hdr->image_load_address,
|
||||
@ -566,7 +576,6 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
|
||||
|
||||
boot_params->magic = VPU_BOOT_PARAMS_MAGIC;
|
||||
boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number;
|
||||
boot_params->frequency = ivpu_hw_pll_freq_get(vdev);
|
||||
|
||||
/*
|
||||
* This param is a debug firmware feature. It switches default clock
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_HW_H__
|
||||
@ -82,9 +82,14 @@ static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range)
|
||||
return range->end - range->start;
|
||||
}
|
||||
|
||||
static inline u32 ivpu_hw_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
|
||||
static inline u32 ivpu_hw_dpu_max_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return ivpu_hw_btrs_ratio_to_freq(vdev, ratio);
|
||||
return ivpu_hw_btrs_dpu_max_freq_get(vdev);
|
||||
}
|
||||
|
||||
static inline u32 ivpu_hw_dpu_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return ivpu_hw_btrs_dpu_freq_get(vdev);
|
||||
}
|
||||
|
||||
static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
|
||||
@ -92,11 +97,6 @@ static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
|
||||
ivpu_hw_ip_irq_clear(vdev);
|
||||
}
|
||||
|
||||
static inline u32 ivpu_hw_pll_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return ivpu_hw_btrs_pll_freq_get(vdev);
|
||||
}
|
||||
|
||||
static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return vdev->hw->pll.profiling_freq;
|
||||
|
@ -1,8 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "ivpu_drv.h"
|
||||
#include "ivpu_hw.h"
|
||||
#include "ivpu_hw_btrs.h"
|
||||
@ -28,17 +30,13 @@
|
||||
|
||||
#define BTRS_LNL_ALL_IRQ_MASK ((u32)-1)
|
||||
|
||||
#define BTRS_MTL_WP_CONFIG_1_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_5_3)
|
||||
#define BTRS_MTL_WP_CONFIG_1_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_4_3)
|
||||
#define BTRS_MTL_WP_CONFIG_2_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_5_3)
|
||||
#define BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3)
|
||||
#define BTRS_MTL_WP_CONFIG_0_TILE_PLL_OFF WP_CONFIG(0, 0)
|
||||
|
||||
#define PLL_CDYN_DEFAULT 0x80
|
||||
#define PLL_EPP_DEFAULT 0x80
|
||||
#define PLL_CONFIG_DEFAULT 0x0
|
||||
#define PLL_SIMULATION_FREQ 10000000
|
||||
#define PLL_REF_CLK_FREQ 50000000
|
||||
#define PLL_REF_CLK_FREQ 50000000ull
|
||||
#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ)
|
||||
|
||||
#define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC)
|
||||
#define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC)
|
||||
#define TIMEOUT_US (150 * USEC_PER_MSEC)
|
||||
@ -62,6 +60,8 @@
|
||||
#define DCT_ENABLE 0x1
|
||||
#define DCT_DISABLE 0x0
|
||||
|
||||
static u32 pll_ratio_to_dpu_freq(struct ivpu_device *vdev, u32 ratio);
|
||||
|
||||
int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev)
|
||||
{
|
||||
REGB_WR32(VPU_HW_BTRS_MTL_INTERRUPT_STAT, BTRS_MTL_ALL_IRQ_MASK);
|
||||
@ -156,7 +156,7 @@ static int info_init_mtl(struct ivpu_device *vdev)
|
||||
|
||||
hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH;
|
||||
hw->sku = BTRS_MTL_TILE_SKU_BOTH;
|
||||
hw->config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO;
|
||||
hw->config = WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -334,8 +334,8 @@ int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable)
|
||||
|
||||
prepare_wp_request(vdev, &wp, enable);
|
||||
|
||||
ivpu_dbg(vdev, PM, "PLL workpoint request: %u Hz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n",
|
||||
PLL_RATIO_TO_FREQ(wp.target), wp.cfg, wp.epp, wp.cdyn);
|
||||
ivpu_dbg(vdev, PM, "PLL workpoint request: %lu MHz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n",
|
||||
pll_ratio_to_dpu_freq(vdev, wp.target) / HZ_PER_MHZ, wp.cfg, wp.epp, wp.cdyn);
|
||||
|
||||
ret = wp_request_send(vdev, &wp);
|
||||
if (ret) {
|
||||
@ -573,6 +573,47 @@ int ivpu_hw_btrs_wait_for_idle(struct ivpu_device *vdev)
|
||||
return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US);
|
||||
}
|
||||
|
||||
static u32 pll_config_get_mtl(struct ivpu_device *vdev)
|
||||
{
|
||||
return REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL);
|
||||
}
|
||||
|
||||
static u32 pll_config_get_lnl(struct ivpu_device *vdev)
|
||||
{
|
||||
return REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ);
|
||||
}
|
||||
|
||||
static u32 pll_ratio_to_dpu_freq_mtl(u16 ratio)
|
||||
{
|
||||
return (PLL_RATIO_TO_FREQ(ratio) * 2) / 3;
|
||||
}
|
||||
|
||||
static u32 pll_ratio_to_dpu_freq_lnl(u16 ratio)
|
||||
{
|
||||
return PLL_RATIO_TO_FREQ(ratio) / 2;
|
||||
}
|
||||
|
||||
static u32 pll_ratio_to_dpu_freq(struct ivpu_device *vdev, u32 ratio)
|
||||
{
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
return pll_ratio_to_dpu_freq_mtl(ratio);
|
||||
else
|
||||
return pll_ratio_to_dpu_freq_lnl(ratio);
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
return pll_ratio_to_dpu_freq(vdev, vdev->hw->pll.max_ratio);
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
return pll_ratio_to_dpu_freq_mtl(pll_config_get_mtl(vdev));
|
||||
else
|
||||
return pll_ratio_to_dpu_freq_lnl(pll_config_get_lnl(vdev));
|
||||
}
|
||||
|
||||
/* Handler for IRQs from Buttress core (irqB) */
|
||||
bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq)
|
||||
{
|
||||
@ -582,9 +623,12 @@ bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq)
|
||||
if (!status)
|
||||
return false;
|
||||
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status))
|
||||
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x",
|
||||
REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL));
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status)) {
|
||||
u32 pll = pll_config_get_mtl(vdev);
|
||||
|
||||
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq, wp %08x, %lu MHz",
|
||||
pll, pll_ratio_to_dpu_freq_mtl(pll) / HZ_PER_MHZ);
|
||||
}
|
||||
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, ATS_ERR, status)) {
|
||||
ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(VPU_HW_BTRS_MTL_ATS_ERR_LOG_0));
|
||||
@ -633,8 +677,12 @@ bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq)
|
||||
queue_work(system_wq, &vdev->irq_dct_work);
|
||||
}
|
||||
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status))
|
||||
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ));
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status)) {
|
||||
u32 pll = pll_config_get_lnl(vdev);
|
||||
|
||||
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq, wp %08x, %lu MHz",
|
||||
pll, pll_ratio_to_dpu_freq_lnl(pll) / HZ_PER_MHZ);
|
||||
}
|
||||
|
||||
if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, status)) {
|
||||
ivpu_err(vdev, "ATS_ERR LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
|
||||
@ -717,60 +765,6 @@ void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 acti
|
||||
REGB_WR32(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, val);
|
||||
}
|
||||
|
||||
static u32 pll_ratio_to_freq_mtl(u32 ratio, u32 config)
|
||||
{
|
||||
u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
|
||||
u32 cpu_clock;
|
||||
|
||||
if ((config & 0xff) == MTL_PLL_RATIO_4_3)
|
||||
cpu_clock = pll_clock * 2 / 4;
|
||||
else
|
||||
cpu_clock = pll_clock * 2 / 5;
|
||||
|
||||
return cpu_clock;
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
|
||||
{
|
||||
struct ivpu_hw_info *hw = vdev->hw;
|
||||
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
return pll_ratio_to_freq_mtl(ratio, hw->config);
|
||||
else
|
||||
return PLL_RATIO_TO_FREQ(ratio);
|
||||
}
|
||||
|
||||
static u32 pll_freq_get_mtl(struct ivpu_device *vdev)
|
||||
{
|
||||
u32 pll_curr_ratio;
|
||||
|
||||
pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL);
|
||||
pll_curr_ratio &= VPU_HW_BTRS_MTL_CURRENT_PLL_RATIO_MASK;
|
||||
|
||||
if (!ivpu_is_silicon(vdev))
|
||||
return PLL_SIMULATION_FREQ;
|
||||
|
||||
return pll_ratio_to_freq_mtl(pll_curr_ratio, vdev->hw->config);
|
||||
}
|
||||
|
||||
static u32 pll_freq_get_lnl(struct ivpu_device *vdev)
|
||||
{
|
||||
u32 pll_curr_ratio;
|
||||
|
||||
pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ);
|
||||
pll_curr_ratio &= VPU_HW_BTRS_LNL_PLL_FREQ_RATIO_MASK;
|
||||
|
||||
return PLL_RATIO_TO_FREQ(pll_curr_ratio);
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev)
|
||||
{
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
return pll_freq_get_mtl(vdev);
|
||||
else
|
||||
return pll_freq_get_lnl(vdev);
|
||||
}
|
||||
|
||||
u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev)
|
||||
{
|
||||
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __IVPU_HW_BTRS_H__
|
||||
@ -13,7 +13,6 @@
|
||||
|
||||
#define PLL_PROFILING_FREQ_DEFAULT 38400000
|
||||
#define PLL_PROFILING_FREQ_HIGH 400000000
|
||||
#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ)
|
||||
|
||||
#define DCT_DEFAULT_ACTIVE_PERCENT 15u
|
||||
#define DCT_PERIOD_US 35300u
|
||||
@ -32,12 +31,12 @@ int ivpu_hw_btrs_ip_reset(struct ivpu_device *vdev);
|
||||
void ivpu_hw_btrs_profiling_freq_reg_set_lnl(struct ivpu_device *vdev);
|
||||
void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev);
|
||||
void ivpu_hw_btrs_clock_relinquish_disable_lnl(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev);
|
||||
bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq);
|
||||
bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq);
|
||||
int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable);
|
||||
void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 dct_percent);
|
||||
u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio);
|
||||
u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev);
|
||||
u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev);
|
||||
|
@ -470,8 +470,8 @@ static void ivpu_job_destroy(struct ivpu_job *job)
|
||||
struct ivpu_device *vdev = job->vdev;
|
||||
u32 i;
|
||||
|
||||
ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d engine %d",
|
||||
job->job_id, job->file_priv->ctx.id, job->engine_idx);
|
||||
ivpu_dbg(vdev, JOB, "Job destroyed: id %3u ctx %2d cmdq_id %u engine %d",
|
||||
job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx);
|
||||
|
||||
for (i = 0; i < job->bo_count; i++)
|
||||
if (job->bos[i])
|
||||
@ -564,8 +564,8 @@ static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32
|
||||
dma_fence_signal(job->done_fence);
|
||||
|
||||
trace_job("done", job);
|
||||
ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d engine %d status 0x%x\n",
|
||||
job->job_id, job->file_priv->ctx.id, job->engine_idx, job_status);
|
||||
ivpu_dbg(vdev, JOB, "Job complete: id %3u ctx %2d cmdq_id %u engine %d status 0x%x\n",
|
||||
job->job_id, job->file_priv->ctx.id, job->cmdq_id, job->engine_idx, job_status);
|
||||
|
||||
ivpu_job_destroy(job);
|
||||
ivpu_stop_job_timeout_detection(vdev);
|
||||
@ -664,8 +664,8 @@ static int ivpu_job_submit(struct ivpu_job *job, u8 priority, u32 cmdq_id)
|
||||
}
|
||||
|
||||
trace_job("submit", job);
|
||||
ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d prio %d addr 0x%llx next %d\n",
|
||||
job->job_id, file_priv->ctx.id, job->engine_idx, cmdq->priority,
|
||||
ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d cmdq_id %u engine %d prio %d addr 0x%llx next %d\n",
|
||||
job->job_id, file_priv->ctx.id, cmdq->id, job->engine_idx, cmdq->priority,
|
||||
job->cmd_buf_vpu_addr, cmdq->jobq->header.tail);
|
||||
|
||||
mutex_unlock(&file_priv->lock);
|
||||
@ -777,7 +777,8 @@ static int ivpu_submit(struct drm_file *file, struct ivpu_file_priv *file_priv,
|
||||
goto err_free_handles;
|
||||
}
|
||||
|
||||
ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n", file_priv->ctx.id, buffer_count);
|
||||
ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u cmdq_id %u buf_count %u\n",
|
||||
file_priv->ctx.id, cmdq_id, buffer_count);
|
||||
|
||||
job = ivpu_job_create(file_priv, engine, buffer_count);
|
||||
if (!job) {
|
||||
|
@ -1,10 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2024 Intel Corporation
|
||||
* Copyright (C) 2024-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "ivpu_drv.h"
|
||||
#include "ivpu_gem.h"
|
||||
@ -90,10 +92,55 @@ sched_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
|
||||
static DEVICE_ATTR_RO(sched_mode);
|
||||
|
||||
/**
|
||||
* DOC: npu_max_frequency
|
||||
*
|
||||
* The npu_max_frequency shows maximum frequency in MHz of the NPU's data
|
||||
* processing unit
|
||||
*/
|
||||
static ssize_t
|
||||
npu_max_frequency_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
struct ivpu_device *vdev = to_ivpu_device(drm);
|
||||
u32 freq = ivpu_hw_dpu_max_freq_get(vdev);
|
||||
|
||||
return sysfs_emit(buf, "%lu\n", freq / HZ_PER_MHZ);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(npu_max_frequency_mhz);
|
||||
|
||||
/**
|
||||
* DOC: npu_current_frequency_mhz
|
||||
*
|
||||
* The npu_current_frequency_mhz shows current frequency in MHz of the NPU's
|
||||
* data processing unit
|
||||
*/
|
||||
static ssize_t
|
||||
npu_current_frequency_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
struct ivpu_device *vdev = to_ivpu_device(drm);
|
||||
u32 freq = 0;
|
||||
|
||||
/* Read frequency only if device is active, otherwise frequency is 0 */
|
||||
if (pm_runtime_get_if_active(vdev->drm.dev) > 0) {
|
||||
freq = ivpu_hw_dpu_freq_get(vdev);
|
||||
|
||||
pm_runtime_put_autosuspend(vdev->drm.dev);
|
||||
}
|
||||
|
||||
return sysfs_emit(buf, "%lu\n", freq / HZ_PER_MHZ);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(npu_current_frequency_mhz);
|
||||
|
||||
static struct attribute *ivpu_dev_attrs[] = {
|
||||
&dev_attr_npu_busy_time_us.attr,
|
||||
&dev_attr_npu_memory_utilization.attr,
|
||||
&dev_attr_sched_mode.attr,
|
||||
&dev_attr_npu_max_frequency_mhz.attr,
|
||||
&dev_attr_npu_current_frequency_mhz.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
* Minor version changes when API backward compatibility is preserved.
|
||||
* Resets to 0 if Major version is incremented.
|
||||
*/
|
||||
#define VPU_BOOT_API_VER_MINOR 26
|
||||
#define VPU_BOOT_API_VER_MINOR 28
|
||||
|
||||
/*
|
||||
* API header changed (field names, documentation, formatting) but API itself has not been changed
|
||||
@ -76,8 +76,15 @@ struct vpu_firmware_header {
|
||||
* submission queue size and device capabilities.
|
||||
*/
|
||||
u32 preemption_buffer_2_size;
|
||||
/*
|
||||
* Maximum preemption buffer size that the FW can use: no need for the host
|
||||
* driver to allocate more space than that specified by these fields.
|
||||
* A value of 0 means no declared limit.
|
||||
*/
|
||||
u32 preemption_buffer_1_max_size;
|
||||
u32 preemption_buffer_2_max_size;
|
||||
/* Space reserved for future preemption-related fields. */
|
||||
u32 preemption_reserved[6];
|
||||
u32 preemption_reserved[4];
|
||||
/* FW image read only section start address, 4KB aligned */
|
||||
u64 ro_section_start_address;
|
||||
/* FW image read only section size, 4KB aligned */
|
||||
@ -134,7 +141,7 @@ enum vpu_trace_destination {
|
||||
/*
|
||||
* Processor bit shifts (for loggable HW components).
|
||||
*/
|
||||
#define VPU_TRACE_PROC_BIT_ARM 0
|
||||
#define VPU_TRACE_PROC_BIT_RESERVED 0
|
||||
#define VPU_TRACE_PROC_BIT_LRT 1
|
||||
#define VPU_TRACE_PROC_BIT_LNN 2
|
||||
#define VPU_TRACE_PROC_BIT_SHV_0 3
|
||||
|
@ -22,7 +22,7 @@
|
||||
/*
|
||||
* Minor version changes when API backward compatibility is preserved.
|
||||
*/
|
||||
#define VPU_JSM_API_VER_MINOR 25
|
||||
#define VPU_JSM_API_VER_MINOR 29
|
||||
|
||||
/*
|
||||
* API header changed (field names, documentation, formatting) but API itself has not been changed
|
||||
@ -53,8 +53,7 @@
|
||||
* Engine indexes.
|
||||
*/
|
||||
#define VPU_ENGINE_COMPUTE 0
|
||||
#define VPU_ENGINE_COPY 1
|
||||
#define VPU_ENGINE_NB 2
|
||||
#define VPU_ENGINE_NB 1
|
||||
|
||||
/*
|
||||
* VPU status values.
|
||||
@ -126,11 +125,13 @@ enum {
|
||||
* When set, indicates that job queue uses native fences (as inline commands
|
||||
* in job queue). Such queues may also use legacy fences (as commands in batch buffers).
|
||||
* When cleared, indicates the job queue only uses legacy fences.
|
||||
* NOTE: For queues using native fences, VPU expects that all jobs in the queue
|
||||
* are immediately followed by an inline command object. This object is expected
|
||||
* to be a fence signal command in most cases, but can also be a NOP in case the host
|
||||
* does not need per-job fence signalling. Other inline commands objects can be
|
||||
* inserted between "job and inline command" pairs.
|
||||
* NOTES:
|
||||
* 1. For queues using native fences, VPU expects that all jobs in the queue
|
||||
* are immediately followed by an inline command object. This object is expected
|
||||
* to be a fence signal command in most cases, but can also be a NOP in case the host
|
||||
* does not need per-job fence signalling. Other inline commands objects can be
|
||||
* inserted between "job and inline command" pairs.
|
||||
* 2. Native fence queues are only supported on VPU 40xx onwards.
|
||||
*/
|
||||
VPU_JOB_QUEUE_FLAGS_USE_NATIVE_FENCE_MASK = (1 << 1U),
|
||||
|
||||
@ -275,6 +276,8 @@ struct vpu_inline_cmd {
|
||||
u64 value;
|
||||
/* User VA of the log buffer in which to add log entry on completion. */
|
||||
u64 log_buffer_va;
|
||||
/* NPU private data. */
|
||||
u64 npu_private_data;
|
||||
} fence;
|
||||
/* Other commands do not have a payload. */
|
||||
/* Payload definition for future inline commands can be inserted here. */
|
||||
@ -791,12 +794,22 @@ struct vpu_jsm_metric_streamer_update {
|
||||
/** Metric group mask that identifies metric streamer instance. */
|
||||
u64 metric_group_mask;
|
||||
/**
|
||||
* Address and size of the buffer where the VPU will write metric data. If
|
||||
* the buffer address is 0 or same as the currently used buffer the VPU will
|
||||
* continue writing metric data to the current buffer. In this case the
|
||||
* buffer size is ignored and the size of the current buffer is unchanged.
|
||||
* If the address is non-zero and differs from the current buffer address the
|
||||
* VPU will immediately switch data collection to the new buffer.
|
||||
* Address and size of the buffer where the VPU will write metric data.
|
||||
* This member dictates how the update operation should perform:
|
||||
* 1. client needs information about the number of collected samples and the
|
||||
* amount of data written to the current buffer
|
||||
* 2. client wants to switch to a new buffer
|
||||
*
|
||||
* Case 1. is identified by the buffer address being 0 or the same as the
|
||||
* currently used buffer address. In this case the buffer size is ignored and
|
||||
* the size of the current buffer is unchanged. The VPU will return an update
|
||||
* in the vpu_jsm_metric_streamer_done structure. The internal writing position
|
||||
* into the buffer is not changed.
|
||||
*
|
||||
* Case 2. is identified by the address being non-zero and differs from the
|
||||
* current buffer address. The VPU will immediately switch data collection to
|
||||
* the new buffer. Then the VPU will return an update in the
|
||||
* vpu_jsm_metric_streamer_done structure.
|
||||
*/
|
||||
u64 buffer_addr;
|
||||
u64 buffer_size;
|
||||
@ -934,6 +947,7 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup {
|
||||
/*
|
||||
* Default quantum in 100ns units for scheduling across processes
|
||||
* within a priority band
|
||||
* Minimum value supported by NPU is 1ms (10000 in 100ns units).
|
||||
*/
|
||||
u32 process_quantum[VPU_HWS_NUM_PRIORITY_BANDS];
|
||||
/*
|
||||
@ -946,8 +960,10 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup {
|
||||
* in situations when it's starved by the focus band.
|
||||
*/
|
||||
u32 normal_band_percentage;
|
||||
/* Reserved */
|
||||
u32 reserved_0;
|
||||
/*
|
||||
* TDR timeout value in milliseconds. Default value of 0 meaning no timeout.
|
||||
*/
|
||||
u32 tdr_timeout;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1024,7 +1040,10 @@ struct vpu_ipc_msg_payload_hws_set_context_sched_properties {
|
||||
s32 in_process_priority;
|
||||
/* Zero padding / Reserved */
|
||||
u32 reserved_1;
|
||||
/* Context quantum relative to other contexts of same priority in the same process */
|
||||
/*
|
||||
* Context quantum relative to other contexts of same priority in the same process
|
||||
* Minimum value supported by NPU is 1ms (10000 in 100ns units).
|
||||
*/
|
||||
u64 context_quantum;
|
||||
/* Grace period when preempting context of the same priority within the same process */
|
||||
u64 grace_period_same_priority;
|
||||
|
@ -438,15 +438,17 @@ static int sw_sync_ioctl_get_deadline(struct sync_timeline *obj, unsigned long a
|
||||
return -EINVAL;
|
||||
|
||||
pt = dma_fence_to_sync_pt(fence);
|
||||
if (!pt)
|
||||
return -EINVAL;
|
||||
if (!pt) {
|
||||
ret = -EINVAL;
|
||||
goto put_fence;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(fence->lock, flags);
|
||||
if (test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {
|
||||
data.deadline_ns = ktime_to_ns(pt->deadline);
|
||||
} else {
|
||||
if (!test_bit(SW_SYNC_HAS_DEADLINE_BIT, &fence->flags)) {
|
||||
ret = -ENOENT;
|
||||
goto unlock;
|
||||
}
|
||||
data.deadline_ns = ktime_to_ns(pt->deadline);
|
||||
spin_unlock_irqrestore(fence->lock, flags);
|
||||
|
||||
dma_fence_put(fence);
|
||||
@ -458,6 +460,13 @@ static int sw_sync_ioctl_get_deadline(struct sync_timeline *obj, unsigned long a
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
||||
unlock:
|
||||
spin_unlock_irqrestore(fence->lock, flags);
|
||||
put_fence:
|
||||
dma_fence_put(fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long sw_sync_ioctl(struct file *file, unsigned int cmd,
|
||||
|
@ -223,7 +223,7 @@ void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mod
|
||||
vsyncstr = mode->crtc_vsync_start - 1;
|
||||
vsyncend = mode->crtc_vsync_end - 1;
|
||||
vtotal = mode->crtc_vtotal - 2;
|
||||
vblkstr = mode->crtc_vblank_start;
|
||||
vblkstr = mode->crtc_vblank_start - 1;
|
||||
vblkend = vtotal + 1;
|
||||
|
||||
linecomp = vdispend;
|
||||
|
@ -428,7 +428,8 @@ v3d_rewrite_csd_job_wg_counts_from_indirect(struct v3d_cpu_job *job)
|
||||
struct v3d_bo *bo = to_v3d_bo(job->base.bo[0]);
|
||||
struct v3d_bo *indirect = to_v3d_bo(indirect_csd->indirect);
|
||||
struct drm_v3d_submit_csd *args = &indirect_csd->job->args;
|
||||
u32 *wg_counts;
|
||||
struct v3d_dev *v3d = job->base.v3d;
|
||||
u32 num_batches, *wg_counts;
|
||||
|
||||
v3d_get_bo_vaddr(bo);
|
||||
v3d_get_bo_vaddr(indirect);
|
||||
@ -441,8 +442,17 @@ v3d_rewrite_csd_job_wg_counts_from_indirect(struct v3d_cpu_job *job)
|
||||
args->cfg[0] = wg_counts[0] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
|
||||
args->cfg[1] = wg_counts[1] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
|
||||
args->cfg[2] = wg_counts[2] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
|
||||
args->cfg[4] = DIV_ROUND_UP(indirect_csd->wg_size, 16) *
|
||||
(wg_counts[0] * wg_counts[1] * wg_counts[2]) - 1;
|
||||
|
||||
num_batches = DIV_ROUND_UP(indirect_csd->wg_size, 16) *
|
||||
(wg_counts[0] * wg_counts[1] * wg_counts[2]);
|
||||
|
||||
/* V3D 7.1.6 and later don't subtract 1 from the number of batches */
|
||||
if (v3d->ver < 71 || (v3d->ver == 71 && v3d->rev < 6))
|
||||
args->cfg[4] = num_batches - 1;
|
||||
else
|
||||
args->cfg[4] = num_batches;
|
||||
|
||||
WARN_ON(args->cfg[4] == ~0);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
/* 0xffffffff indicates that the uniform rewrite is not needed */
|
||||
|
@ -585,8 +585,7 @@ static inline bool drm_gem_object_is_shared_for_memory_stats(struct drm_gem_obje
|
||||
*/
|
||||
static inline bool drm_gem_is_imported(const struct drm_gem_object *obj)
|
||||
{
|
||||
/* The dma-buf's priv field points to the original GEM object. */
|
||||
return obj->dma_buf && (obj->dma_buf->priv != obj);
|
||||
return !!obj->import_attach;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (C) 2020-2024 Intel Corporation
|
||||
* Copyright (C) 2020-2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __UAPI_IVPU_DRM_H__
|
||||
@ -147,7 +147,7 @@ struct drm_ivpu_param {
|
||||
* platform type when executing on a simulator or emulator (read-only)
|
||||
*
|
||||
* %DRM_IVPU_PARAM_CORE_CLOCK_RATE:
|
||||
* Current PLL frequency (read-only)
|
||||
* Maximum frequency of the NPU data processing unit clock (read-only)
|
||||
*
|
||||
* %DRM_IVPU_PARAM_NUM_CONTEXTS:
|
||||
* Maximum number of simultaneously existing contexts (read-only)
|
||||
|
Loading…
Reference in New Issue
Block a user