Commit 0d3ff808 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'drm-fixes-2023-03-30' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Daniel Vetter:
 "Two regression fixes in here, otherwise just the usual stuff:

   - i915 fixes for color mgmt, psr, lmem flush, hibernate oops, and
     more

   - amdgpu: dp mst and hibernate regression fix

   - etnaviv: revert fdinfo support (incl drm/sched revert), leak fix

   - misc ivpu fixes, nouveau backlight, drm buddy allocator 32bit
     fixes"

* tag 'drm-fixes-2023-03-30' of git://anongit.freedesktop.org/drm/drm: (27 commits)
  Revert "drm/scheduler: track GPU active time per entity"
  Revert "drm/etnaviv: export client GPU usage statistics via fdinfo"
  drm/etnaviv: fix reference leak when mmaping imported buffer
  drm/amdgpu: allow more APUs to do mode2 reset when go to S4
  drm/amd/display: Take FEC Overhead into Timeslot Calculation
  drm/amd/display: Add DSC Support for Synaptics Cascaded MST Hub
  drm: test: Fix 32-bit issue in drm_buddy_test
  drm: buddy_allocator: Fix buddy allocator init on 32-bit systems
  drm/nouveau/kms: Fix backlight registration
  drm/i915/perf: Drop wakeref on GuC RC error
  drm/i915/dpt: Treat the DPT BO as a framebuffer
  drm/i915/gem: Flush lmem contents after construction
  drm/i915/tc: Fix the ICL PHY ownership check in TC-cold state
  drm/i915: Disable DC states for all commits
  drm/i915: Workaround ICL CSC_MODE sticky arming
  drm/i915: Add a .color_post_update() hook
  drm/i915: Move CSC load back into .color_commit_arm() when PSR is enabled on skl/glk
  drm/i915: Split icl_color_commit_noarm() from skl_color_commit_noarm()
  drm/i915/pmu: Use functions common with sysfs to read actual freq
  accel/ivpu: Fix IPC buffer header status field value
  ...
parents 8bb95a16 7af63e07
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -8,7 +8,6 @@
#include <linux/pci.h>

#include <drm/drm_accel.h>
#include <drm/drm_drv.h>
#include <drm/drm_file.h>
#include <drm/drm_gem.h>
#include <drm/drm_ioctl.h>
@@ -118,6 +117,10 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
	struct pci_dev *pdev = to_pci_dev(vdev->drm.dev);
	struct drm_ivpu_param *args = data;
	int ret = 0;
	int idx;

	if (!drm_dev_enter(dev, &idx))
		return -ENODEV;

	switch (args->param) {
	case DRM_IVPU_PARAM_DEVICE_ID:
@@ -171,6 +174,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
		break;
	}

	drm_dev_exit(idx);
	return ret;
}

@@ -470,8 +474,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev)

	vdev->hw->ops = &ivpu_hw_mtl_ops;
	vdev->platform = IVPU_PLATFORM_INVALID;
	vdev->context_xa_limit.min = IVPU_GLOBAL_CONTEXT_MMU_SSID + 1;
	vdev->context_xa_limit.max = IVPU_CONTEXT_LIMIT;
	vdev->context_xa_limit.min = IVPU_USER_CONTEXT_MIN_SSID;
	vdev->context_xa_limit.max = IVPU_USER_CONTEXT_MAX_SSID;
	atomic64_set(&vdev->unique_id_counter, 0);
	xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC);
	xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1);
@@ -565,6 +569,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
	ivpu_mmu_global_context_fini(vdev);
err_power_down:
	ivpu_hw_power_down(vdev);
	if (IVPU_WA(d3hot_after_power_off))
		pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
err_xa_destroy:
	xa_destroy(&vdev->submitted_jobs_xa);
	xa_destroy(&vdev->context_xa);
@@ -575,7 +581,11 @@ static void ivpu_dev_fini(struct ivpu_device *vdev)
{
	ivpu_pm_disable(vdev);
	ivpu_shutdown(vdev);
	if (IVPU_WA(d3hot_after_power_off))
		pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
	ivpu_job_done_thread_fini(vdev);
	ivpu_pm_cancel_recovery(vdev);

	ivpu_ipc_fini(vdev);
	ivpu_fw_fini(vdev);
	ivpu_mmu_global_context_fini(vdev);
@@ -622,7 +632,7 @@ static void ivpu_remove(struct pci_dev *pdev)
{
	struct ivpu_device *vdev = pci_get_drvdata(pdev);

	drm_dev_unregister(&vdev->drm);
	drm_dev_unplug(&vdev->drm);
	ivpu_dev_fini(vdev);
}

+6 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#define __IVPU_DRV_H__

#include <drm/drm_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_managed.h>
#include <drm/drm_mm.h>
#include <drm/drm_print.h>
@@ -24,7 +25,10 @@
#define PCI_DEVICE_ID_MTL   0x7d1d

#define IVPU_GLOBAL_CONTEXT_MMU_SSID 0
#define IVPU_CONTEXT_LIMIT	     64
/* SSID 1 is used by the VPU to represent invalid context */
#define IVPU_USER_CONTEXT_MIN_SSID   2
#define IVPU_USER_CONTEXT_MAX_SSID   (IVPU_USER_CONTEXT_MIN_SSID + 63)

#define IVPU_NUM_ENGINES	     2

#define IVPU_PLATFORM_SILICON 0
@@ -70,6 +74,7 @@
struct ivpu_wa_table {
	bool punit_disabled;
	bool clear_runtime_mem;
	bool d3hot_after_power_off;
};

struct ivpu_hw_info;
+35 −78
Original line number Diff line number Diff line
@@ -13,23 +13,22 @@
#include "ivpu_pm.h"

#define TILE_FUSE_ENABLE_BOTH        0x0
#define TILE_FUSE_ENABLE_UPPER	     0x1
#define TILE_FUSE_ENABLE_LOWER	     0x2

#define TILE_SKU_BOTH_MTL            0x3630
#define TILE_SKU_LOWER_MTL	     0x3631
#define TILE_SKU_UPPER_MTL	     0x3632

/* Work point configuration values */
#define WP_CONFIG_1_TILE_5_3_RATIO   0x0101
#define WP_CONFIG_1_TILE_4_3_RATIO   0x0102
#define WP_CONFIG_2_TILE_5_3_RATIO   0x0201
#define WP_CONFIG_2_TILE_4_3_RATIO   0x0202
#define WP_CONFIG_0_TILE_PLL_OFF     0x0000
#define CONFIG_1_TILE                0x01
#define CONFIG_2_TILE                0x02
#define PLL_RATIO_5_3                0x01
#define PLL_RATIO_4_3                0x02
#define WP_CONFIG(tile, ratio)       (((tile) << 8) | (ratio))
#define WP_CONFIG_1_TILE_5_3_RATIO   WP_CONFIG(CONFIG_1_TILE, PLL_RATIO_5_3)
#define WP_CONFIG_1_TILE_4_3_RATIO   WP_CONFIG(CONFIG_1_TILE, PLL_RATIO_4_3)
#define WP_CONFIG_2_TILE_5_3_RATIO   WP_CONFIG(CONFIG_2_TILE, PLL_RATIO_5_3)
#define WP_CONFIG_2_TILE_4_3_RATIO   WP_CONFIG(CONFIG_2_TILE, PLL_RATIO_4_3)
#define WP_CONFIG_0_TILE_PLL_OFF     WP_CONFIG(0, 0)

#define PLL_REF_CLK_FREQ	     (50 * 1000000)
#define PLL_SIMULATION_FREQ	     (10 * 1000000)
#define PLL_RATIO_TO_FREQ(x)	     ((x) * PLL_REF_CLK_FREQ)
#define PLL_DEFAULT_EPP_VALUE	     0x80

#define TIM_SAFE_ENABLE		     0xf1d0dead
@@ -101,6 +100,7 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev)
{
	vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
	vdev->wa.clear_runtime_mem = false;
	vdev->wa.d3hot_after_power_off = true;
}

