mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
drm/xe/xe_survivability: Add support for survivability mode v2
v2 survivability breadcrumbs introduces a new mode called SPI Flash Descriptor Override mode (FDO). This is enabled by PCODE when MEI itself fails and firmware cannot be updated via MEI using igsc. This mode provides the ability to update the firmware directly via SPI driver. Xe KMD initializes the nvm aux driver if FDO mode is enabled. Userspace should check FDO mode entry in survivability info sysfs before using the SPI driver to update firmware. /sys/bus/pci/devices/<device>/survivability_info/fdo_mode v2 also supports survivability mode for critical boot errors. Signed-off-by: Riana Tauro <riana.tauro@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patch.msgid.link/20251208084539.3652902-6-riana.tauro@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
This commit is contained in:
committed by
Rodrigo Vivi
parent
f4e9fc967a
commit
1987ea95ac
@@ -77,11 +77,13 @@
|
||||
|
||||
#define PCODE_SCRATCH(x) XE_REG(0x138320 + ((x) * 4))
|
||||
/* PCODE_SCRATCH0 */
|
||||
#define BREADCRUMB_VERSION REG_GENMASK(31, 29)
|
||||
#define AUXINFO_REG_OFFSET REG_GENMASK(17, 15)
|
||||
#define OVERFLOW_REG_OFFSET REG_GENMASK(14, 12)
|
||||
#define HISTORY_TRACKING REG_BIT(11)
|
||||
#define OVERFLOW_SUPPORT REG_BIT(10)
|
||||
#define AUXINFO_SUPPORT REG_BIT(9)
|
||||
#define FDO_MODE REG_BIT(4)
|
||||
#define BOOT_STATUS REG_GENMASK(3, 1)
|
||||
#define CRITICAL_FAILURE 4
|
||||
#define NON_CRITICAL_FAILURE 7
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "xe_heci_gsc.h"
|
||||
#include "xe_i2c.h"
|
||||
#include "xe_mmio.h"
|
||||
#include "xe_nvm.h"
|
||||
#include "xe_pcode_api.h"
|
||||
#include "xe_vsec.h"
|
||||
|
||||
@@ -79,6 +80,11 @@
|
||||
*
|
||||
* - ``aux_info<n>`` : Some failures have additional debug information
|
||||
*
|
||||
* - ``fdo_mode`` : To allow recovery in scenarios where MEI itself fails, a new SPI Flash
|
||||
* Descriptor Override (FDO) mode is added in v2 survivability breadcrumbs. This mode is enabled
|
||||
* by PCODE and provides the ability to directly update the firmware via SPI Driver without
|
||||
* any dependency on MEI. Xe KMD initializes the nvm aux driver if FDO mode is enabled.
|
||||
*
|
||||
* Runtime Survivability
|
||||
* =====================
|
||||
*
|
||||
@@ -109,6 +115,8 @@ static const char * const reg_map[] = {
|
||||
[AUX_INFO4] = "Auxiliary Info 4",
|
||||
};
|
||||
|
||||
#define FDO_INFO (MAX_SCRATCH_REG + 1)
|
||||
|
||||
struct xe_survivability_attribute {
|
||||
struct device_attribute attr;
|
||||
u8 index;
|
||||
@@ -142,6 +150,11 @@ static void populate_survivability_info(struct xe_device *xe)
|
||||
set_survivability_info(mmio, info, CAPABILITY_INFO);
|
||||
reg_value = info[CAPABILITY_INFO];
|
||||
|
||||
survivability->version = REG_FIELD_GET(BREADCRUMB_VERSION, reg_value);
|
||||
/* FDO mode is exposed only from version 2 */
|
||||
if (survivability->version >= 2)
|
||||
survivability->fdo_mode = REG_FIELD_GET(FDO_MODE, reg_value);
|
||||
|
||||
if (reg_value & HISTORY_TRACKING) {
|
||||
set_survivability_info(mmio, info, POSTCODE_TRACE);
|
||||
|
||||
@@ -203,6 +216,9 @@ static ssize_t survivability_info_show(struct device *dev,
|
||||
struct xe_survivability *survivability = &xe->survivability;
|
||||
u32 *info = survivability->info;
|
||||
|
||||
if (sa->index == FDO_INFO)
|
||||
return sysfs_emit(buff, "%s\n", str_enabled_disabled(survivability->fdo_mode));
|
||||
|
||||
return sysfs_emit(buff, "0x%x\n", info[sa->index]);
|
||||
}
|
||||
|
||||
@@ -220,13 +236,18 @@ SURVIVABILITY_ATTR_RO(aux_info1, AUX_INFO1);
|
||||
SURVIVABILITY_ATTR_RO(aux_info2, AUX_INFO2);
|
||||
SURVIVABILITY_ATTR_RO(aux_info3, AUX_INFO3);
|
||||
SURVIVABILITY_ATTR_RO(aux_info4, AUX_INFO4);
|
||||
SURVIVABILITY_ATTR_RO(fdo_mode, FDO_INFO);
|
||||
|
||||
static void xe_survivability_mode_fini(void *arg)
|
||||
{
|
||||
struct xe_device *xe = arg;
|
||||
struct xe_survivability *survivability = &xe->survivability;
|
||||
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
if (survivability->fdo_mode)
|
||||
xe_nvm_fini(xe);
|
||||
|
||||
device_remove_file(dev, &dev_attr_survivability_mode);
|
||||
}
|
||||
|
||||
@@ -237,7 +258,10 @@ static umode_t survivability_info_attrs_visible(struct kobject *kobj, struct att
|
||||
struct xe_survivability *survivability = &xe->survivability;
|
||||
u32 *info = survivability->info;
|
||||
|
||||
if (info[idx])
|
||||
/* FDO mode is visible only when supported */
|
||||
if (idx >= MAX_SCRATCH_REG && survivability->version >= 2)
|
||||
return 0400;
|
||||
else if (info[idx])
|
||||
return 0400;
|
||||
|
||||
return 0;
|
||||
@@ -253,6 +277,7 @@ static struct attribute *survivability_info_attrs[] = {
|
||||
&attr_aux_info2.attr.attr,
|
||||
&attr_aux_info3.attr.attr,
|
||||
&attr_aux_info4.attr.attr,
|
||||
&attr_fdo_mode.attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -302,12 +327,16 @@ static int enable_boot_survivability_mode(struct pci_dev *pdev)
|
||||
/* Make sure xe_heci_gsc_init() knows about survivability mode */
|
||||
survivability->mode = true;
|
||||
|
||||
ret = xe_heci_gsc_init(xe);
|
||||
if (ret)
|
||||
goto err;
|
||||
xe_heci_gsc_init(xe);
|
||||
|
||||
xe_vsec_init(xe);
|
||||
|
||||
if (survivability->fdo_mode) {
|
||||
ret = xe_nvm_init(xe);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = xe_i2c_probe(xe);
|
||||
if (ret)
|
||||
goto err;
|
||||
@@ -317,6 +346,7 @@ static int enable_boot_survivability_mode(struct pci_dev *pdev)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_err(dev, "Failed to enable Survivability Mode\n");
|
||||
survivability->mode = false;
|
||||
return ret;
|
||||
}
|
||||
@@ -423,8 +453,10 @@ int xe_survivability_mode_boot_enable(struct xe_device *xe)
|
||||
|
||||
populate_survivability_info(xe);
|
||||
|
||||
/* Log breadcrumbs but do not enter survivability mode for Critical boot errors */
|
||||
if (survivability->boot_status == CRITICAL_FAILURE) {
|
||||
/*
|
||||
* v2 supports survivability mode for critical errors
|
||||
*/
|
||||
if (survivability->version < 2 && survivability->boot_status == CRITICAL_FAILURE) {
|
||||
log_survivability_info(pdev);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,12 @@ struct xe_survivability {
|
||||
|
||||
/** @type: survivability type */
|
||||
enum xe_survivability_type type;
|
||||
|
||||
/** @fdo_mode: indicates if FDO mode is enabled */
|
||||
bool fdo_mode;
|
||||
|
||||
/** @version: breadcrumb version of survivability mode */
|
||||
u8 version;
|
||||
};
|
||||
|
||||
#endif /* _XE_SURVIVABILITY_MODE_TYPES_H_ */
|
||||
|
||||
Reference in New Issue
Block a user