1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "xe_step.h" 7 8 #include "xe_device.h" 9 #include "xe_platform_types.h" 10 11 /* 12 * Provide mapping between PCI's revision ID to the individual GMD 13 * (Graphics/Media/Display) stepping values that can be compared numerically. 14 * 15 * Some platforms may have unusual ways of mapping PCI revision ID to GMD 16 * steppings. E.g., in some cases a higher PCI revision may translate to a 17 * lower stepping of the GT and/or display IP. 18 * 19 * Also note that some revisions/steppings may have been set aside as 20 * placeholders but never materialized in real hardware; in those cases there 21 * may be jumps in the revision IDs or stepping values in the tables below. 22 */ 23 24 /* 25 * Some platforms always have the same stepping value for GT and display; 26 * use a macro to define these to make it easier to identify the platforms 27 * where the two steppings can deviate. 28 */ 29 #define COMMON_GT_MEDIA_STEP(x_) \ 30 .graphics = STEP_##x_, \ 31 .media = STEP_##x_ 32 33 #define COMMON_STEP(x_) \ 34 COMMON_GT_MEDIA_STEP(x_), \ 35 .graphics = STEP_##x_, \ 36 .media = STEP_##x_, \ 37 .display = STEP_##x_ 38 39 __diag_push(); 40 __diag_ignore_all("-Woverride-init", "Allow field overrides in table"); 41 42 /* Same GT stepping between tgl_uy_revids and tgl_revids don't mean the same HW */ 43 static const struct xe_step_info tgl_revids[] = { 44 [0] = { COMMON_GT_MEDIA_STEP(A0), .display = STEP_B0 }, 45 [1] = { COMMON_GT_MEDIA_STEP(B0), .display = STEP_D0 }, 46 }; 47 48 static const struct xe_step_info dg1_revids[] = { 49 [0] = { COMMON_STEP(A0) }, 50 [1] = { COMMON_STEP(B0) }, 51 }; 52 53 static const struct xe_step_info adls_revids[] = { 54 [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display = STEP_A0 }, 55 [0x1] = { COMMON_GT_MEDIA_STEP(A0), .display = STEP_A2 }, 56 [0x4] = { COMMON_GT_MEDIA_STEP(B0), .display = STEP_B0 }, 57 [0x8] = { COMMON_GT_MEDIA_STEP(C0), .display = STEP_B0 }, 58 [0xC] = { COMMON_GT_MEDIA_STEP(D0), .display = STEP_C0 }, 59 }; 60 61 static const struct xe_step_info dg2_g10_revid_step_tbl[] = { 62 [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display = STEP_A0 }, 63 [0x1] = { COMMON_GT_MEDIA_STEP(A1), .display = STEP_A0 }, 64 [0x4] = { COMMON_GT_MEDIA_STEP(B0), .display = STEP_B0 }, 65 [0x8] = { COMMON_GT_MEDIA_STEP(C0), .display = STEP_C0 }, 66 }; 67 68 static const struct xe_step_info dg2_g11_revid_step_tbl[] = { 69 [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display = STEP_B0 }, 70 [0x4] = { COMMON_GT_MEDIA_STEP(B0), .display = STEP_C0 }, 71 [0x5] = { COMMON_GT_MEDIA_STEP(B1), .display = STEP_C0 }, 72 }; 73 74 static const struct xe_step_info dg2_g12_revid_step_tbl[] = { 75 [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display = STEP_C0 }, 76 [0x1] = { COMMON_GT_MEDIA_STEP(A1), .display = STEP_C0 }, 77 }; 78 79 static const struct xe_step_info pvc_revid_step_tbl[] = { 80 [0x3] = { .graphics = STEP_A0 }, 81 [0x5] = { .graphics = STEP_B0 }, 82 [0x6] = { .graphics = STEP_B1 }, 83 [0x7] = { .graphics = STEP_C0 }, 84 }; 85 86 static const int pvc_basedie_subids[] = { 87 [0x0] = STEP_A0, 88 [0x3] = STEP_B0, 89 [0x4] = STEP_B1, 90 [0x5] = STEP_B3, 91 }; 92 93 __diag_pop(); 94 95 struct xe_step_info xe_step_get(struct xe_device *xe) 96 { 97 const struct xe_step_info *revids = NULL; 98 struct xe_step_info step = {}; 99 u16 revid = xe->info.revid; 100 int size = 0; 101 const int *basedie_info = NULL; 102 int basedie_size = 0; 103 int baseid = 0; 104 105 if (xe->info.platform == XE_PVC) { 106 baseid = FIELD_GET(GENMASK(5, 3), xe->info.revid); 107 revid = FIELD_GET(GENMASK(2, 0), xe->info.revid); 108 revids = pvc_revid_step_tbl; 109 size = ARRAY_SIZE(pvc_revid_step_tbl); 110 basedie_info = pvc_basedie_subids; 111 basedie_size = ARRAY_SIZE(pvc_basedie_subids); 112 } else if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G10) { 113 revids = dg2_g10_revid_step_tbl; 114 size = ARRAY_SIZE(dg2_g10_revid_step_tbl); 115 } else if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G11) { 116 revids = dg2_g11_revid_step_tbl; 117 size = ARRAY_SIZE(dg2_g11_revid_step_tbl); 118 } else if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G12) { 119 revids = dg2_g12_revid_step_tbl; 120 size = ARRAY_SIZE(dg2_g12_revid_step_tbl); 121 } else if (xe->info.platform == XE_ALDERLAKE_S) { 122 revids = adls_revids; 123 size = ARRAY_SIZE(adls_revids); 124 } else if (xe->info.platform == XE_DG1) { 125 revids = dg1_revids; 126 size = ARRAY_SIZE(dg1_revids); 127 } else if (xe->info.platform == XE_TIGERLAKE) { 128 revids = tgl_revids; 129 size = ARRAY_SIZE(tgl_revids); 130 } 131 132 /* Not using the stepping scheme for the platform yet. */ 133 if (!revids) 134 return step; 135 136 if (revid < size && revids[revid].graphics != STEP_NONE) { 137 step = revids[revid]; 138 } else { 139 drm_warn(&xe->drm, "Unknown revid 0x%02x\n", revid); 140 141 /* 142 * If we hit a gap in the revid array, use the information for 143 * the next revid. 144 * 145 * This may be wrong in all sorts of ways, especially if the 146 * steppings in the array are not monotonically increasing, but 147 * it's better than defaulting to 0. 148 */ 149 while (revid < size && revids[revid].graphics == STEP_NONE) 150 revid++; 151 152 if (revid < size) { 153 drm_dbg(&xe->drm, "Using steppings for revid 0x%02x\n", 154 revid); 155 step = revids[revid]; 156 } else { 157 drm_dbg(&xe->drm, "Using future steppings\n"); 158 step.graphics = STEP_FUTURE; 159 step.display = STEP_FUTURE; 160 } 161 } 162 163 drm_WARN_ON(&xe->drm, step.graphics == STEP_NONE); 164 165 if (basedie_info && basedie_size) { 166 if (baseid < basedie_size && basedie_info[baseid] != STEP_NONE) { 167 step.basedie = basedie_info[baseid]; 168 } else { 169 drm_warn(&xe->drm, "Unknown baseid 0x%02x\n", baseid); 170 step.basedie = STEP_FUTURE; 171 } 172 } 173 174 return step; 175 } 176 177 #define STEP_NAME_CASE(name) \ 178 case STEP_##name: \ 179 return #name; 180 181 const char *xe_step_name(enum xe_step step) 182 { 183 switch (step) { 184 STEP_NAME_LIST(STEP_NAME_CASE); 185 186 default: 187 return "**"; 188 } 189 } 190