Skip to content

Commit a9f5a75

Browse files
committed
Merge tag 'drm-intel-fixes-2022-12-30' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
- fix TLB invalidation for DG2 and newer platforms. (Andrzej) - Remove __maybe_unused from mtl_info (Lucas) - improve the catch-all evict to handle lock contention (Matt Auld) - Fix two issues with over-size (GuC/HuC) firmware files (John) - Fix DSI resume issues on ICL+ (Jani) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/Y662ijDHrZCjTFla@intel.com
2 parents 1b929c0 + 6217e9f commit a9f5a75

File tree

12 files changed

+212
-45
lines changed

12 files changed

+212
-45
lines changed

drivers/gpu/drm/i915/display/intel_dsi_vbt.c

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@
4141

4242
#include "i915_drv.h"
4343
#include "i915_reg.h"
44+
#include "intel_de.h"
4445
#include "intel_display_types.h"
4546
#include "intel_dsi.h"
4647
#include "intel_dsi_vbt.h"
48+
#include "intel_gmbus_regs.h"
4749
#include "vlv_dsi.h"
4850
#include "vlv_dsi_regs.h"
4951
#include "vlv_sideband.h"
@@ -377,15 +379,93 @@ static void icl_exec_gpio(struct intel_connector *connector,
377379
drm_dbg_kms(&dev_priv->drm, "Skipping ICL GPIO element execution\n");
378380
}
379381

