summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2024-08-13 00:03:55 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2024-08-13 00:03:55 +0000
commit1797a9b943468aa31cf662a752a7abe189052f0d (patch)
treed1bc42c0de3d0adef12748091c164d8a350783e4 /sys/dev
parentd772c8df8ec6b07b5b12adc0bd96dad269c6c2ef (diff)
drm/i915: Bypass LMEMBAR/GTTMMADR for MTL stolen memory access
From Ville Syrjala c08c364102d07288610734de34111a666e730ae7 in mainline linux
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/drm/i915/gem/i915_gem_stolen.c8
-rw-r--r--sys/dev/pci/drm/i915/gt/intel_ggtt.c19
-rw-r--r--sys/dev/pci/drm/i915/i915_reg.h3
-rw-r--r--sys/dev/pci/drm/i915/i915_utils.c17
-rw-r--r--sys/dev/pci/drm/i915/i915_utils.h2
5 files changed, 45 insertions, 4 deletions
diff --git a/sys/dev/pci/drm/i915/gem/i915_gem_stolen.c b/sys/dev/pci/drm/i915/gem/i915_gem_stolen.c
index b8a19413320..1fdadbd45e8 100644
--- a/sys/dev/pci/drm/i915/gem/i915_gem_stolen.c
+++ b/sys/dev/pci/drm/i915/gem/i915_gem_stolen.c
@@ -990,8 +990,12 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type,
dsm_size = ALIGN_DOWN(lmem_size - dsm_base, SZ_1M);
}
+ if (i915_direct_stolen_access(i915)) {
+ drm_dbg(&i915->drm, "Using direct DSM access\n");
+ io_start = intel_uncore_read64(uncore, GEN12_DSMBASE) & GEN12_BDSM_MASK;
+ io_size = dsm_size;
#ifdef __linux__
- if (pci_resource_len(pdev, GEN12_LMEM_BAR) < lmem_size) {
+ } else if (pci_resource_len(pdev, GEN12_LMEM_BAR) < lmem_size) {
io_start = 0;
io_size = 0;
} else {
@@ -999,7 +1003,7 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type,
io_size = dsm_size;
}
#else
- if (lmem_len < lmem_size) {
+ } else if (lmem_len < lmem_size) {
io_start = 0;
io_size = 0;
} else {
diff --git a/sys/dev/pci/drm/i915/gt/intel_ggtt.c b/sys/dev/pci/drm/i915/gt/intel_ggtt.c
index 2860d397f8e..14818a3d20b 100644
--- a/sys/dev/pci/drm/i915/gt/intel_ggtt.c
+++ b/sys/dev/pci/drm/i915/gt/intel_ggtt.c
@@ -24,6 +24,7 @@
#include "intel_ring.h"
#include "i915_drv.h"
#include "i915_pci.h"
+#include "i915_reg.h"
#include "i915_request.h"
#include "i915_scatterlist.h"
#include "i915_utils.h"
@@ -1171,13 +1172,20 @@ static unsigned int gen6_gttadr_offset(struct drm_i915_private *i915)
static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
{
struct drm_i915_private *i915 = ggtt->vm.i915;
+ struct intel_uncore *uncore = ggtt->vm.gt->uncore;
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
phys_addr_t phys_addr;
u32 pte_flags;
int ret;
GEM_WARN_ON(pci_resource_len(pdev, GEN4_GTTMMADR_BAR) != gen6_gttmmadr_size(i915));
- phys_addr = pci_resource_start(pdev, GEN4_GTTMMADR_BAR) + gen6_gttadr_offset(i915);
+
+ if (i915_direct_stolen_access(i915)) {
+ drm_dbg(&i915->drm, "Using direct GSM access\n");
+ phys_addr = intel_uncore_read64(uncore, GEN12_GSMBASE) & GEN12_BDSM_MASK;
+ } else {
+ phys_addr = pci_resource_start(pdev, GEN4_GTTMMADR_BAR) + gen6_gttadr_offset(i915);
+ }
if (needs_wc_ggtt_mapping(i915))
ggtt->gsm = ioremap_wc(phys_addr, size);
@@ -1216,6 +1224,7 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
{
struct drm_i915_private *i915 = ggtt->vm.i915;
+ struct intel_uncore *uncore = ggtt->vm.gt->uncore;
struct pci_dev *pdev = i915->drm.pdev;
phys_addr_t phys_addr;
bus_addr_t addr;
@@ -1232,7 +1241,13 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
return ret;
GEM_WARN_ON(len != gen6_gttmmadr_size(i915));
- phys_addr = addr + gen6_gttadr_offset(i915);
+
+ if (i915_direct_stolen_access(i915)) {
+ drm_dbg(&i915->drm, "Using direct GSM access\n");
+ phys_addr = intel_uncore_read64(uncore, GEN12_GSMBASE) & GEN12_BDSM_MASK;
+ } else {
+ phys_addr = addr + gen6_gttadr_offset(i915);
+ }
if (needs_wc_ggtt_mapping(i915))
flags = BUS_SPACE_MAP_PREFETCHABLE;
diff --git a/sys/dev/pci/drm/i915/i915_reg.h b/sys/dev/pci/drm/i915/i915_reg.h
index aefad14ab27..386286356d2 100644
--- a/sys/dev/pci/drm/i915/i915_reg.h
+++ b/sys/dev/pci/drm/i915/i915_reg.h
@@ -5452,6 +5452,9 @@
#define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16
#define GEN6_PCODE_DATA1 _MMIO(0x13812C)
+#define MTL_PCODE_STOLEN_ACCESS _MMIO(0x138914)
+#define STOLEN_ACCESS_ALLOWED 0x1
+
/* IVYBRIDGE DPF */
#define GEN7_L3CDERRST1(slice) _MMIO(0xB008 + (slice) * 0x200) /* L3CD Error Status 1 */
#define GEN7_L3CDERRST1_ROW_MASK (0x7ff << 14)
diff --git a/sys/dev/pci/drm/i915/i915_utils.c b/sys/dev/pci/drm/i915/i915_utils.c
index d742c01214e..95a95731d7d 100644
--- a/sys/dev/pci/drm/i915/i915_utils.c
+++ b/sys/dev/pci/drm/i915/i915_utils.c
@@ -8,6 +8,7 @@
#include <drm/drm_drv.h>
#include "i915_drv.h"
+#include "i915_reg.h"
#include "i915_utils.h"
#include <sys/syslog.h>
@@ -138,3 +139,19 @@ bool i915_vtd_active(struct drm_i915_private *i915)
return i915_run_as_guest();
#endif
}
+
+bool i915_direct_stolen_access(struct drm_i915_private *i915)
+{
+ /*
+ * Wa_22018444074
+ *
+ * Access via BAR can hang MTL, go directly to GSM/DSM,
+ * except for VM guests which won't have access to it.
+ *
+ * Normally this would not work but on MTL the system firmware
+ * should have relaxed the access permissions sufficiently.
+ * 0x138914==0x1 indicates that the firmware has done its job.
+ */
+ return IS_METEORLAKE(i915) && !i915_run_as_guest() &&
+ intel_uncore_read(&i915->uncore, MTL_PCODE_STOLEN_ACCESS) == STOLEN_ACCESS_ALLOWED;
+}
diff --git a/sys/dev/pci/drm/i915/i915_utils.h b/sys/dev/pci/drm/i915/i915_utils.h
index 026fdb3ed1c..4ee6a182ac1 100644
--- a/sys/dev/pci/drm/i915/i915_utils.h
+++ b/sys/dev/pci/drm/i915/i915_utils.h
@@ -401,4 +401,6 @@ static inline bool i915_run_as_guest(void)
bool i915_vtd_active(struct drm_i915_private *i915);
+bool i915_direct_stolen_access(struct drm_i915_private *i915);
+
#endif /* !__I915_UTILS_H */