[PATCH] drm/xe/xe_guc_ads: Consolidate guc_waklv_enable functions
Lin, Shuicheng
shuicheng.lin at intel.com
Thu Jul 24 22:41:51 UTC 2025
On Thurs, July 24, 2025 3:19 PM Jonathan Cavitt wrote:
> 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.
>
> Suggested-by: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
> Signed-off-by: Jonathan Cavitt <jonathan.cavitt at intel.com>
> Cc: Lucas De Marchi <lucas.demarch at intel.com>
> ---
> drivers/gpu/drm/xe/xe_guc_ads.c | 144 ++++++++++++--------------------
> 1 file changed, 54 insertions(+), 90 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_guc_ads.c
> b/drivers/gpu/drm/xe/xe_guc_ads.c index 8ff8626227ae..793a3054c562
> 100644
> --- a/drivers/gpu/drm/xe/xe_guc_ads.c
> +++ b/drivers/gpu/drm/xe/xe_guc_ads.c
> @@ -284,83 +284,41 @@ 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,
> + enum xe_guc_klv_ids klv_id,
> + u32 dwords[], u32 num_dwords,
> + 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, 2),
> - value1,
> - value2,
> - /* 2 dword data */
> - };
> -
> - size = sizeof(klv_entry);
> + size_t size = sizeof(u32) * (1 + num_dwords);
> + u32 *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;
> + return;
> }
> -}
> -
> -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);
>
> - if (*remain < size) {
> + klv_entry = kzalloc(size, GFP_KERNEL);
> + if (!klv_entry) {
> 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 for klv id %d not allocated!\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;
> + /* 16:16 key/length */
> + klv_entry[0] = FIELD_PREP(GUC_KLV_0_KEY, klv_id) |
> + FIELD_PREP(GUC_KLV_0_LEN, 0);
This seems to be not correct? The length info is missed.
Should be:
FIELD_PREP(GUC_KLV_0_LEN, num_dwords) ?
Shuicheng
>
> - size = sizeof(klv_entry);
> -
> - 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;
> + /* add dwords of data */
> + for (int i = 1; i <= num_dwords; i++)
> + klv_entry[i] = dwords[i];
>
> xe_map_memcpy_to(ads_to_xe(ads), ads_to_map(ads), *offset,
> klv_entry, size);
> *offset += size;
> *remain -= size;
> +
> + kfree(klv_entry);
> }
>
> static void guc_waklv_init(struct xe_guc_ads *ads) @@ -373,49 +331,55 @@
> 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_BLOC
> KED,
> - &offset, &remain);
> + guc_waklv_enable(ads,
> +
> GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED,
> + NULL, 0, &offset, &remain);
> 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,
> +
> GUC_WORKAROUND_KLV_ID_GAM_PFQ_SHADOW_TAIL_POLLING,
> + NULL, 0, &offset, &remain);
> if (XE_WA(gt, 16022287689))
> - guc_waklv_enable_simple(ads,
> -
> GUC_WORKAROUND_KLV_ID_DISABLE_MTP_DURING_ASYNC_COMP
> UTE,
> - &offset, &remain);
> + guc_waklv_enable(ads,
> +
> GUC_WORKAROUND_KLV_ID_DISABLE_MTP_DURING_ASYNC_COMPUTE,
> + NULL, 0, &offset, &remain);
>
> 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,
> +
> GUC_WA_KLV_WAKE_POWER_DOMAINS_FOR_OUTBOUND_MMIO,
> + NULL, 0, &offset, &remain);
>
> /*
> * 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 arr[] = {
> + 0xC40,
> + };
> + guc_waklv_enable(ads,
> +
> GUC_WA_KLV_NP_RD_WRITE_TO_CLEAR_RCSM_AT_CGP_LATE_RESTORE,
> + arr, 1, &offset, &remain);
> + }
>
> 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,
> +
> GUC_WORKAROUND_KLV_ID_BACK_TO_BACK_RCS_ENGINE_RESET,
> + NULL, 0, &offset, &remain);
>
> if (GUC_FIRMWARE_VER(>->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(>->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,
> +
> GUC_WA_KLV_RESET_BB_STACK_PTR_ON_VF_SWITCH,
> + NULL, 0, &offset, &remain);
> + if (GUC_FIRMWARE_VER(>->uc.guc) >= MAKE_GUC_VER(70, 47, 0)
> && XE_WA(gt, 16026007364)) {
> + u32 arr[] = {
> + 0x0,
> + 0xF,
> + };
> + guc_waklv_enable(ads,
> +
> GUC_WA_KLV_RESTORE_UNSAVED_MEDIA_CONTROL_REG,
> + arr, 2, &offset, &remain);
> + }
>
> size = guc_ads_waklv_size(ads) - remain;
> if (!size)
> --
> 2.43.0
More information about the Intel-xe
mailing list