382+
enum {
383+
MIPI_RESET_1 = 0,
384+
MIPI_AVDD_EN_1,
385+
MIPI_BKLT_EN_1,
386+
MIPI_AVEE_EN_1,
387+
MIPI_VIO_EN_1,
388+
MIPI_RESET_2,
389+
MIPI_AVDD_EN_2,
390+
MIPI_BKLT_EN_2,
391+
MIPI_AVEE_EN_2,
392+
MIPI_VIO_EN_2,
393+
};
394+
395+
static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv,
396+
int gpio, bool value)
397+
{
398+
int index;
399+
400+
if (drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) == 11 && gpio >= MIPI_RESET_2))
401+
return;
402+
403+
switch (gpio) {
404+
case MIPI_RESET_1:
405+
case MIPI_RESET_2:
406+
index = gpio == MIPI_RESET_1 ? HPD_PORT_A : HPD_PORT_B;
407+
408+
/*
409+
* Disable HPD to set the pin to output, and set output
410+
* value. The HPD pin should not be enabled for DSI anyway,
411+
* assuming the board design and VBT are sane, and the pin isn't
412+
* used by a non-DSI encoder.
413+
*
414+
* The locking protects against concurrent SHOTPLUG_CTL_DDI
415+
* modifications in irq setup and handling.
416+
*/
417+
spin_lock_irq(&dev_priv->irq_lock);
418+
intel_de_rmw(dev_priv, SHOTPLUG_CTL_DDI,
419+
SHOTPLUG_CTL_DDI_HPD_ENABLE(index) |
420+
SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index),
421+
value ? SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index) : 0);
422+
spin_unlock_irq(&dev_priv->irq_lock);
423+
break;
424+
case MIPI_AVDD_EN_1:
425+
case MIPI_AVDD_EN_2:
426+
index = gpio == MIPI_AVDD_EN_1 ? 0 : 1;
427+
428+
intel_de_rmw(dev_priv, PP_CONTROL(index), PANEL_POWER_ON,
429+
value ? PANEL_POWER_ON : 0);
430+
break;
431+
case MIPI_BKLT_EN_1:
432+
case MIPI_BKLT_EN_2:
433+
index = gpio == MIPI_BKLT_EN_1 ? 0 : 1;
434+
435+
intel_de_rmw(dev_priv, PP_CONTROL(index), EDP_BLC_ENABLE,
436+
value ? EDP_BLC_ENABLE : 0);
437+
break;
438+
case MIPI_AVEE_EN_1:
439+
case MIPI_AVEE_EN_2:
440+
index = gpio == MIPI_AVEE_EN_1 ? 1 : 2;
441+
442+
intel_de_rmw(dev_priv, GPIO(dev_priv, index),
443+
GPIO_CLOCK_VAL_OUT,
444+
GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_DIR_OUT |
445+
GPIO_CLOCK_VAL_MASK | (value ? GPIO_CLOCK_VAL_OUT : 0));
446+
break;
447+
case MIPI_VIO_EN_1:
448+
case MIPI_VIO_EN_2:
449+
index = gpio == MIPI_VIO_EN_1 ? 1 : 2;
450+
451+
intel_de_rmw(dev_priv, GPIO(dev_priv, index),
452+
GPIO_DATA_VAL_OUT,
453+
GPIO_DATA_DIR_MASK | GPIO_DATA_DIR_OUT |
454+
GPIO_DATA_VAL_MASK | (value ? GPIO_DATA_VAL_OUT : 0));
455+
break;
456+
default:
457+
MISSING_CASE(gpio);
458+
}
459+
}
460+
380461
static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
381462
{
382463
struct drm_device *dev = intel_dsi->base.base.dev;
383464
struct drm_i915_private *dev_priv = to_i915(dev);
384465
struct intel_connector *connector = intel_dsi->attached_connector;
385466
u8 gpio_source, gpio_index = 0, gpio_number;
386467
bool value;
387-
388-
drm_dbg_kms(&dev_priv->drm, "\n");
468+
bool native = DISPLAY_VER(dev_priv) >= 11;
389469

390470
if (connector->panel.vbt.dsi.seq_version >= 3)
391471
gpio_index = *data++;
@@ -398,10 +478,18 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
398478
else
399479
gpio_source = 0;
400480

481+
if (connector->panel.vbt.dsi.seq_version >= 4 && *data & BIT(1))
482+
native = false;
483+
401484
/* pull up/down */
402485
value = *data++ & 1;
403486

404-
if (DISPLAY_VER(dev_priv) >= 11)
487+
drm_dbg_kms(&dev_priv->drm, "GPIO index %u, number %u, source %u, native %s, set to %s\n",
488+
gpio_index, gpio_number, gpio_source, str_yes_no(native), str_on_off(value));
489+
490+
if (native)
491+
icl_native_gpio_set_value(dev_priv, gpio_number, value);
492+
else if (DISPLAY_VER(dev_priv) >= 11)
405493
icl_exec_gpio(connector, gpio_source, gpio_index, value);
406494
else if (IS_VALLEYVIEW(dev_priv))
407495
vlv_exec_gpio(connector, gpio_source, gpio_number, value);

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -730,32 +730,69 @@ static int eb_reserve(struct i915_execbuffer *eb)
730730
bool unpinned;
731731

732732
/*
733-
* Attempt to pin all of the buffers into the GTT.
734-
* This is done in 2 phases:
733+
* We have one more buffers that we couldn't bind, which could be due to
734+
* various reasons. To resolve this we have 4 passes, with every next
735+
* level turning the screws tighter:
735736
*
736-
* 1. Unbind all objects that do not match the GTT constraints for
737-
* the execbuffer (fenceable, mappable, alignment etc).
738-
* 2. Bind new objects.
737+
* 0. Unbind all objects that do not match the GTT constraints for the
738+
* execbuffer (fenceable, mappable, alignment etc). Bind all new
739+
* objects. This avoids unnecessary unbinding of later objects in order
740+
* to make room for the earlier objects *unless* we need to defragment.
739741
*
740-
* This avoid unnecessary unbinding of later objects in order to make
741-
* room for the earlier objects *unless* we need to defragment.
742+
* 1. Reorder the buffers, where objects with the most restrictive
743+
* placement requirements go first (ignoring fixed location buffers for
744+
* now). For example, objects needing the mappable aperture (the first
745+
* 256M of GTT), should go first vs objects that can be placed just
746+
* about anywhere. Repeat the previous pass.
742747
*
743-
* Defragmenting is skipped if all objects are pinned at a fixed location.
748+
* 2. Consider buffers that are pinned at a fixed location. Also try to
749+
* evict the entire VM this time, leaving only objects that we were
750+
* unable to lock. Try again to bind the buffers. (still using the new
751+
* buffer order).
752+
*
753+
* 3. We likely have object lock contention for one or more stubborn
754+
* objects in the VM, for which we need to evict to make forward
755+
* progress (perhaps we are fighting the shrinker?). When evicting the
756+
* VM this time around, anything that we can't lock we now track using
757+
* the busy_bo, using the full lock (after dropping the vm->mutex to
758+
* prevent deadlocks), instead of trylock. We then continue to evict the
759+
* VM, this time with the stubborn object locked, which we can now
760+
* hopefully unbind (if still bound in the VM). Repeat until the VM is
761+
* evicted. Finally we should be able bind everything.
744762
*/
745-
for (pass = 0; pass <= 2; pass++) {
763+
for (pass = 0; pass <= 3; pass++) {
746764
int pin_flags = PIN_USER | PIN_VALIDATE;
747765

748766
if (pass == 0)
749767
pin_flags |= PIN_NONBLOCK;
750768

751769
if (pass >= 1)
752-
unpinned = eb_unbind(eb, pass == 2);
770+
unpinned = eb_unbind(eb, pass >= 2);
753771

754772
if (pass == 2) {
755773
err = mutex_lock_interruptible(&eb->context->vm->mutex);
756774
if (!err) {
757-
err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
775+
err = i915_gem_evict_vm(eb->context->vm, &eb->ww, NULL);
776+
mutex_unlock(&eb->context->vm->mutex);
777+
}
778+
if (err)
779+
return err;
780+
}
781+
782+
if (pass == 3) {
783+
retry:
784+
err = mutex_lock_interruptible(&eb->context->vm->mutex);
785+
if (!err) {
786+
struct drm_i915_gem_object *busy_bo = NULL;
787+
788+
err = i915_gem_evict_vm(eb->context->vm, &eb->ww, &busy_bo);
758789
mutex_unlock(&eb->context->vm->mutex);
790+
if (err && busy_bo) {
791+
err = i915_gem_object_lock(busy_bo, &eb->ww);
792+
i915_gem_object_put(busy_bo);
793+
if (!err)
794+
goto retry;
795+
}
759796
}
760797
if (err)
761798
return err;

drivers/gpu/drm/i915/gem/i915_gem_mman.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
369369
if (vma == ERR_PTR(-ENOSPC)) {
370370
ret = mutex_lock_interruptible(&ggtt->vm.mutex);
371371
if (!ret) {
372-
ret = i915_gem_evict_vm(&ggtt->vm, &ww);
372+
ret = i915_gem_evict_vm(&ggtt->vm, &ww, NULL);
373373
mutex_unlock(&ggtt->vm.mutex);
374374
}
375375
if (ret)

drivers/gpu/drm/i915/gt/intel_gt.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,9 +1109,15 @@ static void mmio_invalidate_full(struct intel_gt *gt)
11091109
continue;
11101110

11111111
if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50)) {
1112+
u32 val = BIT(engine->instance);
1113+
1114+
if (engine->class == VIDEO_DECODE_CLASS ||
1115+
engine->class == VIDEO_ENHANCEMENT_CLASS ||
1116+
engine->class == COMPUTE_CLASS)
1117+
val = _MASKED_BIT_ENABLE(val);
11121118
intel_gt_mcr_multicast_write_fw(gt,
11131119
xehp_regs[engine->class],
1114-
BIT(engine->instance));
1120+
val);
11151121
} else {
11161122
rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num);
11171123
if (!i915_mmio_reg_offset(rb.reg))

drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,32 @@ static int check_ccs_header(struct intel_gt *gt,
545545
return 0;
546546
}
547547

548+
static int try_firmware_load(struct intel_uc_fw *uc_fw, const struct firmware **fw)
549+
{
550+
struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
551+
struct device *dev = gt->i915->drm.dev;
552+
int err;
553+
554+
err = firmware_request_nowarn(fw, uc_fw->file_selected.path, dev);
555+
556+
if (err)
557+
return err;
558+
559+
if ((*fw)->size > INTEL_UC_RSVD_GGTT_PER_FW) {
560+
drm_err(&gt->i915->drm,
561+
"%s firmware %s: size (%zuKB) exceeds max supported size (%uKB)\n",
562+
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
563+
(*fw)->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW / SZ_1K);
564+
565+
/* try to find another blob to load */
566+
release_firmware(*fw);
567+
*fw = NULL;
568+
return -ENOENT;
569+
}
570+
571+
return 0;
572+
}
573+
548574
/**
549575
* intel_uc_fw_fetch - fetch uC firmware
550576
* @uc_fw: uC firmware
@@ -558,7 +584,6 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
558584
struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
559585
struct drm_i915_private *i915 = gt->i915;
560586
struct intel_uc_fw_file file_ideal;
561-
struct device *dev = i915->drm.dev;
562587
struct drm_i915_gem_object *obj;
563588
const struct firmware *fw = NULL;
564589
bool old_ver = false;
@@ -574,20 +599,9 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
574599
__force_fw_fetch_failures(uc_fw, -EINVAL);
575600
__force_fw_fetch_failures(uc_fw, -ESTALE);
576601

577-
err = firmware_request_nowarn(&fw, uc_fw->file_selected.path, dev);
602+
err = try_firmware_load(uc_fw, &fw);
578603
memcpy(&file_ideal, &uc_fw->file_wanted, sizeof(file_ideal));
579604

580-
if (!err && fw->size > INTEL_UC_RSVD_GGTT_PER_FW) {
581-
drm_err(&i915->drm,
582-
"%s firmware %s: size (%zuKB) exceeds max supported size (%uKB)\n",
583-
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
584-
fw->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW / SZ_1K);
585-
586-
/* try to find another blob to load */
587-
release_firmware(fw);
588-
err = -ENOENT;
589-
}
590-
591605
/* Any error is terminal if overriding. Don't bother searching for older versions */
592606
if (err && intel_uc_fw_is_overridden(uc_fw))
593607
goto fail;
@@ -608,7 +622,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
608622
break;
609623
}
610624