static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)
@@ -218,7 +218,8 @@ static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
		config = 0;
	}

	ivpu_dbg(vdev, PM, "PLL workpoint request: %d Hz\n", PLL_RATIO_TO_FREQ(target_ratio));
	ivpu_dbg(vdev, PM, "PLL workpoint request: config 0x%04x pll ratio 0x%x\n",
		 config, target_ratio);

	ret = ivpu_pll_cmd_send(vdev, hw->pll.min_ratio, hw->pll.max_ratio, target_ratio, config);
	if (ret) {
@@ -403,11 +404,6 @@ static int ivpu_boot_host_ss_axi_enable(struct ivpu_device *vdev)
	return ivpu_boot_host_ss_axi_drive(vdev, true);
}

static int ivpu_boot_host_ss_axi_disable(struct ivpu_device *vdev)
{
	return ivpu_boot_host_ss_axi_drive(vdev, false);
}

static int ivpu_boot_host_ss_top_noc_drive(struct ivpu_device *vdev, bool enable)
{
	int ret;
@@ -441,11 +437,6 @@ static int ivpu_boot_host_ss_top_noc_enable(struct ivpu_device *vdev)
	return ivpu_boot_host_ss_top_noc_drive(vdev, true);
}

static int ivpu_boot_host_ss_top_noc_disable(struct ivpu_device *vdev)
{
	return ivpu_boot_host_ss_top_noc_drive(vdev, false);
}

static void ivpu_boot_pwr_island_trickle_drive(struct ivpu_device *vdev, bool enable)
{
	u32 val = REGV_RD32(MTL_VPU_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
@@ -504,16 +495,6 @@ static void ivpu_boot_dpu_active_drive(struct ivpu_device *vdev, bool enable)
	REGV_WR32(MTL_VPU_HOST_SS_AON_DPU_ACTIVE, val);
}

static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev)
{
	ivpu_boot_dpu_active_drive(vdev, false);
	ivpu_boot_pwr_island_isolation_drive(vdev, true);
	ivpu_boot_pwr_island_trickle_drive(vdev, false);
	ivpu_boot_pwr_island_drive(vdev, false);

	return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0);
}

