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

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
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <drm/drm_accel.h> #include <drm/drm_accel.h>
#include <drm/drm_drv.h>
#include <drm/drm_file.h> #include <drm/drm_file.h>
#include <drm/drm_gem.h> #include <drm/drm_gem.h>
#include <drm/drm_ioctl.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 ...@@ -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 pci_dev *pdev = to_pci_dev(vdev->drm.dev);
struct drm_ivpu_param *args = data; struct drm_ivpu_param *args = data;
int ret = 0; int ret = 0;
int idx;
if (!drm_dev_enter(dev, &idx))
return -ENODEV;
switch (args->param) { switch (args->param) {
case DRM_IVPU_PARAM_DEVICE_ID: 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 ...@@ -171,6 +174,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
break; break;
} }
drm_dev_exit(idx);
return ret; return ret;
} }
...@@ -470,8 +474,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev) ...@@ -470,8 +474,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
vdev->hw->ops = &ivpu_hw_mtl_ops; vdev->hw->ops = &ivpu_hw_mtl_ops;
vdev->platform = IVPU_PLATFORM_INVALID; vdev->platform = IVPU_PLATFORM_INVALID;
vdev->context_xa_limit.min = IVPU_GLOBAL_CONTEXT_MMU_SSID + 1; vdev->context_xa_limit.min = IVPU_USER_CONTEXT_MIN_SSID;
vdev->context_xa_limit.max = IVPU_CONTEXT_LIMIT; vdev->context_xa_limit.max = IVPU_USER_CONTEXT_MAX_SSID;
atomic64_set(&vdev->unique_id_counter, 0); atomic64_set(&vdev->unique_id_counter, 0);
xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC); xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC);
xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1); xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1);
...@@ -565,6 +569,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev) ...@@ -565,6 +569,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
ivpu_mmu_global_context_fini(vdev); ivpu_mmu_global_context_fini(vdev);
err_power_down: err_power_down:
ivpu_hw_power_down(vdev); 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: err_xa_destroy:
xa_destroy(&vdev->submitted_jobs_xa); xa_destroy(&vdev->submitted_jobs_xa);
xa_destroy(&vdev->context_xa); xa_destroy(&vdev->context_xa);
...@@ -575,7 +581,11 @@ static void ivpu_dev_fini(struct ivpu_device *vdev) ...@@ -575,7 +581,11 @@ static void ivpu_dev_fini(struct ivpu_device *vdev)
{ {
ivpu_pm_disable(vdev); ivpu_pm_disable(vdev);
ivpu_shutdown(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_job_done_thread_fini(vdev);
ivpu_pm_cancel_recovery(vdev);
ivpu_ipc_fini(vdev); ivpu_ipc_fini(vdev);
ivpu_fw_fini(vdev); ivpu_fw_fini(vdev);
ivpu_mmu_global_context_fini(vdev); ivpu_mmu_global_context_fini(vdev);
...@@ -622,7 +632,7 @@ static void ivpu_remove(struct pci_dev *pdev) ...@@ -622,7 +632,7 @@ static void ivpu_remove(struct pci_dev *pdev)
{ {
struct ivpu_device *vdev = pci_get_drvdata(pdev); struct ivpu_device *vdev = pci_get_drvdata(pdev);
drm_dev_unregister(&vdev->drm); drm_dev_unplug(&vdev->drm);
ivpu_dev_fini(vdev); ivpu_dev_fini(vdev);
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#define __IVPU_DRV_H__ #define __IVPU_DRV_H__
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_managed.h> #include <drm/drm_managed.h>
#include <drm/drm_mm.h> #include <drm/drm_mm.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
...@@ -24,7 +25,10 @@ ...@@ -24,7 +25,10 @@
#define PCI_DEVICE_ID_MTL 0x7d1d #define PCI_DEVICE_ID_MTL 0x7d1d
#define IVPU_GLOBAL_CONTEXT_MMU_SSID 0 #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_NUM_ENGINES 2
#define IVPU_PLATFORM_SILICON 0 #define IVPU_PLATFORM_SILICON 0
...@@ -70,6 +74,7 @@ ...@@ -70,6 +74,7 @@
struct ivpu_wa_table { struct ivpu_wa_table {
bool punit_disabled; bool punit_disabled;
bool clear_runtime_mem; bool clear_runtime_mem;
bool d3hot_after_power_off;
}; };
struct ivpu_hw_info; struct ivpu_hw_info;
......
...@@ -12,24 +12,23 @@ ...@@ -12,24 +12,23 @@
#include "ivpu_mmu.h" #include "ivpu_mmu.h"
#include "ivpu_pm.h" #include "ivpu_pm.h"
#define TILE_FUSE_ENABLE_BOTH 0x0 #define TILE_FUSE_ENABLE_BOTH 0x0
#define TILE_FUSE_ENABLE_UPPER 0x1 #define TILE_SKU_BOTH_MTL 0x3630
#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 */ /* Work point configuration values */
#define WP_CONFIG_1_TILE_5_3_RATIO 0x0101 #define CONFIG_1_TILE 0x01
#define WP_CONFIG_1_TILE_4_3_RATIO 0x0102 #define CONFIG_2_TILE 0x02
#define WP_CONFIG_2_TILE_5_3_RATIO 0x0201 #define PLL_RATIO_5_3 0x01
#define WP_CONFIG_2_TILE_4_3_RATIO 0x0202 #define PLL_RATIO_4_3 0x02
#define WP_CONFIG_0_TILE_PLL_OFF 0x0000 #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_REF_CLK_FREQ (50 * 1000000)
#define PLL_SIMULATION_FREQ (10 * 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 PLL_DEFAULT_EPP_VALUE 0x80
#define TIM_SAFE_ENABLE 0xf1d0dead #define TIM_SAFE_ENABLE 0xf1d0dead
...@@ -101,6 +100,7 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev) ...@@ -101,6 +100,7 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev)
{ {
vdev->wa.punit_disabled = ivpu_is_fpga(vdev); vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
vdev->wa.clear_runtime_mem = false; vdev->wa.clear_runtime_mem = false;
vdev->wa.d3hot_after_power_off = true;
} }
static void ivpu_hw_timeouts_init(struct ivpu_device *vdev) 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) ...@@ -218,7 +218,8 @@ static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
config = 0; 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); ret = ivpu_pll_cmd_send(vdev, hw->pll.min_ratio, hw->pll.max_ratio, target_ratio, config);
if (ret) { if (ret) {
...@@ -403,11 +404,6 @@ static int ivpu_boot_host_ss_axi_enable(struct ivpu_device *vdev) ...@@ -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); 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) static int ivpu_boot_host_ss_top_noc_drive(struct ivpu_device *vdev, bool enable)
{ {
int ret; int ret;
...@@ -441,11 +437,6 @@ static int ivpu_boot_host_ss_top_noc_enable(struct ivpu_device *vdev) ...@@ -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); 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) 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); 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) ...@@ -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); 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) static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
{ {
int ret; int ret;
...@@ -629,34 +610,10 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable) ...@@ -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) static int ivpu_hw_mtl_info_init(struct ivpu_device *vdev)
{ {
struct ivpu_hw_info *hw = vdev->hw; struct ivpu_hw_info *hw = vdev->hw;
u32 tile_fuse;
hw->tile_fuse = TILE_FUSE_ENABLE_BOTH;
tile_fuse = REGB_RD32(MTL_BUTTRESS_TILE_FUSE); hw->sku = TILE_SKU_BOTH_MTL;
if (!REG_TEST_FLD(MTL_BUTTRESS_TILE_FUSE, VALID, tile_fuse)) hw->config = WP_CONFIG_2_TILE_4_3_RATIO;
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->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;
}
ivpu_pll_init_frequency_ratios(vdev); ivpu_pll_init_frequency_ratios(vdev);
...@@ -797,21 +754,8 @@ static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev) ...@@ -797,21 +754,8 @@ static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev)
{ {
int ret = 0; int ret = 0;
/* FPGA requires manual clearing of IP_Reset bit by enabling quiescent state */ if (ivpu_hw_mtl_reset(vdev)) {
if (ivpu_is_fpga(vdev)) { ivpu_err(vdev, "Failed to reset the VPU\n");
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");
ret = -EIO; ret = -EIO;
} }
...@@ -844,6 +788,19 @@ static void ivpu_hw_mtl_wdt_disable(struct ivpu_device *vdev) ...@@ -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); 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 */ /* Register indirect accesses */
static u32 ivpu_hw_mtl_reg_pll_freq_get(struct ivpu_device *vdev) 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) ...@@ -855,7 +812,7 @@ static u32 ivpu_hw_mtl_reg_pll_freq_get(struct ivpu_device *vdev)
if (!ivpu_is_silicon(vdev)) if (!ivpu_is_silicon(vdev))
return PLL_SIMULATION_FREQ; 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) static u32 ivpu_hw_mtl_reg_telemetry_offset_get(struct ivpu_device *vdev)
......
...@@ -21,7 +21,7 @@ struct ivpu_bo; ...@@ -21,7 +21,7 @@ struct ivpu_bo;
#define IVPU_IPC_ALIGNMENT 64 #define IVPU_IPC_ALIGNMENT 64
#define IVPU_IPC_HDR_FREE 0 #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 * struct ivpu_ipc_hdr - The IPC message header structure, exchanged
......
...@@ -489,12 +489,12 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 ...@@ -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 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_file_priv *file_priv = file->driver_priv;
struct ivpu_device *vdev = file_priv->vdev; struct ivpu_device *vdev = file_priv->vdev;
struct drm_ivpu_submit *params = data; struct drm_ivpu_submit *params = data;
struct ivpu_job *job; struct ivpu_job *job;
u32 *buf_handles; u32 *buf_handles;
int idx, ret;
if (params->engine > DRM_IVPU_ENGINE_COPY) if (params->engine > DRM_IVPU_ENGINE_COPY)
return -EINVAL; return -EINVAL;
...@@ -523,6 +523,11 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) ...@@ -523,6 +523,11 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
goto free_handles; 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", ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n",
file_priv->ctx.id, params->buffer_count); 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) ...@@ -530,7 +535,7 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
if (!job) { if (!job) {
ivpu_err(vdev, "Failed to create job\n"); ivpu_err(vdev, "Failed to create job\n");
ret = -ENOMEM; ret = -ENOMEM;
goto free_handles; goto dev_exit;
} }
ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, params->buffer_count, 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) ...@@ -548,6 +553,8 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
job_put: job_put:
job_put(job); job_put(job);
dev_exit:
drm_dev_exit(idx);
free_handles: free_handles:
kfree(buf_handles); kfree(buf_handles);
......
...@@ -98,12 +98,18 @@ static int ivpu_resume(struct ivpu_device *vdev) ...@@ -98,12 +98,18 @@ static int ivpu_resume(struct ivpu_device *vdev)
static void ivpu_pm_recovery_work(struct work_struct *work) static void ivpu_pm_recovery_work(struct work_struct *work)
{ {
struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, recovery_work); struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, recovery_work);
struct ivpu_device *vdev = pm->vdev; struct ivpu_device *vdev = pm->vdev;
char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL}; char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL};
int ret; int ret;
ret = pci_reset_function(to_pci_dev(vdev->drm.dev)); retry:
if (ret) ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev));
if (ret == -EAGAIN && !drm_dev_is_unplugged(&vdev->drm)) {
cond_resched();
goto retry;
}
if (ret && ret != -EAGAIN)
ivpu_err(vdev, "Failed to reset VPU: %d\n", ret); ivpu_err(vdev, "Failed to reset VPU: %d\n", ret);
kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt); kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt);
...@@ -306,6 +312,11 @@ int ivpu_pm_init(struct ivpu_device *vdev) ...@@ -306,6 +312,11 @@ int ivpu_pm_init(struct ivpu_device *vdev)
return 0; return 0;
} }
void ivpu_pm_cancel_recovery(struct ivpu_device *vdev)
{
cancel_work_sync(&vdev->pm->recovery_work);
}
void ivpu_pm_enable(struct ivpu_device *vdev) void ivpu_pm_enable(struct ivpu_device *vdev)
{ {
struct device *dev = vdev->drm.dev; struct device *dev = vdev->drm.dev;
......
...@@ -21,6 +21,7 @@ struct ivpu_pm_info { ...@@ -21,6 +21,7 @@ struct ivpu_pm_info {
int ivpu_pm_init(struct ivpu_device *vdev); int ivpu_pm_init(struct ivpu_device *vdev);
void ivpu_pm_enable(struct ivpu_device *vdev); void ivpu_pm_enable(struct ivpu_device *vdev);
void ivpu_pm_disable(struct ivpu_device *vdev); void ivpu_pm_disable(struct ivpu_device *vdev);
void ivpu_pm_cancel_recovery(struct ivpu_device *vdev);
int ivpu_pm_suspend_cb(struct device *dev); int ivpu_pm_suspend_cb(struct device *dev);
int ivpu_pm_resume_cb(struct device *dev); int ivpu_pm_resume_cb(struct device *dev);
......
...@@ -146,8 +146,8 @@ int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size) ...@@ -146,8 +146,8 @@ int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size)
unsigned int order; unsigned int order;
u64 root_size; u64 root_size;
root_size = rounddown_pow_of_two(size); order = ilog2(size) - ilog2(chunk_size);
order = ilog2(root_size) - ilog2(chunk_size); root_size = chunk_size << order;
root = drm_block_alloc(mm, NULL, order, offset); root = drm_block_alloc(mm, NULL, order, offset);
if (!root) if (!root)
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/apple-gmux.h> #include <linux/apple-gmux.h>
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <drm/drm_probe_helper.h>
#include "nouveau_drv.h" #include "nouveau_drv.h"
#include "nouveau_reg.h" #include "nouveau_reg.h"
...@@ -299,8 +300,12 @@ nv50_backlight_init(struct nouveau_backlight *bl, ...@@ -299,8 +300,12 @@ nv50_backlight_init(struct nouveau_backlight *bl,
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
struct nvif_object *device = &drm->client.device.object; struct nvif_object *device = &drm->client.device.object;
/*
* Note when this runs the connectors have not been probed yet,
* so nv_conn->base.status is not set yet.
*/
if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(ffs(nv_encoder->dcb->or) - 1)) || if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(ffs(nv_encoder->dcb->or) - 1)) ||
nv_conn->base.status != connector_status_connected) drm_helper_probe_detect(&nv_conn->base, NULL, false) != connector_status_connected)
return -ENODEV; return -ENODEV;
if (nv_conn->type == DCB_CONNECTOR_eDP) { if (nv_conn->type == DCB_CONNECTOR_eDP) {
......
...@@ -89,7 +89,8 @@ static int check_block(struct kunit *test, struct drm_buddy *mm, ...@@ -89,7 +89,8 @@ static int check_block(struct kunit *test, struct drm_buddy *mm,
err = -EINVAL; err = -EINVAL;
} }
if (!is_power_of_2(block_size)) { /* We can't use is_power_of_2() for a u64 on 32-bit systems. */
if (block_size & (block_size - 1)) {
kunit_err(test, "block size not power of two\n"); kunit_err(test, "block size not power of two\n");
err = -EINVAL; err = -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment