Skip to content

Commit a859eca

Browse files
committed
Merge tag 'drm-fixes-2025-12-13' of https://gitlab.freedesktop.org/drm/kernel
Pull more drm fixes from Dave Airlie: "These are the enqueued fixes that ended up in our fixes branch, nouveau mostly, along with some small fixes in other places. plane: - Handle IS_ERR vs NULL in drm_plane_create_hotspot_properties() ttm: - fix devcoredump for evicted bos panel: - Fix stack usage warning in novatek-nt35560 nouveau: - alloc fwsec sb at boot to avoid s/r problems - fix strcpy usage - fix i2c encoder crash bridge: - Ignore spurious PLL_UNLOCK bit in ti-sn65dsi83 mgag200: - Fix bigendian handling in mgag200 tilcdc: - Fix probe failure in tilcdc" * tag 'drm-fixes-2025-12-13' of https://gitlab.freedesktop.org/drm/kernel: drm/mgag200: Fix big-endian support drm/tilcdc: Fix removal actions in case of failed probe drm/ttm: Avoid NULL pointer deref for evicted BOs drm: nouveau: Replace sprintf() with sysfs_emit() drm/nouveau: fix circular dep oops from vendored i2c encoder drm/nouveau: refactor deprecated strcpy drm/plane: Fix IS_ERR() vs NULL check in drm_plane_create_hotspot_properties() drm/bridge: ti-sn65dsi83: ignore PLL_UNLOCK errors drm/nouveau/gsp: Allocate fwsec-sb at boot drm/panel: novatek-nt35560: avoid on-stack device structure
2 parents 237f1bb + 5300831 commit a859eca

16 files changed

Lines changed: 166 additions & 76 deletions

File tree

drivers/gpu/drm/bridge/ti-sn65dsi83.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,14 @@ static void sn65dsi83_handle_errors(struct sn65dsi83 *ctx)
429429
*/
430430