static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
{
	int ret;
@@ -629,34 +610,10 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)
static int ivpu_hw_mtl_info_init(struct ivpu_device *vdev)
{
	struct ivpu_hw_info *hw = vdev->hw;
	u32 tile_fuse;

	tile_fuse = REGB_RD32(MTL_BUTTRESS_TILE_FUSE);
	if (!REG_TEST_FLD(MTL_BUTTRESS_TILE_FUSE, VALID, tile_fuse))
		ivpu_warn(vdev, "Tile Fuse: Invalid (0x%x)\n", tile_fuse);

	hw->tile_fuse = REG_GET_FLD(MTL_BUTTRESS_TILE_FUSE, SKU, tile_fuse);
	switch (hw->tile_fuse) {
	case TILE_FUSE_ENABLE_LOWER:
		hw->sku = TILE_SKU_LOWER_MTL;
		hw->config = WP_CONFIG_1_TILE_5_3_RATIO;
		ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Lower\n");
		break;
	case TILE_FUSE_ENABLE_UPPER:
		hw->sku = TILE_SKU_UPPER_MTL;
		hw->config = WP_CONFIG_1_TILE_4_3_RATIO;
		ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Upper\n");
		break;
	case TILE_FUSE_ENABLE_BOTH:

	hw->tile_fuse = TILE_FUSE_ENABLE_BOTH;
	hw->sku = TILE_SKU_BOTH_MTL;
		hw->config = WP_CONFIG_2_TILE_5_3_RATIO;
		ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Both\n");
		break;
	default:
		hw->config = WP_CONFIG_0_TILE_PLL_OFF;
		ivpu_dbg(vdev, MISC, "Tile Fuse: Disable\n");
		break;
	}
	hw->config = WP_CONFIG_2_TILE_4_3_RATIO;

	ivpu_pll_init_frequency_ratios(vdev);

@@ -797,21 +754,8 @@ static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev)
{
	int ret = 0;

	/* FPGA requires manual clearing of IP_Reset bit by enabling quiescent state */
	if (ivpu_is_fpga(vdev)) {
		if (ivpu_boot_host_ss_top_noc_disable(vdev)) {
			ivpu_err(vdev, "Failed to disable TOP NOC\n");
			ret = -EIO;
		}

		if (ivpu_boot_host_ss_axi_disable(vdev)) {
			ivpu_err(vdev, "Failed to disable AXI\n");
			ret = -EIO;
		}
	}

	if (ivpu_boot_pwr_domain_disable(vdev)) {
		ivpu_err(vdev, "Failed to disable power domain\n");
	if (ivpu_hw_mtl_reset(vdev)) {
		ivpu_err(vdev, "Failed to reset the VPU\n");
		ret = -EIO;
	}

@@ -844,6 +788,19 @@ static void ivpu_hw_mtl_wdt_disable(struct ivpu_device *vdev)
	REGV_WR32(MTL_VPU_CPU_SS_TIM_GEN_CONFIG, val);
}

static u32 ivpu_hw_mtl_pll_to_freq(u32 ratio, u32 config)
{
	u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
	u32 cpu_clock;

	if ((config & 0xff) == PLL_RATIO_4_3)
		cpu_clock = pll_clock * 2 / 4;
	else
		cpu_clock = pll_clock * 2 / 5;

	return cpu_clock;
}

/* Register indirect accesses */
static u32 ivpu_hw_mtl_reg_pll_freq_get(struct ivpu_device *vdev)
{
@@ -855,7 +812,7 @@ static u32 ivpu_hw_mtl_reg_pll_freq_get(struct ivpu_device *vdev)
	if (!ivpu_is_silicon(vdev))
		return PLL_SIMULATION_FREQ;

	return PLL_RATIO_TO_FREQ(pll_curr_ratio);
	return ivpu_hw_mtl_pll_to_freq(pll_curr_ratio, vdev->hw->config);
}

static u32 ivpu_hw_mtl_reg_telemetry_offset_get(struct ivpu_device *vdev)
+1 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ struct ivpu_bo;
#define IVPU_IPC_ALIGNMENT	   64

#define IVPU_IPC_HDR_FREE	   0
#define IVPU_IPC_HDR_ALLOCATED	   0
#define IVPU_IPC_HDR_ALLOCATED	   1

/**
 * struct ivpu_ipc_hdr - The IPC message header structure, exchanged
+9 −2
Original line number Diff line number Diff line
@@ -489,12 +489,12 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32

int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
	int ret = 0;
	struct ivpu_file_priv *file_priv = file->driver_priv;
	struct ivpu_device *vdev = file_priv->vdev;
	struct drm_ivpu_submit *params = data;
	struct ivpu_job *job;
	u32 *buf_handles;
	int idx, ret;

	if (params->engine > DRM_IVPU_ENGINE_COPY)
		return -EINVAL;
@@ -523,6 +523,11 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
		goto free_handles;
	}

	if (!drm_dev_enter(&vdev->drm, &idx)) {
		ret = -ENODEV;
		goto free_handles;
	}

	ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n",
		 file_priv->ctx.id, params->buffer_count);

@@ -530,7 +535,7 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
	if (!job) {
		ivpu_err(vdev, "Failed to create job\n");
		ret = -ENOMEM;
		goto free_handles;
		goto dev_exit;
	}

	ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, params->buffer_count,
@@ -548,6 +553,8 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)

job_put:
	job_put(job);
dev_exit:
	drm_dev_exit(idx);
free_handles:
	kfree(buf_handles);

Loading