Skip to content

Commit 2ffd45d

Browse files
committed
Merge tag 'drm-fixes-2024-07-12' of https://gitlab.freedesktop.org/drm/kernel
Pull drm fixes from Dave Airlie: "Oh I screwed up last week's fixes pull, and forgot to send.. Back to work, thanks to Sima for last week, not too many fixes as expected getting close to release [ sic - Linus ], amdgpu and xe have a couple each, and then some other misc ones. amdgpu: - PSR-SU fix - Reseved VMID fix xe: - Use write-back caching mode for system memory on DGFX - Do not leak object when finalizing hdcp gsc bridge: - adv7511 EDID irq fix gma500: - NULL mode fixes. meson: - fix resource leak" * tag 'drm-fixes-2024-07-12' of https://gitlab.freedesktop.org/drm/kernel: Revert "drm/amd/display: Reset freesync config before update new state" drm/xe/display/xe_hdcp_gsc: Free arbiter on driver removal drm/xe: Use write-back caching mode for system memory on DGFX drm/amdgpu: reject gang submit on reserved VMIDs drm/gma500: fix null pointer dereference in cdv_intel_lvds_get_modes drm/gma500: fix null pointer dereference in psb_intel_lvds_get_modes drm/meson: fix canvas release in bind function drm/bridge: adv7511: Fix Intermittent EDID failures
2 parents 5e04975 + 8b68788 commit 2ffd45d

File tree

14 files changed

+122
-60
lines changed

14 files changed

+122
-60
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,21 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
10931093
unsigned int i;
10941094
int r;
10951095

1096+
/*
1097+
* We can't use gang submit on with reserved VMIDs when the VM changes
1098+
* can't be invalidated by more than one engine at the same time.
1099+
*/
1100+
if (p->gang_size > 1 && !p->adev->vm_manager.concurrent_flush) {
1101+
for (i = 0; i < p->gang_size; ++i) {
1102+
struct drm_sched_entity *entity = p->entities[i];
1103+
struct drm_gpu_scheduler *sched = entity->rq->sched;
1104+
struct amdgpu_ring *ring = to_amdgpu_ring(sched);
1105+
1106+
if (amdgpu_vmid_uses_reserved(vm, ring->vm_hub))
1107+
return -EINVAL;
1108+
}
1109+
}
1110+
10961111
r = amdgpu_vm_clear_freed(adev, vm, NULL);
10971112
if (r)
10981113
return r;

drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
406406
if (r || !idle)
407407
goto error;
408408

409-
if (vm->reserved_vmid[vmhub] || (enforce_isolation && (vmhub == AMDGPU_GFXHUB(0)))) {
409+
if (amdgpu_vmid_uses_reserved(vm, vmhub)) {
410410
r = amdgpu_vmid_grab_reserved(vm, ring, job, &id, fence);
411411
if (r || !id)
412412
goto error;
@@ -456,6 +456,19 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
456456
return r;
457457
}
458458

459+
/*
460+
* amdgpu_vmid_uses_reserved - check if a VM will use a reserved VMID
461+
* @vm: the VM to check
462+
* @vmhub: the VMHUB which will be used
463+
*
464+
* Returns: True if the VM will use a reserved VMID.
465+
*/
466+
bool amdgpu_vmid_uses_reserved(struct amdgpu_vm *vm, unsigned int vmhub)
467+
{
468+
return vm->reserved_vmid[vmhub] ||
469+
(enforce_isolation && (vmhub == AMDGPU_GFXHUB(0)));
470+
}
471+
459472
int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev,
460473
unsigned vmhub)
461474
{

drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ void amdgpu_pasid_free_delayed(struct dma_resv *resv,
7878

7979
bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev,
8080
struct amdgpu_vmid *id);
81+
bool amdgpu_vmid_uses_reserved(struct amdgpu_vm *vm, unsigned int vmhub);
8182
int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev,
8283
unsigned vmhub);
8384
void amdgpu_vmid_free_reserved(struct amdgpu_device *adev,

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10048,7 +10048,6 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
1004810048
}
1004910049

1005010050
/* Update Freesync settings. */
10051-
reset_freesync_config_for_crtc(dm_new_crtc_state);
1005210051
get_freesync_config_for_crtc(dm_new_crtc_state,
1005310052
dm_new_conn_state);
1005410053

drivers/gpu/drm/bridge/adv7511/adv7511.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ struct adv7511 {
401401

402402
#ifdef CONFIG_DRM_I2C_ADV7511_CEC
403403
int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511);
404-
void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1);
404+
int adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1);
405405
#else
406406
static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
407407
{

drivers/gpu/drm/bridge/adv7511/adv7511_cec.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf)
119119
cec_received_msg(adv7511->cec_adap, &msg);
120120
}
121121

