diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 699292eae02e..bac3e926583a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2554,6 +2554,14 @@ enum i915_power_well_id { #define GEN11_GT_VEBOX_DISABLE_SHIFT 16 #define GEN11_GT_VEBOX_DISABLE_MASK (0xff << GEN11_GT_VEBOX_DISABLE_SHIFT) +#define GEN11_EU_DISABLE _MMIO(0x9134) +#define GEN11_EU_DIS_MASK 0xFF + +#define GEN11_GT_SLICE_ENABLE _MMIO(0x9138) +#define GEN11_GT_S_ENA_MASK 0xFF + +#define GEN11_GT_SUBSLICE_DISABLE _MMIO(0x913C) + #define GEN6_BSD_SLEEP_PSMI_CONTROL _MMIO(0x12050) #define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0) #define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2) diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 4babfc6ee45b..a504281e2afa 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -158,6 +158,45 @@ static u16 compute_eu_total(const struct sseu_dev_info *sseu) return total; } +static void gen11_sseu_info_init(struct drm_i915_private *dev_priv) +{ + struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu; + u8 s_en; + u32 ss_en, ss_en_mask; + u8 eu_en; + int s; + + sseu->max_slices = 1; + sseu->max_subslices = 8; + sseu->max_eus_per_subslice = 8; + + s_en = I915_READ(GEN11_GT_SLICE_ENABLE) & GEN11_GT_S_ENA_MASK; + ss_en = ~I915_READ(GEN11_GT_SUBSLICE_DISABLE); + ss_en_mask = BIT(sseu->max_subslices) - 1; + eu_en = ~(I915_READ(GEN11_EU_DISABLE) & GEN11_EU_DIS_MASK); + + for (s = 0; s < sseu->max_slices; s++) { + if (s_en & BIT(s)) { + int ss_idx = sseu->max_subslices * s; + int ss; + + sseu->slice_mask |= BIT(s); + sseu->subslice_mask[s] = (ss_en >> ss_idx) & ss_en_mask; + for (ss = 0; ss < sseu->max_subslices; ss++) { + if (sseu->subslice_mask[s] & BIT(ss)) + sseu_set_eus(sseu, s, ss, eu_en); + } + } + } + sseu->eu_per_subslice = hweight8(eu_en); + sseu->eu_total = compute_eu_total(sseu); + + /* ICL has no power gating restrictions. */ + sseu->has_slice_pg = 1; + sseu->has_subslice_pg = 1; + sseu->has_eu_pg = 1; +} + static void gen10_sseu_info_init(struct drm_i915_private *dev_priv) { struct sseu_dev_info *sseu = &mkwrite_device_info(dev_priv)->sseu; @@ -768,8 +807,10 @@ void intel_device_info_runtime_init(struct intel_device_info *info) broadwell_sseu_info_init(dev_priv); else if (INTEL_GEN(dev_priv) == 9) gen9_sseu_info_init(dev_priv); - else if (INTEL_GEN(dev_priv) >= 10) + else if (INTEL_GEN(dev_priv) == 10) gen10_sseu_info_init(dev_priv); + else if (INTEL_INFO(dev_priv)->gen >= 11) + gen11_sseu_info_init(dev_priv); /* Initialize command stream timestamp frequency */ info->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 0cbb92223013..933e31669557 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -114,7 +114,7 @@ enum intel_platform { func(has_ipc); #define GEN_MAX_SLICES (6) /* CNL upper bound */ -#define GEN_MAX_SUBSLICES (7) +#define GEN_MAX_SUBSLICES (8) /* ICL upper bound */ struct sseu_dev_info { u8 slice_mask;