summaryrefslogtreecommitdiff
path: root/drivers/gpu
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/gpu
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/gpu')
-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
5 files changed, 61 insertions, 34 deletions
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);