]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/xe/xe_guc_ads: Consolidate guc_waklv_enable functions
authorJonathan Cavitt <jonathan.cavitt@intel.com>
Mon, 28 Jul 2025 19:48:06 +0000 (19:48 +0000)
committerLucas De Marchi <lucas.demarchi@intel.com>
Tue, 5 Aug 2025 14:59:38 +0000 (07:59 -0700)
Presently, multiple versions of the guc_waklv_enable_.* function exist,
all with different numbers of dwords added to the klv_entry array.  This
is not extensible, and more duplicates of the function will need to be
created if it ever becomes necessary to support 3 or more dwords per wa
in the future.

Consolidate the disparate guc_waklv_enable functions into a single
guc_waklv_enable function that can take an arbitrary number of dword
values.

v2:
- Update length value properly (Shuicheng)

v3: (Harrison)
- Use data as a term instead of dwords or arr
- Reformat warning message to use hex values
- Eliminate need for kzalloc and klv_entry array
- Reorder function parameters to fix line wrapping

v4:
- Miscellaneous formatting fixes (Cavitt)

v5: (Harrison)
- s/data_range/data_len_dw
- Use data_len_dw to calculate size for xe_map_memcpy_to

Suggested-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Cc: Lucas De Marchi <lucas.demarch@intel.com>
Cc: Shuicheng Lin <shuicheng.lin@intel.com>
Cc: John Harrison <john.c.harrison@intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
Link: https://lore.kernel.org/r/20250728194806.68176-2-jonathan.cavitt@intel.com
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
drivers/gpu/drm/xe/xe_guc_ads.c

index 8ff8626227ae4328cb1433268d9b64344829c6c0..2ceaa197cb2f080996478eb9e56cd477fa70f947 100644 (file)
@@ -284,81 +284,26 @@ static size_t calculate_golden_lrc_size(struct xe_guc_ads *ads)
        return total_size;
 }
 
-static void guc_waklv_enable_two_word(struct xe_guc_ads *ads,
-                                     enum xe_guc_klv_ids klv_id,
-                                     u32 value1,
-                                     u32 value2,
-                                     u32 *offset, u32 *remain)
+static void guc_waklv_enable(struct xe_guc_ads *ads,
+                            u32 data[], u32 data_len_dw,
+                            u32 *offset, u32 *remain,
+                            enum xe_guc_klv_ids klv_id)
 {
-       u32 size;
-       u32 klv_entry[] = {
-                       /* 16:16 key/length */
-                       FIELD_PREP(GUC_KLV_0_KEY, klv_id) |
-                       FIELD_PREP(GUC_KLV_0_LEN, 2),
-                       value1,
-                       value2,
-                       /* 2 dword data */
-       };
-
-       size = sizeof(klv_entry);
-
-       if (*remain < size) {
-               drm_warn(&ads_to_xe(ads)->drm,
-                        "w/a klv buffer too small to add klv id %d\n", klv_id);
-       } else {
-               xe_map_memcpy_to(ads_to_xe(ads), ads_to_map(ads), *offset,
-                                klv_entry, size);
-               *offset += size;
-               *remain -= size;
-       }
-}
-
-static void guc_waklv_enable_one_word(struct xe_guc_ads *ads,
-                                     enum xe_guc_klv_ids klv_id,
-                                     u32 value,
-                                     u32 *offset, u32 *remain)
-{
-       u32 size;
-       u32 klv_entry[] = {
-               /* 16:16 key/length */
-               FIELD_PREP(GUC_KLV_0_KEY, klv_id) |
-               FIELD_PREP(GUC_KLV_0_LEN, 1),
-               value,
-               /* 1 dword data */
-       };
-
-       size = sizeof(klv_entry);
+       size_t size = sizeof(u32) * (1 + data_len_dw);
 
        if (*remain < size) {
                drm_warn(&ads_to_xe(ads)->drm,
-                        "w/a klv buffer too small to add klv id %d\n", klv_id);
-       } else {
-               xe_map_memcpy_to(ads_to_xe(ads), ads_to_map(ads), *offset,
-                                klv_entry, size);
-               *offset += size;
-               *remain -= size;
+                        "w/a klv buffer too small to add klv id 0x%04X\n", klv_id);
+               return;
        }
-}
-
-static void guc_waklv_enable_simple(struct xe_guc_ads *ads,
-                                   enum xe_guc_klv_ids klv_id, u32 *offset, u32 *remain)
-{
-       u32 klv_entry[] = {
-               /* 16:16 key/length */
-               FIELD_PREP(GUC_KLV_0_KEY, klv_id) |
-               FIELD_PREP(GUC_KLV_0_LEN, 0),
-               /* 0 dwords data */
-       };
-       u32 size;
 
-       size = sizeof(klv_entry);
+       /* 16:16 key/length */
+       xe_map_wr(ads_to_xe(ads), ads_to_map(ads), *offset, u32,
+                 FIELD_PREP(GUC_KLV_0_KEY, klv_id) | FIELD_PREP(GUC_KLV_0_LEN, data_len_dw));
+       /* data_len_dw dwords of data */
+       xe_map_memcpy_to(ads_to_xe(ads), ads_to_map(ads),
+                        *offset + sizeof(u32), data, data_len_dw * sizeof(u32));
 
-       if (xe_gt_WARN(ads_to_gt(ads), *remain < size,
-                      "w/a klv buffer too small to add klv id %d\n", klv_id))
-               return;
-
-       xe_map_memcpy_to(ads_to_xe(ads), ads_to_map(ads), *offset,
-                        klv_entry, size);
        *offset += size;
        *remain -= size;
 }
