mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 13:59:45 -04:00
drm/xe/xe_guc_ads: Consolidate guc_waklv_enable functions
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>
This commit is contained in:
committed by
Lucas De Marchi
parent
bcddb12c02
commit
7c9de25efa
@@ -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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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_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);
|
||||
|
||||
if (xe_gt_WARN(ads_to_gt(ads), *remain < size,
|
||||
"w/a klv buffer too small to add klv id %d\n", klv_id))
|
||||
"w/a klv buffer too small to add klv id 0x%04X\n", klv_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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));
|
||||
|
||||
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(>->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, NULL, 0, &offset, &remain,
|
||||
GUC_WA_KLV_RESET_BB_STACK_PTR_ON_VF_SWITCH);
|
||||
if (GUC_FIRMWARE_VER(>->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)
|
||||
|
||||
Reference in New Issue
Block a user