Commit 9bca5bcd authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2025-04-17' of...

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: default avatarDave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20250417084043.GA365738@linux.fritz.box
parents 9025588c 76c332d1
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
// 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);
}
+13 −4
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2020-2024 Intel Corporation
 * Copyright (C) 2020-2025 Intel Corporation
 */

#include <linux/firmware.h>
@@ -233,9 +233,19 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
	fw->dvfs_mode = 0;

	fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr);
	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_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS");
	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,
@@ -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
+7 −7
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2020-2024 Intel Corporation
 * Copyright (C) 2020-2025 Intel Corporation
 */

#ifndef __IVPU_HW_H__
@@ -82,19 +82,19 @@ 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 void ivpu_hw_irq_clear(struct ivpu_device *vdev)
static inline u32 ivpu_hw_dpu_freq_get(struct ivpu_device *vdev)
{
	ivpu_hw_ip_irq_clear(vdev);
	return ivpu_hw_btrs_dpu_freq_get(vdev);
}

static inline u32 ivpu_hw_pll_freq_get(struct ivpu_device *vdev)
static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
{
	return ivpu_hw_btrs_pll_freq_get(vdev);
	ivpu_hw_ip_irq_clear(vdev);
}

static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
+64 −70
Original line number Diff line number Diff line
// 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)
+3 −4
Original line number Diff line number Diff line
/* 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);
Loading