@@ -373,49 +318,46 @@ static void guc_waklv_init(struct xe_guc_ads *ads)
        remain = guc_ads_waklv_size(ads);
 
        if (XE_WA(gt, 14019882105) || XE_WA(gt, 16021333562))
-               guc_waklv_enable_simple(ads,
-                                       GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED,
-                                       &offset, &remain);
+               guc_waklv_enable(ads, NULL, 0, &offset, &remain,
+                                GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED);
        if (XE_WA(gt, 18024947630))
-               guc_waklv_enable_simple(ads,
-                                       GUC_WORKAROUND_KLV_ID_GAM_PFQ_SHADOW_TAIL_POLLING,
-                                       &offset, &remain);
+               guc_waklv_enable(ads, NULL, 0, &offset, &remain,
+                                GUC_WORKAROUND_KLV_ID_GAM_PFQ_SHADOW_TAIL_POLLING);
        if (XE_WA(gt, 16022287689))
-               guc_waklv_enable_simple(ads,
-                                       GUC_WORKAROUND_KLV_ID_DISABLE_MTP_DURING_ASYNC_COMPUTE,
-                                       &offset, &remain);
+               guc_waklv_enable(ads, NULL, 0, &offset, &remain,
+                                GUC_WORKAROUND_KLV_ID_DISABLE_MTP_DURING_ASYNC_COMPUTE);
 
        if (XE_WA(gt, 14022866841))
-               guc_waklv_enable_simple(ads,
-                                       GUC_WA_KLV_WAKE_POWER_DOMAINS_FOR_OUTBOUND_MMIO,
-                                       &offset, &remain);
+               guc_waklv_enable(ads, NULL, 0, &offset, &remain,
+                                GUC_WA_KLV_WAKE_POWER_DOMAINS_FOR_OUTBOUND_MMIO);
 
        /*
         * On RC6 exit, GuC will write register 0xB04 with the default value provided. As of now,
         * the default value for this register is determined to be 0xC40. This could change in the
         * future, so GuC depends on KMD to send it the correct value.
         */
-       if (XE_WA(gt, 13011645652))
-               guc_waklv_enable_one_word(ads,
-                                         GUC_WA_KLV_NP_RD_WRITE_TO_CLEAR_RCSM_AT_CGP_LATE_RESTORE,
-                                         0xC40,
-                                         &offset, &remain);
+       if (XE_WA(gt, 13011645652)) {
+               u32 data = 0xC40;
+
+               guc_waklv_enable(ads, &data, sizeof(data) / sizeof(u32), &offset, &remain,
+                                GUC_WA_KLV_NP_RD_WRITE_TO_CLEAR_RCSM_AT_CGP_LATE_RESTORE);
+       }
 
        if (XE_WA(gt, 14022293748) || XE_WA(gt, 22019794406))
-               guc_waklv_enable_simple(ads,
-                                       GUC_WORKAROUND_KLV_ID_BACK_TO_BACK_RCS_ENGINE_RESET,
-                                       &offset, &remain);
+               guc_waklv_enable(ads, NULL, 0, &offset, &remain,
+                                GUC_WORKAROUND_KLV_ID_BACK_TO_BACK_RCS_ENGINE_RESET);
 
        if (GUC_FIRMWARE_VER(&gt->uc.guc) >= MAKE_GUC_VER(70, 44, 0) && XE_WA(gt, 16026508708))
-               guc_waklv_enable_simple(ads,
-                                       GUC_WA_KLV_RESET_BB_STACK_PTR_ON_VF_SWITCH,
-                                       &offset, &remain);
-       if (GUC_FIRMWARE_VER(&gt->uc.guc) >= MAKE_GUC_VER(70, 47, 0) && XE_WA(gt, 16026007364))
-               guc_waklv_enable_two_word(ads,
-                                         GUC_WA_KLV_RESTORE_UNSAVED_MEDIA_CONTROL_REG,
-                                         0x0,
-                                         0xF,
-                                         &offset, &remain);
+               guc_waklv_enable(ads, NULL, 0, &offset, &remain,
+                                GUC_WA_KLV_RESET_BB_STACK_PTR_ON_VF_SWITCH);
+       if (GUC_FIRMWARE_VER(&gt->uc.guc) >= MAKE_GUC_VER(70, 47, 0) && XE_WA(gt, 16026007364)) {
+               u32 data[] = {
+                       0x0,
+                       0xF,
+               };
+               guc_waklv_enable(ads, data, sizeof(data) / sizeof(u32), &offset, &remain,
+                                GUC_WA_KLV_RESTORE_UNSAVED_MEDIA_CONTROL_REG);
+       }
 
        size = guc_ads_waklv_size(ads) - remain;
        if (!size)