Commit 69620d5c authored by Daniel Vetter's avatar Daniel Vetter
Browse files

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



Short summary of fixes pull:

 * various ivpu fixes
 * fix nouveau backlight registration
 * fix buddy allocator in 32-bit systems

Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20230330141006.GA22908@linux-uq9g
parents 493fd8b8 25bbe844
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