]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/xe3p_lpm: Configure MAIN_GAMCTRL_QUEUE_SELECT
authorBrian Welty <brian.welty@intel.com>
Mon, 20 Oct 2025 02:05:46 +0000 (19:05 -0700)
committerLucas De Marchi <lucas.demarchi@intel.com>
Tue, 21 Oct 2025 00:21:11 +0000 (17:21 -0700)
Starting from Xe3p, there are two different copies of some of the GAM
registers:  the traditional MCR variant at their old locations, and a
new unicast copy known as "main_gamctrl."  The Xe driver doesn't use
these registers directly, but we need to instruct the GuC on which set
it should use.  Since the new, unicast registers are preferred (since
they avoid the need for unnecessary MCR synchronization), set a new GuC
feature flag, GUC_CTL_MAIN_GAMCTRL_QUEUES to convey this decision.  A
new helper function, xe_guc_using_main_gamctrl_queues(), is added for
use in the 3 independent places that need to handle configuration of the
new reporting queues.

The mmio write to enable the main gamctl is only done during the general
GuC upload.  The gamctrl registers are not accessed by the GuC during
hwconfig load.

Last, the ADS blob for communicating the queue addresses contains both a
DPA and GGTT offset. The GuC documentation states that DPA is now MBZ
when using the MAIN_GAMCTRL queues.

Bspec: 76445, 73540
Signed-off-by: Brian Welty <brian.welty@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://lore.kernel.org/r/20251019-xe3p-gamctrl-v1-1-ad66d3c1908f@intel.com
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
drivers/gpu/drm/xe/regs/xe_gt_regs.h
drivers/gpu/drm/xe/xe_guc.c
drivers/gpu/drm/xe/xe_guc.h
drivers/gpu/drm/xe/xe_guc_ads.c
drivers/gpu/drm/xe/xe_guc_fwif.h

index 228de47c0f3f58f0bbf70649c273dbb56382d996..1876f2957c6df3f9e38fccd6501792c349dbca57 100644 (file)
 #define SARB_CHICKEN1                          XE_REG_MCR(0xe90c)
 #define   COMP_CKN_IN                          REG_GENMASK(30, 29)
 
+#define MAIN_GAMCTRL_MODE                      XE_REG(0xef00)
+#define   MAIN_GAMCTRL_QUEUE_SELECT            REG_BIT(0)
+
 #define RCU_MODE                               XE_REG(0x14800, XE_REG_OPTION_MASKED)
 #define   RCU_MODE_FIXED_SLICE_CCS_MODE                REG_BIT(1)
 #define   RCU_MODE_CCS_ENABLE                  REG_BIT(0)
index d94490979adc007db3a668eca7b2c4a16dfe7d59..37e3735f34e632e95eb6187ebedc360ece01d7a1 100644 (file)
@@ -91,6 +91,9 @@ static u32 guc_ctl_feature_flags(struct xe_guc *guc)
        if (xe_configfs_get_psmi_enabled(to_pci_dev(xe->drm.dev)))
                flags |= GUC_CTL_ENABLE_PSMI_LOGGING;
 
+       if (xe_guc_using_main_gamctrl_queues(guc))
+               flags |= GUC_CTL_MAIN_GAMCTRL_QUEUES;
+
        return flags;
 }
 
@@ -1255,8 +1258,13 @@ int xe_guc_min_load_for_hwconfig(struct xe_guc *guc)
 
 int xe_guc_upload(struct xe_guc *guc)
 {
+       struct xe_gt *gt = guc_to_gt(guc);
+
        xe_guc_ads_populate(&guc->ads);
 
+       if (xe_guc_using_main_gamctrl_queues(guc))
+               xe_mmio_write32(&gt->mmio, MAIN_GAMCTRL_MODE, MAIN_GAMCTRL_QUEUE_SELECT);
+
        return __xe_guc_upload(guc);
 }
 
