diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_step.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_step.c | 70 | 
1 files changed, 69 insertions, 1 deletions
| diff --git a/drivers/gpu/drm/i915/intel_step.c b/drivers/gpu/drm/i915/intel_step.c index 74e8e4680028..42b3133d8387 100644 --- a/drivers/gpu/drm/i915/intel_step.c +++ b/drivers/gpu/drm/i915/intel_step.c @@ -135,6 +135,8 @@ static const struct intel_step_info adlp_n_revids[] = {  	[0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_D0 },  }; +static void pvc_step_init(struct drm_i915_private *i915, int pci_revid); +  void intel_step_init(struct drm_i915_private *i915)  {  	const struct intel_step_info *revids = NULL; @@ -142,7 +144,10 @@ void intel_step_init(struct drm_i915_private *i915)  	int revid = INTEL_REVID(i915);  	struct intel_step_info step = {}; -	if (IS_DG2_G10(i915)) { +	if (IS_PONTEVECCHIO(i915)) { +		pvc_step_init(i915, revid); +		return; +	} else if (IS_DG2_G10(i915)) {  		revids = dg2_g10_revid_step_tbl;  		size = ARRAY_SIZE(dg2_g10_revid_step_tbl);  	} else if (IS_DG2_G11(i915)) { @@ -235,6 +240,69 @@ void intel_step_init(struct drm_i915_private *i915)  	RUNTIME_INFO(i915)->step = step;  } +#define PVC_BD_REVID	GENMASK(5, 3) +#define PVC_CT_REVID	GENMASK(2, 0) + +static const int pvc_bd_subids[] = { +	[0x0] = STEP_A0, +	[0x3] = STEP_B0, +	[0x4] = STEP_B1, +	[0x5] = STEP_B3, +}; + +static const int pvc_ct_subids[] = { +	[0x3] = STEP_A0, +	[0x5] = STEP_B0, +	[0x6] = STEP_B1, +	[0x7] = STEP_C0, +}; + +static int +pvc_step_lookup(struct drm_i915_private *i915, const char *type, +		const int *table, int size, int subid) +{ +	if (subid < size && table[subid] != STEP_NONE) +		return table[subid]; + +	drm_warn(&i915->drm, "Unknown %s id 0x%02x\n", type, subid); + +	/* +	 * As on other platforms, try to use the next higher ID if we land on a +	 * gap in the table. +	 */ +	while (subid < size && table[subid] == STEP_NONE) +		subid++; + +	if (subid < size) { +		drm_dbg(&i915->drm, "Using steppings for %s id 0x%02x\n", +			type, subid); +		return table[subid]; +	} + +	drm_dbg(&i915->drm, "Using future steppings\n"); +	return STEP_FUTURE; +} + +/* + * PVC needs special handling since we don't lookup the + * revid in a table, but rather specific bitfields within + * the revid for various components. + */ +static void pvc_step_init(struct drm_i915_private *i915, int pci_revid) +{ +	int ct_subid, bd_subid; + +	bd_subid = FIELD_GET(PVC_BD_REVID, pci_revid); +	ct_subid = FIELD_GET(PVC_CT_REVID, pci_revid); + +	RUNTIME_INFO(i915)->step.basedie_step = +		pvc_step_lookup(i915, "Base Die", pvc_bd_subids, +				ARRAY_SIZE(pvc_bd_subids), bd_subid); +	RUNTIME_INFO(i915)->step.graphics_step = +		pvc_step_lookup(i915, "Compute Tile", pvc_ct_subids, +				ARRAY_SIZE(pvc_ct_subids), ct_subid); +} +  #define STEP_NAME_CASE(name)	\  	case STEP_##name:	\  		return #name; | 
