summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/xe/xe_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/xe/xe_pci.c')
-rw-r--r--drivers/gpu/drm/xe/xe_pci.c113
1 files changed, 85 insertions, 28 deletions
diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
index f326dbb1cecd..732ee0d02124 100644
--- a/drivers/gpu/drm/xe/xe_pci.c
+++ b/drivers/gpu/drm/xe/xe_pci.c
@@ -13,16 +13,19 @@
#include <drm/drm_color_mgmt.h>
#include <drm/drm_drv.h>
-#include <drm/xe_pciids.h>
+#include <drm/intel/xe_pciids.h>
#include "display/xe_display.h"
#include "regs/xe_gt_regs.h"
#include "xe_device.h"
#include "xe_drv.h"
#include "xe_gt.h"
+#include "xe_gt_sriov_vf.h"
+#include "xe_guc.h"
#include "xe_macros.h"
#include "xe_mmio.h"
#include "xe_module.h"
+#include "xe_pci_sriov.h"
#include "xe_pci_types.h"
#include "xe_pm.h"
#include "xe_sriov.h"
@@ -40,12 +43,6 @@ struct xe_subplatform_desc {
const u16 *pciidlist;
};
-struct xe_gt_desc {
- enum xe_gt_type type;
- u32 mmio_adj_limit;
- u32 mmio_adj_offset;
-};
-
struct xe_device_desc {
/* Should only ever be set for platforms without GMD_ID */
const struct xe_graphics_desc *graphics;
@@ -74,7 +71,7 @@ __diag_push();
__diag_ignore_all("-Woverride-init", "Allow field overrides in table");
#define PLATFORM(x) \
- .platform = (x), \
+ .platform = XE_##x, \
.platform_name = #x
#define NOP(x) x
@@ -146,6 +143,7 @@ static const struct xe_graphics_desc graphics_xehpc = {
.vram_flags = XE_VRAM_FLAGS_NEED64K,
.has_asid = 1,
+ .has_atomic_enable_pte_bit = 1,
.has_flat_ccs = 0,
.has_usm = 1,
};
@@ -163,7 +161,9 @@ static const struct xe_graphics_desc graphics_xelpg = {
#define XE2_GFX_FEATURES \
.dma_mask_size = 46, \
.has_asid = 1, \
+ .has_atomic_enable_pte_bit = 1, \
.has_flat_ccs = 1, \
+ .has_indirect_ring_state = 1, \
.has_range_tlb_invalidation = 1, \
.has_usm = 1, \
.va_bits = 48, \
@@ -211,13 +211,14 @@ static const struct xe_media_desc media_xe2 = {
.name = "Xe2_LPM / Xe2_HPM",
.hw_engine_mask =
GENMASK(XE_HW_ENGINE_VCS7, XE_HW_ENGINE_VCS0) |
- GENMASK(XE_HW_ENGINE_VECS3, XE_HW_ENGINE_VECS0), /* TODO: GSC0 */
+ GENMASK(XE_HW_ENGINE_VECS3, XE_HW_ENGINE_VECS0) |
+ BIT(XE_HW_ENGINE_GSCCS0)
};
static const struct xe_device_desc tgl_desc = {
.graphics = &graphics_xelp,
.media = &media_xem,
- PLATFORM(XE_TIGERLAKE),
+ PLATFORM(TIGERLAKE),
.has_display = true,
.has_llc = true,
.require_force_probe = true,
@@ -226,7 +227,7 @@ static const struct xe_device_desc tgl_desc = {
static const struct xe_device_desc rkl_desc = {
.graphics = &graphics_xelp,
.media = &media_xem,
- PLATFORM(XE_ROCKETLAKE),
+ PLATFORM(ROCKETLAKE),
.has_display = true,
.has_llc = true,
.require_force_probe = true,
@@ -237,7 +238,7 @@ static const u16 adls_rpls_ids[] = { XE_RPLS_IDS(NOP), 0 };
static const struct xe_device_desc adl_s_desc = {
.graphics = &graphics_xelp,
.media = &media_xem,
- PLATFORM(XE_ALDERLAKE_S),
+ PLATFORM(ALDERLAKE_S),
.has_display = true,
.has_llc = true,
.require_force_probe = true,
@@ -252,7 +253,7 @@ static const u16 adlp_rplu_ids[] = { XE_RPLU_IDS(NOP), 0 };
static const struct xe_device_desc adl_p_desc = {
.graphics = &graphics_xelp,
.media = &media_xem,
- PLATFORM(XE_ALDERLAKE_P),
+ PLATFORM(ALDERLAKE_P),
.has_display = true,
.has_llc = true,
.require_force_probe = true,
@@ -265,7 +266,7 @@ static const struct xe_device_desc adl_p_desc = {
static const struct xe_device_desc adl_n_desc = {
.graphics = &graphics_xelp,
.media = &media_xem,
- PLATFORM(XE_ALDERLAKE_N),
+ PLATFORM(ALDERLAKE_N),
.has_display = true,
.has_llc = true,
.require_force_probe = true,
@@ -278,7 +279,7 @@ static const struct xe_device_desc dg1_desc = {
.graphics = &graphics_xelpp,
.media = &media_xem,
DGFX_FEATURES,
- PLATFORM(XE_DG1),
+ PLATFORM(DG1),
.has_display = true,
.has_heci_gscfi = 1,
.require_force_probe = true,
@@ -290,7 +291,7 @@ static const u16 dg2_g12_ids[] = { XE_DG2_G12_IDS(NOP), 0 };
#define DG2_FEATURES \
DGFX_FEATURES, \
- PLATFORM(XE_DG2), \
+ PLATFORM(DG2), \
.has_heci_gscfi = 1, \
.subplatforms = (const struct xe_subplatform_desc[]) { \
{ XE_SUBPLATFORM_DG2_G10, "G10", dg2_g10_ids }, \
@@ -320,7 +321,7 @@ static const struct xe_device_desc dg2_desc = {
static const __maybe_unused struct xe_device_desc pvc_desc = {
.graphics = &graphics_xehpc,
DGFX_FEATURES,
- PLATFORM(XE_PVC),
+ PLATFORM(PVC),
.has_display = false,
.has_heci_gscfi = 1,
.require_force_probe = true,
@@ -329,19 +330,20 @@ static const __maybe_unused struct xe_device_desc pvc_desc = {
static const struct xe_device_desc mtl_desc = {
/* .graphics and .media determined via GMD_ID */
.require_force_probe = true,
- PLATFORM(XE_METEORLAKE),
+ PLATFORM(METEORLAKE),
.has_display = true,
};
static const struct xe_device_desc lnl_desc = {
- PLATFORM(XE_LUNARLAKE),
+ PLATFORM(LUNARLAKE),
.has_display = true,
.require_force_probe = true,
};
-static const struct xe_device_desc bmg_desc __maybe_unused = {
+static const struct xe_device_desc bmg_desc = {
DGFX_FEATURES,
- PLATFORM(XE_BATTLEMAGE),
+ PLATFORM(BATTLEMAGE),
+ .has_display = true,
.require_force_probe = true,
};
@@ -388,6 +390,7 @@ static const struct pci_device_id pciidlist[] = {
XE_DG2_IDS(INTEL_VGA_DEVICE, &dg2_desc),
XE_MTL_IDS(INTEL_VGA_DEVICE, &mtl_desc),
XE_LNL_IDS(INTEL_VGA_DEVICE, &lnl_desc),
+ XE_BMG_IDS(INTEL_VGA_DEVICE, &bmg_desc),
{ }
};
MODULE_DEVICE_TABLE(pci, pciidlist);
@@ -470,10 +473,52 @@ static void read_gmdid(struct xe_device *xe, enum xe_gmdid_type type, u32 *ver,
KUNIT_STATIC_STUB_REDIRECT(read_gmdid, xe, type, ver, revid);
- if (type == GMDID_MEDIA)
- gmdid_reg.addr += MEDIA_GT_GSI_OFFSET;
+ if (IS_SRIOV_VF(xe)) {
+ /*
+ * To get the value of the GMDID register, VFs must obtain it
+ * from the GuC using MMIO communication.
+ *
+ * Note that at this point the xe_gt is not fully uninitialized
+ * and only basic access to MMIO registers is possible. To use
+ * our existing GuC communication functions we must perform at
+ * least basic xe_gt and xe_guc initialization.
+ *
+ * Since to obtain the value of GMDID_MEDIA we need to use the
+ * media GuC, temporarly tweak the gt type.
+ */
+ xe_gt_assert(gt, gt->info.type == XE_GT_TYPE_UNINITIALIZED);
+
+ if (type == GMDID_MEDIA) {
+ gt->info.id = 1;
+ gt->info.type = XE_GT_TYPE_MEDIA;
+ } else {
+ gt->info.id = 0;
+ gt->info.type = XE_GT_TYPE_MAIN;
+ }
+
+ xe_guc_comm_init_early(&gt->uc.guc);
+
+ /* Don't bother with GMDID if failed to negotiate the GuC ABI */
+ val = xe_gt_sriov_vf_bootstrap(gt) ? 0 : xe_gt_sriov_vf_gmdid(gt);
+
+ /*
+ * Only undo xe_gt.info here, the remaining changes made above
+ * will be overwritten as part of the regular initialization.
+ */
+ gt->info.id = 0;
+ gt->info.type = XE_GT_TYPE_UNINITIALIZED;
+ } else {
+ /*
+ * We need to apply the GSI offset explicitly here as at this
+ * point the xe_gt is not fully uninitialized and only basic
+ * access to MMIO registers is possible.
+ */
+ if (type == GMDID_MEDIA)
+ gmdid_reg.addr += MEDIA_GT_GSI_OFFSET;
+
+ val = xe_mmio_read32(gt, gmdid_reg);
+ }
- val = xe_mmio_read32(gt, gmdid_reg);
*ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val) * 100 + REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
*revid = REG_FIELD_GET(GMD_ID_REVID, val);
}
@@ -554,6 +599,7 @@ static int xe_info_init_early(struct xe_device *xe,
{
int err;
+ xe->info.platform_name = desc->platform_name;
xe->info.platform = desc->platform;
xe->info.subplatform = subplatform_desc ?
subplatform_desc->subplatform : XE_SUBPLATFORM_NONE;
@@ -628,6 +674,9 @@ static int xe_info_init(struct xe_device *xe,
xe->info.va_bits = graphics_desc->va_bits;
xe->info.vm_max_level = graphics_desc->vm_max_level;
xe->info.has_asid = graphics_desc->has_asid;
+ xe->info.has_atomic_enable_pte_bit = graphics_desc->has_atomic_enable_pte_bit;
+ if (xe->info.platform != XE_PVC)
+ xe->info.has_device_atomics_on_smem = 1;
xe->info.has_flat_ccs = graphics_desc->has_flat_ccs;
xe->info.has_range_tlb_invalidation = graphics_desc->has_range_tlb_invalidation;
xe->info.has_usm = graphics_desc->has_usm;
@@ -655,9 +704,10 @@ static int xe_info_init(struct xe_device *xe,
gt = tile->primary_gt;
gt->info.id = xe->info.gt_count++;
gt->info.type = XE_GT_TYPE_MAIN;
- gt->info.__engine_mask = graphics_desc->hw_engine_mask;
+ gt->info.has_indirect_ring_state = graphics_desc->has_indirect_ring_state;
+ gt->info.engine_mask = graphics_desc->hw_engine_mask;
if (MEDIA_VER(xe) < 13 && media_desc)
- gt->info.__engine_mask |= media_desc->hw_engine_mask;
+ gt->info.engine_mask |= media_desc->hw_engine_mask;
if (MEDIA_VER(xe) < 13 || !media_desc)
continue;
@@ -672,7 +722,8 @@ static int xe_info_init(struct xe_device *xe,
gt = tile->media_gt;
gt->info.type = XE_GT_TYPE_MEDIA;
- gt->info.__engine_mask = media_desc->hw_engine_mask;
+ gt->info.has_indirect_ring_state = media_desc->has_indirect_ring_state;
+ gt->info.engine_mask = media_desc->hw_engine_mask;
gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET;
gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH;
@@ -697,6 +748,9 @@ static void xe_pci_remove(struct pci_dev *pdev)
if (!xe) /* driver load aborted, nothing to cleanup */
return;
+ if (IS_SRIOV_PF(xe))
+ xe_pci_sriov_configure(pdev, 0);
+
xe_device_remove(xe);
xe_pm_runtime_fini(xe);
pci_set_drvdata(pdev, NULL);
@@ -757,7 +811,9 @@ static int xe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
return err;
- xe_display_probe(xe);
+ err = xe_display_probe(xe);
+ if (err)
+ return err;
drm_dbg(&xe->drm, "%s %s %04x:%04x dgfx:%d gfx:%s (%d.%02d) media:%s (%d.%02d) display:%s dma_m_s:%d tc:%d gscfi:%d",
desc->platform_name,
@@ -951,6 +1007,7 @@ static struct pci_driver xe_pci_driver = {
.probe = xe_pci_probe,
.remove = xe_pci_remove,
.shutdown = xe_pci_shutdown,
+ .sriov_configure = xe_pci_sriov_configure,
#ifdef CONFIG_PM_SLEEP
.driver.pm = &xe_pm_ops,
#endif