122-
void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
122+
int adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
123123
{
124124
unsigned int offset = adv7511->info->reg_cec_offset;
125125
const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY |
@@ -131,16 +131,19 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
131131
unsigned int rx_status;
132132
int rx_order[3] = { -1, -1, -1 };
133133
int i;
134+
int irq_status = IRQ_NONE;
134135

135-
if (irq1 & irq_tx_mask)
136+
if (irq1 & irq_tx_mask) {
136137
adv_cec_tx_raw_status(adv7511, irq1);
138+
irq_status = IRQ_HANDLED;
139+
}
137140

138141
if (!(irq1 & irq_rx_mask))
139-
return;
142+
return irq_status;
140143

141144
if (regmap_read(adv7511->regmap_cec,
142145
ADV7511_REG_CEC_RX_STATUS + offset, &rx_status))
143-
return;
146+
return irq_status;
144147

145148
/*
146149
* ADV7511_REG_CEC_RX_STATUS[5:0] contains the reception order of RX
@@ -172,6 +175,8 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
172175

173176
adv7511_cec_rx(adv7511, rx_buf);
174177
}
178+
179+
return IRQ_HANDLED;
175180
}
176181

177182
static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable)

drivers/gpu/drm/bridge/adv7511/adv7511_drv.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
469469
{
470470
unsigned int irq0, irq1;
471471
int ret;
472+
int cec_status = IRQ_NONE;
473+
int irq_status = IRQ_NONE;
472474

473475
ret = regmap_read(adv7511->regmap, ADV7511_REG_INT(0), &irq0);
474476
if (ret < 0)
@@ -478,29 +480,31 @@ static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
478480
if (ret < 0)
479481
return ret;
480482

481-
/* If there is no IRQ to handle, exit indicating no IRQ data */
482-
if (!(irq0 & (ADV7511_INT0_HPD | ADV7511_INT0_EDID_READY)) &&
483-
!(irq1 & ADV7511_INT1_DDC_ERROR))
484-
return -ENODATA;
485-
486483
regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);
487484
regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
488485

489-
if (process_hpd && irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder)
486+
if (process_hpd && irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder) {
490487
schedule_work(&adv7511->hpd_work);
488+
irq_status = IRQ_HANDLED;
489+
}
491490

492491
if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {
493492
adv7511->edid_read = true;
494493

495494
if (adv7511->i2c_main->irq)
496495
wake_up_all(&adv7511->wq);
496+
irq_status = IRQ_HANDLED;
497497
}
498498

499499
#ifdef CONFIG_DRM_I2C_ADV7511_CEC
500-
adv7511_cec_irq_process(adv7511, irq1);
500+
cec_status = adv7511_cec_irq_process(adv7511, irq1);
501501
#endif
502502

503-
return 0;
503+
/* If there is no IRQ to handle, exit indicating no IRQ data */
504+
if (irq_status == IRQ_HANDLED || cec_status == IRQ_HANDLED)
505+
return IRQ_HANDLED;
506+
507+
return IRQ_NONE;
504508
}
505509

506510
static irqreturn_t adv7511_irq_handler(int irq, void *devid)
@@ -509,7 +513,7 @@ static irqreturn_t adv7511_irq_handler(int irq, void *devid)
509513
int ret;
510514

511515
ret = adv7511_irq_process(adv7511, true);
512-
return ret < 0 ? IRQ_NONE : IRQ_HANDLED;
516+
return ret < 0 ? IRQ_NONE : ret;
513517
}
514518

515519
/* -----------------------------------------------------------------------------

drivers/gpu/drm/gma500/cdv_intel_lvds.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
311311
if (mode_dev->panel_fixed_mode != NULL) {
312312
struct drm_display_mode *mode =
313313
drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
314+
if (!mode)
315+
return 0;
316+
314317
drm_mode_probed_add(connector, mode);
315318
return 1;
316319
}

drivers/gpu/drm/gma500/psb_intel_lvds.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,9 @@ static int psb_intel_lvds_get_modes(struct drm_connector *connector)
504504
if (mode_dev->panel_fixed_mode != NULL) {
505505
struct drm_display_mode *mode =
506506
drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
507+
if (!mode)
508+
return 0;
509+
507510
drm_mode_probed_add(connector, mode);
508511
return 1;
509512
}

drivers/gpu/drm/meson/meson_drv.c

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -250,29 +250,20 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
250250
if (ret)
251251
goto free_drm;
252252
ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_0);
253-
if (ret) {
254-
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
255-
goto free_drm;
256-
}
253+
if (ret)
254+
goto free_canvas_osd1;
257255
ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_1);
258-
if (ret) {
259-
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
260-
meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
261-
goto free_drm;
262-
}
256+
if (ret)
257+
goto free_canvas_vd1_0;
263258
ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_2);
264-
if (ret) {
265-
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
266-
meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
267-
meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1);
268-
goto free_drm;
269-
}
259+
if (ret)
260+
goto free_canvas_vd1_1;
270261

271262
priv->vsync_irq = platform_get_irq(pdev, 0);
272263

273264
ret = drm_vblank_init(drm, 1);
274265
if (ret)
275-
goto free_drm;
266+
goto free_canvas_vd1_2;
276267

277268
/* Assign limits per soc revision/package */
278269
for (i = 0 ; i < ARRAY_SIZE(meson_drm_soc_attrs) ; ++i) {
@@ -288,11 +279,11 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
288279
*/
289280
ret = drm_aperture_remove_framebuffers(&meson_driver);
290281
if (ret)
291-
goto free_drm;
282+
goto free_canvas_vd1_2;
292283

293284
ret = drmm_mode_config_init(drm);
294285
if (ret)
295-
goto free_drm;
286+
goto free_canvas_vd1_2;
296287
drm->mode_config.max_width = 3840;
297288
drm->mode_config.max_height = 2160;
298289
drm->mode_config.funcs = &meson_mode_config_funcs;
@@ -307,7 +298,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
307298
if (priv->afbcd.ops) {
308299
ret = priv->afbcd.ops->init(priv);
309300
if (ret)
310-
goto free_drm;
301+
goto free_canvas_vd1_2;
311302
}
312303

313304
/* Encoder Initialization */
@@ -371,6 +362,14 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
371362
exit_afbcd:
372363
if (priv->afbcd.ops)
373364
priv->afbcd.ops->exit(priv);
365+
free_canvas_vd1_2:
366+
meson_canvas_free(priv->canvas, priv->canvas_id_vd1_2);
367+
free_canvas_vd1_1:
368+
meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1);
369+
free_canvas_vd1_0:
370+
meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
371+
free_canvas_osd1:
372+
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
374373
free_drm:
375374
drm_dev_put(drm);
376375

0 commit comments

Comments
 (0)