611-
err = firmware_request_nowarn(&fw, uc_fw->file_selected.path, dev);
625+
err = try_firmware_load(uc_fw, &fw);
612626
}
613627

614628
if (err)

drivers/gpu/drm/i915/i915_gem_evict.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
416416
* @vm: Address space to cleanse
417417
* @ww: An optional struct i915_gem_ww_ctx. If not NULL, i915_gem_evict_vm
418418
* will be able to evict vma's locked by the ww as well.
419+
* @busy_bo: Optional pointer to struct drm_i915_gem_object. If not NULL, then
420+
* in the event i915_gem_evict_vm() is unable to trylock an object for eviction,
421+
* then @busy_bo will point to it. -EBUSY is also returned. The caller must drop
422+
* the vm->mutex, before trying again to acquire the contended lock. The caller
423+
* also owns a reference to the object.
419424
*
420425
* This function evicts all vmas from a vm.
421426
*
@@ -425,7 +430,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
425430
* To clarify: This is for freeing up virtual address space, not for freeing
426431
* memory in e.g. the shrinker.
427432
*/
428-
int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
433+
int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww,
434+
struct drm_i915_gem_object **busy_bo)
429435
{
430436
int ret = 0;
431437

@@ -457,41 +463,52 @@ int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
457463
* the resv is shared among multiple objects, we still
458464
* need the object ref.
459465
*/
460-
if (dying_vma(vma) ||
466+
if (!i915_gem_object_get_rcu(vma->obj) ||
461467
(ww && (dma_resv_locking_ctx(vma->obj->base.resv) == &ww->ctx))) {
462468
__i915_vma_pin(vma);
463469
list_add(&vma->evict_link, &locked_eviction_list);
464470
continue;
465471
}
466472

467-
if (!i915_gem_object_trylock(vma->obj, ww))
473+
if (!i915_gem_object_trylock(vma->obj, ww)) {
474+
if (busy_bo) {
475+
*busy_bo = vma->obj; /* holds ref */
476+
ret = -EBUSY;
477+
break;
478+
}
479+
i915_gem_object_put(vma->obj);
468480
continue;
481+
}
469482

470483
__i915_vma_pin(vma);
471484
list_add(&vma->evict_link, &eviction_list);
472485
}
473486
if (list_empty(&eviction_list) && list_empty(&locked_eviction_list))
474487
break;
475488

476-
ret = 0;
477489
/* Unbind locked objects first, before unlocking the eviction_list */
478490
list_for_each_entry_safe(vma, vn, &locked_eviction_list, evict_link) {
479491
__i915_vma_unpin(vma);
480492

481-
if (ret == 0)
493+
if (ret == 0) {
482494
ret = __i915_vma_unbind(vma);
483-
if (ret != -EINTR) /* "Get me out of here!" */
484-
ret = 0;
495+
if (ret != -EINTR) /* "Get me out of here!" */
496+
ret = 0;
497+
}
498+
if (!dying_vma(vma))
499+
i915_gem_object_put(vma->obj);
485500
}
486501

487502
list_for_each_entry_safe(vma, vn, &eviction_list, evict_link) {
488503
__i915_vma_unpin(vma);
489-
if (ret == 0)
504+
if (ret == 0) {
490505
ret = __i915_vma_unbind(vma);
491-
if (ret != -EINTR) /* "Get me out of here!" */
492-
ret = 0;
506+
if (ret != -EINTR) /* "Get me out of here!" */
507+
ret = 0;
508+
}
493509

494510
i915_gem_object_unlock(vma->obj);
511+
i915_gem_object_put(vma->obj);
495512
}
496513
} while (ret == 0);
497514

0 commit comments

Comments
 (0)