]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/xe/vf: Use register values obtained from the PF
authorMichal Wajdeczko <michal.wajdeczko@intel.com>
Thu, 23 May 2024 19:22:35 +0000 (21:22 +0200)
committerMichal Wajdeczko <michal.wajdeczko@intel.com>
Fri, 24 May 2024 08:02:26 +0000 (10:02 +0200)
As part of the its initialization, the VF driver has already
obtained a list of the runtime (fuse) register values from the
PF driver. When VF driver is attempting to read register that is
inaccessible to the VF, use the values from this list instead.

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240523192240.844-2-michal.wajdeczko@intel.com
drivers/gpu/drm/xe/xe_gt_sriov_vf.c
drivers/gpu/drm/xe/xe_gt_sriov_vf.h
drivers/gpu/drm/xe/xe_mmio.c

index bab3858b423ebcd86f21f89c0726519cc544ef44..237486a80fb5e1bf02d90914ff1d6da6a1e80a8e 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/bsearch.h>
 
 #include <drm/drm_managed.h>
 #include <drm/drm_print.h>
@@ -21,6 +22,7 @@
 #include "xe_guc.h"
 #include "xe_guc_hxg_helpers.h"
 #include "xe_guc_relay.h"
+#include "xe_mmio.h"
 #include "xe_sriov.h"
 
 #define make_u64_from_u32(hi, lo) ((u64)((u64)(u32)(hi) << 32 | (u32)(lo)))
@@ -677,6 +679,57 @@ failed:
        return err;
 }
 
+static int vf_runtime_reg_cmp(const void *a, const void *b)
+{
+       const struct vf_runtime_reg *ra = a;
+       const struct vf_runtime_reg *rb = b;
+
+       return (int)ra->offset - (int)rb->offset;
+}
+
+static struct vf_runtime_reg *vf_lookup_reg(struct xe_gt *gt, u32 addr)
+{
+       struct xe_gt_sriov_vf_runtime *runtime = &gt->sriov.vf.runtime;
+       struct vf_runtime_reg key = { .offset = addr };
+
+       xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
+
+       return bsearch(&key, runtime->regs, runtime->regs_size, sizeof(key),
+                      vf_runtime_reg_cmp);
+}
+
+/**
+ * xe_gt_sriov_vf_read32 - Get a register value from the runtime data.
+ * @gt: the &xe_gt
+ * @reg: the register to read
+ *
+ * This function is for VF use only.
+ * This function shall be called after VF has connected to PF.
+ * This function is dedicated for registers that VFs can't read directly.
+ *
+ * Return: register value obtained from the PF or 0 if not found.
+ */
+u32 xe_gt_sriov_vf_read32(struct xe_gt *gt, struct xe_reg reg)
+{
+       u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
+       struct vf_runtime_reg *rr;
+
+       xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
+       xe_gt_assert(gt, gt->sriov.vf.pf_version.major);
+       xe_gt_assert(gt, !reg.vf);
+
+       rr = vf_lookup_reg(gt, addr);
+       if (!rr) {
+               xe_gt_WARN(gt, IS_ENABLED(CONFIG_DRM_XE_DEBUG),
+                          "VF is trying to read an inaccessible register %#x+%#x\n",
+                          reg.addr, addr - reg.addr);
+               return 0;
+       }
+
+       xe_gt_sriov_dbg_verbose(gt, "runtime[%#x] = %#x\n", addr, rr->value);
+       return rr->value;
+}
+
 /**
  * xe_gt_sriov_vf_print_config - Print VF self config.
  * @gt: the &xe_gt
index d6d37b193d17e2d2cb22c78408bf2ffa8e0b112b..be69c1025320ad1b5ee3cd6d186837d4b03d285f 100644 (file)
@@ -10,6 +10,7 @@
 
 struct drm_printer;
 struct xe_gt;
+struct xe_reg;
 
 int xe_gt_sriov_vf_bootstrap(struct xe_gt *gt);
 int xe_gt_sriov_vf_query_config(struct xe_gt *gt);
@@ -17,6 +18,7 @@ int xe_gt_sriov_vf_connect(struct xe_gt *gt);
 int xe_gt_sriov_vf_query_runtime(struct xe_gt *gt);
 
 u16 xe_gt_sriov_vf_guc_ids(struct xe_gt *gt);
+u32 xe_gt_sriov_vf_read32(struct xe_gt *gt, struct xe_reg reg);
 
 void xe_gt_sriov_vf_print_config(struct xe_gt *gt, struct drm_printer *p);
 void xe_gt_sriov_vf_print_runtime(struct xe_gt *gt, struct drm_printer *p);
index ff7a7cf995302beb9bd2f788772c168b962b614b..248e93ec6df7d5baa57bb04bb21b57d29df83dc1 100644 (file)
@@ -22,6 +22,7 @@
 #include "xe_gt.h"
 #include "xe_gt_mcr.h"
 #include "xe_gt_printk.h"
+#include "xe_gt_sriov_vf.h"
 #include "xe_macros.h"
 #include "xe_module.h"
 #include "xe_sriov.h"
@@ -479,6 +480,9 @@ u32 xe_mmio_read32(struct xe_gt *gt, struct xe_reg reg)
        struct xe_tile *tile = gt_to_tile(gt);
        u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
 
+       if (!reg.vf && IS_SRIOV_VF(gt_to_xe(gt)))
+               return xe_gt_sriov_vf_read32(gt, reg);
+
        return readl((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr);
 }