summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-03-13 01:32:14 +0300
committerDave Airlie <airlied@redhat.com>2026-03-13 01:32:23 +0300
commit3c9eced53749be418128170f89979f5d50547fd1 (patch)
tree5b53070afd19555f498ac9aa73a6bbc391480733 /drivers
parent50ae4ce2a6ace992025be3fdb14e244e88ddae18 (diff)
parent49973e2a4156a88e46ba1c1c484b7c214199a181 (diff)
downloadlinux-3c9eced53749be418128170f89979f5d50547fd1.tar.xz
Merge tag 'drm-misc-fixes-2026-03-12' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes
A pixel byte swap fix for st7586, a null pointer dereference fix for gud, two timings fixes for ti-sn65dsi83, an initialization fix for ivpu, and a runtime suspend deadlock fix for amdxdna. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <mripard@redhat.com> Link: https://patch.msgid.link/20260312-accurate-ambrosial-trout-bfabf8@houat
Diffstat (limited to 'drivers')
-rw-r--r--drivers/accel/amdxdna/aie2_ctx.c14
-rw-r--r--drivers/accel/amdxdna/amdxdna_ctx.c10
-rw-r--r--drivers/accel/ivpu/ivpu_hw_40xx_reg.h6
-rw-r--r--drivers/accel/ivpu/ivpu_hw_ip.c1
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi83.c13
-rw-r--r--drivers/gpu/drm/gud/gud_drv.c9
-rw-r--r--drivers/gpu/drm/gud/gud_internal.h4
-rw-r--r--drivers/gpu/drm/gud/gud_pipe.c54
-rw-r--r--drivers/gpu/drm/sitronix/st7586.c15
9 files changed, 73 insertions, 53 deletions
diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c
index afee5e667f77..c0d348884f74 100644
--- a/drivers/accel/amdxdna/aie2_ctx.c
+++ b/drivers/accel/amdxdna/aie2_ctx.c
@@ -165,7 +165,6 @@ aie2_sched_notify(struct amdxdna_sched_job *job)
trace_xdna_job(&job->base, job->hwctx->name, "signaled fence", job->seq);
- amdxdna_pm_suspend_put(job->hwctx->client->xdna);
job->hwctx->priv->completed++;
dma_fence_signal(fence);
@@ -290,19 +289,11 @@ aie2_sched_job_run(struct drm_sched_job *sched_job)
struct dma_fence *fence;
int ret;
- ret = amdxdna_pm_resume_get(hwctx->client->xdna);
- if (ret)
+ if (!hwctx->priv->mbox_chann)
return NULL;
- if (!hwctx->priv->mbox_chann) {
- amdxdna_pm_suspend_put(hwctx->client->xdna);
- return NULL;
- }
-
- if (!mmget_not_zero(job->mm)) {
- amdxdna_pm_suspend_put(hwctx->client->xdna);
+ if (!mmget_not_zero(job->mm))
return ERR_PTR(-ESRCH);
- }
kref_get(&job->refcnt);
fence = dma_fence_get(job->fence);
@@ -333,7 +324,6 @@ aie2_sched_job_run(struct drm_sched_job *sched_job)
out:
if (ret) {
- amdxdna_pm_suspend_put(hwctx->client->xdna);
dma_fence_put(job->fence);
aie2_job_put(job);
mmput(job->mm);
diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c
index 666dfd7b2a80..838430903a3e 100644
--- a/drivers/accel/amdxdna/amdxdna_ctx.c
+++ b/drivers/accel/amdxdna/amdxdna_ctx.c
@@ -17,6 +17,7 @@
#include "amdxdna_ctx.h"
#include "amdxdna_gem.h"
#include "amdxdna_pci_drv.h"
+#include "amdxdna_pm.h"
#define MAX_HWCTX_ID 255
#define MAX_ARG_COUNT 4095
@@ -445,6 +446,7 @@ put_shmem_bo:
void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job)
{
trace_amdxdna_debug_point(job->hwctx->name, job->seq, "job release");
+ amdxdna_pm_suspend_put(job->hwctx->client->xdna);
amdxdna_arg_bos_put(job);
amdxdna_gem_put_obj(job->cmd_bo);
dma_fence_put(job->fence);
@@ -482,6 +484,12 @@ int amdxdna_cmd_submit(struct amdxdna_client *client,
goto cmd_put;
}
+ ret = amdxdna_pm_resume_get(xdna);
+ if (ret) {
+ XDNA_ERR(xdna, "Resume failed, ret %d", ret);
+ goto put_bos;
+ }
+
idx = srcu_read_lock(&client->hwctx_srcu);
hwctx = xa_load(&client->hwctx_xa, hwctx_hdl);
if (!hwctx) {
@@ -522,6 +530,8 @@ put_fence:
dma_fence_put(job->fence);
unlock_srcu:
srcu_read_unlock(&client->hwctx_srcu, idx);
+ amdxdna_pm_suspend_put(xdna);
+put_bos:
amdxdna_arg_bos_put(job);
cmd_put:
amdxdna_gem_put_obj(job->cmd_bo);
diff --git a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h
index 421242acb184..fc0ee8d637f9 100644
--- a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h
+++ b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h
@@ -121,12 +121,6 @@
#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY 0x0003006cu
#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY_STATUS_DLY_MASK GENMASK(7, 0)
-#define VPU_40XX_HOST_SS_AON_RETENTION0 0x0003000cu
-#define VPU_40XX_HOST_SS_AON_RETENTION1 0x00030010u
-#define VPU_40XX_HOST_SS_AON_RETENTION2 0x00030014u
-#define VPU_40XX_HOST_SS_AON_RETENTION3 0x00030018u
-#define VPU_40XX_HOST_SS_AON_RETENTION4 0x0003001cu
-
#define VPU_40XX_HOST_SS_AON_IDLE_GEN 0x00030200u
#define VPU_40XX_HOST_SS_AON_IDLE_GEN_EN_MASK BIT_MASK(0)
#define VPU_40XX_HOST_SS_AON_IDLE_GEN_HW_PG_EN_MASK BIT_MASK(1)
diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c
index 959984c54341..37f95a0551ed 100644
--- a/drivers/accel/ivpu/ivpu_hw_ip.c
+++ b/drivers/accel/ivpu/ivpu_hw_ip.c
@@ -931,7 +931,6 @@ static int soc_cpu_boot_40xx(struct ivpu_device *vdev)
static int soc_cpu_boot_60xx(struct ivpu_device *vdev)
{
- REGV_WR64(VPU_40XX_HOST_SS_AON_RETENTION1, vdev->fw->mem_bp->vpu_addr);
soc_cpu_set_entry_point_40xx(vdev, vdev->fw->cold_boot_entry_point);
return 0;
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index f6736b4457bb..17a885244e1e 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -351,9 +351,9 @@ static u8 sn65dsi83_get_dsi_range(struct sn65dsi83 *ctx,
* DSI_CLK = mode clock * bpp / dsi_data_lanes / 2
* the 2 is there because the bus is DDR.
*/
- return DIV_ROUND_UP(clamp((unsigned int)mode->clock *
- mipi_dsi_pixel_format_to_bpp(ctx->dsi->format) /
- ctx->dsi->lanes / 2, 40000U, 500000U), 5000U);
+ return clamp((unsigned int)mode->clock *
+ mipi_dsi_pixel_format_to_bpp(ctx->dsi->format) /
+ ctx->dsi->lanes / 2, 40000U, 500000U) / 5000U;
}
static u8 sn65dsi83_get_dsi_div(struct sn65dsi83 *ctx)
@@ -517,6 +517,7 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state)
{
struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
+ const unsigned int dual_factor = ctx->lvds_dual_link ? 2 : 1;
const struct drm_bridge_state *bridge_state;
const struct drm_crtc_state *crtc_state;
const struct drm_display_mode *mode;
@@ -653,18 +654,18 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
/* 32 + 1 pixel clock to ensure proper operation */
le16val = cpu_to_le16(32 + 1);
regmap_bulk_write(ctx->regmap, REG_VID_CHA_SYNC_DELAY_LOW, &le16val, 2);
- le16val = cpu_to_le16(mode->hsync_end - mode->hsync_start);
+ le16val = cpu_to_le16((mode->hsync_end - mode->hsync_start) / dual_factor);
regmap_bulk_write(ctx->regmap, REG_VID_CHA_HSYNC_PULSE_WIDTH_LOW,
&le16val, 2);
le16val = cpu_to_le16(mode->vsync_end - mode->vsync_start);
regmap_bulk_write(ctx->regmap, REG_VID_CHA_VSYNC_PULSE_WIDTH_LOW,
&le16val, 2);
regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_BACK_PORCH,
- mode->htotal - mode->hsync_end);
+ (mode->htotal - mode->hsync_end) / dual_factor);
regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_BACK_PORCH,
mode->vtotal - mode->vsync_end);
regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_FRONT_PORCH,
- mode->hsync_start - mode->hdisplay);
+ (mode->hsync_start - mode->hdisplay) / dual_factor);
regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_FRONT_PORCH,
mode->vsync_start - mode->vdisplay);
regmap_write(ctx->regmap, REG_VID_CHA_TEST_PATTERN, 0x00);
diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
index d0122d477610..17c2dead2c13 100644
--- a/drivers/gpu/drm/gud/gud_drv.c
+++ b/drivers/gpu/drm/gud/gud_drv.c
@@ -339,7 +339,9 @@ static int gud_stats_debugfs(struct seq_file *m, void *data)
}
static const struct drm_crtc_helper_funcs gud_crtc_helper_funcs = {
- .atomic_check = drm_crtc_helper_atomic_check
+ .atomic_check = drm_crtc_helper_atomic_check,
+ .atomic_enable = gud_crtc_atomic_enable,
+ .atomic_disable = gud_crtc_atomic_disable,
};
static const struct drm_crtc_funcs gud_crtc_funcs = {
@@ -364,6 +366,10 @@ static const struct drm_plane_funcs gud_plane_funcs = {
DRM_GEM_SHADOW_PLANE_FUNCS,
};
+static const struct drm_mode_config_helper_funcs gud_mode_config_helpers = {
+ .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
+};
+
static const struct drm_mode_config_funcs gud_mode_config_funcs = {
.fb_create = drm_gem_fb_create_with_dirty,
.atomic_check = drm_atomic_helper_check,
@@ -499,6 +505,7 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id)
drm->mode_config.min_height = le32_to_cpu(desc.min_height);
drm->mode_config.max_height = le32_to_cpu(desc.max_height);
drm->mode_config.funcs = &gud_mode_config_funcs;
+ drm->mode_config.helper_private = &gud_mode_config_helpers;
/* Format init */
formats_dev = devm_kmalloc(dev, GUD_FORMATS_MAX_NUM, GFP_KERNEL);
diff --git a/drivers/gpu/drm/gud/gud_internal.h b/drivers/gpu/drm/gud/gud_internal.h
index d27c31648341..8eec8335f5f9 100644
--- a/drivers/gpu/drm/gud/gud_internal.h
+++ b/drivers/gpu/drm/gud/gud_internal.h
@@ -62,6 +62,10 @@ int gud_usb_set_u8(struct gud_device *gdrm, u8 request, u8 val);
void gud_clear_damage(struct gud_device *gdrm);
void gud_flush_work(struct work_struct *work);
+void gud_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state);
+void gud_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state);
int gud_plane_atomic_check(struct drm_plane *plane,
struct drm_atomic_state *state);
void gud_plane_atomic_update(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index 4b77be94348d..b355bf4d3389 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -580,6 +580,39 @@ out:
return ret;
}
+void gud_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ struct drm_device *drm = crtc->dev;
+ struct gud_device *gdrm = to_gud_device(drm);
+ int idx;
+
+ if (!drm_dev_enter(drm, &idx))
+ return;
+
+ gud_usb_set_u8(gdrm, GUD_REQ_SET_CONTROLLER_ENABLE, 1);
+ gud_usb_set(gdrm, GUD_REQ_SET_STATE_COMMIT, 0, NULL, 0);
+ gud_usb_set_u8(gdrm, GUD_REQ_SET_DISPLAY_ENABLE, 1);
+
+ drm_dev_exit(idx);
+}
+
+void gud_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ struct drm_device *drm = crtc->dev;
+ struct gud_device *gdrm = to_gud_device(drm);
+ int idx;
+
+ if (!drm_dev_enter(drm, &idx))
+ return;
+
+ gud_usb_set_u8(gdrm, GUD_REQ_SET_DISPLAY_ENABLE, 0);
+ gud_usb_set_u8(gdrm, GUD_REQ_SET_CONTROLLER_ENABLE, 0);
+
+ drm_dev_exit(idx);
+}
+
void gud_plane_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *atomic_state)
{
@@ -607,24 +640,12 @@ void gud_plane_atomic_update(struct drm_plane *plane,
mutex_unlock(&gdrm->damage_lock);
}
- if (!drm_dev_enter(drm, &idx))
+ if (!crtc || !drm_dev_enter(drm, &idx))
return;
- if (!old_state->fb)
- gud_usb_set_u8(gdrm, GUD_REQ_SET_CONTROLLER_ENABLE, 1);
-
- if (fb && (crtc->state->mode_changed || crtc->state->connectors_changed))
- gud_usb_set(gdrm, GUD_REQ_SET_STATE_COMMIT, 0, NULL, 0);
-
- if (crtc->state->active_changed)
- gud_usb_set_u8(gdrm, GUD_REQ_SET_DISPLAY_ENABLE, crtc->state->active);
-
- if (!fb)
- goto ctrl_disable;
-
ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
if (ret)
- goto ctrl_disable;
+ goto out;
drm_atomic_helper_damage_iter_init(&iter, old_state, new_state);
drm_atomic_for_each_plane_damage(&iter, &damage)
@@ -632,9 +653,6 @@ void gud_plane_atomic_update(struct drm_plane *plane,
drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
-ctrl_disable:
- if (!crtc->state->enable)
- gud_usb_set_u8(gdrm, GUD_REQ_SET_CONTROLLER_ENABLE, 0);
-
+out:
drm_dev_exit(idx);
}
diff --git a/drivers/gpu/drm/sitronix/st7586.c b/drivers/gpu/drm/sitronix/st7586.c
index b57ebf37a664..16b6b4e368af 100644
--- a/drivers/gpu/drm/sitronix/st7586.c
+++ b/drivers/gpu/drm/sitronix/st7586.c
@@ -347,6 +347,12 @@ static int st7586_probe(struct spi_device *spi)
if (ret)
return ret;
+ /*
+ * Override value set by mipi_dbi_spi_init(). This driver is a bit
+ * non-standard, so best to set it explicitly here.
+ */
+ dbi->write_memory_bpw = 8;
+
/* Cannot read from this controller via SPI */
dbi->read_commands = NULL;
@@ -356,15 +362,6 @@ static int st7586_probe(struct spi_device *spi)
if (ret)
return ret;
- /*
- * we are using 8-bit data, so we are not actually swapping anything,
- * but setting mipi->swap_bytes makes mipi_dbi_typec3_command() do the
- * right thing and not use 16-bit transfers (which results in swapped
- * bytes on little-endian systems and causes out of order data to be
- * sent to the display).
- */
- dbi->swap_bytes = true;
-
drm_mode_config_reset(drm);
ret = drm_dev_register(drm, 0);