431431
ret = regmap_read(ctx->regmap, REG_IRQ_STAT, &irq_stat);
432-
if (ret || irq_stat) {
432+
433+
/*
434+
* Some hardware (Toradex Verdin AM62) is known to report the
435+
* PLL_UNLOCK error interrupt while working without visible
436+
* problems. In lack of a reliable way to discriminate such cases
437+
* from user-visible PLL_UNLOCK cases, ignore that bit entirely.
438+
*/
439+
if (ret || irq_stat & ~REG_IRQ_STAT_CHA_PLL_UNLOCK) {
433440
/*
434441
* IRQ acknowledged is not always possible (the bridge can be in
435442
* a state where it doesn't answer anymore). To prevent an
@@ -654,7 +661,7 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
654661
if (ctx->irq) {
655662
/* Enable irq to detect errors */
656663
regmap_write(ctx->regmap, REG_IRQ_GLOBAL, REG_IRQ_GLOBAL_IRQ_EN);
657-
regmap_write(ctx->regmap, REG_IRQ_EN, 0xff);
664+
regmap_write(ctx->regmap, REG_IRQ_EN, 0xff & ~REG_IRQ_EN_CHA_PLL_UNLOCK_EN);
658665
} else {
659666
/* Use the polling task */
660667
sn65dsi83_monitor_start(ctx);

drivers/gpu/drm/drm_plane.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,14 +338,14 @@ static int drm_plane_create_hotspot_properties(struct drm_plane *plane)
338338

339339
prop_x = drm_property_create_signed_range(plane->dev, 0, "HOTSPOT_X",
340340
INT_MIN, INT_MAX);
341-
if (IS_ERR(prop_x))
342-
return PTR_ERR(prop_x);
341+
if (!prop_x)
342+
return -ENOMEM;
343343

344344
prop_y = drm_property_create_signed_range(plane->dev, 0, "HOTSPOT_Y",
345345
INT_MIN, INT_MAX);
346-
if (IS_ERR(prop_y)) {
346+
if (!prop_y) {
347347
drm_property_destroy(plane->dev, prop_x);
348-
return PTR_ERR(prop_y);
348+
return -ENOMEM;
349349
}
350350

351351
drm_object_attach_property(&plane->base, prop_x, 0);

drivers/gpu/drm/mgag200/mgag200_mode.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,30 @@ static void mgag200_set_startadd(struct mga_device *mdev,
161161
WREG_ECRT(0x00, crtcext0);
162162
}
163163

164+
/*
165+
* Set the opmode for the hardware swapper for Big-Endian processor
166+
* support for the frame buffer aperture and DMAWIN space.
167+
*/
168+
static void mgag200_set_datasiz(struct mga_device *mdev, u32 format)
169+
{
170+
#if defined(__BIG_ENDIAN)
171+
u32 opmode = RREG32(MGAREG_OPMODE);
172+
173+
opmode &= ~(GENMASK(17, 16) | GENMASK(9, 8) | GENMASK(3, 2));
174+
175+
/* Big-endian byte-swapping */
176+
switch (format) {
177+
case DRM_FORMAT_RGB565:
178+
opmode |= 0x10100;
179+
break;
180+
case DRM_FORMAT_XRGB8888:
181+
opmode |= 0x20200;
182+
break;
183+
}
184+
WREG32(MGAREG_OPMODE, opmode);
185+
#endif
186+
}
187+
164188
void mgag200_init_registers(struct mga_device *mdev)
165189
{
166190
u8 crtc11, misc;
@@ -496,6 +520,7 @@ void mgag200_primary_plane_helper_atomic_update(struct drm_plane *plane,
496520
struct drm_atomic_helper_damage_iter iter;
497521
struct drm_rect damage;
498522

523+
mgag200_set_datasiz(mdev, fb->format->format);
499524
drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
500525
drm_atomic_for_each_plane_damage(&iter, &damage) {
501526
mgag200_handle_damage(mdev, shadow_plane_state->data, fb, &damage);

drivers/gpu/drm/nouveau/dispnv04/nouveau_i2c_encoder.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -94,26 +94,6 @@ int nouveau_i2c_encoder_init(struct drm_device *dev,
9494
return err;
9595
}
9696

97-
/**
98-
* nouveau_i2c_encoder_destroy - Unregister the I2C device backing an encoder
99-
* @drm_encoder: Encoder to be unregistered.
100-
*
101-
* This should be called from the @destroy method of an I2C slave
102-
* encoder driver once I2C access is no longer needed.
103-
*/
104-
void nouveau_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
105-
{
106-
struct nouveau_i2c_encoder *encoder = to_encoder_i2c(drm_encoder);
107-
struct i2c_client *client = nouveau_i2c_encoder_get_client(drm_encoder);
108-
struct module *module = client->dev.driver->owner;
109-
110-
i2c_unregister_device(client);
111-
encoder->i2c_client = NULL;
112-
113-
module_put(module);
114-
}
115-
EXPORT_SYMBOL(nouveau_i2c_encoder_destroy);
116-
11797
/*
11898
* Wrapper fxns which can be plugged in to drm_encoder_helper_funcs:
11999
*/

drivers/gpu/drm/nouveau/include/dispnv04/i2c/encoder_i2c.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,24 @@ static inline struct i2c_client *nouveau_i2c_encoder_get_client(struct drm_encod
202202
return to_encoder_i2c(encoder)->i2c_client;
203203
}
204204

205-
void nouveau_i2c_encoder_destroy(struct drm_encoder *encoder);
205+
/**
206+
* nouveau_i2c_encoder_destroy - Unregister the I2C device backing an encoder
207+
* @drm_encoder: Encoder to be unregistered.
208+
*
209+
* This should be called from the @destroy method of an I2C slave
210+
* encoder driver once I2C access is no longer needed.
211+
*/
212+
static __always_inline void nouveau_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
213+
{
214+
struct nouveau_i2c_encoder *encoder = to_encoder_i2c(drm_encoder);
215+
struct i2c_client *client = nouveau_i2c_encoder_get_client(drm_encoder);
216+
struct module *module = client->dev.driver->owner;
217+
218+
i2c_unregister_device(client);
219+
encoder->i2c_client = NULL;
220+
221+
module_put(module);
222+
}
206223

207224
/*
208225
* Wrapper fxns which can be plugged in to drm_encoder_helper_funcs:

drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ struct nvkm_gsp {
7373

7474
const struct firmware *bl;
7575
const struct firmware *rm;
76+
77+
struct {
78+
struct nvkm_falcon_fw sb;
79+
} falcon;
7680
} fws;
7781

7882
struct nvkm_firmware fw;

drivers/gpu/drm/nouveau/nouveau_fence.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,11 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
183183
fctx->context = drm->runl[chan->runlist].context_base + chan->chid;
184184

185185
if (chan == drm->cechan)
186-
strcpy(fctx->name, "copy engine channel");
186+
strscpy(fctx->name, "copy engine channel");
187187
else if (chan == drm->channel)
188-
strcpy(fctx->name, "generic kernel channel");
188+
strscpy(fctx->name, "generic kernel channel");
189189
else
190-
strcpy(fctx->name, cli->name);
190+
strscpy(fctx->name, cli->name);
191191

192192
kref_init(&fctx->fence_ref);
193193
if (!priv->uevent)

drivers/gpu/drm/nouveau/nouveau_hwmon.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ nouveau_hwmon_get_pwm1_max(struct device *d,
125125
if (ret < 0)
126126
return ret;
127127

128-
return sprintf(buf, "%i\n", ret);
128+
return sysfs_emit(buf, "%i\n", ret);
129129
}
130130

131131
static ssize_t
@@ -141,7 +141,7 @@ nouveau_hwmon_get_pwm1_min(struct device *d,
141141
if (ret < 0)
142142
return ret;
143143

144-
return sprintf(buf, "%i\n", ret);
144+
return sysfs_emit(buf, "%i\n", ret);
145145
}
146146

147147
static ssize_t

drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -259,18 +259,16 @@ nvkm_gsp_fwsec_v3(struct nvkm_gsp *gsp, const char *name,
259259
}
260260

261261
static int
262-
nvkm_gsp_fwsec(struct nvkm_gsp *gsp, const char *name, u32 init_cmd)
262+
nvkm_gsp_fwsec_init(struct nvkm_gsp *gsp, struct nvkm_falcon_fw *fw, const char *name, u32 init_cmd)
263263
{
264264
struct nvkm_subdev *subdev = &gsp->subdev;
265265
struct nvkm_device *device = subdev->device;
266266
struct nvkm_bios *bios = device->bios;
267267
const union nvfw_falcon_ucode_desc *desc;
268268
struct nvbios_pmuE flcn_ucode;
269-
u8 idx, ver, hdr;
270269
u32 data;
271270
u16 size, vers;
272-
struct nvkm_falcon_fw fw = {};
273-
u32 mbox0 = 0;
271+
u8 idx, ver, hdr;
274272
int ret;
275273

276274
/* Lookup in VBIOS. */
@@ -291,8 +289,8 @@ nvkm_gsp_fwsec(struct nvkm_gsp *gsp, const char *name, u32 init_cmd)
291289
vers = (desc->v2.Hdr & 0x0000ff00) >> 8;
292290

293291
switch (vers) {
294-
case 2: ret = nvkm_gsp_fwsec_v2(gsp, name, &desc->v2, size, init_cmd, &fw); break;
295-
case 3: ret = nvkm_gsp_fwsec_v3(gsp, name, &desc->v3, size, init_cmd, &fw); break;
292+
case 2: ret = nvkm_gsp_fwsec_v2(gsp, name, &desc->v2, size, init_cmd, fw); break;
293+
case 3: ret = nvkm_gsp_fwsec_v3(gsp, name, &desc->v3, size, init_cmd, fw); break;
296294
default:
297295
nvkm_error(subdev, "%s(v%d): version unknown\n", name, vers);
298296
return -EINVAL;
@@ -303,15 +301,19 @@ nvkm_gsp_fwsec(struct nvkm_gsp *gsp, const char *name, u32 init_cmd)
303301
return ret;
304302
}
305303

306-
/* Boot. */
307-
ret = nvkm_falcon_fw_boot(&fw, subdev, true, &mbox0, NULL, 0, 0);
308-
nvkm_falcon_fw_dtor(&fw);
309-
if (ret)
310-
return ret;
311-
312304
return 0;
313305
}
314306

307+
static int
308+
nvkm_gsp_fwsec_boot(struct nvkm_gsp *gsp, struct nvkm_falcon_fw *fw)
309+
{
310+
struct nvkm_subdev *subdev = &gsp->subdev;
311+
u32 mbox0 = 0;
312+
313+
/* Boot */
314+
return nvkm_falcon_fw_boot(fw, subdev, true, &mbox0, NULL, 0, 0);
315+
}
316+
315317
int
316318
nvkm_gsp_fwsec_sb(struct nvkm_gsp *gsp)
317319
{
@@ -320,7 +322,7 @@ nvkm_gsp_fwsec_sb(struct nvkm_gsp *gsp)
320322
int ret;
321323
u32 err;
322324

323-
ret = nvkm_gsp_fwsec(gsp, "fwsec-sb", NVFW_FALCON_APPIF_DMEMMAPPER_CMD_SB);
325+
ret = nvkm_gsp_fwsec_boot(gsp, &gsp->fws.falcon.sb);
324326
if (ret)
325327
return ret;
326328

@@ -334,27 +336,48 @@ nvkm_gsp_fwsec_sb(struct nvkm_gsp *gsp)
334336
return 0;
335337
}
336338

339+
int
340+
nvkm_gsp_fwsec_sb_ctor(struct nvkm_gsp *gsp)
341+
{
342+
return nvkm_gsp_fwsec_init(gsp, &gsp->fws.falcon.sb, "fwsec-sb",
343+
NVFW_FALCON_APPIF_DMEMMAPPER_CMD_SB);
344+
}
345+
346+
void
347+
nvkm_gsp_fwsec_sb_dtor(struct nvkm_gsp *gsp)
348+
{
349+
nvkm_falcon_fw_dtor(&gsp->fws.falcon.sb);
350+
}
351+
337352
int
338353
nvkm_gsp_fwsec_frts(struct nvkm_gsp *gsp)
339354
{
340355
struct nvkm_subdev *subdev = &gsp->subdev;
341356
struct nvkm_device *device = subdev->device;
357+
struct nvkm_falcon_fw fw = {};
342358
int ret;
343359
u32 err, wpr2_lo, wpr2_hi;
344360

345-
ret = nvkm_gsp_fwsec(gsp, "fwsec-frts", NVFW_FALCON_APPIF_DMEMMAPPER_CMD_FRTS);
361+
ret = nvkm_gsp_fwsec_init(gsp, &fw, "fwsec-frts", NVFW_FALCON_APPIF_DMEMMAPPER_CMD_FRTS);
346362
if (ret)
347363
return ret;
348364

365+
ret = nvkm_gsp_fwsec_boot(gsp, &fw);
366+
if (ret)
367+
goto fwsec_dtor;
368+
349369
/* Verify. */
350370
err = nvkm_rd32(device, 0x001400 + (0xe * 4)) >> 16;
351371
if (err) {
352372
nvkm_error(subdev, "fwsec-frts: 0x%04x\n", err);
353-
return -EIO;
373+
ret = -EIO;
374+
} else {
375+
wpr2_lo = nvkm_rd32(device, 0x1fa824);
376+
wpr2_hi = nvkm_rd32(device, 0x1fa828);
377+
nvkm_debug(subdev, "fwsec-frts: WPR2 @ %08x - %08x\n", wpr2_lo, wpr2_hi);
354378
}
355379

356-
wpr2_lo = nvkm_rd32(device, 0x1fa824);
357-
wpr2_hi = nvkm_rd32(device, 0x1fa828);
358-
nvkm_debug(subdev, "fwsec-frts: WPR2 @ %08x - %08x\n", wpr2_lo, wpr2_hi);
359-
return 0;
380+
fwsec_dtor:
381+
nvkm_falcon_fw_dtor(&fw);
382+
return ret;
360383
}

drivers/gpu/drm/nouveau/nvkm/subdev/gsp/priv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
enum nvkm_acr_lsf_id;
77

88
int nvkm_gsp_fwsec_frts(struct nvkm_gsp *);
9+
10+
int nvkm_gsp_fwsec_sb_ctor(struct nvkm_gsp *);
911
int nvkm_gsp_fwsec_sb(struct nvkm_gsp *);
12+
void nvkm_gsp_fwsec_sb_dtor(struct nvkm_gsp *);
1013

1114
struct nvkm_gsp_fwif {
1215
int version;

0 commit comments

Comments
 (0)