@@ -1657,6 +1665,25 @@ void xe_guc_declare_wedged(struct xe_guc *guc)
        xe_guc_submit_wedge(guc);
 }
 
+/**
+ * xe_guc_using_main_gamctrl_queues() - Detect which reporting queues to use.
+ * @guc: The GuC object
+ *
+ * For Xe3p and beyond, we want to program the hardware to use the
+ * "Main GAMCTRL queue" rather than the legacy queue before we upload
+ * the GuC firmware.  This will allow the GuC to use a new set of
+ * registers for pagefault handling and avoid some unnecessary
+ * complications with MCR register range handling.
+ *
+ * Return: true if can use new main gamctrl queues.
+ */
+bool xe_guc_using_main_gamctrl_queues(struct xe_guc *guc)
+{
+       struct xe_gt *gt = guc_to_gt(guc);
+
+       return GT_VER(gt) >= 35;
+}
+
 #if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
 #include "tests/xe_guc_g2g_test.c"
 #endif
index 1cca05967e621c9fee54ce6d7769fdfe62a3719e..e2d4c5f44ae34d4940d3a5f57fcff55db4665efe 100644 (file)
@@ -52,6 +52,7 @@ void xe_guc_stop_prepare(struct xe_guc *guc);
 void xe_guc_stop(struct xe_guc *guc);
 int xe_guc_start(struct xe_guc *guc);
 void xe_guc_declare_wedged(struct xe_guc *guc);
+bool xe_guc_using_main_gamctrl_queues(struct xe_guc *guc);
 
 #if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
 int xe_guc_g2g_test_notification(struct xe_guc *guc, u32 *payload, u32 len);
index 22ac2a8b74c80390be88bcd7684889998ffd19b8..bcb85a1bf26d950f4e4b96b5d32b8f6d76cbb784 100644 (file)
@@ -820,16 +820,20 @@ static void guc_mmio_reg_state_init(struct xe_guc_ads *ads)
 static void guc_um_init_params(struct xe_guc_ads *ads)
 {
        u32 um_queue_offset = guc_ads_um_queues_offset(ads);
+       struct xe_guc *guc = ads_to_guc(ads);
        u64 base_dpa;
        u32 base_ggtt;
+       bool with_dpa;
        int i;
 
+       with_dpa = !xe_guc_using_main_gamctrl_queues(guc);
+
        base_ggtt = xe_bo_ggtt_addr(ads->bo) + um_queue_offset;
        base_dpa = xe_bo_main_addr(ads->bo, PAGE_SIZE) + um_queue_offset;
 
        for (i = 0; i < GUC_UM_HW_QUEUE_MAX; ++i) {
                ads_blob_write(ads, um_init_params.queue_params[i].base_dpa,
-                              base_dpa + (i * GUC_UM_QUEUE_SIZE));
+                              with_dpa ? (base_dpa + (i * GUC_UM_QUEUE_SIZE)) : 0);
                ads_blob_write(ads, um_init_params.queue_params[i].base_ggtt_address,
                               base_ggtt + (i * GUC_UM_QUEUE_SIZE));
                ads_blob_write(ads, um_init_params.queue_params[i].size_in_bytes,
index 50c4c2406132e3c8dd404acc8dc0f11dee5a4dad..c90dd266e9cf90c73ac962ca4153b0aefba87362 100644 (file)
@@ -113,6 +113,7 @@ struct guc_update_exec_queue_policy {
 #define   GUC_CTL_ENABLE_SLPC          BIT(2)
 #define   GUC_CTL_ENABLE_LITE_RESTORE  BIT(4)
 #define   GUC_CTL_ENABLE_PSMI_LOGGING  BIT(7)
+#define   GUC_CTL_MAIN_GAMCTRL_QUEUES  BIT(9)
 #define   GUC_CTL_DISABLE_SCHEDULER    BIT(14)
 
 #define GUC_CTL_DEBUG                  3