15ca02815Sjsg // SPDX-License-Identifier: MIT
25ca02815Sjsg /*
35ca02815Sjsg * Copyright © 2020,2021 Intel Corporation
45ca02815Sjsg */
55ca02815Sjsg
65ca02815Sjsg #include "i915_drv.h"
75ca02815Sjsg #include "intel_step.h"
85ca02815Sjsg
95ca02815Sjsg /*
105ca02815Sjsg * Some platforms have unusual ways of mapping PCI revision ID to GT/display
115ca02815Sjsg * steppings. E.g., in some cases a higher PCI revision may translate to a
125ca02815Sjsg * lower stepping of the GT and/or display IP. This file provides lookup
135ca02815Sjsg * tables to map the PCI revision into a standard set of stepping values that
145ca02815Sjsg * can be compared numerically.
155ca02815Sjsg *
165ca02815Sjsg * Also note that some revisions/steppings may have been set aside as
175ca02815Sjsg * placeholders but never materialized in real hardware; in those cases there
185ca02815Sjsg * may be jumps in the revision IDs or stepping values in the tables below.
195ca02815Sjsg */
205ca02815Sjsg
215ca02815Sjsg /*
225ca02815Sjsg * Some platforms always have the same stepping value for GT and display;
235ca02815Sjsg * use a macro to define these to make it easier to identify the platforms
245ca02815Sjsg * where the two steppings can deviate.
255ca02815Sjsg */
261bb76ff1Sjsg #define COMMON_STEP(x) .graphics_step = STEP_##x, .display_step = STEP_##x, .media_step = STEP_##x
271bb76ff1Sjsg #define COMMON_GT_MEDIA_STEP(x) .graphics_step = STEP_##x, .media_step = STEP_##x
285ca02815Sjsg
295ca02815Sjsg static const struct intel_step_info skl_revids[] = {
305ca02815Sjsg [0x6] = { COMMON_STEP(G0) },
315ca02815Sjsg [0x7] = { COMMON_STEP(H0) },
325ca02815Sjsg [0x9] = { COMMON_STEP(J0) },
335ca02815Sjsg [0xA] = { COMMON_STEP(I1) },
345ca02815Sjsg };
355ca02815Sjsg
365ca02815Sjsg static const struct intel_step_info kbl_revids[] = {
371bb76ff1Sjsg [1] = { COMMON_GT_MEDIA_STEP(B0), .display_step = STEP_B0 },
381bb76ff1Sjsg [2] = { COMMON_GT_MEDIA_STEP(C0), .display_step = STEP_B0 },
391bb76ff1Sjsg [3] = { COMMON_GT_MEDIA_STEP(D0), .display_step = STEP_B0 },
401bb76ff1Sjsg [4] = { COMMON_GT_MEDIA_STEP(F0), .display_step = STEP_C0 },
411bb76ff1Sjsg [5] = { COMMON_GT_MEDIA_STEP(C0), .display_step = STEP_B1 },
421bb76ff1Sjsg [6] = { COMMON_GT_MEDIA_STEP(D1), .display_step = STEP_B1 },
431bb76ff1Sjsg [7] = { COMMON_GT_MEDIA_STEP(G0), .display_step = STEP_C0 },
445ca02815Sjsg };
455ca02815Sjsg
465ca02815Sjsg static const struct intel_step_info bxt_revids[] = {
475ca02815Sjsg [0xA] = { COMMON_STEP(C0) },
485ca02815Sjsg [0xB] = { COMMON_STEP(C0) },
495ca02815Sjsg [0xC] = { COMMON_STEP(D0) },
505ca02815Sjsg [0xD] = { COMMON_STEP(E0) },
515ca02815Sjsg };
525ca02815Sjsg
535ca02815Sjsg static const struct intel_step_info glk_revids[] = {
545ca02815Sjsg [3] = { COMMON_STEP(B0) },
555ca02815Sjsg };
565ca02815Sjsg
575ca02815Sjsg static const struct intel_step_info icl_revids[] = {
585ca02815Sjsg [7] = { COMMON_STEP(D0) },
595ca02815Sjsg };
605ca02815Sjsg
615ca02815Sjsg static const struct intel_step_info jsl_ehl_revids[] = {
625ca02815Sjsg [0] = { COMMON_STEP(A0) },
635ca02815Sjsg [1] = { COMMON_STEP(B0) },
645ca02815Sjsg };
655ca02815Sjsg
665ca02815Sjsg static const struct intel_step_info tgl_uy_revids[] = {
671bb76ff1Sjsg [0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_A0 },
681bb76ff1Sjsg [1] = { COMMON_GT_MEDIA_STEP(B0), .display_step = STEP_C0 },
691bb76ff1Sjsg [2] = { COMMON_GT_MEDIA_STEP(B1), .display_step = STEP_C0 },
701bb76ff1Sjsg [3] = { COMMON_GT_MEDIA_STEP(C0), .display_step = STEP_D0 },
715ca02815Sjsg };
725ca02815Sjsg
735ca02815Sjsg /* Same GT stepping between tgl_uy_revids and tgl_revids don't mean the same HW */
745ca02815Sjsg static const struct intel_step_info tgl_revids[] = {
751bb76ff1Sjsg [0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_B0 },
761bb76ff1Sjsg [1] = { COMMON_GT_MEDIA_STEP(B0), .display_step = STEP_D0 },
775ca02815Sjsg };
785ca02815Sjsg
795ca02815Sjsg static const struct intel_step_info rkl_revids[] = {
805ca02815Sjsg [0] = { COMMON_STEP(A0) },
815ca02815Sjsg [1] = { COMMON_STEP(B0) },
825ca02815Sjsg [4] = { COMMON_STEP(C0) },
835ca02815Sjsg };
845ca02815Sjsg
855ca02815Sjsg static const struct intel_step_info dg1_revids[] = {
865ca02815Sjsg [0] = { COMMON_STEP(A0) },
875ca02815Sjsg [1] = { COMMON_STEP(B0) },
885ca02815Sjsg };
895ca02815Sjsg
905ca02815Sjsg static const struct intel_step_info adls_revids[] = {
911bb76ff1Sjsg [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_A0 },
921bb76ff1Sjsg [0x1] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_A2 },
931bb76ff1Sjsg [0x4] = { COMMON_GT_MEDIA_STEP(B0), .display_step = STEP_B0 },
941bb76ff1Sjsg [0x8] = { COMMON_GT_MEDIA_STEP(C0), .display_step = STEP_B0 },
951bb76ff1Sjsg [0xC] = { COMMON_GT_MEDIA_STEP(D0), .display_step = STEP_C0 },
965ca02815Sjsg };
975ca02815Sjsg
985ca02815Sjsg static const struct intel_step_info adlp_revids[] = {
991bb76ff1Sjsg [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_A0 },
1001bb76ff1Sjsg [0x4] = { COMMON_GT_MEDIA_STEP(B0), .display_step = STEP_B0 },
1011bb76ff1Sjsg [0x8] = { COMMON_GT_MEDIA_STEP(C0), .display_step = STEP_C0 },
1021bb76ff1Sjsg [0xC] = { COMMON_GT_MEDIA_STEP(C0), .display_step = STEP_D0 },
1035ca02815Sjsg };
1045ca02815Sjsg
1055ca02815Sjsg static const struct intel_step_info xehpsdv_revids[] = {
1061bb76ff1Sjsg [0x0] = { COMMON_GT_MEDIA_STEP(A0) },
1071bb76ff1Sjsg [0x1] = { COMMON_GT_MEDIA_STEP(A1) },
1081bb76ff1Sjsg [0x4] = { COMMON_GT_MEDIA_STEP(B0) },
1091bb76ff1Sjsg [0x8] = { COMMON_GT_MEDIA_STEP(C0) },
1105ca02815Sjsg };
1115ca02815Sjsg
1125ca02815Sjsg static const struct intel_step_info dg2_g10_revid_step_tbl[] = {
1131bb76ff1Sjsg [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_A0 },
1141bb76ff1Sjsg [0x1] = { COMMON_GT_MEDIA_STEP(A1), .display_step = STEP_A0 },
1151bb76ff1Sjsg [0x4] = { COMMON_GT_MEDIA_STEP(B0), .display_step = STEP_B0 },
1161bb76ff1Sjsg [0x8] = { COMMON_GT_MEDIA_STEP(C0), .display_step = STEP_C0 },
1175ca02815Sjsg };
1185ca02815Sjsg
1195ca02815Sjsg static const struct intel_step_info dg2_g11_revid_step_tbl[] = {
1201bb76ff1Sjsg [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_B0 },
1211bb76ff1Sjsg [0x4] = { COMMON_GT_MEDIA_STEP(B0), .display_step = STEP_C0 },
1221bb76ff1Sjsg [0x5] = { COMMON_GT_MEDIA_STEP(B1), .display_step = STEP_C0 },
1231bb76ff1Sjsg };
1241bb76ff1Sjsg
1251bb76ff1Sjsg static const struct intel_step_info dg2_g12_revid_step_tbl[] = {
1261bb76ff1Sjsg [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_C0 },
1275ca02815Sjsg };
1285ca02815Sjsg
1299345d605Sjsg static const struct intel_step_info adls_rpls_revids[] = {
1301bb76ff1Sjsg [0x4] = { COMMON_GT_MEDIA_STEP(D0), .display_step = STEP_D0 },
1311bb76ff1Sjsg [0xC] = { COMMON_GT_MEDIA_STEP(D0), .display_step = STEP_C0 },
1329345d605Sjsg };
1339345d605Sjsg
134*f005ef32Sjsg static const struct intel_step_info adlp_rplp_revids[] = {
135*f005ef32Sjsg [0x4] = { COMMON_GT_MEDIA_STEP(C0), .display_step = STEP_E0 },
136*f005ef32Sjsg };
137*f005ef32Sjsg
13827957781Sjsg static const struct intel_step_info adlp_n_revids[] = {
1391bb76ff1Sjsg [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_D0 },
14027957781Sjsg };
14127957781Sjsg
gmd_to_intel_step(struct drm_i915_private * i915,struct intel_ip_version * gmd)142*f005ef32Sjsg static u8 gmd_to_intel_step(struct drm_i915_private *i915,
143*f005ef32Sjsg struct intel_ip_version *gmd)
144*f005ef32Sjsg {
145*f005ef32Sjsg u8 step = gmd->step + STEP_A0;
146*f005ef32Sjsg
147*f005ef32Sjsg if (step >= STEP_FUTURE) {
148*f005ef32Sjsg drm_dbg(&i915->drm, "Using future steppings\n");
149*f005ef32Sjsg return STEP_FUTURE;
150*f005ef32Sjsg }
151*f005ef32Sjsg
152*f005ef32Sjsg return step;
153*f005ef32Sjsg }
154*f005ef32Sjsg
1551bb76ff1Sjsg static void pvc_step_init(struct drm_i915_private *i915, int pci_revid);
1561bb76ff1Sjsg
intel_step_init(struct drm_i915_private * i915)1575ca02815Sjsg void intel_step_init(struct drm_i915_private *i915)
1585ca02815Sjsg {
1595ca02815Sjsg const struct intel_step_info *revids = NULL;
1605ca02815Sjsg int size = 0;
1615ca02815Sjsg int revid = INTEL_REVID(i915);
1625ca02815Sjsg struct intel_step_info step = {};
1635ca02815Sjsg
164*f005ef32Sjsg if (HAS_GMD_ID(i915)) {
165*f005ef32Sjsg step.graphics_step = gmd_to_intel_step(i915,
166*f005ef32Sjsg &RUNTIME_INFO(i915)->graphics.ip);
167*f005ef32Sjsg step.media_step = gmd_to_intel_step(i915,
168*f005ef32Sjsg &RUNTIME_INFO(i915)->media.ip);
169*f005ef32Sjsg step.display_step = STEP_A0 + DISPLAY_RUNTIME_INFO(i915)->ip.step;
170*f005ef32Sjsg if (step.display_step >= STEP_FUTURE) {
171*f005ef32Sjsg drm_dbg(&i915->drm, "Using future display steppings\n");
172*f005ef32Sjsg step.display_step = STEP_FUTURE;
173*f005ef32Sjsg }
174*f005ef32Sjsg
175*f005ef32Sjsg RUNTIME_INFO(i915)->step = step;
176*f005ef32Sjsg
177*f005ef32Sjsg return;
178*f005ef32Sjsg }
179*f005ef32Sjsg
1801bb76ff1Sjsg if (IS_PONTEVECCHIO(i915)) {
1811bb76ff1Sjsg pvc_step_init(i915, revid);
1821bb76ff1Sjsg return;
1831bb76ff1Sjsg } else if (IS_DG2_G10(i915)) {
1845ca02815Sjsg revids = dg2_g10_revid_step_tbl;
1855ca02815Sjsg size = ARRAY_SIZE(dg2_g10_revid_step_tbl);
1865ca02815Sjsg } else if (IS_DG2_G11(i915)) {
1875ca02815Sjsg revids = dg2_g11_revid_step_tbl;
1885ca02815Sjsg size = ARRAY_SIZE(dg2_g11_revid_step_tbl);
1891bb76ff1Sjsg } else if (IS_DG2_G12(i915)) {
1901bb76ff1Sjsg revids = dg2_g12_revid_step_tbl;
1911bb76ff1Sjsg size = ARRAY_SIZE(dg2_g12_revid_step_tbl);
1925ca02815Sjsg } else if (IS_XEHPSDV(i915)) {
1935ca02815Sjsg revids = xehpsdv_revids;
1945ca02815Sjsg size = ARRAY_SIZE(xehpsdv_revids);
195*f005ef32Sjsg } else if (IS_ALDERLAKE_P_N(i915)) {
19627957781Sjsg revids = adlp_n_revids;
19727957781Sjsg size = ARRAY_SIZE(adlp_n_revids);
198*f005ef32Sjsg } else if (IS_RAPTORLAKE_P(i915)) {
199*f005ef32Sjsg revids = adlp_rplp_revids;
200*f005ef32Sjsg size = ARRAY_SIZE(adlp_rplp_revids);
2015ca02815Sjsg } else if (IS_ALDERLAKE_P(i915)) {
2025ca02815Sjsg revids = adlp_revids;
2035ca02815Sjsg size = ARRAY_SIZE(adlp_revids);
204*f005ef32Sjsg } else if (IS_RAPTORLAKE_S(i915)) {
2059345d605Sjsg revids = adls_rpls_revids;
2069345d605Sjsg size = ARRAY_SIZE(adls_rpls_revids);
2075ca02815Sjsg } else if (IS_ALDERLAKE_S(i915)) {
2085ca02815Sjsg revids = adls_revids;
2095ca02815Sjsg size = ARRAY_SIZE(adls_revids);
2105ca02815Sjsg } else if (IS_DG1(i915)) {
2115ca02815Sjsg revids = dg1_revids;
2125ca02815Sjsg size = ARRAY_SIZE(dg1_revids);
2135ca02815Sjsg } else if (IS_ROCKETLAKE(i915)) {
2145ca02815Sjsg revids = rkl_revids;
2155ca02815Sjsg size = ARRAY_SIZE(rkl_revids);
216*f005ef32Sjsg } else if (IS_TIGERLAKE_UY(i915)) {
2175ca02815Sjsg revids = tgl_uy_revids;
2185ca02815Sjsg size = ARRAY_SIZE(tgl_uy_revids);
2195ca02815Sjsg } else if (IS_TIGERLAKE(i915)) {
2205ca02815Sjsg revids = tgl_revids;
2215ca02815Sjsg size = ARRAY_SIZE(tgl_revids);
222*f005ef32Sjsg } else if (IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) {
2235ca02815Sjsg revids = jsl_ehl_revids;
2245ca02815Sjsg size = ARRAY_SIZE(jsl_ehl_revids);
2255ca02815Sjsg } else if (IS_ICELAKE(i915)) {
2265ca02815Sjsg revids = icl_revids;
2275ca02815Sjsg size = ARRAY_SIZE(icl_revids);
2285ca02815Sjsg } else if (IS_GEMINILAKE(i915)) {
2295ca02815Sjsg revids = glk_revids;
2305ca02815Sjsg size = ARRAY_SIZE(glk_revids);
2315ca02815Sjsg } else if (IS_BROXTON(i915)) {
2325ca02815Sjsg revids = bxt_revids;
2335ca02815Sjsg size = ARRAY_SIZE(bxt_revids);
2345ca02815Sjsg } else if (IS_KABYLAKE(i915)) {
2355ca02815Sjsg revids = kbl_revids;
2365ca02815Sjsg size = ARRAY_SIZE(kbl_revids);
2375ca02815Sjsg } else if (IS_SKYLAKE(i915)) {
2385ca02815Sjsg revids = skl_revids;
2395ca02815Sjsg size = ARRAY_SIZE(skl_revids);
2405ca02815Sjsg }
2415ca02815Sjsg
2425ca02815Sjsg /* Not using the stepping scheme for the platform yet. */
2435ca02815Sjsg if (!revids)
2445ca02815Sjsg return;
2455ca02815Sjsg
2461bb76ff1Sjsg if (revid < size && revids[revid].graphics_step != STEP_NONE) {
2475ca02815Sjsg step = revids[revid];
2485ca02815Sjsg } else {
2495ca02815Sjsg drm_warn(&i915->drm, "Unknown revid 0x%02x\n", revid);
2505ca02815Sjsg
2515ca02815Sjsg /*
2525ca02815Sjsg * If we hit a gap in the revid array, use the information for
2535ca02815Sjsg * the next revid.
2545ca02815Sjsg *
2555ca02815Sjsg * This may be wrong in all sorts of ways, especially if the
2565ca02815Sjsg * steppings in the array are not monotonically increasing, but
2575ca02815Sjsg * it's better than defaulting to 0.
2585ca02815Sjsg */
2591bb76ff1Sjsg while (revid < size && revids[revid].graphics_step == STEP_NONE)
2605ca02815Sjsg revid++;
2615ca02815Sjsg
2625ca02815Sjsg if (revid < size) {
2635ca02815Sjsg drm_dbg(&i915->drm, "Using steppings for revid 0x%02x\n",
2645ca02815Sjsg revid);
2655ca02815Sjsg step = revids[revid];
2665ca02815Sjsg } else {
2675ca02815Sjsg drm_dbg(&i915->drm, "Using future steppings\n");
2681bb76ff1Sjsg step.graphics_step = STEP_FUTURE;
2695ca02815Sjsg step.display_step = STEP_FUTURE;
2705ca02815Sjsg }
2715ca02815Sjsg }
2725ca02815Sjsg
2731bb76ff1Sjsg if (drm_WARN_ON(&i915->drm, step.graphics_step == STEP_NONE))
2745ca02815Sjsg return;
2755ca02815Sjsg
2765ca02815Sjsg RUNTIME_INFO(i915)->step = step;
2775ca02815Sjsg }
2785ca02815Sjsg
2791bb76ff1Sjsg #define PVC_BD_REVID GENMASK(5, 3)
2801bb76ff1Sjsg #define PVC_CT_REVID GENMASK(2, 0)
2811bb76ff1Sjsg
2821bb76ff1Sjsg static const int pvc_bd_subids[] = {
2831bb76ff1Sjsg [0x0] = STEP_A0,
2841bb76ff1Sjsg [0x3] = STEP_B0,
2851bb76ff1Sjsg [0x4] = STEP_B1,
2861bb76ff1Sjsg [0x5] = STEP_B3,
2871bb76ff1Sjsg };
2881bb76ff1Sjsg
2891bb76ff1Sjsg static const int pvc_ct_subids[] = {
2901bb76ff1Sjsg [0x3] = STEP_A0,
2911bb76ff1Sjsg [0x5] = STEP_B0,
2921bb76ff1Sjsg [0x6] = STEP_B1,
2931bb76ff1Sjsg [0x7] = STEP_C0,
2941bb76ff1Sjsg };
2951bb76ff1Sjsg
2961bb76ff1Sjsg static int
pvc_step_lookup(struct drm_i915_private * i915,const char * type,const int * table,int size,int subid)2971bb76ff1Sjsg pvc_step_lookup(struct drm_i915_private *i915, const char *type,
2981bb76ff1Sjsg const int *table, int size, int subid)
2991bb76ff1Sjsg {
3001bb76ff1Sjsg if (subid < size && table[subid] != STEP_NONE)
3011bb76ff1Sjsg return table[subid];
3021bb76ff1Sjsg
3031bb76ff1Sjsg drm_warn(&i915->drm, "Unknown %s id 0x%02x\n", type, subid);
3041bb76ff1Sjsg
3051bb76ff1Sjsg /*
3061bb76ff1Sjsg * As on other platforms, try to use the next higher ID if we land on a
3071bb76ff1Sjsg * gap in the table.
3081bb76ff1Sjsg */
3091bb76ff1Sjsg while (subid < size && table[subid] == STEP_NONE)
3101bb76ff1Sjsg subid++;
3111bb76ff1Sjsg
3121bb76ff1Sjsg if (subid < size) {
3131bb76ff1Sjsg drm_dbg(&i915->drm, "Using steppings for %s id 0x%02x\n",
3141bb76ff1Sjsg type, subid);
3151bb76ff1Sjsg return table[subid];
3161bb76ff1Sjsg }
3171bb76ff1Sjsg
3181bb76ff1Sjsg drm_dbg(&i915->drm, "Using future steppings\n");
3191bb76ff1Sjsg return STEP_FUTURE;
3201bb76ff1Sjsg }
3211bb76ff1Sjsg
3221bb76ff1Sjsg /*
3231bb76ff1Sjsg * PVC needs special handling since we don't lookup the
3241bb76ff1Sjsg * revid in a table, but rather specific bitfields within
3251bb76ff1Sjsg * the revid for various components.
3261bb76ff1Sjsg */
pvc_step_init(struct drm_i915_private * i915,int pci_revid)3271bb76ff1Sjsg static void pvc_step_init(struct drm_i915_private *i915, int pci_revid)
3281bb76ff1Sjsg {
3291bb76ff1Sjsg int ct_subid, bd_subid;
3301bb76ff1Sjsg
3311bb76ff1Sjsg bd_subid = FIELD_GET(PVC_BD_REVID, pci_revid);
3321bb76ff1Sjsg ct_subid = FIELD_GET(PVC_CT_REVID, pci_revid);
3331bb76ff1Sjsg
3341bb76ff1Sjsg RUNTIME_INFO(i915)->step.basedie_step =
3351bb76ff1Sjsg pvc_step_lookup(i915, "Base Die", pvc_bd_subids,
3361bb76ff1Sjsg ARRAY_SIZE(pvc_bd_subids), bd_subid);
3371bb76ff1Sjsg RUNTIME_INFO(i915)->step.graphics_step =
3381bb76ff1Sjsg pvc_step_lookup(i915, "Compute Tile", pvc_ct_subids,
3391bb76ff1Sjsg ARRAY_SIZE(pvc_ct_subids), ct_subid);
3401bb76ff1Sjsg }
3411bb76ff1Sjsg
3425ca02815Sjsg #define STEP_NAME_CASE(name) \
3435ca02815Sjsg case STEP_##name: \
3445ca02815Sjsg return #name;
3455ca02815Sjsg
intel_step_name(enum intel_step step)3465ca02815Sjsg const char *intel_step_name(enum intel_step step)
3475ca02815Sjsg {
3485ca02815Sjsg switch (step) {
3495ca02815Sjsg STEP_NAME_LIST(STEP_NAME_CASE);
3505ca02815Sjsg
3515ca02815Sjsg default:
3525ca02815Sjsg return "**";
3535ca02815Sjsg }
3545ca02815Sjsg }
355