summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-09-22 18:32:50 +1000
committerDave Airlie <airlied@redhat.com>2026-09-22 18:35:06 +1000
commitb0a3a811634aa7422f8a92196db47a06a70bda16 (patch)
tree15f8b05b9a0e99e87fecb6751a0a9ef59589c28c /drivers/gpu
parent014ee7742bed896f1aee13ecdee5fe8c7826c0a1 (diff)
parent93f51579e7df248780214094418f205253383cc5 (diff)
downloadlinux-next-b0a3a811634aa7422f8a92196db47a06a70bda16.tar.gz
linux-next-b0a3a811634aa7422f8a92196db47a06a70bda16.zip
Backmerge tag 'v7.3-rc4' into drm-next
Linux 7.3-rc4 Requested by Philipp Stanner for 2ab510e63197360945f915dd5631a77c63ac6b27 would be needed as a groundlayer for further patches that extend the locking in drm_sched Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/adp/Kconfig1
-rw-r--r--drivers/gpu/drm/ast/ast_cursor.c3
-rw-r--r--drivers/gpu/drm/bridge/tc358768.c15
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi83.c6
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt7
-rw-r--r--drivers/gpu/drm/drm_atomic_uapi.c13
-rw-r--r--drivers/gpu/drm/drm_exec.c13
-rw-r--r--drivers/gpu/drm/drm_panic_helper_qr.rs4
-rw-r--r--drivers/gpu/drm/gud/gud_pipe.c7
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.c15
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_caps.c9
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c15
-rw-r--r--drivers/gpu/drm/i915/i915_query.c4
-rw-r--r--drivers/gpu/drm/logicvc/Kconfig1
-rw-r--r--drivers/gpu/drm/loongson/lsdc_plane.c5
-rw-r--r--drivers/gpu/drm/msm/Makefile1
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gmu.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a6xx_gpu.c12
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_device.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c15
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c1
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.c21
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c36
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_phy.c8
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c2
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c1
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h3
-rw-r--r--drivers/gpu/drm/msm/msm_gem_vma.c2
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.c2
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.h1
-rw-r--r--drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml2
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c4
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig3
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c7
-rw-r--r--drivers/gpu/drm/scheduler/sched_entity.c8
-rw-r--r--drivers/gpu/drm/scheduler/sched_rq.c20
-rw-r--r--drivers/gpu/drm/scheduler/tests/mock_scheduler.c11
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c2
-rw-r--r--drivers/gpu/drm/vboxvideo/vbox_mode.c4
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c2
-rw-r--r--drivers/gpu/drm/verisilicon/vs_cursor_plane.c2
-rw-r--r--drivers/gpu/drm/verisilicon/vs_hwdb.c44
-rw-r--r--drivers/gpu/drm/verisilicon/vs_hwdb.h4
-rw-r--r--drivers/gpu/drm/verisilicon/vs_primary_plane.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_plane.c4
-rw-r--r--drivers/gpu/drm/xe/xe_pagefault.c8
-rw-r--r--drivers/gpu/drm/xe/xe_pagefault_types.h3
47 files changed, 223 insertions, 136 deletions
diff --git a/drivers/gpu/drm/adp/Kconfig b/drivers/gpu/drm/adp/Kconfig
index 9fcc27eb200d..acfa21ee06d2 100644
--- a/drivers/gpu/drm/adp/Kconfig
+++ b/drivers/gpu/drm/adp/Kconfig
@@ -6,7 +6,6 @@ config DRM_ADP
select DRM_KMS_HELPER
select DRM_BRIDGE_CONNECTOR
select DRM_DISPLAY_HELPER
- select DRM_KMS_DMA_HELPER
select DRM_GEM_DMA_HELPER
select DRM_PANEL_BRIDGE
select VIDEOMODE_HELPERS
diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c
index fd19c45f2abe..690d4cd1db5e 100644
--- a/drivers/gpu/drm/ast/ast_cursor.c
+++ b/drivers/gpu/drm/ast/ast_cursor.c
@@ -25,6 +25,7 @@
#include <linux/sizes.h>
#include <drm/drm_atomic.h>
+#include <drm/drm_blend.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -355,6 +356,8 @@ int ast_cursor_plane_init(struct ast_device *ast)
}
drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs);
drm_plane_enable_fb_damage_clips(cursor_plane);
+ drm_plane_create_blend_mode_property(cursor_plane,
+ BIT(DRM_MODE_BLEND_COVERAGE));
return 0;
}
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
index d1fc6af37cc5..19b43efcf93f 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -1263,10 +1263,13 @@ tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
return input_fmts;
}
-static bool tc358768_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static int tc358768_bridge_atomic_check(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
{
+ struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+
/* Default to positive sync */
if (!(adjusted_mode->flags &
@@ -1277,13 +1280,15 @@ static bool tc358768_mode_fixup(struct drm_bridge *bridge,
(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
adjusted_mode->flags |= DRM_MODE_FLAG_PVSYNC;
- return true;
+ bridge_state->input_bus_cfg.flags = bridge->timings->input_bus_flags;
+
+ return 0;
}
static const struct drm_bridge_funcs tc358768_bridge_funcs = {
.attach = tc358768_bridge_attach,
.mode_valid = tc358768_bridge_mode_valid,
- .mode_fixup = tc358768_mode_fixup,
+ .atomic_check = tc358768_bridge_atomic_check,
.atomic_pre_enable = tc358768_bridge_atomic_pre_enable,
.atomic_enable = tc358768_bridge_atomic_enable,
.atomic_disable = tc358768_bridge_atomic_disable,
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index b4a4dd83eb5c..eb5b249cc43c 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -405,7 +405,7 @@ retry:
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
- return 0;
+ return err;
}
static void sn65dsi83_reset_work(struct work_struct *ws)
@@ -421,11 +421,13 @@ static void sn65dsi83_reset_work(struct work_struct *ws)
ret = sn65dsi83_reset_pipe(ctx);
if (ret) {
dev_err(ctx->dev, "reset pipe failed %pe\n", ERR_PTR(ret));
- return;
+ goto bridge_exit;
}
+
if (ctx->irq)
enable_irq(ctx->irq);
+bridge_exit:
drm_bridge_exit(idx);
}
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
index 4546363447ff..0f3d85e4845e 100644
--- a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
@@ -7,3 +7,10 @@ kms_hdmi_inject@inject-4k,Fail
kms_lease@lease-uevent,Fail
msm/msm_mapping@memptrs,Fail
msm/msm_mapping@ring,Fail
+
+# Started failing with v7.3-rc2 backmerge
+# https://gitlab.freedesktop.org/drm/msm/-/work_items/104
+kms_cursor_legacy@single-move,Fail
+kms_cursor_legacy@torture-bo,Fail
+kms_cursor_legacy@forked-bo,Fail
+kms_cursor_legacy@torture-move,Fail
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 4acfb588c412..1eebcf6f5e05 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1469,10 +1469,12 @@ static int prepare_signaling(struct drm_device *dev,
struct dma_fence *fence;
struct drm_out_fence_state *f;
+ ret = -ENOMEM;
+
f = krealloc(*fence_state, sizeof(**fence_state) *
(*num_fences + 1), GFP_KERNEL);
if (!f)
- return -ENOMEM;
+ goto err_free_event;
memset(&f[*num_fences], 0, sizeof(*f));
@@ -1481,12 +1483,12 @@ static int prepare_signaling(struct drm_device *dev,
fence = drm_crtc_create_fence(crtc);
if (!fence)
- return -ENOMEM;
+ goto err_free_event;
ret = setup_out_fence(&f[(*num_fences)++], fence);
if (ret) {
dma_fence_put(fence);
- return ret;
+ goto err_free_event;
}
crtc_state->event->base.fence = fence;
@@ -1542,6 +1544,11 @@ static int prepare_signaling(struct drm_device *dev,
}
return 0;
+
+err_free_event:
+ drm_event_cancel_free(dev, &crtc_state->event->base);
+ crtc_state->event = NULL;
+ return ret;
}
static void complete_signaling(struct drm_device *dev,
diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
index 41034a5996ff..2453ec41360f 100644
--- a/drivers/gpu/drm/drm_exec.c
+++ b/drivers/gpu/drm/drm_exec.c
@@ -322,6 +322,19 @@ int drm_exec_prepare_array(struct drm_exec *exec,
{
int ret;
+ /*
+ * Make sure to lock a contended object even when no objects are
+ * given, otherwise drm_exec_retry_on_contention() would loop
+ * forever on patterns like:
+ *
+ * ret = drm_exec_prepare_array(exec, objs, num_objects, ...);
+ * drm_exec_retry_on_contention(exec);
+ *
+ * with num_objects == 0.
+ */
+ if (!num_objects)
+ return drm_exec_lock_contended(exec);
+
for (unsigned int i = 0; i < num_objects; ++i) {
ret = drm_exec_prepare_obj(exec, objects[i], num_fences);
if (unlikely(ret))
diff --git a/drivers/gpu/drm/drm_panic_helper_qr.rs b/drivers/gpu/drm/drm_panic_helper_qr.rs
index 22966956331e..4941731fb60f 100644
--- a/drivers/gpu/drm/drm_panic_helper_qr.rs
+++ b/drivers/gpu/drm/drm_panic_helper_qr.rs
@@ -407,8 +407,8 @@ impl DecFifo {
for i in (0..self.len).rev() {
self.decimals[i + len] = self.decimals[i];
}
- for i in 0..len {
- self.decimals[i] = (chunk % 10) as u8;
+ for decimal in &mut self.decimals[..len] {
+ *decimal = (chunk % 10) as u8;
chunk = div10(chunk);
}
self.len += len;
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index 5ef887d8485a..aa7792966287 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -482,6 +482,9 @@ int gud_plane_atomic_check(struct drm_plane *plane,
if (!new_plane_state->visible)
return 0;
+ if (gdrm->flags & GUD_DISPLAY_FLAG_FULL_UPDATE)
+ new_plane_state->ignore_damage_clips = true;
+
if (old_plane_state->rotation != new_plane_state->rotation)
crtc_state->mode_changed = true;
@@ -562,8 +565,8 @@ int gud_plane_atomic_check(struct drm_plane *plane,
goto out;
}
- req->properties[num_properties + i].prop = cpu_to_le16(prop);
- req->properties[num_properties + i].val = cpu_to_le64(val);
+ req->properties[num_properties].prop = cpu_to_le16(prop);
+ req->properties[num_properties].val = cpu_to_le64(val);
num_properties++;
}
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index cce041e1da51..90173040d825 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -531,18 +531,13 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
}
static void i9xx_cursor_disable_sel_fetch_arm(struct intel_dsb *dsb,
- struct intel_plane *plane)
+ struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(plane);
enum pipe pipe = plane->pipe;
- /*
- * Clear this whenever the hardware has selective fetch, not just when
- * the current state uses it. The cursor may have been enabled with
- * selective fetch earlier and had its enable bit orphaned when the
- * feature was switched off.
- */
- if (!HAS_PSR2_SEL_FETCH(display))
+ if (!crtc_state->enable_psr2_sel_fetch)
return;
intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), 0);
@@ -592,7 +587,7 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb,
if (crtc_state->enable_psr2_su_region_et)
wa_16021440873(dsb, plane, crtc_state, plane_state);
else
- i9xx_cursor_disable_sel_fetch_arm(dsb, plane);
+ i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
}
}
@@ -701,7 +696,7 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb,
if (plane_state)
i9xx_cursor_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state);
else
- i9xx_cursor_disable_sel_fetch_arm(dsb, plane);
+ i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
if (plane->cursor.base != base ||
plane->cursor.size != fbc_ctl ||
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
index 7b6cc6055da8..98657aa4d3d5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_caps.c
@@ -426,12 +426,15 @@ calc_allowed_config_filter(struct intel_dp_link_caps *link_caps,
const struct intel_dp_link_config *forced_params)
{
struct intel_dp_link_caps_filter allowed_configs = INTEL_DP_LINK_CAPS_FILTER_NONE;
+ struct intel_display *display = to_intel_display(link_caps->dp);
struct intel_dp_link_caps_order order = bw_desc_config_order();
struct intel_dp_link_caps_iter iter;
struct intel_dp_link_config config;
iter_start(&iter, link_caps, order, enabled_configs);
for_each_dp_link_config(&iter, &config) {
+ int config_idx;
+
if (forced_params->rate &&
forced_params->rate != config.rate)
continue;
@@ -446,7 +449,11 @@ calc_allowed_config_filter(struct intel_dp_link_caps *link_caps,
if (config.lane_count > max_limits->lane_count)
continue;
- allowed_configs.config_mask |= BIT(iter_pos_to_idx(link_caps, order, iter.pos));
+ config_idx = iter_pos_to_idx(link_caps, order, iter.pos);
+ if (drm_WARN_ON(display->drm, config_idx < 0))
+ continue;
+
+ allowed_configs.config_mask |= BIT(config_idx);
}
intel_dp_link_caps_iter_end(&iter);
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 8c0f414badf3..45e8379d93d4 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -880,18 +880,13 @@ skl_plane_disable_arm(struct intel_dsb *dsb,
}
static void icl_plane_disable_sel_fetch_arm(struct intel_dsb *dsb,
- struct intel_plane *plane)
+ struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(plane);
enum pipe pipe = plane->pipe;
- /*
- * Clear this whenever the hardware has selective fetch, not just when
- * the current state uses it. The plane may have been enabled with
- * selective fetch earlier and had its enable bit orphaned when the
- * feature was switched off.
- */
- if (!HAS_PSR2_SEL_FETCH(display))
+ if (!crtc_state->enable_psr2_sel_fetch)
return;
intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0);
@@ -927,7 +922,7 @@ icl_plane_disable_arm(struct intel_dsb *dsb,
skl_write_plane_wm(dsb, plane, crtc_state);
- icl_plane_disable_sel_fetch_arm(dsb, plane);
+ icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state);
if (plane_has_normalizer(plane))
intel_de_write_dsb(display, dsb,
@@ -1647,7 +1642,7 @@ static void icl_plane_update_sel_fetch_arm(struct intel_dsb *dsb,
intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id),
SEL_FETCH_PLANE_CTL_ENABLE);
else
- icl_plane_disable_sel_fetch_arm(dsb, plane);
+ icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state);
}
static void
diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c
index 0c55fb6e9727..11157fb14db3 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -403,8 +403,10 @@ static int query_perf_config_list(struct drm_i915_private *i915,
ids = krealloc(oa_config_ids,
n_configs * sizeof(*oa_config_ids),
GFP_KERNEL);
- if (!ids)
+ if (!ids) {
+ kfree(oa_config_ids);
return -ENOMEM;
+ }
alloc = fetch_and_zero(&n_configs);
diff --git a/drivers/gpu/drm/logicvc/Kconfig b/drivers/gpu/drm/logicvc/Kconfig
index 579a358ed5cf..11aae1626199 100644
--- a/drivers/gpu/drm/logicvc/Kconfig
+++ b/drivers/gpu/drm/logicvc/Kconfig
@@ -4,7 +4,6 @@ config DRM_LOGICVC
depends on OF || COMPILE_TEST
select DRM_CLIENT_SELECTION
select DRM_KMS_HELPER
- select DRM_KMS_DMA_HELPER
select DRM_GEM_DMA_HELPER
select REGMAP
select REGMAP_MMIO
diff --git a/drivers/gpu/drm/loongson/lsdc_plane.c b/drivers/gpu/drm/loongson/lsdc_plane.c
index 25a38e6a6e51..35d45e893f2d 100644
--- a/drivers/gpu/drm/loongson/lsdc_plane.c
+++ b/drivers/gpu/drm/loongson/lsdc_plane.c
@@ -7,6 +7,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_print.h>
@@ -765,7 +766,7 @@ int ls7a1000_cursor_plane_init(struct drm_device *ddev,
drm_plane_helper_add(plane, &ls7a1000_cursor_plane_helper_funcs);
- return 0;
+ return drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_COVERAGE));
}
int ls7a2000_cursor_plane_init(struct drm_device *ddev,
@@ -790,5 +791,5 @@ int ls7a2000_cursor_plane_init(struct drm_device *ddev,
drm_plane_helper_add(plane, &ls7a2000_cursor_plane_helper_funcs);
- return 0;
+ return drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_COVERAGE));
}
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index d0c3a4c6703b..0b8f2cafed19 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -177,7 +177,6 @@ quiet_cmd_headergen = GENHDR $@
cmd_headergen = mkdir -p $(obj)/generated && $(PYTHON3) $(src)/registers/gen_header.py \
$(headergen-opts) --rnn $(src)/registers --xml $< c-defines > $@
-# TODO how to do this for a2xx/a5xx which have different .xml arg?
quiet_cmd_headergen_json = GENHDRJSN $@
cmd_headergen_json = mkdir -p $(obj)/generated && $(PYTHON3) $(src)/registers/gen_header.py \
$(headergen-opts) --rnn $(src)/registers --xml $(filter %.xml,$^) perfcntrs --json $< > $@
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 27cac853975f..6d49c51df1a2 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -320,7 +320,7 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu)
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val,
- (val & mask) == reset_val, 100, 10000);
+ (val & mask) == reset_val, 100, 100000);
if (ret)
DRM_DEV_ERROR(gmu->dev, "GMU firmware initialization timed out\n");
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index f9de9329dee3..081e79ea4652 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -23,9 +23,15 @@ static u64 a6xx_gmu_get_timestamp(struct msm_gpu *gpu)
u64 count_hi, count_lo, temp;
do {
- count_hi = gmu_read(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_H);
- count_lo = gmu_read(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L);
- temp = gmu_read(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_H);
+ if (adreno_is_a750_family(adreno_gpu)) {
+ count_hi = gmu_read(&a6xx_gpu->gmu, REG_A7XX_GMU_CX_AO_COUNTER_H);
+ count_lo = gmu_read(&a6xx_gpu->gmu, REG_A7XX_GMU_CX_AO_COUNTER_L);
+ temp = gmu_read(&a6xx_gpu->gmu, REG_A7XX_GMU_CX_AO_COUNTER_H);
+ } else {
+ count_hi = gmu_read(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_H);
+ count_lo = gmu_read(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L);
+ temp = gmu_read(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_H);
+ }
} while (unlikely(count_hi != temp));
return (count_hi << 32) | count_lo;
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 7f20320ef66a..05c77fe27e62 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -25,7 +25,7 @@ MODULE_PARM_DESC(disable_acd, "Forcefully disable GPU ACD");
module_param_unsafe(disable_acd, bool, 0400);
static bool skip_gpu;
-MODULE_PARM_DESC(no_gpu, "Disable GPU driver register (0=enable GPU driver register (default), 1=skip GPU driver register");
+MODULE_PARM_DESC(skip_gpu, "Disable GPU driver register (0=enable GPU driver register (default), 1=skip GPU driver register");
module_param(skip_gpu, bool, 0400);
extern const struct adreno_gpulist a2xx_gpulist;
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 8cd2020d4b7e..5832dc25d6bf 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -52,6 +52,12 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname,
return -ENODEV;
}
+ /* We need PAS to be able to load the firmware */
+ if (!qcom_pas_is_available()) {
+ DRM_DEV_ERROR(dev, "PAS is not available\n");
+ return -EPROBE_DEFER;
+ }
+
ret = of_reserved_mem_region_to_resource(np, 0, &r);
if (ret) {
zap_available = false;
@@ -170,18 +176,11 @@ out:
int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
- struct platform_device *pdev = gpu->pdev;
/* Short cut if we determine the zap shader isn't available/needed */
if (!zap_available)
return -ENODEV;
- /* We need PAS to be able to load the firmware */
- if (!qcom_pas_is_available()) {
- DRM_DEV_ERROR(&pdev->dev, "PAS is not available\n");
- return -EPROBE_DEFER;
- }
-
return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid);
}
@@ -1262,6 +1261,8 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
release_firmware(adreno_gpu->fw[i]);
+ pm_runtime_dont_use_autosuspend(&gpu->pdev->dev);
+
if (priv && pm_runtime_enabled(&priv->gpu_pdev->dev))
pm_runtime_disable(&priv->gpu_pdev->dev);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 36a497f1d6c1..e8729fe1cfef 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -118,6 +118,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx)
ctx->pending_intf_flush_mask = 0;
ctx->pending_wb_flush_mask = 0;
ctx->pending_cwb_flush_mask = 0;
+ ctx->pending_periph_flush_mask = 0;
ctx->pending_merge_3d_flush_mask = 0;
ctx->pending_dsc_flush_mask = 0;
ctx->pending_cdm_flush_mask = 0;
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index bc646d172abe..4dcbd9b99d06 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -756,6 +756,7 @@ enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
struct msm_dp_link_info *link_info;
u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
int mode_pclk_khz = mode->clock;
+ int link_pclk_khz;
bool is_yuv_420;
if (!dp || !mode_pclk_khz || !dp->connector) {
@@ -775,6 +776,8 @@ enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
if (is_yuv_420 && !msm_dp_display->panel->vsc_sdp_supported)
return MODE_NO_420;
+ link_pclk_khz = is_yuv_420 ? mode_pclk_khz / 2 : mode_pclk_khz;
+
if (is_yuv_420 || msm_dp_display->wide_bus_supported)
mode_pclk_khz /= 2;
@@ -786,9 +789,9 @@ enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
mode_bpp = default_bpp;
mode_bpp = msm_dp_panel_get_mode_bpp(msm_dp_display->panel,
- mode_bpp, mode_pclk_khz);
+ mode_bpp, link_pclk_khz);
- mode_rate_khz = mode_pclk_khz * mode_bpp;
+ mode_rate_khz = link_pclk_khz * mode_bpp;
supported_rate_khz = link_info->num_lanes * link_info->rate * 8;
if (mode_rate_khz > supported_rate_khz)
@@ -1458,6 +1461,20 @@ void msm_dp_display_atomic_disable(struct msm_dp *dp)
msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+ /*
+ * If .atomic_enable() bailed out - link training failure is the common
+ * case - the mainlink was never brought up and ->power_on stayed false.
+ * Driving the PUSH_IDLE pattern into a controller that was never
+ * enabled times out, and .atomic_post_disable() then drops the
+ * controller's runtime-PM reference without tearing the PHY back down,
+ * because msm_dp_display_disable() returns early on !power_on. On
+ * glymur (Snapdragon X2 Elite) that combination is answered by a
+ * TrustZone-level SOCCP/ADSP force-stop and a silent SoC reset.
+ * There is nothing to push idle, so leave it alone.
+ */
+ if (!dp->power_on)
+ return;
+
msm_dp_ctrl_push_idle(msm_dp_display->ctrl);
}
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7e4e3718b536..b292dfd266d1 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -129,7 +129,7 @@ struct msm_dsi_host {
struct clk *dsi_pll_pixel_clk;
unsigned long byte_clk_rate;
- unsigned long byte_intf_clk_rate;
+ bool byte_intf_clk_div_2;
unsigned long pixel_clk_rate;
unsigned long esc_clk_rate;
@@ -382,8 +382,20 @@ int msm_dsi_runtime_resume(struct device *dev)
int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
{
+ unsigned long byte_intf_clk_rate;
+ long rounded_byte_clk_rate;
int ret;
+ rounded_byte_clk_rate = clk_round_rate(msm_host->byte_clk,
+ msm_host->byte_clk_rate);
+ if (rounded_byte_clk_rate < 0) {
+ pr_err("%s: failed to round byte clock rate, %ld\n",
+ __func__, rounded_byte_clk_rate);
+ return rounded_byte_clk_rate;
+ }
+
+ msm_host->byte_clk_rate = rounded_byte_clk_rate;
+
DBG("Set clk rates: pclk=%lu, byteclk=%lu",
msm_host->pixel_clk_rate, msm_host->byte_clk_rate);
@@ -401,7 +413,11 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
}
if (msm_host->byte_intf_clk) {
- ret = clk_set_rate(msm_host->byte_intf_clk, msm_host->byte_intf_clk_rate);
+ byte_intf_clk_rate = msm_host->byte_clk_rate;
+ if (msm_host->byte_intf_clk_div_2)
+ byte_intf_clk_rate /= 2;
+
+ ret = clk_set_rate(msm_host->byte_intf_clk, byte_intf_clk_rate);
if (ret) {
pr_err("%s: Failed to set rate byte intf clk, %d\n",
__func__, ret);
@@ -669,24 +685,12 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
{
- long rounded_byte_clk_rate;
-
if (!msm_host->mode) {
pr_err("%s: mode not set\n", __func__);
return -EINVAL;
}
dsi_calc_pclk(msm_host, is_bonded_dsi);
-
- rounded_byte_clk_rate = clk_round_rate(msm_host->byte_clk,
- msm_host->byte_clk_rate);
- if (rounded_byte_clk_rate < 0) {
- pr_err("%s: failed to round byte clock rate, %ld\n",
- __func__, rounded_byte_clk_rate);
- return rounded_byte_clk_rate;
- }
-
- msm_host->byte_clk_rate = rounded_byte_clk_rate;
msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
return 0;
}
@@ -2495,9 +2499,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
goto unlock_ret;
}
- msm_host->byte_intf_clk_rate = msm_host->byte_clk_rate;
- if (phy_shared_timings->byte_intf_clk_div_2)
- msm_host->byte_intf_clk_rate /= 2;
+ msm_host->byte_intf_clk_div_2 = phy_shared_timings->byte_intf_clk_div_2;
msm_dsi_sfpb_config(msm_host, true);
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
index eb1088755cb3..77dce35cd45e 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
@@ -168,13 +168,13 @@ static int msm_hdmi_phy_probe(struct platform_device *pdev)
ret = msm_hdmi_phy_resource_enable(phy);
if (ret)
- return ret;
+ goto err_pm_disable;
ret = msm_hdmi_phy_pll_init(pdev, phy->cfg->type);
if (ret) {
DRM_DEV_ERROR(dev, "couldn't init PLL\n");
msm_hdmi_phy_resource_disable(phy);
- return ret;
+ goto err_pm_disable;
}
msm_hdmi_phy_resource_disable(phy);
@@ -182,6 +182,10 @@ static int msm_hdmi_phy_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, phy);
return 0;
+
+err_pm_disable:
+ pm_runtime_disable(dev);
+ return ret;
}
static void msm_hdmi_phy_remove(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index db1b655dd055..f3d2eaa04f14 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (1=on (default), 0=disab
module_param(modeset, bool, 0600);
static bool separate_gpu_kms;
-MODULE_PARM_DESC(separate_gpu_drm, "Use separate DRM device for the GPU (0=single DRM device for both GPU and display (default), 1=two DRM devices)");
+MODULE_PARM_DESC(separate_gpu_kms, "Use separate DRM device for the GPU (0=single DRM device for both GPU and display (default), 1=two DRM devices)");
module_param(separate_gpu_kms, bool, 0400);
DECLARE_FAULT_ATTR(fail_gem_alloc);
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 89ca9da3e1f2..dd6d6c507d77 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -155,6 +155,7 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
helper->fb = buffer->fb;
fbi->fbops = &msm_fb_ops;
+ fbi->flags |= FBINFO_VIRTFB; /* system memory */
drm_fb_helper_fill_info(fbi, helper, sizes);
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index dff60cbc9d95..7c6a8c01f910 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -68,6 +68,9 @@ struct msm_gem_vm {
/** @base: Inherit from drm_gpuvm. */
struct drm_gpuvm base;
+ /** @rcu: RCU-delayed free so an exported sched fence->sched stays valid. */
+ struct rcu_head rcu;
+
/**
* @sched: Scheduler used for asynchronous VM_BIND request.
*
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index c11d021581e0..1badec3caa7b 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -166,7 +166,7 @@ msm_gem_vm_free(struct drm_gpuvm *gpuvm)
dma_fence_put(vm->last_fence);
put_pid(vm->pid);
kfree(vm->log);
- kfree(vm);
+ kfree_rcu(vm, rcu);
}
/**
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c
index 59c69aa75649..38e1e6866301 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.c
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
@@ -140,5 +140,5 @@ void msm_ringbuffer_destroy(struct msm_ringbuffer *ring)
msm_gem_kernel_put(ring->bo, ring->gpu->vm);
- kfree(ring);
+ kfree_rcu(ring, rcu);
}
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h
index 3631ec283c6e..0bfb6b0f42fa 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.h
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.h
@@ -55,6 +55,7 @@ struct msm_ringbuffer {
/*
* The job scheduler for this ring.
*/
+ struct rcu_head rcu;
struct drm_gpu_scheduler sched;
bool sched_initialized;
diff --git a/drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml b/drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml
index 33404eb18fd0..b3082738c99d 100644
--- a/drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml
+++ b/drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml
@@ -141,6 +141,8 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
<reg32 offset="0x1f9f0" name="GMU_BOOT_KMD_LM_HANDSHAKE"/>
<reg32 offset="0x1f957" name="GMU_LLM_GLM_SLEEP_CTRL"/>
<reg32 offset="0x1f958" name="GMU_LLM_GLM_SLEEP_STATUS"/>
+ <reg32 offset="0x1f880" name="GMU_CX_AO_COUNTER_L" variants="A7XX"/>
+ <reg32 offset="0x1f881" name="GMU_CX_AO_COUNTER_H" variants="A7XX"/>
<reg32 offset="0x1f888" name="GMU_ALWAYS_ON_COUNTER_L" variants="A6XX-A7XX"/>
<reg32 offset="0x1f840" name="GMU_ALWAYS_ON_COUNTER_L" variants="A8XX-"/>
<reg32 offset="0x1f889" name="GMU_ALWAYS_ON_COUNTER_H" variants="A6XX-A7XX"/>
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index ed88a649667e..63fc7c6a7f1a 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -30,6 +30,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder.h>
#include <drm/drm_framebuffer.h>
@@ -993,6 +994,9 @@ static struct drm_plane *qxl_create_plane(struct qxl_device *qdev,
drm_plane_helper_add(plane, helper_funcs);
+ drm_plane_create_blend_mode_property(plane,
+ BIT(DRM_MODE_BLEND_PREMULTI));
+
return plane;
free_plane:
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index e7f49fe845ea..4e58685f58ff 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -68,6 +68,7 @@ config ROCKCHIP_CDN_DP
config ROCKCHIP_DW_DP
bool "Rockchip specific extensions for Synopsys DW DP"
+ select DRM_BRIDGE_CONNECTOR
help
This selects support for Rockchip SoC specific extensions
to enable Synopsys DesignWare Cores based DisplayPort transmit
@@ -145,6 +146,8 @@ config ROCKCHIP_RGB
config ROCKCHIP_RK3066_HDMI
bool "Rockchip specific extensions for RK3066 HDMI"
depends on DRM_ROCKCHIP
+ select DRM_DISPLAY_HELPER
+ select DRM_BRIDGE_CONNECTOR
help
This selects support for Rockchip SoC specific extensions
for the RK3066 HDMI driver. If you want to enable
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 587e60232ec7..efd5a98e80bd 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -241,10 +241,11 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
of_graph_get_remote_port(endpoint.local_node);
of_property_read_u32(remote_port, "reg", &port_id);
- sprintf(name, "%s vp%d", remote_port_parent->full_name, port_id);
+ snprintf(name, sizeof(name), "%s vp%d",
+ remote_port_parent->full_name, port_id);
} else {
- sprintf(name, "%s %s",
- remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
+ snprintf(name, sizeof(name), "%s %s",
+ remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
}
DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index bf97508a45b9..e4069fcb0272 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -563,9 +563,10 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
*/
smp_wmb();
+ spin_lock(&entity->lock);
spsc_queue_pop(&entity->job_queue);
-
drm_sched_rq_pop_entity(entity);
+ spin_unlock(&entity->lock);
/* Jobs and entities might have different lifecycles. Since we're
* removing the job from the entities queue, set the jobs entity pointer
@@ -651,6 +652,9 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
* Make sure to set the submit_ts first, to avoid a race.
*/
sched_job->submit_ts = submit_ts = ktime_get();
+
+ spin_lock(&entity->lock);
+
first = spsc_queue_push(&entity->job_queue, &sched_job->queue_node);
/* first job wakes up scheduler */
@@ -661,5 +665,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
if (sched)
drm_sched_wakeup(sched);
}
+
+ spin_unlock(&entity->lock);
}
EXPORT_SYMBOL(drm_sched_entity_push_job);
diff --git a/drivers/gpu/drm/scheduler/sched_rq.c b/drivers/gpu/drm/scheduler/sched_rq.c
index 0464d324d98d..23f46ec610e7 100644
--- a/drivers/gpu/drm/scheduler/sched_rq.c
+++ b/drivers/gpu/drm/scheduler/sched_rq.c
@@ -257,19 +257,17 @@ static ktime_t drm_sched_entity_get_job_ts(struct drm_sched_entity *entity)
struct drm_gpu_scheduler *
drm_sched_rq_add_entity(struct drm_sched_entity *entity, ktime_t ts)
{
+ struct drm_sched_rq *rq = entity->rq;
struct drm_gpu_scheduler *sched;
- struct drm_sched_rq *rq;
/* Add the entity to the run queue */
- spin_lock(&entity->lock);
- if (entity->stopped) {
- spin_unlock(&entity->lock);
+ lockdep_assert_held(&entity->lock);
+ if (entity->stopped) {
DRM_ERROR("Trying to push to a killed entity\n");
return NULL;
}
- rq = entity->rq;
spin_lock(&rq->lock);
sched = rq->sched;
@@ -289,7 +287,6 @@ drm_sched_rq_add_entity(struct drm_sched_entity *entity, ktime_t ts)
drm_sched_rq_update_fifo_locked(entity, rq, ts);
spin_unlock(&rq->lock);
- spin_unlock(&entity->lock);
return sched;
}
@@ -343,16 +340,17 @@ drm_sched_rq_next_rr_ts(struct drm_sched_rq *rq,
*/
void drm_sched_rq_pop_entity(struct drm_sched_entity *entity)
{
+ struct drm_sched_rq *rq = entity->rq;
struct drm_sched_job *next_job;
- struct drm_sched_rq *rq;
+
+ lockdep_assert_held(&entity->lock);
+
+ spin_lock(&rq->lock);
/*
* Update the entity's location in the min heap according to
* the timestamp of the next job, if any.
*/
- spin_lock(&entity->lock);
- rq = entity->rq;
- spin_lock(&rq->lock);
next_job = drm_sched_entity_queue_peek(entity);
if (next_job) {
ktime_t ts;
@@ -375,8 +373,8 @@ void drm_sched_rq_pop_entity(struct drm_sched_entity *entity)
drm_sched_entity_save_vruntime(entity, min_vruntime);
}
}
+
spin_unlock(&rq->lock);
- spin_unlock(&entity->lock);
}
/**
diff --git a/drivers/gpu/drm/scheduler/tests/mock_scheduler.c b/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
index 8e9ae7d980eb..2dfa3efef210 100644
--- a/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
+++ b/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2025 Valve Corporation */
+#include <kunit/device.h>
+
#include "sched_tests.h"
/*
@@ -288,6 +290,7 @@ static const struct drm_sched_backend_ops drm_mock_scheduler_ops = {
*/
struct drm_mock_scheduler *drm_mock_sched_new(struct kunit *test, long timeout)
{
+ static unsigned int instance;
struct drm_sched_init_args args = {
.ops = &drm_mock_scheduler_ops,
.num_rqs = DRM_SCHED_PRIORITY_COUNT,
@@ -297,11 +300,19 @@ struct drm_mock_scheduler *drm_mock_sched_new(struct kunit *test, long timeout)
.name = "drm-mock-scheduler",
};
struct drm_mock_scheduler *sched;
+ struct device *dev;
+ char name[64];
int ret;
sched = kunit_kzalloc(test, sizeof(*sched), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, sched);
+ snprintf(name, sizeof(name), "%s-%u", args.name, instance++);
+ dev = kunit_device_register(test, name);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+ args.dev = dev;
+
ret = drm_sched_init(&sched->base, &args);
KUNIT_ASSERT_EQ(test, ret, 0);
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 1b9477381a1d..53c68e29ebc2 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1433,7 +1433,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
if (ttm_tt_is_populated(tt)) {
ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags);
- if (!ret) {
+ if (ret > 0) {
spin_lock(&bdev->lru_lock);
ttm_resource_del_bulk_move_unevictable(bo->resource, bo);
ttm_resource_move_to_lru_tail(bo->resource);
diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c
index 7f21b11dedbe..bb3f7f0ad7c4 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_mode.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c
@@ -15,6 +15,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_edid.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
@@ -540,6 +541,9 @@ static struct drm_plane *vbox_create_plane(struct vbox_private *vbox,
drm_plane_helper_add(plane, helper_funcs);
+ drm_plane_create_blend_mode_property(plane,
+ BIT(DRM_MODE_BLEND_COVERAGE));
+
return plane;
free_plane:
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index b17e73bce384..82a7f2ac4c7e 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -1188,7 +1188,7 @@ int vc4_kms_load(struct drm_device *dev)
drm_mode_config_reset(dev);
- drm_kms_helper_poll_init(dev);
+ drmm_kms_helper_poll_init(dev);
return 0;
}
diff --git a/drivers/gpu/drm/verisilicon/vs_cursor_plane.c b/drivers/gpu/drm/verisilicon/vs_cursor_plane.c
index 6a7fd9e179bb..1fa6b7578b27 100644
--- a/drivers/gpu/drm/verisilicon/vs_cursor_plane.c
+++ b/drivers/gpu/drm/verisilicon/vs_cursor_plane.c
@@ -11,6 +11,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_crtc.h>
#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fourcc.h>
@@ -269,6 +270,7 @@ struct drm_plane *vs_cursor_plane_init(struct drm_device *drm_dev,
return plane;
drm_plane_helper_add(plane, &vs_cursor_plane_helper_funcs);
+ drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_COVERAGE));
return plane;
}
diff --git a/drivers/gpu/drm/verisilicon/vs_hwdb.c b/drivers/gpu/drm/verisilicon/vs_hwdb.c
index 2a0f7c59afa3..ebf6f843bc88 100644
--- a/drivers/gpu/drm/verisilicon/vs_hwdb.c
+++ b/drivers/gpu/drm/verisilicon/vs_hwdb.c
@@ -10,82 +10,50 @@
#include "vs_dc_top_regs.h"
#include "vs_hwdb.h"
-static const u32 vs_formats_array_no_yuv444[] = {
+static const u32 vs_primary_formats_array_no_yuv444[] = {
DRM_FORMAT_XRGB4444,
DRM_FORMAT_XBGR4444,
DRM_FORMAT_RGBX4444,
DRM_FORMAT_BGRX4444,
- DRM_FORMAT_ARGB4444,
- DRM_FORMAT_ABGR4444,
- DRM_FORMAT_RGBA4444,
- DRM_FORMAT_BGRA4444,
DRM_FORMAT_XRGB1555,
DRM_FORMAT_XBGR1555,
DRM_FORMAT_RGBX5551,
DRM_FORMAT_BGRX5551,
- DRM_FORMAT_ARGB1555,
- DRM_FORMAT_ABGR1555,
- DRM_FORMAT_RGBA5551,
- DRM_FORMAT_BGRA5551,
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGBX8888,
DRM_FORMAT_BGRX8888,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_ARGB2101010,
- DRM_FORMAT_ABGR2101010,
- DRM_FORMAT_RGBA1010102,
- DRM_FORMAT_BGRA1010102,
/* TODO: non-RGB formats */
};
-static const u32 vs_formats_array_with_yuv444[] = {
+static const u32 vs_primary_formats_array_with_yuv444[] = {
DRM_FORMAT_XRGB4444,
DRM_FORMAT_XBGR4444,
DRM_FORMAT_RGBX4444,
DRM_FORMAT_BGRX4444,
- DRM_FORMAT_ARGB4444,
- DRM_FORMAT_ABGR4444,
- DRM_FORMAT_RGBA4444,
- DRM_FORMAT_BGRA4444,
DRM_FORMAT_XRGB1555,
DRM_FORMAT_XBGR1555,
DRM_FORMAT_RGBX5551,
DRM_FORMAT_BGRX5551,
- DRM_FORMAT_ARGB1555,
- DRM_FORMAT_ABGR1555,
- DRM_FORMAT_RGBA5551,
- DRM_FORMAT_BGRA5551,
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_RGBX8888,
DRM_FORMAT_BGRX8888,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_ARGB2101010,
- DRM_FORMAT_ABGR2101010,
- DRM_FORMAT_RGBA1010102,
- DRM_FORMAT_BGRA1010102,
/* TODO: non-RGB formats */
};
static const struct vs_formats vs_formats_no_yuv444 = {
- .array = vs_formats_array_no_yuv444,
- .num = ARRAY_SIZE(vs_formats_array_no_yuv444)
+ .primary_array = vs_primary_formats_array_no_yuv444,
+ .primary_num = ARRAY_SIZE(vs_primary_formats_array_no_yuv444)
};
static const struct vs_formats vs_formats_with_yuv444 = {
- .array = vs_formats_array_with_yuv444,
- .num = ARRAY_SIZE(vs_formats_array_with_yuv444)
+ .primary_array = vs_primary_formats_array_with_yuv444,
+ .primary_num = ARRAY_SIZE(vs_primary_formats_array_with_yuv444)
};
static struct vs_chip_identity vs_chip_identities[] = {
diff --git a/drivers/gpu/drm/verisilicon/vs_hwdb.h b/drivers/gpu/drm/verisilicon/vs_hwdb.h
index 2065ecb73043..616076d931a5 100644
--- a/drivers/gpu/drm/verisilicon/vs_hwdb.h
+++ b/drivers/gpu/drm/verisilicon/vs_hwdb.h
@@ -10,8 +10,8 @@
#include <linux/types.h>
struct vs_formats {
- const u32 *array;
- unsigned int num;
+ const u32 *primary_array;
+ unsigned int primary_num;
};
struct vs_chip_identity {
diff --git a/drivers/gpu/drm/verisilicon/vs_primary_plane.c b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
index 20a820f1ef30..95f4a06039e7 100644
--- a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
+++ b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
@@ -173,8 +173,8 @@ struct drm_plane *vs_primary_plane_init(struct drm_device *drm_dev, struct vs_dc
plane = drmm_universal_plane_alloc(drm_dev, struct drm_plane, dev, 0,
&vs_primary_plane_funcs,
- dc->identity.formats->array,
- dc->identity.formats->num,
+ dc->identity.formats->primary_array,
+ dc->identity.formats->primary_num,
NULL,
DRM_PLANE_TYPE_PRIMARY,
NULL);
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index 946f163013b8..9f442b6afa9c 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -24,6 +24,7 @@
*/
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -611,6 +612,9 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
if (type == DRM_PLANE_TYPE_PRIMARY)
drm_plane_enable_fb_damage_clips(plane);
+ else if (type == DRM_PLANE_TYPE_CURSOR)
+ drm_plane_create_blend_mode_property(plane,
+ BIT(DRM_MODE_BLEND_PREMULTI));
return plane;
}
diff --git a/drivers/gpu/drm/xe/xe_pagefault.c b/drivers/gpu/drm/xe/xe_pagefault.c
index 1286be7fdcf2..f9e5bd41cfd1 100644
--- a/drivers/gpu/drm/xe/xe_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_pagefault.c
@@ -684,6 +684,13 @@ static void xe_pagefault_queue_work(struct work_struct *w)
*/
guard(xe_pm_runtime)(xe);
+ /*
+ * A live VM holds a PM reference, but a torn-down VM does not.
+ * Guard the entire worker loop to safely drain stale faults and
+ * prevent autosuspends from desyncing batched CT flushes.
+ */
+ guard(xe_pm_runtime)(xe);
+
#define USM_QUEUE_MAX_RUNTIME_MS 20
threshold = jiffies + msecs_to_jiffies(USM_QUEUE_MAX_RUNTIME_MS);
@@ -811,6 +818,7 @@ static int xe_pagefault_queue_init(struct xe_device *xe,
drm_dbg(&xe->drm, "xe_pagefault_entry_size=%d, total_num_eus=%d, pf_queue->size=%u",
xe_pagefault_entry_size(), total_num_eus, pf_queue->size);
+ pf_queue->xe = xe;
spin_lock_init(&pf_queue->lock);
pf_queue->data = drmm_kzalloc(&xe->drm, pf_queue->size, GFP_KERNEL);
diff --git a/drivers/gpu/drm/xe/xe_pagefault_types.h b/drivers/gpu/drm/xe/xe_pagefault_types.h
index 6e1c0360648d..8ae6b9848bdc 100644
--- a/drivers/gpu/drm/xe/xe_pagefault_types.h
+++ b/drivers/gpu/drm/xe/xe_pagefault_types.h
@@ -8,6 +8,7 @@
#include <linux/workqueue.h>
+struct xe_device;
struct xe_gt;
struct xe_pagefault;
@@ -243,6 +244,8 @@ struct xe_pagefault {
* queue to absorb the device’s worst-case number of outstanding faults.
*/
struct xe_pagefault_queue {
+ /** @xe: Back-pointer to the Xe device */
+ struct xe_device *xe;
/**
* @data: Data in queue containing struct xe_pagefault, protected by
* @lock