258 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2022 Intel Corporation4 */5 6#include "xe_step.h"7 8#include <linux/bitfield.h>9 10#include "xe_device.h"11#include "xe_platform_types.h"12 13/*14 * Provide mapping between PCI's revision ID to the individual GMD15 * (Graphics/Media/Display) stepping values that can be compared numerically.16 *17 * Some platforms may have unusual ways of mapping PCI revision ID to GMD18 * steppings. E.g., in some cases a higher PCI revision may translate to a19 * lower stepping of the GT and/or display IP.20 *21 * Also note that some revisions/steppings may have been set aside as22 * placeholders but never materialized in real hardware; in those cases there23 * may be jumps in the revision IDs or stepping values in the tables below.24 */25 26/*27 * Some platforms always have the same stepping value for GT and display;28 * use a macro to define these to make it easier to identify the platforms29 * where the two steppings can deviate.30 */31#define COMMON_STEP(x_) \32 .graphics = STEP_##x_, \33 .media = STEP_##x_34 35__diag_push();36__diag_ignore_all("-Woverride-init", "Allow field overrides in table");37 38/* Same GT stepping between tgl_uy_revids and tgl_revids don't mean the same HW */39static const struct xe_step_info tgl_revids[] = {40 [0] = { COMMON_STEP(A0) },41 [1] = { COMMON_STEP(B0) },42};43 44static const struct xe_step_info dg1_revids[] = {45 [0] = { COMMON_STEP(A0) },46 [1] = { COMMON_STEP(B0) },47};48 49static const struct xe_step_info adls_revids[] = {50 [0x0] = { COMMON_STEP(A0) },51 [0x1] = { COMMON_STEP(A0) },52 [0x4] = { COMMON_STEP(B0) },53 [0x8] = { COMMON_STEP(C0) },54 [0xC] = { COMMON_STEP(D0) },55};56 57static const struct xe_step_info adls_rpls_revids[] = {58 [0x4] = { COMMON_STEP(D0) },59 [0xC] = { COMMON_STEP(D0) },60};61 62static const struct xe_step_info adlp_revids[] = {63 [0x0] = { COMMON_STEP(A0) },64 [0x4] = { COMMON_STEP(B0) },65 [0x8] = { COMMON_STEP(C0) },66 [0xC] = { COMMON_STEP(C0) },67};68 69static const struct xe_step_info adlp_rpl_revids[] = {70 [0x4] = { COMMON_STEP(C0) },71};72 73static const struct xe_step_info adln_revids[] = {74 [0x0] = { COMMON_STEP(A0) },75};76 77static const struct xe_step_info dg2_g10_revid_step_tbl[] = {78 [0x0] = { COMMON_STEP(A0) },79 [0x1] = { COMMON_STEP(A1) },80 [0x4] = { COMMON_STEP(B0) },81 [0x8] = { COMMON_STEP(C0) },82};83 84static const struct xe_step_info dg2_g11_revid_step_tbl[] = {85 [0x0] = { COMMON_STEP(A0) },86 [0x4] = { COMMON_STEP(B0) },87 [0x5] = { COMMON_STEP(B1) },88};89 90static const struct xe_step_info dg2_g12_revid_step_tbl[] = {91 [0x0] = { COMMON_STEP(A0) },92 [0x1] = { COMMON_STEP(A1) },93};94 95static const struct xe_step_info pvc_revid_step_tbl[] = {96 [0x5] = { .graphics = STEP_B0 },97 [0x6] = { .graphics = STEP_B1 },98 [0x7] = { .graphics = STEP_C0 },99};100 101static const int pvc_basedie_subids[] = {102 [0x3] = STEP_B0,103 [0x4] = STEP_B1,104 [0x5] = STEP_B3,105};106 107__diag_pop();108 109/**110 * xe_step_pre_gmdid_get - Determine IP steppings from PCI revid111 * @xe: Xe device112 *113 * Convert the PCI revid into proper IP steppings. This should only be114 * used on platforms that do not have GMD_ID support.115 */116struct xe_step_info xe_step_pre_gmdid_get(struct xe_device *xe)117{118 const struct xe_step_info *revids = NULL;119 struct xe_step_info step = {};120 u16 revid = xe->info.revid;121 int size = 0;122 const int *basedie_info = NULL;123 int basedie_size = 0;124 int baseid = 0;125 126 if (xe->info.platform == XE_PVC) {127 baseid = FIELD_GET(GENMASK(5, 3), xe->info.revid);128 revid = FIELD_GET(GENMASK(2, 0), xe->info.revid);129 revids = pvc_revid_step_tbl;130 size = ARRAY_SIZE(pvc_revid_step_tbl);131 basedie_info = pvc_basedie_subids;132 basedie_size = ARRAY_SIZE(pvc_basedie_subids);133 } else if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G10) {134 revids = dg2_g10_revid_step_tbl;135 size = ARRAY_SIZE(dg2_g10_revid_step_tbl);136 } else if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G11) {137 revids = dg2_g11_revid_step_tbl;138 size = ARRAY_SIZE(dg2_g11_revid_step_tbl);139 } else if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G12) {140 revids = dg2_g12_revid_step_tbl;141 size = ARRAY_SIZE(dg2_g12_revid_step_tbl);142 } else if (xe->info.platform == XE_ALDERLAKE_N) {143 revids = adln_revids;144 size = ARRAY_SIZE(adln_revids);145 } else if (xe->info.subplatform == XE_SUBPLATFORM_ALDERLAKE_S_RPLS) {146 revids = adls_rpls_revids;147 size = ARRAY_SIZE(adls_rpls_revids);148 } else if (xe->info.subplatform == XE_SUBPLATFORM_ALDERLAKE_P_RPLU) {149 revids = adlp_rpl_revids;150 size = ARRAY_SIZE(adlp_rpl_revids);151 } else if (xe->info.platform == XE_ALDERLAKE_P) {152 revids = adlp_revids;153 size = ARRAY_SIZE(adlp_revids);154 } else if (xe->info.platform == XE_ALDERLAKE_S) {155 revids = adls_revids;156 size = ARRAY_SIZE(adls_revids);157 } else if (xe->info.platform == XE_DG1) {158 revids = dg1_revids;159 size = ARRAY_SIZE(dg1_revids);160 } else if (xe->info.platform == XE_TIGERLAKE) {161 revids = tgl_revids;162 size = ARRAY_SIZE(tgl_revids);163 }164 165 /* Not using the stepping scheme for the platform yet. */166 if (!revids)167 return step;168 169 if (revid < size && revids[revid].graphics != STEP_NONE) {170 step = revids[revid];171 } else {172 drm_warn(&xe->drm, "Unknown revid 0x%02x\n", revid);173 174 /*175 * If we hit a gap in the revid array, use the information for176 * the next revid.177 *178 * This may be wrong in all sorts of ways, especially if the179 * steppings in the array are not monotonically increasing, but180 * it's better than defaulting to 0.181 */182 while (revid < size && revids[revid].graphics == STEP_NONE)183 revid++;184 185 if (revid < size) {186 drm_dbg(&xe->drm, "Using steppings for revid 0x%02x\n",187 revid);188 step = revids[revid];189 } else {190 drm_dbg(&xe->drm, "Using future steppings\n");191 step.graphics = STEP_FUTURE;192 }193 }194 195 drm_WARN_ON(&xe->drm, step.graphics == STEP_NONE);196 197 if (basedie_info && basedie_size) {198 if (baseid < basedie_size && basedie_info[baseid] != STEP_NONE) {199 step.basedie = basedie_info[baseid];200 } else {201 drm_warn(&xe->drm, "Unknown baseid 0x%02x\n", baseid);202 step.basedie = STEP_FUTURE;203 }204 }205 206 return step;207}208 209/**210 * xe_step_gmdid_get - Determine IP steppings from GMD_ID revid fields211 * @xe: Xe device212 * @graphics_gmdid_revid: value of graphics GMD_ID register's revid field213 * @media_gmdid_revid: value of media GMD_ID register's revid field214 *215 * Convert the revid fields of the GMD_ID registers into proper IP steppings.216 *217 * GMD_ID revid values are currently expected to have consistent meanings on218 * all platforms: major steppings (A0, B0, etc.) are 4 apart, with minor219 * steppings (A1, A2, etc.) taking the values in between.220 */221struct xe_step_info xe_step_gmdid_get(struct xe_device *xe,222 u32 graphics_gmdid_revid,223 u32 media_gmdid_revid)224{225 struct xe_step_info step = {226 .graphics = STEP_A0 + graphics_gmdid_revid,227 .media = STEP_A0 + media_gmdid_revid,228 };229 230 if (step.graphics >= STEP_FUTURE) {231 step.graphics = STEP_FUTURE;232 drm_dbg(&xe->drm, "Graphics GMD_ID revid value %d treated as future stepping\n",233 graphics_gmdid_revid);234 }235 236 if (step.media >= STEP_FUTURE) {237 step.media = STEP_FUTURE;238 drm_dbg(&xe->drm, "Media GMD_ID revid value %d treated as future stepping\n",239 media_gmdid_revid);240 }241 242 return step;243}244 245#define STEP_NAME_CASE(name) \246 case STEP_##name: \247 return #name;248 249const char *xe_step_name(enum xe_step step)250{251 switch (step) {252 STEP_NAME_LIST(STEP_NAME_CASE);253 254 default:255 return "**";256 }257}258