Commit 51c7960b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'drm-fixes-2025-04-19' of https://gitlab.freedesktop.org/drm/kernel

Pull drm fixes from Dave Airlie:
 "Easter rc3 pull request, fixes in all the usuals, amdgpu, xe, msm,
  with some i915/ivpu/mgag200/v3d fixes, then a couple of bits in
  dma-buf/gem.

  Hopefully has no easter eggs in it.

  dma-buf:
   - Correctly decrement refcounter on errors

  gem:
   - Fix test for imported buffers

  amdgpu:
   - Cleaner shader sysfs fix
   - Suspend fix
   - Fix doorbell free ordering
   - Video caps fix
   - DML2 memory allocation optimization
   - HDP fix

  i915:
   - Fix DP DSC configurations that require 3 DSC engines per pipe

  xe:
   - Fix LRC address being written too late for GuC
   - Fix notifier vs folio deadlock
   - Fix race betwen dma_buf unmap and vram eviction
   - Fix debugfs handling PXP terminations unconditionally

  msm:
   - Display:
       - Fix to call dpu_plane_atomic_check_pipe() for both SSPPs in
         case of multi-rect
       - Fix to validate plane_state pointer before using it in
         dpu_plane_virtual_atomic_check()
       - Fix to make sure dereferencing dpu_encoder_phys happens after
         making sure it is valid in _dpu_encoder_trigger_start()
       - Remove the remaining intr_tear_rd_ptr which we initialized to
         -1 because NO_IRQ indices start from 0 now
   - GPU:
       - Fix IB_SIZE overflow

  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"

* tag 'drm-fixes-2025-04-19' of https://gitlab.freedesktop.org/drm/kernel: (26 commits)
  drm/msm/a6xx+: Don't let IB_SIZE overflow
  drm/xe/pxp: do not queue unneeded terminations from debugfs
  drm/xe/dma_buf: stop relying on placement in unmap
  drm/xe/userptr: fix notifier vs folio deadlock
  drm/xe: Set LRC addresses before guc load
  drm/mgag200: Fix value in <VBLKSTR> register
  drm/gem: Internally test import_attach for imported objects
  drm/amdgpu: Use the right function for hdp flush
  drm/amd/display/dml2: use vzalloc rather than kzalloc
  drm/amdgpu: Add back JPEG to video caps for carrizo and newer
  drm/amdgpu: fix warning of drm_mm_clean
  drm/amd: Forbid suspending into non-default suspend states
  drm/amdgpu: use a dummy owner for sysfs triggered cleaner shaders v4
  drm/i915/dp: Check for HAS_DSC_3ENGINES while configuring DSC slices
  drm/i915/display: Add macro for checking 3 DSC engines
  dma-buf/sw_sync: Decrement refcount on error in sw_sync_ioctl_get_deadline()
  accel/ivpu: Add cmdq_id to job related logs
  accel/ivpu: Show NPU frequency in sysfs
  accel/ivpu: Fix the NPU's DPU frequency calculation
  accel/ivpu: Update FW Boot API to version 3.28.3
  ...
parents 8560697b 0467145f
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